Rendering

Worldbuilding

Virtual Production

Developer Tools

Audio

UMG / Slate Improvements

Editor

Modeling and Sculpting Tools

Animation

DMX

Unreal Cloud Services

Platform

XR

Mobile

Gameplay Framework

Artificial Intelligence

Physics

Niagara

Accessibility Improvements

Unreal Insights

Datasmith

Variant Manager

RAD Tools

Online

Networking and Multiplayer

Templates and Sample Content

Platform SDK Upgrades

Release Notes

Upgrade Notes

What's New?

Unreal Engine 5.0 was a groundbreaking release, bringing a whole slate of new tools to users. 5.1 is building upon the framework of 5.0, delivering updates and improvements to facilitate the creation of next-generation, real-time 3D content and experiences even further. Our focus was on making our feature set robust, workflow-friendly, and versatile, with the needs of different sectors in mind.

Visual Integrity and Performance

We have delivered improvements to support you in creating 60 fps games for next-generation consoles and capable PCs. Those include:

Improvements in Lumen, Nanite, and Virtual Shadow Maps.

Building Bigger Worlds and Collaboration

You can create larger worlds using World Partition.

Improvements were made to make teamwork more efficient, facilitating the game development process.

Virtual Production and In-Camera VFX

We continue to rapidly develop new tools for virtual production and In-Camera VFX (ICVFX). Working with footage is now easier than ever.

Use the In-Camera VFX Editor to do color correction, apply light cards, and perform general stage operations.

DMX configurations are now improved by means of MVR support.

Lumen has an initial implementation for nDisplay.

GPULM workflows have been improved.

Keep reading to find out more information about these tools, and the full list of all improvements in Unreal Engine 5.1.

This release includes improvements submitted by our community of Unreal Engine developers on GitHub. Thank you to each of these contributors to Unreal Engine 5.1:

ABoy (lvhuming), AchimTuran, Adrian-Marian Popoviciu (ArmainAP), Aidin Abedi (aidinabedi), aknauermaxon, Albin Odervall (albinodervall), aldenc98, Alex Garcia Ruiz de Oteiza (AlexOteiza), Alexander (DecoyRS), Amit Kumar Mehar (amuTBKT), andersonbisconsin, Andreas Andersson (derwiath), Antoine Vugliano (avudnez), AntsyBoi, az6667, Ben Raziel (benraziel), Ben Rog-Wilhelm (zorbathut), Ben Sutherland (BlenderSleuth), Ben Sweeney (BenSweeneySG), BenAD83, Benito Alessandrino (BennyExtreme), Benjamin Thomas Blodgett (BenVlodgi), bestofact, bhickmanl, bitdewy (bitdewy), bmiwcy, Brang Pakdring (brangpd), Brent G (Punlord), Brent Goodacre (WGBrent), Brent Scriver (FineRedMist), Bromfitsen, Cameron Rapp (MalikuMane), cbrandtieng, Cecco (ceccocecco), Charles Alexander (muchcharles), Chris Anderson (CasperTheCat), Chris Haddon, Christian Kendall (ckendal3), Chris Wallis (The Coalition), cmsinflexion, CodingBot (ameaninglessname), Colden Cullen (ColdenCullen), daktor, Damien Kochanek (DamienKochanek), Dan Hertzka (HertzDonut), David Bollo, David Gilbert (davidyrgilbert), David Nadaski (GlassBeaver), dbsigurd, dening (loening), Denis Blank (Naios), Dezső Zoltán (zaki), Diyou, Dmitry Korshunov (originomeg), Dmitry Vinnik (vinnik-dmitry07), Doğa Can Yanıkoğlu (dyanikoglu), dorgon chang (dorgonman), Dorian (Hisamera), Dorian Gardes (d-gardes), Doug Richardson (drichardson), Douglas Jose (douglasjose), Douglas Lassance (douglaslassance), drcxd, Dzmitry Malyshau (dm-tesla), Eddie Stubbington (Edstub207), Edin Suta (edinsuta), Elhoussine Mehnik (HoussineMehnik), Elliot Colp (ecolp-improbable), Emil Rosenquist (EmilRosenquist), Enno Rehling (ennorehling), Eric Thiffeault (ethiffeault), Ethan Thornburg (erebel55), etheranger, Evan Hart (ehartNV) (NVidia), Filippo Tarpini (Filoppi), Fluffy Kalashnikov (FluffyKalashnikov), Fredrik (Temaran), furby™ (furby-tm), fury22pl, Gabriel T. Nardy (gtnardy), Gamergenic (gamergenic), Gaurang Ingale (gaurang-ingale), Geordie Hall (geordiemhall), Georgy Treshchev (gtreshchev), Giovanni Paolo Viganò (gpvigano), Hannah Gamiel (hgamiel), Hirofumi Seo (HSeo), IgnacioFDM, Igor Karatayev (yatagarasu25), igor-kondratiev, Ilddor, Ilya (ill), Incredible (ameaninglessname), Isaac Ashdown (Eyesiah), Isaac Ribeiro (i-ribeiro), Jack Andersen (jackoalan), Jack Isaacs (JackIsaacs), Jackson Fields (fieldsJacksonG), Jacob Kostenick (kostenickj), James Baxter (TheJamsh), Jared Taylor (Vaei), Jay Lu (JayLu2000), Jeremy Abel (jeremyabel), Jessica Chen (Intel), jm00517, John (GoldNotch), John Dickinson (jdckmz), Jonas Kjellström (JonasKjellstrom), Jørgen P. Tjernø (jorgenpt), JSaueressig88, Juan M Gómez (jmgomez), June Rhodes (hach-que), Justin Bostian (jb5n), JustinTime (JustinTether), Kacper Kowalczuk (Ogniok), kaffeewolf, Kai Klyden (RoboMage), Kenn Zhang (breakstring), Kenshin Azuma (aziogroup), Kevin Østerkilde (Kosai106), Kevin Xiao (KXOC), Koji Kawasaki (kedamazigoku), KonstantinKohl, KrisRedbeard, Kristján Valur Jónsson (kristjanvalur), Krunoslav Zaher (kzaher), Krzysiek Justyński (MothDoctor), leobenaducci, Levil0229, lijenicol, lijinlong, LindyHopperGT, LizardThief, losemymind (losemymind), Lukasz "iniside" Baran (iniside), MagForceSeven, Måns Isaksson (mansisaksson), Marat Radchenko (slonopotamus), Marcel Egle (EgleM2022), Marco Antonio Alvarez (surakin), Marijn Suijten (MarijnS95), Mario Arsenov (Xertor), Marius Petcu (dapetcu21), Marnix Kuijs (MarnixKuijs), Matias N. Goldberg (darksylinc), Matthias Hölzl (hoelzl), Maxim Ivanov (redbaron), melchior-haven, Meta Immersive Synthetics (metakgs), Michael McCartney (mccartnm), Mike Bell (MichaelBell), Mike Seese (seesemichaelj), Mike Slegeir (tehpola), mikoto-studio, Milan Šťastný (aknarts), Minseok Lee (codeonwort), Mohammad Mossa (WizardCell), Morva Kristóf (KristofMorva), muyang.zhang (87770906), nathandh13, Neema Teymory (nteymory), Nicholas Frechette (nfrechette), Nicholas Nathan Colotouros (NicholasColotouros), Nick Edwards (NEdwards-Sharkmob), Nick Edwards (NEdwards-SumoDigital), Nick Lamprecht (freezernick), NickScriv, Nico Ell (nicoell), nuntax, nutti, Paolo Galeone (galeone), Paul Greveson (moppius), Paweł (PoetaKodu), Peter Kovář (1div0), phisko, Phyronnaz, pl-dsk, Pratik Chavan (ppchavan001), ProgC, projectgheist, pwoytiuk, Qinja, QRare, Quentin Dietz (quentin-dietz), RangeMachine, Rareden, Remi Palandri, Rem (rveilleux), René Ferdinand Rivera Morell (grafikrobot), Rick G (rtrick), Rob Cowsill (rcowsill), Robert.Kawiak (Intel), Robert Kihl (kihl), RumbleballTheReal, rveilleuxBHVR, Ryan DowlingSoka (Ryan-DowlingSoka), Ryan Van Vliet (RyanVHumanoid), ryugibo, S_MC (slimsons), Scott Ramsay (foobit), Sean Saleh (seansaleh), Sébastien Rombauts (SRombauts), Setepenre (Delaunay), SkyXMoon, splatxman, sqexmuelas, Stas Korotaev (Stals), steelixb, Stefan Zimecki (stefan-zimecki) (Improbable.io), sunduk, SungJinKang (SungJJinKang), takaokato, Teodor Chishiki Jakobsson (Maigo), Tobi W (TWAtGH), Tom van Dijck (tvandijck), Travis Hopkins (djethernet1), Urszula Kustra (ukustra), Valery Komarov (ValeryKomarov), Ves (VesCodes), WinsonS (WinsonSS), Wouter Weynants (WouterWeynants), xiexbmu, yang xiangyun (pdlogingithub), Yashas Gujjar (yashasg), yashverma, Yohann MARTEL (ymartel06), YoshikazuAzechi (y-azechi), yumnuska, Yuri Belleri (ZioYuri78), Yuriy (SmelJey), Zsófia Balogh (zosiu), 丛越 (congyue1977), 华清飞扬-小木子 (hui211314dd), 徐晨 (kimixuchen)

Rendering

Lumen Improvements

Lumen now supports the Two-Sided Foliage shading model, by gathering lighting from the backface and scattering it through the leaf, attenuated by the material's Subsurface Color.





Lumen's Software Ray Tracing also has a new, much more accurate representation for foliage through stochastic semi-transparent distance field ray traces, which fixes over-occlusion on foliage.

Lumen uses Spatiotemporal Blue Noise for cleaner image quality, especially when the camera is not moving. The biggest quality improvements can be seen when Lumen is using the High Global Illumination scalability level, which is targeted at 60fps on next generation consoles.



Lumen's Software Ray Tracing now samples the Surface Cache directly instead of a low resolution and leaky voxel representation. This improves secondary bounces, reflections, and global illumination from small emissive surface elements.



When the project has High Quality Translucency Reflections enabled, Lumen Reflections provide mirror reflections on the frontmost layer of Translucent Surface materials.



Lumen Reflections now support Single Layer Water, with reflections forced to mirror.



Other Lumen features and improvements for this release include:

In Hardware Ray Tracing mode, reflections now support fast alpha masking by evaluating alpha from the Surface Cache.

The Surface Cache generation algorithm is now more robust and able to cover a higher variety of meshes, including having Surface Cache for tiny scene elements.

Additional internal settings were added to High, Epic, and Cinematic scalability levels to support greater control over performance vs. quality tradeoffs.

The Skylight Leaking feature is available in Post Process Volume settings to use as a non-physically-based art direction knob to keep indoor areas from going fully black.

The Diffuse Color Boost feature is available in Post Process Volume Settings to increase the amount of bounced light in scenes.

Lumen is now optionally supported in Scene Captures by forcing Lumen GI and Reflections to be enabled in the capture component's Post Process Volume settings. By default the Surface Cache resolution is reduced to 50% of its default size when run in a scene capture, but you can override this in the component's settings.

Lumen now supports multiple viewports in nDisplay. Each viewport will use an independent Lumen Scene.

Added experimental Hardware Ray Tracing support in Vulkan.

Includes Surface Cache reflection lighting only, with no support yet for Hit Lighting.

Many stability and bug fixes.

For more information, see Lumen Technical Details.

Nanite Improvements

Nanite includes the following features and improvements for this release:

Now supports materials using the following options:

Two Sided

Masked Blend Mode

World Position Offset (beta)

Bounds for culling are not yet being updated so triangles may disappear depending on usage.

Pixel Depth Offset

More information about the expected performance characteristics of these features can be found in the Nanite documentation.

Improved support for Nanite foliage geometry:

A new Preserve Area option for Nanite static meshes prevents thinning out of geometry at far distances when enabled for foliage.

Landscape Grass meshes can now have Nanite enabled.

Nanite foliage performance is a complex topic, with many influencing factors that are highly content-dependent. More information can be found in the Nanite documentation.

Improved support for hybrid Nanite / non-Nanite workflows for the purpose of authoring for platforms both with and without Nanite support:

You can add a Nanite representation to existing non-Nanite meshes from the Content Browser using the right-click menu item Level of Detail > High Res > Import High Res…. With this workflow, the pre-existing mesh and LOD chain become the Fallback Mesh, rather than the import process automatically generating a Fallback Mesh from the Nanite geometry.

Added a Nanite Switch expression in Materials to enable you to define specialized behavior when being rendered with Nanite.

Added a Nanite Override Material slot to Materials and Material Instances. If you set this slot, the assigned meshes rendering as Nanite will instead use the referenced material. The slot is forcibly defaulted to None in Material Instances, so that setting the override in a parent material will not cause it to be automatically inherited in any children.

Static Mesh components now have a Disallow Nanite parameter, making it possible to use a mix of Nanite and non-Nanite actors from the same mesh asset.

Nanite-enabled meshes now support the Hidden Shadow flag. This allows custom shadow proxy meshes to be Nanite, improving the performance of Virtual Shadow Maps.

Instanced Static Mesh components drawing as Nanite now respect distance-based culling settings.

(Experimental) You can now convert Landscapes to be rendered using Nanite.

(Experimental) You can enable initial support for native ray tracing and path tracing of Nanite meshes by setting r.RayTracing.Nanite.Mode=1. This approach preserves all detail while using significantly less GPU memory than zero-error fallback meshes. Early tests show a 5-20% performance cost over ray tracing a low-quality fallback mesh, but results may vary based on content.

Many other quality and performance improvements.

Starting in Unreal 5.1, Nanite requires Shader Model 6 to be enabled with DirectX 12. No settings changes are required for Vulkan.

For more information, refer to Nanite Virtualized Geometry.

Temporal Super Resolution Improvements

Temporal super-resolution is now improved in this release in multiple areas:

Better support for anti-aliasing of animated materials.

Improved quality and reduced ghosting on translucent geometry or geometry with incorrect motion vectors.

Better detection of pixel flickering and moire with improved anti-aliasing quality and less ghosting.

Performance optimizations for 60fps targets.

For more information, refer to Anti-Aliasing and Upscaling.

Path Tracer Improvements

Path Tracer includes the following features and improvements for this release:

Added support for a variety of engine features:

Exponential Height Fog and Sky Atmosphere

The Exponential Height Fog component requires you to enable Volumetric Fog. Local lights default to not casting volumetric shadows and must be enabled in their settings, which matches their default workflow with real-time lighting.

The Sky Atmosphere is supported with the Reference Atmosphere Post Processing Volume setting. Volumetric Clouds are not yet supported when this setting is enabled.

Planar Decals

Water Geometry and Single Layer Water Shading Model

Per-Instance Custom Data and Per-Instance Random material expressions

Added support for Light Functions. Colored light functions are also possible, in the Path Tracer only, by enabling r.PathTracing.LightFunctionsColor.

Added the Reference Motion Blur option to the Movie Render Queue for more accurate motion blur, with a higher performance cost to get smooth results. In this mode, no post-process vector blur is applied, and denoising is applied after all spatial and temporal sample accumulation. Higher temporal samples should be applied to increase quality.

Added support for multi-GPU rendering (mGPU). SLI is required. To enable it, pass -MaxGPUCount=2 on the Unreal Editor command line and set r.PathTracing.MultiGPU=1, which can be toggled at runtime. (r.AllowMultiGPUInEditor=1 is no longer required in .ini files to enable mGPU in the editor.)

Added experimental support for the Optix denoiser. This denoiser runs on the GPU, offering faster denoising times. It also includes an experimental temporal component which tries to reduce flickering in denoised animations. When both the OpenImageDenoise and Optix plugins are loaded, use r.PathTracing.SpatialDenoiser.Type 0 (default - OpenImageDenoise) or 1 (Optix) to select the currently active denoiser. Please note that the Optix denoiser is only supported on Nvidia hardware and you must manually enable the plugin.

Added experimental support for temporal denoising which can be enabled with r.PathTracing.TemporalDenoiser 1 Temporal denoising is intended to be used with Movie Render Queue with Reference Motion Blur enabled. The Optix denoiser uses the Optical Flow SDK from NVIDIA to estimate motion vectors, while the OpenImageDenoise denoiser uses an Engine built-in algorithm. Please note that this feature does not guarantee perfect temporal stability in all cases, so high sampling rates may still be required.

For more information, refer to Path Tracer.

GPU Lightmass Improvements

GPU Lightmass includes the following features and improvements for this release:

Added support for the following engine features:

Sky Atmosphere

Stationary Sky Lights (with Bent Normals)

Volumetric Shadows for Stationary Lights

Colored translucent shadows from Static Lights

IES Profiles for Static Lights

Per-light shadow casting flags

Improved behavior of Irradiance Cache and First Bounce Ray Guiding to have higher quality using the same settings.

Improved denoiser results at low light levels by applying tonemapping and inverse tonemapping before and after the Intel denoiser to mitigate discoloration issues under extreme dynamic ranges.

Improved the quality, performance, and GPU memory usage with the Volumetric Lightmap renderer.

Instead of rendering the entire scene's volumetric lightmap probes all at once, the renderer progresses through probes in batches. However, this breaks the interactive preview for volumetric lightmaps.

With these changes, only a quarter of the original GPU memory is needed to bake volumetric lightmaps and probe placement has been improved so that approximately 25% fewer probes are needed.

For more information, see GPU Lightmass.

Translucent Overlay Material

You can now assign Static and Skeletal Meshes a secondary Overlay Material. You can use this to achieve certain visual effects without requiring a duplicate mesh. The mesh will be rendered twice – once with a base material and once with the translucent overlay material. There is only one overlay material per mesh regardless of the number of material slots, allowing for shading effects that span across the entire mesh in one pass.



On-Demand Shader Compilation

On-Demand Shader Compilation (ODSC) compiles only the shaders needed to render what is seen on screen in the editor, and during iterative platform development using cook-on-the-fly. ODSC can significantly reduce the number of shaders to be compiled for those who routinely sync their builds and have a large number of shaders to compile, those who iterate on materials and shaders often, and for anyone without access to a remote DDC for cached shaders.

ODSC is enabled by default and can be controlled with the cvar r.ShaderCompiler.JobCacheDDC.

While ODSC can reduce shader compilation for most working on large projects that regularly compile large numbers of shaders, it does not currently reduce the number of "global shaders" that are compiled during the initial startup of the editor.

DX12 PSO Compilation Improvements

UE 5.1 aims to reduce stalls caused by shader compilation by starting to compile PSOs earlier, when components are loaded, rather than at the point where the object is rendered. This reduces or eliminates the need to manually gather PSO caches, which is a time-consuming process and cannot guarantee perfect coverage.

It is still possible to experience stalls if an object has to be rendered immediately after it's loaded. For the case of background streaming of distant objects, we've added the option to skip rendering the mesh until the PSO is ready, which trades stalls for delays in drawing these objects. Similarly, if a title needs to teleport the camera to a completely new location, or otherwise needs to display many new materials at once, there won't be enough time to compile all the PSOs. In this case, the game code needs to load the materials and meshes earlier, and hint the renderer ahead of time that it will need to draw them.

The existing PSO cache system can still work alongside the new system. It's possible to devise hybrid approaches, where there's a small, manually generated PSO cache containing materials which are known to be needed all the time, or are going to be used after a teleport event, and let the automatic system take care of most of the other materials.

This system is still under development and its performance will improve in future engine releases. It will also be expanded to support other RHIs, such as Vulkan.

Strata Materials (Experimental)

Strata is a new way of authoring materials that replaces the fixed suite of shading models, such as Default Lit and ClearCoat, with a more expressive and modular framework that provides a greater range of surface appearances and a wider parameter space from which to work. Performance for Strata Materials scales according to complexity and desired budget of a project, with legacy materials having a similar cost as before.



You can enable Strata from the Project Settings under Engine > Rendering >Strata.

To learn more about Strata in its experimental state, visit the Epic Developer Community forums.

Texture and Texture Asset Editor Improvements

Textures and The Texture Asset Editor includes the following improvements for this release:

You can now import Textures as 32-bit float single-channel and four-channel formats R32F and RGBA32F. For backwards compatibility, these options are opt-in and must manually be switched on, even if the source file on disk uses a 32-bit float format. (Skylights currently clamp the Specified Cubemap to 16-bit float, limiting the maximum pixel value to 65,504. This will be addressed in a future engine version.)



Textures with non-power-of-two dimensions can now have mipmaps. Each dimension should still be a multiple of 4 in order for the texture to be compressible. This can be useful to store content in its native aspect ratio and improve some features such as anisotropic filtering, however depending on the platform it might not always save memory relative to the next power-of-two size up.

Added Toolbar options for Texture2D Arrays to be displayed as Slices with a checkbox.

Added Toolbar options for Cubemap HDR textures to display as Faces and 3D View with checkboxes.

When viewing a Render Target used in a Scene Capture component, the Details panel now displays the total GPU memory usage of the Scene Capture and all textures affiliated with it, including the Lumen Scene if Lumen is enabled in the capture.

Lumen off:



Lumen on:



DirectX 12 with Shader Model 6 is Default on PC for New Projects

All newly-created projects for Unreal Engine 5 now use DirectX 12 with Shader Model 6 (SM6) enabled by default on PC. DX12 enables us to be more efficient on all fronts regarding CPU time, GPU time, and memory usage, and it unlocks new features (ray tracing being the most prominent one).

Nanite and Virtual Shadow Maps require DX12 with SM6 going forward.

For projects already using DirectX 12, you can enable SM6 from the Project Settings under Platforms > Windows > D3D12 Targeted Shader Formats with the SM6 checkbox.

When DX12 is used on PC, the engine will try each enabled shader model in descending order, so if both SM5 and SM6 are enabled, it will first try SM6, and if it is not supported by the machine, fall back to SM5. If none of the enabled shader models is usable, it will fall back to DX11 SM5, unless that's disabled in the project settings. This logic does not apply if the RHI or shader model is forced via the command line, using the -dx12, -dx11, -sm5, -sm6 (and so on) flags; in that case, the engine will quit if the forced configuration is not supported.

Please note that shader instruction counts in the Platform Stats section of the Material Editor will not be directly comparable between SM6 and SM5 because of the differences in the SM6 intermediate language. The SM6 instruction count will appear higher for equivalent levels of complexity. SM6 instruction counts should only be compared to other SM6-compiled materials.

Anamorphic Depth of Field and Camera Crop (Experimental)

Depth of field adds support for anamorphic lenses that have a vertically stretched bokeh shape. Anamorphic bokeh provides a performant option without having to provide fully custom texture support to your project. Additionally, you can now crop the camera view to a commonly-used or custom aspect ratio.



You can find the anamorphic bokeh settings in the Cine Camera and Post Process Volume settings under Lens Settings using the Squeeze Factor setting.

You can find the settings to crop your camera's aspect ratio in the Cine Camera under Crop Settings. Choose a common aspect ratio or use Cropped Aspect Ratio to specify one.

For more information, refer to Cinematic Depth of Field.

Material Editor In-line Editing

We redesigned over eighty Material Expressions to include in-line editing of constant values and properties directly on the node in the Material Graph. This is a powerful quality-of-life improvement for the Material editing workflow, as users no longer need to select a node and edit values in the Details panel in many cases.

Light Mixer (Beta)

The Light Mixer is a new editor window that displays all lights in the scene in a compact tabular format for rapid inspection and editing, similar to how the Environment Light Mixer includes scene environment lighting components.



Features of the Light Mixer:

Create and re-parent lights directly from the Light Mixer.

Display lights with hierarchical context inside of folders, or as a flat list with no folders.

Edit the same field at once on all selected lights.

Open multiple tabs called collections with user-selected subsets of lights.

Isolate a single light with a Solo button, turning off editor visibility on all other lights.

Enable / disable Sync Selection to automatically select the same light in the Viewport and World Outliner.

Customize which lighting properties are displayed for editing.

Show multiple Light components contained within Blueprints.

Virtual Shadow Maps: Distant Light Mode

Virtual Shadow Maps improve the efficiency of scenes with many local lights rendered at a distance. Enable it using the console command r.Shadow.Virtual.DistantLightMode.

Virtual Shadow Maps now require DirectX 12 with Shader Model 6 (SM6) be enabled in the Project Settings. SM6 is enabled from the Platforms > Windows > D3D12 Targeted Shader Formats.

Hardware Ray Tracing Windows 10 Version Requirements

Hardware Ray Tracing now requires the same minimum Windows 10 version as Nanite and Virtual Shadow Maps. For more details, refer to Hardware and Software Specifications. Ray Tracing shaders are compiled when targeting either SM5 or SM6 D3D12 shader formats, as before.

Worldbuilding

World Partition Data Layer Improvements

Data Layers is a system designed to conditionally load and unload your world data by toggling data layers in the editor and at runtime. Data Layers are an excellent way to organize your world in the editor to handle different scenarios in your game, and create variations of the same world.



This release, the Data Layers system received the following improvements:

Data Layers functionality is now split into two constructs:

Data Layer Assets for storing data useful across multiple worlds.

Data Layer Instances that reference a Data Layer Asset and are world specific.

Quality of life improvements to the Data Layer Outliner.

Level Instance support: Actors inside a Level Instance can now reference Data Layers in the world.

For more, see the World Partition - Data Layers documentation.

HLOD Support for Water Body Actors

Unreal Engine's full suite of Water System rendering and meshing tools provide the ability to add a variety of Water Body Actor types to your levels to represent water.



In this release, Unreal Engine's Hierarchical Level of Detail system (HLODs) now fully supports Water Body Actors. You can assign each Actor to an HLOD Layer, and each Actor has a variety of HLOD settings that can be customized to fit your project's needs.

For more information on the Water system, refer to the Water System documentation.

For more information on the Hierarchical Level of Detail system, refer to the Hierarchical Level of Detail and World Partition - Hierarchical Level of Detail documentation.

Actor Editor Context

With the release of Unreal Engine 5.1, the editor now displays the Actor Editor Context in the lower right corner of the 3D viewport.



This small box displays the currently-selected sub-level, World Partition Data Layer, Level Instance, or the currently-active Outliner Actor Folder. Any Actors placed in the world are automatically added to the current Actor Editor Context.

Uncontrolled Changelist Support in Source Control

Unreal Engine's Source Control system supports collaboration within development teams by facilitating the sharing of asset and code files through version control, as well as by providing file backups and a history of changes for your project.



Source Control works closely with One File Per Actor making it an important part of World Partition workflows.

In Unreal Engine 5.1, Source Control has received several quality-of-life improvements and can now make use of Uncontrolled Changelists. This feature tracks all the writable files within your project, providing a running list of all your local changes.

Track changes in multiple uncontrolled changelists.

Move files individually to controlled changelists or revert them at any time.

Prevent exclusive checkout lock for testing and debugging, reducing file contention.

Uncontrolled Changelists are enabled by default in Unreal Engine 5.1.

For more information on in-engine Source Control, refer to Source Control Inside Unreal Editor documentation.

Large World Coordinate Support for World Partition (Beta)

Large World Coordinates (LWC) introduces support for double-precision data variant types in Unreal Engine 5. With the 5.1 release, we expanded the system to support for World Partition.

Large World Coordinates World Max Increase

New for this release, we raised the default world extents from 22 km to 88,000,000 km, allowing for much larger worlds to be created.

For more information on Large World Coordinates, refer to the Large World Coordinates documentation.

Virtual Production

In-Camera VFX Editor

We added a dedicated stage operator panel to collect the most commonly-used controls for ICVFX stage operations in one curated UI. Color corrections, nDisplay adjustments, and light cards are now presented in one place allowing for efficient stage operations.



Improved Light Card system

We enhanced Light Cards to use a UV projection logic that keeps them in the designed shape when represented on an LED wall. We also slimmed down the UI for the creation, editing, and placement of Light Cards to present only the controls that are relevant to this creative lighting task.

Improved Color Correction controls for ICVFX

We expanded the workflows for color correction for ICVFX productions. Color correction regions work in 3D, and you can combine them with or use them in conjunction with 2D shapes as power windows. This is in addition to the per-viewport color corrections. You can now optionally restrict color grading effects of any given Color Correction Region / Window to the pixels that belong to an array of actors.

Media Plate



Previously, streaming media in your scene required manually mapping together elements using Blueprints. You can now add the Media Plate actor element directly to your Scene instead, which takes care of all the underlying connections. Media Plate uses the EXR tiling and mips for image sequences at the highest-quality maximum resolution and color depths. When you use the premade Sphere and Rectangle shapes in Media Plate, Unreal Engine only streams the pixels currently viewed by the Camera, lowering the budget cost for streaming. This lets you balance the load on render notes and improves per-PC bandwidth limitations.

The new video architecture brings:

A greatly simplified video import process.

Support for Media Playlists.

Drag and drop support for the suggested assets and Actors.

Updated Info and Preview windows.

Sequencer integration.

View frustum culling for improved performance.

A Media Player and Texture Manager.

EXR Plate Performance



Uncompressed EXRs provide the best quality for video footage and have the fastest path for processing using adequately fast storage devices. We added a new system to pre-process uncompressed EXRs and break them down into a set of tiles and mipmap levels. Using the workflow of the Media Plate Actor then allows these properly optimized EXRs to playback through the system with the best possible efficiency by streaming and rendering only the visible tiles according to the Viewport alongside with the right mip level, whether being rendered through the nDisplay system or standalone.

Lumen for In-Camera VFX (Experimental)

Lumen now has support for multiple viewports in nDisplay and can be used for ICVFX. Each viewport will use an independent Lumen Scene to eliminate artifacts in LED volumes. In addition to Lumen, Virtual Shadow Maps also support multiple viewports for nDisplay and ICVFX through the same mechanism.

Cine Camera near clipping

The Cine Camera now has a per-camera Custom Near Clipping Plane.

Virtual Camera

Output from Virtual Camera now includes support for WebRTC Pixel Streaming, offering a more reliable and performant streaming option that can be viewed both in the Live Link VCam app as well as in any web browser. Virtual Camera also now includes support for Enhanced Input in Editor, to allow for remappable control of the VCam with any supported hardware device. These changes are enabled by default on the new VCamActor, which replaces VirtualCamera2Actor, alongside a redesigned default operator HUD focused on a Live Action Camera-Like feel and a clean frame image.

Furthermore, there are Virtual Camera UI and UX improvements.



Virtual Scouting Improvements

Virtual Scouting now works with OpenXR and Enhanced Input system.

Live Link Face CSV Importer plugin

If you use the Live Link face iOS app to record facial capture on the device only (not connected to Unreal Engine and recorded in Take Recorder), you can now import the (backup) recording once extracted. The device stores a .csv file with the raw timecode and blendshape data. Once imported, the result is a level sequence with a Live Link track, equivalent to what you would have achieved by recording the live stream in Take Recorder.

Multi-user Server UI

We added a UI to the multi-user server to inspect the running status of the server live. This allows operators and ICVFX stage managers to inspect, monitor, and diagnose problems during multi-user server operation. This has benefits over the console server which only provided a stream of connection information over a console command and did not provide contextual information about the running server operation.

The console server is still available for operation on headless computers or computers where running a UI is not possible. For example, a Linux server or containerized operation.

Movie Render Queue

We made several improvements to how Movie Render Queue (MRQ) handles texture streaming. Improved handling for incorrect mipmaps being loaded when Texture Streaming is enabled. Texture streaming is still disabled by default in MRQ, but can be enabled to save memory in large projects.

You can now create Virtual Texture and Nanite cinematic caches using the Prestreaming Recorder. This plugin is used as a render pass to build a cache for the Cinematic Prestreaming system to interpret. Once built, you can reference the cache in your sequence to ensure that Nanite and Virtual Texture data streams in more reliably during your cinematic.



We added new camera-related features to Movie Render Queue. You can now render from multiple camera angles in the same shot by enabling Render all Cameras before running your MRQ job.

Orthographic cameras are now also supported, making it possible to render sequences using non-perspective cameras. Currently Path Tracer is the only supported render pass for this option.

We simplified the Movie Render Queue API in a way that greatly reduces the complexity of using MRQ in shipping projects. Now you can simply request a new job from the subsystem, set the configuration for it, and then ask the subsystem to render the job. You no longer need to use queues, manually configure the executor, or set up basic settings on the job such as the world to render and the level sequence as a soft path.

nDisplay



We improved the workflow to provide users the ability to specify arbitrary time-synchronous pixel sources and destinations to ICVFX cameras, nDisplay viewports, and the application window backbuffer. This means, in addition to the native UE 3D scene render, users can now also register IP video sources such as SMPTE 2110, media textures, or live-generated data from hardware capture devices to nDisplay viewports.

We added support for SMPTE-2110 I/O (using Rivermax) to Unreal Engine. Using the new Media I/O Mapping System, nDisplay render nodes can directly stream to LED wall processors that support SMPTE-2110. This also allows a different hardware configuration for nDisplay systems where each inner frustum can be rendered by a dedicated machine. Each inner frustum can then be shared to each machine that renders part of the total image for compositing over the outer frustum. This will allow for improved performance, and linear scalability of cameras as well as more predictable content performance.

Users can now render nDisplay viewports to disk using MRQ. New settings allow users to pick a configuration file and the desired viewports to render at their native and specified resolutions.

You can now quickly launch an nDisplay-enabled project locally, to use for debugging and locally trying out your project on your PC without needing a cluster.

Developer Tools

Default Visual Studio Version

Unreal Build Tool (UBT) now generates the Visual Studio solution file for the latest version of Visual Studio installed, unless you have a Platform SDK installed that does not support the latest version. In this case, UBT generates the Visual Studio solution file for the latest version of Visual Studio that supports the Platform SDK in question. The preferred compiler is Visual Studio 2019.

Clang 13 Support

Clang 13 is now the required version when compiling for Clang-based platforms such as Linux.

Static Code Analysis

Unreal Build Toolnow supports running several different Static Code Analyzers. Static code analyzers use a variety of algorithms and techniques to analyze source code and find bugs without executing the code.

Supported Analyzers:

Default: Uses the default static analyzer for the selected compiler.

VisualCpp: Uses the built-in Visual C++ static analyzer. Only supported for Microsoft Visual C++ (MSVC) based platforms.

PVSStudio: Uses the PVS-Studio static analyzer. Only supported for MSVC-based platforms. This analyzer requires a license, for more information, refer to the PVS-Studio site.

Clang: Uses the Clang static analyzer. This forces the compiler to use Clang for MSVC-based platforms. This analyzer is in Beta.

The syntax for using Unreal Build Tool to run a static code analyzer is:

For example, you can enter the following into the command-line to run the default static code analyzer for the selected compiler with Unreal Editor as the target on a Windows 64-bit system:

For more information, refer to the Static Code Analysis documentation, which includes details about the supported analyzers and additional command line options.

C# Unreal Header Tool

Unreal Header Tool (UHT) has been rewritten using C# and integrates directly with the Unreal Build Tool. The purpose of this rewrite is to:

Improve maintainability.

Decrease build times.

Reduce build farm times.

Remove engine hooks.

The C++ Unreal Header Tool is now deprecated and will be removed as soon as possible, but no earlier than UE 5.2.

There are two reasons to continue using C++ UHT prior to its removal from Unreal Engine along with information about how to continue using C++ UHT:

You use UHT script generator plugins that currently have no C# version.

If UBT detects a script generator plugin being used on a project and a C# version does not exist in the plugin, then UBT will automatically revert to using C++ UHT.

You have local changes to UHT.

In this case, set bUseBuiltInUnrealHeaderTool = false in the UEBuildConfiguration category to disable C# UHT.

In either case, it is important to port C++ UHT changes and script generator plugins to C# prior to C++ UHT being removed from UE. If you need to make changes to C# UHT, you can find the source code in Engine/Source/Programs/Shared/EpicGames.UHT.

We provided a sample C# script generator plugin in Engine/Plugins/ScriptPlugin/Source/ScriptGeneratorUbtPlugin. Furthermore, all existing UHT exporters are written using the same mechanism and are found in Engine/Source/Programs/Shared/EpicGames.UHT/Exporters. Here is a short guide to help:

Create a C# project in the same directory tree as the plugin with the existing C++ script generator plugin. The extension of the plugin must be .ubtplugin.csproj.

In Visual Studio, generate the project files. Your plugin will now be listed in Programs/UnrealBuildTool.Plugins.

Add EpicGames.UHT as an assembly dependency and not a project dependency.

Using ScriptGenerator.cs as a reference, create a class that will contain the entry point for exporting scripts. This class must have the UnrealHeaderTool attribute and the static method must have the UhtExporter attribute.

Lastly, C# generator plugins must support the same defined constants available to build C# sources such as UE_5_1_OR_LATER.

The supplied factory object contains the context needed to export the UE data types. The factory object contains a UhtSession. This UhtSession includes a list of UhtPackages. You can find the data types defined in the headers in the UhtHeaderFiles, which are located within the UhtPackages.

Export files in asynchronous tasks to improve performance.

Export files using the IUhtExportFactory.MakePath and IUhtExportFactory.CommitOutput methods to take advantage of built-in change detection, reference, and verification output.

Use BorrowStringBuilder to use cached string builders.

Avoid temporary objects and strings as much as possible.

Use the IUhtSession.GoWide property for debugging to see if -nogowide was specified on the command line. When present, do not use asynchronous tasks to generate output, but rather call your export code directly as this will simplify debugging.

Audio

MetaSounds (Beta)



MetaSounds, our high-performance graph-based audio system, has several new improvements in 5.1.

We've expanded our library of nodes to provide new functionality, such as pitch shift, grain delay, rerouting, and more. Additionally, we added multichannel audio output support, making it easier for you to create immersive surround sound experiences.

To learn more about MetaSounds, refer to the MetaSounds documentation.

Audio Modulation

The Audio Modulation plugin is no longer a Beta feature and is now fully integrated with MetaSound. This feature provides a generic method for modulating audio parameters. Now, anything can be a modulation source or destination. You can define your own groups of parameters and control them how you want.

Audio Gameplay Volumes (Beta)

Audio Gameplay Volumes are the next iteration in geometry-based audio management and control. Designed as a replacement for the legacy Audio Volumes system, the Audio Gameplay Volumes system provides component-based options for Unreal Audio Engine feature integrations, extensibility, and tighter gameplay integration, including movability and dynamic transformations.

To learn more about Audio Gameplay Volumes, refer to the Audio Gameplay Volumes documentation.

Soundscape (Beta)

Soundscape procedurally generates ambient sounds, such as rustling foliage, chirping birds, and bustling traffic, which are streamed as the player moves around the world. Once set up, the plugin manages and composes these sound systems autonomously and removes the need to manually create them.

Waveform Editor (Beta)



The Waveform Editor is a new tool for viewing and editing sound waves within Unreal Editor. It can trim, fade, normalize, and make other waveform adjustments. Sound wave metadata can even be altered to support loop regions, cue points, and more. These modifications can be saved to a new asset to preserve the original.

UMG / Slate Improvements

UMG Viewmodel (Beta)

The Viewmodel plugin provides a framework that makes it simpler for designers to work independently from programmers when making structural changes to widgets.

Previously, there were two main methods for forwarding data to a widget in UMG:

Attribute binding: The widget defers the value of one of its fields (such as a text field) to a Property or a Blueprint function that returns a value. This implementation was flexible and easy to use, but had performance issues, as it would continually update a widget regardless of whether the property itself actually changed.

Event-driven updates:** Gameplay calls functions that manually update the UI, or the UI updates based on Event Dispatchers or Delegates. This provides superior performance, but requires manual code changes to reflect any changes in the UI.

The Viewmodel plugin provides the best of both methods. After enabling this plugin, you can create a Viewmodel to hold the variables used in your UI, then bind widgets to the properties in your Viewmodel.



A Viewmodel is a separate object that holds copies of a set of variables needed in your UI. Whenever you need to make a change to one of these variables, you update it within the Viewmodel rather than directly in your UI. The Viewmodel then notifies the bound widget in your UI that its value has changed, and pushes an update. This streamlines the process of creating a data-driven UI by eliminating the busywork of creating callbacks and update functions, and provides exposure to programmers separate from the UI itself.

For more information on how to use ViewModel in your projects, refer to the Viewmodel documentation.

Named Slot Widgets



UE 5.1 introduces Named Slot Widgets in UMG. These widgets act as placeholders for other widgets when creating templates. Normally, when you create a child class of a UMG widget, the widgets in its hierarchy are hidden.

Named Slots appear in the hierarchy and can be populated in the PreConstruct event safely, making it easier to preview your template widget with test use cases. Additionally, when you insert a child into a Named Slot, its place within the hierarchy and render order is preserved based on the parent class.

UMG Tool Palette Plugin (Experimental)



We added a new Tool Palette plugin to UMG in UE 5.1. This tool palette provides quick access to commonly used tools, widgets, and interactions. You can enable this plugin in the plugins menu to try it out.

Editor

Better Asset Searching and Filtering

The Outliner and Reference Viewer now support Asset filtering. These filters behave the same as Content Browser filters, and they support advanced search syntax operators.

You can now save an Asset search as a custom filter in the Outliner, Content Browser, and Reference Viewer. Once saved, custom filters, as well as individual filter settings, are available across all streams and projects for the user who created them.

We made the following improvements to searching and filtering Assets in the Content Browser:

The search bar shows a history of your most recent searches.

Filters are displayed in a vertical column by default. You can toggle between the new (vertical) and legacy (horizontal) filter layout from the Content Browser's Settings menu.

The Filter dropdown menu shows a badge when at least one filter is active.

Outliner Improvements

To improve Outliner navigability, headers now stack when you scroll up and down.



We made it easier to find Actors in the Outliner by adding the following features:

You can configure the Outliner to always scroll to an Actor when you select that Actor in the Level Viewport. Enable this option from the Outliner's Settings menu by toggling Always Frame Selection.

When an Actor is selected in the Level Viewport, press F to highlight that Actor in the Outliner.

Parent items of the currently selected Actor are now highlighted even when the current selection is collapsed.

You can now have up to four instances of the Outliner and customize each instance separately.

You can choose which columns display in the Outliner by right-clicking a column header, then clicking a column name to toggle whether to show or hide it.

Reference Viewer Tool Redesign

We redesigned the Reference Viewer tool to support a greater number of Asset references and a greater depth of the reference graph. Reference search now supports a search depth of 50 and search breadth of 1000 Asset levels.

Finding Asset references now leverages Unreal Engine's improved searching and filtering capabilities to give you better control over which types of Assets are displayed in the reference graph.

Asset nodes in the reference graph are color-coded by Asset type and can be customized to display additional information, such as the Asset's thumbnail and its file path.

For a rundown of all the Reference Viewer improvements in Unreal Engine 5.1, refer to the Reference Viewer documentation.

Python Type Hinting

The Python plugin can now generate the stub file with type hinting. Type hints will appear in your Python IDE auto-completion menu. To enable type hinting, from the Unreal Editor menu bar, go to Edit > Editor Preferences…. From here, navigate to Plugins > Python. Enable Developer Mode and choose your desired Type Hinting Mode. This generates a Python stub file you can add to the IDE of your choice. For more information on how to enable type hinting and the various type hinting modes available, refer to the documentation for Setting Up Autocomplete for Unreal Editor Python Scripting.



Localization Pipeline Automation Improvements

The Localization Commandlet has the following improvements in UE 5.1:

In previous versions of UE, the localization pipeline needed the build system to run through each step of the build process before handling localization. This meant, to see errors and warnings for localization, users needed to rebuild their entire project. In UE 5.1, the localization commandlet will run a preflight that gathers localization files, then checks them for errors and warnings. This eliminates the need to wait for a full build to find localization errors, greatly improving the expediency of debugging localization. This improvement is available through the UAT localization commandlet.

Whereas previous versions of UE used only .txt files for word count and namespace conflict reports, UE 5.1 now supports using .csv files, providing improved clarity and organization of information. This format is enabled by default in UE 5.1, but you can change this by going to your engine's install directory, navigating to Engine/Config/Localization/Engine.ini, and setting the ConflictReportName and WordCountReportName fields to use the .txt file extension instead of .csv.

UE 5.1 adds several quality-of-life changes to handling localized text in code. Use #define LOCTEXT_NAMESPACE and #undef LOCTEXT_NAMESPACE to mark sections of code as belonging to a specific localization namespace. Then, you can use the LOCTEXT macro in between those macros to define a localized text entry with a key and a string of default text.

In the above example, the key TerrainDefaultRuleDesc with the default text Top would be added to the Paper2D namespace. Additionally, localized text now supports using escape characters.

Curve Table Editor

You can now edit Simple Curves and Rich Curves in the Curve Data Table Editor. When creating a Curve Table, you can open the editor to edit curves in the table or curve view without needing to go back to the external program you created them with.

You can create Curve Tables in the Content Browser by navigating to the Miscellaneous section. You can select Rich Curves or Simple Curves by selecting the type of interpolation.



Creating a new cubic Curve Table creates a Rich Curve table.



Creating a constant or linear Curve Table or importing a spreadsheet creates a set of Simple Curves you can then edit inside Unreal Engine.



When editing Simple Curves, we maintain the constraints that all curves must have identical key times, so keys can't be moved horizontally, and adding a key adds a key to all curves.



The editor now supports renaming and removing curves along with improved rendering of constant curve tables.



Along with editing curve key values, new toolbar enhancements include the ability to retime, add or delete key columns, and reimport.

Virtual Assets (Beta)

Virtual Assets provide you with faster and more efficient methods for syncing data among all members of your team as your project begins to grow in size.

When working with Assets, users only need a minimal amount of information about their assets to display them in the editor. For example, a Texture may need a thumbnail image and editor properties (such as coordinates and scale), however the bulk of the .UAsset file for textures is pixel data, which may not be needed and would be wasteful to have your team sync to your project.

These assets have been split into core asset metadata portions that exist where the assets are in your source control and split the bulk data into a separate location. If a user requires the bulk data, they will be able to sync on demand, in source control.

The features include:

The functionality to virtualize your entire project at the same time, by package path, by specific asset types, or by specific assets.

Support for Texture and Audio Assets.

New Import Framework

Unreal Engine 5.1 features a new Import Framework designed to provide users with a high performance, customizable asset pipeline. The framework works in the editor and at runtime, as well as provides scripting support using Blueprint and Python.



This new framework is format agnostic and works using the following steps:

Translator: Converts the file format to an intermediary graph structure in Unreal Engine.

Factory: Generates actors and assets from the pipeline output.

Pipeline: Processes the graph structure into a description of Unreal Engine Actors and Assets.

The framework currently supports the following formats:

Image formats: BMP, DDS, EXR, HDR, JPG, PCX, PNG, PSD, TGA, TIFF

Light format: IES

3D models: GLTF, OBJ

Material: MTLX

In this initial release, MaterialX is import-only, and only supports translation of materials using the standard_surface shading model.

File formats previously supported by Unreal Engine are still supported using the Legacy framework.

For more information, refer to the Import/Export Interchange documentation. (Link TBD)

Modeling and Sculpting Tools

UV Editor (Beta)

Introduced as Experimental in 5.0, the UV Editor has moved to Beta in 5.1. Previously, the UV Editor was accessible through a plugin. Now, you can quickly access the editor in three ways:

Use the UV panel in Modeling Mode.

Right-click your mesh within your Level.

Right-click your mesh in the Content Browser.

UV creation and editing continue to improve, not only with the UV Editor enabled by default but with the following:

We added the Transform tool to support more complex transform behaviors than the gizmo can provide. This control includes chained scale, rotate, translate, and a variety of pivot options to adjust the relative motion of the transforming UVs.

UDIM support is now active for the Layout and Unwrap tools.

You can pin existing UV islands to the UDIM they currently occupy while undergoing layout or unwrapping operations.

The Distribute tool creates automatic spacing between UV islands based on bounding box edge rules.

Manual distance adjustments are now supported, giving users precise control over the spacing between UV selections when performing the various distributions.

A new mode for minimally removing overlap is active. This attempts to move selected regions apart, if needed, to prevent their bounding boxes from intersecting. The mode also works with the new manual distance controls, allowing separation distance customization.

The Split tool now supports whole triangle regions, vertices, and edges. We are providing quick selection and segmentation of existing UV islands.

The Align tool includes additional grouping logic, where individually selected islands can be aligned independently of each other and for the selection to be aligned as a group, preserving relative positioning.

The Alignment and Distribute tools now support vertex and edge selections for more precise positioning along boundaries and internal lines. Accordingly, the tools support treating individual vertices as independent entities, creating the finest scale per vertex alignment and distribution.

The UV Editor's 3D Viewport supports camera snapping to selection.

The new camera focus button can initiate this in the Viewport's toolbar or using the default camera snap keybind (Alt+F).

Use the AutoUV tool to create UVs based on existing mesh polygroups.

An option exists to automatically arrange the resulting islands into UDIM tiles according to their origin PolyGroup.

Many of these improvements mimic traditional artists and drawing applications. To learn more, refer to the UV Editor documentation.

Pattern Tool

We expanded the artists' modeling toolkit with the addition of the Pattern tool. Tile one or more selected meshes along a Line, Grid, or Circle oriented on a movable 3D plane. Various parameters are available for each tiling pattern, including interpolating translation, rotation, and scale. Output the resulting pattern as a merged Dynamic Mesh, per-element Actors (static or dynamic), or an instanced Static Mesh component.

Animation

Animation Synthesis

Using the Machine Learning (ML) Deformer system, users can now create their own ML Deformer models to approximate high-quality mesh deformations in Unreal Engine.

Packaged as a plugin, the ML Deformer Framework uses the existing Neural Network Inference (NNI) framework as well as a reusable asset type and editor, that you can use to train, inspect, and debug ML Deformer models that deform meshes by evaluating the neural networks at runtime.

The ML Deformer system also provides integration with the Deformer Graph system that you can use to edit and fine-tune generated mesh deformations.

Additionally, you can enable the new Neural Morph Model plugin to use a prefabricated high-performance deformer model to train high-quality deformations on your characters with a low memory footprint.

The Neural Morph Model is a replacement for the Vertex Delta Model. Requiring only a few megabytes of additional data per character and fast hardware performance, the Neural Morph Model enables the use of high quality ML-based mesh deformation models on modern platforms.

In addition to the introduction of the ML Deformer framework and the Neural Morph Model, the ML Deformer asset editor has received several performance and quality-of-life improvements.

For more information, refer to the ML Deformers documentation.

The Deformer Graph plugin features an Editor that allows users to create and edit Deformer Graph assets to customize complex mesh vertex deformation behaviors for any skinned mesh.

With the Deformer Graph Editor you can use a combination of custom Blueprint logic and HLSL (High-Level Shader Language) scripting to create and customize mesh deformer systems that modify mesh vertex data using dynamic inputs at runtime. The Deformer Graph is a powerful alternative to traditional linear skinned meshes using Morph Targets or Cloth simulation to create intricate mesh deformations at runtime.

For more information, refer to the Deformer Graph documentation.

Physics Control Component (Experimental)

The Physics Control Component is a plugin that provides a means for you to add simple, intuitive, and powerful physically-based controls to a Blueprint. With these physics controls, you can take advantage of the emergent physical motion of static and skeletal meshes, while still retaining artistic and gameplay control.

With the Physics Control Component you can easily create controls that affect all or only part of a Skeletal Mesh. For example, you can create physics controls to operate in world space, for situations where you want to see some emergent motion and still retain a lot of control. You can set physics controls to operate in parent space to create reactive muscle-like limb behaviors. Physics controls can even operate between any local or external physical bodies.

Additionally, you can direct the physics controls to use animations, procedural targets, or a combination of both.

To see example applications of the Physics Control Component, such as full body effects, secondary motion, and hit reactions, refer to the Physics Control level in the Content Examples project.

Animation Gameplay

The Pose Search plugin now features the new Motion Matching Animation Blueprint node, a dynamic alternative to State Machines, you can use to build character locomotion animation systems.

Using a Database asset containing the character's locomotion animations, the Motion Matching node makes informed animation pose selections from the set of stored animations, to match the character's Movement Model at runtime. Using the Motion Matching node, a high-quality, responsive character locomotion animation system can be set up quickly and efficiently, without the need for complex State Machine logic.

To increase a character's Motion Matching animation fidelity and quality, you can simply add more animations to the characters Motion Database or Database Set asset. With each additional animation, the Motion Matching node is able to draw from more data to more accurately and effectively select quality output poses to match the player's movement model.

The Pose Search plugin also comes packaged with a custom integration of the Rewind Debugger you can use to record and analyze the Motion Matching pose selection process, to see which poses were selected, which poses were not selected, and why. You can then use this information to adjust and fine-tune the selection process to fit any project's needs.



Animation Runtime

With a refreshed user interface, the Rewind Debugger now features a timeline of animation data tracks that display visual graphs of information, that you can use to see vital updates and changes in animation data while debugging a character's animation system.

The Rewind Debugger timeline features a track of animation data for each of the debug subject's components or child objects. You can use the Rewind Debugger to analyze and debug Animation Sequence playback, Notifies, Curves, Blend Weights, and more. Each track of animation data can also be selected within the timeline to populate the new Rewind Debugger details panel with more precise readouts of the selected animation data for debugging.

Additionally, the Rewind Debugger now features Pose Watch integration, that you can enable in the characters Animation Blueprint to observe the output pose of any blueprint node within the recorded segment of gameplay.

For more information, refer to the Rewind Debugger documentation.

Sequencer

To assist with the simultaneous movement and scaling of multiple keyframes, you can now use Layer Bars to move keyframes and sections in Sequencer. Layer Bars are hierarchical and appear on Actor, Component, and Folder Tracks. Manipulating them at any of these points will appropriately manipulate other Layer Bars within, making it easier to retime keyframes on your Actors without needing to expand each track.



Key Bars have been added to Sequencer as an easier way to retime neighboring pairs of keyframes. Selecting and dragging the line drawn between two keyframes will move both keys relative to each other, which can save time from multi-selecting each key individually, and preserving custom curves between these keys.



You can now dynamically constrain your Sequencer objects in a variety of ways using Unreal Engine's new Constraint feature. Similar to constraining methods in other animation tools, you can constrain entire transforms with the Parent Constraint, or along individual channels with Translation, Rotation, Look-At, or Scale Constraints.

Constraints make it easier to dynamically and non-destructively attach your Objects, Actors, and Control Rig Controls to each other in your Sequencer animation.

Control Rig

To improve consistency with other similar Blueprint tools, we renamed Setup Event to Construction Event. We also added new Spawn nodes to make procedural rig creation in the Construction Event faster and easier.



We made several quality of life improvements and UX changes to Control Rig to improve your workflow.

The Control Rig Editor now supports multiple graphs, which provide a means for you to organize and partition rig logic into separate graphs.

You can now add Custom Events to your Rig Graph (called User Defined Events), which provide a means for you to create and execute your own rig events.

You can now show Controls overlaid on top of geometry, similar to "X-Ray" settings in other software, by enabling Show Controls as Overlay in the Animation Mode panel.

We added Proxy Controls, which are a new type of Control that can be linked to other Controls in a Driver / Driven relationship.

You can now attach Python commands to pins in the Control Rig Editor, enabling automated setup of nodes.



IK Rig and Retargeter

We added new properties available when you are using the IK Retargeter to control the length, width, and splay of IK Goals. In most cases, you can use this to adjust the stride and overall stance of a retargeted character.

We provided new tools and workflows to improve retargeting results from vastly different characters. You can now reduce foot sliding and other similar problems by using Speed Planting workflows. To learn more about this workflow, refer to the Speed Planting documentation.

We made several user interface and user experience changes to the IK Rig and IK Rig Retargeting editors to improve workflows, layout, and tool behavior. Notable changes include:

Both the source and target skeletons can now be seen in the Viewport, along with the skeleton hierarchy in the Retarget Editor. Additional filters, search bars, and hierarchical sorting can now be used to improve your ability to isolate and edit chain properties.

Certain properties, such as the IK properties, are now disabled if the retarget chain does not require them. We also added a simpler UI for properties, including property reset indicators for properties with non-default values.

Retargeting poses can now be saved and imported, making it possible to share custom poses on your project.

We improved retarget pose editing by allowing numerical entry of bone rotations for easier, more precise control.



DMX



MVR is a key format for the transport of DMX fixtures and patching information in the live events and film/TV industries. This support allows for collaboration with teams using CAD applications such as Vectorworks, and lighting consoles such as the Grand MA3.

In order to import Vectorworks files into UE for Live Events or VP stage previs, we added support for GDTF and MVR to the Datasmith workflow.

MVR provides DMX fixture transforms, patching information and GDTF signature files, while Datasmith imports common mesh and texture data.

We are improving bi-directional workflows between Unreal Engine and DMX, where Unreal Engine triggers DMX events and DMX consoles are able to control Unreal Engine Actors. This supports the growing collaboration between users of Unreal Engine and members of production teams using DMX-based lighting consoles.

Previously, DMX support was enabled by means of the DMX plugin, and the send / receive functionalities were only enabled in Play / Preview / Game or Packaged modes. We added support for being live while in editor, enabling users to drive in-editor elements using DMX.

We added numerous UI tweaks and workflow improvements to the DMX Pixel Mapper, in particular the ability to set the 2D fixture mapping grid using a previously-imported MVR dataset layout.

Unreal Cloud Services

Pixel Streaming

We introduced support to pilot virtual cameras (VCams) using remote Pixel Streaming sessions. This is achieved using the new Pixel Streaming Output Provider, which is selected as an output provider for a VCam actor.

We also added experimental support to the Virtual Production LiveLink iOS app to stream and control the virtual camera on iOS devices using Pixel Streaming. In the past, controlling virtual cameras using the LiveLink app induced a noticeable level of latency, but Pixel Streaming allows us to provide much lower latencies when driving virtual cameras. Support for this workflow is experimental and not yet ready for production.

The Pixel Streaming frontend, signaling server, SFU, and relevant scripts have all been moved into their own top level Github repository decoupled from the Unreal Engine release cadence. This makes it possible for us to update these components more frequently without being locked to the Unreal Engine release cycle. The repository can be found here:

https://github.com/EpicGames/PixelStreamingInfrastructure

For Pixel Streaming users going forward, there should be nearly no change in your workflow. When you package your application, there will be a small script bundled with your application that, when run, will download the correct version of the Github release based on your engine version. If there are browser-breaking changes or issues between releases this repository will provide a mechanism for us to address these outside of the release windows. Additionally, we hope to encourage Pixel Streaming users to report frontend / server issues to this repository where we can collaborate with our users more easily.

In 5.1, we introduced support to decode Pixel Streaming video streams in-engine. This makes it possible to provide streaming between multiple applications and potentially between editors. This feature is accompanied by new blueprint nodes to set up stream playback in the engine without writing any C++ code. Currently, you can play back streams using a special material.





In the past, Unreal Engine users could stream packaged Unreal Engine applications and games. Due to the increase in remote working and remote collaboration, we introduced experimental support to Pixel Streaming to stream the entire Unreal Editor itself. Streaming the editor can be tested out using the new Pixel Streaming toolbar now visible when Pixel Streaming is enabled. Or, if you are launching in an unattended setup, you can launch with -EditorPixelStreamingStartOnLaunch. Running editor streaming works the same way as normal Pixel Streaming, and the signaling server is still required.

There are some limitations around the editor experience. For example, currently multi-monitor streaming is not yet supported. In general this feature is an experimental preview, we intend to expand the feature set and user experience in subsequent releases; however, users should be advised to take caution if building against this feature as it will likely change.

Platform

Unreal Editor on Apple Silicon (Experimental)

Previous versions of Unreal Engine supported building projects for Apple's ARM-64 architecture, but Unreal Editor itself was not natively built for it and depended on the Rosetta instruction translator when running on Apple Silicon devices. UE 5.1 rolls out an experimental version of native support for Apple Silicon in Unreal Editor, meaning that M1 devices and later should see improved performance when running the editor.

This support is not available in builds distributed through the Epic Games launcher. Instead, you need to build Unreal Engine from source on your Apple Silicon-based Mac with Xcode. Building UE with Xcode on Apple Silicon platforms will default to building the experimental native version, with the target device listed as My Mac. To build the Rosetta version you need to change the target device to My Mac (Rosetta).



Note that Marketplace plugins are unlikely to work with this configuration, as they are not arm64-compatible yet.

Linux IDE Workflow Improvements

In UE 5.1, we improved support for VS Code as a default option for IDEs in Linux. Error handling and messaging is also present when you have multiple IDEs and the code accessor fails to find the correct one.

Google Stadia Support

In UE 5.1, we have deprecated support for the Google Stadia platform. We will remove Stadia support in UE 5.2.

XR

Improved OpenXR Support

We added support for the ResetOrientationAndPosition interface function and Pixel Density, experimental support for Screen Percentage with Temporal Upscale, along with stability improvements and bug fixes.

Enhanced Input (Beta)

In 5.1, you can use Enhanced Input to create complex input handling for OpenXR projects. Enhanced Input now supports OpenXR-compatible controllers and head mounted displays.

We updated the VR Template to include examples of how to use Enhanced input for your XR projects.



Rendering Feature Parity (Experimental)

We added initial stereo support for Nanite, Lumen and Temporal Super Resolution. Currently this is only supported on PC while using the Deferred renderer.

OpenXR Support for HoloLens

We removed the Windows Mixed Reality Plugin for Unreal Engine and moved to OpenXR for the HoloLens. To develop projects for HoloLens in 5.1, install the Windows Mixed Reality OpenXR Runtime and the Microsoft OpenXR Plugin.

Refer to the OpenXR Prerequisites documentation for more information about setting up your HoloLens project with OpenXR.

Deprecated Oculus VR and SteamVR Plugins

We deprecated the Oculus VR and SteamVR Plugins in 5.1. Use the OpenXR plugin and the appropriate OpenXR runtime for your Oculus or SteamVR projects.

Refer to the OpenXR Prerequisites documentation for more information about installing the OpenXR plugin and runtimes.

Mobile

Development Requirements and Compatible Hardware For Mobile

The following are the supported OS versions and minimum hardware for mobile devices supported by Unreal Engine 5.1. For additional information about required SDKs and IDEs, refer to the Platform SDK Upgrades section.

UE 5.1 supports iOS, iPadOS, and tvOS devices running OS version 15 or later. The following are the minimum compatible device models:

iOS 15

iPhone 6S or later

iPod Touch 7th generation

iPadOS 15

iPad 5th generation or later

iPad Air 2* or later

iPad Mini 4* or later

iPad Pro (all models)

tvOS 15

Apple TV HD*

Apple TV 4K (first generation)

Apple TV 4K (second generation)

*Apple A8/A8X-based devices (iPad Air 2, iPad Mini 4 and Apple TV HD) require a project setting to enable support.

For information about the required SDKs and MacOS versions, refer to the SDK Upgrade Notes below.

UE 5.1 supports Android devices meeting the following specifications:

Android 8 or higher running 64-bit Android

64-bit Arm-based CPU

Compatible GPUs

Mali T8xx, G71, G72, G76, G77, G78, and G710 series

Adreno 5xx, 6xx, or 7xx series

PowerVR GM9xxx series

Xclipse 920

Compatible Graphics APIs

OpenGL ES 3.2

Vulkan supported on Android 10 or later devices with compatible drivers

For information about the required SDK versions, refer to the SDK Upgrade Notes below.

The Deferred Shading Mode for the Mobile Renderer is now Production-Ready

The Mobile Renderer Deferred Shading Mode, introduced in UE 4.26 as an Experimental feature, is now production-ready in UE 5.1. This mode is optimized for tiled GPUs common in mobile devices, and enables several high-quality lighting features not supported in the mobile forward rendering path, such as light functions, IES profiles, and lit decals. All devices supported by UE for mobile can run the deferred mode, including both Vulkan and OpenGL ES modes on Android.

Additionally, the Mobile Deferred path now supports the following rendering features previously only operational on mobile using the forward rendering path:

Distance Field Shadowing

Spotlight Shadows

Screen-Space Ambient Occlusion

The following features are supported when not using pre-computed lightning:

Skin shading model

Hair shading model

Thin translucent model

DirectX Shader Compiler Used for All Mobile Paths

UE 5.0 set DirectX Shader Compiler (DXC) as the default shader compiler for Vulkan and GLES. In UE 5.1, all mobile feature levels now use DXC, including Metal. This improves consistency and feature parity between each rendering path and opens up the resources of the DXC community to all mobile projects in Unreal Engine.

Mobile Rendering Improvements

We added the following features and improvements to the mobile rendering pipeline in UE 5.1. These features are focused on improving rendering optimization.

UE now supports ARM's Adaptive Scalable Texture Compression (ASTC) compression standard as an option.

In UE 5.1, we added the option to specify the precision mode of materials and material expressions for mobile devices. The three available modes are:

Full-precision for every float

Full-precision for material expressions only

Half-precision for every float

The main new addition is the ability to use full-precision for material expressions while engine shaders use half precision. This is generally more reliable than globally setting half-precision, as we have internally determined which engine shader variables are safe to use as half-precision.

You can find the Mobile Float Precision Mode setting under Project Settings > Engine – Rendering > Mobile.



You can also configure it on a per-material basis.

UE 5.1 adds support for clustered local lights and reflections to the Mobile Forward and Mobile Deferred rendering modes.



Previously, UE would build PSO caches as single, monolithic caches for entire applications. This consumes a great deal of memory, as applications would load PSO caches for assets the user may not even see during gameplay, and the compilation process was also time-consuming.

In UE 5.1, PSOs are broken into caches on a per-asset basis during the cooking phase, and then the PSOs are loaded only for assets used. This reduces the need to recompile PSOs for assets that have not changed, and reduces the memory footprint for loading them.

Both Android OpenGL and Vulkan RHIs now have separate PSO precompiling processes (Android services). Running the PSO precompile operations on separate processes solves many concurrency issues with graphics drivers, and delivers more stability and typical performance gains of between 3-5x precompile time savings.

Platforms with different rendering settings can now have their settings better represented in the in-editor platform preview. Previously, a single shader platform was used for all mobile previewing, meaning features such as Distance Field Shadows could not be accurately previewed if they were enabled on one platform but not another. Each preview platform now uses an independent shader platform to remove this limitation.

Scalability and device profile console variables are now applied in the editor when previewing mobile platforms.

UE 5.1 adds support for Android NDK 25, a new long-term support release. This includes a new LLVM 14 toolchain with optimizations for faster code, a roughly 15% reduction in compilation times, and smaller binary sizes.

Gameplay Framework

Blueprints

Similar to the Blueprint Nativization tool, the Blueprint Header View is a new method you can use to quickly convert Unreal Engine Blueprint Classes and Blueprint Structs to C++ code.



During the conversion process the Blueprint Header View creates C++-style declarations for all of your Blueprint's variables, functions, actor components and event dispatchers.

To start using the Blueprint Header View in your project, you can right-click a Blueprint Class or Struct in the Content Browser and select Preview Equivalent C++ Header from the context menu.



Using the new Blueprint Namespace feature you can selectively organize a project's Blueprints to only load relevant assets and content when opened in the editor. By delegating content using Namespaces, complex Blueprints can be loaded and presented faster when opening a new instance of the Unreal Engine editor, and large amounts of content can be organized to increase user workflow efficiency.



Additionally, when using Namespaces, you can filter Blueprint content using type pickers and the right-click context menu to reduce item list load times, keeping workspaces organized and functional.

Within a Blueprint's Class Settings, you can set and reference a Blueprint's assigned Namespace using the Blueprint Namespace property in the Details panel.



For more information, refer to the Blueprint Namespace documentation.

Enhanced Input

The Enhanced Input plugin provides you with a new feature-rich method of creating and managing player inputs and controls.

Using Input Action assets, you can set and define player input methods for individual inputs or axis controls. Input Action assets are collected and managed within Input Mapping Context assets, that provide you with more comprehensive control over your project's player inputs and behaviors, creating dynamic systems that can adjust contextually at runtime.

Additionally, the Enhanced Input systems help you organize and manage your player inputs as projects grow and scale, with robust features that assist with the creation and management of online, local, and split-screen multiplayer input systems.

For an example of the Enhanced Input system in action, refer to the Lyra sample project.

For more information, refer to the Enhanced Input documentation.

Mass

The Mass Entity system received significant improvements for UE 5.1 and is now considered a Beta feature. We expect further major changes to Mass's API and we are committed to continuous development of the entire Mass framework.

We moved Mass Entity's shared fragments from the Archetype-level down to the Chunk-level, to limit archetype fragmentation.

In addition, we separated the entity-managing parts of the Mass Entity Subsystem into a new type: Mass Entity Manager. This promotes the creation of isolated entity pools in custom use-cases, for testing purposes, and others.

We turned on multi-threaded execution of Processors hosted by the Mass Processing Phase Manager by default for all targets, other than dedicated servers.

MassEntityQuery can now express subsystem requirements, which is a crucial element of the multi-threading safety of Mass processing. In addition, queries owned by Processors are now used to determine additional inter-processor dependencies critical to ensuring threading safety.

Mass Entity introduces the Mass Debugger UI Tool in UE 5.1. This tool provides visibility into selected Mass Entity Manager archetypes by showing their composition and Entity counts.

The tool also shows which archetypes are being processed by specific Processors, and it visualizes the Mass processing graphs owned by the Mass Processing Phase Manager.

Artificial Intelligence

Smart Objects

In UE 5.1, Smart Objects received general stability and workflow improvements that make it more convenient to set up Smart Object Definitions.

The API is consistent compared to UE 5.0, which allows for backwards compatibility when migrating projects.

One of the main use cases for Smart Objects is the ability to create meaningful gameplay interactions during gameplay. For this reason, Smart Objects received initial experimental support for the Gameplay Interactions plugin. We plan to continue improving support in future versions, with the goal of embedding Gameplay Interactions into Smart Objects that will combine State Trees and Contextual Animations with replication support.

With the UE 5.1 release, you can now use the Environment Query System to select the best matching Smart Object for an AI Agent or player in the Level.

State Tree



State Tree is Unreal Engine's general-purpose hierarchical state machine introduced in UE 5.0. For UE 5.1, State Tree received significant improvements and is now considered production ready. As part of this process, State Tree received significant API changes compared to 5.0.

This update includes improved Actor-centric and Blueprint-centric workflows. You can now use State Trees with a Blueprint-only workflow.

You can now parameterize State Trees, which allows you to use the same State Tree with different data. The update also includes added support for more complex condition-based expressions.

Improvements to State Tree Events provide a simpler way of triggering State changes based on external logic.

In addition, this update simplifies the usage of Tasks and Conditions within the State Tree. It is now easier to connect Conditions to Tasks, without using Evaluators. This creates a simpler, more streamlined State Tree. For example, you can now access Actor data directly, without having to use Evaluators.

In UE 5.1, State Trees added the concept of Sub-Trees. With Sub-Trees, you can reuse common parts of a State Tree. This improves reusability and provides an intuitive way of building complex State Trees.

Sub-Trees are similar to Blueprint Macros, where you can create a Sub-Tree with a given name and define its inputs. You can call Sub-Trees directly inside the State Tree by name.

The State Tree internal storage received several optimizations, which resulted in a significant reduction of memory usage per active State Tree. At runtime, only active Tasks are stored in State Tree memory. In addition, large properties in the State Tree can be bound as references, instead of full copies compared to UE 5.0.

These improvements resulted in memory usage reduction of about 75% in the City Sample when approximately 35,000 State Trees are running during gameplay.

Navigation Mesh in World Partition

Unreal Engine 5.1 includes initial experimental support for dynamic Navigation Meshes (Navmesh) when using World Partition.

It is now possible to use the Dynamic mode as the Runtime Generation for the Navigation Mesh to build a world partitioned dynamic NavMesh in a world partitioned map.

In this case, changes to the Navigation Mesh are ignored for objects that are loaded and unloaded which are part of the base Navigation Mesh. In addition, dynamic tile building is limited to the loaded space when using a World Partition dynamic Navmesh.

This update includes improved support when using Fixed Tile Pool Size with World Partition. You will now receive a warning when adding Navmesh tiles if they cannot be added because the tile limit has been reached. In addition, the Fixed Tile Pool Size limit is ignored when building navigation with the UWorldPartitionNavigationDataBuilder commandlet, allowing for faster builds.

The navigation data is now externally packaged, which means building a world-partitioned Navmesh does not dirty the main map anymore.

In addition, when building a normal Navmesh in a World Partition map, the entire map is now loaded automatically before building the Navigation Mesh.

Physics

Scene Queries and Rigid Body Simulation Performance

Unreal Engine 5.1 includes a number of performance improvements to both the rigid body and scene query functionality. Below we show comparisons between test builds of UE 5.0 and the UE 5.1 release.

We tested many different examples with the updates to UE 5.1 and focused on the worst performing examples from UE 5.0. The first example is a tumbler test where we placed 512 dynamically simulated convex objects into a spinning convex object. Below shows this result where the UE 5.1 test is now 50% faster.



The second example is a test with complex terrain, 100k static objects placed in the world, and 512 dynamic convex objects dropped onto the heightfield terrain. Below shows the result of raycasts against this map where the performance of Unreal Engine 5.1 is now twice as fast as Unreal Engine 5.0.



Fluid Simulation

Unreal Engine 5.1 includes improvements to its turbulence model and small scale forces. These improvements make it easier to add additional detail to the leading edges of the simulation. This can make the simulation look more natural as the shapes will be displayed more prominently.

No Small Scale forces compared to with Small Scale forces.



We added a new Tricubic Interpolation mode which you can use to add extra details without increasing the overall resolution of the simulation. This results in a more detailed simulation at a similar cost to simulations in a previous version of Unreal Engine.

Unreal Engine 5.1 includes several improvements to the memory consumption of fluid simulations. This results in the ability to fit higher resolution simulations in the same memory budget compared to UE 5.0.

Destruction

Chaos Destruction has received significant improvements in Unreal Engine 5.1.

The Fracture Hierarchy received the following updates:

Parent clusters now stack automatically when scrolling through the bone list.

You can color the hierarchy by level to improve readability.

We introduced a new Column Mode, which displays contextual information based on the following options:

State and size: Displays the relative size, initial state, and anchoring information per bone.

Damage: Displays the runtime damage information per bone. This helps artists tune damage thresholds for the asset.

Removal: Displays the remove on break settings per bone.

Collision: Displays information about the imported collision from the original Static Mesh.

We added a new run-time Damage Watcher to the Fracture Mode in 5.1. You can enable the Enable Runtime Data Collection option under the General Settings and click Simulate to record the damage results.

The damage taken per bone is displayed under the Damage Column Mode. The damage threshold and which bones broke (if any) is also displayed.

The Unreal Engine 5.1 update includes improvements to several Fracture Mode tools. You can learn more about these tools by reading the Destruction documentation and following the available Destruction Learning Path.

We added a new GeoMerge tool to merge selected pieces of geometry in a Geometry Collection. The tool formerly known as GeoMerge is now TinyGeo, to indicate its main intended use of cleaning up tiny pieces of extra geometry.

New convex hull generation settings enable you to balance between the accuracy of the generated hulls and their overlap with neighboring hulls.

Default convex generation settings (applied to all new or reset geometry collections) can now be set in the Fracture Mode project settings.

The Validate utility is now a modal tool with checkboxes to control exactly what it will validate and fix. It can now optionally fix single-child clusters, which are not desirable in simulation.

The Selection tools now include buttons to select all leaves or all clusters at the current view level.

The Auto Cluster tool now includes clustering by Fraction of Input, greatly improving iteration speed when reducing hierarchies.

The new Avoid Isolated option ensures that clusters always contain more than a single transform.

The Mesh Paint mode now supports Geometry Collections. Users can now paint vertex colors and textures on fractured geometry.

In addition, vertex colors now propagate on new vertices generated by fractures, providing more consistent behavior of Materials using them.

It is now possible to use collision from the original Static Mesh used to build a Geometry Collection. This provides fine customization of collisions, especially for non-convex shapes.

We improved the existing removal on sleep feature and introduced a new remove on break feature. Here are the differences between the features:

Remove on sleep:

We added new parameters to provide a means to remove slow moving pieces as well.

Partially broken clusters will now crumble to release smaller pieces to be eventually removed.

Remove on Break:

It is now possible to remove pieces after they break off. You can set these parameters on a per-bone basis, and you can set the cluster to crumble instead of being removed.

A new Connection Graph method is now available providing more precise connections and reducing issues where pieces would remain floating in mid-air.





A new damage propagation system is available, providing for more predictable and controlled breaking behavior. You can parameterize this at the instance level, and it offers controls for break-induced and shock-induced damage propagation.

We added a new set of blueprint functions that can act on specific pieces of a Geometry Collection. Events and trace queries can now return an Item Index that can be used in functions to query the level of a fractured piece, apply internal and external strain, apply forces, or even request a cluster to crumble.

This allows the user to be very precise in targeting parts of the Geometry Collection without the need of a Field.



UE 5.1 includes several performance improvements, both at runtime and during the authoring process.

Runtime: We made several optimizations to provide a means for a larger number of Geometry Collections to be placed in a Level.

Authoring: We optimized a number of tools in the Fracture Mode for a large number of Geometry Collections. In addition, fracture tools now display a progress bar with the option to cancel the operation during lengthy computations.

Cloth Simulation

Cloth simulation received several improvements in UE 5.1.

You can now record and play back cloth simulation within Sequencer.



We added a new Pressure control to the cloth configuration, as well as a new Set Pressure function in the Blueprint Chaos Cloth Interactor. These controls can add constant pressure force to each triangle of a simulated cloth.

You can modulate the effect across the mesh using the Pressure paintable mask. The pressure force is always applied in the triangle's normal direction, so using a negative value will push the triangle in the opposite direction.



We added a new buckling feature to the Bending Element constraint. This feature allows the Bending Element constraint to weaken, or strengthen, depending on the Buckling Ratio and Buckling Stiffness parameters. These parameters provide users with better control over the cloth material's creases during simulation.

Once the element has bent, such that it has folded more than this ratio from its rest angle ("buckled"), it switches to using the Buckling Stiffness, instead of the Bending Stiffness. When the Buckling Ratio = 0, the Buckling Stiffness is never used. When the Buckling Ratio = 1, the Buckling Stiffness will be used as soon as it is bent past its rest configuration.

Bending will use the Buckling Stiffness instead of Bending Stiffness once the cloth has buckled, that is, bent beyond a certain angle. Typically, Buckling Stiffness is set to be less than Bending Stiffness. The Buckling Ratio determines the switch point between using Bending Stiffness and Buckling Stiffness.



You can activate this feature by enabling the UseBendingElements checkbox in the configuration.

In UE 5.1, cloth simulation received several overall improvements to self-collision.

There is now an additional self-collision resolution step available through the Use Self Intersections parameters. In addition, self-collision friction now has its own Self Collision Friction parameter.

You can adjust the self intersection resolution to correct any cloth intersections not handled by collision repulsions.

We added a new Self Collision Friction parameter to the cloth simulation. This parameter refers to the friction coefficient for cloth-to-cloth interactions.

A small value results in cloth sliding smoothly over itself. The bigger the value, the more friction will be applied to the interaction, and the less the cloth will move around its points of contact with itself.



In UE 5.1, a new Nearest Neighbor Model plugin is available. This plugin provides tools to create in-game cloth with rich folds and wrinkles, with a relatively small runtime overhead and memory footprint.

In the plugin editor, you can train a neural network that finds the nearest neighbor in a small pre-simulated data set (usually between 50 to 100 frames) for any given pose. The nearest neighbor is then used to transfer geometry details onto the cloth of the given pose, resulting in a high-fidelity runtime simulation.

Niagara

GPU Ribbons

Ribbons are now supported on the GPU. In previous versions, the Ribbon Renderer could only be added to a CPU emitter. Depending on the needs of your game, and the features you want to use, you can now choose whether to render on the GPU or the CPU.

Scalability Mode

Turn on Scalability Mode in the Niagara Editor to preview different scalability settings. By doing so, you can fine-tune your effects to play on different platforms. Scalability settings have been removed from the default view, and added to Scalability Mode for better clarity.



Emitter Versioning

Starting in 4.27, for those creating custom modules, you could use versioning to push out new modules to a team without breaking any existing effects.

5.1 now adds the same functionality to emitters, so you can version an entire emitter to deploy it to a team. Versioning lets you update or modify your templates without creating new assets or losing existing behaviors.



Flipbook Baker (Beta)

UE 5.0 introduced the first version of the Flipbook Baker, the tool used to bake out a rasterized flipbook of an effect. UE 5.1 introduces a more refined user experience, as well as additional options. You can now bake out these types:

2D Texture

Volume Texture

Simulation Cache (Experimental)

Render Dependency Graph

Niagara is now supported in the Render Dependency Graph. For more information, refer to the Render Dependency Graph documentation.

Heterogeneous Volumetric Rendering (Experimental)

Niagara Fluids rendering was introduced in UE 5.0. The initial implementation was limited, only allowing you to add 2 directional lights to the fluid simulation. It was also not possible to cast shadows on the fluid.

Heterogeneous Volumetric Rendering is designed to take the lighting you have already set up in your scene and apply it to your fluid simulation rendering. This type of rendering works with all types of lights, not only directional lights. While there is no limitation on the number of lights you can use, currently the implementation is linearly more expensive as each light is added.

If you have other objects in your level, they can also cast shadows on the fluids volume. This creates a more realistic look, making the fluid effect more integrated in the scene.

To enable this experimental feature, select the checkbox Enable Heterogeneous Volumes in the Project Settings. Then apply the material MI_HeterogeneousVolumes_GasExplosionCine to the Mesh Renderer on a fluid simulation.

Fluid Quality Improvements (Beta)

Niagara Fluids have several improvements to quality and performance in this version:

We improved the turbulence model.

We also improved small-scale force, helping with the detail on the leading edge of simulations.

We implemented tricubic interpolation, adding extra detail without increasing the resolution, though there is a tradeoff in performance.

We made improvements to performance of fluids overall.

UX / UI Improvements

The Niagara Editor has a new, streamlined layout. The Parameters panel has been moved to the lower left, giving more room to the System Overview in the center. The Curve Editor and the Log are now docked on the bottom, next to the Timeline.



Panels like the Parameters panel or the Selection panel are now contextual, so they update depending on what you select.

Previously, when you selected a Niagara Actor in the Level Editor, there was a section called Override Parameters. This section has been renamed to User Parameters.

We replaced the previous Scratch Pad interface with a new workflow to create Scratch Modules directly in the Niagara Editor. Add as many scratch modules as you need, and you can display each as their own tab in the Niagara Editor.



When you create many custom user parameters, keeping them organized in the Parameters panel can be a challenge. The Hierarchy Editor gives you the ability to not only categorize and organize your variables, but also to set up their default values.



When you select a Niagara system in the Level Editor, you will now see a section in the Details panel called Effects. This can help you quickly isolate the parameters you need to edit for Niagara systems.



There are new ways of opening the Niagara Debugger and tracking the elements you want to analyze.

To quickly turn on the Debugger on a particular system, click the Niagara component in the Level Editor, and from the Details panel select Debug. This opens the Niagara Debugger with the system information already set.



You can also debug a specific parameter, such as the age of a particle. From the Parameters panel in the Niagara Editor, right-click the parameter you want to track, then select Watch Parameter in Niagara Debugger.



This automatically turns on all the relevant options you need in the Debugger to see that parameter's information.

For more information, refer to the Niagara Debugger documentation.

Accessibility Improvements

We made the following improvements to the accessibility tools in UE 5.1:

Multi-User Screen Reader Support

The Screen Reader plugin can now support more than one user at a time, providing a means for more than one visually-impaired user to play at once. If users' input devices have specialized audio ports available, such as the ones located on game console controllers, each user can connect a set of headphones to output their screen readers' voices separately. Alternatively, for PC users and users without headphones, the screen reader will output voices with different pitches for each user. Screen reader users are represented with the FScreenReaderUser class, which can request voice announcements, retain information about the accessible widget it is currently focused on, and use the new Navigation Policy to define how users navigate.

Navigation Policies

You can now define a Navigation Policy to provide fine control over how visually-impaired users navigate the screen, similar to how commercial screen readers work. To make a Navigation Policy, create a class that implements IScreenReaderNavigationPolicy. After that, you can set the navigation policy for a screen reader user by using FScreenReaderUser::SetNavigationPolicy and providing a shared reference to the one you want to use.

Unreal Insights

Unreal Insights is a companion application for Unreal Engine that lets you analyze and profile the CPU and memory performance of your game. For general information, refer to the Unreal Insights documentation.

Top Menu

There are new top menu commands available:

Import Table: From Timing Insights, you can now import any .csv or .tsv table to analyze. You can apply grouping and hierarchical path breakdown features on any table.

Session Browser: If you have closed the Session Browser, you can reopen it from an open trace file.

Open Trace File: If you have a trace open in Timing Insights already, you can open a different trace file and it will replace your current session or open a second session.

Auto Open Live Trace: When enabled, the current session will change automatically to the live trace.

Session Browser

You can now filter and sort the trace sessions list in Unreal Insights to better analyze the specific data you are looking for.

You can search traces by name or by command line.



There is now a method to rename and delete trace sessions directly from the Session Browser by right-clicking on the trace. When deleting or renaming through the context menu, it will delete or rename the trace file and any associated cache files.

Memory Insights

To capture a memory trace, you must start the session from the command line. To start recording, run the editor or the game from the command line with the additional argument trace=default,memory. The reason you need to start with these arguments from the command line is that trace information needs to be tracked as soon as the engine initializes.

You can now start memory insights from the command line using extra trace channels metadata and assetmetadata. This provides asset names and class names to the Memory Insights session for additional filtering options. For example, you can calculate the cost of memory allocation per asset, or per class name.

There is now a Path Breakdown option for grouping string columns, which when selected will create a collapsible hierarchy view. You can group low-level memory (LLM) tags, assets, and top source files this way.

Grouping this way not only helps visual organization, but also lets you view the cost for the parent groups.

In previous versions of Unreal Insights, you could right-click on items grouped by callstack then select Open in Visual Studio from the context menu. In this version, this option is available even when not grouped by callstack. For example, if you have grouped items by tags, you can right-click on the allocation and select Open in Visual Studio.

The Modules View in Memory Insights shows a list of all .dll files. In this version, we split Statistics information into separate columns for easy sorting. You will now find columns for the number of symbols that are: Discovered, Cached, Resolved, and Failed.



List items that failed are highlighted in red, and list items that resolved properly are highlighted in green. Yellow indicates that some of the symbols have resolved and some have failed.

Networking Insights

You can now highlight an event in the Packet View, to help you see how many bits that specific event is using in the packet. This makes it possible to quickly see how much bandwidth an event is using relative to other data.

You can choose to highlight either:

The aggregated bitcount for all instances of the event; or

The maximum bitcount used by a single event.

There is a new tab called NetStatsCounters where you can view stats counters related to the replication system for the selected packet or range of packets. There are two different categories of stats:

FrameStats: Stats counters for the entire frame. This is typically used for reporting stat counters related to networking, for work that is shared between all connections. For example, how many objects are currently being updated on this frame.

PacketStats: Stats counters related to each specific packet. For example, how many objects were scheduled to be serialized, and how many actually did fit into the packet.

You can now trace simple stats associated with network trace data using the macros UE_NET_TRACE_PACKET_STATSCOUNTER and UE_NET_TRACE_FRAME_STATSCOUNTER. Data traced with either of these macros will be displayed in the NetStatsCounters tab in Network Insights.

Timing Insights

We added support for ParallelFor tasks.

Cooking Insights provides a profiling method to gather and display information about the way packages are cooked. To record a cook session, start from the command line using the argument -trace=default,cook.

When you enable the cook channels, this adds a panel to Timing Insights called Packages. This displays a list of all the packages associated with that cooking event. For each package, there are statistics available, including: LoadTime, SaveTime, BeginCache, IsCacheCooked, and Asset Class. Each of these is displayed in a column that can be grouped and sorted.



Use the option Grouping > Path Breakdown - Package Name to generate a collapsible hierarchy view of the data. You can also group by Asset Class.

If your game uses coroutines, you can now view coroutines in Timing Insights. Coroutines are when something begins its execution on one thread, and finishes on a different thread. We now display timing events that are specific to coroutines.

You can now enable screenshots within Timing Insights. When you enable Screenshot Tracing, you can take a screenshot and a red vertical line will display in the Timing Insights timeline. You will also see a thumbnail of the screenshot. This can help you to debug visually in Timing Insights.

To enable screenshot tracing, start from the command line using the argument -trace=default,screenshot.

Once screenshot tracing is enabled, from the console command type in trace.screenshot to take a screenshot at that frame.

There's a new channel you can add when starting Timing Insights from the command line called Asset Load Time. This channel does two things:

Enables named CPU timers for UObject::Serialize.

Toggles on the tracing of Blueprint names.

In the past, tracking Blueprint names was enabled by default, but this would add a lot of cost to the trace runtime event. Now, if you want to enable Blueprint name tracing, you must turn on this argument in the command line.

To enable asset load time tracking from the command line, use the argument -trace=default,AssetLoadTime

Because there are many timers added when Blueprint names are toggled on, they are hidden in Trace Insights by default. After enabling Asset Load Time tracking, you can display Blueprint names by adding the argument -statnamedevents.

In UE 5.0, when you copied a timing event, it would copy only the name. Now, when you copy a timing event using Ctrl+C it copies the name, the duration, and the associated metadata, as it is displayed in the Timing Insights panel.

Timing Insights can be run directly from the command line without opening the UI. You can either specify a single command directly in the command line, or you can execute a series of commands by using a response file. In each case, a set of data is exported to a .csv or .tsv file.

TimingInsights.ExportThreads: This command exports a list of GPU and CPU threads.

TimingInsights.ExporTimers: This command exports a list of GPU and CPU timers.

TimingInsights.ExportTimingEvents: This command exports a list of GPU and CPU timing events. The list of events that is exported can be filtered by thread, timer, or by time range.

TimingInsights.ExportTimerStatistics: This command exports the list of GPU and CPU timers and their aggregated statistics.

These commands can be useful for running automated tests.

For more information on executing commands from the command line directly, refer to the Timing Insights documentation.

Trace

There are some existing console commands you can use from UE while Unreal Insights is running such as trace.start and trace.stop to start and stop a trace file. There are two new console commands we added in 5.1:

Trace.SnapshotFile <filename>: This writes a snapshot of the current in-memory trace buffer to a file. If you are already tracing actively, it does not interrupt the active trace, but instead records a second trace file in parallel just for this snapshot.

Trace.Bookmark <name>: This emits a Bookmark event with the given string name. Bookmarks appear in Timing Insights as a vertical line at the time the Bookmark was recorded. Previously this was available through the API only as TRACE_BOOKMARK().

Trace.Screenshot <Name> <bIncludeUI>: As mentioned above, you can run this console command to generate a vertical line and optionally include the UI by specifying true or false for a screenshot in Timing Insights.

You can choose to either start tracing automatically at the start of your project, or wait to initiate a trace command from the console command. The default behavior of the UnrealInsights.exe is to have autostart enabled.

If autostart is enabled, the runtime automatically tries to connect with the local trace server if the Unreal Insights Session Browser is detected as running.

You can perform tracing at runtime using a worker thread, a dedicated thread to capture all the tracing information. Alternatively, you can do the tracing directly on the game thread at the end of a regular frame. Using the game thread has an impact on game performance.

By default, we use the worker thread, the recommended setup. However, for servers it is not always possible to have a worker thread. You can disable the worker thread and use the game thread instead by using the command line parameter -notracethreading.

Datasmith

New 3ds Max Plugin

We completely rewrote the Datasmith 3ds Max plugin, and consolidated all Datasmith features in a new ribbon toolbar in 3ds Max. The new plugin improves performance, and provides several new features and improvements.



The new Datasmith plugin for 3ds Max supports Direct Link. You can now connect a 3ds Max project to an Unreal Engine project, and sync them manually, or automatically using the Direct Link Auto Sync feature.

The new Datasmith plugin for 3ds Max improves support for:

VRay: more supported material parameters, and proxy meshes

Corona: Support for PBR materials and proxy meshes

Railclone: export improvements, and support for Railclone5

Forest Pack: export improvements, and support for Forest Pack 7

Baked 3ds Max textures are no longer automatically exported at a resolution of 4096. You can now cap the maximum resolution to values between 64 to 4096. This improves import / export performance for large scenes with complex materials.

XRef scenes are scenes loaded from an external 3ds Max file into your current file. When you export a 3ds Max project with Datasmith, you can now decide whether or not to export XRef scenes as well. The XRef scene export toggle is in the new ribbon toolbar.

Datasmith now supports more parameters for supported light types, including:

ArnoldLight

CoronaSun

PhotometricLight and TPhotometricLight

VRaySun

The new Datasmith plugin for 3ds Max automatically converts bitmap, baked, normal, bump, and procedural texmaps.

Revit Plugin Improvements

In this release, we added Direct Link Auto Sync to the Revit Datasmith Exporter. If Auto Sync is enabled, your Unreal project syncs automatically when you make changes to the linked Revit project.

Datasmith settings are now stored as custom data in Revit project files.

This release also adds support for exporting the following information from Revit:

Views: you can specify which view to export from your Revit project, no matter which view you're currently working in.

Custom origin point: You can define the Base Point or the Survey Point in Revit as a custom origin point to use as the insertion point in Unreal.

Decals: Datasmith now exports Revit decals as Unreal Engine decals.

Sketchup Plugin Improvements

For this release, we focused on optimizing the Datasmith plugin for Sketchup.

We improved how Datasmith exports complex hierarchies. Instead of exporting one Actor per group head or component head, and one Actor for every mesh in a group or component, Datasmith merges meshes in groups and components automatically. The result is a simpler hierarchy in Unreal Engine that is closer to what you see in the Sketchup outliner.

If you use the Color by Tag feature to set the colors of objects in Sketchup, Datasmith now exports those colors.

We also added image support. The Datasmith plugin for Sketchup now exports images as Mesh Actors with textures.

Solidworks Plugin Improvements

The Datasmith plugin for Sketchup now supports more Solidworks features. You can now export Solidworks configuration display states as variants of a Level Variant Set. You can also export user-created directional, spot, and point lights with data for position, cone angle, brightness, and color.

Improved Metadata Handling for Visual Dataprep

Visual Dataprep is a system for creating reusable import "recipes" that reorganize, clean, merge, and modify scene elements before creating final Assets and Actors in an Unreal Engine Project.

For UE 5.1, we made some usability improvements for working with metadata in Visual Dataprep.

Metadata keys and values are now more readable, and are selectable, so you can copy and paste them into filter fields instead of copying them manually.

We also added new string matching options for keys. When you filter by metadata, you can now use a contains expression that can handle all keys with, for example, similar prefixes or suffixes. This saves time when you are writing import processes for models from applications that use slightly different names for the same keys.

Universal Scene Description (USD) File Workflows

Unreal Engine 5.1 features several new features and workflow improvements for working with USD files.

You can now use Live Link to synchronize an external source with content in a USD file in Unreal Engine. Use the new Set up Live Link option in the USD Stage window to connect a DCC application such as Autodesk Maya with a USD scene in Unreal Engine that has a character in it, and you can use the DCC to drive the character. Link / USD integration is also useful for working with motion capture. Use USD to load a scene with characters into Unreal Engine, and have the motion capture drive the characters in the USD scene.

The new Set up Control Rig option in the USD Stage window lets you connect a control rig to a character in a USD file in Unreal Engine. You can use the control rig to create and edit skeletal animations, and save the animation data back to the USD file. You can set up a Control Rig Asset or generate an FK control rig.

We added several options for editing prims in the USD Stage window. These include:

Commands to cut, copy, and paste prims.

Options to duplicate prims in a variety of ways. For example, you can create a flattened duplicate of a composed prim, or duplicate a single layer.

Isolation mode. You can isolate, and work on specific layers, which is useful when you want to review or modify the edit history. Changes that you make in isolation mode are applied to the isolated layer.

When you add a reference in the USD Stage you can now specify a target prim in the referenced file.

You can now add payloads to the USD Stage the same way you add references.

We added support for Groom in USD files. You can now import Groom caches and static Groom files as assets, and use them the same way you use Groom assets imported with Alembic. You can also load them on the USD stage.

The USD importer uses a custom Groom APIschema to import Grooms from USD BasisCurves. The importer also supports Alembic Grooms that follow the Alembic groom specification, so you can import an Alembic Groom referenced in a USD file.

We also added a new Groom binding API schema that you can use to bind a Groom to a skeletal mesh or geometry cache. You can set up a Groom on a character, load the result into the USD stage, and play back the simulation and character animation together in Unreal Editor.

Other Data Formats

Khronos Group's GL Transmission Format (glTF™) is an extensible, open-standard file format designed for compact file size, fast loading, and complete scene representation. It's used to import and export models out of Twinmotion and it is the preferred exchange format for Sketchfab tools and libraries.

In this release, we improved glTF support and integrated it more tightly in Unreal Engine.

We integrated the glTF importer in the new Interchange framework. The existing glTF Importer and Datasmith glTF Importer plugins are scheduled to be removed in a future release.

The glTF importer now supports:

Unlit materials.

The khr_texture_transform extension.

Importing rigged models with Skeletal Meshes, Skeletons, and Animation Sequence assets.

The glTF exporter, formerly available as an external plugin, is now part of Unreal Engine. It currently must be enabled separately.

We improved character encoding, so non-English language names and labels of actors and assets are now exported correctly.

CADKernel is an alternative algorithm for tessellating CAD models you import into Unreal Engine. It uses the same tessellation parameters as the default algorithm, but produces better results in some cases, particularly for models with radial features. CADKernel also does a better job at limiting the number of open edges after tessellation.



Left: CAD model tessellated with the default Unreal engine algorithm. Right: The same model tessellated with CADKernel

To activate CADKernel, set the ds.CADTranslator.DisableCADKernelTessellation console variable to False or 0. You can change the variable from the Console Variables Editor.

After you activate CADKernel, Unreal Engine uses it by default when you import a CAD model. If you have already imported a CAD model, perform a full reimport to have Unreal Engine re-tessellate it with CADKernel.

MaterialX is an open standard used to represent rich materials and looks, and transfer them easily between platforms and applications. The new MaterialX importer in UE 5.1 supports the following MaterialX nodes:

All inputs of the Autodesk Standard Surface material.

Point, spot, and directional lights.

A subset of the MaterialX standard data types and nodes.

LiDAR Point Cloud Improvements

For this release, we migrated the LiDAR Point Cloud Asset editing tools to the Unreal Engine 5 framework. You can now access all of the point cloud editing tools from a new LiDAR mode, available from the Select Mode dropdown in the main toolbar.

This update aligns the point cloud editing workflow with other Unreal Editor workflows such as mesh editing. You can select, merge, edit, and build collisions on your point cloud assets, and preview the results in the Level.

You can now use point cloud selection tools (for example, the lasso tool or the polygon selection tool) to add and subtract points from a selection. In addition to extracting points from a cloud, you can now create static meshes from selected points.

Point cloud Actors now have a Point Orientation setting that allows you to align point cards along calculated normals, rather than always facing the camera. Normal-facing cards produce more pleasing visual results, and better lighting interaction.

The LiDAR point cloud plugin can now import normals from ASCII files and E57 files that contain normal data.

The new Color Source > Data with Classification Alpha property for point cloud Actors lets you mix the RGB color of points with custom alpha values, based on point classification. This is useful when you want to show, hide, or fade whole groups of points based on their classification.

Variant Manager

For this release, we migrated the Variant Manager tools to the Unreal Engine 5 framework. The look and feel are now consistent with other tools in UE 5.1. We also overhauled the user interface, based on design feedback, to make it more visually appealing and easier to use.





Top: the previous variant manager in Unreal Engine 5.0. Bottom: the new variant manager in Unreal Engine 5.1

RAD Tools

Oodle Texture 2.9.7

Identical bit output on all platforms

Faster arm64 encoders.

Shared Texture Encoding

For all platforms

Bink

Support for standard SRT subtitle files

Online

Online Services Plugins

The new Online Services plugins for Unreal Engine now have a fully defined interface, and have moved out of Experimental status and into Beta. These plugins will work alongside the existing Online Subsystem plugins, and both are available for use.

Users of the new Online Services plugins will find:

More consistent and robust APIs.

Enforced safe calling patterns.

Improved type safety.

Simplified delegate binding.

The ability to easily extend an existing implementation.

Developing your own plugin for use with your own online backend is easier now with a shared common framework. The framework in the Online Services plugins provides:

Async operation result caching

Sequencing async operations

Per-backend configuration

Exec command handler

Minimal boilerplate

Logging

Included in this version are the following implementations:

EOS Online Services plugin implementation for using the EOSSDK.

NULL Online Services plugin implementation for development purposes.

OSSAdapter Online Services plugin implementation for using any existing OnlineSubsystem by means of the new APIs.

The following interfaces are available in the new Online Services plugins:

Achievements

Auth

Commerce

Connectivity

Leaderboards

Lobbies

Presence

Sessions

Social

Stats

Title File

User File

User Info

For more information, refer to the Online Services documentation.

Lyra

Players can now invite and join friends to their matchmaking sessions by using the Epic Online Services (EOS) overlay.

Networking and Multiplayer

Iris (Experimental)

Iris is an experimental implementation of a new replication system for Unreal Engine. The goal of Iris is to enable richer multiplayer experiences with larger, more interactive worlds, higher player counts, and reduced server costs. Iris achieves replication performance improvements over the current replication system by:

Unlocking scalability by removing antipatterns that constrain it

Enabling concurrency through separation of replication and game thread data

Improving efficiency by sharing as much work as possible for multiple objects and connections

Iris is an opt-in system and will exist alongside the current replication system for the foreseeable future. Existing game code will continue to work as before. Opting into Iris requires game code to use new engine APIs, however, existing replicated properties and Remote Procedure Call (RPC) definitions in C++ and Blueprints remain compatible.

Subobject Replication Improvements

Replicated Subobjects in Unreal Engine provide a way to replicate any UObject-derived class and the replicated properties they contain. The previous system for replicating components and subobjects employs the virtual function AActor::ReplicateSubobjects.

Using the new system, actors now have methods that register subobjects to a list on the owning Actor or Actor Component, with the replication of these registered subobjects handled automatically by the actor channel. This process offers greater control over when and where subobjects are replicated.

The Registered Subobjects List is an opt-in feature. To enable the Registered Subobjects List, set the property bReplicateUsingRegisteredSubObjectList = true in your Actor or Actor Component class. Then call AddReplicatedSubObject in ReadyForReplication, BeginPlay, or when creating a new subobject. Finally, be sure to call RemoveReplicatedSubObject whenever you modify or delete a subobject.

The old system will continue to work alongside the new system for the foreseeable future. For more information about enabling the Registered Subobjects list and working with the new system, refer to the Replicated Subobjects documentation.

Templates and Sample Content

Simulation Templates



Unreal Engine 5.1 adds a new Simulation templates category. Simulation templates offer a broad range of starting points for various enterprise simulation applications and are preconfigured with:

Specific settings for outdoor environments.

Realistic sky and lighting.

Georeferencing tools.

For more information, refer to the Unreal Engine Templates Reference page.

Platform SDK Upgrades



Windows

Visual Studio 2019 v16.11.5, Visual Studio 2022

Windows SDK 10.0.18362

LLVM clang 13.0.1

.NET 4.6.2 Targeting Pack

.NET 6.0

IDE Version the Build farm compiles against

Visual Studio - Visual Studio 2019 14.29.30146 toolchain and Windows 10 SDK (10.0.18362.0)

Xcode - Xcode 13

GDK

Windows SDK: 10.0.19041.0

GDK: June 2022 Update 2

Firmware Version: Recovery September 2022 10.0.22621.2216

Supported IDE: Visual Studio 2019

Android

Android Studio 4.0

Android NDK r25b

Android SDK

Recommended: SDK 32

Minimum for compiling UE: SDK 30

Minimum target SDK for running on device: SDK 26

AGDE v22.2.69+ required if you are using AGDE debugging.

ARCore

1.22

ARKit

4.0

Linux

Native Linux Development

Recommended OS: Ubuntu 22.04 or CentOS 7

Compiler: clang 13.0.1

Cross-Platform Development

Cross-Compile Toolchain: v20 clang-13.0.1-based (CentOS 7)

Oculus

33.0

OpenXR

1.0.22

Google Stadia (Deprecated)

1.82.0.102432

Steam

1.47

SteamVR

1.5.17

Switch

SDK 14.3.0 + optional NEX 4.6.7

Minimum Firmware Version: 14.1.2-1.1

Nintendo Dev Interface 2.5.5

Supported IDE: Visual Studio 2019, 2022

PS4

Orbis SDK 9.508.001

System software:

10.008.001

Supported IDE: Visual Studio 2019, 2022

PS5

Prospero SDK 5.00.00.33

System Software:

6.00.00.42

Supported IDE: Visual Studio 2019, 2022

macOS

Recommended

Latest macOS 13 Ventura, Latest Xcode 14

Minimum

macOS 12 Monterey, Xcode 13.4.1

Machine Architecture Note

Native Apple Silicon support is available for macOS targets for both editor and project builds. Editor support for Apple Silicon is experimental.

Some third-party SDKs and plugins do not yet contain ARM64 slices and may have compatibility issues.

iOS / tvOS / iPadOS

Recommended

Latest Xcode 14

Minimum

Xcode 13.4.1

Supported Target SDK versions: iOS 15 or later

Graphics API: Metal 2.4 and Metal 3.0

Release Notes

Animation

New:

Control Rig now has additional properties exposed to Blueprints and scripting.

Added support for in-between Morph Targets when importing FBX files.

The in-betweenMorph Targets are now imported as standalone Blend Shapes with their animation curves baked accordingly to preserve the original animation.

You can now select things below the ground in preview scene viewports.

The floor shown in the preview scene within each persona editor no longer blocks selection of items below ground.

You can now set custom bone colors using the Bone Color property in the Editor Preference.

Added a new UE_ANIM_REMOVE_DEPRECATED_ANCESTOR_TRACKER definition to remove large deprecated members from FAnimationUpdateSharedContext.

Added a new asset information section for Animation Montages when working with blueprints.

Added a looping flag property to Animation Sequences and Blend Spaces. This is used to set the default loop value when creating asset player nodes.

Blend Masks and Blend Profiles can now be organized in different categories under the Skeleton Tree view.

The City Sample's AnimToTexture plugin is now available as an experimental Engine plugin.

Fixed a bug that caused an Animation Sequence's cache stats and debug name to not register.

Added the new experimental Curve Expressions plugin, that you can use to copy to Skeletal Meshes' animation curves. You can also make adjustments to the copied animation curves using simple text expressions.

Added a Copy Context Menu option to copy Curve names from the Timeline editor to the clipboard.

The Pose Driver node is now production ready.

Added a GetMeshDNA function to SkelMeshDNAUtils in RigLogic.

Improvement:

Bone rendering has been consolidated across all Animation Editor viewports.

Animation Sequence compression is now asynchronous during cooking.

Crash Fix:

Fixed a crash that could occur when playing Animation Montages when the owning Actor is destroyed while executing one of its Animation Notifies.

Fixed a crash that could occur by debugging while live coding.

Bug Fix:

Fixed a bug that could cause wrong values being set when pasting a bone transform in the Skeleton Editor.

Added missing implementation to UMovieScene3DConstraintTrack::RemoveAllAnimationData().

Fixed a bug that could cause root motion modes to not be selectable in the animation viewport.

Deprecated:

The USkeletalMesh pointer of the USkinnedMeshComponent has been replaced with the new USkinnedAsset base type pointer enabling Unreal Engine to utilize new types of skinned asset components.

New:

Motion Warping: Added support when using the animation warping plugin for injecting translations when there is no translation to warp in the animation.

Added an animation modifier within the AnimationModifierLibrary to reorient the root bone in an animation while maintaining mesh position and rotation.

Added an animation modifier to the AnimationModifierLibrary to copy transforms from one bone to another.

Added a new simplified framework within the Motion Warping plugin by removing the node's bInLocalSpace option.

Root motion is now always warped in mesh space.

The Motion Warping plugin has transitioned from the Experimental stage and is now in the Beta production phase.

Added support for Blend Spaces within the Pose Search plugin.

Added a new experimental Foot Placement locomotion node within the Pose Warping plugin.

You can now disable the Pose Warping plugin's Orientation Warping node when sufficient Root Motion data isn't available to calculate good warping results.

Montages played from Linked Animation Blueprint Graphs and Layers will now behave correctly when using Inertial Blending after enabling the debug command: bUseMainInstanceMontageEvaluationData.

Montages using Inertial Blends now support Blend Profiles.

Added experimental root bone offset property to the Animation warping plugin's Orientation Warping node, that can be used to follow Root Motion rotation more closely during forward-facing turns.

The Animation Warping plugin is now production ready.

Added a new State Machine Function Library that allows you to query the active state, as well as dynamically transition between states.

Added a new experimental Offset Root Bone node within the Animation Warping plugin

Improvement:

Animation Notify States can now check if they have reached the end or were canceled before completing, using the new UAnimNotifyLibrary NotifyStateReachedEnd function in the Event Reference data.

Improved the behavior of the Stride Warping node at low character movement speeds.

Improved the Stride Warping behavior on manual mode when stride scale is 1 and interpolation is also enabled.

Improved the Stride Warping behavior for 3x interpolation speed while using manual mode.

Bug Fix:

Fixed a bug that could cause the animation graph to avoid updating the entire graph from the game thread when only using root motion from an animation montage asset.

Fixed bug that could occur within the Motion Warping plugin that could cause root motion occurring outside the warp window to be stomped during the last tick.

Fixed a bug that could occur when using the Motion Warping plugin that would abort warping if the user jumps to a different point in the animation sequence while the warping window is active.

Fixed a bug that could cause erratic behavior in Montages during section loops under very specific timing and frame rate conditions.

Fixed a bug that could occur with Montage Notifies that would not show the assigned name on the notify tracks.

Fixed a bug that can cause sudden flips to existing Orientation Warping angles, when adding Root Motion data to nodes that did not contain any previously.

Fixed an issue where the Apply Root Motion Ability Task could restore a movement mode without also restoring the custom movement mode.

Fixed a bug that could cause Transition Events to not fire from Conduits.

Fixed a bug that could disrupt the prediction behavior of the Motion Trajectory Component when the character is turning on the spot.

New:

Added an aggregate node type in Control Rig, which will concatenate multiple unit nodes of the same type to allow for a dynamic number of input pins.

Added Parameter At Length Percentage Control Rig node, which can be used to return the U parameter of a spline at a given length percentage.

New Control Rig Template nodes offer a new way to organize sets of nodes in manageable groups. After grouping a set of nodes with a Template node you can take advantage of wildcard pins which can pass an input into each of the supported nodes' respective compatible input.

Setup Events are now called as Construction Event.

You can use new Construction events to spawn Bones, Nulls, Controls and more.

You can now create and invoke your own Control Rig Events custom triggered logic.

You can also invoke Control Rig Events using Python commands or within Unreal Engine Blueprints.

Control Rig nodes can now be updated to their latest version with the Upgrade Node(s) context menu option in the graph.

Added a new type of execution callback called the Dispatch Factory.

A Dispatch Factory can rely on lambdas to generate a callback based on the types passed to it.

The Control Rig hierarchy now supports Metadata storage directly within the elements of the hierarchy. The metadata is then readable and writable in the graph using the metadata nodes, Blueprints, or Python using the hierarchy's API.

You can now use Profiles when working within the IK Retargeter to store, edit, and apply retarget settings at runtime using Blueprints.

You can now invoke events from the top toolbar and context menu in Control Rig.

You can now manage Control Rig events in Action Palette.

You can now enable Debug Drawing during Control Rig interaction.

You can now use the new IK Retargeter hierarchy view to quickly manage and edit bone transforms with a clear visualization of the full skeleton chain.

Using the new Control Rig Overlay mode, controls can now be drawn on top of a Skeletal Mesh in the level viewport.

Control Rig now supports creating and managing Aim Bones and Two Bone IKs using Python.

The IK Retargeter's source and target IK Rigs and meshes are now fully swappable with no need to create separate retarget assets for different source IK rigs.

You can use new Control Rig Proxy Controls to interact with animatable, keyable controls, through helper controls. Proxy Controls can not be keyed and are invisible to Sequencer, but offer you the flexibility of using the Interaction even in Control Rig.

You can now set a Control Rig component's class in Blueprints.

You can now create Control Rig and Rig VM workflows using Python. These workflows can then be registered to operate a specific node or a set of nodes. You can see example workflows in the Control Rig plugin.

You can now convert any data type to and from a string using the ToString and FromString nodes.

The Control Rig's Spherical Pose Reader node has been optimizatized and now operates with a 5-15% increase in performance.

You can now store Metadata within the Control Rig Hierarchy using the new Dispatch Factory system. Metadata can be read and written to and from elements in the Control Rig's hierarchy.

By storing Metadata in the Control Rig Hierarchy you can use that data during construction or with blueprints to drive the Control Rig during runtime.

You can now index an array in Rig VM using negative values.

When indexing with negative values, -1 represents the last element, -2 represents the second to last element, ext.

You can now get and set a control shape transform when working with Control Rigs.

You can now use new Stride Warping Settings when working with the IK Retargeter. You can use the Stride Warping properties to adjust a character's stride length across retargeted animations.

You can now enable a debug visualization of the Rigid Body Animation Blueprint node, that will display the node's physics bodies and constraints.

The RigidBody node's physics bodies will be drawn in the Animation Blueprint Editor's viewport when the node is selected. You can enable a visualization of the node's constraints using settings in the node's Details panel.

You can now toggle the visualization of individual physics bodies in the Physics Asset Editor's hierarchy tree panel.

To toggle the visualization, first enable the option in the Skeleton Tree's Settings menu.

After enabling the visualization toggle, you can enable or disable the visualization for each physics body using its associated checkbox.

You can now view a synchronized debug visualization of a character's physics bodies and constraints between the Physics Asset Editor and the Animation Blueprint Editor.

This unified view also means any debug visualization options are universally set across both editor environments.

You can now upgrade Rig VM from struct to dispatch.

You can now assign per-element tags within the Control Rig hierarchy.

A useful application of tags in the Control Rig hierarchy could be to delineate if an element is on the Left or Right side of a character. These tags can then be used to quickly search for elements later during the Control Rig's execution.

You can now use the new Set Default Parent Control Rig node to change an element's parent or identify it as the new default node in a chain.

Rig VM now uses a new low-level mechanism for a node's upgrade path, enabling the API to allow nodes to describe their own upgrade path.

You can implement FRigVMStruct::GetUpgradeInfo to enable RIG VM nodes to be upgraded automatically.

You can now use new Boolean Toggle nodes with Control Rigs.

Control Rig now provides you with feedback when changing initial transforms during a forward solve.

If you then change the initial transform of a hierarchy element during the forward solve a note will now be issued on the node in question.

The first execution index of each node can now be displayed on nodes using the Show Node Instruction Index on any node in the Control Rig graph editor.

By enabling the Show Node Instruction Index, it can assist you when debugging a Control Rig graph, by revealing which nodes are being executed by the graph.

Added introspection on function arguments to Rig VM.

You can now use the FRigVMRegistry's access to FRigVMFunction to list the function arguments for each registered callback function or dispatch.

When selecting objects in the Control Rig hierarchy, the hierarchy relationship of the elements is retained if copied or moved.

IK Rig and Retargeter assets now have custom icons.

You can now use Python getters for shape transform in Control Rig.

You can use new Root Settings in the IK Retargeter to control the motion of the retargeted root bone, with the added ability to adjustments to the retargeted root bone independently of the character's feet.

You can manually change the pin types on the new wildcard pins in Control Rig.

The IK Retargeter now features the new Speed Planting property, that you can useto create retargeted animations without foot sliding, regardless of the size difference between the source and target character.

You can now enable debugging watches within Control Rig functions.

You can now import poses from pose assets or animation sequences to the IK Retargeter.

Additionally you can export retargeted poses as pose assets.

Control Rig now supports preferred Euler angles.

Euler angles set on Controls or Bones are now preferred over potential quaternion representations during the solve.

Using the Advanced Tab on the Control Rig Animation Blueprint Node you can now choose which Events to run during execution.

You can now set up multiple connections to the same source variable node in Rig VM.

Using the IK Retargeter you can now control any Pole Vector twisting on any retarget chain without needing to set up an IK.

Unreal Engine will now issue warnings for unconnected execute pins in Control Rig.

The Retarget Pose From Mesh animation node now also copies curve values from the source mesh component.

You can now mirror IK Rig retargeted chains.

Added the ability to see when an IK Rig retargeted chain's settings have been modified.

Deformer Graph node Pins can now specify data sizing that is a multiple of a given execution context. You can also use expressions to fully customize the pin's data sizing.

Deformer Graphs can now receive input, bind to, and receive data from, multiple Actor components as inputs.

Deformer Graphs now support the execution of multiple graphs. Each Deformer Graph can contain and execute a Setup Graph to perform initialization functions, an Update Graph to perform functions every rendered frame, and Trigger Graphs that can be queued to perform specialized functions and can be called using Blueprints.

The Skeletal Modeling tool has been relocated to the new Skeletal Modeling Tools plugin.

Exposed the ActorToTrack and ControlRigClass properties to Cinematics.

Improvement:

Variable nodes in Control Rig can now reference an input parameter inside a function.

Rig element names now support spaces in Control Rig.

Improved the performance of Control Rig's Hermite spline.

Updated the MLDeformer readme file to clarify install instructions for other non-windows platforms.

Control Rig's TypeIndex now operates in typedef for easier debugging.

When using the IK Retargeter you can now edit the retargeted pose on both the source and the target skeleton.

The IK Retagreter now provides precise numerical input for bone editing and a reworked interface for pose management.

Convert debug breakpoints from TSharedPtr to guid based struct.

The Control Rig outliner for FKControlRig has been improved.

Control Rig and RigVM asset loading performance has been Improved.

The Control Rig's performance for cycle checking transforms has been improved.

The Print String node can be used to print any data type value to the screen at runtime, for debugging purposes.

The Rig VM's Refactor template data-type system now operates using Integers rather than string comparisons.

Rig VM has received an API performance increase due to a more efficient registry lookup mechanism.

When editing retargeted poses, you can no longer make direct horizontal translations on the retargeted skeleton's root bone.

You can instead use the new Horizontal Scaling property to achieve more reliable results.

The performance of Control Rig's Constraint nodes has been improved.

Rig VM nodes that used to be represented as many different instances and supporting different data types can now be represented as a FRigVMDispatchFactory.

See the Print node's improvements for an example of this implementation.

Increased the default number of Control Rig nodes that can run concurrently from 64 to 256.

The Control Rig Editor hotkey shortcut, used to perform a duplication, has been changed, and is now Ctrl+D.

The default Control Rig naming convention has been changed to TemplateName.

Additionally, the PrototypeName metadata tag used for FRigVMStruct specializations has been renamed to TemplateName to match the API feature.

The visibility of Proxy Controls affects the visibility of other proxies sharing the same driven controls.

The Retarget Pose from Mesh node now outputs the character's reference pose when no source component is found.

IK Retargeter now auto-populates the Skeletal Mesh property when applying an IK Rig.

Bug Fix:

The Category field of Control Rig functions can now be cleared after it is given a value.

Fixed Control Rig Blueprint compilations causing the right-click context menu to get slower over time.

Fixed the Control Rig AnimGraph Node not being able to accept array pin connections.

Fixed Aim nodes causing flipping when the primary and the secondary targets are at a certain angle.

Control Rig's template collision message has been changed to a display rather than as a warning.

If two collision templates are defined with the same arguments, the second collision will fail during registration, and issue a warning to the log.

Fixed a bug that could cause IK Rig retargeted chain to unexpectedly rest to default values.

Fixed a bug that could cause bone and name filters within the IK Rig and IK Retargeter hierarchy panels to not function properly.

Fixed a bug that could cause the IK Retargeter viewport to not properly frame selections when pressing "F" key.

Fixed a bug that could cause vectors in a Control Rig to not export correctly when used on Animation Blueprints.

Fixed a bug that could cause a delay in the seamless editing of IK Rig and Retarget assets.

Changes to the IK Rig are now immediately reflected in any open Retarget asset.

Fixed bug that could cause an IK Rig retarget chain name to add an unwanted suffix when trying to rename the asset.

Fixed bug that could occur in the IK Retargeter when editing the translation of a target skeleton's root bone, that would push the character too far if the character was scaled up.

Fixed a bug that could cause the IK Retargeter to not properly register Vicon skeletons and other skeletons where the root bone is the pelvis.

Fixed a bug that could prevent the renaming of a single item with a case change.

It's important to note that both FString and FName operator are case insensitive resulting in misunderstanding when renaming items with altered cases.

Fixed a bug that could cause IK Retargeter chains using Globally Scaled translation mode to incorrectly apply scaled root motion when retargeting root motion between characters of different sizes.

Fixed a bug that could occur with exported retargeted animation sequences that would not update the Retarget Source Asset without manually updating the asset using the context menu.

Fixed a bug that could cause a case-change when renaming goals in an IK Rig.

Fixed a bug that could cause curves contained within a Control Rig to not retain the validity flag, and target curves to be declared as invalid if it writes a zero-value.

Fixed a bug that could cause Control Rig Display actors to behave unstable.

Fixed a crash that could occur when working with spawnables in a sequencer project that contains a Control Rig.

Deprecated:

Deprecated bezier nodes in Control Rig.

Deprecated Static Mesh Control node in Control Rig. Instead, you should use the Rig Hierarchy panel to create new controls manually or use the new Spawn nodes.

Deprecated Transform Constraint node in Control Rig. Instead, you should use the new Constraint nodes.

Deprecated the forced tick order dependency between Control Rig component and its mapped Skeletal Mesh components. Instead, you should use tick prerequisite related Blueprint APIs to ensure the mapped Skeletal Mesh components tick after the Control Rig Component.

The Deformer Graph Compute Kernel's Parameter array has been deprecated, and its functionality has been implemented into the Input bindings.

New:

Added the new bUpdateMeshWhenKinematic parameter to Skeletal Mesh Components, that updates Skeletal Meshes using physics bodies when they are set to kinematic simulation, rather than only when set to dynamic or simulated.

Added a set of preload dependencies on sparse class data and its archetype for blueprint CDOs.

Added track filtering to the Animation Sequence timeline.

Added the ability to blend regular animation sequences in mesh space as an option in the Blend Space properties, under Sample Smoothing.

Improved the Skeleton Tree children default ordering behavior.

The new behavior now lists sockets, preview meshes, and virtual bones ahead of a bone's children.

A Skinned Mesh Component's Predicted Level of Detail Level is now accessible from Blueprints.

The right-click context menu for Animation assets now has an option to Replace Skeleton, that you can use when a Skeleton asset has become orphaned.

The Compatible Skeletons feature is now accessible from the Skeleton Editor's Retarget Sources tool.

Added the ability to enable Pose Watching with Aim Offsets and Blend Masks.

Skeletal Meshes with a configured Leader Pose Component now will not tick the Animation Pose by default.

This default can be changed when calling SetLeaderPoseComponent with the new FollowerShouldTickPose parameter.

Added a new orbit camera mode to the Animation Editors camera widget.

Additionally you can now set a 'Lock Camera Rotation' and 'Pause On Orbit' options in the Editor Preferences.

When creating a new asset in the Content Browser, Level Sequence, Template Sequence, and Camera Animation Sequence asset types are now accessible in a new Cinematics top-level asset category.

The Pose Watch icon, that appears on animation blueprint nodes in the blueprint graph, that have been pose watch enabled, has been updated.

You can now create event-based transitions within State Machines.

The Rewind Debugger, packaged in the Animation Insights plugin, now has Pose Watch support.

You can now assign a Skeleton to an Animation Blueprint using the new context menu option Assign Skeleton in the Content Browser.

Added the option to strip Additive Base-Poses during cooking to save memory, This function is disabled by default and can be enabled using the console command a.StripAdditiveRefPose.

Relocated the Pose Asset editor's Update Source button below the asset field, as it was often hidden, depending on the width of the details panel.

Fixed a bug that could cause Notify states to re-trigger erratically when a montage is re-played.

Added a new tooltip for the Rewind Debugger curve tracks to preview curve value at cursor position.

Added a new TraceFiltering trace channel.

Note, the TraceFiltering trance channel will not be enabled by default on builds with the Trace Source Filtering plugin installed.

You can now save animation curves from the animation timeline editor in the clipboard.

Added new keyboard shortcuts for Rewind Debugger playback controls.

Added a new Project Settings section for Rewind Debugger.

Double-clicking a Linked Anim Layer node, now also attaches the newly opened Animation Blueprint editor to the corresponding AnimInstance for seamless debugging.

Added new Teleport flags to the Rewind Debugger that will return a skeletal mesh component to its original location when resuming the project.

Improvement:

Add support for LWC promotion when copying TMap properties via their property access, this change fixes issues experienced when supplying curve values via a node pin on Modify Bone animation blueprint nodes.

Improved animation blueprint re-instancing by removing the special case instance in the Blueprint re-instancing pipeline for animation blueprints. This allows linked animation graphs to persist across live-recompilations.

The new compiling behavior is opt-out using a console variable, in case your project relies on the old compiling behavior.

Improved Blueprint variable permissions filtering.

Added a critical section to the Property Access Library to prevent race conditions.

The HideBoneByName command now does not stop BoneAnim when TickOption is AlwaysTickPoseAndRefreshBones.

ShouldTriggerAnimNotifyState is now public.

Template Animation Blueprints can now be used with Skeletal Meshes as a standalone asset.

The Animation Budget Allocator can now be used in Blueprint-only projects.

Refined the animation asset's Create Asset submenu in the Content Browser, for increased organization and user efficiency.

Added expanded filtering options within the Animation Blueprint interfaces.

Added the adoption to prevent physics asset creation on import, this functionality is enabled by default.

The process of copying the final output pose for animation playback has been optimized by removing any redundant copies of the reference pose.

If incorrect pose results persist, you can traverse the bone index array in increasing order and fill in any gaps with the reference pose.

Enabled drag and drop functionality to support dragging pure functions from the MyBlueprint panel to AnimGraphs in Animation Blueprints.

Blocked all drag and drop functionality of dragging impure functions into AnimGraphs to prevent incompatibility errors.

Additionally blocked drag and drop functionality for all functions into State Machines to prevent incompatibility errors.

Replaced the message log readout, Compressing Animations with Preparing Animations.

Replaced the Animation Blueprint RigidBody node's MasterAlpha property with the new WorldAlpha property.

The Morph Target implementation workflow has been significantly optimized. The improvement can be most notably felt when setting up a Skeletal Mesh with many Morph Targets, where there are multiple active simultaneously.

Crash Fix:

Fixed a crash that could occur while deleting a blendspace node.

Fixed a crash that could occur by canceling an in progress animation sequence export.

Fixed a crash that could occur in EDL (Edit Decision Lists) builds caused by accessing sparse class data in Link() before it is serialized.

Fixed a crash that could occur when re-instancing UAnimInstance.

Fixed a crash that could occur when customizing an Animation Blueprint node that is no longer associated with a valid Blueprint.

Fixed a crash that could occur when compiling an animation blueprint that contains an empty state machine.

Fixed a crash that could occur when compiling linked Animation Blueprint graphs.

Fixed a crash that could occur while working in Asset Editor Mode Manager, by closing Unreal Editor with an open Animation Blueprint editor on screen.

Fixed a crash that could occur when opening Animation Sequence in the editor, when the Sequence relies on a compatible skeleton.

Fixed a crash that could occur while packaging a project containing a character using a remapped skeleton.

Fixed a crash that could occur when using the Rewind Debugger to trace object properties and the object contained a property of type Map.

Fixed crash that could occur when loading a Layered blend per bone node that has empty blend mask entries.

Fixed a crash that could occur by re-instancing clobbering the size of 1EditFixedSize1 arrays in Animation Blueprint nodes.

Fixed crash that could occur when trying to re-instance post-process Animation Blueprint instances on components with no mesh.

Bug Fix:

Fixed an issue that could cause property access nodes to report an erroneous error when using split pins in functions.

Fixed a bug that failed to allow you to apply permissions to Physics Assets and Control Rigs in the Skeletal Mesh context menu.

Fixed a bug that prevented users from enabling smoothing for BlendSpaces.

Fixed a bug that could occur while compiling an animation blueprint that contains a Control Rig node that caused a memory stomp.

Fixed a bug that could cause users to be unable to set defaults on interface pins.

Fixed a bug that caused a blueprint function's thread safe property to not update after a user performed undo and subsequent redo commands.

Fixed a bug that could occur causing asset overrides to not work correctly for blendspace and sequence playback nodes that use identical defaults.

Fixed a bug that caused the display of the animation compression progress to not occur.

Fixed a bug that caused leaking linked animation instances when reinitializing animation.

Fixed an issue that could cause LOD issues when baking an animation in Sequencer, including stretched and deformed geometry.

Fixed an issue that could cause compiling irregularities with child animation Blueprints.

Fixed a bug that could prevent editing of input parameters on input pose nodes in the main animation blueprint graph.

Fixed a bug that could cause nested structs that are bound to animation node pins to not display their child values.

Fixed a bug that could cause non-editor-ticking skeletal meshes to produce unexpected animation LOD results after compiling.

Fixed a crash that could occur in cooked builds where references to editor-only properties were left in the animation blueprint bytecode.

Fixed an issue that could occur to a characters reference pose when linking in a new linked anim graph and compiling.

Fixed a bug that could cause animation compression settings to preload before any load of game content in editor builds.

Additionally Fixes have been made to prevent warnings about calling LoadObject in PostLoad of animation sequences.

Fixed a crash that could occur from Layered Animation that are linked from initialization and added runtime warnings for situations when this could cause issues.

Fixed a bug that could cause erroneous warnings to occur regarding child animation blueprints.

Fixed a bug that could cause a display of animation layer interfaces on content browser tiles.

Fixed a bug that could cause renaming issues with linked animation layers where some layer nodes would not correctly pick up the rename.

Fixed a bug that could cause a duplication of animation blueprints with custom property bindings producing internal compiler errors.

Fixed a bug that prevented ticking of animation instances during reinstancing.

Fixed a bug that could cause per-bone sample smoothing to not affect the correct bones.

Fixed a bug that could occur when adding or removing an animation layer graph's input pose, the instance will now refresh instances without requiring a manual refresh.

Fixed a bug that could occur with the animation blueprint interface falsely displaying in the asset creation menu.

Fixed a bug that could produce incorrect collisions when using the URO / budget allocator interpolation combined with the SkipKinematicUpdateWhenInterpolating flag.

Fixed a bug that could cause the Layered blend per bone node's Blend Masks to fall out of sync with any present Blend Poses.

Fixed a bug that could cause Animation Blueprints that contain Pose Handlers to behave improperly by expanding the asset override tree.

Fixed a bug that could cause the blend profiles submenu to not appear on a subsequent opening of a skeleton asset.

Fixed a bug that could occur when using mesh-space blending in Blend Spaces, in particular additive or offset Blend Spaces.

Fixed a bug that could cause animation node functions to be bound in Layered Animation interfaces.

Fixed a crash that could occur when reverting an added bone socket or virtual bone to a Skeleton asset.

Fixed a bug that could cause deleted Skeleton assets to still be listed in the Compatible Skeletons list of other Skeletons.

Fixed a bug that could cause an Undo/Redo command to not function when performed on a BlendSpaces' "BlendSpaceDetails Axis" properties.

Fixed a bug that could cause a tracepoint break from triggering when frame-stepping in the editor with an active Animation Blueprint preview.

Fixed a bug that could cause erratic behaviors when attempting to create comments in any Animation Blueprint graph.

Fixed a bug that could cause irregular behavior with the Blend Profile slider when making minor adjustments.

Fixed a bug that could cause the Pose pin attribute connections to not display properly when routing through a reroute node in Animation Blueprints.

Fixed a bug that could occur when copy-pasting nodes dependent upon a source State Machine state to carry over their existing dependencies.

Fixed a bug that could cause tags to not display on State Machine nodes.

Fixed a bug that could open the 'Create Animation Blueprint' window off-screen when using Windows scale window.

Fixed a bug that could cause the Retarget Pose from Mesh node to display an error when compiling, stating the exposed IK Retargeter Asset input binding has not been defined when an asset is assigned using the node properties or graph interface.

Fixed a bug that could cause incorrect asset menu actions to appear for Animation Blueprints.

Fixed a bug that could cause pin type colors to only appear white in state machines.

Fixed a bug that could cause blend profile entries to persist after their parented bones have been removed from a skeleton.

Fixed a bug that could cause blend profile names to be reset if you clicked off of the field, rather than committing the name using Enter.

Fixed a bug that caused the AnimationStreaming library to use incorrect Low-Level Memory Tracker tags, designated for audio tracking.

Fixed a bug that could cause incorrect behavior in Spline IK node.

Fixed a bug that could cause the Sequence Player node's start position description to not match its functionality.

Fixed a visual bug that could cause Animation State Machine UX to display trailing dots at each option.

Additionally, the Add New State Machine option has been renamed to State Machine.

Fixed a bug that could cause errors with the auto-wire functionality for non-pose pins on nodes in Animation Blueprints.

Fixed a bug that could cause a Skeleton's defined preview mesh to be reset if it comes from a compatible skeleton.

Fixed a bug that could cause the Animation Notify Panel to not display the notify selection correctly when working with custom window display scaling.

Fixed a bug that could cause Sync Groups to not work correctly during zero-duration/inertial blends.

Fixed a crash that could occur if an Animation Sequence is deleted while in use in a Blend Space preview editor.

Fixed crash that could occur when Pose Watch has been enabled on a Skeletal Mesh Component.

Fixed a bug that could cause the Inspector Panel to not update a node's properties if not explicitly selected.

Fixed a bug that could cause a mesh's details text overlay to block mouse selections in the Animation Editors.

Fixed crash that could occur when changing an Composite Animation segment's start time, end time, or play rate.

Fixed a bug that could cause the Animation Blueprint's Random Sequence Player node to not transition out when an automatic transition rule is active.

The FAnimNotifyEvent::IsBlueprintNotify() now supports metadata filtering using the AnimNotifyList.

Fixed a crash that could occur after duplicating a State Machine in the MyBlueprint panel, within the Animation Blueprint editor.

Fixed a bug that could cause issues when remapping a character's skeleton including incorrectly adding or removing virtual bones.

Fixed a bug that could cause Blend Space Evaluators to not generate Animation Notifies during playback.

Fixed a bug that could cause proportionally-linked Animation Notifies to not move when the length of the Animation Sequence is edited.

Fixed a bug that could cause incorrect clipping behavior of Animation Notifies when the length of an Animation Sequence is edited.

Fixed a bug that could cause sync groups to not function properly when using a Transition Leader group across non-zero-length transitions.

Fixed a bug that could cause a Skeleton's associated assets to not load properly.

Fixed a bug that could cause Sequence Evaluator nodes to not be displayed in the Rewind Debugger's Blend Weights view.

Fixed a bug that could cause weapons and other attached objects to not stay attached to the character when scrubbing in Rewind Debugger.

Fixed a bug that could occur in Rewind Debugger and Animation insight where, Inertialization node properties were not shown under the correct node in the Anim Graph Debug view.

Fixed a bug that could cause the Make Dynamic Additive node to incorrectly respect the ExpectsAdditive flag.

Fixed a bug that could cause bone transforms stored on the clipboard to not correctly paste.

Fixed a bug that could cause the UI in the animation timeline editor from adding float and metadata curves.

Fixed a bug that could cause single frame discrepancy between the information shown by the Rewind Debugger and the previewed Skeletal Mesh on the editor viewport.

Fixed a bug that could cause some untagged memory allocations in GameplayInsights and SourceFiltering to include a proper LLM tag.

Fixed a bug that could cause a camera Feild of View (FOV) to not replay correctly when scrubbing in Rewind Debugger.

Deprecated:

Deprecated the unused bRaiseMaxErrorToExisting with the UAnimationSettings.

Deprecated all master and slave terminology, to indicate dependent relationships in the codebase, the new terminology is now Leader and Follower respectively.

New:

Added blueprint functions to get and set Control Rig parameter section masks.

Animation Sequence sections now contain the Swap Root Bone property, where you can choose to apply root motion animation to the Actor or Component in Sequencer.

You can now include or exclude Bones or Curves from being recorded in Take Recorder by using Include Animation Names and Exclude Animation Names.

Added several Blueprint functions to LevelSequenceEditorSubsystem:

ConvertToPossessable

ConvertToSpawnable

Copy/Paste Tracks

Copy/Paste Sections

CopyPaste Bindings

Copy/Paste Folders

AddActors

CreateCamera

Added Start at Current Timecode to Take Recorder. If enabled, this makes Take Recorder start recording at the current sequence time as opposed to restarting at the playback start time.

Added Swap Buffered Curves which stores the current curve to the buffer and restores the buffer to the current curve. The Store/Swap/Apply options can be accessed when right-clicking on keys or curves in the Curve Editor.

Added a new toggle to show or hide Buffered curves in the Curve Editor if the curve is selected.

You can now specify a specific bone in a skeletal mesh to record timecodes onto using Animation Attributes. If the bone name doesn't exist, it will fall back to the root.

Added functions for evaluating the root bone timecode and subframe attributes in Editor Utility Widget Blueprints.

Curves will now automatically frame when pasted in the Curve Editor if Auto Frame is enabled from the Curve Options menu.

FMovieSceneGeometryCacheParams is now exposed as a BlueprintType.

Mass Scale can now be animated in Sequencer.

Added a recording speed field in Take Recorder, where you can set the Time Dilation of the engine when recording.

Added SetMaterialIndex and GetMaterialIndex Blueprint Functions for PrimitiveMaterialTrack and ComponentMaterialTrack.

Added new commands that can be bound to keyboard shortcuts for Control Rig Controls filter, Control Rig Selected Controls filter and Reset filters.

Subsequence and Shot Tracks can now be filtered in Sequencer.

Added SetDefaultParameters Blueprint function for Take Recorder.

Timecode Subframe values will now display on Animation Sequence sections in Sequencer as a suffix when present in animations.

Added an option to Snap Time to Selection in the Curve Editor.

Added a tooltip to the Object Binding Track in Sequencer to show the object class that it is bound to.

Added the ability to toggle jobs in Movie Render Queue.

Added Sequencer GetByteTrackEnum and SetByteTrackEnum Blueprint Functions.

Added new marker hotkeys to Curve Editor:

Step to Next Mark: Ctrl + Shift + Period (.)

Step to Previous Mark: Ctrl + Shift + Comma (,)

Create / Delete Mark at current time: M

Added an option to TakeRecorderActorSource to show or hide the progress dialog.

Added functionality into TakeRecorderSourceHelpers to add or remove Actor sources.

Enhanced the Frames Per Second tooltip with the names of the Level Sequences that are not matching when there is a frame rate mismatch between Subsequences and their parent.

Added support for the new property setter functions, for example, UPROPERTY(Setter = MyPropertySetter). When evaluating a property keyframe, Sequencer will call this function if it exists.

Added an option to show or hide the status bar in Sequencer's View Options menu.

Added an option in the View Options menu to automatically expand nodes in the Sequencer Outliner upon the child being selected.

Added an option to gather child bindings on FBX export from Sequencer when using Python.

You can now render multiple cameras in a scene at the same time. When the experimental feature is enabled, the main camera used for the sequence, in addition to all other camera components rendered in the scene, will be rendered simultaneously as additional passes.

Added a new experimental Cinematic Prestreaming plugin that you can use to record certain types of asynchronous streaming requests, such as Nanite and Virtual Textures. You can then playback these streaming requests in a Level Sequence after the initial scene render, but in advance of when the scene is visible to the player.

The experimental Cinematic Prestreaming plugin is designed to improve cinematic quality offline rendered cinematics.

Offline rendered cinematics are able to avoid Texture resolutions from being visible in the final frames, but requires rendering two passes. The first pass to generate the request list and the second to use the generated data.

Added a new experimental flushing mechanism to the sequencer texture streaming system to remove any blurry textures that would be visible when using texture streaming.

Using texture streaming significantly reduces VRAM usage when rendering large scenes. This will automatically be enabled if you use the Game Overrides setting to set Texture Streaming to Don't Override. This feature can be disabled by setting bFlushStreamingManagers to false.

Added a new lookup table to channel proxies for finding channels by name.

Added new Sequencer commands to clear selections in Sequencer and Curve Editor using the Escape key.

Added a new Lazy-create for the camera's animation sub-system linker. This simplifies debugging by creating less linkers in simple test levels.

When rendering a shot, you can now specify the render to only include the shot in the context of the root sequence.

You can now specify Data Layers instead of Editor Layers in the Stencil Layer feature.

Sequencer Channels can now be overridden with other types of channels.

For instance, you can now change the Rotation.X channel of a transform section, which is normally a keyframed curve channel, to make use of a perlin noise generator channel.

Added more system information categories to EXR metadata such as total memory available, total memory used by all processes, cpu vendor/name, and more.

It is important to note, not all metadata is supported on all hardware.

Added a simplified API for creating renders using Movie Render Queue in game at runtime.

Added a new role to sequencer's Entity Component System (ECS) linkers to make it easier to set debug breakpoints in linker code.

Added more descriptive statistics for each property type, instead of using Apply Properties for all property types.

Added finer control over which systems are included or and which are excluded in a given linker.

With the Debug Options property, you can now automatically capture an Unreal Insights trace for the duration of the render.

This makes it easy for artists to capture a trace file to send to programmers for further analysis when they see unexpectedly slow performance.

The example Python Runtime executor has been updated with a corrected command line argument, and printed warnings about how the script is meant to function as an example and will need editing to be usable in a project.

Added a root sequence's name to sequence instance classes for easier debugging.

Added a menu extender to sequencer, and to sequencer context menus, so that multiple channels can extend their menus.

You can now copy and paste related controls between multiple Control Rigs in the Curve Editor.

You can now toggle the IsEnabled state of sequencer properties using Python scripting.

The version token can now come after shot_name in the format list and will be treated as a local version of the per-shot folder, instead of a global version, which is shared by all shots.

The Exposed UMovieSceneSection::GetAutoSizeRange() property is now exposed to scripting using the UMovieSceneSectionExtensions.

For tracks that support auto-sizing, such as animation and audio, you can now query if the auto-size data has a start and end frame, as well as if it receives the data. This simplifies adding assets using Python as you can use a unified function, for all tracks that support GetAutoSizeRange, regardless of underlying asset type. This addition simplifies the need to use a unique way of determining how long an asset is for each type.

Added a system to check for valid players in camera cut tracks to fix edge-case crashes when saving a level sequence.

You can now add Sequences to Sub-Sequences with the InsertSequence command, similar to the InsertShot command for adding Cinematic Shot tracks.

You can now save the UI width percentage between the Sequencer Timeline and the Outliner in Sequencer settings.

You can now drag-and-drop Data Layer assets from the Data Layer window or the Content Browser into existing Data Layer sections.

Added the new console variable Sequencer.DuplicateLinkedAnimSequence, that you can use to toggle an animation sequence's duplication behavior when the level sequence is duplicated.

Added new Tween Tool modes:

Push / Pull

Blend to Neighbor

Added Linked Anim Sequence functions to Blueprints and Python:

Create Linked Anim Sequence

Get Linked Anim Sequences

Get Source Level Sequence

Sequencer playback hotkeys now will always function in Animation Mode regardless of panel focus.

Game View will now hide Control Rig Controls in that viewport.

Added an editor preference to enable drag selection on left mouse click instead of moving the camera: Left Mouse Drag Does Marquee.

Created a new Project Setting category for Cinematic Camera where you can set defaults for Lens, Filmback, and Aspect Ratio Crop.

Indirect manipulation using Ctrl now works with Control Rig objects.

The Orbit camera around selection editor preference now correctly works for Control Rig Controls.

Marked up LevelSequenceEditorSubsystem with _API macro to allow for usage outside of the module.

Added an option to disable reacting to playback replication changes on the sequence player.

Added a native interface for controlling whether the effects of a UMovieSceneSequencePlayer can be observed.

Added IgnoreFitlersWhenCollapsed setting so if a section is collapsed and there is a filter, it will only show filtered key areas when that flag is false. Defaults to true to keep existing behavior.

Changed template sequence actors to use asynchronous updates.

Added a scripting method for deleting root folders from a sequence.

Exposed LinkAnimSequence function to scripting.

ALevelSequenceActor::LevelSequenceAsset is now a replicated property and initializes the player if it changes.

Exposed movie scene sub section / focused sequence navigation to scripting:

Focus section

Focus parent

Get hierarchy

Added a GetDescendantSubSections function to MovieSceneCommonHelpers.

Improvement:

Moving a keyframe to the same time as another keyframe in the Curve Editor will now remove and replace the old keyframe.

The Look at Tracking Interp Speed property on Cine Camera Actors is now animatable in Sequencer.

Buffered Curves are now consistently called Buffered Curves in the Curve Editor instead of Stored Curves.

Buffered curves now can only apply and swap to the curve it was made on.

You can now cancel a Take Recorder recording that is in progress.

The Cinematic Viewport timeline range is now synchronized to Sequencer's timeline. This change helps prevent cases where the timeline padding could appear very large and unusable, due to a large working range.

You can now add an animation track to the top level Actor binding if the root is a Skeletal Mesh component. This loosens previous restrictions to make it more convenient to add animation without also needing to add Component Tracks first.

Added Play/Pause/Stop functions to the Actor Sequence Component.

The Track filter button now has a red dot to indicate if any filters are active.

Camera Cut tracks are now included in the Cameras track filter.

Sequencers main toolbar has been converted to use the Tool Menus framework.

Several color changes have been made to curves and keyframes in the Curve Editor.

Keyframes are now the same color as the curve.

Selected keyframes are white, which can be changed in Editor Preferences.

The default color for non-axis curves is now a darker gray.

The blue channel for Z and B channels is now brighter to contrast better against the dark background.

Locking and unlocking camera cuts can now be performed with Shift-C.

Added MOVIESCENETRACKS_API to some MovieScene3DTransformSection Functions so they can be used by other Plugins.

MovieScene::SetComponentTransformAndVelocity can now be used by other Plugins.

Actors referenced in Sequencer now no longer forcibly show in the Outliner, unless it is a Spawnable.

The ExportLevelSequenceFBX Python command is now able to export a Subsequence within a Master Sequence.

Added hotkey support for selecting all keyframes forward and backward in the Curve Editor. Ctrl + ] and Ctrl + [.

Dragging and dropping Movie Render Queue assets now appends the jobs in the queue to the active queue.

The Sequencer tab will now display with an asterix if the asset has unsaved changes.

Sequencer Bezier interpolation now occurs on doubles instead of floats.

Sequencer can now handle cases in which multiple ECS entities are driving a single transform section. This is a new situation that arises from overridden channels.

Sequencer now passes its owning section when evaluating a channel. Some new channel types, such as perlin noise, need the section pointer to look up contextual data, like tick resolution.

The Use Camera Cut for Warm Up range detection behavior is now the difference between the Camera Cut Section start, and the first evaluated frame of the Camera Cut section itself. This improvement was made to better handle sub-sequences being clipped by parent ranges.

Reduced the amount of concurrent memory required for panoramic blending, by blending it into the final output texture as soon as each sample is done in order to free up more memory.

Cloth behavior, when using temporal sub-sampling, has been improved by automatically increasing the sub-step count when needed.

It is important to note that Cloth will still present a different result than in viewport due to the increased number of chances to resolve collisions and have physics forces applied.

You can now have multiple Control Rig's active at the same time. Using the Outliner, you can now observe and manage all Control Rigs in the active level sequence.

Linked Anim Sequences will now save when the Level Sequence is saved.

Parent and Child definitions in the Snapper tool will now reset when switching Shots or Subsequences.

You should now only be able to snap to a single parent when using the Snapper Tool.

Added Evaluate All Skeletal Mesh Components option to AnimSequenceLink.

Linked Animation Sequences will now be dirtied at the same time you dirty your Level Sequence.

Crash Fix:

Fixed crash with ReplayTracks plugin.

Fixed a crash that would occur when modifying a parent asset while recording with Take Recorder.

Fixed a crash that could occur when using the Command Line Encoder option if the output directory tree did not fully exist before encoding started.

Fixed a crash that would occur when keying onto additive sections with different number of controls due to the hidden track editor variable.

Fixed a crash when unresolved bound objects in Sequencer were being deleted.

Fixed a crash when calling FindOrGetDefaultSettingForShot when InMasterConfig was null.

Bug Fix:

Set Curve Color For Selected now only changes the color for selected and not all curves.

Fixed an issue where repeatedly setting custom curve colors would result in broken keyframe coloring in the Curve Editor.

Changing curve colors in the Editor Preferences menu now correctly applies the color change immediately.

Fixed still being able to add and move Marks if Sequencer was locked.

Fixed subtitles appearing even when Suppress Subtitles is enabled in the Audio track section.

Fixed a bad cast error when trying to cast to a MovieScenePropertyTrack.

Fixed a bug where all Control Rig controls would be selected if you selected the Folder Track that contained them.

Fixed an issue where the Sequencer editor menu extensions were shown for sequence types other than Level Sequences.

Fixed synchronization issues where curves would not appear in the Curve Editor if you had Selected Control Rig Controls enabled.

Fixed an issue where dragging a Control Rig into Sequencer would create a duplicate Control Rig track for the actor and all of its skeletal mesh components.

Sequencer: Clamp to playback range before snapping to frames, otherwise the scrubbed to frame could be a subframe when snapping is on.

Fixed a bug where all Animation Notifies would fire at once at the loop point when looping animations in Sequencer.

Fixed an issue with adding keyframes in the Curve Editor using Ctrl + MMB would still cause slight disturbances to the curve shape if snapping was enabled.

Fixed Curve Editor snapping to occur in all view modes: Absolute, Stacked, and Normalized.

Fixed an issue with Camera Rig Rail where the mount visual would rotate if Lock Orientation to Rail was disabled.

Fixed an issue where muted tracks could be muted forever when deleting tracks.

Fixed smoothed replicated playback causing desyncs during looped playback.

Fixed an issue when copy and pasting attached spawned objects not correctly binding to the newly pasted bindings.

Fixed an issue with Curve Editor bindings for Zoom To Fit All, Zoom To Fit Horizontal, and Zoom To Fit Vertical not working.

Fixed an issue where if you select a control in the Anim Outliner or in Sequencer, the transform gizmo wouldn't appear because the Control was not considered selected.

Convert to Spawnable now creates a transform track that takes the transform origin into account.

Fixed an issue when recording Spawnable Actors in Take Recorder that are children of other Actors not being recorded resulting in the recorded Actor appearing at an incorrect transform.

Fixed a crash in Sequencer when dragging "Animation Mode" keyframes.

Fixed an issue that caused the playhead to not follow the cursor consistently when dragging it at low speeds.

Fixed an issue where deleting a recorded Actor after a Take Recorder recording would cause all Actors to be removed from the source list.

Removed interp from RelativeScale3D, which fixes an issue where meshes would flicker between their initial Transform Scale Values and the Relative Scale 3D values on playback.

Fixed an issue where not all keyframes would be selected when clicking on a curve in the Curve Editor.

Fixed an issue for the Control Rig Snap Tool not taking full world transform into account.

Fixed a bug with Control Rig selection where if you select a keyframe on a Control Rig element, the corresponding element would get deselected.

Fixed a bug where changing a color on a keyframe using the Color Picker would also reset the keyframe tangent.

Fixed an issue where if you select a Control in the Anim Outliner, the transform gizmo won't be updated so you can't click on a gizmo to move it immediately.

Fixed an issue where sometimes the clicking and dragging would drag the playback ranges instead of the playhead.

Fixed an issue where OnStop would not always fire.

Fixed an issue where Spawnable objects can't be retrieved immediately after opening Sequence.

Fixed a case where Take Recorder would get confused over which Camera to bind to the Camera Cuts track if another Camera was a Component of an Actor.

Fixed an issue with Camera frustum visualizations not updating when lens values update in Sequencer.

Fixed an issue where undoing in the Curve Editor would change the current time.

Fixed an issue where the Snapper Tool would not correctly work when snapping backwards from your current time.

Fixed an issue where deleting the last keyframe would not reset the property to the previously unkeyed value.

Fixed an issue where pasting keyframes in the Curve Editor would paste to all curves in view and not the selected one.

Fixed an issue where Muted track sections could still have their data changed.

Fixed ExponentialHeightFog.SecondFogData properties not dirtying render state when set from Sequencer evaluation.

Fixed an issue that prevented saving a Control Rig animation to an Animation Sequence that was currently being referenced in Sequencer.

Fixed an issue when copy and pasting tracks with multiple bindings on it.

Fixed a bug that could use name-lookups for channels, instead of assuming their type and index.

name-lookups is now a potentially invalid assumption when channels can be overridden.

Fixed a bug that could cause cloth simulation to not occur if a render was started long after the level was first loaded.

Fixed a bug that could cause Control Rig to mark a section as changed when the channel proxy changes.

Fixed a bug that could create an arbitrary section range when a new section is created past the playback end.

Fixed a bug that could cause high temporal sample counts to have their delta times clamped during Level Tick which created mismatches between calculated component velocities and render thread delta times.

Fixed a bug that could cause clamping of looping subsequences.

Previously, a compilation's range was clamped by the containing section's range, so some of the sub-sequence's animation would not be taken into account after the last loop and still play.

Fixed a bug that could incorrectly initialize a camera's animation sequences upon creation.

Previously, sequences were only initialized when the asset was opened in Sequencer for the first time. This could lead to problems if the asset was added to something else, like a camera shake or a level sequence, before edits were made..

Fixed a bug that could cause a regression in jpeg or png file's writing times that significantly slowed down large resolution renders.

Fixed a bug that could cause a widening of old, single-precision floating point properties on Blueprints.

Fixed a bug that could cause an issue with setting default values when the binding ID changed for actor reference sections.

Fixed a bug that could cause a visible seam on the right edge of the editor.

Fixed a bug that could cause png alpha channels to only register as partially transparent.

Fixed a bug that could cause erratic behavior with alpha-in-tonemapper warnings.

Fixed a bug that could cause a Trigger Cameras to cut changes between camera cut sections even if the camera actor is the same.

This restores a previous edge-case behavior that users relied on for their projects.

Fixed a bug that would register the same tick client multiple times.

Fixed a bug that could cause default-construct components created by a mutation to prevent corrupted memory from making it into the sequencer evaluation.

Fixed a bug that could cause code from getting a component writer to a single entity.

Fixed a bug that could cause non-layered EXRs from using the wrong Alpha Allowed property which prevented the property from writing out to alpha channels.

Fixed a bug that could cause a project's aspect ratio constraints to not correctly restore.

Fixed a bug that could prevent selected infinite sections from being moved or dragged.

Fixed a bug that could cause an issue when trying to use png files in combination with the Command Line Encoder failed with some third party encoding software.

Fixed a bug that could fail to try and resolve bound actors with component possessables.

Fixed a bug that could cause the Command Line Encoder to not use version tokens in the filename.

Fixes a bug that could clear delegates tied to destroyed objects that should not be left in the latent actions list.

Fixed a bug that could causethe additive-from-base blend type to not perform when recomposing values for keying.

Fixed a bug that could cause the project settings class for Render (Local)/Render (Remote) to not properly store references to late-loaded class types such as those defined in Python or in a game's Plugins.

Fixed a bug that could cause the 'Write all Samples' to not respect the project_dir format string.

Fixed a bug that could cause separately composited Burn In/Widget Renderers to not actually write an alpha channel when the main output was as JPEG or BMP file.

Fix bug that could cause a section-preroll to be ignored for camera cut tracks.

Fixed a bug that could cause the DetailLighting render pass not apply the correct view modes causing reflections to not display.

Fixed a bug that caused the float and double channel context menus to not merge into a single "curve channels" context menu.

Previously, the float channels, specifically the channel for transform sections, was not affected by any context menus.

Fixed a bug that could cause multiple custom movie renderers to be displayed at once, instead of just the current one.

Fixed a bug that could cause the template sequence property multipliers to not always be reliably being taken into account.

Fixed a bug that could cause high temporal sample counts being artificially clamped by overriding the minimum timestep for Chaos Physics to zero during renders.

Fixed a bug that could cause Tick Resolution migration code to not successfully migrate locked sections and not migrating Marked Frames.

This fix also adds the ability to recursively apply the time migration to all child sequences.

Fixed a bug that could occur when trying to add a job through the Sequencer UI, then disabling a setting, and then adding the job again, which could result in the disabled settings to duplicate and become active again.

Fixed a bug that could cause formatted strings that come from shots to provide the incorrect values, from the Master Configuration, when used in filenames.

Fixed a bug that could prevent the use of the job initialization timer when using the year, month and day tags, which would cause files to go into separate folders when a job rolled over midnight in UTC time.

Fixed a bug that could cause Video Codecs to function when the Overwrite Existing property was disabled.

Fixed a bug that could prevent a saved Queue from showing the correct names for jobs that used Presets for their settings.

Fixed jobs with modified presets having the wrong name after being duplicated in the queue.

Fixed a bug that could cause the MoviePipelineInProcessExecutor to crash if provided with a bad Sequence path.

Fixed a bug that could cause the date and time tags to not resolve in output paths when clicked on in the UI.

Fixed a bug that could cause the full path name of template sequences' bound actor classes to not register if only its short name was saved.

Fixed a bug that could cause the Animation Custom Mode and Swap Root Bone properties to not be exposed to Blueprints.

Fixed a crash that could occur by calling DeleteAllJobs immediately after calling RenderWithExecutor.

Fixed a bug that could fail to include a sequence's play rate when computing sequence shake pattern duration.

Fixed a bug that could generate duplicates from bindings when first resolved.

Fixed a bug that could cause motion blur to get stuck when the Camera Cut track stopped evaluating.

This was only an issue if the Motion Vector Simulation system was enabled and the camera being returned to was not a Cine Camera Component.

Fixed a bug that could cause an incorrect upkeep of property stats when upgrading floats to doubles.

Fixed a bug that could assert on exit if the runner's linker is pending kill.

This could happen if the linker is flagged for destruction before whatever owns the runner.

Fixed a bug that could cause alpha channels to be speckled due to dithering when using png and jpeg file outputs.

Fixed a crash that could occur in the Animation Sequencer animation selection filter, by adding Montages to animation tracks.

At this time, only animation sequences are currently supported.

Fixed a crash that could occur with Video Codecs when they failed to initialize due to an invalid output file path, such as writing to a hard drive that did not exist.

Fixed a bug that could cause mapped Skeletal Mesh to not update the Skeletal Mesh accordingly to the controls.

Fixed a bug that could cause all linker evaluations to start with an un-clean capture source, even in cases when there are nested linkers running.

This fixes asserts caused by mismatched pre-animated states.

Fixed a bug that could cause a custom range for Move Render Queue renders in shipping builds to be incorrectly set.

Fixed a bug that could cause a baked Control Rig to include all of the rig's Compatible Skeletons.

Fixed a bug that could cause only select Control Rig Controls to deselect when a control isn't clicked.

Fixed a bug that could cause Network Level Authentication (NLA) issues with root motion not blending correctly when there are multiple skeletons blending.

Fixed a bug that could cause drag-and-drop functionality, when adding animation sequences to the Sequencer timeline, to create a new dedicated track rather than adding the sequence to an existing track.

Fixed an issue where copy and pasting Control Rig data would not paste correctly if the Selected Control Rig Controls track filter was enabled.

Fixed an issue where orbiting (Alt + LMB) the camera around a selected Control Rig would sometimes duplicate it.

Fixed an issue where orbiting (Alt + LMB) the camera around a selected Control would sometimes move the Control instead of the camera.

Fixed an issue where duplicating Linked Anim Sequences would point to both the original and the duplicate.

Fixed a case where sequencer bindings could be resolved using the wrong PIE instance ID.

Fixed replicated sequences that begin at a non-zero start time causing a jump on the first frame.

Fixed an issue where Motion Trail keyframes would appear at the level origin, instead of hiding.

Fixed derived Cine Camera data not updating when modifying properties from Blueprints.

Fixed an issue where very small marquee selections would sometimes select all Control Rig Controls.

Fixed an issue with Motion Trail ticks not drawing correctly in multi-viewport scenarios.

Curve Editor selection no longer changes which Controls are selected in the Viewport.

Fixed bound object pointers not being available to child entity instantiators.

Fixed an issue that would cause an Actor with a Control Rig to continuously pop back to its default position in Sequencer when moving the Actor.

Ensured that the current Level Sequence closes before opening the next one when switching Level Sequences.

Fixed an issue that would cause recorded animations from the Take Recorder to be invalid if spaces were in the name.

Fixed an issue where if Selected Control Rig Controls was enabled, Curves would not show up in the Curve Editor.

Fixed an issue where undoing keyframe changes on multiple Control Rig Control would have to be done by undoing each keyframe operation per Control.

Fixed Actor properties controlled by Actor Reference Tracks not being restored correctly if they were null.

Fixed an issue where compression would reset to default compression in Sequence Recorder.

Fixed an issue where scrubbing in the Viewport by pressing B and dragging would not cause audio to play from Audio Tracks.

Fixed an issue where if you called Job->SetConfiguration(Job->GetConfiguration()) it would remove all of the settings from the MRQ job.

Fixed an issue where Sequencer Attach tracks would dirty actors in levels.

Fixed an issue where recording into Subsequences using the Take Recorder wouldn't save them if Save Recorded Assets was enabled.

Fixed looping point indicators not being correctly positioned on Media Track sections that don't start at 0.

Fixed an issue where creating Takes would not respect number padding in your Shot name.

Deprecated:

Sequence Recorder is now hidden in favor of Take Recorder. If necessary, it can be re-enabled with the SequenceRecorder console command.

Deprecated GetSelectedObjects()/SelectObjects in favor of GetSelectedBindings/SelectBindings which operates on FMovieSceneBindingProxy for consistency with all other Blueprint and Python functions.

Deprecated SequencerBindingProxy and typedef it to MovieSceneBindingProxy.

Removed the Export to Camera Anim... feature as it is unable to perform any actions without the deleted Matinee Asset Factory.

Removed:

Completely removed Matinee from the codebase including the data types and runtime evaluation code.

The "InterpEdit" editor mode, asset factories, and other editor support for Matinee.

CameraAnims and their sequencer tracks.

FBX import/export for Matinee assets is removed. Sequencer is now used for all cinematics and camera animation needs.

New:

The new experimental Physics Control Component plugin allows you to add simple, intuitive, and powerful physically-based controls to a Blueprint. With these physics controls, you can take advantage of the emergent physical motion of Static and Skeletal Meshes, while retaining artistic and gameplay control.

Added a new frame based animation timeline setting for the ML Deformer editor.

Use the new command TSoftObjectPtr for training related properties, and only load them when needed.

By defining what parts of the character's mesh will be deformed using a Geometry Cache file, you can now use Skeletal Meshes with more meshes than geometry tracks when generating models using the ML Deformer framework. For example, a Skeletal Mesh character could contain teeth, eyes, etc, while the geometry cache file does not contain those meshes.

Improvement:

Added function libraries missing for Mac builds and NumPy to PythonFoundationPackages. This fixes training errors in the ML Deformer on Mac.

The Machine Learning (ML) Deformer system has been redesigned as a framework that can handle different models using a new unique editor, assets and components. You can explore this new framework by installing the ML Deformer framework plugin.

Improved and simplified the model training process for the MLDeformer VertexDeltaModel.

Improved the Neural Network model by switching rotations from Quaternions to 2 columns of the 3x3 rotation matrices.

You can now store extra per-individual mesh information from FBX scenes when importing FBX files to Unreal Engine.

Bug Fix:

Fixed a bug that could occur if a site packages directory on Mac was not named correctly in PythonFoundationPackages.

Fixed a crash that could occur due to a ML Deformer Model that failed to locate and identify a GPU device.

Fixed a bug that could cause pose generation to fail when using Python code to generate poses for the ML Deformer poses in AutoDesk Maya 2022.

Editor

API Change:

The UAssetToolsImpl::ImportAssetTasks function now properly sets the imported Assets in the FAssetImportTask::Result member of the passed ImportTasks parameter.

Any code that was checking for EPropertyChangeType::Unspecified for movement of array items in the property details panel should now use EPropertyChangeType::ArrayMove instead.

New:

Adding a UI wrapper around the CSV to SVG Tool command line tool.

The arguments are stored as a UObject with reflected properties so you can get a "free" UI by using the property window. Also, this lets you use serialized arguments so you can potentially re-use the settings. You can also programmatically generate the arugment list to pass to CSVtoSVG by iterating the relfected properties.

Added SCSVtoSVG widget which contains/owns the arugment UObject, a property window to edit it, and a SStatList.

When the CSV file property on the arugment changes we infer an output directory and output file name from the input csv file. These can be overriden.

The tool also parses the CSV file to find all the available stats in it to populate a SListView.

When you click generate to make the SVG graph we automatically open the graph in a web browser.

Save the current arugments to config when you close the editor.

FEditConditionContext::GetIntegerValue can now fall back on the underlying property if it is an enum. This allows for bitwise comparison in UProperty EditConditions with enums.

Added support for multiple Level templates using the same map package.

Added a new DDS loader with better support for D3D10-format DDS files.

Added support for loading RGBA8-format DDS files.

Added a CanEditChange signature that takes a full property chain to the property in question.

You can now use multiple console commands in the editor by using FParse::Line to allow commands to be split with newlines or pipe characters ( | ).

You can now add a newline in the console command entry box by using Shift + Enter.

Many Anim Dynamics Animation node parameters can now be edited with a widget in the viewport.

Parameters for physics bodies in a chain can be edited independently.

You can no longer copy/paste bone names in the chain bone array.

Added per-level coloring option for the fracture editor outliner and stats details.

Allowed colliding body settings are now copied and mirrored when physics bodies are mirrored in the Physics Asset Editor. This means that a mirrored body can now collide with the mirror equivalents of its source's allowed colliding bodies.

Bone mirroring in the Physics Asset Editor now recognizes bones that have an "l" or "r" pattern anywhere in their names as 'left' or 'right' bones and will mirror them correctly.

The Asset summary text displayed in the Physics Asset Editor viewport now includes the number of potential colliding pairs of bodies, the number and type of each primitive shape, and the number of cross constraints in the current Asset.

Added additional editor scripting APIs to modify Blueprint variable flags and metadata in BlueprintEditorLibrary.

Added an option to disable collisions with the floor when simulating in the Physics Asset Editor. This option is located in the overflow menu of the Simulate toolbar button.

Added a new column mode parameter to the Fracture Editor outliner that displays various information per bone depending on the the selected mode.

UBlueprintAsyncActionBase - Made WorldContextObject parameter const in RegisterWithGameInstance.

UEditorUtilityBlueprintAsyncActionBase - Made WorldContextObject parameter const in overridden RegisterWithGameInstance.

Add an option to use the P4Config in the Unreal Editor.

Exposed Asset Migration command to scripting.

Added a new GetSelectedFolderPaths function to get the currently selected folder(s) path in utility widgets and Python.

Added a new GC section to the Details panel UI which displays properties specific to the geometry collection component.

Sounds are now loaded and compressed asynchronously in the Unreal Editor whenever possible.

Ctrl + Console Key (` by default) now iterates through active Console Command Executors so you can switch between Cmd and Python using the Ctrl + ` shortcut.

Added a new Texture property, ForceRecompressDDCUID, that you can use to manually change the DDC key to force a rebuild.

Implemented Python Type Hinting when generating the Python stub.

Exposed to Python the option to set a minimum width/height dialog when calling the unreal.EditorDialog.show_object_details_view function.

DDS texture import now supports most pixel formats, and all variants of 2D, cube, cube array, and volume textures, with mips.

Added access to debug color texture encoding for Oodle from the command line.

Added log information for enabling and disabling debug color texture encoding for Oodle.

Mip maps are now supported on non-power-of-two textures.

Added Conv_StringToInt64 to Kismet string library.

VT and UDIM can now export to all supported output image formats.

UAssets that store their imported image data as JPEG can export those JPEG bits directly to JPEG output format without decompression.

More image formats import floating point data as F32 and store losslessly in UAssets. Floating point data is no longer converted to F16 at import time.

Added changelists support to PlasticSCM source control plugin (v1.6.2).

Added TRACE_CPUPROFILER_EVENT_SCOPE to Perforce integration plugin to be able to capture some performance metrics.

Exposed UStaticMesh::GetNumTriangles as a Blueprint function.

Exposed UEnum display name to Python through method get_display_name. For example: print(unreal.TextureCompressionSettings.TC_GRAYSCALE.get_display_name()).

Unreal Engine now supports reading the enum entry display name set in C++ as well as the one injected from Python with the @uenum annotation.

Added Shared Linear Texture Encoding. When enabled (r.SharedLinearTextureEncoding), an encoded texture for a console that would tile a base texture will detect if it can use the same base texture as windows, avoiding re-encoding the base texture. This greatly speeds up multi-platform encoding.

Created a new enum entry, EPropertyChangeType::ArrayMove, to signify movement of items within an array by the property Details panel and other callers to UObject::PostEditChangeProperty.

Added a new Texture property, Editor Show Final Encode. Use this property to see the Final-mode encoding of the texture (for example, with Oodle RDO) in the current Editor session, rather than the Fast-mode encoding without RDO.

Exposed IAssetsTools::DiffAgainstDepot and IAssetTools::DiffAssets functions to Python.

Added a warning dialog when performing a blocking operation.

Constraint position and orientation in the Physics Asset Tool (PhAT) can now be viewed and edited in the Details panel.

Parent and child transform values in the PhAT can now also be displayed relative to the default (snapped) transforms (set when the Physics Asset was created).

The position and orientation components of the parent or child transforms can be independently snapped to defaults using right-click menu options or the reset buttons in the Details panel.

You can now manipulate only the child frame transform via a viewport widget by holding down Shift + Alt.

Fixed the warning and error message boxes using all the spaces of the source control submit confirmation dialog if too many errors or warnings were present.

Added a Keep Checked Out button to the source control window.

Added an array of delegates called ShouldDisableCPUThrottlingDelegates in UEditorEngine that can be used to disable CPU throttling for the editor when it doesn't have focus.

The Pose Watch Manager in the AnimBP editor has been extended to allow control of other areas of debug visualization. Each pose watch now contains one or more elements which represent different aspects of an anim node's debug visualization, including the output pose, physics bodies, etc. where relevant. Those aspects can be hidden or shown individually, even when a node is not selected, by creating a Pose Watch for a node and toggling visibility of the elements in the Pose Watch Manager window. At present, the Rigid Body Animation Node (RBAN) is the only one to take advantage of this new feature.

Added new Texture bool bDoScaleMipsForAlphaCoverage to clarify the feature AlphaCoverageThresholds for older textures.

Added a new memory.WindowsPlatformMemoryGetStatsLimitTotalVirtualGB cvar that simulates a lower memory system to lower the chances of out of memory crashes during cooking.

Exporting a Level to FBX will now use Actor labels instead of Actor names for improved clarity.

The Base Shape Material's Base Color was changed from 1 to 0.9. This change affects all base shapes (sphere, box, cylinder, cone, etc.).

Added ASSETSEARCH_API to Asset Indexer classes.

Changed default arcball behavior to act more like other DCCs.

Added a limit cvar to extend the size of the arcball.

Added a Disable Preview Menu option.

Added FriendlyNames to all ShaderPlatforms in DDSPI.

MenuText now comes from FriendlyNames in DDSPI.

Added Units and ForceUnits to ObjectMacros.h for discoverability.

Improvement:

The Material Editor now only compiles a fixed number of shaders (fewer than 10 per platform) with WorldGridMaterial.

Drastically improved editor performance when selecting a very large number of Static Meshes using the marquee selection tool.

Improved job scheduling for parallel texture compression.

Increased cut-offs for number of pixels per Oodle Texture encode job to reduce number of tiny worker-thread tasks generated.

Restoring expanded items in very large Detail panel hierarchies is now faster.

Typing a character while an Asset picker menu is open will now focus the search box if it is not already focused.

Added support for calculating chain bones immediately without waiting for the Anim Dynamics Animation node to be compiled.

Changing bound bone names no longer resets physics body parameters.

PaintedVertices are no longer serialized when collecting object references to avoid needless operations when launching PIE.

The Check Out Files dialog now displays the type of Actor and no longer displays just "Actor".

The Unreal Editor now supports textures up to 32768x32768.

Texture UDIM import now allows mismatched formats.

Texture UDIM export preserves naming convention and allows choice of export format.

Implemented an 'Unsaved' Editor status bar button that displays the number of unsaved Assets (dirty packages) in the project. Click this button to open the Save Content dialog.

Unreal Engine now warns about potential source control issues when saving unsaved Assets.

Instrumented Python plugin loading time and saved about 500ms to the total module startup time.

Source control changelist window now works better with large changelists (One File Per Actor).

Changelist window now supports text search, filtering, and 2-column sorting.

You can use two new keyboard shortcuts in the changelist window: Enter to submit the currently selected changelist, and Delete to delete it.

P4 changelists are now sorted in ascending order.

Operations that don't directly affect Assets, such as creating and deleting a changelist, are now asynchronous.

When submitting a changelist to source control, you can now edit and save the changelist.

If you add a description to the default P4 changelist while files are checked out, the description and all files attached to that changelist are moved to a new changelist.

Crash Fix:

Duplicating array entries in the Details panel containing a null UObject* / TObjectPtr will no longer cause a crash.

Fixed an editor crash when removing the last texture source in a texture array.

Limited sparse data properties to the common base class when multiple objects with potentially unrelated types are selected into the property editor to avoid a potential editor crash.

Improved the memory estimate for building textures, making out of memory crashes during cooking less likely.

Bug Fix:

Fix property display in the Details panel for Levels with the ReadOnlyKeys metadata.

Editor notifications now only start fading out once the editor starts ticking and no longer disappear when loading takes longer than the expiration time given.

Improved FInstancedStruct property editing stability.

Fixed a bug where PIE didn't respect editor FeatureLevel Settings when having PIE MapOverride set up.

Fixed an issue where modules tab wouldn't reliably be available.

FDirectoryPath properties now correctly update the Enabled state of the "..." button.

Fixed an issue that caused the Blueprint diff tool to potentially call IsChildOf on nullptr for newly added classes.

Components panels now show correctly in the Blueprint diff tool for newly added Blueprints.

Scene Outliner selection no longer resets when changing the Level.

Fixed an issue where, under certain circumstances, multiple child entries representing the same object could be added to a Scene Outliner tree item.

Fixed a visual gap in the header of nested categories in the Details panel, notably in a Blueprint's Class Defaults.

Fixed an issue where certain old texture versions had the incorrect compression format set in their internal UAsset data structure.

Fixed an issue where the editor would sometimes not create or update the thumbnail of an Asset when requested.

Fixed rendering issues with geometry collection for Materials using vertex color when the ShowBoneColors option is disabled.

Fixed a bug that caused text boxes created by property row generators to fail to accept multi-line input.

Editing a vector using the spinboxes in its vector no longer causes stuttering due to Blueprint reinstantiation.

Fixed an editor bug where Actors attached to a static mesh socket inside a blueprint actor weren't updating when the mesh was moved.

Fixed ActorFactory overriding custom names given with PostSpawnActor.

Fixed initial dynamic state not being properly serialized when set via the outliner context menu in the Fracture Editor.

Fixed a bug that caused failures for automated processes (cooking) when the connection to the SCM failed even if the actual process did not need the connection.

Focus now correctly returns to the Unreal Editor if the Zip Project command is canceled.

Texture stats memory is no longer reported after async texture compilation has finished.

Fixed a warning regarding usage of banned words.

Upgrade ISPC ASTC encoder to fix a bug where solid-color blocks with very low alpha values would sometimes revert to all black.

Fixed a missing FActorInstanceHandle::InstanceUID initialization in Actor.

Fixed an issue where CreateNewStreamingLevel scripting function would ignore the NewLevelPath argument.

WhitelistConfigFile is now enough to allow for staging individual configuration files from Restricted folders, without having to also specify WhitelistDirectories for that folder as well.

WhitelistDirectories now works properly for restricted directories in distributed builds.

Fixed FSlowTask automatically canceling when dialogs were created with a delay and ShouldCancel was called before the dialog spawned.

UAssetToolsImpl::ImportAssetTasks function now properly adds imported Assets to the FAssetImportTask results.

Fixed the source control history window not properly displaying multi-line submit descriptions.

Fixed a bug that caused some operations made in the Editor to not be reflected in the changelist window.

Fixed a bug that caused validation warning and error messages to show a scroll bar for long messages rather than wrap around.

Fixed Python calling the wrong delegate if the same delegate name or type was declared in two different UObjects.

Duplicating Assets will no longer keep a Perforce relationship to the original file.

Fixed JSON warnings with reference container values in the project launcher.

Fixed the Delete operation not getting called for source control other than Perforce.

Changed the source control changelist widget tab spawner to a nomad spawner to allow restoring the widget dock position on next Editor restart.

Fixed a bug that caused content cooking to hang when TextureFormatOodle was disabled for DXT format.

Implemented a workaround to declare valid Python methods when the corresponding UFUNCTION has default parameter values declared in the metadata, but also has further parameters that don't have default values, which is illegal in C++ and Python.

The Change Source Control Settings dialog accessed from the Unreal Editor top menu bar now behaves consistently when saving the new settings or canceling.

Fixed argument parsing for the HighResShot command.

Fixed the RemoteSession message handler proxy calling the wrong function.

Fixed AlphaCoverageThresholds that were accidentally enabled for all textures with thresholds = {0,0,0,1}.

Added https:// conditions to links in the Plugin Browser.

Fixed nested submenus closing unexpectedly, when opening one by clicking it (instead of just hovering it) and then navigating in submenus.

Redirected Python stdout/stderr to a buffered text wrapper.

The PYTHONUNBUFFERED environment variable now correctly prevents stdout/stderr from buffering when set.

Fixed deadlock in the splash screen happening when the main thread goes faster than the splash screen and tries to hide the splash before the splash screen thread even created the window.

Fixed Python files being filtered out by the Content Browser.

Fixed a Python GIL (Global Interpreter Lock) deadlock that could occur while loading an Asset.

Fixed variables named X64 to avoid collision with preprocessor definition X64.

Fixed FUpdatePendingChangelistsStatus operation that did nothing if a specific set of changelist was requested.

Fixed an issue when serializing an incoming concert transaction in FConcertSyncObjectReader where object pointer properties would get set to null incorrectly if Skip Assets was true.

Marked the FAssetData::AssetClass, FARFilter::ClassNames and FARFilter::RecursiveClassesExeclusionSet as 'Deprecated Property'.

Changed a Python glue generation error into a warning when a make or a break function signature doesn't comply with Python requirements. Downgrading from an error to a warning, with a message saying that the default make/break will be used instead to make/break the Python object, will prevent licensees from hitting a UE_DEBUG_BREAK every time the debugger is attached.

Fixed a memory leak when a long source control operation blocks the main thread while the rendering thread renders to animate the source control feedback popup.

Exposed TFieldPath<T> as 'FieldPath' to Python.

Removed outdated #define SourceCodeNavigation preventing proper source code navigation if the editor was compiled with clang.

Fixed Analytics asserting and crashing the editor when the analytics property store files contained empty key names.

UActorEditorContextSubsystem is now validated when unbinding in the SActorEditorContext Destructor due to a race condition where the subsystem may not exist by the time the destructor is called.

When importing a FBX file through Import Into Level, the Static Meshes will now have DistanceFieldScale set to 1 instead of 0.

Several bugs in the HDR image loader have been fixed.

The HDR image loader now uses much stricter validation.

When importing a glTF file, the tangent space handedness (w component of the glTF tangent vector) will now be taken into account for meshes.

Fixed Asset Search indexing for FSoftObjectPtr representing references to non-Assets (that is, AActor instances).

Removed:

Access to the built-in editor VR Mode has been removed. Virtual Scouting is the recommended alternative for all users going forward.

Removed GetFriendlyShaderPlatformName.

Deleted RHIShaderPlatformDefinitions.inl.

New:

Enabled Nanite support on Opaque Std Datasmith Materials.

3ds Max Exporter: sorted material slots to make them appear in the same order in Unreal as in the source Multi/Sub-Object material.

Removed the "Reuse identical assets" import option from the USD Stage.

Added some example Python scripts that describe some of the new features implemented in Unreal Engine 5.1, and how to interact with USD, for example to import or export. We will continue to add new scripts. You can find all available sample scripts in the "Engine/Plugins/Importers/USDImporter/Resources/PythonExamples" directory.

The Level Sequence generated by AUsdStageActors now binds not only the components that the Actor generates directly, but also the Actors that own those components.

Exposed the USD.GeneratePhysicsAssets console variable, which controls whether to generate physics Meshes for Static and Skeletal Meshes by default.

Added options to the File menu for exporting the open USD Stage to a new set of files. This is analogous to a "Save As" command.

When the open USD Stage's framesPerSecond attribute is updated, the generated Level Sequence now automatically updates its Display Rate to match.

Alias Import: Added the ds.CADTranslator.Alias.LayersAsActors console variable to convert Alias Layers to Actors on import. When you use the console variable, each Layer is added as an Actor, directly under the Datasmith Scene Actor in the hierarchy. Previously the importer only converted group nodes.

Hidden layers are no longer included in the import.

[SketchUp] Starting from SketchUp 2020.2, exported Static Mesh names are now persistent, meaning they do not change between exports of the same Component.

USD: The import options menu that Unreal Engine displays when you import a USD Stage now contains a tree view, which displays the prim hierarchy of the stage to import. Use the tree view to select and import only a selection or subset of the prims in the stage.

USD: Added support for the usdMtlx plugin on Windows and Linux The usdMtlx plugin included with USD adds a file format plugin for reading MaterialX documents and translating them into UsdShade shading networks.

[glTF] The Vertex data ByteStride attribute is now supported. This fixes issues that occurred when importing glTF files exported from Autodesk 3ds Max 2023.

USD: added support for the usdAbc plugin on Windows, Mac, and Linux.

The usdAbc plugin that is included with USD adds a file format plugin for reading Alembic files.

USD: added basic support for importing Materials with diffuse driven by displayColor.

Added the "USD.MaxInstancesPerPointInstancer" console variable to limit the maximum number of instances parsed from each PointInstancer USD prim.

The USD Stage editor now emits a warning when muting USD layers with unsaved changes. Unsaved changes are lost when layers are muted.

Disabled Skeletal Mesh sections are now ignored when exporting Skeletal Meshes to USD.

Added support for collapsing PointInstancer USD prims into Static Meshes when importing or opening a USD Stage.

Improved parsing of USD Materials to better extract the intended textures, especially if there is indirection or additional shader connections.

Added partial support for handling the "!resetXformStack!" xformOp when it is specified on the transforms of USD prims.

Fixed an issue where Materials baking to USD emitted the "ambientOcclusion" Material input instead of the standard "occlusion" input. The Unreal UsdPreviewSurface base Materials are now used when parsing the "occlusion" material input from USD materials, and support Ambient Occlusion.

Attributes parsed from USD prims are now be considered animated even if they contain only a single time sample. This means these prims are bound to the generated Level Sequences, instead of being ignored.

All Mesh prims exported to USD now specify no that subdivision scheme should be used to parse them. This ensures that DCCs that can subdivide meshes still display normals as they were exported from Unreal.

Enlarged the Actor picker menu in the top right of the USD Stage editor window.

PhysicsAssets are now generated automatically when parsing Skeletal Meshes from USD. You can disable this behavior with the "USD.GeneratePhysicsAssets" console variable.

The USD Stage editor now prompts you to save any modified USD layers to disk when you close a USD Stage with unsaved changes.

Improved handling of Skeleton poses parsed from USD. We now use the restTransforms attribute for the reference USkeleton pose, but account for the USD bindTransforms attribute on the USkeletalMesh itself.

Added an option for picking which USD Material purpose is used to parse Material bindings. The option is available from Options menu in the USD Stage editor, as a property on the AUsdStageActor, and as USD Stage import option.

[SketchUp] Classification Types are now exported to metadata.

[SketchUp] Reduced Actor counts in exported scenes.

Adjusted the export options used to export Levels and Level Sequence Assets, and reordered them for clarity. They should now have better defaults.

[SketchUp] Component geometry is now merged into single Mesh instead of spawning separate Meshes for every disconnected group of faces.

[SketchUp] Image Entity is now supported.

When an Asset, Level or Level Sequence is exported to USD, new additional metadata identifies the export and source Asset. The exporters check the metadata when re-exporting the same file to prevent re-exporting identical, unchanged assets unnecessarily. New export options for all Asset types allow you to disable this behavior.

The USD Stage editor now emits a warning whenever an opinion is authored and it is not the strongest opinion for that property in that stage.

You can now specify which USD layer is the current edit target by clicking the checkmark icons in the "Edit" column in the bottom panel of the USD Stage editor.

Right-clicking a layer in the bottom panel of the USD Stage editor now allows you to clear, save or export the layer.

MaterialX: upgraded MaterialX to version 1.38.5

Implemented drag and drop support to allow reordering or reparenting the layers displayed in the bottom panel of the USD Stage editor.

Added an option called "RootMotionHandling" for using transform animations on Skeleton and SkelRoot prims as additional skeletal animation root bone motion when opening or importing an USD Stage. The option is available from the Options menu in the USD Stage editor window, as a property on the AUsdStageActor; and as a USD Stage import option.

Added support for new file formats to Datasmith import:

CATIA version 5: .CATSHAPE

CATIA version 4: .exp, .session, . dlv

.sab (ACIS)

IFC format is now managed by Datasmith CAD import.

The ds.IFC.EnableNativeTranslator console variable enables the deprecated native IFC translator.

To prevent the import of CAD files with tessellation parameters that can generate huge meshes, we defined the following limits:

Chord error: - 0.03

Max angle: - 5 degrees

We could not limit edge length because 0 equals no Edge length. If the edge length value is not equal to 0, edge length is limited to 0.5, and a warning message is logged.

To set smaller values for metric parameters, use the ds.CADTranslator.MeshingParameterFactor console variable.

CAD faces are sometimes duplicated. The sew option sews the duplicated faces together. Because their meshes are identical, all triangles are sewn and then disconnected.

To prevent that, you can add a process with the option RemoveDuplicatedTriangle.

The ds.CADTranslator.RemoveDuplicatedTriangle console variable, which is set to "false" by default, enables the process.

Because duplicate CAD faces are rare, removing duplicate triangles is resource intensive, the option is disabled by default. To fix a StaticMesh with duplicated triangles, you can re-import it with this option.

Enabled the glTF exporter plugin by default.

Added support for CastShadow property in Actor Elements.

The Microstation .dgn file format is no longer available for Datasmith import.

Alias import with the Stitching option set to Sew allows the merged boundary representation (BRep) to have more than one material assigned (for multi-material surfaces).

The ds.CADTranslator.Alias.SewByMatrial console variable allows you to choose to sew BReps by material (only one material per staticMesh) or not (multi-materials on the staticMesh).

Added fallback behavior for UGLTFExporter::ExportToGLTF to export current playing UWorld if no specific object is passed.

[3ds Max] The Datasmith 3ds Max Exporter plugin keeps the aspect ratio of baked procedural textures.

[3ds Max] The Datasmith 3ds Max Exporter plugin version is now displayed in the Datasmith Messages window.

[3ds Max] You can now toggle XRef Scenes on and off when you export or Direct-link sync 3ds Max content.

With USD, it is now possible to import basis curves or referenced Alembic grooms as groom Assets or caches by applying the GroomAPI schema. Furthermore, the GroomBindingAPI schema can be applied to a mesh prim to bind a groom prim to it in Unreal.

[SketchUp] Parent non-uniform scaling of a rotated sub-component is now enabled in some cases.

[3ds Max] There is now a Limit Texture Resolution option for export of baked procedural texmaps.

[MDL Importer] Updated the MDL SDK.

[3ds Max] Max UV channel ids are now remapped to Unreal UV indexes.

[3ds Max] Corona Light Material is now exported as UEPbr Material.

[3ds Max] Approximated export for ForestColor texmap.

[3ds Max] More stable Static Mesh ID by using the smallest handle value among instance nodes. Reduces needless reimports of Static Meshes.

[3ds Max] MentalRay Arch & Design and VRay Light Materials are now exported as UEPbr Materials.

[3ds Max] Datasmith 3ds Max exporter plugin provides export diagnostic information. For example, statistics about exported/synced scenes, nodes, Materials, and textures.

[3ds Max] Support for CoronaPhysicalMtl with ClearCoat.

[3ds Max] XRefMat and VRayBlendMtl are now exported as UEPbr Materials.

[3ds Max] Max's Physical Material is now converted to a UEPbr Material.

Added a post process to the CAD import process to sew cracks in the mesh.

This process can be disabled with the ds.CADTranslator.SewMeshIfNeeded console variable.

The sew tolerance is the same as the one use in the stitching step of the CAD import (the StitchingTechnique is Heal /Sew). It can be set with the ds.CADTranslator.StitchingTolerance console variable.

[Solidworks] Improved Parts configurations export.

Bug Fix:

Fixed a crash that occurred when trying to parse some types of USD scenes with nested SkelRoot prims.

The USDImporter plugin now displays a warning and cleans invalid normals found when parsing Mesh prims. Previously, it would silently discard all normals and recompute them. The console variable "USD.MeshNormalRepairThreshold" has been introduced to configure this behavior.

Fixed an issue where Level Sequence exports to USD were missing animation tracks when Actors and root Components were bound separately.

[SketchUp] The Datasmith Messages window is now localized.

[SketchUp] Direct Link: Added layer folder (group) visibility synchronization of individual faces.

Fixed an issue where the "Selection Only" Level export option had no effect when exporting Level Sequences to USD. Also added an option to the Level Sequence export options that allows exporting animations of only the selected Actors and Components.

Datasmith: Initialized custom node values in the MFAttr_FrostedGlass in the M_StdTranslucentFrostedGlass.

[SketchUp] Camera changes are now updated via Direct Link.

Fixed an issue where the right panel of the USD Stage editor window wouldn't refresh on some operations, such as clearing the prim selection on the left panel, or switching to another Unreal level.

Fixed a color styling issue on the lower pane of the USD Stage editor window that made it difficult to see whether the currently selected Layer was the edit target or not.

Fixed missing or incorrect Material assignments when exporting some types of Skeletal Meshes to USD.

Fixed an issue where it was not possible to duplicate an AUsdStageActor with a loaded stage.

[SketchUp] Transparent Materials that use textures with no alpha are no longer translated as opaque.

[SketchUp] Opacity scalar and texture alpha are now properly combined to calculate Material opacity.

[SketchUp] The proper texture channel is now used as opacity source.

Added support for PointInstancer USD prims that have other PointInstancer prims within their prototypes. We now collapse the prototypes into Static Meshes.

Fixed an issue where it was not possible to animate the Preview Actor on the Blueprint editor for a Blueprint class that derives the AUsdStageActor, after an instance of said Blueprint was placed in the Level.

Fixed an issue where skeletal animations baked into a Control Rig were not exported when you exported their Level Sequences to USD.

Fixed a crash that occurred when opening the Level Sequence generated by a Blueprint that derives the AUsdStageActor class, while the Blueprint editor for that class is open in the editor.

Fix build errors that occurred when building monolithic editor targets with the USDImporter plugin enabled, but no global ANSI allocator specified.

[SketchUp] Fixed normals when baking transforms into a mesh.

[SketchUp] The Datasmith Export Plugin for Sketchup now displays a warning message when the version of SketchUp 2020 is unsupported. The plugin for SketchUp 2020 requires at least version 2020.2.

[SketchUp] Fixed Component/instance name change synchronization.

[MDLImporter] Fixed crash with baked textures.

[SketchUp] Modified the title, tooltip, and status text for toolbar commands to conform to SketchUp guidelines.

Fixed an issue where foliage instances marked as "invalid" in Unreal were not exported to USD when the Level was exported.

Fixed a crash that could potentially occur when importing using the Actions > Import command in the USD Stage editor windowmenu, and having the corresponding AUsdStageActor's Level Sequence open in the Sequencer.

Fixed an issue where toggling visibility on the USD Stage editor for prims with animated visibility opinions did not show/hide child prims.

Fix an issue where the AUsdStageActor overwrote its Time with its stage's StartTimeCode whenever its Level was loaded.

Fixed an issue where skeletal mesh components generated when you open a USD Stage via an AUsdStageActor didn't animate when going into Play In Editor mode.

Fixed an issue where skeletal animations failed to import from USD when the skel:animationSource relationship was specified inside of the Skeleton prim itself.

[SketchUp] Removed global variables, and fixed use of chdir.

Fixed an issue where glTF variants were not loaded in some scenarios due to name collisions.

[3ds Max] Fixed a crash that occurred when exporting RailClone while using a renderer other than the default 3ds Max renderer, for example, Corona.

Fixed a crash that occurred when importing a USD Stage with SkelRoot prims, and using the ExistingActorPolicy and ExistingAssetPolicy import options to append Actors but replace Assets.

Fixed support for UTF-8 character encoding in the glTF exporter.

Fix an issue where right-clicking and deleting a prim with a reference in the left pane of the USD Stage editor could cause the referenced prim to be deleted with it.

Fixed an issue with the glTF exporter determining texture coordinates for certain combined material properties (Metallic/Roughness and Clear Coat Intensity/Roughness).

Fixed a crash that occurred in some scenarios when exporting skeletal meshes to USD.

Fixed a crash that could occur when logging multiple import errors or warnings during a multi-threaded step.

Fix an issue where values for Light elements were skipped when they were very high or very low.

DatasmithContent: Updated triplanar mapping, normal fixup, and parallax occlusion mapping.

DatasmithContent - Changed the default Opacity Mask Clip Value from 0.333 to 0.5 to support path tracing.

Fix an issue that occurred when importing or opening a USD stage, where no animation tracks would be generated for animated cameras if the Camera prim had both animated transforms as well as animated camera attributes.

Fixed issue that prevented cameras with infinite projection from exporting correctly in glTF exporter.

Fix an issue where materials generated when importing or opening USD Stages used non-virtual texture samplers, even when the textures used were imported as virtual because they had high resolutions.

[Solidworks] Assembly configuration export fixes.

[Solidworks] Lights export fixes for light names and spotlight direction.

[3ds Max] Various fixes for CoronaLight Cylinder orientation, Photometric light attenuation, Arnold light intensity, CoronaSun color/temperature, and VRaySun color/temperature.

[3ds Max] Updated the Forest Pack API to the latest version, and fixed some stability issues.

Groom and groom cache import settings specified in Python scripts are now applied properly. If you want to import a groom Asset and groom cache from the same file, and you need to specify their respective import settings, you must import them in separate import tasks..

[Solidworks] Display state change now correctly updates Materials via Direct Link.

[3ds Max] RailClone object transform math fix.

[3ds Max] Fixed export of animated transforms when the parent of an animated node is hidden.

Fixed a loading issue with groom caches that were imported in UE4.

Fixed a quantization issue on groom with guides groom cache with large displacement.

[3ds Max] The Datasmith 3ds Max Exporter plugin no longer changes the names of Max Materials.

[3ds Max] Fixed crash for Blend Material with null input Material.

Fixed an issue where the import options window was missing when re-importing an Asset from Alembic.

Fixed a playback syncing issue between groom cache and geometry cache when rendering in Movie Render Queue.

[3ds Max] Only textures referenced in exported Materials are exported.

[Solidworks] Default directional lights are excluded from export.

[3ds Max] Fixed export of camera parameters for standard cameras.

Alembic files imported as Skeletal Meshes are no longer imported if the Meshes are too big or the animations are too long. Both issues caused crashes during import.

Fixed an issue where groom caches were not being updated when rendering through remote MRQ.

Fixed an issue where Alembic geometry caches imported without "Flatten Tracks" had broken Meshes because the time offset computation was wrong.

[3ds Max]: Fixed reimport of RailClone objects.

Deprecated:

Removed support for custom extensions EPIC_animation_hotspots and EPIC_camera_controls from glTF exporter.

Removed support for creating proxy materials from runtime in glTF Exporter.

New:

Added support for redirecting DataTable row structs in the DataRegistry.

Actors can now change which Asset they browse to.

Actors can now only browse to Assets who only have an alias exposed.

Added a config option to disable the enable / disable checkbox for plugins in the plugin browser.

Updated plugin templates to be driven from data.

UEditorLevelLibrary::GetGameWorld now returns the editor world instead of the game world.

Added delegates in EdModeInteractiveToolsContext that allow UEdModes to receive Render and DrawHUD calls.

Added a new UInteractiveToolManager::PostActiveToolShutdownRequest function that allows a Tool to request that it be shut down (for example, a Tool that wants to apply an action and exit on-click).

Added a new UInteractiveToolManager::OnToolShutdownRequest delegate. If bound, PostActiveToolShutdownRequest will call this delegate first to allow higher-level code to handle the shutdown request (for example, by forwarding to EdModeInteractiveToolsContext::EndTool).

Added Toolstack support to tool menus.

Added PIE callbacks to the editor utility subsystem.

Crash Fix:

Fixed a crash if no group Actor is selected when attempting to add Actors to a selected group.

Bug Fix:

Fixed a bug that caused UEditorLevelLibrary::GetGameWorld to return the editor world instead of the game world.

Fixed bug with conflicting GameInstanceIDs used by NetTrace when running multiple sessions in PIE.

Fixed a problem when using iris replication where a NetConnection's ViewTarget was not properly updated.

Actors and components that aren't in the current editing context can no longer be selected.

Actors are no longer considered initialized when running deferred construction scripts due to pending Asset compilation.

The editor now forces outstanding Static Mesh compilation when saving a world to prevent construction scripts to be deferred.

The editor now tests if the world is valid before running deferred Actor construction scripts.

When considering compilation for games specifically, the editor now force compiles Static Meshes of unregistered components. This also prevents unnecessary deferring of construction scripts.

Fixed an issue where child Actor components were unable to be selected in the viewport when a user is selecting components inside an Actor.

Deprecated:

Deprecated the typed element selection set on the tool builder state. This can be replaced with the context object that exposes the typed element set within an asset editor. This fixes CIS errors and sets us up to remove this next release.

API Change:

The FGenericAccessibleMessageHandler::RaiseEvent() function no longer takes a list of parameters and instead need to take a FAccessibleEventArgs struct. Users that use this API must upgrade the parameters to the new struct params.

New:

UStructs can now provide a CanEditChange override by setting the TStructOpsTypeTraitsBase2::WithCanEditChange trait.

The Reset to Default button is no longer hidden when a details row is disabled. Instead, it is grayed out.

Exposed SBorder's protected methods GetBorderImage() and GetBorderBackgroundColor().

KiB/MiB/GiB/TiB are now accepted spellings for the Units/ForceUnits metadata.

Added TAttribute::CreateStatic() to disambiguate in cases where Create() does not correctly detect that additional arguments are meant to be forwarded to the function.

You can now drag EQS queries from the content browser and drop them into the editor world. Additionally, the EQSTestingPawn will be auto-created and set up with the selected EQS query.

Added Widget List to Widget Reflector, which lists all currently active widgets, grouped by the location where they were created. This can be useful for pinpointing SWidget leaks. This requires UE_WITH_SLATE_DEBUG_WIDGETLIST to be defined, since it makes use of the functionality in FWidgetList.

Created a global name filter for asset paths that external code can assign.

SBorder now can be constructed with the .Padding(1,2,3,4) declarative style, just like SBox and widget slots.

Added SBox overrides for setting Padding() without constructing an FMargin, as is the case with slots.

Details view's IsPropertyReadOnly delegate is now evaluated every frame instead of only when refreshing the tree, similar to how IsPropertyVisible now works.

Added support for changing value of a SSpinBox using the mouse wheel. This can be enabled using the EnableWheel argument.

Added a new metadata property called WheelStep to specify the step value. The default step is either 1.0, or 0.1 if clamp range is less than or equal to 10.0.

Step can be modified by holding Control (1/10) or Shift (10x).

Both the internal SSpinBox of SNumericEntryBox and SPropertyEditorNumeric now use this new feature.

Added the owning struct name to EditCondition error messages to make it easier to find which property is breaking.

Changed UWidget::GetRenderTransform() to return a const reference instead of a copy.

Added a filtering mechanism to MainFrame's MRUFavoritesList and LevelEditorMenu's 'Open Recent Level' through an optional DoesMRUFavoritesItemPassFilterDelegate.

Timecode properties in details panels now support partial entry.

Fixed the SetRowFill RowIndex parameter name.

Editor Utility Widgets now use theirDisplay Name in the menu.

Section buttons have been changed from a segmented control to a wrap box of buttons instead.

Sections can now be multi-selected by holding down the Ctrl key.

Section selector visibility can now be toggled from the options dropdown.

Exposed SVirtualJoystick::FControlInfo to Slate API.

UWidget::IsVisible now checks for render opacity to determine widget visibility.

WidgetNavigation Resolve and TryRename now allow for customization of navigation behavior in a plugin for UMG.

Added a GetTextLineCount to SMultiLineEditableText and SlateEditableTextLayout to be able to get text line count.

Added AddVerifiedEditableText to FMultiBoxBuilder to expose SEditableTextBlock::OnVerifyTextChanged.

For list views, created a new delegate called OnFinishedScrolling that fires when an animated scroll finishes.

Added new blueprint nodes to set font materials for all types of text, the default style for rich text, and editable text blocks.

Added new options for Common Text Blocks to start and stop scrolling text through blueprint such as when a widget becomes hovered and unhovered. This also works with the overflow policy of ellipsis to turn on and off ellipsis when scrolling is active or not.

Added new blueprint node to create a dynamic material from a rich text block's default text style.

Refactored FGenericAccessibleMessageHandler to raise accessible events that include user Id and additional arguments. This allows more information to be passed around for modules that require more accessibility information, such as User or Controller Id. This creates the basis for multiple users to use the screen reader at the same time.

Added SlateScripting plugin, SlateScriptingCommands module and UICommandsScriptingSubsystem.

Enables registering commands dynamically within existing UI Command Lists through scripting.

Sequencer, Curve Editor, Content Browser, Main Frame, Level Editor and Level Viewports are currently the only systems exposing the command lists.

New methods have been added to SOutputLog.h and SOutputLog.cpp to create a new timestamp menu item and submenu in the output log settings menu.

The screen reader plugin can now support multiple users at the same time. Developers can provide key bindings to allow players to opt into the screen reader framework for accessibility functionality.

Introduced screen reader navigation policies. This allows the screen reader to navigate around UI elements on the screen separate from regular Slate navigation similar to how commercial screen readers behave.

Screen reader plugins refactor to use the new accessible focus API to support multiple simultaneous users.

Improvement:

Menu searching now works for Material attribute properties.

Crash Fix:

Fixed a case in the DrawLine Blueprint API where a crash would occur when points overlapped.

Prevented a crash when opening the Static Mesh Editor when using nullrhi.

Fixed a crash that occurs when using "Replace With" in the Hierarchy panel. This occurred when selecting a Blueprint that extends a Widget class in the Library.

Division by zero in SScaleBox::OnArrangeChildren is now prevented.

Fixed nullptr dereference when the level editor module is being unloaded since the tab's parent is already de-allocated if the engine is exiting. This bug is also prevented in Slate altogether.

Fixed a crash that would occur when auditing static meshes with no static lighting enabled.

Bug Fix:

Increased Content Browser item description width to 700 in tooltips.

Property matrix now correctly displays EditCondition checkboxes only when applicable to the row. Property matrix rows also hide if the EditConditionHides metadata is set.

SEnumCombo now only dismisses its own menu when an option is selected.

Expanding the Advanced subcategory no longer causes previously collapsed nodes to re-expand.

When multiple components of an actor are multi-selected and edited at the same time, all of them will now receive a PostEditChangeProperty() call.

Details row TitleProperty values are now retrieved recursively. This was a regression from UE4 that caused issues in cases that should have worked, such as with an array of instanced objects, because the category node would cause the search to end.

Viewport overlay widgets are now visible even when rendering a full-screen UMG widget.

Color picker for color properties on externally added FStructOnScope properties now resets and cancels correctly.

Show Only Modified now accounts for the visibility of a custom reset to default handler provided to FDetailWidgetRow::OverrideResetToDefault().

Scrolling a row out of the visible region of the Details view now commits any changes that were being made to that row.

Numeric properties can have ForceUnits metadata specified for them even inside containers.

The FPrimaryAssetId selector now respects DisplayThumbnail metadata.

Removed the Create menu's "Blendables" category.

The UObject::IsSelected on UVisual is now hidden to avoid confusion with UI selection state.

It is no longer possible to dock tabs into docking areas that are contained inside the tab.

Added Bengali, Gujarati, Odia, Kannada, Malayalam and Tamil to the list of character ranges that require complex text shaping.

You can now search for basic shapes in the Add Component list.

EditDefaultsOnly properties on UUserWidgets now appear in the UMG Designer details panel.

Fixed an issue preventing edits to Timecode properties in the Details panel from being correctly recognized in the undo system.

DefaultGameMoviePlayer now makes sure that a loading screen shows the User Widget until the end of the loading screen.

Fixed a case where ContentBrowserDrawer is not marked as the primary content browser when selected in ChooseNewPrimaryBrowser.

Correction to SceneViewport to use the cached display metrics instead of the Initial ones which could cause issues when monitor settings or resolution changes when the engine is running.

Correction to BP node Play Animation with Finished Event to correctly trigger the finish event on the next frame even if the game is paused and prevent from triggering it if the widget no longer exist.

Fixed issues when multiple Widget Interaction Components focus on the same widget.

When replacing a binding with new widgets, UMG will move the content of the old binding to the new one rather than reuse the existing binding. This fixes issues where UMG would incorrectly keep old possessable bindings.

Curve Editor Stacked View now properly renders labels.

Re-enabled color override for the Editor window title bar.

The Rendering > Advanced > TextureStreaming/LOD/etc. categories now use the correct display name.

NameContent in Details panel rows now correctly respects user-defined HAlign, allowing for labels to contain a HorizontalBox with both left and right aligned slots.

Details value widgets are no longer stretched due to property rows having a minimum height.

Advanced dropdowns in the Details panel no longer randomly disappear when scrolling.

Fixed a bug that caused some calculations with shadow offset not to consider font scale.

Fixed an issue where nested utility widgets could cause the open Level to be dirtied since they wouldn't properly be marked transient like the outermost utility widget.

Fixed issue where string table selection combobox wouldn't show the filter text box anymore if there were no results, making it impossible to clear.

Fixed a bug that would occur in List Views when changing the Consume Mouse Wheel setting to "When Scrolling Possible". This bug caused mouse wheel input to fail being consumed when scrolling up.

Fixed an issue where timestamps in asset auditor would use month instead of minute.

Fixed an issue where timestamps in the asset auditor would incorrectly clear when a custom audit is cancelled.

Fixed typos in "toggle screen messages" outputs.

New:

Projects and plugins can now provide enhanced tooltip content for the editor, and they can override the default tooltip content.

If you use the SDocumentationTooltip widget, or standard UI items such as menus that create SDocumentationTooltip widgets, you can provide content for enhanced tooltips in the Documentation/Source folder of your plugin or project.

You can override default enhanced tooltip content by providing files with the same path and excerpt names as the default ones in Engine/Documentation/Source.

If an enhanced tooltip excerpt contains a variable named [VAR:ToolTipOverride], the content of that variable overrides the default content for the initial simple tooltip.

If you have documentation that you want to link to from editor widgets or enhanced tooltip content, you can now provide your own custom base URLs. You can define these programmatically by calling IDocumentation::RegisterBaseUrl(), or in the *Editor.ini file as follows: [/Script/Documentation.DocumentationSettings] +DocumentationBaseUrls=(Id="ID",Url="http://myBaseUrl/{PAGEID}").

You can specify the base URL ID any time you provide a page ID for a documentation link. For links in code, the methods in IDocumentation now accept an optional parameter. For links in enhanced tooltip files, specify the ID in the tooltip file in either the BaseUrl metadata at the top of the file, or in the [VAR:BaseUrl] variable within the excerpt.

VR Editor: Added a dropdown menu to the VR Mode toolbar button which you can use to quickly change between the standard VR Editor Mode and specialized modes such as Virtual Scouting.

Rather than specifying VR interactor or teleporter class overrides directly in editor preferences, these are now determined by selecting a blueprintable subclass of VREditorMode.

The "experimental" warning popup no longer displays if the Virtual Scouting class is active.

You can now use Shift+ left-click to duplicate-drag a pin connection.

Scene Capture render targets now start with the alpha channel disabled.

Created the experimental Landscape Texture Patch Component to apply repositionable, texture-based landscape height and weight map edits (editor-only).

Added proper support for property change type in the spline component visualizer (interactive changes when manipulating spline points, non-interactive change at the end of the drag operation).

Added Project Settings to deactivate landscape or water mesh updates during interactive changes of water body or island splines.

Reorganised Water Editor Project Settings.

Unified landscape brush command shortcuts with other modeling tools

Added a command to change both the brush size (left-right mouse move) and falloff (up-down mouse move). The default keyboard shortcut is Ctrl + Alt + right-click drag.

Added a DoesCommandSupportInput function to the editor viewport client in order to centralize copy/paste logic.

Improved formatting of landscape notifications.

Added BP setters for ForcedLOD and LODBias on landscape components.

SetLOD can now be called both at runtime and in-editor.

Added buttons to select all landscape spline segments or control points.

UWaterMeshComponent::ShouldRenderSelected is now editor-only.

Added visual logs for when the cache data is accessed and when the cache is expanded.

Cache area is now aligned on the whole landscape to avoid expanding the cache when expanding the cached area within the limits of an already sampled landscape component.

Decoupled the rendering of the water information texture (flow, depth, and shape data) from the landscape.

Implemented separate render passes leveraging the SceneRenderer interface to draw the water data at runtime.

Added a new optional Water LOD system which replaces water mesh tiles at a distance with simplified, non-dynamically tessellated meshes. This allows the water rendering system to scale for large worlds without needing to increase the resolution of the Water Info texture.

Added functionality to open other Content Browser instances by right-clicking on the tab of a Content Browser.

Changed the Close Tab keyboard shortcut from Ctrl + F4 to Ctrl + W.

Checkboxes in filter menus now show an indeterminate state when items in the sub-menu are a mix of enabled and disabled.

The Details Panel now shows a modified badge when any view option that filters down the results is active.

Renamed Select Mode in the Level Editor toolbar to Selection Mode.

Add functionality to the Outliner to see the current hierarchy of items stacked at the top. This can be enabled by enabling the Stack Hierarchy Headers option in the Outliner.

Exposed a function to sync to the current folder in the Content Browser to scripts.

Added a notification for when all Content Browsers are locked and the user tries to open one.

Redesigned the Physics Asset Profiles panel to be aligned with the UE5 style.

Added functionality to scroll to the current selection on pressing the F key in the Outliner.

Updated the column view in the Content Browser to use similar workflows as other column views in the editor (like the Outliner).

Water bodies with null materials can now cut holes in the water mesh quad tree.

When an item in the Outliner is selected and collapsed, the parent items are now highlighted.

Updated async notifications to be consistent with the UE5 style for all notifications

Added support for collision view mode for landscape heightfield collision components. The collision data is displayed when the CVar ShowFlags.Collision is set to 1. The CVar "landscape.ShowCollisionMesh" is used to determine which heightfield is displayed: 1 corresponds to the complex heightfield, 2 to the simple heightfield, and 3 to the editor-only heightfield.

Added a one-time popup for a user's industry for analytics. This popup can be suppressed either by turning off all analytics or specifically with bSuppressIndustryPopup on UAnalyticsPrivacySettings.

The Level Editor now supports up to 4 Outliners that can be enabled from the main menu (Window > Outliner).

Added a dedicated set of icons for Plastic SCM.

Added an edit layer insertion dialog prompting the user to choose where a new edit layer should be inserted in the current edit layer stack.

Added options to expand or collapse all items to the Outliner Settings menu.

Changed the Save and Browse buttons on Asset editor toolbars to icon-only.

Added filters for Material Layer Instances and Material Layer Blend Instances to the Content Browser and Reference Viewer

Disabled the Pinned Column and Context Menu options in the Outliner on maps with World Partition disabled.

Renamed the Level Column to Package Short Name in the Outliner on World Partition-enabled maps.

Adding BoldItalic and Italic font style to FStyleFonts. These are used in the AnimCurve viewer and Class Viewer respectively.

You can now use the Shift + Click shortcut to copy / paste in the Details panel.

Added support to copy / paste between different color types.

Added AllowCreate to SObjectPropertyEntryBox / SPropertyEditorAsset to prevent creating new Assets from the asset picker. This behaves similarly to NoCreate metadata on UPROPERTY, but allows on a non-property based customization.

The editor now allows painting on the edges of landscape components.

Added option to export a single file for grid-based worlds.

Improvement:

Landscape scene proxies are now only refreshed if CVarLandscapeShowCollisionMesh has changed from the previous value. This prevents hitches when unrelated CVars are modified.

The details section API has been rewritten so that categories can now be part of multiple sections simultaneously.

Sections are now sorted alphabetically. General and All are special-cased to be the first and last categories respectively.

Reference Viewer now indicates when the breadth limit has been reached.

Reference Viewer Overflow nodes can now be expanded by double- clicking.

Reference Viewer UI is more responsive when changing the search depth on large scenes.

Edit layer heightmaps and weightmaps are now properly deleted when deleting landscape components.

Landscape notifications have been reworked for better readability and to improve notification clutter issues.

Crash Fix:

Fixed a crash that happened when trying to access the visibility landscape mask on mobile: when the mobile mesh path is enabled, there's no such texture. This means that GlobalDistanceField will not support landscape visibility.

Fixed a crash that occurred when deleting components because the deleted components were still referenced in the shared weightmap texture usages.

Fixed a crash that occurred when using an invalid scale factor on the landscape copy/paste gizmo.

Fixed a crash that occurred when invalidating the lighting cache on landscape components.

Fixed a crash that occurred when adding spline points to oceans with non-zero shape dilation.

Fixed a crash when saving an existing, already-saved map containing a dirty landscape using Save As to rename it.

Fixed a crash when loading some Landscapes with ES3.1 preview render mode enabled.

Fixed a crash that occurred when copy/pasting landscape and water bodies across levels.

Bug Fix:

Fixed multiple issues with highlighting and deleting links using Alt + left-click when both ends had multiple links.

Ctrl + mouse wheel in Foliage editing mode now correctly adjusts size in 5% increments per mouse wheel click.

Fixed GetCompleteBounds calculation in World Partition worlds when the Landscape is composed of only a single streaming proxy.

Fixed a bug that caused Scene Capture render targets to display as a checkerboard in Texture Editor.

Fixed the "change landscape brush size / falloff / strength" commands that couldn't work with default chord values nor secondary key bindings.

Fixed "cmd" modifier not being taken into account all the time in copy/paste logic.

Fix an empty notification being shown when all remaining undo / redo transactions expired.

Fixed missing render dependency in Landmass (noise texture), which could lead to blockiness when the brush was running without the texture being fully loaded.

Fixed viewport not updating when switching landscape visualization modes.

Fixed Painting Restriction not appearing when there's no active paint layer.

Fixed "Use target value" in the landscape UX being displayed for sculpt tools while it's only valid in paint mode.

Sanitized suggested landscape layer info package name when creating a landscape layer info file associated with a layer name (which doesn't have the same restrictions that package names have)

Added support for non-square heightmaps in landscape edit layers local merge

Landscape edit layers local merge fixes.

Fixed assert when updating heightmaps of different sizes

Protected double-click behavior in the Outliner against deleted actors.

Fixed incorrect removal of IsGameWorld check in world partitioned-worlds.

Fixed a bug where ActorDescReferences was incorrectly used for PIE worlds.

Fixed various places where components within the LandscapeComponents member of ALandscapeProxy could potentially be null (they are null in the dedicated server).

Unified text formatting of double properties on set.

Fixed a delay of many frames while the landscape BP brushes were asynchronously waiting for the required materials to be compiled.

Added support for subsections in landscape edit layers local merge.

Fixed bHasLayersContent not being set properly for the main ALandscape actor in distributed landscape setups (One ALandscape, multiple ALandscapeStreamingProxy actors), which incorrectly dirtied the Level.

Fixed water brush letting the user change the list of affected weightmap layers while it's actually automatically populated by the list of layer names specified in the water bodies.

Fixed weightmap changes on water bodies not triggering the appropriate water brush updates.

Fixed landscape tools using ShowForMode not displaying properties when in weightmap mode with no active paint layer (Use Target Value and Painting Restriction).

Made landscape edit layers read-only, removed related context menu and prevent layer reordering in non edit layers-related landscape tools (Component Add/Delete/Move/Select,Mask,New/Resize Landscape).

Don't use a modal error message box when the currently selected edit layer is locked in those tools (since they're not edit layers-related)

Fixed transaction localization for landscape resolution change * Fixed New Landscape - Fill World not being transacted

Fixed assert when iterating over components from a parallel (game) thread.

Delayed the call of CustomBrush_Landmass's GetBlueprintRenderDependencies so that it doesn't start updating it until the brush is ready.

Memory reports now properly account for landscape collision.

The editor now logs an error when reading inavlid texture data on the CPU with SplineFalloffModulationTexture for Layer Info Object and doesn't apply modulation.

The editor now logs an error and reverts to the default texture when reading invalid texture data on the CPU for the alpha brush's AlphaTexture.

Fixed undo/redo for Layer Info Object not triggering an update of the landscape splines.

Landscapes no longer incorrectly start updating before their textures and materials are streamed in and compiled.

Landscapes with Landmass no longer flatten the first time they update when On Demand Shader Compilation is enabled.

Fixed data caching function used in the Smooth and Flatten tools when using combined layers.

Fixed ASan issue with dirty data (weightmap/heightmap texture resolving debugging code) by removing usage of lambda in favor of direct call to the dirty function.

Fixed redundant ifdefs and invalid comments.

Removed overallocation of material instances array (was previously done to account for hardware tessellation which doesn't exist anymore).

Renamed FLandscapeEditLayerReadbackResult to FLandscapeEditLayerComponentReadbackResult to better match what it actually is and changed the output type of readback results from ResolveLayersTexture from a map to an array.

Water Body components now have custom scene proxies which contain the geometry describing that water body as well as a small dilation region to solve undersampling issues with the water info texture.

Fixed an issue with resizing of new or imported landscapes by dragging the boundaries not working.

Fixed a bug causing no visual indicator highlighting the current selection when using arrow keys to navigate dropdown menus.

Fixed default water brush and water zone spawn behavior to more intelligently choose the correct landscape, support multiple landscapes, and set the zone bounds to properly match the landscape.

Fixed a bug where top-level menus would draw over tabs in certain situations.

Fixed curl noise being applied in both jump flood and cache distance field materials for water bodies, causing deep pockets near the shorelines.

Z scaling and non-Z rotation is now allowed for water bodies not rendered by the water mesh.

Fixed issue with lingering river mesh components after performing an undo operation.

Fixed missing Water in Water Waves Asset Editor.

Added a minimum size to the Sources Panel headers in the Content Browser to prevent overlap.

Fixed an issue causing drag on the splitters to fail in certain situations

Fixed Landscape.DumpLODs console command not producing output.

The editor now correctly sets the ParentTab for StaticMeshEditorViewport on spawning that tab, and also checks SEditorViewport::IsVisible for StaticMeshEditorViewport visibility, as it takes into consideration last time on screen.

Fixed a bug causing search text in the Content Browser context menu to disappear sometimes.

Fixed a bug in the Outliner causing an item to get deselected if it was collapsed.

Fixed an issue where frame notifications couldn't be dismissed if they would also time out because the pointer would reset.

If dismissing a toast created by the message log, the toast's expire duration is now correctly set to 0.

Fixed a bug that affected single-file export for heightmaps/weightmaps.

Fixed a problem where users couldn't import a single heightmap/weightmap file if it was named with the same prefix as the grid-based ones located in the same folder (for example, Heightmap.png with Heightmap_x0_y0.png, etc. being present in the same folder).

Fixed an assert when generating grass while there's actually no grass data.

Altered the ContentPadding of the WrapButton ComboButton so that the button appears as a circle, instead of the football shape that appeared previously.

Added the access specifier to Variables under the My Blueprint view.

Landscape preview settings no longer affect actual Landscape rendering.

The editor now checks that LastOuter is valid before dereferencing.

Fixed a bug where a map load triggered navmesh rebuild.

Fix an Asset importing error after deleting MobileStarterContent.upack.

Fixed an issue with water textures being generated in-editor at insufficient resolution.

Fixed landscape not updating on changes to water on Mac and Linux.

Deprecated:

The old WaterVelocityTexture has been deprecated and no longer contains data.

Renamed EditorViewport.SubMenu.Layouts in StarshipStyle to Icons.Layout and moved it to StarshipCoreStyle.

Foundation

New:

A Force reload option has been added for the AutomationOpenMap function.

Support for individual test exclusion for different RHI when parent suite does not exclude all RHI Enhanced management of RHI through the UI If a RHI is specifed, any child test can be excluded on an additional RHI by clicking on edit exclusion.

Made AFunctionalTest's Author and Description public properties.

Used dot syntax to name Blueprint functional tests instead of using the full package path. (replacing / by .)

Added an option to keep Play-In-Editor(PIE) open in the advance settings of the Test Automation Window.The Default behavior is off, however this behavior can be changed through project config settings.

Improved test exclusion list mechanic.

Renamed blacklist to excludelist.

Support has been added for the section exclusion rule to be able to exclude entire section of tests.

Marked excluded test as skipped in the report instead of entirely removed for test list. A check has been added for exclusion just before running the test.

Added support for exclusion management from the Test Automation window and added a column at the end of each row.

Exposed device information to the UE test report.

Added support for metadata in Gauntlet test report for Horde Limitations.

Management through the UI is limited to which tests are available through the active worker node. This means Runtime only tests are not listed from a worker that is Editor and platform specific, and are not clearly identified.

Added support for Blueprint Editor Utilities in UE functional tests

Added a SetFilter command to the Automation framework.

Debug Hud - Stat rendering optimizations. This cuts the cost of DrawStatsHUD by about half.

Added Draw text effects (shadow, outline) in same pass as main text draw to avoid calling draw several times.

Updated the CharacterList to cache the FCharacterEntry's directly to avoid creation/copying of them.

Updated FBatchedElements::AddVertex function to takes float vectors to avoid expensive LWC conversions.

Only set SImage MouseDown and DoubleClick event if bound. This can save memory when there are many widgets.

Added bAutoCollapseWithEmptyText to UCommonRichTextBlock to mirror UCommonTextBlock.

Adding ForEachLoadedAsset to FStreamableHandle. This allows for operations on the loaded assets without creating an intermediate array.

Tabs can now be inserted into the tab list.

Added the TabIndex parameter to RegisterTab. If a new tab is being inserted before the end of the list, the tab list will rebuild the tabs in correct order.

Added the option to defer rebuilding till next tick.

Added GetTextStyleSet function to URichTextBlock.

Set ConfigCache GetXOrDefault to return value from the config or default value.

Set OodleDataCompression to use one OodleScratchBufferCount per core in tools. It will still default to 2 Buffer counts per core for game runtimes. This results in a significant speedup in iostore compression at fast compress levels.

Bug Fix:

Avoided duplicates of Screenshot comparison artifacts when producing automated test html/json report.

Automated Test report path will now log only if it was generated.

Fixed Previously Excluded Test from not inheriting exclusion settings from the parent suite.

Added a Fix for incorrect return values for FUntilCommand.

Fixed Functional test from not running when the Navigation System is disabled.

Validated that the item at the tail of the automation latent command is the item that is completed before removing it.

Fixed Automation Worker Instance Name from not being unique for some console platforms.

Fixed const in FAutomationTestBase::TestEqual function signatures.

Fixes for UCommonActivatableWidgetSwitcher. If the switcher has an owning activatable widget, only activate switcher child if the owning widget is active.

Fixed issue in UPlayerInput where analog values weren't cleared when flushing pressed keys.

Deprecated:

Deprecated FAutomationTestBase::SetSuccessState and FAutomationTestBase::GetSuccessState functions.

Removed:

Disabled exclusion editing on remote sessions.

NotEnoughParticipant state in favor of Skipped.

Implicit conversions from large world coords to floats by explicitly using float vector types.

Direct index cache from the CharacterList as it didn't actually make it faster due to the complex logic when getting a character.

Unnecessary include libraries.

New:

Added .so and .dylib as files to consider as library files to help reduce relinking on Mac and Linux.

Added the ability to compile specific files while a live coding session is active. The output is sent to a different location to prevent conflicts with overwriting object files for the live coding session.

Updated EpicGames.Build to be a .NET 6 project.

Added Unreal Build Tool plugin support. It is currently only used by C# UHT.

Added XGE config bUnavailableIfInUse to allow falling back to a different executor if XGE is in use.

Added XGE config MinActions to avoid using XGE for small groups of tasks.

Modified assembly cache to not include "ref" or "refint" directories which contain the reference dlls.

Added an option to include the CPP/WinRT language projection headers and set the TargetWindowsVersion to the configured value when using Windows 10 SDK.

Deprecated bCompileForSize UBT Target option and replaced with OptimizationMode enum to fine tune a balance between speed and code size.

Rewrote the GenerateClangDatabase mode in UBT to work with the clang tools like IWYU.

Updated the unity file logic in Unreal Build Tool to merge generated cpp files and module cpp files into the same unity files to improve compile times. This can be disabled globally by setting bMergeModuleAndGeneratedUnityFiles in the target to false or in a module by setting bMergeUnityFiles to false.

Extended BuildLibForMac.command with more options and better option parsing.

Added support to inline the generated cpp files into the module cpp files using a new macro UE_INLINE_GENERATED_CPP_BY_NAME. This improves compile times because less header parsing is required.

Added support for targeting arm64 on Win64 with VS2019 in the UAT BuildCMakeLib command.

Added a mode called PrintBuildGraphInfo to Unreal Build Tool. This mode prints out build information that can be used to help guide compile time improvements.

Added the ability to override the NumIncludedBytesPerUnityCPP from the module rules. This can be used to improve compile times by breaking up large unity files into smaller pieces.

Updated several modules to use shared precompiled headers to improve compile times.

Added support for targeting the Unix platform group in the UAT BuildCMakeLib command.

Added a "deprecation" path for engine includes to allow types to be moved without breaking licensee module builds.

Non-engine modules and targets will have to specify the version of includes from IncludeOrderVersion in TargetRules or ModuleRules. This setting will control the value of UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_XXX where XXX is the version of the engine.

When moving types out of a header, Users will need to include the new location of the type in the header it was removed from but only if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_XXX is set.

If a target does not change its IncludeOrderVersion to the latest version, UBT will print out a message telling users how to upgrade.

This change introduces a new set of SharedPCH permutations to make sure modules with older versions get the PCH with UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_XXX set correctly.

Improvement:

Updated several modules to compile with unity files to improve compile times.

Updated several modules to use shared precompiled header files to improve compile times.

Optimized Unreal Build Tool's startup time.

Bug Fix:

Enabled the reference assembly to be generated in the old location for all projects that include the UE C# props file.

Marked UnrealBuildConfiguration to be serialized to json as a string.

Ignored compile actions that aren't using the C++ compiler when doing live coding. Resolves issues where changes that would contribute to the resource file would cause live coding to fail.

Fixed issue where compiling script modules in UAT where all modules were up-to-date would result in extra assemblies being returned.

Properly exclude build records which fail to parse from the active set of build records.

bStressTestUnity will now supersede adaptive unity.

Fixed an issue where the generated cpp files were not including the needed headers for the types that were marked in the header file.

Removed:

Removed several private precompiled headers to improve compile times.

API Change:

FMath::Min/Max now rely solely on a definition of operator < instead of needing overloads for operator <= and >= respectively, so uses of these functions with custom types will now require operator < to be defined.

Experimental support for C++ Coroutines which can be used by setting bEnableCppCoroutinesForEvaluation to true

The default type for all integer types remains int32.

The base-global-module argument is now expected to be in the format --base-global-module=ModuleName.

The API previously allowed names up to 256 characters. Callers using longer names will need to use shorter names to avoid a failed assertion.

Replaced PanicFlushThreadedLogs with Panic when the program will be forced to terminate, and with Flush otherwise.

New:

Added the trace.bookmark console command which emits a TRACE_BOOKMARK. You can provide the argument with a single string which then becomes the bookmark name.

Added descriptions for various stat EngineStat commands. The stat description has been added to the output of stat help. Using the command - stat detailed will display the build string version (which includes changelist).

Added support for symbols such as "%c" width formatting in FGenericWidePlatformString. Supports "+" and "-" followed by digits as well as "*" for integer value argument.

Changed definition of FMath::Min/Max to be based on less-than comparisons. This both improves code generation in certain situations and makes it easier to use them with custom types.

Implemented a quick workaround to allow munmaps to happen with Mutex unlocked. Currently, We can't define UE_ALLOW_OSMEMORYLOCKFREE on Linux as we'll deadlock with the OsAllocatorCacheLock.

Mutex locks Munmap calls on Linux can take quite a bit of time (few ms in some cases). This should allow these to happen without the Mutex and remove some hitching.

Added context to PostCDOCompiled and call it for skeleton-only compiles

Support for serialization of TVariants has been added.

You can now optionally allow Blueprint class property GUIDs to be included in a cooked build.

Added "OnConfigSectionsChanged" delegate to FCoreDelegates, notifying bindees when the config is updated.

Added boolean bIsRegeneratingOnLoad to PostCDOCompiled context.

Allowed the meta-data for generated types to be cooked as optional data, for use with cooked editors.

Added FCoreUObjectDelegates::OnObjectPostCDOCompiled.

Added debugger visualizer for FIoStoreTocCompressedBlockEntry.

Refactored reference chain searching to handle multiple objects at once to reduce time spent scanning all objects and creating/deleting temporary structures.

Added ShortestToGarbage option to prevent duplicate reference chains by the root reference and the first garbage object encountered.

Added Special cases for the FGCObject referencer to avoid unhelpful deduplication.

Defined a new Tag for PluginBrowser allocations.

Added a struct FTopLevelAssetPath to represent the path of an object whose direct outer is its containing package. For example: /Path/To/Package.AssetName

Improved support for TVariant visitors that use rvalue-reference function parameters.

Added tagging for unassigned allocations.

Added TEnumFlagsRange which enables iteration over each flag set in an enum flags variable.

Unified a Play-In Editor(PIE) world leak that was reporting with LoadMap leak reporting.

Added metadata to crash context for hung thread or present hangs.

FNames containing full object paths have been deprecated across the engine. These strings are redundant and can take as much as 30mb of memory in a large project.

Added a TIdentity_T<> alias for typename TIdentity<>::Type.

Added Peek to TSpscQueue and TMpscQueue.

Added append to FString overloads for BytesToHex[Lower], FSHAHash, FGuid and optimized them.

Added a command line argument for underrun mode.

Added automatic bool-to-integer property conversions.

Added UE_ prefixes to math macros, and conditionally deprecated the old macros with a preprocessor switch.

Added TArray::Append which takes a parameter for any contiguous range.

Added a IsEmpty function to TSpscQueue and TMpscQueue.

Always log out config console variable settings when the last write to the console variable was from the constructor.

Added FGCObjectInfo::IsGarbage function to check Garbage and PendingKill flags.

Renamed garbage streaming levels before GC so that new copies of them can be reloaded when leaks occur with GC reference elimination (pending kill) disabled.

Moved TIsCharEncodingCompatibleWith, TIsFixedWidthCharEncoding and TIsCharEncodingSimplyConvertibleTo traits into their own header files.

Added conversions for UTF32CHAR-to-UTF8CHAR to FGenericPlatformString::Convert.

Windows memory mapping improvements have been added.

Added extra information to fname.stats command for hash table memory usage.

Fixed units for fixed overhead.

TArrayView is no longer passed by a const reference in TSet::Append

Added a TSet::Append overload for TArrayView of const argument type.

Added a component-wise multiplication operator to FIntVector.

Added Support for RotationVector conversions to Quat.

Added additional TCString<UTF8CHAR> functionality.

Added GET_VARARGS_RESULT_UTF8 macro.

Moved TMakeSigned and TMakeUnsigned into their own header files.

Added TasksInsights visualization for parent tasks.

Updated UE::String::Find* to accept UTF8CHAR views.

Added TCHAR<->UTF16 and TCHAR<->WCHAR support in StringConv.h for UTF-8 mode.

Added support for FGenericPlatformString::Convert and ::ConvertedLength with null-terminator.

Added UTF16TEXT macro.

Added MakeUniqueForOverwrite.

Added MicrosoftPlatformCrashContext and MicrosoftPlatformStackWalk to share code between Microsoft platforms.

When sync loading a package, Zen Loader will only execute nodes required for that package to finish loading.

Enabled interface support for AddDynamic and BindDynamic on delegates.

Added a minor improvement to deadlock detection in Tasks System. It will now detect waiting for task completion from inside that task execution, even if inside its inner task.

Added functionality to Tasks Insights tracing task destruction and a context menu item to jump to task's DebugName in IDE if it's a source location.

Added a mode for garbage collection to report a sample of garbage references rather than all of them. This mode can be enabled by setting gc.GarbageReferenceTrackingEnabled to 2.

Renamed leaked packages in in LoadMap during GC reference elimination. pending kill is disabled so that new copies of those maps can be loaded as free memory allows.

Fixed a missing log in LoadMap when ensures are compiled out.

Added ConstCastWeakPtr and StaticCastWeakPtr functions to match the SharedPtr and Reference equivalents.

Added nodiscard to relevant sharedptr-related functions.

Downgraded failure to obtain package name from file name to a warning in IoStore.

Platforms can now opt-in to all-thread backtraces, defaulting to on for Windows and Mac.

Fixed WaitUntilTasksComplete function to tolerate null tasks to TaskGraph.

Moved support for adding all thread callstacks to crash context from Windows to Microsoft.

Added TObjectPtr support to delegates.

Added FORCEINLINE to TIndexedContainerIterator dereferencing operators.

Added missing LLM tracking tags. Untagged Allocations went from > 40000 untagged allocations to 4400.

Instrumented new ParallelFor tasks for Tasks Insights. Markers for ParallelFor tasks now show task lifetime events, and point to which ParallelFor they belong to.

Added Extra GC logging from gc.GarbageReferenceTrackingEnabled . Logging will be completely removed in shipping builds regardless of the settings of the console variable.

New updates for TasksInsights. When selecting a ParallelFor timer it will draw arrows to and from its ParallelFor tasks.

DepletableMpscQueue - a multi-producer/single-consumer concurrent atomic queue that consumes all items at once, atomically, and leaves the queue in a usable empty state.

Added support for custom allocator for TSpscQueue and TMpscQueue.

Added Math constant constexprification and outlining to reduce massive code bloat.

Added delegate FCoreUObjectDelegatess::GetGarbageCollectReportGarbageReferencers for adding additional debug information to garbage reference tracking in GC.

Added GarbageObjectsToVerify function to world context to verify that important objects are cleaned up on world transitions.

Added commands -DebugCoreRedirects and -FullDebugCoreRedirects to the command line parameter that writes to the log when reading and applying core redirects.

Included referencing property information in HandleGarbageReference since it's guarded by a console variable. Allow ENABLE_GC_OBJECT_CHECKS to be overriden outside of GarbageCollection header file.

Added command-line options for -EnablePendingKill and -DisablePendingKill to override config setting.

Added ForwardAsTuple function as a mirror of std::forward_as_tuple.

Added C++ Coroutine Task implementation and support classes.

Added support to cross-compile editor plugins through the runUAT BuildPlugin.

Improved struct packing for TCounter from 32 to 20 bytes, and FScopedDetailTickStats from 32 to 24 bytes.

Added a lower case digits mode for FGuid::ToString.

Improved scoped cpu timers for FEngineLoop.

Added cpu timers for FEngineLoop::Tick, HeartBeat, TickHotfixables and TickRenderingTickables.

Added a scoped cpu timer for FStats::AdvanceFrame.

Made TVector2::Normalize function return a bool indicating whether the normalization was successful, matching the TVector::Normalize function.

Added FloatCastChecked and FloatFitsIn for runtime validation of acceptable precision loss when casting between floating point types.

Added support for signed and unsigned variants of FIntVector, FIntPoint, and FIntRect types.

Added support for 32 and 64 bit variants of FIntVector, FIntPoint, and FIntRect types.

Added functions ToHostLineEndings and FromHostLineEndings for FString converting between different platform line endings.

Updated Oodle to version 2.9.8. Several Oodle Texture encoder improvements to quality and performance, much faster encoding on M1 Macs.

Added log highlighting, based on log category and log search string. It uses the following Command line commands: -LogHighlights="LogNet Cyan, LogTemp Green" -LogStringHighlights="UNetConnection::Close=Purple, NotifyAcceptingConnection accepted from=DarkGreen"

Added AssetSizeQuery commandlet for rapidly getting asset size breakdown by class. The class summary and assets can now be saved to a .CSV.

Assets can be filtered by a wildcard match. This requires the compressed size to have been written back to the asset registry after staging.

Added FTopLevelAssetPath struct to represent the path of an object whose direct outer is its containing package.

Moved utility functions related to linker tables from FLinker to FLinkerTables to be able to have access to these functions from the AssetRegistry code

Garbage Collector can now store information about traversed references which can then later be searched through with FReferenceChainSearch.

FReferenceChainSearch will no longer store raw pointers to UObjects when constructing reference chains, instead it will only preserve basic information about UObjects that are separate from UObjects themselves so that FReferenceChainSearch objects can be used more than one frame.

Expanded LoadMap world leak tracking to add configurable severity and separate console variables for shipping configuration. This reduces memory usage and adds a low memory usage option for approximate direct reference and outer chain checks.

Added support to writing platform specific tags to the asset registry during cook by the book.

Allow command line arguments to the engine in LowLevelTests.

Added ParallelForWithExistingTaskContext, which is similar to ParallelForWithTaskContext except it takes a pre-allocated array of task contexts and launches one task per context.

Limited derived data cache bucket names to 63 characters.

Updated FSoftObjectPtr values stored in the asset registry tags to match the current format returned by FSoftObjectPtr::ToString.

Added IRequestOwner::LaunchTask to DDC to easily chain together tasks and cache requests.

Updated Mac and Linux to use libcurl 7.83.1.

Added a partial derived data cache record propagation to the hierarchy.

FEditorBulkData can now attempt to read payloads from package files without a valid attachment to the file on disk.

Added specializations of TValueOrError for void value and error types.

Added TryReadLock and TryWriteLock to FRWLock.

Added functions to serialize derived data cache types to and from compact binary, including strings wherever appropriate.

Serialized PKG_Cooked and PKG_ContainsNoAsset in the package flags in the FPackageFileSummary.

Restricted the giant FGCCSyncObject and FUObjectHashTables locks to the reachability analysis phase.It is possible to toggle to the previous legacy behavior with the command gc.LockBehavior=1.

Changed the CppStructOps registration code to use struct path names instead of short names. This allows identically named native structs to be registered in different modules

Printing references to stale objects will now take into account GarbageCollectorKeep flags that can prevent an object from being Garbage Collected even though it's not referenced.

Added UStruct::GetStructPathName and UClass::GetClassPathName functions that return an FTopLevelAssetPath type instead of an FString. This means that the engine is now enforcing UClasses and UStructs to be 'top-level objects'. Their Outer object can only be a UPackage object which has a null Outer object.

Added new utility functions that can be used to fix ANY_PACKAGE deprecation warnings. These functions include:

UClass::TryFindTypeSlow

UClass::TryFindTypeSlowSafe

UClass::TryConvertShortTypeNameToPathName

UClass::TryFixShortClassNameExportPath

Converted hardcoded short class and enum names to pathnames due to ANY_PACKAGE deprecation.

Added EPropertyFlags::CPF_NonNullable that can be used with FObjectProperty to ensure that setting nullptr to the property is a no-op and the set has no effect.

Added empty directory deletion to derived data file system cache store maintenance

Added automated startup tests to check if class / struct / enum / property metadata contains values with short type names to help with deprecating the ANY_PACKAGE macro.

When an assertion fails, logs will now be Flushed to provide more details in the debugger and log files.

Per object config sections can now also contain class path names.

Added the Packaging Reference Chunk Database system. This allows projects with iostore containers that have already been deployed to customers to upgrade or change packaging compression settings and avoid re-deploying content to end users.

This provides the previously deployed containers, and chunks containing the same data will be re-used instead of re-compressed.

Added Asset Bulk Data Diff Commandlet.

Added "Diff Tags" support. Commandlet and Diff Tags provide a way to understand why the bulk data for a given asset has changed. Changes are grouped by which diff tags caused the change which allow for rapid understanding of large patch sizes.

Added LoadFromCompactBinary as a standardized way to load from compact binary.

Added derived data cache replay functionality A cache replay can be created from any program that uses the cache, and can be replayed through any cache graph in any program that uses the cache.

You can save a cache replay by adding -DDC-ReplaySave=PathToReplay.ddr to the command line.

You can load a cache replay by adding -DDC-ReplayLoad=PathToReplay.ddr to the command line one or more times.

You can modify the cache priority on loaded replays with -DDC-ReplayLoadPriority=Priority. - For example, -DDC-ReplayLoadPriority=Lowest will queue replayed requests to execute asynchronously.

You can modify the cache policy on loaded replays with -DDC-ReplayLoadAddPolicy=CachePolicy and -DDC-ReplayLoadRemovePolicy=CachePolicy.

-DDC-ReplayLoadAddPolicy=SkipData will make the replay prefetch into the cache stores earlier in the cache hierarchy.

-DDC-ReplayLoadRemovePolicy=QueryLocal will make the replay query only remote cache stores.

You can Filter, save, or load operations by combining arguments. -DDC-ReplayMethods=Get+GetValue+GetChunks will process requests of the corresponding methods.

-DDC-ReplayTypes=Type1[@Rate1][+Type2[@Rate2]...] will only process requests of the corresponding types.

-DDC-ReplayRate=Rate will only process Rate% of the requests that do not match one of the type filters.

-DDC-ReplaySalt=Salt configures the salt used to filter by type and rate, which makes them match consistently between sessions instead of being random.

You can Load a cache replay with the console command: DDC.LoadReplay ReplayPath [Priority=PriorityName].

Added a compact formatting mode to the conversion of compact binary to JSON.

Added FindObject function overloads that accept FTopLevelAssetPath struct as the object path name.

Extended -DDC-MissTypes with more options to simulate cache misses. In the examples below, is the name of a node in the cache store graph, or you can use All to apply to every node.

-DDC-<Node>-MissTypes=StaticMesh+Texture will simulate a miss on every access to to static mesh and texture keys.

-DDC-<Node>-MissTypes=StaticMesh@12.5+Texture will simulate misses on 12.5% of accesses to static mesh keys and every access to texture keys. -DDC-<Node>-MissRate=5

-DDC-<Node>-MissTypes=Texture will simulate misses on every access to texture keys and 5% of other keys.

-DDC-<Node>-MissRate=5 will simulate misses on 5% of keys.

-DDC-<Node>-MissSalt=PositiveInt32 will set the salt used to match keys to simulate misses on. A key always has the same simulated miss behavior with the same salt.

Added EngineConsoleCommandExecutor to provide IConsoleCommandExecutor outside of the editor.

Set UnsafeTypeCastWarningLevel to Error for several widely-used modules. Projects with changes to these Epic-provided modules will need to fix any of these warnings in the modified code in order to build.

Unreal logging functionality is now used in LowLevelTests instead of LocalPrint.

Upgraded to BLAKE3 1.3.1.

Enabled the experimental Unreal Cloud DDC on Mac and Linux.

Added FCompositeBuffer::EqualBytes function to compare the contents of two composite buffers.

Added ConvertLegacyCacheKey to construct new cache keys from legacy cache keys.

Added a commandlet to export an asset registry database to a sqlite database, which allows sql queries of assets, types, and asset tags. This commandlet is in the plugin AssetRegistryExport and must be enabled to be used.

Updated zlib to 1.2.12.

Added IsInheritedInstance to exports.

Added missing generated public hash entries to ArchiveStackTrace.

Added support for writing back compressed asset size to an asset registry during or after iostore packaging.

Added iostore chunk hashes to the asset registry during cook.

Added a dedicated thread for logging.

Added -DDC-Verify arguments to control cache determinism verification.

-DDC-Verify will verify determinism on every access to the cache.

-DDC-Verify=StaticMesh+Texture will verify determinism on every access static mesh and texture keys.

-DDC-Verify=StaticMesh@12.5+Texture will verify determinism on 12.5% of accesses to static mesh keys and every access to texture keys.

-DDC-VerifyRate=5 -DDC-Verify=Texture will verify determinism on every access to texture keys and 5% of other keys.

-DDC-VerifyRate=5 -DDC-Verify will verify determinism on 5% of keys.

-DDC-VerifySalt=PositiveInt32 will set the salt used to match keys to verify. A key always has the same verification behavior with the same salt.

Added AppendChars(TStringBuilderBase&) to allow string builders to work as the output of algorithms.

Reduced stack usage of assertions, crashes, ensures, and fatal logs by between 8 and 24 KiB.

Replaced PanicFlushThreadedLogs() with the new GLog->Panic() that switches logging into a mode that the panicking thread takes over log flushing and only redirects logs to panic-safe output devices.

Utility functions like FindFirstObject or UClass::TryFindType have been introduced to provide similar to ANY_PACKAGE functionality in scenarios where providing an Outer object or object path name is not possible.

Added String/RemoveFrom.h

Cleaned global Engine header dependencies by removing includes of "Engine/NetSerialization.h" from global headers.

Minor dependency cleanup in ComponentSourceInterfaces.h

Added a softobject path table to the package summary header This is to felicitate validation by inspecting the header and allow asset patching by using the header without export loading.

Dependency cleanup in Chaos focused on removing includes from ChaosSolverConfiguration.h.

Added FStringView constructor to FStringFormatArg.

It is now possible to override system guids, which are often used for derived data versions, on a per stream basis allowing the guids to be changed in separate streams without causing merge conflicts.

Modified FlushTree to FlushRequest. It will now Automatically propagate explicit package load request association to package dependencies which allow flush requests to process only related packages while skipping others.

Improvement:

Optimized the FGCObjectInfo::TryResolveObject function to use only FNames instead of FStrings to search for objects.

Improved performance for FLinearColor to sRGB and UNORM conversions.

Refactored to store book keeping and allocations separately, including matching allocations to pools with pointer arithmetic.

Improved Blueprint API for soft object paths. They can now be easily created from path strings and loaded objects.

Renamed related Blueprint functions for clarity.

Optimized AssetDataGatherer cache load.

Optimized performance by limiting a contention between consumer and producers.

Improved AssetRegistry loading optimization.

Optimized macro WITH_CASE_PRESERVING_NAME FName loading to help editor startup time.

Core constexprification pass to reduce code bloat, improve performance and simplify searching for non-constexpr constants.

Optimized BuildCacheKey using FAsciiSet.

Improved several TArray comments.

Optimization in the LinkerLoad, when it has many bulk data loaders. Turned the TArray into a TSet. This speeds up loading certain geometry caches significantly.

Optimized the output redirector to process concurrent logging about 25 times faster

Optimized the derived data file system cache for network file shares.

Optimized formatting FDateTime to be about 7 times faster.

Optimized formatting of log messages to be about 3 times faster.

Refactored compiled-in FProperty constructors so that they have the same signature.

Improved ensure error message during package save when a name isn't mapped.

Crash Fix:

Fixed an unbound delegate crash in the directory watcher.

Added crash fixes with small iostore containers by changing the calculation of number of partitions for iostore containers to use the end of the last block rather than the start of last block.

Fixed a crash during package reload when failing to purge the old package.

Bug Fix:

Blueprint object and field names can now be used with core redirects.

Used pass by reference instead of pass by value for TArray to eliminate a copy in the UNetDriver::ServerReplicateActors_PrioritizeActors function.

Memory image determinism fixes: When building name patches, compare names case sensitively.

Fixed UObject::GetPreloadDependencies not gathering from C++ classes

Reserve byte array for FUniqueNetIdRepl::ReplicationBytes to minimize allocations and wasted space

Garbage Collection locks are no longer acquired when GIsInitialLoad is true.

Fixed an overflow issue where very large float A values would sometimes results in pixels with A=0 on FLinearColor to sRGB conversion.

Allow methods that can only be invoked from a constructor be available when fetching vtable addresses for HotReload and Live Coding.

Fixed FInstancedStruct edits not propagating to instances when editing a Class Default Object.

Fixed bugs in crash malloc. When a small pool was exhausted it became impossible to free any allocations in the pool, because Free used the same search function as Malloc which only considered pools with space available.

Fixed FName debug visualizers on clang and gcc platforms.

Fixed divide by zero in vectorized TTransform<T>::InverseTransformPosition and TTransform<T>::InverseTransformVector functions that were causing floating point exceptions.

When the engine renames a garbage package that cannot be freed because of GC reference elimination pending kill is disabled, removed those packages and their exports from the async loading thread's caches.

Fixed a compile error in static analysis builds when copy constructing a 2-tuple of different, but compatible types.

Marked packages as garbage in PrepareStreamedOutLevelsForGC so that weak pointers to them in the net driver's guid object cache become invalidated even if they are not freed because of dangling references when GC pending kill is disabled.

Fixed LaunchFixProjectPathCase assuming that TCHARs are WIDECHARs and fixed FOutputDeviceStdOutput::Serialize in UTF-8 mode.

Fixed memory corruption when converting a null-terminated string via StringConv<UTF8CHAR> where the string ends with two high surrogate pairs.

Give DEFAULT_SERVER_FAKE_FORKS a default value for all games/builds.

Fixed many invalid uses of TCHAR and TEXT in UTF-8 mode.

Fixed FString and TStringBuilder appending UTF8CHARs.

Made FFilteredActorCollector keep weak pointers to Actors in order to support disabling GC pending kill reference elimination.

Fixed FMapProperty::IsPermutation and FSetProperty::IsPermutation functions.

Replaced nullptr_t with TYPE_OF_NULLPTR to prevent errors being reported in IDEs utilizing clangd, like QT Creator.

Fixed UTF-8 decoding from emitting multiple chars for a correctly parsed codepoint but invalid value.

Fixed TNonRelocatableInlineAllocator leaking heap allocations.

Various Niagara class fixes for compiling under C++20.

Release pointers to components in FParticleSystemWorldManager when they are marked as garbage.

Fix EGuidFormats::Short so that it uses Base64 encoding as the documentation states

Fixed compile error in TIsInvocable when given a member function pointer and an incompatible target type.

Made TTransform trivially-copyable in vectorized mode.

Removed useless ANSI->UTF8 conversions. Fixed incorrect sign extensions during to-UTF8 conversions.

Fixed FGenericWidePlatformString asserting and going into an infinite recursion when setting PLATFORM_USE_GENERIC_STRING_IMPLEMENTATION=1 in Windows.

Marked LocalPlayer as garbage when removing it from GameInstance to track outstanding references when GC reference elimination (pending kill) is disabled.

Disabled the use of PersistentGarbage flag because for removing reported garbage references.

Fixed TNonRelocatableInlineAllocator leaking heap allocations.

Fixed output when converting a string with an orphaned high surrogate at the end of the input.

Added UObject::GetImplementingOuter, an interface counterpart to UObject::GetTypedOuter.

Added header with state of editor-only-data-stripping to saved asset registry to allow properly loading cooked asset registries from a WITH_EDITORONLY_DATA binary.

Fixed a hang on shutdown of UELibrary caused by the trace thread not being shut down.

SceneCaptureComponent releases pointers to garbage Actors pre-GC.

Fixed broken assert strings in TArray64 and TArrayView64.

Made formatting functions FString::Printf capable of taking char* formatting strings in UTF-8 mode.

Fixed incorrect memory ordering in TSharedPtr::IsUnique in ThreadSafe mode.

Remove FAndroidPlatformString::Strncmp, which read out of bounds for unterminated string, and fall back to the faster FGenericPlatform algorithm.

Inserted dummy values into memory images for names like vtable pointers.

Fixed archetype flag from not being set during object duplication during text import of a UObject property preventing serialization and PostEditProperties from reading it.

FThread now supports the -nothreading command-line argument.

Fixed reversed ordering of mounted containers in the FilePackageStore.

Unified the alignment behaviors of FMallocTBB::TryMalloc and FMallocTBB::TryRealloc functions.

Made UClass::Implements private to prevent accidental misuse.

Added a scope object IModularFeatures::FScopedLockModularFeatureList to easily lock and unlock the list of modular features when accessing it.

Fixed render capture provider from firing an assert when accessing IModularFeatures from outside the game thread.

Avoid locking the modular features list when calling GetEngineCrypto, since the IEngineCrypto is only accessed once and stored in a static member.

Check the IsValid flag when comparing Tboxes, and more generally take the flag more often into account.

fixed implicit 64-bit to 32-bit conversion in ParallelTransformReduce.

Added CORE_API to FComplexStatUtils struct for games usage.

Fixed forwarding of -DDC=<Graph> to child processes to avoid initializing DDC and only forward non-default graph names.

Refactored initial load in AsyncLoading to remove the Zen loader dependency on the prebaked script object blob located in the global.ucas. This will rely on NotifyRegistrationEvent callbacks.

Made initial loading more robust when Blueprints are referenced by native Class Default Objects.

Fixed missing logging of callstacks for failed assertions.

Restored the functionality of the command DEBUG OOM. By default the command will leak 1MiB of memory per frame in 64KiB chunks, but these values can now be overridden by entering additional values after the command.

FAutomationTestBase::bSuppressLogs will now default initialize to false and keep its value if a derived class change it.

Nested subobjects that have overridden properties in a Blueprint are now initialized correctly from their archetype, and not the native default values.

Nested subobjects that are part of Objects created from a template will now correctly initialize their properties from the supplied template.

Fixed a regression that incorrectly flagged nested template objects as inherited instanced subobjects in the package export map.

The correct object will now be looked into when determining if the inherited instance should be instantiated.

Fixed CreateFileReader to respect the flags passed to it.

We now propagate the necessary object flags when duplicating an instanced subobject to another owner.

Calling Rename on a UPackage will no longer reset the loaders for all currently loaded packages which caused memory bloating in the editor.

Added support for structured bindings to UE_LOG, checkf, ensureMsgf.

Ensure that editor-only subobjects are instanced on load for cooked packages when running on platform targets that include editor-only data.

Fixed FObjectPtrProperty::Identical from not respecting deep comparisons.

DirectoryWatcherWindows will now handle ERROR_INVALID_PARAMETER when buffer size is too large to watch a network file share.

pendingkill flags will now properly clear to prevent asserts when duplicating Actors.

Fixed a data race in FAsyncWriter that was in the file output device.

AsyncLoading will no longer reconstruct existing destination subobjects in cooked packages, they should always have been created from the correct up-to-date template.

Fixed the console command obj refs -history=1 from not looking in Garbage History when it's enabled.

Fixed AssetManager ModifyCook to correctly apply cook rules to asset bundles so it handles labels properly.

Added ensure to set GIsGarbageCollecting=true for the complete IncrementalPurgeGarbage phase since we always want BeginDestroy to behave the same even if it is called from a full blocking Garbage Collection or from an incremental Garbage Collection step.

Fixed destroying a ChildActorComponent from failing an assert in the UObjectBase destructor that was checking for NAME_None.

Made GetTransientOuterForRename more available. This can be used to fix a crash when changing a class if that class needs to be within.

Fixed the use of FORCENOINLINE and UE_DEBUG_SECTION macros for logging and assertions.

Class verification is now being deferred to package import creation time on load whenever appropriate, so that load linker warnings don't emit false positives.

Fixed code generation for TFieldPath property in UFunction params.

Added propagation of derived data cache records that contain metadata with no values.

Fixed deadlocks during crash reporting by avoiding allocations in the FAsyncWriter::SerializeBufferToArchive function on platforms that use FPlatformMallocCrash.

Fixed IsDefaultObject to not return true for Class Default Objects.

Fixed compilation manager duplicating a subobject when one of the same name already exists.

Fixed instanced variable defaults from not duplicating on copy paste.

Moved exported symbols from TokenizedMessage to the .cpp file.

Fixed data loss that was caused by a failure to look up component templates during reinstancing.

Fixed incorrect assignment of GIsConsoleExecutable that caused performance degradation when stdout is redirected to a file or pipe.

Removed non-suppressible warnings from SetTimeStamp.

Fixed String Tables from not loading Metadata.

Fixed an edge case where objects could be post loaded during async loading without having been deserialized.

When saving an ini file, the SourceIniHierarchy wasn't being configured correctly, causing things like array clearing to not be handled correctly.

Previously an errant heartbeat present hang could be triggered if the macro PLATFORM_PRESENT_HANG_DETECTION_ON_BY_DEFAULT was disabled. This change resolves the initialization of present hang detection settings preventing a race condition that triggered the errant hang.

PLATFORM_PRESENT_HANG_DETECTION_ON_BY_DEFAULT can now be safely disabled.

Fixed a compile error when STATS is disabled.

Fixed potential deadlocks when serializing objects while holding the object hash lock and async building meshes.

Deprecated:

Removed out of date CEF content.

Deprecated FDateTime plus FDateTime operator.

Delegate nested binding types.

Deprecated UE_SECURITY_LOG and CLOSE_CONNECTION_DUE_TO_SECURITY_VIOLATION macros.

FBlueprintContextTracker::GetScriptStack which returned a TArray copy of the script stack is deprecated in favor of FBlueprintContextTracker::GetCurrentScriptStack and FBlueprintContextTracker::GetCurrentScriptStackWritable which return a TArrayView of the script stack

Deprecated PLATFORM_COMPILER_HAS_IF_CONSTEXPR.

Replaced DEPRECATED_MACRO with UE_DEPRECATED_MACRO.

Deprecate and remove the usage of FUntypedBulkData. Users should use the generic FBulkData or the typed TBulkData.

Deprecated StartAsyncLoading and CreateStreamingRequestForRange.

Deprecated and replaced the usage of StartAsyncLoading and CreateStreamingRequestForRange with a new batch API for requesting bulk data. The new API fits better with the I/O dispatcher API and does not assume that the bulk data resides in the same I/O chunk. The new API also removes state handling away from the bulk data instances.

Bulk Data - deprecate GetPackagePath/PackageSegment

Deprecated the public string view literals _SV, _ASV, _WSV, and _U8SV. which have been changed to TEXTVIEW, ANSITEXTVIEW, WIDETEXTVIEW, UTF8TEXTVIEW.

Removed aggressive subobject replacement. Replaced with a toggleable audit to report any cases where the aggressive replacement was in use from the replacement archiver.

Deprecated ANY_PACKAGE macro support for looking up UObjects using the ANY_PACKAGE macro. Programmers are encouraged to provide the Outer object or object path names when upgrading their project, such as FindObject<UClass>(nullptr, TEXT("/Script/Engine.Actor")) whenever possible.

Deprecated FolderName in UPackage and replaced it in PackageSummary with the PackageName.

Removed:

Ensure from FName about unfreezing names that were created for a case-insensitive target. We rely on the archive used for serialization to save names with their case intact.

References to Actors to help ensure partial GC when there are outstanding references.

Removed ignored calculated values from TBigInt::ToInt, FGenericPlatformMallocCrash::InitializeSmallPools and FArchive::SerializeCompressedNew functions.

Deleted SavePackage1. It has been replaced by SavePackage2 and is no longer supported.

Removed TObjectPtr.IsNull, TObjectPtr.IsNullNoResolve, FObjectPtr.IsNull and FObjectPtr.IsNullNoResolve.

Removed deprecated PackageGUID and Dynamic Type from FObjectExport

Removed rendering includes from PhysicsPublic.h in favor of forward declarations.

New:

Added commands to open File History, Revision Graph, and Timelapse views from the UnrealVS.P4 menu.

UHT will now warn the user if any form of GENERATED_BODY is used in code that is being skipped.

Added warnings when C++ UHT is used. These warnings include the reasons why C++ UHT is being used. The warning is currently disabled but informational messages will still be generated.

Console feedback is now provided when starting live coding fails packaged builds.

Added compile PCH with -fpch-instantiate-templates in Unreal Build Tool if compiling with clang 11+. This flag has shown to improve compile times by 10-20% when using PCH.

Added support for deprecation macros for enum values in UHT.

Added support for final keyword on structure definitions.

Added --include argument to sync subcommand to limit the files synced in Unsync.

Added --files flag to info subcommand to list files in manifests in Unsync.

Added support for syncing subsets of files in a directory in UnsyncUI. File group is activated by finding any file that matches the regex, then groups from the regex can be used to populate the --include argument to Unsync CLI.

Added option to CSVInfo to extract specified stat values from the CSV.

Added -showAllStats which outputs all stat samples to the json file as an array.

Added -statFilters which lets you specify what stats to output values for.

Added additional info to the help text. + Added option to write events with their frame numbers.

Added the name of the platform when dumping the Manifest into FinalCopy_XXX.txt.

Added a new delegate to the CSV profiler that fires once on frame 0 of the capture so we can send the pause event as soon as valid.

The PerformanceTrackingSubsystem now handles sending the pause/resume events.

Added option to remove programs when generating project files.

Generate a .vsconfig that recommends Visual Studio components to be installed, this will prompt the user to run the installer in the Solution Explorer.

Allow custom output directory using -OutputDir= in Generate Clang Database with Unreal Build Tool.

Added support for specifying the C Standard when compiling plain C files.

Added the ability for an individual UObject class to change how its name is reported in stat IDs. This allows us to change stats like PlayerPawn.NiagaraComponent to PlayerPawn.FootstepFX.

Added a few implementations of the ANSI overload of FExternalProfiler::StartScopedEvent. This enables using the ANSI external profiler on all platforms.

Added import_text / export_text to wrapped structs in the PythonScriptPlugin. Any struct can now be exported to text or imported from text — similar to what you can do in C++ using the UScriptStruct.

Changed "named events enabled" text to render regardless of which path enabled it, instead of only when using the "stat namedevents" path.

Added metric for percent of frames where the game thread is over some budget in PerfReportTool. This metric can be added to summary tables.

Added OnCSVProfileEndRequested delegate that is called immediately before ending a capture that allows any final information to be written.

Added FVector4 support to Unreal.natvis so the W component appears in preview windows without manually expanding.

Improvement:

Improved support for contextual logging in UHT.

Updated Live Coding to Live++ 1.6.10.

Cleaned up formatting in both C++ and C# UHT.

Improved logging to show the object type being reloaded.

Updated PerfReportTool to treat extra links starting with '/' as links instead of link templates.

Changes to the Histogram summary table in PerfReportTool:

Removed the hitch table since the tool has a separate hitch summary.

New option to suppress the averages table.

Reversed from under to over budget.

Improved support for PreBuildSteps generating files.

Crash Fix:

Fixed a reliability issue with Live Coding where it could crash on startup.

Fixed a crash issue when LiveCodingConsole is run independently.

Bug Fix:

Fixed net enabled properties when would prevent properties from finding their getter/setter methods.

Classes that are detected by live coding that do not change in structure will no longer invoke the reinstancing system since it isn't needed. Changes to default values will be mantained.

Fixed an issue where project plugins would not compile with an installed engine.

Fixed wrong API macro from being used in C# UHT.

Fixed an issue where C# UHT was not catching some Blueprint properties contained in editor only sections.

Fixed UHT from failing to add enum metadata to a fixed array when a space appears in the array size.

Fixed an issue with LiveCoding reload where a fatal error would be generated even if a class had not changed.

Fixed issue where packaged Blueprint builds would not be able to start live coding without first having to clear the live coding source project variable.

Fixed a C# UHT issue where unterminated strings were not detected properly and could result in an infinite loop.

Fixed an issue in C# UHT where if an old style enum was returned from the "Implementation" method, the zero value would not be wrapped in the TEnumAsByte.

Fixed issue where Live Coding could remove properties from a class that contained delegates.

Fixed UHT error when class name contains only a prefix.

Fixed an issue where C# UHT would not declare shadowing errors where C++ UHT would.

The CoreNet header file will now be automatically included in UHT generated code when needed.

Fixed an issue where live coding would warn that a plugin was not enabled for live coding. This would happen if the plugin was not explicitly enabled by the project, but was loaded by another plugin.

Refactored HotReload/Live Coding re-instancing to re-instance classes more orderly and support the referencing of the new default object prior to the class being re-instanced.

Initialized UseShellExecute to the default of the .NetFramework to avoid issues. The default used to

Added ShortNames to Code Access plugins to reduce the pressure on path length.

Fixed the creation of multiple packages\platforms in a single call in BuildCookRun. The upluginmanifest file needs to be platform specific. It will prevent some of the packages from running otherwise.

Fixed csv profiler pause event not firing at start of capture.

The skipClient option in Unreal Automation Tool resulted in internal exceptions and infinitely looping test runs. Fix includes:

NullAppInstance only completed on WaitForExit, but some tests have completion criteria other than exit. To resolve this, NullAppInstance tests are now considered complete upon creation.

IDeviceUsageReporter now takes a platform reference and correctly handles a null platform. No events will be logged when given a null platform.

Fixed a C# Unreal Header Tool issue where struct properties were not performing all required validations.

Fixed a C# Unreal Header Tool issue where struct serializers were appearing in the wrong place.

Fixed the Rider project generator in the presence of platform extension specializations in Unreal Build Tool.

Added all files under Unreal Build Tool output directory to fix an issue running build setup on linux builders.

Fixed HelmTask in BuildGraph:

No longer modify the global kubecontext, but rather pass the context to use into helm.

Added an option to specify which kubeconfig to use.

Fixed an issue with values not being handled correctly.

Fixed an issue with HelmTask in BuildGraph not handling the situation when there were no values files.

Deprecated:

Enabled C# UHT by default. Set UEBuilderConfiguration bUseBuiltInUnrealHeaderTool to false to force C++ UHT to be used. C++ UHT will automatically be run if ScriptPlugins are enabled when a C# UBT plugin isn't detected in the same module.

API Change:

Added TraceAnalysis LLM tag which captures all memory allocated by the FAnalysisProcessor.

Added Trace/CpuProfile LLM tag which captures allocation of per-thread buffers used by the cpu profiler trace.

Unreal Insights: Added Exec function API to IUnrealInsightsModule and to IInsightsComponent.

New:

Added "FVirtualWinApiHooks::" and ".*/ConcurrentLinearAllocator.*" to symbol filters.

Added support for stats counters with the ShouldClearEveryFrame flag to reset to 0 at the beginning of each Game frame during analysis.

Added separate counters for frame variants of stats counters with a ShouldClearEveryFrame flag.

Added Open Source in Visual Studio option for any callstack frame of any allocation item, in the Allocs Table/Tree view.

Added the Trace.Screenshot command to that creates a screenshot and sends it to the trace file.

Added TraceAnalysis and Trace/CpuProfile LLM_SCOPEs to reduce Untagged allocations.

Extended the command line argument -ExecOnAnalysisCompleteCmd to be used without AutomationTesting and to run custom commands exposed by Insights components.

Added custom response file support for -ExecOnAnalysisCompleteCmd command line argument.

Added Tag column to the 4K Page Breakdown view preset.

Set the initial sorting mode to Descending for most numeric columns in Timers, Counters, Net Stats, Mem Allocs, and generic table/tree views.

Added Auto Open Live Trace toggle option in the main menu. If enabled, the analysis starts automatically for each new live trace session, replacing the current analysis session.

Added time limit for updating metadata for a trace. If the time limit is exceeded, the current metadata analysis stops, allowing other traces to update metadata, then it will retry with an increased time limit.

Added infinite symbol for End Event Index and Event Distance table columns in Allocs Table.

Added sorting for all columns in the trace sessions list view.

Changed Ctrl+C when copying the selected CPU/GPU timing event to copy the duration and the metadata of the timing event.

Added custom commands exposed by the TimingProfiler: - TimingInsights.ExportThreads file, - TimingInsights.ExportTimers file, - TimingInsights.ExportTimingEvents file [-columns="..."] [-threads="..."] [-timers="..."] [-startTime=...] [-endTime=...], The "..." params defines filters for list of columns, threads or timers; it supports *?-type wildcards.

Added Platform, AppName, Build Config, and Build Target of trace session being analyzed to the application title name.

Added LLM_SCOPE in FSlateApplication::OnSizeChanged in an effort to reduce untagged allocations.

Split the "Stats" column into 4 separate columns: Discovered, Cached, Resolved and Failed.

Added sorting for all columns.

Added Rename option in the context menu for a trace session. Allows renaming for the selected utrace file. The ucache file is also renamed automatically.

Added Delete in option context menu for a trace session. Deletes the selected utrace file. The ucache file is also deleted automatically.

Added Insights.Enumerate10K and Insights.Enumerate100K tests that can be run from Unreal Insights on any utrace files.

Added filtering for the list of trace sessions by Name, by Platform, by App Name, by Build Config, and by Build Target.

Added stats.NamedEvents 0/1 and stats.VerboseNamedEvents 0/1 console commands to be able to force enable or disable the NamedEvents. The existing stat NamedEvents and stat VerboseNamedEvents are still available with toggle state behavior.

Added error checking for large memory traces.

Added Insights memory scope in various places to capture untagged memory when Insights is running in the Editor.

Enabled SameValue aggregation for the Memory Tag column of the Memory Allocations table/tree view. The Aggregated value is equal with it's children value if all children have exactly same value, otherwise the aggregated value is empty.

Added Class Name column to the Allocs Table together with a custom view preset.

Added more UObject memory scopes to reduce the Untagged allocations.

Added F5 key shortcut to refresh the list of trace sessions.

Added the console command Trace.SnapshotFile. This command saves a utrace file with content of the trace tail buffers.

Added Empty Callstack for callstacks traced/resolved with zero stack frames.

Added Asset column and Asset view preset to the Memory Allocations table view.

Added "Path Breakdown" grouping for all string columns.

Added a toggle button to choose between searching and filtering the list of trace sessions by Name or by the Command Line. Added highlights for searched text.

Added LLM_SCOPEs in PythonScriptPlugin to reduce the Untagged allocations.

Added TraceUtilLibrary to control Insight traces from Blueprints.

Added MemoryTrace function name prefix to ignore callstack frames when detecting the top function of a callstack.

Updated icon for the UnrealTraceServer.exe.

Added new TimingInsights.ExportTimerStatistics command to the ExecOnAnalysisComplete parameter. This will export statistics for all timers to a CSV file and supports specifying a range inside the trace file through bookmarks.

Added "Session Browser" in the main menu. Opens the Unreal Insights Session Browser window.

Added "Open Trace File / Open in New Instance..." in the main menu. Starts analysis for a specified trace file, in a separate Unreal Insights instance.

Added "Open Trace File / Open in Same Instance..." in the main menu. Starts analysis for a specified trace file, replacing the current analysis session.

Added "Top Source File" and "Callstack Size" columns in Mem Allocs table and improved tooltip for "Top Function" column.

Updated description of some memory rules to avoid confusion.

Added LLM_SCOPEs to each analyzer in TraceServices and Insights plugins to reduce the Untagged allocations.

Added memory tracing for D3D11 and D3D12 using the "video memory" root heap / address space to match LLM stats.

Added GetTraceDestination, IsConnected and GetActiveChannelsString to public interface.

Added tracing for the cooking profiler.

Improvement:

Memory insights performance fixes for a large hash bucket in the backtrace.

Improved the performance and memory usage for sorting the Function column in the Allocs Table and in the sorting of text columns.

Implemented micro-optimizations to sorting code for Timers and Counters.

Improved coloring to highlight modules with failed status.

Improved performance of sorting,filtering, and grouping operations involving the top function of an allocation's callstack.

Improved performance of memory analysis (processing of live allocations in AllocationsProvider) with up to 50%.

Switched the short living allocations to use only the linked list, with a reduced size.

Improved metadata update by prioritizing the newer trace sessions. enabled parallel update for metadata.

Improved analysis of scoped memory events by avoiding a "strlen" for each scoped event.

Improved analysis of mem tag events.

Improved performance of filtering and grouping.

Crash Fix:

Fixed a crash in Unique Values grouping for string columns.

Fixed a crash when closing Unreal Insights while having a minor tab undocked in Timing Insights, Memory Insights, Asset Loading Insights or Networking Insights.

Fixed TraceStats crashing when the stat name is a wide char FName.

Workaround for crash in TRACE_LOG_MESSAGE when encounters string arguments are not null-terminated.

Fixed a crash when a CPU timing event has metadata with zero fields.

Fixed crash in the analysis of timing events emitted just before EndThread trace event.

Bug Fix:

Fixed the command line argument -AutoQuit to work without AutomationTesting.

Fixed a bug where changing a preset resulted in hiding the Hierarchy column.

Fixed "Audio" LLM child tags for Audio_Analysis, Audio_MetaSound and Audio_SpatializationPlugins.

Multiple fixes and improvements to TPagedArray and its iterator.

Fixed trace analysis to continue reading at least one more loop after encountering a SYNC point.

Fixed case where SourceCodeAccessor remains in a started state and does not respond anymore to more requests.

Fixed support for unicode file names for trace files in the UnrealTraceServer.

Fixed session name when a trace name contains a dot char.

Fixed deadlock for analysis thread when session completes.

Fixed issue where the number of Discovered symbols for a module was lower than Resolved and Failed.

Disabled Profiler if STATS is not enabled.

Fixed the order of GPU and GPU2 tracks.

Merged tags that had the same name but different id, when grouping by Tags in Memory Allocs table.

Fixed grouping by Tags in the Memory Allocs table when all tags are unknown/untagged.

Fixed StatsTrace from incorrectly tracing disabled stats.

Fixed callstack tracing not capturing correct backtrace for majority of allocations in Editor Win64 Debug.

Fixed analysis of timing events with metadata.

Fixed the full name of LLM tags to include parent names when there are multiple levels of inheritance.

Fixed track invalidation when a track filter is changed.

Fixed TextureProfiler to emit the inline stat spec events only once. The spec events are "important" trace events. These events are cached by the trace system, so they should not be emitted continuously.

Fixed Important Events cache stats displayed by Trace.Status console command.

Fixed allocations analysis to safely ignore errors re invalid MemoryScopePtr scoped events.

Fixed max width for the search boxes.

Fixed initialization of Platform Events.

Fixed missing tree items when multiple groupings are added in a generic Tree Table view. Groupings are now recursively applied correctly when a grouping creates a hierarchy of node.

Removed:

Removed Unique Values grouping for StartEventIndex, EndEventIndex and Count columns.

Removed Path Breakdown grouping for Top Function column.

Framework

New:

Added support for multiple concurrent devices in RawInputPlugin.

Increased the number of Axis to 24 and the number of buttons to 96.

Added support for objects being managed by the Significance Manager without reference elimination.

Cleaned up references between scene components when Actors are destroyed or streamed out, to avoid holding reference to garbage objects. On destruction, attachments are cleared between components owned by different actors. On un-initialize component, attachments are cleared between components in different outer hierarchies, i.e. different streaming levels. Note that this changes behavior so that attachments between scene components in different levels will be broken when either level is streamed out (made not visible) even if the level is not unloaded and garbage collected.

Added query functions for Blueprints to check if there were modifier keys held (Alt, Shift, etc.) given a key state struct.

Added logging to indicate when log levels have been raised to verbose levels to help track down log spam.

Unified how we modify GCycleStatsShouldEmitNamedEvents so that we guarantee it won't drop below zero.

Made FAssetData ~16 bytes smaller (technically 20, but there's an odd number of 32-bit structures now, so we'll shrink 8 when deprecated AssetClass is deleted). This saves about 5MB if the project has 300K+ assets. Ensure you switch any manual manipulation of ChunkIDs to use the helper methods.

Optimized code size and overhead for Insights markers generated for scope cycle counters. Down from 213 bytes per marker, to 142 bytes.

Added UE::LWC::NarrowWorldPositionChecked run time validating narrowing cast for FVector world positions.

Enabled ISPC on more supporting platforms and subsystems.

Added a UStruct-type parameter to TStructTypeBitSet type to further improve its type-safety.

Added Blueprint Graph Support for FInstancedStruct.

Added an "index iterator" to TStructTypeBitSet, allowing iterative retrieval of non-empty indices of a given container.

Added UPropertyBag and FInstancedPropertyBag, which allow users to configure and edit custom structs inline via UI or code.

Added a function to TStructTypeBitSet to fill an instance with an amount of false or true values corresponding to the number of known types tracked by a given bitset specialization.

Extended TStructTypeBitSet to support UClasses as well.

Added SetLineThickness() to UBoxComponent.

Bug Fix:

Fixed incorrect parent class in data only blueprints if parent class was changed without compiling.

Fixed crash after using LiveCoding to remove an interface function while the blueprint editor was open.

Fixed an issue where the SceneComponent hierarchy on component destruction was attaching the to-be-destroyed child components to new parents, and did not attach living child components to to-be-destroyed parents.

Fixed an issue where there was a possible division by zero in FHistogram::GetAverageOfAllMeasures.

Fixed an issue where strong pointers for UGameFrameworkComponentManager::AllReceivers were being stored, so failure to remove actors prevented world cleanup after PIE when GC reference elimination (pending kill) was disabled.

Removed the reference from Player to PlayerController when PlayerController removes its reference to Player in OnNetCleanup.

Fixed an issue where there was duplication of implemented interfaces in parent Blueprint classes.

Fixed an issue where references from LODActor where not being released when SubActors were destroyed.

Fixed an issue where user widgets were not being allowed to remove themselves from the player layers in the viewport even if the associated player controller was destroyed.

FComponentReference::OtherActor was converted to a weak object reference.

Fixed an issue where StructTypeBitSet.StructTracker was not being instanced per module.

Converted serialized external actor/component references to weak object references in the debug camera controller so that they don't prevent garbage collection.

Fixed the Reset to Default button behavior on Instanced Structs.

Fixed several truncation warning to the Engine module and its dependencies.

Fixed several issues with MassReplication when adding and removing clients.

New:

In MassEntity, shared fragments have been changed from being unique per archetype to unique per chunk.

Added MassEntity optimization when new archetypes are added to the system. When a new Archetype is added, the queries will now only check against the newly added Archetypes, instead of running against all available Archetypes.

Removed the MassEntity Archetype filter because the system no longer shares fragments per archetype (fragments are shared per chunks). Users should now use Chunk filters on shared fragments.

Added a button in the property grid that validates the Mass Entity Config asset.

Added code that detects an infinite loop in BTDecorator_ConditionalLoop, just like in BTDecorator_Loop.

Added a new console command that freezes any Mass Movement. This helps users debug Mass Movement.

Added functionality to Mass Trait to allow users to specify fragment ownership and dependencies.

Added option where the user can specify to incur most of the Mass Fragment initialization cost in the first frame, instead of spreading the cost throughout the first period.

Added a pop up toast that informs the user that no errors were detected during the MassEntityConfig validation process.

Stopping a Behavior Tree during processing is now supported. The request is queued until the Behavior Tree processing is completed.

ANavigationData now supports external packaging. This prevents sublevel navigation data from being discarded when using OFPA.

Added a warning to UNavigationSystemV1::GetNavDataForProps when using invalid FNavAgentProperties.

The NavMesh tile pool can now be resized when being built through the UWorldPartitionNavigationDataBuilder (ignoring bFixedTilePoolSize).

A warning will now appear when tiles cannot be added to the NavMesh because the tile limit has been reached.

The NavMesh debug display property bHeightfieldSolidPostRadiusFiltering has been renamed to bHeightfieldSolidPostInclusionBoundsFiltering. In addition, several properties were given descriptions.

The initialization of dtNavMesh parameters have been moved to the init() and the parameters are now serialized in ARecastNavMesh. This provides safer initialization flow and fixed potential mismatches between the NavMesh Actor and the serialized NavMesh data.

Changed bAutoDestroyWhenNoNavigation to be false by default in the NavMesh.

The NavMesh FGameplayDebuggerCategory_Navmesh can now display navigation data name, even if not a ARecastNavMesh.

Added log tracking to FRecastNavMeshGenerator RebuildAll(), independently of hte loading time.

Changed OnNavigationGenerationFinished() to display the Actor label and full name, instead of the package name.

Extracted FNavigationDirtyElement from NavigationTypes.h and removed all include dependencies.

Copying cache data when filling navigation data chunk actors for Navmeshes using the Dynamic Modifiers Only mode.

Upgraded to use FVector::FReal rather than floats.

Improvement:

The NavMesh will only include the navigation relevant components when computing UNavModifierComponent navigation bounds.

Navigation will only update Actors and its components in the Navigation Octree if the Actor has been initialized.

Crash Fix:

Fixed a bug in ARecastNavMesh::InvalidateAffectedPaths where a pointer could be pointing to an invalid memory location resulting in a crash.

Fixed a bug that would result in a crash when the EQS Details panel was closed while selecting a Test or Generator in an EQS query.

Fixed a bug in FEditorBuildUtils::TriggerNavigationBuilder() where a missing package would cause a crash.

Fixed an issue where using the World Partition Static Navmesh would cause a crash.

Bug Fix:

Fixed an issue where a new stimuli was added while processing the existing ones and this was causing issues.

Fixed an issue in the Behavior Tree where a search would result in a Decorator or Service being ticked twice in the same frame.

Fixed a bug where the range loop of the AI Perception component would change while iterating through stimuli.

Fixed a bug where a Behavior Tree would crash when the Actor destroyed itself while inside a Behavior Tree notification (e.g.: Tick, BecomeRelevant, CeaseRelevant, etc).

Fixed a bug where UAIPerceptionSystem UnregisterSource(Actor, SenseClass) would not do anything if a null SenseClass was passed in. Now it correctly unregisters the source Actor from all senses.

Fixed a bug where sometimes a Behavior Tree would select the wrong node, if the selected node was a subtree.

Fixed an issue in the Behavior Tree where a queued request during a transition would be executed, even if the requestor was not active anymore.

Fixed a bug where the Mass Processors Config values that are edited via the Project Settings were not saved correctly.

Fixed a bug in the Visual Logger cone macro where the Origin parameter did not match its function definition.

Fixed the low height span filtering during navmesh generation (Fixed bugs where the NavMesh would not be generated under low height objects).

The World Partition NavMesh builder will now avoid saving empty packages, as the delete operation is already saving them.

Updated dtClosestHeightPointTriangle() to check the denominator to prevent NaN results. In addition, this change improved precision and calculation speed.

Fixed a bug where the World Partition NavMesh would not generate because of incorrect settings.

Recently added Hierarchical Instanced Static Meshes log will not be displayed to reduce clutter.

Fixed a bug where the transformed convex collision was generating an incorrect NavMesh.

Fixed a bug where the NavMesh would not generate correctly for Landscape Mesh Collision Components.

Fixed a bug in dtRandomPointInConvexPoly() where it would return an incorrect value when the s parameter is equal to 1.

Fixed an issue where RecastNavMeshGenerator was dirtying tiles if dirty areas overlapped them.

Fixed a navigation issue where using bShouldBuildNavigationData and UResavePackagesCommandlet would check out non-navigation data-related assets.

Fixed an issue in World Partition Navmesh where WorldPartitionNavigationDataBuilder was checking out packages that were being deleted, overriding their delete status.

Fixed an issue in the Navmesh where using int32, instead of FNavTileRef for updated tiles would result in tiles being reused from the tile pool while still being referenced in the updated tile lists

Fixed an issue in the Navmesh where using the bShouldDiscardSubLevelNavData property was not working in some use cases. This property now takes effect in ARecastNavMesh::PostLoad(), instead of ARecastNavMesh::PostInitProperties().

Fixed an issue where Foliage instance static meshes were not affecting the Navmesh.

Fixed an issue where UResavePackagesCommandlet was not waiting for Static Meshes to be compiled before generating navigation data.

Fixed an issue with the Gameplay Debugger Navmesh rendering where using bRestrictBuildingToActiveTiles and GetDebugGeometry() would gather data for all active tiles for each tile in the TileSet, instead of doing this once. This was causing high framerates.

Fixed an issue with Hierarchical Instance Static Meshes where they were not modifying the Dynamic Navmesh if there were no instances on the component register and the instances were added later on.

Deprecated:

Remove some deprecated methods and members in navigation.

Crash Fix:

Fixed an issue where the GameplayDebuggerPlayerManager's editor-time ticking was getting its game-world tick via the tickable object mechanic. This was causing a crash in cases where GameplayDebuggerPlayerManager tried accessing UWorld.

Bug Fix:

Fixed an issue where users were not able to summon VisualLog while in the ‘-game' mode. This still requires ENABLE_VISUAL_LOG to be true.

New:

Changed the EQS Test's Reference Value to have the opposite effect matching its description and designed function. This change ensures the proper fix up of existing assets in PostLoad.

Crash Fix:

Fixed an issue with EQSTestingPawn where undoing editor-time actor movement from a "No EQS query results" location to a "some results" location was causing a crash.

Bug Fix:

Fixed an issue where EEnvTestScoreOperator::Multiply was not initializing the ItemScore value.

New:

Added the ability to build navigation for runtime data layers.

Added options to select and display internal Navmesh tile generation steps by setting properties on a Navmesh actor.

Added the OnNavigationInitDone delegate to UNavigationSystemBase.

Added the FindOverlappingEdges() method to get wall edges that intersect a convex polygon.

Added debugging code to track when Navmesh regeneration is taking longer than the desired maximum time allocated per frame during the time-slice operation. Slow time sliced tiles are logged both in normal log files and the visual logger. See FNavRegenTimeSlicer::TestTimeSliceFinished().

The Navmesh recast ledge span filtering code now supports time slicing.

Removed dtOffMeshSegmentConnection::height because it was not being serialized. This variable is currently unused.

Improvement:

The corridor now caches navigation data around the path and allows smoother path following, with less access to the navigation data during the path following.

Bug Fix:

Fixed an issue with client-side dynamic Navmesh generation.

Fixed an issue where the bounds passed to FNavigationOctree::AddNode were not being validated properly.

Fixed an issue where the Navmesh rendering colors were not displaying correctly when originating from a recast.

Fixed an issue where building the Navmesh by using the chunky region partitioning included the remaining non-divisible cells into the last split.

Fixed an issue where CalculateMaxTilesCount() was not changing correctly per platform and target.

Fixed an issue where the Navmesh rendering was not displaying some triangles.

Fixed an issue where the warning "Can't load actor" would appear when building a World Partition Navmesh. This was caused by Actors being deleted but World Partition not being notified and trying to load deleted Actors.

Fixed an issue where the message "The Navigation Mesh needs to be rebuilt" was appearing when running a Listen Server and Client.

Fixed an issue where building the NavMesh with disconnected single cells would not build contours.

Fixed an issue where the message "The Navigation Mesh needs to be rebuilt" was appearing when there was no navigation being built.

Fixed an issue where UInstancedStaticMeshComponent's navigation relevancy could result in removal from the Navigation octree if UNavigationSystemV1::UpdateActorAndComponentsInNavOctree was called after the first ISM instance got added.

Fixed an issue where cell size was clamping incorrectly in the RecastNavmesh.

Fixed an issue where some memory in FNavigationMemoryStat was not being tracked correctly. We were calling FDefaultAllocator::ForAnyElementType instead of FNavigationMemoryStat::ForAnyElementType and we were not logging memory used via STAT_NavigationMemory.

Fixed an issue where the navigable areas were not checking that their recast tile indices would fit into an int32.

Fixed an issue where a missing Crowd Manager would result in a nullptr de-reference.

Fixed an issue where collision boxes would have their Navigation Area Class reset to NavArea_Obstacle on project load.

Added a fix for Server Assert at FNavRegenTimeSlicer::TestTimeSliceFinished upon initializing a session.

New:

Added a log message to make it clearer when a perception component is not attached to a controller.

Added the ReportTouchEvent() function for touch sense.

New:

Added a method to retrieve a Behavior Definition from a request result.

Crash Fix:

Fixed an issue with the SmartObjectSystem where trying to register a SmartObjectComponent without a SmartObjectDefinition set would result in a crash.

Bug Fix:

Fixed an issue with SmartObjectCollections and Smart Object registrations not working correctly when Smart Objects were placed in a persistent map before the collection was built. The collection building keeps its role as a component-independent Smart Object entity collection.

New:

Added the AudioMotorSim plugin that provides a generic way to compose vehicle behaviors from a set of tunable, reusable components.

Added a Source Effect variation of Convolution Reverb.

Added a new Reverb AudioGameplayVolume Component, which controls reverb effects upon entering or exiting the associated volume.

Added a new Submix Override AudioGameplayVolume Component, which controls submix effect chain overrides upon entering or exiting the associated volume.

Added the Absolute Value MetaSound node.

Added OnListenerEnter and OnListenerExit Blueprint events for AudioGameplayVolumes.

Added the QToBandwidth MetaSound node that converts filter parameter values for ease of use with the Biquad Filter node

Added a name field to Audio Gameplay Volume Filter Proxy.

Added a name field to Audio Gameplay Volume Attenuation Proxy.

Added timecode rate and drop frame data reading from RIFF iXML for Sound Waves.

Added the au.Debug.Streaming console command to support audio stream profiling.

Added the Ring Modulation MetaSound node.

Added the ability to default AudioModulation ModulationControlMix stages to the value of a bus' parameter when changing a mix stage's associated ModulationControlBus.

Added the Trigger Select MetaSound node to support passing input triggers to output triggers based on given input indices.

Added Trigger On Threshold MetaSound nodes for Float and Integer types.

The WavePlayer MetaSound node now supports surround sound audio channel configurations.

Constructor pins have been added to allow you to set constant values for the lifetime of a MetaSound asset.

Added Bink Audio decoder libraries for Stadia.

Added low-level memory tracking for audio spatialization plugins.

MetaSound Sources now support surround sound audio output.

SoundWave Cue Points can now be accessed from Blueprints.

Improvement:

AGVListener tracks active proxy mutators to allow for a removal step.

AGVListener tracks owning audio device ID (instead of world ID).

Added detail customization to the AudioGameplayVolume Reverb component.

Renamed FillMutator to CopyAudioDataToMutator in the AudioGameplayVolume system to better reflect functionality.

Restructured creation code path in the AudioGameplayVolume system to remove the need for Super calls.

Renamed AudioGameplayVolumeProxyComponent to AudioGameplayVolumeComponent to reduce name length and to better reflect intent.

Renamed UAudioGameplayVolumeComponentBase to UAudioGameplayVolumeMutator.

AudioGameplayVolume Components may now be added at runtime.

Added profiling information for Audio Gameplay Volume Proxy types.

Reduced the baseline runtime memory footprint for MetaSounds.

Source Data Override plugins can now be implemented for all of our supported platforms.

Improved low-level memory tracking in audio-related code to provide more accurate data for analysis and debugging.

Re-enabled support for visualizing sound source attenuation shapes with the au.3dvisualize.attenuation console variable.

Renamed UMetaSound to UMetaSoundPatch for clarity and in response to community feedback.

Audio Modulation destinations now support sets.

Audio Modulation sources now support unions and can be mixed with each other at runtime.

Audio parameter transmitters will no longer be generated for SoundWave asset types which do not support parameters.

Improved support for 3rd party and plugin-defined DataTypes within MetaSounds.

Submix sends can now be performed before or after attenuation.

Crash Fix:

Fixed a crash that occurred when calling certain Audio Bus Blueprint nodes without input assets.

Fixed a crash that occurred in AudioCapture when no audio devices were enabled.

Fixed a crash that occurred when undoing changes to AudioVolume assets.

Fixed a crash that would occur when using the submix spectrum analyzer with an unclamped hop size.

Fixed a crash caused by the Flanger MetaSound node.

Bug Fix:

Adjusted Audio Gameplay Volume Proxy activation timing so that other components have a chance to initialize first.

Fixed an AudioGameplayVolume issue concerning an uninitialized listener at the origin.

Fixed an issue where Audio Gameplay Volume Listener Enter and Exit messages would propagate to disabled components.

Fixed errors in several tooltips.

Fixed an issue in GameplayStatics involving ownership assignment of new Audio components.

SynthComponent will now avoid taking destroyed component pointers when creating audio components.

Fixed unexpected Actor lifecycle behavior due to Sound Library holding strong references.

Generator nodes in MetaSounds will no longer behave incorrectly when given negative frequencies.

Fixed a frequency modulation issue in MetaSounds that would result in frequencies going above the Nyquist frequency.

Fixed an issue where the submix buffer listener would erroneously receive audio with sibling submix audio mixed in.

Fixed an overflow warning in the Soundscape system.

Changes made to virtualized MetaSound parameters from Blueprints or C++ will now be respected.

Fixed an incorrect calculation of real values of spectrum in AudioFFT.

Fixed an issue where setting the Wet/Dry value on the Compressor MetaSound node would introduce phasing.

Mixed values will now be properly passed in the associated parameter's units when using the Normalized Boolean option on a MetaSound Modulator Mix node.

Importing a 16-bit .wav file will no longer send a warning to the output log.

Fixed an issue where a Modulation Parameter's unit would not display correctly when used in a Control Bus Mix.

Undo and redo actions will now function properly when adding and removing MetaSound interfaces.

Fixed streaming seek failures in LPCM decoder.

Fixed a bug where MetaSounds did not properly virtualize if the WaveInstance's Volume Modifier value is set to 0.

Fixed a bug where putting large values in the Bitcrusher MetaSound Node's Bit Depth value would occasionally produce unexpected distortion.

Sample count in the Bink decoder is now properly updated when seeking.

Correctly modulating a parameter on a SoundWave or MetaSound will no longer display a mismatch warning.

The Parameter and Destination mismatch warnings now display all mismatches on the SoundWave or MetaSound.

The MetaSound Editor meter values and channel count now display correctly for mono MetaSound Sources.

Fixed an issue where MetaSound input nodes would create unexpected connections when renaming.

Fixed an issue where using multiple submix spectral analysis delegates would produce incorrect output values.

Fixed an issue where MetaSound nodes contained within comment nodes could produce unintended movement.

MetaSound assets with non-spherical attenuation will now virtualize properly.

SoundWave asset thumbnails will no longer disappear when dragging and dropping.

Fixed an issue where enabling the base submix toggle would not affect previewed MetaSounds.

Fixed an off-by-one error causing looping SoundWaves within MetaSounds.

Deprecated:

The MatchDevice option for Sound Wave Sample Rate Quality has been deprecated.

New:

Minor QoL improvements for Blueprint stack traces.

Warnings will always display the name of the function that tripped the warning.

Complete stack traces have an additional <--- to highlight the top of the stack.

Full paths are used, which helps track down the package that has the Blueprint.

Exposed UCurveBase class to Blueprint.

Move Blueprint extensions to private and exposed getters and setters.

Crash Fix:

Fixed crash in the script disassembler.

Fixed CompileAllBlueprints from crashing on a Blueprint function that contained a delegate input.

Bug Fix:

Tooltips for floats were not the same in the My Blueprint window for floats, the display should now include either a single-precision or double-precision next to the float type.

Event Dispatcher Inputs will now inform and warn the end-user when there is an existing matching input name.

Fixed a missing warning when macro pins have a name conflict.

Updated code comment on FScriptMapHelper and FScriptSetHelper FindInternalIndex functions. The API will now redirect potential callers to the more efficient method for iteration.

Exposed on spawn properties which use a BlueprintSetter if available.

Fixed Loss of precision with String to Float Real conversion.

Fixed a regression which caused the root transform to be discarded on a serialized Actor-based Blueprint's instanced component hierarchy after inserting a new root component into its native parent class.

Fixed FAssetData from reporting that a UBlueprintGeneratedClass is a UBlueprint which was causing the wrong ActorFactory to be selected.

The tooltip for float map values in Blueprint Structures will now show precision Similar to GetToolTipForComboBoxType and GetToolTipForComboBoxSecondaryType.This ensures that we can see the precision of the float type when it's a map value.

Fixed an Infinite Loop that was caused from Macros setup not being detected.

Fixed a regression that could block property value serialization of import text from creating a placeholder linker object in lieu of a deferred Blueprint class asset at editor load time.

Fixed a legacy pin default value mismatch warning check on node reconstruction to handle string diffs that convert to identical values.

Blueprint Class Default Object package export creation is now deferred on load so placeholder dependencies can be resolved prior to invoking the native base class Actor. This allows for proper component type override support at the Blueprint editor level.

Fixed a CIS Content Error where unhandled implicit casts were found during compilation of a function. The BP compiler had erroneously reported that python nodes might be missing implicit casts.

Delegate fixup was not working when bound functions are not in the current Blueprint. A consequence of using doubles in Blueprints is that delegate binding can fail if a native delegate signature uses floats. The proxy function graph will now read this property when it calls the original function.

Vector literal pins had lacked precision with high values Similar to other numerical Slate widgets. SGraphPinVector now has a template so that it can choose between a float and double representation. Currently, only the BP editor will use the double variant, while other tools continue to use a float.

SGraphPinVector2D and SGraphPinVector4 have been updated to use a template.

Fixed FBasicTokenParser::GetToken function to support double literals.

Added support for resolving weak references to placeholder linker objects created in deferred Blueprint object serialization paths on editor load.

Deprecated:

Deprecate Make Literal Double node Instead of having two float-related literal nodes, we should only have one.

Deprecated ClassNames and RecursiveClassesExclusionSet pins on make and break nodes for the native ARFilter struct type.

Deprecated UBlueprint::bHasAnyNonReducibleFunction.

Removed:

Removed engine plugin test assets that were no longer in use.

Crash Fix:

Fixed a crash when adding or removing variables from a Blueprint that inherits from another Blueprint.

Fixed a Blueprint compiler crash that occured after deleting a default instanced subobject element from a set or map variable.

Removed a redundant second-stage compilation pass after duplicating a Blueprint with a missing or invalid parent class, which could lead to a crash in certain scenarios.

Serializable data is now purged before consigning child function objects to the trash container during Blueprint class compilation. This avoids crashes related to serializing object references after they may have been freed.

Fixed a Blueprint compiler crash that occurred when struct type dependencies were missing

Bug Fix:

Delegate bindings are now fixed after renaming a custom event node without requiring a full Blueprint compilation pass.

Fixed the Blueprint compiler to generate a well-formed bytecode expression for a struct literal term when the struct type declares one or more fields of a type that does not have Blueprint support.

Fixed regression when reinstancing Blueprints that have complicated child object graphs.

Updated cache dependent lists prior to reloading and/or unloading a Blueprint's outer package.

No longer attempt to re-instance artifacts from a previous re-instancing pass when reloading a Blueprint asset.

Inherited component template overrides are now being included in Blueprint data validation.

Removed:

Removed the Blueprint editor project setting: "Force All Dependencies to Recompile". The command BP.bForceAllDependenciesToRecompile 1 can be used at the console for debugging if still needed.

New:

Added a Break This Link command to graph editor, which is displayed instead of the Break Link submenu when there's only one link to display.

Exposed enum EAssetEditorOpenLocation to Blueprint

Blueprint namespace editor features are now enabled by default.

Blueprint graph pin value inspection tooltips are now expandable by default when debugging in PIE.

Reportedadditional context to the log without crashing the editor.

Crash Fix:

Fixed the source of a potential editor crash during Blueprint namespace harvesting.

Fixed a regression that led to an editor crash when right-clicking a Blueprint delegate variable without an active function graph tab.

Fixed an editor crash that would occur when replacing one or more references to a conflicting variable name after reparenting a Blueprint class.

Fixed a crash that occured when undoing an Add Event operation in the Blueprint Editor.

Bug Fix:

Enabled external DLL linkage for SFindInBlueprints (and related) Blueprint editor APIs.

Unloaded type assets are now included in the member type selector in the User-Defined Structure asset editor.

Blueprint-added component names are now validated on entry to conform to UObject naming conventions.

We now defer re-running construction scripts until after we fix up the template hierarchy when duplicating a component in the Blueprint editor.

Removed some unnecessary computations in FEdGraphPinReference::GetTypeHash.

Excluded override flag members from the optional input pin set on MakeStruct nodes. An "override flag" is an inline toggle-style Boolean edit condition.

Inline toggle edit conditions can no longer be exposed directly as an input on a MakeStruct node. This brings the MakeStruct node UX closer to parity with the Property Editor UX.

Composite nodes can no longer be pasted into Blueprint graphs that aren't schema-compatible with the node's subgraph.

Fixed a regression that could trigger an ensure when editing inherited variable default values in the Blueprint editor.

Fixed a regression that caused subobjects instanced from non-native archetypes to fail export creation, which led to some data loss on load.

Added guard code to catch invalid Blueprint node spawner references during Garbage Collection.

Bug Fix:

A stub function is now emitted if the Blueprint compiler backend raises an error during translation of compiled script statements to bytecode. This avoids a potential ICE report at runtime.

Blueprint execution will now bypass development-only nodes in a Blueprint function graph when a project is configured to compile them out at cook time.

Fixed latent call site targets in a compiled Blueprint ubergraph to avoid re-entry when the latent info term is declared as the first argument in the native API signature.

API Change:

Now Ability Tasks should make sure to call Super::OnDestroy only after they do anything needed to the Ability pointer, as it will be nulled out after calling it.

New:

Added support for Gameplay Effects to add blocked ability tags.

Exposed APlayerState::IsSpectator to Blueprints.

Added console variable for Blueprint Action Filter Caching. (set BP.EnableActionMenuFilterCaching to true to speed up right click menu in Blueprint graphs)

Converted FGameplayAbilitySpec/Def::SourceObject to be a weak reference.

Made a Ability System Component reference in the Ability Task a weak pointer so Garbage Collection can delete it.

Added WaitGameplayTagQuery nodes. One ia based off of the UAbilityTask and the other is of UAbilityAsync. This node specifies a TagQuery, and will trigger it's output pin when the query becomes true or false, based on configuration.

Added a templated version of the GetCharacterMovement function.

Added color coordinated outlines to changed nodes/pins in the Blueprint diff window to reflect their diff state.

Added virtual method to controllers to control if they participate in seamless travel.

Modified AbilityTask debugging in Console Variables to enable debug recording and printing to log by default in non-shipping builds (with ability to hotfix on/off as needed).

You can now set AbilitySystem.AbilityTask.Debug.RecordingEnabled to 0 to disable, 1 to enable in non-shipping builds, and 2 to enable all builds (including shipping).

You can use AbilitySystem.AbilityTask.Debug.AbilityTaskDebugPrintTopNResults to only print the top N results in log (to avoid log spam).

STAT_AbilityTaskDebugRecording can be used to test perf impact from these on-by-default debugging changes.

Added the ability to override the list of default Blueprint categories. These can be configured in the Blueprint Editor settings.

Exposed functions for fetching a scalar material parameter index and then setting the parameters by index to Blueprint in order to optimize cases with extreme amounts of material parameters where many are set each frame.

Made UDataAsset types diffable in editor rather than from text.

Removed redundant enum EWaitGameplayTagQueryAsyncTriggerCondition.

Removed AActor::DetachFence reducing size of AActor by 16 bytes. It's not necessary to prevent the Actor from being deleted before the component finishes its destruction. In Garbage Collection all objects must complete FinishDestroy before any objects can be freed, and UPrimitiveComponent's fence will ensure both objects live long enough.

Added a new Initialization State System to the Game Framework Component Manager. This system allows individual components to register with a global subsystem for handling initialization state changes for an Actor without requiring that the Actor knows about all possible components.

Components can broadcast their state during initialization and other components can listen for callbacks on state changes. This is designed to be used with Game Feature Plugins to build game-specific initialization flows that work properly in multiplayer situations.

Fixed typos with type name, FMinimapReplicationTagCountMap to match the type name FMinimalReplicationTagCountMap.

Added a new PreLevelRemovedFromWorld callback for cases where the handler needs to act on the level while it still has its OwningWorld.

Added support for preloading data registries and sources in the editor when a game feature is registered instead of waiting for full activation. This will show the valid keys in the picker UI but can result in missing errors for invalid accesses in PIE. This is currently opt-in with PreloadInEditor on the game feature action.

Updated the SignificanceManager which maintains lists of objects to update rather than rebuilding each frame. Previously we would build up the lists of objects to update, and the list of objects requring sequential post work each frame. We now update these lists in Register/Unregister to keep them in sync with ManagedObjects.

GameplayTasksComponent and AbilitySystemComponent now support the registered subobject API

Moved some replicated members to private access. Derived classes should use the Get/Set functions instead. By default these components keep replicating their subobjects from the ReplicateSubObjects function.

Added support for removing plugin-added gameplay tags when a gameplay feature is unregistered. With default settings this will only happen in the editor as removing tags at runtime is much riskier.

Added the Blueprint Header View plugin, a new tool to assist developers in converting Blueprints to C++.

Create the Platform Input Device Mapper. This provides an interface that platforms can use to create a map of Input Devices to their owning PlatformUser. This will allow for granular control of how many input devices are mapped to a single user, which some platforms want to do differently than others.

The API can be used to query what devices are mapped to which user, so that you can easily determine which controller should recieve a force feedback event, or which user has pushed a certain button.

Created the FInputDeviceID struct, which represents a single input device such as a gamepad, keyboard, or mouse. These are globally unique, and allocated by the Platform Input Device Mapper. This struct will replace the old "int32 ControllerID" that is used in various places to provide some type safety and maintainability.

Added Functions to query all the currently connected devices on a given platform, as well as get their current state and owning platform users. These can be exposed to Blueprints from the local player, game instance, or a subsystem in the future.

New delegates for the ConnectionChange and PairingChange of a gamepad device that utilize the new FInputDeviceId and FPlatformUserId.

Added functions to the GenericApplicationMessageHandler for the "OnController_X" functions.

Added visibility for local function variables inside the Blueprint diff tool.

Added debug recording of camera shakes.

Added a debug command to filter GameplayCue events.

Fixed Typo and format in K2Node_IfThenElse.

Added a showdebug Devices command that will display debug info about all current platform users and their connected input devices. This will display some basic information on the screen that will be useful while testing on different platforms.

Added an Input Setting to toggle motion controls. This can be useful if you want to enable/disable any logic inside of UPlayerInput::InputMotion. Adding this setting in the Input Settings will make it a config variable that you can simply set per-platform from the DefaultInput.ini, which will be useful when shipping on multiple platforms.

Added this flag on the player controller so that you can enable or disable motion controls per player if desired.

Added a boolean bShouldFireDelegatesInEditor property to the Enhanced Input Component. This will make sure that only Input Components that have the flag specifically set when they are created will fire in-editor delegates with an Editor Script Guard. This ensures that no game-only input actions will be fired as editor delegates while keeping the implementation details hidden from the editor users.

Added Register and unregister camera stand-in property accessors on module load and unload.

Added GameplayStatics functions for getting the player's platform user id instead of the older int32 controllerID.

Added a ShouldFlushKeysWhenViewportFocusChanges function to the player controller, which allows the GameViewportClient to check if the PlayerController keys need to be flushed when the viewport changes depending on the Input Mode you are in.

Blueprint Debugger's search field will now search for actual variable names as well as display names

Renamed UMatineeCameraShake to ULegacyCameraShake.

Added ability to check if a UInputComponent is in an APlayerController's input stack.

Added Override properties for the Player Input and Input Component classes on the Pawn and Player controller. This will give you the capability to override the input classes at the Blueprint level so that you don't need native C++ to override it.

Created accessors on the Enhanced Player input for the currently applied mapping contexts and mappings. These functions will make it easier for users to extend this class, while still keeping the AppliedInputContext and EnhancedActionMappings properties const and non-mutable.

Added the Enhanced Input Editor Subsystem. The Enhanced Input Editor subsystem will allow you to bind to Input Delegates in Editor Utility Actors or other Editor-time objects. The input is driven by an InputProcessor, and this subsystem will only incur any cost to the user if they manually enable it.

Added an input component to the Editor Utility Actor so that you can bind to enhanced input and other runtime input delegates in editor utilities outside of PIE. This will make it easier for virtual production teams to bind input of physical camera equipment to Actors in the level. Listening to input is opt-in per utility, and would currently only be triggered if you create an associated Input Action that is available to the Editor.

Made the TickForcedInput function protected on the EnhancedInputSubsystemInterface. Without this, the only place that you can tick the input on the Enhanced Input subsystem would be from the Enhanced Input module itself.

Added Degree ATan and Degree ATan2 to the k2node_mathexpression, as well as DegreeToRadian and RadianToDegree functions.

Added UTimelineComponent::GetScaledTimelineLength function, which returns the timeline's length divided by the play rate.

Changed the default behavior for variable name collisions with a native parent class, Blueprint variables will now be removed and all references in Blueprints will point at the native variable.

Added Enhanced Input developer and Platform settings which will allow you to specify per-platform input data. Created a "UEnhancedInputPlatformData" base class that can be subclassed in a Blueprint and placed on specific platforms. By default, this object has a map of Input Contexts that will "redirect" one context to another. This makes it possible to swap out Input Mapping Contexts on specific platforms, with an asset that will simply be added to the input ini of the game.

Added Gameplay cameras world subsystem for an easier way to start and stop animations.

Added a flag for flushing input when you change the UI mode on a player controller. This will ensure that any input actions get properly canceled and have their key state reset if desired.

Added new debug commandsAbilitySystem.DebugAbilityTags, AbilitySystem.DebugBlockedTags, andAbilitySystem.DebugAttribute to the Gameplay Ability System.

Automatically upgrade projects with the default input class to use Enhanced Input when the project starts. Enhanced Input is fully backwards compatible and users that were previously using the DefaultInput classes will not see any behavioral change. By default this behavior is on, but it can be turned off with the console variable EnhancedInput.bEnableAutoUpgrade.

Added a function to allow you to get the mapping context priority from the Enhanced Input subsystem.

Added a Scale by delta time input modifier. This can be useful if you wanted to have your look input implemented, then you don't need to add an additional deltatime call in your input code every time.

Added a ControlMappingsRebuiltDelegate delegate to the Enhanced Input local player subsystem. This allows you to listen for changes to control mappings or bindings for the UI and rebuild them.

Added support for input pins with multiple connections to the PinValueInspection tooltip.

Allow Debugging of Transient Blueprint object instances.

Added functions on the game instance and local player to create players based on a platform user id instead of the older int32 controllerId.

Fixed the Enum to String Node to not display as a compact node, which was making it look different from a Byte to String for clarity.

Added a menu bar to Blueprint Debugger for opening closed tabs.

Added better logging to indicate why Gameplay Abilities failed to be activated.

Added a project setting to suppress deprecation warnings for specific properties or functions in Blueprints.

Added helper methods in the engine to get the local player from a FInputDeviceId.

Added an FText action description to UInputAction.

Changed the category of the Input Mapping Context description field to be consistent with the input action's.

Created a new UnmapAllKeysFromAction function to be more explicit.

Added a Blueprint function to get a debug string representation of a Gameplay Attribute.

Allow calls to CreateChildActor to supply a function to manipulate properties before the construction script is run.

Extended Enhanced Input with a combo Input Trigger. This allows users to trigger an Input Action through the completion of a series of Input Actions that are specified by the user. Users can specify times to complete Input Actions and Input Actions that cancel/stop the combo.

Added support for dragging variables onto pins to automatically convert/promote them.

Added a new Gameplay Task resource overlap policy to cancel existing tasks.

Fixed a comment in the Gamemode class when ending the match.

Made action mappings within an input mapping context reorderable in Enhanced Input.

Added new ObjectIsA method that is Blueprint pure.

Improvement:

Optimized padding in AActor to reduce size from 664 bytes to 640.

Improved diff messages for local function variables inside the Blueprint diff tool.

Optimized sequencer camera animations by excluding unnecessary systems from the linker, and by using a much simpler bound object instantiator.

Refactored component instance data cache to be able to store actor or component instance data

Crash Fix:

Fixed a crash that occurred when opening a collapsed node after undoing the creation of a second execution pin.

Fixed a crash that occurs when splitting then recombining connected pins.

Fixed a potential crash in FBluepirntEditorUtils::FindAndSetDebuggableBlueprintInstances.

Fixed a crash when expanding Set Properties in the Blueprint Debugger.

Bug Fix:

Fixed issue where replicated loose gameplay tags were not replicating to the owner.

Fixed AbilityTask bug where abilities could be blocked from timely garbage-collection.

Fixed inconsistencies in the Blueprint diff tool where graphs wouldn't move together when you click a diff entry.

Fixed a bug where hovering over variables in the Blueprint diff tool caused them to jump around

Fixed a bug where the Add components list search didn't compare non-beautified component names.

Fixed an issue when a gameplay ability listening to activate based on a tag would fail to be activated. This would happen if there were more than one Gameplay Ability listening to this tag, and the first one in the list was invalid or didn't have authority to activate.

Destroyed the smart object collection Actor rather than using MarkAsGarbage so the level doesn't keep a garbage reference to it.

Variables marked EditInstanceOnly inside UStruct variables are no longer visible in the Blueprint details view.

Fixed a bug where changing a variable type inside of a Blueprint Structure caused a cannot parse value error.

Fixed bug where characters were repeatedly enter falling mode during lateral root motion due to gravity being inverted.

Members of structs in instanced objects in components are now correctly displayed.

Added an option to the game feature plugin creation template to allow setting EnableByDefault and properly show that in the plugin UI. This is used in Lyra to create default enabled game feature plugins.

Fixed a warning about the simulate options of the character's arrow component not being valid.

Fixed an issue where Blueprint callable functions on native interfaces were incorrectly detected as invalid.

Changed Game Feature plugins to load the DefaultPluginName.ini using the same method as normal plugins so it works on arrays. The old code to load PluginName.ini still runs with a log message.

Moved some Gameplay plugins with Blueprint hooks to initialize in PreDefault so they are ready for early Blueprint loads referenced by native code.

Changed the Common UI game viewport to check the override delegate before letting the UI block input.

Fixed a memory leak that occured when composite data tables have sources with conflicting rows.

Fixed editor UI when adding the first game feature plugin to a project, validation would always fail if Plugins/GameFeatures didn't already exist.

Fixed GameplayEffects that use Data Registries correctly from warning on load and improved the warning text.

Removed code from UGameplayAbility that was incorrectly only registering the last instanced ability with the Blueprint debugger for breakpoints.

Fixed NetworkPredictionCVars cmd description mismatch so that the commands match up with their proper functions.

Fixed a bug where UAnimDataModel would cause the debugger to hang while generating debug info.

Stop and discard camera shakes that are getting recompiled while they're in the previewer tool.

Only create a new default subobject when destroying a component if the owner's class is not native. Native owner classes do not have to have a DefaultSceneRoot when you drag in the C++ class directly from the content browser into the level.

Fixed BindAction function from not accepting additional function parameters.

Added a default console key for Hungarian keyboard layout.

Changed FCachedKeyToActionInfo::PlayerInput pointer to a WeakObjectPtr. In order to be Garbage Collected on level transitions.

Added a null check on the PlayerInput in OnInputOwnerEndPlayed because it is a weak pointer and not guaranteed to be there.

Do not allow pass by reference to be changed for array properties as they are implicitly always pass by reference.

Align Client names in Blueprint Debugger with PIE window titles.

Created camera shake instances using the world. The parent sequence is running in. This fixes missing context for camera animation sequences inside camera shakes.

Fixed SetupAttachment false positive ensure that occured when called on a component that already had an AttachParent.

Added a special case to FKismetDebugUtilities::FindClassPropertyForPin for reroute nodes.

Fixed Gameplay Ability System Ability getting stuck if EndAbility was called during the lock inside ApplyGameplayEffectSpecToTarget.

Fixed BP Debugger Step Over not behaving correctly with Sequence nodes with a branch as the end of the exec line.

Fixed a bug where delegate pins in LatentGameplayTaskCall nodes were not correctly compiled with delegates from super classes.

Fixed a bug where Debugging mode was not ended if the PIE Window was closed.

Fixed a jump resimulation issue that occured on the character movement component.

Input Action instance data that is flagged to trigger with StartedAndTriggered will now ensure that the Started delegate will always get called before the Triggered delegate.

Fixed sequence camera shakes not being torn-down correctly in some situations.

Fixed a bug where MultiLine metadata was applied to all new Blueprint variables.

Prevented abstract classes from being used by create object from class nodes

Fixed a bug where Step Over would sometimes break inside the function you're trying to step over.

Fixed a bug where the Blueprint Debugger would not find debuggable objects in a WorldPartition sublevel.

Fixed incorrect documentation of the FNodeHandlingFunctor function.

Fixed camera manager's BlendParams keeping outdated information.

Changed Make and Break nodes for the FInputActionValue struct in Blueprints to correctly take in a EInputActionValueType enum instead of the incorrect FInputActionValue struct.

Call the correct "OnController" function from the SVirtualJoystick. Before it was only calling OnControllerAnalog, which will result in normal FKey's never having their "Released" input be triggered. This fix calls OnControllerButtonPressed and OnControllerButtonReleased for non-analog keys, which will give the correct behavior.

Fixed the wrong serial on the first camera animation handle.

Fixed character movement data that could be left with dangling UObject references.

Fixed a bug in Network Prediction Examples plugin where locally-predicted Actors could exhibit stuttering motion.

Fixed deprecated Event Dispatchers on components that do not throw a warning on their attached Actors.

Fixed a bug that could allow stale Root Motion Source objects to stay in memory indefinitely.

Fixed issue where player pawns would not be spawned from the function RestartPlayerAtTransform.

Fixed a bug that prevented Network Prediction Insights tool from showing trace data samples.

Clamp the local pixel mouse position to the range of an int32 to prevent invalid casting bounds.

Fix to allow users to coerce a BlueprintImplementableEvent with no return value to treat the override as a function rather than an event.

Fixed a bug where the jump apex height could vary if root motion was active while a character jumped.

Fixed an ensure in FPreviewScene when using a GameMode that derives directly from AGameModeBase.

Fixing issue where private functions could be overridden in the "My Blueprint" tab.

Collision visibility option in the Blueprint editor.

ChildActorComponent now registers to the ChildActor's OnDestroy event. This allows the component to clean up its references if the ChildActor is destroyed through a path that doesn't involve the component itself.

The Blueprint callstack will now be dumped when the MostRecentPropertyAddress is null.

Fixed empty Actors having a root component with an Edit in Blueprint hyperlink.

Fixed issue where Enhanced Input Action node trigger events were incorrectly flagged as unsupported.

Updated icons for Enhanced Input assets so they display correctly.

Made ClearActionBindings and ClearBindingsForObject virtual on the UInputComponent and overrode the UEnhancedInputComponent to ensure the additional Enhanced action bindings are cleared. Previously calling ClearActionBindings on an EnhancedInputComponent would still leave some bindings uncleared.

Deprecated:

Demoted BlueprintSnapNodes plugin to Experimental.

Deprecated the IsPrimaryPlayer function on the APlayerState. This function always returned "True" incorrectly. Instead of using this function on the player state, you can use the Player Controller or ULocalPlayer's Platform User ID and check if that is the platform's primary user in the IPlatformInputDeviceMapper.

Deprecated UInputMappingContext::UnmapAction.

Deprecate the core delegates for OnControllerConnectionChange and OnControllerPairingChange in favor of the new IPlatformInputDeviceMapper versions that will allow you to get info about what gamepad specifically has sent input events.

Update SlateApplication and the message handler to take in FInputDeviceId and FPlatformId instead of the old int32 controllerid for controller input.

Deprecated the old version InputKey on the base UnrealClient. All Input functions on the client have been upgraded to take in a FPlatformUserId and FInputDeviceId in favor of a single int32 ControllerId.

Deprecated the GetPawnPhysicsVolume query in favor of new GetPhysicsVolume query that can be called on any Actor.

Made rerun construction scripts editor only.

Moved UCSModifiedProperties into sparse storage as only a small percentage of all components stored data in it.

Removed:

Removed the UEnhancedInputEngineSubsystem. This will be replaced in favor of a World subsystem after the player input has been separated from the player controller.

Removed "Within=PlayerController" on the Enhanced Player Input. This allows you to spawn a new player input without an owning player controller, such as with the editor input subsystem.

Removed AbilitySystem.Debug.NextTarget and PrevTarget commands in favor of global HUD NextDebugTarget and PrevDebugTarget commands.

Deprecated 5.0 functions from Enhanced Input. Enhanced Input was experimental when these functions were deprecated.

Old version of AddMappingContext.

Old version of RemoveMappingContext.

Old version of RequestRebuildControlMappings.

Removed float result components and the float blender system. Implemented double precision and handled float to double conversion during property instantiation.

The Default value to the name of the action with the common "IA_" prefix and replaced underscores with white spaces.

Removed MultiLine metadata tag instead of setting it to false in Blueprint variable details customization.

Unused local variables in Blueprint graph nodes.

API Change:

MASS_DO_PARALLEL is now enable for all non-UE_SERVER builds.

All the FMassEntityQuery hosted as properties by processors need to be registered at construction time.

New:

Made Mass's multithreading enabled by default.

Introduced a MassDebugger UI tool. The tool contains information on:

All registered Processors.

At runtime shows all Archetypes present at the time of data gathering (which can be manually instigated).

Archetypes display their composition

Comparisson between archetype compositions is supported.

Summary information is displayed when multiple archetypes are selected including total number of entities and memory allocated.

Mass Processing Phases' processing graphs along with dependency information

The views are synchronized meaning clicking an archetype or a processor in one view will reflect in other views marking relevant elements.

Marked a number of Mass or Mass-used systems as save to be accessed off-game-thread. Also added a dedicated traits template for shared fragments.

Added a TSharedPtr<FMassEntityManager> member to MassExecutionContext. This change has long been coming, we always use given execution context with only a single entity manager instance, and the lack of connection between context and the manager required some use cases to cache the manager.

Mass's original procedural Farm Test has been brought back and can be found in MassEntityTestSuite module.

Modified FMassArchetypeSubChunks to support archetype-less entities (i.e. built but not created).

Enriched MassEntityQuery with capability to declare USubsystem requirements, that then can be fetched at runtime via the MassExecutionContext. MassEntityQuery requirements are declared just like other requirements with a dedicated AddSystemRequirement call. MassExecutionContext supplies functions for fetching subsystem instances checking if active query declared them as dependency in a given mode (ReadOnly or ReadWrite).

Added another flavor of FMassEntityManager::GetOrCreateConstSharedFragment that makes for more consistent hash calculation (the function itself is calculating it).

Exposed parts of MassEntityTestSuite for reuse in other test-focused plugins.

Mass's gameplay debugger category now displays fragment composition of a selected entity.

Added mass.LogKnownFragments console command that prints out all "known" tags and fragments.

Added API functions to batch-change entity collection's tags.

Separated "entity management" and USubsystem elements of UMassEntitySubsystem. Now UMassEntitySubsystem hosts a shared ref of newly created FMassEntityManager type, and users are free to create their own FMassEntityManager instances to create isolated entity pools.

Added a way to mark up MassEntityQueries as owned by a processor and auto-registering such queries. Also added some verification code that ensures all queries run as part of processors are properly marked up as such. This change supports automated, resource-based processor dependencies.

Switched UMassEntitySubsystem.FlushedCommandBufferQueue from TQueue<T, EQueueMode::Mpsc> to more efficient TMpscQueue<T>.

Resource-based Mass processor dependency solving resulting in finer-grain dependencies resolution. The main change is that if a processor P in group A depends on a processor R in group B we no longer infer group A depending on group B (which was the case previously). In fact, groups are no longer represented outside of dependency solving step - once dependencies are solved we end up with a list of processors ordered in a way respecting both declared "execute after" and "execute before" dependencies but also dependencies resulting from requirements declared by Processors' queries.

Added debug name to Mass archetypes.

Made Mass gameplay debugger category's use of UMassDebuggerSubsystem optional and instead require UMassEntitySubsystem.

Changed how we treat missing dependencies in Mass dependency solving - used to be an error, now we create dummy temporary nodes to maintain before-after dependencies even if used in reference to a non-existing item.

Cut UMassDebuggerSubsystem's capability to host entity handles to be debugged and replaced the only use case (in Mass gameplay debugger category) with a custom query to fetch location-owning entities. The old approach had the downside of allowing to pick only entities that had a special debug fragment in their composition, which resulted in confusion while trying to pick entities.

Added MassProcessor.ProcessorRequirements to track subsystems (and potentially other elements) accessed by a given processor outside of MassEntityQuery.ForEachEntityChunk.

Added support for declaring subsystem requirements to MassEntityQuery and fetching subsystem instances from MassExecutionContext using TSubclassOf.

Bug Fix:

Made UMassSignalProcessorBase::OnSignalReceived thread safe.

Made MassEntityQuery.ForEachEntityChunk's path for entity collections utilize stored requirements mapping if given archetype is "known" by the query (i.e. its one of the cached archetypes). This is the most common case and reusing mapping save nontrivial of work.

Deprecated:

Renamed GET_MASS_CONFIG_VALUE macro in MassSimulationSettings to GET_MASSSIMULATION_CONFIG_VALUE to avoid confusion with the MassEntitySettings' one

Renamed FMassCommandAddFragment and FMassCommandRemoveFragment to FMassCommandAddFragments and FMassCommandRemoveFragments respectively.

Mass batching-focused API changes. "Old" mass commands completely removed and reimplemented as batched commands using the new batched API. Other renamed types:

FMassArchetypeSubChunks to FMassArchetypeEntityCollection

FSubChunkInfo to FArchetypeEntityRange

FArchetypeChunkCollectionWithPayload to FMassArchetypeEntityCollectionWithPayload

Extracted MassExecutionContext into a separate header/cpp files.

"System" and "Subsystem" names' use has been made consistent across Mass's code, favoring "Subsystem". A number of function and parameter names has been affected.

UE::MassEntity namespace has been renamed to UE::Mass, for consistency with overall Mass namespace naming.

Renamed MassProcessingPhase.h/cpp files to MassProcessingPhaseManager.h/cpp

MassSchematic and MassSimulationLocalCoordinator have been removed due to no longer being used.

Removed UMassLODProcessorBase due to it not serving an actual purpose.

Got rid of DECLARE_ENUM_TO_STRING-declared EnumToString functions declared for Mass enums. Use UEnum::GetValueAsString instead.

Constified FMassReplicationContext's LOD subsystem access

Cut FMassEntityQuery::ParallelForEachEntityChunk as defunct and no loner being used. We consider bringing it back, but it will be a brand new reimplementation to match current subsystem requirements accessing model.

Switched MassEntity from supporting interaction with USystems over to UWorldSubsystems. The main reason for the change is to avoid non-UWorldSubsystems special cases we don't utilize nor test at this time. The change is reversible once we have a non-UWorldSubsystem use case.

Introduced a FMassDebugger struct to host all debug-time API and avoid polluting other Mass classes with those. Existing debug-time functions will be moved over with time.

Renamed FMassExternalSubystemBitSet to FMassExternalSubsystemBitSet

New:

Updated to openssl-1.1.1n on all platforms. The Mac version contains arm64 support.

Enabled explicit base names when creating graph nodes in ReplicationGraph. This can improve readability when using logging and debug cmds like RepGraph.PrintGraph.

Added -forkautostatsport command-line option that automatically sets a unique port for each forked child with PerfCounters. Ports used will start at statsPort+1.

Setting net.AllowPIESeamlessTravel 1 will now enable experimental support for seamless travel in Play in Editor networking.

Added cheat to validate the old and new methods of replicating subobjects. Enabled via net.SubObjects.CompareWithLegacy. The comparison is run only for actors that converted to the new list. This calls the ReplicateSubObject virtual so the method still needs to be implemented for the validation to work.

Actor classes can officially control which of their ActorComponent get replicated or not.

Classes that want to control component replication need to override AllowActorComponentToReplicate to do so.

Classes can also return a ELifetimeCondition in the new function and set a net condition to specific components.

The override and net condition only work for classes that set bReplicateUsingRegisteredSubObjectList to true.

Added option to manually control untracked class reporting in ReplicationGraph.

Added optional config that will prevent Actors from replicating if they are not in the BeginPlay state.

Enabled via the net.ReplicateOnlyBeginPlay console variable.

The only exception is if a RPC is called on an actor before BeginPlay and opens the ActorChannel. This is because when opening the channel to send the RPC, we need to serialize the actor entirely for the client channel opening. If the actor has not begun play yet we will set up their components for replication and serialize them anyway. Note that sending RPCs this early is not recommended if the BeginPlay on the authority sets replicated variables that the client needs in his BeginPlay also.

Implemented optional support for assigning a TransactionId for LevelStatusUpdate and ServerUpdateLevelVisibility requests. This is used in multiplayer to allow servers to rely on level visibility status reported by clients to know what data to replicate to clients. Behavior is controlled by two CVars (by default, both are disabled):

LevelStreaming.ShouldClientUseMakingInvisibleTransactionRequest — if enabled client will send a request to server and wait for an ack before making a streaming level invisible.

LevelStreaming.ShouldServerUseMakingVisibleTransactionRequest — If enabled server will associate a transaction id to each call to ClientUpdateLevelStreamingStatus and wait for the response from the client of that particular request before updating LevelVisibility for replicated data. This is to solve some issues where we might have multiple requests in flight.

Added ActorComponent::ReadyForReplication virtual function to ActorComponent initialization flow.

This function will be called between InitComponent but before the component's BeginPlay.

It can be used to register pre-existing replicated subobjects or set up replicated properties early.

This is useful in situations where a component might call an RPC on itself very early inside BeginPlay and trigger the first replication of all its network properties.

Added a console variable that controls if actors and actor component classes use the new subobject replication by default or not.

net.SubObjects.DefaultUseSubObjectReplicationList needs to be enabled to opt-in to the new method by default.

Classes can still choose their own method by setting bReplicateUsingRegisteredSubObjectList in their constructor.

Added multiple console variables to control how much time is spent on each step of the replay recording process per frame.

demo.ForcePersistentLevelPriority: always record the persistent level first when using level streaming fixes and prioritization

demo.DestructionInfoPriority: allow destruction info be to prioritized lower than max int32

demo.LateDestructionInfoPrioritize: prioritize destruction info after the active actor set

demo.ViewTargetPriorityScale: scale view target replay priority

Demo.MaxDesiredRecordTimeMS: update MaxDesiredRecordTimeMS on the current world's demo driver

Demo.CheckpointSaveMaxMSPerFrame: update CheckpointSaveMaxMSPerFrame on the current world's demo driver

Demo.ActorPrioritizationEnabled: update ActorPrioritizationEnabled on the current world's demo driver

Demo.SetLocalViewerOverride: update SetLocalViewerOverride on the current world's demo driver

demo.MaximumRecDestructionInfoTime: cap the percent of a budgeted frame that can be spent replication destruction info

Added additional recording metadata to replay headers:

CheckpointLimitInMS

FrameLimitInMS

MinRecordHz

MaxRecordHz

Platform

BuildConfig

BuildTarget

Added -skipreplayrollback to not generate startup actor rollback state.

Added network granular memory tracking to multiple replay data structures.

Added networking granular memory tracking to multiple data structures.

Provided a delegate for game code to listen to for Replay ID updates.

Added support for using poll instead of select in BSD sockets. Sockets will use poll by default (if supported by the platform), but this can be toggled with the USE_SOCKET_FEATURE_POLL macro.

Added configurable limits for replay event sizes when loading save game replays.

Added configurable limits for the maximum number of network exports to read from a replay file during playback.

Added net.AllowPIESeamlessTravel to control seamless travel in single process PIE.

Added random data to handshake packets in an attempt to work around potential ISP packet-filtering issues.

Exceeding the maximum allowed replication size for an object now generates an ensure for improved visibility.

Make servers send close-reasons/NMT_CloseReason to client, for log-info/debugging.

Added more NetDriver/Beacon close reason coverage.

Added logging to help debug amortized replay replication times.

Added an API to retrieve the changelist a replay was recorded on while playing back the replay.

Use UWorld RemoveNetworkActor instead of directly calling NetDriver RemoveNetworkActor during seamless travel tick in case there is no NetDriver.

Improved LLM tag coverage for networking memory.

Added a compile time option for inclusion of the sub-object replication key feature.

Added a compile time option to remove usage of the replication graph ForceNetUpdate delegate.

Added checks for unsupported nested NetDeltaSerialize structs.

Added more comments and a warning around dependent actors in RepGraph.

Added Session ID's and Client ID's (Connection ID's) to packet protocol.

Added net.QueuedBunchTimeoutSeconds to replace a hardcoded value.

Added logging when the value of net.QueuedBunchTimeoutSeconds is exceeded.

Added a network driver setting for the maximum number of channels per connection.

Added a connection flag to control whether replication size limits can be ignored.

Prevent world settings for temporary transition maps from replicating in order to prevent warnings during seamless travel.

Exposed NetworkProfiler API for linking.

Added '-LogDebug=MatchStr' command-line parameter and 'LogTrace AddDebug MatchStr' console command to NetcodeUnitTest to trigger debugging on a particular log line pattern.

Added logging to assist in debugging actor channel failures.

Added replay result codes for failure to decrypt and missing event data.

Set an engine default for the net.PartialBunchReliableThreshold console variable to improve network performance of large bunches when there is packet loss.

Improvement:

Statsport/exec listener now returns a different error message when the exec callback is not registered, the cmd itself was not processed by the exec or the cmd is missing the 'c=' param.

Clamped replay priority into a valid range before rounding.

Adjusted recording CSV stats around actor vs destruction info.

Modified custom property replication conditions to be stored outside of any active network driver, and provided an API to modify them at any time.

Cleanup of sub-object references in replay recording.

Improved memory usage of shared serialization data.

Improved the memory usage of fast array replication states.

Adjusted the replay streamer interface to make it easier to add common analytics attributes.

Modified replay scrubbing to reduce memory allocations.

Improved memory allocation of the local file replay streamer.

Increased default value for NetPackedMovementMaxBits.

Refactored log tracing and added ability to trigger console commands on certain logs.

Command-line example: -LogCommand="ReadContentBlockPayload failed=obj list class=ShooterGameState"

Console command example: LogCommand Add ReadContentBlockPayload failed=obj list class=ShooterGameState

Changed subobject outer ensure to a log, so it now falls back to the default behavior (actor as outer) if outer is unavailable.

Crash Fix:

Fixed issue with ConnectionId assignment that could cause server crash.

Fixed multiple crash issues with asynchronous replay recording property validation.

Fixed handling of replication history when the maximum replicated size was exceeded for an object, which would often lead to a crash.

Fixed crash referencing spectator controllers when loading replay checkpoints.

Fixed a crash when using out parameters in RPC calls.

Fixed a replication graph crash in the ShooterGame sample when seamless traveling.

Fixed a replay crash when attempting to load a map that no longer exists.

Bug Fix:

SupportsMultithreadingPostFork will not assert if the command-line has not been set when called, instead, it will return true/false based on the DEFAULT define and hope the cmdline override will not break anything later.

Export FStreamingLevelActorListCollection to external modules.

Prevented actors outside the destruction radius but inside the current OutOfRange radius check from being added to the OutOfRange list in ReplicationGraph, and, instead keep actors in the PendingDestructionList until they get inside the send radius or outside the OutOfRange radius.

Marked NetDriver and related objects as garbage as much as possible when destroying the net driver. Released references to objects from open channels on clients during net driver shutdown.

Fixed grid cell node doubling child node actors.

Invalidated replicators on the client as soon as their object becomes garbage.

Cleaned up the replicator so it doesn't leak through AllOwnedReplicators. Handled the case where subobjects are marked as garbage during the channel update, or where the ability system marks a replicated subobject as garbage on the client.

Explicitly enforced bReplicateUsingRegisteredSubObjectList to false for classes for which we will not convert their ReplicateSubObjects function to the new method.

Actors flagged for serialization will now be serialized just before we call destroy on them with Replay Recording. This allows them to be serialized in a state where they still have most components and properties intact.

Fixed off by one bug in DisableAllReplicatedPropertiesOfClass which did not properly disable all properties.

Fixed an issue where NetConnection->ViewTarget was not properly updated prior to replicating data.

Released object references from dormant replicators when levels are streamed out or actors are destroyed.

Fixed NMT_Failure early disconnects from missing NMT_CloseReason.

Reduced the number of forced property comparisons when using SetReplicates.

Fixed a replay checkpoint recording issue when using push model dirty state tracking.

Fixed servers not ignoring the destruction info net messages.

Fixed uninitialized vector data when receiving new replicated actors.

Fixed a case where replicated sub-objects would not be recorded into replay checkpoints.

Fixed handling of invalid package paths received from clients that could cause a crash.

Use Owner instead of AttachmentRoot Actor for AttachParent when replicating attachment.

Fixed handling of actors destroyed in the middle of an amortized replay checkpoint save.

Fixed an issue where replicated scene components could be added to the AttachChildren array at the indices of unmapped references, leading to the component being overwritten when the reference was mapped.

Have UActorChannel::KeyNeedsToReplicate check if the subobject is pending dormancy in order to prevent cases where an unchanged key prevents the channel from going dormant.

Fixed potential package map name mismatch warnings in PIE.

Prevent stale/garbage LastViewTarget actor being added to Replication List.

Fixed missing call to PostReplicatedChange on the fast array serializer, when mapping previously unmapped objects (Items PostReplicatedChange calls were not affected). Fixed for both 'net.SupportFastArrayDelta' on/off paths.

Fixed a race condition in replay recording of torn off actors.

Fixed a case where recording a new replay would not stop an existing recording first.

Fixed a missing level name remap in PIE that prevented seamless travels from succeeding.

Changed the ensure for destroying a NetDriver during its tick to not trigger for PendingNetGames.

Fixed incorrect timestamp check, preventing disabling of challenge ack resend code path server side.

UNetReplicationGraphConnection::PrepareForReplication now checks if the connection is in the correct world.

Fixed RemoteViewPitch being generated incorrectly.

Fixed levels unnecessarily tracking destroyed actors during replay playback.

Fixed replays recording multicast RPCs from only relevant to owner actors.

Call NotifyControllerChanged from ClientRestart in case it is received with the valid pawn before APawn::OnRep_Controller is called.

Handle emptying the map name if CurrentMapName == DestinationMapName when no transition map is specified in order to prevent issues when seamlessly traveling to the same map.

Fixed compiling in shipping with stats enabled.

Fixed an issue where tracking and validating replicated subobjects would be skipped if custom subobject replication was used.

Replicated FSoftObjectPtrs to dynamic, spawned-at-runtime replicated objects now resolve properly on clients.

Deprecated:

Removed support for replay network smoothing mode in network playback data.

Deprecated the AES ECB packet handler component in favor of the AES GCM handler.

Removed:

STAT_RepLayout_AddPropertyCmd

Removed a strong level reference from replay scrubbing state.

Removed replay backwards compatibility handling for versions prior to the minimum supported version.

"LastCompletedSeamlessTravelCount == SeamlessTravelCount" check was removed from APlayerController::HasClientLoadedCurrentWorld to prevent issues when client finishes travel before the server.

Level Design and Art Tools

Bug Fix:

Fixed an issue when computing the distance of a full spline segment that uses constant interpolation. Function incorrectly returned a distance of 0 for all partial distances, however when computing the "full" distance with p=1 it should have returned the true distance between the points. This fixes another issue with generation of the Spline Curve's Reparam Table where spline keys would map to incorrect distances if a spline had any number of constant interpolation points.

Implemented an actionable message on load to create the water collision profile when it is not defined, rather than checking the DefaultEngine.ini on load.

Fixed default-enabled Editor modes showing up in random order, by giving the modes prescribed priorities.

Fixed an issue where the spline visualizer wasn't taking into account the list of enabled/supported spline point types for the given spline component.

Fixed Actors being attached to a Level Instance that is not being edited.

Fixed metallic, specular, and roughness being packed into a single texture.

Fixed import descriptor not refreshing when toggling Flip Y Axis setting from ImportExport tool. Also made option to flip coordinate on Y axis available when exporting tiled landscape.

New:

Created a 'contain(other interval)' function to TInterval1.

Add a "prevent tiny triangles" option to Remesher. Currently the area threshold matches the threshold used when creating a cloth simulation mesh.

Exposed an optional second importance weight to the FPriorityOrderPoints class

Added FColliderMesh::FindNearestHitTriangle() and FColliderMesh::FindNearestTriangle() wrappers around mesh AABBTree functions.

Renamed ::GetAABBTree() to ::GetRawAABBTreeUnsafe() to discourage usage.

Added new oriented box fit variant that starts from the fast DiTO box and optimizes the fit iteratively, and changed modeling tools oriented box fits to use the new algorithm.

Improvements to the FMeshBevel operation, which resolves many failure cases in higher-level Beveling operations in Modeling Tools and Geometry Scripting.

Updated Degenerate triangles to now be filtered out when creating Complex Collision geometry for UDynamicMeshComponent, to avoid warnings in the physics system.

Added a new FMeshPlanarSymmetry class for detecting and applying planar symmetry to mesh vertices.

UDynamicMeshComponent now supports the Visible In Ray Tracing Component setting. However this does not currently override the UDynamicMeshComponent-specific Enable Raytracing flag.

Added FDynamicMesh3::EnumerateEdgeTriangles() function, which has the same API as ::EnumerateVertexTriangles().

Added function UE::Geometry::TrianglesToOverlayElements() in MeshIndexUtil.h which collects elements from triangles in a mesh attribute overlay.

Added FDynamicMesh3::EnableMatchingAttributes() function to expose FDynamicMeshAttributeSet::EnableMatchingAttributes() at the Mesh level.

UpdatedUDynamicMeshComponenttonow support a separate "transient" flag for disabling collision updates, configurable via SetTransientDeferCollisionUpdates(). This setting allows C++ code, such as code that implements a live 3D transform of mesh vertices, to temporarily disable collision re-generation without modifying the serialized bDeferCollisionUpdates UProperty.

Added a new FMeshResolveTJunctions class that attempts to fix situations in meshes where a boundary vertex lies on the interior of some other boundary edge (a "T-Junction"). Exposed this capability in the Weld Tool in Modeling Mode.

Updated Morphology.h to use sparse SDF due to memory savings over the dense SDF. The AutoLOD tool and the Morphology tool use this class, but the behavior shouldn't change.

Bug Fix:

Made GteMinimumVolumeBox3 robust to failing to find a convex projection for some faces.

Fixed a bug that made the fit always ignore results from the ProcessEdges pass, and added an option to always skip that pass (for a faster method that matches the previous behavior).

Fixed incorrect float casts in FAxisAlignedBox3d and FAxisAlignedBox2d when casting to FBox and FBox2D, making this cast function correctly at large world coordinates.

UDynamicMeshComponent now supports overrides to the color/material and normals, allowing display of vertex colors, group colors, or a (configurable) custom color, as well as facet normals (flat shading). These settings can be configured for any such Component in the Actor properties. The wireframe color is now also configurable.

Added an fp:precise pragma to the MSVC compile of XAtlas, giving more consistent results across platforms and build settings.

Deprecated:

We deprecated the timestamp on TDynamicPointSet3, as it was unused.

New:

Added InvertMeshSelection function.

Added Geometry Script function SetMeshSelectionVertexColor, sets vertex color on selected faces/vertices, optionally creating "creases" in the vertex color overlay around the selection border

Added ThickenShells option to ApplyMeshSolidify function.

Added AppendMeshTransformed function that appends N copies of a mesh to another mesh, with a custom Transform applied for each.

Added ExpandContractMeshSelection function, which can grow or shrink a Mesh Selection based on mesh connectivity.

Added ApplyUniformRemesh function, which applies remeshing algorithms to a UDynamicMesh similar to the Remesh Tool in Modeling Mode.

Added ApplyMeshOffsetFaces function.

Added ApplyMeshInsetOutsetFaces function.

Added a 2D Voronoi diagram generation function.

Added ResolveMeshTJunctions function that exposes the new T-Junction Resolution algorithm.

Added AppendSweepPolygon function which takes the sweep path/curve as a list of FTransforms, instead of FVectors, giving the caller more control over rotation and scaling along the sweep. This function should replace usage of AppendSimpleSweptPolygon.

The CopyMeshFromStaticMesh Geometry Script function now works on UStaticMesh assets at Runtime, if the bCPUAccess flag was enabled on the Asset at cook time.

Added "Frozen" flag on GeneratedDynamicMeshActor. Users can disable expensive mesh recomputations when not editing procedural mesh generation parameters/settings.

Add support for optional Mesh Selection to:

TranslateMeshUVs

ScaleMeshUVs, RotateMeshUVs

SetMeshUVsFromPlanarProjection

SetMeshUVsFromBoxProjection

SetMeshUVsFromCylinderProjection

Add support for optional Mesh Selection to RecomputeMeshUVs.

Add a new GetMeshUVSizeInfo function that can be used to get UV Area/Bounds, and 3D Area/Bounds, for a given selection.

Added support for optional input Mesh Selection to ComputeMeshConvexHull function.

Added a new ComputeMeshConvexDecomposition function that exposes new automatic convex decomposition strategy.

Added SplitMeshBowties function.

Added RepairMeshDegenerateGeometry function.

Added GetMeshInfoString function.

Added support for optional Mesh Selection to:

ApplyPerlinNoiseToMesh

ApplyIterativeSmoothingToMesh

ApplyDisplaceFromTextureMap

ApplyDisplaceFromPerVertexVectors

Added ApplyMeshDisconnectFaces function.

Added ApplyMeshDuplicateFaces function.

Added a new ApplyMeshLinearExtrudeFaces function that supports linear extrusion of entire mesh or selection. Redirect previous ApplyMeshExtrude function to ApplyMeshExtrude_Compatibility_5p0.

Added a new ApplyMeshBevelSelection function, which supports various ways to interpret the MeshSelection as set of faces or edges to bevel

Added ComputePolygroupsFromPolygonDetection functionthat exposes new quad-detection algorithm (currently only quad polygons are detected).

Added an Auto-Compact option to Simplify and Remesh functions, that when enabled will automatically Compact the output mesh. This new setting is enabled by default, to reduce the chance of users hitting errors when passing the output simplified/remeshed mesh into downstream functions.

Added CopyMeshUVLayerToMesh and CopyMeshToMeshUVLayer functions. These can map a UV layer to a separate mesh, editing it, and then transferring the edited positions/topology back to the UV layer of the source mesh.

Added SampleSplineToTransforms functionthat computes a set of FTransforms at points along a USplineComponent, using various sampling strategies.

Added AppendSweepPolyline function, similar to AppendSweepPolygon but sweeps an open 2D profile curve instead of a closed 2D polygon.

Added a new FGeometryScriptMeshSelection type that can store/represent Vertex, Triangle, and Polygroup "selections" on a UDynamicMesh.

Add various functions for working with this new type, including:

CreateSelectAllMeshSelection

ConvertMeshSelection

CombineMeshSelections

ConvertIndexArrayToMeshSelection

ConvertIndexSetToMeshSelection

ConvertIndexSetToMeshSelection

ConvertIndexListToMeshSelection

ConvertMeshSelectionToIndexList

SelectMeshElementsInBox

SelectMeshElementsInSphere

SelectMeshElementsWithPlane

SelectMeshElementsByNormalAngle

SelectMeshElementsInsideMesh

ExpandMeshSelectionToConnected

GetMeshSelectionInfo

DebugPrintMeshSelection

GetMeshSelectionBoundingBox

GetMeshSelectionBoundaryLoops

Add various new Geometry Script functions for editing a mesh based on a mesh selection:

DeleteSelectedTrianglesFromMesh

TransformMeshSelection

TranslateMeshSelection

RotateMeshSelection

ScaleMeshSelection

SetPolygroupForMeshSelection

SetMaterialIDForMeshSelection

Added CopyMeshSelectionToMesh, which copies triangles identified by the selection to a new UDynamicMesh.

Added Geometry Script functions for manipulating FGeometryScriptIndexList, UVList, and ColorList objects, to bring up to parity with functions for Scalar and Vector lists.

Added options for the Geometry Script AppendMesh node's attribute handling.

Now by default, if meshes do not have the same attributes enabled, any attribute enabled on either mesh will be enabled on the result mesh. The caller can optionally make the result only enable the attributes on the source or the target mesh.

Bug Fix:

Added Geometry Script function CopyCollisionMeshesFromObjectwhich extracts meshed collision shapes, or the complex collision mesh, as a UDynamicMesh from various object types (StaticMesh, Volume, and DynamicMeshComponent).

Updated Geometry Script functions that read or sample from a UTexture2D to now work at runtime, but only if the texture format is VectorDisplacementMap.

If this is not the case, errors are now gracefully handled instead of hard crashing.

The Geometry Script function AutoGeneratePatchBuilderMeshUVs now gracefully handles a non-compact input mesh, and prints a warning if such a mesh is passed.

New:

Added a vertex-based connected components class that can be used with any TriangleMeshType and supports connecting based on spatial proximity as well as triangle topology.

Made FMeshBoolean's automatic mesh simplification code optionally avoid simplifications that would noticeably change the vertex normals. We also enabled this feature when computing fractures, to prevent the fracture code from generating results with incorrect normals.

Bug Fix:

Fixed failure cases in the exact predicates library.

Adjusted FindNearestCurveToRay when processing segments in a curve, to balance the distance-to-ray-origin against the ray-segment distance to find the optimal segment.

Fixed issues with the GeometryCore FPriorityOrderPoints class:

It now uses the SpatialLevels argument.

The early-stopping optimization is fixed, so it no longer causes spatial 'clumping' of points when enabled.

The code no longer incorrectly refers to some of the importance weights as "curvature," as the class is general-purpose and other features are often used for importance weights.

An 'OffsetResFactor' (Offset Resolution Factor) parameter was exposed, to allow more control of how clumpy the distribution is; we recommend a value of 1 or 2 to best distribute the input points.

Fixed instability in initializing GeometryCore's TQuaternions almost aligned to -Z axis, or generally rotating almost 180 degrees with a TQuaternion::FromTo() call.

Fixed a few unsafe typecasts.

New:

Added a Async Physics build for Dynamic Mesh component.

Added SRGBToLinear node for transforming vertex colors of dynamic meshes in GeometryScript.

Added LinearToSRGB node for transforming vertex colors of dynamic meshes in GeometryScript.

Added CopyMeshToSkeletalMesh node to GeometryScript.

Added CopyMeshFromSkeletalMesh node to GeometryScript.

Added BakeTexture node to GeometryScript.

Added BakeVertex node to GeometryScript.

Added CreateNewTexture2DAsset node to GeometryScript.

Updated Geometry Script functions to automatically fix mesh orientation when transforming meshes with negative scales.

Adjusted LineSegmentGenerators to use the given box center when computing box lines.

Added a PolyPath class to Geometry Script, which provides an (optionally-closed) polyline/polygon with 3D vertices, and a set of associated utility functions. The utility functions include one to generate a PolyPath from a USplineComponent.

Added the Spectral Conformal UV Solver option to the Geometry Script RecomputeMeshUVs function.

Added the Spectral Conformal UV Solver option to the Geometry Script RecomputeMeshUVs function.

Bug Fix:

Fixed transform handling in Geometry Script functions, by making them use ApplyTransformInverse() and InverseTransformPosition() rather than trying to invert an FTransform.

New:

The BakeAll tool now supports skeletal and dynamic meshes as source meshes.

Added sample filter mask support to the BakeTexture tool.

Added sample filter mask support to the BakeAll tool.

Added Object Space Normal bake support to BakeAll tool.

Added Position bake support to BakeAll tool.

Added Selective Tessellation Options to the Displace Tool to only tessellate and displace those triangles that belong to a specific material.

Added a Random Colors option to the collision geometry visualizations in the PInspct and Msh2Coll tools.

Initialized implementation of optional boundary constraint projection for the Remesh tool.

Constrained edges along a boundary can collapse, and vertices can move, but they are projected back to the original boundary curve geometry.

Vertices at boundary "corners" (defined using an angle threshold criterion) are constrained to not move or be deleted.

DynamicMesh3: Add comments to AppendTriangle functions saying the vertices must exist and the indices must be distinct

Added a Detail Customization class for AutoLOD properties to enable HintText to be used in some text entry fields when the field is empty.

Updated AutoLOD tool's UI to validate group layer name and weight map layer name when specified by the user. Issues a warning if the specified layer doesn't exist

Adjusted AutoLOD tool's UI to not clear the warning area if there is a non-empty result.

Turn selection checkboxes into buttons in PolyEd and TriEd modeling tools.

Added the Spectral conformal parameterization option to the Unwrap UVs tool.

Support running various tools only on limited selections in the UV editor, and support multi-asset selections.

Support seam edges to be collapsed by the remesher if Preserve Sharp Edges in unchecked in the Remesh tool.

Added a Smooth Boundary operation to the Mesh Selection tool.

Added convex decomposition options to Msh2Coll tool and Geometry Script collision functions.

Updated PolyEd to work better on many common open-boundary cases by placing extra selectable corners on sharp group edge bends.

Adjusted the Add Primitive tools accept/cancel so that the initial click can place the mesh and then the settings can be modified before accepting the tool.

Allow users to set specific extrude distance in PolyEd tool.

Allow users to create a new asset in CubeGrid tool if the underlying asset is deleted.

Various CubeGrid tool improvements. - Made the tool Accept/Cancel.

Added the ability to set block size at current power

Added ability to initialize the grid from a given actor, initialized to the current target.

Added the option for the grid sizes to follow the default editor grid (1, 5, 10, 50, 100, etc).

Allowed global mode for gizmo manipulation, to allow editor grid snapping to work.

Add Select All and Invert Selection actions to PolyEd.

Enable selection support within the UV Editor's Layout tool.

Enabled support of selection within the UV Editor's Unwrap tool.

Implemented support for snapping on gizmo initiated transforms in the UV Editor.

Added a new toolbar in the 2D viewport that resembles the snapping controls found in the main level editor.

Added support for selection mechanics within the 3D viewport.

Updatedthe 3D UV Editor viewport to support mouse picking and marquee selection modes, just as in the 2D viewport.

Provided a new Select All command bound to Ctrl + A. The Escape key will unselect all selected elements.

Added a bridge edge action to the PolyEd tool, which creates a face between two boundary edges. If the two edges being bridged are connected by edges at either end, this action will not weld the edges of the new face to the existing edges, potentially leaving holes in the mesh.

Made the transform gizmo in the PolyEd tool visible by default - appearing automatically when any portion of the mesh is selected.

Support for creating DynamicMeshActors in Modeling Mode is now enabled by default.

Mesh Booleans and CutMeshesWithMeshes. When filling holes, generate normals and UVs for the new patches

Updated the UV Project status bar message to include information about Shift+Ctrl+Click for repositioning without reorienting.

Adjusted the PivotAct tool to now show the active transform position and rotation in the tool's details panel.

Extended the edge weld action in the PolyEd tool to group edges. Edges that have vertices other than their endpoints can be welded by sequentially welding their simple edges automatically. If the two group edges being welded have different numbers of vertices, then the group edge with fewer vertices is split until the two have the same number.

Added support for symmetric mesh vertex sculpting in the VSculpt tool. Symmetry is detected and applied via vertex/point-set symmetry rather than topological symmetry. The Symmetry Plane is auto-detected (implemented in FMeshPlanarSymmetry) and currently cannot be specified by the user.

Added a "Find Quads" mode to the Polygroup Generation Tool in Modeling Mode ("GrpGen"). This mode attempts to reconstruct the source quads of a triangle mesh as Polygroups by incrementally finding pairs of triangles. The implementation of this algorithm is in the FPolygroupsGenerator::FindSourceMeshPolygonPolygroups() function.

Added support for creating and selecting a target Polygroup layer in the Polygroup Generator tool (GrpGen).

Added support for setting target groups from an existing layer. Users can perform operations such as copying groups between layers and duplicating an existing layer.

The Edit Normals Tool in Modeling Mode now allows the user to specify alternate Polygroup layers to define normal creases.

Added support for Spectral Conformal unwrapping mode in the UV Editor's Unwrap tool to match functionality existing in the Modeling Mode version of the tool.

Changed the selection gizmo placement in the UV Editor from being the centroid to the bounding box center of the selected elements.

Added support for a new launcher for the UV Editor to appear in the Modeling Mode UVs tools category.

Added a new ISM Editor Tool. Users can select and manipulate Instances in all the InstancedStaticMeshComponents of the selected Actors.

Added new high performance rendering components for handling mesh highlighting on large meshes in the UV Editor.

Includes 2D and 3D variations of Point Sets, Line Sets, and Triangle Sets. These are considerably stripped down from the previously used component classes, designed with the intent on reducing needed memory bandwidth to move data to the rendering thread.

Made the following mesh creation tools generate tangents for their created meshes:

PolyExt

PathExt

PathRev

BdryRev

Allowed selection mode changes even if the mechanic is not currently enabled in the UVEditor.

Added drag alignment mechanic to the plane control gizmo in PolyExt tool, enabling translational and rotational snapping when moving or rotating the plane used for drawing the profile to extrude.

UVEditor: Cleaned up options for the various UV Unwrap algorithms to only be visible to the user when the appropriate method has been selected to reduce confusion in the UX.

Added hotkey R to hide plane control gizmo in the PolyEd tool.

Added toggleable corner point visualization to the PolyEd tool.

Improvement:

Adjusted UVs to always stay aligned in the same orientation when using the CubeGrid tool.

Updated CubeGrid's UVs to be contiguous when performing multiple steps with the same selection.

Updated CubeGrid sides to maintain the same groups with repeated steps of the same selection.

Added support in CubeGrid for scaling UV's.

Added support in CubeGrid for focus hotkey.

Improved performance and runtime speed of rebuilding the UV overlays and meshes when edits or channel switches are performed, particularly on high polygon count meshes.

Cleaned up warnings in the UV Editor related to type truncation and loss of precision issues in adherence with coding best practices.

Improved WeightMap support in many tools in Modeling Mode, such as Duplicate and where possible Combine. In cases where weight map layers with duplicate names could be created, unique names are now auto-generated/enforced.

Bug Fix:

Improved Mesh Boolean and Self-Union (MshBool and Merge tool) results to better handle nearly-coplanar sliver triangles.

Fixed issue where the TargetMesh property was incorrectly set for skeletal and dynamic mesh targets in the BakeAll tool.

Fixed MaterialID bakes to overwrite pixel buffers instead of accumulate.

Fixed incorrect tangent normal bakes in the BakeAll tool by ensuring that the normals are transformed into the correct space for each source mesh.

Fixed issue where the preview material in the BakeTexture tool was not reset when output type was modified.

Fixed issue where the preview material in the BakeAll tool was not reset when the output type was modified.

Fixed correspondence strategy in FMeshMapBaker when input meshes are the same.

Fixed an issue where the error material was not shown when BakeTexture tool had invalid inputs.

Fixed an issue where the error material was not shown when BakeVertex tool had invalid inputs.

Fixed an issue where the error material was not shown when BakeAll tool had invalid inputs.

Fixed the error material not being shown when output types are restored on tool startup with invalid inputs in the BakeTexture tool.

Fixed the error material not being shown when output types are restored on tool startup with invalid inputs in the BakeAll tool.

Fixed the error material not being shown when output types are restored on tool startup with invalid inputs in the BakeVertex tool.

Fixed an issue where vertex colors were incorrectly encoded when converting between static and dynamic meshes.

Fixed bugs with how the CubeGrid tool deals with materials.

Made the Msh2Coll tool use a background thread to compute collision shapes, so it will not lock up the editor while it computes.

Prevented BakeRS tool UI from allowing user to try baking only rotation, when the input's transform included both rotation and non-uniform scale, as UE transforms don't support this.

Fixed a crash when Displace tool tries to read WeightMap data from a deleted StaticMeshAsset.

Fixed PolyEd performance regression on highly tessellated mesh regions.

Fixed a bug where the number of the vertical slices being generated is always off by one in the Sphere Primitive Tool.

Corrected Lattice tool to hide the gizmo only if constrained vertices are selected.

Fixed PolyEd modeling tool failing to deal with certain bowtie group topologies.

Fixed a bug in the Displace tool where undoing changes to the Perlin noise properties would not update the mesh in the viewport.

Adjusted PolyEd offset and inset to work in pathological bowtie-related cases.

Fixed DisconnectTriangles in cases of bowties.

Fixed normal generation in CubeGrid tool.

Fixed crash in CubeGrid if gizmo is dragged without ever having selected anything.

Fixed PolyCut tool's handling of non-uniform scale

Fixed various UV editor undo/redo transactions not being expired when the editor is closed.

Fixed the exact predicates code accessing an index past the end of its local stack arrays.

Resolved the Lattice tool's handling of negative scales.

Fixed issue where converting a selection type resulting in an empty selection would cause an ensure to be thrown in the UV Editor.

Fixed handling of some transforms with a negative scale in the modeling tools and geometry script functions for managing collision geometry.

Adjusted the BdryRev tool to snap to the local mesh pivot if its rotation axis is 100,000 units (1000 meters) away from the target shape when the tool starts. This reduces the likelihood of confusing cases where the axis is too far away to be useful or visible.

Resolved bug where undoing a selection would continue to transform the previous selection using the interactive gizmo.

Fixed vertex sculpting brush alpha's "RotationAngle" display name not fitting in the available space, by changing the display name from "Rotation" to "Angle".

Resolved handling of negative scales for a number of modeling tools and geometry script functions.

Fixed issue in the UV Editor where activating some tools resets the selection mode, causing the user to re-select their desired mode after using the tool.

Made the PathRev tool warn the user if the draw plane and axis is far from the camera position, with an explanation of how to place the draw plane in the view.

Resolved issue where a crash would occur when a dynamic mesh is loaded into the UV Editor and then deleted externally before exiting the UV Editor.

Prevented crash upon opening the UV Editor if the live preview tab was closed prior to last exiting the UV Editor. Also forces the live preview tab to be opened automatically upon UV Editor startup.

Fixed issues where starting Play in Editor (PIE) mode wouldn't prevent the UV Editor from performing unwanted actions, such as saving assets.

Added a bSRGBConversion parameter to ProceduralMeshComponent's CreateMeshSection and UpdateMeshSection functions. The caller can control whether sRGB conversion is performed. To keep current results unchanged, the default values of this parameter for the two functions is different (Create doesn't convert, but Update does).

Corrected issue in the UV Editor where polygroups were being incorrectly set on operation factory instances in the Unwrap Tool.

Fixed for PolyEdit and PolyPath tools not rendering preview results when at Large World Coordinate scales.

Made vertex sculpting's symmetry detection more robust, so it should detect vertex mirror symmetry for arbitrary (non-axis-aligned) mirror planes.

Resolved issue in the UV Editor where displaying background texture incorrectly handled textures that need non-color samplers in materials, such as normals.

Fixed the level editor gizmo lurking invisibly, still clickable, in the HitProxy buffer after modeling tool start

Resolved crash when right-clicking on the asset tab in the UV Editor would fail an assertion.

Fixed a corner case in the BSP lightmap code causing a divide by zero and triggering an 'ensure' when the input spans zero range and exactly aligns to Scale. This happens at large-world-coordinate scales due to float precision.

Removed ability for the Editor Viewport Camera Controller to affect the UV Editor's 2D viewport. This solves the issues around keyboard navigation causing unexpected lockups in the editor during extreme zoom instances.

Fixed issue where the UV Editor's UI was in a semi-broken state after an autosave event occurred.

Fixed Merge tool not working at large world coordinate scales.

Fixed crash bug due to selection hover behavior in the UVEditor not being correctly handled by the Input Router during shutdown conditions.

Fixed the modeling mode split tool's "from output" material selection method for inputs with multiple materials.

Made sculpt tools focus on the sculpting brush using hotkey 'F', rather than the whole model.

Fixed crash bug occurring when selecting elements while multiple assets are loaded in the UV Editor.

Made PlanePositionGizmo use double precision to compute plane intersections, and not crash if plane intersection fails.

Fixed VoxBlnd, VoxMrph, and VoxWrap tools not showing a live preview of their result at large world coordinate scales.

Prevented "No Action" item from appearing in the Action dropdown for the Channel edit tool.

Fixed Lattice tool's Dimensions setting becoming editable on control point movement redo.

Corrected handling of negative scales in UDynamicMeshComponent::ApplyTransform.

Disabled cast shadows for the Preview UV Layout square.

Fixed Hole tool and Boundary Revolve tool from seeing polygroup boundary edges instead of mesh boundary edges.

Fixed the Boundary Revolve tool skipping the last vertex on open boundaries.

Stopped auto-loading settings from switching the target preset in AutoLOD. Users can now choose whether they want to instead write their current settings to that target.

Deprecated:

Deprecated the unused Timestamp and GetTimestamp function on TPolygon2 and TPolyline3. Any code that needs to track timestamps for polygons or polylines should do so separately from these structs.

The UPersistentMeshSelectionManager along with related functions and classes. This is replaced by new experimental functionality in the UGeometrySelectionManager class (disabled by default).

Removed UV Island Conformal Unwrap action, now that its functionality is superseded by the Unwrap tool having selection support.

New:

Added feature to move (Left Alt down) actors from Data Layer(s) to another data layer in the Data Layers Outliner.

Prevented most common cases of UV generation failure when performing material baking when using World Partition - HLOD.

Enabled Nanite on landscape HLODs if the source landscape proxies are Nanite-enabled when using World Partition - HLOD.

Added support to World Partition - HLODs for automatic texture sizing for Merged & Simplified HLODs and reused existing code to share it between all HLOD generation methods

In World Partition - HLOD, automated ScreenSize computation for "Simplify" HLOD method. ScreenSize option is now deduced from the meshes bounds and the configured draw distance.

Added "-DebugCapture" option to the WorldPartitionMinimapBuilder, which writes bitmaps of all captured tiles & the final minimap.

Instancing HLOD layers now has a "Disallow Nanite" option. This is necessary on Nanite meshes that have multiple LODs, otherwise the setting of the mesh's last LOD as the component ForcedLOD will not work.

Exposed HLOD options on landscapes when using World Partition - HLODs.

Added support for Approximate simplification method to Level HLODs

Changed HLOD actors folders & labels naming in the scene outliner

Unified autosubmit code for World Partition Builders

Added auto submit support to existing builders

Added auto submit tags support to allow scripts to provide robomerge tags for a CL

Improvement:

Fixed and Improved World Partition Spatial Hash Grid Preview editor material used to preview grids in the world.

Added highlighting full grid cells crossing the loading range radius .

Added loading range circle.

Extended the grid un-highlighted past the loaded area.

Added a small circle to identify the center point.

Fixed offsets.

Bug Fix:

Fixed screen percentage warping by setting the post-process to pre-tonemapping.

Fixed a bug where the World Partition minimap wouldn't capture LevelInstance since it never is able to UpdateStreamingState to load the actors in that LevelInstance before being captured.

Fixed a crash occurring in the HLOD builder commandlet when hashing landscape texture source data while potentially asynchronously building textures.

Fixed a few places where the FTextureSource's data was not being used.

Fixed crash in world browser when unloading a World Composition level that cannot be unloaded because of lingering reference.

Compute HLOD bounds in Z by using the subactors bounds rather than relying on the world's min/max Z when using World Partition - HLODs.

Improved error handling for the Merge Actor - Mesh Approximate Tool.

Ensure that child actor components are marked as HLOD relevant if the child actors are HLOD relevant for World Partition - HLODs

In the minimap builder, fixed stretched tile capture when tile wasn't square.

Fixed an issue where World Partition: Actors ActorGuid must not be reset in AActor::Serialize() when duplicating for PIE.

Fixed an issue where IMeshMergeUtilities::CreateProxyMesh() returns a single static mesh when it could return multiple meshes.

Makes sure skydome actors are excluded from HLOD in all Engine map templates.

Improved outdated HLOD detection

Excluded some HLOD builder subclasses from editor dropdowns.

Fixed an issue with ISMC custom primitive data being stored in the HLOD proxy descriptor.

Marked level packages created through UWorldPartitionLevelStreamingDynamic::LoadInEditor() as transient. This prevents the editor from asking to save those temp packages.

Fixed custom primitive data not taken into account in some specific cases with World Partition - HLODs.

Prevented false positive when testing for outdated HLODs

Hide texture size property unless texture sizing type is "Use Single Texture Size" or "Use Automatic Biased Sizes" in World Partition - HLOD: Material Proxy settings.

Avoided deleting World Settings from retained sublevels when using the World Partition - Conversion Commandlet.

Deleted HLOD actors from retained sublevels when using the World Partition - Conversion Commandlet.

Level Design and Art Tools /GeometryScript

New:

Added vertex color bake support to the BakeVertex tool.

Added CreateCircle and CreateArc functions to Geometry Script's new PolyPath class

Localization

New:

Expose ENGINE_API for QueueSubtitles.

Added support for preview versions of the localization manifests to be generated and deleted during a preview localization run.

This addresses false positives for localization warnings that can arise from comparing gathered strings to a stale manifest file.

Added a preview parameter to the Localization Unreal Automation Tool command which allows the command to run in preview mode.

Localization commandlets now generate *_Preview.manifest files during a run into the destination path specified by the config files.

The localization automation script will delete all files that end with _Preview.manifest at the end of the gather run.

Improved checks for manifest filename extensions to ensure no malformed manifest filenames are passed into the commandlet.

Introduced a Preview cmd line arg to GatherTextCommandlet to allow the gathering of source and asset files without checking out or writing any localization files. This makes dry runs to print all localization warnings much easier for debugging.

Introduced the -Preview arg and -GatherType param to UGatherTextCommandlet.

The -GatherType param can have values of All, Source, Asset or Metadata. Source will only gather source files, Asset will only gather Asset files, Metadata will only gather Metadata and All will gather all 3.

The -GatherType param is only supported in preview mode right now. This is because manifests are updated every single gather and we do not want the manifest to only reflect partial gathers.

Added additional logs to display when the commandlet is run with -Preview and -GatherType.

Refactored parts of UGatherTextCommandlet to reduce hard coded switch and param names.

Introduced a virtual function in UGatherTextCommandletBase to allow commandlets to be conditionally skipped in preview mode.

Bug Fix:

Inserted a no-break space between the currency code and the numeric value to improve readability when formatting a foreign monetary value.

When a currency is not from the current locale, the currency formatter may prepend or append the ISO currency code to disambiguate. However, this may cause readability issues. For example, 1500 Japanese yen is formatted as "¥1,500" in ja-JP, but it was formatted with its ISO currency code as "1 500 JPY" in es-ES or as "JPY1 500" in es-MX. In the last case, readers may mistakenly think that the price was 500 yen at a glance due to the spacing.

We inserted a no-break space between the currency code and the numeric value, so that it is now formatted as "JPY 1 500".

Online

New:

The callback of the gdk function XNetworkingRegisterConnectivityHintChanged is now called from the game thread, where we can safely call XNetworkingGetConnectivityHint.

Make Party Invite Reject a virtual method in SocialUser.

Only enable multiplayer subscription (which creates RTA connection) when create/join MPSD session.

Added callback to handle xbl multiplayer connection id change, to make sure connection id in MPSD sessions is up to date.

Added callback to handle xbl multiplayer subscription lost (lost connection to RTA), to stop multiplayer and delete all MPSD sessions.

Added USocialSettings::GetSocialPlatformDescriptionForOnlineSubsystem to get a social platform description by OnlineSubsystem name.

Bug Fix:

Fixed the potential playfab net driver initialization failure by delaying the authentication check of playfab user.

Cache the sanitized text only when successful, because it can fail to sanitize when becoming offline. When back online, we need to sanitize it again instead of getting it from the cache.

Fixed the connection failure of non-seamless multiplayer map travel on gdk when using playfab, listening server will no longer recreate the PlayFab EndPoint, so the URL of the EndPoint will not change.

Fixed the random playfab authorize failure when retry, now it depends on the waiting time to receive the custom session data change (contains new invitation data), not how many times it has retried.

Fixed the potential stuck issue when using playfab, now when error happens it will be returned to NetDriver, so it can be handled by map travel code.

Fixed UWebAPIDefinition class to use AutoCollapseCategories instead of CollapseCategories.

Fixed issue with H.265 being played using DX12 or Vulkan using WMFmediaPlayer.

Fixed DX12 playback with WMFmediaPlayer (H264/5, HAP, ProRes).

Fixed ElectraPlayer's close/shutdown code so it can also succeed during the engine's shutdown (PreExit) phase.

Made social user list keep weak pointers to users to fix GC errors when leaving PIE with GC reference elimination (pending kill) disabled.

Converted SocialToolKit LocalPlayerOwner to weak pointer.

Removed:

Removed PartyPackage.h. The PACKAGE_SCOPE usage caused issues with subclasses trying to override PACKAGE_SCOPE virtuals.

Bug Fix:

Stage Base.ini into crash reporter pak files to fix issues with missing configuration.

New:

Added Verbose logging to track progress of HttpManager::Flush.

Added an option to increase HTTP log verbosity when a request is being retried.

New:

Added getter for EOS platform handle in OSSEOS, enabling sharing the platform with other systems.

Updated Android to EOS-SDK-Android-21924193-v1.15.3, and swapped to using the libc++_static variant.

Added IOnlineSubsystemEOS public interface header.

Changed BucketId in EOS Sessions to use BuildUniqueId to fix compatibility issues.

Updated CreateLobbyOptions fields:

Addition of lobby id override and lobby host migration options.

Removed hard coded search parameters from sessions and lobbies.

Refactored DestroyLobbySession to make use of lobby host migration logic.

Increased verbosity level for logs in FSonyHTTPRequest::TickSendState and FSonyHTTPRequest::TickThreadedRequest from Verbose to VeryVerbose.

Updated Steam SDK to version 1.53a (with native Mac M1 support).

Changed the default gamertag mode to Classic to reflect changes in GDK guidelines.

Added USocialToolkit::CanAutoRecreatePersistentParty to control whether we should automatically recreate a persistent party on unexpected loss.

Added a Compare method to party rep data that can compare a specific value without needing a full party rep data wrapper.

Added an overload Checkout method that does not return receipts to the IOnlinePurchase interface.

It is recommended to be used if the product (game) processes purchases via backend services, and the clients do not need to know about the purchase information.

Implemented for all supported platforms.

Improvement:

Refactored of logic surrounding Epic Id queries to construct UniqueIdEOS for lobby members. All logic making such queries now waits for them to finish before triggering any completion delegates. Refactored logic to mirror API Lobby data into OSS Lobbies.

Refactored session object captures in session methods to avoid errors in lambdas.

Moved support for account portal login to the base FEOSHelpers class for subclasses to use on Android.

Crash Fix:

Fixed some crashes caused by converted strings being moved prior to use.

Refactored of FOnlineAsyncTaskGDKRedeemCode to not end prematurely on app reactivation, causing a crash.

Added fix for crash in CopyLobbyData when the session data was outdated.

Fix for crash in FGDKAsyncBlock destruction.

Bug Fix:

Fixed some occurrences of unterminated string conversions.

Fixed OnlineStoreEOS to use the DecimalPoint value from EOS, not the one from UE I18N, as they disagree on the number of minor units in Chilean Pesos (Centavos).

Fixed no core affinity being set for GameChat audio thread on GDK platforms.

Fixed OSSEOS checking the data field of an auth token for validity, and ignoring the string field.

Update Win64 binary to EOS-SDK-21924193-v1.15.3, to fix inability to fall-back on browser for account portal login flow.

Fixed warnings about EOSSDK failing to load, when the SDK does not exist in the first two places we check.

Fixed OSSEOS headers so they are includable outside the plugin.

Fixed error/warning logging noise on LogEOSSDK when platforms are created and destroyed without being ticked, especially in commandlet runs.

Fixed CompoundSubsystemEnum ignoring ESocialSubsystem::Primary and not creating a unique value for a given combination of subsystems.

Added missing CREATE_MIRROR_PLATFORM_SESSION checks in OnlineSessionEOSPlus.

Added logic to cache the updated Auth Token after a refresh in UserManagerEOS.

Addition of logic to make FUserManagerEOS robust to callbacks returning after module shutdown.

Added logic to return canceled error if an EOS purchase was canceled.

Added missing early error exit to FUserManagerEOS::QueryExternalIdMappings.

Fixed CacheDirectory issue with Android EOSSDK initialization

Fixed the purchase validation issue on OnlinePurchaseInterfaceCrossgen that was caused by initializing the OnlinePurchaseInterfaceCrossgen before the OnlineIdentityInterfaceCrossgen.

Deprecated:

The OSS Oculus plugin has been deprecated in UE 5.1 and is no longer supported. The Meta QuestPlatform plugin can be found on either the UE Marketplace or Oculus Developer site.

Removed:

Code for unused and deprecated GooglePlay Billing library. Actual dependency is brought through gradle.

Deleted deprecated OnlineSubsystemTwitch.

New:

Added getter for EOS platform handle in EOSVoiceChat, enabling sharing of the platform handle with other systems.

Reimplemented SetPlayerVolume for EOSVoiceChat, now there is SDK support.

Bug Fix:

Fixed a voice over IP problem on Android and, more generally, if the platform does not implement GetMicrophoneAmplitude.

New:

Added optional/opt-in webserver to WebSocket server using the already available functionality from the underlying libwebsockets implementation.

Added serving static content through the websocket server without taking an extra port for a webserver.

Added ability to serve directories on disk as http mounts.

Bug Fix:

Fixed memory leak in FWebSocketServer where some manually created arrays were not using delete.

Platform

API Change:

The use of an integer "Controller Id" to refer to both a logical user and a specific input device is being deprecated in favor of the new FPlatformUserId and FInputDeviceId types.

In 5.1 it is possible to convert between those types and the deprecated Controller Id, but this will not be available in a future version of UE when full support is added for multiple input devices under a single user.

New:

Don't add messaging endpoint unless Xbox console is available to avoid long hang.

Added support for PlatformUserId to clearly differentiate between logical users and input devices. Instead of using raw integers for both the controller Id and the user index, there are now different types for users and devices. To support this conversion there are utility functions in GenericPlatformMisc and the online identity interface that allow conversion between the new types and integer indexes.

Added pool support in MallocBinned3 for larger than default alignment (16). Previously these allocations would allocate in page-sized blocks which could lead to large memory waste.

Load DP on demand when using dp.override.

Added Getters for ShaderPlatform Name, the Shader Format of the ShaderPlatform, and the ShaderPlatformPropertiesHash as defined in DDPI

Bug Fix:

GDBPrinter bug fixes: Fixed TSparseArray printer. Fixed FName printer so that it doesn't use a hardcoded value to determine if it's a valid FName or not. Disabled broken TMap and TSet printers, but you will see output from the TSparseArray printer so you can see the stored values.

Remove XboxCommon implementation of PublishSymbols so it uses the same implementation as Windows and don't attempt to compress pdbs. Fixes issues with failing to publish large PDBs that the compression format does not support.

Fixed valid SDK filtering in Turnkey by adding missing fields to SDKDescriptor declarations.

Fixed a problem that was preventing Platform Extensions from calling StartupModule on new extension modules.

Fixed IterateDirectory() method on Unix, iOS, and Mac so it's behavior matched other platforms (Windows, etc.).

Disabled PLATFORM_ALLOW_ALLOCATIONS_IN_FASYNCWRITER_SERIALIZEBUFFERTOARCHIVE on platforms which use FPlatformMallocCrash during crash handling.

New:

Adding FirstMove events to windows. This is enabled with WindowsApplication.EnableFirstTouchEvent.

New:

Improved process for exporting to Raspberry Pi 4.

Added a new vendor ID for Broadcom.

Split ASTC and ETC2 support into separate texture formats for Vulkan, as ASTC may not be supported.

Bug Fix:

Added support for IsGamepadAttached on Linux.

Added support for Linux to search (using "which") for CLion outside of the default expected location.

Linux windows now have a reasonable minimum size, and no longer can be scaled down to 1 pixel wide/tall.

UE on Linux now locates any standalone Rider installation if it is either installed to the default location "/opt" (Rider Installation Guide), or anywhere else that is on the PATH.

Fixed an issue where global shaders would get cooked for Linux Server platforms if it had any targeted RHIs enabled.

The Chromium Embedded Framework (CEF) library that powers the Web Browser Widget has been updated to use Chromium's "Ozone" rendering backend under Linux. As a result, the Web Browser Widget now renders correctly in Linux environments that lack an X11 server, such as desktops running Wayland without the XWayland compatibility layer, and headless environments such as containers.

Fixed missing quotes in GenerateProjectFiles.sh.

Fixed QMake project generator defines.

Bug Fix:

PipelineCaches directories are no longer trimmed in pak memory optimization. These need to be queried to discern when it is appropriate to kick off shader loads while installing data.

PipelineCaches directories are no longer trimmed in .pak memory optimization, as they need to be queried to tell when it is appropriate to begin shader loads when installing data.

New:

Script added to retrieve Pixel Streaming Samples files from new repository in PixelStreaming/Resources.

Added Editor Streaming module for compositing and streaming of the Unreal Editor.

Pixel Streaming now uses WebRTC codec negotiation.

Pixel Streaming now supports custom protocols.

Pixel Capture plugin created which can capture pixel buffers and sample them at independent rates.

Added support for arbitrary audio input into Pixel Streaming.

Added a compute shader for faster I420 conversion when using VPX, this is faster than CPU readback and conversion in our tests.

Added peers can now swap roles between P2P and simulcast mid-stream. To test this new feature:

Simply toggle the PreferSFU toggle in the settings panel.

Click the new restart stream button in the settings panel.

The editor can now resize appropriately if requested by the front end when Pixel Streaming the editor.

PixelStreamingVCam supports camera control with ARKit.

Streamer will now attempt reconnection after a set delay instead of instantly.

Added embedded C++ signaling server, used for unit testing and some limited use cases where we cannot download servers (for example, offline usage in virtual production).

Added a new module in Pixel Streaming plugin called "PixelStreamingServers" that is the C++ API for launching a signaling server (embedded or downloaded).

Added datachannel support to SFU.

Added WebRTC C++ client behavior to pixel streaming system. This is used for developing unit tests.

Added a unit test that will start streaming, connect a client and check that a data channel message can be sent.

Added the ability for a user to start/stop streaming as needed through the use of PixelStreaming.StartStreaming and PixelStreaming.StopStreaming.

Added the ability for the stream resolution to be changed at runtime.

Added a ForceKeyFrame blueprints and C++ method which forces the module's default streamer to send a keyframe.

Added support for use of WebRTC version 96 with Pixel Streaming. Note: There are noticeable performance regressions introduced with this version that are being investigated. Version 84 remains the default.

Added the ability to stream the main Level Editor window to the browser.

Added a Pixel Streaming specific toolbar for starting and stopping streaming in the editor, as well as configuring some basic plugin settings.

Added ARKit transform support for controlling PixelStreamingVCam cameras with ARKit transform data received from the LiveLink app. See PixelStreamingVCamSession for handling of this data.

Added stat pixelstreaminggraphs that show real time graphs of Pixel Streaming stats.

Added -PixelStreamingInputController=Host (or Any) to optionally restrict stream inputs to a single host peer. The default is -PixelStreamingInputController=Any.

Added PixelStreamingServers utility to launch PixelStreaming servers from C++. (Added accompanying test too).

Added tests for FPixelStreamingSourceFrame, FPixelStreamingFrameMetadata, FPixelStreamingFrameAdapterProcess and FPixelStreamingFrameAdapter.

Added the ability to override the default InputDevice.

Added the ability to have multiple streamers.

Added support for LeftTriggerAnalog and RightTriggerAnalog to be sent as acceptable button press options in Pixel Streaming — even though they are analog inputs, some use cases require mapping them as buttons.

Added launch arg -PixelStreamingNegotiateCodecs to enable negotiating Pixel Streaming video codecs with the browser.

Default case: Negotiating video codecs is disabled and Pixel Streaming will only send a single selected codec, which can be configured using -PixelStreamingEncoderCodec=H264/VP8/VP9.

Improvement:

WebRTC version upgraded to 4664 (M96) on Windows.

Allow Editor dimensions to be set at launch time when Pixel Streaming editor with "-EditorPixelStreamingResX= and -EditorPixelStreamingResY=", or "-EditorPixelStreamingRes=".

Implemented more accurate Pixel Streaming frame time stats.

Fixed match viewport resolution browser side option.

Changes to improve performance of editor when Pixel Streaming plugin is enabled but not streaming.

Crash Fix:

Fixed PixelStreaming module state cleanup that was causing packaging crashes.

Bug Fix:

Fixed resolution changing which was broken in 5.0.

Fixed cirrus.js emitting ugly error message if config file was read only..

Fixed PixelStreaming controller input. PixelStreaming is now compatible with the new FGenericApplicationMessageHandler controller interface.

Fixed Pixel Streaming FPS CVar so that it correctly enforces FPS.

Fixed to make current Pixel Streaming compatible with older versions of UE signaling protocol where "playerConnected" message is not sent.

Fixed for format requests locking forever.

Fixed multi-peer Pixel Streaming not working with VPX codec.

Fixed so that NVENC now only needs to scale frames as needed, there was some extraneous scaling happening before.

Fixed on screen hud stats on startup that were not dismissable.

Fixed bug where SFU peers were unable to receive data channels messages from the streamer.

Fixed failing "connect" test where quality & input controller messages were being sent too early (before datachannel was established) for P2P peers.

Fixed PixelStreamingAudioComponent finding trying to find audio sink on a data-only peer and crashing.

Fixed PIXELSTREAMING_API exports on some files.

Fixed PixelStreaming.build.cs that was too harsh about excluding any file with 'node' in the name.

Fixed PixelStreaming.build.cs to exclude packaging the platform_scripts/cmd/coturn directory.

Fixed Vulkan fast texture copy codepath to not crash in some edge cases.

Removed:

Removed Pixel Streaming Samples as it has been moved to its own repository on GitHub.

Removed unnecessary CVarPixelStreamingWaitForTextureCopy due to refactor.

API Change:

In an unlikely case you relied on the previous behavior, set FSceneViewExtensionContext::bStereoEnabled=true in your code before calling FSceneViewExtensions::GatherActiveExtensions()

New:

OpenXR: Expose xrGetCurrentInteractionProfile to blueprint

Added setting to specify which PIE instances get the VR headset if multiple PIE instances are used.

Added PrimaryPIEClientIndex setting to Editor Preferences > Level Editor > Play > Multiplayer Options > Client.

Added features related to play area bounds to OpenXR.

Added a Blueprint to get the bounds and their origin in UE world space.

Added a Delegate to respond to play area updates.

Added basic support for blink and pupil info in eye tracking. Will be false/0.0 if this feature is not supported by the platform.

XR: Added keyword "HMD" to IsHeadMountedDisplayEnabled, and IsHeadMountedDisplayConnected

OpenXR: Added OnDestroySession to IOpenXRExtensionPlugin.

Added haptic Soundwave support for stereo sounds.

Added Support for Gauntlet automation to launch on HoloLens devices

Exposed parameters of a fake stereo device for tweaking in UI (PR #9224 contributed by ppchavan001).

Initial change to support setting PixelDensity in OpenXR.

Added pipelined access to PixelDensity, and checks to ensure that app-set PixelDensity is not more than the runtime actually supports.

OpenXR: Register with FCoreDelegates::VRHeadsetRecenter Now that FOpenXRHMD supports ResetOrientationAndPosition correctly, we can register with the FCoreDelegate for those clients.

Added support for multi-viewport on PC (D3D11/12, Vulkan) for stereo rendering and enabled by default.

Added mono pass from plugin driven views in OpenXR.

HMD extensions are now opt-in rather than opt-out when setting up a view family.

Added protected access to AllocateDepthTexture

Added Emulated world/tracker locked quad layers for OpenXR

Translucency light volume textures are now shared between both views of a stereo pair.

Made VSM debug view work in both eyes.

Removed Omni-Directional Stereo Capture (experimental)

Added "Emulate Stereo" level play option for standalone games for easier testing of rendering issues in VR without a headset.

Added pipelined support for NativePresent in FOpenXRRenderBridge

Added more ways to enable OpenXR validation (-openxrdebug, -openxrvalidation)

OpenXR PixelDensity: custom quantization of width In the scenario where we have an atlased stereo texture, we need to make sure each half of the texture is aligned by 8 (new Strata requirement). We can do this by manually quantizing the texture after applying pixel density.

Added Lumen hardware raytracing in VR.

Improvement:

Extracted MicrosoftSpatialAudio from WindowsMixedRealityInterop so that it can be used with OpenXR rather than WMR.

Changed CalculateRenderTargetSize assert so that it tolerates Game or Rendering thread.

Improved tooltip for ShadingRate Material attribute.

Bug Fix:

Fixed a typo in Epic_openxr.h

Fixed MicrosoftSpatialAudio when using MicrosoftOpenXR -

Fixed hololens target settings ini lookup.

Fixed code that used to run while the RenderThread did not exist, and thus ran on the game thread, this code now runs on the render thread.

Fixed FScheduler members being shadowed by FHoloLensRunableThread

Fixed SceneTextures.cpp using module lookup functions in the render thread that are only safe to use without locking on the game thread.

Added an accessor for this information to IStereoRendering.h and cached the values in the oculus HMD implementation. This cached value can be safely read on any thread.

VectorVM fix for arm64 Neon -Need return type of MakeVectorRegisterInt64 for Neon to match SSE.

OpenXRAR - avoid assert in GetDisplayTime when the openxr session is not synchronized. -Checking IsFocused before trying to get time. xrLocateSpace is only supposed to work when in the focused state. Our pins will retain their last known position. During pin creation they won't locate at all which should result in them maintaining their unreal world position.

Fixed AR Tracked Geometry 64 bit FVector.

VR PIE now correctly resizes the viewport

Fixed thread safety of XR LockModularFeatureList.

Fixed OpenXRHMD initialize space locations to avoid bad quaternions.

Changed OpenXR xrGetReferenceSpaceBoundsRect make ensure on failure into a warning.

Changed FPostProcessRectParams to support 2DArray textures

Fixed shadow rendering using multiviewport in VR.

Fixed translucency artifacts in VR.

Fixed SingleLayerWater in Instanced Stereo in VR

Fixed issue where ValveIndex_Left_Trackpad_Touch would never call release.

Enable ISR + multi-viewport for PSVR2

Fixed the Editor Viewport not restoring correctly after exiting VR Editor Mode

Fixed properly pipeline frame state from Game Thread to Render thread

Pass SV_ViewID to VIEW_ID as uint, no more casting to float

Fixed volumetric cloud rendering in stereo.

Fixed too dark mobile preview.

Fixed volumetric fog in VR.

Fixed artifacts with the distance field shadows in VR.

Fixed XR scene textures to use requested extents more uniformly.

Fixed crashing in forward when velocity output in base pass and MSAA are enabled.

Fixed Nanite rendering in VR

Fixed bind InstancedViewUB independent of active stereo rendering The shader compiler will enable ISR or Mobile Multi-View in shaders, independent of whether they are actively engaged in stereo rendering.

Fixed support for the left texture for the Quad stereo layer.

Disable max viewport resolution

Fixed crash in ImgMediaMipMapInfoManager with -stereoenabled.

Deprecated:

Remove GetScreenPercentage blueprint function deprecated since 4.19.

The XR system click/touch FKeys, which cannot be bound in OpenXR, have been deprecated.

Platform Mobile

New:

Added r.Mobile.DesiredResX/Y for Android and -mobileresx and -mobileresy commandline overrides as alternative to using r.MobileContentScaleFactor.

Set either r.Mobile.DesiredResX or r.Mobile.DesiredResY to a value greater than 0, otherwise r.MobileContentScaleFactor will be used. If you set both, r.MobileDesiredResX will be used. These values are in pixels, and X and Y correspond to the current orientation of the device. Whichever dimension you set, the other one will be automatically calculated to preserve the aspect ratio. The final resolution used will be clamped to the device window resolution for the orientation.

Fixed Shader Complexity Preview ES31.

Added the static method ShouldCompileShaderFrequency to filter frequencies for mobile platforms. This can be used to only allow vertex, pixel or compute shaders.

Bug Fix:

APlayerController now enables motion controls by default.

Mobile platforms have UE_COMMONINPUT_PLATFORM_SUPPORTS_TOUCH set to true for the CommonUI plugin.

Mobile Texture Lookup Scene Depth now outputs WorldZ instead of DeviceZ.

Vulkan Shader Compiler now checks the Shader Format instead of the Shader Platform.

Added a method to check if Mobile post-processes should allow flipping. This is used to prevent Scene Captures from being flipped, as they are used as textures and sampled in the main scene.

Backbuffer now sets the TexCreate_ResolveTargetable flag for cases when MobileHDR is set to false and MSAA is enabled.

Removed:

SceneDepthAux removed from certain platforms.

New:

libUnreal.so is now built against static libc++ due to issues with overriding new and delete. All our out of the box dependencies were updated to reflect this change. This was necessitated due to the engine upgrading to NDK 25b. Unreal Build Tool will scan for dependencies and throw an error if they require libc++_shared.so. You can disable this check using the bDisableLibCppSharedDependencyValidation option. You should update all dependencies in your project to build against static libc++, as mixing both static and shared libc++ within one app is unsupported by NDK and known to cause startup crashes. We still include libc++_shared.so in your .apk by default to give provide room to upgrade your project. If you have successfully upgraded your project to eliminate any dependencies on libc++_shared.so, you can skip packaging it using the bSkipLibCpp option within the /Script/AndroidRuntimeSettings.AndroidRuntimeSettings group of your .ini file.

To reduce binary size in Android shipping builds, all symbols except the ones called from Java are now hidden by default. Debug\Development\Test builds still have default visibility to allow symbolication of crashes and asserts.

Updated libunwind to the latest version from Github.

Android toolchain now supports both full and thin LTO options. You can enable these with any of the following options:

TargetRules

bAllowLTCG or bPreferThinLTO

UBT command line arguments: -LTCG/-ThinLTO. Please note that you have to enable both options if you want to enable ThinLTO. On Android, unlike on other platforms, PGO doesn't assume LTO, so if you have PGO builds and want to have LTO enabled, you'll need to enable LTO manually. This is due to toolchain issues, as having PGO assume LTO can cause extremely long build times and out of memory linker crashes.

Added Clang Analyzer support to Android toolchain. This can be enabled using the -StaticAnalyzer UBT command. Refer to TargetRules.cs for more information.

Added Android Toolchain option to disable stack protector. It can be disabled using the bDisableStackProtector option in the /Script/AndroidRuntimeSettings.AndroidRuntimeSettings group of your config file (*Engine.ini).

Added file and line number logging for UnrealPluginLanguage (UPL) warnings and errors.

Raised minimum Android version supported to 8.0 (SDK level 26).

Set the minimum Java compile SDK level for Android to 30.

If the -BypassGradlePackaging option is passed to UnrealBuildTool, Android packaging will be faster when only libUnreal.so changes.

Individual OpenGL uniform buffers now have the option to force using real uniform buffers instead of emulated uniform buffers.

Added Mobile Fidelity FX FSR as a plugin.

Added support to SPIRV to generate structs from arrays with constant access which allows OpenGLShaderCompiler. This improves packing of shader data.

Added ANDROID_SDK_HOME for AGDE to the SetupAndroid script.

Crash Fix:

Added SPIR-V patch pass to fix driver crashes on Android 10.

Fixed a possible crash on Macs where the editor would not properly shut down due to missing Turnkey support for Android.

Bug Fix:

Android builds macOS now uses the rootProject path for AFSProject construction for AndroidFileServer. This fixes broken build processes.

Because JCenter is now a read-only repository, mavenCentral repository is now preferred before JCenter. This is in compliance with Google's guidance regarding JCenter.

Removed deprecated AppCache settings calls from WebViewControl.

Fixed issues with Adreno version checks in MediaPlayer. These now use a more detailed regex search instead of parseInt to determine the modelnumber.

Fixed misnamed functions for background and foreground delegates in Android media plugins.

Added a check for ro.soc.model for ConfigRules chipset matching.

Fixed installing of the overflow OBB file for Android.

Fixed a null reference exception when running Turnkey on an installed engine build without Android support.

Android: Prevent hang during pause by flushing GT before blocking RT During Android Pause, the Event Thread (ET) will block the Rendering Thread (RT), followed by waiting for a Game Thread (GT) command to complete. With Vulkan enabled, there could be a scenario where the game thread (GT) is waiting on the RT to flush. If the GT is waiting on RT while the ET blocks the RT, the ET will then deadlock waiting for GT. Instead, the ET can wait on the GT to finish first, with an unblocked RT.

Added PropagateAlpha when generating the manifest for Android.

Android: Prevent hang during pause by flushing GT before blocking RT During Android Pause, the Event Thread (ET) will block the Rendering Thread (RT), followed by waiting for a Game Thread (GT) command to complete. With Vulkan enabled, there could be a scenario where the game thread (GT) is waiting on the RT to flush. If the GT is waiting on RT while the ET blocks the RT, the ET will then deadlock waiting for GT. Instead, the ET can wait on the GT to finish first, with an unblocked RT.

Changed the SDKManager check order for the SetupAndroid script.

Added missing support for Turnkey for Android on Mac.

Deprecated:

Removed legacy Visual Studio and NVidia Tegra Nsight Android project generators. These are now replaced by Google's AGDE.

New:

Fixed IMappedFileHandle::MapRegion to map files or regions smaller than the page size.

New:

Ignore iTunes DLL if the version number cannot be parsed expected.

Added tvOS Bink Audio Decoder library.

Bug Fix:

Fixed multiple bugs in MallocBinned, the default allocator for iOS.

Fixed iOS Remote Mac toolchain cwrsync home directory detection. This was causing issues with SSH key generation in some Windows Active Directory environments.

RAD

New:

Added the latest Bink binaries.

Rendering

New:

Added a reference motion blur mode to MRQ In this mode, the post-processed motion blur is ignored and the Path Tracer accumulates frames across temporal samples instead, denoising only once per-frame instead of once per-temporal sample. This can be used to workaround limitations of the post processed motion blur effect, and allows pushing the temporal sample count higher than otherwise possible.

Added experimental temporal denoising for offline path tracing that is spatially denoised. It gives a final touch to mitigate the temporal instability while preserving fine details. Enable the temporal denoiser in MRQ by adding the console variable 'r.PathTracing.TemporalDenoiser 1' when Path Tracing Denoising is enabled in the Post Process Volume Path Tracing settings when Denoiser is enabled.

Hair strand rendering now allows a negative threshold to disable the Path Tracer invalidation to work around cases where the hair simulation does not fully settle. It also removes the clamp so the threshold can be increased past 1cm without fully disabling it.

Added console variable r.SkinCache.SkipCompilingGPUSkinVF which enables you to skip compiling all GPU Skin Vertex Factor variants (except the pass through) if you are using GPU Skin Cache. The idea is that if you are using GPU Skin Cache and all Skeletal Meshes can fit within the cache at runtime, you only need the global compute shaders to perform GPU skinning. This means you will never need any GPU skin factory variants for any material, so they can skip compiling these shaders for significant savings.

Don't compile GPU Skin Virtual Factories for special materials when 'r.SkinCache.SkipCompilingGPUSkinVF' is enabled. This accounts for roughly a couple thousand shaders across all our special engine materials, and these shaders will not be used, even for special cases in the engine, so it is safe to skip them.

Only compile ‘FTrivialMaterialCHS' when the proper console variables have been turned on. This saves on having to compile this shader variant for every material. In internal test projects, this saves ~2,000 shaders of ~3% of all shaders, and saves 15 shaders from being compiled in WorldGridMaterial in that same project.

Avoid calling ‘Get Material With Fallback' which was forcing compiling of shaders for materials even when On Demand Shader Compile (ODSC) was turned on. In CitySample, we went from compiling 125,000 shaders down to 9,000 shaders, which went from spending 13 minutes submitting shaders down to ~15 seconds. Calling ‘GetIncompleteMaterialWithFallback' is safe to do in this case, since we don't actually need shaders from the material and are simply querying it for blend mode and for certain ray tracing flags.

When running with On Demand Shader Compilation (ODSC), do not try to fetch fully completed shader maps from the DDC, which improves latency.

MRQ will submit remaining jobs for compilation for all the materials in the world and block on the results before rendering.

MRQ

When running with ODSC in the editor Materials can have incomplete or partial shader maps. Shaders might be missing and we need to ensure all of them are compiled so we don't ever render a frame with the default material.

This logic will run before every render frame to properly handle new materials being loaded.

If there are no incomplete materials this logic is a no-op and very lightweight. ~600us.

UMaterialInterface

Added a function to UMaterialInterface to query if we have a complete set of shaders.

Made CacheShaders and IsComplete part of the public interface of UMaterialInterface.

Optimizations

31x speedup to 'SubmitRemainingJobsForWorld'when there is no work to do. This went from 20ms down to 0.645ms. It only performs the material update context (which flushes rendering commands) when there are materials that actually need to do work.

This turns 'SubmitRemainingJobsForWorld' into a no-op when there is no work.

Misc

When blocking on all shader map be sure to spawn a slow dialog so we can see the progress of shader compilation. - Only spawn the dialog (a heavy operation) if there are jobs.

Always show the dialog even in PIE.

Enabled Editor On Demand Shader Compilation, which drastically reduces the number of shaders compiled when working in the editor. On average, a 1.6x speedup when opening the editor and a map in various projects. Best case, a 2.23x speedup.

Added a way to override the Sky Atmosphere visual sun disk radius from the material graph independently from the directional light radius.

Volumetric fog now handles height fog start distance.

When running with ODSC in the editor Materials can have incomplete or partial shader maps. In other words, some shaders might be missing. If a render system requires all shaders to be present and can't use ODSC functionality to compile the necessary shaders we need a mechanism for compiling just the missing shaders.

Added UMaterialInterface::CacheShaders which is implemented for UMatetrial and UMaterialInstance. The call is just forwarded along to CacheResourceShadersForRendering and InitStaticPermutation respectively.

You can call CacheResourceShadersForRendering multiple times (even with a completed shader map) and it will not recache uniform expressions. If the Resource's shader map is complete the function is a no-op.

FObjectCacheContext can accept a UWorld and will only return primitives that are in that world.

Added a function SubmitRemainingJobsForWorld(UWorld* World, EMaterialShaderPrecompileMode CompileMode) that will iterate all materials used by primitives in the world and compile the missing shaders.

SubmitRemainingJobsForWorld() is used in various scenarios in the editor to ensure al shaders are compiled for all materials before proceeding.

Explicitly try to compile UI and PP materials. Since we don't know which ones are used in the given world we just have to iterate all loaded ones. This is a potential area of optimization.

If there are already complete shader maps (if you are not running with the shader job cache), SubmitRemainingJobsForWorld is fast and results in a no-op for each material.

Added an ‘illuminance meter' to the HDR (Eye Adaptation) visualization mode that shows mean and accounts for viewport rect.

Fixed shadowed local lights looking dull at high exposure inside the volumetric fog.

Fixed a typo in RayTracingMaterialHitShaders.usf.

Added Vulkan external memory support.

Added scoped CPU markers to various D3D shader compiler functions to make this easier to profile when shader compilation is done in process.

Added Global Shader Types to the ‘DumpMaterialShaderTypes' commandlet. This sorts global shaders alphabetically so diffs between output is stable. Also, added stats for scanning the asset registry and dumping the stats, and added a separate global shaders histogram, but it is currently not being dumped into the output log. The full asset path is reported for materials and material instance constants to make them easier to find in the editor.

Added Sky Atmosphere transmittance on forward shaded translucent when per pixel mode is selected on the atmospheric Directional Light.

Added an analytics provider to ‘DumpMaterialShaderTypes' to track nightly statistics across various projects. It calculates the total shaders in the Default Materials as a good metric. This impacts editor startup time and is the default materials are the worst case scenario for usage flags. It only gathers analytics if passed in on the commandline.

Added the ability to pass ‘-analytics' through automated testing. The following analytics are reported: ProjectName, BuildVersion, Platform, ShaderPlatform, TotalShaders, TotalMaterials, Total MaterialInstances, TotalGlobalShaders, and TotalDefaultMaterialShaders.

Added an automated test to run the DumpMaterialShaderTypes commandlet, which is useful for catching shader count regressions on projects.

Added a new test called "ShaderTypeRegressionTest" which can be run with the command line: RunUAT BuildGraph -Script=Engine/Build/ShaderTypeRegressionTest.xml -Target="Shader Type Regression" -append:Projects="EngineTest" -append:Projects="CitySample" -append:Projects="Lyra" -append:Projects="MedievalGame[UnrealEditor]"

The results are saved to Engine\Programs\AutomationTool\Saved\...

Volumetric Clouds is now precompiled through DXC. This accelerates volumetric domain materials (cloud shaders) compilation time by at least 6x.

Replaced UE4 references with UE5 in related UnrealLightmass files.

Added DumpGPU viewer script for Linux and Mac. Currently requires the Chrome Browser to view the dump files.

‘Set Source Cubemap Angle' for Skylight components is now exposed in Blueprints.

Added a warning when the maximum number of active ray tracing lights is equal to or greater than ‘RAY_TRACING_LIGHT_COUNT_MAXIMUM'.

Exposed ‘BuildLightMaps' command to Python and Blueprint Utilities.

Stat Groups are added to the list of stats printed when running "stat help"

Changed default value for World Position Offset culling distance in ray tracing to 120m.

Added support for multiple reflection captures for Single Layer Water materials.

The GPU Dump Viewer now dumps both .sh and .bat so a dump can be opened either on Mac, Linux, or Windows regardless of the platform the files were dumped from.

Added UE-DumpGPUPath environment variables to dump across Perforce workspaces at the same location by default on a dev machine.

Implemented proper support for togglable Stationary direct lighting on mobile and deleted 'baked Stationary as Static' path. This change makes high quality and low quality lightmaps have unified lighting content and now they differ only in encoding.

Added support for CustomDepth in Translucency pass on Mobile LDR.

Refactored mobile Custom Depth and Stencil to line up with Desktop on all mobile platforms.

Clustered local lights and reflections are now supported on Mobile Forward and Deferred rendering paths. Local light shadows are supported on Mobile Forward and Deferred, and need to enable full depth prepass to generate the ShadowMaskTexture.

Disabled Simple Lights when using the Mobile Forward Renderer.

Mobile now supports additional shading models, such as Two Sided Foliage, Cloth, and Eye. They use the same shading models as the dynamic lighting code path on Desktop.

Reduced the size of UParticleModuleSpawn to 224 bytes to fit in a smaller FMallocBinned2 pool.

Reset UniqueTables instead of emptying it to reduce allocator churn. Reset FCommandListResourceState::ResourceStates instead of emptying it to reduce allocator churn.

Changed the Reflection Capture's encoded HDR data to RG11B10 format.

Skip reflections for simple translucent materials for both Mobile Forward and Deferred rendering paths. Translucent materials will fall back to single reflection or sky capture on Mobile Deferred if clustered reflection is disabled.

Enabled Ambient Occlusion on Mobile LDR.

Initial work to support rendering with LWC-scale position. The basic approach is to add HLSL types FLWCScalar, FLWCMatrix, FLWCVector, and so on. Inside shaders, absolute world space position values should be represented as FLWCVector3. Matrices that transform into absolute world space become FLWCMatrix. Matrices that transform from world space become FLWCInverseMatrix. Generally, LWC values work by extending the regular float value with an additional tile coordinate. Final tile size will be a trade-off between scale and accuracy. Value represented by a FLWCVector thus becomes V.Tile * TileSize + V.Offset. Most operations can be performed directly on LWC values. There are HLSL functions like LWCAdd, LWCSub, LWCMultiply, LWCDivide. The goal is to stay with LWC values for as long as needed, then convert to regular float values when possible. One thing that comes up a lot is working in translated (rather than absolute) world space. WorldSpace + View.PrevPreViewTranslation = TranslatedWorldspace. Except 'View.PrevPreViewTranslation' is now a FLWCVector3, and WorldSpace quantities should be as well. So that becomes LWCAdd(WorldSpace, View.PrevPreViewTranslation) = TranslatedWorldspace. Assuming that we're talking about a position that's "reasonably close" to the camera, it should be safe to convert the translated WS value to float. The 'tile' coordinate of the 2 LWC values should cancel out when added together in this case. Materials are fully supporting LWC-values as well. Projective texturing and vertex animation materials that I've tested work correctly even when positioned "far away" from the origin. Lots of work remains to fully convert all of our shader code. There's a function LWCHackToFloat(), which is a simple wrapper for LWCToFloat(). The idea of HackToFloat is to mark places that need further attention, where I'm simply converting absolute WS positions to float, to get shaders to compile. Shaders converted in this way should continue to work for all existing content (without LWC-scale values), but they will break if positions get too large. General overview of the changes are as follows:

LargeWorldCoordinates.ush - This defines the FLWC types and operations GPUScene.cpp, SceneData.ush

Primitives add an extra 'float3' tile coordinate. Instance data is unchanged, so instances need to stay within the single-precision range of the primitive origin. Could potentially split instances behind the scenes (I think) if we don't want this limitation HLSLMaterialDerivativeAutogen.cpp, HLSLMaterialTranslator.cpp, Preshader.cpp

Translated materials to use LWC values SceneView.cpp, SceneRelativeViewMatrices.cpp, ShaderCompiler.cpp, InstancedStereo.ush

View uniform buffer includes LWC values where appropriate

Added Blueprint function "Resize Render Target 2D" to support changing the resolution of a Render Target.

Added an editor utility script function "Set LOD Screen Sizes" in "Static Mesh Editor Subsystem" to set the LOD screen size for static meshes. Useful for batch modification of LOD settings.

Scene Capture: Added Blueprint function node "DeprojectSceneCaptureToWorld" to support translating UV coordinates in scene capture space to a world space ray, similar to "DeprojectScreenToWorld" which operates on the player camera. Allows hit tracing operations into scene capture surfaces without requiring C++ code. A typical approach involves feeding "DeprojectSceneCaptureToWorld" the output of a "Find Collision UV" node (requires "Support UV From Hit Results" enabled in Physics Settings). The "Find Collision UV" node receives a Hit reference from a "Line Trace By Channel" node. You can then use the output World Position and World Direction as a secondary ray to feed into another call to "Line Trace By Channel" to find the collision in the Scene Capture.

Added a new console variable r.SkeletalMeshClothBlend.Enabled, which is set true by default. When the variable is false, the cloth weight used in skin rendering is set to 0 and the rendered mesh will effectively ignore the output of the cloth simulation.

With Vulkan, a UE4 specific fix has been disabled on UE5 that was causing performance hitches.

Move VulkanMemory.h to Private for easier hotfixing in the future.

Refactored Layers and Extensions for the following on Vulkan:

Split code for layers and extensions.

Keep string arrays for layer management, and share as much code as possible between device and instance layers.

Create a new class for extensions and manage them through a single flow.

Package the code for the extension and its features+properties together in a single place, so the device code only iterates on loops of generic classes.

Keep distinct states to track if an extensions: is supported by the engine, is enabled in the engine, is supported by the driver at runtime, is activated at runtime.

If an extension is present but a required feature isn't, disable the extension.

Remove feature structs from Vulkan Device when they were only used for init.

Track promotion status of extensions (for future dev).

Revisit some 'per platform' extensions that were enabled on all platforms.

Read Skeletal Mesh render data from streaming bulk data so the editor can load the cooked data that is not cooked in line. This fixes editor-only renders the highest LOD when using cooked data as only the highest LOD is cooked inline.

Added validation for invalid custom water bodies (no water mesh specified).

Added support for Large World Coordinates (LWC) on GPUSkinnedVertexFactory and SkinCache shaders.

Implemented GPUSkinCache debug visualization modes. 'Overview' mode shows skin cache on/off, recompute tangents on/off. 'Memory' modeshows skin cache memory consumption per sk mesh, includes RT if sk mesh uses a separate RT entry *) 'RayTracingLODOffset` shows RT LOD index offset from raster LOD index.

Fixed skeletal mesh previous frame local-to-translated-world position in large world coordinates for both GPUSkinVF and LocalVF PassThrough.

The r.UseLegacyMaintainYFOVViewMatrix console variable can now be set in config files.

Implemented support for asynchronous creation and deletion of FRenderResource. The resource list uses a thread local free list that is coalesced later.

Added support for FUintVector3 & FQuat4f as shader parameters.

Added support for callbacks to simulate any-hit and intersection shaders in inline ray tracing.

Added new ray tracing debug modes. ‘Dynamic Instances' mode shows instances that go through a dynamic path. ‘Proxy Type' mode shows instances colored by proxy type hash. ‘Picker' allows picking instances/triangles with a mouse to show BLAS and instance info.

Added support for "Distant Lights" to Virtual Shadow Maps (VSM), making it possible to support far more local lights with VSM shadows enabled by forcing caching, reducing page-table size, and round-robin updates on lights with a small screen-space footprint. Disabled by default, it can be enabled by setting r.Shadow.Virtual.DistantLightMode=1.

Virtual Shadow Maps now support split screen rendering with caching and correct page marking.

Changed how cards guides are generated at import time. This improves accuracy for picking the correct principal direction used for generated guides.

Changed hair cards guide to have a root/tip color to make debugging easier.

Added planar reflection support for hair strands.

GatherRayTracingWorldInstancesForView was split into several parts in order to run most of the work asynchronously. This saves up to two-thirds of the GatherRayTracingWorldInstancesForView rendering thread critical path time in large projects. The main rendering thread cost is now FPrimitiveSceneProxy::GetDynamicRayTracingInstances(), which currently can't be moved to a task.

The NVidia UReflexBlueprintLibrary API is now available to other modules.

Added Rect Light texture atlas support. This allows a single texture binding for all textured area lighting.

Added a project setting to disable per-object translucency shadows (disabled by default). To use translucency self-shadowing you must now enable this project setting. The Console Variable for this setting is r.Shadow.TranslucentPerObject.ProjectEnabled.

Improved groom decimation accuracy and fixed invalid hair decimation when the decimation factor is larger than 0.5.

Added Order Independent Transparency per-pixel sorting support for translucent Materials (experimental). Order Independent Transparency must be enabled in Project Settings and is off by default. It is currently only supported on PC Dx12. This is the initial step for fine grain/per-pixel sorting.

Added precomputed BSDF directional albedo path for non-editor target. This avoids running the BuildTable pass which is too long on low-powered platforms.

Changed the representation of hair strands from a cross to a quad cylinder to avoid self-shadowing artifacts and prevent discontinuities between segments.

GPU texture formats for 32 bit float uncompressed pixels are now available (R32F and RGBA32F). Some platforms only support point/nearest sampling of 32 bit floats.

Added previous position support for geometry cache and fixed hair strands motion vector when continuous level of detail (CLOD) is used.

Added Groom Binding listing, preview, and skeletal mesh animation, within the Groom Asset Editor.

Moving some of the FRayTracingScene initialization work into an asynchronous task which:

Adds FRayTracingScene::BuildInitializationData, which builds FRayTracingSceneWithGeometryInstances.

Adds FRayTracingScene::CreateWithInitializationData() that consumes FRayTracingSceneWithGeometryInstances data.

Runs BuildInitializationData as soon as ray tracing instance culling tasks finish.

Waits for scene initialization data in FDeferredShadingSceneRenderer::DispatchRayTracingWorldUpdates, which saves ~0.2-0.3ms of rendering thread time in large scenes.

Unified the 8 separate variations of WriteRawToTexture_RenderThread into a single function on FTexture2DDynamicResource.

Implemented and enabled two-pass Hierarchical Z-Buffer (HZB) occlusion culling for Virtual Shadow Maps when using Nanite geometry, making it render correct shadows under all forms of disocclusion. The console variable for this setting is ‘r.Shadow.Virtual.UseHZB'.

Improved and simplified 'ShaderPrint' to be the unique interface for outputting debug information from shaders. It regroups string printing, line, triangles, and widget (experimental) drawings into a single interface.

Added Groom Alembic supports for GroupName.

Added RootUV, Color attributes, Roughness attributes, and Precomputed Guide Weights information when importing a Groom Asset.

Added r.Shadow.Virtual.Cache.ForceInvalidateClipmaps that can be used to force invalidation for Virtual Shadow Map clipmaps, even when caching is enabled. This is useful when the light is constantly invalidating (moving sunlight, for example) to reduce cache-management overhead.

Changed voxelization to use an adaptive voxel size based on screen projection. This significantly reduces the cost of voxelization, shadow masks, and transmittance masks when grooms are further away from the camera.

Reduced groom binding data size by deduplicating unique triangle data. The data size of the resulting binding asset type is reduced to approximately 1/5 of the original.

Ray Tracing static primitive LOD calculations are now run asynchronously, as results are only needed much later for the FRayTracingSceneAddInstancesTask. This allows GatherRayTracingWorldInstancesForView() to start earlier on the rendering thread.

Disabled primitive octree culling (console variable 'r.UseVisibilityOctree') by default as this causes visibility culling issues because of the limited extent of the tree (HALF_WORLD_MAX).

Added tangent debug mode to the Groom Asset Editor.

Added ray tracing Material evaluation to hair strands and custom primitive intersection.

Fixed hair strands shadow culling when a hair instance is not visible in the primary view.

Added per-object triangle sorting per view in order to improve translucent ordering artifacts.

Implemented Large World Coordinates (LWC) support of Mesh Distance Fields data and related techniques.

Batch Top Level Acceleration Structure (TLAS) builds on platforms that support it.

Ray Tracing LightGrid is now calculated in translated world space.

More than one PreviewPlatform can now use the same ShaderPlatforms.

Improved expand bias in Distance Field Shadows by calculating the bias applied to two-sided meshes proportional to voxel size. You can adjust this bias with the console variable 'r.DFShadow.TwoSidedMeshDistanceBiasScale.'

Global Signed Distance fields are now updated in translated world space. The clipmap center is used as the origin of translated world space during the update.

Added console variable flags that automatically modify the KeyString when modified. The following KeyStrings are modified based on platform. The console variable r.MobileHDR is using this system now and others will follow in future releases.

ECVF_GeneralShaderChange = 0x200 modify the Shader KeyString for All Platforms.

ECVF_GeneralShaderChange = 0x400 modify the Shader KeyString for mobile Platforms.

ECVF_GeneralShaderChange = 0x800 modify the Shader KeyString for Desktop Platforms.

Create loose parameters uniform buffer to encapsulate GPUSkinPassThroughVertexFactory PreviousPositionBuffer. These changes ensure failure in MessPassProcessor.cpp in debug_editor build, due to PreviousPositionBuffer being a loose SRV parameter.

Enabled Hardware Ray Tracing (shadows, reflections, ambient occlusion, global illumination) and the Path Tracer to now work in large worlds.

Added support for capsule shadows in Large World Coordinates (LWC).

Added support for multiple layers in FRayTracingScene.

Added epsilon trace support in Raytraced Shadows to avoid self intersections.

Changed ShaderArchive, GlobalShaderCache, ShaderDebugInfo and Autogen to use ShaderPlatformName and not ShaderFormat when naming their output files.

Updated MeshUtilities::GenerateStratifiedUniformHemisphereSamples to use concentric disk sampling.

Support specifying MaxAttributeSizeInBytes in FRayTracingPipelineStateInitializer instead of always using RAY_TRACING_MAX_ALLOWED_ATTRIBUTE_SIZE.

Improvement:

Updated the Base Shape's material in Engine Content because it could cause invalidation of automatic image tests. The base color was changed from a value of (1, 1, 1, 1) to (0.9, 0.9, 0.9, 1.0). This change affects all base shapes (sphere, box, cylinder, and so on) that use the base shape material. Having a base color of 1.0 represents a physically unrealistic material that reflects 100% of all incoming light, which can create strange results where light never attenuates.

Increased the Sample Per Pixel limit in the user interface for ray tracing passes.

Adds a viewer console for GPUDumpViewer that can detect errors in the dump, such as incomplete dump.

Improved the velocity precision on Android GLES platforms by using UINT format instead of FLOAT format.

Improved the quality of AlphaToCoverage on mobile.

Upgraded Vulkan SDK from 1.2.162.0 to 1.3.204.0.

Improved VulkanRHI GPU rendering with earlydepthstencil.

Added texture address mode member to volume textures to allow control of all three axes at once.

Offloaded GPU scene uploads to an async task.

The HDR tonemapper is now using ACES 1.3.

Converted volumetric lightmap textures to RenderDependencyGraph (RDG).

Ported GPU scene buffers to RenderDependencyGraph (RDG).

Improved BuildHiddenComponentList performance by ~2ms in split-screen by expanding the hidden actor's components directly instead of doing it every frame.

Removed cases of AddCopyToResolveTargetPass which either weren't necessary or weren't performing multisample resolves.

Converted scene reflection capture path to RenderDependencyGraph (RDG).

Conversions from the working color space (as set in rendering settings) are now correctly accounted for in the CombinedLUT and tonemapper.

Improved water body map check error messages.

Renamed the editor experimental setting bEnableAsyncSkeletalMeshCompilation to bEnableAsyncSkinnedAssetCompilation.

Moved scene texture config and parameters into the Engine Library.

Moved scene renderer deletion off the render thread.

Moved RenderDependencyGraph (RDG) builder destruction off the render thread.

Moved dynamic mesh passes and BeginSceneOcclusion off the render thread.

Replaced thread-local MemStack with ConcurrentLinearAllocator across the renderer.

Refactored the ray tracing geometry update logic for Skeletal Mesh to simplify its process. This includes:

All skin cache entries needing RT geometry update are processed altogether in end-of-frame update whether batch dispatching or not, simplifies the logic.

Transition buffers to read immediately after skin cache DoDispatch calls, simplifies the logic.

No longer cache the flag to indicate whether RT geometry needs to be rebuilt, the logic is calculated directly when updating RT geometry.

Improved hair strands root UV precision.

Improved the performance of heightfield distance field management.

Added the Frequency name to the "Unrecognized shader frequency" Shader Compiler error.

Improved support for callable shaders.

Reduced memory usage during RayTracingScene setup.

Optimization:

Reduced GPUSkinPassThrough vertex factory shader permutations by merging it into local vertex factory. PassThroughVF is kept as a wrapper class.

Reduced morph target vertex factory shader permutations by merging it into the GPUSkin vertex factory.

Reduced multi influence cloth vertex factory shader permutations by merging with single influence cloth vertex factory.

Crash Fix:

Fixed a potential crash where deleted primitives could potentially be put into the ray tracing mesh command cache even though their resources were already released.

Fixed a potential crash in Movie Render Queue from null pointer dereference when searching MRQ setting classes.

Made some Volumetric Fog console variables safe from causing a crash to occur.

Fixed a crash when attempting to load ray tracing shaders when ray tracing is disabled.

Removed an assert that was firing when rendering hair.

Fixed an assert triggering because baked depth data was found to be invalid.

Fixed a debug crash when GPUScene and modulated shadow are enabled.

Fixed a crash while cooking Android with Lightmap Virtual Texturing enabled.

Fixed a crash that could occur when using High Resolution Screenshot with ‘Use custom depth as mask' enabled on Mobile Preview.

Fixed crash on Vulkan when trying to read data from TextureCubeArray.

Fixed a rare Vulkan RHI crash caused by an incorrect instance count when drawing indirect lines.

Fixed random crash occurring in HLOD builder commandlet, where we're hashing landscape texture source data while potentially asynchronously building textures. UTexture2D::GetSizeX() / UTexture2D::GetSizeY() should be prevented in those cases, since unlike in the landscape editor, nothing ensures that FinishCachePlatformData() is called on those textures and the returned sizes end up being wrong / thread-unsafe. Also fixed a couple of places where we were not using the FTextureSource's data (even though those calls should be fine since they happen in a place where texture compilation is done)

Fixed a crash that occurred when the bone name setup in a GroomComponent was incorrect.

Fixed a crash with Hair when per-pixel linked list (PPLL) rendering is enabled, and hair groom are selected, proxy geometry is queried/rendered.

Fixed a crash when using Materials with the UseHairStrands option enabled on a non-groom geometry.

Fixed a crash when rendering hair strands with the Path Tracer when hair length scale was lower than 1.

Fixed a crash that occurred when hair strands were rendered without any voxelization.

Fix a crash that occurred when setting curve decimation above one.

Fixed a crash that occurred when the number of DistanceField Mips was higher than DistanceField::NumMips.

Fixed crash in FHZBOcclusionTester when MapResults is called before Submit.

Bug Fix:

Fixed some issues that could occur when ‘ShowFlag.Rendering' is disabled.

Fixed Sky Light Capture not working correctly when toggling effect quality level.

Fix an issue with ‘GetMaxNumInstructionsForShader' that reported the incorrect instruction count for the given shader type. The function was not checking to see if the shader type in the pipeline was the same as the shader type we are asking for.

Applied fix for Volumetric Cloud to work with Large World Coordinates (LWC).

Ensure slow task dialog is shown when blocking ‘on all shader' maps to be compiled. This way we can see the progress on how many shaders are being compiled.

FFloat16 is not currently included in TShaderParameterTypeInfo, and increasing its array count will not increase its NumRows as intended. Simply hardcode correct values.

Do not allow ‘r.SkinCache.SkipCompilingGPUSkinVF=1' on mobile platforms (FeatureLevel == ERHIFeatureLevel::ES3_1). Some mobile platforms have a limit on how big buffers can be for skin cache positions. If we ever exceed this amount on a specific mesh, we skip the skin cache operation and need to fallback to a GPU Skin Shader. Since we don't know which shaders will be needed on a per-mesh basis, we must disable this feature and assume we need GPU Skin Shaders for ‘all materials'.

Fixed LoadAction to keep previous FinalLightingAtlas content if it was produced earlier (fix issue in Vulkan).

Prevent shifts by a negative value, which addresses static analysis warning: warning V610: Undefined behavior. Check the shift operator <<. The right operand is negative ('....' = [-1..254]) - Texture Resolution will be 1.

Fixed Sky Atmosphere not updating correctly the cached camera aerial perspective buffer settings after console variable tweaks.

Fixed a potential NaN in cloud depth texture with half float.

Applied a fix for broken fog due to Large World Coordinates (LWC).

Fix Game Thread and Render Thread access issues when performing shader compilation using FMaterial.

SubmitCompileJobs was assumed to be render thread only. Make this explicit in the function name and add a render thread check.

Added SubmitCompileJobs_GameThread to perform shader compilation submitted from the Game Thread safe.

Keep a ref to a GameThreadPendingCompilerEnvironment because the one on the GameThreadShaderMap goes away after we clone.

Added render thread check to GetRuntimeVirtualTextureOutputAttibuteMask_RenderThread.

Move simple enum types from ShaderCompiler.h to ShaderCompilerCore.h so we can access EShaderCompileJobPriority in MaterialShared.h

Fixed incorrect usage SubmitCompileJobs that was submitted from the Game Thread using the Render Thread maps.

Further reducing the geometry collection BLAS build count. a) Move the build out of the section loop so that we add one BLAS per geometry collection. b) Create the ray tracing geometry but delay the BLAS build later to dynamic raytracing geometry update.

Fixed geometry collection performance issue by creating one TLAS per geometry collection instead of one per transform.

Fixed a shader issue that was evident with SpeedTree foliage.

Fixed an issue with DumpGPU when only the 32-bit version of Chrome Browser is installed.

Fixed an issue with calling the DumpGPU command on mobile platforms.

Fixed an issue with DumpGPU's resource search by saving all resource descriptors into a single Base/ResourceDesc.json file.

Added dump timing measurement details to log when using DumpGPU.

Fixed an issue with ‘OpenGPUDumpViewer.bat' when a parent directory has a space in the file path.

Fixed issues with ray tracing translucency looking overly bright when the tonemapper is disabled.

Fixed an issue with missing GPUDumpViewer files from a packaged build on Android and iOS.

Fixed black mip 0 in DumpGPU when a texture has a mip chain on D3D11 by using the capture by compute shader.

Avoid divide-by-zero in GetLightMapColorLQ.

Fixed Lightmass wrong string formatting.

Ray tracing now takes into account the ‘Visible In Scene Captures Only' flag.

Fixed an issue where Static Lighting was broken when using Forward Rendering. The lightmap build data would get invalidated incorrectly while cooking.

Fix DumpGPU file write error.

When having lines that use world and screen space scaling in the same batch, OrthoZoomFactor can get overwritten, causing following vertices to potentially be generated wrongly.

Fixed an issue where ray tracing could accidentally be enabled when disabled in render settings.

Fixed incorrect Hierarchical Instance Static Mesh culling in ray tracing because bounds are not always initialized when the culling happens.

Fixed FNiagaraRendererMeshes::GetDynamicRayTracingInstances fails to use Reserve, MoveTemp, or Emplace_GetRef to avoid copies and reallocations.

Automation tests that do not have ray tracing enabled will now disable ray tracing explicitly to avoid enabling it by accident when D3D12 is active.

Fixed a bug with Cascaded Shadow Map caching on mobile.

Fixed a bug with DepthAux corruption on Mobile OpenGL.

Fixed an issue where the indirect lighting of translucency is too bright on mobile.

Fix an issue with depth of field jittering when the anti-aliasing method on mobile is set to Temporal Anti-Aliasing.

Fix a shader bug on mobile with pixel projected reflection.

Fixed an issue with stencil testing in Post Process Materials if MobileSupportFetchBindedCustomStencilBuffer

Fixed an issue with fetching depth in mobile's separate translucent pass with Vulkan subpass.

Fixed an issue with alpha detection in Virtual Texture builder causing tiles in the same virtual texture to use different formats.

Fixed an issue that the Multi-Sampling Anti-Aliasing (MSAA) was broken on Android.

Changed the precision of length2 from half to float to fix artifacts on Mobile Vulkan.

Fixed an issue with reflection being too bright on Mobile Deferred renderer with Static Lighting disabled.

Fixed an issue with mobile alpha coverage when the material is masked but writes every pixel.

Fixed an issue with resolving Multi-Sampling Anti-Aliasing (MSAA) texture on IOS.

Fixed an issue where the GlobalClipPlane doesn't work on depth-only vertex shader on Mobile Preview Shader platform.

Fixed an issue where the brightness was not consistent when using Multi-Sampling Anti-Aliasing on iOS.

Resolved an issue where depth content was not being kept when Temporal Anti-Aliasing was enabled. It was because the bKeepDepthContent was false if CameraCut is used and the SceneDepthTexture could be a dummy black texture (RGBA8 format) and a RenderDependencyGraph (RDG) validation failed at creating StencilTexture SRV which was expecting PF_DepthStencil format.

Fixed an issue when Multi-Sampling Anti-Aliasing (MSAA) is enabled, it would only output SceneColor for SunMask on iOS.

Fixed an issue with dark screens with Vignette enabled on Android.

Fixed an issue with counting Skeletal and Static Meshes memory with mesh streaming enabled. The IncrementMemoryStats was called at the FSkeletalMeshLODRenderData::InitResources and FSkeletalMeshStreamIn::DoFinishUpdate.

Fixed light flickering issue on Mobile Vulkan that could happen on Cloth and Hair assets.

Fixed an issue with Cascaded Shadow Maps when using split-screen on mobile.

Disabled GPUScene for landscape on mobile since it is not supported.

Fixed an assert on Vulkan when a texture is created from TransientHeap with Discard as its initial state.

Fixed CmdBuffer->IsSubmitted() assert on Vulkan.

Implemented changes on Vulkan RHI to avoid the automatic clearing of new targets when they are allocated in transient memory since it gets put in the upload command buffer that can execute earlier in the frame (when the same memory is potentially used by a different transient resource).

Resolved a bug that caused flickering in the Editor when using Vulkan.

Make it clear that PlatformData can't be null when creating texture cube array, fix static analysis warning.

Fixed a Scene Capture issue so editor-only components aren't created when running a commandlet.

Fixed 16 byte alignment of array elements for Vulkan. There are a few macros to help with conversion of cases where a single scalar is used in shader parameter arrays (and cannot be packed with other scalars).

[C++] SHADER_PARAMETER_SCALAR_ARRAY(MemberType,MemberName,NumElements): adds an automagically packed array of scalars to shader parameters.

[C++,HLSL] GET_SCALAR_ARRAY_ELEMENT(PackedArray, ElementIndex): returns the value at that index in the scalar array.

[HLSL] DECLARE_SCALAR_ARRAY(ScalarType, ScalarName, ElementCount): declares an automagically packed array of scalars.

For Vulkan, we fixed an occasional layout error in Virtual Textures depending on which pass runs first after it is resized.

Fixed an issue where a GameThread would stall (waiting for render thread) whenever a console variable was changed during gameplay.

Fixed a NaN error introduced by fog when it is used on materials used by DrawCanvas

Fixed mem report texture usage computation for landscape components. This includes:

HeightmapTexture / XYOffsetmapTexture, which are only used on the non-mobile path, were artificially increasing the ref counts on platforms where mobile and non-mobile paths are enabled (in mobile mode).

Weightmap[0], which contains the normal map in mobile mode, was not accounted for by the material instance's GetUsedTextures call, since it uses inlined HLSL code to sample it, rather than a texture sample material expression

Fixed the visual calibration (device-encoding-only) viewport passes for HDR in scRGB mode.

Fixed data race and potential double delete in FCanvas deletion path.

Enabling HDR in the Editor now supports use with both HDR and non-HDR monitors.

Fixed the "Selected Morph Target Vertices" Editor visualization, which was broken.

Bug Fix: User Interface HDR composition in the Editor is now consistent with in-game HDR composition.

Implemented a fix in the usage of ERayTracingPrimitiveFlags::UnsupportedProxyType. Its value is 0, so it must not be used with EnumHasAnyFlags().

Fixed "Primary Rays" Ray Tracing debug view mode by renaming ERayTracingPrimaryRaysFlag::ConsiderSurfaceScatter to PrimaryView and using it to initialize the first ray instance inclusion mask in the RayTracingPrimaryRays Ray Generation Shader (RGS).

Changed how hair strand textures are computed. These changes process hair strands textures in tile, and split computation over several frames to avoid Timeout Detection and Recover (TDR) on large grooms.

Fixed an issue with HighResShot not clipping the rectangle to image bounds, and allowing memory to be read out of bounds.

Changed groom bound computation when attached to a parent skeletal mesh, depending on whether it is attached relatively or not. The relative attachment is done based on attachment bone naming.

Implemented a fix to exclude primitives that are meant to be hidden in game from the ray tracing scene when game view is enabled or in Play in Editor mode.

Fixed an issue with hair strand shadows when Ray Traced Shadows is enabled. Ray Traced Shadows are now done in translated world space, replacing a previous temporary workaround for computing transversal in world space.

Fixed a crash when r.RayTracing.Shadows is enabled dynamically. Previously FScene contained an array of Ray Trace Shadowed lights, which was updated when a light was added or removed. However, this is incorrect as the light's Ray Traced Shadow state depends on console variables that may be changed dynamically. The solution is to check if the scene currently contains any lights with Ray Traced Shadows during rendering. This is more expensive but robust. The array of RT-Shadowed lights is removed as it was not used beyond checking if it's empty.

Fixed a reentrancy bug by making FSimpleMeshDrawCommandPass only run SetupDrawCommands the first time BuildRenderingCommands is called. This fixes a check in groom rendering.

Fixed a hair selection issue under certain camera position and view resolutions.

Fixed texture arrays with mip chains and streaming by adding an access point to texture arrays to get the mip data.

Texture2dArrays now stream properly, correctly handling LODBias and packed mip tails.

Platform Linux for the LiveLinkOverNDisplay Plugin was whitelisted in nDisplay.

Fixed hair strands support for light functions by ensuring that light functions evaluated for hair strands will fetch the correct scene depth value.

Fixed an issue where ACompositingElement could not initialize properly because Super::BeginPlay was not called.

Fixed "Single Sample Shadow From Stationary Lights" by propagating the flag to GPU-Scene.

Fixed the estimate for how many streaming texture mips to prefetch to avoid a blocking cache fetch on the main thread in the Editor.

Implemented a fix for depth bounds setting outside of valid range on fog pass. The Render Hardware Interface (RHI) validation layer now has checks to catch such issues in the future.

Fixed a leak when using the Null renderer (primarily for autotests), by implementing a valid Sync method.

Fixed a memory leak relating to UpdateTextureRegions inFRemoteSessionARCameraChannel::UpdateRenderingTexture.

Added support for root UV in hair card Groom Assets.

Fixed the visualization of Cards guides so they are only available when simulation is enabled.

Fixed missing update of hair ray tracing geometry when hair radius / tip / root / ray tracing scale are updated on a static groom.

Fixed hair LOD colorization on cards and meshes geometry.

Fixed a typo in the Blueprint action-menu category for composure export functions.

PR #9127: Corrected a typo in an FLiveLinkLog warning message.

Implemented code to use a conservative vertex count to initialize ray tracing geometries with multiple segments. The value of Segment.MaxVertices must be at least as large as the maximum value in the index buffer, plus 1. Previously this was initialized to per-segment vertex count, which can be too small.

Fixed a bug to hide the shadow of primitives with "hidden shadow" enabled when the actor is hidden in the Editor UI. Previously, the shadow would remain even if the primitive was hidden in the Editor.

Fixed Texture Profiler compiler errors.

Apply "Get Ray Tracing Quality Switch," "Get Path Tracing Quality Switch," and "Get Lightmass Replace State" functions to ray tracing callable and miss shaders.

Fixed an issue in FTextureLayout3d causing higher than expected memory usage.

Fixed an issue with the availability of heightmap visibility when building the Global Distance Field in cooked builds.

Fixed issues with Distance Field Shadows in water when using async compute.

Fixed issues with Distance Field Shadows when using split screen.

Fixed GlobalDistanceField corruption that occurred when a scene contained only heightfields.

Fixed issues with materials applying vertex offset or modifying opacity based on DistanceToNearestSurface.

Deprecated:

Deprecated bOverrideWaterMesh (WaterMeshOverride is enough to override the water mesh, no need for an additional boolean).

Deprecated the view uniform buffer from MeshPassRenderState.

Removed:

Removed all flip-y completely and only flip-y at the end on Android GL with a native window API since there is no need to handle flip-y on high level.

Removed the limitation of having a max of four local lights when using Mobile Forward Renderer.

Removed the ‘High Quality Reflection' option when using the Mobile Forward Renderer.

Removed the division of Pi on Mobile Directional Light's color in C++ to line up with desktop in shaders.

Removed the Mobile rendering project setting to set ‘Max Movable Spotlights / Point Lights'. On Mobile, this forces Movable Point Lights to be Static.

Removed view uniform buffer from ray tracing mesh draw commands and deleted FPersistentUniformBuffers::ViewUniformBuffer.

Crunch and zlib compression support on Virtual Texture tiles was removed from the engine.

Removed the r.CachedRayTracingInstances.CacheLocalTransform/LazyUpdate console variable.

Removed the deprecated FRayTracingSceneInitializer codepath.

New:

Virtual Shadow Map cache can optionally be allocated per view. Can be a significant performance win by avoiding constant cache thrashing when rendering multiple view families (for example, this is used for nDisplay). Enable the feature on the FSceneViewStateInterface using AddVirtualShadowMapCache. See also the related RemoveVirtualShadowMapCache and HasVirtualShadowMapCache functions.

Added Virtual Texture warmup frames for Material baking. The number of warmup frames is controlled by the MaterialBaking.VTWarmupFrames Console Variable and defaults to 5. Warmup will only happen if the Material samples Virtual Textures.

Added support for updating the Virtual Texture system when using DrawTileMesh. This allows systems that capture or bake Materials to warm up source Virtual Textures correctly.

Added a renderer project setting to enable Virtual Textures to be used in opacity masks. This setting defaults to off, which is the current behavior.

The Groom system now supports reading the skinned mesh geometry cache from the deformer graph system. This allows Groom to stay synched to the animated mesh when deformer graphs are used.

Compression settings for Runtime Virtual Texture (RVT) streaming mips are now stored in the RVT Component instead of the RVT Asset.

Decal components are now exposed to Blueprints.

Added support for velocity vector output for objects that are marked as Static but have Materials with World Position Offset.

Translucency Sort Priority is now used to sort Mesh Decals.

Bug Fix:

Fixed sphere geometry vertex buffer to use FVector3f, rather than FVector.

Fixed a bug that caused a failure when setting a Material Instance Dynamic on a decal after World Partition streaming has already happened.

Removed an unnecessary warning that nothing will be written to virtual texture for empty foliage actors.

Implemented changes to force a depth prepass when Virtual Textures are enabled for a project. This fixes an issue where masked Materials could not be used with Virtual Textures when the depth prepass wasn't enabled.

Fix a bug with no velocity being written for Unlit Materials.

Fix a bug with Virtual Textures not updating correctly in debug view modes.

Fixed an issue where Adaptive Virtual Textures would read from pages that weren't fully mapped, which could lead to flickering or sampling errors.

Implemented changes to disable parallel Render Dependency Graph if it's not running in a dedicated render thread.

New:

The Path Tracer now invalidates the path-traced out when decals are added, removed or transformed.

Implemented Subsurface Scattering support for the eye shading model.

Implemented Alpha Holdout blend mode.

Enabled progress display by default and reduced the default Samples Per Pixel value to 2048 in the Post Process Settings.

Dithered opacity masked Materials should now ignore the clip value.

The Path Tracer now takes the normal map into account at the exit point of the random walk for better detail preservation in Subsurface Scattering.

Added support for Light Functions in the Path Tracer. This also includes colored light functions when using them with the console variable ‘r.PathTracing.LightFuntionColor'.

Invalidate Path Tracer when Sequencer time changes This change also allows the Path Tracer to be used in the Niagara editor (with constant invalidation, but avoiding blurring).

Improved filtering of which scene proxies should impact Path Tracer invalidation.

Add support for path tracing in the Material Editor and Static Mesh Editors.

Added Light Function support for ray tracing. Lights with assigned light function materials will now show up correctly in raytraced reflections.

Implement Sky Atmosphere and Exponential Height Fog in the Path Tracer.

Added support for Distance Field Shadow on water materials using Single Layer Water. Set the console command ‘r.Water.SingleLayer.ShaderSupportDistanceFieldShadow' to enable it. This change requires restarting the editor.

Implemented Ray Tracing support for the Image Plate plugin.

Added support for a Light's ‘Source Length' setting in Ray Tracing.

Added functions on UExponentialHeightFogComponent to allow users to set Second Fog variables in code along with FSecondFogData struct to allow setting them through Blueprint.

Implemented a workaround for incorrect shadow ranges in directional lights due to the changed default values in the Unreal Engine 5.0 release. Old defaults are no longer loaded if they are part of Blueprints, regardless of the engine version used to create the Blueprint.

Improvement:

Improvements to Virtual Shadow Map static caching categorization. Primitives are still categorized initially based on mobility, but if a static primitive invalidates the virtual shadow map (usually due to the use of world position offset in a material) it will be transitioned to dynamic automatically to avoid continually invalidating the static cache.

Optimization:

Several optimizations to light loop for shadowed lights that together lead to some gains in scenes with several local lights, and large gains when using virtual shadow maps one pass projection with many local lights.

Reduced barriers and GPU idle time for small lights.

Decoupled virtual shadow map one pass projection from clustered shading. When only a virtual shadow map is present for a light and no light functions are used, it can now take a fast path in the light loop.

Crash Fix:

Fixed an assert on Light count when there are no lights in the scene.

Fix potential crash when ray-traced shadows are disabled for the project but there is still a Light in the scene that enables ray-traced shadows.

Bug Fix:

Applied a fix for potential NaNs in the hair shading model.

Fixed Moveable Lights not invalidating the Path Tracer.

Avoid invalidating the Path Tracer when a Moveable Light transform has been set but did not actually change.

Fixed a constant invalidation in MRQ renders when camera depth of field is animated.

Fixed missing scene invalidations when changing skylight or moving atmosphere / fog components.

Fixed a constant path tracer invalidation being caused by Post Process Material blending.

Fixed an issue with MRQ where the post-processed output is not accumulated properly when using the Path Tracer.

Applied a fix for Reflection Captures sometimes showing up black in packaged games.

Fixed the bug that Gizmos are affecting global illumination. Added translucent editor primitives support. Top view mesh elements with translucent materials will go through editor primitive rendering instead of the standard translucency pass.

Applied a workaround for potential GPU timeouts when raytracing procedural hair primitives from a long distance.

Fixed sky and cloud issues that could occur in split-screen.

Fixed skylight intensity not updating through Sequencer.

Volumetric fog history and pre integrated light froxel texture are now pre exposed to avoid smearing artifacts at super low exposure.

GPULightmass should complete shader compilation before building lighting. The alternative is to have lightmass constantly restart as new shaders complete.

Implemented code to avoid Distance Field Ambient Occlusion self shadowing when using the console variable r.AOQuality >= 2.

Fixed incorrect distance field indirect self shadowing.

New:

Lumen support added for Scene Capture 2D. By default Lumen is disabled for Scene Capture to save memory, but can be enabled via post process override settings in the Scene Capture Actor (override Dynamic Global Illumination Method and/or Reflection Method to Lumen). Lumen requires persistent state to function properly, so Lumen for Scene Capture requires either bCaptureEveryFrame or bAlwaysPersistRenderingState to be set to true. Lumen will be disabled if both are false. The persistent memory usage for Lumen is significant, from 300 to 600 MB or more, depending on quality settings. The Texture Editor has been upgraded to display GPU memory usage for Scene Capture 2D to allow the overhead to be observed. By default the quality is set to minimum, but can be overridden with the Scene Capture Cache Resolution Scale post process setting under Lumen.

Surface cache generation algorithm is now more robust and able to cover a higher variety of meshes, including having surface cache for tiny scene elements.

Distance field stochastic semi-transparency for foliage Software Ray Tracing. This gives a more accurate representation of foliage, less over-occlusion.

Added Lumen Diffuse Color Boost to Post Process Volume. It allows brightening indirect lighting by calculating DiffuseColor for indirect lighting as pow(DiffuseColor, 1 / DiffuseBoost). Values above 1 (original diffuse color) aren't physically correct, but they can be useful as an art direction knob to increase the amount of bounced light in the scene. Best to keep below 2 as it also causes reflections to be brighter than the scene.

Enabled Lumen Radiosity on High GI settings.

Lumen Scene Direct Lighting now supports Rect Light Source Texture.

Added Skylight leaking control for Lumen as a new Post Process Volume setting that allows skylight to leak intentionally to prevent areas from going fully black with global illumination. It's useful for art direction, as it is a non-physical control, although it should be kept very subtle (.005 or less) to avoid losing HDR lighting contrast. Skylight leaking ramps up over distance, which creates Ambient Occlusion and keeps it from looking flat.

Lumen now supports the Two Sided Foliage shading model by accumulating irradiance for the backface, giving much higher quality foliage shading. The High GI scalability level disables r.Lumen.ScreenProbeGather.TwoSidedFoliageBackfaceDiffuse to avoid overhead. Also, improved Screen Probe hardware tracing biasing on two sided materials

Removed ray dithering fade at the end of trace distance when far field isn't used

When lighting surface cache pick N most important lights instead of N first lights. It improves lighting quality and fixes nondeterministic surface cache lighting as sometimes lights may be added to a scene in a different order. Control this with r.LumenScene.DirectLighting.MaxLightsPerTile.

Added an AffectIndirectLightingWhileHidden property to the Primitive Component, which allows hidden primitives to be injected into Global Illumination (GI) and Reflections. This is useful as an extra art direction tool to create cheap invisible area lights through GI.

Increased the Global Signed Distance Field (SDF) resolution when using Lumen Software Ray Tracing.

Added support for lighting channels for analytical lights.

Improvement:

In Software Ray Tracing mode voxel lighting volume has been replaced with an object grid, which allows sampling of the surface cache directly instead of a low resolution and leaky resampled voxel representation. This improves secondary bounces, reflections and GI from small emissive surface elements.

Optimized radiosity card tile memory size by allocating based on the update atlas size instead of a physical atlas size.

Added UPrimitiveComponent::InvalidateLumenSurfaceCache() to support manual surface cache refreshing on any material change.

Raised Lumen GI's intensity clamp (firefly prevention) by a factor of 2 now that Lumen has less noise.

Lumen lighting propagation is now faster while using editor movement widgets and toggling directional lights and skylights.

Lumen GI now uses Spatiotemporal Blue Noise, which gives much cleaner indirect lighting, especially when the camera is still and in screenshots. 'High' GI scalability quality in particular is improved.

Crash Fix:

Fixed a crash which occurred when reallocating surface cache pages with a modified aspect ratio after an object scale transform.

Fixed crash which occurred when enabling reflection hit lighting with a surface cache project setting.

Bug Fix:

Fixed Emissive Light Source not correctly encoded to be injected into the Voxel Lighting.

Lumen Screen Traces now skip hitting foliage materials to fix noise that could occur around grass.

Fix Radiance Cache leaking in Software Ray Tracing mode due to rays starting inside geometry.

Fixed randomly missing mesh cards from cook

Fixed mesh distance field volume interpolation on consoles.

Disabled Octahedral Irradiance format for Screen Probe Gather on Epic GI scalability settings as it doesn't handle gradients well.

Fixed Lumen GI and Reflections being culled at 1 million Unreal Units.

Invisible shadow casters are now filtered out from Lumen Scene.

Fixed an infinite loop that would occur when generating mesh cards for huge meshes.

Fixed area and capsule lights to respect source radius and length when lighting the surface cache.

Fixed non-Nanite per ISM surface cache generation.

Fixed an issue with indirect light rendering when the Lighting Complexity View Mode is enabled

Fixed missing Global Illumination energy on AMD GPUs.

API Change:

The DirectX Shader Compiler (DXC) no longer allows duplicate semantics in shader signatures. Particularly using SV_InstanceID requires careful examination of vertex factories input as it will likely be already defined there.

New:

Exposed azimuthal roughness on hair through the scatter (Metallic) parameter. The default value of 0 corresponds to 1.0 azimuthal roughness (current behavior) while increasing the scatter amount makes the hair more and more forward scattering, leading to a softer appearance. The lowest possible roughness is limited to 0.1 to limit noise.

Implemented support for Per Instance Custom Data for non-Nanite use cases (including ray tracing shaders).

When switching between rendering preview modes, On-Demand Shader Compilation (ODSC) should be used. AllMaterialsCacheResourceShadersForRendering now accepts a parameter to decide whether to fully cache and complete all shader maps. By default this is true to maintain previous behavior. When switching preview materials this behavior defaults to false and we let ODSC in the editor handle which shaders need to be compiled, resulting in far fewer shaders compiled.

Set InstructionCount when compiling shaders with DXC, which fixes an issue where all compiles of SM6 shaders were reporting 0 instructions.

Implemented single shader file compilation for cooked platform On-Demand Shader Compilation (ODSC). For example, recompileshaders /Engine/Private/Lumen/LumenVisualizeHardwareRayTracing.usf which would result in: 1) the game sends the shader file string across the network to the cooking server, 2) cooking server finds all shaders of that type, 3) cooking server flushes those specific types from the global shader map, and 4) cooking server recompiles just those shaders and sends them back to the game. There is still work to do in this regard to refactor duplicate code in RecompileShadersForRemote, and to implement the ability for material shader maps to compile just specific shader types requested (which doesn't yet exist).

Added UCompileShadersTestBedCommandlet which is meant as a simple way to profile/test/optimize shader compilation. Currently, it only compiles the global shaders. Having a commandlet is faster and easier to run repeatable tests than dealing with starting up the editor. You can run your projects with this commandlet with ‘ProjectName -run=CompileShadersTestBed -ddc=Cold -ddc=NoShared -noshaderddc -trace=default,counters', which ensures you don't get results in any DDC and that you always compile shaders.

Added more information to the DumpMaterialShaderTypes commandlet output.

Keep track of a map from static parameter hash to a list of all mat instances that share the same hash (currently this data isn't being printed out.)

Print the full path to the parent material. Some assets have the same name making it hard to track down which asset we were referring to.

Generate and print out the static parameter hash for each material instance.

Added material instance function to generate a string which contains a comma separated list of base property overrides for material instances. These cause shaders to be stored with material instances.

Generate and print out the base property override string to see which material instances also cause shaders. This output looks like the following:

Base Property Overrides: True

bOverride_OpacityMaskClipValue_0, bOverride_BlendMode_1, bOverride_ShadingModel_0, bOverride_TwoSided_0, bOverride_DitheredLODTransition_0, bOverride_CastDynamicShadowAsMasked_0, bOverride_OutputTranslucentVelocity_0

Volumetric Cloud conservative density is now a float4 (conservative density in x and side float3 side payload in yzw).

Dump DDC keys for global shaders. The console variable r.Material.DumpDDCKeys has been renamed to r.ShaderCompiler.DumpDDCKeys. The directory they output to changed from "MaterialDDCKeys" to "ShaderDDCKeys." Break getting the global shader map DDC key string out into a function to make it easier to call when we dump DDC keys. Global Shader map section files are named "GlobalShaderMap-%s" where %s is the name of the section (usually a global shader type). Editor and Game shaders are dumped to separate directories. Exposed ShouldDumpShaderDDCKeys function so material code can see if dumping is enabled.

Added command line parameters to specify a specific shader model and material quality level to cook for. This is used to limit what cooking shadermaps to a single shader model and/or material quality level. It's useful for locally cooking or specific situations where you want to cook a minimal set of shader maps. Each command line parameter can be used independently. Also, added -CacheShaderFormat that when specified during a cook, the cooker will only compile this shader model if supported for each material. Added -CacheMaterialQuality that when specifying this during a cook, the cooker will only compile this quality level and default for each material. For example, -CacheShaderFormat=PCD3D_SM5 and -CacheMaterialQuality=[0,1,2,3]

Output the WorldGridMaterial's human readable DDC key string to the log. This is done for diagnostic purposes on users' machines, and for the build machines.

Added new shader compilation editor analytics.

ShadersCompiled: The number of shaders compiled.

ShaderDDCMisses: How many times we missed shader maps in the DDC. This is a measure of how many times we didn't find Global and DefaultMaterial shaders.

ShaderDDCHits: How many times did we successfully find shaders in the DDC.

TimeShaderCompilationWasActive: Wall clock time of how long shader compilation was active across your whole editor session.

Added better output to COTF + ODSC. Prints out what command is being run (global, material, changed, singleshader) and prints out exactly how many shaders were compiled.And added a function to convert command type enum to a string.

Added an exec command "Material DumpDebugInfo" which dumps debug information for each shader in the material given as an argument. It can be run like the following: "material dumpdebuginfo WorldGridMaterial". It can also be used to see which shaders get invalidated when changing shader code:

"material dumpdebuginfo WorldGridMaterial", change the shader usf/ush file, run "recompileshaders material WorldGridMaterial", then "material dumpdebuginfo WorldGridMaterial", and diff the outputs of the two.

The filename follows the following format: Engine\Programs\AutomationTool{ProjectName}++UE5+Main-CL-20942948-WorldGridMaterial-2022.07.05-16.11.42.csv

The file output looks like:

Frequency, Target, VFType, ShaderType, SourceHash, VFSourceHash, OutputHash, IsShaderPipeline SF_Pixel, PCD3D_SM5, FGPUSpriteVertexFactory, TShadowDepthPSPixelShadowDepth_PerspectiveCorrect, 2DD4725EA72D0498EB6B1E656F35564D97083FC8, 920506EE58508D22D29046DCE7DF15BF34940059, EC976B76E986CB7E5235B154F9A0B3AF3AB9B1AD, false SF_Vertex, PCD3D_SM5, FGPUSpriteVertexFactory, TVirtualTextureVSBaseColorNormalRoughness, A3C811C874410080F3138AEF4489CCA932D7395A, 920506EE58508D22D29046DCE7DF15BF34940059, CD25F583872C5ECF0E156EA8F50AF96B6B199BDA, fal

Water geometry now works with Pixel Depth Offset (PDO).

Added the ability to specific material and material instances to cook using the command line to the CompileShaders commandlet. This adds the ability to specify which -targetplatform we should compile shaders for. You can specify multiple platforms by adding them together. For example, "-targetplatform=Windows+MyNewPlatform - Call BeginCacheForCookedPlatformData" to compile shaders instead of CacheShaders since the former allows you to specify platform. The following are some additional usage examples:

Specify collection EngineTest -run=CompileShadersTestBed -targetplatform=Windows -collection=MyCollectionName

Specify material list EngineTest -run=CompileShadersTestBed -targetplatform=Windows -materials=/Game/MyNewMaterial.MyNewMaterial+/Game/Tests/Materials/CoolMaterial.CoolMaterial

Specify both a collection and material list EngineTest -run=CompileShadersTestBed -targetplatform=Windows -collection=MyCollectionName -materials=/Game/MyNewMaterial.MyNewMaterial+/Game/Tests/Materials/CoolMaterial.CoolMaterial

Reduced the size of UMaterialInstanceDynamic by 8-bytes to drop into a smaller FMallocBinned2 pool.

Added the control to turn on / off Screen Space Reflections on translucency dynamically using showflag and ‘r.SSR.Quality'.

The new HLSL translator supports Virtual Texturing.

The Material Editor colors wires based on data type when using the new HLSL generator.

Input and output data types are tracked for node connections in the Material Graph. Pins and wires are now color-coded by data type.

Run two passes of PrepareExpression. The first pass to determine types, and second pass to flag expressions that are used. This way we can skip flagging constant/zero expressions (which we don't know about during the first pass)

Added 'Total Thread Preprocess Time' for shader compilation. This instrument shows how long shader preprocessing takes for each shader compilation job, keep a running total in our shader stats per shader type, add logging to track total thread preprocessing time for all shaders, and fixup local variable names to match the output log names.

The new HLSL translator supports structs in preshaders, which enables constant folding to be tracked across struct assignments.

Implemented changes to optimize GetMaterialShaderMapKeyString during cooks.

The new HLSL Material translator now supports automatic mip bias input.

The new HLSL Material translator now supports flow control in preshaders.

ShaderDebugPath now respects the material quality level for '...\Saved\ShaderDebugInfo\PCD3D_SM5\WorldGridMaterial\Default\FLocalVertexFactory\FHitProxyPS' or '...\Saved\ShaderDebugInfo\PCD3D_SM5\WorldGridMaterial\Epic\FLocalVertexFactory\FHitProxyPS' :

Use 'LexToString(EMaterialQualityLevel::Type QualityLevel)' to convert the quality level enum to a string.

This specifically appends to the DebugName the material quality at the level in the code where we "know" about the material. I wanted to avoid changing the parameters to the function, 'GlobalBeginCompileShader', because it is material agnostic.

Generate if{}/else{} control flow rather than ?: for material switch expressions. Added non-static bool MCT type to allow plugging bool expressions into switch nodes when using new HLSL translator.

Support matrix types in new HLSL translator Other various fixes/additions.

Added support for Material Layers with new HLSL translator.

Implemented const-correctness changes in new HLSL translator. 1) FExpression* is mostly always 'const'. 2) Since expressions should not change after creation, UMaterialExpression::GenerateHLSLStatements/Expression are const-methods.

Some fixes for rules around promoting scalar values in new HLSL translator which supports some new node types.

Texture values are no longer generated as HLSL code directly. Instead, they are replaced with a new 'Object' type system, which allows expressions to generate C++ objects of arbitrary type. This gives the texture sample expression full visibility into the texture object being sampled, which simplifies some code generation. More importantly it will allow virtual textures to work, which wasn't really possible with the previous system

Added the "DumpMaterialExpressions" commandlet to dump an info table of all material expressions in the engine and the plugins enabled on the project to a plain text file which includes the following output material expression fields:

Name for the name of the UMaterialExpression class (shows in material editor node search).

DisplayName for the optional display name set on the class (shows in material editor node search and overrides Name).

Caption to show text displayed on the material expression node.

Description

Tooltip Output location <Project>\Saved\MaterialEditor\MaterialExpressions.txt

The experimental CFLAG_RemoveDeadCode was added to ShaderMinifier to run a shader rewriting step that removes unused functions and types from the shader source before compilation. This improves compile times.

Added DistanceFieldApproxAO Material node to calculate approximate ambient occlusion.

Fixed duplicated SV_InstanceID semantic across the shader code.

Added the ability to split the Pipeline State Object (PSO) cache among chunks, so each chunk contains the cache only for the assets it contains.

The Command-Line Argument -noshaderddc now applies to the global shaders as well.

Improvement:

Improved the specular and diffuse matching between Rasterizer and Path Tracer for SSProfile. Switch DMFP to MFP automatically.

Removed compilation (of never used!) legacy simple forward shading permutations from Windows shader databases (~27% reduction of SM6, ~22% reduction of SM5 when simple forward was enabled in the compiler).

Crash Fix:

Fixed multiple crashes that could occur when undoing materials in the Material Editor. The transaction system was not aware of the EditorOnly data owned by the UMaterial, meaning that any undo/redo operation left the editor-only data on the UMaterial in an incorrect state. For instance, UMaterialExpressions with properties missing, override virtual function Modify on UMaterial, and call Modify on the EditorOnly data owned by the UMaterial.

Fixed occasional failures to decompress shaders in ShaderCodeArchive.cpp.

Bug Fix:

We now ensure shaders are cached before drawing a tile with a material. In the editor with ODSC, shader maps could be incomplete resulting in them drawing a tiling with the default material (which never gets updated) If the material is detected to be incomplete, it will synchronously compile shaders so they are ready before drawing. Display a slow task if possible (not PIE)

Fixed noise caused by world unit scale for large distance screen space subsurface scattering.

Added console variable 'r.SSS.Checkerboard.NeighborSSSValidation' to fix subsurface profile border artifact when checkerboard is turned on. It is off by default due to performance concerns since it introduces one extra profile ID access per pixel at low quality (TAA mode by default), and four extra profile ID accesses per pixel at high quality.

Fixed the ‘Total Shaders' compiled counter and stat to account for the job cache DDC. We were potentially over counting actual shaders compiled if we found a job already in the cache. Now we increase the counter when we finish a job that was not cached, and use ‘JobsCompleted' on the FShaderCompilerStats as a proxy for the number of total shaders compiled instead of counting the number compiled in the ShaderCompilerStats, because these are wrong and don't account for the job cache. Also, added a trace CPU profiler scope to FinishCompilation.

Fixed an issue with wrong refraction happening when SingleLayerWater triangles are not horizontal in the world.

Shader compilation will retry now when the following conditions are true: r.ShaderDevelopmentMode=1, and bSpecialEngineMaterial==True. This allows you to retry compilation of special engine materials, like WorldGridMaterial, even if you have bPromptToRetryFailedShaderCompiles=False.

Fix for various issues with the "CompileShadersTestBed" commandlet by making it behave more like the cooker.

The commandlet shouldn't be configured for rendering. This was originally done to force shader compilation to happen in PostLoad. This caused textures resources to be created, which is not needed and was causing crashes.

Properly wait on potential DDC requests.

Wait on shader compilation by calling ProcessAsyncResults, which is exactly what the cooker calls.

While we have jobs to compile we process the results.

Be sure to flush rendering commands so we cleanup deferred delete objects like Shader Maps.

Added logging to commandlet.

Enabled "LogMaterial" for this commandlet so we can see DDC puts w/ DDC key.

Fixed long wait times in FODSCManager::Tick caused by running when cook-on-the-fly is not enabled. Also only flush in ProcessCookOnTheFlyShaders if some work was actually done.

When modifying a parameter value on a UMaterial, all expressions that match the name are updated, rather than simply the first.

Compiler errors are now generated if a Material tries to append more than 4 components worth of data.

Made sure that Blueprint exposed functions resulting in a Material (UMaterialInterface) draw are synchronously waiting for their shaders to be ready before issuing the draw command. This also removes double-update of canvas in Blueprint functions.

Fixed a bug where custom scene textures could not be read in widget Materials.

Removed fogging from water brush translucent Materials.

Fixed a case where only the first virtual texture sampled on an Actor decal was updated correctly.

Fixed a bug where decals that sample world normals were not able to write to emissive.

Code was rewritten to use HLSL precise keywords in a number of places, including where World Position Offset is used. This fixes broken velocity vectors, and broken Editor outlines for a range of Materials.

Fixed a bug with broken shadow casting from Material Instances when the "Cast Shadow as Masked" setting is enabled in the parent Material.

Corrected an issue with Material Instances on decals looking incorrect when using cook on the fly.

Fixed a bug with CorrelatedColorTemperature in TonemapCommon.ush.

Fixed writing Virtual Texture feedback in ThinTranslucency Materials by using a hard-coded stochastic alpha threshold.

Fixed issues with texture streaming on very skewed textures (4x1024 and similar) and non-power of two textures with cinematic LOD levels.

Fixed a rare crash when building Hierarchical Levels of Detail (HLOD) in a commandlet by removing shadermap access that can pose threading hazards.

Fixed hitching while precompiling the Pipeline State Object (PSO) cache.

New:

Enable compilation and usage of tier1 Windows DX12 mesh shaders in Nanite if running under SM 6.6 w/ atomics.

Implemented initial Nanite raster pipeline register/unregister/de-duplication, including launching each raster pipeline during Nanite rasterization if programmable raster is enabled. Also hooked up graph GetMaterialMask function to Nanite HW raster pixel shader stage.

Implemented Nanite support for rendering complex collisions for the fallback meshes.

Added Nanite CPU Material culling to avoid unnecessary CPU and GPU overhead from numerous empty raster and shading dispatches/draws (content and view dependent).

Implemented basic HW triangle barycentric path for Nanite HW raster passes (NANITE_USE_HW_BARYCENTRICS). Some APIs and platforms can further improve this with special intrinsics.

Packed PixelValue into PageInfo for a single uint2 no interpolation VS -> PS param (so parameter cache performance is unchanged, since the cache perf is based on attribute count not element count), and also export PixelValue so depth only Nanite rasterization can use it if needed. The pixel shader behavior is unchanged though (PixelValue is only exported for 64b vbuffer).

Added ability to cull Nanite Instanced Static Meshes at a distance from the camera.

Refactored Nanite Material GBuffer passes to run off the render thread.

A Nanite Material override setting was added to Materials and Material Instances. The main advantage for this as opposed to using the NaniteSwitch Material Expression is that references from override Materials are not cooked on non-Nanite platforms.

Streaming data for Nanite can now be fetched asynchronously from the Derived Data Cache in the Editor.

The Nanite streamer now runs the GPU transcode in asynchronous compute on platforms that support it.

Added a Nanite MaterialCount debug visualization mode which can be enabled with the console variable 'r.Nanite.Visualize MaterialCount'.

Made imposter building optional with the console variable 'r.Nanite.Builder.Imposters'. This setting is turned off by default.

Implemented changes to improve disk size for smaller Nanite meshes.

Improved Nanite partitioning heuristics to produce fewer expensive multi-Material clusters.

The PreSkinnedPosition shader graph node now works with Nanite.

Improvement:

Removed a massive number of Nanite rasterizer shader permutations across all platforms/shaderdbs, significantly improving iteration times for the editor and cooker, especially when these numbers get multiplied by the number of materials that utilize programmable features in addition to the default material "fixed function" path.

CLUSTER_PER_PAGE has been fully removed (since we no longer ever run CLUSTER_PER_PAGE=0), which now makes it mutually inclusive with VIRTUAL_TEXTURE_TARGET.

HAS_RASTER_BIN has been replaced with a dynamic branch, since this is just a per cluster index offset based on a simple uniform buffer load.

ADD_CLUSTER_OFFSET has been replaced with a dynamic branch, since this is just a per cluster index offset based on a simple uniform buffer load.

HAS_PREV_DRAW_DATA has been replaced with a dynamic branch, since this is just a per cluster index offset based on a simple uniform buffer load.

NEAR_CLIP (only change to significantly affect codegen) has been turned into a dynamic branch based on FNaniteView. This lets us merge depth clip/clamp rasterizer calls in VSM together instead of relying on HAS_PREV_DRAW_DATA, and a future optimization can now be done to merge local and directional light full Nanite pipeline calls together.

VISUALIZE permutation removed from VS/MS since it only loaded uniform values that passed down per-vertex into fragment stage as nointerpolation parameters. Pixel shader now constructs this uint2 directly under the VISUALIZE permutation.

NANITE_MESH_SHADER_INTERP removed by default but still left in the code, since it is a work in progress potential optimization for DX12 mesh shaders.

Removed explicit Lumen and VSM usage of NANITE_RENDER_FLAG_HAVE_PREV_DRAW_DATA (now the dynamic branch path is only taken if CullRasterizeMultiPass implicitly breaks the rasterization into multiple calls due to NANITE_MAX_VIEWS_PER_CULL_RASTERIZE_PASS overflow).

Performance was tested on a 2080Ti in AncientGame, and the delta is effectively noise (tested cached and uncached VSM). Further testing on other platforms will occur, but it is important to get this change in for all the benefits and easy to tweak things later if needed.

Added an optimization to Nanite rasterizer binning. Multiple triangle Material span indirections of a single cluster are now emitted, rather than a single cluster indirection where each rasterizer VS needs to re-calculate whether or not a triangle is contained in the active rasterizer bin.

Implemented a significant optimization in certain heavy programmable raster scenes to use a fixed function path in Nanite if the only programmable feature is World Position Offset (WPO), but Evaluate WPO is false.

Implemented a minor CPU optimization to deferred pipeline registration on the Nanite draw lists. This is experimental and work is ongoing.

Converted Nanite Streaming buffers to support the Render Dependency Graph (RDG).

Optimization:

Explicitly disable WPO evaluation on Landscape Nanite meshes.

Merged Nanite HW rasterizer passes into a single RDG pass, and also SW rasterizer passes into a single RDG pass. All passes update various buffers with atomics, so they are now always marked with SkipBarrier to disable synchronization between passes and allow for overlap. VSM in AncientGame campfire went from 4.64ms -> 3.41ms, Primary raster went from 1.34ms -> 1.07ms. Lumen raster 0.20ms -> 0.18ms. Much higher gains expected in content with high numbers of rasterizer bins (more overhead to remove using this optimization) MedievalGame is even better: Primary raster 1.82ms -> 0.92ms, VSM 2.99ms -> 2.07ms, Lumen 0.43ms -> 0.19ms

Optimized raster binning by merging separate HW and SW dispatches together, and also fixed the cluster thread group count so we don't spawn 64x useless thread groups. Tested on a 2080Ti with AncientGame campfire.

Separate HW/SW dispatch vs. Merged HW/SW dispatch Primary 1.28ms -> 1.02ms Directional VSM 1.66ms -> 1.52ms Local VSM 2.21ms -> 1.96ms

Merged HW/SW dispatch -> Fixed Cluster Counts Primary 1.02ms -> 1.01ms Directional VSM 1.52ms -> 1.43ms Local VSM 1.96ms -> 1.92ms

Big rewrite/optimization of Nanite programmable raster pipeline registration with GPUScene on the CPU, added raster bin visualization plus duplicate define code cleanup, added initial WIP two sided material support (will optimize the math shortly), and fixed a number of programmable raster VSM related bugs.

Crash Fix:

Fix a Nanite crash which occurred when enabling Shader Complexity Mode in a cooked build.

Fixed a Nanite crash that would occur when setting the Preview Render Level to SM5 after successfully rendering SM6.

Fixed a potential crash when Nanite Derived Data Cache requests fail during cooking.

Added vertex sanitation code to the Nanite builder to fix a potential crash when the input mesh has bad floating point data.

Fixed a Nanite streaming crash when all pages early out.

Bug Fix:

Fixed a race condition which occurred when accessing the RasterMaterial or ShadingMaterial WeakObjectPtr on the render thread.

Fixed incorrect calculations that occurred in Nanite micropoly rasterizer when two sided materials are used.

Fixed Nanite AuditMaterials logic to correctly handle Material instances changing Blend Mode.

Fixed issues with Nanite triangle culling on orthographic cameras.

Fixed an issue where Nanite Geometry Collections could go missing when raytracing.

Fixed a logic issue with Nanite instance culling where the "Visible In Scene Capture Only" flag would not work properly.

Fixed an issue where Nanite Static Mesh settings would reset every time you re-import.

Fixed an issue where cluster DAG cuts from the Nanite Trim feature were sometimes inconsistent between clusters and groups, which could potentially lead to encoder crashes.

Added logic to the Nanite streamer to retry Derived Data Cache (DDC) streaming requests if they fail. Derived Data Cache warnings were improved to include resource names.

Fixed an incorrect warning message for Nanite cluster buffer overflows.

Removed:

Fully removed Nanite and Virtual Shadow Map SM5 vendor extension, lockbuffer hack, and DX11 support from UE5

API Change:

Previously, new renderers were added by UClass; now it's a manual process to register new renderers, which allows for more flexibility. See FNiagaraRendererCreationInfo for more details.

New:

Niagara node pins can be moved multiple steps at once.

Added a "loose type" mode to Niagara. Users can now treat position types as vector types.

Added unit metadata to system and emitter properties. You can enter values in seconds by default, but if you enter units in a different value it will auto-convert them. For example, entering ‘500 ms' will convert to 0.5 seconds.

Overview modes now have a simplified display when the view is zoomed out.

Improved Niagara pin type colors.

Changed the parameter types of transform nodes to more clearly differentiate vector and position types.

Made the Niagara component a Blueprint type.

Double-clicking on a script node now opens the selected version in the graph.

Added custom validation rule support to Niagara. Users can refer to UNiagaraValidationRule and its subclasses for examples to write their own.

The UI now shows convertible linked inputs for stack input bindings.

Changed the default value of the property Only Create on Spawn in the Component Renderer. The default value was previously true, it is now false. Previously, particles only got a component from the Component Renderer when they spawned, but now they will get that component as soon as it becomes available. This resolves issues that users had with burst systems, particularly when used in conjunction with Sequencer. Old assets are not affected.

Added file include support for CustomHlsl nodes.

Added a message to the emitter and script graphs when downstream assets are affected.

You can now specify version dependencies in modules.

Improved the audio player:

One-shot audio no longer loops.

Persistent Audio Components are destroyed when particles die.

Audio modules work in emitter and system scripts.

Added a setting to zoom-fit system assets when opened.

Added an option to collapse disabled Niagara modules.

Niagara components that are not auto-activated now stay off when you change users parameters.

Improved numerics resolution, and made type checking stricter for operation nodes.

Made the compilation status more obvious in Niagara's viewport.

Removed loose parameter bindings from main Niagara parameters.

Data Interfaces should now opt in to the new binding path by setting UseLegacyShaderBindings to false.

BindParameters, SetParameters, and UnsetParameters are now BuildShaderParameters and SetShaderParameters.

CreateComputeParameters and GetComputeParametersTypeDesc are now CreateShaderStorage and GetShaderStorageType.

Shader storage should no longer be required for the majority of cases. Only those which require data based on bound functions will need additional data, everything else should be statically set.

Modified Niagara Compute Dispatch to use FRDGBuilder through the pipeline.

Legacy data interfaces run on the Graph execution timeline. Some caveats now exist, for example peeking the current buffer on the MainDataSet will be wrong.

Converted data interfaces run on the Graph build timeline, executing passes as required.

Converted data interfaces have been updated to use new PreStage, PostStage, and PostSimulate functions.

Various other parts of Niagara have been updated to allow operations on the Graph builder timeline, for example, readbacks, debug drawing, profiling, and more.

Various global compute shaders have been updated to use shader parameter structs.

Added support for spawning over 16k max secondary particles per frame in Niagara Fluids.

SimCache functions now access data from Blueprints.

Added methods to get the socket index from filtered and unfiltered sockets.

Added Velocity to all functions to make it consistent.

Added Interpolated methods for World Space functions.

Added RGB and RGBA pins to dynamic parameter material nodes.

We now show pin names and added RGBA to the Particle Color node.

Removed a case that blocked SRV for uniform sampling.

Reduced the size of the GPU triangle uniform sampling buffer from 16 bytes per triangle to 8 bytes.

Added a custom element count binding for simulation stages.

Added reset to default option to the camera in the Baker.

Added camera bookmarks to the Baker.

Added Attribute Capture Mode options to Niagara SimCache. This allows you to capture all, renderer only, or user-supplied attributes only into the cache.

Created a Blueprint library for capturing Niagara SimCache data.

We now support position types for material parameter bindings.

We now detect if a data interface is being used with a CPU script or not.

We now allow the static mesh data interface to access GPU resources if it's not used by a CPU script.

SRVs will be available on the target platform.

Support added for Cube, 2DArray, and Volume Sample data interfaces to select both the texture and render target types. SetTextureObject function can take either parameter now.

Data interfaces can add renderer-only attributes for capturing. For example, if a data interface ran a process post cache read to update the state required to render the system, we may not cache it, since the sim cache will only store renderer-bound attributes.

Emitter Properties data interfaces can access data that is not part of the data buffers.

Added a method to the particle reader to understand local or world space.

Static mesh data interface CPU access warnings no longer include socket sampling.

Added validation rules to simulation stage budgeting.

There is now an option to reset Niagara and Cascade when crossing too many large world coordinate tiles, since this will result in rendering artifacts.

Added constant material parameter bindings for renderers.

We now track registered components on the Debug HUD, and optionally show their information.

Converted the Collision data interface to Render Graph.

Converted the Physics data interface to Render Graph and shader parameters.

Added SubUV to the renderer information. This removes the GPU data deduplication, but this should be done via data interface deduplication and is not robust when using pointers.

Added Sprite Renderer Info data interface for reading information from a sprite renderer inside a script.

Converted Audio data interfaces to use shader parameter structs.

Landscape data interface uses the shader template and shader parameters.

Cross level references now use TSoftObjectPtr instead of TObjectPtr.

Physics Field Update now uses Template, Shader Parameter, and Render Graph.

Added a project setting for sort precision. Renderers can now override this project setting.

Converted Niagara Debug Drawing to Render Graph.

Converted the EmitterProperties, ActorComponent, and SimpleCounter data interfaces to shader parameters.

Converted RasterizationGrid to shader parameters and Render Graph.

Converted GeometryCollection and ChaosDestruction data interfaces to Render Graph.

Updated the NiagaraVariant when calling array set functions.

Converted StaticMesh data interface to shader parameters and Render Graph.

Exposed occluded line drawing color scale and set defaults to 5%.

Added Matrix User Parameters Setters. This truncates to FMatrix44f so will loosen precision for large world coordinates.

Separated expanding bounds between dynamic and static. Added an option to snap bounds to units, to reduce update transform frequency as they grow. When no static bounds or dynamic bounds are present, we do not return the static bounds.

Converted the Grid2D data interface to use template and parameter structure binding. All read-write data interfaces now use correct formatting for shader parameters.

Converted example mouse data interface to parameter bindings.

Converted RenderTarget data interface to use template and parameter structure binding.

Curve data interface now uses template and parameter structure binding.

Converted GBuffer data interface to use template and parameter structure binding

Converted Spline data interface to shader parameters. Object Reader conversion and Neighbor Grid 3D conversion now use shader structures.

Converted MeshRendererInfo, VectorField, CurlNoise, Camera, and Occlusion data interfaces to shader parameters.

Rigid Mesh Collision data interface converted to Render Graph.

Converted Export data interface to use template and parameter structure binding.

Moved constant buffers into loose parameters, with the exception of the external cbuffer. Parameter binding is now enabled when possible, for example when there are no legacy data interfaces, external cbuffers, or view uniform buffers.

Initial pass for Niagara Simulation Cache. Currently a full restart cache per frame is generated. It only contains system simulation and particle data set information. This is still highly experimental, while it works in cooked and uncooked we fully expect the data formats will change.

Added support for shared static float buffers that data interfaces can push data into.

Added NiagaraDebugHud console command to quickly enable or disable the HUD.

Added a Blueprint method to modify filtered sockets and bones for skeletal mesh sampling.

We now flush Niagara pending ticks in batches if we inject a large amount in a single frame. Render Graph has a limit on the number of passes that can execute. We avoid surpassing this limit, for example, by skipping forward in the Sequencer timeline.

Added support for returning the bone scale on a skeletal mesh data interface.

Converted Hair to Render Graph.

Converted Texture data interfaces to use template and parameter structure bindings.

Added a method for data interfaces to draw to the Debug HUD. Debug HUD is now wrapped with WITH_NIAGARA_DEBUGGER to make sure it's compiled out.

Fixed an RHI resource leak by calling release on uniform buffer before memstack wipes memory.

Updated the Array data interface to shader parameters.

Converted the Async GPU Trace data interface to shader parameters and Render Graph.

Added an experimental VirtualTexture data interface.

Converted the Skeletal Mesh data interface to Render Graph and shader parameters.

Added support for pulling a bind pose vertex or triangle.

Added overrides for translucent sort priority and offset.

Updated the Graph node Add menu logic. Loaded enums no longer show up in the make/break list unless the library only flag is off.

Improved the UX for the Device Tree and CVar Conditions:

Cleaned up Niagara Device Tree. Device profiles have a new value called bIsVisibleForAsssets that lets you indicate which device profiles should be visible in other assets.

Improved tooltips and coloring on the Device Tree to better show what is enabled or disabled and why.

Added tooltips for CVar conditions to text entry and suggestion boxes showing the CVar help text.

Platforms now specify a min and max Niagara Quality Level they support, which reduces need for trawling .ini files and allows fragments to set the quality level.

CVar Conditions now have more control over what occurs when the condition is passed or failed. Previously they could only disable the set when the condition failed, which is now the default.

New renderers added to emitters have a default asset assigned (for example a material or a mesh).

Multiple tweaks and additions for making scalability smarter with regards to culling important player FX.

New master mode for scalability culling allowing us to pause all culling. Useful for special cases such as a front end.

Added ability to reset FXBudget on mode transitions.

Tidied up library spawn functions with an initialization struct version.

NiagaraComponents can now be told that they are a player effect explicitly.

Physics Asset is replaced by Rigid Mesh Collision data interface for skeletal and static mesh collisions. All Niagara Fluids templates have been updated.

Niagara scalability can now globally be paused or disabled via the console command fx.Niagara.ScalabililityCullingMode.

Added a function to get spline length.

Implemented cubic interpolation for 3D gas simulations (velocity and scalar advection). This gives a large increase in quality.

Removed "Common" section from the Parameters panel in the Niagara Editor.

Event spawn scripts can now modify the initial values for particle attributes, so modules dependent on this can function correctly when spawning from events. An example of how this could be used is the ScaleColor module. This is optional per event handler, but defaults to enabled. Existing content has this disabled to maintain existing behavior.

Streak source particles for fluid simulations to avoid artifacts.

Added Get Velocity to the Actor data interface.

GPU scripts now log their errors in the Niagara log in a more reliable way.

You can now bind the attached component or a local player using Add Source Mode.

Small scale force to break up mushroom shapes on 3D gas simulations.

Added an option on 3D Flip simulations to add more particles near the surface of the sim for more detail and smoother surfaces.

Renderers now have default assets assigned to them, and new renderers can be registered via the Niagara Editor Module.

Selecting from the Parameters panel will highlight active usages in the stack overview.

Added an Effects section to the Niagara Component. Also added a category with Debug and Reset buttons. You can now summon the Niagara Debugger to view given variables, emitter, system, component, and more in context in the Niagara Editor.

Improvements to Niagara's scalability visibility culling options. This inlcudes custom view frustum checks that allow some visibility culling that is not based on the results of rendering code. As such, this can be used for pre-culling.

The Niagara Outliner can now pull data from a running instance of the game for a specific Niagara System into a Niagara SimCache for analysis and debugging.

Fluid bounds are programmable and set via the setup of the simulation.

Generalized the UvMapping feature so that it can be shared by both static and skeletal meshes. It now takes a different approach when specifying the uv index for the static mesh via a system script level VM function.

Stripped data from NiagaraSystems when AV data is not required (server builds).

Added a new function called vector field (LoadSample) to grab raw values by index rather than interpolated values.

Added mesh streaming reporting to Niagara and Cascade primitive component to ensure renderable meshes are being adequately streamed in. It now reports a scaled instance at the origin of the component. It does not take into account dynamic mesh scale.

When saving from the NiagaraSystemToolkit we now save the version not in edit mode. This prevents recompilation when someone references the system (for example in a level or a cook).

Added turbulence and small scale field to Niagara Fluids. The new small scale turbulence can be used to add edge breakup on simulations. It works by incorporating a random vector at each cell, ranged by the density value inside the simulation.

Added a bounds calculator for Niagara Light Renderers.

Disabled dependency on the HairStrands plugin for Niagara Fluids. Old assets may now fail to run properly without manually enabling the HairStrands plugin for access to the NiagaraDataInterfacePhysicsAsset class. Newer assets are no longer dependent on this plugin, and in the future the class itself will be migrated to the Niagara plugin.

Improvements to the Rigid Body data interface:

Debug rendering now shows the actors providing rigid bodies.

Added an emitter-based script for selecting actors using physics queries.

Made improvements to memory and runtime performance.

Improvement:

Optimizations for cooking in Niagara.

Updated the UI to handle cache changing while the UI is open, and to use the new API to read the data.

Made changes to the Static Mesh data Interface API for consistency.

We no longer add to GPUDataInterfaces if the data interface is not used by a GPU emitter. This improves the performance and reduces the memory of generating GPU ticks in some situations.

Cleaned up the copy and paste behaviors for Niagara Overview Graphs.

Copying from emitters is now no longer supported. The intended behavior here isn't well defined, so users are directed to the more supported path of using the add emitter option from the context menu.

Creating comments is no longer supported in emitter graphs. The overview is transient so any comments would not persist.

Migrated NiagaraDataInterfacePhysicsAssets to NiagaraPlugin. Implementing an interface on GroomComponent produces consistent behavior.

Added a stack warning for emitters which exclusively use emitter-sourced objects and are using dynamic bounds.

Crash Fix:

Fixed a crash when using undo after adding a renderer.

Prevented a crash in the editor when a struct with an unsupported type member was used in a module script.

Fixed a crash when playing audio from a particle system on a platform that had audio disabled.

Fix a crash when an event spawn info had no space left.

Fixed a crash when using fx.SuppressNiagaraSystems 1 with NiagaraDataInterfaceArrayFunctionLibrary.

Bug Fix:

Fixed a bug where user parameters that are linked to position types were only partially converted to positions.

Fixed a few bugs with the search bar in the generated code view.

Fixed an issue when duplicating a module would also duplicate all the script variable guids.

Fixed a bug when position bindings couldn't see position variables.

Prevented Niagara compilations from stacking, now you can have at most one pending compile request.

Fixed a bug that prevented playing audio from Niagara in cooked builds.

Fixed a bug when the array index changed, but was not picked up correctly in the Geometry Cache Renderer.

Fixed an issue when user parameters that were bound to renderer position bindings were not updated to position types.

Fixed a bug where pooled effects attached to Actors in hidden sublevels were not hidden properly.

Fixed a memory leak when several script source copies were left in the root set after compiling a Niagara system.

Fixed properties not showing for CustomHlsl nodes when the first input was a data interface.

Fixed a bug when types for user parameters were not considered across emitters.

Fixed an issue when Niagara systems without auto-activation would reinitialize after a compile request.

Fixed a bug when setting bOwnerNoSee on Niagara components wasn't hiding the Component if one of the emitters used a Light Renderer.

Fixed issues with memory image names. We now:

Write to the MemoryImageNames array.

Copy the contents of TArrayView rather than the layout of the view object itself.

Handle the name layout during patch application on foreign platforms.

On the Actor's EndPlay, we now release references to the source Actor and Component from NiagaraDataInterfaceSkeletalMesh.

Fixed GPU executing particle update script on spawn when interpolated spawning is disabled.

Fixed an issue when holding onto task references longer than necessary.

Fixed Mesh Renderer dynamic parameter constant bindings not working.

Fixed a potential issue that could cause a crash in an edge case for Cascade's activation code.

Fixed an issue with bool select nodes on the GPU where data is passed from the experimental virtual machine (VM).

When fixed delta tick is enabled, we now force solo mode.

Changed GPU initialize LODResource to TRefCountPtr to avoid stream out.

Fixed an issue that could cause some errors from correctly showing up in the editor for GPU simulations.

Fixed an issue when ray tracing was using PreViewTranslation for GPU instances. This also resolved missing large world coordinate support for Niagara and ray tracing.

Fixed a bug with the Niagara Platform Set CVar text entry box.

Resolved a memory stomp on loading UNiagaraGraph.

Fixed emitter mode visibility tag and mesh index not working on Mesh Renderers.

Fixed when a previous external cbuffer was using the current data. When not calling PostTick on GPU Context, we didn't push the data from current to previous.

Fixed an issue when GPU scene mesh path was dangling into a potentially reallocated buffer.

Fixed an incorrect LOD calculation in GetFirstValidLODIdx.

Fixed issues with default quality levels for uninitialized device profiles that could cause incorrect scalability behavior.

Fixed the Niagara Editor preview not resetting correctly when changing the Scalability Mode preview settings.

Fixed an issue that would prevent local player FX reactivating after being scalability culled in some cases.

Fixed an issue causing some Niagara user parameters set from Blueprints to be reset when a system was reactivated.

All the renderer material bindings now show up in GetBoundAttributes. Prior to this change, there could be subtle differences in the data being preserved in cooked and uncooked.

Modified the warmup delta time, it now affects the tick count and time properties. Added stack warnings on systems and emitters if the emitter maximum delta time is smaller than the system's warmup delta time.

Fixed issue in the Scalability Manager that could cause no updates to occur in some cases.

Fixed an issue with a duplicate user parameter of type position or vector being created when a variable with the same name but opposite type already existed.

Static variables were depending on pin persistent GUIDs for caching. This is insufficient as some pins are zeroed out for persistent GUIDs. Picking the pin offset and parent guid in that case.

Fixed an issue when some InstanceOverrideParameter data interfaces were being used before being post-loaded, and so missing some required post-load fixup.

Fixed a bug that would cause the tick function for Niagara solo components to be left running even when the systems were inactive.

Now detecting if a function signature actually changes when upgrading a data interface function call. This was causing an unnecessary reallocation of pins when doing a static duplicate.

StackFunctionInput cache now correctly populates the data source.

Fixed type checking of visited parameters when evaluating Fail If Not Set errors, as we may have intentional type mismatches for large world coordinate types.

We now prevent caching shaders for scripts that are not associated with a system. This prevents the compilation of standalone scripts and scripts from standalone emitters.

Made CullProxy on NiagaraComponent transient, so that we don't try to save any references to the dynamically created proxy component.

Initialized UNiagaraScriptVariables added to graphs with default mode Value when the variable is in the module namespace.

Apply SystemLWCTile to track the large world coordinate tile when evaluating Mesh signed distance fields (SDFs) in Niagara.

Fixed an issue where BoundAttributes in NiagaraComponentRendererProperties were getting trimmed.

We now handle TypeDefinitions with transient structs during serialization. If a small world coordinate struct is available, we use the mapping of this struct during the session to serialize out the large world coordinate version.

Fixed an issue when systems that shared the same name (but different paths) would overwrite results when dumping byte code.

Cleanup natvis for niagara types:

Types have been moved into their own niagara.natvis file.

We can then resolve FNiagaraTypeDefinitionHandle through global pointers so that FNiagaraVariable can now be properly visualized.

Incorporated the type into the ordering of the attributes. This resolves an issue that resulted in multiple attributes with the same name, but compatible types (float and position).

Fixed two issues with attribute trimming Niagara particle scripts:

Parameters to an impure function that were using the StackContext namespace weren't being properly included in the dependency chain.

Custom HLSL nodes which internally used impure data interface functions wouldn't necessarily have their inputs marked as dependents (in the case where a dummy output variable was being used, which itself got trimmed).

Stale and garbage-collected actor components can no longer be accessed when using the ActorComponent data interface.

Fixed the FindQuatBetween script to handle the case where one (or both) of the input vectors are 0 length (an identity quat will be returned).

Made sure we only enable bAreaWeighting if the option is selected and the underlying data is present. If you have modified the mesh, but it hasn't actually applied the change, it now behaves as expected.

Fixed Niagara VM bytecode generation for if blocks when a variable was assigned and then used within the same block.

Fixed VM bytecode generation which was failing in a very small number of cases of the form:

A = GetFirstValue;

B = A;

A = GetSecondValue;

C = A; This would get GetSecondValue assigned to C instead of GetFirstValue.

Added an SSA pass to help reduce overwriting registers. This added logic removes self assignments, and adds logic to stop propagating when values are dirtied. From a sampling of scripts, about 2% are changed (where 1-3 unnecessary ops have been deleted).

Niagara shaders now respect r.DumpShaderDebugWorkerCommandLine as expected.

Implemented fixes for experimental compressed particle systems.

Only particle systems will have their attributes compressed.

Previous versions of our deny list will also be denied compression (we don't want to be comparing half Particles.Previous.Position with float Particles.Position).

Fixed stride being supplied to VF shaders.

Added a work around for an issue when Niagara GPU scripts for the editor platform would have compile requests that were never properly handled, including being put into DDC. This happened when compile requests were dirty on load.

Made sure that DataInterface curves are consistent with respect to UpdateTimeRanges and BuildLUT for WITH_EDITORONLY_DATA.

Fixed a bug where the Niagara stack did not reflect the compile status correctly, and only updated error symbols after clicking on it.

Transient systems created during script merging are now reset.

New:

Added initial support for rendering water in the Path Tracer.

Exposed a missing path tracing show flag in scene captures.

New:

Added support for a Screen Space Reflection input pass to scene view extensions, which mirrors the post-process Material blend location.

Extended Luminance Range is enabled for new projects by default.

Improvement:

Improved pixel shader animation and translucencies no longer ghost as much as in UE5.

Local exposure is now applied when calculating bloom.

Crash Fix:

Prevent crashes with post process materials when one of them is not a Material Instance and it tries to blend the parameters. The easiest fix is just to skip blending the materials together. The blending functions below only work on instances, so skip blending if we are just a material interface. This can happen in two scenarios: 1) A wrong material type is assigned into the post process material array, and 2) the same material is placed in twice. The MID lookup code above won't create two separate MIDs for the same material, resulting in this code trying to blend a MID with a Material Interface.

Bug Fix:

Fixed an issue with PlanckianIsothermal in TonemapCommon.ush

New:

Added parallel setup for Render Dependency Graph (RDG) passes, and offloaded RDG buffer uploads and uniform buffer creations off the render thread.

Changed the minimum driver version for Nanite on Vulkan, and also added a check for Linux.

On the Vulkan RHI, added an option to change pipeline queries to BOTTOM_OF_PIPE. This gives more precise measures for a single span, but might alter overall frame time on some platforms. TOP_OF_PIPE remains the default.

A draw texture utility was added to RenderGraphUtils, which is used for copying with format conversions.

Implemented support for parallel buffer creation and lock/unlock.

All platforms now use the same Vulkan SKD flow for compilation to ensure that the engine is always built with the provided version at a minimum. A local SDK is only preferred if it is newer.

Local uniform buffers were deprecated, as RHICreateUniformBuffer now works on any thread.

On Vulkan, DriverDenyList entries were split per operating system, as driver numbering is different on each OS.

DriverDenyList support was added to Linux.

Added DriverDenyList entries for Vulkan on Windows and Linux.

Added Render Graph (RDG) versions of UnifiedBuffer utilities.

For Vulkan, fixed all cases of single scalar in shader parameter arrays to respect 16 byte alignment.

Added static_assert to prevent the creation of new asserts moving forward. Used SHADER_PARAMETER_SCALAR_ARRAY/GET_SCALAR_ARRAY_ELEMENT for single parameters, or packed them with surrounding parameters when possible.

Added "ultimate" version of AddClearRenderTargetPass that lets the user clear multiple mips, multiple array slices, with / without a custom clear color or viewport and does so by using a clear action if possible. Note that the existing versions have not been deprecated since they are more straightforward (they clear only a single mip/slice).

In Vulkan, use vk_enum_string_helper to print enum names in debug messages.

Implemented support for fused CopySrc | CopyDest transitions for Vulkan in RDG.

In Vulkan, we set the initial state of GParticleCurveTexture to SRVMask since it might get bound before it is filled for the first time. This fixes a validation error.

Added support for RHI validation breadcrumb logging with transition validation errors.

Added parallel UpdateUniformBuffer support by taking a command list.

Made RHICreateUniformBuffer thread safe.

Added bindless resource support as a requirement for ray tracing on PC (SM 6.6 + Resource Binding Tier 3). Compile DXR shaders using the same profile when targeting PCD3D_SM5 and PCD3D_SM6 (for example,. lib_6_6 or lib_6_5 based on USE_SHADER_MODEL_6_6 define).

Ensure that BC6+7 textures have good mappings on all platforms and RHIs, including ES3.1 RHI for performance mode. BC6+7 should now be useful in multi-platform games.

Only set the D3D12 residency priority for acceleration structure resources on pool creation, rather than on individual BLAS creation. Saves significant CPU time when creating transient (short-lived) acceleration structures.

Use D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_IN / OUT instead of just IN for GPU bread crumbs. This is more accurate when there are multiple GPU commands back-to-back without barriers. However it may be slightly more expensive when many breadcrumbs are inserted. This also fixes MaxParameterCount in FD3D12CommandContext::WriteGPUEventStackToBreadCrumbData and slightly refactors FD3D12CommandListManager::FDiagnosticBuffer.

Reduced redundant D3D12 PSOs by ignoring vertex stream strides when computing the PSO cache key. D3D12_INPUT_LAYOUT_DESC part of D3D12 graphics PSO descriptor only includes the format, slot/semantic index, and so on. The stride is set at draw time using ID3D12GraphicsCommandList::IASetVertexBuffers. This saves a small percentage of total created low-level PSOs.

Added the r.RayTracing.EnableInEditor and r.RayTracing.EnableInGame console variables to control whether ray tracing effects should be enabled by default in the editor and in game (if corresponding game user setting does not exist).

Added support for creating raw buffer SRVs for any buffer in D3D12. In some RHIs, a raw buffer view can only be created if the buffer itself was originally created with a corresponding flag. However, modern RHIs such as D3D12 allow creating raw views for any buffer. This change adds FRawBufferShaderResourceViewInitializer to create raw views of buffers when GRHISupportsRawViewsForAnyBuffer is true.

Added Raster Ordered View (ROV) type support for shader binding.

Skip redundant calls to ID3D12Device5::SetResidencyPriority, which are extremely expensive The current priority can be stored in the D3D12 resource private data and redundant priority setting can be skipped. This is important for buffer allocations coming from CreateRayTracingBuffer.

Added the r.RayTracing.RequireSM6 console variable which can be used to only compile ray tracing shaders when targeting the SM6 D3D12 shader format.

Added Shader Model 6 warning dialogs, so that if a static mesh is detected to use Nanite, or a project is configured to use Virtual Shadow Maps and SM6 is not enabled in the project settings, a warning shows that SM6 needs to be enabled. Both cases only warn if the project was already configured to use a D3D platform.

Added an option for enabling Nanite in Project Settings.

Adding initial experimental D3D12 bindless support.

Added public interfaces and data for initial experimental bindless support.

Reworking shader platform settings on Windows to be per-RHI. This removes the ill-fated "min/max feature level" configs that can cause confusion. On Windows, "TargetedRHIs" is now split into "D3D11TargetedShaderFormats", "D3D12TargetedShaderFormats" and "VulkanTargetedShaderFormats". "TargetedRHIs" is still parsed for backwards compatibility. Using this, projects can now be more easily configured for D3D12-only or even Vulkan-only.

Updated FShaderFormatsPropertyDetails to use FName instead of FString for shader platforms. Also added a filtering method for mixed RHI platforms like Windows.

Reflection data is now included with SM6 embedded PDBs.

Added initial GetResourceFromHeap and GetSamplerFromHeap support.

Added TexCreate_Shared to FD3D11Texture3D.

Added a minimal interface to OpenGLDrv.

Added ERHIInterfaceType so the public RHIs can identify themselves.

Added templated GetDynamicRHI to avoid accidental Validation DynamicRHI casts.

Added depth clip control to the rasterizer state.

Added VRS D3D12RHI updates for defer ShadingRateImage binding to State Cache. Previously, we would bind the shading rate image plus related combiners as part of SetRenderTargetsAndClear. Instead, VRS images can now use the state cache infrastructure to reduce binding overhead.

Added "Supports Ray Tracing" to platform properties. This is checked in addition to the project/platform settings for RayTracing but is opt-in per platform instead of always enabled if the setting is enabled. This has the effect of reducing the number of platforms that say they support RayTracing which directly reduces the number of shader platforms that "support" RayTracing.

Added D3D12 Mesh shader support for ID3D12Device8, ID3D12Device9, and ID3D12Device10.

Created FShaderParameterMap::FindParameterAllocation method that returns the parameter struct instead of using reference parameters.

Implemented a change to migrate back to using UniformBuffer structs since the cbuffer uses the same name as the struct, we have to rename the cbuffer using a consistent prefix. The reflection handling also needs to reinterpret the renamed cbuffer as the correct UniformBuffer.

Added the ability to create a per-platform public interface for D3D12RHI.

Added Create functions to FRDGTextureDesc, which now derives from FRHITextureDesc instead of being an alias.

Improvement:

Added log messages for when D3D12CreateDevice fails.

FCubemapTexturePropertiesPS permutations have been modernized.

Changed WindowsTargetSettingsDetails to use shared functions to describe shader platforms.

Renderer dependency cleaned up by removing RenderGraph.h from SceneRenderTargetParameters.h.

Updated Agility SDK to 1.602.0

Refactored D3D12 descriptor management to go through a central manager.

Restored functionality to r.ShaderCompiler.EmitWarningsOnLoad.

Added more DXGISwapChain and DXGIFactory coverage in D3D12 and cleaned up adapter/swapchain code with available types.

D3D12RHI QuantizeBoundShaderState implementations now return the struct instead of taking it as an argument.

Moved ShaderParameterParser into its own source files.

Moved the bulk of SetShaderParameters to ShaderParameterStruct.cpp.

Shader reflection handling has been reorganized to funnel through common functions.

Moved D3D12RHI::ExecuteCodeWithCopyCommandQueueUsage into ID3D12DynamicRHI::RHIExecuteOnCopyCommandQueue.

Cleaned up the DXGI includes in D3D121RHI.

D3D12 descriptor heap size checks have been extended to allow for proper binding tier 3 support.

Moved Vulkan and OpenGL implementations of ApplyStaticUniformBuffers out of headers to remove header dependency on RHICore.

Reworked the parameter rewrite code to support automatic bindless conversion.

The Max RHIFeatureLevel is now output to the log on D3D12RHI creation.

Cleaned up D3D12 SRV and UAV implementations. Primarily renaming the "Initialize" methods to be more verbose about when they're called in relation to when the view is created. This allows us to identify when a CreateView call is for a newly-allocated descriptor or one that's been around for a while. Stubs added for deferred updates to bindless descriptors, not implemented yet. Unified a few RHI commands in RHICreateShaderResourceView to use a single command. Removed FD3D12ShaderResourceViewWithLocation and FD3D12UnorderedAccessViewWithLocation since they're no longer used.

Renamed the ShaderPrint uniform buffer to ShaderPrintData so it no longer collides with ShaderPrint() functions.

Switched ERHIFeatureLevel:SM6 from SM6.5 to SM6.6 in order to use the built-in 64-bit atomics.

Added TypedUAVLoad support checking for D3D12.

Added bNeedsExtraShaderFormats to TargetRules to protect hidden platforms from exposing their DataDrivenPlatformInfo defines to other hidden platforms.

D3D12 Mesh shader support will now be checked with all other CheckFeatureSupport calls.

Mesh shader support is now validated before creating D3D12 Mesh and Amplification shaders.

SetShaderParameters implementations have been cleaned up using a new helper class that loads parameters from passed in binary blobs.

DXGI includes have been cleaned up in D3D11RHI.

D3D12 Root Signature creation is now unified under a common path.

Updated Intel ExtensionsFramework version and added Intel Runtime support for atomic 64.

Added proper lifetime management to resources used by FRHICommandD3D12UpdateUniformBuffer

Updated the check for aliased textures in FD3D12TextureStats.

Launching a game that isn't cooked with any shader formats for the selected RHI now shows an error dialog before fatally quitting.

Added GRHISupportsLargerVariableRateShadingSizes to control support of 2x4/4x2/4x4 tile sizes. On D3D12, this maps to D3D12_FEATURE_DATA_D3D12_OPTIONS6::AdditionalShadingRatesSupported.

FRHITextureCreateDesc can now be constructed functionally via reference-returning Set functions.

Crash Fix:

Fixed a crash with Landscapes when using -rhivalidation. This fix ensures that the RHIBuffer is held for the life of the frame, as not all RHI backends have the Shader Resource View (SRV) to maintain a hard reference to the source buffer.

Implemented changes to avoid using the "groupshared bool" on Vulkan, as it has issues on some NVIDIA drivers. This fixes a crash in Vulkan engine tests (and playback of D3D12 captures in RenderDoc).

Fixed crashes that occurred when rendering offscreen in D3D12.

Bug Fix:

Fixed an assert when booting the QAGame Editor. Needed to use EnumHasAllFlags instead of EnumHasAnyFlags when testing BUF_RayTracingScratch, because it's a compound flag.

Fixed a bug with DriverDenyList support for Vulkan where no driver date was invalidating entries.

Fixed an issue with ProfileGPU scoping error in D3D12 where it erroneously included async compute scopes in the device GPU profiler stack.

In Vulkan, fixed a validation error where a view was created beyond its number of slices when the first slice index was offset.

Applied a fix for double signal of GPU fence in DX12 when performing All -> Graphics transition.

In Vulkan, allow MOBILE_EMULATION to be defined in VULKAN_PROFILE shaders. This fixes the gizmo not appearing when using Vulkan for Android emulation (alpha channel was not being set correctly for composite pass).

In Vulkan, when a slice is specified, create the view for only that slice or layouts will be altered by the render pass for other slices. Fixes bad layouts in Vulkan Mobile Preview.

Fixed a validation issue (in CitySample) with 2D copies using 0 as a Z component. This was resolved by adding DebugName to validation layer messages.

Fixed Anisotropy EngineTests on Vulkan.

Fixed a bug in CheckAllWritten() on Vulkan, and enabled it for graphic pipelines.

Fixed Render Dependency Graph culling behavior differences between Clang and Microsoft Visual C++ (MSVC) due to static initialization of shader parameter metadata.

Resolved a bug with texture 2D array resource creation.

Unified the DataDrivePlatformInfo for VULKAN_SM5 in a common VulkanPC fake platform to prevent settings on different platforms from overwriting one another. Previously they would all fill the same VULKAN_SMS in the FGenericDataDrivenShaderPlatformInfo::Infos array.

Fixed validation errors for unfreed resources which caused a loop on shutdown for as long as there were new entries to delete.

Added RHICopyTexture unit tests and fixed inconsistencies and bugs in that code.

Fixed validation errors on Vulkan where 2D default textures were used for Texture3D parameters.

Added BlackArrayDummy to system textures (single black pixel slice-texture array) because Metal requires texture arrays to be bound to texture array parameters.

Implemented changes to prevent collisions in the CurrentlyDeleting assert between an RHIThread running FRHIResource::FlushPendingDeletes and workers creating PSOs.

Fixed an issue with D3D12 validation errors encountered on the ray tracing indirect buffer. This was solved by duplicating relevant logic from GetResourceDescAndAlignment() into the ray tracing indirect buffer creation path so that D3D12RHI_RESOURCE_FLAG_ALLOW_INDIRECT_BUFFER is included for indirect buffers.

Fixed an issue with the SRV array slice not referencing the correct subresource in the Render Dependency Graph.

Fixed an issue where dxgi.dll was being freed before it was used.

Fixed an issue where view states were being set to the wrong FeatureLevel due to ULocalPlayer::PostInitProperties() creating view states before the UWorld was initialized.

RHI-specific arguments are now passed to launched processes as expected.

Implemented a workaround fix for the O0 crash in DXC when compiling FPathTracingRG.

Fixed issues involving RemoveUniformBuffersFromSource implicitly calling TransformStringIntoCharacterArray.

Fixed the missing VRS image state for XSX.

The Windows Feature Level checkboxes should now prompt the user to restart.

Addressed issues caused by improper handling of multi-plane texture formats.

Launching the Editor without selecting feature levels will now fall back to default feature levels as expected.

Fixed an issue where shader cooker stats would show incorrect shader format names.

Fixed instances where FRHITexture*Desc types were being used incorrectly instead of FRDGTextureDesc types.

Deprecated:

Deprecated CopyToResolveTarget method.

Deprecate D3D12RHI::ExecuteCodeWithCopyCommandQueueUsage.

Deprecated RHICreateTexture2DArray, RHICreateTexture3D, RHICreateTextureCube, and RHICreateTextureCubeArray.

Deprecated RHI*CommandList::SetComputeShader and switching to the PSO cache's SetComputePipelineState to move towards ComputerPipelineState as the default binding method.

Deprecated all of the Create functions in FRHITextureDesc.

Removed:

Removing the majority of D3D12RHI_API uses.

Removed the "equality comparison with extraneous parentheses" warning from DXC compiles.

Removed the Experimental label from PCD3D_SM6.

Removed more uses of GMaxRHIFeatureLevel. Focus started on GenerateMips and AddClearUAVPass.

Removed deprecated RHI functions.

Removed private RHI header includes.

Removed unnecessary dependencies on RHICore and RHI ThirdParty libraries.

Removed deprecated EShaderPlatform entries.

Removed the long-form create functions and constructors from FRHITextureCreateDesc in favor of the shorter versions.

New:

Implemented ‘Lightmass Replace' material expression to work with GPU Lightmass This allows static lighting to be baked with a simpler material, or to tweak the color of indirect lighting through the material graph.

For this release, we recommend using the NVIDIA driver 522.25. Later versions of the driver are known to cause issues at this time.

Simulation

API Change:

Exposed proximity tolerance as a parameter.

Chaos Immediate Physics which is used by Rigid Body Animation Nodes (RBAN) now creates a straight capsule body when a tapered capsule is requested in ChaosInterface::CreateGeometry. Previously tapered capsules defined in physics assets were just ignored. The new capsule will have a radius equal to the mean of the requested tapered capsule's radii.

Removed the console variable p.ChaosCloth.Solver.UseImprovedTimeStepSmoothing since there is no more solver dedicated code for the time step smoothing. A new console variable p.ChaosCloth.UseTimeStepSmoothing, which defaults to 1, has also been added to completely disable time step smoothing if ever desired.

New:

Added timestep post-processing in PBD evolution.

Added PoissonSolve function.

Add a 'skip fraction' to the custom Voronoi fracture tool, to remove a percentage of the 'live' sites.

Reduced the size of UPhysicsConstraintTemplate to 1008, so it fits in a smaller FMallocBinned2 pool.

Added a normals baking option to Fracture's AutoUV tool.

Added a grid distribution option for fracture mesh cut.

Added a 'custom' fracture pattern tool to support more user control of Voronoi fractures.

For optimization, RBAN memory usage has been reduced.

For Cloth, the Delete Cloth Asset button's tooltip has been updated.

Reduced memory footprint for triangle mesh implicit object when using LWC.

Added the missing Local Damping Coefficient in the SetDamping Blueprint function for Choas Cloth.

Added a menu option for the grab/poke interaction distance in the Physics Asset Tool.

Unregistered the cloth tick function whenever the owner Skeletal Mesh Component tick is disabled.

Changed the Physics Asset Tool simulate key to Alt + I.

Added an asset exporter abstract interface, and made it appear from the right click menu of the Clothing window whenever a corresponding modular feature is added.

Exposed per-axis constraint drive strengths etc on ConstraintInstance.

Updated Rigid Body Animation Nodes (RBAN) tonow optionally add kinematic objects at runtime to represent any Cloth Colliders defined in a parent skeleton. This can be used to improve the behavior of RBAN alternatives to cloth simulation (often used at lower LODs).

Added a Checkbox called Use External Cloth Collision on the RBAN node preferences panel to enable the kinematic objects feature.

Optimized the generation of geometry collections connection graphs has been.

Made the fracture mode interactive selection tool's "keep fraction" option attempt to space out the bones it keeps, rather than choosing completely at random. Gave user control of the random seed.

Added leaf and cluster selection tools to Fracture Mode

Improved the Children selection tool in Fracture Mode to not deselect nodes with no children.

Added project-default convex generation settings to Fracture Mode's project settings.

*Updated the Convex tool to include buttons to save and load convex generation settings.

We now apply project-default convex generation settings to all new or reset geometry collections.

Added an option to skip automatic removal of overlaps between neighboring hulls In the geometry collection convex hull generation settings.

New instance of geometry collections will now properly be initialized using the corresponding asset damage threshold array

Added AddImpulse and AddRadialImpulse functions to Geometry Collection component.

Added support for convex shapes in FBodyInstance GetShortestDistanceToPoint and GetClosestPointAndNormal methods.

Query based events now set ItemIndex when the hit component is a geometry collection corresponding to one of its specific parts.

Added multiple blueprint function taking this ItemIndex as an input allowing users to apply strain and/or break to specific part of the geometry collection.

Updated the CollisionObjectReductionPercentage geometry collection setting to also apply to convex collision, where it previously was restricted to other types of simple collision.

Added a flag on RigidBody AnimNode to allow it to use synchronous physics simulation.

Renamed CVar to p.RigidBodyNode.DeferredSimulationDefault to reflect that it's the project default, not an override.

Added an option to the AutoCluster tool in Fracture Mode to choose number of Voronoi sites as a fraction of total children to cluster, instead of directly specifying the number

Added options to the AutoCluster tool to (try to) prevent creating isolated children, by merging such clusters with neighbors, and clusters of all children (by skipping cluster creation in that case).

Added the ability for a geometry collection component to opt-out from sleep and/or break removal logic set on the asset.

Added a merge-selected-only option to the Fracture Mode TinyGeo tool, and stop selecting all after every merge.

Updated Geometry collections to now properly account for static meshes BuildScale parameter when importing geometry.

Added support for CCD, linear and angular damping for geometry collections.

Added asset-level option to use size specific damage thresholds for geometry collections.

Updated a number of the Fracture Mode tools run expensive computations in a background thread, with a regularly-sampled progress/cancel UI. This includes the Fracture tools such as Voronoi, Plane, and Mesh, as well as the AutoUV tool.

Added support for Enable Gravity parameter for geometry collections – only accounted for at initialization.

Updated the Convex builder to now use a new convex hull generation algorithm.

Updated the Geometry Collection Break events to now return the index of the specific piece. This "ItemIndex" can now be used to call blueprint functions targeting specific parts of the geometry collection.

Improved remove on max sleep feature for geometry collections to be able to also remove slow moving pieces, allowing for more efficient removal behavior.

Partial clusters will now crumble into smaller pieces after a certain time if remove on max sleep is enabled

Optimized collision impulse processing for Geometry Collections.

Added AddForce, AddRadialForce, and AddTorqueInRadians functions to Geometry Collection component.

Added interpolated asynchronous physics support for geometry collections.

Updated the p.ChaosCloth.Ispc command to register during static initialization (and in test builds), so it can be changed at startup for automated/unattended testing.

Added support for the Start Awake parameter for geometry collections.

Added a "Keep Frac" setting to the fracture interactive selection tool, to allow dropping a random fraction of the selection filter.

Provided an optimized code path for mostly vertical sweeps )

Added particle velocity visualization.

Changed the aerodynamic forces visualization colors depending on whether the particles are kinematic or dynamic.

Added support for Geometry Collections in Mesh Painting mode.

Geometry collection fragments hidden using the Fracture Editor Hide tool will now be excluded from the simulation.

Improved Chaos Cloth bending elements to be much more stable and correct, especially when the initial rest shape is not flat.

Added the "Buckling" feature in Chaos Cloth (i.e., biphasic materials), which adds "Buckling Stiffness" and "Buckling Ratio".

Updated Chaos Cloth bending element will now use its Buckling Stiffness rather than its Bending Stiffness once the cloth has bent beyond the limit set by Buckling Ratio.

Added options on geometry collection creation:

Ask if the user wants to duplicate input materials to create internal material slots.

Ask if the user wants to split the mesh by connected components, creating separate bones for each component.

Improved the names and organization of the geometry collection convex hull generation settings.

Overlap removal settings are now a separate group

Renamed "Can Exceed Fraction" to "Allow Larger Hull Fraction"

Renamed "Can Remove Fraction" to "Max Removal Fraction" and moved it to the overlap removal settings group.

Renamed the GeoMr' tool to TinyGeo in Fracture Mode.

Added a new GeoMrg tool in the 'edit' category which just merges the geometry from selected bones.

Added new blueprint functions to apply external and internal strain to specific geometry collection fragments.

Updated the Fracture Mode's validation tool into a modal tool with options, so the user can see what it will and won't do. Also added an option for it to remove 'clusters of one.'

Added the Chaos Cloth Air Pressure Field (Normal displacement). This adds a new "Pressure" field and map to cloth which is used to model a difference in air pressure on two sides of cloth (e.g., inflatable objects, puffy jackets, pillows).

Updated the fracture tools to propagate vertex colors internally on fracture via a smooth solve, so vertex colors are consistent within a fractured mesh.

Added standard fracture settings (including random seed to control the cut distribution) back to the Mesh fracture tool, except not Grout and Noise (as these aren't supported).

Updated Geometry collection to now caching their local bounds to reduce runtime overhead.

Updated Edge and Bending constraint debug drawing colors to be based on their parallel graph coloring. Constraints solved in parallel are the same color. This is largely for developer debugging, so you probably don't need to worry about it, but this is what the color change means!

Added the ability to define a timer for fragments ( including clusters) to be removed after a certain amount of time. This adds a new Remove On Break tool in the Fracture Editor that allows to set those parameters per fragment

Added several geometry collection blueprint functions to control individual fragments by applying linear and angular velocity as well as getting their initial level in the hierarchy.

Updated Existing Self Collisions in Chaos cloth (enabled via "Use Self Collisions") to now take normals into account and have a "Self Collision Friction" coefficient.

Updated Self collisions Chaos cloth to be (slightly) faster, especially on hardware with a lot of CPU parallelism. It is still not recommended to use self collisions where speed is critical.

Added a new "Use Self Intersections" flag has been added which will fix self intersections that were missed by the existing Self Collisions algorithm. This feature is highly experimental with significant changes and improvements expected in future releases.

Added anchored property to anchor a geometry collection fragment which allows it to hold the structure while still being able to be removed unlike setting its initial state to kinematic. This can be set by using the right-click menu in the hierarchy in the Fracture editor outliner.

Updated transient / un-Saved properties to work more logically for Geometry Collection data:

The ManagedArrayCollection 'Saved' flag controls whether the whole property is saved, rather than just its data.

Always save everything when transacting (ignore the Saved flag) Also when loading, remove properties that were not in the map that was loaded from.

Stop manually removing some unsaved attributes, as the Saved flag should take care of that instead.

Stop loading from the DDC (after already loading from the transaction history) for every undo/redo transaction.

Changed the geometry collection 'remove overlaps' fracture convex generation option to support more options -- specifically adding options to only remove overlaps on clusters, or overlaps of clusters with other clusters.

Added a Convex OverlapRemovalShrinkPercent variable to the geometry collection convex generation settings, to compute overlap removal on scaled-down convex hulls (without baking that scale into the hull). This gives additional flexibility when overlap removal is removing too much of the collision volumes.

Bug Fix:

Fixed hit event not reporting other component or actor when it is a geometry collection component.

Fixed crash in fracture mode AutoCluster tool when there are no bones

Disable radial fracture position (center, normal) settings when position is controlled by gizmo. Update tooltips to explain why they're disabled.

Updated Chaos Cloth to reset the field's outputs to avoid it affecting the cloth once it is no longer active.

Restricted the solver field update in Chaos Cloth to the currently active LOD set of particles, thus avoiding unnecessary updates for the inactive LODs.

Fixed the Chaos Shared Config ownership that was preventing some Skeletal Mesh assets from being saved once the first/original cloth asset owner had been deleted.

Fixed an issue in Chaos Cloth where the collision particles index wasn't reset during an LOD change, and was causing the external collision sources to be re-added multiple times.

Geometry Collection: Fixed shape generation not properly using relative size when clustering is on.

Fixed the stiffness exponentiation calculations in Chaos Cloth. Prevented a 0 Low or High painted stiffness to be turned into a small stiffness whose effect is still perceivable on all related constraints when values are close to 0 and 1.

Fixed issue where adding an element to the size specific array in a geometry collection asset details would sometimes add two.

Fixed a crash when FParallelClothTask::GetDesiredThread() was called outside of the game thread.

Fixed issue with heightfield depth computation when sample point is outside of the XY bounds of the heightfield.

Fixed convex generation to properly remove internal and invalid faces.

Updated Fracture Mode to only auto-scroll to bones in the outliner/histogram if they are selected via a single bone selection in the 3D view. This prevents the outliner view from auto-scrolling to the first bone in the list after every click while the user is multi-selecting within the outliner itself.

Fixed rotated box-shaped fields that resulted in a smaller area of effect than expected.

Fixed non-nanite cached geometry collections not properly updating their bounds in editor when using sequencer.

Fixed Geometry Collection's size specific damage threshold calculation to now properly accounting for max cluster level value.

Fixed inertia tensor calculation for geometry collection clusters when the original mesh has a world transform with a non zero rotation.

Improved performance of proximity detection when fracturing very large meshes, especially for meshes with regular face orientations.

Fixed inertia calculation for scaled geometry collection.

Deleted geometry collection components are now properly handled by the Chaos-Niagara interface.

Fixed complex collision display for spline mesh components.

Factorized FMeshBatch spline setup code.

Fixed a performance problem that caused the editor to take a very long time to convert a set of large static meshes to geometry collections.

Fixed issue where sleeping geometry collections could be unexpectedly woken up by distant fields.

Fixed performance bug in fracture mode that could cause a very long processing time on reset of a large geometry collection with many input parts.

Fixed an edge case where running sweep queries against dirty elements in the AABBTree could lead to an infinite loop.

Fixed issue where kinematically moving geometry collection would have their velocity set to 0 when activated by a field.

Chaos Cloth: Fixed the velocity calculations when MaxPhysicsDelta kicks in, preventing the cloth from receiving excessive impulses as the time step gets clamped.

Fixed capsule ray-cast sometimes returning false negatives.

Fixed off-centered rotations issues for geometry collections when using asynchronous physics or caching.

Fixed a crash due to fracture mode outliner being out of sync with geometry after an undo or redo.

Fixed Geometry Collection hit proxies rendering incorrectly for triangles referencing a few vertices in each buffer, due to an incorrect offset parameter.

Fixed geometry collection hit proxies rendering incorrectly in fracture mode when not actively selecting bones.

Fixed smoothed velocities computation that could cause rigid bodies to flip between a sleeping and dynamic state while falling if they add a small force applied to them.

Moved smoothed time step operations out of the solver of Chaos Cloth, leveraging the velocity scale to avoid cloth tugging issues. This also allows for more drastic change in time steps without causing the simulation to explode, as when using the slomo command for example.

Fixed the fracture mode AutoUV tool to use more appropriate texture types when baking. For example, using linear rather than sRGB mapping when encoding values like distances, curvatures, and normals.

Updated the fracture mode brick tool to work correctly with zero grout, rather than forcing the grout to always be non-zero.

Fixed Chaos cache manager not working after resetting a cached geometry collection.

Fixed the fracture mesh tool creating a very deep hierarchy when applying multiple cuts; it now only adds one level of children for a given fractured bone.

Fixed character movement interaction with scaled geometry collections.

Fixed bug where a blueprint Chaos collision event would not properly set the OtherComponent property.

Fixed the fracture mode AutoUV tool's box projection feature sometimes messing up unrelated UV layers, and generating bad results for isolated triangles.

Resolved rare crash when dynamically creating and deleting Chaos vehicles.

Fixed Fractures to now be computed in a consistent local space, rather than globally. This makes the noise applied to fracture surfaces not depend on the world-space position of the geometry collection.

Fixed fracture mode capturing 'escape' when in PIE and simulate modes, making it difficult to leave the mode.

Fixed cook warning related to selection material in geometry collection.

Fixed cached geometry collection bounds not being updated properly when scrubbing start time from caches in editor mode, causing them to sometimes be wrongly culled by the rendering system in editor.

Fixed crash attempting to retrieve shapes from a body instance that has no actor instance (e.g. welded bodies).

Fixed incorrect identification of owned instance shapes in GetSquaredDistanceToBody for welded instances.

Enabled mask filters for Chaos collision.

Adjusted zero-component scale behavior to always pass a valid scale to avoid creating invalid body instances due to invalid scales

Fixed physical material resolve for landscapes with a simple collision mip enabled. Both material assignments and holes should be represented correctly now.

Fixed rigid bodies no longer colliding after being constrained with a constraint using "Disable Collision". After the constraint breaks we now update the ignore manager for the bodies in question to re-enable their interaction.

Fixed incorrect class filter for default destructible material to allow proper selection and avoid warnings for missing classes.

Fixed exports of UShapeComponent templated methods so that the explicit instantiations can be called from external modules.

Minor Chaos non-unity build fixes.

Added warning for default physics collision handler to catch invalid actor references in pending collision lists.

Fixed player collision mode rendering of convex elements which was previously not taking element transforms into account.

Fixed use-after-move when building unions of implicit objects.

Fixed OnHit event propagation to correctly identify the shape that the collision came from and the component that owns it.

Added a memory barrier to TObjectPool to ensure no writes to the head block will reorder beyond grabbing a free item pointer

Fixed erroneous deleter being used for derived types of FProxyTimestampBase

Fixed physical material mask set operation causing the map array to endlessly expand on repeated calls.

Fixed a few control paths that could lead to the dirty grid acceleration in scene queries to get caught inside an infinite loop which was showing up as a write-deadlock on the main thread

Fixed disabled constraints never being removed from the constraint graph leading to severe performance degradation after long runtimes. Fixed disabled constraints never being removed from their owning particle joint lists - leading to dangling joint pointers in the particles.

Fixed geometry collection/provider asserting that its geometry is of inner types without unwrapping its implicit.

Fixed the cast helpers for Chaos geometries only accepting callable objects that return value types.

Changed null actor release message from Warning to Verbose as it is a valid code path currently when welding shapes into a body instance of a parent that is set to NoCollision.

Fixed a bug that was preventing physics constraint forces from being reported.

Hoisted branch evaluation allocations out of AABB inner loops, reduces repeated allocations within a frame when objects move in Chaos scenes.

Removed ensure in GetWorldVelocityAtPoint that required the object to be kinematic or dynamic. It is valid to request a velocity from a static object without firing an ensure - the velocity will always be zero in that case.

Fixed incorrect access to inner physics materials during update when a material had not yet been created.

Re-enabled scene-wide physics collision handler customization.

Grouped sibling choice and cost for AABBTree leaf insertion to avoid double cache misses.

Refactored nodes to be smaller so more nodes fit in a cache line.

Altered node access pattern during FindSibling to avoid repeated indirection through the Node array.

Fixed incorrect joint constraint termination leading to memory leaks and dangling joints that slow down the solver.

Changed coincident vertex Warning during tri-mesh cleaning to Display. This is a recoverable issue as we just delete those triangles and move on. Display will still message to the user that there are invalid triangles to address.

Deprecated:

Deprecated remove on fracture option for Geometry collections - this is now replaced by recently introduced and more flexible remove on break

New:

Upgraded Blosc to version 1.21.0

Added support for OpenVDB and Blosc on Mac and Linux in addition to Windows.

UI

New:

Added new LLM subtags for UI and increased UI LLM coverage.

Added a Blueprint-callable setter for bHideInputAction on CommonButtonBase.

API Change:

As the FTextBlockStyle is now embedded in the FEditableTextBoxStyle, it cannot be initialized the exact same way. If you need, you can now configure the FTextBlockStyle of an FEditableTextBoxStyle by calling SetTextStyle on it.

New:

Added InitialSortMode attribute to FColumn and STableColumnHeader. InitialSortMode will default to EColumnSortMode::Ascending as before.

Added icons for C++ widget classes.

Previously, UMG MultilineEditableTextBox contained both a Font with an EditableTextBoxStyle, and another Font with a TextBlockStyle. This was error-prone as it was not clear which one was supposed to be modified. To solve this duplication issue, the Font from the EditableTextBoxStyle has been removed, and the TextBlockStyle has been moved from the MultilineEditableTextBox to the EditableTextBoxStyle.

Added general support for external per-mode widgets to be displayed by UMG editor. This improves UMG editor extensibility.

Crash Fix:

Fixed a crash that would occur when capturing callstacks using Slate Insights in editor.

Bug Fix:

Fixed an issue where FDirectoryPath properties failed to disable the path selection button when the property is disabled.

Fixed the checkbox style on editor utility widgets.

Addressed an issue where zero-sized scissor rects were not culled.

Fixed an issue where the mouse was not properly locked to the game window.

Fixed several issues with Slate line and spline rendering.

Addressed an issue where SDockTab::OnTabClosed would not fire when the tabs were removed.

Fixed an issue causing slider and text selections to be offset when displaying in non-standard viewport resolutions.

Fixed the order of parameters in KeyEvent.

New:

Keyboard input type overrides are now available for Spinbox

Added an option to make moved widgets only invalidate the SWorldWidgetScreenLayer if they are visible.

Added list reordering to widget animations.

Added DrawSpline to Widget Blueprint library.

Added a size overlay for the currently selected widget to the UMG editor.

Exported FCommonAnalogCursor from the CommonUI module.

Crash Fix:

Fixed a potential crash that would occur in UCommonButtonBase::RefreshDimensions when the preview widget is rebuilt.

Added guards against CommonUI action router not existing on game shutdown.

Bug Fix:

Safeguards have been added to prevent null entries from being added to a ListView with SetListItems

Setting a Margin variable in a parent blueprint now correctly updates child blueprint variables as well.

Fixed a bug that caused the cursor to disappear while using PIE with CommonUI.

Fixed widget references not updating in UMG Designer on compile.

Fixed issues preventing zoom from functioning well at small sizes in UMG Editor.

Fixed rounded box outlines when using default CommonUI style with full transparency.

Added missing broadcasts in CommonLazyImage and CommonLazyWidget.

Fixed editable text box default focused color black.

Editable texts will now react instantaneously to any change to the font settings done in the UMG designer. Previously it was necessary to force a refresh.

Virtual Production

New:

You can now predetermine the number of frames to capture when using MediaCapture.

Multi-User: Added an option/cvar for closing Sequencer when a sequence is closed by a remote user.

DMXFixtures: Fixed visibility logic on all light fixtures to make sure it's responsive.

Extended INetworkMessagingExtension to support network monitoring. Subscribers can provide bytes lost, bytes received, and bytes sent that can be displayed in a Multi-User Server session.

Changed the default console variable values for Concert.EnableOpenRemoteSequencer and for Concert.EnableSequencerPlaybackSync to be true.

Improved handling of World Partition levels in a Multi-User session.

Added a delegate to the IConcertClientWorkspace class to indicate that a workspace has been synced and finalized.

Added the LiveLinkFaceImporter plugin to the Unreal Editor source. Previously this plugin was only available on the marketplace.

Added a setting to control the size of the work send queue for Multi-User. Sessions with a large number of transactions and clients that join late may cause this queue to fill up and never recover.

Fixed incorrect values sent over Multi-User when using the Console Variable Editor.

VP Roles improvements:

Moved roles to a menu in the level editor toolbar.

Mde it easier to select/remove roles.

Added roles subsystem to provide a basic Blueprint API.

Added modifier key to increment/decrement timed data monitor offset by 10 and 0.1. By default, the Shift key will increment/decrement by 0.1, and the Control key will increment/decrement by 10.

Changed VirtualCamera plugin to Runtime.

Added a function to VCam Modifiers that allows them to access their associated name in the modifier stack.

Added an intermediate dialogue when creating VCam related Blueprints to prompt for an optional InputActionContext. This dialogue is used when creating VCam Modifiers or VCam Widgets.

Changed Right Click Asset Creation Menu to "VCam" from "Virtual Camera".

Exposed ILiveLinkClient::GetSourceType to Blueprints. Name changed to GetSourceTypeFromGuid to avoid conflict with existing GetSourceType function using a Source Handle.

Bug Fix:

Added additional precautions to deal with "slightly off" blocked ranges being set to control "blocked synced" playback.

Improved the TCPMessaging retry on connection failure mechanic.

Fixed blocked/synced playback timeouts with enabled audio playback on player setup. Syncing was disabled.

DMXFixtures now checks if a DMX component is valid before reading it to avoid warnings in Blueprints.

Added support for camera Field of View in beam shader.

Fixed division by zero in zoom component.

Trashed VCam components are now properly disabled when they are replaced in the Editor (usually via rerun construction scripts).

Made LiveLink an explicit requirement of the VirtualCamera plugin.

VCamComponent no longer tries to access the Live Link Client during cook.

Fixed an issue where VCam Modifier Names were resetting when changing modifier properties in the Details panel.

Deprecated:

DMXFixtures - Deprecated MinQuality and MaxQuality UProperties. Now using BeamQuality and ZoomQuality.

API Change:

CaptureSceneViewportImpl and CaptureRenderTargetImpl have been deprecated and replaced with InitializeCapture called for any type of capture and specific post initialize methods for each type of capture like PostInitializeCaptureViewport.

New:

Added an importer for ulens files. This makes it possible to associate a LensFile asset with a file on disk, so it can be reimported as well.

OpenEXR: Upgraded OpenEXR to version 3.1.5.

Updated MediaCapture to use RDG, and added structured buffer output support to media capture.

Added immediate rhi resource capture mode to MediaCapture.

Added support for UAV output configuration from media converter in media texture.

The Live Link API now allows deriving from LiveLinkProvider and MessageBusSource classes.

Added autodetection for Blackmagic genlock format.

Aja input format input is now autodetected by default.

Added automatic exporting of data collected during camera calibration to disk.

Added support for importing camera calibration datasets.

Added "Depth of Field Supported" flag to the LiveLink Camera Role to allow a LiveLink Source to enable/disable depth of field (Focus Override) on a Camera Component.

Media capture now automatically reopens media capture when media output is modified.

Added option to enable linear conversion when doing a media capture.

Added control key modifier to timed data buffer visualizer to zoom faster.

Added format autodetection for Aja timecode.

Added format autodetection for Aja Timecode Provider.

Added Aja GPU direct support for input. Enabled by the console variable MediaIO.EnableGPUDirectInput.

Renamed "Lens Distortion Component" to "Lens Component".

Fixed a bug to guarantee that a camera recorded with Take Recorder would have nodal offset baked into its recorded transform.

Added "Evaluation Mode" option to Lens Component to choose where the Focus and Zoom values used to evaluate a Lens File come from.

Added media playback buttons to the simulcam viewport to support pausing and seeking a file media source used for camera calibration.

Added ability for each controller in the LiveLink component to potentially control a different component.

Added "Distortion Source" setting to Lens Component, with options to use a Lens File, a LiveLink Lens subject, or to manually drive the distortion state.

Added "Filmback Override" setting to Lens Component, with options to use the filmback specified in a Lens File or a user-specified "Cropped Filmback".

Changed the Composure CG Layer setting to choose a Lens Component instead of a Distortion Source.

Deprecated Lens Distortion Handler Picker structure.

Deprecated methods for querying for a Lens Distortion Handler from the Camera Calibration Subsystem.

Added a new track recorder to Take Recorder to support recording distortion state from a Lens Component and applying distortion to a camera on playback of a level sequence.

Timed Data Monitor Improvements:

Put channels in alphabetical order in buffer visualizer.

Added buttons to increment/decrement frame offset and time evaluation offset.

Added dropdown to select evaluation offset type (frame vs seconds).

Fixed style not being registered resulting in white texture.

Added indicator in frame time to display when you are over your frame budget.

Added console command to reinitialize timecode and genlock. Commands are TimecodeProvider.Reset and CustomTimeStep.Reset.

Added support for Rivermax 2110 video streaming for input as a MediaSource.

Added support for Rivermax 2110 video streaming for output as a MediaOutput.

Bug Fix:

LensFile image dimensions are now saved on the asset itself.

Fixed IsChildOf called on nullptr in RemoteControl.

Fixed crash when adding LiveLink component.

Fixed a crash that happened when using file media capture with resolution that needs padding.

Fixed float FileMedia output expected stride.

Fixed crash caused by Media IO player not clearing itself from the timed data monitor system.

Fixed LiveLinkLightController not setting the LightComponent's "Use Temperature".

Fixed lens file import doing wrong coordinate conversion (unreal to opencv instead of the opposite).

Fixed Remote Control preset transactions being ignored by Multi-User.

Fixed NDisplay config "rebind all" not working if generated for a different config (Viewport properties excluded). Added context menu for rebinding viewport properties.

Fixed audio crashing when outputting audio with Blackmagic on Linux.

Fixed nDisplay exposed properties on viewports not being able to be rebound. Fixed some nDsplay properties changing to <multiple values> after being changed in the preset.

Fixed Blueprint event not being callable with raw Remote Control API.

In the Remote Control panel, exposing/unexposing now properly generates transactions in the undo history.

Fixed Aja media capture outputting a still image after unexpected engine closes.

Fixed Remote Control unexpose not working on nDisplay viewport properties.

Fixed desync between the Remote Control web interface and Unreal Engine when entering or exiting a Multi-User session.

New:

nDisplay: Added support for the resize tool in the OutputMapping UI to lock the aspect ratio when being dragged by holding shift.

New:

Added OpenColorIO support for selecting displays and views when available in the configuration file.

Improvement:

Added OpenColorIO plugin Blueprint function to activate color transforms in game mode, called "Create In-Game OpenColorIO Display Extension".

Added 32-bit float lookup table texture support in OpenColorIO for improved precision, exposed as a plugin setting.

OpenColorIO plugin now uses v2.1's new GPU processor, while maintaining legacy support via a plugin setting.

Bug Fix:

OpenColorIO source and destination color space conversion settings are now correctly reset if no longer available in the configuration.

Fixed OpenColorIO crashing on Mac when using Lumen overview viewports.

Improvement: Migrated OpenColorIO viewport settings from EditorPerProjectUserSettings.ini config to plugin-specific OpenColorIO.ini file.

Fixed mismatch in Composure between preview window and viewport: the tone curve is now consistently disabled by default, with option to re-enable.

Fixed media texture trilinear sampling with new style output.

New:

Added the first version of the Render Grid plugin (still in heavy development), which allows you to render several variations (different materials, colors, etc) of the same level sequence with ease.

Switchboard: Added a "Vulkan" option to the nDisplay "Render Mode" setting.

SwitchboardEditor: The Switchboard toolbar button is no longer automatically hidden after desktop shortcuts have been created.

Sequencer Playlists: Added support for opening multiple Playlist assets simultaneously. Double-clicking Playlist assets in the Content Browser will now spawn new Playlists editor tabs.

Virtual Scouting: Added a new "Virtual Scouting" plugin, which contains code required for OpenXR compatibility. For now, the "Virtual Production Utilities" plugin is also still required to use Virtual Scouting.

Virtual Scouting: GetHMDDeviceType is now shimmed for backward compatibility when using the OpenXR plugin, instead returning the name of the deprecated VR plugin which corresponds to the active OpenXR interaction profile.

Virtual Scouting: Added a "Game View" toggle to the Virtual Scouting settings panel, and added an "Enter VR Mode" Blueprint function to the VPScoutingSubsystem.

Switchboard: Added a setting to allow finding levels that are inside plugins.

Virtual Scouting: You can now use the OpenXR aim pose for the laser origin when applicable, rather than the grip pose. We have added a socket named "OpenXrGrip" to the Virtual Scouting Oculus controller mesh (SM_Controller_RiftS), adjusted to coincide roughly with the OpenXR grip pose. For any mesh where this socket is present, the interactor mesh relative transform is adjusted to treat the socket as the mesh origin. This allows us to preserve the original mesh origin for compatibility with the deprecated Oculus VR plugin and its differing motion controller pose.

VR Editor: Changed UIBrightness upper bound property annotation from ClampMax to UIMax, in order to permit values >10.0 to be typed in.

Switchboard: Added support for hostnames in addition to IP addresses. Address-type settings fields will now attempt name resolution on the entered value, with highlighting to indicate the lookup status (yellow = pending, red = failed).

Added support to join all interfaces on multicast address when 0.0.0.0 is used for UDP unicast.

Enhanced Switchboard tool to allow users to save configurations outside of the main config folder.

RemoteControlWebInterface: Added dedicated view for Virtual Production FX, Color Correction & Light Card control.

Added SwitchboardListener and Multi-User Server as build steps in UnrealGameSync.

Added an option to the Multi-User persist dialog to allow users to make a file writable if source control is not enabled.

RemoteControlWebInterface: Added support for Controllers.

Enabled ShotGrid plugin for Linux.

Added Shader and Asset Loading status column to the Stage Monitor tool.

The VPBookmark Actor used by both Virtual Camera and Virtual Scouting has been nativized.

Added CineCameraComponent in VPBookmarkActor in order to save camera parameters on the bookmark

Added the function InjectInputForAction to the VCamComponent that will inject the input to whichever input system the component is currently using.

Added SetActorLabel function in the VCamBP function library that will be accessible from VCam modifiers and widgets.

Implemented GetWorld function in VCamModifier class that will expose Actor related functions for VCam modifiers.

Enhanced Input has been enabled in the VRTool and VirtualScoutingInteractor classes to support future development of VR in Editor toolsets.

All materials associated with the Virtual Scouting tools have been modified to ignore pre-exposure. They can now be used in scenes with physically accurate lighting values and remain visible regardless of lighting ratios or exposure level.

The Viewfinder tool now uses the CineCameraComponent filmback size and crop settings to define screen size and render target dimensions.

Viewfinder and Viewfinder_v02 now display focal length from the focal length variable on the CinecameraComponent rather than the lens preset name to support arbitrarily named lenses.

Take Recorder's "Review Last Take" now considers Multi-User setups where multiple takes may have been recorded.

VPCineCamera SceneCapture2Dcomponent no longer captures every frame, saving performance in VR Scouting sessions with multiple VPCineCameras spawned in.

UDP Messaging will now detect when a message cannot be properly routed and mark the endpoint as unreachable. This prevents the UDP Messaging module from initiating auto-repair, which would force the entire connection to be rebuilt.

Bug Fix:

Virtual Scouting no longer logs an error and refuses to launch if r.PostProcessing.PropagateAlpha is not set to 0, which otherwise led to the rendered image displaying all black in the HMD.

SwitchboardListener: Fix for building with bForceEnableExceptions ("error C2712: cannot use __try in functions that require object unwinding").

Sequencer Playlists: Fixed a potential crash when specifying out-of-bounds start/end frame offset values.

SwitchboardListener: Fixed expansion of %TEMP% in file destination paths on non-Windows platforms. This was causing a crash attempting to launch nDisplay devices running on Linux.

Switchboard: Fixed unhandled exceptions during creation of a new Switchboard configuration when attempting to invoke wmic to populate guesses for project/engine paths.

Switchboard now uses Build.bat/Build.sh instead of invoking UnrealBuildTool.exe directly, which ensures that the environment is set correctly.

Sequencer Playlists: Fixed an issue where hold sections could display the wrong frame for certain sequences.

For RemoteCotnrolWebInterface, there's no need to install NodeJS anymore. Plugins download required nodejs binary.

Virtual Scouting - the Sequencer tool now opens the first available level sequence Actor.

Upgrade Notes

Animation

Upgrade Notes:

Hide Transform and TransformNoScale as available control types in Control Rig. Controls of Type Transform and TransformNoScale will continue to work — but users cannot create new controls of those types through the UI.

The Update event is now called Forwards Solve and the Inverseevent is now referred to as Backwards Solve in Control Rig.

Spherical Pose Reader can now be mirrored. Inner/outer falloff regions are independent. Added debug drawing of coordinate axes.

Node should behave as before, though you may find the inner/outer regions are tuned slightly differently after upgrading.

Upgrade Notes:

Root instance handles are now type-enforced in Sequencer.

This prevents passing an FInstanceHandle to something that specifically wants a root instance handle.

FRootInstanceHandle is implicitly castable to an FInstanceHandle, but not visa-versa.

Some forward-facing APIs that deal with root instance handles have been changed to use FRootInstanceHandle over FInstanceHandle.

Editor

Upgrade Notes:

Upgraded the remote_execution.py script in the PythonScriptPlugin. Changes are backwards compatible. No changes to previous code that utilizes remote_execution.py is necessary. Changes include:

Added macOS support and fixed problems with command socket not being able to start in Unreal.

Added Python 3.9 support.

Updated hair strands to support Alembic groom_group_cards_id for hair card generation.

In order to use the new Alembic schema field 'groom_group_cards_id', any relevant groom assets with this field must be re-imported.

Foundation

API Change:

FAssetBundleData now only stores the paths of top level assets to save space, though it can still be populated by TSoftObjectPtr properties tagged with the appropriate metadata.

FSoftObjectPath and FTopLevelAssetPath should be able to replace FNames that referenced object paths in most cases without problems, however they are restricted to storing strings which have the correct form (for example, they start with a '/', they do not contain adjacent subobject delimiters, and so on).

Upgrade Notes:

FSoftObjectPath should be used to contain the paths of objects that may exist at any depth in an object hierarchy, such as /Path/To/Map.Map:PersistenLevel.Actor.Component.

It stores the first two components (the package name and top level asset name) as FNames and the rest of the path as an FString.

FTopLevelAssetPath should be used to contain the paths of objects which always have a package as their direct outer, such as /Path/To/Package.AssetName.

FAssetData::ObjectPath is deprecated, FAssetData::GetSoftObjectPath or GetObjectPathString should be used instead.

Upgrade Notes:

Updated common memory reporting commands to properly use -csv output and added parsable delimiting to MemReport output.

Fixed audiomemreport command to properly redirect to a different OutputDevice (removed -skipcsvforaudio, added -log).

Any tools that parse the output of affected memory profiling commands like "obj list" or "listtesxtures" may need adjusted to respect the new formatting. These outputs should now use more standard csv formatting that doesn't include leading or trailing white spaces in cells. MemReport files now include "Begin/End command" notations for each section.

Framework

Upgrade Notes:

Large world support (~88 million km wide) is enabled for all worlds.

If your project relies on the 22km UE4 WORLD_MAX you may revert to that version by building with UE_USE_UE4_WORLD_MAX=1.

Alternatively project code can be updated to use UE_OLD_WORLD_MAX and equivalents as appropriate. Refer to EngineDefines.h for the complete list of OLD (UE4), LARGE (UE5), and HUGE_DISTANCE (precision limits) defines.

AWorldSettings::bEnableLargeWorlds was deprecated as part of this change. Test projects that previously relied on this toggle will continue to function and will now apply world bounds restrictions to actors further than ~44 million km from the origin. You may use AWorldSettings::bEnableWorldBoundsChecks to alter this behavior.

Upgrade Notes:

Enabled the Enhanced Input plugin by default.

Upon project startup, if you have not customized your UPlayerInput or UInputComponent classes in your project, they will automatically be set to the new Enhanced Input versions.

You can disable the automatic upgrade path by setting the console variable "EnhancedInput.bEnableAutoUpgrade" to false if desired.

Enhanced Input is fully backwards compatible with the old input system, so you can make your UPlayerInput and UInputComponent's based on the Enhanced Input equivalents and all old Action and Axis mappings will still work. This provides a solid upgrade path where you can upgrade your input code at your own pace, or just keep it and start using Enhanced Input for new features.

Level Design and Art Tools

API Change:

Use volatile for INEXACT to force rounding.

API Change:

Added an AggGeom to the dynamic mesh component to support the addition of the Async Physics build for Dynamic Mesh component. Collision update functions should update instead of the one on the current BodySetup. This ensures new collision changes are not overwritten by an async build replacing the BodySetup.

Upgrade Notes:

Update the CopyMeshToStaticMesh and CreateStaticMeshAsset Geometry scripting functions to use the standard engine FMeshNaniteSettings data structure to define Nanite settings instead of the previous custom structures/fields.

This is a breaking change, Blueprints that use the now-deprecated properties will need to be manually updated.

The previous NaniteProxyTrianglePercent values can be converted to the FMeshNaniteSettings Fallback Percent field by dividing the value by 100.

API Change:

This adjustment is designed to support tools where the selection type before the tool is activated is not compatible with the tool's function and requires conversion (for example vertices to triangles). The old behavior was also partially broken, where attempts to call a mode change on an inactive selection mechanic would result in the mode being changed transparently, but with no other processing taken, such as converting the active selection or sending undo changes.

Platform

Upgrade Notes:

Added a native async save API.

Any save game operations that are currently nested in AsyncTask calls or similar can be moved to use the new async save game API.

Upgrade Notes:

Fixed issue where shader pipeline cache files could be incorrectly trimmed from the pak directory list.

API Change:

AVEncoder no longer stores a width and height. These properties have been moved to the FVideoEncoderInput. This input is now the source of truth and both AMF and NVENC will adapt their resolution to the input resolution

Moved ECodec to public so the module can expose a method to select what codec the user would like to use.

Modified packaging of a PixelStreaming project so that ps-infra files are placed in a nicer location.

Renamed the encoders and their corresponding factories to better describe their purpose.

Upgrade Notes:

Fixed PixelStreamingAudioComponent that had delayed audio.

Fixed audio bitrate from Unreal Engine to browser that was set to a low default causing compressed audio quality in stream. The new default is now Opus maximum value of 510kb/s.

Fixed the Selective Forwarding Unit (SFU) not being added to the Pixel Streaming samples folder for a packaged project.

Fixed default max bitrate not being high enough to support 4k.

Fixed reconnections not autoplaying in the browser.

Refactored Pixel Streaming start-up logic to be a more uniform code path.

Refactored Pixel Streaming URL to use settings function like PixelStreamingIP and Port.

Fixed backwards compatibility break where offers from players would not result in a connection.

Fixed a deadlock scenario that could be triggered with rapid peer connects/disconnects.

Fixed a crash in WebRTC caused by not removing the audio sink when a peer disconnects.

Fixed streams being capped at 30fps by default.

Fixed incorrect WebRTC headers being included in the public header.

Frames now flow through a much more rigid set of operations to get streamed.

Video Sources have a Video Adapter and are fed by a Video Input.

Video Adapters are fed by the input and contain a number of Processes.

Processes take the input frame and adapt it to a format that the encoder can use.

Frame Buffers now contain a reference to the adapter, frame data is grabbed from here as needed by the encoder.

Adapters and their processes are public with the intention that users can implement their own adapt step for other encoders.

Streamer is now modular so we can have multiple streamers with their own inputs that stream to their own location.

Extracted out the copy texture into a rendering util and tweaked how it handles transitions.

Modify PixelStreamingModule to use new functions for creating a streamer.

Added optional codepaths to use WebRTC M96 or M84.

Refactored plugin to enable using our API for the new Pixel Streaming Player plugin.

Created a new PixelStreamingPeerConnection class to wrap the webrtc peer connection with specific pixel streaming behavior.

Made the signaling server connection public and renamed its observer methods so it is obvious when they are implemented.

Some small changes to frame buffers to make handling of cached data slightly safer.

Made use of lambdas more explicit where possible.

Remove unnecessary warning message from PixelStreamingAudioComponent.

Rendering

Upgrade Notes:

Default to writing velocity in base pass instead of in depth pass. This is because we do not currently support nanite WPO with depth pass velocity (work to fix this is ongoing). To avoid any confusion or problems for licensees who are trying out the new nanite WPO, we default to this setting that works everywhere.

Licensees can locally set depth pass velocity if they are not using nanite WPO and want the potential performance improvement.

Upgrade Notes:

Pixel shader animations no longer ghost.

Translucencies no longer ghost.

VFX no longer ghost.

Simulation

Upgrade Notes:

Geometry collection now allows import of collision from the static meshes they are generated from.

Existing geometry collection assets will need to be reset in the Fracture Editor to allow this feature to work.

Then the "Import Collision From Source" checkbox then needs to be checked to allow using them.

A "Collision" column mode in the Fracture Editor outliner has been added that will display if collisions are used, or are available or not.

Fracture Editor outliner can now display run-time damage information, including maximum damage, current threshold and if the piece broke or not.

In order to enable this feature, the component needs to have "Enable Run Time Data Collection" enabled.

Then, in the Fracture Editor, simply run the simulation then pause or stop and then refresh the Fracture Editor outliner in "Damage" column mode.

Size specific damage thresholds generation has been improved for geometry collections where bones can get assigned more predictable thresholds from the settings.

Existing assets will use the cluster only computability mode and will need to uncheck the "Per Cluster Only Damage Threshold" check box.

Added new interface to ChaosWheeledVehicleMovementComponent which enabled direct control over the drive and braking torque per wheel.

The new blueprint compatible functions are SetDriveTorque and SetBrakeTorque. They take two parameters, Torque specified in Newton Meters and a wheel index. The wheel index matches the wheel array in the wheeled vehicle movement component.

This has a few modes of operation allowing you to add to or completely override the torque at each wheel.

The new property ExternalTorqueCombineMethod on the wheel class ChaosVehicleWheel, has three states:

None [the default] - No external torque will be applied to the simulation when you call the above set torque functions.

Override - The external torque provided by the set torque functions will be used and any internal calculations for engine/ brakes will be ignored.

Additive - The external torque provided by the set torque functions will be added to any internal calculations from engine/ brakes.

This mode can also be changed at runtime via the blueprint compatible function SetTorqueCombineMethod.This is also defined per wheel.

There is no change to current behavior, the new feature is enabled by setting a new property (ExternalTorqueCombineMethod) which is defaulted to off.

Added brake and shock damage propagation options to geometry collection component (enabled by default). This allows finer tuning and more realistic breaks.

No upgrade needed, older assets will keep it disabled, only new assets will have it enabled by default.

In the Chaos Vehicle Plugin it was noted that the wheel forces were being applied to high up and not at the road surface.

Rectifying this means vehicle handling will change dramatically, likely requiring a lowering of the center of mass by approximately the wheel radius to get the same result.

To alleviate this issue a new property (bLegacyWheelFrictionPosition) has been added to retain the old behavior. This will automatically be enabled on any existing vehicles but will default to false on any new vehicles that are created.

To ensure all your vehicles are consistent on existing projects, ensure bLegacyWheelFrictionPosition property is enabled on the ChaosWheeledVehicleMovementComponent.

New:

Added a new connection graph method for geometry collection that filters overreaching connections by testing for bounds overlaps.

Because this method produces better quality connection graphs, it is recommended to use it when possible.

Added crumbling event for geometry collections that triggers whenever a cluster crumbling related function is called.

Crumbling event will only fire if Notify Crumbling is enabled on the corresponding geometry collection component.

UI

Upgrade Notes:

Added BP_OnPressed and BP_OnReleased blueprint-implementable events to CommonButtonBase of CommonUI for better control over visual states and animations.

New:

Calling Stop Animation is now an asynchronous operation.

This is currently enabled by default, but controllable through the UMG.AsyncAnimationControlFlow cvar (false disables this new flow).

When an animation would usually be ticked by the animation tick manager, it now schedules an update on Stop, and queues a latent action to finish stopping before it completes the operation.

Content that specifically relies upon Stop Animation being a synchronous call (that is, it relies upon animated values being immediately realized after Stop Animation has been called) should either disable UMG.AsyncAnimationControlFlow, or rework the content to respond to an OnAnimationStopped event (the latter being more preferable).

Version-Specific Conversion Notes

Asset Compatibility

Mandatory Updates

Development Platform Changes

PhysX and Chaos Physics Systems

Console Variables for Shader Debugging

Other Changes

C++ Object Pointer Properties

Rendering

World Building

Tools

Control Rig

Audio

Gameplay Framework

Networking

Core

This guide describes how to upgrade your Unreal Engine 4 projects to Unreal Engine 5 (UE5).

Unreal Engine 5 (UE5) introduces a series of changes, upgrades, and new features to the systems that made up Unreal Engine 4 (UE4). Although there have been significant changes to the engine, the built-in conversion process handles most of the work involved in migration without requiring any user action.

To begin, open UE5 from the Epic Games Launcher. If UE5 is already running, from the main menu, go to File > Open Project from the main menu. Then, select the project you want to upgrade and click Open.

Click the Open a Copy button to upgrade a separate copy of your project, leaving the original unchanged.



If you click More Options on this dialog, you can choose to either:

Skip the conversion, which attempts to open the project as-is.

Convert in-place, which attempts to convert the existing project rather than make a copy of it.

When you convert a project to UE5, we highly recommend using the Open a Copy workflow described above. The Convert in-place and Skip conversion options may not work as expected and may lead to data corruption and data loss.

Once you update a project to a newer version of Unreal Engine, you won't be able to open it in an older version. Attempting to do so will fail.

Once the conversion process is complete, most projects will be ready to build and run in UE5 without further action. However, certain new or upgraded features benefit from, or even require, some manual updates to operate properly in UE5 and take advantage of its full capabilities. Among the largest systemic changes are Nanite, Lumen, and Chaos. Nanite and Lumen will require some of work to get graphics-centric projects looking the same as they did in UE4, and heavily physics-based projects that have not already switched to Chaos will need some configuration and Asset modification.

This page covers mandatory updates and other noteworthy system changes, such as system deprecations and replacements. If you are using these features, you will need to perform the updates described in the Mandatory Updates section to bring your UE4 projects into UE5 successfully. Updates described in the Other Changes section may or may not impact your projects, but it is worth to keep them in mind.

Version-Specific Conversion Notes

Refer to the table below to understand how your project will convert depending on the Unreal Engine version it was created with.

Project Created With Version

Conversion Notes

Unreal Engine 4.0 to 4.26

Your project will load in any version of Unreal Engine that is the same or newer than the version it was created with.

The Unreal Engine API has changed over time, which means some projects created with much older versions may not load correctly. For example, Blueprints saved all the way back in 4.0 might call functions that were deprecated in 4.10 and no longer exist in 5.0. However, the project should still load and let you fix up the references that were deprecated or removed.

Unreal Engine 4.27

Your project will load in Unreal Engine 4.27, 5.0, and newer versions. Note that your project will not load in Unreal Engine 5.0 Early Access.

This was communicated as part of the Unreal Engine 5.0 Early Access compatibility notes.

Unreal Engine 5.0

Your project will load in Unreal Engine 5.0 and newer versions.

Unreal Engine 5.1 and newer versions

Your project will load in any version of Unreal Engine that is the same or newer than the version it was created with.

Asset Compatibility

Assets saved in an older version of Unreal Engine can be opened in a newer version. For example, if you save an Asset in Unreal Engine 4.26, you can open it with Unreal Engine 5.0.

Assets saved in a newer version of Unreal Engine cannot be opened in an older version. For example, if you saved an Asset in Unreal Engine 5.0, you will not be able to open it in Unreal Engine 4.26.

Mandatory Updates

The following sections describe changes that you may need to make to your UE4 project in order to bring it into UE5. Some of these changes are mandatory, while others are optional but recommended and will become mandatory in future versions of UE5.

Development Platform Changes

If you write C++ code in Visual Studio, you must switch to Visual Studio 2019 if you are not already using it. This is also the default Visual Studio IDE for the latest version of UE4. UE5 does not support Visual Studio 2017 or Visual Studio 2015.

UE5 does not support 32-bit platforms, and there are no plans to add 32-bit platform support in the future.

UE5 standardizes Target Platform Names. You will need to update build scripts and, in some cases, DeviceProfiles.ini files. This primarily affects you if you run these scripts directly; if you use UAT, you should not need to make changes.

The following table contains the list of changed Target Platform Names:

UE4 Target Platform Name

UE5 Target Platform Name

Windows

WindowsEditor

WindowsNoEditor

Windows

MacNoEditor

Mac

Mac

MacEditor

LinuxNoEditor

Linux

Linux

LinuxEditor

LinuxAArch64NoEditor

LinuxAArch64

PhysX and Chaos Physics Systems

UE5 uses the Chaos Physics engine for physical simulation, replacing PhysX as the default. Physics simulation under Chaos Physics behaves differently from PhysX, requiring developers to make adjustments in order to see consistent behavior.

The physics tick rate will change for any newly created projects by default. The tick rate change will be accessible from Tick Async Physics within Project Settings (menu: Edit > Project Settings). This new feature will simulate Physics on its own thread instead of on the Game Thread.

This change improves determinism by running physical simulation updates at a fixed rate. As a result of having a fixed update rate, networked physics simulation is easier to keep synchronized because client and server systems run at the same interval.

No longer running on the Game Thread means that there is a potential delay between input to the physics system from the Game Thread and the physics system's reaction to that input. You must account for this delay to avoid unpredictable behavior in projects where gameplay logic relies heavily on physics simulation. Running Physics-heavy gameplay code in C++ callbacks which execute on the Physics Thread can mitigate this, but will require modifying project code to use this approach.

Console Variables for Shader Debugging

For the release of Unreal Engine 5, the console variables used for debugging shaders have changed. The table below offers a guide to these renames.

If your project use any of these variables in their configuration files, you will need to update them when migrating to UE5 to continue using the generated data for shader debugging.

Old Console Variable Name

New Console Variable Name

Description

r.Shaders.KeepDebugInfo

r.Shaders.Symbols

Enables debugging of shaders by generating symbols and writing them to disk for consoles. Desktop symbols are stored online.

N/A

r.Shaders.ExtraData

Generates shader names and any additional shader data.

r.Shaders.PrepareExportedDebugInfo

r.Shaders.GenerateSymbols

Generates symbols but does not write them to disk. Instead, symbols are stored in the Derived Data Cache (DDC).

r.Shaders.ExportDebugInfo

r.Shaders.WriteSymbols

Writes symbols to disk if they have been generated.

r.Shaders.AllowUniqueDebugInfo

r.Shaders.AllowUniqueSymbols

Generates symbol associations based on shader source. By default, this is off.

r.Shaders.ExportDebugInfo.Zip

r.Shaders.WriteSymbols.Zip

When writing symbols to disk, they are written out as a single ZIP file.

The console variable r.Shaders.KeepDebugInfo has been split into two console variables (r.Shaders.Symbols and r.Shaders.ExtraData) to remove the changes to runtime shader data when only symbols are required. It is useful for platforms that support exported debug information because it allows symbols to be generated for shipping builds without changing the final shader data.

For more information about this process, refer to the Shader Debugging page.

Other Changes

These updates are not required to get your Unreal Engine 4 (UE4) project running in the Unreal Engine 5 (UE5), but may be required in future versions, or may help you to take advantage of the engine's full capabilities.

Read through this page to learn how to prepare yourself for future versions of Unreal Engine 5 (UE5), and to get the most out of the engine's new and upgraded features.

C++ Object Pointer Properties

The following section only applies to projects using C++ code. Blueprints Visual Scripting users do not need to take any action. C++ Licensee projects can keep using raw object pointers or optionally begin to use TObjectPtr.

UE5 introduces TObjectPtr, a template-based, 64-bit pointer system, as an optional replacement for raw object pointers in editor builds. This system adds dynamic resolution and access tracking in editor builds, while performing identically to raw pointers in non-editor builds. TObjectPtr variables also convert automatically to raw pointers when passed to functions or stored in local variables. Many engine classes that once featured raw pointers in UPROPERTY variables now use TObjectPtr. While most interactions with TObjectPtr types will implicitly convert to raw pointers, there are some rare cases where direct interactions with engine class member variables need to change from raw pointer semantics to TObjectPtr semantics. For example, the RootComponent property in AActor was a USceneComponent* in UE4, but is a TObjectPtr<USceneComponent> in UE5; in some rare cases, you may need to update direct interactions with RootComponent, though calls to GetRootComponent, which still has USceneComponent* return type, can always remain as they are.

Although it is optional, we recommend using TObjectPtr<T> over T* for UObject pointer properties and container classes found in UCLASS and USTRUCT types. Since TObjectPtr converts to raw pointers for non-editor builds, this will not impact the behavior or performance of a shipped product, but may improve your experience when developing in editor builds. Use the following methods to adapt your programming style to this new pointer system:

When calling the "Find" family of container functions, use TObjectPtr<T>* instead of T** to capture the return value.

Range-based iteration through raw pointer containers might have used auto* as the iterator variable type. Change these to auto&. We also recommend using auto& or const auto& in new code, since TObjectPtr can cache resolved object addresses, saving time on future access attempts.

Call ToRawPtr or Get on your TObjectPtr when you need a raw pointer and implicit conversion is not available. Common cases include ternary operations and usage inside of const_cast. When passing parameters to function delegates, declare a parallel delegate function as a pass-through, replacing raw pointers with TObjectPtr parameters. The following example shows a passthrough delegate function:

In most cases, such as when passing parameters to functions or storing data in local variables, TObjectPtr automatically converts to raw pointer types. There are a few rare cases, such as those described above, where you will have to perform minor code modifications, but most projects will not need this.

UE5 includes UnrealObjectPtrTool, a program that automatically converts engine-visible raw pointer properties to the TObjectPtr system. You can find it in the UE5/Programs/UnrealObjectPtrTool/ section of the solution hierachy in your code IDE. The source code resides in Engine/Source/Programs/UnrealObjectPtrTool/. The executable exists in your Engine/Binaries/Win64 folder. Depending on your Operating System or Development Enviroment, this executable may be located in your Engine/Binaries/OS folder, where OS represents your operating system.

This optional program's purpose is to expedite the process of converting your code from raw pointers to the TObjectPtr system. It will update UPROPERTY variables in class and struct definitions within your header files, but will not make all of the necessary changes to your source code as described above; you will still need to make those adjustments manually and ensure that your project compiles before using UnrealObjectPtrTool.

To use UnrealObjectPtrTool, follow these steps:

Navigate to your DefaultEngine.ini UHT config file located in your Engine\Programs\UnrealHeaderTool\Config directory.

Inside of your DefaultEngine.ini file, modify the following script:

Rebuild your project to ensure all the code is parsed by UHT.

Your UHT log may be named Log_UHT.txt or UnrealHeaderTool.log depending on how your project is compiled. You can navigate to either of the following folder directories:

Compile UnrealObjectPtrTool from the Visual Studio solution.

This step is only required if running the Engine from source, otherwise the UnrealObjectPtrTool is precompiled when installing from the Epic Games Launcher.

Run the UnrealObjectPtrTool executable:

You can add the Optional parameter: -PREVIEW or -n to get a preview of the potential changes.

Rendering

The following default settings have changed, and could affect the look of your project:

Screen Space Global Illumination: The project setting for Screen Space Global Illumination (Beta) and the related console variable r.SSGI.Enable have been removed and the previous status lost. To re-enable Screen Space Global Illumination as the project's default global illumination method, go to Project Settings > (Engine) Rendering > Global Illumination properties and set Dynamic Global Illumination Method to Screen Space (Beta). To re-enable Screen Space Global Illumination on a Post-Process Volume, go to the volume's properties and locate the Global Illumination category, then set the Method field to Screen Space (Beta).

Ray Tracing support with Lumen Hardware Ray Tracing: Standalone Ray Tracing features are being deprecated in Unreal Engine 5 . However, the engine's ability to compute these lighting effects is not being removed, since Lumen covers these lighting features. What is being removed is the standalone Ray Tracing system that has been developed in Unreal Engine 4. Those features worked mostly in isolation of one another, meaning that they weren't guaranteed to support the same features of the engine equally or consistently. Lumen is adding entirely new implementations of ray tracing features for reflections and global illumination to its Hardware Ray Tracing path. As UE5 continues to develop, the ray tracing features of Lumen will continue to improve, offering wider support and feature parity with other parts of the engine.

Ray Tracing Reflections, Global Illumination, and Shadows have been separated into their own features that can be enabled independently of each other. Each of these features can be found in Project Settings > Rendering and requires that Support Hardware Ray Tracing be enabled to use them.

Under the Global Illumination section, select the Dynamic Global Illumination Method preferred.

Under the Reflections section, select the Reflection Method preferred.

Under the Hardware Ray Tracing section, check the box for Ray Tracing Shadows to be used.

Reflections and Global Illumination can also be set using a Post Process Volume to select from the Global Illumination and Reflection methods.

Generating Mesh Distance Fields: Lumen's Software Ray Tracing features largely rely on Signed Distance Fields for mesh representation. The Default Voxel Density of all Distance Fields has increased from 0.1 to 0.2. This is neccessary to achieve good software tracing quality with Lumen, but it significantly increases Distance Field memory usage. To adjust this property, go to Project Settings > (Engine) Rendering, where you will find the Generate Mesh Distance Fields checkbox and the Distance Field Voxel Density property. You may need to restart the editor after changing this setting for it to take effect.

Nanite obsoletes most use cases for Hardware Tessellation. Hardware Tesselation has been removed from UE5. For use cases that Nanite does not support, users may want to increase the resolution of their assets if necessary.

Lumen replaces Light Propagation Volumes and Distance-Field Global Illumination (DFGI).

Compared to Light Propagation Volumes, Lumen provides additional features, much higher quality, and is under active development, although it has a higher baseline performance cost.

DFGI was an experimental feature; developers should use Lumen instead of DFGI for dynamic global illumination.

Over time, Lumen Global Illumination and Reflections will replace the majority of ray tracing features with similar or higher-quality results.

Legacy Tonemapper, which was deprecated in UE4, does not exist in UE5. No developer action is required.

Cascade will be deprecated in UE5 5.0, and removed in a later release. UE5 developers should switch to Niagara. An automated converter to upgrade Cascade data to Niagara is in development.

Some Ray Tracing features are being deprecated and moved from a standalone system that requires support to having these features integrated into Lumen's Hardware Ray Tracing system. This means that Reflections and Global Illumination will be directly integrated into Lumen. These standalone features have been deprecated to provide a unified experience with broader support of engine features. (See the "Rendering" section above for more details.)

World Building

World Partition is the system UE5 uses to handle large, streaming worlds. The World Composition system that UE4 used still exists, but is deprecated and will not receive upgrades, fixes, or support. World Composition will be removed in a future version of UE5.

To convert your maps to the World Partition system, use WorldPartitionConvertCommandlet on your project, and provide the name of each map to convert, one at a time. As an example, to convert the TM_WorldComp_P map, found at /Game/Maps/Tools/Landscape/TM_WorldComp_P in the packaged QAGame project, run the editor with the command-line options:

This will convert the TM_WorldComp_P map to the World Partition system. The -ConversionSuffix causes the converted map to save as TM_WorldComp_P_WP instead of overwriting the original map. Because of the -SCCProvider=None option, the commandlet will run without interacting with your project's source control provider. This process will also generate a TM_WorldComp_P.ini file containing the settings used to convert the map, and for potential future conversions. The conversion process itself builds runtime grids (for the World Parition system) out of the existing World Composition data, and assigns the map's Actors to the appropriate grids.

Developers using C++ can see UWorldPartitionRuntimeSpatialHash::ImportFromWorldComposition and UWorldPartitionRuntimeSpatialHash::GetActorRuntimeGrid to examine or modify the logic involved in generating grids and assigning Actors to them.

Tools

New geometry editing tools will replace the experimental Legacy Editable Mesh Plugin.

Movie Render Queue will replace Movie Scene Capture.

VR Level Editing will be stripped down to only support VR preview, but UE5 continues to support virtual production scouting.

Take Recorder will replace Sequence Recorder. Take Recorder includes all of the features that Sequence Recorder offered.

Camera Animation Sequences will replace Camera Anims.

UE5 also removes Editor Feature Packs associated with removed plugins. Users of those plugins will need to ensure that they do not reference the removed content in their projects.

Sequencer will fully replace Matinee after the full release of UE5. Matinee was deprecated, but still existed in UE4.

Control Rig

Spaces are renamed to Nulls.

Gizmos are renamed to Shapes.

Set Initial Transform from Current now reads as Set Offset Transform from Current.

Collections are now replaced by Arrays.

Transform Constraint node is deprecated and replaced with individual point, rotation, and parent contraint nodes.

The new Parent Constraint node can be used in place of a Project to New Parent and Set Transform nodes.

Space Switching can now be used instead of Parent Switch Constraint.

Bezier Data Type is replaced with the Splines plugin.

ControlRigHierarchyModifier no longer is in use for Python, this is replaced with RigHierarchy for querying rig elements and RigHierarchyController to author rig elements.

ControlRigBlueprint no longer has a property named controller. To access the main RigVMController, use the function: ControlRigBlueprint.get_controller().

Mapping is not handled in Construction Script, but on Pre-Initialize of Control Rig Component.

Audio

Unreal Audio Mixer will replace the deprecated Legacy Audio Backends by UE5 5.0. Users do not need to take any action. UE5 will use Unreal Audio Mixer and leverage modern audio backends by default; these are compatible with all preexisting audio features.

Audio Volumes, Sound Class Mix, and Sound Cues will be deprecated by UE5 5.0, with plans to remove them in a future release of UE5.

Sound Cues will be superseded by MetaSounds, which will be available in UE5 5.0.

Sound Class Mix will be superseded by the Modulation and Submix systems, which are now available.

Audio Volumes will be superseded by a new system currently in development, which will be available in UE5 5.0.

Users are encouraged to move to the new versions of these systems as soon as possible.

Gameplay Framework

Blueprint Nativization will not exist in UE5. Projects that leveraged this feature should not see any changes or need to receive any modifications in order to function properly, though performance may be impacted. If this happens, developers will need to take other optimization approaches.

Networking

AES, RSA, and RSA Key AES Encryption Handlers will be deprecated as of UE5 5.0, and removed in a future release of UE5. Only DTLS is used at this point.

AES GCM will remain in use past UE5 5.0, but will be removed in a future release of UE5. users do not need to modify their projects as a result of this change.

Core

Zen Loader will replace the Event-Driven Loader. Since most users do not interface directly with the Event-Driven Loader, this change use not require any actions during project migration.

Unreal Insights instrumentation will replace the Stats System after the full release of UE5 5.0. The Stats System will continue to exist in UE5 5.0, but will eventually be removed in favor of Unreal Insights.

Development Setup

What's New

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Hardware and Software Specifications

Choose your operating system:

Windows

macOS

Linux

This page describes how to download and install Unreal Engine.

Installing Unreal Engine

To download and install Unreal Engine, you need to:

Download and install the Epic Games Launcher.

Sign up for an Epic Games account, if you don't have one.

Sign in to the Epic Games Launcher.

Install Unreal Engine.

Download and Install the Epic Games Launcher

The Unreal Engine tab in the Epic Games Launcher is where you manage all of your Unreal Engine (UE) installations. You can have multiple versions of UE installed on the same computer.

To download and install the Launcher, follow these steps:

Access the Download Unreal Engine page.

Select the license type that best matches how you intend to use UE.

There are two types of licenses available:

Publishing, if you plan to make games.

Creators, if you plan to make other types of content.

You can learn more about the different kinds of licensing available from the Unreal Engine FAQ.

Click the DOWNLOAD NOW button that corresponds to the license type you selected. This will download the Launcher installer to your computer. Depending on your operating system settings, you might be asked to select a save location, or have to approve a security prompt before the download can start.

After the download finishes, run the installer and wait for it to complete.

Choose your operating system:

Windows

macOS

Linux

Create an Epic Games Account

After the setup program installs the Epic Games Launcher on your machine, you will be prompted to sign in with your Epic Games account.

If you have an account, sign in to the Launcher and continue to the next section.

If you don't have an account, click Sign Up to create one. You can sign up for an Epic Games account with your email, or with a supported social media or gaming platform account.





You can also proceed without creating an account by clicking Sign In Later. However, you will not be able to download or use Unreal Engine without an account.

Your account information is processed in accordance with the Epic Games Privacy Policy.

After you've created your account, Sign In to the Launcher.

Install Unreal Engine

Now that you've signed in to the Epic Games Launcher, you're ready to install Unreal Engine.

Click the Unreal Engine tab inside the Epic Games Launcher, then click the Install Engine button.





(Optional) Click the Browse button to change the install path.





Click the Options button to select which Engine components you want to install. This is where you select components such as:

platform support

starter content

debug symbols

engine source code

You can add or remove components from an installed version of Unreal Engine at any time, by clicking the drop-down arrow next to the Launch button for that version, then selecting Options.

Before you install Unreal Engine, make sure you have enough disk space. Requirements vary depending on the engine components you select. The Options screen will show you how much space you need for the installer download, as well as the engine itself.





After you finish selecting the engine components you need, click the Apply button.

Click the Install button and wait for the installation to complete. Depending on your system specifications and Internet connection speed, downloading and installing Unreal Engine can take between 10 to 40 minutes, sometimes longer.

You can have multiple versions of Unreal Engine installed. To add more versions, in the Library tab, click the Add (+) button next to ENGINE VERSIONS, then select the Engine version you want to install from the drop-down and click Install.





Launch Unreal Engine

After the install completes, click the Launch button to open Unreal Engine.





Congratulations! You are now ready to start using Unreal Engine.

Changing the Location of a Previous Installation of Unreal Engine

If you have a previous installation of Unreal Engine on your disk, but the Epic Games Launcher does not recognize it, follow the steps below to register this installation with the Launcher. You can also use this method to move an existing installation to a new location on disk.

In the Epic Games Launcher, click the Add (+) button to add a new version. Select the version that corresponds to the Unreal Engine version you want to register or move.



Click the Browse button to choose the location on disk where you want to move the installation. The folder you choose must be empty.



(Optional) Click the Options button to configure which engine components you want to install.

Wait until the engine starts to install (the text Installing should appear on the tile), then click the Cancel (X) button to stop the installation.



The tile should now display a Resume button.

Open Windows Explorer or another file manager and move the files from the original install location into the new location (that is, the folder you selected in step 2).

Return to the Launcher and click the Resume button to resume the installation.



After you've completed the steps above, the Launcher will start verifying the installation. It will also download any optional components you selected that it can't find in the installation folder. This might take some time.

When this process completes, you will be able to launch this version of Unreal Engine from the Epic Games Launcher.

This page describes how to download and install Unreal Engine.

Installing Unreal Engine

To download and install Unreal Engine, you need to:

Download and install the Epic Games Launcher.

Sign up for an Epic Games account, if you don't have one.

Sign in to the Epic Games Launcher.

Install Unreal Engine.

Download and Install the Epic Games Launcher

The Unreal Engine tab in the Epic Games Launcher is where you manage all of your Unreal Engine (UE) installations. You can have multiple versions of UE installed on the same computer.

To download and install the Launcher, follow these steps:

Access the Download Unreal Engine page.

Select the license type that best matches how you intend to use UE.

There are two types of licenses available:

Publishing, if you plan to make games.

Creators, if you plan to make other types of content.

You can learn more about the different kinds of licensing available from the Unreal Engine FAQ.

Click the DOWNLOAD NOW button that corresponds to the license type you selected. This will download the Launcher installer to your computer. Depending on your operating system settings, you might be asked to select a save location, or have to approve a security prompt before the download can start.

After the download finishes, run the installer and wait for it to complete.

Choose your operating system:

Windows

macOS

Linux

Create an Epic Games Account

After the setup program installs the Epic Games Launcher on your machine, you will be prompted to sign in with your Epic Games account.

If you have an account, sign in to the Launcher and continue to the next section.

If you don't have an account, click Sign Up to create one. You can sign up for an Epic Games account with your email, or with a supported social media or gaming platform account.





You can also proceed without creating an account by clicking Sign In Later. However, you will not be able to download or use Unreal Engine without an account.

Your account information is processed in accordance with the Epic Games Privacy Policy.

After you've created your account, Sign In to the Launcher.

Install Unreal Engine

Now that you've signed in to the Epic Games Launcher, you're ready to install Unreal Engine.

Click the Unreal Engine tab inside the Epic Games Launcher, then click the Install Engine button.





(Optional) Click the Browse button to change the install path.





Click the Options button to select which Engine components you want to install. This is where you select components such as:

platform support

starter content

debug symbols

engine source code

You can add or remove components from an installed version of Unreal Engine at any time, by clicking the drop-down arrow next to the Launch button for that version, then selecting Options.

Before you install Unreal Engine, make sure you have enough disk space. Requirements vary depending on the engine components you select. The Options screen will show you how much space you need for the installer download, as well as the engine itself.





After you finish selecting the engine components you need, click the Apply button.

Click the Install button and wait for the installation to complete. Depending on your system specifications and Internet connection speed, downloading and installing Unreal Engine can take between 10 to 40 minutes, sometimes longer.

You can have multiple versions of Unreal Engine installed. To add more versions, in the Library tab, click the Add (+) button next to ENGINE VERSIONS, then select the Engine version you want to install from the drop-down and click Install.





Launch Unreal Engine

After the install completes, click the Launch button to open Unreal Engine.





Congratulations! You are now ready to start using Unreal Engine.

Changing the Location of a Previous Installation of Unreal Engine

If you have a previous installation of Unreal Engine on your disk, but the Epic Games Launcher does not recognize it, follow the steps below to register this installation with the Launcher. You can also use this method to move an existing installation to a new location on disk.

In the Epic Games Launcher, click the Add (+) button to add a new version. Select the version that corresponds to the Unreal Engine version you want to register or move.



Click the Browse button to choose the location on disk where you want to move the installation. The folder you choose must be empty.



(Optional) Click the Options button to configure which engine components you want to install.

Wait until the engine starts to install (the text Installing should appear on the tile), then click the Cancel (X) button to stop the installation.



The tile should now display a Resume button.

Open Windows Explorer or another file manager and move the files from the original install location into the new location (that is, the folder you selected in step 2).

Return to the Launcher and click the Resume button to resume the installation.



After you've completed the steps above, the Launcher will start verifying the installation. It will also download any optional components you selected that it can't find in the installation folder. This might take some time.

When this process completes, you will be able to launch this version of Unreal Engine from the Epic Games Launcher.

This page describes how to download and install Unreal Engine.

Installing the Engine

Unreal Engine on Linux supports precompiled installed builds as well as source code builds. For information about using source builds, refer to Building Unreal Engine from Source. To use a precompiled build, follow these steps:

Open the Unreal Engine for Linux page. It will prompt you to to create or sign into an Epic Games account. If you already have one, sign in to access the page. If you don't have an account, click Sign Up to create one.



You can sign up for an Epic Games account with your email, or with a supported social media or gaming platform account.



Download the .zip file containing the version of Unreal Engine that you need.



Unzip the contents of the .zip to your desired installation directory.

Run Engine/Binaries/Linux/UnrealEditor from the Terminal to launch Unreal Engine.

Recommended Hardware

Minimum Software Requirements

Graphics Card Drivers

Performance Notes

Requirements for UE5 Rendering Features

Choose your operating system:

Windows

macOS

Linux

This page covers the hardware and software requirements for Unreal Engine 5. It also describes what is installed by the pre-requisites installer included in the Unreal Engine installer.

Recommended Hardware

Operating System

Windows 10 64-bit version 1909 revision .1350 or higher, or versions 2004 and 20H2 revision .789 or higher.

Processor

Quad-core Intel or AMD, 2.5 GHz or faster

Memory

8 GB RAM

Graphics Card

DirectX 11 or 12 compatible graphics card

RHI Version

DirectX 11: Latest drivers

DirectX 12: Latest drivers

Vulkan: AMD (21.11.3+) and NVIDIA (496.76+)

Operating System

Latest MacOS Ventura

Processor

Quad-core Intel, 2.5 GHz or faster

Memory

8 GB RAM

Video Card

Metal 1.2 Compatible Graphics Card

Operating System

Ubuntu 22.04

Processor

Quad-core Intel or AMD, 2.5 GHz or faster

Memory

32 GB RAM

Video Card

NVIDIA GeForce 960 GTX or Higher with latest NVIDIA binary drivers

Video RAM

8 GB or more

RHI Version

Vulkan: AMD (21.11.3+) and NVIDIA (515.48+)

To get the most out of rendering features of Unreal Engine 5 such Nanite and Lumen, see the Requirements for UE5 Rendering Features section of this page.

Minimum Software Requirements

Minimum requirements for running the engine or editor are listed below.

Running the Engine

Operating System

Windows 10

DirectX Runtime

DirectX End-User Runtimes (June 2010)

Running the Engine

Operating System

macOS latest Monterey

Running the Engine

Operating System

Any reasonable new Linux distro from CentOS 7.x and up

Linux Kernel Version

kernel 3.x or newer

Additional Dependencies

glibc 2.17 or newer

The requirements for programmers developing with the engine are listed below.

Developing with the Engine

All 'Running the Engine' requirements (automatically installed)

Visual Studio Version

Visual Studio 2019 v16.11.5 or later (recommended)

Visual Studio 2022



iOS App Development



iTunes Version

iTunes 12 or higher

Developing with the Engine

Xcode Version

13.4.1

Developing with the Engine

Operating System

Ubuntu 22.04

Compiler

clang 13.0.1



Optional



IDE

Visual Studio Code, Rider

Software Installed by the Prerequisite Installer

The Unreal Engine includes a prerequisite installer that installs everything needed to run the editor and engine, including several DirectX components and Visual C++ redistributables. When you install Unreal Engine through the Epic Games Launcher, the Launcher automatically installs these prerequisites for you. However, you may need to run the prerequisite installer yourself if you build Unreal Engine from source, or if you need to prepare a computer with all the Unreal Engine prerequisites for a specific purpose—for example, if you are setting up a fresh computer to act as a Swarm Agent.

You can find the installer in the Engine/Extras/Redist/en-us folder under your Unreal Engine installation location.

Support for 32-bit platforms has been removed in Unreal Engine 5.

If you use Perforce to get the Unreal Engine source code, you'll also find precompiled binaries in the same Engine/Extras/Redist/en-us folder of the Perforce repository. The source for the installer is under Engine/Source/Programs/PrereqInstaller.

The following table lists the software that is installed by the prerequisite installer.

DirectX Components

Visual C++ Redists

XInput 1.3 (April 2007)

Visual C++ 2010 CRT

X3DAudio 1.7 (February 2010)

Visual C++ 2010 OpenMP library

XAudio 2.7 (June 2010)

Visual C++ 2012 CRT

D3D Compiler 4.3 (June 2010)

Visual C++ 2013 CRT

D3DCSX 4.3 (June 2010)

Visual C++ 2015 CRT

D3DX9 4.3 (June 2010)

Microsoft Visual C++ 2015-2022 Redistributable

D3DX10 4.3 (June 2010)

D3DX11 4.3 (June 2010)

The most important DirectX components from that list are the XInput, X3DAudio, and XAudio dependencies. These aren't included in standard installations of DirectX (and aren't distributed with Windows by default), so they have to be installed manually or distributed with the application.

Some features of Unreal Engine that require DirectX 12, require at minimum Windows 10 version 1703 (Window Creator Update). For the best experience that supports features like Nanite, Virtual Shadow Maps, and Lumen, we recommend using Windows 10 version 2004 or 20H2.

Graphics Card Drivers

We currently recommend using the latest stable releases from each card manufacturer:

Download NVIDIA drivers here

Download AMD drivers here

Performance Notes

This list represents a typical system used at Epic, providing a reasonable guideline for developing games with Unreal Engine 5:

Windows 10 64-bit (Version 20H2)

64 GB RAM

256 GB SSD (OS Drive)

2 TB SSD (Data Drive)

NVIDIA GeForce RTX 2080 SUPER

Xoreax Incredibuild (Dev Tools Package)

Six-Core Xeon E5-2643 @ 3.4GHz

If you don't have access to Xoreax Incredibuild (Dev Tools Package), we recommend compiling with a machine having 12 to 16 cores.

Requirements for UE5 Rendering Features

Some rendering features of Unreal Engine 5 have different requirements than the minimum specifications.

UE5 Feature

System Requirements

Lumen Global Illumination and Reflections

Software Ray Tracing:

Video cards using DirectX 11 with support for Shader Model 5

Hardware Ray Tracing:

Windows 10 build 1909.1350 and newer with DirectX 12 support

Windows 10 version 1909 — The revision number should exceed or be equal to .1350.

Video cards must be NVIDIA RTX-2000 series and higher, or AMD RX-6000 series and higher

Nanite Virtualized Geometry

All versions of Windows 10 build 1909.1350 and newer, and Windows 11 with support for DirectX 12 Agility SDK are supported.

Windows 10 version 1909 — The revision number should exceed or be equal to .1350.

Windows 10 version 2004 and 20H2 — The revision number should exceed or be equal to .789.

DirectX 12 (with Shader Model 6.6 atomics), or Vulkan (VK_KHR_shader_atomic_int64)

SM6 must be enabled in the Project Settings. (On by default in new projects.)

Latest Graphics Drivers

Virtual Shadow Maps

All versions of Windows 10 build 1909.1350 and newer, and Windows 11 with support for DirectX 12 Agility SDK are supported.

Windows 10 version 1909 — The revision number should exceed or be equal to .1350.

Windows 10 version 2004 and 20H2 — The revision number should exceed or be equal to .789.

DirectX 12 (with Shader Model 6.6 atomics), or Vulkan (VK_KHR_shader_atomic_int64)

SM6 must be enabled in the Project Settings. (On by default in new projects.)

Latest Graphics Drivers

Temporal Super Resolution

Runs on any video card that supports Shader Model 5, but the limit of 8UAVs per shader has performance implications. Temporal Super Resolution shaders compile with 16bit types enabled on D3D12 that supports Shader Model 6.

Launcher PCB Mode

Enabling Launcher PCB Mode

Disabling Launcher PCB Mode

Windows Registry Install Path Override

Adding a Registry Install Path Override

Installing the Epic Games Launcher and Unreal Engine on multiple computers can be time-consuming and difficult to maintain, especially for IT staff and developers managing dozens or even hundreds of computers in academic, office or Internet cafe environments. To help those users, we updated the Launcher with functionality that makes it easier to set up and update applications, such as Unreal Engine (UE). The following overview describes how to install the Launcher on multiple computers so that you can set up and maintain applications with ease.

By the end of this document, you will learn how to enable Launcher PCB Mode and if necessary, you will know how to set the Windows Registry Install Path Override after enabling the PCB Mode feature.

At this time, these features are only supported on the Windows operating system.

Launcher PCB Mode

On Windows, the Launcher typically stores manifest, dynamic, and temporary files in the system's ProgramData folder (for example, %programdata%\Epic or C:\ProgramData\Epic). Often, if an office, academic, or Internet cafe administrator installs the Launcher and Unreal Engine on a server without mirroring the program data to client machines, they will encounter installation issues, including a client's inability to find game installs and re-installs of applications.

Sometimes, system administrators need to run a series of complicated steps to mirror the program data folder onto client machines. To simplify their workflow, the Launcher now supports PCB Mode. After enabling PCB Mode, the Launcher stores the program data folder inside of its install folder. Internet cafe owners, for example, will be able to set up the Launcher once on the server machine, such that the server's install folder will be cloned to its clients. With all of the program data files in the install folder, no additional work is necessary.

If you have never installed UE before, take some time to read through our initial installation guide, which goes through the basics of Installing Unreal Engine.

Enabling Launcher PCB Mode

Follow these steps to enable Launcher PCB Mode:

Install the Launcher on at least one machine (this can be a server). Later on, we will call this machine the 'original computer'.

Before moving onto the next step, make sure that the Launcher is closed.

To enable Launcher PCB Mode, move (or copy) the Epic folder into the Launcher's install directory. For illustrative purposes, we are moving the Epic folder from C:\ProgramData\Epic to C:\Program Files (x86)\Epic Games\Launcher.



PCB Mode attempts to simplify a user's workflow for installing multiple Engines from a Launcher. Read through the Launcher PCB Mode section to learn more about this new Launcher mode.

Using the Launcher, install the engine(s)-of-choice into the new computer(s).

Finally, copy the Launcher's and Engine's install directory to the new computer(s).

If the new computer's Engine install path is different from the original computer's path or if the new computer has different drive letters, you need to add a Registry Install Path Override after enabling the Launcher PCB Mode.

Disabling Launcher PCB Mode

To disable this mode, close the Launcher, and move the Epic folder from the Launcher's install directory back into the ProgramData directory, making sure to restart the Launcher after the move.

We encourage you to move the Epic folder rather than deleting it, because if you delete the folder from the Launcher install directory, you will probably lose manifest files (binary files that cannot be modified), which tell the Launcher where your game or application is installed.

Windows Registry Install Path Override

The Launcher stores game and application install location information in manifest files living in the system's ProgramData folder. At this time, if you move an installed game or application to a new location, the Launcher can't discover the moved installs. This can be problematic, especially for users who are moving the Launcher and game (or application) installs to machines that do not have the same drive letter or directory structure as the original install machine. If you find yourself having problems moving (or copying) the Launcher or its installs onto new machines, you may need to specify a registry install path override to point to the copied or moved game or application folder.

Typically, registry install path overrides are used with PCB Mode.

Install path (InstallLocation) overrides are specified in the Windows registry on a per game (or per application) basis, and the InstallLocation overrides may be added to any one of the following registry locations:

HKEY_LOCAL_MACHINE\SOFTWARE\Epic Games\EpicGamesLauncher\Overrides

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Epic Games\EpicGamesLauncher\Overrides

HKEY_CURRENT_USER\SOFTWARE\Epic Games\EpicGamesLauncher\Overrides

HKEY_CURRENT_USER\SOFTWARE\WOW6432Node\Epic Games\EpicGamesLauncher\Overrides

The next section uses the Registry Editor in Windows 10.

Adding a Registry Install Path Override

Perform the following steps to add a Registry Install Path Override:

In the search bar on the taskbar, type regedit.

Select the regedit Run command to open the Registry Editor.

You are going to use the Registry Editor to add the InstallLocation Override Subkey, which can be added to any one of the registry locations being listed in the Registry Install Path Override section. For the purposes of illustration, we are adding the Subkey to the following Key:

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Epic Games\EpicGamesLauncher\Overrides

Navigate to the following registry location: HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Epic Games\EpicGamesLauncher, making sure to select the EpicGamesLauncher Key.

To create a new Subkey for the EpicGamesLauncher Key, select the Edit menu, hover over the New option, and select the Key command.

Name the new Subkey, Overrides.

Now, repeat the previous two steps to create a new Subkey for Overrides, which you'll name UE_(Engine Version).

The registry path's format must include UE's mandatory folder name, which you can find in the Launcher's Install Dialog. As you can see in the following image, the mandatory folder name for this example is UE_5.0:



Select the Edit menu, hover over the New option, and select the String Value command.

Name the new String Value name, InstallLocation.

Finally, define the data value for InstallLocation, matching UE's mandatory folder name. In this example, we are using C:\Epic Games\UE_5.0.



The Launcher only reads registry values once on start-up, so if you update the registry, you need to restart the Launcher for it to discover the changes.

Installing UE and Content

Using the Launcher

From GitHub

Performing Updates

Using the Launcher

Copying UE and Content

Disabling Automatic Updates

Best Practices for Students

During Network Outages

Preparing for Memory Wipes

As universities, colleges, and trade schools continue to offer Unreal Engine (UE) to students and faculty, one of the most frequently asked questions we get from these users is how to distribute UE on school computers without exposing the academic account being used to access the engine. If you are installing UE in an academic environment, this document describes how deployment automation can be used to distibute academic installations of UE.

Installing UE and Content

Typically, schools install UE on several computers, for example, in a computer lab or instruction room. At this time, we do not provide a silent (or one-step) installer for UE, which means that the installer needs to be manually run at least once on a machine in the academic environment. Rather than mirroring the install machine or manually running the installer on the rest of the computers in the classroom, we automated part of the deployment process.

Perform the following steps to install UE in an academic environment:

Using the Launcher

If your school's network is behind a proxy server, it is a best practice to use the UE on GitHub build because the Launcher will not run behind the server. If, however, you prefer to use the Launcher version behind the proxy server, contact your IT department to have them open port 7777 or 7778. Keep in mind, though, that opening these ports does not always enable the Launcher to open or update behind a proxy server.

Download the latest installers using the following links:

PC - MSI

macOS - DMG

Run the installer on the machine you want to make an image from.

After the installer finishes its routine, the Launcher automatically runs, enabling you to log in with your Epic Games credentials.

To download and install the latest version of UE, begin by selecting the Unreal Engine sidebar option.



Click for full image.

Next, select the Library tab at the top.



Click the Engine Versions (+) button.



Open the drop-down list to select the engine version you want to download. For purposes of this example, select version 5.0.1.



Finally, click the Install button and follow the Installer's prompts to get Unreal Engine 5.0.1 onto your machine.



Some instructors use our learning samples in their curricula, and suppose an instructor teaching game design wants to use our Lyra Starter Game sample as a teaching tool. To download Lyra, they will need to select the Samples tab (1), then click on the Lyra Starter Game (2).



Click for full image.

From the Lyra Starter Game's Content Detail menu, first click the Free button to gain access to the content. The EULA window appears.



Click for full image.

Before downloading a learning sample, refer to the Supported Platforms and Supported Engine Version sections of the Content Detail menu, which we update when deploying new releases.

Accept the EULA, and the button changes to Create Project, click it to start setting up the project.



Set the project's name, its installation folder, and, if required, the engine version, before selecting Create.



When the Lyra Starter Game is done installing, you will see it in the Library > My Projects menu. It is also available to create new projects in the Vault.



If you see any automatically created projects in the Library > My Projects menu, delete them.

If you do not delete projects that the Launcher automatically creates for you, it may cause problems for users on share-machines using the same projects. This includes the Lyra Starter Game project created in the previous example, you will still have it available in the Vault.

After removing all of the automatically-created projects, you can mirror this machine's setup to the rest of your class's computers. Alternatively, you can save this machines image so that you can distribute it out to your lab's computers.

From GitHub

Visit the following pages (in order) to learn how to download, install, and update UE from GitHub:

Accessing Unreal Engine on GitHub

Downloading Unreal Engine Source Code

Updating to the Latest Changes from Epic

Performing Updates

After installing UE, you are ready to use the engine and some free content in an academic environment. It is important, however, to plan for updates because when new versions of UE are released, or when engine content is released, you can update the mirror or push out new content to install machines by copying the relevant files, which you can automate with a script.

Read through the following sections to learn how to update UE and engine content in an academic environment:

Using the Launcher

From a central machine, open the Launcher and navigate to the Library menu.

Click the Engine Versions (+) button.

After the Launcher downloads the latest version of UE, you can update the mirror.

If you do not want to perform updates using the Launcher, read through the following section to learn how to copy updates to lab machines with UE.

Copying UE and Content

Copy the following directories from the base machine to every machine that you want to update:

(Local Directory)\Epic Games\Launcher\VaultCache

[Local Directory]\Epic Games(Engine Version)

In some cases, it is possible to install the Launcher in the C:\Program Files (x86) folder.

If you are copying a specific version, for example, version 5.0, you can copy C:\Program Files (x86)\Epic Games(Engine Version), otherwise, you can use the wildcard character (*) to automate the copy operation for all engine versions, which looks like C:\Program Files (x86)\Epic Games\*.

Make the following directory on every machine that you want to update, [Local Drive Letter]\ProgramData\Epic\EpicGamesLauncher\Data\Manifests.

Assuming you recently downloaded the engine, copy the most recently downloaded .item file from [Local Drive Letter]\ProgramData\Epic\EpicGamesLauncher\Data\Manifests to the machine's local manifest directory (from the previous step).

As an example, the item file might look something like, ~\Manifests\6CB2FA12345680D212345678B525AE86.item .

To verify you have a copy of the most recently downloaded item file, open the file in a text editor and search for "AppName".

After following these steps, the Launcher automatically detects updates when a user runs the Launcher. This is true for new engine versions and downloaded content from the Marketplace.

If you want to disable the Launcher from automatically detecting updates, read through the following section.

Disabling Automatic Updates

By default, the Launcher automatically checks for updates during its launch routine. To prevent Launcher updates from taking up class time, perform the following steps:

Right-click the EpicGamesLauncher - Shortcut to open the Launcher's contextual menu.

Select the Properties to open the file's Properties window.

Locate the Target: property in the Shortcut tab and add the -noselfupdate command to the end of the target line.

Do not forget to re-enable Launcher updates when class is not in session.

Best Practices for Students

There are scenarios that might impact your students' ability to access UE (or downloaded content). For example, your school might regularly wipe computers for security (or resource) reasons, which might affect a student's progress in-class. To help those students, we have collected the following best practices for some common scenarios they might face while using UE in an academic environment.

During Network Outages

Students can run the Launcher during network outages by selecting the Continue in Offline Mode option during sign-in.



Click for full image.

After signing-in in Offline Mode, students can access UE, their projects, and previously downloaded content.

Preparing for Memory Wipes

If your school has a policy of wiping computer (or drive) memory on a regular schedule, returning student computers to their base image, students must save their work in a directory that will not be wiped (or cleared).

For example, suppose a student creates a new Lyra Starter Game project from their Vault on the Library tab.



When creating the new project, the student should specify a folder (or network directory, such as a Sandbox drive) that will not be removed when their computer is re-imaged.



As long as your school's policy allows it, students typically download additional content using the Launcher, however, if the downloaded content is not saved off the mirrored drive, the content will most likely be wiped during re-imaging.

Content Browser

Menu Bar

Main Toolbar

Level Viewport

Content Drawer / Content Browser

Bottom Toolbar

Outliner

Details Panel

This page describes the most common elements of the Unreal Engine 5 interface and what they do. It also links to other pages where you can learn more. Some of the elements described on this page, such as panels and menu bars, are generally the same across various parts of the engine. You should spend some time getting familiar with their general purpose and and functionality, especially if you're new to developing games and applications with Unreal Engine.

When you open Unreal Engine 5 for the first time, the Level Editor opens. You will see the following window:



Default Unreal Editor interface in Unreal Engine 5. Click the image for full size.

Number

Name

Description

1

Menu Bar

Use these menus to access editor-specific commands and functionality.

2

Main Toolbar

Contains shortcuts for some of the most common tools and editors in Unreal Engine, as well as shortcuts to enter Play mode (run your game inside Unreal Editor) and to deploy your project to other platforms.

3

Level Viewport

Displays the contents of your Level, such as Cameras, Actors, Static Meshes, and so on.

4

Content Drawer button

Opens the Content Drawer, from which you can access all of the Assets in your Project.

5

Bottom Toolbar

Contains shortcuts to the Command Console, Output Log, and Derived Data functionality. Also displays source control status.

6

Outliner

Displays a hierarchical tree view of all content in your Level.

7

Details panel

Appears when you select an Actor. Displays various properties for that Actor, such as its Transform (position in the Level), Static Mesh, Material, and physics settings. This panel displays different settings depending on what you select in the Level Viewport.

Menu Bar



Each editor in Unreal Engine has a menu bar that is located in the top-right of that editor window (Windows) or at the top of the screen (macOS). Some of the menus, such as File, Window, and Help, are present in all editor windows, not just the Level Editor. Others are editor-specific.

Main Toolbar

The Main Toolbar contains shortcuts to some of the most used tools and commands in Unreal Editor. It is divided into the following areas:



1. Save Button

Click this button to save the Level that is currently open.

2. Mode Selection

Contains shortcuts for quickly switching between different modes to edit content within your Level:

Select Editing

Landscape Editing

Foliage Editing

Mesh Painting

Fracture Editing

Brush Editing

3. Content Shortcuts

Contains shortcuts for adding and opening common types of content within the Level Editor.

Shortcut

Description

Create

Choose from a list of common Assets to quickly add to your Level. You can also access the Place Actors panels from this menu.

Blueprints

Create and access Blueprints.

Cinematics

Create a Level Sequence or Master Sequence cinematic.

4. Play Mode Controls

Contains shortcut buttons (Play, Skip, Stop, and Eject) for running your game in the Editor.

5. Platforms Menu

Contains a series of options you can use to configure, prepare, and deploy your project to different platforms, such as desktop, mobile, or consoles.

6. Settings

Contains various settings for the Unreal Editor, Level Editor Viewport, and game behavior.

Level Viewport

The Level Viewport displays the contents of the Level that is currently open. When you open a project in Unreal Engine, the project's default Level opens in the Level Viewport by default. This is where you can view and edit the contents of your active Level, whether it's a game environment, a product visualization app, or something else.

The Level Viewport can generally display the contents of the Level in two different ways:

Perspective, which is a 3D view you can navigate to see the contents of the viewport from different angles.

Ortographic, which is a 2D view that looks down one of the main axes (X, Y, or Z).



Different views of the Level Viewport in Unreal Engine 5. Top: Perspective view. Bottom: Top-down ortographic view. Click the image for full size.

To learn more about the Level Viewport, refer to the pages below.

Content Drawer / Content Browser

The Content Browser is a file explorer window that displays all of the Assets, Blueprints, and other files contained in your project. You can use it to browse through your content, drag Assets into the Level, migrate Assets between projects, and more.



Content Browser window in Unreal Engine 5.

The Content Drawer button, located in the bottom-left corner of the Unreal Editor, opens a special instance of the Content Browser that automatically minimizes when it loses focus (that is, when you click away from it). To keep it open, click the Dock in Layout button in the top-right corner of the Content Drawer. This creates a new instance of the Content Browser, but you can still open a new Content Drawer.

Bottom Toolbar

The Bottom Toolbar contains shortcuts to the Command Console, Output Log, and Derived Data functionality. It also displays source control status. It is divided into the following areas:



Number

Name

Description

1

Output Log

Debugging tool that prints out useful information while your application is running.

2

Command Console

Behaves as any other command line interface: enter console commands to trigger specific editor behaviors.

Type help and press Enter to open a list of available console commands in your browser.

3

Derived Data

Provides Derived Data functionality.

4

Source Control Status

Displays source control status if your project is connected to source control (for example, GitHub or Perforce). Otherwise, this will say Source Control Off.

Outliner

The Outliner panel (formerly known as World Outliner) displays a hierarchical view of all content in your Level. By default, it is located in the upper-right corner of the Unreal Editor window.



You can also use the Outliner panel to:

Quickly hide or reveal Actors by clicking their associated Eye button.

Access an Actor's context menu by right-clicking that Actor. You can then perform additional, Actor-specific operations from that menu.

Create, move, and delete content folders.

Details Panel

When you select an Actor in the Level Viewport, the Details panel will show the settings and properties that affect the Actor you selected. By default, it is located on the right side of the Unreal Editor window, under the World Outliner panel.



This example shows a cube Static Mesh Actor's Details panel. With the cube Static Mesh selected, the Details Panel appears docked to the right-hand side of the Unreal Editor. Click the image for full size.

Project

Blueprint

Object

Class

Actor

Casting

Component

Pawn

Character

Player Controller

AI Controller

Player State

Game Mode

Game State

Brush

Volume

Level

World

This page describes the most commonly used terms when working with Unreal Engine. If you find yourself wondering, "What is an Actor?" or "What is a Component?" this page will answer your questions, and more.

Once you understand a term, check the topics linked at the end of the section to learn more.

This page uses some programming concepts, notably classes and subclasses. In C++, a class is a code template that contains variables and behavior and can be extended. A subclass is a class that inherits some or all code and functionality from a parent class.

All of the C++ classes mentioned on this page are specific to Unreal Engine.

Project

An Unreal Engine 5 Project holds all the contents of your game. It contains a number of folders on your disk, such as Blueprints and Materials. You can name and organize folders inside a Project however you wish. The Content Browser panel inside the Unreal Editor shows the same directory structure found inside the Project folder on your disk.

Every project has a .uproject file associated with it. The .uproject file is how you create, open, or save a project. You can create any number of different projects and work on them in parallel.

For more information, see Projects and Templates.

Blueprint

The Blueprint Visual Scripting system is a complete gameplay scripting system that uses a node-based interface to create gameplay elements from within Unreal Editor. As with many common scripting languages, it is used to define object-oriented (OO) classes or objects in the engine. As you use Unreal Engine, you'll often find that objects defined using Blueprint are colloquially referred to as "Blueprints."

For more information, see Blueprints Visual Scripting.

Object

Objects are the most basic class in Unreal Engine - in other words, they act like building blocks and contain a lot of the essential functionality for your Assets. Almost everything in Unreal Engine inherits (or gets some functionality) from an Object.

In C++, UObject is the base class of all objects; it implements features such as garbage collections, metadata (UProperty) support for exposing variables to the Unreal Editor, and serialization for loading and saving.

For more information, see:

Unreal Architecture

Class

A Class defines the behaviors and properties of a particular Actor or Object in Unreal Engine. Classes are hierarchical, meaning a Class inherits information from its parent Class (that is, the Class it was derived or "sub-classed" from) and passes that information to its children. Classes can be created in C++ code or in Blueprints.

For more information, see:

Blueprint Class

Gameplay Classes

Class Creation Basics

Actor

An Actor is any object that can be placed into a level, such as a Camera, static mesh, or player start location. Actors support 3D transformations such as translation, rotation, and scaling. They can be created (spawned) and destroyed through gameplay code (C++ or Blueprints).

In C++, AActor is the base class of all Actors.

For more information, see:

Actors

Actors and Geometry

Casting

Casting is an action that takes an Actor of a specific class and tries to treat it as if it were of a different class. Casting can succeed or fail. If casting succeeds, you can then access class-specific functionality on the Actor you cast to.

For example, let's say you're making a game where you have multiple types of Volumes that can affect the player character in different ways. One of these volumes is Fire, which decreases player health over time. When the player overlaps with any Volume in the Level, you can cast that Volume to Fire to try to access its ""damage player health"" functionality.

If the cast succeeds — that is, if the player is standing in the fire — the player's health starts to decrease.

If the cast fails — that is, if the player is standing in any other kind of Volume — their health is not affected.

Casting is different from simply checking whether an Actor is of a given class, which would return a binary (yes or no) answer, but wouldn't allow you to interact with any specific functionality of that class.

Component

A Component is a piece of functionality that can be added to an Actor.

When you add a Component to an Actor, the Actor can use the functionality that the Component provides. For example:

A Spot Light Component will make your Actor emit light like a spot light.

A Rotating Movement Component will make your Actor spin around.

An Audio Component will give your Actor the ability to play sounds.

Components must be attached to an Actor and can't exist by themselves.

For more information, see:

Components

Components Window

Components

Pawn

Pawns are a subclass of Actor and serve as an in-game avatar or persona (for example, the characters in a game). Pawns can be controlled by a player or by the game's AI, as non-player characters (NPCs).

When a Pawn is controlled by a human or AI player, it is considered to be Possessed. Conversely, when a Pawn is not controlled by a human or AI player, it is considered to be Unpossessed.

For more information, see:

Pawn

Possessing Pawns

Character

A Character is a subclass of a Pawn Actor that is intended to be used as a player character. The Character subclass includes a collision setup, input bindings for bipedal movement, and additional code for player-controlled movement.

For more information, see:

Characters

Setting Up a Character

Setting Up Character Movement

Player Controller

A Player Controller takes player input and translates it into interactions in the game. Every game has at least one Player Controller in it. A Player Controller often possesses a Pawn or Character as a representation of the player in a game.

The Player Controller is also the primary network interaction point for multiplayer games. During multiplayer play, the server has one instance of a Player Controller for every player in the game since it must be able to make network function calls to each player. Each client only has the Player Controller that corresponds to their player and can only use their Player Controller to communicate with the server.

The associated C++ class is PlayerController.

For more information, see Player Controllers.

AI Controller

Just as the Player Controller possesses a Pawn as a representation of the player in a game, an AI Controller possesses a Pawn to represent a non-player character (NPC) in a game. By default, Pawns and Characters will end up with a base AI Controller unless they are specifically possessed by a Player Controller or told not to create an AI Controller for themselves.

The associated C++ class is AIController.

For more information, see AI Controllers.

Player State

A Player State is the state of a participant in the game, such as a human player or a bot that is simulating a player. Non-player AI that exists as part of the game world doesn't have a Player State.

Some examples of player information that the Player State can contain include:

Name

Current level

Health

Score

Whether they are currently carrying the flag in a Capture the Flag game.

For multiplayer games, Player States for all players exist on all machines and can replicate data from the server to the client to keep things in sync. This is different from a Player Controller, which will only exist on the machine of the player it represents.

The associated C++ class is PlayerState.

For more information, see Gameplay Framework Quick Reference.

Game Mode

The Game Mode sets the rules of the game that is being played. These rules can include:

How players join the game.

Whether or not a game can be paused.

Any game-specific behavior such as win conditions.

You can set the default Game Mode in the Project Settings and override it for different Levels. Regardless of how you choose to implement it, you can only have one Game Mode for each Level.

In a multiplayer game, the Game Mode only exists on the server and the rules are replicated (sent) to each of the connected clients.

The associated C++ class is GameMode.

For more information, see:

Game Mode and Game State.

Setting Up a Game Mode

Game State

A Game State is a container that holds information you want replicated to every client in a game. In simpler terms, it is 'The State of the Game' for everyone connected.

Some examples of what the Game State can contain include:

Information about the game score.

Whether a match has started or not.

How many AI characters to spawn based on the number of players in the world.

For multiplayer games, there is one local instance of the Game State on each player's machine. Local Game State instances get their updated information from the server's instance of the Game State.

The associated C++ class is GameState.

For more information, see Game Mode and Game State.

Brush

A Brush is an Actor that describes a 3D shape, such as a cube or a sphere. You can place brushes in a level to define level geometry (these are known as Binary Space Partition or BSP brushes). This is useful if you want to quickly block out a level, for example.

For more information, see:

Geometry Brush Actors

Content Examples

Volume

Volumes are bounded 3D spaces that have different uses based on the effects attached to them. For example:

Blocking Volumes are invisible and used to prevent Actors from passing through them.

Pain Causing Volumes cause damage over time to any Actor that overlaps them.

Trigger Volumes are programmed to cause events when an Actor enters or exits them.

For more information, see Actors Reference.

Level

A Level is a gameplay area that you define. Levels contain everything a player can see and interact with, such as geometry, Pawns, and Actors.

Unreal Engine saves each level as a separate .umap file, which is why you will sometimes see them referred to as Maps.

For more information, see:

Levels

Level Editor

World

A World is a container for all the Levels that make up your game. It handles the streaming of Levels and the spawning (creation) of dynamic Actors.

For more information, see:

World Settings

Level Streaming

Level Editor

Static Mesh Editor

Material Editor

Blueprint Editor

Physics Asset Editor

Behavior Tree Editor

Niagara Editor

UMG UI Editor

Font Editor

Sequencer Editor

Animation Editor

Control Rig Editor

Sound Cue Editor

Media Editor

nDisplay 3D Config Editor

DMX Library Editor

Unreal Engine 5 provides a combination of tools, editors, and systems you can use to create your game or application.

This page uses the following terms:

A tool is something you use to perform a specific task, like placing Actors inside a level, or painting terrain.

An editor is a collection of tools you use to achieve something more complex. For example, the Level Editor enables you to build your game's levels, or you can change the look and feel of Materials inside the Materials Editor.

A system is a large collection of features that work together to produce some aspect of the game or application. For example, Blueprint is a system used to visually script gameplay elements.

Sometimes, systems and editors can have similar names. For example, the Material Editor is used to edit Material assets, while the Material system provides the underlying support for using Materials in Unreal Engine.

Some of these tools and editors in Unreal Engine are built-in, while others come in the form of optional plugins that you can enable or disable depending on your project needs. To learn more about plugins, refer to the Working with Plugins page.

This page gives an overview of the major tools and editors you will be working with inside Unreal Engine 5. The use of various Unreal Engine tools is covered in detail in feature-specific documentation.

Whether you use the Blueprint Editor to script behaviors for the Actors in your level, or create particle effects with the Niagara Editor, a good understanding of what each editor can do and how to navigate each one can improve your workflow and help prevent stumbling blocks during development.

Level Editor

The Level Editor is the primary editor where you construct your gameplay levels. This is where you define the play space for your game by adding different types of Actors and Geometry, Blueprints Visual Scripting, Niagara, and so on. By default, when you create or open a project, Unreal Engine 5 will open the Level Editor.

For more information, see Level Editor.

Static Mesh Editor

You can use the Static Mesh Editor to preview the look, collision, and UV mapping, as well as set and manipulate the properties of Static Meshes. Inside the Static Mesh Editor, you can also set up LODs (or Level of Detail settings) for your Static Mesh assets to control how simple or detailed they appear based on how and where your game is running.

For more information, see Static Mesh Editor UI.

Material Editor

The Material Editor is where you create and edit Materials. Materials are assets that can be applied to a mesh to control its visual look. For example, you can create a dirt Material and apply it to floors in your level to create a surface that looks like it is covered in dirt.

For more information, see Material Editor User Guide.

Blueprint Editor



Blueprint Editor inside Unreal Engine 5. Click for full view.

The Blueprint Editor is where you can work with and modify Blueprints. These are special Assets that you can use to create gameplay elements (for example, controlling an Actor or scripting an event), modify Materials, or implement other Unreal Engine features without the need to write any C++ code.

For more information, see Blueprint Editor Reference.

Physics Asset Editor

You can use the Physics Asset Editor to create Physics Assets for use with Skeletal Meshes. In practice, this is how you implement physics features like deformations and collisions. You can start from nothing and build to a full ragdoll setup, or use the automation tools to create a basic set of Physics Bodies and Physics Constraints.

For more information, see Physics Asset Editor.

Behavior Tree Editor

The Behavior Tree Editor is where you can script Artificial Intelligence (AI) through a visual node-based system (similar to Blueprints) for Actors in your levels. You can create any number of different behaviors for enemies, non-playing characters (NPCs), vehicles, and so on.

For more information, see Behavior Tree User Guide.

Niagara Editor

The Niagara Editor is for creating special effects by leveraging a fully modular particle effects system composed of separate particle emitters for each effect. Emitters can be saved in the Content Browser for future use, and serve as the basis of new emitters in your current or future projects.

For more information, see Niagara Key Concepts.

UMG UI Editor

The UMG (Unreal Motion Graphics) UI Editor is a visual UI authoring tool that you can use to create UI elements, such as in-game head's up displays, menus or other interface-related graphics.

For more information, see UMG UI Designer Quick Start Guide.

Font Editor

Use the Font Editor to add, organize and preview Font Assets. You can also define font parameters, such as Font Asset layout and hinting policies (font hinting is a mathematical method that ensures your text will be readable at any display size).

For more information, see Font Asset and Editor.

Sequencer Editor



Sequencer was used in the production of the Weta Digital animated short, Meerkat. Click for full view.

The Sequencer Editor gives you the ability to create in-game cinematics with a specialized multi-track editor. By creating Level Sequences and adding Tracks, you can define the makeup of each Track, which will determine the content for the scene. Tracks can consist of things like Animations (for animating a character), Transformations (moving things around in the scene), Audio (for including music or sound effects), and so on.

For more information, see Sequencer Overview.

Animation Editor

The Animation Editor within Unreal Engine 5 is used for editing Skeleton Assets, Skeletal Meshes, Animation Blueprints, and various other animation assets.

For more information, see Animation Editors.

Control Rig Editor

Control Rig is a suite of animation tools for you to rig and animate characters directly in-engine. Using Control Rig, you can bypass the need to rig and animate in external tools, and instead animate in Unreal Editor directly. With this system, you can create and rig custom controls on a character, animate in Sequencer, and use a variety of other animation tools to aid your animating process.

For more information, see Control Rig.

Sound Cue Editor

The behavior of audio playback in Unreal Engine 5 is defined within Sound Cues, which can be edited using the Sound Cue Editor. Inside this editor, you can combine and mix several sound assets to produce a single mixed output saved as a Sound Cue.

For more information, see Sound Cue Editor.

Media Editor

Use the Media Editor to define media files or URLs to use as source media for playback inside Unreal Engine 5.

You can define settings for how your source media will play back, such as auto-play, play rate, and looping, but you can't edit media directly.

For more information, see Media Editor Reference.

nDisplay 3D Config Editor

nDisplay renders your Unreal Engine scene on multiple synchronized display devices, such as powerwalls, domes, and curved screens. With the nDisplay Configuration Editor, you can create your nDisplay setup and visualize how content will be rendered across all the display devices.

For more information, see nDisplay 3D Config Editor.

DMX Library Editor



DMX in action. This screenshot is from a sample project by Moment Factory. Click for full view.

DMX (Digital Multiplex) is a standard for digital communication used throughout the live-events industry to control various devices, such as lighting fixtures, lasers, smoke machines, mechanical devices, and electronic billboards. In the DMX Library Editor, you can customize these devices and their commands.

For more information, see DMX.

Spaces

Space Transformations

Spaces

Space in Unreal

Other Names

Description

Tangent

Orthogonal (can deviate after interpolation), can be left or right handed. The TangentToLocal transform contains rotation only, so it is OrthoNormal (can be inverted by transposing).

Local

Object Space

Orthogonal, can be left or right handed (triangle cull order needs adjustment). The LocalToWorld transform contains rotation, non-uniform scaling (including negative non-uniform scaling which can change the winding order), and translation.

World

The WorldToView transform contains only rotation and translation, so distances in View space are the same as in World space.

TranslatedWorld

World

TranslatedWorld - PreViewTranslation

TranslatedWorld

World + PreViewTranslation

Translated matrices are used to remove camera position from the combined transform matrices, which improves precision when transforming vertices.

View

CameraSpace

The ViewToClip transform contains scale on x and y, but no translation (which would be an off center projection). It scales and translates z. It also applies a projection to convert into the homogeneous ClipSpace.

Clip

HomogeniousCoordinates, PostProjectionSpace, ProjectionSpace

After the perspective projection matrix was applied. Note that W in Clip space is the same as View Space Z.

Screen

NormalizedDeviceCoordinates from OpenGL

After the perspective divide:

left/right

-1,1

top/bottom

1,-1

near/far

0,1 (OpenGL RHI needs to transform this to -1,1)

Viewport

ViewportCoordinates, WindowCoordinates

In pixels :

left/right

0, width-1

top/bottom

0, height-1

Space Transformations

Transformation between spaces should always be named using the form X To Y.

Examples:

WorldToView

TranslatedWorldToView

TangentToWorld

Hardware and Software Requirements

Acquiring Unreal Engine

Building Unreal Engine from Source

Connecting to Perforce

Launching the Editor

Creating Your First Project

Compiling Code Projects

Hardware and Software Requirements

This page covers the hardware and software requirements for Unreal Engine 5. It also describes what is installed by the pre-requisites installer included in the Unreal Engine installer.

Recommended Hardware

Operating System

Windows 10 64-bit version 1909 revision .1350 or higher, or versions 2004 and 20H2 revision .789 or higher.

Processor

Quad-core Intel or AMD, 2.5 GHz or faster

Memory

8 GB RAM

Graphics Card

DirectX 11 or 12 compatible graphics card

RHI Version

DirectX 11: Latest drivers

DirectX 12: Latest drivers

Vulkan: AMD (21.11.3+) and NVIDIA (496.76+)

Operating System

Latest MacOS Ventura

Processor

Quad-core Intel, 2.5 GHz or faster

Memory

8 GB RAM

Video Card

Metal 1.2 Compatible Graphics Card

Operating System

Ubuntu 22.04

Processor

Quad-core Intel or AMD, 2.5 GHz or faster

Memory

32 GB RAM

Video Card

NVIDIA GeForce 960 GTX or Higher with latest NVIDIA binary drivers

Video RAM

8 GB or more

RHI Version

Vulkan: AMD (21.11.3+) and NVIDIA (515.48+)

To get the most out of rendering features of Unreal Engine 5 such Nanite and Lumen, see the Requirements for UE5 Rendering Features section of this page.

Minimum Software Requirements

Minimum requirements for running the engine or editor are listed below.

Running the Engine

Operating System

Windows 10

DirectX Runtime

DirectX End-User Runtimes (June 2010)

Running the Engine

Operating System

macOS latest Monterey

Running the Engine

Operating System

Any reasonable new Linux distro from CentOS 7.x and up

Linux Kernel Version

kernel 3.x or newer

Additional Dependencies

glibc 2.17 or newer

The requirements for programmers developing with the engine are listed below.

Developing with the Engine

All 'Running the Engine' requirements (automatically installed)

Visual Studio Version

Visual Studio 2019 v16.11.5 or later (recommended)

Visual Studio 2022



iOS App Development



iTunes Version

iTunes 12 or higher

Developing with the Engine

Xcode Version

13.4.1

Developing with the Engine

Operating System

Ubuntu 22.04

Compiler

clang 13.0.1



Optional



IDE

Visual Studio Code, Rider

Software Installed by the Prerequisite Installer

The Unreal Engine includes a prerequisite installer that installs everything needed to run the editor and engine, including several DirectX components and Visual C++ redistributables. When you install Unreal Engine through the Epic Games Launcher, the Launcher automatically installs these prerequisites for you. However, you may need to run the prerequisite installer yourself if you build Unreal Engine from source, or if you need to prepare a computer with all the Unreal Engine prerequisites for a specific purpose—for example, if you are setting up a fresh computer to act as a Swarm Agent.

You can find the installer in the Engine/Extras/Redist/en-us folder under your Unreal Engine installation location.

Support for 32-bit platforms has been removed in Unreal Engine 5.

If you use Perforce to get the Unreal Engine source code, you'll also find precompiled binaries in the same Engine/Extras/Redist/en-us folder of the Perforce repository. The source for the installer is under Engine/Source/Programs/PrereqInstaller.

The following table lists the software that is installed by the prerequisite installer.

DirectX Components

Visual C++ Redists

XInput 1.3 (April 2007)

Visual C++ 2010 CRT

X3DAudio 1.7 (February 2010)

Visual C++ 2010 OpenMP library

XAudio 2.7 (June 2010)

Visual C++ 2012 CRT

D3D Compiler 4.3 (June 2010)

Visual C++ 2013 CRT

D3DCSX 4.3 (June 2010)

Visual C++ 2015 CRT

D3DX9 4.3 (June 2010)

Microsoft Visual C++ 2015-2022 Redistributable

D3DX10 4.3 (June 2010)

D3DX11 4.3 (June 2010)

The most important DirectX components from that list are the XInput, X3DAudio, and XAudio dependencies. These aren't included in standard installations of DirectX (and aren't distributed with Windows by default), so they have to be installed manually or distributed with the application.

Some features of Unreal Engine that require DirectX 12, require at minimum Windows 10 version 1703 (Window Creator Update). For the best experience that supports features like Nanite, Virtual Shadow Maps, and Lumen, we recommend using Windows 10 version 2004 or 20H2.

Graphics Card Drivers

We currently recommend using the latest stable releases from each card manufacturer:

Download NVIDIA drivers here

Download AMD drivers here

Performance Notes

This list represents a typical system used at Epic, providing a reasonable guideline for developing games with Unreal Engine 5:

Windows 10 64-bit (Version 20H2)

64 GB RAM

256 GB SSD (OS Drive)

2 TB SSD (Data Drive)

NVIDIA GeForce RTX 2080 SUPER

Xoreax Incredibuild (Dev Tools Package)

Six-Core Xeon E5-2643 @ 3.4GHz

If you don't have access to Xoreax Incredibuild (Dev Tools Package), we recommend compiling with a machine having 12 to 16 cores.

Requirements for UE5 Rendering Features

Some rendering features of Unreal Engine 5 have different requirements than the minimum specifications.

UE5 Feature

System Requirements

Lumen Global Illumination and Reflections

Software Ray Tracing:

Video cards using DirectX 11 with support for Shader Model 5

Hardware Ray Tracing:

Windows 10 build 1909.1350 and newer with DirectX 12 support

Windows 10 version 1909 — The revision number should exceed or be equal to .1350.

Video cards must be NVIDIA RTX-2000 series and higher, or AMD RX-6000 series and higher

Nanite Virtualized Geometry

All versions of Windows 10 build 1909.1350 and newer, and Windows 11 with support for DirectX 12 Agility SDK are supported.

Windows 10 version 1909 — The revision number should exceed or be equal to .1350.

Windows 10 version 2004 and 20H2 — The revision number should exceed or be equal to .789.

DirectX 12 (with Shader Model 6.6 atomics), or Vulkan (VK_KHR_shader_atomic_int64)

SM6 must be enabled in the Project Settings. (On by default in new projects.)

Latest Graphics Drivers

Virtual Shadow Maps

All versions of Windows 10 build 1909.1350 and newer, and Windows 11 with support for DirectX 12 Agility SDK are supported.

Windows 10 version 1909 — The revision number should exceed or be equal to .1350.

Windows 10 version 2004 and 20H2 — The revision number should exceed or be equal to .789.

DirectX 12 (with Shader Model 6.6 atomics), or Vulkan (VK_KHR_shader_atomic_int64)

SM6 must be enabled in the Project Settings. (On by default in new projects.)

Latest Graphics Drivers

Temporal Super Resolution

Runs on any video card that supports Shader Model 5, but the limit of 8UAVs per shader has performance implications. Temporal Super Resolution shaders compile with 16bit types enabled on D3D12 that supports Shader Model 6.

Acquiring Unreal Engine

Unreal Engine can be downloaded by licensees from Epic's Perforce (P4V) proxy server. The login credentials for the Perforce server are provided to your team's technical lead by Epic Games in your UDN welcome email. Only one set of login credentials is provided to each team.

Source Code Branches

You'll notice that we've published UE's source code in several branches.



Branches whose names contain dev, staging, and test are typically for internal Epic processes, and are rarely useful for end-users Other short-lived branches may appear from time to time as we stabilize new releases or hotfixes.

The Release branch always reflects the current official release. These are extensively tested by our QA team, so they make a great starting point for learning Unreal Engine and for making your own projects. We work hard to make releases stable and reliable, and aim to publish a new release every few months.

Most active development on UE happens in the ue5-main branch. This branch reflects the latest release of the engine and may be buggy or it may not compile. We make it available for developers who are eager to test new features or work in lock-step development with us.

If you choose to work in this branch, be aware that it is likely to be ahead of the branches for the current official release and the next upcoming release. Therefore, content and code that you create to work with the ue5-main branch may not be compatible with public releases until we create a new branch directly from ue5-main for a future official release.

Downloading the Source Code

Please follow these instructions to download the Unreal Engine source code.

Refer to our Setting Up Visual Studio to ensure that you have a version of Visual Studio that is compatible with your desired version of Unreal Engine.

Install GitHub for Windows then fork and clone our repository.

To use Git from the command line, see the Setting up Git and Fork a Repo articles.

If you'd prefer not to use Git, you can get the source with the 'Download ZIP' button on the right. The built-in Windows zip utility will mark the contents of zip files downloaded from the Internet as unsafe to execute, so right-click the zip file and select 'Properties...' and 'Unblock' before decompressing it. Third-party zip utilities don't normally do this.

Install Visual Studio.

All desktop editions of Visual Studio can build UE, including Visual Studio Community, which is free for small teams and individual developers. Refer to the Setting Up Visual Studio page to ensure that you have downloaded all of the necessary VS components for working with UE.

Open your source folder in Explorer and run Setup.bat.

This will download binary content for the engine, as well as installing prerequisites and setting up Unreal file associations. On Windows, a warning from SmartScreen may appear. Click More info, then Run anyway to continue.

A clean download of the engine binaries may take some time to complete. Subsequent checkouts only require incremental downloads and will be much quicker.

Run GenerateProjectFiles.bat to create project files for the engine. It should take less than a minute to complete.

Load the project into Visual Studio by double-clicking on the UE5.sln file. Set your solution configuration to Development Editor and your solution platform to Win64, then right click on the UE target and select Build. It may take anywhere between 10 and 40 minutes to finish compiling, depending on your system specs.

After compiling finishes, you can load the editor from Visual Studio by setting your startup project to UE5 and pressing F5 to debug.

Install a Git client like GitHub for Mac, then fork and clone our repository.

To use Git from the Terminal, see the Setting up Git and Fork a Repo articles. If you'd rather not use Git, use the 'Download ZIP' button on the right to get the source directly.

Install the latest version of Xcode.

Open your source folder in Finder and double-click on Setup.command to download binary content for the engine. You can close the Terminal window afterwards.

If you downloaded the source as a .zip file, you may see a warning about it being from an unidentified developer (because .zip files on GitHub aren't digitally signed). To work around it, right-click on Setup.command, select Open, then click the Open button.

In the same folder, double-click GenerateProjectFiles.command. It should take less than a minute to complete.

Load the project into Xcode by double-clicking on the UE5.xcworkspace file. Select the ShaderCompileWorker for My Mac target in the title bar, then select the 'Product > Build' menu item. When Xcode finishes building, do the same for the UE5 for My Mac target. Compiling may take anywhere between 15 and 40 minutes, depending on your system specs.

After compiling finishes, select the 'Product > Run' menu item to load the editor.

Our developers and support teams currently use the latest version of Ubuntu; as a result, we may not be able to provide support for other Linux distributions (including other versions of Ubuntu).

Install a visual Git client and fork our repository. If you'd prefer not to use Git, use the Download ZIP button on the right to get the source as a zip file.

Open your source folder and run Setup.sh to download binary content for the engine.

Both cross-compiling and native builds are supported.

Cross-compiling is handy when you are a Windows (Mac support planned too) developer who wants to package your game for Linux with minimal hassle, and it requires a cross-compiler toolchain to be installed (refer to the Linux cross-compiling page).

Native compilation is discussed in a separate README.

This page shows Licensees how to download and build Unreal Engine from our source code repository on GitHub. If you'd like to download the binary version of Unreal Engine, read our Installing Unreal Engine documentation to learn how to Get Unreal.

Additional target platforms

Android support will be downloaded by the setup script if you have the Android NDK installed. See the Android Quick Start guide.

iOS development requires a Mac. Instructions are in the iOS Quick Start guide.

Development for consoles and other platforms with restricted access, like Sony PlayStation, Microsoft Xbox, and Nintendo Switch, is only possible if you have a registered developer account with those third-party vendors.

Depending on the platform, additional documentation or guidance may be available in the Unreal Developer Network support site, or as a downloadable archive in the section of the Unreal Engine Forums that is dedicated to your platform.

If you don't have access to these resources, first register a developer account with the third party vendor. Then contact your Epic Games account manager if you have one, or fill out and submit the Console Development Request form for Unreal Engine if you don't. Epic will contact you with a formal agreement to digitally sign. Once this is approved, you will receive instructions on how to access source code, binaries, and additional instructions for your platform.

Licensing and Contribution

Your access to and use of Unreal Engine on GitHub is governed by the Unreal Engine End User License Agreement. If you don't agree to those terms, as amended from time to time, you are not permitted to access or use Unreal Engine.

We welcome any contributions to Unreal Engine development through pull requests on GitHub. Most of our active development is in the master branch, so we prefer to take pull requests there (particularly for new features). We try to make sure that all new code adheres to the Epic coding standards. All contributions are governed by the terms of the EULA.

Next Steps

Now that you've downloaded and set-up Unreal Engine, you're ready to build the engine from source.

The first time you start the editor from a fresh source build, you may experience long load times. The engine is optimizing content for your platform to the derived data cache, and it should only happen once.

Your private forks of the Unreal Engine code are associated with your GitHub account permissions. If you unsubscribe or switch GitHub user names, you'll need to re-fork and upload your changes from a local copy.

Building Unreal Engine from Source

Read about Hardware and Software Specifications, and make sure that Microsoft Visual Studio is installed prior to building Unreal Engine (UE) from source. Also, depending on your system's specifications, it may take between 10 and 40 minutes to compile the Engine.

Inside the root directory, where you downloaded and adjusted the UE Source Code run GenerateProjectFiles.bat to set-up your project files.



All project files are intermediate ([UERoot]\Engine\Intermediate\ProjectFiles). You must generate project files each time you sync a new build to ensure they are up to date. If you delete your Intermediate folder, you must regenerate project files using the GenerateProjectFiles batch file.

Load the project into Visual Studio by double-clicking UE5.sln.



Set your solution configuration to Development Editor.



Set your solution platform to Win64.



Right-click the UE5 target and select Build.



For instructions on building the engine and creating executables on platforms other than Windows, please see Building Unreal Engine from Source.

Connecting to Perforce

Connect to Epic's Perforce Server

Connecting to the Epic Games Perforce server requires using the SSL feature, and you must be running a 2017.2 or later version of a Perforce client (P4V, p4, or API). You can take advantage of latency based routing to automatically connect to the closest Perforce regional proxy by using the global DNS name. Alternatively, you can connect directly to a regional proxy to ensure you always connect to the closest one.

If you are running a local proxy, you must connect through a broker instead of using the region proxy servers. You can connect to the global broker using the address below:

ssl:p4-licensee.epicgames.com:1666

Install the P4V Perforce client for Windows. The client can be downloaded from the Perforce Downloads page.

In the Open Connection dialog, enter the following connection info:

Server: ssl:p4-licensee.epicgames.com:1666

The address above should automatically direct you to a regional proxy with the best latency based on your geographic location. If, for some reason, you need to connect to a specific regional proxy, you can connect to them using the addresses below:

United States East (Virginia): ssl:p4-licensee-east.us.epicgames.com:1666

United States West (Oregon): ssl:p4-licensee-west.us.epicgames.com:1666

Asia Pacific Northeast (Tokyo): ssl:p4-licensee-northeast.ap.epicgames.com:1666

Europe Central (Frankfurt): ssl:p4-licensee-central.eu.epicgames.com:1666

User: Perforce username provided by Epic Games.

Password: Perforce password provided by Epic Games.

Click OK to connect to the Perforce Server.



Click the image for full size.

When connecting to an endpoint for the first time, you must explicitly trust that endpoint.

The Epic SSL fingerprint is 45:0D:78:E2:0E:9E:E4:82:45:80:16:36:29:5E:54:4D:66:31:6C:43.

P4V will prompt you to trust the new endpoint.

Command line p4 uses the p4 trust command: $ p4 trust -y.

In P4V, choose Connection > New Workspace to create a new workspace for the engine. Enter the information below and click OK to create the workspace:

Workspace name: Give your new workspace a name.

Stream: Click Browse and select //UE5/Release-Latest from the list of available streams.



In the Depot pane, expand the Filter Depot menu and select Tree Restricted to Workspace View.



Download Unreal Engine

Epic Games distributes Unreal Engine to licensees via the //UE5/Release-Latest stream in the Perforce depot. This contains the entire engine along with several additional projects in the form of example games, samples, and demos. You have the option of downloading everything or picking and choosing only the parts you want or need.

To get set up as quickly as possible, we recommend you only download the bare minimum to start with and then download other parts on an as-needed basis. This can dramatically reduce idle time spent waiting for the download to finish. We also provide a //UE5/Release-Latest-Minimal stream to help with this.

Because there are a large number of files in the //UE5/Release-Latest stream and the total download size is many gigabytes, the download can take a long time when syncing the entire branch.

Right-click on the stream you want to download and choose Get Latest Revision.



The latest version of all files will be downloaded.

Launching the Editor

The process of running the editor requires passing the name of the project to run as an argument to the executable.

You can add the -debug switch to force the executable to load the debug version of the modules for your project, which contain all of the debugging symbols. This is necessary even when debugging through Xcode with the configuration set to Debug because the main executable is always compiled using the Development configuration. Of course, you must first compile your modules using the Debug configuration so they exist for the executable to load.

The process of running the editor requires passing the name of the project to run as an argument to the executable.

You can add the -debug switch to force the executable to load the debug version of the modules for your project, which contain all of the debugging symbols. This is necessary even when debugging through Visual Studio with the configuration set to Debug because the main executable is always compiled using the Development configuration. Of course, you must first compile your modules using the Debug configuration so they exist for the executable to load.

From a command prompt, navigate to your [LauncherInstall]/[VersionNumber]/Engine/Binaries/Mac directory.

Run the UEEditor.app passing it the path to your project:

From a command prompt, navigate to your [LauncherInstall][VersionNumber]\Engine\Binaries\Win64 directory.

Run the UEEditor.exe, passing it the path to your project.

Navigate to your [LauncherInstall][VersionNumber]\Engine\Binaries\Win64 directory.

Right-click on the UEEditor.exe executable and choose Create shortcut.

Rename the shortcut to something like MyProject - Editor.exe as this reflect that this shortcut runs the MyProject game editor.

Right-click on the newly created shortcut and choose Properties.

Add the name of the game to run as an argument at the end of the Target property:

Press OK to save the changes.

Double-click the shortcut to launch the editor.

The editor must be run from the command prompt to load a specific project directly or with no arguments to access the Project Browser.

If the editor is not set to open the most recent project at startup, running the editor executable without any arguments will launch the Project Browser. From here, you can create a new project , open your existing projects , or open content examples and sample games .

Creating Your First Project

When you open Unreal Editor, the Project Browser will appear. The Project Browser provides a jumping off point from which you can create projects, open your existing projects, or open sample content like sample games and Showcases.

When you launch Unreal Engine, the Unreal Project Browser opens automatically. This is where you can:

Create a new project.

Open an existing project.

Manage existing projects.

The diagram below illustrates the steps to create a new project in Unreal Engine.



Creating a new project in Unreal Engine from the Project Browser window.

To create a new project, follow these steps:

Select the development category (1) that best matches your industry and project goals.

You can select from the following categories:

Games

Film, Television, and Live Events

Architecture, Engineering, and Construction (AEC)

Automotive, Product Design, and Manufacturing (APM)

Select a template (2) for your project. The templates you can choose from are based on the category you selected in step 1.

Unreal Engine contains a number of project templates you can use as a starting point for your own projects. To learn more about the different project templates available, refer to the Templates Reference page.

Configure the Project Defaults (3). In this section, you can select your target platform (that is, the hardware where your game or application will run, like a computer or a mobile device), configure quality and ray tracing settings, and more.

Some of the settings below may not be available for certain templates. For example, the Handheld AR template can only use Blueprint implementation.

You can configure the following settings:

Setting

Description

Implementation

Select how you want to implement your project's logic, such as character movement, level transitions, and so on.

You can choose from the following options:

Blueprint, if you want to build your project in the Unreal Editor, and use the Blueprint Visual Scripting system to create interactions and behavior.

C++, if you want to build your project by programming with C++ in Visual Studio.

For more information about these implementation methods, refer to the following pages:

Blueprint Visual Scripting

Programming with C++

Target Platform

Select the kind of platform your project is intended for:

Desktop

Mobile

Quality Preset

Select the maximum quality level, based on which platform your project targets. We recommend that you choose:

Maximum, if you are developing your project for a computer or game console.

Scalable, if you are developing your project for mobile devices.

Starter Content

Select whether you want your new project to include starter content. Starter content includes some simple Static Meshes with basic textures and Materials. It is useful if you want to start learning and experimenting straight away, without worrying about sourcing and importing custom content.

Ray Tracing

Select whether to enable or disable ray tracing for your project.

For more information about ray tracing in Unreal Engine, refer to the Hardware Ray Tracing and Path Tracing Features page.

Select where you want to store your project, and give your project a name (4).

Click Create (5) to finish creating your new project.

Result

Unreal Engine creates a new project with the settings you configured, and then automatically opens the project.

Compiling Code Projects

If you create a project with the Blank template, or any of the Blueprints Only templates, you can immediately begin working with your project in Unreal Editor. When working with any game or engine C++ code, however, you will need to compile your code in order to see any changes reflected in the game.

Unreal Engine (UE) uses a custom building method using the UnrealBuildTool (UBT) which handles all the complex aspects of compiling the project and linking it with the engine. This process occurs transparently allowing you to simply build the project through the standard Visual Studio build workflow.

UnrealBuildTool uses the *.build.cs and *.target.cs files to build the game project. These are automatically generated when a project is created using a C++ template, or when the CPP Class Wizard is used to add code to a project created from a Blueprints Only template.

Build Configuration

Unreal projects have multiple targets, including Editor, Client, Game, and Server, described by *.target.cs files. Furthermore, each of these can be built to different configurations. In Visual Studio, this manifests as a Visual Studio *.vcxproj file with different configurations for each target. The solution configurations are named as [Configuration][Target Type] (for example, "DevelopmentEditor" for the default editor target, and "Development" for the default standalone game target). The configuration you use will be determined by the purposes of the build you want to create.

Every build configuration contains two keywords, and the first keyword indicates the state of the engine and your game project. For instance, if you compile using a Debug configuration, you will be able to debug your game's code. The second keyword indicates the target you are building for. For example, if you want to open a project in Unreal, you need to build with the Editor target keyword.

Build Configuration - State

Description

Debug

This configuration contains symbols for debugging. This configuration builds both engine and game code in debug configuration. If you compile your project using the Debug configuration and want to open the project with the Unreal Editor, you must use the -debug flag in order to see your code changes reflected in your project.

DebugGame

This configuration builds the engine as optimized, but leaves the game code debuggable. This configuration is ideal for debugging only game modules.

Development

This configuration enables all but the most time-consuming engine and game code optimizations, which makes it ideal for development and performance reasons. Unreal Editor uses the Development configuration by default. Compiling your project using the Development configuration enables you to see code changes made to your project reflected in the editor.

Shipping

This is the configuration for optimal performance and shipping your game. This configuration strips out console commands, stats, and profiling tools.

Test

This configuration is the Shipping configuration, but with some console commands, stats, and profiling tools enabled.

Build Configuration - Target

Description

Game

This configuration builds a stand-alone executable version of your project, but requires cooked content specific to the platform. Please refer to the Packaging Projects Reference page to learn more about cooked content.

Editor

To open a project in Unreal Editor and see all code changes reflected, the project must be built in an Editor configuration.

Client

If you are working on a multiplayer project using UE networking features, this target designates the specified project as being a Client in UE's client-server model for multiplayer games. If there is a <GAME_NAME>Client.Target.cs file, the Client build configurations will be valid.

Server

If you are working on a multiplayer project using UE networking features, this target designates the specified project as being a Server in UE's client-server model for multiplayer games. If there is a <GAME_NAME>Server.Target.cs file, the Server build configurations will be valid.

Term Definitions

Section 1: Quickstart

Section 2: Accessing and Managing Accounts

Section 3: Installing Unreal Engine

Section 4: Getting Started

Section 5: Learning

Section 6: Support Resources

If you are an Unreal Engine developer with a custom license agreement or if you are currently evaluating Unreal Engine for a custom license, this document is for you. If you are a developer operating under the standard EULA and are interested in custom terms or premium Epic support, please contact us.

Term Definitions

Learn the following terms before proceeding.

Term

Definition

Unreal Developer Network (UDN)

Our private site for dedicated custom license support.

Unreal Engine

A complete suite of tools for creating interactive experiences.

UE

Acronym for Unreal Engine.

Unreal Editor

The interface used to develop with Unreal Engine.

Epic Games Launcher

A platform for installing Unreal Engine, including managing user projects and downloaded content.

Datasmith

A feature in Unreal Engine that provides import capabilities for data from a wide variety of CAD, BIM, and 3D content creation tools.

Section 1: Quickstart

For the best experience in getting started with your Unreal Engine license, follow these steps in order, skipping any that you have already completed.

1. Set up UDN access

If you are just starting with your Unreal Engine license, your first step is to sign into the Unreal Developer Network. Technical administrators are granted initial access, then given the ability to set up additional access rights for their staff.

2. Install Unreal Engine

The next step is to install the Unreal Engine. For most non-game developers, the recommended method is using the Epic Games Launcher, which you can download here. If you intend to customize the source code, or require standalone installers or distributed installation, you can find out more about your options in our detailed guide, where you can also learn about managing different installations side by side.

3. Install Datasmith Plugins (Optional)

Datasmith is a default feature in Unreal Engine. However, some formats such as 3ds Max, SketchUp Pro, and Revit, also require exporter plugins to be installed in the source application.

4. Launch Unreal Engine

You're now ready to get started and launch Unreal Editor. If you installed Unreal Engine using the Launcher, log in, click the Unreal Engine sidebar text, and click the yellow Launch button. You can also launch the editor from the Library tab, where you can select from multiple engine installations or load directly into your specific projects. Refer to our detailed guide for information about launching a custom or offline build of Unreal Editor.

5. Create a project

When you first open Unreal Editor, the Project Browser will appear. You can create a new project from a template here. You can also load one of the fully fleshed-out example projects from the Samples tab of the launcher.

6. Start your learning journey

There's a wealth of learning resources to help you get up to speed, including our Online Learning Platform. There's also lots of help available from the Unreal Engine Documentation.

7. Get Help

Are you stuck or are you experiencing any problems? Do you have a burning question? Reach out to the Unreal Developer Network. You can also engage with our public community, or contact us directly if you still need help.

Section 2: Accessing and Managing Accounts

The first step toward getting yourself and your staff up and running with your Unreal Engine license is to set up everyone's access. This section is recommended for technical administrators and provides more details than the information offered in the Quick Start guide.

Your Epic Account

Your gateway to the majority of features and services related to Unreal Engine is your Epic Games account, which is associated with your specific email address. You may have previously created an Epic account using your current professional email address, but if not, then you will need to sign up for an account.

All staff in your organization will also require their own Epic accounts to access all features and services for Unreal Engine. They will need to create individual accounts from www.unrealengine.com to log in.

UDN Access for You and Your Team

Epic staff will grant the initial UDN access to the primary technical contact who was identified during the license-signing process. This individual will be granted administrative permissions and have the ability to extend UDN access to additional staff.

Look for an email message titled "Welcome to the Unreal Developer Network (UDN) community!" which is automatically sent after your access has been enabled.

Follow the link in the email to log in to the UDN with the Epic account credentials related to your professional email address. You may experience login issues if you are already logged in to the Epic ecosystem with a different Epic account that does not have UDN access.

Upon the first login, complete the onboarding process to set up your profile and notification settings, and then your access is complete. You can now review knowledge articles, search for posts submitted by other developers, or post your own support requests.

To grant UDN access to additional members of your team, the primary technical contact who has been granted administrative permissions will need to follow the steps outlined in the UDN Administrator Guide.

Epic account security

For your account's security, we recommend that you enable Two-Factor Authentication. To do so, go into your Account Settings and click on the Password & Security tab. Scroll to the bottom, click the Send email verification link to confirm your email address, and then (based on your preference) click to choose either Enable Authenticator App or Enable Email Authentication.

Section 3: Installing Unreal Engine

A core part of your Unreal Engine license is access to the software tools it includes. This section will guide you through your options and methods for installing them.

Unreal Engine hardware and software requirements

Before installing the Unreal Engine, make sure your system will be able to run it. Recommended system specifications for Unreal Engine use on Windows, Mac, and Linux are available here.

We typically recommend using the latest stable releases for your graphics card driver.

Download NVIDIA drivers

Download AMD drivers

If you experience performance issues, VTune can be an extremely useful tool for finding problems; however, it only works on Intel CPUs. One of the most common bottlenecks is disk I/O, so getting a RAID 0 disk array and extra RAM can help.

Acquiring Unreal Engine

The Unreal Engine is available through a variety of sources, depending on your needs and use case. Use the following flow diagram to determine which is right for you, and then read the associated lettered paragraphs below to proceed.



State(s)

Definition

A

Do your staff need source code access to modify the engine's standard functionality?

B

Epic Games Launcher

C

GitHub

D

Perforce (by request)

D/E

Distributed Installation or Unreal Engine Standalong Installer (by request)

Most software that you are familiar with is provided as an executable program stored in binary (computer-readable) files. The Unreal Engine is available in a binary format, which is easiest to get started with, but which comes with the limitation that each release is provided as-is, meaning that it cannot be modified except with plugins, or when Epic releases an updated version.

The alternate approach is Source Code, which is also provided for Unreal Engine. Anyone can download the engine source code, make changes, updates, or improvements they want, then compile the code into a usable build. This approach grants a lot of control, but is also more complicated to get started with, and requires programming experience.

The binary build of the Unreal Engine is freely accessible to everyone to download using the Epic Games Launcher, and the source-code build is freely available to everyone through GitHub. These options are recommended to you as well, however, as a custom licensee, alternate access options are also available if required.

Accessing the binary build of the Unreal Engine using the Epic Games Launcher is the recommended approach for most non-game customers. The launcher will manage your downloads, notify you of updates, and handle the installation of plugins and other downloadable content. The only drawbacks may be presented for organizations that do not allow internet access or enforce restrictive software policies for their staff.

If you do not already have the Epic Games Launcher installed, then you can download it here. This specific download link enables a setting for non-game customers that will hide the navigation options for various video games that are normally available on the Launcher. These can be re-enabled in the Launcher settings if desired. The Launcher is also available from the Download button on www.unrealengine.com.

Once you have installed the Epic Games Launcher, you can log in to it with your Epic Account credentials. While on the Unreal Engine tab, you can click the yellow button on the right to install the latest version of the Unreal Engine, or you can navigate to the Library page for more control over the version you want to install.

It is important to note that new versions of Unreal Engine 4 are released multiple times a year and that each of these major version releases is a separate installation and not updates to the previous version. For example, if you have UE 5.0 installed, and UE 5.1 is released and you choose to install it, you will keep the previous 5.0 installation and add 5.1 as a separate new installation. This is represented on the Epic Games Launcher's Library page as different engine slots, where new slots can be added by clicking the Add (+) button.



Each major version is likely to receive smaller hotfix updates (represented by a point number, like .2 and .3). The Launcher will provide a notification when a hotfix is available, and the update for these will apply directly to the existing installation. When you install an engine version, it will always install the latest available version, with any hotfixes applied.

When installing Unreal Engine, it is helpful to note that you can choose where it installs to (this can be important since the file size for the Unreal Engine is multiple gigabytes) and that you also are provided installation options. The Options provide a way for you to configure what you need to download, such as code required to develop for particular platforms.



Once an engine version has been installed and the installation has been verified, click Launch to open the Unreal Editor.

For information on using the Editor, see "Section 4: Getting Started."

While on the Epic Games Launcher, don't forget to explore the Community, Samples, and Marketplace pages to discover additional resources.

If you require the ability to modify source code for Unreal Engine, downloading the source code through GitHub is the default recommendation.

For GitHub access, you need to successfully link your Epic Games account with your GitHub account. Once you have done so, you will be able to access the Unreal Engine source code through GitHub. More details can be found below:

Link your GitHub account.

Download Unreal Engine source code.

Build the Unreal Engine source code.

If neither of the above options meets your business needs, then Epic may be able to provide alternative access.

For businesses where the Unreal Engine is used on computers without an internet connection, we can provide an offline solution with a standalone version of the Unreal Engine.

For businesses that require source code access but whose needs are not met by GitHub, we can provide access to Epic's Perforce repository for Unreal Engine development.

If you have already been granted alternate access, additional documents are provided to explain how to get started. If you require special access, reach out to your Epic Business Development Manager.

The traditional installation workflow for the Unreal Engine is that the end-user directly downloads, and either installs or compiles the engine on their local computer. However, we are aware that this workflow is not appropriate for all organizations.

It is possible to download the engine to a single computer, then mirror the installation out to other computers. We have prepared a document to provide more information regarding this installation process here. The document was written specifically for academic institutions, but the installation information is applicable to other organizations.

Optional setup for Datasmith

Datasmith is a core part of Unreal Engine, and is immediately available for use by creating a new project from the categories of either Film, Television, and Live Events, Architecture, Engineering, and Construction, or Automotive, Product Design, and Manufacturing (see the Creating your first project section below for more details). If you are working with a project of a different category and want to enable Datasmith, you can navigate to Edit > Plugins > Importers, and from there enable the required Datasmith components and restart Unreal Editor.

Some formats, such as 3ds Max, SketchUp Pro, and Revit, also require plug-ins to be installed in the source application. If you intend to export your assets from these applications, follow the link to get the Exporter Plugins and install them.

Section 4: Getting Started

The Unreal Engine offers a wealth of resources to help you and your staff succeed with your projects—everything from getting up to speed with the Unreal Editor to becoming proficient with advanced development techniques. This section will guide you through the information you need on that journey, and we recommend you share it with all staff who will be using Unreal Engine.

Getting started

If you have used the Epic Games Launcher to install the Unreal Engine, you can launch the Unreal Editor by logging into the launcher, and clicking the yellow Launch button. Alternatively, you can launch the editor from the Library tab, where you can also manage your engine installations or directly open a specific project.

If you have installed the Unreal Engine via compiled source code or a standalone offline build, navigate to the directory where Unreal Engine was saved, and locate the executable in the following path:

Platform

Path

Windows

\Engine\Binaries\Win64\UE4Editor.exe

macOS

/Engine/Binaries/Mac/UE4Editor.app

You may want to create a desktop shortcut for easier access in the future.

When you first open Unreal Editor, the Project Browser will appear. The Project Browser provides a starting point from which you can create projects, open your existing projects, or open any downloaded sample projects.

When creating a new project, different templates are available, depending on the project category you select. The Blank template creates a completely empty project, while other template options provide foundations of content and functionality.



Some templates require the installation of Visual Studio to compile components of the project or optional C++ code.

When you first create a project, you can optionally include Starter Content to add some basic assets to your levels. Starter Content is only intended for early development; when you are ready to replace it with production-quality assets, you can either shop the Unreal Engine Marketplace, or import your own assets from other applications.

Once you have created your project, you can reload it when launching Unreal Editor either by selecting it on the launcher from the My Projects section or by creating a desktop shortcut with the target properties such as:

Platform

Path

Windows

[UE4Directory]\Engine\Binaries\Win64\UE4Editor.exe "[ProjectPath][ProjectName].uproject"

macOS

[UE4Directory]/Engine/Binaries/Mac/UE4Editor.app "[ProjectPath][ProjectName].uproject"

Working from a blank project may be intimidating at first if you are intending to build interactive functionality, but templates are still only starting points. Sometimes it is easier to have a complete example that you can learn from, and customize to your own requirements.

We offer a large range of example projects, accessible from the Learn tab on the Launcher, under Engine Feature Samples.



To use one of these samples, click the project to open a details page, click FREE, then click Create Project. After the project installs, you can open it from the Project Browser or the Library page.

Section 5: Learning

Whether you're just finding your feet, or looking to extend your knowledge to include advanced techniques, we have everything you need to learn.

Documentation

Our extensive Unreal Engine Documentation features quick-start guides, reference manuals, scripting and programming guides, release notes, and more.

From here, you can get started learning the basics of Unreal Editor.

Once you have a basic familiarity with the engine, you can search for information on specific topics on the docs site to learn more about specific topics.

For information about using Datasmith, check out the Datasmith documentation.

Learning videos

If you prefer to absorb information in video format, our Online Learning Platform offers a great range of on-demand video tutorials.

Once you've mastered the basics, you can filter the content by topics such as Architecture/Construction, Automotive, Game Development, and more, to find the learning path that's right for you.

Section 6: Support Resources

Unreal Developer Network

Unreal Engine custom licensees can access premium support through the Unreal Developer Network. This is an exclusive support website where you can ask questions, get answers from Epic Games staff, and learn from the interactions of other developers with our staff.

Although Epic provides many different support channels to accommodate our variety of users, we ask that you please log all of your questions, issues, and feedback to the UDN. This way we can ensure that we are are able to provide the assistance you require.

To learn more about how to make the best use of our support site and grant access to additional staff, take a look at the various knowledge base articles which have been prepared.

Community resources

While we recommend that you bring your specific questions or issues to UDN, you may also find it helpful to engage with our public community for discussions with other developers and to quickly search for known solutions. Visit the Unreal Engine Forums to engage in discussions with fellow developers.

Reaching out

Do you still have questions or issues? Get in touch, and we'll get you up and running as quickly as possible.

Contact your Business Development Manager for any questions about your license or to activate additional benefits.

Email us at developer-access@unrealengine.com for general questions about the account or onboarding help.

Root Directory

Common Directories

Engine-specific Directories

Game Project Directories

Solution Directories

At the top level, there is the Engine directory as well as any game projects you have. The Engine directory contains the engine itself and all of the tools that come with it. Each game folder contains all of the files pertaining to that game. There is a much greater separation between the engine and game projects in UE4 than in previous versions of the engine.

Root Directory

Engine - Contains all source code, content, etc. that makes up the engine.

Templates - Collection of project templates available when creating new projects.

GenerateProjectFiles.bat - Used to create the UE4 solution and project files necessary for working with the engine and your game(s) in Visual Studio. See Project Files for IDEs for details.

UE4Games.uprojectdirs - Helper file that allows the engine to discover projects in subdirectories.

Common Directories

Some subdirectories are common amongst both the Engine and game project directories:

Binaries - Contains executable files or other files created during compiling.

Build - Holds files needed for building the engine or game, including files necessary for creating platform-specific builds.

Config - Configuration files for setting values that control engine behavior. Values set in the game project Config files override the values set in the Engine\Config directory.

Content - Holds content for the engine or game, including asset packages and maps.

DerivedDataCache - Contains derived data files generated on-load for referenced content. Not having cache files present for referenced content can increase load times dramatically.

Intermediate - Contains temporary files generated during building the engine or game. In game directories, Shaders are stored in the Intermediate directory.

Saved - Contains autosaves, configuration (.ini) files, and log files. Additionally, the Engine > Saved directory contains crash logs, hardware information, and Swarm options and data.

Source - Contains all of the source files for engine or game, including the engine source code, tools, gameplay classes, etc.

Engine - Source files in the Engine directory are categorized into the following:

Developer - Files used by both the editor and engine.

Editor - Files used by just the editor.

Programs - External tools used by the engine or editor.

Runtime - Files used by just the engine.

Game - Source files in a game project directory are organized by module; one directory per module. Each module contains the following:

Classes - Contains all gameplay class header (.h) files.

Private - Contains all .cpp files including gameplay class implementation files and the module implementation file.

Public - Contains the module header file.

Engine-specific Directories

Some subdirectories are specific to the Engine directory.

Documentation - Contains the engine documentation, both source and published files.

HTML - Published HTML documentation files.

Source - Source markdown documentation files.

Extras - Additional helper and utility files.

Plugins - Contains plugins used in the engine.

Programs - Contains configuration files and log files for projects stored in the UE4 root directory and other Unreal programs such as UnrealFrontend and UnrealHeaderTool.

Shaders - Holds the shader source files (.usf) for the engine.

Game Project Directories

Directory

Description

Binaries

Contains executable files or other files created during compiling.

Config

Default project settings for your game.

Content

Contains content for the engine or game, including asset packages and maps.

External dependencies

Displays the public engine header files (only visible in Visual Studio).

Intermediate

Contains files that are generated by UnrealBuildTool such as Visual Studio project files. These files can be deleted and rebuilt.

Saved

Contains files that are generated by the engine such as config files and logs. These files can be deleted and rebuilt.

Source

Contains game module object class files.

Solution Directories

Directory

Description

Classes

Contains game object class definitions (.h files).

Config

Default project settings for your game.

External dependencies

Displays the public engine header files (only visible in Visual Studio).

Private

Contains private game object class implementation files (.cpp files).

Public

Contains public game object class implementation files (.cpp files).

Accessing the Content Browser

Content Drawer

Content Browser Topics

The Content Browser is the primary area of the Unreal Editor for creating, importing, organizing, viewing, and managing content Assets within your Unreal project. You can also use it to manage content folders and perform specific Asset operations, such as:

Browse to and interact with all of the Assets in your project.

Find Assets using a text filter, which you can optionally combine with more advanced filtering.

Organize Assets into private, local, or shared collections.

Identify Assets that might contain problems.

Migrate Assets between content folders or to a different project.

To learn more about each of these operations, refer to the Content Browser Topics section on this page.

Accessing the Content Browser

There are three ways to open the Content Browser:

From the Window menu in the top menu bar.



From the Create menu on the Main Toolbar.



By clicking the Content Drawer button on the bottom toolbar of the editor. This opens a temporary Content Browser you can then dock to the editor window. To learn more, refer to the Content Drawer section on this page.



You can open up to four instances of the Content Browser at the same time. This is useful, for example, if you want to:

Have different Asset types filtered in different Content Browsers, such as one that just shows Static Meshes and another that just shows Materials.

Move Assets between different folders in your project.

By default, the Content Browser docks along the bottom of the Unreal Editor window. You can click and drag to re-dock it anywhere within the editor, or float it as its own window. You can also right-click the Content Browser tab and select Move to Sidebar, which will collapse the Content Browser to a clickable tab in the left-hand sidebar of the Unreal Editor window.

Content Drawer

The Content Drawer is a special instance of the Content Browser with slightly different behavior. To open it, either:

Click the Content Drawer button on the bottom bar of the editor.

Use the Ctrl + Space Bar (Windows) or Cmd + Space Bar (macOS) keyboard shortcut.

The Content Drawer automatically minimizes when it loses focus (that is, when you click away from it). To keep it open, click the Dock in Layout button. This creates a new instance of the Content Browser, but you can still open a new Content Drawer.



The Dock in Layout button on the Content Drawer.

Content Browser Topics

To learn more about working in the Content Browser, refer to the pages below.



Describes the Content Browser interface and functionality.



Reference for working with the Sources panel inside the Content Browser



Adjust thumbnail display, Asset filtering, and other areas of the Content Browser.



Use filters and Collections to sort and group Assets within the Content Browser.



Reference for advanced search operators you can use in the Content Browser.

Navigation Bar

Sources Panel

Collections

Filters Column

Search Bar

Asset View

Settings Button

The Content Browser is divided into the following areas:



Number

Name

1

Navigation Bar

2

Sources Panel

3

Collections

4

Filters

5

Search Bar

6

Asset View

7

Settings Button

Navigation Bar

The Navigation Bar contains controls for working with Assets, navigating back and forward between folder paths, and shows a breadcrumb trail path for the folder that is currently open.



Number

Name

Description

1

Asset Control Buttons

These buttons have the following functionality:

Add: Click this button to add existing Assets to your project or create a new Asset.

Import: Click this button to open a file browser and select one or more Assets to add to your project.

Save All: Click this button to save all Assets that have unsaved changes.

To learn more about importing Assets to your project, refer to the Importing Assets Directly page.

2

History Back and Forward Buttons

These buttons function like the Back and Forward buttons in a web browser. Use them to navigate back and forward between recent file paths.

3

Breadcrumb Trail Path

This section shows the current folder path. Click any folder to quickly navigate to it.

Sources Panel

The Sources panel contains a list of all folders inside your Unreal Engine project.



Number

Name

Description

1

Favorites Panel

This panel contains references to Assets that you have added to your Favorites.

2

Project Name

This is the name of the project that is currently open. Click the arrow next to the project name to collapse or expand the folders list.

3

Search Buttons

Click this button to open the Search bar, which you can use to narrow down the list of available folders in the button's associated panel by entering search criteria. Folders are filtered down in real time to only those whose names include the characters you enter.

4

Asset Tree

This hierarchical list shows all folders in your Unreal Engine project. It behaves the same as the folder tree in Windows Explorer or the Finder in macOS. To expand or collapse a folder, click the arrow next to its name.

You can exclude folders from the Asset Tree by prefixing the search text with a hyphen (-). For example, entering -anim in the Search box hides any folder whose name contains that string, such as Animation or Animator.

For more information about the Sources panel, refer to the Sources Panel Reference page.

Collections

The Collections panel displays a list of all the Collections you have access to.



Number

Name

Description

1

Collapse / Expand Button

Click this button to collapse or expand the Collections area.

2

Add Collections Button

Click this button to create a new Collection.

3

Search Buttons

Click this button to open the Search bar, which you can use to narrow down the list of available Collections by entering search criteria. Collections are filtered down in real time to only those whose names include the characters you enter.

4

Collections List

An alphabetical list of all Collections in this project.

5

Asset Count

Shows the number of Assets in each Collection.

For more information on Collections and their use, refer to the Filters and Collections page.

Filters Column

The Filters column contains all built-in and custom filters for the user that is currently logged in. Click a filter to enable or disable it.



For more information on working with filters, refer to the Filters and Collections page.

Search Bar

The Search bar provides a wide range of functionality for quickly locating Assets based on their name and type. The Asset View, which displays the contents of the folder you select in the Sources panel, updates dynamically based on the parameters you enter here.



Number

Name

Description

1

Filters Button

Click this button to open the Filters menu, which you can use to customize the kinds of Assets that display in the Asset View.

For more information on working with filters, refer to the Filters and Collections page.

2

Search Bar

Use the Search bar to search for Assets by name. Assets are filtered down in real time to only those whose names include the characters you enter.

3

Save Search Button

Click this button to save your current search as a new filter or Collection. This is useful if you want to run the same search again in the future.

4

Previous Searches Button

Click this button to see a list of previous searches.

Asset View

The Asset View shows all available Assets within the currently selected folder or Collection.

From the Asset View, you can:

Drag and drop Assets directly into the Level.

Create and import Assets from the context menu that opens when you right-click inside the Asset View.

Create new folders.



Number

Name

Description

1

View Area

This shows all of the Assets in the currently selected folders or Collections after all filters and search criteria have been applied.

2

Asset Count

Shows the current number of assets displayed once all filters and searches are applied.

Settings Button



This button opens the Settings menu, where you can adjust the following settings for the Content Browser:

View style (how Assets are displayed: Tiles, Lists, or Columns).

Search filters.

Content to include or exclude.

Search options.

For more information, refer to the Content Browser Settings Reference page.

Enabling the Developers Folder

Collaborating with Other Developers

Excluding the Developers Folder from Cooked Builds

The Developers folder in the Content Browser is where you can duplicate and work on Assets without worrying about breaking things in your project. Use the Developers folder to experiment with different things, from small-scale Asset modification to project-wide refactors.

If you work in a shared project with other developers, each developer has their own folder.

The Developers folder uses the same name as your Windows username, but without characters that aren't allowed in Unreal Engine folder names, like periods or spaces.

Because the Developers folder is meant to act as a sandbox environment, you should never reference Assets from this folder anywhere outside this folder. Doing so can cause errors when cooking the project or cause cooking to fail.

Enabling the Developers Folder

If you don't see the Developers folder in your Content Browser, follow these steps to enable it:

In the Content Browser, click Settings.

From the Settings menu, enable the Show Developer Content option.



Click the image for full size.

Collaborating with Other Developers

If you use source control, you can configure Unreal Engine to see Assets in other developers' folders. To do this, follow these steps:



Click the image for full size.

In the Content Browser, click the Filters button.

From the Filters menu, select Other Filters > Other Developers.

Excluding the Developers Folder from Cooked Builds

If you want to make sure that you don't accidentally package broken or in-progress Assets, you can exclude the Developers folder from cooked builds.To do this, follow these steps:



Click the image for full size.

From the main menu, go to Edit > Project Settings and search for the Directories to never cook array.

You can find this array by using the Search box at the top of the section.

Click the Add (+) button to add a new item to the array.

Click … to open a list of folders in your project.

Click the Developers folder to select it.

Toggling the Sources Panel

Adding and Removing Sources

Source-Based Asset Display

Right-Click Context Menu

The Sources panel, located on the left side of the Content Browser, contains a list of all folders and Collections within your Unreal Engine project. You can customize it to include other types of Assets and Asset organization features, and use it to initiate some common editor operations.

When you select one or more folders, collections, or other types of Asset groups from the Sources panel, the Asset View panel will display the contents of your selection.



Toggling the Sources Panel

You can open and close the Sources panel from the Settings menu in the upper-right corner of the Content Browser, by enabling or disabling the Show Sources Panel option. Closing the Sources panel gives you more space to work with Assets in the Asset View.

Adding and Removing Sources

By default, the Sources panel displays two Asset sources to start:

A hierarchical list of all folders within your Unreal Engine project, grouped under the project name.

An alphabetical list of Asset Collections for the current project.

You can also add the following Asset sources:

Source

Contents

How to Add

Favorites

Assets that you've marked as Favorites by right-clicking them in the Asset View and selecting Add To Favorites from the context menu.

From the Settings menu, enable the Show Favorites option.

C++ Classes folder

Browseable hierarchy of all C++ classes in Unreal Engine.

From the Settings menu, enable the Show C++ Classes option.

Developers folder

Folder you can use to collaborate with other developers on multi-user projects.

From the Settings menu, enable the Show Developers Content option.

Engine Content folder

Collection of stock Assets with various contents and functionality.

From the Settings menu, enable the Show Engine Content option.

Plugin-specific content folders

Content folders added by various Unreal Engine plugins.

From the Settings menu, enable the Show Plugin Content option.

Localized content

Localized content in the L10N/ folder.

From the Settings menu, enable the Show Localized Content option.

Source-Based Asset Display

The Asset View shows Assets from the currently selected source. You can use searches and filters to further control which Assets display in the Asset View.

To see Assets from multiple folders, you must select all the folders you want to search. You can use the following mouse and key combinations to select multiple folders:

Left-click replaces your current selection with the folder you clicked.

Shift + Left-click selects a range of folders between a start and end point.

Ctrl + Left-click selects or deselects individual folders.

Right-Click Context Menu

If you right-click any of the folders within the Sources panel, the following context menu displays.

Option

Description

New Folder

Creates a new folder as a child of the currently selected folder.

Show in New Content Browser

Opens this folder in a new Content Browser window. You can have up to four instances of the Content Browser open at the same time, not including the Content Drawer.



Folder Options



Add/Import Content

This submenu offers the same functionality as the Add button on the Content Browser's Navigation Bar. Use it to import or create new Assets in the currently selected folder.

Show in Explorer (Windows) / Show in Finder (macOS)

Opens the folder in Windows Explorer (Windows) or Finder (macOS).

Rename

Makes the folder name editable so you can change it. Press Enter to save your change, or Escape to cancel the renaming.

Add to Favorites

Adds the folder to the Favorites section.

Set Color

Sets the color of the selected folder for organizational purposes.



Bulk Operations



Save All

Saves all Assets in the current Folder that have been modified.

Resave All

Resaves all Assets in the current Folder, whether they have been modified or not.

Delete

Deletes the current folder and all of its contents.

Fix Up Redirectors in Folder

Finds referencers to all redirectors in the selected folders and resaves them if possible, then deletes any redirectors that had all their referencers fixed.

Migrate

Copies Assets found in this folder, as well as their dependencies, to another project's Content folder. For more information, refer to the Migrating Assets page.

Reference Viewer

Shows a graph of references for the folder. For more information, refer to the Finding Asset References page.

Size Map

Show an interactive map of the approximate memory used by the Assets in this folder and everything they reference.

Audit Assets

Opens an Assets Audit window that displays detailed information about the Assets in the current folder. You can use filters to further refine the information that displays in this window.

Shader Cook Statistics

Display statistics related to shader cooking.

Validate Assets in Folder

Validate Assets contained within the folder and flag Assets that have issues.



Source Control



Connect to Source Control

Connects this folder to source control. After you have connected this folder to source control, the operations below become available.

Check Out

Marks the selected folder as checked out, which locks it from edits by other users.

Mark for Add

Marks the selected folder for addition onto the source control server.

Check In

Submits all edits and additions, and then unlocks the checked-out folder.

Sync

Syncs all Assets in this folder to the latest version.

This might override any local changes you have made.

Option

Description

Move Here

Moves the folder to the new location and removes it from its original location.

Copy Here

Creates a duplicate of the selected folder in the destination folder.

Advanced Copy Here

Creates a duplicate of the selected folder in the destination folder, along with its dependencies. Also fixes any dependencies that were broken as a result of the move.

View Type

Locking

View

Search

Content Browser Editor Preferences

The Settings button is located in the top-right corner of the Content Browser. Clicking it opens a menu where you can adjust various settings for the current instance of the Content Browser, such as:

View type (how Assets are displayed: Tiles, Lists, or Columns).

Search filters.

Content to include or exclude.

Search options.



View Type

These settings affect how Assets in the Asset View are displayed. You can choose one of the following View Types:

Tiles

The Tiles view lays out all Assets into a grid of tiles, like so:



List

The List view lays out all Assets into a list of thumbnails with names and file types, like so:



Columns

The Columns view lays out all Assets with a spreadsheet-like arrangement of properties, like so:



The details displayed change depending on the type of Asset. For example, Blueprint Assets display their Type and Parent Class, and Static Meshes display their vertices and triangles counts.

You can perform the following operations on each column:

Sort the Assets by the column's value in ascending or descending order by left-clicking the column name.

Hide a column by hovering over its name, then clicking the vertical ellipsis menu and selecting Hide Column.

Unhide columns from the Settings menu by selecting the Toggle Columns option and enabling the columns you want to display.

You can also export all of the Asset details as a .csv file. From the Settings menu, select the Export to CSV option. Note that this option only displays if the Asset Viewer is currently using the Columns view.

Locking

The Lock Content Browser option is a toggleable setting. If enabled, this instance of the Content Browser will ignore Find in Content Browser requests.

View

Use the View settings to toggle what displays in the Content Browser, as well as filtering behavior.

Option

Description

Show Folders

Disable this option to have the Content Browser show all Assets in the project in a single view.

Disable the Show Empty Folders sub-option to have the Content Browser show only folders that contain at least one Asset.

Show Empty Folders

Disable this option to have the Content Browser hide empty folders.

Show Favorites

Enabling this option adds a new Favorites category at the top of the Sources panel. This category displays if you have added at least one folder or Asset to your Favorites.

To add a folder or Asset to your Favorites, right-click it, then select Add To Favorites from the context menu.

Filter Recursively

Toggle this option to control whether Asset View filters should apply recursively.

Show All Folder

Toggles the visibility of the All folder in the Sources Panel folder hierarchy. If disabled, the folder hierarchy will move one level up.

Organize Folders

Enable this option to organize folders automatically in the Content Browser's Asset view.

Path View Filters

Toggles options that affect the Path View in the Content Browser. This option is useful when working with large-scale projects that use content from multiple sources.

Show Sources Panel

Toggle this option to show or hide the Sources panel.

Content

Toggle the following options to control whether or not certain types of Assets display in the Asset View.

Option

Description

Show C++ Classes

If enabled, shows the Engine C++ Classes folder in the Sources panel. This folder contains a browseable hierarchy of all C++ classes in Unreal Engine.

Show Developers Content

If enabled, shows the Developers folder in the Sources panel. This folder is used to collaborate with other developers on multi-user projects.

Show Engine Content

If enabled, shows the Engine Content folder in the Sources panel. This folder contains a collection of Unreal Engine stock Assets with various contents and functionality.

Show Plugin Content

If enabled, plugin-specific content will display in the Content Browser.

Show Localized Content

If enabled, localized content will display in the Content Browser.

Search

Use the Search options to control what gets included or excluded from searches performed within the Content Browser:

Asset class names

Asset paths

Collection names

Thumbnails

Use the Thumbnail options to control how thumbnails are generated and displayed.

Option

Description

Thumbnail Size

Choose from one of the five possible sizes for thumbnails that display in the Asset View:

Tiny

Small

Medium

Large

Huge

Thumbnail Edit Mode

If enabled, you can adjust the thumbnails of 3D Assets by left-clicking and dragging inside the thumbnail. When you are finished, click the Done Editing button to save your changes. To revert your changes, click the Undo button in the top-right corner of the thumbnail.



You must save your Asset to save the changes you made to its thumbnail.

Real-Time Thumbnails

If enabled, Asset thumbnails are rendered in real time.

Content Browser Editor Preferences

You can adjust further settings that affect the Content Browser from the Editor Preferences (menu: Edit > Editor Preferences, then select the Content Browser section).

Setting

Description

Assets to Load at Once Before Warning

The number of Assets that can be loaded simultaneously in the Content Browser before Unreal Engine shows a warning.

Open Sources Panel by Default

If enabled, the Content Browser will open the Sources Panel by default.

Number of Assets to Keep in the Recently Opened Filter

The number of Assets that will be displayed by the Recently Opened filter in the Asset View.

Enable Realtime Material Instance Thumbnails

If enabled, Material instance thumbnails will be rendered in real time.

Asset Filters

Enabling Filters

Disabling Filters

Deleting Custom Filters

Bulk Filter Operations

Using the Recently Opened Filter

Collections

Creating Collections

Adding Assets to Collections

Removing Assets from Collections

Renaming and Deleting Collections

Filters and Collections are two different ways to sort and group Assets inside the Content Browser. There are a few key differences between them:

Filters automatically show or hide Assets in the Asset View. You can have multiple filters active at the same time, and toggle them on or off individually. Filters are saved locally and shared across projects.

Collections contain manually added references to Assets. You can only view the contents of one collection at a time in the Asset View. Collections can be local to your machine, or you can share them with other users.

Filters and Collections apply to individual Content Browsers. This means that you can have different Content Browsers displaying different types of Assets - for example, one Content Browser could display only Static Meshes belonging to a specific Collection, and another could display the 20 most recently opened Assets.

Asset Filters

Filters provide a way to narrow down the Assets visible within the Asset View of the Content Browser. Filters can be based on either:

Asset type, such as Blueprints, Materials, Static Meshes, and so on.

Asset state, such as whether an Asset is currently checked out of source control.

Unlike Collections, you can have multiple filters active at the same time.

Enabling Filters

To enable a filter, you must first add it to the Filters area of the Content Browser. To do this, from the Content Browser's Search bar, click the Filters drop-down (highlighted in the screenshot below). This opens a menu which shows all available filters you can select from, divided into specific categories.



Click a filter to add it to the Filters area. You can also add all filters under a category by clicking the category itself. The checkbox next to a filter category shows whether any filters in that category are enabled:

A plus sign (+) means all filters in that category are enabled.

A minus sign (-) means only some filters in that category are enabled.

An empty checkbox means no filters in that category are enabled.

Filters are additive, which means that any new filters you add will increase the number of possible Assets that display in the Asset View. For example, if you start by selecting the Static Mesh filter, you will only see Static Meshes. If you then select the Blueprint filter, you will see Static Meshes and Blueprints.

You can also create custom filters from the drop-down menu. Go to Custom Filter > Create New Filter, then enter the following information in the window that appears:



Filter Label: Give your filter a name. Filter names must be unique.

Color: Use the color wheel to select the color that this filter will use in the Filters area of the Content Browser.

Filter String: Enter the criteria for the Assets shown by this filter. You can use advanced search operators.

Disabling Filters

There are two ways to disable filters:

Click the filter in the Filters area to toggle it on and off. Deactivated filters are grayed out and have no effect. To turn a filter back on, click it again. Disabling a filter in this manner does not remove it in the Filters area.

From the Filters drop-down, navigate to an enabled filter and click its name to disable it. This action also removes the filter from the Filters area.



In this example, the Level and Material filters are enabled, and the AnimBP and devAssets filters are disabled.

Deleting Custom Filters

Deleting a custom filter using this workflow does not have a confirmation dialog and cannot be undone.

To delete a custom filter, follow these steps:

From the Filters drop-down, go to Custom Filters.

Click the Edit button ( ) next to the filter you want to delete.

In the window that opens, click the Delete button.

Bulk Filter Operations

Right-clicking a filter in the Filters area opens a context menu with the following available operations:

Operation

Description

Remove: [Filter Name]

Removes this filter from the Filters area. If it is a custom filter, it will not be deleted and you can re-add it from the Filters drop-down.

Enable Only This: [Filter Name]

Disables all other filters except for the currently selected one.

Enable All Filters

Enables all filters.

Disable All Filters

Disables all filters. Note that this doesn't remove any filters from the Search and Filters bar.

Remove All Filters

Removes all filters from the Search and Filters bar.

This operation cannot be undone.

Remove All But This: [Filter Name]

Removes all filters except for the currently selected one from the Search and Filters bar.

This operation cannot be undone.

Using the Recently Opened Filter

Use the Recently Opened filter to view the 20 most recently opened Assets for a selected folder. You can find this filter in the Filters drop-down, under the Other Filters category.

When using the Recently Opened filter, selecting the Content folder will display the most recently opened Assets for the entire project folder. Selecting a sub-folder might show only a few items, or nothing at all. The list is dependent on the most recently opened Assets being contained within the folder being selected.

Note that this filter can return fewer than 20 items, or even no items, if you're working in a brand new project.



In this example, the Recently Open filter only shows 8 items, because these are the only items that were opened since the project was created.

You can change the number of Assets listed by the Recently Opened filter. In Editor Preferences, under Content Browser, change the Number of Assets to Keep in the Recently Opened Filter.

Collections

Collections serve as a way to organize sets of Assets into groups. Unlike folders, Collections don't contain the Assets themselves, but only references to those Assets. In practice, this means that one Asset can belong to more than one Collection.

Collections display in the Sources panel, under the folder tree.

Creating Collections

To create a new Collection, follow these steps:

Click the Add (+) button on the Collections panel.



Select the Collection type.



You can choose from one of the following options:

Type

Description

Shared Collection

Shared Collections are visible to other users. This option is only available if you're working in a multi-user project.

Private Collection

Private Collections are available only to the users who have been specifically invited to view the Collection. This option is only available if you're working in a multi-user project.

Local Collection

Local Collections are only available on your local machine.

Enter a name for your new Collection, then press Enter.

You can create child Collections by right-clicking a Collection, then selecting New from the context menu that appears and following steps 1-3 outlined above.

Adding Assets to Collections

You can add one or more Assets to a Collection by using one of the following methods:

Click the Asset to select it, then drag it into a Collection.

Right-click the Asset. Then, from the context menu, select Manage Collections, and click the Collection you want to add the Asset to.

Collections the Asset already belongs to will have a check mark next to their name.

Click the Asset to select it, then enable the check mark next to the Collection you want to add the Asset to.

If the Asset is already a part of that Collection, the check mark next to the Collection will already be enabled. In this case, clearing the check mark will remove the Asset from that Collection.

If you add an Asset to a Collection that has a parent Collection, the Asset will also be added to the parent Collection.

Removing Assets from Collections

You can remove Assets from a Collection by using one of the following methods:

Right-click the Asset. Then, from the context menu, select Manage Collections, and click the Collection you want to remove the Asset from.

Collections the Asset already belongs to will have a check mark next to their name.

Click the Asset to select it, then disable the check mark next to the Collection you want to remove the Asset from.

If you select an Asset in a Collection and press Delete, you can delete the Asset entirely. You will get a prompt verifying that this is what you want to do, but keep in mind that deleting an Asset means it is completely removed from your project. To simply remove an Asset from a Collection, always use one of the methods described above.

Renaming and Deleting Collections

To rename a Collection, right-click it and select Rename from the context menu. Then, enter a new name and press Enter. To cancel the rename, press Escape.

To delete a Collection, right-click it and select Delete from the context menu, then click Delete on the confirmation window that appears. Note that, since Collections are references to the actual Assets, deleting your Collections will not delete the Assets within the Collection.

Special Keys

Strings

Asset Metadata

You can search for your content in the Content Browser using advanced search operators. These operators can refine your search, making it easier for you to find what you need. You can also use them to search for key-value pairs from Asset metadata, and access special key values.



An example of using an advanced search operator in the Content Browser Search box.

The following table shows all the available operators:

Operator (Type)

Syntax

Description

Example

Equal (Binary)

= == :

Tests whether the value returned for a given key is equal to the specified vaDlue.

Name="Blast" Name==Blast Name:Bla...

NotEqual (Binary)

!= !:

Tests whether the value returned for a given key is not equal to the specified value.

Name!=Blast Name!:"Blast"

Less (Binary)

<

Tests whether the value returned for a given key is less than the specified value. This supports numeric values only.

Triangles<92

LessOrEqual (Binary)

<= <:

Tests whether the value returned for a given key is less than or equal to the specified value. This supports numeric values only.

Triangles<=92 Triangles<:92

Greater (Binary)

>

Tests whether the value returned for a given key is greater than the specified value. This supports numeric values only.

Triangles>92

GreaterOrEqual (Binary)

>= >:

Tests whether the value returned for a given key is greater than or equal to the specified value. This supports numeric values only.

Triangles>=92 Triangles>:92

Or (Binary)

OR || |

Tests two values and returns true if either evaluate to true.

Blast OR Type:Blueprint !Blast || Path:Testing Name:"Blast" | Path:Testing...

And (Binary)

AND && &

Tests two values and returns true if both evaluate to true.

Blast AND Type:Blueprint !Blast || Path:Testing Name:"Blast" | Path:Testing...

Not (Pre-Unary)

NOT !

Tests the value that follows it and then returns the inverted results.

NOT Blast ! "Blast"

TextCmpInvert (Pre-Unary)

-

Modifies a text value so that it will return the inverted result of the operation it is involved in.

-Blast -"Blast"

TextCmpExact (Pre-Unary)

+

Modifies a text value so that it will perform an "exact" text comparison.

+Blast +"Blast"

TextCmpAnchor (Pre-Unary)

...

Modifies a text value so that it will perform an "ends with" text comparison.

...ast ..."ast"

TextCmpAnchor (Post-Unary)

...

Modifies a text value so that it will perform a "starts with" text comparison.

Bla... "Bla"...

Special Keys

Most keys available for searching come from Asset metadata that was extracted from the Asset registry. However, there are several special keys that exist for all Asset types. These special keys only support Equal or NotEqual comparison operators.

Key

Alias

Description

Name

N/A

The Asset name.

Path

N/A

The Asset path.

Class

Type

The Asset class.

Collection

Tag

The names of any collections that contain the Asset.

Strings

Strings can either be quoted (single or double) or not quoted. Quoted strings can contain nested quotes; however, you must use a backslash ( \ ) to exit any nested quotes. The main difference between using unquoted and quoted strings is that quoted strings can use spaces and special characters in search terms. By default, they will perform partial string matches unless a TextCmpExact or TextCmpAnchor operator is used to modify the behavior.

Below are some examples using single and double quotes and backslashes:

A literal backslash ( \ ) must be used to escape using another backslash.

Asset Metadata

Hovering over an Asset's name in the Content Browser will display its metadata.



Example metadata for a Texture Asset.

Different Assets may list different metadata specific to that type, so Static Meshes would be different than a Skeletal Mesh.

You can use any type of metadata to search for Assets with that characteristic. Your search should use the following syntax:

[Metadata Name] [Operator] [String or Numeric Value]

For example:

Triangles>=10500

Type==Skeletal

UVChannels>2

CollisionPrims!=0

Metadata is not case-sensitive, but it does require no spacing between characters. For example, if you want to search for Morph Target, you should use MorphTarget.

Basic Search Example

A basic search takes a metadata object and uses an Operator to test against a string or value.

For example:

To search for any Asset that has more than 1500 triangles, you would use Triangles>1500.

To search for all Blueprint Assets, you would use Type==Blueprint.

Advanced Search Examples

By using the AND, OR, and NOT operators, you can test against multiple search operations at once. For example, to search for any Asset that is using a Translucent Material that is using the Default Lit Shading Model, you would use the following syntax:

By using the AND operator, both operations testing the Blend Mode and Shading Model must evaluate to true to display any results.

When you use the OR operator, either operation can independently evaluate to true to display its result. For example,not every Material using a Translucent Blend Mode will be using Default Lit. For complex advanced searches, Operators of the same type always combine together. Parentheses can resolve the ambiguity when you start using different operator types. For example, we can perform two searches and then evaluate them to display results. The first operation will evaluate any Material that is Translucent and Default Lit:

The second operation will evaluate any Material that is a Deferred Decal and that doesn't use Scene Color:

You can use parentheses to evaluate the results of both of these searches, like so:

By using the OR operator between the parentheticals, the results will evaluate each parenthetical on its own and display results that return true for either one. If you were to use the AND operator, all four operations would have to return True to display any results.

Plugins

Enabling a Plugin

Disabling a Plugin

Installing Plugins from the Unreal Engine Marketplace

Plugin Installation Locations

A plugin is an optional software component that adds specific functionality to Unreal Engine. Plugins can add entirely new features and modify built-in functionality without modifying the Unreal Engine code directly. For example, a plugin might add new menu items and toolbar commands to the editor, or even add entirely new features and editor sub-modes.

You can enable or disable plugins independently for each project, depending on your needs.

There are two types of plugins available in Unreal Engine:

Unreal Engine plugins.

Third-party plugins.

Enabling a Plugin

To enable an Unreal Engine plugin, follow these steps:

From the main menu, go to Edit > Plugins. This opens the Plugins window.



Plugins window in Unreal Engine 5.

Find the plugin you want to enable using the list on the left of the screen. Alternatively, enter a term in the Search box to search for all plugin names and descriptions that contain this term.



This example shows all search results for the term "xr". Note that the search term is highlighted everywhere it appears.

To enable a plugin, click the checkbox next to it.



Enabling a plugin

For plugins that are not production-ready, such as beta plugins, you might see a warning asking you to confirm that you want to enable that plugin.

Save your work, then restart Unreal Engine.

Third-party plugins might require additional steps before you can enable them. For more information, refer to the documentation for the third-party plugin you want to install. Note that Epic Games is not responsible for the contents of third-party plugins.

Disabling a Plugin

To disable a plugin, follow these steps:

From the main menu, go to Edit > Plugins. This opens the Plugins window.



Plugins window in Unreal Engine 5.

Find the plugin you want to disable using the list on the left of the screen. Alternatively, enter a term in the Search box to search for all plugin names and descriptions that contain this term.



This example shows all search results for the term "xr". Note that the search term is highlighted everywhere it appears.

To disable a plugin, clear the checkbox next to it.



Disabling a plugin

If the plugin you want to disable is a dependency for other plugins (that is, other plugins require it to function), you will see a notification asking you if you want to disable those plugins as well. Note that this might break existing functionality in your project if you used any of those plugins to implement it.

Save your work, then restart Unreal Engine.

Installing Plugins from the Unreal Engine Marketplace

While Unreal Engine contains plugins that offer many different kinds of functionality, you can also install additional plugins from the Unreal Engine Marketplace.

To install a plugin using this method, follow the steps below. These steps use the free glTF Exporter plugin by Epic Games as an example.

In the Epic Games Launcher, navigate to the Unreal Engine tab, then go to Marketplace.



Search for the plugin you want to install.



On the plugin's tile, click Add to Cart.



Click the Cart button and check out.



For free plugins, you don't need to perform any additional steps at this stage. For paid plugins, you must complete the payment process before you can use them.

After you check out, the plugin's tile will display the word OWNED.

Go to the plugin's page in the Launcher. You can do this by searching for the plugin, then clicking the plugin's tile. Then, on the plugin's tile, click Install to Engine.



Select the engine version you want to install the plugin to, then click Install.



This dropdown menu only shows the Unreal Engine versions that the plugin supports, even if you have other Unreal Engine versions installed.

After the installation completes, open the version of Unreal Engine you installed the plugin for, and enable the plugin following the instructions in the Enabling a Plugin section on this page.

Plugin Installation Locations

Unreal Engine stores all plugins at the following locations:

C:\Program Files\Epic Games\UE_[version]\Engine\Plugins on Windows

/Users/Shared/Epic Games/UE_[version]/Engine/Plugins on macOS

Creating a New Keyboard Shortcut

Removing an Existing Keyboard Shortcut

Importing and Exporting Keyboard Shortcuts

Keyboard shortcuts, also known as keybinds, are combinations of key presses on your keyboard that execute specific commands or actions. You can configure the shortcuts for common commands, as well as some tool-specific commands, to suit your workflow and personal preferences. To do this, open the Editor Preferences window: from the main menu, go to Edit > Editor Preferences, then select the Keyboard Shortcuts section.



The Keyboard Shortcuts editor in the Editor Preferences window.

Commands are grouped by functional area. Each command can have up to two keyboard shortcuts associated with it.

Creating a New Keyboard Shortcut

Click inside the text field for the command you want to bind to a keyboard shortcut.

Press the combination of keys you want to use to execute the command.



Unreal Engine will automatically save the new shortcut when you click anywhere outside the text field.

If the combination of keys you pressed is already bound to another command, you will see a warning.



If you want to remove the existing binding and assign the keyboard shortcut to the new command, click the Override button. If you want to keep the existing binding and cancel the new one, click anywhere outside the text field.

Removing an Existing Keyboard Shortcut

To remove an existing keyboard shortcut, click the Delete (X) button next to it.



Importing and Exporting Keyboard Shortcuts

You can migrate your custom keybinds between different installations of Unreal Engine by exporting them as an .ini file that you can then import into another UE installation. This is useful, for example, if you work on different computers, or if you rebuild or reinstall Unreal Engine often.

To save your custom keybinds as an .ini file, click the Export button. To import a set of custom keybinds from an .ini file, click the Import button. Both of these buttons are located at the top of the Keyboard Shortcuts editor.



Location of the Export and Import buttons.



Level Editor Preferences - Viewports

Controls

Viewport Look and Feel

Editor Look and Feel

Level Editing

Source Control

Particles

Content Browser

Privacy

Disable Bug Reports

Disable Usage Data

Auto Save

The Editor Preferences window is used to modify settings that control the behavior of Unreal Editor with respect to controls, viewports, source control, auto-saving, and more.

To open the Editor Preferences window, click Edit > Editor Preferences.



Level Editor Preferences - Viewports

Controls

Option

Description

Flight Camera Control type

This setting determines whether the flight camera is used and how it is accessed. The flight camera uses the W, A, S, and D keys to dolly and pan the camera, similar to how standard FPS controls work. W and S dolly the camera in and out, while A and D pan, or strafe, the camera side to side. When active, this overrides any hotkeys using these controls, including toggling show flags.

Option

Description

Use WASD for Camera Controls

The flight camera and WASD controls are always active.

Use WASD Only When Right Mouse Button is Held

The flight camera and WASD controls are only active when the RMB is pressed.

Never Use WASD for Camera Controls

The flight camera and WASD controls are never active.



Grab and Drag to Move Orthographic Cameras

If enabled, clicking the Left or Right Mouse Buttons and dragging the mouse in an orthographic viewport will scroll the camera. Essentially what this means in practice is when you click and drag, the scene will move with the mouse. With this disabled, the scene moves opposite of the mouse.

Orthographic Zoom to Cursor Position

If enabled, zooming in the orthographic viewports will be centered around the mouse cursor. When disabled, zooming is centered on the center of the viewport.

Link Orthographic Viewport Movement

If enabled, all orthographic viewports will be linked to focus on the same position. So moving the camera in one orthographic viewport will cause the other orthographic viewports to follow. When disabled, all viewports can be navigated independently.

Aspect Ratio Axis Constraint

Determines which axis of the perspective viewport is used to control the field of view (FOV) to maintain the aspect ratio when resizing.

Option

Description

Maintain Y-Axis FOV

The Y-Axis (vertical) is used to determine the FOV.

Maintain X-Axis FOV

The X-Axis (horizontal) is used to determine the FOV.

Maintain Major Axis FOV

The larger of the two axes is used to determine the FOV.



Mouse Scroll Camera Speed

Determines the speed at which the perspective camera moves when navigating with the mouse.

Viewport Look and Feel

Option

Description

Highlight Objects Under Mouse Cursor

If enabled, objects will be highlighted using a transparent overlay in viewports while hovering over them with the mouse cursor.

Editor Look and Feel

Option

Description

Use Small Tool Bar Icons

If enabled, toolbar icons across the whole editor will be smaller and without labels.





Normal

Small



Level Editing

Option

Description

Enable Combined Translate/Rotate Widget

If enabled, the combined Translation and Rotate-Z tool is made available.



Clicking BSP Enables Brush

If enabled, clicking on a Brush surface selects the brush and Ctrl + Shift + Click selects the surface. When disabled, the opposite is true; clicking selects the surface and Ctrl + Shift + Click selects the brush.

Update BSP Automatically

If enabled, Brush geometry rebuilds automatically when brushes are moved or modified in the viewport. When disabled, geometry must be rebuilt to see the changes.

Preserve Actor Scale on Replace

If enabled, replacing Actors will respect the scale of the original Actor. Otherwise, the replaced Actors will have a scale of 1.0.

Source Control

Option

Description

Prompt for Checkout on Package Modification

If enabled, the editor will automatically prompt for SCC checkout on package modification.

Allow Source Control

If enabled, the editor source control integration for packages and maps is used.

Add New Files when Modified

If enabled, new files are automatically added to source control.

Host

The host and port for your source control server. Example: hostname:1234

Username

The user name to sue when connecting to source control.

Workspace

The clientspec for source control.

Particles

Option

Description

Use Curves for Distributions

If enabled, Distributions will use the curves in place of the baked lookup tables when being rendered in the editor.

Content Browser

Option

Description

Auto Reimport Textures

If enabled, source files for textures are monitored and textures are automatically re-imported when the source file is modified.

Assets to Load at Once before Warning

The number of objects to load at once in the Content Browser before displaying a warning about loading many assets.

Privacy

The Editor in Unreal Engine 4 (UE4) collects usage data to help Epic continually improve UE4. There are three types of data that the Editor can collect:

Crash reports - generated when an error causes the Engine to crash.

Bug reports (also known as ensures) - generated when an issue causes the project to reach a certain unforeseen state, but does not cause a crash.

Usage data (also known as analytics) - a collection of data about the user.

When the Engine crashes, a crash report is generated. Crash reports automatically offer you a choice of whether or not to send crash data to Epic.

For bug reports, you can disable data collection in the Privacy category of Editor Preferences. Follow these steps to disable bug reports.

In the menu bar, click Edit > Editor Preferences.



In the Editor Preferences dialog, scroll down to the Privacy category.



Click Bug Reports. In the right pane, under Options, the default setting is Send unattended bug reports.



If you do not want bug reports sent to Epic, click Don't Send.



Usage data primarily consists of aggregated or anonymized information that does not directly identify you as an individual user. However, this usage data may also include the following:

User's IP address

User's Internet Service Provider (ISP)

User's Continent, Country and City

User's Epic Account ID

User's project name

If you are concerned about privacy and want to opt out of usage data collection, you can change the setting in the Privacy category of Editor Preferences. Follow these steps to disable usage data collection.

In the Editor Preferences dialog, scroll down to the Privacy category.



Click Usage Data. In the right pane, under Options, the default setting is Send Usage Data.



If you do not want usage data sent to Epic, click Don't Send.



To learn more about Epic's general privacy practices, see Epic's Privacy Policy.

Auto Save

Option

Description

Enable AutoSave

If enabled, the editor will automatically perform a save operation at specified intervals.

Save Maps

If enabled, the auto-save procedure will attempt to save modified, loaded maps.

Save Packages

If enabled, the auto-save procedure will attempt to save modified content packages.

Frequency in Minutes

The time interval in minutes to wait between auto-saves.

Warning in Seconds

The number of seconds the warning is displayed before an auto-save is performed.



The Project Settings window provides access to configuration options that affect:

Your Unreal Engine project.

How the engine behaves when running your project.

How the project should run on specific platforms.

Some plugins also append their configuration options to the Project Settings window.

All of the settings in this window are stored in your project's default engine configuration file (Engine.ini). The Project Settings window simply provides an intuitive user interface for editing these. You can also manually edit the Engine.ini file to change individual settings.

Accessing Project Settings

To open the Project Settings window, from Unreal Engine's main menu, go to Edit > Project Settings.



Selecting Project Settings in Edit menu



Categories and Sections

The Project Settings window is divided up into various categories and sections of related options. Categories are displayed as headings, while each of these sections is displayed as a hyperlink that opens the options for that section in the right panel.

You can export the settings into a backup file on your computer or import settings from the file by clicking Export or Import in the upper-right corner of the Project Settings window.

The editor .ini file is updated every time you change something in the Project Settings, and the values in it apply to all platforms. The editor .ini file is in <ProjectDirectory>\Config\DefaultEngine.ini.

Platform .ini files have to be edited manually in a text editor and only apply to a specific platform. An example of a platform .ini file is <ProjectDirectory>\Config\Windows\WindowsEngine.ini

The Project Settings window contains the following sections and categories:



Reference for the Project section of the Unreal Engine Project Settings.



Reference for the Game section of the Unreal Engine Project Settings.

This section is a work in progress and will eventually cover all Unreal Engine project settings.

Description

About

Publisher

Legal

Displayed

Settings

Encryption

Encryption

Signing

Gameplay Tags

Gameplay Tags

Advanced Replication

Advanced Gameplay Tags

Maps & Modes

Default Modes

Default Maps

Local Multiplayer

Game Instance

Movies

Movies

Packaging

Packaging

Project

Prerequisites

Supported Platforms

Target Hardware

Target Hardware

Pending Changes

Description

This is where you set information about your project, such as the project name, version, company name, copyright, and so on. These settings are mainly for informational purposes and will not affect how the project runs or behaves.

About

Section

Description

Description

The project description text.

Project ID

The project's unique identifier.

Project Name

The project's non-localized name.

Project Version

The project's version number.

Project Thumbnail

The project's preview thumbnail.

Publisher

Section

Description

Company Name

The name of the company (author, provider) that created the project.

Company Distinguished Name

The Distinguished Name of the company (author, provider) that created the project, which is used by publishing tools on some platforms.

Homepage

The project's homepage URL.

Support Contact

The project's support contact information.

Legal

Section

Description

Copyright Notice

The project's copyright and / or trademark notices.

Licensing Terms

The project's licensing terms.

Privacy Policy

The project's privacy policy.

Displayed

Section

Description

Project Displayed Title

The project's title as displayed on the window title bar. Can include the tokens {GameName}, {PlatformArchitecture}, {BuildConfiguration}, or {RHIName}, which will be replaced with the specified text.

Project Debug Title Info

Additional data to be displayed on the window title bar in non-shipping (debug) configurations. Can include the tokens {GameName}, {PlatformArchitecture}, {BuildConfiguration}, or {RHIName}, which will be replaced with the specified text.

Settings

Section

Description

Should Window Preserve Aspect Ratio

Specifies whether the game's window should preserve its aspect ratio when resized by the user.

Use Borderless Window

Specifies whether the game should use a borderless Slate window instead of a window with system title bar and border.

Start in VR

Specifies whether the game should attempt to start in VR, regardless of whether -vr was set in the command line.

Allow Window Resize

Specifies whether the user should be allowed to resize the game window, when not using full screen.

Allow Close

Specifies whether a Close button should be shown for the game window, when not using full screen.

Allow Maximize

Specifies whether a Maximize button should be shown for the game's window, when not using full screen.

Allow Minimize

Specifies whether a Minimize button should be shown for the game's window, when not using full screen.

Encryption

Encryption

Section

Description

Encryption Key

The default encryption key used to protect .pak files.

Secondary Encryption Keys

Secondary encryption keys that can be selected for use on different assets.

Games are required to make these keys available to the .pak platform file at runtime in order to access the data they protect.

Encrypt Pak Ini Files

Encrypts all .ini files in the .pak.

Gives security to the most common sources of mineable information, with minimal runtime IO cost.

Encrypt Pak Index

Encrypts the .pak index, making it impossible to use UnrealPak to manipulate the .pak file without the encryption key.

Encrypt UAsset Files

Encrypts .uasset files.

Encrypt All Asset Files

Encrypts all files in the .pak file.

Secure, but will cause some slowdown to runtime IO performance, and high entropy to packaged data which will be bad for patching.

Generate New Encryption Key

Generates a new encryption key.

Signing

Section

Description

Signing Public Exponent

The RSA key public exponent used for signing a .pak file.

Signing Modulus

The RSA key modulus used for signing a .pak file.

Signing Private Exponent

The RSA key private exponent used for signing a .pak file.

Enable Pak Signing

Enable signing of .pak files to prevent tampering of the data.

Generate New Signing Keys

Generate a new signing key.

Gameplay Tags

Gameplay Tags

Section

Description

Import Tags from Config

If true, will import tags from .ini files in the Config/Tags folder.

Warn on Invalid Tags

If true, will give load warnings when reading in saved tag references that are not in the dictionary.

Clear Invalid Tags

If true, will clear any invalid tags when reading in saved tag references that are not in the dictionary.

Invalid Tag Characters

These characters cannot be used in gameplay tags, in addition to special ones like newline.

Category Remapping

This allows base engine tag category metadata to remap to multiple project-specific categories.

Gameplay Tag Table List

List of data tables to load tags from.

Gameplay Tag Redirects

List of active tag redirects.

Gameplay Tag List

List of active tag redirects.

Advanced Replication

Section

Description

Fast Replication

If true, will replicate gameplay tags by index instead of name.

For this to work, tags must be identical on client and server.

Commonly Replicated Tags

List of most frequently replicated tags.

Num Bits for Container Size

Numbers of bits to use for replicating container size. Set this based on how large your containers tend to be.

Net Index First Bit Segment

The length in bits of the first segment when net serializing tags.

We serialize NetIndexFirstBitSegment + 1 bit to indicate "more", which is slower to replicate.

Advanced Gameplay Tags

Section

Description

Restricted Config Files

A list of .ini files used to store restricted gameplay tags.

Restricted Tag List

Restricted tags are intended to be top-level tags that are important for your data hierarchy and modified by very few people.

Maps & Modes

Default Modes

Section

Description

Default GameMode

GameMode to use if not specified in any other way (for example, per-map DefaultGameMode or in the URL).

You can choose any GameMode class in your project.

Default Pawn Class

The default pawn class used by players.

You can choose any pawn class in your project.

HUD Class

HUD class this game uses.

You can choose any HUD class in your project.

Player Controller Class

The class of PlayerController to spawn for players logging in.

You can choose any PlayerController class in your project.

Game State Class

The class of GameState associated with this GameMode.

You can choose any GameState class in your project.

Player State Class

A PlayerState of this class will be associated with every player to replicate relevant player information to all clients.

Spectator Class

The pawn class used by the PlayerController for players when spectating.

Global Default Server Game Mode

GameMode to use if not specified in any other way (for example, per-map DefaultGameMode or in the URL).

This setting is only used when running the engine as a dedicated server.

You can choose any GameMode class in your project.

If not set, the GlobalDefaultGameMode value will be used.

Game Mode Map Prefixes

Overrides the GameMode to use when loading a map that starts with a specific prefix.

Game Mode Class Aliases

List of GameModes to load when the game is specified in the URL (for example, DM could be an alias for MyProject.MyGameModeMP_DM).

Default Maps

Section

Description

Editor Startup Map

If set, this map will be loaded when the Editor starts up.

You can choose any map available in your project.

Editor Template Map Overrides

Map templates that should show up in the new level dialog.

This will completely override the default maps chosen by the default editor.

Game Default Map

The map that will be loaded by default when no other map is loaded.

You can choose any map available in your project.

Local Map Options

The default options that will be appended to a map being loaded.

Transition Map

The map that is loaded when transitioning from one map to another.

You can choose any map available in your project.

Server Default Map

The map that will be loaded by default when no other map is loaded.

This setting is only used when running the engine as a dedicated server.

You can choose any map available in your project.

Local Multiplayer

Section

Description

Use Splitscreen

Specifies whether the screen should be split or not when multiple local players are present.

Two Player Splitscreen Layout

The viewport layout to use if the screen should be split and there are two local players.

You can choose from the following options:

Horizontal

Vertical

Three Player Splitscreen Layout

The viewport layout to use if the screen should be split and there are three local players.

You can choose from the following options:

Favor Top

Favor Bottom

Horizontal

Vertical

Four Player Splitscreen Layout

The viewport layout to use if the screen should be split and there are four local players.

You can choose from the following options:

Grid

Horizontal

Vertical

Skip Assigning Gamepad to Player 1

If enabled, this will make it so that gamepads start being assigned to the second controller ID in local multiplayer games.

In PIE (Play in Editor) sessions with multiple windows, this has the same effect as enabling the Route 1st Gamepad to 2nd Client setting in Editor Preferences.

Game Instance

Section

Description

Game Instance Class

The class to use when instantiating the transient GameInstance class.

You can choose any GameInstance class in your project.

Movies

Movies

Section

Description

Wait for Movies to Complete

If enabled, the game waits for startup movies to complete even if loading has finished.

Movies Are Skippable

If enabled, startup movies can be skipped by the user when a mouse button is pressed.

Startup Movies

Movies to play on startup.

Note that these must be in your game's Game/Content/Movies directory.

Packaging

Packaging

Section

Description

Use Pak File

If enabled, all content will be put into one or more .pak files instead of many individual files. This is enabled by default.

Use Io Store

If enabled, use .utoc / .ucas container files for staged / packaged package data instead of .pak.

Use Zen Store

If enabled, use Zen storage server for storing and fetching cooked data instead of using the local file system.

Make Binary Config

If enabled, staging will make a binary config file for faster loading.

Generate Chunks

If enabled, will generate .pak file chunks.

Assets can be assigned to chunks in the editor or via a delegate (see ShooterGameDelegates.cpp).

Can be used for streaming installs (PS4 Playgo, XboxOne Streaming Install, etc).

Generate No Chunks

If enabled, no platform will generate chunks, regardless of settings in platform-specific .ini files.

Chunk Hard References Only

Normally, during chunk generation, all dependencies of a package in a chunk will be pulled into that package's chunk.

If this is enabled, only hard dependencies are pulled in. Soft dependencies stay in their original chunk.

Build HTTP Chunk Install Data

If enabled, it will generate data for HTTP Chunk Installer.

This data can be hosted on a web server to be installed at a runtime.

Requires the Generate Chunks option to be enabled.

HTTP Chunk Install Data Directory

When Build HTTP Chunk Install Data is enabled, this is the directory where the data will be built to.

Package Compression Min Size to Consider DDC

Specifies the minimum (uncompressed) size for storing a compressed IoStore chunk in the Derived Data Cache (DDC).

HTTP Chunk Install Data Version

Version name for HTTP Chunk Install Data.

Share Material Shader Code

By default, shader code gets saved inline inside Material Assets. Enabling this option will store only shader code once as individual files.

This will reduce overall package size, but might increase loading time.

Deterministic Shader Code Order

If this option is disabled, the shader code will be stored in the library essentially in a random order, squarely the same in which the assets were loaded by the cooker.

Enabling this option will sort the shaders by their hash, which makes the shader library more similar between builds. This can help patching, but can adversely affect loading times.

Shared Material Native Libraries

By default, shader code gets saved into individual platform-agnostic files. Enabling this option will use the platform-specific library format only if one is available.

This will reduce overall package size but might increase loading time.

Ini Key Blacklist

List of the .ini file keys to strip when packaging.

Ini Section Blacklist

List of .ini file sections to strip when packaging.

Additional Builds for This Project

A list of custom builds that will show up in the Platforms menu to allow customized builds that make sense for your project. Will show up near Package Project in the Platforms menu (in the main Level Editor toolbar).

Force One Chunk Per File

If true, individual files are only allowed to be in a single chunk and it will assign it to the lowest number requested.

If false, files may end up in multiple chunks if requested by the cooker.

Max Chunk Size

If greater than 0, this sets a maximum size per chunk.

Chunks larger than this size will be split into multiple .pak files such as pakchunk0_s1.

This can be set in platform-specific game .ini files.

Create Compressed Cooked Packages

Create compressed cooked packages (decreased deployment size).

Package Compression Format

A comma-separated list of formats to use for .pak file and IoStore compression.

If more than one format is specified, the list is in order of priority, with fallbacks to other formats in case of errors or unavailability of the format (for example, if the format's plugin is not enabled).

Commonly PackageCompressionFormat=Oodle or PackageCompressionFormat=None.

Use This Compression Format Not Hardware Override

If enabled, forces the use of the specified Package Compression Format.

This option overrides any platform-specific values set by the HardwareCompressionFormat parameter in DataDrivenPlatformInfo.ini.

Package Compression Command Line Options

A generic setting for allowing a project to control compression settings during .pak file and IoStore compression.

For example: PackageAdditionalCompressionOptions=-compressionblocksize=1MB -asynccompression.

Package Compression Method

For compressors with multiple methods, select one. For example, for Oodle, you may use one of these:

Kraken

Mermaid

Selkie

Leviathan

You can read the description of every method here.

Encoder Effort Level for Debug & Development

For compressors with variable levels, select the encoder level, which makes packages smaller but takes more time to encode.

This does not affect decode speed.

For faster iteration, use lower effort levels (for example, 1).

Encoder Effort Level for Test & Shipping

Package compression level test shipping.

Encoder Effort Level for Distribution

Package compression level distribution.

Minimum Amount of Bytes Which Should Be Saved When Compressing a Block of Data, Otherwise Data Remains Uncompressed

A generic setting which is used to determine whether it is worth using compression for a block of data when creating IoStore or .pak files.

If the amount of saved bytes is smaller than the specified value, then the block of data remains uncompressed.

The optimal value of this setting depends on the capabilities of the target platform. For example, PackageCompressionMinBytesSaved=1024.

Note that some compressors (for example, Oodle) do their own internal worth it check and only use this value to determine the minimal size of a block which should be compressed.

Minimum Percentage of a Block of Data Which Should Be Saved When Performing Compression, Otherwise Data Remains Uncompressed

A generic setting which is used to determine whether it is worth using compression for a block of data when creating IoStore or .pak files.

If the saved percentage of a compressed block data is smaller than the specified value, then the block remains uncompressed.

The optimal value of this setting depends on the capabilities of the target platform. For example, PackageCompressionMinPercentSaved=5.

Note that some compressors (for example, Oodle) do their own internal worth it check and ignore this value.

Enable DDC for IoStore Compression

Specifies whether the Derived Data Cache should be used to store and retrieve compressed data when creating IoStore containers.

Include Crash Reporter

Specifies whether to include the crash reporter in the packaged project.

This is included by default for Blueprint-based projects, but can optionally be disabled.

Internationalization Support

Predefined sets of cultures whose internationalization data should be packaged.

You can choose from the following options:

English

EFIGS: English, French, Italian, German, Spanish

EFIGSCJK: English, French, Italian, German, Spanish, Chinese, Japanese, Korean

CJK: Chinese, Japanese, Korean

All

Localization Targets to Chunk

List of localization targets that should be chunked during cooking (if using chunks).

Localization Target Catch All Chunk ID

The chunk ID that should be used as the catch-all chunk for any non-asset localized strings.

Cook Everything in the Project Content Directory (Ignore List of Maps in the "List of Maps to Include in a Packaged Build" setting)

Cook all things in the project content directory.

Cook Only Maps (This Only Affects Cookall)

Cook only maps (this only affects the Cookall flag).

For more information, see the Content Cooking page.

Exclude Editor Content When Cooking

Don't include content in any editor folders (anything under Engine/Content/Editor*) when cooking.

This can cause issues with missing content in cooked games if content that the game uses is being excluded.

Exclude Movie Files When Staging (Skip Movies)

This setting tells the Editor to not include movies by default when staging or packaging.

If this setting (bSkipMovies in the .ini file) is true, all movie files in Engine\Content\Movies and <ProjectRoot>\Content\Movies are skipped, and the movies listed in UFSMovies and Non-UFSMovies are staged or packaged.

If this setting (bSkipMovies in the .ini file) is false, all movie files in Engine\Content\Movies and <ProjectRoot>\Content\Movies are staged or packaged.

Specific Movies to Package (UFSMovies)

If bSkipMovies is true, these specific movies will still be added to the .pak file (if using a .pak file; otherwise, they're copied as individual files).

The name of the movie file should have no extension in the listing: if the filename of your movie is, for example, Level2CinematicScene.mp4, you should add Level2CinematicScene to this array.

UFSMovies and Non-UFSMovies fields are read from platform .ini files instead of only being read from the editor .ini files.

Specific Movies to Copy (Non-UFSMovies)

If SkipMovies is true, these specific movies will be copied when packaging your project, but are not supposed to be part of the .pak file.

The name of the movie file should have no extension in the listing: if the filename of your movie is, for example, Level2CinematicScene.mp4, you should add Level2CinematicScene to this array.

UFSMovies and Non-UFSMovies fields are read from platform .ini files instead of only being read from the editor .ini files.

Compressed Chunk Wildcard

If set, only these specific .pak files will be compressed.

This should take the form of *pakchunk0*.

This can be set in a platform-specific .ini file.

List of Maps to Include in a Packaged Build

List of maps to include when no other map list is specified in the command line.

Additional Asset Directories to Cook

Directories containing .uasset files that should always be cooked regardless of whether they're referenced by anything in your project.

These paths are stored either as a full package path (for example, /Game/Folder, /Engine/Folder, /PluginName/Folder) or as a relative package path from /Game.

Directories to Never Cook

Directories containing .uasset files that should never be cooked, even if they are referenced by your project.

These paths are stored either as a full package path (for example, /Game/Folder, /Engine/Folder, /PluginName/Folder) or as a relative package path from /Game.

Test Directories to Not Search

Directories containing .uasset files that are for editor testing purposes and should not be included in enumerations of all packages in a root directory because they will cause errors on load.

These paths are stored either as a full package path (for example, /Game/Folder, /Engine/Folder, /PluginName/Folder) or as a relative package path from /Game.

Additional Non-Asset Directories to Package

Directories containing files that should always be added to the .pak file (if using a .pak file; otherwise they're copied as individual files).

This is used to stage additional files that you manually load via the UFS (Unreal File System) file IO API.

These paths are relative to your project's Content directory.

Additional Non-Asset Directories to Copy

Directories containing files that should always be copied when packaging your project, but are not supposed to be part of the .pak file.

This is used to stage additional files that you manually load without using the UFS (Unreal Files System) file IO API, for example, third-party libraries that perform their own internal file IO.

These paths are relative to your project's Content directory.

Additional Non-Asset Directories to Package for Dedicated Server Only

Directories containing files that should always be added to the .pak file for a dedicated server (if using a .pak file; otherwise they're copied as individual files).

This is used to stage additional files that you manually load via the UFS (Unreal File System) file IO API.

These paths are relative to your project's Content directory.

Additional Non-Asset Directories to Copy for Dedicated Server Only

Directories containing files that should always be copied when packaging your project for a dedicated server, but are not supposed to be part of the .pak file.

This is used to stage additional files that you manually load without using the UFS (Unreal Files System) file IO API, for example, third-party libraries that perform their own internal file IO.

These paths are relative to your project's Content directory.

Localizations to Package

Cultures whose data should be cooked, staged, and packaged.

Project

Section

Description

Build

Specifies whether to build the game executable during packaging.

You can choose from the following options:

Always

Never

If Project Has Code, or Running a Locally Built Editor

If Running a Locally Built Editor

Build Configuration

The build configuration for which the project is packaged.

You can choose from the following options:

Debug

DebugGame

Development

Test

Shipping

Build Target

Name of the target to build.

Staging Directory

The directory to which the packaged project will be copied.

Full Rebuild

If enabled, a full rebuild will be enforced each time the project is being packaged.

If disabled, only modified files will be built, which can improve iteration time.

Unless you iterate on packaging, we recommend full rebuilds when packaging.

For Distribution

If enabled, a distribution build will be created using the shipping configuration.

If disabled, a development build will be created.

Distribution builds are for publishing to the App Store.

Include Debug Files in Shipping Builds

If enabled, debug files will be included in staged shipping builds.

Prerequisites

Section

Description

Include Prerequisites Installer

Specifies whether to include an installer for prerequisites of packaged games, such as redistributable operating system components, on platforms that support it.

Include App-Local Prerequisites

Specifies whether to include prerequisites alongside the game executable.

App-Local Prerequisites Directory

A directory containing additional prerequisite packages that should be staged in the executable directory.

Can be relative to either the Engine folder within your Unreal Engine installation directory or the folder where your .uproject file is located.

Supported Platforms

Here, you can select the supported platforms for your project. Attempting to package, run, or cook your project on an unsupported platform will result in a warning.

You can choose one or more of the following options:

All Platforms

Android

HoloLens

IOS

Linux

LinuxARM64

TVOS

Windows

Target Hardware

Target Hardware

Section

Description

Optimize Project Settings for

Select the hardware class and a graphical level.

You can choose from the following options:

Class of hardware to target:

Desktop: Desktop or console

Mobile: Mobile or tablet

Graphical level to target:

Maximum: High-end features default to enabled.

Scalable: Some features are disabled by default but can be enabled based on the actual hardware.

Pending Changes

This section will show all pending changes to your project's settings.

Asset Manager

Asset Manager

Redirects

Asset Registry

Asset Tools

Advanced Copy

Asset Manager

Asset Manager

Section

Description

Primary Asset Types to Scan

List of asset types to scan at startup.

Directories to Exclude

List of directories to exclude from scanning for Primary Assets, useful to exclude test assets.

Primary Asset Rules

List of specific asset rule overrides.

Custom Primary Asset Rules

List of game-specific asset rule overrides for types, this will not do anything by default.

Only Cook Production Assets

If true, DevelopmentCook assets will error when they are cooked, you should enable this on production branches.

Should Manager Determine Type and Name

If true, the asset manager will determine the type and name for Primary Assets that do not implement GetPrimaryAssetId, by calling DeterminePrimaryAssetIdForObject and using the .ini settings.

This works in both cooked and uncooked builds, but is slower than directly implementing GetPrimaryAssetId on the native asset.

Should Guess Type and Name in Editor

If true, PrimaryAsset Type / Name will be implied for assets in the editor even if bShouldManagerDetermineTypeAndName is false.

This guesses the correct ID for content that hasn't been resaved after GetPrimaryAssetId was implemented.

Should Acquire Missing Chunks on Load

If true, this will query the platform chunk install interface to request missing chunks for any requested primary asset loads.

Should Warn About Invalid Assets

If true, the asset manager will warn when it is told to load or do something with assets it does not know about.

Redirects

Section

Description

Primary Asset Id Redirects

Redirect from Type:Name to Type:NameNew.

Primary Asset Type Redirects

Redirect from Type to TypeNew.

Asset Path Redirects

Redirect from /game/assetpath to /game/assetpathnew.

Asset Registry

Section

Description

Metadata Tags For Asset Registry

The metadata tags to be transferred to the Asset Registry.

Asset Tools

Advanced Copy

Section

Description

Advanced Copy Customizations

List of rules to use when advanced copying assets.

Working with Projects

Updating Projects to Unreal Engine 5

Project Templates

An Unreal Engine project holds all the contents of your game and application and ties everything together. It contains a number of folders and Assets on your disk, such as Blueprints, Materials, 3D Assets, animations, and so on.

The Content Browser inside the Unreal Editor uses the same file and folder structure as the Project folder on your disk.



The Content Browser mirrors the file and folder structure of the Unreal Engine project on disk. Click the image for full size.

Every Unreal Engine project has a .uproject file associated with it. The .uproject file is how you create, open, or save a project. You can create any number of different projects and work on them in parallel.

Working with Projects

To learn more about Unreal Engine projects, refer to the pages below.



Describes how to create and configure a new project in Unreal Engine.



Describes how to access and open an existing project in Unreal Engine.



Steps for converting an existing project to a template

Updating Projects to Unreal Engine 5

To learn how to upgrade projects created in Unreal Engine 4.2x to Unreal Engine 5, refer to the guide below.



Steps and requirements for migrating your Unreal Engine 4 projects to Unreal Engine 5.

Project Templates

Unreal Engine templates are starting points for different types of projects. Templates contain premade Assets, such as Mannequins that have their player input and animations already configured, or sample scenes for lighting studies and stylized renderings.

In addition to Unreal Engine's existing templates, you can convert any project to a custom template so you can reuse its Assets and configuration as needed.



Templates available with Unreal Engine and how to use them



Introduction to the First Person template in Unreal Engine



Introduction to the Third Person template in Unreal Engine



Introduction to the Simulation Blank template in Unreal Engine





When you launch Unreal Engine, the Unreal Project Browser opens automatically. This is where you can:

Create a new project.

Open an existing project.

Manage existing projects.

The diagram below illustrates the steps to create a new project in Unreal Engine.



Creating a new project in Unreal Engine from the Project Browser window.

To create a new project, follow these steps:

Select the development category (1) that best matches your industry and project goals.

You can select from the following categories:

Games

Film, Television, and Live Events

Architecture, Engineering, and Construction (AEC)

Automotive, Product Design, and Manufacturing (APM)

Select a template (2) for your project. The templates you can choose from are based on the category you selected in step 1.

Unreal Engine contains a number of project templates you can use as a starting point for your own projects. To learn more about the different project templates available, refer to the Templates Reference page.

Configure the Project Defaults (3). In this section, you can select your target platform (that is, the hardware where your game or application will run, like a computer or a mobile device), configure quality and ray tracing settings, and more.

Some of the settings below may not be available for certain templates. For example, the Handheld AR template can only use Blueprint implementation.

You can configure the following settings:

Setting

Description

Implementation

Select how you want to implement your project's logic, such as character movement, level transitions, and so on.

You can choose from the following options:

Blueprint, if you want to build your project in the Unreal Editor, and use the Blueprint Visual Scripting system to create interactions and behavior.

C++, if you want to build your project by programming with C++ in Visual Studio.

For more information about these implementation methods, refer to the following pages:

Blueprint Visual Scripting

Programming with C++

Target Platform

Select the kind of platform your project is intended for:

Desktop

Mobile

Quality Preset

Select the maximum quality level, based on which platform your project targets. We recommend that you choose:

Maximum, if you are developing your project for a computer or game console.

Scalable, if you are developing your project for mobile devices.

Starter Content

Select whether you want your new project to include starter content. Starter content includes some simple Static Meshes with basic textures and Materials. It is useful if you want to start learning and experimenting straight away, without worrying about sourcing and importing custom content.

Ray Tracing

Select whether to enable or disable ray tracing for your project.

For more information about ray tracing in Unreal Engine, refer to the Hardware Ray Tracing and Path Tracing Features page.

Select where you want to store your project, and give your project a name (4).

Click Create (5) to finish creating your new project.

Result

Unreal Engine creates a new project with the settings you configured, and then automatically opens the project.

Opening Projects from the Epic Games Launcher

Opening Projects from the Project Browser

Opening Projects from Unreal Engine

Opening Projects From Disk

There are several ways to open an existing Unreal Engine project, depending on where it is located and the version of Unreal Engine it was created with.

Opening Projects from the Epic Games Launcher

In the Epic Games Launcher, click Unreal Engine on the left navigation, then click Library at the top of the Launcher. You will see a list of all Unreal Engine projects on your local machine.

If you copied a project from another computer or from the Internet, the project will not appear in this list until you have opened it locally at least once. Refer to the Opening Projects From Disk section on this page to learn more.



My Projects section of the Epic Games Launcher. Click the image for full size.

Double-click any project thumbnail to open that project.

The Launcher displays the following information for each Project:

Project name

Project thumbnail

Unreal Engine version that the project is compatible with

Right-clicking a project's thumbnail in the Launcher brings up a context menu with the following options:

Option

Description

Open

Opens the project in the version of Unreal Engine that it is compatible with.

Show in folder

Opens the project folder in a new Windows Explorer (Windows) or Finder (macOS) window.

Create shortcut

Creates a shortcut to the project on the desktop.

Clone

Creates an exact copy of the project. You can specify the name and location of the new project.

Delete

Permanently deletes the project.

The project files are not moved to the Recycle Bin, like they would be if you deleted the project folder from Windows Explorer or Finder. If you accidentally delete a project using this option, you will not be able to recover it.

Opening Projects from the Project Browser

When you launch any version of Unreal Engine, the Project Browser displays and opens the Recent Projects panel by default. Much like the projects list in the Epic Games Launcher, this section displays all the Unreal Engine projects on your disk.

If you copied a project from another computer or from the Internet, the project will not appear in this list until you have opened it locally at least once. Refer to the Opening Projects From Disk section on this page to learn more.



Project Browser in Unreal Engine 5. Click the image for full size.

Double-click any project thumbnail to open that project. Alternatively, click the project to select it, then click Open.

The Launcher displays the following information for each Project:

Project name

Project thumbnail

Unreal Engine version that the project is compatible with

Right-clicking a project's thumbnail in the Project Browser brings up a context menu with an option to open your project folder in a Windows Explorer or Finder window.

Enable the Always load last project on startup checkbox in the bottom-left corner of the Project Browser to have Unreal Engine 5 always open the last project you worked on when you launch the engine.

Opening Projects from Unreal Engine

In Unreal Engine, from the main menu, go to File > Open Project. This opens a window that displays a list of local projects, similar to the Project Browser.



Opening a project from Unreal Engine. Click the image for full size.

To open a project, either:

Select the project from the list, then click Open.

Double-click the project thumbnail.

If the project you want to open for isn't in the list, click Browse, then browse to the project folder and open the (ProjectName).uproject file.

Opening a project with a different version of Unreal Engine than the one it was created in can lead to data corruption and data loss. It is recommended to open a copy of the project to preserve the original.

Opening Projects From Disk

If you copied a project from another computer or from the Internet, the project will not appear in this list until you have opened it locally at least once.

To open a project from disk, follow these steps:

Make sure you have installed the Unreal Engine version that the project was created with.

Navigate to the project's folder on disk.

Double-click the (ProjectName).uproject file. This file is located directly inside your project's folder.



In this example, you would double-click the MyProject.uproject file.

If you don't have the version of Unreal Engine that the project was created with, you will see a pop-up window asking you to select which version of Unreal Engine to open the project with.



Select an Unreal Engine version from the drop-down, or click the ellipsis (...) button to browse to an Unreal Engine executable on your disk, then click OK.

Opening a project with a different version of Unreal Engine than the one it was created in can lead to data corruption and data loss. It is recommended to open a copy of the project to preserve the original.

Starter Map

Advanced Lighting Map

When you create a new project from a template, you have the option to include the Starter Content pack in your new project. This pack contains Static Meshes, particles, Materials, and other Assets you can use to quickly populate your project.

To include starter content in your project, when you create a new project, under Project Defaults, enable the Starter Content option.



Click the image for full size.

In your project, starter content is located in the Content/StarterContent folder in the Content Browser.

Starter Map



Click the image for full size.

The StarterMap Level, located in the Content/StarterContent/Maps folder, is a demo of the starter content in action. Press Play or Simulate in the Main Toolbar to see it in action.

To learn more about navigating the Viewport, see Viewport Controls.

Advanced Lighting Map



Click the image for full size.

Starter content also includes the Advanced_Lighting Level, which demonstrates a lighting setup created using Blueprints.

You can place different Assets on the platform stage in the middle to see how they look under these lighting conditions, or open the BP_LightStage Blueprint and examine its construction script to see how it was created.

The BP_LightStage Blueprint implements all of the following:

Directional Light

Skybox sphere

HDRI background

Atmospheric light

Height fog

Sky Light

Light shafts

Rotating the BP_LightStage Actor in the Level defines the sun direction and HDRI rotation. The atmosphere also responds to the Actor's rotation.

You can set the following properties on the BP_LightStage, either as defaults for the Blueprint or on the placed instance in the Level:

Property

Description

Global Brightness

Adjusts a global multiplier on all brightness values.

Use HDRI

Whether or not to use HDRI as background. If using HDRI, there are additional settings for setting brightness, contrast, tint, cubemap, and rotation.

If you want to use an HDRI with a directional light, you may want to paint out the sun in your HDRI before importing and then line up the sun rotation with the one in the HDRI. Shooting reference objects will help you match the direct vs. indirect light ratio.

Use Sun Light

Enables the Directional Light, which is movable by default.

Stationary Light for Sun

Makes the Directional Light stationary.

Override Sun Color

By default, the sun gets its color from the angle to match atmospheric scattering. When this option is enabled, this behavior is disabled and Tint is used instead.

Disable Sun Disk

Disables the sun disk that the Directional Light places in the atmosphere.

Shadow Distance

Sets the draw distance for dynamic shadows.

Use Atmosphere

Enables atmospheric scattering. Most atmosphere settings on the BP_LightStage correspond to the same settings on an Atmospheric Fog Actor.

Use Fog

Enables exponential height fog.

Altitude

Sets the height of the fog, so you do not have to move the Actor.

Light Shaft Bloom and Light Shaft Occlusion

Enables or disables post-process light shafts from the sun direction.

To use the Advanced Lighting Assets in an existing project, you can migrate the Advanced_Lighting map, which also migrates its associated Assets.

Configuring Input for Playable Characters

Available Templates in Unreal Engine 5

Games Templates

Film, Television, and Live Events Templates

Architecture, Engineering, and Construction Templates

Automotive, Product Design, and Manufacturing Templates

Simulation Templates

When you create a new Unreal Engine project, you have the option to use one of the existing templates as a base for your game or application. Unreal Engine templates contain character controllers, Blueprints, and other features that work without the need for additional configuration.

To learn how to create a new project from a template, refer to the Creating a New Project page.

When you select a template, you will see a description that tells you more about the template and what it contains. Scroll down to read the full description.



Example of a template description for the Handheld AR template. Click the image for full size.

You can also create custom templates from any one of your existing projects. To learn more, refer to the Creating Custom Templates page.

Configuring Input for Playable Characters

Many templates include a character you can control using your keyboard, mouse, or controller. In Unreal Engine terms, this is called a Pawn.

You can view existing controls for your Pawn and configure new ones in the Input section of the Project Settings. To open it:

From the main menu, go to Edit > Project Settings.

In the left sidebar, scroll down to the Engine section, then click Input.

Expand the Bindings section to edit the:

Action Mappings, which define the keys that control actions such as jumping.

Axis Mappings, which control movement. Depending on the template, movement may be restricted on one or more axes. For example, in the Side Scroller template, the Pawn can only move left / right and jump.



Default Input configurations for the Side Scroller template, showing the controls for moving and jumping. Click the image for full size.

Available Templates in Unreal Engine 5

The templates in Unreal Engine 5 are split into the following categories:

Games

Film, Television, and Live Events

Architecture, Engineering, and Construction

Automotive, Product Design, and Manufacturing

Simulation

Each of these categories also includes a Blank template, which consists of an empty project with no additional content and settings. This is the most basic template available.

Games Templates



Vehicle Advanced template in Unreal Engine 5.

Unreal Engine's Games templates offer quick starting points for various kinds of games such as first- and third-person, side-scroller, or driving.

Although these are tagged as "Game" templates, you can use them as a starting point for any kind of project. For example, you can use the VR Template to create a virtual reality walkthrough of a three-dimensional space. The Third Person template is generally a good starting point for many different kinds of projects.

Template Name

Template Contents

Additional Documentation

First Person

A first-person character armed with a gun that shoots physics-based projectiles. Player experience Level contents from the character's viewpoint.

First Person Template Overview

Third Person

A third-person character and basic geometry. The camera is located above and behind the character.

Third Person Template Overview

Flying

A spaceship that moves in three-dimensional space, with a camera that follows it.

Puzzle

A simple grid of blocks and an on-screen score counter. Click or tap the blocks to change their color and increase the score counter.

Rolling

A physics-based rolling ball you can control with a keyboard or virtual joystick, as well as some basic geometry.

Top Down

A character you move by clicking or tapping to a new location. The camera is in a fixed position above the character and follows their movement.

Twin Stick Shooter

A spaceship that moves and fires, as well as some geometry that the projectiles can affect.

Handheld AR

A starting point for creating AR applications you can deploy to Android or iOS. Includes runtime logic for scanning an environment to gather data for creating interactive planes in the virtual scene, and lighting and scene depth information.

Handheld AR Template Quickstart

Handheld AR Template Technical Reference

Side Scroller

A 3D character that moves sideways in a restricted 3D environment. The camera is fixed and keeps the player character at the center of the screen. The Level also includes some platforms the character can jump to.

2D Side Scroller

A Paper 2D sprite that moves in a restricted 2D environment. The Level also includes some platforms the character can jump to.

Paper 2D

Vehicle

A simple physics-driven vehicle with two different camera views — one inside the vehicle, the other above and behind it — as well as a HUD.

Vehicle Advanced

A more complex physics-driven vehicle with double wishbone suspension. Features two different camera views — one inside the vehicle, the other above and behind it — as well as a HUD.

Virtual Reality

A starting point for all of your virtual reality (VR) projects in Unreal Engine 5. It includes encapsulated logic for teleport locomotion and common input actions, such as grabbing and attaching items to your hand.

VR template

Developing for VR in Unreal Engine

Film, Television, and Live Events Templates



DMX template in Unreal Engine 5.

The Film, Television, and Live Events templates provide a starting point for live production work.

Template Name

Template Contents

Additional Documentation

Virtual Production

Functionality for VR Scouting, Virtual Camera, SDI Video, Composure, and nDisplay.





Virtual Camera Actor Quick Start

DMX

Examples for addressing, patching, and controlling proxy lighting fixtures, as well as recording and playback of live DMX data streams in and outside Unreal Engine.

DMX

InCamera VFX

Blueprints, plugins, and example stages for in-camera VFX workflows. Use this as a starting point for Virtual Production shoots with LED volumes.

In-Camera VFX Template

In-Camera VFX Overview

nDisplay

Display functionality using a cluster of PCs. Use as a starting point for rendering on complex arrangements of physical displays for live performances.

nDisplay Template

Rendering to Multiple Displays with nDisplay

Architecture, Engineering, and Construction Templates



Archvis template in Unreal Engine 5.

The Architecture, Engineering, and Construction templates use Datasmith to import content from various 3D programs into Unreal Engine, where you can further refine that content for desktop and XR applications.

Template Name

Template Contents

Additional Documentation

Archvis

Example architectural visualisation workflows with sample scenes for sun studies, interior renderings, and non-photorealistic stylized renderings.

Design Configurator

Uses Variant Manager, UMG, and Blueprint functionality to build a project where you can toggle between different object states such as visibility, initiate animation sequences, switch between views, and toggle between different design options.

Hololens Viewer

Navigation and interaction for Microsoft HoloLens. Use this template as a starting point for collaborative industrial or architectural projects.

HoloLens Viewer Template

Collab Viewer

Navigation and interaction for desktop and VR in collaborative sessions. This template contains some archviz-specific starter content and has several additional plugins enabled by default, including OpenXR and LiveLink.

Collab Viewer Template

Handheld AR

A starting point for creating AR applications you can deploy to Android or iOS. Includes runtime logic for scanning an environment to gather data for creating interactive planes in the virtual scene, and lighting and scene depth information.

Handheld AR Template Quickstart

Handheld AR Template Technical Reference

Automotive, Product Design, and Manufacturing Templates



Photo Studio template in Unreal Engine 5.

The Automotive, Product Design, and Manufacturing templates use Datasmith to import content from various 3D programs into Unreal Engine, where you can further refine that content for desktop and XR applications.

Template Name

Template Contents

Additional Documentation

Photo Studio

A premade photographic studio environment you can use for cinematics and product presentations.

Hololens Viewer

Navigation and interaction for Microsoft HoloLens. Use this template as a starting point for collaborative industrial or architectural projects.

HoloLens Viewer Template

Product Configurator

Uses Variant Manager, UMG, and Blueprint functionality to build a generic product configurator (that is, a program that lets you swap out different parts to test out new looks for a product, such as different colors for a car).

Product Configurator

Collab Viewer

Navigation and interaction for desktop and VR in collaborative sessions. This template also contains a sample model car that can be explored in VR.

Collab Viewer Template

Handheld AR

A starting point for creating AR applications you can deploy to Android or iOS. Includes runtime logic for scanning an environment to gather data for creating interactive planes in the virtual scene, and lighting and scene depth information.

Handheld AR Template Quickstart

Handheld AR Template Technical Reference

Simulation Templates



Illustrative use of a Simulation template in Unreal Engine 5.

Simulation templates offer a broad range of starting points for various enterprise simulation applications. These templates contain the following functionality:

Specific settings for outdoor environments.

Realistic sky and lighting.

Georeferencing tools.

Template Name

Template Contents

Additional Documentation

Simulation Blank

A template that consists of an empty project with the required settings and plugins enabled. This template is suitable as a starting point for most simulation applications and contains the following features:

Earth atmosphere

Atmospheric lighting

Volumetric clouds

Geographical coordinates

World Geodetic System (WGS84)

Handheld AR

A starting point for creating AR applications you can deploy to Android or iOS. Includes runtime logic for scanning an environment to gather data for creating interactive planes in the virtual scene, and lighting and scene depth information.

Handheld AR Template Quickstart

Handheld AR Template Technical Reference

Virtual Reality

A starting point for all of your virtual reality (VR) projects in Unreal Engine 5. It includes encapsulated logic for teleport locomotion and common input actions, such as grabbing and attaching items to your hand.

VR template

Developing for VR in Unreal Engine

Playing and Simulating

Static Mesh Actors

Skeletal Mesh Actors

Creating a First Person Project

Template Contents

Blueprints

First Person Character

Rifle and Projectile

Level

Improving your Project

What's Next?

When you create a new project, Unreal Engine gives you a list of templates you can choose from. These templates contain some ready-to-use Assets, such as level geometry, a character you can control, and simple character animations. Many tutorials use one of these templates as a starting point.

In a first-person game, the player sees the game from the viewpoint of the character they are playing as. Some first-person games show parts of the character models, like the character's arms or a weapon. This is different from a third-person game, where you see the action from a point that's behind and slightly above the character.

The First Person template in Unreal Engine 5 contains the following elements:

A playable first-person character that can move and shoot.

A gun that can be picked up and fires projectiles.

A Level with basic geometry (ramps, platforms).

Cubes that react when the player or a projectile collides with them.

Creating a First Person Project

Launching Unreal Engine 5 opens the Project Browser window, where you can choose to open an existing Unreal project or create something new. To create a first-person project, select the Games category on the left, and then select the First Person template.



Creating a new first-person project in Unreal Engine 5.

There are several additional settings you can configure for your First Person project. For an overview of these, refer to the Creating a New Project page.

If you want to have some ready-to-use objects to populate your Level with, choose the With Starter Content option when configuring your Project Settings. These are great to use while you get used to the controls and workflows in Unreal Engine.

After following these steps, you now have a basic Level with a first-person character you can control using the keyboard and mouse.

Why don't you try out your new Level? In the Main Toolbar, click Play, then try to move around and shoot some cubes.

Use the WASD keys to move your character, and look around by moving the mouse. Walk over to the gun to pick it up, then left-click to fire a projectile.

Template Contents

The First Person template contains all of the basic elements of a simple First-Person Shooter (FPS) game or any other kind of first-person experience. The following section details these elements and where to find them in the Content Browser.

Blueprints

The First Person Template includes Blueprints for the:

Player character

Rifle

Rifle projectile

Game mode

These Blueprints are located in the Content/FirstPerson/Blueprints folder.

Each Blueprint's Event Graph includes comments and annotations to help you understand what different node groups do and some of the logic behind the implementation.



Here, you can see some developer comments inside the BP_Rifle Blueprint. Click the image for full size.

First Person Character

Assets for the player character are located in the Content/FirstPersonArms folder. Here, you can find the Skeletal Mesh, Materials, Textures, and animations for the character.

Rifle and Projectile

The Content/FPWeapon folder contains the Assets for the rifle and projectile. The rifle uses a Skeletal Mesh (SK_FPGun). Projectiles are spawned on left-click and apply a physics impulse to any physics-enabled Actor they collide with in the Level. You can see how this logic was implemented in the BP_FirstPersonProjectile Blueprint located in the Content/FirstPerson/Blueprints folder.

Level

The Assets that make up Level geometry (Static Meshes, Materials, and Textures) are located in the Content/LevelPrototyping folder.

Improving your Project

Now that you have a playable Level, you can start to import content and tweak things to make your game more interesting.

The easiest way to add more content inside your Level is to drag-and-drop it from the Content Browser. If you chose to include starter content when you created your project, you should already have some additional things you can drag-and-drop into your Level.

For more in-depth instructions on how to populate your Level, see Level Designer Quick Start.

What's Next?

Now that you've gone through the basics of creating a first-person experience, here are some other things you can try:

Import and configure a different model for your gun, or choose a different weapon entirely. You can download premade Assets from the Unreal Engine Marketplace or create your own.

Populate your Level with free content and props from Quixel Bridge. You can build a variety of indoor and outdoor environments, and new content is added regularly.

Add some fancy visual effects to your game, like motion blur or vignette, by using post-processing.

Create an in-game heads-up display (HUD) with Unreal Motion Graphics (UMG) to display information such as player health and ammo count.

Add AI characters using Behavior Trees. You can set them up to chase, flee, help, or harm the player.

Playing and Simulating

Static Mesh Actors

Skeletal Mesh Actors

Creating a Third Person Project

Template Contents

Third-Person Character

Animations

Level

Improving Your Project

Character

Level

What's Next?

When you create a new project, Unreal Engine gives you a list of templates you can choose from. These templates contain some ready-to-use Assets, such as level geometry, a character you can control, and simple character animations. Many tutorials use one of these templates as a starting point.

In a third-person game, the player sees the game world from a Camera that's located at a fixed distance behind and slightly above their character. In Unreal Engine, you can control camera distance and position, and adjust it as needed.

The Third Person template in Unreal Engine 5 contains the following elements:

A playable third-person character that can move and jump.

Additional meshes for the character.

A Level with basic geometry (ramps, platforms).

Physics-enabled cubes that react when the player collides with them.

The template also comes with redesigned Mannequins.

Creating a Third Person Project

Launching Unreal Engine 5 opens the Project Browser window, where you can choose to open an existing Unreal project or create something new. To create a third-person project, select the Games category on the left, and then select the Third Person template.



Creating a new third-person project in Unreal Engine 5.

There are several additional settings you can configure for your Third Person project. For an overview of these, refer to the Creating a New Project page.

If you want to have some ready-to-use objects to populate your Level with, choose the With Starter Content option. These are great to use while you get used to the controls and workflows in Unreal Engine.

After following these steps, you now have a basic Level with a third-person character you can control.

Why don't you try out your new Level? In the Main Toolbar, click Play. Use the WASD keys to move your character, press the Space bar to jump, and look around by moving the mouse.

Template Contents

The Third Person template contains all of the basic elements of a simple third-person experience. You can use it as a starting point for a traditional role-playing game (RPG), third-person shooter, or any other kind of application. The following section details the main template elements and where to find them in the Content Browser.

Third-Person Character

Assets for the player character are located in the Content/Characters folder. By default, the Third Person template starts with the feminine Unreal Engine 5 Mannequin. This folder contains additional Skeletal Meshes for the player character, both in the style of Unreal Engine 5 and the legacy Unreal Engine Mannequin.



Unreal Engine 5 Mannequins.

The new Mannequins in Unreal Engine 5 are named Manny and Quinn.

Unreal Engine 5 Mannequins also come with configurable Level of Detail (LOD) settings. LODs help optimize your application for different platforms. For example, applications targeting mobile platforms (Android, iOS) should use less detailed character models. This helps improve your application's performance on these platforms. The Data Asset that controls Mannequin LODs is located in the Content/Characters/Mannequins/Meshes folder.

Animations

Animations for UE5 Mannequins are located in the Content/Characters/Mannequins/Animations folder. There are two sets of animations specific to the two Mannequins.

The Animation Blueprints make full use of the new IK Rig system in Unreal Engine 5. Unlike legacy animations, IK Rig can be used to dynamically modify pose-based solver parameters. An example of this can be seen in the screenshots below: the position of Quinn's feet adjusts dynamically to match the kind of terrain she is standing on.



To see how this was implemented, have a look at the CR_Mannequin_BasicFootIK rig in the Content/Mannequins/Rigs folder.

Also in the Rigs folder, the CR_Mannequin_Body Control Rig Asset can be used to easily pose and animate the Mannequin directly in the editor. To learn more about how to pose and animate with Control Rig, refer to the Control Rig section of the Unreal Engine 5 documentation.

Level

The Assets that make up Level geometry (Static Meshes, Materials, and Textures) are located in the Content/LevelPrototyping folder.

Improving Your Project

Now that you have a playable Level, you can start to import content and tweak things to make your game more interesting.

Character

You can change your character's appearance by changing its Static Mesh. As an example, let's change the default Mannequin mesh. To do this, follow these steps:

In the Content Browser, go to Content/ThirdPerson/Blueprints, then double-click the BP_ThirdPersonCharacter Blueprint to open it in the Blueprint Editor.



In the Blueprint Editor, in the Components panel, click the Mesh(CharacterMesh) Component to select it.



Click the image for full size.

With the Mesh(CharacterMesh) Component selected, find the Details panel on the right side of the Blueprint Editor. Then, in the Mesh section, click the drop-down next to the Skeletal Mesh parameter and select SKM_Manny from the list.



Click the image for full size.

Still in the Details panel, in the Animation section, set the following options:

Animation Mode: Use Animation Blueprint

Anim Class: ABP_Manny



Click the image for full size.

Compile and Save the Blueprint.



Click the Viewport tab to confirm that the mesh has updated.



Click the image for full size.

Your character can already run and jump, but you can also add other types of character movement, like walking or crouching. For a detailed tutorial, see Setting Up Character Movement.

Level

Your Level already has some simple geometry, like stairs and platforms. The easiest way to add more content inside is to drag-and-drop it from the Content Browser.

If you chose to include starter content when you created your project, you should already have some things you can drag-and-drop into your Level.

For more in-depth instructions on how to populate your Level, see Level Designer Quick Start.

What's Next?

Now that you've gone through the basics of creating a third-person experience, here are some other things you can try:

Import and configure a different model for your player character. You can download premade characters from the Unreal Engine Marketplace, or use a MetaHuman instead.

Populate your Level with free content and props from Quixel Bridge. You can build a variety of indoor and outdoor environments, and new content is added regularly.

Add some fancy visual effects to your game, like motion blur or vignette, by using post-processing.

Create an in-game heads-up display (HUD) with



Add AI characters using Behavior Trees. You can set them up to chase, flee, help, or harm the player.

Playing and Simulating

The Simulation Player Controller (BP_SimPlayerController)

The Simulation Floating Pawn (BP_SimfloatingPawn)

The Simulation Blank template is an Empty World Level template enriched with simulation-specific settings and functionality. It consists of an empty environment with the following features and characteristics:

A flat Static Mesh as the ground/floor.

A SunSky system with Earth-specific settings:

North offset compatible with the GeoReferencing plugin conventions.

A directional light with realistic Sun properties (Intensity, Source Angle), casting far shadows that leverage the Virtual Shadow Maps system (requires enabling the DirectX 12 (SM6. Experimental) option under Project Settings > Platforms - Windows and a compatible graphics card).

Volumetric clouds, with a natural-looking material.

Exponential Height Fog.

Stars (note that these are for cosmetic purposes only, and do not accurately represent realistic star positioning for any given real-world location).

A global Post-Process Volume with Exposure settings corresponding to human vision.

A Georeferencing Actor to locate the environment on Earth.

The Geographic location of the UE origin in the SunSky and Georeferencing Actors has been set to 73W, 45N. You'll have to adapt it to your actual environment location if needed.

This template also comes with a custom BP_SimGameMode Blueprint that defines a specific BP_SimPlayerController and BP_SimfloatingPawn. These Blueprints are provided as an example of how to enhance the default features of the base Controller and Pawn classes and are explained below.

The Simulation Player Controller (BP_SimPlayerController)

This controller comes with some key shortcuts to allow the following player actions at runtime:

Navigate freely with a floating Pawn spawned on play (BP_SimfloatingPawn).

Alternate between this floating Pawn and a Pawn that already exists in the Level.

Control the time of day.

Display a profiling and stats widget.

Display the Geospatial location status bar.

The following keyboard shortcuts are available:

Key

Action



Pawn controls



Enter

Alternate between the Floating Pawn and a pre-existing Level Pawn.

Tab

When controlling a Level Pawn, switch to the next controllable Pawn.

Shift + Tab

When controlling a Level Pawn, switch to the previous controllable Pawn.

1 - 6

Direct shortcut to control a specific Level Pawn. If there are more than 6, use the Tab key.



Time of Day controls



End

Decrease the current Time of Day.

Page Down

Increase the current Time of Day.

Insert

Smoothly transition the Time of Day to a Dawn value.

Home

Smoothly transition the Time of Day to a Noon value.

Page Up

Smoothly transition the Time of Day to a Dusk value.



Widget controls



P

Show / Hide the Profiling Widget.

G

Show / Hide the Geospatial Widget.

Geospatial Widget



Click image for full size.

The Geospatial Widget is a status bar displaying your current location on Earth in different coordinate systems:

Projected CRS.

Geographic CRS (Lat/Long).

Geocentric (ECEF).

To learn more, refer to the Georeferencing a Level page.

Profiling Widget



Click image for full size.

The Profiling Widget is a debug utility to profile the performance of your application.

The left button stack will show or hide different performance counters, which you can also access by their associated stat counterName console command. The widget displays the most common and useful ones:

FPS

Unit

Engine

SceneRendering

Game

GPU

Since profiling is heavily linked to the number of frames per second (FPS), the second column of buttons is where you can enable or disable vertical sync (VSync) or cap FPS to 30 or 60 FPS if desired.

The Simulation Floating Pawn (BP_SimfloatingPawn)

The Simulation Floating Pawn is an improved version of the Unreal Engine default Pawn, with the added capability to control the maximum navigation speed using the mouse wheel. This helps when dealing with large environments.

Clicking the mouse wheel will reset to the default speed.

Prerequisites

Converting a Project

Conversion Result

This page shows how to use Unreal Engine's built-in project update feature to convert your Unreal Engine project to a newer version of the engine.

After you update a project to a newer version of Unreal Engine, you will not be able to open it in an older Unreal Engine version. As a best practice, we always recommend converting a copy of the project by following the steps below. Once you make sure your converted project works as intended, you can manually delete the old version.

Prerequisites

This workflow requires Visual Studio 2019 to be installed on your machine.

Converting a Project

To convert a project, follow these steps:

Launch the version of Unreal Engine to which you want to convert your project. For example, if you have an Unreal Engine 5 project, and you want to convert it to Unreal Engine 5.1, launch Unreal Engine 5.1.

In the Unreal Project Browser window that opens, find the project you want to convert.

Use the search bar (1) to find the project by name. Note that the version of Unreal Engine that the project was created with displays on the project tile (2).



Click the image for full size.

Click the project tile to select it, then click Open.

In the dialog window that appears, click Open a Copy to have Unreal Engine create a copy of your project and attempt to update it and open it in the current version.



If you click More Options, you also have access to the following options:



Option

Description

Convert in-place

If you select this option, Unreal Engine attempts to convert the original project as it is without making a copy first.

This can cause irreversible data corruption and data loss if the conversion fails.

Skip conversion

If you select this option, Unreal Engine attempts to open the project as it is, without attempting to upgrade it first.

This can cause irreversible data corruption and data loss if the project fails to open.

Conversion Result

Regardless of the option you select, Unreal Engine attempts to automatically generate the code for your project files.

If the conversion succeeds, your project will open in the Unreal Editor.

If the conversion fails, Unreal Engine will display an error log with more information about the failure and why it occurred. You need to resolve the causes of the failure manually before attempting to update the project again.

How Recovery Hub Works

Recovery Hub Interface

Recovering a Session

Deleting a Session

Recovery Hub is an Unreal Engine plugin that helps with the recovery of an engine session after a crash or abnormal exit. In Unreal Engine 4, this plugin was named Disaster Recovery.

The Recovery Hub plugin isn't enabled by default. To use it, you must first enable it.

If you work with Assets larger than 2GB, Recovery Hub will consume a large amount of disk space as it records each transaction. You should disable the system temporarily if you start to run out of disk space. To do this, in the Plugins > Recovery Hub section of the Project Settings window, disable the Is Enabled option.

How Recovery Hub Works

When the Editor launches, Disaster Recovery automatically checks to see if the last sessions ended abnormally. If it did, the Editor retrieves the previously recorded list of transactions and offers to replay them for you. You can choose to replay some or all of the transactions to help recover work that may have been lost when the last Editor session crashed.

Recovery Hub reads each change to an Actor or Asset as a transaction and maintains a list of the most recent transactions. If the Editor crashes, you can roll back your project to a previous transaction to restore any lost work.

Because Recovery Hub only supports Level editing and Sequencer, it works best in conjunction with autosave files and it's not intended as a replacement for autosave. Each save and autosave counts as a transaction in Recovery Hub.

Enable Autosave from the General > Saving & Loading section of the Editor Preferences.

Recovery Hub Interface



Click the image for full size.

The Recovery Hub window consist of the following areas:

Number

Name

Description

1

Main Toolbar

Contains two buttons:

Import: Import a crash data dump in .json format.

Delete: Delete the currently selected session.

2

Sessions panel

Displays a list of saved sessions.

3

Configurations button

Click this button to open the Recovery Hub plugin settings in Project Settings.

4

Session details

Displays a list of transactions for the currently selected session.

Recovering a Session

To recover an Unreal Editor session after a crash, follow these steps:

Open Recovery Hub. From the main menu, go to Tools > Recovery Hub.

From the Sessions panel, select a session to recover.

Click Recover All. This button appears after an Editor crash.

Deleting a Session

If you want to free up disk space, you can delete old Recovery Hub sessions you no longer need. To do this, follow these steps:

Open Recovery Hub. From the main menu, go to Tools > Recovery Hub.

From the Sessions panel, select a session to recover.

Click the Delete button.

Steps

End Result

Unreal Engine's templates offer a powerful starting point for your projects. You can use them to quickly start developing for a specific platform or to create a specialized project, such as a multi-display experience.

With Unreal Engine, you can also create custom templates from existing projects to meet your specific needs.

A custom template is an Unreal Engine project configured such that the engine includes it in the list of templates that appears when you create a new project.

Custom templates can include content, settings, and code, and can have specific plugins enabled or disabled by default.

Steps

In the instructions below, [ProjectName] refers to your Unreal Engine project's name (for example, MyProjectName.uproject). This is different from the ProjectName variable (without square brackets) in the DefaultGame.ini file.

To convert an existing project into a template:

Copy the entire project's folder into the Templates folder of your Unreal Engine installation. If you installed Unreal Engine from the Epic Games Launcher, the Templates folder will be located at:

C:\Program Files\Epic Games\UE_[version]\Templates on Windows

/Users/Shared/Epic Games/UE_[version]/Templates on Mac

If you compiled Unreal Engine from source, the Templates folder will be located at [ForkLocation]\UE4\Templates.

Open the [ProjectName]\Config\DefaultGame.ini file. Then, add or update the ProjectName variable. This is the name that will display in the template selection screen when you create a new Unreal Engine project.

Example:

Note that the ProjectID variable is a unique ID generated for each project.

From your Unreal Engine installation folder, go to Templates\TP_FirstPerson\Config\. Copy the TemplateDefs.ini file to the [ProjectName]\Config folder.

You can use any existing template folder instead of TP_FirstPerson, as long as it has a TemplateDefs.ini file.

Open the TemplateDefs.ini file you copied in the previous step and update the LocalizedDisplayNames and LocalizedDescriptions variables. There are four sets of variables, one for each language Unreal Engine supports: English (en), Korean (ko), Japanese (ja), and Simplified Chinese (zh-Hans).

Example:

When you create a new project, your template will appear in the category specified in the TemplateDefs.ini file. This is controlled by the Categories variable. Despite the variable name, a template can only have one category assigned to it.

The possible options are:

Games - Games

ME - Film, Television, and Live Events

AEC - Architecture, Engineering, and Construction

MFG - Automotive, Product Design, and Manufacturing

For more information, open the TemplateCategories.ini file in the [UE installation path]\UE_[Version]\Templates folder.

You can add an icon and a preview image in the [ProjectName]\Media folder. These images must use the PNG format and follow the naming conventions below:

Icon: [ProjectName].png.

Preview: [ProjectName]_Preview.png.

End Result

You should now see the new template in the New Project dialog.



A new custom template called My Test Template can be seen in this instance of the Unreal Project Browser.

To see new templates, you only need to close and open the New Project window. However, if you make any changes to an existing template (for example, if you change its name or description), you must restart Unreal Engine before the changes are displayed in this window.

Static Mesh Actors

Skeletal Mesh Actors

Lighting the Environment

Sound Sources

A Level is all or part of your game's "world". Levels contain everything a player can see and interact with, like environments, usable objects, other characters, and so on. In video games, it's common to have multiple levels with clearly delineated transitions between them (for example, once you beat the final boss in a level, you move on to the next one). For other types of interactive experiences made with Unreal Engine, you might use different Levels to transition between different kinds of showcases or environments.

Unreal Engine saves each Level as a separate .umap file, which is why you will sometimes see Levels referred to as Maps.

Here is a minimal list of elements that come together to create a Level:

A .umap file, which is the Level itself. Think of it as a container that holds everything else.

An environment made of Static Mesh Actors. These can be trees, rocks, walls, or any other environment fixture. Some environments also use other types of Actors, such as Landscape Actors or Water Actors.

A player character represented by a Skeletal Mesh Actor.

One or more lights of different types.

Ambient sounds and sound effects (for example, footstep sounds).

Complex levels can contain other features like particle effects, visual post-processing, Level Streaming, and so on.

If you would like to see what an advanced Unreal project looks like, have a look at the Stack O Bot example game on the Unreal Engine Marketplace.

The pages below can teach you more about how to create and work with Level Assets in Unreal Engine 5.



How to create, save, and open Level assets in UE4



Use the Levels window to manage your persistent level and sublevels.



The World Settings panel is where you set and override Level-specific settings.



How to set the default editor and game Levels for your project

Creating Levels

Saving Levels

Opening Levels

Like many other kinds of Unreal Engine data, Levels are stored in individual Asset files. You can perform many of the common Asset operations on Level Assets. However, there are some special considerations that you need to keep in mind. These will be detailed below.

This page covers the following workflows:

Creating Levels

Saving Levels

Opening Levels

Creating Levels

To create a new Level in Unreal Engine, you can use any of the following methods:

From the main menu, go to File, then select New Level.

Right-click in the Content Browser. Then, under Create Basic Asset, select Level.

Use the Ctrl + N (Windows) or Cmd + N (Mac) keyboard shortcut.

Any of these actions opens the New Level window shown below.



The New Level window displays all the Level templates available. You can choose from the following templates:

Open World: A Level with sample content that uses the World Partition feature to create a large, streamable open world.

Empty Open World: A Level that uses World Partition but does not contain any content.

Basic: A Level with a floor plan, lighting, atmosphere, and exponential fog.

Empty Level: A Level with nothing in it.

Select the level you want to use from this window, then click Create. The new Level will open automatically.

When connected to source control, new Levels that you create and save will be automatically added to source control.

Saving Levels

Like any Asset, you need to save a Level to keep your changes when you close Unreal Engine or switch to another Level.

To save a Level, you can use any of the following methods:

From the main menu, go to File, then select Save Current Level.

Use the Ctrl + S (Windows) or Cmd + S (Mac) keyboard shortcut.

The first time you save a Level is slightly different. You need to specify where you want to save the Level Asset, and what to name it.



The Save Level As window behaves the same as any other file save dialog. Give your Level Asset a name, select the folder where you want to save it, and click Save.

To save a copy of a Level under a different name, you can use any of the following methods:

From the main menu, go to File, then select Save Current Level As.

Use the Ctrl + Alt + S (Windows) or Cmd + Option + S (Mac) keyboard shortcut.

Changing Levels will prompt you to save your current Level(s) with the Save Content dialog.

Opening Levels

To open a Level, you can use any of the following methods:

From the main menu, go to File, then select Open Level and choose the Level to open.

Use the Ctrl + O (Windows) or Cmd + O (Mac) keyboard shortcut.

Levels

World Partition

Adding New Sublevels

Moving Actors Between Levels

Level Details

Visualizing Sublevels

When working on Unreal Engine 4 legacy projects or non-game projects such as architectural visualization, you can use the Levels window for level management. For game development in Unreal Engine 5.0 and beyond, the Levels window has been made obsolete by World Partition. This page covers managing multiple levels through the Levels window.

The steps uses the Architecture template as a reference.

You can access the Levels window from the Windows menu.



You will always have a Persistent Level, and you can have one or more sublevels that are always loaded or are streamed in with Level Streaming Volumes, Blueprints, or C++ code. The Levels window shows all of these levels, enabling you to change which level is current (indicated in bold blue text), save one or more levels, and access Level Blueprints. If changes are made in the Level Editor's Viewport, you will modify the current Level. You can use this window to work on multiple maps, as long as they are all writeable.



By right-clicking on the Persistent Level, you can perform operations like making it the current level, changing its visibility and lock status, and selecting all the Actors in that level.



Right-clicking on any sublevel provides similar options, with additional entries for removing the sublevel and changing its streaming method.



Changing a Level's visibility is for visualization purposes only and does not effect whether or not a level will stream into the game when it is run. However, a Level that is not visible here will not be affected if you rebuild the Level, which can be a great timesaver if you have complicated levels.

Adding New Sublevels

You can create sublevels by splitting off part of an existing Persistent Level or sublevel, by creating a new Level, or by adding an existing Level. Adding a new sublevel makes it the current Level, so if you want to continue working in the level you were using before the addition, make sure to right-click on it and select Make Current from the context menu.

Adding an Existing Level

Click on the Levels dropdown menu, then select Add Existing to add a new sublevel.



Select your Level to add in the Open Level dialog, then click on Open.



Creating an Empty Sublevel

Click on the Levels drop-down menu, then select Create New to create a new blank Level.



Choose to create a blank level or template



Select a save location and a name for your Level, then click on Save.



The new Level is added as a sublevel of your current Persistent Level, and it will also be the current Level for working in the Viewport.

Splitting Off Sublevels

If you've already created a Level, and later decide you want to split part of that Level off for streaming or for collaboration with a team, you can use it to create a new Level with Actor.

Select the Actors you want to move to the new Level in the Scene Outliner or in the Viewport.

In the Levels window, click on the Levels drop-down menu, then select Create New with Selected Actors to create a new Level.



Select a save location and a name for your Level, then click on Save.



All your selected Actors will be removed from their original Level and added to the new one, which will be added as a sublevel of your current persistent Level and made the current Level for working in the Viewport.

If you are moving an Actor that another Actor that remains in the persistent Level references, you will get a pop-up message asking if you really want to delete it from the persistent Level.



Moving Actors Between Levels

While you can copy Actors from your active Level, then switch active Levels to paste Actors, there is a simpler way to move Actors between Levels.

Select the Actors you want to move to the new level in the Scene Outliner or in the Viewport.

Right-click on a Level in the Levels window, then select Move Selected Actors to Level from the context menu.



Press Ctrl+S to save all Levels.

Level Details

The Level Details button is indicated with a magnifying glass in the Levels Window, and provides you access to additional information about your current Levels. To set Level Streaming Volumes, you need to open the Level Details for your streaming Levels; for more on this process, see Level Streaming Volumes Reference.



No additional details are visible for persistent Levels, although there is a drop-down menu you can use to change to another Level.



For sublevels, you can set the Level's offset Position and Rotation, the Streaming Volumes to use, and the debug Level Color. Advanced settings like the minimum time between unload requests to improve performance are also accessible here.



Visualizing Sublevels

You can set the color of sublevels either in the main Levels window or in the Level Details window.

To toggle showing the level color, use the Show button on the viewport, then select Advanced > Level Coloration.



The persistent level will be shown in white, while all sublevels will be indicated in their selected colors. Level Coloration works in perspective and orthographic viewports, and will be toggled off with Game Mode.



Precomputed Visibility

Game Mode

Lightmass

World

Physics

Broadphase

HLOD System

World Partition Setup and World Partition

Navigation

VR

Rendering

Audio

Tick

AI

Cooking

Each Level can have unique settings applied to it from the World Settings panel. You can use this panel to do everything from making sure the right Game Mode is activated when you play the Level to adjusting how global illumination works for that Level.

To open the World Settings panel, from the main menu, go to Window, then select World Settings.



Default location of the World Settings panel. Click the image for full size.

The World Settings panel docks next to the Details panel in the editor UI by default. From here, you can now specify the settings for the current Level.

Use the Search box to quickly find a setting.



World settings are split into groups based on which aspects of your Level they influence. Some of these settings are general, such as those affecting the Game Mode and navigation. Other, more specialized groups of settings are used to configure your game's lighting, audio, physics, and so on.

You can adjust the following groups of settings:

Precomputed Visibility

Precomputed visibility volumes reduce rendering thread time at the cost of runtime memory. This helps optimize your game's performance when you work with smaller levels or target a platform where dynamic occlusion culling may be limited depending on hardware, such as mobile. It doesn't scale well for larger, more complex environments.

For more information, see Precomputed Visibility Volumes.

Game Mode

This is where you select and configure a Game Mode for your current Level. Game Modes define the rules of your game, such as players number, score, or win conditions. You can choose from existing Game Modes that come with the project template you used, or create custom ones.

After you select a game mode from the GameMode Override drop-down, you can configure settings specific to it.

For more information, see Setting Up a Game Mode.

Lightmass

In this section, you specify Lightmass settings, such as the detail and quality of indirect lighting and whether to use ambient occlusion (that is, simulating soft shadows from indirect lighting, which can add depth to your scene).

To learn more about Lightmass, as well as the different settings you can configure, see Global Illumination.

World

These settings affect core aspects of your game world, like level bounds, navigation systems, and the depth an Actor can fall to before it is destroyed.

For more information on different areas inside this section, see:

World Composition

Level Streaming Volumes Reference

Physics

Use this section to override the World Gravity, which affects certain Z-axis actions, such as how high up a character can jump or the fall speed of objects.

You can also specify more advanced settings here, such as a default physics volume class and a physics collision handler class.

To learn more about physics in Unreal Engine 5, see Physics.

Broadphase

This section contains settings for Broadphase collision, which is a feature of NVIDIA's PhysX system. You can specify whether to use Broadphase client- or server-side.

Unreal Engine implements Multi-Box Pruning, which splits up the Broadphase into a grid of boxes whose settings you can control. The MBPBounds and MBPOuter Bounds sections control the bounds for the multibox.

The space inside MBPBounds is divided by the MBPNumSubDivs value to create the grid. For example:

If MBPNumSubDivs = 2, this creates a grid of 4 cells (2 x 2).

If MBPNumSubDivs = 3, this creates a grid of 9 cells (3 x 3).

If a physically active object falls outside the bounds specified by the MBPOuterBounds, it is no longer considered for collision. Enabling the Use MBPOuter Bounds option creates four specialized cells at the edges of the multibox grid.

To learn more about this system, see NVIDIA's documentation on Rigid Body Collision.

HLOD System

In this section, you can enable Hierarchical Levels of Detail (HLODs).

HLODs can replace multiple Static Mesh Actors with single, combined Static Mesh Actor at long view distances. This 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.

To learn more about working with HLODs, see Hierarchical Level of Detail.

World Partition Setup and World Partition

World Partition is a new data management and distance-based level streaming system that provides a complete solution for large world management. The system removes the previous need to divide large levels into sublevels by storing your world in a single persistent level separated into grid cells, and provides you with an automatic streaming system to load and unload those cells based on distance from a streaming source.

To learn more about World Partition and how to configure its settings, refer to the World Partition section of the Unreal Engine 5 Early Access documentation.

Navigation

Configure the navigation grid used in your Level.

VR

Use the World to Meters variable to adjust the scale of your virtual world. Increasing or decreasing this number will make the user feel larger or smaller in relation to the world around them. This setting is expressed in Unreal Units (UU). Inside of UE4, 1 Unreal Unit (UU) is equal to 1 Centimeter (cm).

Assuming your content was built with 1 Unreal Unit = 1 cm, setting World To Meters to 10 will make the world appear to be very large, while setting World To Meters to 1000 will make the world appear very small.

To learn more about scaling your VR experience, see VR World Scale.

For a general introduction to XR development in UE5, see XR Development.

Rendering

In this section, you can configure several settings related to distance field ambient occlusion, as well as dynamic indirect shadows.

For more information, see Distance Field Ambient Occlusion.

Audio

Use the settings in this section to configure default sound behaviors in your Project, such as volume, reverb, and fade time.

To learn more about audio and sound in Unreal Engine 5, see Working with Audio.

Tick

Ticking refers to running a piece of code or Blueprint script on an Actor or Component at regular intervals, usually once per frame. Ticking is generally enabled separately for each Actor or Component.

Unless your game is running legacy code that specifically requires the per-frame Tick() update function to run before the one-time initialization BeginPlay() function, you should disable this option to make sure that objects tick correctly.

To learn more about Ticking and Actor behaviors, see



AI

In this section, you can enable Unreal Engine 4's Artificial Intelligence (AI) system.

To learn more about this system, see Artificial Intelligence.

Cooking

Cooking is part of the process of building your game and deploying it to a platform, such as PC or mobile These settings affect how the content in your Scene will be included in your built game.

To learn more about this process, see Packaging and Cooking Games.

In the



Click on the Edit menu to open it.



Select Project Settings.



Selecting the Project Settings option will open up your project's settings.



Click on Maps & Modes in the left panel to open that subsection of Project Settings.



Click on the dropdown arrow to the right of the Game Default Map field, then select your desired Level from the list.



Repeat step 5 if you wish to change the Editor Default Map as well.

In the advanced section of Default Maps, you can set Local Map Options, a Transition Map, and a Server Default Map.

Any piece of content in an Unreal Engine project is an Asset. You can think of Assets like building blocks that you use to create your game and application.

Assets can be of many different types, such as Static Meshes, Materials, particle systems, and sound cues. Some Assets are created outside Unreal Engine (for example, in other 3D applications like Maya or 3ds Max). Other Assets, such as Blueprints, are created directly inside the engine.

You should always manage Assets through the Content Browser.

To learn how to work with Assets in Unreal Engine, refer to the pages below.



Describes two methods of importing small sets of Assets into your Unreal Engine project.



How to create, delete, and manage Assets from the Content Browser.



How to copy Assets from one project to another.



Describes how to create, read, and modify metadata on your Unreal Engine Assets.



Using the Migration Tool to Migrate Assets from Unreal Engine to UEFN.



This document outlines how to the auto-reimport functionality of UE4 works, and how to set it up to get the most out of the feature.



Describes how to use the Reference Viewer tool to quickly find Asset references.



How to remove duplicate Assets by consolidating multiple assets into a single Asset and fixing up references.



Tool for examining Unreal Engine classes and creating child classes.



Tool for viewing and editing multiple properties of multiple Actors at the same time.

Required Setup

Selecting Files to Import

Importing from the Content Browser

Importing Using Drag and Drop

Importing the Assets

Saving the Imported Assets

This page describes two of the most common methods of importing content into Unreal Engine 5. There are other, more advanced methods of importing specialized content, such as using Datasmith to import content from CAD applications. However, for most types of basic content – such as Textures or Static Meshes – the methods described on this page should be enough.

Required Setup

Before you can follow the instructions on this page, download and extract these Sample Assets.

Selecting Files to Import

Importing from the Content Browser

To import one or more Assets using the Content Browser's Import button, follow these steps:

Open an instance of the Content Drawer or Content Browser. To do this, click the Content Drawer button in the lower left corner of the Unreal Editor.



Location of the Content Drawer button. Click the image for full size.

In the Sources panel on the right, from your project's folder tree, select the folder where you want to import your Asset.

If the folder you selected cannot contain any Assets, clicking the Add and Import buttons will have no effect. For example, you cannot import Assets into a project's top-level folder (All, in the screenshot below).



In this example, we have created a new folder called ImportedContent and selected it in the Sources panel.

Do one of the following:

Click the Add button. Then, from the context menu, select Import to [folder path].



Click the image for full size.

Note that the folder path displayed in this menu option is different from what you see in the folder tree of the Content Browser. /Game/ is the equivalent of All/Content/.

You can also open this context menu by right-clicking inside the folder window in the Content Browser, or by right-clicking any folder in the tree and hovering over Add/Import Content.

Click the Import button.



In the window that opens, browse to the folder where you extracted the downloaded Sample Assets. Click and drag to select all four of the files in this folder, then click Open.



After you click Open, Unreal Engine will display a dialog with import options for the Assets you selected. Refer to the Importing the Assets section below.

Importing Using Drag and Drop

To import one or more Assets using drag and drop, follow these steps:

Open an instance of the Content Drawer or Content Browser. To do this, click the Content Drawer button in the lower left corner of the Unreal Editor.



Location of the Content Drawer button. Click the image for full size.

In the Sources panel on the right, from your project's folder tree, select the folder where you want to import your Asset.

If the folder you selected cannot contain any Assets, clicking the Add and Import buttons will have no effect. For example, you cannot import Assets into a project's top-level folder (All, in the screenshot below).



In this example, we have created a new folder called ImportedContent and selected it in the Sources panel.

Open your operating system's file manager (Windows Explorer on Windows, or Finder on macOS). Then, navigate to the folder where your Assets are located.

Select your Assets, then drag and drop them into the Content Browser.



Click the image for full size.

After you click Open, Unreal Engine will display a dialog with import options for the Assets you selected. Refer to the Importing the Assets section below.

Importing the Assets

Regardless of the method you used, after you selected the files you want to import, the Import Options window will appear. These options will change depending on which type of file you are importing. For example, the screenshot below shows import options for an FBX file.



To learn more about these import options, refer to the FBX Import Options Reference page.

To complete the import process, you can either:

Click Import All to import all of the selected Assets.

Click Import for each individual Asset if you want to configure their settings separately.

During the import process, a dialog box will appear in the lower right corner of your screen informing you that T_Rock_04_n.TGA was imported as a normal map. This is because Unreal Engine automatically detects some Texture types, like Normal maps, and imports them as the correct Asset type. Click OK to close this dialog box.



Unreal Engine creates .uasset files in your project that hold the contents of each file you imported.

Saving the Imported Assets

After you finish importing your Assets, you will notice that their icons are marked with an asterisk (*) in the Content Browser. The asterisk means that the Assets are not saved yet.

Unreal Engine doesn't move the files you selected into your project folder. Instead, it creates .uasset files to store the newly imported Assets.



Click the Save All button in the Content Browser's menu bar to save the imported Assets.



A dialog will appear that lists all of the unsaved Assets and gives you the choice to select which ones you want to save by enabling or disabling the checkbox next to that Asset's name.

Select the Assets you want to save, then click Save Selected.



After you save the Assets, you'll notice that the asterisks on their icons have been removed, indicating that the Assets have been successfully saved.



Unreal Engine saves all the .uasset files that were created after import.

Sources Panel Reference

Creating Assets

Asset References

Viewing Asset References

Copying Asset References

Replace References Tool

Managing Assets

Moving and Copying Assets

Deleting Assets

Exporting Assets

In Unreal Engine 5, you can create, delete, and manage Assets directly from the Content Browser. This page describes common Asset workflows, and explains what Asset references are and how to handle moving or deleting your Assets in the editor. Further, you will explore how to export some types of Assets from Unreal Engine into a format that other applications can import.

Creating Assets

To create a new Asset, right-click inside a blank area of the Content Browser. Then, from the context menu that appears, choose the Asset you want to create. This creates a blank Asset of the type you specified. For some Assets, like Blueprints, you can select additional options, like the Blueprint's parent class.



The options in this menu may differ based on your version of Unreal Engine and which plugins you have enabled for your project. Click the image for full size.

Unlike importing Assets, which brings something you made in an external application into Unreal Engine, this method creates a blank Asset which you can populate with content.

Asset References

If an Asset makes use of another Asset in some way, we say that the Assets reference (or have a reference to) each other. For example, if a Cube Actor uses a Color Material, the Actor references that Material. This is why it is important to make sure that references are updated whenever you move or rename an Asset, and that you remove any references to an Asset before you delete it.

Viewing Asset References

To view an Asset's references, right-click the Asset in the Content Browser. Then, from the context menu that appears, select Reference Viewer. A new window will open that displays a visual representation of the Asset's references.



Reference Viewer window for a Material Asset. Click the image for full size.

For more information about the Reference Viewer, refer to the Finding Asset References page.

Copying Asset References

To copy one or more Assets' references to the clipboard, select the Asset or Assets in the Content Browser. Then, right-click your selection and, from the context menu that appears, select Copy Reference.

References contain the Asset type and the path to the .uasset file. They will look similar to the examples below:

This is useful if you need to paste the Asset's reference in a text field, or if you need to generate an external list of Assets.

Replace References Tool

The Replace References Tool provides a way to combine multiple Assets into a single one.

To learn more about this tool, refer to the Replace References tool page.

Managing Assets

To perform common Asset actions, right-click the Asset and select the desired action from the context menu that appears. These actions include:

Action

Description

Edit

Opens the selected Asset in its Editor. For example, performing this action on a Blueprint opens it in the Blueprint Editor.

Rename

Makes the Asset's name editable. To rename the Asset, type a new name and press Enter. After you rename the Asset, Unreal Engine will update all references to the Asset to its new name.

Duplicate

Creates a copy of the selected Asset at the current location. To relocate the copy, drag it to another folder.

Save

Saves the selected Asset.

Show in Folder View

Highlights the Asset's parent folder in the folder tree. Useful for finding the actual location of Assets that are part of a collection.

Show in Explorer (Windows) / Show in Finder (Mac)

Opens an instance of Windows Explorer or Finder at the Asset's location on disk. This is the location of the .uasset file.

Never move, copy, or delete Assets directly on disk, as this might break functionality in your project and lead to data corruption or data loss. Always manage .uasset files through Unreal Editor.

If you need to move an Asset from one project to another, refer to the Migrating Assets page to learn how to do this.

Moving and Copying Assets

You can move or copy Assets and folders in your project through the Content Browser.

The steps to moving or copying an Asset are:

Click the Asset you want to move, then drag it to another folder in the Content Browser or folder tree. As you drag the Asset, a popup window will follow your mouse cursor, indicating which Asset you are trying to move.



When you release the mouse button, a menu will appear.



The menu confirms the folder name and contains a list of three options:

Option

Description

Move Here

Moves the Asset to the new location.

Copy Here

Creates a copy of the Asset at the new location, and leaves the original Asset at its current location.

Advanced Copy Here

Creates a copy of the Asset at the new location, and attempts to automatically resolve all of that Asset's references and dependencies. This option includes an additional save dialog where you need to confirm that you want to save the Asset you copied.

Deleting Assets

To delete an Asset, you can either:

Right-click it in the Content Browser. Then, from the context menu that appears, select Delete.

Select the Asset in the Content Browser, World Outliner, or Level Viewport, then press Delete on your keyboard.

This action will bring up a confirmation window. If your Asset isn't being referenced anywhere (that is, it's not being used anywhere in your Unreal project), click the Delete button to confirm:



If your Asset is being referenced somewhere, the confirmation window will notify you of this and ask you what you want to do. There are two types of referencing that can happen:

If the Asset is referenced by other Assets, it means that another Asset in your project is using this one. For example, if you are trying to delete a Material, and a Static Mesh uses that Material, you will see this warning.

If the Asset is referenced in memory, it could be open in a separate editor window, or it might have been used recently and is still cached in memory.

If you are seeing zero Asset References, but at least one Memory Reference, close all other editor windows and try again. If that doesn't work, save your work and restart Unreal Engine.

In this situation, you have two options:



If you select Replace References, you can choose another Asset to replace this one wherever it is referenced in your project. For example, if a Static Mesh uses a Material, and you want to delete that Material, you can choose a different Material that the Static Mesh will use after the deletion.

If you select Force Delete, the Asset will be deleted without any additional corrections being performed.

This can cause data corruption and data loss. At a minimum, Assets that reference the deleted one will no longer work correctly, but this can break your entire project.

Exporting Assets

Assets in your project are stored on disk as .uasset files, which is a file format specific to Unreal Engine. Exporting an Asset saves it to disk in a format that can then be read by other applications.

To export an Asset from your project, right-click it in the Content Browser. Then, from the context menu that appears, select Asset Actions > Export. This will open a window where you can name your exported Asset and select the location where to save it.

The file type available for export will change depending on the type of Asset you selected. For example, for a Static Mesh Asset, you will see the options to export it as an FBX, OBJ, COPY, or T3D file.

Not all Assets can be exported.

If you want to use the same Assets across multiple projects, use the Migrate tool to copy the Assets, along with their references and dependencies. For example, if you migrate a Material, any Texture Assets that define that Material will automatically be copied along with it. This is useful when you need to merge or fork projects, or when transitioning from a test environment into a production project.

To use the Migrate tool, follow these steps:

From the Content Browser, select the Asset or Assets you want to migrate.

To select multiple Assets, hold down Ctrl and left-click each Asset you want to select.

If you want to select a range of Assets, left-click the first one, then hold down Shift and left-click the last one. This selects all Assets between the fist and last one.



In this example, we have selected four Material Assets.

Right-click any of the selected Assets. From the context menu that appears, select Asset Actions > Migrate.

This opens the Asset Report window, which shows all of the Assets that will be copied as part of the migration process.



If you don't want to migrate an Asset in this list, uncheck the checkbox next to that Asset. Keep in mind, however, that this might break other Assets you are trying to migrate (for example, a Material will no longer show correctly if one of its Textures is missing).

Click OK to confirm that you want to migrate the Assets. This will open a file browser window where you can select the project to migrate the Assets to (also known as the target project).



Select the Content folder in your target project, then click the Select Folder button.

After you confirm the migration, a progress bar will appear to track the migration progress.

If the target project's Content folder contains an Asset with the same name as an Asset you want to migrate, you will see the following warning:



Click Yes to overwrite the Asset, or No to skip the Asset and continue migrating the others. You can also make this choice for all Assets by clicking Yes All or No All.

Once the migration completes, you will see a dialog confirming that all Assets have been migrated. Click Show Message Log in this dialog to view a full list of migrated Assets.



Troubleshooting Asset Migration

If you attempt to migrate Assets into anything other than an Unreal project's Content folder, you will receive the following message:

If you want to be able to use your migrated content in the target project right away, click No, then select that project's Content folder.

If an Asset doesn't display correctly after migration, make sure that you also migrated all of its dependencies. Check if the Asset displays correctly in the original project, then reattempt the migration and make sure all of the Asset's dependencies are selected in the Asset Report window.

Using Metadata in the Unreal Editor UI

Viewing Metadata on Assets

Filtering the Content Browser

Working with Asset Metadata

You can assign metadata to any Asset in your Unreal Engine Project, to record information about that specific Asset that you might need to make use of later on. This metadata is a set of key-value pairs that you can define freely for your own purposes.

For example, metadata could include things like the name of the Asset's creator, the intended usage of the Asset in your Project, or the status of the Asset in your team's workflow (like In Progress, Done, Approved, and so on).

Once set, you can use this metadata to help filter Assets in the Content Browser, or to identify Assets in Blueprint or Python scripts that you run in the Unreal Editor.

Because this metadata is assigned to the Assets in your Project, you can't access it directly in your runtime gameplay code. It is intended primarily for scripting Asset management operations in the Unreal Editor.

You can also import metadata that you've created in some third-party applications into Unreal Editor along with your Assets. For details on how to get metadata into the Unreal Engine through the FBX import process, see FBX Asset Metadata Pipeline.

Using Metadata in the Unreal Editor UI

Although you can't currently modify metadata in the UI Unreal Editor, you can view the metadata attached to any Asset, and you can use metadata keys to filter the Assets shown in your Content Browser.

Viewing Metadata on Assets

To view the metadata assigned to any Asset, right-click the Asset in the Content Browser, and choose Asset Actions > Show Metadata.



You'll see a list of all the keys and values attached to that Asset:



Filtering the Content Browser

To filter the Assets in the Content Browser by specific metadata tags:

Open the Project Settings window by choosing Edit > Project Settings from the main menu.

Select the Game > Asset Manager section, and find the Asset Registry > Metadata Tags For Asset Registry setting. Add to this list the names of any keys you want to be able to use for filtering Assets.



Click for full image.

In the Filters bar of the Content Browser, type the tag name followed by =, followed by the value you want to search for. The list of Assets is automatically filtered to only show Assets that contain the metadata tag you specify, and for whom the value of that tag matches the value you type after the =.

Working with Asset Metadata

You'll need to install the Editor Scripting Utilities plugin if you haven't already. For details, see Scripting and Automating the Editor.

Choose your implementation method:

Blueprints

Python

You'll find the nodes you'll need to manage Asset metadata under the Editor Scripting > Metadata category.

To use these nodes, your Blueprint class must be derived from an Editor-only class, such as the PlacedEditorUtilityBase class. For details, see Scripting the Editor using Blueprints.

The Asset you want to work with has to be loaded before you can work with its metadata. You can use the Editor Scripting > Load Asset node to do that. If you set or remove metadata values, you'll also need to use a node like Save Asset or Save Loaded Asset afterward if you want to keep your changes.

Getting Metadata from an Asset

If you know the name of the metadata key you want to retrieve, you can use the Get Metadata Tag node. For example, this script retrieves the value of a single tag by name, and prints it to the Viewport:



Click for full image.

You can also use the Get Metadata Tag Values node to retrieve all of the metadata as a map of tag-value pairs. For example, this script retrieves all metadata for an Asset, and writes each key and each value to the Viewport in order:

Click for full image.

Setting New Metadata Tags

Use the Set Metadata Tag node. For example:



Click for full image.

If the tag name you specify does not already exist in the Asset's metadata, it is added with the value you specify. If the Asset already has a tag with the name you specify, the value of that tag is updated.

Removing Existing Metadata

Use the Remove Metadata Tag node, and provide the tag name you want to remove. For example:



Click for full image.

If you want to remove all metadata tags from an Asset, you can call this node in a loop:



Click for full image.

You'll find the functions you need for managing metadata in the unreal.EditorAssetLibrary class.

The Asset you want to work with has to be loaded before you can work with its metadata. You can use unreal.EditorAssetLibrary.load_asset() to load the Asset from its filename in your Project content. If you set or remove metadata values, you'll also need to use a function like unreal.EditorAssetLibrary.save_asset() or unreal.EditorAssetLibrary.save_loaded_asset() afterward if you want to keep your changes.

Getting Metadata from Assets

If you know the name of the metadata key you want to retrieve, you can use the get_metadata_tag(asset, tag_name) function. For example, this script retrieves the value of a single tag by name, and prints it to the log:

You can also use the get_metadata_tag_values(asset) function to retrieve all of the metadata assigned to an Asset as a dictionary. You can then loop through the keys and values. For example, this script retrieves all metadata for an Asset, and writes each key and each value to the log in order. Note that the keys in this dictionary are not actually strings, but unreal.Name objects. You can coerce these objects to strings using the built-in str() function.

Setting New Metadata Tags

Use the set_metadata_tag(asset, tag_name, value) function. For example:

If the tag name you specify does not already exist in the Asset's metadata, it is added with the value you specify. If the Asset already has a tag with the name you specify, the value of that tag is updated.

Removing existing metadata tags

Use the remove_metadata_tag(asset, tag_name) function, and provide the name of the tag you want to remove. For example:

If you want to remove all metadata tags from an Asset, you can call this function in a loop:

Using the Migration Tool

Limitations

You can use content originally created in Unreal Engine 5 (UE5) in Unreal Editor for Fortnite (UEFN). UEFN supports a wide range of UE5 asset types.

The preferred asset migration workflow is to use the Migration Tool in the Unreal Editor, and select the Content folder in your UEFN project as the target destination.

This migration path provides a means to reuse your previously-saved assets from UE5 in new UEFN projects, while also leveraging the new features and Fortnite content available in UEFN.

UEFN does not support all of Unreal Engine's asset types. Further, some supported asset types have additional limitations to comply with Fortnite performance requirements. For example, Static Mesh assets should not exceed 20k vertices. Read about UEFN asset limitations here.

Using the Migration Tool

The Migration Tool was updated in Unreal Engine 5.1 to support UEFN as a target destination.

Prerequisites

To move content from UE to UEFN with the Migration Tool, your projects must meet the following minimum version requirements.

Source — An Unreal Engine project running in UE 5.1 or newer.

Destination — A UEFN project running on Fortnite 23.00UEFN or newer.

Procedure

Use the following steps to migrate content from UE to UEFN with the Migration Tool.

Open the Unreal Engine project from which you want to migrate assets.

Right-click an asset or folder in the Content Browser to display the context menu and select Asset Actions > Migrate.



Review the Asset Report dialog and click OK to confirm you want to migrate the selected assets. For assets with dependencies, such as a Static Mesh with associated Materials and Textures, the entire dependency tree is displayed. You can uncheck any assets you don't want to migrate, but be aware that you can break asset references if you do this.



In the file browser dialog, open your UEFN Project folder. Navigate to Plugins > Project Name > Content, and click Select Folder.



You must select the base Content folder of the UEFN Project, otherwise the migration will fail. If the asset or its dependencies are located deeper in your UE5 folder hierarchy, those additional folders are automatically created in the UEFN project.

The asset and its dependencies appear in the Content Browser of your UEFN project. You can now drag the asset into your Level.



Limitations

The Migration Tool is not aware of the content limitations of the destination, so it cannot perform any sort of asset validation when you attempt to migrate content. In other words, the Migration Tool will migrate your assets whether or not they are actually compatible with UEFN.

As noted above, UEFN has many asset limitations. For example, some asset types cannot exceed a certain size, and some UE5 asset types are not supported at all.

The current implementation of the Migration Tool needs to load all the assets in memory to migrate them. This tool is in active development. We expect to provide performance improvements and a better user experience for validating and cleaning up incompatible content in the future.

Setup

Auto reimporting in Unreal Engine 4 allows you to work in your external content creation package and have any saved changes automatically reflected inside Unreal Engine 4 without any user input. This can be a huge productivity win where you are iterating on a particular asset, and need to see the changes reflected in your game immediately.

UE4 monitors a set of user-defined folders for changes to source content files. Where a file has changed, and that file was used to import an asset in your game, Unreal Engine 4 will automatically reimport the changed file into its dependent asset(s).

Setup

Auto Reimport settings exist under Editor Preferences > Loading & Saving > Auto Reimport:



The feature can be entirely enabled and disabled with the Monitor Content Directories checkbox.

Using the default settings, it is recommended that you place all source content files alongside their relevant assets in the Content folder. Custom configuration will be required for any other workflows.

Property

Description

Directories to Monitor

This setting defines which folders Unreal Engine 4 will monitor for changes. Folders can be virtual paths (for example /Game/Textures), or absolute paths (C:/Game/SourceArt/). Only source content files that reside inside these folders will be eligible for auto-reimport.

Include/Exclude Wildcards

By default, Unreal Engine 4 will detect any changes to any files, and reimport them as necessary. Sometimes it's useful to limit this to only work on certain file types, or perhaps exclude a certain subfolder or extension. Multiple wildcards must be added as new entries. Here are some example configurations:

To include only fbx files, add a new include wildcard with the value *.fbx

To operate on fbx, png and psd files, add 3 new include wildcard with the values .fbx, .png, and *.psd

To ignore changes to any source files in a subfolder, add an exclude wildcard with the value Subfolder/*

Import Threshold Time

Specifies the amount of time (in seconds) to wait after a change has been detected before processing the change.

Auto Create Assets

Determines whether a newly created file should automatically have an asset created for it. In order for this to work, you must be monitoring a virtual path (e.g. /Game/) or have specified a mount point (which determines where to create the new file)

Auto Delete Assets

Determines whether deleting a source content file should also delete its associated asset in UE4. This will only happen where there is a 1-1 mapping between source file and asset.

Detect Changes on Restart

Unreal Engine 4 is able to detect changes to files that have occurred since UE4 was shutdown. Any such changes will be processed when UE4 is reopened. This specific functionality may not be desirable where source control is enabled that will update source content. In this environment it is recommended that Detect Changes on Restart is turned off to avoid the potential of redundant reimporting after getting latest.

Search Options

Context Menu Options

Reference Tree Tool

Using the Reference Tree

Options

View Menu

Options Menu

Context Menu

Notes

The Reference Viewer displays a graph of assets that reference or are referenced by any assets that are currently selected in the Content Browser.

To display the Reference Viewer, right-click a selected asset (or assets) in the Content Browser, and, on the context menu that appears, click Reference Viewer.



Other assets that reference the selected asset(s).

The selected asset(s).

Other assets that are referenced by the selected asset(s).

You can also access the Reference Viewer by right-clicking a folder in the Asset Tree. The Reference Viewer will display a graph of references for all assets in that folder.

For more information about the Content Browser, see Content Browser.

Search Options

In the upper-left corner of the Reference Viewer, you can see two options related to the search used by the Unreal Editor to build the graph.



Item

Description

Search Depth Limit

The depth to which the engine will search for references. For example, a value of 2 means that the graph will display not only the assets related to the selected asset, but also the assets that are related to those related assets.

Search Breadth Limit

The number of references listed in a given column (reference or referenced by). For example, if an asset references 20 assets, but the value of the Search Breadth Limit is set to 10, only 10 assets will be displayed in that column.

Context Menu Options

To view options for an asset in the graph, right-click the asset. A context menu will appear.

Item

Description

Find in Content Browser

Finds the selected asset in the Content Browser.

Re-Center Graph

Recreates the graph around the selected asset, with assets it references and is referenced by.

List Referenced Objects

Displays a list of assets referenced by the selected asset.

List Objects That Reference

Displays a list of assets that reference the selected asset.

Make Collection With Referenced Assets

Creates a Collection with the assets that reference and are referenced by the selected asset.

Show Reference Tree

Displays a Reference Tree for the selected asset. Note that depending on the complexity of your game, this may take some time.

Reference Tree Tool

The Reference Tree is a tool that allows you to list the reference chains for a specific asset. A reference chain is a list of references in which each object in the list references the objects below it in the list. The Reference Tree Tool allows you to easily find how objects are being referenced.

In the following image, you can see that the root of the tree is a Material named M_RTS_Env_Lava_01. The root of the tree is always the object being examined. You can see that the Material is referenced by six Static Mesh Actors.



Using the Reference Tree

You can access the Reference Tree from the Reference Viewer, which is a tool that displays a graph of asset dependencies. To open the Reference Viewer, right-click an asset in the Content Browser, and then click Reference Viewer.

In the Reference Viewer, if you right-click an asset in the graph to display its context menu, you can then click Show Reference Tree, which will display the Reference Tree for that asset.

For more information about the Reference Viewer, see Finding Asset References.

The initial load of the Reference Tree window may take several seconds, depending on how complex your game is and how many objects you have. Although the Reference Tree can be a useful tool, if you want to see the dependencies between assets, you may be able to find the information you want in the Reference Viewer itself, which typically loads more quickly than the Reference Tree.

Options

Rebuild Tree - Regenerates the tree and examines all loaded objects. This may take some time, but it is useful if you have changed references to the asset being examined.

Expand All - Expands all nodes in the tree.

Collapse All - Collapses all nodes in the tree.

Show Script Objects - Displays script objects (references to assets in script), which are not displayed by default.

If you right-click an item in the Reference Tree, you will see a context menu with the available options.

Open Editor - Opens the asset in the appropriate asset editor. (For example, a Static Mesh would be opened in the Static Mesh Editor.)

Show in Content Browser - Browses to the asset's location in the Content Browser, and selects it.

Double-clicking the asset in the Reference Tree also browses to the asset's location in the Content Browser and selects it.

Notes

The Reference Tree Tool only shows browsable Objects or Actors.

Due to performance reasons with the tree, only the first 100 items in each leaf of the tree are shown. If there are more than 100 items, a node will be added saying how many more there are.

This tool is currently a work in progress.

Using the Replace References Tool

Invoking the Replace References Tool

Consolidating Assets

Saving Dirtied Packages

How the Replace References Tool Works

Best Practices

Limitations and Caveats

The Replace References Tool provides a simple way within the editor to combine multiple assets into one asset. As an example, consider a texture that has become duplicated numerous times over the course of development, resulting in a waste of resources by storing multiple copies of what amounts to the exact same texture. The Replace References Tool allows the user to select all such uses as desired and have them all point to one particular instance of the texture instead.

While this has been greatly reduced by the Unreal Engine's ability to just re-import the source asset, if you attempt to add the exact same file twice (same name and path), it can still happen with multiple people working on a game.

Using the Replace References Tool

The asset consolidation is fairly simple to use, but caution must be exercised to utilize it properly.

Invoking the Replace References Tool

To gain access to the tool, you simply select at least one asset you wish to use in the consolidation process within the Content Browser. Afterwards, right-click, and within the context menu that appears, click "Replace References." The Replace References dialog will appear, populated with all of the assets that were selected while summoning the tool. You can add additional assets by dragging them from the Content Browser into the main part of the dialog.

Consolidation is generally restricted to selected objects of the same type, with some exceptions allowed for Textures and Materials. If you do not see the Replace References option, or a drag-drop operation was not allowed, you should make sure you have only selected assets of the same type! If you have accidentally added an asset that you did not intend, you can remove it from the dialog by selecting it and pressing the Delete key on your keyboard.



Here a texture has been duplicated many times! Selecting them all and right-clicking grants the option to Replace References.

Consolidating Assets

Once you have populated the dialog with all of the assets you would like to use in the consolidation process, select one of the assets to serve as the "asset to consolidate to" and then click Consolidate Assets. All references to the assets you did not choose from the list will be replaced with references to the asset you did, deleting the non-chosen assets in the process.

The Consolidate Assets button is grayed out (and unavailable) until at least two assets are in the dialog and at least one is selected.



Inside the Replace References dialog, selecting an asset marks it as the "asset to consolidate to."



Upon clicking Consolidate Assets, you will be prompted with a Delete Assets dialog, which enables you to remove assets that are no longer referenced and thus no longer necessary. Click Delete.



All of the duplicates have been consolidated to the chosen asset!

Saving Dirtied Packages

The consolidation dialog provides the option to Save dirtied packages, in the lower-left corner. If you check this option, you will be prompted upon the completion of a consolidation operation to save any of the UAssets dirtied by the process. This is a handy way to ensure that all of the UAssets affected by consolidation are properly saved without having to find them all in the Content Browser yourself. If, for whatever reason, a consolidation is unsuccessful or an error occurs, the UAssets will not be saved and you will be warned appropriately.

How the Replace References Tool Works

The actual consolidation process occurs in multiple steps. First, for any valid objects that are to be consolidated, the tool attempts to replace all references of those objects with references to the "object to be consolidated to" within objects/UAssets that are already loaded and in memory. What this means is if you have a map or UAsset already open that is referring to one of the objects to be consolidated, the tool will attempt to update it immediately. Next, the tool attempts to delete the objects to be consolidated directly (there is a potential for this to fail, see Limitations and Caveats). Finally, if the deletion was successful, the tool leaves behind object redirectors in the place of the deleted objects. These will redirect unloaded UAssets with references to the deleted objects to the object you consolidated them to.

Best Practices

Improper use of the Replace References Tool can be extremely dangerous given the nature of what it does. Users of the tool should always think carefully about what they are about to do and decide if the resulting operation would make sense in the context of their assets. The tool attempts to guard against some obviously incorrect consolidations, but users should still always exercise caution in order to avoid ruining UAssets. Keep in mind that the tool will delete consolidated assets and route previous uses of them to the selected Object; it is not an alternative method of doing a "replace Actor"-type operation.

While the Replace References Tool will attempt to forcibly replace references to Objects to consolidate in UAssets/maps that are currently loaded and in memory, it is best to maximize the chance of a successful consolidation by having as few things referencing the Objects to consolidate as possible while using the tool. In particular, it is extremely ill-advised to have sub-editors (such as the Blueprint Editor or the Static Mesh Editor) open and utilizing assets that are about to be consolidated.

The Replace References Tool makes heavy use of object redirectors, meaning it is a good idea to occasionally make use of the Fixup Redirects Commandlet sometime after the use of the Replace References Tool.

Limitations and Caveats

While useful, the Replace References Tool does have some limitations and caveats, outlined below:

To prevent the user from accidentally destroying their work, the Replace References Tool can only be invoked on assets that share the same class/type, with an exception made if all objects are a type of Material or a type of Texture (meaning that a Material could be consolidated to a Decal Material, even though they are not strictly the same type). This restriction is in place to prevent consolidations that would certainly cause crashes, such as consolidating a Material into a Static Mesh. Even where cross-type consolidation is allowed, the tool presents a clearly visible warning that multiple types have been chosen for consolidation.

The Replace References Tool cannot always consolidate the assets the user has selected. If a user selects an "asset to consolidate to" that contains references to one of the assets to consolidate, that particular asset to consolidate will not be consolidated. Allowing such an operation would make the "asset to consolidate to" refer to itself, which would certainly lead to trouble. At the end of a consolidation operation, the user is warned which, if any, of their assets were skipped for consolidation.

The Replace References Tool can sometimes fail to consolidate an otherwise valid asset if not all of its references could be cleared, or it could not be deleted for some reason. This type of failure is critical, resulting in "partial consolidation," in which some uses of an asset have been consolidated and some have not. This type of failure should be quite rare, but should the situation arise, the user is warned with a dialog showing the affected assets and potentially affected UAssets. The user should NOT save any of the affected UAssets or they will be accepting a potentially disastrous partial consolidation.

As mentioned in Best Practices, it is extremely ill-advised to utilize the Replace References Tool while potentially affected assets are being used in various sub-editors, such as Persona or the Blueprint Editor. Ultimately, most sub-editors as of yet do not respond well to having references swapped from under them, so using the sub-editors while consolidating can lead to the sub-editors being put into invalid states and/or potentially crashing.

The Replace References Tool only replaces references to the consolidated objects in UAssets that were already loaded at the time of the operation. It relies on object redirectors to fix up the remaining references in unloaded UAssets. This means care should be taken to not perform an action that will trample on, overwrite, delete, etc. the redirectors, unless specifically desired. Otherwise, some UAssets will correctly be fixed up and some will not. As outlined earlier, making use of the Fixup Redirects Commandlet can alleviate this issue.

For now, once a consolidation operation has been successfully performed, it is advised to save the relevant UAssets before attempting to load into memory any unloaded UAssets that also reference one of the consolidated objects. A currently outstanding Content Browser/Object Redirector "bug" can cause consolidated assets to reappear in the browser if a referencing UAsset is loaded before saving.

Opening the Class Viewer

Class Viewer Interface

Working with Classes

Dragging and Dropping Classes

Using the Class Picker

Configuring the Class Picker

The Class Viewer in Unreal Engine is used to:

Examine a hierarchical list of classes that the Editor uses.

Create and open Blueprints.

Open associated C++ Header files and create new C++ classes based on a specific class.

Opening the Class Viewer

To open the Class Viewer, from Unreal Engine's main menu, go to Tools > Class Viewer.

Class Viewer Interface



The Class Viewer interface consists of the following areas:

Number

Name

Description

1

Filters and Search bar

Use the Filters drop-down to restrict the classes that appear to one or more of the following:

Actors

Placeable Actors

Blueprint base classes

Use the Search bar to find classes by name.

2

Settings button

Click this button to open the Settings menu, which you can use to:

Expand or collapse all classes.

Show or hide internal classes.

Show classes from other developers who use the Developer folder.

3

Classes view

Shows all classes that fit the criteria you selected.

Working with Classes



If a class has children, click the drop-down arrow to the left of the class name (1) to show the children of that class.

Click the drop-down arrow to the right of a class name (2) or right-click the class name to open a context menu with the options below.

The actions you can perform on a class are different based on class type (Blueprint or C++).

Option

Blueprint Class

C++ Class

Create Blueprint

Creates a new Blueprint parented to the selected Blueprint.

Creates a new Blueprint parented to the selected Blueprint.

Edit Blueprint

Opens the selected Blueprint in the Blueprint Editor.

N/A

Find in Content Browser

Finds the Blueprint Actor in the Content Browser.

N/A

Open Source Code

N/A

Opens the class header file in Visual Studio.

Create New C++ Class

N/A

Opens the C++ Class Wizard to create a new class with the selected class as the Parent class.

Dragging and Dropping Classes

Click and drag a Blueprint class from the Class Viewer into the viewport to add a new Blueprint Actor of that class to the currently open Level.

You can also drag any class from the Class Viewer to a combo box in the Details panel or World Settings window, if the class is a child of the class associated with the combo box. For example, you can drag any GameMode child class into the GameMode Override combo box in World Settings.

When dragging classes into a combo box, note that:

Classes that haven't been loaded will not appear in the combo box.

Dropping a class into the combo box will force-load the class.

Using the Class Picker

You can switch the Class Viewer to Class Picker mode using only code. The Class Picker displays a list of available classes, such as for converting Static Meshes or selecting a parent for a new Blueprint.

Using the Class Picker requires knowledge of how to use C++ in Unreal Engine.

Configuring the Class Picker

FClassViewerInitializationOptions, which is used for initializing a Class Picker, has the following options that control Class Picker behavior:

Option

Description

Mode

This is set to ClassPicker by default.

You can change this to ClassBrowsing, which spawns a normal Class Viewer instead. Note that most of the options below don't work in a Class Viewer.

DisplayMode

You can choose from the following options:

TreeView, which shows parent-child relationships between classes.

ListView, which shows a simple list of classes.

You can use the following filters to configure which classes show in the Class Picker:

Filter

Description

bIsActorsOnly

Only shows classes that are children of AActor.

bIsPlaceableOnly

Only shows classes that are placeable in the Level. If this is true, bIsActorsOnly will also be assumed to be true.

bIsBlueprintBaseOnly

Only shows Blueprint base classes. This is useful if you only want to see lasses that Blueprints can be created from.

bShowUnloadedBlueprints

Shows unloaded Blueprints, despite their parents being filtered out due to custom filters.

bShowNoneOption

Shows a None option in Class Picker. Doesn't affect Class Viewer. When you pick an item, a NULL class is passed.

Accessing the Property Matrix

Property Matrix Window

Customizing Property Matrix Columns

Editing Properties

The Property Matrix tool is used to compare and bulk-edit values for multiple objects. With this tool, you can:

View specific properties for a large number of objects in a customizable table view.

Edit different types of objects at the same time.

Identify objects with incorrect settings.

Work with properties of Arrays and Struct types.

Accessing the Property Matrix

There are two ways to access the Property Matrix:

From the Details panel.

From the Content Browser.

From the Details Panel

In the Level Viewport, select one or more Actors.

In the Details panel, click the Open Selection in Property Matrix button, which is on the left of the Search bar.



Click the image for full size.

From the Content Browser

In the Content Browser, select one or more Assets.

Right-click the selected Assets and, from the context menu, select Asset Actions > Bulk Edit via Property Matrix.

Property Matrix Window

The Property Matrix window is divided into three major areas:

Area

Description

Grid

Each row represents an object, identified by its Name in the first column. The rest of the columns display some of the object's properties. To learn how to add or remove columns, see the Customizing Property Matrix Column section on this page.

Display

Shows a list of all available properties and their values. You can also use this panel to edit properties.

Property Editor

Shows a list of editable properties shared by all selected objects.

Customizing Property Matrix Columns

The Property Matrix displays data in a complex table layout, with columns that change based on the type of objects you selected. Unreal Engine attempts to automatically populate the table with useful columns, but you can also customize the columns that display.

To add or remove columns, pin or unpin properties in the Display panel by clicking the Pin button (1) next to the properties you want to display.

Each column has a drop-down menu (2) that appears when you hover the column header. Use this menu to remove a column or to remove all other columns except for the current one. You can also remove a column by middle-clicking its header.

Click a column header to sort the table based on that property.



Customizing column display in the Property Matrix: (1) Pin button, (2) column header drop-down menu. Click the image for full size.

Editing Properties

You can edit properties individually or in bulk, and you can edit the same property for multiple objects regardless of object types.

To edit a property for a single object:

Click a cell to select it.

If the cell contains text, double-click the cell to edit the text. Otherwise, interact with the cell control as you normally would (for example, enable or disable a checkbox, or select a value from a drop-down menu).

(Optional) To preserve your changes, click the Save button in the lower-right corner of the Property Matrix window.

Unsaved objects will have a gray asterisk (*) next to their name.

To edit a property for multiple objects:



Click the image for full size.

Select the objects whose properties you want to edit.

To select one row, click anywhere in that row. To select multiple rows, use Shift + Click for a continuous selection between two rows, or Ctrl + Click to select individual rows.

Find and edit the property you want to edit in the Property Editor.

(Optional) To preserve your changes, click the Save button in the lower-right corner of the Property Matrix window.

Working with Actors

Common Actor Types

An Actor is any object that can be placed into a Level, such as a camera, Static Mesh, or player start location. Actors support 3D transformations such as translation, rotation, and scaling. They can be created (spawned) and destroyed through gameplay code (C++ or Blueprints).

In C++, AActor is the base class of all Actors.

To create a Level, you place Actors into a Level (map), then move and scale them to create an environment, and add script to make them behave the way you want. This section covers the basic techniques of working with Actors, such as placing, selecting, and transforming Actors. It also covers some of the most commonly used Actor types.

Working with Actors



Shows how you can place Actors such as props, lights, and cameras into your Level.



Overview of methods available for selecting Actors in the Level Editor viewport.



How to modify the location, rotation, and scale of Actors in a Level.



Overview of Actor snapping in Unreal Engine.



Setting that controls whether an Actor can move or change in some way during gameplay.



How to create and work with groups of Actors in Unreal Engine.



How to merge two or more Static Mesh Actors into a single Actor in Unreal Engine.

Common Actor Types

This is not a comprehensive list of every Actor type available in Unreal Engine. Some plugins and project templates add their own Actors, and certain Actors may not be available for all projects.



Describes the properties of Physics Volumes in Unreal Engine.



Place Static Mesh Actors in your Level to create your game world.



Use Skeletal Mesh Actors to create player avatars and populate your game world.



Guide to using Brushes to create level geometry in Unreal Engine.



Understanding the fundamentals of Cameras in Unreal Engine.



Audio Volume reference details



Use Player Start Actors to set up starting locations for players.



Actor that can be activated and cause events to occur in the Level.



Reference for the different kinds of Volume Actors in Unreal Engine.



Pain-Causing Volume reference details



A guide to using the Deferred Decal actor.



Guide to placing 3D Text in Unreal Editor and using it to create motion graphics.



Guide to creating and using Target Actors.

Required Setup

Using the Place Actors Panel

Placing Actors Using the Context Menu

Placing Actors Using Drag and Drop

Placing Actors from the Class Viewer

An Actor is any object that can be placed into a Level, from Static Meshes that create your game's environment, to sounds, cameras, player characters, and so on. This page will show you how to place these Actors into your Level so you can bring your world to life.

Placing an Actor into your Level creates an instance of the object the Actor is based on.

Adding Actors to your Level also adds them to the World Outliner, which is located in the upper-right corner of the Unreal Editor by default. Refer to the World Outliner documentation for more information.

Required Setup

Before you can follow the workflows described on this page, you must create a new project and open it in Unreal Editor. The examples on this page will use the Third Person Template, but you can choose any template you like.

Using the Place Actors Panel

This section will show you how to place Actors from the Place Actors panel. To open this panel, from the main menu, go to Window > Place Actor. The Place Actors panel will open at the left-hand side of the Unreal Editor window.



The Place Actors panel in the Unreal Editor. Click the image for full size.

Let's go ahead and place a simple cube into your Level. In the Place Actors panel, left-click the Cube Actor, then drag it into the Level, as shown in the GIF below.



You can do this for any Actor in the Place Actors panel.

Place Actors Panel Interface



The Place Actors panel consists of three major areas:

Search

Filters

Asset View

Use the Search bar to find any Actor by name.

Use these tabs to quickly switch between Actor categories.

Tab

Contents

Recently Placed

Rolling history of up to the last 20 types of Actors you placed in your Level. This history is project-specific.

Basic

Basic Actors such as planes, Pawns, and trigger volumes. Also contains empty Actors and Characters.

Lights

Different types of lights you can place into your Level.

Shapes

Simple primitives (cube, sphere, cylinder, cone, and plane).

Cinematic

A cinematic camera and related Actors that you can use to simulate real-world camera movement.

Visual Effects

Volumes that visually affect part of all of your Level in some way, such as fog, post-processing, and reflections.

Geometry

Geometry brushes you can use to quickly block out or prototype a level.

Use the Add or Subtract radio buttons to change whether the brush adds geometry to the Level or removes existing geometry.

Volumes

All placeable Volume types.

All Classes

All placeable Actors.

This view shows all Assets that correspond to the search or filters you selected.

An Asset is any piece of content within an Unreal Engine project. All Actors are Assets.

Placing Actors Using the Context Menu

This section will show you how to place Actors through a context menu. A context menu is any menu that opens when you right-click inside Unreal Engine.

You will select the Actor you want to place from the Content Browser. The fastest way to open an instance of the Content Browser is to click the Content Drawer button in the lower-left corner of the Unreal Editor window. If you want this instance to persist when it loses focus (when you click away from it), click the Dock in Editor button in its upper-right corner.



The Content Browser in the Unreal Editor. Click the image for full size.

To place an Actor from the Content Browser, follow the steps below:

In the Content Browser, find the Asset you want to place.

Left-click the Asset to select it.

With the Asset still selected, right-click anywhere in the Level Viewport to open the context menu.

Click the Asset under the Place Actor section.



Placing an Actor from the Content Browser into a Level using the context menu. Click the image for full size.

After selecting the Asset from the context menu, you will see it appear inside your Level at the coordinates where you right-clicked.

You can also use the context menu to quickly add different types of Assets to your level, even when you have a specific Asset selected in the Content Browser. To see the types of Assets you can add, right-click anywhere in your Level Viewport, then hover over the Place Actor section. Click any Actor you see in this section to place it.

Replacing Actors

You can also use the context menu to replace one or more Actors in the Level Viewport with an Asset you selected in the Content Browser. This can be useful if you want to swap multiple Assets at once.

To replace one or more Actors, follow the steps below:

In the Content Browser, select the Actor you want to replace another Actor with.

Right-click the Actor or Actors in the Level Viewport to open the context menu.

Click Replace Selected Actors with.

You can also use this method to replace the selected Actor with any Actor that is also available from the Place Actors panel.

Placing Actors Using Drag and Drop

You can add Actors to your Level from the Content Browser by using drag and drop. To do this, follow the steps below:

In the Content Browser, find the Asset you want to place.

Left-click the Asset, then drag it into the Level Viewport and drop it at the location where you want to place it.



When you drag and drop an Asset from the Content Browser, the following types of Actors are created for the associated type of Asset:

Blueprint: Places an instance of the Blueprint.

Skeletal Mesh: Places a SkeletalMeshActor.

Static Mesh: Places a StaticMeshActor.

Sound Cue: Places an AmbientSound.

Sound Wave: Places an AmbientSound.

Placing Actors from the Class Viewer

A more advanced method of placing Actors is by using the Class Viewer, which is a hierarchical list of all classes used by the Unreal Editor.

To place an Actor from the Class Viewer, follow these steps:

Open the Class Viewer. From the main menu, go to Tools > Class Viewer.

Any Actor that can be placed in the level will be tinted blue in this window.

Select the Asset you want to place, then drag it into the Level Viewport.



For more information, refer to the Class Viewer page.

Simple Selection

Selecting Actors in the World Outliner

Marquee Selection (Click-And-Drag)

Using the Select Menu

Selecting Actors, while simple in nature, is an important part of the level-editing process. The ability to quickly and easily select the Actors that you want to work with enhances productivity and speeds up the design process.

This page details the different ways to select Actors in Unreal Engine.

Simple Selection

The most basic method of selecting Actors is to left-click them in the Viewport. Clicking an Actor will deselect any currently selected Actors and select the new one instead. If you hold down the Ctrl key while you click a new (unselected) Actor, the new Actor is added to the selection. If you hold down the Ctrl key while clicking a selected Actor, the Actor is removed from the selection.

This method is good for selecting small numbers of Actors or several isolated Actors spread out across a Level, but it can be slow and tedious for selecting large numbers of Actors.



Selected Actors are highlighted in the Viewport. In this example, the table is selected, as shown by the yellow highlight and the presence of the Transform widget.

When you select multiple Actors, you can transform them as a group, and you can modify their properties simultaneously in the Details panel.

When you have two or more Actors selected, you can add them to a group to make it easier to re-select them or change their properties at the same time. For more information, refer to the Grouping Actors page.

Selecting Actors in the World Outliner

The World Outliner is a panel in the Unreal Editor that contains a hierarchical tree view of all Actors in the level. By default, it is located at the right-hand side of the Unreal Editor window.

You can select and deselect individual Actors in the list the same way you would in the Viewport.

In addition, you can select multiple Actors in the following ways:

Click an Actor, then hold down the Shift key and click another Actor to select all the Actors between them in the list.



Hold down the Ctrl key and click multiple Actors to select all of them. The Actors don't have to be in sequence.



Selecting any Actor in the World Outliner also selects it in the viewport, and vice versa.

Marquee Selection (Click-And-Drag)

Marquee selection is a quick way to select or deselect a group of Actors within a certain area in the viewport. This type of selection is performed by clicking and dragging the mouse, while optionally holding down a key or key combination. All the Actors within the box will be selected or deselected depending on the combination of keys and mouse button you hold down while dragging the mouse.



Marquee selection in Unreal Editor. Note that this viewport is in orthographic top-down view, which makes it easier to select multiple objects using click-and-drag.

The following table shows the possible keyboard combinations for marquee selection.

Mouse and Keyboard Shortcut

Action

Left-click and drag

Replaces the current selection with the Actors contained in the box.

Left-click and drag + Shift

Adds the Actors contained in the box to the current selection.

Left-click and drag + Ctrl + Alt

Removes the Actors in the box from the current selection.

Using the Select Menu

The Select menu in the Unreal Editor's menu bar brings up some advanced selection techniques.

The options available in this submenu vary depending on the type of Actor you select. For example, if you have a Static Mesh selected, you will see different options than if you have a Blueprint selected.

The table below details some of the common options found within the Select submenu.

Option

Description

Select All

Selects all Actors in the current Level.

Unselect All

Clears the current selection.

Invert Selection

Inverts the current selection (selects all Actors that are not currently selected, and deselects currently selected Actors).

Focus Selected

Centers the selected Actor inside the Level Viewport.

Select Immediate Children

Selects the immediate children of the currently selected Actor. For example, if your Actor hierarchy looks like this:

Actor 1

Actor 2

Actor 3

Actor 4

Actor 5

Actor 6

Actor 7

this operation only selects Actors 2, 3, and 6.

Select All Descendants

Selects all children of the currently selected Actor.

Select Relevant Lights

Selects all Light Actors that affect the currently selected Actor.

Select Matching (Selected Classes)

(For mesh Actors) Selects all Actors with the same Static Mesh and the same Actor class as the selected Actor.

Select Matching (All Classes)

(For mesh Actors) Selects all Actors with the same Static Mesh as the selected Actor.

Select All Additive Brushes

Select All Subtractive Brushes

Select All Surfaces

Selects all brush Actors that match the specified type (additive, subtractive, or surfaces).

Select All With Same Material

Selects all Actors that use the same Material.

Select All Geometry in Hierarchy

Deselect All Geometry in Hierarchy

Select Inverse Geometry in Hierarchy

Selects, deselects, or inverts the current selection of all geometry in the Level.

Manual Transformation

Interactive Transformation

Translation Gizmo

Rotation Gizmo

Scale Gizmo

World and Local Transformation Modes

Adjusting an Actor's Pivot Point

Keyboard Shortcuts

Transforming an Actor in Unreal Engine refers to moving, rotating, or scaling it (in other words, adjusting the position, orientation, and / or size of the Actor). This page describes how to perform each of these actions, as well as some of the commonly used keyboard shortcuts when working with Actors.

There are two ways to transform Actors in the Unreal Editor:

Manual transformation

Interactive transformation

In Unreal Engine, the vertical axis is the Z axis.

Manual Transformation

You can do manual transformation through the Transform section of the Details panel. When you select one or more Actors in the Level Viewport, you can view and edit their Location, Rotation, and Scale in this section. Where applicable, this section also contains Actor mobility settings.



The Transform section of an Actor's Details panel, showing values for the Actor's Location, Rotation, and Scale.

Each Transform property has numeric entry fields for the X, Y, and Z axes. You can type specific values directly into these fields to adjust the selected Actors, or click inside a field and drag your mouse up or down to adjust that field's value.

If more than one Actor is selected, and their Location or Rotation has multiple values, the relevant fields will display Multiple Values. In this case, if you enter a number it will overwrite that value for all selected Actors. Note that this may cause the Actors to overlap.



With multiple Actors selected, one or more Transform fields can have multiple values, as this example illustrates.

To reset an Actor's Location, Rotation, or Scale to their default values after you've made changes, click the Reset to Default button ( ).

You can lock the Scale fields by clicking the Lock Scale button ( ). When locked, the values for each axis (X, Y, and Z) change in unison, which allows for uniform scaling and prevents distortion.

Transform properties default to relative coordinate space, which means the transform occurs relative to the Actor's parent. You can toggle between relative and world transforms by clicking the dropdown arrow next to a property label. World transforms occur relative to world coordinates instead of the Actor's parent. For more information, see the World and Local Transformation Modes section on this page.

Interactive Transformation

You can do Interactive transformation directly inside the Level Viewport, using a visual tool called a gizmo. Sometimes, a gizmo can also be called a widget; in Unreal Engine, these terms mean the same thing.

A gizmo is made up of several parts that are color-coded according to which axis they affect:

Red represents the X axis.

Green represents the Y axis.

Blue represents the Z axis.

You can use transformation gizmos to move, rotate, or scale Actors.

Gizmos are more intuitive to use, but they can be less precise than entering coordinates manually. Use grid snapping for precise positioning when using gizmos. For more information, refer to the Actor Snapping page.

The gizmo takes different forms depending on what type of transformation is being performed: translation, rotation, or scale. You can choose which type of gizmo you want to use by clicking its icon in the Level Viewport toolbar, which is located in the upper-right section of the viewport, or by using keyboard shortcuts.



The Level Viewport toolbar is located in the upper-right section of the viewport. Click the image for full size.



Left to right: Shortcuts to the Selection, Translation, Rotation, and Scaling gizmos in the Level Viewport toolbar.

With one or more Actors selected, you can toggle between the different types of gizmos by pressing the Space Bar on your keyboard.

You can toggle the visibility of transformation gizmos on and off from the Main Toolbar's Settings menu by enabling or disabling the Show Transform Widget option.

Translation Gizmo

The Translation gizmo is a set of color-coded arrows pointing down the positive direction of each axis in the world. Use it to move an Actor along an axis, a plane, or freely.

Click an arrow and drag an arrow to move the selected Actor along that axis.



Translating a cube along a single axis.

To move an Actor along two axes simultaneously, click the square at the point where the two axes meet, then drag to move the Actor along the plane defined by the two axes (XY, XZ, or YZ).



Translating a cube along two axes (a single plane).

To move the Actor freely along all three axes, click and drag the white sphere at the point where all three axes intersect. You can also use the mouse wheel to move the Actor nearer or farther.



Translating a cube along all three axes.

To duplicate an Actor, hold down the Alt key, then click and drag a Translation gizmo arrow. This creates and moves a duplicate of the selected Actor, leaving the original unchanged at the starting position.



Duplicating an Actor using the Translation gizmo.

Rotation Gizmo

The Rotation gizmo is a set of three color-coded arcs, each associated with one axis. When you drag one of the arcs, the selected Actor rotates around that axis. For this gizmo, the axis affected by any one of the arcs involved is the one perpendicular to the arc. For example, the arc aligned to the XY plane rotates the Actor around the Z axis.



Rotating an Actor using the Rotation gizmo.

When you hover the cursor over a particular arc, that arc turns yellow, indicating that you can drag it to rotate the Actor. When you start to rotate the Actor, the gizmo changes shape to show only the axis around which the Actor is being rotated. The amount of rotation is displayed in real time to help you gauge your progress.

Scale Gizmo

The Scale gizmo has handles that end in cubes. When you drag the gizmo by one of these handles, you scale the selected Actor only along the associated axis. The handles are color-coded by axis, similar to the Translation and Rotation gizmos.



Scaling an Actor along a single axis.

You can scale an Actor along two axes simultaneously in the same way you can use the Translation gizmo to move an Actor along a plane defined by two axes. Each axis is connected to each other axis with a line that forms a triangle. These triangles align with one of the three planes (XY, XZ, YZ). Dragging one of these triangles scales the Actor along both axes that define that plane. When the mouse hovers over one of these triangles, the associated handles turn yellow.



Scaling an Actor along a single plane.

You can also scale an Actor along all three axes, thus maintaining its original proportions. If you hover the cursor over the cube where all three axes meet, all three handles turn yellow. Dragging by that center cube scales the Actor proportionally.



Scaling an Actor proportionally.

World and Local Transformation Modes

When using the interactive transformation method, you can choose which reference coordinate system you want to use when performing the transformation. This means you can transform the Actor in accordance to either:

World space - that is, along the world axes, or

The Actor's local space - that is, along its local axes.

The example below shows the difference between world and local space, using a Static Mesh Actor.





World space: The translation gizmo's XYZ axes are the same as the world's XYZ axes. Dragging along the Z axis moves the cube up and down in relation to the floor.

Local space: The translation gizmo's XYZ axes use the cube's local coordinates. Dragging along the Z axis also moves the cube up and down, but at an angle.

By default, the Unreal Editor starts out in world transformation mode. To switch to local transformation mode, click the Globe icon in the Level Viewport toolbar. The globe turns into a cube icon, indicating that you are now in local transformation mode. Click the cube to switch back to world coordinates.



The Globe icon indicates that transformations for the currently selected Actor use world space coordinates.

Adjusting an Actor's Pivot Point

When transforming Actors, you typically perform your transforms from the base pivot of the Actor. If you have a transformation gizmo enabled, you can see the pivot point where the three axes of that gizmo intersect.

You can adjust the location of an Actor's pivot temporarily by middle-clicking on the sphere in the center point of the Translation gizmo and dragging to move the pivot. You can then transform the object around the new pivot point.

The pivot point can be inside or outside an Actor.



In this example, the Static Mesh Actor rotates around an external pivot point.

The pivot jumps back to its original location as soon as you deselect that Actor. To make the pivot change permanent, after you adjust the pivot, right-click the Static Mesh and select Pivot > Set as Pivot Offset.

To reset the pivot to its default location, right-click the Static Mesh, then select Pivot > Reset Pivot Offset.

Keyboard Shortcuts

Below are some of the common keyboard shortcuts when working with Actors.

Control

Tool or Action

W

Selects the Move tool.

E

Selects the Rotate tool.

R

Selects the Scale tool.

V (hold down while using a translation gizmo)

Toggles vertex snapping.

Left-click and drag (on a transformation gizmo)

Moves, rotates, or scales the selected Actor, depending on the transformation gizmo that is currently active.

Middle-click and drag (on a pivot point)

Moves the pivot of the selected Actor.

Ctrl + W (on an Actor)

Duplicates the selected Actor at the same coordinates as the original.

Alt + Left-click and drag (on a translation gizmo)

Duplicates the selected Actor.

H (on an Actor)

Hides the selected Actor.

Ctrl + H

Shows all hidden Actors.

Shift + E (on an Actor)

Selects all matching Actors in the Level of the same type as the selected Actor.

Ctrl + Left-click (on an Actor)

Adds the Actor to the current selection of Actors.

Surface Snapping

Grid Snapping

Snapping Preferences

Vertex Snapping

Snapping is a feature that allows you to easily position an Actor by aligning it with a grid or another object. When snapping is enabled, the Actor will jump to fixed positions when transformed.

Unreal Engine implements snapping in several different ways:

Surface snapping

Grid snapping

Vertex snapping

Surface Snapping

Surface snapping makes Actors align to the floor or another surface. Enable surface snapping from the Level Viewport toolbar: click the Surface Snapping button, then enable the Surface Snapping option.



Click image for full size.

Surface Snapping button and options in the Level Viewport toolbar.

After you enable surface snapping, you can also set the following options:

Option

Description

Rotate to Surface Normal

If enabled, Actors will automatically rotate to match the alignment of the surface they snap to.

Surface Offset

Modify this value to configure the distance between the Actor and the surface it snaps to.

If you select an Actor and press the End key, the Actor snaps to the nearest surface - for example, your Level's floor plane.

Grid Snapping

When grid snapping is enabled in Unreal Engine, an Actor will move, rotate, or scale in increments of a specific value. For example, if your translation snapping value is set at 10 units, you can only move Actors in 10 unit increments.

Unreal Engine uses a separate grid for each transformation:

The Drag Grid allows for snapping to a 3-dimensional implicit grid within the Level.

The Rotation Grid provides for incremental rotation snaps.

The Scale Grid forces the Scale gizmo to snap to additive increments, but can be set to percentage values in the Editor Preferences (see the Snapping Preferences section below).



Click image for full size.



Click image for full size.



Click image for full size.

Drag Grid

Rotation Grid

Scale Grid

Each snapping grid is activated by clicking its icon in the Level Viewport toolbar. When a grid is active, its icon will be highlighted. You can change each grid's increments from the dropdown to the right of its activation button.

Snapping Preferences

The settings for the Drag Grid, Rotation Grid, and Scale Grid can all be configured from within the Editor Preferences panel, along with additional options for snap behavior. To access these preferences, from the main menu, select Edit > Editor Preferences > Viewports, then scroll down to the Snap category.



Click image for full size.

Grid Snapping preferences in the Unreal Engine Editor Preferences.

You can set the following options:

Option

Description

User Power of Two Snap Size

Enable this option to use power of 2 grid settings (1, 2, 4, 8, 16…) instead of decimal grid sizes.

Enable Grid Snapping

If enabled, Actor location will snap to the grid. This is the same as the toggle button on the Level Viewport toolbar.

Enable Rotation Snapping

If enabled, Actor rotation will snap to the grid.

Enable Scale Snapping

If enabled, Actor scale (size) will snap to the grid.

Use Percentage Based Scaling

Enable this option to use Unreal Engine's legacy multiplicative (percentage) scaling instead of the current additive method.

Enable 2D Layer Snapping

This enables an additional option in the Level Viewport toolbar you can use to snap objects to a 2D layer if your project requires it. The default layers are Foreground, Default, and Background. You can customize these by clicking Edit Layers from the drop-down.

Decimal Grid Sizes

Use this array to customize snapping grid sizes. These values display in the Level Viewport's toolbar.

Decimal Grid Intervals

This setting controls the decimal interval between grid reference lines in orthographic viewports.

Pow 2Grid Sizes

If you enabled the User Power of Two Snap Size, use this array to customize power-of-2 snapping grid sizes.

Pow 2Grid Intervals

This setting controls the power-of-2 interval between grid reference lines in orthographic viewports.

Common Rot Grid Sizes

Use this array to customize the Common rotation grid intervals. These values display in the Level Viewport's toolbar, under the Rotation Grid Snap dropdown.

Divisions Of 360Rot Grid Sizes

Use this array to customize the Divisions of 360 rotation grid intervals. These values display in the Level Viewport's toolbar, under the Rotation Grid Snap dropdown.

Scaling Grid Sizes

Use this array to customize scaling grid intervals. These values display in the Level Viewport's toolbar.

Vertex Snapping

Vertex snapping is a feature you can use to snap one object to another object by using the polygonal vertices of their respective meshes. Vertices are the points where two or more edges meet..

To use vertex snapping, hold down the V key while using the translation gizmo. While you hold down the V key, as soon as you start moving an object, you will see the polygon vertices you can snap that object to. This is especially useful when used in conjunction with pivot adjustment: you can snap the pivot directly to a vertex, then use that as a means to snap the object to a vertex on another object.

The video below demonstrates how to snap two pipes together precisely using this technique. Note also where the two Static Meshes' pivot points are located.

This technique is useful for walkways, walls, doors, or any other object that needs to be placed precisely in relation to another object.

Static Actors

Stationary Actors

Movable Actors

The Mobility setting controls whether an Actor can move or change in some way during gameplay. This primarily applies to Static Mesh Actors and Light Actors. It is located in the Actor's Details panel, under the Actor's Transform coordinates.



The Mobility setting in an Actor's Details panel.

An Actor that supports this setting can have one of three mobility states:

Static

Stationary

Movable

Static Actors

Static mobility is reserved for Actors that will not move or update in any way during gameplay.

Static Mesh Actors whose mobility is set to Static have their shadows contribute to pre-calculated lightmaps that use Lightmass to generate and process them. This mobility makes them ideal for structural or decorative meshes that never need to relocate during gameplay. Note, however, that their Materials can still be animated.

Light Actors whose mobility is set to Static contribute to pre-calculated lightmaps that use Lightmass. They illuminate the Level for Static and Stationary Actors. For Movable Actors, they use an indirect lighting method like Volumetric Lightmaps.

For more information, refer to the Static Light Mobility page.

Stationary Actors

Stationary mobility is reserved for Actors that can change during gameplay but not move.

Static Mesh Actors whose mobility is set to Stationary can be changed but not moved. They do not contribute to pre-calculated lightmaps using Lightmass and are lit like Movable Actors when lit by a Static or Stationary Light. However, when lit by a Movable Light, they will use a Cached Shadow Map to reuse for the next frame when the light is not moving, which can improve performance for projects using dynamic lighting.

Light Actors whose mobility is set to Stationary can change in some way during gameplay, such as having their color or intensity changed (to be brighter or dimmer), or even being completely off. Stationary lights still contribute to pre-calculated lightmaps using Lightmass but can also cast dynamic shadows for moving objects.

Too many Stationary Lights affecting the same Actor can have a significant impact on performance. Refer to the Stationary Light Mobility page for more information.

Movable Actors

Movable mobility is reserved for Actors that need to be added, removed, or changed in some way during gameplay. This includes moving, scaling, swapping with another Actor, and so on.

Static Mesh Actors whose mobility is set to Movable cast fully dynamic shadows that do not contribute to precomputed lighting stored in lightmaps. The way Movable Static Mesh Actors interact with lights depends on the light type:

Movable light: The Actor only casts only a dynamic shadow.

Stationary light: The Actor uses a combination of dynamic shadowing and precomputed lighting data, such as Volumetric Lightmaps.

Static light: The Actor is only lit by precomputed lighting data and does not cast any dynamic shadows.

Light Actors whose mobility is set to Moveable can only cast dynamic shadows. In addition to being able to move the light during gameplay, they can also change their color and intensity at runtime and have it update the scene accordingly. However, care must be taken when making these lights cast dynamic shadows since their shadowing method is the most performance intensive, depending on which shadow-casting features are enabled for your project.

Movable lights also support Lumen, a dynamic global illumination and reflections system.

Non-shadow-casting Movable Lights add no cost to scene rendering due to Unreal Engine's Deferred rendering system.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Selecting Actors

Grouping Actors

Working with Actor Groups

Regrouping

Ungrouping

Lock and Unlock Group

Adding and Removing Actors

Transforming Actors and Actor Groups

Group Actors together so you can manage multiple Actors at the same time. With Actor groups, you can:

Transform grouped Actors as a single unit through rotation, translation, and scaling. Individual Actor transformation is locked while Actors are part of a Group.

Temporarily unlock a group to transform individual Actors, then lock it again to freeze the Actors inside the group and prevent changes to an individual Actor's transforms.

Add and remove Actors from a group.

An Actor can only belong to one group at a time.

Before you can group Actors together, you need to make sure that the Allow Group Selection option is enabled. This option is located in the Settings menu on the Main Toolbar. You can also toggle this option using the Ctrl + Shift + G keyboard shortcut.



Allow Group Selection option in the Settings menu.

Grouping Actors

To group two or more Actors together, select the Actors, then do either of the following:

Right-click one of the selected Actors to bring up the context menu, then select Group.

Use the Ctrl + G keyboard shortcut.

Actor groups are delineated with green brackets in the Viewport.



An Actor group consisting of four Static Mesh Actors. Any transformations will affect all Actors in this group simultaneously.

It is not possible to group Actors that are in different Levels. Moving an Actor that is currently in a group from one Level to another will remove it from the existing group. However, you can move entire groups across Levels.

When you group Actors together, you create a Group Actor in the World Outliner. To select all Actors in that group, you can select either the Group Actor or any member of the group.



A Group Actor in the World Outliner.

For more information about Actor selection, refer to the Selecting Actors documentation.

Working with Actor Groups

Actor group options are located in the Group section of the context menu that opens when you right-click a selection of Actors or an Actor group, in the Viewport or in the World Outliner.

The sections below describe the options for working with groups in Unreal Engine.

Regrouping

When a selection contains at least one group and other ungrouped Actors, the Regroup option becomes available in the context menu.

Regrouping removes all selected Actors from any existing groups, then creates a new group from all selected Actors. Use this option to quickly create a new group out of a selection without needing to manually disband other groups.

You can also use the Ctrl + G keyboard shortcut to regroup Actors. This shortcut behaves differently depending on whether you have selected:

No Actor groups: Ctrl + G creates a new group that contains all of the selected Actors.

At least one Actor group: Ctrl + G performs a regroup, as described above.

Ungrouping

The Ungroup option removes all Actors from the selected groups and deletes the groups.

For groups that are unlocked, the ungroup operation will remove the selected Actors from the group without attempting to keep them within any existing group hierarchy.

You can also use the Shift + G keyboard shortcut to ungroup Actors and / or nested groups.

Lock and Unlock Group

The Lock and Unlock options are available when you are working with an existing group.

By default, newly created groups are in a locked state. When a group is in a locked state:

If you select any Actor in a locked group, the entire group will be selected.

Transformations will affect all Actors in the group.

If a group is unlocked, you can:

Select and transform individual Actors that are part of that group.

Remove Actors from the group.

The brackets surrounding a group indicate whether it is currently locked or unlocked. Green brackets signify that the group is locked. Red brackets mean that the group is unlocked.





Left: A locked Actor group. The brackets around it are green and the pivot point is at the center of the group.

Right: An unlocked Actor group. The rightmost cube is currently selected and can be transformed individually.

Adding and Removing Actors

The Add to Group option is only available after you select one group and other ungrouped Actors. This option adds the ungrouped Actors to the existing group.

The Remove from Group option is only available after you select one or more Actors in an unlocked group. This option will remove the selected Actors from the group. If a nested group is removed from a larger group, it still remains a group itself.

If a group contains no Actors, it is automatically deleted, and its Group Actor is removed from the World Outliner.

Transforming Actors and Actor Groups

The pivot point of an Actor group is automatically set to the center point of that group. When the group is locked, you can only transform all actors inside the group around the group's pivot points. To transform individual Actors around their own pivot points, you must unlock the group first.

To set the pivot point of an Actor group, select the group, then hold down the Alt key and middle-click at the location where you want to set the pivot point. Alternatively, middle-click and drag the sphere at the center of the group's transformation gizmo to move the pivot point.



This GIF illustrates how to move the pivot point of an Actor group, and demonstrates how the Actor group rotates around the new pivot point.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Selecting Actors

Actor Merging Workflow

Merge Types

Merge

Simplify

Batch

Approximate

Merge Settings

Merge

Simplify

Batch

Approximate

Replace Source Actors

In Unreal Engine, you can combine two or more Static Mesh Actors into a single new Actor using Actor merging. This reduces draw calls and helps with project optimization.

Actor Merging Workflow

To merge two or more Static Mesh Actors inside your Level, follow these steps:

In the Level Viewport or World Outliner, select the Static Mesh Actors you want to merge.

From the top menu bar, go to Actor > Merge Actors.

Select the type of merge you want to perform: Merge, Simplify, Batch, or Approximate. Refer to the Merge Types section on this page for more information.

The option you select will perform the merge automatically using the default or last configured settings. To configure merge options, from the top menu bar, go to Actor > Merge Actors > Merge Actor Settings.

Name your new Actor and select the folder where it should be created, then click Save.

Merge Types

Unreal Engine offers different methods to merge Static Mesh Actors, depending on what you are merging:

Merge

Simplify

Batch

Approximate

These options are described below.

Merge

By default, this method merges all selected Static Mesh Actors, creating one mesh section for each Material. You can specify LOD levels to use.

The number of draw calls is equivalent to the number of Materials. This method preserves UVs.

You can also select to merge all Materials, which bakes a single Material for the entire mesh. This results in a single section and a single draw call, but does not preserve UVs. Occlusion culling is performed per section.

Simplify

This method merges all selected Static Mesh Actors into a single mesh, called a Proxy Mesh. It uses the lowest-detail LOD of each selected mesh and simplifies mesh geometry based on the settings provided. Vertex count is also reduced.

This method results in one draw call. It bakes one Material for the entire mesh and does not preserve UVs. Occlusion culling is performed for the whole mesh.

Refer to the Proxy Geometry Overview page for additional information.

Batch

This method creates instanced Static Mesh components from identical Static Mesh components. It preserves UVs and does not affect occlusion culling.

Approximate

This method is new to Unreal Engine 5 and is similar to the Simplify merge method. The difference is that it can handle much more complex source meshes (for example, Nanite meshes), whereas the Simplify method would fail during either the simplification or the texture baking steps.

Merge Settings

You can configure individual merge settings from the Merge Actor Settings panel. To access this panel, from the top menu bar, go to Actor > Merge Actors > Merge Actor Settings.

Merge

When using this merge method, you can configure the options below.

The Mesh Settings section contains properties that affect the Static Meshes that will be merged.

Option

Description

Pivot Point at Zero

If enabled, the pivot point of the merged Actor will be set to the Level's origin (0,0,0).

If disabled, the point of the merged Actor will be the pivot point of the first Static Mesh Actor selected for the merge.

Merge Physics Data

Merges all of the collision primitives into a single physics object.

Bake Vertex Data to Mesh

Bakes vertex data, including vertex color and normals, into the merged Static Mesh Actor.

Output UVs

An array that contains multiple UV channels. If the source meshes contain valid UVs for a specified channel, you can select whether or not to output the UV channel into the merged Static Mesh Actor.

LOD Selection Type

Control which LODs are added to the merged object. You can select one of the following options:

Use all LOD levels: Uses all available LOD levels.

Use specific LOD level: Use only the selected LOD level.

Calculate correct LOD level: Calculates the optimum LOD level for the given screen size.

Always use the lowest-detail LOD (the highest LOD index): Uses the lowest-detail LOD available.

Include Imposters

If enabled, the merge will include imposter LODs that are part of the source Static Meshes.

Allow Distance Field

If enabled, a distance field will be computed for this Mesh. Disable this option to save memory if the merged mesh will only be rendered in the distance.

Generate Lightmap UVs

Creates a new lightmap UV layout for the merged Static Mesh Actor, using the existing UV islands. This new layout will be placed in the target lightmap UVChannel.

Generate Nanite Enabled Mesh

If enabled, generates a Nanite-enabled mesh.

Target Light Map Resolution

Specifies the resolution for the new lightmap UVs, which controls the distance calculated between each island within the layout. Higher resolutions will yield tighter spacing between each island.

Computed Light Map Resolution

If enabled, lightmap resolution will be computed by summing up the Lightmap resolutions for the source Static Meshes.

The Material Settings section contains properties that affect the textures and Materials of the Static Meshes to be merged.

You can't merge Materials for multiple Static Meshes if the LODSelection Type option in the Mesh Settings section is set to Use all LOD levels.

Option

Description

Merge Materials

If enabled, the Materials of all the merged assets will be combined into a single Material with a new UV layout.

The following subsettings only become available if Merge Materials is enabled.

Texture Size

Sets the horizontal (X) and vertical (Y) pixel dimensions, or resolution, for the final merged Material's textures.

Texture Sizing Type

Normal Map

If enabled, generates a Normal map for the merged Actor.

Tangent Map

If enabled, generates a Tangent map for the merged Actor.

Metallic Map

If enabled, generates a Metallic map for the merged Actor. While this option is enabled, the Metallic Constant property has no effect.

Metallic Constant

Sets a constant value for the Metallic property of the merged Actor's Material. Only enabled if the Metallic Map option is unchecked.

Roughness Map

If enabled, generates a Roughness map for the merged Actor. While this option is enabled, the Roughness Constant property has no effect.

Roughness Constant

Sets a constant value for the Roughness property of the merged Actor's Material. Only enabled if the Roughness Map option is unchecked.

Anisotropy Map

If enabled, generates an Anisotropic map for the merged Actor. Anisotropy is a Material's property to change its appearance depending on the direction it is viewed from. While this option is enabled, the Anisotropy Constant property has no effect.

Anisotropy Constant

Sets a constant value for the Anisotropy property of the merged Actor's Material. Only enabled if the Anisotropy Map option is unchecked.

Specular Map

If enabled, generates a Specular map for the merged Actor. While this option is enabled, the Specular Constant property has no effect.

Specular Constant

Sets a constant value for the Specular property of the merged Actor's Material. Only enabled if the Specular Map option is unchecked.

Emissive Map

If enabled, generates an Emissive map for the merged Actor.

Opacity Map

If enabled, generates an Opacity map for the merged Actor. While this option is enabled, the Opacity Constant property has no effect.

You must also set the Blend Mode to Translucent for opacity to work correctly in the generated instances.

Opacity Constant

Sets a constant value for the Opacity property of the merged Actor's Material. Only enabled if the Opacity Map option is unchecked.

Opacity Mask Map

If enabled, generates an Opacity Mask map for the merged Actor. While this option is enabled, the Opacity Mask Constant property has no effect.

You must also set the Blend Mode to Masked for opacity to work correctly in the generated instances.

Opacity Mask Constant

Sets a constant value for the Opacity Mask property of the merged Actor's Material. Only enabled if the Opacity Mask Map option is unchecked.

Ambient Occlusion Map

If enabled, generates an Ambient Occlusion map for the merged Actor. While this option is enabled, the Ambient Occlusion Constant property has no effect.

Ambient Occlusion Constant

Sets a constant value for the Ambient Occlusion property of the merged Actor's Material. Only enabled if the Ambient Occlusion Map option is unchecked.

Tangent Texture Size

Sets the horizontal (X) and vertical (Y) pixel dimensions, or resolution, for the merged Actor's Tangent texture. Enabled when Texture Sizing Type is set to Use per property manually overridden texture sizes.

Anisotropy Texture Size

Sets the horizontal (X) and vertical (Y) pixel dimensions, or resolution, for the merged Actor's Anisotropy texture. Enabled when Texture Sizing Type is set to Use per property manually overridden texture sizes.

Blend Mode

Sets how the Material's color is blended with background colors. You can choose from the following options:

Opaque: Defines a surface through which the light neither passes nor penetrates.

Masked: Defines whether the merged Material will use masking (that is, have different areas be visible or not based on a masking texture).

Translucent: Defines the visibility of a Material by using an Opacity value.

Additive: Takes the pixels of the Material and adds them to the pixels of the Background.

Modulate: Multiplies the value of the Material against the pixels of the background.

AlphaComposite (Premultiplied Alpha): Used with textures that already have a pre-multiplied alpha.

AlphaHoldout: Creates a cutout effect by holding out the alpha in the Material and punching a hole through objects behind it.

Allow Two Sided Material

If enabled, the generated Material will be two-sided.

Gutter Size

Sets the gutter size, in texels, to add to each subchart of the baked-out Material for the top mip level.

Create Merged Material

If enabled, creates a flat Material from all Materials of the Actors to be merged, along with a new set of UVs. By default, this Material will not be applied to any section.

Use Vertex Data for Baking Material

If enabled, uses vertex data such as vertex color to bake Material results. This is useful if you have a Material that is being controlled in some way by vertex color.

Use Texture Binning

Calculate the varying output texture sizes according to their importance when packing the final atlas texture.

Reuse Mesh Lightmap UVs

If enabled, attempts to reuse the lightmap UVs of the source Static Meshes when baking the Material. If disabled, generates a new set of lightmap UVs.

Merge Equivalent Materials

If enabled, attempts to merge Materials that are deemed equivalent.

Enabling this option can cause artifacts in the merged Static Mesh if output color is determined by world position or Actor position.

If the Landscape Culling option is enabled, Unreal Engine will use existing landscape geometry to cull fully occluded triangles when merging Actors.

For example, if you have a tree mesh that was planted such that the bottommost triangles are well below the surface of a landscape, then those occluded triangles will be removed after the merge.

Simplify

When using the Simplify merge method, you can configure the options below.

Option

Description

Screen Size

The screen size of the merged Static Mesh, in pixels.

Calculate Correct LODModel

If enabled, calculates the correct LOD models based on source meshes and transition size.

Override Spatial Sampling Distance

Overrides the spatial sampling distance when converting multiple Static Meshes for proxy LOD merging.

Large geometry with high sampling can have very high memory costs.

Material Settings

You can configure the same Material settings described in the Merge section on this page.

Merge Distance

Sets the distance at which meshes are merged together. For example, this can fill in gaps like doors and windows in distant geometry.

Unresolved Geometry Color

Sets the color to be assigned to LOD geometry that can't be associated with the source geometry (for example, doors and windows that were further than the Merge Distance and were filled in). You can set red, green, and blue (RGB) values, as well as an alpha (A) value that controls transparency.

Transfer Distance Override

Overrides the search distance at which Unreal Engine discovers texture values for simplified geometry. This is useful if you set a manual value greater than zero for the Merge Distance option, which generates new geometry in concave corners.

Hard Edge Angle

Sets the angle at which a hard edge is introduced between the faces of the merged Static Mesh.

This option increases vertex count and might introduce additional UV seams. It is only recommended if you are not using Normal maps.

Normal Calculation Method

Select the method used to control Normal calculation for the simplified geometry. You can choose from the following options:

Angle Weighted: Use the angle of a triangle at a vertex to weight how much that triangle's normal contributes to that vertex's Normal.

Area Weighted: Use triangle area to weight how much a triangle's Normal contributes its vertices' Normals.

Equal Weighted: Average the Normal of each triangle sharing a vertex.

For more information about Normal calculation, refer to the Normal Calculation Method page.

Light Map Resolution

Sets the lightmap resolution.

Compute Light Map Resolution

If enabled, computes lightmap resolution as a sum of the dimensions for each mesh included for merging.

Enable Volume Culling

If enabled, culling volumes can exclude geometry.

Allow Adjacency

If enabled, allows adjacency buffers for tessellation in the merged Static Mesh.

Allow Distance Field

If enabled, a distance field will be computed for this mesh. Disable this option to save memory if this mesh will only be rendered in the distance.

Reuse Mesh Lightmap UVs

If enabled, attempts to reuse the lightmap UVs of the source Static Meshes when baking the Material. If disabled, generates a new set of lightmap UVs.

Group Identical Meshes for Baking

If enabled, bakes identical meshes or mesh instances only once. This results in better quality baked textures and greatly reduces baking time.

This can lead to discrepancies with the source mesh visual, especially for materials that are using world position or per instance data.

Create Collision

If enabled, generates collision for the merged Static Mesh.

Allow Vertex Colors

If enabled, vertex colors will be saved in the merged Static Mesh.

Generate Lightmap UVs

Creates a new lightmap UV layout for the merged Static Mesh Actor, using the existing UV islands. This new layout will be placed in the target lightmap UVChannel.

Generate Nanite Enabled Mesh

If enabled, generates a Nanite-enabled mesh.

Batch

When using the Batch merge method, you can configure the options below.

Option

Description

Actor Class to Use

Select the class to use for the instanced Static Meshes.

Instance Replacement Threshold

Sets the minimum number of Static Mesh instances needed before a Static Mesh is replaced with an instanced version.

Skip Meshes with Vertex Colors

If enabled, Static Meshes that use vertex colors will not be instanced. This prevents data loss because instanced Static Meshes do not support vertex colors per instance.

Use HLOD Volumes

If enabled, instanced Static Meshes will be split up based on their intersection with HLOD volumes.

Select the type of Instanced Component

Select the type of instanced component to use for the instanced Static Meshes.

Approximate

When using the Approximate merge method, you can configure the options below.

Shape Settings

Description

Output Type

The type of output from the mesh approximation process.

Mesh and Materials: Generates both the mesh and its material.

Mesh Shape Only: Skips the material baking step and only generates the mesh.

Approximation Accuracy

The approximation accuracy in meters, which will determine (for example) voxel resolution.

Attempt Auto Thickening

If enabled, attempts to auto-thicken thin parts or flat sheets.

Target Min Thickness Multiplier

A multiplier on Approximation Accuracy used for auto-thickening.

Ignore Tiny Parts

If enabled, tiny parts will be excluded from the mesh merging, which can improve performance.

Tiny Part Size Multiplier

A multiplier on Approximation Accuracy used to define tiny-part threshold, using maximum bounding-box dimension

Base Capping

Optionally close off the bottom of open meshes. Possible options are:

No Base Capping

Convex Polygon: Adds a downwards-facing polygon at the base of the mesh.

Convex Solid: Adds a downwards-facing polygon at the base of the mesh and thickens it into a closed solid.

These options can have very different effects on the resulting mesh depending on whether or not the other input objects are closed meshes, as well as the 'winding' threshold. For example, a large mountain scan that is uncapped should use the polygon and not the solid, but if it's many kitbashed mesh parts, the open mesh can introduce significant problems and using the solid may be more reliable.

Fill Gaps

If enabled, topology is expanded / contracted to fill small gaps between objects.

Gap Filling Distance

The distance in meters to expand / contract to fill gaps.

Clamp Voxel Dimension

The maximum allowable voxel count along main directions. This is a limit on Approximation Accuracy.

Winding Threshold

The Winding Threshold controls hole filling at open mesh borders. Smaller value means more or rounder filling.

Option

Description

Occlusion Method

The type of hidden geometry removal to apply:

No Occlusion Filtering

Visibility Based Filtering

Occlude from Bottom

If enabled, then the OcclusionMethod computation is configured to try to consider downward-facing "bottom" geometry as occluded.

Simplify Method

Mesh Simplification criteria:

Geometric Tolerance: Constrain simplification to a maximum geometric deviation from the input meshes. The maximum is provided by the Geometric Deviation option below.

Fixed Triangle Count: Simplification will aim to reach a target count of triangles, provided by the Target Tri Count option below.

Triangles Per Area: Simplification will aim for a number of triangles per square meter, provided by the Triangles per M option below.

Geometric Deviation

The allowable geometric deviation, in meters, used when the Simplify Method is set to Geometric Tolerance.

Target Tri Count

The target triangle count for mesh simplification, used when the Simplify Method is set to Fixed Triangle Count.

Triangles Per M

The approximate number of triangles per square meter, used when the Simplify Method is set to Triangles Per Area.

Ground Clipping

Configures how the final mesh should be clipped with a ground plane, if desired. The options are:

No Ground Clipping: Does not perform ground clipping.

Discard With ZPlane: Discards triangles whose vertices are all below the clip plane.

Cut With ZPlane: Performs a mesh cut to eliminate the portion of the mesh that is below the clip plane.

Cut And Fill With ZPlane: Same as the Cut With ZPlane option above, and also closes the cut mesh by inserting new triangles where the cut was performed.

For all of these options, the height (Z) of the clip plane is provided by the Ground Clipping ZHeight option.

Ground Clipping ZHeight

The Z-Height for the ground clipping plane, if Ground Clipping is enabled.

Normals Settings

Description

Estimate Hard Normals

If enabled, Normal angle will be used to estimate hard Normals

Hard Normal Angle

The Normal angle to use to detect hard Normals.

UV Settings

Description

UV Generation Method

The Mesh UV Generation method:

Prefer UVAtlas: Uses Microsoft's open-source UVAtlas library.

Prefer XAtlas: Uses the XAtlas open-source mesh parametrization / UV unwrapping library.

Prefer PatchBuilder: Uses Unreal Engine's own UV generation algorithm.

Initial Patch Count

The number of initial patches the mesh will be split into before computing island merging. Only relevant for the PatchBuilder UV generation method.

Curvature Alignment

Controls the alignment of the initial patches to creases in the mesh. Only relevant for the PatchBuilder UV generation method.

Merging Threshold

The distortion / stretching threshold for island merging. Larger values increase the allowable UV stretching. Only relevant for the PatchBuilder UV generation method.

Max Angle Deviation

UV islands will not be merged if their average face Normals deviate by more than this value. Only relevant for the PatchBuilder UV generation method.

Mesh Settings

Description

Generate Nanite Enabled Mesh

Whether to generate a Nanite-enabled mesh.

Support Ray Tracing

Whether ray tracing will be supported on this mesh. Disable this to save memory if the generated mesh will only be rendered in the distance.

Allow Distance Field

Whether to allow a distance field to be computed for this mesh. Disable this to save memory if the generated mesh will only be rendered in the distance.

Nanite Proxy Triangle Percent

The percentage of triangles to reduce down to when generating a coarse proxy mesh from the Nanite mesh.

Material Settings

Description

Multi Sampling AA

If this property is greater than 1, multisample output baked textures by this amount in each direction (for example, 4 == 16x supersampling).

Render Capture Resolution

If this property is zero, use the Material Settings resolution, otherwise override the render capture resolution.

Material Settings

You can configure the same Material settings described in the Merge section on this page.

Capture Field Of View

The field of view angle to use when performing the render capture.

Near Plane Dist

The near plane distance to use when performing the render capture.

Debug Settings

Description

Print Debug Messages

If enabled, print out debugging messages.

Emit Full Debug Mesh

If enabled, write the full mesh triangle set (flattened, non-instanced) used for mesh generation.

This asset may be extremely large.

Replace Source Actors

If the Replace Source Actors option is enabled, the Actors selected in the viewport will be removed and replaced with the new merged Actor. This will not delete their Assets from the Content Browser or from your project folders.

This option is common to all of the merge methods described on this page.

Mesh Actors

Brush Actors (Geometry Actors)

Light Actors

Camera Actors

Audio and Sound Actors

Gameplay Actors

Character and Pawn Actors

Visual Effects Actors

Worldbuilding Actors

Other Actors

This page describes the most common types of Actors you will be working with in Unreal Engine. The Actors are grouped by purpose and functionality. Each section includes links to other pages and resources where you can learn more about these Actors and what you can do with them.

Note that this is not a comprehensive list of every Actor type available in Unreal Engine. Some plugins and project templates add their own Actors, and certain Actors may not be available for all projects.

Mesh Actors

A mesh defines the shape and size of an environment prop or a player character. Unreal Engine uses two types of mesh Actors:

Static Mesh Actors, which are used to build levels and environments.

Skeletal Mesh Actors, which are typically used for player characters and animated non-player characters (NPCs).

Static Mesh Actors

The Static Mesh Actor is a simple type of Actor that displays a mesh in the Level. Although the name implies that the Actor is static (or unable to move), the "static" refers to the type of mesh used rather than the Actor's ability to move. A mesh is static if its geometry does not change. Otherwise, the Actor itself can be moved or changed in other ways during play.

Static Mesh Actors are commonly used to create game worlds or other types of environments.

Refer to the Static Meshes section to learn more.

Skeletal Mesh Actors

The Skeletal Mesh Actor displays an animated mesh whose geometry can be deformed, typically through the use of control points during animation sequences. These can either be created and exported from external 3D animation applications, or programmed directly in Unreal Engine.

Skeletal Mesh Actors are commonly used to represent player characters or NPCs, as well as other animated creatures and complex machinery.

Refer to the Skeletal Mesh Actors page to learn more.

Brush Actors (Geometry Actors)

Brush Actors are a basic type of Actor that displays simple 3D geometry in the scene, such as spheres, cubes, and stairs. These Actors can be changed using the Geometry Editing mode in the Level Editor.

The following types of Brush Actors are available in Unreal Engine:

Box

Cone

Cylinder

Curved Stair

Linear Stair

Spiral Stair

Sphere

Brush Actors are commonly used to quickly prototype environments and block out levels. Use these to get a rough impression of the size and placement of environment props.

Refer to the Geometry Brush Actors page to learn more.

Light Actors

As the name suggests, Light Actors are used to place different types of lights around your Level. Some Light Actors have a limited area of effect around them, while others affect your entire Level.

The following types of Light Actors are available in Unreal Engine:

Directional Light

Point Light

Spot Light

Rect Light

Sky Light

You can learn more about lighting fundamentals in Unreal Engine from the following Unreal Online Learning courses:

Lighting Essential Concepts and Effects

Introducing Global Illumination

Directional Light Actor

A Directional Light simulates light that is being emitted from a source that is infinitely far away. This means that all shadows cast by this light will be parallel, making this the ideal choice for simulating sunlight.

Refer to the Directional Lights page to learn more.

Point Light Actor

Point Lights work like real-world light bulbs. A Point Light emits light in all directions from its center, which is a single point in the Level.

Refer to the Point Lights page to learn more.

Spot Light Actor

Spot Lights work like a stage light or a flashlight. A Spot Light emits light outward in a conical shape from a single point. The Spot Light's shape is defined by two separate cone angles:

Inner Cone Angle, inside which the light achieves full brightness.

Outer Cone Angle, which defines the outer bounds of the Spot Light.

From the Inner Cone Angle and extending towards the limits of the Outer Cone Angle, the light's intensity falls off, softening around the Spot Light's disc of illumination.

Refer to the Spot Lights page to learn more.

Rect Light Actor

Rect Lights emit light into the Level from a rectangular plane with a defined width and height. You can use these to simulate any kind of light sources that have rectangular surface areas, such as windows, televisions, or monitor screens.

Refer to the Rectangular Area Lights page to learn more.

Sky Light Actor

The Sky Light captures distant parts of your Level and applies them to the scene as a light source. That means the sky's appearance and its lighting / reflections will match, whether your sky is coming from the atmosphere, layered clouds on top of a skybox, or from distant mountains.

If you are developing an Augmented Reality (AR) application, consider using an ARSky Light Actor instead.

ARSkyLight is a subclass of the SkyLight class that uses real-world environment probes to update reflections. It regenerates lighting and reflections whenever the corresponding probe's texture updates based on the real-world lighting. This all occurs on the render thread.

Refer to the Sky Lights page to learn more.

Camera Actors

Like their real-world counterpart, Camera Actors are used to view your Level and create cinematic sequences. In addition, there are a number of supporting Actors that can be used to simulate real-world camera shots.

Refer to the Camera Actors page to learn more.

Audio and Sound Actors

Audio and Sound Actors are used to add music, voice recordings, and sound effects to your Level.

Ambient Sound Actor

Use an Ambient Sound Actor to play a looping (continuous) sound at a specific location in the Level.

Refer to the Ambient Sound Actor User Guide page to learn more.

Audio Volume

With the Audio Volume Actor, you can define areas within a Blueprint graph that can be used to process sounds, and use its settings to apply reverb effects, set volumes, define the zones affected, emulate occlusion on a sound, and define the shape of the sound volume.

Refer to the Audio Volume page to learn more.

Gameplay Actors

Gameplay Actors trigger interactive functionality. Despite their name, they have a broad range of uses in all kinds of interactive applications, not just games.

Below are the most common types of Gameplay Actors.

Anything that you can place in your Level is called an Actor. A Volume is a type of Actor that has a three-dimensional shape, such as a cube or sphere.

Player Start

A Player Start is an Actor that is placed in the Level to designate where the player character spawns when the player starts the Level.

Refer to the Player Start Actor page to learn more.

Trigger Volumes

Triggers are Actors that cause an event to occur when something else in the Level interacts with them, such as the player character or another object. For example, a player can interact with a trigger to switch on a light.

The following types of triggers are available in Unreal Engine:

Box Trigger

Capsule Trigger

Sphere Trigger

All three of these trigger types have the same functionality. The only thing that's different is the shape. You can choose between different shapes depending on the kind of visual representation the trigger has in your Level.

In addition, Unreal Engine also has a generic Trigger Volume. Much like Geometry Actors, you can use this volume to quickly prototype interactions in your Level.

Refer to the Trigger Volume Actors page to learn more.

Blocking Volume

As the name suggests, Blocking Volumes are used to prevent the player from passing through. For example, you might use Blocking Volumes so your player doesn't fall off the edges of your game world.

Kill ZVolume

The Kill ZVolume Actor instantly "kills" (destroys) the player character once they enter or interact with its volume. You can specify the kill condition in the Kill ZVolume Actor's Details panel.

Note that the Kill ZVolume Actor is different from the Kill Z option in the World Settings panel, which destroys the player once they fall past a certain point along the Z axis (vertical axis).

Pain Causing Volume

A Pain Causing Volume causes damage over time to any player or object that enters it. For example, if a player stands in the fire, you can set up a Pain Causing Volume to deal corresponding damage to their health.

Don't stand in the fire.

Refer to the Pain-Causing Volume Actor page to learn more.

Character and Pawn Actors

Both Pawns and Characters are Actors that represent player and AI-controlled characters.

Pawn

A Pawn is the physical representation of a player or AI entity within the world. The Pawn not only determines what the player or AI entity looks like visually, but also how it interacts with the world in terms of collisions and other physical interactions.

Depending on the kind of project you're building, the Pawn could be a player avatar, a car, or have no physical representation at all.

There are two types of Pawns available in Unreal Engine 5:

Pawn Type

Description

Pawn

This is an empty Pawn Actor. It doesn't have any visual representation (mesh) or controls attached to it.

Default Pawn

This is a simple Pawn Actor with spherical collision and built-in flying movement. Note that you need to attach a controller Component to it before it responds to player input.

Character

A Character is a specific type of Pawn that is designed for a vertically-oriented player character that can walk, run, jump, fly, and swim through the world. In other words, if your player controls a bipedal avatar (for instance, a human), the avatar will be a Character rather than a Pawn.

There are several types of Character Actors available in Unreal Engine. When you set up your project, choose the one that best matches the project type.

Character Type

Description

Further Reading

Character

This is a simple Character Actor with capsule collision, an empty mesh, and character movement. As-is, this Actor is invisible in the Level, but can be controlled.

Arch Vis Character

The Arch Vis Character is based on Unreal Engine's First Person Character class. Some of its parameters, such as warp and turn speed, have been adjusted to allow for smoother movement. This Character is optimized for architectural visualization projects.

Using the Archviz Character Pawn (YouTube)

Paper Character

The Paper Character is used for 2D projects. The difference between a Paper Character and a generic Character is that the Paper Character has a Paper Flipbook Component (a Sprite) to represent the character visually, whereas the generic Character uses a three-dimensional mesh.

Paper 2D Sprites

Visual Effects Actors

Visual Effects Actors are used to change the look and feel of your Level. These Actors only have a limited area of effect, defined by a finite three-dimensional volume.

Post Process Volume

The Post Process Volume applies one or more visual effects to the objects contained within it. Unreal Engine offers a broad range of effects that can be applied, from bloom and vignettes to global illumination and ray tracing reflections.

Depending on the size and complexity of your Level, as well as your device's specs, post-processing can be a resource-intensive process and can have a significant impact on performance at runtime.

Refer to the Post Process Effects section to learn more.

Reflection Capture Actors

Reflection Capture Actors are used to capture the contents of the Level for reflection. They capture a static image of the area around them, and map it to a sphere or a box shape, depending on the Actor's shape. Anything within the volume of a Reflection Capture Actor will have its static image reflected by any reflective surfaces around it.

The following types of Reflection Capture Actors are available in Unreal Engine:

Sphere Reflection Capture

Box Reflection Capture

Refer to the Reflections Environment page to learn more.

Planar Reflection Actor

A Planar Reflection Actor captures a 2D mirror image of the scene. It is ideal for creating dynamic mirror reflections and for capturing things that aren't within the current camera view.

Refer to the Planar Reflections page to learn more.

Decal Actor

Decal Actors can be placed over the surface of a mesh to render a Material on top of it, much like a real-world "sticker". You can use decals to add details and variations to multiple surfaces that use the same texture, like adding water leaks or paint splatters to modular walls.

Refer to the following pages to learn more:

Decal Actors





Worldbuilding Actors

Use Worldbuilding Actors to add realistic details to your Level, such as sky atmosphere, fog, and volumetric clouds.

Sky Atmosphere Actor

The Sky Atmosphere Actor is a physically-based sky and atmosphere-rendering technique. It's flexible enough to create an Earth-like atmosphere with time-of-day featuring sunrise and sunset, or to create extraterrestrial atmospheres of an exotic nature. It also provides an aerial perspective to which you can simulate transitions from ground to sky to outer space with proper planetary curvature.

Refer to the Sky Atmosphere page to learn more.

Volumetric Cloud Actor

The Volumetric Cloud Actor is a physically-based cloud rendering system that uses a material-driven approach to give artists and designers the freedom to create any type of clouds they need for their projects. The system provides scalable clouds that can adapt to projects using ground views, aerial views, and ground to outer space transitions

Refer to the Volumetric Clouds page to learn more.

Exponential Height Fog Actor

Exponential Height Fog creates more density at lower altitudes within a Level and less density at higher altitudes. The transition is smooth, so you never see a hard cutoff as you increase altitude.

Exponential Height Fog also provides two fog colors — one for the hemisphere facing the dominant directional light (or directly upward if none exists), and another color for the opposite hemisphere.

Refer to the Exponential Height Fog User Guide page to learn more.

Other Actors

Unreal Engine contains a number of other Actors you can use to add various elements to your Level. Some of these Actors are enabled by default, while others require that you enable specific plugins first. To learn how to enable plugins in Unreal Engine, refer to the Working with Plugins page.

Text Render Actor

The Text Render Actor provides a simple way to add text to your Level. For a quick usage example, create a new Third Person project. The blue text that reads "THIRD PERSON" across the floor is rendered using a Text Render Actor.

You can create and animate more complex 3D text using the Text 3D plugin. Refer to the 3D Text Actor page to learn more.

Target Point Actors

Target Point Actors give you a generic point in the world that you can spawn items from. If you are familiar with other 3D applications such as 3Ds Max or Maya, Target Point Actors are very similar to dummy Actors that you find in those programs.

Refer to the Target Point Actors page to learn more.

Actors and Geometry

There are some properties that are designated for this volume which can be adjusted from the Details panel.

Property

Description

Terminal Velocity

Determines the Terminal Velocity of Pawns using CharacterMovement when falling.

Priority

Determines which PhysicsVolume takes precedence if they overlap.

Fluid Friction

Determines the amount of friction applied by the volume as Pawns using CharacterMovement move through it. The higher this value, the harder it will feel to move through the volume.

Water Volume

Determines if the volume contains a fluid, like water.

Physics on Contact

Determines if the Actor is affected by the volume by touching it (by Default, an Actor must be inside the volume for it to affect them).

Actors and Geometry

Static Meshes

Placing a Static Mesh Actor

Changing a Static Mesh Actor's Material

Moving a Static Mesh Actor During Gameplay

Enabling Physics for Static Mesh Actors

Enabling Collision for Static Mesh Actors

The Static Mesh Actor is a simple type of Actor that displays a 3D mesh in the Level. Although the name implies that the Actor is static (or unable to move), the "static" refers to the type of mesh used rather than the Actor's ability to move. A mesh is static if its geometry does not change. Otherwise, the Actor itself can be moved or changed in other ways during play.

Static Mesh Actors are commonly used to create game worlds or other types of environments.

Unreal Engine includes the following default Static Mesh Actors:

Cube

Sphere

Cylinder

Cone

Plane

In addition to these, you can import your own Static Mesh Actors that were created in other 3D applications.

To learn more about how to import content into Unreal Engine, refer to the Importing Assets Directly page.

Placing a Static Mesh Actor

The quickest way to place a Static Mesh Actor is to drag it into the Level Viewport from the Content Browser. You can then use its Transform properties to place it where it needs to be.



To learn about other methods for placing Actors, refer to the Placing Actors page.

Changing a Static Mesh Actor's Material

You can override the Materials applied to a Static Mesh individually for each Static Mesh Actor. This way, you can use a single Static Mesh Asset more than once in a Level while giving each a unique appearance.

The example below shows three Static Mesh Actors that use the same Static Mesh, which is a simple three-dimensional cube. Each Actor uses a different Material.



To replace the Material assigned to a Static Mesh, locate the Material in the Content Browser, then drag it over the Static Mesh Actor in the Level Viewport, as shown in the example below.



To learn about other methods for assigning a Material to a Static Mesh, refer to the Setting Up Materials With Static Meshes page.

Moving a Static Mesh Actor During Gameplay

An Actor's Mobility setting controls whether an Actor can move or change in some way during gameplay.

By default, Static Mesh Actors have Static mobility. To move, rotate, or scale a StaticMeshActor during play, you must first make it Movable. To do this, in the Actor's Details panel, set its Mobility to Movable.



To learn more about different Mobility settings and how they affect Static Mesh Actors, refer to the Actor Mobility page.

Enabling Physics for Static Mesh Actors

If you want a Static Mesh Actor to be affected by gravity and collisions, enable the Simulate Physics property in the Actor's Details panel.



You can read more about how physics are implemented in Unreal Engine in the Physics section.

In the example below, the sphere Static Mesh Actor has Simulate Physics enabled. When simulation starts, gravity affects the sphere and makes it fall until it collides with the ground.



Enabling Collision for Static Mesh Actors

Collision is an Actor's property to react to other Actors in the environment when they collide with that Actor.

By default, if a Static Mesh has Physics Bodies, either generated in your 3D authoring package (see FBX Content Pipeline) or in the Static Mesh Editor (see Collision Response Reference), it will have collision and it will be set to Block All.

Refer to the Collision documentation for more information on different types of collision and how they affect a Static Mesh Actor.

Actors and Geometry

Skeletal Mesh Animation System

Placing a Skeletal Mesh Actor

Animating a Skeletal Mesh Actor

Changing a Skeletal Mesh Actor's Material

Skeletal Mesh Actor Collision

The Skeletal Mesh Actor displays an animated mesh whose geometry can be deformed, typically through the use of control points during animation sequences. These can either be created and exported from external 3D animation applications, or programmed directly in Unreal Engine.

To learn more about how to import content into Unreal Engine, refer to the Importing Assets Directly page.

Like the name suggests, Skeletal Meshes have a skeleton that consists of a number of bones. These are used in the animation process.

Skeletal Mesh Actors are commonly used to represent player characters, NPCs, other animated creatures, and complex machinery. The Unreal Engine Mannequin that appears in the



Placing a Skeletal Mesh Actor

The quickest way to place a Skeletal Mesh Actor is to drag it into the Level Viewport from the Content Browser. You can then use its Transform properties to place it where it needs to be.



To learn about other methods for placing Actors, refer to the Placing Actors page.

Animating a Skeletal Mesh Actor

There are two basic ways to animate a Skeletal Mesh Actor in Unreal Engine:

Using an Animation Blueprint to play and blend multiple animations together.

Using an Animation Asset to play a single Animation Sequence one time or in a loop.

To learn more about animating Skeletal Meshes, refer to the Skeletal Mesh Animation System page.

Changing a Skeletal Mesh Actor's Material

You can override the material of a Skeletal Mesh Actor individually to change its appearance. This is useful if you want to use the same Static Mesh in the Level multiple times, but want to have some variation between them.

The example below shows three Skeletal Mesh Actors that use the Unreal Mannequin Skeletal Mesh. Each Actor uses a different Material.



To replace the Material assigned to a Skeletal Mesh, locate the Material in the Content Browser, then drag it over the Skeletal Mesh Actor in the Level Viewport, as shown in the example below.



To use a Material with a Skeletal Mesh Actor, you need to enable the Used with Skeletal Mesh option. To do this:

In the Content Browser, double click the Material to open it in the Material Editor.

In the Details panel, enable the Used with Skeletal Mesh option.



The Used with Skeletal Mesh option in the Material Editor. Click for full size.

Skeletal Mesh Actor Collision

Normal collision creation and detection does not work with Skeletal Mesh Actors. To have your Skeletal Meshes collide with objects in the Level, your Skeletal Mesh Actors need to have a Physics Asset that is specifically created for them.

To learn more about Physics Assets and their use, refer to the [making-interactive-experiences/Physics/physics-asset-editor) documentation.

To create and assign a Physics Asset to a Skeletal Mesh Actor, follow these steps:

Find the Skeletal Mesh in the Content Browser and right-click it.

In the context menu, select Create > Physics Asset > Create and Assign.



Creating and assigning a Physics Asset to a Skeletal Mesh.

Level Editor

Level Editor Modes

Actors and Geometry

Uses for Geometry Brushes

Creating Brushes

Brush Primitives

Modifying Brushes

Brush Properties

Drag Grid

Brush Order

Brush Surfaces

Brush Solidity

Next Steps

Geometry Brushes, also known as Binary Space Partitioning (BSP) Brushes, is Unreal Engine's tool for level construction. Conceptually, it is best to think of a Geometry Brush as filling in and carving out volumes of space in your level. You can use the brushes to create basic shapes for your level design process, either as permanent fixtures or as something temporary to test while your artists create the final meshes.

Previously, Geometry Brushes were used as the primary building block in level design. However, that role has been passed on to Static Meshes, which are far more efficient. However, Geometry Brushes can still be helpful in the early stages of a product for rapid prototyping of levels and objects, espcially those who do not have access to 3D modeling tools. This document goes over the use of Geometry Brushes and how to utilize them for your level.



Geometry Brushes are not recommended as a final method of level design. It is not required, but can be useful at the early stages of creation.



Uses for Geometry Brushes

While Static Meshes are now primarily used to populate levels with geometry, Geometry Brushes still have their place. Here are some of the typical uses of Geometry Brushes:

Blocking Out Levels

A standard workflow for developing a level might go something like:

Block out and path level

Playtest flow and gameplay

Modify layout and repeat testing

Initial meshing pass

Initial lighting pass

Playtest for collision and performance issues

Polish pass





Brush Blocking / Rough-In

Final level

The first step is to block out the level to figure out the layout and flow before putting any time into populating the level with Static Meshes and other finished art assets. You can do this by using Geometry Brushes to create a shell for the level, then, through testing and iterating, the team agrees on the final layout. Geometry Brushes are perfect for this aspect of the level design process because it does not require any time or involvement from the art team. The level designer can use the tools built into the Unreal Editor to create and modify the Geometry Brushes until they are happy with the layout and the way the level plays.

As testing finalizes and meshing begins, the level designer gradually replaces Geometry Brushes with Static Meshes. This replacement process allows for faster initial iterations and provides an excellent reference for the art team.

Simple Filler Geometry

Often, when a level designer is creating their level, they will come upon a situation where they need a relatively simple piece of geometry to fill in a gap or space. If no existing Static Mesh fills the area, instead of tasking the art team to create a custom mesh, the designer can use Geometry Brushes to fill the space. Even though Static Meshes are better performance-wise, you can occasionally use Geometry Brushes without any serious impact as long as the geometry is simple.

Creating Brushes

Create a brush using the Geometry tab in the Place Actors panel:

Choose Place Actors Panel from the add dropdown.



Select the Geometry icon.



Drag one of the primitive types from the list into a Viewport.



Choose the Brush Type (additive or subtractive) in the Details panel.

Modify your Brush using the Brush Settings in the Details panel, the transform widget, or activate the Brush Editing Mode. See Modifying Brushes for more details.

Brush Primitives

Primitive

Description



Creates a Geometry Brush Actor in a Box shape that can then be customized within the Details panel. Options include:

Box Builder Settings

X

Set the size in the X-Axis.

Y

Set the size in the Y-Axis.

Z

Set the size in the Z-Axis.

Wall Thickness

If Hollow is checked, set the thickness of the inner walls of the Brush.

Hollow

Check this box to have a hollow space inside the Brush (which is a fast way to make a room) rather than a solid. If checked, enables the Wall Thickness setting.

Tessellated

Check this box to tessellate the sides of the box into triangles, rather than remaining as quads.





Creates a Geometry Brush Actor in a Cone shape that can then be customized within the Details panel. Options include:

Cone Builder Settings

Z

Set the height in the Z-Axis.

Cap Z

If Hollow is checked, set the height of the inner cap in the Z-Axis.

Outer Radius

Set the radius of the base of the cone.

Inner Radius

If Hollow is checked, set the radius of the inner wall of the cone.

Sides

Set the number of sides around the shape of the cone.

Align to Side

Check this box to align the rotation of a side along the X-Axis. Disable to let one of the angles point down the axis.

Hollow

Check this box to have a hollow space inside the Brush (which is a fast way to make a room), rather than a solid. If checked, enables the Inner Radius setting.





Creates a Geometry Brush Actor in a Cylinder shape that can then be customized within the Details panel. Options include:

Cylinder Builder Settings

Z

Set the height in the Z-Axis.

Outer Radius

Set the radius of the cylinder.

Inner Radius

If Hollow is checked, set the radius of the hollow space inside the cylinder.

Sides

Set the number of sides around the shape of the cylinder.

Align to Side

Check this box to align the rotation of a side along the X-Axis. Disable to let one of the angles point down the axis.

Hollow

Check this box to have a hollow space inside the Brush (which is a fast way to make a room), rather than a solid. If checked, enables the Inner Radius setting.





Creates a Geometry Brush Actor in a Curved Staircase shape, meaning a staircase that bends around at an angle but cannot wrap over itself - for that, you would need a Spiral Staircase. The Curved Staircase extends all the way to the ground. The shape can be customized within the Details panel. Options include:

Curved Stair Builder Settings

Inner Radius

Set the radius of the inner column around which the steps will wrap.

Step Height

Set the height of each stair.

Step Width

Set the width of each stair.

Angle of Curve

Set the angle of rotation for each stair.

Num Steps

Set the number of steps in the staircase.

Add to First Step

Set the additional height to the first step, effectively changing the height of the entire staircase. (Enter a negative value to reduce the height of the first step).

Counter Clockwise

Check this box to curve the stairs counterclockwise rather than clockwise.





Creates a Geometry Brush Actor in a Linear Staircase shape, meaning a straight staircase that does not bend. The staircase extends all the way to the ground. The shape can then be customized within the Details panel. Options include:

Linear Stair Builder Settings

Step Length

Set the length of each stair.

Step Height

Set the height of each stair.

Step Width

Set the width of each stair.

Num Steps

Set the number of stairs in the staircase.

Add to First Step

Set additional height to the first step, effectively changing the height of the entire staircase. (Enter a negative value to reduce the height of the first step).





Creates a Geometry Brush Actor in a Spiral Staircase shape, meaning a staircase can repeatedly wrap over itself. This staircase does not extend all the way to the ground. The shape can be customized within the Details panel. Options include:

Spiral Stair Builder Settings

Inner Radius

Set the radius of the inner column around which the steps will wrap.

Step Width

Set the width of each stair.

Step Height

Set the difference in the height of each stair relative to the stair below it.

Step Thickness

Set the thickness of the stair.

Num Steps Per 360

Set the number of steps required to make one complete revolution.

Num Steps

Set the number of steps in the staircase.

Add to First Step

Set additional height to the first step, effectively changing the height of the entire staircase. (Enter a negative value to reduce the height of the first step).

Sloped Ceiling

Check this box to create a sloped underside for the staircase, rather than tiers.

Sloped Floor

Check this box to create a sloped floor, effectively turning it into a spiraling ramp instead of a traditional staircase.

Counter Clockwise

Check this box if you want the stairs to curve counterclockwise instead of clockwise.





Creates a Geometry Brush Actor in a Sphere shape that can then be customized within the Details panel. Options include:

Sphere Builder Settings

Radius

Set the radius of the sphere.

Tessellation

Set the number of sides used to make the sphere. Due to the method of tessellation, this is capped at 5.



Modifying Brushes

You can modify Brushes using several methods, each suited to particular situations and how you wish to edit the Brush.

Brush Editing Mode

The best way to change a Brush's actual shape is to use the Brush Editing Mode. This editor mode allows the direct manipulation of the Brush's vertices, edges, and faces. It is very similar to working in a very simplified 3D modeling application.



You can have the Brush Editing and Place Actors panels open simultaneously for workflow efficiency.



For more information about Brush Editing Mode and how to use it to modify Brushes, see the Level Editor Modes page.

Transform Widgets

It is possible to modify your Brush using the various editor transform widgets. These allow you to translate, rotate, and scale interactively and are accessible via the widget buttons in the viewport toolbar:



For more information on the Transform widgets and how to use them, please see Transforming Actors.

Brush Properties

You can edit existing Brushes by selecting the Brush and using the Details panel. If you have the entire Brush selected, you will see the Brush Settings category:



Brush Types

The Brush Type dropdown includes the following:

Brush Type Dropdown

Additive

Set the Brush to Additive.

Subtractive

Set the Brush to Subtractive.

Each Brush Type is particularly suited to specific situations.

Additive Brushes are solid, filled-in spaces. The Additive Brush is the type you use for any Brush geometry you wish to add to the level. A good way to visualize an additive Brush is to imagine the four walls, the floor, and the ceiling of a room. Each would be a separate box-like Additive Brush in your map, with corners matching up to form an enclosed space.

A Subtractive Brush is a hollow, carved-out space. This is the type of Brush you would use to remove solid space to create doors, windows, and so on, from previously created additive Brushes. Subtractive space is the only area that players can freely move around in.

Advanced Properties

Clicking the button at the bottom of the Brush Settings exposes the advanced Brush properties:



The Polygons dropdown offers the following options:



Polygons Dropdown

Merge

Merge together any planar faces on a Brush.

Separate

Reverse the effects of a merge.

The Solidity dropdown includes the following:

Be sure to read the Brush Solidity section for more details.



Solidity Dropdown

Solid

Set the Brush solidity to be solid.

Semi Solid

Set the Brush solidity to be semi-solid.

Non Solid

Set the Brush solidity to non-solid.

The Order dropdown includes the following:

Be sure to read the Brush Order section for more details:



Order Dropdown

To First

Make the selected Brush the first to be calculated.

To Last

Make the selected Brush the last to be calculated.

Align and Static Mesh Buttons

If you expand the properties under the Brush Settings Category, the following buttons appear:

Brush Type Dropdown

Align Brush Vertices

Snap the Brush's vertices to the grid.

Create Static Mesh

Convert the current Brush to a Static Mesh Actor, saved at the location specified.

Drag Grid

The drag grid used to snap objects in the world is very important when working with Brushes. If you don't set the edges or corners of Brushes on the grid, errors can occur, causing rendering artifacts or other problems. You should always make sure the drag grid is enabled when working with Brushes and make sure that you keep the vertices of your Brushes on this grid at all times.

Brush Order

The order in which Brushes are placed is critical, as the addition and subtraction operations are performed according to this order. Placing a subtractive Brush and then an additive Brush will not have the same effect as placing an additive Brush and then a subtractive Brush, even if they are in the exact locations.

If you subtract from empty space and add on top, the subtractive Brush is essentially ignored, as you cannot subtract from anything. However, if you place those same Brushes in the opposite order, you add to empty space, then subtract from the addition, carving space out of it.

Sometimes you may place Brushes out of order or want to add a new Brush that needs to be calculated before an existing Brush. The Brushes' order can be modified, as seen in the Brush Properties section.

Brush Surfaces

If you select a Brush surface (use Ctrl + Shift + Left Click to select the surface and not the Brush), you will see the following categories in the Details panel:



Geometry Category

The Geometry category contains a few tools for helping you manage Material application across Brush surfaces.

Geometry Category Buttons

Select

Helps you select Brush surfaces based on various situations.

Alignment

Realigns the texture coordinates for surfaces based on your desired settings. This is useful, for example, when you need a complex arrangement of Brushes along the floor to align and look like a single surface.

Clean Geometry Materials

If, through any operations, your Brush surfaces have lost their Material, this will fix the problem.

Surface Properties

The Surface Properties area contains various tools to help you control how textures are placed across your surfaces, as well as lightmap resolution.

Surface Property Categories

Pan

The buttons in this section allow you to pan the texture of the Material either horizontally or vertically by the given number of units.

Rotate

Rotates the texture on a Brush surface's Material by the given number of degrees.

Flip

Allows you to flip the texture on a Brush surface horizontally or vertically.

Scale

Resizes the texture of a Brush surface by the amount given.

The Lighting section allows you to change various important light-centric properties for your Brush surfaces.

Lighting Properties

Lightmap Resolution

Essentially allows for adjustment of the shadows across this surface. The lower the number, the tighter the shadows.



Lightmass Settings



Use Two Sided Lighting

If checked, this surface will receive light on both the positive and negative sides of each polygon.

Shadow Indirect Only

Check this box to allow the surface to create shadows from indirect lighting.

Use Emissive for Static Lighting

Check this box to allow the emissive color of the surface to influence the lighting of static objects.

Use Vertex Normal for Hemisphere Gather

Check this box to use the vertex normal rather than the default triangle normal that prevents self-shadowing.

Emissive Boost

Scales the amount of influence emissive color will have on indirect lighting.

Diffuse Boost

Scales the amount of influence diffuse color will have on indirect lighting.

Fully Occluded Samples Fraction

Fraction of samples along this surface that must be occluded before it is considered to be occluded from indirect lighting calculations.

Brush Solidity

Brushes can be either Solid, Semi-solid, or Non-solid. The solidity of a Brush refers to whether it collides with objects in the world and whether the Brush causes BSP cuts to be created in the surrounding Brushes when building geometry.

The solidity of Brushes can be changed in the Details panel after you create a Brush:



The three types of solidity are explained below.

Solid

Solid Brushes are the default type of Brush. You get these when you create a new additive or subtractive Brush. They have the following attributes:

Block players and projectiles in the game.

Can be additive or subtractive.

Create cuts in the surrounding Brushes.

Semi-Solid

Semi-solid Brushes are colliding Brushes that can be placed in your level without creating cuts to the surrounding world geometry. You can use it to make pillars and support beams, though such objects should be created using Static Meshes. They have the following attributes:

Block players and projectiles, just as Solid Brushes do.

Can only be additive, never subtractive.

Do not create cuts in the surrounding Brushes.

Non-Solid

Non-Solid Brushes are non-colliding Brushes that also do not create cuts in the surrounding world geometry. These have the effect of being visible but unable to be interacted with in any way. They have the following attributes:

Do not block players or projectiles.

Can only be additive, never subtractive.

Do not create cuts in the surrounding Brushes.

Next Steps

After learning the essentials of Geometry Brushes, you can familiarize yourself with the geometry tools in Modeling Mode to further develop your level. To use the Modeling Mode tools on your current Geometry Brushes, you need to convert them using Create Static Mesh in the Advanced tab.

Placing a Camera Actor

Previewing a Camera Actor

Any kind of experience you create in Unreal Engine 5, whether it is a game or something else, will need at least one Camera through which a user can view it. Unreal Engine contains different kinds of Camera Actors that you can use for this purpose.

The following types of Camera Actors are available in Unreal Engine:

Camera Actor, which is a generic type of camera that can be used as a stationary or mobile viewpoint.

Cine Camera Actor, which is a specialized type of camera used to create cinematics. Refer to the Cine Camera Actor page to learn more.

In addition to Camera Actors, you can use the following types of Actors to work with cameras in Unreal Engine:

Actor Type

Description

Further Reading

Camera Blocking Volume

Prevents the camera from entering a specific volume. This is useful, for example, to prevent the camera from clipping through walls or other environments.

Camera Rig Crane

Emulates a boom arm or Camera Jib system, which is used to create Crane Shots. The crane can be pivoted along horizontal and vertical axes, and can be extended as needed.

Camera Rigs

Camera Rig Rail

Emulates a Camera Dolly system, which is used to create Tracking Shots. The rail's track length and curvature can be modified to suit the needs of your shot.

Camera Rigs

Level Sequence Actor

Acts as a container for the Level Sequence Asset. The Level Sequence Asset is located in the Content Browser and contains Sequencer's data. This includes tracks, cameras, keyframes, and animations. This is assigned to a Level Sequence Actor in order to bind its data to a Level.

Sequencer Overview

Placing a Camera Actor

Camera Actors are placed from the Place Actors panel. To add a Camera to your Level, find it in the Place Actors panel, then drag it and drop it into the Level Viewport.

Previewing a Camera Actor

If you select a Camera Actor (or a Blueprint that contains a Camera component), a separate preview window will open within the Level viewport. This window shows what the currently selected Camera "sees".



The Preview window of a Camera Actor. Click the image for full size.

Actors and Geometry

Several properties can be adjusted from the Details panel on this volume to allow for more control over its effects as seen below.



Property

Description

Priority

In the event of overlapping volumes, the highest priority volume will be used. The order is undefined if two or more overlapping volumes have the same priority.

Apply Reverb

Determines if the reverb settings should be used.

Reverb Effect

This is the reverb asset to use for the volume.

Volume

This is the overall volume level of the reverb effect.

Fade Time

This is the time (in seconds) to fade from the current reverb settings into the volumes setting.

Enabled

Determines whether the volume is currently enabled and is able to affect sounds.

Ambient Zone Settings define how Sound Actors located inside the associated Audio Volume will be altered by the Player's location. The Ambient Zone Settings can be adjusted from the Details panel.

Property

Description

Exterior Volume

The final volume of exterior sounds when the player is inside the volume.

Exterior Time

Time to fade to new exterior volume in seconds.

Exterior LPF

Lowpass Filter multiplier applied to exterior sounds when inside (1.0 to apply the maximum LPF).

Exterior LPFTime

Time to fade to new Lowpass Filter level in seconds.

Interior Volume

The final volume of interior sounds when the player is outside the volume.

Interior Time

Time to fade to new interior volume in seconds.

Interior LPF

Lowpass Filter multiplier applied to interior sounds when outside (1.0 to apply the maximum LPF).

Interior LPFTime

Time to fade to new Lowpass Filter level in seconds.

Respawning a Player Character

Placing a Player Start Actor

Player Start BADsize Warning

Using Player Start Actors in Blueprints

Ignoring Player Start in PIE

For any Unreal Engine project that uses playable characters, you can use the Player Start Actor to control where, in the game world, each player character will spawn at runtime.

The Player Start Actor is visually represented as a game controller icon with a flag and an arrow that indicates which direction the player will be facing when they spawn.

When you select a Player Start Actor, you will see two additional components: a Capsule that is a visual representation of the physical space the Actor occupies in the game world, and a Transform widget.



A Player Start Actor in the Level. Left: Unselected; Right: Selected. Click the image for full size.

If your Level doesn't have a Player Start Actor, the player will always start at the 0,0,0 coordinates in the world.

Placing a Player Start Actor

Player Start Actors are placed into the Level via drag-and-drop, same as other Actors.

You can have multiple Player Start Actors into the Level and control which Player Start is used as the player spawn location using Blueprint or C++.

To place a Player Start Actor, follow these steps:



Click the image for full size.

Click the Quick Add button on the Main Toolbar.

Select Basic > Player Start.

Click and drag the Player Start Actor into the Level Viewport.

When using a Player Start Actor to spawn a player, the position and rotation of the player character will match the Player Start's position and rotation. If you want to have a player look at something specific when they spawn, make sure that the arrow component of the Player Start you use to spawn them is pointing in the direction that you want the player to look.

If you have more than one Player Start Actor in your Level, the player will start from a random Player Start each time, prioritizing Player Start Actors that are unobstructed.

Player Start BADsize Warning

While placing or moving a Player Start Actor, you may see a white label with red borders and the text BADsize.



Click the image for full size.

This warning appears when the Player Start Actor overlaps or intersects with something else in the Level, such as props or terrain. To resolve this, move the Player Start until its Capsule component no longer overlaps or intersects with anything else.

Using Player Start Actors in Blueprints

Unreal Engine has several Blueprint nodes that you can use to work with Player Start Actors. These are useful for a number of different scenarios, including respawning players at a Player Start Actor's location or spawning a player at a different Player Start based on different conditions.

The following nodes for working Player Start Actors are available in the Game Mode Blueprint:

FindPlayerStart: Finds a Player Start Actor in the Level based that has a specific tag (defined in the IncomingName property). You can set a Player Start Actor's tag from the Actor's Details panel.



Restart Player at Player Start: Respawns a player using a specified Player Start Actor.



The screenshot below shows an example of how to use these nodes to restart a player at the location of a Player Start with the tag TheStartIWant when pressing the E key. If you want to try this yourself, recreate these nodes in your project's Game Mode Blueprint.



Click the image for full size.

Ignoring Player Start in PIE

When you preview your game in the Unreal Editor using Play-in-Editor (PIE), if you click the Play button in the Main Toolbar, your character will spawn at the Player Start Actor's location.

However, you can also start playing from anywhere within your Level by right-clicking in the Level Viewport and selecting Play From Here from the context menu.

Actors and Geometry

Placing Triggers

Triggering Events

Triggers are Actors that are used to cause an event to occur when they are interacted with by some other object in the level. In other words, they are used to trigger events in response to some other action in the level. All of the default Triggers are generally the same, differing only in the shape of the area of influence - box, capsule, and sphere - used by the Trigger to detect if another object has activated it.







Box Trigger

Capsule Trigger

Sphere Trigger

Placing Triggers

Triggers can be placed in the level by dragging and dropping one of the Trigger types. In Select mode, you can drag a Trigger type from the Place Actors panel Basic tab.



Triggering Events

Triggers are used to activate events placed inside of the Level Blueprint. There are several different types of events that a Trigger can activate. The main ones happen in response to some type of collision with another object, such as something hitting or overlapping with the Trigger, or in response to input from the player.

With the Trigger selected in the Viewport:

Right-click in the Level Blueprint Event Graph and choose one of the events under Add Event for [Trigger Actor Name].



Choosing an event via either of these methods results in an Event node being added to the Level Blueprint for the current level:



The exec pin of the new event node will fire each time the particular event occurs - in the example above, any time an Actor overlaps (or runs through) the Trigger:

Placing Volumes

Representing Volumes Visually

Volume Types in Unreal Engine

Collision and Overlap Volumes

Blocking Volume

Camera Blocking Volume

Kill Z Volume

Pain-Causing Volume

Physics Volume

Trigger Volume

Graphics and Audio Volumes

Audio Volume

Cull Distance Volume

Hierarchical LOD Volume

Lightmass Volumes

Mesh Merge Culling Volume

Post Process Volume

Precomputed Visibility Volume

Precomputed Visibility Override Volume

Level and AI Volumes

Nav Mesh Bounds Volume

Volumes are three-dimensional Actors that change the behavior and characteristics of the area they cover in a Level.

Volumes are support Actors, generally used to detect when certain Actor types have entered a specific area and trigger something in response. Volumes sometimes have built-in effects of their own (either in code or Blueprints).

You can use Volumes to implement effects and behaviors like:

Causing damage to the player or other Actors inside the Volume.

Blocking certain Actors from entering the Volume, acting as a collision surface.

Changing something in the environment (for example, opening a door) when an Actor enters the Volume.

Changing the lighting or visibility in a Level.

Placing Volumes

Place Volumes in a Level in the same way you place any other Actor:

In the Main Toolbar, click the Create button.



Select the Volumes category, then drag the Volume you want to place to the Level Viewport.

For more information, see Placing Actors.

After you place a Volume in the Level, you can resize or reposition it. For more information, see Transforming Actors.

Representing Volumes Visually

Volumes don't have a default visual representation when placed into a Level. In other words, a Volume Actor will be completely invisible at runtime (when your game runs). If you want the player to know that the Volume is there, you must add a visual representation to it.

For example, a Pain-Causing Volume causes damage to anything inside the Volume. You can use it to mark an area that you want the player to avoid, like poison, lava, or another environmental hazard.

If you pace a Pain-Causing Volume into a Level, but don't add any visual representation to it, the player won't see it at runtime:





In-Editor

In-game/PIE

In this case, the player will not know to avoid the Volume, or understand why they take damage when they enter it.

You should provide a hint to the player that explains the Pain Causing Volume:





In-Editor

In-game/PIE

In this case, the fire particle effect provides a visual explanation of why the area is dangerous, while the Pain Causing Volume supports the visuals with the gameplay effect of decreasing the player's health during exposure to the fire.

You can combine the Pain Causing Volume and fire particle effect into a single Actor to be able to move them and duplicate them easily.

Volume Types in Unreal Engine

This section describes some of the commonly used types of volumes in Unreal Engine. Note that this isn't an exhaustive list. Specialized volumes are described in detail in the documentation for their respective areas.

Collision and Overlap Volumes

You can use Blocking Volumes instead of collision surfaces on Static Meshes, particularly in the case of walls in structures. This can cause scenes to operate more predictably, since physical objects won't interact with small details like bumps on the floor and walls. It can also improve performance by reducing the cost of physics simulation.

For more information, see Collision documentation.

Camera Blocking Volumes have pre-configured collision settings that block cameras and ignore everything else. They are intended to define invisible barriers that keep the camera out of unwanted locations.

For example, in a third-person game, the walls of the play area might have decorative coverings, like leafy vines. In this case, you can place a thin Camera Blocking Volume against the wall so that the camera doesn't bump into the vines or go behind the leaves, leaving it to slide smoothly and provide an unobstructed view of the player action.

Use a Kill Z Volume to prevent objects from going out of bounds in certain types of games, such as falling off of a cliff or into a pit in a platformer game, or leaving a spaceship without a suit in a science-fiction setting.

The Kill Z Volume calls the FellOutOfWorld function on any Actor that enters it. By default, Actors will go through a quick cleanup procedure and then destroy themselves. You can override this behavior for any of your Actor types if your game requires something different. For example, if a key or other item that the player is required to collect in order to continue the game falls into a lava pit, your game might want to teleport the item back up to an area the player can reach rather than destroying it, or at least inform the player that the item was lost and reload the last checkpoint, rather than leaving the game in an unwinnable state.

Pain-Causing Volumes, described above, have a set of configurable properties that you can use to specify:

The type and amount of damage they cause

How often they damage what's inside

Whether they cause initial damage

Configure these properties in the volume's Details panel.

If you want to configure the physical setup that affects characters and other physics objects, use Physics Volumes.

A common use for a Physics Volume is the creation of watery environments where the player needs to swim. The effects of Physics Volumes are visible and, paired with the appropriate visual representation, they are easy for the player to understand.

The Character Movement Component class uses the current fields to adjust how their owning Character moves through the environment. If your game has custom physics, derive your own child class from APhysicsVolume.

Trigger Volumes can cause events when a Player or other object enters or exits them. Use them with the Level Blueprint to test out events and gameplay scenarios or functionality without the need for additional Blueprints.

For example, you could place a Trigger Volume in your Level, then create an overlap event for the Volume in your Level Blueprint, which can play a sound, open a door, or start a cinematic scene.

Remember to check the collision settings to ensure that your trigger will react to the intended Actors with the Overlap collision response setting.

Graphics and Audio Volumes

Audio Volumes add sound to the area they cover. There are two kinds of audio volumes you can use:

Audio Volumes (legacy approach)

Audio Gameplay Volumes

Cull Distance Volumes cause objects to be culled (not drawn to the screen) based on that object's distance from the camera and the object size. This can help optimize your scene by not drawing objects when they are small enough to be considered unimportant. Size is calculated by the bounding box along its longest dimension, and the cull distance chosen is the one closest to that size.

For more information, see ()[designing-visuals-rendering-and-graphics\rendering-optimization\visibility-culling\CullDistanceVolume].

Hierarchical LOD Volumes are used by the Hierarchical Level of Detail (HLOD) system to group Actors into a single HLOD cluster. When generating clusters, the Unreal Engine overrides its normal generation process in deference to manually-placed Volumes.

Many maps have meshes out to the edge of the grid in the editor, but the actual playable area that needs high quality lighting is much smaller. Lightmass emits photons based on the size of the level, so those background meshes will greatly increase the number of photons that need to be emitted, and lighting build times will increase.

The Lightmass Importance Volume controls the area that Lightmass emits photons in, allowing you to concentrate it only on the area that needs detailed indirect lighting. Areas outside the importance volume get only one bounce of indirect lighting at a lower quality.

The Lightmass Character Indirect Detail Volume is similar to the Lightmass Importance Volume and generates indirect light samples, not just at Player height above ground, but inside the entire Volume. An example of how this type of Volume is used would be to place the Volume in an elevator shaft, ensuring that indirect lighting will be correct all the way along the shaft, instead of just at the bottom.

For more information, see Lightmass Basics.

Mesh Merge Culling Volumes mark the mesh objects they contain so that these objects will be combined into a single mesh. This can improve performance by making a collection of small meshes in a contained area all cull together as one mesh, or by causing HLOD generation to more optimally reduce geometry.

For more information, see Merging Actors

A Post Process Volume can override Post Process settings applied to the camera inside the volume. You can use it to implement different kinds of visuals in different areas of your Level. For example, you may want a different depth of field (DoF) for indoor and outdoor areas, or different degrees of bloom depending on localized weather effects, like fog.

For more information and a list of effects you can use, see Post Process Effects.

Precomputed Visibility Volumes are used primarily for performance optimization. These Volumes store the visibility of Actors for their location in the world. Only place these in areas that the player can access.

For more information, see Post Process Effects.

Use Precomputed Visibility Override Volumes to manually override the visibility of Actors for their location in the world if the auto-generated result of a Precomputed Visibility Volume needs to be adjusted. These are also used for performance optimization and should only be placed in areas the Player can access.

For more information, see Visibility and Occlusion Culling.

Level and AI Volumes

Nav Meshes calculate navigation paths throughout the areas of a level. Nav Mesh Bounds Volumes are used to control where Nav Meshes will be built in a level.

Within the Volume, a Nav Mesh is constructed on all surfaces with an appropriate angle to be walked upon. You may overlap as many of these as you need to generate the desired Nav Mesh.

To use the Nav Mesh Bounds Volume, create one or more volumes that enclose the navigable areas of your Level. The Nav Mesh will be built automatically.

You can press P at any time in the viewport to visualize the Nav Mesh.

The Content Examples sample project demonstrates how to implement a Nav Mesh into your Level.

In addition to the properties that can be assigned from a Physics Volume, the Pain Causing Volume also has its own set of specific properties outlined below.

Property

Description

Pain Causing

Whether the volume currently causes damage or not.

Damage Per Sec

Damage done per second to the Actors in the volume when Pain Causing is enabled.

Damage Type

This determines the type of damage done to the Actor.

Pain Interval

This is the amount of time, in seconds, between applied damage when Pain Causing is enabled.

Entry Pain

Determines whether or not damage will be applied immediately upon entering the volume, assuming that Pain Causing is enabled. This damage is in addition to the recurring damage applied based on the Pain Interval.

Actors and Geometry

Adding decals to the level

Sizing, tiling and offsetting

Deferred Decal Properties

Material Settings

Performance

Current limitations

The 2x2 block artifacts fix

Current limitations

Deferred decals offer better performance and easier maintenance. Writing to the GBuffer instead of recalculating lighting has several benefits:

The performance with many lights gets much more predictable because there is no limit on the light count or type as the same code path is used for all of them.

Manipulating a screen space mask also allows effects that otherwise would be considered difficult (e.g. wet layer).

The decal is rendered by rendering a box around the decal affecting area.

Adding decals to the level

The easiest way to add decals to a scene is to select an appropriate decal material in the Content Browser, then right-click inside the Viewport and choose Place Actor from the context menu. The decal may then be resized and oriented using the transformation tools.



Sizing, tiling and offsetting

Once the decal is created, it can be positioned and oriented using the translation and rotation widgets.



The non-uniform scaling widget controls the width, height, and far-plane distance of the decal volume.

Deferred Decal Properties

A deferred decal has only a couple of properties:

Item

Description

Material

This holds the material that will be used as a decal.

Sort Order

This allows the user to set a value to control how multiple decals will sort when stacked. Higher values render on top.

Be careful when setting sort values. Setting too many sort values on too many different decals prevents those decals from being sorted via state, which can harm performance.

Material Settings

The DecalBlendMode setting defines how the material properties (diffuse, specular, normal, opacity, ...) are applied to the GBuffer.

The opacity is used to blend the decal contribution. An efficient decal is manipulating only few GBuffer properties. The cases we currently optimize for are represented by the other modes: DBM_Diffuse, DBM_Specular, DBM_Emissive, DBM_Normal.

Item

Description

Translucent

This will blend the full material, updating the GBuffer, and does not work for baked lighting.

Stain

This is Modulate BaseColor, blend rest, updating the GBuffer, and does not work for baked lighting.

Normal

This will only blend normal, updating the GBuffer, and does not work for baked lighting.

Emissive

This is for Additive emissive only.

DBuffer_Translucent Color, Normal, Roughness

This is for non-metal, put into DBuffer to work for baked lighting as well. This will become DBM_TranslucentNormal if normal is not hooked up.

DBuffer_Translucent Color

This is for non-metal, put into DBuffer to work for baked lighting as well.

DBuffer_Translucent Color, Normal

This is for non-metal, put into the DBuffer to work for baked lighting as well. This will become DBM_DBuffer_Color if normal is not hooked up.

DBuffer_Translucent Color, Roughness

This is for non-metal, put into DBuffer to work for baked lighting as well.

DBuffer_Translucent Normal

This is for non-metal, put into DBuffer to work for baked lighting as well.

DBuffer_Translucent Normal, Roughness

This is for non-metal, put into DBuffer to work for baked lighting as well. This will become DBM_DBuffer_Roughness if normal is not hooked up.

DBuffer_Translucent Roughness

This is for non-metal, put into DBuffer to work for baked lighting as well.

Volumetric Distance Function (experimental)

This will output a signed distance in Opacity depending on LightVector.

DBM_ScreenSpaceMask is special as it affects a special masking channel which is currently used by SSAO (Ambient Occlusion). This allows the decal to override or fade the contribution in some areas.

DBM_DiffuseSpecularEmissive is the mode that affects multiple GBuffer channels.

Note that the material blend mode also affects how the GBuffer values are blended together. So it is possible to multiply the diffuse color.

You can use the GBuffer view mode to inspect the GBuffer values that are stored per pixel.

The decal local position is a 3d position in the range 0 to 1. The texture UV is giving you the x and y component. In case you need the z component, you can hook up a CameraVector node to get all 3 vector components.

Performance

The mesh complexity of the objects affected by the decal is not affecting the performance. The decal performance depends on the shader complexity and the shader box size on the screen.

We can further improve the per decal performance. Ideally the bounding box of the decal is small to get better per pixel performance. This can be done manually. An automated method is possible but a good designer can also adjust the placement to improve performance further.

The view mode ShaderComplexity (editor UI or "viewmode ShaderComplexity") can be used to see the impact on the pixel shading cost, it uses a pixel shader cost estimate and accumulates where multiple decals overlap. At the moment the decal masking feature has no effect there (masked parts should have a small constant cost because of using the stencil hardware feature). The following shows a scene without (left) and with decals (right), in normal rendering (top) and with the ShaderComplexity enabled (bottom):



The darker color indicates a higher performance cost of those pixels. This information can be used to optimize the right shaders, remove barely visible decals or place them more efficiently.

Current limitations

We currently only support deferred decals and they only work on static objects.

Normal blending is currently not wrapping around the object.

Streaming is not yet hooked up so make sure the texture is not streamed.

Masking decals (not affecting other object) is not fully implemented.

The 2x2 block artifacts fix

Decals may have 2x2 pixels block artifacts on edges as shown in the screenshot below.



This is where the node "Decal Derivative" comes in. This node must be used carefully as it has a very big performance impact. It returns the derivatives on the X and Y axis of the decal's default texture coordinates necessary for anisotropic texture filtering, but computed differently than using the hardware's default and DDX/DDY nodes, to avoid this 2x2 pixel block artifact.



And using it fixes the artifacts on the decal that benefits from it.



Current limitations

DecalMipmapLevel doesn't support custom UV, but you can patch up its output.

Sequencer Overview

Enabling the 3D Text Plugin

Placing 3D Text in Your Level

Text 3D Actor Settings

Animating Letter-by-Letter

Text 3D Character Transform Settings

Add high-resolution 3D Text to your Level using the geometry-based Text 3D Actor. Use 3D Text objects in any project where you need to show clean, high-quality text in the virtual world, such as live broadcasts and virtual sets.

You can use the Sequencer Editor to animate your 3D text objects, creating motion graphics directly inside the Unreal Editor.

Enabling the 3D Text Plugin

To use 3D Text, you must first enable the Text 3D Plugin.

In the Main Menu Bar, select Edit > Plugins.

From the Text tab, enable Text 3D. You'll be warned that the Plugin is in an experimental state. Click Yes.

Click Restart Now to use the plugin in your project.

If you have made changes to your project, a window opens where you can save your work before restarting.

Placing 3D Text in Your Level

In the Place Actors panel, select All Classes, then Text 3D.

Drag and drop the Text 3D Actor into the level.

In the viewport, select the Text 3D Actor to view its parameters in the Details panel.

Text 3D Actor Settings

The following options are available in the 3D Text section of the Details Panel to control the way your 3D text appears.

Property

Description

Text

Shift+Enter

Extrude

Set the depth of the geometry: how thick the letters are from front to back.

Bevel

Set the size of the bevel along the edges of the characters.

Bevel Type

Set the type of edge bevel: Linear for a sharp, flat bevel, or Half Circle for a rounded edge.

Half Circle Segments

Set the number of segments used to create the curve for the Half Circle bevel.

Front Material

Select the Material to use for shading the front surface of the letters.

Bevel Material

Select the Material to use for shading the surface of the bevel.

Extrude Material

Select the Material to use for shading the sides of the letters.

Back Material

Select the Material to use for shading the back of the letters.

Font

Importing Fonts

Horizontal Alignment

Align horizontal text to the Left, Center or Right with respect to the position of the Actor in 3D space.

Vertical Alignment

Align the text vertically to put the Top Line, Top, Bottom or Center of the letters at the position of the Actor in 3D space.

Kerning

Set additional space between each character.

Line Spacing

Set additional space between each line.

Word Spacing

Set additional space between each word.

Max Width

Set the maximum width of the text.

Max Height

Set the maximum height of the text.

Scale Proportionally

Locks the height and width of the letters to their current ratio. When enabled, any change to either the height or width of the letters applies to both.

Animating Letter-by-Letter

You can interpolate the 3D translation, rotation, and scaling of the letters in a Text 3D Actor between configurable starting and ending values. You can set the order in which the animations progress across the letters in the text (left-to-right, right-to-left, from the middle letters out, or from the outer letters in), and how much each letter's animation overlaps with its neighbors. In combination with the Sequencer tool, this allows you to design dynamic motion graphics that apply animations letter-by-letter.

For example, the following video shows how to apply transforms to the location, scale, and rotation of the letters in a Text 3D Actor, then the effect of using a Level Sequence to animate the transforms over time.

Letter-by-letter animation in a Text 3D Actor is controlled by a Text3DCharacterTransform Component. You'll need to add one of these Components to your Actor, and set up its values.

To set up letter-by-letter animation:

Select your Text 3D Actor in the Viewport or the World Outliner.

In the Details panel, click Add Component and select Text3DCharacterTransform.



Select the new Text3DCharacterTransform at the top of the Details panel to access its settings.



Enable the location, rotation, and/or scale transforms, and adjust their settings to produce the animation effect you want. See the table below for a description of each setting.

As you adjust the settings for the location, rotation, or scale transforms, you can drag the Progress value back and forth between 0 and 100 to preview the effect.

Typically, you will want to use a Level Sequence to play back the animation effect you've designed over time. This will usually involve adding your Text 3D Actor to a Level Sequence, creating new tracks for the Progress setting, then creating keyframes on those tracks that make the values change between 0 and 100 over time. For example:



For details on creating a Level Sequence and working in the Sequencer Editor, see the Sequencer documentation.

Text 3D Character Transform Settings

The Text3DCharacterTransform Component exposes the following settings for the 3D location, rotation, and scale of your text. You can control the three types of transform separately.

Setting

Description

Enabled

Determines whether the Text3DCharacterTransform Component updates the location, rotation, or scale of the letters based on the values in this section.

Enabling this option adds some extra calculations for the CPU to carry out. Typically, you should only enable this setting for types of transforms that you actually need to animate.



Progress

Determines the overall progression of the text animation between the Begin and End states. At 0, the location, rotation, or scale of the text is at its Begin state. At 100, the location, rotation, or scale of the text is at its End state. Values in between interpolate the location, rotation, or scale proporationately in between the Begin and End states.

If you create a Level Sequence to animate the letter-by-letter transforms over time, this is typically the setting that you will want to animate in your Level Sequence.



Order

Determines the direction in which the animation progresses across the letters in your text.

Normal - The animation begins with the leftmost letter and progresses to the right.

From Center - The animation begins with the letters in the center of the text and progresses outward in both directions.

To Center - The animation begins with the outermost letters of the text and progresses inward toward the letters in the middle.

Opposite - The animation begins with the rightmost letter and progresses to the left.

Range

Determines how much overlap there is between adjacent letters. At 0, each letter completes its transformation from the Begin state to the End state before the next letter begins to transform. At 100, all letters begin and end their transformations at the same time. Values in between create a partial overlap between each successive pair of letters. For example, at 50,

Begin

Begin

End or Distance

Sets the desired end state for the location, rotation, or scale of the letters.



Actors and Geometry

Placing Target Point Actors

Using Target Points



When creating worlds for games you sometimes need the ability to place and spawn items in the world for the player to interact with. Target Point Actors do just this; they give you a generic point in the world that you can spawn items from. If you are familiar with other 3D applications like 3Ds Max or Maya, Target Point Actors are very similar to dummy Actors that you find in those programs.

Placing Target Point Actors

Target Point Actors can be found in the Modes panel under the All Classes category. To add one to the world, simply select it from the Modes panel and then drag it into the world.

Using Target Points

Target Point Actors can be used for all kinds of things inside Unreal Engine 4. Here is a list of some of the things that you can use Target Point Actors for.

Look-at targets for cameras during cinematic sequences.

Path points for AI agents.

Spawn point for a VFX.

Spawn points for items like health and item pickups.

Visual cue for where an item is placed / should be placed in the world.

Here is an example showing how a Target Point Actor was used as in a Blueprint to serve as a spawn point.



Component Instancing

A Component is a piece of functionality that can be added to an Actor.

When you add a Component to an Actor, the Actor can use the functionality that the Component provides. For example:

A Spot Light Component will make your Actor emit light like a spot light.

A Rotating Movement Component will make your Actor spin around.

An Audio Component will give your Actor the ability to play sounds.

Unlike Actors, Components can't exist by themselves. They must be attached to an Actor.

When adding Components to an Actor, you are putting together the bits and pieces that make up that Actor as a whole. For example, a car (Actor) consists of its wheels, steering wheel, body, lights, etc. (Components). Similarly, an Actor that represents a player character might have individual Components for the Skeletal Mesh (the character's visual representation), the Camera that follows the character around, and the Controller that receives input from the player.

After you put together the different Components that make up the Actor, you can place the Actor in your Level even without providing any Blueprint script (or C++ code) that dictates how the Actor should function. In keeping with the example above, a car (Actor) can exist as an object in the world (Level) without a driver (Blueprint or C++ code) telling it what to do. Blueprint or C++ code can then be used to access each of the car's Components individually (for example, if the gas pedal Component has been pressed, Blueprint logic could make the car speed up).

Component Instancing

Contrary to the default behavior of sub-objects in general, Components created as sub-objects within an Actor are instanced, meaning each Actor instance of a particular class gets its own unique instances of the Components.

A simple way to visualize this is to imagine the car from the example above above. A Car class might use Components to represent the wheels of the car. Four Wheel Components would be created as sub-objects in the default properties of the class and assigned to a "Wheels" array. When a new Car instance is created, new instances of the Wheel Components are created specifically for that particular Car. If this were not the case, when one Car in the world moved, the wheels of all Cars would turn; which is clearly not the desired behavior. Instancing of Components by default simplifies the process of quickly adding unique sub-objects to Actors.

Without Component instancing, all Component variables would need to be declared using the Instanced property specifier.

Content Examples

Artificial Intelligence



Components Window

Nav Modifier Component

Navigation Components are a type of component that modifies or extends the functionality of the NavMesh (Pathfinding) system in Unreal Engine.

Nav Modifier Component

The Nav Modifier Component does nothing by itself, however, if you have a basic shape component as the root of an Actor, the volume of that Root Component will modify the NavMesh generation within it according to the Nav Modifier Component's Area Class property. You should only have one Nav Modifier Component per Actor as multiples of this Component have no effect. Also, these will appear outside the hierarchy in the Components Tab, and cannot be parented to another component or have anything parented to them.

These Area Classes can define basic things like Cost to enter an area or more advanced things such as areas where a crouched character should be able to navigate.

Cost is an important idea for the NavMesh system. Briefly, the total cost to move from one point to another using NavMesh is the sum of all the area costs the path moves through (a single area's size is defined in the Project's Preferences). But, the solver will always try to find the cheapest path, so you can have it avoid areas (like slippery oil or rough terrain) by increasing the cost to pass through that area. Just remember the solver will still path through high cost areas if it is the cheapest path.

For example, the red area has a very high cost to move through, but the Pawn has no other choice but to move through it.:



But, if you remove a wall:



Then the pawn will avoid the red area even though it means taking a much longer route.

Collision

Physics Bodies

Landscape Splines

Arrow Component

Box Component

Capsule Component

Sphere Component

Spline Component

The Shape Components can be used to create collision or triggers around other objects, indicate orientation or create paths.

Arrow Component

The ArrowComponent is a simple arrow rendered using lines and is useful for indicating which way an object should face. As seen in the door example below, the arrow indicates which way the door should face when placed in the level (as the door may be scripted to only open one way, the direction in which the arrow is facing).



The actual arrow will not show up in-game (unless the Hidden in Game option is unchecked) and the color and size can be adjusted as desired. This Component does not have any collision settings and could poentially also be used as a "marker" for your scripts (for example, adding an ArrowComponent to a CharacterBlueprint just above the characters shoulder, then when the player presses a button, having the CameraComponent move to the location of the ArrowComponent creating an over-the-shoulder style camera).

Box Component

A BoxComponent is a box generally used for simple collision (can also be used as a trigger as in shown in the example below).



A BoxComponent was added around a fire particle effect, with its collision settings set to Generate Overlap Events. When something overlaps the box, an event will be fired where you execute script that applies damage to the Actor that overlaps it. You could also set the Collision Response to BlockAll which would prevent all Actors from entering the box (if you wanted to keep things from entering the fire).

Capsule Component

The CapsuleComponent is a capsule shape which can also be used as simple collision (shown below) or as a trigger.



Above a CapsuleComponent is automatically included when creating a new Character Blueprint and provides the collision settings for the character, keeping them from intersecting with objects in the world. The CapsuleComponent can also Generate Overlap Events or Generate Hit Events to allow you to provide scripts for when either of those events occur.

Sphere Component

SphereComponents are spherical shapes that can be used for collision (ie. collision around projectiles as shown below).



Just as with the Box and Capsule Components, you can set the Collision Responses to generate the type of collision functionality you need.

Spline Component

A SplineComponent can be used to make streets or complex paths (in which other Components can follow). Below a SplineComponent, BillboardComponent and ParticleSystemComponent were added to a Blueprint with the intent of having the particle system following the defined path created by the spline.



Inside the Editor Viewport, you can edit the spline by Right-clicking on the Actor that has SplineComponent. This will bring up a context menu with options like adding points to the spline or defining the type of spline point to use. Below, a path was created to represent the outline of the Unreal Engine logo.



After providing some Blueprint script to update the location of the particle effect, the end result is represented below.



Play In Editor (PIE)

Play Modes

PIE Console

Simulate In Editor (SIE)

You can instantly preview your game inside Unreal Editor at any time, without needing to build it into a standalone application first. This can help you quickly iterate on gameplay and asset tweaks and see how your game changes as a result.

There are two ways to preview your game in Unreal Engine:

Play In Editor (PIE), which you can access from the Play button on the Main Toolbar.

Simulate In Editor (SIE), which you can access from the Play drop-down menu or by using the Alt + S on Windows keyboard shortcut (or Option + S on macOS).

The key difference between playing and simulating in the Editor is that playing will always start the game at the Player Start location and give you control of the player character. Simulating doesn't move the Camera and doesn't spawn a player character.

You can toggle between Play In Editor and Simulate In Editor sessions as needed.

For this tutorial, we have created a new project using the Blueprint Third Person template with Starter Content enabled. If you have not created a project based off a template before or are not sure how to enable Starter Content, refer to the Creating a New Project page to learn how to do this.

Play In Editor (PIE)

This section will show you how you can use Play In Editor to play your game.

With the Blueprint Third Person Template Project open, from the Main Toolbar, click the Play button.



After you click the Play button, the game should start and you should see the character in the Level Editor Viewport.



You will also see the text "Click for Mouse Control" flash briefly in the upper-left corner of the Level Viewport. When playing inside the Level Viewport, you must click inside the viewport to assign mouse control to the playable character.

Click or right-click in the Level Editor Viewport.

You will see the text "Shift+F1 for Mouse Cursor" appear in the upper-left corner of the Level Editor Viewport. If you want to give mouse control back to the Editor itself, press Shift + F1 (Windows) or Shift + fn + F1 (macOS).

While the game is running, you can use the WASD keys for movement, Spacebar to jump and Mouse movement to move the camera.

During the Play session, the Main Toolbar will change to provide additional controls.



Left to right, the controls are:

Pause: Pauses the game.

Frame Skip: This will be grayed out and unavailable while your game is running in this mode.

Stop: Ends the Play session.

Eject: Releases control of the playable character and switches to mouse cursor controls.

You can click inside the Level and use the mouse to move around, or you can use the Editor to make changes to your Level.

While the game is still running in PIE mode, press Shift + F1 to unlock the mouse cursor from the Level Viewport, then click Pause to pause the game.

You will notice that the first two buttons on the Main Toolbar look slightly different:



The Play button has been replaced with a Resume button. Clicking the Resume button will resume the game simulation inside the Level Viewport.

The Frame Skip button is now available. Clicking it will advance gameplay by 1 frame (you can see this easily if you have animated objects, such as particle emitters).

The Stop and Eject buttons have the same functionality as described in step 3 above.

While the game is still paused, click the Eject button on the Main Toolbar.

Left-click the text in the Level Viewport to select it. Then in the Details panel, change its Text value to something else.



Press Enter to confirm the new text. Your changes will immediately appear in the Level Viewport.

From the Main Toolbar, click the Possess button (1), then click the Resume button (2).



Note that the text in the Level has changed from its default value. This method is useful for changing and testing different values for the Actors in your Level during gameplay.



Changes you make to Actors in the Level using this method are not saved by default. To learn how to keep these changes, follow the steps below.

Press Shift + F1 to regain mouse control. Then, from the main toolbar, click the Eject button.

With the game still running in the Level Viewport, right-click the text Actor. Then, from the pop-up menu, select Keep Simulation Changes.



Alternatively, left-click the text Actor to select it, then press K on your keyboard.

Press Esc to stop the play session. Note that your changes have been saved.

Play Modes

When you start a PIE session, you can select from several different Play Modes. This section describes what they are and how to access them.

From the Main Toolbar, click the vertical ellipsis button.



This will open the Play Options menu.

Choose from one of the following options:

Selected Viewport: Launches the game inside the currently selected Viewport.

Mobile Preview ES3.1 (PIE): Launches the game in a standalone version outside of the Editor and provides additional tools used to mimic devices as closely as possible.

New Editor Window (PIE): Launches the game within the Editor; however, it creates a new standalone window, leaving the Level Viewport the same.

VR Preview: Launches a preview of the game on a connected VR device.

Standalone Game: Launches the game in a standalone version outside of the Editor

The default setting is Selected Viewport.

PIE Console

The PIE Console is an in-game console where you can enter commands to display performance data, enable and disable Unreal Engine features, and much more.

To open the PIE console, press the tilde (~) key while playing the game in PIE mode.



Press the tilde key again to expand the console, and press tilde a third time to close it.

The PIE console behaves the same as the Unreal Editor's main console. When you start typing, it automatically tries to complete the console command you are trying to enter.

A great use case for the PIE Console is to profile a project's performance. To learn more, refer to the Stat Commands page.

Simulate In Editor (SIE)

In this section, we will take a look at Simulate In Editor and how to simulate your game.

With your project open, inside the Content Browser, open the Starter Content > Props folder.

Click and drag the Material Sphere prop into the Level, just above the stairs.



To find the Material Sphere prop quickly, use the Search Box inside the Content Browser.

Click the sphere to select it, then click the arrows of the Translation widget to move the sphere up above the stairs, as shown in the screenshot below.



In the Details panel for the sphere, scroll down to the Physics section and enable the Simulate Physics checkbox.



When you start to simulate (or play), the sphere now has physics and should fall to the ground.

Press Alt + S (Windows) or Options + S (macOS) to Simulate in the Editor.



Note that, although there is no player character in the Level, the game starts and the sphere falls to the ground.

Press Esc to stop the simulation. Note that the Main Toolbar now displays a Simulate button instead of the Play button. This button will always reflect the most recently selected Play or Simulate mode that ran for this project.



Click the Simulate button again, then immediately click the Pause button.

From the Main Toolbar, click the Frame Advance button to step through the simulation. Every time you click the button, the sphere should move further down.



Running the Editor

Running the Editor from the Command Line

Running the Editor from the Executable

Running the Editor with No Arguments (Stand-alone)

Running an Uncooked Game

Running an Uncooked Game from the Command Line

Running an Uncooked Game from the Executable

Running a Cooked Game

Useful In-Game Commands

Loading Maps

Loading New Maps

Choose your operating system:

Windows

macOS

Linux



The instructions on this page are for running the engine with projects compiled in a Development build configuration. You can substitute the UEEditor-_.exe or UE-_.exe that you need for opening projects built in other configurations. More information on the binary naming convention can be found on the Building Unreal Engine page.



The instructions on this page are for running the engine with projects compiled in a Development build configuration. You can substitute the UE5Editor-_.app or UE5-_.app that you need for opening projects built in other configurations. More information on the binary naming convention can be found on the Building Unreal Engine page.

Running the Editor

The process of running the editor requires passing the name of the project to run as an argument to the executable.

You can add the -debug switch to force the executable to load the debug version of the modules for your project, which contain all of the debugging symbols. This is necessary even when debugging through Xcode with the configuration set to Debug because the main executable is always compiled using the Development configuration. Of course, you must first compile your modules using the Debug configuration so they exist for the executable to load.

The process of running the editor requires passing the name of the project to run as an argument to the executable.

You can add the -debug switch to force the executable to load the debug version of the modules for your project, which contain all of the debugging symbols. This is necessary even when debugging through Visual Studio with the configuration set to Debug because the main executable is always compiled using the Development configuration. Of course, you must first compile your modules using the Debug configuration so they exist for the executable to load.

Running the Editor from the Command Line

From a command prompt, navigate to your [LauncherInstall]/[VersionNumber]/Engine/Binaries/Mac directory.

Run the UEEditor.app passing it the path to your project:

From a command prompt, navigate to your [LauncherInstall][VersionNumber]\Engine\Binaries\Win64 directory.

Run the UEEditor.exe, passing it the path to your project.

Running the Editor from the Executable

Navigate to your [LauncherInstall][VersionNumber]\Engine\Binaries\Win64 directory.

Right-click on the UEEditor.exe executable and choose Create shortcut.

Rename the shortcut to something like MyProject - Editor.exe as this reflect that this shortcut runs the MyProject game editor.

Right-click on the newly created shortcut and choose Properties.

Add the name of the game to run as an argument at the end of the Target property:

Press OK to save the changes.

Double-click the shortcut to launch the editor.

The editor must be run from the command prompt to load a specific project directly or with no arguments to access the Project Browser.

Running the Editor with No Arguments (Stand-alone)

If the editor is not set to open the most recent project at startup, running the editor executable without any arguments will launch the Project Browser. From here, you can create a new project , open your existing projects , or open content examples and sample games .

Running an Uncooked Game

Once a project is loaded in Unreal Editor, you can test your gameplay in Uncooked Game mode from the Play In menu. To play the uncooked game in its own window, select the New Window At > Default Player Start mode using the Play In dropdown menu in the Level Editor toolbar.



Click to see full-size image:

Running the uncooked game version of the engine executable using either of the below methods will result in the same behavior.

Running an Uncooked Game from the Command Line

When running from the command line, you must pass the name of the project you want to run along with the -game switch as arguments.

From a command prompt, navigate to your [LauncherInstall][VersionNumber]\Engine\Binaries\Win64 directory.

Run the UEEditor.exe passing it the path to the project to run, along with the -game parameter.

From a command prompt, navigate to your [LauncherInstall][VersionNumber]/Engine/Binaries/Mac directory.

Run the UEEditor.app passing it the path to the project to run, along with the -game parameter

Running an Uncooked Game from the Executable

When running from the executable, you must specify the path to the project you want to run along with the -game switch as arguments to the executable via the Target property of a shortcut.

Navigate to your [LauncherInstall][VersionNumber]\Engine\Binaries\Win64 directory.

Right-click on the UEEditor.exe executable and choose Create shortcut.

Rename the shortcut to reflect the game it will run, i.e. MyProject.exe.

Right-click on the newly created shortcut and choose Properties to display the properties of the shortcut.

Add the full path to the project to run as an argument at the end of the Target property, and specify the -game argument to run as a game:

Press OK to save the changes.

Double-click the shortcut to run the game.

Running a Cooked Game

See Packaging Projects for information on how to package and run cooked game builds

Useful In-Game Commands

When you are running the game, there are a multitude of console commands you can use in the console inside the game. The console can be summoned by pressing the ~ (tilde) or Tab keys. Some of the most useful commands are listed below.

EXIT/QUIT

DISCONNECT

OPEN [MapURL]

TRAVEL [MapURL]

VIEWMODE [Mode]

Loading Maps

It is possible to specify a particular map to load when running the engine or editor or load a new map while running the engine. This can be useful for testing by quickly jumping into the map you want to test without needing to make your way through a series of menus.

Loading Maps at Startup

The engine will always attempt to load a default map when it is run. This map is specified in the DefaultEngine.ini config file located in the Config folder of your game project. The map to run by default is set using the Map property in the [URL] section of the .ini file. As an example, when you create a project with a map file named "MyMap", the following is set automatically in its DefaultEngine.ini file:

This will cause the MyMap.umap (located in (UE4Directory)/(YourProjectName)/Content/Maps) to load at startup unless it is overridden. Generally, you will want to specify the map that loads or is used as the background for your main menu as the default map.

To override the default map, you can pass in a map name (without the file extension) as a command line argument. It was mentioned previously that you must specify the project name on the command line. Following these, you can also specify a map name to force the engine to load a map other than the default. For instance, the following command line could be used to load the engine running the ExampleMap map:

To override the default map, you can pass in a map name (without the file extension) as a command line argument. It was mentioned previously that you must specify the project name on the command line. Following these, you can also specify a map name to force the engine to load a map other than the default. For instance, the following command line could be used to load the engine running the ExampleMap map:

The same concept works when running the editor. Specifying the name of the map to load will load that map when the editor opens instead of the default or blank map. To load the editor with the ExampleMap map loaded, the following command line can be used:

UE4Editor.exe "[ProjectPath][ProjectName].uproject" ExampleMap -game

open UEEditor.app --args "[ProjectPath]/[ProjectName].uproject" ExampleMap

The map name can also be a full map URL specifying additional settings such as the GameMode. Settings are appended to the map name as key-value pairs separated by a ?. For example:

Loading New Maps

If you want to load a new map during play, in order to test during development or even to switch maps during gameplay, this can be done using the OPEN or TRAVEL console commands followed by the name of the map (without the file extension) to load.

The difference between the OPEN and TRAVEL commands is described above in the Useful In-Game Commands section.

The commands below load the DM-Deck map during play with the same settings or settings reset, respectively:

Or

Setting A Game Default Map

Creating Packages

Distribution

Advanced Settings

Signing and Encryption

Content Cooking

Optimizing Load Times

Using the Event Driven Loader (EDL) and the Asynchronous Loading Thread (ALT)

Compressing your .pak file

Ordering your pak file

Choose your operating system:

Windows

macOS

Linux

Before an Unreal project can be distributed to users, it must be properly packaged. Packaging ensures that all code and content is up to date and in the proper format to run on the desired target platform.

Several steps are performed during the packaging process. Project-specific source code will be compiled first. Once the code is compiled, all required content will be converted, or "cooked," into a format that can be used by the target platform. Following that, the compiled code and cooked content will be bundled into a distributable set of files, such as an installer.

Under the main File menu, there is an option called Package Project, with a submenu. This submenu provides a list of all supported platforms for which you can package your project.

For packaging on Android, there will be multiple selections. See the Android Reference page for more information.

There are also some Advanced options you can set before packaging.

Setting A Game Default Map

Before packaging your game, you will first need to set a Game Default Map, which will load when your packaged game starts. If you do not set a map and are using a blank project, you will only see a black screen when the packaged game starts. If you have used one of the template maps, like the First Person template or Third Person template, the starting map will be loaded.

To set the Game Default Map, click on Edit > Project Settings > Maps & Modes in the Editor's main menu:



Creating Packages

To package a project for a specific platform, click on File > Package Project > [PlatformName] in the Editor's main menu:





You will be presented with a dialog for selecting the target directory. If packaging completes successfully, this directory will then contain the packaged project.

Confirming the target directory will then initiate the actual process that packages the project for the selected platform. Because packaging can be very time consuming, this process is executed in the background, and you can continue to use the Editor. A status indicator will be displayed in the bottom right corner of the Editor to indicate the progress:





The status indicator also provides a Cancel button to stop the packaging process. In addition, the Show Log link can be used to display extended output log information, which is useful for figuring out what went wrong if the packaging process fails, or for catching warnings that could reveal potential bugs in the product:





The most important log messages, such as errors and warnings, are logged to the regular Message Log window:





If these windows are not visible, they can be accessed by the Window > Developer Tools > Output Log / Message Log options.

Distribution

To submit an iOS or Android game to the App Store or Google Play Store, you need to create your package in Distribution mode. To do this, go to the Packaging Settings option in the Packaging menu, and check the Distribution check box.

On iOS, you will need to create a Distribution Certificate and MobileProvision on Apple's developer website. Install the Distribution Certificate the same way as your Development certificate, and name your distribution provision with a "Distro_" prefix, next to your other one (so you would have both `Distro_MyProject.mobileprovision` and `MyProject.mobileprovision`).

On Android, you will need to create a key to sign the .apk file, and give some information to our build tools with a file called SigningConfig.xml. This file exists in the installed Engine directory (Engine/Build/Android/Java/). If you edit this file, it will apply to all your projects. However, you can copy this file to your project's Build/Android/ directory (without the Java/ subdirectory), and it will be used for just that project. Directions for how to generate the key and fill out the file are found in the file itself.

Advanced Settings

Clicking File > Package Project > Packaging Settings... or Edit > Project Settings > Packaging in the main menu will present you with some advanced configuration options for the packaging feature.



Currently, these include:

Option

Description

Build Configuration

The build configuration to compile your code-based project with. For debugging a code project, select DebugGame. For most other development with minimal debugging support, but better performance, select Development. For the final shipping build, which will have no debugging information and no debugging-oriented features (such as drawing debug shapes or printing debug messages on the screen), select Shipping.

Note that Blueprint-only projects will not have the option to create a DebugGame build.

Staging Directory

The directory that will contain your packaged build. This will be updated automatically when you pick a different directory in the target directory selection.

Full Rebuild

Whether all of your code should be compiled. If disabled, only the modified code will be compiled. This may speed up the packaging process. For shipping builds you should always do a full rebuild to make sure nothing is missing or outdated. This option is enabled by default.

Use Pak File

Whether to package your project's assets as individual files or a single package. If enabled, all assets will be put into a single .pak file instead of copying out all the individual files. If your project uses a lot of asset files, then using a Pak file may make it easier to distribute as it reduces the amount of files you need to transfer. This option is disabled by default.

Generate Chunks

Whether to generate .pak file chunks that can be used for streaming installs.

Build Http Chunk Install Data

Whether to generate data for HTTP chunk installer. This allows this data to be hosted on a webserver to be installed at runtime.

Http Chunk Install Data Directory

This is the directory where data will be installed once it is built.

Http Chunk Install Data Version

This is the version name for HTTP chunk install data.

Include Prerequisites Installer

This specifies whether to include installers for prerequisites of packaged games, such as redistributable operating system components.

Signing and Encryption

With the release of Unreal Engine 4.22, we integrated the industry standard OpenSSL library for desktop platforms (Windows, Mac, and Linux).

When distributed in a shipped product, .Pak files can be signed or encrypted, usually to hinder data extraction or tampering. To activate, deactivate, or adjust the cryptographic settings on your project, go to the Project Settings menu and find the Crypto section.



The cryptographic options within the Project Settings menu.

The following settings are available from this menu:

Option

Description

Encrypt Pak INI Files

Encrypts all .ini files that exist in your project's .pak files. This will prevent easy mining or tampering with configuration data for your product, at minimal runtime cost.

Encrypt Pak Index

Encrypts the .pak file index, which prevents UnrealPak from opening, viewing, and unpacking your product's .pak files, at minimal runtime cost.

Encrypt UAsset Files

Encrypts the .uasset files in the .pak file. These files contain header information about the Assets inside, but not the actual Asset data itself. Encrypting this data provides extra security to your data, but does add a small runtime cost and an increase in data entropy, which can increase patch sizes.

Encrypt Assets

Fully encrypts all Assets within the .pak file.

Note that this setting has a measurable effect on run-time file I/O performance, and increases the amount of entropy in your final packaged data, making the distribution patching system less efficient.

Enable Pak Signing

Activates or deactivates .pak file signing.

In addition, keys for signing or encryption can be set or cleared.

Content Cooking

As a developer, when iterating over new or modified game content, you may not always want to go through the lengthy process of packaging everything into the staging directory and then running it from there. It is, therefore, possible to only cook the content for a particular target platform without packaging it by clicking File > Cook Content > [PlatformName].

Note that this feature will update the content in your project's local developer workspace, and it will not copy out any assets to the staging directory. You can run your game directly from your local developer workspace for fast iteration.

Optimizing Load Times

Short loading times are essential for open-world games but are valuable in every type of game. The Unreal Engine provides several methods to optimize your project's loading time during the packaging process. Here are some recommended practices to decrease the loading time in your games. For information on how to package your project, see the Packaging and Cooking Games section.

Using the Event Driven Loader (EDL) and the Asynchronous Loading Thread (ALT)

The Asynchronous Loading Thread (ALT) is turned off by default but can be turned on in the Project Settings menu under the Engine > Streaming section. For modified engines, some tweaks may be needed, but in general, ALT should double the speed of loading, including games with "up-front" loading times and games that constantly stream data. The ALT works by running serialization and post-loading code concurrently on two separate threads, and as a result, it adds the requirement that UObject class constructors, PostInitProperties functions, and Serialize functions in your game code must be thread-safe. When activated, ALT doubles loading speed. For further information about using asynchronous loading methods (in C++), see the Asynchronous Asset Loading page.

The Event-Driven Loader is activated by default, but can be deactivated in the Project Settings menu under the Engine > Streaming section. For most projects, the EDL will cut load times in half. The EDL is stable and can be back-ported to older versions of the Unreal Engine, or can be tweaked for modified or customized engine versions.



Compressing your .pak file

To use .pak file compression in your project, open Project Settings and find the Packaging section. In that section, open the advanced part of the Packaging heading and check the box labeled "Create compressed cooked packages" that appears.

Most platforms don't provide automatic compression, and compressing your .pak files will decrease loading times, but there are a few special cases to consider:

Platform

Recommendation

Steam

Steam compresses files while they are being downloaded by users, so initial download times will not be affected by your game's .pak file being compressed. However, Steam's differential patch system will work better with uncompressed files. Compressed .pak files save space on the customer's system, but will take longer to download when patching.

Oculus

Do not enable compression of the .pak file. The Oculus patch system cannot properly process a compressed .pak file. Also, compressing the .pak file will not reduce the size of the file.



Check this box to enable compression in your .pak files.

Ordering your pak file

A well-ordered .pak file is critical to reducing load times. To assist with ordering your .pak file optimally, UE4 provides a set of tools to discover the order in which your data assets are needed, and build faster-loading packages. Conceptually, this process is similar to profile-guided optimization. Follow this method to order our .pak file:

Build and run the packaged game with the -fileopenlog command-line option, which causes the engine to log the order in which it opens files.

Exercise all major areas of the game. Load every level, every playable character, every weapon, every vehicle, and so on. Once everything has been loaded, quit the game.

There will be a file in your deployed game called GameOpenOrder.log that contains the information needed to optimize your .pak file order. For example, on Windows builds, the file will be found in WindowsNoEditor/(YourGame)/Build/WindowsNoEditor/FileOpenOrder/. Copy this file to your development directory under the /Build/WindowsNoEditor/FileOpenOrder/ path.

There will be a file in your deployed game called GameOpenOrder.log that contains the information needed to optimize your .pak file order. For example, on Mac builds, the file will be found in MacNoEditor/(YourGame)/Build/WindowsNoEditor/FileOpenOrder/. Copy this file to your development directory under the /Build/MacNoEditor/FileOpenOrder/ path.

With the log file in place, rebuild the .pak file. This and all future .pak files produced will use the file order indicated in the log file.

In a production environment, the log file should be checked into source control and updated periodically with the results of new -fileopenlog runs, including a final run when the game is ready to ship.

Activating Source Control

Activating Source Control via Editor Preferences

Activating Source Control via the Content Browser

Status Icons

Source Control Actions

Checking Out and Checking In

Content Hot Reloading

Deactivating Source Control

The Unreal Editor has built-in support for source control packages. Source control is used to manage changes over time to code and data, and enables teams to coordinate their game development efforts.

Perforce and SVN are supported by default.

Activating Source Control

You can activate source control in one of two ways:

In the Level Editor's Preferences window.

In the Content Browser.

Activating Source Control via Editor Preferences

You can activate source control via the Editor Preferences window (Edit > Editor Preferences > Loading & Saving).



Item

Description

Automatically Checkout on Asset Modification

When checked, this will automatically check out any asset that has been modified.

Prompt for Checkout on Package Modification

When checked, a prompt will appear when you make changes to a source controlled-package, asking if you would like to check out (lock) that package.

Add New Files when Modified

This will add new files into source control when they are modified.

Use Global Settings

Use global source control login settings, rather than per-project. Changing this will require you to login again.

Tool for diffing text

Specifies the file path to the tool to be used for diffing text files.

Activating Source Control via the Content Browser

You can also activate Source Control in the Content Browser. To do so, right-click any asset or folder. At the bottom of the context menu, in the Source Control section, click Connect to Source Control.



This will open a log-in screen where you can select your source-control system and enter any appropriate settings and other information.



Enter the appropriate information, and click Accept Settings. After source control is activated, the display of the assets in the Content Browser will change to reflect their source-control status, and some source-control options will be included on the right-click context menu.

Status Icons

The Content Browser will display special icons on the upper-right corner of assets to give the source control status. Below are the available icons and their meanings:











Checked out by you

Checked out by another user

Marked for add

Not in depot

Newer version of file exists in source control

Source Control Actions

While source control is active, the following context menu will be available when you right-click on an asset:



Item

Description

Check Out

Checks out (locks) the asset for editing. This prevents other users from editing the asset at the same time.

Refresh

Refreshes the source control status of the asset.

History

Gives a revision history list of the selected asset, allowing you to see previous edits.

Diff Against Depot

This allows you to check the asset against the version currently stored in the source control depot.

Checking Out and Checking In

To check out an asset for editing, simply right-click it and choose Check Out. When checking the asset back in, adhere to the following protocol:

Right-click on the asset and choose Check In. A dialog will appear with a required changelist description for the check-in.

Enter a description, which will be added to the asset's revision history.

Click OK when finished.



A changelist description is required, so the OK button will not be enabled until a description is entered.

Content Hot Reloading

Content Hot Reloading is a new feature that the in-editor source control uses to reload content automatically when the content has been modified by source control operations. Currently, automatic reloading only works when performing source control operations via the in-editor source control integration, and any external changes won't trigger a reload. We intend to remove this requirement in a later engine version, so that external changes will also trigger hot reloads.

Content Hot Reloading also provides the ability to reload an asset from its last saved state on command. This can be done by right-clicking the asset in the Content Browser and selecting the Reload option under the Asset Actions group. This can be extremely useful if you have unsaved changes to an asset that you wish to discard in order to revert back to the on-disk version.





This feature currently carries the requirement that you have source control active for your project.



Deactivating Source Control

You may find that you want to deactivate source control after activating it.

Only use this option if you are absolutely certain that you do not want to use source control. Deactivating source control will put your content out of sync with your source-control system, and will make it impossible to check in changes.

To deactivate source control:

In the upper-right corner of the Level Editor window, click the green double-arrow icon ( ). This brings up the Source Control Login screen.

Click the Run Without Source Control button. The green icon in the Level Editor window changes to a red circle with a slash ( ), to indicate that source control is not being used.

Unreal Editor

Editing Assets

Quick Glossary

Projects and Files

What are the common files and directories of an Unreal Engine project?

Where do I put my Assets?

What file formats are supported?

How is my Scene stored?

How do I change my project settings?

Where do my source files go?

From GameObjects to Actors

Where is my GameObject?

Where are my components?

From Unity Prefabs to Unreal Engine Blueprint Classes

Where are Script Component and MonoBehaviour?

Scriptable Actor Blueprint Classes

Blueprint Classes Can Be Extended

Using Blueprint Scripting, C++, or Both

Blueprint Classes Can Extend C++ Classes

Transform Components

Compound Objects

Do I build everything out of Components?

So is everything an Actor?

What is the Gameplay Framework in Unreal Engine?

Writing Code in Unreal Engine

For C++ Programmers

Writing Event Functions (Start, Update, etc.)

Creating Gameplay in Unreal Engine

Instantiating GameObject / Spawning Actor

Casting from One Type to Another

Destroying GameObject / Actor

Destroying GameObject / Actor (with 1-Second Delay)

Disabling GameObjects / Actors

Accessing the GameObject / Actor from a Component

Accessing a Component from the GameObject / Actor

Finding GameObjects / Actors

Adding tags to GameObjects / Actors

Adding tags to MonoBehaviours / ActorComponents

Comparing tags on GameObjects / Actors and MonoBehaviours / ActorComponents

Physics: RigidBody vs. Primitive Component

Layers vs Channels

RayCast vs. RayTrace

Trigger Volumes

Kinematic Rigidbodies

Input Events

FAQ

How do I load my last project automatically?

Where do I set input bindings for my game?

How do I change the starting scene of my project?

How do I run my game?

What units are these?

Which way is up in Unreal Engine's coordinate system?

How do I see Log Output from my game?

How do I throw exceptions?

Where is the .NET Framework?

Does Unreal Engine automatically reload code changes?

Finding Help and Answers

This page provides an overview of Unreal Engine (UE) for users who are familiar with Unity. If you have some Unity knowledge and want to learn how to apply what you learned to working in Unreal Engine, the sections below will help you get started.

Unreal Editor

The Unreal Editor is where you work on your Unreal Engine project. The screenshot below shows Unity and Unreal Editor, side by side. Different areas are color-coded to indicate common functionality. Each block is labeled to show the equivalent Unreal Engine terminology.

Unreal Editor's layout is fully customizable. You can drag and drop tabs, dock them into the main window, change the color scheme, and more.



Visual comparison between the main UI elements in Unity and Unreal Engine 5. Click the image for full size.

Editing Assets

In Unity, you used the Inspector tab to edit selected Assets in your Project. In Unreal Editor, the Details panel exposes properties of selected objects. Editing complex Assets happens in separate editor windows, which you can either dock into the main UE window or drag somewhere else on your desktop (for example, to a second monitor).



Tabbed editors in the Unreal Editor. The Level Editor is in the background, and the Material Editor is currently active.

For a general introduction to the various Asset editors in Unreal Engine, refer to the Tools and Editors page.

Quick Glossary

The following section contains common Unity terms on the left and their Unreal Engine equivalent (or approximation) on the right. Each term in the Unreal Engine column links to separate pages where you can learn more.

Category

Unity

Unreal Engine

Gameplay Types

Component

Component

GameObject

Actor

Prefab

Blueprint Class

Editor UI

Hierarchy Panel

World Outliner

Inspector

Details Panel

Project Browser

Content Browser

Scene View

Level Viewport

Meshes

Mesh

Static Mesh

Skinned Mesh

Skeletal Mesh

Materials

Shader

Material, Material Editor

Material

Material Instance

Effects

Particle Effect

Effect, Particle, Niagara

Game UI

UI

UMG (Unreal Motion Graphics)

Animation

Animation

Skeletal Mesh Animation System

Mecanim

Animation Blueprint

Sequences

Sequencer

2D

Sprite Editor

Paper2D

Programming

C#

C++

Script, Bolt

Blueprint

Physics

Raycast

Line Trace, Shape Trace

Rigidbody

Collision, Physics

Runtime Platforms

iOS Player, Web Player

Platforms

Projects and Files

What are the common files and directories of an Unreal Engine project?

Just like Unity projects, Unreal projects always exist in their own directory and have their own project file with the .uprojectfile extension. You can double-click a .uproject file to load your game into Unreal Editor, or right-click it for additional options.

Project folders have various sub-folders that contain your game's content and source, as well as various configuration files and binaries. The most important are the Content folder, which stores all of your project's Assets, and Config folder, which stores the project's configuration (.ini) files.

Where do I put my Assets?

In Unreal Engine, each project has a Content folder. Similar to a Unity project's Assets folder, this is where your game Assets are stored.

If your Unreal Engine project contains C++ classes, these will be located in your project's Source folder on disk.

To import Assets into your game, drop files into your project's Content directory through the Content Browser.

To learn more about the Asset import process, refer to the Importing Assets Directly page.

What file formats are supported?

Unreal Engine 5 supports some of the most common file types:

Asset Type

Supported Formats

3D

.fbx, .obj

Texture

.png, .jpeg, .bmp ,.tga, .dds, .exr, .psd, .hdr

Sound

.wav

Fonts

.ttf, .otf

Videos

.mov, .mp4, .wmv

In addition, you can use specialized plugins to import other types of content, such as:

Plugin

Supported Content

Datasmith

3D scenes and assets from various CAD applications, such as 3ds Max, SketchUp, Revit, and more

LiDAR Point Cloud Plugin

LiDAR point clouds. Refer to the LiDAR Point Cloud Plugin Overview for a list of supported file types.

USD Importer

.usd (Universal Scene Description)

Alembic File Importer

.abc

How is my Scene stored?

In Unity, you placed GameObjects in a scene and saved that as a Scene asset file. Unreal Engine has a Map file that is similar to a Unity scene. Map files store data about your Level and the objects in it, as well as lighting data and certain level-specific settings.

How do I change my project settings?

From Unreal Editor's main menu, go to Edit > Project Settings.

Like Unity's project settings, these settings:

Control information about your project, such as project name and icons.

Configure game input bindings.

Define how the engine behaves when running your project.

and so on.

To learn more about the Project Settings window, refer to the Project Settings page.

Unity also has what is called "Player Settings". In Unreal Engine, these are Platform Settings and can be configured under the Platforms section of the Project Settings window.

Where do my source files go?

In Unity, you placed C# source files in your Assets folder. In Unreal Engine, your source files are placed in different locations depending on the type of Unreal project you create:

C++ projects have a Source folder in the Unreal project directory. The Source folder contains various files, including C++ source (.cpp) and header (.h) files, as well as some build scripts (Build.cs, Target.cs).

Blueprint projects don't have a Source folder. Blueprints can be placed anywhere within the Unreal project's Content folder.

If you want to add C++ code to a Blueprint project, from the Unreal Editor's main menu, go to Tools > New C++ Class.

Double-click a C++ source file in the Content Browser to open it in Visual Studio (Windows) or Xcode (macOS).

From GameObjects to Actors

Where is my GameObject?

In Unity, a GameObject is a "thing" that can be placed in the world. The Unreal Engine equivalent is an Actor. In the Unreal Editor, you can drag a new empty Actor into the viewport from the Create menu in the Main Toolbar, as shown below:

You could build a game out of empty Actors, but Unreal Engine also includes special types of Actors with built-in features, such as a Pawn (for Actors that can be controlled by a player or by AI), or Character (for controllable player characters that require complex locomotion and interactions). Just like empty Actors, you can drop these special types of Actors into the Viewport, then add or customize their properties and components.

Unreal Engine has a Gameplay Framework that works with these special Actors. You will learn more about the Gameplay Framework later.

Actors in Unreal Engine are a little different from GameObjects in Unity. In Unity, GameObject is C# class which you can't extend directly. In Unreal Engine, Actor is a C++ class which you can extend and customize using inheritance. We will talk more about inheritance further down the page.

Where are my components?

In Unity, you added functionality to a GameObject using components. In Unreal Engine, you add components to Actors. After you drop an empty Actor in your Level, select it, and then click the Add Component button in the Details panel and choose a component to add.

In the video below, we are creating a torch by dropping an empty Actor, then adding a mesh component for the base, followed by a light source and then a particle system to create its flame.

In Unity, a GameObject holds a flat list of components. In Unreal Engine, an Actor contains a Hierarchy of components attached to one-another. You can see this in the example above, where the Light and Particle are attached to the Static Mesh. This has some important implications, which will be covered in the Compound Objects section on this page.

From Unity Prefabs to Unreal Engine Blueprint Classes

In Unity, you built a set of GameObjects with components, then created a prefab from them. You could then place instances of the prefab in your world, or instantiate them at runtime.

Unreal Engine has the same kind of workflow, which is based on Blueprint Classes:

Build an Actor with Components.

Click Blueprint > Add Script in the Actor's Details panel to add a Blueprint to it.

Choose where to save your new Blueprint Class.

Click Create Blueprint.

That's all!

You can access your new Blueprint Classes from the Content Browser. Double-click to edit them directly, or drag them into the open Level to place them in the game world.

Where are Script Component and MonoBehaviour?

In Unity, you had Script Components that you dropped on GameObjects to add C# scripting. You created a class that inherited from MonoBehaviour to define what that component does.

Unreal Engine works the same way: you can create entirely new Component classes, using either Blueprint or C++, and add them to any Actor. Similar to adding Blueprint to an Actor, you can add Components to an Actor in one of two ways:

From the Actor's Details panel.

From the Edit Actor window.

The steps to add a new Component to an Actor are:

From the Actor's Details panel or the Edit Actor window, click Add Component.

Select a Component to add to the Actor. You can either create a new Component, or select from a list of predefined components, such as lights, audio, particle systems, and so on.



In Unity, when creating a new MonoBehaviour, you received a skeleton class file with a Start() function and an Update() function.

In Unreal Engine, a new component has similar functions:

InitializeComponent(), which has the same role as Unity's Start()` function.

TickComponent(), which has the same role as Unity's Update() function.

In Blueprint components, these functions appear as visual nodes.

Scriptable Actor Blueprint Classes

Your new Actor Blueprint Class can have its own Blueprint visual scripting. This way, you can add logic to an entire object, not only an individual component. Combined with inheritance (explained below), this gives you a lot of flexibility when designing your game.

In addition to Blueprint Classes supporting visual scripting, Unreal Engine also supports C++ classes implemented with code. Here is a side-by-side comparison of Unity and Unreal Engine code, followed by an Unreal Engine Blueprint that does the same thing.

Unity C#

Unreal Engine C++

Blueprint



Blueprint Classes Can Be Extended

Similar to Unity prefabs, you can also instantiate Blueprint Classes in Unreal Engine.

In Unreal Engine, you can create a new Blueprint Class which extends an existing Blueprint Class and augments it with new properties, components, and visual scripting functionality.

For example, you can create a Blueprint Class named Monster, which implements basic monster functionality such as chasing people. You can then create further Blueprint Classes which extend it, such as Dragon (a type of Monster with an added fire-breathing ability), Grue (a Monster which only comes out at night), and 8 other classes for different kinds of Monsters. All of these subclasses of Monster inherit the basic functionality from Monster, and also have new features and abilities of their own.

In Unity, you would implement this by creating many different GameObject prefabs: one for Dragon, one for Grue, and so on. Now, say you want to add some new functionality to all monsters, such as the ability to speak using your new Speak Component. In Unity, you had to go and update all 10 prefabs to individually copy and paste the new functionality into it.

In Unreal Engine, all you have to do is modify the Monster Blueprint Class to add this new ability to speak. That's all! Dragon, Grue, and all the other 8 subclasses of Monster will automatically inherit the new speaking functionality; you don't need to do anything else.

Everything in this section also applies to C++ Classes, as well as both Actors and Components. These systems are designed to support large-scale development of extensible functionality, and can scale to projects with tens or hundreds of developers.

Using Blueprint Scripting, C++, or Both

Blueprint Visual Scripting is ideal for simple in-game logic and action sequencing. Because it's easy to access and control in-game objects visually, Blueprint is a great system for designers, artists, and visually-oriented programmers. You can create small standalone-games and other interactive experiences using just Blueprint.

C++ programming is for larger-scale tasks, such as building gameplay systems, complex AI, and new engine features. If you already have some C++ experience, refer to the Programming with C++ page to learn more about C++ programming in Unreal Engine.

Most projects use a mix of Blueprint and C++. Many developers prototype game functionality using Blueprint, which makes it easy to prototype and iterate, and later move some or all of it to C++ for performance and engineering rigor.

Blueprint Classes Can Extend C++ Classes

Much of the magic of Unreal Engine game development comes from the interplay between programmers implementing new features in C++, which designers and artists can then test in Blueprints so they can give hands-on feedback. Here's how a team might structure a UE-based shooter game implementing pickups, using a mix of C++ Classes systems programming and Blueprint Classes for behavior and appearance:



Transform Components

In Unity, each GameObject had a Transform Component, which gave the GameObject a position, rotation, and scale in the world.

Similarly, Unreal Engine Actors have a Root Component, which can be any subclass of Scene Component. A Scene Component gives the Actor a location, rotation, and scale in the world, which are also applied to all Components parented to the Scene Component. Many of the Components that you will use are subclassed from Scene Component, because it is really useful to have a position!

Even if you place an empty Actor, Unreal Engine will still create a Default Scene Root for that Actor, which is just a plain Scene Component. If you drop in a new Scene Component, it will replace the Default Scene Root.

Compound Objects

In Unity, you created compound objects by constructing a hierarchy of GameObjects and parenting their transforms together:



In Unreal Engine, you create compound game objects by nesting Components hierarchically:



As you can see from the diagram, nested hierarchies can be created by attaching Scene Components to one another, since they have a transform - similar to parenting transforms in Unity. Actor Components (the base class for all Components) can only be attached directly to the Actor itself.

Do I build everything out of Components?

It's your choice! Typically, you would use a combination of custom Component types, along with Actor classes that use those Components. As we mentioned before, Unreal Engine has many special types of Actors that guarantee a certain level of capability and always include certain components. For example, a Character always contains a Character Movement Component.

Here are some Unreal Engine Actors that are commonly used:

Pawn - A type of Actor representing a controllable game object, typically the player's avatar. Pawns are moved by Players and AI alike through an owning Controller.

Character - A more specialized version of Pawn designed for biped avatars (avatars with a skeletal structure similar to a human's, who walk on two legs).

Controller - Possesses and controls a Pawn. By separating the Pawn from the controller, you can write AI Controllers that can manipulate a pawn using the same interface the player would.

Player Controller - A more specialized Controller designed for getting player input from a player's Gamepad, Touch, or Mouse/Keyboard, and using that input to drive the Pawn or Character they possess.

So is everything an Actor?

Not everything. Actors are the most common class used for gameplay in Unreal Engine and the only type that can be Spawned into the World. In other words, everything you place in your Level will be an Actor.

The other important type to know about is Object. Object is actually the base class of all Unreal classes, including Actor and many others. This is a much lower-level construct than Actor, but still has features that you would expect from a Unreal class, such as Reflection and Serialization. Object is a very basic class you would use when you need to define a new type that just does not fit the mold of an Actor. For example, Actor Component is the base class for all Components, and derives from Object instead of Actor.

What is the Gameplay Framework in Unreal Engine?

When you started a new Unity project, you had to populate things like GameObjects and components manually. Similarly, in Unreal Engine, you can build your game using Actors and Components. However, Unreal Engine has an additional layer called the Gameplay Framework. If you use certain primitive classes and follow specific conventions, your game will automatically acquire additional features that would otherwise be difficult and time-consuming to implement (for example, full multiplayer support).

To use the Gameplay Framework, you need to learn how to use and customize built-in Actor classes included with Unreal Engine, such as Pawn, Character, and Player Controller. If you want to implement multiplayer, for example, you also need to familiarize yourself with how networking and replication work in Unreal Engine.

Writing Code in Unreal Engine

For C++ Programmers

To use Blueprint scripting, you only need Unreal Engine. All the features you need are built in.

To write code in C++, download Visual Studio on Windows, or install Xcode on macOS. When you first create a new C++ project in Unreal Engine (or add C++ code to an existing project), Unreal Engine will automatically create Visual Studio project files for you.

There are two ways to access Visual Studio from your Unreal Engine project:

In the Content Browser, double-click a C++ class to open it in Visual Studio.

From the main menu, go to Tools > Open Visual Studio. This option only appears if your project contains at least one C++ class.

One important difference in Unreal Engine: You will sometimes have to manually refresh your Visual Studio project files (for example, after downloading a new version of Unreal Engine, or when manually making changes to source file locations on disk.) You can do this in two ways:

From Unreal Engine's main menu, go to Tools > Refresh Visual Studio Project.

Right-click the .uproject file in your project's directory and select Generate Visual Studio project files.

Writing Event Functions (Start, Update, etc.)

If you previously worked with MonoBehaviors, you should be familiar with methods such as Start, Update, and OnDestroy. Below is a comparison between a Unity behavior and its equivalent for Unreal Engine Actors and Components.

In Unity, you might have a simple component that looks like this:

C++

Blueprint



Components in Unreal Engine contain different functions. Here is a basic example:

C++

Blueprint



Remember, in Unreal Engine, you must call the parent class's version of the method.

For example, in Unity C# this would be called base.Update(), but in Unreal Engine C++ you will use Super::TickComponent():

In C++, some classes use the prefix A, while others use the prefix U. A indicates an Actor subclass, whereas U indicates an Object subclass. Another common prefix is F, which is used for most plain data structures and non-UObject classes.

Creating Gameplay in Unreal Engine

The next section covers some advanced Unreal Engine programming concepts. The explanations below assume that you are familiar with Unity C# and want to learn Unreal Engine C++. That said, for most things, you can also use Blueprint and get the same results, so we added examples in both C++ and Blueprint wherever possible.

Let's talk about some of the most common gameplay programming patterns and how to approach them in Unreal Engine. The examples below cover some common Unity functions and how to implement the same functionality in Unreal Engine.

Instantiating GameObject / Spawning Actor

In Unity, you used the Instantiate function to create new instances of objects. This function took any UnityEngine.Object type (GameObject, MonoBehaviour, etc.), and made a copy of it.

Unreal Engine has two different functions to instantiate objects:

NewObject creates new UObject types.

SpawnActor spawns AActor types.

Subclassing UObject in Unreal Engine is much like subclassing ScriptableObject in Unity. These are useful for gameplay classes that do not need to spawn into the world or have attached components like Actors do.

In Unity, if you created your own subclass of ScriptableObject, you would instantiate it like this:

In Unreal Engine, if you crate your own UObject derived type, you can instantiate it like this:

Actors are spawned using the SpawnActor method on a World (UWorld in C++) object. Some UObjects provide a GetWorld method for you (as an example, all Actors do). This method is how you get a World object.

In the example below, notice that, instead of passing in another Actor, we pass in the class of the Actor we want to spawn. In our example, the class can be any subclass of AMyEnemy.

What if you want to make a copy of another object, like what using Instantiate in Unity allows you to do?

The NewObject and SpawnActor functions can also be given a template object to work with. Unreal Engine will make a copy of that object instead of creating a new object from scratch. This will copy over all of its UPROPERTYs and components.

You might be wondering what "from scratch" means in this context. Each object class you create has a default template that contains default values for its properties and components. If you do not override these properties and do not provide your own template, Unreal Engine will use these default values to construct your object. To help illustrate this, let's first look at a MonoBehaviour example:

In the example above, we have an int property that defaults to 42, and a SphereCollider component that defaults to a radius of 20.

We can achieve the same thing in Unreal using the object's constructor:

We set the default property values for the class in the constructor of AMyActor. Note the use of the CreateDefaultSubobject function; we can use this function to create Components and assign default properties to them. All the sub-objects created with this function act as a default template, so we can modify them in a subclass or Blueprint.

Casting from One Type to Another

In this case, we get a component we know we have, then cast it to a specific type and conditionally do something.

Unity C#

Unreal Engine C++

Destroying GameObject / Actor

Unity

C++

Blueprint



Destroying GameObject / Actor (with 1-Second Delay)

Unity

C++

Blueprint

]

Disabling GameObjects / Actors

Unity

C++

Blueprint

]

Accessing the GameObject / Actor from a Component

Unity

C++

Blueprint

]

Accessing a Component from the GameObject / Actor

Unity C#

Unreal Engine C++

Blueprint

] Click the image for full size.

Finding GameObjects / Actors

Unity C#

// Find GameObject by name

Unreal Engine C++

Blueprint



Unreal Engine C++

Blueprint



Adding tags to GameObjects / Actors

Unity C#

Unreal Engine C++

Blueprint



Adding tags to MonoBehaviours / ActorComponents

Unity C#

Unreal Engine C++

Comparing tags on GameObjects / Actors and MonoBehaviours / ActorComponents

Unity C#

Unreal Engine C++

Blueprint



Unreal Engine C++

Blueprint



Physics: RigidBody vs. Primitive Component

In Unity, to give any GameObject physics characteristics, you first had to give it a RigidBody component.

In Unreal Engine, any Primitive Component (UPrimitiveComponent in C++) can be a physical object. Some common Primitive Components are:

Shape Components (Capsule, Sphere, and Box)

Static Mesh Components

Skeletal Mesh Components

Unlike Unity, which separates the responsibilities of collision and visualizations into separate components, Unreal Engine combines the concepts of "potentially physical" and "potentially visible" into a single Primitive Component. Any Component that would have any geometry in the world, that could either be rendered or interacted with physically, is a subclass of PrimitiveComponent.

Layers vs Channels

Collision Channels are the Unreal Engine equivalent of layers in Unity. To learn more, refer to Collision Filtering.

RayCast vs. RayTrace

Unity C#

Blueprint



Click the image for full size.

Trigger Volumes

Unity C#



To learn more about setting up collision responses, refer to the Collision page.

Kinematic Rigidbodies

Unity C#

In Unreal Engine 4, the collision component and rigidbody component are one. The base class for this is UPrimitiveComponent, which has many subclasses (USphereComponent, UCapsuleComponent, etc.) to suit your needs.

Unreal Engine C++

Input Events

Unity C#

Unreal Engine C++:

Blueprint



This is what your input properties in your Project Settings might look like:



To learn more about how to set up input for your Unreal Engine project, refer to the Input page.

FAQ

How do I load my last project automatically?

You can configure Unreal Engine to load the last project you were working on automatically on startup. When you open a project from the Epic Launcher, enable the Always Lost Last Project on Startup option on the Unreal Engine start screen.



Where do I set input bindings for my game?

In Unity, you used the Input Manager settings for your project to set up default bindings.

In Unreal Engine, you configure input bindings from the Project Settings window, in the Input category. In this window, you can add various buttons (actions) and analog controls (axes). Give each control a name and default binding. Once you do that, you can get callbacks to your game's Pawn when input events are triggered.

To learn more about how to set up input for your Unreal Engine project, refer to the Input page.

How do I change the starting scene of my project?

By default, Unreal Engine loads the default Level of your project when you open it. You can change this behavior in the Project Settings window (main menu: Edit > Project Settings), in the General > Loading & Saving category.

How do I run my game?

There are several ways to play-test (run) your game:

Directly in the Unreal Editor, by clicking the Play button on the Main Toolbar.

As a standalone process, by clicking the Platforms button on the Main Toolbar, then selecting your machine from the drop-down list. Note that this will first build an executable for your platform; for example, if you are working on a Windows machine, this will build a Windows executable.

On a different platform (for example, a mobile device or web browser), by clicking the Platforms button on the Main Toolbar, then selecting the platform you want to run your game on. Note that you will need to install all required dependencies first.

To learn more about running your Unreal Engine game on different platforms, refer to the following pages:

Playing and Simulating

Managing Platforms in Unreal Editor

What units are these?

In Unity, the primary unit of measurement is one meter. In Unreal Engine, the primary unit of measurement is one centimeter.

So, if you move something 1 unit (meter) in Unity, that is equivalent to moving something 100 units (centimeters) in Unreal Engine.

If you want to move something 2 feet in Unity, that would be 0.61units (meters). In Unreal Engine, the equivalent is 61 units (centimeters).

Which way is up in Unreal Engine's coordinate system?

Both Unity and Unreal Engine use a left-handed coordinate system, but the axes are named differently. In Unreal Engine, positive X is "forward", positive Y is "right" and positive Z is "up".

How do I see Log Output from my game?

Click the Output Log button in the bottom toolbar.

How do I throw exceptions?

Unlike Unity, Unreal Engine does not use exception handling. Instead, use the check() function to trigger a critical assertion error. You can pass in an error message. If you want to report an error but not halt the program, use ensure() instead. This will log an error with a full call stack, but program execution will continue. If you had a debugger attached, both functions will break into the debugger.

Where is the .NET Framework?

Unlike Unity, Unreal Engine does not use the .NET framework. Unreal Engine has its own set of container classes and libraries. Below is a list of common container comparisons:

.Net Framework

Unreal Engine

String

FString, FText

List

TArray

Dictionary

TMap

HashSet

TSet

You can learn more about other Unreal Engine containers here.

Does Unreal Engine automatically reload code changes?

Yes! You can leave the editor open while you write code. Start a compile from Visual Studio after you have finished editing code, and the editor will "hot reload" your changes automatically.

Finding Help and Answers

Thank you for reading! This guide was initially created for the Unreal community with the help of Unreal Engine developers everywhere, and we have now updated it for Unreal Engine 5. We'll keep improving this document as we learn more about what is most helpful when transitioning to Unreal Engine, so we very much appreciate any feedback and corrections you can offer.

To learn more about Unreal Engine, you can refer to rest of this documentation website, or visit the resources below:

Unreal Engine on YouTube

Forums

Community Resources

A

B

C

D

E

F

G

H

I

J

K

L

M

N

O

P

Q

R

S

T

U

V

W

X

Y

Z

Jump to:

ABCDEFGHIJKLMNOPQRSTUVWXYZ

A

Actor

An Actor is any object that can be placed into a level, such as a Camera, static mesh, or player start location. Actors support 3D transformations such as translation, rotation, and scaling. They can be created (spawned) and destroyed through gameplay code (C++ or Blueprints).

In C++, AActor is the base class of all Actors.

AI

AI, or Artificial intelligence, is behavior controlled by a set of programmed instructions, instead of by human input. For example, non-player characters (NPCs) are controlled with AI.

AIController

Just as the Player Controller possesses a Pawn as a representation of the player in a game, an AI Controller possesses a Pawn to represent a non-player character (NPC) in a game. By default, Pawns and Characters will end up with a base AI Controller unless they are specifically possessed by a Player Controller or told not to create an AI Controller for themselves.

The associated C++ class is AIController.

animation

Animation is a change in a property value over time. Examples include changes in position, rotation, and/or scale, but can also extend to any other property value as well.

"Animation" can refer specifically to sequences created in Unreal Matinee, or to sequences created for Skeletal Meshes in external 3D modeling and animation applications, and then imported into the Unreal Editor. It can even refer to a change over time in an Actor's property (or properties) created by C++ code or Blueprints.

Animation Sequence

An Animation Sequence, or AnimSequence, is an animation asset created in a 3D modeling and animation application for a Skeletal Mesh, and then imported into the Unreal Editor. You can work with Animation Sequences in Persona.

asset

An asset is an element used to build a game. Examples include content imported into or created in the Content Browser, such as Materials, Static Meshes, Textures, Particle Systems, Blueprints, and Sound Cues. Each asset is saved in an individual .uasset file.

B

Blueprints

The Blueprint Visual Scripting system is a complete gameplay scripting system that uses a node-based interface to create gameplay elements from within Unreal Editor. As with many common scripting languages, it is used to define object-oriented (OO) classes or objects in the engine. As you use UE4, you'll often find that objects defined using Blueprint are colloquially referred to as "Blueprints."

Blueprint Editor

The Blueprint Editor is a node-based graph editor. It also has several additional windows that serve targeted information and allow for additional modifications to be made to Blueprints and their graphs.

Blueprint Interface

A Blueprint Interface is a type of asset in which undefined functions are created. Any Blueprint can implement this Interface and then create its own definition of those functions. This serves as one way for Blueprints to communicate to one another, particularly when one Blueprint interacts with many other Blueprints.

Blueprint Macro Library

A Blueprint Macro Library is a Blueprint container that holds a collection of macros or self-contained graphs that can be placed as nodes in other Blueprints. These can be time-savers, because they can store commonly used sequences of nodes, complete with inputs and outputs for both execution and data transfer. Macros are shared among all graphs that reference them, but they are auto-expanded into the graph as if they were a collapsed node during compiling. This means that Blueprint Macro Libraries do not need to be compiled, but changes to a macro are only reflected in graphs that reference that macro when the Blueprint containing those graphs is recompiled.

Brush

A Brush is an Actor that describes a 3D shape, such as a cube or a sphere. You can place brushes in a level to define level geometry (these are known as Binary Space Partition or BSP brushes). This is useful if you want to quickly block out a level, for example.

C

Cascade

Cascade is the particle-system editor in the Unreal Editor. You can access Cascade by creating or opening a particle system in the Content Browser. In Cascade, you can add, modify, and remove Particle Emitters, add modules to Particle Emitters, and modify module properties.

Casting

Casting is an action that takes an Actor of a specific class and tries to treat it as if it were of a different class. Casting can succeed or fail. If casting succeeds, you can then access class-specific functionality on the Actor you cast to.

For example, let's say you're making a game where you have multiple types of Volumes that can affect the player character in different ways. One of these volumes is Fire, which decreases player health over time. When the player overlaps with any Volume in the Level, you can cast that Volume to Fire to try to access its "damage player health" functionality.

If the cast succeeds — that is, if the player is standing in the fire — the player's health starts to decrease.

If the cast fails — that is, if the player is standing in any other kind of Volume — their health is not affected.

Casting is different from simply checking whether an Actor is of a given class, which would return a binary (yes or no) answer, but wouldn't allow you to interact with any specific functionality of that class.

Character

A Character is a subclass of a Pawn Actor that is intended to be used as a player character. The Character subclass includes a collision setup, input bindings for bipedal movement, and additional code for player-controlled movement.

cinematic sequence

A cinematic sequence, also just called a cinematic, is an animation that is played in the game. Some cinematic sequences halt gameplay and involve one or more changes in camera viewpoint; these are called cutscenes. A cinematic sequence can either be created and controlled by Matinee or imported as a pre-rendered video created in an external application.

class

A Class defines the behaviors and properties of a particular Actor or Object in Unreal Engine. Classes are hierarchical, meaning a Class inherits information from its parent Class (that is, the Class it was derived or "sub-classed" from) and passes that information to its children. Classes can be created in C++ code or in Blueprints.

Blueprint Class

A Blueprint Class is an asset that content creators can use to easily add functionality on top of existing gameplay classes. Often shortened as just Blueprint. Blueprints are created inside of Unreal Editor visually, instead of by typing code, and saved as assets in a content package. They essentially define a new class or type of Actor, which can then be placed into maps as instances that behave like any other type of Actor.

collision

Collision is a programmatic way of preventing objects from overlapping during a physics simulation, giving the illusion of solidity in an object. May also refer to a Collision mesh, which is a simplified version of the geometry, generally existing as an invisible shell or hull around the mesh. This simplification aids in performance, allowing complex objects with high polygon counts to calculate their collisions with simpler geometry, which is faster to process.

"Collision" can also be non-blocking (overlapping). In this case, instead of preventing objects from interpenetrating each other, the collision can simply register that the objects are interpenetrating (overlapping).

A Collision surface is required for an object to be simulated via physics calculations.

component

A Component is a piece of functionality that can be added to an Actor.

When you add a Component to an Actor, the Actor can use the functionality that the Component provides. For example:

A Spot Light Component will make your Actor emit light like a spot light.

A Rotating Movement Component will make your Actor spin around.

An Audio Component will give your Actor the ability to play sounds.

Components must be attached to an Actor and can't exist by themselves.

Components Mode

In Components Mode, you can add components to your Blueprint, manage the details of existing components, and arrange components. The list of components in Components Mode is hierarchical.

Components Mode is one of three modes; the others are Default Mode and Graph Mode.

Construction Script

The Construction Script runs following the Components list when an instance of a Blueprint Class is created. It contains a node graph that is executed allowing the Blueprint Class instance to perform initialization operations. This can be extremely powerful as actions like performing traces into the world, setting meshes and materials, and so on can be used to achieve context-specific setup. For instance, a light Blueprint could determine what type of ground it is placed upon and choose the correct mesh to use from a set of meshes or a fence Blueprint could perform traces extending out in each direction to determine how long of a fence is needed to span the distance.

The Construction Script controls functionality while working with the object in the Editor, and the Event Graph controls functionality during gameplay; Construction Scripts do not execute during gameplay.

Content Browser

The Content Browser is the primary area of the Unreal Editor for creating, importing, organizing, viewing, and modifying content assets within Unreal Editor. It also provides the ability to manage content folders and perform other useful operations on assets, such as renaming, moving, copying, and viewing references. The Content Browser can search for and interact with all assets in the game.

In the Content Browser, you can search and sort assets by type, and you can filter your view of the assets either by choosing specific types of assets in the Filters drop-down list, or by typing text in the Search Assets box.

Controller Class

Controllers are non-physical Actors that can possess a Pawn (or Pawn-derived class like Character) to control its actions. A PlayerController is used by human players to control Pawns, while an AIController implements the artificial intelligence for the Pawns they control. Controllers take control of a Pawn with the Possess function, and give up control of the Pawn with the Unpossess function.

D

data pin



Data pins are used for taking data into a node or outputting data from a node. Data pins are type-specific and can be wired to variables of the same type (which have data pins of their own) or a data pin of the same type on another node. Like execution pins, data pins are displayed as an outline when not wired to anything, and solid when wired.



Nodes can have any number of input or output data pins. The data pins of a Function Call node correspond to the parameters and return value of the corresponding function.

Defaults Mode

The Class Defaults or Defaults mode displays all of the properties of the Blueprint, including variables contained within the Blueprint and components defined in native code as well as replication, navigation, and collision properties. The values set for these properties in the Defaults mode will be used when new instances of the Blueprint are created.

Defaults Mode is one of three Blueprint Editor modes; the others are Components Mode and Graph Mode.

Details panel

The Details panel is a panel in the Level Editor that contains information about the properties for various elements. Many of the tools and editors in UE4 contain Details panels: the Level Editor, Matinee, Persona, and so on.

Director Group

The Director Group is a specific type of Matinee group that controls camera viewpoints. You can use the Director Group to switch camera viewpoints between shots. Each Matinee sequence can have only one Director Group.

E

event

In Blueprints, an event is an entry point, or first executed node of visual scripting. This entry point is often triggered by an in-game occurrence. For instance, a player entering a volume can trigger an Overlap event, which can then be used to cause any functionality to happen within a Blueprint, such as opening a door, turning on a light, and so on.

EventGraph

The EventGraph of a Blueprint contains a node graph that uses events and function calls to perform actions in response to gameplay events associated with the Blueprint. This is used to add functionality that is common to all instances of a Blueprint. This is where interactivity and dynamic responses are setup. For example, a light Blueprint could respond to a damage event by turning off its LightComponent and changing the material used by its mesh. This would automatically provide this behavior to all instances of the light Blueprint.

execution pin



Execution pins are used to connect nodes together to create a flow of execution. When an input execution pin is activated, the node is executed. Once execution of the node completes, it activates an output execution pin to continue the flow of execution. Execution pins are displayed as an outline when not wired, and solid when wired to another execution pin. Function Call nodes always have only a single input execution pin and a single output execution pin as functions only have one entry point and one exit point. Other types of nodes can have multiple input and output execution pins, allowing for different behavior dependent on which pin is activated.

F

FBX file

FBX is a file format developed by Autodesk. This file format is used to import Static Meshes, Skeletal Meshes, and Animation Sequences into the Unreal Editor.

Flow Control

Flow Control operations allow the flow of execution to be controlled explicitly in Blueprints. This control can be in the form of choosing one branch of the graph to execute based on whether some condition is true, executing a specific branch multiple times, executing multiple branches in a specific order, and so on. The default flow control operations include branches (if statements), loops (for and while), gates, and sequences.

framework

The framework systems form the foundation of gameplay in the Unreal Engine. The gameplay framework can be divided into three categories: gametype, player, and interface. Each of these is responsible for a particular aspect of the gameplay and each is comprised of one or more systems and classes that define the different parts and how they work together.

G

GameMode

The Game Mode sets the rules of the game that is being played. These rules can include:

How players join the game.

Whether or not a game can be paused.

Any game-specific behavior such as win conditions.

You can set the default Game Mode in the Project Settings and override it for different Levels. Regardless of how you choose to implement it, you can only have one Game Mode for each Level.

In a multiplayer game, the Game Mode only exists on the server and the rules are replicated (sent) to each of the connected clients.

The associated C++ class is GameMode.

GameState

A Game State is a container that holds information you want replicated to every client in a game. In simpler terms, it is 'The State of the Game' for everyone connected.

Some examples of what the Game State can contain include:

Information about the game score.

Whether a match has started or not.

How many AI characters to spawn based on the number of players in the world.

For multiplayer games, there is one local instance of the Game State on each player's machine. Local Game State instances get their updated information from the server's instance of the Game State.

The associated C++ class is GameState.

Graph

The Graph is a visual representation of a particular graph of nodes as it shows all of the nodes contained in the graph as well as the connections between them. It provides editing capabilities for adding and removing nodes, arranging nodes, and creating links between

Breakpoints can also be set in the Graph to aid in debugging Blueprints.

The Blueprint Editor Modes were removed in 4.7. Please see Blueprint Editor Reference for information about the Blueprint Editor Interface.

group

In Matinee, a group is a container for animation and visual effects for a specific Actor. In the Level Editor, a group is an organizational object in which selected Actors can be combined together so they can be transformed as a single unit.

H

I

J

K

key, keyframe

In animation, a key or keyframe is a record of a given value or values at a specific time. Curves are then used to interpolate between these keyframes, resulting in animated change over time.

keybindings

Keybindings are custom-defined keyboard shortcuts. In the Unreal Engine, you can bind specific keys or key combinations to execute specific commands or actions.

Kill Z

The Kill Z is the coordinate along the Z axis at which an Actor is automatically destroyed or players are killed. Setting a Kill Z helps prevent player characters from getting stuck and being unable to respawn when they fall off an edge.

L

Level

A Level is a gameplay area that you define. Levels contain everything a player can see and interact with, such as geometry, Pawns, and Actors.

Unreal Engine saves each level as a separate .umap file, which is why you will sometimes see them referred to as Maps.

M

Material

A Material is an asset that can be applied to a mesh to control the visual look of the scene. At a high level, it is probably easiest to think of a Material as the "paint" that is applied to an object. But even that can be a little misleading, since a Material literally defines the type of surface from which your object appears to be made. You can define its color, how shiny it is, whether you can see through the object, and much more.

In more technical terms, when light from the scene hits the surface, a Material is used to calculate how that light interacts with that surface. These calculations are done using incoming data that is input to the Material from a variety of images (textures) and math expressions, as well as from various property settings inherent to the Material itself.

Unreal Engine 4 utilizes a physically-based shading model. This means that rather than defining a Material using arbitrary properties (such as Diffuse Color and Specular Power), you instead use properties more easily relatable to the real world. These include Base Color, Metallic, Specular, and Roughness.

Matinee

The Matinee animation tool provides the ability to animate the properties of Actors over time, to create either dynamic gameplay or cinematic in-game sequences. The system is based on the use of specialized animation tracks in which you can place keyframes to set the values of certain properties of the Actors in the level. The Matinee Editor is similar to the non-linear editors used for video editing, making it familiar to video professionals.

Matinee Actor

A Matinee Actor is a specific instance of a Matinee animation, created as an Actor and placed in your scene.

Migrate Tool

The Content Browser contains the Migrate Tool, which allows assets to be copied from one project to another, along with any dependent assets. For instance, you can migrate a Material, and any Texture assets that define that Material will automatically be copied along with it. This is useful when you need to merge or fork projects, or when transitioning from a test environment into a production project.

Mobility

Mobility is a property of Static Mesh and Light Actors. The Mobility property, which is set in the Details panel, determines whether an Actor can move during gameplay. In addition, for Light Actors, the Mobility property determines the types of light and shadows cast. Mobility property settings include Static, Stationary (Light Actors only), and Movable.

In the World Outliner, an Actor's Mobility setting is indicated by a small colored dot on the left: orange for Movable, yellow for Stationary, none for Static.

Actors with a Movable setting have the most versatility but the highest performance hit; Actors with a Static setting have the least versatility but the lowest performance hit.

Modes panel

Modes change the primary behavior of the Level Editor for a specialized task, such as moving and transforming assets in the world, sculpting landscapes, generating foliage, creating geometry brushes and volumes, and painting on meshes. Modes panels contain a selection of tools tailored to the selected editing mode.

Movable

Movable is one possible Mobility property settings. This setting can be applied to both Static Mesh and Light Actors.

Movable Static Mesh Actors can be moved during gameplay, and can interact with other Actors.

Movable Lights are lights that can be moved and changed in game. Typical uses would be headlights on a car, flashlights, light fixtures that sway in the wind, and so on. Movable Lights are completely dynamic, and do not support indirect lighting at the moment. Movable lights use dynamic shadowing for the entire scene. As a result, shadow casting movable lights can cost 20x more than a Stationary light.

Of the three light mobilities, Movable lights tend to have medium quality, highest mutability, and the highest performance cost.

Movable Lights can change position, rotation, color, brightness, falloff, radius, and just about every other property they have.

Move tool

The Move tool is a transformation widget that you can use to move (translate) Actors in your scene along the X, Y, and Z axes.

N

node

A node is a single block of visual scripting code, generally seen as a shape into which various data and/or execution wires are connected.

O

Object

Objects are the most basic class in Unreal Engine - in other words, they act like building blocks and contain a lot of the essential functionality for your Assets. Almost everything in Unreal Engine inherits (or gets some functionality) from an Object.

In C++, UObject is the base class of all objects; it implements features such as garbage collections, metadata (UProperty) support for exposing variables to the Unreal Editor, and serialization for loading and saving.

P

panel

A panel is a part of the UI that contains information about your level and can be moved, docked, or dragged into a separate window. Examples include the Details panel and the Content Browser.

Pawn

Pawns are a subclass of Actor and serve as an in-game avatar or persona (for example, the characters in a game). Pawns can be controlled by a player or by the game's AI, as non-player characters (NPCs).

When a Pawn is controlled by a human or AI player, it is considered to be Possessed. Conversely, when a Pawn is not controlled by a human or AI player, it is considered to be Unpossessed.

Persona

Persona is the animation editing toolset within Unreal. It is a robust system for editing Skeletons, Skeletal Meshes, Animation Blueprints, and various other animation assets. Most (if not all) of your animation work within Unreal will take place in this editor. This is a multi-purpose tool that contains panels for editing skeletal Sockets, previewing Animation Sequences, setting up animation Blend Spaces and Montages, editing Animation Blueprints, and much more.

You can open Persona by double-clicking any animation-related asset, such as Skeletal Meshes, Blend Spaces, Animation Blueprints, and so on.

PhAT

PhAT, the Physics Asset editing tool in the Unreal Editor, is used to modify physics and collision properties for Skeletal Mesh Actors.

Physical Material

Physical Materials are used to define the response of a physical object when interacting dynamically with the world. Physical Materials are fairly easy to use. Creating one will give you a set of default values, identical to the default physical material that is applied to all physics objects. Examples of this would be a character's dead body (ragdoll), a movable crate, and so on.

pin

A pin is part of a visual scripting node. Pins connect to other nodes via wires. Execution pins must be hooked up in order for a node to execute. Data pins are color-coded according to type, and are used to input data from or output data to other nodes.

pivot point

The pivot point (or origin point) indicates the location on a Static Mesh Actor or a Skeletal Mesh Actor that has been defined in the 3D modeling program in which it was created as the object's base for alignment purposes. The pivot point can be in the center of an object, at its base, or even outside it.

Play In Editor (PIE)

Play In Editor (PIE) is a mode in which you can play your level directly in the Unreal Editor window, starting in a location you specify, for testing purposes. In this mode, you can play the current level exactly as it would play in-game, so that you can test gameplay functionality, including player controls and level events triggered by players' actions.

PlayerController

A Player Controller takes player input and translates it into interactions in the game. Every game has at least one Player Controller in it. A Player Controller often possesses a Pawn or Character as a representation of the player in a game.

The Player Controller is also the primary network interaction point for multiplayer games. During multiplayer play, the server has one instance of a Player Controller for every player in the game since it must be able to make network function calls to each player. Each client only has the Player Controller that corresponds to their player and can only use their Player Controller to communicate with the server.

The associated C++ class is PlayerController.

PlayerState

A Player State is the state of a participant in the game, such as a human player or a bot that is simulating a player. Non-player AI that exists as part of the game world doesn't have a Player State.

Some examples of player information that the Player State can contain include:

Name

Current level

Health

Score

Whether they are currently carrying the flag in a Capture the Flag game.

For multiplayer games, Player States for all players exist on all machines and can replicate data from the server to the client to keep things in sync. This is different from a Player Controller, which will only exist on the machine of the player it represents.

The associated C++ class is PlayerState.

Project

An Unreal Engine 4 Project holds all the contents of your game. It contains a number of folders on your disk, such as Blueprints and Materials. You can name and organize folders inside a Project however you wish.

The Content Browser panel inside the Unreal Editor shows the same directory structure found inside the Project folder on your disk.

Choose your operating system:

Windows

macOS

Linux





The Content Browser pane mirrors the directory structure of the Project folder on your disk. Click the image for full view.

Every project has a .uproject file associated with it. The .uproject file is how you create, open, or save a project. You can create any number of different projects and work on them in parallel.

Q

R

Rotate tool

The Rotate tool is a transformation widget that you can use to rotate Actors in your scene along the X, Y, and Z axes.

S

safe frame

In Matinee, the safe frame is the view, defined by the viewpoint camera's field of view, that will be seen during your cinematic.

Scale tool

The Scale tool is a transformation widget that you can use to scale Actors in your scene along the X, Y, and Z axes.

Simulate In Editor (SIE)

Using the Simulate button begins a Simulate In Editor session in the currently active viewport. While simulating, gameplay begins, including the execution of Blueprints and C++ code that do not rely on a player's interaction with the game. While simulating, you have full access to the Editor's tools, so you can modify the scene and its contents, or even place new Actors. You can also select and inspect Pawns controlled by AI right as they are performing actions, and quickly debug and tweak gameplay behaviors. However, because you are not using a PlayerController while simulating, you cannot enter game controls. You can save certain changes made in a Simulate In Editor session using Keep Simulation Changes.

Skeletal Mesh Actor

A Skeletal Mesh Actor is a 3D model asset that can be animated in an external 3D modeling program and then imported into the Unreal Editor. A Skeletal Mesh Actor consists of two parts: the mesh itself and a hierarchical skeleton whose bones can be used to create animation by deforming the mesh according to rules defined in the 3D modeling program. You can import Skeletal Mesh Actors as assets in the Content Browser.

socket

Commonly in games, you will want to attach an object to the bone of a character. This might be a weapon attached to a hand, or a hat attached to the head. For this purpose, Unreal Engine allows you to create Sockets in its animation toolset - Persona - which are offset from a bone within the Skeletal Mesh. Sockets can then be translated, rotated, and scaled relative to the bone. Static Meshes and/or Skeletal Meshes can also be previewed attached to sockets. This allows content creators to easily set up sockets for a Skeletal Mesh, and then tell the programmer the names of the sockets to attach objects to.

sound cue

A sound cue is an audio asset that contains a reference to an audio file created in an external program that has been imported into a project. You can modify the audio output based on the imported audio file in the Sound Cue Editor.

Static

Static is one of three possible Mobility property settings. This setting can be applied to both Static Mesh and Light Components.

Static Lights are lights that cannot be changed or moved in any way at runtime. They are calculated only within Lightmaps, and once processed, have no further impact on performance. Movable objects cannot integrate with static lights, so the usefulness of static lights is limited.

Of the three light mobilities, Static lights tend to have medium quality, lowest mutability, and the lowest performance cost.

Static Mesh

A Static Mesh is a piece of geometry that consists of a set of polygons that can be cached in video memory and rendered by the graphics card. This allows them to be rendered efficiently, meaning they can be much more complex than other types of geometry such as Brushes. Since they are cached in video memory, Static Meshes can be translated, rotated, and scaled, but they cannot have their vertices animated in any way.

Static Meshes are the basic unit used to create world geometry for levels created in the Unreal Engine. These are 3D models created in external modeling applications (such as 3dsMax, Maya, Softimage, and so on) that are imported into the Unreal Editor through the Content Browser, saved in packages, and then used in various ways to create renderable elements. The vast majority of any map in a game made with Unreal will consist of Static Meshes, generally in the form of Static Mesh Actors. Other uses of Static Meshes are for creating movers such as doors or lifts, rigid body physics objects, foliage and terrain decorations, procedurally created buildings, game objectives, and many more visual elements.

Stationary

Stationary is one of three possible Mobility property settings. This setting can be applied only to Light Components.

Stationary Lights are lights that are intended to stay in one position, but are able to change in other ways, such as their brightness and color. This is the primary way in which they differ from Static Lights, which cannot change in any way during gameplay. However, it should be noted that runtime changes to brightness only affect the direct lighting. Indirect (bounced) lighting, since it is pre-calculated by Lightmass, will not change.

Of the three light mobilities, Stationary lights tend to have the highest quality, medium mutability, and medium performance cost.

T

tangent handle

A tangent handle is a tool used in keyframe editing to adjust the shape and curve of the lines connecting two keyframes. You can find tangent handles attached to the keys in Curve Editors.

Texture

Textures are images that are used in Materials. They are mapped to the surfaces the Material is applied to. Either Textures are applied directly - for example, for Base Color textures - or the values of the Texture's pixels (or texels) are used within the Material as masks or for other calculations. In some instances, Textures may also be used directly, outside of materials, such as for drawing to the HUD. For the most part, Textures are created externally within an image-editing application, such as Photoshop, and then imported into Unreal Editor through the Content Browser. However, some Textures are generated within Unreal, such as Render Textures. These generally take some information from the scene and render it to a Texture to be used elsewhere.

time cursor

The time cursor is the black vertical bar at the bottom of the timeline that indicates the position in time of the animation's playback. You can drag the time cursor back and forth to preview the animation in the 3D viewport.

timeline

A timeline is a visual representation of time in Matinee, which you can use to set and modify keys for keyframe animation, and to preview your cinematic. Different from the Timeline node in Blueprints.

Timeline node

Timeline nodes are special nodes within Blueprints that provide time-based animation to be quickly designed and played back based on events, floats,vectors, or colors that can be triggered at keyframes along the timeline.

Timelines can be edited directly inside the Blueprint editor by Double-clicking on the Timeline in the Graph tab or in the My Blueprint tab. They are specifically built for handling simple, non-cinematic tasks such as opening doors, altering lights, or performing other time-centric manipulations to Actors within a scene.They are similar to level sequences as they both provide values such as floats, vectors, and colors to be interpolated between keyframes along the timeline.

U

Unreal Frontend

UnrealFrontend (UFE) is a tool intended to simplify and speed up daily video game development and testing tasks, such as preparing game builds, deploying them to a device, and launching them. UFE is designed to be the central interface for all game deployment, profiling, and testing tasks.

V

viewport

The viewport is the visual representation of your level in the Level Editor. While working on your level, you can use a 3D viewport, 2D viewports, or a combination. Viewports contain a variety of tools to help you see exactly the data you need.

volume

Volumes are bounded 3D spaces that have different uses based on the effects attached to them. For example:

Blocking Volumes are invisible and used to prevent Actors from passing through them.

Pain Causing Volumes cause damage over time to any Actor that overlaps them.

Trigger Volumes are programmed to cause events when an Actor enters or exits them.

W

widget

A widget is a visual tool used in the Level Editor. Widgets typically have a visual representation in the viewport. For example, the Move tool has red, green, and blue arrows indicating the X, Y, and Z axes.

wire

A wire is a line connecting two nodes in the graph section of a visual script, such as a Blueprint. You create wires by dragging from the pins on nodes. You can drag a wire from a pin on one node to a pin on another node, or you can drag from a pin to an empty space, and use the context menu that is created to select another node to add to your graph. Like pins, wires are color-coded.

World

A World is a container for all the Levels that make up your game. It handles the streaming of Levels and the spawning (creation) of dynamic Actors.

X

Y

Z

Exporting Alembic Caches

Importing Alembic Files

Import as Static Mesh

Import as Geometry Cache

Import as Skeletal

The Alembic file format (ABC) is an open computer graphics interchange framework that distills complex, animated scenes into a non-procedural, application-independent set of baked geometric results. Unreal Engine 4 (UE4) enables you to import your Alembic files through the Alembic Importer, which gives you the freedom to create complex animations externally, then bring them into UE4 and render them in real-time.

Import Alembic files in a similar manner to several of the other forms of importing content into UE4.

You can also watch the Unreal Engine Live Stream on Animation Topics which include the Alembic File Importer:

Exporting Alembic Caches

To export an Alembic cache from Autodesk Maya:

From the File Menu under Cache and Alembic Cache, select Export All to Alembic... (or Selection) based on your needs.



In the Export window under Advanced Options, enable UV Write and Write Face Sets options, then click Export.



You will need to enable Write Face Sets if you plan to create Materials during import into Unreal Engine 4 as Materials are created based on found Face Set Names.

Importing Alembic Files

To import an Alembic File into Unreal Engine 4:

Inside the Content Browser, click the Import button and point to your .abc file.

The Alembic Cache Import Options window will appear where you can define the method/options for importing. This window displays the name of the file and location you are importing from. You will also see checkbox options for the assets within your file that you can choose to include or exclude from the import process (you can also use the top level checkbox to include or exclude all tracks).



Currently, Unreal Engine only supports meshes containing three and four-sided polygons. Your Alembic data will fail to load if your geometry contains any polygons with greater than four sides, or if your geometry is made from NURBS or SubDiv surfaces.

Import as Static Mesh

During the import process, you can define how to import your content. By default, the Alembic Import Type is set to Static Mesh.



Importing an Alembic cache as a Static Mesh will import a single frame, specified by Frame Start value in the Sampling section, as one or multiple Static Meshes. The Alembic animation from that frame will be imported as a Static Mesh asset and without animation. The following settings are also available:

Static Mesh Options

Setting

Description

Merge Meshes

Enable to merge the Static Meshes on import (this can cause problems with overlapping UV sets).

Propagate Matrix Transformations

Enable to apply matrix transformations to the meshes before merging them. (See Propagate Matrix Transformations.)

Generate Lightmap UVs

Enable to create lightmap UVs on import.

When importing an Alembic file as a Static Mesh, if your data contains several meshes within it, you can choose Merge Meshes to create a single Static Mesh inside Unreal Engine. If you disable this option, each mesh within your Alembic file will be imported into UE4 as an individual Static Mesh instead.

Propagate Matrix Transformations

When enabling Merge Meshes, consider whether or not to Propagate Matrix Transformations prior to merging the meshes. This will take the transformation data contained within the Alembic file and propagate it to the meshes upon merging so they retain their transform data.

Consider the sample scene created below which we export as an Alembic cache.



When we import the file into UE4 as a Static Mesh with Merge Meshes and Propagate Matrix Transformations we get the following:



If we Merge Meshes but uncheck the Propagate Matrix Transformations we get the following:



Each of the meshes are merged at the 0,0,0 origin.

Sampling Options



Setting

Description

Sampling Type

The type of sampling performed while importing the animation.

Per Frame (default): Samples the animation according to the imported data.

Per X Frames: Samples the animation at given intervals determined by Frame Steps.

Per Time Step: Samples the animation at given intervals determined by Time Steps.

Frame Start

Starting index to start sampling the animation from.

Frame End

Ending index to stop sampling the animation at.

Skip Empty Frames at Start of Alembic Sequence

Skip empty (pre-roll) frames where there is no geometry and start importing at the frame which contains actual data.

Normal Calculation Options



Setting

Description

Force One Smoothing Group Per Object

Enable to force smooth normals for each individual object rather than calculating smoothing groups.

Hard Edge Angle Threshold

Threshold value that determines whether an angle between two normals should be considered hard (closer to 0 means more smooth).

Recompute Normals

Enable to force the recomputation of normals.

Ignore Degenerate Triangles

Enable to ignore degenerate triangles when calculating tangents and normals.

The following is a high-level overview of how normals are calculated based on the Import type and how normals are used within the file to be imported.

When importing a file that contains normals for all frames:

For Static Meshes / Geometry Cache : the engine uses existing normals.

For Skeletal Meshes : the normals from the first frame determine smoothing groups, which are used to calculate normals for the average frame and all the bases and morph-targets (we do this in all cases).

When importing a file that contains normals for only the first frames:

For Static Meshes :If using frame 0, the engine uses existing normals. Otherwise it calculates smoothing groups and normals for the requested frame.

For Geometry Cache : the engine calculates smoothing groups and resulting normals for all frames.

When importing a file that contains no normals:

The engine calculates non-smooth normals, generates smoothing groups according to the calculated normals and recalculates normals within the smoothing groups.

When enabling Recompute Normals, the path specified above is used (for no normals).

When importing as a Skeletal Mesh, if your animation has a large normal delta, you may run into issues getting correct-looking normals. This is a known issue caused by the way morph-targets can alter the face and vertex normals. As a workaround, you can bypass this problem by using the (experimental) skin cache feature.

You can enable this feature in your Project Settings using the Support Compute Skincache and Force all skinned meshes to recompute tangents options.

This should recompile shaders the next time you start the editor. When you open the Skeletal Mesh asset, you should be able to enable the Recompute Tangent option for each material or section..

If you have hard edges on the meshes you import, you may want to look at the Hard Edge Angle Threshold and how smoothing group calculation is performed.





To calculate Smoothing Groups, first, the vertex and face normals are calculated, which are then used to look at all the faces that connect to a particular face. By calculating the angle between the normals, we can then determine if an edge is hard or soft (similar to the Soft/Hard Edges tool in Maya). Below, the image on the left we would consider a soft edge, while the image on the right, a hard edge. This is because the angle between the two normals in the image on the left is smaller than that of the angle of the two normals in the image on the right.



Knowing this, we use a dot product to generate a range from 0 to 1 as a threshold to define when an edge should be hard versus soft. For example, a value closer to 1 would mean that the angle is larger resulting in a hard edge, while closer to 0 would mean a soft edge. This information is then used to generate groups of normals that share soft edges. For each of these groups, we smooth the normals across the faces creating smooth faces.

Forcing one smoothing group per object makes each individual object completely smooth (all soft edges).

Import as Geometry Cache

Importing as a Geometry Cache creates a new type of animation asset that allows playback of vertex-varying sequences.



The imported Alembic animation will be played back as a Flipbook of frames and performance will scale with the complexity of your mesh.

Geometry Cache includes the same Sampling and Normal Calculation settings as the Static Mesh import option, while adding additional support for Materials and motion vectors. This method of import has the ability to create Materials according to found Face Set names (this will not work without Face Sets defined in your external application and exported as part of the Alembic cache). Importing motion vectors is enabled by changing the Motion Vectors option found in the Geometry Cache category of the importer:



Click the small down arrow at the bottom of the Geometry Cache section to see these options.

Setting

Description

No Motion Vectors

No motion vectors will be present in the geometry cache. Enabled by default.

Choosing this option will result in no motion blur.

Import Abc Velocities as Motion Vectors

Imports the velocities from the Alembic file and converts them to motion vectors. Storing the motion vectors on disc, will increase the file size..

If your geometry cache contains changing topology (the number of vertices changes during the animation), make sure to export vertex velocities from your 3D application and use this option.

Calculate Motion Vectors During Import

Forces calculation of motion vectors during import. Storing the motion vectors on disc, will increase the file size..

If your geometry cache does not contain changing topology (the number of vertices changes during the animation), use this option.

Include motion vectors to calculate the vertex velocities of your model and use them to calculate motion blur.

Currently, Geometry Cache assets do not support an adjacency buffer, which is required for tessellation setup. As a workaround, you can import an animation as a Skeletal Mesh with morph targets (which is a more compressed way of importing) as this will support tessellation.

Import as Skeletal

This method imports the Alembic file as a Skeletal Mesh containing base poses as morph targets and blending between them to achieve the correct animation frame. Importing as a Skeletal Mesh is the most efficient way to play back an Alembic animation, as long as the vertex count does not change.



During import, your animation sequence will be compressed using a Principal Component Analysis (PCA) scheme, in which common poses (bases) are extracted and weighted to compose the original animation during playback time. When importing as a Skeletal Mesh, in addition to Sample, Normal Calculation and a Create Materials option you can also define the percentage (or fixed number of bases used) to tweak the level of compression.

Compression Options

Setting

Description

Merge Meshes

Enable to merge the individual meshes for compression purposes.

Bake Matrix Animation

Enable to bake Matrix-only animation as vertex animation.

Base Calculation Type

Determines how the final number of bases that are stored as morph targets are calculated.

Percentage Based (default): Determines the number of bases to use with the given percentage.

Fixed Number: Sets a fixed number of bases to import.

Percentage (Max Number) of Total Bases

Generates the given percentage or fixed number of bases as morph targets.

This is one of the more important aspects for the level of compression. Entering a low amount of bases compresses the animation more, but fine animation detail may be lost. Conversely, entering a high number of bases results in less compression, but retains more animation detail.

Minimum Number Of Vertex Influence Percentage

Sets the minimum percentage of influenced vertices required for a morph target to be valid.

This setting allows you to determine when a base or morph target is imported based on your defined percentage of influence. For example, if we have a model with 1000

Animations containing significant vertex displacement from the origin may cause distortion to the Skeletal Mesh. You can mitigate this by choosing the No Compression option for Base Calculation Type and enable Merge Meshes.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Installing Unreal Engine

Creating a New Project

1. Required Project Setup

2. Creating Folders

3. Importing Meshes

4. Importing Textures

5. Preparing Meshes for Import

6. Creating Materials

7. Editing Materials

8. Applying Materials to Static Mesh Actors

Setting an Actor's Default Material

Changing Material Used by an Actor

9. On your own!

Choose your operating system:

Windows

macOS

Linux



Click image for full size.

This quick start guide shows you how to add assets to your Unreal Engine (UE5) games. By the end of this guide, you'll know how to use the Project Browser to create new projects and navigate the Content Browser to find and add content. You'll also know where to find information on the FBX Content Pipeline while learning how to use the Material Editor to modify Materials before applying them to a Static Mesh Actor.

1. Required Project Setup

Open Unreal Engine from the Launcher.

Create a new Project using the Games > Blank template using the following settings:

C++ enabled

With Starter Content enabled

We'll need to enter a project name, so we'll use Artist_QuickStart.

We can now click Create Project and get started.

The Unreal Editor will now open our new project. Visual Studio will also open and load the solution file that our project has created.

2. Creating Folders

It's always good practice to keep your project's content organized. The first thing you're going to learn is how to create a folder that will store your imported content.

Before you get started: Download Quick Start Assets from the following link.

Sample Assets

Extract the downloaded assets to a location on your computer.



Click image for full size.



Click image for full size.

From the Content Browser inside the Editor, click the Add New button.



Click image for full size.

Select New Folder to create a new folder.



Click image for full size.

Name the folder QuickStartContent.



Click image for full size.

Double-click the QuickStartContent folder.

Naming conventions matter! Be consistent when naming folders and files.

3. Importing Meshes

There are a few ways to add content to your UE5 project; however, we'll focus on the Content Browser's Import functionality.

Now that you're inside the QuickStartContent folder, click the Content Browser's Import button to open a file dialog box.



Click image for full size.

Locate and select the Basic_Asset1 and Basic_Asset2 FBX mesh files.



Click image for full size.



Click image for full size.

Click Open to begin importing the FBX mesh files to your project.

Inside the editor, the FBX Import Options dialog box appears. Clicking Import or Import All adds your meshes to the Project.



Click image for full size.

Click the Save All button to save your imported meshes.



Click image for full size.

A Save Content dialog box appears. Click Save Selected to save your imported assets.



Click image for full size.

Navigating to the QuickStartContent folder, verify that UE5 created the corresponding .uasset files.



Click image for full size.



Click image for full size.

Organize your assets so that you can easily find them.

4. Importing Textures

Navigating to the QuickStartContent folder in the Editor, click the Content Browser's Import button to open a file dialog box.



Click image for full size.

Locate and select the T_Rock_04_D and T_Rock_04_n Targa (TGA) image files.



Click image for full size.



Click image for full size.

Click Open to begin importing the TGA image files to your project.

A confirmation box appears in the lower right corner of the Unreal Editor.



Click image for full size.

Click OK to accept the T_Rock_04_n.TGA normal map's settings.

Click the Save All button to save your imported images.



Click image for full size.

A Save Content dialog box appears.

Click Save Selected to save your imported assets.

Navigating to the QuickStartContent folder, verify that UE5 created the corresponding .uasset files.



Click image for full size.



Click image for full size.

The Marketplace (accessible from the Epic Launcher) is a great place to find and share content.

5. Preparing Meshes for Import

If you have your own meshes to import, this section is for you.

The UE5 FBX import pipeline uses FBX 2018. Using a different version during export may result in incompatibilities.

Choose Your 3D Art Tool

Autodesk Maya

Autodesk 3ds Max

Select the mesh(es) to be exported in the viewport.



Click image for full size.

In the File menu, choose Export Selection (or Export All if you want to export everything in the scene regardless of selection).



Click image for full size.

In the Export dialog box:

Choose the Content folder inside your UE5 Project (1)

Enter a name for the file and set it to FBX Export (2)

Set your Export Options (3)

Click Export All (4)



Click image for full size.

The settings in the Geometry category above are the most basic requirements for exporting Static Meshes to Unreal Engine 5.

You can use the default options for importing. Refer to FBX Import Options Reference for more information on each option.

Your asset has now been imported and you can drag-and-drop it from the Content Browser into your level.



Click image for full size.

In the example above (as part of our Import Options), we imported Materials and Textures.

Select the mesh(es) to be exported in the viewport.



Click image for full size.

In the File menu, choose Export Selected (or Export if you want to export everything in the scene regardless of selection).

[ ](max_export_2.png

Click image for full size.

Choose the Content folder inside your UE5 Project (1) and a name for the FBX file (2) then click the button.



Click image for full size.

Set your options in the FBX Export dialog, then click the button to create the FBX file containing the mesh(es).



Click image for full size.

The settings in the Geometry category above are the most basic requirements for exporting Static Meshes to Unreal Engine 4.

You can leave the default options for importing. Refer to FBX Import Options Reference for more information on each option.

Your asset has now been imported and you can drag-and-drop it from the Content Browser into your level.



Click image for full size.

In the example above (as part of our Import Options), we imported Materials and Textures.

Well done! You've learned how to prepare meshes for import into UE5.

✓ Click here if you want to learn more about the FBX content pipeline..

Clean modeling improves a game's performance.

6. Creating Materials

Materials are assets applied to meshes, contributing to a scene's visual aesthetic. There are a few ways to create and edit materials for your UE5 project; however, we'll focus on using the Material Editor.

Navigating to your Content Browser, click Add New and select Material.



Click image for full size.

Name your material Rock.



Click image for full size.

Your Rock Material is now ready to be used.



Click image for full size.

Double-clicking the Rock Material will open the Material Editor.



Click image for full size.

Read our Material - How-to documentation if you want to learn more about working with material nodes.

Size your textures using powers of two.

7. Editing Materials

At this point, you should have created a new material and opened the Material Editor.



Click image for full size.

You can define a material's color, shininess, transparency, and much more in the Material Editor. You're now ready to edit the Rock Material you created.

Select the Main Material Node in the center of the Material Graph. The Material Editor will highlight the node for you when you select it.



Click image for full size.

It is the only node in the graph (named after your material).

Inside the Details panel, change the Shading Model from Default Lit to Subsurface.



Click image for full size.

The Subsurface Shading Model enables two more pins in the Main Material Node: Opacity and Subsurface Color.



Click image for full size.

Get your textures into the Graph. Hold the T key and left-click inside the Editor's Graph area. A Texture Sample Node should appear inside the graph.



Click image for full size.

You'll want at least 2 textures. Repeat Step 4 until your graph looks like the image below.



Click image for full size.

Select one of the Texture Sample Nodes and locate the Details Panel under the Material Expression Texture Base category.



Click image for full size.

Under the texture property, left-click the pull down menu labeled None and select the color texture named T_Rock_04_D.

You can also use the search field to locate the texture asset by entering T_Rock_04_D in the search field.

Repeat Step 6 for the other Texture Sample Node, making sure to select the normal map texture named T_Rock_04_n.



Click image for full size.

The Material Graph should resemble the image pictured above.

Connect the T_Rock_04_D Texture Sample's Color pin (white) to the Rock Material's Base Color pin.



Click image for full size.

The newly connected white pin contains the texture's color channels.

Connect the T_Rock_04_n Texture Sample's Normal pin (white) to the Rock Material's Normal pin.



Click image for full size.

The newly connected white pin contains information for the texture's normal map.

The Preview should look similar to the image pictured below.



Click image for full size.

Hold the 1 key and left-click in the Graph Panel to create three (3) Constant nodes.



Click image for full size.

The Constant Node is a modifiable scalar float variable.

Hold the 3 key and left-click in the Graph Panel to create one (1) Constant3Vector.



Click image for full size.

The Constant3Vector node is a modifiable vector corresponding to color without an alpha channel.

Read our Constant Expression documentation if you want to learn more about working with constant expressions.

Your nodes should be arranged so that connections can be easily made without wires crossing or sliding beneath each other.



Click image for full size.

Connect all of the Constant and Constant3Vector nodes to corresponding pins in the Rock Material Main Node.



Click image for full size.

Change the values of each Constant and Constant3Vector by updating their Value parameter in the Details panel.

Specular Value = 0.0

Roughness Value = 0.8

Opacity Value = 0.95

Subsurface Color = Red(1,0,0)



Click image for full size.

The Preview should look similar to the image pictured below.



Click image for full size.

Make sure to save your material before exiting the Material Editor.

You're almost done! You've just used the Material Editor to edit your Rock Material.

A list of all Material Editor Keyboard Shortcuts can be found by going to Edit Menu > Editor Preferences > Keyboard Shortcuts > "Material Editor" and "Material Editor-Spawn Nodes" categories.

8. Applying Materials to Static Mesh Actors

You're now ready to bring things together!

The objective of this step is to apply our Material to the Static Mesh we imported. Specifically, you'll learn how to:

Set an Actor's Default Material

Change Materials used by an Actor

Setting an Actor's Default Material

This section will show you how to set a Static Mesh Actor's default material. The default material will be used whenever an Actor is placed in the level.

Inside the Content Browser, double-click the asset you imported earlier in this guide.



Click image for full size.

The Static Mesh Editor will load your asset for editing.



Click image for full size.

Inside the Details panel under LOD0, left-click the material's drop-down menu.



Click image for full size.

Select the Rock Material you created earlier. The material should be available in the selection window.



Click image for full size.

Your Preview Pane will update to reflect the newly applied material.



Click image for full size.

Clicking the Save button first, close the Material Editor.

Inside the Content Browser, drag-and-drop the newly textured Static Mesh Actor into your level.



Click image for full size.

The specified Material will be used anytime you place this asset in the level.

Changing Material Used by an Actor

When we placed a Static Mesh object in our level, we created an instance of our object (an Actor). For every instance of that Actor, we're able to specify its Material.

Here's how you change a Static Mesh Actor's Material.

Select your Static Mesh Actor.



Click image for full size.

Inside the Details panel, locate the Materials section and click the Materials dropdown menu.



Click image for full size.

Inside the pop-up menu, select a different Material.



Click image for full size.

Alternatively, drag-and-drop a new Material onto the Static Mesh Actor.



Click image for full size.

You've just applied materials to your Static Mesh Actors by:

Setting your Actor's Default Material

Changing Material used by your Actor

We've now reached the end of the Artist Quick Start Guide. By now, you should have the skills needed to:

✓ Set-up a Project ✓ Create Materials ✓ Edit Materials ✓ Apply Materials to a Static Mesh Actor

Are you ready to do some exercises on your own?

9. On your own!

Using what you know, create a new Material similar to this graph:



Click image for full size.

The Main Material node settings simulate a plastic material.

Add Basic_Asset1 to the level, apply the Material to it, and update the Material to apply a "Brick" Normal Map Texture.



Click image for full size.

For information on importing different types of content, refer to:

Information on the FBX pipeline (in general): FBX Content Pipeline.

Information on the FBX Skeletal Mesh pipeline: FBX Skeletal Mesh Pipeline.

Information on the FBX Animation pipeline: FBX Animation Pipeline.

Information on the FBX Morph Target pipeline: FBX Morph Target Pipeline.

Information on the FBX Material pipeline: FBX Material Pipeline.

Information on Importing Audio: Audio Files.

For specifics covered in this Quick Start Guide, refer to:

Information on Supported Image Types: Texture Import Guide.

Information on Materials: Materials.

Information on the Content Browser: Content Browser.

Information on the Static Mesh Editor: Static Mesh Editor UI.

Unreal Engine supports a variety of file formats for importing content into your project.

FBX is a flexible file format that is owned by Autodesk and provides interoperability between digital content creation (DCC) applications. Some applications such as Autodesk Motionbuilder support the format natively. While others such as Autodesk Maya, Autodesk 3ds Max, and Blender support the format using FBX plugins.

The advantages of the Unreal FBX Import pipeline over other importing methods are:

Using a single file format for Static Mesh, Skeletal Mesh, animation, and morph targets.

Importing multiple LODs and Morphs/Blendshapes in one import operation.

Importing Material and Texture assets, and automatically applying them to Static Meshes.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.



Setting up, exporting, and importing animations for Skeletal Meshes using the FBX content pipeline.



Describes how to get custom user-defined attributes into Unreal through FBX, and how to work with them in the Unreal Editor using Blueprints and Python.



Explanations of the options available in the FBX Import Options dialog.



Guide to transferring basic materials and textures with meshes using the FBX content pipeline.



Creating and importing Morph Targets for Skeletal Meshes using the FBX content pipeline.



Using Import Into Level to bring full FBX scenes into Unreal Engine 4.



Setting up, exporting, and importing Skeletal Meshes using the FBX content pipeline.



Setting up, exporting, and importing Static Meshes using the FBX content pipeline.



Descriptions of errors generated during importing FBX files.

Naming

Creating Animations

Exporting Animations from 3D Apps

Importing Animations

Animation support in the FBX import pipeline provides a simple workflow for getting animations for Skeletal Meshes from 3D applications into Unreal for use in games. Currently, only a single animation for each Skeletal Mesh can be exported/imported in a single file.

This page is a technical overview of using the FBX content pipeline to import animations into Unreal.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

This page includes information on both Autodesk Maya and Autodesk 3ds Max, please choose your preferred content creation tool below and the information relevant only to the chosen tool will be displayed:

Choose Your 3D Art Tool

Autodesk Maya

Autodesk 3ds Max

Naming

When importing animations into Unreal using the FBX format, the AnimationSequence will be named the same as the name of the file. When importing animations along with a Skeletal Mesh, the AnimationSequence that is created will be taken from the name of the root bone in the animation sequence. This can easily be renamed after the import process is complete through the Content Browser.

Creating Animations

Animations can be unique to a single Skeletal Mesh or they can be reused for any number of Skeletal Meshes as long as each Skeletal Mesh uses the same skeleton. All you really need to create an animation and export it into Unreal using the FBX pipeline is a skeleton that has been animated. Having a mesh bound to the skeleton is completely optional, though it makes the process of creating the animation much easier as you can see how the mesh is deforming during the animation. At export time, only the skeleton is required though.

Exporting Animations from 3D Apps

Animations must be exported individually; one animation per Skeletal Mesh to a single file. The steps below are for exporting a single animation into a file by itself. The mesh bound to this skeleton has been hidden as it is not absolutely necessary for exporting animations by themselves.

Select the joints to be exported in the viewport.



In the File menu, choose Export Selection (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the animation to and set the appropriate options in the FBX Export dialog. For the purposes of exporting animations, you must enable the Animations checkbox.



Click the button to create the FBX file containing the mesh(es).

Select the bones corresponding to the animation to be exported in the viewport.



In the File menu, choose Export Selected (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the animation to and click the button.



Set the appropriate options in the FBX Export dialog. For the purposes of exporting animations, you must enable the Animations checkbox.



Click the button to create the FBX file containing the mesh(es).

Importing Animations

The FBX animation import pipeline allows for importing both a Skeletal Mesh and animation all at once, or importing one or the other individually.

Skeletal Mesh with Animation

Click the button in the Content Browser. Navigate to and select the FBX file you want to import in the file browser that opens. Note: you may want to select in the dropdown to filter out unwanted files.



The imported path of the imported asset depends on the current location of the Content Browser while importing. Make sure to navigate to the appropriate folder prior to performing the import. You may also drag the imported assets into a new folder once import is complete.

Choose the appropriate settings in the FBX Import Options dialog. The name of the imported mesh will follow the default naming rules See the FBX Import Dialog section for complete details of all of the settings.



Click the button to import the mesh and LODs. The resulting mesh, animation (AnimationSequence), material(s), and texture(s) will be displayed in the Content Browser if the process was successful. You can see the AnimationSequence that was created to hold the animation was named after the root bone of the skeleton by default.



Individual Animations

To import animations, you first need an AnimationSequence to import the animation into. This can be created through the Content Browser or directly in the AnimationSequence Editor.

Unreal Editor supports importing multiple animations contained in a single FBX file; however, many DCC tools such as 3ds Max and Maya do not currently support saving multiple animations to a single file. If you export from a supporting application such as Motion Builder, Unreal will import all the animations in that file.

Click the button in the Content Browser. Navigate to and select the FBX file you want to import in the file browser that opens. Note: you may want to select in the dropdown to filter out unwanted files.



The imported path of the imported asset depends on the current location of the Content Browser while importing. Make sure to navigate to the appropriate folder prior to performing the import. You may also drag the imported assets into a new folder once import is complete.

Choose the appropriate settings in the FBX Import Options dialog. The name of the imported mesh will follow the default naming rules. See the FBX Import Dialog section for complete details of all of the settings.



When importing animation on its own, you must specify an existing skeleton!

Click the button to import the mesh and LODs. The resulting mesh, animation (AnimationSequence), material(s), and texture(s) will be displayed in the Content Browser if the process was successful. You can see the AnimationSequence that was created to hold the animation was named after the root bone of the skeleton by default.



Unreal Editor supports non-uniform scale animations. When importing an animation, if scale exists, it will also import without the need for setting additional options. For memory reasons, the engine does not save scale for all animations and only saves it if it has scale that is not 1.

Refer to the Skeletal Mesh Animation page for more information and video samples.

Goals

Objectives

Exporting Animations

Importing Animations

Importing Animation with Skeletal Mesh

Importing Animation without Skeletal Mesh

We can import animations into Unreal Engine from external 3D modeling applications, such as 3DS Max, Maya or Blender. Although we're using 3DS Max and Maya to illustrate this lesson's goal, you can import animations into Unreal Engine from any 3D modeling application with a save feature.

Before getting started: Please make sure you have access to a 3D modeling application.

Goals

The focus of this guide is to show you how to import animations from external 3D modeling programs.

Objectives

After going through this guide, you'll know:

How to export animations from external 3D modeling applications.

How to import animations into Unreal Editor from external 3D modeling applications.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

Choose Your 3D Art Tool

Autodesk Maya

Autodesk 3ds Max

Exporting Animations

Animations must be exported individually with one animation per skeletal mesh in a single file.

Select the joints to be exported in the viewport.



In the File menu, choose Export Selection (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the animation to and set the appropriate options in the FBX Export dialog. For the purposes of exporting animations, you must enable the Animations checkbox.



Click the button to create the FBX file containing the mesh(es).

Select the bones corresponding to the animation to be exported in the viewport.



In the File menu, choose Export Selected (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the animation to and click the button.



Set the appropriate options in the FBX Export dialog. For the purposes of exporting animations, you must enable the Animations checkbox.



Click the button to create the FBX file containing the mesh(es).

Importing Animations

Unreal's FBX animation import pipeline allows content developers to import animations with or without skeletal meshes.

Importing Animation with Skeletal Mesh

In the Content Browser, click the Import button.



Locate and select the FBX file you want to import.



Click Open to begin importing the FBX file you want to import to your project.

Update the appropriate settings in the FBX Import Options dialog.

Default settings should be sufficient when importing a mesh that doesn't share an existing skeleton. When importing LODs, the name of the imported mesh will follow default Naming Conventions. Refer to our FBX Import Dialog documentation for additional information about all of the settings.



There are two import buttons available to us in the FBX Importer. The first option we have is the Import button, allowing us to import the currently selected FBX file with our specified settings. The second option we have is the Import All button, allowing us to import all of the currently selected FBX files with our specified settings.

For more information on the settings available to us in the FBX Importer, go to the FBX Import Options Reference page.

Clicking Import or Import All adds your meshes to the project.

The imported skeletal mesh and animations appear inside the Content Browser if the process succeeded.



By default, the AnimationSequence created to hold the imported animation is named after the skeleton's root bone.

Importing Animation without Skeletal Mesh

Unreal allows content creators to import multiple animations in a single FBX file; however, many DCC tools (such as 3ds Max and Maya) do no support the saving of multiple animations to a single file. If you export from supporting applications (such as Motion Builder), Unreal will import all of the animations contained in that file.

Before beginning this section, you'll need an AnimationSequence to import the animation into. Animation sequences can be created through the Content Browser or directly in the AnimationSequence Editor.

Inside the editor, click the Import button.



Locate and select the FBX file you want to import.



Click Open to begin importing the FBX file you want to import to your project.

Update the appropriate settings in the FBX Import Options dialog.

Default settings should be sufficient when importing a mesh that doesn't share an existing skeleton. When importing LODs, the name of the imported mesh will follow default naming conventions. Refer to our FBX Import Dialog documentation for additional information about all of the settings.



You must specify an existing skeleton when importing animations individually.

The imported skeletal mesh and animations appear inside the Content Browser if the process succeeded.



By default, the AnimationSequence created to hold the imported animation is named after the skeleton's root bone.

Now that we've reached the end of this guide, you've learned:

✓ How to export animations from external 3D modeling applications.✓ How to import animations into Unreal Editor from external 3D modeling applications.

Metadata Sources

Autodesk Maya

Autodesk 3ds Max

Metadata After Import

As the size and complexity of real-time 3D productions increases, and as the number of tools that make up a modern production pipeline continues to grow, adding intelligent automation to increase artist efficiency becomes ever more critical. This intelligent automation typically relies heavily on metadata: custom-defined properties about your Assets that give them meaning within your project.

An artist or creator adds metadata properties in one application, typically where the Asset is first created. The metadata then stays associated with that Asset, and applications farther down the pipeline can read that metadata and use it to make decisions about how to process or handle that Asset.

In the Unreal Editor, you can set and retrieve metadata keys and values for your Assets using Blueprints or Python scripting, as explained on the Asset Metadata page. This can help you with any Asset management operations you carry out solely within the context of your Unreal Project.

However, the real value of having metadata on Assets typically lies in interoperability with external applications, and in the ability to create larger Asset management pipelines that span multiple applications. To this end, the Unreal FBX Importer brings in certain kinds of Asset metadata from FBX files and makes that metadata available inside the Unreal Editor.

Because this metadata is assigned to the Assets in your Project, you can't access it directly in your runtime gameplay code. It is intended primarily for use in the Unreal Editor, for scripting Asset management operations.

Metadata Sources

When you import an FBX file into Unreal, the importer reads any FbxProperty values attached to the objects in that file and attaches them to the Unreal Assets it creates as a dictionary or map of tag-value pairs.

The following applications are known to support exporting custom user-defined metadata to FBX files through this FbxProperty system.

Autodesk Maya

To create metadata for an Asset in Maya, add extra custom attributes to the object. For details on how to do this, see the Maya Help.

Your custom attributes should show up in the Maya Attribute Editor, in the object's Extra Attributes list. For example, this object has two custom attributes created for it: one string property and one numeric property:



Autodesk 3ds Max

To create metadata for an Asset in 3ds Max, add it to the User Defined tab of the Object Properties dialog:



Currently metadata from 3ds Max is imported as a single string that contains the complete contents of the User Defined text box, which you can access in the FBX.UDP3DSMAX metadata tag. You will likely need to split this string value yourself when you read it in your Unreal Editor Python or Blueprint script.



Metadata After Import

There are a couple of things you need to know about how your Asset metadata appears in Unreal.

All metadata keys and values are stored as strings in Unreal Engine, regardless of their original type when set in an external application. For example, if you set a metadata value in Mayaas a number like 22, this will be a string that contains the value "22" when you read it back in a script within Unreal. If you need the values to be numbers, use a Blueprint conversion node like Utilities > String > String to Int or String to Float, or a built-in Python string parsing functions like int() or float().

If you create tag names with spaces in your source application, the spaces will be removed by FBX.

Typically, tag names have a prefix that indicates the source of the value. For Assets imported through FBX, this prefix is FBX.. Other applications or plugins may use other prefixes. For example, the Unreal Shotgun integration uses the prefix SG..

When you work with Skeletal Meshes, you may be able to assign different metadata values to each separate bone in the skeleton. In this case, the FBX import process still assigns all the metadata values to the Skeletal Mesh Asset, but it includes the bone names in the prefixes of the metadata tag names so that you can distinguish the values that apply to each individual bone. For example, on a Skeletal Mesh you may see tags similar to FBX.Right_Arm.tag_name and FBX.Right_Hand.tag_name.

So, for example, a tag that you create in Maya with the name Created By is available in Unreal as FBX.CreatedBy.

For more information on how to use this imported metadata in the Unreal Editor, see Asset Metadata.

Static Mesh Options

Skeletal Mesh Options

Animation Options

Transform

Miscellaneous

Material Options

Naming Rules

While importing FBX files into Unreal Engine 4 is a relatively simple procedure, there are quite a few options available for tweaking the imported asset. This document will cover those options.

When you import content through the Content Browser using the FBX pipeline, the FBX Import Options dialog appears. The importer will automatically detect what kind of file you are attempting to import and adjust its interface accordingly.

Static Mesh Options

The options available when importing a StaticMesh using FBX are explained below.



Option

Description



Mesh



Skeletal Mesh

For Static Meshes: This will attempt to import the FBX file as a Skeletal Mesh. The import options will switch to handle importing the FBX file as a Skeletal Mesh.

Auto Generate Collision

This will automatically generate collision for your Static Mesh. This will not be used if custom collision is detected in the FBX file.

Static Mesh LODGroup

This dropdown allows you to choose the LOD group to which the mesh will be assigned. Mesh LOD groups define default level-of-detail settings, light map resolution, and permit global overrides (e.g. reduce all SmallProp LODs by 10%). Mesh LOD group settings may be overridden per-platform / device profile. You may select an LOD group at import time and change it at any time in the Static Mesh Editor.

Vertex Color Import Option

If enabled, vertex colors on an existing mesh are replaced with the vertex colors from the FBX file. Disable this to preserve vertex colors painted within the editor using the Mesh Paint tool.

Vertex Override Color

This will be override color in the case that Vertex Color Import Option is set to Override.

Remove Degenerates

If enabled, degenerate triangles found during import will be removed. Disabling this option will keep degenerate triangles found. In general, this option should be enabled.

Build Adjacency Buffer

If true, the mesh will be optimized for PN tessellation. It is recommended to disable for larger meshes.

Build Reveresed Index Buffer

This is used to reduce the number of GPU state changes between drawcalls. This is required to optimize a mesh in mirrored transform. It will also double the index buffer size.

Generate Lightmap UVs

If enabled, the importer will generate a set of unique, non-overlapping, UVs for use with static lighting.

One Convex Hull per UCX

This option forces all UCX meshes to receive one convex hull. If disabled, then a UCX mesh could be decomposed by the engine into a series of convex hulls to get the appropriate shape.

Transform Vertex to Absolute

If true, the FBX file will use the transform, offset, and pivot for the world origin. If false, the FBX will import without any node heirarchy transform.

Bake Pivot in Vertex

If true, the pivot rotation will be applied to the mesh. The pivot of the FBX file will then be the origin of the mesh. Transform Vertex to Absolute must be set to false.

Import Mesh LODs

Creates LOD models for Unreal meshes from LODs defined in the file. Otherwise, only the base mesh from the LOD group is imported. For Skeletal Meshes, the LOD models can be skinned to the same skeleton, or a different skeleton. If the LOD model is skinned to a different skeleton, it must meet the Unreal LOD requirements, with the exception that the name of the root bones can be different since the FBX importer renames the root bones automatically.

Normal Import Method

This import option adjusts how Normals will be handled. The options are as follows:



Option

Description

Compute Normals

The engine computes normals and tangents. Smoothing group and normal info is discarded from the FBX info.

Import Normals

The normals are imported from the FBX file, tangents are computed by the engine.

Import Normals and Tangents

The normals and tangents are imported from the FBX file and nothing is computed by the engine.



Normal Generation Method

The option to choose between MikkTSpace or Built-in Normal generation method.

Skeletal Mesh Options

The options available when importing a SkeletalMesh using FBX are explained below.



Option

Description



Mesh



Skeletal Mesh

For Skeletal Meshes, disabling this will have the importer attempt to import the FBX file as a Static Mesh.

Import Mesh

Whether to import the mesh. This allows animation only imports when importing a Skeletal Mesh.

Import Content Type

Mesh content type you are importing.

Skeleton

The Skeleton the SkeletalMesh should target. If no existing Skeleton is selected, a new one will be created from the SkeletalMesh being imported. The new Skeleton's name will be that of the SkeletalMesh with Skeleton appended.

Vertex Color Import Options

If enabled, vertex colors on an existing mesh are replaced with the vertex colors from the FBX file. Disable this to preserve vertex colors painted within the editor using the Mesh Paint tool.

Vertex Override Color

This will be override color in the case that Vertex Color Import Option is set to Override.

Update Skeleton Reference Pose

If enabled, this will update the Reference Pose of Skeleton Asset of the Skeletal Mesh/Animation being imported, to the reference pose in the FBX file being imported.

Use T0As Ref Pose

If enabled, the first frame (frame 0) of the animation track will be used to replace the Skeletal Mesh's reference pose.

Preserve Smoothing Group

If enabled, triangles with non-matching smoothing groups will be physically split, duplicating shared vertices.

Import Meshes in Bone Hierarchy

If enabled, meshes nested in bone hierarchies will be imported instead of being converted to bones.

Import Morph Targets

If enabled, MorphTargets will be imported from the FBX files along with the SkeletalMesh.

Import Mesh LODs

If enabled, creates LOD models for Unreal meshes from LODs defined in the file. Otherwise, only the base mesh from the LOD group is imported. For skeletal meshes, the LOD models can be skinned to the same skeleton, or a different skeleton. If the LOD model is skinned to a different skeleton, it must meet the Unreal LOD requirements, with the exception that the name of the root bones can be different since the FBX importer renames the root bones automatically.

Normal Import Method

Allows for control of how Normals will be handled. The options are as follows:

Option

Description

Compute Normals

The engine computes normals and tangents. Smoothing group and normal info is discarded from the FBX info.

Import Normals

The normals are imported from the FBX file, tangents are computed by the engine.

Import Normals and Tangents

The normals and tangents are imported from the FBX file and nothing is computed by the engine.



Normal Generation Method

The option to choose between MikkTSpace or Built-in Normal generation method.

Create PhysicsAsset

If enabled, this will generate a new PhysicsAsset for the imported Skeletal Mesh. The PhysicsAsset will be composed of mostly spheres (with the exception being the root which will be a capsule/SphrL object), with the constraints being completely free on all rotational axis and completely locked on positional axis.

Select PhysicsAsset

If Create PhysicsAsset is disabled, you will be able to choose a PhysicsAsset that already exists or none to simply not have the Skeletal Mesh associated with a PhysicsAsset.

Animation Options

The options available when importing an Animation using FBX are explained below.



Option

Description



Mesh



Skeleton

The Skeleton the SkeletalMesh should target. If no existing Skeleton is selected, a new one will be created from the SkeletalMesh being imported. The new Skeleton's name will be that of the SkeletalMesh with Skeleton appended.



Animation



Import Animations

If enabled, Animations will be imported from the FBX files along with the SkeletalMesh. A name for the Animation can be entered in the text box to override the default naming.

Animation Length

Option

Description

Exported Time

This option imports animation frames based on what is defined at the time of export.

Animated Time

Will import the range of frames that have animation. Can be useful if the exported range is longer than the actual animation in the FBX file.

Set Range

This will enable the Start Frame and End Frame properties for you to define the frames of animation to import.

Import Meshes in Bone Hierarchy

If checked, the meshes nested in bone hierarchies will be imported instead of being converted to bones.

Frame Import Range

Option

Description

Min

When Set Range is used in Animation Length, this will enable you to set the start frame of the animation you wish to import.

Max

When Set Range is used in Animation Length, this will enable you to set the end frame of the animation you wish to import.

Use Default Sample Rate

If true, the default sample rate of 30 frames-per-second is used for the animation. If unchecked, the system determines the sample rate from the FBX file.

Custom Sample Rate

Sample FBX animation data at the specified sample rate. When set to 0, the best sample rate is automatically determined.

Import Custom Attribute

If enabled, import a custom attribute as a curve within the animation. Requires Import Animations to be enabled.

Delete Existing Custom Attribute Curves

If true, all previous custom attribute curves will be deleted when doing a reimport.

Import Bone Track

Import bone transform tracks. If false, this will discard any bone transform tracks. (Useful for curves-only animations.)

Set Material Curve Type

If true, this will set the Material Curve Type for all custom attributes that exists.

Material Curve Suffixes

Specify the suffix for Material Curve Types using the custom attribute. This does not matter if Set Material Curve Type is set to true.

Remove Redundant Keys

Redundant keys will be removed when importing a custom attribute as a curve.

Delete Existing Morph Target Curves

If enabled, this deletes currently existing MorphTargets. This setting is only used when reimporting a mesh and can be set in the Skeletal Mesh Editors Reimport settings tab.

Do not import curves with 0 values

When importing a custom attribute or morph target as a curve, do not import if it doesn't have any value other than zero. This is to avoid adding extra curves to evaluate.

Preserve Local Transform

The way the engine calculates and accumulates transforms is different. We calculate the global transform and then calculate back to the local transform. In some cases, this can affect animations using 3DS Max or non-uniform scale.

Override Animation Name

The name to assign the animation. If nothing is entered here, the Naming Rules will be used. Requires Import Animations to be enabled.

Transform

The options available when importing any Static or Skeletal Mesh asset using FBX are explained below.



Option

Description

Import Translation

This will enable the mesh to be moved along the XYZ axis when imported. This will be the location of the mesh when imported offset from the world origin.

Import Rotation

This will enable the mesh to be rotated along the XYZ axis when imported.

Import Uniform Scale

This will enable the mesh to be scaled uniformly when imported.

Miscellaneous

The other various options available when importing any Static or Skeletal Mesh asset using FBX are explained below.



Option

Description

Convert Scene

This will convert the scene from the FBX coordinate system to use UE4's coordinate system.

Force Front XAxis

This will convert the scene from the FBX coordinate system to UE4's coordinate system with the front X axis instead of -Y axis.

Convert Scene Unit

This will convert the scene from the FBX units of measurement to UE4's unit of measure, centimeters.

Override Full Name

This will use the string "Name" field as the full name of the mesh. This option only works when the scene contains one mesh.

Material Options

The options available when importing a Material using FBX are explained below.



Option

Description



Material



Search Location

Specify where we should search for matching materials when importing:

Option

Description

Local

Search for matching material in local import folder only.

Under Parent

Search for matching material recursively from parent folder.

Under Root

Search for matching material recursively from root folder.

All Assets

Search for matching material in all asset folders.



Material Import Method

Specify the import method for the following options.

Option

Description

Create New Materials

Automatically creates a new material asset from import

Create New Instanced Materials

Enables selection of Base Material Name.

Do Not Create Material

Do not create a new material asset from import



Import Textures

If enabled, Textures referenced in the FBX file are imported into Unreal. If Import Materials is true, textures are always imported regardless of this setting.

Invert Normal Maps

If enabled and textures are being imported, normal maps values will be inverted.

Reorder Material to Fbx Order

If enabled, the material list will be reordered to the same order as the FBX file.

Naming Rules

The table below shows how the various content types will be named when Override FullName is enabled.

The table assumes the following:

%1 is the name of the asset being imported, i.e. the last part of the Import Path.

%2 is the mesh node name in the FBX file. For SkeletalMesh, if it is composed of multiple FBX meshes, the first FBX mesh name is used as the part of FBX node name.

Content Type

Naming Rules

StaticMesh

If Override FullName is:

Enabled

If single mesh in file - Named as %1

If multiple meshes in file and Combine Meshes is:

Enabled - Named as %1

Disabled - Named as %1_%2

Disabled

If single mesh in file - Named as %1_%2

If multiple meshes in file and Combine Meshes is:

Enabled - Named as %1

Disabled - Named as %1_%2

SkeletalMesh

If Override FullName is:

Enabled

If single mesh in file - Named as %1

If multiple meshes in file - Named as %1_%2

Disabled - Named as %1_%2

AnimationSequence

If importing Animation with SkeletalMesh:

If animation name is entered (considered %1 in this case):

If single sequences in file - Named as %1

If multiple sequences in file - Named as %1_%2

If no name entered - Named as %1_%2

If importing only Animation:

If single sequences in file - Named as %1

If multiple sequences in file - Named as %1_%2

MorphTarget

Uses the names of the MorphTarget nodes in the FBX file.

Material Support

Multiple Materials

Material Naming

Material Ordering

Texture Import

The FBX pipeline transfers materials and textures applied to meshes (both Static Meshes and Skeletal Meshes) from 3D applications into Unreal. Simple materials can be converted by importing the textures used in source materials, thereby creating materials in Unreal with textures hooked-up to the appropriate channels and then, finally, applying the materials to the imported meshes. The FBX pipeline streamlines the mesh import process by automating what used to be a manually intensive process.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

This page includes information on both Autodesk Maya and Autodesk 3ds Max. Please choose your preferred content creation tool below. The tool's relevant information will then be displayed:

Choose Your 3D Art Tool

Autodesk Maya

Autodesk 3ds Max

Material Support

Only basic materials are supported for import with the FBX pipeline. The types of materials that can be transferred are:

Surface

Anisotropic

Blinn

Lambert

Phong

Phone E

Standard

Multi/Sub-Object

In addition to these material types, only specific features of those materials can be transferred. The FBX material pipeline does not transfer individual settings, but it does support the transfer of certain maps or textures used by the materials.

Currently, the supported maps (textures) being imported with the mesh will be added to the material, and some common types will be connected to their default inputs on the material, but some will require manual connections. Furthermore, the more uncommon map types may not be imported at all, such as using the Diffuse channel in Maya for Ambient Occlusion.

Multiple Materials

Meshes can have several materials applied to them, each covering certain faces of the mesh, and the FBX pipeline has the ability to handle the import of meshes with several materials (assuming they have been set up correctly in the 3D application).

Maya is pretty straightforward when it comes to the use of multiple materials on a mesh. You simply select the faces of the mesh you want to have the material applied to and then apply the material.





A material will be created in Unreal Editor for each material applied to the mesh in Maya, and the imported mesh will have material slots for each of these materials. When applied to the mesh, the materials will only affect the corresponding polygons of the mesh (just as they did in Maya).

In 3dsMax, multiple materials are handled by the use of a Multi/Sub-Object material. Each face of a mesh has a Material ID and each Standard material within the Multi/Sub-Object material is applied to the corresponding Material ID.





A material will be created in Unreal Editor for each of the Standard materials within the Multi/Sub-Object material and the imported mesh will have material slots for each of these materials. When applied to the mesh, the materials will only affect the corresponding polys of the mesh, just as they did in 3dsMax.

Material Naming

Materials created by Unreal Editor during the import process will be named the same as the source materials in the 3D application. Where the name is pulled from, depends on which application exported the mesh.

Coming from Maya, the material name in Unreal Editor is transferred from the name of the shading engine applied to the mesh in Maya.



Coming from 3dsMax, the material name in Unreal Editor is transferred directly from the name of the material applied to the mesh in 3dsMax.



Material Ordering



As of 4.14, the Skin## naming convention is no longer required to specify Material order.

When Materials are initially imported from an FBX, the Material Name is assigned to the Material Slot, so that when you reimport your FBX, the Orginal Import Material Name can be used to match up the Materials to the correct Element Index. This method is much more consistent than using the Skin## naming convention to order your Materials, guaranteeing that the import process looks directly at the name in the FBX file to determine which sections should match up with the existing Materials already populated in the list. The Slot Name here will match the Material Name drop-down selection in the Level of Detail (LOD) sections of your meshes.

If you hover over the text for Slot Name, the tooltip will list the name of the Material that was imported. Any Static Meshes or Skeletal Meshes that were imported prior to 4.14 will be given a Material Name of None in the tooltip.



To add or remove any Material Slots, use the add (+) button at the top of the Materials list, and the remove (x) button next to the Slot Name. Added Slots can be used to override the lower LOD sections, but not the base LOD.





Add (+) Material Slot

Remove (x) Material Slot

You can set your Material on a component at runtime, using the Slot Name you gave your Material by calling Set Material By Name. This saves you from having to hard-code the Material Element's index number to retrieve the Material Slot you're looking for. It also ensures that your gameplay code still works properly if the order of the Materials on the meshes were to ever change (since it references the Slot Name instead).

Texture Import

If a Material has a texture assigned as either the diffuse or normal map in the 3D application, those textures will be imported into Unreal as long as the Import Textures setting is enabled in FBX Import Properties.



A Texture Sample expression will be built in the newly-created material in Unreal Editor and the imported texture will be assigned to that Texture Sample. A Texture Coordinate expression will also be added to the material and connected to the UVs input of the Texture Sample. However, you will need to connect some textures to their material slots.



If the textures applied to the material in the 3D application are in a format that is not compatible with Unreal, or are connected to an unknown material attribute (for example, Diffuse in Maya), they will not be imported. In this case, and also if no textures were present in the material to begin with, the material in Unreal Editor will be populated with a randomly-colored Vector Parameter.



Supported Materials

Material Naming

Material Ordering

Importing Meshes with Multiple Materials

Importing Textures

We're using reference images from 3DS Max and Maya throughout this reference guide. Although there are other 3D modeling applications available for your use, this reference guide only covers 3DS Max and Maya.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

Choose Your 3D Art Tool

Autodesk Maya

Autodesk 3ds Max

Supported Materials

Unreal's FBX pipeline supports the following materials:

Surface

Anisotropic

Blinn

Lambert

Phong

Phone E

Standard

Multi/Sub-Object

Only basic materials are supported by Unreal's FBX pipeline. Uncommon map (texture) types will not be imported.

Material Naming

Unreal names materials in correlation with the originating application.

For Maya, the material name in Unreal Editor is transferred from the name of the shading engine applied to the mesh in Maya.



For 3dsMax, the material name in Unreal Editor is transferred directly from the name of the material applied to the mesh in 3dsMax.



Material Ordering

If material order is important, content creators can specify imported material order by using the *_skin## naming convention.

For example, order can be established by naming materials accordingly:

M_ExampleMesh_skin00

M_ExampleMesh_skin01

Importing Meshes with Multiple Materials

Unreal's FBX pipeline can import meshes with multiple materials.

Maya is pretty straightforward when it comes to the use of multiple materials on a mesh. You simply select the faces of the mesh you want to have the material applied to and then apply the material.





A material will be created in Unreal Editor for each material applied to the mesh in Maya, and the imported mesh will have material slots for each of these materials. When applied to the mesh, the materials will only affect the corresponding polygons of the mesh (just as they did in Maya).

In 3dsMax, multiple materials are handled by the use of a Multi/Sub-Object material. Each face of a mesh has a Material ID and each Standard material within the Multi/Sub-Object material is applied to the corresponding Material ID.





A material will be created in Unreal Editor for each of the Standard materials within the Multi/Sub-Object material and the imported mesh will have material slots for each of these materials. When applied to the mesh, the materials will only affect the corresponding polys of the mesh, just as they did in 3dsMax.

Importing Textures

If the material has a texture assigned as either a diffuse or normal map in the 3D application, those textures will be imported into Unreal as long as the Import Textures setting is enabled.

Naming

Setting Up Morph Targets

Exporting Morph Targets

Importing Morph Targets

A Morph Target is a snapshot of vertex locations for a specific mesh that have been deformed in some way. For instance, you can take a character model, reshape their face to create a facial expression, and then save that edited version as a Morph Target. In Unreal, you can blend the Morph Target to cause the character's face to make that expression. Morph Targets can be imported into Unreal via FBX, and will be encapsulated within an Animation Sequence.

This makes it very easy to import complex Morph Target animations into Unreal, since you can have any number of Morph Targets driving a single animation. For instance, you could use Morph Targets in your animation package to animate a character speaking some dialog. This animation may use any number of Morph Targets to capture the full motion of the face. However, when imported, the result will appear to be just a single Animation Sequence. You still have access to the animation data for each Morph Target via Curves.

Morph Target support in the FBX import pipeline provides an easy method for getting morph targets for skeletal meshes from 3D applications into Unreal for use in games. The pipeline allows for any number of morph targets for any number of Skeletal Meshes to be imported within a single file.

This page is a technical overview of using the FBX content pipeline to import morph targets into Unreal.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

This page includes information on both Autodesk Maya and Autodesk 3ds Max, please choose your preferred content creation tool below and the information relevant only to the chosen tool will be displayed:

Choose Your 3D Art Tool

Autodesk Maya

Autodesk 3ds Max

Naming

When importing morph targets into Unreal using the FBX format, the individual morph targets will be named according to the names of the blend shapes or morphs in the 3D application.

The name will be the name of the blendshape added to the name of the blendshape node, i.e. [BlendShapeNode]_[BlendShape].

The name will be the name of the channel in the Morpher modifier.

Setting Up Morph Targets

Setting up morph targets in Maya to be exported to FBX requires the use of blend shapes. The steps below provide a brief explanation of the steps necessary to set up a morph target for export. Refer to the help files of the application for more detailed information.

Start with the base mesh.



Duplicate the mesh that will be modified to create the target pose. In this case, it is the head. Create the target pose. For this example, the target pose is the character winking.



Select the target mesh and then the base mesh in that order.



In the Create Deformers menu of the Animation menu set, select Blend Shape. The target mesh can be deleted after this step if desired.



The blend shape node is now visible in the base mesh's properties. These are the names that will be used in Unreal. You can change the names of the blendshape node and the blendshape here.



Adjusting the blendshape's weight up to 1.0 causes the base mesh to interpolate toward the target pose.



Setting up morph targets in 3dsMax to be exported to FBX requires the use of the Morpher modifier. The steps below provide a brief explanation of the steps necessary to set up a morph target for export. Refer to the help files of the application for more detailed information.

Start with the base mesh.



Duplicate the mesh that will be modified to create the target pose. In this case, it is the head. Create the target pose. For this example, the target pose is the character winking.



Add a Morpher modifier to the base mesh. It needs to be before the Skin modifier in the stack.



With the morph channel you want to populate selected, press the in the Morpher modifier's properties rollout or right-click on the channel and choose Pick Object From Scene.



In the viewport, click on the target mesh.



The morph channel is now populated and displays the name of the target mesh. This is the name that will be given to the morph target in Unreal. You can change it in the Channel Parameters section of the Morpher modifier's rollout.



Adjusting the channel's weight up to 100.0 causes the base mesh to interpolate toward the target pose.



Exporting Morph Targets

Select the base mesh(es) and joints to be exported in the viewport.



In the File menu, choose Export Selection (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the morph target to and set the appropriate options in the FBX Export dialog. For the purposes of exporting morph targets, you must enable the Animations checkbox and all of the Deformed Models options.



Click the button to create the FBX file containing the morph target(s).

Select the base mesh(es) and bones to be exported in the viewport.



In the File menu, choose Export Selected (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the morph target to and click the button.



Set the appropriate options in the FBX Export dialog. For the purposes of exporting morph targets, you must enable the Animations checkbox and all of the Deformations options.



Click the button to create the FBX file containing the morph target(s).

Importing Morph Targets

The FBX morph target import pipeline allows for importing both a SkeletalMesh and morph target all at once. If you import and add morph targets to an existing Skeleton with morph targets already applied, the existing ones will be overridden.

Skeletal Mesh with Morph Targets

Click the Import button in the Content Browser. Navigate to and select the FBX file you want to import in the file browser that opens. Note: you may want to select in the dropdown to filter out unwanted files.



Choose the appropriate settings in the Import dialog. Make sure that Import Morph Targets is enabled. Note: The name of the imported mesh will follow the default Naming Rules. See the FBX Import Dialog section for complete details of all of the settings.



Click the OK button to import the mesh and LODs. The resulting mesh, morph target (MorphTargetSet), material(s), and texture(s) will be displayed in the Content Browser if the process was successful. You can see the MorphTargetSet that was created to hold the morph target was named after the root bone of the skeleton by default.



By viewing the imported mesh in Persona and using the Morph Target Previewer tab, you can adjust the strength of the imported morph target and see that it is working as expected.



The effect of Morph Targets is often subtle, but the control it offers the animator and the believability it adds to a character cannot be overstated.

FBX Full Scene Workflow

FBX Scene Import Options Dialog

Full Scene Reimporting

The Import Into Level command enables users to import full FBX scenes into their levels instead of importing assets individually. Users are given full control of exactly which assets will be imported, as well as per-asset control over import settings. The workflow also allows for selective reimporting for individual assets that receive further edits outside of Unreal.

At this time, FBX full scene import supports the following asset types:

Static Meshes

Skeletal Meshes

Animations

Materials (Basic support; may not match original material in your content creation app)

Textures

Rigid Mesh

Morph Targets

Cameras (no animation)

Lights

In order to reimport your scene later, you must import your scenes as a single Blueprint containing components for each asset in the scene.

FBX Full Scene Workflow

From the Main Menu bar, choose File > Import Into Level



Select the FBX file containing the scene you wish to import.



Choose the destination folder in your Unreal project.



Using the FBX Scene Import Dialog, select the assets (static meshes, skeletal meshes, and materials) from your scene you would like to import.



You may also select the final output of the import process, importing all selected FBX scene assets as:

Individual level Actors

Components of a single Actor

Components of a single Blueprint Actor Class (this is the only method that supports full scene reimporting)

Once you have imported your FBX scene, all of the assets will be imported into your project, along with an FBX Scene Data asset. This asset contains all of the linking information between the original FBX scene and all of the assets that were just imported into your project.



FBX Scene Import Options Dialog

The FBX Scene Import Options Dialog gives you complete control over which assets will be imported into your scene and which will be included in the final output asset(s). You can also establish named groups of specific import settings, and quickly assign them to objects in your scene.

Scene Tab

The Scene tab is where you can control how each asset from your FBX scene will be imported. The left side includes a tree view of the scene hierarchy. The right includes general import options for the entire scene.



It is important to note that unchecking an asset in the tree view of the Scene Tab will not prevent that asset from being imported. It only prevents the asset from being included in the final output (level actors, single actor components, or Blueprint). In order to completely prevent an asset from being imported, you must uncheck it in both the Scene Tab and the Static Meshes or Skeletal Meshes tab, respectively. This workflow enables you to import assets from the scene that you may use eventually.

Option

Description

Create Content Folder Hierarchy

This will automatically create a folder representing each tier in the hierarchy. The folder will be named after the first item found at that hierarchy level.

Import as Dynamic

If checked, the mobility of all actors or components will be dynamic. If unchecked, they will be static.

Hierarchy Type

This is where you choose the final output of the import process:

Blueprint Asset

This creates a single Blueprint Actor. All the assets selected in the tree view will become components of this Blueprint Actor. This is the only hierarchy type that supports full scene reimporting.

Actor Component

This will create a single Actor, with each of the selected assets from the tree view imported as its components. This type does not support reimporting.

Actors

This option will import each of the assets in the tree view as individual Actors. This type does not support reimporting.

Static Meshes Tab

The Static Meshes tab contains all options for importing the various Static Meshes found in your FBX scene file. On the left is a list of all of the included meshes, where you can uncheck meshes you do not want imported. On the right are the Static Mesh import options. This tab includes the ability to create presets of import options that can be quickly applied to groups of Static Meshes in the list view. The options found are similar to those in the standard Static Mesh import options.

The Static Meshes tab also includes the ability to create sets of override options, which will be covered in the Option Overrides section.



Skeletal Meshes Tab

The Skeletal Meshes tab will show all of the Skeletal Meshes being imported into the scene from your FBX file. On the left is a list of all the included Skeletal Meshes. As with the Static Meshes tab, you can uncheck any meshes you do not want to import. The right side contains a list of options for each of the Skeletal Meshes being imported, and is very similar to the standard Skeletal Mesh import options.

The Skeletal Meshes tab also includes the ability to create sets of override options, which will be covered in the Option Overrides section.



Materials Tab

The Materials tab enables control over the materials that are being imported into your scene along with your FBX file. You can also Right-click on an existing material from the FBX file and replace it with an existing one in your project.

Keep in mind that the FBX importer never allows you to override materials that already exist in the project. You can only assign existing materials to replace those in the FBX, or it will create new materials with basic texture hookups.



Also on the Materials Tab you can override the location of where to save all Materials. Click the Browse option and define where in your project you would like to import your Materials to.



Option Overrides

Option overrides can be used to group sets of import options into a named set, which can then be applied to multiple assets simultaneously. This allows users to quickly create sets of common options for groups of meshes, rather than having to set them all one at a time.

To create and apply an option override:

Click the Create Override button found in either the Static Meshes or Skeletal Meshes tab.



Enter a name for the new override.



With the new override selected from the dropdown at the top of the options list, set your desired options.



Select any number of meshes from the list on the left of the tab, then Right-click and choose your new override from the context menu.



You may also remove any selected override by clicking the Delete button, located above the options list.

Full Scene Reimporting

If you have imported your scene as a Blueprint object, you also have the ability to do a full scene reimport. This works very similarly to the full scene import functionality, but also tells you what components of your FBX scene have been added, removed, or edited. Using full scene reimport, it is easy to return to your DCC app, make any desired changes, and then bring your complete scene back into Unreal, selectively applying only the changes you wish to update.

Scene Reimport Workflow

To reimport your scene Right-click on the FBX Scene Import Data asset (or any assets imported by a previous scene import) and choose Reimport from the context menu.



This will open the FBX Scene Reimport Options dialog. This dialog is similar to the FBX Scene Import options, but will also show any assets that have been removed (their icons will have a minus sign) and assets which have been added (their icons will have a plus sign). The scene asset tree view can also be filtered to show you which assets in your FBX scenes have been added, removed, or changed.



The dialog consists of the same four tabs as before:

Scene

Static Meshes

Skeletal Meshes

Materials

Reimport List Filter Buttons

All of the tabs of the FBX Scene Reimport Options dialog contain a series of filters for quick access to changed assets. These filters include:



Option

Description

Add

This will automatically create a folder representing each tier in the hierarchy. The folder will be named after the first item found at that hierarchy level.

Delete

This only shows those assets in the FBX scene that have been removed since the last import.

Overwrite

This shows only assets that will be overwritten from the last import.

Diff

This shows only assets that are different (added or deleted) from the last import.

Reimport Scene Tab

The Reimport Scene tab is essentially the same as the Scene tab from the original Import Into Level operation. However, a key difference is the ability to reimport the hierachy. When the Reimport Hierarchy checkbox (found at the top of the Options group) is checked, this re-imports the Blueprint's hierarchy, causing you to lose any changes you've made to the Components list of the Blueprint. Any node graph changes you make to the Blueprint will be maintained.



Reimport Static Meshes Tab

The Reimport Static Meshes Tab shows offers the same functionality as the standard Static Meshes Tab found in the FBX Scene Import Dialog, now applied to meshes being reimported. You can also filter the results using the Filter Options.



Reimport Skeletal Meshes Tab

The Reimport Skeletal Meshes Tab shows offers the same functionality as the standard Skeletal Meshes Tab found in the FBX Scene Import Dialog, now applied to meshes being reimported. You can also filter the results using the Filter Options.



Reimport Materials Tab

The Reimport Materials Meshes Tab shows offers the same functionality as the standard Materials Tab found in the FBX Scene Import Dialog, now applied to materials that are a part of the FBX scene being reimported.

Remember that the importer will never overwrite existing Materials!



General Setup

Single Mesh vs Multi-Part Mesh

Rigging

Skeleton

Binding

Pivot Point

Triangulation

Creating Normal Maps

Materials

Vertex Colors

Export Mesh from 3D App

Import Mesh

Skeletal Mesh LODs

LOD Setup

Multi-Part LODs

Export LODs

Import LODs

Export to FBX from Unreal Editor

Physics Assets

Animations

Morph Targets

Skeletal Mesh support in the FBX import pipeline provides a streamlined workflow for getting animated meshes from 3D applications into Unreal for use in games. In addition to the meshes being imported, animations and morph targets can be transferred using the FBX format all within the same file if desired. Also, the textures (diffuse and normal map only) used in the materials applied to those meshes in the 3D application will be imported and materials will be automatically created and applied to the imported meshes.

Features supported for importing Skeletal Meshes using FBX:

Materials including textures

Animations

Morph Targets

Multiple UV sets

Smoothing groups

Vertex colors

LODs

Currently, only a single animation for each Skeletal Mesh can be imported in a single file. Multiple morph targets can be transferred for a Skeletal Mesh in one file, though.

This page is a technical overview of using the FBX content pipeline to import Skeletal Meshes into Unreal.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

In any case below where the document tells you to use the Import Asset button, you can also just click and drag an FBX file in from your OS's file browser.

This page includes information on both Autodesk Maya and Autodesk 3ds Max, please choose your preferred content creation tool below and the information relevant only to the chosen tool will be displayed:

Choose Your 3D Art Tool

Autodesk Maya

Autodesk 3ds Max

General Setup

Single Mesh vs Multi-Part Mesh

Skeletal Meshes can be comprised of a single, contiguous mesh or they can be made up of several separate meshes all skinned to the same skeleton.



Using multiple meshes makes it possible to LOD individual parts differently as well as exporting parts separately for use in modular character systems. There is no performance penalty for creating your Skeletal Meshes this way. The individual parts are all combined when being imported into Unreal Editor.

Rigging

Rigging refers to the binding of a mesh to a skeletal hierarchy of bones/joints. This allows the bones/joints of the underlying skeleton to influence the vertices of the mesh, deforming it as they move.

In Maya, you will generally use the Joint Tool to create the skeleton for your Skeletal Mesh. Again, there are endless tutorials on using this tool and creating rigs in Maya. The Maya help is also a good source of information on the subject.



Skeletal density has increased dramatically since Unreal 3

How you go about creating skeletal hierarchies in 3dsMax is up to you. You may use the standard Bones Tools as they work quite well, or create your own hierarchy of objects to allow for completely custom geometry and controls. There are many ways to skin a cat (pardon the pun) and tons of tutorials out there that show how to create animation rigs for game characters. You can also refer to the 3dsMax Help for complete details on how the tools work.



In Maya, the mesh(es) are bound to the skeleton using the Smooth Bind command. The process is the same whether the Skeletal Mesh consists of a single complete mesh or is made up of multiple mesh parts.

Select the mesh(es) to be bound.



Shift + Select the root joint of the skeleton.



Select Smooth Bind from the Skin > Bind Skin menu.



Now you can adjust the weights of the vertices of the mesh for each joint to determine which vertices are influenced by which bones and to what degree. This can be done using the Paint Skin Weights Tool or whichever method you prefer.



In 3dsMax, the mesh(es) must be bound to the skeleton using the Skin modifier. The process is the same whether the Skeletal Mesh consists of a single complete mesh or is made up of multiple mesh parts.

Select the mesh to be bound.



Add a Skin modifier from the Modifier List.



In the Parameters rollout of the Skin modifier, click the button to add the bones that will influence the mesh. The Select Bones window will open.



Select the bones in the Select Bones window and click the Select button to add the bones.



The bones are now displayed in the Bones list of the modifier.



Now you can adjust the weights of the vertices of the mesh for each bone to determine which vertices are influenced by which bones and to what degree. This can be done using envelopes, directly entering the weights for the vertices, or whichever method you prefer.



Pivot Point

The pivot point of the mesh in Unreal Engine determines the point around which any transformations (translation, rotation, scale) will be performed.



The pivot point of a Skeletal Mesh is always located at the root bone/joint of the skeleton. This means it does not matter where the root of the skeleton is located within the scene. It will be as though it is at the origin (0,0,0) when exporting from a 3D modeling application.



Triangulation

Meshes in Unreal Engine must be triangulated as the graphics hardware only deals with triangles.



There are several ways you can ensure your mesh is triangulated.

Model the mesh with only tris - best solution, provides the most control over the end result.

Triangulate the mesh in the 3D app - good solution, allows cleanup and modification before export.

Allow the importer to triangulate the mesh - okay solution, allows no cleanup but can work for simple meshes.

Allow the FBX exporter to triangulate the mesh - okay solution, allows no cleanup but can work for simple meshes.

Note: Allowing the FBX exporter to triangulate the mesh results in completely random smoothing when Split Non-Matching Triangles is checked. Importing an FBX-triangulated mesh back into Maya and re-exporting shows proper smoothing.

It will always be best to manually triangulate the mesh in the 3D application, controlling the direction and placement of

Automatic triangulation can lead to undesirable results.



Creating Normal Maps

Normal maps can be created for your meshes directly inside of most modeling applications by creating both a low-res render mesh and a high-res detail mesh.



The geometry of the high-res detail mesh is used to generate the normals for the normal map. Epic uses a workflow internally that introduces XNormal into the process and generally results in much better normals when rendering inside of Unreal Engine 4. For details on this process, see Textures.

Materials

The materials applied to meshes modeled in external applications will be exported along with the mesh and then imported into

This streamlines the process as textures do not need to be imported separately in Unreal Ed, materials do not need to be created and applied, etc. The import process is capable of performing all of these actions when using the FBX pipeline.

These materials also need to be set up in a specific way, especially when the mesh has multiple materials or the order of the materials on the mesh is important (i.e. for character models where material 0 needs to be the body and material 1 needs to be the head).

For complete details of setting up materials for export, see the FBX Material Pipeline page.

Vertex Colors

Vertex colors (one set only) for Skeletal Meshes can be transferred using the FBX pipeline. No special setup is necessary.



Export Mesh from 3D App

Skeletal Meshes can be exported individually or multiple meshes can be exported to a single FBX file. The import pipeline will separate multiple Skeletal Meshes into multiple assets within the destination package.

Select the mesh(es) and joints to be exported in the viewport.



In the File menu choose Export Selection (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the mesh(es) to and set the appropriate options in the FBX Export dialog and then click the button to create the FBX file containing the mesh(es).



Select the mesh(es) and bones to be exported in the viewport.



In the File menu, choose Export Selected (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the mesh(es) to and click the button.



Set the appropriate options in the FBX Export dialog and then click the button to create the FBX file containing the mesh(es).



Import Mesh

Click the button in the Content Browser. Navigate to and select the FBX file you want to import in the file browser that opens. Note: you may want to select in the dropdown to filter out unwanted files.



The path of the imported asset depends on the current location of the Content Browser while importing. Make sure to navigate to the appropriate folder prior to performing the import. You may also drag the imported assets into a new folder once import is complete.

Choose the appropriate settings in the FBX Import Options dialog. The defaults should be sufficient when importing a mesh that does not share an existing Skeleton. See the FBX Import Dialog section for complete details of all of the settings.



If the Skeletal Mesh being imported shares an existing Skeleton, click the Select Skeleton dropdown menu and select the Skeleton asset from the list.



Click the button to import the mesh(es). The resulting mesh (as well as materials and textures if those options were enabled) are displayed in the Content Browser if the process was successful.



By viewing the imported mesh within Persona, you can determine that the process worked as expected.



Skeletal Mesh LODs

Skeletal Meshes can make use of levels of detail (LODs) in-game in order to limit the impact of meshes as they get farther from the camera. Generally, this means each level of detail will have a reduced number of tris, simpler skeleton, and, perhaps, a simpler material (or materials) applied to it.

The FBX pipeline can be used to export/import these LOD meshes.

LOD Setup

In general, LODs are handled by creating models of varying complexity going from the full-detail base mesh to the lowest-detail LOD mesh. These should all be aligned and occupying the same space with the same pivot point and should all be skinned to the same skeleton. It is also possible for Skeletal Meshes to be made up of multiple individual meshes within the 3D application. Each of these parts can have LODs independent of the rest of the mesh. This means that some parts can have simplified versions in different LODs while other parts continue to use higher detail versions. Each LOD mesh can have completely different materials assigned, including different amounts of materials. This means the base mesh could use multiple materials to give the desired amount of detail up close, but the lower-detail meshes could use a single material since details will be less noticeable.

Select all of the meshes (base plus LODs) in order from the base LOD down to the last LOD. This is important so that they are added in the correct order in terms of complexity. Then select the Level of Detail > Group command from the Edit menu.



You should now have the meshes all grouped under the LOD Group.



Select all of the meshes (base plus LODs - the order is not important) and then select the Group command from the Group menu.



Enter a name for the new group in the dialog that opens and the click the button to create the group.



Click the button to view the Utilities panel and then choose the Level of Detail utility. Note: You may need to click and select it from the list.



With the group selected, click the button to create a new LOD Set and add the meshes in the selected group to it. The meshes will automatically be ordered according to their complexity.



Setting up LODs for multi-part Skeletal Meshes is almost identical to setting up LODs for a full mesh with the exception that each individual part that has LODs will have an LOD group created for it. The process for setting up those individual LOD groups is identical to the process outlined above.

Export LODs

To export the Skeletal Mesh LODs:

Select the LOD Group(s) and the joints to be exported.



Follow the same export steps used for the base mesh (described above in the Export Mesh section).

Select the Group(s) of meshes that comprise the LOD Set and the bones to be exported.



Follow the same export steps used for the base mesh (described above in the Export Mesh section).

Import LODs

Skeletal Mesh LODs can be imported easily through the Mesh Details panel in Persona under LOD Settings.

Open the Skeletal Mesh you wish to apply an LOD to in Persona and go to the Mesh Tab.

In the Mesh Details panel, scroll down and find the LOD Settings section and click the LOD Import option.



Navigate to and select the FBX file you want to import in the file browser that opens.



The imported LOD will be added to the Mesh Details panel.



Under each LOD, the Screen Size setting indicates when to use the LOD.



Note: Using a smaller number means use the LOD when further away while larger numbers mean use the LOD when closer. In the image above, LOD0 is used when closer to the Skeletal Mesh while LOD1 is used when further away.

When importing or adding LODs, Reduction Settings can also be adjusted for the LOD.



Export to FBX from Unreal Editor

Skeletal Meshes previously imported into Unreal Editor can be exported back to an FBX file from within the Content Browser.

Assets in cooked packages cannot be exported as the source data which has been cooked out is required for the export process.

In the Content Browser, select the Skeletal Mesh you want to export.



Right-click on the Skeletal Mesh and choose Asset Actions > Export.



Choose a location and name for the file to export in the file browser that appears. Note: make sure FBX File (*.FBX) is selected as the file type.



Physics Assets

For complete details on using the Physics Asset Tool (PhAT), see the Physics Asset Tool user documentation.

Animations

For complete details on using the FBX content pipeline to create and import animations, see the FBX Animation Pipeline page.

Morph Targets

For complete details on using the FBX content pipeline to create and import morph targets, see the FBX Morph Target Pipeline page.

FBX Import Options Reference

FBX Skeletal Mesh Pipeline

FBX Import Options Reference

Goals

Objectives

Exporting Skeletal Meshes from External 3D Modeling Applications

Importing Skeletal Meshes

Verifying Imported Skeletal Meshes

Choose your operating system:

Windows

macOS

Linux

We can import static meshes into Unreal Engine from external 3D modeling applications, such as 3DS Max, Maya or Blender. Although we're using 3DS Max and Maya to illustrate this lesson's goal, you can import skeletal meshes into Unreal Engine from any 3D modeling application with a save feature.

Before getting started: Please make sure you have access to a 3D modeling application.

Goals

The focus of this guide is to you how to import skeletal meshes from external 3D modeling applications.

Objectives

After going through this guide, you'll know:

How to export skeletal meshes from external 3D modeling applications.

How to import skeletal meshes into Unreal Editor.

How to verify that skeletal meshes were imported properly.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

Choose Your 3D Art Tool

Autodesk Maya

Autodesk 3ds Max

Exporting Skeletal Meshes from External 3D Modeling Applications

Skeletal meshes can be exported individually or multiple meshes can be exported to a single FBX file. The import pipeline will separate multiple Skeletal Meshes into multiple assets within the destination package.

Select the mesh(es) and joints to be exported in the viewport.



In the File menu choose Export Selection (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the mesh(es) to and set the appropriate options in the FBX Export dialog and then click the button to create the FBX file containing the mesh(es).



Select the mesh(es) and bones to be exported in the viewport.



In the File menu, choose Export Selected (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the mesh(es) to and click the button.



Set the appropriate options in the FBX Export dialog and then click the button to create the FBX file containing the mesh(es).



Importing Skeletal Meshes

In the Content Browser, click the Import button.



Locate and select the FBX file you want to import.





Click Open to begin importing the FBX file you want to import to your project.

Update the appropriate settings in the FBX Import Options dialog.

Default settings should be sufficient when importing a mesh that doesn't share an existing skeleton. Refer to our FBX Import Options Reference for detailed information on all of the settings.





There are two import buttons available to us in the FBX Importer. The first option we have is the Import button, allowing us to import the currently selected FBX file with our specified settings. The second option we have is the Import All button, allowing us to import all of the currently selected FBX files with our specified settings.

For more information on the settings available to us in the FBX Importer, go to the FBX Import Options Reference page.

Clicking Import or Import All adds your meshes to the project.

If the Skeletal Mesh being imported shares an existing skeleton, click the Select Skeleton dropdown menu and select the skeleton asset from the list.



The imported mesh appears inside the Content Browser if the process succeeded.



Verifying Imported Skeletal Meshes

Double-click the imported mesh to view it in Persona.



Verify that the asset imported properly by viewing it in Persona.

Now that we've reached the end of this guide, you've learned:

✓ How to export skeletal meshed from external 3D modeling applications.✓ How to import skeletal meshes into Unreal Editor.✓ How to verify that skeletal meshes were imported properly.

FBX Import Options Reference

FBX Skeletal Mesh Pipeline

Goals

Objectives

Setting-up Skeletal Mesh LODs

Exporting Skeletal Mesh LODs

Importing Skeletal Mesh LODs

Choose your operating system:

Windows

macOS

Linux

We can import Skeletal Mesh Levels of Detail (LOD) into Unreal Engine from external 3D modeling applications, such as 3DS Max, Maya or Blender. Although we're using 3DS Max and Maya to illustrate this lesson's goal, you can import Skeletal Mesh LODs into Unreal Engine from any 3D modeling application with a save feature.

Before getting started: Please make sure you have access to a 3D modeling application.

Goals

The focus of this guide is to show you how to import Skeletal Mesh LODs from external 3D modeling programs.

Objectives

After going through this guide, you'll know:

How to set-up Skeletal Mesh LODs from external 3D modeling applications.

How to export Skeletal Mesh LODs from external 3D modeling applications.

How to import Skeletal Mesh LODs into Unreal Editor from external 3D modeling applications.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

Choose Your 3D Art Tool

Autodesk Maya

Autodesk 3ds Max

Setting-up Skeletal Mesh LODs

Select all of the meshes (base plus LODs) in order from the base LOD down to the last LOD. This is important so that they are added in the correct order in terms of complexity. Then select the Level of Detail > Group command from the Edit menu.



You should now have the meshes all grouped under the LOD Group.



Select all of the meshes (base plus LODs - the order is not important) and then select the Group command from the Group menu.



Enter a name for the new group in the dialog that opens and the click the button to create the group.



Click the button to view the Utilities panel and then choose the Level of Detail utility. Note: You may need to click and select it from the list.



With the group selected, click the button to create a new LOD Set and add the meshes in the selected group to it. The meshes will automatically be ordered according to their complexity.



Setting up LODs for Multi-Part Skeletal Meshes is almost identical to setting up LODs for a full mesh with the exception that each individual part containing LODs will have an LOD group created for it. The process for setting up those LOD groups is identical to the process outlined above.

Exporting Skeletal Mesh LODs

Select the LOD GRoups and the joints to be exported.



Follow the same export steps used for the base mesh (described in the Export Mesh from 3D App section).

Select the group of meshes that comprise the LOD Set and the bones to be exported.



Follow the same export steps used for the base mesh (described in the Export Mesh from 3D App section).

Importing Skeletal Mesh LODs

Skeletal Mesh LODs can be imported through the Mesh Details panel in Persona under LOD Settings.

Persona is the animation editing toolset within UE4. Refer to the Animation Editors for additional information.

To apply an LOD to a skeletal mesh, double-click the animation asset from the Content Browser to open Persona (example sequence pictured below).



In the Mesh Details panel, scroll down to find the LOD Settings section and click the LOD Import option.



In the file browser, locate and select the FBX file you want to import.





The imported LOD is now added to the Mesh Details panel.



Under each LOD, the Display Factor setting indicates when to use the LOD. In the example pictured below, LOD0 is used when your position is closer to the Skeletal Mesh, whereas LOD1 is used when your position is further away from the Skeletal Mesh.



Using a small Display Factor tells Unreal Engine to use the LOD when your position is further away from the Skeletal Mesh. Larger Display Factors tell Unreal Engine to use the LOD when your position is closer to the Skeletal Mesh.

Now that we've reached the end of this tutorial, you've learned:

✓ How to set-up Skeletal Mesh LODs from external 3D modeling applications.✓ How to export Skeletal Mesh LODs from external 3D modeling applications.✓ How to import Skeletal Mesh LODs into Unreal Editor from external 3D modeling applications.

General Setup

Pivot Point

Triangulation

UV Texture Coordinates

Creating Normal Maps

Materials

Collision

Sockets

Vertex Colors

Export Mesh

Import Mesh

Static Mesh LODs

LOD Setup

Import LODs

Create LODs for Imported Static Meshes

The StaticMesh support in the FBX import pipeline makes getting meshes from 3D applications into Unreal Engine 5 a simple, painless task. When meshes are imported, the textures used in the materials applied to those meshes in their respective 3D application (diffuse and normal map only) are also imported and, in turn, used to generate the materials applied to the mesh in UE5.

Features supported for importing Static Meshes using FBX:

Static Meshes with materials including textures

Custom collision

Multiple UV sets

Smoothing groups

Vertex colors

LODs

Multiple separate Static Meshes (can also be combined into a single mesh at import)

Currently, when importing multiple meshes with custom collision in a single file, only the first mesh's collision will be imported.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

General Setup

In general, you are free to create Static Meshes using any tools and methods you want. There are some stipulations as far as setting up UVs, placement of the mesh, etc. that you need to account for in order for the exporting and importing to go smoothly and for the mesh to work properly in Unreal Editor.

Pivot Point

The pivot point of the mesh in Unreal Engine determines the point around which any transformations (translation, rotation, scale) will be performed.



Click image for full size.

The pivot point is always located at the origin (0,0,0) when exporting from a 3D modeling application. Because of this, it is best to create your meshes at the origin, with the origin generally being located at one corner of the mesh to allow for proper alignment when snapping to the grid inside of Unreal Editor.



Click image for full size.

Triangulation

Meshes in Unreal Engine must be triangulated as the graphics hardware only deals with triangles.



Click image for full size.

There are several ways you can ensure your mesh is triangulated.

Model the mesh with only tris - best solution, provides the most control over the end result.

Triangulate the mesh in the 3D app - good solution, allows cleanup and modification before export.

Allow the FBX exporter to triangulate the mesh - okay solution, allows no cleanup but can work for simple meshes.

Allow the importer to triangulate the mesh - okay solution, allows no cleanup but can work for simple meshes.

It will always be best to manually triangulate the mesh in the 3D application, controlling the direction and placement of edges. Automatic triangulation can lead to undesirable results.



Click image for full size.

UV Texture Coordinates

The import of multiple UV sets is supported by the FBX pipeline in Unreal Engine 5. For Static Meshes, this is generally used to handle one set of UVs for the diffuse. There are no special requirements for setting up the UVs for Static Meshes using the FBX pipeline.

Creating Normal Maps

Normal maps can be created for your meshes directly inside of most modeling applications by creating both a low-res render mesh and a high-res detail mesh.



Click image for full size.

The geometry of the high-res detail mesh is used to generate the normals for the normal map. Epic uses a workflow internally that introduces XNormal into the process and generally results in much better normals when rendering inside of Unreal Engine 5. For details on this process, see the Textures.

Materials

The materials applied to meshes modeled in external applications will be exported along with the mesh and then imported into Unreal. This streamlines the process as textures do not need to be imported separately in Unreal, materials do not need to be created and applied, etc. The import process is capable of performing all of these actions when using the FBX pipeline.

These materials also need to be set up in a specific way, especially when the mesh has multiple materials or the order of the materials on the mesh is important (i.e. for character models where material 0 needs to be the body and material 1 needs to be the head).

For complete details of setting up materials for export, see the FBX Material Pipeline page.

Collision

Simplified collision geometry is important for optimizing collision detection in-game. Unreal Engine 5 provides basic tools for creating collision geometry within the Static Mesh Editor. Some circumstances, though, are best handled by creating custom collision geometry within your 3D modeling application and exporting it with the render mesh. Generally, this is true for any mesh with an opening or concave area that objects need to not collide with.

For instance:

Doorway meshes

Walls with window cutouts

Oddly shaped meshes

Collision meshes are identified by the importer based on their name. The collision naming syntax should be:

Mesh Prefix and Name

Description

UBX_[RenderMeshName]_##

A Box must be created using a regular rectangular 3D object. You cannot move the vertices around or deform it in any way to make it something other than a rectangular prism, or else it will not work.

UCP_[RenderMeshName]_##

A Capsule must be a cylindrical object capped with hemispheres. It does not need to have many segments (8 is a good number) at all because it is converted into a true capsule for collision. Like boxes, you should not move the individual vertices around.

USP_[RenderMeshName]_##

A Sphere does not need to have many segments (8 is a good number) at all because it is converted into a true sphere for collision. Like boxes, you should not move the individual vertices around.

UCX_[RenderMeshName]_##

A Convex object can be any completely closed convex 3D shape. For example, a box can also be a convex object. The diagram below illustrates what is convex and what is not:



RenderMeshName must be identical to the name of the render mesh the collision mesh is associated with in the 3D application. So if you have a render mesh named Tree_01 in your 3D application, your collision mesh should be in the scene with that mesh and named UCX_Tree_01, and then exported along with the render mesh to the same FBX file. If you need more than one collision object for a mesh, you can extend their names with further identifiers, such as: UCX_Tree_01_00, UCX_Tree_01_01, UCX_Tree_01_02, etc... and they all will be associated as collision for that mesh.

Currently, spheres are only used for rigid-body collision and Unreal's zero-extent traces (e.g. weapons), not non-zero extent traces (e.g. Player movement). Also, spheres and boxes do not work if the StaticMesh is non-uniformly scaled. In general you probably want to create UCX primitives.

Once your collision objects are set up, you can export both the render and collision mesh in the same .FBX file. When you import the .FBX file into Unreal Editor, it will find the collision mesh, remove it from the render mesh, and turn it into the collision model.

Breaking up a non-convex mesh into convex primitives is a complex operation, and can give unpredictable results. Another approach is to break the collision model into convex pieces yourself in Max or Maya.

In the case of an object whose collision is defined by multiple convex hulls, results are best when the hulls do not intersect with one another. For example, if the collision for a lollipop were defined by two convex hulls, one for the candy and one for the stick, a gap should be left between the two as in the following illustration:



Click image for full size.

UCX_Candy

Small gap between collision surfaces

UCX_Stick

Sockets

Sockets are commonly used in games to attach an object to another object, whether this be for a Skeletal or Static mesh. Unreal Engine 4 provides tools for creating sockets inside the Static Mesh Editor. Sometimes it may be necessary to set these up within your 3D modeling application and export it with your render mesh. These sockets can be Translated, Rotated, and scaled relative to the bone on a Skeletal mesh or or the size of the Static Mesh.

To use a socket in your modeling application you will need to use a Dummy or Helper object with the SOCKET_ Prefix.

Mesh Prefix and Name

Description

SOCKET_[RenderMeshName]_##

Use this on any Dummy or Helper objects in your modeling application to assign a socket to your mesh.

RenderMeshName must be identical to the name of the render mesh the socket object is associated with in the 3D application. So if you have a render mesh named Object_01 in your 3D application, your socket object should be in the scene with that mesh and named SOCKET_Object_01, and then exported along with the render mesh to the same FBX file. If you need more than one socket object for a mesh, you can extend their names with further identifiers, such as: SOCKET_Object_01_00, SOCKET_Object_01_01, SOCKET_Object_01_02, etc... and they all will be associated as sockets for that mesh.

When creating sockets for your mesh, you can only have a single mesh FBX setup with sockets that can be imported into Unreal Engine 5. For instance, if you have two render meshes that you want to be separate assets will need to be imported as separate FBX files. This means that you cannot import multiple meshes and assign the sockets to each separate mesh, and that if you have two sets of render meshes with their own sockets they will not import correctly. As an example, if I have Object_01 with SOCKET_Object_01_00, and another render mesh Box_01 with SOCKET_Box_01_00 I cannot export both of these meshes with their sockets together. They would need to be exported as separate FBX files.

Vertex Colors

Vertex colors for Static Meshes can be transferred using the FBX pipeline. No special setup is necessary



Click image for full size.

Export Mesh

Static Meshes can be exported individually or multiple meshes can be exported to a single FBX file. The import pipeline will separate multiple Static Meshes into multiple assets within the destination package unless specified to combine the meshes by enabling the Combine Meshes setting at the time of import. Refer to the documentation for exporting FBX files for your 3rd party DCC tool of choice, remembering to adhere to the guidelines presented earlier for the creation of your meshes.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

Import Mesh

Click the Add/Import button in the Content Browser and choose Import. Navigate to and select the FBX file you want to import in the file browser that opens.

You may want to select in the dropdown to filter out unwanted files.



Click image for full size.

The path of the imported asset depends on the current location within the Content Browser. Make sure to navigate to the appropriate folder prior to performing the import. You may also drag the imported assets into a new folder once import is complete.

Choose the appropriate settings in the Import dialog. The defaults should be sufficient in most cases. See the FBX Import Dialog section for complete details of all of the settings.



Click image for full size.

Click the Import button to import the mesh(es). The resulting mesh, material(s), and texture(s) will be displayed in the Content Browser if the process was successful.



Click image for full size.

Although textures and materials can be imported with a Static Mesh, only Color and Normal will automatically be connected (assuming a supported material was used), Specular maps will be imported but not connected, other maps, for example an Ambient Occlusion map in the Diffuse slot of a Maya material, will not even be imported; it is best to check your materials and connect any unconnected maps and check which maps did not import. Simply double-click the new material and connect the available textures with their appropriate inputs.

By viewing the imported mesh in the Static Mesh Editor and enabling the display of collision, you can determine that the process worked as expected.



Click image for full size.

Alternatively, you can actually just click and drag an FBX file from Windows into the Content Browser and it will bring up the import dialog for you.

Static Mesh LODs

Static Meshes can make use of levels of detail (LODs) in-game in order to limit the impact of meshes as they get farther from the camera. Generally, this means each level of detail will have a reduced number of tris and, perhaps, a simpler material (or materials) applied to it.



Click image for full size.

The FBX pipeline can be used to import LOD meshes created using DCC tools, or LODs can be created for imported static meshes directly inside UE.

LOD Setup

In general, LODs are handled by creating models of varying complexity going from the full-detail base mesh to the lowest-detail LOD mesh. These should all be aligned and occupying the same space with the same pivot point. Each LOD mesh can have completely different materials assigned, including different amounts of materials. This means the base mesh could use multiple materials to give the desired amount of detail up close, but the lower-detail meshes could use a single material since details will be less noticeable.

Each DCC tool will have its own workflow for creating LODs for static meshes, so refer to the documentation for your tool of choice for specifics about how to create and include them in your FBX exports.

Import LODs

Static Mesh LODs can be imported along with the base mesh in the Content Browser or they can be imported individually through the Static Mesh Editor.

Click the Add/Import button in the Content Browser and choose Import. Navigate to and select the FBX file you want to import in the file browser that opens.

You may want to select in the dropdown to filter out unwanted files.

The path of the imported asset depends on the current location within the Content Browser. Make sure to navigate to the appropriate folder prior to performing the import. You may also drag the imported assets into a new folder once import is complete.

Choose the appropriate settings in the Import dialog. The defaults should be sufficient, but also make sure that Import LODs is enabled. Note: When importing LODs, the name of the imported mesh will follow the default naming rules. See the FBX Import Dialog section for complete details of all of the settings.



Click image for full size.

Click the Import button to import the mesh and LODs. The resulting mesh, material(s), and texture(s) will be displayed in the Content Browser if the process was successful.



Click image for full size.

Although textures and materials can be imported with a Static Mesh, only Color and Normal will automatically be connected (assuming a supported material was used), Specular maps will be imported but not connected, other maps, for example an Ambient Occlusion map in the Diffuse slot of a Maya material, will not even be imported; it is best to check your materials and connect any unconnected maps and check which maps did not import. Simply double-click the new material and connect the available textures into their appropriate inputs.

By viewing the imported mesh in the Static Mesh Editor, you can cycle through the LODs using the LOD Picker in the Details panel.



Click image for full size.

Create LODs for Imported Static Meshes

Once a static mesh has been imported, you can either create LODs for it manually, which is longer but will get the best results, especially for complex meshes, or you can use UE's LOD autogeneration tool, which is faster for when you need to generate LODs for multiple simple meshes.

FBX Import Options Reference

FBX Static Mesh Pipeline

Goals

Objectives

Importing Static Meshes from External 3D Modeling Applications

Verifying Imported Static Meshes

Choose your operating system:

Windows

macOS

Linux

We can import static meshes into Unreal Engine from external 3D modeling applications, such as 3DS Max, Maya or Blender. Although we're using 3DS Max and Maya to illustrate this lesson's goal, you can import static meshes into Unreal Engine from any 3D modeling application with a save feature.

Before getting started: Please make sure you have access to a 3D modeling application.

Goals

The focus of this guide is to show you how to import static meshes from external 3D modeling applications.

Objectives

After going through this guide, you'll know:

How to import static meshes into Unreal Editor from external 3D modeling applications.

How to verify that static meshes were imported properly.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

Choose Your 3D Art Tool

Autodesk Maya

Autodesk 3ds Max

Importing Static Meshes from External 3D Modeling Applications

Select the mesh(es) and joints to be exported in the viewport.



In the File menu choose Export Selection (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the mesh(es) to and set the appropriate options in the FBX Export dialog and then click the button to create the FBX file containing the mesh(es).



Select the mesh(es) and bones to be exported in the viewport.



In the File menu, choose Export Selected (or Export All if you want to export everything in the scene regardless of selection).



Choose the location and name for the FBX file to export the mesh(es) to and click the button.



Set the appropriate options in the FBX Export dialog and then click the button to create the FBX file containing the mesh(es).



Verifying Imported Static Meshes

Double-click the imported mesh to view it in the Static Mesh Editor.



Click image for full size.



Click image for full size.

Verify that the asset imported properly by viewing the imported mesh in the Static Mesh Editor.

Now that we've reached the end of this guide, you've learned:

✓ How to import static meshes into Unreal Editor from external 3D modeling applications.✓ How to verify that static meshes were imported properly.

FBX Import Options Reference

FBX Static Mesh Pipeline

Setting-up Static Mesh LODs

Exporting Static Mesh LODs

Importing Static Mesh LODs

You can import Static Mesh Levels of Detail (LOD) into Unreal Engine from external 3D modeling applications, such as 3DS Max, Maya, or Blender. Although 3DS Max and Maya are used to illustrate this lesson's goal, you can import Static Mesh LODs into Unreal Engine from any 3D modeling application with a save feature.

Prerequisites

You have access to a 3D modeling application.

You have a model with LODs created.

Objectives

After going through this guide, you'll know:

How to set up Static Mesh LODs from external 3D modeling applications.

How to export Static Mesh LODs from external 3D modeling applications.

How to import Static Mesh LODs into Unreal Editor from external 3D modeling applications.

The Unreal Engine FBX import pipeline uses FBX 2020.2. Using a different version during export may result in incompatibilities.

Choose Your 3D Art Tool

Autodesk Maya

Autodesk 3ds Max

Setting-up Static Mesh LODs

Select all meshes, from the base LOD down to the last LOD. The selection order is essential for ensuring the LODs are added in the correct order of complexity. Then select the Level of Detail > Group command from the Edit menu.



Click image for full size.

All meshes are now grouped under the LOD Group.



Click image for full size.

Select all of the LOD meshes (the order is not important) and then select the Group command from the Group menu.



Click image for full size.

Enter a name for the new group in the dialog that opens and the click the button to create the group.



Click image for full size.

Click the button to view the Utilities panel and then choose the Level of Detail utility. Note: You may need to click and select it from the list.



Click image for full size.

With the group selected, click the button to create a new LOD Set and add the meshes in the selected group to it. The meshes are automatically ordered according to their complexity.



Click image for full size.

Exporting Static Mesh LODs

In Maya, select the LOD Group and any collision geometry.



Click image for full size.

Go to the file menu and select Export Selection.



Click image for full size.

Choose the path where you want to save your mesh. Make sure to give it a name, choose FBX as the file format, and enable the export of animations in the FBX exporter properties. Enabling animation is required for LODs to be exported.



Click image for full size.

In 3ds Max select the Group of meshes that comprise the LOD Set and any collision geometry.



Click image for full size.

Go to the file menu and select Export > Export Selected.



Click image for full size.

Choose the path where you want to save your mesh. Make sure to give it a name, choose FBX as the file format, and then save.



Click image for full size.

In the FBX Export window enable animation under the Animation properties. This is required for LODs to be exported.



Click image for full size.

Importing Static Mesh LODs

Importing Static Mesh LODs is done a few ways. One option uses the Content Browser, as shown below, and the other is from within the Details panel in the Static Mesh Editor. To learn how to import LOD from the Static Mesh Editor, refer to the Creating and Using LODs documentation.

In the Content Browser, click the Import button.



Click image for full size.

Locate and select the FBX file you want to import.



Click image for full size.

Click Open to begin importing the mesh file to your project.

In the FBX Import Options dialog box, choose the appropriate settings, making sure the Import LODs option, under Mesh > Advanced, is enabled.



Click image for full size.

There are two import buttons available to us in the FBX Importer. The first option is the Import button, making it possible to import the currently selected FBX file with your specified settings. The second option is the Import All button; this imports all of the currently selected FBX files with our specified settings.

For more information on the settings in the FBX Importer, refer to the FBX Import Options Reference documentation.

Click Import or Import All to import the mesh to your project.



Click image for full size.

When importing LODs, the name of the imported mesh will follow default Naming Conventions. Refer to our FBX Import Dialog documentation for additional information about all of the settings.

Your imported mesh will show in the Content Browser, along with any Textures and Materials applied.



Click image for full size.

Double-click the Static Mesh to open the Static Mesh Editor. By viewing the imported mesh in the Static Mesh Editor, you can cycle through its LODs using the Auto LOD dropdown.



Now that you have reached the end of this guide, you've learned:

✓ How to set up Static Mesh LODs from external 3D modeling applications.✓ How to export Static Mesh LODs from external 3D modeling applications.✓ How to import Static Mesh LODs into Unreal Editor from external 3D modeling applications.

Generic

Mesh

StaticMesh

SkeletalMesh

Animation

This is a list of error or warning messages you may encounter during importing FBX files.

Generic

Importing failed to create new asset. In this case, you are likely to have other warning messages that indicate the cause of the failures.

Loading FBX Scene has failed. Either the file is corrupted or it is not the correct file type.

An asset already exists with the given name. Make sure to use a different name to import or import into a different folder.

Currently importing asset is going to replace currently existing asset of the same name.

When overriding existing assets, the importer needs to delete the old asset first, however the importer cannot delete it because of references.

Try using a different name or importing into a different folder.

Opening file and importing has failed. Either the file is corrupted or it is not the correct file type.

No Mesh was found in the file. Make sure the FBX contains a mesh object.

Mesh

Mesh object does not contain geometry.

Mesh is composed of polygons other than triangles, so the importer attempted to triangulate, but failed. Check the source content and triangulate it in your DCC tool.

The importer only supports smoothing on a polygon level, and when smoothing was done by edge, the importer will attempt to convert edge smoothing to polygon smoothing, but that has failed.

(FBX API ComputePolygonSmoothingFromEdgeSmoothing.)

The importer only supports smoothing on a polygon level, and when smoothing was done by vertex, the importer will attempt to convert vertex smoothing to polygon smoothing, but that has failed.

Face Material index is not valid. Either it is mapped to the wrong index or the material is not available. The importer forces the index to 0 when this happens.

FBXMesh object is not found in the node given. Make sure the mesh exists in the scene.

No smoothing group information was found in this FBX scene. Please make sure to enable the "Export Smoothing Groups" option in the FBX Exporter plug-in before exporting the file.

Even for tools that do not support smoothing groups, the FBX Exporter will generate appropriate smoothing data at export-time so that correct vertex normals can be inferred while importing.

Invalid Mesh LOD index. In order to add LOD(N), the current mesh should contain all of LOD from [0-(N-1)].

You should select a file for the LOD. No file was selected.

You may only select one file for the LOD.

StaticMesh

Currently the importer supports up to MAX_MESH_MATERIAL_INDEX(64) materials. Break your mesh into multiple pieces to fix this.

The light map UV set for Static Mesh appears to have layout problems. Either the triangle UVs are overlapping one another or the UVs are out of bounds (0.0 - 1.0 range.)

SkeletalMesh

This error is thrown when importing an LOD (or importing a Skeletal Mesh with LODs) and the requested mesh for the LOD does not have the same root bone as the original mesh. They should have same root bone.

The importer cannot have bones with the same name in the Skeletal Mesh hierarchy. Make sure each bone name is unique.

The importer did not find any vertices weighted to the skeleton. Skeletal Meshes are required to have at least one vertex weighted to the skeleton.

While restoring the sort order for the section, strips could not be matched to the new data.

Unable to restore triangle sort setting for the section number in the old mesh, as a matching section could not be found in the new mesh. The custom sorting information has been lost.

Unable to restore triangle sort setting for the section as the new mesh does not contain that many sections. Please find the matching section and apply manually.

Could not find any valid mesh on the root hierarchy. If you have mesh in the sub hierarchy, please enable option of [Import Meshes In Bone Hierarchy] when importing.

Could not find a valid root node.

Could not find any valid Nodes.

Ignoring this deformer because it did not find any the weighting information.

Scene does not contain a Bind Pose. Make sure you have a Bind Pose in the scene. If you do not, import with [Use Time 0 as Reference Pose] enabled.

No cluster is found.

Could not find any bone nodes. If it is rigid, please use the [Import Rigid Body] option.

Could not find any valid bind poses. A bind pose can exist but be invalid. Often this can be fixed by recreating bind pose in the DCC tool.

Found multiple roots. The importer only supports one root per mesh.

Some bones are missing from the bind pose data. If you would like to avoid this, you can import with [Use Time 0 as Reference Pose] enabled or fix the bind pose in your DCC tool.

There are vertices in the Skeletal Mesh that are not weighted to a bone. These vertices will be fully weighted to the root bone.

Input mesh has a section with no triangles. This mesh may not render properly.

Input mesh has too many vertices. The generated mesh will be corrupt!

Consider adding extra materials to split up the source mesh into smaller chunks.

If you have [Create Physics Asset] on, it will try to create physics asset.

It can fail if:

The importer failed to create the Skeletal Mesh (and thusly has no bones to build the Physics Asset)

The mesh is too small and the Physics Asset creation default setting will not work with it.

If this fails, you can create physics asset after imported.

Bring up the Right-Click Context menu on the Skeletal Mesh -> Create... -> Create Physics Asset. You can then adjust the settings for creating a Physics Asset to work with the size of your Skeletal Mesh.

The importer is trying to recreate skeleton, but it failed because an asset exists with the same name, but it is of a different type of asset (eg: Static Mesh). Try to import in a different folder or with a different name.

Your Skeletal Mesh has too many bones, Unreal Engine's current max bone count is 65536.

Skeletal Mesh does not have any UVSets. Creating a default set.

New mesh is missing bones that are required by the LOD(s). Make sure these bones exist in the new mesh.

Failed to import LOD. Please check other warning/error messages that came up.

Root bone name in the LOD does not match with original mesh root bone name. Make sure both root bone names match.

New mesh for LOD bones should exist in the original mesh. If it has extra bones, the importer cannot match.

New mesh for LOD bone hierarchy should match with the original bone hierarchy. The parent does not match for the specified bone.

The mesh LOD you are importing has some vertices with more than one influence. If you would like to have soft vertex deformation, please set CheckSingleInfluenceLOD to False in the Editor INI file.

The mesh LOD is missing a bone that is required by a socket. This can cause game play artifacts when the Actor switches to the LOD.

Could not find morphtarget for the LOD.

Animation

Mesh contains the root bone in the description, but animation does not contain that bone track. The animation data should contain at least root bone track.

Make sure if this animation FBX is supposed to be for the given skeleton.

Make sure the original mesh contains same bone hierarchy as the animation.

Failed to build skeleton to create animation track.

Could not find an animation track.

Animation track length is zero. You can try different options of time options.

Exported Time: Find scene's local start and end time

Animated Time: Find root's animated time

Set Range: Set range of the frame

Root bone of animation does not match with the root bone of the skeleton it is importing for. Is the animation file intended for this skeleton?

Animation contains duplicated bones.

Animation contains bones that are not found in skeleton.

Animation does not contain any valid animation tracks, takes, or blendshapes.

This can be caused by using shearing or other forms of transforms the importer does not support. Or this can possibly happen due to a math error. If the animation looks fine in Persona, you can ignore this warning.

Getting Started

Overview and Reference Topics

The Unreal Engine's Hair rendering and simulation system uses a strand-based workflow to render each individual strand of hair with physically accurate motion. It enables artists to simulate and render hundreds of thousands (or more) photoreal hairs in real-time for grooms created in DCC packages.

Getting Started



An overview of strand-based hair import, rendering, and simulation in Unreal Engine.



Describes guidelines for exporting grooms as Alembic files for use with Unreal Engine.



A guide to getting started using hair rendering and simulation with characters in your project.

Overview and Reference Topics



Describes guidelines for exporting Grooms as Alembic files for use with Unreal Engine.



An overview of using imported Groom Caches with Hair Grooms.



A list of all settings and properties relevant to hair rendering and simulation with Groom Assets.



A reference for creating follicle mask and strands textures from Groom Assets.

The Hair Rendering and Simulation features are intended to provide a minimally viable implementation of strand-based hair importing, rendering, and simulation. This update does not provide a hair grooming solution. Hair shaping, or grooming, will need to be performed in an external DCC tool such as Maya by using their XGen tool or the plugin Shave and a Haircut. Other tools like Ornatrix, Yeti, or Houdini can be used as well.

Goals

Curves

Width

Naming Conventions

Scoping and Precedence

General Properties

Geometry Parameters

This document outlines an informal schema for Alembic files in an attempt to standardize the import of hair groom and guide hair information into Unreal Engine for use with the Hair Rendering and Simulation features. The intent is that as you generate Hair Grooms, conforming to this schema allows Unreal Engine to import those grooms directly. Upon import, attributes that are supported by UE4 for both rendering and physics will be mapped to those attributes in the Alembic file.

Goals

Define a groom-specific, informal, Alembic metadata schema to facilitate importing of hair into Unreal Engine.

Examine the attributes that are supported by Unreal Engine for hair, and map those attributes onto Alembic.

Curves

The general shape of the hair is read from the standard Alembic Curve schema:

Width

Groom attributes exported using this specification enables the importer to retrieve and use them when building the groom. However, the width attribute does have a special behavior. For example, in a DCC application like Maya, width values are exported directly on the curves so there's no need to export a custom groom_width attribute; the importer will convert Maya's width values into the groom_width attribute. It is worth noting that if the groom_width attribute is present in your groom, it will not be overwritten during import. If no groom_width attribute is specified, or one couldn't be converted from width values, the builder in Unreal Engine falls back to using a value of 1 centimeter for the width value.

The curve width can be stored per-ICurve using:

Or it can be stored per-curve using:

Or it can be stored per-cv using:

Note that the importer supports kUniformScope, but this has not been tested.

Naming Conventions

Property names must be lowercase with no spaces or special characters.

All properties must start with the following prefix:

For example, groom_id, groom_color, or groom_width are all using the proper naming conventions.

Scoping and Precedence

Properties in this document have an assigned scope. The scope controls at which level the groom property can be defined.

The available scopes are:

Scope

Description

Constant

These parameters have a single value for all curves with an AbcGeom::ICurves Object.

Uniform

These parameters have a value per-curve in an AbcGeom::ICurves Object.

Vertex

These parameters have a value per-curve per-cv.

General Properties

This section outlines properties that apply to the groom as a whole. These properties should be added to the topmost node: IXForm or ICurves.

Name

Type

Optional

Description

Value

groom_version_major

int16

No

Used to identify which major version of the groom schema this file conforms to.

1

groom_version_minor

int16

No

Used to Identify which minor version of the schema this file conforms to.

5

groom_tool

string

Yes

The name and version of the tool that generated this file. Useful for debugging and tracking down issues.

groom_properties

string

Yes

String describing the parameters used to generate this groom. These are tool-specific options, used for debugging.

Geometry Parameters

All geometry parameters are optional but have internal behavior to fall back on if they are not present with your exported groom.

Name

Type

Scope

Optional

Description

Range

groom_ guide

int8/16/32

Constant/Uniform

Yes

Guides are generated from the imported strands and decimation settings.

0 = Not a guide / 1 = Guide

groom_group_id

int32

Constant/Uniform

Yes

All strands will be grouped together.

[0, INT_MAX]

groom_root_uv

float32/64[2]

Uniform

Yes

Root UVs are computed by projecting the root of the strand onto a sphere.

This attribute is optional. If not specified, a root UV is automatically generated in the engine using a spherical mapping.



[-FLOAT_MAX, FLOAT_MAX]

groom_id

int32

Uniform

Yes

Strands won't have IDs. This is intended for use in debugging and with groom_closest_guides attribute.

[0, INT_MAX]

groom_color

float32/64[3]

Vertex

Yes

Falls back to black.

[0, FLOAT_MAX]

groom_closest_guides

int32[3]

Uniform

Yes

Intended for specialized use where the interpolation data is computed outside of Unreal Engine.

[0, INT_MAX]

groom_guide_weights

float32[3]

Uniform

Yes

Intended for specialized use where the interpolation data is computed outside of Unreal Engine.

[0, FLOAT_MAX]

Types of Groom Caches

Importing a Groom Cache into Unreal Engine

Using a Groom Cache in Unreal Engine

Using a Groom Cache in a Level Sequence

A Groom Cache is an extension of a Groom Asset that allows playback of groom animations that are simulated in other digital content creation (DCC) applications and exported to Unreal Engine using Alembic. A Groom Cache Alembic is a Groom Alembic which contains time samples that animate some attributes. The supported attributes that can be animated are vertex position, width, and color.

Types of Groom Caches

There are two types of Groom Cache Alembic files that can be imported into Unreal Engine: Guides Groom Caches and Strands Groom Caches

A Guides Groom Cache supports only vertex position animation of the guides. It uses the in-engine strands interpolation to transfer the guides animation to the render strands, requiring that the Groom Asset enable simulation on each of the groom groups. It is suitable for playing back a groom animation that animates only the vertex position where the in-engine interpolation gives satisfactory results. This type of groom cache is more lightweight and performant than using a Strands Groom Cache.

A Strands Groom Cache contains the animated attributes for every strand, causing it to consume more memory and bandwidth than a Guides Groom Cache. The benefit is more flexibility because it supports width and color in addition to vertex position, and is higher fidelity since it contains the exact simulation that was computed in the DCC application. This type of groom cache does not use the in-engine interpolation, and does not require enabling simulation on the Groom Asset. A current limitation of a Strands Groom Cache is it must contain vertex position animation, it cannot have just width and color animation by itself.

Strands Groom Caches are useful for playing back groom animations that cannot be simulated in-engine, or where simulation or interpolation does not give satisfactory results. For example, having an animation that shows hair growth where the hair grows longer and thicker.

Keep in mind that for a Groom Cache to work with a Groom Asset, they must have the same topology, such as the same number of strands, vertices, vertex per strand, and so on. For hair instances where you want to do hair shortening, the number of vertices globally and per-strand must not change, instead it is their position that must change to animate the strand length.

Importing a Groom Cache into Unreal Engine

Since a Groom Cache is a Groom with a time sample, the Groom Cache Alembic is detected as a regular Groom during import. However, the Groom Import Options will show a Groom Cache section with Import Groom Cache enabled.



Import Groom Cache can be disabled to import only the Groom Asset. It is not possible to import a guides-only Groom Asset nor a guides-only Groom Cache.

With a strands-only groom, the guides are automatically generated at import with the interpolation settings, and those settings are used to generate the guides for a Guides Groom Cache. If the guides are already included in the Alembic, they are used instead for both the Groom Asset and the Groom Caches unless the Groom Import Option Override Guides is enabled, which is found under the Groups > Index [n] > Interpolation Settings.



In cases where you already have a Groom Asset that is topologically compatible with the Groom Cache being imported, you can disable Import Groom Asset and specify that Groom Asset to use.



The import process applies the import settings of the specified Groom Asset to the Groom Cache you are importing. This is especially important with the decimation and interpolation settings to ensure that the Groom Asset and Groom Caches have the same imported topologies.



When Import Groom Asset is disabled, you cannot import the Groom Cache until a Groom Asset is specified.

The other settings in the Groom Cache section are there to control the imported animation range, such as specifying a starting and ending frame to use, and skipping any empty frames that may be at the start of the Groom animation.



Using a Groom Cache in Unreal Engine

After you import a Groom Cache, it can be applied to a Groom Cache assignment slot of a Groom Component.



Groom Caches must be used in conjunction with a topologically compatible Groom Asset, since they do not contain the render data or resources to render the strands of the groom.

You can't assign a Groom Cache (2) to a Groom Component if it already has a Groom Binding (1) assigned, the Groom Cache assignment slot will be grayed out.



For Guides Groom Caches, the Groom Asset must enable simulation for each Groom Group for the Groom Animation to be visualized while using Play-in-Editor (PIE).

Using a Groom Cache in a Level Sequence

A Groom Cache can be used and controlled from a Level Sequence by adding a Groom Cache track on the Actor with a Groom Component.



If the Groom Component already has a Groom Cache applied to it, the Groom Cache section on the track automatically sizes to fit the animation range. Otherwise, you have to size it manually.



Enabling Hair in your Project

Project Setting

Plugins Browser

Basic Workflow

Groom Asset

Generating Strands Textures

Setting up a Hair Material

Binding Asset

Enabling Physics Simulation

Debugging Hair

Known Limitations

HairWorks Users

Traditionally, hair that has been created for use in real-time engines has been created using card-based techniques, or other similar approximation. Card based workflows use a large number of flat sheets (or cards) to give the approximate shape, and motion, of a much larger number of individual hairs. Using the Groom system and tools of Unreal Engine enables you to render each individual strand of hair, which significantly improves visual fidelity of simulated hair in real time.

While no standard format currently exists for hair grooms, the groom system provides a naming convention-based scheme using Alembic (.abc) files to ingest data exported from your modeling application. It provides support for multiple hair groupings within a single file, such as head, vellus, beard, eye lashes, and brows, a hair shader and rendering system, and dynamic physics integration driven by Niagara.

The groom system provides a minimal viable implementation of strand-based hair importing, editor, rendering, and simulation. The system does not provide a hair grooming solution. Hair shaping, or grooming, needs to be performed in your external modeling application, such as XGen within Maya, Ornatrix, Yeti, Shave and a Haircut, or Houdini.

Enabling Hair in your Project

Enable the following plugins and settings to get started using Hair Grooms in your project.

An Editor restart is required for each of these to take effect.

Project Setting

Open the Project Settings by going to Edit > Project Settings. Under Rendering > Optimizations, enable the Support Compute Skin Cache option.



Plugins Browser

Open the Plugins browser window by going to Edit > Plugins. Under the Geometry category, enable these plugins:



Alembic Groom Importer

Groom

Basic Workflow

The flowchart below describes the high-level process of bringing your own Hair Grooms into Unreal Engine and attaching them to a Skeletal Mesh character that can be animated.



Create your Hair Groom in your preferred DCC application.

Export your Hair Groom as an Alembic (*.abc) file.

Import your Alembic Groom file into Unreal Engine.

(Optional) Create a Binding Asset from the Content Browser for your Skeletal Mesh.

Place your Groom Asset in the World (as an Actor or in a Blueprint).

Attach the Groom Component (Actor) to Skeletal Mesh Socket with Transfer Skinning.

Setup and Assign your Hair Material

Once these steps are completed, you will have an interactive groom that can be used on an attached Skeletal Mesh that is animating.

Follow along with the Hair Rendering and Simulation Quick Start guide to perform all these steps in more detail.

For additional details on setting up your Hair Groom for export and import into Unreal Engine, see the Alembic for Grooms Specification reference page that covers the schema that will enable Unreal Engine to import grooms directly.

Groom Asset

Groom Assets represent your imported Alembic (.abc) file's hair groom and they are stored in your Content Browser. Double-clicking the Groom Asset opens the Groom Asset Editor.



Click image for full size.

With the Groom Asset Editor you can manage and edit parts of your groom. You'll be able to:

Assign Materials

Create Levels of Detail Meshes that represent strands, cards, or a mesh

Enable and configure physics settings

Debug your groom with different view modes

Right-clicking the Groom Asset in the Content Browser provides several additional Groom Actions that enable you to:



Rebuild the selected groom's build settings from the Groom Import Options.

Create Binding to generate a Binding Asset used to attach a groom to a Skeletal Mesh.

Create Textures for Follicle and Strands using the selected groom.

For more information, see Groom Asset Editor.

Generating Strands Textures

The Groom Asset enables you to create textures based on the strands data from your imported grooms. You can generate a follicle mask for your skeletal mesh to better blend hair with its mesh surface. You can also create multiple strands textures that can be used to create a hair mesh or hair cards.

Your groom can be used to generate textures which can be applied to meshes.







Depth Texture

Tangent Texture

Hair Mesh with Generated Textures

For more information, see Generating Groom Textures.

Setting up a Hair Material

For Hair geometry to render correctly, it needs a Material assigned whose Shading Model is set to Hair.



You'll also need to have Use with Hair Strands enabled under the Usage category. This should automatically be enabled when applied to a Groom for the first time, but if not, you can enable it manually.

The following is an example Hair Material using the Hair Attributes Expression:



Click image for full size.

Binding Asset

You can use Groom Binding Assets to attach and skin a Groom Component to a Skeletal Mesh Component. It's a way to assign a groom to the Skeletal Mesh it has been authored for and assign it to ones with the same topology.



Click image for full size.

Create a Binding Asset by right-clicking on a Groom Asset in the Content Browser and selecting Create Binding from the context menu. Use the Groom Binding Options window to assign a Target Skeletal Mesh and Source Skeletal Mesh to create the binding.

A Target Skeletal Mesh must be specified to create the Binding Asset. Otherwise, no binding is created during this process.

Enabling Physics Simulation

Enable physics on your groom by opening the Groom Asset Editor and from the Physics panel, check the box next to Enable Simulation under the Solver Settings.



Click image for full size.

Once enabled, you can explore the various physics settings that affect the groom component. See the Hair Properties Reference for details about each property.

Debugging Hair

Use the following console variables for debugging hair in your project:

Console Variable

Description

r.HairStrands.DebugMode

Enable one of the following command modes to draw various stats and debug information about hair rendering to the screen:

0 - Off

1 - Cluster info

2 - All DOMs light bounds

3 - Screen projected clusters

4 - Deep opacity maps

5 - Sub-pixel sample count

6 - TAA resolve type (regular/responsive)

7 - Type of hair coverage

8 - Hair density volume

9 - Hair tangent volume

10 - Hair base color volume

11 - Hair roughness volume

12 - Hair mesh projection

13 - Hair coverage

r.HairStrands.StrandMode

Enable this command to render the selected debug mode for hair strands in the scene:

0 - off

1 - Simulation strands

2 - Rendering strands influence

3 - Roots UV

4 - Roots UV UDIM texture index

5 - Hair UV

6 - Hair seed

7 - Hair dimensions

8 - Hair radius variation

9 - Hair vertices color

10 - Hair vertices roughness

Known Limitations

Frame rate depends on the size of the groom, its resolution, and underlying hardware that it's being run on. For example, you should expect a 30Hz or higher framerate with an RTX-2080Ti for a human-like groom at 1080p. Higher quality settings result in a significant performance drop.

Grooms do not yet support proper precomputed (Static/Stationary) lighting.

Depth of Field is supported but may still produce some artifacts.

HairWorks Users

For those using NVIDIA's hair solution HairWorks, which consists of DCC tool integration and real-time rendering and simulation for hair, Unreal Engine has deprecated HairWorks since version 4.16 of the engine. The long term plan is for the Groom system features to help provide a migration path for those who are currently using the HairWorks integration.

While the last official NVIDIA version of HairWorks made available for UE4 through their GitHub branch is version 4.16, various patches and upgrades have been created and are available online but are not official supported.

1 - Required Setup

2 - Creating and Importing your Groom

3 - Attaching a Groom to a Skeletal Mesh

Setting up the Groom Component

Creating a Binding Asset

4 - Setting Up Your Hair Material

5 - Setting Up Hair Physics

The focus of the Hair Rendering and Simulation guide is to walk you through the basics of working with your hair grooms on skinned meshes in Unreal Engine.

After going through this tutorial, you will know how to:

Set up a project for hair rendering and simulation.

Set up a groom for use with an animated skeletal mesh.

Set up a basic Hair material.

Enable and control physics for hair.

1 - Required Setup

Create a new project using using the Third Person template.

In the editor, go to the Main Menu and select Edit > Project Settings to open the Project Settings window. Under the Rendering > Optimization category, enable the Support Compute Skin Cache option.



You can ignore the Restart Now popup that appears in the bottom right of the editor window since the next steps also require you to restart the editor.

Go to the Main Menu again and this time select Edit > Plugins to open the Plugins browser window.



In the search bar start typing groom and enable the following plugins:

Alembic Groom Importer

Groom

Restart the editor for changes to the Project Settings and Plugins to take effect.



2 - Creating and Importing your Groom

Grooms for a character — even a simple one — can contain different types of hair, such as that for heads, beards, brows, and more. Each of these types of hair could have its own Material and physics settings. There are also types of hair within each group, such as hairs that are to be used during simulation. This information can be defined during grooming in your DCC application, and Unreal Engine looks at this information to define guides.

In your preferred DCC application, create your Groom and then export it to Alembic .abc file format.

Use the Alembic for Grooms Specification to prepare your groom for Unreal Engine with proper naming conventions.

In the Content Drawer, click the Import button to import your Alembic file with your groom, or drag and drop your Alembic file into the Content Browser.



In the Groom Import Options window, consider the following options:



Modify the initial Rotation that is baked into the groom, which avoids some extra runtime cost.

Use the Override Guides check box to replace the imported guides with a set of strands selected from the imported strands. The amount of guides depends on the Hair to Guide Density value.

Use the Interpolation Quality and Interpolation Distance to modify how the pairing between guides and the strands is handled for transferring the guide motion.

The Randomize Guide and Unique Guide checkboxes affect how a guide influences a strand is handled; whether only a single or multiple guides should influence a strand.

Click Import.

During the import process, the Groom system looks for attributes and groups that follow the Alembic naming conventions outlined in the Alembic for Grooms specifications page, and imports them to a new Groom Asset. Among these attributes, the RootUV attribute fetches the UV of the underlying surface, such as a skin surface, which allows for the creation of some spatial variation across the groom.

3 - Attaching a Groom to a Skeletal Mesh

The Groom component enables you to attach a Groom Asset and bind a groom to a Skeletal Mesh's surface. An optional Binding Asset caches the projected data of the groom onto the Skeletal Mesh, which saves GPU costs of doing this at startup when one is not created and assigned.

Setting up the Groom Component

For this part of the guide, we'll use the SKM_Manny found in the Third Person template. If you do not have this, you can add it to your project from the Content Browser by clicking Add New > Add Feature or Content Pack, and selecting the Third Person template.

Also, note that this same setup can be applied inside of a character Blueprint.

In the Content Browser, locate the SKM_Manny Skeletal Mesh found in the Characters > Mannequins > Meshes folder and drag it into the scene.

With the Skeletal Mesh selected, use the Details panel to click the Add Component button and add a Groom Component.

Select the Groom component and use the Groom Asset slot to assign your imported groom to this Skeletal Mesh.

Creating a Binding Asset

In your Content Drawer, locate your Groom Asset. Right-click it and select Create Binding.



The Groom Binding Options window will open. To create the asset, it's required that you assign a Target Skeletal Mesh and you can optionally specify a Source Skeletal Mesh that shares similar topology as the Target Skeletal Mesh. With these slots assigned, click Create.



This will open your Groom Binding Asset. Save it and close the window.



Select the Skeletal Mesh in your level. Use the Details panel to select the Groom Component in the Components panel. Under the Groom section, use the Binding Asset slot to assign the Binding Asset you created.



4 - Setting Up Your Hair Material

By Default, Unreal Engine contains a simple Hair Material with HairDefaultMaterial.

The steps below are optional for this guide since Unreal Engine includes a default hair material. However, if you've not set one up before, the steps below will guide you through the properties and setting required to do so.

In the Content Drawer, click the Add button and select Material.



Give your Material Asset a name and open it.

In the Material Editor, use the Details panel to set the following:



Shading Model: Hair

You also need to enable Use with Hair Strands. When the material is applied to a groom component, this checkbox should automatically enable itself and recompile the material. If it doesn't, you can enable it from the Usage category of the Details panel in the Material Editor.

In the Material Graph, use the following node setup for a basic hair material:



Use a Constant4Vector for the Base Color and a Constant to control the Roughness.

If you're setting up more complex hair materials, use the HairAttribute expression in the Material Graph to access the hair attributes such as UV, Dimensions, RootUV, and Seed.

Save and close the Material Editor.

You can apply your hair material in one of two ways; directly on the Groom Asset component through its Details panel in the Level or Blueprint, or by opening the Groom Asset from the Content Browser. Assign your hair material to the Material element slot.

Groom Asset Actor (Details panel)



Groom Asset (Groom Asset Editor)

5 - Setting Up Hair Physics

In this step, you'll enable physics simulation for your Groom Asset.

In your Conent Drawer, locate your Groom Asset and open it in the Groom Asset Editor.

Go to the Physics tab and check the box next to the Enable Simulation option.



Once enabled, the properties in the Physics tab can be used to control the physics properties of the hair.

See the Hair Rendering and Simulation Settings reference page for more information on these Groom Asset properties.

Once enabled, you should see physics applied to the hair while working in the editor and when using play-in-editor (PIE) or simulate-in-editor modes.

Groom Component

Groom Asset

Groom Import Options

Binding Asset Options

Binding Asset

This page contains a reference for properties and settings available for Hair Rendering and Simulation using Groom Assets.

Groom Component

The following properties are available from the Groom component's Details panel when added to a Level as an Actor or when added to a Blueprint.



Click image for full size.

Property

Description



Groom Group Desc



Hair Width

Overrides the hair width (in centimeters).

Hair Root Scale

The scale of the hair width at the root.

Hair Tip Scale

The scale of the hair width at the tip.

Hair Shadow Density

Controls the hair density to reduce or increase hair count during shadow rendering. It enables you to inrease/decrease the shadowing on hair when the number of strands is not realistic.

Hair Raytracing Radius Scale

Scales the hair geometry radius for ray-tracing effects, such as shadows.

Use Hair Raytracing Geometry

Enables hair geometry to be used with ray tracing features.

LOD Bias

Sets the bias for the selected level of detail (LOD). A value greater than 0 will progressively select lower detailed LODs. This property is used when 'r.HairStrands.Cluster.Culling' is enabled.

Use Stable Rasterization

When enabled, this ensures the hair does not alias. When enabled, groups of hairs might appear thicker. Isolated hair should remain thin.

Scatter Scene Lighting

When enabled, hair is lit with the scene color. It is used for vellus/short hair, like peach fuzz, to bring light from the surrounding surface, like skin.

Hair Length Scale

When enabled, this allows scaling the length of the hair.



Materials



Element [N]

Assign your Hair Material to this Asset slot.



Groom



Groom Asset

The Groom Asset to be used for rendering this Actor.

Binding Asset

An optional Binding Asset for binding a groom onto a Skeletal Mesh. If the Binding Asset is not specified, the projection is done at runtime, which implies a large GPU cost at statup time.

Use Cards

When enabled, this option forces the groom to use cards/meshes geometry instead of strands.

Attachment Name

An optional name, where the Groom component should be attached at, when parented to a Skeletal Mesh.



Groom Cache



Groom Cache

The groom animation to playback on this component. It must be compatible with the Groom Asset.

Running

Enable to play back the animation.

Looping

Enable to loop the animation when the elapsed time is past the animation range.

Manual Tick

Enable to play back only through Sequencer.

Elapsed Time

This is a read-only value that shows the time that has elapsed since the start of the animation.



Simulation



Physics Asset

The Physics Asset to be used for this groom when physics simulation is enabled.

Groom Asset

Imported alembic .abc files create a Groom Asset in the Content Browser. When opened, the Groom Asset Editor enables you to edit properties and settings relevant to the groom.



Click image for full size.

For more information, see the Groom Asset Editor User Guide .

Groom Import Options

The Groom Import Options are available when importing a Groom Alembic .abc file. Grooms are imported as one of two options: a Groom Asset or as an animated Groom Cache.





Groom Import Options

Groom Cache Import Options

Property

Description



Conversion



Rotation

Rotation in Euler angle in degrees to fix up or front axes.

Scale

Scale value to convert file unit into centimeters.



Groom Cache



Import Groom Cache

Import the animated groom detected in this alembic file.

Frame Start

The starting index to start sampling the animation from.

Frame End

The ending index to stop sampling the animation at.

Skip Empty Frames at Start of Groom Animation

When enabled, skips empty (pre-roll) frames and starts importing at the frame which actually contains data.

Import Groom Asset

Import, or re-import, the Groom Asset from this file.



Preview



Group Name

The name given to the hair group.

Group ID

The ID given to the hair strands in this hair group.

Curve Count

The number of hair strands within this hair group.

Guide Count

The number of simulation guides within this hair group.

Has Precomputed Weights

This defines whether to use the precomputed weights.



Preview: Decimation Settings



Curve Decimation

Uniformly reduces the number of hair strands used.

Vertex Decimation

Uniformly reduces the number vertices for each hair strand.



Preview: Interpolation Settings



Override Guides

Replaces the imported guides by selecting a set of strands from the imported groom. The amount of guides depends on the value set by Hair to Guide Density.

Hair to Guide Density

Density factor for converting hair into guide curve if no guides are provided.

Interpolation Quality

Interpolation data quality:

Low: Builds interpolation data based on nearest neighbor search. Low quality interpolation data, but fast to build, taking only a few minutes.

Medium: Builds interpolation data using curve shape matching search but within a limited spatial range. This is a tradeoff between Low and High in terms of quality and build time, which can take several minutes.

High: Builds interpolation data based on curve shape matching search resulting in high quality interpolation data. But it is relatively slow to build, taking several dozen minutes.

Interpolation Distance

Interpolation distance metric:

Parametric: Builds interpolation data based on curve parametric distance.

Root: Builds interpolation data based on distance between guide's root and strand's root.

Index: Builds interpolation data based on guide and strands vertex indices.

Randomize Guide

Randomize how guides influence a strand.

Use Unique Guide

Enables whether only a single or multiple guides should influence a strand.

Binding Asset Options

The following properties are available creating or opening an Binding Asset for a given Groom Asset in the Content Browser. Right-click a Groom Asset and choose the Create Binding option from the menu to open these properties.



Property

Description



Build Settings



Groom Binding Type

Sets the type of binding to create a Groom Asset Binding for: Skeletal Mesh or Geometry Cache.

Target Skeletal Mesh

The Skeletal Mesh which the Groom Asset is attached to.



Hair Interpolation



Num Interpolation Points

The number of points used for Radial Basis Function (RBF) interpolation.



Conversion



Source Skeletal Mesh

The Skeletal Mesh on which the groom was originally authored. This is an optional slot, and is only used if the hair binding is done on a different Skeletal Mesh than the one which it has been authored.

Matching Section

The number of points used for the Radial Basis Function (RBF) interpolation.

Binding Asset

After having created a Binding Asset for a Groom, you can open it from the Content Browser to access the following properties.



Property

Description



Build Settings



Groom Binding Type

Sets the type of binding to create a Groom Asset Binding for: Skeletal Mesh or Geometry Cache.

Groom

The Groom Asset that this Binding Asset is attached to.

Source Skeletal Mesh

The Skeletal Mesh on which the groom was originally authored. This is an optional slot, and is only used if the hair binding is done on a different Skeletal Mesh than the one which it has been authored.

Target Skeletal Mesh

The Skeletal Mesh on which the groom is attached to.

Num Interpolation Points

The number of points used for Radial Basis Function (RBF) interpolation.

Matching Section

The number of points used for the Radial Basis Function (RBF) interpolation.



Hair Groups



Curve Count

The number of curves contained in the imported groom file for this binding asset.

Curve LOD

The number of rendered level of detail curves used for this binding asset.

Guide Count

The number of guides contained in the imported groom file used for the binding asset.

Guide LOD

The number of simulation levels of detail used for this binding asset.

Follicle Texture

Strands Textures

The Groom Asset enables you to create textures based on the strands data from your imported grooms. You can generate a follicle mask for your skeletal mesh to better blend hair with its mesh surface. You can also create multiple strands textures that can be used to create a hair mesh or hair cards.

To get started, follow these steps:

Right-click your Groom Asset in the Content Browser.



Choose the type of texture you want to create: Create Follicle Texture and Create Strands Texture.

Follicle Texture

The Follicle texture contains a small distance field of the roots, which allows some effects within the shaders of the underlying surface materials to be captured from the Skeletal Mesh. The generate texture contains multiple channels to store texture information. You can choose several grooms at the same time to fill these channels in the generated texture.

When you choose Create Follicle Texture, the Groom Follicle Mask Options window opens. Choose your options and click Create to generate your follicle texture mask. These textures will be saved in the same location as your Groom Asset.



Property

Description

Resolution

The texture resolution of the follicle mask. The resolution is rounded to the closest power-of-two size, for example, 256, 512, and 1024.

Root Radius

The size of the root of the strand in the generated follicle mask, measured in pixels.



Grooms



Groom

The Groom Asset to be used to generate the follicle texture mask.

Channel

The color channel of the texture mask to store this groom's follicle texture mask in.

In the following example, two grooms have been selected with the first groom outputting its follicle mask into the R (or red) channel, and the second outputs a follicle mask to the G (or green) channel.



Click image for full size.

Strands Textures

The Strands textures includes several textures generated from your groom to be applied to a specified hair mesh.

When you choose Create Strands Textures, the Groom Strands Textures Options window opens. Choose your options and click Create to generate your strands textures. These textures will be saved in the same location as your Groom Asset.



Property

Description

Resolution

The texture resolution of the strands textures that are generated (tangent, opacity, depth, and attribute). The resolution is rounded to the closest power-of-two size, for example, 256, 512, and 1024.

Trace Type

Choose the direction of the traces that should be performed for the projection when generating the strands textures.

Trace Outside performs traces from the mesh's surface to the outside. This works well for facial hair.

Trace Inside performs traces from the mesh's surface to the inside. This works well for hair grooms.

Trace Bidirectional performs traces in both directions, inside and outside.

Trace Distance

The distance from the mesh surface until the hair is projected onto the mesh.

Mesh Type

Selects the type of input mesh that is used for tracing: Static Mesh or Skeletal Mesh.

Static Mesh

The Static Mesh asset on which the groom strands will be projected on to generate textures. Requires you to set the Mesh Type to Static Mesh.

Skeletal Mesh

The Skeletal Mesh asset on which the groom strands will be projected on to generate textures. Requires you to set the Mesh Type to Skeletal Mesh.

LOD Index

The level of detail mesh index on which the texture projection is performed.

Section Index

The section of the mesh on which the texture projection is performed.

UV Channel Index

The UV channel index to use for texture projection.

Group Index

The groom index which should be baked into the textures. When the array is empty, all groups are included by default.

The result is several texture assets that include depth, attributes, opacity and tangent, with which you can apply to a hair mesh. Below are two example textures output from the groom mapped to a hair mesh.





Depth Texture

Tangent Texture

An example hair mesh representation of the groom with the generated textures applied:



Click image for full size.

Converting Legacy XGen Descriptions

Convert Guides to NURBS Curves

Convert Grooms to XGen Interactive Grooms

Exporting Spline Descriptions to NURBS Curves

Creating Attributes

Create Group ID Attributes

Create Guide Attributes

Groom_Width Attribute

Export to Alembic from Maya

Applying Textures to Hair UVs

This guide will show you how to set up a groom for import from Maya's legacy XGen hair creation system for importing into Unreal Engine with a set of supported attributes outlined in the Alembic for Grooms Specification documentation.

Maya 2018.6 was used in creation of assets for this guide.

Converting Legacy XGen Descriptions

Convert Guides to NURBS Curves

Use the following steps to convert your groom's guides to curves in order to save out a set of curves that match the guides you want to transfer.

Set Maya's menu set to Modeling so that you see the correct menu options available.



From the main menu, click the Generate dropdown and select XGen Editor.

In the XGen window, use the Utilities tab to select Guides to Curves.



Click Create Curves.

Once completed, your groom's output should look similar to this:



Convert Grooms to XGen Interactive Grooms

If you're using legacy XGen Description, the groom will need to be converted to be an XGen Interactive Groom. You can do this by:

Select the XGen Description nodes.



While in the Modeling menu set, use the main menu to click the Generate dropdown, then select Convert to Interactive Groom.



Exporting Spline Descriptions to NURBS Curves

Follow these steps to export your selected spline descriptions as an Alembic file that can be imported with the interpolated hairs as NURBS curves.

Select your XGen Spline Description nodes, and while in the Modeling menu set, use the main menu to click the Generate dropdown. Select Cache > Export Cache from the list.



In the Export Cache window, set the following:

Cache Time Frame: Set to Current Frame

Multiple Transforms: Disabled

Write Final Width: Enabled



Enter a name for your file, and select Alembic as the file type.



Click Export.

Use the File menu to select Import. This opens the Import window, which can be used to select and import your Alembic ('.abc') file into your scene.



Once imported, you should now have an XGen Spline Description that was exported and saved as an Alembic file and imported bringing in the interpolated hairs in as NURBS curves.



Creating Attributes

Create Group ID Attributes

Interpolated hair can be exported in one or more groups. These groups are recognized in Unreal Engine for unique material assignment.

Use the following script when creating group ID attributes:

Create Guide Attributes

When creating the guide attributes for your groom, only the curves tagged as guide are used for simulation in Unreal Engine. If there are no guides specified in the Alembic file, a percentage of the interpolated hairs will be internally tagged as guides during the import process into Unreal Engine.

When importing a groom with no guides, the percentage of interpolated hairs that are tagged as guides can be set using the Groom Import Options. By default, only 10% of the number of hairs will be used as guides.

Use the following script when creating your guide attributes:

For Maya, the width value has a special behavior, unlike other DCC applications that can follow the Alembic for Grooms Specification to retrieve them and use them to build the groom.

Maya can export width values directly on the curves so that there's no need to export a custom groom_width attribute; the importer converts those values into that attribute automatically. Should the groom_wdith attribute be present with the groom during import into Unreal Engine, it is not overwritten. If groom_wdith is not specified, or cannot be converted from width values, the builder will fal back on a value of 1 centimeter.

Export to Alembic from Maya

In Maya, select the Guides and Group_ID curves that you want to export.

Each node needs to have a unique name.

While in the Modeling menu set, use the main menu to click the Cache dropdown, then select Alembic Cache > Export Selection to Alembic.



In the Export Selection window, under the General Options category, set the Cache time range to Current Frame.



Under the Attributes category, type the name of the Attribute you want to the list and click the Add button. Add the following schema attributes:



groom_group_id

groom_guide

Enter a file name in the File name textbox, and set the Files of type to Alembic.



Click the Export Selection button.

Applying Textures to Hair UVs

The following steps and included script can help you set up your own XGen hair that can be exported to Unreal Engine, and have an applied texture represented on individual hair strands.

In Maya use the Modeling menu to select Generate > Create Interactive Groom Splines.



You can create guides and brush the hair as you like for your project. When ready, export the curves as an Alembic Cache by selecting Generate > Cache > Create New Cache.



Remove your XGen hair by hiding or deleting it. Then, reimport your exported hair curves with your source mesh in the Maya scene.



Depending on your scene, you will have thousands of spline curves parented under a top curve, SplineGrp0 in this example. Edit the following Python script and replace the following values with the one from your project:

export_directory

hair_file

curve_top_group

uv_mesh

You can download the script below here.

In Maya, run the script with the changed values to generate a new Alembic ('.abc') file which can be imported into Unreal Engine.

In Unreal Engine, create a new Material using the Hair Shading Model. In the material graph, add a Hair Attributes expression and plug the Root UV into the UV input of the Texture Sample.



The groom_root_uv attribute specifies per hair the underlying mesh UV which it is attached to. This attribute is optional, and if not specified, a root UV is automatically generated in the engine using a spherical mapping.

Drag your imported hair Alembic file into the level from the Content Browser, and assign your hair material to it. You should end up with something like this:

Make sure that your hair Alembic file in the level has a width greater than 0.



Opening the Groom Asset Editor

Groom Asset Editor Interface

Viewport Display Options

Viewport Options

Perspectives

View Modes

Show

LODs

Viewport

Details Panels

Level of Detail

Interpolation

Strands

Cards

Procedural Generation

Generating Procedural Cards

Meshes

Materials

Physics

Binding

The Groom system is designed to handle hair strands from imported groom Alembic .abc files. However, for scalability purposes, it also supports alternative geometry representations using cards and meshes. All of these geometric representations are managed within a single asset and component for ease of setup.

The Groom Asset Editor manages most of the aspects of your groom, enabling you to modify various parts of the groom for how it's rendered, how it handles physics simulation, creating and managing levels of detail (LODs), and much more.

Opening the Groom Asset Editor

The Groom Asset Editor is opened from the Content Browser by double-clicking any Groom Asset, or through the right-click context menu of a Groom Asset.



Groom Asset Editor Interface

The Groom Asset Editor is comprised of these regions:



Click image for full size.

Viewport Display Options: Includes viewport options, view perspectives, view modes, debug views, and level of detail visualization.

Viewport: Displays the groom asset with its assigned materials, level of details, and physics representation.

Details Panels: Includes

Viewport Display Options

The Viewport Display Options toolbar provides basic rendering and visualization options.



Viewport Options

The Viewport Options dropdown menu provides basic rendering options within the viewport. You can toggle real-time mode, change the field of view, and set the screen percentage for supersampling.

These options, and more, are accessed using the dropdown arrow in the viewport display options toolbar.



Perspectives

The Perspectives dropdown provides perspective and orthographic views; a perspective view that's a 3D window into the level, and orthographic views that are 2D viewports that look down on of the main XYZ axes.



View Modes

The View Modes dropdown provides a number of visualization options common to all editor viewports, such as lighting, optimization, materials, and exposure value control for the viewport.



Show

The Show dropdown provides Groom Asset Editor specific visualization options to help you see the type of data being processed in your scene, as well as diagnose errors or unexpected results for this groom.



Property

Description

Guide

Displays the guides used for simulation.

Guide Influence

Shows simulation clumps (all the strands influenced by one guide) in color visualization.

UV

Displays the UV along each strand.

Root UV

Displays the UV at the root of each strand.

Root UDIM

Displays the UDIM at the root of each strand.

Dimension

Displays the width/length variations of each strand.

Seed

Displays (in color) the random seed used per strand.

Radius Variation

Shows (in color) the size of the strands. Blue represents thinner strands. Yellow represents thicker strands.

Tangent

Displays tangents direction of each strand.

Base Color

Displays the base color stored per vertex. If base color is not exported from your modeling application with your groom, the strands will appear black.

Roughness

Displays the roughness stored per vertex. If the roughness is not exported from your modeling application with your groom, the strands will appear black.

Hair CVs

Displays hair strands CVs.

Vis. Clusters

Shows clusters of hair used for culling and level of detail purposes.

Hair Groups

Displays hair groups.

Cards Guide

These are some example visualizations from the Show dropdown.









Seed

Hair CVs

Vis.Clusters

Base Color

LODs

The LODs dropdown enables you to visualize levels of detail within the viewport automatically or by specifying a particular level.



Switch between LODs automatically based on the options specified in the Level of Detail panel when using the LODs Auto option. This option automatically switches LODs based on their screen size in the viewport. Alternatively, use the dropdown to select from the available levels of detail that have already been generated to see them represented regardless of screen size.

Viewport

The Viewport is where you can view your imported Groom Asset with changes made in its different details panels, and use different visualization and debug view modes to inspect your groom.

Details Panels

The Groom Asset Editor contains several Details panels which control a variety of attributes related to your groom.

Explore the panels below to learn about the attributes, properties, and options available:

Level of Detail

Interpolation

Strands

Cards

Meshes

Materials

Physics

Binding

Level of Detail

The Level of Detail (LOD) panel controls the decimation of the groom's individual levels of detail. This includes controlling at what visible screen size the LOD should change and what type of geometry it should use (strands, mesh, or cards) for representation.



Property

Description



LOD [N]



Curve Decimation

Decimates the groom by reducing the number of strands. The removed strands are chosen randomly from the groom's imported strands.

Vertex Decimation

Decimates the groom by removing vertices on strands.

Angular Threshold

Defines the maximal angle value of two consecutive strands' segments for removing a vertex. Higher values mean more decimation.

Screen Size

Defines the screen size below which this LOD will be enabled.

Thickness Scale

Increases the strand thickness compensating for the loss of a strands curve. The Thickness Scale adjust an automatic scaling value that is computed.

Visible

Toggles the visibility of this LOD.

Geometry Type

Sets what type of geometry will be used to represent this level of detail. Choose between the following:

Strands

Cards

Meshes

Binding Type

Sets the Groom simulation mode to represent this level of detail. Choose between the following:

Rigid

Skinning

Simulation

Sets what type of attachment points will be used to represent this level of detail. Choose between the following:

Auto

Enable

Disable

RBF Interpolation

Sets the Global Interpolation mode to represent this level of detail. Choose between the following:

Auto

Enable

Disable

Cluster World Size

Defines the average size (in world space) of a hair cluster. A groom is divided into a set of clusters for fine grain level of detail selection and culling.

Cluster Screen Size Scale

Scales the projected screen of a cluster to bias its level of detail selection.



LOD



LOD Selection Type

Set whether the LOD selection should happen on the CPU or the GPU. When CPU is selected, the strands LODing is coarser but allows for all types of geometrical representation (strands, cards, and meshes). When GPU is selected, LODing is more fine grain but only supports strand geometry.

Minimum LOD

Specify the minimum LOD of detail to cook for all platforms, or specify minimum LODs for individual platforms by adding them using the Plus button.

Disable Below Min LOD Stripping

Set a flag to override the removal of LODs below the Minimum LOD set for all platforms, or specify platforms by adding them using the Plus button.

To preview the various LOD in the editor viewport, click on the LOD Auto button within the viewport and select the desired LOD:





Higher LOD Preview

Lower Imported Mesh LOD Preview

Interpolation

The Interpolation panel modifies some of the properties set during initial import of the groom.



Property

Description



Hair Group



Curve Decimation

Decimates the groom by reducing the number of strands. The removed strands are chosen randomly from the groom's imported strands.

Vertex Decimation

Decimates the groom by removing vertices on strands.

Override Guides

When enabled, overrides the imported guides by selecting a subset of strands used as a guide.

Hair to Guide Density

Defines the ratio of strands used as guides.

Interpolation Quality

Defines the quality of the interpolation when interpolating Guides motions onto the strands.

Interpolation Distance

Defines metric used for pairing guides and strands together.

Randomize Guide

When enabled, the guides used for interpolation are slightly randomized to break up clumps that can happen.

User Unique Guide

When enabled, a single guide is used for motion interpolation.



Interpolation



RBF Interpolation

When enabled, the Radial Basis Function (RBF) is used for interpolation instead of the local skin rigid transform.

Hair Interpolation Type

Select the type of interpolation to use when the groom is bound to a Skeletal Mesh:

Rigid Transform: Only the translation of the root closest skin triangle is used during interpolation.

Offset Transform: Only the translation of the root closest skin triangle is used during interpolation.

Smooth Transform: The translation of the root closest skin triangle and a smooth rotation computed from the guide are used during interpolation.

Strands

The Strands panel controls various rendering properties related to the strands geometry of the groom. You can set your material, change key properties of the strands of the hair, such as width, root, and tip scale, and enable ray tracing for the groom.



Property

Description

Material

The material used for the cards representation LODs.

Hair Width

Changes the size of the hair strands. This value corresponds to the width of the largest strand with the default value coming from the imported groom.

Hair Root Scale

Scales the width of the strand starting with the strand's root and fading down towards the tip.

Hair Tip Scale

Scales the width of the strand from the strand's tip and fading down towards the root.

Hair Shadow Density

Scales the hair density making shadow and transmission lighter or stronger uniformly over the groom.

Hair Raytracing Radius Scale

Scales the strand's width when raytraced shadowing is used.

Voxelize

When enabled, hair strands are voxelized to provide more accurate lighting computation.

Use Stable Rasterization

When enabled, the strands are less noisy but can appear a little bit thicker.

Scatter Scene Lighting

When enabled, the strands use the underlying scene lighting as a source light. This property is intended for really short hair, like peach fuzz.

Cards

The Cards panel is where you set up your cards' geometry, textures, and specify whether the engine should generate cards procedurally or use imported ones.



Property

Description

Material

The assigned material used for the Cards representation LODs.

Source Type

Choose the type of cards to use:

Procedural (Experimental)

Imported

Procedural Mesh

The mesh reference for the card geometry.

Imported Mesh

The mesh reference for the card geometry.



Procedural Settings (See Below)





Textures



Depth Texture

The depth texture used for the cards asset. This texture is optional, but when set the value is forwarded to the Hair Attributes node in the Material Editor.

Coverage Texture

The coverage texture used for the cards asset. This texture is optional, but when set the value is forwarded to the Hair Attributes node in the Material Editor.

Tangent Texture

The tangent texture used for the cards asset. This texture is optional, but when set the value is forwarded to the Hair Attributes node in the Material Editor.

Attribute Texture

The attribute texture used for the cards asset. This texture is optional, but when set the value is forwarded to the Hair Attributes node in the Material Editor.

Auxiliary Data Texture

The auxilliary texture enables user data to be transferred for the Cards Asset. It is an optional texture that when set, the value is forwarded to the Hair Attributes node in the Material Editor.

Material Texture

The Material Texture used for the hair meshes. This texture can be generated through the hair-textures option on Groom Asset.

Group Index

The group index on which this card's geometry will be mapped to

LOD Index

The LOD index at which this cards asset should be used.

This feature is experimental. Output results can vary widely depending on the complexity of your grooms.

The Procedural selection generates cards from your strands in your groom. You can specify Geometry and Texture properties that determine how the cards are generated for your groom.



Property

Description



Geometry Setting



Generation Type

Choose whether to use guides or strands for card generation. When strands are selected, a random selection will be used for card generation.

Cards Count

Defines how many cards are generated when Generation Type is set to Cards Count.

Cluster Type

Defines how clumps are formed to generate cards. Choose between High and Low. High creates more well defined clumps but is slower to process.

Min Segment Length

Defines the minimum length between two consecutive card segments.

Angular Threshold

Defines the maximal angle value of two consecutive card segments. Higher values reduce the geometrical complexity of the cards decimation.

Min Cards Length

Cards having length smaller than this threshold are removed.

Max Cards Length

Cards having length larger than this threshold are removed.



Texture Settings



Atlas Max Resolution

The maximum atlas resolution of the generated cards atlas. This value is only a suggestion for the card generator and is not enforced.

Pixel Per Centimeters

Sets the pixel density (or precision) for generating the cards atlas.

Length Texture Count

The number of clumps variations to be generated.

Generate a procedural Cards Asset using the following steps:

Set the Source Type to Procedural using the dropdown menu.

Set the Group Index and the LOD Index for which the cards should be generated. For example, if you want LOD 2 to use cards instead of strands, you would use 2 for the indices.

Under the Source Type dropdown menu, press the Refresh button to generate the Cards Asset.

Under the Source Type dropdown menu, press the Save button to save and reload the Cards Asset.

Meshes

The Meshes panel manages the mesh geometry used for LODs in a Groom Asset. This panel lists all mesh geometry, but all listed geometry is not necessarily used.



Property

Description

Material

The assigned material used for the Cards representation LODs.

Imported Mesh

The assigned mesh geometry to be referenced.



Textures



Depth Texture

The depth texture used for the cards asset. This texture is optional, but when set the value is forwarded to the Hair Attributesnode in the Material Editor.

Coverage Texture

The coverage texture used for the cards asset. This texture is optional, but when set the value is forwarded to the Hair Attributes node in the Material Editor.

Tangent Texture

The tangent texture used for the cards asset. This texture is optional, but when set the value is forwarded to the Hair Attributes node in the Material Editor.

Attribute Texture

The attribute texture used for the cards asset. This texture is optional, but when set the value is forwarded to the Hair Attributes node in the Material Editor.

Auxiliary Data Texture

The auxiliary texture enables user data to be transferred for the Cards Asset. It is an optional texture that when set, the value is forwarded to the Hair Attributes node in the Material Editor.

Material Texture

The Material Texture used for the hair meshes. This texture can be generated through the hair-textures option on Groom Asset.

Group Index

The group index that this card's geometry will be mapped to.

LOD Index

The LOD index at which this card asset should be used.



LOD



Minimum LOD

Specify the minimum LOD of detail to cook for all platforms, or specify specific minimums for individual platforms by adding them using the Plus button.

Materials

The Materials panel defines materials that can be used by the Groom Asset.

Use the Add (+) button to add a new Material reference. Use the Slot Name to give the material a name, otherwise it'll use the default name of the material that is assigned.



The Material slots found in the Strands, Meshes, and Cards panels lets you select from the referenced materials list.



Physics

The Physics panel provides settings to enable physics simulation, and modifying motion behavior of grooms.



Property

Description



Solver Settings



Enable Simulation

Enables physics simulation for the groom asset.

Niagara Solver

Select the Niagara solver to be used for simulation. Choose from Groom Rods, Groom Springs, and Custom Solver.

Custom System

Add a custom Niagara system to be used if the Niagara Solver is set to Custom Solver.

Sub Steps

The number of sub steps to be done per frame. The actual solver calls are done at 24 frames per second.

Iteration Count

The number of iterations to solve constraints with the xpbd solver.



External Forces



Gravity Vector

The acceleration vector measured in cm/s2 to be used for gravity.

Air Drag

The coefficient between 0 and 1 to be used for air drag.

Air Velocity

The velocity of the surrounding air measured cm/s.



Material Constraints: Bend Constraints



Solve Bend

Enables the solve of the bend constraint during the xpbd loop.

Project Bend

Enables the projection of the bend constraint after the xpbd loop.

Bend Damping

Damping applied for the bend constraint using a value between 0 and 1.

Bend Stiffness

The stiffness for the bend constraint in GPa.

Stiffness Scale

The curve determines how much the bend stiffness is scaled along each strand. The X axis range is 0,1. 0 maps to the root and 1 to the tip.



Material Constraints: Stretch Constraints



Solve Stretch

Enables the solve of the stretch constraint during the xpbd loop.

Project Stretch

Enables the projection of the stretch constraint after the xpbd loop.

Stretch Damping

The damping for the stretch constraint using a value between 0 and 1.

Stretch Stiffness

The stiffness for the stretch constraint in GPa.

Stiffness Scale

The curve determines how much the stretch stiffness is scaled along each strand. The X axis range is 0,1. 0 maps to the root and 1 to the tip.



Material Constraints: Collision Constraints



Solve Collision

Enables the solve of the collision constraint during the xpbd loop.

Project Collision

Enables the projection of the collision constraint after the xpbd loop.

Static Friction

The static friction used for collision against the Physics Asset.

Kinetic Friction

The kinetic friction used for collision against the Physics Asset.

Strands Viscosity

The viscosity between 0 and 1 that is used for self-collision.

Grid Dimension

The dimension of the grid used to compute the viscosity force.

Collision Radius

The radius that will be used for the collision detection against the Physics Asset.

Radius Scale

The curve determines how much the collision radius is scaled along each strand. The X axis range is 0,1. 0 maps to the root and 1 to the tip.



Strands Parameters



Strands Size

The number of particles per guide that will be used for simulation.

Strands Density

The density of strands measured in g/cm3.

Strands Smoothing

The smoothing between 0 and 1 of the incoming guides curves for better stability.

Strands Thickness

The strands thickness in centimeters that will be used for mass and inertia computation.

Thickness Scale

The curve determines how much the strands thickness is scaled along each strand. The X axis range is 0,1. 0 maps to the root and 1 to the tip.

Binding

The Binding panel is where you can manage any Binding Assets that are used with this Groom.



Content Creation



Skeletal Meshes are made up of two parts: A set of polygons composed to make up the surface of the Skeletal Mesh, and a hierarchical set of interconnected bones which can be used to animate the vertices of the polygons.

Skeletal Meshes are often used in Unreal Engine to represent characters or other animating objects. The 3D models, rigging and animations are created in an external modeling and animation application (3DSMax, Maya, Softimage, etc), and are then imported into Unreal Engine and saved into packages by using Unreal Editor's Content Browser.



Setting up, exporting, and importing Skeletal Meshes using the FBX content pipeline.

Content Creation

Skeletal Mesh to Static Mesh Conversion

Per Platform LOD

Steps

End Result

While having multiple Level of Detail (LOD) Skeletal Meshes can help lessen the rendering cost of distance objects, the extra memory required to store this information can be an issue on platforms that have limited resources like memory. In the following How - To we will take a look at restricting the number of Skeletal Mesh LOD's a platform can use.

Steps

In the following section, we will take a look at specifying which Skeletal Mesh LOD's should be used when your Unreal Engine 4 (UE4) project is used on PC, Console, and Mobile platforms.

Inside the Content Browser, locate a Skeletal Mesh with LOD's to work with and open it up inside the Skeletal Mesh Editor.



For this example the Skeletal Mesh that was selected has four LOD's, however, you can pick one that has more or less depending on the needs of your project.

Once the Skeletal Mesh is open in the Skeletal Mesh Editor, in the Asset Details panel under LOD Settings, click the + sign next to Minimum LOD.



From the displayed list, select the platform that you want to override by clicking on the platform name.



For the example above, we set overrides for the Desktop, Mobile and Console Platform Groups.

You can also set the individual platforms within each Platform Group identified in the table below.

Platform Group

Platform

Desktop

Linux, Mac, or Windows

Mobile

Lumin, TVOS, HTML5, Android, or iOS

Console

Switch, Xbox One, or PS4

Enter a Minimum LOD value for each of your Platforms.



The Minimum LOD setting works by restricting which LOD level should be used first. Inputting zero will allow each LOD to be used while inputting four will allow only the last LOD to be used. For the example above, we use a value of zero for Default, a value of zero for Desktop, a value of two for Mobile, and finally a value of 1 for Console.

Once that is completed, make sure to press the Save button to save your changes.



End Result

Once all Platforms have had their respective LOD's set, the Skeletal Mesh is ready to be used in game.

The image below breaks down how LODs are used based on the Platform.



On PC's, all LODs are used as the minimum has been set to 0.

On Console, LOD 0 is not used as the minimum has been set to 1.

On Mobile, both LOD 0 and LOD 1 are not used as the minimum has been set to 2.

Posing Skeletal Meshes

Saving Skeletal Mesh Poses

Using Skeletal Mesh Poses

Converting Multiple Placed Skeletal & Static Meshes

Having the ability to pose your project's characters and save those poses for later use, can be a huge time saver when it comes to taking screenshots for marketing or promotional material. In the following document, we will go over how you can pose your Unreal Engine 4 (UE4) project's characters and then save those poses as Static Meshes for later use.

For this example, we will be using the SK_Mannequin that comes with the Third Person Template project. If you have not done so already, create or open a project that makes use of this template.

Posing Skeletal Meshes

In the following section, we will go over what needs to be done so that a Skeletal Mesh can be posed.

First, inside of the Content Browser, locate and then open the SK_Mannequin Skeletal Mesh asset by double-clicking on it.



Once the SK_Mannequin Skeletal Mesh has opened, go to Show > Bone > All Hierarchy to display all of the bones in the viewport.



Select a bone to adjust by clicking on it, and then use the Move, Rotate, and Scale tools, to move, rotate, and scale the various bones until you have a pose that you want.



Saving Skeletal Mesh Poses

Now that we have a Skeletal Mesh posed, we will take a look at how to go about saving those poses as Static Meshes in the following section.

When you are happy with your pose, press the Make Static Mesh button that is on the Main Toolbar of the Skeletal Mesh Editor.



After the Make Static Mesh button has been pushed, you will be prompted to specify a location and name for the newly created Static Mesh asset. Click on the folder you want the Static Mesh to be placed into, input a name for the Static Mesh in the Name box, and then press the OK button to create and save the Static Mesh.



When the conversion process has finished, there should be a new Static Mesh placed in the location that you specified.



Using Skeletal Mesh Poses

With the Skeletal Mesh now posed and saved as a Static Mesh, we will look at how you can use them in your projects.

To use the newly-created (and posed) Static Mesh, select the posed Static Mesh in the Content Browser, and then drag it from the Content Browser into the level like with any other type of Static Mesh asset.



When the posed Static Mesh has been placed in the level, you can then use it like any other Static Mesh in your project.

Converting Multiple Placed Skeletal & Static Meshes

One of the other benefits this tool offers, is that it will allow you to convert Static or Skeletal meshes that have been placed into a level. In the following section, we will take a look at how you go about doing this.

This process will only work with Static or Skeletal meshes. If you try to add BSP to this process, the BSP brush will not convert to a Static Mesh.

Inside of your level, select the assets you want to convert into Static Meshes.



With all of the meshes selected, right-click on one of the meshes. From the context menu that is displayed, select the Convert Actors To Static Mesh option.



From the dialogue box that is displayed, select a name and location for the newly created Static Mesh to be saved, and then press the OK button to start the conversion process.



Once the conversion process has been completed, you should have a new Static Mesh that is composed of the Static and Skeletal Meshes that you selected in the level. You can then use this Static Mesh (as you would any other asset) inside of UE4.



Static Mesh assets are the basic unit used to create world geometry for levels created in the Unreal Engine. These 3D models are created in external modeling applications (such as 3dsMax, Maya, Blender, and so on) that are imported into the Unreal Editor through the Content Browser. The vast majority of any level made with Unreal Engine will consist of Static Meshes, generally in the form of Static Mesh Actors.

Since Static Meshes are cached in video memory, they can be translated, rotated, and scaled and can be more complex than other types of geometry.



How To Create and Use LODs.



How To Import a Static Mesh into Unreal Engine.



Techniques and guidelines for setting up lightmap UVs for Static Meshes.



The Proxy Geometry tool set was developed as a way to increase your Unreal Engine 4 (UE4) projects performance while keeping the visual quality of your project uneffected.



How To Set Up Collision



How to set a material on a mesh in the Static Mesh Editor.



How to set up LOD's on a per-platform basis.



How To use the Automatic LOD Generation system in UE5.



Tool used to preview the look, collision, and UVs as well as set and manipulate the properties of StaticMesh assets.



Deforming a StaticMesh using morph targets and WorldPositionOffset.



How To Set Up and Use Sockets with Static Mesh Actors



The role of UV Channels for rendering Static Meshes, and how you can work with them in the Unreal Editor.



How to set up LOD Screen Sizes on a per-platform basis.

Set Up

Creating a LOD

Collision

LODs in Use

When a player is up close to a Static Mesh you have placed in your level, you want the mesh to look very detailed. However, you do not need that mesh to be very detailed and complex once the player moves far away from the mesh. There is no point in having a very complex and detailed mesh if it is only taking up a few pixels on the screen and the player can barely see it. However, the mesh needs to be detailed when the player is up close to the mesh and can see it clearly. In UE5, you can place a mesh in your level that switches to a less complex mesh as the player moves away from it in order to make your level perform better. You can do this through the use of Level of Details, or LODs. This How-to will show you how you can import a less detailed version of a mesh into UE5 and have your mesh seamlessly swap from one mesh to the other as the player moves closer or farther away.

Set Up

This How-to does require that you already have some sort of mesh saved as a .FBX that you can import into UE5. For this example, we will be using a simple crate made in Maya. Note, you may also use an asset of your own that you have created in another application.

Once you have exported your mesh, launch UE5. If you have a project that you would like to work with, feel free to use it for this How-to. Otherwise, create a new project with the Blueprint First Person template making sure that Starter Content is enabled. If it is not, you may not have some of the assets that we will be using later and it may become hard to follow along.

For detailed instructions on creating a new Project, see the Create a New Project page.

After you have done that, give your project a name and location, and click the Create Project button.

Creating a LOD

Once your project has loaded, navigate to the Meshes folder inside the Content Browser and find the asset named SM_Cube.



Click image for full size.

Once you have found that asset, open it inside the Static Mesh Editor by either double-clicking or by right-clicking and selecting Edit from the context menu that appears. Now you should have something that looks similar to what is shown below.



Click image for full size.

Once you have the asset open in the Static Mesh Editor, locate the Details panel. It is in the upper right corner by default. Once you find it, it should look like what is shown below:



Click image for full size.

The top section is labeled LOD0. LOD is a zero-based system, so LOD0 will be the first entry, LOD1 would be the second, and so on. LOD0 is the base LOD of the mesh and will be the only one that is used if the mesh only has 1 LOD, which this mesh does right now. Next, we are going to change that.

The section directly under that one is named LOD Settings. In this section, there are a few options we are going to go over. The first one is Number of LODs. It is at 1 by default and will increase as you import LODs. This value also can be editable if auto mesh reduction is available. However, in order to use this feature you must first obtain a license from Simplygon.

The next option we will go over is LOD Import. This option will give you a drop down menu similar to this:



Click image for full size.

Select Import LOD Level 1. This should open up a window that allows you to browse to the .FBX file mentioned earlier in this How-to. Browsing to and selecting the .FBX file will import that mesh LOD1, or the second LOD. Once you have done this, you will see a pop-up notification at the bottom right of your screen that should look similar to this:



Click image for full size.

In this example we are only importing 1 LOD which will give us a total of 2, but you can import more if you wish. To do so, simply click on the drop down menu for LOD Import and select Import LOD Level X where X equals whichever LOD was the next one that you wanted to import. You could also reimport any LOD you had already imported. If you wanted to import another mesh for LOD1 instead of the one you already had imported, just click on the drop down menu for LOD Import and select Reimport LOD Level 1. If you clicked on the drop down menu now, your options would look like this:



Click image for full size.

Now that the mesh for LOD1 has been imported, we are going adjust a few of the values to demonstrate the power of LODs. The first option inside the LOD Settings section of the Details panel we are going to look at is Auto Compute LOD Distances. What this does is tell when to switch from one LOD to another by equally dividing the percent of screen size by the amount of LODs. For example, in this case, we have two LODs, so when the mesh takes up 50 percent or more of the screen, LOD0 will appear. When the mesh takes up less than 50 percent of the screen, LOD1 will appear. If there are three LODs, than LOD0 will appear when the mesh takes up 66.7 percent of the screen or more, LOD1 will appear between that value and 33.3 percent, and LOD2 will appear if the mesh takes up less than 33.3 percent of the screen. This may not be very helpful in this case however as the mesh we are using will more often than not take up less than 50 percent of the screen. We can manually change these values, however, by unchecking Auto Compute LOD Distances and manually adjust the Screen Size value for the individual LODs



Click image for full size.

For the purposes of this demonstration, we are going to uncheck Auto Compute LOD Distances. Once you have done that, find the Screen Size value under LOD1 and change it to 0.01. This means that when the cube mesh that we have in our level takes up less than 1 percent of the screen size, our cube will switch to the mesh you imported as LOD1 (in this example, a crate.) We can also change the material for each LOD, as well. Just to further demonstrate the power and usefulness of LODs, we will change the material of LOD1 to M_Metal_Gold.



Click image for full size.

Collision

You can set the Static Mesh to use Complex Collision (per triangle) from any LOD you have imported. This is useful for optimising physics performance, especially if you have lots of Complex Collisions against Static Meshes or Complex Collision Traces. However, there is no switch at run time between Complex Collision when the LOD's change, the chosen LOD will be used for all Complex Collision against the mesh.

See Setting Up Collisions With Static Meshes for information on setting this up.

LODs in Use

After you have done this, save your mesh and go back to the Level Editor. You will see that whenever you are closer to the mesh, it is the cube. As you back away from the mesh, it becomes the crate you imported. Also note that it is not calculated by distance, but by screen size, so if you place a larger instance of the mesh beside a smaller instance of the mesh and start moving an equal distance away from both of them, the smaller instance will switch to the next LOD before the larger instance does. Take a look at the example below.





LOD Far

LOD Near

Note that as we moved farther away, only the cube in the foreground took up more than 1 percent of the screen, so it was still at LOD0, or the cube. However, the meshes in the back became smaller as we moved away and thus took less than 1 percent, and switched to LOD1 (or the golden crates in this example.) Also note that LODs scale with screen size so if you detach the Viewport and resize it, the percentage of what the mesh covers will scale with the size of the Viewport and, thus, change LODs accordingly.

Obviously changing a cube to a crate is not the most practical use of LODs, but this example illustrates how LODs function. Now you are ready to apply LODs to the meshes in your level so that they look good up close but are optimized for performance when further away.

Set Up

Exporting

Import

FBX Import Options

Saving Imported Assets

Many tools within Unreal Engine can help you create assets for your Levels. However, there may come a time when you have to create an asset in an exterior application and import it into Unreal Engine. In this tutorial, you will learn the basics of importing a Static Mesh, made in another 3D application, into the engine for placement in your Levels.

Set Up

To make sure the transition from your 3D modeling software, whether it be Maya, 3ds Max, or some other modeling program, is successful there are a few things to check:

The size of your model will scale as intended to Unreal Engine's measurement of Unreal Units, where 1 Unreal Unit equals 1 centimeter.

Your mesh is exported as an FBX, the recommended file format for 3D objects.

Any textures and materials applied to your static mesh are supported file types.

To learn more about supported file types, refer to FBX Content Pipeline and Textures documentation.

You can skip this step if you have a project you are already working on. However, if you need a project to work with, open the launcher and create a new project. For more information on creating projects in Unreal Engine, see Creating a New Project.

The project category and template you choose and whether or not you have included Starter Content will not matter for this tutorial.

Exporting

After you complete your model, the first step towards importing it into the engine is exporting it from the 3D application used to create the mesh.

This example will cover exporting this sphere model from Maya into your Level. However, feel free to use any application that can export FBX files. To get started, follow these steps:



Click image for full size.

Go to the file menu in your respective application and select Export.



Click image for full size.

Choose the path where you want to save your mesh. Make sure to give it a name and select the appropriate file type.



Click image for full size.

Import

Now that you exported your mesh from the 3D application, you will need to import it into your project. Follow these steps to get started:

Within your project, locate your Content Browser. Browse through the folders there to choose where to import your mesh.

In this example, the sphere mesh, shown below, was imported into a folder labeled Meshes.

Once you are in the folder you want to save your mesh to, import your mesh by doing one of the following:

Right-clicking in an empty space within your folder and selecting Import to... from the context menu.

Clicking the Import button at the top of the Content Browser.



Click image for full size.

In the pop-up Window, browse to find your exported mesh. When you find your mesh, you can import it by either double-clicking it or clicking Open.



Click image for full size.

FBX Import Options

After you have selected the mesh to import, the FBX Import Options menu will appear. By default, it will look very similar to the image below.



Click image for full size.

However, there are many other options that you can play with when importing your mesh. To learn more about these options, refer to FBX Import Options Reference.



Click image for full size.

For this example, all of the defaults are fine and you can import the mesh the way it is.

The process is very similar if you have a mesh that you want to import as a Skeletal Mesh. You need to select the first checkbox, Skeletal Mesh, in the Mesh section.

To finish the process, you can do one of the following:

Click Import, allowing you to choose the Import Options for each individual mesh.

Click Import All, importing all the meshes with the same options.

If you imported more than one mesh, after you click Import, another FBX Import Options menu would appear. As you only imported one mesh in this example, clicking Import or Import All yields the same result and brings you back to your Content Browser.

Saving Imported Assets

In the FBX Import Options, Materials and Import Textures are checked to true by default. Any materials or textures applied to your model from your 3D application will be imported into the engine.

The colored bars on the bottom of the thumbnail tell you what type of Asset it is. Your Static Mesh is the Asset with the light blue bar at the bottom.



Click image for full size.

After checking all your Assets have been properly imported, you need to save them. Click the Save All button in the Content Browser's menu bar to save the imported Assets.

The asterisks on your Asset icon are now gone, indicating a successful save.

Unreal Engine will save your imported Assets as .uasset in your project folder.

With your mesh imported into Unreal Engine and saved, you can now use it in your Level. To implement your mesh into your Level, refer to Placing Actors.

Global Illumination

Generating Lightmap UVs

Creating a Lightmap

Auto-Generating Lightmap UVs

Custom Lightmap UVs

Texture UV versus Lightmap UV

Contiguous UVs and Padding

Lightmap UV Examples

Simple Object

Complex Object

Organic Object

The Importance of Lightmap Resolution

Inspecting Lightmaps and Settings

Static Mesh Editor

Enabling the UV Overlay

Setting the Lightmap Coordinate Index

Setting the Lightmap Resolution

Level Viewport

Using the Lightmap Density View Mode

Lighting Only View Mode

World Settings

Compress Lightmaps

Directly Lit Areas

Indirectly Lit Areas

Directly Lit Areas with Increased Lightmap Resolution

Packed Light and Shadow Map Texture Size

Troubleshooting and Optimization

Error Coloring

Overlapping Lightmap UVs

Wrapping UVs

Statistics Window

Lighting Build Info

Static Mesh Lighting Info



When creating assets for your game, you will often go through the process of setting up a UV that is laid out for your textures. If your project intends to use any form of baked lighting (static or stationary), you will also need to set up a UV channel that stores lighting information. This UV is called a Lightmap UV, which is similar to a texture UV in that it consists of laid-out UV charts (or UV islands) that are unique to each static mesh except this particular UV is used to store baked lighting and shadow information. The process of lightmapping is one of the more challenging areas of environment art creation because, unlike texture UVs, each face of the model needs to have its own unique space on the lightmap with no overlapping faces, and UV charts need to ensure that there is enough padding (or spacing) between them to avoid artifacts.

Lightmaps are only required when a static mesh will be lit using any form of baked (or precomputed) lighting. If your game or project only uses dynamic lighting, there is no need to set up lightmaps for each static mesh.

Creating a Lightmap

There are two ways you can create a lightmap:

Using Unreal Engine's Lightmap Auto-Generation tool

Creating a custom one with UV editing tools

Auto-Generating Lightmap UVs

Creating custom lightmap UVs can be a time-consuming process, especially if you have projects requiring thousands or ten of thousands of assets. An auto-generated lightmap can be a quick way to pack a lightmap UV to save you a significant time investment of manually setting one up and padding it correctly. We've adopted this process into our own workflow here at Epic.

When importing your own assets, a lightmap UV will be generated for you automatically (unless disabled) in the FBX Import Options window.



A lightmap will be automatically generated based on the UV for the texture layout (UV channel 0). The generated lightmap UV repacks the islands so that they meet the requirements of a good lightmap with no errors: no overlapping or wrapping islands, and enough padding between islands to limit artifacts based on the targeted lightmap resolution.

Once a lightmap UV has been generated for a static mesh, it can be adjusted in the Static Mesh Editor, using the lightmap generation settings in the Details panel Build Settings, but there is no requirement to ever touch these settings once the lightmap UV has been generated.



These settings can be used at any time to generate a lightmap UV or repack existing ones. The tool uses a repacking algorithm to generate the lightmap based on a Source Lightmap Index (or UV channel) and then stores it in a new specified by the Destination Lightmap Index. The algorithm repacks the UV charts from the specified source lightmap index but does not cut or split them in the process. Keep this in mind when creating lightmap UVs and by doing a little bit of upfront work in your modeling software or UV editing software, you can get a good result by splitting the UV charts before import into UE4.

For additional information, see Generating Lightmap UVs.

Custom Lightmap UVs

For the majority of static meshes that you import into UE4, you'll be able to use an auto-generated lightmap UV because a good result can be achieved with minimal effort. However, for those times when it's not possible to adequately use an auto-generated UV, you'll want to create a custom lightmap unwrap in your modeling software or UV editing tool.

Depending on the capabilities of your UV editing tools and the type of asset you're creating, you may find that a custom lightmap is the ideal choice since it may require more attention to detail than other assets. A lot of UV editing tools, like the one pictured below from Autodesk 3ds Max have a range of features that enable you to easily flatten, reshape, connect, and break apart UV charts in ways that make sense. These are options that are not available with UE4's lightmap generation.



Autodesk 3ds Max UV Editing Tools.

Later parts of this page will cover the basics unwrapping UVs to get specific results and this is a process that can be combined with auto-generate lightmaps. If you'd like to jump ahead, you can see the Contiguous UVs and Padding section of this page.

Texture UV versus Lightmap UV

Setting up a texture UV often requires a different approach to laying out the UV charts to get the best result than how you would for lightmap UV. Lightmaps must be laid out flat without any overlapping areas and they need enough padding between each UV chart to ensure that there isn't any light leaking. Setting up a texture UV doesn't have these stipulations because it only matters how you want the texture mapped to those UV charts. It's acceptable for them to have islands that are overlapping or even wrapping, because you can have tiling textures or ones assigned to different parts of the geometry.

For example, the building facade below has four sides that have the same texture mapped to its different faces. Instead of using UV space for each side, a single texture has been created and each side's UV charts have been laid on top of one another. This enables space to be used efficiently for a single texture that is mapped to all faces without having to use a higher resolution due to less texel density.

When the lightmap is laid out (right), all faces are represented with their own UV space so that a proper light bake can be generated. Some parts have been separated and are given enough padding between the other charts to ensure fewer artifacts or light leaks.



Texture UV Layout

](LightmapUVLayout.png " Lightmap UV Layout")

Lightmap UV Layout

Contiguous UVs and Padding

One approach to setting up lightmapping UVs is to have contiguous (or connected) groupings of the geometry. To generate a smooth lighting result, it's ideal to connect faces in ways that make sense to represent the geometry.

For example, the UV charts below have connected all the front and side faces of the geometry into a single UV chart and the top has been separated into its own island.



UV Charts for the static mesh geometry.

Once unwrapped, it's necessary to include a minimum amount of padding between UV charts to prevent light and shadow bleed artifacts. A minimum of four texels is usually required to avoid all bleeding artifacts since DXT texture compression operates on 4x4 texel blocks.

If you are setting up a custom lightmap for padding, use the following equation to determine the proper texel spacing for your grid:

Example of the formula above using a resolution of 64:

UE4 uses a pixel for padding meaning that we need to subtract one from each side when trying to find out snapping grid to manually snap UV charts to the grid. Using the auto-generated lightmap UVs will pack them with the appropriate padding.



Wasted UV Padding

Necessary UV Padding

The edges of the lightmap UV do not need additional padding because Lightmass already pads around the edges of the lightmap to prevent any sort of light and shadow bleeding when combining the lightmap texture atlas for the level. This leads to unnecessary padding and wasted UV space.

Using the UV space efficiently can require you to force some UVs together with brute force and scaling to fit them within the UV space.



(From left to right) Lighting only view in Unreal Engine; static mesh with texture; texture UV layout, lightmap UV layout.

It's more important that we have a clean contiguous surface without interruption for the lighting result than to worry about 1:1 scaling. A lightmap that has a 1:7 scaled ratio whereby it has twice the coverage will produce a better result even if the islands are non-uniformly scaled. Areas that are too thin but maintain a 1:1 ratio will not light correctly because it cannot capture a good result. Another key takeaway from this example is that the negative interior cuts have been separated (highlighted red) to prevent them from sharing light and shadow information for the contiguous UV charts where a smooth lighting result is important.

Lightmap UV Examples

The following examples explore custom lightmap UV layouts for simple, complex, and organically structured geometry. These can give you an idea of how to approach and maintain a smooth lighting result.

This building facade represents a simple modular piece that is a good example of a contiguous geometry that when unwrapped mirrors its low-poly geometry.



Texture UV Layout



Lightmap UV Layout

Using contiguous faces make it much easier to maximize coverage in the UV space for better light bakes at lower lightmap resolutions with a nearly perfect lightmap. Notice that there are no seams and no subtle dark lines caused by split UV charts.



Click image for full size.

For designs that do not adhere to any of the rules of thumb for contiguous UVs, like ones that have a lot of geometry or negative space with few elements, you will need to split the UV charts and add much more padding to prevent artifacts.



Static mesh and lightmap UV layout



Light bake result

The railings lightmap shows some distortion on the vertical pieces that hold the rail together (middle image, right side). The two sides and middle section of those pieces were forced together. Even though it has distortion in the UV, it still has enough coverage to generate a good result.

The interiors of the circular pieces on the railing have been split for the front and the back sides into their own contiguous islands. The side that will be visible to the player has the inner and outer faces grouped so that three-quarters of those areas have smooth lighting. The back side of the railing is its own island since it's most likely not something that would be easily visible in the level. Instead, focusing on the majority that is visible to players is most important to have a good result for.

Sometimes, you may have complex geometry that works against what works best for a Lightmap UV. In addition to the medium-sized asset, this one has a lot of negative space, which only adds to its complexity.



Static mesh and lightmap UV layout



Light bake result

When there are so many separate elements, there is a potential for a lot of wasted UV space due to padding. In this instance, there is no choice but to use a higher lightmap resolution to ensure that quality is maintained. By using a little forethought, this example planned to use a higher lightmap resolution by combining UV charts that made sense and also knowing that it would still not look perfect. There will be some bleed but not so much that it would ruin the lighting result.

Depending on your memory budget, you could use a higher lightmap resolution to reduce some artifacts, but it's always better to use as low a resolution as possible for performance and optimization. Also, keep in mind that a good material with an interesting diffuse and normal texture can hide some lightmap issues.

For geometry that has a lot of rounded shapes or that is more organic in design, it's better to project the surface flat and relax the UVs as needed.



Static mesh lightmap UV layout



Baked Lighting Result

For organic shapes, look at how the geometry can be broken apart in a way that makes sense, like splitting UV charts at places that would naturally work. The biggest concern when doing this is that any edge split will break the smoothness of the lighting result. So, in the case of this fountain, breaking the top of the fountain into its top and bottom halves, the center being its own, and the bottom base as its own island make the most sense to reduce visible seams in the light bake. A good rule-of-thumb is to split your lightmap UVs at sections where there are deep recesses or crevices.

The UV chart for the center column doesn't look like its mesh, instead, it's been straightened out to use the UV space more efficiently. For a lightmap UV, this is perfectly acceptable to enable a nice, smooth lighting result.

The Importance of Lightmap Resolution

An effective lightmap will fill the majority of the UV space as efficiently as possible in order to use the lowest resolution that obtains a good lighting result. Most lightmapping issues can be mitigated by using the UV space to maximize coverage while maintaining enough padding between the UV charts.

If your project is built for desktop platforms, they can typically afford to use higher resolutions since they have a larger memory budget to pull from. However, for consoles and mobile platforms, memory budgets need to be tightly controlled. It's common to sacrifice some lightmap resolution quality to stay within budget.

Depending on the geometry and its complexity, it may be helpful to break the mesh into smaller pieces so that each can have a unique lightmap with good coverage and use a lower lightmap resolution while doing so.

Inspecting Lightmaps and Settings

Static Mesh Editor

The Static Mesh Editor enables you to inspect any UVs attached to your Static Mesh, generate your own Lightmap UVs, set the resolution of the lightmap texture for this mesh, and more.

Use the UV dropdown in the toolbar to select a UV channel to display.



Once selected, the UV channel displays an overlay in the Static Mesh Editor Viewport.



The currently displayed UV channel is indicated above the overlay.



The Lightmap Coordinate Index specifies which UV channel should be used for this static mesh when Lightmass generates a lightmap texture during a lighting build.

In the Static Mesh Editor General Settings section, locate the Lightmap Coordinate Index.



UE4 will attempt to assign the proper UV channel where possible when importing a static mesh that currently has a lightmap channel (UV Channel 1) or if a lightmap is generated during import. However, if you generate a lightmap UV after import for a static mesh that did not already have one, you'll need to manually assign the correct UV Channel to the Lightmap Coordinate Index.

The Lightmap Resolution enables you to set the default texture resolution for the baked light and shadow texture generated by Lightmass during a lighting build. This resolution will be used for all instances of this Static Mesh placed in a level.

In the Static Mesh Editor General Settings section, locate the Lightmap Resolution.



You can also override a static mesh's lightmap resolution in any level by enabling Overridden Light Map Res and plugging in a resolution size. This setting overrides this particular instance of the Static Mesh.



Setting Light Map Resolution or Overridden Light Map Res lower than the Min Lightmap Resolution used for a generated Lightmap UV will cause seams and potential light leaks once lighting is built. The Min Lightmap Resolution should be the lowest resolution you ever intend to set for this Static Mesh to ensure that enough padding is maintained between UV Charts.

Level Viewport

The Level viewport enables you to use different view modes to inspect your lighting builds and lightmap resolution densities relative to other Static Meshes. These view modes help you inspect the final results as well as troubleshoot lightmap and lighting build issues.

The Lightmap Density view mode enables you to visualize the density of the assigned lightmaps resolution with a checkered grid relative to other Static Mesh Actors in the level based on an "ideal" (or max) density setting. It's important to have an even density across your scene to get consistent lighting when using baked lighting.



A scene from Epic's Infiltrator demonstrating the Lightmap Density view mode.

Enable this view by using the Level viewport to select View Modes > Optimization Viewmodes > Lightmap Density.



Once enabled, a color grid will overlay all Static Meshes in the scene based on their current Lightmap Resolution.

The following density colors indicate how the ideal lightmap resolution for the level relates to the lightmap resolution set for the static meshes in the level.







Less than ideal texel density

Ideal texel density

Max or greater than ideal texel density

Note that any Static Mesh with its mobility set to Movable will display Brown in the Lightmap Density view mode since it doesn't require a lightmap UV or need to be optimized within this regard.

The default density is an average one to get you started. Depending on your game's texture budget, you may need to adjust the color ranges to be more strict or loose to make this view mode useful to your project. Use the Lightmap Density Rendering Options found in the main toolbar under the Build > Lighting Info to set them.



Property

Description

Ideal Density

Sets the ideal density at which texel density should be for objects in the scene. The ideal texel density is green.

Maximum Density

Sets the maximum density at which texel density is considered too dense for the scene. The texel density is red.

Color Scale

Scales the color for the scene when using Lightmap Density view mode.

Grayscale Scale

Scales the brightness level of the grayscale factor for the scene based on the Ideal and Maximum density values.

Render Grayscale

Enables grayscale to be used for the lightmap density view mode.

The Lighting Only view mode is useful to inspect lighting in your scene without material texture information. This is extremely useful when looking at the light build result.



Use this view mode with Error Coloring to visualize lightmap errors in your scene resulting from overlapping or wrapping UVs.

World Settings

The World Settings panel contains settings specific to the level currently loaded, it includes some additional settings specific to lightmaps, like choosing whether they should be compressed to save memory, setting the maximum size of the packed texture atlas that stores the lightmaps, and access to the packed lightmap textures generated for the level.



By default, UE4 already compresses generated lightmap textures for optimization. When the Compress Lightmaps checkbox is unchecked, the packed lightmap texture atlas will not use compression. It will increase memory usage significantly (by four times) when doing so, but it can reduce artifacts caused by compression algorithms.

For surfaces that do not use a normal map, compression artifacts can be visible for smaller lightmaps packed into the texture atlas. By using good textures and normal maps, the baked lighting result is improved. For some problematic lightmap UVs where you're increasing lightmap resolution, keep in mind that re-working the UV charts to have additional coverage within the UV space can improve these types of compression artifacts.

In directly lit areas with high contrast, compression artifacts may be easier to spot. With compression disabled, the lightmap result is smoother, without the blotchiness but at a much higher cost.





In indirectly lit areas, compression artifacts are less noticeable. While the result is smoother when compression is disabled, it's less likely to be noticed when textures and normal maps are applied.





The lightmap resolution of the trim mesh at the base of the wall (centered between the columns against the floor) has been increased to demonstrate that similar results can be achieved by simply increasing the lightmap resolution rather than disabling compression. By doubling the original lightmap resolution, the majority of artifacts have been eliminated and the texture memory usage is minimal to non-existent for this small of a change.





When lightmaps are generated for the level for individual Actors, they will be packed and stored into multiple texture atlas'. Loading individual lightmap textures per-Actor is not very efficient and would increase the GPU workload to load and unload them continuously.



The number of Static Mesh Actors used in a level and their lightmap resolution will determine the number of texture atlas' that will be used. Larger lightmap resolutions increase the amount of space they use in the atlas. The size of the texture atlas can be adjusted by using a power of two (512, 1024, 2048, or 4096) value for the setting Packed Light and Shadow map Texture Size.



Troubleshooting and Optimization

Error Coloring

Error Coloring enables any warnings that appear in the Message Log under Map Check to be visualized after a lighting build by overlaying a color in the lightmap where the error is occurring.



When Use Error Coloring is enabled, the Lighting Quality must be set to Medium or Preview to visualize the results.



Using the Lighting Only view mode can make it easier to look for and find these types of issues.

An Overlapping Lightmap UV warning indicates that the UV charts are overlapping another part of the geometry within the UV space of the lightmap. All UVs must have their own space in the UV when being used for a Lightmap. The error coloring overlays Orange for any of these UV charts. Note that Texture UVs do not have to adhere to this.



Click image for full size.





A Wrapping UV warning indicates that the UV charts are outside of the 0-1 UV space. The error coloring overlays Green for any of these UV charts.



Click image for full size.





Statistics Window

The Statistics window contains a lot of useful data for lighting, textures, and primitives that are in the currently loaded level(s). A lot of the data here requires a lighting build first to be useful.

To open the Statistics window, use the file menu to select Edit > Statistics.



Click image for full size.

Use the dropdown menu in the upper left to select the type of data you want displayed.



The Lighting Build Info shows a sorted list of Actors in the currently loaded level(s) and how it took to compute lighting for each of them. This list can help you to track down problematic meshes that may be taking a long time to compute lighting for. For example, a high lightmap resolution or number of lights in the scene interacting with an Actor can contribute to the time it takes to compute lighting for it.



Click image for full size.

The Static Mesh Lighting info shows a sorted list of Actors in your currently loaded level(s) and information about its lightmap. This list can help you quickly identify the lightmap resolutions of Actors and the texture memory they'll use.



Click image for full size.

Global Illumination

Caveats and Considerations

Import Options Settings

Lightmap Generation Settings

Generating a Lightmap UV

Regenerating Existing Lightmap UVs

Unwrapping UVs for lightmaps is time-consuming and one way you can mitigate this is to use Unreal Engine 5's (UE5) auto-generation tool to generate a lightmap UV from your existing texture UVs on import or through the Static Mesh Editor.

Caveats and Considerations

By default, an auto-generated lightmap UV repacks the existing UV charts from the static mesh's first UV (UV Channel 0 in UE5). This UV is commonly used as the texture UV, so it's possible that the UV charts aren't laid out or set up in a way that is best suited for a lightmap UV, even with the auto-generation tools in UE5.

Consider the following when creating an auto-generated lightmap UV.

Generated lightmap UVs require an existing source UV to repack and that process is only as good as the UV used meaning that if the UV charts aren't broken up and properly laid out, a good repack will not be possible.

During repacking, UE5 will not split UV chart edges to create separate UV islands. It only repacks the existing UV charts from the source UV index.

UV charts are normalized when generated over maximizing coverage of the UV space with independently scaled or stretched charts.

Import Options Settings

During import, a lightmap UV will be generated for any static mesh by default when Generate Lightmap UVs is enabled. The lightmap UV will be generated from UV Index 1 of your Static Mesh (UV Channel 0 in UE5) and assigned to Lightmap Coordinate Index 1.



Click image for full size.

You can inspect your generated lightmap UV using the Static Mesh Editor. See Unwrapping UVs for Lightmaps for more information.

Lightmap Generation Settings

The Static Mesh Editor Build Settings contains settings to generate and repack lightmap UVs. These options enable you to generate a lightmap UV without having to do so during import or post import if you want to refine the generated lightmap UV.



Click image for full size.

Enable Generate Lightmap UVs to use the UV generation options detailed below in the table to control how the Lightmap UV is generated and repacked:



Click image for full size.

Property

Description

Min Lightmap Resolution

Dictates the minimum padding needed for UV charts when packing the UVs. This target value ensures that packing is texel accurate down to the minimum lightmap resolution used. It will limit the light and shadow bleed that can happen when the value of Lightmap Resolution is lower than this value.

Source Lightmap Index

Chooses the UV channel from which to generate the lightmap UV.

Destination Lightmap Index

Sets the UV channel that the generated lightmap UV will be stored in.

Generating a Lightmap UV

The following steps walk through the process of generating a new lightmap UV from the Static Mesh Editor.

Open the Static Mesh Editor. In the Details panel, navigate to the Build Settings of LOD0.



Click image for full size.

Generate lightmap UVs with the following settings:



Click image for full size.

Enable Generate Lightmap UVs.

Set the Min Lightmap Resolution to an ideal power of 2, which should be the lowest lightmap resolution that this mesh would ever use. This ensures that less light and shadow artifacts might affect the UV charts.

Typically, the Source Lightmap Index should be left on 0 or set to an existing UV channel to generate the lightmap UV from. Only available UV channels will be available to choose from.

The Destination Lightmap Index sets the UV channel to create or store the lightmap UV in. It can be any value (where value represents the actual number of current UV channels for this Static Mesh) plus one.

Click Apply Changes.

In the Details panel under General Settings, set the following:



Click image for full size.

Enter a Lightmap Resolution that this static mesh should use by default for any instances placed in a level. The resolution entered should be higher than the Min Lightmap Resolution used for generating the lightmap UV in the Build Settings.

Set the Lightmap Coordinate Index to the UV channel being used for your Lightmap UV. Typically, this should match the Destination Lightmap Index used to generate the lightmap UV in the Build Settings. This UV channel dictates which UV channel is used when generating the lightmap textures during a lighting build.

In this example, the texture UV has been used to create a new lightmap UV. The texture UV is used as the source to repack for the lightmap UV, and the Texture UV has been laid out in a way that works best not to waste any texture space. With that approach, parts of the mesh are scaled larger (or smaller) based on their importance to get adequate texture resolution without wasting space in the texture.





When the lightmap UV is generated, it is scaled to have the same density (normalized) and then packed into the UV space with enough padding between each UV chart to avoid light and shadow artifacts from a light build. Here, you may notice a little bit of wasted space in the generated lightmap UV, however, this is negligible and would not justify reworking the UV in a custom tool just to make it use this space.

Regenerating Existing Lightmap UVs

Regenerating (or repacking) an existing lightmap UV can be performed using the Static Mesh Edtior's Build Settings. There are benefits to regenerating a lightmap UV for a Static Mesh.

It enables you to change the padding between UV charts to use a higher or lower Min Lightmap Resolution without reimporting the mesh. This is most ideal when you have a lot of individual UV charts and gets a tighter pack in the lightmap UV.

It enables you to repack any existing lightmap UVs from any Source Lightmap Index, including a previously generated lightmap UV channel.

The following steps demonstrate regenerating a custom UV from an imported static mesh:

Open the Static Mesh Editor. In the Details panel, navigate to the Build Settings of LOD0 to set the following options:



Click image for full size.

Optional Set the Min Lightmap Resolution to a new value that is higher or lower. This adjusts how much padding should be between the UV charts.

Set the Source Lightmap Index to the UV channel you want to re-pack

Set the Destination Lightmap Index to be the same one as the Source Lightmap Index.

Click Apply Changes.

Below is a comparison of the custom lightmap UV that was originally imported with the static mesh. You'll notice that the UV charts have been disproportionately scaled to one another, but it's perfectly acceptable as a lightmap UV because it meets the criteria for no overlapping UVs. Regenerating the UV will normalize all the UV charts for an evenly distributed light and shadow bake result. Each UV chart will also be given an appropriate amount of padding between them to ensure less shadow and light leaking artifacts.





It is worth noting that the custom lightmap UV focuses more on having coverage for smaller pieces that the player will see more closely. By increasing coverage of some pieces, the lightmap resolution can be lower to get the same result as the repacked lightmap resolution. You can use your judgment if this is something that you should resolve outside of UE5 for your particular assets.

Starting Out

Guides

Reference

The Proxy Geometry tool set was developed as a way to increase your Unreal Engine 4 (UE4) project's performance while keeping the visual quality of your project uneffected.

The Proxy Geometry Tool is currently only supported on PCs that use Microsoft Windows. Mac and Linux support will be added at a later date.

Starting Out



Overview of the Proxy Geometry system in Unreal Engine 4.

Guides

Reference



Product documentation including reference and guides for Unreal Engine 4

Steps

End Result

In the following How - To we, will take a look at using the Spatial Sampling Distance override parameter to manually adjust the feature minimum size that the system captures when it re-meshes all the Objects (before it simplifies).

Steps

First, inside of any Unreal Engine 5 (UE5) level, select a few Static Meshes to work with.



Click image for full size.

With the Static Meshes still selected open up the Merge Actors tool by going to Tools. Then from the displayed list, select the Merge Actors tool.



Click image for full size.

When the Merge Actors tool opens, click on the 2nd icon to access the Proxy Geometry tools. Then under Proxy Settings, expand the Material Settings section.



Click image for full size.

Locate the Override Spatial Sampling Distance parameter and click on the box next to its name to enable it.



Click image for full size.

Set the value of Override Spatial Sampling Distance to 100 and then press the Merge Actors button.



Click image for full size.

By default, the system computes a guess at this size based on the bounding box of the geometry and the requested Screen Size. If you look in the Window > Developer Tool > Output Log, you will see that the actual number used by the system will be written out. The larger this number is, the less simplification will be performed. The smaller the number is, more simplification will be performed.

Specify a name and location for the newly created Static Mesh and then press the Save button to begin the Proxy Geometry creation process.



Click image for full size.

End Result

When the process has completed you will now have a new Static Mesh, Material and Textures of all the Static Meshes you had selected in the first step of this How - To. The images below demonstrate the effects of setting the Override Spatial Sampling Distance to different values has on the created Static Mesh.

Override Spatial Sampling Distance = 0.5 | Override Spatial Sampling Distance = 1 | Override Spatial Sampling Distance = 10 | Override Spatial Sampling Distance = 100



Steps

End Result

Before your can use the Proxy Geometry tool you will first need to enable it. In the following How - To we will take a look at how you go about enabling the Proxy Geometry tool in your UE5 projects.

Steps

First launch your UE5 project and once it has opened, open up the Project Settings by going to the main toolbar and selecting Edit > Project Settings.



Click image for full size.

Once the Project Settings is open, go to Editor > Hierarchical LOD Mesh Simplification and under the General section click the Hierarchical LOD Mesh Reduction Plugin and then select the ProxyLODMeshReduction plugin.



Click image for full size.

Then go to Tools and then click on the Merge Actors option.



Click image for full size.

End Result

When the Merge Actors tools is open, you should see two icons at the top. Click on the second icon to access the options for the Proxy Geometry Tools.



Click image for full size.

Note that all options will be grayed out until a Static Mesh that is placed in a level is selected.

Steps

End Results

For watertight geometry, the Proxy Geometry tool will automatically discard any inaccessible structures like interior walls, furniture, and anything within a closed structure. For ideal results source geometry should be constructed or altered with this in mind, but due to game production constraints that isn't always feasible. To facilitate the generation of efficient proxy LODs from source geometry that is nearly water-tight, the ProxyLOD tool can now optionally use the level set-based techniques of dilation and erosion, to close gaps. The intended use case is primarily doors and windows in distant buildings and in the following How-To we will take a look at how the Proxy Geometry Tool can be setup to automatically close any gaps that the generated geometry might have.



Steps

In the following section we will take a look at how you can ensure that any open geometry is closed on the Static Mesh that is generated by the Proxy Geometry tool.

First locate a structure or object that has openings that you want to close. For this example, the following small house was constructed using only Static Meshes that can be found in the Starter Content.



Next, open the Merge Actors tool by going to Window > Developer Tools > Merge Actors.



Inside of the level, select all of the Static Mesh Actors that make up the object that you want to generate new geometry for.



In the Merge Actors tool, click the second icon to access the Proxy Geometry tool, and then expand the Proxy Settings.



In the Proxy Settings, set the Merge Distance value to 120.



The Merge Distance parameter tells the Proxy Geometry tool the distance at which gaps should be closed. Smaller numbers will close smaller gaps while larger gaps will fill bigger gaps.

Next, click the Merge Actors button and input a name and location in the Content Browser for the newly created Static Mesh. Then click the Save button to start the merging process.



Once the merge has completed, locate the newly created Static Mesh in the Content Browser, and double-click it to open it in the Static Mesh Editor.



Depending on the object you selected, you might have some issues with the Proxy Geometry tool creating new geometry that extends further than desired (like the following image):



To fix issues like this, first re-select all the Static Meshes that make up your object. Then in the Merge Actors tool, and increase the Merge Distance to a value of 175. Then enable the Transfer Distance Override and set it to a value of 100.



To get a better idea of what values you should use, check the Output Log. The Output Log tells you what values are used for the Spatial Sampling Distance (Voxel size for re-meshing) and Transfer Distance Override (Material Distance). Once you know what values are used, you can either increase or decrease those values depending on what results you are looking for.



Once that has been completed, click the Merge Actors button to begin the process again. When the Proxy Geometry generation has completed the object now looks like this.



Depending on how your geometry is set up, you may need to repeat the above process a few times using different values for Merge Distance and Transfer Distance Override, until you get results you are happy with.

End Results

Getting the best results is going to take some time and iteration, as each object for which you generate Proxy Geometry will require slightly different values for both Merge Distance and Transfer Distance Override. In the following image comparison, you can see the results that can be achieved when setting the Merge Distance and Transfer Distance Override to values of 0, 100, 200, and 300.

Example of what happens when both the Merge Distance and Transfer Distance Override are set to values of 0, 100, 200, and 300.



Steps

End Result

Surprisingly, there are times when adding a little geometry will actually result in more efficient proxy results. This is due to the fact that the underlying spatially sampling and remeshing steps in the proxy lod pipeline are built around concepts that remove inaccessible geometry. In the following How-To we will take a look at how to address issues like this in your Unreal Engine 4 (UE4) projects.

Steps

First, locate a group of Static Meshes that are arranged to form some type of room that has an opening like in the following image.

Select all of the Static Meshes that make up the room along with any items the room might contain and then run the Proxy Geometry Tool create a new proxy Static Mesh.

While the Proxy Geometry Tool did a great job creating a new Static Mesh, there is a lot of detail on the inside of the room that could be removed. To help the Proxy Geometry Tool better understand that, it should remove all of the geometry inside of the building, add a small Static Mesh to the level, and position it so that it covers any openings the room might have.

Once all the openings have been covered by pieces of geometry, run the Proxy Geometry Tool one more time.

End Result

When the Proxy Geometry Tool finishes, take a look inside the room. Notice how almost every single triangle on the inside has been removed, like in the following image.

The reason for this is because adding a new Static Mesh to this model to act as a blocker allowed the Proxy Geometry Tool to automatically remove all the room's internal structure early in the proxy generation. This results in a much shorter production time, a smaller number of final triangles, and a better use of the texture space. In many cases the addition of geometry in the form of a closed door, a floor, or simply a few planes to seal the backside of a complicated facade will greatly simplify the results.

Steps

End Results

The extreme constraints on Fortnite memory usage call for very efficient use of Level of Detail (LOD) meshes. For most of the proxies, very small Base Color Textures where generated and no Normal map is used. Because of this, this approach requires the highest quality normals on the proxy mesh itself. In the following How-To we will take a look at how you can specify how the Normals of a Static Mesh are calculated when using the Proxy Geometry tools.



Steps

In the following section we will take a look at how you can adjust the manner in which the generated Static Meshes Normals are calculated when using the Proxy Geometry tool.

First locate an object that requires you to create a Proxy Static Mesh for it. For this example, the following small house was constructed using only Static Meshes that can be found in the Starter Content.



Next, open up the Merge Actor tool by going to Window > Developer Tools > Merge Actors.



Inside the level, select all the Static Mesh Actors that make up the object for which you want to generate new geometry.



In the Merge Actor tool, click the second icon to access the Proxy Geometry tool and then expand the Proxy Settings.



Under the Proxy Settings, expand the Material Settings section and disable the Normal Map option.



If you don't disable the Normals here, you will not see the correct results because you will be seeing the Normals from the Normal map, and not from the generated Static Mesh.

Next, click the box next to the Hard Edge Angle option to disable it. This disables all normal calculations on the generated Static Mesh.



Next, click the Merge Actors button and input a name and location in the Content Browser for the newly created Static Mesh. Then click the Save button to start the merging process.



Once everything has completed, open up the newly created Static Mesh, which should look something like the following image.



The above image is not what we want; we want the generated object to have Normals that look almost identical to the Normals of the object that it was generated from. To fix this issue, go to the Merge Actor tool and re-enable the Hard Edge Angle option.



Once the Hard Edge Angle has been re-enabled, re-run the Merge Actors tool. When it has completed, you should now have a building that looks like the following image:



End Results

Getting the best results is going to take some time and iteration as each object could require slightly different settings to get the best results. Also keep in mind that when you are specifying a value for the Hard Edge Angle you could increase or decrease the number of vertices that are used in the generated Static Mesh. The following image comparison shows what happens a Static Mesh and it's vertices when setting the Hard Edge Angle to values of 0, 5, 10, 50, 80, 130, and 180.

The following image comparison shows the different shading and vertex counts when setting the Hard Edge Angle to values of 0, 5, 10, 50, 80, 130, and 180.



Steps

End Results

The Proxy Geometry tool will allow you to specify which method should be used when computing the Vertex Normals of a given Static Mesh. In the following How-To we will take a look at how you can change the Vertex Normal calculation method and the effect that will have on your generated Static Meshes.

Steps

In the following section, we will take a look at how you can adjust the method that is used to calculate the Normals that are used for a Static Mesh.

First, locate a Static Mesh or group of Static Meshes that you want to generate new geometry for and select the Mesh or Meshes inside the Viewport.

Next, open the Merge Actor tool by going to Window > Developer Tools > Merge Actors.

In the Merge Actor tool, click the second icon to access the Proxy Geometry tool and then expand the Proxy Settings.

Set the Screen Size value to 50 and make sure that the Normal Calculation Method is set to Angle Weighted.

By setting the Screen Size to a value of 50 we are telling the Proxy Geometry tool to reduce the amount of triangles used in the selected Static Mesh.

Next, click the Merge Actors button and input a name and location in the Content Browser for the newly created Static Mesh. Then click the Save button to start the merging process.



Once that has completed, double-click the Static Mesh to open it in the Static Mesh Editor, where you can see the results.



End Results

Getting the best results is going to take some time and iteration as each object could require a different Normal Calculation Method to achieve the desired results. The results can also be very subtle depending on the type of object that you are using. The following image comparison shows how the Static Mesh used in this example looks when the Normal Calculation Method is set to Angle Weighted, Area Weighted and Equal Weighted.

The following image slider shows the results that each of the three Normal Calculation Methods can achieve. First you will see Angle Weighted then Area Weighted and finally Equal Weighted.



Calculating dynamic shadows for dense geometry or many small meshes combined can have a high performance cost. Using shadows cast by proxy geometry is a method to reduce that cost, by creating a single, simplified mesh to cast the shadow rather than calculating the individual shadows for more complex meshes or multiple smaller meshes.

An example use case is an apartment building that's made up of many different windows, walls, balconies and other high detail features.

To optimize dynamic shadows using proxy shadows:

In the Details panel under Lighting, disable Cast Shadows on all your meshes for which you want the proxy geometry to cast shadows instead.



Add a lower-detail version of the meshes. A proxy shadow caster mesh can be created with the Merge Actor tool (using the Proxy Mesh tab) if the shape is more organic or complex, but for a square building a regular scaled-up cube will work fine. Refer to the Proxy Geometry Overview for more information.



Leave Cast Shadows enabled on the proxy shadow caster.

In the Details panel under Rendering, disable Render in Main Pass on the proxy shadow caster.



Make sure the proxy shadow caster is properly aligned with the visible, higher-detail original.

This technique can also work very well for distant objects with Far Cascade shadow maps enabled.

Now, the building will appear as if it's casting a shadow but it will be much cheaper and faster to render than before.

Reference

Reference



In the following table you will find property descriptions for each of the settings that you will find in the Proxy Geometry Tool:

Property Name

Description

Screen Size

Screen size of the resulting proxy mesh in pixels.

Override Spatial Sampling Distance

Override when converting mesh from proxy lod merging. Warning, large geometry with small sampling has very high memory costs.

Material Settings

Material simplification settings.

Calculate Correct LOD Model

Determines whether or not the correct LOD models should be calculated given the source meshes and transition size.

Merge Distance

Distance at which meshes should be merged together, this can close gaps like doors and windows in distant geometry.

Unresolved Geometry Color

Base color assigned to LOD geometry that can't be associated with source geometry. For example, doors and windows that have been closed by the Merge Distance.

Transfer Distance Override

Override search distance used when discovering Texture values for simplified geometry. Useful when non-zero Merge Distance settings generates new geometry in concave corners.

Hard Edge Angle

Angle at which a hard edge is introduced between faces. Note: Increases vertex count and may introduce additional UV seams. It is only recommended if not using Normal Maps.

Normal Calculation Method

Controls the method used to calculate the Normal for simplified geometry.

Light Map Resolution

Lightmap resolution size.

Compute Light Map Resolution

If ticked will compute the lightmap resolution by summing the dimensions for each mesh included for merging.

Enable Volume Culling

Allows culling volumes to exclude geometry.

Allow Adjacency

Whether to allow Adjacency buffers to tessellation in the merged mesh.

Allow Distance Field

Whether to allow distance field to be computed for this mesh. Disable this to save memory if your mesh will only rendered in the distance.

Reuse Mesh Lightmap UVs

Whether to attempt to reuse the source mesh's lightmap UVs when baking the Material or always generate a new set.

Allow Vertex Colors

Whether to allow Vertex Colors saved in the merged mesh.

Generate Lightmap UVs

Whether to generate lightmap UVs for the merged mesh.

In the following table you will find description for each of the available Console Commands that can be used with the Proxy Geometry Tool:

Command Name

Description

r.ProxyLODChartColorVerts

Color verts by UV chart. Default off.0: Disabled.1: Enabled.

r.ProxyLODCorrectCollapsedWalls

Shall the ProxyLOD system attempt to correct walls with interpenetrating faces0: Disabled - Default.1: Enable, may cause cracks.

r.ProxyLODMaterialInParallel

Doing material work in parallel with mesh simplification.0: Disable.1: Enable - Default.

r.ProxyLODMaxDilationSteps

Limit the number of dilation steps used in gap filling for performance reasons. This may affect gap filling quality as bigger dilations steps will be used with a smaller max.0: Will disable gap filling.1: Default.- Default.

r.ProxyLODMeshReductionModule

Name of the Proxy LOD reduction module to choose. If blank it chooses any that exist.

r.ProxyLODRemeshOnly

Only remesh. No simplification or Materials.0: Disabled - will simplify and generate Materials.- Default.1: Enabled - will not simplify or generate Materials.

r.ProxyLODSingleThreadSimplify

Use single-threaded code path.0: Multithreaded. - Default.1: Single threaded.

r.ProxyLODTransfer

0: shoot both ways.1: preference for forward - Default.

r.ProxyLODUseTangentSpace

Controls the option to generate a Mikk-T space at each vertex. Default on. When this is disabled, a tangent space of (1,0,0) (0, 0, 1) (0,1,0) is added to each vertex for encoding the normal map.0: world space at each vertex.1: tangent space at each vertex - Default.

Proxy Geometry Tool

Proxy Geometry Tool Static Mesh Generation

Proxy Geometry Tool Texture Generation

A Brief Note on Tool Performance

Proxy Geometry Tool

The goal of the Proxy Geometry tool is to help reduce the runtime rendering cost of Static Meshes and their corresponding Materials and Textures. The Proxy Geometry tool achieves this by combining multiple Static Meshes and their corresponding Materials into one single Static Mesh with one single set of Textures and Materials that still matches the original Static Mesh's shape and look but with a reduced number of triangles. This reduced result can be used as a proxy for the original geometry in cases were the difference in quality is either acceptable or not appreciable, for example structures that are distant from the camera.

Proxy Geometry Tool Static Mesh Generation

The results that you get when using the Proxy Geometry tool can vary depending on the settings used in the tool. The images below where created using just the default settings of the Proxy Geometry tool.





Before Proxy

After Proxy

Object Count

22

Object Count

1

Triangle Count

27,308

Triangle Count

4,032

Material Count

6

Material Count

1

While the Static Mesh might not look exactly like the original object, the savings that you get from using the Proxy Geometry tool are quite significant. In this testing scene, we took 22 Static Meshes with six Materials and over 27k triangles and transformed that into a single Static Mesh with one Material and a triangle count of 4k.

Proxy Geometry Tool Texture Generation

The Proxy Geometry Tool will also generate a new set of Textures that correspond to the new Static Mesh geometry that was created. The image below shows an example of what this generated Texture looks like when compared to the original Textures that where used.





A Brief Note on Tool Performance

The first time the proxy system processes an item of geometry, a shader cache on the game thread is populated, incurring a one-time cost. This means that subsequent iterations (For example, changing some parameter and rebuilding that proxy) can be much faster. When comparing against the existing 3rd party options, a 2x to 3x speed improvement is seen with this new system on modest spatial sized geometry clusters, but on very large geometry the time to completion is similar.

Please note that the above information on speed improvements only relates to generating proxies inside of the UE4 Editor, not their use in game. In game performance benefits from the use of proxies will depend on quantities such as the final polygon count and texture sizes.

Steps

End Result

In the following How - To we will take a look at using the Proxy Geometry Tool to create new Static Meshes and Textures for your UE5 projects levels.

Steps

The Proxy Geometry Tools are part of the Merge Actor tools so to open them up you need to go to Tools and then click on the Merge Actors option.



Click image for full size.

When the Merge Actors tool is open, you should see two icons at the top. Click on the second icon to show the options for the Proxy Geometry Tools.



Click image for full size.

The options in the Proxy Geometry tool will only become active when you have Static Meshes selected in a level.

Navigate to a location in a level and then start selecting Static Meshes. For this example 21 Static Meshes have been selected but please feel free to select as many Static Meshes as you want.



Click image for full size.

With the Static Meshes still selected locate the Merge Actors window and then press the Merge Actors button to begin the Proxy Geometry tool creation process.



Click image for full size.

When prompted, specify a Name and Location for the new assets that the Proxy Geometry Tool will create. Once that is completed, press the Save button to continue the Proxy Geometry tool creation process.



Click image for full size.

The time that it takes for the Proxy Geometry tool to finish can range from a few minutes to a few hours. The current progress will be shown in the following window.



Click image for full size.

When the Proxy Geometry tool has completed, go to the Content Browser and search for the newly created assets by input the name given to them in step five.



Click image for full size.

End Result

To view the Static Mesh that was created, go to the Content Browser and double-click on the Static Mesh that was generated. When looking at the Static Mesh in the Static Mesh Editor, note the reduced triangle and material count.



Click image for full size.

You can invoke the Proxy Geometry tool from Blueprint and Python scripts. This can help you automate your Asset creation and data preparation pipeline, combining and simplifying Static Mesh Actors and their Materials from scripts that you run inside the Unreal Editor. This can significantly improve rendering performance at the cost of some visual precision.

For example, this wheel assembly contains 147 separate Static Mesh Actors with a total of 900,000 triangles, with a separate Material for each mesh. This adds up to hundreds of heavy drawcalls on the GPU. After running the Proxy Geometry tool, the Actors are merged into a single model with a single Material, which can be rendered with one drawcall.





The triangle count is also reduced by 97%. This has caused some deformation, but you can adjust the settings in your script to find the right balance between simplification and visual quality.

Because the Proxy Geometry tool involves some relatively complex transformations to your geometry, and offers many settings to control its operation, we recommend getting started with the tool by using it through its UI in the Editor. Move on to invoking it from scripts only when you are confident that you understand the tool, its settings, and have a good idea of the effects you're expecting. See the rest of the guides in this section for more information.

Prerequisite: If you haven't already done so, you'll need to install the Editor Scripting Utilities Plugin. For details, see Scripting and Automating the Editor.

Choose your implementation method:

Blueprints

Python

The Proxy Geometry tool is exposed through the Editor Level Library > Create Proxy Mesh Actor node.



You'll need to give this node the following inputs:

An Array that contains all Static Mesh Actors that you want to merge. Note that these must be Static Mesh Actors, not Actors that contain Static Mesh Components.

An Editor Scripting Create Proxy Mesh Actor Options object that contains the settings used by the proxy geometry tool. This object exposes most of the settings that are shown in the Proxy Geometry tool's UI. To get one of these objects, drag to the left from the Merge Options input, and choose Make EditorScriptingCreateProxyMeshActorOptions.



Click for full image.

Use this object to provide the settings for the Proxy Geometry tool. Many of the detailed settings are provided in another object, which you pass to the Mesh Proxy Settings input. To get one of these objects, repeat what you did above: drag left from the Mesh Proxy Settings input, and choose Make MeshProxySettings.



Click for full image.

For example, the following snippet takes all the Actors that are currently selected in the Level Viewport and World Outliner, merges them together into a proxy mesh, saves the result to an Asset with a specified name and location, and replaces the original Static Mesh Actors in the Level with a single instance of the newly generated proxy Asset.



Click for full image.

The Proxy Geometry tool is exposed through the unreal.EditorLevelLibrary.create_proxy_mesh_actor() function. You'll need to pass this function the following parameters:

An Array that contains all of the Static Mesh Actors that you want to merge. Note that these must be Static Mesh Actors, not Actors that contain Static Mesh Components.

An unreal.EditorScriptingCreateProxyMeshActorOptions object that contains the settings to be used by the proxy geometry tool. This object exposes most of the settings that are shown in the Proxy Geometry tool's UI. You'll need to create one of these objects and set up its properties.

For example, the following snippet takes all the Static Mesh Actors in the Level, merges them together into a proxy mesh, saves the result to an Asset called Proxy, and swaps out the original Static Mesh Actors in the Level for a single instance of the Proxy Asset.

Steps

End Result

In the following How-To, we will take a look at using the Proxy Geometry Tool in conjunction with the Hierarchical Level of Detail (HLOD) system. Using these two tools together will help increase your Unreal Engine 4 (UE4) project's rendering performance by reducing both draw calls and number of triangles drawn to the screen per frame.

Steps

Go to your project's World Settings and display the LODSystem menu option.



In the LODSystem menu, enable the following two options:



Property Name

Description

Enable Hierarchical LOD System

Enables the HLOD to be used with this level.

Simplify Mesh

Enables Proxy Geometry Static Mesh simplification.

Open up the Hierarchical LOD Outliner tools by going to Window > Hierarchical LOD Outliner.



Press the Generate Clusters button on the Hierarchical LOD Outliner and when that is completed, press the Generate Proxy Meshes button to begin the HLOD and Proxy Geometry creation process.



End Result

When the Hierachical LOD tool has finished processing, you can see how many triangles were removed and also compare the results against the original by moving the slider back and forth.



The image comparison slider below shows an example of the types of results you can get when using just the default settings with Simplify Mesh enabled.





Set Up

Collision On a Simple Shaped Mesh

Collision On a More Complex Mesh

Simulating Physics and Collision Presets

In Unreal Engine, you can have Static Meshes do many things, such as change its Texture or Material during gameplay, or move throughout your Level using Sequencer. It is likely, whatever you have your Static Mesh do in your Level, you do not want to have the player be able to walk or shoot through the mesh. That is where setting up collision on your Static Mesh is useful.

Set Up

To start, create a new project using the First Person Game template and enable Starter Content. For more information on creating new projects in Unreal Engine, refer to Creating a New Project.

You may already have a level and Static Meshes of your own to work with. If you do, you can skip this step. However, with the template, you can fire projectiles to demonstrate a point later discussed, so using this template may help you follow along.



Click image for full size.

Once the project is open, in the Content Browser you can use the search bar or navigate to Content > Starter Content > Props to open the Static Mesh named SM_Door.



Click image for full size.



Click image for full size.

SM in SM_Door stands for Static Mesh and follows the standard naming convention recommended by Unreal Engine. Following a consistent naming convention helps maintain an organized project. To learn more about naming files in Unreal Engine, refer to Recommended Asset Naming Conventions.

Once you have found SM_Door, go ahead and open up the Static Mesh Editor by either:

Double-clicking on the asset.

Right-clicking on the asset and selecting Edit from the context menu.

When the editor opens, you will see something similar to what is shown below:



Click image for full size.

Collision On a Simple Shaped Mesh

By default, there is no collision mesh set on the door. Without collision, the player can walk through the door.

You can test this by placing the door into your Level before setting up collision, then play the Level.



Also, if you want the door to blow away when you shoot it or fall to the ground when placed in the sky, you will need to set Simulate Physics to true from the Details panel. However, this option is not available by default if the Static Mesh does not have a collision.



Click image for full size.

These effects are undesirable in most cases, so go ahead and set up collision for this Static Mesh.

In the menu bar at the top of the Static Mesh Editor, there is a Collision dropdown menu. Click it to see the options for adding collision to your mesh. You can also access these options by clicking the Collision dropdown menu in the toolbar ( ) . To learn more about the layout of the Static Mesh Editor, refer to Static Mesh Editor UI.



Click image for full size.

The door mesh is a rather simple shape. This makes things easy when trying to set up collision for your Static Mesh.

The top three options in the Collision menu surround your Static Mesh with a simple collision shape used as the bounds of what can and cannot be blocked or overlapped with your mesh. Below are examples of the door mesh with these collision meshes.













Sphere Simplified Collision

Capsule Simplified Collision

Box Simplified Collision

If you already have a Simplified Collision on a mesh and you add another, the new collision does not replace the other collision, but adds to it.

Adding all three of the Simplified Collisions from above gives you something that looks like the image below.



Click image for full size.

To solve this, you can do one of the following:

Select one of the collisions and press the delete key.

Select Delete Selected Collision from the Collision dropdown menu to remove them one by one.

In the Collision menu, select Remove Collision to remove all collisions on the Static Mesh.



Click image for full size.

After applying the collision, click the collision mesh to notice a translation widget. You can translate, rotate, and scale the collision mesh like you would with any other object within the engine.

Collision On a More Complex Mesh

Using the simple collision mesh you set up in the last section will work fine for:

A Static Mesh that can easily fit into a capsule or box.

A Static Mesh where having precise collision does not matter.

However, you may have a Static Mesh with a more complex shape requiring a precise collision. This section will go over how to set that up.

Back in the Props folder, within the Starter Content, browse to the Static Mesh SM_Chair. Double-click on the thumbnail to open it up in the Static Mesh Editor.

As you can see, this mesh already has collision on it, and looks similar to what is shown below:



Click image for full size.

Let's assume you want the player to be able to sit on the cushion of the chair. The default collision mesh of the chair has an invisible barrier that would prevent the player from sitting.

When the player is playing the game, they only see the Static Mesh itself, not the collision mesh. The player would try to sit on the chair and not know why something is blocking their way.

Remove the collision mesh by selecting Remove Collision from the Collision dropdown menu. You can try to use the primitive shapes you used in the previous section, but as you can see in the images below, none look quite right.







Sphere Simplified Collision

Capsule Simplified Collision

Box Simplified Collision

It seems none of the primitive shapes quite achieve the precise collision needed. However, you can get closer with the other options within the Collision dropdown menu. These options are called the K-DOP Simplified Collision generators.

K-DOP is a type of bounding volume, which stands for K discrete oriented polytope (where K is the number of axis-aligned planes). Basically, it takes K axis-aligned planes and pushes them as close to the Static Mesh as possible. You use the resulting shape as a collision hull.

In the Static Mesh Editor K can be:

10 - Box with 4 edges beveled - you can choose X- Y- or Z-aligned edges.

18 - Box with all edges beveled.

26 - Box with all edges and corners beveled.



Click image for full size.

Here is what your chair mesh looks like with 10-DOP, 18-DOP, and 26-DOP respectively.







10DOP

18DOP

26DOP

These collision options are closer to the precision needed, but there is still a gap between the cushions that might prevent the player from sitting down in the chair.

Select Remove Collision one more time. Next, select Auto Convex Collision from the Collision dropdown menu.



Click image for full size.

The Convex Decomposition panel, pictured below, will then appear in the Details panel.



Click image for full size.

The table below describes each option in the Convex Decomposition panel.

Option

Description

Hull Count

Determines the number of primitives to represent the collision mesh.

Max Hull Verts

Increases or decreases the number of vertices your collision mesh has.

Hull Precision

Number of voxels to use when generating the collision mesh.

The higher these values, the more precise your collision mesh will be, but also the more complex. Clicking Apply applies these settings to your Static Mesh and makes the collision mesh visible.





Default Settings

Max Accuracy and Max Hull Verts

Another way to set up a precise collision is by using multiple Simplified Collision meshes. If you remember from earlier, creating another Simplified Collision mesh does not replace the original one but adds to it. Also, each collision mesh has its own transform widget allowing you to translate, rotate, and scale individually. You can use this to create a custom collision mesh for your Static Mesh.

To get started select Add Box Simplified Collision from the Collision dropdown menu. Click the collision mesh to bring up its transform widget.

Next, translate, rotate, and scale the collision mesh so that it fits along the arm of the chair down to the ground.



With the collision mesh still selected, duplicate the collision mesh by either selecting Duplicate Selected Collision from the Collision dropdown menu or by pressing Ctrl + D.

Next, move this collision mesh so that it fits along the other arm of the chair.



Click image for full size.

Duplicate the collision mesh again. With this new mesh selected, move, scale, and rotate the mesh to fit along the bottom of the chair.



Click image for full size.

Duplicate that collision mesh and move it up, so it fits along the chair's seat.



Click image for full size.

Duplicate the collision mesh one more time and rotate it, so it fits along the back of the chair.

When you are done, you will have something that looks similar to this:



Click image for full size.

You could go back and follow the shape of the chair more closely, but for now the current collision mesh will allow a player to sit on the cushion.

Simulating Physics and Collision Presets

With collision applied to your Static Mesh, it can now simulate physics. Save your chair mesh by clicking the Save button on the left of the Toolbar within the Static Mesh Editor.

Next find SM_Chair inside your Content Browser and drag it into the level. With it still selected, look at the Details panel.

In the Physics section of the Details panel, the Simulate Physics option is now available and will be false by default. If you play the Level now with Simulate Physics set to false, walking into the chair or shooting projectiles at it has no effect. However, your character can not walk through the chair as it now has a collision.

To shoot projectiles at the chair using the First Person Shooter template, you need to walk your character into the weapon to collect it, then Click to shoot.



Click image for full size.

Stop playing the Level and set Simulate Physics to true. Now when you play, notice the chair moves when the player walks into it. The Static Mesh also gets shot across the level and into the air when you shoot at it.



This is not only because the Static Mesh is simulating physics, but also because the mesh is set to Physics Actor by default under Collision Preset.

Go back to the Details panel for the chair and in the Collision section, there is a dropdown menu labeled Collision Presets. The way this instance of the Static Mesh reacts to other objects in the world depends on what its Collision Presets are. Take a look at the options you have, which are shown below.



Click image for full size.

If you switch it to Overlap All, as soon as play begins, you see the Static Mesh fall right through the level. There is also a custom preset, which allows you to manually set how the mesh responds to different objects in your level.

You may want it to block Pawns, but overlap Projectiles, and ignore everything else. In the custom preset, you can tell the Static Mesh to do that.

When selecting a Static Mesh Actor in the level editor, or any Static Mesh Component such as those in the Blueprint Editor, the Details Panel > Collision Category > Collision Presets will show Default. This indicates there has been no change to the Collision Preset from what it was initially set to. If something else is listed here, such as BlockAll, that indicates the selected Static Mesh Actor / Component has had its Collision Preset overridden.



Click image for full size.

Now that you have collision set up on your mesh, you are ready to place it in your Level and use its collision to set up how it affects and can be affected by other objects.

To continue learning about collisions in Unreal Engine, refer to the Collision documentation.

Setup

Applying a Material via the Details Panel

Applying a Material via the Static Mesh Editor

No matter what type of Static Mesh you put into your Level, chances are when the player looks at that object, you want it to have a Material. In this guide, you will learn a couple of ways to apply a Material to your Static Mesh.

Setup

If you already have a project you are working on, you can use that project to follow along. If you do not, start by launching Unreal Engine and creating a new project with Starter Content enabled. For more information on creating new projects in Unreal Engine, refer to Creating a New Project.

This guide uses the First Person game template, but the template you use does not matter for this tutorial. The important thing is to make sure Starter Content is enabled if you are creating a new project. If you do not, you won't have the assets referenced later in this guide, which might make it difficult to follow along.



Click image for full size.

Once your project is loaded, open your Content Browser and open the folder labeled Starter Content, as shown below.



Click image for full size.

Inside of the Starter Content folder, there is a folder labeled Props. Open that folder and find the Static Mesh labeled SM_Chair.

SM in SM_Chair stands for Static Mesh and follows the standard naming convention recommended by Unreal Engine. Following a consistent naming convention helps maintain an organized project. To learn more about naming files in Unreal Engine, refer to Recommended Asset Naming Conventions.



Click image for full size.

Click and drag SM_Chair into the Level Viewport. A copy of the Static Mesh now appears in your Level. To learn other methods of adding a Static Mesh to your Level, refer to Placing Actors.



Click image for full size.

Applying a Material via the Details Panel

A quick way to switch the Material of one instance of a Static Mesh is by highlighting that particular instance and changing the Material in the Details panel. The following section goes over how you can do that.

When placing a Static Mesh into your Level an instance of the mesh is created. Any Material assigned to the instance will not affect the Static Mesh itself.

Highlight your Static Mesh by clicking it in the Viewport or searching for SM_Chair in the Outliner.

With the Static Mesh selected, go to the Details panel. There will be a Materials section with a thumbnail and a dropdown menu with the current Material name.



Click image for full size.

Selecting another Material from the dropdown menu changes the Material applied to that instance of the Static Mesh. The change is reflected in your Viewport, as demonstrated below:





Normal Chair with Details

Brick Chair with Details

Applying a Material via the Static Mesh Editor

Now you can change the Material of one instance of a Static Mesh in your Level, but what if you want to change the default Material of the Static Mesh itself? Well, you can do that from within the Static Mesh Editor.

Go back to SM_Chair within the Props folder in your Content Browser. Once you have it selected, you can access the Static Mesh Editor in two ways:

Double-click the mesh inside the Content Browser.

Right-click on the mesh and select Edit from the context menu.



Click image for full size.

After double-clicking the asset inside the Content Browser or selecting Edit from the right-click context menu, the Static Mesh Editor will open, as shown below.



Click image for full size.

In the Details panel, on the right-hand side of the Static Mesh Editor, find the Material Slots section. There you can see a thumbnail of the Material used on the Static Mesh and a dropdown menu beside it with the name of the Material. To learn more about the layout of the Static Mesh Editor, refer to Static Mesh Editor UI.



Click image for full size.

Click on the dropdown menu and select another Material.

You have now applied a new Material to the Static Mesh, as shown below.



Click image for full size.

Next, click Save in the Toolbar at the top of the Static Mesh Editor. The applied Material is now the default Material of the Static Mesh and any instance of the mesh placed in the Level.



Click image for full size.

To continue learning about Materials, refer to Materials documentation.

Steps

End Result

While having multiple Level of Detail (LOD) Static Meshes can help lessen the rendering cost of distance objects, the extra memory required to store this information can be an issue on platforms that have limited resources like memory. In the following How-To we will take a look at restricting the number of LOD's a platform can use.

Steps

In the following section we will take a look at specifying which LOD's should be used when your UE5 project is used on PC, Console, and Mobile platforms.

First, inside the Content Browser, locate a Static Mesh that has a few LOD's to work with and open it up inside the Static Mesh Editor. For this example the Static Mesh that was selected has four LOD's however you can pick one that has more or less depending on the needs of your project.



Click image for full size.

Once the Static Mesh is open in the Static Mesh Editor, go to the Details Panel and expand the LOD Settings category.



Click image for full size.

Locate the Minimum LOD input and then click on the small white triangle next to it to expose the per-platform LOD options.



Click image for full size.

From the displayed list, select the platform that you want to override by clicking on the platform name. For this example we will be setting overrides for Desktop, Mobile and Console.



Click image for full size.

The Minimum LOD setting works by restricting which LOD level should be used first. Since our example Static Mesh has four LOD's this means that we can input numbers ranging from zero to four. Inputting zero will allow each LOD to be used while inputting four will allow only the last LOD to be used. For this example input a value of zero into Default, input a value of one into Desktop, input a value of two into Console, and finally input a value of three into Mobile.



Click image for full size.

Once that is completed, make sure to press the Save button to save your changes.



Click image for full size.

End Result

Once all platforms have had their respective LOD's set, the Static Mesh is now ready to be used in your UE5 project. To get a better understanding of how this works, check out the following image:



Click image for full size.

When this Static Mesh is viewed on a PC, it will only display three of the four LOD's because the Minimum LOD for PC was set to a value of one.

When this Static Mesh is viewed on a Console, it will only display two of the four LOD's because the Minimum LOD for Console's was set to a value of two.

When this Static Mesh is viewed on Mobile, it will only display one of the four LOD's because the Minimum LOD for Mobile was set to a value of three.

Setup

Creating LODs

Using LOD Groups

Manually Creating LODs

End Result

The Automatic LOD generation system allows you to automatically reduce the polygon count of your Static Meshes to create LODs with the Unreal Engine 5 (UE5) Editor. Automatic LOD generation uses what is called quadratic mesh simplification to help generate the LODs for Static Meshes. Quadratic mesh simplification works by calculating the amount of visual difference that collapsing an edge (by merging two vertices) would generate. It then picks the edge with the least amount of visual impact and collapses it. When this happens, the tool will pick the best place to put the newly merged vertex, removing any triangles that have also collapsed along with the edge. It will continue to collapse edges until it reaches the requested target number of triangles. In the following guide, we'll show you how-to setup and use the automatic LOD generation system in your UE5 projects.

Setup

In the following section, we will create a new project that has Starter Content, and then open up a Static Mesh asset to work with.

For this part of the how-to guide, we will use the SM_Rock Static Mesh that comes with the Starter Content. However, feel free to use any Static Mesh of your choosing to follow along.

If you have not done so already, open, or create a new UE5 project, making sure that the With Starter Content setting is enabled.



Click image for full size.

Once the project has loaded, locate the SM_Rock Static Mesh, and double-click on it to open it up in the Static Mesh Editor.



Click image for full size.

Creating LODs

There are two different ways in which LODs can be generated. The first method, which is the method Epic recommends, is to use the LOD Group presets, which automatically creates LODs based on pre-configured settings. The second method involves setting up the LODs yourself. Below, you will find detailed descriptions on how to use each LOD creation method.

Using LOD Groups

Using LOD Groups is the preferred way to create LODs inside UE5 with the Automatic LOD tool. In the following section, we will go over how you go about setting up and using LOD groups in your UE5 projects.

First, locate your project's BaseEngine.ini file and open it up inside of a Text editor. Now, look for the [StaticMeshLODSettings] section. If you do not see this entry in your BaseEngine.ini file, copy and paste the following code into your BaseEngine.ini file.

Adding, removing, or adjusting entries from this section will add, remove, or adjust how the LOD groups function when they're used.

Now, open the UE5 Editor and then open up a Static Mesh you want to generate LODs for by double-clicking on it in the Content Browser. For this example, we will be using SM_Rock, which comes with the Starter Content.

With the Static Mesh now open in the Static Mesh Editor, go to the Details panel and expand the LOD Settings section.



Click image for full size.

In the LOD Settings section, click on the LOD Group button, and from the displayed list, select the SmallProp option.



Click image for full size.

You will then be notified that what you are doing will overwrite your current settings with the new setting from SmallProp. Press the Yes button to continue.



Click image for full size.

The Static Mesh Editor should now have four new LOD entries (LOD0, LOD1, LOD2, and LOD3) added to the Details panel. If you click on each LOD entry, you will notice that the settings correspond to the settings that were defined in the StaticMeshLODSettings in your project's BaseEngine.ini file.



Click image for full size.



Click image for full size.

Make sure Auto Compute LOD Distances is checked, as it will help in determining which screen size to use for the LOD. Because the algorithm knows how much visual difference every edge collapse is adding, it can use this information to determine what distance that amount of error is acceptable. Turning this off, means that the screen size for each LOD needs to be set by hand, which could lead to errors.

Now, experiment with the different LOD Group settings to see how they will create LODs for your objects. In the next section, we will go over how to manually create LODs.

Manually Creating LODs

In this section, we will go over how to manually setup and create LODs for your project's assets.

While the following will create LODs for you, Epic recommends using the LOD Groups method that was described in the previous section.

In the Details panel of the Static Mesh Editor, expand the LOD Settings section, and look for the Number of LODs option.



Click image for full size.

The LOD Group provides a list of presets to quickly choose the right LOD settings for your project. These can be changed per project in BaseEngine.ini under [StaticMeshLODSettings]. We encourage you to set up good categories for your project, primarily using LOD groups, instead of controlling the details of every LOD.

Set the Number of LODs to four, and then press the Apply Changes button to add the four (new) LODs to the mesh.



Click image for full size.

Make sure Auto Compute LOD Distances is checked, as it will help in determining which screen size to use for the LOD. Because the algorithm knows how much visual difference every edge collapse is adding, it can use this information to determine what distance that amount of error is acceptable. Turning this off, means that the screen size for each LOD needs to be set by hand, which could lead to errors.

Press the small, white, triangle next to LOD1 to expand that section, and then press the small, white, triangle next to Reduction Settings.



Click image for full size.

Under Reduction Settings, locate the Percent Triangle section, and set it to a value of 75 before pressing the Apply Changes button.



Click image for full size.

Now, expand LOD2 and LOD3, setting the Percent Triangles for LOD2 to 25 percent, and setting the Percent Triangle for LOD3 to 12 percent. When completed, you will see a number of triangles each LOD uses next to the LOD name (like in the image below).



Click image for full size.



Click image for full size.

Now, as you move your camera closer and further away from the object in the Static Mesh Editor, you will be able to see the LODs change. If the visual change in the LODs is too hard to notice, information about the LOD change is displayed on the left side of the screen.



Click image for full size.

With the LODs now setup for this Static Mesh, when this Static Mesh is placed in a level, it will automatically choose which LOD to display based on how far the camera is away from it.

End Result

In the following document we took a look at two different ways to use the automatic LOD generation tools UE5 has to offer. Remember that when using the automatic LOD tools, it is best to first setup and define different LOD groups that meet your project's needs and then select those various setting using the LOD Group drop down that can be found under LOD Settings.

Menu Bar

Toolbar

Viewport Panel

Details Panel

Bottom Toolbar

Controls

The Static Mesh Editor consists of four areas:



Click image for full size.

Menu Bar

Toolbar

Viewport Panel

Details Panel

Bottom Toolbar

You can close any panel by clicking the small X in the upper-right corner of the tab. You can also hide any panel by right-clicking on the tab, and then clicking Hide Tab on the context menu that appears. To once again display a panel that you have closed, click that panel's name on the Window menu.

Pressing F1 displays the Unreal Engine Static Mesh Editor UI documentation.

Menu Bar



Click image for full size.

File



Click image for full size.

Command

Description

Open Asset

Opens the Global Asset Picker to quickly find an asset and open the appropriate editor. (CTRL + P)

Save All

Saves all unsaved levels and assets for your project. (CTRL + SHIFT + S)

Choose Files to Save

Brings up a dialog box that allows you to choose which levels and assets you want to save for your project.

Save

Saves the asset you are currently working on. (CTRL + S)

Save As

Saves the asset you are currently working on under a new name. (CTRL + ALT + S)

Edit



Click image for full size.

Command

Description

Undo

Undoes the most recent action. (CTRL + Z)

Redo

Redoes the most recent Undo, if it was the last action taken. (CTRL + Y)

Undo History

Brings up the Undo History panel in a separate window.

Command

Description

Delete Socket

Deletes the selected socket from the mesh. (DELETE)

Duplicate Socket

Duplicates the selected socket. (CTRL + D)

Command

Description

Editor Preferences

Gives you a list of options, any of which open that part of the Editor Preferences window, where you can modify your Unreal Editor preferences.

Project Settings

Gives you a list of options, any of which open that part of the Project Settings window, where you can modify various settings for your Unreal Engine project.

Plugins

Brings up the Plugins window.

Asset



Click image for full size.

Command

Description

Find in Content Browser

Locates and selects the current asset in the Content Browser. (CTRL + B)

Reference Viewer

Launches the Reference Viewer showing the selected assets' references. (ALT + SHIFT + R)

Size Map

Displays an interactive map showing the approximate size of this asset and everything it references. (ALT + SHIFT + M)

Audit Assets

Opens the Audit Assets UI and displays information about the selected assets. (ALT + SHIFT + A)

Shader Cook Statistics

Shows the Shader Cook statistics. (CTRL + ALT + SHIFT + S)

Reimport filename

Reimports the current asset from its original location on disk.

Find Source

Opens the explorer to the location of the selected asset.

Additional Data

Toggles whether or not to draw additional user data associated with the asset.

Bake Out Materials

Bake out Materials for given LODs.

Collision



Click image for full size.

Command

Description

Add Sphere Simplified Collision

Generates a new sphere collision mesh encompassing the Static Mesh.

Add Capsule Simplified Collision

Generates a new capsule collision mesh encompassing the Static Mesh.

Add Box Simplified Collision

Generates a new box collision mesh encompassing the Static Mesh.

10DOP-X Simplified Collision

Generates a new axis-aligned box collision mesh with the 4 X-axis aligned edges beveled (10 total sides) encompassing the Static Mesh.

10DOP-Y Simplified Collision

Generates a new axis-aligned box collision mesh with the 4 Y-axis aligned edges beveled (10 total sides) encompassing the Static Mesh.

10DOP-Z Simplified Collision

Generates a new axis-aligned box collision mesh with the 4 Z-axis aligned edges beveled (10 total sides) encompassing the Static Mesh.

18DOP Simplified Collision

Generates a new axis-aligned box collision mesh with all edges beveled (18 total sides) encompassing the Static Mesh.

26DOP Simplified Collision

Generates a new axis-aligned box collision mesh with all edges and corners beveled (26 total sides) encompassing the Static Mesh.

Convert Boxes to Convex

Converts any simple box collision meshes to convex collision meshes.

Remove Collision

Removes any simplified collision assigned to the Static Mesh.

Delete Selected Collision

Deletes the selected collision from the mesh. (DELETE)

Duplicate Selected Collision

Duplicates the selected collision. (CTRL + D)

Auto Convex Collision

Generates a new convex collision mesh based on the shape of the Static Mesh asset.

Copy Collision from Selected Static Mesh

Copies any collision meshes that were created in the native 3D application and saved with the Static Mesh.

Find Source

Locates the folder location of the current asset .

For more information about collision for Static Meshes in Unreal Engine, refer to the Setting Up Collisions With Static Meshes page.

Window



Click image for full size.

Command

Description

Viewport

Toggles the display of the Viewport panel.

Details

Toggles the display of the Details panel.

Socket Manager

Displays the Socket Manager panel, which is not displayed by default.

Convex Decomposition

Displays the Convex Decomposition panel, which is not displayed by default.

Preview Scene Settings

Toggles the display of the Preview Scene Settings panel.

Command

Description

Cinematics

Sequence Recorder: Opens a Sequence Recorder tab.

Content Browser

Brings up the Content Browser tool in a separate window. Enables opening multiple Content Browser windows.

Command

Description

Device Output Log

Brings up the Device Output Log in a separate window.

Interchange Results Browser

Brings up the Interchange Results Browser.

Message Log

Brings up the Message Log in a separate window.

Output Log

Brings up the Output Log in a separate window.

Command

Description

Open Marketplace

Brings up the Marketplace window to shop for Assets.

Quixel Bridge

Brings up a Quixel Bridge tab for importing Assets.

Command

Description

Load Layout

Default Editor Layout: Loads the default layout that the Unreal Editor automatically generates.

UE4 Classic Layout: Loads the default editor layout of Unreal Engine 4.

Import Layout: Import a custom layout (or a set of layouts) from a different directory and load it into your current instance of the Unreal Editor UI.

Save Layout

Save Layout As: Save the current layout customization on disk so it can be loaded later.

Export Layout: Export the current layout customization to a different directory.

Remove Layout

Remove All User Layouts: Remove all the layout customizations created by the user.

Enable Fullscreen

Enables fullscreen mode for the application, expanding across the entire monitor. (SHIFT + F11)

Tools



Click image for full size.

Command

Description

New C++ Class

Brings up a window to add C++ code. The code can only be compiled if Visual Studio is installed.

Generate Visual Studio Project

Generates your C++ code in Visual Studio.

Command

Description

Find in Blueprints

Brings up the Find in Blueprints tool in a separate window. Enables opening multiple Find in Blueprints windows.

Cache Statistics

Displays cache statistics.

Class Viewer

Displays all existing classes within the current project.

CSV to SVG

A table of tools for generating vector line graphs.

Localization Dashboard

Brings up the Localiztion Dashboard for your project in a separate window.

Merge Actors

Brings up the Merge Actors tool in a separate window.

Natine Tools

Tools for auditing and optimizing Nanite assets.

Project Launcher

The Project Launcher provides advanced workflows for packaging, deploying, and launching your projects.

Resource Usage

A table displaying data usage of each asset type.

Session Frontend

Brings up the Session Frontend in a separate window.

Struct Viewer

Brings up the Struct Viewer in a separate window, which displays all structs that exist within the project.

Virtual Assets

Statistics for Virtual Assets.

Command

Description

Debug

Brings up the Debug Tool in a separate window.

Blueprint Debugger: Brings up the Blueprint Debugger in a separate window.

Collision Analyzer: Brings up the Collision Analyzer in a separate window.

Debug Tools: Brings up the Debug Tools in a separate window.

Modules: Brings up the Modules tab in a separate window.

Niagara Debugger: Brings up the Niagara Debugger in a separate window.

Pixel Inspector: Brings up the viewport Pixel Inspector tool in a separate window

Stylus Input Debug: Displays current values of stylus inputs.

Visual Logger: Brings up the Visual Logger tool in a separate window.

Widget Reflector: Brings up the Widget Reflector tool in a separate window.



Profile

Profile Data Visualizer: Brings up the Profile Data Visualizer tool in a separate window.

Trace Data Filtering: Bring up the Visual Logger tool in a separate window, allows for setting Trace Channel states.

Audit

Asset Audit: Brings up the Asset Audit window, which enables viewing detailed information about assets.

Material Analyzer: Brings up the Material Analyzer tool in a separate window

Platforms

Device Manager: Brings up the Device Manager in a separate window.

Device Profiles: Brings up the Device Profiles in a separate window

Command

Description

View Changelists

Brings up a dialog displaying current changelists.

Submit Content

Brings up a dialog with check-on options for content and levels.

Connect to Source Control

Brings up a dialog box that allows you to choose or interact with a source-control system Unreal Editor can integrate with.

Command

Description

Run Unreal Insights

Brings up the Unreal Insights Session Browser.

Help



Click image for full size.

Command

Description

StaticMesh Editor Documentation

Opens a browser window and navigates to the documentation about this tool. ( F1)

Command

Description

Documentation Home

Brings up an internet browser to technical resources for utilizing the engine.

C++ API Reference

Classes, functions, and other elements that make up the C++ API.

Console Variables

Reference companion for console variables and commands.

Command

Description

Online Learning

Learn Unreal Engine for free with easy-to-follow video courses and guided learning paths.

Forums

Navigate to the Unreal Engine forums to view announcements and engage in discussions with other developers.

Q&A

Navigates to the Question and Answer section of the Forum.

Command

Description

Support

Navigates to the Unreal Engine support website's main page.

Report a Bug

Navigates to an online portal for reporting bugs in the Unreal Editor.

Issue Tracker

Navigates to the Unreal Engine issue tracker page

Command

Description

About Unreal Editor

Displays application credits, copyright information, and build information.

Credits

Display application credits.

Visit UnrealEngine.com

Navigates to UnrealEngine.com where you can learn more about Unreal technology.

Toolbar



Click image for full size.

Command

Description

Save

Saves the current asset.

Browse

Browses to the associated asset and selects it in the most recenty-used Content Browser (summoning one if necessary).

Reimport Base Mesh

Reimport Base Mesh: Reimports the base mesh.

Reimport Base Mesh + LODs: Reimports the base mesh and all the custom LODs.

Collision

Quick access to display the same Collision options as the menu bar.

UV

None: Toggles display of the static mesh's UVs.

UV Channel #: Toggles display of the Static Mesh's UVs for the selected channel(s) for the static mesh asset in the Preview Panel.

Remove Selected: Removes the currently selected UV from the static mesh.

Viewport Panel

The Viewport panel shows a rendered (or optionally wireframe) view of the Static Mesh asset. This allows you to examine the Static Mesh as it would be rendered in-game. Simultaneously, the Viewport contains tools and visualizers to see specific data such as:

The bounds of the Static Mesh asset.

Any Collision Mesh assigned to the Static Mesh.

The UVs of the Static Mesh.

Overlaid onto the Viewport panel is a set of statistics or information about the Static Mesh asset.



Click image for full size.

In this information you will find the following:

LOD: Displays the number of LOD (Levels of Detail) for the Static Mesh.

Current Screen Size: The vertical height of the mesh displayed on screen as a proportion of the height of the viewport.

Triangles: Displays the number of triangles in the Static Mesh.

Vertices: Displays the number of vertices in the Static Mesh.

UV channels: Number of UV channels. Unique, non-overlapping UVs are required for shadow mapping.

Distance Field: The resolution and memory footprint of the distance field for this mesh.

Approx Size: Displays the approximate size (Length x Width x Height) of the Static Mesh in Unreal units with a scale of 1 in all axes.

Num Collision Primitives: Number of collisions primitives.

The tables below cover the basics of the Viewport. For more information about using this panel, refer to the Using Editor Viewports documentation.

Viewport Options



Click image for full size.

Command

Description

Realtime

Toggles whether the viewport updates in realtime, or only when clicked on / moused over. By default, it is turned off, and you may need to click in the viewport once after the mesh is loaded in order to get streamed textures displaying at high resolution. (CTRL + R)

Show Status

Toggles showing stats in the viewport. If Realtime is not enabled, Show Stats automatically enables it. (SHIFT + L)

Show FPS

Toggles showing the frames per second in the viewport. If Show Stats is not enabled, Show FPS automatically enables it. (CTRL + SHIFT + D)

Field of View (H)

Controls the Horizontal Field of View — how much of the left and right of the frame is visible.

Far View Plane

Choose the distance to use as your far view plane. Setting this to zero acts as an infinite far view plane.

Screen Percentage

Sets the percentage of the screen your Preview panel uses.

Layouts

Provides the option to arrange the viewport between one to four panes.

Viewpoint Type



Click image for full size.

Command

Description

Perspective

The default viewpoint used in the viewport, providing a 3D view of your Asset.

Top

Switches the viewport to the top view in 2D. (ALT+J)

Bottom

Switches the viewport to the bottom view in 2D. (ALT+SHIFT+J)

Left

Switches the viewport to the left view in 2D. (ALT+K)

Right

Switches the viewport to the right view in 2D. (ALT+SHIFT+K)

Front

Switches the viewport to the front view in 2D. (ALT+H)

Back

Switches the viewport to the back view. (ALT+SHIFT+H)

Lit



Click image for full size.

Command

Description

Lit

Shows the final result of your scene once all of the Materials and lighting have been applied. (ALT + 4)

Unlit

Removes all lighting from the scene, showing you Base Color only. (ALT + 3)

Wireframe

Toggles the viewmode of the Preview panel between a lit view and a wireframe view. (ALT + 2)

Detail Lighting

Activates a neutral Material across the entire scene, using the normal maps of the original materials. (ALT + 5)

Lighting Only

Shows a neutral Material that is only affected by lighting. (ALT + 6)

Reflections

Overrides all materials with a flat normal and a roughness of 0, which is a mirror.

Player Collision

Renders a color-coded view of what a Player or Pawn can collide with. Static Mesh collision displays as green, Volumes as pink, and Brushes as a grayish-violet.

Visibility Collision

This setting will render a color-coded view of what Actors in the scene will block visibility traces. Static mesh collision displays as green, volumes as pink, and brushes as a grayish-violet.

Optimization Viewmodes

Select from the following options:

Light Complexity: Renders a view showing where raw light overlaps.

Lightmap Density: Renders a view of lightmap density in the scene, with blue being the least dense and red being the most dense.

Stationary Light Overlap: Renders a view of where stationary lights overlap.

Shader Complexity: Renders a view of the shader complexity in a scene. Light green is the least complex, moving to darker greens as complexity increases, and the most complex areas are in red.

Shader Complexity and Quads: Renders a view with both shader complexity and quad overdraw displayed.

Quad Overdraw: Renders a view with just quad overdraw complexity displayed.

Material Texture Scales: Visualize the accuracy of the material texture scales used for texture streaming.

Required Texture Resolution: Visualize the ratio between the currently streamed texture resolution and the resolution wanted by the GPU.



Level of Detail Coloration

Select from the following options:

Mesh LOD Coloration: Renders the scene using LOD color visualization.

Hierarchical LOD Coloration: Renders the scene using HLOD color visualization.



Command

Description

Player Collision

Renders a color-coded view of what a Player or Pawn can collide with. Static Mesh collision displays as green, Volumes as pink, and Brushes as a grayish-violet.

Visibility Collision

This setting will render a color-coded view of what Actors in the scene will block visibility traces. Static mesh collision displays as green, volumes as pink, and brushes as a grayish-violet.

Command

Description

Auto

Enable or disable automatic exposure.

EV100

Allows you to set the exposure value when Auto exposure is disabled.

Show



Click image for full size.

Command

Description

Sockets

Displays any sockets that have been applied to this mesh. For more information about sockets, refer to Skeletal Mesh Sockets (ALT + S)

Vertices

Toggles display of vertices in the Preview panel. (ALT + V)

Vert Colors

Toggles visibility of vertex colors.

Normals

Toggles display of vertex normals in the Preview panel. (ALT + N)

Tangents

Toggles display of vertex tangents in the Preview panel. (ALT + T)

Binormals

Toggles display of vertex binormals (orthogonal vector to normal and tangent) in the Preview panel. (ALT + B)

Show Pivot

Toggles visibility of the mesh's pivot point. (ALT + P)

Grid

Toggles visibility of the grid in the Preview panel.

Bounds

Toggles display of the bounds of the Static Mesh.

Simple Collision

Toggles display of the simplified collision mesh of the Static Mesh, if present.

Complex Collision

Toggles display of the complex collision for this Static Mesh.

Physical Material Masks

Toggles physical material masks.

LOD



Click image for full size.

Command

Description

LOD Auto

Automatically sets Level of Detail (LOD).

LOD 0

Forces LOD 0.

Details Panel



Click image for full size.

The Details panel shows specific properties pertaining to the Static Mesh Actor, such as the Materials applied to the surface, LOD options, and mesh reduction options.

For information about the basics of using this panel, refer to the Level Editor Details Panel documentation.

Bottom Toolbar



Click image for full size.

Command

Description

Content Drawer

Opens a temporary Content Browser (Ctrl+Spacebar).

Output Log

Debugging tool that prints out useful information while your application is running.

CMD

Executes the following command options:

CMD: Executes Unreal Console commands

Python: Executes Python scripts, including files.

Python (REPL): Executes a single Python statement and shows its results.



Source Control Off

Signals if Source Control is disabled or active. Provides the followiing options once active:

View Changelist: Opens a dialog displaying the current changelist.

Submit Content: Opens a dialog with check in options of content and levels.

Checkout Modified Files: Opens a dialog to checkout any assets which have been modified.

Connect to Source Control: Opens a dialog to perform source control operations on content and levels.



Controls

Mouse Controls

Viewport Panel

LMB + Drag - If the camera is locked, rotates the mesh around its Z-axis and moves towards or away from the origin. Otherwise, rotates the camera around its Z-axis and moves the camera along its local X-axis.

RMB + Drag - If the camera is locked, rotates the mesh. Otherwise, rotates the camera.

LMB + RMB + Drag - If the camera is not locked, moves the camera along its local YZ plane.

Keyboard Controls

Ctrl + R - Toggles realtime in the Preview panel.

L + Mouse Move - Rotates the preview light in the Preview panel.

Camera Hotkeys

Alt+H - Position camera to the Front Orthographic view.

Alt+J - Position camera to the Top Orthographic view.

Alt+K - Position camera to the Side Orthographic view.

Alt+G - Position camera to the Perspective view.

Script Setup and Installation

Creating Morph Targets

Material Setup

Morph Targets provide a way to deform a mesh from its base form towards a target form. Generally, these are used with SkeletalMeshes as part of the Animation system; however, using the StaticMeshMorpher.ms maxscript and the StaticMeshMorphTarget Material Function, StaticMeshes also have the ability to be setup for deformation using morph targets.

This method performs the deformation by using multiple UV channels, vertex colors, and the WorldPositionOffset. The offsets of the vertices for each morph target are stored as vertex colors in a UV channel. The StaticMeshMorphTarget Material Function then extracts these and makes them available within the Material. By passing them to the WorldPositionOffset input of the material, the vertices of the mesh can be transformed to the positions of the vertices in the morph target.

Script Setup and Installation

The StaticMeshMorpher.ms maxscript is located in your build at UE4/Engine/Extras/FX_tools/3DSMax2012_x64/.

To run the StaticMeshMorpher.ms maxscript:

In 3dsMax, in the MAXScript menu choose Run Script....

Navigate to the location of the StaticMeshMorpher.ms maxscript in your build and open it.

The script's interface is displayed and ready to be used.

The script can also be bound to a key combination or added to a custom menu to make running it faster and easier.

Creating Morph Targets

Morph targets require multiple instances of the same mesh with their vertices transformed. For example, a melting ball of ice could have three forms:







Game Model

Morph Target 1

Morph Target 2

The morph targets are packed into UV channels 2 and 3 (assuming two morph targets are being packed), and the normals for morph target 1 can also be stored in the mesh's vertex colors if desired.

To pack morph targets:

Press the button and then select the game model mesh in the scene.



Press the button and then select the mesh for the first morph target in the scene.



Repeat the process above for the second morph target in the scene, if one exists.



Check the Store Morph 1 Normals checkbox if desired.

Press the button to begin the process of packing the morph targets into the UV channels.



The mesh can be exported from 3dsMax and imported into Unreal normally. See FBX Static Mesh Pipeline for details on this process.

Material Setup

The StaticMeshMorphTargets function provides access to the morph targets and normals inside the Material applied to the StaticMesh. This function has two outputs corresponding to the two morph targets and one output for the normals. The morph target outputs provide values that can be plugged into the WorldPositionOffset input channel of the Material node, while the normal output, as you might expect, can be connected to the Normal input channel of the Material node.

In order to allow for morphing between the base mesh and the morph targets, one or more LinearInterpolate expressions are used with a single ScalarParameter driving the Alpha input. This allows the morph targets to be driven at runtime by gameplay code or Matinee.

An example setup (only the morph network) is shown here:



The result as the Time parameter in the network above goes from 0 to 1 is shown below:



Set Up

Creating Your First Socket

Attaching Objects to a Static Mesh

Detaching

Creating a Doorway With a Solid Door

Creating a New Socket

Attaching the Door to the Frame

While making your Level in Unreal Engine, there may come a time when you want to attach something to your Static Mesh. You could parent an object to the Static Mesh in the World Outliner. However, you still have to position it in the exact place you want it on your mesh, which can get tedious. Sockets are attach points you can place on your Static Mesh. Once set up, you can connect objects to the Socket. This tutorial will show you how to create a Socket for your Static Mesh and use it for your Level.

Set Up

If you already have a project that you are working on, you can use that project to follow along. If you do not, start out by launching Unreal Engine and creating a new project with Starter Content enabled. For this guide the First Person Template is used, but you can use whichever template you would like. For more information on creating new projects in Unreal Engine, refer to Creating a New Project.

Once your project is open, find the Starter Content folder within the Content Browser. Next, navigate to the Props folder and find the Static Mesh named SM_DoorFrame.

If you are working on a project but didn't enable Starter Content, you can import the Assets from the Content Browser. Choose Add Feature or Content Pack from the Add dropdown menu. Refer to Content Browser Interface for more information.



Click image for full size.



Click image for full size.

Open SM_DoorFrame in the Static Mesh Editor by doing one of the following:

Double-clicking the Asset.

Right-clicking the Asset and selecting Edit from the context menu.

After, the door frame will appear in the Static Mesh Editor, as shown below.



Click image for full size.

Creating Your First Socket

With the Static Mesh opened in the Static Mesh Editor, you can create a socket to place a fire particle in the middle of the doorway.

To start, click the Window dropdown menu at the top of the Static Mesh Editor and select Socket Manager.



Click image for full size.

The Socket Manager window will appear next to the Details panel, as shown below. Once opened, click Create Socket ( ).



Click image for full size.

After clicking the button the Socket is created and you are prompted to rename it. In this example, Fire is used.



Click image for full size.

Looking at your Static Mesh in the Viewport, you can see a translation widget for the Socket. If not, make the Socket visible by clicking it in the Viewport or the Socket Manager panel.



Click image for full size.

Once you can see the Socket, you may notice the location is incorrect. By default, when you create a new Socket, it is located at the origin of the Static Mesh. In this case, the bottom center of the door frame.

You can use the translate widget in the Viewport to move the Socket manually to the desired location or change its relative location, rotation, and scale from within the Socket Manager panel. For this guide, you want the Socket in the middle of the doorway so the player will have to walk through fire as they go through the door.

Change the value of Z in its Relative Location from 0 to 115, as shown in the image below.



Click image for full size.

Attaching Objects to a Static Mesh

With a Socket placed on Static Mesh, you can begin to attach objects to your Static Mesh in your Level.

Click Save in the Toolbar inside the Static Mesh Editor and return to the Level Editor.

Find SM_DoorFrame inside your Content Browser and drag a copy into your Level. Next, go to the Particles folder inside the Starter Content folder and find the Asset named P_Fire.



Click image for full size.

Drag a copy of P_Fire into your Level as well. This particle effect will serve as the fire attached to SM_DoorFrame.

Once you dragged in an instance of P_Fire, right-click the particle inside the Viewport to open the context menu.



Click image for full size.

In the context menu, select Attach To. Inside the search box, type Door Frame and select SM_DoorFrame.



Click image for full size.

Once you select SM_DoorFrame, choose where you want to attach the object. The list consists of None and every Socket you created for your Static Mesh. Select Fire from the list.



Click image for full size.

In the Outliner, P_Fire is now a child of SM_DoorFrame, but you may notice the particle effect did not snap to the location of the Socket. For that to happen, you need to reset the transform location of the particle effect.



Click image for full size.

With P_Fire selected go to the Transform section of the Details panel. To the far right of the Location bar click the reset arrow ( ) to change the settings back to default.

As a child of SM_DoorFrame, the particle effect's location is now relative to its parent. Therefore the transform values reset to 0,0,0 as it snaps to the Socket.



Click image for full size.

The particle effect is now attached to your Static Mesh.



With the particle effect attached to the Static Mesh via its Socket, you can still move, rotate, and scale the particle effect separately from the Static Mesh. However, any transformations made to the Static Mesh also affect any objects attached.

Detaching

Detaching an object from a Static Mesh follows similar steps as attaching an object.

Right-click on the object you want to detach, and select Detach from the context menu. The object is no longer a child of the Static Mesh.



Click image for full size.

Creating a Doorway With a Solid Door

Now that you have used Sockets to create a fiery doorway, it is time to create something more practical.

In the Props folder within the Starter Content, find SM_DoorFrame and drag another copy of it into the Level. Next, find SM_Door, and drag it into the Level.



Click image for full size.

You could attach the door to the door frame using the Socket already created, but there is a problem. The Static Mesh SM_Door has an origin at the bottom corner, so attaching the door to the Fire Socket will leave the door floating in the air and bursting through the corner of the doorway. To fix this problem, you are going to make another Socket.

Creating a New Socket

Reopen SM_DoorFrame in the Static Mesh editor and add a new Socket in the Socket Manager panel. Name the Socket door, so later you know this is where you want to attach the door mesh.

You can manually move the Socket using the 3D widget, or you can move it by changing the relative location, rotation, and scale from within the Socket Manager panel. For this example, changing the Socket's relative location's value of Y to 42 places the Socket at the bottom corner of the door frame mesh.



Click image for full size.

If you do not see the sockets, highlight the Sockets Button so that sockets are visible.



Click image for full size.

Attaching the Door to the Frame

Now that you have a socket to attach the door to the frame, save your door frame mesh and return to the Level Editor.

Select the instance of the door mesh in your Level and right-click to bring up its context menu.

From within the context menu, select Attach and search for SM_DoorFrame.

Find the instance of the door frame you want to attach the door to and select it. When asked which Socket to connect to to, select Door.



Click image for full size.

By default, SM_Door will not have a collision set. If you play the Level now, the player can walk through the solid door, which is not very useful. Set a Simple Box Collison for the door inside the Static Mesh Editor. Refer to Setting Up Collisions with Static Mesh to learn how.

After setting the collision, use Blueprints for scripting a behavior for the door to open and close. Learn how with the Opening Doors guide.

UV Channels in the Static Mesh Editor

Listing UV Channels

Visualizing a UV Channel

Removing a UV Channel

Creating UV Mappings

Option 1: Unwrapping the Mesh Geometry

Option 2: Projecting Mesh Geometry into a UV Channel

UV Channels in Editor Scripting

A UV Channel is a set of data within a Static Mesh that maps each of the mesh's vertices to coordinates in 2D space. These mappings define how 2D texture maps get wrapped around the 3D geometry when the mesh is rendered.

You typically create and manage your UV mappings in a dedicated modeling tool—the same tool you use to create the geometry of your Static Mesh. However, the Editor does offer a few possibilities for working with the UV Channels of your models, outlined below on this page.

UV Channels have two main purposes in the Engine:

Texture coordinates in Materials: When you create a Material that samples a texture map and applies it to the surface of a Static Mesh, you can use a Texture Coordinate (or Texcoord) node to specify a UV Channel. The Material uses the mapping between 2D coordinates and 3D vertex positions contained in the selected UV Channel to determine which areas of the texture should be used to shade what triangles in the 3D model.

For example, UV Channel 0 in this simple plane Static Mesh (shown at the top right of the following image) shows the simplest way to map the two triangles of the mesh (A and B) into texture space. When you use this UV Channel (set by the Coordinate Index property of the TexCoord node), the Material applies the full width and height of a texture to the plane.



Click image for full size.

On the other hand, the image below shows UV Channel 1, which rotates and skews the mapping between the triangles and the UV texture space. When the same image texture is applied to the Static Mesh, it changes what parts of the texture get applied to what parts of the Static Mesh.



Click image for full size.

Triangles in the UV mapping can overlap. An overlap just means that the same part of the texture gets applied to multiple parts of the 3D Static Mesh geometry.

The U in "UV channel" refers to the horizontal axis of the texture; the V refers to the vertical axis. Texture coordinates are usually kept between 0 and 1, where (0,0) represents the bottom left of the texture, and (1,1) represents the top right. However, this is not always true. By default, when a U or V value exceeds 1 or is below 0, the Material will "wrap" around to the other side of the texture. For example, a V value of 1.25 is usually treated as 0.25. However, you can choose to clamp these values instead in your Material, limiting them to a minimum value of 0 and a maximum value of 1.

Lightmaps: UV channels are also used to store and apply lightmaps. A lightmap is a special kind of texture that stores precomputed lighting information for Static Meshes. When you have lights in your Level that have their Mobility setting set to Stationary or Static, and you build the lighting for your Level, the Lightmass tool saves the indirect lighting (and direct lighting for Static lights) to lightmap textures, using a UV channel to determine the mapping between the 3D geometry of the Static Mesh and the 2D texture space.

UV channels used for lightmaps have to follow some special rules. Because every part of an object usually receives different amounts of lighting, no two triangles in the mesh can overlap in the 2D texture space. Each triangle must cover its own area in the texture. In addition, all UV coordinate values must fall between 0 and 1. Lightmap textures can not "wrap around" the same way as regular texture mappings.For these reasons, lightmap UVs are typically generated—or packed—from simpler UV mappings.

For example, this pillar's texture mapping UV channel maps the geometry of each of the four sides to the same overlapping areas of the texture. When you use this UV channel to apply a texture to the geometry, each of the sides uses the same parts of the texture.



Click image for full size.

However, in the object's lightmap UV, each side needs to cover its own unique area of 2D space:



Click image for full size.

For more information on lightmap UVs and how to generate them, see Understanding Lightmapping in Unreal Engine and Generating Lightmap UVs.

Each Static Mesh in the Engine can have up to seven different UV Channels, so you can set up multiple different ways of wrapping textures for different Materials (or for different texture sampling nodes within a single Material).

UV Channels in the Static Mesh Editor

In the Static Mesh Editor UI, you can list, visualize, and remove UV Channels.

Listing UV Channels

When you have any Static Mesh Asset open in the Static Mesh Editor, you can use the UV button in the Toolbar to list all the UV Channels in use by the current Static Mesh.



Click image for full size.

Visualizing a UV Channel

Select any UV Channel in the list to visualize the mapping of the mesh's triangles into 2D texture space as an overlay in the Viewport:



Click image for full size.

Select None at the top of the list to hide the UV overlay.

Removing a UV Channel

When you have a channel selected in the list, you can remove it. Each UV Channel stores texture coordinates for each vertex as part of the Static Mesh, so you may be able to save some runtime memory by removing any mappings you don't use.



Click image for full size.



Click image for full size.

All other UV Channels that were present in the list after the deleted channel are moved up one spot to fill the empty space left by the removed channel.



Click image for full size.

You can't delete a UV Channel if your Static Mesh Asset is set up to generate lightmap UVs, and the UV Channel you have selected is already in use as the source or destination channel for lightmap UVs. Either deactivate the Build Settings > Generate Lightmap UVs option, or change the Build Settings > Source Lightmap Index and Build Settings > Destination Lightmap Index settings to point to different UV Channels.

Creating UV Mappings

When a Material uses textures as source data for its channels (like its Base Color, Normal Map, Roughness, and so on), it typically uses the model's UV mapping to determine what parts of those textures get wrapped around what parts of the geometry. Therefore, when a model does not have any UV mappings, or it has UV mappings that are poorly laid out, you'll often see visible problems when you try to use a textured Material. For example, if the UV mapping has many seams—places where triangles that are adjacent on the mesh geometry are not adjacent in the UV mapping—the texture will show a visible joint at that seams. Or, if your UV mapping assigns areas of UV space unevenly to the triangles of the mesh—so that big triangles on the mesh are mapped to small areas of the texture or vice-versa—the texture will look stretched or distorted on different parts of the mash.

For best artistic results, you should always try to create the UV mappings for your 3D objects in a dedicated modeling tool. However, this is not always possible. For example, when you import data from some types of CAD modeling applications into Unreal Engine, there may be no way for you to create a high-quality UV mapping in your source application. For these cases, you can create UV mappings in the Unreal Editor.

The Unreal Editor offers two ways to create UV mappings for a Static Mesh:

Option 1: Unwrapping the Mesh Geometry

Option 2: Projecting the Mesh to 2D space

Project Setup: In order to use either of the UV channel generation methods outlined below, you must install the UV Editor Plugin for your Unreal Engine project.



Click image for full size.

In this approach, the triangles that make up your Static Mesh geometry are automatically unfolded and flattened. The surface area of the triangles is automatically adjusted to preserve the adjacency of neighboring triangles, and seams are introduced anywhere the angle between adjacent surfaces crosses a threshold you set.

To unwrap a Static Mesh into a new UV mapping:

Choose the Static Mesh you want to unwrap, and do either of the following:

Right-click your Static Mesh in the Content Browser and select Unwrap UV from the context menu.



Click image for full size.

Open the Static Mesh that you want to generate in the Static Mesh Editor. Then, from the Toolbar of the Static Mesh Editor, select UV > Unwrap UVs.



Click image for full size.

If you don't see either menu option, make sure that you have enabled the Polygon Editing Plugin for your project.

Set up parameters to control the results of the unwrapping:



Click image for full size.

Setting

Description

Channel Selection

Determines how the unwrapping process chooses what channel to save the new UV mapping to.

Automatic Lightmap Setup: Saves the unwrapped UV mapping to the channel that is set for this Static Mesh as the source for Lightmap UVs, then generates new lightmap UVs from the new UV mapping.

First Empty Channel: Saves the unwrapped UV mapping to the first empty UV channel in the Static Mesh.

Specify Channel: Choose this option to specify a channel index in the UVChannel setting.

UVChannel

When Channel Selection is set to Specify Channel, use this setting to determine the index of the UV channel that the unwrapped UV is saved to.

Angle Threshold

Determines the maximum angle between two adjacent faces for those faces to remain connected after unwrapping. Raising this value minimizes the number of separate UV "islands", keeping more triangles connected to their neighbors and reducing the number of seams that may cause breaks in texture mapping. However, this may also introduce more distortion in the wrapped textures, as triangles may need to be more aggressively resized in 2D space in order to remain connected to their neighbors.

Click Proceed.

You can project the 3D geometry of your Static Mesh into 2D texture space using a projection volume: a plane, box, or sphere. In this approach, each face of your Static Mesh is projected outward on to the faces of the projection volume, then the projection volume is unwrapped into 2D texture space.



This feature currently only handles projecting the 3D mesh to 2D, not the full projection editing capabilities found in a full-featured modeling and texturing tool.



Open the Static Mesh that you want to generate in the Static Mesh Editor.

For example, double-click the Static Mesh Asset in the Content Browser.

In the Toolbar of the Static Mesh Editor, select UV > Generate UVs.

If you don't see this menu option, make sure that you enable the Polygon Editing Plugin for your project.

You'll see the Generate UV panel appear, offering a set of controls that help you control the results of the UV projection.



Click image for full size.

You'll also see a green volume appear around your Static Mesh in the Viewport, with a standard Unreal Editor manipulator gizmo.

If the volume and manipulator don't appear at first, toggle the Show Gizmo button at the bottom of the Generate UV panel.

In the Projection Type setting, choose the volume that best fits the dimensions of your Static Mesh.

Adjust the size, position, and rotation of the volume to match the extents of your Static Mesh.

To do this, you can use the manipulator in the Viewport or the text fields in the Generate UV panel. You can also use the Fit button to make the volume fit extents of the Static Mesh geometry automatically as a good starting point.

In the Target Channel setting, set the index of the channel where you want to save the projected UV mapping.

Most Materials get texture coordinates from channel 0. If you're generating a UV mapping to improve the way textures map around your Static Mesh geometry, you'll typically want to set 0 in this field.

Click Apply to generate the UV mapping and save it to the target channel in the Static Mesh.

The following table describes all the settings in the Generate UV panel:

Setting

Description

Projection Type

The volume that the Static Mesh geometry is projected to.

Size

The dimensions of the projection volume.

Position

The position of the projection volume relative to the pivot point of the Static Mesh.

Rotation

The rotation of the projection volume relative to the pivot point of the Static Mesh.

UV Tiling Scale

The scale of the projection in UV space. Larger values make the projection larger in texture space, which results in texture details appearing smaller when wrapped around the surface of the mesh.

UV Offset

Controls the placement of the projection in 2D texture space. Smaller values on the X axis move the projection to the left in the UV mapping; larger values move the projection to the right. Smaller values on the Y axis move the projection upward in the UV mapping; larger values move the projection downward.

Target Channel

The index of the UV channel where the projection will be saved. This can't be the same channel as the one being used by the Static Mesh Editor to store generated lightmap UVs. If the target channel already contains data, the Editor will ask for confirmation before proceeding.

Show Gizmo

Toggles rendering the projection volume and manipulator gizmo in the Viewport.

Apply

Generates the UV projection according to the settings above and saves the result to the Target Channel.

Fit

Makes the size of the projection volume enclose the full geometry of the Static Mesh.

UV Channels in Editor Scripting

You can also work with UV Channels in Blueprint and Python scripts that you run in the Unreal Editor. You can do everything that you can do in the Static Mesh Editor, plus you can add new channels and generate new UV mappings.

Prerequisite: If you haven't already done so, you'll need to install the Editor Scripting Utilities Plugin. For details, see Scripting and Automating the Editor.

Choose your implementation method:

Blueprints

Python

You'll find the nodes you'll need to manage UV Channels under the Editor Scripting > Static Mesh category.

To use these nodes, your Blueprint class must be derived from an Editor-only class, such as the PlacedEditorUtilityBase class. For details, see Scripting the Editor using Blueprints.

All of these functions work with a Static Mesh Asset, which you'll typically need to load by calling the Editor Scripting > Asset Library > Load Asset node.

Modifying UV Channels modifies the Asset. Assuming you want to keep the changes you make, you'll also need to use a node like Editor Scripting > Asset Library > Save Asset or Save Loaded Asset afterward. See the examples below.

Listing UV channels

You can use the Get Num UV Channels node to find out how many UV Channels currently exist in a given Static Mesh Asset.

For example:



Click image for full size.

Removing a UV Channel

Each UV Channel stores texture coordinates for each vertex as part of the Static Mesh, so you may be able to save some runtime memory by removing any mappings you don't use.

To remove a UV Channel, call the Remove UV Channel node. Pass it the Static Mesh Asset and the index of the UV Channel that you want to remove.

For example:



Click image for full size.

All other UV Channels that were already present in the list after the specified index are moved up one spot, to fill the empty space left by the removed entry.

You can't delete a UV Channel if your Static Mesh Asset is set up to generate lightmap UVs, and the UV Channel you have selected is already in use as the source or destination channel for lightmap UVs. Either deactivate the Build Settings > Generate Lightmap UVs option, or change the Build Settings > Source Lightmap Index and Build Settings > Destination Lightmap Index settings to point to different UV Channels.

Adding a New UV Channel

You can add a new UV Channel to your Static Mesh Asset by calling either of the following nodes:

Add UV Channel - Adds the new channel at the end of the existing list of channels.

Insert UV Channel - Adds the new channel at the index you specify, moving each other UV Channel down one number in the list. Note that the array of UV Channels can't be sparse: you can only insert a new channel at a position in the list that is next to another existing channel. For example, if there are three UV Channels in the list (indices 0, 1, and 2), you can add a new one with index 3, but not with index 4.



Click image for full size.

The new mapping is empty. You'll want to fill it somehow before you use it—either by projecting the mesh geometry (see below) or by using it as the destination for lightmap generation.

Unwrapping Mesh Geometry into a UV Channel

You can create new UV mappings by having the Static Mesh Editor automatically unfold and flatten the triangles that make up your Static Mesh geometry. The surface area of the triangles is automatically adjusted to preserve the adjacency of neighboring triangles, and seams are introduced anywhere the angle between adjacent surfaces crosses a threshold you set.

Project Setup: In order to use the UV channel generation method outlined below, you must install the Polygon Editing Plugin for your Unreal Engine project.

Use the Generate Unwrapped UVs node. You'll need to give this node:

A reference to the Static Mesh Asset you want to modify,

The index of the UV channel where you want the unwrapped UV to be saved. If this channel does not exist yet, the unwrapping process will create it.

The maximum angle between two adjacent faces for those faces to remain connected after unwrapping. Raising this value minimizes the number of separate UV "islands", keeping more triangles connected to their neighbors and reducing the number of seams that may cause breaks in texture mapping. However, this may also introduce more distortion in the wrapped textures, as triangles may need to be more aggressively resized in 2D space in order to remain connected to their neighbors.

For example:



Click image for full size.

Projecting Mesh Geometry into a UV Channel

You can create new UV mappings by projecting the triangles in the Static Mesh onto a 2D plane or a simple 3D volume.

Each of the nodes described below saves the UV mapping it creates into a UV Channel that you specify. This UV Channel must already exist; if it doesn't exist, the function will not create it.

Use the Generate Planar UV Channel node to project your Static Mesh geometry onto a plane. Use this kind of projection if only one side of your Static Mesh needs to have textures wrapped around it.

For example:



Click image for full size.

Use the Generate Cylindrical UV Channel node to project your Static Mesh geometry onto the sides, top and bottom of a cylinder.

For example:



Click image for full size.

Use the Generate Box UV Channel node to project your Static Mesh geometry onto the faces of a cube.

For example, the following script creates a box the same approximate size as the Static Mesh, then creates a new UV mapping by projecting the geometry of the Static Mesh onto the sides of that box:



Click image for full size.

You'll find the LOD management functions in the unreal.EditorStaticMeshLibrary class.

All of these functions work with a Static Mesh Asset, which you'll typically need to load by calling a function like unreal.EditorAssetLibrary.load_asset.

Modifying UV Channels modifies the Asset. Assuming you want to keep the changes you make, you'll also need to use a function like unreal.EditorAssetLibrary.save_asset or unreal.EditorAssetLibrary.save_loaded_asset afterward.

Listing UV channels

You can use the unreal.EditorStaticMeshLibrary.get_num_uv_channels function to find out how many UV Channels currently exist in a given Static Mesh Asset.

For example:

Removing a UV Channel

Each UV Channel stores texture coordinates for each vertex as part of the Static Mesh, so you may be able to save some runtime memory by removing any mappings you don't use.

To remove a UV Channel, call the unreal.EditorStaticMeshLibrary.remove_uv_channel function. Pass it the Static Mesh Asset and the index of the UV Channel that you want to remove.

For example:

All other UV Channels that were already present in the list after the specified index are moved up one spot, to fill the empty space left by the removed entry.

You can't delete a UV Channel if your Static Mesh Asset is set up to generate lightmap UVs, and the UV Channel you have selected is already in use as the source or destination channel for lightmap UVs. Either deactivate the Build Settings > Generate Lightmap UVs option, or change the Build Settings > Source Lightmap Index and Build Settings > Destination Lightmap Index settings to point to different UV Channels.

Adding a New UV Channel

You can add a new UV Channel to your Static Mesh Asset by calling either of the following functions:

unreal.EditorStaticMeshLibrary.add_uv_channel - Adds the new channel at the end of the existing list of channels.

unreal.EditorStaticMeshLibrary.insert_uv_channel - Adds the new channel at the index you specify, moving each other UV Channel down one number in the list. Note that the array of UV Channels can't be sparse: you can only insert a new channel at a position in the list that is next to another existing channel. For example, if there are three UV Channels in the list (indices 0, 1, and 2), you can add a new one with index 3, but not with index 4.

For example:

The new mapping is empty. You'll want to fill it somehow before you use it—either by projecting the mesh geometry (see below) or by using it as the destination for lightmap generation.

Unwrapping Mesh Geometry into a UV Channel

You can create new UV mappings by having the Static Mesh Editor automatically unfold and flatten the triangles that make up your Static Mesh geometry. The surface area of the triangles is automatically adjusted to preserve the adjacency of neighboring triangles, and seams are introduced anywhere the angle between adjacent surfaces crosses a threshold you set.

Project Setup: In order to use the UV channel generation method outlined below, you must install the Polygon Editing Plugin for your Unreal Engine project.

Use the unreal.UVGenerationFlattenMapping.generate_flatten_mapping_u_vs() function. Pass it:

A reference to the Static Mesh Asset you want to modify,

The index of the UV channel where you want the unwrapped UV to be saved. If this channel does not exist yet, the unwrapping process will create it.

The maximum angle, in degrees, between two adjacent faces for those faces to remain connected after unwrapping. Raising this value minimizes the number of separate UV "islands", keeping more triangles connected to their neighbors and reducing the number of seams that may cause breaks in texture mapping. However, this may also introduce more distortion in the wrapped textures, as triangles may need to be more aggressively resized in 2D space in order to remain connected to their neighbors.

For example:

Projecting Mesh Geometry into a UV Channel

You can create new UV mappings by projecting the triangles in the Static Mesh onto a 2D plane or a simple 3D volume.

This is currently only exposed in the Unreal Editor scripting APIs, not in the UI of the Static Mesh Editor. However, the process and the settings required by the API are easier to understand if you are already familiar with visual tools for mesh projection, such as those in 3ds Max. See the UVW Map Modifier in the 3ds Max Help for background.

Each of the functions described below saves the UV mapping it creates into a UV Channel that you specify. This UV Channel must already exist; if it doesn't exist, the function will not create it.

Use the unreal.EditorStaticMeshLibrary.generate_planar_uv_channel function to project your Static Mesh geometry onto a plane. Use this kind of projection if only one side of your Static Mesh needs to have textures wrapped around it.

For example:

Use the unreal.EditorStaticMeshLibrary.generate_cylindrical_uv_channel function to project your Static Mesh geometry onto the sides, top and bottom of a cylinder.

For example:

Use the unreal.EditorStaticMeshLibrary.generate_box_uv_channel function to project your Static Mesh geometry onto the faces of a cube.

For example, the following script creates a box the same approximate size as the Static Mesh, then creates a new UV mapping by projecting the geometry of the Static Mesh onto the sides of that box:

Steps

End Result

To control when one Level Of Detail (LOD) Static Mesh transitions into another one, Unreal Engine 5 (UE5) uses the current size of the Static Meshes size in Screen Space. While this method of controlling LOD transitions works quite well the numbers used for one platform might not work for another one. In the following How - To we will take a look at customizing the LOD Screen Size for each platform your UE5 project can be used on.

Steps

In the following section we will take a look at how to specify the Screen Size at which LOD transactions should take place on a per platform basis.

First, inside the Content Browser, locate a Static Mesh that has a few LODs to work with and open it up inside the Static Mesh Editor. For this example the Static Mesh that was selected has four LODs however you can pick one that has more or less depending on the needs of your project.



Click image for full size.

Once the Static Mesh is open in the Static Mesh Editor, go to the Details Panel and expand the LOD Settings category.



Click image for full size.

Disable the checkmark box next to Auto Compute LOD Distances so that we can manually set the distance at which LOD transition should take place.



Click image for full size.

Next, go to the LOD Picker section and enable the Custom option by clicking on the checkmark box next to it. This will allow you to see all LODs at the same time in the Static Mesh editor.



Click image for full size.

Expand the LOD1 section and next to the Screen Size option,click on the small white triangle to expose the option to add per-platform LOD overrides.



Click image for full size.

From the displayed per-platform override list, select the Add Override for Mobile option.



Click image for full size.

Repeat the above step for LOD 2 and LOD 3 and when completed your Details panel should look like the following image.



Click image for full size.

You can now adjust the Mobile Screen size by inputting a new number in the box under the Mobile option. To figure out which screen size you should use for which LOD, the Viewport inside the Static Mesh Editor displays the Current Screen Size.



Click image for full size.

End Result

With the ability to override the distance at which LODs will transition on Mobile devices set, you can now go back and setup the transition distance for Console and PC using the exact same steps if that is required for your project. If you decide to do this then your LOD sections will look like the following image.



Click image for full size.

Modeling Mode contains a variety of tools for creating both simple and complex 3D meshes for all your visualization projects. These tools are designed to streamline the modeling creation process and are compatible with meshes created using traditional workflows, as well as more complex meshes that are generated by photogrammetry.

Here you will find the topics to help you begin creating your own 3D meshes inside Unreal.



Learn the basics of the Modeling editor mode.



Getting started with Modeling Mode and creating 3D assets in Unreal Engine



Learn the use of PolyGroups and how to create them.



Learn about the different tool categories for in-engine modeling.



Overview of the UV Editor interface and tools.



A guide to using Geometry Script Fuctions and Blueprint Nodes



A reference for the Blueprint Nodes and Functions used with Geometry Script.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Accessing the Modeling Editor

Understanding Key Concepts

Terminology

Triangles and PolyGroups

Tools, Undo History, and Accepting Changes

Meshes, Assets, and Project Settings

Using the Modeling Mode

Creating a Mesh

Editing a Mesh

Tool Categories

Geometry Script

The Modeling editor mode, refered to as Modeling Mode, provides a toolset for creating, sculpting, and editing meshes directly in Unreal Engine. You can use it to create new meshes, rapidly prototype level geometry, and edit existing models to add variety to your world. This overview outlines the core concepts behind these tools and their workflow, how to access them, and the basics of working with them.

Accessing the Modeling Editor

To use the Modeling Mode, click the Select Mode dropdown, then select Modeling. Alternatively, press SHIFT+5 to immediately switch to this mode.



The Mode Toolbar (1) and the Modeling panel (2) will appear.



If you select a tool from the Mode Toolbar, its properties will appear in the Modeling panel. You can use this panel to configure your tool's output before you commit to creating a mesh or making changes.

Understanding Key Concepts

Although many tools in Modeling Mode are similar to their counterparts in other modeling software, there are a few important key differences in how Modeling Mode structures mesh editing that you should know before you begin working with it.

Terminology

The modeling tools are usable when you are working on various types of Actors in Unreal Engine, for example, a Static Mesh, a Dynamic Mesh, or a Volume. These are collectively referred to as "a mesh" or "meshes", except for occasions where a tool is only usable for a specific Actor type.

Triangles and PolyGroups

Unreal Engine renders all models as triangulated meshes. In other words, when you import or create a mesh, its surface is automatically broken up into triangles (tris) regardless of whether they were already defined in a different environment. This conversion to triangles provides several guarantees:

UE can't import or create a model that it can't render.

UE's rendering is portable across all platforms, as all graphics drivers universally recognize triangles.

UE does not need to spend time and resources resolving quadrilateral (quad) polygons and n-gons (polygon with more than 4 sides) into triangles at runtime.

In the Modeling editor, you can edit the triangles of your model using the tools in the TriModel category. These are the most low-level editing tools, based entirely around selecting and editing tris and vertices directly.

Although Unreal Engine does not natively recognize quads or n-gons, it does support PolyGroups, which can mimic those features. PolyGroups are arbitrary collections of triangles that various tools in the Modeling editor can define. You can then manipulate these groupings using the PolyModel tools.

When creating a mesh using the Shapes category, you can configure the PolyGroups of your new mesh using the Polygroup Mode setting.



Additionally, you can use the TriSel (Triangle Selection), GrpGen (PolyGroup Generation), and GrpPnt (PolyGroup Paint) tools to assign PolyGroups.



You can then use PolyGroups for traditional modeling using the PolyEd tool and to create UV islands using the UV tools.

To learn more about creating and using PolyGroups, refer to the Understanding PolyGroups documentation.

Tools, Undo History, and Accepting Changes

Most mesh editing tools in the Modeling editor mode will not apply changes to meshes immediately. Instead, the tool shows a preview of the mesh with your changes in place, and a prompt will display the Cancel and Accept buttons.



If you exit Modeling Mode or press Cancel, the changes are discarded, and the mesh will revert to what it looked like before you started editing it. If you press Accept, the Modeling editor applies the changes. It will also apply the changes from a tool if you select a different modeling tool while in the middle of the same editing session.

Unreal Editor keeps an undo history of each operation a tool performs when using the mesh editing tools. For example, if you do several extrude operations using TriEd or PolyEd, using Undo will undo the most recent one first, stepping back through the history of each of your edits.

All tools have an On Tool Accept category in their settings to configure what happens to modeling operations in your undo history. By default, the Handle Inputs setting is set to Delete Inputs. This means after you press Accept, Unreal Editor will treat your mesh editing session as a single operation, and using Undo will revert all the changes you made since the last time you pressed Accept. You can change Handle Inputs to keep some or all of your individual changes.

Meshes, Assets, and Project Settings

The type of Actor you choose to represent your mesh determines how Modeling Mode handles the creation and editing process. When creating a new mesh using the Shapes or Create category, you use Output Type to select the desired Actor. You can choose between the following Actors as your target mesh:

Static Mesh

Represents your model and is saved in the Content Browser. An instance of the mesh is placed in the Level.

Dynamic Mesh

Represents your model and is saved in the Level only.

Volume

Represents an area that triggers a behavior and is saved in the Level only.

These types have various use cases and benefits. You can change the Actor type of the current mesh using editing tools such as Convert and Transfer. Using Project Settings, you can configure the creation and selection of meshes, as well as the saving of Assets.

Refer to the Working with Meshes documentation to continue learning about how output types are handled and how to adjust settings for your workflow.

Using the Modeling Mode

Creating a Mesh

To create a new mesh, click any of the tools in the Shapes category and move your mouse cursor into the Viewport. A template of the shape you selected will follow your cursor and snap to the Level grid. Click where you want to add the mesh in your game's world and the editor will create the shape with the parameters you configured in the Modeling panel.



You can also create meshes using tools in the Create category. For example, the PolyExt tool can draw a footprint for a mesh, then extrude it to create a custom 3D shape.



Editing a Mesh

Most of the other tools in Modeling Mode are built around editing an existing mesh in your game's world. For example, if you select TriEd or PolyEd, then click a mesh, you can select its individual components and perform modeling operations on them. Individual operations in the TriEd and PolyEd tools, such as Extrude, Push Pull, or Cut Faces, appear in the Modeling panel. After you make your edits, click the Accept button at the bottom of the viewport to finalize your changes or click Cancel to discard them.



You can select any mesh in your world and edit it using these tools, including meshes that were not created with the Modeling editor. For example, you can use the Lattice tool on a high-quality Static Mesh to quickly reshape it.

If you are going to edit a high-quality model, it is highly recommended that you duplicate the asset using the MshDup tool to preserve the original mesh.

Tool Categories

Category

Description

Shapes

Creates a new mesh using a selection of predefined primitives.

Create

Build meshes from paths or existing geometry.

PolyModel

Perform granular editing using a mesh's PolyGroups. Only useable if the model has more than one polygroup.

TriModel

Perform granular editing using a mesh's triangles.

Deform

Alter or distort a mesh as a whole or in specific areas.

Transform

Adjust the placement or representation of a mesh.

MeshOps

Optimize a mesh's geometry.

VoxOps

Convert a mesh into voxels to perform volumetric operations before converting it back into a mesh.

Attributes

Inspect and adjust the secondary properties of a mesh.

UVs

Edit the UV coordinates of a mesh, changing how textures are mapped to the surface.

Baking

Generate textures and vertex color data for meshes.

Volumes

Convert between volume, mesh, Binary Space Partitioning (BSP), and Simple Collision representations. You can also inspect the collision and physics properties of the selected mesh.

LODs

Edit and manage the levels of detail (LODs) for a mesh.

To learn more about these tools, refer to the Modeling Tools documentation.

Geometry Script

Geometry Script is an Unreal Engine plugin containing a set of Function Libraries that provide the ability to generate and edit mesh geometry via Blueprints and Python. Geometry Script UFunctions and Blueprint Nodes operate on UDynamicMesh objects, which are objects created using the FDynamicMesh3 C++ triangle mesh data structure. This is the same data structure used by the Geometry Processing plugin and Modeling Editor Mode.

Geometry Script can be used in Editor Utility Widgets and Asset Actions to create custom mesh analysis / processing / editing tools. It can also be used in Actor Blueprints to create "procedural objects" and implement complex geometric queries.

For more information on using Geometry Scripting, refer to the Geometry Script Users Guide.

Output Type

Static Mesh

Dynamic Mesh

Volume

Preview Mesh

Exceptions

Modeling Mode Project Settings

Modeling Mode Quick Settings

Modeling Mode is an editor mode that provides you with the tools to create and edit your own 3D mesh directly in Unreal Engine. Although Modeling Mode works similarly to other modeling software, there are a few key differences in how the editor mode creates new meshes and handles editing that you should know before you begin working with it.

To better understand and use the content of this page, familiarize yourself with Modeling Mode by reading the Modeling Mode Overview documentation.

Output Type

You can create a new mesh using the tools found in the Shapes or Create categories of the Modeling Tools palette:



Unreal Engine uses the Output Type specified in the Modeling panel when creating a new mesh. Output types that are not supported by the selected tool are grayed out.



Static Mesh

A Static Mesh is a type of Actor that represents 3D geometry. When you select Static Mesh as the type, the Actor is saved in your Content Browser as an Asset, and an Actor instance is placed in the Level.



When you accept new edits, the original Static Mesh is updated. These updates apply to any duplicates made in the Viewport, as they are an instance of the same mesh.

To properly create a copy saved separately in the Content Browser, you can use the MshDup (Mesh Duplicate) tool. Using this tool to clone your Static Mesh before you start modeling will ensure that the original Asset remains intact and make it possible to change only individual Static Meshes in your world as needed.

Modeling Mode saves new Static Mesh based on the settings in the Modeling Mode section of the Project Settings. You can quickly customize settings using the New Asset Location property in the Modeling Mode Quick Settings.

Dynamic Mesh

A Dynamic Mesh is an Actor that visually represents a Static Mesh; however, their functions differ. Dynamic Meshes are saved in the Level instead of the Content Browser since it is not an Asset.

Dynamic Meshes can help you create an efficient workflow by saving time on editing because:

No Build step is required

No Asset is created

You can edit duplicates without updating the original mesh

There are a few caveats to know when using Dynamic Meshes:

It is not efficient for rendering and memory.

It is not compatible with Lumen or Nanite.

You can use the Convert tool to change a Dynamic Mesh to a Static Mesh or Volume, and vice versa. This conversion option is beneficial when you are editing a high-resolution mesh with a long Build time after a tool operation.

Volume

A Volume is a type of Actor you can use to alter the behavior of areas in your Level. When selected, the standard Volume Types become available.

To learn about the Volume Types, refer to the Volume Actors in Unreal Engine documentation.

When creating a new Volume using either the Shapes or Create category, the mesh appears similar to a Static or Dynamic Mesh. Once you select Accept, the mesh is represented as a traditional Volume (a 3D outline).

Preview Mesh

After you create a mesh and accept it, your shape is ready for editing. When you edit a mesh using Modeling Mode, the original mesh is hidden and replaced with a preview mesh (Dynamic Mesh Actor). The Dynamic Mesh Actor becomes a container that holds the changes to your mesh until you click the Accept button. Once you accept the changes, Modeling Mode applies the changes and overwrites the existing target output mesh.

While the tool is active, the original mesh can be unhidden by toggling the Visible property under the Rendering category in the Details panel. Once the changes are accepted, they are applied to the existing target output mesh. The preview mesh is destroyed, and the original mesh Actor is unhidden.

Exceptions

Some tools give you the option to overwrite the existing mesh or create new meshes directly. Here are some examples:

Mesh Merge (MshMrg)

Mesh Bool (MshBool)

Trim

Merge

Vox Wrap

Vox Blend (VoxBlnd)

Vox Morph (VoxMrph)



Click image for ful size.

These tools give you the option to create a New Object using the result of your edit or to overwrite the First Input Object or Last Input Object.

There are also tools that create non-mesh Assets. The Baking tools create Texture Assets and saves them in the selected location.

Modeling Mode Project Settings

There are several options for Modeling Mode in the Project Settings you can use to configure the creation and selection of meshses, as well as the saving of Assets. They are found in the Plugins > Modeling Mode and Plugins > Modeling Mode Tools sections.



Click image for ful size.

Property

Description

Default Mesh Object Type

Determines the default mesh type for Modeling Mode tools. Requires an Editor restart to take effect. The following options are available:

Static Mesh Asset

Volume Actor

Dynamic Mesh Actor

Asset Generation Location

Determines where assets generated by Modeling Mode tools are stored by default.The following options are available:

Auto Generated World Relative Asset Path: Stores assets in an auto-generated folder relative to the level they are being saved in.

Auto Generated Global Asset Path: Stores assets in an auto-generated folder located in the Content folder of your project.

Current Asset Browser Path if Available: Stores assets in the folder currently selected in the Content Browser, if available. If not, assets are saved in the auto-generated asset path.

Asset Generation Mode

Determines how assets generated by the Modeling Mode tools are handled. The following options are available:

Auto Generate and Autosave: Generates and automatically saves new assets on creation.

Auto Generate But Do Not Autosave: Generates new assets and marks them as modified.

Interactive Prompt to Save: Generates new assets and prompts you to save them.

Asset Generation Asset Path

Defines the file path where auto-generated assets are saved. This is relative to the parent path defined in the Asset Generation Location. Leaving this blank disables this option.

Store Unsaved Level Assets in Top Level Game Folder

If enabled, determines whether auto-generated assets in an unsaved level are stored relative to the top level Game folder or are stored in the Temp folder. You cannot save assets stored in the Temp folder until they are moved to a permanent location.

Use Per User Autogen Subfolder

If enabled, determines if auto-generated assets are stored in specific user folders within the auto-generated folder.

Autogen Subfolder User Name Override

Overrides the user name used for per-user folders within the auto-generated folder.

Append Random String to Name

Appends a short, random string to the name of auto-generated assets.

Enable Persistent Selections

If enabled, maintains your selection when changing between tools. This feature is Experimental and is disabled by default.



Click image for ful size.

Property

Description

Enable Ray Tracing While Editing

Enables Ray Tracing when using Modeling Mode tools. This affects the performance of tools with real time feedback, such as 3D Sculpting.

Enable Ray Tracing

Enables Ray Tracing for new assets created using the Modeling Mode tools, if support is optional.

Enable Collision

Enables collision for new meshes created using the Modeling Mode tools.

Collision Mode

Determines the default Collision Mode for new meshes created using the Modeling Mode tools. The following options are available:

Project Default

Simple and Complex

Use Simple as Complex

Use Complex as Simple

For more information on these settings, refer to Simple versus Complex Collision.

Modeling Mode Quick Settings

The Modeling Mode Quick Settings are located at the bottom of the Modeling Tools Details panel and contain options for specifying the LOD to display during editing and the location to save new Assets.



Click image for ful size.

Property

Description

Editing LOD

Determines which LOD mesh you are currently editing.

New Asset Location

Determines where the new Asset you are currently creating will be saved. This overrides the current project setting for this Asset.

1 - Creating a Box Primitive

2 - Creating the Outer Frame

3 - Adding Additional Detail

4 - Unwrapping UVs

5 - Bring the Crate into the Level

Result

The Modeling Mode toolset in Unreal Engine is used to create meshes, rapidly prototype new level geometry, and edit existing meshes all without leaving the Editor.



In this quick start, you will create this pine crate using Modeling Mode.

This quick start guide walks you through the creation of a wood crate using several of the tools in Modeling Mode. You start by creating a new primitive shape and add detail using several of the PolyEdit tools. Next, you prepare your model for texturing using the UV tools. Finally, you add a Material and drop it into your Level with full collision and physics simulation.

Prerequisite Topics

Before starting this quick start guide, we recommend you familiarize yourself with Modeling Mode and how Unreal Engine handles 3D models.

Although many tools in Modeling Mode are similar to their counterparts in other modeling software, there are a few key differences in how the Modeling Mode editor structures mesh editing that you should know before you begin working with it.

For more information, see the Modeling Mode Overview.

1 - Creating a Box Primitive

Before you start, create a new project based on the First Person Game template. For more information on creating new projects in Unreal Engine, see Creating a New Project.

Open Modeling Mode by clicking the Select Mode drop down menu and select Modeling. This will open the Mode Toolbar and Modeling panel.



Open Modeling Mode using the Modes dropdown menu.

In the Shapes category at the top of the Mode Toolbar, click Box and adjust the settings in the Modeling panel to your desired size. For this guide, the default settings are fine. This creates a 100 centimeter box that is about half the height of the default character.



Creating a box primitive with the default settings using the Box tool.

Click in the Viewport to create your box, then click Complete at the bottom of the screen or press Enter.

2 - Creating the Outer Frame

Turning your primitive shape into a detailed 3D model begins with defining its PolyGroups.



A box primitive with six defined PolyGroups.

It can be helpful to collapse the sections you are not using in the Mode Toolbar.



Select the box in the viewport. In the Mode Toolbar, find the Attributes section and click GrpGen. This will generate PolyGroups for the box.



Select the GrpGen tool in the Modeling Tools palette.

The default Conversion Mode and settings are fine for this Quick Start, so click the Accept button at the bottom of the viewport or press Enter.



Create your PolyGroups using the default settings.

In the Mode Toolbar, locate the PolyModel tools section and click PolyEd. This will open the PolyEdit tools in the Modeling panel.



Click on PolyEd to view the tool'sparameters in the Modeling panel.

Select one of the faces in the Viewport and click Inset. Move the mouse in the viewport until the face is inset the amount shown in the image below.



Inset the selected face to create the outer frame of the crate.

Click the mouse again to inset the face.

Select the inner face you created and click Extrude. Extrude the face inward to create the outer frame of the crate.



Extrude the inner face inward to finish creating the outer frame. This face has been extruded 5 centimeters.

If grid snapping is enabled in the viewport, the distance that the face extrudes is equal to the Position Grid Snap value set in your Viewport. Adjusting this setting can give you more control during the editing process.

Repeat this process for each side of the crate. Don't forget the bottom face.

3 - Adding Additional Detail

Next, you will add a cross brace to the outer frame of the crate.

In the PolyEd tools, select the inner face you just extruded and click the Decompose button. This will split the face into its component triangles and create an edge from corner to corner.



Useing the Decompose tool on the center face will split the face into two triangles.

Select the new edge you created. Then hold Shift and select the additional edges in the corners connected to the new edge as shown in the image below.



Select the new edge and the two connected corner edges. Bevel them to create a new face that will be used for the cross brace.

With the edges selected, navigate to the Edge Edits section and click Bevel. Leave the settings at the defaults and click the Apply button at the top of the menu. This splits the edge and creates a new face.

You can disable Select Vertices and Select Faces in the Selection Filter section of the Tools Details panel to make selecting individual edges easier.

Select the new face and extrude it until it is level with the outer frame.



Extrude the new face until it is level with the outer frame to create the cross brace.

This creates two inner faces, one at the end of the extruded cross brace and one in the inner corner. Move your camera view inside the crate and select the inside faces as shown below.



Move the camera inside the crate and select the inner face at the end of the cross brace.



Move the camera down and to the left to select the inner face in the corner.

Click Delete or press the Delete key to remove the faces.

The Weld tool joins two edges at the location of the last one selected. Select the two edges shown below.



Move the camera back outside the crate to select the two edges located where the cross beam meets the corner.

Click Weld.

Repeat this process for the other end of the inner frame.

Repeat the process for each side of the crate.

4 - Unwrapping UVs

To display the wood texture correctly, the crate will need to be UV unwrapped.

Since you have made significant changes to the original box shape, click GrpGen and generate new PolyGroups for the crate. Change the Min Group Size to 3 to generate six new PolyGroups (one per side) similar to the image below.



Use the GrpGen tool to generate six new PolyGroups.

Click Accept or press Enter to continue.

Next, go to the UVs section of the menu and select the Unwrap tool. At the top of the Modeling panel, open the Island Generation dropdown menu and select PolyGroups.



Use the Unwrap tool to create a UV map for the crate.

Change the value of the Texture Resolution to 2048. This changes the offset between the UV islands to make sure there are enough pixels between them.



Change the Texture Resolution to 2048 to generate enough space between UV islands.

To see the generated UV map, click the checkbox for the Enabled option in the Preview UV Layout section of the menu. Your UV map will look similar to the image below. Click Accept or press Enter to finalize the UV map.



Enable the UV map preview window.

Finally, check the quality of the generated UV map by adding a wood material to the crate. In the Details panel, open the Materials section and click the dropdown menu for Element 0. Search for the M_Wood_Pine Material and apply it to the crate.



Add the M_Wood_Pine Material in the Details panel.

5 - Bring the Crate into the Level

Make the crate ready for your Level by adding Simplified Box Collision in the Static Mesh Editor and enabling Physics Simulation.

Locate your crate asset in the Content Browser and open it in the Static Mesh Editor. This can be done by navigating to the FirstPerson/Maps/_GENERATED/User folder and double clicking your box asset.



Return to Select mode and open the crate in the Static Mesh Editor.

You will notice that the version of your crate in the Static Mesh Editor does not have the M_Wood_Pine Material applied to it. Adding a Material to a Static Mesh through the Details panel only applies it to that instance of the static mesh. Applying the pine Material in the Static Mesh Editor will apply it to all future instances of the crate.

Click on the Collision menu and select Add Box Simplified Collision to add a basic collision box to the crate.



Open the Collision menu and select Add Box Simplified Collision.

Locate the Collision Complexity section in the Details panel. Open the drop down menu and select Project Default.



Change the Collision Complexity property to Project Default in the Details panel in the Static Mesh Editor.

Back in the Editor window, enable Simulate Physics in the Details panel.



Enable Simulate Physics in the Details panel.

Result

Over the course of this quick start, you created a wood crate Asset using the Modeling Mode toolset, entirely inside the Unreal Editor. You added detail to your model, added a UV map, and a wood Material.

Finally, you added appropriate collision settings and enabled physics to make your crate a game ready Asset.



The final version of the pine crate inside the Level.

Modeling Mode Quick Start

Modeling Mode Overview

The Why and What of PolyGroups

Creating PolyGroups

Triangle Selection Tool

Merge

PolyGroup Paint Tool

PolyGroup Generate Tool

Shapes Tools

Using PolyGroups

Building shapes

Creating UVs

Assigning Multiple Materials to One Mesh

FAQ

The Modeling Mode Overview, introduces you to PolyGroups, and the Quick Start guide shows you how to use some of the tools for assigning PolyGroups. We recommend reviewing these two documents before continuing.

This guide further explores the tools for creating PolyGroups and how you can use these groups in other modeling tools. The goal at the end of this guide is to understand PolyGroups to build an efficient workflow for creating and editing your geometry in-engine.

The Why and What of PolyGroups

In traditional modeling software, you have the option of polygonal modeling. However, Unreal Engine renders all models as triangulated meshes.





A quad based cube in Maya.

The same cube rendered as triangles in Unreal Engine.

The conversion to triangles means Unreal Engine does not natively recognize quads or n-gons, making triangles the foundation on which in-engine modeling is built. To provide an approximation to the traditional modeling workflow, you can use PolyGroups.

PolyGroups are a set of grouped triangles. These groupings are then manipulated using the PolyModel tools, mimicking traditional polygon editing options.

For example, using the cube imported from Maya, we assign a separate PolyGroup to each triangle using the TriSel tool under the TriModel category.

To visualize the PolyGroups being created you can set Face Color Mode to By Group.

With PolyGroups set, you can now use the PolyEd tool under the PolyModel category. However, the current PolyGroups each represent a single triangle, which isn't the best use of the PolyEd tool.



PolyGroups consisting of one triangle – each color indicates a PolyGroup.

When you merge two triangles on one of the sides of the mesh into one PolyGroup, you have the representation of a quad.

In the video using Merge creates a new PolyGroup consisting of two triangles.

When working with low-polygon meshes and blockouts, PolyGroups provide a way to interact with more intuitive surfaces than raw triangles. However, PolyGroups can also be applied to high-polygon meshes to help manipulate chunks of complex geometry, which otherwise would be complicated to edit.

Creating PolyGroups

To better understand PolyGroups, it helps to know the tools you can use to create them. The order in which you use these tools depends on your preferred workflow and needs. The important thing to remember is you can use any set of triangles as a PolyGroup.

Triangle Selection Tool

As shown in the video above, the TriSel tool can assign a PolyGroup to one or more triangles. Instead of selecting one triangle per PolyGroup, we now select two for quad editing using PolyEd.

In the video new PolyGroups are created at the intersection of each edge loop.

Triangles not assigned a PolyGroup are automatically grouped into one.

Merge

When using the PolyEd tool, you can continue combining existing PolyGroups into a new group.

The process of combining existing PolyGroups is destructive, meaning the prior PolyGroups will no longer exist.

In the video each face represents a PolyGroup, and you can group faces using Merge.

PolyGroup Paint Tool

There are dedicated tools for creating PolyGroups, and one is the GrpPnt tool, where you can interactively paint your groupings.

In the video the GrpPnt tool creates new PolyGroups consisting of two triangles. Show Wireframe is enabled to visualize the two triangles in each PolyGroup.

You can use the Action setting to choose any of the following selection modes:

Brush

Fill

Group Fill

Lasso

To see what PolyGroup is assigned, hover over said PolyGroup and use the hotkey Shit + G. The Set Group row will update to the associated number.

PolyGroup Generate Tool

Another dedicated tool for grouping triangles is the GrpGen tool. PolyGroups are automatically assigned upon opening the tool. How the PolyGroups are assigned is determined by the Conversion Mode.

Conversion Mode

Description

Face Normal Deviation

Convert based on Angle Tolerance between face normals.

Find Quads

Create PolyGroups by merging triangle paris into quads.

From UV Islands

Create PolyGroups based on UV islands.

From Hard Normal Seams

Create PolyGroups based on hard normal seams.

From Connected Tris

Create PolyGroups based on connected triangles.

Furthest Point Sampling

Create PolyGroups centered on well-spaced sample points, approximating a surface Voronoi diagram.

Copy From Layer

Copy from existing PolyGroup layer.



PolyGroups are generated by quads (merging triangle pairs).

You can use the Output Layer to create a new PolyGroup layer.

Shapes Tools

When creating meshes using the Shapes tools, you can configure the PolyGroups of your new meshes using the Polygroup Mode setting.



The Polygroup Mode has the following grouping options:







Per Shape

Per Face

Per Quad

Outputs the entire mesh as a single group.

Automatically divide the mesh into recognizable face groups.

Automatically divide the mesh into a group for each quad.

Because PolyGroups are arbitrary, you can also create multiple PolyGroup Layers to handle different sets of them on the same model. You can configure these in the Attributes > AttrEd tool.

PolyGroup Layers are not universal to your project. Instead, they are created for individual static mesh assets. This particular assignment means that you cannot assume that two different meshes will have the same PolyGroup Layers, but it also means that you can define them as needed on a case-by-case basis.

Using PolyGroups

Building shapes

The fundamental use of PolyGroups is geometry editing, as shown with the PolyEd tool.

Additional ways in which PolyGroups help with constructing a mesh include:

Precisely editing regions.

Four PolyGroups are merged into one for extrusion.

Creating holes.

Smoothing a mesh using the Subdivide tool.



Click image to expand.

Creating deformations using the PolyDef tool.

Interior Vertices of a PolyGroup are not selectable, only bordering vertices. To select the interior vertices, use Decompose to deconstruct the PolyGroup.

Creating UVs

You can use PolyGroups to assist in creating UVs for your model. In the Quick Start guide, six PolyGroups are assigned to the crate (one per side). Then UV islands are generated based on the existing PolyGroups.



You can then use the UV tools to deconstruct the UVs further or you can add more PolyGroups.



Additional PolyGroups are assigned to indicate an UV island.

Now when you unwrap your model, more UV islands are created.



To learn more about the UV tools, refer to the UVs Category documentation.

Assigning Multiple Materials to One Mesh

You can assign multiple Materials to your geometry using the MatEd tool. To help visualize what triangles you want to assign the Material, you can select PolyGroups from the Face Color Mode, which is especially helpful for high-density meshes.

FAQ

Is there a way to clear all PolyGroups to start over?

Yes, by using the Clear All option in the GrpPnt tool.

Does it matter if I have PolyGroups consisting of one triangle?

Although you can still edit your mesh using tools such as PolyEd, it may yield unexpected results. For example, when adding an edge loop to a mesh where the top side has two PolyGroups containing one triangle, the loop will slant to the side. If there is one PolyGroup grouping the two triangles (representing a quad), then the loop would continue straight across.





Distorted Edge Loop

Corrected Edge Loop

Does creating PolyGroups interfere with rendering?

No, PolyGroups are just a tool to help perform classic modeling techniques you may be used to in other modeling software. At render time, triangles are still used.

Modeling Mode Overview

Modeling Mode Quick Start

Shapes

Create

PolyModel

TriModel

Deform

Transform

MeshOps

VoxOps

Attributes

UVs

Baking

Volumes

LODs

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Modeling Mode provides an array of tools for creating and editing geometry. These tools are organized into specific categories to help guide you through your modeling process.

The Shapes and Create categories can get you started with building a new mesh. To edit and inspect properties of your mesh you can use the following categories:

PolyModel: Edit a mesh using PolyGroups.

TriModel: Edit a mesh through its triangles.

Deform: Sculpt or distort a mesh as a whole or in specific areas.

Transform: Adjust the placement or representation of a mesh.

MeshOps: Optimize a mesh's geometry.

VoxOps: Convert a mesh into voxels to perform volumetric operations before converting it back into a mesh.

Attributes: Inspect and adjust the secondary properties of a mesh.

UVs: Edit UV coordinates of a mesh.

Baking: Generate textures and vertex color data for meshes.

Volumes: Convert between Volume, mesh, Binary Space Partitioning (BSP), and Simple Collision representations.

LODs: Edit and manage the levels of detail (LODs) for a mesh.

Each tool per category opens a specific toolset and settings in the Modeling panel. Refer to the categories below to learn how to implement them in your workflow.

The modeling tools are usable when you are working on various types of Actors in Unreal Engine, for example, a Static Mesh, a Dynamic Mesh, or a Volume. These are collectively referred to as "a mesh" or "meshes", except for occasions where a tool is only usable for a specific Actor type.

Shapes

Create a new mesh using a selection of predefined primitives shown in the image below.



To learn more, see the Shapes Category documentation.

Create

Build meshes from paths or existing geometry.



Several tools, such as PolyExt and PathExt, use a grid to draw shapes. To control the position of the grid, Ctrl + Click your desired location.

Tool

Description

PolyExt

Draw and extrude polygons freehand or from a selection of predefined shapes.



PathExt

Draw and extrude PolyPaths to create new meshes such as walls and ramps.



PathRev

Draw and revolve pathways around an axis to create a symmetrical mesh.



BdrRev

Revolves the mesh boundary loops to create a new shape.



MshMrg

Combines multiple meshes into one, keeping intersecting geometry.



MshDup

Duplicates a single mesh, creating a new Actor.



Pattern

Tile one or more selected meshes along a Line, Grid, or Circle oriented on a movable 3D plane.



PolyModel

Perform granular editing using a mesh's PolyGroups.



PolyModel stands for PolyGroup Model, not to be confused with polygon.

Tool

Operation

PolyEd

Opens tools, such as Extrude, Bevel, and Edge Loop, to edit meshes via PolyGroups.



PolyDef

Opens tools to deform meshes via their PolyGroups.



CubeGr

Create blockout meshes using a repositionable grid.



MshBool

Subtract or add mesh pairs.



MshCut

Split one mesh into parts using a second mesh.



SubDiv

Increase the resolution of a mesh by PolyGroups or triangles.



TriModel

Perform granular editing using a mesh's triangles.



TriModel stands for Triangle Model.

Tool

Operation

TriSel

Quickly select triangles to edit a mesh and adjust secondary properties.



TriEd

Opens tools to edit the mesh via triangles.



HFill

Fills any holes in your mesh.



Mirror

Reflect a mesh(es) along a given plane to create new geometry.



PlnCut

Cut the selected mesh on a plane.



PolyCut

Cuts the selected mesh with extrude polygon and open tools to define the new mesh.



Trim

Trim or cut selected meshes with a second mesh.



Deform

Alter or distort a mesh as a whole or in specific areas.



Tool

Operation

VSculpt

Sculpt the target mesh, adjusting its vertices, using various brushes.



DSculpt

Sculpts the target mesh using various brushes and dynamically adds new geometry to the mesh through remeshing.



Smooth

Even out the surface of the mesh, helping remove jagged artifacts.



Offset

Adjust the positioning of the mesh's vertices by a specified amount along their normal.



Warp

Reshape a mesh using non-linear transforms such as Blend, Flare, and Twist.



Lattice

Edit a mesh via its vertices using a structure of points.



Displace

Distort the vertices of a mesh based on preset algorithms, user-generated weight maps, or texture maps.



Transform

Adjust the placement or representation of a mesh.



Tool

Operation

XForm

Transform different aspects of the selected mesh.



Align

Repositions the selected meshes in relation to one another.



Pivot

Edit the pivot point placement on the selected mesh.



PivotAct

Adds an Actor object to the selected mesh to act as a pivot for child components. Opens tools to edit the pivot points and Actor object.



BakeRS

Bakes the scale and rotation values into the mesh. By default scale is uniformly set to 1, while rotation is uniformly set to 0.



Transfer

Transfers the data of one mesh to a target mesh or to a specific LOD used by the target mesh.



Convert

Change the Output Type of a mesh between a Static Mesh, Dynamic Mesh, or Volume.



Split

Takes a mesh with disconnected geometry and splits them into separate mesh.



MeshOps

Optimize a mesh's geometry.



When using the following tools it is helpful to change the View Mode and enable Mesh Edges under Show > Advance.

Tool

Operation

Simplify

Attempts to reduce the triangle density of the selected mesh.



Remesh

Retriangulate and increase triangle density on the selected mesh.



Weld

Automatically combines disconnected edges of the selected mesh within a given tolerance.



Jacket

Removes hidden triangles from the selected meshes.



Merge

Combines multiple meshes into one, resolving self intersections.



Project

Map or Re-mesh one mesh onto the targeted mesh (the second selected mesh).



VoxOps

Convert a mesh into voxels to perform volumetric operations before converting it back into a mesh.

[

Tool

Operation

VoxWrap

Wrap a selected mesh using voxels—helping remove holes as well as removing self-intersections and hidden triangles.



VoxBlnd

Blend selected meshes using voxels.



VoxMrph

Offset or inset the surface of the selected meshes using voxels.



VoxBool

Perform boolean operations on selected meshes and then wrap the result with voxels.



VoxMrg

Merges selected meshes then voxelates the result.



Attributes

Inspect and adjust the secondary properties, such as normals and PolyGroups, of a mesh.



Tools

Operations

Inspct

Visualize attributes, such as wireframes, tangent vectors, and bowtie vertices, and view mesh statistics.



Nrmls

Recomputes the normals and opens tools to set Normals calculations by toggling options on and off and setting the Normals Topography.



Tngnts

Edit the mesh's lines and tangents.



AttrEd

Edit the mesh's different attributes, UVs, and add new attributes as well.



GenGrps

Generates PolyGroups for your mesh.



GrpPaint

Paint PolyGroups onto a mesh using brushstrokes.



MapPnt

Paint on specific Weight Map Layers, which first need to be generated with the AttrEd tool.



MatEd

Assign multiple materials and new material elements to triangles selected via brushstrokes.



UVs

Edit the UV coordinates of a mesh, changing how textures are mapped to the surface.



To learn more, see to the UVs Category documentation.

Tools

Operation

AutoUV

Auto-unwrap and pack UVs for the selected mesh.



Unwrap

Flattens your 3D object out into 2D space to compute UV coordinates, helping minimize stretched and squashed areas.



Project

Opens a toolset to define and add seams to the selected mesh.



SeamEd

Define and add UV seams to the selected mesh.



XFormUV

Transform UV islands in UV space.



Layout

Transform and pack existing UVs.



UV Editor

Launch a dedicated Editor for creating and editing UVs.



Baking

Generate textures and vertex color data for meshes.



For proper baking, the source mesh(es) and target mesh need to be overlapping..

Tools

Operation

BakeTX

Bake the source mesh's details to a target mesh as textures.



BakeAll

Bake textures for a single mesh from multiple source meshes.



BakeVtx

Bake a source mesh's details to a target mesh as vertex colors.



BakeRC

Bakes textures for a target mesh from multiple source meshes via a virtual photo or render capture.



Volumes

Convert between Volume, mesh, Binary Space Partitioning (BSP), and Simple Collision representations. You can also inspect the collision and physics properties of the selected mesh.



Tool

Operation

Vol2Msh

Define and convert a Volume Actor to a Static or Dynamic Mesh Actor.



Msh2Vol

Defines the conversion of a mesh to a new Volume.



PInspct

Inspect physics geometry for the selected mesh.



Msh2Coll

Convert the selected mesh(es) to Simple Collision Geometry for the last selected mesh.



Coll2Msh

Converts Simple Collision Geometry to a new mesh Actor.



LODs

Edit and manage the levels of detail (LODs) for a mesh.



Tool

Operation

LODMgr

Opens the LOD Manager to define and create LODs for the selected Static Mesh Asset.



AutoLOD

Opens a toolset to generate and define Static Mesh LOD Assets.



ISMEd

Edit instances in Instance Static Mesh Components.



Modeling Tools

Modeling Mode Overview

Working with Meshes

Predefined Shapes

Tool Settings

Output Type

Shape

Positioning

Material

You can create a new mesh using the Shapes category in Modeling Mode. The category provides a selection of predefined primitives to use as a starting base.



We recommend reviewing the Modeling Tools documentation for an overview of all the tool categories and how they may fit into your modeling workflow.

Predefined Shapes

You can choose between nine shapes, represented in the table below.











Box

Sphere

Cylinder) (Cyl)

Cone

Torus









Arrow

Rectangle (Rect)

Disc

Stairs

You can select your desired shape and drag it into the scene for placement. After placing your mesh, you can still adjust the tool settings in the Modeling panel. Once you have your desired settings, click Accept.

Tool Settings

You use the Modeling panel to control settings such as how you place your mesh in the scene, its output type, and dimensions.



As with other Modeling Mode tools, parameter values are remembered when reopening the tool.

Output Type

The Output Type sets the type of mesh you create. You can choose between the following types:

Static Mesh

Dynamic Mesh

Volume

You can update the mesh type at any stage of the modeling process by various tools, such as Convert and Transfer, found in the Transform category.

To learn more about these output types and Asset management, refer to the Working with Meshes documentation.

Shape

You can adjust the dimension and subdivisions of your mesh under the Shape setting. Each shape has specific options.

In addition, you can configure the PolyGroups of your new mesh using the Polygroup Mode setting.



The Polygroup Mode has the following grouping options:







Per Shape

Per Face

Per Quad

Outputs the entire mesh as a single group.

Automatically divide the mesh into recognizable face groups.

Automatically divide the mesh into a group for each quad.

To learn more about PolyGroups, refer to the Understanding PolyGroups documentation.

Positioning

You can position your mesh in your Level based on your scene or the ground plane.

Choosing On Scene from Target Surface positions your mesh based on the surface normal of the geometry your cursor resides over.

If you set Collision Presets to No Collision for any object in your Level, then On Scene will not detect the object.

Choosing Ground Plane positions your mesh in the Level with the Z-axis set to 0.

You can also adjust the pivot location to the base, top, or center. You can visualize the position of the pivot by the cursor placement, highlighted in the table below.







Base

Centered

Top

Material

You can select the appropriate Material for your mesh. You can also set the UV Scale and enable Show Wireframe.



Modeling Mode Overview

UV Editor

Understanding Key Concepts

UV

UV Map

UV Islands

UDIM

Common Functionality

UV Channel

Poly Group Layer

Preview Material

Preview UV Layout

UV Tools

AutoUV

Unwrap

Project

SeamEd

XFormUV

Layout

UV Editor

A valuable step after modeling is creating UVs for accurate Texture placement on your mesh. The UVs category in Modeling Mode provides tools for Level based UV editing. UV editing in your Level helps contextualize your model's UVs in comparison to its environment.



Click image to expand.

There are limits to this workflow, and you may find using the UV Editor more appropriate to achieve your desired UV map.

Understanding Key Concepts

Before learning about the tools, we recommend you familiarize yourself with common terminology.

UV

UVs are a parameterization (U,V) of a 3D surface mesh into a normalized (0-1) 2D space. In other words, they represent coordinates in 2D space that translate to vertices on your 3D model.



The 2D space is represented horizontally as U and vertically as V, thus the name UV coordinates (also referred to as 2D or texture coordinates).



Click image to expand.

UV Map

The collection of UV islands and their layout is called a UV map. The UV map determines how a Texture will be wrapped around your 3D geometry when rendered—this process of texture wrapping is known as UV mapping.



Click image to expand.

A Material uses the mapping between 2D coordinates and 3D vertex positions to determine which areas of the Texture are used to shade what triangles in your 3D model.

UV Islands

UV islands, also called charts, are a collective of connected triangles within a given boundary of edges. However, one triangle can represent an island.



Click image to expand.

UDIM

A traditional UV map is created in the 0-1 unit square. This limitation in texture space can make creating efficient textures difficult.



Click image to expand.

UDIMs make it possible to manage multiple resolutions for a single model by using additional unit squares. You may need certain parts of your model to have a 1k texture, while others use a 4k texture. In addition, you can choose multiple lower-resolution textures for differing parts to accumulate to a high-resolution image. Using different texture regions at different resolutions helps achieve the appropriate texel density for your model.

UDIMs is short for U-Dimension – the direction in which a set number of unit squares (or UDIM tiles) are used for textures before moving up in the V direction and repeating the process. UDIMs is a process practiced heavily in the VFX industry compared to traditional video game development.



Click image to expand.

For UDIM creation and management you need to use the UV Editor.

Common Functionality

Some tools have shared settings that we explain here.

UV Channel

A UV Channel contains your UV map. You can create multiple UV maps for one model using UV Channels.

UV Channels provide the ability to layer Textures on your mesh and store data such as baked lights. You can create and manage channels using the following:

The UV Editor's Channel tool

The Static Mesh Editor

AttrEd tool under the Attributes category while in Modeling Mode

The UV Editor provides functionality to add, delete, and copy channels.

To learn more about UV Channels, refer to the Using UV Channels With Static Meshes documentation.

Poly Group Layer

You can decide to constrain the arrangement of UVs based on your geometry's PolyGroups.

You can create and manage PolyGroups through tools such as GrpGen and GrpPnt. To learn more about PolyGroups, refer to the Understanding PolyGroups documentation.

Preview Material

You use the Preview Material to help visualize your UVs. You can switch between the following Material:

Material

Description

Original

Displaying the current Material applied in the Details panel.

Checkerboard

Applies a temporary checkerboard Material.

Override

Applies a temporary Material located in your Content Browser.

Using the checkerboard material, you can adjust the density and preview the look of additional channels that are set to the mesh.

Preview UV Layout

For some tools, you can preview your UV map in 2D Space.



Click image to expand.

The preview panel will match the movement of the camera for visibility. In addition, you can:

Control which side it appears on

Scale the panel

Manually adjust the position using Offset

Enable wireframe

The preview panel will show all your UVs with a square border depicting the 0-1 unit square. However, the panel can become challenging to read for models with UDIMs or UVs far away from 0-1.



Click image to expand.

UV Tools

When creating new UVs, you can use the AutoUV or Project tool to get started. You can use the remaining tools after to work out the details. Use the SeamEd tool for a manual start.

You can adjust Texture resolution using the Layout, AutoUV, and Unwrap tools.

AutoUV

You can automatically unwrap and pack your UVs using AutoUV. This automation is helpful as a starting point for custom UV mapping or background assets needing a quick UV map.

There are three methods for control: UVAtlas, XAtlas, and PatchBuilder.

Method

Description

Patch Builder

Supports large models, such as Nanite. Default option built in-engine.

UV Atlas

More valuable for organic objects, minimizing stretching. To learn more on UV Atlas, refer to Using UVAtlas.

Does not work on Linux.



XAtlas

Designed for light maps and mechanical meshes. To learn more about XAtlas, refer to XAtlas Github.

In Patch Builder mode you can layout UVs based on predefined PolyGroups.

Unwrap

The Unwrap tool flattens your 3D object out into 2D space to compute UV coordinates, helping minimize stretched and squashed areas (distortion)

In the video, using the Unwrap tool to recompute the UVs removes the high-distortion area around the seam, resulting in more proportional UVs.

You can use the UV Editor to perform the operation on a selected UV island(s).

You can decide if you want to UV unwrap based on Existing UVs or PolyGroups. How your UVs automatically unwrap is determined by the Unwrap Type.

Unwrap Type

Description

ExpMap

Performs a fast unwrap but is limited in reducing distortion.

Conformal

Reduces distortion compared to ExpMap, but is increasingly expensive on large islands.

SpectralConformal

Compared to the Conformal method reduces the distortion further but is more expensive to compute. Additionally has the option Preserve Irregularity to remove unnatural distortion due to mesh irregularity.

Island Merging

UV islands are merged into larger islands if it does not increase distortion beyond defined limits.

If you are texturing a simple geometry such as a flat plane, then all unwrap types will give you approximately the same result. If you are working with a mesh that is not uniformly tessellated and has a complex shape, Spectral Conformal is the best option. It provides the least distortion; however, it computes slower.

You also have the option to choose a Layout Type and preserve UDIMs.

Project

One way to create a UV map is by projecting it from a selected shape or point onto your geometry. The Project tool is an alternative to AutoUV for initializing your UV maps quickly.

Project works well on geometry with a similar silhouette to the selected Projection Type. The tool may not be the best option for complex geometry as it can cause distortion and unwanted seams. However, it can serve as a starting point before using the UV Editor.

You can choose from the different Projection Types illustrated in the table below.









Box

Cylinder

Plane

ExMap

Useful for assets with sharp edges, such as a crate or book.

Useful for assets with round edges, such as an arm or tree trunk.

Useful for flat assets, such as a mirror or wall.

Useful for decals in a separate UV Channel.

You may notice ExpMap has an identical shape to the Plane projection; however their operation is different. Instead of projecting based on a shape, ExpMap projects based on a point.

To learn more about the ExpMap projection, refer to the paper Interactive Decal Compositing with Discrete Exponential Maps.

You can adjust the dimension of each shape for a better fit around your mesh. To uniformly define the size, enable Uniform Dimensions and adjust only the X value. You can then use the transform widget for further adjustments.

Initialization determines the way the projection shape automatically fits your model when activating the Project tool. You have four options described in the table below.

Initialization Type

Description

Default

Projection to bounding box center.

Use Previous

Projection based on previous usage of the Projection tool.

Auto Fit

Automatically fits the UV Projection Dimensions to your geometry based on the current projection orientation.

This method will appear the same as Default unless the orientation of the projection shape is altered.



Autofit Align

Automatically orients the projection, then automatically fits the UV Projection Dimension to your model.

You can change the Initialization type after opening the Project tool. However, as soon as you alter the projection type, dimension, or position, Initialization deactivates.

To reactivate Initialization, set the desired type and then either:

Reselect the Project tool.

Press the Reset button under Actions.

The Actions options also let you initiate Auto Fit and Auto Fit Align at any point needed.

If Uniform Dimension is enabled, you may not see the projection shape change when using Initialization or Actions.

Finally, using the UV Transformation settings, you can adjust the rotation, scale, and translation of the projected UVs.

SeamEd

You can interactively separate edges to create seams in the Viewport. Click a vertex and drag to a neighboring vertex to create a seam. You can make multiple seams before clicking Accept or pressing the Enter key.

It is not necessary to select directly onto a vertex to highlight it; clicking near the vertex on the geometry will do. This selection option will help you avoid choosing other Actors in the scene.

You typically want seams invisible to your audience unless it is the desired aesthetic. Knowing what parts of your asset are visible in the experience is essential in understanding where to create seams.

To merge seams together, you will need to use the Sew tool in the UV Editor. In addition, the tool doesn't support multiple UV Channels.

XFormUV

The XFormUV tool also provides interactive control in the Viewport. You can scale, rotate, and translate UVs per island. To adjust multiple islands at once, hold the Shift key.

The XFormUV tool helps adjust distortion in individual islands after using the other UV tools.

Layout

The Layout tool helps organize your UV islands into the 0-1 unit square.

The process of laying out UVs into a UV space is called UV packing. There are three Layout Types to help pack your UVs:

Layout Type

Description

Transform

Transform applies scaling and translation to all your UVs, regardless if particular islands are selected. Keeps the current layout of the UVs. These scale and translation controls are available in Stack and Repack.

Stack

Uniformly scale and translate each UV island individually to pack in a unit square with overlap. Stacking can be useful when two UV islands share the same texturing design, removing the need for replication.

Repack

Uniformly scale and translate UV islands collectively to pack in a unit square with no overlap. Unique to Repack is the Allow Flips setting. Enabling this feature can save space when packing UVs but can lead to issues for downstream operations.

Using the UV Editor, you can organize your UV islands within their originating UDIM when Preserve UDIMs is enabled.

UV Editor

Although the UV tools provide editing capabilities, there are limits such as:

Merging edges

UDIM management

Multi-asset workflow

Manual precision control of islands, vertices, and triangles

The UV Editor picks up these limitations by providing a toolset and Viewports for such capabilities. Refer to the UV Editor documentation to learn how to use this Editor.



Click image to expand.

Modeling Mode Overview

The Default Interface

Accessing the UV Editor

Toolbar

Display

Tools

Sew

Split

Layout

Transform

Align

Distribute

Channels

Seam

AutoUV

Unwrap

2D Viewport

Controls

3D Viewport

Controls

Next Steps

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

The UV Editor provides the toolset and Viewports for creating and modifying UVs. Compared to the Level Editor's UV tools, the UV Editor delivers a more interactive 2D view with fine-grain editing of UVs. In addition, it provides options such as:

Merging edges

UDIM management

Multi-Asset workflow

Before using the UV Editor, it is essential to understand the unique aspects of modeling in-engine and the common terminology associated with creating UVs.





UVs with Distorted Texture

UVs with Uniform Texture

When opening the UV Editor, the initial UV map shown is pulled from your imported mesh, and meshes created in-engine have default UVs created.

The Default Interface

The UV Editor interface consists of four core components:



Click image to expand.

Toolbar

Tools

2D Viewport

3D Viewport

Accessing the UV Editor

You can access the UV Editor in three ways:

Use the UV panel in Modeling Mode.

Right-click your mesh within your Level.

Right-click your mesh in the Content Browser.

Toolbar

Action

Description

Save

Save your UV map.

Browse

Opens the location of the current mesh in the Content Browser.

Apply

Applies your UV changes to your original mesh.

Channels

Switch between UV mapss for a mesh. Use the Channel tool to create and edit UV maps.

Display

Control the look of your 2D Viewport.

Using the Display tab, you can toggle the visibility of the grid and rulers in the 2D Viewport. You can also set the background to visualize textures mapped to your UVs.



Click image to expand.

In addition, you can label UDIMs based on the location of your UV Islands or from Textures. You can manually apply UDIMs using the Active UDIMs plus icon.

When a background is enabled, it displays automatically for the 0-1 unit square. UDIMs must be set for the background to appear correctly in other unit squares.

Tools

Use the UV Editor tools to create and manage the desired UV map(s) for your mesh. When creating new UVs, you can use the AutoUV tool, then the remaining tools to work out the details. For a manual start, use the Seam tool.

You can adjust Texture resolution using the Layout, AutoUV, and Unwrap tools.

Sew

The Sew tool connects two corresponding edges. When using the tool, the selected edge will be highlighted in red, and its counterpart edge in green. These highlighted edges will combine once you click the Sew tool.



If you receive the warning that no viable sew candidate edges are selected then the selected edge is already connected within the UV island or is a boundary edge.

Split

Use the Split tool to separate the UV coordinates of your mesh manually. You can split along a given selection of the following:

Bowtie vertices

This disconnects the UV topology from any bowtie vertices within the selection.

These are vertices that join triangles by one point instead of an edge. It is unnecessary to select individual bowtie vertices for the tool to work. Selecting UV islands and then using the Split tool will disconnect any existing bowtie vertices.

Edges

This disconnects the UV topology at the edge(s).

Triangles

This slices out whole regions.

The thicker-saturated outline of your UVs indicates a seam. Use this to identify if you properly split your selection.

Layout

The Layout tool helps organize your UV islands into a 0-1 space or within their originating UDIM when Preserve UDIMs is enabled.

The process of laying out UVs into a UV space is called UV packing. There are three Layout Types to help pack your UVs:

Layout Type

Description

Transform

Transform applies scaling and translation to all your UVs, regardless if particular islands are selected. Keeps the current layout of the UVs. These scale and translation controls are available in Stack and Repack.

Stack

Uniformly scale and translate each UV island individually to pack in a unit square with overlap. Stacking can be useful when two UV islands share the same texturing design, removing the need for replication.

Repack

Uniformly scale and translate UV islands collectively to pack in a unit square with no overlap. Unique to Repack is the Allow Flips setting. Enabling this feature can save space when packing UVs but can lead to issues for downstream operations.

The tool operates on the current selection of islands or all islands if nothing is selected.

Transform

The Transform tool provides explicit numerical input for scale and translation compared to the gizmo in the 2D Viewport.

You can perform rapid transformations using the Quick Translate and Quick Rotate options. For further precision, use the Advance Transform section, where you have the option to adjust the pivot.

Translation Mode decides how to position the UVs using either of the following options:

Relative moves elements respective to their current position.

Absolute moves elements based on the Manual input in the Transform Origin.

Transform Origin decides the UVs' pivot location, which controls the relative motion of the transforming UVs.

Transform Origin Mode

Description

Bounding Box Center

Pivots around the center of all island bounding boxes.

Origin

Pivots using the global origin of 0,0.

Individual Bounding Box Center

Pivots around each island's bounding box center.

Manual

Pivots based on a user-specified point.

Transformation operations are performed in order from top to bottom.

Align

Line up existing UVs based on their edges, vertices, or islands.

To further assist you to adequately position UVs, the following options are available:

The Alignment Anchor controls what geometry the alignment is relative to when performed.

Grouping Mode controls how alignment considers grouping the selection to the alignment behavior.

Distribute

You can adjust the spacing of UV vertices and islands.



Similar to the Align tool, use the Distribute tool to help remove stretching and distortion in your UVs.

Channels

You can manage UV maps by adding, copying, and deleting channels. UV Channels consist of differentiating UV maps for one mesh.

Multiple UV Channels provide the ability to layer textures on your mesh, as well as baking lights. For example, with the crate, you can have one channel for the wooden texture and another for a Decal with the wording, "FRAGILE".

To learn more about UV Channels, refer to the Using UV Channels With Static Meshes documentation.

Seam

Using the 2D or 3D Viewport, you can interactively separate edges to create seams. You automatically create seams when at least two vertices are selected, and you can separate multiple UVs before clicking Complete in the Viewport.

Be mindful of where your seams appear. You typically want seams invisible to your audience unless it is the desired aesthetic. Knowing what parts of your asset are visible in the experience is essential in understanding where to create seams





AutoUV

You can automatically unwrap and pack your UVs. This automation is helpful as a starting point for custom UV mapping or background assets needing a quick UV map.

There are three methods for control: UVAtlas, XAtlas, and PatchBuilder.

Method

Description

Patch Builder

Supports large models, such as Nanite. This is the default option built in-engine.

UV Atlas

Use for organic objects, to minimize stretching.

Does not work on Linux.



XAtlas

Designed for light maps and mechanical meshes.

In Patch Builder and UV Atlas mode, you can layout UVs based on predefined PolyGroups. In addition, you can automatically organize the specified PolyGroups into UDIMs.

To visualize the numbering of each UDIM, use the Display dropdown menu.

Unwrap

The Unwrap tool flattens your 3D object out into 2D space to compute UV coordinates, helping minimize stretched and squashed areas (distortion).

The tool operates on the current selection of islands or all islands if nothing is selected.

You can decide if you want to UV unwrap based on Existing UVs or PolyGroups. How your UVs automatically unwrap is determined by the Unwrap Type.

Unwrap Type

Description

ExpMap

Performs a fast unwrap but is limited in reducing distortion.

Conformal

Reduces distortion compared to ExpMap, but is increasingly expensive on large islands.

SpectralConformal

Compared to the Conformal method reduces the distortion further but is more expensive to compute. Additionally has the option Preserve Irregularity to remove unnatural distortion due to mesh irregularity.

Island Merging

UV islands are merged into larger islands if it does not increase distortion beyond defined limits.

If you are texturing a simple geometry such as a flat plane, then all unwrap types will give you approximately the same result. If you are working with a mesh that is not uniformly tessellated and has a complex shape, Spectral Conformal is the best option. It provides the least distortion; however, it computes slower.

2D Viewport

The 2D Viewport represents the 2D Space (also referred to as UV or Texture Space) for displaying your UV map. It is the primary Viewport for unwrapping and packing UVs. Unique to this Viewport are the UV selection types in the table below.











Select Vertices

Select Edges

Select Triangles

Select Islands

Select Mesh

The Viewport grid consists of what's known as Unit squares. The default Unit square for UVs is 0-1. A texture map is placed in one unit square and UDIMs are numbered by each unit square used starting at 1001.



Click image to expand.

UDIMs are created horizontally to a max of 10 units before continually up to the next row, repeating the process if needed.

Controls

You have the following navigation options in the 2D Viewport:

Scroll with the middle mouse button to zoom in and out.

Right-click to translate the grid.

Avoid using hotkeys associated with the Level Viewport.

The Translate Gizmo mimics the one used for Modeling Mode and reorients when re-clicking the UV after performing a rotation.

3D Viewport

Live view of your UVs on your 3D mesh. Unique to the 3D Viewport is the Focus Camera, which snaps to your current selection of UVs. You can use the hotkey Alt + F when the 3D Viewport is active.

Controls

When Orbit Camera is enabled, you have the standard navigation controls in addition to pan, orbit, and zoom. Fly Camera has the same navigations along with game-style controls.

To learn more about these controls, refer to the Viewport Controls documentation.

There is also the option to adjust the View Mode from the default Lit option. To learn more, refer to Viewport Modes.

Next Steps

Now that you're familiar with the basics of the UV Editor, you can:

Begin UV mapping your geometry.

Learn about using Textures and creating Materials.

What is Geometry Script?

DynamicMesh Objects

UDynamicMesh

DynamicMeshComponent

DynamicMeshActor

GeneratedDynamicMeshActor

Key Differences between UStaticMesh and UDynamicMesh

GeometryScript Function/Node Pattern

Using UDynamicMesh Pools

Creating a Procedural Mesh Object using Actor Blueprints

What is Geometry Script?

Geometry Script is an Unreal Engine plugin containing a set of Function Libraries that provide the ability to generate and edit mesh geometry via Blueprints and Python.

Geometry Script UFunctions and Blueprint Nodes operate on UDynamicMesh objects, which are objects created using the FDynamicMesh3 C++ triangle mesh data structure. This is the same data structure used by the Geometry Processing Plugin and Modeling Editor Mode.

Geometry Script can be used in Editor Utility Widgets and Asset Actions to create custom mesh analysis / processing / editing tools. It can also be used in Actor Blueprints to create "procedural objects" and implement complex geometric queries.

Geometry Script has a variety of potential uses:

Testing and quality analysis of third-party mesh importers.

Analyzing mesh UVs to identify assets with wasted texture space.

Scripted merging of mesh assets for production workflows.

Procedural mesh Actors such as the Level Design Tool Objects used in the Lyra Sample Game.

DynamicMesh Objects

Geometry Script operates on several new object types:

UDynamicMesh

UDynamicMeshComponent

ADynamicMeshActor

Similar to the Static Mesh / StaticMeshComponent / StaticMeshActor architecture, these classes are not specifically part of the Geometry Script plugin - they are located in the Geometry Framework engine module, and can be used separately from Geometry Script.

UDynamicMesh

The core component that enables Geometry Script is the UDynamicMesh object. This UObject is a container for a mesh data structure that is not tied to a specific Component. This diverges from previous Unreal Engine approaches like UProceduralMeshComponent in that mesh geometry can be created and manipulated without an explicit scene representation.

For example, a UDynamicMesh can be initialized based on a UStaticMesh Asset, edited, and then stored back in the Asset. Combined with Editor Utility Widgets to provide the user interface, this approach allows tech artists to create custom purpose-built mesh editing tools in Blueprint, or to script Mesh Asset query/editing operations via Python.

Various other Editor mesh geometry types can also be converted to/from UDynamicMesh, such as Gameplay Volumes.

DynamicMeshComponent

In addition to UDynamicMesh, UDynamicMeshComponent has been promoted into a "real" (non-transient, serializable) Component. This Component is similar in spirit to a UProceduralMeshComponent, however it is backed by a UDynamicMesh, which can then be manipulated via GeometryScript.

UDynamicMeshComponent has been developed over the past several years as part of the Mesh Modeling Toolset, where it has been used to provide realtime previews of mesh editing. Similar to UProceduralMeshComponent, it supports updates to the mesh geometry - not just updating vertex attributes, but also creating and modifying the entire mesh topology. This can be done both in-Editor and at Runtime. Raytracing is supported, however Nanite and Lumen are not.

DynamicMeshActor

ADynamicMeshActor is similar to AStaticMeshActor in that it is largely a container for a UDynamicMeshComponent. However, DynamicMeshActor does provide some specific support for Actor Blueprints that wish to implement procedural mesh generation based on UDynamicMesh.

Modeling Mode Tools that previously could only create new StaticMesh Assets can now also create new DynamicMeshActors, and the editing Tools can edit either type of mesh Actor (in addition to Volumes).

GeneratedDynamicMeshActor

AGeneratedDynamicMeshActor is a subclass of ADynamicMeshActor that provides additional support for implementing Blueprint-based procedural mesh Actors. Specifically, this class provides the function On Rebuild Generated Mesh that can be implemented in BP Subclasses to generate a mesh, instead of doing so in the Construction Script. This provides better in-Editor interactive performance, and leaves the door open to more carefully managed large-scale procedural geometry generation in the future.



GeneratedDynamicMeshActor is currently Editor-Only.

Key Differences between UStaticMesh and UDynamicMesh

Unlike UStaticMesh, UDynamicMesh is not an Asset. A UDynamicMeshComponent "owns" its UDynamicMesh, it is not shared between multiple Components like a UStaticMesh is. This means, for example, that Instanced rendering is not available. The UStaticMesh is stored as part of the Component (and the Actor), similar to ProceduralMeshComponent. This means that the mesh is stored "In the Level", not in a separate asset file. Duplicating a UDynamicMeshComponent creates a copy of the mesh, and transferring between levels or projects must be done via copy-paste.

In many ways, UDynamicMeshComponent behaves much more like mesh objects in a DCC tool, such as Autodesk 3ds Max, Autodesk Maya, or Blender. This does introduce potential problems with huge meshes dramatically increasing the size of the level file. However, with One File Per Actor, the mesh data will be stored with the OFPA Actor file, rather than the level (so, still potentially huge, but in a separate file).

GeometryScript Function/Node Pattern

The majority of Geometry Script functions/nodes follow a very standard pattern similar to the Apply Mesh Plane Cut node shown below.



The first argument, Target Mesh, is the UDynamicMesh that will be edited by the operation. Generally, Geometry Script operations modify the input mesh, rather than creating a new mesh, to avoid creating several temporary mesh objects. The input UDynamicMesh is always also returned as an output, also called Target Mesh (same name == same object). This makes it easy to chain multiple operations in sequence.

Geometry Script nodes have many parameters and settings. The most frequently used options are exposed as arguments, but more options are provided via an operation-specific Options structure. The most common way to create the right Options structure is to drag off the empty Options pin. This is not necessary unless you wish to modify the defaults. In addition, you can right-click on the Options pin and use the Split Struct Pin context menu item to directly expand the Options structure in the node, as shown below.



Most nodes also have a Debug pin to provide geometric debugging support for mesh generators. This is not actively being used, but is a placeholder for future functionality.

Using UDynamicMesh Pools

It is common to need to create temporary meshes inside a mesh generator, for example creating a primitive mesh to be subtracted from the "main" mesh. To do this, a temporary UDynamicMesh is needed. While one can be created using ConstructObjectFromClass, if this is done in a procedural generator, that mesh must be Garbage Collected after usage. If the generator is run frequently then it is more efficient to re-use the mesh across runs.

DynamicMeshActor has built-in support for this using a UDynamicMeshPool. This can be done by calling AllocateComputeMesh to get a temporary mesh, and then release it somewhere before the end of the Blueprint execution path. Each temporary mesh can be explicitly released using ReleaseComputeMesh, or by calling ReleaseAllComputeMeshes, which will release any temporary meshes currently allocated from the pool.



In an Editor Utility Widget, there is no default DynamicMeshPool instance to allocate meshes from, however you can use CreateDynamicMeshPool to create one (for example, as a variable in the Editor Utility Widget or Utility Blueprint.)

Creating a Procedural Mesh Object using Actor Blueprints

As noted above, one exciting use case for GeometryScript is to create procedural mesh "objects" using Actor Blueprints. An example is shown below, using a BP subclass of GeneratedDynamicMeshActor. The On Rebuild Generated Mesh Event is used to populate the UDynamicMesh of a UDynamicMeshComponent. These classes are described in the Geometry Script Reference. The UDynamicMesh is passed to a GeometryScript function Append Box, which creates a mesh based on the input variables.



The clip below shows an example of using an instance of this BP Actor - essentially we have created a parametric box primitive mesh, with just a few BP nodes. By adding additional nodes we can build increasingly complex mesh generators directly in Blueprints. The current GeometryScript library contains over 150 functions/nodes for mesh generation and editing.



Asset and Component Read/Write

Primitive Generation

Transform and Deformation

Composition and Decomposition

Mesh Modeling

Mesh Selections

Modify Mesh by Selection

Transform Mesh

Materials and PolyGroups

Mesh Modeling

Subdivision Functions

Simplification Functions

Normals Functions

Cleanup/Repair Functions

Low-Level Mesh Queries

Low-Level Mesh Building

Low-Level List Management

Low-Level Math

MaterialID Functions

Vertex Values

Texture Sampling and Creation

Baking

UV Functions

PolyGroup Functions

Mesh Geometric Queries

PolyPath

Mesh Comparisons

BVH & Spatial Queries

Utilities

Glossary

The Geometry Script Library contains a very broad range of functionality, from low-level mesh construction and queries, such as building a mesh triangle-by-triangle or counting its vertices, to high-level operations like mesh booleans and intersection tests.

For more information on using the Geometry Script Library, see Geometry Script Users Guide.

Most functions are available while working in the editor and at runtime. However, some are only available while working in the editor and have been noted in the tables below.

Asset and Component Read/Write

You can use these functions to read and write Dynamic Mesh instances, such as reading and writing to or from an existing or new Asset or Component.

Node Name

Description

Copy Mesh From Static Mesh

Extracts a Dynamic Mesh from a Static Mesh Asset.

Copy Mesh To Static Mesh

Updates a Static Mesh Asset with new geometry converted from a Dynamic Mesh.

Copy Mesh From Component

Extracts a Dynamic Mesh Actor from any supported Component type, in World or Local space.

Create New Volume From Mesh

Creates a new Volume Actor, such as a Blocking Volume, from a Dynamic Mesh Actor.

This node only works in the Editor.



Create New Static Mesh Asset From Mesh

Creates a new Static Mesh Asset from a Dynamic Mesh Actor.

This node only works in the Editor.



Set Static Mesh Collision From Mesh

Generates Simple Collision shapes for a Static Mesh Asset based on the input Mesh.

Set Dynamic Mesh Collision From Mesh

Generate Simple Collision shapes for a Dynamic Mesh Component based on the input Mesh.

Copy Collision Meshes From Object

Extracts the Collision Geometry from From Object and copies it with meshes stored in To Dynamic Mesh.

For Simple Collision, From Object can be a Static Mesh Asset or any Primitive Component.

For Complex Collision, From Object can be a Static Mesh Asset, Static Mesh Component, or Dynamic Mesh Component.



Reset Dynamic Mesh Collision

Clears Simple Collisions from the Dynamic Mesh Component.

Copy Mesh From Skeletal Mesh

Copies the Skeletal Mesh into the target Dynamic Mesh.

Copy Mesh To Skeletal Mesh

Copies the given Dynamic Mesh to the Skeletal Mesh.

Primitive Generation

You can use these functions to generate and append a primitive mesh to the input Dynamic Mesh.

Node Name

Description

Append Box

Appends a 3D box to a specified Dynamic Mesh.

Append Sphere Lat Long

Appends a 3D Sphere triangulated using latitude/longitude topology to a Dynamic Mesh.

Append Sphere Box

Appends a 3D sphere triangulated using box topology to a Dynamic Mesh.

Append Capsule

Appends a 3D Capsule to a Dynamic Mesh.

Append Cylinder

Appends a 3D Cylinder (with optional end caps) to a Dynamic Mesh.

Append Cone

Appends a 3D cone to a Dynamic Mesh.

Append Torus

Appends a 3D torus (donut) or partial torus to a Dynamic Mesh.

Append Rectangle

Appends a planar Rectangle to a Dynamic Mesh.

Append Round Rectangle

Appends a planar Rectangle with Rounded Corners (RoundRect) to a Dynamic Mesh.

Append Disc

Appends a planar disc to a Dynamic Mesh.

Append Triangulated Polygon

Appends a Delaunay triangulation of a planar 2D polygon to a Dynamic Mesh.

Append Revolve Polygon

Appends the surface-of-revolution of a 2D polygon, full or optionally-capped partial revolution to a Dynamic Mesh.

Append Spiral Revolve Polygon

Revolves a 2D polygon on a helical path, like one used to create a vertical spiral.

Append Revolve Path

Revolves an open 2D path, with optional top and bottom end caps.

Append Simple Extrude Polygon

Extrudes a 2D polygon along a vertical path using a selected Dynamic Mesh.

Append Simple Swept Polygon

Sweeps a 2D polygon along an arbitrary 3D path using a selected Dynamic Mesh.

Append Linear Stairs

Appends a linear staircase using a selected Dynamic Mesh.

Append Curved Stairs

Appends a rising circular staircase using a selected Dynamic Mesh.

Append Mesh Transformed

Applies each transform to Append Mesh and then adds its geometry to the Target Mesh.

Append Sweep Polygon

Sweeps and rotates a 2D polygon along the Sweep Path to create a 3D mesh that appends to the provided mesh.

Append Voronoi Diagram 2D

Generates triangulated Voronoi Cells from the provided Voronoi Sites, identifying each with PolyGroups, and appends to the provided mesh.

Transform and Deformation

You can use these functions to manipulate the vertex positions of a Dynamic Mesh. These manipulations do not change the mesh topology or connectivity.

Node Name

Description

Translate Mesh

Applies a translation to the vertices of a Mesh.

Scale Mesh

Applies a scale transformation to the vertices of a Mesh.

Transform Mesh

Applies an arbitrary FTransform to the vertices of a Mesh.

Apply Bend Warp To Mesh

Applies a bend warp around an axis defined by a Transform.

Apply Twist Warp To Mesh

Applies a twist warp around an axis defined by a Transform.

Apply Flare Warp To Mesh

Applies a Flare/Bulge warp.

Apply Math Warp To Mesh

Applies various simple math-function-based warps, currently a 1D or 2D sine-wave with arbitrary orientation.

Apply Perlin Noise To Mesh

Applies a 3D Perlin noise displacement to the entire mesh or regions of the mesh defined by optional Selection.

Apply Iterative Smoothing To Mesh

Applies several mesh smoothing iterations to the entire mesh or a subset defined by the optional Selection

Apply Displace From Texture Map

Applies a displacement to a Dynamic Mesh based on a Texture2D and a UV channel.

Rotate Mesh

Rotates the mesh relative to the specified origin.

Composition and Decomposition

You can use these functions to combine meshes together, or split them apart.

Node Name

Description

Copy Mesh To Mesh

Copies the mesh from one Dynamic Mesh into another.

Get Sub Mesh From Mesh

Copies a list of triangles from one Dynamic Mesh to another.

Split Mesh By Components

Separates a mesh into parts, one for each connected component, drawn from a Dynamic MeshPool.

Split Mesh By Material IDs

Separates a mesh into parts, one for each Material ID, drawn from a Dynamic MeshPool.

Append Mesh

Appends the geometry from one mesh to another, with optional Transform.

Append Mesh Repeated

Appends the geometry from one mesh to another based on the number of times it should repeat, accumulating a transform each time. This operation is useful for making patterns.

Mesh Modeling

These functions provide standard high-level modeling operations, but are generally calling the low-level mesh processing code that the similarly-named Tool in Modeling Mode would call.

Node Name

Description

Apply Mesh Boolean

Applies a Boolean operation (such as, Union, Intersect, and Subtract) to a Dynamic Mesh based on a second mesh.

Apply Mesh Plane Cut

Applies a plane cut to a mesh, optionally filling any holes created.

Apply Mesh Plane Slice

Slices a mesh into two halves, with optional hole filling.

Apply Mesh Mirror

Mirrors a mesh across a plane, with optional cutting and welding of triangles.

Apply Mesh Offset

Moves the vertices of a mesh to an offset surface.

Apply Mesh Shell

Moves a copy of the mesh's triangles to an offset surface, and stitches them to the original triangles. For example, to create a thickened shell.

Apply Mesh Extrude

Extrudes the triangles of a mesh along a constant direction. For example, it creates a solid from an open triangulated polygon.

Apply Mesh Solidify

Replaces the mesh with a voxelized-and-meshed approximation (VoxWrap operation).

Apply Mesh Morphology

Replaces the mesh with an SDF-based offset mesh approximation.

Apply Mesh Self Union

An object performs a Boolean Union operation with itself, computing actions such as repairing self-intersections and removing floating geometry.

Apply Mesh Polygroup Bevel

Applies Mesh Bevel operation to all Polygroup Edges.

Mesh Selections

These functions identify regions of a mesh to different tools so they can operate locally. Several functions can work on the entire mesh or a subset defined by a Selection. Selection Types include: Triangle, Vertices, and PolyGroups.

Node Name

Description

Invert Mesh Selection

Invert the Selection on the Target Mesh.

Create Select All Mesh Selection

Creates a Selection of the given Selection Type containing all the elements of the Target Mesh

Convert Mesh Selection

Converts a Mesh Selection to a different Type.

By default, Vertices map to Triangles within a one-ring neighborhood and Triangles to all contained vertices.



Combine Mesh Selections

Combines two Mesh Selections into a new Mesh Selection. The two inputs, Selection A and Selection B must have the same Type.

Convert Index Array To Mesh Selection

Creates a Mesh Selection from the Index Array.

Convert Index Set To Mesh Selection

Creates a Mesh Selection from the Index Set.

Convert Mesh Selection To Index Array

Converts a Mesh Selection to an Index Array.

Convert Index List To Mesh Selection

Creates a Mesh Selection from the Index List. For cases where the Index List Type does not match the Selection Type, Convert Mesh Selection with bAllowPartialInclusion=true is used to convert.

Convert Mesh Selection To Index List

Converts a Mesh Selection to an Index List.

Select Mesh Elements In Box

Creates a new Mesh Selection of the Selection Type for the Target Mesh by finding all elements contained in the Box.

Select Mesh Elements In Sphere

Creates a new Mesh Selection of the Selection Type for the Target Mesh by finding all elements contained in the Sphere.

Select Mesh Elements With Plane

Creates a new Mesh Selection of the Selection Type for the Target Mesh by finding all elements on one side of the plane, particularly the side that the surface normal of a Plane points towards.

Select Mesh Elements By Normal Angle

Creates a new Mesh Selection of the Selection Type for the Target Mesh by finding all elements that have a normal vector that is within an angular deviation threshold from the given Normal.

For Triangle and Polygroup selections the triangle facet normal is used, for Vertex selections the per-vertex averaged normal is used.



Select Mesh Elements Inside Mesh

Creates a new Mesh Selection of the Selection Type for the Target Mesh by finding all elements inside a second Selection Mesh.

Expand Mesh Selection To Connected

Expands the Selection on the Target Mesh to connected regions and returns the New Selection.

Get Mesh Selection Bounding Box

Gets the 3D Bounding Box of a Mesh Selection.

Get Mesh Selection Boundary Loops

Computes the set of Vertex Loops bordering a Mesh Selection. Both the 3D polylines and lists of vertex indices are returned for each Loop.

For a Vertex selection, this function returns the border loops around the one-ring neighborhood of the vertex selection.



Get Mesh Selection Info

Queries information about a Mesh Selection.

Debug Print Mesh Selection

Prints information about the Mesh Selection to the Output Log.

Modify Mesh by Selection

Functions for editing geometry from a given selection.

Transform Mesh

Node Name

Description

Transform Mesh Selection

Applies the given transform to the selected part of the mesh.

Translate Mesh Selection

Applies the given translation to the selected part of the mesh.

Rotate Mesh Selection

Rotates the selected part of the mesh relative to the specified origin.

Scale Mesh Selection

Applies the given scale to the selection part of the mesh.

Materials and PolyGroups

Node Name

Description

Set Material ID For Mesh Selection

Sets a new Material ID on all the triangles of the given Selection.

Set Polygroup For Mesh Selection

Set a new Polygroup on all the triangles of the given Selection, for the given Group Layer.

Mesh Modeling

Node Name

Description

Apply Mesh Disconnect Faces

Disconnects the triangles of the Target Mesh identified by the Selection.

Apply Mesh Duplicate Faces

Duplicates the triangles of Target Mesh identified by the Selection input.

Apply Mesh Linear Extrude Faces

Applies Linear Extrusion to the triangles of Target Mesh identified by the Selection.

Apply Mesh Offset Faces

Applies an Offset to the faces of Target Mesh identified by the Selection, or all faces if the Selection is empty.

Apply Mesh Inset Outset Faces

Applies an Inset or Outset to the faces of Target Mesh identified by the Selection, or all faces if the Selection is empty.

Apply Mesh Bevel Selection

Applies a Mesh Bevel operation to parts of Target Mesh using the Bevel Options settings.

Subdivision Functions

These functions apply various mesh subdivision strategies to a Dynamic Mesh.

Node Name

Description

Apply Recursive PNTessellation

Apply PN (Point-Normal) Tessellation to the input mesh using a recursive strategy, that is, 1-to-4 triangle splits.

Apply Polygroup Catmull Clark SubD

Apply Catmull Clark Subdivision to the Polygroup Topology of the Mesh (discards input triangulation).

This node only works in the Editor.



Apply Triangle Loop SubD

Apply Loop Subdivision to the input mesh.

This node only works in the Editor.



Apply Selective Tessellation

Tessellate the specified mesh Selection using the indicated Pattern Type.

Apply PNTesselation

Applies PN Tessellation to the input mesh.

Apply Uniform Tessellation

Applies uniform tessellation to the input mesh.

Simplification Functions

These functions simplify a mesh using various strategies.

Node Name

Description

Apply Simplify To Triangle Count

Simplifies the mesh until a target triangle count is reached.

Apply Simplify To Vertex Count

Simplifies the mesh until a target vertex count is reached.

Apply Simplify To Tolerance

Simplifies the mesh to a target geometric tolerance. For example, any further simplification would result in a deviation from the input mesh larger than the tolerance.

Apply Simplify To Planar

Simplifies planar areas of the mesh that have more triangles than necessary.

This does not change the 3D shape of the mesh.



Apply Simplify To Polygroup Topology

Simplifies the mesh down to the Polygroup Topology. For example, the high-level faces of the mesh polygroups. Another example would be on a default Box-Sphere where simplifying to polygroup topology produces a box.

Normals Functions

These functions recompute the Normals of a mesh.

Node Name

Description

Flip Normals

Flips the mesh normals by reversing the orientation of each face.

Set Per Vertex Normals

Sets the mesh normals to per-vertex normals. For example, no split normals at any vertex.

Set Per Face Normals

Sets the mesh normals to per-face/triangle normals. For example, split normals along every edge of the mesh.

Compute Split Normals

Computes split-normals for the mesh based on an angle tolerance and/or other factors such as polygroup topology.

Recompute Normals

Recomputes the existing mesh normals. Preserves existing split normals. For use after mesh deformations, for example.

Compute Tangents

Recomputes tangents for the mesh (various methods).

Cleanup/Repair Functions

You can use these functions to fix issues in a mesh, or to apply other standard repairs.

Node Name

Description

Compact Mesh

Compacts the mesh's vertices and triangles to remove any "holes" in the Vertex ID or Triangle ID lists (see discussion in Low-Level Mesh Queries section).

Discard Mesh Attributes

Removes the Attribute Set from a Dynamic Mesh, such as all UVs, Normals, Material IDs, Vertex Colors, and extended Polygroup Layers. Note that this may prevent many functions from working.

Auto Repair Normals

This function tries to automatically reorient the Normals of a mesh so that they are consistent, such as fixing flipped normals.

Weld Mesh Edges

Welds any open boundary edges of the mesh together if possible in order to remove "cracks."

Fill All Mesh Holes

Tries to fill all open boundary loops (such as holes in the geometry surface) of a mesh.

Remove Small Components

Removes connected components of the mesh that have a volume, area, or triangle count below a threshold.

Remove Hidden Triangles

Removes any triangles in the mesh that are not visible from the exterior view, under various definitions of "visible" and "outside."

Resolve Mesh TJunctions

Attempts to resolve t-junction in the Target Mesh.

Split Mesh Bowties

Splits vertices in the Target Mesh that otherwise produce a bowtie where only a single vertex connects regions of the mesh.

Repair Mesh Degenerate Geometry

Modifies the Target Mesh by deleting small triangles or merging triangles until all edges are greater than a specified minimum length.

Low-Level Mesh Queries

These functions provide low-level information about the elements of a mesh. In this context, VertexID and TriangleID are integers.

In a Dynamic Mesh, there may be gaps in VertexID or TriangleID range — after vertices/triangles are deleted — and some operations (like Simplification) may return a mesh with gaps present. Gaps in the ID ranges are cleaned up using the Compact Mesh function.

Node Name

Description

Get Vertex Count

Gets the number of vertices in the mesh.

Get Num Vertex IDs

Gets the number of Vertex IDs in the mesh, which may be larger than the Vertex Count, if the mesh is not dense. For example, after deleting vertices.

Is Valid Vertex ID

Returns true if a Vertex ID refers to a valid vertex.

Get All Vertex IDs

Returns an IndexList of all Vertex IDs in mesh.

Get Vertex Position

Gets the 3D position of a mesh vertex, by Vertex ID.

Get All Vertex Positions

Returns a Vector List of all the mesh vertex positions. This list may be extensive.

Get Triangle Count

Returns the number of triangles in the mesh. Note that this is a function on the Dynamic Mesh directly.

Get Num Triangle IDs

Gets the number of Triangle IDs in the mesh. The number may be larger than the Triangle Count if the mesh is not dense, even after deleting triangles.

Is Valid Triangle ID

Returns true if a TriangleID refers to a valid Triangle.

Get All Triangle IDs

Returns an Index List of all Triangle IDs in a mesh.

Get Triangle Indices

Returns the vertex indices triplet for a Triangle.

Get All Triangle Indices

Returns a TriangleList of all Triangle indices triplets in a mesh.

Get TrianglePositions

Returns the three corner positions for a Triangle.

Get TriangleFace Normal

Returns the face/facet normal of a Triangle.

Get TriangleUVs

Returns the three corner UVs for a Triangle.

Get Triangle Material ID

Returns the current Material ID for a Triangle.

Get All Triangle Material IDs

Returns an Index List of all triangle Material IDs.

Get Triangle Polygroup ID

Returns the current Polygroup ID for a Triangle, in a given Polygroup layer.

Get Has Vertex ID Gaps

Returns true if there are gaps in the Vertex ID list. For example, Get Number of Vertex IDs is greater than Get Vertex Count.

Get Has Triangle ID Gaps

Returns true if there are gaps in the Triangle ID list, such that Get Num Triangle IDs is greater than Get Triangle Count.

Get Is Dense Mesh

Returns true if the mesh is dense. For example, no gaps in Vertex IDs or Triangle IDs.

Get Mesh Has Attribute Set

Returns true if the mesh has an Attribute Set enabled to store UVs, Normals, Material IDs, and Vertex Colors. This is generally enabled by default..

Low-Level Mesh Building

These functions construct a mesh triangle-by-triangle and perform other low-level mesh editing operations.

Using these functions in situations that involve looping over the elements of meshes with many thousands of triangles can be quite slow in Blueprint or Python scripting.

Node Name

Description

Set Vertex Position

Sets the 3D position of a mesh vertex.

Add Vertex To Mesh

Adds a new vertex to the mesh and returns a new Vertex ID.

Add Vertices To Mesh

Adds a list of vertices to the mesh.

Delete Vertex From Mesh

Removes a vertex from the mesh.

Delete Vertices From Mesh

Removes a list of vertices from the mesh.

Add Triangle To Mesh

Adds a triangle (3-element Vertex ID tuple) to the mesh.

Add Triangles To Mesh

Adds a list of triangles to the mesh.

Delete Triangle From Mesh

Removes a triangle from the mesh.

Delete Triangles From Mesh

Removes a list of triangles from the mesh.

Delete Triangles In Polygroup

Deletes all triangles from the mesh that have a particular polygroup, in a specific Polygroup layer.

Append Buffers To Mesh

Adds a set of vertices/triangles to the mesh, with attributes such as Normals and UVs. Similar to Create Mesh Section in Proc Mesh Component.

Set Mesh Triangle Normals

Sets the Normals of a mesh triangle.

Set Mesh Triangle UVs

Sets the UVs of a mesh triangle.

Set Triangle Material ID

Sets the Material ID of a mesh triangle.

Low-Level List Management

These functions cover list management for: Index List, Scalar List, Vector List, UV List, and Color List.

Node Name

Description

Get Index List Length

Returns the number of items in the Index List.

Get Index List Last Index

Returns the index of the last item in the Index List.

Get Index List Item

Returns the item stored in the Index List at the specified location.

Set Index List Item

Updates the value of the item stored in the Index List at the specified location.

Convert Index List To Array

Converts an Index List to an array of integers.

Convert Array To Index List

Converts an array of integers to an Index List.

Duplicate Index List

Duplicates the contents Index List into Duplicate List.

Clear Index List

Resets all the items in the Index List to the Clear Value.

Get Scalar List Length

Returns the number of items in the Scalar List.

Get Scalar List Last Index

Returns the index of the last item in the Scalar List.

Get Scalar List Item

Returns the Scalar (double) stored in the Scalar List at the specified location.

Set Scalar List Item

Updates the value of the Scalar stored in the Scalar List at the specified location.

Convert Scalar List To Array

Converts a Scalar List to an array of doubles.

Convert Array To Scalar List

Converts an array of doubles to a Scalar List.

Duplicate Scalar List

Copies the contents of Scalar List into Duplicate List.

Clear Scalar List

Reset all the items in the Scalar List to the Clear Value.

Get Vector List Length

Returns the number of items in the Vector List.

Get Vector List Last Index

Return the index of the last item in the Vector List.

Get Vector List Item

Return the FVector stored in the VectorList at the specified location.

Set Vector List Item

Updates the value of the FVector stored in the Vector List at the specified location.

Convert Vector List To Array

Converts a Vector List to an array of FVectors.

Convert Array To Vector List

Converts an Array of FVectors to a Vector List.

Duplicate Vector List

Copies the contents of Vector List into Duplicate Vector List.

Clear Vector List

Resets all the items in the Vector List to the Clear Value.

Get UV List Length

Returns the number of items in the UV List.

Get UV List Last Index

Returns the index of the last item in the UV List.

Get UV List Item

Returns the FVector2D stored in the UV List at the specified location.

Set UV List Item

Updates the value of the FVector2D stored in the UV List at the specified location.

Convert UV List To Array

Converts a UV List to an array of FVector2Ds.

Convert Array To UV List

Converts an array of FVector2D to UVList.

Duplicate UV List

Duplicates the contents of UV List into Duplicate List.

Get Color List Length

Returns the number of items in the Color List.

Get Color List Last Index

Returns the index of the last item in the Color List.

Get Color List Item

Returns the FLinearColor stored in the Color List at the specified location.

Set Color List Item

Updates the value of the FLinearColor stored in the Color List at the specified location.

Convert Color List To Array

Converts the Color List to an array of FLinearColor.

Convert Array To Color List

Converts an array of FLinearColor to a Color List.

Extract Color List Channel

Creates a Scalar List that corresponds to the 0,1, or 2 channel of a Color List.

Extract Color List Channels

Creates a Vector List from a Color List. The channels in the Color List are mapped to vector components by means of X Channel Index, Y Channel Index, and Z Channel Index.

Low-Level Math

Functions that operate on the Vector Lists and Scalar Lists in a component wise fashion. The functions that take multiple lists, such as Vector Dot, require the lists to have the same number of elements.

Node Name

Description

Vector Length

Computes the length of each vector in Vector List A and returns the value in the Scalar List.

Vector Dot

Computes the dot-product between each pair of vectors in Vector List A and Vector List B, and returns the value in the new Scalar List.

Vector Cross

Computes the cross-product between each pair of vectors in Vector List A and Vector List B and returns the value in the new Vector List.

Vector Normalize In Place

Normalizes each vector in Vector List, and stores the value in a Vector List. If a vector is degenerate, set the normal to the Set On Failure vector.

Vector Blend

Computes ConstantA * A + ConstantB * B for each pair of vectors in Vector List A and Vector List B, and returns the value in the new Vector List.

By default this (constants = 1) adds the two vectors. Set ConstantB = -1 to subtract B from A.

You can also use the function to Linear Interpolate, by setting ConstantB = 1 - ConstantA.



Vector Blend In Place

Computes ConstantA * A + Constant B * B for each pair of vectors in Vector List A and Vector List B, and stores the value in Vector List B.

By default this (constants = 1) adds the two vectors. Set ConstantB = -1 to subtract B from A.

You can also use the function to Linear Interpolate, by setting ConstantB = 1 - ConstantA.



Scalar Vector Multiply

Computes Scalar Multiplier * Scalar * Vector for each scalar/vector pair in the two input lists, and returns the value in a new Vector List.

Scalar Vector Multiply In Place

Computes Scalar Multiplier * Scalar * Vector for each scalar/vector pair in the two input lists, and stores the value in the input Vector List.

Constant Vector Multiply

Computes Constant * Vector for each element in the Vector List and returns the value in a new list.

Constant Vector Multiply In Place

Computes Constant * Vector for each element in Vector List, and stores the value in Vector List.

Vector To Scalar

Converts each Vector in Vector List to a Scalar by computing ConstantX * Vector.X + ConstantY * Vector.Y + ConstantZ * Vector.Z , and returns the value in a new Scalar List.

You can use it to extract the X, Y, and Z values from a Vector, or other component-wise math.



Scalar Invert

Computes Numerator / Scalar for each element of the Scalar List and returns the value in a new Scalar List.

If Abs(Scalar) < Epsilon, set to Set On Failure value.



Scalar Invert In Place

Computes Numerator / Scalar for each element of the Scalar List and stores the value in input Scalar List.

If Abs(Scalar) < Epsilon, set to Set On Failure value.



Scalar Blend

Computes ConstantA * A + ConstantB * B for each pair of values in Scalar List A and Scalar List B and returns the value in the new Scalar List.

By default this (constants = 1) just adds the two values. Set ConstantB = -1 to subtract B from A.

The function can also be used to Linear Interpolate, by setting ConstantB = 1 - ConstantA.



Scalar Blend In Place

Computes ConstantA * A + ConstantB * B for each pair of values in ScalarListA and ScalarListB and return in ScalarListB.

By default this (constants = 1) just adds the two values. Set ConstantB = -1 to subtract B from A.

Can also be used to Linear Interpolate, by setting Constant B = ( 1 - ConstantA ).



Scalar Multiply

Computes Scalar Multiplier * A * B for each pair of values in Scalar List A and Scalar List B, and returns the values in the new Scalar List.

Scalar Multiply In Place

Computes Scalar Multiplier * A * B for each pair of values in Scalar List A and Scalar List B, and returns the values in Scalar List B.

Constant Scalar Multiply

Computes Constant * Scalar for each value in Scalar List, and returns the values in the new Scalar List.

Constant Scalar Multiply In Place

Computes Scalar Multiplier A * B for each pair of values in Scalar List A and Scalar List B, and returns the values in the current Scalar List.

MaterialID Functions

Functions for manipulating Material IDs of a mesh. A Material ID is a per-triangle integer and is not directly connected to any specific Material. Each Material ID is associated with a Mesh Section when converting to or from a Static Mesh.

Node Name

Description

Get Has Material IDs

Returns true if the mesh has Material IDs available/enabled.

Enable Material IDs

Enables Material IDs on a mesh, initialize to 0.

Clear Material IDs

Resets all Material IDs on a mesh to 0.

Get Max Material ID

Returns the maximum Material ID currently set on a mesh.

Remap Material IDs

For all triangles with a Material ID matching a given value, and sets the Material ID to a new value.

Set All Triangle Material IDs

Sets the Material ID of all triangles in a mesh to the values in an input Index List.

Set Polygroup Material ID

Sets the Material ID of all triangles in a mesh that have a specified Polygroup ID (in a given Polygroup layer) to the specified Material ID.

Vertex Values

You use these values to get and manipulate mesh values stored at vertices, including Vertex Colors

Multiple values, such as Normals, can be stored at a given vertex but these methods will only return one.

Node Name

Description

Set Mesh Constant Vertex Color

Sets all vertex colors to a specific color.

Set Mesh Per Vertex Colors

Sets the color for every vertex using a Color List.

Get Mesh Per Vertex Colors

Gets a list of single vertex colors for each mesh vertex in the Target Mesh, derived from the Vertex Color Overlay.

Set Mesh Selection Vertex Color

Sets the colors in the Target Mesh's Vertex Color Overlay, identified by the Selection, to a constant value.

For a Vertex Selection, each existing Vertex Color Overlay Element for the vertex is updated.

For a Triangle or Polygroup Selection, all Overlay elements in the identified Triangles are updated.

For a Vertex Selection, each existing Vertex Color Overlay Element for the vertex is updated.

For a Triangle or Polygroup Selection, all Overlay elements in the identified Triangles are updated.



Convert Mesh Vertex Colors SRGB To Linear

Apply an SRGB to Linear color transformation on all vertex colors.

Convert Mesh Vertex Colors Linear To SRGB

Apply a Linear to SRGB color transformation on all vertex colors.

Get Mesh Per Vertex Normals

Get a list of single normal vectors for each mesh vertex in the Target Mesh, derived from the Normals Overlay.

Get Mesh Per Vertex UVs

Get a list of single vertex UVs for each mesh vertex in the Target Mesh, derived from the specified UV Overlay.

Texture Sampling and Creation

Functions for reading and creating texture data.

Node Name

Description

Sample Texture 2D At UV Positions

Sample the given Texture Map at the list of UV positions and return the color at each position in the Color List output.

Create New Texture 2D Asset

Create a serialized Texture 2D Asset from a temporary UTexture2D.

Baking

These functions bake data between a source and target mesh into texture or vertex color data. You can bake various mesh data such as normals, curvature, and ambient occlusion.

Node Name

Description

Bake Texture

Creates Textures for the Target Mesh from data sampled in the Source Mesh.

Bake Vertex

Populates the vertex colors in the Target Mesh with the results of the Baking properties of the given Source Mesh.

UV Functions

You use these functions to manipulate the UVs of a mesh.

Node Name

Description

Get Num UV Sets

Gets the number of UV Layers on a Mesh.

Set Num UV Sets

Sets the number of UV Layers on a Mesh.

Get UV Set Bounding Box

Gets the 2D bounding box of all UVs in a UV Set.

CopyUVSet

Replaces target UV set with values from source UV set.

Translate Mesh UVs

Applies 2D Translation to all UVs, or a subset of UVs if you provide a Selection, in the UVSet Index.

Scale Mesh UVs

Applies 2D Scale to all UVs, or a subset of UVs if you provide a Selection, in the UVSet Index.

Rotate Mesh UVs

Apples 2D Rotation to all UVs, or a subset of UVs if you provide a Selection, in the UVSet Index.

Recompute Mesh UVs

Recomputes UVs for a Mesh based on different types of well-defined UV islands, such as existing UV islands, PolyGroups, or the Selection input.

Repack Mesh UVs

Packs the existing UV islands into standard UV space.

Set Mesh UVs From Planar Projection

Using Planar projection, set UVs for an entire mesh or a subset you define by the Selection input.

Set Mesh UVs From Box Projection

Using Box Projection, set UVs for an entire mesh or a subset you define by the Selection input.

Set Mesh UVs From Cylinder Projection

Using Cylinder Projection, set UVs for an entire mesh or a subset you define by the Selection input.

Auto Generate Patch Builder Mesh UVs

Computes new UVs using PatchBuilder method, and optionally pack.

Auto Generate X Atlas Mesh UVs

Computes new UVs using XAtlas, and optionally packs.

Get Mesh UVSize Info

Computes information about dimensions and areas for a UVSet of a Mesh, with an optional Mesh Selection.

Get Mesh Per Vertex UVs

Gets a list of single vertex UVs for each mesh vertex in the TargetMesh, derived from the specified UV Overlay.

Copy Mesh UV Layer To Mesh

Copies the 2D UVs from the given UVSet Index in Copy From Mesh to the 3D vertex positions in Copy To UV Mesh. Polygroup IDs and Material IDs are preserved in the UV Mesh.

Copy Mesh To Mesh UV Layer

Transfers the 3D vertex positions and triangles of Copy From UVMesh to the given UV Layer identified by To UV Set Index of Copy To Mesh. The 3D positions (X,Y,Z) will be copied as UV positions (X,Y).

PolyGroup Functions

Functions for manipulating PolyGroups of a mesh. PolyGroups are per-triangle integers that implicitly define regions and patches of triangles in Modeling Tools and some Geometry Script operations. However, a PolyGroup layer is ultimately a per-triangle number, and you can use it for any other purpose.

Node Name

Description

Get Has Polygroups

Returns true if the mesh has a standard Polygroup Layer.

Enable Polygroups

Enables standard Polygroup Layer on a Mesh.

GetNum Extended Polygroup Layers

Returns the count of extended Polygroup Layers.

Note that extended Polygroup Layers are not yet fully supported by all operations or modeling tools.



Set Num Extended Polygroup Layers

Sets the number of extended Polygroup Layers on a Mesh.

Clear Polygroups

Resets the triangle Polygroup assignments to a constant value for a given Polygroup Layer.

Copy Polygroups Layer

Copies Polygroups from one layer to another.

Convert UV Islands To Polygroups

Creates and assigns a new Polygroup for each disconnected UV island of a Mesh.

Convert Components To Polygroups

Creates and assigns a new Polygroup for each disconnected component of a Mesh.

Compute Polygroups From Angle Threshold

Sets Polygroups by partitioning the mesh based on an edge crease/opening-angle.

Compute Polygroups From Polygon Detection

Identifies polygons and assigns Polygroup IDs.

Mesh Geometric Queries

These functions allow for high-level geometric queries of a mesh.

Node Name

Description

Get Mesh Bounding Box

Computes the bounding box of the mesh vertices.

Get Mesh Volume Area

Computes the volume and area of the mesh.

Get Is Closed Mesh

Returns true if the mesh is closed, such as no topological boundary edges.

Get Num Open Border Loops

Returns the number of open border loops, such as "holes" in the mesh.

Get Num Open Border Edges

Returns the number of topological boundary edges in the mesh.

Get Num Connected Components

Returns the number of separate connected-components in the mesh, such as "triangle patches" connected by shared edges.

Compute Mesh Convex Hull

Computes the Convex Hull of a given Mesh, or part of the mesh you define by the Selection input, and returns in a separate mesh.

Compute Mesh Swept Hull

Computes a 2D swept-hull of the input mesh and returns in a separate mesh.

Compute Mesh Convex Decomposition

Computes a Convex Hull Decomposition of the given Target Mesh. Assuming more than one hull is requested, multiple hulls will be returned that attempt to approximate the mesh. There is no guarantee that the entire mesh is contained in the hulls.

PolyPath

These functions perform PolyPath manipulations. A PolyPath is a path defined by an ordering of vertices.

Node Name

Description

Get Poly Path Num Vertices

Returns the number of vertices in the PolyPath

Get Poly Path Last Index

Returns the index of the last vertex in the PolyPath.

Get Poly Path Vertex

Returns the 3D location of the specified vertex.

Get Poly Path Tangent

Returns the local tangent vector of the PolyPath at the specified vertex index.

Get PolyPath Arc Length

Returns the length of the PolyPath.

Get NearestVertexIndex

Returns the index of the nearest PolyPath vertex to the specified point in 3D.

Flatten To 2D On Axis

Creates a 2D flatten copy of the path, by dropping the given axis and using the other two coordinates as the new X, Y coordinates.

Convert Spline To PolyPath

Samples the positions from a USplineComponent into a PolyPath, based on the given Sampling Options.

Convert PolyPath To Array

Populates an array of 3D vectors with the PolyPath vertex locations.

Convert Array To PolyPath

Creates a PolyPath from an array of 3D position vectors.

Convert PolyPath To Array Of Vector 2D

Creates an array of 2D Vectors with the PolyPath vertex locations projected onto the XY plane.

Convert Array Of Vector 2D To PolyPath

Creates a PolyPath from an array of 2D position vectors. The Z-coordinate of the corresponding PolyPath vertices will be zero.

Create Circle Path 3D

Creates a closed circle around the origin on the XY plane, then is repositioned by the Transform input.

Create Circle Path 2D

Creates a closed circle on the XY plane around the given Center.

For closed paths, the end vertex is not a duplicate of the start vertex.



Create Arc Path 3D

Creates an open arc around the origin on the XY plane, then is repositioned by the Transform input.

Create Arc Path 2D

Creates an open arc on the XY plane around the given Center.

Mesh Comparisons

These functions enable comparisons between two meshes. These nodes do not modify either mesh through their usage.

Node Name

Description

Is Same Mesh As

Returns true if the two input meshes are equivalent under the comparisons defined by the input options.

Measure Distances Between Meshes

Measures the min/max and average closest-point distances between two meshes.

Is Intersecting Mesh

Returns true if the two input meshes (with optional transforms) are geometrically intersecting.

BVH & Spatial Queries

These functions create and query a Bounding Volume Hierarchy (BVH) object for a mesh.

Node Name

Description

Build BVH For Mesh

Builds a BVH object for a mesh that can be used by Is BVH Valid For Mesh, Rebuild BVH for Mesh, Find Nearest Point On Mesh, Find Nearest Ray Intersection With Mesh, and Is Point Inside Mesh nodes. The function returns a Geometry Script Dynamic Mesh BVH struct.

Is BVH Valid For Mesh

Checks if the BVH object can still be used with the Mesh — it generally returns false if the mesh has been changed.

Rebuild BVH For Mesh

Rebuilds the BVH object for the mesh in-place, which can reduce memory allocations, compared to building a new BVH.

Find Nearest Point On Mesh

Finds the nearest point on the mesh/BVH to a given 3D point.

Find Nearest Ray Intersection With Mesh

Finds the nearest intersection of a 3D ray with the mesh/BVH.

Is Point Inside Mesh

Tests if a point is inside the mesh/BVH using the Fast Winding Number query.

Utilities

These helper functions are useful in Geometry Script mesh processing and procedural generators.

Node Name

Description

Create Dynamic Mesh Pool

Creates a new Dynamic Mesh Pool object.

Create Unique New Asset Path Name

Create a new unique asset name given a base path and base asset name, which is useful with functions like Create New Static Mesh Asset From Mesh.

This node only works in the Editor.



Get Mesh Info String

Returns a debug string that contains mesh statistics and other information.

Sample Spline To Transforms

Sample a USplineComponent into a list of FTransforms, based on the given Sampling Options.

Glossary

Term

Definition

Overlay

A data structure representing a type of vertex data applied to a mesh.These types include: vertex color, normal, tangent, and UV.

Multiple values of the specified type can be stored at a single vertex. In such cases, depending on the type, one of the following occurs: the last value is used, the values are averaged, or an arbitrary value is used.



One-ring

The neighboring vertices of the selected vertex, connected by an edge.



The one-ring of vertex M.



UV Set/Layer

Contains the UV coordinates of a mesh, also referred to as the UV Channel. You can use multiple UV Channels to represent different UV maps.

Getting Started

Guides

Software and File Type Interop Guides

Reference

Datasmith is a collection of tools and plugins that bring entire pre-constructed scenes and complex assets created in a variety of industry-standard design applications into Unreal Engine.

The following pages will help you understand how Datasmith works, what kind of results it produces in Unreal, and how to use it to start crafting real-time visualizations around your design content.

Getting Started



An overview of how Datasmith works, and what you should expect when you use it.



How to use Datasmith to bring files that you create in supported 3D design applications into Unreal Engine.

Guides



Contains details about specific issues in the way Datasmith imports scenes into Unreal, and next steps you can follow to work with the imported Assets in Unreal Engine.



Describes what happens when you reimport content that you brought into Unreal using Datasmith, and how you can take advantage of this iterative workflow.



Describes how to import Datasmith and CAD files using Blueprint or Python, and how to change the way your scene is transformed into Unreal Assets and Actors.



Make reusable recipes that import assets and prepare them for real-time rendering.



Get custom metadata about Assets into Unreal, and use Blueprint and Python scripting to work with that metadata in the Editor and at runtime.



An overview of Datasmith Direct Link technology in Unreal Engine.

Software and File Type Interop Guides



The Datasmith 3ds Max Exporter plugin brings content from Autodesk 3ds Max into the Unreal Editor.



How to import Datasmith scenes from Graphisoft Archicad into Unreal Engine.



Describes special considerations that apply only when you use Datasmith to bring scenes from Maxon Cinema 4D into the Unreal Editor.



Describes special considerations that apply when you use Datasmith to import scenes from 3DExcite Deltagen or Autodesk VRED.



Describes special considerations that apply only when you use Datasmith to bring scenes from Autodesk Navisworks into the Unreal Editor.



Describes special considerations that apply only when you use Datasmith to bring scenes from Autodesk Revit into the Unreal Editor.



Describes special considerations that apply when you use Datasmith to import scenes from McNeel Rhinoceros 3D.



Describes special considerations that apply only when you use Datasmith to bring scenes from Trimble SketchUp Pro into the Unreal Editor.



Describes how to install the Datasmith Solidworks Exporter plugin, how to get Solidworks content into Unreal Engine, and how Datasmith coverts Solidworks content.



Describes special considerations that apply when you use Datasmith to import content from CAD file formats.



Describes special considerations that apply only when you use Datasmith to bring scenes from IFC files into the Unreal Editor.

Reference



An overview of how Datasmith works, and what you should expect when you use it.



Details all the third-party software applications and data formats that Datasmith works with.



Describes all the options you can set when you use Datasmith to import content into Unreal Engine.



Details what Datasmith features work on which different platforms.



Outlines guidelines and best practices for developing an application to export third-party content to Unreal Engine via Datasmith.

How Datasmith Helps

The Datasmith Workflow

What You Get After Import

Static Mesh Assets

Material Assets

Texture Assets

Other Asset Types

The Datasmith Scene Asset

Level Actors and the Scene Hierarchy

Tracking and Handling Overrides

Properties Tracked as Overrides

Next Steps

Datasmith is a collection of tools and plugins that help you bring content into Unreal Engine 5.

Datasmith is designed to solve the specific challenges faced by people outside of the game industry who want to use the Unreal Engine for real-time rendering and visualizations — in industries including architecture, engineering, construction, manufacturing, live training, and more. But it also may be of interest to game developers who share similar problems in their asset pipelines.

How Datasmith Helps

Datasmith has some very ambitious goals:

To bring entire pre-constructed scenes and complex assemblies into Unreal, regardless of how large, dense or heavy those scenes may be. Rather than forcing you to deconstruct your scenes and assemblies into individual chunks, then pass each chunk to the game engine separately through an FBX import pipeline, then re-assemble the scene in the Unreal Editor, Datasmith re-uses the assets and layouts that you've already built for other purposes in other design tools.

To support the widest possible range of 3D design applications and file formats. It already works with a huge variety of sources, including Autodesk 3ds Max, Trimble Sketchup, Dassault Systèmes SolidWorks, and more with each release.

To handle the tricky problem of bringing in changes that get made in source material that you've already imported, without requiring you to re-do all the work that you've done to those Assets in Unreal. (To read more about this, see Datasmith Reimport Workflow.)

Currently, Datasmith is focused on translating your design content into forms that Unreal Engine can understand and render in real-time. Longer-term, the aim is to add more intelligent data preparation, tailoring the imported content for maximum runtime performance in the game engine, and adding smarter runtime behaviors.

The Datasmith Workflow

Datasmith currently uses a file-based workflow to bring your designs into Unreal.

You save or export your design data in a format that Datasmith can handle. Datasmith reads the native file format of many common CAD applications. For some applications, including 3ds Max and SketchUp Pro, you'll need to install a special plugin, which you'll use to export files with the .udatasmith extension. (See the Datasmith Supported Software and File Types.)

In the Unreal Editor, you use the Datasmith Importer to bring the saved or exported file into your current Unreal Engine Project. At this point, you can control what data you want to bring in from that file, and set a few parameters that control the translation process. (See the Datasmith Import Options.)



Click image for full size.

What You Get After Import

After you use Datasmith to import a file, the first thing you should see is all the elements of your source scene appearing in the Unreal Editor viewport. They may not look amazing yet — you'll handle lighting and look development later — but at this point your Unreal Level should be already be assembled exactly the way it was in your source application.



Click image for full size.

You'll also see that many new Assets are created in your Project's Content Browser (1), and new Actors are placed in the current Level (2).

Static Mesh Assets

For many reasons, Datasmith avoids bundling everything in your source scene into a single mesh in Unreal. Overly large, complex meshes are typically very hard to light and render smoothly with good performance, and restrict you from being able to work with the various parts of your scene individually in Unreal.

Instead, Datasmith creates a set of separate Static Mesh Assets, each of which represents a building block for the scene: an individual chunk of geometry that can be placed into a Level and rendered in the Engine. In dividing the scene up into Static Meshes, Datasmith does its best to respect whatever object organization you've already set up in your source application.

Datasmith places each of these Static Mesh Assets into the Geometries folder:



If your source scene contains multiple copies of the same geometry, Datasmith usually creates only one Static Mesh Asset for that object. It uses multiple instances of that Asset in the Level, each with its own position, rotation, and other properties. This typically reduces memory use at runtime and increases performance. For example, in this scene, there are many hanging lights, but only one Static Mesh Asset (L_Globe_01).

To read more about Static Meshes in Unreal, see Static Meshes.

Material Assets

Every Static Mesh in Unreal needs to be assigned one or more Material Assets, which describe the way its surfaces interact with incoming light. For each different type of surface Datasmith identifies in your source scene, it creates a new Material Asset in the Materials folder, and assigns it to the Static Mesh Assets that need to use it.



To read more about Materials and Unreal's physically based rendering system, start here: Materials.

Texture Assets

If your source application uses any textures to define the colors or other physical properties of the scene's geometry, Datasmith imports each of those textures into a Texture Asset in the Textures folder, and sets up the corresponding Material to refer to the new Texture Asset. If necessary, Datasmith may also convert your source image file to a format that Unreal recognizes.



For information on working with Textures in Unreal, see Textures.

Other Asset Types

Static Meshes, Materials, and Textures, described in the preceding sections, are the kinds of Assets that you'll see most often in scenes that you import with Datasmith. Depending on the kinds of elements you have in your source scene, you may also see some other new folders in your Content Browser next to your Geometry, Materials, and Textures folders.

Lights - If your scene contains any lights that use IES profiles to specify the way their intensities change over distance, the Datasmith importer places into this folder the Texture Assets that define those light intensities. For more information on IES Light Profiles in the Unreal Engine, see also IES Light Profiles.

Animations - If your scene contains objects with position, rotation, or scale values that change over time, the Datasmith importer converts those animations into Sequence Assets. You can use these Sequences to replay the animations from your source scene within the Unreal Engine or Unreal Editor. For details on how this conversion is carried out, see Datasmith Import Process.

The Datasmith Scene Asset

Datasmith creates a single Datasmith Scene Asset, named according to the file you imported. This new kind of custom Asset is a key part of the Datasmith import strategy. Its job is to contain everything needed to re-assemble your original scene in the Unreal Editor from the Static Mesh building blocks that were imported along with it, and the built-in object types provided by the Unreal Engine.

It stores references to all the Static Mesh, Material and Texture Assets that were imported with it.

It stores the import settings you used to create it.

Most importantly, it contains a hierarchy or tree of all the types of objects in your original scene that Datasmith supports, including geometry objects, lights, and cameras. Each of these scene elements stores its position, rotation and scale in 3D space relative to its parent. In addition, each different type of element maintains a set of information that Datasmith was able to convert from your source application.

You can drag and drop the Datasmith Scene Asset into any Level to place a fully assembled representation of your original scene or CAD assembly into the Level. This recreates its full scene hierarchy automatically in your Level, using Unreal Engine equivalents for the information it brought in from your source file. See the next section for details.

Level Actors and the Scene Hierarchy

Finally, when all of your new Assets are ready, Datasmith places an instance of your Datasmith Scene into your current Level, replicating inside your Level the entire scene hierarchy that Datasmith was able to convert from your source application or file format.

Each element in the scene hierarchy is represented by a type of Unreal Engine Actor.



Geometry objects are typically represented by Static Mesh Actors, which reference the Static Mesh Assets in your Content Browser.

If your imported scene contains lights, these will typically be represented using one of the Light Actor types built in to Unreal, such as a Point Light or a Spot Light. See Light Types and Their Mobility.

If your imported scene contains any cameras, these will typically be represented by an Unreal Camera Actor or CineCamera Actor.

At the root of the imported scene hierarchy you'll find a Datasmith Scene Actor, which references the Datasmith Scene Asset that was used to create it.

Often you'll see other kinds of Actors in the scene hierarchy, such as Lift_C or Lift_R in this image. Datasmith typically creates one of these Actors any time the parenting hierarchy in your source scene has a parent that is not associated with a particular geometry object. These Actors typically don't have any Static Meshes, lights or other objects assigned to them. However, these Actors can still be handy to use when managing your scene. Because the transforms of children are relative to their parents, as you move a parent Actor around in the scene, all of its children automatically follow.

Tracking and Handling Overrides

The Datasmith Scene keeps track of certain kinds of changes, or overrides, that you make to your imported Assets and Actors in Unreal. This has two main benefits:

You can selectively roll back the changes that you make to an Asset or Actor in Unreal. This returns all of the information Datasmith tracks about those selected Assets or Actors to the way it was when you first imported your content through Datasmith. Right-click the Asset in the Content Browser, or right-click the Actor in either the Viewport or the World Outliner, and select Datasmith > Reset Overrides.



Click image for full size.

When you reimport a Datasmith Scene, you don't lose any of the tracked overrides you've made in Unreal. For example, if you've moved an Actor to a new position in the scene, or set a different Material for an Actor, Datasmith preserves those changes after you re-import the scene. For more information, see Datasmith Reimport Workflow.

Properties Tracked as Overrides

In general, changes you make to any information that Datasmith brings into Unreal from your source application are tracked as overrides. Changes that you make to additional Unreal-specific properties are not tracked as overrides.

For example:

For each Actor that Datasmith creates in your Level, it brings the transform of that Actor in 3D space into Unreal from your source application. If you move or rotate an Actor in your Level, Datasmith tracks that change as an override.

On the other hand, each Static Mesh Actor has a Cast Shadow setting, which is not imported from your source application. Datasmith enables this setting by default when it creates each new Actor. If you change that setting to turn shadow casting off, Datasmith does not track that change as an override. If you reset overrides for this Static Mesh Actor, that setting remains turned off.

The following table lists the kinds of information that the Datasmith Scene currently tracks as overrides for each type of Asset and Actor it creates in Unreal.

Object type

Tracked properties

Static Mesh Actors

3D transforms

Mobility

Layers

Tags

Material assignments

Changing Material assignments also overrides the default connection between Static Mesh Assets and Actors that represent instances of those Assets inside a Level. If you modify the Material assignment in a Static Mesh Asset that you imported with Datasmith, Static Mesh Actors in your Levels that are instances of that Asset are not immediately updated as they typically would be.

Light Actors

3D transforms

Intensity and color values set by Datasmith

IES profiles

Layers

Tags

Camera Actors

3D transforms

FOV and exposure values set by Datasmith

Layers

Tags

Static Mesh Assets

Material assignments

Lightmap resolutions and Build settings

Tessellation settings (for Static Meshes that come from CAD files)

Changes you make to the geometry of the Static Mesh Asset itself in Unreal, such as removing triangles, are not tracked as an overrides.

Material Instance Assets

All the settings that you can modify in the Material Instance Editor are tracked by Datasmith as overrides. This includes all settings exposed by the Parent Material. It also includes the settings that are common to all Material Instances, such as Parent, Blend Mode, Two-Sided, and so on.

Parent Material and Texture Assets

None.

Next Steps

Now that you're familiar with the basics of the Datasmith import workflow, and how you can work with your Datasmith content in your Project, you can:

Read more about the details of what happens inside the Datasmith import process.

Read about special considerations for the 3D software you want to use with Datasmith, in the Datasmith Software Interop Guides.

Import a Datasmith file yourself and get started. See the Tutorial pages.

Setting Up Collisions With Static Meshes

Material Instance Editor UI

Instanced Materials

Real-Time Compositing with Sequencer

Generating Lightmap UVs

Lightmass Basics

Using Datasmith Metadata

Setting up Collisions with Static Meshes in Blueprints and Python

Modeling Mode Overview

Using UV Channels With Static Meshes

Units and Scale

Names and Labels

Triangle Facing Direction

Collisions and Physics

Lights

Materials

Animations

Layers

Metadata

The following sections provide details about specific issues that Datasmith handles during the scene conversion. Understanding these issues can help you understand the results that Datasmith produces, and to work with your content in the Unreal Editor.

You can download the two projects used in this page from Sketchfab:

"Richard's Art Gallery - Audio Tour" by shinymagic is licensed under Creative Commons Attribution.

"Vintage fan" by Noah is licensed under Creative Commons Attribution.

Units and Scale

In Unreal Engine, all distances are always measured in centimeters. However, other 3D design applications typically offer a choice of units of measurement. If you use a different unit of measurement in your source application, Datasmith automatically takes care of adjusting the scale of your scene so that your geometry appears at exactly the same real-world size in the Unreal Engine, and at the right locations in 3D space. You don't have to change anything about the way you work in your source application.

For example, if you use inches as the unit of measurement in your source application, an object that is ten units long in your original scene becomes 25.4 world units long in the Unreal Engine.





Source

After import

When a scene hierarchy contains parents with non-uniform scales and custom pivot transforms that are compensated for at the level of individual objects, the complexity of the coordinate system conversions can make the results in Unreal Engine not match your initial scene. If you encounter this problem, you may be able to solve it by returning to your original scene and simplifying the transforms in your scene hierarchy.

Names and Labels

Datasmith detects naming information about the geometry in your source application, and reuses this information as much as possible for the Assets and Actors that it creates. The exact process is a little different for each different application or file format, and the results in the Unreal Engine may be slightly different from your source application, but the ultimate goal is to make it possible for you to find and manage your content after import.

For Static Meshes, you'll see that the name of the Asset in the Content Browser, the filename of the Asset on disk, and the name of the Actor in the Level are often different.

Content Browser label - Datasmith generates the label for each Static Mesh Asset in the Content Browser based on the naming information it finds in your source file, if any. Some supported applications and file formats allow multiple objects to exist with the same name. If this is the case in your scene, you may find that several Assets in the Content Browser end up with the same label.

Filename - However, the file name of each Asset on disk needs to be unique. Therefore, Datasmith names each Asset file using a unique identifier that it extracts from the source application.

Actor name - Each time Datasmith places an Actor into a Level, it tries to give that Actor exactly the same name the corresponding object had in your source file, if any. If it can't find a unique name, it reuses the same label from the Content Browser to name the Actor. If another Actor already exists in the Level with that name, Datasmith makes the Actor name unique by incrementing a numeric suffix.

Note that there is a distinction between the labels that you see for Static Mesh Assets in the Content Browser, and the names of the files Datasmith generates for those Assets on disk. This should be transparent for most purposes while you're working in the Editor. However, if you want to use Blueprint or Python scripting to work with your Assets or your Datasmith Scene, you may need to be aware of this distinction.

Triangle Facing Direction

In order to achieve the best possible performance at runtime, Unreal Engine culls any triangles that it doesn't expect to be visible. This avoids spending any GPU cycles to render those triangles. In particular, the Engine assumes that all objects have a thickness. Any triangles that face away from the camera are assumed to be the back side of that object, and will be hidden from view by the front side of the object. This is called back-face culling, and it's an optimization technique that is used extensively in 3D rendering.

However, some design applications do not make the same distinction between the front and back faces of a surface, and may render surfaces regardless of which side you view them from. When working in your design tool, you may not always be aware of the facing direction of a given surface. This can lead to the surface normal, which is the direction perpendicular to the surface, pointing inward, or away from the direction that you need the surface to be viewed from. This may lead you to create planar, single-walled geometry without any thickness at all.

After you import your scene, this may cause some parts of your scene to be invisible when viewed from certain angles in the Unreal Engine. It may even look as if those parts of your model were not imported; however, the likelihood is that their surface normals are pointing away from the camera you're using to view the scene. If you rotate around the model, you may find that those surfaces suddenly appear.

For example, in the following scene (on the left), the ceiling and the ends of the pipes appear to be missing, even though the geometry was imported correctly. Enabling the Two Sided option for the Materials makes the surfaces appear (see below for details).





The best way to deal with this situation is in your source application. Keep the following suggestions in mind:

We highly recommend modeling all objects with thickness whenever they need to be seen from all sides, and making sure that the normals face outward.

If you know that your object will only need to be viewed from one side, you can fix the missing mesh by flipping the normal of the surface in your source application and re-importing the scene. This leaves the surface as one-sided, but at least inverts the facing direction of the surface so that it appears correctly when viewed in the Unreal Engine from the direction you need.

Some modeling applications, such as Rhino, 3ds Max, Cinema 4D and SketchUp, offer viewport modes that make it easier to find back-facing triangles. See the documentation for your modeling tool for details.

However, if you want to fix the problem in the Unreal Editor without going back to your source scene, you could also consider the following options:

You can flip the orientation of the triangles in the Static Mesh Editor so that they face the other direction. See Modeling Mode Overview. However, the same problem will still remain if those triangles are visible from the other side. This may be a good solution for something like a ceiling that will only be seen from the inside, but not for an interior wall that can be seen from both sides. Keep in mind that if you ever modify this piece of geometry in your source scene and re-import your Datasmith Scene Asset, you'll lose the changes you made in the Static Mesh Editor. So if you have to go back and modify your geometry for another reason, make sure to go back and fix the orientation of the faces in SketchUp at the same time.

You can make the Material two-sided in the Material Editor. This makes the Engine render the surface when it is seen from either side. Although this sounds at first like a good solution, it tends to produce visual artifacts when used with Static or Stationary lighting, as both sides of the surface will use the same space in the lightmap texture. If your Material is a Material Instance, look in the Details panel of the Material Editor for General > Material Property Overrides > Two Sided. Or, you can find this property in the Details panel of the Material Editor.



Click for full image.

You may have an issue not with the visibility of the face itself, but only with light coming through the object — such as a ceiling that does not correctly block light from a directional light overhead. To address this, configure the Static Mesh Actor so that it casts shadows from both sides. Look in the Details panel for the Lighting > Shadow Two Sided setting.



Click for full image.

Unreal Engine offers multiple ways to light your scene. The method that offers the best runtime performance, and typically the smoothest, most realistic spread of indirect illumination, is baked lighting. To use this approach in Unreal Engine, you give the lights in your scene a Mobility setting of either Static or Stationary, then use a tool in the Unreal Editor called Lightmass to build the lighting for the scene. This calculates the light that hits each object in the scene from those Static and Stationary lights, and stores it in a special kind of texture, called a lightmap. At runtime, this lighting information is applied from each object's lightmap texture to its surface.

In order for this system to work, every vertex in a Static Mesh needs to be mapped to a unique coordinate in the 2D space of its lightmap texture. This mapping is called a UV set or UV channel. Moreover, this 2D coordinate space needs to be laid out in such a way that no two triangles in the mesh overlap each other in the 2D texture space. If two triangles in the mesh are mapped the same area of the 2D texture, then Lightmass won't be able to store a unique pattern of light and shadow for each of those triangles. This causes odd lighting artifacts at runtime.

To ensure that all your Static Meshes are ready to receive static lighting, Datasmith automatically invokes the Unreal Editor's automatic UV unwrapping system for each Static Mesh it imports. This process adds two new UV sets to each Static Mesh:

One is a simple unwrapping of the triangles that make up the mesh into a flat representation in 2D space. This breaks the mesh into multiple smaller "islands" that each represent a connected section of the mesh surface.

The islands in the first lightmap are then rearranged and resized to fit into a layout that avoids any overlap, and that minimizes wasted space around the islands. This is the final layout that will be used for the object's lightmap when you build the lighting for your Level.

Then, Datasmith automatically sets up the Static Mesh Asset to use the second generated UV for storing and applying lightmaps.

If you use 3ds Max, and you have already set up UV channels that you want to use for your lightmaps, refer to the Datasmith for 3ds Max guide.

Collisions and Physics

By default, Datasmith doesn't set up any physics for the Static Mesh Assets it creates. You can set up physics for your Static Meshes in the Unreal Editor after you import; for details, see Setting up Collisions With Static Meshes, or Setting up Collisions With Static Meshes in Blueprint and Python.

If you're working with 3ds Max, you can model your own custom geometry in 3ds Max, and have the Datasmith importer automatically assign that geometry to the Static Mesh Assets it creates. For details, refer to the Datasmith for 3ds Max page.

Lights

Datasmith imports light sources from file formats that support them, converting them automatically into the most appropriate type of light supported by Unreal Engine: typically, a Point Light, Spot Light, Rectangular Area Light, or Directional Light.

Area, Plane, and Volume Lights

Some applications, such as 3ds Max and Cinema 4D, support lights that are emitted from 2D shapes or 3D volumes. These types of lights do not have an exact counterpart in the Unreal Engine. This includes mental ray area lights, V-Ray and Corona plane, disc, dome and sphere lights, and so on. When Datasmith imports one of these area lights, it mimics the light's behavior using a special, custom-written Blueprint class called DatasmithAreaLightMesh.





This Blueprint essentially pairs an auto-generated emissive surface with an auto-generated Rect Light, Point Light, or Spot Light:

The job of the emissive surface is to represent the visible, physical extents of the light in the Level's 3D space, and in reflections from other surfaces.

The job of the Rect Light, Point Light, or Spot Light is to emit the actual light out into the scene.

You can control the shape, size, color, and intensity of the emissive glow, and the properties of the Light Actor. Select the DatasmithAreaLightMesh Actor in the Level Viewport or World Outliner, and use the settings in the Light category of the Details panel. For example:



Click for full image.

Some settings, such as Color and Intensity, affect both the emissive glow and the Light Actor.

The result of this setup is a light that has a visible presence in the scene, and that illuminates surrounding objects. However, unlike in offline renders you might do in your source application, if your DatasmithAreaLightMesh uses a Spot Light or a Point Light, the actual light the DatasmithAreaLightMesh emits into the Level is cast from a single point rather than from the whole surface.

The emissive surface does not currently cast any light out into the scene, regardless of whether you bake your lighting using Lightmass or whether you use dynamic lighting. Only the Point Light or Spot Light Component actually illuminates the surrounding objects in the Level.

Materials

The Datasmith import process creates a new Material Asset in the Unreal Engine Project to represent each different set of geometry surface properties it recognizes in the scene it imports. Although the goal of the scene transformation is to carry over surface properties with the best possible fidelity, you'll likely need to tweak these Materials after import. You can double-click any Material Asset to edit it.

Most of the Material Assets that you'll find in the Materials folder are Material Instances. That means that when you edit the Material Instance, you'll see a pre-set list of settings that are determined by its parent or "master" Material. In the Content Browser you can see whether a material is a Material Instance.



Click for full image.

For more information about what Material Instances are and how to work with them, see Instanced Materials and Creating and Using Material Instances.

Each Material Instance also has a Parent Material: a different kind of Material Asset that contains a node graph similar to a Blueprint. This graph determines the actual operations that are carried out on the GPU when the Unreal Engine needs to render a surface that has the Parent Material or any of its Material Instances applied. The way the Parent Material's graph is constructed also controls the settings that are exposed in its Material Instances, and how those settings are used.

Datasmith assigns your Material Instances different Parent Materials depending on your source application, according to the following principles:

In most cases, Datasmith assigns each Material Instance a pre-existing Parent Material that is included as part of the Datasmith plugin. Typically, the pre-defined settings exposed by these Parent Materials are very similar to the material authoring settings that are available in your source application.

You can freely edit these exposed settings in each Material Instance that Datasmith creates in your Project. Each different Parent Material offered by Datasmith offers a different set of properties:

Datasmith_Color - This Parent Material is used for solid colors and textured surfaces, mostly when importing CAD models. See The Datasmith Color Material below.

SketchUpMaster - This Parent Material is used for all surfaces imported from SketchUp. See the SketchUp Pro interop guide.

RevitMaster - This Parent Material is used for all surfaces imported from Revit. See the Revit interop guide.

If you're importing content from 3ds Max or Rhino, you may find that Datasmith also creates new Parent Materials in your Project, inside the Materials/Master folder. 3ds Max offers a much richer Material authoring workflow than most other source applications, and one that is conceptually similar to Unreal Engine Material graphs. Therefore, Datasmith is typically able to create new Master Materials that are very close to the custom Materials you have in 3ds Max, rather than having to reuse pre-set Parent Materials that have a pre-set graph and a pre-set list of exposed settings. In this case, Datasmith typically still creates Material Instances for those custom Parent Materials. It then applies those Material Instances to your Static Mesh Assets and to the Static Mesh Actors in your scene. In most cases, modifying the properties of the Material Instances should be enough to give you a good level of control over the rendered results. For some types of 3ds Max Materials, Datasmith may skip creating the Material Instances. In this case, it simply assigns the new Parent Material to your Static Mesh Assets and Actors.

If you want to alter the actual Material graph that a Material Instance uses to determine how to shade the surface based on those properties, you need to duplicate the Parent Material and modify the properties in your duplicate. For details on this process, see Modifying a Datasmith Master Material.

Another option, instead of working with the Materials created by Datasmith, is always to completely replace the Material created by Datasmith with another physically based Material. This could be a Material that you create yourself in Unreal Editor, or from a third-party.

The Datasmith Color Material

Many computer-aided design (CAD) applications use simple surface colors to shade geometry. Datasmith typically brings these sufaces into Unreal as Instances of the Datasmith_Color Material.

The color of this Material is typically pre-set to exactly match a color from your source scene. When you use these Materials in the Unreal Engine, pay particular attention to the brightness of the color values. Design tools sometimes allow very bright surface colors — even including solid white — that are not often found in nature. You may need to tone these values down substantially in order for your lighting to look realistic.

Datasmith is typically able to respect the opacity of your source materials. If a surface color in your source scene is set to be semi-transparent, such as a glass panel, Datasmith brings its opacity into the Alpha channel of the Color setting. If you want to use the Alpha channel to make a previously non-transparent Material become semi-transparent in the Unreal Editor, you'll also have to change the Material's blending mode. In the General section, expand the Material Property Overrides group, check the Blend Mode option, and set its value to Translucent.

The Datasmith_Color parent Material also allows you to use three different kinds of texture maps: a diffuse map that provides the base color of the surface (overriding the Color setting), a normal map that provides fine surface details, and a transparency map that allows different parts of the same surface to have different opacity values. Datasmith may use these texture map settings if it can export those kinds of texture maps from your source application. If you have a Datasmith_Color Instance with a flat color, and you want to use texture maps like these in order to increase the realism of your surface, you might want to activate these settings and assign Texture Assets to them. When you enable one of the Map settings, you're offered a new setting under Texture Parameter Values where you can set the Texture you want to use.

However, you might be better off learning how to create your own Material from scratch, so that you can take advantage of other physically based properties of the Unreal Engine renderer that are not exposed by the Datasmith_Color parent Material, such as the Roughness and Metallic properties. See Physically Based Materials.

Animations

If your source scene contains objects with animated 3D transforms — objects whose translation, rotation, and/or scale values change over time — Datasmith can import those animations into your Unreal Engine project. It creates a new Level Sequence that contains a track for each animated object in the scene, and saves this Level Sequence into the Animations folder next to your Datasmith Scene Asset. You can use this Level Sequence to play back the animation in the Unreal Editor or in the Unreal Engine at runtime.

For example, in this 3ds Max scene, the sections of this garage door are animated to move along a spline, and at the same time the camera is animated to rotate around the object.

After import, you can double-click the Level Sequence Asset in the Content Browser to open it up in the Sequencer UI and play back the animation.

For example, in this video, the Level Viewport is set to show the view from the camera in the Datasmith scene, so the animated result looks the same as the original in 3ds Max.

There are some important things to note about this workflow:

Datasmith does not import any animation curves. Instead, for each frame in the original source animation, it bakes a keyframe for each animated object that contains that object's current transform.

Datasmith does not handle animations on sub-objects, mesh deformations, object properties, or skeletal rig animations. It only handles animations that change the overall translation, rotation, or scale of a scene object in 3D space.

For more about Level Sequences and how to work in the Sequencer UI, see the documentation on the Sequencer Editor.

Support for importing animations is currently limited to scenes imported from 3ds Max, Cinema 4D, VRED, Deltagen, and glTF files. (For instructions on how to include animations from a 3ds Max scene in your exported Datasmith file, see Exporting Datasmith Files from 3ds Max.)

Rendering Camera Animations

If your source scene contains an animated camera, the Level Sequence that Datasmith creates will contain a track for the corresponding CineCameraActor in your Unreal Engine Level. This track contains keyframes that store the 3D transforms of that camera as it moves and rotates in 3D space. If you select that CineCameraActor in the World Outliner and play the Level Sequence in the Unreal Editor, you'll see that the camera's preview window in the Level Viewport plays back the animation from that camera's point of view.

However, if you need to render the Level Sequence to a movie file or image sequence on disk from the animated camera's point of view, you need to first add a Camera Cut track to the Level Sequence, and add your animated camera to that Camera Cut track.

Double-click your Level Sequence to open it in the Sequencer UI.

Click the + Track button, then select Camera Cut Track from the menu.



Click for full image.

Click the + Camera button on the new Camera Cuts track, and select the camera whose point of view you want to use. If you want to use a camera that is already animated in the Level Sequence, you can select it from the Existing Binding list.



Click for full image.

When your Level Sequence contains many animated tracks, it may be hard to find the camera you want in the Existing Binding list. If so, you can select your camera from the New Binding list instead, or to drag your CineCameraActor from the World Outliner to the new Camera Cuts track in the Sequencer UI.

Your CineCameraActor is represented in the Camera Cuts track by a block in the timeline. If necessary, drag the left and right boundaries of this block to line up with the start and end of the animation.



Click for full image.

Next time you render the Level Sequence, it will render each frame from the point of view of the camera in the Camera Cuts track.

You can add multiple different CineCameraActors to the Camera Cuts track to make the render switch back and forth between them automatically at different times.

For more information, see also Working with Camera Cuts and Take Recorder.

Using Animations In Multiple Levels

Every Level Sequence contains references to Actors within a single specific Level. When you use Datasmith to import a scene that contains animation, the Level Sequence will contain references to the animated Actors in the Level that you have open at the time you import your scene.

If you later drop the same Datasmith Scene Asset into a different Level, the Level Sequence won't be able to find the same Actors in that new Level. The track names show up in red in the Sequencer, and playing the sequence with the new Level open has no effect. You have a few options to fix this:

You can update the Level Sequence to point to the copies of the Actors in the new Level.

With your new Level open, click the General Settings icon in the Sequencer Toolbar, and choose Fix Actor References from the menu.



Click for full image.

The Actor tracks should return to their usual color. Then, save your change to the Level Sequence.

The Level Sequence can only work with one level at a time. When you assign it to the new level, it will no longer work with the old one.

You can duplicate the Level Sequence Asset in the Content Browser before you fix its Actor references as described above. That way, you'll have one Level Sequence that works in the original Level you imported your content into, and another that works in your new Level.

If you reimport your Datasmith Scene Asset, only the original Level Sequence is updated with changes to the animation in the source scene. You may need to recreate your duplicate and fix its Actor references again.

If you need the same imported Level Sequence animation to work within multiple Levels, consider using sublevels. You can import your Datasmith scene into an empty Level, then add that Level as a sublevel inside each of the Levels that you need to play the animation. For more information on what sublevels are and how to use them, see Managing Multiple Levels.

Animation Timing and Frame Accuracy

Playing back a complex animation that contains many tracks and keyframes can sometimes result in hitches and "pops" as the playback adjusts for inconsistencies between the frame rate of the animation and the number of frames per second being rendered by the Unreal Engine. To avoid this and ensure the smoothest possible playback, Datasmith always enables the Lock to Display Rate at Runtime property on the Level Sequences that it creates.

You'll find this setting in the Sequencer UI here:



Click for full image.

This should improve the smoothness of your animations. However, you should be aware that it constrains the maximum frame rate of the Engine to the frame rate of your animation. If you need the Engine to run at a greater frame rate, this may not be an appropriate solution. For example, if your animation clip was authored in your source application at 24 or 30 frames per second, but you need your animation to play back in VR at 90 frames per second, constraining the Engine's frame rate to the animation's frame rate may not be a good solution for you. In cases like these, you may need to disable this option on your Level Sequence Assets.

Layers

If your source application offers the ability to organize your content into layers, or some similar content, Datasmith preserves that organization in the Unreal Editor. You can use the Layers window (Window > Layers) to show and hide layers, or to quickly find and select all objects in a layer.

However, the Unreal Editor doesn't support nested layers. If your source scene uses nested layers, Datasmith automatically flattens the hierarchy of layers into a single list.

For more about how to work with Layers in the Unreal Editor, see Layers Panel.

Metadata

For some kinds of source file formats, Datasmith imports metadata about the geometry objects in your scene that you set in your source application. You can access this metadata in the Unreal Editor using Blueprint and Python scripts. For details on this system, see Using Datasmith Metadata.

Technical Application-Specific Metadata

Some third-party applications and file formats provide access to technical metadata values about individual scene objects, such as their unique IDs, object classes, or other application-specific data. Datasmith imports this kind of technical data into Component Tags that it assigns to the Static Mesh Component that represents each object's geometry in the Level.

You can access the metadata from the Details Panel.

Select the Actor whose Component Tags you want to view in the Level Viewport or in the World Outliner.

In the Details panel, select the Static Mesh Component assigned to the Actor.

Scroll down in the Details panel to find the Tags > Component Tags list.



Click for full image.

This kind of technical information is typically specific to the source application that created the object. Therefore, it is kept separate from the Datasmith Metadata described in the previous section. Datasmith Metadata, by contrast, is typically intended to represent "real-world" information about individual scene objects, such as their BIM data, construction properties, cost, or manufacturer; or, it may represent custom user-defined properties that have a specific meaning in your production workflow.

Full Scene Reimport

Changes to the Scene Hierarchy

Changes to Geometry, Materials, and Textures

When to Use Full Scene Reimport

Individual Asset Reimport

When to Use Individual Asset Reimport

Data Preservation

Unreal Engine Properties

Datasmith Overrides

Auto Reimport

Datasmith brings design data from a variety of source applications into Unreal Engine, typically for the purpose of building real-time visualizations and experiences around that data. But often, while you're working on building those visualizations and experiences in Unreal, the scene or design data that you're basing your work on needs to change in order to meet new requirements or incorporate feedback from stakeholders. To avoid painful and costly re-work, you need to be able to incorporate those upstream changes without losing all the work you've done in the Unreal Editor.

This page describes the different ways you can pull updates to Datasmith content into your Unreal Project, and what happens to your Assets and Actors in the process. You have two options:

Reimport the complete Datasmith Scene - This updates the Datasmith Scene Asset to contain all the latest changes that have been made in your source scene, and attempts to reconcile those changes with the work you've done in the Unreal Editor. See Full Scene Reimport below.

Reimport individual Assets imported by Datasmith - such as Static Meshes, Materials, or Textures. This allows you to process changes to selected Assets without affecting the rest of the Datasmith Scene. See Individual Asset Reimport below.

For detailed instructions on how to use these import workflows in the Unreal Editor, see Datasmith Reimport Workflow.

Full Scene Reimport



Click image for full size.

You can reimport an entire Datasmith scene, all at once. This approach updates all of the Assets created by Datasmith in your Content Browser to match the latest changes you've made in your source application or data file. From there, you can selectively update the Datasmith Scene Actors in your Levels to synchronize them with the new scene hierarchy maintained by the Datasmith Scene Asset.

Changes to the Scene Hierarchy

When you reimport a Datasmith scene, the scene hierarchy contained in the Datasmith Scene Asset is immediately updated with all the latest changes that you've made in your source scene. After the import, the scene hierarchy in the Datasmith Scene Asset will have all the same information as if you were importing the scene fresh for the first time.

However, those changes to the scene hierarchy won't necessarily be reflected in Unreal Engine Levels that contain your Datasmith Scene. Instances of the Datasmith Scene that you've dropped into a Level in your Project become out of date with the scene hierarchy in the Level until you synchronize them with the updated Asset.

Synchronizing updates the information in the Datasmith Scene Actor, and its children in the World Outliner, to match the updated Asset as follows:

Modified Actors. Any Actors that you haven't modified in the Unreal Editor are immediately updated to match the latest information about them in the reimported Datasmith Scene. Any Actors that you have modified in the Unreal Editor are updated to match the latest information in the reimported Datasmith Scene, except for changes that Datasmith has tracked as overrides.

New Actors. Any new objects that you've added to your source file since the last time you imported have new Actors added into the Level to represent them.

Deleted Actors. Any objects that you've deleted in your source file have their corresponding Actors removed from the Unreal Level — unless those Actors contain other overrides. If the Unreal Actor that corresponds to a deleted object contains overrides, it is not deleted from the Level until you specifically delete it. Any Actors that you've deleted from the Level in Unreal but that still exist in the source file are not added back to your Level by default. However, you can enable this option when you synchronize the Datasmith Scene Actor in your Level with the reimported Datasmith Scene Asset.

Parenting relationships. The parenting hierarchy of the Actors in the Level is updated to match changes in the source file.

For example, the following before-and-after image illustrates:

Objects that have been deleted in the source scene — in this case, the Lift objects — get removed from the Datasmith Scene.

Changes that have been made to the object parenting structure in the source scene — in this case, the lights being grouped together under a new parent — are reflected in the Datasmith Scene.

Objects that have been added to the source scene — in this case, the toolboxes — get added to the Datasmith Scene.



Click image for full size.

There are two ways you can synchronize your Datasmith Scene Actor with its Asset:

When you reimport a Datasmith Scene Asset, you can automatically update any Datasmith Scene Actors in the currently opened Level that were created from that Asset. This is a simple approach that works well if you've only added your Datasmith Scene to a single Level.

You can synchronize the Datasmith Scene Actor in a Level with its Datasmith Scene Asset on demand at any time. You'll need to use this approach if you have multiple different Levels in your Project that contain instances of your Datasmith Scene, and you need them all to reflect the changes in your source scene.

For details, see Reimporting Datasmith Content.

Changes to Geometry, Materials, and Textures

When you reimport a Datasmith scene:

Datasmith recreates Static Mesh, Texture, and Material Instance Assets only if you have modified them in your source file since the last time you imported the scene.

Datasmith always recreates all Parent Material Assets, regardless of whether or not they have been modified in your source file.

When Datasmith recreates an Asset, it may overwrite changes that you've made to that Asset in Unreal!

Typically, you should not lose any information that Datasmith tracks as overrides, or any information that is specific to the Unreal representation of your scene's objects. However, you might lose changes that you've made in Unreal to information that is brought in by Datasmith, but that Datasmith does not track as an override. For example, overwriting an Asset will overwrite changes that you've made in Unreal to the internals of a Parent Material graph or to the geometry of a Static Mesh Asset.

To avoid losing changes that you make to your Assets in Unreal, you have two options:

When you re-import, deselect the Process checkbox for the corresponding asset type in the Reimport Options dialog box, to avoid reimporting that type of Asset. For example, if you've modified an imported Material graph in Unreal, and you don't want to lose those changes, you could deselect the Materials & Textures option. However, if there are other Material Assets that you do want to update from the source, this approach won't work. In this case, you could selectively reimport only the Assets of that type that you want to update; see Option 2. Individual Asset Reimport below.

Whenever you need to modify an Asset that you've imported with Datasmith, duplicate the Asset you want to modify into a different folder and modify the duplicate instead. Then, update any uses of the original Asset to use your duplicate instead. When you re-import, the original Asset will be overwritten, but your duplicate will remain untouched.

When you reimport the scene after deleting objects or materials in your source file, Datasmith does not delete the Assets that it had previously created for those objects. The Assets remain in your Content Browser, so that you can continue using them in the Unreal Editor as standalone Assets, outside the context of the Datasmith Scene. However, when you synchronize a Datasmith Scene Actor in one of your Levels to match the reimported Datasmith Scene Asset, instances of those deleted Assets will be removed (unless they contain any overrides).

The following before-and-after image illustrates what happens to Static Mesh Assets when you reimport a scene:

Objects that you've modified in the source scene — the light globe in this example — are re-created in Unreal, and the old versions of the Assets are overwritten.

Objects that you've deleted in the source scene — the yellow lift elements in this example — are not removed from your Project's Content Browser.

Objects that you've added to the source scene — the toolbox in this example — are added to the Content Browser as new Assets.



Click image for full size.

Remember that when you make a change to an Asset in the Unreal Engine, that change is immediately reflected everywhere that the Asset is used. The same applies when Datasmith recreates or modifies an Asset during a reimport. For example, if you change the geometry of an object in your source application, you'll see that after reimporting the corresponding Static Mesh Asset, all Actors in all Levels that instantiate that Static Mesh Asset are updated automatically to show the new geometry.

When to Use Full Scene Reimport

We recommend using full scene reimport in most cases. In particular, you need to reimport the full scene if:

You need to bring in new objects or materials from your source scene that didn't exist previously in Unreal.

The layout of the scene objects in 3D space has changed, or objects have new parenting relationships in the scene hierarchy that you want to be reflected in Unreal.

You aren't able to reimport your Assets individually. This may be either because too many objects have changed in your source file to work with them one-by-one, or because you don't know which Assets have changed.

Individual Asset Reimport



Click image for full size.

Instead of reimporting the entire Datasmith Scene, you can reimport selected Unreal Engine Assets that were created by the Datasmith import process — for example, individual Static Mesh Assets, Materials or Textures.

When you use this option, almost exactly the same thing happens as described under Changes to Geometry, Materials, and Textures above, but limited to the single Asset that you select. The only differences are:

The Asset is always recreated from scratch, even if it has not been modified in the source scene. For example, in the case of a Static Mesh Asset, the geometry of the Static Mesh is always rebuilt, so any changes that you've made to the geometry in Unreal are overwritten.

The Datasmith Scene Asset does not change, so no changes are made to the scene hierarchy in any Level that you've placed your scene into, regardless of whether you re-synchronize the Datasmith Scene Actors in those Levels.

Because the Datasmith Scene Asset does not change, it continues to track overrides to your Asset relative to the last time you imported the scene as a whole. If you reset the overrides on your reimported Asset, it will revert to its state the last time you imported the entire Datasmith Scene.

When to Use Individual Asset Reimport

Individual Asset reimport can be a good choice when:

You want to bring in changes to a small number of Assets, but you know that the overall Datasmith Scene contains changes to other Assets or to the scene hierarchy that you don't want to bring in.

You want to apply different Datasmith import settings to specific Assets than you applied when you imported the whole Datasmith Scene.

This workflow can be particularly useful for CAD models that need to be tessellated on import, because you can apply different tessellation settings to different parts of the Datasmith Scene. This may help you optimize the performance of your scene by controlling the number of triangles in each Static Mesh Asset. For example, you could import your CAD file with low-resolution settings, then selectively re-import a smaller number of important Static Mesh Assets at higher resolutions.

You can achieve the same purpose by retessellating selected Static Mesh Assets instead of reimporting them. Unlike reimporting, retessellating does not reimport the geometry of the Asset from the CAD scene file. It regenerates the triangular mesh for the Static Mesh Asset based on the last imported geometry, using the new settings you provide. For details, see Retessellating CAD Geometry.

Data Preservation

Whether you choose to reimport the complete Datasmith scene or to reimport individual Assets, much of the work you've done in Unreal is preserved in the reimport process. This includes:

Properties that are tracked by Datasmith as overrides. See Datasmith Overrides below.

Properties that are exclusive to Unreal Engine. See Unreal Engine Properties below.

Unreal Engine Properties

You should never lose any changes you make to properties on your Assets and Actors that are specific to Unreal — that is, properties that Datasmith does not import from your source file.

For example, suppose that you use Datasmith to import a scene, then you disable the Cast Shadows property of one of your imported Static Mesh Actors in the Unreal Editor. When you reimport the Datasmith Scene Asset and synchronize the Datasmith Scene Actor in your Level, that Cast Shadows property remains disabled.

Datasmith Overrides

When you reimport a Datasmith Scene or Asset, you should never lose any change you've made to an Unreal Engine Asset or Actor that Datasmith recognizes as an override. Overrides include things like which Materials are assigned to your Static Mesh Assets and Actors, and the 3D transforms of Actors in your Levels that were created as part of a Datasmith Scene.

For details on what changes are considered overrides, see Datasmith Import Process.

The next time you reset overrides to an Asset or an Actor after you reimport a Datasmith Scene, the Unreal Asset or Actor will be reset to its post-reimport values, not its original values. For example:

Suppose that your scene contains a Static Mesh Asset named "Chair", and after your initial Datasmith import it is assigned a Material named "Color_00000000".

In the Unreal Editor, you modify this Asset to use a new, physically based Material named "Black Leather". Datasmith tracks this change as an override.

Now, in your source scene, you change the color properties of the chair, and reimport the Asset or the Datasmith Scene that contains it. At first, your reimported Asset is still be assigned the "Black Leather" Material that you assigned in Unreal.

If you reset the overrides on the Asset, it does not revert to using the original "Color_00000000" Material, it reverts to using the new Material Asset that Datasmith generated to match the new color properties of the chair.

Auto Reimport

You can configure the Unreal Editor to monitor selected folders for Assets that have changed, and reimport those Assets automatically.

We don't recommend using this system for your Datasmith Scene Assets, or for the individual Assets created by Datasmith. Use auto-reimport only for other kinds of models or Assets that you add to your Project, like FBX files that you import separately as additional set dressing around your Datasmith models.

For details on setting up this system for your non-Datasmith content, see Auto Reimport.

Metadata Sources

Viewing Metadata in Unreal Editor

Accessing Metadata in Blueprint and Python

Accessing Metadata During Import

Accessing Metadata After Import

The Datasmith importer can automatically bring in metadata about the objects it handles: information that you set up for those objects in your 3D design or CAD application. Metadata is most often used to store real-world information about the mechanical part or architectural element that the asset represents, such as the cost of the piece, the material it's made of, physical properties like its weight or insulation efficiency, or usage information like the maximum torque to apply to a part. You can also use metadata to store any other kind of information about an Asset that you might need for your Project.

Having this metadata available in the Unreal Editor and Unreal Engine can help you in two ways:

In your asset pipeline: You can use metadata when you're importing Assets and setting up your Levels to help distinguish different kinds of Assets and Actors that need different processing. For example:

You could use metadata during the Datasmith import process to identify certain kinds of Assets that you won't need in your final scene, so that you can skip importing them.

After import, you could use it to identify Actors in your Level that you want to merge, join, or replace, or whose Materials you want to replace.

At runtime in your game: You can use metadata at runtime to show users selected information about your Actors that comes from your source design tool. For example:

If the objects in your Level have BIM data that contains information about their structural properties, you might want to visualize that information in your interactive experience when the player selects those objects in the scene.

Or, if your project is a product configurator that allows the player to choose between different design options, you might want your gameplay logic to calculate and show a running total of the cost of the player's current choices based on the cost metadata assigned to the visible Assets.

This page describes how to get metadata into Unreal through the Datasmith import process, and how access it in your scripts both in the Editor and at runtime.

Metadata Sources

Datasmith currently imports metadata from the following design tools:

Autodesk 3ds Max

Autodesk Revit

Dassault Systèmes Solidworks

Trimble SketchUp Pro

Maxon Cinema 4D

IFC 2x3 files

Graphisoft Archicad

Autodesk Navisworks

McNeel Rhinoceros (Rhino)

Datasmith currently only handles metadata on geometry, not other kinds of scene objects like lights or cameras.

Viewing Metadata in Unreal Editor

After the Datasmith import process is complete, you can view the metadata for any Static Mesh Actor in your Level in its Details panel, under the Asset User Data section:



Datasmith metadata is currently read-only in the Editor.

Accessing Metadata in Blueprint and Python

There are multiple different ways to access the metadata associated with your scene objects. Which one you should use depends on whether you need to access the metadata during the Datasmith import process, or after the import has finished.

All metadata keys and values are stored as strings in Unreal Engine, regardless of their original type in your design or CAD application. For example, if you set a metadata value in 3ds Max as a Boolean value like true or as a number like 312, they will be strings when you read them back in a script within Unreal. If you need the values to be Booleans or numbers, use a Blueprint conversion node like Utilities > String > String to Int or String to Float, or built-in Python string parsing functions like int() or float().

Accessing Metadata During Import

If you need to access your metadata during the Datasmith import process—for example, to identify certain meshes that you want to filter out before generating Unreal Assets for your scene—you can read the metadata from the Datasmith Scene. For background information on how to run a script during the input process, see Customizing the Datasmith Import Process.

You'll find the metadata attached to mesh actor elements in the Datasmith Scene.

Choose your implementation method:

Blueprints

Python

The nodes you'll need are under Datasmith > Scene and Datasmith > Element.

To reach these nodes, you need to disable the Context Sensitive checkbox in the context menu, or find the nodes you need in the Palette.

Node

Description

Get All Metadata

Retrieves an array of all metadata objects recorded for all objects in the Datasmith Scene.

Get All Objects and Values for Key

Retrieves a list of all objects in the Datasmith Scene that have a specified key. You'll also get a list of all values recorded for that key across all those objects.

Get Metadata for Object

Retrieves all metadata assigned to a specified object.

Get Metadata Value for Key

Retrieves the value of a specified key assigned to a specified object.

Get Metadata Keys and Values for Value

Retrieves all keys on a specified object whose value matches the String to Match input.

For the nodes above that return a Datasmith Metadata Element object, you can get the keys and values from the metadata object by using Datasmith > Element > Get Properties, Get Property and Get Property Count:



Example usage

This example shows how you could use the values assigned to a metadata key to identify geometry that you know you won't need in your Project, and to remove it from your Datasmith Scene before creating Static Mesh Assets:



Click for full image.

During the Datasmith import process, you can get to the metadata about your scene objects through the unreal.DatasmithSceneElement object. For details on the following functions, see the Python API Reference.

get_all_metadata(object_class) Retrieves an array of all metadata objects recorded for all objects in the Datasmith Scene.

get_all_objects_and_values_for_key(key, object_class) Retrieves a list of all objects in the Datasmith Scene that have a specified key. You'll also get a list of all values recorded for that key across all those objects.

get_metadata_for_object(object) Retrieves all metadata assigned to a specified object.

get_metadata_value_for_key(object, key) Retrieves the value of a specified key assigned to a specified object.

get_metadata_keys_and_values_for_value(object, string_to_match) Retrieves all keys on a specified object whose value matches the second parameter.

Example usage

This example shows how you could use the values assigned to a metadata key to identify geometry that you know you won't need in your Project, and to remove it from your Datasmith Scene before creating Static Mesh Assets:

Accessing Metadata After Import

When the import process finalizes your Datasmith Scene into Unreal Assets and Actors, it also applies the metadata from each mesh element in the Datasmith Scene to all the Actors in the Level that represent instances of that Static Mesh Asset. You can then use Blueprint or Python to retrieve the metadata for any or all of the Static Mesh Actors in your Level.

Choose your implementation method:

Blueprints

Python

The following nodes access metadata for one specific Actor. These have very little impact on performance, so you can use them anytime, even at runtime in your project. If you want to visualize the imported metadata for one or more selected objects in your scene—say, in a callout or a menu in your project's runtime UI—these are the nodes you'll want to use in your runtime Blueprint graphs.

You'll find them under the Datasmith User Data category.

Node

Description

Get Datasmith User Data Value for Key

Retrieves the value of the metadata with the specified key assigned to the specified object.

Get Datasmith User Data Keys and Values for Value

Retrieves all keys on the specified object that have the value you specify in the String to Match input. Use this node if you know the value you're looking for, but not the name of the key.

Get Datasmith User Data

Retrieves a metadata object that contains all key-value pairs recorded for the Actor, so that you can iterate through them yourself.

The following nodes, by contrast, access the metadata for all Static Mesh Actors in the current Level (or all that share a given class). Since your Level can potentially contain a large number of Actors, each with many properties, these functions may be expensive in CPU resources and could cause poor performance when used in runtime gameplay. Therefore, you can only use them in graphs that you create on Editor-only Blueprint classes.

You'll find these nodes under the Editor Scripting > Datasmith User Data category.

Node

Description

Get All Objects and Values for Key

Retrieves a list of all Actors in the current Level that have a specified key in their Datasmith metadata. You'll also get a list of all values recorded for that key across all those objects.

Get All Datasmith User Data

Retrieves the full list of all metadata objects for all Actors in the current Level.

The Get Datasmith User Data and Get All Datasmith User Data nodes above return Datasmith User Data Object References. This object has one variable you can access, called Metadata, which is a map of all the key-value pairs that make up the object's Datasmith metadata. To work with this kind of object, drag off the output pin and select Variables > Get Metadata:



This gives you the keys and values as a map. You can then use the utility nodes in the Utilities > Map category to work with the data. For example, this graph iterates through all the keys one by one, and retrieves the value associated with each key:

Click for full image.

For more information about Blueprint Map nodes, see the Blueprint API Reference.

Example usage

This section shows a simplified example of how you could visualize your asset metadata at runtime for an object that the player selects in the Level.



The text is written by a UMG widget that contains two text fields, each bound to a string variable. In the Blueprint graph for the widget, a custom action extracts two items of Datasmith metadata from an Actor that you pass in a custom event, and saves those items to the bound variables.



The following Level Blueprint shows an example of how to add a widget like this when play begins, and how to feed it with the Actor under the cursor every time the user presses a mouse button.

Click for full image.

For more information about building user interfaces in UMG, see the UMG UI Designer Quick Start Guide and the surrounding sections.

After the Datasmith import process is done, you can access metadata for all Actors or selected Actors using the unreal.DatasmithContentLibrary class. For details on the following functions, see the Python API Reference.

get_all_datasmith_user_data(object_class) Retrieves the full list of all metadata objects for all Actors in the current Level.

get_all_objects_and_values_for_key(key, object_class) Retrieves a list of all Actors in the current Level that have a specified key in their Datasmith metadata. You'll also get a list of all values recorded for that key across all those objects.

get_datasmith_user_data(object) Retrieves a metadata object that contains all key-value pairs recorded for the specified Actor, so that you can iterate through them yourself.

get_datasmith_user_data_keys_and_values_for_value(object, string_to_match) Retrieves all keys on the specified Actor that have the value you specify in the second parameter. Use this node if you know the value you're looking for, but not the name of the key.

get_datasmith_user_data_value_for_key(object, key) Retrieves the value of the metadata with the specified key assigned to the specified Actor.

Example usage

In Python scripts that you run inside the Unreal Editor, you can use Datasmith metadata after import to identify Static Mesh Actors in your Level that you want to apply certain special processing to.

Datasmith Overview

Datasmith Import Options

Customizing the Datasmith Import Process

Dataprep Import Customization

Prerequisites

Datasmith Plugins

Additional Software

Import Datasmith Content into Unreal Engine

Customizing the Import Process

This page describes how to use Datasmith to import content from a supported 3D design application or file format into Unreal Engine.

Prerequisites

Before you can import content with Datasmith, you might have to enable some Unreal Engine plugins or install additional software.

Datasmith Plugins

To import content into Unreal Engine using Datasmith, your project must have the Datasmith Importer plugin enabled. If you don't enable the plugin, you won't see the Datasmith import options in Unreal Engine. Some supported file formats require additional plugins.

For a list of supported applications, file formats, and plugin requirements, see Datasmith Supported Software and File Types.

To learn how to enable plugins in Unreal Engins, see Customizing Unreal Engine.

If you start your project from one of the Architecture or Automotive, Product Design, and Manufacturing templates, some or all of the Datasmith plugins are enabled by default.

Additional Software

To import some supported file formats, you must install additional software. The following file formats have specific software requirements:

File Format

Requirement

.wire

Install a version of Autodesk Alias AutoStudio that is compatible with your .wire file.

Import Datasmith Content into Unreal Engine

In Unreal Editor, open the project that you want to import Datasmith content into.

If you want to bring your content into an existing Level in your project, open it now. Otherwise, create a new Level or use the default Level.

In the main toolbar, open the Create menu and select Datasmith > File Import. A file import dialog opens.



Select the file you want to import, and click Open. A file dialog opens.

Choose a location in your project to store the imported content, and click OK. The Datasmith Import Options dialog opens.

To create a new top-level folder for your Datasmith content, right-click an empty area in the file dialog. To create a subfolder of an existing folder, right-click that folder.

In the Datasmith Import Options dialog, select the types of content that you want to import from your source file, and set the other import options as needed.



The Datasmith Import Options dialog displays different import options for different file types. For more information about import options, see Datasmith Import Options.

When you finish setting the import options, click Import. Datasmith Does the following:

Reads the imported file.

Creates new Assets in your project.

Places the Datasmith Scene into the current Level.

For more information about the import process, see the Datasmith Overview.

Customizing the Import Process

You can customize the Datasmith import process in the following ways:

Use Blueprints visual scripting or Python scripts to automate the import. For details, see Customizing the Datasmith Import Process.

Use Dataprep to perform additional operations on the data at import time. You can save and reuse Dataprep import recipes to create your own set of Asset import pipelines. For details, see Dataprep Import Customization.

Reimporting the Datasmith Scene Asset

Synchronizing a Datasmith Scene Actor with its Asset

During the Reimport

After the Reimport

Reimporting Individual Assets

This page describes how to reimport Datasmith content into the Unreal Editor, and how to control what updates get synchronized to the Actors in your Levels.

For background information, including an overview of what reimporting does to the assets in your Project and the Actors in your Level, see Datasmith Reimport Workflow.

Reimporting the Datasmith Scene Asset

To reimport the Datasmith Scene Asset from a new version of a source file:

Right-click the Datasmith Scene Asset in the Content Browser.



Click image for full size.

If you've saved the changes to your source scene into the same file on disk that you last used to create or reimport this Datasmith Scene Asset, select Reimport from the context menu.

If you've saved the changes to your source scene into a different file on disk, select Reimport With New File from the context menu, and browse to the new file you want to use.

You'll be prompted to specify some reimport options. These are the same ones you originally set on import, with a couple of additions.The new options, under Sync Current Level Actors, determine whether the updates made to your Datasmith Scene Asset should also be applied to any Datasmith Scene Actors in the current Level that were created from the Asset you're updating.



Click image for full size.

If you don't want to synchronize your Actors now, you can do it later. See Synchronizing a Datasmith Scene Actor with its Asset below.For more information on the other import options, see Datasmith Import Process.

Set the options you want the importer to use, and click Import.

The reimport process may overwrite Static Mesh geometry, Parent Materials, and Texture Assets in your Content Browser. For details, see Datasmith Reimport Workflow.

Synchronizing a Datasmith Scene Actor with its Asset

There are two ways you can re-synchronize a Datasmith Scene Actor in a Level with its corresponding Datasmith Scene Asset:

During the reimport.

After the reimport.

During the Reimport

At the time you reimport a Datasmith Scene Asset:

Open the Level that contains your Datasmith Scene Actor.

Reimport your Datasmith Scene Asset as described under Reimporting the Datasmith Scene Asset above.

In the Import Options dialog, find the Sync Current Level Actors section. Make sure to check the Datasmith Scene Actors box.If you want to add back to your Level any Actors that you've previously deleted, also check the Re-Spawn Deleted Actors option.



Click image for full size.

Click Import.

After the Reimport

At any time after you reimport a Datasmith Scene Asset:

Open the Level that contains your Datasmith Scene Actor.

Select the Datasmith Scene Actor in the Outliner.



Click image for full size.

In the Details panel, find the Datasmith section.



Click image for full size.

If you want to add back to your Level any Actors that you've previously deleted, check the Respawn deleted actors option.

Click Update actors from Scene.

Reimporting Individual Assets

Instead of reimporting an entire Datasmith Scene Asset, you can pick and choose individual Static Mesh, Material, and Texture Assets to update.

To re-import a single Asset:

Right-click the Asset in the Content Browser, and choose Reimport from the context menu.



Click image for full size.

For a Material Asset, choose Datasmith > Reimport Material.



Click image for full size.

You'll only see the Datasmith > Reimport Material option for Material Assets that Datasmith created from scratch to match a material definition in your source file, which is typically the case only for Parent Materials imported from 3ds Max. However, this option does not appear for Material Assets that are instances of Materials built in to Datasmith, which is typically the case for Materials imported from CAD files or SketchUp.

You'll be prompted to specify some reimport options for the Asset.These are the same ones you originally set on import. For more information on all these options, see Datasmith Import Process.

When you re-import individual Assets, you don't get the option to synchronize Level Actors. Every reference to the Asset in your Project will automatically use the updated version of your Asset. See Datasmith Reimport Workflow.

What is Datasmith Runtime?

Using Datasmith Runtime with Blueprints

Loading Datasmith Content at Runtime

Creating a Datasmith Direct Link with Blueprints

What is Datasmith Runtime?

Datasmith Runtime is a collection of Datasmith features that are available at runtime (as opposed to an in-editor workflow) in an Unreal Engine-based application. You can use these features to create applications that can import .udatasmith files and manipulate them using Blueprints.



Datasmith Direct Link is accessible in a cooked Unreal Engine-based application using Datasmith Runtime and Blueprints.

With Datasmith Runtime, you can create custom applications that take advantage of Datasmith Direct Link or visualize Datasmith data on demand as part of an iterative 3D workflow.

Enable the following plugins in your project to work with Datasmith Runtime:

Datasmith Content

Datasmith Importer

Datasmith Runtime

Datasmith Runtime is officially supported in Unreal Engine 4 and Unreal Engine 5 using Windows and MacOS. While Datasmith Runtime will work with Linux, this is experimental and you may experience instability and performance issues.

Using Datasmith Runtime with Blueprints

Datasmith Runtime exposes a variety of Datasmith features and import options using several Blueprint nodes. Listed below are the most common:



The most common Datasmith Runtime Blueprint nodes.

Make Datasmith Runtime Import Options

Exposes several import parameters and converts them to a data structure:



Inputs

Description

Build Hierarchy

Determines whether the hierarchy of Actors is built. Choosing a more detailed hierarchy increases loading and rendering time.

None: Imports the source content with the hierarchy stored in the Datasmith Runtime Actor. Your content will not be represented in the World Outliner.

Simplified: Imports the source content while minimizing the number of Actors created. Allows exposing objects so the application can modify their properties, while limiting the number of draw calls due to the high number of Actors in the scene.

Unfiltered: Imports the source content with full hierarchy.

Build Collision

Determines the type of collision used for components.

No Collision: Does not have any representation in the physics engine. Provides the best possible performance.

Query Only (No Physical Collision): Uses only spatial queries. Useful for objects that do not need physical simulation such as pawn navigation. Improves performance.

Physics Only (No Query Collision): Uses only physics simulation. Useful for objects that do not need spatial queries. Improves performance.

Collision Enabled (Query and Physics): Uses both spatial queries and physics simulation.

Collision Type

Determines the type of collision used for Static Meshes.

Project Default: Uses the project's physics settings.

Simple and Complex: Uses both simple and complex shapes. Simple shapes are used for regular scene queries and collisions. Complex (per-poly) shapes are used for complex scene queries.

Use Simple Collision as Complex: Uses only simple shapes for all scene queries and collision tests.

Use Complex Collision as Simple: Uses complex (per-poly) shapes for all scene queries and collision tests. Can be used for simulation in static shapes only. Might be necessary if precise collision is needed while navigating a scene.

Import Metadata

Reads and imports metadata for Actors. Increases load time.

The Tesselation Options input is currently not used.

Set Import Options

Sets the value of the selected import options for Datasmith content using a Datasmith Runtime Actor. Uses a Datasmith Runtime Actor as the Target and Datasmith Runtime Import Options as its value.



Load File

Loads the .udatasmith file located at the specified file path. Requires a File Path and Datasmith Runtime Actor as inputs.



Load File from Explorer

Opens a File Browser window so you can browse to a location and select a .udatasmith file. Requires a Datasmith Runtime Actor as input. A Default File Path is optional.



Though it works with both Windows and Mac operating systems in Play In Editor (PIE), Load File from Explorer works only with Windows at runtime.

Get Direct Link Proxy

Returns an interface to a Direct Link connection called a Direct Link Proxy. This is the first step in creating a Datasmith Direct Link connection.



Get List of Sources

Gets a list of Datasmith Direct Link Sources. Requires a Direct Link Proxy as input.



Open Connection with Index

Opens a Direct Link connection with the source located at the specified index value. Requires a Datasmith Runtime Actor and a Source Index as input.



Close Connection

Closes an open Direct Link connection associated with a specified Datasmith Runtime Actor.



Loading Datasmith Content at Runtime

Using Datasmith Runtime, you can load Datasmith content inside a cooked application while having access to the hierarchy and Actor properties.



Click for full image.

To load Datasmith content using Blueprints:

Create a new Actor Blueprint to contain the anchor point for the Datasmith content. You can do this by right-clicking in the Content Browser and selecting Blueprint Class from the context menu. In the Pick Parent Class window, select Actor and name the new Blueprint class DatasmithActor. Double-click the new Blueprint to open the editor.



This anchor will serve as the origin point for the imported Datasmith content. If your content is offset from the origin in your source application, then Unreal Engine will maintain that offset from the anchor when the content is imported.

Select the Event Graph tab and remove every event except Event BeginPlay. Drag a connection from Event BeginPlay and add the Spawn Actor From Class node. Open the Class dropdown menu and select DatasmithRuntimeActor. Promote the Return Value to a variable and name it Anchor.



Spawn Actor requires a Transform to spawn the Anchor. Right-click to the left of Spawn Actor and add a Make Transform node. Connect the output from Make Transform to the Spawn Transform pin on Spawn Actor.



To finish the Blueprint, click and drag from the execute pin of the Set node and add a Load File from Explorer node. Connect a reference to the Anchor variable to the Datasmith Runtime Actor input.



Save and Compile the Blueprint. Add a copy of your Anchor Blueprint to the level and press Play to test.

Unreal Engine will open a File Explorer window and ask you to select a file.

Creating a Datasmith Direct Link with Blueprints

You can also open a Datasmith Direct Link between one or more source applications and your Unreal Engine project at runtime using Datasmith Runtime.

Start by creating a new Actor Blueprint to contain the anchor point for your Datasmith content. Double-click the new Blueprint to open the editor.

Similar to the previous example, select the tab for the Event Graph and remove every event except for Event BeginPlay. Drag a connection off Event BeginPlay and add the Spawn Actor From Class node. Open the Class dropdown menu and select DatasmithRuntimeActor.

A Transform is required to spawn the Anchor. Right-click to the left of Spawn Actor and add a Make Transform node. Connect the output from Make Transform to the Spawn Transform pin on Spawn Actor.



Next, you need a Direct Link Proxy to act as a connection point between your application and your source application. Drag a connection from the Set node and create a Get Direct Link Proxy. Promote the output to a variable and name it Direct Link Sources Proxy. Set it to be Public.



Click the plus (+) button in the Functions section of the My Blueprints panel to create a new function. Name it DirectLinkUpdate. You will use this new function to trigger the Direct Link connection during runtime.



Start by getting a copy of your Direct Link Proxy variable. Drag a line from the variable and create a Get List of Sources node. Promote the output to a variable to hold the list of Direct Link sources and make this variable public.



Drag the Anchor variable you created earlier from the My Blueprint tab into the Direct Link Update function. Drag the a line from the output, then type in Set Import Options to select and insert that node.



Right-click and create a Make Datasmith Runtime Import Options node, and then drag a connection from the output to the Import Options input.



Finish the function by dragging a line from Set Import Options and creating an Open Connection with Index node. This takes in an anchor and a Source Index as input. Connect the reference to the Anchor to the Target input.



Click the plus (+) next to Variables to create a new variable. Name it SourceIndex, and make it of type Integer.



Connect the new variable to the Source Index input on the Open Connection with Index node. An index value of 0 will connect to the first source in the list.



Finally, click on the DirectLinkUpdate function in My Blueprints and enable Call In Editor in the Details panel. This option makes the function available at runtime in the Details of the Anchor object.



Click for full image.

Save and Compile. The finished Blueprint should look like the example below:



Click for full image.

Start your source application and run the project by clicking the Play button. Select your Anchor in the World Outliner and click the Direct Link Update button in the Details panel. Then, click the Synchronize with Direct Link button in your source application. You will see your Datasmith content appear in your Level using the import options specified in the Blueprint.

Disabling the Use Less CPU when in Background option enables the engine to update the 3D viewport when the Unreal Engine window is not focused and when a Pawn in the level is not possessed. This option is found in the Editor Preferences under General > Performance.

Setting up a Direct Link Connection

Using Direct Link in Packaged Projects

End Result

Datasmith Direct Link is a feature found in many Datasmith Exporter plugins that can incrementally update the viewport in an Unreal Engine-based application, such as Twinmotion, with the push of a button.





Source Application

Destination Application

With the Direct Link workflow, you can set up a Datasmith Direct Link between one or more source applications and multiple destinations such as an Unreal Engine-based application or Twinmotion.



Datasmith Direct Link allows multiple Source applications to connect to one or more Destinations.

This link updates your Unreal Engine Level or Twinmotion model, removing the need to re-export a *.udatasmith file from your source every time you make a change. This makes it easier to update and visualize incremental changes to your 3D scene in near real time.

Setting up a Direct Link Connection

Getting started with the Datasmith Direct Link workflow begins with creating the connection between your 3D application and your Unreal Engine-based application.

Download and install the appropriate Datasmith Exporter plugin for your application. You can download the appropriate plugin here. For more information on using the Datasmith Exporter plugin with your application, see Datasmith Software Interop Guides.



Installing the Datasmith Exporter plugin for Archicad.

Once you have installed the Datasmith Exporter plugin for your 3D application, check to ensure the Datasmith features are enabled. This will depend on your application.

Open your destination application and select your 3D application as the Source.



Datasmith options panel in the Collab Viewer template.

For example, when running a local session in a project setup with the Collab Viewer template, press and hold the spacebar and select the Datasmith options to add one or more Direct Link sources to the Level. For more information on using the Collab Viewer template, see Collab Viewer Template Quick Start.

Back in your source application, sync your Direct Link connection by clicking the Synchronize with Direct Link button.



Sync your changes between applications by clicking the Synchronize with Direct Link button.

Using Direct Link in Packaged Projects

To use Direct Link in packaged projects, you must take an additional step to enable UDP messaging for your project's .exe file.

From Windows Explorer or another file explorer, go to your project folder, then open the WindowsNoEditor folder.

Right-click your project's executable file and, from the context menu, select Create Shortcut.



Right-click the shortcut you created and, from the context menu, select Properties.



In the shortcut's Properties window, add the -messaging parameter to the Target property.

For the current example, the full line would look like this: "C:\Users\admin\Documents\Unreal Projects\DirectLinkTest\WindowsNoEditor\DirectLinkTest.exe" -messaging



Click OK to save your changes.

End Result

With the Direct Link connection established, you are now able to update your Unreal Engine or Twinmotion models with the push of a button.



Disabling the Use Less CPU when in Background option enables the engine to update the 3D viewport when the Unreal Engine window is not focused and when a Pawn in the level is not possessed. This option is found in the Editor Preferences under General > Performance.

Understanding the Import Process

Options for Customizing the Import Process

Before You Start

Examples

Accessing Import Options

About the Datasmith Scene

Scene Contents

Working with the Datasmith Scene

The goal of the Datasmith import process is to bring a set of 3D objects that you've set up in a content creation tool smoothly into the Unreal Editor. To do this, it automatically translates objects such as meshes, lights, cameras and surface materials into their Unreal Engine equivalents while doing its best to respect the intent of your design, and it automatically populates a Level with instances of these Assets for you. For details, see Datasmith Overview.

Sometimes, however, you may want to get inside the import process and change the way it translates your original scene into Unreal Engine Assets, or to change what it does with those Assets. For example, if there are parts of your original scene that you know you won't need in your Unreal Engine Project, you might want to filter those objects out before creating your Assets. This reduces the number of different pieces of content you have to deal with in the Unreal Editor, and can speed up the import for large scenes.

This page shows how you can use Blueprint or Python scripting to take control of the Datasmith import process.

Understanding the Import Process

When you import a scene using one of the Datasmith importers in the Unreal Editor Toolbar, as described in Importing Datasmith Content into Unreal Engine, the importer internally performs a two-step process to take your data from a .udatasmith, CAD, or other source file on disk and turn it into Assets and Actors in the Unreal Editor:

The importer reads the contents of the file into an in-memory data structure called a Datasmith Scene. This contains a representation of the 3D objects in the scene, their relationships, and all the properties of those objects that Datasmith was able to extract from your original scene.

When the Datasmith Scene is ready in memory, a second stage of the import process finalizes the scene elements into Unreal Engine Assets in the Content Browser. When the Datasmith Scene Asset is ready, the import process spawns it in the current Level. This in turn spawns all of its children: Actors, Static Mesh Actors, Lights, Cameras, and so on.



Options for Customizing the Import Process

If you use a Blueprint or Python script to launch the Datasmith import process, you can de-construct the process above and carry out each of the two stages separately. This allows you to insert your own processing after you construct the Datasmith Scene in memory, but before you finalize that scene into Assets and Actors.

The overall process is the same for both Blueprint and Python:

Construct a new in-memory Datasmith Scene representation from the location of a .udatasmith, CAD, or other supported file type on disk.

Do any additional scene modifications that you want to affect the way your scene is transformed into Unreal Assets.

One way you can make it easier to identify what objects you need to change is to take advantage of metadata about the objects in your scene. For details on how to access metadata in the Datasmith Scene, see Using Datasmith Metadata.

Set up options for the import process. These options are essentially equivalent to the ones you set up in the Unreal Editor UI when you use the Import Datasmith button to start the import. For example, you set the path where the importer should place your imported assets within your project, what types of objects it should create from the Datasmith Scene, tessellation settings for parametric CAD formats, and so on.

Complete the import process to finalize your Datasmith Scene into Unreal Assets.

When you no longer need the Datasmith Scene that you constructed above, you should destroy the scene in order to clear the memory resources it uses.

Now that the import process is done, your new Assets are available in the Content Browser, and your new Actors are available in the current Level (if you requested them to be added in your import options). If you want to do additional post-processing on the generated Unreal Assets, like creating collision data or LODs automatically, this is a great time to do that. See also Scripting and Automating the Editor.

Customizing the import process is very likely to have an effect on the re-import process outlined in Datasmith Reimport Workflow. For example, if you use a script to remove elements such as meshes or lights from the Datasmith Scene before you complete the import process, then you re-import the Datasmith Scene Asset, your pre-processing script is bypassed during the re-import. The result is that the objects you originally filtered out from the scene are detected as newly added, and are added to your Project or Level.

For now, we recommend doing most modifications after import, using the tools and techniques described under Scripting and Automating the Editor. Modify the Datasmith Scene during import only if you have a particular need that you can't fulfill by modifying Assets and Actors after you finalize the import, such as preventing the creation of certain Assets.

Before You Start

Make sure that you have the Datasmith Importer plugin enabled for your Project.

For background information on how to use Blueprint and Python scripts within the Editor, see the pages under Scripting and Automating the Editor.

Examples

The following examples show how to use Blueprint and Python to customize the process of importing a .udatasmith file and a CAD file into the Unreal Editor.

Choose your implementation method:

Blueprints

Python

If you want to use Blueprint to customize the import process, you'll mainly be using nodes from the Editor Scripting > Datasmith, Datasmith > Scene and Datasmith > Element categories.

To reach the nodes you need, you'll need to use an Editor Utility Widget, and Editor Utility Blueprint, or make your Blueprint class derive from an Editor-only base class, such as EditorUtilityActor. The examples below show Blueprint graphs triggered from buttons in an Editor Utility Widget.

Your destination folder must start with /Game/.

Importing a .udatasmith File

In this example, the Get Options node requests the DatasmithImportOptions class, which contains the basic import settings inside its Base Options variable.



Begin Object Class=/Script/BlueprintGraph.K2Node_ComponentBoundEvent Name="K2Node_ComponentBoundEvent_8" DelegatePropertyName="OnClicked" DelegateOwnerClass=Class'"/Script/UMG.Button"' ComponentPropertyName="Button_235" DelegatePropertyDisplayName=NSLOCTEXT("UObjectDisplayNames", "Button:OnClicked", "On Clicked") EventReference=(MemberParent=Package'"/Script/UMG"',MemberName="OnButtonClickedEvent__DelegateSignature") bInternalEvent=True CustomFunctionName="BndEvt__Button_235_K2Node_ComponentBoundEvent_1_OnButtonClickedEvent__DelegateSignature" NodePosX=-320 NodePosY=896 NodeGuid=1F53FEC54DF915585FBE1BAEF1E26862 CustomProperties Pin (PinId=FA4CF01842EBDE0B61213D8AE4592814,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',MemberName="BndEvt__Button_235_K2Node_ComponentBoundEvent_1_OnButtonClickedEvent__DelegateSignature"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A2B4A6D147468F7579B1F9B1DAF44D59,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_0 73245C05460F1B275DEAA8BAA946C293,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_7" VariableReference=(MemberName="SourcePath",MemberGuid=EE32D38E4D0FD567CB6339BE070DEF14,bSelfContext=True) NodePosX=-256 NodePosY=976 NodeGuid=817A97A7474EC188FF48C88D11DFF5EE CustomProperties Pin (PinId=B47E818542BBE5381CC13B89F464138C,PinName="SourcePath",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_0 E65E2B82418159F25F7E97B975379989,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3C77B64F4771BEA076DEAB9A7E0212B5,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',MemberName="ConstructDatasmithSceneFromFile") NodePosX=-96 NodePosY=896 NodeGuid=8EE73006407B28475CAC12B62DB53AFF CustomProperties Pin (PinId=73245C05460F1B275DEAA8BAA946C293,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_ComponentBoundEvent_8 A2B4A6D147468F7579B1F9B1DAF44D59,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=06B94A4F4D33A50242BB22916E9616B6,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_1 8B494A5145B0700C63131587FD2EEB29,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5D024BD74486182F8E953E986875E019,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nDatasmith Scene Element Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/DatasmithImporter.Default__DatasmithSceneElement",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E65E2B82418159F25F7E97B975379989,PinName="FilePath",PinToolTip="File Path\nString\n\nUDatasmith file path to open. ie: c:/MyFolder/MyFiles.udatasmith",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_7 B47E818542BBE5381CC13B89F464138C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FD94D6EC4245D9A311349A8D6D7DF8BE,PinName="ReturnValue",PinToolTip="Return Value\nDatasmith Scene Element Object Reference\n\nThe opened DatasmithScene, that can be modified and can be imported.",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_1 29C81FD640AE144B15F33AB774E43058,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_1" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=208 NodePosY=896 NodeGuid=857BA71242F6A7A6E4BEFB95132A1D53 CustomProperties Pin (PinId=8B494A5145B0700C63131587FD2EEB29,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_0 06B94A4F4D33A50242BB22916E9616B6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1D4880DD4CD8ECA4FAD60188BF3E12A8,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=29C81FD640AE144B15F33AB774E43058,PinName="DatasmithScene",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_0 FD94D6EC4245D9A311349A8D6D7DF8BE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7FF3F81642FFBC4CA9F6AA8462CE894C,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=97B227144DCA12697425DB8CE9A91983,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_ComponentBoundEvent Name="K2Node_ComponentBoundEvent_9" DelegatePropertyName="OnClicked" DelegateOwnerClass=Class'"/Script/UMG.Button"' ComponentPropertyName="Button_408" DelegatePropertyDisplayName=NSLOCTEXT("UObjectDisplayNames", "Button:OnClicked", "On Clicked") EventReference=(MemberParent=Package'"/Script/UMG"',MemberName="OnButtonClickedEvent__DelegateSignature") bInternalEvent=True CustomFunctionName="BndEvt__Button_408_K2Node_ComponentBoundEvent_2_OnButtonClickedEvent__DelegateSignature" NodePosX=-320 NodePosY=1456 NodeGuid=7D0CE9D547F7F324965189AAB2C643FC CustomProperties Pin (PinId=C3FDA6484D6C6810470C059F6D8DBA0A,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',MemberName="BndEvt__Button_408_K2Node_ComponentBoundEvent_2_OnButtonClickedEvent__DelegateSignature"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8A2A875543CE42299BB978A4E2063A19,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_16 34D5C7684815CD2294E2E59205BF4564,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_ComponentBoundEvent Name="K2Node_ComponentBoundEvent_10" DelegatePropertyName="OnClicked" DelegateOwnerClass=Class'"/Script/UMG.Button"' ComponentPropertyName="Button_728" DelegatePropertyDisplayName=NSLOCTEXT("UObjectDisplayNames", "Button:OnClicked", "On Clicked") EventReference=(MemberParent=Package'"/Script/UMG"',MemberName="OnButtonClickedEvent__DelegateSignature") bInternalEvent=True CustomFunctionName="BndEvt__Button_728_K2Node_ComponentBoundEvent_3_OnButtonClickedEvent__DelegateSignature" NodePosX=-320 NodePosY=1104 NodeGuid=54826F1845C863BBC34D09A0E84A27B4 CustomProperties Pin (PinId=B30EFF934228F2E831BAC6BBE95390B8,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',MemberName="BndEvt__Button_728_K2Node_ComponentBoundEvent_3_OnButtonClickedEvent__DelegateSignature"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=082DBC7843384A852711A0922280A3C8,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_1 F09D350F40F0C72E6A1A949740D04057,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_ComponentBoundEvent Name="K2Node_ComponentBoundEvent_11" DelegatePropertyName="OnClicked" DelegateOwnerClass=Class'"/Script/UMG.Button"' ComponentPropertyName="Button_571" DelegatePropertyDisplayName=NSLOCTEXT("UObjectDisplayNames", "Button:OnClicked", "On Clicked") EventReference=(MemberParent=Package'"/Script/UMG"',MemberName="OnButtonClickedEvent__DelegateSignature") bInternalEvent=True CustomFunctionName="BndEvt__Button_571_K2Node_ComponentBoundEvent_4_OnButtonClickedEvent__DelegateSignature" NodePosX=-320 NodePosY=1968 NodeGuid=9789589C4A41F6D507981B98B21FE6F5 CustomProperties Pin (PinId=F6F7814E495801AB6E923F85CDAB4AB7,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',MemberName="BndEvt__Button_571_K2Node_ComponentBoundEvent_4_OnButtonClickedEvent__DelegateSignature"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A66C28D74097EC2B9E3A2BBC0AF39333,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_17 9552B7B4440102FCD63824BCD3CDC466,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_4" bCommentBubbleVisible_InDetailsPanel=False NodePosX=-368 NodePosY=848 NodeWidth=816 NodeHeight=192 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Construct the Datasmith Scene" NodeGuid=D4F311CB4C1811567506388FF93DF3FF End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_9" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=-272 NodePosY=1184 NodeGuid=3E4F465D49B340586F5C5383DFCD373D CustomProperties Pin (PinId=B19039234515D9D6D77BBBBC3955841D,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_1 8CA76E4B4FBF3D84BFD59A98609DCEAE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=72A798EC4FB618464CABE6AF0094CF9E,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_1" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',MemberName="GetAllMeshActors") NodePosX=-96 NodePosY=1104 NodeGuid=9D0CE225400AD4B34F250B838B1FA984 CustomProperties Pin (PinId=F09D350F40F0C72E6A1A949740D04057,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_ComponentBoundEvent_10 082DBC7843384A852711A0922280A3C8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AF908649489E8BD258632B81E9163487,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_1 8A634C4546F081BBDF032080016B7750,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8CA76E4B4FBF3D84BFD59A98609DCEAE,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_9 B19039234515D9D6D77BBBBC3955841D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6200D1764E2A2BF25BB534AC9C4C5E97,PinName="ReturnValue",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_1 52DE027F4AC9008EC95C818F9C7D007F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_1" MacroGraphReference=(MacroGraph=EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForEachLoop"',GraphBlueprint=Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=99DBFD5540A796041F72A5A9DA655026) ResolvedWildcardType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',ContainerType=Array) NodePosX=208 NodePosY=1104 NodeGuid=5F663B75474EF370330823BB9B947C93 CustomProperties Pin (PinId=8A634C4546F081BBDF032080016B7750,PinName="Exec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_1 AF908649489E8BD258632B81E9163487,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=52DE027F4AC9008EC95C818F9C7D007F,PinName="Array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_1 6200D1764E2A2BF25BB534AC9C4C5E97,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C74584BC48D87EC21BD9F89CBD4D5447,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_IfThenElse_0 90BA1A0C4803055E2C26A985E3C3F637,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6BD909C44DBF27901D89FCBD6FA0C196,PinName="Array Element",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_2 7D64F01042DA58B86C5ADC9F78468668,K2Node_Knot_1 736766394358480B1D3DB2AFCBB75D8C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=615807344B9CB28D00D7919AE0E73C57,PinName="Array Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=740A582C4FE874CBAF9A7FBBE5B66D9D,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_2" bIsPureFunc=True bIsConstFunc=True FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithActorElement"',MemberName="GetLabel") NodePosX=448 NodePosY=1168 NodeGuid=763C3EC5467BF317BB7A65AC00D3CFAF CustomProperties Pin (PinId=7D64F01042DA58B86C5ADC9F78468668,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_1 6BD909C44DBF27901D89FCBD6FA0C196,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FE9F3BC349E06FBCFFF3819C53E736D3,PinName="ReturnValue",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_3 784F3CFE44EB60EED770CE8C00A833F5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_3" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetStringLibrary"',MemberName="Contains") NodePosX=720 NodePosY=1168 NodeGuid=87F43007459F37E6E3C1D093145ECDAE CustomProperties Pin (PinId=8ED82A39451CBBEDD11E9A84C8C57583,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetStringLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetStringLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=784F3CFE44EB60EED770CE8C00A833F5,PinName="SearchIn",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_2 FE9F3BC349E06FBCFFF3819C53E736D3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CDED70BB48352F4B36AECE8DF41D59F5,PinName="Substring",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_10 A61750104C0CCB8BD7332FAFABCB0B36,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=27E608714F1137737C8F588450A88EEE,PinName="bUseCase",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7290B3A14BB8F8F5CC0CBC9DC2F59C7D,PinName="bSearchFromEnd",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B61D4BE2440F9FE5805FDA8F4699DE8B,PinName="ReturnValue",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="false",AutogeneratedDefaultValue="false",LinkedTo=(K2Node_IfThenElse_0 C6374EC44D19BDBEFAA39791B998A224,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_10" VariableReference=(MemberName="ExcludeKeyword",MemberGuid=5EDD18B84283704C6A93AA8FCBD53BB2,bSelfContext=True) NodePosX=544 NodePosY=1264 NodeGuid=1DC641374C00E1AD096B31B586C98273 CustomProperties Pin (PinId=A61750104C0CCB8BD7332FAFABCB0B36,PinName="ExcludeKeyword",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_3 CDED70BB48352F4B36AECE8DF41D59F5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A98C972B4454102AFFE54BB60DCCE5AE,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=1024 NodePosY=1104 NodeGuid=7BF7AD6446AA5D3BD7A9C48C1F7A7CE6 CustomProperties Pin (PinId=90BA1A0C4803055E2C26A985E3C3F637,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_1 C74584BC48D87EC21BD9F89CBD4D5447,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C6374EC44D19BDBEFAA39791B998A224,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_CallFunction_3 B61D4BE2440F9FE5805FDA8F4699DE8B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F33417484D8690D3C3C203B9DDCDF2F9,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_4 9EF64EBE440A216720E04AA6CC4B71F7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F63746FA45B783F34CB98B8B69B2487A,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_4" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',MemberName="GetMeshElement") NodePosX=1248 NodePosY=1168 NodeGuid=385A2E4F4A61C50666917E82540A8CCD CustomProperties Pin (PinId=9EF64EBE440A216720E04AA6CC4B71F7,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_IfThenElse_0 F33417484D8690D3C3C203B9DDCDF2F9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=006ED87B4EFBFE47CDA6DEBA234157EF,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_5 F49269844DAF895470D5C3A1651738EA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=70CE54A549D1DEB53BAF44B63251CC14,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_4 2EB534AF44E068BF92C8718EFD97F85C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D996A2184425B1D74810B199447BB1C2,PinName="ReturnValue",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_5 066348544D45E15D92C5BA9A54137EFC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_1" NodePosX=448 NodePosY=1360 NodeGuid=F82925BA44D4C1F2F655BC80C4C88D2C CustomProperties Pin (PinId=736766394358480B1D3DB2AFCBB75D8C,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_1 6BD909C44DBF27901D89FCBD6FA0C196,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8D48C5904859E9F5FD1AC2B649675C86,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_4 89B038D04A8257E4EDD7E0B7B7F71D65,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_4" NodePosX=1152 NodePosY=1360 NodeGuid=0BF0647B4CD00A3155AB53801A947485 CustomProperties Pin (PinId=89B038D04A8257E4EDD7E0B7B7F71D65,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_1 8D48C5904859E9F5FD1AC2B649675C86,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2EB534AF44E068BF92C8718EFD97F85C,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_4 70CE54A549D1DEB53BAF44B63251CC14,K2Node_Knot_5 2991785048D4A29507659E8128D52F46,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_11" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=1376 NodePosY=1296 NodeGuid=779FC91147DB7F7C90494ABBA212086F CustomProperties Pin (PinId=27A96AEF460C1183B4A0029F8E59EB84,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_5 FF7A47EC4E3D76CB7736068BCDD18449,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FBA4B4D946631EB71F693792EC2F8CD6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_5" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',MemberName="RemoveMesh") NodePosX=1552 NodePosY=1168 NodeGuid=8E48797F4790674A4B76A88D1B864418 CustomProperties Pin (PinId=F49269844DAF895470D5C3A1651738EA,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_4 006ED87B4EFBFE47CDA6DEBA234157EF,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AB280A58483150FC58963A96A7B9BF13,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_6 37112D5445D133F3C80D618ADD0093AC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FF7A47EC4E3D76CB7736068BCDD18449,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_11 27A96AEF460C1183B4A0029F8E59EB84,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=066348544D45E15D92C5BA9A54137EFC,PinName="InMesh",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_4 D996A2184425B1D74810B199447BB1C2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_12" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=1680 NodePosY=1312 NodeGuid=C8ACB9CF472E1D2EB14558B972482BE8 CustomProperties Pin (PinId=3711FB544CDEE2C13D11628DA9EDF8F3,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_6 7D3CABE74392B154F4793483203EAA3B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BF5A59D64EC084B64C863E9D200B3C2F,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_6" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',MemberName="RemoveMeshActor") NodePosX=1856 NodePosY=1168 NodeGuid=161D1732488C6A95002AFF907B4539E1 CustomProperties Pin (PinId=37112D5445D133F3C80D618ADD0093AC,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_5 AB280A58483150FC58963A96A7B9BF13,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9F9C411548B20C46777D74A9967C165B,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7D3CABE74392B154F4793483203EAA3B,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_12 3711FB544CDEE2C13D11628DA9EDF8F3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8D080A9C4D24A7BABBCFCDB85CE801C0,PinName="InMeshActor",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_5 0DA686F04F4AECD0845522B509A788FE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5ECBAEC4490366E7CFC946B06625962B,PinName="RemoveRule",PinType.PinCategory="byte",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Enum'"/Script/DatasmithCore.EDatasmithActorRemovalRule"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="RemoveChildren",AutogeneratedDefaultValue="RemoveChildren",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_5" NodePosX=1792 NodePosY=1360 NodeGuid=DDCE6E29401D61487DD80695F86AEA1A CustomProperties Pin (PinId=2991785048D4A29507659E8128D52F46,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_4 2EB534AF44E068BF92C8718EFD97F85C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0DA686F04F4AECD0845522B509A788FE,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_6 8D080A9C4D24A7BABBCFCDB85CE801C0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_5" bCommentBubbleVisible_InDetailsPanel=False NodePosX=-368 NodePosY=1056 NodeWidth=2560 NodeHeight=336 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Modify the scene by excluding meshes and mesh actors whose names match a keyword" NodeGuid=4ADA461F4BF2CA2A5F7231BCD5B7D2BA End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_13" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=-224 NodePosY=1568 NodeGuid=2E25943B401F8F8577E82BBAF178842A CustomProperties Pin (PinId=BA499A854090A91A595B95A1783495B9,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_16 FE7AE720417B9C116A748C8BF58B6CDB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=96527C1C46AE12EDC781DAB73B1C12A6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_14" VariableReference=(MemberName="DestinationFolder",MemberGuid=CFE371D74632A24AB312B3877707C3B1,bSelfContext=True) NodePosX=-256 NodePosY=2096 NodeGuid=1109AD004C63D36BB78A6F8D1165DD26 CustomProperties Pin (PinId=D744023044D0310FB4FC0EACE9C9A1EF,PinName="DestinationFolder",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_17 5A75177B4AB96BE846D9E0B27F9AEF4E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A584E11E42CB231EF2617B87F492483A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_16" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',MemberName="GetOptions") NodePosX=-32 NodePosY=1456 NodeGuid=97FCDE5C489FF0824E19FB948A151088 CustomProperties Pin (PinId=34D5C7684815CD2294E2E59205BF4564,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_ComponentBoundEvent_9 8A2A875543CE42299BB978A4E2063A19,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=69FBCA784932BB62D571E1B7D8FE8AFB,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_2 B48E54254199E321DEA84F851D6E7DD1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FE7AE720417B9C116A748C8BF58B6CDB,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_13 BA499A854090A91A595B95A1783495B9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F50E05814AB9DC255A01E29DDFF51971,PinName="OptionType",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,AutogeneratedDefaultValue="None",DefaultObject="/Script/DatasmithContent.DatasmithImportOptions",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A694A5D94192C05E4958DBA54B1FEC8A,PinName="ReturnValue",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithContent.DatasmithImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_2 CF3C30ED4D489B5EFCE756B667348033,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_6" bCommentBubbleVisible_InDetailsPanel=False NodePosX=-368 NodePosY=1408 NodeWidth=1920 NodeHeight=496 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Set import options" NodeGuid=42D7B83D4335ACC79B82F4AE09653B7B End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_15" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=-256 NodePosY=2048 NodeGuid=822AD0C24B4F2739BE9F8591354B44DB CustomProperties Pin (PinId=B384443E4412494FD645DB9CDB08FAA5,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_17 A1FB7ADB467853781F1CC5AB8AAED65D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8636CAE1400509BE30577FBE384270CD,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_17" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',MemberName="ImportScene") NodePosX=-64 NodePosY=1984 NodeGuid=011E3EBD42FC1B39973E61A699CC4C2F CustomProperties Pin (PinId=9552B7B4440102FCD63824BCD3CDC466,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_ComponentBoundEvent_11 A66C28D74097EC2B9E3A2BBC0AF39333,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A67C951642BC52B64B3773853B70DB8C,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A1FB7ADB467853781F1CC5AB8AAED65D,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_15 B384443E4412494FD645DB9CDB08FAA5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A75177B4AB96BE846D9E0B27F9AEF4E,PinName="DestinationFolder",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_14 D744023044D0310FB4FC0EACE9C9A1EF,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=70A8F04043491F27A1C338B389039CA6,PinName="ReturnValue",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithImporter.DatasmithImportFactoryCreateFileResult"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_7" bCommentBubbleVisible_InDetailsPanel=False NodePosX=-368 NodePosY=1920 NodeWidth=612 NodeHeight=261 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Finish the import" NodeGuid=F940D51E4689060928C57592DED24292 End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_2" VariableReference=(MemberParent=Class'"/Script/DatasmithContent.DatasmithImportOptions"',MemberName="BaseOptions") SelfContextInfo=NotSelfContext NodePosX=1088 NodePosY=1472 NodeGuid=8585577043D4FB1516C6CFAEE3114BB5 CustomProperties Pin (PinId=B48E54254199E321DEA84F851D6E7DD1,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_16 69FBCA784932BB62D571E1B7D8FE8AFB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=82355F254E1B2E00A17100B7DA948B89,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1EB267A54CE218BB3128D7AD1A1F8F33,PinName="BaseOptions",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithImportBaseOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MakeStruct_0 29ADD4EC463A6E87D3F10BAFEBC222A7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=47AB86654912A7BB101BA8A47FD4D612,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithImportBaseOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CF3C30ED4D489B5EFCE756B667348033,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithContent.DatasmithImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_16 A694A5D94192C05E4958DBA54B1FEC8A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MakeStruct Name="K2Node_MakeStruct_0" bMadeAfterOverridePinRemoval=True ShowPinForProperties(0)=(PropertyName="SceneHandling",PropertyFriendlyName="Scene Handling",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:SceneHandling", "Specifies where to put the content"),CategoryName="Import",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(1)=(PropertyName="bIncludeGeometry",PropertyFriendlyName="Geometry",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:bIncludeGeometry", "Specifies whether or not to import geometry"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(2)=(PropertyName="bIncludeMaterial",PropertyFriendlyName="Materials & Textures",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:bIncludeMaterial", "Specifies whether or not to import materials and textures"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(3)=(PropertyName="bIncludeLight",PropertyFriendlyName="Lights",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:bIncludeLight", "Specifies whether or not to import lights"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(4)=(PropertyName="bIncludeCamera",PropertyFriendlyName="Cameras",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:bIncludeCamera", "Specifies whether or not to import cameras"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(5)=(PropertyName="bIncludeAnimation",PropertyFriendlyName="Animations",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:bIncludeAnimation", "Specifies whether or not to import animations"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(6)=(PropertyName="AssetOptions",PropertyFriendlyName="Asset Options",PropertyTooltip=NSLOCTEXT("", "0F230491455674922DB44E8C4C7425E5", "Asset Options"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True,bIsMarkedForAdvancedDisplay=True) ShowPinForProperties(7)=(PropertyName="StaticMeshOptions",PropertyFriendlyName="Static Mesh Options",PropertyTooltip=NSLOCTEXT("", "CC1A9A0A48B5B36994A60782C6B6AC88", "Static Mesh Options"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True,bIsMarkedForAdvancedDisplay=True) StructType=ScriptStruct'"/Script/DatasmithContent.DatasmithImportBaseOptions"' NodePosX=560 NodePosY=1600 AdvancedPinDisplay=Shown NodeGuid=DAC195D74B8CB3A4414829B7D25D37BD CustomProperties Pin (PinId=29ADD4EC463A6E87D3F10BAFEBC222A7,PinName="DatasmithImportBaseOptions",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithImportBaseOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_2 1EB267A54CE218BB3128D7AD1A1F8F33,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=171F34D94B79383AE65760A029766D16,PinName="SceneHandling",PinFriendlyName=NSLOCTEXT("", "00B5E5464946EB7153481285B0C2B933", "Scene Handling"),PinToolTip="Scene Handling\nEDatasmithImportScene Enum\n\nSpecifies where to put the content",PinType.PinCategory="byte",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Enum'"/Script/DatasmithContent.EDatasmithImportScene"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="CurrentLevel",AutogeneratedDefaultValue="CurrentLevel",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B5560C3B4DC3467CA3E5C59807DBE06E,PinName="bIncludeGeometry",PinFriendlyName=NSLOCTEXT("", "E29BA4194EBF4796CEFFE494CCCACE5D", "Geometry"),PinToolTip="Geometry\nBoolean\n\nSpecifies whether or not to import geometry",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="True",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7C7806D542F2EA04C02223A6F3E3DAB8,PinName="bIncludeMaterial",PinFriendlyName=NSLOCTEXT("", "2E235A2F4E599A38E6AD9FA75E8B3894", "Materials & Textures"),PinToolTip="Materials & Textures\nBoolean\n\nSpecifies whether or not to import materials and textures",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="True",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=97A2C92742B464ADFD575ABB460DE516,PinName="bIncludeLight",PinFriendlyName=NSLOCTEXT("", "A7BC48CA4F435CDA95AA33AFF2818B64", "Lights"),PinToolTip="Lights\nBoolean\n\nSpecifies whether or not to import lights",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="True",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DBAFD6A547AAEE45C55A60917F62F5A3,PinName="bIncludeCamera",PinFriendlyName=NSLOCTEXT("", "281FA29A4CD789D25E1A1E91EB2C59BF", "Cameras"),PinToolTip="Cameras\nBoolean\n\nSpecifies whether or not to import cameras",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="True",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C2CE6CA4424E5EBE818668B084C92221,PinName="bIncludeAnimation",PinFriendlyName=NSLOCTEXT("", "09B589194A19E594CD10C2A3F01A35B6", "Animations"),PinToolTip="Animations\nBoolean\n\nSpecifies whether or not to import animations",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="True",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9A9D69B84414C274C225D39D168F84BF,PinName="AssetOptions",PinFriendlyName=NSLOCTEXT("", "2DE66ADC4ED64B3A021F19A9D50B2D3C", "Asset Options"),PinToolTip="Asset Options\nDatasmith Asset Import Options Structure\n\nAsset Options",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithAssetImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="(PackagePath=\"\")",AutogeneratedDefaultValue="(PackagePath=\"\")",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=172E61C74E70357C83B1B78274C0187B,PinName="StaticMeshOptions",PinFriendlyName=NSLOCTEXT("", "D5EE4B2C48B1078B5E8CD1B32AB72F9C", "Static Mesh Options"),PinToolTip="Static Mesh Options\nDatasmith Static Mesh Import Options Structure\n\nStatic Mesh Options",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithStaticMeshImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="(MinLightmapResolution=LIGHTMAP_64,MaxLightmapResolution=LIGHTMAP_512)",AutogeneratedDefaultValue="(MinLightmapResolution=LIGHTMAP_64,MaxLightmapResolution=LIGHTMAP_512)",LinkedTo=(K2Node_MakeStruct_1 3E1FD08447A9B5A2D9CF648E302CCBC9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MakeStruct Name="K2Node_MakeStruct_1" bMadeAfterOverridePinRemoval=True ShowPinForProperties(0)=(PropertyName="MinLightmapResolution",PropertyFriendlyName="Min Lightmap Resolution",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithStaticMeshImportOptions:MinLightmapResolution", "Minimum resolution for auto-generated lightmap UVs"),CategoryName="Lightmap",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(1)=(PropertyName="MaxLightmapResolution",PropertyFriendlyName="Max Lightmap Resolution",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithStaticMeshImportOptions:MaxLightmapResolution", "Maximum resolution for auto-generated lightmap UVs"),CategoryName="Lightmap",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(2)=(PropertyName="bGenerateLightmapUVs",PropertyFriendlyName="Generate Lightmap UVs",PropertyTooltip=NSLOCTEXT("", "5E4B0F3C4DB1928EF0EC2F8F270140A4", "Generate Lightmap UVs"),CategoryName="Lightmap",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(3)=(PropertyName="bRemoveDegenerates",PropertyFriendlyName="Remove Degenerates",PropertyTooltip=NSLOCTEXT("", "8AB594C4430D5D0AB76850983DE8474C", "Remove Degenerates"),CategoryName="Mesh",bShowPin=True,bCanToggleVisibility=True) StructType=ScriptStruct'"/Script/DatasmithContent.DatasmithStaticMeshImportOptions"' NodePosX=16 NodePosY=1664 NodeGuid=863683694AE73CD34D8FCA9CD320E53E CustomProperties Pin (PinId=3E1FD08447A9B5A2D9CF648E302CCBC9,PinName="DatasmithStaticMeshImportOptions",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithStaticMeshImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MakeStruct_0 172E61C74E70357C83B1B78274C0187B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=895442FE45529FEBC167599D880E2604,PinName="MinLightmapResolution",PinFriendlyName=NSLOCTEXT("", "EF642894437DEB4A93EA07BF9DDBD22F", "Min Lightmap Resolution"),PinToolTip="Min Lightmap Resolution\nEDatasmithImportLightmapMin Enum\n\nMinimum resolution for auto-generated lightmap UVs",PinType.PinCategory="byte",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Enum'"/Script/DatasmithContent.EDatasmithImportLightmapMin"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="LIGHTMAP_16",AutogeneratedDefaultValue="LIGHTMAP_64",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E5FDBC0A4CDBE15D62D832A5128507E2,PinName="MaxLightmapResolution",PinFriendlyName=NSLOCTEXT("", "861CE1944CB983F7E5D6F89CACC5884C", "Max Lightmap Resolution"),PinToolTip="Max Lightmap Resolution\nEDatasmithImportLightmapMax Enum\n\nMaximum resolution for auto-generated lightmap UVs",PinType.PinCategory="byte",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Enum'"/Script/DatasmithContent.EDatasmithImportLightmapMax"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="LIGHTMAP_64",AutogeneratedDefaultValue="LIGHTMAP_512",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=72FAF41E46D17734702F0C8518AFDE98,PinName="bGenerateLightmapUVs",PinFriendlyName=NSLOCTEXT("", "676F09A94E4A41663FDA8BB4EC874982", "Generate Lightmap UVs"),PinToolTip="Generate Lightmap UVs\nBoolean\n\nGenerate Lightmap UVs",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="false",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4E718767429D7E6BCFF270B59516F751,PinName="bRemoveDegenerates",PinFriendlyName=NSLOCTEXT("", "BDF0489943221B3008D65BAAB55FCAF5", "Remove Degenerates"),PinToolTip="Remove Degenerates\nBoolean\n\nRemove Degenerates",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="True",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Click the top right of the image to copy the node graph.

Importing a CAD File

In this example, the first Get Options call requests the same DatasmithImportOptions class as the previous example. The second call requests the DatasmithCommonTessellationOptions class, which contains the tessellation settings inside its Options variable. The third call requests the DatasmithCADImportOptions class, which contains additional CAD-specific settings that are generally intended for use in special circumstances.



Begin Object Class=/Script/BlueprintGraph.K2Node_ComponentBoundEvent Name="K2Node_ComponentBoundEvent_0" DelegatePropertyName="OnClicked" DelegateOwnerClass=Class'"/Script/UMG.Button"' ComponentPropertyName="Button_95" DelegatePropertyDisplayName=NSLOCTEXT("UObjectDisplayNames", "Button:OnClicked", "On Clicked") EventReference=(MemberParent=Package'"/Script/UMG"',MemberName="OnButtonClickedEvent__DelegateSignature") bInternalEvent=True CustomFunctionName="BndEvt__Button_95_K2Node_ComponentBoundEvent_0_OnButtonClickedEvent__DelegateSignature" NodePosX=-80 NodePosY=2464 NodeGuid=2E35BEAB4722593A182CC0B141031918 CustomProperties Pin (PinId=0FA7E49345102A62A2AE008BFAEE90AF,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=19C6DCD9454CE19724D4ED8DB8828088,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_7 73245C05460F1B275DEAA8BAA946C293,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_ComponentBoundEvent Name="K2Node_ComponentBoundEvent_5" DelegatePropertyName="OnClicked" DelegateOwnerClass=Class'"/Script/UMG.Button"' ComponentPropertyName="Button_210" DelegatePropertyDisplayName=NSLOCTEXT("UObjectDisplayNames", "Button:OnClicked", "On Clicked") EventReference=(MemberParent=Package'"/Script/UMG"',MemberName="OnButtonClickedEvent__DelegateSignature") bInternalEvent=True CustomFunctionName="BndEvt__Button_210_K2Node_ComponentBoundEvent_5_OnButtonClickedEvent__DelegateSignature" NodePosX=-80 NodePosY=2672 NodeGuid=DD6215304AD48E5A30272F92AE0F787C CustomProperties Pin (PinId=B9EE48A1480BF02FCE9DA098F6E19815,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F3F685684A8AF38F5BA522AF1C199A02,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_8 F09D350F40F0C72E6A1A949740D04057,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_ComponentBoundEvent Name="K2Node_ComponentBoundEvent_6" DelegatePropertyName="OnClicked" DelegateOwnerClass=Class'"/Script/UMG.Button"' ComponentPropertyName="Button_335" DelegatePropertyDisplayName=NSLOCTEXT("UObjectDisplayNames", "Button:OnClicked", "On Clicked") EventReference=(MemberParent=Package'"/Script/UMG"',MemberName="OnButtonClickedEvent__DelegateSignature") bInternalEvent=True CustomFunctionName="BndEvt__Button_335_K2Node_ComponentBoundEvent_6_OnButtonClickedEvent__DelegateSignature" NodePosX=-32 NodePosY=3040 NodeGuid=5879D6BC4DA3827A86CACBAE47D8CBF1 CustomProperties Pin (PinId=2785B97D4B887477D4FEFD9007837016,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=96955004449AA3CEF73EDD9264918F4B,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_14 34D5C7684815CD2294E2E59205BF4564,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_ComponentBoundEvent Name="K2Node_ComponentBoundEvent_7" DelegatePropertyName="OnClicked" DelegateOwnerClass=Class'"/Script/UMG.Button"' ComponentPropertyName="Button_429" DelegatePropertyDisplayName=NSLOCTEXT("UObjectDisplayNames", "Button:OnClicked", "On Clicked") EventReference=(MemberParent=Package'"/Script/UMG"',MemberName="OnButtonClickedEvent__DelegateSignature") bInternalEvent=True CustomFunctionName="BndEvt__Button_429_K2Node_ComponentBoundEvent_7_OnButtonClickedEvent__DelegateSignature" NodePosX=-80 NodePosY=3584 NodeGuid=7AD9F3BE4ECB84482D6195BAB7D2168B CustomProperties Pin (PinId=E0C373974DC735830DCCB18F136E5C9D,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4200B56D4C77C5748CDD08851A0710B3,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_15 9552B7B4440102FCD63824BCD3CDC466,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_0" VariableReference=(MemberName="SourcePath",MemberGuid=EE32D38E4D0FD567CB6339BE070DEF14,bSelfContext=True) NodePosX=-16 NodePosY=2544 NodeGuid=A48C1EE74CF6D3520F9629B68F100792 CustomProperties Pin (PinId=B47E818542BBE5381CC13B89F464138C,PinName="SourcePath",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_7 E65E2B82418159F25F7E97B975379989,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3C77B64F4771BEA076DEAB9A7E0212B5,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_7" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',MemberName="ConstructDatasmithSceneFromFile") NodePosX=144 NodePosY=2464 NodeGuid=38C6A3DF4FC868BB0327DC925B057535 CustomProperties Pin (PinId=73245C05460F1B275DEAA8BAA946C293,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_ComponentBoundEvent_0 19C6DCD9454CE19724D4ED8DB8828088,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=06B94A4F4D33A50242BB22916E9616B6,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_0 8B494A5145B0700C63131587FD2EEB29,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5D024BD74486182F8E953E986875E019,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nDatasmith Scene Element Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/DatasmithImporter.Default__DatasmithSceneElement",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E65E2B82418159F25F7E97B975379989,PinName="FilePath",PinToolTip="File Path\nString\n\nUDatasmith file path to open. ie: c:/MyFolder/MyFiles.udatasmith",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_0 B47E818542BBE5381CC13B89F464138C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FD94D6EC4245D9A311349A8D6D7DF8BE,PinName="ReturnValue",PinToolTip="Return Value\nDatasmith Scene Element Object Reference\n\nThe opened DatasmithScene, that can be modified and can be imported.",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_0 29C81FD640AE144B15F33AB774E43058,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_0" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=448 NodePosY=2464 NodeGuid=421F9F89458E442AB4C95F9B4B899F61 CustomProperties Pin (PinId=8B494A5145B0700C63131587FD2EEB29,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_7 06B94A4F4D33A50242BB22916E9616B6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1D4880DD4CD8ECA4FAD60188BF3E12A8,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=29C81FD640AE144B15F33AB774E43058,PinName="DatasmithScene",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_7 FD94D6EC4245D9A311349A8D6D7DF8BE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7FF3F81642FFBC4CA9F6AA8462CE894C,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=97B227144DCA12697425DB8CE9A91983,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_0" bCommentBubbleVisible_InDetailsPanel=False NodePosX=-128 NodePosY=2416 NodeWidth=816 NodeHeight=192 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Construct the Datasmith Scene" NodeGuid=9C172B42447F781724943B90F5445E65 End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_1" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=-32 NodePosY=2752 NodeGuid=3C2FA3034A934B6EBE0E16962433530F CustomProperties Pin (PinId=B19039234515D9D6D77BBBBC3955841D,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_8 8CA76E4B4FBF3D84BFD59A98609DCEAE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=72A798EC4FB618464CABE6AF0094CF9E,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_8" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',MemberName="GetAllMeshActors") NodePosX=144 NodePosY=2672 NodeGuid=BD792D244EFDF46DCAB7479F70602C27 CustomProperties Pin (PinId=F09D350F40F0C72E6A1A949740D04057,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_ComponentBoundEvent_5 F3F685684A8AF38F5BA522AF1C199A02,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AF908649489E8BD258632B81E9163487,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 8A634C4546F081BBDF032080016B7750,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8CA76E4B4FBF3D84BFD59A98609DCEAE,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nDatasmith Scene Element Base Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_1 B19039234515D9D6D77BBBBC3955841D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6200D1764E2A2BF25BB534AC9C4C5E97,PinName="ReturnValue",PinToolTip="Return Value\nArray of Datasmith Mesh Actor Element Object References\n\nCreate an array with all the MeshActor in the Datasmith scene without taking into account the hierarchy.\nUse CreateMeshActor -or- RemoveMeshActor to modify the Datasmith scene.",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 52DE027F4AC9008EC95C818F9C7D007F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_0" MacroGraphReference=(MacroGraph=EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForEachLoop"',GraphBlueprint=Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=99DBFD5540A796041F72A5A9DA655026) ResolvedWildcardType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',ContainerType=Array) NodePosX=448 NodePosY=2672 NodeGuid=C37D9546442F5898088415A28D356ED0 CustomProperties Pin (PinId=8A634C4546F081BBDF032080016B7750,PinName="Exec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_8 AF908649489E8BD258632B81E9163487,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=52DE027F4AC9008EC95C818F9C7D007F,PinName="Array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_8 6200D1764E2A2BF25BB534AC9C4C5E97,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C74584BC48D87EC21BD9F89CBD4D5447,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_IfThenElse_1 90BA1A0C4803055E2C26A985E3C3F637,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6BD909C44DBF27901D89FCBD6FA0C196,PinName="Array Element",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_9 7D64F01042DA58B86C5ADC9F78468668,K2Node_Knot_0 736766394358480B1D3DB2AFCBB75D8C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=615807344B9CB28D00D7919AE0E73C57,PinName="Array Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=740A582C4FE874CBAF9A7FBBE5B66D9D,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_9" bIsPureFunc=True bIsConstFunc=True FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithActorElement"',MemberName="GetLabel") NodePosX=688 NodePosY=2736 NodeGuid=453376924892746C68E7EDB280F5918F CustomProperties Pin (PinId=7D64F01042DA58B86C5ADC9F78468668,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nDatasmith Actor Element Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 6BD909C44DBF27901D89FCBD6FA0C196,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FE9F3BC349E06FBCFFF3819C53E736D3,PinName="ReturnValue",PinToolTip="Return Value\nString\n\nGets the element label used in the UI",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_10 784F3CFE44EB60EED770CE8C00A833F5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_10" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetStringLibrary"',MemberName="Contains") NodePosX=960 NodePosY=2736 NodeGuid=245FA51646A35B1F233A1BA8FDF7C254 CustomProperties Pin (PinId=8ED82A39451CBBEDD11E9A84C8C57583,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetStringLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetStringLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=784F3CFE44EB60EED770CE8C00A833F5,PinName="SearchIn",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_9 FE9F3BC349E06FBCFFF3819C53E736D3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CDED70BB48352F4B36AECE8DF41D59F5,PinName="Substring",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_2 A61750104C0CCB8BD7332FAFABCB0B36,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=27E608714F1137737C8F588450A88EEE,PinName="bUseCase",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7290B3A14BB8F8F5CC0CBC9DC2F59C7D,PinName="bSearchFromEnd",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B61D4BE2440F9FE5805FDA8F4699DE8B,PinName="ReturnValue",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="false",AutogeneratedDefaultValue="false",LinkedTo=(K2Node_IfThenElse_1 C6374EC44D19BDBEFAA39791B998A224,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_2" VariableReference=(MemberName="ExcludeKeyword",MemberGuid=5EDD18B84283704C6A93AA8FCBD53BB2,bSelfContext=True) NodePosX=784 NodePosY=2832 NodeGuid=A14F654B45650764F3C8018DC83AD3AB CustomProperties Pin (PinId=A61750104C0CCB8BD7332FAFABCB0B36,PinName="ExcludeKeyword",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_10 CDED70BB48352F4B36AECE8DF41D59F5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A98C972B4454102AFFE54BB60DCCE5AE,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_1" NodePosX=1264 NodePosY=2672 NodeGuid=F7888BB5415638157C8233B6C7494DBB CustomProperties Pin (PinId=90BA1A0C4803055E2C26A985E3C3F637,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 C74584BC48D87EC21BD9F89CBD4D5447,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C6374EC44D19BDBEFAA39791B998A224,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_CallFunction_10 B61D4BE2440F9FE5805FDA8F4699DE8B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F33417484D8690D3C3C203B9DDCDF2F9,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_11 9EF64EBE440A216720E04AA6CC4B71F7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F63746FA45B783F34CB98B8B69B2487A,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_11" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',MemberName="GetMeshElement") NodePosX=1488 NodePosY=2736 NodeGuid=91947AE8473BC742B22FF6A12D47AE45 CustomProperties Pin (PinId=9EF64EBE440A216720E04AA6CC4B71F7,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_IfThenElse_1 F33417484D8690D3C3C203B9DDCDF2F9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=006ED87B4EFBFE47CDA6DEBA234157EF,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_12 F49269844DAF895470D5C3A1651738EA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=70CE54A549D1DEB53BAF44B63251CC14,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nDatasmith Mesh Actor Element Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_2 2EB534AF44E068BF92C8718EFD97F85C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D996A2184425B1D74810B199447BB1C2,PinName="ReturnValue",PinToolTip="Return Value\nDatasmith Mesh Element Object Reference\n\nGet the Datasmith MeshElement associated with the actor. The Mesh can be a direct reference to an Unreal Mesh. If it\'s the case it will return an invalid MeshElement.",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_12 066348544D45E15D92C5BA9A54137EFC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_0" NodePosX=688 NodePosY=2928 NodeGuid=98DFB3A14050FD58EDF75D85700F4A33 CustomProperties Pin (PinId=736766394358480B1D3DB2AFCBB75D8C,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 6BD909C44DBF27901D89FCBD6FA0C196,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8D48C5904859E9F5FD1AC2B649675C86,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_2 89B038D04A8257E4EDD7E0B7B7F71D65,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_2" NodePosX=1392 NodePosY=2928 NodeGuid=64A145244CD9AB3EC7B16DAFB34AF87D CustomProperties Pin (PinId=89B038D04A8257E4EDD7E0B7B7F71D65,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_0 8D48C5904859E9F5FD1AC2B649675C86,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2EB534AF44E068BF92C8718EFD97F85C,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_11 70CE54A549D1DEB53BAF44B63251CC14,K2Node_Knot_3 2991785048D4A29507659E8128D52F46,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=1616 NodePosY=2864 NodeGuid=FFEC4DA64D76675E2EFFD9A886251D21 CustomProperties Pin (PinId=27A96AEF460C1183B4A0029F8E59EB84,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_12 FF7A47EC4E3D76CB7736068BCDD18449,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FBA4B4D946631EB71F693792EC2F8CD6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_12" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',MemberName="RemoveMesh") NodePosX=1792 NodePosY=2736 NodeGuid=E7BBFDFA438467744C4F729518A2F425 CustomProperties Pin (PinId=F49269844DAF895470D5C3A1651738EA,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_11 006ED87B4EFBFE47CDA6DEBA234157EF,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AB280A58483150FC58963A96A7B9BF13,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_13 37112D5445D133F3C80D618ADD0093AC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FF7A47EC4E3D76CB7736068BCDD18449,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nDatasmith Scene Element Base Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_3 27A96AEF460C1183B4A0029F8E59EB84,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=066348544D45E15D92C5BA9A54137EFC,PinName="InMesh",PinToolTip="In Mesh\nDatasmith Mesh Element Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_11 D996A2184425B1D74810B199447BB1C2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_4" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=1920 NodePosY=2880 NodeGuid=5E44CF22439CD895B0C1A38EA2201BFB CustomProperties Pin (PinId=3711FB544CDEE2C13D11628DA9EDF8F3,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_13 7D3CABE74392B154F4793483203EAA3B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BF5A59D64EC084B64C863E9D200B3C2F,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_13" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',MemberName="RemoveMeshActor") NodePosX=2096 NodePosY=2736 NodeGuid=1A74BA6248BF6664519F95A987D3A57C CustomProperties Pin (PinId=37112D5445D133F3C80D618ADD0093AC,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_12 AB280A58483150FC58963A96A7B9BF13,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9F9C411548B20C46777D74A9967C165B,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7D3CABE74392B154F4793483203EAA3B,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElementBase"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_4 3711FB544CDEE2C13D11628DA9EDF8F3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8D080A9C4D24A7BABBCFCDB85CE801C0,PinName="InMeshActor",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_3 0DA686F04F4AECD0845522B509A788FE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5ECBAEC4490366E7CFC946B06625962B,PinName="RemoveRule",PinType.PinCategory="byte",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Enum'"/Script/DatasmithCore.EDatasmithActorRemovalRule"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="RemoveChildren",AutogeneratedDefaultValue="RemoveChildren",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_3" NodePosX=2032 NodePosY=2928 NodeGuid=E7C7669148D485A6D79FF59449F3A167 CustomProperties Pin (PinId=2991785048D4A29507659E8128D52F46,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_2 2EB534AF44E068BF92C8718EFD97F85C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0DA686F04F4AECD0845522B509A788FE,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithMeshActorElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_13 8D080A9C4D24A7BABBCFCDB85CE801C0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_1" bCommentBubbleVisible_InDetailsPanel=False NodePosX=-128 NodePosY=2624 NodeWidth=2560 NodeHeight=336 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Modify the scene by excluding meshes and mesh actors whose names match a keyword" NodeGuid=D6745913408A4D9456578E9C073F84EF End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_16" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=16 NodePosY=3136 NodeGuid=30ADD34C41962FEDDB2BDAB8E739AA7F CustomProperties Pin (PinId=BA499A854090A91A595B95A1783495B9,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_14 FE7AE720417B9C116A748C8BF58B6CDB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=96527C1C46AE12EDC781DAB73B1C12A6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_6" VariableReference=(MemberName="DestinationFolder",MemberGuid=CFE371D74632A24AB312B3877707C3B1,bSelfContext=True) NodePosX=-16 NodePosY=3712 NodeGuid=34E310254C49D168BDEB19AE8D89EDAD CustomProperties Pin (PinId=D744023044D0310FB4FC0EACE9C9A1EF,PinName="DestinationFolder",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_15 5A75177B4AB96BE846D9E0B27F9AEF4E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A584E11E42CB231EF2617B87F492483A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_14" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',MemberName="GetOptions") NodePosX=208 NodePosY=3040 NodeGuid=9523559A44C14FBCA6A67FB34CB0B232 CustomProperties Pin (PinId=34D5C7684815CD2294E2E59205BF4564,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_ComponentBoundEvent_6 96955004449AA3CEF73EDD9264918F4B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=69FBCA784932BB62D571E1B7D8FE8AFB,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_3 B48E54254199E321DEA84F851D6E7DD1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FE7AE720417B9C116A748C8BF58B6CDB,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nDatasmith Scene Element Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_16 BA499A854090A91A595B95A1783495B9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F50E05814AB9DC255A01E29DDFF51971,PinName="OptionType",PinToolTip="Option Type\nObject Class Reference",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,AutogeneratedDefaultValue="None",DefaultObject="/Script/DatasmithContent.DatasmithImportOptions",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A694A5D94192C05E4958DBA54B1FEC8A,PinName="ReturnValue",PinToolTip="Return Value\nDatasmith Import Options Object Reference\n\nGet Options",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithContent.DatasmithImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_3 CF3C30ED4D489B5EFCE756B667348033,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_2" bCommentBubbleVisible_InDetailsPanel=False NodePosX=-128 NodePosY=2976 NodeWidth=2304 NodeHeight=544 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Set import options" NodeGuid=21FB006F4667A7351E09AEAAB8C2D203 End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_8" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=-16 NodePosY=3664 NodeGuid=B9EBECE740623154E89621BBD5F66A99 CustomProperties Pin (PinId=B384443E4412494FD645DB9CDB08FAA5,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_15 A1FB7ADB467853781F1CC5AB8AAED65D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8636CAE1400509BE30577FBE384270CD,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_15" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',MemberName="ImportScene") NodePosX=176 NodePosY=3600 NodeGuid=261467044FC227A7A89E5CA740384A52 CustomProperties Pin (PinId=9552B7B4440102FCD63824BCD3CDC466,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_ComponentBoundEvent_7 4200B56D4C77C5748CDD08851A0710B3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A67C951642BC52B64B3773853B70DB8C,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A1FB7ADB467853781F1CC5AB8AAED65D,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nDatasmith Scene Element Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_8 B384443E4412494FD645DB9CDB08FAA5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A75177B4AB96BE846D9E0B27F9AEF4E,PinName="DestinationFolder",PinToolTip="Destination Folder\nString\n\nDestination of where you want the asset to be imported. ie: /Game/MyFolder1",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_6 D744023044D0310FB4FC0EACE9C9A1EF,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=70A8F04043491F27A1C338B389039CA6,PinName="ReturnValue",PinToolTip="Return Value\nDatasmith Import Factory Create File Result Structure\n\nA structure that contains the created actor or the Blueprint actor depending of the options specified at the import.",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithImporter.DatasmithImportFactoryCreateFileResult"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_3" bCommentBubbleVisible_InDetailsPanel=False NodePosX=-128 NodePosY=3536 NodeWidth=608 NodeHeight=224 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Finish the import" NodeGuid=57AB75FC4343B3FDF77BEBA512043DD9 End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_3" VariableReference=(MemberParent=Class'"/Script/DatasmithContent.DatasmithImportOptions"',MemberName="BaseOptions") SelfContextInfo=NotSelfContext NodePosX=544 NodePosY=3072 NodeGuid=B040337249CC58A1F63EC9A5BF561F78 CustomProperties Pin (PinId=B48E54254199E321DEA84F851D6E7DD1,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_14 69FBCA784932BB62D571E1B7D8FE8AFB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=82355F254E1B2E00A17100B7DA948B89,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_18 7EF6D32C467BDF06A9BBA9A34D666E9D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1EB267A54CE218BB3128D7AD1A1F8F33,PinName="BaseOptions",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithImportBaseOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MakeStruct_2 29ADD4EC463A6E87D3F10BAFEBC222A7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=47AB86654912A7BB101BA8A47FD4D612,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithImportBaseOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CF3C30ED4D489B5EFCE756B667348033,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithContent.DatasmithImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_14 A694A5D94192C05E4958DBA54B1FEC8A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MakeStruct Name="K2Node_MakeStruct_2" bMadeAfterOverridePinRemoval=True ShowPinForProperties(0)=(PropertyName="SceneHandling",PropertyFriendlyName="Scene Handling",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:SceneHandling", "Specifies where to put the content"),CategoryName="Import",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(1)=(PropertyName="bIncludeGeometry",PropertyFriendlyName="Geometry",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:bIncludeGeometry", "Specifies whether or not to import geometry"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(2)=(PropertyName="bIncludeMaterial",PropertyFriendlyName="Materials & Textures",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:bIncludeMaterial", "Specifies whether or not to import materials and textures"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(3)=(PropertyName="bIncludeLight",PropertyFriendlyName="Lights",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:bIncludeLight", "Specifies whether or not to import lights"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(4)=(PropertyName="bIncludeCamera",PropertyFriendlyName="Cameras",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:bIncludeCamera", "Specifies whether or not to import cameras"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(5)=(PropertyName="bIncludeAnimation",PropertyFriendlyName="Animations",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithImportBaseOptions:bIncludeAnimation", "Specifies whether or not to import animations"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(6)=(PropertyName="AssetOptions",PropertyFriendlyName="Asset Options",PropertyTooltip=NSLOCTEXT("", "D80DEBAC4B7934980624CA8339D2387F", "Asset Options"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True,bIsMarkedForAdvancedDisplay=True) ShowPinForProperties(7)=(PropertyName="StaticMeshOptions",PropertyFriendlyName="Static Mesh Options",PropertyTooltip=NSLOCTEXT("", "1E0B66CF49DFAAA30F2AF6A1BA90C095", "Static Mesh Options"),CategoryName="Process",bShowPin=True,bCanToggleVisibility=True,bIsMarkedForAdvancedDisplay=True) StructType=ScriptStruct'"/Script/DatasmithContent.DatasmithImportBaseOptions"' NodePosX=80 NodePosY=3200 AdvancedPinDisplay=Shown NodeGuid=27C93E344FF75BF4A787179F5214E72E CustomProperties Pin (PinId=29ADD4EC463A6E87D3F10BAFEBC222A7,PinName="DatasmithImportBaseOptions",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithImportBaseOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_3 1EB267A54CE218BB3128D7AD1A1F8F33,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=171F34D94B79383AE65760A029766D16,PinName="SceneHandling",PinFriendlyName=NSLOCTEXT("", "86A9C3564E27587B96A2AC8BC4F32EB5", "Scene Handling"),PinToolTip="Scene Handling\nEDatasmithImportScene Enum\n\nSpecifies where to put the content",PinType.PinCategory="byte",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Enum'"/Script/DatasmithContent.EDatasmithImportScene"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="CurrentLevel",AutogeneratedDefaultValue="CurrentLevel",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B5560C3B4DC3467CA3E5C59807DBE06E,PinName="bIncludeGeometry",PinFriendlyName=NSLOCTEXT("", "F5B7761A4CB48765260DE99D8D9BFD9A", "Geometry"),PinToolTip="Geometry\nBoolean\n\nSpecifies whether or not to import geometry",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="True",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7C7806D542F2EA04C02223A6F3E3DAB8,PinName="bIncludeMaterial",PinFriendlyName=NSLOCTEXT("", "9AC6974A4B446FC78A229283CF67D947", "Materials & Textures"),PinToolTip="Materials & Textures\nBoolean\n\nSpecifies whether or not to import materials and textures",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="True",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=97A2C92742B464ADFD575ABB460DE516,PinName="bIncludeLight",PinFriendlyName=NSLOCTEXT("", "99E585EE49A714DFB80E72918F95A5F8", "Lights"),PinToolTip="Lights\nBoolean\n\nSpecifies whether or not to import lights",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="True",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DBAFD6A547AAEE45C55A60917F62F5A3,PinName="bIncludeCamera",PinFriendlyName=NSLOCTEXT("", "73BC00C14B6516F454B6CBA9F8F60C1A", "Cameras"),PinToolTip="Cameras\nBoolean\n\nSpecifies whether or not to import cameras",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="True",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C2CE6CA4424E5EBE818668B084C92221,PinName="bIncludeAnimation",PinFriendlyName=NSLOCTEXT("", "8934BCF2442C68D078CF93B25D22D85D", "Animations"),PinToolTip="Animations\nBoolean\n\nSpecifies whether or not to import animations",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="True",AutogeneratedDefaultValue="True",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9A9D69B84414C274C225D39D168F84BF,PinName="AssetOptions",PinFriendlyName=NSLOCTEXT("", "E9A55F264D0C4F0CF77542A5A73EF750", "Asset Options"),PinToolTip="Asset Options\nDatasmith Asset Import Options Structure\n\nAsset Options",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithAssetImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="(PackagePath=\"\")",AutogeneratedDefaultValue="(PackagePath=\"\")",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=172E61C74E70357C83B1B78274C0187B,PinName="StaticMeshOptions",PinFriendlyName=NSLOCTEXT("", "845418CB4A780BE54969298B2A169E4E", "Static Mesh Options"),PinToolTip="Static Mesh Options\nDatasmith Static Mesh Import Options Structure\n\nStatic Mesh Options",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithStaticMeshImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="(MinLightmapResolution=LIGHTMAP_64,MaxLightmapResolution=LIGHTMAP_512)",AutogeneratedDefaultValue="(MinLightmapResolution=LIGHTMAP_64,MaxLightmapResolution=LIGHTMAP_512)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_17" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=576 NodePosY=3200 NodeGuid=D6B67186487A9D5C9CDEB0A01A5DA20C CustomProperties Pin (PinId=BA499A854090A91A595B95A1783495B9,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_18 37D9E7AE4BF50640081CE79EF2948C0B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=96527C1C46AE12EDC781DAB73B1C12A6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_18" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',MemberName="GetOptions") NodePosX=768 NodePosY=3056 NodeGuid=4DDEC2104E428B9B89B3C79376F110B0 CustomProperties Pin (PinId=7EF6D32C467BDF06A9BBA9A34D666E9D,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_3 82355F254E1B2E00A17100B7DA948B89,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9B2EB3D5471624E015192A8F41F3F145,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_4 105D64DD42D97018387B399290A08001,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=37D9E7AE4BF50640081CE79EF2948C0B,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nDatasmith Scene Element Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_17 BA499A854090A91A595B95A1783495B9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=61EE885748CEA00B590841A4D579F5DD,PinName="OptionType",PinToolTip="Option Type\nObject Class Reference",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,AutogeneratedDefaultValue="None",DefaultObject="/Script/DatasmithContent.DatasmithCommonTessellationOptions",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B35448E049BEAC47AF40B0A5A9361E35,PinName="ReturnValue",PinToolTip="Return Value\nDatasmith Common Tessellation Options Object Reference\n\nGet Options",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithContent.DatasmithCommonTessellationOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_4 C14FA89E41B81E97DC051289064126EE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_4" VariableReference=(MemberParent=Class'"/Script/DatasmithContent.DatasmithCommonTessellationOptions"',MemberName="Options") SelfContextInfo=NotSelfContext NodePosX=1104 NodePosY=3088 NodeGuid=E4AFCCF445291B33F6468E8B5A202E88 CustomProperties Pin (PinId=105D64DD42D97018387B399290A08001,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_18 9B2EB3D5471624E015192A8F41F3F145,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=24054A454E4B06BA550BEAAFED679E5A,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_19 3E94DE4147427B169E19D8A8C2BB214D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=964752F94DB2F6DAA6826CA797BF2F92,PinName="Options",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithTessellationOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MakeStruct_4 76BF0769438216689F4B388DBE9A89F7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C14FA89E41B81E97DC051289064126EE,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithContent.DatasmithCommonTessellationOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_18 B35448E049BEAC47AF40B0A5A9361E35,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D988F60942BE19E0AEEA1D8F34BB7BA3,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithTessellationOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MakeStruct Name="K2Node_MakeStruct_4" bMadeAfterOverridePinRemoval=True ShowPinForProperties(0)=(PropertyName="ChordTolerance",PropertyFriendlyName="Chord Tolerance",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithTessellationOptions:ChordTolerance", "Maximum distance between any generated triangle and the original surface. Smaller values make more triangles."),CategoryName="Geometry & Tessellation Options",bShowPin=True,bCanToggleVisibility=True) ShowPinForProperties(1)=(PropertyName="MaxEdgeLength",PropertyFriendlyName="Max Edge Length",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithTessellationOptions:MaxEdgeLength", "Maximum length of any edge in the generated triangles. Smaller values make more triangles."),CategoryName="Geometry & Tessellation Options",bShowPin=True,bCanToggleVisibility=True,bIsMarkedForAdvancedDisplay=True) ShowPinForProperties(2)=(PropertyName="NormalTolerance",PropertyFriendlyName="Normal Tolerance",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithTessellationOptions:NormalTolerance", "Maximum angle between adjacent triangles. Smaller values make more triangles."),CategoryName="Geometry & Tessellation Options",bShowPin=True,bCanToggleVisibility=True,bIsMarkedForAdvancedDisplay=True) ShowPinForProperties(3)=(PropertyName="StitchingTechnique",PropertyFriendlyName="Stitching Technique",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "DatasmithTessellationOptions:StitchingTechnique", "Stitching technique applied on model before tessellation. Sewing could impact number of objects."),CategoryName="Geometry & Tessellation Options",bShowPin=True,bCanToggleVisibility=True,bIsMarkedForAdvancedDisplay=True) StructType=ScriptStruct'"/Script/DatasmithContent.DatasmithTessellationOptions"' NodePosX=592 NodePosY=3264 AdvancedPinDisplay=Shown NodeGuid=385A83744F97E533E0BC44B43E360E94 CustomProperties Pin (PinId=76BF0769438216689F4B388DBE9A89F7,PinName="DatasmithTessellationOptions",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DatasmithContent.DatasmithTessellationOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_4 964752F94DB2F6DAA6826CA797BF2F92,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7164EA4941068E35C2E129974DEF3945,PinName="ChordTolerance",PinFriendlyName=NSLOCTEXT("", "96B74D8D451C57540492F79751A18557", "Chord Tolerance"),PinToolTip="Chord Tolerance\nFloat\n\nMaximum distance between any generated triangle and the original surface. Smaller values make more triangles.",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.100000",AutogeneratedDefaultValue="0.200000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=53F3E2EB4C5D2A16626CBF8EB8C41CF4,PinName="MaxEdgeLength",PinFriendlyName=NSLOCTEXT("", "A56318A14EA7BC0A0FDE0A98ABE3CF82", "Max Edge Length"),PinToolTip="Max Edge Length\nFloat\n\nMaximum length of any edge in the generated triangles. Smaller values make more triangles.",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.000000",AutogeneratedDefaultValue="0.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=4EEB5F4C40459DA0C26B5FA51EF33481,PinName="NormalTolerance",PinFriendlyName=NSLOCTEXT("", "4B38103646880A796B6F418DD98B09AC", "Normal Tolerance"),PinToolTip="Normal Tolerance\nFloat\n\nMaximum angle between adjacent triangles. Smaller values make more triangles.",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="30.000000",AutogeneratedDefaultValue="20.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=4E9862A84B06D606BFE24A8BF52AE046,PinName="StitchingTechnique",PinFriendlyName=NSLOCTEXT("", "CC28CC71411494CAE04748A04C26D75F", "Stitching Technique"),PinToolTip="Stitching Technique\nEDatasmithCADStitchingTechnique Enum\n\nStitching technique applied on model before tessellation. Sewing could impact number of objects.",PinType.PinCategory="byte",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Enum'"/Script/DatasmithContent.EDatasmithCADStitchingTechnique"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="StitchingSew",AutogeneratedDefaultValue="StitchingSew",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_5" VariableReference=(MemberName="DatasmithScene",MemberGuid=7BB429344E807635364604A23A589375,bSelfContext=True) NodePosX=1104 NodePosY=3216 NodeGuid=A07499AC47D06DB5267300B00EDEA2FA CustomProperties Pin (PinId=BA499A854090A91A595B95A1783495B9,PinName="DatasmithScene",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_19 554A38CE4D569BB4187E6EB90099DEA3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=96527C1C46AE12EDC781DAB73B1C12A6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=WidgetBlueprintGeneratedClass'"/Game/NewEditorUtilityWidgetBlueprint.NewEditorUtilityWidgetBlueprint_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_19" FunctionReference=(MemberParent=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',MemberName="GetOptions") NodePosX=1280 NodePosY=3056 NodeGuid=9C03863748F4CBBA846CBE8F927E5F26 CustomProperties Pin (PinId=3E94DE4147427B169E19D8A8C2BB214D,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_4 24054A454E4B06BA550BEAAFED679E5A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AE15C69240467C8640AAD3A6DC7729A7,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_5 A7922AA14B8E8AF188F91FAD279B1052,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=554A38CE4D569BB4187E6EB90099DEA3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nDatasmith Scene Element Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithImporter.DatasmithSceneElement"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_5 BA499A854090A91A595B95A1783495B9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EED75B2F4AE7228AF2A8C989EFE2C5E2,PinName="OptionType",PinToolTip="Option Type\nObject Class Reference",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,AutogeneratedDefaultValue="None",DefaultObject="/Script/DatasmithCADTranslator.DatasmithCADImportOptions",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BF95D0CC485F6B5B3F0B17B98F1B6B75,PinName="ReturnValue",PinToolTip="Return Value\nDatasmith CADImport Options Object Reference\n\nGet Options",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithCADTranslator.DatasmithCADImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_5 9F7304A743785054E5BD57A2939F792A,K2Node_Knot_6 B83566B940066C7C25AEE0B3DE804EF7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_5" VariableReference=(MemberParent=Class'"/Script/DatasmithCADTranslator.DatasmithCADImportOptions"',MemberName="NumThreads") SelfContextInfo=NotSelfContext NodePosX=1616 NodePosY=3056 NodeGuid=DDDB20514FB4F81EDC6DB3B34BE34712 CustomProperties Pin (PinId=A7922AA14B8E8AF188F91FAD279B1052,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_19 AE15C69240467C8640AAD3A6DC7729A7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CD996C23427FB7589948E6830572C5DD,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_6 2A1EBD9F4B78478D1D48DA9D13C07111,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EE8524D44D0AD726F1BC9EA0F86D8DA3,PinName="NumThreads",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="8",AutogeneratedDefaultValue="0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9F7304A743785054E5BD57A2939F792A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithCADTranslator.DatasmithCADImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_19 BF95D0CC485F6B5B3F0B17B98F1B6B75,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=63077A794991242FA6A059AAF1E1260E,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0",AutogeneratedDefaultValue="0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_6" VariableReference=(MemberParent=Class'"/Script/DatasmithCADTranslator.DatasmithCADImportOptions"',MemberName="UVGeneration") SelfContextInfo=NotSelfContext NodePosX=1840 NodePosY=3056 NodeGuid=A9A2CE624FBF01356067CC97E3A026F8 CustomProperties Pin (PinId=2A1EBD9F4B78478D1D48DA9D13C07111,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_5 CD996C23427FB7589948E6830572C5DD,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ABB0CB884CE621740FF41BADA8BC1C47,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A336E0B6426C0E989122098D8CD00075,PinName="UVGeneration",PinType.PinCategory="byte",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Enum'"/Script/DatasmithCADTranslator.ECADUVGeneration"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="Keep",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6E22CE1440B2A8F3E0FCA9B12359AC95,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithCADTranslator.DatasmithCADImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_7 4618A64448C69AC332742D88EF0C0083,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9FEAC9AD4CD32811C4D10AA37A503EA0,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="byte",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Enum'"/Script/DatasmithCADTranslator.ECADUVGeneration"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="Keep",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_6" NodePosX=1632 NodePosY=3200 NodeGuid=B456C313443CFF6B38A65A9E485BF161 CustomProperties Pin (PinId=B83566B940066C7C25AEE0B3DE804EF7,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithCADTranslator.DatasmithCADImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_19 BF95D0CC485F6B5B3F0B17B98F1B6B75,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A8C76D24466D996705D141985C5FE178,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithCADTranslator.DatasmithCADImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_7 0F8CBD4A4A02B6472ABA82A4DA6BFE9A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_7" NodePosX=1792 NodePosY=3200 NodeGuid=C935C45647E5246EC0FFDEA905A4A129 CustomProperties Pin (PinId=0F8CBD4A4A02B6472ABA82A4DA6BFE9A,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithCADTranslator.DatasmithCADImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_6 A8C76D24466D996705D141985C5FE178,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4618A64448C69AC332742D88EF0C0083,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/DatasmithCADTranslator.DatasmithCADImportOptions"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsArray=False,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableSet_6 6E22CE1440B2A8F3E0FCA9B12359AC95,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Click the top right of the image to copy the node graph.

If you want to use Python to customize the import process, your main starting point will be the unreal.DatasmithSceneElement class. This class offers you all the functions you need to construct a scene from a file, work with the elements in that scene (through the functions defined in the base unreal.DatasmithSceneElementBase class), and finalize the import.

Importing a .udatasmith File

Importing a CAD File

Accessing Import Options

When you work with different types of Datasmith source files, the only difference in the API is that different types of files give you different options for controlling the import operation.

For .udatasmith files, the first example above shows how you can access a DatasmithImportOptions object that provides access to destination Asset and path names, what types of data you want to import, lightmap resolution settings, and so on. This works for all types of files you can import with Datasmith.

For CAD files, the second example shows how you can also access a DatasmithCommonTessellationOptions object that controls the settings used in the tessellation process, and a DatasmithCADImportOptions object that offers access to other internal debug settings that you may find useful.

Other file types supported by Datasmith encapsulate their import settings in other classes, such as DatasmithC4DImportOptions for Cinema 4D.

Apart from accessing these import options, the rest of the scripts for working with the Datasmith Scene and the elements inside the scene are exactly the same.

For more detail on these import option classes and the settings they offer, see their entries in the Python API Reference or the Blueprint API Reference.

When you call DatasmithSceneElement.get_options() in Python or use the Get Options node in Blueprint, if you specify a class of Datasmith options that doesn't apply to the type of source file you've constructed, you'll get a null return. In Python, you can test for a None return. In Blueprint, you can pass the returned value to the Utilities > IsValid node to check that it's a valid instance of the class you requested.

As an alternative to using DatasmithSceneElement.get_options() in Python or Datasmith > Scene > Get Options in Blueprint, you can use DatasmithSceneElement.get_all_options() or Datasmith > Scene > Get All Options to retrieve all classes of options for the Datasmith scene that you've constructed in a single map. The key value of each entry in the map is a class of options owned by the Datasmith Scene Element that you constructed from your file, and the value of the entry is the instance of that class owned by the Datasmith Scene Element. If you don't know what kind of file your script will be handling, and therefore what kinds of option classes the DatasmithSceneElement should contain, you can use this approach to retrieve them all and iterate through them.

About the Datasmith Scene

In order to explore what you're able to do with the Datasmith scene during the pre-import phase, it helps to know a little about how the scene is constructed.

Scene Contents

A Datasmith Scene is mostly a container for different types of elements. Each of these elements represents either an Asset that will be created in your Content Browser after import, or an Actor that will be spawned in your Level with its own particular transform in 3D space.

The main asset element types include:

Meshes: Each mesh element represents a block of 3D geometry. When you complete the import, each mesh element ends up as a separate Static Mesh object under the Geometry folder. Each mesh element has a number of material slots, each of which is associated by name with material elements.

Materials: Each material element represents a distinct type of surface that is needed for your geometries. When you complete the import, each material element ends up as a separate Material object under the Materials folder.

Textures: Each texture element represents a single 2D image that is used by at least one of your Materials. When you complete the import, each texture element ends up as a separate Texture object under the Textures folder.

The main actor element types include:

Mesh actors: Each mesh actor element represents an instance of a mesh geometry in your Level. When you complete the import, each mesh actor element ends up as a Static Mesh Actor in your World Outliner.

Light actors: Each light actor element represents a light emitter in your scene. When you complete the import, each light actor element ends up in your Level as an instance of a base Unreal light type, such as a Point Light or Spot Light, or as a custom Datasmith Actor that simulates an Area light. You can get and set a number of properties on these lights, such as their intensity, color, IES profile texture files, and so on.

Camera actors: Each camera represents a point of view that is set up in your source scene. When you complete the import, each camera actor element ends up in your Level as a CineCameraActor. You can get and set some basic properties on these camera actors, such as their aspect ratios.

The data contained in the Datasmith Scene in memory is very similar to what you see in a .udatasmith file if you open it up. If you're using 3ds Max or Sketchup, you can open any exported .udatasmith file to get an idea of how the Datasmith Scene object is constructed:



Working with the Datasmith Scene

You'll mainly interact with the Datasmith Scene in order to retrieve lists of the elements outlined above. To do this in Python, you'll use the functions defined in the DatasmithSceneElementBase class that your DatasmithSceneElement derives from. In Blueprint, you'll use the Datasmith > Scene nodes as shown in the examples above.

Once you have a list of elements, you can iterate through the list to retrieve a particular element. Then, use the Python API for that element (such as DatasmithMeshActorElement), or the Datasmith > Element nodes in Blueprint, to get and set information about that particular element. If your element is an Actor type, you can also get its child actor elements, which lets you browse downward through the scene hierarchy.

If you want to remove existing elements from the scene (as shown in the examples above), or add new elements, you can also do this through the functions exposed in the same places. For example, you could re-shuffle the hierarchy of Actors by removing them and re-adding them under different parents, using functions exposed by your DatasmithSceneElement class in Python, or nodes from the Datasmith > Scene category in Blueprint.

Material Instance Editor UI

Instanced Materials

Steps

End Result

As described in Datasmith Overview and Datasmith Import Process, Datasmith creates a Material Instance in your Project to represent each different type of surface that it detects in your source scene. Each of these Material Instances exposes a pre-set list of properties, which you can modify freely in your Unreal Engine Project.

However, if you want to modify the Master Material that any of your Datasmith Material Instances are based on, always create a duplicate of the original Master Material, save that duplicate in your Project content, make your changes in the duplicate, then set the Material Instance to point to your duplicate Master Material.

The instructions below on this page provide step-by-step instructions for doing so.

The pre-set Parent Material Assets used by Datasmith — such as the Datasmith_Color, SketchUpMaster, and RevitMaster Materials — are included in the Datasmith Plugin content. If you make any changes to these Parent Materials, you'll be changing them for all your Projects, not just for your current Project. And your changes won't be saved in your Project, so if you have to distribute your Project to someone else, or upgrade to a new version of Unreal Engine, you'll lose those changes. Always make a duplicate inside your Project's content folder.

Even when you're working with a Parent Material created by Datasmith inside your Project's content folder — typically, a Parent Material created for a custom-designed Material imported from 3ds Max or Rhino — you should always follow this same procedure to create a duplicate of the original Parent Material instead of modifying the original Parent Material directly. Changes to Parent Material graphs are not preserved as Datasmith overrides, so your changes would be lost the next time you reimport your Datasmith Scene Asset.

Steps

To duplicate and modify the Parent Material for any Material Instance created by Datasmith:

Double-click the Material Instance whose Parent Material you want to modify. This opens the Material Instance in the Material Instance Editor.

In the Details panel, find the General > Parent setting. This identifies the Parent Material that provides the Material Graph that this Material Instance is based on.



Click image for full size.

Double-click the thumbnail image for the Parent.



Click image for full size.

This opens the Parent Material in the Material Editor, where you can see its Material graph.

You can also use the Hierarchy button in the Toolbar to choose and open the Parent Material.



Click image for full size.

From the main menu of the Parent's Material Editor, select File > Save As, and save a copy of the Parent Material anywhere in your Project's content folder.



Click image for full size.

Go back to your Material Instance, and change the General > Parent setting to point to your newly created Master Material.



Click image for full size.

Save the Material Instance.

End Result

You've created a new Parent Material that duplicates the default Parent Material assigned by Datasmith, and you've assigned that new Parent Material to your Material Instance. Now, any changes you make to the graph and settings in your duplicated Master Material will immediately apply to your Material Instance. And, the next time you reimport your Datasmith Scene Asset, you won't lose any of the changes you made in your duplicated Parent Material.

Get Started

Tutorials

Reference

When Datasmith imports a scene into Unreal Engine, it does its best to preserve the geometry, materials, and scene hierarchy that you created in your source application. However, when you build 3D models in specialized applications for purposes other than real-time rendering, the scenes are often not prepared in a way that makes sense for a real-time rendering engine like Unreal. For example, this is often the case for models you create in applications like Rhino for the primary purpose of manufacturing or extruding physical parts, scenes you create in Revit or an IFC-compliant application for the primary purpose of documenting a construction project, scenes you create with procedurally generated elements in Cinema 4D, and so on.

You can always import the raw scene data, then make use of the tools offered by Unreal Editor to adjust your Assets and Actors after the import is complete. However, this has some limitations. For example, you may need to repeat these steps when you reimport the scene to pick up changes made in the source application or when you reimport a different scene with the same settings.

You can use the Visual Dataprep system to create reusable import "recipes" that reorganize, clean, merge, and modify scene elements before creating the final Assets and Actors in your Unreal Engine Project. You can create a recipe once, then reuse it each time you need to import a scene. You can also reuse the same recipe to import different source files, and even reuse it across different Projects. This effectively allows you to create your own standardized set of Asset import pipelines that match the needs of your content.

With the Visual Dataprep system, you can build common data preparation tasks like these into the import process:

Replacing Materials used in your source scene with high-quality Materials made specifically for real-time visualization.

Identifying unnecessary geometry and removing it from the scene.

Merging geometry together to reduce the number of separate objects in the scene.

Creating Levels of Detail to render complex geometry more efficiently.

Creating collisions for Objects that need collision meshes to work in your runtime experience, such as floors and walls.

As you get started with Visual Dataprep, you will discover some other operations that you can use to prepare reusable dataprep recipes for real-time scenes.

Get Started



Overview of the Dataprep system and how it works.

Tutorials



How to create parent Dataprep recipes that expose limited customization parameters to Dataprep Instances.



How to create your own custom filters and operators for the Dataprep system in Blueprint.

Reference



Details on the ways you can filter and select scene elements in Dataprep steps.



Details on the operations you can apply to selected scene elements in the Dataprep system.



Details on ways you can transform the list of objects you want to modify in the Dataprep system.

Enabling Visual Dataprep

Visual Dataprep Assets

Dataprep Editor UI

Dataprep Workflow

Statistics Panel

Dataprep Graphs

Operations, Filters, and Transforms

Action Example

Working with Filters

Creating a Filter from Selected Assets

Inverting Filter Logic

Previewing Filter Results

This page provides an overview of the Visual Dataprep system, and how to get started creating your own custom import recipes to prepare your 3D data for real-time visualization.

Enabling Visual Dataprep

Enable the following plugins for your Project:

DataPrep Editor

Datasmith Importer

Dataprep Geometry Operations - This plugin is required for certain filters and operations.

If you want to import from other kinds of source files that Datasmith supports, you may need to enable other importer plugins for those file types. For details, see Importing Datasmith Content into Unreal Engine.

To learn how to enable plugins, refer to the Working with Plugins page.

If you started your Unreal Project from a Template in the Architecture, Engineering, and Construction or Automotive, Product Design, and Manufacturing categories, some of these Plugins may already be enabled.

Visual Dataprep Assets

The Visual Dataprep system is based around a new kind of Asset, called a Dataprep Asset. This Asset is like a Blueprint in that it lays out a series of steps in a visual representation. However, the purpose of this Dataprep graph is to transform scene data read from one or more input files that you specify.

To create a new Dataprep Asset, right-click in the Content Browser and choose Dataprep > Dataprep Asset from the context menu.



Click image for full size.

Dataprep Editor UI

Like Blueprint classes, Dataprep Assets have their own specialized editor window. You can open this window by double-clicking any Dataprep Asset in the Content Browser.

The Dataprep Editor UI is divided into several panels, which you'll use at different points in the Dataprep workflow.



Click image for full size.

Number

Name

Description

1

Toolbar

Shortcuts for the most important user actions in the Dataprep workflow, including the Import, Execute, and Commit actions.

2

Content Browser Preview

Lists all Assets you have imported from your input files. This is a preview of the Assets that the Visual Dataprep system will create in your Content Browser when you Commit your graph.

3

Viewport Preview

Displays a visual preview of the 3D scenes you have imported from your input files.

4

Outliner Preview

Lists all Actors in the 3D scenes you have imported from your input files. This is a preview of the Actors the Visual Dataprep system will create in your Level, and the scene hierarchy that will be created in your Level's Outliner.

5

Settings Panel

Use this panel to specify the input files you want to import your 3D scenes from, and where you want the Assets to be created in your Project's Content Browser.

If you've exposed any parameters in your Dataprep graph so that they can be overridden in instances of your Dataprep Asset, you'll also see those parameters listed here in the Parameterization section. For details, see Working With Dataprep Instances.

6

Palette

Offers building blocks that you can drag into the Dataprep Graph Editor to build up your import recipe.

7

Dataprep Graph Editor

Area where you can prepare Dataprep recipes, which are left-to-right steps that you want the Dataprep system to take to prepare your input content for real-time visualization in Unreal Engine.

8

Details Panel

Like the Details panel in the main Level Editor, shows information about any Actor that you have selected in the Outliner Preview. Note that these settings are read-only. They are provided only for your information so you can evaluate the effects of your Dataprep Graph on your Actors.

Dataprep Workflow

The typical workflow for setting up a Visual Dataprep asset follows these steps:

Specify input files: In the Settings Panel at the top right, create a new input producer for each file you want to import, or each folder of input files. Click the gear icon to configure additional geometry and tessellation options, such as Chord Tolerance and Stitching Technique.



Click image for full size.

You can also customize the following Output settings:

Folder determines the name of the folder that will be created in your Project's Content Browser to hold your imported Assets. By default, your Assets are distributed by Datasmith into subfolders within this folder according to their type: one for Static Mesh Assets, one for Materials, one for Textures, and so on. (You can override this default distribution when you build your Dataprep graph, by using the Output to Folder operation.)

Level Name sets the name of a new Level Asset that will be created to hold your scene. After you commit the results of the Dataprep graph, you'll be able to add the imported scene into any Level in your Project by adding that sublevel.

Preliminary import: Press the Import button in the Toolbar to import your source files into a temporary world.

You'll see the 3D viewport and other preview panels update with the content read from your file. This content has not yet been added to your Project. It is in a temporary world that only exists in the Dataprep Editor. This gives you an opportunity to modify the Assets and scene hierarchy read from your input files before you save the results to your Project.

This step is technically optional, but it makes it easier for you to evaluate the effects of your Dataprep Graph as you build it.

Build the Dataprep Graph: Drag Select By and Operations nodes from the Palette into the Dataprep Graph Editor, and connect your Action nodes in the order you want them to be carried out. See Dataprep Graphs below.

Test the Graph: Press the Execute button in the Toolbar to run the data you've imported from your source files through the Dataprep Graph you've built. You'll see the preview panels update to show the results.

Individual blocks or Action nodes can be disabled for debugging by right clicking on the name and choosing the Disable option. A disabled block or Action will be grayed out in the graph. They may be enabled by opening the menu again and choosing the Enable option.

Commit: When you're happy with the effects of your graph on the 3D data imported from your input files, press the Commit button in the Toolbar to finalize the import process.

When you commit the results, the Visual Dataprep system saves the Assets in the Content Browser Preview into Assets in your Project. It also modifies the Level that you currently have open to add the hierarchy of Actors shown in the Outliner Preview.

If you prefer to import your Actor hierarchy into a new Level instead, set the name of the Level in the Sub-Level setting in the Settings panel. The Visual Dataprep system will create a new Level with this name (if it does not already exist), add your Actors to that Level, then add that Level as a sublevel within the Level that you currently have open in the main window of the Unreal Editor.

Statistics Panel

Open the Statistics panel from the main menu of the Visual Dataprep asset editor: Window > Statistics. This panel shows a simple comparison of your data's metrics, such as draw calls, number of Actors, or total vertex count, before and after executing the Dataprep Graph.



Click image for full size.

Dataprep Graphs

At the heart of every Dataprep Asset is the Dataprep Graph—the set of operations that the system will carry out on the input files you specify.



Click image for full size.

Every Dataprep Graph is made up of building blocks called Action nodes: vertical stacks of blocks. For example, the graph shown above contains three Action nodes. When you execute the Dataprep graph, it starts at the Start node on the left, then performs each Action node in order, from left to right.

You can resize Actions horizontally to read their full text by dragging their boundaries.



Unlike Blueprint graphs, where conditional branching is allowed, Dataprep graphs always progress from left to right, along a single linear execution path. In addition, there is no data flow between successive Action nodes. All Actions use the same context—a set of Assets and Actors that are imported from input files you provide.

Each Action is a stack of one or more blocks. When the Dataprep graph performs an Action, it treats each block in the Action node from top to bottom.

To start building an Action, you can drag blocks from the palette on the left into the graph editor, or right-click in the background of the graph editor and select blocks from the context palette.

You can group multiple Actions together. To do this:

Click and drag to select the Actions you want to group.

Right-click the group.

From the context menu, select Group Actions.

You can disable all the Actions in an Action Group by right-clicking the group and selecting Disable Action Group from the context menu.

To ungroup Actions, right-click the group, then select Ungroup Actions.

Operations, Filters, and Transforms

There are three basic types of blocks you can use in a Dataprep Action node:

Operations modify Assets, Actors, or Components in some predefined way. For example, the Set Material, Compact Scene Graph, and Set Simple Collision blocks shown above are all different types of operations.

For details on all the different operations you can use in your Dataprep graphs, see Dataprep Operation Reference.

Filters, also called Select By blocks, determine what Assets, Actors, and Components the operations under them in the current Action block should modify. By default, every Action step performs its operations on all Assets, Actors, and Components contained in the temporary world constructed from your input files. You can use these Filter blocks to define a subset of those objects, thereby controlling the objects your Action node will modify.

For details on all the different selection filters you can use in your Dataprep graphs, see Dataprep Selection Reference.

Transforms alter the current selection of Assets, Actors, and Components in potentially complex ways. In this respect, they are like filters. However, a filter block can only cut down the list of objects passed down to it. A transform block, by contrast, can add objects to the current selection.

For example, you might want to select specific trees of objects from the scene hierarchy. To do this, you could use filter blocks to narrow down the full set of scene elements to a small number of specific parent elements, then use a transform block to re-expand that selection to include the children of the selected elements.

For details on all the different transforms you can use to extend or modify the selected set of objects within an Action, see Dataprep Selection Transform Reference.

Action Example

The Action pictured below sets a new Material on the parts of a CAD assembly. This node performs a sequence of steps, processing data through its stack of filters and operations, from top to bottom.



Click image for full size.

Step Number

Name

Block Type

Description

1

Input Pin

N/A

Every Action gathers all data from the temporary world, including all Assets and Actors found in the imported files, and passes those objects to the block at the top of the stack.

2

Filter by Tag

Filter

This filter only keeps Actors that have the "Metal" tag, passing that list of Actors to the next block down.

3

Filter by Actor Label

Filter

This filter only keeps Actors whose names contain the word "Mechanical", passing those on to the next block down.

4

Set Simple Collision

Operator

This operator sets up a Box collision shape on all Static Mesh Assets that are referred to by the set of Actors passed down by the filters above. It then passes the same list of Actors on to the next block down.

5

Set Material

Operator

The last operator finds all Materials on all Static Mesh Components owned by the set of Actors passed down by the filters above, and replaces those Materials with the substitute specified in the Material setting in the block.

After all blocks in this Action are done, the next Action in the graph begins executing. When the next Action starts, it once again gathers all data from the temporary world. All filters put in place by previous blocks are no longer considered. However, any changes made to the scene by previous Actions persist for the next Action—such as changing Materials, deleting Actors, and so on.

Working with Filters

All filter blocks offer some additional options that make it easier for you to capture the exact list of Assets, Actors, and Components that you want to modify with your operation blocks, and to verify that your filters are having the effect you're expecting.

To access these options, right-click any filter block and look for the Filter section in the context menu.



Click image for full size.

If you want to affect multiple filter blocks, hold down the Control key and left-click all the blocks to build your selection. When all the blocks you want to affect are highlighted, right-click any highlighted block. Alternatively, click and drag to select multiple blocks.

Creating a Filter from Selected Assets

With one or more Actors or Components selected from the Viewport, Outliner, or Asset panel, right-click anywhere in the Dataprep Graph Editor and, from the context menu, select Create Filter From Selection.



Click image for full size.

The new filter shows the number of Actors and Assets that will be selected, as well as the first Actors or Assets in the list.

You cannot edit this list directly, but you can create a new filter that includes this one by doing the following:

Right-click the Filter by Selection filter in the Dataprep Recipe.

From the context menu, select Preview Filter(s). This will highlight the Actors and Assets in the World Outliner Preview panel that this filter selects.

To add new Actors and Assets to the filter, hold the Ctrl key and click them in the World Outliner Preview panel.

Right-click anywhere in the Dataprep Graph Editor and, from the context menu, select Create Filter from Selection.

Inverting Filter Logic

Choose Filter > Inverse Filter(s) Selection to reverse the selection logic of any Select By block, turning it into an Exclude By block. When you do this, the operations in the same Action will apply only to the set of scene elements that do not match the criteria you set.

Previewing Filter Results

Choose Filter > Preview Filter(s) to make the Content Browser Preview and the World Outliner Preview panels show a checkmark next to all the Assets and Actors that are selected by your filter.



Click image for full size.

You can only preview one filter, or one selected set of filters, at a time. If you start previewing a different filter or a different set of filters, your previous filters will stop previewing.

Exposing Parameters in a Parent Dataprep Asset

Creating a Dataprep Instance Asset

Setting Up the Dataprep Instance Asset

In the Visual Dataprep system, your Dataprep Assets provide reusable recipes that help you be consistent about how you import and modify 3D data. The Dataprep graph provides a high level of flexibility and power; you can use it to manipulate your data in whatever way you need to make your imported scenes work well at runtime in Unreal Engine.

Sometimes, depending on what tasks you need your Dataprep graph to carry out, you may need to make adjustments in order to work with different input scenes or assets. For example, a new set of input data may use a different naming convention for objects or surfaces, and you may need to change settings in your graph to match. You can always modify your Dataprep Asset graph to handle these new situations. However, Dataprep graphs can be large and complex, and in larger organizations the person who needs to import content might not be the same person who created the graph. In cases like this, it may not always be clear what settings need to be changed.

To make these kinds of situations easier, you can select important settings in your Dataprep graph and expose them as parameters, with descriptive names that you choose. When anyone edits the Dataprep Asset, these exposed parameters show up in a special Parameterization area within the Settings panel at the upper right of the Dataprep Editor. This effectively highlights selected settings that other users might need to customize most often.

In addition, you can create a Dataprep Instance that allows users to only modify the parameters you have chosen to expose, but that prevents them from touching the rest of the Dataprep graph. By judiciously exposing the right settings in your Dataprep Assets and creating Dataprep Instances from them, you can give users in your organization the freedom they need to modify pre-selected settings, without requiring them to modify or even see the actual logic of the Dataprep graph itself.

If you're familiar with the way you work with Materials and Material Instances in the Unreal Engine, the concept of the Dataprep Asset and the Dataprep Instance is exactly analogous.

Exposing Parameters in a Parent Dataprep Asset

To expose settings in a Dataprep Asset so that they can be customized as parameters and overridden in Dataprep Instances:

Set up your Dataprep graph the way you want it.

Right-click the setting you want to expose. In the context menu, under the Parameterization section, click Link to Parameter.



Click image for full size.

You can expose any setting in any type of Dataprep blocks: filter blocks, operator blocks, and transform blocks.

In the text box provided, enter a descriptive name you want to use to refer to the parameter. When the name is the way you want it, click Create New Parameter under the text box.



Click image for full size.

The setting you chose is marked in the Dataprep graph with a link icon, to mark that it has been exposed for customization. You can hover over this icon to see the name of the parameter that corresponds to this setting.



Click image for full size.

The new parameter you created also shows up in the Parameterization section of the Settings panel at the top right of the Dataprep Editor.



Click image for full size.

Modifying the value of the setting in either the block or the Settings panel modifies it in both places.

Your setting is now editable in any Dataprep Instance you create from this Dataprep Asset, under the parameter name you set. See the following sections for details.

If you want to remove the parameterization on a setting so that it can no longer be changed in any Instances of this Dataprep Asset, right-click the setting again and choose Remove Link to Parameter.

You can link multiple settings on different Dataprep blocks to a single named parameter. If different parts of your Dataprep graph rely on the same threshold values or string names, reusing a parameter to drive multiple different block settings can help reduce the number of parameters you expose to your Dataprep Instances.

Creating a Dataprep Instance Asset

You can create a Dataprep Instance Asset from any Dataprep Asset. Right-click the Dataprep Asset in the Content Browser, and in the context menu click Create Instance.



Click image for full size.

Your new Dataprep Instance Asset is created in the same folder as its parent. You can assign it a name and double-click it to open it up in the Dataprep Instance Editor to configure the values of its exposed parameters.

Setting Up the Dataprep Instance Asset

When you edit a Dataprep Instance Asset, it opens in an editor that contains most of the same panels visible in the main Dataprep Editor.



Click image for full size.

The main difference is that the graph editor is completely missing. In a Dataprep Instance, you can't modify or even see the recipe that the Dataprep Instance will use to modify the scenes you import. Instead, you only have access to the settings that have been exposed in the parent Dataprep Asset, in the Parameterization section of the Settings panel at the top right of the editor.

Otherwise, working in the Dataprep Instance Editor is very similar to working in the Dataprep Editor:

Use the Settings panel to customize input files and output locations.

Use the buttons in the Toolbar to Import the input files, Execute the Dataprep graph, and Commit the results to your Unreal Engine Project.

Use the preview panels to interact with your imported data and make sure that it looks the way you are expecting before you commit the results.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Dataprep Overview

How to Create a Custom Dataprep Block

Base Classes

Variables and Settings

Creating a Custom Filter

Creating a Custom Operation

The Dataprep Context

Operations and Editing Operations

Operation Examples

Distributing Static Mesh Actors

Adding Objects to a Layer

The Visual Dataprep system comes with dozens of ready-made filters and operations to handle many of the most common needs for preparing 3D data for real-time visualization. However, no pre-set list of filters and operations could exhaustively support every operation you might need to carry out. If you need your Dataprep graph to do something that is available in the Unreal Editor's scripting system, but that none of the ready-made Dataprep blocks will do for you, you can create your own custom filter or operator to do exactly what you need.

This page describes how to create new filters and operators for your Dataprep graphs.

To use the Dataprep operations in Blueprints, enable the Dataprep Editor plugin. For more information on plugins, see Working with Plugins.

How to Create a Custom Dataprep Block

The overall process is the same for all different types of Dataprep blocks.

Create a new Blueprint class by right-clicking in the Content Browser and selecting Blueprint Class. For details, see Creating Blueprint Classes.

In the Pick Parent Class dialog, expand the All Classes list at the bottom. Choose the base class that corresponds to the type of block you want to create, and click Select. See the table of Base Classes below for the list of Dataprep parent classes you can choose from.



Click for full image.

Rename your new class in the Content Browser if desired.

Double-click your new class to open it in the Blueprint Editor.

Override the functions that your class inherits from its parent class. By overriding functions, you can customize the behavior of the dataprep block when the graph gets executed. To override a function, hover over the Functions category in the My Blueprint panel. Click the Override drop-down that appears, then choose the function you want to override.



Compile and Save your Blueprint class.

The next time you open a Dataprep Asset, you should see your new node added to the palette to the left of the graph editor.

Base Classes

Use one of the following base classes as the parent class for your custom Dataprep block:

Class

Description

DataprepBoolFetcher

Use this class if you want to implement a filter that selects objects if it determines that a certain condition is true.

DataprepFloatFetcher

Use this class if you want to implement a filter that selects objects based on a floating-point numeric property: that is, a number that can have a decimal component.

DataprepIntegerFetcher

Use this class if you want to implement a filter that selects objects based on an integral numeric property: that is, a whole number with no decimal component.

DataprepStringFetcher

Use this class if you want to implement a filter that selects objects based on a string property.

DataprepOperation

Use this class if you want to implement an operator that makes modifications to Actors or Assets.

DataprepEditingOperation

Use this class if you want to implement an operator that makes modifications to Actors or Assets, and that may add or remove Actors and Assets.

Variables and Settings

Any variables that you make publicly visible in your Blueprint class will be exposed as customizable settings in the Dataprep editor for every block of this type. You can use this mechanism to offer Dataprep graph designers the ability to customize the way your function operates.

For example, this operator class contains some publicly visible variables, marked with the open eye icons:



When this type of block is used in a Dataprep graph, those publicly visible variables are exposed as customizable settings:



Note in the example above that the HiddenTextVariable and HiddenVectorVariable are not exposed as settings on the Dataprep block, because they are not marked as public in the Blueprint class. Note also that the settings in the block respect the default settings you set for the variables in the Blueprint class.

Creating a Custom Filter

When you create a custom filter, you can override any or all of the following functions:

Function

Description

Fetch

When you execute a Dataprep graph, and it treats a filter block of this type, it calls this function for each object in the current context.

This function is expected to evaluate the object passed in to the Fetch function to produce an item of information of a specific type: a Boolean value, integer, float, or string. The filter node is responsible for conducting the logic to decide whether the item of information you return satisfies the logical condition expressed in the graph settings: for example, whether an integer you return is greater than or less than a value set by the user in the block, whether a string you return matches or is contained within the string set by the user in the block, and so on.

This function should also return a Boolean value to indicate whether it was successfully able to calculate an output value for the current object. If you return a false value in this Boolean, the filter will exclude the current object.

Get Additional Keyword

The Dataprep Editor calls this function to get a list of keywords for this block. If the user enters one of the keywords returned by your function into the search filter at the top of the palette, the editor will include this block in the list of matching items, even if the user's keyword does not occur in the name of the block.

Get Display Fetcher Name

The Dataprep Editor calls this function to get the display name that it should show in the palette for this block.

Get Node Display Fetcher Name

The Dataprep Editor calls this function to get the display name that it should show in the actual Dataprep graph for every block of this type.

Get Tooltip Text

The Dataprep Editor calls this function to get the text it should show in the tooltip when the user hovers the mouse over the name of this block in the palette, or over a block of this type in the Dataprep graph.

You must override the Fetch function in order for your filter to have any effect. The other functions are optional, but strongly recommended to control the way your block appears in the Dataprep Editor palette.

Creating a Custom Operation

When you create a custom operation, you can override any or all of the following functions:

Function

Description

Get Additional Keyword

The Dataprep Editor calls this function to get a list of keywords for this block. If the user enters one of the keywords returned by your function into the search filter at the top of the palette, the editor will include this block in the list of matching items, even if the user's keyword does not occur in the name of the block.

Get Category

The Dataprep Editor calls this function to determine what subcategory this block should be placed under in the palette, under the Operations list.

If you don't override this function, your operation block will be listed under the User-defined category.

Get Display Operation Name

The Dataprep Editor calls this function to get the display name that it should show in the palette for this block, and the display name that it should show in the actual Dataprep graph for every block of this type.

Get Tooltip

The Dataprep Editor calls this function to get the text it should show in the tooltip when the user hovers the mouse over the name of this block in the palette, or over a block of this type in the Dataprep graph.

On Execution

When you execute a Dataprep graph, and it treats an operation block of this type, it calls this function to carry out the modifications on the imported Assets and Actors. By creating a graph of Blueprint nodes downstream from this event, you can control what your operation does to the list of Assets and Actors that are passed in to it by the previous block in the Action.

See the following sections for details on how to implement your graph.

You must override the Event On Execution event in order for your operation to have any effect. The functions are all optional, but strongly recommended to control the way your block appears in the Dataprep Editor palette.

The Dataprep Context

When the Dataprep system triggers the On Execution event for an operation block while executing a Dataprep graph, it passes in a context object for you to use in your Blueprint graph. This is essentially a list of all the Actors and Assets that your operator can modify. If your operation block is above any filter blocks in its Dataprep Action, this context object will contain all the Assets and Actors that you've imported into the Dataprep world. Otherwise, the context object will contain all the Actors and Assets that have been chosen by the filters above the operation block in the current Dataprep Action.

You can use the Break DataprepContext node to get an array of objects from the context. You can then modify all the objects in the context, or you can narrow down the objects to ones that match a specific type.



Click for full image.

For example, the operation above modifies a setting that is only present on Static Mesh Assets, but not on any other kinds of objects that might be contained in the Dataprep context (like Actors, Texture Assets, or Material Assets). So, it loops through the array of objects in the context, casting each to a Static Mesh. It then makes the modification only if the cast succeeds.

Operations and Editing Operations

There are two parent classes for operator blocks: DataprepOperation and DataprepEditingOperation. Which one you should use depends on the editing operation you need to carry out. If you only need to modify objects that are already contained in the Dataprep context, you can use the DataprepOperation as your parent class. If you need to create new objects—for example, to create Assets in the Content Browser, to spawn new Actors in the Level, or to modify the list of list of objects in the Dataprep context—you must use DataprepEditingOperation as your base class.

When you derive your class from DataprepEditingOperation, you will have access to additional specialized functions in the Blueprint Editor, under the Dataprep > Editing Operations category:



For example, you can use Add Asset to add an Asset to the Dataprep context so that it will be included in the Dataprep context that is passed on to other blocks in the same Dataprep Action.

Always use the functions in the Dataprep > Editing Operations category to carry out actions whenever possible, instead of other nodes that may serve a similar purpose in normal circumstances. The temporary world that the Dataprep system uses to maintain all your imported data is unique; you can only modify it through these functions.

For example, always use the Dataprep > Editing Operations > Create Actor node to spawn a new Actor instead of the typical Editor Scripting > Level Utility > Spawn Actor from Class or Spawn Actor from Object.

Operation Examples

The following implementation of the On Execution event finds all Static Mesh Actors in the context, and redistributes them in space into a grid. The minima and maxima of the grid are taken from variables named Min and Max. These are marked as publicly editable, so they show up as a setting on the block in the Dataprep graph. However, the Actors variable, which is used to store the array of Static Mesh Actors in the scene, is not marked as editable. Therefore, it does not show up in the block on the Dataprep graph.





Begin Object Class=/Script/BlueprintGraph.K2Node_Event Name="K2Node_Event_0" EventReference=(MemberParent=Class'"/Script/DataprepCore.DataprepOperation"',MemberName="OnExecution") bOverrideFunction=True NodePosX=-128 NodePosY=64 NodeGuid=00C23D684C34092D3F8D32A9A8919C6D CustomProperties Pin (PinId=B6B9C1DC47B87824ED65A1A7E1F050D3,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=Class'"/Script/DataprepCore.DataprepOperation"',MemberName="OnExecution"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7966201F44B98504D944FAA610535AA8,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallArrayFunction_1 71F1EA8B408DC625F0ED37B53017AE05,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9855863E40834399DBE2FF8731616591,PinName="InContext",PinToolTip="In Context\nDataprep Context Structure (by ref)\n\nThe context contains the data that the operation should operate on.",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DataprepCore.DataprepContext"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_BreakStruct_0 ADDC769348068C1D93EFB5B89E22E974,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_BreakStruct Name="K2Node_BreakStruct_0" bMadeAfterOverridePinRemoval=True ShowPinForProperties(0)=(PropertyName="Objects",PropertyFriendlyName="Objects",PropertyTooltip="This is the objects on which an operation can operate",CategoryName="Dataprep",bShowPin=True,bCanToggleVisibility=True) StructType=ScriptStruct'"/Script/DataprepCore.DataprepContext"' NodePosX=160 NodePosY=112 NodeGuid=01B37EC349DF63F76785E39BE0C493B4 CustomProperties Pin (PinId=ADDC769348068C1D93EFB5B89E22E974,PinName="DataprepContext",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DataprepCore.DataprepContext"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Event_0 9855863E40834399DBE2FF8731616591,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=06FF21674E369A75117CEF894CC667D1,PinName="Objects",PinFriendlyName="Objects",PinToolTip="Objects\nArray of Object References\n\nThis is the objects on which an operation can operate",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 31BAEA4A425895588B2CE3A995EC9E0F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_0" MacroGraphReference=(MacroGraph=EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForEachLoop"',GraphBlueprint=Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=99DBFD5540A796041F72A5A9DA655026) ResolvedWildcardType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',ContainerType=Array) NodePosX=416 NodeGuid=038E437440773764692B84B24966A2F1 CustomProperties Pin (PinId=494953294EE1E71073A595B79ACCF5F1,PinName="Exec",PinType.PinCategory="Exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallArrayFunction_1 85FB3E7E4D2DBDAF8664719956E2BC38,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=31BAEA4A425895588B2CE3A995EC9E0F,PinName="Array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_BreakStruct_0 06FF21674E369A75117CEF894CC667D1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7ED535AB4919DD7B1D9805B62645EEE4,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="Exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_DynamicCast_0 6E42D51B400E7F8BE62C6186DD47F42E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A57E0444E24F32D27C4B48B3DAB787D,PinName="Array Element",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_DynamicCast_0 1C574FB64C931CA46706D2B880EDAFE7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6EBAA6034194BE364185EE9DA9E20804,PinName="Array Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=265F263247305123B1D06BAD4BB8DB46,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="Exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_0 E696487B41250450B13D76B1AADB3C43,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_DynamicCast Name="K2Node_DynamicCast_0" TargetType=Class'"/Script/Engine.StaticMeshActor"' NodePosX=656 NodeGuid=04FF57704D3C62273504FC85051973A2 CustomProperties Pin (PinId=6E42D51B400E7F8BE62C6186DD47F42E,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 7ED535AB4919DD7B1D9805B62645EEE4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8DAA77A84A306D670516109539946689,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallArrayFunction_0 19C1635745D7FE5FE57F648F687E21BE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DD9C0B1942EEF028A52DA988AC9CD8B9,PinName="CastFailed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C574FB64C931CA46706D2B880EDAFE7,PinName="Object",PinType.PinCategory="Object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 5A57E0444E24F32D27C4B48B3DAB787D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=788A4C924B7A133753B17C91EC82038D,PinName="AsStatic Mesh Actor",Direction="EGPD_Output",PinType.PinCategory="Object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallArrayFunction_0 B2233BDF45F880E36E499F91C27A3907,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A05B4528498A2A3641F420ADDCB87C0D,PinName="bSuccess",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallArrayFunction Name="K2Node_CallArrayFunction_0" FunctionReference=(MemberParent=Class'"/Script/Engine.KismetArrayLibrary"',MemberName="Array_Add") NodePosX=944 NodePosY=-16 NodeGuid=7FC6FAB041C7865D464AA59A4FA184A1 CustomProperties Pin (PinId=19C1635745D7FE5FE57F648F687E21BE,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_DynamicCast_0 8DAA77A84A306D670516109539946689,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7C82D855417C8B3FFD3C5CBC273B646E,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7E81FDD94B1A3D01C1B7588ACA85A2F8,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Array Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetArrayLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetArrayLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=88411E244EF67EF9C487B9BBE4877FD5,PinName="TargetArray",PinToolTip="Target Array\nArray of Static Mesh Actor Object References\n\nThe array to add item to",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_1 684DA05E48034CB30E40E8AF23AEE678,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B2233BDF45F880E36E499F91C27A3907,PinName="NewItem",PinToolTip="New Item\nStatic Mesh Actor Object Reference (by ref)\n\nThe item to add to the array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_DynamicCast_0 788A4C924B7A133753B17C91EC82038D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8089172B41330411E952268641514CD5,PinName="ReturnValue",PinToolTip="Return Value\nInteger\n\nThe index of the newly added item",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0",AutogeneratedDefaultValue="0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_1" VariableReference=(MemberName="Actors",MemberGuid=67AB080C4EB9977BC93A5BB35F6DE4A0,bSelfContext=True) NodePosX=768 NodePosY=128 NodeGuid=0175A5A644A2B3B582B0CF81CE95B07C CustomProperties Pin (PinId=684DA05E48034CB30E40E8AF23AEE678,PinName="Actors",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallArrayFunction_0 88411E244EF67EF9C487B9BBE4877FD5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=029F736F4EEA675C4179B29F7482537F,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/DistributeAssets.DistributeAssets_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_0" VariableReference=(MemberName="Actors",MemberGuid=67AB080C4EB9977BC93A5BB35F6DE4A0,bSelfContext=True) NodePosX=-16 NodePosY=-16 NodeGuid=BFE061A941CF9FD62DF7EFA4ACF80006 CustomProperties Pin (PinId=366FFB14429049A0E7225E99D0A49E7E,PinName="Actors",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallArrayFunction_1 3AD6E49E48DC8A414DB3FDB2EAA06DA6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D460E2DE4FE75A18698DD89BB268822C,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/DistributeAssets.DistributeAssets_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallArrayFunction Name="K2Node_CallArrayFunction_1" FunctionReference=(MemberParent=Class'"/Script/Engine.KismetArrayLibrary"',MemberName="Array_Clear") NodePosX=208 NodeGuid=918E53A24278BAF590114AAB12F72D7F CustomProperties Pin (PinId=71F1EA8B408DC625F0ED37B53017AE05,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Event_0 7966201F44B98504D944FAA610535AA8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=85FB3E7E4D2DBDAF8664719956E2BC38,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 494953294EE1E71073A595B79ACCF5F1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=50B7B4ED4746B7BAA9F8D6848818EDA5,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Array Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetArrayLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetArrayLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3AD6E49E48DC8A414DB3FDB2EAA06DA6,PinName="TargetArray",PinToolTip="Target Array\nArray of Static Mesh Actor Object References\n\nThe array to clear",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_0 366FFB14429049A0E7225E99D0A49E7E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_1" MacroGraphReference=(MacroGraph=EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForEachLoop"',GraphBlueprint=Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=99DBFD5540A796041F72A5A9DA655026) ResolvedWildcardType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',ContainerType=Array) NodePosX=96 NodePosY=336 NodeGuid=6F6305324C0DB841C6A98BB6BD869354 CustomProperties Pin (PinId=E32C7AEC46326F615A747C932D700E1B,PinName="Exec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_2 D3DEA21442BCAAF569C84B88D2F9B304,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=764CCDE749D24B4747EF0281943315A5,PinName="Array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_2 221BFF5840FCEBCA2DF9DA8F27255858,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5D7C934F43FE3C69D1BAD2809C5FF8DE,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_0 3DF6587641AFAAA18B2E8C83D70A5BA3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B26169264F236F5C47C9A3981BAD82F9,PinName="Array Element",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_4 61308CA1492C168D032BC1975B792334,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=835DC6814C8D50AA5E7B958DF138D2CA,PinName="Array Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_4 E68F8AE7407B3700D18F79A755F932B7,K2Node_CallFunction_6 23878F6547C2706EE538DDB3181ED894,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D4D6D7C249A73D2A3B1D74AB770A3B67,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_2" VariableReference=(MemberName="Actors",MemberGuid=67AB080C4EB9977BC93A5BB35F6DE4A0,bSelfContext=True) NodePosX=-448 NodePosY=496 NodeGuid=09049FCE4AD65E210C625EB39B056C21 CustomProperties Pin (PinId=221BFF5840FCEBCA2DF9DA8F27255858,PinName="Actors",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_1 764CCDE749D24B4747EF0281943315A5,K2Node_CallArrayFunction_2 97C7EC7F4BB578735B37A3B22B97393B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=162707E442DF011CABF1D7A39C3F42CF,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/DistributeAssets.DistributeAssets_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallArrayFunction Name="K2Node_CallArrayFunction_2" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetArrayLibrary"',MemberName="Array_Length") NodePosX=-272 NodePosY=544 NodeGuid=84A0D33F41644A8E14D1C3AF2238249E CustomProperties Pin (PinId=85A9FF3B43F131CF929E958E7B76A503,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Array Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetArrayLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetArrayLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=97C7EC7F4BB578735B37A3B22B97393B,PinName="TargetArray",PinToolTip="Target Array\nArray of Static Mesh Actor Object References\n\nThe array to get the length of ",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_2 221BFF5840FCEBCA2DF9DA8F27255858,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=522D6DD84A84EBD183AB2BBA4F11090C,PinName="ReturnValue",PinToolTip="Return Value\nInteger\n\nThe length of the array",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_CallFunction_3 0A20233945E638DC871C31BC2AF0321E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" FunctionReference=(MemberParent=Class'"/Script/Engine.SceneComponent"',MemberName="K2_SetWorldLocation") NodePosX=1552 NodePosY=288 NodeGuid=82CF6D7E47E85D73833DF496E164A6B7 CustomProperties Pin (PinId=3DF6587641AFAAA18B2E8C83D70A5BA3,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_1 5D7C934F43FE3C69D1BAD2809C5FF8DE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3B8404C54739698732516E9E26DEE4A0,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D74A37FF486025437BF73CB06A865071,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nScene Component Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.SceneComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_VariableGet_4 D97F33B64AD0B26DC7E2F792E46087D1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=443AA74344505B345E0FEBBB686F2711,PinName="NewLocation",PinToolTip="New Location\nVector\n\nNew location in world space for the component.",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CommutativeAssociativeBinaryOperator_2 CF111E13426291D8BE7CA78856DEF035,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ED87C46D4587856BEE4BCAB989DB97CB,PinName="bSweep",PinToolTip="Sweep\nBoolean\n\nWhether we sweep to the destination location, triggering overlaps along the way and stopping short of the target if blocked by something. Only the root component is swept and checked for blocking collision, child components move without sweeping. If collision is off, this has no effect.",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4B657491439457A846D4F28F0C999F44,PinName="SweepHitResult",PinToolTip="Sweep Hit Result\nHit Result Structure\n\nHit result from any impact if sweep is true.",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/Engine.HitResult"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1503458E4190B7666B88F7B8D0B787D2,PinName="bTeleport",PinToolTip="Teleport\nBoolean\n\nWhether we teleport the physics state (if physics collision is enabled for this object). If true, physics velocity for this object is unchanged (so ragdoll parts are not affected by change in location). If false, physics velocity is updated based on the change in position (affecting ragdoll parts). If CCD is on and not teleporting, this will affect objects along the entire sweep volume.",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_4" VariableReference=(MemberParent=Class'"/Script/Engine.StaticMeshActor"',MemberName="StaticMeshComponent") SelfContextInfo=NotSelfContext NodePosX=1200 NodePosY=368 NodeGuid=ACB9C70E4832CE226E3FF38B7063E531 CustomProperties Pin (PinId=D97F33B64AD0B26DC7E2F792E46087D1,PinName="StaticMeshComponent",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_0 D74A37FF486025437BF73CB06A865071,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=61308CA1492C168D032BC1975B792334,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_1 B26169264F236F5C47C9A3981BAD82F9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_1" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="FFloor") NodePosX=256 NodePosY=544 NodeGuid=75A0131548862F508B093EA164DEF6E5 CustomProperties Pin (PinId=2941FF354E9ABAD95C26A9B8F3EF8EB9,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C7F1FA894834A3C333B4FC8858AA81E2,PinName="A",PinToolTip="A\nFloat",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_2 E366FF704899A428E4C2998AAF1C1B0C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=392D14134A040AD00915649D30DB61F2,PinName="ReturnValue",PinToolTip="Return Value\nInteger\n\nRounds A down towards negative infinity / down to the previous integer (e.g., -1.6 becomes -2 and 1.6 becomes 1)",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_CallFunction_4 48DA19A1499A0B690CAF10A86AE82F1B,K2Node_CallFunction_6 9AFB4E3F4D84C4D2E5A5DF97603F8956,K2Node_CallFunction_12 5B5C2C94438AE597AFD614899218E3DD,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_2" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Sqrt") NodePosX=64 NodePosY=544 NodeGuid=CB0CDC8E432611B3AC4EE49521A59690 CustomProperties Pin (PinId=B4B93BA74F344ADCB71FC8B909D19218,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=822D5D4E4D376D70D7AAA5A372C6BEF2,PinName="A",PinToolTip="A\nFloat",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_3 DDBC83E34075E83BA460F3905316464E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E366FF704899A428E4C2998AAF1C1B0C,PinName="ReturnValue",PinToolTip="Return Value\nFloat\n\nReturns square root of A",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_1 C7F1FA894834A3C333B4FC8858AA81E2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_3" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Conv_IntToFloat") NodePosX=-64 NodePosY=544 NodeGuid=8846AD674B8D71EB3C5458975B899EDC CustomProperties Pin (PinId=8BDC57974DA5F1D67A093397D8022E91,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0A20233945E638DC871C31BC2AF0321E,PinName="InInt",PinToolTip="In Int\nInteger",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_CallArrayFunction_2 522D6DD84A84EBD183AB2BBA4F11090C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DDBC83E34075E83BA460F3905316464E,PinName="ReturnValue",PinToolTip="Return Value\nFloat\n\nConverts an integer to a float",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_2 822D5D4E4D376D70D7AAA5A372C6BEF2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_4" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Percent_IntInt") NodePosX=480 NodePosY=464 NodeGuid=A95FDBDB4CC9896AF19DD199BDB45077 CustomProperties Pin (PinId=B808795F4B93BB84238B67BC0D987081,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E68F8AE7407B3700D18F79A755F932B7,PinName="A",PinToolTip="A\nInteger",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_MacroInstance_1 835DC6814C8D50AA5E7B958DF138D2CA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=48DA19A1499A0B690CAF10A86AE82F1B,PinName="B",PinToolTip="B\nInteger",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="1",AutogeneratedDefaultValue="1",LinkedTo=(K2Node_CallFunction_1 392D14134A040AD00915649D30DB61F2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B763A4B040B5473E10745293BFB960F6,PinName="ReturnValue",PinToolTip="Return Value\nInteger\n\nModulo (A % B)",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_CallFunction_9 7A0135E643EAF62AF11017A04C11FF9B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_6" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Divide_IntInt") NodePosX=672 NodePosY=416 NodeGuid=B85921954E1484E686436BB7E055358F CustomProperties Pin (PinId=91BD23804EDF0048EFC8B195156834D6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=23878F6547C2706EE538DDB3181ED894,PinName="A",PinToolTip="A\nInteger",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_MacroInstance_1 835DC6814C8D50AA5E7B958DF138D2CA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9AFB4E3F4D84C4D2E5A5DF97603F8956,PinName="B",PinToolTip="B\nInteger",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="1",AutogeneratedDefaultValue="1",LinkedTo=(K2Node_CallFunction_1 392D14134A040AD00915649D30DB61F2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CF7CEB3D49905E5FE5E766BF5257602A,PinName="ReturnValue",PinToolTip="Return Value\nInteger\n\nDivision (A / B)",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_CallFunction_8 0B17855A484EC99AE6DEA7A0B828166C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CommutativeAssociativeBinaryOperator Name="K2Node_CommutativeAssociativeBinaryOperator_1" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Multiply_FloatFloat") NodePosX=944 NodePosY=416 NodeGuid=75349454495DC57EE29E158AF9691190 CustomProperties Pin (PinId=B8A6E45C486B00483E05E1A69AE3D0BF,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CC6A0ED34A4C0797A27F5FB34B04DA9D,PinName="A",PinToolTip="A\nFloat",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_8 4C8102D747DFD8AE65B28FADBCABBF52,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D6D5E3EB4B4BDEF81ED16D9F208864C4,PinName="B",PinToolTip="B\nFloat",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_10 F784F6314CCF125221DD4CAEB4FF13B8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B0D46C724DAEC8F6ABCD77A6581C089B,PinName="ReturnValue",PinToolTip="Return Value\nFloat\n\nMultiplication (A B)",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_11 CDC469F94B0BA4F999DEC5A7DC7EB567,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_8" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Conv_IntToFloat") NodePosX=800 NodePosY=416 NodeGuid=A04FA519498588AE728070822AADDD87 CustomProperties Pin (PinId=2048BEBF447CBC3FDEFA0E9B4F73B072,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0B17855A484EC99AE6DEA7A0B828166C,PinName="InInt",PinToolTip="In Int\nInteger",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_CallFunction_6 CF7CEB3D49905E5FE5E766BF5257602A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4C8102D747DFD8AE65B28FADBCABBF52,PinName="ReturnValue",PinToolTip="Return Value\nFloat\n\nConverts an integer to a float",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CommutativeAssociativeBinaryOperator_1 CC6A0ED34A4C0797A27F5FB34B04DA9D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CommutativeAssociativeBinaryOperator Name="K2Node_CommutativeAssociativeBinaryOperator_0" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Multiply_FloatFloat") NodePosX=960 NodePosY=512 NodeGuid=AD6A2B8E4396ED4BA0E790B32C119356 CustomProperties Pin (PinId=B8A6E45C486B00483E05E1A69AE3D0BF,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CC6A0ED34A4C0797A27F5FB34B04DA9D,PinName="A",PinToolTip="A\nFloat",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_9 F3B8FFB44C76B558FA1C688AA4BA484F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D6D5E3EB4B4BDEF81ED16D9F208864C4,PinName="B",PinToolTip="B\nFloat",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_10 4B31042B40EBF59567BD559EC950054D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B0D46C724DAEC8F6ABCD77A6581C089B,PinName="ReturnValue",PinToolTip="Return Value\nFloat\n\nMultiplication (A * B)",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_11 3CEDDDA64B32BD74F6AD1DBF67FE575D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_9" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Conv_IntToFloat") NodePosX=688 NodePosY=512 NodeGuid=8E84A7AA4D4212561BDB108FEE835F91 CustomProperties Pin (PinId=BF1768DA47C78549A50ABCAEDFC2F966,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7A0135E643EAF62AF11017A04C11FF9B,PinName="InInt",PinToolTip="In Int\nInteger",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_CallFunction_4 B763A4B040B5473E10745293BFB960F6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F3B8FFB44C76B558FA1C688AA4BA484F,PinName="ReturnValue",PinToolTip="Return Value\nFloat\n\nConverts an integer to a float",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CommutativeAssociativeBinaryOperator_0 CC6A0ED34A4C0797A27F5FB34B04DA9D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_10" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="BreakVector") NodePosX=720 NodePosY=592 NodeGuid=2B3962AB428E5E8A7124E39C8E83659C CustomProperties Pin (PinId=323481B1404CE67D6339CE9057D6AAEE,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=148CD1124D432BF6A117F49663AF9489,PinName="InVec",PinToolTip="In Vec\nVector",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CallFunction_12 17FB5858488AFFD3F44BF78960D5A482,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F784F6314CCF125221DD4CAEB4FF13B8,PinName="X",PinToolTip="X\nFloat",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CommutativeAssociativeBinaryOperator_1 D6D5E3EB4B4BDEF81ED16D9F208864C4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4B31042B40EBF59567BD559EC950054D,PinName="Y",PinToolTip="Y\nFloat",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CommutativeAssociativeBinaryOperator_0 D6D5E3EB4B4BDEF81ED16D9F208864C4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=375F8D3145ECBC8E361C14905C03A4B4,PinName="Z",PinToolTip="Z\nFloat",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_11" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="MakeVector") NodePosX=1168 NodePosY=480 NodeGuid=1D6E879346448454C6298EAAFA1D7B47 CustomProperties Pin (PinId=29432B5D4ECF65F95634C48F78E9B947,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CDC469F94B0BA4F999DEC5A7DC7EB567,PinName="X",PinToolTip="X\nFloat",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CommutativeAssociativeBinaryOperator_1 B0D46C724DAEC8F6ABCD77A6581C089B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3CEDDDA64B32BD74F6AD1DBF67FE575D,PinName="Y",PinToolTip="Y\nFloat",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CommutativeAssociativeBinaryOperator_0 B0D46C724DAEC8F6ABCD77A6581C089B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=39187082409BBBADD20A238F8C834A5B,PinName="Z",PinToolTip="Z\nFloat",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_14 4BDF7E14468B44CEE7A8A3BCBFF2CC68,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=55B680D24F114F464B302A8511EA62B4,PinName="ReturnValue",PinToolTip="Return Value\nVector\n\nMakes a vector {X, Y, Z}",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CommutativeAssociativeBinaryOperator_2 7D38DE7F4FA400271D20DC8F242E26E8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CommutativeAssociativeBinaryOperator Name="K2Node_CommutativeAssociativeBinaryOperator_2" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Add_VectorVector") NodePosX=1376 NodePosY=448 NodeGuid=E008AD714A56DA74FAE0CCB5EA3CFBB7 CustomProperties Pin (PinId=8EEBCEA244E672BDCEB578BCA40E99B7,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7D38DE7F4FA400271D20DC8F242E26E8,PinName="A",PinToolTip="A\nVector",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CallFunction_11 55B680D24F114F464B302A8511EA62B4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=057038EC4D757D7E3921FFB3531A5A8B,PinName="B",PinToolTip="B\nVector",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_VariableGet_5 D5966D3D47F5A5B0AC3FD9A35C817FCA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CF111E13426291D8BE7CA78856DEF035,PinName="ReturnValue",PinToolTip="Return Value\nVector\n\nVector addition",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CallFunction_0 443AA74344505B345E0FEBBB686F2711,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_5" VariableReference=(MemberName="Min",MemberGuid=9ACC024B435BC918667500BC2E24C491,bSelfContext=True) NodePosX=1200 NodePosY=416 NodeGuid=0C2FA4F1414EF39EEC42A89C15D565B3 CustomProperties Pin (PinId=D5966D3D47F5A5B0AC3FD9A35C817FCA,PinName="Min",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CommutativeAssociativeBinaryOperator_2 057038EC4D757D7E3921FFB3531A5A8B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9FDD4B274CEF296A7F3FE09C368C7322,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/DistributeAssets.DistributeAssets_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_12" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Divide_VectorInt") NodePosX=560 NodePosY=608 NodeGuid=50A689DB4F1D99C97C9470BE41D11E68 CustomProperties Pin (PinId=4AD3951848D483A0079850B38B2F1A85,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=032894944C21F811807ED68536FD2DA7,PinName="A",PinToolTip="A\nVector",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CallFunction_13 7D0D69CF4F3DE4A160797DB04CB07879,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5B5C2C94438AE597AFD614899218E3DD,PinName="B",PinToolTip="B\nInteger",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="1",AutogeneratedDefaultValue="1",LinkedTo=(K2Node_CallFunction_1 392D14134A040AD00915649D30DB61F2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=17FB5858488AFFD3F44BF78960D5A482,PinName="ReturnValue",PinToolTip="Return Value\nVector\n\nVector divide by an integer",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CallFunction_10 148CD1124D432BF6A117F49663AF9489,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_6" VariableReference=(MemberName="Min",MemberGuid=9ACC024B435BC918667500BC2E24C491,bSelfContext=True) NodePosX=224 NodePosY=720 NodeGuid=094168FF4955054B216C43B854280DBB CustomProperties Pin (PinId=678FB9A84509B44162C30EA5299E457E,PinName="Min",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CallFunction_13 89EDFF4A436528AAC32BE4BB631559E2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EEE391F94A2DEB6F9911F4A6BE90F46E,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/DistributeAssets.DistributeAssets_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_7" VariableReference=(MemberName="Max",MemberGuid=20650C694F7218E4DE53FD98A868058A,bSelfContext=True) NodePosX=224 NodePosY=640 NodeGuid=02AA5F504278F2BB0F9C9A924F0A3E49 CustomProperties Pin (PinId=9A8E09C34274F07B9B2EE3BE30F65B26,PinName="Max",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CallFunction_13 203354334F73788DFB5666A924FB9C6D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4F435F33405A73DC0E098BA95C182699,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/DistributeAssets.DistributeAssets_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_13" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Subtract_VectorVector") NodePosX=384 NodePosY=672 NodeGuid=5424FA3C49A2C7331297DFA70FB3DF56 CustomProperties Pin (PinId=34882EBB49048F111F7D908C93476386,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=203354334F73788DFB5666A924FB9C6D,PinName="A",PinToolTip="A\nVector",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_VariableGet_7 9A8E09C34274F07B9B2EE3BE30F65B26,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=89EDFF4A436528AAC32BE4BB631559E2,PinName="B",PinToolTip="B\nVector",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_VariableGet_6 678FB9A84509B44162C30EA5299E457E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7D0D69CF4F3DE4A160797DB04CB07879,PinName="ReturnValue",PinToolTip="Return Value\nVector\n\nVector subtraction",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CallFunction_12 032894944C21F811807ED68536FD2DA7,K2Node_CallFunction_14 96D603984079C4E0CB6A6E9FB9D81468,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_14" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="BreakVector") NodePosX=720 NodePosY=736 NodeGuid=2C1ADF0449865736848C289CACDC84F1 CustomProperties Pin (PinId=45A37E95423CA2C387C71F8E63FA4524,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=96D603984079C4E0CB6A6E9FB9D81468,PinName="InVec",PinToolTip="In Vec\nVector",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_CallFunction_13 7D0D69CF4F3DE4A160797DB04CB07879,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0771B50940CE3726A2E0FB95417834CA,PinName="X",PinToolTip="X\nFloat",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B926CA4D48387471327C939A6F669AB1,PinName="Y",PinToolTip="Y\nFloat",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4BDF7E14468B44CEE7A8A3BCBFF2CC68,PinName="Z",PinToolTip="Z\nFloat",Direction="EGPD_Output",PinType.PinCategory="float",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_11 39187082409BBBADD20A238F8C834A5B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_0" NodePosX=576 NodePosY=304 NodeGuid=467D05174126A81842F2BCA75DE7E662 CustomProperties Pin (PinId=E696487B41250450B13D76B1AADB3C43,PinName="InputPin",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 265F263247305123B1D06BAD4BB8DB46,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E8B027854E76EEB345250FA1D157AF68,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_1 36DCB7C54F2DBB90219F57B4CCDD09D1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_1" NodePosX=32 NodePosY=304 NodeGuid=2C0B6C9F4AB3F6519CCAFEAE86F0B0C1 CustomProperties Pin (PinId=36DCB7C54F2DBB90219F57B4CCDD09D1,PinName="InputPin",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_0 E8B027854E76EEB345250FA1D157AF68,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D364F7D74821BA897DE765B453D1AB1A,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_2 547227F64740276F8461369C430C20AD,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_2" NodePosX=32 NodePosY=368 NodeGuid=440EE15E48696CF845CE0F9446A6974D CustomProperties Pin (PinId=547227F64740276F8461369C430C20AD,PinName="InputPin",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Knot_1 D364F7D74821BA897DE765B453D1AB1A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D3DEA21442BCAAF569C84B88D2F9B304,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_1 E32C7AEC46326F615A747C932D700E1B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_0" bCommentBubbleVisible_InDetailsPanel=False NodePosX=-176 NodePosY=-64 NodeWidth=1307 NodeHeight=284 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Get all Static Mesh Actors into an array" NodeGuid=DED350294F13FD64505B849D0637099F End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_1" bCommentBubbleVisible_InDetailsPanel=False NodePosX=-496 NodePosY=240 NodeWidth=2357 NodeHeight=656 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Arrange the array of Actors into a grid" NodeGuid=7933753B4201329487EF8DBB09715660 End Object

The following implementation of the On Execution event finds Actors in the context and adds them to a specified Layer in the Editor.





Begin Object Class=/Script/BlueprintGraph.K2Node_Event Name="K2Node_Event_0" EventReference=(MemberParent=Class'"/Script/DataprepCore.DataprepOperation"',MemberName="OnExecution") bOverrideFunction=True NodePosX=-512 NodePosY=144 NodeGuid=7BFDD811461E625E18CDA297A0ACE07F CustomProperties Pin (PinId=6A94143D4A28161A83484FA76A1F1D32,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=Class'"/Script/DataprepCore.DataprepOperation"',MemberName="OnExecution"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=400107C54F6090C4FC2D7BA2A488F159,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 EDE459C142627976C1CCAE86AD15FB96,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=15819F3E477B7967ACCB3AA628CDC787,PinName="InContext",PinToolTip="In Context\nDataprep Context Structure (by ref)\n\nThe context contains the data that the operation should operate on.",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DataprepCore.DataprepContext"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_BreakStruct_0 4DB8DFA048C3E323F0F7DCAB83D97CC0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_BreakStruct Name="K2Node_BreakStruct_0" bMadeAfterOverridePinRemoval=True ShowPinForProperties(0)=(PropertyName="Objects",PropertyFriendlyName="Objects",PropertyTooltip=NSLOCTEXT("", "C01651AF43E8DB7C297092896AACB554", "This is the objects on which an operation can operate"),CategoryName="Dataprep",bShowPin=True,bCanToggleVisibility=True) StructType=ScriptStruct'"/Script/DataprepCore.DataprepContext"' NodePosX=-304 NodePosY=240 NodeGuid=8711FCA242239887390239BDD7EA0E01 CustomProperties Pin (PinId=4DB8DFA048C3E323F0F7DCAB83D97CC0,PinName="DataprepContext",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/DataprepCore.DataprepContext"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Event_0 15819F3E477B7967ACCB3AA628CDC787,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9A559E6C4ED6D42DDD8DB3B22F2B7434,PinName="Objects",PinFriendlyName=NSLOCTEXT("", "F59F9448471786D1307FEDBB91D91626", "Objects"),PinToolTip="Objects\nArray of Object References\n\nThis is the objects on which an operation can operate",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 325F93134E5F1EF04B0834B91D714696,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_0" MacroGraphReference=(MacroGraph=EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForEachLoop"',GraphBlueprint=Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=99DBFD5540A796041F72A5A9DA655026) ResolvedWildcardType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',ContainerType=Array) NodePosX=-48 NodePosY=144 NodeGuid=A07EE16E4458DA0364F48683049AFC97 CustomProperties Pin (PinId=EDE459C142627976C1CCAE86AD15FB96,PinName="Exec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_Event_0 400107C54F6090C4FC2D7BA2A488F159,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=325F93134E5F1EF04B0834B91D714696,PinName="Array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_BreakStruct_0 9A559E6C4ED6D42DDD8DB3B22F2B7434,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E65B438E47D17CE4B494E58296F268FD,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_DynamicCast_0 F4022EF949485DAB11E885BE391FCEF5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DC0898A44FE472F82E53918D4C5DAEFC,PinName="Array Element",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_DynamicCast_0 7E7FDD4F4F103800DCE82A8329A7C3FB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AA8E334B4319361FF281A59FE729A4FF,PinName="Array Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A298B04046F94B331BDFB8B1733A0DBA,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_DynamicCast Name="K2Node_DynamicCast_0" TargetType=Class'"/Script/Engine.Actor"' NodePosX=176 NodePosY=144 NodeGuid=7E595D4E419075326D10119578191319 CustomProperties Pin (PinId=F4022EF949485DAB11E885BE391FCEF5,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 E65B438E47D17CE4B494E58296F268FD,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9512914141694E33C1BF02B1F83E5E94,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_1 B27B18FF4932973E390AB9A29BD39422,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=634512104940E8660A691C954A80F3B2,PinName="CastFailed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7E7FDD4F4F103800DCE82A8329A7C3FB,PinName="Object",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MacroInstance_0 DC0898A44FE472F82E53918D4C5DAEFC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=636FA8544CF8BB02272DEDA79A05B7CA,PinName="AsActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_1 656B087F41449A8A9B5B70B5D1CAEEE0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=84F0E0E0482C6C151A8373989C6F3E09,PinName="bSuccess",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MakeStruct Name="K2Node_MakeStruct_0" bMadeAfterOverridePinRemoval=True ShowPinForProperties(0)=(PropertyName="Name",PropertyFriendlyName="Name",PropertyTooltip=NSLOCTEXT("UObjectToolTips", "ActorLayer:Name", "The name of this layer"),CategoryName="Layer",bShowPin=True,bCanToggleVisibility=True) StructType=ScriptStruct'"/Script/ActorLayerUtilities.ActorLayer"' NodePosX=192 NodePosY=288 NodeGuid=4F30A21440114BF2194745A18D9ED775 CustomProperties Pin (PinId=C949A0F0463AF57D330ABE801D9BFA60,PinName="ActorLayer",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/ActorLayerUtilities.ActorLayer"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_CallFunction_1 042849234A55AB9E720BC296FF8B5671,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F38B7B084FFBC760BCE9C0B0FD0F214F,PinName="Name",PinFriendlyName=NSLOCTEXT("", "5D84CE51410FEF64F3ADD9BF28EF9462", "Name"),PinToolTip="Name\nName\n\nThe name of this layer",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="None",AutogeneratedDefaultValue="None",LinkedTo=(K2Node_VariableGet_4 07B04E214FB7890B5EA4968C46B99886,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_4" VariableReference=(MemberName="LayerName",MemberGuid=148514314B0F07EF5636F095BB2220CE,bSelfContext=True) NodePosX=32 NodePosY=320 NodeGuid=69748F1C40B917388250D5B5BE82B9B3 CustomProperties Pin (PinId=07B04E214FB7890B5EA4968C46B99886,PinName="LayerName",Direction="EGPD_Output",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultValue="None",AutogeneratedDefaultValue="None",LinkedTo=(K2Node_MakeStruct_0 F38B7B084FFBC760BCE9C0B0FD0F214F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C5B3943B4AAE51D8AA1FB387CA2A9E2E,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/SetLayer.SetLayer_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_1" FunctionReference=(MemberParent=Class'"/Script/ActorLayerUtilities.LayersBlueprintLibrary"',MemberName="AddActorToLayer") NodePosX=400 NodePosY=160 NodeGuid=5E008F5F465F598B31A68E87652D6AF4 CustomProperties Pin (PinId=B27B18FF4932973E390AB9A29BD39422,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_DynamicCast_0 9512914141694E33C1BF02B1F83E5E94,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F7176FD540ED555829AC24B1F4D54774,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AF94E6F24AAF5795D0A8AA9B1694B89A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nLayers Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/ActorLayerUtilities.LayersBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,DefaultObject="/Script/ActorLayerUtilities.Default__LayersBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=656B087F41449A8A9B5B70B5D1CAEEE0,PinName="InActor",PinToolTip="In Actor\nActor Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_DynamicCast_0 636FA8544CF8BB02272DEDA79A05B7CA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=042849234A55AB9E720BC296FF8B5671,PinName="Layer",PinToolTip="Layer\nActor Layer Structure (by ref)",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/ActorLayerUtilities.ActorLayer"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,LinkedTo=(K2Node_MakeStruct_0 C949A0F0463AF57D330ABE801D9BFA60,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) End Object

Dataprep Operation Reference

Dataprep Selection Transform Reference

Select By Condition

Is Class Of

Jacketing / Select Hidden

Select By Float

Bounding Volume

Select By Integer

Triangle Count

Vertex Count

Select By String

Actor Label

Metadata Value

Object Name

Actor Layer

Tag Value

This page describes each of the Select By blocks that you can use in the Visual Dataprep system to identify scene elements that you want to carry out operations on.

Each type of Select By block offers a different set of criteria that you can fill in. When the Visual Dataprep system carries out each action in your Dataprep graph, it at first assumes that all operations defined in that action should apply to all Actors and all Assets in the imported scene. However, if your action contains any of the Select By blocks described on this page, the Visual Dataprep system checks each of those scene elements to see if it matches the criteria you've set up in the Select By block. If the scene element doesn't satisfy your criteria, the Visual Dataprep system removes that element from the list of scene elements it applies operations to for the current action. For more background information, see Dataprep Import Customization.

For information about the operations you can carry out on the scene elements identified by your Select By criteria, see Dataprep Operation Reference.

Select By Condition

Select By Condition blocks select a scene element only if a given condition is true for that element.

Is Class Of

Use the Is Class Of block to select a scene element only if its Class after import into Unreal Engine matches the Class name that you specify in the Class setting.

This filter can select Assets, Actors, and Components.



Click image for full size.

Setting

Description

Class

The Class that all scene elements must match to be selected by this block.

Should Include Child Class

Determines whether this block should consider a scene element to match successfully if its Unreal Engine Class is derived from the Class you set in the Class setting.

Enabled by default, the block will accept any scene elements whose Class derives from the Class you specify in the Class setting.

If you disable this setting, the block will only accept scene elements whose Class matches the Class setting exactly.

For example, suppose that you set the Class setting to Actor, and a scene element being considered has the Class StaticMeshActor. In this case, StaticMeshActor inherits from the base Actor Class, so the Is Class Of block will select that scene element only if the Should Include Child Class setting is enabled.

Jacketing / Select Hidden

This filter requires you to enable the Dataprep Geometry Operations plugin.

Use the Jacketing / Select Hidden filter to select elements that are inside of one or several Actors that you previously selected.



Click image for full size.

Setting

Description

Accuracy

Defines the accuracy of the voxel grid that Datasmith uses to determine which elements are inside or outside an Actor's boundaries.

Merge Distance

Sets the maximum size of the gaps in the occluding volumes that the occlusion tests will consider to be filled.

Select By Float

Select By Float blocks select scene elements only if some numeric property of those scene elements is Less Than, Greater Than, or Is Nearly Equal to a given threshold value.

Select By Float blocks consider two numbers to be Is Nearly Equal if the difference between them is less than 0.0001.

Bounding Volume

Use the Bounding Volume block to select a scene element only if it has extents in 3D space (and therefore a bounding box), and only if the total volume of that bounding box satisfies the comparison you specify in the settings.

This filter can select Assets, Actors, and Components.



Click image for full size.

Setting

Description

Dropdown Menu

The type of mathematical comparison you want to carry out between the bounding volume of the object and the volume you specify: Less Than, Greater Than, or Is Nearly Equal.

Float Value

The volume that you want to compare your object's bounding volume against, in cubic centimeters.

For example, suppose a Static Mesh has a bounding volume that is 100 centimeters by 100 centimeters. The volume of its bounding box is 100x100, or 10000 cubic centimeters. Therefore, this block would select that Static Mesh if you set it to Less Than any number larger than 10000, or Greater Than any number below 10000.

Select By Integer

Select By Integer blocks select scene elements only if some numeric property of those scene elements is Less Than, Greater Than, or Is Nearly Equal to a given threshold value.

Triangle Count

Use the Triangle Count block to select only the Static Mesh Actors and Static Mesh Assets whose number of triangles satisfies the comparison you specify in the settings.

This filter can select Assets, Actors, and Components.



Click image for full size.

Setting

Description

Dropdown Menu

The type of mathematical comparison you want to carry out between the number of triangles in the mesh and the number you specify: Less Than, Greater Than, or Is Nearly Equal.

Integer Value

The number that you want to compare your object's triangle count against.

For example, if a Static Mesh Actor or Asset has 2000 triangles, this block would select that object if you set the block to Less Than any number larger than 2000, or Greater Than any number below 2000.

Vertex Count

Use the Vertex Count block to select only the Static Mesh Actors and Static Mesh Assets whose number of vertices satisfies the comparison you specify in the settings.

This filter can select Assets, Actors, and Components.



Click image for full size.

Setting

Description

Dropdown Menu

The type of mathematical comparison you want to carry out between the number of vertices in the mesh and the number you specify: Less Than, Greater Than, or Is Nearly Equal.

Integer Value

The number that you want to compare your object's vertex count against.

For example, if a Static Mesh Actor or Asset has 5000 vertices, this block would select that object if you set the block to Less Than any number larger than 5000, or Greater Than any number below 5000.

Select By String

Select By String blocks select scene elements only if a given string property of those scene elements match a string pattern that you specify.

All string conditions can use either a single string or an array of strings. To toggle between these two options, click the Switch to Single / Switch to Array button. For string arrays, the filter will return any objects (Actors, Assets, and / or Components, depending on filter limitations) that match at least one of the array elements.



Click image for full size.

These blocks offer three string comparisons:

Setting

Description

Contains

The comparison is successful if the string you provide is contained in its entirety anywhere within the value of the string property of the scene element being considered. You can't use any wildcards in this type of comparison; * and ? characters are treated literally.

Matches Wildcard

The comparison is successful if the entire length of the string you provide matches the entire length of the string property of the scene element being considered, using the following wildcard characters:

An asterisk (*) in the pattern can stand in for any number of characters in the string property.

A question mark (?) in the pattern can stand in for zero or one characters in the string property.

The pattern must match the whole length of the string. If you want to provide a partial string that might occur anywhere within the value of the string property you are comparing against, start and end your string pattern with an asterisk (*). For example, if the string property value is MyActorName, then the pattern A*tor will not match, but *A*tor* will.

Exact Match

The comparison is only successful if the string you provide is an exact match for the value of the string property of the scene element being considered. It must be the same length, and it must contain the same set of characters all in the same order.

Actor Label

Use the Actor Label block to select Actors in the Dataprep preview scene — that is, any items shown in the Outliner Preview panel — only if the string that you specify matches the names that you see assigned to those Actors in the Outliner Preview.

This filter can only select Actors and Assets.



Click image for full size.

Setting

Description

Dropdown Menu

The type of string comparison you want to carry out between the Actor's label and the string you provide. See Select By String above for details.

Actor Label (String) Box

The string pattern you want to test against the Actor's label.

Metadata Value

Use the Metadata Value block to select Actors in the Dataprep preview scene — that is, any items shown in the Outliner Preview panel — only if the Actor has Datasmith Metadata with the Key you specify in the settings, and the value of that Datasmith Metadata key matches the string value you provide in the settings.

This filter can select Assets, Actors, and Components.



Click image for full size.

Setting

Description

Dropdown Menu

The type of string comparison you want to carry out between the Actor's Datasmith Metadata value and the string you provide. See Select By String above for details.

Metadata (String) Box

The string pattern you want to test against the Actor's Datasmith Metadata value.

Key Box

The name of the key that you want to look for in the Actor's Datasmith Metadata.

For example, suppose that you have an Actor that is assigned the following set of Datasmith Metadata after import:



Click image for full size.

If you set the Key value to Category, you could select this Actor by choosing the Contains operation and setting the string pattern in the third column to Floor or Floors.

For more about Datasmith Metadata, see Using Datasmith Metadata.

Object Name

Use the Object Name block to select Assets — that is, Static Meshes, Textures, Materials, and Animations listed in the Content Browser Preview panel — only if the string you specify matches the names that you see assigned to those Assets in the Content Browser Preview.

This filter can select Assets, Actors, and Components.



Click image for full size.

Setting

Description

Dropdown Menu

The type of string comparison you want to carry out between the scene element's name and the string you provide. See Select By String above for details.

Object Name (String) Box

The string pattern you want to test against the object's name.

Actor Layer

Use the Actor Layer block to select Actors in the Dataprep preview scene—that is, any items shown in the Outliner Preview panel—only if that Actor is in the Layer that you specify.

This filter can only select Actors.



Click image for full size.

Setting

Description

Dropdown Menu

The type of string comparison you want to carry out between the Actor's Layer and the string you provide. See Select By String above for details.

Actor Label (String) Box

The string pattern you want to test against the Actor's Layer.

Tag Value

Use the Tag Value block to select a scene element only if it possesses the Actor tag you specify in the Tag setting.

This filter can select Assets, Actors, and Components.



Click image for full size.

Setting

Description

Dropdown Menu

The type of string comparison you want to carry out between the Actor's label and the string you provide. See Select By String above for details.

Tag (String) Box

The name of the tag that you want to look for.

Only Actors that have a tag that exactly matches this value will be selected.



For example, if your Actor is imported with the following set of tags:



Click image for full size.

You could select this Actor in your Actor Tag block by setting the value of the Key setting to Max.superclassof: GeometryClass, Max.classof: EditablePolyMesh, Max.handle: 407, or any other value shown in the list above.

For more information on the Actor tags imported by Datasmith, see About the Datasmith Import Process.

Dataprep Selection Reference

Dataprep Selection Transform Reference

On Actor

Add Tags

Add To Layer

Compact Scene Graph

Create Proxy Mesh

Merge

Random Offset Transform

Set Mesh

Set Metadata

Set Mobility

Spawn Actors at Location

On Asset

Output to Folder

Replace Asset References

Set Max Texture Size

On Mesh

Bake Transform

Flip Faces

Generate Unwrapped UVs

Remesh

Set Convex Collision

Set LOD Group

Set LODs

Set Simple Collision

Setup Static Lighting

Simplify Mesh

Weld Edges

Set Collision Complexity

Plane Cut

On Object

Delete Objects

Delete Unused Assets

Set Material

Substitute Material

Substitute Material By Table

This page describes each of the Operations blocks that you can use in the Visual Dataprep system to modify your Assets and scene elements.

Each type of Operations block encapsulates a specific kind of modification that the Unreal Editor can make to 3D data. When the Visual Dataprep system carries out each action in your Dataprep graph, it performs each operation you've defined in that action on all the Assets or Actors that match the criteria set by the Select By blocks above it. For more background information, see Dataprep Overview.

On Actor

On Actor operations apply only to Actors that match the Select By criteria you set for their steps. That means only items that you see listed in the Outliner Preview panel on the right of the Dataprep preview UI. If your Select By criteria match other scene elements, like the Texture, Material, and Static Mesh Assets that are listed in the Content Browser Preview panel on the left of the Dataprep preview UI, the On Actor operation will have no effect on those elements.

Add Tags

This operation adds the array of tags you specify to each Actor or Component that matches the Select By criteria you set for this step.



Click image for full size.

After this block has completed, you can find the list of tags by selecting your Actor in the Outliner Preview and looking in the Details panel. Under the Actor category, expand the advanced options and look for the Tags setting.



Click image for full size.

Add To Layer

This operation takes each Static Mesh Actor that matches the Select By criteria you set for this step and adds it to the Layer you specify.



Click image for full size.

Compact Scene Graph

For each Static Mesh Actor that matches the Select By criteria you set for this step, this operation deletes the Actor if it doesn't have any visual result on the scene, and if none of its descendants in the scene hierarchy have visual results on the scene. The effect is to tidy unnecessary elements from the scene hierarchy without compromising the visual objects in the scene.



Click image for full size.

Create Proxy Mesh

This operation collects the geometry from all Static Mesh Actors and Components that match the Select By criteria you set for this step, and merges the geometry into a single new mesh using the Proxy Geometry Tool.



Click image for full size.

Setting

Description

New Actor Label

Specifies the name of the new Actor created from the merged geometry.

Quality

The level of quality for the geometry of the generated proxy mesh. Lower values are less detailed but may render more efficiently. Higher values are more detailed and faithful to the original geometry but may not be as efficient to render.

Merge

This operation collects the geometry from all Static Mesh Actors and Components that match the Select By criteria you set and merges the geometry into a single new mesh.



Click image for full size.

Setting

Description

New Actor Label

Specifies the name of the new Actor created from the merged geometry.

Pivot Point at Zero

Enable this setting if you want the merged mesh to have its pivot point set at the world origin. If left disabled, the pivot will be located at the first merged component.

Random Offset Transform

For each Actor that matches the Select By criteria you set for this step, this operation applies a random offset to the 3D position, rotation, or scale of the Actor. If you have placeholder elements in your scene, you can use this operation to scatter those elements around, or to give them varied sizes and rotations.

For example, an external architectural scene may contain placeholder objects for scene entourage like trees or bushes. In your Dataprep graph, you may want to replace all of those placeholders with other custom 3D Assets that you've already imported into your Project. However, this might result in a line of trees that are unnaturally identical. By applying random offsets to the position, rotation, and scale of the trees, you can quickly create a more varied and lifelike result without having to adjust the objects manually.



Click image for full size.

Setting

Description

Transform Type

Each Random Offset Transform block can apply offsets to only one of the following:

Location, which adjusts the placement of the objects in 3D space.

Rotation, which adjusts the facing direction of the objects.

Scale, which adjusts the size of the objects.

Reference Frame

Determines what frame of reference is used to interpret the axes in the Min and Max settings:

Global interprets the Min and Max values in world space, relative to the global 3D axes.

Relative interprets the Min and Max values in the object's local space, relative to the object's pivot point.

Min and Max

Sets a range for the random offsets along each of the three axes of 3D space. For each Actor this block treats, it generates a different random number in between the Min and Max values.

Set Mesh

For each Static Mesh Actor or Component that matches the Select By criteria you set for this step, this operation changes all Static Mesh Assets referred to by the Actor or Component to a different Static Mesh Asset that you specify in the settings.



Click image for full size.

Setting

Description

Static Mesh

The Static Mesh Asset that you want the Actor to instance in place of its existing Static Mesh. This replacement may be any Static Mesh in the Content Browser Preview panel of the Dataprep Editor, or any Static Mesh Asset that already exists in your project.

This operation has no effect on Actors that don't already refer to a Static Mesh Asset. For example, if you have an empty Actor in the scene hierarchy that doesn't already have a Static Mesh, you won't be able to use this operation to add a new Static Mesh to that Actor.

Set Metadata

This operation adds an array of keys and values to the Datasmith Metadata maintained by each Actor and Component that matches the Select By criteria you set for this step.



Click image for full size.

After this block has completed, you can find the list of metadata by selecting your Actor or Component in the Outliner Preview and looking in the Details panel under the Asset User Data category.

For more information, see Using Datasmith Metadata.

Set Mobility

For each Actor or Component that matches the Select By criteria you set for this step, this operation sets the value of the Actor's Mobility setting.

The Mobility setting has slightly different implications for Light Actors than it does for Static Mesh Actors. For details on how it is interpreted, see Actor Mobility.



Click image for full size.

Setting

Description

Mobility Type

The value you want to set for the Actor's Mobility setting.

Find the Mobility setting in the Details panel:



Click image for full size.

Spawn Actors at Location

For each Actor that matches the Select By criteria you set for this step, this operation spawns a new Actor at the same 3D coordinates. The newly spawned Actor is an instance of the Asset you specify in the Selected Asset setting.



Click image for full size.

Setting

Description

Selected Asset

The Asset in your Project that you want to spawn new instances of.

On Asset

On Asset operations apply only to Assets that match the Select By criteria you set for their steps. That means only items that you see listed in the Content Browser Preview panel on the left of the Dataprep preview UI. If your Select By criteria match other scene elements, like the Actors that are listed in the Outliner Preview panel on the right of the Dataprep preview UI, the On Asset operation will have no effect on those elements.

Output to Folder

This operation moves each Asset that matches the Select By criteria you set for this step into a subfolder with the name that you specify. You can use this block to customize the way the imported Assets are organized in your Project's Content Browser after you commit the results of your Dataprep graph.

The results of the Output to Folder block are not shown in the Content Browser Preview panel of the Dataprep Editor when you execute your Dataprep graph. You'll only see the results in your Project's Content Browser after you commit the Dataprep graph.



Click image for full size.

Setting

Description

Folder Name

The name of the subfolder that you want the selected Assets to be placed in when you commit your Dataprep graph.

You can use as many Output to Folder blocks as you want in your Dataprep graph. If you use the same Folder Name setting for different blocks, the Assets treated by those different blocks will be gathered together into a single folder. This allows you to redirect the Assets that result from several different filters in different Actions to the same folder in the Content Browser. By pairing multiple Output to Folder blocks with different filters, you can distribute your Assets into whatever organization you want to end up with in your Content Browser.

For example, in this case the main folder set in the settings panel at the top right of the Dataprep Editor is /Content/Motorbike. The first Action in this graph takes all Static Mesh Assets that have fewer than 1000 triangles and moves them to a subfolder named LowPoly. The second Action takes all other Static Meshes with more than 1000 triangles and moves them to a subfolder named HighPoly. Finally, the last two Actions take all Materials and all Material Instances and move them to a subfolder named Surfaces.



Click image for full size.

After you commit the Dataprep graph, the Content Browser has the following folder structure:



Click image for full size.

The Geometries and Materials subfolders normally created by the default Datasmith import process are still created, but in this case they are empty. All Assets have been redistributed to the new HighPoly, LowPoly, and Surfaces subfolders.

Replace Asset References

This block identifies the first Asset in the list of objects passed in. It then attempts to replace all references to the other Assets in the input list with references to the first Asset instead.

For example, suppose that the first object in the input list is a Static Mesh Asset named Chair. This block will look through all other objects in the input list to find other Static Mesh Assets — say, Table, Bench, and Dresser. It will then replace all references to Table, Bench, and Dresser with references to Chair anywhere they are found in the imported scene, and it will delete the Table, Bench, and Dresser Assets entirely.



Click image for full size.

Set Max Texture Size

By default, Datasmith scales imported textures to power-of-2 sizes. This operator sets a value that restricts the maximum in-game variable on a texture, but does not impact the import size of the texture.

The Max Texture Size field behaves like the Maximum Texture Size field on any Texture, rounding the value you entered to the nearest power-of-2 value.



Click image for full size.

On Mesh

On Mesh operations apply only to Static Mesh Assets.

If your Select By criteria match any Static Mesh Assets that you see listed under the Geometries folder in the Content Browser Preview panel, the operation will apply to those Assets.

If your Select By criteria match any Actors in the Outliner Preview that refer to Static Mesh Assets, the operation will also apply to those Static Mesh Assets.

If your Select By criteria match any other kinds of scene elements, like Actors, Textures, or Materials, the On Mesh operation will have no effect on those elements.

Bake Transform

For each Static Mesh Actor that matches the Select By criteria you set for this step, this operation creates a new mesh by baking the transform of the Static Mesh Actor directly into the mesh it refers to and replaces the Static Mesh Actor's mesh with this new mesh. This operation comes with several options:



Click image for full size.

Setting

Description

Bake Rotation

Bakes the current rotation as part of the operation. Enabled by default.

Bake Scale

Determines how the operation handles baking scale and includes the following options:

Bake Full Scale: Bakes all scale information, so the mesh has a scale of 1 on all axes

Bake Non Uniform Scale: Bakes the non-uniform scale information, so that the mesh has a uniform scale.

Do Not Bake Scale: Will not bake the scale as part of the operation.



Recenter Pivot

Translates the geometry of the new mesh so that the Static Mesh Actor's translation is positioned at its center.

Flip Faces

For each Static Mesh that matches the Select By criteria you set up for this step, this operation flips the facing direction of all triangles in the mesh.



Click image for full size.

This block can be helpful to reverse the orientation of meshes that were originally modeled in source applications that have different conventions for the visibility of backward-facing triangles. However, note that it is not selective: it reverses the facing direction of all triangles. If the facing direction of the triangles in your Static Mesh is mixed, so that some are visible and some are not, you may still need to make additional changes such as flipping faces by hand in the Static Mesh Editor, or using a Material with the Two Sided option enabled.

Generate Unwrapped UVs

For each Static Mesh that matches the Select By criteria you set up for this step, this operation unwraps the mesh geometry into a 2D UV map and saves the mapping in the specified UV channel on the Static Mesh Asset.



Click image for full size.

Setting

Description

Channel Selection

Determines what UV channel the generated UV mapping is saved to. First Empty Channel saves the unwrapped UV in the first empty UV channel. Specify Channel saves the unwrapped UV in the channel identified by the UV Channel setting.

UV Channel

When Channel Selection is set to Specify Channel, use this setting to determine the index of the UV channel that the unwrapped UV is saved to.

Angle Threshold

Determines the maximum angle between two adjacent faces for those faces to remain connected after unwrapping. Raising this value minimizes the number of separate UV "islands", keeping more triangles connected to their neighbors and reducing the number of seams that may cause breaks in texture mapping. However, this may also introduce more distortion in the wrapped textures, as triangles may need to be more aggressively resized in 2D space to remain connected to their neighbors.

Remesh

For each Static Mesh that matches the Select By criteria you set for this step, this operation uses isotropic remeshing to reach a triangle count matching the target value you specify. This operation comes with several options:



Click image for full size.

Setting

Description

Target Triangle Count

Specifies the target triangle count of the new mesh.

Smoothing Rate

Applies the specified amount of Vertex Smoothing during the remeshing process. Range from 0-1.

Discard Attributes

If set to True, discards existing UVs and Normals.

Remesh Type

Determines how many passes are applied during the remesh process:

Standard: Applies one pass over the entire mesh, then remeshes only changed edges.

Full Pass: Applies multiple full passes over the entire mesh. This enables the Remesh Iterations option where you can specify the number of incremental passes the tool makes.

Normal Flow: Applies one pass over the entire mesh, then remeshes only changed edges. Uses Normal flow to align triangles with the original input mesh.



Mesh Boundary

Determines how the boundary edges of an open mesh are preserved:

Fixed: Boundary edges are not split or collapsed.

Refine: Boundary edges are split and/or collapsed as needed.

Free: Boundary edges are split, but not collapsed.



Group Boundary

Determines how the boundary edges of a polygroup are preserved:

Fixed: Boundary edges are not split or collapsed.

Refine: Boundary edges are split and/or collapsed as needed.

Free: Boundary edges are split, but not collapsed.



Material Boundary

Determines how the boundary edges of a material region are preserved:

Fixed: Boundary edges are not split or collapsed.

Refine: Boundary edges are split and/or collapsed as needed.

Free: Boundary edges are split, but not collapsed.



Set Convex Collision

For each Static Mesh that matches the Select By criteria you set up for this step, this operation replaces the Static Mesh's collision with a new convex decomposition made up of multiple volumes, or hulls.



Click image for full size.

Setting

Description

Hull Count

The maximum number of convex volumes to create.

Max Hull Verts

The maximum number of vertices that are allowed for any generated convex hull.

Hull Precision

The number of voxels to use when generating the collision volumes.

Set LOD Group

For each Static Mesh that matches the Select By criteria you set up for this step, this operation replaces the existing LODs for the Static Mesh with new ones that are based on the settings for the group you specify.

These LOD groups are the same ones you can set when you enable automatic LOD generation in the Static Mesh Editor UI. For more information, see Setting Up Automatic LOD Generation.



Click image for full size.

Setting

Description

LOGGroupName

The name of the LOD group that defines the settings you want to use for this Static Mesh.

Set LODs

For each Static Mesh that matches the Select By criteria you set up for this step, this operation replaces the existing LODs for the Static Mesh with new ones that are based on the reduction settings you specify.

These reduction settings are the same ones you can set when you enable automatic LOD generation in the Static Mesh Editor UI. For more information, see Setting Up Automatic LOD Generation.



Click image for full size.

Setting

Description

Auto Screen Size

When enabled, the screen sizes at which LODs swap are automatically computed.

Reduction Settings

An array of reduction settings that defines how many Levels of Detail to create, and the percentage of triangles each should contain.

Set Simple Collision

For each Static Mesh that matches the Select By criteria you set up for this step, this operation replaces the existing collisions for the Static Mesh with a simple collision volume of the shape you specify.



Click image for full size.

Setting

Description

Shape Type

Defines the shape of the collision volume that you want to set for the Static Mesh.

Setup Static Lighting

For each Static Mesh that matches the Select By criteria you set up for this step, this operation sets up options that control how the Static Mesh interacts with baked lighting.



Click image for full size.

Setting

Description

Enable Lightmap UV Generation

When enabled, the operation generates lightmap UVs for the Static Mesh.

Resolution Ideal Ratio

A ratio between the scale of the Static Mesh geometry and the lightmap resolution to use for the Static Mesh. Raise this value to make your objects use higher resolution lightmaps. This may increase the quality of baked lighting, but also increases memory requirements.

Simplify Mesh

For each Static Mesh that matches the Select By criteria you set for this step, this operation simplifies the static mesh to a set percentage of its original triangle count. This operation comes with several options:

Setting

Description

Target Percentage

Target percentage of original triangle count

Discard Attributes

If set to True, discards existing UVs and Normals.

Mesh Boundary

Determines how the boundary edges of an open mesh are preserved:

Fixed: Boundary edges are not split or collapsed.

Refine: Boundary edges are split and/or collapsed as needed.

Free: Boundary edges are split, but not collapsed.



Group Boundary

Determines how the boundary edges of a polygroup are preserved:

Fixed: Boundary edges are not split or collapsed.

Refine: Boundary edges are split and/or collapsed as needed.

Free: Boundary edges are split, but not collapsed.



Material Boundary

Determines how the boundary edges of a material region are preserved:

Fixed: Boundary edges are not split or collapsed.

Refine: Boundary edges are split and/or collapsed as needed.

Free: Boundary edges are split, but not collapsed.



Weld Edges

For each Static Mesh that matches the Select By criteria you set for this step, this operation welds vertex pairs within a specified tolerance. If Only Unique is enabled, this operation only merges pairs of equivalent edges.



Click image for full size.

Set Collision Complexity

For each Static Mesh that matches the Select By criteria that you set for this step, this operation sets collision complexity on that mesh to the one you specify.



Click image for full size.

You can select from these four options:

Project Default, as defined in the Project Settings

Simple and Complex

Use Simple Collision as Complex

Use Complex Collision as Simple

Plane Cut

This operation requires you to enable the Dataprep Geometry Operations plugin.

For each Static Mesh that matches the Select By criteria that you set for this step, this operation cuts and removes geometry, such as performing boxing.

For instanced geometry, one of these two scenarios will happen:

If the full mesh is cut, it will no longer be instanced.

If the mesh is partially cut, this will produce a separate Actor for each former instance of the cut mesh.



Click image for full size.

This operation can use both local and world coordinates:

On Static Meshes, this operator will cut in their local referential coordinates.

On Static Mesh Actors, this operator will cut in world coordinates.

For example, consider the following scene:

Setting

Description

Plane's Origin

Defines the origin of the plane to be cut, expressed in local coordinates for Static Meshes, or world coordinates for Static Mesh Actors.

Plane's Orientation

Defines plane rotation in Euler angles, expressed in degrees. The default plane to be cut is XY.

Side(s) To Keep

Selects which side of the cutting plane to keep: Positive, Negative, or Both.

Spacing Between Halves

If you select to keep both sides, this defines the gap between the two sides.

Fill Holes

Enable this option to generate geometry that will fill the cut section.

Export Separated

Enable this option to save cut meshes as separate Assets.

On Object

On Object operations apply to potentially any kind of scene element matched by your Select By criteria.

Delete Objects

This operation deletes all objects that match the Select By criteria you set up for this step.



Click image for full size.

Delete Unused Assets

This operation deletes all Assets that match the Select By criteria you set up for this step and that aren't referenced by any other Assets or Actors.



Click image for full size.

Set Material

For each Static Mesh, Static Mesh Actor, or Component that matches the Select By criteria you set up for this step, this operation replaces all existing Materials with the Material you specify.



Click image for full size.

Setting

Description

Material

The Material you want to use as a substitute for all existing Materials.

Substitute Material

For each Static Mesh, Static Mesh Actor, or Component that matches the Select By criteria you set up for this step, this operation replaces any Material that matches the criteria with the substitute Material you specify.



Click image for full size.

Setting

Description

Material Search

The name or partial name of the Material or Materials you want to replace.

String Match

Defines the type of matching that you want to perform on the Material Search string. These options are interpreted the same way as when you use a string filter in a Select By block. For details, see Visual Dataprep Selection Reference.

Material Substitute

The Material you want to use as a substitute for the Materials that match the criteria above.

Substitute Material By Table

For each Static Mesh, Static Mesh Actor, or Component that matches the Select By criteria you set up for this step, this operation replaces Materials according to a substitution table that you provide in a DataTable Asset.



Click image for full size.

Setting

Description

Material Data Table

The Data Table Asset that determines what Materials are replaced by what other Materials.

The Data Table that you provide in the Material Data Table setting must use the MaterialSubstitutionDataTable row structure. You typically set this row format in the Pick Row Structure dialog box at the time you create your Data Table Asset. For example:



Click image for full size.

With this row structure, each row in the Data Table defines one Material substitution operation that will be executed on each of the Static Mesh Actors and Assets.

The first value in the row, Row Name, provides a name for the substitution. You can set this value freely.

The second value, Search String, is the name or partial name of the Material or Materials you want to replace in this operation.

The third value, String Match, is the type of string comparison you want to make between the Materials in the Static Mesh Assets and Actors and the search string you set in the second value of this row. You can use any of the values accepted by the Substitute Material operation: Exact Match, Contains, or Matches Wildcard. These options are interpreted the same way as when you use a string filter in a Select By block. For details, see Visual Dataprep Selection Reference.

The fourth value, Material Replacement, is the full name of the Material Asset you want to use to replace any Materials that match the search string.

You can get this value by right-clicking a Material in the Content Browser and selecting Copy Reference from the context menu.

For example:



Click image for full size.

Dataprep Selection Reference

Dataprep Operation Reference

Common Controls

Reference Selection Transform

Select Hierarchy

Select Actor Components

Select Owning Actor

Select Overlapping Actors

This page describes each of the Transform blocks that you can use in the Visual Dataprep system to change the objects selected for an Action.

Each type of Transform block encapsulates a specific type of modification that the Unreal Editor can make to the selection of Assets and Actors passed to it. The block then passes the modified selection on to the next block below it within the same Dataprep Action.

Transform blocks are like filters, in that they determine the set of Actors and Assets that other Dataprep blocks in the same Action will operate on. However, a filter block can only cut down the list of objects passed down to it. A Transform block, on the other hand, can add objects to the current selection.

Common Controls

All Transform blocks offer the Output Can Include Input setting.

When this setting is enabled, the Transform block always adds the Actors and Assets passed in to the block to the output selection that it passes on to the next block in the Dataprep Action.

When this setting is disabled, the Transform block only adds the Actors and Assets passed in to the block to the output selection if those Actors and Assets also pass the other selection criteria built in to the block.

Reference Selection Transform

This operation checks each Actor and Asset in the input list looking for references to other Assets in the temporary world. It then adds each referenced Static Mesh, Material, and Texture Asset that it finds to the output selection that it passes on to the next block.



Select Hierarchy

For each Actor passed in to this block, this transform looks for other Actors that are children of that input Actor. It then adds all of those child Actors to the output selection that it passes on to the next block.



Setting

Description

Select

Determines how deeply the selection extends into the descendants of each input Actor.

Use Immediate Children to have the output selection contain only Actors that are direct children of the Actors passed in to the transform block.

Use All Descendants to have the output selection recurse to include the complete hierarchies under the Actors passed in to the transform block.

Select Actor Components

For each Actor passed into this block, this transform looks for all Components of previously selected Actors. It then adds those Components to the output selection that it passes on to the next block.



Select Owning Actor

This transform looks for the parent Actor of each Component passed in to this block. It then adds the parent Actor to the output selection that it passes on to the next block.



Select Overlapping Actors

This transform requires you to enable the Dataprep Geometry Operations plugin.

Selects all Actors that fully or partially overlap previously selected Actors.



One of the goals of Datasmith is to support the widest range of industry standard 3D design applications used across industries including architecture, engineering, construction and manufacturing. For the most part, Datasmith treats each of these supported software applications and file formats in similar ways, and produces similar results, as described in the Datasmith Overview.

However, each of these supported applications and file formats presents unique challenges and opportunities for the import process. The guides listed below detail additional considerations that are specific to each different data source.



The Datasmith 3ds Max Exporter plugin brings content from Autodesk 3ds Max into the Unreal Editor.



How to import Datasmith scenes from Graphisoft Archicad into Unreal Engine.



Describes special considerations that apply only when you use Datasmith to bring scenes from Maxon Cinema 4D into the Unreal Editor.



Describes special considerations that apply when you use Datasmith to import scenes from 3DExcite Deltagen or Autodesk VRED.



Describes special considerations that apply only when you use Datasmith to bring scenes from Autodesk Navisworks into the Unreal Editor.



Describes special considerations that apply only when you use Datasmith to bring scenes from Autodesk Revit into the Unreal Editor.



Describes special considerations that apply when you use Datasmith to import scenes from McNeel Rhinoceros 3D.



Describes special considerations that apply only when you use Datasmith to bring scenes from Trimble SketchUp Pro into the Unreal Editor.



Describes how to install the Datasmith Solidworks Exporter plugin, how to get Solidworks content into Unreal Engine, and how Datasmith coverts Solidworks content.

Datasmith Overview

Datasmith Import Process

Datasmith 3ds Max Workflows

Installing the Datasmith Exporter plugin for 3ds Max

Pre-Install Checklist

Install or Remove the Plugin

Configuring an Unreal Engine Project for Datasmith

Enable the Datasmith Importer Plugin

This page provides a quick description of the Datasmith 3ds Max Exporter plugin, and instructions for how to install it.





Images courtesy of Litrix.

Datasmith 3ds Max Workflows

Use Datasmith to bring 3ds Max content into Unreal Engine in the following ways:

Export a .udatasmith file: export 3ds Max content as .udatasmith files, and import those files into Unreal Engine. For details, see Exporting Datasmith Files from 3ds Max.

Set up a Direct Link: create a live connection between an instance of 3ds Max and an instance of Unreal Engine (or another Unreal Engine-based application), then push 3ds Max content to Unreal Engine automatically or as-needed. For details, see Synchronizing 3ds Max and Unreal with Direct Link.

For detailed information about how Datasmith translates 3ds Max content for Unreal Engine, see How Datasmith Translates 3ds Max Content.

Installing the Datasmith Exporter plugin for 3ds Max

Before you can synchronize or export 3ds Max content, you must download and install the Datasmith 3ds Max Exporter plugin from the Datasmith Export Plugins page.

To see what versions of Autodesk 3ds Max the plugin supports, see Datasmith Supported Software and File Types.

Pre-Install Checklist

Before you install the Datasmith 3ds Max Exporter plugin:

Close all running instances of 3ds Max.

Download the installer for the exporter plugin that matches the Unreal Engine version you intend to use.

Uninstall all previous versions of the Datasmith 3ds Max Exporter plugin.

Install or Remove the Plugin

After you download the installer, open it, and follow the instructions on-screen.

If you need to uninstall the Datasmith 3ds Max Exporter plugin, you can do this from the Control Panel, like any other Windows application.

Configuring an Unreal Engine Project for Datasmith

To import a .udatasmith file into Unreal Engine, or synchronize a 3ds Max Scene with Unreal Engine, your project must have the Datasmith Importer plugin enabled. If you don't enable the plugin, you won't see the Datasmith options in Unreal Engine.

If your project uses the Architecture template, the Datasmith Importer plugin is enabled by default.

Enable the Datasmith Importer Plugin

In Unreal Engine, open the Plugins window: from the main menu, select Edit > Plugins.

In the left pane, select the BUILT-IN > Importer category.

In the right pane, enable the Datasmith Importer plugin.

Datasmith Overview

Datasmith Import Process

The 3ds Max Ribbon

Direct Link Panel

File Export Panel

Settings Panel

Tools Panel

The Datasmith Direct Link Connection Status Window

The Datasmith Messages Window

Enable Statistics for Direct Link

The 3ds Max Ribbon

When you install the Datasmith 3ds Max Exporter plugin, it adds a Datasmith tab to the 3ds Max ribbon (see Using the Ribbon in the 3ds Max documentation). You can access all of the Datasmith tools and settings for 3ds Max from the ribbon.





The Datasmith tab of the 3ds Max ribbon



Direct Link Panel

File Export Panel

Settings Panel

Tools Panel

Direct Link Panel

Option

Description

Synchronize

Pushes the 3ds Max scene or selection to the local Direct Link cache directory.Unreal Engine, and any other destination applications, monitors the cache, and updates the imported scene when it detects a change.You can change the location of the Direct Link cache directory. For details, see Change the Direct Link Cache Directory.

Toggle Auto Sync

When enabled, Datasmith automatically pushes the 3ds Max scene to the Direct Link cache whenever you make a change.Unreal Engine re-imports the scene whenever it detects a change to the cache.

Connections

Opens the Datasmith Direct Link Connection Status window.

File Export Panel

Option

Description

Export

Exports the 3ds Max Scene to a .udatasmith file that you can import into Unreal Engine, or an Unreal Engine-based application such as Twinmotion, or an Unreal Engine runtime application.Datasmith only exports visible objects.

Export Selected

Exports currently selected objects in the 3ds Max scene to a .udatasmith file that you can import into Unreal Engine, or an Unreal Engine-based application such as Twinmotion, or an Unreal Engine runtime application.Datasmith only exports visible objects.

Animated Transforms

Specifies how the Datasmith exporter handles objects with animated 3D transforms.

Current Frame Only: Datasmith exports objects in the scene as they appear in the current frame, without any animation data.

Active Time Segment: Datasmith exports animation data for any objects whose 3D transforms are animated in the active time segment in the 3ds Max timeline.

The Datasmith importer converts animation data into a Level Sequence, which you can use to play back the animations in Unreal Engine.

Settings Panel

Option

Description

Limit Texture Resolution

When Datasmith bakes procedural textures into images for import in Unreal Engine, this setting specifies the maximum number of pixels in the baked images. Possible values range from 4K (4096 pixels) to 16M (16 megapixels).For example, if you set this value to 4K, Datasmith limits textures to resolutions that contain 4096 pixels (64x64, 128x32px, and so on).This setting does not affect the size of raster textures, for example TIFF or JPEG files assigned as bump maps, diffuse maps, and so on.

Export XRef Scenes

Specifies whether to include XRef scenes in the exported .udatasmith file.XRef scenes are externally-referenced scenes that appear in your current file, but are loaded temporarily from other MAX files.For more information, see XRef Scene in the 3ds Max documentation.

Tools Panel

Option

Description

Messages

Opens the Datasmith Messages window.

Add Datasmith Attributes Modifier

Applies a Datasmith Attributes Modifier to currently selected objects.Datasmith Attributes Modifiers provide options to customize the way Datasmith exports specific objects.For details, see Per-Object Conversion Settings.

The Datasmith Direct Link Connection Status Window

The Datasmith Direct Link Connection Status window lists connections between the current instance of 3ds Max and instances of Unreal Engine or another Unreal Engine-based application such as Twinmotion.

Hover over any item in the list to display a tooltip with additional information about the connection.

The Connection Status window also has options for setting the Direct Link cache directory. For details, see Change the Direct Link Cache Directory.





The Datasmith Direct Link Connection Status window in 3ds Max



The Datasmith Messages Window

The Datasmith Messages window provides information about exports from 3ds Max to Unreal Engine. When you export a scene or a selection, the messages window displays some export statistics, and reports of any issues with the content. Typically, notifications alert you to things that the exporter couldn't translate perfectly, or that may not show up in the Unreal Engine in exactly the way they do in 3ds Max.





The Datasmith Messages window in 3ds Max



Enable Statistics for Direct Link

By default, the Datasmith Messages window only shows export statistics when you export a .udatasmith file. To enable export statistics for Direct Link Sync and AutoSync, enter the following command in the MaxScript console window :

Datasmith_SetExportOption_StatSync true

Point Lights

Spot Lights

Rectangular Area Lights

Post Process Effects

Datasmith Overview

Datasmith Import Process

Geometry

Meshes and Tessellation

Instances

Pivot Points

UV Channels

Custom Collision Shapes

Vertex Colors

Levels of Detail

Forest Pack and RailClone Objects

XRef Scenes

Lighting and Rendering Environment

Lights

Exposure

Cameras

Materials

Procedural Textures

Metadata

Conversion Notes and Warnings

Notes and Warnings in 3ds Max

Notes and Warnings in Unreal Engine

When Datasmith translates scenes from Autodesk 3ds Max into Unreal Editor, it follows the process outlined in Datasmith Overview and Datasmith Import Process, but adds some special translation behavior that is specific to 3ds Max.

Read this page to better understand how the Datasmith exporter translates your scene, and how to work with the results in Unreal Editor.

Geometry

This section describes how Datasmith converts geometric objects in a 3ds Max scene into Static Mesh Assets and Actors in an Unreal Engine Project.

Meshes and Tessellation

In most cases, Datasmith uses each 3ds Max object's render mesh to create the geometry for the corresponding Static Mesh Asset in Unreal Engine. Assets in Unreal Engine usually have exactly the same triangles that you see in 3ds Max renderings.

For 3ds Max Body Objects (see Body Objects Category in the 3ds Max documentation), Datasmith bases the geometry of the Static Mesh Asset on the 3ds Max viewport mesh instead of the render mesh.

You can control the granularity of the tessellation that 3ds Max uses to render in a viewport:

In the Viewport Display Settings rollout, set Mesh Quality Presets to Coarse, Medium, or Fine.

Datasmith respects the level of tessellation you set for each Body Object in the scene.

For more information about the Mesh Quality Presets setting, see Viewport Display Settings Rollout in the 3ds Max documentation

Instances

When Datasmith detects multiple instances of the same master object in your 3ds Max scene, it creates one Static Mesh Asset for that object, and places multiple instances of that Static Mesh into the Level in Unreal Engine.

We recommend using instances in 3ds Max for repeating elements in your scene, such as windows, doors, or chairs. Instances are usually better for an Unreal Engine project's runtime memory requirements and performance. It also helps you manage content by reducing the number of Static Meshes.

For more information about instances, see Creating Copies, Instances, and References in the 3ds Max documentation.

Pivot Points

In 3ds Max, you can set a custom pivot point for each object in your scene, even when those objects are instances of the same master object. In Unreal Engine, all instances of the same geometry need to use the same pivot point.

If object instances in your 3ds Max scene have custom pivot points, Datasmith tries to replicate the custom pivot points. How Datasmith translates pivot points depends on whether or not all of the instances in 3ds Max use the same pivot point.

Datasmith does not support importing instances that have both different pivot points and a non-uniform scale in 3ds Max. If you have instances like this, use the Reset XForm Utility on them before you export.

If all instances in 3ds Max have the same custom pivot point, Datasmith sets it as the pivot location for the Static Mesh Asset it creates. When you rotate any Static Mesh Actor that Datasmith creates for this object in the Unreal Engine Level, it rotates around the location of that custom pivot as expected.

If one or more instances use a different pivot location from the others, Datasmith does the following.

Sets the Static Mesh Asset it creates in Unreal to use the default pivot location of the 3ds Max object.

When it places the Asset in the Unreal Engine Level, Datasmith creates a new, empty parent Actor at the location of the custom pivot for that instance instead of creating a Static Mesh Actor.

Finally, Datasmith gives the parent Actor a Static Mesh Component that:

References the Static Mesh Asset.

Has a translation offset from the parent Actor that places it where it needs to be in the 3D scene.

Has a _pivot suffix appended to its name.

When you move, rotate and scale the parent Actor in the Unreal Engine Level, the model behaves as you expect. All you need to note is that the model is a Component of the parent Actor, rather than being a Static Mesh Actor itself.

For example, in the following image, the teapot on the right uses the default pivot point, while the teapot on the left has a custom pivot at the top of its lid.





Click image to expand.



When Datasmith brings the scene into Unreal, it creates a Static Mesh Actor for the teapot on the right. For the teapot on the left, it does the following:

Creates a new Actor called Teapot002, at the location of that pivot point in the 3D world.

Gives the Teapot002 Actor a Static Mesh Component named Teapot002_2, which refers to the Static Mesh asset for the teapot.

Offsets Teapot002_2 from its parent Actor, Teapot002, by exactly the right amount to position it correctly, relative to the other geometry in the scene.





Click image to expand.



UV Channels

Datasmith ensures that every Static Mesh it brings into Unreal Engine has a set of UVs that Lightmass can use to build static lighting into lightmap textures (see Global Illumination). When you synchronize a 3ds Max scene or import a Datasmith file, Unreal Engine creates that UV channel automatically. Every Static Mesh Asset uses the new channel for baking lightmaps.

You can also create custom lightmap UVs in 3ds Max, and use those instead. In that case, it's important to understand how Datasmith brings UVs into Unreal from 3ds Max, and how you can override that behavior.

The next section describes how Datasmith imports UVs from 3ds Max.

The following section, Use Custom Lightmap UVs, explains how to override Datasmith's default import behavior.

Unreal Engine supports up to eight UV channels per Static Mesh. Datasmith uses two of them to generate lightmap UVs. That means Datasmith can preserve up to six pre-existing UV channels for each object that it imports from 3ds Max. In 3ds Max, an object can have up to 99 UV channels, and you don't have to set channel indexes sequentially. Datasmith exports the six channels with the lowest indexes.

When Datasmith imports UV channels, it does the following:

Resets the UV channel indexes to begin at 0

Maps the lowest index in 3ds Max to the lowest index in Unreal, second lowest to second lowest, and so on.

Creates two additional channels for auto-generated lightmaps

For example, the table below shows how Datasmith reindexes UV channels when it imports a 3ds Max object with five channels whose indexes are not fully sequential. Notice that:

In addition to channels 0-4, Datasmith adds channels 5 and 6 for lightmaps.

While there are large gaps between some of the 3ds Max UV indexes, Datasmith remaps each index to the lowest available slot in Unreal Engine.

3DS Max UV Channel

Unreal UV Channel

Notes

1

0

2

1

3

2

10

3

99

4

5

Generated during import to create an automatic unwrap of the geometry contained in the Datasmith scene. It is the basis for the lightmap UV generation used by UV channel 6.

6

Generated based on UV channel 5 to correctly pad and pack the UV charts based on the Datasmith Import Options used for the Static Mesh Lightmap Resolution values.

If you want imported Static Meshes to use pre-existing UV channels that you created in 3ds Max, you have two options.

Option 1: Before you export your scene from 3ds Max, apply a Datasmith Attributes Modifier to specify the index of the UV channel you want Unreal Engine to use for lightmaps. For details, see Per-Object Conversion Settings.

Option 2: After you import your scene into Unreal Editor, you can change the index of the UV channel you want Unreal Engine to use for lightmaps.

In the Content Browser, double-click the Static Mesh Asset whose lightmap UV index you want to change.The Static Mesh Editor opens.

In the Details panel, navigate to General Settings > Advanced, and set Light Map Coordinate Index to the UV channel you want to use.

Alternatively, you can change the lightmap UV index in Python. Call the following function:

static_mesh.set_editor_property("light_map_coordinate_index", index)

Custom Collision Shapes

To improve the behavior and performance of the physics simulation in Unreal Engine, you can model custom geometry for an object in 3ds Max, and use it as the collision mesh for the corresponding Static Mesh in Unreal Engine. The idea is to make the custom geometry match the volume of the original scene object as closely as possible, but minimize the number of triangles it contains.

The next section, Considerations for Using Custom Collision Shapes explains what you need to consider when you use custom collision shapes.

The following section, Set up Custom Collision Shapes, describes how to set up custom collision shapes.

When you use custom collision shapes, the object that you set as a collision mesh can be any completely closed, convex 3D shape. For example, a box. The following diagram illustrates what kinds of shapes are and aren't acceptable.



Also make sure that the pivot point of your custom geometry is at the same location relative to its volume as the pivot point of the original object. For example, in the following image, both the chairs on the right, and the simplified representation on the left have pivot points in the bottom center of their volumes.



If you don't keep the pivot point of your collision geometry at the same place relative to the overall volume, the representation of your object in the physics world won't align with the visible extents of the object. This can cause collisions to happen where you are not expecting them.

To set up custom collision shapes in 3ds Max so that Datasmith imports them into Unreal engine, use a Datasmith Attributes Modifier. In 3ds Max, assign the Modifier to one or more objects in your scene, then use it to specify the object you want Unreal Engine to use as a collision mesh. For details, see Set a Custom Collision Volume in Per-Object Conversion Settings.

To verify that Datasmith imported custom collision shapes correctly, turn on collision rendering in the Level Viewport.

From the Viewport overlay menu, select Show > Collision.

Unreal Engine renders the custom collision volumes on top of your scene objects. The following image shows a sphere that uses a box object as its custom collision volume.





Click for full image.



Vertex Colors

When you associate vertex colors with your 3ds Max objects, Datasmith preserves them when it creates corresponding Static Mesh Assets in the Unreal Engine.

Datasmith does not translate data from other 3ds Max mesh channels, such as Vertex Alpha, Map Channel Color, or Soft Selection Color.

You can use these vertex colors when you create a custom Material in Unreal Editor by including the Constants > Vertex Color node in your Material Graph.

For example, the following images show an object in 3ds Max that is set to display its vertex colors, and a simple custom Material in Unreal Engine that retrieves the vertex colors and passes them directly into the Base Color output.





Vertex colors displayed in 3ds Max. Click image to expand.







Vertex colors displayed in Unreal Engine. Click image to expand.



You can visualize your vertex colors in Unreal Engine to make sure that Datasmith translated them correctly.

In the Content Browser, double-click a Static Mesh Asset to open it in the Static Mesh Editor.

From the Viewport toolbar, select Show > Vert Colors.

Vertex colors in a custom Material Graph can do more than just provide the visible color for a surface. You can also combine and blend them with other surface properties.

Alternatively, you can use vertex colors to associate custom data values with the geometry of your source objects, and pass those values to custom Materials in Unreal Editor to drive visual effects.

For example, you could use vertex colors to assign weights to the branches and leaves of a tree, and use those weights to modulate the effect of a wind animation effect that you apply in a vertex shader.

Levels of Detail

Datasmith does not import custom Levels of Detail that you set up in 3ds Max. You can generate new Levels of Detail automatically in Unreal Editor. For details, see Automatic LOD Generation, or Creating Levels of Detail in Blueprints or Python.

Forest Pack and RailClone Objects

iToo Software's Forest Pack and RailClone are plugins for 3ds Max that scatter, or place large numbers of geometric objects procedurally to help you populate scenes.

When you use Datasmith to import or sync a 3ds Max scene that contains a Forest Pack or RailClone object in Unreal Engine, Datasmith creates a single Actor in the Unreal Engine Level, and names it according to the name of the object in 3ds Max.

Within the Actor, Datasmith creates the following for each type of geometry that the object handles:

A Hierarchical Instanced Static Mesh (HISM) Component.

A Static Mesh Asset in your Project content.

Datasmith then sets each geometry type's HISM Component to refer to its Static Mesh Asset.

Within each HISM Component, Datasmith adds one instance of the Static Mesh asset for each instance that's visible in the 3ds Max scene, and matches the position and rotation of each instance in 3ds Max.

This import process produces an Unreal Engine Level that closely matches the original 3ds Max scene visually and structurally, meaning that in the scene hierarchy, one Forest Pack or RailClone object internally manages all its instances.





The HISM Component is the same technology used in Unreal Engine's Foliage system. It's a very efficient way to render many instances of the same Static Mesh. The Unreal Engine renderer batches all instances managed by the same HISM Component, and makes a single draw call per Material assigned to the Static Mesh Asset. By using the HISM, the renderer can handle more instances without affecting GPU performance or frame rate.

You might want to use Forest Pack or RailClone to manage objects with complex geometry, such as trees, that you intend to replace in Unreal Engine with simpler geometry that performs more efficiently in real time.



To replace a Forest Pack or RailClone object with simplified geometry:

Apply a Datasmith Attributes Modifier to the Forest Pack or RailClone object in 3ds Max, and set it to export only the bounding box of the geometry.For instructions, see the Export the Bounding Box Only section of Per-Object Conversion Settings.

Sync or import the 3ds Max scene.

To update all instances in the Unreal Engine Level to use a new Static Mesh, edit the HISM Component, and, in the Details panel, change the Static Mesh setting.

XRef Scenes

XRef scenes are externally-referenced scenes that appear in your current file, but are loaded temporarily from other MAX files. For more information, see XRef Scene in the 3ds Max documentation. If your scene references one or more XRef Scenes, Datasmith exports them by default.

To prevent Datasmith from exporting XRef Scenes:

From the Datasmith tab of the 3ds Max ribbon, go to the Settings panel, and disable Export XRef Scenes.

Lighting and Rendering Environment

3ds Max offers much more detailed and sophisticated lighting and rendering features than many of the other third-party applications that Datasmith supports. This section describes how Datasmith tries to bring 3ds Max lighting and rendering data into Unreal Engine.

Lights

Datasmith translates a variety of 3ds Max light types, including Standard, Photometric, V-Ray, and Corona lights. For each light, Datasmith brings the following light information into Unreal:

Position, orientation, shape and size in 3D space.

Light type (for example, point light or spot light).

Intensity, units, lamp color, temperature, and filter color.

Render shape visibility.

IES light profiles.





Point lights with IES profiles and scaled Kelvin temperatures. Middle: Point lights with IES profiles and scaled light intensity. Bottom: Spot lights with filter color.

Datasmith tries to approximate the lighting you set up in 3ds Max as closely as possible, but you'll probably have to adjust your Level's lighting after you import a scene into Unreal Engine to make the results look the way you expect, and to optimize lighting performance at runtime. Usually you tweak the Level's lighting by adjusting the post-processing exposure value.

A few notable differences between 3ds Max and Unreal Engine when you use Datasmith:

Unreal Engine currently does not support instances for lights. For each instanced light in your 3ds Max scene, Datasmith creates a separate Light Actor in your Unreal Engine Level.

Although lights are not instanced in Unreal Engine, you can still edit all of them at once by selecting them and changing their properties in the Detail Panel.

Standard lights in 3ds Max are unitless, and they allow custom attenuation parameters that Unreal Engine does not support.

Some V-Ray shapes are not supported, such as Vertical Cylinder, Spheroid, and Custom Mesh lights.

Area lights are handled using a special Blueprint class. For details, see Datasmith Import Process.

Exposure

Datasmith preserves the intensity of 3ds Max lights, but intensity is not enough to ensure that the scene renders well. The Unreal Engine renderer needs a context to interpret light intensity in, so it can determine the luminance of the scene: how bright or dark the scene should appear in the final rendering.

Part of the context comes from the exposure of the camera or view — a set of physical characteristics that govern how sensitive the final image should be to the intensity of light in the scene.

Datasmith also translates several exposure values from 3ds Max.

See the following sections for details:

Physical Camera Exposure Settings

Global Exposure Settings

Auto-Exposure

If your 3ds Max scene contains a Physical Camera, Datasmith preserves its exposure and white balance settings and carries them over to the corresponding Cine Camera Actor the Unreal Engine Level.

For each camera, Datasmith sets the following settings in Unreal Engine to match their equivalents in 3ds Max.

WhiteBalance > Temp

Shutter Speed

ISO

Aperture (f-stop)

It also sets the Exposure > Metering Mode to Manual, which disables auto-exposure.

When you view your Level through the camera, you'll see light levels that closely match the rendered results in 3ds Max.





For more information about Cine Camera Actor settings see Cine Camera Actor.

If your Exposure Control setting in 3ds Max uses either the Physical Camera Exposure Control or VRay Exposure Control, Datasmith creates a Post Process Volume in the Datasmith Scene that applies those global exposure settings to the whole Unreal Engine Level.

In 3ds Max, the exposure settings are in the Environment and Effects dialog. From the main menu, select Rendering > Exposure Control...

Datasmith sets the following settings for the Post Process Volume in Unreal Engine to match their equivalents in 3ds Max.

WhiteBalance > Temp

Shutter Speed

ISO

Aperture (f-stop)

It also sets the Exposure > Metering Mode to Manual, which disables auto-exposure.

When you view your Level using the default perspective camera in the Unreal Editor Viewport, you'll see light intensities that closely match the rendered result from 3ds Max.





In 3ds Max, the global white balance and exposure settings do not have to match the settings assigned to Physical Cameras. If this is the case, and you render the scene from the point of view of a perspective camera, the renderer uses your global exposure settings rather than the settings assigned to any specific Physical Camera.

The same thing happens in Unreal Engine. When you view the scene through the default camera in the Level Viewport, Unreal Engine uses exposure settings that are either global to the Project or come from the active post processing volume. When you view the scene through any Cine Camera Actor, Unreal Engine uses that camera's exposure settings.

Unreal Engine has a built-in auto-exposure system. It monitors the amount of light that reaches the camera, and automatically adjusts the exposure so the final image appears at a reasonable level of luminance.

The auto-exposure system is active by default. For more information about auto-exposure in Unreal Engine see Auto Exposure.

Cameras

For every camera in your 3ds Max scene, Datasmith creates a Cine Camera Actor in Unreal Engine, at the same position and rotation in 3D space, and tries to preserve the camera's focal properties as much as possible. Ideally, viewing the Level through a camera in Unreal Engine is as similar as possible to viewing the scene rendered from the corresponding camera in 3ds Max.

If a camera in 3ds Max has a target, Datasmith sets the Cine Camera Actor to track the corresponding Actor in Unreal Engine. When you move the target Actor around in the Unreal Engine Level, the Cine Camera Actor automatically rotates to track the target Actor.

For more information about how Datasmith translates exposure settings for physical cameras, see Physical Camera Exposure Settings.

Materials

When Datasmith imports a 3ds Max scene into Unreal Engine, it creates one or more parent Material Assets in the project's Materials / Master folder. For each parent Material, it tries to create a Material Graph that uses Unreal Engine's physically-based renderer to produce results that are equivalent to what you see when you render the scene in 3ds Max.

Datasmith imports each material in your 3ds Max scene as a new instance of a parent Material. Not every Material Instance has its own parent. If two different Material Instances can share the same Material Graph, Datasmith attempts to use the same parent Material for both instances.

Datasmith can usually translate 3ds Max Materials with a single shading model and a relatively simple graph well. For example, the material in the following image.



Even for simple materials, a parent Material Asset's graph often looks different from the corresponding material in 3ds Max. When Datasmith converts between shading models, it attempts to preserve the visual result as closely as possible, even if that means adding connections or constants to the graph.

3ds Max supports several other shading models for materials, such as V-Ray, Corona, Mental Ray, and more. Each shading model is a separate piece of software, with unique features that are not always consistent with one another. Datasmith can convert some features into similar features in Unreal Engine, but might not be able to handle some of the more complex or special-purpose ones.

For example, materials with complex graphs that mix multiple output shaders together might be difficult or impossible for Datasmith to reproduce in Unreal Engine. You need to do some extra work after importing the scene to adjust or replace them. The graph in the following image is a good example.

Click for full image.

Procedural Textures

If your 3ds Max scene uses procedural textures, Datasmith exports them as baked textures that it uses in the Unreal Engine Materials it creates. Datasmith saves these baked textures as .tga files. For more information about hoe Datasmith creates materials, see Materials.

Both the number and the size of the textures in the scene affect how long it takes to export from 3ds Max and import into Unreal Engine. You can limit the resolution of baked and procedural textures to improve import export performance. This is especially useful for large scenes with complex materials.

This setting does not affect the size of raster textures, for example TIFF or JPEG files.

To specify the export resolution for baking procedural textures:

From the Datasmith tab of the 3ds Max ribbon, go to the Settings tab, and set Limit Texture Resolution to the desired value.

Values specify the number of pixels in the target resolution, and range from 4K (4096 pixels) to 16M (16 megapixels).

For example, if you set the resolution limit to 4K, Datasmith limits textures to resolutions that contain 4096 pixels, whether that's 64x64, 128x32px, or another set of width/height values.

Metadata

Add your metadata to your 3ds Max objects on the User Defined tab of the Object Properties window.



To get to this panel for a mesh in 3ds Max:

Select the mesh in the outliner or the viewport.

Right-click and choose either Properties or Object Properties from the context menu, or select Edit > Properties from the main menu.

Enter your metadata into this panel as key = value pairs, as shown above.

Be certain to leave a space on both sides of the equal (=) sign. If you don't, Datasmith won't recognize your metadata, and won't import it as expected.

You can also set up user-defined properties using MAXScript.

If your model was originally created in Revit and then imported into 3ds Max, the user-defined properties should already be preset by the 3ds Max importer with the model's BIM information.

Conversion Notes and Warnings

You can get information about the Datasmith conversion process:

In 3ds Max, after you export or synchronize a scene.

In Unreal Engine, after you synchronize or import a scene.

Notes and Warnings in 3ds Max

After Datasmith exports your 3ds Max scene, it lists statistics, notes, problems, warnings or errors that it encountered during the process in the Messages Window (see The Datasmith Messages Window).

If you use Direct Link to synchronize 3ds Max and Unreal Engine, Datasmith does not output statistics by default. To enable export statistics for Direct Link Sync and AutoSync, enter the following command in the MaxScript console window:

Datasmith_SetExportOption_StatSync true

Messages notify you about elements in your scene that might not translate to Unreal Engine exactly as you expect. For example:

Problems with your source scene, such as missing images. You might want to fix these problems in 3ds Max before you export again.

Things in your 3ds Max scene that either Datasmith or the Unreal Engine doesn't support.

Things that Datasmith converted in a way you might not be expecting.

Notes and Warnings in Unreal Engine

After you import your Datasmith scene into the Unreal Editor, you can find information about conversion issues you might need to clean up in the Output Log (from the main menu, select Window > Output Log).

As a starting point, try filtering the Output Log to show only warnings. From the Output Log toolbar, disable Filters > Messages, and Filters > Errors.

Datasmith Overview

Datasmith Import Process

Export a .udatasmith File

Export Settings

File Export Panel Settings

Settings panel Settings

You can export 3ds Max content as .udatasmith files that you can import into Unreal Engine. You can export an entire scene, or a specific selection. In either case, Datasmith only exports objects that are visible in 3ds Max.

To import a .udatasmith file into Unreal Engine, your Unreal Engine project must have the Datasmith Importer plugin enabled. If you don't enable the plugin, you won't see the Datasmith options in Unreal Engine. For more information, see Enable the Datasmith Importer Plugin.

Export a .udatasmith File

From the Datasmith tab of the 3ds Max ribbon, do the following:

Configure the export settings as needed (see Export Settings below).

If you plan to export a specific selection, select the objects you want to export. If you plan to export the entire scene, skip this step.

Do one of the following:

To export the entire scene, click Export.

To export the current selection, click Export Selected.

In the Export Datasmith File dialog, choose a name and location for the exported file. Make sure Save as type is set to Datasmith (*`.udatasmith`), and click Save.

Export Settings

All of the 3ds Max export settings are on the Datasmith tab of 3ds Max ribbon, either in the File Export panel or the Settings panel

File Export Panel Settings

Expand the File Export panel to display the following settings:

Option

Description

Export

Exports the 3ds Max Scene to a .udatasmith file that you can import into Unreal Engine, or an Unreal Engine-based application such as Twinmotion, or an Unreal Engine runtime application.Datasmith only exports visible objects.

Export Selected

Exports currently selected objects in the 3ds Max scene to a .udatasmith file that you can import into Unreal Engine, or an Unreal Engine-based application such as Twinmotion, or an Unreal Engine runtime application.Datasmith only exports visible objects.

Animated Transforms

Specifies how the Datasmith exporter handles objects with animated 3D transforms.

Current Frame Only: Datasmith exports objects in the scene as they appear in the current frame, without any animation data.

Active Time Segment: Datasmith exports animation data for any objects whose 3D transforms are animated in the active time segment in the 3ds Max timeline.

The Datasmith importer converts animation data into a Level Sequence, which you can use to play back the animations in Unreal Engine.

Settings panel Settings

Option

Description

Limit Texture Resolution

When Datasmith bakes procedural textures into images for import in Unreal Engine, this setting specifies the maximum number of pixels in the baked images. Possible values range from 4K (4096 pixels) to 16M (16 megapixels).For example, if you set this value to 4K, Datasmith limits textures to resolutions that contain 4096 pixels (64x64, 128x32px, and so on).This setting does not affect the size of raster textures, for example TIFF or JPEG files assigned as bump maps, diffuse maps, and so on.

Export XRef Scenes

Specifies whether to include XRef scenes in the exported .udatasmith file.XRef scenes are externally-referenced scenes that appear in your current file, but are loaded temporarily from other MAX files.For more information, see XRef Scene in the 3ds Max documentation.

Datasmith Overview

Datasmith Import Process

Update the Direct Link Cache

Import the 3ds Max Scene with Direct Link

Change the Direct Link Cache Directory

The Datasmith Export for 3ds Max plugin supports Datasmith Direct Link (see Using Datasmith Direct Link). Direct Link works by exporting your 3ds Max scene to a local cache. When you connect 3ds Max to Unreal Engine, or another connected application such as Twinmotion, it imports the scene from the cache.

To synchronize a 3ds Max Scene with Unreal Engine, your Unreal Engine project must have the Datasmith Importer plugin enabled. If you don't enable the plugin, you won't see the Datasmith options in Unreal Engine. For more information, refer tosee Enable the Datasmith Importer Plugin.

To synchronize a 3ds Max Scene with Unreal Engine:

Update the Direct Link cache (see Update the Direct Link Cache).

Use Direct Link to Import the 3ds Max scene into Unreal Engine (see Import the 3ds Max Scene with Direct Link).

If you perform a Direct Link import before you update the cache, Unreal Engine will display an error message because there is nothing in the cache to import.

Update the Direct Link Cache

From the 3ds Max ribbon, use the synchronize options in the Direct Link panel of the Datasmith tab.

Synchronize: Performs a one-time push to the Direct Link Cache. When Unreal Engine, or another connected application, connects to 3ds Max via Direct Link, it imports the cache.Use this command if you want to control when Unreal Engine displays changes to the 3ds Max scene.

Toggle Auto Sync: When enabled, Datasmith pushes the 3ds Max scene to the Direct Link cache every time you make a change. Unreal engine and any other connected applications re-import the cache automatically.Use this command if you want Unreal Engine to update whenever you make a change to the 3ds Max scene.

Import the 3ds Max Scene with Direct Link

In 3ds Max, open the scene you want to import into Unreal Engine, and update the Direct Link cache.

In Unreal Engine, in the main toolbar, open the Create menu and select Datasmith > Direct Link Import. The Direct Link Available Sources dialog opens.

If you have more than one instance of 3ds Max open, each instance appears as a separate source in the Direct Link Available Sources dialog.



Select the 3ds Max source that you want to import into Unreal Engine, and click Select. A file dialog opens.

Choose a location in your project to store the imported content, and click OK. The Datasmith Import Options dialog opens.

To create a new top-level folder for your Datasmith content, right-click an empty area in the file dialog. To create a subfolder of an existing folder, right-click that folder.



Set the import options as needed, and click Import. For more information about the Datasmith Import options, see Importing Datasmith Content Into Unreal Engine.

Change the Direct Link Cache Directory

When you connect 3ds Max to Unreal Engine using Direct Link, Datasmith uses a cache directory to temporarily store the contents of your Datasmith scene. For example, sent and received .udatasmith scenes, meshes, textures, and so on.

You can change the cache directory from the Connection Status window:

From the Direct Link panel of the Datasmith tab in the 3ds Max ribbon, select Connections.The Connection Status window opens.

Click the more options button (⋮) to display the Cache Directory setting.

Click the ellipsis button (...) to open a file dialog.

Navigate to the directory you want to use, and click Select Folder.

The cache location updates the next time you open or create a 3ds Max file and synchronize it with Unreal Engine.

To reset the cache to the default directory, click Reset.

Datasmith Overview

Datasmith Import Process

Apply a Datasmith Attributes Modifier

From the 3ds Max Ribbon

From the Modify Panel

Specify a Lightmap UV Index

Verify the UV Index in Unreal Engine

Set a Custom Collision Volume

Export the Bounding Box Only

Bounding Box Export Example

Apply a Datasmith Attributes modifier to objects in a 3ds Max scene to customize the way Datasmith translates individual scene objects from 3ds Max to Unreal Engine.

You can:

Specify the index for the UV channel that you want to use for lightmaps you create in Unreal Engine. See Specify a Lightmap UV Index.

Assign custom collision geometry for objects in your scene. See Set a Custom Collision Volume.

Export objects as simplified bounding boxes, instead of their full geometry. See Export the Bounding Box Only.

Apply a Datasmith Attributes Modifier

In 3ds Max, you apply a Datasmith Attributes modifier from the ribbon, or the Modify panel.

By default, the modifier does not change the export behavior described in How Datasmith Translates 3ds Max Content. To customize that default behavior, you need to change the modifier's settings.

From the 3ds Max Ribbon

The easiest way to apply a Datasmith Attributes modifier to objects in your 3ds Max scene is from the 3ds Max ribbon.

Select the object or objects whose export settings you want to customize.

On the Datasmith Tab, of the 3ds Max Ribbon, select Add Datasmith Attributes Modifier from the Tools panel.

From the Modify Panel

You can also apply a Datasmith Attributes modifier exactly the same way as you apply any other kind of modifier in 3ds Max. For more information, see Modifiers in the 3ds Max documentation.

Select the object or objects whose export settings you want to customize.

Open the Modify panel.

From the Modifier List drop-down menu, find and select OBJECT-SPACE MODIFIERS > Datasmith Attributes.

Specify a Lightmap UV Index

By default, Datasmith creates two new UV channels for each geometric object in your scene (see UV Channels in How Datasmith Translates 3ds Max Content). One channel is a lightmap UV, which stores precomputed lighting, and ensures every object is compatible with Static and Stationary lighting in Unreal Engine.

If you've already created lightmap UVs for your objects in 3ds Max, you might want to use those instead. You can use the Datasmith Attributes modifier to make your objects use the lightmap UVs that you created in 3ds Max. In that case, Datasmith doesn't generate additional UVs when you import your scene into Unreal Engine.

To specify a lightmap UV index:

In 3ds Max, select the objects that you created lightmap UVs for.

Apply a Datasmith Attributes modifier (see Apply a Datasmith Attributes Modifier).

In the Datasmith Attributes modifier settings, do the following:

Set Lightmap UVs to Specify Lightmap Channel.

Set Map Channel to the index of the UV channel that you want the selected objects to use for precomputed lighting.

When you sync the scene with Unreal, or export it and import it into Unreal Engine, the objects with the Datasmith Attributes modifier applied use the Map Channel you specified. Datasmith does not create any new UV channels.

For more information about UVs in Unreal Engine, see Using UV Channels With Static Meshes.

Verify the UV Index in Unreal Engine

To verify that Unreal Engine is using the correct lightmap UV index settings, do the following:

In the Content Browser, find a Static Mesh Asset that corresponds to one of the objects you created lightmap UVs for in 3ds Max.

Double click the Asset to open it in the Static Mesh Editor.

In the Details panel, look for the General Settings > Light Map Coordinate Index setting. This value should correspond to the UV channel that you identified in 3ds Max.

Depending on how Datasmith re-indexes the UV channels when it imports the object into Unreal Engine, the index number shown in the Light Map Coordinate Index setting might not match the number you set in the Datasmith Attributes modifier.

To verify that the index refers to the UV layout that you are expecting, you can display your lightmap in the Static Mesh Editor.

From the Static Mesh Editor Toolbar, select UV > [UV INDEX NUMBER] where UV INDEX NUMBER is the number in the Light Map Coordinate Index setting.

The Static Mesh Editor displays the lightmap in the bottom left of the viewport.

Set a Custom Collision Volume

You can use the Datasmith Attributes modifier to specify an object for Unreal Engine to use as the collision mesh for other scene objects. The collision mesh object must be fully convex, and it must have its pivot located at the same location relative to its volume as the original object. For more information, see Custom Collision Shapes in How Datasmith Translates 3ds Max Content.

To set a custom collision volume:

In 3ds Max, select the objects that you want to set a custom collision mesh for.

Apply a Datasmith Attributes modifier (see Apply a Datasmith Attributes Modifier).

In the Datasmith Attributes modifier settings, do the following:

Enable Use Custom Collision Mesh.

Click Pick Geometric Object.

In the 3ds Max viewport or Outliner panel, select the object that you want to act as the collision mesh.

When you sync, or re-import the scene into Unreal Editor, the object you assigned the Datasmith Attributes modifier to has a new collision volume in the shape of the collision mesh object.

Export the Bounding Box Only

Sometimes, you might want Unreal Engine and 3ds Max to use different geometry for the same scene objects. For example, if your 3ds Max scene contains complex or very dense geometry that you use in offline rendering, you might want to use less complex versions in Unreal Engine because they perform more efficiently in real time.

You can use the Datasmith Attributes modifier to identify objects whose geometry you want to replace with simplified representations when you export the scene. Instead of exporting the full geometry, Datasmith creates lightweight geometric representations of the object based on each object's 3D bounding box.

When you sync, or import the scene into Unreal Engine, the scene objects you marked with the Datasmith Attributes modifier have their original geometry replaced by simple gray bounding volumes. They have the same names and locations as the original objects.

To export bounding box representation of selected objects.

In 3ds Max, select the objects for which you want to set export a bounding box representation..

Apply a Datasmith Attributes modifier (see Apply a Datasmith Attributes Modifier.

In the Datasmith Attributes modifier settings, set Export Geometry As to Bounding Geometry.

Bounding Box Export Example

In the images below, the windows of the 3ds Max scene have a Datasmith Attribute Modifier applied, and are set to export as bounding boxes only. When you import them into an Unreal Engine Level, they appear as simplified volumes with default Materials.





The windows in this 3ds Max scene are set to export as bounding boxes only. Click image to expand.







In Unreal Engine, the windows appear as simplified volumes with default Materials. Click image to expand.



You can use these simplified scene elements in many different ways. For example, you might want to replace the simplified objects with instances of your own custom Static Mesh Assets. Alternatively, you can hide the simplified Actors from view, but use the information they contain (for example, their placement in 3D space or the extents of their bounding boxes) for other purposes.

Exporting Datasmith Files from 3ds Max

Getting and Setting Export Options

Datasmith_GetExportOption_AnimatedTransforms()

Datasmith_SetExportOption_AnimatedTransforms <boolean>

Datasmith_GetExportOption_TextureResolution()

Datasmith_SetExportOption_TextureResolution <index>

Logging Messages to the Datasmith Messages Window

Datasmith_LogInfo <msg>

Datasmith_LogWarning <msg>

Datasmith_LogError <msg>

Datasmith_LogCompletion <msg>

Datasmith_LogFlush()

Exporting .udatasmith Files

Datasmith_ExportDialog()

Datasmith_Export <name> <path> selected:[boolean] quiet:[boolean]

Direct Link and Direct Link Auto Sync

Datasmith_OpenDirectlinkUi()

Datasmith_GetDirectlinkCacheDirectory()

Datasmith_GetUnrealEnginePath()Datasmith_GetUnrealEnginePathFromRegistry()

Datasmith_ToggleAutoSync()

Datasmith_IsAutoSyncEnabled()

Datasmith_GetExportOption_StatSync()

Datasmith_SetExportOption_StatSync <boolean>

Datasmith_SetAutoSyncDelay <seconds>

Datasmith_SetAutoSyncIdleDelay <seconds>

Datasmith_UpdateScene quiet:[boolean]

Datasmith_DirectLinkUpdateScene()

Datasmith_Reset()

When you install the Datasmith 3ds Max Exporter plugin, it adds a small Datasmith_Export interface to the MAXScript environment. Use the interface to automate exports of 3ds Max scenes to .udatasmith files, instead of manually exporting scenes. This page describes the methods that the Datasmith_Export interface exposes.

The syntax for Datasmith 3ds Max export scripts changed in version 5.1. Scripts written for previous versions will not work in version 5.1. You can rewrite existing scripts using the new syntax described on this page.

Some of these methods correspond to commands on the Datasmith tab of the 3ds Max Ribbon (see The 3ds Max Ribbon). When you call a method in MAXScript, the user interface for the corresponding command in the ribbon might not update immediately. To refresh the user interface, go to another tab in the 3dsMax ribbon, and then return to the Datasmith tab.

Getting and Setting Export Options

Datasmith_GetExportOption_AnimatedTransforms()

Returns true if Datasmith is set to export the full animation timeline, and false if it's set to export the current frame only.

Datasmith_SetExportOption_AnimatedTransforms <boolean>

Specifies whether Datasmith exports the full animation timeline or the current frame.

true: Datasmith exports the full animation timeline.

false: Datasmith exports the current frame only.

Datasmith_GetExportOption_TextureResolution()

Returns the index value of the current resolution limit for baked procedural textures that Datasmith exports. Each value corresponds to the number of pixels in a target resolution, regardless of the specific widths / heights of exported textures.

Value

Resolution

0

4096 pixels

1

16,384 pixels

2

65,536 pixels

3

0.25 megapixels

4

1 megapixel

5

4 megapixels

6

16 megapixels

For more information about limiting baked procedural texture resolution, see Procedural Textures.

Datasmith_SetExportOption_TextureResolution <index>

Specifies the maximum resolution for baked procedural textures that Datasmith exports. Accepts values between 0 and 6. Each value corresponds to the number of pixels in a target resolution, regardless of the specific widths / heights of exported textures.

Value

Resolution

0

4096 pixels

1

16,384 pixels

2

65,536 pixels

3

0.25 megapixels

4

1 megapixel

5

4 megapixels

6

16 megapixels

For more information about limiting baked procedural texture resolution, see Procedural Textures.

Example:

Datasmith_SetExportOption_TextureResolution 4

Sets the maximum baked / procedural texture resolution to one million pixels, or one megapixel.

Logging Messages to the Datasmith Messages Window

Use these commands to log custom messages to the Datasmith Messages window. Each type of message displays in a different color.

Message Type

Color

Info

Gray

Warning

Yellow

Error

Red

Completion

Green



Datasmith_LogInfo <msg>

Logs an Info-type message to the Datasmith Messages window. Info messages appear in gray.

Parameter

Type

Description

<msg>

string

The message to output to the Datasmith Messages window

Example: Datasmith_LogInfo "this is an Info message"

Datasmith_LogWarning <msg>

Logs a Warning-type message to the Datasmith Messages window. Warning messages appear in yellow.

Parameter

Type

Description

<msg>

string

The message to output to the Datasmith Messages window

Example: Datasmith_LogInfo "this is a Warning message"

Datasmith_LogError <msg>

Logs an Error-type message to the Datasmith Messages window. Error messages appear in red.

Parameter

Type

Description

<msg>

string

The message to output to the Datasmith Messages window

Example: Datasmith_LogInfo "this is an Error message"

Datasmith_LogCompletion <msg>

Logs a Completion-type message to the Datasmith Messages window. Completion messages appear in green.

Parameter

Type

Description

<msg>

string

The message to output to the Datasmith Messages window

Example: Datasmith_LogInfo "this is a Completion message"

Datasmith_LogFlush()

Writes log messages that are queued in memory to the log file. The log file is stored in the %LOCALAPPDATA%\UnrealDatasmithExporter\Saved\Logs directory.

Exporting .udatasmith Files

Datasmith_ExportDialog()

Opens the Datasmith file export dialog, where you can specify the name and path for the exported .udatasmith file.

Datasmith_Export <name> <path> selected:[boolean] quiet:[boolean]

Exports the 3ds Max model or selection as a .udatasmith file, without opening the Datasmith file export dialog.

This method takes the following arguments:

Parameter

Type

Description

Optional?

name

string

The name of the file to export, without the file extension.

n

path

string

The full path to the directory to export the file to.

n

selected:

boolean

Specifies whether Datasmith exports the entire scene, or only the currently selected objects.

true: Datasmith exports only the visible selected objects.

false: Datasmith exports the entire scene (visible objects only).

y

quiet:

boolean

true: Datasmith exports the .udatasmith file silently, meaning it does not open any associated UI or display a progress bar. This is useful for automation scenarios.

false: Datasmith displays a progress bar and other associated UI when it exports the scene.

y

Example:

Datasmith_Export "DatasmithExportName" "D:\DatasmithExports\3dsMax" selected:true quiet:true

The example above automatically exports selected objects as a .udatasmith file with the name DatasmithExportName at the path D:\DatasmithExports\3dsMax, without displaying a progress bar or other export UI.

Direct Link and Direct Link Auto Sync

Datasmith_OpenDirectlinkUi()

Opens the Datasmith Direct Link Connection Status window.

Datasmith_GetDirectlinkCacheDirectory()

Returns the path to the Direct Link Cache Directory. You can also get the path from the Datasmith Direct Link Connection Status window.

Datasmith_GetUnrealEnginePath()Datasmith_GetUnrealEnginePathFromRegistry()

These methods return the path to the installed Unreal Engine connected via DirectLink. Datasmith_GetUnrealEnginePath() calls Datasmith_GetUnrealEnginePathFromRegistry() and returns the path stored in the registry. If the registry does not contain a path, it returns the default hardcoded path: C:/ProgramData/Epic/Exporter/3dsMaxEngine/.

Datasmith_ToggleAutoSync()

Toggles Direct Link Auto Sync on and off. Use Datasmith_IsAutoSyncEnabled() to check whether Auto Sync is currently enabled .

Datasmith_IsAutoSyncEnabled()

Returns true if Direct Link Auto Sync is currently enabled, false otherwise.

Datasmith_GetExportOption_StatSync()

Returns true if Datasmith is set to output statistics to the Datasmith Messages window when you synchronize the scene using Direct Link or Direct Link Auto Sync, false otherwise.

Datasmith_SetExportOption_StatSync <boolean>

Specifies whether Datasmith outputs statistics to the Datasmith Messages window when you synchronize the scene using Direct Link or Direct Link Auto Sync

true: Datasmith outputs statistics to the Datasmith Messages window.

false: Datasmith does not output statistics.

Datasmith_SetAutoSyncDelay <seconds>

Specifies the interval of the timer that checks conditions for Direct Link Auto Sync.

This method takes the following arguments:

Parameter

Type

Description

<seconds>

float

The duration of the interval between Auto Sync condition checks, in seconds.

Datasmith_SetAutoSyncIdleDelay <seconds>

When Direct Link Auto Sync is enabled, this method specifies the minimum amount of time for which the user has to be idle before Datasmith attempts a Direct Link Auto Sync.

This method takes the following arguments:

Parameter

Type

Description

<seconds>

float

The number of seconds the user has to be idle for before Datasmith attempts a Direct Link Auto Sync.

Datasmith_UpdateScene quiet:[boolean]

Updates the Datasmith 3ds Max Exporter plugin's scene representation to match current 3ds Max scene.

Returns true if the scene changed since the last update, false otherwise.

When you use the Synchronize command from the Datasmith tab of the 3ds Max ribbon, Datasmith first calls this command, and then, if it detects any changes, calls Datasmith_DirectLinkUpdateScene().

This method takes the following arguments:

Parameter

Type

Description

Optional?

quiet:

boolean

true: Datasmith updates the scene silently, meaning it does not open any associated UI or display a progress bar. This is useful for automation scenarios.

false: Datasmith displays a progress bar and other associated UI when it updates the scene.

y

Datasmith_DirectLinkUpdateScene()

Synchronizes the Datasmith 3ds Max Exporter plugin's scene representation with Unreal Engine via Datasmith Direct Link. Sets up tracking for scene changes.

When you use the Synchronize command from the Datasmith tab of the 3ds Max ribbon, Datasmith first calls Datasmith_UpdateScene(). If it detects any changes, it then calls this method.

For more information, see File Export Panel in The Datasmith 3ds Max UI, and Synchronizing 3ds Max and Unreal with Direct Link.

Datasmith_Reset()

Stops tracking scene changes, and resets the Datasmith 3ds Max Exporter plugin's scene representation.

Archicad Workflows

Datasmith DirectLink

Export Workflow

Using the Datasmith Toolbar

Geometry, Layers, and Scene Hierarchy

HotLinks Modules

Materials

Standard Archicad Materials

GDL and Two-Sided Materials

Lights

Cameras

Metadata and Classifications

Actor Tags

This page describes how Datasmith imports scenes from Graphisoft Archicad into Unreal Engine. It follows the basic process outlined in the Datasmith Overview and Datasmith Import Process, but it provides additional details on the Direct Link workflow and translation behaviors specific to Archicad. If you are planning to use Datasmith to import scenes from Archicad to Unreal Engine, reading this page can help you understand how your scene is translated, and how you can work with the imported scene in Unreal Editor.

Archicad Workflows

Datasmith DirectLink

With the DirectLink workflow, you can set up a Datasmith DirectLink between Archicad and Unreal Engine or Twinmotion. This link updates your Unreal Engine level or Twinmotion model, removing the need to re-export a *.udatasmith file from your Archicad scene every time you make a change.

Export Workflow

Using the Export workflow, a .udatasmith file can be exported from Archicad for use in Unreal Engine or Twinmotion. For more information on exporting Datasmith content from Archicad, see Exporting Datasmith Content from Archicad.

For more information importing .udatasmith files into Unreal Engine, see Importing Datasmith Content into Unreal Engine.

Using the Datasmith Toolbar

The Datasmith plugin adds the Datasmith toolbar option to the Windows > Palettes menu.



Datasmith DirectLink toolbar.

Action

Button

Description

Synchronize with Direct Link



Pushes the selected models to Unreal Engine or Twinmotion through the Direct Link connection.

Manage Connections



Launches the Connection Status dialog.

Export to Datasmith File



Launches the existing .udatasmith exporter, used to save a .udatasmith file to disk.

Show Messages



Launches the messages and logging window. This is useful for reporting errors, missing textures, and other information.

Geometry, Layers, and Scene Hierarchy

Archicad objects are imported into Unreal Engine as a single Actor composed of several nested Static Mesh components.



World Outliner showing the hierarchy of an imported Archicad file.

Each Actor in the World Outliner represents a Layer in Archicad and is visible from the Layers panel in Unreal Editor.



Layers represented by Actors in the World Outliner are also represented as layers in the Layer panel.

Object pivot points are imported into Unreal Engine and they retain their same locations from Archicad. However, in some cases due to Archicad SDK limitations, it is possible that pivot locations will not be correctly defined resulting in a mismatch like the one shown below.



Notice that the pivot point for the chair is different in the Editor than in Archicad.

HotLinks Modules

Unreal Engine retains your Archicad HotLink external references that contain 3D elements by importing them as an extra Actor with nested Static Meshes into the Level.

Materials

Unreal Engine builds Materials in the Datasmith scene using a Physically Based Rendering (PBR) graph, where the Master materials are built in realtime by the Datasmith Importer. This process retains the look of the Archicad materials when importing them into Unreal Engine.



The export plugin retains the look of Materials from Archicad when importing into Unreal Engine.

There are two types of materials in Archicad:

Standard materials derived from surface attributes.

Materials derived from GDL objects.

Standard Archicad Materials

Materials from Archicad are exported as PBR materials and imported into Unreal Engine with the following attributes being retained:

Base color

Texture transparency

UV size and more



Properties highlighted in green are considered by the Datasmith exporter.

GDL and Two-Sided Materials

All architectural objects within Archicad are considered closed objects and are exported with materials that are one-sided.

Objects that are thin, such as GDL and Morph objects, export with materials that are two-sided. When this happens, the material name will be appended with a _DS suffix to maintain separation in Unreal Engine from single-sided materials.



The highlighted material is double sided and the name contains the _DS suffix.

Lights

The Datasmith exporter supports basic light types and their parameters. Area lights are imported into Unreal Engine as point lights. Environment and parallel lights are not supported.



A variety of light types imported from Archicad into Unreal Engine.

Archicad Light Type

Unreal Engine Light Class

Supported Parameters

Unsupported Parameters

General Light

Point Light

Intensity

Color

Falloff Distance

Absolute Light Intensity

Shadow casting parameters (Opacity and Quality)

Spot Light

Spot Light

Intensity

Color

Falloff Distance

Absolute Light Intensity

Fade out between inner and outer angles

Shadow casting parameters (Opacity and Quality)

Spot light geometry (limited to circle)

IES Light

Point Light with IES profile

Intensity

Color

Falloff Distance

Absolute Light Intensity

IES Shape

IES Intensity

Shadow casting parameters (Opacity and Quality)

Use Area Shape and Size given in Photometric file

IES Light Quality/Grainy Illumination

Area Light

Datasmith Area Light

Intensity

Color

Falloff Distance

Absolute Light Intensity

Size Length/Width

Shadow casting parameters (Opacity and Quality)

Use Area Shape and Size given in Photometric file

IES Light Quality/Grainy Illumination

Parallel Light

Not Supported

Not Supported

Not Supported

Sun Object

Not Supported

Not Supported

Not Supported

Window Light

Not Supported

Not Supported

Not Supported

Cameras

The current viewpoint in Archicad at the time of export is imported into Unreal Engine as a Camera Actor named "Current View." The following camera properties are supported:

Transform

Sensor Width and Height

Focal Length Min and Max

FStop Min and Max

Focus Distance

Current Focal Length

Current Aperture



Archicad camera settings retained during the import into Unreal Engine.

Unreal Engine also supports Path Cameras. They are imported as Camera Actors under a Scene Actor using the Path name in Archicad.



Path Cameras are supported and are imported into the World Outliner as Camera Actors.

Metadata and Classifications

Most properties within Archicad are exported to Unreal Engine as MetaData when:

The element name Key ID value is the same as the element's name. For example, the ID value for a door is "Wooden_Door".

The key value uses a specific classifications, including:

Key value uses the classification System suffixed with "_ID".

Key value uses the classification System suffixed with "_Name". This is generally empty.

Key value uses the classification System suffixed with "_Description". This is generally empty.

Categories key values contain the prefix "CAT_Xyz"

IFCProperties key values contain the prefix "IFC_Xyz"

IFCAttributes key values contain the prefix "IFC_Attribute_Xyz"

Undefined metadata will not be exported.

For example, if you were to export a Door from Archicad:



Properties of a wooden door in Archicad.

It would export as:

Classifications can be added and edited within Archicad using the Classification Manager:



The Classification Manager within Archicad is used to add additional Classifications.

This menu can be found by clicking the Classification Manager option in the Windows menu.

Actor Tags

Archicad technical data can be exported to Unreal Engine by leveraging Actor Tags within the editor. The data stored within Actor Tags can then be used to perform a variety of operations using Visual Dataprep, Python scripting, and more.

Currently the Datasmith plugin exports:

ID

Type

LibPart (Main, Rev, Name)



Tag values are imported into Unreal as Actor Tags.

Installing the Datasmith Plugin for Archicad

End Result

Removing the Datasmith Exporter for Archicad

Choose your operating system:

Windows

macOS

Linux

Before you can begin exporting your Archicad content, you will need to download the Unreal Datasmith Exporter for Archicad.

To see what versions of Graphisoft Archicad the plugins support, see Datasmith Supported Software and File Types.

We encourage you to share the download link for the Datasmith Exporter plugins with any number of people, both inside and outside of your organization. Please note that users are not permitted to distribute the Datasmith Exporter plugins themselves.

Installing the Datasmith Plugin for Archicad

Close any running instances of Archicad that you may have running on your machine. If any instances are currently running, the installation will fail.

If you already have an older version of the Datasmith Exporter plugin installed, we recommend first uninstalling it before proceeding. For details, see Removing the Datasmith Exporter for Archicad.

Graphisoft provides their own Datasmith Exporter for Archicad. Epic Games recommends removing the Graphisoft plugin before installing its own Datasmith Plugin for Archicad.

Download the Datasmith Exporter plugin installer from the Datasmith Exporter Plugins download page.

When the download is complete, navigate to the location of the file and run the installer.



The Unreal Datasmith Exporter for Archicad Setup Wizard.

Follow the on-screen instructions and accept the license agreement to continue.

The installer automatically detects which versions of Archicad have installed on your system. Check the box for each version you want to export to Datasmith and click Install.



Select which versions of Archicad you want to use with the plugin.

Close any running instances of Archicad that you may have running on your machine. If any instances are currently running, the installation will fail.

If you already have an older version of the Datasmith Exporter plugin installed, we recommend first uninstalling it before proceeding. For details, see Removing the Datasmith Exporter for Archicad.

Graphisoft provides their own Datasmith Exporter for Archicad. Epic Games recommends removing the Graphisoft plugin before installing its own Datasmith Plugin for Archicad.

Download the Datasmith Exporter plugin installer from the Datasmith Exporter Plugins download page.

Open an instance of Archicad and open the Add-On Manager by opening the Options menu and selecting Add-On Manager.



Opening the Add-On Manager.

Navigate to the Edit List of Available Add-Ons section and click the Add button.



Adding a new add on in Archicad.

Navigate to the location of the Datasmith Exporter for Archicad file andselect the package that corresponds with your version of Archicad. Click ok to continue.



Navigate to the location of the Datasmith Exporter for Archicad install file and select the package that corresponds with your version of Archicad.

End Result

With the Datasmith Exporter plugin installed, you can now use the Direct Link workflow and export scenes from Archicad as .udatasmith files. See Exporting Datasmith Content from Archicad.

Epic Games releases a new version of the Unreal Datasmith Exporter plugin for Archicad with every new release of Unreal Engine. If you switch to a different version of Unreal Engine, remember to download and install the matching version of the plugin.

Removing the Datasmith Exporter for Archicad

Use the standard control panel utilities for your system to find and remove the Unreal Datasmith Exporter for Archicad application.

For example, on Windows 10, you can use the Apps & features control panel.



Search for the Datasmith plugins in the Apps & features control panel.

Click the entry for your Datasmith Exporter plugin in the list, then click Uninstall.

Alternatively, use the Uninstall or change a program window from the Control Panel. Right-click the entry for your Datasmith exporter plugin, and choose Uninstall from the contextual menu.



Removing a Datasmith plugin using the Uninstall or change a program control panel.

Use the Add-On Manager inside Archicad to remove the Unreal Datasmith Exporter for Archicad.

Open the Add-On Manager by clicking on the Options menu and selecting Add-On Manager.

Click the checkbox next to Datasmith for ARCHICAD in the Available Add-Ons list to disable the add-on.

Click the Remove button to remove the plugin.



Removing a Datasmith plugin using the Add-on Manager.

End Result

Once you have installed the Datasmith Exporter for Archicad, a Datasmith toolbar option is added to the Windows > Palettes menu.



Enable the toolbar using the Windows > Palette menu option.

Once enabled, clicking the Export to Datasmith option will open the Export to Datasmith file window.



Export content from Archicad using the Export to Datasmith button.

Browse for the location where you want to save your exported file, set the File name, and click Save.

End Result

Your .udatasmith file should now be ready to import into Unreal Engine. See Importing Datasmith Content into Unreal Engine for more information. If your data needs additional cleaning, merging, or other modifications during the import process, see Dataprep Import Customization.

Cinema 4D Workflow

Geometry

Object Visibility

Generators and Deformers

Instances, Cloners, and Arrays

Normal Facing Directions

Lights

Cameras

Scene Hierarchy

How Datasmith Bakes Cinema 4D Procedural Features

Layers

Cinema 4D Materials

Working with Material Channels

Controlling Texture UVs

Parent Materials

Material Import Limitations

Animations

User Data

This page describes how Datasmith imports scenes from Maxon Cinema 4D into Unreal Editor. It follows the basic process outlined in the Datasmith Overview and About the Datasmith Import Process, but adds some special translation behavior that is specific to Cinema 4D. If you're planning to use Datasmith to import scenes from Cinema 4D into Unreal Editor, reading this page can help you understand how your scene is translated, and how you can work with the results in Unreal Editor.





Credit: The classroom scene used on this page is courtesy of Turbosquid user scripter.

Cinema 4D Workflow

Datasmith uses a Direct workflow for Cinema 4D. This means that to get your Cinema 4D content into Unreal using Datasmith, you need to do the following:

In Cinema 4D, save your scene to a .c4d file. From the main menu in Cinema 4D, do one of the following:

If you are using a more recent version of Cinema 4D, select File > Save Project for Cineware option.

If you are using an older version you might need to select File > Save Project for Melange instead.

In Unreal Engine, enable the Datasmith C4D Importer Plugin for your Project. To learn how to enable a plugin, see Working wih Plugins.

In Unreal Engine, use the Datasmith import options to import the .c4d file into your project. For instructions, see Importing Datasmith Content into Unreal Engine.

In Cinema 4D versions prior to R22, you can configure Cinema 4D to automatically include the information Datasmith needs when you save a .c4d file.

From the main menu, select Edit > Preferences.

On the Files tab of the Preferences dialog, enable the following options:

Save Polygons for Melange.

Save Animations For Melange.

Click for full image.

Enabling these options increases the size of the files you save. If file size is a concern, or you frequently work with Cinema 4D scenes that you don't need to import into Unreal Engine, you may prefer to use the File > Save Project for Melange option only when you need it.

Geometry

Datasmith creates a Static Mesh Asset for each visible geometric object in the Cinema 4D scene.

The object name that you see in the Cinema 4D Properties panel is the name Datasmith assigns to the corresponding Static Mesh Asset in Unreal Engine.

To influence the granularity of the Static Mesh Assets and Actors that Datasmith creates, you can merge objects in Cinema 4D before you export the scene.

For example you can do the following:

Use the Connect Objects command in Cinema 4D to merge two objects into a single object. See Connect Objects in the Cinema 4D documentation.

For more flexibility, use the Connect Object in Cinema 4D to combine objects that are closer than a given threshold value into a single mesh. In this case, the Datasmith importer produces a single Static Mesh Asset for the combined mesh, but the connected pieces remain separate objects in Cinema 4D. See Connect Object in the Cinema 4D documentation.

Object Visibility

If you have objects that you don't want to import into Unreal Engine at all, hide them in Cinema 4D before you save your .c4d file. The Datasmith importer does not import geometry of hidden objects into Static Mesh Assets, and does not include them in the Datasmith Scene hierarchy.

You can use the Objects panel in Cinema 4D to hide the objects individually. Alternatively, you can put the objects you want to omit into their own layer, then use the Layers panel to hide all objects in that layer.

Generators and Deformers

When you save your Cinema 4D scene for Melange, every generator in your scene is baked down to a single triangular mesh that represents the total procedurally generated geometry of the object. Similarly, every deformer is baked to a single triangular mesh based on the final state of the deformer. Datasmith imports each of these triangular meshes as a single Static Mesh Asset.

Instances, Cloners, and Arrays

If you use instances, cloners, or arrays in your Cinema 4D scene to place copies of a single object at multiple different locations in your scene, Datasmith respects your intention by creating a single Static Mesh Asset in your Content Browser from that object's geometry. It then places multiple instances of this Static Mesh Asset into the Datasmith Scene.

Normal Facing Directions

The Unreal Engine, like most real-time renderers, automatically culls triangles that face away from the camera in order to maximize performance. However, Cinema 4D can render geometry with or without this backface culling. Depending on how you set up Cinema 4D, you may not be used to taking the facing direction of your surfaces into account. If your scene contains single-sided geometry for which the surface normals of the faces point away from the typical viewing direction, that geometry may seem to disappear when viewed from certain angles in the Unreal Engine.

For example, the image below shows a book that was modeled with one of its surface normals facing inward. After the scene is imported into Unreal, the front cover at first appears to be missing. In this case, flipping the normal direction of the surface makes the sides appear as they should.





You can avoid this problem by verifying in Cinema 4D that your surfaces are facing in the direction you expect. There are a few ways you can do this. For example:

You can enable the Options > Backface Culling setting for your viewport. This hides all faces whose normals are pointing away from the camera, the same way they are hidden in Unreal Engine.

Click for full image.

When you are in Polygons mode, selected faces show up with a yellow highlight when they are facing toward you, but a blue highlight when facng away from you.



You can configure your viewport to show vertex normals as white lines that extend from the center of each face. Choose Options > Configure and go to the Attributes panel. Make sure the Polygon Normals setting is enabled, and disable its Selected Only option to visualize the normals for all faces in the model that you have selected while you're in Polygons mode.



When you find faces with inversed normals in Cinema 4D, you can flip them around using the Reverse Normals command. See the Cinema 4D documentation.

For a complete discussion and more possible solutions, see Datasmith Import Process.

Lights

Datasmith converts most types of lights from Cinema 4D into equivalent light types in Unreal Engine. This translation preserves the most important emissive properties of the light, including its placement in the scene, color, photometric intensity, cone angles, IES profile, and more.

The following table describes how Datasmith maps Cinema 4D light types into Unreal Engine light types:

Cinema 4D

Unreal Engine

Point light, IES light

Point Light

Spot light, Target light

Spot Lights

Area light, PBR light

DatasmithAreaLight Blueprint

Sun light, Infinite light

Directional Lights

Cameras

For each camera in your Cinema 4D scene, Datasmith creates a CineCamera Actor in the Datasmith Scene. This camera is placed at the same position and rotation as its counterpart in Cinema 4D, and preserves some optional settings related to the camera's physical characteristics, including its focal length.

Scene Hierarchy

When Datasmith imports a Cinema 4D scene into Unreal Engine, it creates a hierarchy of Actors that closely matches the hierarchy of objects in Cinema 4D. Datasmith preserves object names and hierarchical relationships as closely as possible, but might not be able to create an exact match.

Possible differences include:

Object ordering: In Unreal Editor the Outliner orders Actors at each level of the hierarchy alphabetically. Actors might appear in a different order than their counterpart objects in Cinema 4D, but it does not affect their hierarchical relationships.

Object names: The names of the Actors Datasmith creates can only contain alphanumeric characters, hyphens, and underscores. If the name of a Cinema 4D object contains any other characters, Datasmith converts them to underscores automatically.

Baking procedural elements: During the import process, Datasmith bakes procedural features of the Cinema 4D scene, and replaces them with sets of static Actorsthat replicate their effects. This can affect the final hierarchy in Unreal Engine. See the next section for details.

How Datasmith Bakes Cinema 4D Procedural Features

Datasmith imports each procedural object in the Cinema 4D scene (for example, a generator, cloner, or array) into Unreal Engine as a single parent Actor with the same name as the original Cinema 4D object.

Under each parent Actor, Datasmith creates Static Mesh Actors that simulate the effect of the procedural geometry. These Static Mesh Actors have the same name as their parent Actors, but with a numeric suffix.

If you use procedural features extensively in Cinema 4D, it can produce complex scene hierachies when Datasmith imports your scenes into Unreal Engine. However, you do have access to each individual Actor as a separate instance in Unreal Engine.

Layers

When you import a Cinema 4D scene, Datasmith imports every named layer that has at least one object in it. It does not import empty layers, meaning layers in the Cinema 4D scene that have no objects in them. Datasmith assigns Level Actors it creates in Unreal Engine to the same Layer their counterpart objects are assigned to in the Cinema 4D scene.

To view imported layers, use the Layers panel (see Layers Panel)

Cinema 4D Materials

Datasmith creates a new Material Asset in the Unreal Engine Project for each Standard Material and Physical Material in your Cinema 4D scene.

The goal of these Material Assets is to respect the way you've set up the surfaces to look in Cinema 4D, while exposing properties that help you take advantage of Unreal's physically based renderer.

To modify a Material:

Double-click it in the Content Browser. Or, select an Actor in your Level that uses the Material you want to modify, and double-click the Material in the Details panel.

You'll open the Material Instance Editor shown below, where you can use the settings in the Details panel to modify the properties imported from Cinema 4D. You can also modify other built-in parameters exposed by the Unreal renderer.

Click for full image.

For more information about how to use the Material Instance Editor, see Material Instance Editor UI.

Working with Material Channels

When you edit a Material imported from Cinema 4D, the top of the Details panel lists the different types of Cinema 4D channels that Datasmith handles during the import process. If you're used to working with materials in Cinema 4D, the effect of these channels and their settings should be familiar to you already.



When a channel is activated in the top 00 Global section, the Details panel also contains a section lower down where you can configure settings related specifically to that channel. These settings expose the most important properties that you can set for the corresponding channel in Cinema 4D.

For example, the channels activated in the image above make additional sections appear. You can see those sections in the image below: Color (1), Reflectance (2), Specular (3), and Normal (4).



The only exception to this rule is the Reflection Color channel. When the Use_ReflectionColor setting is activated, new Reflection Color and Reflection Color Strength settings are added to the 01_Color group.



The values you set in the Reflectance channel affect multiple Material output channels in the Unreal Engine, including the Roughness, Metallic, and Specular channels. Due to these complex relationships, Datasmith only translates one layer from the Cinema 4D Reflectance channel.

Controlling Texture UVs

At the bottom of the Details panel, you'll see settings that control the UV mapping for all channels in the Material. By changing these settings, you can change the way that the Material applies texture maps to the geometry of the Static Meshes it shades. The values you set here apply to all channels that use texture maps. These settings have similar effects to the offset and tiling settings for Texture Tags in Cinema 4d:



Each channel that offers a texture map in its settings also has its own optional UV wrapping controls. For example, the 04_Normal channel accepts a normal map texture, so it also offers a setting that activates a secondary set of UV controls that apply only to the normal map texture:



When you enable this option, a new set of UV mapping controls are added to the channel settings:



If you customize both the general UV settings in the UV group and the settings for a specific channel, the effects are added together.

Parent Materials

Each Material Asset that Datasmith creates is a Material Instance. The parent of this Material Instance is always the C4DMaster Material that is built in to the Datasmith Plugin. You can open up this parent Material to see how each of the properties exposed in the Material Instance are wired together in the Material graph. You can also modify the parent Material to expose other properties, or to change the way the existing properties are taken into account during the shading calculations. See Modifying a Datasmith Master Material.

Material Import Limitations

Datasmith's Material conversion process from Cinema 4D to Unreal Engine has a few limitations: it does not support procedural textures such as noise, node-based Materials (introduced in Cinema 4D R20), or third-party renderers.

In these cases, if you need the result in Unreal Engine to closely match what you see in Cinema 4D, the best approach is to bake your Materials out as bitmap textures, and to create new Materials that apply these baked bitmaps to your objects. See Bake Material in the Cinema 4D documentation.

Animations

If your Cinema 4D scene contains any elements whose 3D transforms are animated over time, including keyframe animations, MoGraph, or Dynamics, Datasmith automatically imports those animated transforms into a new Level Sequence Asset. You can use the Sequencer Tool to play back your animation in Unreal Editor, and use Blueprint to manage interactive playback at runtime.

For important details about how to work with the Level Sequences that Datasmith produces, see the Animations section of About the Import Process.

User Data

In Cinema 4D, you can add User Data to objects in a scene by choosing User Data > Manage User Data in the Attributes panel. For more information about adding User Data in Cinema 4D, see the Cinema 4D documentation.



Datasmith imports User Data from Cinema 4D objects, and stores it as Datasmith Metadata on the corresponding Level Actors. You can access this metadata in the Unreal Editor using Blueprint or Python, and in the Engine at runtime using Blueprint. For more information, see Accessing Metadata in Blueprint and Python.

A few important notes apply to the data conversion:

In Cinema 4D, you can organize User Data into hierarchical groups, but Datasmith Metadata in Unreal Engine is always a flat list of keys and values. If your User Data contains any groups, Datasmith does the following:

flattens the hierarchy.

Puts all metadata keys from all groups into a single flat list.

Discards the group names.

Regardless of the data type you set for your User Data in Cinema 4D, the value stored in the Datasmith Metadata is always a string. Wherever possible, Datasmith converts the original data value into a string that you can parse to extract the relevant information. However, some Cinema 4D data types are not supported, such as gradients, links to other scene objects, priority values, splines, and so on.

Metadata key names can only contain alphanumeric characters, hyphens, and underscores. If the name of your User Data in Cinema 4D contains any other characters, Datasmith converts them to underscores automatically.

Workflow

Deltagen

VRED

Variants

Animations

This page describes how Datasmith imports scenes from 3DExcite Deltagen and Autodesk VRED into Unreal Editor. It follows the basic process outlined in the Datasmith Overview and About the Datasmith Import Process, but adds some special translation behavior that is specific to Deltagen and VRED. If you're planning to use Datasmith to import scenes from Deltagen or VRED into Unreal Editor, reading this page can help you understand how your scene is translated, and how you can work with the results in Unreal Editor.

Datasmith currently only works with VRED Professional. It does not support VRED Design.

Workflow

Deltagen

Datasmith uses an Export workflow for Deltagen. This means that to get your Deltagen content into Unreal using Datasmith, you need to:

Export your Deltagen scene to an .fbx file using the export feature built in to Deltagen.

Enable the Importers > Datasmith FBX Importer plugin for your project, if it is not already enabled. Restart Unreal Engine if prompted.

On the Main Toolbar, click the Datasmith button. Then, from the All Files drop-down, select DeltaGen Fbx files. file. See See Importing Datasmith Content into Unreal Engine.

VRED

Datasmith uses an Export Plugin workflow for VRED. This means that to get your VRED content into Unreal using Datasmith, you need to:

Install a plugin script for VRED, and use it to export your VRED scene to an .fbx file. See Exporting Datasmith Content from VRED.

Enable the Importers > Datasmith FBX Importer plugin for your project, if it is not already enabled. Restart Unreal Engine if prompted.

On the Main Toolbar, click the Datasmith button. Then, from the All Files drop-down, select VRED Fbx files. file. See See Importing Datasmith Content into Unreal Engine..

To read more about other types of Datasmith workflows, see Datasmith Supported Software and File Types.

Variants

The Datasmith Importer does not support look variants from Deltagen.

The Datasmith FBX importer for Deltagen and VRED brings the variants and variant sets that you've defined in your Deltagen or VRED scene into a new LevelVariantSets Asset that it creates in your Content Browser. It also places an instance of this Asset into your Level.

Double-click this Asset to open the Variant Manager window. You can use this window to switch between different variants and variant sets while you're working in the Unreal Editor. You can use a dedicated set of Blueprint functions provided by the LevelVariantSets Actor to switch variants at runtime. You can also customize your variants further, making each variant affect more objects in the Level, or triggering custom Blueprint functions each time it is activated.

It is up to you to decide how the user running your Unreal project should choose between these variants at runtime, and to write the code that triggers the appropriate Blueprint functions. For example, you might want to create a UI or a set of menus where users can select variants, or you can configure your project to switch variants in response to key presses or other inputs. The Datasmith importer and the Variant Manager do not create these UI or menus for you — they only give you all the tools you need to create them yourself.

For more information on the Variant Manager and how it works, see Working with Scene Variants.

To see an example of how to use the Variant Manager with a UI generated from the variants, see the Product Configurator template.

Animations

If your Deltagen or VRED scene contains any animated scene elements, the Datasmith FBX importer brings those animations into Unreal as Level Sequences. You can use the Sequencer tool in the Unreal Editor to work with and edit the animations, use Blueprints to control and play back the animations in your project at runtime, and take advantage of all the other features of the Sequencer tool described in the Sequencer documentation.

For important information about working with Sequencer animations imported by Datasmith, see also the Animations section of About the Datasmith Import Process.

Installing the Exporter Plugin Script

Exporting to Datasmith

Installing the Exporter Plugin Script

Before you can get started working with your VRED content in the Unreal Engine, you need to install a plugin script for VRED.

To see what versions of VRED Professional the exporter plugin currently supports, see Datasmith Supported Software and File Types.

Follow the steps below to install the Datasmith exporter plugin script for any supported version of VRED that you have installed on your computer.

In your Unreal Engine installation folder, find the Engine/Plugins/Enterprise/DatasmithFBXImporter/Resources/VREDPlugin folder.

Copy this folder, along with all of its contents, to a location that your VRED installation searches for plugins.For example, on Windows platforms this may be C:\Users[username]\Documents\Autodesk\VRED-[internalVersion]\ScriptPlugins, where [username] is your Windows user ID, and [InternalVersion] represents the version of VRED you have installed.For complete details on how to find this path, see VRED documentation on creating, editing, and using scripts.

You can also use the VRED Terminal window to help you find this path. Open the Terminal by selecting View > Terminal from the main menu, then look for lines that begin with the text: Looking for script plugins in. For example:

Restart VRED.

Exporting to Datasmith

When you have your VRED scene the way you want it, and you've registered your variants, export the scene to FBX:

From the main menu in VRED, choose:

File > Export > Export to Datasmith... (for VRED 2018)

File > Export Scene Data > Export to Datasmith... (for VRED 2019)

Browse to a folder and choose a file name.

The exporter creates a .FBX file in the location you choose.

End Result

You should now be ready to try importing your new .FBX file into the Unreal Editor. See Importing Datasmith Content into Unreal Engine.

The exporter also creates additional files next to the .FBX:

A .lights file that contains additional information about the lights in your scene.

A .var file that contains information about your registered variants.

A .clips file that contains the animations.

A .mats file that contains additional information about materials.

These files contain information required by the Datasmith importer. If you move your .FBX file to a new location, make sure to keep these additional files at the same relative path.

Datasmith Overview

Datasmith Import Process

Navisworks Workflow

Installation Notes

Converting Geometry to Static Meshes

Merging Objects in the Hierarchy

Setting the Origin

Navisworks Metadata

Navisworks Materials

This page describes how Datasmith imports scenes from Autodesk Navisworks into Unreal Engine. It follows the basic process outlined in the Datasmith Overview and About the Datasmith Import Process, but adds some special translation behaviors specific to Navisworks. If you are planning to use Datasmith to import scenes from Navisworks into UE, reading this page can help you understand how your scene is translated, and how you can work with the results in Unreal Editor.

Navisworks Workflow

Similar to the Revit or 3ds Max Datasmith Exporters, our Navisworks Exporter uses an export workflow. This means that to get your content into the editor using Datasmith, you need to:

Install the Datasmith Exporter for Navisworks. See the Installation Notes section below.

Export your Navisworks content using the Datasmith Export button added to the toolbar by the plugin. See Exporting Datasmith Content from Navisworks.

Use the Datasmith importer available in the Toolbar of the Unreal Editor to import your .udatasmith file. See Importing Datasmith Content into Unreal Engine.

Installation Notes

Before you can export Navisworks content, you must download and install the Datasmith Exporter for Navisworks plugin from the Datasmith Export Plugins page.

To see what versions of Navisworks the plugin supports, see Datasmith Supported Software and File Types.

We encourage you to share the download link to the Datasmith Exporter plugins with any number of people, both inside and outside of your organization. Please note that you are not permitted to distribute the Datasmith Exporter plugins themselves.

Before you install the Datasmith Exporter for Navisworks plugin, make sure that:

Navisworks is not running.

You downloaded the installer for the exporter plugin that matches the Unreal Engine version you intend to use.

You uninstalled all previous versions of the Datasmith Exporter for Navisworks plugin.

After you downloaded the installer, double-click it to open, then follow the instructions on-screen.

If you need to uninstall the Datasmith Exporter for Navisworks plugin, you can do this from the Control Panel, like any other Windows application.

Converting Geometry to Static Meshes

The Datasmith Exporter for Navisworks works to preserve the geometry, materials, and metadata contained in your file by using a process similar to our Revit and 3ds Max exporters:

To maintain performance, Datasmith merges objects in the hierarchy at a user defined level to create larger meshes and maintain triangle counts of less than one million.

Once meshes have been merged, the exporter creates a new Static Mesh asset in your Content Browser for each of the remaining meshes. It preserves the Name of each mesh as set in the Properties panel in Navisworks and places them in a Geometries folder.

The Navisworks hierarchy is maintained in the World Outliner by using empty Actor objects.

Your scene is assembled around a user-defined origin point.

Merging Objects in the Hierarchy

As a Navisworks scene contains a significant amount of data from multiple sources, it is necessary to consolidate the number of assets during the export process. Datasmith does this with a process that merges objects at a user-defined depth of the hierarchy:



In the example below, we can see when the value is set to 2 how the objects are merged 2 levels from the bottom:



If the node subtree contains more than 1M triangles, Datasmith merges objects up to a level where the resulting meshes do not exceed 1M triangles.

Setting the Origin

Autodesk Navisworks uses a double precision coordinate system that allows support for models that are very far away from the origin. This is not compatible with Unreal and can lead to imprecision on import. For this purpose, when using the Datasmith Exporter for Navisworks users can designate the origin point of the scene. This specific point becomes the origin point (0,0,0) inside of UE:



Navisworks Metadata

Datasmith imports metadata stored on objects in Navisworks as Tabs:



The data is prepended with tab names using the following format:

_[TabName]_[PropertyName] = [Value]_

So in the image above, the resulting data would be:

_MyTab_MyStringProperty = "MyStringValue"

MyTab_MyBooleanProperty = "Yes"

MyTab_MyFloatProperty = "0.000"

MyTab_MyIntegerProperty = "0"_

Navisworks Materials

For each surface material in your Navisworks scene, Datasmith will create a Material asset in Unreal with the same name. These assets are placed in the Material folder next to your Datasmith Scene Asset.

Each asset that is placed in the Materials folder is a Material Instance that exposes properties set in Navisworks. You can change these exposed parameters to modify the way the Material looks when applied to a surface. Datasmith assigns these Materials to the Static Mesh assets it creates during the import process.

Datasmith also creates a set of master Materials that can be found in the Materials/Masters folder, one for Translucent Materials and another for Opaque Materials. Each of these master Materials is the parent of at least one of the Material Instances found in the Materials folder. You can edit these Materials if you want greater control over the Material graph that defines how each surface appears in Unreal, exposing additional parameters to child Material Instances or chase the way these parameters are processed during rendering.

Changing a Master Material also changes all Material Instances that inherit from that parent automatically. It's usually a good idea to duplicate a Master Material before you modify it, then make your changes to the duplicate, then finally update specific Material Instances to use your new duplicate as their parent. For details, see Modifying a Datasmith Master Material.

Datasmith Overview

Datasmith Import Process

Exporting From the Ribbon Menu

Exporting With a Python Script

End Result

Exporting From the Ribbon Menu

Once you installed the Datasmith Exporter Plugin for Navisworks, you will have an Unreal Datasmith tab added to the ribbon menu at the top of the screen:



Once you have hidden the elements that you do not want to export, follow the steps below to export your scene for Datasmith using the (*.udatasmith) filetype:

From the ribbon menu, click the Datasmith Export button to open the export panel:



Name

Description

Merge

Allows you to select the level of an object's tree at which elements are merged to create static meshes. See Navisworks for more information.

Origin

Specify the origin point for the scene. This will become 0,0,0 inside Unreal.

Set the level of object merging and the origin point in the Export panel and then click the Export button.



Browse to the location where you want to save your exported file, set the File name, and click Save.

Exporting With a Python Script

You can use a Python script to bulk export Datasmith content from Naviswork. You can try the example

End Result

Your .udatasmith file should now be ready to try importing into Unreal. See Importing Datasmith Content into Unreal Engine. If your data needs additional cleaning, merging, or other modifications during the import process, see Dataprep Import Customization.

Revit Workflow

Installation Notes

Controlling What Gets Exported

Geometry

Instancing

Tessellation

Linked Models

Materials and Textures

Textures and UV Wrapping

Building the Datasmith Scene Hierarchy

Lights

Cameras

Categories

Metadata

RPC Objects

Survey Points and Base Points

This page describes how Datasmith imports scenes from Autodesk Revit into Unreal Editor. It follows the basic process outlined in the Datasmith Overview and About the Datasmith Import Process, but adds some special behavior that is specific to Revit. If you're planning to use Datasmith to import scenes from Revit into Unreal Editor, reading this page can help you understand how your scene is translated, and how you can work with the results in Unreal Editor.





Revit Workflow

Datasmith uses an Export Plugin workflow for Revit. This means that to get your Revit content into the Unreal Engine using Datasmith, you need to:

Install a plugin for Revit. See the Installation Notes section below.

Export your Revit content to a *.udatasmith file. See Exporting Datasmith Content from Revit. Alternatively, you can use Dynamo to batch export Revit views.

Enable the Importers > Datasmith Importer Plugin for your Project, if it's not already enabled.

Use the Datasmith importer in the Toolbar of the Unreal Editor to import your.udatasmith file. See Importing Datasmith Content into Unreal Engine.

Installation Notes

Before you can export Revit content, you must download and install the Datasmith Exporter for Revit plugin from the Datasmith Export Plugins page.

To see what versions of Revit the plugin supports, see Datasmith Supported Software and File Types.

We encourage you to share the download link to the Datasmith Exporter plugins with any number of people, both inside and outside of your organization. Please note that you are not permitted to distribute the Datasmith Exporter plugins themselves.

Before you install the Datasmith Exporter for Revit plugin, make sure that:

Revit is not running.

You downloaded the installer for the exporter plugin that matches Unreal Engine version you intend to use.

You uninstalled all previous versions of the Datasmith Exporter for Revit plugin.

After you downloaded the installer, double-click it to open, then follow the instructions on-screen.

When you launch Revit after you installed the exporter plugin, you might see the following warning: "The publisher of this add-in could not be verified. What do you want to do?" Click Always Load to confirm that you want the Datasmith Exporter plugin to be available each time you launch Revit.

If you need to uninstall the Datasmith Exporter for Revit plugin, you can do this from the Control Panel, like any other Windows application.

Controlling What Gets Exported

You always need to have a 3D View selected and active in Revit in order to export your scene using the Datasmith Exporter plugin. The visibility settings of that 3D View define what elements from the Revit file get included in the exported .udatasmith file.

You can use any 3D View that you already have in your Revit file. However, to take full control over the objects that you bring in to Unreal Engine, we recommend that you set up a new 3D View in Revit, and set up that view so that it shows only the objects that you need in your realtime visualization.

Revit offers many tools and techniques for controlling the visibility of objects inside a 3D View. For example:

You can use the Graphics > Visibility/Graphics Overrides to control the visibility of the different objects and object categories in your Level.

Click for full image.

You can use a Section Box to cut the geometry you export. Only the objects inside your Section Box are exported to Unreal Engine. Note that when an object crosses the boundaries of the Section Box, such as the walls, floor and furniture in the images below, its geometry is truncated. Inside Unreal Engine, the Static Mesh Assets that represent the exported objects only contain the geometry that lies inside the Section Box.

Click for full image.

Temporary Hide and Isolate settings in Revit are respected.

Only geometric objects visible in the current 3D View are exported. Non-geometric objects are ignored.

The Datasmith Exporter respects your choice of which objects are shown and which are hidden, but it does not take into account other settings that control the way the 3D View is drawn in the Revit viewport. For example, it does not take into account the Graphics > Graphic Display Options set for the 3D View (Realistic vs. Shaded Model Display, Cast Shadows, and so on) or the Camera > Rendering Settings (Draft vs. High Quality settings, Lighting schemes, and so on).

For more information about controlling visibility in a Revit 3D View, see also Visibility and Graphic Display in Project Views in the Revit Help.

Geometry

In general, each element that you can select individually in the Revit scene is translated to Unreal as a separate Static Mesh Asset. Some elements, such as railings, may be broken down further into smaller Static Meshes when they are made up of smaller parts.

In all cases, the geometry of each Static Mesh Asset is set to match the dimensions of the Revit object at the time you export the file. Parametric settings and constraints are not carried over into Unreal Engine. So, for example, if you move a floor up or down in the Unreal Editor, the height of the walls will not stretch or shrink to match the new location as it would in Revit.

Instancing

If two objects belong to the same family, and if they have exactly the same parameter values, then both objects are represented in the Datasmith Scene as instances of the same Static Mesh Asset.

Tessellation

Datasmith relies on Revit's built-in tessellation services to create triangular meshes from your scene geometry. In most cases, this produces adequate geometry for use in Unreal Engine. However, if you find these surfaces to be a problem in your Projects, you can try tools offered by the Unreal Editor for reducing the complexity of these meshes, such as the Proxy Geometry tool.

You can also manually specify the level of tessellation for meshes that Revit creates from the Datasmith Export Settings panel. These levels are defined by the Revit API.



Level 8 is the default level of tessellation. This produces the same mesh resolution than with the Revit FBX Exporter:





Level 2

Level 8

Linked Models

If your Revit scene contains any Linked Models — that is, references to other Revit files — Datasmith attempts to find the linked files on your computer using the paths saved in the Revit file. Datasmith includes the data from all linked files that it is able to find in the Datasmith Scene it creates in Unreal Engine.

Materials and Textures

For each different type of surface in your Revit scene, Datasmith creates a new Material Asset in the Unreal Engine project, and places it in the Materials folder next to your Datasmith Scene Asset. The goal of these Materials is to respect the way you've set up the surfaces to look in Revit, while also exposing a set of properties that closely mirror the ones you are used to working with in Revit.





Revit

Unreal

Datasmith currently supports translating diffuse maps and colors, Transparency, Cutouts, and Bump settings from Revit into the Unreal Engine Materials it generates.

To modify a Material in the Unreal Editor:

Double-click it in the Content Browser. Alternatively, select an Actor in your Level that uses the Material you want to modify, and double-click the Material in the Details panel.

This opens the Material Editor shown above, where you can modify these parameters in the Parameter Groups section at the top of the Details panel. You can also modify other built-in parameters exposed by the Unreal renderer.

To override the default value for any property, first check the box to the left of its name to activate the property in your Material. Then, set the value you want the property to use.

Each of these Assets is a Material Instance, whose parent is the RevitMaster Material built in to the Datasmith plugin. You can open up this parent Material to see how each of the properties exposed in the Material Instance are wired together in the Material graph.

Textures and UV Wrapping

Datasmith imports the textures that you use in your Revit Materials into Assets, and places them in the Textures folder next to your Datasmith Scene Asset.

Each Material that uses a Texture Asset offers similar settings to the Revit Texture Editor to control the way the texture map is applied to the surface of the 3D object using the Material.



The Position > Offset value in Revit is modeled by the UVOffsetX and UVOffsetY settings for each type of map.

The Position > Rotation value in Revit is modeled by the UVWAngle setting for each type of map.

The Scale values in Revit, which are based on real-world dimensions, are converted in the Unreal Engine Material to a scale multiplier. As you increase the absolute value of these scale values, the texture becomes smaller on the object.

Datasmith does not convert procedural textures, such as Checker, Noise, Tiles, and so on.

Building the Datasmith Scene Hierarchy

The Datasmith Exporter plugin creates a hierarchy of parent and child Actors in the Datasmith Scene that is intended to reflect the overall organization of your scene in Revit. The intent is to organize the Actors in your Unreal Engine Level according to the concepts you're used to working with in Revit, to make it easier for you to find and work with objects.

This scene hierarchy is constructed according to the following rules:

Each Level in Revit — the Ground Floor, Level 1, Level 2, and so on — is reflected by a separate Actor in the Datasmith Scene hierarchy.

Within each Level, any object that can host other scene elements in Revit becomes a parent for the objects it hosts.

Under the parent Actors that represent the Revit Levels and Hosts, you'll find a Static Mesh Actor to represent each geometric object.

For example, the Actor named Level 1 contains an Actor that represents each wall. Each of these Actors in turn is represented by another parent Actor that has a child for each geometric object hosted by the wall — that is, each door, window, or wall section.



For most "compound" Revit objects, such as curtain walls or railings, the scene hierarchy contains only one Actor to represent the compound object. That Actor contains a Static Mesh Component for each of the sub-objects that the compound element is composed of.

For example, a curtain wall in Revit typically comes through to Unreal Engine as a single Actor. That Actor has a separate Static Mesh Component for each mullion and each panel that makes up the curtain wall.

Lights

Datasmith imports the lights from your Revit scene into Unreal Engine, maintaining the physical units you've set for their intensity.

Cameras

When you import a 3D View from Revit, Datasmith creates a single CineCameraActor in the Unreal Editor Level. It places this camera at the position and orientation of the camera in the Revit 3D View, with a similar field of view. If you select this CineCameraActor in the Level Viewport or the World Outliner, you'll see a preview of its viewpoint that should match very closely the Crop Region of the Revit 3D View at the time you exported your .udatasmith file.

Datasmith does not handle some camera concepts available in Revit, including orthographic projection mode and perspective corrections like tilted, shifted, and cropped regions.

For best results:

Set the Camera > Projection Mode setting for your 3D View to Perspective.

Set the Crop Region for your 3D View in Revit to focus on the view that you want your camera to have in Unreal Engine.

Make sure your camera's target point in Revit is centered within the crop area. You can verify this by showing the camera in other plan and elevation views. If the perspective is shifted, your result in Unreal Engine will not look the way you're expecting.

For example, the 3D View below has a perspective camera with a centered crop region, which translates well:





However, the following 3D View has had its crop region adjusted by hand, shifting one edge of the perspective region unequally toward the target point. This will not translate well.





Categories

Each Revit Category that contains at least one object in the scene carries over into the Unreal Editor as a separate Layer.



You can use these Layers within the Unreal Editor to show and hide categories, or inspect and select the objects assigned to them.

Note that the information provided to the exporter by the Revit SDK does not always link every scene object to a Category. Objects with no assigned Category in Revit are not assigned to any Layer in the Unreal Editor.

Metadata

When you select an element in a Revit view, the Properties palette shows a list of all instance properties that are assigned to that element. You can change these values freely, and add your own custom properties.

Click for full image.

For details on setting and using these properties, see the Revit help.

When you use Datasmith to import a Revit scene into the Unreal Editor, Datasmith assigns all instance properties for each Revit element as metadata on the Static Mesh Actor that it creates for that element in the Unreal Engine Level. This metadata also includes any type properties for the object's Revit type that are not empty.

Because Datasmith metadata is always a flat list of key-value pairs, the category headings in the Properties palette (such as Constraints, Structural, Dimensions and Identity Data in the image above) are not included. Only the names and values of the actual properties are preserved.

Some other, more technical internal information is attached to each Actor using Component Tags. You might find this information useful for identifying the Actors, particularly if you use Blueprint or Python scripts to automate data preparation in the Unreal Editor. For example:

Revit.Instance.Depth. - The depth of the object's family instance or family symbol in the Revit scene hierarchy.

Revit.Instance.Id. - The ID of the object's family instance or family symbol in the Revit document.

Revit.Host.Id. - When the object's family instance is hosted, this value gives the ID of the family instance host in the Revit document.



You can filter the amount of metadata that gets exported with .udatasmith files or via Direct Link from the Settings menu on the Datasmith toolbar inside Revit. This can help reduce the amount of data to be exported, which affects both export performance and the size of the exported Datasmith scene.



Settings for metadata export.

Use the Add Group and Remove Selected buttons to add or remove metadata that you want to be included with the exported Datasmith scene.

Note the following:

The metadata categories are defined by Revit and cannot be changed.

This filter affects both regular export (as a .udatasmnith file) and Direct Link setups.

The list of categories you add to the export filter will be saved within the Revit file.

If the list is completely empty, all metadata will be exported.

RPC Objects

Datasmith brings Rich Photorealistic Content (RPC) objects from Revit scenes into Unreal Engine. For each type of RPC object in your Revit scene, Datasmith imports the visible geometry that you see in Revit into a new Static Mesh Asset. For each of those RPC object types that you have placed in your Revit scene, Datasmith creates a new Static Mesh Actor in the Unreal Engine Level with the same position and orientation in 3D space.



You can find these RPC objects in your Unreal Engine Level by looking for Actors that have been assigned the Revit.RPC Component Tag:



This can be useful if you want to automate a way to replace the placeholder entourage objects used in Revit with alternatives more suited to your 3D realtime visualization.

Survey Points and Base Points

If your Revit scene contains a Base Point or Survey Point, Datasmith imports those points into the Unreal Engine Level, representing them with plain Actors that contain no visible geometry. It records the data about the survey point and base point in Datasmith Metadata on those Actors:





Base Point

Survey Point

When exporting a Datasmith scene, the orientation of the model will be based on the Project Base Point (Project / Plan North). To match the orientation of the exported Revit model with the Survey Point (True North), the Project Base Point needs to be have the same rotation as the Survey Point.

See also Metadata above and Using Datasmith Metadata.

All scenes and models used on this page are courtesy of Turbosquid.

End Result

Once you've installed the Datasmith Exporter plugin for Revit, you'll have a Datasmith ribbon that you can use to export a selected 3D view to a .udatasmith file.



Follow the steps below in Revit to export your scene using this file type.

In the Project Browser, select and open the 3D View that you want to export. The Datasmith Exporter plugin uses the visibility settings defined for the current 3D View to determine what parts of the scene it should export. For details, see Revit.

Open the Datasmith ribbon, then click Export 3D View.

In the Export 3D View to Unreal Datasmith window, browse to the location you want to save your .udatasmith file, and use the File Name box to give your new file a name.

Click Save.

End Result

You should now be ready to try importing your new .udatasmith file into the Unreal Editor. See Importing Datasmith Content into Unreal Engine and Reimporting Datasmith Content.

Along with your new .udatasmith file, you'll see a folder that has the same name but with the suffix _Assets. If you move your .udatasmith file to a new location, make sure that you also move this folder to the same location.

Installing the Plugin

How It Works

Using the Batch Exporter

Similar to the Blueprint scripting system in Unreal Engine, Dynamo for Revit is a visual programming language that gives access to the Revit API and is used to easily automate many repetitive tasks. In addition to being accessible from the add-ins Ribbon toolbar, the Autodesk Revit Exporter for Datasmith uses Dynamo to automate the process of exporting your Revit 3D views as .udatasmith files for use in Unreal Engine.

Installing the Plugin

Begin by downloading and installing the Autodesk Revit Exporter for Datasmith plugin available from Epic Games. This will update any previous version of the plugin that has been installed, as well as add some additional hooks for the Dynamo visual scripting language.

The plugin requires your Dynamo to be version 2.0 or higher. Check this by clicking the Help menu in the Dynamo UI and selecting the About option.

After installing the plugin, launch the Dynamo interface:



Next, you need to import the DatasmithDynamoNode.dll file. In the Dynamo UI, click the File menu and select the Import Library option. You will find the library in one of the following locations:

Revit Version

Location

2018.3

C:\ProgramData\Autodesk\Revit\Addins\2018\DatasmithRevit2018\DatasmithDynamoNode.dll

2019

C:\ProgramData\Autodesk\Revit\Addins\2019\DatasmithRevit2019\DatasmithDynamoNode.dll

2020

C:\ProgramData\Autodesk\Revit\Addins\2020\DatasmithRevit2020\DatasmithDynamoNode.dll

To confirm that the installation of the library is successful, you should see a DatasmithDynamoNode entry in the Add-Ons section of the Dynamo Library.

How It Works

Importing the library installs the Datasmith Dynamo node, which is designed to take in data from your Revit document and export the requested views with a specific level of tessellation:



Number

Description

1

Current Revit document

2

Output path

3

List of Views as ID's

4

Level of tessellation (integer value 1-15, default 8)

Using the current Revit file as the document, the node outputs a .udatasmith file, and a folder of objects in the 3D view as .udsmesh files that are ready for Datasmith.

To demonstrate the use of the Datasmith Dynamo node, the plugin contains a sample Dynamo script file that shows how to use the node to create a batch exporter:



The script goes through the following steps:

Using the Get 3D Views node, the script finds all the 3D views in the current Revit document and adds them to a list.

It then filters the list, looking for either a prefix added to the view name (using the format Prefix_ViewName) or views that are given a specific name. In the example, the prefix default is set to Datasmith, while the Instance Parameter Name default is DatasmithExport.

Next, the script looks at two boolean values to determine whether you want to export all the views or only the views found in the filtered list.

Finally, the chosen views are exported to the chosen folder with an amount of detail defined by the Mesh Tessellation Amount.

To avoid dependencies on the Dynamo API, this version of the batch exporter requires the use of a python node to fetch information about the current document:



Similarly, getting the 3D Views and extracting the ElementID of a given view relies on python nodes:



Using the Batch Exporter

The supplied Dynamo example can be executed and used as a basic batch exporter:



Property

Description

Export To:

Allows you to browse to a folder and specify where you want your Datasmith files.

Mesh Tessellation Amount:

Specify the level of tessellation used during the export as defined by the Revit API. Level 8 is the default. This produces the same mesh resolution as the Revit FBX Exporter.

Tesselation Level 8



Tesselation Level 2





Export All 3D Views:

If ON, this will export every 3D view found in the current Revit document. If OFF, this will find the 3D views in the current Revit document that use a custom name or prefix and export those for Datasmith.

By View Name Prefix / By View Instance Parameter:

Exports only the views that match either a prefix name or a project parameter assigned to a view instance.

If TRUE: Filter by parameter.

If FALSE: Filter by View Name Prefix.



View Instance Parameter Name:

Defines the view name that will be exported.

Export 3D Views Prefixed With:

Defines the view name prefix that will be exported.

Rhino Workflows

Export Workflow

Direct Link Workflow

Using the Datasmith Toolbar

Installation Notes

Converting Geometry into Static Meshes

Instancing

Tessellation and Render Meshes

Mesh Modifiers

Triangle Facing Direction

Rhino Materials

Named Views

Rhino Metadata

Building the Datasmith Scene Hierarchy

This page describes how Datasmith imports scenes from McNeel Rhinoceros (Rhino) into Unreal Engine. It follows the basic process outlined in the Datasmith Overview and Datasmith Import Process, but adds some special translation behavior that is specific to Rhino. If you plan to use Datasmith to import scenes from Rhino into Unreal Editor, reading this page can help you understand how your scene is translated, and how you can work with the results in Unreal Editor.

Rhino Workflows

Export Workflow

Datasmith uses an export workflow for Rhino. This means that to get your Rhino content into Unreal Engine using Datasmith, you need to:

Install the Datasmith Exporter plugin for Rhino. See the Installation Notes section below.

Export your Rhino content using the Save As or Export process. See Exporting Datasmith Content from Rhino.

Use the Datasmith importer available in the Toolbar of the Unreal Editor to import your .udatasmith file. See Importing Datasmith Content into Unreal Engine.

Direct Link Workflow

To preview changes to your Rhino scene in Unreal Engine in real time, you can set up a Datasmith Direct Link between the two. This way, you don't need to manually re-import the entire scene into Unreal Engine every time you want to make a change. For more information, see Using Datasmith Direct Link documentation.

Using the Datasmith Toolbar

Installing the Datasmith plugin adds a dockable toolbar in Rhino.



Datasmith Toolbar in Rhino

You can trigger the same operations by entering their associated commands in Rhino's command line.

To see all of Datasmith's commands, open the Plugin Manager window in Rhino (run PlugInManager in the command line), and select the Datasmith Exporter plugin.

Button

Description

Command Line

Synchronize

Push the selected models through the Direct Link connection.

To quickly select everything in your scene, press Ctrl + A (Windows) or Cmd + A (Mac).

DatasmithDirectLinkSync

Connections

Launches the Connection Status dialog.

DatasmithDirectLinkConnections

Export 3D View

Launches the existing .udatasmith exporter to save a .udatasmith file to disk.

DatasmithExport

Messages

Launches the messages and logging window. This is useful for reporting errors, missing textures, and other information.

DatasmithMessages

After installing the plugin, Rhino will add the Datasmith toolbar to the interface. If you uninstall the plugin, this toolbar will automatically be removed. Any copy of the Datasmith toolbar added to your default toolbar by dragging from the Toolbar section of the Options menu will not be removed by the uninstall process and will need to be removed manually.

Installation Notes

Before you can export Rhino content, you must download and install the Datasmith Exporter for Rhino plugin from the Datasmith Export Plugins page.

To see what versions of Rhino the plugin supports, see Datasmith Supported Software and File Types.

We encourage you to share the download link to the Datasmith Exporter plugins with any number of people, both inside and outside of your organization. Please note that you are not permitted to distribute the Datasmith Exporter plugins themselves.

Before you install the Datasmith Exporter for Rhino plugin, make sure that:

Rhino is not running.

You downloaded the installer for the exporter plugin that matches the Unreal Engine version you intend to use.

You uninstalled all previous versions of the Datasmith Exporter for Rhino plugin.

After you downloaded the installer, double-click it to open, then follow the instructions on-screen.

If you need to uninstall the Datasmith Exporter for Rhino plugin, you can do this like you would any other application:

Windows: Uninstall the plugin from the Control Panel.

macOS: Find the plugin in Finder and drag it to the trash icon on your Dock, or right-click and select Move to Trash.

Converting Geometry into Static Meshes

Datasmith creates a separate Static Mesh Asset for each separate mesh, solid, or surface in the Rhino file. If the object has its Name property set in the Properties panel in Rhino (shown on the left in the image below), Datasmith uses that name for the Static Mesh Asset (shown on the right in the image below). Any Actors that Datasmith creates in your Level that refer to that Static Mesh Asset also use the same name.



Click for full image.

Instancing

When Datasmith detects multiple instances of the same block in your Rhino scene, it only creates one set of Static Mesh Assets for the geometry in that block. It then places multiple instances of those Static Meshes into the scene. This is typically better for the runtime memory requirements and performance of your Project. It also makes it easier to manage the number of Static Meshes in your Content Browser.

Wherever possible, we recommend taking advantage of this by making any repeating elements in your scene (such as windows, doors, or chairs) into blocks in Rhino.

For details, see the Rhino documentation.

Tessellation and Render Meshes

Unreal Engine always renders objects using triangular meshes. If you have objects in your Rhino file that are defined as parametric surfaces, or NURBS, these surfaces need to be transformed, or tessellated, into triangular meshes. Datasmith will utilize the Rhino tessellation options located in File > Properties > Document Properties | Mesh:



Click for full image.

Name

Description

Jagged and Faster

Creates a lower density mesh to shade objects quickly at the cost of some quality.

Smoother and Slower

Creates a higher density mesh to shade objects more accurately at the cost of speed.

Custom

Allows for greater control over the mesh created. The density slider roughly controls the density and number of polygons created from NURBS surfaces. Additional controls are available by clicking the Detailed controls button.

For more information on using custom render options in Rhino, see Polygon Mesh Detailed Options in the Rhino documentation.

Mesh Modifiers

Rhino supports a number of ways to change the appearance of a mesh without the need to directly edit the mesh.

The following mesh modifiers are preserved when you export your data from Rhino using Datasmith:

Shut Lining

Edge Softening

Displacement

Curve Piping

Thickness



Click for full image.

Triangle Facing Direction

The surface maintains orientation when exporting to Datasmith. A way to visualize surface orientation within Rhino is to set the colors of backfaces to a bright green color. Do this by opening the Document Properties and selecting View > Display Modes > Rendered. In that menu, in the Shading Settings, the options for Backface settings appear. Finally, change the Single color for all backfaces color to bright green:



Click for full image.

This way you can check before exporting to Datasmith whether or not faces orient correctly:





For a complete discussion and recommended solutions, see Datasmith Import Process.

Rhino Materials

For each different surface material that Datasmith finds in your Rhino scene, it creates a separate Material Asset in Unreal Engine with the same name. Each Material is then placed in the Materials folder next to your Datasmith Scene Asset.

Each Material in the Materials folder is a Material Instance that exposes properties set in the Rhino file: color values, texture maps, and so on. You can change these exposed properties to modify the way the Material looks when applied to a surface. Datasmith assigns these Material Assets to the Static Mesh Assets it creates to shade their surfaces the same way they appear in your Rhino renders. Datasmith only imports materials from Rhino objects into the Unreal Engine. It ignores Rhino display colors completely. This makes the visual result of your import into the Unreal Engine match the result of rendering in Rhino as closely as possible.

Datasmith also creates a set of parent Materials in the Materials/Master folder. Each of these is the parent of at least one of the Material Assets in the Materials folder. You can edit these parent Materials if you want greater control over the Material graphs that define how each surface appears, expose additional parameters to child instances, or change the way the exposed parameters are taken into account during rendering. Note that changing a parent Material also changes all Material Instances that inherit from that parent automatically. Consider duplicating a parent Material before you modify it, make your changes to the duplicate, then finally update specific Material Instances to use your new duplicate as their parent. For details, see Modifying a Datasmith Master Material.

Named Views

Named Views in Rhino are the equivalent of Cameras in Unreal Engine. When imported into Unreal Engine via Datasmith, each Named View becomes a separate CineCameraActor in the Scene.



Click for full image.

Rhino Metadata

Data input in the Attribute User Text menu exports as Datasmith Metadata:



Click for full image.

Data is entered into the table as a key value pair. For more information on using Attribute User Text, see Attribute User Text in the Rhino documentation

Building the Datasmith Scene Hierarchy

Datasmith builds its scene hierarchy from your Rhino model as follows:

For each layer in your Rhino scene, Datasmith creates an Actor in Unreal Engine to act as the parent for all objects on that layer. Note that unlike the layers it creates in the Layers panel of the Unreal Editor, this hierarchy of Actors is not flattened. The Actors are nested exactly like the layers in your Rhino scene.

Under the Actor that represents each layer, every instanced block on the corresponding layer is represented by another Actor.

Finally, the Actor that represents each layer and each block contains Static Mesh Actors that represent the actual geometry objects that make up that layer or block. Points in Rhino are represented as empty Actors in Unreal Engine. This preserves the points as

Groups in Rhino do not affect the Unreal Engine scene hierarchy, as they are considered selection helpers rather than important elements in the scene hierarchy.

For example, in the image below, you can see that every layer in the Rhino hierarchy has a counterpart Actor in the Unreal Editor. Layers like lights > turn signals, which contain only geometry objects in Rhino, contain only the corresponding Static Mesh Actors in the Unreal Editor. The lights layer in Rhino also contains two block instances, named left_headlight and right_headlight. Each of these is represented by a nested Actor in the Unreal Editor that in turn contains the geometry objects that make up those blocks.



Click for full image.

The model used on this page is courtesy of Turbosquid user tomashorin.design.

End Result

Once you install the Datasmith Exporter Plugin for Rhino, you have an Unreal Datasmith (.udatasmith) filetype available to you when you save or export a scene.



Follow the steps below in Rhino to export your scene using this new filetype.

From the Rhino File menu, select either one of the following options:



Save As: A .udatasmith file is created containing all visible elements.

Export Selected : A .udatasmith file is created containing all the selected elements. Layers containing no selected elements are not exported.

Export with Origin : A .udatasmith file is created containing all visible elements. The scene exports with the specified position offset.

In the Export window, select the Unreal Datasmith (.udatasmith) option from the Save As type dropdown.



Browse to the location where you want to save your exported file, set the File name, and click Save.

Alternatively, click the Export 3D View button on the Datasmith Toolbar. This creates a .udatasmith file containing all visible elements.



For more information about the Datasmith toolbar, see Using the Datasmith Toolbar.

End Result

Your .udatasmith file should now be ready to try importing into Unreal Engine 4. See Importing Datasmith Content into Unreal Engine. If your data needs additional cleaning, merging, or other modifications during the import process, see Dataprep Import Customization.

SketchUp Workflows

Export Workflow

Batch Scene Export with Ruby

Direct Link Workflow

Installation Notes

Using the Datasmith Toolbar

Converting Geometry into Static Meshes

Instancing

Billboards

Triangle facing direction

SketchUp Materials

Colors and Texture Images

Opacity and Blend Modes

UE Extended Properties

Metadata

This page describes how Datasmith imports scenes from Trimble SketchUp Pro into Unreal Editor. It follows the basic process outlined in the Datasmith Overview and About the Datasmith Import Process, but adds some special translation behavior that is specific to SketchUp. If you're planning to use Datasmith to import scenes from SketchUp into Unreal Editor, reading this page can help you understand how your scene is translated, and how you can work with the results in Unreal Editor.





SketchUp Workflows

Export Workflow

Datasmith uses an Export Plugin workflow for SketchUp. This means that to get your SketchUp content into Unreal using Datasmith, you need to:

Install a plugin for SketchUp. See the Installation Notes section below.

Export your SketchUp content to a .udatasmith file. See Exporting Datasmith Content from SketchUp Pro.

Enable the Importers > Datasmith Importer Plugin for your Project, if it's not already installed.

Use the Datasmith importer available in the Toolbar of the Unreal Editor to import your .udatasmith file. See Importing Datasmith Content into Unreal Engine.

Batch Scene Export with Ruby

You can run a Ruby script in SketchUp to batch export .udatasmith files. This helps automate your pipeline.

Before you can do this, you need to install the Ruby Code Editor extension for SketchUp. For instructions on how to do that, see the SketchUp documentation on Managing Extensions. Once you install the Ruby Code Editor extension, you can access it from SketchUp's main menu: Window > Ruby Code Editor.

To export all SketchUp files from a given folder, run this code:

You can also export a single file from code. This is the equivalent of clicking the Export button on the Datasmith toolbar:

Direct Link Workflow

To preview changes to your SketchUp scene in Unreal Engine in real time, you can set up a Datasmith Direct Link between the two. This way, you don't need to manually re-import the entire scene into Unreal Engine every time you want to make a change. For more information, see Using Datasmith at Runtime,

For Unreal Engine, Datasmith DirectLink is only supported on UE 4.27 and later versions, when using one of the following SketchUp versions:

SketchUp 2020 (Windows and macOS)

SketchUp 2021 (Windows and macOS)

Installation Notes

Before you can export SketchUp content, you must download and install the Datasmith Exporter for SketchUp plugin from the Datasmith Export Plugins page.

To see what versions of SketchUp the plugin supports, see Datasmith Supported Software and File Types.

The Datasmith exporter plugin currently only works with SketchUp Pro. It does not support SketchUp Free, or the discontinued SketchUp Make.

We encourage you to share the download link to the Datasmith Exporter plugins with any number of people, both inside and outside of your organization. Please note that you are not permitted to distribute the Datasmith Exporter plugins themselves.

Before you install the Datasmith Exporter for SketchUp plugin, make sure that:

SketchUp is not running.

You downloaded the installer for the exporter plugin that matches the Unreal Engine version you intend to use.

You uninstalled all previous versions of the Datasmith Exporter for SketchUp plugin.

After you downloaded the installer, double-click it to open, then follow the instructions on-screen.

If you need to uninstall the Datasmith Exporter for SketchUp plugin, you can do this like you would any other application:

Windows: Uninstall the plugin from the Control Panel.

macOS: Find the plugin in Finder and drag it to the trash icon on your Dock, or right-click and select Move to Trash.

Using the Datasmith Toolbar

Installing the Datasmith plugin adds a toolbar in SketchUp.



You can take the following actions from the Datasmith toolbar:

Action

Button

Description

Synchronize with DirectLink



Pushes the selected models to Unreal Engine or Twinmotion through the Direct Link connection.

Manage Connections



Launches the Connection Status dialog.

Export to Datasmith File



Launches the existing .udatasmith exporter to save a .udatasmith file to disk

Show Messages



Launches the messages and logging window. Useful for reporting errors, missing textures, and other information.

You can also use these commands from SketchUp's main menu by going to Extensions > Datasmith.

Converting Geometry into Static Meshes

Datasmith divides your SketchUp geometry into Static Mesh assets by combining all connected polygon faces that are in the same component or group, into a single Static Mesh. Knowing this strategy can help you influence the Static Meshes it creates.

If your Static Meshes in Unreal are very large, you may have trouble achieving good results when baking static or stationary lights for your scene. Large meshes require correspondingly large lightmap textures in order to make sure that each part of the model has an adequate amount of texture space to record its light and shadow. You can try increasing the lightmap resolution on the large Static Meshes, but this also increases your baking time and runtime memory requirements. Depending on the way your lightmap UVs are laid out, you may not be able to generate good results at all. If this happens, you can try splitting your large geometries across multiple components or layers in SketchUp to make the Static Meshes easier to deal with in Unreal.

Instancing

When Datasmith detects multiple copies of the same component in your SketchUp scene, it only creates one set of Static Mesh assets for that component, and places multiple instances of those Static Meshes into the scene. This is typically better for the runtime memory requirements and performance of your Project, as well as making it easier to manage the number of Static Mesh assets in your Content Browser.

Wherever possible, we recommend taking advantage of this by making any repeating elements in your scene (such as windows, doors, or chairs) into reusable components in SketchUp.

Billboards

Datasmith exports rotating billboards from your SketchUp scene as flat Static Meshes, and places instances of these flat Static Meshes into the Level.

The orientation of each Static Mesh in the Level is based on the viewpoint of the SketchUp camera at the time you export your scene. When the camera in the Unreal Engine is at the same location in the Level as the original camera in SketchUp, the flat Static Mesh appears the same way as the rotating billboard does in SketchUp. However, as you move the camera around in the Unreal Engine, the rotation of the Static Mesh does not update to match the camera's current viewpoint the way it does in SketchUp.

Triangle facing direction

SketchUp is very permissive about the facing direction of your geometry. You can create "single-sided" geometry — that is, geometry with no thickness — and see it from both sides; you can even apply different materials to the different faces of each plane.

The Unreal Engine uses a different approach: it assumes that all geometry is modeled with a thickness. Any triangles that face away from the camera represent the back side of a surface, and can be assumed to be hidden from view by the front side of that surface. In order to achieve the best possible performance at runtime, it always culls those back-facing triangles to avoid spending GPU cycles rendering triangles that aren't actually visible.

We recommend always modeling your 3D objects with a thickness, so that they work as expected in Unreal. However, if you do use single-sided geometry in SketchUp, Datasmith does its best to respect your intent in the way it assigns materials and facing directions to the triangles in your Static Meshes:

If only one side of your surface in SketchUp has a material assigned, that surface is chosen for the facing direction of the triangle in Unreal.

Otherwise, Datasmith chooses the front side of the surface in SketchUp as the facing direction in Unreal.

If you have a material assigned to both sides, Datasmith imports only the material from the front side.

By default, this means that triangles in single-sided geometry won't appear in your Unreal scene when you look at them from the back side. In addition, the back-facing side does not cast shadows.





In the example above, the sides and bottom of each box face outward. On the left, each side has a single material assigned to its out-facing side. In the center, each has two materials assigned, one to each side. On the right, the red material are assigned to the whole group, and one individual side of the box has a different material assigned specifically to it. The colors on the outward facing sides all translate to Unreal, but the sides facing away are only visible when you look at the boxes from the other side.

The best way to deal with this is to fix it in SketchUp, by giving your objects a thickness. However, if you want to fix the problem in Unreal, there are other options. For a complete discussion, see About the Datasmith Import Process.

SketchUp Materials

For each material in your SketchUp scene, Datasmith creates a new Material Instance in your Unreal Engine Project, attempting to replicate your SketchUp Materials as closely as possible. Each of these Material Assets is an instance of a Parent Material that Datasmith also creates in your Project, in the Materials/Master folder. Datasmith creates the Material graph for each of these Parent Materials with the goal of producing equivalent results in the Unreal Engine's physically based renderer to the results you see when rendering in SketchUp.

Not every Instanced Material has its own Parent. Where possible, if two different Material Instances can share the same Material graph, Datasmith attempts to use a single Parent Material for both Material Instances.

The Material properties you see in Unreal depend on how the SketchUp Material was configured. You can add further Material properties by editing the Parent Material's PBR graph.

These properties will be overwritten if you reimport the scene again from SketchUp.

You can edit Parent Materials to add or override the properties outlined below.

Colors and Texture Images

By default, imported Materials keep the textures or colors that they have in SketchUp. You can override this to make your Material use either a solid color or a texture.

Activate either the Color option or the Use Texture Image option. (If you don't see a Color option at all, de-activate the Use Texture Image option first.)

To use a solid color, set the RGB color values to produce the color you want. Note that the A channel is not used: alpha blending is controlled by a separate Opacity option (see below).

If you choose to use a texture image, you'll see a Texture property, which you can set to refer to the Texture Asset you want to use. (If you want to use a texture that isn't already in your Unreal Project, drag and drop it into your Content Browser to import it into your Project.) You can also use the Texture Scale control if you need to change the way the texture is tiled across the surface. The R value controls horizontal scaling (the U axis in UV space), and the G value controls vertical scaling (the V axis in UV space). The B and A values are not used.

The effect of different texture scale settings.



Opacity and Blend Modes

Whether you use a solid color or a texture map for your Material's base color, you can use the Opacity control to determine how much of the background you can see through the Static Mesh.

By default, if your material in SketchUp has an opacity value below 100%, that value should come through correctly to your Material in Unreal.

If you want to give an Opacity setting to a previously non-transparent Material in Unreal, you have to change the Material's blending mode. In the General section, expand the Material Property Overrides group, check the Blend Mode option, and set its value to Translucent.



Click for full image.

UE Extended Properties

By default, all imported materials are set as non-metallic, with a balanced Roughness value of 0.5. However, you will likely find that tweaking these values for different Materials is an easy way to increase the realism of your scene's rendering in Unreal. You'll find these values under the UE Extended group pf properties:



For any object that is made of metal, select the Metallic option. This makes a subtle difference in the way the base color or texture affects the incoming light that hits the surface.





If the surface of your object is particularly matte or glossy, check the Roughness option and raise or lower the value.





If different parts of your object need to have different glossiness, you could instead opt to use a Roughness Map: a greyscale texture image in which you color the parts that you want to be matte in white, and the parts that you want to be glossy in black.

For more about how the Roughness and Metallic values interact to create shiny surfaces, see also Creating Shiny Materials.

In addition, you can set up Normal Maps for your imported Materials. These give the renderer hints about the small-scale surface details of your geometry:





You can generate Normal Maps and Roughness Maps in 2D image creation software like Adobe Photoshop. In some cases, as with the texture shown above, you may be able to base those Normal Maps and Roughness Maps on your Material's Base Color Textures.

Metadata

For each component you create in SketchUp, you can set Advanced Attributes such as price, size and status:



Entity Info on SketchUp Components or SketchUp Groups are exported as standard Datasmith metadata. Unreal Engine will store metadata on the Actor representing the root of the SketchUp Component or SketchUp Group.

The Datasmith metadata might be attached to the Actor that represents your component in the scene hierarchy, not to any of the individual Static Mesh Actors that represent the geometry of that component. If this is the case in your scene, you will need to adjust the Blueprint and Python examples shown in Accessing Metadata in Blueprint and Python.

End Result

Once you've installed the Datasmith Exporter plugin for SketchUp, you'll have a new .UDATASMITH file type available to you when you export a scene.

Installing the Datasmith plugin for SketchUp adds a new toolbar.



After you install the Datasmith Exporter Plugin for SketchUp, you will have an Unreal Datasmith (.udatasmith) filetype available to you when you save or export a scene.

Follow the steps below in SketchUp to export your scene using this new file type.

Click the Export button on the Datasmith toolbar.



In the Export Model window, name your file and verify that the file extension in the Save as type drop-down list is .udatasmith.



Browse to the location where you want to save your new file, set its file name, and click Export.

End Result

You should now be ready to try importing your new .udatasmith file into the Unreal Editor. See Importing Datasmith Content into Unreal Engine.

Along with your new .udatasmith file, you'll see a folder that has the same name but with the suffix _Assets. If you move your .udatasmith file to a new location, make sure that you also move this folder to the same location.

Download and install the Solidworks Exporter Plugin

Install the Solidworks Exporter Plugin

Uninstall the Solidworks Exporter Plugin

Datasmith Workflows for Solidworks

Export Content From Solidworks

Preview Solidworks Content with Direct Link

How Datasmith Imports Content from Solidworks

Solidworks Feature Support

Converted Entities

Solidworks Data Loading Models

Materials and UVs

Configurations and Display States

Metadata

This page describes how to install the Datasmith Solidworks Exporter plugin, how to get Solidworks content into Unreal Engine using Datasmith, and how Datasmith imports scenes from Solidworks into Unreal Engine.

Download and install the Solidworks Exporter Plugin

To export Solidworks content with Datasmith, download and install the Solidworks Exporter plugin from the Datasmith Export Plugins page.

Make sure to download the plugin for the version of Unreal Engine you plan to use.

To see what versions of Solidworks the plugin supports, see Datasmith Supported Software and File Types.

Install the Solidworks Exporter Plugin

Before you install the Solidworks Exporter plugin:

Uninstall any previous versions of the plugin from your machine.

Make sure that Solidworks is not running on your machine.

To install the plugin, open the installer and follow the instructions.

If the plugin installer detects multiple versions of Solidworks on your machine, and at least one of these versions is supported, it will install the export plugin for all of the Solidworks versions it detects.

Uninstall the Solidworks Exporter Plugin

To uninstall the plugin, locate it in the Windows Control Panel, and remove it as you would any other Windows application.

Datasmith Workflows for Solidworks

You can get Solidworks content into Unreal Engine in the following ways:

Export a Solidworks scene as a .udatasmith file, and import it into Unreal Engine.

Use Direct Link to preview changes to your Solidworks scene in Unreal Engine in real time.

Export Content From Solidworks

To export Solidworks content as a .udatasmith file, you need to:

Install the Solidworks Exporter Plugin.

In Solidworks, load the scene you want to export.

From the main toolbar, open the Save menu (floppy disk icon), and select Save As.



In the Save As window, set Save as type to Unreal (*.udatasmith).

Datasmith saves your scene as a .udatasmith file that you can import into Unreal Engine. For details, see Importing Datasmith Content into Unreal Engine.

If you need to perform additional cleaning, merging, or other modifications to Solidworks data during the import process, you can use Dataprep. For details, see Dataprep Import Customization.

Preview Solidworks Content with Direct Link

Instead of manually re-importing a Solidworks scene into Unreal Engine every time you make a change, you can set up a Datasmith DirectLink between Solidworks and Unreal Engine to preview changes to your scene in real time. When you set up a Direct Link, the Unreal Engine preview updates whenever you make a change to the scene in Solidworks.

For more information, see Using Datasmith Direct Link.

In Solidworks, Datasmith Direct Link is available from the Unreal tab of the main toolbar.



You must Install the Solidworks Exporter Plugin to access Datasmith features, including DirectLink, in Solidworks.

How Datasmith Imports Content from Solidworks

This section describes what happens when you use Datasmith to convert and import objects from Solidworks scenes into elements in an Unreal Engine Project. Datasmith follows the process outlined in the Datasmith Overview and About the Datasmith Import Process, but adds some special translation behavior that is specific to Solidworks.

Solidworks Feature Support

The Datasmith Solidworks exporter supports the following features:

Product structure

Solid geometry

Textures and materials

Display states

Configurations

Metadata

The following features are not supported.

Animations

Lights

Cameras

Construction geometry: points, curves, planes

Converted Entities

When you import a .udatasmith file into Unreal Engine, Datasmith converts the following Solidworks entities into their Unreal Engine counterparts:

Solidworks

Unreal Engine

Sub-assembly

Actor

Part

Static Mesh

Part Instance

Static Mesh Actor

Configuration

Variant

Display State

Variant

Appearance

Material

Solidworks Data Loading Models

When you open an assembly file, Solidworks can load its active components as either lightweight or fully resolved. Depending on the selected mode, data from the model may or may not be available in Solidworks.

We recommend opening assemblies in fully resolved mode to guarantee that the most amount of information will be transferred through Datasmith. For more information, see Solidworks documentation on Components.

Materials and UVs

Solidworks does not have data for UVs associated with parts. Unlike Unreal Engine, Solidworks stores mapping information per material. When exporting data into a .udatasmith file, the Datasmith exporter bakes UVs into the static meshes using the material information. So, if a part is instantiated several times in the Solidworks assembly, and each part instance uses different materials, it may end up with multiple static meshes in Unreal Engine.

Configurations and Display States

If the Solidworks model has display states or configurations, Datasmith may create a Level Variant Set asset. This asset will hold the translated variant entity. For more information, see Solidworks documentation on Configurations.

Metadata

When you import a SolidWorks file, Datasmith adds a minimal amount of pre-set metadata to each Static Mesh Actor it creates, to indicate the part name and assembly of that mesh in the original SolidWorks design. Datasmith does not currently carry over any custom metadata properties that you add to your parts and assemblies.

One of the goals of Datasmith is to support the widest range of industry standard 3D design file formats used across industries including architecture, engineering, construction and manufacturing. For the most part, Datasmith treats each of these supported file formats in similar ways, and produces similar results, as described in the Datasmith Overview.

However, each of these supported file formats presents unique challenges and opportunities for the import process. The guides listed below detail additional considerations that are specific to each different data source.



Describes special considerations that apply when you use Datasmith to import content from CAD file formats.



Describes special considerations that apply only when you use Datasmith to bring scenes from IFC files into the Unreal Editor.

CAD Workflow

Tessellation

Chord Tolerance

Max Edge Length

Normal Tolerance

Stitching Technique

This page describes how Datasmith imports scenes from most supported CAD file formats into Unreal Editor. It follows the basic process outlined by the Datasmith Overview and Datasmith Import Process pages, but adds some special translation behavior that is specific to CAD files. If you're planning to use Datasmith to import scenes from CAD files into Unreal Editor, reading this page can help you understand how your scene is translated, and how you can work with the results in Unreal Editor.

CAD Workflow

Datasmith uses a Direct workflow for most CAD file types. This means that to get your content into Unreal using Datasmith, you need to:

Save your CAD scene to one of the supported file types.

Enable the Importers > Datasmith CAD Importer Plugin for your Project, if it's not already installed.

Use the Datasmith importer available in the Toolbar of the Unreal Editor to import your file. See Importing Datasmith Content into Unreal Engine.

To read more about other types of Datasmith workflows, see Datasmith Supported Software and File Types.

Tessellation

In CAD formats, you often use curves and mathematical functions to define surfaces and solids. The precision and smoothness of these surfaces is ideal for the manufacturing process. However, modern GPU chips are highly optimized for rendering surfaces that are made up of triangular meshes. Real-time renderers and game engines like Unreal, which need to push the limits of these GPUs in order to produce dozens of stunning photoreal quality images every second, typically only work with geometry that is made up of triangular meshes.

Datasmith bridges this gap by automatically computing triangular meshes that closely approximate any curved surfaces in your CAD file that don't already have mesh representations. This process is called tessellation, and it is an essential step in preparing your CAD data for use in real time.

For example, the image on the left shows a surface rendered in a native CAD viewer. The image on the right shows a wireframe of a triangular mesh that was generated for that surface.





Tessellating a surface for real-time rendering involves an implicit tradeoff between the accuracy of the surface and the speed that it can be rendered.

By nature, a triangular mesh can never exactly match the mathematically precise surface it was generated from. Tessellation always implies sampling the original surface at some level of detail to create an approximation that allows the GPU to render the geometry more quickly. Typically, the closer your mesh is to the original surface, the more complex it will be — that is, it will contain more triangles, and those triangles will be smaller. This may look better when it's rendered, but places higher demands on the GPU. If you lower the accuracy of your tessellated mesh, so that it contains fewer, larger triangles, the GPU will be able to render it faster, but that rendering may not give you the visual fidelity you're looking for — it may look blocky or jagged.

Therefore, your goal in the tessellation process is to minimize the number of triangles in your mesh, while maximizing its visual fidelity to the source. This usually means that you aim to have a relatively small number of larger triangles in places where the surface is smoother and flatter, and a relatively large number of smaller triangles in places where the surface is more complex and uneven.

Datasmith offers three parameters that you can adjust when you import a CAD scene, described in the following sections. By tweaking these values, you can control the complexity and fidelity of the Static Mesh geometry that Datasmith creates for your curved surfaces.

You can also override these same options for individual Static Mesh Assets. This allows you to set overall tessellation values for your scene, then override those settings for individual objects that need higher or lower levels of detail. For details, see Retessellating CAD Geometry.

Chord Tolerance

The chord tolerance, sometimes called the chord error or sag error, defines the maximum distance that any point on the tessellated surface can be from the corresponding point on the original surface.



Lowering the value of this parameter makes the tessellated surface stay closer to the original surface, producing more small triangles.

The effect of this setting is most visible in areas with greater curvature: as the tolerance value increases, the generated triangles become larger and the surface smoothness is reduced.







0.5mm: 37 500 triangles

0.5mm: 37 500 triangles

10mm: 13 500 triangles

Max Edge Length

This setting limits the maximum length of any single edge in any triangle in the tessellated mesh.



The effect of this setting is most visible in flatter areas of the model. If you set this value too low, you may see that these flat areas have more small triangles than they really need. On the other hand, if you set this value too high or don't set a limit, you may sometimes get oddly shaped triangles that are extremely long and thin, which are also best avoided.

If you set this value to 0, Datasmith does not limit edge lengths in its generated triangles.







10mm: 128 000 triangles

20mm: 43 700 triangles

40mm: 21 000 triangles

Normal Tolerance

This setting defines the maximum angle, in degrees, between any two adjacent triangles in the tessellated mesh.



Like the chord tolerance, the normal tolerance has an effect on how closely the tessellated mesh follows the original surface. However, it is particularly useful to preserve the level of detail in areas with high curvature, while having little effect on the triangles generated in flatter areas of the surface.







5°: 295 000 triangles

10°: 100 000 triangles

40°: 21 500 triangles

Stitching Technique

The Stitching Technique setting controls how the tessellation process handles parametric surfaces that appear to be connected, but that are actually modeled as separate bodies, or as separate surfaces within a body.

Stitching Sew looks for surfaces that should be connected, and combines their bodies into the same Static Mesh Asset. This option may reduce the number of separate Static Mesh Assets that Datasmith creates in your Project, but takes longer to process.

Datasmith may use different strategies to test for surfaces that it should stitch together. For most types of source files, it tests for connectivity between the surfaces of nearby bodies, and merges any bodies whose surfaces are connected. For other types of files, it uses the scene hierarchy as a hint to determine connected surfaces.

Stitching Heal does the same, but only re-connects surfaces that belong to the same body in the source scene. If Datasmith detects that the geometry of separate surfaces within the same body should be connected, it will merge those surfaces into the same mesh element in the Static Mesh Asset that it creates. However, with this setting enabled, Datasmith will never combine multiple separate objects from the source scene into a single Static Mesh Asset.

Stitching None skips the stitching process completely. Datasmith always creates a separate Static Mesh Asset for each separate body in the source scene. For each of those bodies, Datasmith creates a separate mesh element in the Static Mesh Asset for each surface that the body contains.

Retessellation Rule

When you use the Datasmith importer to bring a scene into the Unreal Editor from a supported CAD file that contains surfaces defined by parametric curves, Datasmith tessellates the surfaces of those scene objects into triangular meshes. At the time you import your file, you provide settings that control the fidelity of the resulting triangular meshes to the original parametric surfaces. You can read more about these settings under Using Datasmith with CAD File Formats. Datasmith uses the import settings you provide at the time you import your CAD file to tessellate all geometry in the scene.

In addition, after your initial import, you can override the values of the tessellation quality settings for individual Static Mesh Assets that you select. This helps you to import your overall scene at one level of detail—typically a low level of detail that tessellates all the objects in the scene relatively quickly. Then, after importing, you can retessellate selected Assets with different quality settings—typically higher levels of detail that provide better visual results for important scene objects. This way, you can achieve a balance between import speed, model complexity, and visual quality that fits the unique needs of each Project's content.

The effect is very similar to the ability to reimport individual Static Mesh Assets in a Datasmith Scene, as described in About the Datasmith Reimport Process. However, the difference is that when you reimport a scene element, Datasmith opens the original CAD scene file, re-reads the geometry data for the selected object from the file, then tessellates that newly imported geometry. When you retessellate the geometry instead, Datasmith does not reopen the original scene file at all. It applies the new tessellation settings to the last imported geometry for the selected Static Mesh Asset. Therefore, retessellating tends to be faster than reimporting, and you can do it even when the original CAD source file is unavailable.

To retessellate individual Static Mesh Assets:

Select the Static Mesh Assets that you want to retessellate in the Content Browser, in the Geometries folder next to your Datasmith Scene Asset.

Right-click any Asset that you have selected, and choose the Datasmith > Retessellate option from the context menu.

Set new values for the tessellation settings described on the Using Datasmith with CAD File Formats page.



This window only contains the settings that control geometry tessellation, not any other settings that you usually set when you import a Datasmith file. If you need to change other import settings, use the Reimport option to reimport the selected Asset from its original CAD scene file.

Click Import.

The retessellation process uses the new values to recompute the triangular mesh for the selected Static Mesh Asset or Assets, but leaves all other Assets in the Datasmith Scene unchanged.





If you don't see the Retessellate option in the context menu, one or more of the Assets you selected were not tessellated at the time they were originally imported. This typically means that the CAD file already contained a triangular mesh for the Asset, rather than a parametric surface. The Datasmith importer simply brought in that existing triangular mesh, and has no original parametric surface data to use as a basis for retessellation.

If this is the case, and if you need to simplify the geometry of the Static Mesh, you can do so using other tools provided by the Unreal Editor: the Proxy Geometry Tool, Levels of Detail, and so on. However, you won't be able to increase the detail of the Static Mesh geometry.

Retessellation Rule

After modeling operations, a NURBS surface can be:

Intact, which means no triangles were removed from the surface after tessellation.

Altered, which means several triangles were removed.

Deleted, which means all triangles were removed.

With that in mind, you can use the Retessellation Rule option controls which surfaces need to be retessellated. You can select one of the following options:

All selects all surfaces for retessellation.

Skip Deleted Surfaces excludes surfaces that had all of their triangles removed.

IFC Workflow

Supported IFC versions

Scene Hierarchy

Lights and Cameras

Layers

Materials

Metadata

How Datasmith Converts Properties from IFC Files

Additional Metadata Tags

Credits

This page describes how Datasmith imports scenes from Industry Foundation Classes (IFC) files into Unreal Editor. It follows the basic process outlined by the Datasmith Overview and Datasmith Import Process pages, but adds some special translation behavior that is specific to IFC. If you're planning to use Datasmith to import scenes from IFC into Unreal Editor, reading this page can help you understand how your scene is translated, and how you can work with the results in Unreal Editor.





IFC Workflow

Datasmith uses a Direct workflow for IFC. This means that to get the content of an IFC file into Unreal using Datasmith, you need to:

Save your .ifc file.

Enable the Importers > Datasmith IFC Importer Plugin for your Project, if it's not already installed.

Use the Datasmith IFC importer available in the Toolbar of the Unreal Editor to import your .ifc file. See Importing Datasmith Content into Unreal Engine.

To read more about other types of Datasmith workflows, see Datasmith Supported Software and File Types.

Supported IFC versions

Datasmith currently supports only the IFC2x3 format.

For details about IFC formats and specifications, see the buildingSMART International technical site.

Scene Hierarchy

Datasmith creates an Actor for each object in your IFC scene. It gives each Actor a name that matches its corresponding object, prefaced by the object's IFC type. The Datasmith Scene arranges these Actors in a hierarchy of parent-child relationships that closely matches the way your IFC objects are organized: sites contain buildings, buildings contain storeys, storeys contain walls, doors, spaces, and so on.

Left: an IFC hierarchy shown in IFC Viewer. Right: the same hierarchy in Unreal Engine. Click for full image.

You may notice a few differences:

In the Unreal Editor World Outliner, shown above on the right, the Actors at each level of the hierarchy are always ordered alphabetically. This may cause visual differences in ordering siblings between Unreal Engine and other IFC viewing and editing applications, but the parent-child relationships remain unchanged.

An IFC file can have multiple objects with the same name, but each Actor in the Unreal Engine Level needs to have a unique name. Datasmith appends a different numeric suffix to distinguish between objects that share the same name.

Datasmith only allows alphanumeric characters, underscores, and hyphens in Actor names. All other characters are changed to underscores.

These minor visual differences do not affect unique IDs or other data assigned to the IFC objects. These values are preserved by Datasmith in metadata assigned to each Actor. You can create best-practice IFC workflows in Unreal Engine by leveraging these metadata values.

Lights and Cameras

The IFC 2x3 specification does not define light emitters or cameras in the same way as Unreal Engine or other 3D design and visualization tools.

Lights in IFC are treated purely as building elements, called ifcLamp objects. These objects do not have measurements of the properties required for realtime rendering, such as illumination radii, intensity, color, and so on. Datasmith imports each ifcLamp element as an Actor in the Datasmith Scene, the same way it imports all other types of objects from the IFC file. However, Datasmith does not create any light sources for them, like Point Lights, Spot Lights, Rectangular Area Lights, and so on.

As with all other IFC objects that Datasmith imports, the properties assigned to each ifcLamp object in the IFC file are available as metadata—both in the Unreal Editor, and at runtime in the Unreal Engine. You can use Blueprint or Python to access and interpret these metadata properties, and to create your own Unreal Engine light sources automatically based on their values.

Cameras are not part of the IFC specification at all, nor can an IFC file save viewpoints on the scene. Therefore, Datasmith does not create any cameras in the Datasmith Scene.

Layers

Datasmith creates a new Layer in the Unreal Engine Level for each different type of IFC object in the scene. It assigns to each Layer all the Actors that represent objects of the corresponding type. You can use these Layers to quickly show, hide, and select all objects of any given type.

For example, in the following image, only the ifcWindow and ifcBeam elements are visible.

Click for full image.

Materials

For each different surface material that Datasmith finds in your IFC scene, it creates a Material Asset in Unreal with the same name, and places that Material in the Materials folder next to your Datasmith Scene Asset. Datasmith assigns these Material Assets to the Static Mesh Assets it creates in order to shade their surfaces.

Each Material in the Materials folder is a Material Instance that exposes properties set in the IFC file: color values, transparency values, specular colors, and so on. Double-click one of these Material Assets to open it in the Material Instance Editor:

Click for full image.

You can change the exposed properties in the Details panel to modify the way the Material looks when applied to a surface. For example, the Material shown above exposes properties for its base color and transparency.

Unlike some other file formats and design applications Datasmith works with, IFC does not offer deep controls over the physical characteristics of surface properties. When Datasmith translates Materials from an IFC file, it preserves your original properties as faithfully as possible. However, the results are not typically lifelike or well-suited to the physically based rendering of the Unreal Engine. Typically, you'll want to replace the default Materials that Datasmith creates and assigns to your Static Mesh Assets. You can author your own physically based Materials in Unreal Engine, or import physically based Materials from other sources—for example, from the Marketplace tab of the Epic Games Launcher.

Datasmith also creates a set of parent Materials in the Materials/Master folder. Each of these is the parent of at least one of the Material Assets in the Materials folder. You can edit these parent Materials if you want greater control over the Material graphs that define how each surface appears, to expose additional parameters to child instances, or to change the way the exposed parameters are taken into account during rendering.

Note that changing a parent Material also automatically changes all Material Instances that inherit from that parent. It's usually a good idea to duplicate a parent Material before you modify it, make your changes to the duplicate, then update specific Material Instances to use your new duplicate as their parent. For details, see Modifying a Datasmith Master Material.

Metadata

Datasmith records all the properties of each object it imports from the IFC file, and it saves those property values as Datasmith Metadata on the Actor it creates to represent that object in the Unreal Engine. You can access this metadata in the Unreal Editor or at runtime in the Unreal Engine.

Left: properties in an IFC file. Right: Datasmith Metadata built from those properties. Click for full image.

How Datasmith Converts Properties from IFC Files

IFC allows properties to be organized into groups. For example, the image above shows several groups: PSet_Revit_Mechanical, PSet_Revit_Dimensions, PSet_Revit_Identity Data, and so on. However, Datasmith Metadata in Unreal Engine is always a flat list of keys and values. If your IFC properties contain any groups, as shown above, Datasmith flattens the hierarchy, putting all metadata keys from all groups into a single flat list. The group names themselves are discarded.

Datasmith only allows alphanumeric characters, hyphens, and underscores in the metadata key names. If the name of your User Data contains any other characters, those characters will be converted to underscores automatically. For example, in the image above, the Fixture Units property is converted to Fixture_Units in the Datasmith Metadata.

All special characters in the metadata values are preserved.

Additional Metadata Tags

Datasmith also stores additional technical metadata about each object as Tags on the Actor that it creates to represent the object in the Unreal Engine. For IFC objects, Datasmith saves a globally unique ID and the Actor's IFC type, as shown in the following image:



For more information, see also Datasmith Import Process.

Credits

IFC building courtesy of https://github.com/buildingSMART/Sample-Test-Files/tree/master/IFC%202x3/Schependomlaan.

© original owners.

This work is licensed under the Creative Commons Attribution 4.0 International License. More info and a link to the full license text is available on http://creativecommons.org/licenses/by/4.0/.

Other IFC hierarchy images are from Project 3: Clinic, available from the National Institute of Building Sciences.

IFC screen captures taken in the RDF IFC Viewer application.

Supported Applications

Supported File Formats and Standards

Export Plugins for macOS

Formats that Unreal Engine Supports Directly

Backward Compatibility

Datasmith currently works with the software applications and file formats listed in the following table.

For each type of software or file format listed, the Status column uses the following icons to indicate the level of readiness you should expect:

Icon

Meaning



Production-ready.



Beta or Experimental feature, shared with customers for testing and feedback. Expect changes, and we may deprecate functionality at our discretion.

The Workflow Type indicates how you package the information from your design application:

Direct means that the Datasmith Importer Plugin in Unreal reads the application's file format directly.

Export means that you need to export the content from your application to a specific file format before Datasmith can import it into Unreal Engine. You export the content using functionality that is already built into your application.

Export Plugin means that you need to install a new plugin into your application in order to export your design data into the format that Datasmith imports into Unreal.

The Importer Plugin column below tells you which Datasmith importer plugin you need to enable in your Unreal Engine Project to be able to import files of each type. For more information about this process, see Importing Datasmith Content into Unreal Engine

You can download all Datasmith exporter plugins from the Datasmith exporter plugins page.

Supported Applications

Application

Support Level

Version

Workflow Type

Importer Plugin

3D ACIS



Up to R27

Direct

CAD

3DEXCITE DELTAGEN



2017, 2018

Export (FBX only)

FBX

ArcGIS CityEngine



Export Plugin

Datasmith

Autodesk 3ds Max



2016, 2017, 2018, 2019, 2020, 2021, 2022

Export Plugin

Datasmith

Autodesk Alias



Up to 2021

Direct

CAD

Autodesk AutoCAD



Direct

CAD

Autodesk Inventor



Up to 2019

Direct

CAD

Autodesk Revit



2018.3, 2019, 2020, 2021, 2022

Export Plugin

Datasmith

Autodesk Navisworks



2019, 2020, 2021, 2022

Export Plugin

Datasmith

Autodesk VRED



VRED Professional 2018, 2019, 2020

Export Plugin

FBX

Dassault Systèmes CATIA V5



R10 - R29

Direct

CAD

Dassault Systèmes SOLIDWORKS



Up to 2021

Export Plugin

CAD

Dassault Systèmes SOLIDWORKS



2020, 2021

Direct

Datasmith

Graphisoft Archicad



23, 24, 25

Export Plugin

Datasmith

Maxon Cinema 4D



Direct

C4D

McNeel Rhinoceros



up to 7

Export Plugin

Datasmith

McNeel Rhinoceros



up to 6

Direct (.3dm files)

Datasmith

PTC Creo (Pro/ENGINEER)



V13 up to Creo 6

Direct

CAD

Siemens NX



V11 - NX CR

Direct

CAD

Trimble SketchUp Pro



2017, 2018, 2019, 2020, 2021

Export Plugin, DirectLink

Datasmith

Supported File Formats and Standards

File Format or Standard Name

Support Level

Version

Workflow Type

Importer Plugin

3DXML



R2018X

Direct

CAD

glTF



2.0

Direct

glTF

Industry Foundation Classes (IFC)



IFC 2x3

Direct

IFC

Initial Graphics Exchange Specification (IGES)



5.2, 5.3

Direct

CAD

JT Open



Up to 10.2

Direct

CAD

Parasolid (x_t)



up to 31

Direct

CAD

Siemens PLM XML



7.0.3 and later (Compatible with TeamCenter 11 or later)

Direct

CAD

STEP



AP203, AP214, AP242

Direct

CAD

Export Plugins for macOS

Most Export Plugins, as well as all Datasmith importers in the Unreal Editor, are currently only available for Microsoft Windows platforms. As of Unreal Engine 4.27, we also support exporting from the following applications on macOS:

Application

Supported Versions

Trimble SketchUp Pro

2019, 2020, 2021

Graphisoft Archicad

23, 24, 25

McNeel Rhinoceros

6, 7

Formats that Unreal Engine Supports Directly

Unreal Engine offers built-in support for importing and exporting FBX files.

These FBX-based workflows are optimized to support game requirements, which tend to be focused on working with individual objects. Datasmith, by contrast, brings in entire scenes, potentially containing thousands of objects, each with its materials, pivots, scale, hierarchy, and metadata, from a wide range of sources. However, you should feel free to use the FBX import pipeline if it suits your needs. For example, you might use it to import pieces of additional set dressing that you'll use to augment your Datasmith content in your Unreal Level.

For details, you can read about our FBX Content Pipeline.

We also offer experimental support for importing the glTF format directly into the Content Browser using the built-in Unreal Editor importer. Like the FBX import process, this has been optimized for object-based workflows, and has different limitations compared to the Datasmith glTF importer. However, you might find it works for you in select cases. To try it out, go to Edit > Plugins > Importers, enable the glTF Importer plugin, and restart Unreal Engine.

Backward Compatibility

Sometimes, we may need to change the Datasmith file format and the behavior of the importer plugins in order to add new features. We do not guarantee backward compatibility between all versions of Unreal and all versions of the Datasmith export plugins. Although you may be able to import a .udatasmith file generated with an older version of an export plugin into a newer version of Unreal Engine, we do not recommend depending on it.

Always use the version of an export plugin that matches the Unreal Engine and Datasmith plugin versions that you need to use the exported file with. To get the most out of Datasmith, and to make sure you benefit from the latest fixes and features, we recommend always using the latest available version of Unreal Engine and the export plugins.

Importing Datasmith Content into Unreal Engine

Datasmith Import Process

Common Datasmith Import Options

CAD Import Options

GLTF Import Options

VRED Import Options

Deltagen Import Options

This page describes the options that you can configure when you use Datasmith to import a file from a supported design application or data file format, or to re-import a Datasmith Scene Asset from its original source.

All file formats offer you the Common Import Options described in the first section. Then, depending on the type of file you're importing, you may have additional options specific to that format. See the following sections for details.

Common Datasmith Import Options

When you use Datasmith to import any kind of file, you can set the following options.



Property

Description

Geometry

Specifies whether or not Datasmith should import geometry from your source file and turn it into Static Mesh assets in your Project.

Materials & Textures

Specifies whether or not Datasmith should import materials and textures from your source file and turn them into Material and Texture assets in your Project.

Lights

Specifies whether or not Datasmith should include lights from your source file in the scene hierarchy maintained by the Datasmith Scene, and create Light Actors in your Level to represent them.

Cameras

Specifies whether or not Datasmith should include cameras from your source file in the scene hierarchy maintained by the Datasmith Scene, and create Cine Camera Actors in your Level to represent them.

Animations

Specifies whether or not Datasmith should import object animations from your source scene into Level Sequences that you can use to play back the animations inside the Unreal Engine.



Static Mesh Options



Min Lightmap Resolution

Sets the minimum lightmap resolution for the Static Mesh Assets that Datasmith generates. This value is used to determine the amount of padding between packed UV charts when generating lightmap UVs in Unreal Engine 4. A good value is typically half of the Max Lightmap Resolution.

Max Lightmap Resolution

Sets the lightmap resolution for the Static Mesh Assets that Datasmith generates. These lightmaps are used to store lighting information per instance when you use precomputed lighting (Static and Stationary lights) in your Level.

Don't set this value too high on import. Set it to a good baseline level for your Project, then increase it for individual Static Mesh assets that need higher resolution to achieve good results when you build your lighting.

Generate Lightmap UVs

Determines whether or not Datasmith should generate lightmap UVs for each Static Mesh Asset it imports. This option is enabled by default, and is typically recommended to ensure that you'll be able to use baked lighting for all geometry that you import through Datasmith.

However, generating lightmaps automatically at import time has downsides. It takes time during the import process. It creates additional UV channels on your Static Meshes, which makes their memory size slightly larger. Finally, you have no direct control over the resulting lightmap.

You may be able to save time and memory by disabling lightmap generation if any of the following are true:

You have already created UV mappings suitable for lightmap baking in your source application.

You intend to use only dynamic lighting or ray tracing for lighting your scene in Unreal.

You intend to generate your own lightmap UVs after import, using tools built in to the Unreal Editor.

See also Working with UV Channels and Understanding Lightmapping in Unreal Engine.

When you reimport a Datasmith scene, the checkboxes under the Include section indicate only whether each type of Asset or Actor should be updated with new and modified content from your source file. If you uncheck one of these items, existing Assets or Actors of that type are not deleted from your Project.

CAD Import Options

When you use the Datasmith importer to import a CAD file (that is, any file that is listed on the Datasmith Supported Software and File Types page as being provided by the CAD importer), you can set the following additional options.

If your source file contains any surfaces that are defined by curves, Datasmith tessellates those surfaces into triangular meshes. These parameters control the tessellation process. They control how closely the generated meshes follow the original surfaces, and therefore also the complexity of the meshes. For all settings, smaller values increase the number of triangles, and higher values decrease the number of triangles.



Property

Description



Geometry & Tessellation Options



Geometry

This option only appears when you import a Rhino file. It determines whether Datasmith should tessellate surfaces into triangular meshes using the parameters in this section, or whether it should reuse triangular meshes generated by Rhino and saved in your Rhino file. For details, see Rhino.

Chord Tolerance

Sets the maximum distance between any point in a generated triangle and the original surface.

Max Edge Length

Sets the maximum length of any edge in any generated triangle.

Normal Tolerance

Sets the maximum angle between any adjacent triangles generated from a surface.

Stitching Technique

Determines whether the import process should try to merge together surfaces that appear to be connected, but that are actually modeled as separate objects.

For an in-depth description of these tessellation parameters and how they affect the resulting Static Mesh geometry, see Using Datasmith with CAD File Formats.

GLTF Import Options

When you use the Datasmith GLTF importer to import a .glTF file (GL Transmission Format), you can set the following additional options:



Property

Description



Lightmaps



Generate Lightmap UVs

In order to use Static or Stationary lighting in the Unreal Engine, your models need to have lightmap UVs in which no two triangles overlap.

Enable this option to have the Datasmith importer automatically generate these lightmap UVs for the Static Mesh Assets it creates. In order for this to work, your models need to have at least one non-empty UV set to start with. If a model does not have any UV sets at all, the importer will create a blank UV set for the Static Mesh Asset, but this blank UV set will not be usable for applying textures or lightmaps to the Static Mesh.

If you've already created valid, non-overlapping lightmaps for the objects in your source application, you can leave this option unchecked to have the Datasmith importer skip creating new lightmap UVs. In this case, your Static Mesh Assets will use the UV set with the highest index as its lightmap UVs.

For more background information, see Working with UV Channels.



Asset Importing



Import Uniform Scale

Determines the scaling factor the importer uses to convert linear distances. The default value of 100 converts from meters (as specified in the glTF specification) to centimeters (as used in the Unreal Engine). If your source scene uses a different unit of measurement than meters, adjust this value to the number of centimeters per unit.

VRED Import Options

When you use the Datasmith VRED importer to import an .fbx file that you exported from VRED, you can set the following additional options:



Property

Description



Processing



Merge Nodes

Combines subtrees of StaticMesh nodes that are not used for animations, variants or other functionality into single StaticMesh nodes. This can make scene management in Unreal easier by reducing the depth and complexity of the scene hierarchy. However, this option is not recommended if you need to clean up your imported Static Meshes manually, or if your scene contains many instances of the same geometry.

Optimize Duplicated Nodes

Reduces the total count of nodes in the scene hierarchy by reusing entire identical subtrees.



Asset Importing



Import FBX animations

Enable this option to import animations from the VRED scene into Unreal, and make them available to Blueprint scripts in your Project.

Import variants file

Enable this option to import variants and variant sets from your VRED scene into Unreal, and make them available to Blueprint scripts in your Project.

Variants file path

Specifies the path to the .var file that contains data about the variants in your VRED scene. By default, this is set to the path and filename that matches the .fbx file you are importing. You only need to set this path manually if you need to import a .var file from a different location.

Import lights file

If you disable this option, but leave the Import > Lights setting enabled in the common Datasmith properties, the lights that Datasmith creates in Unreal will contain only information stored in the .fbx file. If you enable this option, Datasmith imports extra information about the lights in your VRED scene from a .lights file that was created when you exported your scene. This carries over extra properties about your lights that are not supported by FBX, such as IES light profiles, and typically leads to better visual results that more closely match your lighting in VRED.

Light file path

Specifies the path to the .lights file that contains data about the variants in your VRED scene. By default, this is set to the path and filename that matches the .fbx file you are importing. You only need to set this path manually if you need to import a .lights file from a different location.

Textures folder

Specifies a folder path for Datasmith to search for texture files that are referenced in the .fbx file.



Debug



Intermediate Serialization

Enable this option to store scene data read from the .fbx file to an intermediate format. This setting might be useful if you need to import the same scene frequently, and the FBX importer is a bottleneck.

Colorize materials

Enable this option to use randomly colored simple materials instead of importing material parameters like DiffuseColor or textures.



Lightmaps



Generate Lightmap UVs

In order to use Static or Stationary lighting in the Unreal Engine, your models need to have lightmap UVs in which no two triangles overlap.

Enable this option to have the Datasmith importer automatically generate these lightmap UVs for the Static Mesh Assets it creates. In order for this to work, your models need to have at least one non-empty UV set to start with. If a model does not have any UV sets at all, the importer will create a blank UV set for the Static Mesh Asset, but this blank UV set will not be usable for applying textures or lightmaps to the Static Mesh.

If you've already created valid, non-overlapping lightmaps for the objects in your source application, you can leave this option unchecked to have the Datasmith importer skip creating new lightmap UVs. In this case, your Static Mesh Assets will use the UV set with the highest index as its lightmap UVs.

For more background information, see Working with UV Channels.

Deltagen Import Options

When you use the Datasmith Deltagen importer to import an .fbx file that you exported from Deltagen, you can set the following additional options:



Property

Description



Processing



Merge Nodes

Combines subtrees of StaticMesh nodes that are not used for animations, variants or other functionality into single StaticMesh nodes. This can make scene management in Unreal easier by reducing the depth and complexity of the scene hierarchy. However, this option is not recommended if you need to clean up your imported Static Meshes manually, or if your scene contains many instances of the same geometry.

Optimize Duplicated Nodes

Reduces the total count of nodes in the scene hierarchy by reusing entire identical subtrees.

Remove Invisble Nodes

Enable this setting to avoid importing any geometry that were hidden in the Deltagen scene.

Simplify Node Hierarchy

Enable this setting to flatten the Datasmith Scene hierarchy.



Asset Importing



Import VAR

Enable this option to import variants from your Deltagen scene into Unreal, and make them available to Blueprint scripts in your Project.

Import POS

Enable this option to import state data from your Deltagen scene into Unreal.

Import TML

Enable this option to import animation data from your Deltagen scene into Unreal, and make them available to Blueprint scripts in your Project.

Textures Dir

Specifies a folder path for Datasmith to search for texture files that are referenced in the .fbx file.



Debug



Intermediate Serialization

Enable this option to store scene data read from the .fbx file to an intermediate format. This setting might be useful if you need to import the same scene frequently, and the FBX importer is a bottleneck.

Colorize materials

Enable this option to use randomly colored simple materials instead of importing material parameters like DiffuseColor or textures.



Lightmaps



Generate Lightmap UVs

In order to use Static or Stationary lighting in the Unreal Engine, your models need to have lightmap UVs in which no two triangles overlap.

Enable this option to have the Datasmith importer automatically generate these lightmap UVs for the Static Mesh Assets it creates. In order for this to work, your models need to have at least one non-empty UV set to start with. If a model does not have any UV sets at all, the importer will create a blank UV set for the Static Mesh Asset, but this blank UV set will not be usable for applying textures or lightmaps to the Static Mesh.

If you've already created valid, non-overlapping lightmaps for the objects in your source application, you can leave this option unchecked to have the Datasmith importer skip creating new lightmap UVs. In this case, your Static Mesh Assets will use the UV set with the highest index as its lightmap UVs.

For more background information, see Working with UV Channels.

Supported File Formats by Platform

Rebuilding Unreal Engine from Source

Datasmith Export Plugins

This page describes which features of Datasmith work on which different platforms when you download Unreal Engine through the Epic Games Launcher, and when you build the engine yourself from its source code distribution.

Supported File Formats by Platform

Some components used internally by the different Datasmith importers only work on selected Unreal Engine platforms.

Source format

64-bit Windows

Mac OS X

Linux

.udatasmith files







CAD file formats







Alias .wire







Rhino







Cinema 4D







AxF







MDL







glTF







IFC







Deltagen and VRED







Rebuilding Unreal Engine from Source

Some components used internally by the Datasmith importers are not redistributable as part of the Unreal Engine source code. Therefore, you can't rebuild Unreal Engine yourself with support for the features provided by these components.

When you rebuild Unreal Engine yourself from its source code distribution, the Datasmith import plugins support the following formats:

Source format

Rebuildable?

.udatasmith files



CAD file formats



Alias .wire



Rhino



Cinema 4D



AxF



MDL



glTF



IFC



Deltagen and VRED



You may be able to compile Unreal Engine with some of the unsupported features listed above if you download and install the required software development kits from third parties.

Datasmith Export Plugins

The pre-built versions of the Datasmith Exporter Plugins on the Datasmith export plugins download page support the following platforms:

Source application

64-bit Windows

Mac OS X

SketchUp Pro





3ds Max



n/a *

Revit



n/a *

* 3ds Max and Revit are not available on Mac OS X.

When you rebuild Unreal Engine yourself from its source code distribution, you can rebuild the Datasmith Exporter Plugins for Windows. However, you need to download and install the SDK for your source application from Trimble or Autodesk.

Target Audience for this Guide

What You Will Learn

Downloads and Prerequisites

Downloading Unreal Engine and the Datasmith SDK

Understanding Datasmith

Unreal Engine Data Model

Datasmith Design Principles

Datasmith Plugin Types

Export and Import Logic

Reimporting Data After Source Changes

Environment and Lighting

UX Guidelines for Datasmith Exporters

Exporter UI

Progress Information and Error Messages

Exported Files and Folders Structure

Datasmith File Header

Static Mesh Assets

Static Mesh Actors

Empty Actors

Actor Hierarchy

Actors as Components

Actor Layers

Actor Tags

Metadata

Camera Actors

Texture Assets

Materials

Target Audience for this Guide

This guide is aimed at 3D application developers who want to export scenes from third-party design applications into Unreal Engine using the Datasmith framework.

This guide makes the following assumptions:

You are an experienced C++ programmer.

You are familiar with the development of 3D applications.

You are developing functionality to export models from a third-party 3D application to Unreal Engine or Twinmotion.

You are not familiar with how Unreal Engine works, but you are willing to learn about it.

What You Will Learn

This page outlines a series of guidelines and best practices for exporting 3D models from other design applications to Unreal Engine using the Datasmith SDK. Broadly speaking, it outlines:

Datasmith's design philosophy.

Data models and structures in Unreal Engine.

UX guidelines for Datasmith exporters, with separate checklists for each major part of the export process.

Useful API calls and code examples for different scenarios.

Downloads and Prerequisites

This section contains:

A list of required downloads and where to find them.

An overview of the required Datasmith and Unreal Engine knowledge to get you started, and links to resources for further learning.

Downloading Unreal Engine and the Datasmith SDK

If you download and build Unreal Engine from the Unreal Engine GitHub repository, the Datasmith SDK is included with it.

To download the Unreal Engine source code from GitHub, you must first follow the steps outlined in this guide to request access to the repository. If you haven't been granted access, you will receive a 404 error.

After you download the Unreal Engine source code, you will find the Datasmith SDK under:

\Engine\Source\Programs\Enterprise\Datasmith\DatasmithSDK\

The Documentation folder contains a sample project, as well as instructions on how to get your development environment configured.

If you download and install Unreal Engine from the Epic Games launcher, you must download the Datasmith SDK separately from this folder in the Unreal Engine GitHub repository.

Epic Games have developed Datasmith export plugins for a few design applications, such as Revit, SketchUp, and 3ds Max. You can refer to these plugins as examples for your own work.

You can access the source code for these Datasmith export plugins in the Epic Games GitHub repository, under:

\Engine\Source\Programs\Enterprise\Datasmith\

Understanding Datasmith

Datasmith is a collection of tools and plugins that brings pre-constructed scenes created in a variety of design applications into Unreal Engine. It was designed to overcome limitations of other generic file formats, such as FBX or OBJ.

Datasmith is able to:

Handle large meshes.

Store data that Unreal Engine uses, such as:

LODs

Collision

Lights

Object hierarchy

Metadata

Reformat texture files (to the power of 2, into formats handled by Unreal).

To learn more about Datasmith features and functionality, refer to the Datasmith Overview page.

Exporting data happens in two steps:

Parse the design application and construct a DatasmithScene with the DatasmithCore API.

Export the scene to disk using the DatasmithExporter API.

To learn how to use these APIs, refer to the following documentation:

DatasmithCore

DatasmithExporter

Unreal Engine Data Model

Before you start writing your Datasmith exporter, familiarize yourself with how Unreal Engine stores and structures information.

Unreal Engine works with projects. An Unreal project contains at least one Level, which contains one or more Actors. Actors have a position, rotation, and scale. They can exist on different layers, be shown or hidden, have animations, and so on.

Each Actor has one or more Components, which can be:

Geometric Assets, such as Static Meshes.

Lights.

Cameras, and so on.

Static Meshes reference Master Materials or Material Instances. In turns, Material Assets reference Texture Assets.

A single Static Mesh can be referenced by multiple Actors. This is called geometry instantiation.



This diagram illustrates the relationship between Actors, Components, and various types of Assets in Unreal Engine. Click the image for full size.

Datasmith Design Principles

As a plugin developer, you should strive to ensure a consistent user experience, regardless of which software the data is being exported from. As such, it is important to understand and adhere to the Datasmith design principles outlined below. These are the principles that we (the Datasmith developer team) use when developing our own plugins.

Datasmith Plugin Types

All Datasmith plugins use one of the following two schemes:

Exporter / Importer combination. For example, 3ds Max, Revit, and Sketchup use:

A Datasmith exporter plugin on the software side.

The Datasmith File Importer plugin on the Unreal Engine side.

Direct importer. For example, Unreal Engine can import some file formats native to Rhino, Solidworks, and Cinema4D.



This diagram illustrates the various Datasmith import workflows available. Click the image for full size.

The choice of which workflow to use varies on a case-by-case basis.

Export and Import Logic

One of the challenges with exchanging data between different applications is understanding where to put some of the logic. When we translate data from one application to another, we may ask ourselves:

Should we export everything or provide options to exclude some entities?

Should we exclude small objects when exporting? How do we define "small"?

Should we reduce polygon count when exporting? Should we reduce texture resolutions?

Where do we rescale entities to match units and scale?, and so on.

Generally speaking, our approach is to export everything in a granular fashion (that is, object by object), and deal with object merging, polygon reduction and other data preparation operations when the data is later imported into Unreal Engine or Twinmotion.

While there's no strict rule, our general approach is that it's best to have the least amount of options (or none at all) exposed in the Datasmith exporter, and let the Unreal Engine user make most of the decisions during the import.

With this approach, it is up to the Unreal or Twinmotion user to decide how granular his data may be, or how optimized it may be. Unreal Engine's Dataprep is a great tool for making those decisions.



Example division between internal and user-selected operations over the course of the Datasmith export / import process. Click the image for full size.

Reimporting Data After Source Changes

Datasmith brings design data from a variety of source applications into Unreal Engine, typically for the purpose of building real-time visualizations and experiences around that data. Often, while you are working on building those visualizations and experiences in Unreal Engine, the scene or design data that your work incorporates needs to change in order to meet new requirements or incorporate feedback from stakeholders.

To avoid painful and costly re-work, you need to be able to incorporate those upstream changes without losing all the work you've done in the Unreal Editor. To this end, Datasmith offers a re-import workflow that preserves all of your changes within the Unreal project.

From a Datasmith SDK perspective, re-importing data implies two things:

Entities must have a persistent unique identifier. Relying on an object's name is not a good strategy because multiple objects can have the same name.

Entities must be saved with a hash value that permits data re-importing at the highest possible performance.

When a Datasmith entity is created, a unique number is generated based on the object's data. For example, to quickly determine if two meshes are identical, you could either compare them face-to-face using a time-consuming algorithm, or you could compute a numerical value based on the number of vertices, faces, and UVs. Comparing these two values would then be a much faster way to tell if the meshes are identical or not.

Examples are described further down on this page.

Environment and Lighting

Although you may be tempted to perceive Unreal as a rendering engine and expect to export a model with all of its environment settings (cameras, environments, backgrounds, etc.), we find that generally, those artistic decisions are best made by Unreal Engine or Twinmotion users, after the data has been imported into the engine.

The most important aspect is to import model elements (geometry, materials, lights, metadata). Once the data has been imported into Unreal Engine or Twinmotion, users can change materials, tweak lighting, and perform other artistic tasks.

UX Guidelines for Datasmith Exporters

If you made it to this point, you have most likely compiled Unreal and created your first Datasmith file with a small application. Congratulations!

Now it's time to look at UX considerations related to how the data should be structured for end users.

Exporter UI

As we described in the Datasmith Design Principles section above, we want to offer the least amount of options when exporting to Datasmith. Here are some examples:





Datasmith exporter from Revit

Export Options dialog in Unreal Engine

Favor WYSIWYG (What You See Is What You Get) exports by relying on the application's viewing and filtering capabilities. For example, Revit only exports what is visible in the active View, and SketchUp only exports what is visible on-screen. There is no reason to invent a whole new UX to select and filter entities to be exported.

Favor no options at all when exporting.

If you must expose options, keep them as simple as possible. Refer to the 3ds Max exporter above as an example.

Options related to data preparation and optimizations, such as geometry detail, object type filtering, UV channels, etc. These should be decisions made by the Unreal Engine user, in Unreal Engine.

Progress Information and Error Messages

Datasmith exporters collect all entities relevant to transferring and reconstructing the scene in Unreal Engine. It is possible that some entities cannot be exported. You should inform users if one or more entities cannot be exported..

In addition, some projects are very large, which can make the export take a long time. Users should be able to see progress information.

Here are some examples. Click any image below to see it in full size.



Progress information in 3ds Max.



Output warnings in the Revit Datasmith Exporter.



Output warnings in the 3ds Max Datasmith Exporter.

Progress information needs to be presented to the user during export.

Users need to be able to cancel the Datasmith export process.

An error message log should be displayed to inform users about unsupported objects, missing textures, and other issues.

Certain users often demand batch processing and scripting. For example, with SketchUp, 3ds Max or Revit, users can batch export to Datasmith using the native application scripting language.

Do not implement successive modal dialogs (OK / Cancel windows) that interrupt the export process each time an error or a warning occurs.

DatasmithExporter

IDatasmithProgressManager

FDatasmithLogger

For an example implementation, refer to the following file in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithSketchUpRubyExporter/Private/DatasmithSketchUpExporter.cpp

Exported Files and Folders Structure

A Datasmith "file" consists of two parts:

A .udatasmith file that uses an XML data structure.

A "sidecar folder" (an associated folder) that contains all Assets associated with the .udatasmith file.



Example export file with its associated folder.

A single [filename].udatasmith file and a single associated [filename]_Assets folder.

All related Assets are stored in the [filename]_Assets folder.

Assets are referenced in the .udatasmith file's XML structure using relative paths.

Do not reference Assets by absolute paths.

Do not create additional folders and subfolders that contain Assets. Here is an example of an incorrect export:



Note that the Textures folder is outside the Datasmith project files. This is incorrect.

Datasmith File Header

We (Epic Games) use header information to understand where data comes from. Our telemetry only collects statistics about what types of files are imported and from which source.

Below is an example header of a Datasmith file:

Datasmith information must be properly set, similar to the example above.

IDatasmithScene::SetHost

IDatasmithScene::SetProductName

IDatasmithScene::SetProductVersion

For an example implementation, refer to the following file in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithSketchUpRubyExporter/Private/DatasmithSketchUpExporter.cpp

Static Mesh Assets

Static Mesh Assets (IDatasmithMeshElement) define actual geometry, but won't appear in the Unreal or Twinmotion viewport until they are referenced by Actors (IDatasmithMeshActorElement). Multiple `IDatasmithMeshActorElement`s in a scene can also point to the same Static Mesh asset.

A Static Mesh Asset holds data for:

Faces, vertices, normals and smoothing masks

UVs

Collisions

LODs

Vertex colors

Material IDs and assignments, etc.

Below is an example data structure for a Static Mesh Asset in a .udatasmith file:

Static Mesh names must be unique and they must not change between successive exports. This is required to track entities for subsequent re-imports. 3D applications usually provide GUIDs that are well-suited for this purpose.

Static Mesh labels must be sanitized, user-readable, and representative of what that object may be.





Unique names for mesh Assets

User-readable labels in Unreal Engine

Static Mesh Assets (IDatasmithMeshElement) must be reused across Actors where applicable (they must be instanced).

Unreal Engine uses left-handed Z-up coordinates and measures dimensions in centimeters, therefore:

Conversion must be done on the exporter side.

UV texture coordinates must be flipped vertically (on the Y axis) so we don't use a negative scale in material tiling to counteract images being flipped in Unreal Engine.

Scale conversion and coordinate transformation must be baked into the Static Mesh rather than applied to the Actor transforms.





Scale is baked in the geometry, resulting in Actor transforms set to a scale of 1.0 (as opposed to 2.54 or 0.333)

Mesh pivots must be calculated in the mesh so they don't all end up at 0, 0, 0.





Left: mesh pivot aligned with object (correct). Right: pivot at 0, 0, 0 (incorrect)

Triangles must be welded so that smoothing masks and shading work correctly.





Smoothing, Normals, etc. are correctly set on the geometry.

Specify additional LODs.

Specify collision meshes.

Specify Lightmap UV Channel (Unwrap).

Static Mesh names which aren't guaranteed to be unique and repeatable across exports. Do not use object names that are user-specified.

Do not store units rescaling within Actor transforms.

Do not leave pivots at 0, 0, 0.

Do not export thousands of Static Mesh Actors that should be welded together. For example, a Box is typically a single mesh with 6 faces, not 6 individual meshes with a single face each.

IDatasmithMeshElement

FDatasmithMesh

FDatasmithUtils::SanitizeObjectName

For an example implementation, refer to the following file in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithSketchUpRubyExporter/Private/DatasmithSketchUpExporter.cpp

Static Mesh Actors

Static Mesh Actors (IDatasmithMeshActorElementsIDatasmithMeshActorElements) don't define the actual geometry. They point to Static Mesh Assets (IDatasmithMeshElement). Note that several IDatasmithMeshActorElements can reference the same Static Mesh.

Below is an example data structure of a Static Mesh Actor in a .udatasmith file.



Two Static Mesh Actors referencing the same Static Mesh Asset (instancing) imported from 3ds Max.

Mesh Actor names must be unique and they must not change between successive exports. This is required to track entities for subsequent re-imports.

Mesh Actor labels must be sanitized (that is, they must not contain invalid characters) and user-readable.

Static Mesh Assets (IDatasmithMeshElement) must be reused across Actors where applicable (they must be instanced).

Scale and coordinate conversions, as well as coordinate transformations, must be baked into the Static Mesh rather than applied to the Actor transforms.

Layer specification.

Support for tags and metadata.

FDatasmithSceneFactory::CreateActor

FDatasmithSceneFactory::CreateMeshActor

IDatasmithActorElement

IDatasmithMeshActorElement

FDatasmithUtils::SanitizeObjectName

For an example implementation, refer to the following file in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithSketchUpRubyExporter/Private/DatasmithSketchUpComponent.cpp

Empty Actors

Empty Actors are Actors that have no Components or Static Meshes attached to them. They are useful to hold metadata or act as a way to represent parts of a hierarchy. There are no strict rules about how or when you should use them. The guidelines below cover some common use examples.

Use empty Actors for:

Representing null objects (for example, 3ds Max helper objects).

Representing custom origin points (for example, Revit site locations).

Representing other elements that make the hierarchy more readable (for example, Layers from Rhino, Block origins from Rhino, or Levels from Revit).

Representing the head of a compound object that has no geometry of its own (for example, Revit curtain walls).



3ds Max Helper objects translated as Empty Actors.



Empty Actors used to represent invisible elements from Revit.

FDatasmithSceneFactory::CreateActor

FDatasmithSceneFactory::CreateMeshActor

IDatasmithActorElement

IDatasmithMeshActorElement

FDatasmithUtils::SanitizeObjectName

For an example implementation, refer to the following file in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithSketchUpRubyExporter/Private/DatasmithSketchUpComponent.cpp

Actor Hierarchy

Like many other 3D applications, Unreal Engine supports parent / child hierarchies.

Below is an example parent / child relationship in a .udatasmith file.

Use Actor hierarchies to reflect the data model of your application.



3ds Max hierarchy translated as-is to Unreal Engine.

Insert additional empty Actors if necessary to store information relevant to your application's data model (for example, Revit Levels are exported as an extra parent Actor).



Revit Levels added to the hierarchy become a useful way to orient end users.

To make sure your hierarchy is easy to navigate for end users, use empty Actors as parents of Static Mesh Actors only where necessary. Too many empty Actors clutter the hierarchy and make it more difficult to read and use inside both Twinmotion and Unreal Engine.





Too many empty Actors.

Empty Actors used only when necessary.

IDatasmithActorElement::AddChild

For an example implementation, refer to the following file in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithSketchUpRubyExporter/Private/DatasmithSketchUpComponent.cpp

Actors as Components

In applications such as Revit or Archicad, it is typical to have objects that have several sub-elements. For example, a Curtain Wall is typically built with panels and mullions and a Railing is typically built with rails and balusters:



In Revit, Curtain Walls and Railings are special objects that contain sub elements (panels, mullions, balusters, handrails).

While it is possible to export each element as an individual Static Mesh Actor, this ends up exporting too many objects and the World Outliner in Unreal Engine becomes overly crowded, as shown below.



Curtain Wall exported as one StaticMesh Actor per panel and mullion = lots of actors in the World Outliner! Click the image for full size.

If applicable, consider exporting sub-elements as Actor Components. For example, a Curtain Wall object can be exported using the following Actor and Component hierarchy:

Curtain Wall Object → empty Actor.

Panel → Static Mesh Actor Component

Panel → Static Mesh Actor Component

Mullion → Static Mesh Actor Component

Mullion → Static Mesh Actor Component



Curtain Wall exported as an Empty Actor with each panel and mullion as a StaticMesh Actor Component results in considerably less clutter in the World View hierarchy. Click the image for full size.

In the .udatasmith file, the hierarchy looks like this:

Use Static Mesh Actor Components to represent child objects such as curtain wall panels, balusters, or similar compound objects.

You must set both the hierarchy (IDatasmithActorElement::AddChild) and component flag (IDatasmithActorElement::SetIsAComponent) in order for this to work correctly.

IDatasmithActorElement::AddChild

IDatasmithActorElement::SetIsAComponent

For an example implementation, refer to the following file in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithSketchUpRubyExporter/Private/DatasmithSketchUpComponent.cpp

Actor Layers

Like many other 3D applications, Unreal Engine supports the concept of Layers. A Layer is an Actor property that indicates where the Actor sits in a scene's visual hierarchy.

The example below shows a possible use of layers in a .udatasmith file.

If your source application uses Layers, you should translate them to Layers in Unreal Engine.

If your source application doesn't use Layers, consider if there is any other data you can translate into Unreal Engine Layers. For example, Revit doesn't use Layers, but classifies entities into Categories.



Revit entities imported on Layers derived from Revit categories.

Layer names must be unique.

Unreal Engine doesn't support nested layers.





Nested Layers in 3ds Max.

The same layers imported in Unreal Engine. Observe the flat Layer hierarchy.

IDatasmithActorElement::SetLayer

For an example implementation, refer to the following file in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithMaxExporter/Private/DatasmithMaxSceneExporter.cpp

Actor Tags

Unreal Engine supports user-defined tags for Actors. Datasmith uses Actor Tags to hold technical information that describes how data is structured in the source application. Unreal Engine users can then use these Actor tags to perform scripting operations, for example with Python, Blueprint Utilities, or Visual Dataprep.

Below is an example use of tags on Static Mesh Actors in a .udatasmith file exported from 3ds Max:

Although there aren't strict rules as to what to put in an Actor's tags, we adopted the methodology of using tags for holding information that is specific to the source application.

For example, in the case of 3ds Max, we decided to use the tags to hold information about the type of object (in 3ds Max), whether or not it's part of a group, and so on.

For Revit, we have adopted a similar approach where we store information that describes the internal structure of Revit entities.





Actor Tags on Actor Components from Revit.

The same layers imported in Unreal Engine. Observe the flat Layer hierarchy.

Prefix your tags with the name of the application you're importing from (for example: Revit.TagName or Max.TagName).

Use tags to represent technical information about how data is structured in the source application. To store other user-defined data, use metadata instead.

IDatasmithActorElement::AddTag

IDatasmithActorElement::SetIsAComponent

For an example implementation, refer to the following file in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithSketchUpRubyExporter/Private/DatasmithSketchUpComponent.cpp

Metadata

Datasmith carries Key / Value pairs that can be used to store BIM information (or any other custom data) on entities.



Metadata from 3ds Max (left) translated into Unreal Engine (right).

Key / Value pairs can only carry strings. This means that floats, units, etc. will need to be contained ("baked") into the string (for example, "10 mm").

Hierarchical properties are not supported, so you'll need to flatten the hierarchy using an underscore ( _ ) separator. Refer to the Revit example below where Element and Type properties are handled by concatenating text strings to keep things grouped.



A simulated flattened hierarchy using metadata from Revit.

IDatasmithMetaDataElement

IDatasmithMetaDataElement::SetAssociatedElement

FDatasmithSceneFactory::CreateKeyValueProperty

For an example implementation, refer to the following file in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithMaxExporter/Private/DatasmithMaxSceneExporter.cpp

Camera Actors

Datasmith can create Cameras in Unreal Engine, but, depending on your use case, you may or may not want to export cameras from the 3D application. Sometimes, users set cameras explicitly (for example, 3ds Max Physical Cameras). Other times, Cameras are derived from other application concepts (for example, Views from Revit, or Bookmarks from SketchUp).

One key element to consider with regards to Unreal Engine Cameras is that they have physically based characteristics that you will need to set at export time, such as:

Sensor width

Aspect ratio

Exposure value

White point

Depth of Field, and so on.

Below is an example implementation of a Camera with tags and characteristics in a .udatasmith file.



Unreal Engine CineCameraActor.

Depth of Field, Exposure, and other photographic effects defined by post-processing settings are also optional. These require a close relationship between lighting and cameras in the source application which may not be defined in the context of your own Datasmith export.

Unreal Engine Cameras don't support skewed cameras (2-point perspective). For example, Revit can have "cropped" views that will shift the Camera perspective, but Datasmith (and, by extension, Unreal Engine) doesn't support this type of Camera transformation.

IDatasmithActorElement

IDatasmithCameraActorElement

IDatasmithCameraActorElement::SetPostProcess

IDatasmithPostProcessElement

For an example implementation, refer to the following files in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithMaxExporter/Private/DatasmithMaxCameraExporter.cpp

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithSketchUpRubyExporter/Private/DatasmithSketchUpCamera.cpp

Texture Assets

In Unreal Engine, textures represent more than just color information. In order to be sampled and affect lighting and shading correctly, you must indicate the intended use for the texture (texturemode). Possible uses include:

Diffuse

Specular

Normal

NormalGreenInv

Displace

Other

Bump

Ies

We also need to specify its color space (typically Gamma correction or sRGB) as this has a direct impact on how light will work with materials (sRGB and RGB curve).

Below is an example implementation of a texture Asset in a .udatasmith file:

You must set your color space (Gamma / sRGB) correctly, based on the texture's intended use:

sRGB color space is typically used for Albedo textures.

Linear color space is typically used for normal, height, or bump maps.

The texture's name (not filename) must be sanitized (that is, it must not include any invalid characters).

You must place textures in the same folder as the rest of the Assets.



Textures should be exported in the same folder as the other Assets.

Do not use absolute paths.

Do not place textures in a different folder than the rest of the Assets.

While exporting, you don't need to transform textures. The Datasmith importer will handle transforms.

There is no need to convert textures to .uasset files with the DatasmithCore API.

There is no need to reformat, resize, or convert textures to different formats.



This image shows an incorrect use of ``.uasset` files to represent textures.

IDatasmithTextureElement

EDatasmithTextureFilter

EDatasmithTextureMode

IDatasmithTextureElement::SetRGBCurve

FDatasmithUtils::SanitizeName

For an example implementation, refer to the following file in the Unreal Engine repository:

/Engine/Source/Programs/Enterprise/Datasmith/DatasmithSketchUpRubyExporter/Private/DatasmithSketchUpMaterial.cpp

Materials

The following example demonstrates how textures can be exported to a Datasmith file to create a basic PBR material containing an albedo map and a height map.

This example uses the following Material in Rhino:



The Material's settings are as follows:





Albedo map

Height map

The resulting Datasmith file will look like this:

Observe that the two Textures above have different values for texturemode and srgb:

texturemode="0" and srgb="1" for the first Texture

texturemode="6" and srgb="0" for the second Texture

In Unreal Engine, the importer Material's PBR graph will look like this:



Click the image for full size.

Note that the albedo map is set to SRGB=1 and the sampler type is set to Color. This is automatically set up by the Datasmith importer and is the result of setting the exported albedo map as:

The height map, which was greyscale in Rhino, has been converted to a normal map by the Datasmith importer, which is the result of setting the texture as:

texturemode="6" srgb="0"

IDatasmithUEPbrMaterialElement

IDatasmithTextureElement:

SetSRGB - EDatasmithColorSpace

SetTextureMode - EDatasmithTextureMode

GL Transmission Format (glTF™) is an extensible, open-standard file format developed and maintained by Khronos Group. It is designed to create compact files that load quickly, and represent scenes completely.





glTF and the glTF logo are trademarks of the Khronos Group Inc.



The glTF format is used to share rich 3D content between a wide variety of applications, including Unreal Engine, Twinmotion, and Sketchfab, which can import and export glTF content.



Overview of what gTF features Unreal Engine supports



How to import glTF files into Unreal Engine



How to export Unreal Engine content to glTF



How to use scripting, and Blueprint, to export to glTF from the Unreal Editor, and at runtime



Special considerations for exporting Unreal Engine content to glTF



How to pre-bake complex materials into runtime-friendly proxies

Supported glTF Specification

glTF File Formats

glTF Extensions

Extension Limitations

Extensions Supported by the Unreal Engine glTF Exporter

GL Transmission Format (glTF™) is an extensible, open-standard file format developed and maintained by Khronos Group. It is designed to create compact files that load quickly, and represent scenes completely. The glTF format is used to share rich 3D content between a wide variety of applications, including Unreal Engine, Twinmotion, and Sketchfab, which can import and export glTF content.

Supported glTF Specification

The Unreal Engine glTF exporter supports the glTF 2.0 specification. In this documentation, "glTF" refers specifically to glTF 2.0.

glTF 2.0 is more run-time independent than previous versions. It relies only on well-established physically-based rendering (PBR) workflows. Much of the glTF software ecosystem supports glTF 2.0 exclusively.

glTF File Formats

You can import and export the following glTF formats:

Format

Description

JSON.gltf

Includes the following elements, saved separately in a directory you specify:

Full scene description: saved as a JSON-formatted, human-readable UTF-8 text file with the .gltf extension.

Texture files: saved to the format you specify, .png, .jpeg, and so on.

Binary data files: saved separate files with a .bin file extension.

Binary.glb

Combines the full scene description, all binary data, and all textures into a single self-contained binary file.

glTF Extensions

It is impossible for a format like glTF to support every feature of every game engine by default. Instead you can extend the glTF base model with extensions that provide support for specific features (see About glTF Extensions, in the glTF GitHub repository, for more information).

Each glTF extension has a unique name. These names allow applications to identify all of the extensions that a glTF file requires, regardless of whether the application supports all of those extensions.

Every extension name has a prefix that indicates how well-supported the extension is:

Prefix

Support

Description

KHR

Khronos ratified

Broadly supported.The KHR prefix is reserved for Kronos ratified extensions.

EXT

Multi-vendor

Supported by more than one vendor (a company or application).

Various

Vendor

Supported primarily by one vendor (a company or application).Use a vendor-specific registered prefix such as EPIC, ADOBE, or MSFT.Other companies or applications might support these extensions, but it's not guaranteed.

Extension Limitations

Not all applications implement every glTF extension. If an application does not support an extension, it might be able to load and show parts of the glTF file that do not use that extension. However, if the glTF file explicitly requires the extension, the application cannot load the file.

Extensions Supported by the Unreal Engine glTF Exporter

To support many of Unreal Engine's features the glTF exporter implements the following extensions. You can toggle any of them on and off using various settings in the glTF export options.

Extension

Provides support for

KHR_lights_punctual

Point, spot, and directional lights

KHR_materials_unlit

Materials that use the Unlit shading model

KHR_materials_clearcoat

Materials that use the Clear Coat shading model

KHR_materials_variants

Compact multiple Material variants per Asset

KHR_mesh_quantization

Reducing the size and precision of vertex data

KHR_texture_transform

Tiling and mirroring texture coordinates

Epic glTF extensions are only supported by the Unreal Engine glTF viewer. We recommend you avoid using export options that rely on these extensions if you plan to use your exported content on other platforms.

Extension

Provides support for

EPIC_lightmap_textures

Lightmass-baked Unreal-encoded lightmaps

EPIC_level_variant_sets

Scene variants by Unreal Engine's variant manager

EPIC_hdri_backdrops

Unreal Engine backdrop actors for HDR image projection

EPIC_sky_spheres

Unreal Engine's sky sphere actors

EPIC_animation_playback

Animation looping, auto play, start time, and play rate

EPIC_texture_hdr_encoding

HDR encoding for image formats like PNG and JPEG

EPIC_blend_modes

Additive, Modulate, and Alpha Composite blend modes





Import Individual Assets from glTF Files

Import a glTF Scene Into an Unreal Engine Level

You import glTF content into Unreal Engine the same way you import other types of content. You can import an entire scene, or specific Assets.

You can import the following glTF formats:

Format

Description

JSON.gltf

Includes the following elements, saved separately in a directory you specify:

Full scene description: saved as a JSON-formatted, human-readable UTF-8 text file with the .gltf extension.

Texture files: saved to the format you specify, .png, .jpeg, and so on.

Binary data files: saved separate files with a .bin file extension.

Binary.glb

Combines the full scene description, all binary data, and all textures into a single self-contained binary file.

Import Individual Assets from glTF Files

You can import glTF Assets into Unreal Engine the same way you import other Assets.

In the Content Browser, do one of the following:

In the +Add menu, use the Import to command. For detailed instructions see Importing from the Content Browser.

Drag and drop a glTF Asset into the Content Browser. For detailed instructions see Importing Using Drag and Drop. Whichever workflow you use opens the The Interchange Pipeline Configuration (Import Content) dialog box.

Set the import options as needed, and click Import.

Import a glTF Scene Into an Unreal Engine Level

You can import full glTF scenes into Unreal Engine using the same scene import workflow you use for other scene formats such as FBX.

From the main menu, choose File > Import Into Level.

Select the .gtlf or .glb file that contains the scene you want to import, and click Open.The Choose location for importing scene content dialog opens.

Choose the destination folder in your Unreal Engine project, and click OK.The Interchange Pipeline Configuration (Import Content) dialog box opens.

Set the import options as needed, and click Import.

What You Can Export

Export an Asset

Export the Current Level

Export Part of the Current Level

glTF Export Options Reference

General Options

Material Options

Mesh Options

Animation Options

Texture Options

Scene Options

Variant Sets Options

Use the glTF exporter to export individual Assets or the current Level to one of the following formats:

Format

Description

JSON.gltf

Includes the following elements, saved separately in a directory you specify:

Full scene description: saved as a JSON-formatted, human-readable UTF-8 text file with the .gltf extension.

Texture files: saved to the format you specify, .png, .jpeg, and so on.

Binary data files: saved separate files with a .bin file extension.

Binary.glb

Combines the full scene description, all binary data, and all textures into a single self-contained binary file.

This page explains how to export glTF files from the Unreal Editor UI. You can also export glTF files from the Editor using Blueprint, Python scripting, or C++. Runtime export without the Editor is also possible, but there are some limitations. For details, see Scripting glTF Exports.

What You Can Export

You can export the following types of Asset as glTF files:

Static Meshes

Skeletal Meshes

Animation Sequences

Levels

Level Sequences

Materials

Variant Sets

For more information about how the glTF exporter handles each of these Asset types, see How the glTF Exporter Handles Unreal Engine Content.

Export an Asset

To export an Asset to glTF:

In the Content Browser, right-click the Asset you want to export.

From the right-click menu, select Asset Actions > Export… . A file save dialog opens.

In the file save dialog, choose a name and location for the exported file. Make sure Save as type is set to .gltf or .glb, and click Save. The glTF Export Options dialog opens.

Set the export options as needed. For more information, see glTF Export Options Reference.

Click Save.

Export the Current Level

To export the all Actors in the current level to glTF:

Do one of the following:

From the main menu, select File > Export All… .

or

In the Content Browser, right click the Level Asset, and from the right-click menu, select Asset Actions > Export…

A file save dialog opens.

In the file save dialog, choose a name and location for the exported file. Make sure Save as type is set to .gltf or .glb, and click Save. The glTF Export Options dialog opens.

Set the export options as needed. For more information, see glTF Export Options Reference.

Click Save.

Export Part of the Current Level

To export a selection of Actors in the current level to glTF:

Select one or more Actors in the current level.

From the main menu, select File > Export Selected… . A file save dialog opens.

In the file save dialog, choose a name and location for the exported file. Make sure Save as type is set to .gltf or .glb, and click Save. The glTF Export Options dialog opens.

Set the export options as needed. For more information, see glTF Export Options Reference.

Click Save.

glTF Export Options Reference

The glTF Export Options dialog includes the following options:

General Options

Material Options

Mesh Options

Animation Options

Texture Options

Scene Options

Variant Set Options

General Options

Option

Description

Export Uniform Scale

Scales exported Assets to compensate for differences in units.The default value is 0.01, to convert from Unreal Engine's default unit of centimeters to glTF's default unit of meters.

Export Preview Mesh

When enabled, the glTF exporter exports the preview mesh for a standalone animation or Material Asset.

Strict Compliance

When enabled, the glTF exporter truncates some values to strictly conform to the formal glTF specification.

For example it:

Truncates HDR color values to be between 0 and 1.

Adjusts spotlight angle values to conform to the KHR_lights_punctual spec.

It can be difficult to troubleshoot errors caused by out of range values. Although some glTF importers and viewers accept them, or truncate them automatically, we recommend leaving the Strict Compliance setting enabled in most cases.

Skip Near Default Values

When enabled, the glTF exporter does not export floating-point-based JSON properties that are nearly equal to the default values specified in the glTF specification or the specifications for glTF extensions.This reduces the size of the exported JSON data.Skipped properties are treated as though they're set to their exact default values.

Include Generator Version

When enabled, the glTF exporter includes version info for Unreal Engine and the glTF exporter plugin in the exported glTF files.This is useful for troubleshooting issues with the exporter or exported Assets.

Material Options

Option

Description

Export Proxy Materials

When enabled, the glTF exporter checks whether each exported Material has a glTF proxy Material defined in its user data. If it does, the exporter exports the proxy instead of converting the original material.This setting does not affect glTF proxy Materials you reference directly, the way you would any other material.For more information, see glTF Proxy Materials.

Export Unlit Materials

When enabled, Materials that use the Unlit shading model are exported correctly.The glTF exporter uses the KHR_materials_unlit extension to export Unlit materials.For more information, see Shading Model Support.

Export Clear Coat Materials

When enabled, materials that use the clear coat shading model are exported correctly.

The glTF exporter uses the KHR_materials_clearcoat extension to export clear coat Materials.

Some glTF viewers do not support KHR_materials_clearcoat.

For more information, see Shading Model Support.

Export Extra Blend Modes

When enabled, the glTF exporter correctly exports Materials that use the following blend modes:

Additive

Modulate

Alpha composite

The glTF exporter uses the EPIC_blend_modes extension, which is supported by Unreal Engine's glTF viewer, to export Materials that use these blend modes.

For more information, see Blend Mode Support.

Bake Material Inputs

Specifies whether to bake a Material into a texture, and if so, how to bake it.

Disabled: Never use material baking and only rely on material expression matching.

Simple: If a material input needs baking, then only use a simple plane as mesh data.

Use Mesh Data: If a Material input uses mesh-specific data such as vertex color, world position, vector transform nodes and so on, this setting includes that data in the Material baking process, and the resulting texture. For materials that don't use mesh-specific data, the exporter uses a simple plane.

The exporter only uses baking for complex material inputs. For simple texture or constant expressions, it uses Material expression matching.

For more information, see Material Baking.

Default Material Bake Size

When Bake Material Inputs is enabled, this setting specifies the default size of the baked texture that contains the Material input.

You can override this default setting with Material-specific and input-specific bake settings. For more information, see the following sections:

Configure Global Material Bake Settings for Specific Inputs.

Configure Asset Specific Material Bake Options.

Default Material Bake Filter

When Bake Material Inputs is enabled, this setting specifies the default filtering mode used to sample the baked texture.

You can override this default setting with Material-specific and input-specific bake settings. For more information, see the following sections:

Configure Global Material Bake Settings for Specific Inputs.

Configure Asset Specific Material Bake Options.

Default Material Bake Tiling

When Bake Material Inputs is enabled, this setting specifies the default addressing mode used to sample the baked texture.

You can override this default setting with Material-specific and input-specific bake settings. For more information, see the following sections:

Configure Global Material Bake Settings for Specific Inputs.

Configure Asset Specific Material Bake Options.

Default Input Bake Setting

Input-specific default bake settings that override the general defaults.For details, see Configure Global Material Bake Settings for Specific Inputs.

Mesh Options

Option

Description

Default Level Of Detail

Default LOD level used to export a mesh.You can override this setting with Component or Asset settings. For example, a minimum or forced LOD level.For more information about how to control which LOD setting the glTF exporter uses, see Level of Detail (LOD).

Export Vertex Colors

Specifies whether to export vertex colors.

If you set Bake Material Inputs, in the Material Options, to Use Mesh Data, the exporter bakes vertex colors automatically for any Material that needs them.

The glTF format always uses vertex colors as a base color multiplier, which often produces undesirable results. We recommend disabling this option in most cases.

Export Vertex Skin Weights

Specifies whether to export the vertex bone weights and vertex indexes of Skeletal Meshes, which are required for animation sequences.

Use Mesh Quantization

When enabled, the glTF exporter uses quantization for vertex tangents and normals.This setting uses the KHR_mesh_quantization extension, which might cause the Mesh to not load in some glTF viewers.For more information about mesh quantization, see Mesh Quantization for High Quality Lighting and Reflections, and the KHR_mesh_quantization documentation.

Animation Options

Option

Description

Export Level Sequences

Specifies whether the glTF exporter exports Level Sequences. It only supports transform tracks.The exported Level Sequence plays at the Level Sequence Asset's Sequence Display Rate (frames-per-second setting).

Export Animation Sequences

Specifies whether the glTF exporter exports a single animation Asset used by a Skeletal Mesh Component.If you enable this setting, you must also enable Export Vertex Skin Weights in the Mesh Options.

Export Playback Settings

Specifies whether to export the following information for Animations or Level Sequences.

Play Rate

Start Time

Looping

Auto Play information

This setting uses the EPIC_animation_playback extension, which is supported by Unreal Engine's glTF viewer.

Texture Options

Option

Description

Texture Image Format

Specifies the image file format to use for exported textures.

None: The exporter does not export any textures.

PNG: The exporter always exports textures as .png files.

JPEG (if no alpha): The exporter exports textures that do not have an alpha channel as .jpeg files. If a texture has an alpha channel, the exporter exports it as a .png file instead.

Texture Image Quality

Specifies the level of compression for textures exported in a lossy image format.You can set values between 1 (least compressed) and 100 (most compression).Set a value of 0 to use the default compression level for the format. For .jpeg files, 0 is equivalent to the default value of 85.

No Lossy Image Format For

Specifies whether to use lossless image formats for textures that are more sensitive to compression artifacts.

These include the following texture types:

High Dynamic Range (HDR) textures

Normal Maps

Light Maps

Export Texture Transforms

When enabled, the glTF exporter exports UV tiling and un-mirroring settings in a Texture Coordinate expression node for simple Material input expressions.This setting exporter uses the KHR_texture_transform extension.

Export Lightmaps

When enabled, the glTF exporter exports lightmaps created by Lightmass when you export a level.This setting uses the EPIC_lightmap_textures extension, which is supported by Unreal Engine's glTF viewer.

Texture HDR Encoding

Specifies how the glTF exporter encodes textures that have pixel colors with more than 8-bit per channel.

None: The exporter clamps HDR colors to 8 bits per channel.

RGBM: The exporter uses modified RGBM encoding to store HDR colors. For details, see HDR encoding.

This setting uses the EPIC_texture_hdr_encoding extension, which is supported by Unreal Engine's glTF viewer.

Adjust Normalmaps

When enabled, the glTF exporter flips the direction of the green channel in normal maps to conform to the glTF convention.

Scene Options

Option

Description

Export Hidden In Game

Specifies whether to export Actors and Components that are set as hidden in-game.

Export Lights

Specifies whether to export directional, point, and spot light Components according to mobility.You can toggle export separately for Static, Stationary, and Movable lights.This setting uses the KHR_lights_punctual extension.

Export Cameras

Specifies whether to export Camera Components.

Export HDRI Backdrops

Specifies whether to export HDRIBackdrop Blueprints.This setting uses the EPIC_hdri_backdrops extension, which is supported by Unreal Engine's glTF viewer.

Export Sky Spheres

Specifies whether to export SkySphere Blueprints.This setting uses the EPIC_sky_spheres extension, which is supported by Unreal Engine's glTF viewer.

Variant Sets Mode

Specifies whether to export Level Variant Set Actors, and if so, how to export them.

None: Do not export Variant Sets

Khronos: Use the KHR_materials_variants extension to export variant sets.

Epic: Use the EPIC_level_variant_sets extension to export variant sets.

Variant Sets Options

Option

Description

Export Material Variants

Specifies whether and how to export material variants that change the Materials property on a Static or Skeletal Mesh component.

None

Simple

Use Mesh Data

Export Mesh Variants

Specifies whether to export Variants that change the Mesh property on a Static Mesh or Skeletal Mesh Component.

Export Visibility Variants

Specifies whether to export Variants that change the Visible property on a scene Component.



The Export to glTF Function

Exporting with Blueprint

Exporting with Python

Exporting at Runtime

This page explains how to use the Export to glTF function to export Levels or supported Assets from the Unreal Editor using Blueprint or Python, and how to export them at runtime.

The Export to glTF Function

The Export to GLTF function takes the following inputs:

An object to export: this can be any supported Asset. For more information about supported Assets, see How the glTF Exporter Handles Unreal Engine Content.To export the current Level, you can pass an empty (null) reference.

Selected actors: specifies the subset of the scene to export.

When you export using Blueprint or Python, you must provide this set, even if it is empty.

When you export a Level, provide an empty set to export all Actors in the Level.

A destination path: the name, path, and format (file extension) of the exported glTF file. You can specify the following formats:

Format

Description

JSON.gltf

Includes the following elements, saved separately in a directory you specify:

Full scene description: saved as a JSON-formatted, human-readable UTF-8 text file with the .gltf extension.

Texture files: saved to the format you specify, .png, .jpeg, and so on.

Binary data files: saved separate files with a .bin file extension.

Binary.glb

Combines the full scene description, all binary data, and all textures into a single self-contained binary file.

The export options. For more information, see glTF Export Options Reference.

The Export to GLTF function produces the following outputs:

OutMessage: The log messages from the export.

Return value: Returns true if the export was successful, false otherwise.

Exporting with Blueprint

You can add the Export to GLTF action to a Blueprint graph from the context menu (Miscellaneous > Export to GLTF).



Example of a Blueprint function to export a simple cube to glTF. Note the empty set of selected actors.

Exporting with Python

The following code sample exports all Assets in the /game/models/ subfolder as individual glTF files.

Exporting at Runtime

You can use the Export to GLTF function to export glTF files at runtime. However, neither Material baking nor Material expression matching is possible at runtime, so you need to do one of the following to handle most materials:

Pre-bake materials: in the editor, create glTF proxy Materials. The glTF exporter uses the proxy materials for runtime glTF exports. Proxy Materials automatically ship with your application because they are referenced in the User Data for your Unreal Engine Materials.For more information about creating proxy Materials, see glTF Proxy Materials.

In C++, use the GLTFBuilder API at runtime to modify the content of the glTF file before it is exported.

Overview: What You Can Export

Materials

Material Expression Matching

Material Baking

Shading Model Support

Blend Mode Support

Static Meshes

Skeletal Meshes

Animation Sequences

Level Sequences

Level Variant Sets

Variants Supported by the EPIC_level_variant_sets Extension

Actors

HDRI Backdrop Actors

Sky Sphere Actors

Level Sequence Actors

Level Variant Sets Actors

Components

Scene Component

Static Mesh Component

Skeletal Mesh Component

Camera Component

Directional Light Component

Point Light Component

Spot Light Component

Textures

HDR encoding

glTF is a data-driven format, and does not support everything in Unreal Engine. This page explains what kind of content you can export using glTF, and describes how the glTF exporter handles each type of content.

Overview: What You Can Export

The glTF exporter can export several types of Asset from Unreal Engine. When you export an Asset that references other content, the exporter can export some of that content as well.

Assets that you can export directly include the following:

Materials

Static Meshes

Skeletal Meshes

Animation Sequences

Level Sequences

Level Variant Sets

Levels (see Export the Current Level)

Content that you can export indirectly, when a supported Asset references it, includes the following:

Actors

Components

Textures

Materials

The glTF format uses a Metallic / Roughness physically-based rendering (PBR) workflow that can produce photorealistic materials. The glTF workflow is similar to Unreal Engine's workflow, but does not support arbitrary material expressions. Instead, it allows a single texture or constant for each material input.

In the glTF format, some inputs share the same texture (for example, Metallic / Roughness and Base Color / Opacity (Mask) ). To convert an Unreal Engine Material to glTF, the exporter uses the following methods, in the following order:

Material expression matching: faster and more accurate, but supports only simple Material expression patterns.

Material baking: supports most Material expression patterns, but is slower, and requires configuration.

When you export a Material, the exporter tries expression matching first. If expression matching fails, it falls back to material baking. This can happen frequently because most Unreal Engine Material inputs use more advanced expressions than expression matching supports.

You can configure the Material Bake settings to only use expression matching. For details, see Disable Material Baking.

Material Expression Matching

Material expression matching examines each material input expression to determine whether it matches one of a limited range of expression node patterns. If it matches, the glTF exporter extracts the values from the material expression, and converts them.

Expression matching is quicker and more accurate than Material baking, but can only handle very simple and strict expression patterns. The exporter uses it whenever a Material expression satisfies the necessary conditions.

Constant and Vector Parameter nodes

Examples of Constant and Vector Parameter material nodes



Constant and Vector Parameter patterns are not supported for Normal or Ambient Occlusion inputs because of limitations in glTF.

Texture Sample and Texture Parameter nodes, with or without a Texture Coordinate node

Examples of Texture Sample and Texture Parameter material nodes



Expression matching does not support multiplying a Texture Sample node with a constant.

Material Baking

Material baking renders a specific Material input's full expression into a 2D texture. It can handle most Material expressions, but is slower than expression matching, and requires that you configure some settings.

You set the global default values from the glTF export options dialog, in the Material section. See Configure Global Default Material Bake Settings.

You can override the global default settings with per-input default settings. See Configure Global Material Bake Settings for Specific Inputs.

You can also create default Material bake settings for an individual Asset, and even a specific Material input on that Asset. See Configure Asset Specific Material Bake Options.

Material baking works best, and most accurately for Materials that do not depend on when or how they are viewed (for example, things such as time or viewing angle). When the glTF exporter bakes a material, it evaluates each input expression, pixel by pixel, at that moment. Dynamic nodes such as Time, Camera Position, and Reflection Vector become static. We recommend that you avoid view-dependent expressions when you export Materials.

The glTF exporter uses the most specific setting it can find. For any given input on a given Material Asset, the exporter prioritizes settings in the following order.

Settings for a specific input on a specific Material Asset.

Default settings for a specific Material Asset.

Global default settings for a specific type of Material input.

Global default settings.

Configure the global default Material bake settings from the glTF export options dialog, in the Material section.

The global default settings are the ultimate fallback settings. If the exporter does not find a more specific setting for a given input on a given Material Asset, it uses the global default.

You can set the following options:

Option

Description

Bake Material Inputs

Specifies whether to bake a Material into a texture, and if so, how to bake it.

Disabled: Never use material baking and only rely on material expression matching.

Simple: If a material input needs baking, then only use a simple plane as mesh data.

Use Mesh Data: If a Material input uses mesh-specific data such as vertex color, world position, vector transform nodes and so on, this setting includes that data in the Material baking process, and the resulting texture. For materials that don't use mesh-specific data, the exporter uses a simple plane.

The exporter only uses baking for complex material inputs. For simple texture or constant expressions, it uses Material expression matching.

Default Material Bake Size

When Bake Material Inputs is enabled, this setting specifies the default size of the baked texture that contains the Material input.

You can override this default setting with Material-specific and input-specific bake settings. For more information, see the following sections:

Configure Global Material Bake Settings for Specific Inputs.

Configure Asset Specific Material Bake Options.

Default Material Bake Filter

When Bake Material Inputs is enabled, this setting specifies the default filtering mode used to sample the baked texture.

You can override this default setting with Material-specific and input-specific bake settings. For more information, see the following sections:

Configure Global Material Bake Settings for Specific Inputs.

Configure Asset Specific Material Bake Options.

Default Material Bake Tiling

When Bake Material Inputs is enabled, this setting specifies the default addressing mode used to sample the baked texture.

You can override this default setting with Material-specific and input-specific bake settings. For more information, see the following sections:

Configure Global Material Bake Settings for Specific Inputs.

Configure Asset Specific Material Bake Options.

In general, we recommend Use Mesh Data mode for Material baking. Use Mesh Data mode exports unique, per-mesh glTF Materials, but only for Materials that rely on mesh-specific data. This includes Materials that use the following expressions or nodes:

Vertex Color

VertexNormalWS

PixelNormalWS

Local Position

World Position

Actor Position

Object Position

Object Orientation

Object Radius

Object Bounds

Object Local Bounds

Pre-Skinned Local Bounds

Transform and Transform Position

Precomputed AO Mask

Lightmap UVs

Custom Primitive Data

If a Material does not require mesh-specific data, the exporter falls back to Simple mode for that material.

Simple baking mode produces Materials that are not unique to specific meshes. It can use the full texture area, because the mesh data used to bake the Material is a quad. It is more suitable for tiled or repeating textures.

When you bake a Material using mesh-specific data, the glTF exporter assumes that the mesh has lightmap UVs that cover the entire mesh, and do not overlap, which is not always the case. If Use Mesh Data mode produces Materials that look different from what you expect, we recommend that you change the baking mode to Simple.

Global, per-input, default Material bake settings override the global default settings, and are overridden by per-Asset settings.

You set global default Material bake options for a specific input in the glTF Export Options dialog.

Do the following:

In the Material section, locate the Default Input Bake Settings row, and click Add Element (+). A new sub-option appears.

From the drop-down list in the new sub-option row, select a Material input.

Expand the sub-option to display the Size, Filter, and Tiling Material bake settings for the selected input.You can toggle each setting on and off, and set it as needed.

Repeat the process for each Material input that you want to create global default settings for.

You can set Material bake options for individual Assets. A Material Asset can have default material bake options, and input specific Material bake options.

The Asset's default settings override both per-input global default settings, and overall global default settings.

Input-specific settings for an Asset override all other Material Bake settings.

Asset specific settings are inherited by the Asset's children. If a Material Asset has its own bake settings, any Material instance that is a child of the Asset (directly or indirectly) inherits those settings. If the Instance has its own settings, they override the Asset's settings.

To configure Material bake settings for a Material Asset, you add GLTF Material Export Options to its Asset User Data array.

In the Content Browser, select the Asset.

In the Details panel, expand the Asset User Data section.

Locate the Asset User Data row, and click Add Element (+). A new Index row appears.

From the dropdown list in the new Index row, select GLTF Material Export Options.

Do one or both of the following:

Set default Material bake options for the Asset.

Set Material bake options for specific inputs on the Material Asset.

Expand the Index > Override bake Settings > Default section to display the Size, Filter, and Tiling Material bake settings for the Asset.You can toggle each setting on and off, and set it as needed.

Expand the Index > Override bake Settings section.

Locate the Inputs row, and click Add Element (+). A new sub-option appears.

From the drop-down list in the new sub-option row, select a Material input.

Expand the sub-option to display the Size, Filter, and Tiling Material bake settings for the selected input.You can toggle each setting on and off, and set it as needed.

Repeat the process for each Material input that you want to create settings for.

You can disable Material baking completely, and force the glTF exporter to use Material expression matching.

In the glTF Export options dialog, go to the Materials section, and set Bake Material Inputs to Disabled.

When you disable Material baking, the exporter skips any Material input it can't export properly, and logs a warning in the output log. Skipped inputs get the default values specified in the glTF spec.

Shading Model Support

The glTF format supports the following Unreal Engine shading models:

Default Lit

Clear Coat

Unlit

It treats unsupported shading models as Default Lit.

If the material expression graph specifies the shading model, the exporter tries to evaluate it using static analysis. The static analyzer can only handle certain types of expressions. For example, the expression shown in this image:



Example of Shading Model Expression that the static analyzer can evaluate



The static analyzer might not be able to resolve more complicated expressions that use non-static variables. If the analyzer cannot resolve the evaluation to a single static shading model, the exporter chooses whichever of the remaining models supports the most rich and complex shading.

In order of priority it will choose:

Clear Coat

Default Lit

Unlit

If the static analyzer has already eliminated one of those models, the exporter chooses the model with the next highest priority.



Example of Shading Model Expression that the static analyzer can evaluate



Unreal Engine's Default Lit shading model has almost exactly the same material inputs as the default glTF shading model. For a list of Default Lit material inputs, see Shading Models.

There are some important differences between the Unreal Engine model and the glTF model. In the default glTF shading model:

Some inputs share texture slots (see Shared Texture Slots).

Some inputs can only accept textures (see Texture-Only Inputs).

The glTF Metallic / Roughness PBR workflow does not support Specular.

In the default glTF shading model some inputs are paired, and share texture slots.

Base Color shares a slot with Opacity (Mask)

Metallic shares a slot with Roughness

Paired inputs use the same texture, which means they always have the same texture resolution and coordinates. However, each input is represented by a different color channel. For example, in the Metallic / Roughness pair, the Metallic input uses the blue channel and the Roughness input uses the green channel.

In the default glTF shading model the following inputs can only accept textures:

Normal

Ambient Occlusion

Unlike other inputs, these cannot have a constant non-default value, unless you use 1x1 pixel texture to simulate a constant. If the exporter finds a constant value for either input, it does the following:

For Ambient Occlusion, the exporter automatically generates a 1x1 pixel texture to simulate the constant value.

For Normal, the exporter discards the constant, and assumes that the normal vector is meant to be aligned with the surface.

Unreal Engine's Clear Coat shading model extends the Default Lit model.

Clear Coat (intensity)

Clear Coat Roughness

Clear Coat Bottom Normal

The Clear Coat Bottom Normal input is not a regular material input pin. It is a separate custom output node. To use it, you must enable the Materials > Clear Coat Enable Second Normal option in your Unreal Engine project settings.

To support the Clear Coat shading model, the glTF exporter uses the KHR_materials_clearcoat extension. You can toggle Clear Coat shading on and off in the glTF export options dialog. Use the Material > Export Clear Coat materials option.

There are some important differences between the way Unreal Engine and glTF support the Clear Coat shading model.

Some inputs share texture slots (see Shared Texture Slots).

Some inputs can only accept textures (see Texture-Only Inputs).

In the glTF Clear Coat shading model, the Clear Coat and Clear Coat Roughness inputs are paired. Paired inputs use the same texture, which means they always have the same texture resolution and coordinates. However each input is represented by a different color channel. The Clear Coat input uses the red channel and the Clear Coat Roughness input uses the green channel.

In the glTF Clear Coat shading model, the Clear Coat Bottom Normal input can only accept textures. Unlike other inputs, it cannot have a constant non-default value, unless you use 1x1 pixel texture to simulate a constant.

Unreal Engine's Unlit shading model is a standalone model with two material inputs:

Emissive Color

Opacity / Opacity Mask (depending on blend mode)

In the glTF Unlit shading model, these two inputs are paired. Paired inputs use the same texture, which means they always have the same texture resolution and coordinates. However each input is represented by a different color channel. The Emissive Color input uses the blue channel and the Opacity / Opacity Mask input uses the green channel.

To support the Unlit shading model, the glTF exporter uses the KHR_materials_unlit extension, which you can toggle on and off in the glTF export options dialog. Use the Material > Export Unlit materials option.

Blend Mode Support

The glTF exporter supports the following Material blend modes:

Opaque

Masked

Translucent

Additive

Modulate

Alpha Composite

To support the Additive, Modulate, and Alpha Composite blend modes, the glTF exporter uses the EPIC_blend_modes extension, which you can toggle on and off in the glTF export options dialog. Use the Material > Export Extra Blend Modes option.

Static Meshes

glTF provides good support for Static Meshes, but there are a few caveats. This section describes special considerations for exporting Static Meshes from Unreal Engine to glTF.

In glTF, vertex colors always act as a multiplier for the base color, regardless of material. This can produce undesirable results. In most cases, we recommend that you set the glTF export options as follows:

In the Mesh section, disable Export Vertex Colors.

In the Material section, set Bake Material Inputs to Use Mesh Data.

glTF does not support half-precision (16-bit) UVs. We recommend that you use full precision (32-bit) UVs for Static Mesh Assets. Edit the Asset, and In the Details panel, enable the LOD[NUMBER] > Build Settings > Use Full Precision UVs option. *The glTF exporter exports all of a Static Mesh's UV channels. However, most glTF applications, including Unreal's glTF viewer, only support two UV texture coordinate channels. If you plan to export to glTF, make sure that your Materials only use texture coordinates in the first two UV channels.

The glTF file format does not support collision Geometry. The glTF exporter ignores it.

glTF does not support multiple levels of detail. The exporter uses a single LOD to export a Static Mesh. It uses the following rules to decide which LOD to export.

Setting

Location

Scope

Priority

Default Level Of Detail

glTF export options dialog, in the Mesh section.

Global

LowestThis is the global fallback. If no other settings override it, the glTF exporter uses the LOD specified here.

Minimum LOD

Static Mesh Asset properties, in the LOD Settings section.To access, open a Static Mesh Asset in the Static Mesh Editor, and find the setting in the Details panel.

Per Static Mesh Asset

If this LOD is configured for a Static Mesh Asset, and it is set to higher LOD level than the Default Level of Detail setting, then the glTF exporter uses this LOD to export the Static Mesh.

Override Min LOD

Static Mesh Actor properties or Static Mesh Component properties, in the LOD section.To access, select a Static Mesh Actor, and find the setting for the Actor or a Component in the Details panel.

Per Mesh Component or Actor

If this option is enabled for a Static Mesh Actor or a Component, the Min LOD setting overrides the Asset- level Minimum LOD setting.

Forced Lod Model

Static Mesh Actor properties or Static Mesh Component properties, in the LOD section.To access, select a Static Mesh Actor, and find the setting for the Actor or a Component in the Details panel.

Per Mesh Component or Actor

If you configure this LOD for a Static Mesh Actor or a Component, it overrides all other LOD settings, and the glTF exporter uses it to export the Actor.

Quantization is the process of transforming vector attributes that are normally stored at floating point precision so they can be stored at 8-bit or 16-bit precision instead. Quantizing saves disk space and memory.

The following vertex attributes are quantized in Unreal Engine and glTF:

Vertex colors (8-bit per component).

Vertex normals (8-bit or 16-bit per component).

Vertex tangents (8-bit or 16-bit per component).

If you need high-quality reflections and lighting, we recommend that you enable the Use High Precision Tangent Basis option for Static Mesh Assets. When this option is enabled, Unreal Engine stores quantized vertex normals and vertex tangents at 16-bit precision rather than 8-bit precision.

You can find the Use High Precision Tangent Basis option in each Static Mesh Asset's properties.

Open a Static Mesh Asset in the Static Mesh Editor.

In the Details panel, look for the option in the LOD [LEVEL] > Build Settings section, where [LEVEL] is the LOD level you plan to export using the glTF exporter.

To quantize vertex normals and vertex tangents, the glTF exporter uses the KHR_mesh_quantization extension, which you can toggle on and off in the glTF Export Options dialog. In the Mesh section, enable or disable the Use Mesh Quantization option.

Skeletal Meshes

The same export considerations that apply to Static Meshes (see Static Meshes also apply to Skeletal Meshes. The glTF exporter also has some additional limitations for Skeletal Meshes.

glTF does not support the following:

Mesh clothing Assets.

Morph target animations.

Animation Sequences

Unreal animation sequences are fully supported in glTF, as long as you also export vertex skin weights. The glTF exporter also accounts for Unreal Engine animation retargeting.

The Export Vertex Skin Weights option is in the glTF Export Options dialog, in the Mesh section. For details, see the glTF Export Options Reference.

Level Sequences

For the glTF exporter to include a Level Sequence Asset in a scene export, the Asset needs to be assigned to a Level Sequence Actor in the scene.

Support for Level Sequences is limited to transform tracks in absolute space. The glTF exporter does not support blending of multiple tracks.

The glTF exporter exports each Level Sequence at its selected Sequence Display Rate: the frames per second (FPS) setting in the Level Sequence Asset.

Level Variant Sets

In Unreal, you can use Variant Sets to configure almost any property in a scene. To include a Level Variant in a glTF scene export, the Asset needs to be assigned to a Level Variant Sets Actor in the scene.

The glTF exporter can export Level Variant Sets using different extensions. To choose an extension, set the Variant Sets Mode option in the Scene section of the glTF Export Options dialog.

Khronos uses the KHR_materials_variants extension. This extension works with several glTF viewers, but only supports Material variants. The Khronos extension also supports only one active variant at a time, and bundles all variants into the same set. This is different from Unreal Engine, where you can have multiple variants from different sets active at the same time.

Epic uses the EPIC_level_variant_sets extension. This extension only works with the Unreal Engine glTF viewer, but supports more types of variants and multiple active variants in different sets. See the next section for details.

Variants Supported by the EPIC_level_variant_sets Extension

Variant Type

What you can change

Material

Any Material asset on a Static Mesh or Skeletal Mesh Component

Static Mesh

The Mesh asset on a Static Mesh Component

Skeletal Mesh

The Mesh asset on a Skeletal Mesh Component

Visible

The visibility on a scene Component

You can toggle the different types of variants on and off in the glTF Export Options dialog, in the Variant Sets section. For details, see the glTF Export Options Reference.

Actors

The glTF exporter supports some types of Actors in a Level, and can export specific properties for each type. For details, see the following sections:

HDRI Backdrop Actors

Sky Sphere Actors

Level Sequence Actors

Level Variant Sets Actors

The exporter also supports some types of Components, and can export actors that are not one of the supported types, but have one or more supported Components assigned to them. If an Actor has a supported Component assigned to it, the exporter exports specific properties of the Component. For more information, see Components.

HDRI Backdrop Actors

HDRI Backdrop is a Blueprint Actor available via the HDRIBackdrop plugin. You can use it to quickly set up product visualization using HDR image projection.

The glTF exporter supports all HDRI Backdrop properties. For a list of properties, or for more information about the plugin, see the HDRI Backdrop Settings section in the HDRI Backdrop Visualization Tool documentation.

The glTF exporter uses the EPIC_hdri_backdrops extension to export HDRI Backdrop Actors. You can toggle HDRI Backdrops on and off in the glTF Export Options dialog, in the Scene section. For details, see the glTF Export Options Reference.

Sky Sphere Actors

Sky Sphere is a Blueprint Actor that provides a customizable dynamic sky sphere. It mimics the effects of atmospheric fog. The glTF exporter supports the following Sky Sphere properties:

Please note that export of Sky Sphere uses the glTF extension EPIC_sky_spheres, which can be turned off in the export options.

Property

Description

Directional Light Actor

An optional directional light actor to match the sky's sun position and color.

Sun Brightness

Brightness multiplier for the sun disk.

Cloud Speed

Panning speed for the clouds.

Cloud Opacity

Opacity of the panning clouds.

Stars Brightness

Multiplier for the brightness of the stars when the sun is below the horizon.

Colors Determined By Sun Position

If enabled, sky colors will change according to the sun's position.

Sun Height

If no directional light is assigned, this value determines the height of the sun.

Horizon Falloff

Affects the size of the gradient from zenith color to horizon color.

Zenith Color

Horizon Color

Cloud Color

Overall Color

Level Sequence Actors

The Level Sequence Actor is an engine actor that plays Level sequences in the scene. The glTF exporter supports the following Level Sequence Actor properties:

Property

Description

Level Sequence

Auto-play the sequence when created.

Auto Play

Auto-play the sequence when created.

Play Rate

The rate at which to playback the animation.

Start Time

Start playback at the specified offset from the start of the sequence's playback range.

Loop Count

Number of times to loop playback. -1 for infinite, else the number of times to loop before stopping.

The glTF exporter uses the EPIC_animation_playback extension to export playback settings (the last four properties in the table above). You can toggle playback setting exports on and off in the glTF export options.

Level Variant Sets Actors

The Level Variant Sets Actor queries and activates variants in Level Variant Sets at runtime. It is provided by the Variant Manager plugin, which is distributed with Unreal Engine.

The Level Variant Sets property is the only Level Variant Sets Actor property that the glTF exporter supports.

The glTF exporter uses the EPIC_level_variant_sets extension to export Level Variant Sets. You can toggle Level Variant Set export on and off in the glTF export options.

Components

If an exported Actor has a supported Component assigned to it, the glTF exporter exports specific properties of the Component. The following sections provide information about which properties it exports for each supported Component type.

Primitives:

Scene Component

Static Mesh Component

Skeletal Mesh Component

Cameras:

Camera Component

Lights:

Directional Light

Point Light

Spot Light

Scene Component

The glTF exporter supports the following Scene Component properties:

Transformation properties: Location, Rotation, and Scale.

Due to differences in how Unreal Engine applies scale, non-uniform scale may be represented differently in glTF.

Static Mesh Component

The glTF exporter supports the following properties that the Static Mesh Component inherits from the Scene component:

Transformation properties: Location, Rotation, and Scale.

Due to differences in how Unreal Engine applies scale, non-uniform scale may be represented differently in glTF.

It also supports the following Static Mesh properties.

Property

Description

Static Mesh

The Static Mesh used by this component.

Materials

The Materials used by this component.

When it exports a Static Mesh, the glTF exporter uses the following settings:

The level of detail that you configure in the component's LOD settings, using the Forced Lod Model, Min LOD, and Override Min LOD options.

The Asset's Minimum LOD setting.

The Default Level Of Detail specified in the glTF export options.

For details see Level of Detail (LOD).

Skeletal Mesh Component

The glTF exporter uses the EPIC_animation_playback extension to export playback settings for Skeletal Meshes (Play Rate, Start Time, Looping, and Auto Play). It supports the following properties that the Skeletal Mesh Component inherits from the Scene component.

Transformation properties: Location, Rotation, and Scale.

Due to differences in how Unreal Engine applies scale, non-uniform scale may be represented differently in glTF.

It also supports the following Skeletal Mesh properties.

Property

Description

Skeletal Mesh

The Skeletal Mesh used by this component.

Materials

The Materials used by this component.

Anim to Play

The sequence to play on this skeletal mesh.

Looping

If enabled, the sequence will be looped.

Playing

Auto-play the sequence when created.

PlayRate

The rate at which to play the animation.

Initial Position

Start play at the specified offset from the start of the sequence's playback range.

You can toggle playback settings on and off in the glTF Export Options dialog, in the Animation section. For details, see the glTF Export Options Reference.

When it exports a Skeletal Mesh, the glTF exporter uses the following settings:

The level of detail that you configure in the component's LOD settings, using the Forced Lod Model, Min LOD, and Override Min LOD options.

The Asset's Minimum LOD setting.

The Default Level Of Detail specified in the glTF export options.

For details see Level of Detail (LOD).

Camera Component

The glTF exporter supports the following properties the Camera Component inherits from the Scene component:

Transformation properties: Location, Rotation, and Scale.

Due to differences in how Unreal Engine applies scale, non-uniform scale may be represented differently in glTF.

It also supports the following camera properties:

Property

Description

Projection Mode

Specifies the type of camera. Choose Perspective or Orthographic.

Field Of View

The horizontal field of view (in degrees) in perspective mode (ignored in Orthographic mode).

Ortho Width

The desired width (in world units) of the orthographic view (ignored in Perspective mode).

Ortho Near Clip Plane

The near plane distance of the orthographic view (in world units).

Ortho Far Clip Plane

The far plane distance of the orthographic view (in world units).

Aspect Ratio

The ratio of width to height.

Constrain Aspect Ratio

If enabled, black bars will be added if the destination view has a different aspect ratio than this camera requested.

Directional Light Component

The glTF exporter uses the KHR_lights_punctual extension to export directional lights. It supports the following properties that the Directional Light Component inherits from the Scene component.

Transformation properties: Location, Rotation, and Scale.

Due to differences in how Unreal Engine applies scale, non-uniform scale may be represented differently in glTF.

It also supports the following directional light properties:

Property

Description

Intensity

Total energy that the light emits.

Light Color

Filter color of the light.

Temperature

Color temperature in Kelvin of the blackbody illuminant.

Use Temperature

If disabled, use white (D65) as the illuminant.

You can toggle directional lights on and off in the glTF Export Options dialog, in the Scene section. For details, see the glTF Export Options Reference.

Point Light Component

The glTF exporter uses the KHR_lights_punctual extension to export point lights. It supports the following properties that the Point Light Component inherits from the Scene component:

Transformation properties: Location, Rotation, and Scale.

Due to differences in how Unreal Engine applies scale, non-uniform scale may be represented differently in glTF.

It also supports the following point light properties:

Property

Description

Intensity

Total energy that the light emits.

Light Color

Filter color of the light.

Temperature

Color temperature in Kelvin of the blackbody illuminant.

Use Temperature

If disabled, use white (D65) as illuminant.

Attenuation Radius

Bounds the light's visible influence.

You can toggle point lights on and off in the glTF Export Options dialog, in the Scene section. For details, see the glTF Export Options Reference.

Spot Light Component

The glTF exporter uses the KHR_lights_punctual extension to export spotlights. It supports the following properties that the Spotlight Component inherits from the Scene Component.

Transformation properties: Location, Rotation, and Scale.

Due to differences in how Unreal Engine applies scale, non-uniform scale may be represented differently in glTF.

It also supports the following spotlight properties:

Property

Description

Intensity

Total energy that the light emits.

Light Color

Filter color of the light.

Temperature

Color temperature in Kelvin of the blackbody illuminant.

Use Temperature

If disabled, use white (D65) as illuminant.

Attenuation Radius

Bounds the light's visible influence.

Inner Cone Angle

Angle, in degrees,from the center of the spotlight, where falloff begins.

Outer Cone Angle

Angle, in degrees, from the center of the spotlight, where falloff ends.

You can toggle spotlights on and off in the glTF Export Options dialog, in the Scene section. For details, see the glTF Export Options Reference.

Textures

The glTF uses the EPIC_lightmap_textures extension to export textures. It supports following texture types:

Texture 2D

Texture Cube

Light Map Texture 2D

You can configure how the exporter exports textures from the glTF Export Options dialog. Use the options in the Texture section. For details, see the glTF Export Options Reference.

To support texture settings such as color adjustments, the exporter uses the render data (platform data) that Unreal Engine stores internally, rather than the source data.

The advantage to this approach is textures you export look the same as they do when they're rendered in the Unreal Editor or in-game.

The disadvantage is that if Unreal Engine's compression settings introduce any artifacts into the textures, they appear in the exported textures. To minimize artifacts, use the User Interface 2D and HDR compression settings whenever possible.

HDR encoding

The glTF uses the EPIC_texture_hdr_encoding extension to export high dynamic range (HDR) textures.

Because the glTF file format does not support HDR texture formats, the exporter uses modified RGBM encoding. It stores pixels as one byte each for RGB (red, green, and blue) values, and a shared one-byte alpha multiplier.

You can toggle HDR texture export on and off in the glTF Export Options dialog, in the Texture section. For details, see the glTF Export Options Reference.



Create a glTF Proxy Material

glTF proxy Materials are baked versions of the Materials in your Unreal Engine Levels. They are optimized for glTF export, and most commonly used to export Materials at runtime. Because Material baking, and other techniques the glTF exporter relies on, are not possible at runtime, proxy materials are the only way to export a Material properly.

glTF proxy Materials are also useful for:

Previewing: When you generate a proxy Material, you see exactly what your Unreal Engine Material looks like when you export it to glTF.

Performance: Using glTF proxy materials speeds up glTF exports because the exporter no longer needs to do any Material baking, which is the most time-consuming part of the export process.

Some Unreal Engine Materials use mesh-specific data such as world position, vertex colors, and so on. The glTF exporter can bake Unreal Engine Materials with mesh-specific data, but it cannot create proxy materials with mesh-specific data. If you need to create proxies for Materials that use mesh-specific data, you must create a proxy with each mesh individually.

Create a glTF Proxy Material

When you create a glTF proxy Material from an Unreal Engine Material, the proxy appears in a GLTF subfolder of the folder that contains the source Material. It has the same name as the source Material, prefixed with MI_GLTF.

To create a glTF proxy Material, do the following:

In the Content Browser, right-click a Material.

From the right-click menu, select Create GLTF Proxy Material.

When you create a proxy material, the glTF exporter automatically creates a reference to it in the Unreal Engine Material's Asset User Data array.

To see or modify the reference, do the following:

In the Content Browser, select the Asset and edit it.

In the Details panel, expand the Asset User Data section.

Locate the Asset User Data row, and click Add Element (+). A new Index row appears.

From the dropdown list in the new Index row, select GLTF Material Export Options.

Expand the Index > General section.

In the Proxy settings, you can see or modify the reference to the glTF proxy Material.

Getting Started

Guides

The Universal Scene Description (USD) interchange format is an open-source format developed by Pixar to address the need to robustly and scalably interchange and augment arbitrary 3D scenes that may be composed of many elemental assets. USD not only provides a rich toolset for reading, writing, editing, and rapidly previewing 3D geometry and shading, but also provides for the interchange of elemental assets (for example, models) or animations.

Getting Started



An overview of Universal Scene Description (USD) and how to use it in Unreal Engine.



Use USD files to quickly and easily synchronize Unreal Engine and an external content creation tool.

Guides



Workflows and actions you can perform while working with prims in the USD Stage Editor.



A tutorial on using the USD Stage workflow with your USD data.



Use Control Rig to manage USD animations directly in Unreal Editor.

Why use USD?

USD Support in Unreal Engine

Supported Actions

Importing Into Unreal Engine

Authoring and Editing Animation

USD Runtime Support

Nvidia MDL Support

Multi-User Editing Support

Enabling the USD Import Plugin

Using USD in Unreal Engine

USD Stage Workflow

Python Scripting

Use Case for using a Python script

Films, games, and other 3D graphic productions often generate, store, and transmit a great deal of data. This data can come from a variety of softwares (such as Unreal Engine, Maya, Houdini, or Blender) from within the art pipeline that each have their own proprietary form of scene description.

The Universal Scene Description (USD) interchange format is an open-source format developed by Pixar to address the need to robustly and scalably interchange and augment arbitrary 3D scenes that may be composed of many elemental assets. USD not only provides a rich toolset for reading, writing, editing, and rapidly previewing 3D geometry and shading, but it also provides for the interchange of elemental assets (for example, models) or animations.

Unlike other interchange packages, USD also enables assembly and organization of any number of assets into virtual sets, scenes, and shots. You can then transmit these from application to application, and non-destructively edit them (as overrides), with a single, consistent API, in a single scenegraph.

Why use USD?

USD provides a common language for moving significant amounts of data between multiple 3D applications. This provides flexibility when making decisions about your art pipeline and facilitates collaboration between multiple 3D artists (animators, lighting or shading artists, modelers, FX artists, and more) using iterative and non-destructive methods.

USD Support in Unreal Engine

Unreal Engine provides USD support through the USD Stage panel and bi-directional Python workflows.



The USD Stage window. Click image for full size.

Rather than converting USD data into native Unreal Engine Assets like Static Meshes and Materials, the USD Stage workflow works natively with your USD data. This makes it faster to get your USD data into Unreal Engine, gives you a clearer view of how your USD content was originally structured, and handles live updates as you make changes to the source USD file on disk.

The USD Stage provides the following functionality:

Represents 3D data as "prims": static meshes, skeletal meshes, HISM, Materials, Lights, Cameras, Variants, Animation, and Blend shapes.

Non-destructive attribute editing.

USD scene graph and hierarchy visualization.

Loading and unloading content using Payloads.

Support for Textures with USD Preview Surfaces.

Support for Materials with PreviewSurface and DisplayColor.

Support for USD Plugins such as Alembic and Custom path Resolver.

USD features supported at runtime. For more information, see USD Runtime Support.

Loads .usd, .usda, .usdc, and .usdz formats.

For more general information on Universal Scene Description, see Pixar's Introduction to USD.

For more information on working with the Python workflow, see Python Scripting.

Supported Actions

Importing Into Unreal Engine

Content that is displayed on the USD Stage (Static Meshes, Skeletal Meshes, Lights, Foliage, and Landscapes) can be imported into Unreal Engine using the following methods:

Using File > Import Into Level. This process will import both Assets (static mesh, skeletal mesh, materials, textures, and so on) and Actors.

Using the Add/Import button in the Content Browser. This process will only import assets.

Dragging and dropping the file into the Content Browser. This process will only import assets.

Using Action > Import option in the USD Stage Editor. This process will import both assets and Actors. After the import process is complete, assets on the USD stage are replaced with new Actors from the Content Browser.

Authoring and Editing Animation

Animations stored within a USD file are accessible using the associated Level Sequence found in the Properties panel of the USDStageActor.



Open the Level Sequence by selecting the USD Level Stage and double-clicking the Sequence in the Properties panel. Click image for full size.

USD xform animations are displayed as Transform tracks within the Level Sequence. Other forms of animation such as floats, boolean, and skeletal bones, are displayed via the Time track. The USD animation data in the image above is represented as a key / value pair at each timecode for the duration of the animation.

Through the USD Stage generated Level Sequence, you can bind to an Actor that is spawned on the USD Stage and add additional animation through a Transform track.

USD Runtime Support

Unreal Engine supports the loading of USD files at runtime through calling the Set Root Layer Blueprint node on a USD Stage Actor inside the Level.



The Set Root Layer node. Click on image for full size.

This node creates the required Assets and spawns Actors and components into the Level identically to how the process is handled in the editor. Additional Blueprint functions for controlling various USD Stage Actor properties include:

Blueprint Function

Description

Get Generated Assets

Gets the Assets generated for a prim within a given prim path and places them in an array. Uses a USD Stage Actor and Prim Path as inputs.

Get Generated Components

Gets the component generated for a prim within a given prim path. Uses a USD Stage Actor and Prim Path as inputs.

Get Source Prim Path

Gets the Prim Path for a given object on the USD Stage. Uses a USD Stage Actor and an Object reference as inputs.

Get Time

Gets the current timestamp within the target USD Stage Actor. Takes a USD Stage Actor as Target.

Set Initial Load Set

Sets the initial payload to load. Uses a USD Stage Actor as input and provides the following options.

Load All: Load all payloads initially.

Load None: Load no payloads initially.

Set Purpose to Load

Sets the initial Purpose to load. Uses a USD Stage Actor and an integer as input.

0 = Default

1 = Proxy

2 = Render

3 = Guide

Set Render Context

Sets the Render Context of a USD Stage. Takes a USD Stage Actor as Target and reference to a Render Context as input.

Set Time

Sets the current timestamp of a USD Stage. Takes a USD Stage Actor as Target and a float value as input.

For more information on the Purpose attribute and other USD terms, see Pixar's USD Glossary.

Using this process, you can create applications capable of loading and displaying the contents of a USD file at runtime.

To enable the USD importer at runtime, add the following line to your Project.Target.cs file located in the UE_(version)\Engine\Source folder, where Project is your project name:

For example:

Nvidia MDL Support

Unreal Engine supports MDL surface materials using the Nvidia MDL USD schema. For more information on Nvidia MDL, see Nvidia's USD Shader Attributes.

Multi-User Editing Support

Multi-user Editing is supported by many USD Stage operations, including the following:

Adding and removing prims.

Renaming prims.

Editing prim attributes.

Toggling visibility.

Opening, closing, or changing the current stage.

To enable multi-user support for your USD project, enable the USD Multi-User synchronization plugin. To find out more about how to work with Plugins, see Working with Plugins

USD multi-user editing synchronizes the Root Layer property of the USD Stage for each client, ensuring that all users have the same USD files. This is done by having each client open the same USD stage locally, spawning assets and components on their own system, and then only synchronizing the operations done to those assets.

During a multi-user editing session, it is important for all users to access the USD files using the same file path. To make certain that each client can access the same files, we recommend that the target USD files are stored within the project folder and managed using source control.

For more information on Multi-User Editing in Unreal Engine, see Multi-User Editing in Unreal Engine.

It is not possible to undo prim deletion during a multi-user session.

Enabling the USD Import Plugin

To begin working with a USD file in the Unreal Editor, you will need to enable the USD Importer plugin from the Plugins menu. To find out more about how to work with Plugins, see Working with Plugins

After the editor restarts, you will see a new USD Stage option listed under the Window > Virtual Production menu in the Level Editor.

The Place Actors panel lists a new Usd Stage Actor that you can add to your Level.



New USD Actors available in the Place Actors panel.

Using USD in Unreal Engine

Working with USD content in Unreal Engine begins with the USD Stage Editor and the USD Stage Actor.



The USD Stage panel.

Number

Description

1

Hierarchy

2

Properties

3

Layers

USD Stage Workflow

A USD Stage Actor acts as a container for the contents of a loaded USD file and provides an anchor for that data within your Level. The 3D scene objects that are loaded from the USD file and seen in the viewport are fully compatible with most other Unreal Engine features, and you can treat them exactly like other Actors. You can add additional prims that reference content found in other USD files, including animated Skeletal Meshes.

Saving changes made to your USD stage using the File > Save menu in the USD Stage Editor writes those changes back to your USD file.

For more information on working with the USD Stage, see USD Stage Editor Quick Start.

Unreal Engine does not automatically create lightmaps for assets loaded on the USD Stage when a USD file is opened. This can result in a completely black scene when static lighting is built.

Python Scripting

Python scripting with USD provides a flexible way to perform a variety of actions such as batch operations and scene edits that may be difficult or time consuming to do using the user interface. Operations such as hiding or editing the attributes of a large number of prims can be automated quickly using a flexible Python script launched from the Output Log panel.

Prior to using Python, you must enable the Python Editor Script plugin. To find out more about plugins, see Working with Plugins.

You can then use the Output Log located at the bottom of the Level Editor to execute python scripts. You can also open the Output Log as its own panel from Window > Output Log.



Click image for full size.

For more information on using Python scripting with Unreal Engine, see Scripting the Unreal Editor Using Python.

Use Case for using a Python script

When the USD SDK version that ships with Unreal Engine was upgraded to 21.05, the update renamed several attributes within the USDLux Light schemas. To resolve the issue, Unreal Engine includes a Python script that renames USDLux prim attributes to the 21.05 naming convention.

The script can be found within the USDImporter source files located in Engine/Plugins/Importers/USDImporter/Content/Python/usd_unreal/update_lights_to_21_05.py.

Follow these steps to execute the script from the Output Log:

Open the Output Log by selecting Window > Output Log.

Click the Cmd dropdown to the left of the command line field and select Python.

Enter the following in the command line field: "C:\Program Files\Epic Games\UE_4.27\Engine\Plugins\Importers\USDImporter\Content\Python\usd_unreal\update_lights_to_21_05.py" "C:/path/to/root_layer.usda"

Where "C:/path/to/root_layer.usda" is the path to your USD file.

The sample above contains the default path to the Unreal Engine install. Be sure to update the path if you did not install your version of Unreal Engine in the default location.

Press Enter to execute the command.

Duplicating Prims

Cut/Copy/Paste Prims

Adding References

Adding Payloads

Isolate Layers

A USD Stage is a complex composition of layers that can have sublayers, references, and layered files. The USD Stage Editor in Unreal Engine enables you to work with and edit USDs.

This guide explores the actions and workflows you can use while working with USD files in Unreal Engine.

For more information on USD stages and terminology, see Pixar's Universal Scene Description Terms and Concepts.

Also, see the USD Stage Editor Quick Start to get started using the USD Stage Editor in Unreal Engine.

Duplicating Prims

The Duplicate rollout lists several options for duplicating a prim. USD is a complex format and it's not obvious in all cases what "duplication" means. Because of this, the USD Stage Editor provides multiple duplication methods that use slightly different approaches, and that can be useful in different situations.



Flatten Composed Prim combines prim specs and makes a new prim with them, "flattening" everything. If the composed prim has an override on a spec, that override is the only opinion for that spec that will be visible on the duplicated prim.

Single Layer Specs duplicates the prim's specs on the current Edit Target only. You can use this option to duplicate a prim's specs on a given layer without also duplicating overrides defined on stronger layers. This option is only available when the current edit target has specs for the prim you are duplicating.

All Local Layer Specs duplicates each of the prim's specs across all local layers of the USD stage.

You can use a text editor to inspect the changes made to your USD file after saving it in the USD Stage Editor.

Cut/Copy/Paste Prims

The Cut and Copy actions always add flattened representations of the prims to the clipboard stage (similar to the Flatten Composed Prim method of duplicating prims). The Paste action always pastes the prims from the clipboard stage as children of the currently selected prim, on the current Edit Target.

The Clipboard Stage is a separate stage the USD Stage Editor keeps behind the scenes, independent of whatever stage is currently opened. Because of this, it is possible to use these actions to cut, copy, and paste prims across different opened USD Stages.

Adding References

You can give any prims on the USD Stage Editor a reference that points to another prim on the currently-loaded USD Stage or another USD file on your machine. Use the Add Reference option from the right-click context menu to open the Add Reference dialog where you can specify how you want the selected prim to reference another.



Property

Description

Internal Reference

When enabled, the reference will target a prim on this stage.

Target File

Select the USD file to use as a reference.

Use Default Prim

Use the default prim of the target layer as the referenced prim.

Target Prim Path

When Use Default Prim is disabled, select a specific prim of the target stage as the referenced prim.



Advanced



Time Code Offset

Applies an offset to the referenced prim's timeline sampled attributes. For example, setting a value of 10 will delay the start of the referenced animation by 10 time codes.

Time Code Scale

The time scaling factor to apply to the referenced prim's timeline sampled attributes.

To add a reference to a prim on the currently-loaded USD Stage, enable Internal Reference and disable Use Default Prim. This disables the Target File option and enables the Target Prim Path option, where you can specify which prim to use.

To reference another USD layer, leave Internal Reference disabled so that you can specify it as the Target File. You can optionally disable Use Default Prim to specify a prim to use as a reference within the Target Layer. Leaving Use Default Prim enabled uses the default prim of the Target Layer as the referenced prim.

You can use Clear References on the right-click context menu to remove all references used by this prim.

Adding Payloads

Any prims on the USD Stage Editor can contain a payload. Analogous to references, you can add new payloads by right-clicking the prim and picking Add Payload, where you can specify the payload details.



Property

Description

Internal Reference

When enabled, the payload will target a prim on this stage.

Target File

Select the USD file to use as a payload.

Use Default Prim

Use the default prim of the target layer as the payload prim.

Target Prim Path

When Use Default Prim is disabled, select a specific prim of the target layer as the payload prim.



Advanced



Time Code Offset

Applies an offset to the payload prim's timeline sampled attributes. For example, setting a value of 10 will delay the start of the payload animation by 10 time codes.

Time Code Scale

The time scaling factor to apply to the payload prim's time sampled attributes.

To add a payload to a prim on the currently loaded USD Stage, enable Internal Reference and disable Use Default Prim. This disables the Target File option and enables the Target Prim Path option, where you can specify which prim to use.

To use another USD layer as a payload, leave Internal Reference disabled so you can specify a Target File. You can optionally disable Use Default Prim to specify a prim to use as a payload within the Target Layer. Leaving Use Default Prim enabled uses the default prim of the Target Layer as the payload prim.

You can use Clear Payloads on the right-click context menu to remove all payloads used by this prim.

Isolate Layers

The Isolate option is useful when you want to see a particular subtree of layers and not the entire USD Stage. Behind the scenes, while you're picking a particular layer to isolate, you're seeing that layer and all of its sublayers.

You can access this option by right-clicking on the layer you want to isolate in the Layers panel.



Isolating a layer only shows that layer and its sublayers. All other layers are grayed out to indicate they are present on the outer stage but not affecting the isolated stage.

To indicate a layer from the stage is isolated, the USD Stage window displays Isolated Mode in the top-right corner of the window. Clicking this message ends isolation mode and reverts back to the fully composed stage.



Alternatively, you can stop isolating a layer by right-clicking on the same layer and selecting Stop Isolating.

Universal Scene Description in Unreal Engine

1. Creating the USD Stage Actor

2. Editing Properties Using the USD Stage Window

3. Adding New Prims to Your USD Stage Actor

4. Writing Data Back to Your USD File

5. Accessing USD Animations Using Sequencer

6. Importing Assets into an Unreal Engine Project

Unreal Engine provides support for USD through the USD Stage Actor and the USD Stage workflow. In this Quick Start guide, you will:

Creating the USD Stage Actor.

Editing properties using the USD Stage Window.

Adding new Prims to your USD Stage Actor.

Writing data back to your USD file.

Accessing USD animations using Sequencer.

Importing assets into an Unreal Engine project.

Before you begin, you will need the USD Importer plugin enabled in your project. For more information, see Working with Plugins.

Prerequisite Topics

In order to understand and use the content on this page, make sure you are familiar with the following topic:

Universal Scene Description in Unreal Engine

This tutorial uses the Kitchen Set USD file from Pixar. Pixar maintains a small library of USD sample files for learning and demonstration. Download the Kitchen Set and other samples here.

1. Creating the USD Stage Actor

Start working with USD content by opening the USD Stage panel.



Click image for full size.

In the Level Editor, from the Top Menu, select Window > Virtual Production > USD Stage.

From the menu in the USD Stage Editor panel, select File > Open and navigate to your USD file.

The Hierarchy section will populate with the scene hierarchy from your USD file.



The Hierarchy section of the USD Stage window populated with the contents of the Kitchen Set. Click image for full size.

Each USD file you open in Unreal Engine requires its own USD Stage Actor that serves as an anchor for your USD data. The process outlined above will automatically add a USD Stage Actor to your Level.

It is also possible to add a USD Stage Actor using the Place Actors panel and select an associated USD file for it using the Root Layer option in the Details panel.

2. Editing Properties Using the USD Stage Window

You can edit the properties of your USD Stage Actor and prims using the Properties section of the USD Stage Editor window.

Changing the UpAxis of the USD Stage Actor

Select Stage at the top of the hierarchy in the USD Stage window. In the Properties section, locate the upAxis property and click the dropdown menu. Select the new axis to represent up for your USD data.



Select the axis the best fits your USD data. Click image for full size.

Changing the Variant of a Prim

In the USD Stage Editor, select Options > Selection and enable Synchronize with Editor. This synchronizes your selection between the Unreal Engine Level and the USD Stage Editor window.



Enable Synchronize with Editor to synchronize your selection between the USD Stage and the Unreal Engine viewport. Click image for full size.

In the Hierarchy section, click the dropdown arrow next to Kitchen_Set to expand the group. Expand Props_grp to display the props in the scene.

Expand West_grp to display individual prims. Props highlighted in orange indicate that they are composition arcs, and you can right-click any of their prims to add references to them (or clear references from them). Other right-click actions include the ability to add or remove prims, and the ability to toggle, load, or unload payloads.



Click image for full size.

Expand DiningTable_grp and select ChairB_1. In the Properties section you can edit the following:

Property

Description

name

Displays the name of the selected asset.

path

Displays the path of the selected asset.

kind

Defines the type of the selected asset.

assembly: Collection of models.

component: Type of model that contains subcomponents.

group: Collection of models within an assembly.

model: Base type of kind. Assets should not have their kind set to model since it is an abstract commonality used to differentiate components and groups. For more information, see Model Hierarchy in the Pixar USD documentation.

subcomponent: Prims inside a component. Not a type of model.

purpose

Sets the initial Purpose to load. Uses a USD Stage Actor and an integer as input.

Options include:

default

proxy

render

guide

visibility

Sets the initial Purpose to load. Uses a USD Stage Actor and an integer as input.

Options include:

inherited: Inherits visibility from its parent

invisibile: Prim and any prims included in its subtree are not rendered.

xformOp:rotateZ

Defines the Z rotation of the selected asset.

xformOp:translate

Defines the X, Y, and Z location of the asset.

xformOpOrder

Displays the order in which transform operations are applied to the asset.

modelingVariant

Defines the current variant being displayed in the scene. It will only be visible if the asset has one or more variants.

References

Displays all references attached to this prim.

The chairs in this scene have two variants, ChairA and ChairB. With ChairB_1 selected, locate the Variants section of the Properties. Change modelingVariant to ChairA. This will swap the chair mesh used in the scene with the new variant.

3. Adding New Prims to Your USD Stage Actor

Prims are added or removed from the hierarchy using the right-click menu. Once added, their properties can be edited in the Properties section.

Adding a new chair to the Kitchen Set

Right-click the DiningTable_grp entry in the hierarchy and select Add Prim from the menu. Name this new prim ChairB_3.



Adding a new prim to the USD Stage. Click image for full size.

Select your new prim in the hierarchy. In the Details section, change its kind to component.



Changing the properties of the new prim. Click image for full size.

Reference the chair USD file to bring it into the stage. Right-click ChairB_3 in the hierarchy and select Add Reference. Navigate to the location of your Kitchen Set files. Open the assets > Chair folder and select Chair.usd. Click Open.

Your new prim now references the Chair USD data and displays the ChairA variant. It should be located at the Level's origin. Select ChairB_3 in the hierarchy and change the modelingVariant to ChairB.

Click the new chair in the viewport and use the transform tools to place the chair near the table.

4. Writing Data Back to Your USD File

Changes made using the USD Stage Actor can be written back to your USD file. From the USD Stage panel, select File > Save.

5. Accessing USD Animations Using Sequencer

Accessing USD Animations

Animations stored within a USD file are accessible from a specifically-generated Level Sequence spawned by the USD Stage Actor.

In the Outliner, select UsdStageActor. In the USD section of the Details panel, locate the Level Sequence. Double-click the asset to open it in Sequencer.



Double click the Level Sequence in the Details panel. Click image for full size.

For more information on using Sequencer, see Cinematics and Sequencer.

Animating the Chair

To add animation to the new prim ChairB_3 that you created in step three, you will create a new USD file and add it as a layer to the USD Stage Actor.

In the Layers section of the USD Stage window, right-click the kitchen_set.usd layer and select Add New. Save this new file as myanim.usda.



Add a new Layer to your USD data for the animation. Click image for full size.

USD layers use a LIVRPS structure to determine how layers affect the final composition of the scene. For animation to affect the kitchen set, the layer containing that animation must be higher in the layer structure than the scene containing the prims. From the Top Menu in the Level Editor, select Window > Place Actors to open the panel. Search for Usd Stage Actor in the Place Actors panel and drag a new copy into your Level.



New USD Actors in the Place Actors panel. Click image for full size.

Select the UsdStageActor in the Outliner. From the USD Stage panel, select File > Open and browse to your myanim.usda file.

Add the kitchen set back into the layer stack by right-clicking the myanim.usda layer and selecting the Add Existing option. In the File window, navigate to your kitchen_set.usd file and click Open.

Before adding the animation, the USD Stage needs to know how long the animation will be. Click the Stage prim in the hierarchy. In the Properties section, change the endTimeCode and endFrame values to 48.



Change the endTimeCode and endFrame properties. Click image for full size.

Select your new USD Stage Actor in the Outliner. From the Details panel, scroll down to the USD section and locate Level Sequence. Double-click the asset to open it in Sequencer.

In the Sequencer panel, click the + Track button and select the Actor you want to animate from the Actor to Sequencer submenu.



Add a new Track group for the selected Actor. Click image for full size.

Click the Add (+) button on the new track and create a new Transform track.



Add a new Transform track. Click image for full size.

Animate the chair rotating in place. For more information on using Tracks in Sequencer, see Tracks.

Write the data back to USD using File > Save in the USD Stage window.

6. Importing Assets into an Unreal Engine Project

Actors displayed on the USD Stage Actor can be imported into the Unreal Editor's Content Browser through any of the following import options.

Using File > Import Into Level. This process will import both assets (static mesh, skeletal mesh, materials, textures, and so on) and Actors.

Using the Add/Import button in the Content Browser. This process will only import assets.

Dragging and dropping the file into the Content Browser. This process will only import assets.

Using the Action > Import option in the USD Stage Editor window. This process will import everything on the USD Stage Actor and works with both assets and Actors. After the import process is complete, assets on the USD Stage are replaced with new Actors from the Content Browser.

Importing the Kitchen Set into Unreal Engine

With the Kitchen Set open in the USD Stage window, open the Actions menu and select Import.

Select the location to store the imported assets. In this example, importing the Kitchen Set will create a folder named Kitchen_set in the selected location. Materials and static meshes are saved into separate subfolders.

Universal Scene Description in Unreal Engine



Live Link

Overview

Following This Guide

1. Required Setup

2. Establish a Live Link Connection

3. Export a USD File and Use It to Synchronize Assets

Result

Configuration

Enable and Disable the Live Link Connection

Custom Animation Blueprints

Choose Live Link Subjects

The Live Link plugin synchronizes animation assets between Unreal Editor and an outside digital content creation (DCC) tool such as Maya or Houdini, providing a fast way to preview assets as they appear in-engine. Unreal Engine can use Universal Scene Description (USD) files as part of Live Link connections and maintain them over the course of a project, improving the expedience and convenience of this workflow. This tutorial provides a walkthrough of setting up Live Link connections in Unreal Engine using USD files, and an overview of the benefits of the USD format when using Live Link.

Overview

When you set up a Live Link connection using the USD Stage, it adds a custom Live Link schema to the USD prim alongside attributes that describe the connection. As long as this information remains in the USD file and both your DCC and Unreal Engine have a Live Link connection, the connection for the assets can be re-established. If either application restarts or the file was closed and reopened in the DCC, the Live Link connection will need to be re-established.

Following This Guide

The examples in this guide use Autodesk Maya and the Unreal Live Link V2 plugin, but any DCC toolset with Live Link integration should be able to establish a connection to Unreal Engine. Review the instructions for your DCC's Live Link integration for any differences from the workflow presented here.

If you are using the Unreal Live Link V2 plugin, the installer will also set up the Maya Live Link plugin for Unreal Engine. Use this instead of the standard Live Link plugin if you are using Maya.

1. Required Setup

To follow this guide, you need to fulfill the following prerequisites:

Enable the Live Link plugin for both Unreal Engine and your DCC.

Use the Maya Live Link plugin instead if you are using Autodesk Maya.

Enable the USD Importer plugin in Unreal Engine.

To set up the plugins in Unreal Engine, click Edit > Plugins to open the Plugins menu, then locate the plugins and enable them. Refer to the instructions for your DCC's Live Link integration or its guide on using plugins for information about how to activate it.

This guide also uses a new project created with the Third-Person Template. This includes the Unreal mannequin models and their animations. These are available in the Content/Mannequins folder in the Content Browser. This guide uses these assets to provide an example, but they are not necessary to follow these instructions, and you can follow along with any Skeletal Mesh.

2. Establish a Live Link Connection

Open both your DCC and Unreal Editor.

Set up your DCC's Live Link integration.

For Maya, download and install the Unreal Live Link plugin. You can download the installer here, and once you have installed it you can open it by clicking File > Unreal Live Link.

In Unreal Editor, click Window > Virtual Production > Live Link to open the Live Link window.



Click the + Source button in the Live Link window. Highlight Message Bus Source and select your DCC's Live Link connection.



Click to enlarge image.

Your DCC and Unreal Engine will connect and synchronize using Live Link. However, because no asset is synchronized, you will not see any change yet.

3. Export a USD File and Use It to Synchronize Assets

Now that you have opened a Live Link connection, export a USD file and use that to synchronize the asset.

Locate the MM_Run_Fwd animation in the Content Browser. You can find it in Content/Characters/Mannequins/Animations/Manny.



Click to enlarge image.

Right-click MM_Run_Fwd. Click Asset Actions > Export.



Export the asset using the .usda file format.



Click to enlarge image.

While you need to export your file as a .usda file to use the USD stage, you can also export it as a .fbx file for the purposes of importing it into Maya.

In the USD Export Options dialog, make sure Export Preview Mesh is checked, then click Export.



Open your DCC and import the .usda file.

In Maya, click File > Import, then select USD Import and choose the .usda file. Rotate it -90 degrees on the X axis to make it face upwards.

Select the root bone, then add the selection to Live Link.

In Maya, click File > Unreal Live Link to open the Unreal Live Link window.



Select the root bone of your mesh in the hierarchy and click Add Selection in the Live Link window to add it to your list of Live Link subjects.



Click the dropdown for your selection's Type and choose Full Hierarchy.



You will need your Object Name in a later step when you choose your Subject Name in Unreal Editor.

Click Window > Virtual Production > USD Stage to open the USD Stage window.



In the USD Stage, click File > Open, then select the MM_Run_Fwd.usda file.



In the USD Stage, right click the SkelRoot for your model, then click Set Up Live Link.



The Live Link integrations panel appears, and shows DefaultLiveLinkAnimBP as your Animation Blueprint.

Click the Live Link Subject Name dropdown and select the value that corresponds to the Object Name you selected in your DCC. These need to match for the Live Link connection to work.

Result

If you scrub the animation for your asset in your DCC, the animation is synchronized in Unreal Engine.

Configuration

The following options are available in the USD Stage for configuring your Live Link setup.

Enable and Disable the Live Link Connection

You can enable and disable the Live Link connection in the USD stage with the Enable Live Link Connection setting in the USD Stage.



This allows you to quickly alternate between viewing the animation provided using Live Link and viewing the original animation present on the USD Stage.

Custom Animation Blueprints

By default, when you set up Live Link with your USD Stage, the skeletal mesh uses the DefaultLiveLinkAnimBP asset. This Animation Blueprint uses the Live Link Pose node to listen to the pose provided by your DCC.



You can use a custom Animation Blueprint instead by changing the Anim Blueprint Asset field in the Integrations panel. Use the Live Link Pose node in your custom Animation Blueprint to provide compatibility with Live Link.

Choose Live Link Subjects

The Live Link Subject Name selects the particular Live Link subject to synchronize with this specific prim. This has to match the Object Name value of one of the objects added to your DCC's Live Link manager.

Universal Scene Description in Unreal Engine



Control Rig

Overview

1. Required Setup

2. Export a USD File

3. Set Up Control Rig in the USD Stage

Result

Configuration

Forward Kinematic Control Rig

Reduce Keyframes

The USD Importer can use Control Rig to bake and directly manipulate skeletal animation from opened USD Stages. It can then save and maintain changes to the animation in the USD file. This guide walks you through this workflow and provides a reference for some of its configuration options.

Overview

When you bind a Control Rig to your SkelRoot prim in the USD Stage window, the USD Importer automatically performs the following processes:

Adds a Control Rig track to Sequencer.

Runs through the animation from start to finish, adding keyframes to the Control Rig for each frame of animation.

Disables the skeletal animation section.

As a result, the Control Rig has one keyframe for each individual frame of animation, and it effectively assumes control of the animation. Any changes can then be saved out to the USD file, which preserves animation data between sessions. This reduces the amount of busywork needed to quickly edit animations in-engine.

For information about how to reduce the number of automatically generated keyframes from this process, refer to the section on Reducing Keyframes below.

1. Required Setup

To use the USD Importer, you need to enable the USD Importer plugin in the Edit > Plugins menu. Restart the editor after enabling the plugin.



Click to enlarge image.

This guide uses a new project created using the Third-Person template. This includes the Unreal Engine mannequin models and the CR_Mannequin_Body control rig. Both of these are available in the Content/Mannequins folder in the Content Browser.

This guide uses these assets to provide an example, but they are not necessary to follow these instructions. You can follow along with any Skeletal Mesh as long as you have already created a Control Rig for that mesh. For more information on using Control Rigs, refer to the Control Rig documentation.

2. Export a USD File

To take advantage of the USD Stage's functionality for setting up Control Rigs, you need to export a USD of the animation you want to edit.

Select an animation asset and a Control Rig that corresponds to that asset's skeletal mesh. This example uses the following assets from the third-person template:

Animation asset: Content/Characters/Mannequins/Animations/Manny/MM_Walk_InPlace

Control Rig: Content/Characters/Mannequins/Rigs/CR_Mannequin_Body

Right-click the animation in the Content Browser, then click Asset Actions > Export.



Click to enlarge image.

In the export dialog, select Universal Scene Description file (*.usda) as the file type, then click Save.



Click to enlarge image.

In the USD Export Options dialog, click Export.



3. Set Up Control Rig in the USD Stage

Now that you have a USD file for your animation, you can open it using the USD Stage editor and set it up with a Control Rig.

Click Window > Virtual Production > USD Stage to open the USD Stage editor.



In the USD Stage window, click File > Open, then select the .usda file for your animation and click Open in the open file dialog.



Click to enlarge image.

The model appears at the world's origin.

In the USD Stage window, right-click the root of the skeleton, then click Set Up Control Rig.



The Integrations panel appears to the right of the Stage hierarchy. Set the Control Rig asset to your skeletal mesh's Control Rig.



If you do not see the Sequencer window, click the USD Stage Actor in your world's Hierarchy, then double-click the Level Sequence in the Details panel.



Click the newly created Control Rig track in the Sequencer track list.

In this example, the Control Rig is called CR_Mannequin_Body.



Click to enlarge image.

Result

The controls for the rig appear on the mesh in the world. You can now use Sequencer and the Control Rig to edit the existing animation or create new ones from scratch. Any time the system detects a change, it writes it out to the USD Stage, which can then be saved to the file on disk.

Configuration

Setting up a SkelRoot prim for Control Rig will provide it with some attributes that can be configured as the following options on the USD Stage integrations panel.

Forward Kinematic Control Rig

The Use FKControlRig setting disables your selected Control Rig asset and instead uses a default forward kinematic rig that has one control for each bone. You can use this for skeletal meshes you do not already have a Control Rig for.

Reduce Keyframes

To reduce the number of auto-generated keyframes, enable the Control Rig key reduction setting in the Integrations panel. This removes keyframes similar to previous keyframes, relying on the system to tween the animation between the keyframes that remain. You can use the Control Rig key reduction tolerance setting to change the keyframe reduction sensitivity. The higher you make this value, the more aggressively it will reduce keyframes.



Click to enlarge image.

With the LiDAR Point Cloud plugin users can easily import, visualize, and edit point clouds saved in the most common file types. Professionals such as design visualization specialists, manufacturers, set designers, and builders who need to aggregate 3D models with laser-scanned data are able to see an entire project at once, from scanned data to 3D models.

See the pages below to learn how to use and become proficient with the LiDAR Point Cloud plugin.



Use the LiDAR Point Cloud plugin to import, visualize, and edit point clouds in Unreal Engine.



Guide to enabling and using the LiDAR Point Cloud plugin.



Enable Eye Dome lighting to accentuate a point cloud's edges and enhance its depth.



Reference for LiDAR Point Cloud plugin settings and other options

Supported Point Cloud File Formats

Importing and Exporting Point Clouds

Performance

On-Demand Streaming

Clipping Volumes

Changing Data at Runtime

With the LiDAR Point Cloud plugin, you can import, visualize, and edit point clouds in Unreal Engine. The plugin also supports a variety of coloration and shading techniques. Because of its multiple optimizations and dynamic LOD (Level of Detail) scaling, you can work with large datasets without any significant loss of performance, even at runtime.

Supported Point Cloud File Formats

A point cloud is a set of data points where each point is defined by its XYZ coordinates and, optionally, its color. Unreal Engine supports the following point cloud file formats:

Extension

Description

*.xyz, *.pts, *.txt

General types of ASCII point cloud file formats that can contain either:

Point coordinates (X Y Z for each point, expressed in meters)

Point coordinates plus colors, (X Y Z R G B for each point).

Notation can be float (like 0.00892855) or scientific (like 8.92855E-03).

*.las, *.laz

LAS is a public file format for the interchange of three-dimensional point cloud data between users. Although developed primarily for the exchange of LiDAR point cloud data, this format supports the exchange of any three-dimensional X, Y, Z tuplet. This binary file format is an alternative to proprietary systems, as well as to generic ASCII file interchange systems, and is widely used.

LAZ files are compressed LAS files. They are much smaller, but their import is also proportionally slower.

Unreal Engine supports 8-bit, 12-bit, and 16-bit LAS / LAZ files.

*.e57

E57 is a compact, open-source file format that stores and exchanges 3D imaging data such as point clouds, images, and metadata.

Importing and Exporting Point Clouds

To import a point cloud asset, you can use either of these methods:

Drag a point cloud, saved in a supported file format, to your Content Browser.

In the Content Browser, click Add/Import, then navigate to and select the desired file.

On import, meters are converted to Unreal Units (UU), where 1 UU = 1 cm. To use a custom import scale, open the Project Settings for the LiDAR Point Cloud plugin, then change the Import Scale value.

You can export a point cloud asset to ASCII or LAS using the existing Unreal Export tool. In the Content Browser, right-click the asset, then select Asset Actions > Export.

On export, Unreal Units are converted back to meters (multiplying the value by 0.01). To use a custom export scale, open the Project Settings for the LiDAR Point Cloud plugin, then change the Export Scale value.

Performance

Performance is primarily determined by the global point budget, which sets the maximum number of points that can be displayed at one time. Using a shared budget as opposed to a per-component budget allows for efficient rendering of many assets at the same time, as the system will select the most optimal points from all of the visible components. A higher point budget means higher quality with a higher performance cost. The global point budget saves VRAM and improves the frame rate, but does not reduce overall RAM usage.

You can set the global point budget using console variables. The higher the point budget, the denser the point cloud.

For more information, see the console variables section of the LiDAR Point Cloud Plugin Reference page.

On-Demand Streaming

When opening a point cloud, Unreal Engine only loads the necessary header information and streams the actual bulk data as needed. This results in fast asset loading and lowers total RAM consumption.

The newly imported assets will be kept in system memory and won't be able to leverage streaming functionality until they are saved. Once they are saved, the editor will release the memory for that asset.

Loading large numbers of point cloud files in the engine still requires a significant amount of RAM when parsing point cloud data and processing it as Unreal Engine assets. For example, this publicly available LiDAR data from the city of Montreal loaded in Unreal Engine has the following performance indicators:



Individual LAS files

~684 tiles for a total of 253 GB on disk

Unreal RAM usage

~3.5 GB for a budget of 1 million points

Frame Rate

120 fps, with a global budget count of 1 million points

Total Amount of Points

Average 14.3 million points per 1 km x 1 km tile * 621 files = ~8.9 billion points

Clipping Volumes

If you only want to show a section of your data, but don't want to delete the rest of it, you can use a Lidar Clipping Volume Actor. With the LIDAR Point Cloud plugin enabled, you can find this Actor in the Modes panel, under Volumes.

You can configure the properties of a clipping volume from its Details panel.

There are two Modes you can choose from:

Clip Outside hides all the point cloud data outside the clipping volume.



Clip Inside hides all the point cloud data inside the clipping volume.



You can use up to 16 clipping volumes in a Level. If you have overlapping volumes, use the Priority setting to determine which one takes priority.

Changing Data at Runtime

The LiDAR Point Cloud plugin supports inserting, removing, and modifying data at runtime, including in the packaged executable.

There are a few considerations to keep in mind when doing this:

The inserted data has to be within asset bounds. Otherwise, it will interfere with the LOD system.

Moving points doesn't relocate them to neighboring LODs, so it's recommended not to move points around too much.

When inserting many points multiple times, LOD generation can become resource-intensive.

To mitigate the issues described above, you can initialize the point cloud asset with bounds that are much larger than necessary (for example, 100,000 in each axis) and essentially disable the LOD system altogether by changing the Max Bucket Size setting in the plugin's Project Settings to a very large number, like 1,000,000,000.

1. Enabling the Plugin

2. Importing the Point Cloud

3. Building and Testing Collision

4. Editing the Point Cloud

On Your Own!

This Quick Start guide covers the following steps:

Enabling the LiDAR Point Cloud plugin.

Importing a point cloud and placing it into a scene.

Building collision for the point cloud so you can explore it in real time.

Editing the point cloud.

1. Enabling the Plugin

The LiDAR Point Cloud plugin is included with the Unreal Engine, but you must enable it for your Project before you can use it.

Open the Plugins window (main menu: Edit > Plugins).

In the Plugins window, search for the LiDAR Point Cloud Support plugin, then click the Enabled option.



Save your project and restart Unreal Engine.

2. Importing the Point Cloud

Create a new project. Use a template that includes a character controller, such as



Choose the point cloud file you want to import and drag it into the Content Browser.

Drag the point cloud from the Content Browser into the Viewport. This will automatically create an instance of a LidarPointCloudActor and assign your specified cloud to it.

3. Building and Testing Collision

Before you can move around the imported point cloud scan like any other Level, you need to build and enable collision for it.

Double-click the point cloud asset in the Content Browser to edit it. Alternatively, right-click it and select Edit. This opens the point cloud in a separate editor window.

On the main toolbar, click Collison, then select Build Collision.



Click Save to save your changes, then close this window.

Back in the main editor window, from the Place Actors panel, search for a Player Start component and drag it into your level. Place it above the ground.

Click Play to start Play in Editor mode and move around the imported scan.



4. Editing the Point Cloud

Next, you'll be making some simple edits to the point cloud. You can select and edit individual points and point groups using a range of tools.

Double-click the point cloud asset in the Content Browser to edit it. Alternatively, right-click it and select Edit. This opens the point cloud in a separate editor window.

Clicking the Center button on the main toolbar will recenter the point cloud data around its center. This is useful if the data has been defined using coordinates that are far away from the model's origin.

On the main toolbar, click Edit Mode.



You will need to fully load the point cloud into memory to edit it. When prompted to do so, click Yes. The full message is:

The asset needs to be fully loaded into memory to enable editing. This may take a while, depending on the size of the asset. Are you sure you want to continue?

After the point cloud has finished loading and Edit Mode has been enabled, you can make edits to individual points or selected point groups.

To edit points, you must select them first. Click the Selection button and, from the dropdown menu, choose one of the three available selection methods:

Box Selection

Polygonal Selection

Paint Selection



Selected points will be highlighted in orange. Press the Esc key on your keyboard to clear your selection.



You can Hide, Delete, or Extract the selected points.

After you edit the point cloud, you must rebuild its collision.

On Your Own!

Explore some of the other functionality the LiDAR Point Cloud plugin offers:

Enable Eye-Dome Lighting to enhance depth perception.

See the LiDAR Point Cloud Reference for the full range of available options.

Steps

Result

Eye-Dome Lighting (EDL) is a lighting model that accentuates the shapes of objects within a point cloud by grouping objects that are close together and shading their outlines, which enhances depth perception. EDL is implemented as a post-process Material and requires a Post Process Volume to work. It does not use any engine light sources, so it can be used with the unlit rendering method.

EDL can be used with Ambient Occlusion but this may produce an excessively dark image.

Steps

Add a Post Process Volume to your Level. From the Place Actors window, search for Post Process Volume and drag it into your Level.



Select the Post Process Volume and, in its Details panel, scroll to the Rendering Features category.

Expand Post Process Materials and click the plus (+) icon to add a new Material to the array.

From the drop down-menu of the new Material you added, select Asset reference.



Click the None dropdown. Then, under View Options, enable Engine Content and Plugin Content to be visible.



Click the None dropdown menu again. Then, select one of the two following options:

M_PP_EDL_MainPass - This will apply the EDL to every object in the Level, not just point clouds. If you only display point cloud elements, this is the recommended option.

M_PP_EDL_CustomPass - This will apply the EDL only to objects using Custom Depth Pass. This option is recommended if you want to selectively apply EDL.

Enabling Custom Depth Pass will increase the performance cost.

To apply the EDL to the whole Level, enable the Infinite Extent (Unbound) option on the post-processing volume.

Result

EDL has been applied to the Level. Notice the change to edges of objects in the level and how this enhances depth perception.





Project Settings

Octree

Performance

Collision

Automation

Import / Export

Details Panel

Appearance

Rendering

Console Variables

Project Settings

To access the LiDAR Point Cloud plugin settings, open the Project Settings window (menu: Edit > Project Settings).

The plugin settings can be accessed from the Project Settings window.

Octree

Setting

Description

Duplicate Handling

Determines how to handle duplicate points (distances less than 0.0001). You can choose from the following three options:

Ignore: Keeps any duplicates found.

Select First: Keeps the first point and skips any further duplicates.

Select Brighter: Selects the brightest of the duplicates

Max Distance for Duplicate

Maximum distance between two points for them to be considered a duplicate of the other.

Max Bucket Size

Maximum number of unallocated points to keep inside the node before they need to be converted into a full child node. Lower values will provide finer LOD control at the expense of system RAM and CPU time.

Node Grid Resolution

Virtual grid resolution to divide the node into. Lower values will provide finer LOD control at the expense of system RAM and CPU time.

Performance

Setting

Description

Multithreading Insertion Batch Size

Determines the maximum number of points to process in a single batch when using multi-threading.

Use Async Import

When enabled, the editor imports the point clouds in the background, without blocking the main thread.

Prioritize Active Viewport

When enabled, Unreal Engine allocates a larger portion of the available point budget to the viewport that currently has focus.

Cached Node Lifetime

The amount of time a node will be kept in RAM after it is no longer visible. Large values are more likely to avoid reloads from storage at the cost of increased RAM usage.

Release Asset After Saving

If enabled, Unreal Engine will automatically release system memory used by an asset once that asset has been saved and will use asset streaming instead. This is useful to avoid memory blockings when dealing with large datasets.

Release Asset After Cooking

If enabled, Unreal Engine will automatically release system memory used by an asset once that asset has been cooked and will use asset streaming instead. This is useful to avoid memory blockings when dealing with large datasets.

Use Render Data Smoothing

If enabled, render data generation is spread across multiple frames to avoid freezes. With this option enabled, you can also set the Render Data Smoothing Max Frametime option, which controls how much of the frame time should be spent on render data generation.

Use Fast Rendering

Enabling this setting can significantly improve runtime performance (by up to 300% in some cases), but it quadruples VRAM usage. This setting is enabled by default.

You should disable this option during offline video recordings with very high point budgets, where runtime performance is not as important. The increased VRAM usage can quickly saturate the GPU and eventually cause crashes.

Collision

Setting

Description

Meshing Batch Size

Determines the size of per-thread data for the meshing algorithm.

Automation

Setting

Description

Auto Center On Import

If enabled, automatically centers the cloud on import.

Preserving original coordinates may cause noticeable precision loss if the values are too large. If you experience point 'banding' effect, re-import your cloud with centering enabled.

Auto Calculate Normals on Import

If enabled, automatically calculates normals after a point cloud is imported successfully.

Auto Build Collision on Import

If enabled, automatically builds collision after a point cloud is imported successfully.

Import / Export

Setting

Description

Import Scale

On import, meters are converted to Unreal Units (UU), where 1 UU = 1 cm. To use a custom import scale, change this value.

Export Scale

On export, Unreal Units are converted back to meters. To use a custom export scale, change this value.

Details Panel

Appearance

The appearance of point clouds is defined by Actors. This relationship is similar to how Static Mesh Actors represent Static Mesh Assets.

You can change the appearance of a point cloud in your Level from the Appearance section of the Details Panel. Here, you can adjust lighting, point size, rendering, collision, and a number of other settings.

Setting

Description

Point Size

Changes the size of all points. Lower point densities (where a lower point budget is selected) can be somewhat mitigated by increasing this value and the Point Size Bias. If this option is set to 0, each point will use a fixed size of 1 px, disregarding camera distance and data density fluctuations.

Scaling Method

Determines how points in the point cloud will scale. You can choose from the following options:

Per Node: Points are scaled based on the estimated density of their containing node.

Per Node Adaptive: Similar to Per Node scaling, but density is calculated adaptively based on the current view.

Per Point: Points are scaled based on their individual calculated depth.

Fixed Screen Size: Sprites are rendered using a screen-space scaling method.

Hover your mouse over each of these options in the Details panel for more information about their specific use cases.

Gap Filling Strength

Uses a custom Material to enlarge points and render them as paraboloids to minimize visible overlap. This incurs a performance cost of around ~0.7 ms / 1 million points.

Color Source

Choose whether to use the colors embedded in the point cloud data or color the point cloud based on Position, Elevation or Classification.

If you choose Elevation, you can define which colors should be used for the highest and lowest elevation. The rest of the points will be colored using a gradient between these two values.

If you choose Classification, you can further define which colors should be used in the Classification Colors array in this section.

Point Size Bias

Affects how point scaling is performed per LOD. This is related to the r.LidarBaseLODImportance console variable.

If the asset budget is small and the number of overall components is high, point cloud assets can disappear and pop-in. To prevent this, the LOD system actively attempts to allocate at least the minimum quality LOD for assets that are far away from the camera.

Rendering

You can set a number of rendering-specific options from the Rendering section of the Details panel.

Setting

Description

Use Frustum Culling

When this option is enabled, points outside of the visible frustum will not be rendered. Disabling it can reduce data streaming delays when shooting cinematics.

Console Variables

Use these console variables to define other point cloud parameters.

Variable

Default Value

Description

r.LidarBaseLODImportance

0.1

Defines the importance of tiles in the rendering budget depending on the distance from camera. This variable controls how important it is to display at least the lowest quality tile as opposed to spending the budget on what's closest to the camera

r.LidarPointBudget

1000000

Defines the global point rendering budget of the viewports. This value represents the total number of points displayed on-screen at the same time.

r.LidarTargetFPS

59

This setting will continually tweak the point cloud budget to maintain overall fps of the specified value. If r.LidarPointBudget is set to a value greater than 0, target fps is disabled.

r.LidarIncrementalBudget

If set to true, this will automatically increase point budget to very high values as long as the viewport remains stationary. The budget will reset to the previously set value when the viewport moves.

r.LidarScreenCenterImportance

0

Defines the importance of tiles in the rendering budget based on where the camera is looking. A higher value will force lower LODs on the sides of the camera frustum.

stat lidarpointcloud

Shows the statistics of the currently rendered point cloud data.

Getting Started

Tutorials

Credits

When you create realtime 3D experiences around design data, you often need to switch the objects in your scene from one state to another. This may mean swapping objects' positions and rotations in 3D space from one place to another, showing and hiding specific objects, changing Materials, turning lights on and off, and so on.

This is a particularly common need in mechanical and industrial design applications, where some industry-standard modeling and scene design tools allow you to set up multiple variants to represent different versions of your scene. This is sometimes referred to as 150% BOM (Bill of Materials), meaning that the scene contains more than 100% of the visible options.

The classic example is a configurator that lets clients choose in advance between different possible options for an expensive vehicle such as a car, motorcycle, or aircraft, before the vehicle is actually assembled or manufactured. The simple example in the video below shows a car configurator that offers multiple options for items such as wheel trims, brake calipers, and body paint colors.

To help you handle these kinds of scenarios in your own visualization projects, Unreal Engine offers a helper called the Variant Manager. The Variant Manager makes it easier to set up multiple variants of your scene and to switch between these variants—both in the editor and at runtime. For example, in the sample application shown above, the Variant Manager is set up with each available option. A simple on-screen UMG UI calls Blueprint functions exposed by the Variant Manager to activate those options on demand.

The topics in this section describe what the Variant Manager is and how you can use it to produce similar effects.

Getting Started



What the Variant Manager is and how it works.

Tutorials



When you activate a Variant, call a function instead of changing a property value.



Use Editor Scripting to set up the Variant Manager with all your scene variants.



How to customize and use the Product Configurator template

Credits

The car model used on this page is courtesy of Allegorithmic.

The Variant Manager Panel

Setting Up Variants

Automatic Binding and Capturing

Activating Variants in the Editor

Setting Up Dependencies

About the Level Variant Sets Asset and Actor

Runtime Blueprint API

Activating a Variant

Accessing Variant Data

Credits

The Variant Manager is a specialized UI panel in the Unreal Editor that you can use to set up multiple different configurations of the Actors in your Level. Each of these configurations is referred to as a Variant. The Variant Manager helps you to:

Set up these Variants.

Organize the Variants into categories called Variant Sets.

Define what Actor properties each Variant should control, or what functions the Variants should invoke.

Activate or "switch on" different Variants in the Unreal Editor.

To use the Variant Manager, you must have the Editor > Variant Manager Plugin enabled for your Project.

If you start from a Template in either the Architecture, Engineering, and Construction or Automotive, Manufacturing, and Product Design category, this Plugin may be enabled for you by default.

To enable the Variant Manager, use Edit > Plugins to open the Plugins browser. Search for the Variant Manager plugin and check its box to enable it.



Click image for full size.

Right-click in the Content Browser and select Level Variant Set from the Miscellaneous list.



Click image for full size.

When this is complete, you will have something that looks like this:



Click image for full size.

Click the + Variant Set button and name the new set:



Click image for full size.

Once the Variant Set is created, click the Add (+) button next to its name to create a Variant.



Click image for full size.

Right-click an Variant to rename it. Click the "Set from Viewport" button to show it from the Viewport



Click image for full size.

The Variant Manager Panel

The Variant Manager UI is an editor for a specialized type of Asset called a Level Variant Sets Asset. Every time you double-click a Level Variant Sets Asset, the Variant Manager panel opens up for you to set up and work with the Variants managed by that Asset.



Click image for full size.

The UI of the Variant Manager is divided into four columns.

Variants panel: The panel on the left lists all the Variants and Variant Sets being managed by this Level Variant Sets Asset. For example, the image above shows three Variant Sets: Paint, Logo Paint, and Rims. Those Variant Sets contain several Variants: visible in the image are Variants for Blue, Wild Cherry, and Naranja paint colors.

Actors panel: Whenever you have a Variant selected in the leftmost panel, the second panel (Actors) lists all of the Actors that are bound to that Variant. In the image above, the Paint > Blue Variant is selected, so the Actors list includes the Static Mesh Actors for all the painted parts of the motorcycle body.

When you create a binding between an Actor and a Variant, you create a link between them. Activating the Variant causes the bound Actor to respond in a certain way: either by changing the value of a data property, or by calling a function.

Properties panel: When you select one or more bound Actors in the second column, the third panel (Properties) shows you what properties of those Actors are captured in this Variant. In the image above, the Variant captures the Material[1] property; this material determines the visible paint color of the surface.

To capture a property of an Actor means to store a desired value for that property in the Variant.

Values panel: The rightmost panel (Values) shows the value saved in the Variant for each property visible in the Properties panel. In this case, when the Blue Variant switches on, the Variant Manager sets the Material[1] property of its bound Actors to a blue car paint Material.

Dependencies panel: Finally, the bottom panel (Dependencies) shows any constraints that are part of the selected Variant. A Dependency is a constraint that switches on other Variants when the current Variant is enabled. The current Variant does not have any dependencies but does show that it is a part of the Default Variant in the Packages Variant Set.

Setting Up Variants

The overall workflow for setting up scene variants typically follows the columns described above from left to right.

Decide on what Variants you'll need in your scene, and how to categorize your Variants into Variant Sets. Based on those decisions, you use the controls offered by the left-hand column to set up the Variant Manager with these same Variant Sets and Variants. By right-clicking and selecting options from the context menu, you can:

Edit existing Variants.

Add new Variants and Variant Sets.

Move Variants from one set to another.

Assign thumbnail images to Variants and Variant Sets. These thumbnail images can later be used as part of a user interface like the one seen in the Product Configurator template.

Add any necessary Dependencies.

For each of the Variants you created above, you can bind one or more Actors. Bind a new Actor to a Variant by clicking the Add (+) button in the header of the Actors column. You can also drag Actors from the World Outliner panel on to the list of bound Actors, or on to the Variant in the left-hand column. It is also possible to bind and unbind Actors by right-clicking the list in the Actors panel and using the context menu.

For each bound Actor, choose which properties you want the Variant Manager to change.

Every time you bind a new Actor, the Variant Manager automatically opens a window that invites you to choose which properties you want to capture. For example:



Click image for full size.

You can capture any property that is exposed to Blueprints. If the Actor you've bound is a Blueprint Actor, this includes any Variables that you've created in the class and that are marked as Instance Editable.

Capture additional properties at any time by clicking the Add (+) button in the header of the Properties panel, or right-clicking a bound Actor at any time to capture additional properties. Right-click a captured property to remove it from the list.



Click image for full size.

You can also set up the Variant Manager to call functions exposed by the bound Actor when the Variant activates. For details on this, see Calling Functions on Variant Activation.

For each captured property, you set the value that you want the Variant Manager to apply when the Variant activates. You can set captured values at any time by editing them directly in the Values column of the Variant Manager. Alternatively, you can modify the property values elsewhere in the Unreal Editor UI, then update the saved value to match the property's current value by doing any of the following:

Click the Record the current value icon next to the property value.



Click image for full size.

Right-click the property or its captured value and choose Record Current Value from the context menu.



Click image for full size.

When you update a captured value directly in the Values panel for a Variant that you have already switched on, you won't see your change reflected immediately in the Level Viewport. To see the effect of your change, switch on the Variant again. Or, right-click either the property or its captured value, then choose Apply recorded value from the context menu.



Click image for full size.

If you use Datasmith to import scenes from third-party applications that support setting up variants, including Autodesk VRED and 3DExcite Deltagen, and you have variants already set up in your source scenes, Datasmith will automatically set up a Level Variant Sets Asset and Actor for you. All you'll have to do is create the Blueprint logic or UMG widgets in your Project that can switch your variants on in response to user interaction.

Automatic Binding and Capturing

As an alternative to binding Actor properties one-by-one using the approach outlined in the previous section, you can bind Actors and capture their properties automatically as you modify them in the Level.

To toggle automatic binding and capturing, use the toggle button at the top of the Variants column on the left of the Variant Manager UI.





Auto-capture deactivated

Auto-capture activated

While automatic capturing is active, the Variant Manager listens for every change that you make to the Actors in your Level. Whenever you change a property that the Variant Manager can capture, it automatically captures the new value you have set for the modified property and saves it in the Variant that you currently have selected. If the Actor you modified was not already bound to the selected Variant, it is bound automatically.

Automatic binding and capturing can make it faster and easier to set up your Variants. Typically, you use it as follows:

Click the Variant you want to modify in the left-hand Variants column to select it. Or, double-click the Variant if you want to switch on its current state before you make changes.

Toggle the auto-capture button to its activated state.

Modify the Actors that you want to bind to the Variant you have selected. As you work, you should see the Variant Manager automatically bind every Actor you modify and capture every new property value you set.

When your Variant is set up the way you want it, you can either:

Continue capturing properties for another Variant by clicking or double-clicking the new Variant in the left-hand Variants column.

Stop capturing changes by toggling the auto-capture button back to its disabled state.

Be aware when you activate auto-capture mode. If you forget that you have it activated while you work in your Level, you may accidentally record undesired changes to the currently selected Variant.

Activating Variants in the Editor

Whenever you activate a Variant, either at runtime or in the Unreal Editor, the Variant Manager iterates through the list of Actors that you've bound to that Variant. For each of these Actors, it sets all captured properties to the values stored in the Variant. It also calls any functions that you've configured the bound Actor to call.

You can activate Variants in the Unreal Editor when you have the Variant Manager UI open. Use either of the following methods:

Double-click the Variant you want to activate in the leftmost column.

Right-click the Variant you want to activate in the leftmost column, and choose Switch on from the context menu.



Click image for full size.

The Variant Manager uses a small status indicator to show which Variants are switched on: that is, ones whose captured properties all match the values that are currently applied to the bound Actors in the Level. This happens when you switch on the Variant, and it also can happen if you set the same property values manually in the Level.





A deactivated Variant

An activated Variant

For details on activating Variants at runtime, see Runtime Blueprint API below.

Setting Up Dependencies

Once the Variants and Variant sets are established, you can create optional Dependencies for any Variant. A Dependency is a constraint that is added to a Variant that switches on other dependent Variants when it is enabled, such as creating a Default variant that will set other Variants back to their initial setting:



Click image for full size.

Here is how to setup new dependencies for your Variants:



Click image for full size.

Select one of your Variants and click the Add (+) button in the Dependencies panel to create a new dependency.

A dependency needs to know the Variant Set and the Variant that you want to enable when your current selection switches on. Click the drop-down box under Variant Set and select the Variant Set that contains the Variant you want to add to the dependency.

Then select the Variant to enable from the Variant drop-down.

The Variant chosen for a dependency does not need to contain any bound Actors



Click image for full size.

Here we can see Dependencies used to create a variety of package setting options. Notice that the Variant shown contains only Dependencies and does not have any Actor bindings.

About the Level Variant Sets Asset and Actor

Each Level Variant Sets Asset stores information about Actors that live in a specific Level. While you have that Level open in the Unreal Editor, you can use the Variant Manager UI to activate different Variants. As you do, the bound Actors in the Unreal Editor immediately update the values of their captured properties.

If you only need to activate Variants in the Unreal Editor, but not at runtime, then the Level Variant Sets Asset is the only thing you need to set up.

However, Variants are often most useful at runtime in a packaged Project. For example, suppose you have a 150% BOM model of a car in an Unreal Engine Level, with multiple variants that represent different trims. It may be useful to be able to switch between these different trim options in the editor. But if your goal is to create a car configurator that lets end users choose the trim they want, you'll also need to make your Variants controllable by a viewer at runtime.

To do this, you'll need to drag your Level Variant Sets Asset into your Level. This creates a new Level Variant Sets Actor in the Level that links to the Asset you used to create it. This special kind of Actor offers a Blueprint interface that you can use to interact with your Variants from Blueprint gameplay logic and UMG interfaces that you create in your Project. For more information on using the Variant Manager to create a configurator, please see the Product Configurator template documentation.

Each Level Variants Sets Asset works only with the Actors in a single Level. If you open a different Level, the Variant Manager UI will no longer affect the objects in that new Level.

If you need to control Actors in multiple different Levels, you'll need to create a separate Level Variant Sets Asset for each Level, and set each one up separately. Or, if you want them to control the same Actors in the same ways, you can put all the Actors that you need the Level Variants Sets Asset to control into a single sublevel, and add that sublevel to both of the Levels that need those Variants.

Runtime Blueprint API

The Level Variant Sets Actor offers a Blueprint API that you can use to interact with your Variants and Variant Sets at runtime. This API supports two main uses:

Switching on Variants that you identify by name or by index. See Activating a Variant below.

Querying data about the Variant Sets and Variants that you have configured, including their display names. See Accessing Variant Data below.

Activating a Variant

You can switch on any Variant in your Level Variant Set if you know either the name or the index value of both the Variant and its parent Variant Set.

The simplest way to switch on a Variant is to drag right from a reference to the Level Variant Set Actor, find the Level Variant Sets category, and choose either Switch on Variant by Index or Switch on Variant by Name.



Click image for full size.

Accessing Variant Data

You can access the structure of all Variant Sets and Variants that you've configured in the Variant Manager.

Drag right from a reference to the Level Variant Set Actor, find the Level Variant Sets category, and choose Get Level Variant Sets.



Click image for full size.

Once you have a reference to the Level Variant Sets Asset, drag right from the Return Value port and find the Level Variant Sets category to access the Variant Sets set up in the Asset.



Click image for full size.

Use the Get Variant Set or Get Variant Set By Name node to retrieve a Variant Set from its index or its name. Get Num Variant Sets returns the total number of Variant Sets configured in the Level Variant Sets Asset. You can combine this with the Get Variant Set node to loop through all the Variant Sets:



Click image for full size.

Once you have retrieved a reference to a Variant Set, drag right from its Return Value port and find the Variant Set category to work with the data the Variant Set contains.



Click image for full size.

You can use the Get Display Text node to retrieve the name you set for the Variant Set in the Variant Manager UI.

You can also access the Variants within the Variant Set using a set of nodes similar to the ones you used to access the Variant Sets themselves. Use the Get Variant or Get Variant By Name node to retrieve a Variant from its index or its name. Get Num Variants returns the total number of Variants configured in this Variant Set. You can combine this with the Get Variant node to loop through all the Variants in the Variant Set, just as shown above for looping through Variant Sets.



Click image for full size.

Once you have retrieved a reference to a Variant, drag right from its Return Value port and find the Variant category to get its display name, switch it on, and access its bound Actors.



Click image for full size.

This sample Blueprint graph uses the approach outlined above to iterate through all configured Variant Sets and Variants. It prints the name of each Variant Set and each Variant in order to the screen and the output log.



Click image for full size.

Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_0" VariableReference=(MemberName="LevelVariantSetsActor",MemberGuid=52B0394D42785F96B24A3E91547CD032,bSelfContext=True) NodePosX=2640 NodePosY=784 NodeGuid=DE7352A9462BF2FBD4AA3DBB3DD49825 CustomProperties Pin (PinId=38E93D804BC6884C376E8C8EF6CDCCD8,PinName="LevelVariantSetsActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSetsActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 16FD036B4D8BD417BE73C99219BB3DB4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6770B63E452E86A53F725895DEB10A06,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSetsActor"',MemberName="GetLevelVariantSets") NodePosX=2864 NodePosY=656 NodeGuid=89904E6A4FD6624B0C6B4995886074BA CustomProperties Pin (PinId=3A822FE0415F805F99F1349F674B317C,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CustomEvent_0 6F16F9EA4EF5E12CE32B789686874BFB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3CC60D03446A92F2DD7080A9F308D9F4,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_3 D582D24F4CE75F18600111BAD7CE0D78,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=16FD036B4D8BD417BE73C99219BB3DB4,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nLevel Variant Sets Actor Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSetsActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_0 38E93D804BC6884C376E8C8EF6CDCCD8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9425C45E427D368E8635478E1104C2DE,PinName="bLoad",PinToolTip="Load\nBoolean",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=17D4CE2E418F6744B7ECB9B27E033199,PinName="ReturnValue",PinToolTip="Return Value\nLevel Variant Sets Object Reference\n\nReturns the LevelVariantSets asset, optionally loading it if necessary",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_2 2CB39E47498E2AD7551583816B79456A,K2Node_Knot_15 ED53E47D4CD1636590A17C92C4BF0AC0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_2" bIsPureFunc=True FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',MemberName="GetNumVariantSets") NodePosX=3200 NodePosY=736 NodeGuid=E22C0C9A47054A830DBD3A8934E07A4C CustomProperties Pin (PinId=2CB39E47498E2AD7551583816B79456A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nLevel Variant Sets Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 17D4CE2E418F6744B7ECB9B27E033199,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=277F3DE842DEC3C077D913BAAC24B01D,PinName="ReturnValue",PinToolTip="Return Value\nInteger\n\nGet Num Variant Sets",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_MacroInstance_3 DC8BF48F473B723ACBB451BA533F8248,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_1" MacroGraphReference=(MacroGraph=/Script/Engine.EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForLoop"',GraphBlueprint=/Script/Engine.Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=55C904AF4B45FE1761FB55A8DB9FB801) NodePosX=3632 NodePosY=672 NodeGuid=858645474627C41BC5B66CB904665607 CustomProperties Pin (PinId=C38EB482419D112B28A9F3973A51DA52,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_3 25B8310C4ED31A2624AA9D82D87A73EE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7FD5FF7545BC67FF7930F3BD47AAB499,PinName="FirstIndex",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C893A965405D02431F3A00BFE4E06626,PinName="LastIndex",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_3 49DA97B14BF5113CDE00659008AA3EAC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D12CB5F549DF427A48A18F9FF6CB3EE6,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_20 BECF36064B44199648BEF28D740A5F3F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=25788B6F484A13D9D61C458AF4165D0B,PinName="Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_3 A2E0D7AF4E41AB08B26617B905CFF938,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=14DD39CA4C033240571D54A440BB9C7A,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_3" bIsPureFunc=True FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',MemberName="GetVariantSet") NodePosX=3968 NodePosY=736 NodeGuid=1267387F4D192827781345B944956065 CustomProperties Pin (PinId=873AF7494FC9FA8D908A439FCB8C81A0,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nLevel Variant Sets Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_14 4BA4F36B49D3AA6C8914B2A327AF7DA8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A2E0D7AF4E41AB08B26617B905CFF938,PinName="VariantSetIndex",PinToolTip="Variant Set Index\nInteger",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_MacroInstance_1 25788B6F484A13D9D61C458AF4165D0B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9F9204A044E79A0ED7A7EA99B042C6BE,PinName="ReturnValue",PinToolTip="Return Value\nVariant Set Object Reference\n\nGet Variant Set",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_20 B5E040194D8DB0EF72614EA9E0F2A7DE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_2" MacroGraphReference=(MacroGraph=/Script/Engine.EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForLoop"',GraphBlueprint=/Script/Engine.Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=55C904AF4B45FE1761FB55A8DB9FB801) NodePosX=3712 NodePosY=928 NodeGuid=08EB1B0347E83C8829364797F5A98E8C CustomProperties Pin (PinId=69A7B63A4A2F245F358466BFF0C5C62B,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_4 1CDE3A2B4F525CFDE46C17AF0E93885B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=702CAF424207E744860835ABC4D2D4E6,PinName="FirstIndex",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=527FCDF1402C3DAE91555482456402B8,PinName="LastIndex",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_4 CD82FFA548A835703BC7F2A4301DA1CA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7B72C5CE4B9AFAB52DF0F2B97DAE194E,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_14 ECD4A8DE4EC99B68A7686880ACD90A06,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=560A7A734C4DF5E390A46298DDEF3C4E,PinName="Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_7 8463CC674B32C1A1998D84A1BE599697,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C2EB307143C0D3C15590AEA552BD6F4B,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_6" bIsPureFunc=True bIsConstFunc=True FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',MemberName="GetNumVariants") NodePosX=2960 NodePosY=1088 ErrorType=1 NodeGuid=0E9BF5C244FB07CEDF4E02ABDA8B6A8E CustomProperties Pin (PinId=B318BF56415D7FA1ED9D1FA247F397A6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Set Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_3 E6B14C8E4154652D0140BA8F1B6B99B8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4167CDE7459ACD33CFAF8884D93B9214,PinName="ReturnValue",PinToolTip="Return Value\nInteger\n\nGet Num Variants",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_Knot_34 9BC3C27D4177B4A96C96B983DE0FEDD5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_7" bIsPureFunc=True FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',MemberName="GetVariant") NodePosX=4016 NodePosY=1008 NodeGuid=DEFB028549610070F6BCF28757E93E86 CustomProperties Pin (PinId=D50494904C99D49E75D340BAACB29BC5,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Set Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_4 F63EA24F41FA78A7B0CBBCA5054D0DDB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8463CC674B32C1A1998D84A1BE599697,PinName="VariantIndex",PinToolTip="Variant Index\nInteger",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0",AutogeneratedDefaultValue="0",LinkedTo=(K2Node_MacroInstance_2 560A7A734C4DF5E390A46298DDEF3C4E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A9586D54408EEDF821606D8ABF2CB26B,PinName="ReturnValue",PinToolTip="Return Value\nVariant Object Reference\n\nGet Variant",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_13 AD3CBB22472B41E7D8064E9224F2B2E7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_3" NodePosX=2816 NodePosY=1168 NodeGuid=5AB8BE07479451DC7367A9A62F9C9C3D CustomProperties Pin (PinId=E20E6B2E4D1D966BE18EE2A6F439AB98,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CustomEvent_3 B8A329D248B20FA675D74FB7E628F37F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E6B14C8E4154652D0140BA8F1B6B99B8,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_4 1B859C674DA07A63EB0B8BBE67EC3A69,K2Node_CallFunction_6 B318BF56415D7FA1ED9D1FA247F397A6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_4" NodePosX=3760 NodePosY=1168 NodeGuid=567A212B462434C24299319AB1D23632 CustomProperties Pin (PinId=1B859C674DA07A63EB0B8BBE67EC3A69,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_3 E6B14C8E4154652D0140BA8F1B6B99B8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F63EA24F41FA78A7B0CBBCA5054D0DDB,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_7 D50494904C99D49E75D340BAACB29BC5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CustomEvent Name="K2Node_CustomEvent_0" bCallInEditor=True CustomFunctionName="PrintVariantData" NodePosX=2560 NodePosY=656 NodeGuid=E4B9CF4D4A331C3E21CC4B940B309947 CustomProperties Pin (PinId=60DE56D44762EAE16B6F29A6F5ADB3F8,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',MemberName="PrintVariantData",MemberGuid=E4B9CF4D4A331C3E21CC4B940B309947),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6F16F9EA4EF5E12CE32B789686874BFB,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 3A822FE0415F805F99F1349F674B317C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_10" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/Engine.KismetSystemLibrary"',MemberName="PrintString") NodePosX=3248 NodePosY=928 AdvancedPinDisplay=Hidden EnabledState=DevelopmentOnly NodeGuid=BA79909C4E0E6F1EDB9E5F86055171FE CustomProperties Pin (PinId=9873C79A482C77F657151BA4A952F625,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_33 DCA45A574F4B7F44100C2B8F597C7F19,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D18950CA442215FF13CF41972835E682,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_4 3B7EF99E4E6DDC306E2F56B2D6592CB9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0075A17B4486F24650A6BB884F1310E6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.KismetSystemLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=057CB6374768D9DFBD0F86B6CD2133C9,PinName="WorldContextObject",PinToolTip="World Context Object\nObject Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0606096342E9BC49041E808F892937BF,PinName="InString",PinToolTip="In String\nString\n\nThe string to log out",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",LinkedTo=(K2Node_CallFunction_12 687D57F24A44273A5BFA018BB208C946,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=278C7644473AEDAC96E8778C738775F7,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBoolean\n\nWhether or not to print the output to the screen",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=2076A1124E4EFF85673B94A52E42AFCB,PinName="bPrintToLog",PinToolTip="Print to Log\nBoolean\n\nWhether or not to print the output to the log",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=20B7B2BC432850032D7F83B849867BDC,PinName="TextColor",PinToolTip="Text Color\nLinear Color Structure\n\nThe color of the text to display",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.ScriptStruct'"/Script/CoreUObject.LinearColor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=1A20AB1741FB8D708C705C8AC5028E14,PinName="Duration",PinToolTip="Duration\nFloat (single-precision)\n\nThe display duration (if Print to Screen is True). Using negative number will result in loading the duration time from the config.",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=1ABD9909498F401007FA98B2F2C562F0,PinName="Key",PinToolTip="Key\nName\n\nIf a non-empty key is provided, the message will replace any existing on-screen messages with the same key.",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_11" bIsPureFunc=True bIsConstFunc=True FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',MemberName="GetDisplayText") NodePosX=2832 NodePosY=992 ErrorType=1 NodeGuid=618E0379414278DF875E3EA58D1BD4C3 CustomProperties Pin (PinId=67D80E644D54918A5D75A8AA8E051FF8,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Set Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CustomEvent_3 B8A329D248B20FA675D74FB7E628F37F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=69C2A2EA43F265217CBF3E8F26B4C5A3,PinName="ReturnValue",PinToolTip="Return Value\nText\n\nGet Display Text",Direction="EGPD_Output",PinType.PinCategory="text",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_12 1F2A620B4861374FD0E9398B58739224,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_12" bIsPureFunc=True FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/Engine.KismetTextLibrary"',MemberName="Conv_TextToString") NodePosX=3072 NodePosY=1024 bCommentBubbleVisible=True NodeComment="Convert to String" NodeGuid=A8D4E1BF460F8446904548B10C0F9978 CustomProperties Pin (PinId=3FC9A53E444A20093404388B5DABC029,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Text Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.KismetTextLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetTextLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1F2A620B4861374FD0E9398B58739224,PinName="InText",PinToolTip="In Text\nText (by ref)",PinType.PinCategory="text",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_11 69C2A2EA43F265217CBF3E8F26B4C5A3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=687D57F24A44273A5BFA018BB208C946,PinName="ReturnValue",PinToolTip="Return Value\nString\n\nConverts localizable text to the string",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_10 0606096342E9BC49041E808F892937BF,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_13" bIsPureFunc=True bIsConstFunc=True FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',MemberName="GetDisplayText") NodePosX=4304 NodePosY=1008 NodeGuid=D03366444211A8E5E29291B8CDD8B3A8 CustomProperties Pin (PinId=AD3CBB22472B41E7D8064E9224F2B2E7,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_7 A9586D54408EEDF821606D8ABF2CB26B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1869AA6844C133EDA38FEBA3E70104F5,PinName="ReturnValue",PinToolTip="Return Value\nText\n\nGet Display Text",Direction="EGPD_Output",PinType.PinCategory="text",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_15 899BB4664F88FB51C43D72AA556B57A7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_14" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/Engine.KismetSystemLibrary"',MemberName="PrintString") NodePosX=4720 NodePosY=928 AdvancedPinDisplay=Hidden EnabledState=DevelopmentOnly NodeGuid=8E066FC84C6A224FA6CAB3A88650F92B CustomProperties Pin (PinId=ECD4A8DE4EC99B68A7686880ACD90A06,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_2 7B72C5CE4B9AFAB52DF0F2B97DAE194E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C2C1CBE8449029DD805C4881D92584DC,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0F8B46564F4333D75106F98ACE1316E6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.KismetSystemLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7DF3CDA343014F98B5050F98586F164B,PinName="WorldContextObject",PinToolTip="World Context Object\nObject Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8439BD144F1686B35E38C9B7C6CBD4E4,PinName="InString",PinToolTip="In String\nString\n\nThe string to log out",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",LinkedTo=(K2Node_CallFunction_15 DB63FBBC42A0CEDA8A5E14A23D4C29EC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3D079A51442708028798CCA0AA4A0B62,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBoolean\n\nWhether or not to print the output to the screen",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=848E7FE941882A5EEDEA8384793FFE77,PinName="bPrintToLog",PinToolTip="Print to Log\nBoolean\n\nWhether or not to print the output to the log",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=03B93FEB492C778FF4DFEE91F190E59B,PinName="TextColor",PinToolTip="Text Color\nLinear Color Structure\n\nThe color of the text to display",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.ScriptStruct'"/Script/CoreUObject.LinearColor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=70C0EB1D44F56791FB0836978FE6CF62,PinName="Duration",PinToolTip="Duration\nFloat (single-precision)\n\nThe display duration (if Print to Screen is True). Using negative number will result in loading the duration time from the config.",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=50F73CC34F13AB12774B6DA0E8B6F3FF,PinName="Key",PinToolTip="Key\nName\n\nIf a non-empty key is provided, the message will replace any existing on-screen messages with the same key.",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_15" bIsPureFunc=True FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/Engine.KismetTextLibrary"',MemberName="Conv_TextToString") NodePosX=4544 NodePosY=1024 bCommentBubbleVisible=True NodeComment="Convert to String" NodeGuid=263B9114498504F90CAE4FA639BA5109 CustomProperties Pin (PinId=193319D141838CD3B6614BB8BA5217D6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Text Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.KismetTextLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetTextLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=899BB4664F88FB51C43D72AA556B57A7,PinName="InText",PinToolTip="In Text\nText (by ref)",PinType.PinCategory="text",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_13 1869AA6844C133EDA38FEBA3E70104F5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DB63FBBC42A0CEDA8A5E14A23D4C29EC,PinName="ReturnValue",PinToolTip="Return Value\nString\n\nConverts localizable text to the string",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_14 8439BD144F1686B35E38C9B7C6CBD4E4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_3" MacroGraphReference=(MacroGraph=/Script/Engine.EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:DecrementInt"',GraphBlueprint=/Script/Engine.Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=313497C74768FD0B41B3D18DA5D1DAA4) NodePosX=3456 NodePosY=688 bCommentBubbleVisible=True NodeComment="Decrement" NodeGuid=A9B377904F3E462197B8288787431154 CustomProperties Pin (PinId=D582D24F4CE75F18600111BAD7CE0D78,PinName=" ",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 3CC60D03446A92F2DD7080A9F308D9F4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DC8BF48F473B723ACBB451BA533F8248,PinName="Value",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_2 277F3DE842DEC3C077D913BAAC24B01D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=25B8310C4ED31A2624AA9D82D87A73EE,PinName=" ",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_1 C38EB482419D112B28A9F3973A51DA52,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=49DA97B14BF5113CDE00659008AA3EAC,PinName="Result",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_1 C893A965405D02431F3A00BFE4E06626,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_4" MacroGraphReference=(MacroGraph=/Script/Engine.EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:DecrementInt"',GraphBlueprint=/Script/Engine.Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=313497C74768FD0B41B3D18DA5D1DAA4) NodePosX=3536 NodePosY=944 bCommentBubbleVisible=True NodeComment="Decrement" NodeGuid=4E0F8DA8465337B5D623A3AD8457BA71 CustomProperties Pin (PinId=3B7EF99E4E6DDC306E2F56B2D6592CB9,PinName=" ",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_10 D18950CA442215FF13CF41972835E682,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CBBA11E74E64812EC4A92C90E0537ADF,PinName="Value",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_34 C58117634CC7CD6BCB695C9D9982FD99,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1CDE3A2B4F525CFDE46C17AF0E93885B,PinName=" ",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_2 69A7B63A4A2F245F358466BFF0C5C62B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CD82FFA548A835703BC7F2A4301DA1CA,PinName="Result",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_2 527FCDF1402C3DAE91555482456402B8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CustomEvent Name="K2Node_CustomEvent_3" CustomFunctionName="HandleVariantSet" NodePosX=2560 NodePosY=960 NodeGuid=68D1D21F408E8F420A1BE2851EBB38F8 CustomProperties Pin (PinId=39CBEBB44651D716398CC18E2D79E486,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',MemberName="HandleVariantSet",MemberGuid=C5E4C89A407CD2159773AA97773102CB),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=703ED296435C307C18FAE39B50C3A547,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_33 A5EF4A8D4A8FE7DE560C9A9BA18B0933,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B8A329D248B20FA675D74FB7E628F37F,PinName="VariantSet",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_3 E20E6B2E4D1D966BE18EE2A6F439AB98,K2Node_CallFunction_11 67D80E644D54918A5D75A8AA8E051FF8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="VariantSet",PinType=(PinCategory="object",PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"'),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_14" NodePosX=3760 NodePosY=832 NodeGuid=B71862684FEAC006F0B80E908E7C083B CustomProperties Pin (PinId=3823978945DCCB2CF47103B5393BEF22,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_15 14DC580A4988CA9FAC463299DD0A863F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4BA4F36B49D3AA6C8914B2A327AF7DA8,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_3 873AF7494FC9FA8D908A439FCB8C81A0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_15" NodePosX=3168 NodePosY=832 NodeGuid=8D89883640E58DEE92020B8F434EA6E2 CustomProperties Pin (PinId=ED53E47D4CD1636590A17C92C4BF0AC0,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 17D4CE2E418F6744B7ECB9B27E033199,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=14DC580A4988CA9FAC463299DD0A863F,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_14 3823978945DCCB2CF47103B5393BEF22,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_20" FunctionReference=(MemberName="HandleVariantSet",MemberGuid=C5E4C89A407CD2159773AA97773102CB,bSelfContext=True) NodePosX=4320 NodePosY=656 NodeGuid=215E144A41F4BC47D6AE249458270571 CustomProperties Pin (PinId=BECF36064B44199648BEF28D740A5F3F,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_1 D12CB5F549DF427A48A18F9FF6CB3EE6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=487B5C8F425B0575992F6BAC6D4F91B3,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=37E5DF8C4383878B16FEE1A269E431D4,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nSelf Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="self",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B5E040194D8DB0EF72614EA9E0F2A7DE,PinName="VariantSet",PinToolTip="Variant Set\nVariant Set Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_3 9F9204A044E79A0ED7A7EA99B042C6BE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_33" NodePosX=2816 NodePosY=960 NodeGuid=5D17EC084375731CE21FBE9829AAB112 CustomProperties Pin (PinId=A5EF4A8D4A8FE7DE560C9A9BA18B0933,PinName="InputPin",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CustomEvent_3 703ED296435C307C18FAE39B50C3A547,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DCA45A574F4B7F44100C2B8F597C7F19,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_10 9873C79A482C77F657151BA4A952F625,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_34" NodePosX=3408 NodePosY=1136 NodeGuid=98D06D704E1C20C2174C798DCA336460 CustomProperties Pin (PinId=9BC3C27D4177B4A96C96B983DE0FEDD5,PinName="InputPin",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_6 4167CDE7459ACD33CFAF8884D93B9214,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C58117634CC7CD6BCB695C9D9982FD99,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_4 CBBA11E74E64812EC4A92C90E0537ADF,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

You could use the same kind of approach to iterate through your Variant Sets and Variants to do something different. With a little imagination and general UMG knowledge, you can use this information to write a UI system that automatically creates UI widgets that reflect the Variant Sets and Variants you have configured in your Level Variant Sets Asset.

For background information about working in Blueprints, see Blueprint Visual Scripting. For more about creating user interfaces with UMG, see the UMG UI Designer documentation.

Credits

The vehicle model used on this page is courtesy of Allegorithmic.

Adding the Switch Actor to a Level

Selecting the Child Actor to Show

In the Unreal Editor

In Blueprint

In the Variant Manager

The Switch Actor provides a quick way to toggle the visibility of Actors or entire hierarchies of Actors in your Level.

Only one child of the Switch Actor can be visible at any time. When you choose a child Actor that you want to be visible, the Switch Actor automatically hides all other child Actors, along with all their descendants. It then makes the one child Actor you chose visible, along with all of the descendants of that selected child Actor.

This behavior is most convenient when you have mutually exclusive Level Actors or hierarchies of Actors, where only one of those Actors or hierarchies should ever be visible at any given time. For example, a car configurator might offer several different trims, each of which is represented by a different set of Static Mesh Actors that have different geometry, as shown below:



Click image for full size.

To switch the visible model of the car from one trim option to another would require showing and hiding multiple Actors. You could do this using Blueprint, the Variant Manager, or even manually in the Unreal Editor. However, changing visibility on dozens or potentially hundreds of different Actors at the same time can be cumbersome. If you use a Switch Actor as the parent for all the different trim options, you can easily switch between the different trims by setting a single option on the Switch Actor parent.

The Switch Actor is contained in the Editor > Variant Manager Content Plugin. This Plugin is typically enabled by default. However, if you don't see the Switch Actor in your Modes panel, you may need to enable this Plugin for your project.

Adding the Switch Actor to a Level

The Switch Actor is listed in the All Classes tab of the Place Actors panel. Drag it from the Place Actors panel into your Level Viewport.



Click image for full size.

Selecting the Child Actor to Show

The following sections describe the different ways you can choose which child of the Switch Actor you want to show.

In the Unreal Editor

Select the Switch Actor in your World Outliner. In the Details panel, find the Switch Actor > Selected Option setting. This dropdown lists the names of all the child Actors parented by your Switch Actor.



Click image for full size.

Select the option that you want to be visible.

In Blueprint

The Switch Actor offers a Blueprint API that you can use to work with its selected child. If you drag right from a reference to a Switch Actor in a Blueprint graph, you'll find these nodes listed under the Switch Actor category:



Click image for full size.

Node

Name

Description



Get Options

Returns an array of references to all the child Actors currently parented by this Switch Actor.



Get Selected Option

Returns the index of the child Actor that is currently shown.



Select Option

Changes the Switch Actor to select the child with the index you specify.

The array returned by Get Options is not guaranteed to be in the same order as the child Actors that you see in the World Outliner or in the Details panel for the Switch Actor. In addition, the index number that is returned by Get Selected Option and that you specify when you call Select Option both identify elements within this array.

In the Variant Manager

When you bind a Switch Actor to a Variant in the Variant Manager, capture its Selected Option property. The Values column shows a dropdown that lists the names of all the child Actors parented by your Switch Actor.



Click image for full size.

Select the option that you want to be visible when this Variant is switched on.

Steps

End Result

Whenever you bind an Actor to a Variant, the Variant Manager prompts you to choose the properties of that Actor that you want to change when the current Variant is switched on. However, in addition to or instead of changing a bound Actor's property values, you can also specify one or more functions that you want the Variant Manager to invoke on that Actor.

You can set up the Variant Manager to call any function that is already exposed by the Actor you've bound. You can also create your own new Blueprint function from scratch that accepts the bound Actor as an input. The steps on this page show how to do both.

Steps

To call a Blueprint function when a Variant is activated:

Double-click your Level Variant Sets Asset in the Content Browser to open it in the Variant Manager UI.



Click image for full size.

Select the Variant you want to set up in the left-hand column of the Variant Manager UI.



Click image for full size.

If you haven't already bound the Actor whose function you want to call to the Variant, drag it from the World Outliner panel into the Actors column of the Variant Manager.



Click image for full size.

When the Variant Manager prompts you to select which properties you want to capture, you can leave all the properties unchecked. Click Select to continue.

Right-click your Actor in the list of bound Actors on the Variant, and select Add function caller from the context menu.



Click image for full size.

Find the new Function caller item at the bottom of the Properties column, and use the dropdown list in the Values column to choose the function you want to call.



Click image for full size.

Choose Create New Function to create a totally new Blueprint function, or choose an existing function from the Create Quick Binding list if your Actor is already set up with the function you want to call.

The Variant Manager opens a special Blueprint class for you to edit, called the LevelVariantSetDirector. This Blueprint is owned by the Level Variant Sets Asset. Its role to store all logic that you need to run in respose to your Variants being activated.

The Variant Manager automatically creates a new function for you in the LevelVariantSetDirector Blueprint. Whenever your Variant is activated, the Variant Manager automatically calls this function. If you need to further customize the Blueprint logic that gets triggered when the Variant is activated, you can do it in this graph.

If you chose to create a new function in the previous step, you get a new empty function with a default name. You can fill out this function with any Blueprint logic you need to carry out.



Click image for full size.

The Variant Manager passes your new function some information that you might find useful in creating your Blueprint graph:

Parameter

Description

Target

A reference to the bound Actor that you set up with the Function Caller in the previous step.

Level Variant Sets

A reference to the Level Variant Sets Asset that this LevelVariantSetDirector Blueprint controls. You can use this to retrieve information about all the other Variants and Variant Sets that you've configured for the same Asset.

Variant Set

A reference to the Variant Set that contains the current Variant: that is, the Variant that has just been activated.

Variant

A reference to the Variant that has just been activated: that is, the Variant that contains the bound Actor that you set up with the Function Caller.

If you chose to create a quick binding to an existing function exposed by the Actor, the Variant Manager automatically adds a call to that function and hooks it up to the new function it creates in the LevelVariantSetDirector Blueprint. If the function being called on the Actor requires any other input values, such as the New Actor Enable Collision option in the image below, you can set them up in this graph.



Click image for full size.



Click image for full size.

By default, the Variant Manager only calls your function when the Variant is activated at runtime. If you want your function to also run when the Variant is switched on in the editor, select your function node in the LevelVariantSetDirector Blueprint and enable the Call in Editor setting in the Details panel.



Click image for full size.

When you are done setting up your new function or quick binding in the LevelVariantSetDirector Blueprint, Compile and Save the Blueprint. You can then close the Blueprint Editor and the Variant Manager window.

End Result

Whenever you switch on the Variant that you set up with a function caller at runtime, the Variant Manager automatically invokes the function you defined in the LevelVariantSetDirector Blueprint.

If you've enabled the Call in Editor option for the function in the LevelVariantSetDirector Blueprint, the Variant Manager will also automatically invoke your function when you switch on that Variant in the Unreal Editor.

You can add multiple function callers to a single bound Actor if you need to call multiple functions on that Actor when a Variant is activated.

If you've read through the Variant Manager Overview, you've seen that the Variant Manager offers a Blueprint API that you can use at runtime to access information about the variant sets and variants that it contains, and to switch variants on dynamically. However, the Variant Manager also exposes a separate API that is only available to scripts that run in the Editor. You can use this Editor-only API to create new Level Variant Sets Assets and Actors, and to set them up with your scene variants programmatically.

This may be particularly useful if you need to set up scene variants in your Unreal Engine Project automatically to reflect variants or settings that you've already authored in another application. If you can export the data about those scene variants into a format that the Unreal Editor scripting systems can read, you may be able to use the methods described on this page to set up the same scene variants in Unreal Engine. This saves you the time and effort of rebuilding the same variants by hand in the Variant Manager UI. It may also be less error-prone, and more repeatable.

You can use either Blueprints or Python to script the setup of your Variant Manager.

Choose your implementation method:

Blueprints

Python

The most important nodes involved in setting up your scene variants are under the Variant Manager category in the Blueprint palette. The nodes in this category let you create new Level Variant Sets Assets, add Variant Sets and Variants to that Asset, bind Actors to Variants, and capture property values for those Actors.

You can't currently use the Editor scripting API to set up a bound Actor with a Function Caller as described in Calling Functions on Variant Activation. You can only use the scripting API to capture and set property values on bound Actors.

The following table describes some of the nodes you might use most frequently:

Blueprint Name

Description

Create Level Variant Sets Asset

Creates a new, empty Level Variant Sets Asset in the Content Browser, with the specified name and path.

Always make sure your path begins with /Game/ to save your new asset in your project's content folder.



Add Variant Set

Adds the specified Variant Set to the Level Variant Sets Asset. This is the equivalent to clicking the + Variant Set button in the Variant Manager UI. See the tip below for instructions on how to create a new Variant Set from scratch.

Add Actor Binding

Adds the specified Actor to the specified Variant. This is the equivalent of dragging the Actor from the World Outliner and dropping it on to the Variant in the Variant Manager UI.

Get Capturable Properties

Returns the names of all the properties that the Variant Manager can control for the specified Actor. You can use any of these values when you call the Capture Property node.

Capture Property

Saves the value of the property you specify for an Actor in the specified Variant.

Add Variant

Adds the specified Variant as a child of the specified Variant Set.

If you need to create a new Variant Set to add to a Level Variant Sets Asset, or create a new Variant to add to a Variant Set, use you can use the Construct Object from Class node. In the first input, specify the VariantSet or Variant class, depending on which one you need to create. In the second Outer input, always use the Level Variant Sets Asset that you're setting up. Finally, pass the output value to your Add node.

For example, this snippet creates a new Variant Set and adds it to the Asset, then creates a new Variant and adds it to that new Variant Set:



Click image for full size.

Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_10" VariableReference=(MemberName="Level Variant Sets",MemberGuid=E3CC4DBB43B6725A0CB55BB4F693C6F6,bSelfContext=True) NodePosX=448 NodePosY=1568 NodeGuid=358E52234236EA27FF9E409C0152D7C3 CustomProperties Pin (PinId=E381E5044644E82A2EFC6284D1AE69E4,PinName="Level Variant Sets",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_4 F1168C7A439DA6E0DDDA3DAFD6F93852,K2Node_Knot_12 302A96F847ADBB059B1CEDBDA6ABC7A9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6076B4134E69938689ADA886D7015308,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_GenericCreateObject Name="K2Node_GenericCreateObject_4" NodePosX=672 NodePosY=1488 NodeGuid=343224BC4B62792217FC0EAA29B82A76 CustomProperties Pin (PinId=06E383A74552E2095F4DC2B39BE10275,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_ExecutionSequence_1 93AF28404E1265BB869F9386DFC46686,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B2041BCF42F8514093BE4AAC20963B4D,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_23 4780289040B7D4924DCCCAA556B53A5E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=183D2663409D941282912B85D6B2A5CF,PinName="Class",PinToolTip="Object Class Reference Class\nThe object class you want to construct",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManagerContent.VariantSet",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8D0487744D7D91D38C25D49270FA3BBC,PinName="ReturnValue",PinToolTip="Variant Set Object Reference Return Value\nThe constructed object",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_23 C85BFCBB44A59CFE5B032CAF45ABC244,K2Node_Knot_16 C9062A404CC1EE14493007B204591DA0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F1168C7A439DA6E0DDDA3DAFD6F93852,PinName="self",PinFriendlyName="Outer",PinToolTip="Object Reference Outer\nOwner of the constructed object",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_10 E381E5044644E82A2EFC6284D1AE69E4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_23" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="AddVariantSet") NodePosX=1072 NodePosY=1488 NodeGuid=7B939BDC4E8ECB3D656CEE9B40840C6D CustomProperties Pin (PinId=4780289040B7D4924DCCCAA556B53A5E,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_4 B2041BCF42F8514093BE4AAC20963B4D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=92FBF6F04F0A6C1047ACAFA23A415000,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_5 2FF7A3F44BA9EAAF496841AE6E685823,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=60E8420240D8B180AE45979C148474EF,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0C435D9745F6B6F4A62666A4E9B74DBC,PinName="LevelVariantSets",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_13 6C0F0AD346611B3B6CF51BB7115F1F11,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C85BFCBB44A59CFE5B032CAF45ABC244,PinName="VariantSet",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_4 8D0487744D7D91D38C25D49270FA3BBC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_12" NodePosX=688 NodePosY=1664 NodeGuid=7729AF4A4DF767EB11F2E99CFC79AD20 CustomProperties Pin (PinId=302A96F847ADBB059B1CEDBDA6ABC7A9,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_10 E381E5044644E82A2EFC6284D1AE69E4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A5D1D7924DF3468A6F6C739019EF51E2,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_13 07095CF9435DDCCCF928118206D67C73,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_13" NodePosX=912 NodePosY=1664 NodeGuid=784817524F6035BC7E99C78AC8B11D28 CustomProperties Pin (PinId=07095CF9435DDCCCF928118206D67C73,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_12 A5D1D7924DF3468A6F6C739019EF51E2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6C0F0AD346611B3B6CF51BB7115F1F11,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_23 0C435D9745F6B6F4A62666A4E9B74DBC,K2Node_Knot_14 4707ACA54DAB2BD0B9F3D9B40D733EDA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_GenericCreateObject Name="K2Node_GenericCreateObject_5" NodePosX=1344 NodePosY=1488 NodeGuid=4F5AA78A47BE613B614D58B3B83112E8 CustomProperties Pin (PinId=2FF7A3F44BA9EAAF496841AE6E685823,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_23 92FBF6F04F0A6C1047ACAFA23A415000,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E7B7F4C842A34A9FD99F7584CAA6E398,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_24 07B17C78479429469365B4A59585222A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4EE5E6C840A9B11F55F016AB2391F9C9,PinName="Class",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManagerContent.Variant",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=69124E704378F430FEB2BD882FBF709A,PinName="ReturnValue",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_24 B03DEF2243DC2158F62135BB9D761E3B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EE4940124D7693063E2E6DADE00F2043,PinName="self",PinFriendlyName="Outer",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_14 0697390F481718E42AFA4BB9DC6C3E53,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_14" NodePosX=1232 NodePosY=1664 NodeGuid=A4BD856F4E507C54A937EC9042976325 CustomProperties Pin (PinId=4707ACA54DAB2BD0B9F3D9B40D733EDA,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_13 6C0F0AD346611B3B6CF51BB7115F1F11,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0697390F481718E42AFA4BB9DC6C3E53,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_5 EE4940124D7693063E2E6DADE00F2043,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_24" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="AddVariant") NodePosX=1744 NodePosY=1488 NodeGuid=00956F974DB489091D72AA87297360EC CustomProperties Pin (PinId=07B17C78479429469365B4A59585222A,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_5 E7B7F4C842A34A9FD99F7584CAA6E398,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=932A5A024316AF9D9E71E3B4279700F4,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4182DEFD4FDC3758999ED09897EEEF60,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Manager Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E164C9C949B0500A358267A67A51E0E5,PinName="VariantSet",PinToolTip="Variant Set\nVariant Set Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_15 67FB62E44CFFDBD1D495898A104388FE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B03DEF2243DC2158F62135BB9D761E3B,PinName="Variant",PinToolTip="Variant\nVariant Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_5 69124E704378F430FEB2BD882FBF709A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_15" NodePosX=1584 NodePosY=1440 NodeGuid=FDB7762F44268031EA55CFB181091560 CustomProperties Pin (PinId=B3F510DD4C5B395FD621FFB9AE8B70E9,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_16 36DE63E04B2635E2A7800FB8A0BB5A02,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=67FB62E44CFFDBD1D495898A104388FE,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_24 E164C9C949B0500A358267A67A51E0E5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_16" NodePosX=1104 NodePosY=1440 NodeGuid=3A4B5C46403189040BB1B49E895E04D3 CustomProperties Pin (PinId=C9062A404CC1EE14493007B204591DA0,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_4 8D0487744D7D91D38C25D49270FA3BBC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=36DE63E04B2635E2A7800FB8A0BB5A02,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_15 B3F510DD4C5B395FD621FFB9AE8B70E9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Blueprint Example

The following graph from an Editor Utility Widget shows how to set up the Variant Manager programmatically. First it creates a new Actor to work with. Then, it creates a new Level Variant Sets Asset, and sets it up with a new Variant Set. Finally, it adds two Variants to that Variant Set: one where the Actor is visible, and another where the Actor is hidden.



Click image for full size.

Begin Object Class=/Script/BlueprintGraph.K2Node_ExecutionSequence Name="K2Node_ExecutionSequence_0" NodePosX=32 NodePosY=160 NodeGuid=DF0A71BE439A5AA3BA916F8B7CFCCB56 CustomProperties Pin (PinId=E85384C34EFABAC9E94BD88EDDE4A9EA,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Event_0 4BE102E244F08B418D28B481B6E5170D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6FF1F7DA43668D86B12E9DB0D074FD84,PinName="then_0",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 290803024FCCD47F5508F8BF6DE79DB3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4FC3D2D74B794997F3592FBE8B87E2FE,PinName="then_1",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_26 8F7FB51A4A87ADBC5CDA9CAADB8F24F4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BBF3CD6B424CD6D13C2DA188C6EBD82D,PinName="then_2",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_28 F021027C4D654110D1059C9F8F89B148,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1A51A96442B769B9EC2D18BC3B729F24,PinName="then_3",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_22 D29F4FB2478BEB94F8A68591B711B132,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/EditorScriptingUtilities.EditorLevelLibrary"',MemberName="SpawnActorFromClass") NodePosX=528 NodePosY=-240 NodeGuid=B6AA351747D998842C50B38DA58664E3 CustomProperties Pin (PinId=290803024FCCD47F5508F8BF6DE79DB3,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_ExecutionSequence_0 6FF1F7DA43668D86B12E9DB0D074FD84,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=78363A504F5A50AD1BADE3B61F1FF64C,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_3 3FE9BD594EB5287390E7D9996EEF8472,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F4643AF84B5D74C5896479B11352E2E0,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nEditor Level Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/EditorScriptingUtilities.EditorLevelLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/EditorScriptingUtilities.Default__EditorLevelLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=17C2D47A4ACF3E7488BF5C9CB90AD86C,PinName="ActorClass",PinToolTip="Actor Class\nActor Class Reference",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=True,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.StaticMeshActor",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4A323C1441AC277960BCDBAF31F84E2C,PinName="Location",PinToolTip="Location\nVector",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C74C1CDB40BA7C1285CCDEB31B44591C,PinName="Rotation",PinToolTip="Rotation\nRotator",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.ScriptStruct'"/Script/CoreUObject.Rotator"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=26590D8941ED17A651B8FD9ECFEE6614,PinName="bTransient",PinToolTip="Transient\nBoolean",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=896BFF4B4ED88F7820F2C797D62FBBCF,PinName="ReturnValue",PinToolTip="Return Value\nStatic Mesh Actor Object Reference\n\nSpawn Actor from Class",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_3 F4F0E815474F9132D7480A8D0AFF407C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_25" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshComponent"',MemberName="SetStaticMesh") NodePosX=1456 NodePosY=-256 NodeGuid=04C73E5345091C4160F84B8D9E55839D CustomProperties Pin (PinId=2B1A615A4E95AB72DF4EAE8731575940,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_3 7F1D486445B57D6AAB0C95981EBB39E6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CF35EF104AAB4B78F6F3F2A430C80232,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F34BFFBC43BB85EDB2F99EB64FFFB5FB,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nStatic Mesh Component Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_11 94004D764B218A36127971BA62A04CA3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F356A2804814EEA19BAD4A87D07DF107,PinName="NewMesh",PinToolTip="New Mesh\nStatic Mesh Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.StaticMesh"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Engine/EngineMeshes/Cube.Cube",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AB8A66C5413E594B625F3A88E3735F80,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nChange the StaticMesh used by this instance.",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_11" VariableReference=(MemberParent=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshActor"',MemberName="StaticMeshComponent") SelfContextInfo=NotSelfContext NodePosX=1104 NodePosY=-176 NodeGuid=5979463D454A018061128492660A188A CustomProperties Pin (PinId=94004D764B218A36127971BA62A04CA3,PinName="StaticMeshComponent",PinFriendlyName=NSLOCTEXT("UObjectDisplayNames", "StaticMeshActor:StaticMeshComponent", "Static Mesh Component"),Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=True,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_25 F34BFFBC43BB85EDB2F99EB64FFFB5FB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9A069A6242EB02D00C0FCDAF049DF8EC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_3 372635BC47AC1F3A606AC09675654080,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_26" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="CreateLevelVariantSetsAsset") NodePosX=448 NodePosY=192 NodeGuid=B59CB2C14470F322725929A526E87165 CustomProperties Pin (PinId=8F7FB51A4A87ADBC5CDA9CAADB8F24F4,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_ExecutionSequence_0 4FC3D2D74B794997F3592FBE8B87E2FE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8D6BEFAF4EE37E214D35CE89D40F0957,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_4 DB62B7A64B7DB6457F72EBB7AD260901,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E86C619E461E19E690E6A1BDDF4D5F89,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Manager Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7B8873BA43DDD80F7F9F98B5131492F5,PinName="AssetName",PinToolTip="Asset Name\nString",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="GenerateLevelVariantSet",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7EFC8587459724EA241B4D94602AED04,PinName="AssetPath",PinToolTip="Asset Path\nString",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="/Game",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=298C75114F63C375872DA8A7FFB16DB9,PinName="ReturnValue",PinToolTip="Return Value\nLevel Variant Sets Object Reference\n\nCreates a new LevelVariantSetsAsset named AssetName (e.g. \'MyLevelVariantSets\') in the content path AssetPath (e.g. \'/Game\')",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_4 6E2DEE7B47701FC6FF07CBA1AB47B65B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_GenericCreateObject Name="K2Node_GenericCreateObject_0" NodePosX=624 NodePosY=544 NodeGuid=36357E854BBF5698D2B89B98AE574662 CustomProperties Pin (PinId=3D0A7666426B51954907F5B72FFE3D13,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_28 5F9FB3D64AF44469B0A007892487F314,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9607442E4CB9BE620391EE8D175A9012,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_31 73A6C12643F119C26035D6817BB22234,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8A867187414607110CE6E6BF6473E1A7,PinName="Class",PinToolTip="Object Class Reference Class\nThe object class you want to construct",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManagerContent.Variant",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A529A6554BCE5E0DED52E19DD40211FB,PinName="ReturnValue",PinToolTip="Variant Object Reference Return Value\nThe constructed object",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_31 2AA3A91D4C1C3103687A83A130158E1C,K2Node_Knot_18 A8A5F51347F85DEF78E8028966B26CB4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DFB8EAF54438F577DA9F1483CF40EDCC,PinName="self",PinFriendlyName=NSLOCTEXT("", "DE30CEB144B7E775C7BF96BA2A636387", "Outer"),PinToolTip="Object Reference Outer\nOwner of the constructed object",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_13 ECF5D52A49AB25256E1DFBB3FE1728CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_GenericCreateObject Name="K2Node_GenericCreateObject_6" NodePosX=1200 NodePosY=192 NodeGuid=A341135D477F1FABEF5148A14EE1FA43 CustomProperties Pin (PinId=9AB48BA646DABE82E03A8A8C5EF83184,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_4 34BFC782498EEC49B1031C9B61090ACE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0FD0EC8F4BFCF7A9B14D7C91BFFA5A2E,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_5 2E7C18A24AA31A0A5C765FBD844A4E0D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D375930D438E751F2083DEAABB53DC86,PinName="Class",PinToolTip="Object Class Reference Class\nThe object class you want to construct",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManagerContent.VariantSet",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=924FAB674283D75A65F529A89914426D,PinName="ReturnValue",PinToolTip="Variant Set Object Reference Return Value\nThe constructed object",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_5 AEB195584FA47E5EBD6A0BBAB5047E4C,K2Node_Knot_17 E9F057C044625EF8578E9C899BEEA935,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=28B26703482EC0EA843DE78BB1FB527F,PinName="self",PinFriendlyName=NSLOCTEXT("", "3788DB19484DE0722FC54CAA861A3646", "Outer"),PinToolTip="Object Reference Outer\nOwner of the constructed object",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_4 00E3ED34402FE0990F76A38E9603C2A3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_3" VariableReference=(MemberName="Actor",MemberGuid=1C98B6ED4C39D8D40E5A3885A9D0A571,bSelfContext=True) NodePosX=912 NodePosY=-224 NodeGuid=9C19DE3340678A65D4C005907493131E CustomProperties Pin (PinId=3FE9BD594EB5287390E7D9996EEF8472,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 78363A504F5A50AD1BADE3B61F1FF64C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7F1D486445B57D6AAB0C95981EBB39E6,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_25 2B1A615A4E95AB72DF4EAE8731575940,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F4F0E815474F9132D7480A8D0AFF407C,PinName="Actor",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 896BFF4B4ED88F7820F2C797D62FBBCF,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=372635BC47AC1F3A606AC09675654080,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_11 9A069A6242EB02D00C0FCDAF049DF8EC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B874445D483A3B754BB46FB44D52B441,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_4" VariableReference=(MemberName="Level Variant Sets",MemberGuid=E3CC4DBB43B6725A0CB55BB4F693C6F6,bSelfContext=True) NodePosX=848 NodePosY=208 NodeGuid=229F0EDC4DD672BED4B1FBB5B4615FF3 CustomProperties Pin (PinId=DB62B7A64B7DB6457F72EBB7AD260901,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_26 8D6BEFAF4EE37E214D35CE89D40F0957,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=34BFC782498EEC49B1031C9B61090ACE,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_6 9AB48BA646DABE82E03A8A8C5EF83184,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6E2DEE7B47701FC6FF07CBA1AB47B65B,PinName="Level Variant Sets",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_26 298C75114F63C375872DA8A7FFB16DB9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=00E3ED34402FE0990F76A38E9603C2A3,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_6 28B26703482EC0EA843DE78BB1FB527F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5CF231154A9150632E94AB9FC4600BEB,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_5" VariableReference=(MemberName="Variant Set",MemberGuid=D6DA1F6B40E0DD3A7FB9C0A83184974B,bSelfContext=True) NodePosX=1600 NodePosY=208 NodeGuid=F971311B486E640967D5C48EF45858B7 CustomProperties Pin (PinId=2E7C18A24AA31A0A5C765FBD844A4E0D,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_6 0FD0EC8F4BFCF7A9B14D7C91BFFA5A2E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1A1B54CA4B1C836DA0F0FCBC6E21A793,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_27 41489B634E69C98DA0BDC781EF1CDCD2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AEB195584FA47E5EBD6A0BBAB5047E4C,PinName="Variant Set",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_6 924FAB674283D75A65F529A89914426D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=97F30D1F4083A433328A97908173F0BA,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_27 D6EE96A3424B7EB8B1909080E0D30855,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1A775D474F650C34D28867820A7DD614,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_27" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="AddVariantSet") NodePosX=1888 NodePosY=192 NodeGuid=6F7960464BE65CF6F1EEE5A22C0ACD7E CustomProperties Pin (PinId=41489B634E69C98DA0BDC781EF1CDCD2,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_5 1A1B54CA4B1C836DA0F0FCBC6E21A793,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A526F2994EC6169E1001008F021DF24B,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_29 1FABD45842DCF65EE5A645935417A0E4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AA46F4234F77A68D9C5EE082EC393E43,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Manager Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=60D6213F4A842EA4102DF58B00184C93,PinName="LevelVariantSets",PinToolTip="Level Variant Sets\nLevel Variant Sets Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_12 42BE4E4240144C11277C2BA458FC6958,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D6EE96A3424B7EB8B1909080E0D30855,PinName="VariantSet",PinToolTip="Variant Set\nVariant Set Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_5 97F30D1F4083A433328A97908173F0BA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_12" VariableReference=(MemberName="Level Variant Sets",MemberGuid=E3CC4DBB43B6725A0CB55BB4F693C6F6,bSelfContext=True) NodePosX=1600 NodePosY=144 NodeGuid=389DC9DB4830C4118D6259AC9F117653 CustomProperties Pin (PinId=42BE4E4240144C11277C2BA458FC6958,PinName="Level Variant Sets",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_27 60D6213F4A842EA4102DF58B00184C93,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FD709D3B4CF34760112D95A3B0D9A0B1,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_28" bIsPureFunc=True FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/Engine.KismetTextLibrary"',MemberName="Conv_StringToText") NodePosX=1824 NodePosY=352 NodeGuid=3F8051D1478876EE57ACB38B8848B4A5 CustomProperties Pin (PinId=8B72A3134A0A11B5F1FC8595A5B00AF4,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Text Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.KismetTextLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetTextLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CA77503B4DE7A6A0474509883CCF6859,PinName="InString",PinToolTip="In String\nString",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Generate Variant Set",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BDC5DCD6409F68EBA1F609B50968F26F,PinName="ReturnValue",PinToolTip="Return Value\nText\n\nConverts string to culture invariant text. Use Format or Make Literal Text to create localizable text",Direction="EGPD_Output",PinType.PinCategory="text",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_29 50F74C6A48485D523D6E859F2CE5FC70,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_29" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',MemberName="SetDisplayText") NodePosX=2208 NodePosY=176 NodeGuid=019FA33F4509D05B29ABE9972F2EDF8D CustomProperties Pin (PinId=1FABD45842DCF65EE5A645935417A0E4,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_27 A526F2994EC6169E1001008F021DF24B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6AD17EF44D60CDA8BCDC82AA3B4B87E7,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E7F242D24DAAFF236367F987210C3F80,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Set Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_27 FF0EB9E1495E2E0EFD702A8676EC3642,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=50F74C6A48485D523D6E859F2CE5FC70,PinName="NewDisplayText",PinToolTip="New Display Text\nText (by ref)",PinType.PinCategory="text",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_28 BDC5DCD6409F68EBA1F609B50968F26F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_17" NodePosX=1584 NodePosY=320 NodeGuid=70C682A34864C5ABD6054992DDD8D950 CustomProperties Pin (PinId=E9F057C044625EF8578E9C899BEEA935,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_6 924FAB674283D75A65F529A89914426D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=82BD8F284DA8E8B275ED30933FA946B8,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_27 30E2288C433D4ECEFF3AB2B7CCE19C85,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_5" bCommentBubbleVisible_InDetailsPanel=False NodePosX=384 NodePosY=-304 NodeWidth=1440 NodeHeight=368 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Create Static Mesh Actor in the Current Level" NodeGuid=6F00C8C84A656A1CBAF1548E5E9FD979 End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_6" bCommentBubbleVisible_InDetailsPanel=False NodePosX=384 NodePosY=96 NodeWidth=720 NodeHeight=368 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Create Level Variant Sets Asset" NodeGuid=9F31D4994DA03571AF4ED6A9EEDA53CC End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_7" bCommentBubbleVisible_InDetailsPanel=False NodePosX=1136 NodePosY=96 NodeWidth=1296 NodeHeight=368 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Create a Variant Set and Add it to the Level Variant Sets" NodeGuid=F905144E4FA126D9EBE3A79221317428 End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_13" VariableReference=(MemberName="Level Variant Sets",MemberGuid=E3CC4DBB43B6725A0CB55BB4F693C6F6,bSelfContext=True) NodePosX=416 NodePosY=640 NodeGuid=4F434ABD407F8FADDC7E16B6E41480E2 CustomProperties Pin (PinId=ECF5D52A49AB25256E1DFBB3FE1728CC,PinName="Level Variant Sets",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_0 DFB8EAF54438F577DA9F1483CF40EDCC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F809FE1942C44557FA9460A0976C4BAA,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_30" bIsPureFunc=True FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/Engine.KismetTextLibrary"',MemberName="Conv_StringToText") NodePosX=608 NodePosY=704 NodeGuid=3858B5634D4BBE7629FB54B430B30960 CustomProperties Pin (PinId=7724122F427C116F893F3BB5B56B9DD3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Text Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.KismetTextLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetTextLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FE4F6C534E47AAECA1E3E191677EFDFB,PinName="InString",PinToolTip="In String\nString",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Object Visible",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BB58DD014239B4FACF34548CFE87220E,PinName="ReturnValue",PinToolTip="Return Value\nText\n\nConverts string to culture invariant text. Use Format or Make Literal Text to create localizable text",Direction="EGPD_Output",PinType.PinCategory="text",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_31 E8946BB84231774D5E6BF6A6137ECF5E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_31" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',MemberName="SetDisplayText") NodePosX=1024 NodePosY=528 NodeGuid=9D9B09D64700A2915C1D748824B2069F CustomProperties Pin (PinId=73A6C12643F119C26035D6817BB22234,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_0 9607442E4CB9BE620391EE8D175A9012,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6CA36E43429C313147144A94AD8D9088,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_32 EDD4F2B9456444FB07049F935AAEC604,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2AA3A91D4C1C3103687A83A130158E1C,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_0 A529A6554BCE5E0DED52E19DD40211FB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E8946BB84231774D5E6BF6A6137ECF5E,PinName="NewDisplayText",PinToolTip="New Display Text\nText (by ref)",PinType.PinCategory="text",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_30 BB58DD014239B4FACF34548CFE87220E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_14" VariableReference=(MemberName="Actor",MemberGuid=1C98B6ED4C39D8D40E5A3885A9D0A571,bSelfContext=True) NodePosX=1040 NodePosY=768 NodeGuid=14E5A1F64ACA3EDB31F978B09BCDD576 CustomProperties Pin (PinId=306301DC4A6AB30827E332A557DC1F9F,PinName="Actor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_32 1AFAFCFC4B174D427C05458C69590765,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3ED27FF44C64FED2EAFD5D908771C929,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_32" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="AddActorBinding") NodePosX=1296 NodePosY=544 NodeGuid=923315C242A58C0F979428821BBAE4C7 CustomProperties Pin (PinId=EDD4F2B9456444FB07049F935AAEC604,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_31 6CA36E43429C313147144A94AD8D9088,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=84E81B1C485B701BDFCE68AA62080411,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_33 6DEBC155434C62F17F1376A371616246,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E79F93FB477ACD065DDAF5BDA74613BC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Manager Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7A085C7F4BDB8D2A7B61FC8251175201,PinName="Variant",PinToolTip="Variant\nVariant Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_19 12204C3042CD9A3E01D0C4A7754455EB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1AFAFCFC4B174D427C05458C69590765,PinName="Actor",PinToolTip="Actor\nActor Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_14 306301DC4A6AB30827E332A557DC1F9F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_18" NodePosX=1056 NodePosY=736 NodeGuid=BB93B4B64042FFA008F2F399B8E186A1 CustomProperties Pin (PinId=A8A5F51347F85DEF78E8028966B26CB4,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_0 A529A6554BCE5E0DED52E19DD40211FB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8B7024304C4D2AD56CFD74AB98C4AF7B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_19 6498E0824CD4CB8A18CD9AAF43FDF7C2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_19" NodePosX=1136 NodePosY=736 NodeGuid=41637C784747D5FBC74034A493ED9E9A CustomProperties Pin (PinId=6498E0824CD4CB8A18CD9AAF43FDF7C2,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_18 8B7024304C4D2AD56CFD74AB98C4AF7B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=12204C3042CD9A3E01D0C4A7754455EB,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_32 7A085C7F4BDB8D2A7B61FC8251175201,K2Node_Knot_20 0102760C4CAC5538418AB889C4B9A59A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_33" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="CaptureProperty") NodePosX=1536 NodePosY=544 NodeGuid=46E9AC1E4D1D8E57C0F809BFCA9F9D9D CustomProperties Pin (PinId=6DEBC155434C62F17F1376A371616246,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_32 84E81B1C485B701BDFCE68AA62080411,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=076A95904CCE53D49A4DD69A7AC264C5,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_34 CB7704AD44381FD4A694409C984C3202,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FDE2DC304D76137C5DBE5CB309444B58,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Manager Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=22BCC99A4EC49BA319214684F4E3042F,PinName="Variant",PinToolTip="Variant\nVariant Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_20 2C16169F4488B2F68AD7A282C4969464,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2530442A43B84F0EF1FB1AB278B08C59,PinName="Actor",PinToolTip="Actor\nActor Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_15 1DCDE8A14CE7E303A19FA6BD73D75306,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0B05274B43C9ACBA4A325E93F3194AF9,PinName="PropertyPath",PinToolTip="Property Path\nString",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Static Mesh Component / Visible",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8F33441C45BD959E3B8F62891320428A,PinName="ReturnValue",PinToolTip="Return Value\nProperty Value Object Reference\n\nFinds the actor binding to Actor within Variant and tries capturing a property with PropertyPath\nReturns the captured UPropertyValue if succeeded or nullptr if it failed.",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.PropertyValue"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_34 2D49764A40A2A54CC5B2E8866C70F7F6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_20" NodePosX=1392 NodePosY=736 NodeGuid=190CC6394712609221438CB770AA478B CustomProperties Pin (PinId=0102760C4CAC5538418AB889C4B9A59A,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_19 12204C3042CD9A3E01D0C4A7754455EB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2C16169F4488B2F68AD7A282C4969464,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_33 22BCC99A4EC49BA319214684F4E3042F,K2Node_Knot_21 46AC1C2D44E2D45E093277B8F2AB7C6D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_15" VariableReference=(MemberName="Actor",MemberGuid=1C98B6ED4C39D8D40E5A3885A9D0A571,bSelfContext=True) NodePosX=1296 NodePosY=768 NodeGuid=C0CFA3BF403C15CE00BEC1B42ADB31F0 CustomProperties Pin (PinId=1DCDE8A14CE7E303A19FA6BD73D75306,PinName="Actor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_33 2530442A43B84F0EF1FB1AB278B08C59,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=062DC77F48553F2B0A98C6BA58257C81,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_34" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="SetValueBool") NodePosX=1984 NodePosY=544 NodeGuid=07F6372B4EC9EBF4CFE04DA1956DC5C5 CustomProperties Pin (PinId=CB7704AD44381FD4A694409C984C3202,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_33 076A95904CCE53D49A4DD69A7AC264C5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B88B2FA5474B07A59661EBB6AA615472,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_35 1F9D3AD340D9DDD529BE98B64F03EE37,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5484E1BB4DDC8996398C719D87AFE304,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Manager Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2D49764A40A2A54CC5B2E8866C70F7F6,PinName="Property",PinToolTip="Property\nProperty Value Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.PropertyValue"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_33 8F33441C45BD959E3B8F62891320428A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=79FB710D49BE65A397C2909C22E36D7E,PinName="InValue",PinToolTip="In Value\nBoolean",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_35" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="AddVariant") NodePosX=2224 NodePosY=544 NodeGuid=F155E83F4BBC79CFF05C93A90EAC8E32 CustomProperties Pin (PinId=1F9D3AD340D9DDD529BE98B64F03EE37,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_34 B88B2FA5474B07A59661EBB6AA615472,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3C64D552452A9822FE656BBB6B189ECE,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7BC806AE44CDA575A01691954700855A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Manager Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EEA2EB24438421EB84513B92378CFE7D,PinName="VariantSet",PinToolTip="Variant Set\nVariant Set Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_16 ECCE21BF464E55834DC6DC9BD2A5B8A2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DAC66D4848F7FDBCAECD04BE15973DC4,PinName="Variant",PinToolTip="Variant\nVariant Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_21 164C75ED4389531DB1D132A903151A0A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_16" VariableReference=(MemberName="Variant Set",MemberGuid=D6DA1F6B40E0DD3A7FB9C0A83184974B,bSelfContext=True) NodePosX=2000 NodePosY=688 NodeGuid=48EF88A64DCC6F81D9452DB48DECEBAB CustomProperties Pin (PinId=ECCE21BF464E55834DC6DC9BD2A5B8A2,PinName="Variant Set",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_35 EEA2EB24438421EB84513B92378CFE7D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1F9C158C4DC87FF723E26EBAD9368892,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_21" NodePosX=2080 NodePosY=736 NodeGuid=AC17812444B77CB2B20F75BC31454F79 CustomProperties Pin (PinId=46AC1C2D44E2D45E093277B8F2AB7C6D,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_20 2C16169F4488B2F68AD7A282C4969464,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=164C75ED4389531DB1D132A903151A0A,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_35 DAC66D4848F7FDBCAECD04BE15973DC4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_8" bCommentBubbleVisible_InDetailsPanel=False NodePosX=384 NodePosY=480 NodeWidth=2048 NodeHeight=400 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Create a Variant with the Previously Spawned Actor Visible and Add this Variant to the Variant Set" NodeGuid=B584F72341BB66966541DCAE9CDEF510 End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_22" NodePosX=480 NodePosY=1008 NodeGuid=1AC207D640E221262E53A2B0AD01B218 CustomProperties Pin (PinId=D29F4FB2478BEB94F8A68591B711B132,PinName="InputPin",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_ExecutionSequence_0 1A51A96442B769B9EC2D18BC3B729F24,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C0CAFBE2474DA7FA943A1FADA688C1CC,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_7 3D0A7666426B51954907F5B72FFE3D13,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_GenericCreateObject Name="K2Node_GenericCreateObject_7" NodePosX=624 NodePosY=976 NodeGuid=A0E2FDAB49CF58765B5E83BDDF3A4765 CustomProperties Pin (PinId=3D0A7666426B51954907F5B72FFE3D13,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_22 C0CAFBE2474DA7FA943A1FADA688C1CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9607442E4CB9BE620391EE8D175A9012,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_37 73A6C12643F119C26035D6817BB22234,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8A867187414607110CE6E6BF6473E1A7,PinName="Class",PinToolTip="Object Class Reference Class\nThe object class you want to construct",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManagerContent.Variant",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A529A6554BCE5E0DED52E19DD40211FB,PinName="ReturnValue",PinToolTip="Variant Object Reference Return Value\nThe constructed object",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_37 2AA3A91D4C1C3103687A83A130158E1C,K2Node_Knot_23 A8A5F51347F85DEF78E8028966B26CB4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DFB8EAF54438F577DA9F1483CF40EDCC,PinName="self",PinFriendlyName=NSLOCTEXT("", "13EC82A54587CE2EF31AD89CB3314155", "Outer"),PinToolTip="Object Reference Outer\nOwner of the constructed object",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_17 ECF5D52A49AB25256E1DFBB3FE1728CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_17" VariableReference=(MemberName="Level Variant Sets",MemberGuid=E3CC4DBB43B6725A0CB55BB4F693C6F6,bSelfContext=True) NodePosX=416 NodePosY=1072 NodeGuid=A0119A8446384E4EEDF1968E570B3DE0 CustomProperties Pin (PinId=ECF5D52A49AB25256E1DFBB3FE1728CC,PinName="Level Variant Sets",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.LevelVariantSets"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_7 DFB8EAF54438F577DA9F1483CF40EDCC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F809FE1942C44557FA9460A0976C4BAA,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_36" bIsPureFunc=True FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/Engine.KismetTextLibrary"',MemberName="Conv_StringToText") NodePosX=608 NodePosY=1136 NodeGuid=FC57756849EFED7A016DD7AE869BC67D CustomProperties Pin (PinId=7724122F427C116F893F3BB5B56B9DD3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Text Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.KismetTextLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetTextLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FE4F6C534E47AAECA1E3E191677EFDFB,PinName="InString",PinToolTip="In String\nString",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Object Hidden",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BB58DD014239B4FACF34548CFE87220E,PinName="ReturnValue",PinToolTip="Return Value\nText\n\nConverts string to culture invariant text. Use Format or Make Literal Text to create localizable text",Direction="EGPD_Output",PinType.PinCategory="text",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_37 E8946BB84231774D5E6BF6A6137ECF5E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_37" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',MemberName="SetDisplayText") NodePosX=1024 NodePosY=960 NodeGuid=FBB564C1409FD668F2195F9B03B52B94 CustomProperties Pin (PinId=73A6C12643F119C26035D6817BB22234,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_7 9607442E4CB9BE620391EE8D175A9012,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6CA36E43429C313147144A94AD8D9088,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_38 EDD4F2B9456444FB07049F935AAEC604,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2AA3A91D4C1C3103687A83A130158E1C,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_7 A529A6554BCE5E0DED52E19DD40211FB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E8946BB84231774D5E6BF6A6137ECF5E,PinName="NewDisplayText",PinToolTip="New Display Text\nText (by ref)",PinType.PinCategory="text",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_36 BB58DD014239B4FACF34548CFE87220E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_18" VariableReference=(MemberName="Actor",MemberGuid=1C98B6ED4C39D8D40E5A3885A9D0A571,bSelfContext=True) NodePosX=1040 NodePosY=1200 NodeGuid=6FB119B242B3E7E542264293238E40C1 CustomProperties Pin (PinId=306301DC4A6AB30827E332A557DC1F9F,PinName="Actor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_38 1AFAFCFC4B174D427C05458C69590765,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3ED27FF44C64FED2EAFD5D908771C929,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_38" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="AddActorBinding") NodePosX=1296 NodePosY=976 NodeGuid=F66C9A5044DCC8A83D053DBCB6116E1D CustomProperties Pin (PinId=EDD4F2B9456444FB07049F935AAEC604,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_37 6CA36E43429C313147144A94AD8D9088,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=84E81B1C485B701BDFCE68AA62080411,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_39 6DEBC155434C62F17F1376A371616246,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E79F93FB477ACD065DDAF5BDA74613BC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Manager Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7A085C7F4BDB8D2A7B61FC8251175201,PinName="Variant",PinToolTip="Variant\nVariant Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_24 12204C3042CD9A3E01D0C4A7754455EB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1AFAFCFC4B174D427C05458C69590765,PinName="Actor",PinToolTip="Actor\nActor Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_18 306301DC4A6AB30827E332A557DC1F9F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_23" NodePosX=1056 NodePosY=1168 NodeGuid=12321ABE45C99C58AF39BD8E394BB028 CustomProperties Pin (PinId=A8A5F51347F85DEF78E8028966B26CB4,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_7 A529A6554BCE5E0DED52E19DD40211FB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8B7024304C4D2AD56CFD74AB98C4AF7B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_24 6498E0824CD4CB8A18CD9AAF43FDF7C2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_24" NodePosX=1136 NodePosY=1168 NodeGuid=6299AA1D424FAB3E57184C8A8803118C CustomProperties Pin (PinId=6498E0824CD4CB8A18CD9AAF43FDF7C2,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_23 8B7024304C4D2AD56CFD74AB98C4AF7B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=12204C3042CD9A3E01D0C4A7754455EB,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_38 7A085C7F4BDB8D2A7B61FC8251175201,K2Node_Knot_25 0102760C4CAC5538418AB889C4B9A59A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_39" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="CaptureProperty") NodePosX=1536 NodePosY=976 NodeGuid=E1A6CE5E4D30F20C491C459B5112E52D CustomProperties Pin (PinId=6DEBC155434C62F17F1376A371616246,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_38 84E81B1C485B701BDFCE68AA62080411,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=076A95904CCE53D49A4DD69A7AC264C5,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_40 CB7704AD44381FD4A694409C984C3202,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FDE2DC304D76137C5DBE5CB309444B58,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Manager Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=22BCC99A4EC49BA319214684F4E3042F,PinName="Variant",PinToolTip="Variant\nVariant Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_25 2C16169F4488B2F68AD7A282C4969464,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2530442A43B84F0EF1FB1AB278B08C59,PinName="Actor",PinToolTip="Actor\nActor Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_19 1DCDE8A14CE7E303A19FA6BD73D75306,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0B05274B43C9ACBA4A325E93F3194AF9,PinName="PropertyPath",PinToolTip="Property Path\nString",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Static Mesh Component / Visible",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8F33441C45BD959E3B8F62891320428A,PinName="ReturnValue",PinToolTip="Return Value\nProperty Value Object Reference\n\nFinds the actor binding to Actor within Variant and tries capturing a property with PropertyPath\nReturns the captured UPropertyValue if succeeded or nullptr if it failed.",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.PropertyValue"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_40 2D49764A40A2A54CC5B2E8866C70F7F6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_25" NodePosX=1392 NodePosY=1168 NodeGuid=B79728FD4953416F6A244D85B4F989F3 CustomProperties Pin (PinId=0102760C4CAC5538418AB889C4B9A59A,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_24 12204C3042CD9A3E01D0C4A7754455EB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2C16169F4488B2F68AD7A282C4969464,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_39 22BCC99A4EC49BA319214684F4E3042F,K2Node_Knot_26 46AC1C2D44E2D45E093277B8F2AB7C6D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_19" VariableReference=(MemberName="Actor",MemberGuid=1C98B6ED4C39D8D40E5A3885A9D0A571,bSelfContext=True) NodePosX=1296 NodePosY=1200 NodeGuid=720D4D7A43E233AD8B8FC2901EFC8D33 CustomProperties Pin (PinId=1DCDE8A14CE7E303A19FA6BD73D75306,PinName="Actor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/Engine.StaticMeshActor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_39 2530442A43B84F0EF1FB1AB278B08C59,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=062DC77F48553F2B0A98C6BA58257C81,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_40" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="SetValueBool") NodePosX=1984 NodePosY=976 NodeGuid=588329D6437B1EC0C380DCB9A2CDBC10 CustomProperties Pin (PinId=CB7704AD44381FD4A694409C984C3202,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_39 076A95904CCE53D49A4DD69A7AC264C5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B88B2FA5474B07A59661EBB6AA615472,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_41 1F9D3AD340D9DDD529BE98B64F03EE37,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5484E1BB4DDC8996398C719D87AFE304,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Manager Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2D49764A40A2A54CC5B2E8866C70F7F6,PinName="Property",PinToolTip="Property\nProperty Value Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.PropertyValue"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_39 8F33441C45BD959E3B8F62891320428A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=79FB710D49BE65A397C2909C22E36D7E,PinName="InValue",PinToolTip="In Value\nBoolean",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_41" FunctionReference=(MemberParent=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',MemberName="AddVariant") NodePosX=2224 NodePosY=976 NodeGuid=D67894704871D79ACB9E91BFDCE6A903 CustomProperties Pin (PinId=1F9D3AD340D9DDD529BE98B64F03EE37,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_40 B88B2FA5474B07A59661EBB6AA615472,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3C64D552452A9822FE656BBB6B189ECE,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7BC806AE44CDA575A01691954700855A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nVariant Manager Blueprint Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManager.VariantManagerBlueprintLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/VariantManager.Default__VariantManagerBlueprintLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EEA2EB24438421EB84513B92378CFE7D,PinName="VariantSet",PinToolTip="Variant Set\nVariant Set Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_20 ECCE21BF464E55834DC6DC9BD2A5B8A2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DAC66D4848F7FDBCAECD04BE15973DC4,PinName="Variant",PinToolTip="Variant\nVariant Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_26 164C75ED4389531DB1D132A903151A0A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_20" VariableReference=(MemberName="Variant Set",MemberGuid=D6DA1F6B40E0DD3A7FB9C0A83184974B,bSelfContext=True) NodePosX=2000 NodePosY=1120 NodeGuid=FB2E0E114321A436BD9E0585644E8E94 CustomProperties Pin (PinId=ECCE21BF464E55834DC6DC9BD2A5B8A2,PinName="Variant Set",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_41 EEA2EB24438421EB84513B92378CFE7D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1F9C158C4DC87FF723E26EBAD9368892,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/VariantManager.VariantManager_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_26" NodePosX=2080 NodePosY=1168 NodeGuid=6AA659524C6A9D0CDB3EBA8C99D070B1 CustomProperties Pin (PinId=46AC1C2D44E2D45E093277B8F2AB7C6D,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_25 2C16169F4488B2F68AD7A282C4969464,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=164C75ED4389531DB1D132A903151A0A,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.Variant"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_41 DAC66D4848F7FDBCAECD04BE15973DC4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/UnrealEd.EdGraphNode_Comment Name="EdGraphNode_Comment_9" bCommentBubbleVisible_InDetailsPanel=False NodePosX=384 NodePosY=912 NodeWidth=2048 NodeHeight=400 bCommentBubblePinned=False bCommentBubbleVisible=False NodeComment="Create a Variant with the Previously Spawned Actor Hidden and Add this Variant to the Variant Set" NodeGuid=2350ECDA402C5F9DA5167E95CD8E1B0A End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_27" NodePosX=2064 NodePosY=320 NodeGuid=82331BBA4AAE2216489EB2AC42B11A0B CustomProperties Pin (PinId=30E2288C433D4ECEFF3AB2B7CCE19C85,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_17 82BD8F284DA8E8B275ED30933FA946B8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FF0EB9E1495E2E0EFD702A8676EC3642,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.Class'"/Script/VariantManagerContent.VariantSet"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_29 E7F242D24DAAFF236367F987210C3F80,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_28" NodePosX=496 NodePosY=576 NodeGuid=957252B74D2D8AC3C2F183A7F4AE88D2 CustomProperties Pin (PinId=F021027C4D654110D1059C9F8F89B148,PinName="InputPin",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_ExecutionSequence_0 BBF3CD6B424CD6D13C2DA188C6EBD82D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5F9FB3D64AF44469B0A007892487F314,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GenericCreateObject_0 3D0A7666426B51954907F5B72FFE3D13,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

After you run this example, you'll see a new cube created at the origin point of the Level. You'll also have a new Level Variant Sets Asset that lets you show and hide that cube by switching its Variants.

The most important class involved in setting up your scene variants is unreal.VariantManagerLibrary. This class lets you create new Level Variant Sets Assets, add Variant Sets and Variants to that Asset, bind Actors to Variants, and capture property values for those Actors.

You can't currently use the Editor scripting API to set up a bound Actor with a Function Caller as described in Calling Functions on Variant Activation. You can only use the scripting API to capture and set property values on bound Actors.

The following table describes the functions you'll use most often. For details on these and other functions offered by the VariantManagerLibrary, see the Python API Reference.

unreal.VariantManagerLibrary.create_level_variant_sets_asset(asset_name, asset_path) Creates a new, empty Level Variant Sets Asset in the Content Browser, with the specified name and path.

unreal.VariantManagerLibrary.add_variant_set(level_variant_sets, variant_set) Adds the specified Variant Set to the Level Variant Sets Asset. This is the equivalent to clicking the + Variant Set button in the Variant Manager UI.

unreal.VariantManagerLibrary.add_actor_binding(variant, actor) Adds the specified Actor to the specified Variant. This is the equivalent of dragging the Actor from the World Outliner and dropping it on to the Variant in the Variant Manager UI.

unreal.VariantManagerLibrary.get_capturable_properties(actor_or_class) Returns the names of all the properties that the Variant Manager can control for the specified Actor. You can use any of these values when you call capture_property().

unreal.VariantManagerLibrary.capture_property(variant, actor, property_path) Saves the value of the property you specify for an Actor in the specified Variant.

unreal.VariantManagerLibrary.add_variant(variant_set, variant) Adds the specified Variant as a child of the specified Variant Set.

Python Example

The following example shows how to set up a new Level Variant Sets Asset from scratch.

It first sets up a scene consisting of cubes and spheres, then sets up the Variant Manager to change the positions and visibility of those Actors.

The result is as follows: two Variant Sets, each with two Variants.

The first Variant Set switches the positions of the Actors in 3D space to arrange them into a straight line or a circle.

The second Variant Set swaps the Actors between a cube mesh and a spherical mesh.

Overview

Controling the Template

Template Features

Using the BP_Configurator

How to Import Your Data

Adding Your Artwork into the Main Level

Creating Your Variants in the Variant Manager

Connecting to the BP_Configurator



The Product Configurator template in Unreal Engine 5 (UE5) presents 3D visualization artists with a starting point for the creation of a customizable product configurator and user interface. The template utilizes Level Variant Sets, custom UMG interface elements, and a purpose-built configuration Blueprint with the following features:

Geometry variation using Actor switching.

Material and Visibility options.

Camera position and setting variation.

Lighting and environment variation.

Procedurally generated interface that presents users with options.

Ability to add new variations without using Blueprint code.

Overview

Using the Variant Manager, you can define Actor Variants and Variant Sets within a LevelVariantSet Actor. The information is then passed to the BP_Configurator Blueprint; which uses the information to dynamically create the user interface and display all of the variant options, complete with user-defined thumbnail images:



Click image for full size.

Controling the Template

Control

Description

Alt + LMB

Rotate camera around the product.

Alt + RMB

Zoom in/out

G

Hide/Show Interface

Escape

Exit the Configurator

Template Features

The template uses the Variant Manager, a specialized UI panel that organizes different configurations of properties for Actors in your level and stores them in a LevelVariantSet Actor.



Click image for full size.

Number

Description

1

Variants

2

Actors

3

Properties

4

Enable auto-capture properties

The Variants column contains all of your Actor configurations, known as variants, organized into Variant Sets. Each Variant represents an option in the configurator and can contain one or more Actors with a variety of property changes. These are represented by a thumbnail image set by the user. All Variants are translated into buttons in the interface at runtime via the BP_Configurator.

For information on using the Variant Manger, please see the Variant Manager documentation.

Using the BP_Configurator

The BP_Configurator Blueprint takes in data from a specified Level Variant Set and dynamically creates the user interface for your configurator:

The BP_Configurator takes in data from the specified Level Variant Set.

Each Variant Set is translated into an icon on the main UI toolbar.

Each Variant becomes an option in that Variant Set's sub menu.

The Variant is visually represented by the thumbnail set in the Variant Manager.

Variant Sets are represented by the icon of the currently active Variant.

How to Import Your Data

Customizing the Product Configurator template begins with importing your 3d artwork and textures. Unreal Engine 5 supports the use of Datasmith, as well as the FBX Content Pipeline for importing from your favorite 3D applications such as Maya, 3ds Max, and Blender.

Once your 3D and 2D assets have been imported into the Content Browser, you will need to remove the sample guitar from the level and build your Variant and Variant Sets using the Variant Manager. The final step will be to connect your level variant set to the BP_Configurator to create the custom user interface at runtime.

Adding Your Artwork into the Main Level

When your assets have been imported into UE5 and setup in the Content Browser, the example guitar will need to be removed and the new art added to the level:



Click image for full size.



Click image for full size.

The Product Configurator uses one or more root Actors to provide standard placement for your static meshes:



Click image for full size.

To remove the example model, delete the GuitarRoot object and all of its child objects.

Next, place a new Empty Actor into the level to serve as your new root object. Center its location at the level origin (X=0, Y=0, Z=0):



Click image for full size.



Click image for full size.



Click image for full size.

This will place your product in front of the existing camera setup.

Now, place the pieces of your product in the level as children of the root object:



Click image for full size.

Creating Your Variants in the Variant Manager

With the artwork set up in the level, you can begin to create Variants and Variant Sets using a LevelVariantSet Actor and the Variant Manager.

For the dynamic UI created by the BP_Configurator to work, the first and second Variant Sets must be the Environment and the Camera.

Create a LevelVariantSet Actor by right clicking in the content browser, navigating to the Miscellaneous sub menu and choosing the Level Variant Sets option:



Click image for full size.



Click image for full size.



Click image for full size.

Give it a unique name and double click to open the Variant Manager.

Start by creating a custom Variant Set. Click the + Variant Set button and name the new set:



Click image for full size.

Once the Variant Set is created, click the Add (+) button next to its name to create a Variant. This represents the Actors and properties that you want to change when the user selects this preset:



Click image for full size.

Click on the new Variant to highlight it and then click the + button in the Actors column. This will open a new window listing all of the Actors in your scene. Select the Actor that you want to change when the user selects this Variant. Repeat the process for each Actor that will be part of this preset:



Click image for full size.

Next, highlight the Actor that you would like to work with and click the Add (+) button in the Properties column. This will create a new window listing all the properties of the Actor that can be changed as part of the variant. Select the checkbox for each property that will be changed when the variant is selected:



Click image for full size.

This list includes both the default and any user defined properties. In the example above, the Env Map property has been selected. Changing this property will allow you to change the environment in the product configurator during runtime.

The last step is to set the value of the property. This can be completed one of two ways. The first is to manually set the value using the Values column:



Click image for full size.

You can also set the property using the value set in the level by right-clicking the property and selecting Record current value from the context menu to record the current value for your Variant.

As an alternative, pressing the Auto Capture button enables the auto-capture of properties. When activated, this option tells the Variant Manager to listen for changes made to Actors in the level and record them in the selected Variant. If the Actor being modified is not bound to the selected variant, it does so automatically.

Each Variant in a Variant Set also needs a thumbnail. These thumbnails are used as the button icon in the user interface and can be a texture image that is imported into the engine or captured from the viewport. Right click on a variant to open the menu:



Click image for full size.

Repeat this process for all Variants and Variant Sets.

Connecting to the BP_Configurator

To complete the process of customizing the template, your Level Variant Set needs to be connected to the BP_Configurator. Start by deleting the existing LevelVariantSet Actor from the level and replacing it with your own. The Actor must be in the level to be seen by the BP_Configurator:



Click image for full size.

In the Details panel, find the LVSActor option in the Default section of the menu and change the setting to your Level Variant Set using the drop down menu.

Finally, test you configurator:



Click image for full size.



Click image for full size.



Click image for full size.

How Does It Work?

Unreal Engine 4 SpeedTree Pipeline

This section is a copy of the documentation from SpeedTree's Wiki and only focus on the Unreal Engine portion of SpeedTree. For more information, see the SpeedTree Documentation.

Welcome to SpeedTree for Unreal Engine 4. The pages in this section detail how to use the SpeedTree tools and models to their maximum effect in your Unreal Engine 4 application.

How Does It Work?

Using SpeedTree with UE4 is a three step process:

Create or purchase a SpeedTree model. Whether you use models from the SpeedTree library or create one from scratch using the SpeedTree Modeler, you will need a model to get started. Models consist of the SpeedTree files (.srt) and the textures and component meshes (.obj, .fbx) associated with it. Click here to learn more about creating models in SpeedTree.

Import the model into UE4. SpeedTree models are imported into UE4 like any other asset. They come in as a Static Mesh with extra vertex attributes to implement wind and smooth LOD. You can do anything with them that you can do with a Static Mesh inside of UE4. Click here to learn more about import SpeedTree models into UE4.

Place models in your scene. Once imported, SpeedTree models can be placed or painted like any other Static Mesh. Click here to learn more about placing SpeedTree models in UE4.

Unreal Engine 4 SpeedTree Pipeline

Creating Models for UE4

Importing Models into UE4

Working with Models in UE4

Computing Lightmap UV Coordinates

Step 1: Switch to Lightmap Density Rendering Mode

Step 2: Pick a Lightmap Resolution

Step 3: Tune the Lightmap

Step 4: Pick the Lightmap Resolution in Unreal Engine 4

In order to use static lighting (Lightmass) in UE4, you must compute a set of unwrapped UV coordinates for the model. This UV mapping is referred to as the lightmap for the model. Getting a good lightmap is one part science and one part art. The following steps detail how to go about computing lightmap UV mapping in SpeedTree.



Model lightmap and density on the left; Lightmapped model in UE4 on the right.

Step 1: Switch to Lightmap Density Rendering Mode

Using the Render toolbar button, switch the rendering mode to Lightmap Density. Your display should look like the one in the image below.



This visualization shows how well your lightmap resolution is distributed across your model and is intended to closely match the same visualization mode in UE4 (Show -> Lightmap density). Green sections of the model represent ideal density. Blue indicates that the lightmap resolution is too low and may show artifacts when the lightmap is built in UE4. Red indicates the lightmap resolution is too high and is being wasted on that geometry.

The lightmap itself is rendered in the lower left hand corner. Select part of the model to see where it is represented in the lightmap. You can also select triangles in the lightmap to see which part of the model they come from. You want to use as much of the lightmap as possible, with big sections of the model getting big sections of the lightmap. More on how to achieve that later.

The units of the model matter in the visualization. Select the Tree generator and edit Lightmap:Scale to scale the model by the same amount you will in UE4 when you import it. The default value here matches the default value of the importer.

You can change how large the lightmap is rendered in the viewport by editing the corresponding property in the Window properties.

Step 2: Pick a Lightmap Resolution

The resolution of the lightmap is dependent on your project's requirements and the complexity of the tree. The goal is to use the lowest possible lightmap resolution that gives you adequate coverage given the model's placement in your scene.

Set the target lightmap resolution by selecting the Tree generator and editing the Lightmap:Resolution property. It may be possible that the model is too complex to fit in the resolution you have chosen. If so, you will get a warning in the output window and the resolution will be bumped to the smallest resolution that will give each node in the model at least one texel in the lightmap while maintaining the one texel border necessary to prevent rendering artifacts.

Step 3: Tune the Lightmap

Once you have picked a resolution, the next step is to tune how the lightmap is distributed across the model to make sure the parts of the model that need the most density have it. In general, you will want the most density in the trunk, low branches, and roots. This is the area most often seen by the player and the most prone to obvious artifacts if the density is too low. Leaves often have to have comparitively low density to fit the model in a reasonably small lightmap.

Use a combination of the following tools to tune the lightmap density distribution:

Reset - Select Tools -> Reset lightmap to set all lightmap scalars to 1.0 except the leaves. They are set to 0.0 so that each leaf gets exactly one texel and no more to start with (we will up that later).

Material Scales - Each material has a property called Unwrap scale. Increase or decrease this value to change the relative size of each piece of geometry that uses this material (very useful for caps).

Generator/Node Scales - Each generator/node combination that can house geometry has a Lightmap:Scale property. Change this value to change the size of the selected object's space in the lightmap. The distribution curve on branches can be used to shift the distribution of lightmap space on the object itself (without changing the actual lightmap area used). This curve is used to counteract the fact that branch lightmap density naturally increases near the tip as the geometry narrows but uses the same texture space.

Lightmap Resolution - If you just cannot make it work well in the resolution you have selected, you may need to bump it up by selecting a higher resolution like you did in Step 2. The layout will drastically change so you may need to do a reset and start over if it comes to this.

You can go into node editing mode and scale up individual branches, fronds, and leaves to tackle particularly troublesome areas.

Best Practice: Keep the leaves at zero until the branches are good. Then scale up the leaves to fill in all of the empty space.

Our algorithm aggressively tries to fit everything in the resolution you have selected. If you scale one component up so large that not everything will fit, the algorithm will adjust and change sizes to make it fit. If this happens, you may suddenly lose density where it was fine before. This effect can be counteracted by lowering the scale you just edited to get it back in range.

Step 4: Pick the Lightmap Resolution in Unreal Engine 4

When you import the model in UE4, it will have a default lightmap resolution of 64 like all Static Meshes. Select the mesh asset and enter the ligthmap resolution (Details -> Static Mesh Settings -> Lightmap Resolution) you used here. When you build lighting in UE4, you should have amazing results on some of the hardest types of geometry to lightmap!

Create Your Model

Get it Ready for Static Lighting

Add Wind to the Model

Add Levels of Detail to the Model

Compute Ambient Occlusion for the Model

Add Collision Object to the Model

Unreal Engine 4 SpeedTree Pipeline

Creating a model for use with UE4 can be as simple or as complex as your project requires. The following sections detail everything you can do with SpeedTree that can benefit you inside of UE4.

Create Your Model

Get started by creating your model at the highest level of detail using standard SpeedTree modeling. If you are new to SpeedTree, you might want to start here or have a look at some of our introductory videos. Do not forget, it is often easier to edit an existing model than it is to start from scratch.

When you save a model, several files are created. For example, if you were editing a model called "MyTree", these files are:

MyTree.spm - This is the SpeedTree model you are editing. It is the file you will open in the Modeler to make changes.

MyTree.srt - This is an optimized version of the model and the file you will import into UE4.

MyTree_Atlas.tga, MyTree_Atlas_Normal.tga - This is the texture atlas created from all of the untiled texture maps on your model and its associated normal map.

MyTree_Atlas_Billboards.tga, MyTree_Atlas_Billboards_Normal.tga - This is a billboard atlas that consists of 360 degree normal mapped images of your model. These can serve as the lowest LOD should you desire it.

Get it Ready for Static Lighting

If you are going to use static lighting in your scene, you will need to set up lightmapping uv coordinates. SpeedTree will automatically create a set of unwrapped UV texture coordinates for the model suitable for use with UE4's lightmass. If you are not going to use static lighting on your model, you can skip this step; otherwise, this step is essential. Click here for a detailed explanation of how to get the best lightmap for your model.

Add Wind to the Model

Wind animation in the SpeedTree modeler will carry over to UE4. The best way to get good settings for your model is to start with the Wind Wizard. This utility will apply wind settings based on your answers to a few simple questions. From there, select the "Fan" object and fine tune the wind behavior by editing the properties.

Of particular importance is the Style property in the Presets group. This property sets the wind complexity and has a direct impact on the vertex shader performance in UE4. Options are detailed below and are ordered from low quality/short shaders to high quality/longer shaders:

None - No wind shader code will be executed in UE4. This is the absolute fastest way to render a SpeedTree model and still get camera facing geometry (should you need it) and smooth LOD transitions.

Fastest - The model will sway back and forth but will not have individual branch or leaf motion.

Fast - The model with sway back and forth and leaves will ripple.

Better - The model will sway, leaves will ripple, and branches will move independently.

Best - The model will sway, leaves will ripple and tumble, and branches will move independently.

Palm - Fronds will whip and move in the direction of the wind (leaves behave like "Best").

You can back the effect down in the UE4 material editor, but you cannot go higher than what you set in the Modeler. It is often a good idea to tune the model using Best or Palm and lower the complexity in UE4 if you need to optimize performance.

Add Levels of Detail to the Model

LODs are added by selecting the Tree generator and checking the Enabled property in the Level of Detail group. Set the number of LODs in this section as well. Each generator has an LOD group that controls how that part of the model degrades. Click here for more information on how to edit LODs on your model.

Compute Ambient Occlusion for the Model

SpeedTree will compute a per-vertex ambient occlusion value for your model. These values can be hooked to UE4's material ambient occlusion system or to anything else in the material shader. Click here for more information on computing ambient occlusion.

Add Collision Object to the Model

A series of spheres and capsules can be added to the model to use as collision volumes in UE4. The quickest way to get started with collision objects is by selecting "Tools -> Generate collision primitives…" and letting SpeedTree add some automatically. Click here for more information.

Unreal Engine 4 SpeedTree Pipeline

Creating Models for UE4

Importing Models into UE4

Working with Models in UE4

Computing Lightmap UV Coordinates

When you save a model in the UE4 version of the Modeler (or use the compiler for custom licensees), you should have a .srt file that represents your model. This is the file you will import into the UE4 Editor. The SpeedTree model will be imported into a normal Static Mesh object. Click here if you do not have an .srt file.

Import the .srt file as you would any other asset. You may want to make a folder for your model to keep the resulting assets organized as pictured below. Press Import to import your model.



You have a number of options during import that are presented to you in the import dialog. First is the choice between 3D geometry, billboards, or both. If a tree will only be used close-up, it is a "hero" tree, or you otherwise have trouble with the billboard as the lowest LOD (as is sometimes the case with dynamic shadows falling on the flat billboard geometry), you can choose to ignore the billboard mesh. Or, if a tree will only be used far away and you want to save loading the 3D geometry, you can only import the billboard. Just importing the billboard mesh also creates a Static Mesh that can be used with UE4's foliage layers.

In the import dialog, you can also choose to include detail, specular, and branch seam blending in the materials used on the 3D tree. You can also add vertex processing to the materials, which puts a special SpeedTree node into the material that can handle wind, billboarding, and other effects computed per-vertex on the tree.

Finally, you can import any collision primitives that were set up in the SpeedTree Modeler into collision information on the new SpeedTree mesh.



Once the import process is complete, you should have the following new assets (pictured below):

A Static Mesh that represents your model. You can edit options on this asset like you would any other Static Mesh (e.g., LOD ranges, lightmap resolution, etc.).

Texture assets for each atlas, billboard atlas, and tiling texture map on your model.

Material assets for each component (draw call) of the model.



The materials are of particular importance. It is important to note that you are completely free to edit the materials generated by the importer. These materials get the basics in place but can be improved and tailored to suit your scenes.

The SpeedTree node connected to "World Position Offest" (pictured below) is the only SpeedTree specific component. If you disconnect it, everything rendered with that material will be identical to a Static Mesh. With it connected, you will get SpeedTree wind and smooth LOD transitions. There are several options available on the SpeedTree node:

Geometry Type - This setting controls what type of geometry is rendered and is set automatically. This value rarely needs to be edited.

Wind Type - This property controls the complexity/quality of the wind shader applied to the material. This value matches what you set in the Modeler on import. If vertex processing performance is an issue, this is a good way to reduce the vertex overhead on SpeedTree objects quickly.

LOD Type - Use this to control whether SpeedTree models smoothly transition between LOD states or pop between them like standard Static Meshes.

Billboard Threshold - Billboards are modeled as a cluster of planes, each with a different billboard image applied. Use this property to control how quickly each plane disappears based on its viewing angle.

The SpeedTree Color Variation node (also pictured below) adds color variation to the material based on the models position/orientation. Use this to add subtle color change effects without adding multiple tree models.



Wind

Level of Detail

Once you have imported the model as an asset, you can place it in your scenes like you would any other Static Mesh. The most common methods are:

Place them manually. Simply drag the asset and drop it in the scene to place a model. This gives you the most flexibility in how it is lit. Setting the mobility to Static will disable the ability to move the SpeedTree at runtime but will allow it to be lit by Lightmass in addition to dynamic lights. Setting it to Movable will enable you to move the SpeedTree around at runtime but it will not be able to receive static lighting.



Paint them as foliage - Drag the asset to the foliage painting area and paint the models like any other Static Mesh.



Painted geometry is instanced and renders very quickly; however, you will need to enable Lightmaps for the instances and possibly set a lower lightmap resolution. Keep this in mind as you populate your scenes.

Wind

Add wind to the scene by adding a wind direction source object (Select Window -> Class Viewer, search for "WindDirectionalSource", and drag it into the scene). The Speed property defaults to 0.1. Increase this value to something like 1.0 to start with have stronger winds. There are also other properties for Strength and Min/Max Gust Amount.

Level of Detail

LOD transitions are based on screen space area in UE4. These values are edited by editing the Static Mesh asset associated with the SpeedTree model. Default values are chosen upon import that work for typical situations.

Unreal Engine 4 SpeedTree Pipeline

Creating Models for UE4

Importing Models into UE4

Working with Models in UE4

Computing Lightmap UV Coordinates

Localization and Internationalization

ICU and Internationalization Support

Cultures

Chinese

Spanish

Localization Targets

Localization Pipeline

PO File Format

Packaging Localization Data

Localization and Internationalization

Localization and Internationalization (L10N and I18N) are two concepts that are often combined under the umbrella of "localization". However, they are two distinct things, and Unreal Engine 4 (UE4) handles them in different ways. The localization system in UE4 is centered around our "text" type, whereas our internationalization support makes use of the International Components for Unicode (ICU) library.

While they are separate, in UE4 you cannot have localization at runtime without the appropriate internationalization support.

ICU and Internationalization Support

ICU is a mature and robust internationalization library that UE4 uses to deal with anything involving culture-specific data or processing, including the following:

Obtaining the current culture for the platform/OS.

Handling the prioritized fallback of cultures.

Handling the culture correct formatting of numbers (including percentages and currency), and dates and times (including timezone data).

Handling the culture correct plurarity of numbers (during text formatting).

Handling Unicode compliant transformation of text (eg, ToUpper, ToLower).

Handling Unicode compliant comparison and collation of text.

Handling Unicode compliant boundary analysis (characters, words, and line-breaks).

Handling Unicode compliant bi-directional (BiDi) text detection.

The culture-specific data that ICU needs to function is stored outside of ICU itself, and UE4 provides some coarse data sets that you can use to minimize your project size:

English (~1.77MB)

EFIGS - English, French, Italian, German, and Spanish (~2.38MB)

EFIGSCJK - English, French, Italian, German, Spanish, Chinese, Japanese, and Korean (~5.99MB)

CJK - Chinese, Japanese, and Korean (~5.16MB)

All (~15.3MB)

Which one of these you choose depends on what regions you localize your project for, and these choices can be set in your Project Settings. See Packaging Localization Data for more information.

Cultures

Cultures in UE4 contain internationalization information for a particular locale. Culture names are composed of three hyphen-separated parts (an IETF language tag):

A two-letter ISO 639-1 language code (such as "zh").

An optional four-letter ISO 15924 script code (such as "Hans").

An optional two-letter ISO 3166-1 country code (such as "CN").

When UE4 looks for localization data for a particular culture, it processes them from most to least specific. For example:

zh-Hans-CN is processed as "zh-Hans-CN", then "zh-CN", then "zh-Hans", then "zh".

en-GB is processed as "en-GB", then "en".

In order to achieve the widest coverage for a particular culture, use the least specific culture code that is valid. Usually that is just the language code, but you should be aware of regional language variations that need to be considered.

In most cases these regional variations are limited to a specific country code, which makes them easy to resolve. However, there are some more complex cases as shown below.

Chinese

Chinese has two variants, Simplified and Traditional, represented by the "Hans" and "Hant" ISO-15924 script codes. Use "zh-Hans" for your Simplified localization, and "zh-Hant" for your Traditional localization.

Spanish

Spanish has two main variants: European and Latin American. However, there is no convenient script code that can be used to distinguish one from the other. There is an IETF language tag for Latin American Spanish ("es-419"), but most platforms will not provide this, and instead will give you an actual country code ("es-MX").

To solve this, use "es" for European Spanish, and "es-419" for Latin American Spanish. Then use the culture remapping feature of UE4 to map the Latin American Spanish speaking countries to "es-419".

This can be done by adding the following to your DefaultGame.ini file:

Localization Targets

Localization Targets are named, self-contained modules of localization data. Localization Targets have the following properties:

They have text gathered from a specified set of sources;

They are stored in a manifest file;

They are translated in culture-specific archive files;

They are compiled into culture-specific localization resource files, and the compiled culture-specific resource files are what the system displays.

A project can have a single Localization Target for simplicity, or it can have multiple Localization Targets in order to break up the project's localization data into sections. The Unreal Editor has a separate Localization Target from the rest of UE4, so that the Editor can be localized without distributing that localization data with games. Typically, a game will have one Localization Target for all of the base project's localization data, and additional Localization Targets for any expansions.

Localization Pipeline

The UE4 localization pipeline is modeled around an "author-at-source" approach to localization. This means that if you need some text saying "Hello World!" in your UI, you just type "Hello World!" into the text property (or use the NSLOCTEXT or LOCTEXT macros in C++) and the localization gatherer takes care of capturing the text so that it can be localized.

The "author-at-source" approach is very dynamic, and this approach allows developers to avoid thinking much about localization during development. However, it can also be frustrating for teams that want strict control over the text used in their project. To address this, UE4 has support for String Tables to allow an "author-once-and-reference" approach to localization (although internally, the pipeline just treats String Tables as another "author-at-source" source).

An older (and no longer supported) method to work around the lack of native String Tables was to use a "fake" native culture (most likely "es-US-POSIX") with IDs as the source text, and then use the string collapsing functions UE4 had prior to version 4.14 to translate these IDs into each language. You may find references to this method in older support questions, but it should no longer be used. Projects using that method should migrate to String Tables.

The localization pipeline itself works on Localization Targets, and a Localization Target is made up of two parts: its configuration (stored in Config/Localization/), and its data (stored in Content/Localization/{TargetName}/).

If we assume a Localization Target working with English ("en") and French ("fr"), then its layout in the Content/Localization/ folder would look like this:

All of the above files and folders are generated by the various parts of the localization pipeline.

Folder

Description

{TargetName}.manifest

Manifests are custom JSON files that store all of the text gathered from your source code and assets by the localization pipeline.

Manifests are re-generated each time the localization gather step is run, and shouldn't be hand-edited.

{TargetName}.archive

Archives are custom JSON files that store per-culture translations for the text gathered into the manifest.

Archives are trimmed each time the localization gather or import steps are run to remove entries for old sources.

Archives can be hand-edited, but we strongly suggest that you do not hand-edit. Our recommended workflow is to edit the exported PO files and re-import them.

{TargetName}.po

PO (Portable Object) files contain the per-culture text to be translated, along with their current translations.

PO files are generated by the localization export text step, and are re-imported into the archives by the localization import text step.

PO is a common format, and may be edited locally either by-hand or via a translation tool like Poedit, or collaboratively via something like OneSky or XLOC.

{TargetName}.locres

LocRes are custom binary files that store the compiled per-culture translations for use at runtime.

LocRes files are re-generated each time the localization compile step is run, and get staged into a packaged build.

LocRes are the only files that your project will load localization data from at runtime (including in the editor), so any edits or changes to your source data (such as from importing a PO file) must be compiled before they take effect.

{TargetName}.locmeta

LocMeta are custom binary files that store the compiled target meta-data (currently only the native culture for the target) for use at runtime.

LocMeta files are regenerated each time the localization data is compiled, and is staged into a packaged build.

Localization Targets also specify a "native" culture, which should be set to the culture that you author your content in (commonly referred to as your "source text" or "source data").

Native cultures can contain "translations" just like any other culture, although native culture translations only exist to facilitate copy-editing your source text without editing the source code or assets directly.

Foreign cultures use the native culture text as their source text for translation, and will become "stale" if the native culture text is changed (there's a setting in the localization compile step to allow stale translations if required).

For more information on optimizing your localization pipeline, see Pipeline Optimization.

PO File Format

Unreal uses the following default format for its PO files, depending on the collapse mode being used in the PO export.

When using the Identical Text Identity and Source Text collapse mode:

msgctxt contains the Unreal identity of the entry.

msgid contains the source string.

msgstr contains the translation.

When using the Identical Namespace and Source Text collapse mode:

msgctxt contains the Unreal namespace of the entry.

msgid contains the source string.

msgstr contains the translation.

We also have an alternative format that produces better results if you're using Crowdin to manage your translations, though please note that this format isn't able to detect stale translations imported from PO files (as we no longer have the source the translation was made against).

This mode produces the same output when using the Identical Namespace and Source Text collapse mode, but for the Identical Text Identity and Source Text collapse mode it produces the following:

msgctxt is unused.

msgid contains the Unreal identity of the entry.

msgstr contains the source string (for the native culture), or the translation (for foreign cultures).

X-Crowdin-SourceKey header attribute specifies that msgstr is used as the source text from the native culture.

Packaging Localization Data

Packaging the correct localization and internationalization data for your project requires adjusting some settings under the advanced Packaging section of your Project Settings.

The two settings you'll want to verify are:

Localizations to Package - With this you can choose which cultures you want to stage localization data for. You can use the Show Localized option to filter the list to only show cultures that you have LocRes files for.

Internationalization Support - With this you can choose which set of ICU internationalization data you want to stage. This option must overlap with the localization data you intend to stage.



Text Literals

Creating Text Literals in C++

Creating Text Literals in INI Files

Creating Text Literals in Assets

Text Formatting

Text Formatting in C++

Text Formatting in Blueprints

Argument Modifiers

Plural Forms

Gender Forms

Hangul Post-Positions

Text Formatting Best Practices

Text Generation

Numerical Text Generation

Numerical Generation in C++

Numerical Generation in Blueprints

Chronological

Chronological Generation in C++

Chronological Generation in Blueprints

Transformative

Transformative Generation in C++

Transformative Generation in Blueprints

String Tables

Text Value Marshalling

Data Tables

Polyglot Data

Polyglot Data in C++

Polyglot Data in Blueprints

Localized Text Sources

Text in Unreal Engine (UE) is the primary component for localization. It is a specialized string, represented by the [`FText`] type in C++. This should be used when you have user-facing text that needs to be localized.

Internally, FText is implemented as a TSharedRef to an ITextData. This makes it very cheap to copy, and the FTextSnapshot utility provides an efficient way to detect if a cached FText value has actually changed.

The data held within FText instances varies, depending on how the FText was created. This variance is handled by the internal "text history" (FTextHistory). Text histories support the culture-correct rebuilding of text, and and also form the key component for the following:

Live culture switching.

Sending FText over the network.

Creating culture invariant sources.

Converting FText to FString is typically a lossy operation, as it loses the text history. It should only be done if you no longer need the localization data. For example, if there is a lower-level API that works on strings, which is managed by a higher-level API that watches for text changes (such as STextBlock). This conversion can also be used when passing the data into an external API that only accepts strings.

If you need text that not localizable (such as converting a player name from an external API into something you can display in your UI), you can use FText::AsCultureInvariant, which produces an FText instance that has no localization data (and cannot be localized). The INVTEXT macro can do the same thing for literal strings.

Text Literals

Localizable text is made up of three components: a namespace; a key (which form its identity); and a source string (which is the basis of what gets translated, and acts as validation against "stale" translations). The most common way to create localizable text in UE is by using a text literal.

Creating Text Literals in C++

Text literals can be created in C++ by using the LOCTEXT family of macros.

Text Literal Macros

Macro

Description

NSLOCTEXT

Creates a localized piece of text by defining the namespace, key, and source string.

LOCTEXT

Creates a localized piece of text by defining the key and source string, with the namespace being defined with LOCTEXT_NAMESPACE.

Example:

Creating Text Literals in INI Files

Text literals can be created in INI files using the NSLOCTEXT macro syntax.

Creating Text Literals in Assets

Text literals can be created using FText properties. A key is generated for you automatically, but you can define a custom namespace or key for your text by using the advanced combo next to the text field. It is also fine to use the default namespace or key.

Text Formatting

Text formatting provides a way to combine text in a way that is easier to localize, by using a localizable format pattern that injects real text to replace format placeholders.

Format placeholders are contained within a pair of curly braces, and can be numbers (for index-based formatting) or strings (for name-based formatting). For example:

"You have {0} health left.""You have {CurrentHealth} health left."

Format placeholders can also specify a function (called an "argument modifier") to run on their argument data. These are specified as a pipe followed by the function name and arguments. For example:

"{NumCats} {NumCats}|plural(one=cat,other=cats)"

The backtick (`) character can be used to escape curly braces and pipes to avoid them being treated as formatting markup. It can also be used to escape itself to produce a literal ` character.

Example:

"Result `{ {Res} }" formatted with Res set to 10 would produce "Result { 10 }"

"Result \\{Res}\\" formatted with Res set to 10 would produce "Result \10\"

Text Formatting in C++

Text formatting in C++ is handled by the FText::Format family of functions. Each function takes an FTextFormat pattern, which will implicitly construct from an FText instance, followed by additional arguments as defined in the table below.

Argument

Formatting Type

Description

FText::Format

General text formatting.

Either accepts index-based arguments (using FFormatOrderedArguments or variadic arguments), or name-based arguments (using FFormatNamedArguments).

FText::FormatOrdered

Variadic index-based formatting.

Accepts any arguments that FFormatArgumentValue can construct from.

FText::FormatNamed

Variadic name-based formatting.

Accepts consecutive name (anything that FString can construct from) then value (anything that that FFormatArgumentValue can construct from) arguments.

You should consider pre-compiling format patterns you use frequently into an FTextFormat to improve formatting performance. The compiled pattern will automatically recompile if the active culture changes.

Text Formatting in Blueprints

Text formatting in Blueprints is handled by the Format Text node. This node can either take a literal format pattern, or the node can have the pattern linked to another Text pin.

When a literal format pattern is specified, the format argument pins will be generated automatically.

When the format pattern is linked to another Text pin, you must manually specify the arguments for the format using the Details panel of the node.





Argument Modifiers

Argument modifiers provide a way to pre-process an argument before it gets added to the formatted string. Argument modifiers are extensible. You create an argument modifier by implementing the ITextFormatArgumentModifier interface, and registering a factory function for a given keyword (see FTextFormatter::RegisterTextArgumentModifier).

UE provides some argument modifiers by default: there are modifiers for plurality, gender, and Hangul post-positions.

Plural forms allow you to use different text based upon a numeric variable given to your text format. Plural forms may be cardinal (such as "There is 1 cat" or "There are 4 cats"), or ordinal (such as "You finished 1st!" or "You finished 2nd!"). Plural forms are specified as key-value pairs, and support any of the following keywords (as defined for your culture by the CLDR data): zero, one, two, few, many, other. Values are an optionally quoted string, that can also contain format markers.

Cardinal Format Example:

Ordinal Format Example:

Gender forms allow you to use different text based on an ETextGender value given to your text format, such as "Le guerrier est fort" or "La guerrière est forte". Gender forms are specified as a list of values in the order of [masculine, feminine, neuter], where neuter is optional. Values are an optionally quoted string that may also contain format markers.

Format Example:

Hangul post-positions help you follow the grammar rules present in Korean, and will insert the correct glyph(s) based on whether the value being inserted ends in a consonant or a vowel, such as "사람은" or "사자는". Hangul post-positions are specified as a list of values in the order of [consonant, vowel]. Values are an optionally quoted string.

Format Example:

Text Formatting Best Practices

When injecting a number that affects the sentence, handle these variances using the plural forms argument modifiers, rather than branching in code. When you use plural forms, the sentence is correctly translated for languages that do not share the plural rules of your source language.

When injecting a personal noun, make sure you include an argument for the gender of the person. This is important for languages with grammar rules for gender, as it allows your translators to switch their translation based on the gender (see Gender Forms).

Avoid injecting nouns for objects (such as "table," "door," or "chair"), or be prepared to make them localizable. These nouns might have one gender in one language, and a different gender in another language. This makes the format pattern string impossible to accurately localize without per-culture metadata. Ideally, you should include full sentences rather than just the noun. This will ensure accurate translations.

Future versions of UE might include a function for translators to use metadata to tag text that represents nouns, that they can later branch on in format patterns to produce accurate translations.

Avoid concatenating partial sentences. This can cause problems, as it is possible for each clause or part to be translated correctly and yet the translation of the whole could be incorrect. It is better to rewrite the text into full sentences, so you can ensure correct translation.

Text Generation

Text generation uses internationalization data to produce culture-correct text that doesn't rely on direct localization. There are three types of text generation: numerical, chronological, and transformative.

Numerical Text Generation

Numerical generation is used to convert numeric types into a text representation that is friendly for humans to read. The exact rules for this are culture-specific, and can also be tweaked on a per-generation basis if more specific control is required.

As an example, under the default generation rules, the floating-point number "1234.5" would generate as "1,234.5" under English, "1 234,5" under French, and "١٬٢٣٤٫٥" under Arabic.

Numerical generation in C++ is handled by the following functions.

Function

Description

FText::AsNumber

Converts any numeric type supported by UE into a user-friendly text representation ("1234.5" becomes "1,234.5").

FText::AsPercent

Converts a float or double into a percentage text representation ("0.2" becomes 20%).

FText::AsMemory

Converts a value (in bytes) to a user-friendly memory representation ("1234" becomes "1.2 KiB").

FText::AsCurrencyBase

Converts a value in the base representation of a currency into a user-friendly currency representation ("123450" for "USD" becomes "$1,234.50").

Most of the functions in the table take an optional [FNumberFormattingOptions](https://api.unrealengine.com/INT/API/Runtime/Core/Internationalization/FNumberFormattingOptions/index.html) to control the output (the default is taken from the active locale), and also an optional culture (default is the active locale).

Numerical generation in Blueprints is handled by the following nodes.

Nodes

Description

ToText (byte), ToText (integer), ToText (float)

Converts the supported numeric types into a user-friendly text representation ("1234.5" becomes "1,234.5").

AsPercent

Converts a float or double into a percentage text representation ("0.2" becomes 20%).

AsCurrency

Converts a value in the base representation of a currency into a user-friendly currency representation ("123450" for "USD" becomes "$1,234.50").

Most of the nodes in the table take advanced arguments to control the output.

Chronological

Chronological generation is used to convert date and time types into a text representation that is friendly for humans to read. The exact rules for this are culture-specific, and the date/time style can be adjusted on a per-generation basis if more specific control is required.

Under the default generation rules, a date representing the 22nd day of the 5th month of the year 1998 would generate "May 22, 1998" under English (United States), "22 May 1998" under English (United Kingdom), "22 mai 1998" under French, and "٢٢‏/٠٥‏/١٩٩٨" under Arabic.

Chronological generation in C++ is handled by the following functions.

Function

Description

FText::AsDate

Converts a FDateTime value to a user-friendly date representation.

FText::AsTime

Converts a FDateTime value to a user-friendly time representation.

FText::AsDateTime

Converts a FDateTime value to a user-friendly date and time representation.

FText::AsTimespan

Converts a FTimespan value to a user-friendly delta-time representation (in hours, minutes, and seconds).

Most of the above take EDateTimeStyle to control the output (default is taken from the active locale, but may be set as "short", "medium", "long", or "full").

Time generation expects to be given a UTC-based time by default (which it will convert to the local timezone). If the given time is not UTC-based (such as if it is already in local time), then you should pass [FText::GetInvariantTimeZone()](https://api.unrealengine.com/INT/API/Runtime/Core/Internationalization/FText/GetInvariantTimeZone/index.html) as the timezone argument.

Chronological generation in Blueprints is handled by the following nodes.

Nodes

Description

AsDate

Converts a non-UTC-based "DateTime" value to a user-friendly date representation as-is (without adjusting to the local timezone).

AsDate (from UTC)

Converts a UTC-based "DateTime" value to a user-friendly date representation (adjusting to the local timezone).

AsTime

Converts a non-UTC-based "DateTime" value to a user-friendly time representation as-is (without adjusting to the local timezone).

AsTime (from UTC)

Converts a UTC-based "DateTime" value to a user-friendly time representation (adjusting to the local timezone).

AsDateTime

Converts a non-UTC-based "DateTime" value to a user-friendly date and time representation as-is (without adjusting to the local timezone).

AsDateTime (from UTC)

Converts a UTC-based "DateTime" value to a user-friendly date and time representation (adjusting to the local timezone).

AsTimespan

Converts a "Timespan" value to a user-friendly delta-time representation (in hours, minutes, and seconds).

Transformative

Transformative generation is used to convert text into a different representation of itself. For example, you can convert lower case text to upper case text, or convert upper case text to lower case text.

Transformative generation in C++ is handled by the following functions.

Function

Description

FText::ToLower

Converts a FText instance to its lowercase form in a unicode compliant way.

FText::ToUpper

Converts a FText instance to its uppercase form in a unicode compliant way.

Transformative generation in Blueprints is handled by the following nodes.

Node

Description

Text to Lower

Converts a "Text" instance to its lowercase form in a unicode compliant way.

Text to Upper

Converts a "Text" instance to its uppercase form in a unicode compliant way.

String Tables

String Tables provide a way to centralize your localized text into one (or several) known locations, and then reference the entries within a string table from other assets or code in a robust way that allows for easy re-use of localized text.

String Tables can be defined in C++, loaded using a CSV file, or created as an Asset. See the String Tables page for more information.

Text Value Marshalling

Text values can be losslessly marshalled as strings (using FTextStringHelper, or the ImportText and ExportText functions of UTextProperty).

The following formats are supported:

Text Literal

Description

NSLOCTEXT

A text literal that specifies the namespace, key, and source string.

LOCTEXT

A text literal that specifies the key, and source string.

LOCTABLE

A String Table reference.

INVTEXT

A piece of culture-invariant text (see FText::AsCultureInvariant).

LOCGEN_NUMBER

A piece of text generated from a number (see FText::AsNumber).

LOCGEN_NUMBER_GROUPED

A piece of text generated from a number with grouping enabled (see FText::AsNumber and FNumberFormattingOptions::DefaultWithGrouping).

LOCGEN_NUMBER_UNGROUPED

A piece of text generated from a number with grouping disabled (see FText::AsNumber and FNumberFormattingOptions::DefaultNoGrouping).

LOCGEN_NUMBER_CUSTOM

A piece of text generated from a number with custom formatting options (see FText::AsNumber and FNumberFormattingOptions).

LOCGEN_PERCENT

A piece of text generated from a number as percentage (see FText::AsPercent).

LOCGEN_PERCENT_GROUPED

A piece of text generated from a number as a percentage with grouping enabled (see FText::AsPercent, and FNumberFormattingOptions::DefaultWithGrouping).

LOCGEN_PERCENT_UNGROUPED

A piece of text generated from a number as a percentage with grouping disabled (see FText::AsPercent, and FNumberFormattingOptions::DefaultNoGrouping).

LOCGEN_PERCENT_CUSTOM

A piece of text generated from a number as a percentage with custom formatting options (see FText::AsPercent, and FNumberFormattingOptions).

LOCGEN_CURRENCY

A piece of text generated from a number as a currency (see FText::AsCurrencyBase).

LOCGEN_DATE_UTC

A piece of text generated from a UTC date adjusted to the specified or local timezone (see FText::AsDate).

LOCGEN_DATE_LOCAL

A piece of text generated from a non-UTC date without timezone adjustment (see FText::AsDate).

LOCGEN_TIME_UTC

A piece of text generated from a UTC time adjusted to the specified or local timezone (see FText::AsTime).

LOCGEN_TIME_LOCAL

A piece of text generated from a non-UTC time without timezone adjustment (see FText::AsTime).

LOCGEN_DATETIME_UTC

A piece of text generated from a UTC date and time adjusted to the specified or local timezone (see FText::AsDateTime).

LOCGEN_DATETIME_LOCAL

A piece of text generated from a non-UTC date and time without timezone adjustment (see FText::AsDateTime).

LOCGEN_TOLOWER

A piece of text converted to lowercase in a unicode compliant way (see FText::ToLower).

LOCGEN_TOUPPER

A piece of text converted to uppercase in a unicode compliant way (see FText::ToUpper).

LOCGEN_FORMAT_ORDERED

A piece of text generated from a formatting pattern using index-based arguments (see FText::FormatOrdered).

LOCGEN_FORMAT_NAMED

A piece of text generated from a formatting pattern using name-based arguments (see FText::FormatNamed).

"Raw" strings can also be imported, but a new key will be generated for each import. This produces unstable keys for localization.

Data Tables

One common cause of unstable localization keys is iteratively importing raw strings from a CSV file into a Data Table, as this causes a new key to be generated after each import. A solution for this is to assign the imported text a deterministic key post-import by overriding the OnPostDataImport function on your row struct, and calling FText::ChangeKey to assign the new key.

Typically we use the data table name as the namespace, and a combination of the row name and property name as the key. For example:

As of the 4.22 release, deterministic keys are already applied to any raw strings imported into a Data Table, but you can still override OnPostDataImport if you need custom keying behavior.

Polyglot Data

Polyglot data allows new localization data to be added at runtime, either to interface with an external system, or to allow hot-fixing localization without building new LocRes files.

Polyglot data is comprised of: a namespace and key (its identity); a native string; the category of the text (such as game, engine, editor), to control when the polyglot data is used; an optional native culture (which will fallback to the native culture of the category if unset); and a series of per-culture translations.

If you want to use polyglot data to override an existing translation, then you must ensure the namespace, key, and native string of the polyglot data matches that of the source text you intend to replace.

Polyglot Data in C++

Polyglot data in C++ is represented by the FPolyglotTextData type, and it can either be used directly (using FPolyglotTextData::GetText to resolve the polyglot data into a text instance), or it can be passed to FTextLocalizationManager::RegisterPolyglotTextData (to patch existing text entries).

Polyglot Data in Blueprints

Polyglot data in Blueprints is represented by the Polyglot Text Data type, and can be used with the Polyglot Data to Text function to resolve the polyglot data into a text instance.

Localized Text Sources

Localized text sources are the primary way that the UE text localization manager discovers and processes localized text data. UE provides two of these by default: FLocalizationResourceTextSource (which hosts LocRes support), and FPolyglotTextSource (which hosts polyglot data support).

Localized text sources can provide a way to interface with an external system, and can be added on a per-project basis by creating and registering a type derived from ILocalizedTextSource.

Creating String Tables

Creating String Tables in C++

Creating String Tables Using CSV

Creating a String Table Asset

Referencing a String Table

Referencing a String Table in C++

Referencing a String Table in the INI File

Referencing a String Table Asset

Redirecting a String Table

Redirecting a String Table in the INI File

Redirecting a String Table Asset

String Tables provide a way to centralize your localized text into one (or several) known locations, and then reference the entries within a string table from other assets or code in a robust way that allows for easy re-use of localized text.

Creating String Tables

String Tables can be defined in C++, loaded using a CSV file, or created as an Asset.

Creating String Tables in C++

String Tables can be created in C++ by using the LOCTABLE family of macros.

Macro

Description

LOCTABLE_NEW

Creates an empty string table instance.

LOCTABLE_FROMFILE_X

Creates a string table instance and populates it from the given CSV file. When using the _ENGINE variant, the file is relative to the Engine content directory, and when using the _GAME variant, the file is relative to the project content directory.

LOCTABLE_SETSTRING

Sets an entry in a string table.

LOCTABLE_SETMETA

Sets optional meta-data for an entry in a string table.

Example:

Creating String Tables Using CSV

String Tables defined in CSV can be loaded using the LOCTABLE_FROMFILE_X macros, or can also be imported to/exported from a String Table asset.

Example:

The CSV format used for string tables has two mandatory columns, "Key" and "SourceString," with any extra columns being parsed as meta-data for your string table entries.

Quotes in CSV files are escaped using two sets of quotes ("") rather than C-style escaping (\"), however other control characters in your string (including tabs and new-lines) should be escaped using C-style escaping.

CSV string tables loaded using the LOCTABLE_FROMFILE_X macros are monitored for changes, and are automatically re-imported if they change on the disk (this is for Editor builds only).

CSV string tables aren't staged automatically. It is recommended that you place your CSV string tables in a known folder and then add them to the Additional Non-Asset Directories to Package in your project's Packaging settings.

Creating a String Table Asset

String Table assets can be created using the Content Browser (Add > Miscellaneous > String Table), and can be managed through the String Table editor. The String Table editor cannot currently edit meta-data, however any meta-data imported from a CSV file is preserved.



String Table assets are binary, so they cannot be resolved if a merge conflict happens. We recommend that you keep the String Table assets more granular than when you are using C++ or CSV to minimize your conflict domain.

Referencing a String Table

You can reference string tables in C++, in INI files, or as an Asset.

Referencing a String Table in C++

String Tables can be referenced in C++ using either the LOCTABLE macro, or the static FText::FromStringTable function. The underlying logic is identical, although the macro is easier to type but will only work with literal values, whereas the function will work with both literal and variable arguments.

Referencing a String Table in the INI File

String Tables can be referenced in INI files using the LOCTABLE macro syntax.

Referencing a String Table Asset

String Tables can be referenced using FText properties.

Click the white arrow next to a text property to link that property instance to a string table entry, instead of defining your localized text inline.

Redirecting a String Table

We recommend that you avoid renaming or moving string tables when possible. However, if you need to rename or move a string table, there is a way to redirect whole tables, and to redirect individual keys. You can do this in INI files, or by redirecting a String Table Asset.

Redirecting a String Table in the INI File

String Tables can be redirected using an INI file. The following example will redirect an entire string table to point to another string table:

If you want to redirect an entry in one string table to an entry in another string table, use the following example:

Redirecting a String Table Asset

Moving or renaming a String Table Asset will leave an Asset Redirector behind. This is processed and followed like any other Asset Redirector.

Localizing Fonts

Localizing Dialogue

Creating Asset Groups

Asset localization allows you to completely replace one Asset with another on a per-culture basis.

Localized Assets exist in per-culture folders under the "L10N" folder within your project Content folder. So if you have an Asset named /Game/MyFolder/MyAsset and you want to localize the Asset for French ("fr"), then the localized Asset would be /Game/L10N/fr/MyFolder/MyAsset.

The Content Browser has options to help you manage localized Assets. These can be found under the Asset Localization sub-menu. To create or manage localized Assets using the Content Browser options, you must have LocRes files available for the cultures you are localizing for. Localized Assets are hidden by default in the Content Browser. Click View Options > Show Localized Assets to view them.

Localized Assets are not hot-reloaded if the culture is changed at runtime, as content hot-reloading is only available in the Editor. If you plan to support dynamic culture changing at runtime, you might need to restart your game for those changes to take effect. Restarting the game purges and reloads the localized Assets.

Assets containing bytecode (such as Blueprints) cannot be localized, as these can be nativized into C++. These Assets cannot be replaced at runtime.

Localizing Fonts

Font localization can happen in one of two ways:

You can use composite fonts to produce a single font Asset that works for all cultures.

You can use Asset localization to produce separate font Assets for each culture.

The second option is only recommended if your project doesn't support dynamic culture changing at runtime, and doesn't display any unrestricted user-defined text (such as player names, or a chat window). In all other cases the first option will provide a better result.

Localizing Dialogue

Dialogue localization is centered around the Dialogue Wave Asset type, which allows you to define spoken text (and optional subtitle overrides) that are gathered through the standard localization pipeline gather step.

Dialogue Waves themselves are not a full dialogue or conversation system. They simply provide a way to say "Line X is spoken from person A to persons B, C, or D", using a designated Sound Wave for each combination. The number of unique Sound Waves that you need for each language might vary, depending on the rules of the language. However, that concern is encapsulated within the Dialogue Wave. As a result, you only need to play it with the correct context, and you'll get the accurately localized result.

Unreal Engine 4 (UE4) also provides a series of utilities to aid in the recording and management of localized dialogue. You do not have to use these utilities to localize dialogue in UE4, but they do automate a lot of the work.

If you use these utilities, the utilities will generate an extra per-culture file in the content folder of your localization target, called {TargetName}Dialogue.csv. Dialogue Sheets are custom CSV files that contain the per-culture lines of dialogue gathered from your Assets by the localization pipeline. They are generated by the localization export script step, and are re-imported into the archives by the localization import script step.

Keep in mind the following information about Dialogue Sheets:

The SpokenDialogue field can be copy-edited during recording and re-imported as the current translation.

The AudioFileName field defines the per-culture WAV file that the recorded audio for the line of dialogue should have (see below).

Once audio has been recorded from these Dialogue Sheets, the audio file should be named as defined by the AudioFileName field, and placed into a culture sub-folder (for example, MyRecordedAudio/fr). This can then be imported into UE4 using the import dialogue step, to produce the correct Dialogue and Sound Wave Assets (this can be done iteratively as new audio becomes available).

The default dialogue filename format guarantees uniqueness, but is not very readable by users. This can be changed using the Dialogue Filename Format setting under the Audio section of your Project Settings. The filename format you use should be decided before starting to record any audio, because it will be difficult to change later.

Due to the relatively high cost of translating dialogue compared to translating text, it is expected that dialogue localization will only begin once the script is finalized, and will follow this workflow.

Native dialogue is set for a line of dialogue.

Native dialogue is recorded and potentially copy-edited (potentially with several iterations). If copy-edited, the edited native dialogue is re-imported ready for translation.

Native dialogue is translated as text, ready for producing localized dialogue.

Localized dialogue is recorded and potentially copy-edited (potentially with several iterations). If copy-edited, localized dialogue is re-imported to ensure accurate subtitles.

Any native text changed during this process is expected to restart the workflow from step 1.

Creating Asset Groups

Asset groups allow you to create sets of Asset classes that can be assigned a different culture than the rest of your project.

A common use-case of this would be allowing the player to choose to have audio in one language, with everything else in another language. To do this, define a new Asset group called Audio and set it to use the audio classes for your project (this would typically go inside DefaultGame.ini):

Now you can assign a unique culture to this Asset group, without affecting the rest of your project. See the Managing the Active Culture page for more information.

The Localization Dashboard

Translation Editor

Translation Picker

Automating Localization

The Localization Dashboard

The Localization Dashboard in Unreal Engine 4 (UE4) is a tool that takes care of managing your localization targets. While it's still classed as experimental, it is stable and is used internally for all of our projects. It is the recommended way to manage Localization Targets, and can be accessed through the Window menu in the editor.

The Dashboard will create a Game Localization Target for you by default, and unless your project is particularly complex, this is probably the only Localization Target you need. You can use the Gather Text settings to specify where your source code and Assets can be found, and you can use the Cultures settings to specify which languages you are going to localize your project for. This includes setting your Native culture to the language you author your content in.

If you add a new Localization Target, make sure you specify an appropriate loading policy for it (typically Game). If you don't, the Localization Target does not get loaded at runtime.

Once your Localization Target is set up, you can use the toolbar under the Cultures section to Gather, Export, Import, and Compile your project texts. This is a process that can be run iteratively over time as new translations become available, or as new source text is added.

Once you run these actions, you will find some INI files in your Config/Localization folder. These are generated each time those actions are run using the Dashboard, and do not need to be submitted to source control unless you plan to automate your localization pipeline.

Currently the Localization Dashboard and localization commandlets (which form the localization pipeline) have two completely different configuration layouts for a Localization Target (with the Localization Dashboard generating the commandlet version).

Translation Editor

The translation editor is accessible through the Localization Dashboard. This provides a simple way to check the translation for a piece of text. It provides three translation tabs in its UI:

Untranslated: Text that has no translation associated with it.

Needs Review: Text that has previously been translated against an older version of the source text.

Completed: Text that has been translated against the current version of the source text.

The translation editor is a simple tool that is not updated frequently, and is probably lacking features that you would want for a comprehensive translation effort (for example, it has no translation memory). Because of this, we recommend that you only use the translation editor for spot-fixes. Instead of using the translation editor, we recommend that you use the PO export/import pipeline, combined with an external translation tool (such as Poedit, OneSky, or XLOC) for general translation work.

Translation Picker

The Translation Picker is an experimental tool that is not updated frequently. This tool lets you interrogate information from the text values used in your UI, including when using Play in Editor (PIE).

Enable the Translation Picker by clicking Editor Preferences > Experimental. Once enabled, it can be accessed through the Window menu in the Editor.

When the Translation Picker is active, it will show a floating window near your cursor that lists all the text values used by the widget under the cursor. Once you have found the text value you want to inspect, you can press the ESC key to lock the picker to that selection.

Localizable text (in other words, text that has an identity and has also been gathered and compiled into a LocRes file) will show an inline editable text field that can be used to spot-fix the current translation.

The ability to edit a translation inline was broken in Unreal Engine versions 4.13 - 4.21, but it has been fixed for Unreal Engine version 4.22.

Automating Localization

Localization automation is available by using the Localize script of the Unreal Automation Tool (UAT). This script provides a way to run various parts of the localization pipeline, and you can use it to generate nightly localization updates for your products, as well as to interface with your external localization provider. This script is currently hard-coded for a Win64 Development Editor build.

Prior to Unreal Engine version 4.22:

This script was named Localise. This name still exists as an alias.

OneSky was the default value for the LocalizationProvider argument. If you are not using a localization provider, you will have to set this argument to an empty string.

A basic invocation, without an external localization provider, for an in-source build (a project within the Unreal Engine 4 root folder) would look like this:

A basic invocation, without an external localization provider, for an out-of-source build (a project outside the UE4 root folder) would look like this:

Interfacing with an external localization provider involves creating a class deriving from LocalizationProvider. We provide two localization providers by default, OneSky and XLOC.

Localization Provider

Implementation Information

OneSky

Implemented by OneSkyLocalizationProvider.

Create a class derived from OneSkyConfigData to contain your configuration data, and pass the Name of the configuration to the -OneSkyConfigName argument to choose the correct configuration.

Pass the name of your OneSky group to the -OneSkyProjectGroupName argument.

Pass -LocalizationProvider=OneSky to use the OneSky localization provider.

XLOC

Implemented by XLocLocalizationProvider.

Create a class derived from XLocLocalizationProvider and fill in the Config variable with your configuration data.

Override StaticGetLocalizationProviderId and GetLocalizationProviderId to return the name of your configuration, and pass this name to the -LocalizationProvider argument to choose the correct configuration.

Gathering Assets

Validating Asset Caches

Gathering Assets

Asset gathering is the part of the localization pipeline that uses the most resources. This is because localization often must load Assets (and their dependencies) to extract the localizable text values contained within them. In order to minimize the number of Assets that actually need to be loaded during a gather, Unreal Engine 4 (UE4) adds a "gather cache" to the header of Asset files (generated when you save), which means that only the Asset header needs to be loaded in order to gather the text.

You can view the current cache for an Asset by going to the Asset Localization menu in the Content Browser, and selecting Show Localization Cache.

Certain kinds of Assets (such as Blueprints, or Levels with a non-empty Level Blueprint) are unable to generate a gather cache due to their use of bytecode. This is because UE4 gathers text values from bytecode, but bytecode is too volatile to be reliably cached on save.

A summary of how many Assets are uncached due to bytecode is printed to the log during an Asset gather. If you find your Asset gather is spending most of its time gathering from Assets that contain bytecode, then you might consider moving the text within those Assets into String Tables so that you can refer to those entries instead.

Only Assets that contain a serialized text value that passes FText::ShouldGatherForLocalization are loaded during an Asset gather. Culture-invariant, empty, and whitespace-only text, as well as String Table references, all fail this check. This is why using a String Table can improve your Asset gather performance.

Validating Asset Caches

There are some utilities available to help report or fix stale and missing gather caches on Assets in your project. These take a while to run, because they have to load every Asset into memory. However, they can offer significant future savings if you have a large number of uncached Assets. These utilities are run as extra arguments in the normal localization commandlet.

Example:

If you are upgrading a project from an Unreal Engine 4 version older than 4.20, you should at least run ReportStaleGatherCache to verify that your cache is up-to-date, since stale caches can cause localization issues.

These options are not exposed in the Localization Dashboard. Instead you must use the gather INI file generated by the dashboard for your localization target, and run the localization commandlet manually.

Argument

Description

ReportStaleGatherCache

Generates a StaleGatherCacheReport.txt file alongside the manifest for your localization target. This file contains a list of any Assets that contain a stale gather cache.

FixStaleGatherCache

Attempts to automatically fix any Assets that contain a stale gather cache, by re-saving them.

FixMissingGatherCache

For Assets too old to have a gather cache, this attempts to automatically fix Assets that are missing a gather cache by re-saving them.

Querying and Applying Cultures

Getting the Active Culture

Setting the Active Culture

Querying the Available Languages

Overriding the Default Culture

Localization Preview

Culture Remapping

Culture Restrictions

Querying and Applying Cultures

The Active Culture in Unreal Engine 4 (UE4) can actually refer to one of three things:

The language - The language is used to work out which localization data should be used.

The locale - The locale is used to control how numbers/dates/times/etc are formatted within our internationalization library.

An Asset group culture - Asset groups allow you to create a group of Asset classes that can be assigned a different culture than the main project language.

It is possible set all of these at once by changing the Active Culture. However, if your project intends to use Asset groups, then you'll want to treat the language and locale (which games often set to the same value) and Asset groups as separate settings.

UE4 makes this separation simple, and also provides some utilities that you can use in both C++ and Blueprints to help manage the settings.

Getting the Active Culture

The underlying active culture information is stored in the FInternationalization singleton, but UKismetInternationalizationLibrary provides a small set of wrapper functions that let you consistently access the information from both C++ and Blueprints.

Function

Description

GetCurrentLanguage

Get the active language as an IETF language tag.

GetCurrentLocale

Get the active locale as an IETF language tag.

GetCurrentAssetGroupCulture

Get the culture for a named asset group as an IETF language tag.

Setting the Active Culture

The underlying Active Culture information is stored in the FInternationalization singleton, but UKismetInternationalizationLibrary provides a small set of wrapper functions that let you set the values from both C++ and Blueprints. They also provide a way to optionally persist the new settings to the per-user config file.

Function

Description

SetCurrentCulture

Set the Active Culture (language, locale, and all asset groups) from an IETF language tag.

SetCurrentLanguage

Set the active language from an IETF language tag.

SetCurrentLocale

Set the active locale from an IETF language tag.

SetCurrentLanguageAndLocale

Set the active language and locale from an IETF language tag.

SetCurrentAssetGroupCulture

Set the culture for a named asset group from an IETF language tag.

ClearCurrentAssetGroupCulture

Clear the culture for a named asset group (will revert back to using the active language).

The culture can also be changed in non-shipping builds using engine console commands.

Example:

Querying the Available Languages

The underlying available language information is stored in the FTextLocalizationManager singleton, but UKismetInternationalizationLibrary provides a small set of wrapper functions that lets you consistently access the information from both C++ and Blueprints.

Function

Description

GetNativeCulture

Get the native culture of a localization category as an IETF language tag.

GetLocalizedCultures

Get the list of cultures that have localization data available as IETF language tags.

GetSuitableCulture

Get the most suitable culture from a list of available cultures.

GetCultureDisplayName

Get the display name of a culture from its IETF language tag.

Overriding the Default Culture

UE4 determines the default culture by querying the underlying platform layer for the active language and locale. If the platform language isn't supported, UE4 falls back to the native language of your Localization Target. In a shipped project, you probably won't override this behavior. However, during development these overrides can be useful for testing other languages.

The default settings for your project will typically be defined in your DefaultGame.ini. This example shows setting the culture to French.

Example:

This example shows setting the language and locale to French, while setting the Audio Asset group to Japanese.

Example:

The settings can also be overridden using command line flags.

Example:

Localization Preview

The localization preview provides a way to preview your project localization data without leaving the Editor, and is configured by the Preview Game Language setting. To change these settings, follow these steps.

In the menu bar of the Editor, click Edit > Editor Preferences.



Click here for full image

In the Editor Preferences dialog, under General, click Region and Language.



Click here for full image

Click the dropdown next to Preview Game Language and select the language you want to preview.

The preview is automatically activated when Play in Editor (PIE) is running, as well as being passed to any standalone instances that are launched in the Editor. This preview can also be used in the UMG Editor to preview widgets in different languages. While a preview is running, all editable text fields are made read-only to prevent accidentally overwriting source data with translation data.

The PIE and UMG previews are not always fully accurate representations of what your project will look like at runtime, because they only load the localization data without affecting the language or locale settings. If you want an accurate representation, run a standalone instance in the Editor (which is the same as running the editor with -game).

Culture Remapping

Culture re-mapping provides a way to map one culture code onto another, and can be useful in dealing with regional variance that can't be handled by a script or country code. Culture re-mappings go inside your DefaultGame.ini file, and are a pair of IETF language tags separated by semi-colons.

Example:

Culture Restrictions

Culture restrictions provide a way to enable or disable certain cultures, which you can do on a per-build configuration basis. Culture restrictions can be useful if you want to disable languages that are required for testing, but should not be in the shipped version of your project.

Culture restrictions typically go inside your DefaultGame.ini file, and are set with an IETF language tag. You can include a list of build configurations to apply the restriction to (no listed build configurations implies that the restrictions apply to all build configurations).

Example:

Starting Out

Content Guides

Whether you are creating a small real-time environment to display your latest product or a large open world game level designed for maximum immersion, Unreal Engine provides you with the tools to create stunning interactive worlds.

Here, you will find the topics to help you design and build your environments. Learn how to build your level in the editor and bring it to life with lights, props, foliage and more.

Starting Out



Get up and running with the basics of the Unreal Editor.

Content Guides



Information on the Hierarchical Level of Detail system in Unreal Engine



How to work with the Landscape system for creating terrain for large, open, outdoor environments.



Topics that demonstrate features and tools for lighting scenes.



An introduction to the One File Per Actor System and how it can be used in your projects.



Information on tools used in the creation of large outdoor environments.



A collection of features, tools, and information about using the water rendering and meshing system.



An overview of the World Partition system and how to use it in your projects.



An overview of the interface used for the design and construction of game levels and environments.



An introduction to Actor Editor Context, a system for organizing the Actors in your Level

Prerequisites

Georeferencing means to associate an environment with locations in physical space. The term is commonly used in the geographic information systems field to describe the process of associating a physical map or raster image of a map with spatial locations. Once the environment has been georeferenced, Unreal Engine can express actual geographic coordinates (such as latitude/longitude or UTM coordinates).

The GeoReferencing plugin must be enabled to use the features described here.

Theoretical Background

Coordinate Reference Systems (CRS) and Ellipsoids

When it comes to locating objects on a planet, one must choose a Coordinate Reference System (CRS) to express the location.

What makes it complicated is that planets are neither planes nor spheres: they are ellipsoids. There are different ellipsoid models (called datums), the most well-known one being the WGS84 for Earth.



For example, with the WGS84 ellipsoid, there is an approximate 22km of difference between the lengths of the axes!

a = 6 378 137.0 m

b = 6 356 752.314 245 m

1/f = 298.257 223 563

Each Coordinate Reference System defines locations using the ellipsoid model it is based on. However, there are different kinds of CRS, each with additional properties.

Geographic CRS

A geographic CRS uses polar coordinates to express the location of one point on the planet.



Latitude = Elevation in degrees to the Equator

Longitude = Azimuth in degrees to the Prime Meridian (Greenwich)

Altitude = Height in meters to the reference ellipsoid.

Angles are expressed in decimal degrees, or DMS (Degrees, Minutes, Seconds).

There are, in fact, two kinds of latitude definitions; when the datum is not a sphere, local normal to the ellipsoid model is involved, which makes for more complex calculations, but that is out of scope here.

Geocentric CRS

A geocentric CRS uses Cartesian coordinates to define the location of any point on the planet, with the origin located at the planet center.

The following image shows the Earth-Centered, Earth-Fixed (ECEF) CRS, which is the standard reference CRS used in distributed simulation protocols such as DIS/HLA.



Origin = Earth center

X Axis points to the Equator/Prime Meridian (Greenwich) intersection.

Z Axis aligns with the Earth's axis of rotation.

Y Axis is orthogonal to the former two axes.

Coordinates are expressed in meters.

Projected CRS

A projected coordinate system is a Geographic Coordinate System in which the planet has been "flattened" using a map projection. This is what we have always used when looking at paper maps. There are different ways to project a sphere to a plane, so there are lots of possible map projections, with more or less deformation, depending on the area mapped.

Most basic projections are using planar, conical or cylindrical shapes.













One of the most frequently used projections is the Mercator projection, which has several variants.

For instance, there is the Universal Transverse Mercator projection, widely used in the Simulation Industry. This CRS divides Earth into 60 parts, or zones, and projects each of these north / south-oriented zones using a cylindrical projection that is tangent to the central meridian of each zone.



This is a Cartesian coordinate system, but in addition to the XYZ coordinates, it needs a Zone and Hemisphere identifier to define the origin. Specific assumptions are necessary to make sure all coordinates are positive.

Each 6°-wide UTM zone has a central meridian located by definition at X=500,000 meters. This central meridian is an arbitrary value convenient for avoiding any negative coordinates. All easting values will be greater than this central value, and all westing values will be lower, but all values will be positive.

If you're in the Northern Hemisphere, the equator has a northing value of 0 meters. In the Southern Hemisphere, the equator starts at 10,000,000 meters. This is because all values south of the equator will be subtracted from this value while being kept positive. This is called a false northing because y-coordinates in the Southern Hemisphere will avoid negative values.

There are derivatives of this system such as the Military Grid Reference System (MGRS).

How to Describe a CRS

There are so many possible projection systems that conventions have been defined to declare their particular settings, such as Ellipsoid, Units, Meridians, Projections, and so on. This data can be saved in various formats, with the most-used being Well-Known-Text (WKT) and the European Petroleum Survey Group (EPSG) code.

Several websites, like http://epsg.io/, give information about each CRS, the details of which are outside the scope of this document.

It is very important to know the CRS that you want to use to convert coordinates to the right values.

References

For more information about geodesy (the field of mathematics that deals with the shape and area of Earth), you can have a look at the following links.

CRS: https://en.wikipedia.org/wiki/Geographic_coordinate_system

Geographic CRS : https://en.wikipedia.org/wiki/World_Geodetic_System#WGS84

ECEF: https://en.wikipedia.org/wiki/ECEF

Mercator Projection : https://en.wikipedia.org/wiki/Mercator_projection

UTM Projection: https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system

MGRS: https://en.wikipedia.org/wiki/Military_Grid_Reference_System

Georeferencing Plugin

Unreal Engine comes with a Georeferencing plugin that you can use to define the level origin coordinates in one specific CRS, and provides functions to convert coordinates between each different CRS. In Unreal Engine, each Actor has coordinates defined relative to this level origin, so to know an arbitrary georeferenced location, you need to locate the engine origin on Earth.

Consider these two different cases:

Flat Planet: Your Unreal Engine environment is small enough to be approximated by a flat ground surface (smaller than some hundreds of km). In that case, you can model the ground in a projected mode, and define all coordinates in a projected CRS with one simple translation offset.

Round Planet: Your Unreal Engine environment is so big that you need to take into account the planet curvature (this is almost certainly the case if you are using the Large World Coordinates feature). In that case, your environment geometry can cover the whole planet, with a spherical or ellipsoidal shape. In this case, there are two ways to place your origin: at the center of the planet shape, or at any point on the surface. In the latter case, Unreal Engine assumes the Z-axis is pointing up, and normal to the ellipsoid at this point.

These cases can be illustrated by the image below.

On a Flat Planet, your environment is the green square. The modeling origin chosen for your level is the P point. It's an arbitrary location on the planet, and it can be defined using Geographic coordinates (latitude and longitude), or using Cartesian coordinates, but in a specific projected CRS. The XYZ coordinates are then represented within the CRS as east / north / up directions.

On a Round Planet, you have two different choices:

Locate your Level origin at the planet center. This is the ECEF case, there is no geometry at the origin, but instead at coordinates with large values depending on the planet radius. The ECEF CRS is a Cartesian coordinate system, and its axes are aligned to the Unreal Engine axes.

Locate your Level origin at an arbitrary point on the planet surface. As in the Flat Planet case, these coordinates can be expressed in a Geographic or Projected CRS. It is more convenient to keep the Up direction of the level aligned with the ellipsoid normal at this location, and make sure you orient the plane geometry in such a way that the Front and Right vectors are matching the North and East vectors.



In the geospatial industry, most coordinates are expressed in right-handed frames, but Unreal Engine uses a left-handed coordinate system. To remain consistent with geospatial usage, the Georeferencing plugin expresses coordinates using right-handed logic. This means that it inverts the Y coordinate at some point when converting coordinates (this is transparent to the end user).

For the Georeferencing plugin, we chose the following default axes conventions:







When the Unreal Engine Frame matches the Tangent Frame





When the Unreal Engine Frame matches the ECEF Frame



If you prefer to use another convention, you will have to perform a coordinate swap before invoking the Georeferencing functions.

Unreal Engine automatically handles the World Origin offset shifting you activate when you use World Composition or when you perform a manual rebasing.

Setting up the Georeferencing System

From the main menu, go to Edit > Plugins, then enable the Georeferencing plugin. Restart Unreal Engine.



Once enabled, you can use this plugin to convert coordinates between four systems:

The Unreal Engine coordinate system

A Projected CRS of your choice

A Geographic CRS of your choice

The standard ECEF CRS

From the Place Actors panel, find the Geo Referencing System Actor, drag it into your level, then select it to view its properties in the Details panel.



Property

Description

Planet Shape

Flat or Round. This depends only on your project geometry shape/scale.

Projected CRS

Identified by a string. This can be any CRS supported by the PROJ library. Refer to the https://epsg.io/ website to find appropriate CRS definitions.

Geographic CRS

Identified by a string. This can be any CRS supported by the PROJ library. Refer to the https://epsg.io/ website to find appropriate CRS definitions.

Property

Description

Origin Location in Projected CRS

Determines whether the Origin is defined using the Projected or the Geographic CRS coordinates.

Origin at Planet Center

Round Planet only. Determines whether the origin is defined as the planet center.

Origin Projected Coordinates Easting

Origin east-west coordinate when using Projected CRS coordinates.

Origin Projected Coordinates Northing

Origin north-south coordinate when using Projected CRS coordinates.

Origin Projected Coordinates Up

Origin up-down coordinate when using Projected CRS coordinates.

Origin Latitude

Origin north-south coordinate when using Geographic CRS coordinates.

Origin Longitude

Origin east-west coordinate when using Geographic CRS coordinates.

Origin Altitude

Origin up-down coordinate when using Geographic CRS coordinates.

Using invalid strings for the CRS projection identifications will generate an error message. Make sure you are using a correct CRS definition as defined on https://epsg.io/.





In the screenshot below, the geometry is flat, then modeled in a projected CRS. The EPSG Code 32617 is for UTM North Zone 17, and the coordinates correspond to a location near Epic Games HQ. EPSG:4326 is the WGS84 ellipsoid, meaning that all geographic coordinates in latitude, longitude, and altitude will be defined in relation accordingly.



For floating point accuracy reasons, these origin values have to be integers to avoid bad roundings. Consider this constraint when modeling your environment. Internally, the Georeferencing plugin does all its computations in double precision to maintain accuracy at any planet location.

When Round Planet is selected, an extra checkbox is displayed to set up your origin location.

If you check Origin at Planet Center, it means that you are using the ECEF case. The origin is explicitly defined at the planet center as described previously, and no further information is required.

Otherwise, you can set the Level Origin at an arbitrary location on the ellipsoid using the CRS of your choice.



Converting Coordinates

In order to convert coordinates, you need to access the Georeferencing system, then call one of the functions in the Georeferencing category.





The possible conversions are explained in the picture below.



It is important you remember the Georeferencing system works in double precision, and cannot directly expose the coordinates in the Blueprint system that only support single precision floating values. The system outputs specific structures (FCartesianCoordinates, FGeographicCoordinates), and we recommend using these structures during all computations, then getting their float approximations at the final step.

Unreal Engine CRS is your level coordinate system. Every Actor has its coordinates in FVector variables. The first step is for you to transform these coordinates into a Georeferenced CRS, but still using Cartesian coordinates, (ECEF or Projected), depending on your case. You then have the ability to convert this location to geographic coordinates.

When you transform Unreal Engine coordinates into Projected or ECEF coordinates, the computation path depends on the Flat Planet / Round Planet property.

For example, if you are on a Round Planet and ask for an Engine to Projected conversion, it first converts the coordinates to ECEF (basic translation), then to Projected (complex projection). These intermediate steps are illustrated by the Green and Red circular arrows. That means, if you are interested in getting the geographic coordinates only, the optimal path for performance will be UE > ECEF > Geographic if you are on a Round Planet, and UE > Projected > Geographic on a Flat Planet.



Obtaining Values

Once you have the FCartesianCoordinates or FGeographicCoordinates, you have different options to get the values:

In Blueprint, by calling ToFloatApproximation (this approximation corresponds to the conversion from double precision to Blueprint single precision).

By using custom C++ code to do your own processing; if you want to maintain the full double precision, we recommend getting these values by writing functions that will directly take one of the FCartesianCoordinates or FGeographicCoordinates structures.

By converting them to a display text, with possible rounding options.



Formatting

FCartesianCoordinates

FGeographicCoordinates

To Compact Text

([X], [Y], [Z])

([Latitude], [Longitude], [Altitude]m)

With Latitude, Longitude possibly written as [Degree]° [Minutes]' [Seconds]"

To Full Text

X=[X], Y=[Y], Z=[Z]

Latitude=[Latitude] Longitude=[Longitude] Altitude=[Altitude]m

With Latitude, Longitude possibly written as [Degree]° [Minutes]' [Seconds]"

To Separate Texts

[X]

[Y]

[Z]

[Latitude]

[Longitude]

[Altitude]

Tangent Vectors and Transforms

You can use the Georeferencing system to get the Tangent vectors (East, North, Up) expressed in the Unreal Engine CRS by using the Get ENUVectors at Geographic Location node. You can use this, for example, to move a pawn that will follow the planet surface.



You can also get the Tangent Transform at any location on the planet using the Get Tangent Transform at Geographic Location node. Combining this transformation with a local object transformation will get the world-space transformation of your object to the Unreal Engine CRS.



A very specific function node is also provided: Get Planet Center Transform. If you have your own ellipsoidal planet mesh that you want to position in a way that it will be tangent to the origin that you declared in your Georeferencing settings, call this function to set this Actor transformation and it will be oriented to the location you defined.



Additional Tools and Content

The Georeferencing system comes with additional tools located in the Georeferencing Content folder in the Content Browser. You can display these if you select Show Plugin Content in the View Options dropdown menu.

Georeferencing Status Bar

You can find a sample UMG widget in /GeoReferencing/UI/UMG_GeoStatusBar, which, once added to the viewport, will display the current view location in various CRS: Projected, Geographic, and ECEF.



You can duplicate it and customize it to your liking.



Coordinates Inspector Utility Widget

You can find a special Editor Utility Widget in /GeoReferencing/UtilityWidgets/EUW_CoordinatesInspector. If you run it inside the editor, it displays a panel where you can control the georeferenced coordinates of your view, and of the point located under your mouse.





Location Probes and Rebasing Actors

In the GeoReferencing/Models/LocationProbe/BP_LocationProbe folder, you can find a BP_Location Probe Blueprint for performing in-game coordinate measurements.

Drop it in your level, add it to any location, and it will display its coordinates in each CRS.

You can even spawn a grid of probes using one of the provided Spawner Blueprints to automate the process.





To deal with large coordinates, you can have Unreal Engine shift the origin to ensure accuracy.

This rebasing system is automatically used during World Composition, but you can also control it directly. For that purpose, a BP_Rebasing Actor is provided as an example to demonstrate how you can control this system.

The Georeferencing system always considers the current origin offset in its computations.

A complex level in Unreal Engine contains hundreds of detailed Static Mesh assets that combine together to build a virtual world. With this level of detail, it can become difficult to load a multi-kilometer level all at once.

The Hierarchical Level of Detail (HLOD) system can be used to organize multiple Static Mesh Actors and combine them into a single proxy mesh and Material at long view distances. This helps reduce the number of Actors that need to be rendered for the scene, which reduces the number draw calls per frame and increases performance. This is especially useful when working with large open worlds.



This how to covers how to generate the HLOD meshes for your HLOD enabled Unreal Engine 4 project.



Overview of the Hierarchical Level of Detail system in Unreal Engine 4



A reference page for the interface elements and properties found in the Hierarchical LOD Outliner.

Steps

Generate Clusters

Generate Proxy Meshes

In order to use Hierarchical Level of Detail (HLOD) Meshes, there are two processes you must perform in order to set up HLOD Meshes in your Level. First, you must Generate Clusters which groups Actors in your level together based on the settings you specify in the Cluster Generation Settings.

After Generating Clusters, you can then Generate Proxy Meshes out of those clusters. The process of Generating Proxy Meshes can take a long time based on the complexity of your scene or the settings specified in the Mesh Generation Settings.

In this how-to, we go through an example of building HLOD Meshes by Generating Clusters and Generating Proxy Meshes.



Click image for full size.

Steps

After you define your Cluster Generation Settings for the HLOD levels you need, click the Generate Clusters button.



Click image for full size.



Click image for full size.

Once the process starts, you will see a progress bar appear that indicates the LOD level being generated.



Click image for full size.

After clustering completes, the clustered LOD Actors will be populated inside the HLOD Outliner window.



Click image for full size.

You can expand an LOD Actor to view the clustered Static Meshes by clicking the expand arrow to the left of the name.



Click image for full size.

You can also see the clusters in the Viewport by selecting an LOD Actor (and Static Meshes) from the HLOD Outliner.



Click image for full view.

If you want to make changes to a given cluster, you can adjust the Cluster Generation Settings to your desired settings and Generate Clusters again. You can also use the HLOD context menus to define settings for LOD Actors or what to do with a Static Mesh Actor in a cluster.

Once you are satisfied with the clusters, click the Generate Proxy Meshes button.



Click image for full size.

Once the process starts, a progress bar will appear and indicates the LODActor and LOD Level being worked on out of the total number of Proxy Meshes that will be generated.



Click image for full size.

Depending on your HLOD Settings, the complexity of your scene, and your computer specifications, this process can take a long time to complete. As a frame of reference, a system with a 12-core i7 processor, a GTX-980 video card, and 64 GB of RAM took 10 to 12 minutes with default settings on both HLOD Levels, with 100+ LOD Actors per HLOD level.



Click image for full size.

Generate Clusters

Cluster generation uses the settings from the individual HLOD Levels to decide how it should group Static Mesh Actors in the scene together. This generation process can take some time depending on the settings use, the number of Actors being groups, whether materials are generated, and generally on your hardware's specs.

Once you've setup your specific settings for the individual HLOD levels you need, click the Generate Clusters button.



Click image for full size.

Once the process starts you'll see a progress bar appear that indicates the LOD level being generated.



Click image for full size.

Now that the process has completed you'll see the HLOD Outliner populated with all the clustered Actors.



Click image for full size.

You can expand the individual LODActors to see what Static Meshes make up this cluster by clicking the arrow button to the left of the name.



Click image for full size.

You can visualize the clusters in the level by selecting a LODActor from the HLOD Outliner and locating it in the editor viewport.



Click image for full size.

To visualize how the generated clusters work in the editor you can use the Forced LOD Level menu to see the HLOD in action without the need to have it transition at a specific screen size. This is helpful for troubleshooting any issues appearing on screen that may be part of the generated cluster.



Click image for full size.

Should you run into any issues you don't like with the generated cluster you can expand the specified cluster and select the offending Static Mesh Actor. You can then click and drag it to another cluster, or you have the option to Remove or Exclude it from the generation of the cluster by right-clicking on the Actor's name in the list.

Actors can also be excluded on a per-instance basis by selecting them in the level and in their Details Panel set the option for Can be in Cluster to false.

Further, if you wish to add an Actor to a Cluster you can click and drag from the Outliner to the Cluster you wish it to be included in.



Click image for full size.

Repeat this process while adjusting the values in the HLOD's level Cluster Generation Settings until you are happy with the clusters being generated, then continue on to the next section: Generate Proxy Meshes.

Generate Proxy Meshes

After you're happy with the results of the generated cluster you can move on to the option to Build the clusters into a Proxy Mesh. This proxy mesh will be a newly created Static Mesh Actor that combines materials (if enabled), has it's own lightmaps, and it's own editable static mesh that can be opened in the static mesh editor.

If you're ready to build the proxy meshes you can now click the button "Generate Proxy Mesh" button to start the process.



Click image for full size.

Once the process starts you'll see the progress bar appear that indicates the HLOD Level being worked on and the number of Proxy Meshes being generated. This progress bar does not show all the HLOD Levels and total number of proxy meshes being created, only that specific level.



Click image for full size.

Depending on your HLOD Level settings, the number of proxy meshes being created, and your system specs this process can take a while, even for high-end machines!

As a reference the Proxy Mesh Generation process for my machine (12-core i7 processor, GTX-980, and 64GB of RAM) took ~10-12 minutes with default settings for both HLOD Levels and ~100+ LODActors per HLOD level.

Proxy Meshes

Hierarchical LOD Volume

Example

HLOD Overrides

HLOD Visualization



Hierarchical Level of Detail (or HLOD), in its simplest form, is a way to combine pre-existing Static Mesh Actors into a single HLOD Proxy Mesh and Material (with atlased Textures). Using HLOD may lead to increased performance as they reduce draw calls down to one call per Proxy Mesh as opposed to a draw call for each individual Static Mesh Actor. When generating HLOD Proxy Meshes, there several parameters you can adjust which help define how Static Mesh Actors are grouped together as clusters that will ultimately be built into Proxy Meshes.

To use HLOD, you will need to enable the HLOD system in each of the Levels you wish to take advantage of the system.

Proxy Meshes

Proxy Meshes can be opened independently and their settings can be adjusted as desired.



The Proxy Mesh above contains several elements that had their own Textures which were combined into a single texture (below).



For anything using Mask or Opacity, alpha channels are not passed to the merged Texture. If opacity or masked items are needed, disable the option for Merge Textures. When doing this the Proxy Mesh will assign the original material as a Material Element ID instead of combining them.

Hierarchical LOD Volume

The Hierarchical LOD Volume (HLOD Volume) is used to manually define/create an HLOD cluster. The Hierarchical LODVolume can be an be dragged into your Level from the Place Actors panel in the Volumes tab.



You can place this volume around Actors you want to be grouped in the same cluster. It can be helpful to make this slightly larger than the Actors you wish to include and should not be tightly bounding them. Once you have placed the volume around the Actors you can use the option Generate Clusters from the HLOD Outliner to create a new cluster with these grouped Actors.

Below, we have several cubes and spheres within an HLOD Volume and one cube and the floor outside the volume.



When we Generate Clusters inside the HLOD Outliner, we have two separate clusters: one containing the Static Mesh Actors inside the HLOD Volume, the other containing the Static Mesh Actors that are not inside the HLOD Volume.



Click image for full view.

Optionally, you can enable Only Generate Clusters for Volumes (below) to generate clusters for only Static Mesh Actors that exist within an HLOD Volume.



Click image for full view.

Example

Below is an example of Generated Clusters before and after adding HLOD Volume.



HLOD Level Desired Bound Radius: 500



Drag in the Volume and scale accordingly to cover your Actors.



Selecting the generated LODActor from the HLOD Outliner shows the cluster created and the Cluster bounds.

Right-click on the LODActor in the HLOD Outliner and click on Select Contained Actors to see the Actors used for this particular LODActor in your scene.





HLOD Overrides

When you select an LOD Actor in the Level, inside the Details panel, you can override the Hierarchical LODSettings being used.



Please see Mesh Generation Settings and properties for more information.

HLOD Visualization

There are visualization modes you can use to view Mesh LODs and HLODs in the viewport. To access these, click the View Mode button in the upper-left corner of the viewport and select your perfered method of LOD Coloration.



During a play session you can enter console command viewmode hlodcoloration to achieve the same result.

Property and Interface Reference

HLOD Actions

HLOD Scene Actors

LOD Actor Context Menu

Actor Context Menu

Properties

Cluster Generation Settings

Mesh Generation Settings

There are several options that are available within the Hierarchical LOD (Level of Detail) Outliner that you can use to define how your HLOD meshes are set up. Once enabling the HLOD system, you can access the HLOD Outliner from the window menu option under Level Editor.



Click image for full size.



Click image for full size.

This page breaks down the available properties within the HLOD Outliner, refer to each section for more information.



Click image for full size.

HLOD Actions - these options enable you to generate your HLOD Proxy Meshes for each of the clusters in your Level, re-generate clusters and build Proxy Meshes for each of the generated clusters in the Level, save all external HLOD data, or switch between LOD viewing options.

HLOD Scene Actors - this contains each of the clusters (or Proxy Meshes) that have been generated along with information about each Actor. You can also Generate or Delete Clusters from this panel as well as perform contextual actions by right-clicking on a Scene Actor.

LODSystem - this enables you to define how many HLOD Levels you want to include along with the Cluster and Mesh Generation Settings per HLOD Level. You can also override the Material used for Proxy Materials or override the HLODSetup Asset.

Property and Interface Reference



Click image for full size.

HLOD Actions

Across the top of the HLOD Outliner, you will find the available options:



Click image for full size.

Generate Proxy Meshes

This option becomes available after you have Generated Clusters that you wish to Generate Proxy Meshes from. When you generate Proxy Meshes, this will use the clustered LODs and merge these Actors together into a single asset. You can define how Proxy Meshes are clustered with the Cluster Generation Settings and ultimately how your Proxy Meshes are generated using the Mesh Generation Settings. This option also only affects the generated meshes, not the entire Level.

Be aware that this process can take a very long time depending on your scene complexity and settings you've chosen for your HLOD levels.

Build (Rebuild) All

This option can be used to build both the clusters and Proxy Meshes from those clusters in one step. Typically, you will want to generate clusters and ensure that you are content with the desired results before generating the Proxy Meshes (this option will automatically build the Proxy Meshes). Once you have generated clusters, the option Rebuild All is available which will re-generate clusters and build Proxy Meshes from those clusters.

Unlike Generate Proxy Meshes, this option will dirty the Level and may take a significant amount of time depending on your scene complexity and settings.

Save All

This option enables you to save all external HLOD data, this includes Meshes, Materials, and Textures.

LOD View

This option enables you to choose the LOD level to view inside the Editor or to assign a Forced Viewing Level inside the Editor. This is helpful for debugging any LOD issues you may have.

HLOD Scene Actors

The HLOD Scene Actors panel enables you to Generate Clusters (but not the Proxy Meshes) for Meshes in the Level or Delete Clusters (which will delete all clusters in the Level). This panel also displays all the LODActors for a given LOD Level along with information about the Actor such as their original triangle count, the reduced number of triangles in an LOD mesh, the percentage of triangle reduction retained by an LOD mesh, and what Level the LOD Mesh resides in.



Click image for full size.

Additional actions can be accessed by right-clicking on an LOD Actor or Static Mesh Actor in the panel:

LOD Actor Context Menu

Right-click any LOD Actor listed under the Scene Actor Name column to bring up the menu below and available options.



Click image for full size.

Option

Description

Select LOD Actor

Selects the LOD Actor in the viewport (same effect as left-clicking the cluster).

Select Contained Actors

Selects all the Actors contained in the LOD Cluster.

ForceView

Toggles the LOD view of the HLOD Actor in the viewport.

This option is available for LODActors that have been built into Proxy Meshes.

Rebuild Proxy Mesh

Forces the right-clicked cluster to rebuild its Proxy Mesh.

Create Containing Hierarchical Volume

Creates a Hierarchical Volume around the Actors contained in the Cluster that can then be modified to encompass greater or fewer Actors.

Delete Cluster

Deletes the right-clicked Cluster.

Actor Context Menu

Expanding an LODActor exposes the scene Actors included in the generated HLOD cluster. Right-click a Scene Actor for the following options:



Click image for full size.

Option

Description

Remove From Cluster

Removes the right-clicked Actor from the cluster.

Exclude From Cluster Generation

Excludes the right-clicked Actor from cluster generation. If you wish to re-add the excluded Actor click and drag it from the World Outliner into the cluster in the Hierarchical LOD Outliner.

Properties

Below, broken out by major section, are the properties that can be found in a Hierarchical LODSetup in the LODSystem panel located in the lower portion of the Hierarchical LOD Outliner interface.

Cluster Generation Settings

The Cluster Generation settings enable you to control how HLOD clusters will be generated to include Actors from your levels by setting the desired bounds of your clusters, how full the cluster should be, and the minimum number of Actors that must be used to generate a cluster.



Click image for full size.

Property

Description

Allow Specific Exclusion

This works in combination with a property on mesh components, you can add an HLOD level index for which this mesh should not be included. This allows you to only include small props for HLOD level 0, and ignore them for subsequent HLODs (as you wouldn't be able to see them from certain distances etc.)

Desired Bound Radius

The radius in which to cluster meshes together. This is not guaranteed but used to calculate filling factor for auto clustering.

Desired Filling Percentage

This is used when generating clusters, it determines how much of the cluster's bounds (sphere) is supposed to be occupied by the bounds of any actors it contains. Essentially the % of the cluster volume that has to be used by contained actors.

Min Number of Actors to Build

Min number of Actors to build LODActor.

Only Generate Clusters for Volumes

If enabled, will only generate clusters for meshes within HLOD Volumes.

Mesh Generation Settings

The Mesh Generation settings enable you to control specific properties that will be used when HLOD cluster Actors are merged, like generating lightmaps, combining Materials, transition size, and more.



Click image for full size.

Property

Description

Transition Screen Size

This will calculate the distance to show the cluster at according to its size. It calculates the distance at which the cluster would occupy the user defined screen size, according to a fixed Field of View (FOV) / 16:9 ratio. If you would want to force all clusters to switch at a predefined distance you can do so with the Override draw distance.

Override Draw Distance

Forces all clusters to switch at the predefined distance specified.

Simplify Mesh

If enabled, the resulting mesh will be simplified. If disabled, it will just merge Actors but will not simplify using the lower LOD if it exists. For example, if you build LOD 1, it will use LOD 1 of the mesh to merge Actors if it exists. If you merge Materials, it will reduce drawcalls.



Merge Settings



Generate Light Map UV

When enabled, this will generate a lightmap UV for the merged mesh and assign the Lightmap Coordinate Index to 1.

Target Light Map Resolution

The lightmap resolution you'd like to use for the HLOD Actor.

Computed Light Map Resolution

Whether or not the lightmap resolution should be computed by summing the light map resolutions for the input Mesh Components.

Pivot Point at Zero

When the merged mesh should have a pivot located a the World Origin (coordinate 0,0,0), or if the pivot should be located at the first Actor listed when generating the HLOD cluster.

Merge Physics Data

When enabled, the collision primitives will be merged for the combined Actors.

Merge Materials

With this enabled the system will bake down the materials assigned to all contained meshes and combine them into a single material. This allows for reducing the draw call complexity of the merged mesh, this is only used when you merge the meshes rather than generating a proxy mesh. In case you are simplifying a mesh we will always bake the materials, and apply it to the proxy mesh.

Material Settings

The settings here enable you to control how your Materials are packed and combined when the HLOD Actor is generated.

Property

Description

Texture Size

Size of the generated BaseColor texture map.

Texture Sizing Type

Whether to use the specified Texture Size parameters for all Material properties, use automatically biased texture sizes based on Texture Size, or to use per property manually overridden Texture Sizes.

Normal Map

Whether to generate a Normal map.

Metallic Map

Whether to generate a Metallic map.

Metallic Constant

Enables to you set a metallic constant value in place of a texture map.

Roughness Map

Whether to generate a Roughness map.

Roughness Constant

Enables to you set a roughness constant value in place of a texture map.

Specular Map

Whether to generate a Specular map.

Specular Constant

Enables to you set a specular constant value in place of a texture map.

Emissive Map

Whether to generate an Emissive map.

Opacity Map

If enabled, an Opacity map will be baked out for the resulting merged Actor. This nullifies the Opacity Constant property.

Must also use the Blend Mode of Translucent to show correctly in the generated instances.

Opacity Constant

Only enabled if Opacity Map is disabled, this sets a constant value for the Opacity property of the resulting merged Actor's Material.

Opacity Mask Map

If enabled, an Opacity Mask map will be baked out for the resulting merged Actor. This nullifies the Opacity Mask Constant property.

Must also use the Blend Mode of Masked to show correctly in the generated instances.

Opacity Mask Constant

Only enabled if Opacity Mask Map is disabled, this sets a constant value for the Opacity Mask property of the resulting merged Actor's Material.

Ambient Occlusion Map

Whether to generate an Ambient Occlusion map.

Ambient Occlusion Constant

Enables you to set an ambient occlusion constant value in place of a texture map.

Blend Mode

Enables you to define the Blend Mode for Proxy Materials.

Gutter Size

The gutter (in texels) to add to each sub-chart for our baked-out Material for the top mip level.

Bake Vertex Data to Mesh

When enabled, vertex data (such as vertex colors) will be baked into the resulting Proxy Mesh.

Output UVs

When enabled, any vertex colors that have been painted on the selected meshes will be incorporated into the generated HLOD Actor and Material that is created.

LODSelection Type

Enables you to define how the LOD level is determined.

Specific LOD

A given LOD level to export from the source meshes.

Use Vertex Data for Baking Material

When enabled, vertex data will be used when baking out Materials.

Use Texture Binning

This will calculate the varying output texture sizes according to their importance when packing the final atlas texture.

Reuse Mesh Lightmap UVs

Whether to attempt to re-use the source mesh's lightmap UVs when baking the Material or always generate a new set.

Merge Equivalent Materials

Whenever you either generate a merged mesh or a proxy mesh we need to determine which materials to bake down. Whenever this value is set, we will also merge any material instances. Say you have dynamic material instances that get generated for any of your placed props. They will essentially be the same material under the hood, but might had instance specific properties. This means when you merge them it will only use one instance for all of the meshes, this means that the final look of the HLOD mesh might be different than the original.

This can cause artifacts in the merged mesh if world position/actor position is used to determine output color.

Use Landscape Culling

When enabled, landscape geometry can be used to cull away (or remove) any triangle sections of the mesh that are not visible.

Allow Distance Field

Whether to allow distance field to be computed for this mesh.

Disable this to save memory if the merged mesh will only be rendered in the distance.

The Landscape system inside of Unreal Engine is a collection of tools that allow you to create expansive outdoor environments.

The topics below will help you Sculpt your Landscape Actors, create customized Materials, and paint them on your Landscape to create your own immersive world.



Guide to using the tools for editing Landscape terrains.



Collision settings for Landscape.



Explains the Landscape Edit Layers feature for non-destructive layers and splines in heightmaps.



Setting up materials to work with Landscape terrains



An overview of the Landscape Outdoor Terrain System and how to use it in your projects.



Getting up and running with the basics of the Landscape System in Unreal Engine.



Understanding the construction and dimensions of Landscape Outdoor Terrain.



Guide to creating new Landscape terrains.



Guide to creating new Landscape import formats via plugin.

Content Guides

After you have created a Landscape, you can now utilize any of the following tools to customize it:

Modify its shape in Sculpt mode.

Modify its visual appearance in Paint mode.

Change the size, shape, and type of Brush you use to modify the Landscape's shape and appearance.

Modify the size and shape of its components in Manage mode.

Copy, paste, import, and export parts of the Landscape's heightmap with Landscape Gizmos.

Modify the Landscape's Material.

Create Splines for any linear features you want to use in your Landscape.

Create holes in your Landscape for features such as caves.

For information about creating Landscapes, see Creating Landscapes.

The Landscape Tools also work in the VR Editor. For the controls for using Landscape in VR, see the



Content Guides



Guide to the brushes available for modifying Landscapes.



Guide to the Landscape Copy Tool available for modifying Landscapes.



Guide to the Landscape tool's Manage mode.



Guide to the Landscape tool's Paint mode.



Guide to the Landscape tool's Sculpt mode.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Circle

Alpha

Pattern

Component

Gizmo

The Landscape tool's Brush defines the size and shape of the area of the Landscape that will be affected by either sculpting or painting. Brushes can have different shapes, sizes, and falloffs. Brushes should be a familiar concept to anyone who has experience using Photoshop or a similar image-editing application.

You can set the brush type and falloff in either the Sculpt or Paint tab of the Landscape toolbar. Settings can also be adjusted in the Landscape panel.





Property

Description

Brush Size

Determines the size of the brush in Unreal Units including the falloff. Within this area, the brush will have at least some effect.

Brush Falloff

Determines the percentage from the brush's extents where the falloff should begin. Essentially, this determines how hard the brush's edges are. A falloff of 0.0 means the brush will have full effect throughout with hard edges. A falloff of 1.0 means the brush will only have full effect at its center, and the effect will be reduced throughout its entire area to the edge.

Use Clay Brush

Clay Brush allows for an organic, additive approach to sculpting your Landscape. Similar to working with digital clay. If selected, uses a Clay Brush.

The size and falloff of the current brush is displayed in the viewport as a pair of concentric circles.







Falloff: 0.0

Falloff: 0.5

Falloff: 1.0

Circle



The Circle brush applies the current tool in a circular area, with a falloff defined both numerically and by type.



Circle Brush Falloff Type

Icon

Type

Description



Smooth

A linear falloff that has been smoothed to round off the sharp edges where the falloff begins and ends.



Linear

A sharp linear falloff, without rounded edges.



Sphere

A half-ellipsoid-shaped falloff that begins smoothly and ends sharply.



Tip

A falloff with an abrupt start and a smooth ellipsoidal end. The opposite of the Sphere falloff.

Below is an example of each of these falloff types when operating on the heightmap, with the same radius and falloff:









Smooth

Linear

Spherical

Tip

Alpha



The Alpha brush is similar to the Pattern brush, but instead of tiling the texture across the Landscape as you paint, it orients the brush texture in the direction of your painting and drags the shape as you move the cursor.



Alpha Brush Settings



Setting

Description

Texture

Sets the Texture to be used, assigned from the Content Browser.

Texture Channel

Sets the Alpha brush's contents to the data from the corresponding channel of the Texture that is currently assigned.

Brush Size

Sets the size of the brush.

Use Clay Brush

If selected, uses a clay brush.

Pattern



The Pattern brush allows you to use an arbitrary shape for the brush by sampling a single color channel from a texture to use as the alpha for the brush. The texture pattern is tiled as the brush is painted.

For example, the textures below could be used as the alpha:



Those would result in the following brushes:





Pattern Brush Settings



Setting

Description

Texture

Sets the Texture to be used, assigned from the Content Browser.

Texture Channel

Sets the Pattern brush's contents to the data from the corresponding channel of the Texture that is currently assigned.

Brush Size

Sets the size of the brush.

Brush Falloff

Sets the brush falloff.

Use Clay Brush

Enables you to use a clay brush.

Texture Scale

Sets the size of the sampled Texture in relation to the surface of the Landscape.

Texture Rotation

Sets the rotation of the sampled texture in relation to the surface of the Landscape.

Texture Pan [U/V]

Sets the offset of the sampled texture on the surface of the Landscape.

Component



The Component brush is used for operating on individual components. The cursor becomes limited to a single component at a time:



The Component brush is the only brush available when you are using tools that operate on the individual component level.

Gizmo



The Gizmo brush is used for modifying your Landscape with Landscape Gizmos, which are tools that you use to perform actions to a specific localized area of the Landscape.

The Gizmo brush is available only when you are using the Copy/Paste tool in Sculpt mode.

For more information about Gizmos, see Landscape Copy Tool.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Accessing the Gizmo Tool

Copying to the Gizmo

Pasting from the Gizmo

Gizmo Data Import/Export

Landscape Gizmos are editor-only Actors that are similar to volumes in that they define a specified area. Their purpose is to hold height and layer data for an area of a Landscape so that it can be copied to another location on the Landscape or exported for use in a different Landscape or heightmap generator (World Machine, Terresculptor,...).

Accessing the Gizmo Tool

To access the Gizmo tool:

In Landscape mode, click the Sculpt tab to open the Sculpt Tools toolbar.



Choose Copy option from the toolbar. The Gizmo brush appears on your selected Landscape as a red-outlined box.



Selecting the Gizmo brush creates a temporary Gizmo Actor. You can use the transformation tools to manipulate this Actor as you would any other, to define the area of the Landscape you want to copy.

For more information about the transformation tools, see Transforming Actors.

You can also modify the Gizmo Actor's properties in the Details panel.



Property

Description

Width

The base width for Gizmo Actor in Unreal Units; X axis shown as red line.

Height

The base height for the Gizmo Actor in Unreal Units; Y axis shown as green line.

LengthZ

The base Z length for the Gizmo Actor in Unreal Units.

MarginZ

The Z value for space when you fit the Gizmo to the selection, with Max height and Min height. When you fit Gizmo to selected region, LengthZ = (Max height - Min height) + 2 * MarginZ.

MinRelativeZ

The minimum height value of data in the Gizmo. Height values in the Gizmo are normalized from 0.f to 1.f and displayed as (Value - MinRelativeZ) * RelativeScaleZ.

RelativeScaleZ

The height scale of the data in the Gizmo.

TargetLandscape

The currently selected Landscape, which the Gizmo tool will be used on.

Copying to the Gizmo

In order to copy a portion of a Landscape, the data for that area must be copied to a Gizmo. Then, that data can later be pasted to another location.

To copy a selected region:

In Sculpt mode, select the Region Selection sculpting tool.



Use the brush strokes to select a region of the Landscape, similar to the normal painting process.



Select the Copy/Paste sculpting tool.



The Gizmo will become visible in the viewport.



Click the Fit Gizmo to Selected Regions button to position and size the Gizmo so that it encompasses all selected regions.



Click the Copy Data to Gizmo button to transfer the data for the selected region of the Landscape within the Gizmo's bounds. Pressing Ctrl + C performs the same function.



To copy an area within a Gizmo:

Select the Region Copy/Paste sculpting tool. The Gizmo will become visible in the viewport.

Select the Gizmo by clicking on it. The transform widget should appear.



Move, rotate, and scale the Gizmo so that it encompasses the portion of the Landscape you wish to copy.



Press the Copy Data to Gizmo button to transfer the data for the portion of the Landscape within the Gizmo's bounds. Pressing Ctrl + C performs the same function.





Pasting from the Gizmo

Pasting data from a Gizmo makes it possible to transfer parts of a Landscape from one location to another. The data can either be pasted completely to create an identical feature, or it can be painted to the new location using brush strokes and strength settings to partially transfer the feature.

Before data can be pasted from a Gizmo, it must first be copied to a Gizmo.

To paste Gizmo data:

Move, rotate, and scale a Gizmo that contains data so that it covers the area you wish to paste the data to.





Paste the data using one of the available brushes (Circle, Pattern, Alpha, Gizmo) to "paint" the data from the Gizmo.

The Gizmo brush is used to fully paste the data from the Gizmo. Pressing Ctrl + V also fully pastes the data from the Gizmo.

Other brushes can be used to paint the data from the Gizmo using the current brush size and strength.





Gizmo Data Import/Export

Heightmap data can be imported from and exported to the Gizmo through the Gizmo Import/Export section in the Landscape Editor.



To import data to the Gizmo:

Click the browse for file button ( ) and select the heightmap file (16-bit raw file) you want to import to the Gizmo.

Since the import process uses the .raw file format, there is no way to correctly determine which dimension is which. UE4 will populate a dropdown menu with several different sizes that can be accessed by clicking the down arrow shown above. You may need to try a few different sizes before you find the one that works for your Landscape.

If you want to import layer weight information as well, press the Add Layer button ( ) to add as many layers as desired.

Select the layer weightmap file (8-bit raw file) to import for each layer. The file and layer name will be filled in. The layer name uses the name of the file by default. Change the layer name if needed. Enabling the No Import checkbox will prevent any individual layer information from being imported.

The Layer Name must match the name of a layer that exists on the Landscape or the import will fail.



Once the heightmap and any layers are selected, press the Import to Gizmo button to import the data to the Gizmo.If the dimensions are not correct, you may see something similar to this:



Reverse the dimensions and re-import to get the correct result. If the dimensions were correct, the Gizmo should show the correct data.

To Export Gizmo Data:

With the Gizmo populated with data (see Copying to the Gizmo), press the Export Gizmo Data button to export the Gizmo data to a file. Enabling the Gizmo copy/paste all layers checkbox at the top of the Gizmo options will export the heightmap and all layers' weight data to files.

Choose a location and name for the heightmap file.

If exporting layers, choose locations and filenames for each exported layer.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Landscape Selection

Components

Component Tools

Component Properties

In Manage Mode, you can create new Landscapes and use the component tools to modify an existing Landscape's components. You can also select components and modify their properties in the Details panel.

For information about creating Landscapes, see Creating Landscapes.

Landscape Selection

In the Landscape panel, select which Landscape to modify from a list of all the Landscapes currently in your level.



To select a Landscape:

In the Landscape panel click the Landscape drop-down box in the Landscape Editor section to display a list of all Landscapes currently in the map.

Choose the Landscape you want to edit.

Selecting a Landscape from the list makes that the active Landscape. All subsequent editing will then be applied to that Landscape.

Components

Components are the building blocks of any Landscape Actor. You can work with them using the Component tools and adjust their properties individually in the Details panel.

Component Tools

The tools described below act on the component level of the currently selected Landscape.



The Selection tool selects Landscape components for subsequent use with other tools, such as moving them to a streaming level or deleting components.

Control

Operation

Left Mouse Button click

Toggles the selection of the component.

Shift + Left Mouse Button click

De-Selects components.

The selection cursor is always limited to one component:



When components have been selected, they become shaded red:



Option

Description

Clear Component Selection

Clears the current selected component(s).



The Add tool creates new components for the current Landscape, one at a time.

Control

Operation

Left Mouse Button click

Adds a new component.

When the Add Landscape Component tool is active, the cursor shows a green wireframe where new components can be added:



Using the tool adds a new component where the cursor is located:





The Delete tool deletes any selected components.

Control

Operation

Left Mouse Button click

Deletes highlighted components selected by the Selection tool. If no components are currently selected, deletes the component highlighted by moving the mouse cursor over it.



Using the tool removes the selected components:





This tool moves the selected components, via using the Selection tool, to the current streaming level. This makes it possible to move sections of a Landscape into a streaming level so that they will be streamed in and out with that level, optimizing the performance of the Landscape.

When the streaming level is visible, the Landscape renders all the components:



You can toggle the visibility of the level by clicking the eye icon ( ) for that level in the Levels panel (accessible on the Level Editor's Window menu). Doing so causes the components in that level to no longer be rendered:





Landscape Splines are a flexible system for creating any linear feature that needs to conform to a Landscape, and can even push and pull the terrain to better facilitate building these features. They are created and edited using the spline tool in the Landscape tool.



For information about how to create and modify spline curves, see Landscape Splines.

Component Properties

You can set the properties of individual components, including LODs and component-specific Materials, in the Details panel.

You can also set LODs for selected component, which means an individual component can have its own LOD settings.

To set LODs for selected component:

Select the components whose LODs you want to set. For information about selecting components, see Selection.

In the Details panel, under Landscape Component, adjust the Forced LOD and LODBias settings to obtain the desired result.



You can set a Material Override for selected components, which means that an individual component can have a different Material assigned to it than its Landscape does.

To set a Material Override for selected components:

Select the components that you want to use a different Material for. For information about selecting components, see Selection.

In the Content Browser, find and select the Material you want to use.

In the Level Editor's Details panel, under Landscape Component, click the Assign arrow icon ( ) to assign that Material to the selected components.



Creating a Spline

Joining and Splitting Splines

Adding a Static Mesh Actor to a Spline

Editing a Spline

Applying Splines to the Landscape

Spline Properties

Control Point Properties

Spline Segment Properties

Controls Reference

Landscape Splines are a flexible system for creating any linear feature that needs to conform to a Landscape, and can even push and pull the terrain to better facilitate building these features. They are created and edited using the spline tool in the Landscape tool.

The Spline tool is best used to make streets or paths in the environment, but in general, it can be used for any mesh that must conform to the terrain, such as cobblestone walls or long straight rows of corn.

Creating a Spline

Under the Manage tab, select Splines.



Press Ctrl + Left-click to set your spline's first control point. The control point's sprite looks like a sculpted, Landscape mountain.



Press Ctrl + Left-click again to create another control point and connect it to the first point by a spline segment. The selection changes to the new control point so that you can repeat this action and add more control points.



Alternatively, you can use ALT + Left Mouse Button (LMB) Drag to create a new spline control point and segment. Select an existing control point and ALT+LMB Drag in the direction you want to place the new point. If you select the point at either end of the spline, ALT+LMB Drag adds a new segment and extends the spline. As you drag the point, you will see what the new segment will look like in the viewport.

Joining and Splitting Splines

To join two splines, select one spline and then Ctrl + Left-click on the other.

To split a spline, press Ctrl + Left-click on a segment. This splits the segment at that point and inserts a new control point.

In addition to Ctrl + Left-click, you can use ALT+LMB Drag to split a spline. Select a spline point on either side of the segment and ALT+LMB Drag the cursor towards an existing segment to split the path.If Use Auto Rotate Control Point is enabled, after you release the cursor, the spline point auto-rotates to maintain a smooth spline.



Adding a Static Mesh Actor to a Spline

In the Content Browser, find and select the Static Mesh asset that you want to use with your spline.

Click on a spline control point on your Landscape.

In the Level Editor's Details panel, in the Landscape Spline section, next to Select all connected, click the Segments button. This ensures that the Static Mesh is added to all the spline's segments.



In the Landscape Spline Meshes section, under Spline Meshes, if there is no element, click the plus icon ( ) to add one.



Expand the element you just added. Next to Mesh, click the Assign arrow icon ( ) to assign the selected Static Mesh.



You can also assign a Static Mesh to an individual control point by selecting that control point and assigning the Static Mesh in the Details panel, in the Mesh section.

Editing a Spline

Spline control points respond as you would expect to the translation and rotation tools, but the scale tool brings up a different tool, spline tangents.



If a segment is selected, it shows the tangents at each end of the segment, and if a control point is selected, it shows the tangents of all connected segments. You can adjust the scale of the tangent by dragging the end of it, which alters how curved the segment of spline is.

Applying Splines to the Landscape

The Apply Splines to Landscape button modifies the Landscape heightmap and layer weightmaps with the spline information. The heightmap is raised or lowered to fit the spline, with a smooth cosine-blended falloff on either side. This is controlled by the width and falloff properties of the spline control points, and the Raise/Lower Terrain option on the individual spline segments. The Texture layer that is painted (if any) is specified in the Layer Name property of the individual spline segments, and the painting is affected by the spline width and falloff settings in the control points.

Spline Properties

The properties of the selected control points or segments are displayed in the Level Editor's Details panel.

Control Point Properties

Property

Description

Location

Position of the control point relative to the Landscape.

Rotation

Rotation of the control point, and controls the direction of the tangent of any attached spline segments.

Width

Width of the spline, and shown as solid lines. Affects all connected segments.

Side Falloff

The width of the cosine-blended falloff region on either side of the spline, and shown as dotted lines.

End Falloff

Control point at the end of a spline with only one attached segment. The length of the cosine-blended falloff region smoothly ends the spline segment.

Layer Name

Name of the painted blendmask layer when applying the spline to the Landscape.

Raise Terrain

Raises the Landscape to match spline when applying the spline to the Landscape. Good for roads on embankments.

Lower Terrain

Lowers the Landscape to match spline when applying the spline to the Landscape. Good for rivers and ditches.

Spline Segment Properties

Property

Description

Connections

Settings specific to the two control points attached to the segment.

Connections Sub-Properties

Tangent Len: Scale of the tangent at this point, and controls the segment curve. Negative tangents cause the segment to connect to the back of the control point.

Socket Name: Overrides the Static Mesh's assigned Material with a different Material for the spline.



Layer Name

Name of the painted blendmask layer when applying the spline to the Landscape.

Raise Terrain

Raises the Landscape to match spline when applying the spline to the Landscape. Good for roads on embankments.

Lower Terrain

Lowers the Landscape to match spline when applying the spline to the Landscape. Good for rivers and ditches.

Property

Description

Spline Meshes

The meshes applied to the spline. Multiple meshes will be applied in random order controlled by the random seed.

Spline Meshes Sub-Properties (per mesh used)

Mesh: The Static Mesh applied to the spline.

Material Overrides: Socket on the control point connected to the end of the segment.

Center H: Determines whether to horizontally center the mesh on the spline or use the mesh's origin.

Offset: Offsets the mesh from the spline (units are in mesh-space, unscaled by the spline).

Scale to Width: Determines whether to scale the mesh to fit the spline width or to use the mesh as-is.

Scale: Multiplier to the size of the mesh. If Scale to Width is enabled, the Scale specified here is relative to the spline width. Otherwise, it is relative to the mesh's natural size.

Forward Axis: Chooses the forward axis of the Spline Mesh.

Up Axis: Chooses the Up axis of the Spline Mesh.



Collision Profile Name

Name of the Collision Profile to use with this spline.

Cast Shadow

Enables the casting of shadows by the mesh.

Random Seed

Controls the application order of multiple spline meshes to the spline.

Max Draw Distance

Max Draw Distance for all the meshes used in the spline.

Translucency Sort Priority

Sets the sort priority of translucent objects. Ignore if your meshes are not translucent. The default priority is zero.

Hidden in Game

Hides the Static Meshes in game.

Place Spline Meshes in Streaming Levels

Determines whether spline meshes should be placed in Landscape proxy streaming levels or the spline's level. Default is True.

Controls Reference

Controls

Operation

Left Mouse Button

Selects a control point or segment.

Shift + Left Mouse Button (LMB)

Selects multiple control points or segments.

Ctrl + A

Selects all control points connected to the currently selected control points and/or all segments connected to the currently selected segment.

Ctrl + LMB

Adds a new control point, and automatically connects to any selected control points.

With a control point or multiple control points selected, creates a segment joining any selected control points to the new control point.

With a segment selected, splits the segment at that point and inserts a new control point.

ALT + LMB Drag

With a control point selected, adds a new control point and translates it in the direction of the drag.

Splits the path when dragged through an existing segment.

Adds a new segment when dragged away from either end of the spline.

Del

Deletes the selected control points or segments.

R

Automatically calculate rotation for selected spline control points.

T

Automatically flip the tangents for the selected control points / segments.

F

Flips selected spline segments (only affects meshes on the spline).

End

Snaps the selected control points to the Landscape below.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Painting Tools

Paint

Smooth

Flatten

Noise

Layers

Layer Info Objects

Orphaned Layers

Weight Editing

The tools in Paint mode enable you to modify the appearance of your Landscape by selectively applying Material layers to parts of your Landscape Actor.

For more information about Landscape Materials, see Landscape Materials.

Painting Tools

You can use the Painting Tools to modify the appearance of your Landscape by selectively applying layers of specially designed Landscape Materials to sections of it.

Common Controls

Operation

Left Mouse Button

Performs a stroke that applies the selected tool's effects to the selected layer.

Ctrl+Z

Undo last stroke.

Ctrl+Y

Redo last undone stroke.

The Paint Tools have some common options:

Option

Description

Tool Strength

Controls how much effect each brush stroke has.

Use Region as Mask

When checked, the region selection acts as a mask with the active area being comprised of the selected region.

Negative Mask

When checked, and when Use Region as Mask is also checked, the region selection acts as a mask, but the active area is comprised of the unselected region.

For more information about Landscape Material layers, see Layers, later on this page.

Paint



The Paint tool increases or decreases the weight of the Material layer being applied to the Landscape, in the shape of the currently selected brush and falloff.

Additional Option

Description

Use Target Value

If checked, blends the values of the noise being applied toward a target value.

Smooth



The Smooth tool averages the layer weights across the area on which the tool is used. The strength determines the amount of smoothing.

Layer Smoothing





Additional Option

Description

Filter Kernal Scale

Sets the scale multiplier for the smoothing filter kernel.

Detail Smooth

If checked, performs a detail preserving smooth using the specified detail smoothing value. Larger detail smoothing values remove more details, while smaller values preserve more details.

Flatten



The Flatten tool directly sets the selected layer's weight to the value of the Tool Strength slider.

Additional Option

Description

Flatten Mode

Determines whether the tool will increase or decrease the application of the selected layer's weight, or do both.

Noise



The tool applies a noise filter to the layer weight. The strength determines the amount of noise.

Additional Option

Description

Use Target Value

If checked, blends the values of the noise being applied toward a target value.

Noise Mode

Determines whether to apply all noise effects, only the noise effects that result in increasing the application of the layer, or only the noise effects that result in reducing the application of the layer.

Noise Scale

The size of the perlin noise filter used. The noise filter is related to position and scale, which means if you do not change Noise Scale, the same filter is applied to the same position many times.

Layers

A layer is the part of the assigned Landscape Material that you want to paint onto your Landscape to change its appearance.

Landscape layers determine how a texture (or material network) is applied to a Landscape Actor. A Landscape can use multiple layers with different Textures, scaling, rotation, and panning blended together to create the final textured terrain.

The layers defined in the Landscape Material automatically populate the list of Target Layers in the Landscape tool's Paint mode. Each layer is displayed with its name and a small thumbnail image.



Whichever layer is selected is the one you can apply to the Landscape with the Paint Tools, according to the tools' options and settings, and to the brush you are using.



Many of the Paint Tools are similar to the Sculpting Tools, and you use them similarly, but to manipulate the weight of layers instead of the heightmap.

You create layers in the Material itself. For more information about layers and Landscape Materials, see Landscape Materials.

Layer Info Objects

A layer info object is an asset that contains information about a particular Landscape layer. Every Landscape layer must have a layer info object assigned to it, or else it cannot be painted. You can create layer info objects from the Landscape panel.

There are two kinds of layer info object, Weight-Blended and Non Weight-Blended:

Weight-Blended - Painting a weight-blended layer will decrease the weight of all other weight-blended layers. For example, painting mud will remove grass, and painting grass will remove mud. This is the most commonly used type of layer info object.

Non Weight-Blended - Layers that are independent of each other. Painting a non weight-blended layer does not affect the weights of the other layers. These are used for more advanced effects, such as blending snow onto other layers: instead of having grass, mud, rock or snow, you would use a non weight-blended snow layer to blend between "grass, mud, or rock" and "snowy grass, snowy mud, or snowy rock."

You can either create a layer info object from the layer itself, or reuse an existing layer info object from another Landscape.

To create a layer info object:

Press the Plus icon to the right of the Layer name.

Choose Weight-Blended Layer (normal) or Non Weight-Blended Layer.

Choose the location to save the layer info object.

After their creation, layer info objects exist as assets in the Content Browser:



They can then be reused by other Landscapes.

Even though it is possible to use the same layer info object in multiple Landscapes, within a single Landscape you can use each layer info object only once. Each layer in a Landscape must use a different layer info object.

To reuse an existing layer info object from another Landscape:

Find and select the layer info object in the Content Browser.

In the Landscape panel, in the Target Layers section, to the right of the layer with which you want to use the layer info type, click the Assign icon ( ).

Layer info objects can only be used if their layer name matches the layer they were originally created for.

The primary purpose of layer info objects is to act as a unique key for painted layer data, but they also contain a couple of user-editable properties:

Option

Description

Phys Material

The Physical Material (if any) assigned to areas of Landscape where this layer is dominant.

Hardness

The value used by the Erosion tool.

Orphaned Layers

If a layer is removed from the Landscape Material after it has been populated in the Target Layers list of a Landscape and it has painted data on the Landscape, it will be displayed in the list with a ? icon. This denotes an orphaned layer.



Areas previously painted with this layer will likely appear black, but the exact behavior depends on your Landscape Material.

You can delete orphaned layers from the Landscape, though it is recommended that you first paint over any areas where the layer was used. The painted layer data is preserved until the layer is deleted, so no information is lost if you make a mistake in the Landscape Material.

To delete a layer from your Landscape:

Click the X icon to the right of the layer's name.



Weight Editing

At every Landscape vertex, each layer has a weight specifying how much influence that layer has on the Landscape. Layers have no particular blending order. Instead, each layer's weight is stored separately and the results added. In the case of weight-blended layers, the weights add up to 255. Non weight-blended layers are independent of other layers and can have any weight value.

You can use the Paint tool to increase or decrease the weight of the active layer. To do so, select the layer whose weight you want to adjust, and use one of the Paint tools to apply the layer to the Landscape. For Weight-Blended layers, as you increase the weight of one layer, the weight of the other layers will be uniformly decreased. Fully painting one layer will result in no weight on any other layer.

When you are reducing a weight-blended layer by holding down Ctrl + Shift while painting, it is not clear what layer should be increased to replace it. The current behavior is to uniformly increase the weights of any other layers. Because of this behavior, it is not possible to paint all layers completely away. Instead of painting layers away, it is recommended you choose the layer you want to paint in its place, and paint that additively.

Landscape Brushes

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Tool Workflow

Sculpting Tools

Region Tools

The process of sculpting a Landscape involves using a variety of tools that modify the underlying heightmap. These tools range from the simple Sculpt tool that paints height values using a brush and strength scale, to many other tools that use complex algorithms to apply interesting effects to the heightmap, such as erosion. Each tool has a set of properties that determines how the tool affects the Landscape.



Tool Workflow

Once you've created your Landscape, you will have access to the other features of the Landscape tool. To use sculpting, select the Sculpt mode tab.

Once selected, the Sculpt tool options will become available for choosing the type of sculpting tool along with the brush style and falloff type you would like to use to apply their effects to your landscape heightmap using strokes.



With your Sculpting tool selected, you can now use the following controls to start sculpting your landscape:

Common Controls

Operation

Left Mouse Button

Performs a stroke that applies an additive application of the selected tool's effects to the heightmap and raises the terrain.

Left Mouse Button + Shift

Performs a stroke that applies an subtractive application of the selected tool's effects to the heightmap and lowers the terrain.

Ctrl + Z

Undo last stroke.

Ctrl + Y

Redo last undone stroke.

Sculpting Tools

Use the Sculpting Tools to modify the shape of your Landscape in various ways. Explore the different sculpting selections available below:



Region Tools

Use the Region Tools to perform actions on specific regions of the Landscape. Explore the different Region options available below:







Using the Copy/Paste Tool

Tool Settings

The Copy/Paste tool will copy the height data from one area of a Landscape to another area through the use of the gizmos. You can also import existing heightmap data that can be pasted into the Landscape or export selected regions of your height data as it's own heightmap .raw file for use in an external program.

Using the Copy/Paste Tool

In this demonstration, the gizmo is manually scaled to copy a region and then paste it in another location, and then the Region Selection is used to paint an area the gizmo can automatically scaled to fit so that it can be copy and pasted to another location.

Copy/Paste Gizmo

The Gizmo is used to capture the Landscape's height data that can then be copied to other parts of the Landscape. This enables you to easily move parts of your Landscape, import height data from an existing heightmap, or to export your height data to a heightmap file that can be used with an external program, like World Machine.







In these examples, the gizmo bounds have been scaled around a painted region that is to be captured, then the gizmo is positioned to another part of the Landscape, and, lastly, it's pasted onto the existing Landscape.

To learn how to use the gizmo, you can read about the gizmo tool here.

Tool Settings





Property

Description

Copy Data to Gizmo

Copies the data within the gizmo bounds to the gizmo taking into account any masking from the selected regions.

Fit Gizmo to Selected Regions

Positions and resizes the gizmo so that it completely encompasses all region selections.

Fit Height Values to Gizmo

Scales the data in the gizmo to fit the gizmo's Z-size.

Clear Gizmo Data

Clears the gizmo of any copied data.

Tool Strength

Strength of the tool. If you're using a pen/tablet with pressure-sensing, the pressure used affects the strength of the tool.

Paste Mode

Whether the past will only raise, only lower, or both raise and lower.

Both: The paste will raise and lower values where the data would be.

Raise: The paste may only raise values and pastes where the data would be. Any areas below the heightmap are left unchanged. This is good for copying and pasting mountains.

Lower: The paste may only lower values and pastes where the data would be. Any areas above the heightmap are left unchanged. This is good for copying and pasting valleys or pits.



Gizmo Copy/Paste All Layers

Copies and pastes all layers. Otherwise, it will only copy and paste the layer selected in the targets panel.

Snap Gizmo to Landscape Grid

Makes sure the gizmo is snapped perfectly to the Landscape so that the sample points line up, which makes copy and pastes less blurry. Irrelevant if gizmo is scaled.

Use Smooth Gizmo Brush

Smooth the edges of the gizmo data into the Landscape. Without this, the edges of the pasted data will be sharp.



Advanced



Gizmo Import/Export

The available options that can be used when importing or exporting the selected region's heightmap.

Heightmap: Set the import file path for the heightmap file you want to import.

Heightmap Size: The size of the heightmap data that is being imported. This property should not have to be adjusted.

Layer Filename: Set the import file path for the heightmap data used for painted layers.

Layer Name: Set the name of the imported heightmap layer.



Adding Landscape Blueprint Brushes to Edit Layers

Built-In Landscape Blueprint Brush Types

CustomBrush_Landmass Brush

Blend Modes

Shape Capping

Falloff

Noise

CustomBrush_LandmassRiver Brush

CustomBrush_MaterialOnly Brush

Landscape Blueprint Brushes provde a stack of user-defined sculting brushes that can be manipulated non-destructively, so that any changes to a brush lower in the stack automatically flow through to the brushes above it in the stack. These brushes can be used to layer multiple terrain manipulations on top of one another while maintaining separation of those manipulations, enabling them to be reordered or moved around the terrain as necessary.



To use Landscape Blueprint Brushes, you must enable the Landmass plugin in the Plugins Browser and check Enable Edit Layers when creating your Landscape.

To enable the Landmass plugin in the Plugins Browser:

From the main menu, open the Plugins Browser.



Search for Landmass and click Enable.



To enable Edit Layers when creating your Landscape:

Check the Enable Edit Layers property in the New Landscape section.



Adding Landscape Blueprint Brushes to Edit Layers

To add a new Landscape Blueprint Brush to an existing Edit Layer:

With the Landsape mode selected in the Level Editor Toolbar, select the Sculpt tab and select Blueprint from the available sculting tools.



Click the Blueprint Brush dropdown and select one of the available types of brushes.



In the viewport, click the Landscape to add the new brush.



Built-In Landscape Blueprint Brush Types

CustomBrush_Landmass Brush

The CustomBursh_Landmass brush generates a landmass shape from a user-defined spline shape and a collection of configurable effects—such as erosion, curl noise, and displacement—and applies the resulting shape to the terrain



The Blend Mode determines how the shape is added to, or cut into, the terrain—similar to CSG or boolean operations. There are four blend modes available:

Blend Mode

Description

Alpha Blend



Min



Max



Additive



The shape generated by a Landmass brush can either be capped or uncapped. If the shape is capped, it resembles a plateau with a flat top. An uncapped shape resembles a mountain or hill with a peak.





Cap Shape enabled

Cap Shape disabled

Falloff determines the slope of the transition from the brush shape to the underlying terrain.

Type

Description

Angle

The falloff slope is determined by a specified angle. Larger falloff angles result in steeper slopes. For uncapped shapes, the falloff continues inside the shape as well to form a peak.







30 degrees

45 degrees

60 degrees



Width

The falloff slope is determined by specifying a distance in Unreal Units. Smaller falloff distances result in steeper sloes.







100 units

200 units

400 units



Noise applies up to two octaves of curl noise to the generated landmass shape.

Property

Description

Curl [1/2] Strength

Sets the amplitude of the noise applied to the landmass shape.







Strength 0

Strength 1

Strength 2



Curl [1/2] Tiling

Sets the frequency of the noise applied to the landmass shape.







Tiling 0

Tiling 5

Tiling 15



CustomBrush_LandmassRiver Brush

The CustomBrush_LandmassRiver brush extrudes a Static Mesh along a user-defined spline and raises or lowers the terrain to match the extruded mesh. This brush is useful for laying out roads or rivers where the terrain automatically adjusts to match up.



CustomBrush_MaterialOnly Brush

The CustomBrush_MaterialOnly brush uses a Material to apply procedural noise to the whole terrain to form a base.



Using the Erosion Tool

Tool Settings

The Erosion tool uses a thermal erosion simulation to adjust the height of the Landscape heightmap. This simulates the transfer of soil from higher elevations to lower elevations by natural forces. The larger the difference in elevation, the more erosion will occur. This tool also applies a noise effect on top of the erosion, if desired, to provide a more natural random appearance.

Using the Erosion Tool

In this example, the Erosion tool is being used on the front and back sides of the mountain face. On the front side, the incline is not as steep, so the surface is not eroded as quickly with the settings being used. However, on the back side, the incline is much steeper and erodes much more quickly.

Use the following controls to Sculpt with Erosion for your Landscape heightmap:

Controls

Operation

Left Mouse Button

Applies erosion values that raises, lowers, or does both to the the heightmap.





In this example, Erosion uses noise painted onto the hillside to raise or lower the surface giving it variations in different heights based on the strength and various property values used to drive the erosion being applied.

Tool Settings





Property

Description

Tool Strength

Controls how much effect each brush stroke has.

Threshold

The minimum height difference necessary for the erosion effects to be applied. Smaller values will result in more erosion being applied.

Surface Thickness

The thickness of the surface for the layer weight erosion effect.

Iterations

The number of iterations performed. Larger values result in more levels of erosion.

Noise Mode

Whether to apply noise to raise or lower the heightmap, or do both.

Both: Raises and lowers values for all erosion effects applied to the heightmap.

Raise: Applies erosion effects that result in raising the heightmap.

Lower: Applies erosion effects that result in lowering the heightmap.



Noise Scale

The size of the noise filter used. The noise filter is related to position and scale, which means if you do not change Noise Scale, the same filter is applied to the same position many times.

Using the Flatten Tool

Tool Settings

The Flatten tool pushes or pulls all other parts of the heightmap to the level that is currently under the mouse when activated. This can raise or lower the surrounding heightmap values to be the same value.

Using the Flatten Tool

In this example, the Flatten tool is being used in the middle of the hillside to flatten out areas at the point where the mouse click was initiated. As long as the mouse is held down, the height value that was detected is used along any surface to raise or lower (depending on your tool settings) to that height.

Use the following controls to sculpt your Landscape heightmap:

Controls

Operation

Left Mouse Button

Flattens or levels by both raising and lowering or individually raising and lowering the heightmap.





The brush strength determines the amount of Flattening that can happen when using the Flatten tool.

Tool Settings





Property

Description

Flatten Target

Sets the target height toward which to flatten.

Tool Strength

Controls how much smoothing occurs with each brush stroke has.

Flatten Mode

Determines whether the tool will raise or lower the heightmap section under the brush.

Both: Raises and lowers values to the current height value when the mouse click is activated.

Raise: Raises values that are lower than the currently selected height when the mouse click is activated. Any values above this clicked point will be left unchanged.

Lower: Lower values that are higher than the currently selected height when the mouse click is activated. Any values lower than this clicked point will be left unchanged.



Use Slope Flatten

If checked, flattens along the Landscape's existing slope instead of flattening toward a horizontal plane.

Pick Value Per Apply

If checked, constantly selects new values to flatten toward, instead of only using the first clicked point.



Advanced



Show Preview Grid

When Flatten Target is enabled, you can enable this option to show a preview grid for the flatten target height.

Terrace Interval

Sets the height of the Terrace interval for Terrace Flatten mode.

Terrace Smoothing

Sets the smoothing value for Terrace Flatten mode

Using the Hydro Erosion Tool

Tool Settings

The Hydro Erosion tool uses a hydraulic erosion simulation (erosion by water) to adjust the height of the Landscape heightmap. A noise filter is used to determine where the initial rain is distributed for the simulation. Then the simulation is calculated to determine water flow from the initial rain as well as dissolving, water transfer, and evaporation. The result of the calculation provides the actual value used to lower the heightmap.

Using the Hydro Erosion Tool

In this example, the Hydro Erosion tool has been used to paint rain erosion onto the surface of the hillside. This makes it appear that parts of the Landscape have eroded away over time as rain has fallen. The tool settings can enable the amount of rain and areas that it affects to help define the look.

Use the following controls to Sculpt with Hydro Erosion for your Landscape heightmap:

Controls

Operation

Left Mouse Button

A noise filter is used to erode parts of the heightmap.





In this example, as Hydro Erosion is used to paint onto the Landscape the heightmap runs a simulation that treats the heightmap as if rain has eroded away its surface over time. This can create interesting looks and crevices to the Landscape.

Tool Settings





Property

Description

Tool Strength

Controls how much effect each brush stroke has.

Rain Amount

The amount of rain to apply to the surface. Larger values will result in more erosion.

Sediment Cap.

The amount of sediment that the water can carry. Larger values will result in more erosion.

Iterations

The number of iterations performed. Larger values result in more levels of erosion.

Initial Rain Distribution

Whether rain is applied randomly or to the entire area.

Selection

Description

Both

This will use a random pattern that acts like it has rained in some places and not others to erode parts of the heightmap.

Positive

This will act as if it has rained in all parts of the applied area to erode parts of the heightmap.



Rain Dist Scale

The size of the noise filter for applying initial rain to the surface. The noise filter is related to position and scale, which means if you do not change Rain Dist. Scale, the same filter is applied to the same position many times.

Detail Smooth

If checked, performs a detail-preserving smoothing to the erosion effect using the specified detail-smoothing value. Larger detail-smoothing values remove more details, while smaller values preserve more details.

Using the Mirror Tool

Tool Settings

The Mirror tool enables you to mirror or rotate the existing Landscape heightmap geometry along the X or Y axis.

In this example, the Mirror tool is used to mirror the entire entire Landscape Actor along the Y axis.

Using the Mirror Tool

In the Landscape toolbar, in Sculpt tab, select the Mirror tool.



Use the Operation drop-down selection to choose the axis and mirroring method you would like to use for your selected landscape. The directional arrow indicates which side of the landscape geometry will be mirrored on.



If necessary, adjust the Mirror Point values for the mirror plane or Left-click and drag the directional arrow on mirror plane into the position you want to mirror.

Only the currently selected Operation axis will be used for the Mirror Point. For example, if the Operation method is "-X to +X" the X axis is the only active Mirror Point that will be affected.



Once you are satisfied with your edits, you can hit the Apply button to see the results.



You now have a landscape with mirrored geometry.

Mirror Smoothing Width

If the edge seams from mirroring your landscape look unnatural or too sharp in contrast after you apply your changes you can use CTRL + Z to undo your last action. Then you should adjust the Smoothing Width so that these edge vertices that are merged are softened.





In this example, the left image has no smoothing applied after the Landscape is mirrored, whereas the right is using a value of 10 to smooth the mirrored edges and reduce the harshness of the seam.

Tool Settings





Property

Description

Mirror Point

This sets the location of the mirror plane. This will default to the center of the selected Landscape and in most cases will not normally need to be changed.

Operation

The type of mirroring operation to perform. For example, -X to +X will copy and flip the -X half of the Landscape onto the +X half.

Recenter

This button places the mirror plane back at the center of the selected Landscape.

Smoothing Width

This will set the number of vertices on either side of the mirror plane to smooth over reducing sharp contrasting angles for mirrored sides.

Using the Noise Tool

Tool Settings

The Noise tool applies a noise filter to produce variations in the surface of the Landscape heightmap.

Using the Noise Tool

In this example, the Noise tool is used to paint on the Landscape, similarly to how Sculpt would be used, and in doing so variations are painted around this area that raise and lower the heightmap based on the tool settings. This enable you to paint grande or subtle variations into your Landscape.

Use the following controls to Sculpt with Noise for your Landscape heightmap:

Controls

Operation

Left Mouse Button

Heightens or increases the heightmap or selected layer's weight.





In this example, Noise has been painted onto the smooth Landscape surface giving it variations in different heights based on the strength and property values used.

Tool Settings





Property

Description

Tool Strength

Controls how much effect each brush stroke has.

Use Target Value

If checked, blends the values of the noise being applied toward a target value.

Noise Mode

Determines whether to apply all noise effects, only the noise effects that result in raising the heightmap, or only the noise effects that result in lowering the heightmap.

Both: Raises and lowers values for painted values of Noise to the heightmap when the mouse click is activated.

Add: Raises values when painting Noise to the heightmap when the mouse click is activated.

Sub: Lowers values when painting Noise to the heightmap when the mouse click is activated.



Noise Scale

The size of the perlin noise filter used. The noise filter is related to position and scale, which means if you do not change Noise Scale, the same filter is applied to the same position many times.

The brush strength determines the amount of raising or lowering that can happen when using the Noise tool.

Using the Ramp Tool

Tool Settings

The Ramp tool enables you to select two locations on your Landscape and create a flat ramp between the two points, with a falloff you specify for the sides.

Using the Ramp Tool

In the Landscape toolbar, in the Sculpt tab, select the Ramp tool.



In the viewport, Left-click and drag or simply Left-click in two different places on your Landscape to mark the beginning and end points of the ramp.



If you change your mind about adding a ramp after starting to set the beginning and end points, you can click Reset to clear them.

Select either marker and adjust its position. In this case, it has been moved along the Z-axis above the Landscape surface.



When you are satisfied with the position, click the Add Ramp button in the Tool Settings to create the ramp.



Now you have a ramp that has been sculpted into your heightmap.



Tool Settings





Property

Description

Ramp Width

Sets the width of the ramp.

Side Falloff

Sets the edge falloff on the sides of the ramp where it merges inot the rest of the landscape. This falloff gives a softness to the edge flow on these sides. A setting of 0 means no falloff; a setting of 1 means all falloff and no flat surface for the ramp.

Using the Region Selection Tool

Tool Settings

The Region Selection tool selects regions of the Landscape using the current brush settings and the tool strength to be used to fit a Landscape gizmo to a specific area or to act as a mask for copying data to, or pasting data from, a gizmo.

Using the Region Selection Tool

In this example, the Region Selection tool has been used to paint an area of the Landscape using the default positive method, then switching to the negative mask method that enables you to paint areas that don't want to include, and finally showing the Use Region As Mask section that captures the entirety of a Landscape component that is painted rather than just areas within it.

Use the following controls to paint areas that can be used for selection by doing the following:

Controls

Operation

Left Mouse Button

Adds to the selected region.

Shift + Left Mouse Button

Removes from the selected region.





In this example, an area has been painted for selection that can then be used for masking layers or with the Copy/Paste tool.

Tool Settings





Property

Description

Clear Region Selection

Clears the current selected region(s).

Tool Strength

Controls how much effect each brush stroke has.

Use Region as Mask

When checked, the region selection acts as a mask with the active area being comprised of the selected region.



Negative Mask

When checked, and when Use Region as Mask is also checked, the region selection acts as a mask, but the active area is comprised of the unselected region.



Using the Retopologize Tool

The Retopologize tool automatically adjusts Landscape vertices with an X/Y offset map to improve vertex density in areas that need it, like steep cliffs. This allows for reduced texture stretching in these types of areas by spreading the vertices into these areas that are less dense.

An X/Y offset map will make the Landscape slower to render and paint on with other tools, so only use the Retopologize tool if needed.

Using the Retopologize Tool

In this example, we have a steep incline that was created by flattening an area, however, it left these vertical areas with fewer Landscape vertices spread across the surface which caused the textures to appear stretched and some jagged artifacts around the edges of the flattened area. By using the Retopologize tool the surrounding vertices have been pulled and redistributed without significantly altering the work that was done to make the flattened area. This reduces the stretching and jagged edges that appear.

Use the following controls to paint an X/Y offset map to retopologize your Landscape heightmap:

Controls

Operation

Left Mouse Button

Heightens or increases the heightmap or selected layer's weight.

Retopologize Lit View





Retopologize Wireframe View





In these comparison examples, you can see how the texture stretching has been reduced in these sharp inclines for the lit view and with the wireframe view you can see how the vertices have been redistributed to be more evenly spaced in these steep inclines.

Tool Settings



There are no tool settings specific to Retopologize that can be adjusted. Simply select the tool from the selection and paint the areas in your Landscape that need to have their vertex density redistributed.

Using the Sculpt Tool

Tool Settings

The Sculpt tool enables you to raise and lower the height of the Landscape heightmap in the shape of the currently selected brush and falloff.

Using the Sculpt Tool

In this example, the Sculpt tool applies height values to raise or lower the height data for the Landscape. Simply clicking and applying movement over the region you want to paint will adjust the values based on the tool settings used.

Use the following controls to sculpt your Landscape heightmap:

Controls

Operation

Left Mouse Button

Heightens or increases the heightmap or selected layer's weight.

Shift + Left Mouse Button

Lowers or decreases the heightmap or selected layer's weight.

Tool Settings





Property

Description

Tool Strength

Controls how much effect each brush stroke has. If you're using a pen/tablet with pressure-sensing used, this will affect the strength of the tool.

Use Target Value

Enables a target value that the tools blend toward with each brush stroke.

The brush strength determines the amount of raising or lowering that can happen when using the Sculpting tool.

Using the Smooth Tool

Tool Settings

The Smooth tool will soften the heightmaps painted values to give your Landscape a smoother flow and appearance by getting rid of jagged artifacts that can sometimes happen after using the Sculpting or Erosion tools.

Using the Smooth Tool

In this example, the Smooth tool is used to soften some of the harder edge artifacts that can happen when using the various Landscape tools.

Use the following controls to sculpt your Landscape heightmap:

Controls

Operation

Left Mouse Button

Smoothens and softens the heightmap or selected layer's weight.





The Brush Strength determines the amount of smoothing that can happen when using the Smooth tool.

Tool Settings





Property

Description

Tool Strength

Controls how much smoothing occurs with each brush stroke.

Filter Kernel Scale

Sets the scale multiplier for the smoothing filter kernel for the radius that smoothing will be performed over. Higher values smooth out bigger details, while lower values only smooth out smaller details.

Detail Smooth

If checked, performs a detail-preserving smoothing using the specified detail-smoothing value. Larger-detail smoothing values remove more details, while smaller values preserve more details.

Using the Visibility Tool

Tool Settings

The Visibility tool enables you to mask out (create holes) in parts of your Landscape, for areas such as caves.

Using the Visibility Tool

In this example, the Visibility tool is used with a Landscape Material that has been setup to use a Landscape Visibility Mask. This enables parts of the Landscape to be painted invisible or visible so that you can create caves and other underground areas using additional Static Mesh Actors. This demonstration shows painting the invisibility and then repainting the visibility.

Use the following controls to paint masked or to unmask areas of visibility for your Landscape:

Controls

Operation

Left-Click

Adds the visibility mask, making the Landscape invisible.

Shift + Left-click

Removes the visibility mask, making the Landscape components visible again.





In this example, the Landscape Hole Material has been used to paint invisible (or masked out) areas for the Landscape. When painting masked out areas, you only get an on or off state, so there is no way to have a transitional gradient from fully masked to unmasked.

Using Opacity Mask to Create a Hole

Although you can use the sculpting tools to create a vertical holes in your Landscape, you may find that you also want to create horizontal ones, such as ones for caves. You can do so by using opacity masking to "paint" away the visibility of a section of your Landscape with the Visibility tool.

In order to paint away the visibility of a section of your Landscape, you must set up the Landscape Material correctly using a Landscape Hole Material. For information about setting this up properly, you can read about Landscape Hole Materials here.

If you use the Visibility tool without having a Landscape Hole Material assigned, the Visibility tool will remove the Material layers applied to the selected sections, but will not create a hole in the Landscape itself.

After you have set up your Landscape Hole Material, you can use the painting tools to create a hole in your Landscape.

To create a Landscape hole:

Make sure you have a Landscape Hole Material assigned to your Landscape.



Click image for full size.

In the Landscape toolbar, in Sculpt mode, select the Visibility tool.



Click image for full size.

Find the location on your Landscape where you want to create a hole.



Adjust the brush size to the size you want to use.



Left-click to create the hole and Shift + Left-click to erase a hole that was created.



You can now fit Static Mesh Actors in the hole in the Landscape to create a cave.

To test out the collision of the new hole using Play In Editor (PIE), you may have to change from Landscape mode to Place mode.

Tool Settings



There are no tool settings specific to Visibility that can be adjusted in this section. Follow the steps to setup a proper Landscape Hole Material (detailed above) and use the paint to controls to draw in your masked areas.

If you do not have a Landscape Hole Material assigned to your Landscape, you will see the following warning in Visibility tool panel under Target Layers:



Landscape Collision

Collision Mip Level

Viewing Collision Mip Level

Adjusting the Landscape Collision Mip Level

Mixing Collision Mip Level Options

Setting Collision Mip Level Per Landscape Components

Landscape Collision

The Unreal Engine 5 (UE5) Landscape system enables you to specify the detail level of the geometry used for both simple and complex collisions for the entire Landscape as a whole or on a per-Component basis. In the following sections, we will go over how to use the system as well as any relevant information you must know before using this in your UE5 projects.

For this example, we are using the Content Examples project, specifically the Landscapes map, that can be found in the Learn tab of the UE5 Launcher.

Collision Mip Level

If you select any Landscape Actor that has been placed in a level and go to the Details panel, under the Collision section you will find two settings called Collision Mip Level and Simple Collision Mip Level.

Collision Mip Level

The Collision Mip Level sets the complexity of the Complex collision that is used for the Landscape. Setting Collision Mip Level to 0, the default, will give you a very accurate Landscape collision at the expense of memory. Setting this value to 5, the maximum setting, will make the Landscape collision cheaper, but the accuracy of the collision will suffer.

Drag the slider to adjust the Collision Mip Level from 0 to 5





Simple Collision Mip Level

The Simple Collision Mip Level sets the complexity of the Simple collision that is used for the Landscape. Setting Simple Collision Mip Level to 0, the default, will give you a very accurate Landscape collision at the expense of memory. Setting this value to 5, the maximum setting, will make the Landscape collision cheaper, but the accuracy of the collision will suffer.

Drag the slider to adjust the Simple Collision Mip Level from 0 to 5





Viewing Collision Mip Level

You can visualize the Landscape collision geometry using the Playeer Collision Viewmode. To enable this view mode, go to the View Mode menu in the Editor viewport toolbar and select either Player Collision or Visibility Collision.



Click image for full size.

Player Collision

The Player Collision view mode displays the Simple Collision Mip Level.

Visibility Collision

The Visibility Collision view mode displays the Collision Mip Level.

Adjusting the Landscape Collision Mip Level

To set the complexity for both simple and complex Landscape collision you will need to do the following:

Select your Landscape Terrain in the Editor viewport. In the Details panel, expand the Collision section.



Click for full image.

Under the Collision section, find the Collision Mip Level option. Set the value from 0 to 5 and then press the Enter key to apply the change. The gray collision mesh in the level updates automatically to reflect the changes.





Mixing Collision Mip Level Options

You can set the complexity of both the simple and complex Landscape collision meshes to provide a better balance between performance and accuracy. To set the simple and complex collision levels independently in your project you will need to do the following:

Select your Landscape and in the Details panel and expand the Collision section.



Click for full image.

Set the Collision Mip Level to a value of 0 and Simple Collision Mip Level to a value of 2.



Click for full image.

In the following image comparison, you can see what happens to the Landscape collision when the Collision Mip Level and Simple Collision Mip Level are set to different values.





For most cases, you will want to leave the Collision Mip Level at 0 and then use 1 or 2 for the Simple Collision Mip Level. Using any higher numbers will start to show inaccuracies between the player and collision.

Setting Collision Mip Level Per Landscape Components

You can set the Collision Mip Level collision for individual Landscape Components which enables you to reduce the Landscape collision complexity even further in non-playable areas of the level.

To set the Collision Mip Level for an individual component in your project, you will need to do the following:

From the Modes dropdown, click on the Landscape option and make sure the Manage tab is selected.



Click for full image.



Click for full image.

Select a few Landscape components by clicking on them with the Left Mouse Button. The selected Landscape Components are highlighted in red.



Click for full image.

In the Details panel, expand the Landscape Component section and change both the Collision Mip Level and Simple Collision Mip Level to 5.



Click for full image.

In the Landscape Manage section under Tool Settings, press the Clear Component Selection button to deselect any currently selected Landscape components.



Click for full image.

Select a few more Landscape components and this time set both Collision Mip levels to a value of 2.



Click for full image.

In the following image, the Collision Mip level for each of the four outlined Landscape Component has been set to a different level.



Click for full image.

Number

Collision Mip Level

1

3

2

4

3

5

4

2

Adding Layers to Your Landscape

Managing Layers

Locking and Unlocking Layers

Hiding and Unhiding Layers

Highlighting Layers

Editing Layers

Ordering Layers

Adjusting Alpha Layer Blending

Erasing Height in Layers

Using Non-Destructive Splines

Additional Information

Landscape Edit Layers enables you to edit Landscape Heightmaps and paint landscapes using non-destructive layers, and you can add multiple layers to your landscape that can be edited independently from each other. You can also reserve a layer for splines, which enables you to add and paint splines non-destructively. Adding, moving, and editing these splines automatically updates the non-destructive layer.

To use Landscape Edit Layers, check Edit Layers under the Manage tab when creating a new Landscape. Layers cannot be added retroactively to an existing Landscape; you will always need to create a new Landscape to use them in your project.



Click image for full size.

Toggling the layer system off after using the system results in the Editor destructively removing all layer data.

Adding Layers to Your Landscape

Instead of having one layer to sculpt a heightmap or paint materials, you can now add multiple layers to your landscape. These new layers function as a foundation for sculpting and painting a landscape, which allows you to manipulate and maintain landscapes more efficiently.

By default, you will always have one layer (Layer1), which is the initial base layer. To add a new layer, right-click the existing layer and select Create. You can also Rename a layer from this menu.

We recommend renaming your layers so you know which is the base layer, and which layers are ones you added. You can add as many layers to the landscape as you want.



Click image for full size.

Managing Layers

There are several options for managing your layers, which include: locking/unlocking layers, hiding/unhiding layers, and highlighting your layer with Layer Contribution.

Locking and Unlocking Layers

You can lock layers by selecting the Lock icon. The closed lock indicates the layer cannot be edited, and the open lock indicates the layer can be edited.



Click image for full size.

Hiding and Unhiding Layers

If you want to exclude a layer from blending, you can select the eye icon to Hide the layer.



Click image for full size.

Highlighting Layers

To highlight your layer, you can turn on Layer Contribution. By highlighting your layer, you can see the entirety of your sculpted layer. The highlight will remain on your layer until you turn it off. To turn on Layer Contribution, navigate to Lit > Vizualizers > Layer Contribution. To see the layer's contribution to a heightmap, select the layer in Sculpt mode. To see the layer's contribution to a paint layer, select the layer in Paint mode.

Use a combination of these tools to effectively sculpt and paint your heightmap. For example, if you decide to paint Layer1 and do not lock your Base Layer, you can paint both layers. By hiding Layer1 you can see where you painted onto the Base Layer. However, if you lock the Base Layer before painting Layer1, the Base Layer will not have any changes.

Editing Layers

There are several ways you can edit your layer, which include: ordering layers, adjusting the alpha layer blending, and using the Erase tool.

Ordering Layers

You can drag and drop layers in any order. When you move layers, the order in which those layers display in the viewport changes.



Click image for full size.

Adjusting Alpha Layer Blending

You can change the blending for each layer by adding or subtracting from the Alpha value. The viewport displays changes to the values in real time.



Click image for full size.

Each layer has two Alpha values, one to control heightmap blending and the other to control paint layers blending. Setting a negative heightmap Alpha value will result in a subtractive blend. Paint layers each have an additional flag to determine if blending is additive or subtractive.



Erasing Height in Layers

If you use the Erase Tool on the layer, the sculpting reverts to the default layer height. Layer Contribution can be helpful when using the Erase Tool because the layer is easy to identify.



Click image for full size.

Using Non-Destructive Splines

Splines can now be created and managed in their own layer, separate from the base layer of the heightmap. This means that you can now edit, change, and move splines non-destructively and the landscape will terraform automatically.

To add a spline, first add a new layer. Right-click to Rename the layer, and then select Reserve for Splines. Select Continue at the prompt.



Click image for full size.



Click image for full size.

You can edit splines using the Details panel, and adjust the spline using the Transform Controls. Changing the layer order also affects splines, which means parts of the spline can be hidden by the landscape depending on the layer order.

Additional Information

There are additional features to Landscape Edit Layers that enable you to build on your landscape easily and non-destructively. See the following features for additional information:

Landscape Blueprint Brushes

Layer Weights and Ordering

Landscape Specific Material Nodes

Landscape Layer Blend Node

Blending Layers

Landscape Layer Coords Node

Landscape Layer Switch Node

Landscape Layer Weight Node

Landscape Visibility Mask Node

Landscape Layer Blend Types

Landscape Layer Blend Technical Information

Tessellation and Displacement

Mobile Landscape Materials

Using Layer Blending

Using Landscape Layer Weight Nodes

Using Landscape Layer Blend Nodes

Creating Landscape Hole Materials

Assigning Materials to Landscapes

Assigning a Landscape Hole Material to a Landscape

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Although any random Material can be used with a Landscape Actor, the Material system inside Unreal Engine 5 (UE5) provides some Landscape-specific material nodes that can help improve the textures for your Landscape. In this document, we explain how these material nodes function, and how you can use them in your Landscape materials.

You modify Materials for use with Landscapes the same way you modify other Materials, in the Material Editor.

Layer Weights and Ordering

Landscapes use weight blending rather than alpha blending, so the blend factors for all layers at any location will add up to 1.0. Alpha blending is useful because it does not depend on order, so you can paint any layer at any time. Additionally, when you use alpha blending the alpha layer weight is increased, while other existing layer weights are decreased.

However, the disadvantage to using alpha blending is that when one layer is painted to 100%, the weight value for all other layers will be 0%. This is shown when using the Paint tool to remove a layer that is already at 100%. Because the other layers are at 0%, the tool has nothing available to replace the 100% layer you are removing, so it appears as if the layer was not changed.

Landscape Specific Material Nodes

Inside of the Material Editor, there are six specific nodes that can be used with the Landscape system. You can find all these nodes in the Palette menu, under the Landscape category.



Click image for full size.

Landscape Layer Blend Node

The LandscapeLayerBlend node enables you to blend together multiple Textures or Material networks so that they can be used as Landscape layers. The LandscapeLayerBlend uses an array to store information about the Landscape layers. To add layers to this array, select the plus sign icon.



Click image for full size.

When you add multiple layers to the LandscapeLayerBlend node, the Layer Names populate in the LandscapeLayerBlend node.



Click image for full size.

Number

Property

Description

1

Layers

The list of layers the node contains. You can add layers by clicking the plus icon ( ).

2

Additional Layers

These are what additional layers look like when they are collapsed.

3

Layer Name

The unique name that you give the layer. The Layer Name corresponds to the layer name used in Paint mode in the Landscape tool window.

4

Blend Type

Either LB_AlphaBlend, LB_HeightBlend, or LB_WeightBlend. See Landscape Layer Blend Types on this page.

5

Preview Weight

This is the weight value for the layer to preview the blending in the Material Editor.

6

Const Layer Input

This is for supplying a numeric value as a color to use in case you do not want to use a texture. This is mainly used for debugging a layer if there is an issue.

7

Const Height Input

This is for supplying a numeric value as a height in case you do not want to use a texture.

The following table details the Layer Blend node inputs and outputs.



Click image for full size.

Number

Item

Description

1

Layer *LayerName

Each layer adds an input for the layer to blend together. This input is only available after layers are added and named in the Details panel.

2

Height *LayerName

This is where you supply a height map to blend with. This input is only visible on layers that have their Blend Type property set to LB_HeightBlend.

3

Unlabeled Output

The result of the layers blended together.

Blending Layers

When using certain combinations of layer blend modes you could end up with black spots all over your Landscape where different layers meet. This problem is especially prevalent when using the LB_HeightBlend mode for multiple Landscape layers. LB_HeightBlend works by modulating the blend factor, or weight, for the layer using the specified height value. When you have multiple layers painted on an area and they all are set to LB_HeightBlend, it is possible that all the layers painted in a particular area will simultaneously have a 0 height value, so the desired blend factor for each layer becomes 0.

Because there is no implicit or explicit ordering, the result will be black spots because no layers will have any contribution to that area. The situation is worse when you are blending a Normal map, because it results in a Normal value of (0,0,0) which is not valid and will cause rendering problems with the lighting. The solution to this problem is to use LB_AlphaBlend for one of the layers like in the example below.

In the left image, all layers are LB_HeightBlend, causing some areas to be black. On the right, the red "1" layer has been changed to use LB_AlphaBlend, which solves the problem.



Click image for full size.

Below is an example of the properties of the Landscape Layer Blend node for all the layers being blended together. Make sure to note how the Soil layer has its blend mode set to LB_AlphaBlend while the other layers have theirs set to LB_HeightBlend. This is to stop the issue mentioned above (having black spots where layers meet) from happening.



Click image for full size.

If you need to delete a layer, click the drop-down arrow to the right of the layer's element number to open the menu, and select Delete.



Click image for full size.

Landscape Layer Coords Node



Click image for full size.

Number

Property

Description

1

Mapping Type

The ELandscapeCoordMappingType that specifies the orientation to use when mapping the Material (or network) to the Landscape.

2

Custom UVType

The mapping place to use on the terrain. The CustomUVType outputs the UV coordinates to map the Material to the Landscape based on the given property values.

3

Mapping Scale

Applies uniform scaling to the UV coordinates.

4

Mapping Rotation

Applies the rotation, in degrees, to the UV coordinates.

5

Mapping Pan [U]

Applies the offset in the [U] direction to the UV coordinates.

6

Mapping Pan [V]

Applies the offset in the [V] direction to the UV coordinates.

7

Unlabeled Output

Outputs the UV coordinates to map the material to the Landscape based on the given property values.

Landscape Layer Switch Node

The LandscapeLayerSwitch node allows you to exclude some Material operations when a particular layer is not contributing to a region of the Landscape. This allows you to optimize your Material by removing calculations that are not necessary when a particular layer's weight is zero.



Click image for full size.

Number

Property

Description

1

Parameter Name

The unique name that you give to the parameter.

2

Preview Used

If checked, uses a preview.

3

LayerUsed

When the layer specified in the node's properties is in use by the current region of the Landscape.

4

LayerNotUsed

When the layer is not used by the current region of the Landscape and has a weight of zero.

5

Unlabeled Output

Either the LayerUsed or LayerNotUsed inputs, depending on whether or not the layer contributes to the particular region of the Landscape.

Landscape Layer Weight Node

The LandscapeLayerWeight expression allows Material networks to be blended based on the weight for the associated layer obtained from the Landscape the Material.The weight for this layer is used as the alpha value for blending the two input networks.



Click image for full size.

Number

Property

Description

1

Parameter Name

The unique name that you give to the parameter.

2

Preview Weight

The weight to use for preview purposes in the Material Editor.

3

Const Base

You can specify a base color here that you would like for your Landscape to have

4

Base

The network to blend this layer with. This is generally the result of any previous layer blending, but can be empty if this is the first layer.

5

Layer

The network to blend together to create this layer.

6

Unlabeled Output

Outputs the result of the blending between the Base and Layer inputs based on the layer weights of the layers involved.

Landscape Visibility Mask Node

The LandscapeVisibilityMask node removes visible parts of your Landscape, so you can create holes in your landscape to, for example, create caves.



Click image for full size.

Number

Property

Description

1

Unlabeled Output

Outputs the visibility mask properties.

Make sure the output is connected to the Opacity Mask slot of your Material and that the Materials Blend Mode is set to Masked. Otherwise the node may not work correctly.



Click image for full size.

Landscape Layer Blend Types

The Landscape Layer Blend material node has three different blend modes that you can choose from. Each different Layer Blend type is used when you are trying to achieve a different result.

Blend Type

Function

LB Weight Blend

Use if you have layers coming in from an external program, like World Machine, or if you wanted to be able to paint any layer independent of one another without worrying about layer order.

LB Alpha Blend

Use if you want to paint in detail and if you want a defined layer order. For example, painting snow over rock and grass will occlude them, but erasing snow will reveal rock and grass beneath it.

LB Height Blend

This is the same as LB_WeightBlend but also adds detail to the transition between layers based on a height map. This allows, for example, dirt to appear in the gaps between rocks at the layer transition point, instead of just smoothly blending between rock and dirt.

Here is an example of the LB Height Blend in action. As you can see, the dirt to appears in the gaps between rocks at the layer transition point. This way you get a nice transition where layers meet.



Landscape Layer Blend Technical Information

Under the hood, these layer nodes behave like a Static Switch Parameter node, which enables you to switch from using one part of the Material to using another. Each component of the Landscape has its own MaterialInstanceConstant created from the main Landscape Material, which is applied to just that component. If a particular layer is not used on a specific Landscape component, the subtree of nodes connected to the layer will be discarded. This reduces overall Material complexity, enabling the Material applied to the Landscape to contain any number of texture samples as long as the number of samples being used on any individual component never exceeds the maximum set by the shader model specifications (16 for SM 3.0).

This means it is possible to set up a master Material that contains every texture or network used anywhere on the Landscape. This can end up being a very complex collection of networks, while still keeping the final Materials applied to the components of the Landscape within the parameters allowed by the hardware.

Any network of material expressions can be connected to the Layer inputs in place of a simple TextureSample. This makes it possible to do more complex effects such as transitioning from detail textures to larger macro textures depending on the distance the layer is being viewed from.

Tessellation and Displacement

The Tessellation Multipliers and World Displacement channels of the Material can be used in conjunction with Landscape terrains to provide additional detail and deformation when the Landscape is close to the camera. These work exactly as they would with any other standard Material, and the layer blending can be used in conjunction with these just as with the Base Color, Normal, or any other channel. The Landscape will also only render hardware tessellation on the highest level-of-detail(LOD) which will fade out as the Landscape approaches the second LOD. Subsequent LODs will no longer have tessellation enabled, which will significantly improve performance when enabling tessellation for displacement on your Landscape Terrain.

These features are limited for use with DirectX 11 enabled. As such, they should be used as secondary polish effects unless you are targeting DirectX 11 hardware specifically. You can read more about how to enable and use tessellation in your project by reviewing the Tessellation Multiplier page.



In the visualization above, the highest LOD (white) is rendered with tessellation enabled, while the other LODs (colors) are rendered without tessellation.

Mobile Landscape Materials

Mobile landscapes are no longer limited to just three Landscape layers. While three is still an optimized case, any number of layers are supported provided there are sufficient Texture Samplers. The Landscape layer allocation now takes Feature Level Switch material node allowing a single PC or Console Landscape Material to also have a Mobile version. The following image shows how the Landscape used in the PC and Console versions of Fortnite Battle Royale looks when used for mobile devices.



Using Layer Blending

The ability to blend multiple textures and materials networks into paintable Landscape layers is the basis for texturing Landscape terrains. In order to blend layers together, you can use either multiple LandscapeLayerWeight nodes or one to two LandscapeLayerBlend nodes depending on if you are using a Normal Map or not.

Using Landscape Layer Weight Nodes

Setting up and using LandscapeLayerWeight nodes is a quite easy process for which will be outlined below.

All layer names must be unique, so we recommend naming your layers with a descriptive name that indicates what the layer contains. This will help you remember where content is in your layer and help you navigate through layers faster.

In the Material Editor, add a LandscapeLayerWeight node to the Material Graph. By default, it will have the Parameter Name "None."



Click image for full size.

In the Details panel, change the Parameter Name to a descriptive name for the layer, for example, "Rock". After you enter a **Parameter Name**it will be updated on the node itself.



Click image for full size.

Add additional LandscapeLayerWeight nodes, until you have one for each layer that you want your Material to have. In this example, we are going to be using just two LandscapeLayerWeight nodes.

Add and connect Texture Samples, or other material network expressions, to your LandscapeLayerWeight nodes.

Add a LandscapeLayerCoords node, set its UV titling to what you want, and connect it to the Texture Sample nodes.

Drag from each Layer node's output pin to the Base pin of the next layer node to connect them with a wire (leaving the first layer node's Base pin unconnected).

Drag from the final Layer node's output pin to the Base Color input of the Material's Base node.

When completed, you should have something that looks like the following example using LandscapeLayerWeight nodes:



Click image for full size.

You can preview the effects of different weights on the Material by changing the Preview Weight properties of the LandscapeLayerWeight nodes.

Using Landscape Layer Blend Nodes

As an alternative to manually blending layers together with the LandscapeLayerWeight node, the LandscapeLayerBlend node blends multiple layers together using either alpha blending or alpha blending with a height-based offset. The height-based offset allows a layer to blend with other layers based on a heightmap input.

In the Material Editor, add a LandscapeLayerBlend node.

In the Details panel, next to Layers, click the plus icon ( ) to add a layer.



Click image for full size.

Expand the layer to view its properties.

Change the Layer Name to a descriptive name for the layer, for example, "Snow".



Click image for full size.

Determine whether you want the layer to be alpha blended or height blended, and set the Blend Type accordingly.

Add as many additional layers as you want for your Landscape Material. Rename them and set their Blend Types appropriately.

Connect the LandscapeLayerBlend node's output to the Base Color input of your Material's base node.

Add Texture Sample nodes, and connect their main outputs to the Layer inputs of the LandscapeLayerBlend nodes. Alternatively, you can create a more complex material network and connect it to the Landscape Layer Blend Layer input. For any height-blended layers, connect the Texture Sample's alpha output to the LandscapeLayerBlend's Height input.

When you are done, your Landscape Material network will look something like this:



Click image for full size.

You can preview the effects of different weights on the Material by changing the Preview Weight properties of the LandscapeLayerBlend nodes.

Creating Landscape Hole Materials

Creating holes in your Landscape is something that you can do in Manage Mode but only by deleting entire Landscape components at a time. To get around this, you can use a Landscape Hole Material to mask out the visibility and collision of a certain location on your Landscape. This is great if you want to make something like an entrance to a cave in the side of a mountain.

You can use the same Material for your Landscape Material and your Landscape Hole Material, but be aware that Materials that use opacity masks are more costly performance-wise, than Materials that do not. This is why you have the option of creating a separate Landscape Hole Material.

Open the Material Editor, and in the Details panel set the Blend Mode to Masked.



Click image for full size.

Next, add a LandscapeVisibilityMask node to the Material Graph and connect its output to the Opacity Mask input.



Click image for full size.

Once the material has been compiled, it is now time to assign it to the Landscape so that it can be used. This can be done in the Landscape Hole Material section in the Details panel.



Click image for full size.

Now you can set up the rest of your Landscape Material like you normally would and when completed, you should have something that looks similar to this.



Click image for full size.

You should now be able to mask and unmask the visibility of your terrain, like in the video below.

For information about using the painting tools to create a Landscape hole, see Using Opacity Masking to Create a Hole.

Assigning Materials to Landscapes

After creating a Material for a Landscape, you need to assign the Material to a Landscape Actor in your level to use the Material.

Find the Landscape Material that you want to use in the Content Browser.

Select the Landscape, either in the viewport or in the World Outliner.

In the Level Editor's Details panel for the Landscape, in the Landscape section, next to Landscape Material, click the Assign arrow ( ) to assign the selected Material.



Click image for full size.

Assigning a Landscape Hole Material to a Landscape

You can assign different Material to act as the Landscape Hole Material, which is a Material with specific opacity settings.

See the section on Landscape Hole Materials for general information on hole materials. For information on opacity masking, see Using Opacity Masking to Create a Hole.

Find the Landscape Hole Material that you want to use in the Content Browser and select it.

Select the Landscape, either in the viewport or in the World Outliner.

Navigate to the Level Editor Details > Landscape > Landscape Hole Material. Select the arrow ( ) to assign the selected Material.



Click image for full size.

Landscape Tool Modes

Landscape Features

Large Terrain Sizes

Landscape Memory Usage

Static Render Data Stored as Textures in GPU Memory

Continuous Geo-MipMap LOD

Heightmap and Weight Data Streaming

High Resolution LOD-Independent Lighting

Collision

Using the Landscape system, you can create terrain for your world. Mountains, valleys, uneven or sloped ground, and even openings for caves are possible. Using the collection of tools in the Landscape system, you can modify your terrain's shape and appearance.

For information about opening and using the Landscape tool, refer to the Landscape Quick Start Guide.

Landscape Tool Modes



The Landscape tool has three modes, accessible by their icons at the top of the Landscape tool's window.

Icon

Mode

Description



Manage mode

Create new Landscapes, and modify Landscape components. Manage mode is also where you work with Landscape Copy Tool to copy, paste, import, and export parts of your Landscape. For more information about Manage mode, refer to Landscape Manage Mode.



Sculpt mode

Modify the shape of your Landscape by selecting and using specific tools. For more information about Sculpt mode, refer to Landscape Sculpt Mode.



Paint mode

Modify the appearance of parts of your Landscape by painting textures on it, based on the layers defined in the Landscape's Material. For more information about Paint mode, refer to Landscape Paint Mode.

Creating a Landscape means creating a Landscape Actor. As with other Actors, you can edit many of its properties, including its assigned Material, in the Level Editor's Details panel. For more information about Details panels, refer to Level Editor Details Panel.

Landscape Features

Below are the main features and techniques employed by the Landscape terrain system.

Large Terrain Sizes

The Landscape system paves the way for terrains that are orders of magnitude larger than what has been possible in Unreal Engine previously. Because of its powerful Level of Detail (LOD) system and the way it makes efficient use of memory, heightmaps up to 8192x8192 are now legitimately possible and feasible. Unreal Engine now supports expansive outdoor worlds, which means quick game creation without modifiying stock engine or tools.



Click image to expand.

Landscape Memory Usage

Landscapes are generally a better choice for creating large terrains than Static Meshes.

Landscapes use 4 bytes per vertex for the vertex data. Static Meshes store position as a 12-byte vector, and tangent X and Z vectors packed into 4 bytes each, and either 16-bit or 32-bit float UVs for a total of either 24 or 28 bytes per vertex.

This means Static Meshes use 6 or 7 times the memory Landscapes use for the same vertex density. Landscapes also store their data as Textures and can stream out unused LOD levels for distant areas and load them from disk in the background as you approach them. Landscapes use a regular heightfield that efficiently stores collision data compared to the collision data for Static Meshes.

Static Render Data Stored as Textures in GPU Memory

On most platforms, the Landscape system stores the render data for the terrain in Textures in GPU memory. This storage can be used for data look-up in the vertex shader. The render data uses a 32-bit Texture for storage, with the height occupying 16-bits in the form of the R and G channels and the normal stored as 28-bit values for X and Y, occupying the B and A channels, respectively. Additionally, if the Retopologize tool is being used, another 32-bit Texture will store the X and Y offsets.

Continuous Geo-MipMap LOD

Standard Texture mipmaps handle LODs for Landscape terrains. Each mipmap is a level of detail, and the mipmap to sample can be specified using the text2Dlod HLSL instruction. Your Landscape can have a large number of LODs, yet maintain smooth LOD transitions, because mip levels for both LODs involved in a transition can be sampled, and then the heights and X and Y offsets can be interpolated in the vertex shader creating a clean morphing effect.







Fully LOD 1

Morphing from LOD 1 to LOD 2

Fully LOD 2

Heightmap and Weight Data Streaming

With Textures storing data, the standard Texture streaming system in Unreal Engine handles streaming mipmaps in and out as needed. This applies to the heightmap data and the weights for Texture layers. Only requiring the mipmaps needed for each LOD minimizes the amount of memory used at any time, which means you can create a more extensive terrain.

High Resolution LOD-Independent Lighting

The entire high-resolution (non-LOD'd) normal data is available for lighting calculations due to the storage of the X and Y slopes of the Landscape.





Landscape LODs

Full Resolution Normals

This means you can always use the highest resolution of the terrain for per-pixel lighting, even on distant components that have been LOD'd out.





Simple Vertex Lighting

High Res Per-Pixel Lighting

When this high-resolution normal data combines with detailed normal maps, Landscape terrains can achieve highly detailed lighting with very little overhead.





Geometry Normals Only

With Detail Normals

Collision

Landscape uses a heightfield object for its collision. Layers can specify a Physical Materials. The collision system will use the dominant layer at each position to determine which Physical Material to use. It is possible to use a reduced resolution collision heightfield (for example, 0.5x render resolution) to save on memory requirements for large Landscape terrains. The collision and render components for distant Landscapes can also be streamed out using the level streaming system.

1 - Working with the Landscape Tools

2 - Creating a new Landscape

3 - Sculpting the Landscape

4 - Creating Landscape Materials

5 - Painting Landscape Materials

6 - Landscape Tips and Tricks

The Unreal Editor Landscape Quick Start Guide walks you through creating a new Landscape, sculpting the Landscape, creating new Materials for the Landscape, and painting those Materials on the Landscape.

1 - Working with the Landscape Tools

The Landscape system inside of Unreal Engine 5 (UE5) is a collection of tools that allow you to create expansive outdoor environments. But before we dive into creating our first Landscape, let us first familiarize ourselves with some of the tools and keyboard inputs that are most commonly used to interact with the Landscape system.

Opening the Landscape Tool and Working with Modes

All of the tools that are used to interact with the Landscape system can be found under the Landscape option that is located in the Modes dropdown menu. To enable the Landscape tools, open the Modes dropdown and choose the option from the menu.

The Landscape tool has three modes, Manage, Sculpt, and Paint that are accessible by clicking on their icons at the top of the Landscape's toolbar window. Each mode will allow you to interact with the Landscape in a different manner. Here is a very quick rundown of what each mode allow you to do.



Icon

Mode

Description



Manage mode

Create new Landscapes, and modify Landscape components. Manage mode is also where you work with Landscape Copy Tool to copy, paste, import, and export parts of your Landscape. For more information about Manage mode, refer to Landscape Manage Mode.



Sculpt mode

Modify the shape of your Landscape by selecting and using specific tools. For more information about Sculpt mode, refer to Landscape Sculpt Mode.



Paint mode

Modify the appearance of parts of your Landscape by painting textures on it, based on the layers defined in the Landscape's Material. For more information about Paint mode, refer to Landscape Paint Mode.

Interacting with the Landscape Tools

While each of the three modes within the Landscape tools allows you to interact with the Landscape differently, but the keyboard and mouse keys that you use are similar. Here is a rundown of some of the most common keys, key combinations, and mouse buttons that are used when working with the Landscape tool.

Common Controls

Operation

Ctrl

Allows you to select Landscape components.

Left Mouse Button

Heightens or increases the heightmap or selected layer's weight. For example, in Sculpting mode, this will raise the Landscape heighmap. In Paint mode this will apply the selected material to the Landscape.

Shift + Left Mouse Button

Lowers or decreases the heightmap or selected layer's weight. For example, in Sculpting mode, this will lower the Landscape heightmap. In Paint mode, this will erase the selected material that was applied to a particular section of the Landscape.

Ctrl + Z

Undoes last action.

Ctrl + Y

Redoes last undone action.

2 - Creating a new Landscape

Creating a New FPS Blueprint Project

Before we begin to create our first Landscape, lets create a new project First Person Project.

If you are unfamiliar with how to create a new project, check out the following page on Creating a New Project.

Creating a Landscape

First, create a new First Person project if you have not done so already. While you can use other templates for this tutorial, the First Person will make it a little easier to inspect your Landscape. After choosing the First Person option, click the Next button.



Click image for full size.

Make sure your project is set up to use Blueprints and contains the Starter Content folder. Choose a location where your project will be stored on your computer and make sure it has a proper name. Finally, click the Create Project button to continue.



Click image for full size.

Once you have created your new project and the editor has been loaded, create a new level using File > New Level and select the Default Level from the New Level Template.



Click image for full size.

With your new level now created, select the Floor from the level and press the Delete key to remove it from the level.

Make sure that you select your player start and move it up slightly in the Z-axis. This will make sure that your player does not start under your newly created Landscape.

Once completed, you should now have something that looks similar to the following image.



Click image for full size.

With the level cleared out and the player start moved up in the Z-axis slightly, it is now time to create a new Landscape. To create a new Landscape, click on the Landscape option in the Modes dropdown menu.



Click image for full size.

Once you have clicked on the Landscape option, you should see the following set of Landscape tools displayed in the Landscape panel.



Click image for full size.

For this tutorial, we will just focus on creating a Landscape using the default settings. If you would like to know more about the various settings in the Manage mode of the Landscape tool, please refer to Creating Landscapes. For now, make sure that your settings match the image below and then press the Create button to create the Landscape.



Click image for full size.

When done, you should have something that looks like this.



Click image for full size.

3 - Sculpting the Landscape

Sculpting the Landscape is a time consuming process. All of the tools used for sculpting can be found under the Sculpt tab in the Landscape toolbar. If you would like to know more about what each of the Sculpting Tools does in detail, take a look at the Sculpt Mode page. For quick reference, here is a list of the most common key and mouse interactions that are used when sculpting the Landscape.

Common Controls

Operation

Ctrl

Allows you to select Landscape components.

Left Mouse Button

Heightens or increases the heightmap or selected layer's weight. For example, in Sculpting mode, this will raise the Landscape heighmap. In Paint mode, this will apply the selected material to the Landscape.

Shift + Left Mouse Button

Lowers or decreases the heightmap or selected layer's weight. For example, in Sculpting mode, this will lower the Landscape heightmap. In Paint mode, this will erase the selected material that was applied to a particular section of the Landscape.

Ctrl + Z

Undoes last action.

Ctrl + Y

Redoes last undone action.

For this part of the Landscape tutorial, we are going to start with a completely flat section of the Landscape and then build up the details as we go along. The goal here is not to exactly mimic what was created in the tutorial but to get you familiar and comfortable with using the various Landscape tools.

There could be a lot of various reasons as to why what you do in this tutorial does not come out exactly the same as what you see in the following screen shots. Working with the Landscape tools requires a lot of trial and error so your results will vary, sometimes greatly, from what you are seeing in the following set of images. The most important thing to get out of this tutorial is to understand how each of the Landscape tools work and how all the tools work together to give you the final product.

To begin, first find a section of the Landscape that you would like to work with. For this tutorial, we are not going to be filling in the entire Landscape but just a section of it. For ease of use, set a camera bookmark by pressing Ctrl + 1 on the keyboard. This will set a camera bookmark which will make it easier for you to gauge how your Landscape is coming along by giving you a camera view to always come back to. At any time during your editor session, if you press the 1 Key, your camera will be returned to the exact same position that you set.



Click image for full size.

With the bookmark set, begin painting in the larger details for hills and valleys using the Sculpt Tool. You can find the brush size and strength settings that were used for this step listed below and when completed, you should have something that looks like the following. You can change the value of the Brush Size and Strength either in the Landscape panel or the Landscape toolbar located just above the viewport.

Remember that you use Left Mouse Button to raise the Landscape height and Shift + Left Mouse Button will lower the height of the Landscape.

Tool Used

Brush Size

Strength Setting

Scupt Tool

8192

0.29



Click image for full size.

Once the the hills and valleys are blocked out, it is time to use the Smooth Tool to help refine the look and feel of them. Using this tool will smooth your Landscape features and make them seem more natural. Be careful not to smooth away all your features! You can find the brush size and strength settings that were used for this step listed below and when completed, you should have something that looks like the following.

Tool Used

Brush Size

Strength Setting

Smooth Tool

2048

0.29



Click image for full size.

Now that the Landscape is smoothed out, it is time to add some flat mesa like sections using the Flatten Tool. The Flatten Tool captures the height information of the location of your first click and raises/lowers the heightmap to meet that point as you drag around the brush. You can find the brush size and strength settings that were used for this step listed below and when completed, you should have something that looks like the following.

Tool Used

Brush Size

Strength Setting

Flatten Tool

2048

0.29



Click image for full size.

It is time to use the Ramp Tool to add some flat ramps between the mesas. This tool works by designating a start point and an end point for your ramp and then clicking the Add Ramp button to create a flat path between the two points. Each point can be moved any direction to create a ramp that fits each unique situation. You can find the brush size and strength settings that were used for this step listed below and when completed, you should have something that looks like the following. If it is not very clear where the Ramp was used, it has been highlighted in yellow.

Tool Used

Ramp Width

Side Falloff

Ramp Tool

2000

0.40



Click image for full size.

Next, we are going to add some erosion effects to the Landscape to give it a weathered look using the Erosion Tool which works by simulating erosion done by wind. This tool is perfect for shaving away parts of your hills to create mountain peaks and ridges. You can find the brush size and strength settings that were used for this step listed below and when completed, you should have something that looks like the following.

Tool Used

Brush Size

Strength Setting

Erosion Tool

693

0.25



Click image for full size.

In the next step, we will take the erosion that was just added in the previous step and push it further by adding some Hydro Erosion to the Landscape. The Hydro Erosion Tool is different than the Erosion Tool as it is for simulating how water will erode Landscape details over time. Like the Smooth Tool, be careful not to erode away all your detail. You can find the brush size and strength settings that were used for this step listed below and when completed, you should have something that looks like the following.

Tool Used

Brush Size

Strength Setting

Hydro Erosion

2048

0.29



Click image for full size.

To break up the surface of the Landscape even more, we will use the Noise Tool. The Noise Tool adds random noise to the surface of the Landscape by randomly moving the Landscape vertices up or down or both at the same time. You can find the brush size and strength settings that were used for this step listed below and when completed, you should have something that looks like the following.

Tool Used

Brush Size

Strength Setting

Noise Tool

2048

0.29



Click image for full size.

For the final step in the Landscape sculpting part of the tutorial, we will re-use the Smooth Tool to help smooth out some of the more jagged areas of the Landscape to give it a more natural look. While you might not need to do this step yourself, this was done to help even out some of the areas that appear too deep or areas that the player might get stuck in if they fall into. You can find the brush size and strength settings that were used for this step listed below and when completed, you should have something that looks like the following.

Tool Used

Brush Size

Strength Setting

Smooth Tool

1121

0.16



Click image for full size.

4 - Creating Landscape Materials

Folder Setup

We have finished sculpting the Landscape, it is time to add some Materials to it so that it better resembles something that we see in the real world. But before you do this, you need to first setup some folders to organize the content that you create and migrate into your project.

If you would like to know more about how to setup folders in Unreal Engine 5, please refer to the following page about Folders.

Start by creating a new folder called Landscape in your project's Content folder.

Then inside the Landscape folder, create the following three folders:

Materials

Resources

Textures

When completed, you should have something that looks like the following.



Click image for full size.

Migrating Textures

Now that we have the folders in place, it is time to Migrate some Textures from the Landscape Mountains learning project so that we have some Textures to work with. This project can be found under the Learn tab in the Epic Games Launcher. If you would like to know more about how to Migrate content from one project to another one, please check out the following page on how to Migrate Content.

When Migrating content between projects, you could possibly end up with additional folders that you do not want. To fix this, select the Textures that you want inside of the Content Browser and then drag them from their current location into the folder that you want them to be placed in. This is purely a house keeping step and will have no impact on the outcome of the tutorial.

You can find the textures located in the following folder located in the Landscapes Content example project.

/Game/ExampleContent/Landscapes/Textures/

The Textures that you will be Migrating over from the Landscape Content Example project are as follows.

T_LS_Grass_01_D

T_LS_Grass_01_N

T_FullGrass_D

T_FullGrass_N

T_IceNoise_N

Once you have the textures migrated over, make sure they are placed in the Textures folder that was created in the steps above.

Creating the Landscape Material

Creating a Material for our Landscape can be done in the following steps.

Navigate to the Materials folder in the Content Broswer.

Right-click in the Content Browser and select Material from the Create Basic Asset list.

Name the newly created Material something that will allow you to easily find it, like Landscape_Material for example.

If you have not already done so, please check out the Materials pages to gain a more in-depth understanding of how materials work inside of Unreal Engine 5.

When this is complete, you will have something that looks like this:



Click image for full size.

With our new Landscape Material created, open up the Material by Double-clicking on it inside of the Content Browser. When you do, you should see something like this come up on the screen:



Click image for full size.

It is time to start adding nodes inside of the Material Editor. The first node that you are going to want to create is a LandscapeLayerCoords UV node. This node will help to generate UV coordinates that will be used to map the Landscape Material to the Landscape Actor.



Click image for full size.

The quickest way to find nodes specific to Landscape is to search for them in the Materials Palette box using Landscape as the key word.



Click image for full size.

The next Material nodes that we are going to add are going to be for the textures for the ground's Base Color and Normal maps. For the snow, we are just going to use a Vector Parameter (V + Left-click) that uses an off White color. To make sure that no Metallic information is used, a Constant (1 + Left-click) of 0 is used and plugged into the Metallic input. Finally, for the Roughness, we set a Scalar Parameter (S + Left-click) so that this value can be tweaked via a Material Instance. Finally, make sure that you connect the LandscapeCoords to the UV's of each of the Texture Samples. When completed, your node network should look like this:



Click image for full size.

To add the Texture Sample nodes for the various textures, select the desired texture in the Content Browser and then press T + Left-click in the Material Editor's graph to create the node.

To find more information about these keybindings, take a look at the Edit > Editor Preferences > Keyboard Shortcuts window and select the Material Editor - Spawn Nodes section.

Number

Texture Name

1

T_LS_Grass_01_D

2

T_FullGrass_D

3

T_LS_Grass_01_N

4

T_FullGrass_N

5

T_IceNoise_N

After the Material nodes have been added and the LandscapeCoords connected to the textures UVs, it is time to add and setup the Landscape Layer Blend node. The Landscape Layer Blend node allows for the blending of layers via Weight blending, Height blending, or Alpha blending. Weight blending uses each layer's painted weight to determine which to display. We use Weight blending where we want two surfaces to blend seamlessly into each other, such as rock into sand. Height blending uses the same weight information along with an additional height value taken from the Texture Sample's Alpha channel and is best used when one material needs to clearly sit on top of another, such as the Grass and Snow sitting on top of the Soil layer. Finally, Alpha blending uses the painted weight information with an Alpha layer to determine the final result.

The following table shows what Textures are associated with which Layer Name and what Blend Type they use.

When you first place down a Landscape Layer Blend node, it will be blank like in the image below labeled one. To add Layers, you need to select the node in the Material Graph and then in the Details panel, click on the Plus icon that is in-between the word Elements and the Trash Can icon. This icon is highlighted yellow in the image labeled two. How many textures you are using will determine how many Layers you will want to have.



Layer Blend Base Color

Texture

Layer Name

Blend Type

Preview Weight

T_LS_Grass_01_D

Soil

LB Weight Blend

1.0

T_FullGrass_D

Grass

LB Height Blend

0.0

Snow as a Vector 3

Snow

LB Height Blend

0.0



Click image for full size.

Layer Blend Normal

Texture

Layer Name

Blend Type

Preview Weight

T_LS_Grass_01_N

Soil

LB Weight Blend

1.0

T_FullGrass_N

Grass

LB Height Blend

0.0

T_IceNoise_N

Snow

LB Weight Blend

0.0



Click image for full size.

For more in-depth information about using the Landscape Layer Blend node or to troubleshoot any issues, please read the Terrain Expressions page.

Once the Layer Blend nodes have been set up, it is time to connect the Texture maps to them. Height blended materials will have both a Layer connection and a Height connection to accommodate the need for the additional height information. When completed, you should have something that looks like the following.



Click image for full size.

The material connections were colored in Photoshop to help better illustrate where everything needed to be connected. Currently there is no way to change the color of lines connecting Material nodes inside of Unreal Engine 5.

5 - Painting Landscape Materials

With the Landscape material created, it is time to apply the Material to the Landscape and begin using the Paint tools.

Landscape Painting Prep

Before we can begin painting the Landscape, there is some setup that needs to be done first. Start by applying your Landscape Material to the Landscape:

Find your Material in the Content Browser. This should be located under a folder labeled Materials that was created in the previous section. Click on it so that it is selected.



Click image for full size.

With the Landscape Material selected in the Content Browser, select the Landscape in the world. Then in the Details panel, expand the Landscape section and look for the Landscape Material input.



Click image for full size.

Apply the Material to the Landscape using the Use Selected Asset from the Content Browser arrow icon. You can also drag the Material asset from the Content Browser to the Details panel and drop it on the Landscape Material input.



Click image for full size.

When completed, you should have something that looks like this:



Click image for full size.

If you see black lines in your Landscape, they come from having Un-Built lighting. If you re-build your level's lighting, the black lines will go away.

Now that the Landscape Material is applied, it is almost time to stat painting but before we can do that, we must first create and assign three Landscape Layer Info Objects. If you try to paint before you assign the Landscape Layer Info Objects, you will get the following warning message.



Click image for full size.

You need to create three Landscape Layer Info Objects, one for each Texture that you want to paint. Here is how you do it:

First, make sure that you are in Landscape Paint mode.



Click image for full size.

In the Landscape panel, under the Target Layers section, you should see three inputs labeled Soil, Grass, and Snow.



Click image for full size.

To the right of the names, there is a Plus Sign icon. Clicking that will bring up another menu that will ask what type of layer you would like to add. For this example, pick the Weight-Blended Layer (normal) option.



Click image for full size.

When you select the Weight-Blended Layer (normal) option, you will be prompted with a pop-up box that is asking you where you want to save the newly created Landscape Layer Info Objects. Select the Resources folder that is under the Landscape folder and then press the OK button.



Click image for full size.

Once you have completed the first one, repeat the same process for the other two. You should have something that looks like the following:



Click image for full size.

Now with the Landscape Layer Info Objects created and applied, we can begin to paint our Landscape.

Painting the Landscape

Before you begin to paint the Landscape, here is a re-cap of some of the most used commonly used keyboard and mouse inputs that you will use when painting the Landscape.

Common Controls

Operation

Left Mouse Button

Performs a stroke that applies the selected tool's effects to the selected layer.

Ctrl+Z

Undo last stroke.

Ctrl+Y

Redo last undone stroke.

The main tool that you will use for applying textures to your Landscape is going to be the Paint Tool. To find out more about all of the tools that you can use to paint on the Landscape, check out the Paint Mode documentation.

To apply a Material to the Landscape, press and hold the Left Mouse Button to apply whatever you have selected to the area under the brush.

To select a new texture to paint, make sure you are in Landscape Painting Mode then under the Target Layers section, select which texture you want to paint with by clicking on it in the list. Whichever texture is highlighted will be painted on the Landscape. In the image below, you can see the Soil layer is highlighted meaning that this is the texture that will be painted to the Landscape.



Click image for full size.

When you finish painting, you should have something that looks like this.



Click image for full size.

Possible Issues and Workarounds

When you first start painting on your Landscape you might run into an issue where the base Material disappears or turns black, like in the following picture:



Click image for full size.

This happens when there is no Paint Layer data on the Landscape when you first start to paint. To fix this issue, continue to paint over the Landscape generating the Paint Layer data as you go. If you would like to fill in the entire Landscape, first select a large brush size, like 8192.0, pick a layer that you want to use as a base and paint over the entire Landscape once. This will create Paint Layer data and allow you to continue to paint without anything turning black.

Another issue that you might run into is that the scale of the Textures on your Landscape are either too big or too small. To fix this, open your Landscape Material and select the Landscape Coords node. With that node selected, adjust the Mapping Scale in the Details panel and save the Material. Once the Material is re-compiled, check the scale out in the viewport. If the scale is not to your liking, then repeat the processes above until you get the results you want.



Click image for full size.

Here is a comparison between a Mapping Scale of 0.5 on the Left and 5.0 on the Right.





6 - Landscape Tips and Tricks

While the quick start tutorial above will get you up and running with a Landscape, it barely scratches the surface of what the Landscape tools can do. This section aims to show you some tips and tricks for using the Landscape Tool as well as some external tools that you can use to generate your Landscape.

Tips & Tricks

When using the Paint Tools, you might find it easier to paint over what you would like to erase than to try and erase it using Shift + Left Mouse Button.

When using the Alpha Brush, remember that you can change what the pattern that the brush uses by selecting a different RGB channels from the Texture Channel drop down menu. This is very handy because you can pack up to three different Alpha patterns in a single texture.



Click image for full size.

Landscape compiles shaders separately for each component based on which layers are painted on them. For example, if you have a component with a dirt layer on it but no trace of the grass layer has been painted on it, the textures for the grass layer are left out of the material for that component, making it cheaper to render. So when you do an optimization pass, it can be worthwhile to go over a Landscape and look for components that only have a tiny trace of a given layer and erase them to reduce material complexity.

Another issue to watch out for when painting layers is to avoid having too many textures on one component. The material editor stats show the limit of how many texture samples you are allowed to use, but for Landscape materials the masks for each layer count as texture samples too and do not show in the stats. If a component starts showing the default texture (Grey Squares) when you paint a new layer onto it, it is likely that it is gone over the texture sample limit and either needs to have a layer erased or the material needs to be optimized to use less textures.

You can change the LOD Distance Factor for individual Landscape components so they will simplify at closer or further distance thresholds. Things like mountain peaks or anything with a distinct silhouette will LOD most noticeably as you move further away, so you can reduce the LOD bias for those components to preserve their shape. You can also raise the LOD bias for low-detail areas like flat plains that will not look noticeably different with less tessellation.

World Composition

Unreal Engine 5 (UE5) now offers the ability to create massive worlds made using Landscape that can easily be managed by using the World Composition tool. World Composition was designed to help simplify the management of large worlds, especially if those worlds are made using the Landscape system. To find out more about the World Composition tool, please refer to the official document that you can find here:

World Composition Documents

External Creation Tools

While the default Landscape tools do have the ability to meet all of your sculpting and painting needs, there could be some situations where you might want some extra control over your Landscape's look and feel. The following is a list of software packages that could help you obtain the results you are looking for if you cannot get them from using the Landscape tools.

Houdini

Procedural terrain generation in Houdini uses a collection of heightfield nodes to let you use layer shapes and add noise to define the look of your digital landscapes. Use advanced erosion tools for more control over details such as fluvial lines, river banks, debris, and new hierarchical scattering for more efficient placement of elements into landscapes. You can then export height and/or mask layers to create terrain in UE5, or you can wrap up your terrain networks into Houdini Digital Assets that will open up in UE5 using the Houdini Engine plug-in. When Digital Assets include heightfield nodes, they will integrate seamlessly with Unreal Engine's native Terrain tools.

Mudbox

While primarily a tool for digital sculpting and painting 3D meshes, Mudbox can also be used to generate heightmap data for your Landscape. You can read more about how Mudbox might be able to help you out with your Landscape by checking out their website.

Terragen

Terragen is another powerful fully procedural terrain creation software. Much like World Machine, it can be used to build, texture, and export both heightmaps and textures for your Landscape. You can read more about how Terragen might be able to help you out with your Landscape by checking out their website.

World Machine

World Machine is a powerful procedural terrain creation software. It can be used to build, texture, and export both heightmaps and textures for your Landscape. You can read more about how World Machine might be able to help you out with your Landscape by checking out their website.

ZBrush

Zbrush is another digital sculpting and painting tool that can be used to generate heightmap data for your Landscape. You can read more about how Zbrush might be able to help you out with your Landscape by checking out their website.

Landscape Components

Component Sections

Landscape Component UI

Performance Considerations

Calculating Heightmap Dimensions

Example 1

Example 2

Calculating Heightmap Z Scale

Recommended Landscape Sizes

Layer Debug Mode

Striking the balance between beauty and performance when creating a Landscape in Unreal Engine can be a challenge. When building a Landscape, it is important to understand how the Landscape Actor is constructed and what dimensions provide the best performance. Valid dimensions for Landscape heightmaps are not always obvious when getting started. Being able to determine which heightmap dimensions are valid and which are optimal requires a thorough understanding of the underlying architecture of the Landscape, which are covered on this page.

Landscape Components

Landscapes are divided into multiple Landscape Components, which are Unreal Engine's base unit for rendering, visibility calculations, and collision. All of the Landscape Components in a Landscape are the same size and are always square. The size of the Landscape Component is decided when the Landscape is created and depends on the Landscape's size and detail.

Each Landscape Component's height data is stored in a single texture. Because of this, the texture's size must be a power-of-two number of vertices. The shared row of vertices along the edge of two neighboring Landscape Components is duplicated and stored in each one. For this reason, it makes sense to think about the number of 4-sided polygons (quads) in each Landscape Component.

The illustration below shows a very simple Landscape (outlined in green) that contains four Landscape Components. Each is made up of a single quad and one has been separated to show how the vertices where the Landscape Components meet are duplicated.



A Landscape made of four Landscape Components

Component Sections

Components can optionally be divided into either 1 or 4 (2x2) subsections to increase the resolution of the Landscape. These subsections are the base unit of Landscape LOD calculation.

Using 4 (2x2) subsections gives you the same size heightmap as using four times as many Landscape Components with only one subsection each, but using fewer Landscape Components gives better performance.

The size of each section (in number of vertices) must be a power of two value (with a maximum of 256x256) so that different LOD levels can be stored in the mipmaps of the texture. This will lead to the number of quads in a Landscape Component in each direction (x or y) either being a power of two value minus 1 (if 1 section per Landscape Component) or a power of two value minus 2 (if 4 sections per Landscape Component).

The illustration below shows an individual Landscape Component (outlined in green) that contains four sections. Each section is made up of 9 (3x3) quads. Again, you can see that the vertices where the sections meet are duplicated.



A Landscape Component containing four subsections.

Landscape Component UI

A Landscape Actor is color-coded to make it easier to identify each type of Landscape Component. The edges of the Landscape are highlighted in yellow, the edge of each component is in light green, section edges (if set to 2x2 sections) are in medium green, and the individual Landscape quads are in dark green.



A new Landscape being created in the Viewport showing the UI colors.

Color

Description

Yellow

Landscape Actor Edge

Light Green

Landscape Component Edge

Medium Green

Landscape Section Edge

Dark Green

Landscape Individual Quad

Performance Considerations

The choice of Landscape Component size compared to the total number of Landscape Components is a performance trade-off. Smaller Landscape Component sizes facilitate quicker LOD transitions and the occlusion of more terrain, but the smaller size also means you will need more Landscape Components.

Each Landscape Component has a render-thread CPU processing cost and each section is a draw call, so try to keep these numbers to a minimum. For the largest Landscapes, Epic recommends a maximum of 1024 Landscape Components.

Calculating Heightmap Dimensions

To create a system that can accommodate very large terrain sizes and still be efficient in terms of memory and performance, the architecture applies restrictions on the dimensions of the heightmap. These restrictions are described below. This means that some dimensions are valid and others are not.

The dimensions for a Landscape are based on the number of quads in each section, the number of sections in each Landscape Component, and the total number of Landscape Components in the Landscape. Once you determine the number of total Components and the resolution of each one, you can calculate the dimensions of the Landscape as a whole using the formula below:

(A*Quads + 1, B*Quads + 1)

A and B are the number of Landscape Components in each direction, and Quads is the number of quads per Landscape Component.

Below are two different examples of using this formula.

Example 1

If you start with a Landscape Component consisting of a single subsection that contains 64x64 vertices, then the Landscape Component size is 63x63 quads. If your Landscape has10x10 of these Landscape Components, then you have 630x630 quads total in your Landscape. To import the heights for this Landscape, you need a heightmap of 631x631 vertices, because there is always one more row of vertices than there are quads (think of a 1x1 quad - it needs 4 vertices). Therefore, 631x631 is a valid Landscape size.

Example 2

If you have a Landscape Component divided into 4 subsections, each of which is made up of 64x64 vertices, that leads to 63x63 quads per section and 126x126 quads per Landscape Component. If you have 32x32 of these components, you get 126 * 32 = 4032 quads total in each direction. Therefore, the total Landscape will be 4033x4033 vertices.

These examples focus on square Landscapes. However, you can create Landscapes that are not square. Assuming 63 quads per Component, you could have any Landscape of AxB Components with a total size in vertices of (A*63+1 , B*63+1).

Calculating Heightmap Z Scale

Unreal Engine calculates your heightmap's height by using values between -256 and 255.992, stored with 16-bit precision. The calculated height is then multiplied by the Z scale value that you input when you import the heightmap data. For example, a Z scale value of 1 results in a maximum height of roughly 256 cm and a maximum depth of -256 cm. Therefore, at the default Z scale value of 100, your height values will be between 256 m and -256 m.



Adjusting the Z scale during the import process.

Calculating a custom height requires the use of a ratio to convert your custom height value into the -256 to 256 range that Unreal Engine uses. Since the height range is a total of 512 units (-256 to 0 is 256 units and 0 to 256 is another 256 units), the ratio is 1/512 or 0.001953125.

You apply this by first converting your measurement to centimeters and then multiplying by the ratio.

Here is an example:

To represent Mauna Kea, the highest peak in Hawaii at 4207m, in an Unreal Engine Level:

Start by multiplying 4207 by 100 to convert the height into centimeters. This equals 420,700 cm.

Next, multiply this new value by the ratio: 420,700 multiplied by 0.001953125 equals 821.6796875‬.

This gives you a Z scale value of 821.6796875‬ and results in a heightmap that will go from -210,350 cm to 210,350 cm.

This process will give you the exact height of the mountain with no room for values below sea level. If you would like some additional space in your Landscape's height, adjust your initial height accordingly. To use the same example, Mauna Kea also extends 5761 m below sea level. This would give a total height to start with of 9968 m.

Recommended Landscape Sizes

Below is a list of recommended Landscape sizes that maximize the area while minimizing the number of Landscape Components.

Overall size (vertices)

Quads / section

Sections / Component

Landscape Component size

Total Landscape Components

8129 x 8129

127

4 (2x2)

254x254

1024 (32x32)

4033 x 4033

63

4 (2x2)

126x126

1024 (32x32)

2017 x 2017

63

4 (2x2)

126x126

256 (16x16)

1009 x 1009

63

4 (2x2)

126x126

64 (8x8)

1009 x 1009

63

1

63x63

256 (16x16)

505 x 505

63

4 (2x2)

126x126

16 (4x4)

505 x 505

63

1

63x63

64 (8x8)

253 x 253

63

4 (2x2)

126x126

4 (2x2)

253 x 253

63

1

63x63

16 (4x4)

127 x 127

63

4 (2x2)

126x126

1

127 x 127

63

1

63x63

4 (2x2)

Layer Debug Mode

Enabling Layer Debug mode toggles the visibility of specific layer weights on the Landscape in the viewport. Toggle the Layer Debug mode from the viewport menu: go to View > Landscape Visualizers.



Enabling the Landscape Debug visualizer

When Layer Debug Visualizer is enabled, you can select individual color channels for each of the target layers in the list.



Using the Landscape Debug Visualizer to visualize your Landscape's Paint Layers.

Selecting a channel will apply a shader to the Landscape which shows the area of the selected target layer that is covered by that channel.



Landscape Debug Visualizer applied to a Landscape.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Opening the Landscape Tool

Creating a new Landscape using the Landscape Tool

Unreal Engine 5 (UE5) is capable of creating massive terrain-based worlds using its suite of powerful terrain editing tools. Use the Landscape tool to create immersive outdoor terrain pieces that are optimized to maintain playable frame rates across a multitude of different devices.

You can create your Landscape using any of the following methods:

Create a new Landscape heightmap from scratch using the in-engine Landscape tools.

Import a Landscape heightmap created previously in Unreal Editor or created through external tools. Check out Creating and Using Custom Heightmaps and Layers.

Create your own format for importing Landscapes. Check out Creating Custom Landscape Importers.

For examples of the Landscape tool in action, see Landscapes Content Examples.

Opening the Landscape Tool

Before you can create a Landscape, you must first open the Landscape tools. From the Main Toolbar, click Select Mode, then select Landscape.



Click image for full size.

You can also press Shift + 2 on your keyboard to change to the Landscape tool at any time.

The first time you open the Landscape tool, you will automatically be taken to the Manage Mode tab. If you do not have any other Landscape Actors currently in your level, you will be prompted to create one. In Landscape Manage Mode, you can create new Landscapes and modify existing Landscapes and their components.



Click image for full size.

If your Level already contains one or more Landscapes, the Landscape tab will look different. The Landscape Editor section will display a dropdown menu with the Selection tool visible. From this dropdown menu, you can select a Landscape to work with.



Click image for full size.

Creating a new Landscape using the Landscape Tool

You create a new Landscape from scratch from the New Landscape section of the Landscape tool panel.



Click image for full size.

Number

Option

Description

1

Create New

Creates a new Landscape Actor in your Level.

2

Import from File

Imports a Landscape heightmap made in an external program.

3

Enable Edit Layers

Enables the use of Non-Destructive Landscape Layers and Splines.

4

Material

Assigns a Material to your Landscape.

5

Layers

Displays any layers that are a part of your Landscape Material.

6

Location

Sets the location in the world where the Landscape is created.

7

Rotation

Sets the rotation of the Landscape in the world.

8

Scale

Sets the scale of the Landscape in the world.

9

Section Size

Landscapes use Section Size for LOD and Culling. Landscapes with smaller sections can have more optimized LODs but at a higher CPU cost. Larger sections have fewer components and are less costly on the CPU.

If you want to have a large Landscape, you will need to use a larger section size, since using a smaller section size and then scaling the Landscape will increase the cost on the CPU.

10

Sections Per Component

Helps with the Landscape LOD. Each section is the basic unit for the Landscape LOD. One component could have 2 x 2 sections, which means that it is possible that one component could be rendering four different LODs at once.

With a larger section size, you get the added benefit of reduced CPU calculation time. However, you might run into issues with the Landscape rendering too many vertices at once. This could be especially prevalent when using very large areas of Landscape. These issues could be even worse on mobile devices because of the limited amount of draw calls you can have due to hardware limitations.

11

Number of Components

Sets the size of your landscape along with Section Size. This value is capped at 32 x 32 since each component has a CPU cost associated with it. Going over this cap could result in performance issues with the Landscape.

12

Overall Resolution

The number of vertices your Landscape is using.

13

Total Components

The total number of components that will be created for your Landscape.

14

Fill World

Makes your Landscape as big as possible.

15

Create

Creates your Landscape in the world using the settings you specified.

For the example below, we are going to leave all of the Landscape settings at their default values that are listed below.

Property Name

Value

Section Size

63 x 63 Quads

Section Per Component

1 x 1 Section

Number of Components

8 x 8

Overall Resolution

505 x 505

Be careful when choosing Section Size because as the number of components increase, build times and performance can be dramatically affected. 63x63 quads per section is generally recommended as it gives good performance and size.

When completed, you should have something that looks like this in your New Landscape properties box.



Click the image for full size.

In the main viewport, there should be a preview of the new Landscape you are setting up which should look like the following:



Click the image for full size.

Landscape Actors can Move, Rotate, and Scale like any other Actor.

You can assign a Material to your Landscape when you create it. To do so, select an appropriate Material in the Content Browser, and then assign it in the New Landscape section, next to Material, by clicking the Assign arrow icon. For more information about Landscape Materials, see Landscape Material Layer Blending.



Click the image for full size.

When you are ready to create your new Landscape, click the Create button in the lower-right corner of the Landscape tool panel. The Landscape will appear in the viewport as a flat plane. If you assigned a Material to it, it will appear with the Material applied. If not, it will use the Level Editor's default Material.



Click the image for full size.

If the Landscape is large or complex, it may take a few seconds for it to appear.

Once you have pressed the Create Button, you should have something that looks similar to the following.



With your new Landscape now created, you can now start to Sculpt or Paint the Landscape to your liking.

Editing Landscapes

Landscape Paint Mode

Creating Landscapes

Layers

Layer Formats

Layer Import

Heightmaps

Heightmap Formats

Importing Custom Heightmaps

There will be times your Landscape will require that you use external programs to create both the heightmap and layers that you will need. Unreal Engine 4 (UE4) accommodates this style of workflow by allowing for the import of custom heightmaps and layers.



If this is your first time using the Landscape tools, you might want to check out the Landscape Overviewfirst.

Layers

Landscape layers are special textures that can contain both heightmaps and color data. Which can be used customize the look and feel of your Landscape.

Layer Formats

Landscape layers can be imported from external programs via implementation of the ILandscapeHeightmapFileFormat and ILandscapeWeightmapFileFormat interfaces. The editor's existing support for image-based importing has been converted to use this interface and is fully supported. Images for the built-in formats are still required to be grayscale, 8 bits per pixel, single channel files in either .PNG or .RAW format. If you are creating layers in Photoshop, use the following settings when creating a new document:



Layer Import

Importing Layers that were made in an external application provides you with the flexibility to use your preferred terrain workflow, but you first need to make sure that a few things are set up in order to get everything to work smoothly.

First, make sure that you have created a Landscape to work with. If you have questions regarding the Landscape creation process, check out Landscape Creation.

Next, make a new Material. For this example, we will be making a very basic Material that could be easily be expanded upon if needed. The Setup for your Material should look something like this.



Number

Description

1

LandscapeLayerCoords

2

TextureSample: T_Ground_Grass_D (Found in StarterContent/Textures)

3

TextureSample: T_Ground_Gravel_D (Found in StarterContent/Textures)

4

TextureSample: T_Rock_Slate_D (Found in StarterContent/Textures)

5

LandscapeLayerBlend

Once the Material is complete, apply it to the Landscape Actor. This will turn your whole landscape black.



To fix the issue, you will need to add some Layer Info to your Landscape Actor. For this example, create one Layer Info object for each of our three layers. To read more about Layer Info objects, refer to the Layer Info Objects page.



When completed, your Target Layers section of your Landscape panel should look something like this.



Now it is time to import our custom layer. To do this, right-click on the chosen Target Layer and select the Import from file option from the pop up menu. This will prompt you to choose the .PNG or .RAW file that contains your custom layer data. Your custom layer file should be the same resolution as your Landscape Actor's Overall Resolution that was set when you created it (the default is 505 x 505).



If your layers are not output at the correct size, you will see the following warning:



To fix this issue, return to your image editing software and resize your file to match the correct Landscape extent as displayed by the warning message.

Heightmaps

Using external tools to create a base heightmap to use inside UE4 can be a excellent way of speeding up the Landscape creation process. Programs such as World Machine and Terragen can quickly create the base heightmap for your Landscape. Which can then be imported, cleaned up, or modified using the editing tools inside Unreal Editor, making it a better fit with the world and desired game play.

Heightmap Formats

When exporting heightmaps from external programs, only the following formats are usable inside UE4.

16-bit, grayscale PNG file

16-bit, grayscale RAW file in little-endian byte order

If you are using Photoshop to export your heightmap, set up your new images like the following:

When making a heightmap in an external application, a value of White (255 in all channels) will represent the highest point on your heightmap and a value of Black (0 in all channels) will represent the lowest point on your heightmap.

Importing Custom Heightmaps

Importing a custom heightmap is initiated by clicking the New button from the Landscape Mode toolbar. To activate it, select the radio button labeled Import from File in the Landscape panel to open the ability to import a heightmap from a file.



Select a Heightmap to import by pressing the button next Heightmap File option and then select your Heightmap using the file browser.



Now let's try importing a custom heightmap. For this example, we will be using the image below.



Make sure you right-click Save as on the image (above) to download it to your PC.

With the example heightmap saved to your PC, it is now time to use it in the Landscape tools.

Open the Landscape tool and click the New button from the Manage Mode tab.



Select Import from File.



Click the button in the Heightmap File section and choose the example Heightmap you downloaded earlier.



Now press the Import button to create a new Landscape based on your heightmap.



Before pressing the Import Button:



After pressing the Import Button:



Writing A Custom Importer

Creating your own heightmap and weightmap formats for importing landscape data is accomplished by writing a plugin. The plugin will add your new format to the engine, as well as importing the data from your files.

Writing A Custom Importer

In order to create new importers, your plugin should create instances of objects implementing ILandscapeHeightmapFileFormat and ILandscapeWeightmapFileFormat, and register those objects with ILandscapeEditorModulemodule::RegisterHeightmapFileFormat and ILandscapeEditorModulemodule::RegisterWeightmapFileFormat, respectively.

Implementing the ILandscapeHeightmapFileFormat interface in a plugin requires overriding the following functions:

const FLandscapeFileTypeInfo& GetInfo() const: Returns type information indicating which file types this class handles, and whether or not exporting is supported.

FLandscapeHeightmapInfo Validate(const TCHAR* HeightmapFilename) const - Validates the named file, or rejects it and returns an error code and message.

FLandscapeHeightmapImportData Import(const TCHAR* HeightmapFilename, FLandscapeFileResolution ExpectedResolution) const - Actually imports the file.

void Export(const TCHAR* HeightmapFilename, TArrayView<const uint16> Data, FLandscapeFileResolution DataResolution, FVector Scale) const - Exports the file, if this format supports exporting (see the return value from GetInfo). This is the only function that doesn't need to be overridden in order to compile. However, if it is called without being overridden, it will call check.

(Destructor) - Classes that implement this interface should use a virtual destructor, as they will be deleted via a pointer to the interface class.

Implementing the ILandscapeWeightmapFileFormat interface is nearly identical, with only minor differences in some return types:

const FLandscapeFileTypeInfo& GetInfo() const - Returns type information indicating which file types this class handles, and whether or not exporting is supported.

FLandscapeWeightmapInfo Validate(const TCHAR* WeightmapFilename) const - Validates the named file, or rejects it and returns an error code and message.

FLandscapeWeightmapImportData Import(const TCHAR* WeightmapFilename, FLandscapeFileResolution ExpectedResolution) const - Actually imports the file.

void Export(const TCHAR* WeightmapFilename, TArrayView<const uint16> Data, FLandscapeFileResolution DataResolution, FVector Scale) const - Exports the file, if this format supports exporting (see the return value from GetInfo). This is the only function that doesn't need to be overridden in order to compile. However, if it is called without being overridden, it will call check.

(Destructor) - Classes that implement this interface should use a virtual destructor, as they will be deleted via a pointer to the interface class.

For further information and examples, you can see the interfaces in LandscapeFileFormatInterfaces.h, the .PNG implementations in LandscapeFileFormatPng.cpp and LandscapeFileFormatPng.h , and the .RAW implementations in LandscapeFileFormatRaw.cpp and LandscapeFileFormatRaw.h. All of this code is in the LandscapeEditor module in the engine.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Installing Unreal Engine

Creating a New Project

1. Required Setup

2. Navigating the Viewport

3. Create a New Level

4. Placing Actors in the Level

5. Editing Placed Actors

6. Running the Build Process

7. On Your Own!

Choose your operating system:

Windows

macOS

Linux



At the end of this guide, you'll have a room similar to the one pictured above.

The focus of the Unreal Editor Quick Start Guide is to walk you through the basics of working with Unreal Engine 5.

After going through this tutorial, developers will know the following:

How to navigate viewports

How to create a new level

How to place and edit actors in levels

How to build and run levels

1. Required Setup

In the Project Browser, you can create new projects based off several different template types, or open any previously created projects or samples that you have downloaded. Let's create a new project.

After Installing Unreal Engine and launching the Unreal Editor, the Project Browser appears. Under New Project Categories, select a development category. For this quick start, let's create a project from the Games category, then click Next.



Click image for full size.



Click image for full size.

In the second page of the Project Browser, select the Blank template, then click Next.



Click image for full size.



Click image for full size.

On the final page of the Project Browser, select the Blueprint and With Starter Content settings, enter a Folder location and Name for your project, then click Create Project.



Click image for full size.



Click image for full size.

2. Navigating the Viewport

With the project open and ready to go, the first thing you may notice is the Viewport in the center of the Unreal Editor.



Inside the Viewport is where you will do most of your level construction. The template project that we selected in the previous step includes a small sample Level and some assets for us to get started with. Using this little area as a point of reference, take a moment to get used to the Viewport Camera Controls by using the most common methods of navigating the Viewport in Unreal Engine 5.

Standard Controls

These controls represent the default behavior when clicking and dragging in the viewports with no other keys or buttons pressed. These are also the only controls that can be used to navigate the orthographic viewports.

Control

Action



Perspective



LMB + Drag

Moves the camera forward and backward and rotates left and right.

RMB + Drag

Rotates the viewport camera.

LMB + RMB + Drag

Moves up and down.



Orthographic (Top, Front, Side)



LMB + Drag

Creates a marquee selection box.

RMB + Drag

Pans the viewport camera.

LMB + RMB + Drag

Zooms the viewport camera in and out.



Focusing



F

Focuses the camera on the selected object. This is essential to make the most out of tumbling the camera.

To switch to an Orthographic View, click the Perspective drop-down then select an Orthographic View Mode.



Click image for full size.

WASD Fly Controls

All of these controls are only valid in a Perspective viewport, and by default you must hold RMB to use the WASD game-style controls.

Control

Action

W / Numpad8 / Up

Moves the camera forward.

S / Numpad2 / Down

Moves the camera backward.

A / Numpad4 / Left

Moves the camera left.

D / Numpad6 / Right

Moves the camera right.

E / Numpad9 / Page Up

Moves the camera up.

Q / Numpad7 / Page Dn

Moves the camera down.

Z / Numpad1

Zooms the camera out (raises FOV).

C / Numpad3

Zooms the camera in (lowers FOV).

Orbit, Dolly, and Track

Unreal Editor supports Maya-style pan, orbit, and zoom viewport controls, making it much easier for Maya artists to jump into the tool. If you are unfamiliar, here is a breakdown of the keys:

Command

Description

Alt + LMB + Drag

Tumbles the viewport around a single pivot or point of interest.

Alt + RMB + Drag

Dollies (zooms) the camera toward and away from a single pivot or point of interest.

Alt + MMB + Drag

Tracks the camera left, right, up, and down in the direction of mouse movement.

The use of the F key is not limited to Maya-style controls. You can always press F to focus on a selected object or group of objects.

3. Create a New Level

Next we will create a new Level that we will use to build our game environment in. While there are several different ways in which you can create a new Level, we will use the File Menu method, which lists level selection options.

Inside the Unreal Editor, click the File Menu option then select New Level....



Click image for full size.



This will open the New Level dialog window:



Click image for full size.



The Default level includes some of the commonly used assets for constructing levels, the VR-Basic level includes some assets for constructing levels with the VR Editor, and Empty Level is a completely blank level with no assets. For the purposes of this guide we are going to start from scratch with a completely blank slate.

Click the Empty Level to select it.

4. Placing Actors in the Level

In this step, we will begin placing Actors (for example, lights or geometry) into our empty level. We will cover the two most common ways of adding Actors to the level: through Select Mode and through the Content Browser. After completing this step, you will know how to place Actors inside your own levels and can begin manipulating those Actors to create your environment.

In the Place Actors panel on the left, click the Geometry category and select the Box.



Click image for full size.

Left-click and drag the Box into the Level Viewport.



Click image for full size.

When you release the Left Mouse Button, the Box is added to the level.



In the Details panel (lower-right window of the editor), with the Box still selected, set Location and Rotation all to 0.

Set the Scale to 4 x 4 x 0.1.



Click image for full size.

We will use this as the floor on which the player can walk around.

In the Place Actors panel select the Lights tab, then drag-and-drop a Directional Light into the level on top of the floor.

](13-place-light.png)

Click image for full size.

On the Translation Tool, click and drag the Z-Axis (blue) on the gizmo up, away from the surface of the floor.



If the Directional Light becomes unselected, you can re-select it by Left-clicking on it in the Level Viewport.

In the Place Actors panel, select the Visual Effects tab and drag-and-drop an Volumetric Cloud into the level.



Click image for full size.

The Volumetric Cloud Actor will add a basic sky to the level and the level will become illuminated instead of dark.

In the Place Actors panel, select the Basic tab and drag-and-drop a Player Start into the level.



Click image for full size.

In the Place Actors panel, select the Volumes tab and drag-and-drop a Lightmass Importance Volume into the level.



Click image for full size.

The Lightmass Importance Volume is used to control and concentrate lighting and shadowing effects within the volume. When placing the Lightmass Importance Volume in the level, the default size of the volume does not cover our playable area, so we will need to scale it up.

Inside the Level Viewport, press R to switch to the Scale Tool.

Click and drag the white box in the center of the Scale Tool so that the Lightmass Importance Volume encapsulates the floor.



Click image for full size.

Inside the Content Browser under Content > StarterContent > Props, drag-and-drop the SM_TableRound into the level.



Click image for full size.

Try to place the table in the center of the floor using the Move Tool (press W if it is not selected).

Also under Content > StarterContent > Props, drag-and-drop the SM_Chair into the level.



Click image for full size.

With the SM_Chair selected inside the Level Viewport, press E to access the Rotation Tool.



Left-click and drag the blue axis arc (the gizmo will update to show degrees) and rotate the chair to face the table.



Using the placement methods above, create a small scene by adding more Actors from the Modes Panel and Content Browser.



Click image for full size.

Try adding some lights, props, walls and a roof (found under the Content > StarterContent > Architecture folder).

Need help punching out the holes for windows and doors? Check out our video on Adding Windows & Doors.

5. Editing Placed Actors

With several different Actors placed inside our level, the next step involves Editing Actor Properties that can change the look or the way the Actor functions in the level, giving us a more customized looking level. We will start with editing the properties of our Directional Light Actor then shift our focus to applying Materials to some of the Static Mesh Actors that you have placed in your level.

Once you have finished this step, you will have seen where to access and modify the properties of Actors, so that you can begin editing and experimenting with different settings inside your own levels.

Select the Directional Light Actor by Left-clicking on it in the Viewport.



In the Details Panel under the Light category, enable Atmosphere Sun Light:



Click image for full size.

Depending on the rotation of your Directional Light Actor, the sky color will change. If you rotate the Viewport around, you will see that the sun now aligns with the Directional Light Actor. This is a real time process, so you can rotate the Directional Light Actor (press E to switch to Rotation Mode) and the sky will change color from night to sunrise, daytime, and sunset.

Next we will change the Material on one of your placed Static Mesh Actors by first selecting it.

With your Actor selected, in the Details panel under Materials, click the drop-down box under Element 0.



Click image for full size.

In the pop-up window, select the M_Brick_Clay_New Material.



Click image for full size.

All Actors in your level have many properties for you to adjust inside the Details panel. Explore changing their settings!



Click image for full size.

Try changing the Light Color of your lights, applying more Materials or changing the Scale of the Actors in your level.

6. Running the Build Process

By now you may have noticed the "Preview" labels in the shadows and the light leaking under walls.



This is because all the lights in the scene are static and use precomputed, or baked lighting, which has not been calculated yet. The "Preview" text is there to remind you that what you are seeing in the viewport currently is not what you will see in the game.

In this step, we will go through the Build process which will build all levels (precompute lighting data and visibility data, generate any navigation networks and update all brush models). We will also take a look at Light Quality settings inside of the Build Options, which we can use to adjust the quality of our lighting when it is built.

From the Main Toolbar, click the down-arrow next to the Build option.



Click image for full size.

Under Lighting Quality, choose the Production setting.



Click image for full size.

This will give us the highest quality lighting but is the slowest in terms of computation time and will increase the time it takes to Build the game. Our level is small, so it should not impact us too much, but keep this in mind when you are working on larger levels as you may want to leave it on a mid-low level setting while creating your level and switching it to Production in a "final pass" on your level.

Wait for the Build to complete.



You will see the progress in the lower-right corner of the Unreal Editor as seen in the image above. Once the Build process is complete, the level lighting will update to give you a better indication of the final result.



From the Main Toolbar, click the Play Button to play in the editor.



Click image for full size.

Using WASD to move and the Mouse to turn the camera, you can fly around your level.

7. On Your Own!

At this point, you should have created a Build of the level lighting and previewed your game with the Play in Editor feature. Each of the steps leading up to this point have been aimed at getting you quickly up to speed on how to perform the most common actions when constructing levels inside the Unreal Editor.

Using the methods that were provided during the course of this guide, try to do the following on your own:



Change the lighting of the level to a moonlit, night scene.

Add another room, attached to the first room.





On the attached room, try to make it elevated and join them with stairs.

Add some bushes, a couch, shelves and a front door.



Add different kinds of lights with different colors.

Use different Materials on some of your Actors.

For more information on the topics covered in this quick start guide, see the Building Virtual Worlds.

As for specifics covered in this quick start:

For more information on the Level Editor, see: Level Editor

For more information on Viewports, see: Viewports

For more information on the Editing Modes available in Unreal Editor, 5 see: Level Editor Modes

For more information on the Content Browser, see: Content Browser

For more information on the Details Panel, see: Details Panel

For more information on Building, see: Lightmass

For more information on Lighting, see: Lighting Quick Start Guide

New UE5 Lighting Features

Lighting Essentials

Lighting Features and Tools

Lighting Tools and Plugins

General

A significant part of building any virtual world is determining how it will be lit. This means being able to efficiently light small enclosed scenes with small lights to large worlds primarily lit by single dominant light source. The engine provides the tools and lighting options necessary to achieve the results your project's demand.

The topics in this page contains information on the the various lighting features and tools available to use, along with guides that create a learning path to the ins and outs of lighting a scene in Unreal Engine.

New UE5 Lighting Features



A high level overview of Lumen's dynamic global illumination and reflections features.



An overview of technical capabilities and specifications of the Lumen Global Illumination and Reflections system.



Overview of using high resolution shadowing designed with film-quality assets and large dynamically lit open worlds in mind.

Lighting Essentials



The available types of lights to choose from and how their mobility settings affect lighting in the scene.



An overview of the various properties and features that lights support.



Rendering subsystem including lighting and shadowing, materials and textures, visual effects, and post processing.

Lighting Features and Tools



Components and tools that enable users to build immersive worlds with environment lighting from fog, clouds, sky and atmosphere.



A collection of topics on the global illumination options available to choose from.



A high level overview of Lumen's dynamic global illumination and reflections features.



An overview of Mesh Distance Fields and its available features that you can use when developing your games.



A collection of topics around the supported features of ray tracing and path tracing.



An overview of available shadowing methods and the properties they support.



Overview of using high resolution shadowing designed with film-quality assets and large dynamically lit open worlds in mind.



Systems for how reflections are captured and displayed on reflective surfaces.

Lighting Tools and Plugins



A collection of tools and plugins that are useful for lighting scenes.



An overview of using screen space shadowing to harden shadow contact points.



Information on using phsyics capsules for dynamic soft shadowing of Skeletal Meshes.

General



Effects applied to the whole rendered scene prior to being rendered.



An overview of the volumetric fog and lighting options available with the Exponential Height Fog Component.



An overview of using Direcitonal Light to simulate light scattering through the atmosphere.



This page explains how to use transparency in your Materials.



Guide for using the Bump Offset node in your Materials.



An overview of setting up and using IES textures with lights.



A Blueprint tool to quickly set up product visualization using an HDR image projection with real-time lighting and shadowing.

Light Mixer

Environment Light Mixer

Fog Effects

Fog Effects Topics

Atmosphere, Cloud, and World Lighting Effects

Atmosphere, Clouds, and World Lighting Topics

Atmosphere, Clouds, and World Lighting Properties Reference

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Unreal Engine provides a set of components that allow for designers and artists to create immersive worlds with physically based lighting at large — or even small — scale while working efficiently to do so. These environment lighting components for atmosphere, clouds, fog, and lighting all work seamlessly together to create a unified experience that supports fully dynamically lit worlds.

The tools and features in this page will help you get started with creating your own worlds.

Light Mixer

The Light Mixer is a dockable editor window where you can add, edit, and reference properties of Directional, Point, Spot, and Rect Lights in your Level.

For artists and designers, this window simplifies and can speed up your workflow by having them availabl and editable in one location. This includes lights that are components of scene Actors or of Blueprints. You can use Collections to organize them as well.



For more information, see Light Mixer.

Environment Light Mixer

The Environment Light Mixer is a dockable editor window where you can add, edit, and reference properties of environment lighting components for sky, clouds, atmosphere lights, and a sky light.

For artists and designers, this window simplifies and can speed up your workflow by having them all available in one location.



For more information, see Environment Light Mixer.

Fog Effects

Fog effects are useful for adding ambiance to the world and setting the mood for environments. This includes creating multi-layered fog for high and low-lying areas, and volumetric effects for light shafts.



The Sky Atmosphere includes its own scattering and height fog simulation, but also works well with the Exponential Height Fog to support all types of lights in the scene.





When the Project Setting Support Sky Atmosphere Affecting Height Fog is enabled, any contribution from Exponential Height Fog is additive. The Sky Atmosphere's height fog is applied on top of the Exponential Height Fog colors. However, should the Fog Inscattering Color and Directional Inscattering Color be set to black, the Sky Atmosphere will directly affect and influence the coloring of any Exponential Height Fog in the scene.

Fog Effects Topics



An overview of the height-based, distant fog system.



An overview of the volumetric fog and lighting options available with the Exponential Height Fog Component.

Atmosphere, Cloud, and World Lighting Effects

The lighting components for Sky Atmosphere, Volumetric Clouds, Directional Lights, and Sky Light make up the majority of your enviornment lighting. These components all work seamlessly together dynamically lit large worlds possible.



In your Levels, you can use the following components:

Up to two Directional Lights for the sun and moon, two suns, or any combination.

A single Sky Light with optional real-time capturing.

A Sky Atmosphere with its own height fog.

Volumetric Clouds with or without a sky dome mesh.

With Real Time Capture enabled on the Sky Light, use the keyboard shortcut Right Ctrl + L (first Directional Light) or Right Ctrl + Right Shift + L (second Directional Light) in combination with moving the mouse to change lighting dynamically and see the results instantly.

Atmosphere, Clouds, and World Lighting Topics



A physically-based sky and atmosphere rendering system with time-of-day features and ground-to-space view transitions featuring aerial perspective.



Real-time cloud rendering using volumetric materials.



The basics of undestanding directional lights.



The basics of undestanding sky lighting.

Atmosphere, Clouds, and World Lighting Properties Reference



Settings and property reference for the Sky Atmosphere Component.



Settings and property reference for the Volumetric Clouds Component.

Opening the Environment Light Mixer

Environment Light Mixer Interface

Toolbar

Adding Scene Components

Controlling the Amount of Properties Detail

Components Panels

The Environment Light Mixer is an editor window where you can create and edit a Level's environment lighting components for sky, clouds, atmosphere lights, and sky lighting. For designers and artists, it's a single window that enables you to edit these components quickly and choose the amount of properties detail you want access to.



Click image for full size.

Opening the Environment Light Mixer

Open the Environment Light Mixer from the Main Menu by selecting Window > Env. Light Mixer.



Environment Light Mixer Interface

The Environment Light Mixer's interface is comprised of two primary elements:



Click image for full size.

Toolbar

Components Panels

Toolbar

The Toolbar is where you'll add and configure the level of properties detail that is visible in the Components Panels.



Click image for full size.

When you open the Environment Light Mixer window, if you are starting from an empty Level, you will find the following components listed:



Click image for full size.

Sky Light

Atmosphere Lights (2x Directional Lights for sun and moon, or two suns representation)

Sky Atmosphere

Volumetric Cloud

If any of these components is added from the Place Actors panel or already exists in the scene, the list will automatically reflect what is not currently added. Likewise, when you remove a component from the scene, the create button becomes available again in the toolbar.

Controlling the Amount of Properties Detail

When one of the available components is referenced in your Level – whether you added it through the Environment Light Mixer, or it already exists – the component's properties are added to the Components Panel where you can adjust and edit various properties for each of them.

For those that want maximum control over editing of their components, you can change the amount of properties shown using the Property Details dropdown:



Minimal provides the bare essentials for components.

Normal provides the common properties for components.

Normal+Advanced provides common and advanced properties for components.

Below are examples of the amount of properties shown for the Directional Light using each detail amount:







Minimal

Normal

Normal+Advanced

Click images for full size

Components Panels

The Components Panels lists any of the components available in the Toolbar to add to your scene. It includes components for Sky Atmosphere, Volumetric Clouds, up to two Directional Lights, and a Sky Light.

By Default, the properties displayed for each component is limited to its Minimal set but can be extended to show more using the Property Details dropdown in the toolbar.



Using Exponential Height Fog

Exponential Height Fog Properties

Using Exponential Height Fog Features

Secondary Fog Layer

Volumetric Fog

Performance

Exponential Height Fog creates more density in low places of a map and less density in high places. The transition is smooth, so you never get a hard cutoff as you increase altitude. Exponential Height Fog also provides two fog colors — one for the hemisphere facing the dominant directional light (or straight up if none exists), and another color for the opposite hemisphere.

Using Exponential Height Fog

In the Place Actors panel, select the Exponential Height Fog Actor, under Visual Effects. Left-click and drag to place it in the world.



Positioning the Exponential Height Fog Actor will determind the height of the fog. Use the Fog Height Falloff to further adjust the height.





Exponential Height Fog Properties

In the Exponential Height Fog Component section, you can edit the following properties related to the component:

Property

Description



Exponential Height Fog Component



Fog Density

This is the global density factor, which can be thought of as the fog layer's thickness.

Fog Height Falloff

Height density factor controls how the density increases as height decreases. Smaller values make the transition larger.

Second Fog Data

These settings control the secondary fog level. Setting the Fog Density of this secondary fog layer to 0 will have no influence.

Fog Density: The secondary fog layer's global density factor, which can be used to add another fog layer thickness.

Fog Height Falloff: The height density factor for the secondary fog layer that controls how the density increases as height decreases. Smaller values make the transition larger.

Fog Height Offset: The height offset relative to the Actor's Z height position in the world.

Fog Inscattering Color

Sets the inscattering color for the fog. Essentially, this is the fog's primary color.

Sky Atmosphere Ambient Contibution Color Scale

This color is used to modulate the Sky Atmosphere component conntribution to the non-directional component of the fog.

Fog Max Opacity

This controls the maximum opacity of the fog. A value of 1 means the fog will be completely opaque, while 0 means the fog will be essentially invisible.

Start Distance

Distance from the camera that the fog will start.

Fog Cutoff Distance

Scene elements past this distance will not have fog applied. This is useful for excluding skyboxes that already have fog baked into them.



Inscattering Texturing



Inscattering Color Cubemap

Cubemap that can be specified for fog color, which is useful to make distant, heavily fogged scene elements match the sky. When the cubemap is specified, Fog Inscattering Color is ignored, and Directional inscattering is disabled.

Inscattering Color Cubemap Angle

Angle to rotate the Inscattering Color Cubemap around the Z (height) axis.

Inscattering Texture Tint

The tint color used when Inscattering Color Cubemap, which is useful for making quick edits without having to reimport the cubemap specified with Inscattering Color Cubemap.

Fully Directional Inscattering Color Distance

Distance at which Inscattering Color Cubemap should be used directly for the Inscattering Color.

Non-Directional Inscattering Color Distance

Distance at which only the average color of Inscattering Color Cubemap should be used as Inscattering Color.



Directional Inscattering



Directional Inscattering Exponent

Controls the size of the directional inscattering cone, which is used to approximate inscattering from a directional light source.

Directional Inscattering Start Distance

Controls the start distance from the viewer of the directional inscattering, which is used to approximate inscattering from a directional light.

Directional Inscattering Color

Sets the color for directional inscattering, used to approximate inscattering from a directional light. This is similar to adjusting the simulated color of a directional light source.



Volumetric Fog



Volumetric Fog

Whether to enable Volumetric Fog. Scalability settings control the resolution of the fog simulation.

The Volumetric Fog currently does not support Start Distance, Fog Max Opacity, and Fog Cutoff Distance. In general, it cannot match Exponential Height Fog, in general, since it has non-physical behavior.

Scattering Distribution

Controls the scattering phase function—how much incoming light scatters in various directions. A distribution value of 0 scatters equally in all directions, while a value of 0.9 scatters predominantly in the light direction. In order to have visible volumetric fog light shafts from the side, the distribution will need to be closer to a value of 0.

Albedo

The height fog particle reflectiveness used by Volumetric Fog. Water particles in the air have an albedo near white, while dust has slightly darker value.

Emissive

Light emitted by Exponential Height Fog. This is a density, so more light is emitted the further you are looking through the fog. In most cases, Sky Light is a beter choice. However, Volumetric Fog does not support precomputed lighting right now, so Stationary Sky Light is unshadowed, and Static Sky Light doesn't affect Volumetric Fog at all.

Extinction Scale

Scales the height fog particle extinction amount used by Volumetric Fog. Values larger than 1 cause fog particles everywhere absorb more light.

View Distance

Distance over which Volumetric Fog should be computed. Larger values extend the effect into the distance but expose under-sampling artifacts in details.

Start Distance

The distance from the camera that the Volumetric Fog will start, in world units.

Near Fade in Distance

The distance over which Volumetric Fog will fade in from the start distance.

Static Lighting Scattering

Controls the intensity of scattered static lighting in the Volumetric Fog.

Override Light Color with Fog Inscattering Colors

Whether to use Fog Inscattering Color for the Sky Light's Volumetric Scattering Color and Directional Inscattering Color for the Directional Light's Scattering Color. Make sure your Directional Light has Atmosphere Sun Light enabled. It allows Volumetric Fog to better match Exponential Height Fog in the Distance but produces non-physical volumetric lighting that may not match surface lighting.

Using Exponential Height Fog Features

The sections below cover the usage of some of the features found in the Exponential Height Fog volume:

Secondary Fog Layer

Add a second fog layer to your level using the properties found under the Second Fog Data category. It enables you better define and control fog at a second Z (height) level in your map with controls for density, height falloff, and height offset.





Volumetric Fog

Control Volumetric Fog by enabling it in the Exponential Height Fog's Details panel under the Volumetric Fog category.

Unreal Engine's Volumetric Fog computes participating media density and lighting at every point in the camera frustum so that varying densities and any number of lights affecting the fog can be supported.



See Volumetric Fog for additional details and usage.

Performance

The rendering cost of Exponential Height Fog is similar to two layers of constant density height fog with an additional optimization; fog Start Distance. The start distance is used to artificially keep some defined area in front of the viewer without fog. This also helps performance as pixels can be culled by the Z-buffer.

Below are examples of this in practice:

Fog Start Distance: 0

Fog Start Distance: 5000

Fog Start Distance: 5000 with high fog density

Fog Start Distance Preview



Depending on the scene content and when using a far fog Start Distance, the rendering cost can be 50% or less. This optimization is implemented by rendering a full-screen quad that has a Z-value and depth test enabled.

Light Mixer Interface

Managing Lights

Light Context Menu

Light Collections

Customizing Light Mixer

Lights as Components

The Light Mixer provides a dedicated interface tailored to the creative requirements for lighting. Artists can isolate lights, change their visibility, and have relevant settings readily available to achieve a desired look. Lights can also be grouped into collections for quicker access to groups of lights.

The Light Mixer focuses on management of standard Light Types and is complementary to the Environment Light Mixer, which focuses on environment lighting components, such as sky, clouds, atmosphere lights, and skylight.

The Light Mixer panel displays all the lights that exist in the currently loaded Level and its sub-levels. It even shows lights that are components of existing scene Actors or inside Blueprints. You can specify which light parameters you want to display in the panel and change their values directly within this panel.



Light Mixer Interface

Open the Light Mixer from the Editor main menu by selecting Window > Light Mixer.

The Light Mixer interface consists of these elements:



Toolbar

Light Mixer Panel

Toolbar

The Toolbar is where you can add different types of lights to the scene, and to the list of lights in this component panel.



You can do the following from the Toolbar:

Add Lights to the scene.

Filter Lights using the Search bar.

Sync the Lights in the Level with Light Mixer.

Toggle Light Mixer options.

Manage Light Collections.

Sync Selection

The Sync Selection toggle synchronizes the Light selection in the Light Mixer to the Outliner selection.



If enabled, clicking items in the Light Mixer list also selects the same items in the Outliner.

You can use Alt + Click to select items only in the Light Mixer list without selecting them in the Outliner.

If this option is disabled, selections will not synchronize unless you hold down the Alt key while clicking lights in the Light Mixer.

Settings Menu

The Light Mixer Settings menu contains options to configure the list view, as well as a command to force the list of scene lights to rebuild.



The Settings menu contains the following options:



List View Options to toggle whether folders are visible or not in the Light Mixer panel.

Open Generic Object Mixer Instance opens a blank panel for development purposes. This underlying toolset is used to make panels similar to the Light Mixer and Environment Light Mixer panels composed of different objects that can be edited in a singular place.

Rebuild List forces the Light Mixer panel to re-evaluate the entire scene for lights and updates to lights if the list doesn't update as expected. This is like a hard refresh of the Light Mixer.

Managing Lights

The Light Mixer panel is where you can manage and edit Lights in your scene.

Filtering Lights

Use the Search Filter at the top of the Light Mixer panel to filter lights or objects by name.



For large scenes with many lights, filtering lights with search can speed up workflows.

Selecting Multiple Lights

You can select one or more Lights using the following keyboard shortcuts:

Individually select Lights by holding Ctrl and clicking them.

Select groups of Lights by clicking one, then holding Shift and selecting another light in the list. Any objects between the first clicked and last clicked will be selected as a group.

You can deselect individual Lights or groups of Lights in the same manner.

Editing Multiple Lights

By selecting multiple Lights at once, you can change the values of their shared attributes from within the Light Mixer panel without having to update each Light individually. Editing multiple Lights' attributes simultaneously can speed up your workflow for lighting and editing scenes. This includes being able to isolate lights and change light visibility to work on areas of your Level.

Light Visibility

Toggling the visibility (or muting) Lights will turn them off and on in a non-destructive way. Click the Eye icon to toggle the visibility of the selected Light or Lights.

[VIDEO LINK: https://drive.google.com/file/d/15wPBqSGab4n_QYYU-R4smt1NQs3eKKi9/view?usp=share_link]

Isolating Lights

There is an option to isolate (or Solo) any selected Light(s) so that only they are visible. This way, you can quickly see the lighting influences from one or more lights in the scene in a non-destructive way. Lights can be isolated individually or as a group when the parent object or folder is isolated.

Click the Dash ( - ) icon under the Headphones column to toggle the Visibility flag of all unselected Lights in the scene. When a Light is set to Solo, the dash is replaced by the Headphones icon. Clicking the Headphones icon next to a light that is set to Solo will re-enable visibility of all other lights in the scene.

Adding Lights

Use the Add button to add directional, spot, point, or rectangular area lights to the scene, which you can then click and drag into place.



Alternatively, you can drag any one of the light types directly from the menu into the scene to place it.

Light Context Menu

The right-click Context Menu looks and works similarly to the one used in the Outliner.



One additional option provided by the Context Menu is to Select or Add Collection, which you can read about in the Light Collections section below.

Edit Options

Use the Edit menu to Cut, Copy, Paste, Duplicate, Delete, and Rename lights. Alternatively, you can either use keyboard shortcuts (like Ctrl+X, Ctrl+V, and so on) in place of the menu options.

Replacing Lights

Use the Replace Selected Actors With option to replace a selected Light with another Light. You can even replace them with other Actors in the list that are not lights. All Actors in the list must have at least one light as a child component.

Reparenting Lights

There are two ways to reparent one or more lights:

Drag and Drop Method

Select the Lights you want to reparent and drag them over the listed object you want them to be parented to.

Attach to Method

Select the Lights you want to re-parent.

Right-click the selected Lights and, from the context menu, select Attach To.

Select an Actor from the list you want to reparent the Lights to.

Light Collections

Collections serve as a way to organize Assets into groups into non-destructive user-defined sets. In the Light Mixer panel, you can use this same workflow to make a collection of lights to speed up lighting workflows by organizing and isolating lights that you frequently change for easier access.

All the lights in the scene automatically belong to a default light collection called All. This particular collection category doesn't appear until another collection is created.

Creating a Light Collection

Create Light Collections using the right-click Context Menu in the Light Mixer panel.

Select one or more lights in the Light Mixer panel.

Right-click the selected lights to open the Context Menu.

Click Select or Add Collection.

In the text field, give the collection a Name and press Enter to confirm.

The newly created Light Collection will be listed between the Search Filter and Light Mixer Panel columns. There is no limit to the number of Light Collections you can create to help manage your scene.



Viewing a Light Collection

You can view a Light Collection by clicking its name in the Collections bar under the Search. Clicking a collection shows only the Lights and components belonging to that collection. The All collection restores all the lights to the Light Mixer panel.

Adding Lights to a Light Collection

Add lights to Light Collections using the right-click Context Menu. The workflow is the same as creating a collection, except that you can choose from a list of existing Light Collections to add a light to instead of creating a new collection.

From the Context Menu next to Select or Add Collection, under the text field, find an existing Light Collection from the list to add the Lights to, and check the box next to the Collection to add the Lights to it.

Lights are not exclusive to a single Light Collection. You can have as many collections as you need and the same Lights can belong to any of them.

Removing Lights from a Light Collection

Remove lights from Light Collections using the right-click Context Menu. The workflow is the same as creating a collection, except that you are changing the selection of collections the Light belongs to.

In the Context Menu next to Select or Add Collection, under the text field, uncheck any Light Collections to remove the selected Lights from those collections.

Deleting, Duplicating, and Renaming Light Collections

Right-click the tab of any Light Collection to Delete, Duplicate, or Rename that collection.



The All Light Collection is the only one that cannot be deleted, duplicated, or renamed. Right-clicking it will not expose these options.

Reordering Light Collections

Reorder Light Collections by left-clicking and dragging them to a new position.

The All Light Collection is the only one that cannot be reordered.

Customizing Light Mixer

The Light Mixer provides a customizable list of light attributes to display in the panel. You can add and remove light attributes to fit the needs of your workflow by exposing the most important light information and the options you need most frequently for editing.





The light attributes available to choose from to add to the Light Mixer panel.



Adding and Removing Light Attributes

The attributes columns list Light attributes for quick access without the need to go back and forth between the Details panel and Light Mixer panel.

You can add and remove light attributes by moving the mouse over any Column header and clicking the Overflow Menu icon (it looks like three vertical dots), which opens a list of user-editable Light attributes. You can perform these actions in the attributes list:

Add a column for the selected attribute by enabling the checkbox next to the Light attribute.

Remove a column for the selected attribute by disabling the checkbox next to a Light attribute that has an enabled checkbox.

Search for a particular attribute by starting to type when the attribute list is open. A search filter will replace the menu and then only display results that match your search terms.

Currently, when you add any attribute columns to the Light Mixer panel, columns are added in the order in which they appear in the list. Column placement will be configurable in a future release.

Lights as Components

The Light Mixer lists and displays Lights that are components of other Actors and Blueprints in the scene. You can edit the Lights contained within these other Actors and Blueprints like any other light in the scene, but you can't move or reparent them within the Light Mixer panel.

Lights Contained Inside Other Actors

You can add Lights to scene Actors as components using Level's Details panel. These Lights will be listed as components in the Light Mixer Panel, along with their parent Actor.



This is an Actor in the scene that has two Point Lights as components.



The Light Mixer recognizes that this Actor has two Lights as components and lists them in the Light Mixer panel, along with the Actor they are components of.



If the Actor only has a single Light as a component, it collapses into a single editable line.



Lights Contained Inside Blueprints

Lights contained within a Blueprint Actor as a component are listed in the Light Mixer. You can also click the Blueprint to open it for editing directly in the Blueprint Editor.



This is a Blueprint that has two Point Lights as child components of a Static Mesh component.



When this Blueprint is added to a Level, the Light Mixer recognizes that it contains Lights as components and lists them in the Light Mixer panel.



If the Blueprint only contains a single Light, it collapses into a single editable line.



This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Enabling the Sky Atmosphere Component

Sky Atmosphere Model

Sky Rendering Options

Rendering the Sky using a Skydome Mesh

Planetary Atmospheres Viewed from Space

Atmosphere Sunlight Shafts and Quality

Visualization and Debugging

Supported Platforms

Additional Notes

The Sky Atmosphere component in Unreal Engine is a physically-based sky and atmosphere-rendering technique. It's flexible enough to create an Earth-like atmosphere with time-of-day featuring sunrise and sunset, or to create extraterrestrial atmospheres of an exotic nature. It also provides an aerial perspective to which you can simulate transitions from ground to sky to outer space with proper planetary curvature.



The Sky Atmosphere gives an approximation of light scattering through a planetary atmosphere's participating media, giving outdoor levels a more realistic or exotic look by including the following:

You can have two atmospheric Directional Lights that receive sun disk representation in the atmosphere with sky color that depends on the sunlight and atmosphere properties.

A sky color that will vary, depending on the altitude of the sun, or in other terms, how close the dominant Directional Light's vector gets to being parallel with the ground.

Control over scattering and fuzzy settings, allowing for full control of your atmospheric density.

Aerial perspective that simulates the curvature of the world when transitioning from ground to sky to space views.

Enabling the Sky Atmosphere Component

Enable the Sky Atmosphere component by following these steps using the Place Actors panel in the Level Editor:

Place a Sky Atmosphere component in the scene.



Place a Directional Light in the scene.



From its Details panel, enable Atmosphere Sun Light.

If using multiple Directional Lights, set the Atmosphere Sun Light Index for each; for instance, 0 for the Sun and 1 for the Moon.

Place a Sky Light in the scene to capture Sky Atmosphere and have it contribute to the scene lighting.



Adjusting Atmospheric Directional Lights

When you've enabled Atmosphere Sun Light on your Directional Light(s) and set the Atmosphere Sun Light Index for each, you can quickly adjust each light's position using the following keyboard shortcuts:

Right Ctrl + L with mouse movement will adjust the Directional Light set to index 0. Typically this would be the Sun.

Right Ctrl + L + Shift with mouse movement will adjust the Directional Light set to index 1. Typically this would be the Moon.

Moving these light sources will affect the atmosphere based on properties set in the Sky Atmosphere component for each Directional Light.

Sky Atmosphere Model

Simulating the sky and atmosphere requires several properties that mimic the look and feel of a real-world atmosphere. These properties can be used to define the look of the sky and atmosphere by scattering light in an appropriate and accurate manner. By default, the Sky Atmosphere component represents the Earth.

For an Earth-like planet, the atmosphere is made up of multiple layers of gasses. They themselves are made up of particles and molecules that have their own shape, size and density. When photons (or light energy) enter the atmosphere and collide with the particles and molecules there, they are either scattered (reflected) or absorbed (see below).



(1) Incident Light from the Sun; (2) Particles in the Atmosphere; (3) Redirected Light Energy.

The Sky Atmosphere system simulates absorption with Mie scattering and Rayleigh scattering. These scattering effects enable the sky to appropriately change colors during time-of-day transitions by simulating how the incident light interacts with particles and molecules in the atmosphere.

The sky color changes depending on the time-of-day simulation when using the Sky Atmosphere component.

Rayleigh Scattering

The interaction of light with smaller particles (such as air molecules) results in Rayleigh scattering. This type of scattering is highly dependent on the light wavelength. For instance, in the Earth's sky, blue scatters more than other colors, giving the sky its blue color during the daytime. However, at sunset, it appears red because light rays need to travel further in the atmosphere. After long distances, all blue light is scattered away before other colors, resulting in colorful sunsets full of yellow, orange, and red colors.



(1) Incident light; (2) Small particles in the atmosphere; (3) Rayleigh scattered light energy.

In an Earth-like atmosphere, when sunlight interacts with small particles (1) in the atmosphere (2), Rayleigh scattering happens throughout the atmosphere. The upper atmosphere is less dense compared to the lower atmosphere near the Earth's surface (3).



Increasing or decreasing the density of particles in the atmosphere causes light to scatter more or less.

Drag the slider to see the effects of decreasing and increasing the Rayleigh Scattering Scale. (Left to right, 1–3)



Decreased scattering causes light to scatter less through the atmosphere. This is 10x less dense than Earth's atmosphere.

This is representative of an Earth-like atmospheric density.

Increased scattering allows light to scatter more through the atmosphere. This is 10x more dense than Earth's atmosphere.

Mie Scattering

The interaction of light with larger particles—such as those from dust, pollen, or air pollution—suspended in the atmosphere results in Mie scattering. These particles are referred to as aerosols and can be caused naturally or by human activity. Incident light that follows the Mie scattering theory usually absorbs light, causing the clarity of the sky to appear hazy by occluding light. Light also usually scatters more forward, resulting in bright halos around the light's source, such as around the sun disk in the sky.



(1) Incident light; (2) Large particles in the atmosphere; (3) Mie-scattered light energy.

Increasing or decreasing the aerosol density causes more or less clarity in the sky, contributing to how hazy it looks.

Drag the slider to see the effects of decreasing and increasing the Mie Scattering Scale. (Left to right, 1–3)



Decreased particle density allows the sky to appear more clearly. It has less haze and light is scattered less directionally.

Default Mie scattering scale.

Increased particle density causes the sky to become occluded. It also causes the sky to appear hazy with the strong forward scattering lob around the incident light direction.

Mie Phase

The Mie Phase controls how uniformly light scatters when interacting with larger aerosol particles in the atmosphere. With Mie scattering, light usually scatters more forward, resulting in bright halos around the light's source, such as around the sun disk in the sky.



(1) Incident Light; (2) Larger particles in the atmosphere; (3) Stronger Mie-scattered light energy.

Use the Mie Anisotropy property to control how uniformly Mie scattering happens across the atmosphere.

Drag the slider to see the effects of decreasing and increasing the Mie Anisotropy of the atmosphere. (Left to right, 1–3)



Decreasing the Mie Anisotropy scatters light more uniformly across the atmosphere. This example is using a value of 0.

Default settings mimic an Earth-like atmosphere. This example is using a value of 0.8.

Increasing the Mie Anisotropy scatters light more directionally causing it to tighten around the light source. This example is using a value of 0.9.

Atmospheric Absorption

The amount and colors absorbed are controlled using the Absorption Scale and Absorption color picker properties. The examples below demonstrate removing a single RGB color through the increased Absorption Scale.

Drag the slider to see the effects of decreasing and increasing the Absorption Scale of the atmosphere. (Left to right, 1-3)



No atmospheric absorption.

Default Earth Ozone absorption scale.

Increased Ozone absorption scale.

The amount and colors absorbed are controlled using the Absorption Scale and Absorption color picker properties. The examples below demonstrate removal of a single RGB color through an atmosphere with increased absorption.







Green Absorbed

Red Absorbed

Blue Absorbed

Absorption of some colors may not be as noticeable during different times of day due to the way light scatters through the atmosphere.

Altitude Distribution

The Sky Atmosphere component enables you to control the atmosphere from not only a ground perspective but also from an aerial and space one. This means that you can effectively define the curvature of your world so that transitioning from ground to sky to space feels and looks like a real-world atmosphere.

Use the following properties to achieve this use:

Ground Radius to define the planet's size.

Atmospheric Height to define the height of the atmosphere above which we stop evaluating light interactions with the atmosphere.

Rayleigh Exponential Distribution to define the altitude (in kilometers) at which Rayleigh scattering effect is reduced to 40% due to reduced density.

Mie Exponential Distribution to define the altitude (in kilometers) at which Mie scattering effect is reduced to 40% due to reduced density.

Drag the slider to see the effects of decreasing and increasing Rayleigh height of the atmosphere. (Left to right, 1–3)



Rayleigh Atmosphere Height is 0.8 kilometers.

Default Rayleigh Atmosphere Height of 8 kilometers.

Rayleigh Atmosphere Height is 80 kilometers.

Artistic Direction

Additionally, the Sky Atmosphere component supports artistic control when designing the look of your project.

The Aerial Perspective View Distance Scale property scales distances from the view to surfaces to make them look thicker when viewed from a high enough distance above the ground surface.

Drag the slider to change the Aerial Perspective View Distance Scale property. (Left to right, 1-3)



Some atmospheric properties were set up for this scene.

The same scene with the Aerial Perspective View Distance Scale increased slightly.

The same scene with Aerial Perspective View Distance Scale doubled.

Mie scattering is a component of the atmosphere and is a height fog simulation in itself, meaning you can already use it to create height fog in your scene without using the Exponential Height Fog component (see below).





Height fog produced from the Sky Atmosphere component without Exponential Height Fog component.

Should your project require Exponential Height Fog, it can be enabled in the Project Settings under the Rendering category by setting Support Sky Atmosphere Affecting Height Fog. Contribution from height fog is additive; it applies sky atmosphere height fog on top of the existing faked colors provided by the Exponential Height Fog component. To have Sky Atmosphere component affect and influence Exponential Height Fog, you'll need to set Fog Inscattering Color and Directional Inscattering Color to Black using their respective color pickers.



With these set, you can use the Sky Atmosphere's Height Fog Contribution setting under the Art Direction category to apply artistic control over how much light coming through the atmosphere affects the height fog. Below is an example of height fog contribution being adjusted.

Drag the slider to see the height fog contribution increase and decrease its contribution to the Sky Atmosphere component. (Left to right, 1-3)



Default height fog contribution from the Sky Atmosphere component.

Half height fog contribution (0.5) from the Sky Atmosphere component.

Double height fog contribution (2.0) from the Sky Atmosphere Component.

Sky Rendering Options

The sky and aerial perspective is rendered on screen using ray marching. However, doing so for each pixel can be expensive, especially with today's standard pushing towards 4K or 8K resolution. That is why the sky is evaluated in a few lookup tables (LUTs) at low resolution. Those LUTs are:

By default, all of these LUTs are all evaluated, but using the examples below you can determine the needs for your own projects.

Type of LUT Used

Description

FastSkyViewLUT

Stores a latitude/longitude texture of the ray ray marched sky luminance around a point of view. It is applied on the sky pixels only.

AerialPerspectiveLUT

Stores the transmittance and scattered luminance into froxel (camera frustum voxel). This is used to apply aerial perspective on opaque and transparent meshes**.

MultipleScatteringLUT

During ray marching, used to evaluate the multiple scattering contributions.

TransmittanceLUT

During ray marching, used to evaluate the remaining illuminance from the sun light for any position within the atmosphere and on the planet.

DistanceSkyLightLUT

Stores non-occluded luminance after a scatter event with a uniform phase function.

Many of these settings allow you to control the LUT's performance and visual quality for your project. For additional details about them, see the Sky Atmosphere Properties page.

Rendering the Sky using a Skydome Mesh

For some projects, you will want to position the skydome mesh around the world, enabling artists to control the way the sky is composited with clouds, stars, sun and any other celestial bodies.

To set up a skydome mesh to work with the Sky Atmosphere component, you'll need to set the following in its Material:

Blend Mode: Opaque

Shading Model: Unlit

The sky material is rendered as the last opaque mesh during the base pass, meaning that aerial perspective will not be applied on it to avoid double contribution. However, height fog and volumetric fog will continue to be applied, if used.

In this material, you will have the freedom to compose the sky, sun disk, clouds and aerial perspective. Also, you will have to compute lighting on the clouds and other elements in the sky. Several Material Expressions can be used to achieve this in your materials. You can find them by searching the term "SkyAtmosphere" in the Material Editor.

When creating your own sky material, which has customized clouds, planets, sun, or other object, you should enable the Is Sky flag in the Material advanced properties. However, keep in mind that it disables contribution from aerial perspective (atmospheric fog) of the Sky Atmosphere component, but does apply height and volumetric fog to the scene from the Exponential Height Fog component.

For additional information about these Material Expressions, see the Sky Atmosphere Properties page.

The shape of the skydome mesh is important when using some of these expressions since they will drive evaluation of those values. For example, if you use the functions to evaluate lighting on clouds, you can assume the skydome pixel world position represents the cloud world position in the atmosphere.

Time of Day Example Level

A working example template map demonstrating a skydome mesh with a material using the Sky Atmosphere Material Expressions is available within Unreal Engine.



This Level is located in the Engine Content folder under Engine/Content/Maps/Templates, or you can use the main menu to create a new level and select the TimeOfDay_Default Level.

Planetary Atmospheres Viewed from Space

In addition to creating beautiful atmospheres from a planet's surface, the Sky Atmosphere system is capable of creating a planetary atmosphere viewed from space. Without any special setup, you can even move seamlessly from the planet's surface through the atmosphere to outer space.

This video uses assets and materials that are not part of the Sky Atsmosphere system, such as the star field and meshes that represent the planet surface.

The following properties are useful when setting up a planet to be viewed from outer space (or even just a very high altitude):

Ground Radius define the size of your planet (measured in kilometers).

Atmosphere Height defines the height of the atmosphere above the planet's surface (measured in kilometers).

Rayleigh Exponential Distribution defines the altitude at which the Rayleigh effect is reduced to 40%.

Below are some examples using demonstrating different planetary atmospheres using variations of these three properties:











Ground Radius: 6360 km

Ground Radius: 300 km

Ground Radius: 300 km

Ground Radius: 300 km

Ground Radius: 300 km

Atmosphere Height: 100 km

Atmosphere Height: 100km

Atmosphere Height: 100 km

Atmosphere Height: 100 km

Atmosphere Height: 300kn

Rayleigh Distribution: 8 km

Rayleigh Distribution: 8 km

Rayleigh Distribution: 2 km

Rayleigh Distribution: 32 km

Rayleigh Distribution: 32 km

Click images for full size.

Moving the Atmosphere

The Sky Atmosphere component is freely movable within Level using the selectable Transform Mode. Choose from the following options:

Planet Top at Absolute World Position places the top ground level of the atmosphere at the world origin coordinates (0,0,0) in the scene. The Sky Atmosphere is not movable when this option is selected.

Planet Top at Component Transform places the top ground level of the atmosphere relative to the component's transform origin. Moving the transform of the Sky Atmosphere component, or one that it is a child of, moves the atmosphere within the level.

Planet Center at Component Transform places the atmosphere centered to the component's transform origin. Moving the transform of the Sky Atmosphere component, or one that it is a child of, moves the atmosphere within the level.

The Sky Atmosphere component can be parented to objects in the scene, such as a planet mesh.

Atmosphere Transmittance

Light transmittance through the atmosphere is optimized for ground-level views; a single transmittance is evaluated for the top of the planet, but for a planetary view, the transmittance should be evaluated per pixel for the atmosphere terminator to look correct. This also enables the atmosphere to cast shadows on nearby moons, or other celestial objects.





Per pixel transmittance also enables shadowing of objects in outer space, such as nearby moons and other celestial objects, according to properties set on the Sky Atmosphere component.





Enable per pixel transmittance on your Directional Light by ticking the checkbox for Per Pixel Atmosphere Transmittance.

Moving from Ground to Outer Space

The Sky Atmosphere system is optimized for scenes that are on ground level. However, there is nothing preventing you from traveling from the ground to a high aerial view, or even outer space. While the transition through the atmosphere should be seamless—without a noticeable transition—from the look-up tables (LUTs) to per pixel tracing, you may sometimes experience a hitch or when this happens.

This optimization can be disabled by setting the following console command values to 0:

r.SkyAtmosphere.FastSkyLUT

r.SkyAtmosphere.AerialPerspectiveLUT.FastApplyOnOpaque

Once disabled, it is worth noting that you may encounter the following issues. These are some suggestions to help you work around them for your project to find a balance that best fits your project.

A high-frequency pattern can become visible when it should be absorbed by temporal anti-aliasing (TAA). However, when moving the camera very fast, there is a camera cut that happens—restarting TAA—so it is visible in space views.

Due to the way samples count is based on distance, samples become visibly large (as circles) in the atmosphere. Visibility of the samples is a side-effect of the density of medium in the atmosphere being higher, and very concentrated, close to the ground, which is a typical ray marching issue. You can solve this in a couple of ways:

Trade performance for quality increase by increasing the number of samples with r.SkyAtmosphere.SampleCountMax or r.SkyAtmosphere.DistanceToCountMax.

Set up logic to adjust and tweak atmospheric properties when in outer space to have less particles near the ground, making them more uniform and height distributed.

Atmosphere Sunlight Shafts and Quality

Shadowing from a Directional Light source is used to create sunlight shafts within the atmosphere for ground-level and space views.

Ground view atmosphere sunlight shafts:





Space view atmosphere sunlight shafts:





Use the following properties to enable and control sunlight shafts:

Enable Cast Shadow on Atmosphere to cast shadows from opaque objects. Also, enable Cast Cloud Shadows to enable shadow casting from cloud materials when using the Volumetric Cloud system.

Set a high value for the Dynamic Shadow Distance. For instance, the examples below used a shadow distance of 100000000 units (or 1000 kilometers).

For outer space views, enable Per Pixel Atmosphere Transmittance to apply accurate planetary shadowing that also casts shadows on nearby celestial objects, such as a moon.

You can further improve the quality of sunlight shafts using the following:

The tracing quality of the atmosphere is scalable using the Sky Atmosphere component's Trace Sample Count Scale property. This property is important when generating LUTS, or when using per pixel tracing. The maximum number of samples is clamped but can be increased by using the console command r.SkyAtmosphere.SampleCountMax. Also, keep in mind that the number of samples only reach the specified kilometers set by r.SkyAtmosphere.DistanceToSamplesCountMax.

Improving the overall quality of sunlight shafts within the atmosphere is handled by increasing the r.SkyAtmosphere.FastSkyLUT.Width and r.SkyAtmosphere.FastSkyLUT.Height values. Quality can further be improved for fog on opaque and translucent surfaces by increasing the width of r.SkyAtmosphere.AerialPerspectiveLUT.Width.

To use the fast sky LUT commands, r.SkyAtmosphere.FastSkyLUT must not be disabled.

Use caution when increasing the Aerial Perspective LUT. It uses a 3D volume texture. Increasing its size can significantly increase memory usage.

Achieving cinematic quality of atmosphere rendering is done by disabling the Sky View and Aerial Perspective LUTs optimizations, which use a lower resolution to be performant. They can be disabled by setting r.SkyAtmosphere.FastSkyLUT and r.SkyAtmosphere.AerialPerspectiveLUT.FastApplyOnOpaque to 0. Atmosphere will become slower to render but produces fewer visual artefacts with high-frequency detail that appear in some areas, such as a planet's shadow or its scattering lobe. You'll also want to increase the tracing quality on the Sky Atmosphere component (see above).

Visualization and Debugging

The Sky Atmosphere visualization and debugging view enables you to see—in real time—the changes you make to the atmosphere settings.



The Hemisphere View shows a visual representation of your atmosphere, taking into account Rayleigh and Mie scattering along with Absorption.

The Time-of-Day Preview displays different times of day based on the settings that are applied to the Sky Atmosphere component.

The Graph View shows a representation of Rayleigh, Mie, and Absorption values within the Sky Atmosphere component's set Ground Level and Atmosphere Height.

Enable the Sky Atmosphere visualization to be drawn on screen using the command:

Supported Platforms

The Sky Atmosphere component supports the following platforms to provide a scalable atmosphere system:

Feature

Mobile

XB1 / PS4

XBX / PS5

Low-end / High-end PC

Sky Atmosphere

YES*

YES

YES

YES

* Requires a skydome mesh with a material that has Is Sky enabled.

Additional Notes

Setting up Physically-Based Sky Lighting

When the sun is at its zenith, it should be set to 120000 lux (or cd:sr*m^2) for an angular diameter of 0.545 degrees.

The total Lux on a white diffuse surface with a perpendicular sun at its zenith should be around 150000 Lux.

Sky contribution would be 20% of that total.

Disable Ambient Occlusion when measuring this value in the Engine using the luminance/illuminance meter that is available in the HDR (Eye Adaptation) Visualization tool (Show > Visualize).

Multiscattering in the Sky Atmosphere component should be equal to 1 and Earth Albedo is 0.4 (linear) by default.

When the moon is at its zenith, it should be set to 0.26 Lux for an angular diameter of 0.568 degrees.

Why does the ground/lower hemisphere appear dark?

When you are close to the ground, there isn't any fog, so you don't get the scattering effect nor any fog color. This means for the lower hemisphere of a virtual planet, it is black. To address this, try the following:

Populate the scene with a terrain or mesh to represent the planet surface.

Use an Exponential Height Fog component as a lower hemisphere color filler.

Place your terrain or mesh surface at a higher altitude.

Why does the second Directional Light source have a lower impact on the sky?

Currently, multi-scattering is not evaluated for the second light source.

Why are texels visible on the skydome?

Try increasing the resolution of the FastSkyViewLUT (r.SkyAtmosphere.FastSkyViewLUT.SampleCountMax) if texels appear on the sky. If texels appear on fogged elements, increase the resolution of the AerialPerspectiveCameraVolumeLUT (r.SkyAtmosphere.AerialPerspectiveLUT.DepthResolution).

Do atmospheric lights work when the camera is not close to the +Z North Pole of the planet?

As an optimization, sun light transmittance effect on surface lighting is only evaluated as if the camera is at the top of the planet (over +Z position). This will be improved in a future release based on feedback.

Can you render multiple planetary atmospheres on screen at once?

This is not currently supported with this version of the Sky Atmosphere system.

Noise, aliasing, and some rings of different colors are visible

When you have high-frequency elements or values that generate high spikes in the atmosphere close to the ground that are hard to catch, resolve this using one of two ways:

Increase the Sky Atmosphere sample count using r.SkyAtmosphere.SampleCountMax.

If you're using the FastSky LUT instead of per-pixel ray marching, use r.SkyAtmosphere.FastSkyLUT.SampleCountMax. Additional details can be found in the Sky Rendering Options section above.

Project Settings

Sky Atmosphere Properties

Sky Atmosphere Material Expressions

SkyAtmosphereViewLuminance

SkyAtmosphereAerialPerspective

SkyAtmosphereLightDirection

SkyAtmosphereLightIlluminance

SkyAtmosphereDistantLightScatteredLuminance

SkyAtmosphereLightDiskLuminance

Console Commands

This page includes reference information for the Sky Atmosphere system. It includes information about Project Settings, component properties, console commands and the SkyAtmosphere Material Expressions.

Project Settings

The following Project Settings are used to affect the Sky Atmosphere component in your project.



Property

Description





Support Sky Atmosphere

The Sky Atmosphere component requires extra samplers/textures in order to be bound to apply aerial perspective on transparent surfaces (and all surfaces on mobile via per-vertex evaluation).

Support Sky Atmosphere Affecting Height Fog

The Sky Atmosphere component can light up the height fog but it requires extra samplers/textures to be bound to apply aerial perspective on transparent surfaces (and all surfaces on mobile via per-vertex evaluation). It reuires that Support Sky Atmosphere be enabled.

Sky Atmosphere Properties

The following settings can be found on the Sky Atmosphere component in the Level Details panel.



Property

Description



Planet



Transform Mode

Choose how the Sky Atmosphere component's transform placement and movement in the level. Choose one of the following from the dropdown menu:

Planet Top at Absolute World Origin: Places the top ground level of the atmosphere at the world origin coordinates (0,0,0) in the scene. The Sky Atmosphere is not movable when this option is selected.

Planet Top at Component Transform: Places the top ground level of the atmosphere relative to the component's transform origin. Moving the transform of the Sky Atmosphere component, or one that it is a child of, moves the atmosphere within the level.

Planet Center at Component Transform: Places the atmosphere centered to the component's transform origin. Moving the transform of the Sky Atmosphere component, or one that it is a child of, moves the atmosphere within the level.

Ground Radius

The planet radius measured in kilometers from the center to the ground level.

Ground Albedo

The ground albedo that tints the atmosphere when the sun light bounces on it. This is only taken into account when MultiScattering is greater than 0.



Atmosphere



Atmosphere Height

The height of the atmosphere above the ground surface, measured in kilometers.

MultiScattering

Render multi-scattering as if sun light bounces around in the atmosphere. It is achieved using dual scattering approach.

Trace Sample Count Scale

The scale of the Atmosphere tracing sample count.



Atmosphere — Rayleigh



Rayleigh Scattering Scale

Rayleigh scattering coefficient angle.

Rayleigh Scattering

The Rayleigh scattering coeffecients resulting from molecules in the air at an altitude of 0 kilometers.

Rayleigh Exponential Distribution

The altitude in kilometers at which Rayleigh scattering effect is reduced to 40%.



Atmosphere — Mie



Mie Scattering Scale

Mie scattering coefficient scale.

Mie Scattering

The Mie scattering coefficients resulting from particles in the air at an altitude of 0 kilometers. Light is scattered more as it increases.

Mie Scattering Absorption

Mie absorption coefficient scale.

Mie Absorption

The Mie absorption coefficients resulting from particles in the air at an altitude of 0 kilometers. Light is absorbed more as it increases.

Mie Anisotropy

A value of 0 means light is uniformly scattered. A value closer to 1 means light will scatter more forward, resulting in halos around light sources.

Mie Exponential Distribution

The altitude in kilometers at which Mie effects are reduced to 40%.



Atmosphere — Absorption



Absorption Scale

Absorption coefficients for another atmosphere layer. Density increase from 0 to 1 between 10 to 25 kilometers and decreases from 1 to 0 between 25 to 40 kilometers. This approximates ozone molecule distribution in the Earth atmosphere.

Absorption

Absorption coefficients for another atmosphere layer. Density increases from 0 to 1 between 10 to 25 kilometers and decreases from 1 to 0 between 25 to 40 kilometers. The default values represent ozone molecules absorption in the Earth atmosphere.

Tent

Represents the altitude-based tent distribution of absorption particles in the atmosphere.

Tip Altitude: The altitude at which the tent function reaches its peak.

Tip Value: The density at the tent tip altitude.

Width: The width, or variation of altitude, over which the tent function linearly decreases to reach 0.



Art Direction



Sky Luminance Factor

Scales the luminance of pixels representing the sky. For example, not belonging to any surface.

Aerial Perspective Distance Scale

Makes the aerial perspective look thicker by scaling distances from view to surfaces (opaque and translucent).

Height Fog Contribution

Scale the sky and atmosphere lights contribution to the height fog when Support Sky Atmosphere Affects Height Fog is enabled in the Project Settings.

Transmittance Min Light Elevation Angle

The minimum elevation angle in degrees that should be used to evaluate the sun transmittance to the ground. Useful to maintain a visible sun light and show on meshes even when the sun has started going below the horizon. This does not affect the aerial perspective.

Aerial Perspective Start Depth

The distance in kilometers at which to start evaluating the aerial perspective. By default is set to 100 meters.

Sky Atmosphere Material Expressions

The following Material Expressions are used when creating a sky material where you want to compose the sky, sun disk, clouds, and aerial perspective. Computing the lighting on the clouds and other elements in the sky is assisted with these expressions.

To explore a working example using these expressions within a material that are applied to a skydome mesh, see the TimeOfDay_default map found in the Engine/Content/Maps/Templates folder.



Click image for full size.

Also, for additional details, see the "Rendering a Skydome Mesh" section of the Sky Atmosphere page.

The shape of the skydome mesh is important when using some of these expressions since they will drive evaluation of those values. For example, if you use the functions to evaluate lighting on clouds, you can assume the skydome pixel world position represents the cloud world position in the atmosphere.

SkyAtmosphereViewLuminance

Th SkyAtmosphereViewLuminance expression outputs the sky luminance resulting from the interaction with atmospheric lights in the atmosphere.



SkyAtmosphereAerialPerspective

The SkyAtmosphereAerialPerspective expression outputs RGBA-colored in-scattered luminance in RGB and grayscale transmittance over the skydome world position in A.



The shape of the skydome mesh is important because it drives the evaluation of these values. For instance, if you use these functions to evaluate the lighting on clouds, you can assume that the skydome pixel world position represents the cloud world position in the atmosphere. However, there is an override to provide the sampled position.

SkyAtmosphereLightDirection

The SkyAtmosphereLightDirection expression takes in the Atmospheric Light Index for a Directional Light and outputs the light direction from the light.



In the Details panel, set the Light Index for the Directional Light being referenced. This should match the Directional Light's Atmosphere Sun Light Index property.

SkyAtmosphereLightIlluminance

The SkyAtmosphereLightIlluminance expression takes in the Atmospheric Light Index for a Directional Light and outputs illuminance reaching the skydome world position (see note below). This is illuminance, so it needs to be integrated against a BxD/phase function to get luminance to accumulate. A multiplication with a uniform phase function of 1/(4π) is a good starting point.



In the Details panel, set the Light Index for the Directional Light being referenced. This should match the Directional Light's Atmosphere Sun Light Index property.

The shape of the skydome mesh is important because it drives the evaluation of these values. For instance, if you use these functions to evaluate the lighting on clouds, you can assume that the skydome pixel world position represents the cloud world position in the atmosphere. However, there is an override to provide the sampled position.

SkyAtmosphereDistantLightScatteredLuminance

The SkyAtmosphereDistanceLightScatteredLuminance expression outputs the sky scattered luminance integrated over the unit sphere, assuming a uniform phase function. The sample is taken at the specified altitude of the DistanceSkyLight LUT (r.SkyAtmosphere.DistanceSkyLightLUT.Altitude).



SkyAtmosphereLightDiskLuminance

The SkyAtmosphereLightDiskLuminance expression takes in the Atmospheric Light index for a Directional Light and outputs the light sun disk luminance with atmosphere transmittance applied.



In the Details panel, set the Light Index for the Directional Light being referenced. This should match the Directional Light's Atmosphere Sun Light Index property.

Console Commands

The following console commands enable you to control the performance and visual quality of your atmosphere.

For additional details, see the "Sky Rendering Options" section of the Sky Atmosphere page.

Console Variable

Description



System



r.SkyAtmosphere

Sky Atmosphere components are rendered when this is not 0, otherwise ignored.

r.SupportSkyAtmosphere

Enables Sky Atmosphere rendering and shader code.

r.SupportSkyAtmosphereAffectsHeightFog

Enables Sky Atmosphere affecting height fog. It requires r.SupportSkyAtmosphere to be true.

r.SkyAtmosphere.LUT32

Uses the full 32-bit per-channel precision for all sky look-up tables (LUT).

r.SkyAtmosphere.EditorNotifications

Enables the rendering of in-editor notification to warn the user about missing sky dome pixels on screen. It is better to keep it enabled and will be removed when shipping.

r.SkyAtmosphereASyncCompute

SkyAtmosphere on async compute. Default is false.



Fast Sky View LUT



r.SkyAtmosphere.FastSkyLUT

When enabled, a lookup texture is used to render the sky. It is faster, but can result in visual artifacts if there are some high-frequency details in the sky such as Earth shadow or scattering lob.

r.SkyAtmosphere.FastSkyLUT.SampleCountMin

Fast sky minimum sample count used to compute sky/atmosphere scattering and transmittance. The minimal value is clamped to 1.

r.SkyAtmosphere.FastSkyLUT.SampleCountMax

Fast sky maximum sample count used to compute sky/atmosphere scattering and transmittance. The minimal value is clamped to r.SkyAtmosphere.FastSkyLUT.SampleCountMin +1.

r.SkyAtmosphere.FastSkyLUT.DistanceToSampleCountMax

Fast sky distance in kilometers after which at which SampleCountMax samples is used to ray march the atmosphere.

r.SkyAtmosphere.FastSkyLUT.Width

The width of the FastSky LUT.

r.SkyAtmosphere.FastSkyLUT.Height

The height of the FastSky LUT.



Aerial Perspective



r.SkyAtmosphere.AerialPerspective.StartDepth

The distance at which we start evaluate the aerial perspective. Default is set to 100 meters.

r.SkyAtmosphere.AerialPerspective.DepthTest

When enabled, a depth test is used to not write pixel closer to the camera than StartDepth, effectively improving performance.



Aerial Perspective LUT



r.SkyAtmosphere.AerialPerspectiveLUT.DepthResolution

The number of depth slices to use for the aerial perspective volume texture.

r.SkyAtmosphere.AerialPerspectiveLUT.Depth

The length of the LUT in kilometers (default is 96 kilometers to get nice cloud/atmosphere interactions in the distance for the default sky). Further than this distance, the last slice is used.

r.SkyAtmosphere.AerialPerspectiveLUT.SampleCountPerSlice

The sample count used per slice to evaluate aerial perspective scattering and transmittance in camera frustum space froxel.

r.SkyAtmosphere.AerialPerspectiveLUT.SampleCountMaxPerSlice

The sample count used per slice to evaluate aerial perspective. The effective sample count is usually lower and depends on SampleCountScale on the component as well as .ini files, scattering and transmittance in camera frustum space froxel.

r.SkyAtmosphere.AerialPersepctiveLUT.Width

The width and height on screen of the AerialPerspective LUT.

r.SkyAtmosphere.AerialPerspectiveLUT.FastApplyOnOpaque

When enabled, the low resolution camera frustom/froxel volume containing the atmospheric fog, which is usually used for fog on translucent, is used to render fog on opaque. It is faster but can result in visual artefacts if there are some high frequency details, such as earth shadow or scattering lob.



Raymarching Sky



r.SkyAtmosphere.SampleCountMin

The minimum sample count used to compute sky/atmosphere scattering and transmittance. The minimal value will be clamped to 1.

r.SkyAtmosphere.SampleCountMax

The maximum sample count used to compute sky/atmosphere scattering and transmittance. The minimal value will be clamped to r.SkyAtmosphere.SampleCountMin +1.

r.SkyAtmosphere.SampleLightShadowmap

Enables the sampling of atmospheric lights shadow map in order to produce volumetric shadows.

r.SkyAtmosphere.DistanceToSampleCountMax

The distance in kilometers after which at which SampleCountMax samples is used to ray march the atmosphere.



Transmittance LUT



r.SkyAtmosphere.TransmittanceLUT

Enables the generation of the sky transmittance.

r.SkyAtmosphere.TransmittanceLUT.SampleCount

The sample count used to evaluate transmittance.

r.SkyAtmosphere.TransmittanceLUT.UseSmallFormat

If true, the transmittance LUT uses a small R8BG8B8A8 format to store data at lower quality.

r.SkyAtmosphere.TransmittanceLUT.LightPerPixelTransmittance

Enables Sky Atmosphere light per pixel transmittance, but only for opaque objects in the deferred renderer. It is more expensive but space/planetary views will be more accurate with it enabled.

r.SkyAtmosphere.TransmittanceLUT.Width

The width of the Transmittance LUT.

r.SkyAtmosphere.TransmittanceLUT.Height

The height of the Transmittance LUT.



Multi-Scattering LUT



r.SkyAtmosphere.MultiScatteringLUT.SampleCount

The sample count used to evaluate multi-scattering.

r.SkyAtmosphere.MultiScatteringLUT.HighQuality

When enabled, 64 samples are used instead of 2, resulting in a more accurate multi-scattering approximation (but also a bit more expensive.)

r.SkyAtmosphere.MultiScatteringLUT.Width

The width of the MultiScattering LUT.

r.SkyAtmosphere.MultiScatteringLUT.Height

The height of the MultiScattering LUT.



Distance Sky Light LUT



r.SkyAtmosphere.DistantSkyLightLUT

Enable the generation of the sky ambient lighting value.

r.SkyAtmosphere.DistantSkyLightLUT.Altitude

The altitude at which the sky samples are taken to integrate the sky lighting. Defaults to 6 kilometers, typicall cirrus clouds altitude.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

How are clouds rendered?

Ray Marching the Cloud Volume

Light Multiple Scattering

Cloud Occlusion and Shadowing

Setting Up and Using Volumetric Clouds

Initial Level Setup

Sky Light Cloud Reflections Quality

Ray Marching Quality Modes

Achieving Cinematic Quality

Volumetric Material

Volumetrics Plugin Content

Example Cloud Materials

Blueprint Placed Clouds

Blueprint Painted Clouds

Performance and Scalability

Supported Platforms

Controlling Cloud Tracing Quality

Optimizing your Volume Cloud Material

Budgeting with the Sky Light Real Time Capture Mode

Conservative Density Evaluation

Ray Tracing and Volumetric Clouds

The Volumetric Cloud component is a physically-based cloud rendering system that uses a material-driven approach to give artists and designers the freedom to create any type of clouds they need for their projects. The cloud system handles dynamic time-of-day setups that is complemented by the Sky Atmosphere and Sky Light using the real time capture mode. The system provides scalable, artist-defined clouds that can adapt to projects using ground views, flying, and ground to outer space transitions.



How are clouds rendered?

Previously, rendering clouds in real-time for games and cinematics have primarily been achieved through static materials applied to a sky dome mesh or a similar approach. Now, the volumetric cloud system uses a three-dimensional volume texture that is ray-marched to represent cloud layers in real-time. The material-driven approach provides the most flexibility for artists and designers to create clouds that can move across the sky, of any type, and can handle different times of day.

The sections that follow explore and break down the cloud system's elements that contribute to rendering them for real-time rendering.

Ray Marching the Cloud Volume

The participating media that makes up clouds require complex lighting simulations that either aren't possible, or are too expensive, for real time simulation on consumer-grade hardware. The Volumetric Cloud system employs ray- marching and approximation to simulate cloud rendering for scalable real-time performance across many supported platforms and devices. This makes it possible to support real time time-of-day simulations that support the multiple light scattering effect of lighting, shadowing from clouds and onto clouds, light contribution from the ground onto the bottom layer of clouds, and much more.

Light Multiple Scattering

Light rays that travel through a volume have the potential to scatter on particles within the volume before reaching your eye, or a camera sensor. This effect of light is called multiple scattering, and it is what defines the distinct appearance of clouds. In a cloud, the droplets that make up the cloud usually lead to an albedo that is close to a value of 1, meaning that light is almost never absorbed within the volume. Light that is not absorbed passes through the volume making the scattering effect very complex in the process. The multiple scattering effect of the participating media affects light travel through the cloud volume; it's what makes them look bright while also appearing very thick.

The complexity of multiple scattering in real-time rendering is solved by using an approximation of realistic scattering by tracing multiple octaves (or steps) of light transmittance in the volume material. The Volumetric Advanced Material Output expression enables you to set the number of octaves used along with the amount of multiple scattering contribution, occlusion, and eccentricity that happens.

The example below shows the difference between no octaves used (single scattering), one octave, and two octaves of multiple scattering approximation. High octaves apply additional scattering approximations to your cloud material but make the shader more expensive in the process.

For games projects, it is recommended to only use a single octave of light multiple scattering for performance considerations. However, you can use high Contribution and low Occlusion values on the Volumetric Advanced Material expression in your cloud material to similar effect without impact to performance. See the Volumetric Material section below.

Ground View:

Drag the slider to change the number of Multiple Scattering Approximation Octaves used from 0 - 2.







Higher Altitude View:

Drag the slider to change the number of Multiple Scattering Approximation Octaves used from 0 - 2.







Cloud Occlusion and Shadowing

An important aspect of clouds is due to how they occlude light and cast shadow on surfaces. Cloud occlusion and shadowing is primarily handled by atmosphere lights and the volume material used to represent the cloud. These components enable you to control different aspects that define the look of your clouds, such as having sunlight shafts, or cloud self shadowing.

There are two modes for cloud shadowing available which can be toggled in the cloud material used; the default Ray Marched and Beer Shadow Maps (BSM).





Ray marching the volume shadow uses secondary ray marching to get sharp, colored shadows but is limited in distance that shadows can be traced due to the limited number of samples that can be used. Ray-marched shadows are good for ground to sky to space transitions even though they are more expensive.

Beer shadow maps use cascaded shadow maps to support far shadow distances for clouds and casting shadows on the ground. They are also faster to render, but are less accurate and lack volumetric self shadow color. Beer shadow maps are usually enough for clouds viewed from the ground.

For console platforms, such as Xbox One and PlayStation 4 or other systems using similar specifications, Beer shadow maps are recommended for cloud shadowing.

Toggle between these modes inside of your cloud volume material by adding a Volumetric Advanced Material Output expression to your material graph. With the node selected, toggle the Ray March Volume Shadow checkbox from the Details panel to switch between two types of shadowing.



Atmosphere lights, such as ones for the sun and moon, provide control for cloud and atmospheric shadowing. With them, you can control the strength of shadows, the distance that cloud shadowing happens from the current camera position (in kilometers), and whether clouds can self-shadow and cast shadows into the atmosphere, to name a few.



Enabling Cast Cloud Shadows on an atmospheric light allows for the cloud volume to shadow scene elements and to cast sunlight shafts (also called God Rays) within the atmosphere, whereby sunlight shafts are defined by the Sky Atmosphere component.





The Cloud Shadow Map Resolution Scale drives the resolution and performance cost of the sunlight shafts. Reducing the radius of the cloud shadow map around the camera with the Cloud Shadow Extent property can help focus the shadow map resolution for sharper, better results.

Casting shadows onto the atmosphere and clouds from opaque objects is enabled with Cast Shadows on Atmosphere and Cast Shadows on Clouds. Shadowing for large objects is achieved using a large enough Dynamic Shadow Distance or using Far Shadow Distance on the Directional Light to shadow objects that enable the Far Shadow flag in their details.



Simulating light multiple scattering within participating media using the octave approximation can result in some energy being lost. The atmosphere light property Cloud Scattering Luminance Scale provides a nice counterbalance that enables you to scale the light contribution using a color picker, making it possible to have more interesting and natural light scattering without the added expense.



These are some examples with different Cloud Scattering Luminance Scales.

Click image for full size.

The Sky Light component provides a Real Time Capture mode that handles interactions with atmosphere, clouds, height fog, and opaque meshes using an Unlit material that is tagged Is Sky. This mode makes it possible to create natural-looking and dynamic time-of-day simulations without sacrificing performance.

Learn more about the Real Time Capture mode and other optimizations in the Sky Light page.

Soft ambient shadowing is an important part of defining the natural look of clouds. The Sky Light component uses the Cloud Ambient Occlusion properties to control how much light clouds can block coming from contribution of the sky and atmosphere lights. These properties can be found under the Atmosphere and Cloud section in the Details panel of the Sky Light.

The comparison below shows ambient occlusion enabled with increased strength, which controls how much light contribution sky and atmosphere lights have by progressively reducing the amount of light multiple scattering that happens.





Skylight AO contribution on the atmosphere and clouds can be described as:

Shadow Tracing Costs:

When using secondary marching per sample, the cost is driven by values setup on the Volumetric Cloud component with Shadow View Sample Count Scale.

When the cloud samples the Directional Light Beer Shadow Map (which is also used to cast shadow on meshes), then a single evaluation of the shadow map is done at each ray marched position. The Beer Shadow Map generation is driven by information coming from the setup on the Directional Light component with Cloud Shadow Ray Sample Count Scale.

Setting Up and Using Volumetric Clouds

The volumetric clouds system is a core part of the available atmospheric components that make up the sky and planet's atmosphere. The following sections will help you get started in setting up and using these components together with the cloud system.

Initial Level Setup

Create a new level (or use an existing one) that contains the following components:

A Directional Light with Atmosphere Sun Light enabled to represent the sun or moon.

A Sky Atmosphere component to represent the planet's atmosphere.

A Sky Light with Real Time Capture optionally enabled if you want to have dynamic time-of-day simulation.

A Volumetric Cloud component with a volume material assigned to represent the clouds in the sky.

Simplify creation and editing of atmospheric components within your level by using the Environment Light Mixer. It provides relevant settings for each component within a single panel.

For more information, see Environment Light Mixer.

Sky Light Cloud Reflections Quality

The Sky Light component provides scene reflections for volumetric clouds. The Volumetric Cloud component enables you to control the number of samples used to ray march reflection surfaces in the scene from the Details panel under the Cloud Tracing section. You can scale the number of samples used for reflections of clouds and for the shadowed reflections of clouds.

Drag the slider to see progressive increase of samples used when tracing the cloud's reflection ray sample counts: 0.25, 0.5, 0.75, 1 (Default), 2, 4, and 8.















The properties Reflection Sample Count Scale and Shadow Reflection Sample Count Scale are clamped. The following commands can be used to increase scale and sample counts:

r.VolumetricCloud.ReflectionRaySampleMaxCount

r.VolumetricCloud.Shadow.ReflectionRaySampleMaxCount

r.VolumetricCloud.ViewRaySampleMaxCount

r.VolumetricCloud.SampleMinCount

r.VolumetricCloud.DistanceToSampleMaxCount

See Sky Light for more information on its real time capture mode and reflection quality properties.

Ray Marching Quality Modes

The cloud system provides scalable quality modes that fit many gameplay types from standard to fast-paced gameplay that requires ground-to-space movement. It also supports cinematic quality for projects that are less concerned with running in real time.

The quality modes are defined by the command r.VolumetricRenderTarget:

Reactive modes supporting cloud intersections with opaque surfaces but with traces completed at a lower resolution: r.VolumetricRenderTarget.Mode 0 is the recommended option for quality. It supports fast-paced gameplay that may have ground-to-space transitions, or flying through clouds. Clouds are fast to trace but can appear to have low resolution. Traces happen at quarter resolution, reconstruction at half resolution, and upsample on screen at full resolution.

r.VolumetricRenderTarget.Mode 1 balances quality with performance to fit a lot of types of gameplay that are good for ground views. This mode is more expensive but looks higher quality. Traces happen at half resolution, reconstruction and upsample on screen at full resolution.

A less reactive mode but looks full resolution:

r.VolumetricRenderTarget.Mode 2 focuses on higher quality while still supporting ground views for real-time gameplay. This mode is fast to trace and looks high resolution, but it does not support cloud intersection with opaque meshes.

Cinematic mode is achieved by starting with r.VolumetricRenderTarget 0 and following the suggestions in the Achieving Cinematic Quality workflow (see below).

Quality can further be improved, or lowered, for the platforms you're intending to deploy to through console commands following r.SkyAtmosphere. and r.VolumetricClouds.. Also, user-facing properties can be found in the Volume Material, and on the Volumetric Cloud and Directional Light components.

Achieving Cinematic Quality

This is an advanced workflow that bypasses optimizations used by the engine for real time rendering of clouds and sky and can significantly impact performance.

Achieving cinematic (or per pixel) quality for the Sky Atmosphere and Volumetric Clouds components is handled through some commands, setting attributes in your cloud material, and by increasing the number of samples used to trace the atmosphere and cloud volume.





The steps below are the primary starting points to achieving the highest quality clouds and atmosphere in your project.

Set r.VolumetricRenderTarget to 0 to start enabling cinematic quality results.

Set r.VolumetricCloud.HighQualityAerialPerspective to 1 to enable cinematic aerial perspective for clouds to use high quality ray tracing instead of low resolution LUTs.

Set the following on the Volumetric Cloud component:

Under the Cloud Tracing section, increase the sample count scale for View, Reflections, and Shadows. Sample counts can be increased for each of these scales using commands found in their tool tips.

Enable the Use per Sample Atmospheric Light Transmittance property to apply atmosphere transmittance per sample instead of using the Directional Light's global transmittance.

Set the following in your Volume Cloud Material using the Volumetric Advanced Material Output expression:

Apply ground lighting to the bottom of cloud layers, giving more shape and color to clouds in the scene.

Enable Ground Contribution from the Details panel. On the Volumetric Cloud component, use the Ground Albedo to specify the ground color used to light the cloud from below with respect to the sunlight and atmosphere.

Set the number of approximations used to simulate the multiple scattering of light through the cloud volume:

You can better simulate multiple scattering effects of light through the cloud volume by increasing the number of Multi Scattering Approximation Octaves used, up to a value of 2.

Light will scatter more through the cloud volume when applying additional octaves meaning that you'll want to adjust the Multi Scattering Contribution and Multi Scattering Occlusion values on the Volumetric Advanced Output expression to compensate.

Enable the following shadowing properties of Atmospheric Lights:

Set Cast Cloud Shadow to cast shadows from clouds onto scene elements and into the atmosphere.

Set Cast Shadows on Clouds to cast shadows from opaque objects onto cloud layers.

The Directional Light must have a large enough Shadow Dynamic Distance to effectively shadow large objects onto clouds.

Choose between the following quality improvements for Sky Atmosphere based on your project needs:

Improve the overall quality of atmosphere rendering.

Set r.SkyAtmosphere.FastSkyLUT to 0. Disabling this optimization is slower to render, but produces fewer visual artefacts with high-frequency detail that can appear in places like the earth's shadow or scattering lobe.

Increase tracing quality of the atmosphere and sunlight shafts within the atmosphere.

Requires r.SkyAtmosphere.FastSkyLUT to be enabled.

Set r.SkyAtmosphere.AerialPerspectiveLUT.FastApplyOnOpaque to 0.

On the Sky Atmosphere component, use the quality slider Trace Sample Count Scale to adjust the number of samples used. If the max range isn't enough, use the command r.SkyAtmosphere.SampleCountMax to choose a higher limit and manually enter a value in the property field.

Improve the quality of sunlight shafts by increasing the LUT sizes set with the commands r.SkyAtmosphere.FastSkyLUT.Width and r.SkyAtmosphere.FastSkyLUT.Height.

Improve the quality of fog on opaque and transparent surfaces by increasing the size of r.SkyAtmosphere.AerialPerspectiveLUT.Width.

Exercise caution when increasing this value because it is a 3D volume texture that increases memory consumption.

Volumetric Material

A material using the Volume material domain drives the look of clouds using volume textures. A volume texture is a 3D texture that is sliced into a series of 2D textures aligned to a grid. These types of textures within a material are used for different volumetric effects, like smoke and clouds, because they work well for things like light traveling through a volume.

The volume texture below represents a series of two-dimensional images in a grid (left) that when stacked, they make a three-dimensional volume representation (right).



Open and view a volume texture with the Texture Editor to display its two-dimensional image view (left), or its three-dimensional volume view (right).

Along with the attributes controllable in the Volumetric Cloud Component and Material, the volume texture is the basis that provides the initial look of your cloud and helps define what is possible. Volume textures open up the possibilities through your cloud material to create many different types of clouds and effects.

The examples below demonstrate several varieties of clouds that can be created using a single volume material with some adjustable parameters through instancing. This example uses the M_volumetricCloud_02_Profiles_Soft that is available in the Volumetrics plugin content (see below).



Your volume material has material expression input and output nodes that provide editable attributes forming the basis of your cloud material. Some of these settings have performance implications that increase or reduce the cost of the shader.

It's recommended when using these expressions to parameterize the values of these expressions to quickly and easily adjust their values in a Material Instance.

Volumetrics Plugin Content

The content within this plugin is for demonstration purposes and may not be entirely optimized for use in projects. It also may change or be removed during any further releases. It is meant as a starting point for creating your own content within the editor.

The Volumetrics plugin contains example and experimental content created by Epic's own technical artists, some of which may not be specifically designed for cloud rendering or other types of tools using volume rendering, like fluid simulation.

Follow these steps to get started:

The plugin can be enabled from the main menu by selecting Window > Plugin. Search and enable the Volumetrics plugin.



Click Image for full size.

In your Content Drawer / Content Browser, click Settings to enable Show Engine Content and Show Plugin Content.



Click Image for full size.

Use your Content Drawer / Content Browser to locate and select the Volumetrics folder where the plugin content is stored.

Example Cloud Materials

Several types of cloud materials are available to choose from in this plugin. They can be used to create different types of clouds in your scenes.

You'll find these cloud materials located in the /Content/Sky/Materials folder with the prefix M_Volumetric_Cloud_. For example, Content/Sky/Materials/M_Volumetric_Cloud_02_Profiles_Soft.

To use them effectively, create a Material Instance of the cloud material and apply that to the Volumetric Cloud component's Material slot. When you open the instance of the material, you'll be able to change parameters to render the clouds and achieve a desired look, density, scale, and much more.

The majority of the clouds captured in screenshots for this documentation were created from these example cloud materials with their parameters changed in the material instance.

Blueprint Placed Clouds

Place individual clouds Blueprint Actors in your scene using the example set up in this plugin folder. The individually placed Blueprints in the scene can be scaled, rotated, and moved along the X and Y-axes. The Volumetric Cloud component is required to be in the scene as well along with an assigned cloud material to be used. The Blueprint Cloud Actor enables additional customization and placement of clouds within your scene.

You'll find an example setup in the /Tools/CloudCompositing/Maps folder in the Composite_Cloud_Object Level. Take a look at the BP_CloudMask_Object and the BP_CloudMask_Generator to see how this scene is set up and the available properties you can adjust on this Actor.

Blueprint Painted Clouds

Start painting clouds onto your skies using this example set up to add sparse or densely-packed clouds to your scene. This example uses a play-in-editor game mode with a simple user interface to paint clouds using your mouse cursor that can scale the brush, its intensity, and more.

You'll find an example setup in the /Tools/CloudCompositing/Maps folder in the Paint_Clouds Level. Select the BP_PaintClouds Actor to explore some of the properties you can change for how your cloud is painted.

To start painting clouds, press Play in the main toolbar to play-in-editor. Use the following to start painting clouds in the scene:

Left Mouse Button paints the cloud volume

Mouse Wheel scales the size of the paint brush.

Shift + Mouse Wheel changes the strength of the brush strokes being painted.

Shift while painting removes painted areas.

Right Mouse Button + Mouse Wheel scales the velocity speed painted into the cloud when Velocity is chosen from the Paint Mode dropdown in the BP_PaintCloud properties.

Performance and Scalability

Managing performance and scalability across multiple platforms is important when developing your projects. The sections below contain information on scaling the quality of clouds and other features relevant to capturing and lighting clouds in your projects.

Supported Platforms

The Volumetric Cloud and Sky Atmosphere components support the following platforms to provide a scalable atmosphere system:

Feature

Mobile

XB1 / PS4

XBX / PS5

Low-end / High-end PC

SkyAtmosphere

YES*

YES

YES

YES

Volumetric Clouds

NO

YES**

YES

YES

* Requires a skydome mesh with a material that has Is Sky enabled. ** To achieve acceptable performance on these platforms, it is recommended to evaluate cloud self shadowing using the shadow map approach instead of secondary tracing mentioned in the Volume Ray Marching and Shadows Maps section.

Controlling Cloud Tracing Quality

The cloud system performs a number of traces through the volume material. The quality of the traced result is dependent on the number of samples used. The more samples used, the higher the quality will be. The opposite is true as well, the fewer samples used, the lower the quality will be.





For different platforms, it's important to strike a balance between performance and quality. The Cloud Tracing properties enable you to scale the tracing quality of key cloud attributes, like clouds in reflections, shadowing samples for clouds and clouds in reflections, and the distance from the camera that cloud shadowing should stop.



Each of these properties has its own console command that can be set individually per-platform using the Device Profiles configuration (*.ini) file. This provides a broad level of flexibility when setting target scalability across different platforms.

Optimizing your Volume Cloud Material

The basis of rendering clouds starts with your volume material and the Volumetric Advanced Output and Volumetric Advanced Input expressions that are used in the Material Graph. While you can parameterize a lot of aspects of your cloud material to control some of its attributes through material instancing, some can only be set on this node from the base material.

The following suggestions are set on the Volumetric Advanced Output expression and can be used independently of each other when deciding how to optimize your project's cloud material:

Use Gray Scale Material to only consider the R (red) channel of the material's input parameters during evaluation. In your scene, the material response of the cloud will be grayscale but lighting of the material will still be colored.

Enable Ground Contribution if your frame budget allows. It adds some costs to tracing to sample the shadowed lighting contribution from the ground on to the bottom layer of the clouds.

Limit the number of Multi Scattering Approximation Octave Counts used to save some performance in the shader. By default, it uses single scattering (0) but can use a max of two approximation octaves to simulate the multiple scattering of light effect in the cloud volume.

Use the Ray March Volume Shadow checkbox to toggle between secondary ray marching the cloud volume or using cascaded shadow maps. Enabling cascaded shadow maps (unchecking the box) provides a performance boost and gives infinite length for shadowing even though they become less accurate and grayscale in color.

The Conservative Density attribute is used to accelerate the ray marching by skipping expensive material evaluation early on. The X component of the float vector (Vector3) represents the participating medium conservative density. When the value is greater than 0, the material is evaluated, otherwise, it evaluates the next sample directly. For additional details, see Volumetric Cloud Reference.

Budgeting with the Sky Light Real Time Capture Mode

The Sky Light's Real Time Capture mode enables 9-frames time slicing to distribute a single frame's capture over multiple frames. This optimization improves performance for achieving time-of-day simulations, making it much less costly because time slicing is only as expensive as its most costly frame. It provides you the opportunity to push quality in other areas of your frame budget without additional costs.

For example, if you were to break down the captured scene elements and their frame cost and see that Specular Convolution is taking 0.8 milliseconds (ms) per frame, but Sky and Cloud are only taking 0.6 ms, you still have room in the frame budget to increase sky and cloud quality marginally without paying additional cost.

Conservative Density Evaluation

Conservative Density has been added as a way to optimize the ray marching process. Evaluating the entirety of the cloud material graph for each sample that is ray marched in the atmosphere would quickly become too expensive. To make it more cost-efficient, a user-specified conservative density is inexpensively reasonable to evaluate. For example, the material evaluation could be a top-down two-dimensional texture describing the cloud density whereby the only rule is that the conservative density must be greater than 0 where there is cloud in the atmosphere when evaluating using the Volumetric Advanced Input expression.

While ray marching the atmosphere, a cloud material sample is taken in two steps if the conservative density input is used:

On the Volumetric Advanced Output node, the conservative density input (Vector 3) graph is evaluated.

If the Conservative Density of X (in the Vector3) is greater than 0:

A decision to evaluate the more expensive material graph plugged into the Main Material node (evaluating Albedo, Emissive Color, and Extinction) is used.

The values can be accessed using the Volumetric Advanced Input node, which avoids computing the conservative density values that have already been evaluated in Step 1.

Otherwise, if the Conservative Density of X is equal to or less than 0, the more expensive material evaluation is skipped and goes to the next sample.

Unreal Engine doesn't support dynamic branching in its material graph. The ConservativeDensity input enables dynamic branching to skip the more expensive material evaluation that can happen. When Unreal Engine natively supports dynamic branching in materials, inputs like this will be obsolete and let technical artists make decisions for what can be dynamically skipped.

Ray Tracing and Volumetric Clouds

The cloud system doesn't support Ray Tracing features and only takes into account the clouds as rendered into the Sky Light. Tracing volumetric clouds for reflections would be significantly costly to performance.

In instances where you want reflections on an object in the sky, placing the Sky Light Actor closer to it (in the sky) would help.

Volumetric Cloud Component

Material Expressions

Atmosphere Lights and Sky Light

This page includes reference information for the Volumetric Cloud, Material expressions, and Light component properties.

Volumetric Cloud Component

The following properties can be found on the Volumetric Cloud component through the Details panel when it is placed in a level. The properties found in this component enable you to define the physical attributes of the cloud placed in your Level, such as its distance from the surface of the planet, how tall the cloud volume is, the quality of the ray-marched clouds, and more.



Property

Description



Layer



Layer Bottom

The altitude at which the cloud layer should start, measured in kilometers (km) above the ground.

Layer Height

The altitude at which the cloud layer should end, measured in kilometers (km) above the ground.

Tracing Start Max Distance

The maximum distance of the volumetric surface before which we will accept to start tracing, measured in kilometers (km).

Tracing Max Distance Mode

Select the mode to control how the tracing max distance should be interpreted. Options are:

Distance from Point of View

Distance from Cloud Layer Entry Point

Tracing Max Distance

The maximum distance that will be traced inside the cloud layer, measured in kilometers (km).



Planet



Planet Radius

The planet radius used when there is not a Sky Atmosphere component present in the scene.

Ground Albedo

The ground albedo color used to light the cloud from below with respect to the sun light and the Sky Atmosphere. This is only used by the cloud material when the Volumetric Advanced Material Output node has Ground Contribution enabled in its Details panel. (See the Material Expressions section of this page.)



Cloud Material



Material

The material assigned that describes the cloud volume. It must be a material that uses the Volume Material Domain.



Cloud Tracing



Use Per Sample Atmospheric Light Transmittance

Whether to apply atmosphere transmittance per sample instead of using the light global transmittance.

Sky Light Cloud Bottom Occlusion

Occlusion amount applied to the Sky Light contribution at the bottom of the cloud layer. This is a fast approximation to sky lighting being occluded by clouds without having to trace rays or sample an ambient occlusion (AO) texture.

View Sample Count Scale

The scale of the view tracing sample count. The quality level scalability console variables affect the maximum range. The sample count resolution is clamped according to the scalability setting of r.VolumetricCloud.ViewRaySampleCountMax.

Reflection Sample Count Scale

The scale of the reflection tracing sample count. The quality level scalability console variables affect the maximum range. The sample count resolution is clamped according to the scalability setting of r.VolumetricCloud.ReflectionRaySampleMaxCount.

Shadow View Sample Count Scale

The scale of the shadow view tracing sample count. The quality level scalability console variables affect the maximum range. The sample count resolution is clamped according to the scalability setting of r.VolumetricCloud.Shadow.ViewRaySampleMaxCount.

Shadow Reflection Sample Count Scale

The scale of the shadow reflection view tracing sample count. The quality level scalability console variables affect the maximum range. The sample count resolution is clamped according to the scalability setting of r.VolumetricCloud.Shadow.ReflectionRaySampleMaxCount.

Shadow Tracing Distance

The shadow tracing distance measured in kilometers (km).

Stop Tracing Transmittance Threshold

When the mean transmittance is below this threshold, we stop tracing. This is a good way to reduce the ray marched sample count, and thus increase performance.

Select the mode to control how the tracing max distance should be interpreted. Options are:

Distance from Point of View

Distance from Cloud Layer Entry Point

Material Expressions

The following Material Expressions can be added to your Material Graph to define attributes of your volumetric clouds.

Volumetric Advanced Material Output Expression

The Volumetric Advanced Material Output expression provides control over a set of cloud parameters that affect the volume material applied to the Volumetric Cloud component when added to a material graph. It also provides additional cloud properties from the Material Editor Details panel when selected (see below).



Property

Description



Phase



Phase G

The parameter G input to the phase function describes how much forward (g < 0) or backward (g > 0) light scatters around. A valid range would be between -1.0 and 1.0. Defaults to 0 when no amount is specified. It is evaluated per sample if Per Sample Phase Evaluation is enabled.

Phase G2

The parameter G2 input to the second phase function describes how much forward (g < 0) or backward (g > 0) light scatters around. A valid range would be between -1.0 and 1.0. Defaults to 0 when no amount is specified. It is evaluated per sample if Per Sample Phase Evaluation is enabled.

Phase Blend

The linear interpolation (lerp) factor is used when blending the two phase functions parameterized by G and G2. A valid range is between 0.0 and 1.0. Defaults to 0 when no amount is specified. It is evaluated per sample if Per Sample Phase Evaluation is enabled.

Multi Scattering Contribution

Represents how much contribution each successive octave will add to the multiple-scattering. It is evaluated per pixel, and a valid range is between 0.0 and 1.0 from low to high contribution. Defaults to 0.5 contribution if no value is specified.

Multi Scattering Occlusion

Represents how much occlusion will be reduced for each successive octave. It is evaluated per pixel, and a valid range is between 0.0 and 1.0 from low to high occlusion. Defaults to 0.5 occlusion if no value is specified.

Multi Scattering Eccentricity

Represents how much the phase will become isotropic for each successive octave. It is evaluated per pixel, and a valid range is between 0.0 and 1.0 from anisotropic to isotropic. Defaults to 0.5 scattering eccentricity if no value is specified.

Conservative Density

Represents a three component float vector (Vector3). The X component must represent the participating medium conservative density. If the value is greater than 0, the material will be evaluated and will evaluate the next sample directly. This optimization is used to accelerate ray marching by skipping expensive material evaluation early on. The Y and Z components (of the Vector3) are used to pass extra data with the conservative density to the material evaluation step, which avoids computing it again.

For example, a simple top down 2D density texture would be enough to help by not evaluating the material in empty regions. The Y and Z components can contain parameters that can be recovered during the material evaluation using the Volumetric Advanced Material Input node. This attribute is evaluated per pixel.

When selected, the Material Editor Details provides additional properties that can be set for any cloud material using this material. It enables you to directly set Phase and Multi-Scattering values that aren't parameterized. You can control the number of octave approximations used to simulate the multiple scattering effect of light, apply contribution of ground lighting to the bottom of the cloud layer, and more.



Property

Description



Phase



Per Sample Phase Evaluation

Enable this option to force the phase function to be evaluated per sample, instead of once per pixel (globally). Per sample evaluation is slower.



Multi-Scattering



Multi Scattering Approximation Octave Count

How many octaves to use for the multiple-scattering approximation. This increases the cost of the shader, so it's best to use a single octave. 0 means single scattering only.



Options



Ground Contribution

Sample the shadowed lighting contribution from the ground onto the medium (single scattering). This adds some costs to the tracing when enabled.

Gray Scale Material

Sets this material to only be considered for gray scale, only using the R channel of the input parameters internally. The lighting will still be colored. This is an optimization.

Ray March Volume Shadow

Disable this to use the cloud shadow map instead of secondary ray marching. This is usually enough for clouds views from the ground and it should result in a performance boost. Shadows now have infinite length but also become less accurate and gray scale.

Clamp Multi Scattering Contribution

Sets whether multiple scattering contribution entry is clamped in [0,1] or not. When disabled, the artist is in charge of ensuring the visual remain in a reasonable brightness range.

Atmosphere Lights and Sky Light

Atmospheric lights contribute to rendering of the volumetric clouds in your scene with properties that define their lighting in static and dynamic time-of-day scenes.

Directional Light

The Volumetric Cloud component supports lighting from up to two Directional Light sources, such as a moon and sun, or two suns. The Directional Light provides lighting and shadowing for clouds and opaque objects onto clouds. It also enables you to specify the strength, extent, and resolution of the shadows of clouds in your scene.



Property

Description



Atmosphere and Cloud



Atmosphere Sun Light

Whether the Directional Light can interact with the atmosphere, clouds and generate a visual sun disk, all of which compose the visual sky.

Cast Shadows on Clouds

Whether the light should cast any shadows from opaque meshes onto clouds. This is disabled for any secondary Directional Lights that have Atmosphere Sun Light enabled and set to Atmosphere Sun Light Index of 1, such as another sun or as a moon light.

Cast Shadows on Atmosphere

Whether the light should cast any shadows from opaque meshes into the atmosphere when a SkyAtmosphere is used.

Cast Cloud Shadows

Whether the light should cast any shadows from the clouds onto the atmosphere and other scene elements.

Cloud Scattering Luminance Scale

Scales the light contribution when scattered in cloud participating media. This can help counter balance the fact that our current multiple scattering solution is only an approximation.



Advanced Properties



Per Pixel Atmosphere Transmittance

Whether to apply atmosphere transmittance per pixel on opaque meshes instead of using the light's global transmittance.

Cloud Shadow Strength

The strength of the shadow. Higher values will block more light.

Cloud Shadow on Atmosphere Strength

The strength of shadows on the atmosphere. When set to 0, shadows on the atmosphere is disabled.

Cloud Shadow on Surface Strength

The strength of shadows on opaque and transparent meshes. When set to 0, shadows on opaque and translucent surfaces is disabled.

Cloud Shadow Depth Bias

Controls the bias applied to the front shadow depth of the volumetric cloud shadow map.

Cloud Shadow Extent

The world space radius of the cloud shadow map around the camera. Measured in kilometers (km).

Cloud Shadow Map Resolution Scale

Scales the cloud shadow map resolution. The resolution is clamped by r.VolumetricCloud.ShadowMap.MaxResolution.

Cloud Shadow Ray Sample Count Scale

Scales the number of samples used for shadow map tracing. The sample count resolution is clamped with r.VolumetricCloud.ShadowMap.RaySampleMaxCount.

Sky Light

The Sky Light component provides soft ambient shadowing support that can be enabled and controlled with the following properties.



Property

Description



Atmosphere and Cloud



Cloud Ambient Occlusion

Whether the cloud should occlude sky contribution within the atmosphere (progressively fading out multiple scattering) or not.

Cloud Ambient Occlusion Strength

The strength of the ambient occlusion. Higher values will block more light.

Cloud Ambient Occlusion Extent

The world space radius of the cloud ambient occlusion map around the camera in kilometers (km).

Cloud Ambient Occlusion Map Resolution Scale

Scales the cloud ambient occlusion map resolution. The resolution is clamped by r.VolumetricCloud.ShadowMap.MaxResolution.

Cloud Ambient Occlusion Aperture Scale

Controls the cone aperture angle over which the sky occlusion due to volumetric clouds is evaluated. A value of 1 takes the entire hemisphere into account, resulting in blurry occlusion. A value of 0 takes a single direction of occlusion (vertical) into account, resulting in sharp occlusion.

Exponential Height Fog

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Volumetric Fog Controls

Temporal Reprojection

Precomputed Lighting on Volumetric Fog

Performance

Currently Supported Features

Known Issues

Training Stream

Volumetric Fog is an optional part of the Exponential Height Fog Component. Volumetric Fog computes participating media density and lighting at every point in the camera frustum to support varying densities and any number of lights that affect the fog.





In this scene, Volumetric Fog is coming from the directional light source off screen through the arch and surrounding area to create shadowed fog.



Volumetric Fog Controls

When setting up and adjusting Volumetric Fog, you can control it globally or locally in your scene. The global controls enable you to use the Exponential Height Fog component to control fog for the the entire scene. The local controls enable you to control fog by way of a particle system in areas where the particles can spawn.

Global Controls

To control Volumetric Fog, you can adjust the properties in your Exponential Height Fog and on each Light to control the Light's contribution amount.

Volumetric Fog controls can be found in the Exponential Height Fog component under the Volumetric Fog section. The exponential height distribution provides a global density for Volumetric Fog.



Property

Description

Scattering Distribution

This determines how directional the volumetric scattering is; a value of 0, means light scatters equally in all directions, while a value close to 1 causes scattering, predominantly in the direction of the light (you have to be looking at the light to see its scattering).

Albedo

This is the overall reflectiveness of the participating media. Clouds, fog, and mist, which are based on water particles, have an Albedo close to 1.

Emissive

This is a density of light emitted by height fog.

Extinction Scale

Controls how much the participating media blocks light.

View Distance

This is the distance from the camera over which Volumetric Fog will be computed. In the created volume texture for the fog there are a limited number of Z slices depending on this distance. Increasing the distance will result in under-sampling that can cause artifacts to appear. The number of Z slices can be adjusted by using r.VolumetricFog.GridSizeZ, where higher is better quality, but will be more expensive.

Start Distance

This is the distance (in world units) from the camera from which the volumetric fog will start.

Near Fade In Distance

This is the distance over which volumetric fog will fade in from the start distance.

Static Lighting Scattering Intensity

Scales the intensity of the volumetric fog static lighting scattering.

Override Light Colors with Fog Inscattering Colors

When enabled, uses the Fog Inscattering Color, Directional Inscattering Color, and Inscattering Texture properties to override the light color with Volumetric Fog.

Each Light's contribution amount to the scene (and whether it shadows the fog) can be controlled by adjusting the following properties on each Light's Details panel under the Light section.



Property

Description

Volumetric Scattering Intensity

Controls how much this light will contribute to the Volumetric Fog. When set to 0, there is no contribution.

Cast Volumetric Shadow

Toggles whether or not to cast a volumetric shadow for lights contributing to Volumetric Fog. When shadow casting is enabled, Point and Spot Lights are approximately three times more expensive because they contribute to the volume textures shadowing, where as non-shadow casting lights only contribute to the fog but do not shadow.





In this example, the Spot Light's contribution to the Volumetric Fog has been disabled by setting the Volumetric Scattering Intensity to 0.

Local Controls

Materials using the Volume domain describe Albedo, Emissive, and Extinction for a given point in space. Albedo is in the range [0-1], while Emissive and Extinction are world space densities with any value greater than 0.



This is an example of the simplest Volume Material for a Particle System.

Volume materials currently only work on particles and positions inside of the particle radius will be valid, which is usually handled by a SphereMask.

Placing a single Particle System with the material causes a sphere of density to be added to the Volumetric Fog. The effect is fully three dimensional (3D) with no billboards involved.



Taking this approach a step further, you could use multiple spherical fog particles with noise from textures to limit fog to a certain area of your scene.



In this scene, the fog particles have populated these low-lying areas to create a localized fog effect that is shadowed using Voluemtric Fog.

Temporal Reprojection

The volume textures (voxels) used by Volumetric Fog are relatively low-resolution and aligned to the camera frustum. Volumetric Fog uses a heavy temporal reprojection filter with a different sub-voxel jitter per frame to smooth out the aliasing. As a side-effect, fast-changing lights, like flashlights and muzzle flashes, leave lighting trails. To disable the contribution of these lights, set Volumetric Scattering Intensity to 0.

Precomputed Lighting on Volumetric Fog

Volumetric Lightmaps support static lighting application for Volumetric fog by having each fog voxel interpolate precomputed lighting to its position in space.





Stationary Lights have their indirect lighting stored in lightmaps, which now affects fog.





Skylights are shadowed properly, preventing indoor areas from becoming over-fogged.





Static and Emissive for Static lights affect fog without costing anything since they're all merged into the Volumetric Lightmap.

Performance

The GPU cost of Volumetric Fog is primarily controlled by the volume texture resolution, which is set from the Shadow level of the Engine Scalability. Volumetric Fog costs 1 millisecond on PlayStation 4 at High settings, and 3 milliseconds on an NVIDIA 970 GTX on Epic settings, which has eight times more voxels to operate on.

Particles using Volume domain can add a significant GPU cost, depending on their 3D overdraw and instruction count. Use the console command profilegpu to inspect this cost.

Point and Spot Lights that have Cast Volumetric Shadow enabled, cost approximately three times more than unshadowed Point and Spot Lights.

Currently Supported Features

This list comprises the currently supported features of Volumetric Fog:

A single Directional Light, with shadowing from Cascaded Shadow Maps or static shadowing, with a Light Function.

Any number of Point and Spot Lights, with dynamic or static shadowing (if Cast Volumetric Shadowing is enabled).

Shadowing of Stationary Sky Lights.

Precomputed Lighting through Volumetric Lightmaps (Direct Lighting of Static Lights, Indirect Lighting of Stationary Lights).

A single Skylight, with shadowing from Distance Field Ambient Occlusion (if enabled).

Particle Lights (if Volumetric Scattering Intensity is greater than 0).

Also, translucency is properly affected by Volumetric Fog, depending on its position in the scene. By default, translucency computes fog at vertices, so water planes with low tessellation can introduce artifacts. These materials can be set to compute fogging per-pixel to solve this with Compute Fog Per-Pixel enabled in the Material Details.

Known Issues

The following features are not yet supported while using Volumetric Fog:

IES profiles and Light Functions on Point and Spot Lights.

Shadowing from Ray Traced Distance Field Shadows.

Shadowing from Volumetric Fog (itself).

Source Radius on Point and Spot Lights.

Some settings in the Exponential Height Fog, like Fog Cutoff Distance, Start Distance, and Fog Max Opacity.

Common Questions

Below are some common questions or issues that may arise when using Volumetric Fog.

How can one achieve stronger light shafts without heavy global fog?

When the global density of fog is increased, you get denser fog, so you only notice light shafts (shadows of light) if the fog is dense enough to have everything heavily fogged. There are two ways to go about having stronger light shafts without heavy fog:

Keep the global fog density low, but use a higher Volumetric Scattering Intensity for the Directional Light. Also, adjust the Scattering Distritbution to nearly 0.9 in your Exponential Height Fog Actor.

Keep the global fog density low, but increase it in certain areas with Volume particles.

Can Exponential Height Fog and Volumetric Fog be used at the same time?

At this time, Volumetric Fog replaces Fog Inscattering Color within the Volumetric Fog View Distance. Because Volumetric Fog is physically-based and Exponetial Fog is not, it's impossible to blend the two systems in the distance for them to precisely match. This also means that some settings in the Exponential Height Fog component will have no effect on Volumetric Fog.

Can the Volumetric Fog's center be decoupled from the camera? This would be ideal for top-down games...

Not currently, though, a standalone volume would be ideal for this. However, it's hard to integrate them with translucency efficiently.

Training Stream

Things to Consider for Lights and their Properties

Setting Properties for Lights

General Light Features and Properties Topics

Directional Light Features and Properties Topics

Sky Light Features and Properties Topics

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Lights in Unreal Engine contain a large set of properties to work with, which are partly dependent on the Light's mobility and type.

Light properties are found in the Details panel when a light is selected in the Level. Depending on the set Mobility of Static, Stationary, or Movable determines what features and properties of the light are supported for the selected light.



Light properties of a Directional Light.

Things to Consider for Lights and their Properties

Before diving into the specific features and properties of Lights, you'll want to consider the following:

What types of lights does your scene require to light it?

What Mobility should your lights have?

Lights with different mobilities can be mixed and matched as needed to light a scene. However, considerations must be considered for what that means for the lighting, shadows, and assets it affects within the Level. Not all properties support every mobility or light type.

Shadowing is a broad subject with lighting. Mobilities, type of light, or even enabled lighting features in the Project Settings can affect how lighting works within the project.

Some types of lights complement other standalone features, such as one for Environmental Lighting.

Setting Properties for Lights

The properties and features of lights can be found in the Details panel when a light is selected in the Level.

Each light must have its Mobility set to Static, Stationary, or Movable.



All properties of lights are listed no matter what selection is made, but the mobility affects some properties that are supported. For example, Lightmass settings only affect mobilities set to Static or Stationary.

Explore the topics below to learn about some of the features and properties you can use with the Lights in your scenes and projects.

General Light Features and Properties Topics

A listing of general concepts and features related to all, or most, types of lights you can use. These can be individual features of lights you can use, or properties of lights that work with larger features, like Global Illumination.



An overview of using physically based lighting units with light sources.



A collection of topics on the global illumination options available to choose from.



An overview of available shadowing methods and the properties they support.



Systems for how reflections are captured and displayed on reflective surfaces.



The available types of lights to choose from and how their mobility settings affect lighting in the scene.



An overview of Mesh Distance Fields and its available features that you can use when developing your games.



An overview of using channels of a light source to light specific surfaces.



An overview of setting up and using IES textures with lights.



An overview of using materials to mask a light's projected area.





An overview of using multiple lighting setups for a single scene.

Directional Light Features and Properties Topics

The following features work with Directional Lights.



An overview of using Direcitonal Light to simulate light scattering through the atmosphere.



A physically-based sky and atmosphere rendering system with time-of-day features and ground-to-space view transitions featuring aerial perspective.



Real-time cloud rendering using volumetric materials.

Sky Light Features and Properties Topics

The following features work with a Sky Light.



Components and tools that enable users to build immersive worlds with environment lighting from fog, clouds, sky and atmosphere.

Usage

Importing and Assigning to Lights

Profile Light Intensity

Texture Properties

3D Light Profile Visualization

Additional Notes

Performance

Spot Lights

Acquiring and Previewing Light Profiles

The Illuminating Engineering Society (IES) has defined a file format which describes a light's distribution from a light source using real world measured data. These IES Photometric files, or IES Profiles, are a lighting industry standard method of diagramming the brightness and falloff of light as it exists a particular real world light fixture. It enables them to account for reflective surfaces in the light fixture, the shape of the light bulb, and any lensing effects that happens. This type of photometric lighting is primarily used in Enterprise fields (such as Media and Entertainment or Architecture and Manufacturing), but is often used in games production to achieve realistic lighting effects, too.

IES Light Profiles are a 1D texture (gradient). However, they are not actual texture files. The curve defines light intensity in an arc that "sweeps" around an axis to make Point, Spot, and Rect Lights appear to be casting light realistically based on the provided real-world data. The curve works like a multiplier for the overall brightness of the light, as if you were projecting a texture from a light, but without the overhead of using a texture, or the errors that can occur at some angles.

In the examples below, the IES Profile is assigned to a Point Light and the diagram in the top left of each panel shows the shape of the given IES Profile.



Click the image for full size.

If you were to open an IES Profile in a text editor, you would find that it is an ASCII file containing a wide array of metadata, like this example for a Lithonia TE_150S_E17_C:

Usage

Use the following steps to use your own IES Profiles:

Importing and Assigning to Lights

Import an IES Profile by using one of the available import methods for textures: using the Add button, drag-and-drop, or context menu.

Select a Point, Spot, or Rect Light from your scene. Under the Details panel, assign the light profile to the IES Texture slot under Light Profiles.



Using a light profile with precomputed Static lighting builds can potentially produce poor results due to the light profile's mask and a low lightmap resolution. Increasing the lightmap resolution of the receiving surface or using Stationary or Movable Lights produce the best result.

Profile Light Intensity

Optionally, you can choose to use IES Profile's light intensity over the Light's Intensity:



Use IES Intensity uses the light brightness from the profile, and when disabled will use the selected light's intensity value.

IES Intensity Scale globally scales the profile's brightness contribution. This value can only be set when Ues IES Intensity is enabled.

Texture Properties

When opening an IES Profile, the Texture Editor provides a couple of options under Texture Light Profiles that you can set:



Click the image for full size.

Property

Description

Brightness

The light brightness in candelas imported from the IES Profile. When enabling Use IES Intensity on the light and this value is less than or equal to 0, the profile will be used for masking only, causing the light to be completely masked by the profile. Also, this should be used in conjunction with the light's setting for Inverse Squared Falloff.

Texture Multiplier

This uneditable value is the multiplier used to map texture value to a result that is integrated over a sphere to 1.0f.

3D Light Profile Visualization

When selecting a light that has an IES Texture assigned, a visualization of the light's representation will be shown.





Additional Notes

Performance

IES Profiles render very fast and do not have a significant effect on performance, making them a more ideal option for shaping your light than a Light Function.

Spot Lights

Using IES Profiles on any Point or Rect Lights turns them—visually speaking—into Spot Lights and using them on a Spot Light will operate the same way except the Spot Light's cones will mask the IES Profile effect. However, since the projection area of a Spot Light is a 179 degree arc (at its maximum), any IES data past that point is lost.





In this comparison, the IES profile emits light in all directions. When used by a Spot Light, the IES data is clipped to the Spot Light's Cone Angle. When used by a Point Light, the IES profile is unclipped.

Acquiring and Previewing Light Profiles

The easiest way to acquire IES Profiles is to visit the manufacturer's website and download them, as almost all major lighting manufacturers provide them free of charge. A couple of links are provided below:

Lithonia Lighting

Philips

To visualize the light's IES Profile, you can use photometric viewers, such as IESviewer, which is freely available. With it, you can select a light profile, visualize the profile and preview what it would look like before you decide to import it.



Image credit to Andrey Legotin.



Some manufacturer sites, such as Lithonia's site, have a built-in profile viewer that can be used in your web broswer without needing to download the profile to preview it.

Usage

Example

Limitations

Performance

On Mobile



Lighting Channels allow dynamic lights to only affect objects when their lighting channels overlap. This is primarily intended for cinematic use to give users powerful control over how Actors are lit. At the moment, Unreal Engine supports up to 3 lighting channels.

Usage

By default, Directional Lights, Spot Lights, Point Lights, and all Actors that can be affected by lights (Static Meshes, Skeletal Meshes, etc.) have Lighting Channel 0 enabled. If you would like a lightable Actor to be affected by another Lighting Channel, you must enable that channel on both the Actor and the light.

Example



In the above image, the white Directional Light can only affect Channel 0, which includes the mannequin on the left and the background Static Meshes, while the purple Point Light can only affect Channel 1, which only includes the mannequin on the right.

You can see how the properties are set here:



Click for full image.

For lights, the property can be found in the Advanced pulldown menu of the Light category in the Details panel. For Actors that can be lit, you can find the Lighting Channels properties in the Lighting category of the Details panel.

Limitations

Lighting channel influence is applied dynamically. This means it won't work with Static Lights or Static Mesh Actors with Static Mobility. Static Mesh Actors with Mobility set to Movable do work, however. You'll need to use either Stationary or Movable lights.

Lighting channels will only affect direct lighting on opaque materials. So, translucent or masked materials will not work.

Performance

The performance impact of using Lighting Channels is minimal, but also non-zero. In a scene with 1 directional light, Radeon 7870, at 1080p for example:

Lighting Channels Satus

Time in ms

off

0.42ms StandardDeferredLighting 1 draws 1 prims 3 verts

on

0.08ms CopyStencilToLightingChannels 1 draws 1 prims 3 verts0.45ms StandardDeferredLighting 1 draws 1 prims 3 verts

On Mobile

As of Unreal Engine 4.13, Lighting Channels works on mobile renderers with the following features supported:

Multiple directional lights are supported in different channels.

Each primitives can only be affected by one directional, and it will use the directional light from first lighting channel it has set.

CSM shadows from stationary or movable directional lights cast only on primitives with matching lighting channels.

Dynamic point lights fully support lighting channels.

Creating a Light Function

Applying a Light Function

Known Issues & Common Questions

Light Functions are, in essence, a Material that can be applied to filter a light's intensity.

It should be noted, however, that you cannot change the color of lights using a Light Function, only the Light Color setting can do that. Also, Static Lights cannot use Light Functions, as this feature is only available for non-lightmapped lights, like Stationary and Movable lights.

In the image below, a Material uses Panner and ScalarParameter nodes to move a texture while generating a flickering effect.



Click image for full size.

Creating a Light Function

You can create a Light Function by setting the Material Domain of a Material to use the Light Function attribute.



Applying a Light Function

You can apply a Light Function to a light from inside the Details panel under the Light Function Material setting.



Known Issues & Common Questions

The following describes known issues when using Light Functions with the Forward Render.

Light Function only works if cast shadows are enabled: This happens because FScene::AssignAvailableShadowMapChannelForLight only assigns a Shadow Map channel to shadow casting lights. Light functions need to be rendered into a Shadow Map to be passed into the base pass in the Forward Render.

Light Function only works if there's one shadow casting object: This happens because FDeferredShadingSceneRenderer::RenderForwardShadowProjections skips the light unless VisibleLightInfo.ShadowsToProject.Num() > 0.



Properties

Occlusion Method

Bloom Method

GPU Cost

Light Shafts can be generated by directional lights to simulate the real world effect of crepuscular rays, or atmospheric shadowing of atmospheric in-scattering. These rays add depth and realism to any scene.

Properties

The directional light has a Light Shaft category in its properties.



The table below provides an information for these properties.

Property

Description

Directional Light

Enable Light Shaft Occlusion

Whether to occlude fog and atmosphere in-scattering with screen-space blurred occlusion from this light.

Occlusion Mask Darkness

Controls how dark the occlusion masking is. A value of 1 results in no darkening term. While values greater than 1 and less than 0 can be used, they will create more specialized effects.

Occlusion Depth Range

Everything closer to the camera than this distance will occlude light shafts.

Enable Light Shaft Bloom

Whether to render light shaft bloom from this light. For directional lights, the color around the light direction will be blurred radially and then added back to the scene.

Bloom Scale

Scales the additive color of the bloom, making it more or less pronounced.

Bloom Threshold

Scene color must be larger than this to create bloom in the light shafts.

Bloom Max Brightness

After exposure is applied, scene color brightness larger than Bloom Max Brightness will be rescaled down to Bloom Max Brightness.

Bloom Tint

Multiplies against scene color to create the bloom color. It colorizes the light shaft bloom effect.

Light Shaft Override Direction

Makes light shafts come from somewhere other than the light's actual direction (only used when non-zero and does not have to be normalized).

Occlusion Method

The occlusion method creates a mask from the depths of the objects on the screen, blurs it away from the light, and uses it to mask fog and atmosphere. This acts more like real life light shafts in that the shadowing of the fog is what creates the light shafts. Note that this also means that your light shafts can only be as strong as your fog / atmosphere. This is intended to be used in games trying for a more realistic look.



The sun directional light can be slightly off the screen and still produce occlusion light shafts, however, they currently fade out as you approach a 90 degree angle from the sun.

Bloom Method

The bloom method captures the scene's color (including translucency and fog in-scattering) right around the light source in world space, and blurs it radially away from the light. This method is not really emulating anything that happens in the real world but it is very controllable (not limited by density of fog) and looks impressive. The bloom method works best when there is an interesting bright area around the sun disk, like brightly lit clouds. This is because a bright sun disk will cause some aliasing since it is so small, and the blur is an image space operation.



GPU Cost

These effects (Occlusion and Bloom) cost separately, so it is best to only enable the one you want. At 1080p on a 680GTX, occlusion is 0.5ms and bloom on a single light is 0.68ms.

Lighting Units for Light Intensities

Directional Light

Emissive Surfaces

Sky Light

Emissive Materials as Static Lights

Point, Spot, and Rect Lights

Tips and Suggestions

General Considerations

Lights in Unreal Engine (UE) are defined using physically based lighting units, making it possible to enter known, measurable values to achieve fully realistic lighting. In addition to light types supporting different lighting units, Post Process for Eye Adaptation (or Auto Exposure) now supports an extended range of values and is expressed in EV100 (ISO 100). Between the physically based units for lighting and auto exposure, creating realistic lighting is much more achievable without "magic" numbers and artists having to "eyeball" different values.

Lighting Units for Light Intensities

Each type of light displays its physically based lighting unit next to its Intensity value in its Details panel when selected.



For these types of lights, their intensity is displayed as follows:

Directional Light uses Direct Normal Illuminance, expressed as Lux which is equal to one lumen per squared meter.

Sky Light and Emissive Materials as Static Lights use Luminance expressed as Candela per meter squared (cd/m2).

Point, Spot, and Rect Lights can select between the following lighting units:

Candela (cd) is a measure of luminous intensity emitted uniformly across a solid angle of one steradian (sr). For example, a light set to 1000 cd would measure 1000 lux at one meter.

Lumen (lm) is a measure of the luminous flux emitted into the angle of one steradian. In photometry, luminous flux (or luminous power) is the measure of the perceived power of light. No matter its distribution (wide or narrow spot), the total amount of energy emitted will be the same.

Unitless is an engine-specific light intensity value and maintains compatibility with engine releases prior to Unreal Engine 4.19.

Directional Light

Directional Lights are expressed in Direct Normal Illuminance or Lux (lx) which represents the Illuminance produced on the earth by the visible part of the direct solar radiation on a surface perpendicular (or normal) to the Sun's rays. It is expressing the total amount of light falling on a surface.

Emissive Surfaces

Emissive surfaces are expressed in Candela Per Meter Squared (cd/m2) which specifies the pixel luminance before any lighting is added.

Sky Lights use the pixel intensity multiplied by the light intensity result in a total luminance that is expressed in cd/m2 in HDR. For example, if the HDR pixels were thought of as a filter and those pixels ranged from 0 to 1.0 with the sky set to an intensity of 1000 cd/m2, the resulting luminance would be 1.0 * 1000 cd/m2.

For Emissive Materials applied to Static Meshes that enable the per-Actor settings Use Emissive for Static Lighting, the luminance of the surface is used to bake lighting into the scene.

Point, Spot, and Rect Lights

For Point, Spot, and Rect Lights, you can specify the unit type of any Light that has Inverse Squared Falloff enabled. You can use the Details panel section Light to set the Intensity Units to Candela,Lumen or Unitless.

Inverse Squared Falloff is physically based distance falloff where the attenuation radius is only clamping the lights contribution supported by all three light unit types. When disabled, only Unitless is available. Lights with Inverse Squared Falloff disabled are useful when placing low-intensity fill lights where you don't want a bright spot near the light.



The default unit type for Point, Spot, and Rect Lights can be set with in the Project Settings > Rendering > Default Settings.

The relationship between each unit is defined as follows:

1 cd = 625 unitless

1 cd = 1 lm/sr

Note that when the intensity of a light is defined in Candelas, it is unaffected by its cone angle. Otherwise, when the light intensity is defined in Lumens, its luminous power only applies to the solid angle affected by the light, in Steradians (sr).

For Point Lights, the solid angle affected by the light is 4π sr :

Illuminance (1 lm) ≈ 49.7 * Illuminance (1 unitless)

Illuminance (1 cd) ≈ 12.6 * Illuminance (1 lm)

For Spot Lights, the solid angle is defined by 2π * (1 - cos(θ)), where θ is the light cone half angle:

Illuminance (1 lm) ≈ 99.5 / (1 - cos(θ)) * Illuminance (1 unitless)

For the default cone, θ = 44° and the solid angle is about 1.76 sr :

Illuminance (1 lm) ≈ 354 * Illuminance (1 unitless) for default Spot Lights.

Illuminance (1 cd) ≈ 1.76 * Illuminance (1 lm) for default Spot Lights.

The smaller the cone angle, the stronger the surface illumination from the light will be when the light intensity is expressed in Lumens.

For Rect Lights, the solid angle is defined as 2π sr :

Illuminance (1 lm) ≈ 199 * Illuminance (1 unitless)

Illuminance (1 cd) ≈ 3.14 * Illuminance (1 lm)

Tips and Suggestions

Below are some suggestions to get the most out of a physically based lighting workflow:

If after placing a light the image goes white, then the auto exposure range may be too limited. Consider increasing the Auto Exposure Max EV100 (and Histogram Max EV100).

If reflective surfaces have artifacts like black patches, the SceneColor buffer might be overflowing. To fix it, either enable Apply Pre-Exposure before writing to the scene color in the Project Settings, or reduce the brightness of lights in the scene.

Don't forget that there are some default Post Process settings already applied to the scene (even when there is no Post Process Volume present). These default settings may affect the camera settings in unexpected ways. It is recommended to place a Post Process Volume in the scene so that you can change those settings as needed.

If you change the Project Settings to use the extended default luminance range, it will break existing exposure configurations. You will have to migrate / reconfigure manually the settings for those assets so that it's safe to do it from the start of your process.

Auto exposure histogram can suffer from stability issues where a small change in the scene generates a slightly different exposure value. To workaround this issue, reduce the Histogram Min and Max range around the actual usage in the scene. To see the usage, enable the Visualize HDR show flag.

General Considerations

Some special care must be taken to avoid default value propagation issues between assets and instances. It's recommended that any light instanced from another light (through Blueprints or default objects) keeps the same light unit as their parent. Otherwise, ones already in use should not have their units changed. Doing this will guarantee that changing the default values will have the expected behavior and propagate to instances correctly and help prevent breaking existing instances.

The default project Light Units for Point, Spot, and Rect Lights can be specified in Project Settings > Rendering > Default Settings.



Feature Limitations

Using Lighting Scenarios

Unreal Engine has support for using different Precomputed Lighting Scenarios in levels. This allows a single level to store and display multiple lighting setups, giving you the flexibility of dynamic lighting, but at the fixed cost of pre-computed lighting. Having the ability to change between different Precomputed Lighting Scenarios is of particular importance for Virtual Reality (VR) or Architectural Visualization projects that require high quality renderings with the benefits of fast performance measures. As you read through this reference, you'll learn how to use Precomputed lighting in your projects.

Day Scenario

Night Scenario

In the above image; the Directional Light, Sky Light, and Skybox have been placed in a Lighting Scenario level called Day Scenario. The Spotlights for the streetlights have been placed in a different Lighting Scenario level called Night Scenario.

Feature Limitations

While Precomputed Lighting scenarios have a lot of advantages, there are some disadvantages and limitations that you'll need to be aware of while using them. In the following section, you'll go over some of these limitations and how you can avoid (or work around) them.

Only one Lighting Scenario level should be visible at any time in a game.

When a Lighting Scenario level is present, Lightmap data from all Sublevels will be placed inside of it so that only the Day Scenario Lightmaps are loaded when it's daytime. As a result, Lightmaps will no longer be streamed by Sublevels.

Sublevel Lightmap data is stored in the Lighting Scenarios BuiltData package. Registering Reflection Captures from other Sublevels modifies the active lighting scenario's BuiltData. Loading a sublevel twice and only loading a lighting scenario's BuiltData once will produce the following error:

Using Lighting Scenarios

To use Lighting Scenarios in your project, you will need to do the following:

First go to Window > Levels to open up the Levels Manager.



With the Levels Manager open, right-click on a Sub level in the Levels menu, go to Lighting Scenario, and select the Change to Lighting Scenario option to make the level a Lighting Scenario level.



When a Lighting Scenario level is visible, its Lightmaps will be applied to the world.

Make sure the Level Streaming method is set to Blueprint by right-clicking on the Sublevel, going to Change Streaming Method, and selecting Blueprint (if it's not already selected).



Now place any light or Static Meshes your project needs into either of the lighting levels and then build each level's lighting as you would with any other level.



Once the lighting has finished building, open up the Blueprint of the Persistent Level and then add a Load Stream Level (by name) node, connecting it to the Event Begin Play node.



Connect the Event Begin Play node to the Load Stream Level node and then input the name of the Level you want to load. Also, make sure to check both Make Visible After Load and Should Block on Load to make sure you can see the newly loaded level.



Press the Play button to launch the project and when the first level loads, it should now be using the Day level lighting. To use Night level lighting, you can use the same setup, but you'll need to change the level name to your night time level (instead of the day time level).





Although there are some notable limitations, using Precomputed Lighting Scenarios can provide your project with many benefits; such as improved performance and the ability to change to baked lighting (to meet your project's needs).

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Precomputed Global Illumination

Precomputed Global Illumination Methods

Precomputed Global Illumination Supporting Topics

Dynamic Global Illumination

Dynamic Global Illumination Topics

Global illumination (sometimes referred to as indirect lighting and indirect illumination) simulates lighting interactions with geometry and material surfaces to add accurate lighting to scenes. Global illumination also takes into account absorption and reflectiveness of the materials in which it interacts.

Simulating the way in which light behaves in a 3D world is handled in one of two ways: using lighting that supports movement and interaction, or precomputed lighting that doesn't require scenes to be overly dynamic or interactive with lighting.

Unreal Engine provides multiple lighting paths to choose from for global illumination solutions, and often they are not exclusive to one another and can be seamlessly blended. For example, it is possible to have both dynamic lighting and baked lighting within the same scene.

For comparison, the list below highlights some of the benefits of choosing a precomputed or dynamic global illumination path for your project:

Ideal for scenes where lighting doesn't need to change.

Performance costs are relative to the memory required to load and store the lightmap textures.

Quality and accuracy of results is set by the texture resolution of the lightmap texture being baked and applied to geometry.

Supports Static Mesh and BSP geometry by default.

Static Meshes require setting up a Lightmap UV to store lighting data.

Can be used in combination with dynamic lighting.

Ideal for times where lighting needs to change, such as turning a light on or off, or a time-of-day system.

Large, open-world environments present impractical requirements for baked lighting (even without a time-of-day system). Bake times, memory usage, texture storage and playback are considerable factors to use dynamic GI.

Performance costs can be significantly more expensive to calculate in real-time depending on the method being used.

Quality and accuracy is often traded with performance. Some Dynamic GI methods are limited by real-time usage.

Supports all geometry types by default.

Can be used in combination with precomputed lighting.

Precomputed Global Illumination

The light baking system in Unreal Engine computes lighting data on the CPU, or GPU, using the Lightmass Global Illumination system. This method of precomputing lighting is used to achieve high-quality results that aren't compromised by real-time limitations by storing the information in textures that are then applied to geometry. This method of lighting cannot be changed dynamically and is ideal for projects where lighting doesn't need to change, or for mobile projects where dynamic lighting is limited.

CPU-based Lightmass uses the CPU with a separate program called Unreal Swarm to compute and generate lighting data. This method can use a single machine or distribute lighting data to build farms.

GPU-based Lightmass uses your current machine's NVIDIA GPU which supports DirectX 12 and ray tracing to compute and generate lighting data.

Precomputed Global Illumination Methods



A run down of all the features and settings of Lightmass.



Learn about the GPU-based system for generating precomputed lighting data.

Precomputed Global Illumination Supporting Topics



Cached indirect lighting samples used for global illumination of dynamic objects and unbuilt scene preview.



Volumetric lighting samples used for global illumination of dynamic objects and unbuild scene previews.



Help increase the quality of baked interior lighting.



An overview of Unreal Swarm, our task distribution system for computationally expensive applications, including Unreal Lightmass, the high-quality static global illumination solver.



High level introduction to Lightmass.

Dynamic Global Illumination

The dynamic global illumination methods in Unreal Engine provide real-time scalable solutions for dynamic indirect lighting in your projects. This means being able to place, move, and light objects in the world without additional costs of baking lighting or having additional set up. Dynamic indirect lighting also means being able to accurately simulate time-of-day transitions or something as simple as turning a light on and off and having light bounce and reflect accurately.



Lumen is a fully dynamic global illumination and reflection system that is designed for next-generation consoles. It is the default dynamic global illumination system and uses multiple ray tracing methods to solve global illumination and reflections at scale.

Screen Space Global Illumination (SSGI) is a post processing effect that generates global illumination for objects within the scene based solely on the current visible objects within the camera view. This is a low-cost and most effectively used in conjunction with existing precomputed or dynamic global illumination methods as an additive effect.

Ray Tracing Global Illumination (RTGI) uses hardware to ray-trace scene lighting for dynamic global illumination. It provides two methods:

This feature is deprecated. It may be removed in a future release.



Brute Force emulates how an offline renderer solves indirect lighting but is slower to render.

Final Gather uses a two-pass algorithm to distribute shading points throughout the scene and to reconnect them to the shading point history to trade quality for performance for real-time ray tracing global illumination.

Dynamic Global Illumination Topics



A high level overview of Lumen's dynamic global illumination and reflections features.



An overview of technical capabilities and specifications of the Lumen Global Illumination and Reflections system.



An overview of dynamic global illumination using a screen space effect.



An overview of the features that use hardware to render real-time ray traced results.



Features for Static and Stationary lights

Features for Stationary Lights Only

Features for Static Lights Only

Getting the Best Quality with Lightmass

Getting the Best Lighting Build Times

Lightmass Settings

Lightmass creates lightmaps with complex light interactions like area shadowing and diffuse interreflection. It is used to precompute portions of the lighting contribution of lights with stationary and static mobility.

Communication between the Editor and Lightmass is handled by the Swarm Agent, which manages the lighting build locally and can also distribute the lighting build to remote machines. The Swarm Agent, which opens minimized by default, also tracks lighting build progress and keeps you up to date with which machines are working for you, what they are working on, and how many threads each one is using.

A sample image of the Swarm Agent is pictured below (the bar near the bottom shows how much of the build is complete).



Features for Static and Stationary lights

Diffuse Interreflection

Diffuse Interreflection is by far the most visually important global illumination lighting effect. Light bounces by default with Lightmass, and the BaseColor term of your material controls how much light (and what color) bounces in all directions. This effect is sometimes called Color Bleeding. Diffuse Interreflection is incoming light reflecting equally in all directions, which means that it is not affected by the viewing direction or position.

Here is a scene built by Lightmass with a single Directional Light and only direct lighting shown. The areas that are not directly visible to the light are black. This is the result without global illumination.



This is what the first diffuse global illumination bounce looks like. Notice the shadow behind the chair on the left, this is called an Indirect Shadow because it is the shadow of the indirect light. The brightness and color of the diffuse bounce depends on the incoming light and the diffuse term of the material that the light interacts with. Each bounce is darker than the previous, since some of the light gets absorbed by surfaces instead of being reflected. The pillar bases get more indirect light than other surfaces because they are closer to the areas in direct light.



This is the second diffuse bounce. The light has become much more attenuated and evenly distributed.



And here is the scene with four diffuse bounces combined. Simulating global illumination creates much more detailed and realistic lighting than manually placing fill lights. Indirect shadows in particular are not possible with fill lights.



Bounced lighting picks up the diffuse color of the underlying material, as you can see below. This is where the term Color Bleeding comes from. Color Bleeding is most noticeable with highly saturated colors. You can exaggerate the effect by raising Diffuse Boost on the Primitive, Material, or Level.





Character lighting

Lightmass places samples in a uniform 3d grid inside the Lightmass Importance Volume at a low resolution, and also on top of upward facing surfaces that characters are likely to walk on, at a higher resolution. Each lighting sample captures indirect lighting from all directions, but not direct lighting.

The first image is a debug visualization of lighting samples placed above the floor, the second image is the same scene in Lit mode. Notice how the samples above the red tapestry picked up the red bounced light. The samples are visualized as a single color, but they really capture lighting from all directions.





The Indirect Lighting Cache then interpolates the indirect lighting for a movable object using these lighting samples. The indirect lighting affects the color of the light environment shadow, but not the direction. Use Show > Visualize > Volume Lighting Samples to preview these in your Viewport.



For more information, see the Indirect Lighting Cache documentation.

The default settings for volume sample placement will result in a large number of samples in a large map. This will cause Indirect Lighting Cache interpolation times to be very large. Use Static Lighting Level Scale to reduce the sample count in large maps.

Movable objects outside the Lightmass Importance Volume will have black indirect lighting.

Ambient Occlusion

Lightmass calculates detailed indirect shadows automatically, but it can be useful to exaggerate indirect shadows for artistic purposes or to enhance the perception of proximity in a scene.

Ambient occlusion is the indirect shadowing you would get from a uniformly bright upper hemisphere, like an overcast sky. Lightmass supports calculating ambient occlusion, applying it to direct and indirect illumination, and then baking it into lightmaps. Ambient occlusion is enabled by default, and can be disabled by unchecking the checkbox Use Ambient Occlusion in the Lightmass Settings of Lightmass under the World Settings.

In the first image is a scene with indirect lighting but no ambient occlusion. In the second image is the same scene with ambient occlusion applied to both the direct and indirect lighting, note the darkening where objects come together.





No Ambient Occlusion

Ambient Occlusion

Property

Description

Visualize Ambient Occlusion

Overrides lightmaps with just the occlusion factor when lighting is built. This is useful for seeing exactly what the occlusion factor is, and comparing the effects of different settings.

Max Occlusion Distance

Maximum distance for an object to cause occlusion on another object.

Fully Occluded Samples Fraction

Fraction of samples taken that must be occluded in order to reach full occlusion. Note that there is also a per-primitive FullyOccludedSamplesFraction, which allows controlling how much occlusion an object causes on other objects.

Occlusion Exponent

Higher exponents increase contrast.









Default AO settings (MaxOcclusionDistance of 200, FullyOccludedSamplesFraction of 1.0, OcclusionExponent of 1.0).

MaxOcclusionDistance of 5. Low frequency occlusion is removed, only occlusion in corners is left.

FullyOccludedSamplesFraction of 0.8. Occlusion is shifted darker across all ranges, any areas that were at 80% occluded or above saturate to black.

OcclusionExponent of 2. The shadowing caused by occlusion darkens from midrange to saturated dark much more quickly, occlusion is pushed into corners.

Ambient occlusion is nearly free as far as lighting build time goes when Num Indirect Lighting Bounces is greater than 0.

Ambient occlusion requires a fairly high lightmap resolution to look good, since it changes quickly in corners.

Preview quality builds do not do a very good job at previewing ambient occlusion, since AO requires pretty dense lighting samples (just like indirect shadows).

Masked shadows

Lightmass takes the opacity mask of BLEND_Masked Materials into account when calculating shadows. The part of the material that gets clipped in the editor viewports also does not cause any shadowing, which allows much more detailed shadowing from trees and foliage.





Features for Stationary Lights Only

Bent Normal sky occlusion

Lightmass generates directional occlusion in the form of a bent normal whenever a Sky Light with Stationary Mobility is enabled.

Distance field shadowmaps

Lightmass computes distance field shadowmaps for Stationary Lights. Distance field shadow maps maintain their curvy shape very well even under lower resolutions; however they do not support area shadowing or translucent shadows.

Features for Static Lights Only

Area lights and shadows

With Lightmass, all lights with Static Mobility are area lights by default. The shape used by Point and Spot Light sources is a sphere, whose radius is set by Light Source Radius under Lightmass Settings. Directional Light sources use a disk, positioned at the edge of the scene. Light source size is one of the two factors controlling shadow softness, as larger light sources will create softer shadows. The other factor is distance from the receiving location to the shadow caster. Area shadows get softer as this distance increases, just like in real life.

In the first image is a Static Directional Light with only static lighting, the penumbra size is the same everywhere. In the second image, Lightmass calculated area shadows whose sharpness is controlled by both the light source size and occluder distance. Notice how the shadow of the pillar is much sharper close to where the pillar meets the ground.





The light source radius for Point and Spot Lights is drawn in yellow wireframe, while the influence radius is drawn in teal. In most cases, you will want to make sure the light source does not intersect any shadow casting geometry, or the light will be emitting on both sides of that geometry.



Translucent shadows

Light passing through a translucent material that is applied to a static shadow casting mesh will lose some energy, resulting in a translucent shadow.



The amount of light passing through the material is called Transmission, and ranges between 0 and 1 for each color channel. A value of 0 would be fully opaque, and a value of 1 would mean that the incident light passes through unaffected. There is no material input for Transmission, so currently it is derived from the other material inputs as follows:

Lit materials

BLEND_Translucent and BLEND_Additive: Transmission = Lerp(White, BaseColor, Opacity)

BLEND_Modulate: Transmission = BaseColor

Unlit materials

BLEND_Translucent and BLEND_Additive: Transmission = Lerp(White, Emissive, Opacity)

BLEND_Modulate: Transmission = Emissive

This means that at an opacity of 0, the material will not filter out incident lighting and there will be no translucent shadow. At an opacity of 1, incident lighting will be filtered by the material's emissive or Base Color (depending on whether it is lit). Note that indirect lighting will sometimes wash out the translucent shadows and make them less saturated than the emissive or diffuse of the translucent material.

There are several factors controlling translucent shadow sharpness.

In the first image, a large light source was used (directional light with a Light Source Angle of 5) and in the second, a small light source was used (Light Source Angle of 0).





In the first image, a small light source was used, but the lightmap resolution was too low to capture the sharp translucent shadows. In the second image, the material was exported at too low of a resolution (controlled by Export Resolution Scale in the Material Editor) to capture the sharp shadows.





Indirect light is also affected by Translucent Materials. The window in this image filters incoming light based on its Transmission, and that light then bounces around the scene with its color modified.



Translucent Materials currently do not scatter light, so they will not bleed color onto objects around them.

The first diffuse bounce is currently not affected by translucent shadows. This means that first bounce indirect light passing through a translucent material will not be filtered by the material's Transmission.

Refraction (caustics from transmission) is currently not supported.

Getting the Best Quality with Lightmass

Making lighting noticeable

During rendering, lit pixel color is determined as BaseColor * Lighting, so base color directly affects how visible the lighting will be. High contrast or dark diffuse textures make lighting difficult to notice, while low contrast, mid-range diffuse textures let the lighting details show through.

Compare the lighting clarity between the scene in the first image built with mid-range diffuse textures, to the scene in the second image also built with Lightmass but with noisy, dark diffuse textures. Only the most high-frequency changes are noticeable in the scene in the second image, like the shadow transitions.





The Unlit view mode is useful for viewing the Diffuse term. The scene in the first image looks flatter and more monotone in the Unlit view mode, which means the lighting is doing all the work and variations in final pixel color are mostly due to lighting differences. (To get good lighting, your scene should look flat and boring in the Unlit view mode.) Baking lighting and macro features into the diffuse textures will counteract the lighting.





Using the editor's color picker on several parts of the unlit image, we can see that the scene in the first image has diffuse values around 0.5, while the scene in the second image has diffuse values around 0.08. Looking at the histogram of these unlit images in Photoshop gives a good idea of the distribution of the diffuse textures.

Photoshop shows you color values in gamma space, so a value of 186 (.73) is actually halfway between black and white, NOT a value of 127 (.5).* The first image shows what the histogram should look like to get noticeable lighting.



Avoid ambient lighting! Ambient lighting like the Ambient cubemap adds a constant ambient term to your level, which reduces contrast in indirectly lit areas.

Setup lights so that there is high contrast between the directly lit areas and indirectly lit areas. The contrast will make it easier to pick out where shadow transitions are and will give your level a better sense of depth.

Setup lights so that the bright areas are not too bright, and the dark areas are not completely black, but still have detail noticeable. It is important to check out the dark areas on the final target display.

Improving lighting quality

Using texture lightmaps with high resolution is the best way to get detailed, quality lighting. Using high lightmap resolution has the downsides of taking up more texture memory and increasing build times, so it is a tradeoff. Ideally, most of the lightmap resolution in your scene should be allocated around the high visual impact areas and in places where there are high frequency shadows.

Lightmass Solver settings are automatically set based on what quality of build is requested in the Lighting Build Options dialog. Production should give good enough quality that the artifacts are not clearly noticeable with a diffuse texture applied.

Getting the Best Lighting Build Times

There are several ways to improve your Lightmass build times:

Only have high resolution lightmaps in areas that have high-frequency (quickly changing) lighting. Reduce the lightmap resolution for Brush surfaces and Static Meshes that are not in direct lighting or affected by sharp indirect shadows. This will give you high resolution shadows in the areas that are most noticeable.

Surfaces that are never visible to the player should be set to the lowest possible lightmap resolution.

Use a Lightmass Importance Volume to contain the areas that are most important (just around the playable area).

Optimize the lightmap resolutions across the map so that build time for meshes is more even. The lighting build can never be faster than the slowest single object, regardless of how many machines are doing the distributed build. Avoid large continuous meshes that surround a large part of the level and with high lightmap resolution. You will get better build times if you break these up into more modular pieces, especially on machines with many cores.

Meshes with a lot of self-occlusion will take longer to build, for example a rug with many layers parallel to each other will take much longer to build than a flat floor.

The Lighting Build Info dialog is a very important tool for improving lighting build times. First, build lighting in the level that you want to see stats for. Then, open the dialog under Build > Lighting Info > Lighting StaticMesh Info. Change the drop down to Lighting Build Info. This will show a sorted list of meshes and how long they took to compute lighting for.



Lightmass Settings

Lightmass Importance Volume

Many maps have meshes out to the edge of the grid in the editor, but the actual playable area that needs high quality lighting is much smaller. Lightmass emits photons based on the size of the level, so those background meshes will greatly increase the number of photons that need to be emitted, and lighting build times will increase. The Lightmass Importance Volume controls the area that Lightmass emits photons in, allowing you to concentrate it only on the area that needs detailed indirect lighting. Areas outside the importance volume get only one bounce of indirect lighting at a lower quality.

An overhead wireframe view of a multiplayer map is shown in the first image. The actual playable area that needs high quality lighting is the small green blob at the center.

In the second image, a close-up of the playable area of the multiplayer map is shown, with the correctly setup Lightmass Importance Volume selected. The Lightmass Importance Volume reduced the radius of the region to light from 80,000 units to 10,000 units, which is 64x less area to light.





You can add a Lightmass Importance Volume to a level by dragging a Lightmass Importance Volume object from the Volumes tab of the Place Actors panel into the level then scaling it to the needed size.



You can also convert a Brush into a Lightmass Importance Volume by clicking the Convert Actor drop down box inside the Details panel under Actor.



After clicking the drop down box, a menu will appear where you can select the type of Actor to replace the Brush with.



If you place multiple Lightmass Importance Volumes, most of the lighting work will be done with a bounding box that contains all of them. However, Volume Lighting Samples are only placed inside the smaller volumes.

World Settings

Lightmass settings can be adjusted inside the World Settings panel under the Lightmass section.



You can access World Settings by clicking the Settings icon from the main Toolbar on the right side of Editor and selecting World Settings.



Property

Description

Static Lighting Level Scale

Scale of the level relative to the scale of the engine, which is 1 Unreal Unit = 1cm. This is used to decide how much detail to calculate in the lighting and smaller scales will greatly increase build times. For a huge level, larger scales around 2 or 4 can be used to lower build times.

Num Indirect Lighting Bounces

Number of times light is allowed to bounce off surfaces, starting from the light source. 0 is direct lighting only, 1 is one bounce, etc. Bounce 1 takes the most time to calculate, followed by bounce 2. Successive bounces are nearly free, but also do not add very much light, as light attenuates at each bounce.

Indirect Lighting Quality

Scales the sample counts used by the Lightmass GI solver. Higher settings result in fewer solver artifacts (noise, splotchiness) at much increased build times. Note that this will not affect artifacts due to using lightmaps (texture seams, compression artifacts, texel shapes).

Indirect Lighting Smoothness

Higher values cause the indirect lighting to be smoothed more, which can hide solver noise, but also causes detailed indirect shadows and Ambient Occlusion to be lost. It can be useful to lower this somewhat (.66 or .75) when increasing Indirect Lighting Quality for highest quality.

Environment Color

Color that rays which miss the scene will pick up. The environment can be visualized as a sphere surrounding the level, emitting this color of light in each direction.

Environment Intensity

Scales Environment Color to allow an HDR environment color.

Diffuse Boost

Scales the diffuse contribution of all materials in the scene. Increasing DiffuseBoost is an effective way to increase the intensity of the indirect lighting in a scene. The diffuse term is clamped to 1.0 in brightness after DiffuseBoost is applied, in order to keep the material energy conserving (meaning light must decrease on each bounce, not increase). If raising Diffuse Boost does not result in brighter indirect lighting, the diffuse term is being clamped and the Light's Indirect Lighting Scale should be used to increase indirect lighting instead.

Volume Lighting Method

Technique to use for providing precomputed lighting at all positions inside the Lightmass Importance Volume.

Use Ambient Occlusion

Enables static Ambient Occlusion to be calculated by Lightmass and built into your lightmaps.

Generate Ambient Occlusion Material Mask

Enables generating textures storing the AO computed by Lightmass. These can be accessed through the Precomputed AO Mask material node, which is usefull for blending between material layers on environment assets. Be sure to set Direct Illumination Occlusion Fraction and Indirect Illumination Occlusion Fraction to 0 if you only want the Precomputed AO Mask!

Visualize Material Diffuse

Override normal direct and indirect lighting with just the material diffuse term exported to Lightmass. This is useful when verifying that the exported material diffuse matches up with the actual diffuse.

Visualize Ambient Occlusion

Override normal direct and indirect lighting with just the AO term. This is useful when tweaking ambient occlusion settings, as it isolates the occlusion term.

Compress Lightmaps

Enables compressing lightmap textures. Disabling lightmap texture compression will reduce artifacts but increase memory and disk size by 4x. Use caution when disabling this.

Volumetric Lightmap Detail Cell Size

Size of an Volumetric Lightmap voxel at the highest density (used around geometry), in world space units. This setting has a large impact on build times and memory, use with caution. Halving the Detail Cell Size can increase memory by up to a factor of 8x.

Volumetric Lightmap Maximum Brick Memory Mb

Maximum amount of memory to spend on Volumetric Lightmap Brick data. High density bricks will be discarded until this limit is met, with bricks furthest from geometry discarded first.

Volumetric Lightmap Spherical Harmonic Smoothing

Controls how much smoothing should be done to Volumetric Lightmap samples during Spherical Harmonic de-ringing. Whenever highly directional lighting is stored in a Spherical Harmonic, a ringing artifact occurs which manifests as unexpected black areas on the opposite side. Smoothing can reduce this artifact. Smoothing is only applied when the ringing artifact is present. 0 = no smoothing, 1 = strong smooth (little directionality in lighting).

Volume Light Sample Placement Scale

Scales the distances at which volume lighting samples are placed. Volume lighting samples are computed by Lightmass and are used for GI on movable components. Using larger scales results in less sample memory usage and reduces Indirect Lighting Cache update times, but less accurate transitions between lighting areas.

Direct Illumination Occlusion Fraction

How much of the AO to apply to direct lighting.

Indirect Illumination Occlusion Fraction

How much of the AO to apply to indirect lighting.

Occlusion Exponent

Higher exponents increase contrast.

Fully Occluded Samples Fraction

Fraction of samples taken that must be occluded in order to reach full occlusion.

Max Occlusion Distance

Maximum distance for an object to cause occlusion on another object.

Force No Precomputed Lighting

This essentially deactivates Lightmass' ability to produce light and shadowmaps, forcing the level to only use dynamic lighting.

Packed Light and Shadow Map Texture Size

Maximum size of textures for packed light and shadow maps.

Light Settings

Below are Lightmass settings that can be adjusted inside the properties of a light under the Lightmass section.



Property

Description

Light Source Angle

For Directional Lights Only, determines the angle that the light's emissive surface extends relative to a receiver, affects penumbra sizes.

Indirect Lighting Saturation

0 will result in indirect lighting being completely desaturated, 1 will be unchanged.

Shadow Exponent

Controls the falloff of shadow penumbras, or how fast areas change from fully lit to fully shadowed.

Use Area Shadows for Stationary Light

Whether to use area shadows for stationary light precomputed shadowmaps. Area shadows get softer the further they are from shadow casters, but require higher lightmap resolution to get the same quality where the shadow is sharp.

Primitive Component Settings

Below are Lightmass settings that can be adjusted on a Brush added from the Geometry tab of the Place Actors panel. These options are found under the Details panel of the Brush.



Property

Description

Use Two Sided Lighting

If checked, this object will be lit as if it receives light from both sides of its polygons.

Shadow Indirect Only

If checked, this object will only shadow indirect lighting. This is useful for grass, since the geometry that is rendered is just a representation of the actual geometry and does not necessarily cast accurately shaped shadows. It is also useful for grass because the resulting shadows would be too high frequency to be stored in precomputed lightmaps.

Use Emissive for Static Lighting

If true, allow using the emissive for static lighting.

Use Vertex Normal for Hemisphere Gather

Typically the triangle normal is used for hemisphere gathering which prevents incorrect self-shadowing from artist-tweaked vertex normals. However in the case of foliage whose vertex normal has been setup to match the underlying terrain, gathering in the direction of the vertex normal is desired.

Emissive Boost

Scales the emissive contribution of all materilas applied to this object

Diffuse Boost

Scales the diffuse contribution of all materials applied to this object.

Fully Occluded Samples Fraction

Fraction of AO samples taken from this object that must be occluded in order to reach full occlusion on other objects. This allows controlling how much occlusion an object causes on other objects.

Base Material Settings

Below are the Lightmass settings that can be adjusted inside a Material for the Base Node under the Details panel.

For more information on the Material Editor, see the Material Editor User Guide.



Property

Description

Diffuse Boost

Scales the diffuse contribution of this material to static lighting.

Export Resolution Scale

Scales the resolution that this material's attributes are exported at. This is useful for increasing material resolution when details are needed.

Cast Shadow as Masked

For translucent materials, treats the material as if it is masked for the purposes of shadow casting.

Enabling GPU Lightmass

Unreal Engine 5.1 Driver Requirements

Additional Requirements for Setting Up GPU Lightmass

Reducing GPU Timeout Detection and Recovery Crashes

Disabling Real-Time Ray Tracing Features

Configuring GPU Memory

Using Virtual Texture Lightmaps for In-Editor Previewing

Enabling Multiple GPUs for Building Lighting

Using GPU Lightmass

GPU Lightmass Baking Modes

Interactive Baking

Using GPU Lightmass Speed Modes

GPU Lightmass Settings

Setting Up Lightmap UVs and their Resolutions

Controlling the Number of Light Bounces

Choosing a Denoising Option

Limitations of GPU Lightmass

GPU Lightmass (GPULM) is a light-baking solution that precomputes complex light interactions from lights which have their mobility set to Stationary or Static, and stores that data in generated lightmap textures that are applied to scene geometry. This system of baking lighting into textures is similar to the CPU-based Lightmass Global Illumination system. However, using the GPU to generate and build lighting data means that you can leverage the latest ray tracing capabilities with DirectX 12 (DX12) and Microsoft's DXR framework.

GPU Lightmass significantly reduces the time it takes to calculate, build, and generate lighting data for complex scenes, achieving speeds comparable to those of distributed builds using Swarm with the CPU-based Lightmass. Additionally, GPULM offers new workflows with interactivity that enables you to edit the scene, then recalculate and rebuild lighting on-the-fly. This workflow is not possible with the CPU-based Lightmass system.

Enabling GPU Lightmass

Use the following steps to enable GPU Lightmass in your projects.

Open the Plugins tab from the Edit > Plugins menu. Under the Built-In > Editor category, locate and enable GPU Lightmass.



A prompt to restart the Unreal Editor will appear after you enable GPU Lightmass. To save time, modify the following Project Settings before you restart the Editor.

Open the Project Settings window from the Edit > Project Settings menu:

Under the Engine > Rendering category, enable the following:

Hardware Ray Tracing > Support Hardware Ray Tracing



Ray Traced Shadows and Ray Traced Skylight are not needed for GPU Lightmass to function. Leave these features disabled unless you need them for your project.

Virtual Textures > Enable Virtual Texture Support

Virtual Textures > Enable Virtual Texture Lightmaps

Under the Platforms > Windows category, set the following:

Targeted RHIs > Default RHI: DirectX 12

Restart the editor for these changes to take effect.

Unreal Engine 5.1 Driver Requirements

For this release, we recommend using the NVIDIA driver 522.25. Later versions of the driver are known to cause issues.

Additional Requirements for Setting Up GPU Lightmass

The following are additional suggestions to best work with GPU Lightmass in your projects.

Situations where you have a complex scene that puts the GPU under heavy load can cause a timeout delay (or TDR). This subsequently causes a crash to occur within Windows 10. This type of crash impacts not only Unreal Engine but anything on your machine using the GPU. You will typically see a message similar to the one below.



It is possible to prevent, or reduce, occurance of these types of crashes by extending the time it takes for the GPU to timeout, giving your GPU time to potentially recover without causing the Editor to close.

See the Movie Render Queue documentation for details on how to adjust the timeout delay and recovery settings within Windows 10.

Ray Tracing features require a Windows 10 development environment with DirectX 12 and a Ray Tracing-capable NVIDIA GPU. For additional information, see our Ray Tracing features documentation for a full list of requirements.

GPU Lightmass leverages Microsoft's DXR API for ray tracing, which requires DirectX 12. While ray tracing is required for GPU Lightmass to work, it does not require any additional ray-tracing features, including ray-traced shadows, ambient occlusion, and reflections.

Unless you explicitly want to use those ray tracing features along with baked lighting, it is best to disable all these features. If you require baked lighting with ray traced features, you can have a scene containing both static and dynamic lights. Use the following console command to disable ray tracing effects.

Alternatively, you can set this in your project configuration file so that all ray tracing features are disabled when the project loads. Add the following lines to the project's DefaultEngine.ini configuration file located in your project's Config folder. Add these lines under the [/Script/Engine.RendererSettings] section:

GPU Lightmass requires that there be enough GPU memory available to account for its overhead. With that in mind, the following considerations affect the success of using GPULM to bake complex scenes.

There must be enough GPU memory to store the entire scene in memory at the lowest level of detail (LOD) mesh, that is, the highest quality LOD mesh.

GPULM does not currently take LODs into consideration while baking. See the Limitations of GPU Lightmass section of this page for more details.

The Virtual Texture system can require significant memory use during light builds. This largely depends on the complexity of your scene and its size.

There must be enough CPU memory to store all generated lightmaps in RAM. The GPU can swap out lightmaps to the CPU's RAM, but lightmaps are not saved to disk until the entire light bake is completed.

DX12 generally uses more GPU memory than DX11. If you have a scene that was pushing the limits of your GPU memory in DX11, you may find it difficult to use in DX12 without some sacrafices, due to additional overhead from ray tracing and virtual texture requirements.

GPULM has its own memory usage requirements for optional settings, like Irradiance Cache.

The CPU-based Lightmass system requires a significant amount of memory for large scenes, which could be problematic for light baking. Often using a distributed build with Swarm could mitigate these types of issues. With GPULM, currently the only solution when running out of memory is to optimize the scene by reducing geometric or texture detail, or to upgrade to a GPU with more memory.

Enabling the Virtual Texture system with Virtual Texture Lightmaps allows for lightmaps to be generated and stored as virtual textures. This has the added benefit of allowing for light builds to update in the level viewport in real time. It also enables editing as the scene is being built instead of having to cancel or wait for the build to complete.

GPULM does not require the Virtual Texturing system to be enabled to simply build lighting but does require it for the interactive and real-time editing functionality. If you do not intend to use virtual texturing in your project or do not require interactive preview, you can forego enabling these and save some overhead while working in the editor.

Windows 10 version 2004 or newer is required for multi-GPU support.

Multiple GPUs to compute lighting for your project is supported when using an NVIDIA SLI-based GPU that also supports ray tracing. Multi-GPU support is enabled with the following steps.

Your GPUs must be connected with NVLink bridges and you must enable SLI in the NVIDIA Control Panel.

In the Unreal Engine DefaultEngine.ini file located in your [Engine Install Path]/Engine/Config folder, under the [/Script/Engine.RendererSettings] section, enable multiple GPUs by adding r.AllowMultiGPUInEditor=1.

Pass the command line argument -MaxGPUCount=[n] — where n represents the number of GPUs available through SLI — when launching the editor. For example, -MaxGPUCount=2 would use two GPUs while in multi-GPU mode to compute lighting.

Optionally, you can create a shortcut for UnrealEditor.exe and in the Properties settings, set the add -MaxGPUCount=[n] to the Target line.



Once the editor starts, you can confirm you are using Multi-GPU mode by opening the Output Log and searching the log for message:

Performance when using multiple GPUs can decrease the build completion times on average. For example, in medium-sized test scenes using two RTX-2080TIs, build times were found to be about 1.7x faster on average when volumetric lightmaps are not heavily used. Improved speeds for build completion are dependent on a number of factors, such as scene size and complexity, engine feature multi-GPU support, and the number of GPUs being utilized.

GPU Lightmass multi-GPU support is ideally suited for architectural and virtual production-type environments that rely on a single area. Large game-sized levels might encounter memory and virtual texture limitations depending on their complexity and the amount of VRAM available on the GPU. It is possible for architectural and virtual production environments to reach the same limitations as game-size levels if they have a lot of complexity to their design and set up. Multi-GPU limitations:

Volumetric Lightmap calculation is not yet supported. Scenes that have a significant Volumetric Lightmap computation will see less overall performance gains.

Irradiance cache is generated locally on each GPU. Depending on the content, you may have slight shading differences between different baked tiles. This can be addressed by increasing the Irradiance Cache Quality, or by disabling Use Irradiance Caching entirely.

Texture encoding and denoising are run on the CPU, and are not affected by multi-GPU.

Using GPU Lightmass

GPU Lightmass has its own panel which you can access through the Level Editor's toolbar. Under the Build dropdown menu, select GPU Lightmass.



You can dock the GPU Lightmass panel within the Editor, similarly to other panels. Unlike CPU Lightmass, which has most of its properties in World Settings, almost all the settings that affect GPU Lightmass are found within the plugin's own panel, pictured below.



Once you have configured your settings, click Build Lighting to start a bake.



Use the Viewport Realtime checkbox to toggle the viewport's realtime mode. The speed at which GPU Lightmass builds lighting is significantly increased when the viewport has realtime mode disabled. See the Using GPU Lightmass Speed Modes section of this page for more details.



GPU Lightmass Baking Modes

GPU Lightmass includes two modes with which to bake lighting: Full Bake and Bake What You See (BWYS).



Full Bake mode renders the full lightmap resolution for every object in the scene as lighting is being calculated and built. The results aren't visible until the build completes.

Bake What You See mode offers greater flexibility in that you only build lighting for what is visible within the viewport instead of the entire scene. It also enables interactivity during the light building process to recalculate lighting as changes are being made, when the viewport's real-time mode is enabled.

Both of these baking modes are view-dependent, meaning that they first prioritize objects within the view before moving onto other objects in the scene.

In Full Bake mode, GPULM uses the following procedures.

Every object within the scene is considered, and objects within the current view are prioritized.

Lighting is baked in texture space at an object's full lightmap resolution, and completed lightmap tiles are sent to the Virtual Texture system to update the display.

Once all objects have been calculated and a lightmap rendered, encoding takes place and saves the data automatically.

Bake What You See mode offers a non-destructive way of interactively working within a scene with lighting results being calculated (and recalculated) in real-time. It encourages on-the-fly adjustments in areas of your scene where lighting is actively being worked on. Because of this interactivity, the BWYS workflow for light builds differs from that of Full Bake as follows.

The Runtime Virtual Texture system determines visible tiles at the mipmap level necessary to resolve on screen.

Lighting is baked in texture space at the resolved mipmap resolution of each tile within the camera view.

Once all on-screen tiles have completed, BWYS waits indefinitely for the scene or viewport camera to update.

Pressing the Save button starts encoding the final lightmaps. A completed lighting build is not produced for the scene if you choose to save the results; only parts of the scene which were visible on screen have their lighting data ready to be stored and saved.

Pressing Save does not end the light bake, it only saves any encoded lightmap data that has been generated up to this point. Instead, press Cancel to stop the process.

Interactive baking is readily available for both Full Bake and BWYS modes, prioritizing visible virtual texture tiles that have been mapped to the current camera view; moving the camera will re-prioritize tiles for the current view. While interactive baking is used for both light baking modes, it is most useful used in conjunction with BWYS mode.

Starting BWYS mode kicks off a lighting build that only completes when it is manually stopped. This mode only considers and builds lighting for objects within the camera view. Moving the camera around the scene, changing position or adding/removing objects from the scene, or changing properties of scene Actors cause lighting to be recalculated in real-time. Because this mode requires the lighting results to be manually saved, it is a non-destructive way to work if lighting was previously built for the scene.

One benefit of GPU Lightmass is that it leverages virtual texturing during light bakes. This enables lighting to be built and displayed in real-time in the editor viewport. It also works progressively if the scene is being edited at the same time and updates the scene lighting accordingly. The drawback to using in-editor previewing in real time is that there is additional overhead of re-rendering frames in the scenes to update the visible result. Disabling this overhead frees up the GPU to work more efficiently and quicker.

When the state of the Level Viewport's Realtime mode controls the two speeds at which GPULM operates. When Realtime mode is:

On: GPU Lightmass uses slow mode because of the additional overhead of rendering frames in real-time.

Off: The overhead of rendering the scene in real-time is removed, which significantly increases the speed of lighting builds.

There are three ways to toggle the Level Viewport Realtime mode.

In the GPU Lightmass panel, use the realtime viewport checkbox to toggle the Realtime mode of the viewport.



Use the Level Viewport Options dropdown menu to toggle Realtime mode.



Keyboard shortcut Ctrl + R.

In addition to the Realtime mode toggle for the viewport, GPULM also includes settings to increase the speed of lighting builds using some built-in parameters.



Realtime Workload Factor is a multiplier that can improve the speed of a lighting build when Realtime mode is toggled On in the viewport. Using too high a value can cause the editor to become unresponsive in scenes with lots of geometry.

Non-Realtime Workload Factor is a multiplier that can improve speed of lighting builds when Realtime mode is toggled Off.

The Workload Factor options are not a guarantee that your builds will instantly become faster and these options should be used with caution. The multipliers determine the size of the chunks of work sent to the GPU, and the effectiveness of this size is one of many factors that determines the final speed on the GPU. For example, increasing Non-Realtime Workload Factor can make a fast bake go slower in some projects. There is no hard and fast rule for settings that will work in every situation.

GPU Lightmass Settings

GPU Lightmass contains most of its settings within its own panel.



Properties

Description



General



Show Progress Bars

If true, a green progress bar is drawn within each tile as it renders. A red bar indicates the First Bounce Ray Guiding is in progress. Bars may appear black in very bright scenes that have their exposure turned down.

Mode

Choose the baking mode that best fits your development needs:

Full Bake: This mode renders the full lightmap resolution for every object in the scene.

Bake What You See: This mode renders only the virtual texture tiles for objects in view, at the mip level determined by the Virtual Texture system. The camera can be moved to render more tiles. This mode only saves its results if you press the Save button.



Denoising



Denoise when

When enabled, denoising will take place on the CPU after rendering. When deciding when denoising of the lightmap bake should happen, choose between the following options:

None: Lightmaps will not have any denoising applied to them.

On Completion: The entire lightmap will have denoising applied when the bake is finished.

During Interactive Preview: Each tile is denoised as it finishes, which is useful for previewing parts of a scene but is less efficient.

Denoiser

Intel Open Image Denoise: The default option uses the Intel Open Image Denoise library to reduce the overall amount of residual noise in the rendered output.

Simple Firefly Remover: An alternative denoiser that specifically targets firefly artifacts, or excessively bright specks sometimes caused by small intense light sources.



Global Illumination



GI Samples

The total number of ray paths executed per texel across all bounces against surfaces. This should be set to the lowest value that gives artifact-free results with the denoiser.

Stationary Light Shadow Samples

The number of samples used for lights that have their mobility set to Stationary. The shadows are calculated and stored separately from global illumination.

Use Irradiance Caching

Enable this for interior scenes, to achieve more physically correct global illumination intensities (with some biasing). If not enabled, results may appear darker than expected. Disable for exterior scenes.

Use First Bounce Ray Guiding

When Use Irradiance Caching is enabled, this option searches the hemisphere over each first bounce sample to find the brightest directions to weigh the rest of the samples towards. It improves results for interior scenes with specific sources of light, such as a window. The quality of this pass is controlled with the Trial Samples setting.



Volumetric Lightmap



Quality Multiplier

Enables you to allocate more Global Illumination samples into Volumetric Lightmaps to reduce noise.

Detail Cell Size

Sets the size of the Volumetric Lightmap voxel at the highest density used around geometry in the scene, in world space units.



Irradiance Caching



Quality

The number of samples per Irradiance Cache cell.

Agressive Leak Prevention

When enabled, use Irradience Cache Backface Detection to prevent light leaks at the cost of more fireflies and slower speed. Recommended when Irradience Cache Quality is >=256.

Size

The size of each Irradiance Cache cell. Smaller sizes will be slower but more accurate.

Corner Rejection

Provides better control over rejection of Irradiance Cache entries around corners, helping reduce light leaking and artifacts that can happen.

Debug: Visualize

When enabled, the Irradiance Cache cells are visible. It's useful for setting the Irradiance Cache cell size and its quality. The visualization may appear black in very bright scenes that have their exposure turned down.



First Bounce Ray Guiding



Trial Samples

The number of samples used for First Bounce Ray Guiding, which are thrown away before sampling for lighting.



System



Realtime Workload Factor

Control the baking speed with this multiplier when the viewport has Realtime mode enabled.

Non-Realtime Workload Factor

Control the baking speed with this multiplier when the viewport has Realtime mode disabled.

Lightmap Tile Pool Size

The pool of visible tiles which GPU Lightmass manages for calculations. The pool size should be set based on the size of the viewport and how many tiles will be visible on screen at once. Increasing the pool size increases GPU memory usage.

The Volumetric Lightmap Detail Cell Size sets the size of a Volumetric Lightmap voxel at the highest density around geometry in the scene. Decreasing the size of the voxel can significantly increase the time it takes to build lighting and the amount of memory that gets used. In some cases, halving this value can increase memory by up to a factor of eight.



Baking lighting requires that each Static Mesh have its own Lightmap UV and that the UV charts (also called UV islands) are all contained within the 0-1 texture space and have no overlapping or wrapping pieces. This ensures that when lighting is calculated that no artefacts occur due to a bad lightmap UV.

You can learn more about setting up lightmap UVs and generating them within Unreal Engine by taking a look at these pages:

Unwrapping UVs for Lightmaps

Auto-Generating Lightmap UVs

Setting up a good Lightmap UV is the first step to getting a quality light bake for your object's geometry. Next, it's important to make sure that the lightmap texture applied to your geometry has enough resolution to capture all the necessary light and shadow detail. This means changing the lightmap resolution per object, as needed. You can do this in one of two ways:

Set the Light Map Resolution of the object using the Static Mesh Editor.



Select a Static Mesh Actor in the scene and, in the Details panel under the Lighting category, set a new lightmap resolution for this individual Actor using its Overridden Light Map Res property.



The number of light bounces within any given scene is not controllable. Instead, GPULM uses a Russian Roulette algorithm, which takes into account various probabilities and weighting calculations to determine how many bounces any given ray being cast will take. This also means that light bounces unlikely to contribute to indirect lighting and illumination of the scene are more likely to be terminated.

The GI Samples property of GPULM controls the maximum number of path-traced segments for each texel (or pixel within a texture map), including spatial samples and bounce segments. Increasing the number of GI Samples increases the number of both the spatial samples and (potentially) the depth samples.

GPU Lightmass relies on denoising methods provided by Intel's Open Image Denoise library to remove noise and smooth the results of the final lightmap renders.

There are three options to choose from when considering how you want your light bakes to be denoised. Use the Denoise when dropdown to make your selection:



None: No denoising is applied to the lighting render. This can be useful to determine a number of GI Samples to use for a given scene. For example, if you noticed artifacts being introduced by the denoiser, increasing the samples and possibly other settings, such as Irradiance Cache and First Bounce Ray Guiding, provide the denoiser with higher quality input.

On Completion: Denoises the results of the light build on the CPU after rendering. The entirety of the scene's lightmaps are denoised when the light build is finished.

During Interactive Preview: Denoises each virtual texture tile as it completes. This can be useful for seeing final results more quickly but is less efficient because it requires transferring each tile off the GPU to denoise on the CPU, and then back to the GPU to display.

The comparison below shows a completed light build with and without denoising applied.





Limitations of GPU Lightmass

Below are some of the known limitations of the current implementation of GPULM. This is not an exhaustive list and is intended to give you a rough idea of the support of core features. Keep in mind that some features in this list may never be supported while many will be resolved in future releases of the engine.

Feature

Supported (Yes/No/Partially)

Description

Distributed Baking

N

There are currently no plans to support distributed builds by Swarm Agent for GPULM. The current strategy is to focus on support for multiple GPUs and rely on their power and memory capacity.

Multiple GPU

Yes

Requires NVIDIA cards that support NVLink or SLI.

Translucent Shadows

Y

Translucent and colored translucent shadows are now supported.

World Position Offset

N

Pixel Depth Offset

N

GPULM does not take into account PDO, which could lead to lighting discontinuities.

Stationary Sky Light

N

Support is planned in a future release of the engine.

Lighting Channels

N

Lighting Scenarios

Y

Custom Settings and Properties of Lights

N

The following lights settings are not yet supported with GPULM:

Indirect Lighting Intensity

Source Texture (with exception of Rect Lights)

Some of these settings can be used partially with Stationary lights. The baked GI will not honor the feature, but the dynamic direct lighting from the light source will.

Precomputed Ambient Occlusion

N

Lightmass Portals

N

This is partially handled by the First Bounce Ray Guiding property of GPULM.

Lightmass Importance Volume

Partially

These volumes are not used to make distinction between areas of the scene to control quality. Instead, they are used for determining placement of Volumetric Lightmaps.

Volumetric Lightmaps

Y

These are honored by GPULM. Their placement can be done by using Lightmass Importance Volumes around the level, but it is not required. Settings for Volumetric Lightmap Detail Cell Size and are found in the GPULM panel.. The Volumetric Lightmap is always rendered in full, even when using Bake What You See mode.

Level of Detail Meshes

Y

Lightmass World Settings and Per-Object Settings

N

There are many settings to tweak the results of lightmass for the CPU-based workflow. Most of these settings are not used with GPULM and do not have equivalent features or settings.

How it works

Previewing Unbuilt Lighting



CPU Lightmass generates lightmaps for indirect lighting on static objects, but dynamic objects like characters need a method of receiving indirect lighting as well. This is solved by the Indirect Lighting Cache, which uses samples generated by Lightmass at build-time to calculate the indirect lighting for dynamic objects at runtime.

In the images below, you can see the difference between the dynamic objects rendered with and without the contribution from the indirect lighting cache:



Diffuse lighting in the Elemental level without the Indirect Lighting Cache.



Diffuse lighting with the Indirect Lighting Cache.

How it works

From a high level point of view:

Lightmass places lighting samples throughout the level and computes indirect lighting for them during a lighting build.

When it comes time to render a dynamic object, the Indirect Lighting Cache checks to see if it already has available lighting for that object and uses it if so.

If no lighting was available (the object is new or moved too much), the Indirect Lighting Cache interpolates lighting from the precomputed lighting samples.

Lightmass places the lighting samples on top of upward facing surfaces with high density, and everywhere else with low density. The samples are limited to being within the Lightmass Importance Volume, and they are only placed on static surfaces.



Using Show > Visualize > Volume Lighting Samples to visualize the lighting samples generated by Lightmass.

The goal with this workflow is to require as little content setup as possible. However, sometimes this placement heuristic gives insufficient detail in areas that are floating in space, for example an elevator that characters ride on or a flying section. You can place Lightmass Character Indirect Detail Volumes around those areas to get more detail.

At runtime, the Indirect Lighting Cache will interpolate the lighting samples to positions around each movable object. A movable object is any component with Mobility set to Movable.

Here the torus is a movable Static Mesh and the 5x5x5 interpolation positions are shown.



This interpolation only happens when the object moves enough to invalidate it, hence the cache naming. Note that the positions are quite far from the object's bounds. This is to provide continuous and stable lighting as the object moves through the world. Most objects will effectively get 3x3x3 interpolation resolution. The volume lighting samples store directional indirect lighting which allows normal maps to work.

Previewing Unbuilt Lighting

The Indirect Lighting Cache also allows previewing of objects with unbuilt lighting. It works pretty well for smaller objects, but not very well for large meshes like buildings or floors. When you move a Static Mesh that had lighting built, it will automatically switch to the Indirect Lighting Cache until the next lighting build.

Here one of the pillars has been duplicated and it gets indirect lighting for previewing instead of being black.





Lightmass Importance Volume

Building

Quality Modes

Lightmass creates lightmaps with complex light interactions like area shadowing and diffuse interreflection. It is used to precompute portions of the lighting contribution of lights with stationary and static mobility.

Lightmass Importance Volume

Many maps have meshes out to the edge of the grid in the editor, but the actual playable area that needs high quality lighting is much smaller. Lightmass emits photons based on the size of the level, so those background meshes will greatly increase the number of photons that need to be emitted, and lighting build times will increase. The Lightmass Importance Volume controls the area that Lightmass emits photons in, allowing you to concentrate it only on the area that needs detailed indirect lighting. Areas outside the importance volume get only one bounce of indirect lighting at a lower quality.



You can add a Lightmass Importance Volume to a level by dragging a Lightmass Importance Volume object from the Volumes tab of the Place Actors panel into the level then scaling it to the needed size.



You can also convert a Brush into a Lightmass Importance Volume by clicking the Convert Actor drop down box inside the Details panel under Actor.



After clicking the drop down box, a menu will appear where you can select the type of Actor to replace the Brush with.



If you place multiple Lightmass Importance Volumes, most of the lighting work will be done with a bounding box that contains all of them. However, Volume Lighting Samples are only placed inside the smaller volumes.

Building

Click the Build in the Main menu panel and select Build Lighting Only, also you can choose Build All Levels.



A dialog like this will appear at the bottom right of the screen.



Click Keep when it finishes.



And that is it. Depending on the number of lights, quality mode, the size of the level, what portions are contained within a Lightmass Importance Volume, and if other computers are available for the Swarm client to use, this process could take a few minutes or possibly substantially longer.

Quality Modes



These presets are about time versus quality. The Preview setting will render quickly and will give an ok representation of most baked direct lighting, while the Production setting renders more slowly, but gives a more realistic look while also correcting for various light bleed errors.

Production - Looks awesome, takes a while.

High - Looks good, takes some time.

Medium - Looks better, takes a bit longer to calculate.

Preview - Gets the point across, but at least it is fast.

These are just the presets, there are a vast number of settings that can be tweaked to get the desired lighting for your game. See the Lightmass documentation for more info on how to fine tune Lightmass settings.



How It Works

Steps

End Result

Known Issues and Limitations

When gathering lighting, Lightmass can backtrack to Point, Spot and Directional light sources using photons from the Photon Mapping technique. This means that it can find small windows where light is entering from these light types and resolve the incoming lighting with high-quality. However, SkyLights and Emissive meshes don't support photon emission efficiently, so Lightmass can only find the small important lighting features with brute force. This manifests as splotchy artifacts around indoor corners. To help Lightmass better understand where the light should be coming from, you can place Lightmass Portals Actors around the areas that are critical to lighting. In the following document, we will take a look at setting up and using Lightmass Portals in your Unreal Engine projects.

How It Works

From a high-level, Lightmass Portals work in the following manner:

Lightmass Portals are most useful when a scene is lit using a Skylight, HDR image or a Static Mesh that is set to Use Emissive for Static Lighting checked.



Click for full image.

Lightmass Portals are placed and in the level and scaled to fit any open areas that are important to the final lighting.



When Lightmass is building the light, the Lightmass Portals tell Lightmass that more light rays should come from this area yielding higher quality light and shadows.





Steps

To use Lightmass Portals in your projects, you will need to do the following.

From the Place Actors panel, search for Lightmass Portal and then drag the Lightmass Portal Actor into your Level to place it.



Click for full image.

Using the Move, Rotate and Scale tools, position and scale the Lightmass Portal to be about the same size or slightly smaller than the opening or area you want Lightmass to focus more rays towards.



Click the Build in the Main menu panel, select Build and change the Lighting Quality to Production.



When that has all been completed, click the Build in the Main menu panel and select Build All Levels to start the Lightmass lighting build.



End Result

Once your Lightmass build has completed, you will have something similar to the following image.





If you take a close look at the Without Portals image, you will notice that there is a lot of noise in the image, especially in the darker areas when compared to the With Portals image.

Known Issues and Limitations

Lightmass Portals work by forcing Lightmass to send rays toward the portal. Because of this, you should only use Lightmass Portals on small levels and only for lighting that is critical to the scene. Failing to do this (and adding too many Lightmass Portals) can drastically increase your Lightmass build times.

Only use Lightmass Portals on very small levels as Lightmass Portals are not occluded by anything. Using them in big open world-type levels will result in longer-than-needed light baking times.

If you are using Static Meshes for Emissive light casters and the results are noisy, place a Lightmass Portal around the area where the Static Meshes' light is supposed to be emitted from.

Getting Started with Lumen

Lumen Lighting Features

Lumen Global Illumination

Lumen with Sky Lighting

Lumen and Emissive Materials

Lumen Reflections

Lumen Two-Sided Foliage

Supported Light Types and Other Features

Lumen Settings

Lumen Project Settings

Post Process Settings

Additional Notes

Lumen Lighting Update Speed

Disabling Static Lighting for the Project

Material Ambient Occlusion

Lumen is Unreal Engine 5's fully dynamic global illumination and reflections system that is designed for next-generation consoles, and it is the default global illumination and reflections system. Lumen renders diffuse interreflection with infinite bounces and indirect specular reflections in large, detailed environments at scales ranging from millimeters to kilometers.

Getting Started with Lumen

Newly-created projects have Lumen Global Illumination and Reflections enabled by default, as well as their dependencies like Generate Mesh Distance Fields.

Existing projects converted from Unreal Engine 4 to Unreal Engine 5 will not automatically enable Lumen features. This prevents breaking or changing any lighting paths within those projects.

Lumen is enabled from the Project Settings under the Rendering > Dynamic Global Illumination and Reflections categories.



Global Illumination and Reflections can be set independently. In each category, set the following to enable Lumen:

Dynamic Global Illumination: Lumen

Reflection Method: Lumen

When enabled, the property Generate Mesh Distance Fields will be enabled, if it is not already. It is required for Lumen's Software Ray Tracing mode. Requires the engine to be restarted.

Lumen Global Illumination replaces Screen Space Global Illumination (SSGI) and Distance Field Ambient Occlusion (DFAO). Lumen Reflections replace Screen Space Reflections.

When Lumen is enabled for a project, precomputed static lighting contributions are disabled and all lightmaps are hidden.

Lumen Lighting Features

Lumen brings robust dynamic global illumination to Unreal Engine and integrates well with other supporting systems in Unreal Engine 5, such as Nanite, World Partition, and Virtual Shadow Maps.

Unreal Engine 4 features, like Screen Space Global Illumination and Ray Tracing Global Illumination (RTGI) were not reliable or performant for projects that relied on real-time with a high enough quality. Also, these features did not fully integrate with other important systems to widely support most features of the engine.

Lumen Global Illumination

Lumen Global Illumination solves diffuse indirect lighting. For example, light bouncing diffusely off a surface picks up the color of that surface and reflects the colored light onto other nearby surfaces — creating an effect called color bleed. Meshes in the scene also block indirect lighting, which also produces indirect shadowing.



Lumen provides infinite diffuse bounces, which are important in scenes with bright diffuse materials like the white paint in the apartment below.



Unreal Engine 5's Nanite Virtualized Geometry allows for geometry to be much more detailed than ever before. Lumen achieves full-resolution shading, while computing indirect lighting at a much lower resolution for real-time performance.



Lumen with Sky Lighting

Sky lighting is solved as part of Lumen's Final Gather process. It includes sky shadowing, allowing indoor space to be much darker than outdoor lighting, providing a much more natural effect.



Lumen also provides lower-quality global illumination for Lit Translucency and Volumetric Fog.



Lumen and Emissive Materials

Emissive materials propagate light through Lumen's Final Gather with no additional performance cost. However, there's a limit to how small and bright emissive areas can be before they begin to cause noise artifacts to appear. It is inherently much more difficult to solve than manually placed light sources.



Lumen Reflections

Lumen solves indirect specular, or reflections, for the full range of material roughness values.



Diffuse global illumination and shadowed skylight can be seen in all reflections. Lumen Reflections also support Clear Coat materials, like the car example below.



Lumen provides glossy reflections on translucency, like the car windows in the example below.



When the project has High Quality Translucency Reflections enabled, Lumen Reflections provide mirror reflections on the frontmost layer of translucent surface materials.



Lumen Reflections now support Single Layer Water materials, with reflections forced to mirror.



Lumen Two-Sided Foliage

The Two-Sided Foliage shading model is solved by gathering lighting from the backface and scattering it through the leaf, attenuated by the material's Subsurface Color.





Supported Light Types and Other Features

At a high level, Lumen supports the following:

All Light Types are supported, which includes Directional, Sky, Point, Spot, and Rect Lights.

Light Functions are supported on all types of lights.

Lights with their Mobility set to Static are not supported because Static Lights are stored completely in lightmaps and their contribution is disabled when Lumen is enabled.

Lumen Settings

Settings for Lumen are found in two places: Project Settings and the Post Process Volume.

Lumen Project Settings

All Project Settings that are for, or affect, Lumen are found in the Engine > Rendering section. Project Settings contains all the default settings for Lumen for the project.



Below is a listing of all settings that are needed by, or affect, Lumen:

Property Name

Description



Global Illumination



Dynamic Global Illumination Method

Choose the type of dynamic global illumination you want to use in your project.



Reflections



Reflection Method

Choose the type of dynamic reflections you want to use in your project.



Lumen



Use Hardware Ray Tracing when available

Uses Hardware Ray Tracing for Lumen features when supported by the video card, RHI, and operating system. Lumen will fall back to Software Ray Tracing otherwise. Hardware Ray Tracing has significant scene update costs for scenes with more than 100,000 instances. See Ray Tracing Performance Guide for information.

Ray Lighting Mode

Controls how Lumen Reflection rays are lit when Lumen is using Hardware Ray Tracing. By default, Lumen uses Surface Cache for best performance, but can be set to Hit Lighting for Reflections for higher quality.

High Quality Translucency Reflections

Whether to use high quality mirror reflections on the front layer of translucent surfaces. Other layers will use the lower quality Radiance Cache method that can only produce glossy reflections. This increases GPU cost when enabled from the Post Process Volume settings.

Software Ray Tracing Mode

Controls which tracing method Lumen uses when ray tracing the scene. Detail Tracing traces against individual mesh's Distance Fields for the highest quality. Global Tracing traces against the lower detail Global Distance Field for fastest traces.



Hardware Ray Tracing



Support Hardware Ray Tracing

Enables ray tracing from supported operating systems, RHI, and video cards for higher quality results.



Software Ray Tracing



Generate Mesh Distance Fields

Whether to build distance fields of Static Meshes. This is needed for Software Ray Tracing with Lumen and Distance Field Ambient Occlusion which is used to implement Movable Sky Light shadows and ray-traced distance field shadows on Directional Lights. Enabling this increases build times, memory usage and disk size of Static Meshes.

Distance Field Voxel Density

Determines how the default scale of a mesh converts into Distance Field Voxel dimensions. Changing this causes all distance fields to be rebuilt. Large values consume memory very quickly.

Post Process Settings

Post Process Volumes contain overrides and artist-controlled properties for Lumen. The settings are found in the Global Illumination and Reflections categories.



Below is a listing of all settings for Lumen found in the Post Process Volume:

Property Name

Description



Global Illumination: Lumen Global Illumination



Lumen Scene Lighting Quality

Larger scales cause Lumen Scene to be calculated with a higher fidelity, which can be visible in reflections, but at a higher GPU cost.

Lumen Scene Detail

Controls the size of instances that can be represented in Lumen Scene. Larger values ensure small objects are represented, but increase GPU cost.

Lumen Scene View Distance

Sets the maximum view distance of the scene that Lumen maintains for ray tracing against. Larger values increase the effective range of sky shadowing and global illumination, but increase GPU cost.

Final Gather Quality

Increases the quality of Lumen Global Illumination and reduces noise being rendered, but increases the GPU cost of rendering it.

Max Trace Distance

Controls the maximum distance that Lumen should trace while solving lighting. Values that are too small cause lighting to leak into large areas, such as caves. Large values increase the GPU cost to render the scene.

Scene Capture Cache Resolution

Scale factor for Lumen Surface Cache resolution. Smaller values save GPU memory, at a cost in quality. Defaults to 0.5 if not overridden. This should be set on the Scene Capture component in its Post Process Settings.

Lumen Scene Lighting Update Speed

Controls how much Lumen Scene is allowed to cache lighting results to improve performance. Larger scales cause lighting changes to propagate faster, but increase GPU cost.

Final Gather Lighting Update Speed

Controls how much Lumen Final Gather is allowed to cache lighting results to improve performance. Larger scales cause lighting changes to propagate faster, but increase GPU cost.

Diffuse Color Boost

Allows brightening indirect lighting by calculating material diffuse color as pow(DiffuseColor, 1/DiffuseColorBoost). Values above 1 (original diffuse color) are not physically correct, but they can be useful as an art direction knob to increase the amount of bounced light in the scene. It works best to keep the value below 2 as it also causes reflections to be brighter than the scene.

Skylight Leaking

Controls what fraction of the Sky Light intensity should be allowed to leak. This is useful as an art direction knob (non-physically based) to keep indoor areas from going fully black.

Full Skylight Leaking Distance

Controls the distance from a receiving surface where skylight leaking reaches its full intensity. Smaller values make the skylight leaking flatter, while larger values create an Ambient Occlusion effect.



Reflections: Lumen Reflections



Quality

Increases the quality of Lumen Reflections on surfaces, and reduces noise being rendered, but increases the GPU cost of rendering them.

Ray Lighting Mode

When using Hardware Ray Tracing with Lumen, this setting controls whether reflections will reuse the Surface Cache for cheap lighting, or calculate lighting at the hit point for higher quality.

High Quality Translucency Reflections

Whether to use high quality mirror reflections on the front layer of translucent surfaces. Other layers will use the lower quality Radiance Cache method that can only produce glossy reflections. This increases GPU cost when enabled. Requires that the Project Setting High Quality Translucency Reflections be enabled first.

Additional Notes

The following are some additional considerations to keep in mind while working with Lumen features in your projects.

Lumen Lighting Update Speed

Lumen uses a number of caches to achieve real-time performance. While local lighting changes propagate quickly, global lighting changes, like disabling the Sun, can take multiple seconds to propagate. Projects can use the Lumen Scene Lighting Update Speed and Final Gather Lighting Update Speed controls in the Post Process Volume to work around this delay at the cost of increased GPU cost.

Disabling Static Lighting for the Project

Precomputed lighting from Static lighting is removed when Lumen is enabled. You can disable precomputed lighting entirely for your project from the Project Setting under the Engine > Rendering section by disabling Allow Static Lighting.

Disabling Static lighting also saves some static lighting overhead with shader permutations. It also allows Material Ambient Occlusion to work with Lumen Global Illumination.

Projects that already use Static Lighting will have their lightmaps loaded into memory and on disk until Force No Precomputed Lighting is enabled in the World Settings of an already loaded Level. You then need to rebuild the lighting and save the Level to remove lightmap data.

Material Ambient Occlusion

Lumen Global Illumination supports Material Ambient Occlusion, which provides reliable self-occlusion on Skeletal Meshes.

To use Material Ambient Occlusion with Lumen:

Disable Allow Static Lighting in the Project Setting to create space in the GBuffer.

Set the Material to output to Ambient Occlusion.



Left, Lumen GI on a Skeletal Mesh with only Screen Traces (Software Ray Tracing); Right, Material Ambient Occlusion.

Material Ambient Occlusion is not visible when using the Buffer Visualization Ambient Occlusion view mode.

Lumen Global Illumination supports Material Bent Normal Maps. However, these are significantly more expensive than Material Ambient Occlusion with little visual improvement.

To use Bent Normal Maps with Lumen:

Set r.GBufferDiffuseSampleOcclusion=1 in the [SystemSettings] section of your project's DefaultEngine.ini configuration file and restart the editor.

Set up the Material to output to the Bent Normal custom output node.

Surface Cache

Screen Tracing

Lumen Ray Tracing

Software Ray Tracing

Hardware Ray Tracing

Large Worlds

Far Field

General Limitations of Lumen Features

Performance

Lumen Platform Support

Lumen Visualization Options

Troubleshooting Topics

Problem-Causing Meshes

Mismatch Between Shadow Maps and Ray-Traced Shadows

Lumen uses multiple ray-tracing methods to solve Global Illumination and Reflections. Screen Traces are done first, followed by a more reliable method.

Lumen uses Software Ray Tracing through Signed Distance Fields by default, but can achieve higher quality on supporting video cards when Hardware Ray Tracing is enabled.

Lumen's Global Illumination and Reflections primary shipping target is to support large, open worlds running at 60 frames per second (FPS) on next-generation consoles. The engine's High scalability level contains settings for Lumen targeting 60 FPS.

Lumen's secondary focus is on clean indoor lighting at 30 FPS on next-generation consoles. The engine's Epic scalability level produces around 8 milliseconds (ms) on next-generation consoles for global illumination and reflections at 1080p internal resolution, relying on Temporal Super Resolution to output at quality approaching native 4K.

Surface Cache

Lumen generates an automatic parameterization of the nearby scene's surface called Surface Cache. It is used to quickly look up lighting at ray hit points in the scene. Lumen captures the material properties for each mesh from multiple angles. These capture positions (called Cards) are generated offline for each mesh.

Cards can be visualized with the console command r.Lumen.Visualize.CardPlacement 1.



By default, Lumen only places 12 Cards on a mesh, but you can increase that amount by setting Max Lumen Mesh Cards in the Build Settings of the Static Mesh Editor. Adjusting the number of cards is useful for more complex interiors or single meshes with irregular shapes.



Areas that don't have Surface Cache coverage are colored pink in the Surface Cache View Mode of the Level Editor.

These areas will not bounce light and will appear black in reflections. Issues like this can be fixed by increasing the number of Cards used with Max Lumen Mesh Cards, but that may not solve all issues. Alternatively, breaking the mesh into less complex pieces can resolve these types of issues as well.





View Mode > Lumen > Surface Cache

Lumen Surface Cache Visualization of Complex Mesh

Click image for full size.

Click image for full size.

Materials with view-dependent logic, such as Pixel Depth, Camera Position, or Camera Vector may appear incorrectly in Lumen Surface Cache view mode. Materials that use these nodes can use the Ray Tracing Quality Switch node to provide a version of the Material that works with Lumen Surface Cache, or to optimize Surface Cache captures for complex materials.



For more information about using the Ray Tracing Quality Switch node, see Ray Tracing Performance Guide.

Nanite accelerates the mesh captures used to keep Surface Cache in sync with the triangle scene. High polygon meshes in particular, need to be using Nanite to have efficient captures. Foliage and Instanced Static Mesh Components can only be supported if the mesh is using Nanite.

After the Surface Cache is populated with material properties, Lumen calculates direct and indirect lighting for these surface positions. These updates are amortized over multiple frames, providing efficient support for many dynamic lights and multiple bounce global illumination.

Unreal Engine provides visualization modes for Surface Cache and Cards representation. See the Lumen Visualization Options section of this page for more details.

Only meshes with simple interiors can be supported — walls, floors, and ceilings should all be separate meshes. Importing an entire room, which includes furniture, in a single mesh is not expected to work with Lumen.

Screen Tracing

Lumen features trace rays against the screen first (called Screen Tracing or Screen Space Tracing), before using a more reliable method if no hit is found, or the ray passes behind a surface. Screen tracing supports any geometry type and is useful for covering up mismatches between the Lumen Scene and triangle scene.

The disadvantage in using screen traces is that they greatly limit controls for art direction, which would only apply to indirect lighting, like lighting properties for Indirect Lighting Scale or Emissive Boost. Setting a large Indirect Lighting Scale on a light will cause view-dependent global illumination, as Screen Traces cannot support it correctly.

The example scene below uses Screen Traces first before falling back to other, more costly tracing options. When disabling Screen Traces for global illumination and reflections, it is possible to see only the Lumen Scene produced by Software Ray Tracing. Screen Traces help resolve the mismatch that can happen between the triangle scene and Lumen Scene.

You can perform this type of comparison by disabling Screen Traces from the Level Viewport's Show > Lumen menu and removing the check next to Screen Traces.





Lumen Ray Tracing

Lumen provides two methods of ray tracing the scene: Software Ray Tracing and Hardware Ray Tracing.

Software Ray Tracing uses Mesh Distance Fields to operate on the widest range of hardware and platforms but is limited in the types of geometry, materials, and workflows it can effectively use.

Hardware Ray Tracing supports a larger range of geometry types for high quality by tracing against triangles and to evaluate lighting at the ray hit instead of the lower quality Surface Cache. It requires supported video cards and systems to operate.

Software Ray Tracing is the only performant option in scenes with many overlapping instances, while Hardware Ray Tracing is the only way to achieve high quality mirror reflections on surfaces.

Software Ray Tracing

Lumen uses Software Ray Tracing against Signed Distance Fields by default. This tracing representation is supported on any hardware supporting Shader Model 5 (SM5), and only requires that Generate Mesh Distance FIelds be enabled in the Project Settings.

The renderer merges Mesh Distance Fields into a Global Distance Field to accelerate tracing. By default, Lumen traces against each mesh's distance field for the first two meters for accuracy, and the merged Global Distance Field for the rest of each ray.

Projects with extreme overlapping instances can control the method Lumen uses with the project setting Software Ray Tracing Mode. Lumen provides two options to choose from:

Detail Tracing is the default method and involves tracing against the individual mesh's signed distance field for the highest quality. The first two meters are used for accuracy and the Global Distance Field for the rest of each ray.

Global Tracing only traces against the Global Distance Field for each ray for the fastest traces.

Mesh Distance Fields are streamed in and out based on distance as the camera moves through the world. They are packed into a single atlas to allow ray tracing.

Use the command r.DistanceFields.LogAtlasStats 1 to output mesh distance field statistics to the log.

The quality of Lumen's Software Ray Tracing depends on the quality of the mesh's distance field representation. There are two visualization options, one for Mesh DistanceFields and the other for Global DistanceField. These visualization modes are found under the viewport's Show > Visualize menu.









Scene View

Mesh Distance Fields Visualization

Global Distance Field Visualization

For some meshes, thin surfaces may not have a good distance field representation and could cause issues with light leaking. The Mesh Distance Field visualization can help you spot these types of issues.



(Left to Right) Triangle Mesh, Distance Field Resolution Scales 1.0 (Default), 1.5, 2.0

There are two ways to go about improving a meshes distance field representation:





Project Settings: Distance Field Voxel Density

Static Mesh Editor: Distance Field Resolution Scale

Click image for full size.

Click image for full size.

Projects can globally increase mesh distance field quality using the Distance Field Voxel Density found in the Project Settings.

Increase the Distance Field Resolution Scale of individual meshes that need more quality from the Static Mesh Editor Build Settings.

Increasing Distance Field resolution or density will increase the disk size of the project.

Software Ray Tracing has some limitations relating to how you should work with it in your projects and what types of geometry and materials it currently supports.

Geometry Limitations:

Only Static Meshes, Instanced Static Meshes, Hierarchical Instanced Static Meshes, and Landscape terrain are represented in the Lumen Scene.

Foliage must be enabled with the setting Affect Distance Field Lighting found in the Foliage Tool settings.

Material Limitations:

World Position Offset (WPO) is not supported.

Transparent materials are ignored by distance fields and Masked materials are treated as Opaque.

Masked materials can cause significant over-shadowing on foliage where large areas of leaves are masked out.

Distance fields are built off of properties of the material assigned to the Static Mesh Asset rather than the override component.

Overriding with a material that has a different Blend Mode or that has Two-Sided property enabled will cause a mismatch between the triangle representation and the mesh's distance field representation.

Workflow Limitations:

Software Ray Tracing requires that levels be composed of modular geometry. Things like walls, floors, and ceilings should be separate meshes. Large single meshes, such as a Mountain or multi-story building, will have a poor distance field representation that can cause self-occlusion artifacts to appear.

Walls should be no thinner than 10 centimeters (cm) to avoid light leaking.

Distance Fields cannot represent extremely thin features, or one-sided meshes seen from behind. Avoid these types of artifacts by ensuring the viewer doesn't see the triangle back faces of one-sided meshes or only use closed geometry.

Mesh Distance Field resolution is assigned based on the imported scale of the Static Mesh.

A mesh that is imported very small and then scaled up on the component will not have sufficient distance field resolution. Instead, set the distance field resolution from the Static Mesh Editor's Build Settings if you use scaling on placed instances in a Level.

Hardware Ray Tracing

Hardware Ray Tracing supports a larger range of geometry types than Software Ray Tracing, in particular it supports tracing against skinned meshes. Hardware Ray Tracing also scales up better to higher qualities — it intersects against the actual triangles and has the option to evaluate lighting at the ray hit instead of the lower quality Surface Cache.

To use high quality hit lighting, the following must be enabled in the Project Settings under the Engine > Rendering section:



Support Hardware Ray Tracing: Enabled

Use Hardware Ray Tracing when available: Enabled

Ray Lighting Mode: Hit Lighting for Reflections

While Hardware Ray Tracing provides the highest quality of the two ray tracing methods, it also has the highest setup cost in large scenes causing tracing to become expensive with many overlapping meshes. Dynamically deforming meshes, like skinned meshes, also incur a large cost to update the Ray Tracing acceleration structures each frame, proportional to the number of skinned triangles. You can learn more about the setup and cost of Hardware Ray Tracing in the Ray Tracing Performance Guide.

For Static Meshes that have Nanite enabled, Hardware Ray Tracing can only operate on the Fallback Mesh. This is a mesh that is generated by Nanite's Fallback Relative Error property to be used when the full detail mesh cannot be. These fallback meshes can be visualized in the Level viewport under the Show > Advanced > Nanite Meshes.

Screen Traces are used to cover the mismatch between the full triangle meshes rendered by Nanite and the Fallback Mesh being ray-traced by Lumen. However, there are some cases where the mismatch is too large to be hidden. In these cases, raising the Fallback Relative Error can reduce incorrect self-intersection artifacts.





Lumen will use Hardware Ray Tracing when:

The project has Support Hardware Ray Tracing and Use Hardware Ray Tracing when available enabled.

Changing the first setting requires restarting the engine.

The project is running on a supported operating system, RHI, and video card. Currently only the following platforms support performant Hardware Ray Tracing:

Windows 10 with DirectX 12

Video cards must be NVIDIA RTX-2000 series and higher, or AMD RX 6000 series and higher.

PlayStation 5

Xbox Series S / X

A project using Hardware Ray Tracing for Lumen may also want to fallback to Software Ray Tracing when needed, but not pay the memory costs and scene update costs of both at the same time. In these cases, you should add the following console variable to your DefaultEngine.ini configuration file:

With this setting disabled, it is no longer possible to toggle Use Hardware Ray Tracing when available at runtime.

Large Worlds

Lumen Scene operates on the world around the camera, enabling large worlds and streaming. Lumen relies on Nanite's Level of Detail (LOD) and Multi-View rasterization for fast scene captures to maintain the Surface Cache, with all operations throttled to prevent hitches from occurring. Lumen does not require Nanite to operate, but Lumen's scene capturing becomes very slow in scenes with lots of high polygon meshes that have not enabled Nanite. This is especially true in scenes if the assets do not have good LODs set up for them.

Fast camera movement will cause Lumen Scene updating to fall behind where the camera is looking, causing indirect lighting to pop in as it catches up.

When Lumen is using Software Ray Tracing, Lumen Scene only covers 200 meters (m) from the camera position, but can be increased up to 800 m with the Lumen Scene View Distance setting in the Post Process Volume. Past the highest Lumen Scene distance, only Screen Traces are active for global illumination.

Far Field

Lumen Hardware Ray Tracing implements Far Field traces, which extend Lumen Global Illumination and Reflections to one kilometer distance from the camera by default.

Far Field traces are enabled by the console variable r.LumenScene.FarField=1 in the DefaultEngine.ini configuration file, and requires the use of World Partition's Hierarchical Level of Detail (HLOD). Far Field requires the use of HLOD1 to be built.

When Far Field is enabled, it is traced beginning at the Max Trace Distance (default is 200m) and continues to r.LumenScene.FarField.MaxtraceDistance (default is 1 kilometer). Since objects can be culled from ray tracing using r.RayTracing.Culling.Radius, your projects will likely want the culling radius and max trace distance to match. Otherwise, the near-field (objects from the camera to the Max Trace Distance) may be culled before the far-field traversal point, which will leave a gap in coverage.



The Unreal Engine 5 technical demo "The Matrix Awakens" demonstrates large-world global illumination using Far Field traces.

General Limitations of Lumen Features

Lumen Global Illumination cannot be used with Static Lighting in lightmaps. Lumen Reflections should be extended to work with global illumination in lightmaps in a future release of Unreal Engine 5, which will provide a way to further scale up render quality for projects using Static lighting techniques.

Lumen Reflections do not support multiple specular reflections.

Single Layer Water Materials are currently not supported by Lumen.

Lumen does not currently support Scene Captures or Split-screen.

Lumen is not compatible with Forward Shading.

Performance

Lumen uses the Scalability settings found in the Level Editor under the viewport Settings > Engine Scalability Settings. These settings contain general quality settings from Low to Cinematic, but also allow you to specify individual features settings in the same ranges. The scalability options are not limited to the Editor and can be called through Blueprint to use in the projects you ship.

Lumen is only active when the global Quality, or the individual Global Illumination, and Reflections are set to High, Epic, Cinematic sclabaility settings.



Lumen relies heavily on Temporal Upsampling with the Unreal Engine 5 feature Temporal Super Resolution algorithm for 4K output. The engine scalability options set target fps with Lumen default settings.

Epic scalability level is set for a 30 fps budget (8 ms for global illumination and reflections) at 1080p on next-generation consoles.

High scalability level is set for a 60 fps budget. However, note that achieving a 60 fps budget with acceptable quality is still a work in progress.

Lumen is disabled for Low and Medium scalability levels.

Materials with roughness below 0.4 cost the most for Lumen to solve lighting for, as extra rays have to be traced to provide Lumen Reflections.

Lumen Platform Support

Lumen does not support previous-generation consoles, such as PlayStation 4 and Xbox One.

Projects that rely on dynamic lighting can use a combination of Distance Field Ambient Occlusion and Screen Space Global Illumination on those platforms and legacy PC hardware.

Lumen is developed for next-generation consoles (PlayStation 5 and Xbox Series S / X) and high-end PCs. Lumen has two ray tracing modes, each with different requirements.

Software Ray Tracing Requirements:

Video cards using DirectX 11 with support for Shader Model 5 (SM5)

Requires an NVIDIA GeForce GTX-1070 or higher card.

Hardware Ray Tracing Requirements:

Windows 10 with DirectX 12

Video cards must be NVIDIA RTX-2000 series or higher, or AMD RX-6000 series or higher.

Lumen does not support mobile platforms. There are no plans to develop a dynamic global illumination system for the mobile renderer. Games using dynamic lighting need to use unshadowed Sky Light on mobile.

Lumen does not currently support Virtual Reality (VR) systems. While VR can be supported, the high frame rates and resolutions required by VR make dynamic global illumination a poor fit.

Lumen Visualization Options

Lumen provides several ways of visualizing data in the Unreal Editor that can be helpful in inspecting and troubleshooting how Lumen is lighting the scene.

The primary Lumen view modes are found in the Level Viewport under the View Modes menu:





Lumen View Modes Options

Lumen Overview Visualization

Click image for full size.

Click image for full size.

Overview shows all three of Lumen's visualizations as small tiles over the rendered scene.

Lumen Scene shows Lumen's version of the scene, in the highest quality available: Surface Cache or Hardware Ray Tracing.

Reflection View shows the scene as Lumen Reflections see it, including limited tracing distances used by reflections.

Surface Cache is the same as Lumen Scene except that areas of meshes that were too complex to be covered are color highlighted in pink.

Additional visualizations are found in the Level Viewport's Show > Visualize menu.









Scene View

Mesh Distance Fields Visualization

Global Distance Field Visualization

Mesh Distance Fields shows the individual mesh's Signed Distance Field representations that make up the scene.

Global Distance Field shows the lower detail distance field that has been merged of individual mesh distance fields. There are also some console commands you can use to visualize other data used for Lumen:

Lumen's Card Placement looks at how capture positions (called Cards) are used in the scene. These Cards are generated offline for each mesh, and are used to capture the material properties of each mesh from multiple angles. Enable this visualization mode using r.Lumen.Visualize.CardPlacement 1.

Hardware Ray Tracing uses the Nanite Fallback Mesh, which is generated from the Fallback Relative Error property of the Static Mesh Asset. The fallback mesh is used to cover mismatches between Screen Traces and the Nanite ray-traced scene in Lumen Reflections. Use Show > Advanced > Nanite Meshes to disable Nanite rendering and see the fallback mesh used by Lumen.

Troubleshooting Topics

When troubleshooting any Lumen-related issues in your scene, a good place to start is with the Lumen Overview view mode.

Lumen Scene should match the main scene view in ways that have noticeable impact on indirect lighting. Significant pink areas in Lumen Surface Cache view mode should be solved by raising the Max Lumen Mesh Cards in the Static Mesh settings, or splitting the mesh into multiple parts.



Problem-Causing Meshes

In cases where you have problem-causing meshes contributing to indirect lighting, they can be removed from Lumen Scene using by using the Level instance's Details panel to disable one of the following:

For Software Ray Tracing, unchecking the box for Affect Distance Field Lighting removes them.

For Hardware Ray Tracing, unchecking the box for Visible in Ray Tracing removes them.

Mismatch Between Shadow Maps and Ray-Traced Shadows

Lumen reuses the Renderer's shadow maps for shadowing the Lumen Scene. However, these are only available for on-screen positions. For off-screen surfaces, Lumen uses ray tracing for shadowing. When there is significant mismatch between these two techniques, Lumen Global Illumination becomes highly view-dependent, similarly to screen space techniques like Screen Space Global Illumination.

This type of issue can be solved by figuring out what is cursing the mismatch to occur. Disable the Reuse Shadow Maps show flag under Show > Lumen while looking at the Lumen Scene view mode to see the ray-traced shadows.

Splotchy artifacts seen in mirror reflections happen because Lumen uses very low quality settings to calculate multi-bounce global illumination since there is not much budget for it. In the Post Process settings, increase the Lumen Scene Quality to reduce artifacts.





Lumen Scene View Mode

Improved Lumen Scene Lighting Quality to 4

Small meshes appear black in mirror reflections because Lumen culls small objects from Lumen Scene for performance. In the Post Process Setting, Increase the Lumen Scene Detail will capture smaller meshes over farther distances.





Sky occlusion and global illumination are only maintained in Lumen Scene for the first 200 meters. In the Post Process settings, increase the Lumen Scene View Distance to maintain Lumen Scene over farther distances.

In cave-like, or enclosed areas, if light leaking is happening, it is because Lumen limits how far rays are traced to improve performance, but missing an occluder causes light leaking.

In the Post Process Setting, raise the Lumen Scene Detail and the Max Trace Distance.

For example, the mesh below is an enclosed box with no holes viewed from the outside.



Inside the box, you can see that skylighting is leaking throughout the scene.



Raise the following values:

Lumen Scene View Distance

Max Trace Distance

The light leaking should now be fixed.



When changing or toggling Lumen Global Illumination off, the lighting in the scene changes too slowly causing it to fade rather than quickly turn on or off.

For example, toggling the Sky Light off in the following scene, you see the lighting slowly fade out.



You can improve the speed at which Lumen Global Illumination changes by increasing the Post Process Volume setting for Final Gather Lighting Update Speed.

Notice how the skylighting turns off more quickly than before.



Remember to turn these settings back to defaults after the change to get back to cheaper lighting.

Small objects are culled from Lumen Scene leaving only the Screen Traces to pick up small emissive meshes. This leads to inconsistency in their lighting in the scene. Set the Level instances Emissive Light Source from the Details panel.





Lumen uses its Surface Cache for lighting reflection rays by default since it is significantly faster to render. However, lighting can be configured to evaluate at the ray hit by setting one of the following:

In the Project Settings, set Ray Lighting Mode to Hit Lighting for Reflections.

This changes lighting for the entire project.

In the Post Process Volume, set Ray Lighting Mode to Hit Lighting for Reflections.

Ideal for individual changes where you only need it for a single shot or viewpoint.

In the example scene below, notice how the specular highlights on the wall and stairs are missing in the reflection.





Using SSGI

Controlling Quality

Additional Console Commands

Additional Notes

Screen Space Global Illumination (SSGI) is an Unreal Engine feature that aims to create natural-looking lighting by adding dynamic indirect lighting to objects within the screen view. SSGI also makes it possible to have dynamic lighting from emissive surfaces, such as neon lights or other bright surfaces.

Screen Space Global Illumination works best as a supplimental indirect lighting illumination method to precomputed lighting from Lightmass.





Using SSGI

Use the following properties and console variables when working with SSGI.

You can enable Standalone SSGI in the Post Process Volume settings by enabling the Method and choosing Screen Space (Beta) from the dropdown menu.



Controlling Quality

SSGI has several quality settings that you can enable using the following command:

Use a value between 1 and 4 to change the quality:

Dragging the slider shows SSGI's quality levels from 1 to 4.



1 - Ray Steps: 8; Ray Count: 4

2 - Ray Steps: 8; Ray Count: 8

3 - Ray Steps: 8; Ray Count: 16

4 - Ray Steps: 12; Ray Count: 32

Additional Console Commands

You can also use the following commands to control SSGI:

The HalfRes command to render SSGI at half resolution.

The Leak Free Project uses previous frame's scene color to achieve better quality results.

Additional Notes

Large occluders and fallback techniques, such as precomputed lighting.

SSGI, like other screen space effects, is best used in conjunction with other indirect lighting techniques, such as precomputed lighting from lightmass. When you have large objects that block portions of the screen, SSGI becomes apparent when it's being used as the sole indirect lighting illumination for the scene. For example, using baked lighting reduces screen space artifacts when transitioning behind a large occluder where a bright object may be located. SSGI is recommended as a means to improve indirect lighting illumination in your scene but not as a sole indirect lighting method.

What is Unreal Swarm?

Requirements

Setting up Swarm Coordinator

Deploying Swarm Agents

Setting up Agent Groups

Managing Swarm Cache

Reading Agent Logs

Monitoring Progress

Stopping Swarm Agents

Frequently Asked Questions

What are some ways I can improve build times when using Swarm Agent(s) and Coordinator?

Why am I not getting Agent distribution?

How can I limit CPU usage when building lighting?

When trying to launch Swarm Agent, I get a Windows application error for UnrealLightmass.exe, what does this mean?

Are Swarm Agent and Coordinator supported for Mac or Linux?

Can my GPU be used to build lighting?

What do the following errors mean?



Depending on your development environment, rendering large and open worlds can take a lot of time because computing lighting, shadows, and geometry can be expensive. There are several ways to reduce your project's build time, such as upgrading your hardware beyond our recommended specifications or by utilizing a task distribution system, which is where Unreal Swarm comes in, reducing the time it takes to perform expensive computations, such as solving for high-quality static global illumination.

What is Unreal Swarm?

Unreal Swarm is a general application and task distribution system, comprised of two application types, one being a coordinator that distributes build task(s), and the other being an agent that utilizes the host system's resources to complete its assigned job(s).



After setting up the Swarm, a Swarm Coordinator will manage the job(s) and task(s) of Swarm Agent(s) on your network.

Requirements

Before you can begin setting up Unreal Swarm:

Install Unreal Engine 4 (UE4) on at least one Windows machine in your network. You'll use this machine to launch the Swarm Coordinator. See Installing Unreal Engine.

On each Windows machine that you want to act as a Swarm Agent, install the prerequisites required to run the Unreal Engine and editor. You can do this in any of the following ways:

Install the required version of the DirectX End-User Runtimes, which you can download from the link on the Hardware and Software Requirements page.

Run the prerequisite installer that is bundled with Unreal Engine, as decsribed on the Hardware and Software Requirements page.

Install the Epic Games Launcher and Unreal Engine.

Unreal Swarm currently runs only under Windows. The machine that you use to start the light build, and all machines that you want to participate in the distributed computation, must be running a version of Windows that is supported by Unreal Engine.

If you'd like to set up a render farm for computationally expensive tasks, please make sure to coordinate with your IT department to set up the appropriate permissions on machine(s) that will need to host Swarm Coordinator(s) and Agent(s).

Setting up Swarm Coordinator

If you've identified the machines that you'd like to use, and if you've installed UE4; you're ready to set up Swarm Coordinator by following these steps:

After installing UE4, navigate to [UE4ROOT]\Engine\Binaries\DotNET.

Make a new directory on the machine that will distribute tasks to other machines on the network. For illustrative purposes, we're naming the new directory, Swarm Coordinator.

Now, move (or copy) the following files from the [UE4ROOT]\Engine\Binaries\DotNET folder into the newly created directory:

AgentInterface.dll

SwarmCommonUtils.dll

SwarmCoordinator.exe

SwarmCoordinator.exe.config

SwarmCoordinatorInterface.dll

SwarmInterface.dll

UnrealControls.dll

Finally, to verify that you can run the application on your machine, go ahead and double click on the Swarm Coordinator executable.

If you already have Swarm Agents deployed, Swarm Coordinator displays its Agent Dialog Window (1) and Restart Options Area (2).



Click for full image.

At this point, you don't need to do anything with the application, so go ahead and move onto the next section, where you'll set up Swarm Agent(s).

Deploying Swarm Agents

Now that you've set up Swarm Coordinator, you're ready to deploy Swarm Agents. After identifying the machine(s) that you'd like to host your agents, go ahead and follow these steps:

On each of the machines that you'd like to host a Swarm Agent, make a new directory. For illustrative purposes, we're naming our new directory, Swarm Agent.

Move (or copy) the following files from the [UE4ROOT]\Engine\Binaries\DotNET folder into the newly created directly: SwarmAgent.exe, AgentInterface.dll, SwarmCommonUtils.dll, SwarmCoordinatorInterface.dll, SwarmInterface.dll, and UnrealControls.dll.

To deploy an agent, double click on the Swarm Agent executable.

After launching Swarm Agent, the Swarm icon appears in the Windows Notification Area. Double click the Swarm icon to open the application's main menu.

To configure Swarm Agent, click the Settings tab.

To enable Developer Settings, set the ShowDeveloperMenu flag (in Settings > Developer Settings) to True.

When you update an Agent's settings, it's worth noting that Swarm Agent writes settings out to SwarmAgent.Options.xml (or, if Developer Settings are enabled, to SwarmAgent.DeveloperOptions.xml).

In the Distribution Settings drop down menu, locate the CoordinatorRemotingHost field, entering the host computer's IPv4 Address.

If you don't know your computer's IPv4 Address, go ahead and run ipconfig from the Command Prompt.

If you don't want to enter the system's IPv4 Address into the CoordinatorRemotingHost field, you can enter the Coordinator's DNS Name.

Finally, go ahead and open Swarm Coordinator, where you'll find details about deployed Swarm Agent(s).



Click for full image.

Setting up Agent Groups

Setting up Agent Groups is useful for creating execution clusters. For example, one set of machines might belong to a group that isn't part of a render farm, whereas another cluster might have machines belonging to the farm.

Getting started, go ahead and open the Settings > Distribution Settings menu.



To set up an Agent group, you'll first want to specify which group jobs you want this Agent to be deployed to. For example, we're specifying that this Agent will deploy to "FarmGroup" jobs in the AllowedRemoteAgentGroup setting.



If you want this Agent to be deployed to "FarmGroup" jobs, make sure that the AgentGroupName matches AllowedRemoteAgentGroup. In the following example, we're precluding this Agent from being deployed to "FarmGroup" jobs.



If you'd like to learn more about an Agent's Distribution Settings, the following table provides some useful notes, covering the remaining properties that can be specified for each Agent in your execution cluster(s).

Setting

Default Value

Description

AgentGroupName

Default

This is the name of the agent group that this Swarm Agent belongs to.

AllowedRemoteAgentGroup

DefaultDeployed

This is the name of the agent group jobs that this Swarm Agent can be deployed to.

AllowedRemoteAgentNames

RENDER*

The filter string (' ', ',' or ';' delimited) being used by the remote machine.

AvoidLocalExecution

False

Setting this flag to True means that you'd like to enable the distribution of jobs and tasks from this Swarm Agent (with no local execution).

Setting this flag is more of a suggestion (rather than a mandate) because it sets the thread priority to Idle, favoring other Agents connected on the Swarm over itself. This is due to the fact that if there aren't any other Agents available (or if Swarm can't find a Coordinator), you'll still get a build running on that Agent rather than an infinite wait time (or failure).

CoordinatorRemotingHost

RENDER-01

This is the name of the machine that's hosting Swarm Coordinator. You can enter one of two strings into this field, either the Coordinator's DNS Name or its IPv4 address.

EnableStandaloneMode

False

Setting this flag to True disables the distribution system for outgoing and incoming tasks.

Managing Swarm Cache

After you've deployed your Swarm Agent(s), you'll want to manage the Agents' Swarm Cache. Typically, managing an Agent's Swarm Cache involves updating the Agent's cache settings, clearing its cache, and validating its cache.

To update the Agent's cache settings, navigate to the Settings > Cache settings menu.



From this menu, you'll be able to update the Agent's Cache Settings (as described below).

Setting

Default Value

Description

CacheFolder

[Folder on Disk]/SwarmCache

This is the location of the cache folder, being on a fast drive with lots of space.

MaximumCacheSize

10

In gigabytes, this is the approximate maximum size of the cache folder.

MaximumJobsToKeep

5

This is the number of previous jobs to record logs and output data.

Additionally, if you want to clear the host machine's cache, which is used by Swarm Agent to complete its assigned tasks, invoke the Clean command in the Cache menu.



Finally, if you want to validate the machine's cache, invoke the Validate command in the Cache menu.



It's good practice to clean and validate your Swarm Cache on a regular basis, especially if Unreal Lightmass is crashing and causing builds to fail.

Reading Agent Logs

Clicking on the Log tab opens the Log window that Swarm Agent log messages are flushed to.



If you want to specify the amount of output being flushed to the Log window, update the MaximumJobApplicationLogLines variable (found in the Developer Settings > Log Settings menu) to change the number of output lines from a Job application before it truncates what goes to the Log window.



If you need to locate AgentLog text files for debug or maintenance purposes, it's important to note that, at the beginning and end of every Job, Agent activity is logged to a file in [Folder on Disk]\SwarmCache\Logs.



Click for full image.

Typically, the default logging level to files on disk is set to ExtraVerbose, whereas the default logging level to a Swarm Agent's Log window is set to Informative. If you want to change how detailed you'd like the Log output to be, update the Verbosity variable, which is found in the Settings > Log Settings menu.



Monitoring Progress

If you want to monitor an agent's progress as it works on the jobs and tasks being assigned to it, open the Swarm Status window.



When an agent is running, you'll see progress bars per machine, and for every progress bar, there are regions reflecting whether the application is initializing (1), preparing to do work (2) (both of which are not distributed work) or performing distributed work (3).



To get more details about a job's progress, hover your mouse cursor over the progress bars.

Finally, the Distributed Progress bar located at the bottom tells you the percentage of a Job that has been completed (4) versus the percentage that is currently being worked on (5).



Stopping Swarm Agents

To stop a Swarm Agent, click File > Exit to close the application and kill its process.



Alternatively, right click the Swarm icon in the Windows Notification Area and select its Exit command.

At this point, Swarm Coordinator and Swarm Agent can run with minimal intervention. Given the number of lights, objects, and the quality of calculations that need processing, you'll find that with enough agents, Unreal Lightmass builds should only take a few minutes rather than a few hours.

Depending on your development environment (including the size and complexity of the scene that you're working on), you may want to update how many cores are reserved on your local machine to improve build performance. This can be done by tuning the LocalJobsDefaultProcessorCount variable, which is located in the Developer Settings > Local Performance Settings menu.



If you have some general questions about running Unreal Swarm, check out the following set of Frequently Asked Questions.

Frequently Asked Questions

What is Unreal Swarm?

Requirements

Setting up Swarm Coordinator

Deploying Swarm Agents

Setting up Agent Groups

Managing Swarm Cache

Reading Agent Logs

Monitoring Progress

Stopping Swarm Agents

Frequently Asked Questions

What are some ways I can improve build times when using Swarm Agent(s) and Coordinator?

Why am I not getting Agent distribution?

How can I limit CPU usage when building lighting?

When trying to launch Swarm Agent, I get a Windows application error for UnrealLightmass.exe, what does this mean?

Are Swarm Agent and Coordinator supported for Mac or Linux?

Can my GPU be used to build lighting?

What do the following errors mean?

Adding Lightmass Importance Volume(s) in player-accessible areas:

This volume is used to focus where Lightmass spends its time on for accuracy and quality. The idea is that these should cover an area where the player can be. Areas outside of the volume will receive fewer photons and thus a lower quality result. Note that using single large volumes to encompass an area defeats their purpose of focusing photon calculations in key areas.

Adjusting Lightmap Resolutions:

Individual Static Meshes that have high Lightmap resolutions and a lot of light contributions in a scene can increase build times, not only for the scene, but for a single Actor. Where possible, lower Lightmap resolutions for a quality result and use the Statistics window to get an idea of how long it took to build a single Actor for the Level. To get a good result for large (or complex) Static Meshes where you find you are setting higher Lightmap resolutions, you may want to consider breaking it into separate smaller meshes or rework the Lightmap UV (where possible) to get better coverage for the parts that matter.

Enabling Foliage Tool Lightmap Resolutions:

Instanced Static Meshes used when you paint Foliage into your level automatically use the Lightmap resolution of the Static Mesh that it's referencing. When you have hundreds (or even thousands) of these painted into your level, that resolution can be too high for the system to handle. It will lead to exponentially longer build times, potential Lightmass crashes due to memory constraints, and higher texture memory consumption.

It is recommended to enable the Light Map Resolution and use the default value of 8 or possibly set it to a lower value of 4. This lowers the resolution of all instances, but the perceivable quality loss is minimal since static shadowing only needs to be displayed at a distance while dynamic shadowing is handled near the camera.



Click image for full size.

Reducing the number of scene Actors and (or) Lights:

The number of shadow casting Actors and (or) Lights in the levels means that all these interactions have to be considered when calculating lighting. Reducing light is a key way to limit the number of Actors that a single light interacts with. Reducing the influence radius for lights that don't need to affect a large area can decrease the number of computations and thus increase the speed of the light build being processed.

Using higher than recommended system specifications:

Swarm Agent is a CPU intensive process that requires a lot of calculations. If you're only using your local machine, a good CPU and lots of RAM can improve build process time. Keep in mind, that the other factors previously mentioned also play a role in build processing time.

Remote Swarm Agents may decline to work on your job for a few different reasons, the most common among them is that they're already busy doing someone else's work. Another possibility is that they have determined that they are too busy to take on a job at that time, often caused by the machine doing something resource intensive, such as compiling or cooking content. In the Swarm Status tab of the Agent window, you should see a full list of all remote agents that could potentially help with your build. If one of them isn't currently available, you'll see a white bar ticking along with the rest of the build, and if you mouse over the bar, you will see "Waiting for remote to become available".

Also, a more advanced way to peek at the available remote agents (even when you're not doing a build) is to click on the Log tab and select Ping Remote Agents from the Network menu. You'll see a list of the remote machines and their current state.

From the Swarm > DeveloperSettings tab, you can limit CPU cores used during a lighting build for your local machine and remote ones with LocalJobDefaultProcessCount and RemoteJobDefaultProcessorCount.

For your local machine, you may want to limit its contribution to only a few cores, leaving enough for it to comfortably work on other tasks. By default, a couple of cores will be left free for this, but you may find you need more cores available to work with locally leaving distributed tasks handling more of the work for light build computations.



This type of error means that something is preventing the application from opening in Windows that is not directly the cause of UE4. Below are some steps you can take to resolve the issue:

Make sure you have the appropriate and latest Visual Studio dependencies installed. For Unreal Engine version 4.9 and earlier, you'll need VS2013 dependencies and for 4.10 and later, you'll want to have VS2015 dependencies.

If that does not resolve your issue, try using a free application (for example, Dependency Walker) to troubleshoot any DLL issues that may be preventing the UnrealLightmass.exe from loading.

Currently, Swarm Agent and Coordinator are only supported for Windows. Light builds on Mac and Linux will only build locally.

Swarm does not currently support GPU computations for lighting data.

Lightmass Crashed with "Ran out of memory allocating [some value]"



Click image for full size.

In this situation, Swarm Agent failed to process data for Lightmass because it ran out of memory. This most often happens when you're not using Swarm Coordinator to distribute a build across multiple agents requiring a single machine to do all the work. Lightmass can run out of memory when computing a large Level with many Actors and Lights or if Lightmap resolutions are too high.

You can reduce the chances of getting this error by increasing the amount of RAM on your local machine, adding agents for distribution, lowering the Lightmap resolution of Actors where possible or even adding a Lightmass Importance Volume to focus computations for key areas that players can access.

Lightmass Crashed with "Assertion Failed: (Index >=0)&(Index<ArrayNum))"



Click image for full size.

When you receive this error, you should Clean and Validate your Swarm Cache.

Editor toast pop-up "Light Build Failed. Swarm failed to kick off."

When you attempt to build lighting from the Unreal Editor, you may get this message. If so, the following are some common reasons:

Make sure you do not have multiple instances of Swarm Agent open and running. You can check this by looking at the task processing that is running or in Windows by looking in the Windows Notification Area.

Corrupt levels and/or Actors in the level.

Not having correct exceptions for SwarmAgent.exe for Firewall and Anti-Virus software.

Installation or corruption issue with the Engine. For users with the Launcher, select your engine version drop down and select Verify.

Source build issue with Unreal Lightmass. Rebuild the UnrealLightmass solution.

If Swarm is still failing to start, its ports could be in use by another system process.

Open your Swarm Log and check for the following error message:

Exception details: System.Net.Sockets.SocketException (0x80004005): No connection could be made because the target machine actively refused it 123.456.7.89:8009

You may need to involve your IT department to solve this issue with port assignments, especially since Swarm requires ports 8008 and 8009 to function properly. Without those ports, it will fail to initiate any agents or coordinator. It is not an issue specifically caused by UE4.

How It Works

Settings

Performance

Additional Notes

Troubleshooting

Volumetric Lightmaps replace the Indirect Lighting Cache and Volume Lighting Samples going forward.

The Indirect Lighting Cache can be re-enabled by opening the World Settings > Lightmass Settings and setting the Volume Lighting Method to Sparse Volume Lighting Samples.

Lightmass generates surface lightmaps for indirect lighting on static objects. However, dynamic objects (like characters) need a method of receiving indirect lighting as well. This is done by storing precomputed lighting in all points in space called a Volumetric Lightmap at build-time and then used for interpolation at runtime for indirect lighting of dynamic objects.





Sparse Volume Lighting Samples determined leaking amounts and lighting accuracy. Volumetric Lightmaps improve upon this.

How It Works

From a high-level, the Volumetric Lightmaps system works in the following manner:

Lightmass places lighting samples throughout the level and computes indirect lighting for them during the lighting build.

When it comes time to render a dynamic object, the Volumetric Lightmap is interpolated to each pixel being shaded, providing precomputed indirect lighting.

If no built lighting is available (meaning the object is new or has moved too much), lighting is interpolated to each pixel from the Volumetric Lightmap for Static objects until lighting is rebuilt.

When a Lightmass Importance Volume is placed, the Volumetric Lightmap builds bricks that are made up of 4x4x4 cells (lighting samples). When lightmass is run, the cells are placed over the whole Lightmass Importance Volume and then it uses more cells around static geometry in the scene to capture better indirect lighting results.



Each of these points (or spheres) is a Volumetric Lightmap lighting sample, which uses a Third Order Spherical Harmonic to store the incoming lighting in all directions.



Near objects, any static geometry that is within one of the bricks will use more cells where indirect lighting changes the most. This data structure enables interpolation of indirect lighting to any point in space on the GPU.



(From left to right) A Lightmass Importance Volume with a single Static Mesh placed within the volume. Cells around the static geometry are higher-density; An example representation of a single side of a brick showing the placement of 4x4x4 cells; The same example representation of cells with higher-density when static geometry is present during a lighting build.

Enabling Volumetric Lightmap Visualization

Use the view mode for Volumetric Lightmap to visualize the lighting samples in the level viewport by clicking Show > Visualize > Volumetric Lightmap.





Enable Volumetric Lightmap view mode

Visualization Volumetric Lightmap lighting samples

Click image for full size.

Click image for full size.

When visualizing the Volumetric Lightmap after a lighting build, you can see the density of the lighting samples that gathers around static geometry based on the cells within the Lightmass Importance Volume that is affected. Lighting Samples farther away from the static geometry are less dense since they do not have any geometry near them.





The Indirect Lighting Cache only placed lighting samples above the surface of static geometry. The Volumetric Lightmap places samples in high-densities around static geometry for more detail where indirect lighting changes the most.

Previewing Unbuilt Lighting

The Volumetric Lightmap allows previewing of objects with unbuilt lighting. When you move a Static Mesh that had lighting previously built for it, it will automatically switch to the Volumetric Lightmaps until the next lighting build.





The column in the center has been copied and is now lit by the Volumetric Lightmap until lighting is built again.

Precomputed Lighting on Movable Objects

Unlike the Indirect Lighting Cache where interpolation between a lighting sample happens once for the whole component, the Volumetric Lightmap allows for more detail by interpolating to each pixel instead. This leads to a reliable distribution of detail that results in fewer cases of light leaking.





The added detail of Volumetric Lightmaps blends the character better with the environment.





For movable objects that are embedded in any static geometry, it now provides a better match for the static object lighting compared to the Indirect Lighting Cache.

Precomputed Lighting on Volumetric Fog

Volumetric Lightmaps support static lighting application for Volumetric fog by having each fog voxel interpolate precomputed lighting to its position in space.





Stationary Lights have their indirect lighting stored in lightmaps, which now affects fog.





Skylights are shadowed properly, preventing indoor areas from becoming over-fogged.





Static and Emissive for Static lights affect fog without costing anything since they're all merged into the Volumetric Lightmap.

Settings

The Volumetric Lightmap settings can be accessed from the World Settings located under the Lightmass Settings.



Setting

Description

Volumetric Lighting Method

Technique used for providing precomputed lighting at all positions inside the Lightmass Importance Volume.

Volumetric Lightmap

Lighting samples are computed in an advanced grid which covers the entire Lightmass Importance Volume. Higher-density grids are used near geometry. The Volumetric Lightmap is interpolated efficiently on the GPU per-pixel allowing accurate indirect lighting for dynamic objects and volumetric fog. Positions outside of the Importance Volume reuse the border texels of the Volumetric Lightmap (clamp addressing). On mobile, interpolation is done on the CPU at the center of each object's bounds.

Sparse Volume Lighting Samples

Volume lighting samples are placed on top of static surfaces at medium-density and everywhere else in the Lightmass Importance Volume at low-density. Positions outside of the Importance Volume will have no indirect lighting. This method requires CPU interpolation, so the Indirect Lighting Cache is used to interpolate results for each dynamic object, adding Rendering Thread overhead. Volumetric Fog cannot be affected by precomputed lighting with this method.



Volumetric Lightmap Detail Cell Size

Size of a Volumetric Lightmap voxel at the highest density (used around geometry), in world space units. This setting has a large impact on build times and memory and should be used with caution.

Volumetric Lightmap Maximum Brick Memory Mb

The maximum amount of memory to spend on Volumetric Lightmap Brick data. High-density bricks will be discarded until this limit is met with bricks furthest from geometry discarded first. Trimming memory too heavily will result in inconsistent resolution and it would be better to increase Volumetric Lightmap Detail Cell Size instead.

Volumetric Lightmap Spherical Harmonic Smoothing

Controls how much smoothing should be done to Volumetric Lightmap samples during Spherical Harmonic de-ringing. Whenever highly directional lighting is stored in a Spherical Harmonic, a ringing artifact occurs which manifests as unexpected black areas on the opposite side. Smoothing can reduce this artifact. Smoothing is only applied when the ringing artifact is present. 0 = no smoothing, 1 = strong smooth (little directionality in lighting).

Volume Light Sample Placement Scale

Scales the distances at which volume lighting samples are placed. Volume lighting samples are computed by Lightmass and are used for GI on movable components. Using larger scales results in less sample memory usage and reduces Indirect Lighting Cache update times, but less accurate transitions between lighting areas.

Performance

The following considerations should be taken into account when considering performance and memory usage with Volumetric Lightmaps.

Volumetric Lightmaps on a third person character cost .02ms of GPU time on the PlayStation 4. All Indirect Lighting Cache Rendering Thread cost is removed.

In Epic's Paragon map Monolith, memory usage increased from 5Mb with the Indirect Lighting Cache to 30Mb with Volumetric Lightmaps at default Detail Cell Size settings. Memory usage can be seen under the Stat MapBuildData command in the Editor with Volumetric Lightmap Memory





Click image for full size.



Volumetric Lightmap versus Indirect Lighting Cache

Below are the details of the comparisons that can be made between the Indirect Lighting Cache and Volumetric Lightmaps:

Precomputed Light Volumes/Indirect Lighting Cache

Volumetric Lightmaps

Costly interpolation on the CPU

Efficient interpolation on the GPU

Per-object interpolation, even on instanced components

Per-pixel interpolation

Cannot affect Volumetric Fog

Works with Volumetric Fog

Placed with high-density only on top of static surfaces resulting in leaking from low-density samples

Placed with high-density all all around static surfaces

Black samples outside of the Lightmass Importance Volume

Border voxels are stretched to cover areas outside of the Lightmass Importance Volume

Supports Level Streaming

Level Streaming is supported but requires that all levels (including those streamed in) must be built at the same time. For more details, see the "Additional Notes" section below.

Level Streaming is supported but requires that all levels (including those streamed in) must be built at the same time. For more details, see the "Additional Notes" section below.

Additional Notes

If you reduce the Volumetric Lightmap Detail Cell Size in a large level to get more accuracy, you need to raise the Volumetric Lightmap Maximum Brick Memory Mb as well. Otherwise, the detail cells will get culled causing dynamic object indirect lighting to be less accurate.

Level Streaming requires that all levels (the Persistent and any sub-levels) all be built at the same time, otherwise streamed in levels will not be registered correctly. Streaming levels are primarily a memory optimization where the most detailed bricks volumes are merged into a bigger volume that is a cube (equal dimensional sides) instead of a box (different dimensional sides). The most detailed bricks are streamed with the closest sub-level and higher level bricks are always persistent. In levels that contain actual geometry, the majority of data goes into the most detailed level bricks. There should be little concern given to parts of the volume that appear to be empty (or "wasted") space if the level is filled with geometry. The current system uses a single volume texture, meaning that we can't do much about empty space since we don't support multiple volume textures that has overlap and blending.

Use Volumetric Lightmap Density Volumes to provide local control over the density of samples within areas of the scene. These volumes only supports convex shapes. Add one to your scene from the Place Actors panel in the Level Editor.

Troubleshooting

The Detail Cell Size has been lowered for more samples, but the sample density is lower than requested near static geometry.

Detail bricks can be culled if the Maximum Brick Memory is too low, or if all lighting in the area is nearly equal.

There is light leaking through a wall on characters but no on the Static Meshes nearby.

The only current solutions to leaking are to decrease Detail Cell Size (allowing more memory) or increase the thickness of the wall.

Lighting Plugins

There are several tools and plugins found within the engine that are useful for helping light environments, or providing visualization options for individual objects in a scene.

Explore the tools and plugins below to learn how they can benefit your worksflows and projects.

Lighting Plugins



A Blueprint tool to quickly set up product visualization using an HDR image projection with real-time lighting and shadowing.



A tool that provides a time of day system that is geographically accurate for location, date, and time.



A tool giving you fine control over the Sun's geographic location based on latitude, longitude, date, and time.

Enabling HDRI Backdrop

Workflow

HDR Image Setup

HDR Image Backdrop Mesh Setup

HDRI Backdrop Settings

Projection Center

Lighting Distance Factor

Additional Notes

Additional Resources

It's often desirable to showcase a model in a visually rich context with minimal effort, and using a High Dynamic Range (HDR) image as a backdrop is a common technique to achieve this.The key benefits of using an HDR image as a backdrop for product visualization is that it's relatively quick to set up, it's customizable, and provides beautiful illumination and reflections. However, using an HDR image as a background is not sufficient on its own. For the result to be plausible, there needs to be a fake ground plane that acts as a shadow catcher to ground the object in the HDR image's environment when being lit, creating consistency between the place object for visualization with the background.

The HDRI Backdrop Actor enables you to do all of this and more, improving your product visualization workflow. It automatically handles the following:

Background mesh (such as a sky dome or custom geometry)

Ambient lighting from a Dynamic Sky Light

Dynamic reflections

Ground projection with shadow catching

Enabling HDRI Backdrop

Before you can use this Asset, you need to enable the HDRI Backdrop Plugin for your Project.

Open your Project in the Unreal Editor.

Click the Edit in the Main menu panel and select Plugins.

Under the Rendering category, locate the HDRI Backdrop Plugin and check its Enabled box.



Click image for full size.

Click Restart Now to restart your Project and apply the changes.



Click image for full size.

Workflow

Import a spherical HDR image that uses latitude and longitude into the Content Browser. You can do this by using the Import Button, Right-Click context menu, or Drag-and-Drop methods.

Once imported, be sure to set the appropriate Maximum Texture Size and Mip Gen Settings for the HDR image in the Texture Editor. For additional information, see the HDR Image Setup section of this page.

Use HDRI Haven's site to download some interesting HDR images for free, or you can use some of the ones available in that work well with the HDRI Backdrop Actor. Use the Content Browser's View Options to enable Show Engine Content and Show Plugin Content to display Cubemap Assets available for use. The engine includes some by default that are stored in the DatasmithContent Content/Textures folder.

Click the File in the Main menu panel and select New Level. Then, in the New Level window, select Empty Level.



In the Place Actors panel under Lights, click and drag the HDRI Backdrop asset into the Level Viewport.



With the HDRI Backdrop asset selected in your level, use the Details panel to set the following:



Click image for full size.

Cubemap: Choose a cubemap from the available options or drag one from the Content Browser onto this slot.

Use the Mesh assignment parameter to select an appropriate mesh when using cubemaps that don't display well with a dome or spherical shaped mesh, such as a warehouse or boxed style space.

Size: Adjust the value here to set the size of the mesh that the HDR image is being projected onto.

Projection Center: Select the 3D gizmo to move the projection center to match your camera placement and adjust as needed to reduce skewing and stretching of the HDR image on the backdrop.

See the HDRI Backdrop Settings section of this page for further details about these and other settings you can adjust.

Optionally, add a Light Source and set it to Movable if you want dynamic shadows in your visualization.



Click image for full size.

HDR Image Setup

When you import an HDR image as an Unreal Asset, it isn't modified by the HDRI Backdrop Actor. You need to manually apply several settings in the Texture Editor first:



Click image for full size.

The Imported, Displayed, and Max-In-Game resolution of this HDR image.

The Mip Gen Settings should be set to NoMipmaps to use the full quality.

The Maximum Texture Size should match the larger resolution value of the imported HDR image — 4096 in this example.

If you do not change these values, your HDR image will not appear correctly. It will have low resolution and look muddy.

HDR Image Backdrop Mesh Setup

Not all HDR images are created equal and may require their own custom geometry to project onto. In the Editor, there are several backdrop meshes to choose from, in addition to the HDR images provided.

Before you can see the available Static Meshes in the asset selection drop-down window, you must first use the Settings to enable Show Engine Content and Show Plugin Content.



Click image for full size.

Use the asset selection box next to Mesh to choose an environment mesh to project the HDR image onto. This can be any Static Mesh, such as custom geometry you've created or one of the three that are provided in the engine.



Backdrop Mesh

Mesh

Description

EnviroDome



A sky dome mesh with a ground plane that is ideal for large exterior environment HDR images.

EnviroBoxSharp



A box environment with hard edges that is ideal for interior environments, like a warehouse or space with walls that are well defined.

EnviroBox



A box environment with smoothed edges that is ideal for studio-like environments, often ones like those with single color backdrop cloths.

Below, these examples demonstrate each Mesh backdrop included with the Engine:







Default EnviroDome

EnviroBoxSharp

EnviroBox

HDRI Backdrop Settings

The following settings can be set, enabled, and adjusted from the Details panel of the HDRI Backdrop asset when selected in your level:

Property

Description

Cubemap

Assign an imported HDR image that will be projected onto the ground and backdrop, and is used by the built-in Sky Light source.

Intensity

Sets the intensity of the embedded Sky Light and how emissive the backdrop HDR image is. Higher values result in brighter ambient lighting being samples from the HDR image (cd/m2).

Note that the physical lighting units are measured in cd/m2, like the Sky Light or Emissive Materials. Sun and Sky sources have that range in the thousands of units, which it does hand-in-hand with physical cameras where the Exposure Value (EV) are in the range of EV100:14 (see the "Sunny 16" rule). However, with the HDRI Backdrop asset, it is not required to use physically correct values, but you may need to set the EV to something significantly lower than the EV100:14. It's also worth noting that some HDR images range from 0 to 5.0 or greater than 5 cd/m2 while others are ranging from 0 to 100K units. This means that when you swap HDR images, there may be a noticeable difference in brightness changing.



Size

Sets the size (in meters) of the mesh used to project the HDR image. It controls the diameter of the backdrop mesh and should be adjusted based on the HDR image used, the horizon height, and the content in the scene. For most exterior scenes, a typical size should be approximately 100 meters.

Projection Center

Defines the projection point of the HDR image.

Lighting Distance Factor

Specifies the ground area that will be affected by lighting and shadows. Lit areas will have slightly different shading depending on the intensity and other lighting parameters in the scene. This enables the lit area range to blend smoothly around the camera to reduce shading differences with the background HDR projection.

Use Camera Projection

Disables ground tracking and enables the HDR image to follow the camera.

Mesh

Specify a custom Static Mesh object to use as a backdrop from which the HDR image is projected.

Projection Center

The Projection Center of the HDR image on the backdrop should be set to match the height of the camera used to capture the image.

Select the 3D gizmo to define the central location of the projection in 3D space:

Or, you can manually enter these values in the transform text boxes (however, for the smoothest interaction, it's recommended to use the 3D gizmo in the Viewport):



Z (Height) should be approximately 90 centimeters (cm), which is the average height of a camera tripod used to capture the HDR image. However, the height depends on the height of the camera that was used to capture the image, so you may need a different value.

X and Y enables you to offset the projection origin. In most instances, this shouldn't be changed.

Lighting Distance Factor

You can add your own lighting to your scene and adjust any of the parameters, however, there may be instances where the lighting and shadow intensity differs from the backdrop. The Lighting Distance Factor enables you to define the ground area around the camera to blend the scene's lighting and shadows to reduce these differences.





The Lighting Distance Factor value is a percentage of the Dome's Size value. A typical value would be around 0.5, or a little higher. Artifacts can happen if this is not used carefully. When set too high, a horizontal line will appear at the backdrop edge, and lower values will help to resolve these artifacts.

In instances where compositing shadows and ambient occlusion (AO) on the backdrop is not needed, you can set the value to 0.

Additional Notes

Below are some additional notes and suggestions when working with the HDRI Backdrop asset:

Interaction with the Sky Light Actor

When adding the HDRI Backdrop to your scene, it creates a dynamic Sky Light as a sub-component. If a regular Sky Light exists, it should be deleted. Otherwise, the scene will have multiple Sky Lights which will affect performance, quality, and the desired result in the scene.

HDR Image Stretching

To achieve the best result with minimal stretching, the Camera should be placed and looking around the origin of the projection. Adjusting the Projection Center reduces the stretching in favor of relative scaling.

Ray Tracing Features

The HDRI Backdrop works with all of Unreal Engine's light types along with supported Hardware Ray Tracing features. The HDRI Backdrop Blueprint includes a Sky Light component by default with Cast Ray Tracing Shadow enabled, which is the prerequisite to do proper image-based lighting (IBL) with ray tracing.

Also, keep in mind, that additional Ray Tracing features can be enabled and set in a Post Process Volume, when adding one to your scene. You can control Ambient Occlusion, Global Illumination, Translucency, and Reflections.

Intensity, HDR Content, and Exposure

The HDR image is fed into and driven by a Sky Light. The content of the HDR image will greatly affect the brightness of the scene. The HDRI Backdrop asset doesn't attempt to perform normalizations of the pixel values in the HDR image to provide a stable intensity regardless of its content. This means that when you switch between different HDR images, you will need to adjust the Intensity since this is not handled automatically. However, this may be added in a future release.

High Precision Normals

Changing this G Buffer format option encodes the Default format at 16 bits per-channel. It produces higher quality reflections along smooth, high-poly geometry. When using the default format, you may see artifacts that present themselves as wavy reflections across these smooth, reflective surfaces.

In the Project Settings under Rendering > Optimizations, use the GBuffer Format dropdown to select High Precision Normals.





Reflection Capture Resolution

Changing this value enables you to have high quality reflections from Cubemaps and HDR images projected onto the skydome and Reflection Capture Actors in the scene.

In the Project Settings under the Rendering > Reflections category, set a power of 2 value for your desired Reflection Capture Resolution. This resolution will automatically apply to all reflection captures placed in your scene. For the Sky Light, you can set the maximum resolution value you want to use.





Additional Resources

NASA's Juno 3D Model provided by "NASA 3D Resources."

HDR Images provided by "HDRI Haven."

Sky Atmosphere Component

Project Templates and Setup

Enabling the Sun Position Calculator Plugin

Using the Sun and Sky Actor

Properties and Settings

ArchVis Template Level Examples

Exterior

Interior

Additional Notes

Additional Resources

The Sun Position Calculator plugin includes a Geographically Accurate Sun Positioner that gives you fine control over the Sun's position based on a geographic location and date in time. The SunSky Actor is part of this same plugin. It uses the same mathematical equations to govern the position of the Sun in the sky and includes a bundle of components—a Directional Light, Sky Light, and SkyAtmosphere—to produce true-to-life renderings that show realistic patterns of sunlight and shadow.

The SunSky Actor makes it simple and quick to set up your scenes no matter your aesthetic choice, with settings for Daylight Saving Time (DST), the date, and the time of day. It's designed to work well within games and other industries, like our Architectural, Engineering and Construction (AEC), or Automotive, Product Design and Manufacturing.

Project Templates and Setup

When creating a new project, you can select from different industry types and templates relevant to your needs.

Depending on the template you choose, some properties are enabled/disabled by default. These properties affect the look and functionality of the SunSky Actor.

Keep the following in mind when choosing a Template Category and Template:

The project setting for Extend default luminance range in Auto Exposure settings is required for this SunSky Actor to display correctly without editing its properties.

Some templates for each template category enable the Sun Position Calculator by default. You can verify this by going to the main menu and selecting Edit > Plugins and searching for the plugin once you've opened a new project.

This page demonstrates how to use the Sun and Sky Actors within the ArchVis Unreal Engine (UE) Template. To use this template, simple create a new project, select the Architecture, Engineering, and Construction New Project Category, and select the ArchVis template.

Enabling the Sun Position Calculator Plugin

From the main menu, choose Edit > Plugins.

Find the Sun Position Calculator plugin under the Misc category and check it's Enabled checkbox.



Click image for full size.

Click the Restart Now button to apply your changes and re-open the Unreal Editor.



Click image for full size.

Using the Sun and Sky Actor

Once you've enabled the Sun Position Calculator plugin, you'll find a new Actor called Sun and Sky available in the Editor Place Actors panel in the Lights tab.



Drag it into the Level viewport.



Click image for full size.

When adding a SunSky Actor to your scene, it's best to remove any Directional Light, Sky Light, or SkyAtmosphere components that are already there. Otherwise, it's best to start with a new Blank Level if you're starting from scratch.

When you drag a SunSky Actor into the Level and it appears bright white, you can do one of two things:

Enable Extend default luminance range in Auto Exposure settings in the Project Settings under the Rendering category (under the Default section).



Click image for full size.

Or, if you don't want this project setting to affect the look of your project, you can select the SunSky Actor's Directional Light and use a lower Lux intensity (open the SunSky actor, select the Directional Light under Components, locate the Light section in the Details pane, lower the Intensity until you're happy).



The SunSky Actor contains movable Actors for Directional Light, SkyLight, and SkyAtmosphere components as part of its Blueprint. When the scene component SunSky(Self) is selected, the exposed Blueprint properties that can be set—such as those for date, time of day, latitude and longitude—are displayed. Selecting the individual components—like those for the Directional Light or SkyAtmosphere—displays their own properties. These properties—like mobility and intensity—can also be set.



Properties and Settings

The following adjustable properties are found in the SunSky Actor Details panel.



Since Transformation properties are pretty standard for all Actors, we've skipped them below.

Property

Description



Location



Latitude

The degree north or south of the equator.

Longitude

The degree east or west of the prime meridian.

Time Zone

The specified time for a given region of the world. The time zone uses GMT as a basis.

North Offset

Sets the directional position of North for the SunSky Actor and its components.



Date



Month

Sets the current month.

Day

Sets the current day.

Use Daylight Saving Time

Enables Daylight Saving Time (DST).

DST Start Month

Sets the Month at which DST starts in the current year.

DST Start Day

Sets the Day at which DST starts in the current year.

DST End Month

Sets the Month at which DST ends in the current year.

DST End Day

Sets the Day at which DST ends in the current year.

DST Switch Hour

Sets the beginning and ending hours of DST.



Time



Solar Time

Sets the time of day.

Enter this value as a float in military time. For example, 12:30 AM would be 00.5 and 12:30 PM would be 12.5.



ArchVis Template Level Examples

When you create a project, the template category for Architecture, Engineering, and Construction includes a template called ArchVis.



This template project is dedicated to architecture visualization workflows, with examples for sun studies, interior rendering, and non-photorealistic stylized renderings. It includes the following assets already set up for you to use:

Multiple Levels that contain scenes set up to demonstrate visualization with physically accurate lighting using the SunSky Actor.

Lighting configuration and Post Process Volume with ray-tracing features already set for those projects that have enabled ray tracing.

Example Cameras and Sequencers used to render out the scene. These also include dynamic time-of-day transitions.

This template also enables the Datasmith plugin, which is a collection of tools and plugins designed to import scenes and assets created in offline rendering applications, like 3ds Max and CAD software, into a real-time engine.

Exterior

The Exterior Level demonstrates usage of the SunSky Actor with multiple cameras used with Sequencer to demonstrate a time-of-day sequence while moving through the scene in various locations. It can be found in the Content/ArchVisProject folder.

It's also a use of the SunSky Actor components lighting the scene dynamically, as well as a demonstration of the various real-time Ray Tracing when they are enabled for the project.

Interior

The Interior Level demonstrates usage of the SunSky Actor components to light the scene with precomputed static lighting. It can be found in the Content/ArchVisProject folder.

This includes:

Using Lightmass to generate baked global illumination and lighting for the scene.

Using Lightmass Importance Volumes and Lightmass Portals to control and focus the area from where Lightmass emits photons in.

Additional Notes

Ray Tracing features enabled by default on the SunSky Actor for the Directional Light and Sky Light to both support casting of ray-traced shadows.

It's possible to manually change rotational values of the Directional Light in the SunSky Actor. However, when you change other settings that affect other parts of the SunSky Actor, your manually adjusted rotational values will be reset to the default position. This prevents contradicting values incorporated with the idea of a geolocated calculation.

SkyLight Actors now come with the Real Time Capture mode enabled by default. This should help you better capture your SkyAtmosphere Component, Volumetric Clouds, Height Fog, and more. Just remember that this mode is only available when using the dynamic or stationary modes. If you'd like to disable the Real Time Capture mode, simply select the SkyLight Actor, navigate to the Details panel, and uncheck the Real Time Capture box at the top of the Light section.

Additional Resources

When you input a location by name at the website LatLong.net, it returns a map view, along with latitude, and longitude coordinates.

The website TimeAndDate.com has a section of their site dedicated to the Time Zone Map, which can be useful when figuring out what time zone you want to set the SunSky Actor to use. By default, it uses -5 GMT.

Getting Started

Modifying Settings at Runtime

In some contexts, the position of the Sun in the sky is not an aesthetic choice. Instead, it is a critical design factor.

This is often true in large architectural and construction projects, but it may apply any time you need to produce true-to-life renderings that show realistic patterns of sunlight and shadow.

In these cases, you need to be able to place the Sun in your Unreal Engine Level precisely, according to the same mathematical equations that govern the position of the Sun in the real sky of Earth. These complex equations incorporate a number of settings that include the geographical location of the observer on the globe, the date, and the time of day.

The Sun Position Calculator Plugin solves these mathematical equations for you in the Unreal Engine. You define the latitude, longitude, cardinal points, date, and time of day. Then, the Sun Position Calculator works in tandem with the default sky sphere in the Unreal Engine to place the Sun disk in the sky sphere and to orient the main Directional Light in the Level.

Getting Started

Prerequisite: The Sun Positioner works with the default BP_SkySphere that you'll find already set up for you in most new levels you create in the Unreal Editor. You must make sure that your Level contains a BP_SkySphere instance.

To get started:

From the main menu, choose Edit > Plugins.

Find the Sun Position Calculator plugin under the Misc category, and check its Enabled checkbox.



Click for full image.

Click Restart Now to apply your changes and re-open the Unreal Editor.



Click for full image.

Navigate to the Content Browser, open the Settings and enable both Show Engine Content and Show Plugin Content.



Find the BP_SunPosition Asset in the SunPosition Content folder, and drag it into the Viewport.



It is represented by a gizmo that looks like the cardinal points of a compass. (This gizmo only appears in the Unreal Editor, not when you run your Project.)

Select the gizmo in the Viewport, or the BP_SunPosition Actor in the Outliner.



Click for full image.

In the Details panel, set up the properties of your scene that govern the Sun placement:



Setting

Description

Latitude

Use negative values for coordinates South of the equator, and positive values for coordinates North of the equator.

Longitude

Use negative values for coordinates West of the meridian, and positive values for coordinates East of the meridian.

Time Zone

Set this value to indicate the number of hours your scene is offset from Coordinated Universal Time (UTC) or Greenwich Mean Time (GMT).

North Offset

Controls the relation between the objects in your Level and the cardinal points of the compass. Changing this control also rotates the visual placement of the BP_SunPosition gizmo in your Level. Adjust this value until the cardinal points shown on the gizmo point are oriented correctly with respect to the objects in your Level.

Don't rotate the gizmo itself in the Level Viewport using the Rotate tool. Only use this North Offset setting to control the cardinal points.

Date and Time

Set the time of year and the time of day you want to simulate.

As you change the values of these properties, you should see the Sun move around in your sky and the shadows change in the Unreal Editor.

Modifying Settings at Runtime

You can change the settings for the BP_SunPosition Actor at runtime. This allows you to drive the position and light angle of the Sun based on UI widgets or other gameplay events.

In order to be able to change the angle of the sunlight at runtime, you need to make the main Directional Light in your Level Movable. Select the Directional Light in the Outliner or the Level Viewport, find the Mobility setting in the Details panel, and set it to Movable.



When you want to modify a value at runtime in a Blueprint script, you need an Object Reference to the BP_SunPosition Actor contained in your Level. You can retrieve it dynamically using the Get All Actors of Class node as shown below:



Because Get All Actors of Class can be expensive, it's best to do this once (say, when the level is loaded or your widget is constructed) and saving the result to a variable, rather than doing it each time you need to get or set a value.

Once you have the Object Reference, drag right from its output port and expand the Variables category to find the list of Get and Set nodes that you can use to retrieve and set the same values exposed in the Details panel in the Unreal Editor.



Set as many values as you need to their new values. When you're done, drag right from the output port of the BP_SunPosition variable and invoke its Update Sun node.



For example, the following snippets from a Widget Blueprint set up a UI slider that changes the hour to any value between 6am and 10pm.



Click for full image.

In action, the slider looks like this:

Types of Lights

Overview of Light Types

Light Mobility

Overview of Light Mobility

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Unreal Engine provides several types of light to create nearly any type of lighting scenario and to work with small to large scale worlds. Each of these types of lights also has its own mobility option to define how it interacts with the other Actors in the scene and how the lighting system will utilize the light.

Types of Lights

The types of lights available in the Editor make it possible to light your world in various styles and configurations to achieve the look you want for your project. With these light types, you can light any size scenes from large sprawling worlds to small localized interiors.

Unreal Engine provides the following types of lights:

Directional Lights are the primary outdoor light, or any light that needs to appear as if it's casting light from extreme, or near infinite, distances.

Sky Light captures the background of the scene and applies it to the Level's geometry.

Point Lights act as a light bulb, casting light in all directions from a single point.

Spot Lights emit light from a single point in a direction limited by a set of cones.

Rect Lights emit light from a rectangular surface in a direction.

Directional and Sky Lights are useful for large exteriors or to provide lighting and shadowing through interior openings. For large exteriors, Directional Lights are most effective for lighting dense foliage and other geometry more efficiently.





Directional Light

Sky Light

Point, Spot, and Rect Lights are useful for lighting smaller localized areas. Their type and properties can help define their shape and look within a given scene. These types of lights also share a lot of the same properties.







Point Light

Spot Light

Rectangular Area Light

Overview of Light Types



The basics of undestanding directional lights.



The basics of undestanding sky lighting.



The basics of undestanding point lights.



The basics of undestanding spot lights.



The basics of undestanding rectangular area lights.

Light Mobility

Each type of Actor in a scene has its own Mobility setting that controls whether it is allowed to move or change in some way during gameplay. For Light Actors, the mobility selection defines how the light will be treated in the scene when a light build is taking place.

It's important to choose the type of light mobility that makes the most sense for your project as they will impact performance, look, and design choice. Some features of lights are limited in their functionality or not entirely supported for some platforms or machines. For example, dynamic shadowing is not supported for all types of lights on mobile platforms.

Each Light Actor has three mobility states:



Mobility State

Description

Static

This mobility is reserved for Light Actors that are not intended to move or update in any way during gameplay.

Static lights will contribute to pre-calculated lightmaps using Lightmass. These lights will illuminate the scene and generate lighting data for any Actors set to Static and Stationary, but for Movable ones, they will be lit by lighting data stored in the Indirect Lighting Cache or Volumetric Lightmaps to light them.

Stationary

This mobility is reserved for Actors that can during gameplay, but not move.

These lights can change in some way during gameplay, such as having their color or intensity changed, or turned completely off. Stationary Lights contribute to pre-calculated lightmaps using Lightmass, but they can also cast dynamic shadows for movable objects. Stationary lights come with added cost and are limited by the number of lights that can affect a single object at any given time. For example, A single object can only be affected by up to four Stationary Lights at any time.

Movable

This mobility is reserved for Light Actors that need to be added, removed, or moved during gameplay.

These lights only cast dynamic shadows. In addition to being able to move them during gameplay, they can also change their color, intensity, and other light properties as needed.

Care must be taken when using lights with this mobility since their shadowing cost is the most costly. However, non-shadowing Movable lights are very inexpensive to calculate, and carry a lower cost than lights that are set to Static since there is no lighting data that needs to be saved to disk.

Overview of Light Mobility



Fully dynamic lights capable of changing all its properties during runtime.



Partially dynamic and precomputed lighting capable of changing some of its properties during runtime.



Precomputed lighting baked into textures that cannot change and has no lighting cost during runtime.



Directional Light Properties

The Directional Light simulates light that is being emitted from a source that is infinitely far away. This means that all shadows cast by this light will be parallel, making this the ideal choice for simulating sunlight. The Directional Light when placed can be set to one of three Mobility settings:

Static - (pictured left) which means that the light cannot be changed in game. This is the fastest method for rendering and allows for baked lighting.

Stationary - (also pictured left) which means the light will only have its shadowing and bounced lighting from static geometry baked by Lightmass, all other lighting will be dynamic. This setting also allows for the light to change color and intensity in game, but, it does not move and allows partial baked lighting.

Moveable - (pictured left) which means the light is totally dynamic and allows for dynamic shadowing. This is the slowest in terms of rendering but allows for the most flexibility during gameplay.

Below you will see a representation of sunlight being cast through an opening in a roof.





The left image shows just the light, the right image has its Shadow Frustum enabled in order to see that the Directional Light is casting parallel light rays.

Light Direction (pictured left) is indicated by an arrow that points in the direction the light will emit which is useful for placing and orientating your light as needed.

Directional Light Properties

The properties of a Directional Light are broken up into 5 categories: Light, Light Shafts, Lightmass, Light Function and Cascaded Shadow Maps:

Light

Property

Description

Intensity

Total energy that the light emits.

Light Color

The color that the light emits.

Used As Atmosphere Sun Light

Uses this Directional Light to define the location of the sun in the sky.

Affects World

Disables the light completely. Cannot be set at run time. To disable a light's effect during runtime, change its Visibility property.

Casts Shadows

If the light casts shadows.

Indirect Lighting Intensity

Scales the indirect lighting contribution from the light.

Min Roughness

Min roughness effective for this light, used for softening specular highlights.

Shadow Bias

Controls how accurate the shadows from this light are.

Shadow Filter Sharpen

How much to sharpen shadow filtering for this light.

Cast Translucent Shadows

Whether this light is allowed to cast dynamic shadows through translucent objects.

Affect Dynamic Indirect Lighting

Whether the light should be injected into the Light Propagation Volume.

Cast Static Shadows

Whether this light casts static shadows.

Cast Dynamic Shadows

Whether this light casts dynamic shadows.

Affect Translucent Lighting

Whether the light affects translucency or not.

Light Shafts

Property

Description

Enable Light Shaft Occlusion

Whether to occlude fog and atmosphere inter scattering with the screen space blurred occlusion from this light.

Occlusion Mask Darkness

How dark the occlusion masking is, a value of 1 is no darkening.

Occlusion Depth Range

Everything close to the camera than this distance will occlude the light shafts.

Enable Light Shaft Bloom

Whether to render light shaft bloom for this light.

Bloom Scale

Scales the additive bloom color.

Bloom Threshold

Scene color must be larger than this to create bloom in the light shafts.

Bloom Tint

What color to tint the bloom coming from the light shafts.

Light Shaft Override Direction

Can be used to make the light shafts come from somewhere other than the light's actually direction.

Lightmass

Property

Description

Light Source Angle

Angle that the directional light's emissive surface extends relative to a receiver, affects penumbra sizes.

Indirect Lighting Saturation

A value of 0 will completely desaturate this light in Lightmass, 1 will be unchanged.

Shadow Exponent

Controls the falloff of shadow penumbras.

Light Function

Property

Description

Light Function Material

The light function material to be applied to this light.

Light Function Scale

Scales the light function projection.

Light Function Fade Distance

The distance at which the light function should be completely faded to the value in Disabled Brightness.

Disabled Brightness

Brightness factor applied to the light when the light function is specified but disabled, say from the property above: Light Function Fade Distance.

Cascaded Shadow Maps

Property

Description

Dynamic Shadow Distance MovableLight

How far Cascaded Shadow Map dynamic shadows will cover for a movable light, measured from the camera.

Dynamic Shadow Distance StationaryLight

How far Cascaded Shadow Map dynamic shadows will cover for a stationary light, measured from the camera.

Num Dynamic Shadow Cascades

Number of cascades to split the view frustum into for the whole scene.

Cascade Distribution Exponent

Controls whether the cascades are distributed closer to the camera (larger exponent) or further from the camera (smaller exponent).

Cascade Transition Fraction

Proportion of the fade region between cascades.

Shadow Distance Fadeout Fraction

Controls the size of the fade out region at the far extent of the dynamic shadow's influence.

Use Inset Shadows for Movable Objects

(Stationary lights only) Whether to use per-object inset shadows for movable components, even though cascaded shadow maps are enabled.

Atmosphere and Cloud

Directional Lights support the Sky Atmosphere and the Volumetric Clouds features of Unreal Engine.

Additional information and demonstration can be found in the Volumetric Clouds page under the Directional Light Interactions and Shadowing section.

Property

Description



Atmosphere and Cloud



Atmosphere Sun Light

Whether the Directional Light can interact with the atmosphere, clouds and generate a visual sun disk, all of which compose the visual sky.

Cast Shadows on Clouds

Whether the light should cast any shadows from opaque meshes onto clouds. This is disabled for any secondary Directional Lights that have Atmosphere Sun Light enabled and set to Atmosphere Sun Light Index of 1, such as another sun or as a moon light.

Cast Shadows on Atmosphere

Whether the light should cast any shadows from opaque meshes into the atmosphere when a SkyAtmosphere is used.

Cast Cloud Shadows

Whether the light should cast any shadows from the clouds onto the atmosphere and other scene elements.

Cloud Scattering Luminance Scale

Scales the light contribution when scattered in cloud participating media. This can help counter balance the fact that our current multiple scattering solution is only an approximation.



Advanced Properties



Atmosphere Sun Light Index

Two atmosphere lights are supported at any time to represent the sun and moon, or two suns. Use this index to set the primary and secondary light source. For example, the sun would be 0 and the moon would be 1.

Atmosphere Sun Disk Color Scale

A color multiplied with the sun disk luminance.

Per Pixel Atmosphere Transmittance

Whether to apply atmosphere transmittance per pixel on opaque meshes instead of using the light's global transmittance.

Cloud Shadow Strength

The strength of the shadow. Higher values will block more light.

Cloud Shadow on Atmosphere Strength

The strength of shadows on the atmosphere. When set to 0, shadows on the atmosphere is disabled.

Cloud Shadow on Surface Strength

The strength of shadows on opaque and transparent meshes. When set to 0, shadows on opaque and translucent surfaces is disabled.

Cloud Shadow Depth Bias

Controls the bias applied to the front shadow depth of the volumetric cloud shadow map.

Cloud Shadow Extent

The world space radius of the cloud shadow map around the camera. Measured in kilometers (km).

Cloud Shadow Map Resolution Scale

Scales the cloud shadow map resolution. The resolution is clamped by r.VolumetricCloud.ShadowMap.MaxResolution.

Cloud Shadow Ray Sample Count Scale

Scales the number of samples used for shadow map tracing. The sample count resolution is clamped with r.VolumetricCloud.ShadowMap.RaySampleMaxCount.

Supported Shadow Types

Shadow Biasing

Shadow Map Caching

Shadow Map Caching Performance

Shadow Map Caching Limitations

Lights that have their Mobility set to Movable are lights that can be or be changed dynamically in any way during runtime — these are sometimes called dynamic lights. Their performance cost is higher than those lights that are Static or Stationary, and depend on the number of meshes affected by the light along with the triangle count of those meshes. For example, a shadow-casting dynamic light with a large radius has a higher performance cost than one with a smaller radius.

Movable light's support dynamic indirect lighting when used with Lumen Global Illumination and Reflections.

Of the three light mobilities to choose from, Movable lights have varying quality (depending on the type of dynamic shadows being used), highest mutability, and highest performance cost.

Supported Shadow Types

Movable lights support a lot more dynamic lighting and shadowing methods than Static and Stationary Lights do. The following types of shadowing are supported for lights that are Movable:

Shadow Maps provide whole scene dynamic shadows. It is the standard shadowing method for all dynamic shadowing in the engine, and they work across most platforms for all light types. Shadow maps do not provide soft area shadowing, like many of the other shadowing methods in this list.

Virtual Shadow Maps provide consistent, high resolution shadow maps that works well with film-quality assets and large dynamically lit open worlds. They provide soft area shadowing and work well with Nanite, Lumen Global Illumination and Reflections, and World Partition to deliver the highest quality at a reasonable performance cost. Virtual Shadow Maps are supported on the latest console and PC platforms that support DirectX 11 or DirectX 12.

Ray Tracing Shadows simulate soft area lighting effects for the highest shadowing quality at reasonable performance. They use the ray tracing architecture supported by NVIDIA GPU hardware running on Windows 10 (or later) with DirectX 12.

Mesh Distance Field Shadows provide lighting effects and soft area shadowing from meshes based on a distance field representation of the mesh. This method requires the distance field meshes for the project, which is needed for software ray tracing in Lumen Global Illumination and Reflections, and Distance Field Ambient Occlusion.

Shadow Biasing

The default shadow mapping techniques in Unreal Engine work across all platforms for Movable lights to provide dynamic shadowing. Shdaow mapping comes with some limitations that produce artifacts, such as faceted shadows on curved surfaces and shadow contact hardening at surface intersections that can make objects look like they are floating or not grounded in the scene.

Shadow biasing is a per-light set of properties that help reduce these types of artifacts while improving accuracy of self-shadowing and contact hardening from these light sources. These biasing settings work by finding a trade-off between balancing accuracy in one areas while reduing self-shadowing artifacts in another.





Adjusting the Shadow Slope Bias reduces self-shadowing artifacts at the loss of shadow accuracy, which can cause a peter-panning (or floating) effect for grounded objects in the scene. Slope bias adjustments won't solve all your self-shadowing issues with dynamic lighting, but it can solve most of them. It's up to you to decide the right balance for your project.

Directional Lights have an extra depth bias property that controls the bias strength across the Cascaded Shadow Maps (CSM). It reduces dicontinuities of shadow artifacts at cascade transition points.





The following properties are available on Lights to adjust shadow biasing:

Property

Description

Shadow Cascade Bias Distribution

(Directional Lights Only) Controls the depth bias scaling across Cascaded Shadow Maps. It mitigates the difference in shadow artifacts between different cascade transitions. Values of 1 scales shadow bias based on each cascade's size. 0 scales shadow bias uniformly across all cascades.

Shadow Bias

Controls how accurate self shadowing of whole scene shadows are from this light source. At 0, shadows start at their shadow caster surface but there will be many artifacts. Larger values have shadows start farther from their caster and there won't be any self-shadowing artifacts, but the object may appear to float above a surface. Values around the mid-point of 0.5 is a good trade-off balance between accuracy and reduction in self-shadowing artifacts.

Shadow Slope Bias

This works in additions to Shadow Bias to control the accuracy of self-shadowing of whole scene shadows from the selected light. This property increases the amount of bias depending on the slope of a given surface. At 0, shadows start at their caster surface but will have many self-shadowing artifacts. Larger values will start shadows farther from their caster and there won't be any self-shadowing artifacts but objects might appear to float above a surface.

Shadow Filter Sharpen

Adjusts the sharpness of direct shadowing from Stationary or Movable lights. It can reduce the soft shadowing effect of shadow mapping.

Shadow Map Caching

Shadow map caching is a feature of Movable lights that makes shadow casting from Point and Spot Lights much more affordable in games. In Levels where you have assets that don't need to move, their shadow calculation is costing performance each frame. Shadow map caching looks at these assets that have their Mobility set to Static or Stationary and doesn't need to recalculate them each frame unless something changes with them or the light.

Shadow map caching has a significant impact on performance, especially in levels where there are a lot of assets affected by a lights.

For instance, in a moderately sized scene with three shadow-casting Movable Point lights, they could take upwards of 14 milliseconds to render shadow depths. With cached shadows enabled, those same three lights may take around 1 millisecond to render shadow depths.

Shadow map caching require memory to store the cached shadows, and for large enough scenes, you may need to adjust the amount of memory alloted to them with the console command r.Shadow.WholeSceneShadowCacheMb.

Shadow Map Caching Performance

Check the performance cost of shadow map caching by enabling/disabling caching with the console command r.Shadow.WholeSceneShadows. Be sure to first have

You can check the performance of cached shadows by opening the stat window for shadow rendering with Stat ShadowRendering. Then enable/disable cached shadows with the console command r.Shadow.WholeSceneShadows.





Shadow Map Cashing: Enabled

Shadow Map Caching: Disabled

Shadow Map Caching Limitations

Shadow map caching can significantly decrease the cost of using dynamic shadowing in your Levels, but there are some limitations that must be considered when using with unsupported features of the engine.

By default, caching can only happen when the following assets meets these criteria:

Primitives in the Level must have their Mobility set to Static or Stationary.

Materials that use World Position Offset will not be cached.

Point Lights and Spot Lights are supported and must have their Mobility set to Movable while casting shadows.

Lights that move around will not have their shadows cached.

Materials that use animated Tessellation or Pixel Depth Offset can cause artifacts because their shadows will be cached but look incorrect with the asset.



Point Light Properties

Point Lights work much like a real world light bulb, emitting light in all directions from the light bulb's tungsten filament. However, for the sake of performance, Point Lights are simplified down emitting light equally in all directions from just a single point in space. The Point Light when placed can be set to one of three Mobility settings:

Static - (pictured left) which means that the light cannot be changed in game. This is the fastest method for rendering and allows for baked lighting.

Stationary - (also pictured left) which means the light will only have its shadowing and bounced lighting from static geometry baked by Lightmass, all other lighting will be dynamic. This setting also allows for the light to change color and intensity in game, but, it does not move and allows partial baked lighting.

Moveable - (pictured left) which means the light is totally dynamic and allows for dynamic shadowing. This is the slowest in terms of rendering but allows for the most flexibility during gameplay.

Two examples of a Point Light placed inside a level are shown below.





The image on the left is a Point Light without its radius showing, and the same light with it enabled is shown in the right image, giving a good impression of where the light will affect the world.

While the light from a Point Light only emits from that point in space, having no shape, Unreal Engine 4 can give a point light a radius and a length for use within reflections and specular highlights to give the point light more of a physical feel.



Point Light Properties

The properties of a Point Light are broken up into 4 categories: Light, Light Profiles, Lightmass, and Light Function.

Light

Property

Description

Intensity

Total energy that the light emits.

Light Color

The color that the light emits.

Attenuation Radius

Bounds the light's visible influence.

Source Radius

Radius of light source shape.

Source Length

Length of light source shape.

Affects World

Disables the light completely. Cannot be set at run time. To disable a light's effect during runtime, change its Visibility property.

Casts Shadows

If the light casts shadows.

Indirect Lighting Intensity

Scales the indirect lighting contribution from the light.

Use Inverse Squared Falloff

Whether to use physically based inverse squared distance falloff, where AttenuationRadius is only clamping the light's contribution.

Light Falloff Exponent

Controls the radial falloff of light when UseInverseSquaredFalloff is disabled.

Specular Scale

Multiplier on Specular Highlights. Use only with great care! Any value besides 1 is not physical! Can be used to artistically remove highlights mimicking polarizing filters or photos touch up.

Shadow Bias

Controls how accurate the shadows from this light are.

Shadow Filter Sharpen

How much to sharpen shadow filtering for this light.

Contact Shadow Length

The length of screen space to ray trace for sharp contact shadows. A value of zero disables this option.

Cast Translucent Shadows

Whether this light is allowed to cast dynamic shadows through translucent objects.

Affect Dynamic Indirect Lighting

Whether the light should be injected into the Light Propagation Volume.

Cast Static Shadows

Whether this light casts static shadows.

Cast Dynamic Shadows

Whether this light casts dynamic shadows.

Affect Translucent Lighting

Whether the light affects translucency or not.

Light Profiles

Property

Description

IES Texture

The IES "Texture" used for the light profile. IES files are ASCII though Unreal represents them as textures, they are not image files.

Use IES Brightness

If false, it will use the Brightness of the light to determine how much light to produce. If true, it will use the IES files brightness in Lumens (usually much larger than default values on lights in Unreal).

IES Brightness Scale

Scale for IES brightness contribution, as they can seriously blow out a scene.

Lightmass

Property

Description

Indirect Lighting Saturation

A value of 0 will completely desaturate this light in Lightmass, 1 will be unchanged.

Shadow Exponent

Controls the falloff of shadow penumbras.

Light Function

Property

Description

Light Function Material

The light function material to be applied to this light.

Light Function Scale

Scales the light function projection.

Light Function Fade Distance

The distance at which the light function should be completely faded to the value in Disabled Brightness.

Disabled Brightness

Brightness factor applied to the light when the light function is specified but disabled, say from the property above: Light Function Fade Distance.

Rect Light Properties

Light

Lightmass

Light Functions

Light Profiles



The Rect Light emits light into the scene from a rectangular plane with a defined width and height. You can use them to simulate any kind of light sources that have rectangular areas, such as televisions or monitor screens, overhead lighting fixtures, or wall sconces.

RectLights do not behave like true area lights in all situations. See the discussion on mobility settings below.

Each Rect Light has two key settings, Source Width and Source Height, which determine the size of its rectangle along its local Y and Z axes:



The Rect Light has a spherical attenuation radius, like a Point Light or a Spot Light. As shown in the image above, the Rect Light emits light within its sphere of attenuation only in the positive direction of its local X axis, similar to a Spot Light with its cone set to 180 degrees. However, specular highlights for Rect Lights show the width and height of the light's rectangular area.

Like other types of light sources, Rect Lights have three Mobility settings:

Static: With this setting, the light's direct and indirect illumination are both baked to lightmaps when you build lighting for your level. This is the fastest method for rendering, but it means that the light cannot be changed in the game at runtime.

Stationary: With this setting, only the indirect illumination from the light is baked into lightmaps when you build lighting for your level. The direct lighting cast by the light is calculated dynamically every frame in the game. This setting preserves the high-quality soft shadowing and global illumination pre-computed by Lightmass, but it also permits you to change the color and intensity of the light in the game at runtime.

Movable: With this setting, the light is totally dynamic. None of its direct or indirect illumination is baked by Lightmass at all. This allows your light to cast correct shadows from moving objects in the game at runtime every frame. However, this setting is typically the slowest to render.





The mobility setting you choose also has a significant effect on the way the Rect Light casts light into the scene:

If your Rect Light is set to Static or Stationary, Lightmass takes the width and height of the light into account when it computes the illumination cast from the light source. For example, in the image on the left above, the light from the left and right extents of the rectangle reaches under the model and illuminates most of the floor.In this case, the light emitted from the RectLight is sampled from multiple points across its rectangular surface. Each sampled light emits a fraction of the overall light intensity, so you can think of the RectLight as a simulation of many weak point lights distributed across the rectangular surface. The number of samples increases with the quality of your light build. Preview builds use few samples, so their shadows can look quite blocky. However, raising the quality setting eventually converges toward smoother results, as shown above.

If you set your Rect Light to Stationary Mobility, you may be able to achieve better quality shadows by also enabling the Use Area Shadows for Stationary Light setting.

If your Rect Light is set to Movable, the width and height of the rectangle are only used for specular reflections. The actual light is emitted outward from the center of the Rect Light, similar to a Point Light. For example, in the image on the right above, the sharp shadow cast on the floor indicates that the light is emitted from the center of the rectangle.

Rect Lights that are set to Stationary or Movable are typically much more expensive to render than a Point Light or Spot Light with the same mobility. The exact cost scaling depends on the platform, but in general, Movable lights cost more than Stationary lights. The cost is also due in part to shadow casting, so you may be able to minimize the extra cost by turning off the Casts Shadows option. Alternatively, you could opt to set the mobility of the light to Static, which has no effect on runtime rendering performance at all.

The forward renderer does not currently support Rect Lights. If you need to use forward rendering in your Project, use a Spot Light or Point Light instead.

Rect Light Properties

The properties of a Rect Light are broken up into 4 categories: Light, Lightmass, Light Function and Light Profiles.

Light

Property

Description

Intensity

The total energy that the light emits. Note that for Rect Lights, this value is averaged over the surface area of the light. As you increase the Source Width and Source Height of the light, you will need to increase the Intensity in order to maintain the same apparent brightness.

Light Color

The color that the light emits.

Attenuation Radius

Bounds the light's visible influence. Like a Point Light or a Spot Light, a Rect Light has a spherical attenuation radius.

Source Width

The extent of the Rect Light along its local Y axis.

Source Height

The extent of the Rect Light along its local Z axis.

Barn Door Angle

The angle of the barn door attached to the Rect Light.

Barn Door Length

The length of the barn door attached to the Rect Light.

Source Texture

Specifies a Texture that will be applied on the emitting rectangle. This Texture affects the color of the light emitted by the Rect Light, and is visible in specular reflections. Note, however, that this is only an approximation. It does not affect shadows cast by the Rect Light. Use an HDR image if possible, to avoid banding artifacts. In addition, make sure that the Level of Detail > Mip Gen Settings option for your Texture is set to Blur5.

Temperature

The color temperature of the light, measured in Kelvin.

Use Temperature

Determines whether or not the Temperature setting should apply to this light.

Affects World

Enables and disables the light completely. Cannot be set at run time. To disable a light's effect during runtime, change its Visibility property.

Cast Shadows

Determines whether or not the light casts shadows from objects in the Level.

Indirect Lighting Intensity

Scales the indirect lighting contribution from the light.

Volumetric Scattering Intensity

Scales the intensity and color of the volumetric scattering from this light.

Advanced Settings

Intensity Units

Determines how the light's Intensity setting should be interpreted.

Specular Scale

Multiplier on Specular Highlights. Use only with great care! Any value besides 1 is not physical! Can be used to artistically remove highlights mimicking polarizing filters or photos touch up.

Shadow Resolution Scale

Scales the resolution of the shadowmaps used to calculate dynamic shadows cast by this light. By default, this value is computed based on the screen size of the shadow caster. Note that this value is capped by the value of the global r.Shadow.MaxResolution setting.

Shadow Bias

Controls how accurate the shadows from this light are.

Shadow Filter Sharpen

How much to sharpen shadow filtering for this light.

Contact Shadow Length

The length of screen space to ray trace for sharp contact shadows. A value of zero disables this option.

Contact Shadow Length in World Space Units

Determines whether the Contact Shadow Length setting is interpreted in world space units, or in screen space units.

Cast Translucent Shadows

Determines whether this light is allowed to cast dynamic shadows through translucent objects.

Cast Shadows from Cinematic Objects Only

Determines whether this light should cast shadows only from Components that have the Cast Cinematic Shadows option enabled.

Dynamic Indirect Lighting

Determines whether this light should be included in Light Propagation Volumes.

Force Cached Shadows for Movable Primitives

When enabled, this light will generate cached shadows for movable primitives even when the global r.shadow.cachedshadowscastfrommovableprimitives setting is disabled.

Lighting Channels

Determines the lighting channels that this light should affect.

Cast Static Shadows

Determines whether this light should cast shadows from static objects.

Cast Dynamic Shadows

Determines whether this light should cast shadows from movable objects.

Affect Translucent Lighting

Determines whether this light should affect translucency. Disabling this setting may save some GPU time when your scene has many small lights.

Transmission

Determines whether the light cast by this light source transmits through surfaces with subsurface scattering profiles.

Cast Volumetric Shadow

Determines whether this light source casts shadows from volumetric fog.

Lightmass

The settings in this section are specific to the way this light is treated by the Lightmass global illumination system.

Property

Description

Indirect Lighting Saturation

Determines the saturation of this light in baked lightmaps. A value of 0 completely desaturates this light; 1 leaves it unchanged.

Shadow Exponent

Controls the falloff of shadow penumbras.

Use Area Shadows for Stationary Light

Determines whether to use area shadows for stationary lights. This causes the shadows to get softer as the distance from the caster increases, but can require higher lightmap resolutions to get equally good results in places where the shadows are sharp

Light Functions

Use the settings in this section to set up a Light Function for this light.

Property

Description

Light Function Material

The light function material to be applied to this light.

Light Function Scale

Scales the light function projection.

Fade Distance

The distance at which the light function should be completely faded to the value in Disabled Brightness.

Disabled Brightness

Brightness factor applied to the light when the light function is specified but disabled — for example, when outside the maximum distance set by the Fade Distance setting above.

Light Profiles

Use the settings in this section to set up an IES profile for this light.

Note that Rect Lights project their IES profiles from the center of the light, not along the edges of the light's rectanglular area. This may produce unexpected results.

Property

Description

IES Texture

The IES Texture Asset assigned to the light's profile. Note that IES files are ASCII files, not image files, even though Unreal represents them as textures.

Use IES Brightness

Determines the source of the light's brightness. When this option is enabled, the light uses brightness set in the IES profile, in Lumens. When this option is disabled, the light uses its Intensity setting.

IES Brightness Scale

Scales the brightness contribution when Use IES Brightness is enabled, to avoid the light overwhelming the scene.

Scene Capture

Mobility

Static Sky Light

Stationary Skylight

Movable Sky Light

Distance Field Ambient Occlusion

Precomputed (Static or Stationary) Sky Light

Improved Static Sky Light Directionality

Camera Obscura

Bent Normal for Stationary Sky Lights

Multiple Light Bounces

Real Time Capture

Reflection Quality

Time Slicing Optimization

Shadowing from Movable Objects

Properties

Limitations

The Sky Light captures the distant parts of your level and applies that to the scene as a light. That means the sky's appearance and its lighting/reflections will match, even if your sky is coming from atmosphere, or layered clouds on top of a skybox, or distant mountains. You can also manually specify a cubemap to use.

Scene Capture

The Sky Light will only capture the scene under certain circumstances:

For Static Sky Lights, updates automatically happen when building lighting.

For Stationary or Movable Sky Lights, updates happen once on load and only updates further when Recapture is called unless the Real Time Capture feature is enabled. Both are accessible via the Details panel, and Recapture can also be called via Blueprint in-game.



Details panel Sky Light Recapture button

If you change the texture that the skybox is using, it will not automatically know to update. You'll be required to use one of the methods above for it to update.

A Sky Light should be used instead of the Ambient Cubemap to represent the sky's light because Sky Lights support local shadowing, which prevents indoor areas from getting lit by the sky.

Mobility

Similarly to other Light Types, the Sky Light can be set to one of the following Mobilities:



Mobility

Description

Static

Lighting cannot be changed while in game. This is the fastest method for rendering and allows for baked lighting.

Stationary

When lighting is built, shadowing and light bounces will only be captured from static geometry. All other lighting will be dynamic. This setting also allows for the light to change color, intensity, and the cubemap in-game, but it does not move and allows for partially baked lighting.

Movable

Lighting can be moved and changed in-game as needed.

Static Sky Light

A Sky Light set to Static will be baked completely into the lightmap for static objects in the level and therefore costs nothing. When edits are made to the light's properties, the changes will not be visible until lighting has been rebuilt for the level.

When using a Static Sky Light, only Actors and Lights in the level that have their mobility set to Static or Stationary will be captured and used for lighting. Furthermore, only the emissive contribution of Materials can be captured with a Static Sky Light in order to avoid a feedback loop. For this reason, make sure any skybox has a Material that is set to Unlit.

Stationary Skylight

A Sky Light with Stationary Mobility gets baked shadowing from Lightmass. Once you place a Stationary Sky Light in your level, you have to rebuild lighting once to get the baked shadowing. You can then change the sky light as much as you want without rebuilding. The Sky Light shadowing that Lightmass bakes stores directional occlusion information in what is called a Bent Normal.

Only components and lights with Static or Stationary Mobility will be captured and used for lighting with a Stationary Sky Light.

Like all types of Stationary Lights, the color of the direct lighting can be changed at runtime through Blueprint or Sequencer. However the indirect lighting is baked into the lightmap and cannot be modified at runtime. The amount of indirect lighting can be controlled by IndirectLightingIntensity.





Movable Sky Light

A Sky Light set to Movable does not use any form of precomputation. It captures components and lights of any mobility when setup to capture the scene.

This property requires that Mesh Distance Fields be enabled in the project settings.

Shadowing for a Movable Sky Light is provided by Distance Field Ambient Occlusion from Signed Distance Field Volumes that are generated around each rigid object. Distance Field Ambient Occlusion supports dynamic scene changes where the rigid meshes can be moved or hidden, and it will affect the occlusion.



Click image for full size.

Check out the How to use Distance Field Ambient Occlusion page for more information and examples.

Precomputed (Static or Stationary) Sky Light

When using baked lighting with a Static or Stationary Sky Light, the lighting and shadowing data will be stored in lightmaps. The sections below discuss some of these features supported by Lightmass.

Improved Static Sky Light Directionality

Prior to Unreal Engine 4.18, Static Sky Lights used to be represented by Lightmass with a 3rd Order Spherical Harmonic which didn't capture the detail that could be present in a sunrise or sunset. A filtered cubemap is used now which results in a higher resolution by default. Lightmass will also select the appropriate mip of the cubemap texture based on the size of the Final Gather rays to avoid any aliasing.

To see an example of this type of interaction, go to Engine Content > MapTemplates > Sky and select SunsetAmbientCubemap as it will show a great example.









The biggest difference can be seen in heavily occluded scenes with a Sky Light cubemap that has a lot of brightness and color variations.

With the improved directionality of Static Sky Lights, it is now possible to recreate a pinhole camera effect (Camera Obscura) with a small enough opening. The smaller the opening, the more directional sky lighting will become.





Sky Light Source Cubemap

Resulting Light Build

Click image for full size.

Click image for full size.

Bent Normal for Stationary Sky Lights

For Stationary Sky Lights, static and stationary lighting is baked separately from movable using Lightmass to store directional information in what is called a Bent Normal. This is the direction from the texel to the most un-occluded source of ambient light. Areas that are mostly occluded use this direction for sky lighting instead of the surface normal, which improves quality in cracks.





The first image shows Sky Light with Ambient Occlusion only. The second image shows Sky Light with Bent Normal occlusion. Notice how surfaces in cracks 'agree' on where the lighting is coming from.

For additional information visit the Bent Normal Map page.

Multiple Light Bounces

Multiple bounces of indirect light from Sky Lights is supported by adjusting the Num Sky Lighting Bounces setting in World Settings > Lightmass.





Setting for the number of sky light bounces to use.







For multiple Sky Light bounces to be noticeable, your Materials need to have a high diffuse value in most cases. For example, with a diffuse value of .18 (18% grey), the second sky light bounce will only contribute 18^3 = 0.006 of the light's emitted energy, which is very subtle. With a diffuse value of 0.5, the second skylight bounce will contribute 0.125 of the light's emitted energy and be noticeable.

Each added bounce increases non-distributed build times, so use with care when not using Swarm distribution.

Real Time Capture

The Real Time Capture mode provides dynamic and specular environment lighting, making possible dynamic time-of-day simulations with real-time reflections on scene elements.

This mode is available when the Sky Light's mobility is set to Stationary and Dynamic and when Real Time Capture is enabled from the Sky Light component Details panel.



This mode supports the following components for captured reflections and shadowing:

Sky Atmosphere

Volumetric Clouds

Exponential Height Fog

Sky Dome Meshes with an unlit material tagged as IsSky

These are some additional things to keep in mind when using this mode:

Volumetric Fog is not supported.

Requires a Sky Atmosphere component to be present in the scene for real time capture to work. In a future release, real time capture will be supported without this requirement.

It's possible to render meshes only in real time capture mode by disabling them from rendering in the main view.

It's possible to have a different sky dome mesh for the main view as compared to the reflection of the real time capture when enabling Visible in Real Time Sky Captures on individual actors.

Real Time Capture mode allows for ambient shadowing from Volumetric Clouds to be cast onto the world when Cloud Ambient Occlusion is enabled.

Real Time Capture mode is faster and more efficient than the RecaptureSky Blueprint node because all the computations stay on the GPU without any use of CPU processing that can cause pauses, or slowdowns in gameplay.

If you are using the volumetric clouds, performance can vary a lot depending on the complexity of the cloud material you're using. You can control the performance tradeoff—while respecting visuals in your scene—by adjusting the Volumetric Cloud component's Reflection Sample Count Scale and Shadow Reflection Sample Count Scale values.

Reflection Quality

The quality of reflections captured by the Sky Light is set by the property Cubemap Resolution. It uses power of two values (such as, 64, 128, 256, and so on) to specify a texture resolution for the captured scene.

Keep in mind that higher resolution values increase quality at the cost of performance. The specified value is applied to the highest cubemap mip (a texture's level of detail).

Drag the slider to see decreased (64), default (128), and increased (256) skylight cubemap resolutions being used.



Note that Screen Space Reflections (SSR) has been disabled in these shots. Reflections are only the result of the Sky Light.

Time Slicing Optimization

Real Time Capture mode utilizes a performance optimization called Time Slicing to distribute the captured scene over several frames rather than performing a full scene process every frame. This optimization reduces the per frame cost that would make a full process real time capture every frame too expensive for use on some platforms.

For example, a capture performed on the PlayStation 4 using a 128x128x6 HDR cubemap with sky and volumetric clouds would look something like (measured in milliseconds):

A Full process per frame for a 128x128 cubemap would cost around 1.465ms (divided up as the following):

Sky and Cloud costs 0.60 ms

Cubemap Mip Generation costs 0.05 ms

Specular Convolution costs 0.80 ms

Diffuse Irradiance costs 0.015 ms

The same process but time sliced over 9-Frames Time Slice would cost, at most, 0.20 ms for the most expensive step.

Distributing a single frame's capture over multiple frames has the benefit of keeping real time skylight capture within an affordable budget for your project, because time slicing is only as expensive as its most costly frame. It also means you can look for opportunities to push quality in other areas, such as the quality of the sky or clouds, because you have a little bit of room in the frame budget.

Time slicing is enabled by default, but can be set using the console command r.SkyLight.RealTimeReflectionCapture.TimeSlice.

Shadowing from Movable Objects

Soft shadowing from movable objects onto the environment can be achieved using Capsule Shadows for Skeletal Meshes or Distance Field Indirect Shadowing for rigid meshes. These require a separate setup to work properly.

Properties

There are two categories of Sky Light component properties, Sky Light and Light, although they are not differentiated in the UI. These can be accessed from the Actor Details panel. Sky Light properties are specific to Sky Light Actors, while Light properties are common to all Light Actors. Certain properties are only accesible by expanding the Advanced section, indicated in the table below.



Property

Description



Sky Light



Real Time Capture

When enabled, the sky will be captured and convolved to achieve dynamic diffuse and specular lighting. SkyAtmosphere, VolumetricCloud Components as well as sky domes with Sky materials are taken into account.

Source Type

Whether to capture the distant scene and use it as the light source or to use the specified cubemap. When capturing the scene, anything further than SkyDistanceThreshold from the Sky Light position will be included.

SLS Captured Scene

Construct the sky light from the captured scene. Anything further than Sky Distance Threshold from the sky light position will be included.

SLS Specified Cubemap

Construct the sky light from the specified cubemap.



Cubemap

Specify the Cubemap to use for sky lighting if Source Type is set to SLS_SpecifiedCubemap.

Source Cubemap Angle

The angle to rotate the source cubemap when Source Type is set to SLS Specified Cubemap.

Cubemap Resolution

Maximum resolution for the very top processed cubemap MIP. It also must be a power of 2 texture.

Sky Distance Threshold

Distance from the Sky Light at which any geometry should be treated as part of the sky (also used by Reflection Captures).

Capture Emissive Only

Only capture emissive Materials. Skips all lighting making the capture cheaper. This is recommended when using Capture Every Frame. Advanced.

Lower Hemisphere is Solid Color

Whether all lighting from the lower hemisphere should be set to zero. This is useful to prevent leaking from the lower hemisphere. Advanced.

Lower Hemisphere Color

Use the color picker to select the color for the lower hemisphere. Advanced.



Light



Intensity Scale

The total energy that the light emits.

Affects World

Whether the light can affect the world, or whether it is disabled.

Cast Shadows

Whether the light should cast any shadows.

Indirect Lighting Intensity

Scales the indirect lighting contribution from this light. A value of 0 disables any global illumination (GI) from this light.

Volumetric Scattering Intensity

Intensity of the volumetric scattering from this light. This scales Intensity and Light Color.

Casts Static Shadows

Whether the light should cast shadows from static objects. Also, requires Cast Shadows to be set to True. Advanced.

Casts Dynamic Shadows

Whether the light should cast shadows from dynamic objects. Also, requires Cast Shadows to be set to True. Advanced.

Affect Translucent Lighting

Whether the light affects translucency or not. Disabling this can save GPU time when there are many small lights. Advanced.

Transmission

Whether light from the skylight transmits through surfaces with subsurface scattering profiles. Requires the light to be movable. Advanced.

Cast Volumetric Shadow

Whether the light shadows Volumetric Fog. Advanced.

Cast Deep Shadow

Whether the light should cast high quality hair-strands self shadowing. When this option is enabled, an extra GPU costs is applied to this light. Advanced.

Cast Ray Traced Shadows

Whether the light shadows are computed with shadow mapping or ray tracing (when available). Advanced.

Affect Ray Tracing Reflections

Whether the light affects objects in reflections when ray traced reflection is enabled. Advanced.

Affect Ray Traced Global Illumination

Whether the light affects global illumination when ray traced global illumination is enabled. Advanced.

Deep Shadow Layer Distribution

Change the deep shadows layer distribution. 0: linear (uniform layer distribution), 1: exponential (more details on near small shadows). Requires Cast Deep Shadow to be enabled. Advanced.



Atmosphere and Cloud



Cloud Ambient Occlusion

Whether the cloud should occlude sky contribution within the atmosphere (progressively fading out multiple scattering) or not.

Cloud Ambient Occlusion Strength

The strength of the ambient occlusion. Higher values will block more light.

Cloud Ambient Occlusion Extent

The world space radius of the cloud ambient occlusion map around the camera in kilometers (km).

Cloud Ambient Occlusion Map Resolution Scale

Scales the cloud ambient occlusion map resolution. The resolution is clamped by r.VolumetricCloud.ShadowMap.MaxResolution.

Cloud Ambient Occlusion Aperture Scale

Controls the cone aperture angle over which the sky occlusion due to volumetric clouds is evaluated. A value of 1 takes the entire hemisphere into account, resulting in blurry occlusion. A value of 0 takes a single direction of occlusion (vertical) into account, resulting in sharp occlusion.

Limitations

These features would be useful with SkyLights but are not yet implemented:

Soft shadowing from movable objects (characters) onto the environment is not integrated with Sky Light and currently requires implementing separate features at additional rendering cost.

The SkyLightComponent Blueprint function RecaptureSky() can be used, however it has a high processing cost and requires at least 120 ms, leading to a pause or slowdown in gameplay.



Spot Light Properties

A Spot Light emits light from a single point in a cone shape. Users are given two cones to shape the light - the Inner Cone Angle and Outer Cone Angle. Within the Inner Cone Angle, the light achieves full brightness. As you go from the extent of the inner radius to the extents of the Outer Cone Angle, a falloff takes place, creating a penumbra, or softening around the Spot Light's disc of illumination. The Radius of the light defines the length of the cones. More simply, this will work like a flash light or stage can light.

Like other lights, a Spot Light can be set to one of three Mobility settings:

Static - (pictured left) which means that the light cannot be changed in game. This is the fastest method for rendering and allows for baked lighting.

Stationary - (also pictured left) which means the light will only have its shadowing and bounced lighting from static geometry baked by Lightmass, all other lighting will be dynamic. This setting also allows for the light to change color and intensity in game, but, it does not move and allows partial baked lighting.

Moveable - (pictured left) which means the light is totally dynamic and allows for dynamic shadowing. This is the slowest in terms of rendering but allows for the most flexibility during gameplay.

Two examples of a Spot Light placed inside a level are shown below demonstrating how to determine the light radius and cone effectors:





On the left a Spot Light without its cones showing light radius, on the right the same Spot Light with its cone effectors showing.

Spot Light Properties

The properties of a Spot Light are broken up into 4 categories: Light, Light Profiles, Lightmass, and Light Function.

Light

Property

Description

Intensity

Total energy that the light emits.

Light Color

The color that the light emits.

Inner Cone Angle

Sets the inner cone angle of the Spot Light, in degrees.

Outer Cone Angle

Sets the outer cone angle of the Spot Light, in degrees.

Attenuation Radius

Bounds the light's visible influence.

Source Radius

Radius of light source shape.

Source Length

Length of light source shape.

Affects World

Disables the light completely. Cannot be set at run time. To disable a light's effect during runtime, change its Visibility property.

Casts Shadows

If the light casts shadows.

Indirect Lighting Intensity

Scales the indirect lighting contribution from the light.

Use Inverse Squared Falloff

Whether to use physically based inverse squared distance falloff, where AttenuationRadius is only clamping the light's contribution.

Light Falloff Exponent

Controls the radial falloff of light when UseInverseSquaredFalloff is disabled.

Min Roughness

Min roughness effective for this light, used for softening specular highlights.

Shadow Bias

Controls how accurate the shadows from this light are.

Shadow Filter Sharpen

How much to sharpen shadow filtering for this light.

Cast Translucent Shadows

Whether this light is allowed to cast dynamic shadows through translucent objects.

Affect Dynamic Indirect Lighting

Whether the light should be injected into the Light Propagation Volume.

Cast Static Shadows

Whether this light casts static shadows.

Cast Dynamic Shadows

Whether this light casts dynamic shadows.

Affect Translucent Lighting

Whether the light affects translucency or not.

Light Profiles

Property

Description

IES Texture

The IES "Texture" used for the light profile. IES files are ASCII though Unreal represents them as textures, they are not image files.

Use IES Brightness

If false, it will use the Brightness of the light to determine how much light to produce. If true, it will use the IES files brightness in Lumens (usually much larger than default values on lights in Unreal).

IES Brightness Scale

Scale for IES brightness contribution, as they can seriously blow out a scene.

Lightmass

Property

Description

Indirect Lighting Saturation

A value of 0 will completely desaturate this light in Lightmass, 1 will be unchanged.

Shadow Exponent

Controls the falloff of shadow penumbras.

Light Function

Property

Description

Light Function Material

The light function material to be applied to this light.

Light Function Scale

Scales the light function projection.

Light Function Fade Distance

The distance at which the light function should be completely faded to the value in Disabled Brightness.

Disabled Brightness

Brightness factor applied to the light when the light function is specified but disabled, say from the property above: Light Function Fade Distance.

Lightmap Resolution

Lightmass Settings

Per-Light Lightmass Settings

World Settings Lightmass Settings

Lights that have their Mobility set to Static are lights that cannot be changed or moved in any way during runtime. They are precomputed using Lightmass when a lighting built is performed. Static Lights store their data in textures called Lightmaps that are applied to geometry in the Level. Once the lighting build is complete, these lights have no further impact on performance.

Static Meshes with their Mobility set to Movable and Skeletal Meshes do not integrate (or blend) fully with Static Lighting. However, when a light build takes place, lighting data is stored in Volumetric Lightmaps or the Indirect Lighting Cache to assist in lighting and grounding these movable objects within a statically lit area.

Of the three light mobilities, Static Lights tend to have medium quality, lowest mutability, and the lowest performance cost.

Lightmap Resolution

Static Lights generate their lighting data with Lightmass and store it in lightmaps that are stored per-Level and applied to the geometry within that Level after a lighting build takes place.

Because lightmaps store their lighting data in textures applied to geometry, it's important to set a good lightmap resolution for individual actors to capture good shadow detail on its surfaces. You can use one of the following ways to set the lightmap resolution for an object in the scene:

Open the Static Mesh Asset in the Static Mesh Editor and use its Details panel to set the default Light Map Resolution used by this asset anywhere it's used.

In the Level Editor, select a Static Mesh Actor and use its Details panel to enable Overridden Light Map Res and enter a new lightmap resolution to use for this individual Actor. This option is most useful when you have scaled the object and need to make its lightmap textures consistent with the other objects around it.

The examples below compare a low lightmap resolution with a higher one. Low lightmap resolutions do not accurately capture detail compared to higher resolutions. It is worth noting that higher resolutions require additional disk space for the texture data and take longer to process when building lighting for the scene.







Lightmap Resolution: 64

Lightmap Resolution: 128

Lightmap Resolution: 512

Because lightmap resolution can be set per-Asset, or overridden per-Actor within a Level, it's important that shadows appear consistent between the assets that receive static shadows and that they integrate with the surrounding shadows appropriately. The Level Editor view mode for Lightmap Density (found under the View Modes > Optimization Viewmodes dropdown) shows a tiled pattern on any Static Mesh Asset with its Mobility set to Static that will generate a lightmap texture. The tiles represent the current texel density based on the lightmap resolution of the Static Mesh Asset with other Assets in the scene.

In this example, the texel density of the floor does not match much of the surrounding lightmap resolutions of the objects in the scene. Note where the block in the center meets the floor and the inconsistency of the shadow baked in across the floor compared to the block.





Lighting Only View Mode with built shadows

Lightmap Density View Mode — Low Floor Asset Lightmap Texel Density

Increasing the lightmap resolution of the floor more closely aligns the texel density to the block in the center and other objects in the scene. Note how the shadows are more consistent between the floor and the block now because the texel densities are more closely aligned.





Lighting Only View Mode with built shadows

Lightmap Density View Mode — Higher Floor Asset Lightmap Texel Density

Lightmass Settings

Static Lights have their own settings that located on the light and within the World Settings that affect their interactions within the Level.

Per-Light Lightmass Settings

On selected Lights within the scene that have their Mobility set to Static, the following settings under the the Lightmass category affects the lighting build.

Property

Description

Light Source Angle

On a Directional Light, this controls the angle that the emissive surface extends relative to a receiver and affects the penumbra sizes of shadows cast from a Directional Light.

Indirect Lighting Saturation

Controls the amount of desaturation applied to the baked bounce lighting.

Shadow Exponent

Controls the falloff of the shadow penumbras.

World Settings Lightmass Settings

For each Level, use the World Settings > Lightmass Settings to configure how static lighting is computed in the world. The setting here will affect any of the Static Lights in the currently loaded Level(s).

Property

Description

Static Lighting Level Scale

Scale of the level relative to real world scale (1 Unreal Unit is equal to 1 centimeter). All scale-dependent Lightmass setting defaults have been made to work well with real world scale. Any Levels with a different scale should use this scale to compensate, such as large worlds where it can significantly reduce build times when set to a higher value, like 2 or 4. Lower values will drastically increase build times.

Num Indirect Lighting Bounces

The number of light bounces to simulate for point, spot, and directional lights, starting from the light source. 0 produces direct lighting only. The first bounce takes the most time to calculate and contributes the most to visual quality, followed by the second bounce of light. Successive bounces don't really affect light build times, but have much lower visual impact, unless the material diffuse colors are close to 1.

Num Sky Light Bounces

The number of skylight and emissive bounces of light to simulate. Lightmass uses a non-distributable radiosity method for skylight bounces whose cost is proportional to the number of bounces.

Indirect Lighting Quality

This setting can be used to increase the global illumination solver sample counts in order to get higher quality for Levels that need it. It can be useful to reduce Indirect Lighting Smoothness somewhat (approximately 0.75) when increasing quality to get defined indirect shadows.

This setting does not affect compression artifacts, UV seams or other texture based artifacts that can happen during a light build.



Indirect Lighting Smoothness

This setting is useful in some lighting conditions when Lightmass cannot resolve accurate indirect lighting. 1 is the default smoothness that is setup to work well for a variety of lighting situations. Higher values like 3 will smooth out the indirect lighting more but at the cost of indirect shadows losing detail.

Environment Color

Represents a constant color light surrounding the upper hemisphere of the Level, like a sky. The light source currently does not get bounced as indirect lighting and causes reflection capture brightness to be incorrect. Instead, it's recommended to use a Static Sky Light instead.

Diffuse Boost

Scales the diffuse contribution of all materials in the scene.

Volume Lighting Method

Technique to use for providing precomputed lighting at all positions inside the Lightmass Importance Volume.

Volumetric Lightmap: Lighting samples are computed in an adaptive grid which covers the entire Lightmass Importance Volume. Higher density grids are used near geometry. The Volumetric Lightmap is interpolated efficiently on the GPU per-pixel, allowing accurate indirect lighting for dynamic objects and volumetric fog. On mobile, interpolation is done on the VPU at the center of each object's bounds.

Sparse Volume Lighting Samples: Lighting samples are placed on top of Static surfaces at medium density, and everywhere else in the Lightmass Importance Volume at low density. Positions outside of the Importance Volume will have no indirect lighting. This method requires CPU interpolation so the Indirect Lighting Cache is used to interpolate results for each dynamic object, adding Rendering Thread overhead. Volumetric Fog cannot be affected by precomputed lighting with this method.

Use Ambient Occlusion

When enabled, Ambient Occlusion will be baked into the lightmaps.

Generate Ambient Occlusion Material Mask

Whether to generate textures toring the ambient occlusion computed by Lightmass. These can be accessed through the PrecomputedAOMask material node, which is useful for blending between different material layers on environment assets.

Be sure to set Direct Illumination Occlusion Fraction and Indirect Illumination Occlusion Fraction to 0 if you only want the PrecomputedAOMask.



Visualize Material Diffuse

When true, overrides the normal direct and indirect lighting with just the exported diffuse term.

Visualize Ambient Occlusion

when true, override normal direct and indirect lighting with just the ambient occlusion term.

Compress Lightmaps

Whether to compress lightmap textures. Disabling lightmap texture compression will reduce artifacts but increase memory and disk size used by a significant amount.

Volumetric Lightmap Detail Cell Size

The size of a Volumetric Lightmap voxel at the highest density (used around geometry), in world space units. This has a large impact on build times and memory and should be used with caution. Halving the Detail Cell Size can increase memory by up to a factor of 8x.

Volumetric Lightmap Maximum Brick Memory Mb

Maximum amount of memory to spend on Volumetric Lightmap Brick data. High density bricks will be discarded until this limit is met, with bricks farthest from geometry being discarded first.

Volumetric Lightmap Lightmap Spherical Harmonic Smoothing

Controls how much smoothing should be done to Volumetric Lightmap samples during Spherical Harmonic de-ringing.Whenever highly directional lighting is stored in a Spherical Harmonic, a ringing artifact occurs which manifests as unexpected black areas on the opposite side. Smoothing can reduce this artifact. Smoothing is only applied when the ringing artifact is present. 0 is equal to no smoothing, 1 to strong smoothing (with little directionality in lighting).

Volume Light Sample Placement Scale

Scales the distances at which volume lighting samples are placed. Volume lighting samples are computed by Lightmass and are used for global illumination on movable components. Using large scales results in less sample memory usage and reduces Indirect Lighting Cache update times, but less accurate transitions between lighting areas.

Direct Illumination Occlusion Fraction

How much of the ambient occlusion to apply to direct lighting.

Indirect Illumination Occlusion Fraction

How much of the ambient occlusion to apply to indirect lighting.

Occlusion Exponent

Higher exponents increase contrast.

Fully Occluded Samples Fraction

Fraction of samples taken that must be occluded in order to reach full occlusion.

Max Occlusion Distance

Maximum distance for an object to cause occlusion on another object.



Advanced Properties



Lightmaps

The computed lightmap textures save for the Level.

Force No Precomputed Lighting

Whether to force lightmaps and other precomputed lighting to not be created, even when the engine thinks they are needed. This is useful for improving iteration in Levels with fully dynamic lighting and shadowing.

Any lighting and shadowing interactions that are usually precomputed are lost if this setting is enabled.



Packed Light and Shadow Map Texture Size

The maximum size of textures for packed light and shadow maps.

Stationary Direct Lighting

Stationary Light Shadowing

Stationary Indirect Lighting on Opaque Materials

Stationary Indirect Lighting on Translucent Materials

Stationary Light Dynamic Shadowing

Stationary Directional Light Dynamic Shadowing

Stationary Light Indirect Shadowing

Use Area Shadows for Stationary Lights

Lights that have their Mobility set to Stationary are lights that are intended to stay in one position, but are able to change in other ways, such as their brightness and color. This is the primary way they differ from Static Lights, which cannot change in any way during gameplay.

Of the three light mobilities to choose from, Stationary lights have the highest quality, medium mutability, and medium performance cost.

Stationary Lights use both dynamic and static lighting to achieve its result, with indirect lighting and shadowing being stored within lightmaps for the Level. Direct shadows are stored within shadow maps. These lights make use of Distance Field Shadows, meaning that their shadows can remain crisp even with fairly low lightmap resolutions on lit objects.

Stationary Direct Lighting

Stationary Lights use both dynamic direct lighting and static indirect lighting to achieve its result. The indirect lighting and shadowing is stored in lightmaps, while direct shadowing is stored in shadow maps. Because Stationary Lights are rendered dynamically using deferred shading, their brightness and color is able to change at runtime, and also support Light Functions and IES Profiles in the same way.

Stationary Lights also have high quality analytical specular, like Movable Lights.





Stationary Light Shadowing

Only four or fewer Stationary Lights can overlap one another or any single piece of geometry in the Level, meaning that in some cases you will have fewer Stationary lights that can overlap in some parts of your Level. Shadowing cannot affect the overlap test, so the Directional Light typically requires a channel from the entire Level it is in, even areas that may be underground or hidden by other geometry. Once the channel limit is reached, only dynamic (or whole scene shadows) are used, which brings with it considerable performance cost.

When the limit of up to four Stationary Lights overlap at any time within a Level, the light icon will change to one with a Red X over the offending light until the overlap limit is resolved. There is a Stationary Light Overlap visualization mode that highlights offending lights in red until the overlap is resolved.

Enable the Stationary Light Overlap visualization from the Level Editor View Mode > Optimization Viewmodes dropdown selection.



Stationary Indirect Lighting on Opaque Materials

Lightmass generates distance field shadow maps for Stationary Lights on Static objects during the lighting build process. Distance field shadow maps provide accurate shadow transitions, even at lower resolutions, and incur very little runtime cost. For example, lightmaps require uniquely unwrapped UVs on all meshes that have their mobility set to Static and have indirect lighting from a Static or Stationary light source.



Accurate shadowing of a Static Mesh Actor onto opaque surfaces.

Lighting must be built to display shadows from Stationary or Static light sources, otherwise dynamic shadows are used.

Stationary Indirect Lighting on Translucent Materials

Translucency recieves shadowing at low cost with Stationary Lights since Lightmass precomputes a shadow depth map from Static geometry in the Level. That shadow depth is applied to translucency at runtime. This form of shadowing is fairly coarse and only captures shadowing in meters.





The resolution of the static shadow depth map is controlled with StaticShadowDepthMapTransitionSampleDistanceX and StaticShadowDepthMapTransitionSampleDistanceY in the BaseLightmass.ini configuration file. It has a default value of 100, meaning one texel every meter.

Stationary Light Dynamic Shadowing

Dynamic objects, such as Static Meshes with their Mobility set to Movable and Skeletal Meshes, must integrate into the world from shadow maps, which is accomplished with per object shadows. Each Movable object creates two dynamic shadows from a given Stationary Light: a shadow to handle the static world onto the movable object, and a shadow to handle the movable object casting onto the world.

With this setup, the only shadowing cost for Stationary Lights comes from the Movable objects it affects. It also means the cost can vary from very little to a large amount depending on how many Movable objects there are. With enough Movable objects being affected, it's actually more efficient to use a light with its Mobility set to Movable.

In the example scene below, the spheres have their Mobility set to Movable and the rest of the scene geometry is set to

In the example scene below, a Stationary Directional Light is used to light the scene. The spheres have their Mobility set to Movable with the rest of the scene set to Static. Lighting has been built for the scene. The per object shadow frustums of each Movable sphere integrates seamlessly with the scene by receiving shadows from the objects behind and casting their own shadows that blend with the ones on the ground.



Per object shadows used by Movable components apply a shadow map to the object's bounds, therefore the bounds of the object must be accurate. For Skeletal Meshes, this means they should have a Physics Asset. For Particle Systems, a fixed bounding box must be large enough to contain all particles it generates.

Directional Stationary Lights are special in that they support whole scene shadows through Cascaded Shadow Maps at the same time as precomputed static shadowing. This is useful in scenes with lots of animating foliage where you want to have moving shadows around the player but do not want to pay the cost of having many levels of cascaded shadow maps covering a large view range at a larger cost.

A Directional Stationary Light uses Cascaded Shadow Maps for direct shadowing near the player within a specified range with Dynamic Shadow Distance Stationary Light. Any shadows beyond this distance fades into precomputed static shadows stored in lightmaps. By default, all Directional Stationary Lights start with a value of 0, meaning there is no dynamic shadowing taking place.

To save performance when you have a lot of Movable objects in the scene but want to use a smaller dynamic shadow distance, enable Inset Shadows for Movable Objects. It allows for movable objects to have a shadow even when they are outside of the cascaded shadow maps range and reduces shadowing cost significantly if there are many movable objects in the scene.

Stationary Light Indirect Shadowing

Stationary Lights store their indirect lighting in lightmaps when lighting is built for the Level, just like Static Lights do. Indirect Lighting cannot be modified without invalidating lighting and needing to be rebuilt with exception to changing the Light's Intensity and Light Color. However, this does not affect the intensity or colors of the baked shadows.

A Post Process Volume does enable indirect shadows intensity and color to be changed using the Global Illumination category properties for Indirect Lighting Color and Indirect Lighting Intensity.

whether to use area shadows for stationary light precomputed shadow maps. area shadows get softer the further they are from shadow casters, but require higher lightmap resolution to get the same quality where the shadow is sharp.

By default, Static Lights automatically use area shadows — crisp, hard shadowing near surface contacts with softer shadows the farther surfaces are apart from one another — when building lighting. For Stationary Lights, the property Use Area Shadows for Stationary Lights enables soft area shadowing for any Static geometry in the scene affected by this light.

This property is enabled on Stationary Lights under the Lightmass section in the Light's Details panel.





Use Area Shadows for Stationary Lights is only available on Stationary Lights and require higher lightmap resolutions for good results.

How does it work?

Scene Representation

Quality

Global Distance Field

Foliage

Two-Sided Distance Field

Foliage Tool Settings

Enabling Distance Fields

Limitations

References

Essentials



Unreal Engine leverages the power of Distance Fields to have dynamic ambient occlusion and shadowing for Static Mesh Actors in your games. In addition to that, the Mesh Distance Field representation of an Actor can be used for other features like GPU particle collision or even with the Material Editor to create dynamic flow maps and much more.

Continue reading below to learn how Mesh Distance Fields work and some of the ways you can use it in your games.

How does it work?

To represent a Static Mesh's surfaces, a Signed Distance Field (SDF) is used. It works by storing the distance to the nearest surface in a volume texture. For every point on the exterior of the mesh is considered positive distance and any point inside the mesh stores a negative distance. In the example below, the positive distances are being traced and stored to represent the tree later on.



The first property of SDF that make them useful is that when tracing a ray, you can safely skip through empty space as the distance to the nearest surface is already known (this is sometimes called Sphere Tracing). This allows the intersections to be determined with a small number steps. By ray tracing a distance field, a visibility result is produced, meaning that if the ray intersects the mesh, the light will then be shadowed.



The second property that makes SDF useful is that when you trace a ray, by tracking the closest distance a ray passed by an occluding object, an approximate cone intersection can be computed with no extra cost. This approximation makes it possible to do very soft area shadows and sky occlusion using distance fields. This property is key to features like Distance Field Ambient Occlusion as a small number of cones can compute a soft visibility for the entire hemisphere of a receiver point.



You can read further about using Distance Fields for Lighting here.

Scene Representation

Each level that you create is made up of all these Mesh Distance Fields for your placed Actors. When Mesh Distance Fields are generate, they are done so "offline" using triangle raytracing that stores the results in a volume texture. Because of this, mesh distance field generation cannot be done at runtime. This method computes the Signed Distance Field rays in all directions to find the nearest surface and stores that information.

You can visualize the Mesh Distance Fields that represent your scene by using the viewport and selecting Show > Visualize > Mesh Distance Fields.





Menu to Enable Visualization

Mesh Distance Field Visualization

Click images for full size.

When you see areas that are more white than gray, it means that many steps were needed to find the intersection of the mesh surface. Rays at grazing angles to surfaces took many more steps to intersect than would have for a simpler mesh.

Quality

The quality of a Mesh Distance Field representation is controlled by its volume texture resolution. This can be modified using Distance Field Resolution Scale in the Build Settings of the Static Mesh Editor.



Click image for full size.

The Mesh Distance Field quality will be best for levels that are built out of meshes with similar size, as large meshes tend to create errors. For example, meshes in Fortnite either conform to a grid or are props placed around parts of the level, which gives the best results with few errors. Landscapes are handled separately by heightfields and are not affected by Distance Field resolution.







Original Mesh

Resolution is too low, important features are lost

Resolution has been increased, important features represented

Click images for full size.

The resolution of your Mesh Distance Field should be adjusted enough to capture the important features. As you increase the resolution of the mesh, the memory footprint of the Mesh Distance Field will increase as well. In the Static Mesh Editor, you can see the Mesh Distance Field size listed on the top left of the Viewport.



Click image for full size.

When the Mesh Distance Field is generated, corners are rounded off based on resolution. This can be offset by increasing its resolution, but in most cases, should not be an issue depending on the complexity of the mesh. The maximum size volume texture any single mesh can have is 8 megabytes with a resolution of 128x128x128.







For thin surfaces, they can only be represented with a negative texel inside the mesh, which is necessary for finding its root. Increasing the resolution can capture the larger detail more accurately here, but in cases where you're only using Distance Field Ambient Occlusion and the surfaces aren't represented properly. Occlusion further from the surface will be accurate, so it's often not noticeable with sky occlusion.



Global Distance Field

The Global Distance Field is a low-resolution Distance Field that uses Signed Distance Fields occlusion in your levels while following the camera. It creates a cache of the per-object Mesh Distance Fields and composites them into a few volume textures centered around the camera, called clipmaps. Only newly visible areas or those affected by the scene modification need to be updated, so composition doesn't cost much.

The lower resolution of the object Distance Field means that it can be used for everything, but when computing cone traces for sky occlusion, they are sampled near the point of being shaded while the Global Distance Field is sampled further away.

You can visualize the Global Distance Field in the viewport by clicking Show > Visualize > Global Distance Field.



Click image for full size.

Below is a comparison of the per-object Mesh Distance Field visualization in comparison to the Global Distance Field visualization that combines them into clipmaps based on the camera view and distance.





For more information, visit the Distance Field Ambient Occlusion page.

Foliage

Foliage assets can also leverage the Distance Fields making it possible to have dynamic occlusion or even have distance shadowing beyond what Cascaded Shadow Maps can shadow.

Below are some options you should consider when using any foliage assets in your games to get the most out of performance and quality.

For high-density meshes (like trees) where you have surface that are usually made up of a masked material that represents many holes for leaves or branches, these cannot adequately be represented as a solid surface. For this reason, you can enable the Build Setting for Two-Sided Distance Field Generation in the Static Mesh Editor. This option will work well for foliage but does come at a higher ray marching cost.



Look at the example below. The tree on the left is using a default opaque Mesh Distance Field representation. The one on the right has Two-Sided Distance Field Generation enabled. You'll notices that the two-sided mesh distance field is more white than it is gray and the surfaces are now translucent. This means that many more steps were needed to find the intersection of the mesh when generating the volume texture than the opaque one and will come at a higher cost.





Two-Sided Distance Field Generation Disabled

Two-Sided Distance Field Generation Enabled

Click images for full size.

In the Foliage Tool, you must enable each foliage type that you want to use Distance Field lighting features for ambient occlusion and shadowing. By default, this setting is disabled because some foliage assets (like grass) where you would have thousands or tens of thousands of instances would overflow the tile culling buffer. When this happens, you can unsightly artifacts. So, only enable Affect Distance Field Lighting for the foliage assets that you need.



Click image for full size.

Enabling Distance Fields

To enable Mesh Distance Fields for your project, click Edit on the Main menu and select Project Settings.



Navigate to the Engine section and select Rendering. Under the Software Ray Tracing category, toggle the checkbox next to Generate Mesh Distance Fields.



Click image for full size.

When you enable this, you will be prompted to restart your project.



Once completed, you can visualize the Mesh Distance Fields in the viewport by clicking Show > Visualize > Mesh DistanceFields. You should see a similar view to this.





The entirety of this level is represented by instanced Distance Fields that are stored in volume textures.

Limitations

Limitations of the Distance Fields technique:

Support for feature level 5 platforms only (DX-11 and above)

Only casts shadows from rigid meshes. For Skeletal Meshes, you can use Capsule Shadows for indirectly lit areas with Distance Field Ambient Occlusion (DFAO) and soft direct shadowing.

Materials that deform the mesh through World Position Offset or displacement may cause self-shadowing artifacts, as the Distance Field representation is generated offline and does not know about these deformations.

Limitations of the current implementation but can be improved in the future:

Non-uniform scaling cannot be handled correctly (although, mirroring is ok). Scaling the mesh by two times or less is not generally noticeable.

Only supports Static Mesh, Instances Static Mesh, Foliage, and Landscape (Heightfield). Foliage must be enabled with Affect Distance Field Lighting from the Foliage Tool settings.

Hardware Limitations:

All Mesh Distance Field features have been disabled on Intel cards because the HD 4000 hangs in the RHICreateTexture3D call to allocate the large atlas.

References

Quilez,Inigo. "Raymarching Distance Fields." N.p, 2008

Essentials



An overview of using Mesh Distance Fields to create dynamic ambient occlusion for SkyLights.



An overview of using Mesh Distance Fields to create dynamic soft area shadowing.



How to setup and use Distance Field Shadowing.



How to setup and use Distance Field Ambient Occlusion.



How to setup and use Distance Field Indirect Shadows.



A reference page for all the Mesh Distance Field settings that can be found in the Project Settings, Light Components, Static Mesh Editor, and individual Actors.



Scene Setup

Sky Light

Scene Representation

Occlusion Results

Performance

Limitations

Tips and Tricks

Shadowing for Movable Sky Lights is provided by using Signed Distance Field Volumes precomputed around each rigid mesh to generate medium scale Ambient Occlusion. In Unreal Engine, this is called Distance Field Ambient Occlusion (DFAO). It supports dynamic scene changes; the rigid meshes can be moved or hidden, and it will affect the occlusion. Unlike Screen Space Ambient Occlusion (SSAO), occlusion is computed from world-space occluders, so there are no artifacts from missing data off-screen.

This dynamic AO solution will not work for all projects, as it has some invasive limitations which enable it to support dynamic scene changes. In particular, only slight-non-uniform scaling (squishing) is supported. Also, large Static Meshes produce inferior quality results because a small volume texture is mapped to every object.

Scene Setup

This feature requires that Generate Mesh Distance Fields be enabled in your Project Settings in the Rendering section. See the Mesh Distance Fields page for more information.

To enable Distance Field Ambient Occlusion, drag a Sky Light into the scene and set its Mobility to Movable

For a step-by-step guide, follow the Distance Field Ambient Occlusion How-To guide to learn more.

Sky Light

The Sky Light component enables you to adjust the various settings that can be found listed under Distance Field Ambient Occlusion.



These are comparisons of some of the settings you can adjust:

Occlusion Contrast





Minimum Occlusion





Occlusion Tint





For additional information about Sky Light settings and additional examples, see the Mesh Distance Fields Reference page.

Scene Representation

The view mode for Distance Field AO enables you to see how DFAO looks in the level without regards to any other lighting that is happening.

You can visualize the Distance Fields that represent your scene ambient occlusion by using the Level Viewport view mode for Distance Fields Ambient Occlusion by selecting Show > Visualize > Distance Fields Ambient Occlusion.



Click image for full size.

While in this view mode, the only Sky Light setting that will have any effect is Occlusion Max Distance.



Quality

Distance Field AO quality is determined by the resolution of the Mesh Distance Field it represents. Since AO is very soft shadowing, so even if the surfaces aren't represented properly, occlusion further from the surface will be accurate. It's often not noticeable with sky occlusion. However, make sure that the larger details of the mesh are well represented in the Mesh Distance Field for good results. Use the Mesh Distance Field Visualization to inspect the quality.

For additional information about Mesh Distance Field quality, see the Mesh Distance Fields page.

Occlusion Results

Diffuse

Distance Field AO produces a bent normal (the direction of least occlusion) which is used to modify the diffuse sky light calculation (along with an occlusion factor).





In this example is a Fortnite level at midday. In Fortnite, players can knock down any wall, floor or ceiling and build new ones, so the lighting must be updated accordingly. Distance Field AO supports these types of dynamic changes in the level around you.

Specular

Distance Field AO also provides approximate specular occlusion on Sky Lights. This is computed by intersecting the directional occlusion cone with the reflection cone (whose size depends on the material roughness).





Specular occlusion on pipes.

By default, non-directional AO is applied to specular. You can use r.AOSpecularOcclusionMode to give more accurate occlusion results than the default method by intersecting the reflection cone with the unoccluded cone produced by DFAO. Note that this can introduce DFAO sampling artifacts.

Foliage

For Actors painted with the Foliage Tool, you must first enable the option Affect Distance Field Lighting in tool settings.



Even though Distance Field AO operates on surfaces, it can still handle foliage where many small leaves are combined into sheets. The best results are obtained by enabling Two-Sided Distance Field Generation for foliage type assets from the Build Settings options in the Static Mesh Editor. This will soften the computed occlusion.

In the Sky Light options, increase the Min Occlusion to prevent the interior parts of the asset from going fully black.



This is an example where DFAO has been enabled and is using Two-Sided Distance Field Generation:





For Foliage assets that use LODs (Levels of Detail), you can run into some problem with Distance Field AO produces over-occlusion. This happens when the Mesh Distance Field is still accurate at far distances, but the LOD level is using a lower triangle count and may shrink to be inside of the generated Mesh Distance Field.

To combat this, you can use World Position Offset on those LODs to pull the vertices outside of the Distance Field. Typically, a small offset towards the camera is effective enough to resolve the artifact. For billboards, use the Pixel Depth Offset feature to create valid depth values which better represent the original 3D triangle mesh. This technique was used in the "A Boy and His Kite" GDC demo, which relied on Distance Fields for the long view distances.





Distance tree billboards showing over-occlusion. Use Pixel Depth Offset and the Skylight Min Occlusion to reduce over-occlusion.

Landscapes

Landscapes use a heightfield for their representation instead of a Mesh Distance Field. This uses an approximate cone intersection, which is computed against the heightfield enabling pixels without a Distance Field representation to receive occlusion. However, there is no self-shadowing or Distance Field shadowing. Instead, landscapes should use Far Shadows with Cascaded Shadow Maps (CSM) shadowing for far distances.



DFAO visualization view mode showing landscape occlusion.

Performance

The cost of Distance Field AO is primarily GPU time and video memory. DFAO has been optimized such that it can run on medium-spec PC, PlayStation 4, and Xbox One. Currently, it has a much more reliable cost so that it's mostly constant (with a slight dependency on object-density).

In cases with a static camera and mostly flat surfaces, DFAO is 1.6x faster when compared to earlier implementations. In complex scenes with foliage and a fast moving camera, the latest optimizations are 5.5x faster. The cost of Distance Field AO on PlayStation 4 for a full game scene is around 3.7ms.

Optimizations

Below are some of the optimizations that have been added to DFAO to make it faster, more efficient, and to improve its look.

With Unreal Engine 4.16, these are some improvements for DFAO with test results using a PlayStation 4:

Optimization

Orignal Cost (ms)

New Cost (ms)

Savings (ms)

The culling algorithm has changed to produce a list of intersecting screen tiles for each object, instead of the other way around. Each tile/object intersection gets its cone tracing thread group, so wavefronts are much smaller and scheduled better.

3.63

3.48

0.15

Slow instructions in the inner loop have been replaced with fast approximations

3.25

3.09

0.16

The transform was moved out of the inner loop from world to local space (sample position constructed from local space position + direction).

3.09

3.04

0.05

Compute shader for ClearUAV.

3.04

2.62

0.42

Before using smooth sampling for DFAO, adaptive sampling was used which meant that flat surfaces did less work compared to denser scenes with many surfaces, like foliage. It also meant that there could be a lot of splotches in clean environments.

The smooth sampling requires a longer history filter, which can contribute to "ghosting" (or a trail behind a moving object), especially when shadow casters are moved. In Unreal Engine 4.16 and later, Ghosting has been improved by having the Distance Field temporal filter store a confidence value. It is used to track leaking of occlusion during the upsample and then flush those leaked values through the history faster. Overall, this should help reduce ghosting that can happen when the camera or a dynamic object is moving fast.

In the examples below, AO computations are now fast enough to get rid of the adaptive sampling, so occlusion is much smoother.





Scene View





DFAO Visualization

The Global Distance Field is a low-resolution Distance Field that uses Signed Distance Fields occlusion in your levels while following the camera. It creates a cache of the per-object Mesh Distance Fields and composites them into a few volume textures centered around the camera, called clipmaps. Only newly visible areas or those affected by the scene modification need to be updated, so composition doesn't cost much.

The clipmap is separated into four slices around the camera that are only updated where needed, which can happen when camera movement reveals a new slice or an object is never moved causing its influence bounds to become dirty. The average cost of maintaining it stays close to zero, however, in a worse-case scenario, the update cost could be higher when performing something like a teleport.



Clipmap visualization of the texel size of the clipmaps with each clipmap being represented by a different color.

The lower resolution of the object Distance Field means that it can be used for everything, but when computing cone traces for sky occlusion, they are sampled near the point of being shaded while the Global Distance Field is sampled further away.

You can visualize the Global Distance Field in the viewport by clicking Show > Visualize > Global Distance Field.



Click image for full size.

Below is a comparison of the per-object Mesh Distance Field visualization in comparison to the Global Distance Field visualization that combines them into clipmaps based on the camera view and distance.





The Global Distance Field is a lower resolution than its object Distance Fields counterpart, making Global Distance Fields inaccurate near surfaces. When cone traces happen, the object Distance Field is used near the start of the occlusion cone and Global Distance Field for the rest of the trace, giving better results because you get accurate self-occlusion and efficient long distance traces. Because of this, sky occlusion sees five times the performance gain because the effective max object influence distance is dramatically decreased.

Limitations

Limitations of the technique

Only Ambient Occlusion is provided, which is different from Sky Occlusion because it has a limited blocking distance.

Shadows only cast from rigid meshes. For Skeletal Meshes, use Capsule Shadows for indirectly lit areas.

Limitations of the current implementation (can be improved in the future)

Updates to the AO from dynamic scene changes lag a bit as the work is spread across multiple frames causing occlusion to shift around a bit as new samples are generated. This has been improved in Unreal Engine 4.16 and later by having the Distance Field temporal filter store a confidence value which is used to track leaking of occlusion during the upsample and then flush those leaked values through the history faster. This helps reduce the ghosting that happens when the camera is moving.

Large objects will have diminished Distance Field resolution and cause inferior AO quality since a volume texture is mapped to each mesh.

For additional limitation of Distance Fields, see the Distance Fields page.

Tips and Tricks

Cheap Bounce Light

By unchecking Lower Hemisphere is Solid Color on the Sky Light and painting in some ground color into the cubemap, you can get what looks like Sun bounce lighting for no further cost. This will cause light leaking indoors as it does not respect shadowing of the directional light, but can be effective for outdoor scenes.

Scene Setup

Area Shadowing Settings

Point and Spot Light Source Radius

Directional Light Source Angle

Mesh Distance Field Quality

Performance

Optimizations

Limitations

Shadowing from movable light sources is provided using object Distance Fields for each rigid mesh to compute efficient area shadowing from dynamic light sources. In Unreal Engine, this is called Distance Field Shadows (DFS). To calculate shadowing, a ray is traced from the point being shaded through the scene's Signed Distance Fields (SDF) toward each light. The closest distance to an occluding object is used to approximate a cone trace for about the same cost as the ray trace. It allows for high-quality area shadowing from spherical light source shapes.

Scene Setup

This feature requires that Generate Mesh Distance Fields be enabled in your Project Settings in the Rendering section. See the Mesh Distance Fields page for more information.

To enable Distance Field Shadowing, start by dragging a Light into the scene and set its Mobility to Movable and then from the Light Details panel, enable Distance Field Shadows.



For a step-by-step guide, follow the Using Distance Field Shadowing How-To guide to learn more.

Area Shadowing Settings

Each Light type can use Distance Fields shadows to create soft area shadows. These shadows simulate real-world shadows by retaining sharp contact shadows closer to the base and softening the farther the shadow stretches away.





For additional information about Light source settings and additional examples, see the Mesh Distance Fields Reference page.

Point and Spot Light Source Radius

For Point and Spot Lights, the Source Radius is used to determine how large shadow penumbras are on a light. Area shadows are computed with sharp contacts that get softer over long distances. On a Point and Spot Light, it is represented by a yellow sphere.



The Editor draws the source shape of the light with yellow lines.

The Light's source radius sphere should not be intersecting the scene, or it will cause lighting artifacts.





The Distance Field shadows are from a Point Light using a Source Radius to soften the shadows cast by the doorway, bench, and piano on the surrounding geometry.

For additional information about Point and Spot Light settings, see the Mesh Distance Fields Reference page.

Directional Light Source Angle

For Directional Lights, the Light Source Angle is used to determine how large shadow penumbras are on a light. Distance Field Shadows have very few self-intersection problems and therefore avoid the leaking and over-biasing problems in the distance that traditional shadow mapping would have.





Distance Field Shadows from a Directional Light with a Light Source Angle adjusted for softer shadowing.

In most cases, Cascaded Shadow Maps (CSM) are used to provide dynamic shadowing of a Directional Light. These require rendering the meshes in the scene into several cascade shadow maps (levels of detail for shadowing). The cost of shadowing increases at large shadow distances because of how many meshes and triangles are being rendered into the shadow maps.

Distance Field Shadows work much more gracefully in the distance, doing shadowing work only for visible pixels. Cascaded Shadow Maps can be used to shadow an area near the camera while RTDF shadows will shadow farther regions up to the Distance Field Shadow Distance that is set.



When Distance Field Shadows are enabled, anything beyond the set value for Cascaded Shadow Map Distance will be shadowed using Distance Fields. In the comparison using both CSM and RTDF shadowing, the CSM shadow is set to 1,000 CM (centimeters), which allows for sharp shadowing near the camera with lots of added detail. In the shadowing distance beyond 1,000 CM, RTDF shadowing is used, which shadows objects up to 1.2 KM (kilometers) away. This enables the trees in the far distance to cast shadows when this would be too costly for Cascaded Shadow Maps.

For additional information about Directional Light settings, see the Mesh Distance Fields Reference page.

Scene Representation

Each level that you create is made up of all these Mesh Distance Fields for your placed Actors. When Mesh Distance Fields are generate, they are done so "offline" using triangle raytracing that stores the results in a volume texture. Because of this, mesh distance field generation cannot be done at runtime. This method computes the Signed Distance Field rays in all directions to find the nearest surface and stores that information.

You can visualize the Mesh Distance Fields that represent your scene by using the viewport and selecting Show > Visualize > Mesh Distance Fields.





Menu to Enable Visualization

Mesh Distance Field Visualization

Click images for full size.

When you see areas that are more white than gray, it means that many steps were needed to find the intersection of the mesh surface. Rays at grazing angles to surfaces took many more steps to intersect than would have for a simpler mesh.

Mesh Distance Field Quality

Distance Field shadow fidelity has a significant impact on shadow accuracy, more so than Distance Field Ambient Occlusion. Increased Mesh Distance Field resolution will improve the shadows cast by Static Meshes. Use the Mesh Distance Field Visualization to inspect the quality.

The following example shows scene with Distance Field Shadowing with different Distance Field Resolution.





The following example shows scene with Mesh Distance Field visualization with different Distance Field Resolution.





Shadows for Mesh Distance Fields are computed at half-resolution with a depth-aware upsample. Temporal Anti-Aliasing (TAA) does a good job of helping reduce the flickering that can happen with half-resolution but jagged edges can still appear sometimes.

For additional information about Mesh Distance Field quality, see the Mesh Distance Fields page.

Performance

The following GPU times were done on a Radeon 7870 at a resolution of 1920x1080 in a full game scene:

Test

Cascaded/Cuebmap Shadow Maps Cost (ms)

Distance Field Shadows Cost (ms)

Percentage (%) Faster

Directional Light with distance of 10k units, 3 Cascaded Shadow Maps

3.1

2.3

25%

Directional Light with distance of 30k units, 6 Cascaded Shadow Maps

4.9

2.8

43%

One Point Light with a large radius

1.8

1.3

30%

Five Point Lights with a small radius

3.2

1.8

45%

Optimizations

Below are some things you can do or should consider to optimize Distance Fields shadowing:

On a Directional Light, a larger Source Angle increases cost as more objects have to be considered for each point being shadowed.

Larger values for Distance Field Shadow Distance reduce the culling efficiency.

Shadows from meshes with Two-Sided Distance Field Generation (enabled in the Build Settings) will cost more as the resulting shadows are never fully opaque.

Limitations

Distance Field Shadowing shares the general limitations of the Mesh Distance Fields technique. For more information about these limitations, see the Mesh Distance Fields page.

Steps

End Result

Additional Light Settings



When you're developing your games, you will find that there are situations where dynamic lighting is the best choice for your levels, like those with long view distances or ones where you have a large open world. In instances like this, precomputed lighting can be inefficient or too demanding on the target system's resources. Distance Field Shadows, also referred to as Distance Field Shadows, enables you to shadow at farther distances than traditional Cascaded Shadow Maps (CSM) with a Directional Light.

In this guide, you'll learn how to enable Distance Field Shadowing for different Light Types, including Directional, Point, and Spot Lights.

Steps

This feature requires that Generate Mesh Distance Fields be enabled in your Project Settings in the Rendering section. See how to enable Mesh Distance Fields here, if you have not done so already.

Start by navigating to the Place Actors panel, then in the Lights tab, select and drag a Directional, Spot, or Point Light into the main viewport.



To enable Distance Field Shadows on any Light component, the process is the same. The additional sections of this guide will cover specific properties for these light types.

With the Light selected, navigate over to its Details panel and set its Mobility to Movable or Stationary.



In the Details panel under Distance Field Shadows, set Distance Field Shadows to enabled.





Directional Light

Spot/Point Light

If this option is grayed out, make sure that you've first enabled the option for Generate Mesh Distance Fields in the Project Settings, and then check to make sure that the light's Mobility is set to Movable or Stationary.

End Result

Once your Light's have been set to Movable or Stationary and toggled Distance Field Shadowing on, your light will automatically use them for your level. For Directional Lights, Distance Field Shadowing will be enabled for any distance beyond the Cascaded Shadow Maps Dynamic Shadow Distance value.





In this test level for Fortnite, Cascaded Shadow Map (CSM) Dynamic Shadow Distance is 4,500 cm (centimeters) from the camera and when Distance Field Shadowing is enabled, they handle any shadowing beyond the CSM Shadow Distance. When CSM is the only shadowing method being used, distant objects (like the Court House columns) will have light leaking because it is not within the shadow distance. Farther distance objects will also not be shadowed properly.

When using a Directional Light, it can be helpful to set the Cascaded Shadow Map Dynamic Shadow Distance Moveable Light slider to 0 making it possible to only see the shadows produced from Mesh Distance Fields. This is a useful way of testing your scene and diagnosing any potential Distance Field Quality issues in addition to using the visualization view modes.

Additional Light Settings

Use the Distance Field Reference to learn about settings specific to Distance Field Shadowing for Directional Lights and Point/Spot Lights. These settings enable you to have artistic control over your scene where you'll be able to control the softness of shadows and the farthest distance any shadow can cast. There are also some global adjustments specific to Directional Lights that can be used to remove self-shadowing artifacts in the scene caused from LOD (Level of Detail) meshes at farther distances from the camera.

Steps

End Result

Additional Sky Light Settings



In your games, you may rely mostly on screen space techniques to provide dynamic Ambient Occlusion (AO) or even precomputed lighting to make objects feel grounded in the world. These techniques are very useful but have their limitations. Screen Space Ambient Occlusion (SSAO) is limited to using scene depth and can only work within the visible screen space. Precomputed methods only work for static objects in the world, which means they can't update in realtime. Distance Field Ambient Occlusion (DFAO) is a fully dynamic AO method using Mesh Distance Fields for movable Static Meshes. It is also not limited to only being used in dynamically lit worlds; it can be used with precomputed lighting.

In this guide, you'll learn how to enable DFAO for your scene with a Sky Light and then explore the settings that can be adjusted.

Steps

This feature requires that Generate Mesh Distance Fields be enabled in your Project Settings in the Rendering section. See how to enable Mesh Distance Fields here, if you have not done so already.

Start by navigating to the Place Actors panel, then in the Lights tab, select and drag a Sky Light into the Level Viewport.



With the Sky Light selected, navigate over to its Details panel and set its Mobility to Movable.



End Result

Once the Sky Light is set to Movable, Distance Field Ambient Occlusion will automatically be enabled for your level.





You can see in this comparison example how much of a difference adding a Sky Light to your scene can make when Distance Field Ambient Occlusion is enabled.

Additional Sky Light Settings

Use the Distance Field Reference to learn about settings specific to Distance Field Ambient Occlusion for Sky Lights. These settings enable you to have artistic control over your scene, like controlling the accuracy of the occlusion, its tint and contrasts, and more.

Steps

End Result

Additional Settings



When your game relies on precomputed lighting with indirectly lit areas, it can be a challenge to blend movable objects because they will not have soft area shadowing. Sometimes you would need to fake this type of effect to blend dynamic objects with the rest of the scene by using complex material setups or even decals. Distance Field Indirect Shadows (DFIS) enables you to generate a Mesh Distance Fields for single Static Meshes for area shadowing in these indirectly lit areas where traditional shadow mapping techniques wouldn't work well.

Distance Field Indirect Shadowing works similarly to Capsule Shadows for Skeletal Meshes by using precomputed lighting samples generated during a lighting build. The lighting samples use Volumetric Lightmaps to determine the directionality and intensity of the indirect lighting.

In this guide, you'll learn how to enable Distance Fields for individual meshes that can then be used in your levels for area shadowing in areas lit with static indirect lighting so that you see results similar to this:



Steps

Unlike other Mesh Distance Fields features, DFIS does not require Generate Mesh Distance Fields to be enabled for the entire project. It can be enabled per-mesh, as explained in the steps below.

In the Content Browser, start by selecting any Static Mesh asset and double-clicking to open the Static Mesh Editor.



In the Static Mesh Editor, navigate to the Details panel. In the Static Mesh Settings section, set Generate Mesh Distance Fields to enabled. After enabling this, you can save and close the Static Mesh Editor.



Click for full image.

From the Content Browser select the SM_MatPreviewMesh_01 mesh and drag it into the Level Viewport.



With the Actor selected in the Level, go to the Details panel and set its Mobility to Movable.



Then, under the Lighting tab, enable Distance Field Indirect Shadow.



If your scene has not already had it's lighting built, click the Build on the Main menu and select Build Lighting Only to build your lighting for the scene.



End Result

In your indirectly lit areas that get a good amount of bounce light, you should see that your movable Static Mesh can cast a soft shadow in indirectly lit areas whereas before there would be no shadow cast.



Keep in mind, that indirect shadows will be practically non-existent in areas that are directly lit or areas that are brightly lit.

Additional Settings

Use the Distance Fields Reference to learn about settings specific to Distance Field Indirect Shadows for Static Mesh Actors.

Project Settings

Light Components

Directional Light

Point/Spot Light

Sky Light

Static Mesh Editor

Build Settings

General Settings

Actor Components

The Mesh Distance Fields system in Unreal Engine can be used with various different systems that can be enabled or disabled. You can use these settings and properties to obtain a specific style for your Project, or use them for optimization purposes.

Below you'll find the details about the available menu systems and settings you can use that are specific to Mesh Distance Fields.

Project Settings

The Project Settings panel contains the settings to enable Mesh Distance Field generation for the assets in your Project, as well as some optimization options you can enable to make the use of them more efficient in some cases.

Click Edit on the Main menu and select Project Settings to open it.



Settings for adjusting of the Mesh Distance Fields you can find by clicking Rendering > Software Ray Tracing. The table below details the settings available.



Click image for full size.

Property

Description

Generate Mesh Distance Fields

This determines whether the system will build Static Mesh Distance Fields, which can be used with Distance Field Shadows and Distance Field Ambient Occlusion. Enabling this will increase mesh build times and memory usage, and also requires you to restart the Unreal Editor for it to take effect.

If you enable the Generate Mesh Distance Fields setting for your project, you will still have increased memory usage even if you are not using any Distance Field rendering features on any Actors. If you disable this setting and restart the Unreal Editor, Mesh Distance Fields will no longer be loaded, and memory usage will go down.

Distance Field Voxel Density

Determines how the default scale of a mesh convert into distance field voxel dimensions. Changing this will cause all distance fields to be rebuilt. Large values can consume memory very quickly! Changing this setting requires restarting the editor.

Light Components

Below are the available Mesh Distance Field settings and properties that can be set for each Light Type available.

Directional Light

Below are the Directional Light settings that affect Distance Field Shadowing.



Property

Description



Light



Source Angle

This is the light source's angle in degrees and is used to support soft area shadows for dynamic shadowing methods using Distance Fields or Capsule Shadows.



Distance Field Shadows



Distance Field Shadow Distance

This is the farthest distance that will have Distance Field Shadowing. Distance Field Shadows will also cover the distance between this value and the Dynamic Shadow Distance Movable Light for CSM shadows.

Distance Field Shadows

This will toggle Distance Field Shadows on for the light source.



Distance Field Shadows Advanced Properties



Distance Field Trace Distance

This sets a distance in world units for how far shadows can cast from their shadow caster. When using larger values, you will increase the shadowing cost for the scene.

Ray Start Offset Depth Scale

This controls how large an offset there is for tracing shadows are from the receiving surface as the camera gets further away. This can be used to hide self-shadowing artifacts from low-resolution distance fields on large Static Meshes.

The Light Source Angle softens or sharpens shadows based on the rotational angle of the light and the value entered. This allows for very soft shadowing to happen for points of the mesh that are farther away from the shadow receiving surface. Shadows closer to the mesh and the receiving surface will be sharper.





The further the shadows stretch away from the mesh, or the farther that they are from the shadow receiving surface, the softer the shadow will become.

Cascaded Shadow Maps provide very detailed shadowing, but don't work well across extended view distances. Distance Field Shadows can cast shadow over a much greater distance more efficiently, but its quality relies heavily on the resolution of the volume texture generated for the Mesh Distance Field. Mesh Distance Field quality may require a higher resolution to capture important details that would normally show up with shadow mapping. For this reason, it is recommended to use a combination of Cascaded Shadow Maps for areas close to the camera, and Distance Field Shadowing for farther distances.





Despite the distance of all points of the lift from the ground, the shadow remains crisp and detailed when using Cascaded Shadow Mapping. Distance Field Shadows allow for softening of the shadow, based on the Light Source Radius and the distance of the shadow being cast from the surface, which provides a natural look.

The Distance Field Trace Distance controls how far Distance Field Shadowing can extend for any mesh that is casting shadows. Because shadows can extend along receiving surfaces for very long distances, this can cause Distance Field Shadows to increase performance cost for densely populated scenes. Lowering the Distance Field Trace Distance limits how far any one point of the Distance Field Shadow can be cast from a particular mesh without using a shorter Distance Field Shadow Distance.





In this example, a very tall tree is being lit by a Directional Light with a shallow angle (like at sunrise or sunset). Lowering the Distance Field Trace Distance limits the top of the tree from casting indefinitely.

Point/Spot Light

Below are the Point and Spot Light settings that affect Distance Field Shadowing.



Property

Description



Light



Source Radius

This is used as the size of the light source sphere. When you use larger values, you get a larger penumbra, but it can cause slightly lower performance.



Distance Field Shadows



Distance Field Shadows

This controls whether to use Distance Field area shadows.



Distance Field Shadows Advanced Properties



Ray Start Offset Depth Scale

This controls how large of an offset Distance Field Shadows have from the receiving surface as the camera gets further away. This can be useful to hide self-shadowing artifacts from low-resolution distance fields on large Static Meshes.

The Light's Source Radius is used to soften or sharpen area shadowing by adjusting the size representation of the light source itself. Like the Directional Light's Light Source Angle, the shadows will soften as the shadowed point gets farther from a receiving surface.





In this demonstration, the default value of 0 uses a hard-coded Source Radius of 20, to automatically provide soft area shadowing. The larger light source radius of 50 has much softer shadows.

The default Source Radius of 0 has a set hard-coded value of 20. When using a value greater than 0 and less than 20, the area shadows will sharpen accordingly.

The shadow maps for Point and Spot Lights are very detailed and sharp, similar to Cascaded Shadow Maps for Directional Lights. The quality of Ray Traced Distance Field Shadows relies heavily on the resolution of the volume texture generated for the Mesh Distance Field. Mesh Distance Field quality may require a higher resolution to capture important details that would normally show up in a shadow map.





Despite the distance of all points of the lift from the ground, the shadow remains crisp and detailed when using shadow mapping. Distance Field Shadows allow for softening of the shadow based on the Source Radius and the distance of the shadow being cast from the surface, which provides a natural look.

The Ray Start Offset Depth Scale controls the ray starting point for the Distance Field Shadows for a receiving surface, as the camera moves farther away. It helps to prevent self-shadowing artifacts that appear from low-resolution Mesh Distance Fields, or from meshes that have complex geometry which can't be reasonably captured in a volume texture.

In some cases, adjusting the Mesh Distance Field quality can reduce or remove these artifacts, without adjusting where the ray starts. Keep in mind that you may not want to pay the higher memory cost the generated volume texture would require. Ray Start Offset Depth Scale can help curb that cost for this light.





Some self-shadowing artifacts are present in the rock face where it has some crevices and the resolution of the Distance Field doesn't capture that amount of detail. Adjusting the Ray Start Offset Depth Scale a minimal amount will change where the shadow trace should begin by moving it inward.

This setting should only be adjusted by small amounts, as this can affect shadowing for any mesh that casts shadows from the light source which has been adjusted. When adjusting this setting, be cautious, and check different areas of your level. This check is especially important for Directional Lights and distance objects where it could have the most impact on visual quality.

Sky Light

Below are the Sky Light settings that affect Distance Field Ambient Occlusion (DFAO). These settings provide the most artistic control of DFAO in your levels.



Property

Description

Occlusion Max Distance

This is the maximum distance from an occluder to compute occlusion contribution. Raising this value will increase the cost of Distance Field AO, but will allow occlusion from further away.

Occlusion Contrast

This can be used to raise the contrast of the computed occlusion.

Occlusion Exponent

This is an exponent applied to AO. Values lower than 1 will brighten the occlusion without losing contact shadows.

Min Occlusion

This is useful to prevent the occlusion from going fully black when desired. This is also useful to simulate multi-bounce lighting, which would have prevented any areas from going fully black in real life.

Occlusion Tint

This is constant color used to color the occlusion. This should be black to be physically correct; other values can provide artistic stylization.

Occlusion Combine Mode

This controls how occlusion from Distance Field Ambient Occlusion is combined with Screen Space Ambient Occlusion.

Selection

Description

OCM Minimum

This takes the minimum occlusion value. This is effective for avoiding over-occlusion from multiple methods, but can result in the indoors looking too flat.

OCM Multiply

This takes the occlusion values from Distance Field Ambient Occlusion and Screen Space Ambient Occlusion and multiplies them. It gives a good sense of depth everywhere, but it can cause over-occlusion. Screen Space Ambient Occlusion should be tweaked to be less strong compared to Minimum.



The Occlusion Max Distance controls the maximum distance between two points, where occlusion of one point can affect another. When you adjust the Occlusion Max Distance, it also adjusts the accuracy that DFAO will have with other objects in the scene, which means you're increasing the performance cost of it as well.





Lowering the Occlusion Max Distance means that shadowing detail can't be captured for occlusion, since the distance between these points will not cause them to affect the other.





Increasing the Occlusion Max Distance will increase the accuracy of occlusion, because more points can be considered for shadowing, but it does come at a higher performance cost.

The Occlusion Contrast controls the difference in brightness between objects affected by DFAO.





Increasing the value for Contrast darkens a lot of the crevices and areas that are heavily occluded in this scene.

The Occlusion Exponent controls the power of the value being applied to the ambient occlusion. Lower values will brighten up the occlusion shadows, without losing the details for any contact shadowing near surfaces.

The Occlusion Exponent uses a default middle-ground value that works well for most scenes. Below are some comparisons of lower and higher range values.





With the lower value, occlusion for the scene becomes lighter anywhere that is shadowed using DFAO.





With the higher value, occlusion for the scene becomes darker anywhere that is shadowed using DFAO.

The Min Occlusion controls how dark any fully occluded areas can get in your level. It gives artists extra control over lightening DFAO in the occluded areas. This setting works well when used with Occlusion Max Contrast. Where occluded areas are darkened too much with Occlusion Max Contrast, you can then use Min Occlusion to lighten the shadowing a bit.





Here, Min Occlusion brightens up the DFAO occluded areas of the scene.

The Occlusion Tint affords artists the most control over the look of DFAO by enabling the color for occluded areas to be adjusted.





Only occluded areas that are shadowed by DFAO will be tinted based on the color values used.

The Occlusion Combine Mode enables you to choose to combine Screen Space Ambient Occlusion with Distance Field Ambient Occlusion in the scene.





Static Mesh Editor

The Static Mesh Editor contains several Actor-specific settings that affect any instance of this Actor placed in your Levels. These Actor-specific settings are within the Build Settings and General Settings sections of the Details panel in the Static Mesh Editor.



Click image for full size.

Build Settings

The Build Settings enable you to control the quality of your Mesh Distance Field, to enable two-sided generation for objects like foliage, and even to assign the Distance Field of another mesh to the current one.



Property

Description

Distance Field Resolution Scale

This enables you to adjust the quality of this Actor's generated Mesh Distance Field. This setting has an impact on the size of the volume texture that is created.

Two-Sided Distance Field Generation

This enables you to control whether the generated Mesh Distance Field should be two-sided or not. This allows for soft shadows in instances where there are multiple planes that would overlap, but it comes at a higher performance cost.

Distance Field Replacement Mesh

This enables you to select the Distance Field of another Static Mesh to use in place of the current Actor's own Mesh Distance Field.

General Settings

In the General Settings, you can enable options that are not quality-related. It includes the ability to generate a Mesh Distance Field for a particular mesh, without requiring Mesh Distance Fields to be enabled for the entire project. You can also control the self-shadowing that can occur with Static Meshes that are animated, or that move their vertices inside of the Distance Field.



Property

Description

Generate Mesh Distance Field

This controls whether to generate a Distance Field for this mesh, which can be used with Distance Field Indirect Shadows. This is ignored if the Project Setting for Generate Mesh Distance Fields is enabled.

Distance Field Self Shadow Bias

This is used for reducing self-shadowing from Distance Field methods when using World Position Offset to animate the mesh's vertices.

Actor Components

Below are the available Distance Field settings that can be toggled or overridden for individual Actors placed in your Levels.



Property

Description

Distance Field Indirect Shadow

This controls whether to use the Mesh Distance Field representation (when present) for shadowing indirect lighting on movable components (such as from lightmaps or skylight). This works like Capsule Shadows on Skeletal Meshes, except it uses the Mesh Distance Field, so no physics asset is required. The Static Mesh must have Generate Mesh Distance Field enabled in the Build Settings, or the project must have Generate Mesh Distance Fields enabled in order for this feature to work.

Override Distance Field Self Shadow Bias

This controls whether to override the Distance Field Self Shadow Bias setting of the Static Mesh Asset, replacing it with the Distance Field Shadow Bias of this component.

Distance Field Indirect Shadow Min Visibility

This controls how dark the Distance Field Indirect Shadow can be.

Distance Field Self Shadow Bias

This is useful for reducing self-shadowing from Distance Field methods when using World Position Offset to animate the mesh's vertices.

Affect Distance Field Lighting

This controls whether the primitive should affect dynamic Distance Field Lighting methods. This flag also requires that Cast Shadow be enabled.

When using Distance Field Indirect Shadows, the shadow's tone can be adjusted using the Distance Field Indirect Shadow Min Visibility setting. It gives artists more control over how dark these shadows can be, enabling the indirect shadows to blend with the surrounding static shadowing.







Ray Tracing in Unreal Engine

System Requirements

Overviews

Guides

Reference

Ray Tracing techniques have long been used in film, television, and visualization for rendering photo-realistic images, but often it required powerful computers and time to render individual images (or frames). For architectural visualization, this can often mean hours of rendering. For film and television, it can take many hours or even day to render high-quality image sequences.

Unreal Engine uses its own ray tracing code base that is shared with both its real-time and offline rendering paths. Real-Time Ray Tracing is an optimized path to work in real-time to render scenes, such as interactive experiences or in games. The offline path uses the built-in Path Tracer to generate uncompromised renderings of scenes. It works seamlessly with the Movie Render Queue to output the highest quality frame renders.

Explore the topics below to learn more about these paths and how you can use them in your own projects.

Ray Tracing in Unreal Engine

Ray Tracing in Unreal Engine supports two modes:

A hybrid Ray Tracer that couples ray tracing capabilities with traditional raster techniques for real-time rendering.

A Path Tracer for generating high quality, compromise-free rendered results.

System Requirements

The following system requirements must be met to use Ray Tracing and Path Tracing features of Unreal Engine:

System Requirements

Operating System

Windows 10 RS5 (Build 1809) or later

Verify your Windows build by typing winver in the Windows search bar.

GPU

NVIDIA RTX and some GTX series cards with DXR support using the latest device drivers.

For more information, see NVIDIA's site here.

Unreal Engine Version

5.0 and Later

Unreal Engine Rendering Path

Deferred Path

Overviews



An overview of the features that use hardware to render real-time ray traced results.



An overview of the features of the Path Tracer rendering mode.

Guides



A selection of topics for improving performance of ray tracing features in your projects.



A collection of topics to aid with development of projects using hardware ray tracing features.



A how-to guide for configuring the Unreal Engine Movie Render Queue feature to get high-quality cinematics—particularly when using ray tracing.

Reference



A listing of all available properties setting for Ray Tracing and Path Tracer features.

Enabling Hardware Ray Tracing

Features of Hardware Ray Tracing

Using Ray Tracing Features

Performance and Debugging

Supported Ray Tracing Features

Ray tracing techniques have been used in offline rendering for film, television, and visualization because they produce high-quality, natural-looking results with soft shadowing for lights, accurate ambient occlusion, interactive global illumination, reflections, and more. However, rendering images at those quality levels have often required powerful computers and long periods of time to render even a single frame.

With Unreal Engine, ray tracing is made possible with supported hardware allowing for interactive experiences rendered with subtle lighting effects in real-time. Unreal Engine's hardware ray tracing capabilities are coupled with those of traditional raster rendering techniques. Combining the two means tracing rays for fewer samples per pixel and utilizing denoising algorithms to achieve results perceptually close to the results of an offline renderer.

Real-time rendering of Ray Tracing features in the Archviz Interior sample project available on the Epic Games Launcher.

Enabling Hardware Ray Tracing

In the Project Settings under Engine > Rendering > Hardware Ray Tracing, enable Support Hardware Ray Tracing and restart the editor for the changes to take effect.



When Ray Tracing is enabled, it also enables Support Compute Skin Cache for the project, if not already enabled.

Some features of hardware ray tracing, such as Ray Traced Shadows and Ray Traced Skylight, can be enabled independently of other ray tracing features. In the same Hardware Ray Tracing section of the Project Settings, you can enable the features you need for your project.



Features of Hardware Ray Tracing

The following hardware ray tracing features are supported.

Ray Traced Shadows

Ray Traced Shadows simulate soft area lighting effects for objects in the environment. This means that based on the light's source size or source angle, an object's shadow will have sharper shadows near the contact surface than farther away where it softens and widens.





Ray Traced Ambient Occlusion

Ray Traced Ambient Occlusion (RTAO) accurately shadows areas blocking ambient lighting better grounding objects in the environment, such as shadowing the corners and edges where walls meet or adding depth to the crevices and wrinkles in skin.





When compared with Screen Space Ambient Occlusion (SSAO), RTAO grounds objects and adds depth to the scene to produce natural looking shadowing in indirectly lit areas.





By varying the Intensity and Radius properties of the Ambient Occlusion effect, you can control its size and strength.

Ray Traced Reflections

This feature of ray tracing is deprecated and may be removed in a future release.

Ray Traced Reflections (RTR) simulates accurate environment representation supporting multiple reflection bounces.

This example shows a single bounce of ray traced reflections compared to multiple bounces of ray traced reflection. Using multiple bounces creates real-time inter-reflection between reflective surfaces in the scene.





In contrast, Screen Space Reflections (SSR), Planar Reflections, or even Reflection Capture Actors cannot capture the entire scene dynamically nor does it have some of the limitations present in these other reflection methods.

In this comparison, SSR is only capable of a single reflection bounce and is limited to what is visible on the screen for representation. On the other hand, RTR is capable of multiple bounces and is not limited to what is visible, meaning that we can visibly see the sides of the book, reflected floor behind the camera, and additional lightings being reflected on surfaces coming through the window.





Ray Traced Translucency

This feature of ray tracing is deprecated and may be removed in a future release.

Ray Traced Translucency accurately represents glass and liquid materials with physically correct reflections, absorption, and refraction on transparent surfaces.





Ray Traced Global Illumination

This feature of ray tracing is deprecated and may be removed in a future release.

Ray Traced Global Illumination (RTGI) adds real-time interactive bounce lighting to areas of your scene not directly lit by a given light source.





There are two ray-traced global illumination methods to choose from in the Post Process Volume:

Brute Force emulates offline renderers indirect lighting, but is slower to render.

Final Gather provides a single bounce of indirect lighting, but is faster to render.

This feature is experimental.

The Final Gather approach to ray-traced global illumination uses a final gather-based technique that trades some quality for runtime performance. The technique is a two-pass algoirthm, whereby the first pass distributes shading points throughout the scene — similarly to the Brute Force method — but at a fixed rate of one sample per pixel. A history of up to 16 shading point samples are stored in screen space during this pass. During the second pass, the algorithm attempts to reconnect to the shading point history, amortizing the cost of the method.

The Brute Force algorithm is intended to emulate the Path Tracer's ground truth reference and is similar in how it executes the result. The Final Gather method trades that emulation for performance. This has it's own limitations, like being limited to a single bounce of indirect diffuse global illumination, and reprojection from the previous frame sample data is susceptible to ghosting when the camera is moving fast.

To aid in suppressing temporal ghosting artifacts, you can use the following command to modify the world space rejection criteria.

It is currently based on a world distance measured from the original shading point. This rejection crieteria defaults to 10 units.

The Final Gather method also requires the following settings to be used in the Post Process Volume for it to work effectively:

Max Bounces: 1

Samples Per Pixel: 16

Any additional Max Bounces beyond 1 are silently discarded and when adjusting the Samples Per Pixel. It's best to increase the value by powers of two (8, 16, 32, 64).

Using Ray Tracing Features

The sections below provide details for using ray tracing features in your project using the Post Process Volume and individual light properties.

Post Process Volume

Use Post Process Volumes provides controls for some ray tracing features:

Ambient Occlusion

Global Illumination

Reflections

Translucency.



Click image for full size.

For additional information about the available post process settings, see Ray Tracing and Path Tracer Properties.

Lights

Lights support casting soft area shadows for all types of lights when Cast Ray Traced Shadows is enabled. The soft shadowing of the light is based on the size of the light source and its distance from the shadow-casting object.





Control the softness of the shadow by adjusting the following:

On a Directional Light, set the Source Angle.

On Point and Spot Lights, set the Source Radius.

On a Rect Light, set the Barn Door Angle and Barn Door Length to shape the light and soften the shadow softness.

Sky Lights

Sky Lighting supports soft ambient shadowing when Cast Ray Traced Shadow is enabled and the Source Type is specified. The Sky Light captures the distance parts of the level and applies that to the sene as a light.



For Ray Traced Global Illumination to work with sky lighting, enable the experimental console variable r.RayTracing.GlobalIllumination.EvalSkyLight.

Performance and Debugging

The following sections suggest starting points and basic tooling you can use to debug and inspect the performance of hardware ray tracing in your projects.

Stat GPU

Use the stat command GPU Stats to check relevant GPU performance of ray tracing features. It provides relevant information about ray tracing features which are enabled and how much frame time is being spent on each to render the current scene view.



Stat D3D12RayTracing

Use the stat command Stat D3D12RayTracing to check relevant ray tracing resource usage.



Ray Tracing Debug View Modes

Hardware ray tracing provides a selection of debug view modes to look at specific areas and features of ray tracing. Use the Level Viewport to access these debug views from the View Modes dropdown under Ray Tracing Debug.



Force Disable All Ray Tracing Effects

Use the console variable r.RayTracing.ForceAllRayTracingEffects to quickly enable or disable all ray tracing features in the scene.

0 disables all ray tracing features.

1 enables all ray tracing features.

-1 uses the state previously set by any console variables and it uses values set in the Post Process Volume. (Default)

Supported Ray Tracing Features

This list is intended to give you an idea of what is currently supported and is not meant to be a comprehensive list of supported ray tracing features.

Feature

Supported (Y/N/Partially)

Additional Notes



Rendering Path



Deferred

Y

Forward

N



Types of Lights



Directional Light

Y

Sky Light

Y

Point Light

Y

Spot Light

Y

Rect Light

Y



Lighting Features



Emissive Surfaces

Partially

Supported for reflections on surfaces, but does not emit light or cast shadows.

Light Transmission

N

The translucent shadow is treated as opaque, meaning no colored shadows or light transmission through the material.

Area Shadowing

Y

IES Profiles

Y

Light Functions

N

Volumetric Fog

N

Image Based Lighting (IBL)

Y

Support for HDRI with Sky Light.



Materials: Blend Mode



Opaque

Y

Masked

Y

Translucent

Y

Anisotropic

Y



Materials: Shading Model



Default Lit

Y

Unlit

Partially

Masked

Partially

Supports casting of masked shadows.

SubSurface and SubSurface Profile

Y

Preintegrated Skin

Partially

Works but the result isn't correctly raytraced. It uses the raster pipeline.

Clear Coat

Y

TwoSided Foliage

Y

Hair

Partially

Works but the result isn't correctly raytraced. It uses the raster pipeline.

Cloth

Partially

Works but the result isn't correctly raytraced. It uses the raster pipeline.

Material Functions

Y

Two-Sided

Y

World Position Offset

Y

Enabled per-Actor through the details panel with the property Evaluate World Position Offset. Supports, Static Meshes, Instanced Static Meshes, and Hierarchical Instanced Static Meshes.



Geometry Types



Skeletal Mesh

Y

Static Mesh

Y

Geometry Cache (Alembic)

Y

Landscape

Y

Hierarchical Instanced Static Mesh (HISM)

Y

Instanced Static Mesh (ISM)

Y

Splines

N

Procedural Mesh

Y

This type of geometry can be expensive to render in Ray Tracing.

BSP Brushes

N

Levels of Detail (LOD)

Y

Dithered LOD transitions are not yet supported.



Visual Effects (VFX)



Niagara

Partially

Currently supports Sprites, Ribbons, and Mesh emitters.

Cascade

N



Platform Support



Multi-View (VR and Split-Screen)

Y

Materials

Ray Tracing Quality Switch Replace Node

Ray Traced Shadows Per Material

Testing Material Costs

Translucency Index of Refraction (IOR)

Controlling the amount of Refraction

Single Sided and Two Sided Material Refraction

Light Transmission for Subsurface Profile Materials

Reflections

Ray Tracing Reflection Capture Fallback

Including Translucent Objects in Reflections

Sky Lights

Geometry Considerations with Ray Tracing

General Optimizations for Hardware Ray Tracing Features

Ray Tracing Solid Angle and Distance-based Culling

Evaluating Denoiser Quality

This page contains suggestions you can use with Hardware Ray Tracing features.

Materials

The following suggestions work with Materials and hardware ray tracing features.

Ray Tracing Quality Switch Replace Node

Use this node to replace entire parts of your Material logic to lower the cost of features like ray tracing global illumination, reflections, and translucency with less complex logic. When applying these in your Material, it will affect any ray tracing with this material where it is applied in the Level.

The example below shows the Normal logic path with diffuse, roughness and normal map textures. The Ray Tracing path removes the Normal map texture and uses less complex logic for Roughness. This change makes the material cheaper to render for ray tracing effects, especially with ray tracing global illumination and reflections.



Click image for full size.

Ray Traced Shadows Per Material

Use the Cast Ray Traced Shadows checkbox to set whether this Material casts ray traced shadows. This is useful for controlling specific elements of any Materials assigned to geometry that should, or should not cast a raytraced shadow.

Testing Material Costs

Complex Materials can affect performance of hardware ray tracing features. Use the console command r.RayTracing.EnableMaterials to test performance impact.

Translucency Index of Refraction (IOR)

When setting up a Material for refraction with ray tracing, the Refraction material input controls the index of refraction (IOR) in your translucent materials.

The amount of refraction is set up in the Material applied to an object. In the Level, the post process settings control whether refraction is ray traced and the maximum number of refraction bounces that are possible.





Material Setup:

Enable Two Sided in your Material.

While this is not a requirement, single sided/non-manifold geometry doesn't have a good way of handling volume tracking or ray medium stacking. A two-sided material provides accurate results and is the recommended method for handling all translucent materials when using ray tracing translucency.

Set the Lighting Mode to Surface Translucency Volume or Surface Forward Shading.

Use the Refraction input to control the index of refraction.

Post Process Volume Rendering Features Setup:

Under the Translucency category, set the Type to Ray Tracing.

Under the Ray Tracing Translucency category, set the following:

Refraction: Enabled

Max Refraction Rays: Set the maximum number of rays to use. This should be a high enough value that it allows light to pass through to the other side.

Use a [Material Instance]() to dynamically control the IOR of the material with instance results.

Controlling the amount of Refraction

The amount of refraction and light transport that takes place is controlled by using the Refraction input in a Material. The Post Process Volume settings must have the Refraction check box enabled and greater than 1 Max Refraction Rays set.

The translucent material below is using a refraction input value of 0.04. The post process has a Max Refraction Ray count of 6 to pass light through the translucent material.





The examples below shows how different refraction input values in the Material affect the index of refraction.

Dragging the slider shows the amount of refraction being applied from 0.01, 0.05, and 0.1.



The examples below demonstrate how the Post Process Volume Max Refraction Rays value affects light transport through the translucent material. A single ray does not provide enough bounces to escape the material, leaving it appearing darkened or black. Increasing the maximum number of refraction rays gives light a greater opportunity to escape the material. Not all materials or rays will require the maximum number of refraction rays, but in cases where more are needed, this may leave some materials looking darker than needed.

Dragging the slider shows the result of using 1, 3, and 5 refraction rays.



Single Sided and Two Sided Material Refraction

Ray traced refraction works with both single sided and two sided materials to allow light transport through the object's volume. While single sided materials are supported for refraction, two side materials provide physically accurate results and is recommended for all Translucent Materials using ray tracing transparency.





Use the Post Process Volume Max Refraction Rays property to set the number of refraction bounces light transport should use.

Light Transmission for Subsurface Profile Materials

Light transmission on materials using a Subsurface Profile is possible when the light source also has the Transmission property enabled on the Actor placed in the Level.





A small scattering simulation is run during the ray tracing shadow computation to compute the expected volumetric scattering distance through the medium to the shadow-casting light. The scatter distance is used during lighting to compute the in-scattering contribution from the light.

Reflections

The following suggestions work with the Reflection Environment and hardware ray tracing features.

Ray Tracing Reflection Capture Fallback

Ray Tracing Reflections are more expensive when rendering multiple bounces that create reflections inside of reflections. Without multiple bounces, the intra-reflected materials appear black. A lower cost solution is to use ray traced reflections for and then fall back to placed Reflection Capture Actors in the Level as the last bounce.

Enable reflection capture fallback with the console variable r.RayTracing.Reflections.ReflectionCaptures.



Dragging the slider shows a single bounce RTR, two bounces RTR with no reflection capture fallback, and a single bounce with reflection capture fallback.

Including Translucent Objects in Reflections

Enable objects with translucent materials to appear in Ray Traced Reflections by enabling Include Translucent Objects in the Post Process Volume settings from the Ray Tracing Reflections category.

Sky Lights

Capturing distance objects, like a sky dome mesh, should be disabled for Sky Light contribution, unless it is needed. This saves some performance and optimizes the scene.

The BP_SkySphere sky dome mesh and Blueprint that is included with starter Levels has this sky light contribution disabled by default. It will make reflections from sky look different than expected but saves performance with hardware ray tracing.

Object contribution is enabled/disabled from the Details panel with the checkbox for Visible in Ray Tracing when the object is selected in the Level.

Geometry Considerations with Ray Tracing

Geometry with small holes, or lots of little details, can significantly impact performance. For example, trees and bushes with lots of leaves, or grates and fences that have holds in them.

Indoor environments are slower to render than outdoors ones because often light enters from the outside and is expected to bounce around well enough to light a room. Areas that are directly lit by a light are faster to render than ones indirectly lit by light. Also, consideration with other ray tracing features like reflections and translucency affect performance in these situations.

General Optimizations for Hardware Ray Tracing Features

Setting Reflections and Translucency Maximum Roughness

Use Max Roughness to set a threshold for raytraced reflections on Materials. This can be done within the Post Process Volume or using the console command r.RayTracing.Reflections.MaxRoughness.

Setting a Maximum Ray Distance for Global Illumination, Reflections, and Translucency

This sets a maximum ray distance for each of these features to lower their cost and contribution in the scene.

Use the console to set the MaxRayDistance console variable for each of these raytraced features. You can find them under r.RayTracing.*.

Ray Traced Global Illumination Optimizations

Screen Percentage and Sample Per-Pixel default to 50 and 4, respectively. If different values are needed, use the console commands r.RayTracing.GlobalIllumination.ScreenPercentage, and r.RayTracing.GlobalIllumination.SamplesPerPixel.

Light contribution to global illumination can be set on each Light Actor by enabling/disabling Affect Global Illumination.

Ray Tracing Solid Angle and Distance-based Culling

Scenes with ray tracing require objects outside of the camera view to be present in the scene, especially for highly reflective surfaces, which can increase cost of rendering. Culling objects that aren't visible or needed can help optimize and gain some of that performance back.

Ray tracing provides several ways of culling objects in the scene: by distance from the camera, or by projecting an area (or a angle) behind the camera and testing individual object bounds to determine whether they should be culled, not at all, or both simultaneously. The type of culling used is set by using one of the following values with the console variable r.RayTracing.Culling.

0 culling is disabled.

1 culls objects behind the camera by distance and solid angle. (Default culling method)

2 culls objects in front of and behind the camera by distance and solid angle.

3 culls objects in front and behind the camera by distance or solid angle.

Higher values cull more objects in the world.

Additionally, the ray tracing console variables (r.RayTracing.*) use two commands to configure Solid Angle culling: an angle and a radius.

Angle sets the projected area angle behind the camera (in degrees) that object's bounds will be tested against for whether they should be culled or not. Increasing the angle will aggressively cull a lot of objects.

Radius culls any object outside of the specified radius. By default, the radius is set to 100 meters (or 10000 cm/Unreal Units).

Two examples of ray tracing console variables using these would be r.RayTracing.Culling.Angle, and r.RayTracing.StaticMeshes.WPO.CullingRadius.

If distance-based culling is needed, any radius variables should be set to -1.

Evaluating Denoiser Quality

Hardware ray tracing features rely heavily on denoising algorithms to use as few pixels as possible and make up the different with a denoiser to intuit the rest. You can evaluate the quality of the denoiser for different ray tracing effects by following these steps:

Disable Temporal Anti-Aliasing and Depth of Field

Both of these are running in linear color space in Unreal Engine's renderer. They do some HDR color weighting tricks to avoid aliasing between shadows and highlights.

Compare the Denoised single sample per pixel with an Undenoised single sample per pixel.

The result will look incorrect due to the energy difference and that the denoiser is darkening the shadows too much. However, a single sample per pixel will look brighter due to the tonemapper's non-linear operation.

For a better comparison, the Denoised single sample per pixel should be tested against an Undenoised multiple samples per pixel.





The denoised single sample per pixel will not be perfect due to information loss. However, when compared to undenoised multiple samples per pixel, the results are consistent.

Keep in mind that the denoiser supports up to four samples per pixel for hardware ray tracing features. The more samples used, the closer it is to matching the undenoised multiple sampples per pixel result.

Benefits of the Path Tracer

Path-Traced Examples

Enabling the Path Tracer in Your Project

Using the Path Tracer in the Level Editor

Using the Path Tracer with Movie Render Queue

Path Tracer Post Process Volume Settings

Limitations of the Path Tracer

Supported Features of the Path Tracer

Additional Information

Reducing Firefly Artifacts

Denoising Options

Skylighting with the Path Tracer

Fog and Atmosphere Volumetrics

Direct Visibility of Light Sources

Glass Rendering with the Path Tracer

Rough Light Transmission and Reflections

Useful Console Variables

Frequently Asked Questions

Capturing a Converged Path-Traced Image using HighResShot

Enabling the Path Tracer at Runtime

Avoiding Timeout Delays on Windows for "D3D Device Removed Crashes"

Instances Disappearing in the Path-Traced View

Using Path Tracer with Nanite-Enabled Meshes

Enabling Support for Multiple GPUs

The Path Tracer is a progressive, hardware-accelerated rendering mode that mitigates the disadvantages of real-time features with physically correct and compromise-free global illumination, reflection and refraction of materials, and more. It shares the ray tracing architecture built into Unreal Engine, with minimal to no additional setup required to achieve clean, photoreal renders.



"Virtual tour in Unreal Engine" by ARCHVYZ. Design by Toledano Architects.

The Path Tracer uses the same ray-tracing architecture as other ray-tracing features, such as Real-Time Ray Tracing and GPU Lightmass, making it ideal for ground truth comparisons and production renders. The Path Tracer only uses geometry and material present in the scene to render its unbiased result, and does not share the same ray-tracing code that has been developed to work well for real-time rendering.

Benefits of the Path Tracer

The Path Tracer provides the following benefits when compared to other rendering modes:

The ability to generate high-quality photorealistic renders with physically accurate results.

Minimal or no additional setup required to achieve comparable results to other offline renderers.

Reduces the feature gap of comparable real time features. For example, materials seen in reflections and refractions are rendered without limitations, such as having global illumination and path-traced shadows present.

Full integration with Sequencer and Movie Render Queue to support Film / TV quality render outputs.

Path-Traced Examples

The following scenes are examples of the high-quality renders achieved using the Path Tracer.



"Virtual tour in Unreal Engine" by ARCHVYZ. Design by Toledano Architects.

Enabling the Path Tracer in Your Project

The Path Tracer requires Hardware Ray Tracing to be enabled for the project. The following system requirements must be met and these settings must be enabled.

System Requirements:

Operating System: Windows 10 1809 or later

GPU: NVIDIA RTX and DXR driver-enabled GTX series graphics cards

Project Settings:



Platforms > Windows > Targeted RHIs > Default RHI: DirectX 12

Engine > Rendering > Hardware Ray Tracing: Enable Path Tracing

Engine > Rendering > Hardware Ray Tracing: Enable Support Hardware Ray Tracing

Engine > Rendering > Hardware Ray Tracing: Enable Path Tracing

Unreal Engine 5 introduced settings that control the creation of path tracer specific shader permutations for materials. Projects which do not plan to use the path tracer at all can disable this setting to reduce shader compilation time.

Engine > Rendering > Optimizations: Enable Support Compute Skin Cache

When Support Hardware Ray Tracing is enabled for the project, a pop-up window asks you to enable Support Compute Skin Cache if it is not already enabled. This is required to support hardware ray tracing and path tracing features.

Restart the engine for changes to take effect.

Using the Path Tracer in the Level Editor

Enable the Path Tracer view in the Level Viewport by using the View Modes dropdown menu to select Path Tracing.



When enabled, the renderer progressively accumulates samples from the current view by continuously adding samples while the camera is not moving. When the target sample count is reached, the frame will be denoised (if denoising is enabled in the Post Process Setting) to remove any remaining noise present in the render.

In most cases, when the scene changes the samples are invalidated and the process starts again. Moving the camera, changing views, updating or changing materials on an object, and moving or adding objects to the scene will all result in the scene's samples being invalidated.

The Path Tracer can be used interactively and will quickly start to display pixels with shaded color as samples accumulate. The amount of time it takes to render largely depends on the complexity of the scene and the materials being sampled. Outdoor scenes tend to render more quickly as rays can escape with fewer and faster bounces. Interior scenes, especially those with materials with albedos close to 1.0, cause light paths to be longer and will therefore result in a longer render time.

Using the Path Tracer with Movie Render Queue

This section goes into details about using the Movie Render Queue to generate a path-traced rendered output. For general usage and workflow information, see Movie Render Queue before proceeding.

The Movie Render Queue (or MRQ) is useful for production pipelines when producing high-quality rendered outputs. When combined with the Path Tracer, it allows for substantially higher quality renders than could be achieved otherwise.

The Path Tracer module enables the Path Tracer to be used to output rendered frames and it provides some settings specific to its rendering path.



Post Process Volumes placed in the Level also control specific path tracing functionality, such as the maximum number of ray bounces, support for emissive materials, and exposure.

MRQ also contains other settings modules that provide additional controls and options for achieving higher-quality renders.

The High Resolution module provides settings to render frames as separate tiles that can be combined to render higher single frame resolutions than would otherwise be possible. Individual tiles can use up to the largest resolution supported by your graphics card (for example, 7680x4320 for RTX 3080 cards).

The Anti-aliasing module provides specific settings to adjust the sample counts per pixel and for better motion blur quality. This module provides warm-up times that can be required for level-loading and visual effects to render the scene accurately.

Temporal Sample Count interpolates several rendered frames at slightly offset instances in time, improving motion blur quality. This accumulation of samples happens after denoising occurs, helping stabilize residual artifacts from individual spatial passes.

Spatial Sample Count sets the number of samples per pixel to use per frame. Increasing the samples per pixel, decreases noise present in each render pass while increasing the time needed to render each frame. The Post Process Volume samples per pixel setting has no effect over this setting for the MRQ output.



The total number of samples taken per pixel is the product of the spatial and temporal sample counts. Spreading the samples across both spatial and temporal can produce better results in some cases. For example, if you want to use 16 samples per pixel, you could apply 4 samples to spatial and 4 to temporal, or 16 to spatial and 1 to temporal.



The Console Variables module enables you to add any console variables that are relevant to your rendered frames. This includes overrides for quality, or toggling of some settings that would be relevant to the Path Tracer.

The Output module provides settings to configure the output directory, file name, image resolution, and the start / end frames you want to render.

Path Tracer Post Process Volume Settings

Placed Post Process Volumes in the Level provide configurable properties for the Path Tracer. These include settings for the maximum number of light bounces, samples per pixel, anti-aliasing quality (or Filter Width), and more.

Settings for the Path Tracer can be found in the Post Process Volume Details panel under the PathTracing category.



Property

Description

Max. Bounces

Sets the maximum possible number of light bounces rays should travel before being terminated.

Samples Per Pixel

Sets the number of samples used per pixel for convergence. A higher number of samples reduces noise of the rendered image.

Filter Width

Sets anti-aliasing filter width to improve output quality. Lower values yield sharper (more aliased) results, while larger values yield softer (blurier) results.

Emissive Materials

Enables bounce lighting for emissive materials. Enabling this property prevents double-counting illumination of surfaces that are also represented by actual light sources, and noise from small emitters. For example, having an emissive material representing a small light bulb while also using a point or spot light source to illuminate the area would be double-counted in this case.

Max Path Exposure

Sets the maximum exposure allowed for path tracing in order to reduce firefly artifacts from occurring. Adjusting the exposure to a higher value than the scene's exposure helps mitigate these artifacts. (See Additional Information section of this page for more details and an example of this type of artifact).

Reference Depth of Field

Enables reference-quality depth of field, which replaces the post-process effect.

Reference Atmosphere

Enables path tracing in the atmosphere instead of baking the Sky Atmosphere contribution into the skylight. Any Sky Light component present in the scene is automatically ignored when this setting is enabled. Refer to the Reference Atmosphere section of this page.

Denoiser

This toggle uses the currently loaded denoiser plugin on the last sample to remove noise from the rendered output. By default, Intel's Open Image Denoiser plugin is used by the Unreal Engine. This toggle has no effect on the rendered output if the denoiser plugin is not enabled.

Limitations of the Path Tracer

The following are some of the current limitations of path tracing in Unreal Engine.

Bright Materials slow down interior renders

Materials which have an albedo value close to 1.0, such as a bright white color, cause rendering of frames to take longer than needed because the path Tracer needs to simulate the path of lights with many bounces. Interior scenes are especially susceptible to this because light rays can take longer to escape the environment before being terminated. The Path Tracer employs the Russian Roulette technique to terminate rays that aren't likely to contribute to the scene sooner. Rays that continuously bounce through the scene are less likely to happen because they are terminated by the Russian Roulette technique when possible. When a material's albedo uses a value close to 1.0, termination of the ray path is less likely to happen, and contributes to longer render times for the frame.

Materials that reflect all incoming light are rare in the real world, and these tend to have a washed out appearance to their surface. For this reason, it is recommended that you keep the Base Color below 0.8 for all diffuse materials.

Dynamic Scene Elements

The Path Tracer works by having the renderer accumulate samples over time. This is ideal for static scenes and less so for dynamic scenes that include elements such as moving lights, animated skinned meshes, and visual effects. These types of elements do not invalidate path tracing in the editor and appear as blurred, or streaking artifacts in the frame. This only appears when working in the editor and is remedied by using the Movie Render Queue to render out final elements.

Path Tracing Material Quality Switch Nodes

Optimizing materials for path tracing features by reducing their complexity using the PathTracingQualitySwitch node reduces complexity or workarounds used in standard materials. Since runtime is not a concern, compromises to the material are not needed. Using these nodes helps provide a compromise-free result without duplicating the material.

Ray Tracing Material Quality Switch Nodes

Optimizing material for ray tracing features by reducing their complexity uisng the Ray Tracing Quality Switch node helps reduce their costs at runtime. This allows Unreal Engine's ray tracing features to use a simpler material compared to the deferred renderer. Since the Path Tracer is intended for high quality output, it uses the Normal port of these Switch nodes, despite being based on ray tracing. To control the behavior of materials specifically for the Path Tracer, use the PathTracingQualitySwitch node instead.

HDRIBackdrop is not compatible with the Path Tracer

The current implementation of the HDRIBackdrop component leads to double-counted illumination in the Path Tracer and disables importance sampling of the HDRI lighting. It is recommended to use a Sky Light with a specified texture and setting the path tracer console variable r.PathTracing.VisibleLights 2 to make the backdrop appear.

This does not provide a shadow-catching ground plane.

For additional information and notes on specific features, see the Supported Features section below.

Supported Features of the Path Tracer

The limitations of the Path Tracer are either limitations of the current implementation or features that aren't planned for support. This list of features intends to give you an idea of what is currently supported with this current release. It is not a comprehensive list of all supported features / properties of the engine.

The Path Tracer shares the same code used with Real-Time Ray Tracing features of Unreal Engine. In general, if a feature is supported by real-time ray tracing then it should be supported by the Path Tracer.

Feature Name

Supported?

Additional Notes



Geometry Types



Nanite

Yes

The Fallback Mesh is used for Nanite-enabled meshes by default. Lower the Fallback Relative Error parameter in the Static Mesh Editor to use more of the source mesh's triangles. (Experimental) Initial support for native path tracing of Nanite meshes is enabled when setting the console variable r.RayTracing.Nanite.Mode 1. This preserves all detail while using significantly less GPU memory than zero-error fallback meshes.

Skinned Meshes

Yes

Animations do not invalidate the path tracer, which can cause blurring, or streaking, to be visible in the viewport. Movie Render Queue should be used to output final images.

World Position Offset-driven Animation

Yes

Evaluate World Position Offset should be enabled on individual scene Actors. They do not invalidate the Path Tracer, which can cause blurring, or streaking, to be visible in the viewport. Movie Render Queue should be used to output final images.

Hair Strands

Yes

Hair Strand support is still considered experimental as it can require many resources to build efficient acceleration structures. The console variable r.HairStrands.RaytracingProceduralSplits can be used to balance between rendering performance and acceleration structure build performance (memory usage). The default value of 4 emphasizes rendering performance, but heavy grooms can lead to instability. If you experience GPU timeouts, try lowering this value to or reduce the number of hair segments in the groom.

Landscape

Yes

Spline Meshes

No

Instanced Static Mesh

Yes

Hierarchical Instanced Static Mesh

Yes

Water Geometry

Yes



Visual Effects



Niagara Particle Systems

Yes

Particle systems do not invalidate the Path Tracer, causing blur / streaking to be visible in the viewport. Movie Render Queue should be used to output final images.



Light Types



Directional Light

Yes

Sky Light

Yes

Currently Sky Light capture is only visible when Real Time Capture is enabled.

Sky Atmosphere and Volumetric Clouds aren't yet supported.

To improve render quality, increase the resolution of the Sky Light capture to be higher than used for real-time capture.

When not using Real Time Capture mode, a sky box / sphere is expected to have sky representation. Its material must have the flag Is Sky enabled in the material's settings, otherwise its illumination will be double-counted against the skylighting — and is likely to produce noise since it won't be importance sampled.

Sky box / sphere shapes should also not cast shadows because they can occlude contributions from the Sky Light and Directional Light.

Point Light

Yes

Spot Light

Yes

Rect Light

Yes



Lighting Features/Properties



Emissive Materials

Yes

Emissive parts that are small can introduce a lot of noise to the rendered scene. They can also cause double-counted lighting if the emissive parts have a light associated with them. Use the Emissive Materials checkbox in the Post Process Volume settings to disable them, or use the console variable r.PathTracing.EnableEmissive 0.

Sky Atmosphere

Yes

Requires a Sky Light in the scene which has Real Time Capture enabled on the component. Or, enabling the Post Process Volume setting Reference Atmosphere, which path traces the atmosphere instead of baking the Sky Atmosphere contribution into the Sky Light. Any Sky Light present in the scene is automatically ignored when this setting is enabled. Refer to the Fog and Atmosphere section of this page.

Volumetric Clouds

Partially

Requires a Sky Light in the scene which has Real Time Capture enabled. When the Post Process Volume setting Reference Atmosphere is enabled, this component is currently ignored.

Exponential Height Fog

Yes

Requires Volumetric Fog setting to be enabled. Not all controls are supported since some have non-physical meaning. Refer to the Fog and Atmosphere section of this page.

Volumetric Fog

Yes

Must be enabled on Exponential Height Fog component. Refer to the Fog and Atmosphere section of this page.

IES Profiles

Yes

Light Functions

Yes

Also supports colored light functions when r.PathTracing.LightFunctionColor is enabled. Color light functions are currently only supported in the path tracer.



Post Processing



Depth of Field

Yes

By default, the Path Tracer leverages the engine's post-processed depth of field but inherits the inherent limitations of this approach when it comes to translucent materials. As an alternative, enable a reference quality mode in the Post Process Volume which simulates depth of field directly during the path tracing process instead.

Motion Blur

Partially

The most accurate results can be obtained with Movie Render Queue when Reference Motion Blur is enabled on the Path Tracing module. This option enables more accurate motion blur with higher performance cost to get smooth results. In this mode, no post-process vector blur is applied, and denoising is applied after all spatial and temporal sample accumulation. Higher temporal samples should be applied to increase quality. Be aware of the tick resolution limitations in Sequencer when using very high temporal sample counts.



Material Shading Models



Unlit

Yes

Default Lit

Yes

Subsurface

Yes

Preintegrated Skin

Yes

Renders identically to the subsurface shading model.

Alpha Holdout

Yes

Clear Coat

Yes

Subsurface Profile

Yes

Requires a subsurface profile with Burley subsurface scattering enabled.

Two Sided Foliage

Yes

Hair

Yes

Support for this shading model is still considered experimental and has not yet been calibrated against the behavior of the Lit Shading Model.

Cloth

Yes

Eye

Yes

SingleLayerWater

Yes

Added experimental support for this shading model. Since the raster implementation is heavily dependent on post-processing, a close match is not currently possible.

Thin Translucent

Yes

From Material Expression

Yes



Material Features



Colored Shadows

Yes

Can be achieved with the Thin Translucent or solid glass. See the Glass Rendering with the Path Tracer and Color Absorption sections of this page.

Translucent Shadows

Yes

Refraction

Yes

Decals

Yes

Only planar decals are implemented at the moment. Mesh Decals are not supported.

Anisotropy

Yes



System Support



Multiple GPU

Yes

Requires a GPU that supports NVIDIA NvLink / SLI. Refer to Enabling Rendering using Multiple GPUs section of this page.

Sequencer Movie Render Queue

Yes

Orthographic Camera

Yes

Per Instance Custom Data

Yes

Per Instance Random Data

Yes

Additional Information

The Path Tracing mode works differently than some other rendering methods within Unreal Engine. This means that something that works well for real-time rendering may not work best for path-traced rendering. The following sections describe some of these inconsistencies and common issues as well as the steps you can take to improve your results with the Path Tracer.

Reducing Firefly Artifacts

The Path Tracer simulates light by randomly tracing rays according to material properties. When bright areas of the scene have a low probability of being discovered, the resulting samples can become excessively bright, creating specs of light (or fireflies) that appear and disappear within the frame. Path tracing attempts to minimize the most common sources of these effects, but they can still occur in some scenarios.



When the path-traced result is combined with bloom post processing passes, the resulting pixels can be particularly noticeable because of how they appear and disappear, or become brighter and dimmer.

The Post Process Setting Max Exposure Path controls the maximum exposure used in the rendered path-traced scene. Adjusting the exposure to be a few steps higher than the current scene exposure, set by the Post Process Max EV100 (found under the Lens > Exposure section), will reduce the chance of fireflies occurring.

Denoising Options

When rendering frames with the path tracer interactively through the viewport or with Movie Render Queue will always have a bit of noise present. One way of reducing noise is by using a denoising algorithm to stabilize the end results, producing cleaner images with less noise.

The path tracer enables denoising through the Post Process Volume settings when Denoiser is enabled under the Path Tracing section.

The denoising algorithms are implemented through plugins in the Unreal Engine from the following third-party denoising libraries:

Intel's Open Image Denoise library is a CPU-based denoiser that removes noise from the last sample taken and improves the quality of long-running frames.

NVIDIA Optix AI-Accelerated Denoiser library is a GPU-accelerated artificial intelligence trained on tens of thousands of images to reduce visual noise, while providing faster denoising times.





The OpenImageDenoise plugin is enabled by default.

This denoiser runs on the CPU and is not designed for interactive denoising, but rather to help improve the quality of long-running frames. This denoiser does not guarantee temporal consistency in all cases and may require a high number of samples per pixel for stable output. Temporal stability can be improved when using Movie Render Queue to increase the Temporal Sample Count in the Anti-Aliasing module settings.

This plugin is experimental

The OptixDenoise plugin must be enabled in the Plugins browser.

This denoiser uses GPU-accelerated artificial intelligence to reduce visual noise, while providing faster denoising times. The denoiser also contains a temporal component which tries to reduce flickering in denoised animations.

When both the OptixDenoise and OpenImageDenoise plugins are enabled for your project, you must use the console variable r.PathTracing.SpatialDenoiser.Type to choose which denoiser will be used when denoising is enabled in the Post Process Volume settings. 0 (default) uses the OpenImageDenoise plugin. Set to 1 to use the OptixDenoise plugin.

Skylighting with the Path Tracer

Skylighting is handled in two ways: using a traditional skybox with an applied sky material, or using the Real Time Capture mode of the Sky Light to capture the sky, atmosphere, and clouds in the scene.





Skybox Mesh

Sky Light Real Time Capture

Using a skybox to represent the sky requires a couple of things to be set up on the mesh and in the material for it to work well with the Path Tracer. First, the sky material must have the flag Is Sky enabled in the Material's Details panel settings. This ensures that the illumination of the skybox material won't be counted twice when the Sky Light is present in the scene. It also potentially reduces the amount of noise that can occur if the skybox were to in fact be counted twice.



In the Level, select the skybox Actor and use the Details panel to disable Cast Shadows to prevent the mesh from occluding contributions from the Sky Light and Directional Light in the scene.



Alternatively, lighting contributions from the Sky Atmosphere and Volumetric Clouds systems can be captured by enabling Real Time Capture mode on the Sky Light. Because of this limitation for capturing skyboxes, Sky Atmosphere, and Volumetric Clouds for skylighting representation, their resolutions are dependent on the Sky Light Cubemap Resolution.





Sky Light Cubemap Resolution: 128 (Default)

Sky Light Cubemap Resolution: 512

Fog and Atmosphere Volumetrics

The Path Tracer supports volumetrics from Sky Atmosphere and Exponential Height Fog components.

When Reference Atmosphere is enabled in the Post Process Volume settings, the Sky Atmosphere lighting is computed volumetrically, giving more realistic results. While in this mode, any Sky Light in the scene is automatically ignored as the sky lighting is only influenced by local and Directional Light sources. The path tracer represents the planet as a very large sphere so that the correct shadowing is present, and so that the ground color is properly reflected in the bounced lighting onto the sky from all directions.





Additional notes for using Reference Atmosphere:

To use the Sky Atmosphere as intended, adjust its Transform Mode setting to Planet Top at Component Transform, and move the component down below your scene.

Volumetric Cloud component is not yet supported. They require a Sky Light which has Real Time Capture enabled. See Sky Lighting with the Path Tracer section of this page.

Fog is supported when using an Exponential Height Fog component that has Volumetric Fog enabled.



Not all controls are supported as some of the parameters have non-physical meaning.The primary parameters supported are:

Fog Density and Fog Height Falloff

Scattering Distribution

Albedo

Extinction Scale

View Distance

Note that this used to limit the region of influence of the height fog since infinite extents can lead to long rendering times.

Direct Visibility of Light Sources

Non-punctual light sources — such as Point Lights with a source radius, Rect Lights, and Sky Lights — are not visible to direct camera rays by default. The exception to this is Sky Lights with Real Time Capture enabled.

Skylighting paired with skybox geometry and static, or specified, cubemaps are not typically seen by camera rays. This can be modified by setting the console variable r.PathTracing.VisibleLights 1.

All light sources are visible in reflections and refractions regardless of if the visible lights console variable is enabled. This ensures that they are seen by all possible ray paths. However, in some cases, this might cause unexpected behavior. For example, a Rect Light placed directly behind a glass window will be visible and will block the view through the window, which is only the case for true refraction, when the index of refraction is not equal to 1.

Glass Rendering with the Path Tracer

There are two methods of rendering glass with specified thickness with the Path Tracer: by using a few values which provide a physically accurate look based on the physical properties of the surface, or by using additional properties which allow for more control over art direction but are less physically correct. Both of these methods are acceptable and valid for use with the Path Tracer to achieve high-quality results with glass-like materials.

Achieving physically accurate results only requires a few values and parameters to be set in the material, like this example below:



Click image for full size.

In situations where more control is needed over the art direction, adjusting the Base Color can tint the glass reflection (but not the shadows), and a Fresnel plugged into the Opacity input allows the reflection falloff to be controlled more closely.



Click image for full size.

The Path Tracer uses approximate caustic paths to help reduce noise, especially in cases where a glass or metal surface has lower roughness values. For these types of materials, the reflective caustics can produce various patterns and can take up an impractical amount of time, or samples, to converge for a noise-free image.

For example, these images were taken sequentially during the rendering and sample accumulation process with the final image being the finished and denoised result.



Click image for full size.

Because caustics generally take a long time to converge to a noise-free result, the Path Tracer reduces image noise by approximating the caustics that would be present in the image using the console command r.PathTracing.ApproximateCaustics 1. This variable is enabled by default.





Another element to consider is the difference between refractive caustics and approximate casustics. By using the denoiser, it is possible to preview how the caustics would appear given enough time to converge, whereas the approximate caustics gives a production-ready image in much shorter time.

(w:900)

(w:900)

The Thin Translucency shading model is useful for achieving physically accurate results with appropriately colored translucent shadowing for thick glass with approximate caustics.



Click image for full size.

One thing to be aware of is that each interface is treated as a unique pane of glass, which means that refraction is not calculated by the shader and the object will look more like a bubble than solid geometry.





Standard Glass Material

Thin Translucent Glass Material

Click image for full size view.

Click image for full size view.

Materials with their Blend Mode set to Translucent and a non-unit Refraction parameter are rendered as solid glass. You can control the color of the transmission through the glass (also known as "Beer's law"), use the Absorption Medium material output node in the Material Graph. This feature is only available for the Path Tracer as it requires tracking the state of the ray color through multiple bounces.

This is an example of the material setup used to control absorption in the Path Tracer.



When setting a RGB color, values close to 1 will not demonstrate absorption.

The example material above use Transmittance Color to control the amount of absorption that is happening. The specified color is normalized to be reached after a distance of 100 units. To change this distance, use the following formula Transmittance Color = Color^(100/Distance).









Absorption: 0x

Absorption: 1x

Absorption: 10x

Absorption: 100x

The Unreal Engine 5 implementation of Energy Conservation is used to reduce the energy loss in the specular lob of metals and glass materials.

You can turn on Energy Conservation from the Project Settings under the Engine > Rendering > Materials section.

To preserve backwards compatibility this feature is currently disabled by default. In a future release of the engine, this feature is expected to be enabled by default.





Rough Light Transmission and Reflections

The Path Tracer is unique in that it allows for the rendering of rough transmission in addition to rough reflection — and in the case of the Path Tracer, these shader parameters are coupled together.

In the examples below, the roughness value of the glass material varies to demonstrate the approximate caustics, roughness of the reflection, and the effect it has on the translucent shadow being cast.

Drag the slider to see the glass material change from no roughness to some roughness. Roughness values are from 0 to 0.2



Useful Console Variables

The following are some useful console variables to have enabled when using the Path Tracer.

Console Variable

Description

r.PathTracing.VisibleLights

Makes all lights visible to camera rays. This is disabled by default to match the raster-based modes of the engine, but it can be useful to understand how lights are modeled and to spot cases where lights are overlapping.

r.PathTracing.ProgressDisplay

This adds a small progress bar to the view that displays progress toward the configured samples per pixel. The progress bar will automatically be hidden when accumulation is completed. It does not affect renders with Movie Render Queue and is safe to have on.

r.PathTracing.Denoiser

This option can be used to quickly toggle the denoiser on and off (assuming the current sample accumulation is complete). Unlike the Post Process Volume setting, changing this will not cause accumulation to restart and can be useful for quickly comparing the rendered frame with and without denoising enabled.

Frequently Asked Questions

Capturing a Converged Path-Traced Image using HighResShot

Use the console variable r.HighResshotDelay equal to the currently active Samples Per Pixel in your scene. A good way to validate that the correct output is being captured is to leave r.PathTracing.ProgressDisplay set to 1. If the progress bar is not present in the captured image, sample accumulation is complete.

Enabling the Path Tracer at Runtime

The Path Tracer can be used at runtime (on supported platforms). Use the console command show PathTracing to toggle the Path Tracer on and off in a game viewport. In a Blueprint, you may use Execute Console Command to perform this task.

Avoiding Timeout Delays on Windows for "D3D Device Removed Crashes"

Windows tries to maintain system responsivenss by limiting the amount of time a GPU kernal can take. For a resource intensive process, such as brute force path tracing, this limit can be hit more frequently, particularly on lower end GPUs or when light simulation becomes too complex to finish in a reasonable time.

The engine exposes a few console variables to control the amount of work performed at once, though that these variables can reduce overall performance if set incorrectly. It's recommended to keep watch on overall performance with the stat gpu command.

r.PathTracing.DispatchSize controls the maximum width and height in pixels for the path-traced render. if this value is lower than your viewport or image resolution, the render may take place in several steps, which increases the amount of times Windows can verify that the GPU is still responsive. The default is 2048.

r.PathTracing.FlushDispatch controls how frequently to flush the command list during the path tracing process. Setting this to 1 gives Windows more chances to verify the GPU is still responsive. By default, this is set to 2.

In extreme cases, it may be difficult to maintain good performance while avoiding crashes. In such cases, it is possible to change the Windows Timeout limit itself. See How to Fix a GPU Driver Crash.

For scenes containing hair, it is possible for acceleration structure (BLAS) timeouts to occur. In this case, try lowering the value of r.HairStrands.RaytracingProceduralSplits to 1 or 2.

Instances Disappearing in the Path-Traced View

The default culling implementation for Hardware Ray Tracing can be overly aggressive in the context of path tracing, since ray tracing is also used for camera visibility. If instances appear to be missing when switching to the Path Tracer view, try setting r.RayTracing.Geometry.InstancedStaticMeshes.Culling to 0.

Using Path Tracer with Nanite-Enabled Meshes

There is experimental support for native path tracing of Nanite-enabled meshes which can be enabled with r.RayTracing.Nanite.Mode 1. This mode uses the Nanite streaming system to prepare ray-traced meshes on-the-fly, preserving much more detail than is possible for Fallback Meshes.

The path tracer also supports the Nanite-enabled meshes Fallback Mesh for representation. The Fallback Mesh uses a percentage of the source mesh's triangles for representation but leads to Nanite-enabled meshes having lower detail in the scene. Increase the Fallback Mesh's detail in the Static Mesh Editor by adjusting the Fallback Triangle Percent and Fallback Relative Error parameters.

For more information on configuring these settings, see the "Fallback Mesh" section of the Nanite documentation.

Enabling Support for Multiple GPUs

Requires Windows 10 version 2004 or newer to use multiple GPUs.

Computing lighting with multiple GPUs (mGPU) is supported through NVIDIA's Scalable Link Interface (SLI) technology that links multiple NVIDIA GPUs together. This improves the amount of processing power that is needed to render scenes using core Hardware Ray Tracing features, such as the Path Tracer and GPU Lightmass.

Enable support for multiple GPU configurations by:

Connecting GPUs with NVLink bridges and enabling SLI in the NVIDIA Control Panel.

Pass the command line argument -MaxGPUCount=N, where N is the number of GPUs available. For example, -MaxGPUCount=2.

With the editor open, use the console variable r.PathTracing.MultiGPU 1 to enable multi-GPU support. You can also add this console variable to your DefaultEngine.ini file located in [Unreal Engine Root]/Engine/Config under the [/Script/Engine.RendererSettings].

Once the editor opens, you can check the Output Log to confirm that multi-GPU mode has been enabled. Look for LogD3D12RHI: Enabling multi-GPU with 2 nodes.

Post Process Volume

Types of Lights

Directional Light

Point and Spot Lights

Rect Light

Sky Light

Actors

Materials

This page contains reference for properties and settings of the features of Real-Time Ray Tracing and the Path Tracer.

Post Process Volume

The following features of Ray Tracing and the Path Tracer are found in the Post Process Volume settings.

Property

Description



Global Illumination



Method

Chose what global illumination method to use: None, Lumen, Screen Space, or Ray Traced.



Ray Tracing Global Illumination



Type

Sets what Ray Tracing Global Illumination method to use:

Disabled: Disables RTGI methods.

Brute Force: Uses the slower, more accurate brute force method for dynamic indirect lighting using RTGI.

Final Gather: Uses a faster, less accurate final gather method for dynamic indirect lighting using RTGI.

For more information, see the Ray Traced Global Illumination section of the Real-Time Ray Tracing page.

Max Bounces

Sets the maximum number of bounces of light that will be used by RTGI.

Samples Per Pixel

Sets the number of samples to use per pixel for RTGI. Additional samples decrease performance while increasing quality and accuracy. Set to 1 sample per pixel by default.



Reflections



Method

Sets what method of dynamic scene reflections to use: None, Lumen, Screen Space, or Ray Traced.



Ray Tracing Reflections



Max Roughness

Sets the maximum roughness value that Ray Traced Reflections will be visible before falling back to raster methods that are less expensive. Reflection contribution is smoothly faded when close to the roughness threshold and this parameter behaves similarly to SSR's Max Roughness setting. Lower values fall back to other methods more quickly.

Max Bounces

Sets the maximum number of bounces that Ray Traced Reflections uses. More bounces create inter-reflection but comes at a higher cost. Set to 1 bounce by default.

Samples Per Pixel

Sets the number of samples to use per pixel for Ray Traced Reflections. Additional samples decrease performance while increasing quality and accuracy. Set to 1 sample per pixel by default.

Shadows

Sets how shadows should be reflected. Choose between:

Hard Shadows which has no soft shadows

Area Shadows to have soft shadowing like raytraced shadows

Disable to disable shadowing in Ray Traced Reflections

Include Translucent Objects

When the checkbox is checked, this sets whether translucent materials will be included in Ray Tracing Reflections.



Ray Tracing Ambient Occlusion



Enabled

When the checkbox is checked, it enables Ray Tracing Ambient Occlusion (RTAO).

Samples Per Pixel

Sets the number of samples to use per pixel for Ray Traced Ambient Occlusion (RTAO). Additional samples decrease performance while increasing quality and accuracy. Set to 1 sample per pixel by default.

Intensity

Defines how much ambient occlusion affects non-direct lighting for Ray Traced Ambient Occlusion. Lower values decrease the effect while higher values increase how strong the effect is.

Radius

Controls the distance in Unreal Units that ambient occlusion affects.



Translucency



Type

Sets whether to use Ray Tracing or Raster method for reflections within this volume. When selecting Raster, default translucency methods will be used instead of ray traced ones.



Ray Tracing Translucency



Max Roughness

Sets the maximum roughness value that Ray Traced Translucency will be visible before falling back to raster methods that are less expensive. Translucency contribution is smoothly faded when close to the roughness threshold and this parameter behaves similarly to SSR's Max Roughness setting. Lower values fall back to other methods more quickly.

Max Refraction Rays

Sets the maximum number of refraction rays that Ray Traced Translucency uses. Additional Samples decrease performance while increasing quality and accuracy. Set to 3 refraction rays by default.

Samples Per Pixel

Sets the number of samples to use per pixel for Ray Traced Translucency. Additional samples decrease performance while increasing quality and accuracy. Set to 1 sample per pixel by default.

Shadows

Sets how shadows should be reflected. Choose between:

Hard Shadows which has no soft shadows

Area Shadows to have soft shadowing like raytraced shadows

Disable to disable shadowing in Ray Traced Translucency

Refraction

Sets whether refraction should be enabled or not for Ray Traced Translucency. If disabled, rays will not scatter and only travel in the same direction as before the intersection event.



Path Tracing



Max. Bounces

Sets the maximum possible number of light bounces rays should travel before being terminated.

Samples Per Pixel

Sets the number of samples used per pixel for convergence. A higher number of samples reduces noise of the rendered image.

Filter Width

Improves quality of the rendered image by setting the filter width used by anti-aliasing. Lower widths yeild sharper (or more aliased) results. Larger values soften (or blur) aliasing results.

Emissive Materials

Enables bounce lighting for emissive materials. Enabling this property prevents double-counting illumination of surfaces that are also represented by actual light sources, and noise from small emitters. For example, having an emissive material representing a small light bulb while also using a point or spot light source to illuminate the area would be double-counted in this case.

Max Path Exposure

Sets the maximum exposure allowed for path tracing in order to reduce firefly artifacts from occurring. Adjusting the exposure to a higher value than the scene's exposure helps mitigate these artifacts. (See Additional Information section of this page for more details and an example of this type of artifact).

Denoiser

This toggle uses the currently loaded denoiser plugin on the last sample to remove noise from the rendered output. By default, Intel's Open Image Denoiser plugin is used by the Unreal Engine. This toggle has no effect on the rendered output if the denoiser plugin is not enabled.

Types of Lights

Unreal Engine includes different types of lights which have their own settings that work specifically with ray tracing and path tracing.

Directional Light

The following properties of Directional Lights affect real-time ray tracing and path tracing. Properties are located in the Light and Ray Tracing categories of the Details panel.

Property

Description



Light



Source Angle

The angle subtended by light source in degrees (also known as angular diameter). Lower angles give sharper shadow contacts whereas higher degree angles give softer shadows.

Cast Ray Traced Shadow

Sets whether shadows from this light are computed with traditional shadow maps or ray-traced. When selecting Use Project Setting, the light will default to whether ray traced shadows is enabled or disabled in the Project Settings under Engine > Rendering > Hardware Ray Tracing with the property Ray Traced Shadows.

Affect Ray Tracing Reflections

Whether the light affects objects in reflections when Ray Traced Reflections is enabled.

Affect Ray Tracing Global Illumination

Whether the light contributes to ray traced global illumination when Ray Tracing Global Illumination is enabled.



Ray Tracing



Shadow Source Angle Factor

Adds a scaling factor to the shadow source angle relative to what is specified by Light Source Angle. This property requires that Cast Ray Traced Shadow be enabled.

Samples Per Pixel

Sets the number of samples to use per pixel for Ray Traced Shadows from a Directional Light. Additional samples decrease performance while increasing quality and accuracy. Set to 1 sample per pixel by default.

Point and Spot Lights

The following properties of Point Lights and Spot Lights affect real-time ray tracing and path tracing. Properties are located in the Light and Ray Tracing categories of the Details panel.

Property

Description



Light



Source Radius

The radius of the light sources shape. A smaller radius gives sharper shadow contacts whereas a higher radius gives softer shadows.

Cast Ray Traced Shadow

Sets whether shadows from this light are computed with traditional shadow maps or ray-traced. When selecting Use Project Setting, the light will default to whether ray traced shadows is enabled or disabled in the Project Settings under Engine > Rendering > Hardware Ray Tracing with the property Ray Traced Shadows.

Affect Ray Tracing Reflections

Whether the light affects objects in reflections when Ray Traced Reflections is enabled.

Affect Ray Tracing Global Illumination

Whether the light contributes to ray traced global illumination when Ray Tracing Global Illumination is enabled.



Ray Tracing



Samples Per Pixel

Sets the number of samples to use per pixel for Ray Traced Shadows from Point and Spot Lights. Additional samples decrease performance while increasing quality and accuracy. Set to 1 sample per pixel by default.

Rect Light

The following properties of Rect Lights affect real-time ray tracing and path tracing. Properties are located in the Light and Ray Tracing categories of the Details panel.

Property

Description



Light



Source Width

The width of the light source shape.

Source Height

The height of the light source shape.

Barn Door Angle

The angle of the winged doors at the edge of the Rect Light's shape. The angle controls the forward direction and spread of the light.

Barn Door Length

The length of the winged door at the edge of the Rect Light's shape. The length controls the sharpness of the light source's edge, similar to how Source Radius works with Point Lights and Spot Lights.

Cast Ray Traced Shadow

Sets whether shadows from this light are computed with traditional shadow maps or ray-traced. When selecting Use Project Setting, the light will default to whether ray traced shadows is enabled or disabled in the Project Settings under Engine > Rendering > Hardware Ray Tracing with the property Ray Traced Shadows.

Affect Ray Tracing Reflections

Whether the light affects objects in reflections when Ray Traced Reflections is enabled.

Affect Ray Tracing Global Illumination

Whether the light contributes to ray traced global illumination when Ray Tracing Global Illumination is enabled.



Ray Tracing



Samples Per Pixel

Sets the number of samples to use per pixel for Ray Traced Shadows from a Rect Light. Additional samples decrease performance while increasing quality and accuracy. Set to 1 sample per pixel by default.

Sky Light

The following properties of Sky Lights affect real-time ray tracing and path tracing. Properties are located in the Light and Ray Tracing categories of the Details panel.

Property

Description



Light



Cast Ray Traced Shadow

Sets whether shadows from this light are computed with traditional shadow maps or ray-traced. When selecting Use Project Setting, the light will default to whether ray traced shadows is enabled or disabled in the Project Settings under Engine > Rendering > Hardware Ray Tracing with the property Ray Traced Shadows.

Affect Ray Tracing Reflections

Whether the light affects objects in reflections when Ray Traced Reflections is enabled.

Affect Ray Tracing Global Illumination

Whether the light contributes to ray traced global illumination when Ray Tracing Global Illumination is enabled.



Ray Tracing



Samples Per Pixel

Sets the number of samples to use per pixel for Ray Traced Shadows from a Sky Light. Additional samples decrease performance while increasing quality and accuracy. Set to 1 sample per pixel by default.

Actors

The following properties of placed Actors affect real-time ray tracing and path tracing. Properties are located in the Rendering and Ray Tracing categories of the Details panel.

Property

Description



Rendering: Advanced



Visible in Ray Tracing

When enabled, this component will be visible in ray tracing effects. When disabled, it will be removed from ray tracing effects like reflections, translucency, shadows, and more.



Ray Tracing: Advanced



Evaluate World Position Offset

When enabled, this Actor will be evaluated for ray tracing effects for any assigned Materials that make use of World Position Offset.

Ray Tracing Far Field

If true, this component is available to be ray traced as a far field primitive, even if it is hidden.

Ray Tracing Group Id

Defines the runtime groups of components. For example, it allows assembly of multiple parts of a building at runtime. When set to -1, the component doesn't belong to any group.

Ray Tracing Group Culling Priority

Defines how quickly this Actor should be culled. For example, buildings and larger objects should have a low priority, but smaller objects should have a higher priority so that they are culled sooner.

Materials

The following properties of Materials affect real-time ray tracing and path tracing. Properties are located in the Details panel of the Material Editor.

Property

Description



Material



Cast Ray Traced Shadows

Set whether this Material should allow its assigned Actor to cast ray traced shadows when Ray Tracing features are enabled. Requires that the Light Source casting shadows to have Cast Ray Traced Shadows enabled.

Overview of Ray Tracing Costs

Bottom Level Acceleration Structure Updates

World Position Offset on Static Mesh Components

Top Level Acceleration Structure Build

Culling

Ray Traversal Cost

Ray Traversal Debug Visualization Modes

Performance Debug Visualization

Traversal Debug Visualization

Hit Shading Costs

Far Field

Additional Ray Tracing Debug Visualization Modes

Picker Debug Visualization Mode

Dynamic Instances Debug Visualization Mode

For projects that need to maintain a real-time performance budget, it's important to set a frame budget in order to achieve that target frame rate. Typically, that would be 30 or 60 frames per second (FPS). There are many opportunities for optimizing and improving performance of your projects by making adjustments to content or workflows.

This guide covers some starting points for optimizing Ray Tracing features of Unreal Engine and ways you can pin-point trouble areas through debugging the scene and investigating those issues.

Overview of Ray Tracing Costs

Hardware Ray Tracing uses a two-level Bounding Volume Hierarchy (BVH) to accelerate ray traversal. The Top Level Acceleration Structure (TLAS) contains all mesh instances for the whole scene. The meshes referenced by those instances are Bottom Level Acceleration Structures (BLAS).

The diagram below gives a visual representation of how the BVH works for ray traversal.



There are three main categories of costs associated with Ray Tracing:

Building the Bottom Level Acceleration Structures for dynamically deforming meshes, like skinned meshes and hair.

Building the Top Level Acceleration Structure for the scene and the Shader Binding Table (SBT).

Ray traversal for each feature that uses Ray Tracing.

For development of your project, you can test the ray tracing cost of specific types of geometry with console variables. This is useful for measuring their costs or disabling them entirely for Ray Tracing features. You'll find them listed under r.RayTracing.Geometry.*.

Geometry Type

Console Variable

Default State

Static Meshes

r.RayTracing.Geometry.StaticMeshes

Enabled

Skeletal Meshes

r.RayTracing.Geometry.SkeletalMeshes

Enabled

Instanced Static Meshes

r.RayTracing.Geometry.InstancedStaticMeshes

Enabled

Landscape Terrain

r.RayTracing.Geometry.Landscape

Enabled

Geometry Cache

r.RayTracing.Geometry.GeometryCache

Enabled

Geometry Collection

r.RayTracing.Geometry.GeometryCollection

Disabled

Niagara Meshes

r.RayTracing.Geometry.NiagaraMeshes

Enabled

Niagara Ribbons

r.RayTracing.Geometry.NiagaraRibbons

Enabled

Niagara Sprites

r.RayTracing.Geometry.NiagaraSprites

Enabled

Procedural Meshes

r.RayTracing.Geometry.ProceduralMeshes

Enabled

Bottom Level Acceleration Structure Updates

While the BLAS for Static Meshes are only built once at load (or during the cook on consoles), dynamically deforming meshes have to rebuild every frame and this can incur significant cost. The BLAS rebuilds are a GPU operation, and are typically proportional to the total number of triangles being deformed. Using a large number of Skeletal Meshes with a large number of triangles can quickly become a major GPU cost.

BLAS rebuild costs can be observed in the GPU Profiler under the following areas:

Scene > CommitRayTracingGeometryUpdates

Scene > CommitHairRayTracingGeometryUpdates

Scene > RayTracingGeometry

Geometry types which rebuild every frame include:

Skinned meshes through GPUSkinCache

Landscape is rebuilt to support its continuously morphing level of detail (LOD)

Geometry Collections for Chaos Destruction

Hair

Procedural Mesh

Niagara Particle Systems

High polygon Skeletal Meshes are the most common cause of high BLAS build costs. Skeletal Meshes can use the property Ray Tracing Min LOD found in the Skeletal Mesh Editor, which prevents the highest LODs from being used for Ray Tracing features.

Use the console command D3D12.DumpRayTracingGeometries when running a project with D3D12 to get a list of all the memory allocations for dynamic BLAS rebuilds dumped to the log. This list can be used to optimize your project.

World Position Offset on Static Mesh Components

World Position Offset (WPO) is challenging to support efficiently with Ray Tracing features because it requires dynamically rebuilding the BLAS, as well as unique memory for each instance.

By default, Unreal Engine ignores WPO when building Ray Tracing Scene, which can cause self-intersections artifacts. Static Mesh Components can opt-in to using WPO with ray tracing with the Evaluate World Position Offset setting. However, it only works for a short distance around the camera, 50 meters unless otherwise specified.

Use the following to enable and adjust the supported WPO distance from the camera:

r.RayTracing.Geometry.StaticMeshes.WPO 1

r.RayTracing.Geometry.StaticMeshes.WPO.CullingRadius 5000.0f

The dynamic BLAS builds caused by WPO show up in the GPU profiler under Scene > RayTracingGeometry > RayTracingDynamicGeometryUpdate.

Instanced components, like Instanced Static Mesh Component, do not support WPO by default because of its extreme cost. Components that have a Evaluate World Position Offset toggle do not enable it by default. Toggling it on can significantly increase memory pressure and slow render times because it effectively converts every instance in a single mesh with a separate BLAS.

Top Level Acceleration Structure Build

The Top Level Acceleration Structure is rebuilt every frame, and has a cost on the Rendering Thread, RHI Thread, and the GPU. These costs are mostly proportional to how many mesh instances go into the acceleration structure.

Using the stat command Stat SceneRendering, you will find the number of instances being rebuilt every frame under Ray tracing instances.



To measure the cost of the Rendering Thread, use the command Stat SceneRendering and look for the GatherRayTracingWorldInstances.



To measure the cost of the RHI Thread, you can use per-RHI stats, such as Stat D3D12RayTracing.



GPU cost can be measured with the stat command Stat GPU. Look at entries for RayTracingScene and RayTracing to get an idea of their costs.



In order to achieve a 30 frames per second target on next generation consoles, scenes should generally have 100,000 instances or fewer in the Ray Tracing Scene after culling. On Windows, the number of instances can vary significantly.

Culling

Scenes with ray tracing require objects outside of the camera view to be present in the scene, especially for highly reflective surfaces. This increases the cost of rendering the scene. Culling objects that aren't visible or needed helps with optimizing performance.

Since ray tracing needs to keep objects visible, even when they aren't in view, the console variable r.RayTracing.Culling provides some options to help optimize what is visible outside of the current view and over what distance.

The following options are provided:

1 culls objects behind the camera by distance and solid angle (default ray tracing culling method).

2 culls objects in front of and behind the camera by distance and solid angle.

3 culls objects in front and behind the camera by distance or solid angle.

Each culling option progressively culls more objects in the ray tracing scene.

Because the TLAS is rebuilt every frame, mesh instances can be culled based on their distance or angle to the camera when setting option 3.

Additionally, the Radius and Angle that the Ray Tracing Culling option uses can be configured on their on using the following console commands:

r.RayTracing.Culling.Radius: Sets a distance around the camera beyond which objects are culled. Default radius is 10000 (100 meters).

r.Raytracing.Culling.Angle: Culls meshes whose projected angle is smaller than 5 degrees. The default is 1.

For an open world project, such as City Sample, the culling Radius was increased to 15000 (150 meters), while the culling Angle was reduced to 0.5 (2.5 degrees) in account for large areas with lots of reflective surfaces that needed objects to be visible over farther distances.

Culling causes a lack of coverage in the Ray Tracing Scene and is best paired with the Far Field to provide traces for distant geometry.

Mesh components tagged with a Ray Tracing Group Id greater than 0 can be culled as an aggregate using r.RayTracing.Culling.UserGroupIds 1. This method can be useful if your scene is built out of many disparate parts, but you'd like to cull them as a single object.



Ray Tracing Group Id property found on a selected Actor in a Level.

Ray Traversal Cost

Ray queries are spawned by features which use Hardware Ray Tracing, such as Ray Tracing Shadows, Lumen Global Illumination, and Lumen Reflections. GPUs solve these Ray queries with dedicated hardware that traverses the acceleration structures to find a hit.

An example of ray traversal costs in the Profile GPU log output would be:

The cost of ray traversal is proportional to the number of Ray queries issued by the lighting feature, and the amount of mesh overlap in the scene.

When meshes overlap, the ray must traverse them all independently to find the closest hit, because Ray Tracing uses a two-level acceleration structure. The mesh overlap can cause extremely slow ray traversal in scenes built by piecing different assets together as needed (also called kitbashing).



Example of kitbashed assets used to layer rocks in the Unreal Engine 5 "Valley of the Ancients" technical demo.

In order for scenes to be compatible with Hardware Ray Tracing, mesh overlap must be kept to a minimum.

There are other common causes of high ray traversal costs, the first being skyboxes — they overlap the entire scene and must be traversed by every ray, even if they are not hit. Another is grass — it has large bounds and high geometry complexity.

In these cases (or any others that are similar), you can choose to have those ray tracing tracing skip those meshes. Select the Actors in the world and use their Details panel to disable Visible in Ray Tracing.

Ray Traversal Debug Visualization Modes

The following debug modes are currently only available on console platforms.

There are two debug modes that are useful for investigating high traversal costs: Performance and Traversal.

To enable these modes, you'll use the following commands:

"[Mode]" is replaced by the visualization method you want to see: Performance or Traversal Node. For example, it would be r.RayTracing.DebugVisualizationMode Traversal Node.

Performance Debug Visualization

Performance debug visualization shows a heatmap of the TraceRay call, showing the combined time of BVH traversal and material evaluation time (executing Closest Hit/Miss shaders).



Ray Tracing Performance debug visualization.

The colors of the visualization go from purple (no cost) to yellow (high cost). The heatmaps scale can be adjusted to fit your project's needs using r.RayTracing.DebugTiming Scale.

This mode is most useful to find problematic objects and materials for Ray Tracing. If Ray Tracing cost is too high, it is a good idea to check if what's showing in that mode looks reasonable.

For example, the objects visible in the main view are also present in debug mode, no undesired objects are present and the material cost looks as expected for those objects. If there is nothing that stands out, it might be because the slow down is not caused by one single object but the combination of different smaller issues.

Traversal Debug Visualization

The Traversal debug visualization shows a heatmap of only BVH traversal — how many iterations it takes to find a hit. For Lumen passes that don't use materials or similar passes that use simple hit shading/inline, the highest cost is usually the BVH traversal.

The colors of the heatmap goes from green (few iterations) to red (many iterations). Intuitively, the more iterations that happen, the slower the traversal. The values are in the range of 50-100 iterations for a typical scene. For a complicated scene, including multiple overlapping high polygon meshes, there are around 100-150 iterations.

Anything above that suggests there might be a problem, for example, it would not be uncommon for a broken mesh to see 1000+ iterations. The Traversal Triangle debug visualization is useful for checking individual meshes triangles.

For Traversal debugging, there are three modes to select from:

Traversal Debug mode

Command Name

Description

Visualization View

Node Intersection Count

Traversal Node

Used to investigate scene traversal costs. For example, when many instances are overlapping in TLAS.

These are BVH nodes in the internal, platform-specific representations of BLAS.





Triangle Intersection Count

Traversal Triangle

Shows the hits of nodes that contain only triangles (leaf nodes).



Total Intersection Count

Traversal All

Sum of BVH node hits and triangle node hits.



Hit Shading Costs

When a ray hits a triangle, the material is evaluated and used for shading the hit point. For complex materials using procedural texturing and many virtual textures, this can be a very expensive process.

The Ray Tracing Quality Switch node is an expression that can be used in your Materials to provide a cheaper implementation for shading ray hits.



The node can replace entire parts of your Material logic to lower the overall cost of Ray Tracing features. Using this node affects all ray tracing effects for this material.

A simple example (see below) would be a material that includes logic that is costly for ray tracing effects. The RayTracingQualitySwitch node includes two inputs: Normal and RayTraced.

The Normal input contains all the logic needed for the material and is how it would appear on surfaces in the world. The RayTraced input should have less complexity in the logic path that increases the cost of ray tracing effects, like the Normal map.



Click image for full size.

Far Field

Ray Tracing supports a Far Field representation that extends Lumen Global Illumination and Reflections to one kilometer from the camera by default. The Far Field makes use of Hierarchical Level of Detail (HLOD) meshes generated by World Partition by default. The HLOD1 mesh is used for Far Field representation.

Currently, only Lumen lighting features make use of Ray Tracing Far Field, and only when enabled for the project with the command r.LumenScene.FarFields 1.

On selected meshes that should be visible to the Far Field, toggle the Ray Tracing Far Field setting.



In the editor, the Far Field can be visualized using the ray tracing debug visualization mode for FarField. Enter the following commands:

In the visualization below, the far-field is the tinted red geometry using the HLOD1 meshes generated by World Partition. Anything closer to the camera is the high-detail geometry.



Lumen's Ray Tracing Far Field debug visualization. Far-field geometry is tinted red.

Additional Ray Tracing Debug Visualization Modes

The Ray Tracing Debug visualization modes enable you to gather information about the ray tracing scene.

You can access these visualization modes from the Level Viewport using the View Modes dropdown selection, or by entering the console command r.RayTracing.DebugVisualizationMode followed by the name of the visualization mode.



Picker Debug Visualization Mode

The Picker debug visualization mode displays information about the ray-tracing geometry and the instance under the cursor. The Picker mode can operate on two different domains: Triangles and Instances.

You can swap between these modes using the console command r.RayTracing.Debug.PickerDomain followed by 0 for Triangles (default) or 1 for Instances.





Triangles Debug Picker Domain

Instance Debug Picker Domain

Click image for full size.

Click image for full size.

On the left side of the viewport, information about the ray-tracing geometry is displayed along with which Picker Domain is currently being used.



Dynamic Instances Debug Visualization Mode

The Dynamic Instance debug visualization mode shows dynamic instances within the ray-tracing scene. Every frame, dynamic instances are rebuilt and show as either Red for static instances or Green for dynamic instances.



In order to understand and use the content on this page, make sure you are familiar with the following topics:

Sequencer Overview

Movie Render Queue

Objective

Step 1. Project Setup

System Configuration (Optional but Recommended)

Download the Sample Project

Enable the Movie Render Pipeline Plugin

Step 2: Load a Project Sequence into the Sequencer Editor

The Sequencer Editor

Step 3: Add a Sequence to the Movie Render Queue

Step 4: How to Select Configuration Options

Output Settings Explained

Rendering Settings Explained

Additional Settings Explained

Step 5: Select Your Options

Step 6: Configure the Anti-Aliasing Settings

Step 7: Configure the Console Variables

Step 8. Configure the Output

Step 9: Save Your Configuration Settings

Step 10: Final Output and Results

Troubleshoot the Render

Disable GPU Timeout

On Your Own!

Rendering Locally versus Remotely

Temporal Sampling and Denoisers

Additional Ray-Tracing Console Commands

This guide is for Windows 10 64-bit users.

When the objective is to achieve a quality render offline, you do not have to be concerned with the cost of real-time rendering. This provides an opportunity to use settings and commands that greatly increase the quality, precision, and look for features like Ray-Tracing Global Illumination and Ray-Tracing Reflections. You can also get improved Motion Blur, and remove unwanted anti-aliasing artifacts.

The guide will take you through some of the settings you can use to produce a high-quality render outside of real-time concerns. You will learn to use the Movie Render Queue to configure a sample sequence using custom settings and console variables.

For a sense of what a full, high-quality render would look like, watch this video:

This guide follows a process similar to the one used to generate the video above. The primary difference is that you will be using Movie Render Queue instead of the Blueprint Director.

Objective

After going through this guide, you will have a better understanding of how to:

Get Sequencer ready for use with Movie Render Queue

Output high-quality image sequences

Tweak output settings for improved images when rendering images that use ray tracing

Apply your own custom settings using console variables

For best results, go through the steps below in sequence.

Step 1. Project Setup

Before starting, you will need to change a system setting, download the sample project that goes with this guide, and enable the Movie Render Pipeline plugin.

System Configuration (Optional but Recommended)

When GPU commands take too long to execute, Windows will assume that the graphics card has crashed, and will reset the driver, which in turn will cause the engine to close.

Increasing the amount of time it takes before Windows detects a GPU Timeout can be done by changing the Timeout Detection and Recovery (TDR) time in the Windows Registry.

You will need admin rights on your computer to make these edits.

To edit the TDR (before loading the sample project):

Using the Windows Start menu search bar, enter regedit to launch the Registry Editor.

Navigate to the category Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers.

Select TdrDelay from the list, then right-click and select Modify.



This value is measured in seconds. Select Decimal, set a Value data of 60, then click OK.

Additional information on TDR can be found in the Microsoft Timeout Detection and Recovery (TDR) Registry Keys documentation.

Download the Sample Project

This guide uses ArchViz Interior as the sample project to generate the final image sequence that is rendered out at the end. The project provides a photorealistic scene that uses ray-tracing features, such as shadows, ambient occlusion,and global illumination.

Open Epic Games Launcher. Click Unreal Engine from the options on the left, then select the Learn tab on the top.



Scroll down to the Engine Feature Samples section, then select ArchViz Interior. When the CONTENT DETAIL window opens, click Free to download the project, then click Create Project. For this guide, leave the project name as ArchVizInterior.

Browse to select the download location or accept the default.

The project requires a ray tracing-compatible card with DirectX 12 ray-tracing support. For more information on ray tracing system requirements, see Real-Time Ray Tracing.

To learn more about the Archviz Interior project and how it was developed, see Archviz Interior Rendering.

Enable the Movie Render Pipeline Plugin

Before you can use the Movie Render Queue, the Movie Render Pipeline plugin must be enabled.

With the ArchViz Project downloaded and open in the engine, go to Edit > Plugins.

Select Built-In if not already selected, then search for movie. Movie Render Pipeline should appear.



If not enabled already, check the Enabled box to activate the plugin, then close the window.

Step 2: Load a Project Sequence into the Sequencer Editor

In this step, you will work with a cinematic sequence, or cinematic for short, that has been set up in the Archviz Interior project.

If you are not already familiar with the Sequencer and Movie Render Queue features, you might find it helpful to explore the prerequisite documents listed at the top of this page.

With the Archviz Interior project open, locate the level sequences in Content Browser. For this project, all level sequences are in the Content > Cinematic folder.



Double-click the archviz_cine_MASTER sequence to open it in the Sequencer Editor. It should look similar to the image below.



This master sequence contains all of the individual shots used in this sample project.

Another way to access a master sequence is from the Level Editor. Click the Cinematics dropdown to select and access any existing master sequence in an open project.

The Sequencer Editor

The Sequence Editor provides an effective way to visually examine established shots, which can help you decide a frame range to render when using the Movie Render Queue.

For this exercise, the frame range will be specified, but later, you will probably want to select your own range of frames for rendering. If you are new to the Sequencer Editor, familiarize yourself with the features described below. Otherwise, go directly to Step 3: Add a Sequence to the Movie Render Queue.

The Shots Track contains information for all cameras used in the cinematic. In this cinematic, each shot contains the camera that will be used when rendering. Click the dropdowns on the left to view any nested tracks.



Clicking the Camera button for any camera in the panel will snap the Level viewport to the perspective of that camera.



Use the playback control panel or the slider to scrub the timeline and view shots and frame ranges. Note that the slider shows the current frame number.



With the Sequencer open, from the Level Editor, select Perspective > Cinematic Viewport.



This opens a playback control panel in the viewport, with additional information on the cinematic.



Step 3: Add a Sequence to the Movie Render Queue

Next, you will add a sequence to the Movie Render Queue. This is the sequence from which you will render a high-quality set of images.

If you are accustomed to the movie rendering workflow in Sequencer, note that the Movie Render Queue has a very different access path and user interface.

From the editor menu bar, select Window > Cinematics > Movie Render Queue.



When first opened, the window should be empty, like the image below.



Click the + Render button, then click the archviz_cine_MASTER Level Sequence file from the dropdown list to add it to the queue.



You can also add a sequence to the queue by dragging the sequence into the queue window from the Content Browser.



To remove a sequence, use any of the following:

Select the sequence, then click the – button.



Highlight and press the Del key on your keyboard.

Right-click the sequence, then click Delete.

To highlight multiple sequences, hold the Shift key and click to select. You can then delete multiple sequences at the same time.

Step 4: How to Select Configuration Options

Before rendering any sequences loaded in the queue, you will need to configure the settings you want to use. There are a wide variety of settings that can be adjusted, such as output format, filename, and anti-aliasing settings.

The first step is to select the settings you will want to configure.

With the window open and the master sequence on the list, click Unsaved Config*.



This will open the Setting/Presets window.



This window is where you will make configuration changes, but first you need to pick the settings you want to configure. To add a setting, click the + Setting button and a list of options will open.



Options are in three groupings: Settings, Rendering, and Output (described in more detail below).

To move one of these options from this list to the Setting/Presets window, click the entry in the dropdown. When you add an item to the window, it is removed from this list.

Repeat steps 3 and 4 to add more options to the list.

Each option that you add to the Setting/Presets window has a toggle switch. Use these toggles to enable or disable the option for the rendering process. This will turn the setting off for that render only, without removing the option completely from these presets.



To remove an item from the Setting/Presets window, highlight the item, then press the Del key. It will be removed from the Setting/Presets window, and added back to the list of options.

Output Settings Explained



There are several image types that you can use for output. Each has its own pros and cons, so you'll need to find what fits best with your own project workflow.

One consideration is whether a file type provides an alpha channel—important if you need an image with a transparent background.

Another consideration is whether the format is lossless or lossy. Lossless compression means that all original image data can be recovered when a file is uncompressed, whereas lossy compression does not recover all original data.

Output Type

Alpha Channel

Lossy or Lossless

Notes

.bmp Sequence [8bit]

No

Lossless

Quick to write to disk but large file sizes due to their uncompressed nature.

.jpg Sequence [8bit]

No

Lossy

Smaller file size makes this format good for previews.

.png Sequence [8bit]

Yes

Lossless

Larger file size, but higher quality image.

.exr Sequence [16bit]

Yes

Lossless

A high-dynamic range format developed by Industrial Light and Magic and used in video compositing.

.wav Audio

N/A

N/A

For audio output.

More information about image types can be found in the Movie Render Queue Export Formats Guide.

Both .png and .exr image formats offer the ability to output the alpha channel with the image, but first you will need to enable this support. From the editor menu bar, select Edit > Project Settings > Engine > Rendering > Postprocessing > Enable alpha channel support in post processing (experimental) > Linear color space only.

Once this change is applied, you will be prompted to restart the engine. To create a transparent background, you will need to hide opaque objects in your scene such as Sky and Atmospheric Fog.

You can select more than one output format, but for this exercise, we will only use one.

Rendering Settings Explained



You have two possible settings for rendering. These specify how the final image will output.

Render Type

Description

Deferred Rendering

The default option. Toggling Deferred Rendering off disables the final frame render but does not stop the queue from processing the other steps in the configuration settings. It should be enabled while following the steps in this guide.

UI Renderer (Non-Composited)

Provides flexibility by rendering UMG widgets into a separate .png or .exr file that can be composited with the frame render in a separate compositing application, such as Adobe Premiere or Final Cut Pro—useful when compositing interface-related graphics.

Additional Settings Explained



With the Settings options, you can specify additional configurable items to use when rendering the final output image.

Setting Type

Description

Anti-aliasing

Controls the number of samples and sample types used when rendering out the final images.

Burn In

An overlay with information such as the name of the scene or shot, or the date, time, or frame information. These overlays are referred to as Burn Ins as they are burned into the movie when it is rendered out. Can be replaced with a custom widget if needed.

Camera

Can be used to control shutter settings, which affects effects like motion blur and exposure.

Console Variables

Calls console variables to execute specifically when rendering from the Movie Render Queue.

Game Overrides

Overrides several common game-related settings, such as Game Mode and Cinematic Quality settings. This is useful if the normal mode of the game displays UI elements or loading screens that you do not want to capture.

High Resolution

Provides a way to use tiled renders to produce larger images than would normally be possible because of maximum texture sizes or memory limits on GPUs.

You will only use a couple of these in this exercise, but you can (and should) explore all options later on your own.

For more information on these settings, see the Movie Render Queue Image Settings Guide.

Step 5: Select Your Options

Add the following options to the Setting/Presets window:

.png Sequence [8bit]

Deferred Rendering

Anti-Aliasing

Console Variables

Another option, Output, will also be on the list under Settings. This is the only option that cannot be deleted.



This is what your Setting/Presets window should look like at this point.

Step 6: Configure the Anti-Aliasing Settings

Anti-aliasing is a way of smoothing lines and removing visual distortions. Spatial sampling and temporal sampling each use different approaches to address anti-aliasing and noise-related issues.

Spatial samples work by rendering the same moment in time but with slightly different camera position offsets, and with no amount of time passing between two different spatial samples while accumulating samples from different offset positions.

Temporal samples work by slicing the camera shutter open time into specified sub-frames, and using engine motion blur to interpolate between the smaller slices. It is particularly suitable for increasing motion blur quality.

For more on the distinctions between temporal and spatial sampling, and guidelines on when to use one method over the other, see the Anti-Aliasing Movie Render Queue Settings.

The values used in this guide are a combination of both methods.

This guide was developed using an RTX-2080 Ti graphics card. Depending on your own setup, you may need to lower some values here to produce a final frame render, or, if you are using a higher-end card, like a Quadro RTX, you can push the sample count higher.

From the Movie Render Queue window, click the Unsaved Config* link to open the settings. (The * indicates that these settings have not yet been saved. You will save the presets once all settings have been entered.)

On the Setting/Presets window, click Anti-aliasing to open a settings dialog.

Add the following values:

Spatial Sample Count: 1

Temporal Sample Count: 64

Override Anti Aliasing Mode: Enabled

Anti Aliasing Method: None

Render Warm Up Count: 120

Engine Warm Up Count: 120



The values for the Render Warm Up Count and Engine Warm Up Count provide a buffer with enough time when building the temporal history and simulations for them to settle before a frame is captured. For example, this would allow auto exposure or other screen effects to achieve a good starting point before rendering out the first frame.

These settings will render a high-quality image. The goal here is to demonstrate a higher-quality image than what you would get from a real-time render. Because of this, you do not need to be concerned about real-time performance or the time the render takes.

This tradeoff in quality versus performance, however, does mean that the higher the sample count, the longer the render takes for each frame.

Because you can doesn't mean you should!

It is recommended that you test initially using a few frames rather than by setting everything to its highest value before starting. Your aim should be to find settings that work best for your project based on your GPU and setup.

Step 7: Configure the Console Variables

You can call most of the console variables (CVARs) that you will want to execute when rendering from the Movie Render Queue. This is extremely useful for rendering high-quality results that are too expensive for real time.

The CVARs listed in the queue will only execute when the image is rendered from the queue. These settings do not permanently change anything in the level that has already been set up—it works with existing settings and only overrides those settings indicated in the queue for the final image output.

This approach is particularly valuable with ray tracing, where increased sample counts and bounces directly affect performance but greatly improve the quality and precision of the lighting result.

Click Console Variables to open a settings dialog.



Click the Add (+) button to enter a variable and its value, using the list below:

r.MotionBlurQuality: 4

r.MotionBlurSeparable: 1

r.DepthOfFieldQuality: 4

r.BloomQuality: 5

r.Tonemapper.Quality: 5

r.RayTracing.GlobalIllumination: 1

r.RayTracing.GlobalIllumination.MaxBounces: 2

r.RayTracing.Reflections.MaxRoughness: 1

r.RayTracing.Reflections.MaxBounces: 2

r.RayTracing.Reflections.Shadows: 2

The fastest and most accurate way to enter these CVARs is to cut and paste from this document, then press the Tab key to move the cursor to the value field.

Repeat Step 2 until all have been added.



As with the anti-aliasing values, the console variables used here focus on quality over performance.

For Ray Tracing Global Illumination (r.RayTracing.GlobalIllumination), setting a value of 1 calls the brute force method. This is accurate, and allows multiple bounces of indirect lighting, but is computationally expensive. If you were to change this value to 2, it would use a temporal history method, which is much faster but only allows a single bounce of indirect light, and produces some ghosting artifacts (pixels that trail after a moving image).

The other CVARs in this exercise use scalable values that control the quality level.

If you want to know the details of a console variable, you can use the backtick ( ` ) key to open the console and search for that console command. Use the following format to display the tooltip:

[consolevariablename] ?

For example, if you input r.RayTracing.GlobalIllumination ?, the output of the tooltip would look something like:

The result of this query will display in the Output Log. To access, go to Window > Developer Tools > Output Log.

All of the variables and values chosen for this guide offer a high-quality starting point for rendering out from the project.

As you work with your own projects, you may want to experiment with different variables and values. For CVARs specific to ray tracing, see On Your Own! at the end of this guide.

Step 8. Configure the Output

The final configuration step in the Setting/Presets window is Output.

You can render the entire sequence, a range of frames, or individual frames. Since the high-quality output is time-consuming, for this exercise you will limit the output to a short segment from the sequence.

Click Output on the Setting/Presets window to open a settings dialog.



Under File Output, enter:

Output Directory: The directory where you want to render the image to. By default, it will be saved to your project folder. To browse for a different directory, click the ... to the right.

File Name Format: The default name, if unchanged, is the name of the sequence and the frame number(s) rendered.

Output Resolution: The target image size. Default is 1920 (width) by 1080 (height). Leave it at the default.

Use Custom Frame Rate: Changes the frame rate for the output. Leave disabled.

Override Existing Output: Click this box to enable.

Under Frames, enter:

Handle Frame Count: Not used in this exercise. Leave at default value of 0. To learn more about this option, see Sequencer Overview.

Output Frame Step: Not used in this exercise. Leave at default value of 1.

Use Custom Playback Range: Click to enable.

Custom Start Frame: Sets the first frame for the render range. Enter 450.

Custom End Frame: Sets the last frame for the range. Enter 550. This range of 100 frames is enough to show quality of reflections, motion blur, and global illumination, without spending an enormous amount of time waiting for the render to complete.

Click Accept to save all settings entered.

Step 9: Save Your Configuration Settings

Saving your settings is an easy way to use them again with this and other projects. Once you have saved a Preset, you can go back later and edit those settings as you find ways to tweak the settings for a project workflow, or copy the Preset to other projects.

You can also edit the settings and save or save-as later as you find ways to tweak the settings for a project workflow.

From the Movie Render Queue window, click Unsaved Config* to open the Setting/Preset window.

Click Presets, then Save As Preset.



In the Save Config Preset window, give your preset Asset a name.

A new directory path will be automatically generated in the project Content Browser: Cinematics > MoviePipeline > Presets. Accept the default location, or use the Content navigation panel on the left to choose a different directory.



Click Save.



Because this preset is now an Asset, it can be opened in the Content Browser and copied into another project, independent of a sequence file.

If your saved preset does not show, click the dropdown to open a list of any presets saved for this project.



Step 10: Final Output and Results

In this final exercise step, you will render out your selected range of images from the sample sequence using the values you set up and saved.

You have two options for rendering:

Render (Local): Renders the queue in the current Editor instance, and is similar to Play In Editor (PIE). This is the most common workflow and recommended due to the fast iteration time.

Render (Remote): The default behavior is to launch a separate process to render the queue, similar to the "Use Separate Process" in the old Render Movie system. Changes to files will need to be saved when launching the separate process. The behavior of this button can be replaced with an in-house solution, such as using a render farm.

For this exercise, you will render locally for easy preview.

In the Movie Render Queue window, make sure your sequence is loaded, along with the presets you saved, then click the Render (Local) button.



A preview window will launch, then capture and output each frame based on parameters and values in the presets.



The status information displays at the bottom on the left, and sequence information on the right.

This render output was set up for quality, not speed. If it seems like your computer is taking a long time, be patient—it can be a slow process.

Once the render is complete, the preview window will close. The captured frames can be found in your saved output directory. To navigate to that folder quickly, click the link in the Movie Render Queue window under the Output column.

Here is a video clip showing the final result of the 100-frame shot render.

You may see some artifacts that still need to be addressed, such as reflections that seem to flicker on the gold cup. Such issues can be optimized or addressed using other techniques in the Material. (For more on these techniques, see ArchViz Interior Rendering.

You will, however, see improved anti-aliasing, shadowing, motion blur, and multi-bounce global illumination and reflections. Use the comparison below to examine the differences in frame 540 with the default settings (left) and the settings specified for the output in this exercise (right).





In this guide, you have learned how to set up and configure the Movie Render Queue to render out high-quality image sequences in multiple formats. You can bring these image sequences into third-party editing and compositing software—like Adobe Premiere, After Effects, Final Cut Pro, Nuke, or Resolve—to generate a video clip or perform further shot editing and color grading.

Troubleshoot the Render

If the render fails, or if the engine freezes up or crashes, there are a few things you can check.

Do you have the most current GPU driver for your graphics card?

If you do not, then download it.

Does your GPU support ray tracing?

For more information ray-tracing system requirements, see Real-Time Ray Tracing.

If these do not resolve the issue, try the next step.

Disable GPU Timeout

The information below can also help avoid or reduce GPU timeouts, but should be applied only if you run into timeout issues or if the engine crashes when rendering.

The console command r.D3D12.GPUTimeout sets whether to enable or disable the GPU from timing out, which can cause the engine to close.

0 disables GPU timeout. This should be used with extreme care as it could cause your PC to freeze.

1 enables GPU timeout. This is set by default, and causes the editor to close when an operation is taking too long to complete on the GPU.

Because you are going to apply this only to your project, not to your entire system, do these steps after you have downloaded the ArchViz Interior sample project, and while Unreal Engine is closed.

With Unreal Engine closed, go to the project Config folder. Example: D:\ue_local_project_Epic_official_demo\ArchVizInterior\Config

Open the ConsoleVariable.ini file in a text editor, and scroll to the bottom of the file, then add these two lines at the end:

; disable GPU Timeout

r.D3D12.GPUTimeout=0

The first line is a comment to remind you what the CVAR is for. The second line is the actual CVAR with the intended value.

Save the file. If prompted to override, click OK. Close your text editor.

Launch the engine and load the Archviz project. The GPU timeout CVAR is now in effect.

On Your Own!

You have learned a basic workflow for the Movie Render Queue, but settings you used here are just a starting point. Following are some suggestions for you to try on your own.

Rendering Locally versus Remotely

In Step 10: Final Output and Results, you output your render locally. This method is good for previewing while still providing a high quality result. However, using remote rendering does not run the Unreal Editor render code during the process.

If you have access to a render farm, then you can implement your own handling of the Render (Remote) command to have the job sent to a render farm. At this time Unreal Engine does not include support for any existing third-party render farm software. Unreal Engine 4.25 currently requires writing new implementations using C++. We are looking to add support for writing implementations in Python in the near future.

Temporal Sampling and Denoisers

There are two temporal sampling approaches to address anti-aliasing in the image processing.

When working in the editor in real time, you are using Temporal Anti-Aliasing (TAA), which is a specific real-time, anti-aliasing technique. It has downsides, such as ghosting or noise artifacts when the camera moves really fast or objects move across finely detailed materials, which make it less suitable for high-quality image output.

Instead, you can use Temporal Sampling. This method is a similar technique to TAA, but uses real render data to anti-alias the image. It resolves the issues with real-time TAA, but processes much more slowly because it uses more samples to generate better results. For example, if it uses 8x samples, it would take eight times as long to process as real-time TAA.

The other aspect is that ray tracing uses different denoisers for many of its features. It uses fewer samples but produces an equivalent result as though it were using more samples by softening the samples with blurring and smoothing. With the Movie Render Queue, since you don't care about real-time performance, you can disable the denoisers and use more samples to produce a more physically accurate result.

With this in mind, you can disable the following denoisers when using Movie Render Queue with ray-tracing features by adding them to your console variables list:

r.AmbientOcclusion.Denoiser: 0

r.DiffuseIndirect.Denoiser: 0

r.RayTracing.SkyLight.Denoiser: 0

r.Reflections.Denoiser: 0

r.Shadow.Denoiser: 0

r.RayTracing.GlobalIllumination.Denoiser: 0

When TAA is disabled by setting the Anti Aliasing Method to None in the Configuration Settings dialog, it is also a good idea to turn off temporal accumulation of samples when the denoisers are disabled in the CVARs. Explore the ones below in your own tests for Movie Render Queue:

r.AmbientOcclusion.Denoiser.TemporalAccumulation: 0

r.GlobalIllumination.Denoiser.TemporalAccumulation: 0

r.Reflections.Denoiser.TemporalAccumulation: 0

r.Shadow.Denoiser.TemporalAccumulation: 0

Additional Ray-Tracing Console Commands

Many ray-tracing feature values are optimized for real-time usage. This means that they use fewer sample counts, with a limit on maximum bounces or other settings that trade quality for performance.

Below are more console variables you can use in the Movie Render Queue to trade performance for quality. This is especially useful since this feature executes these commands only when a render is run from the queue, and the settings do not permanently override any of the real-time settings you might have set up in a post process volume in the editor.

Samples Per Pixel: Each ray-tracing feature can use few or many samples to generate the final result. Denoisers use fewer pixels and are often used to do the heavy-lifting. With Movie Render Queue, you have the option of disabling the denoiser and increasing samples per pixel to increase quality.

Some examples would be:

r.RayTracing.Reflections.SamplesPerPixel

r.RayTracing.Shadow.SamplesPerPixel

r.RayTracing.GlobalIllumination.SamplesPerPixel

Maximum Number of Bounces: Ray-tracing features like Reflections, Global Illumination, and Clear Coat benefit by having reflections or light bounce around multiple times in a scene to produce a more natural, higher quality result. These settings would be extremely expensive for real time rendering.

r.RayTracing.GlobalIllumination.MaxBounces

r.RayTracing.Reflections.MaxBounces

r.RayTracing.Reflections.MaxUnderCoatBounces

Sky Light: In real-time ray tracing, sky light can be an additional expense, given its infinite distance, when calculating each frame for features like Reflections and Global Illumination.

The following CVARs can enable additional skylight options in ray-tracing when working with the Movie Render Queue:

r.RayTracing.GlobalIllumination.EvalSkyLight

r.RayTracing.SkyLight.EnableTwoSidedGeometry

r.RayTracing.Reflections.RayTraceSkyLightContribution

r.RayTracing.SkyLight.EnableMaterials

These are a few of the CVARs available. You can explore others by opening the console window and typing r.RayTracing to see a list of available variables.

Types of Reflections

Lumen Reflections

Ray Tracing Reflections

Screen Space Reflections

Reflection Capture Actors

Planar Reflections

High Quality Reflections

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Reflections are an important aspect of bringing environments to life by allowing light to ground objects in the scene. In real-time 3D, reflections start with how the Materials are set up. Materials with low roughness values make surfaces more or less reflective. This can be the difference between creating a mirror-like surface or like brushed metal.

Unreal Engine provides several dedicated reflection systems to use for your projects. Some of these can be used in conjunction with one another or on their own, deprioritizing any other reflection methods. Choosing what types of reflections you enable for your project primarily comes down to the quality you want to achieve and the platforms you're targeting to release on. Some reflection systems may be too costly to performance, only supported on certain platforms, or may have hardware restrictions.

Types of Reflections

When developing your project, you'll want to consider whether your project needs dynamic reflections, the level of quality it should achieve, and if the target platform you want to release on supports them or not.

For example, using a combination of static Reflection Captures with a dynamic Screen Space Reflections post process effect works well for most platforms and is fast to render but has rendering artifacts due to their nature. However, using Lumen Global Illumination and Reflections or Ray Tracing Reflections emulate light and reflections more accurately to ground objects in the scene, but comes at a higher rendering cost and is not supported on all platforms.

The available reflection systems support the following types of reflections and platforms:

Reflection System

Type of Reflections

Supported Platforms

Lumen Reflections

Dynamic

High-end Desktop PCs and Next-Gen Consoles

Ray Tracing Reflections

Dynamic

Desktop PC systems with Windows 10, DirectX 12, and a supported NVIDIA GPU

Screen Space Reflections

Dynamic

Desktop and Consoles

Reflection Captures

Static

All Platforms

Planar Reflections

Dynamic

All Platforms

Lumen Reflections

Lumen Reflections are part of the Lumen Global Illumination and Reflection system which uses either software or hardware-based ray tracing to generate reflections for the scene. Lumen uses a combination of methods to accurately represent the scene through screen traces when using software ray tracing mode. When hardware ray tracing mode is enabled, it will leverage the existing ray tracing architecture for reflections but requires a supported NVIDIA GPU to operate.





For more information, see Lumen Global Illumination and Reflections.

Ray Tracing Reflections

This feature of ray tracing is deprecated and may be removed in a future release.

Hardware Ray Tracing Reflections use ray-tracing techniques to emulate the way light works for accurate environment representation and supports multiple reflection bounces. Ray Tracing in Unreal Engine requires a supported NVIDIA GPU and Windows OS that supports DirectX 12.





For more information, see Hardware Ray Tracing.

Screen Space Reflections

Screen Space Reflections (SSR) are a dynamic post process effect that is limited to only reflecting what is visible on the screen. Objects off screen or occluded by objects on screen are not able to be represented in screen space reflections, which can cause rendering artifacts in the reflections.



For more information, see Screen Space Reflections.

Reflection Capture Actors

Reflection Capture Actors are a low-cost, static capture of the area the reflection probe is placed. Many of these can be placed around the Level with no performance impact since they are calculated before runtime.



There are two types of Reflection Captures to choose from: a Box and a Sphere shape. They work by capturing an image of the surrounding environment from their center and then mapping that to the reflection capture shape. Reflection Captures can overlap and blend with one another and are often placed with a large one to encompass an area and smaller ones for more defined static reflections on surfaces.

For more information, see Reflection Capture Actors.

Planar Reflections

Planar Reflections is an Actor that can be placed along surfaces to create accurate, dynamic reflections of the scene whereby it renders the level again from the direction of the reflection. This method of reflection can be costly, but provides accurate reflections and is supported on all platforms.





For more information, see Planar Reflection.

High Quality Reflections

Default reflection quality settings strike a good balance between performance and visual quality. However, for projects that are less concerned about performance and want to push quality of reflections even higher, you can use the High Precision Normals GBuffer to do so.

An important factor in achieving high quality reflections is how accurately the vertex normal and tangent can be represented. High density meshes may lead to adjacent vertices quantizing to the same vertex normal and tangent values, which leads to blocky jumps in normal orientation. Encoding the normals and tangents as 16 bits per channel enables developers to make the trade off between higher quality and how much additional memory is used encoding vertex buffers.





The following settings are required to enable High Precision Normals for reflections:

In the Project Settings under Engine > Rendering > Optimizations change the GBuffer Format to High Precision Normals.



Open any Static Mesh Asset and using the Details panel in the Static Mesh Editor, under LOD 0 > Build Settings enable Use High Precision Tangent Basis.



Screen Space Reflections VS Planar Reflections

Enabling Planar Reflections

Planar Reflection Actor Properties

Planar Reflections Actor Scene Capture Properties

Unreal Engine (UE) supports real-time Planar Reflection that can give more accurate looking reflections than Screen Space Reflections (SSR) provide but come with a higher rendering cost. This higher rendering cost is due to how Planar Reflection works, as Planar Reflection actually renders the level again from the direction of the reflection.



Screen Space Reflections VS Planar Reflections

Screen Space Reflections (SSR) are much more efficient than Planar Reflections when it comes to rendering, but are also much less reliable.The image comparison below shows the limits of SSR versus Planar Reflections.





Screen Space Reflections: The image on the left shows the limitation of Screen Space Reflections. Notice the significant amount of 'leaking' that happens at the edges of the image or the part of the pool towards the camera view where reflections start to fade out. This happens because SSR can not reflect objects that are off-screen.

Planar Reflections: The image on the right shows the same level, however, this time, Planar Reflections have been enabled. Notice how there is no leaking in the image, even at the sides and edges of the pool, the reflection is consistent and accurate. This is because Planar Reflections can reflect objects that are off-screen regardless of camera view.

Enabling Planar Reflections

To use enable and use Planar Reflections in your project you will need to do the following:

Click the Edit in the Main menu panel, select Project Settings.



In the Project Settings menu, navigate to the Rendering > Reflections section.



Click image for full size.

Click on the check box next to Support global clip plane for Planar Reflections.



Click image for full size.

Failing to re-start the UE Editor after Planar Reflections are enabled will result in Planar Reflections not working.

Restart the UE Editor when prompted.



Once the UE Editor has restarted, go to the Place Actors panel and in the Visual Effects tab, select and drag a Planar Reflection Actor to the Level.



Click image for full size.

With the Planar Reflection Actor now placed in the level, you can now use the G key to hide and unhide the Actor. You can also use the Move, Rotate, and Scale tools to better position and size the Planar Reflection Actor to meet your levels needs.

Any nearby reflective Materials will automatically be affected by the Planar Reflection Actor as soon as it is added to the level. Static Meshes that are placed in the level will also have their normals used to distort the reflection, allowing for the simulation of waves.

Planar Reflection Actor Properties

The Planar Reflection Actor has a number of properties that when adjusted can significantly affect the look of the reflection. The following table outlines these properties and how they will change the look of the Planar Reflection.



Properties

Description

Normal Distortion Strength

Controls the strength of normals when distorting the planar reflection.

Prefilter Roughness

The roughness value to prefilter the planar reflection texture with. This is useful for hiding low resolutions. Larger values have a larger GPU cost.

Distance from Plane Fadeout Start

Receiving pixels at this distance from the reflection plane will begin to fade out the planar reflection.

Distance from Plane Fadeout End

Receiving pixels at this distance from the reflection plane will have completely faded out the planar reflection.

Angle from Plane Fade Start

Receiving pixels whose normal is at this angle from the reflection plane will begin to fade out the planar reflection.

Angle from Plane Fade End

Receiving pixels whose normal is at this angle from the reflection plane will have completely faded out the planar reflection.

Show Preview Plane

Toggles the visibility of the reflection plane while working in the Editor. This does not affect the planar reflection.



Advanced Properties



Prefilter Roughness Distance

The distance at which the prefilter roughness value will be achieved.

Screen Percentage

Downsample percent can be used to reduce GPU time rendering the planar reflection. This directly affects the quality of the reflection produced by the planar reflection.

Extra FOV

Addtional Field of View (FOV) used when rendering to the reflection tetxure. This is useful when normal distortion is causing reads outside the reflection texture. Larger values increase rendering thread and GPU cost, as more objects and triangles have to be rendered into the planar reflection.

Render Scene Two-Sided

Whether to render the scene as two-sided, which can be useful to hide artifacts where normal distortion would read "under" an object that has been clipped by the reflection plane. With this setting enabled, the backfaces of a mesh woul dbe displayed in the clipped region instead of the background which is potentially a bright sky. Be sure to add the water plane to the Hidden Actors if enabling this, as water plane will not block the reflection.

LOD Distance Factor

Scales the distance used by Level of Detail (LOD). Set to values greater than 1 to cause the scene capture to use lower LODs than the main view to speed up the scene capture pass.

Planar Reflections Actor Scene Capture Properties

The Planar Reflection Actor also has a number of properties that enable you to control the performance cost of the realtime reflection that is captured.



Property

Description

Primitive Render Mode

Controls what primitives get rendered into the scene capture.

Render Scene Primtive (Legacy) - Renders all primitives in the scene;

Render Scene Primtives - Renderes all primitives in the scene except any added to the Hidden Actors list;

Use ShowOnly List - Renders only Actors listed in the Show Only Actors list.

Capture Source

Controls capture source type.

Scene Color (HDR) in RGB, Inv Opacity in A;

Scene Color (HDR) in RGB, 0 in A;

Final Color (LDR) in RGB

Scene Color (HDR) in RGB, Scene Depth in A;

Scene Depth in R;

Device Depth in RGB;

Normal in RGB (Deferred Renderer only);

Base Color in RGB (Deferred Renderer only);

Final Color (HDR) in Linear sRGB gamut;

Final Color (with tone curve) in Linear sRGB gamut.

Capture Every Frame

Whether to update the capture's contents every frame. If disabled, the component will render once on load and then only when moved.

Capture on Movement

Whether to update the capture's contents on movement. It is disabled if you are going to capture manually from Blueprint.

Always Persist Rendering State

Whether to persist the rendering state even if Capture Every Frame is disabled. This enables velocities for Motion Blur and Temporal Anti-Aliasing (TAA) to be computed.

Hidden Actors

A list of selected Actors available in the level to hide in the scene capture.

Show Only Actors

A list of Actors available in the level that will be rendered by this scene capture when using the Primitive Render Mode for Use ShowOnly List.

Max View Distance Override

Sets the maximum render distance (in centimeters) for primtives rendered in the scene capture when values are greater than 0. This can be used to cull distance objects from a reflection if the reflecting plane is in an enclosed areas like a hallway or room.

Capture Sort Priority

Sets the capture priority within the frame to sort scene capture on GPU to resolve interdependencies between multiple capture components. The highest value will come first.

Use Ray Tracing if Enabled

Whether to use ray tracing for this capture. Ray Tracing must be enabled in the project.

Profiling Event Name

Sets a name for the profiling event when profiling the GPU. This is useful to know which planar reflection is being used when using multiple ones in your levels.



Advanced Properties



General Show Flags

Common feature show flags that toggles some features and Actors from being rendered to the scene capture. For example, Anti-aliasing, Fog, Static and Skeletal Meshes, and more.

Advanced Show Flags

Common advanced feature show flags that toggles some features and Actors from being rendered to the scene capture. For example, Foliage, Instanced Static Meshes, Paper 2D Sprties, and more.

Post Processing Show Flags

Toggles show flags for Bloom, Eye Adaptation, and Motion Blur from being rendered to the scene capture.

Light Types Show Flags

Toggles show flag for Sky Lighting from being rendered to the scene capture.

Lighting Components Show Flags

Toggles show flags for Ambient Occlusion and Dynamic Shadows from being rendered to the scene capture.

Lighting Features Show Flags

Toggles common show flags for Lighting features from being rendered to the scene capture. For example, Distance Field Ambient Occlusion (DFAO), Light Functions, Screen Space Reflections, and more.

Hidden Show Flags

Toggles show flags for Lighting and Post Processing from being rendered to the scene capture.

Planar Reflection Limitations

While Planar Reflections offer some very realistic reflections, this features does have a number of limitations which are listed below.

Planar Reflections cause your entire scene to be rendered twice, so you'll want to budget half your frame time for it on the Rendering thread and GPU!

Limit the number of Planar Reflections placed in the world. Often times, one will still be too much.

Size it appropriately, which enables it to be culled when not visible.

The cost to render the Planar Reflection Actor comes directly from what is currently being rendered in the level. Scenes that are triangle and draw call heavy will suffer the most performance issues when this feature is enabled because those costs don't scale with Screen Percentage.

Planar Reflection Performance

While enabling and using Planar Reflections in your project will give you crisp and reasonably accurate reflections, this option will have a direct impact on the project's performance. In the following section, we will take a look at the performance impact enabling Planar Reflections will have in a high-end PC project as well as a project that is geared towards mobile devices.

Examples below use the Kite & Infinity Blade Grass Lands project for demonstrating the performance impact of the Planar Reflections. You can find this project in the Marketplace of the Epic Games Laincher.

Planar Reflection Performance & Kite Demo

Due to the size and varying height of the Kite demos Landscape terrain, adding and then scaling a single Planar Reflection Actor to encompass the entire level would not work and could lead to very poor performance. Instead, Planar Reflection Actors were strategically placed and scaled to fit areas of the level that needed them. In the following image, we can see what the visual impact Planar Reflections have on water used the Kite demo.





While the visual impact Planar Reflections have on the level is quite dramatic, so is the impact they have on performance. If you take a look at the left hand image below, Planar Reflection Off, you will see that the entire level is taking 31 ms to render. If you take a look at the right hand image, Planar Reflections On, you will see that the entire level is taking 29.19 ms to render. On top of that, Planar Reflection are adding an additional 23.07 ms of rendering time bring the total time to render the scene with Planar Reflections enabled to around 52 ms.





Planar Reflection Off

Planar Reflection On

Click for full image

Click for full image

The reason why Planar Reflections are taking around 31 ms to render is due to the fully dynamic lighting and shadowing used in Kite. Levels that make use of Stationary / Precomputed lighting and shadowing will be much more efficient when rendered again for the Planar Reflection.

Planar Reflection Performance & Infinity Blade Dungeons

Due to the size and layout of the Infinity Blade Elven Ruins map, only one Planar Reflection was needed and it was scaled to match the already existing water Static Mesh that was placed in the level. In the following images, we can see the visual impact adding a Planar Reflection has on the look of the water in the Elven Ruins map.





While adding a Planar Reflection makes the water look more lifelike, the impact it has on performance is quite small when compared to the Kite Demo. If you take a look at the image on the left hand side below, Planar Reflections Off, you can see that without Planar Reflections the scene is costing around 11 ms to render. If you take a look at the image on the right hand side, Planar Reflections On, you can see that with Planar Reflections cost around 1.67 ms to rendering bring the total time to render the level to around 13 ms.





Planar Reflection Off

Planar Reflection On

Click for full image

Click for full image

The reason that Planar Reflections only cost 1.67 ms to render in the Elven Ruins map versus the 23.07 ms that it takes to render the Planar Reflections in the Kite Demo is due to how the Static Meshes and Materials that are used in the Elven Ruins were built. Since the Elven Ruins map and its content was designed for mobile devices, close attention was paid to the amount of triangles and Material instructions each asset used. Because of this, when Planar Reflections are enabled in the Elven Ruins map, they will cost less as the assets that are used in the map are greatly reduced in complexity and size when compared to the Kite Demo assets.

Reflection Capture Shapes

Sphere shape

Box shape

Setting Up a Level to use the Reflection Environment

Glossy Indirect Specular

Reflection Capture Lightmap Mixing

Lightmap Mixing and Existing Content

Editing Reflection Probes

Using a Custom HDRI Cubemap in a Reflection Probe

Adjusting Reflection Probe Resolution

Adjusting Skylight Reflection Resolution

Blending Multiple Reflection Probe Data

Visualizing

Performance Considerations

Limitations

Reflection Capture Actors are probes that can be placed around the world to capture a static image of the area they cover. This reflection method reprojects the captured cubemap onto surrounding reflective materials. It is a low-cost method of reflections with no runtime performance cost.

Reflection Capture Shapes

There are currently two reflection capture shapes: sphere and box. The shape is very important because it controls what part of the level is captured into the cubemap, what shape the level is reprojected onto in reflections, and which part of the level can receive reflections from that cubemap (area of influence).

Sphere shape

The sphere shape is currently the most useful. It never matches the shape of the geometry being reflected but has no discontinuities or corners, therefore, the error is uniform.



The sphere shape has an orange influence radius that controls which pixels can be affected by that cubemap, and the sphere that the level will be reprojected onto.

Smaller captures will override larger ones, so you can provide refinement by placing smaller captures around the level.

Box shape

The box shape is very limited in usefulness and generally only works for hallways or rectangular rooms. The reason is that only pixels inside the box can see the reflection, and at the same time all geometry inside the box is projected onto the box shape, creating significant artifacts in many cases.



The box has an orange preview for the projection shape when selected. It only captures the level within Box Transition Distance outside this box. The influence of this capture fades in over the transition distance as well, inside the box.

Setting Up a Level to use the Reflection Environment

The first step toward having good reflections is setting up diffuse lighting including indirect lighting through the use of lightmaps. The Lightmass page contains more info on how to accomplish this if you are unfamiliar with using it. Common errors preventing Lightmass indirect lighting from working after a build include but are not limited to the following:

A shadow casting skybox.

Lack of a LightmassImportanceVolume.

Missing or incorrectly setup lightmap UVs.

Having Force No Precomputed Lighting set to True in the World Properties.

Since the level's diffuse color is what will be reflected through the Reflection Environment you will need to do the following for the best results.

Ensure significant contrast between directly lit and shadowed areas.

Remember that the bright diffuse lit areas are what will show up clearly in reflections.

Darker shadowed areas are where the reflections will be most visible.

Use the Lit viewmode together with the Specular show flag disabled to see the level as the reflection captures see it.

It is also extremely important to setup your level's Materials to work well with the Reflection Environment by keeping the following in mind.

A flat, mirror surface will reveal the inaccuracies of combining cubemaps projected onto simple shapes.

Curvy geometry or rough surfaces can both obscure these artifacts and provide convincing results.

It is important to use detail Normal maps and specify some degree of roughness on Materials that will be used in flat areas as this will help them better show off reflections.







Smooth surface but curvy geometry: Good quality reflections

Rough surface but flat geometry: Good quality reflections

Smooth surface AND flat geometry: Evident that reflections do not match up

Place reflection captures in the areas that you want to have reflections. Try to place the sphere captures such that the part of the level you want to reflect is contained just inside their radius since the level will be reprojected onto that sphere shape. Try to avoid placing captures too close to any level geometry, as that nearby geometry will dominate and block important details behind it.

Glossy Indirect Specular

In technical terms, the Reflection Environment provides indirect specular. We get direct specular through analytical lights, but that only provides reflections in a few bright directions. We also get specular from the sky through a Sky Light, but that does not provide local reflections since the Sky Light cubemap is infinitely far away. Indirect specular allows all parts of the level to reflect on all other parts, which is especially important for Materials like metal which have no diffuse response.





Full lighting



The Reflection Environment works by capturing the static level at many points and reprojecting it onto simple shapes like spheres in reflections. Artists choose the capture points by placing Reflection Capture Actors. Reflections update in real time during editing to aid in placement but are static at runtime. Projecting the captured level onto simple shapes gives approximate parallax for the reflection. Each pixel blends between multiple cubemaps to get the final result. Smaller ReflectionCapture Actors override larger ones, so you can refine reflection parallax accuracy in areas as needed. For example, you might place a capture at the center of a room and then refine the reflection by placing smaller captures at the corners of the room.

Materials with varying glossiness are supported by generating blurry mipmaps from the captured cubemaps.



However, just using the cubemap reflections on a very rough surface results in an overly bright reflection that has significant leaking due to lack of local occlusion. This is solved by reusing the lightmap data generated by Lightmass. The cubemap reflection is mixed together with the lightmap indirect specular based on how rough the material is. A very rough material (fully diffuse) will converge on the lightmap result. This mixing is essentially combining the high detail part of one set of lighting data (cubemaps) with the low-frequency part of another set of lighting data (lightmaps).

For this to work correctly, though, only indirect lighting can be in the lightmap. This means that only the indirect lighting from Stationary lights can improve the quality of reflections on rough surfaces. Static light types should not be used together with the Reflection Environment as they will put direct lighting in the lightmap. Note that this mixing with the lightmap also means that the map must have meaningful indirect diffuse lighting and that lighting must already be built to see results.





Reflection Capture Lightmap Mixing

When you use Reflection Capture Actors, UE mixes the indirect Specular from the Reflection Capture with the indirect Diffuse lighting from lightmaps. This helps to reduce leaking since the reflection cubemap was only captured at one point in space, but the lightmaps were computed on all the receiver surfaces and contain local shadowing information.





While lightmap mixing works well for rough surfaces, this method breaks down on smooth surfaces as reflections from Reflection Capture Actors no longer match reflections from other methods like Screen Space Reflections or Planar Reflections. Because of this, lightmap mixing is no longer applied to very smooth surfaces. A surface with Roughness value of 0.3 will get full lightmap mixing, fading out to no lightmap mixing by Roughness 0.1 and below. This also allows Reflection Captures and Screen Space Reflections to match better and make it harder to spot transitions between the two.

Lightmap Mixing and Existing Content

By default, lightmap mixing will be enabled which means it will affect existing content. In cases where you had reflections leaking on smooth surfaces, that leaking will be more apparent. To solve this, you can either place additional Reflection Capture Actors around the level to help reduce the leaking. Or you can revert to the old lightmap mixing behavior. For this click Edit on the Main menu panel and select Project Settings.



Navigate to the Engine > Rendering > Reflections and then un-check Reduce lightmap mixing on smooth surfaces.



Click image for full size.

You can fine tune the amount of lightmap mixing that will take place by adjusting the following commands using the UE console.

r.ReflectionEnvironmentBeginMixingRoughness (default = 0.1)

r.ReflectionEnvironmentEndMixingRoughness (default = 0.3)

r.ReflectionEnvironmentLightmapMixBasedOnRoughness (default = 1)

r.ReflectionEnvironmentLightmapMixLargestWeight (default = 1000)

Editing Reflection Probes

When making edits to Reflection Probes there are a number of different things that you must remember to do to ensure that you get the results you are after. In the following section we will cover what these things are and how you can make sure you are getting the best quality reflections in your projects.

Using a Custom HDRI Cubemap in a Reflection Probe

Reflection Probes have the ability to not only specify which cubemap they should be using for reflection data but also what size that cubemap should be. Previously UE hard-coded the resolution of the cooked cubemaps reflection probes would use. Now developers can choose the resolution that best suits their needs based on performance, memory, and quality tradeoffs. Below is a comparison image that shows the difference between using the Captured Scene option versus the Specified Cubemap option.





To specify a custom HDRI Cubemap for your project's Reflection Probes to use you will need to do the following:

First, make sure that you have an HDRI Cubemap Texture available for use. If you do not have an HDRI Cubemap Texture in your project, one comes bundled with the Starter Content called HDRI_Epic_Courtyard_Daylight.



Navigate to the Place Actors panel and in the Visual Effects tab, select and drag a Sphere Reflection Capture Actor to the Level.



Click image for full size.

Select a Reflection Probe Actor that has been placed in the Level and in the Details panel under the Reflection Capture section change the Reflection Source Type from Captured Scene to Specified Cubemap



Click image for full size.

With the Reflection Probe still selected in the Level, go to the Content Browser and select the HDRI Texture you want to use. Then in the Reflection Capture Actor, under the Reflection Capture drag the HDRI Texture from the Content Browser to the Cubemap input.



Click image for full size.

Click Build on the Main menu panel and select Build Reflection Capture to use the new HDRI Cubemap Texture that was just specified.



Click image for full size.

Adjusting Reflection Probe Resolution

You can globally adjust the resolution of the HDRI Cubemaps that are used for the Reflection Capture Actors by doing the following:

Open up your Project settings by going to the Main Toolbar and then selecting Edit > Project Settings.



From the Project Settings menu go to the Engine > Rendering section and then look for the Reflections option. By adjusting the Reflection Capture Resolution option you can increase or decrease the size of the HDRI Cubemap Texture that was specified.



Click image for full size.

Please note that the Cubemap Resolution will only work with numbers that are powers of 2 like 16, 64, 128, 256, 512, and 1024. When using values other than a power of 2, it will be rounded to the nearest accepted resolution value. Also, be extremely careful when using high resolution values as it will dramatically affect performance due to the GPU memory requirements.

The following images show what how the reflections will look when the Reflection Capture Resolution is set to 1, 4, 8, 16, 32, 64, 128, 256, 512 and 1024.

Drag the slider to see how the different resolutions affect the look of the reflection.



Adjusting Skylight Reflection Resolution

Like with the Reflection Probes, Skylights also have the ability to define and adjust the resolution of the HDRI cubemap that they use for reflections. To utlize this functionality in your UE project you will need to do the following:

From the Place Actors panel in the Lights tab, select and then drag a Skylight into your Level.



Click image for full size.

Select the Skylight and in the Details panel under the Light section, disable the Real Time Capture and then change the Source Type to SLS Specified Cubemap.



Click image for full size.

Click on the drop down box in the Cubemap section and select an HDRI cube map from the list.



After the cubemap has been selected you can adjust its resolution by changing the value in the Cubemap Resolution input.



Please note that the Cubemap Resolution will only work with numbers that are powers of 2 like 16, 64, 128, 256, 512, and 1024. When using values other than a power of 2, it will be rounded to the nearest accepted resolution value. Also, be extremely careful when using high resolution values as it will dramatically affect performance due to the GPU memory requirements.

Blending Multiple Reflection Probe Data

You can blend between multiple different cubemap reflections by providing the Reflection Capture Actors with different HDRI cubemaps. To accomplish this in your UE project all you need to is the following:

First, make sure that you have at least one Reflection Probe added to your Level and that you have changed the Reflection Source Type to Specified Cubemap and input an HDRI Texture into the Cubemap input.



Click image for full size.

Duplicate or add a new Reflection Probe to the Level and position / adjust its Influence Radius it so that part of it's yellow influence radius is intersecting with the first Reflection Probe.



Click image for full size.

Select the newly duplicated / created Reflection Probe Actor and in the Details panel under the Cubemap section change the HDRI cubemap to a different one.



Click image for full size.

Click Build on the Main menu panel and select Build Reflection Capture to use the new HDRI Cubemap Textures that were just specified.



Click image for full size.

Visualizing

The Reflection Override viewmode has been added to make it easier to see how well the reflections are set up. This viewmode overrides all normals to be the smooth vertex normal, and makes all surfaces fully specular and completely smooth (mirror like). Limitations and artifacts of the Reflection Environment are also clearly visible in this mode so it is important to switch to Lit periodically to see what the reflections look like in normal conditions (bumpy normals, varying glossiness, dim specular).



Some new show flags have been added which are useful for isolating down the components of the lighting:

Flag

Description

Lighting Components > Diffuse

Disabling diffuse will hide diffuse contribution from all lighting methods.

Lighting Components > Specular

Disabling specular will hide specular contribution from all reflection methods.

Lighting Features > Reflection Environment

This will disable the Reflection Environment feature, but other reflection features will still be active (SSR, analytical specular).

Performance Considerations

The Reflection Environment cost is only dependent on how many captures influence the pixels on the screen. It is very similar to deferred lighting in this sense. Reflection captures are bounded by their influence radius and therefore they are culled very efficiently. Glossiness is implemented through the cubemap mipmaps so there is little performance difference between sharp or rough reflections.

Limitations

Reflections through this method are approximate. Specifically, the reflection of an object will rarely match up with the actual object in the level due to projection onto simple shapes. This tends to create multiple versions of that object in reflections as many cubemaps are being blended together. Flat, smooth surfaces that cause mirror reflections will show the error very noticeably. Use detail normal maps and roughness to help break up the reflection and these artifacts.

Capturing the level into cubemaps is a slow process which must be done outside of the game session. This means dynamic objects cannot be reflected, although they can receive reflections from the static level. If quality is a consideration, light functions can be enabled (r.reflectioncapture.enablelightfunctions 1) to improve volume and complex lighting capture at lighting build, or level start.

Only the level's diffuse is captured to reduce error. Purely specular surfaces (metals) will have their specular applied as if it were diffuse during the capture.

There can be significant leaking when there are different lighting conditions on both sides of a wall. One side can be setup to have correct reflections, but it will always leak into the other side.

Due to DX11 hardware limitations, the cubemaps used to capture the level are all 128 on each side, and the world can have at most 341 reflection captures enabled at one time.

Screen Space Reflection is an effect which is enabled by default that alters the appearance of objects on the surface of Materials. There are only a handful of options that can be tweaked for this effect which are outlined below.

Property

Description

Intensity

Enable/Fade/Disable the Screen Space Reflection feature by percentage (avoid numbers between 0 and 1 for consistency).

Quality

0=Lowest Quality while 100=Maximum Quality (50 is the default to provide better performance).

Max Roughness

Used to determine what roughness we fade the Screen Space Reflections (0.8 works well, smaller can run faster).

Supported Shadowing Methods

Static and Stationary Light Preview Shadowing

Configuring Shadowing Properties of Lights

Source Angle, Radius, Height and Width

Attenuation Radius

Casting Shadows

Volumetric Shadowing

Global Illumination Indirect Lighting

Shadow Bias

Contact Shadows

Lightmass Settings

Shadowing with Materials and Textures

Distance Field Shadowing

Directional Light

Cloud and Atmosphere Shadowing

Cascaded Shadow Maps

Shadow Performance and Optimization Options

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Shadows make objects feel grounded in the world. They give the viewer a sense of depth and space. Shadowing is supported by all available types of lights and determined by a light's mobility.

Supported Shadowing Methods

The type of shadowing used by a light is determined by what its Mobility is set to: Static, Stationary, or Movable. Mobility is the primary guiding factor in whether a light should cast a precomputed shadow baked into a texture called a lightmap, a dynamic shadow generated in real-time, or one that uses a combination of precomputed and dynamic shadowing.

A Light's Mobility can be set independently of other lights in the Level, meaning that you can use any combination of mobilities to light the scene.

The following shadowing methods are available to use:

Some require Project Settings to be enabled, or additional properties to be enabled on the Light to work.

Shadow Mapping

The default shadowing method that renders geometry into shadow depth maps. This shadowing method works for all platforms that support dynamic shadowing, but it requires manual setup of shadowing distances and only culls per-component, causing poor performance with high polygon scenes. Also, it does not support Nanite geometry.

Virtual Shadow Maps

This shadowing method renders geometry into virtualized shadow depth maps. It provides high quality shadows for next-gen projects with simplified setup. It has high efficiency culling when used with Nanite geometry.

Ray-traced Shadows

This method traces a set number of samples per pixel using Hardware Ray Tracing with denoising algorithms to render high quality ray-traced shadows in real-time.

Distance Field Shadows

This method uses signed distance fields per Static Mesh and is used by Lumen Software Ray Tracing for dynamic soft area shadows.

Precomputed Shadows with Lightmass

This method uses lighting data from the scene to generate lightmap textures that are applied to Static geometry in the Level. Geometry requires additional setup with proper lightmap UVs. Precomputing lighting for the scene can vary depending on machine specifications, scene complexity, and other factors when determining how long a light build will take.

Static and Stationary Light Preview Shadowing

When editing a Light with its Mobility set to Stationary or Static the light is considered un-built. Preview Shadowing is enabled to give you an idea of what the shadows will look like when lighting is rebuilt, but they are not representative of the final, baked result.

To indicate what are actually preview shadows, shadows from these lights are shown in the Level Editor with the text Preview.



Preview text over shadows is visible only while working in the Level Editor. If you launch your project in Play-In-Editor (PIE) or Standalone Game modes, no text will appear over unbuilt shadows.

To resolve any preview shadows, you will need to build lighting. Use the Main Menu to select Build > Build All Levels to kick off a lighting build.





Built Scene Shadows

Preview Shadows

Preview shadows can be disabled while working in the Editor by unchecking the Preview Shadows Indicator under the Level Viewport Show > Visualize menu.

Configuring Shadowing Properties of Lights

The following properties can be found on the available Types of Lights.

The properties are accessible through the Level's Details panel when a Light is selected.











Directional Light

Sky Light

Point Light

Spot Light

Rect Light

Click images for full size.

Source Angle, Radius, Height and Width

Each type of light has an option to set the angle, radius, or height and width of its light source to control the size and shape of the shadows it casts. Larger angles, radii, heights, and widths soften shadows for objects the light affects.

In the examples below, the left Spot Light has no source radius specified and produces sharp shadows. The right Spot Light has a moderate source radius specified, which softens the shadows of that light depending on the distance of the objects from it.



When looking at the Spot Lights in the Level Editor viewport, you can see the Source Radius of the light is represented by the yellow sphere on the Spot Light on the right side.



Point, Spot, and Rect Lights all have a visible source size that updates in real-time while being edited.



Point Lights and Spot Lights have an additional option to control length of the Source Radius with the Source Length property, making it possible to create cylindrical light shapes like a tube light.



Attenuation Radius

The Attenuation Radius of Point, Spot, and Rect Lights enable you to set a bounding area that this light will affect. While this is not physically accurate, it is important to clamp the bounds of dynamic shadowing-casting lights for performance.

In the examples below, the left Spot Light has a smaller attenuation radius than the one one on the right. Notice how the light only affects the area within the farthest point of its radius.



When the lights are selected, you can see how the distance of the attenuation radius affects the objects within its area and doesn't shadow objects outside of its reach.



Casting Shadows

Cast Shadow controls whether the selected light should contribute shadows to the scene.



Left, shadow casting enabled; Right, shadow casting disabled.

Volumetric Shadowing

The Volumetric Scattering Intensity scales the fog intensity and light color when enabled. It enables a light to contribute more to fog without having to directly increase its intensity.

Lights contribute to Volumetric Fog when enabled for the scene.

You can control the contribution of individual lights to Volumetric Fog with Volumetric Scattering Intensity. By default, volumetric shadows are disabled for lights but can be enabled with Cast Volumetric Fog.





Global Illumination Indirect Lighting

Global Illumination provides indirect lighting for a scene from light that hits a surface and bounces within a space. It provides fill lighting and soft area shadowing for surfaces to ground objects within the space. Unreal Engine supports indirect lighting with precomputed baked global illumination from Lightmass, and dynamically with Lumen and Screen Space Global Illumimation.

The Mobility of a light determines which method a light should contribute to (in some cases).



Scene showing real-time indirect lighting with Lumen dynamic global illumination.

Some dynamic global illumination methods are not able to be combined with precomputed ones, such as Lumen with baked global illumination. However can work together, such as using Hardware Ray Tracing with baked global illumination.

Shadow Bias

When using the default shadow mapping method, the shadow map generated to shadow assets in the Level are set per-light to maintain a balance between performance and shadowing quality. Shadow maps have some limitations, such as faceting on curved geometric surfaces or self-shadowing artifacts, that can be adjusted using Shadow Biasing properties found on lights.

Shadow bias is a per-light set of properties that help improve accuracy of self-shadowing and contact hardening from a light source. Biasing settings are useful for finding a trade-off between accuracy in one area while reducing self-shadowing artifacts in another.





For more information, see Movable Lights.

Contact Shadows

Contact Shadows are a per-light additive feature to use on top of other shadowing methods employed by lights. It is a screen space effect that draws rays from a pixel's position toward the light source through the scene's depth buffer. Thus, it helps improve contact hardening and accuracy of shadows in some cases, but is limited by what is visible within the current camera view.

Use Contact Shadows Length property to define their length whereby a value of 1 is equal to the entire screen, 0.5 is half the screen, and 0 is disabled. Lower values produce less noise and may appear more accurate depending on the scene.





Lightmass Settings

The Lightmass settings on a light affect precomputed lighting when the Light Mobility is set to Static or Stationary and a lighting build has been completed.

These settings control the baked softness of the shadow with Source Angle for Directional Lights, how much this light's saturation affects indirect lighting, and the fall off of shadow penumbras with a shadow exponent.

Shadowing with Materials and Textures

Lights can use Light Functions and IES Light Profiles to further define aspects of lights and their shadows.

Light Functions are a Material type that can be applied to non-lightmapped lights, like Movable Lights and the direct lighting of Stationary Lights to filter a light's intensity, but not its color. It can also be used to apply an animated texture to the light source. For example, simulating moving cloud shadows from a Directional Light.



IES Light Profiles are textures which describe a light's distribution from a light source using real-world measured data. They are a lighting industry standard method of diagramming the brightness and fall off of lights as it exists in a particular light fixture.





Distance Field Shadowing

Mesh Distance Fields have a variety of uses from shadowing to creating interactive materials and dynamic indirect lighting and reflections with Lumen.

A mesh distance field representation of a Static Mesh is used to produce soft shadowing from a Movable light sources when the Distance Field Shadows property is enabled.

This method of shadowing is similar to other methods, like Hardware Ray Tracing and Virtual Shadow Maps where the Source Angle, Radius, or Size control penumbra of shadow.



Left, shadows maps; Right, shadows from mesh distance fields.

Directional Light

Directional Lights contains unique settings relevant to this light source to simulate large world lighting.

In the Light's Atmosphere and Clouds section, there are settings and properties that affect how this light source will interact with Sky Atmosphere and Volumetric Clouds, such as having the sun affect the atmosphere and clouds, casting shadows from or onto clouds, and shadow quality, to name a few.



Cascaded Shadow Maps split the camera view frustum into different cascades (or shadow levels of detail) for whole scene dynamic shadowing. This optimizes shadows over larger distances to provide quality where it's needed: higher quality closer to the camera position, lower quality farther away from the camera position.

The settings found under the Cascaded Shadow Maps section specify the number of cascades to use, their maximum distance, where to distribute quality, and where the transition between each cascade should be.



Cascaded shadow maps have a maximum distance you specify. But when you need shadowing on larger objects beyond this, you can use the Far Shadow Cascades to enable shadowing art farther distances. However, the one difference here is that you have to enable specified assets that you want to have shadowing at this distance. You can do this with this by selecting an Actor in the Level and enabling Far Shadow on that asset.



Shadow Performance and Optimization Options

Performance of shadows can largely depend on the shadowing method being employed for your project.

The properties mentioned in this section are starting points for optimizing lighting within a scene, especially for dynamic lights where some methods of shadowing are more expensive, like the default shadow mapping.

Attenuation Radius for Point, Spot, and Rect Lights is important to control not only where light is within the scene but to limit the number of objects that have to be shadowed, which can make them expensive for some shadowing methods, especially the default shadow mapping method.

Disabling Cast Shadows on dynamic lights can improve performance if the shadows are not contributing a lot to the scene, the light affects a lot of objects with a large attenuation radius, or assets have a lot of geometric detail. This mostly affects methods lit using traditional shadow mapping, but it's important to consider for any dynamic light to reduce frame cost.

Setting a Max Draw Distance on a light will limit its dynamic shadowing contribution up to that point. For scenes where you have a lot of small to medium-sized lights affecting an area, this can help reduce frame cost. Using Max Fade Range in addition to the max draw distance will fade that light out over time so that it doesn't abruptly appear and disappear.

The Shadow Map shadowing method is a product of balancing quality with performance. Sometimes, you want to trade performance for a bit of quality. The Shadow Map Resolution property enables you to increase the shadow map of the selected light to trade quality for performance.

When using Hardware Ray Tracing Shadows you can adjust the Samples Per Pixel property under the Ray Tracing section to apply more samples to the light's ray-traced shadows. Fewer samples reduce quality and improve performance, while more samples improve quality (to a point with the denoising algorithm) but cost more.

Getting Started



Capsule Shadows can be used to enable support for soft shadow casting for Skeletal Meshes by using a capsule representation of your character made from a Physics Asset. The soft shadows serve to ground the character in indirectly lit areas and give soft shadows in directly lit areas.

Getting Started



An overview on using phsyics capsules for dynamic soft shadowing of Skeletal Meshes.



A guide to setting up and using a Physics Assets for a Skeletal Mesh character for soft shadowing.

Character Capsule Representation

Usage

Capsule Shadow Settings

Capsule Indirect Shadows

Capsule Direct Shadows

Performance

Limitations

Unreal Engine supports soft shadowing for characters in lit areas with Capsule Shadows using a capsule representation of a Skeletal Mesh from a Physics Asset. This shadowing method grounds a character to the scene with soft area shadowing, especially in indirectly lit areas, which is not possible when using traditional shadow mapping techniques.

Character Capsule Representation

A Physics Asset is used to create an appoximate representation of the character to support very soft shadowing. Since the capsules are attached to the bones of the character, this allows for the shadow to move and cast accurately within the scene.





The shadows on the ground in the Physics Asset viewport are not representative of Capsule Shadows.

Usage



Open your Skeletal Mesh, and in the Asset Details panel, use the Shadow Physics Asset selection to assign your Physics Asset that will be used for Capsule Shadows.

Capsule Shadow Settings



Property

Description

Capsule Direct Shadow

This will enable soft shadowing from direct (movable) lights when the capsule representation is assigned to the Skeletal Mesh's Shadow Physics Asset slot.

Capsule Indirect Shadow

This will enable soft shadowing from precomputed lighting (lightmaps and skylight) when the capsule representation is assigned to the Skeletal Mesh's Shadow Physics Asset slot.

Capsule Indirect Shadow Min Visibility

This will allow artists to control how dark the capsule shadow, in indirectly lit areas, can be.

Capsule Indirect Shadows

When you enable Capsule Indirect Shadow, the capsule representation of the character will be used to cast a directional soft shadow based on the volume lighting samples placed and computed by Lightmass during a lighting build. Capsule Indirect Shadows enables your characters to feel grounded in these areas where traditional shadow mapping will not work very well.



When Capsule Indirect Shadow is enabled, your character will cast a soft shadow that can ground them in areas with only bounce lighting.





In an open area with only a Sky Light as the light source, there will be little directionality, since light is coming from all around. This produces a subtle soft "blob" shadow below the character when using precomputed lighting.





In an enclosed area where light is coming through an opening, the indirect lighting cache is used to give directionality and softness to the capsule shadow by interpolating between the placed volume lighting samples as the character moves through the space. At the doorway, the character's shadow will be less intense with little directionality, but as the character moves further away from the doorway, the shadow's intensity and directionality will increase.

Artists are afforded additional control by adjusting the Capsule Indirect Shadow Min Visibility. This enables you to adjust how dark the capsule shadow will be in indirectly lit areas, using precomputed lighting. This can be be useful to reduce any self-shadowing from a capsule in these areas, or to soften the shadow's intensity, so that it blends nicely with surrounding shadows.





Capsule Direct Shadows

Enabling Capsule Direct Shadow on light sources enables you to define how soft area shadowing is for the shadow caster on a shadow receiver based on the angle of the light or the size of the light source.



Capsule Shadows for direct lighting should be used as a scalability option for cheaper shadows than rendering highly detailed polygonal Skeletal Meshes into shadowmaps. For additional information, see the sections directly below for specific mobilities required for the light source. Also, see the "Limitations" section below.

For a Directional Light, the Source Angle property enables you specify the Sun's angle in degrees to soften shadows.

This property works for all light mobilities (Static, Stationary, and Movable) when Capsule Direct Shadow is enabled.



|

For Spot and Point Lights, the Source Radius sets the size of the light source emitting light; the larger the source the softer the shadows and smaller, the more hard the shadow contacts are.

Capsule Direct Shadowing requires that the light source have its mobility set to Stationary and that lighting has been built for the scene before the Source Radius on the light will have any effect.





Once lighting has been built for your scene, you can adjust the Source Radius property without having to rebuild lighting. This property only affects movable actors with Capsule Shadows or Mesh Distance Fields enabled.

Performance

The GPU performance cost of Capsule Shadows is proportional to the number of capsules used, the number of characters, and the screen size that their shadow affects.

Using a Radeon 7870 at 1080p, for example:

GPU Cost with 10 Capsules

Time in milliseconds (ms)

A single character on screen

0.29 ms

Each additional character on screen

0.05 ms

This implementation is very efficient, since it computes shadowing at half resolution with a depth-aware upsample, while using screen tile culling to reduce the amount of shadowing work to only happen where it is needed.

Limitations

Requires DirectX 11, due to tiled deferred implementation using compute shaders.

Movable Point and Spot Lights are not currently supported.

Self-shadowing artifacts can exist for arbitrary mesh shapes.

Can only use Sphyls and Spheres for capsule representation.

When capsule shadows get so soft that they become ambient occlusion, there's an artifact in the shadowing that causes a hard line.

Movable Point and Spot lights are not supported because it costs more to remove one object out of the whole scene shadows and do a per-object shadow for it. Stationary lights are always going to be a per-object shadows method so Capsule Direct Shadow for faster shadow rendering makes sense.

1 - Required Setup

2 - Your Character - Creating a Shadow Physics Asset

3 - Your Character - Assigning the Physics Asset

4 - Your Level - Enabling Capsule Shadows For Your Character

5 - On Your Own!

At the end of this guide, you'll have a scene similar to the one above.

Goals

The Capsule Shadows Quick Start intends to quickly get you up and running with the basics of creating a capsule representation of your character with a Physics Asset and enabling Capsule Shadows for character in your games differently lit environments.

Objectives

After going through this tutorial, developers will know the following:

How to create a Physics Asset for shadows.

How to assign the Shadow Physics Asset to your Skeletal Mesh.

How to enable Capsule Shadows in your level for your characters.

1 - Required Setup

Before we get started, the first thing we'll need to do is to create a new project that we can work from for the rest of this guide. In the steps below, we'll use Unreal Engine 4's Project Browser to create the project. After completing this step, you will have a template that you can build onto for your future projects.

Steps

Start by opening Unreal Engine from the Epic Games Launcher. The Project Browser will appear.

Create a new project in the Games > Third Person template, with the following settings:

Blueprint enabled

No Starter Content enabled

Click Create Project.

End Result

After creating our project, and once the Unreal Editor has finished loading, you will be presented with the Main Editor Interface shown below. In the Content Browser, you will see various folders for the Blueprint Third Person Template that we will use in the next steps.



Click image for full size.

In the next step, we will start by setting up a new Physics Asset for our Third Person Character that will be used for our Capsule Shadows.

2 - Your Character - Creating a Shadow Physics Asset

With your project ready to go, in this step, we'll create a new Physics Asset for the Third Person Character's Skeletal mesh that will be used for shadow representation with Capsule Shadows.

Steps

Inside of the Content Browser, use the folder hierarchy to navigate to Mannequin > Character > Mesh folder. Here you will find the asset named SK_Mannequin, which you'll use. Select it, and then right-click, to bring up the context menu. From there, select Create > Physics Asset > Create.



After you click Create, the New Asset window will open to create the new Physics Asset. Set the Minimum Bone Size to 15 and then click OK.



Only use Sphyl bodies for the best result. Sphere bodies will also work, but they are not as flexible in their use with character Skeletal Meshes.

Next, the Physics Asset Tool will open with your new Physics Asset for the Skeletal Mesh SK_Mannequin.



This is an optional step. Before moving forward, it is recommended that you take a moment and give your newly created Physics Asset a name. Do this by minimizing the PhAT window, and in the Content Browser, locate the Physics Asset that was created for SK_Mannequin in your Mesh folder. Give it a name so that you can locate it later ("SPA_Mannequin" would be a good name). Once you've done this, you can maximize the PhAT window again.



In the PhAT window, you'll now want to adjust the various Physics Bodies, so that the capsule represents the character more accurately. This will require deleting some existing bodies, along with scaling and rotating the remaining ones to better fit. Below, you'll find a list of things you should keep in mind when adjusting and removing your capsules:

Limit the number of bodies by removing unnecessary capsules; like hands, arms, multiple capsules for the torso and neck, etc.

Foot capsule placement is very important to make your character look grounded, and may need to be tweaked later to look more accurate.

Use a little bit of overlap between the capsules's joints to avoid gaps in the shadow.

Capsules for the arms are not necessary for this Quick Start and can be removed.

When you are finished with your adjustments, you should have something that looks similar to this. The placement does not have to be perfect and can easily be tweaked later to refine any shadowing issues that you may run into.



End Result

Now that the Physics Asset for the character's capsule representation is complete, you should be familiar with the process of creating a new Physics Asset and setting it up to represent your character with as few bodies as possible.





Before: 21 Capsule Bodies

After: 10 Capsule Bodies

In the next step, we'll assign our new Physics Asset to our Skeletal Mesh.

3 - Your Character - Assigning the Physics Asset

We created a new Physics Asset for our Skeletal Mesh character that we'll use in this step to assign in the Skeleton Editor.

Steps

Inside of the Content Browser, use the folder hierarchy and navigate to the Mannequin > Mesh folder. Select SK_Mannequin asset and double-click to open it.



When the Skeleton Editor opens, navigate to the Asset Details panel and scroll down to locate the tab for Lighting. Click the selection box next to Shadow Physics Asset and select the Physics Asset we created in the previous step.



Be vigilant in naming your Physics Assets clearly because when you use the Shadow Physics Asset selection box, all Physics Assets for the project will be listed here.

You can now Save & Close the Skeleton Editor.

End Result

You have now assigned the Physics Asset that you created in the previous step to your character's Shadow Physics Asset slot. This will enable your character to use this Physics Asset for shadowing purposes.

In the next step, we will add our character to the level, and then enable Capsule Shadowing.

4 - Your Level - Enabling Capsule Shadows For Your Character

In the previous step, you assigned the Physics Asset to your character in the Skeleton Editor as its Shadow Physics Asset, which, in this step, will enable you to use Capsule Shadowing for your character in directly and indirectly lit areas when enabled.

Steps

Inside the Content Browser, use the folder hierarchy to navigate to the ThirdPersonBP > Blueprints folder. Select the ThirdPersonCharacter Blueprint, and double-click to open it.



When the Blueprint Editor opens, use the Components window, and select Mesh (Inherited). Then, in the Details panel, scroll down and locate the Lighting tab. Under the advanced rollout, locate and enable the following:

Capsule Direct Shadows

Capsule Indirect Shadows



Click image for full size.

With Capsule Shadows enabled for Direct and Indirect lighting, you can Save & Close the ThirdPersonCharacter Blueprint.

Before we can fully test Capsule Shadows, you'll need to create some indirectly lit areas in your level to use Capsule Indirect Shadows. From your Level Viewport, select the Floor Actor, and then hold down the ALT key while left-clicking to drag a copy up along the Z-axis (Blue). Move the floor Actor to the top of the outer walls, and then use the X-axis (Red) on the translation tool to move it back, so that only part of the floor is covered. This will give you an area that uses indirect lighting when you rebuild the lighting for the scene.

Now, select the Direcitonal Light, named "Light Source", from the World Outliner. In its Details panel, set the Intensity for the light to 10. This will make sure there is enough light to illuminate the area being covered.



From the Main Toolbar, click the Build button so that lighting will be rebuilt for the scene. This ensures that you will be able to use Capsule Indirect Shadows for your character.



End Result

You now have a character that supports Capsule Shadowing when in direct and indirect lighting. You can Play in Editor (PIE) to move your character around the scene to see how the soft shadows look.

You can enable both Capsule Shadow settings individually, such that, if you don't need the soft shadowing while your character is lit in open areas, you can disable this option and leave only Capsule Indirect Shadow enabled for these areas that are indirectly lit.

In the final step, there are some challenges you can attempt on your own, along with reminders for creating a Shadow Physics Asset.

5 - On Your Own!

Now that you have created a sample Shadow Physics Asset for Capsule Shadowing, you can try some of the following on your own:

Try using different lighting angles, or time-of-day scenarios, for mid-day, dusk, or evening.

Adjust the Light Source Angle of your Directional Light to soften your Capsule Shadow in areas that are directly lit so that your character blends in with surrounding shadows.

Add some closed off areas with doorways and windows (or something similar) to a cave opening, to get contrasting light that gives directionality for the light source when Capsule Indirect Shadow is enabled.

Use the setting for Capsule Indirect Shadow Min Visibility in your Character's Details panel to blend the soft shadow's intensity with your environment.

Add some additional capsule bodies for the arms of your character for shadowing when it's near wall surfaces, like with a cover system, or if your character goes prone.

To explore some additional features of Unreal Engine, see the following:

For information covering Capsule Shadows, see Capsule Shadows.

For information covering the Physics Asset Tool, see Physics Asset Tool.

For information covering Lighting, see [building-virtual-worlds\lighting-and-shadows).

Adding Detail to your Characters

Scenes with Contact Shadows

Enabling Contact Shadows



When creating scenery and characters for your application, there are times when you'll want to add visual depth to the rendering. Adding Contact Shadows is a great way to improve the visual depth and fidelity of your scene because they provide a more accurate approximation of shadowing, allowing you to add a contoured shadow that might not be achieved with other shadowing algorithms.

Adding Detail to your Characters

One use case for enabling Contact Shadows for a given Point Light is to render an additional Level of Detail (LOD) for your characters. The following images should give you a good idea of what Contact Shadows can add to a character. As you drag the comparison slider from right to left, you'll notice that the character located within the radius of a Point Light with enabled Contact Shadows exhibits additional details that aren't present when Contact Shadows are turned off.





When you turn on Contact Shadows, you're directing the renderer to execute a per-pixel screen space algorithm on a per-light basis. This means that the Contact Shadow algorithm is executing a light computation pass, performing scene depth buffer ray marching so as to determine whether the queried pixel is to be occluded from the Point Light source that has Contact Shadows enabled.

Scenes with Contact Shadows

Another use case for enabling Contact Shadows is to eliminate the need for computing parallax occlusion mapping shadows within a material's pixel shader that only supports one light. The following image provides a comparison of parallax occlusion mapping materials with and without Contact Shadows enabled.



It's important to note that your parallax occlusion mapping materials should output the pixel depth offset.

The following is an example of Contact Shadows interacting with a parallax occlusion mapping material.



Contact shadow length = 0.1 on both lights.

Enabling Contact Shadows

By default, Contact Shadows are disabled on Point Lights, whereby the Point Light's Contact Shadow length is initialized to 0. To enable Contact Shadows, perform the following steps:

First, drag a Point Light into your scene.



Now, expand the Light section of the Details panel for your newly created Point Light Component by clicking on the expansion arrow.



Click for full image.

To enable contact shadows, set the Contact Shadow Length to a value greater than 0.



Click for full image.

By setting the Contact Shadow's length to a value greater than 0, you're directing the renderer to trace rays from a pixel's position toward the light source through the scene's depth buffer. Typically, you'll want to set the Contact Shadow's length to a maximum value of 1, where 1 means that the ray traverses the entire screen. Whereas, setting the Contact Shadow's length to a value of 0.5 means that the ray traverses only half of the screen. Note that the number of samples taken in the scene depth buffer remain constant, which means that you'll see more noise (artifacts) as you increase the Contact Shadow's length. Basically, a Contact Shadow length of 0.75 generates more noise than a length of 0.1.

Nanite Virtualized Geometry

Goals of Virtual Shadow Maps

Enabling Virtual Shadow Maps

Soft Shadows with Shadow Map Ray Tracing

Clipmaps for Directional Light

Local Lights

Coarse Pages

Visualization

Caching

GPU Profiling and Optimization

Supported Platforms

Issues and Limitations

Virtual Shadow Maps (VSMs) is the new shadow mapping method used to deliver consistent, high-resolution shadowing that works with film-quality assets and large, dynamically lit open worlds using Unreal Engine 5's Nanite Virtualized Geometry, Lumen Global Illumination and Reflections, and World Partition features.

Goals of Virtual Shadow Maps

Virtual Shadow Maps have been developed with the following goals:

Significantly increase shadow resolution to match highly detailed Nanite geometry

Plausible soft shadows with reasonable, controllable performance costs

Provide a simple solution that works by default with limited amounts of adjustment needed

Replace the many Stationary Light shadowing techniques with a single, unified path

Conceptually, virtual shadow maps are just very high-resolution shadow maps. In their current implementation, they have a virtual resolution of 16k x 16k pixels. Clipmaps are used to increase resolution further for Directional Lights. To keep performance high at reasonable memory cost, VSMs split the shadow map into tiles (or Pages) that are 128x128 each. Pages are allocated and rendered only as needed to shade on-screen pixels based on an analysis of the depth buffer. The pages are cached between frames unless they are invalidated by moving objects or light, which further improves performance.

Nanite does not support many of the Stationary Light shadowing techniques, such as pre-shadows and per-object (or Inset) shadows. While some of the more dynamic parts of Stationary Light shadowing may work — such as the Cascaded Shadow Maps near the camera viewer — Nanite and Stationary Lights with conventional shadow maps are not supported. If you are using Nanite in your project, you must either use Movable Lights or use Virtual Shadow Maps.

Enabling Virtual Shadow Maps

In the Project Settings under Engine > Rendering in the Shadows section, you can set what Shadow Map Method your project supports, whether Virtual Shadow Maps or the conventional Shadow Maps** that have been used in previous Unreal Engine releases.

Existing projects will need to opt-in using the project setting, or console variable r.Shadow.Virtual.Enable. New projects use Virtual Shadow Maps by default.



What happens with existing shadow methods when VSMs are enabled?

When VSMs are enabled, they replace a variety of existing shadow methods in Unreal Engine:

Stationary precomputed shadows, including 2D Distance Field and shadow factor "shadow maps"

Pre-shadows

Per-object / inset shadows

Cascaded Shadow Maps (CSMs)

Movable dynamic shadows for local lights

Fully baked shadows from Static Lights will still work as before (when not using Lumen). Their contributions are entirely represented in the baked lightmaps and there is no runtime lighting evaluated at all. Stationary lights will use the indirect diffuse contribution from any baked lightmaps, but their direct lighting and shadows are evaluated dynamically (the same as Movable lights) when VSMs are enabled.

Distance Field Shadows are not replaced, and can be used in tandem with Virtual Shadow Maps for Directional Lights. Distance Field Shadows take over for non-Nanite geometry beyond the dynamic shadowing distance of Movable Lights — set on a Directional Light using the Cascaded Shadow Maps property Dynamic Shadow Distance Movable Light. Using Distance Field Shadows provides a useful tool to reduce runtime costs in complex scenes, such as those with lots of non-Nanite foliage.

Nanite geometry always renders to the Virtual Shadow Map regardless of distance, since this is the most performant option and provides the highest quality. It is possible to make non-Nanite geometry behave the same way as Nanite by the console variable r.Shadow.Virtual.UseFarShadowCulling 0.

Local lights (Point and Spot Lights) are not affected, and selecting Distance Field shadows for these continues to override the active shadow map method.

Due to VSM's high resolution and accuracy, the screen space Contact Shadow feature controlled with the Contact Shadow Length property is no longer necessary to achieve sharp contact shadows. It still may have value when used to pick up cheaper shadows from objects set to not render into shadow maps but is not recommended otherwise as it will be less accurate than the shadows VSMs will create.

Ray-traced shadows still take precedence over VSMs as they generally provide the highest quality solution.

Soft Shadows with Shadow Map Ray Tracing

Shadow Map Ray Tracing (SMRT) is a sampling algorithm used with virtual shadow maps to produce more plausible soft shadows and contact hardening. Objects that cast shadows farther will have softer shadows than objects casting shadows closer to a shadow-receiving surface. For example, the mesh pictured below is tall and casts its shadow over a long distance. Shadows near the base are sharper than those farther away.



Example with a Point Light casting soft shadows and contact hardened shadows using Shadow Map Ray Tracing.

Past methods based on Percentage-Closer Filtering (PCF) would over-blur and reduce the visual impact of high-resolution geometry and shadows.





The SMRT algorithm works by shooting a number of rays towards the light source, but instead of evaluating intersections with geometry — like conventional raytracing does — a number of samples along the ray are projected and tested against the virtual shadow map to achieve soft shadowing and contact hardening. Shadow rays are distributed based on the light using Source Radius on local lights or Source Angle on Directional Lights.





Local Light Source Radius

Directional Light Source Angle

Local lights have no Source Radius by default, compared to Directional Lights which start with a low Source Angle. When either are set with an appropriate value, SMRT produces real-time soft shadowing with contact hardening, like the example below using a Point Light with a Source Radius of 10.





Controlling Penumbra Shadow Quality

The penumbra shadow's softness and quality is set by console variables for both local and Directional Lights. They include their own scalability settings that are generally good for most scenes.

Noise in the penumbra is influenced by the number of rays being used, and both local and Directional Lights use eight rays by default when scalability for Shadows is set to Epic.

Use the console variables r.Shadow.Virtual.SMRT.RayCountLocal and r.Shadow.Virtual.SMRT.RayCountDirectional to adjust the number of rays. Fewer rays show visible noise in the penumbra. Setting the associated console variable to 0 disables SMRT and reverts to single-sample hard shadows.





Furthermore, the number of shadow samples taken along each ray's path can be set for both local and Directional Lights to control the maximum softness. Fewer shadow map samples are cheaper to render, but limit the amount of penumbra softness that can be achieved by the light's shadows. For finer control than the Shadow scalability settings, and the console variables r.Shadow.Virtual.SMRT.SamplesPerRayLocal and r.Shadow.Virtual.SMRT.SamplesPerRayDirectional to adjust the number of samples used. Using values between 4 and 8 samples works well.

Dragging the slider will show what happens when a Directional Light with a Source Angle of 5.0 uses Shadow Map Samples that number 0, 2, and 8 (default).



Limitations of Shadow Map Ray Tracing

Quality of SMRT is generally good with the default setting, but there are limitations inherent to using the data from a single shadow map projection rather than testing against true geometry.

Penumbra Size Limits

The shadow's penumbra is clamped for local and Directional Lights to avoid sample divergence from the ray origin that can become increasingly "bent" compared to the ideal test along the ray itself. Using reasonable values for Source Radius on local lights and Source Angle on Directional Lights will avoid results that are too extreme, limiting the extent that the ray can diverge in various ways. Values that are too large can both impact performance and cause shadow penumbrae to visually warp as the camera gets near to them.



Local and Directional Lights can use the console variables r.Shadow.Virtual.SMRT.MaxRayAngleFromLight and r.Shadow.Virtual.SMRT.RayLengthScaleDirectional to loosen or tighten the clamped extents.

Inconsistent Penumbra

Since the Virtual Shadow Map only stores the first depth layer where naive iteration misses intersections with any occluders behind the first one, a variety of light leaking artifacts can happen where the occluders overlap. These types of light leaks are resolved using a gap-filling heuristic that extrapolates depths behind the first occluder based on depths seen before the point of occlusion.

This works well in resolving lighting leaks, but causes penumbrae on surfaces parallel to the light to shrink in size. There is currently no direct way to counteract this effect other than to keep penumbra sizes reasonable.



Examples of inconsistent penumbra shadows.

Penumbra Artifacts

By default, Virtual Shadow Maps only guarantees that the samples around the ray origin (the receiver pixel) will be present. As the algorithm traverses the ray, it can encounter unmapped pages where no shadow data exists. A variety of techniques are used to reduce the impact of this, including dilating the page mappings slightly and having various fallbacks in place during iteration. Even still, occasional artifacts stemming from missing pages can happen, especially around edges of the screen when zoomed in on soft penumbra. These artifacts will manifest as noisy light leaks in shadowed areas. Like other limitations with VSMs, issues can mostly be avoided by keeping shadow penumbra sizes reasonable and avoiding zooming in to the point where they cover large portions of the screen.

Clipmaps for Directional Light

A single virtual shadow map does not provide enough resolution to cover large areas. Directional Lights use a clipmap structure of expanding ranges around the camera, with each clipmap level having its own 16K VSM. Each clipmap level is the same resolution but covers twice the radius of the previous one.





Directional Light Clipmap Visualization

Virtual Shadow Map Pages Visualization

By default, clipmap levels 6 through 22 are allocated virtual shadow map page tables. This means that the default settings have the most detailed clipmap covering 64 cm (2^6 cm) from the camera position, and the broadest clipmap covering about 40 kilometers (2^22 cm). The cost of virtual clipmap levels is insignificant if nothing is present in them, so these defaults work well to cover very large scenes with fairly high resolution near the camera.

The first and last levels can be adjusted using the console variables r.Shadow.Virtual.Clipmap.FirstLevel and r.Shadow.Virtual.Clipmap.LastLevel.

The resolution allocated to a given pixel is a function of the distance away from the clipmap origin — the camera. This is set by Shadow scalability with the console variable r.Shadow.Virtual.ResolutionLodBiasDirectional. A value of 0 picks the resolution required based on the perspective projection of the camera. Projective aliasing — when a shadow is cast on a surface almost parallel to the light direction — is still possible, even at high resolutions, but it can be reduced partly by biasing the resolution. Like Mip biasing in textures, lowering the value by -1 doubles the resolution of shadows with the associated performance tradeoffs. The default value of -1.5 on Epic Shadow scalability provides a reasonable balance for many scenes.

Local Lights

Spot Lights use a single 16k VSM with a mip chain rather than clipmaps to handle shadow level of detail. Similarly, Point Lights use a cube map of 16k VSMs, one for each face.

Local lights provide a significant increase in resolution compared to traditional shadow maps. It is possible to run out of virtual resolution with very large local lights, and care should be taken to use Directional Lights where possible in these cases.





Appropriate mip levels are picked by projecting the size of the screen pixels into shadow map space. Like Directional Lights, it's possible to bias the resolution with the Shadow scalability settings, or using the console variable r.Shadow.Virtual.ResolutionLodBiasLocal.

Per-light resolution controls are not available but may be added in a future release.

Coarse Pages

Depth buffer analysis is used as the primary method of marking pages that are needed to render. There are some systems that need to sample shadows at more arbitrary locations though, such as Volumetric Fog and forward-rendered translucency. Most systems only need low-resolution shadow data that gets filtered and blurred through other data structures.

To accommodate shadowing in these situations, Coarse Pages are marked to ensure that at least low-resolution shadow data is available across the whole domain for sampling. Local lights simply mark the root mip page while Directional Lights can mark a series of pages at various low detail levels to form some coarse clipmaps. Depending on the scene, coarse pages can create performance issues. This is particularly true for non-Nanite dynamic geometry since they are effectively rendering low-resolution shadows over large regions of space, which can result in draw-call bottlenecks.

It is recommended to experiment with disabling non-Nanite objects rendering into the coarse pages using the console variable r.Shadow.Virtual.NonNanite.IncludeInCoarsePages 0.

Many scenes — especially ones consisting primarily of Nanite geometry — do not need non-Nanite objects casting shadows onto Volumetric Fog and similar things. Disabling this can provide a significant performance improvement.

Local light coarse pages can be toggled off with r.Shadow.Virtual.MarkCoarsePagesLocal, if not needed. Directional Light coarse pages can be toggled off with r.Shadow.Virtual.MarkCoarsePagesDirectional, or the range of clipmap levels that coarse pages are marked in can be modified with r.Shadow.Virtual.FirstCoarseLevel and r.Shadow.Virtual.LastCoarseLevel.

In a future release, a more elegant solution would be where some of these effects can be marked for localized pages directly in advance rather than the current, overly conservative coarse pages being used.

Visualization

Visualization options for Virtual Shadow Maps are accessible from the Level Viewport using the View Modes drop-down menu and selecting Virtual Shadow Map.



Visualization options include:

Visualization Name

Description

Shadow Mask

The final shadow mask that is used by shading.

Clipmap/Mip Level

The chosen clipmap (for Directional Lights) or mip (for Local Lights) level.

Virtual Page

Visualization of the virtual page address.

Cached Page

Cached pages are tinted green, uncached pages are red. Pages where only the static page is cached (dynamic uncached) are blue.

By default, the Virtual Shadow Map visualizations display results for the Directional Light. By selecting a light in the World Outliner, you can view visualizations for that light.

You can also enable visualization using the console (except in Shipping builds), which is useful for profiling and debugging a live game. If any of these are set in the editor, they override any mode selection made through the editor's user interface.

Visualization Name

Description

r.Shadow.Virtual.Visualize [mode]

When the view mode visualization is set to Virtual Shadow Map through the Level Viewport or the console command, this command specifies which of the channels to display. Use the names below in place of "[mode]" to enable that visualization. Cache and vpage are two common ones used for visualization and none disables vsm visualization.

mask

mip

vpage

cache

raycount

clipmapvirtual

ShowFlag.VisualizeVirtualShadowMap

Enables the Virtual Shadow Map visualization when a visualization mode is specified.

r.Shadow.Virtual.Visualize.Layout

Choose a layout for the Virtual Shadow Map visualization.

0 is full screen

1 is a thumbnail

2 is split-screen

r.Shadow.Virtual.Visualize.DumpLightNames

Outputs a list of the current lights with Virtual Shadow Maps to the console.

In some build / runtime configurations, the names of the lights may be different from their names in the editor.



r.Shadow.Virtual.Visualize.LightName [light name]

Specify a light by name, partial or full matches are accepted.

To clear a light from being selected using this console variable, specify a light name that won't match any names. Using two quotation marks (") is an acceptable way of resetting it back to no specified light.



Enabling visualization modes has a small but measurable effect on the performance of Virtual Shadow Maps. Be sure to disable the visualization before performance profiling.

Caching

Reusing shadow map pages from previous frames is key to maintaining high performance with Virtual Shadow Maps, especially in complex scenes. Caching is enabled by default, but can disabled for debugging purposes using the console variable r.Shadow.Virtual.Cache 0.

Since pages are only rendered for on-screen pixels, changing camera visibility due to movement of disocclusion can reveal new pages that need to be rendered. Generally, as long as camera movement is relatively smooth, it is not a major source of new pages. On the other hand, you should watch out for very fast movement near objects, large disocclusions, and camera cuts.

In most scenes, the largest source of work comes from shadow map pages that need to be redrawn due to changes in scene geometry. Common sources of cache page invalidations include:

Any light movement or rotation will invalidate all cached pages for that light

Geometry that casts shadows moving, or being added or removed from the scene will invalidate any pages that overlap its bounding box from the light's perspective.

This can include objects such as Blueprints setting properties on primitive components that trigger render state invalidation even though it does not actually move.

Geometry using materials that may modify mesh positions, such as World Position Offset (WPO) or Pixel Depth Offset (PDO)

In instances where you have a slowly moving light, or a shifting Directional Light changing the time of day, VSM pages will effectively not be cached at all. In situations like time-of-day changes, it is recommended to quantize the changes by some small amount to allow cached pages to live for some number of frames since the tiny differences in direction will not be noticeable.

In a future release, caching should improve by adding a priority system and per-frame update budgets to allow finer control over the cost of rendering shadows. For example, allowing shadow resolution to temporarily lower in cases where too many pages need updates.

Managing Cache Invalidations

Decreasing cache invalidations is best done by first visualizing the invalidations, then finding and reducing the things causing them. The Cached Page visualization is a good place to start.



Cached Page Visualization

In this visualization, pages that are fully cached are shaded green. Pages that are new or invalidated are shaded red. As you move the camera you should expect to see small rings of red near screen edges, clipmap boundaries and disoccluded geometry. With a static camera, most of the new pages will come from cache invalidations.

If separate static caching is enabled (see below), pages that are partially cached (where only the static portion is valid) will show up as blue.

Once problem areas have been found, it is often additionally useful to turn on a visualization of the object bounds that are driving the invalidations using the console variable r.Shadow.Virtual.Cache.DrawInvalidatingBounds 1. Inspect these objects and bounds to ensure that they are indeed objects that are expected to invalidate shadows, and that their bounds are as tight as possible. Since all pages that an invalidating object could potentially overlap within its bounds must be invalidated, even moderately inflated bounds combined with low light angles can cause many unnecessary invalidations.



Cached Pages and Invalidating Bounds Visualization

Invalidations that are entirely in the shadow of Nanite objects can be skipped, but this is not true for non-Nanite objects. For this reason it is particularly important to ensure that large shadow-casting objects — such as buildings — use Nanite.

In complex scenes, it can sometimes be difficult to pinpoint what is causing invalidations even with these visualizations. Another tool that can help is the Draw only Geometry Causing VSM Invalidation visualization mode found in the Level viewport under Show > Visualize.



When enabled, any geometry that is not causing cache invalidations is hidden.

Due to implementation details, the Draw Only Geometry Causing VSM Invalidation mode occasionally shows objects that are unrelated to shadowing (such as particle and visual effects) that go through a separate rendering pass and will drawn on top.

Stats are not reliable while using this visualization because rendering the main scene differently affects which pages are mapped and invalidated. It is better to start with other visualization modes and use this one to double-check.

There is a known issue with Scene Capture Components that can cause the entire cache to be invalidated.

Non-Nanite Deformation and Foliage

Geometry that can be deformed using Skeletal animation, or materials using World Position Offset or Pixel Depth Offset always invalidates cached pages every frame. By definition, these cases must also be non-Nanite — which is more expensive — and therefore it is extremely important to ensure that these features are used carefully and bounds are kept under control.

In some cases, such as grass and sometimes foliage, using only Contact Shadows is a sufficient substitute for high resolution shadow maps. In cases where high detail shadows are necessary in the foreground, consider the following to help mitigate the performance cost:

Non-Nanite objects still respect the regular shadow CPU culling settings, such as r.Shadow.RadiusThreshold. Use these to help control the cost of rendering these objects into Virtual Shadow Maps.

In scenes with lots of foliage, it is highly recommended to disable non-Nanite objects in coarse pages with r.Shadow.Virtual.NonNanite.IncludeInCoarsePages 0. Or, consider disabling coarse pages entirely if they are not needed.

Use Mesh LODs to switch to materials that do not use WPO/PDO at distances where the effect is no longer obvious. In some cases, it may be possible to switch off dynamic shadow casting for these objects in the distance and rely entirely on screen space Contact Shadows.

For Directional Lights, there are additional options available:

Distance Field Shadows take over for non-Nanite geometry beyond the Dynamic Shadow Distance Movable Light distance set by the Cascaded Shadow Maps section of the Light. Switching to Distance Field Shadows for non-Nanite in the distance can be a large performance improvement since this geometry does not have the fine-grained LOD scaling that Nanite provides.

In some cases, creating Material LODs that remove WPO/PDO may be impractical, but the end effect of these transformations is small in the distance. Use r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange to set a distance (in centimeters) beyond which cache invalidations from these materials are ignored.

This can cause shadows to "smear" and objects to incorrectly self-shadow if motion is significant, but often the artifacts are a reasonable tradeoff for the performance and convenience.

Separate Static Caching

This feature is considered experimental.

Many scenes consist of a large amount of static geometry that never moves, together with significantly smaller amounts of dynamic (or movable) geometry. By default, this means that the relatively cheap dynamic geometry invalidates pages that then cause the expensive static geometry to be re-rendered, just to update the dynamic portion.

To better optimize in these cases, an optional Separate Static Caching mode can be enabled using r.Shadow.Virtual.Cache.StaticSeparate 1. This mode doubles the size of the physical page pool so that the static geometry in a given page can be cached separately from the dynamic geometry. Even when the dynamic geometry moves, there is no need to redraw the static geometry. Instead, the cached static page can be cheaply composited on top. In cases, such as the Valley of the Ancients sample project, it can be a significant performance optimization as the static terrain is very expensive while the dynamic elements are relatively cheap.

While using this mode, it's important to accurately set the Mobility of Actors in the scene. In particular, if an Actor that is set to Static Mobility moves — or even uses a material with World Position Offset or similarly unsupported materials — it invalidates both the dynamic and static cached pages, resulting in pure overhead for no gain. Conversely, if too much of the expensive geometry is set to Movable Mobility, then there may be little benefit from caching it separately.

The Virtual Shadow Map statistics are a good way to get a high level overview of how well static caching is working. In particular, the number of "invalidated" static pages should be near 0. Finding instances that are invalidating the static cache frequently and switching them to Movable is an important way to ensure the static cache remains valid.

Nanite includes an advanced visualization mode to help determine object mobility in the world, which is also useful for Virtual Shadow Maps.



Nanite's Advanced Virtual Shadow Map Static visualization mode

This visualization mode can be enabled in one of two ways:

Enable Nanite's advanced visualization options with r.Nanite.Visualize.Advanced 1 and then use the Level Viewport to select the View Mode > Nanite Visualization and choose Virtual Shadow Map Static from the list of visualization options.



Click image for full size.

Alternatively, you can enable the Virtual Shadow Map Static visualization with the command r.Nanite.Visualize vsmstatic.

GPU Profiling and Optimization

Unreal Engine provides tools that help you check performance in your projects, and the GPU Profiler (or platform-specific tool) is a good starting place to troubleshoot and debug performance issues.

There are two main performance buckets where VSM costs will show up: Shadow Depths and Shadow Projection (under Lights). The tradeoffs in each of their categories are relatively independent from one another.

Be aware that commands used to list statistics, such as stat gpu and associated counters, can provide unreliable timings, especially if your project's performance is CPU-bound.

Shadow Depths

The Shadow Depths category refers to the cost of rendering geometry into shadow maps.



RenderVirtualShadowMaps(Nanite) contains all rendering of Nanite geometry into VSMs. All Directional Lights are rendered in a single Nanite pass, and all local lights are done in a second pass.

RenderVirtualShadowMaps(Non-Nanite) handles the rendering of non-Nanite geometry. Each visible light has a separate pass with individual draw calls for various objects and instances, the same as conventional shadow maps rendering.

Atlas and Cubemap, along with other similar passes, following the VSM passes are rendering conventional shadow maps. There are still a small number of geometry types that are not yet supported in the Virtual Shadow Maps path, and those follow the old path. If there is no unsupported geometry casting shadows, these passes will not run or allocate shadow map storage. These passes and associated overhead can be disabled entirely with the cvar r.Shadow.Virtual.ForceOnlyVirtualShadowMaps 1, in which case any unsupported geometry types will simply not cast shadows.

The cost of the Shadow Depths pass with VSMs is directly related to how many shadow pages need to be rendered, and how much geometry needs to be rendered into them. Non-Nanite geometry is much more expensive to render into VSMs than Nanite geometry. For this reason, it is recommended to enable Nanite on all supported geometry, including low-poly meshes. The only exception is for features not yet supported by Nanite Virtualized Geometry.

The on-screen stats for VSM pages used can give an idea of how many pages are being used, and where to look to resolve potential problems.

Use the following console variables in succession to enable stats:

r.ShaderPrintEnable 1

r.Shadow.Virtual.ShowStats 1 (or 2 to show only the page statistics)



Stat Name

Description

Physical Pages

The maximum number of physical pages that virtual shadow maps can use.

Allocated

The total number of requested shadow map pages by the current view. It should always be less than Max pages, otherwise corruption can occur. (See the Issues and Limitations section below.)

Cleared

The number of new pages that were cleared in the current frame.

Cached

The number of pages that are already in the virtual shadow map page cache, and that do not need to be rendered in the current frame. Cached pages are very low cost and will have almost no impact on performance. When separate static caching is enabled, this is further split by cached Static Pages and Cached Dynamic Pages.

Invalidated

The number of otherwise-cached pages that were invalidated by dynamic geometry in the previous frame. These pages need to be rendered again because something moved that covers them. When using separate static caching the number of invalidations of static pages should ideally be zero or very close to it. If large numbers of static pages are being invalidated the actor(s) causing the invalidations should be switched to Movable.

Merged

When separate static caching is enabled, this is the number of pages where the dynamic and static pages were merged (due to one or the other not being cached).

The total page counts are a function of the average number of lights that affect each pixel on screen. They can be lowered by reducing screen resolution, shadow resolution (using the console variables for resolution LOD bias), light extents, or the number of shadow casting lights.

Poor performance in shadow depths is typically associated with a high number of pages being used and lots of dynamic invalidation happening, which leads to poor caching of VSMs. See the Caching section for more details on diagnosing and reducing cache invalidations.

Beyond improving caching, there are a number of ways to improve the performance of non-Nanite shadow rendering.

Consider the following to improve non-Nanite object performance:

Enable Nanite on as much geometry as possible for your project.

Nanite geometry renders far more efficiently into Virtual Shadow Maps and should be preferred in every applicable case, regardless of polygon counts.

Nanite geometry can occlude non-Nanite geometry and avoid spurious cache invalidations. Thus, the only non-Nanite objects should be those that are not supported by Nanite itself, such as deforming objects (skinned meshes), or materials using World Position Offset (WPO) and Pixel Depth Offset (PDO).

Non-Nanite objects should have full Mesh LOD hiearchies setup.

It is important that non-Nanite meshes have LODs setup or else they become extremely expensive to render into small pages.

Where possible, it is advisable to switch to non-deforming meshes (no WPO/PDO materials) beyond a distance where the effect is obvious.

CPU culling console variable are still useful for Non-Nanite meshes rendering into Virtual Shadow Maps

Adjust values of CPU culling on non-Nanite objects rendering into Virtual Shadow Maps with the console variable r.Shadow.RadiusThreshold. It can help control the cost of small objects in the distance.

Using Distance Field Shadows for distant shadowing of Non-Nanite Objects

For Directional Lights, it is often necessary to switch to Distance Field Shadows beyond some range, same as Cascaded Shadow Maps. With Virtual Shadow Maps, only non-Nanite geometry will switch to using the Distance Field Shadows while Nanite geometry continues to have full-detail shadows.

Disabling non-Nanite geometry in Coarse Pages can increase performance

Disabling non-Nanite geometry in coarse pages can often net a large performance gain, since non-Nanite geometry is generally inefficient to render into large pages.

The Virtual Shadow Maps statistics can give some insight into non-Nanite instance counts:



Stat Name

Description

Total

Total number of non-Nanite instances input to the GPU culling. Instances are culled separately for each virtual shadow map mip/clipmap level. For example, a single Static Mesh instance can result in 48 instances (8 mip levels * 6 cubemap faces) for each point light that it intersects, 17 instances for each Directional Light (in default configuration there are 17 clipmap levels) and so on.

Drawn

Number of instances actually drawn into all virtual shadow maps after culling.

HZB Culled

Number of instances removed due to being occluded (by Nanite geometry) from the light's perspective.

Page Mask Culled

Number of instances removed due to not overlapping any required pages. This, for example, represents Static Meshes that are discarded when drawing into already cached areas.

Empty Rect Culled

Number of instances removed due to not overlapping any required pages. For example, this represents Static Meshes that are discarded when drawing into already cached areas.

Frustum Culled

Number of instances that were outside the view frustum.

Shadow Projection

The Shadow Projection category is the cost of sampling shadow maps using Shadow Map Ray Tracing. These passes are located under the Lights | DirectLighting | UnbatchedLights and there will typically be one VSM projection pass per associated light. The most expensive pass is usually the main SMRT loop in VirtualShadowMapProjection. The rest should be relatively low cost.

If the projection pass is labeled as RayCount:Static instead of RayCount:Adaptive, a slow path is being taken.

The VSM projection pass described in this section is different from the experimental One Pass Projection described in the next section.



Shadow projection is purely a function of the total number of shadow map samples that are taken across the screen, and performance doesn't depend on the number of pages or caching.

When SMRT is being used, it comes down to:

Average lights per pixel

The more lights touching large portions of the screen, the more expensive rendering will be. Lights covering small numbers of on-screen pixels are cheaper, although there are still some fixed costs per light.

Care should be taken to avoid having the majority of pixels on screen taken up by several large lights.

Rays per pixel

Visible softness of shadows affects performance due to the adaptive ray count. Try reducing the Source Radius of local lights or Source Angle of Directional Lights before lowering any of the ray and sample counts.

Samples per ray

These settings are set by the Shadow scalability setting, but can be further adjusted if needed. See the Shadow Map Ray Tracing section of this page for more details.

Generally, shadow projection costs are much easier to control (trade off with quality and noise) than shadow depth costs.

This feature is considered experimental. The console variable names in this section are likely to change.

Even though smaller lights have a lower cost, they still have some fixed pass overheads. This is being addressed by developing a single-pass shadow projection solution where the majority of local lights in a scene can efficiently evaluate their shadowing in one pass. The shadowed contribution from these lights can then be applied all at once using clustered shading.

This path is enabled using the console variables r.UseClusteredDeferredShading 1 and r.Shadow.Virtual.OnePassProjection 1. For scenes with a lot of small local lights, this can result in significant improvements to performance.

The use of certain light features will prevent a light from being batched even when One Pass Projection is enabled:

Texture Profiles

Light Functions

Lighting Channels

Rect Lights

Directional Lights (there is no benefit to these being batched since they cover the full screen)

In the captures below, the left shows a shadow projection pass happening per-light compared to the right side's one pass projection.



Click image for full size.

In the default path on the left, each local light is accumulated one by one with several passes per light. This is inefficient for small lights that cover a small screen area.

In the new path on the right, all of the shadowed local lights are batched together in the single clustered shading pass (BatchedLights). The Directional Light is still done in a separate pass; it covers the whole screen and thus is not a benefit to batch it.

Each local light still injects into the translucency volume separately. This is less of an issue for performance than the projection, but will likely also be batched together in the future.

When One Pass Projection is enabled it is possible to limit the number of shadowed lights that are fully filtered per-pixel by adjusting r.Shadow.Virtual.OnePassProjection.MaxLightsPerPixel from the default of 16. This is useful both for controlling performance and can save a small amount of transient graphics memory.

If there are more shadowed lights than the maximum in a given pixel (or in practice, a clustered deferred shading tile), additional lights will be shadowed using an inexpensive single hard shadow lookup. This can cause visual discontinuities if the value is set too aggressively, but is generally more forgiving than entirely disabling shadows for lights beyond the count.

This pass is still in development and not enabled by default. The primary caveat is in cases that a local light would have both a virtual shadow map and a classic shadow map (due to some unsupported geometry type in the scene), the One Pass Projections path ignores the latter, causing those shadows to disappear.

If you are using r.Shadow.Virtual.ForceOnlyVirtualShadowMaps already, it should be safe to also enable One Pass Projection. Once current limitations have been addressed, it will likely become the default path used.

Supported Platforms

Virtual Shadow Maps are currently supported on PlayStation 5, Xbox Series S|X, and PCs with graphics cards meeting these specifications, using the latest drivers with DirectX 12:

NVIDIA: Maxwell-generation cards or newer

AMD: GCN-generation cards or newer

All newer version of Windows 10 (newer than version 1909.1350) and Windows 11 with support for DirectX 12 Agility SDK are supported.

Windows 10 version 1909 — The revision number should exceed or be equal to .1350.

Windows 10 version 2004 and 20H2 — The revision number should exceed or be equal to .789.

DirectX 12 (with Shader Model 6.6 atomics), or Vulkan (VK_KHR_shader_atomic_int64)

Latest Graphics Drivers

Issues and Limitations

Virtual Shadow Maps are still actively being developed. There are a number of known issues and limitations to using them currently, and they are currently targeted at high-end desktops and next-generation consoles.

Multiple Lights Performance

Performance in scenes with many small local lights is still a work in progress. For the time being, the best strategy is to enable one pass projection and be very careful with invalidations to keep as many of the pages cached as possible. Multiple local lights will perform far better with Nanite geometry than non-Nanite geometry, so aggressively culling or disabling shadow casting on non-Nanite geometry in the distance can help a lot. In some cases it may be desirable to disable dynamic shadow casting on distant lights entirely and rely solely on screen space Contact Shadows.

In the future, better controls will be available for making algorithmic and quality tradeoffs, as well as throttling updates in these situations.

Low Poly Geometry

Low poly geometry with high curvature and smooth normals can exhibit artifacts. This is known as the "shadow terminator problem." It also occurs in ray tracing and other highly accurate visibility queries. The issue stems from the mismatch between the real low poly geometry and the "smooth" shading normals: in the area near the terminator some of these faces are geometrically in shadow, but the non-geometric shading normals are slightly facing the light. It is common to work around this artifact with a normal-based bias to the shadow lookup. This particular artifact can be more noticeable with Virtual Shadow Maps because by default they are set up to deliver highly detailed shadows from Nanite geometry.

The best way to address this is to increase the polygon count in these objects/regions. Limiting the divergence between the geometric and shading normals reduces or eliminates these artifacts without negatively impacting shadow quality elsewhere. With Nanite adding more polygons is straightforward and generally inexpensive. If the offending objects cannot use Nanite, adding a higher detail level of detail (LOD) often works well too, as these artifacts are mostly visible when objects are near the camera.

If it is not possible to add more geometry, the Virtual Shadow Map normal bias can be increased using r.Shadow.Virtual.NormalBias (default 0.5). Note that this should only be considered when content adjustments are not possible as it will negatively impact the quality of shadows throughout the scene, but particularly in areas of fine detail.

In the examples below, artifacts are visible on a low polygon sphere near the camera with high detail geometry in the background. Adding polygons to the sphere improves the artifacts without negatively affecting the detailed landscape in the background.





Adjusting the bias also improves the artifacts, but fine detail is visibly lost in the background geometry.





Virtual Reality

Virtual reality is not yet fully supported by Virtual Shadow Maps. There are likely to be artifacts with Directional Lights in the right eye.

Split-screen

Split screen has received minimal testing and may have poor performance.

Overflow of Physical Page Pool

With Virtual Shadow Maps, all of the shadow data in the scene for all lights is stored in a single large texture pool. The default pool size is affected by the Shadow Scalability setting, but it may need to be adjusted in scenes with many lights using high resolution shadows.

Alternatively it may need to be adjusted on lower-end hardware to save video memory.

The page pool size can be adjusted using r.Shadow.Virtual.MaxPhysicalPages. Enabling Virtual Shadow Map stats with r.ShaderPrintEnable 1 and r.Shadow.Virtual.ShowStats 2, in succession, will display statistics about the current page pool use.



Example of current page pool use from Virtual Shadow Map on-screen stats.

If the number of Pages exceeds Max Pages corruption will occur, which sometimes manifests visually as a checkerboard pattern, or corrupt or missing shadows. If the shadow page pool overflows, a warning is displayed on screen and in the log.



Example of corrupted virtual shadow maps from an exceeded number of pages in the page pool.

If this occurs, increase the size of the page pool or decrease the shadow resolution or number of virtual shadow map casting lights.

Scene Capture

In some cases, Scene Capture components can cause the entire Virtual Shadow Map cache to be invalidated. The symptoms of this usually manifest as the Invalidations being low in the Virtual Shadow Map statistics, but the cached pages being also low (or sometimes even zero) and the Cached Page visualization being uniformly red.

If this happens, try hiding/removing any Scene Capture actors in the scene to verify if they are causing the issue.

There is currently no workaround other than disabling the Scene Capture when this occurs.

Materials

Only simple subsurface materials are supported. Subsurface Profile and transmission are not yet implemented. If a material is using them, that material will be shadowed as though it is opaque.

Shadow Resolution

Virtual Shadow Maps provide significantly increased resolution compared to conventional shadow maps, but shallow light angles (or projective aliasing) and very large local lights can exhaust the available virtual resolution. This may present itself as box-like shadows and bias issues depending on the geometry's surface.

Directional Light clipmaps are much less susceptible to running out of resolution, but very narrow camera fields-of-view can eventually exhaust those as well.

There is no simple solution to solving projective aliasing with shadow maps. Even with virtual shadow maps, some care must be taken to avoid the worst cases and balance resolution with performance.

Map Check Warnings

Virtual Shadow Maps cause some inaccurate map check warnings to happen:

The Lighting needs to be rebuilt message does not appear when Virtual Shadow Maps are enabled, even though lighting may in fact need to be rebuilt when not using Lumen Global Illumination and Reflections features. While Stationary direct lighting is dynamic with Virtual Shadow Maps enabled, Stationary indirect lighting is still baked.

Warnings regarding preshadows can be ignored as they are not relevant when using Virtual Shadow Maps.

Enabling One File Per Actor

Converting Sublevels

Using OFPA With Source Control

In previous versions of Unreal Engine, when you wanted to make changes to one or more Actors inside a Level, you needed to check the file out of source control. This locked other team members out of that file until your work was complete, slowing down the development process since only one person could work on a file at a time.

One File Per Actor (OFPA) reduces overlap between users by saving data for instances of Actors in external files, removing the need to save the main Level file when making changes to its Actors.

The One File Per Actor feature is only available in the Editor. All Actors are embedded in their respective Level files when cooked.

One File Per Actor is enabled by default when using World Partition. The use of OFPA outside of a World Partition Level is currently considered Experimental and is disabled by default. To enable OFPA outside of World Partition:

From the main menu, go to Edit > Editor Preferences.

From the sidebar, select Experimental.

Locate the Tools section and enable the check box for One File Per Actor.

Enabling One File Per Actor

The One File Per Actor feature is designed to be granular and can be used in two different ways.

The first method is to enable OFPA manually on individual Actors from the Details panel.

In some cases, you may want to enable OFPA for one Actor at a time. To do this, search for the Packaging Mode option in the Details panel, and select External from the dropdown menu.



Enabling OFPA for a single Actor.

After selecting this option, you will be asked if you want to enable the feature for all the Actors in the Level. Select Yes to convert all the Actors in the Level to OFPA or No to only enable it for the selected Actor.

You will need to save the newly created external packages for the Actor and the Level. Afterward, you won't need to save the Level again if you modify the Actor.

The second method is to enable One File Per Actor for use with the entire Level.



Enabling OFPA for a Level.

To do this, follow the steps below:

Open the World Settings panel. From the main menu, go to Window > World Settings.

Navigate to the World section of the panel and enable the checkbox next to Use External Actors.

After you enable this option, save the Level.

You will be asked if you want to convert all Actors to external packaging. Select Yes to complete the conversion to OFPA.



Click Yes to convert all the Actors in the Level.

Converting Sublevels

It is important to note that only the current Level will be converted to OFPA when you activate the Use External Actors option for your Level. To convert any of your sublevels, you must load them and enable the Use External Actors for each of them, as described above. Since this may be an issue if your Level contains several sublevels, you can use a commandlet to convert a Level and its sublevels automatically.



A breakdown of the commandlet.

Follow the steps below to use the commandlet:

Open a Command Prompt window.



At the prompt, navigate to the location of the UnrealEditor.exe file. For example: C:\Builds\Home_UE5_Engine\Engine\Binaries\Win64.



Next, begin typing the command. Start with the name of the .exe file that will run the commandlet, UnrealEditor.exe.

Add the name of the commandlet and the following arguments:

-run="ConvertLevelsToExternalActorsCommandlet" is the name of the commandlet.

-nosourcecontrol tells the commandlet to not use source control.

-convertsublevels tells the commandlet to convert any sublevels the map may have.



Finish the command with the location of the Level: "/Game/Maps/TestMaps/ExternalActors/MasterMap" In this example, Game is the name of your project and MainMap is the name of the map you wish to convert.



Press Enter to run the commandlet. It will then convert the Level and any sublevels to OFPA.

Using OFPA With Source Control

While working in your source control application, you will notice that external Actor file names are encoded. To address this issue, you can view and validate the contents of a changelist before you submit it using the View Changelist window.



An existing changelist for a level that uses OFPA.

This window displays existing changelists and the files they contain. For external Actors, you can see the Actor names, Level paths and Asset types, rather than the encoded filenames.

With changelist support built into the Editor, you can validate the contents of your changelists before you submit them to source control. This is required due to the added complexity that OFPA brings to your projects. For example, a user can check out multiple files and only submit some of them, possibly leaving dangling references.

For more information on using source control in Unreal Engine, see In-Editor Source Control.

When using OFPA, content and Actor files should be submitted to source control from within the Editor.

Changelist support is only available when using Perforce as your source control provider.

Unreal Engine 5 is a powerful engine able to render massive open worlds full of complex flora and fauna. The Open World Tools can be used to procedurally fill large spaces with Static Mesh assets to create outdoor spaces that feel natural and alive.



How to render Static Mesh or Actor Foliage on the surfaces of other geometry for creating ground cover effects.



Learn how to add Grass textures to a landscape.



A listing of properties and descriptions for the Open World tools.



A collection of tips and tricks about how to get the most out of the Open World Tools.



How to set up and use the Procedural Foliage tool.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Foliage Edit Mode

Foliage Mode Panel

Foliage Types

Using Foliage Mode

Foliage Tools

Brush Options

Filter Settings

Culling Settings

LOD Settings

Lighting

Foliage Scalability

Using Foliage with World Partition

Adding Foliage to a Landscape

Reattaching Foliage Instances

Foliage Mode is a set of tools that enables you to quickly paint or erase sets of Static Meshes or Actor Foliage on filter-enabled Actors and geometry. Using this mode, it is possible to populate a large outdoor environment with foliage in a short amount of time.



Foliage can quickly add detail to any outdoor environment.

For examples of the Foliage tool in action, see the Foliage section of the Landscapes Content Examples project.

Foliage Edit Mode

To use the Foliage tool, click the Foliage option (Shift+3) in the Modes dropdown menu.



This will open the Foliage panel.

Foliage Mode Panel



Numbers

Description

1

Tools Palette

2

Brush Options

3

Filter Options

4

Foliage Palette

5

Foliage Details

Foliage Types



Open the Add Foliage Type dropdown menu to add the following:

Foliage Type

Description

Actor Foliage

Foliage type that places Blueprint or Native Actor instances in the scene. High densities of foliage can cause performance issues.

Static Mesh Foliage

Foliage type that uses mesh instancing.This type is best for non-destructive foliage.

Static Meshes placed with Foliage Edit Mode are automatically grouped together into batches that are rendered using hardware instancing, where many instances can be rendered with only a single draw call, while Actor Foliage comes at the same rendering cost as placing normal Actors into a scene.

Using Foliage Mode

Foliage Mode is a collection of tools that are used to paint foliage directly on to a Landscape or other filter-enabled Actor.

Foliage Tools



Tool

Description

Select

Selects individual Foliage Instances. You can select multiple Foliage meshes by holding down the Ctrl button.

All

Selects all Foliage Instances.

Deselect

Clears the current selection.

Invalid

Selects any invalid Foliage Instances.

Lasso

Selects any Foliage Instances of the selected Foliage type when painted over with the brush.

Paint

Paints instances of the selected Foliage type. Erase instances of the selected Foliage type by holding down the Shift key when painting.

Reapply

Selectively changes parameters for Foliage Instances already placed in the world. Use as follows:

Select the Reapply tool and then select the Foliage type you want to apply changes to in the Mesh List.

In the Foliage Details section, make your changes.

Paint the changes on to the Foliage Instances in the level.

Single

Paints a single instance of the selected Foliage type.

Fill

Fills the selected target with Foliage Instances.

Erase

Erases the selected Foliage type when painted over with the brush.

Remove

Removes the selected Foliage Instances.

Move

Moves the selected Foliage Instances to the current Level.

Brush Options

The Brush Options section is context sensitive and contains one or more of the following:



Option

Description

Brush Size

Adjusts the size of the foliage brush.

Point Density

Adjusts the density of the foliage affected by the selected tool. This is a multiplier of the Density property located in the selected foliage type's details.

Erase Density

Adjusts the density of the foliage that is left behind when erasing with the Shift key held.

Single Instance Mode

When enabled, paints a single foliage instance at the cursor location. Can be used in two modes:

All Selected: Places a single instance of all selected foliage types.

Cycle Through Selected: Cycles through placing a single instance of each selected foliage type, placing only one type with each mouse click.

Place in Current Level

When enabled, places instances of the selected foliage types in the current level. Otherwise places the instances of the selected foliage types in the level containing the mesh or Actor being painted on.

Filter Settings

Using the Filters section, you can control which surfaces the selected tool affects and which foliage types are currently active. This is also the section of the menu where new foliage types are added.



Option

Description

Landscape

Places the selected foliage types on to Landscapes.

Static Mesh

Places the selected foliage types on to Static Meshes.

BSP

Places the selected foliage types on to BSP geometry.

Foliage

Places the selected foliage types on to other blocking foliage geometry.

Translucent

Places the selected foliage types on translucent geometry.

Mesh List

Area in which Static Meshes and Actor Foliage used as foliage are placed.

Placing the mouse pointer over a foliage type displays a checkbox that enables or disables that foliage type when using a tool.

Clicking one or more foliage types displays their details in the Foliage Details located below the Mesh List area.

Foliage Details

Area displaying the details of the selected foliage types. Contains a variety of properties for customizing the behavior of the Static Mesh or Actor Foliage.

For more information on adding foliage types to the Mesh List, see Adding Foliage to a Landscape Actor

Culling Settings

Foliage instances are rendered as clusters in a single draw call and each cluster is either rendered or not rendered based on occlusion. Setting a value in the End Cull Distance parameter in the foliage details causes the clusters to be culled beyond that distance. However, this will cause groups of meshes to disappear abruptly as the entire cluster goes out of range.

This can be reduced by adding a Start Cull Distance parameter and then setting up the Material appropriately. In the vertex shader, a per-instance fading factor is calculated, which goes from 1.0 at the start distance to 0.0 at the end distance. This is accessible in the Material using a PerInstanceFadeAmount node. When connecting that to an opacity or masking value, you can use it to fade instances over a distance before they reach the Cull Distance End and are removed from rendering. Lowering the value of the FadeMultiplier parameter will increase the speed of the fade. A value of zero will make your foliage invisible at any distance.

The example Material below multiplies the Material mask by the fading factor to thin out the foliage mesh's leaves until they completely disappear.



Nanite-enabled meshes are not affected by culling distance and instance fading.

LOD Settings

Static Mesh LOD is supported for foliage. There are a few caveats:

You should ensure your Static Mesh has only one entry in the Elements array (visible under LOD0).

Light and shadow maps are shared between all LOD levels, so all LODs need to use the same unwrapping.

Currently, the entire cluster of instances change LODs simultaneously. We may add support for distance-based fading per instance in the future.

Lighting

Shadow and light maps are generated individually by Lightmass as needed for each instance, and these are tiled together for each precomputed batch. There are several settings on the Static Mesh that should be checked for precomputed lighting to operate well with instanced foliage. Lightmass is less forgiving when generating shadow maps for instanced meshes, and incorrect settings could lead to black meshes after rebuilding lighting.

Light Map Coordinate Index: This must be set to a valid UV channel that has a unique UV unwrapping. The Static Mesh Editor's Generate Unique UVs feature, which you can access from the Window menu, can quickly generate a unique unwrapping.

Lightmap Resolution: This must be a small enough number so that all the shadow maps for instances in a single cluster (by default 100) can be tiled together without exceeding the maximum texture resolution (4094x4096).

Foliage Scalability

Foliage Static Meshes can use the Scalability System to increase or decrease the amount of Foliage Instances that are currently being rendered on screen.

To use this functionality within your project:

Navigate to the Foliage Mesh List and select a foliage type.



In the Foliage Details, locate the Scalability section.



Select the checkbox for Enable Density Scaling.



You can now control the density of the foliage being rendered during runtime with the command foliage.DensityScale.

Below, you can see the density of the Foliage changes as the foliage.DensityScale setting is set to 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0.

Drag the slider to adjust the foliage.DensityScale setting from 0.1 to 1.0.

) )

Using Foliage with World Partition

In a World Partition map, the default grid size for Foliage Instances is 256 meters. This is separate from the World Partition grid size.

To change the default size of the Instanced Foliage Grid for new maps:



Open the Project Settings by opening the Edit menu and selecting the Project Settings option.

In the search box, search for Foliage.

Change the value of the Instanced Foliage Grid Size to your desired value in centimeters. In the above example, 25600 centimeters is equal to 256 meters.

The default grid size can be changed for existing maps using the World Partition Builder Commandlet:



To change the default grid size for Foliage Instances:

In Windows, open a Command Prompt window.



At the prompt, begin by navigating to the location of the UnrealEditor.exe executable file. In the above example: c:\Builds\Home_UE5_Engine\Engine\Binaries\Win64.



Next, begin the command with the name of the .exe file that will run the commandlet, UnrealEditor.exe.

Add the name of the project. Here, QAGame.



Add the name of the target map.



Finish the command with the name of the commandlet and the following arguments:

-run=WorldPartitionBuilderCommandlet is the name of the commandlet.

-Builder=WorldPartitionFoliageBuilder is the name of the builder within the commandlet.

-NewGridSize is the new value of the Instanced Foliage Grid in centimeters. In the example, a value 51200 is equal to 512 meters.



Press Enter and the commandlet will change your Foliage Instance Grid setting for the designated map.

Adding Foliage to a Landscape

Painting one or more types of foliage directly on to a Landscape Actor is an excellent way to quickly add detail to any outdoor environment.



Start by creating a new Landscape Actor if your level does not already have one. Sculpt some hills to create a bit of contrast. For more information on creating and working with Landscape Actors, see Landscape Quick Start Guide.



Open the Modes drop down and select the Foliage mode. Alternatively, you can use the hotkey Shift + 3.

In the Content Drawer, navigate to the location of a Static Mesh that you would like to use as a foliage type, such as this Static Mesh Cube. Click and drag the Static Mesh from the Content Drawer to the Mesh List in the Foliage panel.



Select the Paint tool. Adjust the Brush Size in the Brush Options to 128. Adjust the Paint Density to 0.3.



Select the Static Mesh in the Mesh List. Under the Painting section of the Foliage Details, change the Radius value to 100. In this example, this ensures that instances of the cube that will be painted on the Landscape do not overlap.



Next, adjust the Min value of the Scale X to 0.4 and the Max value to 0.8. This will create some variety in sizes when the foliage is painted.



In the viewport, click and hold the LMB to paint foliage across the Landscape.



Reattaching Foliage Instances

There may be times when Foliage Instances can become detached from their base component. For example, when the foliage placement is fine but the base Landscape needs to be changed.

To reattach the foliage to the underlying component, follow these steps:

While in Foliage Mode, select the Foliage Instances you want to reattach.

In the viewport, move the selected instances above the target component.

Press the End key to snap the foliage to the ground. This will reparent the Foliage Instances to the target component. The foliage will also align to the component based on the component's normal if they were originally placed using the Align to Normal option. This setting is located in the Placement section of the Foliage type's Details.

1 - Prerequisites

2 - Initial Level Setup

3 - Grass Tool Actor Creation and Setup

4 - Landscape Materials and the Grass Tool

5 - Using the Grass Tools

6 - On Your Own

Overview

In this Quick Start guide, we will take a look at how you can set up and apply a grass texture to a landscape. Over the course of this Quick Start tutorial you will learn how to create, set up, and spawn static meshes to make your Landscape appear covered in thick grass. You will be introduced to key properties and settings that will help you shape your virtual grasslands to fit your project's needs.



Click image for full size.

You will also learn about the Actors and properties required for a grassy-looking result to function correctly and deliver the results you want. When you have completed this Quick Start, you will have a new level that should look similar to the image above.

Currently, the Grass system will only work with the Landscape Terrain Actor. Trying to use the Grass system to spawn grass on any other Actor type will not work.

1 - Prerequisites

Download the Open World Demo Collection content pack as some of the content from the collection will be used in the following Quick Start. Once the Open World Demo Collection is downloaded, add it to the project that you are using to follow along with this Quick Start by doing the following:

From the Epic Games Launcher in either the Learn or Marketplace tab, locate and then download the Open World Demo Collection.



Click image for full size.

Go the the Library section of the launcher and under Vault section locate the Open World Demo Collection.



Click image for full size.

Click on the Add to Project button.



Click image for full size.

A list of projects that you can add this to will appear. Select the project that you are using to follow along with this Quick Start and then press the Add to Project button.



Click image for full size.

2 - Initial Level Setup

Now, we will create a new level and Landscape terrain so that we have something on which to apply the grass.

Create a new level that uses the blank Default template as a base.



Click image for full size.

Add a new Landscape Actor to the level. In the Main Toolbar, click the Modes button, and select Landscape to display the Landscape panel and toolbar, and then click on the Create button.



Click image for full size.

To help better show off the Grass Tool, we are going to add a some noise to our Landscape terrain so it is not completely flat. In the Landscape toolbar Sculpt tab, click Noise from the tool list. Set the Noise properties with the following values.



Click image for full size.

Property Name

Value

Additional Details

Brush Size

65536.0

This gives us a brush that is big enough to effect the entire Landscape terrain at once.

Tool Strength

0.01

Since we only want a very subtle effect, set the Tool Strength very low and add more intensity by painting more.

Noise Scale

256

Making the Noise Scale bigger makes the noise look smoother and more natural when applied to the Landscape.

Position the Landscape Brush in the viewport so that it covers the entire Landscape terrain. Click the Left Mouse Button 3 to 4 times to add some very subtle noise to the Landscape terrain.

Exit Landscape mode. Click the Modes button, and choose Select to display the Place Actors panel.



Click image for full size.

When completed, you should have something that looks similar to the following image.



Click image for full size.

The Grass system works on a completely flat Landscape terrain. The above modification to the Landscape was done purely for artistic reasons, to help show the final result.

3 - Grass Tool Actor Creation and Setup

We will create the required Actors and Materials the Grass Tool needs to function correctly. We will continue to work with the the level that was created in the last step.

Create a Landscape Grass Type: right-click in the Content Browser. From the displayed context menu, go to Foliage > Landscape Grass Type and name it Grass_00.



Click image for full size.

Open up the Landscape Grass Type and add a new item to the Grass Varieties array: double-click on Landscape Grass Type and once opened, press the Plus icon that is to the right of the Grass Varieties name.



Click image for full size.

Inside of the Landscape Grass Type Actor look for the Grass Mesh section, click on the input box that says None and enter SM_FieldGrass_01 as the search term, then click on the SM_FieldGrass_01 to load it as the Grass Mesh.



Click image for full size.

With the Static Mesh added we need to set the following properties to ensure that we are spawning enough grass mesh and that those meshes are randomly rotated and aligned to the Landscape terrain.



Click image for full size.

Property Name

Value

Additional Details

Grass Density

400.0

Because we want this to look like grass, we must spawn a lot of Static Meshes to make the Landscape appear densely covered in grass.

Use Grid

Enabled

To make the Static Meshes look more naturally placed, this offset is their placement position.

Random Rotation

Enabled

Giving the Static Meshes used for the plants and grasses a random rotation makes sure that the same side of the Static Mesh used is not seen all the time, adding to the visual variety of the scene.

Align to Surface

Enabled

This makes sure that the Static Mesh used conforms to the surface of the Landscape terrain.

4 - Landscape Materials and the Grass Tool

Before we can begin to use the Grass Tools we first have to create a Material that can work with both the Landscape terrain and the Landscape Grass Type. We will cover how to set up this Material, as well as how to link it so that it will work with the Landscape Grass Type.

If you would like to have a more in-depth look at how the Landscape terrain works in UE5, refer to the Landscape pages for more information.

Create a new Material for our Landscape Terrain by right-clicking in the Content Browser, then selecting the Material & Textures option from the Create Basic Asset section, and name the new Material, MAT_GT_Grass.



Click image for full size.

Open up the MAT_GT_Grass Material by double-clicking on the Material inside of the Content Browser, then add the following two Textures from the Open World Demo Collection to the Material Graph.

T_AlpinePatch001_D_alt_R

T_GDC_Grass01_D_NoisyAlpha



Click image for full size.

Using the Palette search function, search for the Material Expression nodes listed below. Once you locate a required Material Expression node, select it in the Palette and then drag it into the Material Graph.

Material Expression Name

Amount

Additional Details

Landscape Layer Blend

1

To make the Landscape terrain look more realistic you will often need to blend and paint multiple together or separately and that is what the Landscape Layer Blend allows you to do.

Landscape Layer Sample

1

This Material Expression allows the Material and the Landscape to talk to one another to ensure the right Static Mesh is used whenever a certain Landscape layer is painted.

Landscape Grass Output

1

This enables the Landscape terrain to be able to spawn the Grass Types based on the setup in the Landscape Material.



Click image for full size.

If you are unfamiliar with how the UE5 Material Editor works or would just like more information about it, check the official Unreal Engine Material documentation for more information on all things related to Materials.

Select the Landscape Layer Blend node and under the Details panel in the Layers section and add two new Layers to it by clicking the Plus icon 2 times.



Click image for full size.

Once 2 layers have been added, set the Layer Name of one to Grass and set the Layer Name of the other one to Rock also setting the Preview Weight to 1.0 for each.



Click image for full size.

Connect the T_AlpinePatch001_D_alt_R Texture to the Layer Rock input on the Landscape Layer Blend node then connect the T_GDC_Grass01_D_NoisyAlpha to the Layer Grass input finally connect the Output of the Landscape Layer Blend node into the Base Color input on the Main Material Node, Mat_GT_Grass.



Click image for full size.

In the Content Browser, select the Grass_00 Landscape Grass Type that was created in the last step.

In the Material under the Grass Type option, press the Arrow icon to load the Actor that is currently selected in the Content Browser.



Click image for full size.

Select the Landscape Layer Sample node under the Parameter Name input Grass for the name and connect the Output from the Landscape Layer Sample to the input of the Landscape Grass Output node.



Click image for full size.

When completed you should have a Material that looks like the following. As always, do not forget to press the Apply and Save buttons to compile and save the Material.



Click image for full size.

5 - Using the Grass Tools

In order to see the Grass system in action, we need to apply the Material that was created in the last step to the Landscape and then use the Landscape painting tools to define where we want the grass to be spawned. In the following section, we will go over how to apply our Material to the Landscape Terrain, then how to use the Landscape Painting Tools to define areas where grass should spawn. We will continue to work in the level that was created in the last step.

Select the Landscape Actor that was placed in the level by clicking on it in the viewport.



Click image for full size.

Locate the MAT_GT_Grass Material in the Content Browser and click on it to select it.

On the Landscape Terrain under the Details panel in the Landscape Material section, press the Arrow icon to apply the MAT_GT_Grass Material to the Landscape Terrain.



Click image for full size.

In the Main Toolbar, click the Modes button, select Landscape mode. From the Landscape toolbar, click on the Paint tab to go into Paint mode.



Click image for full size.



Click image for full size.

Under the Target Layers section, add a new Layer Info by pressing the Plus icon on the far right of the layer name.



Click image for full size.

When prompted, select the Weight-Blended Layer (normal) option, then select a location to save the new Layer Blend in the Content Browser. Make sure that you create Layer Info for both the Rock and the Grass.

Select the Grass Target Layer, then hold down the Left Mouse Button inside the viewport to begin painting the Grass Material to the Landscape Terrain. For this step, try to completely cover the Landscape, giving you results that look like this.



Click image for full size.

Depending on the power of your development PC, when you start to paint on the Landscape the editor might become unresponsive as the grass is spawned. This is normal behavior as the grass is dynamically spawned after you have finished painting. Turning down the Grass Density in the Landscape Grass Type while working, then putting it back up to the desired level when done, is a great way to help mitigate this as much as possible.

To remove grass from the Landscape Terrain, select the Rock Target Layer then inside of the viewport hold down the Left Mouse button to begin replacing the grass Texture with the rock Texture.



Click image for full size.

Adjusting the Brush Size and Tool Strength will help to better define how the grass is placed or removed while painting on the Landscape.

6 - On Your Own

Now that you have seen the power that the Grass tool offers, try using the tools listed below in conjunction with what you have just learned to make a level that looks like the following image:



Use the Procedural Foliage Tool Tool to make the Landscape look like it is densely covered in grass, flowers and bushes.

Define the look and feel of the Landscape terrain using the Landscape Sculpt tools to add features such as hills, mountains and lakes.

Give the surface of the Landscape more visual variety and detail by creating a Landscape Material that has multiple Textures that can be painted on the Landscape terrain.

Adjust the Directional Light to make the level lighting resemble lighting that happens in the early morning or late afternoon.

Set up the level lighting to use a completely dynamic based lighting solution that will make use of dynamic shadows as well as Ray Traced Distance Field Soft Shadows.

Try using the Foliage System tools to remove or tweak the placement, rotation and scale of the Foliage meshes that are placed by the Procedural Foliage tool so that you can get the exact look you are going for.

Show off your creation to others by using a Camera in conjunction with Sequencer to render out a video of your level for you to share with the world.

Overview

Foliage Type

Mesh

Placement

Procedural

Instance Settings

Scalability

Landscape Grass Type

Grass Varieties

Procedural Foliage Spawner

Procedural Foliage Simulation

Overview

This page contains a reference listing of properties you will find while working with the Open World Tools.

Foliage Type

Mesh



Click image for full size.

Property

Description

Mesh

Defines which Static Mesh will be used.

Component Class

The component class to use for foliage instances. You can make a Blueprint subclass of FoliagedInstancedStaticMeshComponent to implement custom behavior and assign that class here.

Override Materials

Material overrides for foliage instances.

Placement



Click image for full size.

Property

Description

Z Offset

Specifies a range from minimum to maximum of the offset to apply to a foliage instance's Z location.

Align to Normal

Whether foliage instances should have their angle adjusted away from vertical to match the normal of the surface they're painted on. If AlighnToNormal is enabled and RandowYaw is disabled, the instance will be rotated so that the +X axis points down-slope.

Random Yaw

If selected, foliage instances will have a random yaw rotation around their vertical axis applied.

Random Pitch Angle

A random pitch adjustment can be applied to each instance, up to the specified angle in degrees, from the original vertical.

Ground Slope Angle

Foliage instances will only be placed on surfaces sloping in the specified angle range from the horizontal.

Height

The valid altitude range where foliage instances will be placed, specified using minimum and maximum world coordinate Z values.

Landscape Layers

If a layer name is specified, painting on Landscape will limit the foliage to areas of Landscape with the specified layer painted.

Collision with World

If checked, an overlap test with existing world geometry is performed before each instance is placed.

Procedural



Click image for full size.

Property

Description

Collision Radius

The CollisionRadius determines when two instances overlap. When two instances overlap a winner will be picked based on rules and priority.

Shade Radius

The ShadeRadius determines when two instances overlap. If an instance can grow in the shade this radius is ignored.

Num Steps

The number of times we age the species and spread its seeds.

Initial Seed Density

Specifies the number of seeds to populate along 10 meters. The number is implicitly squared to cover a 10m x 10m area.

Average Spread Distance

The average distance between the spreading instance and its seeds. For example, a tree with an AverageSpreadDistance 10 will ensure the average distance between the tree and its seeds is 10cm.

Spread Variance

Specifies how much seed distance varies from the average. For example, a tree with an AverageSpreadDistance 10 and a SpreadVariance 1 will produce seeds with an average distance of 10cm plus or minus 1cm.

Seeds Per Step

The number of seeds an instance will spread in a single step of the simulation.

Distribution Seed

The seed that determines placement of initial seeds.

Can Grow in Shade

If true, seeds of this type will ignore shade radius overlap tests with other types.

Spawns in Shade

Whether new seeds are spawned exclusively in shade. Occurs in a second pass after all types that do not spawn in shade have been simulated. Only valid when CanGrowInShade is true.

Max Initial Age

Allows a new seed to be older than 0 when created. New seed will be randomly assigned an age in the range[0,MaxInitialAge].

Max Age

Specifies the oldest a seed can be. After reaching this age the instance will still spread seeds, but will not get any older.

Overlap Priority

When two instances overlap we must determine which instance to remove. The instance with a lower OverlapPriority will be removed. In the case where OverlapPriority is the same regular simulation rules apply.

Procedural Scale

The scale range of this type when being procedurally generated. Configured with the Scale Curve.

Scale Curve

Instance scale factor as a function of normalized age(i.e. Current Age / Max Age). X = 0 corresponds to Age = 0, X = 1 corresponds to Age = Max Age. Y = 0 corresponds to Min Scale, Y = 1 corresponds to Max Scale.

External Curve

For and external curve.

Instance Settings



Click image for full size.

Property

Description

Mobility

Mobility property to apply to foliage components.

Cull Distance

The distance where instances will begin to fade out if using a PerInstanceFadeAmount Material node. 0 disables. When the entire cluster is beyond this distance, the cluster is completely culled and not rendered at all.

Cast Shadow

Controls whether the foliage should cast a shadow or not.

Affect Dynamic Indirect Lighting

Controls whether the foliage should inject light into the Light Propagation Volume. This flag is only used if CastShadow is true.

Affect Distance Field Lighting

Controls whether the primitive should affect dynamic distance field lighting methods. This flag is only used if CastShadow is true.

Cast Dynamic Shadow

Controls whether the foliage should cast shadows in the case of non precomputed shadowing. This flag is only used if CastShadow is true.

Cast Static Shadow

Whether the foliage should cast a static shadow from shadow casting lights. This flag is only used if CastShadow is true.

Light Map Resolution

Overrides the lightmap resolution defined in the static mesh.

Collision Presets

Select collision presets. You can set this data in Project Settings.

Custom Navigable Geometry

Value

Description

No

Primitive doesn't have custom navigation geometry, if collision is enabled then its convex/trimesh collision will be used for generating the navmesh.

Yes

If primitive would affect navmesh, DoCustomNavigableGeometryExport() should be called to export this primitive's navigable geometry.

Even if not Collidable

DoCustomNavigableGeometryExport() should be called even if the mesh is non-collidable and wouldn't normally affect the navmesh.

Dont Export

Don't export navigable geometry even if primitive is relevant for navigation (can still add modifiers).

Cast Shadow as Two Sided

Whether this foliage should cast dynamic shadows as if it were a two sided material.

Receives Decals

Whether the foliage receives decals.

Use as Occluder

If enabled, foliage will render a pre-pass which allows it to occlude other primitive, and also allows it to correctly receive DBuffer decals. Enabling this setting may have a negative performance impact.

Scalability



Click image for full size.

Property

Description

Enable Density Scaling

Whether this foliage type should be affected by the Engine Scalability system's Foliage scalability setting. Enable for detail meshes that don't really affect the game. Disable for anything important. Typically, this will be enabled for small meshes without collision(e.g. grass) and disabled for large meshes with collision (e.g. trees).

Landscape Grass Type

Grass Varieties



Click image for full size.

Property

Description

Grass Varieties

Grass Varieties.

Grass Mesh

Grass Mesh.

Use Grid

If true, use a jittered grid sequence for placement, otherwise use a halton sequence.

Placement Jitter

Placement Jitter.

Start Cull Distance

The distance where instances will begin to fade out using a PerInstanceFadeAmount material node. 0 disables.

End Cull Distance

The distance where instances will have completely faded out when using a PerInstanceFadeAmount material node. 0 disables. When the entire cluster is beyond this distance, the cluster is completely culled and not rendered at all.

Min LOD

Specifies the smallest LOD that will be used for this component. If -1(default), the MinLOD of the static mesh asset will be used instead.

Scaling

Specifies grass instance scaling type.

Scale X

Specifies the range of scale, from minimum to maximum, to apply to a grass instance's X Scale property.

Scale Y

Specifies the range of scale, from minimum to maximum, to apply to a grass instance's Y Scale property.

Scale Z

Specifies the range of scale, from minimum to maximum, to apply to a grass instance's Z Scale property.

Random Rotation

Whether the grass instances should be placed at random rotation (true) or all at the same rotation(false).

Align To Surface

Whether the grass instances should be tilted to the normal of the landscape(true), or always vertical(false).

Use Landscape Lightmap

Whether to use the landscape's lightmap when rendering the grass.

Procedural Foliage Spawner

Procedural Foliage Simulation



Click image for full size.

Property

Description

Random Seed

The seed used for generating the randomness of the simulation.

Tile Size

Length of the tile (in cm) along one axis. The total area of the tile will be TileSize * TileSize.

Num Unique Tiles

The number of unique tiles to generate. The final simulation is a procedurally determined combination of the various unique tiles.

Foliage Types

The types of foliage to procedurally spawn.

Foliage Type Object

The foliage type that will be spawned by the procedural foliage simulation.



Grass Tool Foliage Mesh Culling

Procedural Foliage Volume Based Masking

Texture Based Masking for the Grass Tool

Math Based Masking for the Grass Tool

Non Random Placement for the Grass Tool

In the following section we will be taking a look at some tips and tricks that you can use to push the Open World tools to their limits. The following tips and tricks come right from the Epic developers that used the Open World Tools to create the Kite Demo that was debuted at the 2015 Game Developers conference. Please keep in mind that the following is not meant to be a step by step tutorial but more of a high level look at what was done and how you could apply these techniques to your projects.

If you are looking for more basic information on how to use the Open World Tools check out the Procedural Foliage Quick Start or the Grass Tools Quick Start for more basic information on how to use these tools.

Grass Tool Foliage Mesh Culling

While you can adjust the culling of the Grass Tool to render Static Meshes extremely far in the distance be careful setting the options too high as you could run the risk of crashing your video card and/or UE5 editor session.

When using the Grass Tools in your projects you might notice that past a certain distance the Static Meshes that are used stop being displayed. This is called culling and it is an optimization method that can be used to help lessen the rendering demand for your project by stopping objects from being rendered past a certain distance from the camera. Inside of UE5 you can adjust the distance at which the Grass Tool stops rendering Static Meshes a number of different ways. The first way you can effect the distance at which the Grass Tool culls Static Meshes is to set the Start and End Cull Distance setting that can be found in the Landscape Grass Type Actor under the Grass Varieties section.



Click image for full size.

The image above shows the Culling settings used for the Field Grass Static Mesh that was used for some of the grass in the Kite demo. In the image below we compare the original settings of 6,500 with the new setting of 30,000 making the Static Mesh used for the Grass being rendered further out in the distance.





If you look closely at the comparison screen shots above you will notice that no matter how big you set the End Cull Distance number the Static Mesh that is used will still stop being rendered past a certain point. To make the Static Meshes render even further out you will need to input the following command into the UE5 Console followed by a decimal number.

The Foliage.MinimumScreenSize command will increase or decrease the size, in screen space, at which the Static Meshes will be culled. The reason size in screen space is used in conjunction with distance from the camera is to ensure that you do not accidentally render objects that are very small and very far away from the camera. You can consider this setting more of a catch all to ensure that your projects performance does not suffer in case someone accidently missed setting a certain meshes cull distance. To enter the command press the Tilde(~) or Back tick(`) key on the keyboard to open up the Unreal Console with in the UE5 Editor. When the Unreal Console is opened you should see something that looks like the image below open up at the bottom of the UE5 editor.



Click image for full size.

Input the following command into the console, Foliage.MinimumScreenSize 0.0001, and then press the Enter key to apply the command. After the Grass Maps rebuild, inside of the viewport you should now see the Static Meshes being used rendered further in the distance than before.



Click image for full size.

Here is a comparison image that shows the difference culling distance between the default setting of 0.0001 and a setting of 0.00000001.





Keep in mind that using values bigger than the default of 0.0001 could cause performance problems. If you do decide to increase the Foliage.MinimumScreenSize make sure you perform performance testing to ensure that your changes to culling do not have a huge impact on your projects overall performance.

Procedural Foliage Volume Based Masking

Having the ability to procedurally spawn an entire forest of trees can be a huge time saver, but what if you want to restrict certain trees to only spawn in certain areas? To accomplish this you could do a number of things like use multiple Procedural Foliage Volumes or use the Foliage tool to place the trees where you want. However, that adds a lot of complexity and upkeep to your project. Luckily, the Foliage Types have the option to restrict the placement of the Static Mesh that is assigned to them to a certain layer in the Landscape Material by allowing only that Foliage Type to spawn when that layer is exposed while painting.

No matter which method you use, you will always need to select the Procedural Foliage Volume in the level and click on the Resimulate button to update and see your changes.



Click image for full size.

The image below shows a very simple Landscape Material setup that will allow for three different Foliage Types to be used with three different Textures. Notice how each input in the Layer Blend is uniquely named. This is important because this name is how we associate which Landscape terrain layer the Foliage Type should be restricted to.



Click image for full size.

Once the Landscape Material has been setup, we now need to setup the Foliage Type so that it can be associated with the correct Landscape layer. In the image below you can see an example of how a Foliage Type needs to be setup to restrict the placement of the assigned Static Mesh to a specific layer in the Landscape Material.



Click image for full size.

To set this up for yourself, you will need to do the following inside of the Foliage Type:

Expand the Show Advanced arrow icon to expose the Landscape Layers option.

Press the plus sign icon that is to the right of the word elements to add a new entry in the array.

Input the name of the layer in the Landscape Material that you want to restrict this Foliage Type to.

Once you have the Material and Foliage Types setup, make sure to assign the Material to the Landscape terrain and then start to paint the Landscape as usual. When you are done painting, or if you just want to see what you have so far, select the Procedural Foliage Volume in the level and then press the Resimulate button to update and apply any changes. When completed, the foliage that was spawned will be confined to the Landscape Texture it is associated with like in the following image.



Click image for full size.

If we take a closer look at the image above, we can see that everything has been procedurally placed as expected but none of the spawned meshes intermix with one another. For example, the leaved trees only spawn where the grass Texture is applied to the Landscape. If you look closely, you will see that the same occurs with the bush and pine trees.

Texture Based Masking for the Grass Tool

One of the other methods for controlling where Foliage meshes can or cannot spawn is to use a Texture that acts as a mask telling the Open World Tools to either spawn or not to spawn a Foliage mesh in a specific area. The following image shows a very simple Material that demonstrates Texture based masking.



Click image for full size.

Starting at the far left of this image we have the World Position Scaling section. This is scaling the Mask Texture in world space so that it can be scaled big enough to fit the Landscape terrain. Moving to the left, we have the Mask Texture that is used to define where the foliage should be placed, as well as the blending of the two Landscape Textures. Here is a breakdown of what the different channels of the Mask Texture are used for:

Red Channel: This channel is used to define where the grass meshes should be spawned on the Landscape as well as to define how the Landscape base Textures should be blended.

Green Channel: This channel is used to define where the rock meshes should be spawned on the Landscape.

Finally, on the far right of the image we have the Main Material node and the Grass Output. The Main Material node is setup in the same way as any other standard Material. The Grass Output, however, is setup in a similar manner to how you would do Texture based masking, the key difference being that you are going to use the portion of the Material that is masked or unmasked to spawn or not spawn Static Meshes (instead of just showing a different Texture.) When this Material is applied to a Landscape in UE5 you should get results that look similar to the following image minus the mask Texture that was placed in the corner to show which mask color was doing what to the Landscape.



Click image for full size.

In the image above, the grass Static Mesh, for the most part, are spawned only in areas that use the red channel of the mask Texture, while the rocks use the green channel of the mask Texture to spawn. As you might have noticed, the grass and rocks are not entirely contained within the area of the mask Texture that spawns them. This is expected behavior as the placement of the Static Meshes can be jittered and offset to make things look more natural.

Math Based Masking for the Grass Tool

While using a Texture for masking can be convenient and quick, there could be times where you can not afford the extra Texture data due to performance concerns or you just do not need that much control over the placement. In cases like this you can power the placement using Math functions created in the Material Editor in place of Textures.



Click image for full size.

In the image above, we have taken the Material from the last example but changed how the grass and rocks are spawned. For this example the grass and rocks are spawned in a checkerboard pattern by using the Checker Pattern Material Function to control placement. The One Minus was added to the rocks so that the rocks will spawn in the parts that the grass does not spawn in. When applied to the Landscape, you will see something that looks like the following:



Click image for full size.

Non Random Placement for the Grass Tool

With the right adjustments, the Grass tool can also be used to simulate things like crops growing in a field. In the image below you can see an example of this type of behavior:



Click image for full size.

To get the Grass tool to function like this, make sure that Use Grid is checked, that Placement Jitter is set to 0, and Grass Density is set to something under 100. The following image shows how the Landscape Grass Type was set up to achieve the results you saw in the first image.



Click image for full size.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

1 - Creating Foliage Type Actors

2 - Telling the Spawner What to Spawn

3 - Tweaking Foliage Type Object Properties

4 - Using Multiple Foliage Type Objects

5 - Implementing Procedural Foliage Blocking Volumes

6 - On Your Own!

In this Quick Start tutorial we will take a look at how the Procedural Foliage Tool works. Over the course of this Quick Start tutorial you will learn how to create, set up, and spawn an entire forest's worth of trees inside of UE5 using only the Procedural Foliage tool. You will also be introduced to key properties and settings that will help you shape your virtual forest to fit your project's needs.



You will also be exposed to all of the required Assets and properties the Procedural Foliage tool requires to function correctly and deliver the results you want. When you have completed this Quick Start you will have a new level that should look similar to the image above.

Prerequisites

Before you can use the Procedural Foliage tools in your project, you must first enable them by doing the following.

From the Main Menu open the Edit menu then click on Editor Preferences.



Click image for full size.

Inside of the Editor Preferences right - click on the Experimental section.

Enable the Procedural Foliage option by clicking on the checkmark box next to the word Procedural Foliage.



Click image for full size.

You will also need to download the Open World Demo Collection content pack from the Unreal Engine Marketplace as some of the content from the collection will be used in the following Quick Start. Once the Open World Demo Collection is downloaded add it to the project that you are using to follow along with this Quick Start by doing the following.

From the Epic Games Launcher in the Marketplace locate and then download the Open World Demo Collection.



Click image for full size.

Go the Library section of the launcher and then under Vault section locate the Open World Demo Collection .



Click image for full size.

Click on the button that says Add to Project.



Click image for full size.

You will then be shown a list of projects that you can add this to, select the project that you are using to follow along with this Quick Start and then press the Add to Project button



Click image for full size.

1 - Creating Foliage Type Actors

In this step you will create a new Level, Landscape Terrain, and all of the Assets the Procedural Foliage Tool requires.

Create a new level using the Default Template as a base.



Click image for full size.

Add a new Landscape Actor to the level by first selecting Landscape in the Modes dropdown menu to open the Landscape Panel, and then clicking the Create button to add the Landscape Actor to the level.



Click image for full size.

Using a Landscape Terrain Actor quickly provides you with a very large area to spawn your forest on.



Click image for full size.

If you are not familiar with how Landscape Terrain works or would like to learn more, please refer to Landscape Outdoor Terrain for more information.

Create a new Procedural Foliage Spawner by right-clicking in the Content Browser, expanding the Foliage section, and then clicking on the Procedural Foliage Spawner.



Click image for full size.

Name the Procedural Foliage Spawner in this example PFS_Example or something similar.



Click image for full size.

Drag the Procedural Foliage Spawner from the Content Browser into the level and position it so that it is in the center of the level or at 0,0,200 in the X, Y, and Z axis.



Click image for full size.

Scale the Procedural Foliage Spawner to 100,100,10 in the X, Y, and Z axis to create a large area to spawn your forest in.



Click image for full size.

Now that we have our spawner, we need to give it some Foliage to spawn. To do this, right - click in the Content Browser expanding the Foliage section and then click on Static Mesh Foliage. Name the Static Mesh Foliage Tree_00 or something similar.



Click image for full size.

If you have not done so already, save your work and level by pressing the Save All button to save all content and the Save button to save the level. When prompted for a level name use the name PFT_00. At this point you should have something that looks similar to the image below.



Click image for full size.

2 - Telling the Spawner What to Spawn

In the following section we will cover how to set up the Foliage Type Actors to work with the Procedural Foliage Spawner. You will continue to work with the PFT_00 level that was created in the last step.

Open up the Procedural Foliage Spawner by double - clicking in the Content Browser.



Click image for full size.

Add a new item to the Foliage Types array by clicking the Plus Sign icon that is to the right of the Foliage Types menu option.



Click image for full size.

In the Content Browser, select the Tree_00 Static Mesh Foliage and drag it into the Foliage Type Object, or press the Arrow icon, to load the selected Static Mesh Foliage into the Procedural Foliage Spawner.



Click image for full size.

Open up the Tree_00 Static Mesh Foliage by double - clicking on it in the Content Browser.



Click image for full size.

At the top of the Tree_00 Static Mesh Foliage, locate the Mesh section and then click on the drop down menu that says None.



Click image for full size.

Locate the HillTree_02 Static Mesh from the Open World Demo Collection either by typing "HillTree_02" as the search term or by scrolling through the list, and load it by clicking on it.



Click image for full size.

Back in the viewport select the Procedural Foliage Spawner that was placed in the level and then expand the Procedural Foliage section under the Details panel.



Click image for full size.

Under the Procedural Foliage section click on the Resimulate button and you should now see the Procedural Foliage Spawner densely packed with tress like in the image below.



Click image for full size.

In order to see the proper results, you will need to click on Build in the Main Toolbar to rebuild the lighting every time you use the Resimulate button to create or alter the Procedural Foliage . This can take a long time due to the large number of static meshes involved.

3 - Tweaking Foliage Type Object Properties

Foliage Type Objects (both Static Mesh Foliage and Actor Foliage) come with a number of different properties that you can adjust to control anything from how the Foliage Type Objects are placed on other objects in the level to how the Foliage Type Objects will grow and spread throughout the Foliage Spawner. In the following section we will take a look at what properties are available in Foliage Type Objects and how you can manipulate these properties to get the results you desire. You will continue to work with the PFT_00 level that was used in the last step.

Open up the Tree_00 Static Mesh Foliage.

Expand the Placement section and make sure that both Align to Normal and Random Yaw are enabled.



Click image for full size.

The Placement section is where you can adjust how a Foliage Type Object's meshes are placed on objects in the level.

Under the Procedural section of the Static Mesh Foliage expand the Collision section and set the Shade Radius to 50.



Click image for full size.

The Collision section determines which Foliage Type Objects should be removed when two Foliage Type Objects are competing for the same spawn location or relative space. When a Virtual Seed's collision radius overlaps an existing collision or shade radius from another Foliage Type Object's Virtual Seed, one Virtual Seed will be replaced or killed based on which Foliage Type Object has the higher priority.

Select the Procedural Foliage Spawner that was placed in the level and under the Procedural Foliage section click on the Resimulate button.



Click image for full size.

Back in the Tree_00 Static Mesh Foliage collapse the Collision section and expand the Clustering section, then set Num Steps to 0, so that we get trees that are all the same size and age and then press the Resimulate button. When completed you should have something that looks similar to the image below.



Click image for full size.

Clustering uses a number of properties such as density, age, and proximity to help determine how the specified Foliage Type Object's mesh instances should be placed, grouped and spread around inside of the Procedural Foliage Spawner.

While we now have some space in between our trees, the overall density is still a little too high. To fix this, set the Initial Seed Density to 0.25 and then click on the Resimulate button.



Click image for full size.

As you can see, setting the Initial Seed Density to 0.25 greatly reduced the density of our forest because we are only growing and spreading trees for a single year. To fix this set the Num Steps back to 3, which will grow and spread the trees for 3 years, and then click on the Resimulate button.



Click image for full size.

Expand the Growth section then set the following parameters to the following settings.

Max Age: 20.0

Procedural Scale Max: 10.0



Click image for full size.

The Growth section allows you to adjust how a Foliage Type Object's mesh instances will grow and get bigger over time.

Finally in the Instance Settings under the Cull Distance option, set the Max value to 20,000 and then click on the Resimulate button. When completed you should have something that looks similar to the image below.



Click image for full size.

The Instance Settings allows you to adjust how a Foliage Type Object's mesh instances will be displayed in the level. Inside the Instance Settings you can set or adjust many different properties like Cull Distance, Shadowing, and Collision.

4 - Using Multiple Foliage Type Objects

Adding another species of tree to your virtual forest will greatly help to increase the realism and overall look and feel. Luckily, the Procedural Foliage Spawner allows for you to spawn multiple Foliage Type Objects resulting in one single Procedural Foliage Spawner being able to spawn an entire forest with a multitude of different trees. In the following section we will take a look at how you can set up a Procedural Foliage Spawner to work with multiple Foliage Types. You will be continuing to work with the PFT_00 level that was used in the last step.

Inside of the Content Browser select the Tree_00 Static Mesh Foliage and then press Ctrl + W on the keyboard to duplicate it using Tree_01 as the name.



Click image for full size.

Open the newly created Tree_01 Static Mesh Foliage and under the Mesh section change the mesh to the ScotsPineTall_01 Static Mesh.



Click image for full size.

Open up the Procedural Foliage Spawner from the Content Browser and expand the Foliage Types section.



Click image for full size.

Click on the Plus sign icon to add the option to input another Foliage Type Object.



Click image for full size.

In the Content Browser, select the Tree_01 Static Mesh Foliage and drag it into the Foliage Type Object, or press the Arrow icon, to load the selected Static Mesh Foliage into the Procedural Foliage Spawner.



Click image for full size.

Select the Procedural Foliage Spawner that was placed in the level and then click on the Resimulate button. When completed you should see something like the following image.



Click image for full size.

To make the forest look more interesting open up the Tree_01 Static Mesh Foliage and adjust the following parameters with the following values. The numbers and options that are listed below were selected because they will produce a forest that has interesting clustering and growth interaction with the Static Mesh Foliage instances that are already in use. However please feel free to experiment with these numbers and settings till you get something that suits your needs.

Num Steps: 4

Initial Seed Density: 0.125

Average Spread Distance: 100

Can Grow in Shade: Enabled

Spawns in Shade: Enabled

Max Age: 15

Overlap Priority: 1

Procedural Scale: Max 5.0

Once the settings have been adjusted click on the Resimulate button on the Procedural Foliage Spawner and you should now have something that looks similar to the image below.



Click image for full view.

5 - Implementing Procedural Foliage Blocking Volumes

The Procedural Foliage Blocking Volume is a Volume Actor that can be placed in a level and scaled to a desired size which will prevent the Procedural Foliage Spawner from spawning any Foliage Type Objects inside of the bounds of the Procedural Foliage Blocking Volume. In the following section we will go over how you can add a Procedural Foliage Blocking Volume to your level and use it to prevent Foliage meshes from spawning. You will be continuing to work with the PFT_00 level that was used in the last step.

First find the Procedural Foliage Blocking Volume by searching for it in the Place Actors panel using Proc as the search term.



Click image for full size.

Select the Procedural Foliage Blocking Volume and then drag it from the Place Actors panel into the level.



Click image for full size.

To stop foliage meshes from being spawned in the back portion of the Procedural Foliage Spawner move and scale the Procedural Foliage Blocking Volume using the following location and scale values.

Location X: 5430.0 cm

Location Y: -3900.0 cm

Location Z: 200.0 cm

Scale X: 41.75

Scale Y: 65.5

Scale X: 41.75



Click image for full size.

Now select the Procedural Foliage Spawner in the level and then in the Details click on the Resimulate button. When the Resimulate is completed you should now be missing the entire back section of trees that were intersecting with the Procedural Foliage Blocking Volume.



Click image for full size.

In the following image we can see the before and after results.

Image Number

Results

1:

Before Procedural Foliage Blocking Volume is added

2:

After Procedural Foliage Blocking Volume is added

6 - On Your Own!

Now that you have seen that power the Procedural Foliage tool offers, try using the tools listed below in conjunction with what you just learned about the Procedural Foliage tool to try and make a level that looks like the following image.



Try using Foliage Actors instead of Static Mesh Foliage.

Use the Grass Tool to make the Landscape look like it is densely covered in grass, flowers and bushes.

Define the look and feel of the Landscape terrain using the Landscape Sculpt tools add things like hills, mountains and lakes.

Give the surface of the Landscape more visual variety and detail by creating a Landscape Material that has multiple Textures that can be painted on the Landscape terrain.

Adjust the Directional Light to make the level lighting resemble lighting that happens in the early morning or late afternoon.

Set up the level lighting to use a completely dynamic based lighting solution that will make use of dynamic shadows as well as Ray Traced Distance Field Soft Shadows.

Try using the Foliage System tools to remove or tweak the placement, rotation and scale of the Foliage meshes that are placed by the Procedural Foliage tool so that you can get the exact look you are going for.

Show off your creation to others by using a Camera in conjunction with Sequencer to render out a video of your level for you to share with the world.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Enabling the Water System Plugin and Content

Additional Water Plugin Content

Getting Started

Essentials

Additional Resources

The Water system enables you to create rivers, lakes, and oceans that all interact and work together with your Landscape terrains using a spline-based workflow. The Water system unifies the shading and mesh rendering pipeline, with surfaces that support physics interactions and fluid simulation with gameplay, such as ripples caused by footsteps or the wake behind a boat moving through the water.

Enabling the Water System Plugin and Content

The Water system is a self-contained plugin that can be enabled/disabled depending on whether you need it for your project. The plugin enables the rendering and meshing system for water, and also provides example and default content for you to use.

To enable the Water system, use Edit > Plugins to open the Plugins browser. Search for the Water plugin and check its box to enable it.



Click image for full size.

Restart the editor for changes to take effect.

Additional Water Plugin Content

The Water plugin also contains some default materials and content that can be used in your own projects or for exploration. You can find it in the Content Browser under the Water Content folder.



Click image for full size.



Click image for full size.

If you do not see this folder in your Content Browser, select View Options (located in the bottom-right) and check the boxes next to Show Engine Content and Show Plugin Content.

In this folder, there are example maps and content to try on your own, such as:

Caustics generation

Fluid simulation

Physics simulation buoyancy Blueprints

Getting Started



An overview of how surface meshes and materials are used to render water.

Essentials



An overview of how to use the Water Waves Asset to drive wave simulation.



An overview of the Single Layer Water Material shading model used to render physically based water surfaces.

Additional Resources

Single Layer Water Shading Model

Water Surface Mesh

Water Zone

Water Mesh Level Of Detail Scaling and Tessellation

Water Mesh Tile Size, Extents and Far Distance

Water Materials and Underwater Post Processing

Water Body Actor Materials

River Water Body Material Transitions

Underwater Post Processing

Single Layer Water Material Shading Model

Creating Your Own Water Material

The Water system is made up of two key elements: an editable water surface, and a water surface material. These two elements determine how water in your project behaves and interacts with the objects it comes into contact with. This can mean something as simple as how the water material reflects and refracts light onto objects that come into contact with its surface. For gameplay, it can be how a character creates ripples in the water surface while moving through it, or how buoyant an object is as it floats on the surface of the water.

Water Surface Mesh

The Water system has its own spline-based meshing system that defines areas within the world that should contain water. It uses a Water Zone to set properties that apply to all Water Body Actors (rivers, lakes, and oceans) that are placed in the Level. The Water mesh primarily defines the quality and detail of the water surface being rendered.



Click image for full size.

You must place the Water Zone in a scene to generate the surface of a Water Body type in the Level. By itself, the Water Zone doesn't render a surface. Water Bodies use splines to define areas within the Level that represent rivers, lakes, and oceans. The splines define where water mesh tiles are drawn and rendered by the Water Zone. This is more efficient because it only renders a surface mesh that is visible within the current camera view.

When a Water Zone is in the scene, dragging and dropping a Water Body into the scene adds or removes tiles that represent the water surface. Because all Water Bodies use the same mesh to render water surfaces, they blend seamlessly together (see below). This also means you can have transitions between different types of water surfaces, such as a rapid river flowing into either a calm lake or a turbulent ocean.

Enable the Water Mesh wireframe view by using the console command r.Water.WaterMesh.ShowWireframe 1 to see how these transitions between different Water Bodies interact to create a seamless surface.

r.Water.WaterMesh.ShowWireframe 0 disable.

Water Zone

The Water Zone controls the quality of the surface mesh that makes up the tiles of the individual Water Bodies placed in the Level. The individual Water Bodies also have their own hard limit for size in the Level. It also provides additional options specific to the Ocean Water Body.



Click image for full size.

These settings can significantly impact performance when using highly tessellated surfaces and large extents.

Water Mesh Level Of Detail Scaling and Tessellation

Level of detail (LOD) or the water mesh tiles is handled by traversing a quadtree each frame to generate an optimized set of tiles that are visible on screen. Those tiles are then collapsed for each level of detail when possible, to apply more or less density where it matters most — nearest the current camera view.

Each level of detail is made up of a concentric circle around the camera view based on distance, where each lower level of detail is farther from the camera and contains half the number of vertices as the level that precedes it.

With traditional levels of detail geometry, such as with a Static Mesh, geometry quickly transitions from one level to another based on screen size, which can cause the mesh to have a noticeable transition as one level is switched with another. Because the Water system uses a mesh tile to represent its surface, as the levels of detail transition, they morph into and out of one another, such that four quads morph into a single quad when switching to a lower level of detail, or into 16 when switching to a higher level of detail (see the example below)





Example of a 4x4 quad grid morphing into a 2x2 grid, and back again.

Example of water LOD transition in Fortnite.

The Water Mesh Actor provides controls to explicitly define the scale for the level of detail and the amount of tessellation for mesh tiles. Each of those properties work independently of one another, but should be configured simultaneously to achieve a good balance between performance and the quality of the water surface.

The size radius of each concentric level of detail is controlled by the LODScale property. It sets the distance from the camera where the tiles should start morphing to lower levels of detail.

The Tessellation Factor sets the amount of quality you want the mesh tile to have for all Water Bodies placed in the level by increasing the number of vertices the tiles have. Lakes and Ocean Water Bodies benefit the most from a greater amount of tessellation, especially when there are waves with large peaks and low valleys.

When setting these properties, it's important to balance the following:

High quality up close where the player sees finer detail

Lower quality far away where it doesn't necessarily matter to the player

Performance cost for tessellation quality

Keep in mind that your water materials can also have fine detail that the water system doesn't need to handle through tessellation.

Enable visualization of water tiles by:

Using the Brush Wireframe View Mode in the Level Viewport. This is ideal when you don't have a lot of geometry in the scene, or only have water meshes that are visible.

Using console commands to render water meshes as wireframes:

r.Water.WaterMesh.ShowWireframe 1 displays all water meshes as wireframes.

r.Water.WaterMesh.ShowWireframeAtBaseHeight 1 displays all water meshes at their flat base height position.

Water Mesh Tile Size, Extents and Far Distance

The Water Mesh Actor provides options for defining the size of individual tiles that make up the Level's water mesh, defining how many tiles there are along each exist, and handles long distances for oceans where the sky meets the water.



Click image for full size.

The Tile Size property sets the size of the individual tiles that make up the water mesh. These are measured in the default world units. Increasing/decreasing the Tile Size scales all tiles that make up the water meshes in the Level.







Example Grid of Tile Size

Water Mesh Tile Size: 2400 (Default Size)

Water Mesh Tile Size: 1000

The Extent in Tiles property sets the number of individual tiles that make up the water mesh. The extents are measured from the center of the water mesh to the edge for the XY-axis.







Example Grid of Tile Extents

Extent in Tiles: 64 (Default Size)

Extent in Tiles: 32

The Far Distance is used to fill the space between the farthest tile used by the Extent in Tiles property and the horizon. This adds a low-vertex water mesh that creates the illusion of the Ocean Water Body tiles extending an indefinite distance.





Example Grid of Far Distance

Far Distance Water Mesh Enabled

This far-distance water mesh is located just below the Ocean Water Body base height position, so it limits clipping and avoids any seams that could become visible. It also uses a separate material that should be applied to the Far Distance Material assignment slot of the Water Mesh Actor. The material can be simple, and really only needs to match the color to create a seamless blend from the tiled water mesh.

Use the Far Distance Mesh Extent property to set how far (in world units) the simplified mesh extends.

The example scene below, using an Ocean Water Body, shows how the Water Body appears from ground level. Notice how the Water Body doesn't appear to reach the horizon line (left). The Far Distance properties of the Water Mesh Actor fill in this gap while creating a seamless look between the Water Body and the Far Distance Mesh.





From an aerial perspective, it is clearly visible where the highly tessellated water mesh ends. When using a color-matching Far Distance mesh, it can easily fill the scene and reduce performance impact while seamlessly matching the detailed water mesh.





A simplified Material Instance of the base water material, called Water_FarMesh, is available for use in the Water Content/Materials/WaterSurface folder of your Content Browser.

Water Materials and Underwater Post Processing

The Water system uses several different types of materials to handle rendering of the water surface and transitions between different types of Water Bodies, such as a river flowing into the ocean. The Water system also uses a Post Process Material to define the look below the surface of the water.

Each Water Body has a set of material assignment slots that can be used to override the preconfigured default water materials.



Click image for full size.

Water Body Actor Materials

Water Bodies for River, Lake, and Ocean all use the same material (Water_Material) as their base. It contains a set of switches and parameters specific to each Water Body type, so that a single source material can be used to drive all types of water being used. A Material Instance is created for each of the Water Body types (River, Lake, and Ocean), and each enables a switch that determines the available parameters that correspond to that Water Body type. This workflow maintains a consistent look and design across each of the Water Body type materials.

In the images below, you can see how parameters for float values, RGBA colors, and switches to enable and disable material paths are defined. Parameters become accessible through child material instances, where the parameters of the parent material can be overridden to change the look of the material.



Click image for full size.



Click image for full size.

Base Material with Switches and Parameters

Material Instance using the Override Switches and Parameters

Click image for full size.

Most material parameters are similar across the Water Body types using their Lake, Ocean, or River materials. The one exception is the River's material. The River material contains specific parameters that other Water Body materials don't have, such as velocity, flow control, density, and more. However, River Water Bodies do not have a parameter for waves, whereas Oceans and Lakes do.

Explore each of the different Water Body type Material Instances by opening the Water Content/Materials/WaterSurface folder in the Content Browser.

River Water Body Material Transitions

River Water Bodies allow for water to follow along a spline path from one location to another, and they can originate from lakes, oceans, rivers, or any combination. Unlike lakes and oceans, rivers have a general direction in which the water flows. This can start from a lake and flow into an ocean, another lake, or it can even merge with another river along its route.

Because rivers have a different set of properties from lakes and oceans — namely that they don't generate waves — they use transitional materials to seamlessly blend from River to Lake and River to Ocean transitions. The River Water Body shares the same tile mesh as the Lake and Ocean Water Bodies, making it possible for the transitional material to conform to any other Water Bodies' surface where they come into contact.

The transitional materials are instances of the River Water Body's default material. The only setup required to have a consistent look to the water in your Level is to manually match their color to any other Lake, Ocean, and River Water Body Materials being used.

In the simple example scene below, a landmass is used that contains a Lake Water Body at its center, a Ocean Water Body that surrounds the island, and a River Water Body that connects them. The transition material handles the start of the flow of water out of the lake to the river where it transitions to the ocean. Each Water Body and Transition Material have had their color matched for consistency.



Underwater Post Processing

An important aspect of water, depending on your project, is transitioning from above to below the water's surface. The Water system handles this using post processing.

Water Bodies each have an Underwater Post Process Material assigned, that drives transition through the water's surface using a Post Process Material. Underwater post processing happens automatically when a camera is within the bounds of a given Water Body and is submerged below the water's surface. The Post Process Material also handles transitioning in and out of water by masking out parts of the scene that are not underwater to create a partially underwater view.



Click image for full size.

Each Water Body's Details panel includes specific settings for the Actor, and provides access to the Post Processing Settings to further adjust the look of being underwater without needing to open and manually configure material properties.



Click image for full size.

For optimization purposes, the underwater post processing is only active when the camera is under, or slightly above, the water's surface. This is meant to take into account Lakes and Oceans where wave peaks and valleys can cause the camera to become fully or partially submerged. The underwater post process requires that Generate Collision be enabled for this underwater post processing to work.

Also, Water Body tile meshes are able to seamlessly blend using the transitional materials of the River Water Body. However, should the look of the underwater post processing differ significantly between two Water Bodies (such as moving from a clear river to a murky lake), there is a hard transition as the camera moves between the two post processing volumes.

Single Layer Water Material Shading Model

The Single Layer Water shading model is used for all default water materials because it renders a cost-effective translucency method using a single depth layer. This physically-based shading model supports proper light scattering, absorption, reflection and refraction, and shadowing on the surface of water.



Click image for full size.

All default water materials assigned to Water Bodies use the Single Layer Water shading model. Any shading model can be used with Water Bodies.

For more information on this shading model, see Single Layer Water Shading Model.

Creating Your Own Water Material

It is possible to create your own water material that works well with the Water System, so you don't have to specifically use the default water material assigned to each Water Body.

Keep the following in mind when setting up your own material:

Water Bodies support water materials that use any type of shading model.

The material requires the Usage Flag for Used with Water to be enabled. Whenever a material is assigned to a different type of Actor, this flag should automatically be enabled and the material will recompile. In instances where it is not, check that this flag is enabled if the material is not rendering correctly.

The SingleLayerWater shading model provides translucency and lighting results at lower cost than a traditional translucent material.

Creating a Water Waves Asset

Editing the Water Waves Asset

Gerstner Water Waves Properties

Setting the Number of Waves and Randomness

Wavelength of the Waves Simulation

Amplitude of the Waves Simulation

Direction and Angular Spread of Wind

Steepness of the Waves Simulation

Adding Your Own Wave Simulation Model and Wave Generator

The Water system uses GPU-driven wave data to simulate the surface of waves on Water Body Actors. The Water Waves Asset provides the individual wave parameters that are governed by its simulation model.

Creating a Water Waves Asset

Water Bodies are supplied with a wave simulation model to use with a Water Waves Asset assignment slot. By default, one is already supplied that uses the TODOLINK Gerstner wave simulation model.

While you do not need to create a new Water Wave Asset every time you use a Water Body, there are times when you want different types of wave input from the simulation model to behave differently, or when you want to use a completely different wave simulation model.

You can create your own Water Waves Asset using the Content Browser to click Add/Import or use the Right-Click Context Menu. From the menu, select Water > Water Waves.

On a selected Water Body, use the Water Waves Asset assignment slot to apply this asset.



Click image for full size.



Click image for full size.



Click image for full size.

Editing the Water Waves Asset

When creating, or opening an existing, Water Wave Asset, you select the type of wave simulation to be used, when multiple simulation models are available to choose from. Any editable properties will populate the panel to configure the simulation.



Click image for full size.

Water Waves Asset Editor using Gerstner Water Waves simulation model.

The Waves Source specifies the wave simulation model that is to be used for generating waves on Water Bodies. When one is selected, it provides parameters that are exposed through the selected Waves Source file to control the wave simulation. For example, the Gerstner Water Waves source provides parameters under the Gerstner Wave Generator.

You can configure these parameters to define the look of the wave simulation on any Water Bodies placed in the Level that have this Water Wave Asset assigned to them.

Unreal Engine only provides the Gerstner wave simulation model. However, you can implement other models or your own by using Blueprint or C++ code as a function that outputs waves based on some specified input. See the TODOLINK Adding Your Own Wave Simulation Model and Wave Generator section of this page for more details.

Gerstner Water Waves Properties

The Gerstner Water Waves simulation model provides the following parameters for wave simulation.



Click image for full size.

Property

Description



Default



Num Waves

The number of waves to be summed up.

Seed

A deterministic starting point for generating a random value to feed the wave model.

Randomness

Adds some amount of randomness to the interpolation between the minimum and maximum wavelength and amplitude values used by the Gerstner Water Waves model..



Wavelengths



Min Wavelength

Specifies the low-end of the wavelength range between waves that have a specified falloff.

Max Wavelength

Specifies the high-end of the wavelength range between waves that have a specified falloff.

Wavelength Falloff

Uses the minimum and maximum wavelengths to determine the distance between wave crests on a continuous wave.



Amplitude



Min Amplitude

Specifies the low-end of all generated waves' amplitude with a specified falloff.

Max Amplitude

Specifies the high-end of all generated waves' amplitude with a specified falloff.

Amplitude Falloff

Uses the minimum and maximum amplitudes to determine the height of generated waves.



Directions



Dominant Wind Angle

Set the primary direction from which the wind is blowing.

Dominant Angular Spread

Sets a random wind direction within the specified angle that the window should blow. Waves will appear to travel in this direction.



Steepness



Small Wave Steepness

Specifies the steepness of smaller waves with a specified falloff. The steepness determines how sharp the point of the wave crest becomes. This is achieved through lateral motion and controls how much the waves move side-to-side.

Large Wave Steepness

Specifies the steepness of larger waves with a specified falloff. The steepness determines how sharp the point of the wave crest becomes. This is achieved through lateral motion and controls how much the waves move side-to-side.

Steepness Falloff

Uses the small and large wave steepness values to determine the height range of wave crests that occur.

The Water system's mesh rendering system for surface detail is ideal for defining the macro movement patterns and look of waves. The micro details are best handled using the water material with normal maps where the tessellation of the mesh is limited by the balance of quality and performance.

Material-driven details have been disabled in the demonstrations that follow to demonstrate the macro-level detail that is achievable using the Water Wave Asset alone.

Setting the Number of Waves and Randomness

The Default category of parameters define the overall look of the Lake and Ocean Water Bodies.

The Num Waves parameter specifies the number of waves. This creates the overall look of the waves that are formed. By default 16 waves are used. Using fewer waves is more performant, but offers less variation in the randomness of waves colliding.

The Seed parameter creates a deterministic starting point for a random value, which is passed to the wave simulation algorithm to create variations with the waves. The Randomness parameter feeds random values to the minimum and maximum wavelength and amplitude values, to reduce repeating patterns in the wave simulation.

Wavelength of the Waves Simulation

The Wavelengths parameters specify a minimum and maximum value range for the distance between waves when a falloff value is used. The Seed and Randomness values work together with the Wavelength minimum and maximum value ranges to further define the look of the water surface.

Amplitude of the Waves Simulation

The Amplitude parameters specify a minimum and maximum value range for height displacement between waves. This controls the peaks and valleys of the wave crests. The Seed and Randomness values work together with the Amplitude minimum and maximum value ranges to further define the look of the water surface.

Direction and Angular Spread of Wind

The Directions parameters specify the direction wind is traveling. With the Dominant Wind Angle, the wind will push the waves in the wind's general direction.The Dominant Angular Spread specifies a secondary angle that waves move along while traveling in the direction set by the Dominant Wind Angle.

Steepness of the Waves Simulation

The Steepness parameters define how pointed or rounded the cresting waves become. The steepness of the wave crests is achieved through lateral motion, and controls how much the waves move side-to-side.

Small steepness values have softer, rounded wave crests. Large steepness values have sharper wave crests. These values provide random wave interactions that produce both softer and sharper wave crests without all wave crests being completely soft or sharp.

Adding Your Own Wave Simulation Model and Wave Generator

Unreal Engine provides the Gerstner wave simulation model for the Water System. The Water system is capable of supporting additional wave simulation models through the Water Wave Asset with configurable parameters, which can be done either through C++ code or Blueprint.

The information in this section uses the Gerstner wave implementation as a working example for creating your own wave generator backend for evaluating surface waves.

In C++, you would start by creating a new type that derives from UGerstnerWaterWaveGeneratorBase and uses GenerateGerstnerWaves_Implementation(TArray<FGerstnerWave>&OutWaves) const.

In Blueprint, the Parent Class inherits from the GerstnerWaterWaveGeneratorBase class.



Click image for full size.



Click image for full size.



Click image for full size.

In the Blueprint, you override and add your own Generate Gerstner Waves function that uses the Make GerstnerWave and Make GerstnerWaveOctave nodes to output to an array that stores information.



Click image for full size.



Click image for full size.

In the Water Waves Asset, the Gerstner Wave Generator selection dropdown lists any classes that inherit from the Gerstner Wave Source.



Click image for full size.

Enabling World Partition

Creating Your Project using a Games Template

Using the Open World Default Map

Converting Existing Levels to use World Partition

Using World Partition

Actors in World Partition

Streaming Sources

Using the Player as a Streaming Source

Using the World Partition Streaming Source Component

Runtime Grid Settings

Loading and Unloading Regions in the Editor

Generating a Minimap for the World Partition Window

Generating Hierarchical Levels of Detail (HLODs)

Cooking a World Partition world

Using World Partition with Blueprint

Testing a Partitioned World

Debugging and Runtime Overrides

World Partition Builder Commandlets

World Partition HLODs Builder

World Partition MiniMap Builder

World Partition Rename Duplicate Builder

World Partition Resave Actors Builder

World Partition Foliage Builder

World Partition Navigation Data Builder

World Partition Smart Object Collection Builder

Building large maps used to require developers to manually divide maps into sublevels, then use the Level streaming system to load and unload them as the player traversed the landscape. This method often created issues sharing files between multiple users, and viewing the whole world in context became a difficult task.



World Partition is an automatic data management and distance-based level streaming system that provides a complete solution for large world management. The system removes the previous need to divide large levels into sublevels by storing your world in a single persistent level separated into grid cells, and provides you with an automatic streaming system to load and unload those cells based on distance from a streaming source.

World Partition works closely with the following features:

One File Per Actor

World Partition - Data Layers

Level Instancing

World Partition - Hierarchical Levels of Detail

Enabling World Partition

There are three ways to enable World Partition within Unreal Engine:

Creating a new project from a template in the Games category.

Creating a new Level using the Open World template.

Converting existing levels to use World Partition.

Creating Your Project using a Games Template

World Partition is enabled by default in many of the project templates found in the Games category.



To reduce complexity and provide a scalable solution when creating new projects, grid cell streaming can be enabled and disabled using the Enable Streaming option in the World Settings.



The following templates use World Partition but have Enable Streaming disabled by default:

Blank

First Person

Third Person

Top Down

Vehicle Advanced

Using the Open World Default Map

The Open World default map type is designed to be a starting point for creating large open-world maps and comes with the following features enabled by default:

World Partition

One File Per Actor

Data Layers

Hierarchical Levels of Detail



The map contains a sample 2 km x 2 km Landscape with a Landscape Material and lighting setup for an outdoor environment. This includes a sky atmosphere, skylight, directional light, exponential height fog, and volumetric clouds.



To use the Open World default map type within your project:

Open the File menu and select New Level.

Select the Open World map type.

Click the Create button to create a new map.

Converting Existing Levels to use World Partition

You can add World Partition to any Level by converting it using the Tools > Convert Level menu option, or by using the World Partition Convert Commandlet.

To use the World Partition Convert commandlet, follow these steps:



Command: UnrealEditor.exe QAGame -run=WorldPartitionConvertCommandlet Playground.umap -AllowCommandletRendering

To convert your existing Levels to World Partition:

In Windows, open a Command Prompt window.



At the prompt, begin by navigating to the location of the UnrealEditor.exe executable file. In the above example: c:\Builds\Home_UE5_Engine\Engine\Binaries\Win64.



Next, begin the command with the name of the .exe file that will run the commandlet, UnrealEditor.exe

Add the name of the project. Here, QAGame.



Continue with the name of the commandlet to run, -run=WorldPartitionConversionCommandlet.

Add the name of the map file that will be converted. In the above example Playground.umap.

Finish the command with the additional argument -AllowCommandletRendering.



Press Enter and the commandlet will convert the map to use World Partition.

The following optional arguments are available for this commandlet:

Optional Argument

Description

-SCCProvider=(None,Perforce...)

Specifies which source control provider to use. To run without source control, specify -SCCProvider=None.

-Verbose

Displays verbose logging.

-ConversionSuffix

Appends the _WP suffix to a converted map. This is useful when converting Levels for testing purposes while keeping the source Level intact.

-DeleteSourceLevels

Deletes source Levels after conversion.

-ReportOnly

Reports what would happen during the conversion. Does not do the conversion.

-GenerateIni

Generates a default .ini conversion file for this map. Does not do the conversion.

-SkipStableGUIDValidation

Skips the unstable actor GUIDs validation process. Levels with unstable actor GUIDs will result in different conversion output when converting several times. Resaving the Level fixes this.

-OnlyMergeSubLevels

Converts and merges Levels and Sublevels to One File Per Actor without World Partition. The converted Level can be used as a Level Instance in a World Partition Level.

-FoliageTypePath=[Path]

Extracts Foliage Types as Assets to the given path. Use if the Level contains embedded Foliage Types.

If you want to alter the conversion settings, use a default conversion .ini file with the commandlet. The .ini file needs to be in the same folder as your map file and have the same filename as your map, but with the .ini extension. For example, an .ini file written for the FirstPersonExampleMap.umap would be named FirstPersonExampleMap.ini.

Here is an example of a default conversion .ini file:

Using World Partition

The World Partition system works by storing your world in a single persistent Level file and subdividing the space into streamable grid cells using a configurable runtime grid. These cells are loaded and unloaded at runtime by the presence of streaming sources, such as the player. In this way, Unreal Engine only loads the parts of the Level that the player sees and interacts with at a given time.

Actors in World Partition

When editing the world, Actors can be added anywhere and are automatically assigned to a grid cell based on their Is Spatially Loaded setting, found in their Details panel's World Partition section.



Option

Description

Runtime Grid

Determines in which partition grid this Actor is placed. If None, the grid will be chosen by the partition system.

Is Spatially Loaded

Determines if the Actor is spatially loaded:

If enabled, this Actor is loaded when in range of any streaming source when not assigned to a disabled Data Layer.

If disabled, this Actor is loaded when not assigned to a disabled Data Layer.

Since Actors are saved to their own individual files using the One File Per Actor feature, you do not need to check out the Level file from source control to make changes to the Actors in the world. This frees up the Level file for others on your team.

For more information on the One File Per Actor system and Unreal Engine's integrated source control, see the One File Per Actor documentation.

Actors that reference other Actors in the Level will be bundled together and loaded at the same time.

Streaming Sources

Streaming of grid cells within the grid at runtime is determined by two factors:

Streaming Sources

Runtime Grid Settings

The first is the position of streaming sources in the Level.



Streaming sources are components that define a position in the world and trigger the loading of cells around them. Player Controllers are a streaming source. Other streaming sources can be added to the world using the World Partition Streaming Source component. For example, a streaming source component can be activated at the location that a player will teleport to, so it can load the cells there. Once the grid cells are loaded, the player teleports to the location and the streaming source component is deactivated. Since there is no longer a streaming source at the player's previous location, those grid cells would be unloaded.

Using the Player as a Streaming Source

Each Player Controller is used as a World Partition streaming source using the Enable Streaming Source option. This is enabled by default:



Using the World Partition Streaming Source Component

World Partition streaming is also done using the World Partition Streaming Source component:



This component has the following options:

Option

Description

Default Visualizer Loading Range

Determines the size of the debug visualizer grid when the visualizer is enabled.

Target Grid

Determines the streaming grid affected by this source.

Debug Color

Determines the color used for debugging.

Target HLOD Layer

Determines the HLOD Layer affected by the streaming source.

Shapes

Determines the shape list used to build a custom shape for this streaming source. If empty, will use a sphere with a radius equal to the grid loading range.

Priority

Determines the priority of the streaming source. If a grid cell intersects multiple streaming sources, its priority will be the highest priority amongst all streaming sources.

Streaming Source Enabled

Determines if this component is enabled.

Target State

Determines which state the intersecting grid cell should be in (either Loaded or Activated). If a grid cell intersects multiple streaming sources, the target state will be the highest target value (where activated is greater than loaded).

The Blueprint functions Enable Streaming Source and Disable Streaming Source will enable and disable streaming with this component.



The Blueprint function Is Streaming Completed returns true when the component has finished streaming the grid cells that it intersects with.

Runtime Grid Settings

The second factor that determines whether a grid cell is loaded or unloaded at runtime is the settings of the runtime grid itself. Runtime grid settings are located in the World Settings panel, in the World Partition Setup section.

A 2D Runtime Hash grid is provided by default. Using more than one grid can negatively impact performance.

For more information on the recommended setup and settings for your 2D Runtime Hash grid, see the Big City map located in the City Sample project.



Option

Description

Grid Name

Contains the name of the runtime grid.

Cell Size

Determines the size of the grid cells that are used to generate the streaming Levels. In the example, the Cell Size is 256 square meters.

Loading Range

Determines the range from a streaming source where cells are loaded. In the image above, the Loading Range is a 768 meter radius around a streaming source.

Block on Slow Streaming

Blocks loading in situations where grid cells are not loading fast enough.

Priority

Determines the priority of the streaming source. If a grid cell intersects multiple streaming sources, its priority will be the highest priority amongst all streaming sources.

Debug Color

Determines the color of the grid lines that are shown when Preview Grids is enabled.

Preview Grids

When enabled, displays the grid lines in the viewport.

Instanced Foliage Grid Size

Determines the size of the grid for Instanced Foliage Actors.

Default World Partition Settings

Resets the current grid settings back to default or saves the current settings as the new default.

World Partition Editor Cell Size

Determines the World Partition editor cell size. New sizes will take effect on the next world reload.

Loading and Unloading Regions in the Editor

To support the development of large worlds, all grid cells are initially unloaded. When the Level opens, the Editor will only load Actors that have their Is Spatially Loaded setting marked as False, such as environment backdrops and managers. This supports the development of large worlds where it is impossible to load the entire map in the Editor.

In the World Partition window, you can manually select the region to work in. Open the window by selecting Window > World Partition > World Partition Editor from the main menu.



In the window, click and drag out a region. Then, right-click the selection to open the context menu and select Load Region from Selection.



Generating a Minimap for the World Partition Window

You can generate a Minimap to make navigating in the World Partition window easier by using the Build Minimap option found in the World Partition section of the Build menu, or by using the World Partition Minimap Builder commandlet.



Running this commandlet creates a Minimap image of your World Partition world and places it in the World Partition window.

If you build your Minimap and it does not appear in the World Partition window, you will need to enable Virtual Textures support in your project. To enable Virtual Textures, from the main menu, go to Edit > Project Settings. Then, enable the Enable virtual texture support checkbox.

Generating Hierarchical Levels of Detail (HLODs)

HLODs are generated using the Build HLODs option found in the World Partition section of the Build menu, or by using the World Partition HLODs Builder commandlet.



Running this commandlet creates the HLOD Actors for your World Partition cells according to the generation settings you specified in your HLOD Layers. For more information about using Hierarchical Levels of Detail (HLODs) in World Partition and using the World Partition HLODs Builder commandlet, see the World Partition - Hierarchical Level of Detail documentation.

Cooking a World Partition world

Cooking a World Partition map requires the use of the Cook commandlet:



Command: UnrealEditor.exe QAGame -run=cook -targetplatform=WindowsNoEditor -Unversioned -map=Playground

To cook your World Partition map:

In Windows, open a Command Prompt window.

At the prompt, begin by navigating to the location of the UnrealEditor.exe executable file.

Next, begin the command with the name of the .exe file that will run the commandlet, UnrealEditor.exe.

Add the name of the project. Here, QAGame.

Continue with the name of the commandlet to run, -run=cook.

Finish the command with the following arguments:

-targetplatform=WindowsNoEditor cooks the project for Windows platforms.

-UnVersioned saves all of the cooked packages without versions. These are then assumed to be the current version on load.

-map=Playground specifies the name of the map, in this case Playground.umap.

For more information on using the Cook commandlet, see Content Cooking.

Using World Partition with Blueprint

Both Blueprint Classes and Level Blueprints are supported in a World Partition world. However, Blueprint Classes are preferred, as any Actors referenced in the Level Blueprint will be marked as Always Loaded.

Testing a Partitioned World

Debugging and Runtime Overrides

There are several useful console commands for debugging a World Partition world during runtime.

Console Command

Description

wp.Runtime.ToggleDrawRuntimeHash2D

Toggles 2D debug display of world partition runtime hash.

wp.Runtime.ToggleDrawRuntimeHash3D

Toggles 3D debug display of world partition runtime hash.

wp.Runtime.ShowRuntimeSpatialHashGridLevel

Chooses which grid level to display when showing world partition runtime hash.

wp.Runtime.ShowRuntimeSpatialHashGridLevelCount

Chooses how many grid levels to display when showing world partition runtime hash.

wp.Runtime.ShowRuntimeSpatialHashGridIndex

Shows a specific grid when showing world partition runtime hash. An invalid index will show all.

wp.Runtime.RuntimeSpatialHashCellToSourceAngleContributionToCellImportance

Takes a value between 0 and 1 that modulates the contribution of the angle between streaming source-to-cell vector and source-forward vector to the cell importance. The closer the value to 0, the less the angle will contribute to the cell importance.

wp.Runtime.OverrideRuntimeSpatialHashLoadingRange

Sets the runtime loading range. Takes the following arguments:

-grid=[index]: Sets the runtime grid you would like to affect.

-range=[override_loading_range]: Sets the new runtime loading range

wp.Runtime.MaxLoadingLevelStreamingCells

Limits the number of concurrent loading World Partition streaming cells.

wp.Runtime.HLOD 0

Shows the world without HLODs using wp.Runtime.HLOD.

World Partition Builder Commandlets

World Partition introduces a builder commandlet framework through the UWorldPartitionBuilderCommandlet and the UWorldPartitionBuilder base class.

These commandlets are used to automate batch processes and generate or modify data in World Partition Levels. Large worlds will not have to be loaded all at once to do things like generating HLODs, AI Nav Data, or resave a large number of Actors.

World Partition HLODs Builder

HLODs are generated using the World Partition HLODs Builder commandlet. Running this commandlet creates the HLOD Actors for your World Partition cells according to the generation settings you specified in your HLOD Layers.



Command: UnrealEditor.exe "C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject" "/Game/ThirdPersonBP/Maps/OpenWorldTest" -run=WorldPartitionBuilderCommandlet -AllowCommandletRendering -builder=WorldPartitionHLODsBuilder

For more information about using Hierarchical Levels of Detail (HLODs) in World Partition and using the WorldPartitionHLODsBuilder commandlet, see the World Partition - Hierarchical Level of Detail documentation.

World Partition MiniMap Builder

The World Partition MiniMap Builder commandlet generates or updates the minimap that displays in the WorldPartition Editor window.



Command: UnrealEditor.exe "C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject" "/Game/ThirdPersonBP/Maps/OpenWorldTest" -run=WorldPartitionBuilderCommandlet -AllowCommandletRendering -builder=WorldPartitionMiniMapBuilder

World Partition Rename Duplicate Builder

The World Partition Rename Duplicate Builder commandlet automates the process of renaming or duplicating an existing World Partition Level and all its actors.



Command: UnrealEditor.exe "C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject" "/Game/ThirdPersonBP/Maps/OpenWorldTest" -run=WorldPartitionBuilderCommandlet -SCCProvider=None -builder=WorldPartitionRenameDuplicateBuilder -NewPackage=/Game/ThirdPersonBP/Maps/NewPackage

This will create a duplicate World Partition Level of the OpenWorldTest map named NewPackage and leave the original map untouched.

To rename your World Partition map rather than make a copy, add the -Rename argument.

World Partition Resave Actors Builder

The World Partition Resave Actors Builder commandlet resaves all Actors of a World Partition Level and supports a class filter to resave only a subset of Actors.



Command: UnrealEditor.exe "C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject" "/Game/ThirdPersonBP/Maps/OpenWorldTest" -run=WorldPartitionBuilderCommandlet -SCCProvider=None -builder=WorldPartitionResaveActorsBuilder

When you execute the above example, all of the Actor's packages in the OpenWorldTest level are resaved.

You can use the -ActorClass argument to specify only a subset of Actors to be resaved. For example, adding -ActorClass=StaticMeshActor will resave only the Static Mesh Actors in the specified Level.

World Partition Foliage Builder

In a World Partition map, the default Instanced Foliage Grid Size for Foliage Instances is 256 meters. The World Partition Foliage Builder commandlet is used to change the Instanced Foliage Grid Size for existing World Partition level.



Command: UnrealEditor.exe QAGame Playground.umap -run=WorldPartitionBuilderCommandlet -Builder=WorldPartitionFoliageBuilder -NewGridSize=Value

For more information on using Foliage Mode with World Partition, see the Foliage Mode documentation.

World Partition Navigation Data Builder

The World Partition Navigation Data Builder commandlet rebuilds the navmesh in your World Partition Level.



Command: UnrealEditor.exe "C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject" "/Game/ThirdPersonBP/Maps/OpenWorldTest" -run=WorldPartitionBuilderCommandlet -AllowCommandletRendering -builder=WorldPartitionNavigationDataBuilder -SCCProvider=None

This commandlet takes the following arguments:

Optional Argument

Description

-SCCProvider

Specifies which source control provider to use. To run without source control, specify -SCCProvider=None.

-Verbose

Displays verbose logging.

-Log

Outputs log to a specific file.

-CleanPackages

Wipes all navigation data packages instead of building them.

World Partition Smart Object Collection Builder

The World Partition Smart Object Collection Builder commandlet rebuilds the smart object collection from all the smart object components in your World Partition Level.



Command: UnrealEditor.exe "C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject" "/Game/ThirdPersonBP/Maps/OpenWorldTest" -run=WorldPartitionBuilderCommandlet -builder=WorldPartitionSmartObjectCollectionBuilder

When you execute the above example, all of the Smart Object Collection in the OpenWorldTest level are rebuilt. You can use the -SCCProvider argument with this commandlet to specify which source control provider to use.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Creating Level Instances

Creating a Level Instance

Creating a Packed Level Blueprint

Editing Level Instances

Editing a Level Instance

Editing a Packed Level Blueprint

Breaking Level Instances

Level Instances at Runtime

Data Layers

Level Streaming Modes

Level Instancing is a level-based workflow designed to improve and streamline the level editing experience. Using the Level Instancing workflow one or more Actors are used to create Level Instances that can be placed down and repeated across your world.

This workflow provides the following benefits:

Level Instances are edited in-context, letting you immediately see how your changes will affect your world. Changes made to one instance are repeated across all instances when saved.

Quickly "stamp" copies of commonly used static mesh arrangements in your world, such as points of interest, buildings, and gameplay setups.

Production-ready process used in the creation of the City Sample and Valley of the Ancient demos created by Epic Games.



The City Sample skyline.

Though it is possible to use Level Streaming without using World Partition, Level instances do not automatically have streaming management or streaming strategies outside of a World Partition main world.

Creating Level Instances

There are two types of Level Instances:

Level Instances: Collections of Actors that are combined to create a sublevel. Multiple instances of a sublevel can be repeated across your project, something not possible in previous versions of Unreal Engine. Use this type for points of interest and standalone gameplay setups.

Packed Level Blueprints: Static Mesh assets that are combined to create a single Blueprint Actor that is optimized for rendering. The Static Meshes are replaced with an instance of the Packed Level Blueprint that is linked to a Packed Level Actor. This type is recommended for static buildings and dense visual setups like the mega assemblies used in Valley of the Ancient.

Creating a Level Instance

New Level instances are generated from selected Actors and can be created in either the Viewport or the Outliner.

After selecting the Actors, right-click one of them to pull up the context-sensitive menu. In the menu, navigate to the Level option and select Create Level Instance.



Creating a Level Instance with the context menu.

You will see a dialog box with the following settings:



The new Level Instance dialog box.

Setting

Description

External Actors

Enable external Actors to use the One File per Actor system. For more information, see the One File Per Actor documentation.

Pivot Type

The type of Pivot the Level instance will have:

Center Min Z: Pivot will be located at the center of the Level Instance at the lowest Z value.

Center: : Pivot will be located at the center of the Level Instance.

Pivot Actor: If an Actor is selected as the Pivot, use this dropdown to select which Actor will be the pivot point for the Level Instance.

Pivot Actor

If Actor is selected as the Pivot, use this dropdown to select which Actor will be the pivot point for the Level Instance.

Once you have selected your settings and click Ok, you are asked to save the new Level Instance.

This process creates a new Level Instance Actor in the level, which replaces the previously selected Actors. This Actor represents the Level that was just created and all transforms applied to this Actor are applied to the Level Instance.



The new Level Instance Actor replaces the assets in the level.

The Actors that make up the Level Instance are still visible in the Outliner but are now a child of the Level Instance Actor and are not selectable.



The assets are now children of the Level Instance Actor.

Creating a Packed Level Blueprint

Like Level Instances, Packed Level Blueprints are generated using selected Actors and can be created by right clicking in the Viewport or the Outliner.

After selecting the Actors, right-click one of them to pull up the context-sensitive menu. In the menu, navigate to the Level option and select Create Packed Level Actor.



Creating a Packed Level Blueprint with the context menu.

You will see the same dialog box as above. Select your settings and click Ok. You are then asked to save the new Level and the new Packed Level Blueprint.

This process creates a new Packed Level Actor in the level associated with your Packed Level Blueprint.

Editing Level Instances

Once created, Level Instances and Packed Level Blueprints can be copied and placed across your world.

Editing a Level Instance

To edit your Level Instance, select one of them in the Viewport and right click to open the menu, navigate to the Level option and select Edit. You can also click the Edit button in the Details panel.

This grays out all other Actors in your World, making it easier to edit your Level Instance in context.



All other Actors are grayed our while editing a Level Instance in the Viewport.

When you finish, select the Level Instance Actor in the Outliner and click Commit Changes in the Details panel.



Clicking Commit Changes in the Details Panel saves your Level Instance changes.

To leave editing without committing your changes, press Esc twice.

Any changes made to a Level Instance propagate to all copies of the Level Instance in your world.

Editing a Packed Level Blueprint

To edit your Packed Level Blueprint, locate an instance of it in the Outliner and click Edit. You can also locate the Blueprint in the Content Browser and double click. This will open the Blueprint Editor window.



The Blueprint Editor window showing the selected Packed Level Blueprint.

Like Level Instances, any changes made to the Packed Level Blueprint propagate to all other copies of it in your world.

Breaking Level Instances

Breaking a Level Instance removes the Level Instance Actor or Packed Level Actor from the world and replaces it with the original assets used to create them. It does not delete the Level Instance or Packed Level Blueprint from the Content Browser.

This operation cannot be undone.

Level Instances at Runtime

Data Layers

Level Instances and Packed Level Blueprints support World Partition: Data Layers.

The Actors contained within the Level Instance inherit the Data Layer assigned to its Level Instance Actor by default. Actors within the Level Instance also support additional Data Layers.

For example, a Level Instance that contains the assets to create a house point of interest can be assigned to a Neighborhood data layer. The Level Instance can also contain holiday themed items that are assigned to different holiday data layers that are only visible when that data layer is enabled.

Level Streaming Modes

Level Instances and Packed Level Actors use the World Partition settings to define their streaming behavior, either Embedded Mode or Level Streaming Mode.

These settings are not editable and are included here for reference.

When using Embedded Mode, Level instances that use the One File Per Actor (OFPA) system are discarded and their Actors are added to the World Partition grid at runtime. This is the default runtime mode and the suggested method of streaming Level content. This also makes Level instances exist within the editor only.

Some Actors that do not use OFPA are lost at runtime when using Embedded Mode. For example, the AWorldSettings object of an embedded Level Instance does not exist at runtime as this is a non-OFPA Actor. It is your responsibility to avoid relying on these Actors or to use Level Streaming mode when needed.

Level instances that do not use OFPA cannot be embedded in the World Partition grid and instead use standard Level streaming at runtime. This means that when the Level Instance Actor is loaded through its owning World Partition runtime cell, it loads the associated Level.

This method of Level streaming has an added runtime cost as it adds more Levels to the stream. It is not recommended to use a high density of Levels that use this streaming mode due to the performance impact.

Embedded mode with World Partition: Data Layers is a great way to approximate what could previously be done with dynamically loaded Levels.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Creating HLOD Layers

Using HLOD Layers

Visualizing HLODs

The World Partition system uses a grid to separate your world into cells that can be dynamically loaded and unloaded at runtime. Yet there are times when you want Actors that are distant and non-interactive — such as distant mountains, trees, and cliffs — to still be visible.





HLODs Off. Only content in loaded cells is dsiplayed.

HLODs On. Content in unloaded cells is replaced with HLODs.

The World Partition - Hierarchical Level of Detail (HLOD) system uses custom HLOD Layers to organize large amounts of Static Mesh Actors and generate a single proxy mesh and Material. This technique is used to visualize unloaded World Partition grid cells, to reduce the number of draw calls per frame, and to increase performance, especially when used with large open worlds.

Some world components, such as Landscapes and Water components, are currently not supported by HLOD Actors.

Creating HLOD Layers

World Partition HLODs are controlled by the HLOD Layer asset. These specialized assets contain your settings, and your project can use multiple HLOD Layers:



Create a new HLOD Layer asset by opening the Content Drawer and clicking + Add to open the menu. Navigate to the Miscellaneous menu and select the HLOD Layer asset. (Right-clicking in the Content Drawer opens the same menu.)

Double-click the new HLOD Layer to open it in the Asset Editor:



Setting

Description

Layer Type

Select the layer type from the following options:

Instancing

Merged Mesh

Simplified Mesh

Mesh Merge Settings/Proxy Settings

Displays additional options when the Merged Mesh or Simplified Mesh layer type is selected.

Always Loaded

Determines whether the HLOD proxy mesh generated by this layer will be always loaded.

Cell Size

Sets the cell size of the runtime grid created to contain the HLOD Actors in this layer. This option is not available if you set your HLOD Layer to Always Loaded.

Loading Range

Sets the distance at which the runtime grid streams its cells. This option is not available if you set your HLOD Layer to Always Loaded.

Parent Layer

Enables the assets created by this HLOD Layer to be automatically assigned to a designated HLOD Layer.

HLODMaterial

Sets the base material to use when baking materials for Merge Mesh and Simplified mesh layer types.

This is an advanced setting. The default material is sufficient for most use cases.

Choosing a Layer Type

The first step to using HLOD Layers is to select the layer type:



Layer Type

Description

Instancing

Static Mesh assets in this type of layer are replaced with Instanced Static Mesh (ISM) components using the lowest Level of Detail (LOD) settings for those assets. This type is ideal for imposter meshes, such as trees and foliage.

Merged Mesh

Static Mesh assets in this type of layer are merged to create a single proxy mesh.

Simplified Mesh

Static Mesh assets in this type of layer are merged into a single proxy mesh and mesh simplification is performed.

Mesh Merge Settings

These settings are only available if Merged Mesh is selected:



Setting

Description

Generate Lightmap UV

Generates lightmap UVs for the merged mesh. This new layout will be placed in the Target Lightmap UVChannel.

Target Lightmap Resolution

Specifies the lightmap resolution used for generating lightmap UV coordinates on the generated Static Mesh. This controls the distance between UV islands. Higher resolutions yield tighter spaces between each UV island.

Computed Lightmap Resolution

Determines if the lightmap resolution should be computed by summing the lightmap resolutions for the input mesh components.

Pivot Point at Zero

Determines whether the position of the merged mesh's pivot point is at the world origin or the first merged component.

Merge Physics Data

Determines whether to merge the physics data of the mesh components, specifically collision primitives.

Merge Materials

Merges source materials into a single flat material. This is only available when merging a single LOD level, as determined by your LODSelection Type.

Material Settings

Contains material settings for the simplified material created when Merge Materials is enabled.

Gutter Size

Adds space to the subchart for baked materials for the top mip level. Measured in texels.

Create Merged Materials

Creates a flat material from all source component materials, as well as a new set of UV coordinates. This material is not applied to any section by default.

Bake Vertex Data to Mesh

Bakes vertex data, such as vertex colors and normals, into the resulting proxy mesh.

Output UVs

Outputs the specified UV channels into the merged mesh. Source mesh components must contain valid UVs for the specified channels.

LODSelection Type

Determines which LOD selection mode to use when generating the merged static mesh:

Use all LOD levels: Uses all available LOD levels when merging Actors

Use specific LOD level: Uses the selected LOD level when merging Actors.

Calculate correct LOD level: Calculates the appropriate LOD model for the given screen size.

Always use lowest detail LOD: Uses the lowest detail LOD when merging Actors.

Specific LOD

Specifies a LOD level to export from the source meshes.

Use Vertex Data for Baking Material

Bakes vertex data, such as vertex colors and normals, into the baked-out materials. Only available if Merge Materials is selected.

Use Texture Binning

Calculates varying output texture sizes according to their importance in the final atlas texture. Only available if Merge Materials is selected.

Reuse Mesh Lightmap UVs

Determines whether to reuse the lightmap UVs from the source mesh when baking the material. If false, the engine will generate a new set of UVs.

Merge Equivalent Materials

Attempts to merge materials that are deemed equivalent. The process can cause artifacting in the merged mesh if world position or actor position is used to determine output color.

Use Landscape Culling

Uses available landscape geometry to cull invisible triangles. For example, if you had a tree mesh that was placed where the lowest triangles were below the surface of a landscape, then those occluded triangles would be removed upon merge.

Include Imposters

Includes any imposter LODs that are part of the source mesh components.

Allow Distance Fields

Allows distance fields to be computed for this mesh. Disabling this will save memory if the merged mesh is only rendered in the distance.

Generate Nanite Enabled Mesh

Enables Nanite on the generated mesh.

Proxy Settings

These settings are only available if Simplified Mesh is selected:



Setting

Description

Screen Size

Determines size of the resulting proxy mesh in pixels.

Calculate Correct LODModel

Calculates which LOD model is sufficient based on the specified screen size. This is done by analyzing each input mesh and selecting the correct LOD based on each LOD transition size.

Override Spatial Sampling Distance

Overrides when converting multiple source meshes for proxy LOD merging.

Large geometry with small sampling has a very high memory cost.

Material Settings

Contains settings for material simplification.

Merge Distance

Distance at which meshes should be merged. This can close gaps like doors and windows in distant geometry.

Unresolved Geometry Color

Assigns a base color that is shown when merged geometry can't be associated with the source geometry, such as doors and windows that have been closed by the Merge Distance.

Transfer Distance Override

Overrides the search distance used when discovering texture values for simplified geometry. Used when non-zero Merge Distance settings generate new geometry in concave corners.

Hard Edge Angle

Angle at which a hard edge is introduced between faces. This will increase vertex counts and may introduce additional UV seams. Only recommended when not using normal maps.

Normal Calculation Method

Controls the method used to calculate the normal for simplified geometry:

Angle Weighted: Normals are weighted using the angle of the surrounding faces.

Area Weighted: Normals are weighted using the area of the surrounding faces.

Equal Weighted: Normals are weighted using an average of the normals of the surrounding faces.

Lightmap Resolution

Sets the resolution of the newly generated lightmap.

Compute Lightmap Resolution

Computes the lightmap resolution by summing the dimensions for each mesh included in the merging process.

Enable Volume Culling

Allows culling volumes to exclude geometry.

Allow Distance Fields

Allows distance fields to be computed for this mesh. Disabling this will save memory if the merged mesh is only rendered in the distance.

Reuse Mesh Lightmap UVs

Determines whether to reuse the lightmap UVs from the source mesh when baking the material. If false, the engine will generate a new set of UVs.

Group Identical Meshes for Baking

Bakes identical meshes or mesh instances only once. Will result in better quality baked textures and reduced baking times. Can lead to discrepancies between the merged mesh and the source mesh visual.

Create Collision

Generates collision for the merged mesh.

Allow Vertex Colors

Allows the saving of vertex colors in the merged mesh.

Generate Lightmap UVs

Generates lightmap UVs for the merged mesh.

Generate Nanite Enabled Mesh

Enables Nanite on the generated mesh.

Using HLOD Layers

To generate HLOD proxy meshes, Actors need to be added to an HLOD Layer and told to generate HLODs. Once this is done, a commandlet is run to generate the proxy geometry.

Currently, the commandlet is the only way to generate HLOD proxy geometry.

Adding Actors

Actors are currently added to HLOD Layers in the following ways:

The HLOD property in an Actor's Details panel.



The Default HLOD Layer property of a Data Layer.



The Default HLOD Layer property of the World Settings.



There are HLOD Layer options also available when using the WorldPartitionConvertCommandlet. Using the conversion ini file, you can specify HLOD Layer properties:

A world converted with this configuration specifies a DefaultHLODLayerName (in this example, HLODLayer_Default), which will be created using the properties specified in the matching .ini section. Actors created by HLODLayer_Default will be assigned to HLODLayer_Tree with the properties defined in that section of the .ini file.

Generating HLODs

HLODs are generated using the WorldPartitionHLODsBuilder commandlet. Running this commandlet creates the HLOD Actors for your World Partition cells according to the generation settings you have specified in your HLOD Layers.

HLOD Actors will not be recreated or built if no changes have been made to their source Actors. Making changes to the Actors themselves or their meshes, materials, or textures will result in the HLOD being rebuilt if you re-execute the commandlet.

Follow the steps below to use the commandlet:

In Windows, open a Command Prompt window.



At the prompt, begin by navigating to the location of the UE4Editor.exe file. For example: C:\Program Files\Epic Games\UE_4.26\Engine\Binaries\Win64.



Next, begin the command with the name of the .exe file that will run the commandlet, UE4Editor.exe.

Add the following arguments:

YourProject YourMap -run=WorldPartitionBuilderCommandlet -AllowCommandletRendering -Builder=WorldPartitionHLODsBuilder

Where YourProject is the name of your project folder and YourMap is the name of the map file in which you want to build HLODs.



Additionally, one of the following options can be provided to change the behavior of this command:

Option

Description

-SetupHLODs

Sets up the HLOD Actors for the World Partition cells but does not build their geometry. Can potentially update, delete, or create new Actors.

-BuildHLODs

Builds the geometry for all existing HLOD Actors.

-DeleteHLODs

Deletes all HLOD Actors.

Visualizing HLODs

HLOD Actors can be visualized in the Editor Viewport, while the status of HLOD cells can be visualized at runtime.

In the Editor

In the Editor, change the View Mode to Level of Detail Coloration and choose Hierarchical LOD Coloration. Actors assigned to an HLOD Layer will be green. Zooming the view out will make HLODs appear in Blue.

In the Viewport, changing the View Mode to Level of Detail Coloration and selecting Hierarchical LOD Coloration will display Actors assigned to an HLOD Layer in green:



Moving the camera away from the Actors will show their HLOD proxy mesh in blue:



At Runtime

Running the console command wp.Runtime.ToggleDrawRuntimeHash2D at runtime displays the HLOD cells that are loaded in green.



This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Creating Data Layers

Using Data Layers

Managing Files

Debugging and Runtime Overrides

Data Layers is a system within World Partition you can use to organize your Actors both in the Editor and at runtime.



A sample level completed using Data Layers.

Using Data Layer Assets and Data Layer Instances, you can dynamically load and unload layers in the Editor to help manage complex worlds. This system serves as a replacement to the previous Layers system found in older versions of Unreal Engine.

With Data Layers, you can separate gameplay elements and environment assets in the Editor. Artists can work on specific elements without interacting with gameplay triggers or objects. Designers can use dynamically loaded layers to design intriguing gameplay and elaborate level transitions.

At runtime, you can toggle Data Layers using Blueprints or C++ code to drive gameplay (such as quests, progression, and in-game events). They are an important tool for managing asset streaming in a World Partition workflow.

Creating Data Layers

Data Layers are split into two types of assets: Data Layer Assets and Data Layer Instances. Data Layer Assets contain cross world data and are created using the Data Layers Outliner or in the Content Browser. Data Layer Instances contain world specific data and are created in the Data Layers Outliner.

the Data Layers system requires you to enable World Partition in your map. A map can be converted to World Partition by using Tools > Convert Level or by using the commandlet. For more information on converting existing levels to World Partition, see World Partition.

Data Layer Assets

Data Layer Assets are Unreal Engine assets you can create and view in the Content Browser. They exist at the project level and are not world specific. They contain the following data:

Data Layer Name

Data Layer Type

Debug Color

Data Layer Assets are set to one of two different types, Editor or Runtime. You can use Editor Data Layers to keep your assets organized within your project. You can load and unload Editor Data Layers from memory, and toggle visibility using the Data Layer Outliner.



Setting the options for a Data Layer Asset.

Editor and Runtime Data Layers have identical properties when open in the Content Browser.

Runtime Data Layers are similar to Editor Data Layers but you can manipulate them at runtime using Blueprints or C++. You can use in-game events to load or unload the assets assigned to them, opening up a variety of options for complex gameplay or level transitions. For example, we used Runtime Data Layers in the Valley of the Ancient sample to create the transition between the Light World and the Dark World.





Data Layer Instances

Data Layer Instances are world-specific instances of a Data Layer Asset. Using instances, a Data Layer Asset can exist in two or more worlds and reference the same assets but specify different instance properties.

For example, you create a neighborhood point of interest (POI) in a world and assign those assets to an Editor Data Layer to keep them organized. You then decorate the POI using holiday-specific assets and assign those to a Runtime Data Layer to enable them to be loaded and unloaded during runtime. In the standard version of your world, you set a Data Layer Instance of the Runtime Data Layer to not be loaded by default and to toggle on a specific date to celebrate an in-game holiday. In the same project, you can then use a separate instance of the Runtime Data Layer that is always enabled to create a holiday-themed version of the POI separate from your standard world.

Data Layers Outliner

The Data Layers Outliner is used to view all of your existing Data Layer Instances and create new Data Layer Assets and Data Layer Instances. To open the Data Layers Outliner, select Window > World Partition > Data Layer Outliner.



The Data Layer Outliner.

Number

Description

1

Visibility

2

Data Layer Loaded In Editor

3

Data Layer Type

4

Data Layer Name

5

Data Layer Validation

6

Data Layer Outliner Options

7

Data Layer Asset

8

Is Initially Visible

9

Is Initially Loaded

10

Initial Runtime State

Right-clicking in the Data Layer Outliner opens the context menu:



The Data Layer Outliner context menu.

Selection

Description

Create New Data Layer

Creates a new, empty Data Layer Instance.

Create New Data Layer under "DL_Sample"

Creates a new, empty Data Layer Instance as a child of the selected Data Layer.

Add Selected Actors to Selected Data Layer

Adds the selected Actors to the selected Data Layer Instance.

Move Data Layers To

Makes an existing Data Layer Instance a child of another Data Layer.

Remove Selected Actors from Selected Data Layers

Removes the selected Actors from the selected Data Layer Instance.

Delete Selected Data Layers

Deletes the selected Data Layer.

Rename Selected Data Layers

Renames the selected Data Layer. Only works with legacy Data Layers.

Select Actors in Data Layer

Selects all the Actors assigned to the selected Data Layer Instance.

Append Actors in Data Layer to Selection

Adds the contents of the selected Data Layer Instance to your selection.

Deselect Actors in Data Layer

Removes the contents of the selected Data Layer from your selection.

Collapse All Data Layers

Collapse the Data Layer hierarchy.

Expand All Data Layers

Expands the Data Layer hierarchy.

Make Current Data Layer

Sets the selected Data Layer as the current Actor Editor Context. For more information on Actor Editor Context, see the Actor Editor Context documentation.

Remove Current Data Layer(s)

Removes the selected Data Layer from the current Actor Editor Context.

Clear Current Data Layers

Clears all Data Layers from the current Actor Editor Context.

Make All Data Layers Visible

Sets the visibility of all Data Layer Instances to visible.

Clicking the gear icon displays the Data Layer Outliner options:



Data Layer Outliner oprions.

Selection

Description

Expand All

Expands the Data Layer hierarchy.

Collapse All

Collapse the Data Layer hierarchy.

Stack Hierarchy Headers

Pins the hierarchy items to the top of the outliner.

Only Selection

Displays only selected Actors in the Outliner.

Hide Editor Data Layers

Hides Editor Data Layers In the Outliner.

Hide Runtime Data Layers

Hides Runtime Data Layers in the Outliner.

Hide Actors

Hides the list of Actors assigned to Data Layers in the Outliner.

Hide Unloaded Actors

Hides all Actors from Unloaded World Partition cells in the Outliner.

Hide Level Instance Content

Hides all assets contained inside Level Instances.

Highlight Selected

Highlights Data Layer Instances that contain the selected Actors.

Allow Runtime Data Layer Editing

Allows the editing of Runtime Data Layer Instances.

Reset User Settings

Resets the Data Layer Outliner settings to their default values.

Choose World

Determines which world's Data Layer instances are being displayed.

Updating Legacy Projects using the Data Layers Commandlet

To update an existing project to use Data Layer Assets and Data Layer Instances, use the Data Layer To Asset commandlet:



The format of the Data Layer to Asset commandlet.

Follow the steps below to use the commandlet:

Open a command prompt window.



Open a command prompt.

At the prompt, navigate to the location of the UnrealEditor.exe file. For example: C:\Program Files\UE_5.1\Engine\Binaries\Win64.



Navigate to the location of your engine executable.

Begin typing the command. Start with the name of the .exe file that will run the commandlet, UnrealEditor.exe.



Begin the commandlet with UnrealEditor.exe.

Add the name of the project.



Add the Project Name, such as UnrealEditor.exe CitySample.

Next, add the name of the commandlet to run.



Add the commandlet name. In this example UnrealEditor.exe CitySample -run=DataLayerToAssetCommandlet.

Finally, add the name of the level you want to convert and the destination folder.



Finish by add ng the Level name and destination folder. UnrealEditor.exe CitySample -run=DataLayerToAssetCommandlet Small_CITY_LVL -DestinationFolder=/Game/DataLayerConversion.

Press Enter and run the commandlet.

All previous Data Layers are converted to Data Layer Instances and Data Layer Assets. All Actors that were referencing Data Layers previously now reference Data Layer Assets.

This commandlet has the following optional arguments:

Optional Argument

Description

-Verbose

Logs additional context when converting. This outputs the conversion information for every Actor with a Data Layer.

-NoSave

Runs the commandlet without saving changes.

-IgnoreActorLoadingErrors

Ignores errors when an Actor fails to load during conversion.

Using Data Layers

Creating New Data Layers

To use the Data Layers system in your project, start by creating a Data Layers Asset:



Creating a Data Layer Asset.

In the Content Browser, navigate to the folder where you want to store your Data Layers Asset, right click and select Miscellaneous > Data Layer to create the Data Layers Asset.

In the Data Layers Outliner, right click and select Create New Data Layer. This creates a blank Data Layer Instance named Unknown in the outliner.

Assign your Data Layers Asset to the new instance by opening the drop down menu next to Data Layers Asset and selecting your Data Layers Asset.

Alternatively, dragging and dropping a Data Layer Asset into the Data Layer Outliner creates a new Data Layer Instance with the selected Data Layer Asset assigned. Doing this on an existing Data Layer Instance creates a new child Data Layer Instance with the selected Data Layer Asset assigned.



Assigning a Data Layer Asset to a Data Layer Instance.

Assigning Actors to Data Layers

You can assign an Actor to a Data Layer by using the following options:

Add an asset using the context menu in the Data Layers Outliner.

Add an asset using the Data Layers section in the Details Panel.



Assigning Actors to a Data Layer Instance using the Data Layer Outliner.

To add assets to a Data Layer Instance using the Data Layers Outliner:

Select the assets you want to add to the Data Layer Instance in the Viewport.

Right click on the Data Layer Instance in the Data Layers Outliner that you want to add to and select Add Selected Actors to Selected Data Layers.



Assigning Actors to a Data Layer Instance using the Details Panel.

To add assets to a Data Layer Instance using the Details panel:

Select the assets you want to add to the Data Layer Instance in the Viewport.

Navigate to the Data Layers section of the Details and open Data Layers Assets.

Click the drop down menu for the Index you want to change and select the Data Layers Asset you want to assign. This will assign it to the instance of that Data Layers asset.

This method only works when an instance of the selected Data Layers Asset exists in the world.

Using Actor Editor Context in the level editor, you can set any number of Data Layer Instances as Current. All Actors added with this context active are automatically assigned to the Data Layer Instance set as Current. For more information on Actor Editor Context, see Actor Editor Context.

Performance Concerns

Loading too many assets at once using Data Layers can lead to performance issues.

You should monitor Runtime Data Layer Instance usage closely. Widely used assets assigned to too many Runtime Data Layer Instances can degrade World Partition streaming performance.

Using Data Layers with Blueprints

You can use Blueprints to change the runtime state of Data Layer Assets and Data Layer Instances.

In the example below, pressing and holding the F key will deactivate the GreyBox Data Layer and activate the Ruins Data Layer.



A Blueprint using Data Layers.

The above Blueprint works by doing the following:

Pressing and holding the F key accesses the Data Layer Subsystem.

Using the Set Data Layer Instance Runtime State node, the state of the DL_GreyBox Data Layer Instance changes to Loaded. This makes it loaded but not visible in the level.

The second Set Data Layer Instance Runtime State node changes the state of the DL_Ruins Data Layer Instance to Activated. This makes it loaded and visible.

Releasing the F key reverses the process and sets both Data Layer Instances back to their original states.





Using Data Layers with C++

Similar to the Blueprint example above, you can access your project's Data Layers using C++. The example code shown below creates an Actor named ADataLayerActivator.

When ADataLayerActivator calls BeginPlay, it references a specific data layer and sets its runtime state to Active.

Using Data Layers with Level Instancing

Level Instances and Packed Level Blueprints support Data Layers.

The Actors contained within the Level Instance inherit the Data Layer assigned to its Level Instance Actor by default. Actors within the Level Instance also support additional Data Layers.

Level Instances that contain a reference to a Data Layer Instance not present in the world will not have their Data Layer references carried over.

For example, you can assign a Level Instance that contains the assets to create a house point of interest to a Neighborhood data layer. The Level Instance can also contain holiday-themed items assigned to different holiday data layers only visible when that data layer is enabled.

Managing Files

Keeping with the World Partition system's goal of minimizing file overlap between users, Data Layers reduce the need for users to check out important files, such as the world map file or Actor files, when changes are made.

Each Data Layer has a display label and an internal unique identifier. Unreal Engine stores this information in a list of Data Layers in the WorldDataLayer file which provides the following benefits:

Assigning Data Layers to an Actor only affects that Actor's file In a World Partition world using One File Per Actor.

Renaming a Data Layer only affects its associated label. There is no need to update any Actors associated with the layer.

Deleting a Data Layer only affects the WorldDataLayer file. Actors previously associated with the deleted Data Layer are automatically cleaned up with no need to modify or save the Actor.

Debugging and Runtime Overrides

There are several useful console commands for debugging Data Layers during runtime.

Console Command

Description

wp.DumpDatalayers

Outputs a list of Data Layers and their runtime state in the log.

wp.Runtime.DebugFilerByDatalayer

Filters which Data Layer is visible in the runtime hash 2d debug display.

wp.Runtime.SetDataLayerRuntimeState [state] [layer]

Forces a Data Layer to a specific runtime state.

wp.Runtime.ToggleDataLayerActivation [layer]

Toggles a specific runtime data layer.

wp.Runtime.ToggleDrawDataLayers

Displays a list of Data Layers and their states in the main view.

Choose your operating system:

Windows

macOS

Linux



Click image for full size.



The Default Interface

Tab Bar

Menu Bar

Toolbar

Bottom Toolbar

Viewport

Details

Modes

Outliner

Layers

The Level Editor provides the core level creation functionality for Unreal Editor. You will use it to create, view, and modify levels .You will modify a level mainly by placing, transforming, and editing the properties of Actors.

In Unreal Editor, the scenes in which you create your game experience are generally referred to as Levels. You can think of a level as a 3D environment into which you place a series of objects and geometry to define the world your players will experience. Any object that is placed in your world, be it a light, a mesh, or a character, is considered to be an Actor. Technically speaking, an Actor is a programming class used within the Unreal Engine to define an object that has 3D position, rotation, and scale data. Think of an Actor as any object that can be placed in your levels.

Creating levels begins by placing items in a map inside Unreal Editor. These items may be world geometry, decorations in the form of Brushes, Static Meshes, lights, player starts, weapons, or vehicles. Which items are added when is usually defined by the particular workflow used by the level design team.

The Default Interface

Since the interface for Unreal Editor is highly customizable, it is possible that what you see may change from one launch to the next. Below, you can see the default interface layout.



Click image for full size.



Tab Bar and Menu Bar

Toolbar

Buttom Toolbar

Place Actor / Modes

Viewports

Content Browser / Content Drawer

Outliner

Details

Tab Bar

The Level Editor has a tab along the top with the name of the current level. Tabs from other editor windows may be docked alongside this tab for quick and easy navigation, similar to a web browser.



Click image for full size.



The name of the tab reflects the level currently being edited. This is a pattern consistent throughout the editor—tabs will be named after the current asset being edited.

To the right of the Tab Bar is the name of the current project.

Menu Bar

The Menu Bar in the editor should be familiar to anyone who has used Windows applications previously. It provides access to general tools and commands that are used when working with levels in the editor.



Click image for full size.



The Console (`) is a text field that allows special console commands to be entered that are recognized by the editor. The text field has an auto-complete feature that automatically lists all commands matching the characters in the field.

If are running Source Control, the button on the far right of the menu bar is indicates its status.

Button

Name

Description

= On = Off

Source Control Status

Mouse over the button for connection details. A green icon can be clicked to log in to your connection. A red icon indicates that source control is not in use. Perforce and Subversion are supported. See Source Control documentation for details.

Toolbar



Click image for full size.

The Toolbar panel displays a group of commands, providing quick access to commonly used tools and operations.

See the Toolbar page for descriptions Toolbar items.

Bottom Toolbar



Click image for full size.

Contains shortcuts to the Command Console, Output Log, and Derived Data functionality. Also displays source control status.

See the Toolbar page for descriptions Toolbar items.

Viewport

The Viewport panel is your window into the worlds you create in Unreal Engine.



Click image for full size.

This panel contains a set of viewports, each of which can be maximized to fill the entire panel and offer the ability to display the world from one of three orthographic views (Top, Side, Front) or a perspective view giving you complete control over what you see and how you see it.

See Viewports for more information on working with viewports.

Details



Click image for full size.

The Details panel contains information, utilities, and functions for the current selection in the viewport. It contains transform edit boxes for moving, rotating, and scaling Actors, displays all of the editable properties for the selected Actors, and provides quick access to additional editing functionality depending on the type of Actor(s) selected in the viewport. For example, selected Actors can be exported to FBX and converted to another compatible type. Selection Details allow you to view the materials used by the selected Actors, if any, and quickly open them for editing.

See the Details page for a more complete overview and guide to using the Details panel in the Level Editor.

Modes

The Level Editor can be put into different editing modes to enable specialized editing interfaces and workflows for editing particular types of Actors or geometry.

To display a selection of modes, in the Level Editor Toolbar, open the Modes dropdown.



Click image for full size.

Icon

Mode

Shortcut

Description



Select

Shift + 1

Activate Select mode to select Actors in your scene.



Landscape

Shift + 2

Activate Landscape mode to edit Landscape terrains.



Foliage

Shift + 3

Activate Foliage Mode to paint instanced foliage.



Mesh Paint

Shift + 4

Activate Mesh Paint mode to paint vertex colors and textures on Static Mesh Actors directly in the viewport.



Modeling

Shift + 5

Activate Modeling editing mode.



Fracture

Shift-6

Activate Fracture mode to create destructible objects and environments.



Brush Editing

Shift + 7

Activate Brush Editing mode to modify Geometry Brushes.



Animation

Shift + 8

Activate Animation editing mode.

Modes change the primary behavior of the Level Editor for a specialized task, such as moving and transforming assets in the world, sculpting landscapes, generating foliage, creating geometry brushes and volumes, and painting on meshes. Modes panels contain a selection of tools tailored to the selected editing mode.



Click image for full size.

The Landscape panel

You can close any panel by clicking the small "X" in the upper-right corner of the tab. You can also hide any panel by right-clicking on the tab, and then clicking Hide Tab on the context menu that appears. To reopen a panel that you have closed, click that panel's name on the Window menu.

Outliner



Click image for full size.

The Outliner panel displays all of the Actors within the scene in a hierarchical tree view. You can select and modify Actors directly from the Outliner. Use the Info dropdown menu to display an additional column that shows Levels, Layers, or ID Names.

See the Outliner page for details on using the Outliner.

Layers

The Layers panel allows you to organize Actors in your Level.



Click image for full size.

Layers provide the ability to quickly select as well as control visibility of groups of related Actors. You can use your layers to quickly un-clutter a scene leaving only the geometry and Actors that you are working with. For example, you might be working on a building that has multiple levels but is comprised of many modular parts. By assigning each floor to a layer, you can hide each of the floors you are not working on making the top view much more manageable.

See the Layers Panel page for details on using the Layers panel.

Viewport Topics



Click image for full size.

The Viewports are your window into the worlds you create in Unreal. They can be navigated just as you would in a game, or can be used in a more schematic design sense as you would for an architectural Blueprint. The Unreal Editor viewports contain a variety of tools and visualizers to help you see exactly the data you need.

Viewport Topics

The following topics will get you up to speed on the many ways you can utilize the Unreal Editor viewports.



Basic concepts and features of the Viewports in Unreal Editor.



Explanations for the available View Modes within the viewports.



Descriptions of all of the available Show Flags for the viewports.



Learn about the various control schemes for the editor's viewports.

Viewport Types

Viewport Layout

View Modes

Game View

Immersive Mode

Choose your operating system:

Windows

macOS

Linux

The Viewports are your window into the worlds you create in Unreal. They can be navigated just as you would in a game, or can be used in a more schematic design sense as you would for an architectural Blueprint. The Unreal Editor viewports contain a variety of tools and visualizers to help you see exactly the data you need.



Click image for full size.

Viewport Types

There are two main types of Viewports in Unreal Editor: Perspective and Orthographic. The perspective view is a 3D window into the game world. The Orthographic views - Front, Side, and Top - are 2D Viewports that each look down one of the main axes (X, Y, or Z).









Perspective (3D)

Front (X-Axis)

Side (Y-Axis)

Top (Z-Axis)

You can cycle through the types of Viewports by pressing Alt and G, H, J, or K. These set the Viewport to be Perspective, Front, Side, or Top, respectively.

Viewport Layout

By default, you see a single Perspective Viewport when you open Unreal Editor.



Click image for full size.

The Viewport panel actually contains multiple Viewports, which are laid out in a grid and any of which can be shown

The default layout is a 4x4 that consists of one of each type of Viewport - Perspective, Top, Front, and Side.



Click image for full size.

The Viewports can be minimized and maximized using the and buttons located in the top right corner of each Viewport.

View Modes

The Unreal Editor viewports have a large number of visualization modes to help you see the type of data being processed in your scene, as well as to diagnose any errors or unexpected results. The more common view modes have their own hotkeys, but all can be accessed from the viewport within the View Mode menu.



Click image for full size.



Click image for full size.

The most commonly used view modes are shown here:







Lit

Unlit

Wireframe

See Viewport Modes for a listing and description of all available modes.

Game View

Game View causes the Viewport to display the scene as it would appear in the game. This means that none of the editor-specific elements - such as the Actor icons - are shown. It gives you an easy way to see just how your level will look when you run it in the game.

Drag the slider to toggle Game View.



To enable Game View, simply press the G key (by default) with the Viewport focused or choose the Game View option from the Viewport Options menu:



Click image for full size.

Immersive Mode

Viewports have another state in addition to maximized and minimized that they can be in called Immersive Mode. This refers to Viewport being maximized out to the full extents of the window containing the Viewport panel. When you have the Level editor maximized, this enables you to have your Viewport run in full-screen for a truly immersive editing experience!

To enable Immersive Mode, simply press the F11 key (by default) with the Viewport focused or choose the Immersive Mode option from the Viewport Options menu:



Click image for full size.

You can restore the Viewport to normal using the same procedure above or by pressing the button located at the top right of the Viewport when in Immersive Mode.

Drag the slider to see Immersive Mode in action!



Drag the slider to see Immersive Mode in action!





Lit

Unlit

Wireframe

Detail Lighting

Lighting Only

Light Complexity

Shader Complexity

Stationary Light Overlap

Lightmap Density

Reflections

LOD Coloration

HLOD Coloration

Buffer Visualization

Landscape Visualizers

Exposure

The Unreal Editor viewports have a large number of visualization modes to help you see the type of data being processed in your scene, as well as to diagnose any errors or unexpected results. The more common view modes have their own hotkeys, but all can be accessed from the viewport within the View Mode menu.



Click image for full size.



Click image for full size.

Lit



Click image for full size.

View Mode Hotkey: Alt + 4

Console command: viewmode lit

Lit view mode shows the final result of your scene once all of the Materials and lighting have been applied.

Unlit



Click image for full size.

View Mode Hotkey: Alt + 3

Console command: viewmode unlit

Unlit view mode removes all lighting from the scene, showing you Base Color only.

Wireframe



Click image for full size.

View Mode Hotkey: Alt + 2

Console command: viewmode wireframe

Wireframe shows all of the polygon edges in the scene. In the case of Brushes, you will see the resultant geometry.

Detail Lighting



Click image for full size.

View Mode Hotkey: Alt + 5

Console command: viewmode lit_detaillighting

Detail Lighting activates a neutral Material across the entire scene, using the normal maps of the original materials. This is useful for isolating whether your BaseColor is obscuring lighting by being too dark or noisy.

Lighting Only



Click image for full size.

View Mode Hotkey: Alt + 6

Console command: viewmode lightingonly

Lighting Only shows a neutral Material that is only affected by lighting. It differs from Detail Lighting mode in that you will not see normal maps.

Light Complexity



Click image for full size.



Click image for full size.

View Mode Hotkey: Alt + 7

Console command: viewmode lightcomplexity

Light Complexity shows the number of non-static lights affecting your geometry. This is useful for tracking lighting cost - the more lights affecting a surface, the more expensive it will be to shade.

Light Complexity Coloration

Color













Number of Lights Affecting Surface

0

1

2

3

4

5+

This color scheme is defined in the shader code.

Shader Complexity



Click image for full size.

View Mode Hotkey: Alt + 8

Console command: viewmode shadercomplexity

Shader Complexity Mode is used to visualize the number of shader instructions being used to calculate each pixel of your scene. It is generally a good indication of how performance-friendly your scene will be. In general, it is used to test overall performance for your base scene, as well as to optimize particle effects, which tend to cause performance spikes with a large amount of overdraw for a short period of time.

Only instruction count is used to calculate shader complexity, which may not always be accurate. For example, a shader with 16 instructions, all texture lookups, will be much slower on all platforms than a shader with 16 math instructions. Also shaders which contain loops that are not unrolled will not be represented accurately by the instruction count, this is mainly an issue for vertex shaders. Overall the instruction count is a good metric in the vast majority of cases.

The view mode uses a color spectrum to indicate how expensive the scene is. Green through red represent a linear relationship of "very inexpensive" to "expensive", while pink and white indicate a large jump to "very expensive" pixels. Small areas of white can be tolerated, but if the majority of your screen is covered in bright red or white, the performance will be poor.

Shader Complexity Coloration





































Ideal

Moderate

Expensive

Very Expensive

+ShaderComplexityColors is defined in the BaseEngine.ini file and is linearly interpolated (lerped) based on the total number of instructions for a given pixel.

+ShaderComplexityColors=(R=0.0,G=1.0,B=0.127,A=1.0)+ShaderComplexityColors=(R=0.0,G=1.0,B=0.0,A=1.0)+ShaderComplexityColors=(R=0.046,G=0.52,B=0.0,A=1.0)+ShaderComplexityColors=(R=0.215,G=0.215,B=0.0,A=1.0)+ShaderComplexityColors=(R=0.52,G=0.046,B=0.0,A=1.0)+ShaderComplexityColors=(R=0.7,G=0.0,B=0.0,A=1.0)+ShaderComplexityColors=(R=1.0,G=0.0,B=0.0,A=1.0)+ShaderComplexityColors=(R=1.0,G=0.0,B=0.5,A=1.0)+ShaderComplexityColors=(R=1.0,G=0.9,B=0.9,A=1.0)

MaxPixelShaderAdditiveComplexityCount is set to a default range of 2000, however, this value can be changed in the BaseEngine.ini file to help with the optimization of materials in your project.

MaxES3PixelShaderAdditiveComplexityCount defines the range in the ES3 Preview Mode and is set to a default range of 800.

These Colors can be modified in the BaseEngine.ini file. The max pixel shader additive complexity count variables can also be overridden in your project's DefaultEngine.ini file.

Stationary Light Overlap



Click image for full size.

View Mode Hotkey: None (Menu only by default)

Lightmap Density



Click image for full size.

View Mode Hotkey: Alt + 0

Lightmap Density mode displays the lightmap density of objects that are texture mapped, color coding them by their relation to an ideal/max density setting and displaying a grid that maps to the actual lightmap texels. It is important to have even texel density across your scene to get consistent lightmap lighting.







Less than ideal texel density

Ideal texel density

Max or greater than ideal texel density

Skeletal Meshes will appear in light brown and are not considered in this calculation.

Reflections



Click image for full size.

View Mode Hotkey: None (Menu only by default)

Reflections view mode overrides all materials with a flat normal and a roughness of 0, which is a mirror. This is useful for diagnosing the detail of reflections and allowing you to place more Reflection Capture Actors in areas where you need more detail.

LOD Coloration



Click image for full size.



Click image for full size.

Console command: viewmode LODColoration

LOD Coloration view mode displays the current LOD index of a primitive. This is useful for diagnosing any LOD issues or to see at which distance your LODs are switching.

LOD Primitive Coloration

Color

















LOD Primitive Color

0

1

2

3

4

5

6

7

+LODColorationColors=(R=1.0,G=1.0,B=1.0,A=1.0)+LODColorationColors=(R=1.0,G=0.0,B=0.0,A=1.0)+LODColorationColors=(R=0.0,G=1.0,B=0.0,A=1.0)+LODColorationColors=(R=0.0,G=0.0,B=1.0,A=1.0)+LODColorationColors=(R=1.0,G=1.0,B=0.0,A=1.0)+LODColorationColors=(R=1.0,G=0.0,B=1.0,A=1.0)+LODColorationColors=(R=0.0,G=1.0,B=1.0,A=1.0)+LODColorationColors=(R=0.5,G=0.0,B=0.5,A=1.0)

By default the engine uses only four LODs, but this can be extended in the source code.

HLOD Coloration



Click image for full size.

Console command: viewmode hlodcoloration

HLOD Coloration view mode displays the Hierarchial LOD Cluster index of a primitive.

HLOD Primitive Coloration

Color











HLOD Primitive Color

0

1

2

3

4

+HLODColorationColors=(R=1.0,G=1.0,B=1.0,A=1.0) //white (not part of HLOD)+HLODColorationColors=(R=0.0,G=1.0,B=0.0,A=1.0) //green (part of HLOD but being drawn outside of it)+HLODColorationColors=(R=0.0,G=0.0,B=1.0,A=1.0) //blue (HLOD level 0)+HLODColorationColors=(R=1.0,G=1.0,B=0.0,A=1.0) //yellow (HLOD level 1)+HLODColorationColors=(R=1.0,G=0.0,B=1.0,A=1.0) //purple+HLODColorationColors=(R=0.0,G=1.0,B=1.0,A=1.0) //cyan+HLODColorationColors=(R=0.5,G=0.5,B=0.5,A=1.0) //grey

Buffer Visualization



Click image for full size.

The Buffer Visualization area offers you access to individual buffers within the graphics card, which can help you diagnose problems how your scenes look. In order to make the most out of the buffer visualization modes, it will help to understand the basics of Material Inputs and Material Properties.

Buffer Overview



Click image for full size.

The Buffer Overview visualization mode allows you to see multiple images from the graphics card's GBuffer. Many of these correlate to inputs on Materials, meaning you can see how the scene looks with just a single Material input being used.

Base Color



Click image for full size.

View Mode Hotkey: None (Menu only by default)

The Base Color mode allows you to see the only the Base Color of the Materials in your scene.

Decal Mask



View Mode Hotkey: None (Menu only by default)

The Decal Mask mode shows in white any surface which can receive deferred decals. Objects which cannot appear in black.

Diffuse Color

[

View Mode Hotkey: None (Menu only by default)

Diffuse Color shows the result of Base Color and the Material's Ambient Occlusion inputs.

Shading Model



Click image for full size.

View Mode Hotkey: None (Menu only by default)

The Shading Model mode shows value of the Shading Model property for each Material in the scene.

Light Complexity Coloration

Color









Material's Shading Model

Default Lit

Unlit

Subsurface

Preintegrated Skin

Material AO





View Mode Hotkey: None (Menu only by default)

The Material AO visualization mode shows the result of any texturing or Material Expression nodes that are connected to the Material's Ambient Occlusion input.

Metallic



Click image for full size.

View Mode Hotkey: None (Menu only by default)

The Metallic visualization mode shows the result of any texturing or Material Expression nodes that are connected to the Material's Metallic input.

Note: Materials should generally have Metallic values of 0 or 1, not in between. Values between 0 and 1 will happen due to layer blending, but physical materials will always be a metal or not.

Opacity





View Mode Hotkey: None (Menu only by default)

Opacity visualization mode shows the result of any texturing or Material Expression nodes that are connected to the Material's Opacity input. In the images above, you can see the dreadlocks on the character are somewhat transparent.

The Opacity viewmode only shows opaque materials with Opacity being used, which is important in the case of subsurface scattering materials, as the Opacity controls how far light can penetrate.

Roughness



Click image for full size.

View Mode Hotkey: None (Menu only by default)

Roughness visualization mode shows the result of any texturing or Material Expression nodes that are connected to the Material's Roughness input. Roughness variation is where a lot of reflection variation will come from.

Scene Color



Click image for full size.

View Mode Hotkey: None (Menu only by default)

Scene Color shows the result of the scene before any post processing is done. This means before any exposure, bloom, color correction, or antialiasing. In the above image, the scene appears very dark because exposure has not brightened it up for us.

Scene Depth



Click image for full size.

View Mode Hotkey: None (Menu only by default)

Scene Depth shows the depth of the scene in a constant gradient from white (farthest away) to black (closest).

Separate Translucency RGB



Click image for full size.

View Mode Hotkey: None (Menu only by default)

Separate Translucency RGB shows the color information of any Materials that are Translucent and using Separate Translucency.

Separate Translucency A



Click image for full size.

View Mode Hotkey: None (Menu only by default)

Separate Translucency A shows only the alpha information of any Materials that are Translucent and using Separate Translucency.

Specular Color



View Mode Hotkey: None (Menu only by default)

Specular Color shows the color being imparted to the specular reflections of a Material. Generally, this is inferred from a combination of the Base Color and Metallic values.

Specular



Click image for full size.

View Mode Hotkey: None (Menu only by default)

Specular shows the results of any texturing or Material Expression nodes that are fed into a Material's Specular input.

Subsurface Color



Click image for full size.

View Mode Hotkey: None (Menu only by default)

Subsurface Color shows the results of any texturing or Material Expression nodes that are fed into a Material's Subsurface Color input.

World Normal



Click image for full size.

View Mode Hotkey: None (Menu only by default)

World Normal shows the world space normal of any opaque surfaces.

Ambient Occlusion



Click image for full size.

View Mode Hotkey: None (Menu only by default)

Ambient Occlusion (AO) shows the result of any ambient occlusion calculations that are taking place on the scene. This is separate from any AO textures applied to Materials, as this is a calculation the engine makes based on surfaces and normal maps.

Landscape Visualizers



Click image for full size.

Normal



Click image for full size.

The Normal Landscape visualization mode shows a Landscape in its normal, lit state.

LOD



Click image for full size.

The LOD Landscape visualization mode breaks a landscape up into color-coded panels which represent their current LOD state.

Layer Density



Click image for full size.

The Layer Density Landscape visualization mode shows the landscape in a color-coded mode which shifts from green to red as more layers are added to the Landscape.

Exposure



Click image for full size.

Exposure is a post-processing effect that controls the overall brightness of a scene. This can be set to a fixed value or left to automatic.

Automatic vs. Fixed Exposure

When playing games with Exposure activated in your post processing, you will notice that moving from a light to a dark area or vice versa will cause the camera to temporarily adjust, similarly to how our eyes adjust when moving to different light environments. In most cases, this will be the desired result. However, if the constant shifting is distracting in your particular level, then you can set the view to a fixed exposure. This will lock the exposure in place so it no longer automatically changes as you move from light to dark or dark to light, but it also means that you can easily end up in a situation where the lights are overbright or overdark for the work you need to do.



Click image for full size.

Common

Post Processing

Light Types

Lighting Components

Lighting Features

Lumen

Developer

Visualize

Advanced

Volumes

Layers

Sprites

Foliage Types

The Show Flags are found under the Viewport Show menu. They are a means by which you can show and hide many of the items that are viewed within the viewport. For example, you can hide all particles, all landscape objects, or something a bit more advanced like turning off all of the sprite icons.



Click image for full size.

Common



Click image for full size.

Common



Name





Description



Anti-aliasing

Shows/hides the effect of anti-aliasing.

Atmosphere

Shows/.

BSP

Shows/hides any Brushes in the level. (Alt + Q)

Collision

Shows/hides collision objects in the level. (Alt + C)

Decals

Shows/hides decals in the scene.

Fog

Shows/hides the effects of Height Fog. (Alt + F)

Grid

Shows/hides the grid.

Landscape

Shows/hides any Landscape objects. (T)

Media Planes

Shows/.

Navigation

Shows/hides any Nav Meshes or other navigation Actors. (P)

Particles Sprite

Shows/hides any particles in the scene.

Skeletal Meshes

Shows/hides any Skeletal Meshes in the scene.

Static Meshes

Shows/hides any Static Meshes in the scene. (Alt + W)

Translucency

Shows/hides all objects with translucent Materials. Incidentally, this includes all billboard icons.

Widget Components

Shows/.

Post Processing



Click image for full size.

Post Processing



Name





Description



Bloom

Shows/hides the effect bloom.

Camera Imperfections

Shows/hides the effect of Camera Imperfections.

Color Grading

Shows/hides the effect of Color Grading.

Depth of Field

Shows/hides the effect of Depth of Field.

Eye Adaptation

Shows/hides the effect of Eye Adaptation.

Grain

Shows/hides the effects of Grain.

HMD Distortion

Shows/hides the effects of head-mounted display distortion, such as that used for Oculus Rift.

Lens Flares

Shows/hides the effect of Lens Flares.

Local Exposure

Shows/.

Motion Blur

Shows/hides the effect of Motion Blur.

Post Process Material

Shows/hides the effect of any blendable post process Materials in the scene.

Scene Color Fringe

Shows/hides the result of any Scene Color Fringe effects.

Tone Curve

Shows/.

Screen Percentage

Shows/hides the result of Screen Percentage post effects.

Tonemapper

Shows/hides Tonemapper effects.

Vignette

Shows/hides Vignette effects.

Light Types



Click image for full size.

Lighting Types



Name





Description



Directional Lights

Shows/hides the result of lighting from the Directional Light actor in the scene.

Point Lights

Shows/hides the result of lighting from the Point Light actor in the scene.

Rect Lights

Shows/.

Sky Lighting

Shows/hides the result of lighting from the Sky Light actor in the scene.

Spot Lights

Shows/hides the result of lighting from the Spot Light actor in the scene.

Lighting Components



Click image for full size.

Lighting Components



Name





Description



Ambient Occlusion

Shows/hides ambient occlusion in the scene.

Diffuse

Shows/hides the result of diffuse lighting in the scene, which contains most of the scene color.

Direct Lighting

Shows/hides the result of direct lighting, which contains most of the scene specularity.

Dynamic Shadows

Shows/hides dynamic shadows in the scene.

Global Illumination

Shows/hides the result of global illumination in the scene.

Specular

Shows/Hides the result of specularity in the scene.

Lighting Features



Click image for full size.

Lighting Components



Name





Description



Ambient Cubemap

Shows/hides the result of the ambient cubemap.

Capsule Shadows

Shows/.

Distance Field Ambient Occlusion

Shows/hides the result of the AO generated from Distance Field meshes.

Distance Field Shadows

Shows/hides the result of the GI generated from Distance Field meshes.

Indirect Lighting Cache

Shows/hides the result of indirect lighting on dynamic objects.

Light Functions

Shows/hides the result of light function materials on lights.

Light Shafts

Shows/hides the result of light shafts.

Lumen Global Illumination

Shows/.

Lumen Reflections

Shows/.

Reflection Environment

Shows/hides the result of the reflection environment.

Screen Space Ambient Occlusion

Shows/hides the result of any screen space ambient occlusion.

Screen Space Contact Shadows

Shows/.

Screen Space Reflections

Shows/hides the result of screen space reflections.

Subsurface Scattering

Shows/hides the result of any subsurface scattering within the screen space.

Textured Light Profiles (IES Textures)

Shows/hides the result of IES lighting profiles.

Volumetric Fog

Shows/.

Volumetric Lightmap

Shows/.

Lumen



Click image for full size.

Lumen



Name





Description



Detail Traces

Shows/.

Far Field Traces

Shows/.

Global Traces

Shows/.

Reuse Shadow Maps

Shows/.

Screen Space Directional Occlusion

Shows/.

Screen Traces

Shows/.

Secondary Bounces

Shows/.

Developer



Click image for full size.

Developer



Name





Description



AI Debug

This shows the paths an AI-driven pawn is using to navigate along a Nav Mesh.

Bones

Shows/.

Cache Virtual Shadow Maps

Shows/.

Composite Editor Primitives

Show/hide editor primitives in the scene.

Dedicated Server Debug Drawing

Shows/.

Disable Hardware Occlusion Queries

Shows/.

Gameplay Debug

This shows the paths an AI-driven pawn is using to navigate along a Nav Mesh.

GBuffer Hints (material attributes)

Colorizes objects that have improper Materials. Yellow for objects that are impossibly non-reflective, red for objects that emit more light than they receive.

Hit Proxies

Shows/hides the proxy shapes used by hit detection.

Log Visualizer

Draws any data to the screen that is required by the Log Visualizer system.

Make Composite Editor Primitives Opaque

Shows/.

On Screen Debug

This is to hide things like VisualizeTexture or stats printout.

Refraction

Shows/hides the results of refraction on Materials.

Shadows of Editor-Hidden Actors

Shows dynamic shadows for objects that are hidden in the editor, such as those hidden by pressing the H key.

Test Image

Shows a test image for configuration of monitor and graphics settings.

Vector Fields

Shows/hides any vector fields in the scene.

Virtual Texture Primitives

Shows/.

Visualize Calibration Color

Shows/.

Visualize Calibration Custom

Shows/.

Visualize Calibration Grayscale

Shows/.

Visualize



Click image for full size.

Visualize



Name





Description



Adaptive Depth of Field

Applies a color coding filter to the view such that objects that are blurred by Depth of Field are tinted green and only the area in focus receives its normal color.

Bloom

Shows a visualization window that expresses the scene histogram, as well as how settings are affecting bloom.

Depth of Field Layers

Applies a color coding filter to the view such that objects blurred by near DOF are green, objects blurred by far DOF are blue. Objects in focus appear black.

Distance Field Ambient Occlusion

Shows a visualization of ambient occlusion generated based on mesh distance fields.

Draw Only Geometry Causing VSM Invalidation

Shows/.

Global Distance Field

Shows a visualization of global illumination generated based on mesh distance fields.

HDR

Shows a visualization window that expresses the scene histogram, as well as how exposure settings are affecting brightness.

Light Propagation Volumes

Shows a visualization of the volume that is used for light propagation volumes.

Local Exposure

Shows/.

Mesh Distance Fields

Shows a visualization of the generated mesh distance fields for static meshes in the scene.

Motion Blur

When Motion Blur is on, this changes the view to a Motion Blur visualizer, allowing you to see the motion vectors being used to calculate blur.

Motion Vectors

Shows/.

Out of Bounds Pixels

If a pixel of an object exists outside that object's bounding volume, it can lead to flickering or the object disapearing when the bounding volume (but not the mesh) is off camera. This visualizer colorizes those pixels in blue, yellow, and white.

Physics Field

Shows/.

Precomputed Visibility Cells

Shows a visualization of precomputed visibility cells when used with Precomputed Visibility Volumes.

Preview Shadows Indicator

When lighting has not been built for Static/Stationary lights the "Preview" text will show in unbuilt shadows.

Screen Space Reflections

A visualization for Screen Space Reflections.

Shading Models

Shows/.

Sky Atmosphere

Shows/.

Strata Material

Shows/.

Subsurface Scattering (Screen Space)

A visualization mode that allows you to see subsurface scattering within screen space.

Visualize Level Instance Editing

Shows/.

Visualize Lighting on Probes

Shows/.

Visualize Occlusion Queries

Shows/.

Visualize Post Process Stack

Shows/.

Volume Lighting Samples

Shows a visualization of the volume lighting samples that are placed within a Lightmass Importance Volume when static lighting is built.

Advanced



Click image for full size.

Advanced



Name





Description



Atmospheric Fog

Shows/hides atmospheric fog Actors in the scene.

Audio Radius

Shows/hides the radius of any audio Actors in the scene.

Billboard Sprites

Shows/hides any billboard sprites in the level. This does not extend to sprite particles, only Billboard Components.

Bounds

Shows/hides bounds on selected objects.

BSP Split

Shows/hides Brush surface splits on world geometry.

Camera Aspect Ratio Bars

Shows/hides the bars used with specific aspect ratios set in the camera actor.

Camera Frustums

Shows/hides view frustums of any cameras in the scene.

Camera Safe Frames

When looking through a Camera Actor, this shows the safe frames for that camera. Safe frames are areas a set distance from the edge of the screen where you can guarantee the image will be visible.

Constraints

Shows/hides rigid body constraints. TODO

Deferred Lighting

Shows/hides the deferred lighting in the scene.

Foliage

Shows/hides any Foliage Actors in the scene.

Force Feedback Radius

Shows/.

Grass

Shows/hides any Grass Type Actors in the scene.

HISM/Foliage Cluster Tree

Shows/.

HISM/Foliage Occlusion Bounds

Shows/.

Instanced Static Meshes

Shows/hides any instanced Static Meshes in the scene.

Large Vertices

Shows/hides larger-than-usual vertices on any selected Brushes or Static Meshes.

Level Coloration

Color codes the scene such that each streamed level gets another color. Irrelevant if not using level streaming.

Light Influences

Shows orange lines which point out what lights are influencing selected objects.

Light Radius

Shows/hides light radius shapes. (Alt + R)

LOD Parenting

Use LOD parenting, MinDrawDistance, etc. If disabled, will show LOD parenting lines.

Mass Properties

Shows/.

Mesh Edges

This overlays the mesh wireframe on top of the view.

Mode Widgets

Shows/hides the transform widgets, such as the Move tool.

Nanite Meshes

Shows/.

Niagara Renderers

Shows/.

Paper 2D Sprites

Shows/hides the radius of any Paper 2D Sprite Actors in the scene.

Physical Material Masks

Shows/.

Precomputed Visibility

Shows/hides the radius of any Precomputed Visibility volumes in the scene.

Property Coloration

Shows/.

Render (3D) Text

Whether or not to render any Text Actors or Components that may be in the scene.

Selection

Shows/hides the result of the Selection Highlight.

Senses

Shows/.

Separate Translucency

This shows/hides any objects that are making use of Separate Translucency in their Materials.

Shadow Frustums

Shows/hides a selection of color-coded boxes which represent the shadow frustums used to cast shadows from each light.

Single Layer Water Refraction Full Precision

Shows/.

Splines

Shows/hides any Spline Actors that exist in the level.

Streaming Bounds

Shows/hides spherical radii for each streaming level.

Temporal AA (instead FXAA)

Activates/deactivates Temporal Anti-aliasing. When unchecked, the viewport shows fast approximation anti-aliasing (FXAA).

Tessellation

Shows/hides the result of tessellation in Materials.

Vertex Colors

Shows/hides any vertex colors applied to meshes in the scene.

Visualize Instance Updates

Shows/.

Volumes

Shows/hides any volumes in the scene. (Alt+O)

Volumes



Click image for full size.

Volumes



Name





Description



Show All

Shows all types of volumes in the scene.

Hide All

Hides all types of volumes in the scene.

Audio

Shows/hides Audio Volumes.

Blocking

Shows/hides Blocking Volumes.

Camera Blocking Volume

Shows/hides Camera Blocking Volumes.

Cull Distance

Shows/hides Cull Distance Volumes.

Hierarchical LOD Volume

Shows/hides Hierarchical LOD Volumes.

Kill Z

Shows/hides Kill Z.

Level Streaming

Shows/hides Level Streaming Volumes.

Lightmass Character Indirect Detail

Shows/hides Lightmass Character Indirect Detail Volumes.

Lightmass Importance

Shows/hides Lightmass Importance Volumes.

Mesh Merge Culling

Shows/.

NavMesh Bounds

Shows/hides NavMesh Bounds Volumes.

Nav Modifier

Shows/hides Nav Modifier Volumes.

Pain Causing

Shows/hides Pain Causing Volumes.

Physics

Shows/hides Physics Volumes.

Post Process

Shows/hides Post Process Volumes.

Precomputed Visibility Override

Shows/hides Precomputed Visibility Override Volumes.

Precomputed Visibility

Shows/hides Precomputed Visibility Volumes.

Procedural Foliage Blocking Volume

Shows/hides Procedural Foliage Blocking Volumes.

Procedural Foliage Volume

Shows/hides Procedural Foliage Volumes.

Trigger

Shows/hides Trigger Volumes.

Visual Logger Filter Volume

Shows/.

Volumetric Lightmap Density

Shows/.

World Partition Volume

Shows/.

Layers



Click image for full size.

Layers



Name





Description



Show All

Sets all Layers in the scene to be visible.

Hide All

Hides all Layers in the scene.

Layer Names

This will populate with the names of any Layers you have created in your scene, so that you may show/hide each one individually.

My New Name

Shows/.

Infrastructure 2

Shows/.

Sprites



Click image for full size.

Billboard sprites are generally in-editor icons used for placement of various object types. In this case, they do not refer to sprite particles.

Billboard Sprites



Name





Description



Show All

Shows all types of billboard sprites.

Hide All

Hides all types of billboard sprites.

Characters

Shows/hides Character billboard sprites.

Decals

Shows/hides Decal billboard sprites.

Effects

Shows/hides Effects billboard sprites, which represent the location of Emitter Actors.

Fog

Shows/hides Fog Actor billboard sprites.

FTests

Shows/hides FTest billboard sprites.

Info

Shows/hides Info billboard sprites.

Lighting

Shows/hides Light Actor billboard sprites.

Materials

Shows/hides Materials billboard sprites.

Matinee

Shows/hides Matinee billboard sprites.

Misc

Shows/hides miscellaneous billboard sprites which do not fall into the other categories.

Navigation

Shows/hides Navigation billboard sprites.

Notes

Shows/hides Notes billboard sprites.

Physics

Shows/hides Physics billboard sprites.

Player Start

Shows/hides Player Start billboard sprites.

Sky

Shows/hides Sky billboard sprites.

Solver

Shows/.

Sounds

Shows/hides Sounds billboard sprites.

Target Points

Shows/hides Target Points billboard sprites.

Triggers

Shows/hides Triggers billboard sprites.

Wind

Shows/hides Wind billboard sprites.

Foliage Types



Click image for full size.

Foliage Types



Name





Description



Show All

Hide All

Navigation Controls

Standard

Magic Mouse and Magic Trackpad

Game-style

Pan, Orbit, and Zoom

Scaled Camera Zoom and Pan

Orbit Around Selection

Selection Controls

Transform Controls

Display Controls

There are various controls to enable you to navigate the scene, select and manipulate Actors, and change display options while working in the viewports.

For the purposes of this document, you should assume the following abbreviations:

Control

Abbreviation

Left Mouse Button

LMB

Right Mouse Button

RMB

Middle Mouse Button

MMB

Navigation Controls

There are a variety of ways in which to navigate the Unreal Editor viewports. Some can be done entirely with the mouse, with the keyboard, or with a variety of combinations between the two.

Some of the controls below are configurable in the Keybindings Editor. Their default state is listed here. If you have made changes to them, they may not match.

Standard

These controls represent the default behavior when clicking and dragging in the viewports with no other keys or buttons pressed. These are also the only controls that can be used to navigate the orthographic viewports.

Control

Action



Perspective



LMB + Drag

Moves the camera forward and backward and rotates left and right.

RMB + Drag

Rotates the viewport camera.

LMB + RMB + Drag

Moves up and down.



Orthographic (Top, Front, Side)



LMB + Drag

Creates a marquee selection box.

RMB + Drag

Pans the viewport camera.

LMB + RMB + Drag

Zooms the viewport camera in and out.



Focusing



F

Focuses the camera on the selected object. This is essential to make the most out of tumbling the camera.

Magic Mouse and Magic Trackpad

On a Mac, after enabling Secondary click in System Preference > Mouse for the Magic Mouse, or enabling Secondary click with two fingers in System Preference > Trackpad for the Magic Trackpad, the following controls are available.

Magic Mouse

Magic Trackpad

Action



Persepctive



LMB + Drag

1 Finger Click + Drag

Moves the camera forward and backward and rotates left and right.

RMB + Drag

2 Finger Click + Drag

Rotates the viewport camera.

1 Finger Touch + Drag

2 Finger Touch + Drag

Rotates the viewport camera.



Orthographic (Top, Front, Side)



LMB + Drag

1 Finger Click + Drag

Creates a marquee selection box.

RMB + Drag

2 Finger Click + Drag

Pans the viewport camera.

1 Finger Touch + Drag

2 Finger Touch + Drag

Pans the viewport camera.



Focusing



F

F

Focuses the camera on the selected object. This is essential to make the most out of tumbling the camera.

Game-style

The WASD controls will feel natural to those who are used to playing shooter games on the PC. They are enabled by default and can be used whenever you are holding RMB. This means you will still use RMB to turn the camera while navigating in this way.

These controls are mirrored on the arrow keys and num pad to provide alternate access to them.

All of these controls are only valid in a Perspective viewport, and by default you must hold RMB to use the WASD game-style controls.

Control

Action

W / Numpad8 / Up

Moves the camera forward.

S / Numpad2 / Down

Moves the camera backward.

A / Numpad4 / Left

Moves the camera left.

D / Numpad6 / Right

Moves the camera right.

E / Numpad9 / Page Up

Moves the camera up.

Q / Numpad7 / Page Dn

Moves the camera down.

Z / Numpad1

Zooms the camera out (raises FOV).

C / Numpad3

Zooms the camera in (lowers FOV).

When zooming the camera, holding the RMB will hold the FOV, preventing it from snapping back to its default settings. The FOV will remain until the RMB is released.

When navigating with WASD while holding down the RMB, you can rotate the mouse wheel up to speed up your movement, or rotate the mouse wheel down to slow down your movement.

While using the Magic Mouse or Magic Track you will not be able to change the speed of the camera by using the RMB + Mouse Scroll Wheel, you will need to adjust it using the Viewport camera speed option.

Pan, Orbit, and Zoom

Unreal Editor supports Maya-style pan, orbit, and zoom viewport controls, making it much easier for Maya artists to jump into the tool. If you are unfamiliar, here is a breakdown of the keys:

Command

Description

Alt + LMB + Drag

Tumbles the viewport around a single pivot or point of interest.

Alt + RMB + Drag

Dollies (zooms) the camera toward and away from a single pivot or point of interest.

Alt + MMB + Drag

Tracks the camera left, right, up, and down in the direction of mouse movement.

The use of the F key is not limited to Maya-style controls. You can always press F to focus on a selected object or group of objects.

Scaled Camera Zoom and Pan

When you have one or more objects selected in the Level Viewport, the sensitivity of zoom and pan camera operations is scaled automatically with the distance between the selected objects and the camera. This makes your camera movements feel more natural, especially when you're working with objects at extreme sizes, such as tiny mechanical parts or large landscapes.

To enable scaled zoom and pan, open the Editor Preferences window. Navigate to the Level Editor > Viewports section. In the first section on the right, called Controls, click the arrow at the bottom to expand the section to display more settings.



Click image for full size.

Locate the Use distance-scaled camera speed setting. Click the box to enable. You can disable this setting by clicking the box to clear it.



Click image for full size.

Orbit Around Selection

When you have one or more objects selected in the Level Viewport, you can make the camera orbit around the pivot of the selected objects, rather than orbiting around the center of the screen.

To enable scaled zoom and pan, open the Editor Preferences window. Navigate to the Level Editor > Viewports section. In the first section on the right, called Controls, click the arrow at the bottom to expand the section to display more settings.



Click image for full size.

Locate the Orbit camera around selection setting. Click the box to enable. You can disable this setting by clicking the box to clear it.



Click image for full size.

Selection Controls

You can select Actors in the viewport individually simply by clicking on them or in groups using a box selection in the 2D viewports:





Simple Selection

Box Selection

Control

Action



Simple Selection



LMB

Selects the Actor under the cursor, replacing the current selection.

Ctrl + LMB

Adds the Actor under the cursor to the current selection.



Box Selection (2D Viewports Only)



LMB + Drag

Replaces the current selection with the Actors contained in the box.

Shift + LMB + Drag

Adds the Actors contained in the box to the current selection.

Ctrl + RMB + Drag

Removes any select Actors in the box from the current selection.

Transform Controls

These controls relate to moving, rotating, and scaling Actors in the viewports using the transform tools:







Move Tool (W)

Rotate Tool (E)

Scale Tool (R)

You can see which tool is active in the viewport toolbar:



Click image for full size.

Control

Action

LMB + Drag (on Transform Tool)

Moves, rotates, or scales the currently selected Actors, depending on the active transform gizmo.

W

Selects the Move Tool.

E

Selects the Rotate Tool.

R

Selects the Scale Tool.

V

Toggles vertex snapping which allows you to snap to the vertices of other geometry in the world.

MMB + Drag (on Pivot)

Moves the pivot of the selection temporarily to offset transformations.



Move Tool Controls



Alt + LMB + Drag (on arrows only)

Creates and moves a duplicate of the currently selected Actor(s), leaving the original(s) unchanged.



Move Tool Controls (Perspective Viewports Only)



Ctrl + LMB + Drag

Moves the currently selected Actor(s) along the X axis.

Ctrl + RMB + Drag

Moves the currently selected Actor(s) along the Y axis.

Ctrl + LMB + RMB + Drag

Moves the currently selected Actor(s) along the Z axis.



Move Tool Controls (Orthographic Viewports Only)



Ctrl + LMB + Drag

Moves the currently selected Actor(s) along the plane defined by the two visible axes.



Rotate Tool Controls (Perspective Viewports Only)



Ctrl + LMB + Drag

Rotates the currently selected Actor(s) along the X axis.

Ctrl + RMB + Drag

Rotates the currently selected Actor(s) along the Y axis.

Ctrl + LMB + RMB + Drag

Rotates the currently selected Actor(s) along the Z axis.



Scale Tool Controls



Ctrl + LMB + Drag

Scales the currently selected Actor(s) uniformly along all axes.



Move/Scale Tool Controls (Orthographic Viewports Only)



Ctrl + RMB + Drag

Rotates the currently selected Actor(s) along the visible axis.

Display Controls

These controls affect how the level is displayed in the viewport.

Control

Action

G

Toggles Game Mode, which causes the viewport to render only what would be seen in-game.

Ctrl + R

Toggles real-time playback in the active viewport.

F11

Toggles immersive mode, which puts the viewport into full-screen.

Toolbar

Play In Editor

Simulate In Editor

Testing Gameplay

Choose your operating system:

Windows

macOS

Linux

Unreal Editor allows you to spawn a player anywhere and instantly preview your game from within the editor without waiting for files to save. There are two preview types available: Play In Editor (PIE) which is directly accessed via the Play button located on the Main Toolbar and Simulate In Editor (SIE) which is accessed via the Play dropdown menu (Alt+S). The in-editor preview system supports toggling between Play In Editor and Simulate In Editor sessions, so that you can quickly iterate on gameplay and asset tweaks and see how your game changes as a result.

When you launch a game preview session, the editor quickly creates a duplicate copy of your level. Changes can be saved back to the editor copy of the level using Keep Simulation Changes. This duplication of the level keeps the editor's copy of the world safely immutable.

Game previewing includes level streaming, and the Outliner will update accordingly so that you can select and edit Actors that are streamed in as a result of gameplay. Any Actors you have selected when you begin testing your game with a Play In Editor or Simulate In Editor session will remain selected. The reverse is also true, so any Actors selected during in-editor testing will remain selected after you end the testing session. This means that the Details panel will show the properties for an Actor you select because you want to change its appearance or behavior, even if you begin gameplay in a distant section of the level.

Toolbar

You can begin a Simulate In Editor or Play In Editor session from either the Level Editor or the Blueprint Editor, using the appropriate Toolbar buttons or dropdown menus.

From the Level Editor, you can click the Play button.



Click image for full size.

This will start a Play In Editor (PIE) session, so that gameplay can be tested directly from the editor. Different modes and options for Play In Editor sessions can be selected in the dropdown menu, and the Play In button will use the same settings that were selected for the previous session.

Click the Play dropdown button to display the Play Options dropdown menu.



Click image for full size.

You can change your Play In Editor mode, set basic networked Play In Editor options, or open the full Play In Editor settings window. Clicking on Simulate begins Simulate In Editor mode, which changes the testing section of the Toolbar. While simulating, you can pause or stop gameplay, as well as swap to a Play In Editor session with the Possess button.



Click image for full size.

Play In Editor

Clicking on the Play button in the toolbar (Alt + P) or selecting Play From Here in the Viewport context menu begins a Play In Editor session. Play In Editor allows you to play the current level directly from the editor, so that you can test gameplay functionality, including player controls and level events triggered by players' actions.

Modes

Launching a game preview with a different mode will change the default Play mode that is activated by the Play button.

Gameplay will be shown in the active Level Editor viewport.

Gameplay will be shown in a new window. To change the default size of new windows, use the Play In Editor settings window.

Gameplay will be shown in a new window that runs in its own process. To change the default standalone window size, use the Play In Editor settings window.

Gameplay begins at the current camera location.

Gameplay begins at the Player Start location.

If your game uses a NavMesh for either player-controlled or AI-controlled movement, using Camera Location for your Play In Editor starting location could cause you to spawn in a location that breaks pathing. In this case, starting a Play In Editor session from the Default Player Start is recommended.

Play From Here

You can access an additional Play In Editor mode by right-clicking in the Viewport and selecting Play From Here.



Click image for full size.

Play From Here begins gameplay at the location that you have clicked, and acts as if your Display Type is set to Level Viewport.

Switching to Simulate In Editor

While in a Play In Editor session in a viewport, press Shift+F1 to regain your mouse control. Then, click on Eject in the Toolbar to switch to a Simulate In Editor session. You will detach from the player controller, and begin a Simulate In Editor session at your current location.

You can also press the Eject keyboard shortcut (F10) to switch to Simulate In Editor from Play In Editor.

If you have set up more than one client for your Play In Editor testing with Networked Play In Editor, only the first session (the one in the Viewport) will support switching to Simulate In Editor mode. Even for single-player gameplay testing, Play In Editor sessions where the game is in a new window or in a standalone game process do not support switching to Simulate In Editor.

Simulate In Editor

Using the Simulate button begins a Simulate In Editor session in the currently active viewport. While simulating, gameplay begins, including the execution of Blueprints and C++ code that do not rely on a player's interaction with the game. While simulating, you have full access to the Editor's tools, so you can modify the scene and its contents, or even place new Actors. You can also select and inspect Pawns controlled by AI right as they are performing actions, and quickly debug and tweak gameplay behaviors. However, because you are not using a PlayerController while simulating, you cannot enter game controls. You can save certain changes made in a Simulate In Editor session using Keep Simulation Changes.

Switching to Play In Editor

While in a Simulate In Editor session, you can click on Possess in the Toolbar to switch to a Play In Editor session. You will attach to the player controller, and begin a Play In Editor session in the active level viewport.

You can also press the Possess keyboard shortcut (F10) to switch to Play In Editor from Simulate In Editor.

If you began in-editor testing with a Simulate In Editor session, and then used Possess to attach to the player controller, you will begin your Play In Editor session at the default player start. This is equivalent to selecting Play > Selected Viewport > Default Player Start from the Play dropdown menu. However, if you had previously swapped from a Play In Editor session to a Simulate In Editor session, without leaving in-editor testing mode, when you click Possess, you will re-attach to the player controller and resume gameplay at the location in the level where you previously clicked on Eject.

Testing Gameplay

Blueprints

When you enter Play In Editor or Simulate In Editor mode, all your Blueprint are compiled, although they are not saved. While playing or simulating, all Blueprint graphs are read-only, so you cannot add additional nodes or connect wires differently.



However, you can change Blueprint defaults while a preview session is active, and the changes will be applied to all instances of that Blueprint in the level you are testing.

C++

For projects that contain C++ code, there is a Compile button on the Level Editor Toolbar. This button recompiles and reloads game code on the fly. If you change a property or a function in a C++ file in your project, clicking the Compile button will recompile and reload your game module, so that your code changes are reflected in the editor. In some cases, you can even compile while using Play In Editor or Simulate In Editor, and your code changes will update without you needing to stop gameplay or simulation.

Play In Editor

Game Viewport Settings

Play in New Window

Play in Standalone Game

Multiplayer Options

Play On Device

Multiplayer Options (Server Debug Settings)

Choose your operating system:

Windows

macOS

Linux

There are two ways to open the Play settings panel.

Open the Play settings panel by clicking Edit > Editor Preferences.



Click image for full size.



Then, select the Play in the Editor Preferences window.



Click image for full size.

Or, from the Play dropdown menu, click Advanced Settings.



Click image for full size.

Play In Editor

The Play In Editor settings allow you to change different behaviors during a session. These settings only apply for Play In Editor sessions that display in the Level Viewport. As a result, there are no default window sizes to set.

Setting

Description

Game Gets Mouse Control

Enables game mouse control when PIE starts.

Use Mouse for Touch

Sends mouse movement and clicks as touch events during PIE

Show Mouse Control Label

Displays "Click for Mouse Control" and "Shift + F1 for Mouse Cursor" messages during PIE.

Mouse Control Label Position

Determinies location to anchor the Mouse Control label on screen during PIE.

Viewport Gets HMDControl

Determines if HMD orientation should be used while playing in viewport.

Should Minimize Editor on VRPIE

Minimizes editor on VR PIE.

Auto Recompile Blueprints

Determines whether to automatically recompile Blueprints used in the level when initiating a Play In Editor session.

Enable Game Sounds

Enables sound during a Play In Editor session.

Play In Editor Sound Quality Level

Determines quality level of sound during a Play In Editor session.

Stream Sub-Levels during Play in Editor

Streams sub-levels from disk instead of duplicating editor sub-levels.

Enable PIE Enter and Exit Sounds

Plays a sound when exiting or entering PIE.

Game Viewport Settings

Setting

Description

New Viewport Resolution

Sets the width and height of floating Play In Editor windows (in pixels):

Pick from a list of common window sizes, including settings for devices like phones and tablets.

New Window Width: Sets the width of the new viewport window (in pixels). A value of zero will use the desktop's screen resolution.

New Window Height: Sets the height of the new viewport window (in pixels). A value of zero will use the desktop's screen resolution.

New Window Postion

Sets the screen coordinates for the top-left corner of floating Play In Editor windows (in pixels) This will affect both Play In New Editor Window and Standalone Game:

Left Position: Sets the position of the new viewport on the screen, starting from the left (in pixels).

Top Position: Sets the position of the new viewport on the screen, starting from the top (in pixels).

Center Viewport Position: Enable to always center the position of the first viewport to screen.

Safe Zone Preview

Enables a visual preview of the device safe zone for UI testing.

Play in New Window

When starting a Play In Editor session that displays in a new window, these settings determine the size and starting position of the new window that appears.

Setting

Description

Always On Top

Always have the PIE window on top of the parent windows

Play in Standalone Game

When starting a Play In Editor session that displays in a standalone game window, these settings determine the size and starting position of the new window that appears. You can use these options to pass additional command line settings on to the game client.

Setting

Description

Client Command Line Options

Generates a command line for additional settings that will be passed to the game clients:

Disable Sound (~nosound): Disables sound in your standalone games.

Additional Launch Parameters

Adds extra parameters to be included as part of the command line for standalone games.

Additional Launch Parameters for Mobile

Adds extra parameters to be included as part of the command line for mobile-on-PC standalone games.

Multiplayer Options

These are basic and advanced options for Play In Editor Multiplayer Options. In addition to the number of players and dedicated server options from the Play dropdown menu, there are settings for URL parameters, gamepad routing, and reverting to the multiple-process testing method.

Setting

Description

Launch Separate Server

Launches a separate server even if the net mode doesn't require it. This allows you to test offline --> server workflows by connecting to a server from the offline game.

Play Net Mode

Sets the net mode used for Play In Editor session:

Play Standalone: Starts a standalone game. This will not create a dedicated server, nor automatically connect to one.

Play As Listen Server: Enables the Editor to act as both the server and the client. Additional clients can be opened depending on the number of clients.

Play As Client: Enables the Editor to act as a client. A dedicated server spawns behind the scenes to connect to.

Run Under One Process

Spawns multiplayer windows under a single instance of UE5. This will load much faster but have the potential for more issues.

Enable Network Emulation

Applies the selected network emulation settings when starting the game for the purpose of testing how your game handles network issues:

Emulation Target: Applies the emulation settings to the Server Only, Clients Only, or Everyone.

Network Emulation Profile: Applies a preset for incoming traffic and outgoing traffic. Options are Average, Bad, or Custom

Incoming traffic: Applies settings that add latency and packet loss to all incoming packets. Can add minimum and maximum latency, as well as a percentage amount of packet loss.

Outgoing traffic: Applies settings that add latency and packet loss to all outgoing packets. Can add minimum and maximum latency, as well as a percentage amount of packet loss.

Client

Applies the selected client settings when starting the game:

Play Number of Clients: Opens a number of client windows. The first one will respect Play In Editor Modes options. The rest will respect the Run Under One Process settings.

Route Gampad to Second Window: Routes the gamepad input suring a multiplayer session. If unchecked, then the first gamepad is attached to the first multiplayer window, the second to the second window, and so on. If checked, then the gamepad is routed to the second multiplayer window, allowing the first to be controlled by keyboard and mouse.

Create Audio Device for Every Player: Controls how many audio devices are created. If checked, a separate audio device is created for every player. This will render accurate audio for every player's perspective at the cost of CPU performance. If unchecked, a separate audio device is created for only the first two players.

Client Fixed FPS: Sets each client's framerate to an element in the list. Includes a Listen Server.

Server

Applies the selected server settings when starting the game:

Server Port: Opens the chosen port for simple server networking.

Server Map Name Override: Overrides the map launched by the server. Currently only used by the PIE_StandaloneWithServer net mode.

Additonal Server Game Options: Adds additional parameters that are passed to the server as URL parameters.

Additonal Server Launch Parameters: Adds additional parameters that are passed to the server as arguments.

Server Fixed FPS: Sets the server to run at the specified framerate. Does not impact Listen Server.

Multiplayer Viewport Size (in pixels): Spawns additional clients at the width and height specified. Useful when you need multiple clients but only want to interact with one window.

Play On Device

Setting

Description

Build Game Before Launch

Builds the game before launching it on the device:

Always: Always build.

Never: Never build.

If project has code, or running locally build editor.: Build based on project type.

If running a locally built editor: Build if using a locally built (i.e non-promoted) editor.

Launch Configuration

Uses the selected build configuration when launching on a device:

Same as Editor: Launches on device with the same build confoguration as the editor.

Debug: Launches on device with a Debug build configuration.

Development: Launches on device with a Development build configuration.

Test: Launches on device with a Test build configuration.

Shipping: Launches on device with a Shipping build configuration.

Auto Compile Blueprints on Launch

Recompiles dirty Blueprints before launching.

For more information on build configurations, please see the Build Configurations Reference page.

Multiplayer Options (Server Debug Settings)

Setting

Description

Show Server Debug Drawing by Default

Controls the default value of the show flag ServerDrawDebug.

Show Server Debug Drawing Color Tint Strength

Controls how strongly the debug drawing originating from the server will be biased towards the tint color.

Show Server Debug Drawing Color Tint

Debug drawing originating from the server will be biased towards this color.

Setting up Networked Testing

Advanced Settings

Debugging Blueprints

The Play In Editor (PIE) preview mode supports testing using multiple worlds, so you can test networked play. The editor spawns multiple worlds within the already loaded instance of Unreal Engine, which results in fast iteration time and allows you to debug Blueprints for each world.

Setting up Networked Testing

In the Play In drop down menu in the Level Editor Toolbar or Blueprint Editor Toolbar, you can set how many client worlds to create when you begin a Play In Editor session. In addition, you can specify whether or not to run a dedicated server.



Click image for full size.

Using the Number of Players field, you can specify the total number of players you want to test.

Next, select the NetMode to use:

Option

Description

Play Standalone

Creates a Standalone game. This option does not create a dedicated server. A server can be created by enabling bLaunchSeparateServer.

Play as Listen Server

Creates a session that acts as both a server and a client. Additional instances can be added depending on the number of clients.

Play as Client

Creates a session that acts as a client. A dedicated server is launched in the background.

If the Number of Players field is set to 1, and the NetMode is set to Play Standalone, your Play In Editor session will test standalone, non-networked gameplay.

If the NetMode is set to Play as Client, a dedicated server world is launched, although there is no display or local player for the dedicated server. Using the dedicated server means that none of your clients will be running as a listen server. You can use the dedicated server to check for dedicated server only bugs, such as code that relies on a local player. A basic test configuration for Blueprints that have functionality that relies on servers and clients is to have the Number of Players set to 1, and Play as Client selected. This creates only one window to test play in, but it has the full functionality of a client connected to a dedicated server.

After setting these options, pick your preferred Play In Editor mode to begin testing gameplay. If you have more than one client world and select the Viewport display option for your Play In Editor session, one client world is shown in the viewport, and all others will be shown in new windows. The image below shows testing with 4 players and a dedicated server.



Advanced Settings

The number of client worlds, as well as whether or not to use a dedicated server, can also be set in the Level Editor - Play In Settings window. Here, you can also specify any command line options to be sent to the preview session.

Setting

Description

Launch Separate Server

Launches a separate server even if the net mode doesn't require it. You can use this to test offline --> server workflows by connecting to a server from the offline game.

Play Net Mode

Sets the net mode used for Play In Editor session:

Play Standalone: Starts a standalone game. This will not create a dedicated server, nor automatically connect to one.

Play As Listen Server: Enables the Editor to act as both the server and the client. Additional clients can be opened depending on the number of clients.

Play As Client: Enables the Editor to act as a client. A dedicated server spawns behind the scenes to connect to.

Run Under One Process

Spawns multiplayer windows under a single instance of Unreal Engine. This loads much faster but is not as representative of a player's runtime environment, where each game instance would run in its own process.

Show Server Debug Drawing by Default

Draws debug rendering from the Dedicated Server during Play In Editor.

Server Debug Drawing Tint Strength

Controls the bias of the debug draw color towards the selected tint color.

Server Debug Drawing Color Tint

Selects the tint color of the server debug drawing.

Enable Network Emulation

Applies the selected network emulation settings when starting the game for the purpose of testing how your game handles network issues:

Emulation Target: Applies the emulation settings to the Server Only, Clients Only, or Everyone.

Network Emulation Profile: Applies a preset for incoming traffic and outgoing traffic. Options are Average, Bad, or Custom.

Incoming traffic: Applies settings that add latency and packet loss to all incoming packets. Can add minimum and maximum latency, as well as a percentage amount of packet loss.

Outgoing traffic: Applies settings that add latency and packet loss to all outgoing packets. Can add minimum and maximum latency, as well as a percentage amount of packet loss.

Client

Applies the selected client settings when starting the game:

Play Number of Clients: Opens a number of client windows. The first one will use the Play In Editor Modes options. The rest will use the Run Under One Process settings.

Route Gamepad to Second Window: Routes the gamepad input during a multiplayer session. If unchecked, then the first gamepad is attached to the first multiplayer window, the second to the second window, and so on. If checked, then the gamepad is routed to the second multiplayer window, allowing the first to be controlled by keyboard and mouse.

Create Audio Device for Every Player: Controls how many audio devices are created. If checked, a separate audio device is created for every player. This will render accurate audio for every player's perspective at the cost of CPU performance. If unchecked, a separate audio device is created for only the first two players.

Client Fixed FPS: Sets each client's framerate to an element in the list. Includes a Listen Server.

Server

Applies the selected server settings when starting the game:

Server Port: UDP port number used for game networking.

Server Map Name Override: Overrides the map launched by the server. Currently only used by the PIE_StandaloneWithServer net mode.

Additional Server Game Options: Adds additional parameters that are passed to the server as URL parameters.

Additional Server Launch Parameters: Adds additional parameters that are passed to the server as arguments.

Server Fixed FPS: Sets the server to run at the specified framerate. Does not impact Listen Server.

Multiplayer Viewport Size (in pixels): Spawns additional clients at the width and height specified. Useful when you need multiple clients but only want to interact with one window.

Debugging Blueprints

There is an additional drop down menu in the Blueprint Editor to select the world to debug when running a multiple world scenario:



The world selected in the world list filters the Actors in the Actor list. For example, with All Worlds selected, you will see Actors from every world in the other drop down list. By selecting only one of the worlds, you can see Actors from only that world instance.

This also affects break points. For example, setting the debug world to Client 1 will make it so that only breakpoints will trigger on Actors in Client 1's world.

You can see the client number for a preview window by looking at the window title. For example, in the networked play image above, one window is titled LyraStarterGame Preview [NetMode Client 1].

When All Worlds is selected, any world can trigger break points.

Layer Creation

Layer Naming

Searching Layers

Layer Contents

Adding Actors

Removing Actors

Searching Layer Contents

Visibility

Selection Methods

Type-Specific Selection

Details Layers Section

The Layers panel allows you to organize Actors in your Level.



Click image for full size.

Layers provide the ability to quickly select as well as control visibility of groups of related Actors. You can use your layers to quickly un-clutter a scene leaving only the geometry and Actors that you are working with. For example, you might be working on a building that has multiple levels but is comprised of many modular parts. By assigning each floor to a layer, you can hide each of the floors you are not working on making the top view much more manageable.

An Actor can be in as many layers as you want. This might be useful if you have different sets of Actors that fall under overlapping layers. For instance, you could organize your layers by assigning everything within a particular zone to one layer and have another layer comprised of all the doors in your level.

When creating large levels, the more extensively you use layers, the easier your job will be. And remember, it is always easier to start using layers from the beginning rather than trying to incorporate them after you are already deep into the creation of your level.

Layer Creation

Layers are created in the Layers panel either as empty or using the current selection.

To create an empty layer:

Right-click in the Layers panel and choose Create Empty Layer.



The new layer is displayed in the list.



To create a layer from a selection:

Select the objects to add to the layer in the viewport.



Right-click in the Layers panel and choose Add Selected Actors to New Layer.



The new layer containing the Actors is displayed in the list.



To create a layer by drag and drop:

Select the Actor(s) to add to the layer.

Drag the Actor(s) from the World Outliner on to the empty area in the Layers panel.



The new layer containing the Actors is displayed in the list.



Layer Naming

By default, new layers are given a name using a Layer[number] naming scheme. The number is incremented for each new layer. It is best to make sure you name your layers with descriptive names, and never leave the default naming. For instance, a layer that contains small items scattered on the floor might be named Ground Clutter. This not only makes it easy to quickly see what each layer contains, but also makes it possible to filter the layers using the search feature.

Layer names can contain any alphanumeric characters and can also include spaces, hyphens, and underscores.

To rename a layer:

Right-click on the layer and choose Rename from the context menu.



Enter a name in the text box containing the current name.



The layer is displayed with the new name.



Searching Layers

Layers can be filtered using the search box at the top of the Layers panel. Filtering occurs based on matches between the text entered in the search box and the names of the layers. As you type in the box, the list of layers is filtered in real-time; only displaying those layers whose names match the text.





Unfiltered Layer List

Filtered Layer List

Press the 'X' button to clear the current search terms.

Layer Contents

The contents of a layer can be viewed directly in the Layers panel. The layer contents view displays the name of the layer, a list of all Actors contained in the layer, and information about the layer's contents. To enter the layer contents view, press the See Contents button at the bottom of the Layers panel with the layer you want to view selected.



Click image for full size.

The name of the layer is displayed at the top along with a collection of buttons showing the various types and numbers of Actors contained within the layer.



Click image for full size.

The various buttons to the right of the layer's name show how many of each individual type of Actor are contained within the layer. For instance, the button in the bottom right of the Layers panel informs the user that there are 139 StaticMeshActors contained within the layer.

These buttons can also be used to perform type-specific selections.

To return to the layer list, press the button.

Adding Actors

Actors can be added to one or more layers as a selection or by dragging and dropping from the World Outliner.

To add a selection of Actors:

Select the Actor(s) to add to the layer.



Right-click on the layer you want to add the Actors to and choose Add Selected Actors to Selected Layers.



To add by drag and drop:

Select the Actor(s) to add to the layer.

Drag the Actor(s) from the World Outliner on to a layer in the Layers panel.

You can also drag to the contents bar at the bottom of the Layers panel to assign the Actors to the selected layer.



The layers the Actors are already assigned to are grayed out when dragging and dropping. Additionally, if the Actors being dragged are already assigned to the target layer, a message will inform you of this:

The Actors are added to the layer.

Removing Actors

Actors can be removed from the layer individually or as a group of selected Actors.

To remove individual Actors:

Press the 'X' button next to the Actor in the layer contents view.



The Actor is removed from the layer and the list is updated.



To remove a selection of Actors:

Select the Actors to be removed from the layer.



Right-click on the layer and choose Remove Selected Actors from Layers.



The Actors are removed from the layer.

Searching Layer Contents

The Actors within a layer can be filtered in the layer contents view using the search box at the top. Filtering occurs based on matches between the text entered in the search box and the names of the Actors. As you type in the box, the list of Actors is filtered in real-time; only displaying those Actors whose names match the text.





Unfiltered Layer Contents

Filtered Layer Contents

Press the 'X' button to clear the current search terms.

Visibility

The contents of any layer can be shown or hidden by toggling the Visibility (eye) button for the layer in the layer list.





Visible

Hidden

Selection Methods

Actors within a layer can be selected as a group, individually, or based on type. The Actors within a layer can also be added to or removed from the current selection.

To select all Actors within a layer:

Double-click the layer in the layer list or right-click on the layer and choose Select Actors.



All Actors in the layer are selected, replacing the current selection set.



To append layer Actors to the selection:

Right-click on the layer and choose Append Actors to Selection.



All Actors in the layer are selected, appending them to the current selection set.





Initial Selection

Layer Actors Appended

To remove layer Actors from the selection:

Right-click on the layer and choose Deselect Actors.



All Actors in the layer are removed from deselected, removing them from the current selection set.





Initial Selection

Layer Actors Removed

Type-Specific Selection

Type-specific selection allows you to quickly select all of one type of Actor contained within a layer. This can be performed using the buttons in the contents bar of the main layer list or the title bar of the layer contents view.





Layer List Contents Bar

Layer Contents View Title Bar

Pressing the instances button selects all of the StaticMeshActors in the layer.



Details Layers Section

The Layers category displays which layers the selected Actor(s) belong to using a tag cloud style layout.



Only the layers common to all selected Actors will be displayed.

Clicking the button for a particular layer will remove all selected Actors from that layer.

Actor Names

Search Filter

Favorites

Default Values

Edit Conditions

EditConst Properties

Categories

Choose your operating system:

Windows

macOS

Linux

The Details panel contains information, utilities, and functions specific to the current selection in the viewport. It contains transform edit boxes for moving, rotating, and scaling Actors, displays all of the editable properties for the selected Actors, and provides quick access to additional editing functionality depending on the types of Actors selected in the viewport. For instance, selected Actors can be exported to FBX and converted to another compatible type. The Details panel also allows you to view the Materials used by the selected Actors, if any, and quickly open them for editing.



Click image for full size.

Actor Names

You can set friendly names for Actors directly in the editor. These names can be used to access related Actors or find them using the search functionality in the World Outliner panel.

To edit the Actor Name, simply type the name into the text box at the top of the Details panel.



Click image for full size.

Search Filter

The properties displayed within the Details panel can be filtered using the Search Details box. As you type, the properties are automatically filtered to display only those properties matching the text.



Click image for full size.

To clear the filter, click the button on the right of the Search box.

Because this text box data hides properties that do not match the search criteria, check to make sure it is cleared if you do not see the property you are looking for.

Favorites

This option is currently considered experimental and some features may not work as expected.

If there are properties within an Actor that you frequently change or want quick access to, you can use the Favorites property to flag them so they appear at the top of the Details panel.



Click image for full size.

Above, we checked two options as Favorites, indicated by the star icon next to their property name.

To enable Favorites:

In the Edit menu, select Editor Preferences.





Under Experimental, check the Enable Details Panel Favorites option.



You may need to restart the editor for the changes to be applied.

To mark a Property as a Favorite:

With the option enabled, click the star icon next to a property in any Details panel.



Click image for full size.

Some properties may not offer the ability to favorite them, due to the complexity of their customization.

The property (along with any other marked favorites) is listed under the Favorites section of the panel.



Click image for full size.

Default Values

When a property is modified to a value other than its default value, an indicator is displayed.



Click image for full size.

Reset all properties to their default values by clicking the indicator and choosing to reset the value from the menu.



Click image for full size.

The value of the property is reset to the default value as shown in the menu and the indicator is no longer present.



Click image for full size.

Edit Conditions

Properties can be either be enabled or disabled. A property can only be edited when it is enabled. By default, all properties are enabled unless they have an edit condition. Properties with an edit condition rely on the value of another variable to determine if they are enabled and can be edited.

In some cases, edit conditions are used to determine whether the property will override some other value or if it has any affect at all. Other times, certain properties may simply not make sense unless some condition is met. For example, you may have a group of properties that pertain to indirect lighting and a bool property that globally toggles whether indirect lighting is enabled or disabled. Each property in the group could be conditional on the global toggle so they are only enabled when indirect lighting is being used.

A property with a simple edit condition will be displayed with a checkbox in the left margin. When the checkbox is toggled on, the property is enabled. When not checked, the property is disabled and grayed out.



Click image for full size.

EditConst Properties

Properties declared as editconst, which cannot be modified in the editor, display their values and are highlighted to indicate they cannot be edited.



Click image for full size.



Click image for full size.

Categories

Properties in the Details panel are displayed in categories. Categories such as Rendering, Lighting, and Collision are determined by how the property is declared in code, and are used as a means of organizing related properties into groups. Other categories, such as Transform, Static Mesh, Materials, Actor, Code View, and Layers are custom widgets designed to expose certain properties or functionality in a manner that makes them easier to find, modify and use.

The Level Editor can be put into different editing modes to enable specialized editing interfaces and workflows for editing particular types of Actors or geometry.

To display a selection of modes, in the Level Editor Toolbar, open the Modes dropdown.



Click image for full size.

Icon

Mode

Shortcut

Description



Select

Shift + 1

Activate Select mode to select Actors in your scene.



Landscape

Shift + 2

Activate Landscape mode to edit Landscape terrains.



Foliage

Shift + 3

Activate Foliage Mode to paint instanced foliage.



Mesh Paint

Shift + 4

Activate Mesh Paint mode to paint vertex colors and textures on Static Mesh Actors directly in the viewport.



Modeling

Shift + 5

Activate Modeling editing mode.



Fracture

Shift-6

Activate Fracture mode to create destructible objects and environments.



Brush Editing

Shift + 7

Activate Brush Editing mode to modify Geometry Brushes.



Animation

Shift + 8

Activate Animation editing mode.

Modes change the primary behavior of the Level Editor for a specialized task, such as moving and transforming assets in the world, sculpting landscapes, generating foliage, creating geometry brushes and volumes, and painting on meshes. Modes panels contain a selection of tools tailored to the selected editing mode.



Click image for full size.

The Landscape panel

You can close any panel by clicking the small "X" in the upper-right corner of the tab. You can also hide any panel by right-clicking on the tab, and then clicking Hide Tab on the context menu that appears. To reopen a panel that you have closed, click that panel's name on the Window menu.

Choose your operating system:

Windows

macOS

Linux



Click image for full size.



Select Mode is a specialized tool for speeding up and simplifying environment creation in Unreal Engine 5. Similar in nature to the Content Browser, Select Mode focuses only on Actors, that is, assets that can be directly placed within your level. While active, Select Mode gives you immediate access to all objects that you have placed within your Level.

Select Mode exists as a way to greatly speed up design times when placing and editing various props and other elements in your Level.

When Select Mode is active, after you drag an instance of an asset from the Place Actors panel (by default, located in the upper left corner of the main interface), you can immediately transform and edit Actors in the Level. See Placing Actors for other methods of placing Actors.

Starting Out

Guides

Advanced Topics

Setting up Materials

Mesh Paint mode provides a quick way to adjust color and texture on your Mesh's Materials. The following topics cover all of the critical skills needed to effectively use this tool.

Starting Out



A down-and-dirty quick guide to getting your feet wet with Mesh Paint Mode.



This page describes settings for various parts of the Mesh Paint Tool.

Guides



This page shows how to transfer vertex color data across meshes using Mesh Paint Mode.



An overview of the process of color selection for Mesh Paint Mode.

Advanced Topics

When using any Editor tool, you should think about how you want the tool to affect your Meshes. The following topics cover how Mesh Paint handles painting on individual instances of Meshes placed in your level, as well as how to paint Blend Weight values for multi-texture setups.



This page shows how to copy vertex color from one instance to another.



This page shows how to transfer vertex color data across meshes using Mesh Paint Mode.



A tool which allows vertex colors to be repaired when a new version of a mesh is imported with a different vertex count.

Setting up Materials

The Mesh Paint system requires the Mesh's Material to contain a Vertex Color node, as this is how the vertex color data is passed from the Mesh to the Material. The following topics cover ways to set up a Material so that it can be used with Mesh Paint mode.



This page describes how to set up materials that utilize Vertex Color so that you can paint colors in Mesh Paint Mode.



This page describes how to create a material for 2-way (alpha) texture blending.



This page describes how to set up materials for 3-way (RGB) texture blending.



This page describes how to set up materials for 4-way (ARGB) texture blending.



This page describes how to set up materials for 5-way (1-ARGB) texture blending.



This page shows you a specific example of how to create and use a Two-Texture Material for use with vertex color painting on Meshes.

Activating Mesh Paint Mode

The Mesh Paint tool enables you to paint vertex colors on Static Meshes interactively in the Level Viewport. You can paint multiple instances of a single Mesh with unique color/alpha values, and use that data however you want in your Materials.

Color data can be visualized directly, enabling you to edit multiple Meshes at the same time. Also, using Blend Weights enables you to blend multiple textures using linear interpolation.

Most of the vertex painting features are pretty easy to learn, so if you want to jump right in, here are the basic steps:

Set up a Material that uses vertex color in some way, and apply it to a Mesh.

Activate the Mesh Paint mode and select your Mesh Actor.

Set your paint color and adjust other brush properties appropriately.

While holding down the Ctrl key, click and drag on your Mesh to apply paint.

The following sections describes the process in more detail, including the various brush settings and how Materials are configured.

Activating Mesh Paint Mode

In order to use the Mesh Paint tool, you need to open the Modes drop-down menu and select the Mesh Paint mode.



This displays the Mesh Paint panel and the Color tab of the Modes toolbar.



Mesh Paint Tab



Mesh Paint Toolbar Color Tab

While the Mesh Paint panel is active you can still perform most common Editor actions, such as camera movement and selection. However certain features are disabled, such as translating objects. The Place Actors panel remains available while the Mesh Paint panel is active.

Selecting another option under the Modes drop-down menu closes the Mesh Paint panel. and opens the new panel



When the Mesh Paint panel is open in the Editor, the perspective Viewport will be in Real Time Mode by default. To change this or other Viewport settings, click the dropdown arrow in the upper left corner of your Viewport. This opens the Viewport Options menu.



Setting up Materials

The Mesh Paint system requires the Mesh's Material to contain a Vertex Color node, as this is how the vertex color data is passed from the Mesh to the Material. The following topics cover ways to set up a Material so that it can be used with Mesh Paint mode.



This page describes how to set up materials that utilize Vertex Color so that you can paint colors in Mesh Paint Mode.



This page describes how to create a material for 2-way (alpha) texture blending.



This page describes how to set up materials for 3-way (RGB) texture blending.



This page describes how to set up materials for 4-way (ARGB) texture blending.



This page describes how to set up materials for 5-way (1-ARGB) texture blending.



This page shows you a specific example of how to create and use a Two-Texture Material for use with vertex color painting on Meshes.

There are really an infinite number of ways one could use the colors from a Vertex Color material expression. For this setup, we are going to keep things relatively simple and just multiply the colors into an existing material. This allows us to have the original texture in place, but to tint it with the Mesh Paint tool. First, here is the example mesh:



In order to make this paintable, we need to get the Vertex Color material expression worked into the network. The base material network looks like this:



Click image for full size.

This material has been desaturated a bit, giving us more room to add color using the Mesh Paint tool.

To get our vertex colors worked into the material, we simply need to intercept the Base Color connection and multiply it by a Vertex Color expression's RGB value, like so:



Click image for full size.

Within the commented area, you can see where we have added a Multiply node and a corresponding Vertex Color node.

When you switch to Mesh Paint mode, make sure to select the Colors tab in the Mode Toolbar as shown below.



Then, painting on the mesh produces this result:



Mesh Paint Overview

Here is an example of how you might use the vertex alpha value to blend between two diffuse textures in the Material Editor.



This Material handles the following:

Modulates diffuse color by the painted vertex color (RGB)

Blends between two separate diffuse textures (Diffuse, Diffuse2) using the blend weight stored in the vertex alpha channel (A)

Blends between two separate normal textures (Normal, Normal2) using the blend weight stored in the vertex alpha channel (A)

This is a pretty simple setup that enables a user to choose between two blended textures (by painting alpha), then to tint those textures by painting the vertex color. Here is an application in which the textures have been blended.

First, the Material needs to be applied, the mesh must be selected, Mesh Paint needs to be selected from the Modes drop-down, the Mesh Weight Painting Tool panel needs to be active, and the Texture Weight Type setting should be set to Alpha (Two Textures).



Next, the user would begin by painting with alpha to designate where each texture will be placed. This is what the object looks like when viewed in Alpha mode:



Here is the result as seen without any view modes.



At this point, the user could then start painting on some colors as shown below (seen in RGB mode).



Which, when modulated with the blended textures, would appear as shown below.



Mesh Paint Overview

Blending 3 separate textures can be handled by the Mesh Paint tool very easily, but it does require a special setup in the Material. Consider the following graph:



Here is an overview of the setup:

Each of the color channels (RGB) gets its own Linear Interpolation expression.

Each texture plugs into the B input of its corresponding Lerp node.

The Lerp corresponding to Texture 1 plugs into the Material, and its Alpha will be driven by the Red channel from the vertex color.

The Lerp corresponding to Texture 2 plugs into the A input of the Lerp corresponding to Texture 1, and its Alpha will be driven by the Green channel from the vertex color.

The Lerp corresponding to Texture 3 plugs into the A input of the Lerp corresponding to Texture 2, and its Alpha will be driven by the Blue channel from the vertex color.

Texture one also wraps around and becomes the A plug for the 3rd and final Lerp. This makes Texture 1 the default texture.

Once this is set up, the Mesh Weight Painting Tool should be active and the Texture Weight Type setting should be set to RGB (Three Textures).



Here is an example of this Material, first with the Mesh viewed in RGB Mode, showing the vertex colors in place. Note that with this setup, red corresponds to Texture 1, green corresponds to Texture 2, and blue corresponds to Texture 3.



And here is the final result:



Notice that where the vertex color in the first image is red (Texture 1) there is no change. This is because Texture 1 is also plugged into the A input of the 3rd Lerp expression (see above), making it the default texture. Essentially, you start with Texture 1 and can paint Textures 2 and 3 down as you see fit, or paint Texture 1 back down over them at any time.

If you were going to be setting up such a Material over and over, this would be a great place to deploy a custom Material Function.

Mesh Paint Overview

To handle 4 textures in the blend weights setup, you need to create a Material similar to this:



This works very similarly to the 3-way Material graph, but brings Alpha into the mix to give a 4th blending option. Here is what is happening:

Each of the color channels (ARGB) gets its own Linear Interpolation expression.

Each texture plugs into the B input of its corresponding Lerp node.

The Lerp corresponding to Texture 1 plugs into the Material, and its Alpha will be driven by the Alpha channel from the vertex color.

The Lerp corresponding to Texture 2 plugs into the A input of the Lerp corresponding to Texture 1, and its Alpha will be driven by the Red channel from the vertex color.

The Lerp corresponding to Texture 3 plugs into the A input of the Lerp corresponding to Texture 2, and its Alpha will be driven by the Green channel from the vertex color.

The Lerp corresponding to Texture 4 plugs into the A input of the Lerp corresponding to Texture 3, and its Alpha will be driven by the Blue channel from the vertex color.

Texture one also wraps around and becomes the A plug for the 4th and final Lerp. This makes Texture 1 the default texture.

Once this is set up, the Mesh Weight Painting Tool should be active and the Texture Weight Type setting should be set to ARGB (Four Textures).



Here is an example of this Material, first with the Mesh viewed in RGB Mode, showing the vertex colors in place. Note that with this setup, alpha (shown black) corresponds to Texture 1, red corresponds to Texture 2, green corresponds to Texture 3, and blue corresponds to Texture 4.



And here is the final result:



Notice that where the vertex color in the first image is black (Texture 1) there is no change. This is because Texture 1 is also plugged into the A input of the 4th Lerp expression (see above), making it the default texture. Essentially, you start with Texture 1 and can paint Textures 2, 3, and 4 down as you see fit, or paint Texture 1 back down over them at any time.

If you were going to be setting up such a Material over and over, this would be a great place to deploy a custom Material Function.

Mesh Paint Overview

To handle 5 textures in the blend weights setup, you need to create a Material similar to this:



This works very similarly to the 3-way and 4-way Material setups. However, we now take one minus the Alpha value to get a fifth color. Here is what is happening:

Each of the color channels (ARGB) gets its own Linear Interpolation expression.

An additional Lerp is added, driven by 1 minus the alpha of the Vertex Color node. This will be the fifth color.

Each texture plugs into the B input of its corresponding Lerp node.

The Lerp corresponding to Texture 1 plugs into the material, and its alpha will be driven by the Alpha channel from the vertex color.

The Lerp corresponding to Texture 2 plugs into the A input of the Lerp corresponding to Texture 1, and its Alpha will be driven by the Red channel from the vertex color.

The Lerp corresponding to Texture 3 plugs into the A input of the Lerp corresponding to Texture 2, and its Alpha will be driven by the Green channel from the vertex color.

The Lerp corresponding to Texture 4 plugs into the A input of the Lerp corresponding to Texture 3, and its Alpha will be driven by the Blue channel from the vertex color.

The Lerp corresponding to Texture 5 plugs into the A input of the Lerp corresponding to Texture 4, and its Alpha will be driven by the 1-alpha from the vertex color.

Texture one also wraps around and becomes the A plug for the 5th and final Lerp. This makes Texture 1 the default texture.

Once this is set up, the Mesh Weight Painting Tool should be active and the Texture Weight Type setting should be set to ARGB - 1 (Five Textures).



Here is an example of this Material, first with the Mesh viewed in RGB Mode, showing the vertex colors in place. Note that with this setup, Alpha (shown black) corresponds to Texture 1, red corresponds to Texture 2, green corresponds to Texture 3, and blue corresponds to Texture 4. Incidentally, Alpha is also used for Texture 5 and is also shown in black at the bottom.



And here is the final result:



Notice that where the vertex color in the first image is black (Texture 1) there is no change. This is because Texture 1 is also plugged into the A input of the 4th Lerp expression (see above), making it the default texture. Essentially, you start with Texture 1 and can paint Textures 2, 3, and 4 down as you see fit, or paint Texture 1 back down over them at any time.

If you were going to be setting up such a Material over and over, this would be a great place to deploy a custom Material Function.

Steps

Create the Material

Create and Set Up TextureSample Nodes

Add the Vertex Color and Linear Interpolation Nodes

Set Up Remaining Material Properties

Final Result

Vertex Color Painting is a powerful tool, and there are many ways to use it. The Create a Material for 2-Way Texture Blending page gives a basic explanation for how to set up a Material for blending textures with vertex color painting. This page provides a more concrete use case for this technique. This document demonstrates how to create a two-texture Material for vertex color painting, that blends a rock texture and a moss texture. Once you've created this blended texture, you can use Mesh Paint Mode to paint this texture onto any mesh in your level. You can adjust the settings in the Mesh Paint Mode panel to increase coverage or decrease it, so that the texture is variable across the mesh.





Steps

Create the Material

In the Content Browser, click Add New > Material.



Click image for full size.

Name your new material. In this example, we are using M_2TextureMoss.



Double-click the new Material to open the Material Editor.

Create and Set Up TextureSample Nodes

First we need to add a texture. Right-click in the graph, and in the search bar type texture. In the list of results, select TextureSample. This adds the TextureSample node to the graph.



Click image for full size.

We need four for our example, so copy the TextureSample node and paste it three times so that you have a total of four TextureSample nodes.



Click image for full size.

Position the nodes so that two are together near the top of your graph, and two are together toward the bottom of the graph. This will make them easier to distinguish from each other, and make things more organized.

First we'll select our Diffuse textures. Click one of the top TextureSample nodes. In the Details panel on the left, locate the Material Expression Texture Base section. For the Texture property, click the dropdown to select a texture. In the search bar, type in rock_b. In the results, select T_Rock_Basalt_D.



Click image for full size.

Click on the second of the top TextureSample nodes. In the Details panel, click the Texture dropdown, and in the search bar type grass. In the results, select T_Ground_Grass_D. This is the second of our Diffuse maps.



Click image for full size.

Now we need to select our Normal maps. Click the first of the lower TextureSample nodes. In the Details panel, click the Texture dropdown and type in rock_b again. This time, select T_Rock_Basalt_N. This is the Normal map that matches the Diffuse map we selected in steps 4 and 5.



Click image for full size.

Click the last TextureSample node, and in the Details panel, click the Texture dropdown and type in grass again. In the resutls, select T_Ground_Grass_N.



Click image for full size.

Add the Vertex Color and Linear Interpolation Nodes

Now we'll add the Vertex Color node. Right-click in the graph, and type vertex in the search bar. In the results, select VertexColor. When the VertexColor node is added, notice that it is a red Input Data node.



Click image for full size.

The VertexColor node will combine the two Diffuse maps based on a linear interpolation, or lerp. Right-click the graph and type linear in the search bar. In the results, select LinearInterpolate. This places a Lerp node on the graph.



Click image for full size.

We need two, so copy the first Lerp node and paste a second one on the graph. One is for the Diffuse maps, and the other is for the Normal maps, so position the Lerp nodes accordingly.



Click image for full size.

On the Rock Diffuse map, drag off the RGB output and connect it to the A input on the first Lerp node.



Click image for full size.

On the Grass Diffuse map, drag off the RGB output and connect it to the B input on the first Lerp node. Both your Diffuse maps are now connected.



Click image for full size.

On the Rock Normal map, drag off the RGB output and connect it to the A input on the second Lerp. On the Grass Normal map, drag off the RGB output and connect it to the B input on the second Lerp node. Both your Normal maps are now connected.



Click image for full size.

The Alpha input on the Lerp nodes is the variable that controls the mixture of the Rock and Grass textures. The VertexColor node is going to control the Alpha value, so drag off the top output on the VertexColor node and connect it to the Alpha input on the Diffuse Lerp node, then do the same again for the Normal Lerp node.



Click image for full size.

Now drag off the output of the Diffuse Lerp node and connect it to the Base Color input on the Material node. Drag off the output of the Normal Lerp node and connect it to the Normal input on the Material node.



Click image for full size.

Set Up Remaining Material Properties

Now we'll set the remaining properties on the Material node. Drag off the Metallic input on the Material node, and in the search bar type in constant. Select Constant to add a Constant node. Leave the value at the default of 0.



Click image for full size.

We also want the Specular value to be 0, so connect the Specular input on the Material node to the same Constant node we made in step 1.

We want the Roughness value to be higher than 0, so copy-paste the original Constant node to create another one. Connect the Roughness input to the second Constant node. Select that Constant node, and in the Details panel, set the value to 1.



Click image for full size.

Final Result

Now we have a Material that we can use with Vertex Color painting to paint a texture on our mesh. You can adjust the Strength setting in the Brush section to vary how much of your moss texture is painted onto the mesh. You can adjust the Radius setting up or down, depending on whether you need to paint large sections or small details. You can adjust the Falloff setting to create a hard edge to your texture, or to have it fade out gradually.



Vertex Painting Methods

Vertex Color Painting

Vertex Weight Painting

Texture Weight Painting

Mesh Paint Tools

Brush Settings

Visualization

Inside the Mesh Paint mode panel, there are several options available for using the mesh paint system, each of which has its own settings available for painting vertex color, blending between textures, or painting directly onto the texture file.

Listed below are each of the painting methods available, the tools you can use to work with your vertex color data, the brush settings available while painting, and the view modes available.

Vertex Painting Methods

The Mesh Paint Tool has three different painting modes: Vertex Color Painting, which paints color data directly onto a Mesh's vertices; Vertex Weight Painting, which blends different textures while you are painting; and Texture Weight Painting, which allows painting on textures. The default mode is Vertex Color Painting. The sections below display the options available in each mode.



When you select a method, its settings will populate in the panel under the painting section.

Vertex Color Painting

The Vertex Color Painting mode enables you to paint vertex colors on your mesh, and access its available properties while doing so. You can switch between between the Paint Color and the Erase Color by pressing the X key.



Setting

Description

Paint Color

The color that will be applied while painting (LMB + Drag). A rectangular swatch displays a preview of the current color. Click the swatch to open the Color Picker. You can also type values into the R, G, B, and A fields. If you can't see the R, G, B, and A fields, click the triangle to the left to expand the setting.

Erase Color

The color to use as your "eraser" color while erasing (SHIFT + LMB + Drag). A rectangular swatch displays a preview of the current color. Click the swatch to open the Color Picker. You can also type values into the R, G, B, and A fields. If you can't see the R, G, B, and A fields, click the triangle to the left to expand the setting.

Channels

These check boxes set which color/alpha channels are affected by the paint brush.

LOD Model Painting

This is the specific Level of Detail (LOD) that vertex color painting will be applied to.

Vertex Weight Painting

The Vertex Weight Painting mode enables you to paint vertex weights on your mesh and access its available properties while doing so.



Setting

Description

Texture Weight Type

This configures the blend weight "strategy" by setting the number of textures you are blending between in the material associated with the mesh. When you change this option, the choices available for Paint Texture and Erase Texture will update. Each setting requires a different type of material to be in place in order to be used properly. See the Material Setup page for more information.

Alpha (Two Textures)

This provides 2 texture channels, which will be controlled by painting alpha. This means the material will use only alpha values of 0 (black) and 1 (white) for blending. This setting requires that the object have a 2-way alpha lerp blend material applied, similar to the one demonstrated on the 2-Way Texture Blend Material Setup page.

RGB (Three Textures)

This provides 3 texture channels, which will be controlled by painting RGB values. This means the material will use only RGB values to blend textures. This setting requires that the object have a 3-way lerp blend material applied, similar to the one demonstrated on the 3-Way Texture Blend Material Setup page.

ARGB (Four Textures)

This provides 4 texture channels, which will be controlled by painting ARGB values. This means the material will use RGB values as well as alpha to blend textures. This setting requires that the object have a 4-way lerp blend material applied, similar to the one demonstrated on the 4-Way Texture Blend Material Setup page.

ARGB - 1 (Five Textures)

This provides 5 texture channels, which will be controlled by painting ARGB values. This means the material will use RGB values as well as alpha to blend the first four textures. An internal one minus calculation on the alpha provides a fifth channel for blending. This setting requires that the object have a 5-way lerp blend material applied, similar to the one demonstrated on the 5-Way Texture Blend Material Setup page.

Paint Texture Weight Index

The texture Blend Weight index that will be used when applied during painting.

Erase Texture Weight Index

The texture Blend Weight index that will be used when erased during painting.

Texture Weight Painting

The Texture Weight Painting mode enables you to paint on textures and access its available properties while doing so. You can cycle through textures using the Toolbar or by pressing the period (.) and comma (,) keys. Once you are finished with your texture painting, you can commit the changes using the toolbar or by pressing CTRL + SHIFT + C.





Setting

Description

Paint Color

The color that will be applied while painting (LMB + Drag). A rectangular swatch displays a preview of the current color. Click on the swatch to open the Color Picker. You can also type values into the R, G, B, and A fields. If you can't see the R, G, B, and A fields, click the triangle to the left to expand the setting.

Erase Color

The color that will be applied while erasing (SHIFT + LMB + Drag). A rectangular swatch displays a preview of the current color. Click on the swatch to open the Color Picker. You can also type values into the R, G, B, and A fields. If you can't see the R, G, B, and A fields, click the triangle to the left to expand the setting.

Enable Seam Painting

If this box is checked, dilation is used to allow the painting of texture seams.

Channels

These check boxes set which color/alpha channels are affected by the paint brush.

UV Channel

The UV channel of the selected Actor that will be used for the painted texture.

Paint Texture

This swatch shows the texture to apply painting to. To change the texture, click the Name field to the right of the swatch.

Previous Texture

This cycles to the previous Texture. (Comma)

Next Texture

This cycles to the next Texture. (Period)

Commit Texture

This commits Texture Painting changes. (Ctrl-Shift-C)

Mesh Paint Tools

This section describes the tools you can use to select your mesh and to change your vertex color data when using either Vertex Color Painting or Vertex Weight Painting. This includes copying color data from one instance and pasting it to another, filling the Static Mesh color data with a single color value, propagating your applied paint values from the instance to the base asset, and more.



Setting

Description

Select

This is used to select the mesh for painting.

Paint

This is used to enable the mesh painting tools.

Swap Colors

This swaps the Paint color and Erase color used for Mesh Painting. (X)

Fill

This fills the Mesh or instance being painted using the Paint color, respecting the Channels settings.

Apply

This propagates vertex colors on the instance to the source Meshes. (Formerly the Propagate tool.)

Import

This imports a TGA image file to populate the vertex colors of the selected instances.

Save

This saves the source Meshes for the selected Mesh instances.

Copy

This copies the vertex colors from the selected instance to the source Mesh asset.

Paste

This attempts to paste vertex colors on the selected Mesh instances.

Remove

This removes vertex colors from the selected Mesh instances.

Fix

If necessary, this fixes vertex colors applied to the selected Meshes.

All LODs

This applies the vertex colors from LOD0 to all LOD levels. (Formerly the Apply tool.)

Previous LOD

This cycles to the previous possible Mesh LOD level to Paint on. (B)

Next LOD

This cycles to the next possible Mesh LOD level to Paint on. (N)

Brush Settings

The Mesh Paint tool is a brush-based system. Using the included settings, you can establish a brush designed for wide areas or fine details. Because the Mesh Paint Tool paints color on actual vertices, you might need to adjust settings based on the vertex density of your mesh. This section describes the brush settings common between all the tool's modes while painting on your meshes.



For the options controlled by sliders, you can click and drag the slider to change the value quickly, or you can click the field and type in a number.

Setting

Description

Radius

This sets the radius of the brush in Unreal units. In addition, the brush has a depth-based falloff that is equal to half of this radius. You can press CTRL + Left Bracket ([) to decrease the brush radius, and CTRL + Right Bracket (]) to increase the brush radius.

Strength

This sets the amount of paint to apply each time you click or move the mouse cursor while painting is enabled. Also if brush flow is enabled, a percentage (flow amount) of the brush's strength will be applied to the surface.

Falloff

This sets how the brush's strength falls off with distance. A falloff value of 1.0 means that the center of the brush is 100% strong and fades linearly towards the radius of the brush. A falloff value of 0.5 means that the brush is 100% strong halfway towards the radius, then falls off linearly. A falloff value of 0.0 means the brush is 100% strong over the entire radius. Remember that depth-based falloff is always active, regardless of this setting.

Enable Brush Flow

Checking this box configures the brush to apply paint to every single render frame, even when you are not moving the cursor. It yields results similar to an airbrush.

Ignore Back-Facing

Check this box to ignore triangles facing away from the camera so they will not be affected by the paint brush.

Visualization

This section describes the visualization settings common between all the tool's modes, which you can use to view the painted vertex colors individually or all together.



Setting

Description

Color View Mode

This setting enables different view modes, to help you visualize how vertex color is being applied to your Meshes within the Viewport. You can choose to display just the vertex colors, or you can view individual color channels.

Off

This is the first option in the Color View Mode list. It restores the default Editor View Mode.

RGB Channels

This is the second option in the Color View Mode list. It displays the Actors unlit, with RGB vertex colors showing.

Alpha Channel

This is the third option in the Color View Mode list. It displays the Actors unlit, with only vertex alpha.

Red Channel

This is the fourth option in the Color View Mode list. It displays the Actors unlit, with Red vertex color.

Green Channel

This is the fifth option in the Color View Mode list. It displays the Actors unlit, with Green vertex color.

Blue Channel

This is the sixth option in the Color View Mode list. It displays the Actors unlit, with Blue vertex color.



When painting vertex colors, you are only painting on an individual Instance of the Material and not the actual Material Asset itself. If you want to apply the vertex color data to another instance of the mesh, you can use the functions of the Mesh Paint Toolbar's Colors tab to copy and paste the data onto another mesh or multiple meshes.



When painting vertex colors, the Instance Color Size field in the Mesh Paint panel displays the number of bytes of memory used by the vertex color data (stored in the map package.) This value reflects the total for all Assets that are currently selected.



Command

Description

Copy

Copies the instance vertex color data for the selected Mesh. See Sharing Instance Color Data and the Mesh Paint Tool Reference for more information.

Paste

Pastes instance vertex color data that was previously copied. See Sharing Instance Color Data and the Mesh Paint Tool Reference for more information.

Remove

Discard the data for all selected Meshes and restores the default vertex colors. See the Mesh Paint Tool Reference for more information.

Fix

Attempts to match stored instance data on re-imported Meshes with different vertex counts. See Vertex Color Matching and the Mesh Paint Tool Reference for more information.

There may be cases where you want to paint a mesh and then share those vertex colors with other instances of the mesh in the same level. As an example, maybe you have a pillar and you want to paint the base of the pillar green, and then have all instances in that map appear that way. Instanced vertex color data can be copied and pasted between instances in the level very easily using the Copy and Paste tools in the Mesh Paint Toolbar.

To copy instanced vertex color data, follow these steps:

Select the instance that contains the color data you want to copy and click the Copy icon.

Select the instance(s) to copy the color data to and click the Paste icon.

The color data should now be applied to all of the instances.

When a Static Mesh is reimported with a different vertex count than the number of vertex colors on the instance, you get errors like this in map checks and during cooking:

When instanced vertex colors are mismatched against the original Mesh's vertices, it makes the vertex colors look wrong on a PC; on consoles the vertex colors simply do not exist. To correct that, you can use the Fix tool in the Mesh Paint Toolbar to fix vertex colors if they do not match up with the original Static Mesh Asset.



This feature will only be available if a Mesh needs fixing; otherwise, it is disabled. The tool works well most of the time, especially when you are only making small changes. The more extreme your changes to the Mesh are, the more likely that the colors will not match. The feature is designed to always match some color, even if the changes are drastic. The reason this tool is not automatic is because that would prevent people from easily reversing the fix if they did not like the results. Additionally, adding the feature to Mesh Paint Mode means you can easily perform minor changes after the fix is applied.





The Mesh Paint tool relies on a pair of colors for it to work. Users may choose a Paint Color as well as an Erase Color and swap between them at any time. Color selections are made by way of a standard Color Picker window.



For workflow purposes, it will be easier to think of the Erase Color as an alternate paint color. Using the Erase Color does not remove your previous strokes like using the Eraser Tool in Photoshop or a similar image editing software. Instead, you are just painting with a different color. As an example, if your base is white then you would use white as your Erase color.

While using the Mesh Paint panel, you can also click the Swap icon to reverse the Paint and Erase colors. This is especially handy when you need to quickly jump back and forth between a pair of colors, or do a fast touch-up on a misplaced brush stroke.

You can also use the Reset icon to return to the default the Paint and Erase colors, either for all 4 channels (RGBA) at once or individually. The Paint channel default is white (1, 1, 1, 1), the Erase channel default is black (0, 0, 0, 1).



Swap icon and Reset icon

Clicking on Swap Colors in the Modes Toolbar has the same function as the Swap icon in the Mesh Paint panel.



Remember that the Color Picker has a variety of ways to quickly select colors, including saving color swatches and setting up color themes. Please see the Color Picker documentation for details.

The Toolbar panel provides quick access to commonly used tools and operations.



Click image for full size.

Command

Description



Save the current level.



Display the menu of Editor Modes options. Select an option to display its panel and corresponding toolbar. See Level Editor Modes for more information.



Contains shortcuts for adding and opening common types of content within the Level Editor. Open the Content Browser, displaying all of the content assets contained in your Project. This is where you go to create, import, and edit all content. Open the Epic Games Launcher on the Unreal Engine Marketplace page.



Open the Settings menu to display commonly used options that control selection, editing, and previewing aspects of the Level Editor.



Open the Blueprints menu to access options to create or edit any Blueprints in the world, including opening the Level Blueprint for the current level in the Blueprint Editor. This menu also provides quick access to setting up the framework for your game (for example, game rules, player type, HUD, and so on) from within the editor.



Create a new level sequence or master sequence.



Start the game in normal play mode. Click the arrow to display the Play Options menu. See the Play In Editor section for more information.



Launch the current map on any supported platforms. Click the arrow to access the list of connected devices.

The Bottom Toolbar contains shortcuts to the Command Console, Output Log, and Derived Data functionality. It also displays source control status. It is divided into the following areas:



Click image for full size.

Command

Description



Debugging tool that prints out useful information while your application is running.



Behaves as any other command line interface: enter console commands to trigger specific editor behaviors.



Provides Derived Data functionality.



Connect to or assign your Source Control solution.

Selecting Actors

Actor Snapping

Selection

Scalability

Real Time Audio

Snapping

Viewport

Previewing

The Settings menu in the Level Editor Toolbar contains a set of properties that control selecting, editing, and previewing in the Level Viewport. Open the Settings menu from the Main Toolbar (also known as the Level Editor Toolbar).



The Settings menu contains the following groups of settings:

Selection

Scalability

Real Time Audio

Snapping

Viewport

Previewing

Selection

Option

Description

Allow Translucent Selection

If enabled, clicking geometry with translucent Materials applied selects the Actor.

Enabling this option makes it possible to select transparent meshes, such as glass objects. Disabling it can be useful in other cases. For example, if you have a room filled with translucent particles, selecting other objects in the room would be difficult with this option enabled because clicking the particles would select the Emitter Actor.

Allow Group Selection

If enabled, selecting an Actor in a group selects the whole group instead of the individual Actor.

Strict Box Selection

If enabled, an Actor must be completely within the marquee selection box in order to be selected.

Box Select Occluded Objects

If enabled, marquee box select operations also select objects that are occluded by other objects.

Show Transform Widget

Toggles the visibility of the Transform widget in Viewports.

Scalability

Option

Description

Engine Scalability Settings

Provides quick access to Scalability settings that control the fidelity of various rendering features.

Enable the Monitor Engine Performance? option to see how changing this settings affects your project's performance in real time.

Material Quality Level

Sets the Material quality level used for previewing in the Viewports.

See Material Quality Switch Expression for more information on setting up Materials to work with this setting.

Preview Rendering Level

Sets the rendering level used by the editor. You can restrict rendering quality to device-specific capabilities, including different version of:

Android

iOS

D3D

Real Time Audio

Option

Description

Volume

Controls the volume of Level audio that plays when the Viewport is set to realtime.

Snapping

Option

Description

Enable Actor Snapping

If enabled, Actors snap to the location of other Actors if they are within a specified distance.

Distance

Sets the distance Actors must be within in order to snap to one another if Enable Actor Snapping is enabled.

Enable Socket Snapping

If enabled, Actors can snap to sockets.

Enable Vertex Snapping

If enabled, Actors snap to the nearest vertex on another Actor in the direction of movement.

Enable Planar Snapping

If enabled, Actors snap to the nearest location on the constraint plane. This only works correctly in Perspective views.

Viewport

Option

Description

Hide Viewport UI

Hides the Viewport toolbar and all Viewport UI widgets.

Previewing

Option

Description

Draw Brush Polys

If enabled, semi-translucent polygons are rendered for the faces of a CSG (constructive Solid Geometry) brush when selected.

Only Load Visible Levels in Game Preview

If enabled, only visible levels will be loaded when game preview starts.

Enable Particle System LOD Switching

If enabled, particle systems will use distance LOD switching in perspective Viewports.

Toggle Particle System Helpers

If enabled, shows particle system helpers in Viewports.

Freeze Particle Simulation

If enabled, particle systems freeze their simulation state.

Enable LOD View Locking

If enabled, Viewports of the same type use the same LOD.

Enable Automatic Level Streaming

If enabled, the Viewport will stream in levels automatically when the camera moves.

Outliner Actions

Searching and Filtering in the Outliner

Customizing the Outliner

The Outliner panel displays all the Actors within the scene in a hierarchical tree view. Using the Outliner, you can:

Select and modify Actors.

Search and filter Actors by name, type, and other characteristics.

Use advanced search operators to further refine Actor searches.

Customize which Actor information to display.



By default, the Outliner panel docks to the right side of the Unreal Editor window. Click the image for full size.

You can have up to four instances of the Outliner and customize the settings for each instance separately. Switch between Outliner instances by right-clicking the Outliner tab and selecting a different Outliner, or go to Window > Outliner from Unreal Engine's main menu.



Switching between different Outliner instances.

Outliner Actions

You can perform the following actions on an Actor in the Outliner:

Action

Description

Left-click

Selects that Actor.

Right-click

Displays the same context menu brought up by right-clicking an Actor in the Viewport. Use this to quickly modify an Actor without having to navigate to that Actor in the Viewport.

Left-click and drag

Attaches the Actor being Dragged to another Actor.

F keyboard shortcut

With an Actor selected in the Outliner: Focuses that Actor in the Viewport. With an Actor selected in the Viewport: Scrolls the list of Actors in the Outliner to the selected Actor.

Searching and Filtering in the Outliner

Use the Search box in the Outliner to search and quickly filter the list of Actors in the scene. By default, searching displays all Actors with a partial match to the search term. If you use more than one search term, only Actors that match all the terms will appear.

You can use all of the advanced search syntax operators when searching in the Outliner.

Some of the most common operators are:

Operator

Action

Example

-

Excludes Actors that match a specific term.

-Sky

+

Forces a term to match exactly, as opposed to a partial match.

+Sky will match Sky but exclude Skylight

You can save your search as a custom filter and access custom filters from the Custom Filters category of the Filter drop-down. Custom filters are saved globally for each user, which means they are available across all of the streams and projects of the user who created them.



Filters menu in the Outliner.

Filtering Actors in the Outliner works in the same way as Asset filtering in the Content Browser.

Customizing the Outliner

Right-click any column header to bring up a context menu where you can select which columns to show or hide in the Outliner by enabling or disabling the checkbox next to the column name.



Showing and hiding Outliner columns.

Searching matches terms in all columns in the Outliner, whether or not they are visible.

Left-click and drag the edge of a column header to resize that column.

The Outliner will always scroll to an Actor when you select that Actor in the Viewport. You can disable thai behavior by toggling Always Frame Selection from the Outliner's Settings menu.



Animated demonstration of the Always Frame Selection option when toggled on or off.

Performing a Map Check

Errors

Lighting

Warnings

Actor

BSP Brush

Camera

Class

Foliage

Landscape

Level

Lighting

Navigation

Particle System

Skeletal Mesh

Sound

Static Mesh

Volume

Uncategorized

Infos

Actors

Unreal Engine provides a mechanism for alerting you to potential problems in the form of map check errors and warnings instead of having to hunt down issues manually without knowing what is causing the problem or how to fix it. These errors are an automated way to find out where problems lie and allows you to get them fixed before they have a serious impact on your game.

Performing a Map Check

Map check errors and warnings are displayed following performing a build all of a map and can also be performed separately using the Map Check option in the Level Editor Toolbar's Build menu.

Errors

Errors are critical problems that can potentially cause execution failure. These need to be fixed before proceeding.

Lighting

[LightActor] has same light GUID as [LightActor] (Duplicate and replace the orig with the new one)

Duplicate and replace the original with the new one.

Warnings

Warnings are issues which, while not critical, can cause your game to not function properly or with sub-optimal performance. These should be addressed but are not showstoppers.

Actor

[Actor] : Large Actor casts a shadow and will cause an extreme performance hit unless bUseBooleanEnvironmentShadowing is set to true

A large Actor has been set to cast shadows - this will cause extreme performance issues and should have bUseBooleanEnvironmentShadowing set to true.

[Volume] causes damage, but has no damagetype defined.

This warning is caused when there is a volume that is set to cause damage but does not have a damage type defined. A damage type is important because it tells the game code how to handle a Actor's reaction to taking damage. This can be solved by going to the Actor's Property Window->Physics Volume and setting the 'DamageType' property.

[Actor] : Brush has non-coplanar polygons

This warning is caused when there is a brush in the level that has non-coplanar polygons. This is usually caused by using brush editing tools in geometry mode in extreme ways and can cause missing polygons in the level. This warning can be resolved by deleting the brush and recreating it.

[Actor] in same location as [Another Actor]

This warning is caused when there is an Actor that is in the same exact location as another Actor. This warning is usually the result of an accidental duplication or paste operation. It can be fixed by deleting one of the Actors, or disregarded if the placement was intentional.

[Actor] has invalid DrawScale/ DrawScale3D

This warning is caused when either DrawScale, DrawScale3D X, DrawScale3D Y, or DrawScale 3D Z is equal to zero. Meaning that the Actor will not be shown because it is being scaled to zero on one of its axis. To solve this problem, change any DrawScale's that are zero to be non-zero by selecting the Actor and changing its drawscale at the bottom of the main UnrealEd window.

[Actor] is obsolete and must be removed!

This warning is caused when there is an instance of an Actor in a level that has been marked deprecated. This is usually because an Actor was marked deprecated after the level was created, but the map was never updated. This can be fixed by simply deleting the Actor.

[Actor] bStatic true, but has Physics set to something other than PHYS_None!

This warning is caused when an Actor has its bStatic flag set to true but its Physics is set to PHYS_None. Since bStatic means that the Actor will not be moving, having Physics set to PHYS_None is contradictory. Actors set with the bStatic flag are also not ticked(updated). This error can be solved by going to the Actor's properties and changing its Physics to PHYS_None.

[Actor] : Volume Actor has NULL collision component - please delete

The specified volume Actor has a NULL collision component and should probably be deleted.

[Actor] : Volume Actor has a collision component with 0 radius - please delete

The specified volume Actor has a zero radius for its collision component and should probably be deleted.

[Actor] (LOD [Index]) has hand-painted vertex colors that no longer match the original StaticMesh [StaticMesh]

It looks like the original mesh was changed since this instance's vertex colors were painted down - this may need a refresh.

[Actor] has collision enabled but StaticMesh [StaticMeshName] has no simple or complex collision.

You want to either set Collision Enabled to No Collision on the Actor, or add collision to the mesh (by adding simple collision shapes, and/or enabling collision on sections)

Actor casts dynamic shadows and has a BoundsScale greater than 1! This will have a large performance hit

Serious performance warning... either reduce BoundsScale to be less than or equal to 1 or remove dynamic shadows...

[ActorName] has WorldTrace blocked. It will be considered to be world geometry

BSP Brush

[Brush Actor] : Brush has zero polygons - please delete!

This warning indicates that you have a brush in the level that does not have any polygons associated with it. The brush should be deleted as it is not doing anything useful.

Run 'Clean BSP Materials' to clear [count] references

This warning indicates that there are material references on brush faces that are not contributing to the BSP, and that applying the Tools->'Clean BSP Materials' operation can clean up these references.

[Actor] : Brush has NULL BrushComponent property - please delete!

This warning is caused when there is a Brush with a "None" ConstraintInstance component. It is usually found in older maps where duplication was used to create a Brush and can be fixed by deleting the Brush causing the warning and creating a new one.

[Brush] : Brush is planar

Planar brush used - please note that this may not work well with collision.

Camera

Camera has AspectRatio=0 - please set this to something non-zero

Class

[ ]::[ ] is obsolete and must be removed (Class is abstract)

[ ]::[ ] is obsolete and must be removed (Class is deprecated)

Foliage

Foliage instances for a missing Static Mesh have been removed.

Foliage in this map is missing [MissingCount] cluster component(s) for Static Mesh [MeshName]. Opening the Foliage tool will fix this problem.

Landscape

[LandscapeComponent] : Fixed up deleted layer weightmap

[LandscapeComponent] : Fixed up incorrect layer weightmap texture index

Fixed up shared weightmap texture for layer [Layer] in component [Component] (shares with [Name])

Landscape ([ProxyName]) has overlapping render components at location ([X,Y])

Level

Duplicate level info

Two WorldInfos somehow exist...

Map should have KillZ set.

This warning is caused when the map's KillZ in the WorldInfo properties is set to the default value. All maps should specify a KillZ appropriate for the level so that players cannot simply fall forever until they reach the playable world bounds.

Lighting

[Actor] : Light Actor has NULL LightComponent property - please delete!

This warning is caused when there is a Light Actor with a "None" LightComponent. It is usually found in older maps where duplication was used to create the Actor and can be fixed by deleting the Actor causing the warning and creating a new one.

Maps need lighting rebuilt

This warning is caused when lighting has been invalidated by moving or modifying a light Actor. This can cause problems because the rendered lighting in the level is not accurately representing the current state of lights in the level. This error can be solved by going to the Build menu and rebuilding lighting for a map.

Component is a static type but has invalid lightmap settings! Indirect lighting will be black. Common causes are lightmap resolution of 0, LightmapCoordinateIndex out of bounds.

Navigation

Paths need to be rebuilt

Particle System

[Actor] : Emitter Actor has NULL ParticleSystemComponent property - please delete!

This warning is caused when there is an Emitter Actor with a "None" ParticleSystemComponent. It is usually found in older maps where duplication was used to create the Actor and can be fixed by deleting the Actor causing the warning and creating a new one.

PSysComp has an empty parameter Actor reference at index [Index] ([Actor])

Param.Actor should not be NULL.

PSysComp has an empty parameter material reference at index [Index] ([Actor])

Param.Material should not be NULL.

Skeletal Mesh

[Actor] : SkeletalMeshActor has no PhysicsAsset assigned.

In order for a SkeletalMesh to have an accurate bounding box, it needs to have a PhysicsAsset assigned in its SkeletalMeshComponent. An incorrect or inaccurate bounding box can lead to the mesh vanishing when its origin is not in view, or to poor shadow resolution because the bounding box is too big.

[Actor] : Skeletal Mesh Actor has NULL SkeletalMeshComponent property

The specified SkeletalMeshActor has a NULL SkeletalMeshComponent.

[Actor] : Skeletal Mesh Actor has NULL SkeletalMesh property

The specified SkeletalMeshActor has a NULL SkeletalMesh.

Sound

[Actor] : Ambient sound Actor has NULL AudioComponent property - please delete!

This warning is caused when there is an Ambient sound Actor with a "None" AudioComponent. It is usually found in older maps where duplication was used to create an Actor and can be fixed by deleting the Actor causing the warning and creating a new one.

Ambient sound Actor's AudioComponent has a NULL SoundCue property!

This warning is caused when there is a AmbientSound Actor with a NULL SoundCue property. This is a problem because the Actor will not actually be playing any sounds. This can be fixed by first choosing a sound cue in the generic browser and then going to the Actor's Property Window->Audio Category->Audio Component and setting the 'SoundCue' property.

Static Mesh

[Static Mesh Actor] : Static Mesh Actor has NULL StaticMesh property

This warning is caused when there is a Static Mesh Actor in a level with a NULL StaticMesh property. This can be a problem because the Actor exists and is using memory, but does not have a Static Mesh to actually draw. This warning is usually the result of creating a StaticMesh Actor without first selecting a StaticMesh in the generic browser. This warning can be fixed by first selecting a Static Mesh in the generic browser and then going to the StaticMesh Actor's Property Window->StaticMeshActor Category->StaticMeshComponent->StaticMeshComponent Category to set the 'StaticMesh' Property.

[Actor] : Static Mesh Actor has NULL StaticMeshComponent property - please delete!

This warning is caused when there is a Static Mesh Actor with a "None" StaticMeshComponent component. It is usually found in older maps where duplication was used to create the Actor and can be fixed by deleting the Actor causing the warning and creating a new one.

[StaticMesh] has simple collision but is being scaled non-uniformly - collision creation will fail

Simple collision cannot be used with non-uniform scale. Please either fix the scale or the collision type.

More overridden materials [Count] on Static Mesh component than are referenced [Count] in source mesh [StaticMesh]

[Count] element(s) with zero triangles in Static Mesh [StaticMesh]

Volume

LevelGridVolumes are only allowed in the persistent level

This warning is caused when a LevelGridVolume is placed in a streaming level. These types of volumes are only allowed in the persistent level. This problem can be fixed by moving the LevelGridVolume to the persistent level.

LevelStreamingVolume is not in the persistent level - please delete

This warning is caused when there is a level streaming volume that does not exist in the persistent level. This can be problematic because the volume will not be considered when checking to see if a streaming level should be loaded or unloaded. You can fix this problem by deleting the level streaming volume and recreating it.

No levels are associated with streaming volume.

This warning is caused when there are no levels associated with a LevelStreamingVolume, making it non-functional. This problem can be fixed by associating one or more streaming levels with the offending LevelStreamingVolume.

Uncategorized

Filename [Filename] is too long - this may interfere with cooking for consoles. Unreal filenames should be no longer than [Length] characters.

Please rename the file to be within the length specified.

[ObjectName] : Externally referenced

Infos

Infos are issues which do not need to be addressed by the user but may be useful to know.

Actors

[Actor] : Repaired painted vertex colors

Painted vertex colors were repaired on this Actor.

Setting the Current Context

Current Level

Current Level Instance

Current Data Layer

Current Actor Folder

Toggling Actor Editor Context in the Viewport

Actor Editor Context is an Editor feature that you can use to set a Level, Data Layer, Level Instance, or Outliner Actor Folder as the current editor context. When set to current, any Actors you add to the Viewport are assigned to the current context. Assigning a current Actor Editor Context helps keep your world organized when adding a large number of Actors by assigning them to a specified context automatically, such as keeping all the trees in an environment in a Trees Outliner folder and assigning them to a Trees Data Layer.



The Actor Editor Context set to the Trees Data Layer and Trees Actor Folder. Click image for full size.

A widget in the lower-right corner of the Viewport displays the currently active Level, Level Instance, Data Layer, or Actor Folder.

Setting the Current Context

Current Level

In worlds that don't use World Partition, knowing which level you are working in is an integral part of the sublevel workflow. After adding sublevels to your Level using the Levels window, the Actor Editor Context displays the current Level:



Level window showing the Persistent Level with one sublevel named SubLevel. Click image for full size.



Actor Editor Context showing SubLevel as the current level. Click image for full size.

Using the dropdown menu in the Actor Editor Context widget, you can specify the current Level. All Actors you add to the Viewport are assigned to that Level.



Click the dropdown to change the current Level.

Current Level Instance

Level Instancing is a Level-based workflow that creates prefabricated Level Instances you can place in your world more than once. When editing a Level Instance, Unreal Engine creates a new empty context and the Actor Editor Context widget displays the current Level Instance:



Actor Editor Context showing the current open Level Instance. Click image for full size.

All Actors you add to the Viewport are assigned to the currently open Level Instance. When you commit your changes to the Level Instance, the editor returns you to your previous Actor Editor Context.

Current Data Layer

Data Layers control the loading and unloading of Actors both in the editor and at runtime. Unlike Levels, Actors can be assigned to more than one Data Layer. To set the current Data Layer (or Layers):

If needed, open the Data Layers Outliner by selecting Window > World Partition > Data Layer Outliner.

Right-click the Data Layer you want to make current and select Make Current Data Layer (s).



Data Layer Outliner showing the Trees Data Layer set to current.

This adds the selected Data Layer to the current context. Its name and assigned debug color now display in the Actor Editor Context widget.



Actor Editor Context widget showing Trees as the current Data Layer. Click image for full size.

All Actors you add to the Viewport are assigned to the current Data Layer (or Layers). To clear the current Data Layer context, right-click in the Data Layer Outliner and select Clear Current Data Layer(s) or click the X button located in that section of the Actor Editor Context widget.



Clear the current Data Layer by clicking the X button in the Actor Editor Context widget.

Current Actor Folder

Similar to Data Layers, you can also assign a current Actor Folder in the Outliner. To set the current Actor Folder:

If needed, open the Outliner by selecting Window > Outliner and selecting one of the four Outliner instances.

Right-click the folder you want to make current, then select Make Current Folder from the context menu.



Outliner showing Trees as the current Actor Folder.

This adds the selected folder to the current context. Its name now displays in the Actor Editor Context widget.



Actor Editor Context widget showing Trees as the current Actor Folder. Click image for full size.

All Actors you add to the Viewport are assigned to the current Actor Folder. To clear this context, right-click in the Outliner and select Clear Current Folder or click the X button located in that section of the Actor Editor Context widget.



Clear the current Actor Folder by clicking the X button in the Actor Editor Context widget.

Toggling Actor Editor Context in the Viewport

The Actor Editor Context widget is enabled by default. To disable it, follow these steps:

Click the Viewport Options button in the top-left corner of the Viewport, then select Advanced Settings. This opens the Editor Preferences window.



Click the Viewport options button and select Advanced Settings at the bottom.

Navigate to the Look and Feel section of the Level Editor - Viewports settings and clear the Show Actor Editor Context checkbox.



The Level Editor - Viewports settings. Click image for full size.

World Composition

The Level Streaming feature makes it possible to load and unload map files into memory as well as toggle their visibility during play. This makes it possible to have worlds broken up into smaller chunks so that only the relevant parts of the world are taking up resources and being rendered at any point. If done properly, this allows for the creation of very large, seamless games that can make the player feel as if they are playing within a world that dwarfs them in size.

Level Streaming Overview

Level Streaming Volumes Reference

Loading and Unloading Levels using Blueprints

Loading and Unloading Levels using C++

World Composition

Level Streaming using Volumes

World Composition

World Composition is a specific form of level streaming used to create large worlds. Levels are arranged in a planar grid, and streamed in as the player approaches them.

World Composition

The Persistent Level

Streaming Levels

Dynamic Streaming Methods

Level Streaming Volumes

Scripted Level Streaming

The Level Streaming feature makes it possible to load and unload map files into memory as well as toggle their visibility during play. This makes it possible to have worlds broken up into smaller chunks so that only the relevant parts of the world are taking up resources and being rendered at any point. If done properly, this allows for the creation of very large, seamless games that can make the player feel as if they are playing within a world that dwarfs them in size.

The Persistent Level

The first step towards getting your Levels to blend together seamlessly is creating the persistent Level. This can be thought of as a master Level that is primarily used to govern which Levels will be streamed in and out.

Streaming Levels

Streaming Levels are managed through the Levels window. They can overlap your persistent Level, or be offset to create larger worlds. Each streaming Level can be set to Always Loaded or Blueprint for the streaming type. This setting can be toggled in the Levels window by right-clicking on the sublevel.

When a streaming Level is set to Always Loaded, it is loaded together with the persistent Level. It also becomes visible at the same time as the persistent Level. It ignores streaming volumes assigned to it, as well as any loading or unloading requests sent from Blueprints or C++. This type of sublevel is often used for splitting content that would ordinarily be in the persistent Level into multiple "layers", so artists can collaborate working in parallel without blocking each other. For more information on this workflow, see Managing Multiple Levels. In game, an Always Loaded sublevel is never streamed out, unless the game changes the persistent Level.





Dynamic Streaming Methods

Streaming Levels with the Blueprint streaming type can actually be controlled with Level Streaming Volumes, Blueprints, or C++ code. These Levels can be loaded or unloaded dynamically.

Level Streaming Volumes

Level Streaming Volumes make controlling level streaming very easy. The idea is simple: load/unload requests for a streaming Level are issued based on whether the viewpoint is inside any of the Level Streaming Volumes associated with a Level.

Specifically, Level Streaming Volumes can be used in two ways:

In the game, Level Streaming Volumes cause Levels to load when the player's viewpoint is inside the volume and unload when the player's viewpoint is outside the volume.

In the editor, Level Streaming Volumes can be used to preview Level streaming by automatically hiding/unhiding Levels based on the location of the perspective viewport's camera.

Volume-based level streaming is simple to use and does not require any scripting, making it an ideal way to control level streaming. Furthermore, volume-based level streaming is much easier to maintain than scripted streaming: when demands on the loading system change, Level loading/unloading behavior can be modified by simply resizing the streaming volumes.

Level Streaming Volumes Reference

Level Streaming using Volumes

Scripted Level Streaming

If you want to set up more complex behavior for loading and unloading Levels, similar to the door unlocking example above, you can also set up Blueprint or C++ logic for Level loading and unloading. The key functions are Load Stream Level and Unload Stream Level, and you designate the Level to load by its name.

In addition to Load Stream Level and Unload Stream Level, the Get Streaming Level function enables even more dynamic streaming behavior. Since it gives you access to the actual level streaming object, you can modify and query its state. Using this function in combination with Create Instance, you can also create and stream in copies of a specific sublevel. By applying transforms and sending parameters to these copies, you can create procedural worlds.

Loading and Unloading Levels using Blueprints

Loading and Unloading Levels using C++

Associating Streaming Volumes With Levels

Important Details

Testing Your Streaming Volume Setup

Level Streaming Volumes for Previs

Cost of Level Streaming Volumes

Adding Hysteresis to Unloading Requests

Disabling Level Streaming Volumes

You can adjust how a Level Streaming Volume handles level streaming by adjusting the properties from the Details panel, pictured below.

Property

Description

Streaming Levels

Displays the levels affected by the volume.

Editor Pre Vis Only

Determines if the streaming volume should only be used for editor streaming level previs.

Disabled

If true, the streaming volume is ignored by the streaming volume code. Also used to either disable a Level Streaming Volume without disassociating it from the level, or to toggle the control of a level's streaming between Blueprints and Volume Streaming.

Streaming Usage

Determines what the volume is used for, e.g. whether to control loading, loading and visibility, or just visibility (blocking on load).

Associating Streaming Volumes With Levels

Volume-based level streaming works as follows: each streaming Level can have associated with it a set of Level Streaming Volumes. Each frame, the engine iterates over each Level and checks to see if the player's viewpoint is inside any of the Level Streaming Volumes associated with that Level. If the viewpoint is inside at least one Level Streaming Volume, a request is issued to begin loading that Level. If the viewpoint is outside all Level Streaming Volumes, the Level is marked for unloading.

Level Streaming using Volumes

Important Details

All Level Streaming Volumes must exist in the persistent Level. Level Streaming Volumes that live in other Levels cannot be used for level streaming, and will generate warnings when the map is checked for errors.

If a Level has any streaming volumes associated with it, other methods of streaming the Level will not behave correctly.

A single Level Streaming Volume can affect multiple Levels. Similarly, a single Level can be affected by multiple Level Streaming Volumes.

Volume-based streaming works for split screen. The viewpoints of all local players are considered before any loading/unloading requests are issued.

Testing Your Streaming Volume Setup

It is critical that volume-based level streaming be tested in game on the target platform. Streaming in Play in Editor mode (PIE) will show where the loads/unloads will happen, but streaming in PIE is not representative of real, in-game loading-unloading. This is because in PIE, the Levels are already in memory, and so "loading" a Level is simply a matter of unhiding it instantly.

Running the Level in the standalone game on the target platform is critical in making sure your streaming setups work. Note that on some platforms, it can take several seconds to stream in a Level. Size your Level Streaming Volumes appropriately, so that the Level is loaded by the time the player can reach it. Level loading behavior can be modified by resizing the Level Streaming Volumes associated with a Level. Growing a volume causes associated Levels to load sooner and unload later, while shrinking a volume causes later loads and earlier unloads.

Level Streaming Volumes for Previs

A Level Streaming Volume can be marked for editor previsualization only by setting the Editor Pre Vis Only flag on the Level Streaming Volume. In this manner, volume-based level streaming can still be used for editor previs while at the same time using another streaming method for in-game streaming.

Cost of Level Streaming Volumes

Each frame, UWorld::ProcessLevelStreamingVolumes iterates over each streaming Level and for each Level, that Level will begin loading if any local player is within any of the volumes associated with that Level. Likewise, the Level will be begin unloading if all local players are outside all volumes.

UWorld::ProcessLevelStreamingVolumes exploits coherency in the following manner: for each Level, the volume that most recently contained a player is cached. This cached volume is checked first, so that Levels a player is in or returns to are quickly accepted.

Volumes of any shape are fine, although obviously the fewer the better. An upper bound on the cost of Level Streaming Volumes can be approximated by the sum of the number of Level Streaming Volumes associated with unloaded Levels.

Two stats exist under the "Streaming" stats group for monitoring level streaming performance. The "Streaming Volumes" stat tracks the number of Level Streaming Volumes tested against player viewpoints per frame, while the "Volume Streaming Tick" stat tracks the amount of time spent in UWorld::ProcessLevelStreamingVolumes per frame.

Adding Hysteresis to Unloading Requests

A player moving back and forth across a Level Streaming Volume boundary causes unneeded load/unload requests to be issued. To address this, hysteresis has been added to unloading

No hysteresis exists for loading requests, because if a Level needs to be loaded, we always want it loaded as soon as possible.

The amount of unloading hysteresis can be adjusted by modifying the Min Time Between Volume Unload Requests property of the streaming Level in the Levels window. The default unloading hysteresis is 2.0 seconds.

Disabling Level Streaming Volumes

There is a property on Level Streaming Volumes called bDisabled. When set to true, the volume will be ignored by the streaming volume code, both in-game and in the editor. bDisabled can be used to disable a Level Streaming Volume without dissociating it from the Level.

As an example of where the bDisabled flag is useful, imagine a door leading to a Level whose streaming is controlled with streaming volumes. The streaming volume extends out past the door, so that the Level will be streamed in by the time the player can reach the door and open it. Initially, however, the door is locked, and will become unlocked when the player achieves an objective in another part of the Level. So, even though the streaming volume extends past the door, we don't want the Level on the other side of the door to stream in unless the door is actually unlocked ("openable").

Blueprints and C++ could both be used to toggle the disabled state of Level Streaming Volumes.

Streaming In Levels with Blueprints

Unloading Levels with Blueprints

We want to start streaming in the patio level here, so that by the time the player rounds the corner and begins approaching the patio, the streaming level will be loaded and visible.



As part of the setup, we have two levels, SunTemple_Persistent and SunTemple_Streaming. Our Player Start is in SunTemple_Persistent, and our player in the game is represented by a Character.

Open SunTemple_Persistent in the Content Browser.

Move the Player Start to the very beginning of the temple.



Click on Windows, then select Levels.

Click on the Levels dropdown menu, then select Add Existing... to add a new sublevel.



Select SunTemple_Streaming to add in the Open Level dialog, then click on Open.



Right-click on Persistent Level and select Make Current from the dropdown menu.

Streaming In Levels with Blueprints

Open the Content Browser and create a new Blueprint Class. This class is going to be based on Actor.

Name the new Blueprint Class "LevelStreamer", then save it.

Open LevelStreamer in the Blueprint Editor.

For this scenario, we want to stream the second level in once the Character overlaps the Box Component.

Add a Box Collision Component using the Add Component button in the Components tab.

Open the Blueprint's Event Graph. Select the Box Component in the Components tab, then right-click in the graph to summon the context menu.

Type "begin overlap" then select On Component Begin Overlap to add the event.

Click and drag off of the Other Actor pin, then type "=" into the context menu's search. Select the Equal (Object) entry to add the node.

Click and drag off of the second Object pin on the == node, then type "character" into the context menu's search. Select the Get Player Character entry to add the node.

Hold down the B key and click in the graph to add a Branch node, then connect the boolean pin of the == node to the input on the Branch node.

Connect the execution output pin of the OnComponentBeginOverlap node to the execution input pin of the Branch node.

Right-click in the graph, then type "level" to search in the context menu. Select Load Stream Level from the menu.

Right-click on the Level Name pin and promote it to a variable, then name the variable "LevelToStream" and make it Editable in the Details panel.



Toggle Make Visible After Load and Should Block on Load to true on the Load Stream Level node.

For this example, we are going to have the same default loading behavior for all levels using this Blueprint, but you could also make those Editable variables.

Connect the True execution output pin of the Branch node to the input execution pin on the Load Stream Level node.



Place your LevelStreamer Blueprint into your level, and adjust the placement and scale until it encompasses the part of the persistent world you want your Character to be in to begin streaming, as well as the entire walkable volume where the streaming level will be.

Enter SunTemple_Streaming as the Level to Stream.

Use Play In Editor to test out your streaming level.

Unloading Levels with Blueprints

To unload the level as your Character exits the Box component, your graph will have very similar logic but will end in an Unload Stream Level node.



Streaming In Levels with C++

Unloading Levels With C++

We want to start streaming in the patio level here, so that by the time the player rounds the corner and begins approaching the patio, the streaming level will be loaded and visible.



As part of the setup, we have two levels, SunTemple_Persistent and SunTemple_Streaming. Our Player Start is in SunTemple_Persistent, and our player in the game is represented by a Character.

Open SunTemple_Persistent in the Content Browser.

Move the Player Start to the very beginning of the temple.



Click on Windows, then select Levels.

Click on the Levels dropdown menu, then select Add Existing... to add a new sublevel.



Select SunTemple_Streaming to add in the Open Level dialog, then click on Open.



Right-click on Persistent Level and select Make Current from the dropdown menu.

Streaming In Levels with C++

Open the Content Browser and create a new C++ Class. This class is going to be based on Actor, so select Actor and click Next.

Name the new C++ Class "LevelStreamerActor", then click on Create Class. The new class will now open in Visual Studio or XCode.

For this scenario, we want to stream the second level in once the Character overlaps a BoxComponent called OverlapVolume in our LevelStreamerActor.

In LevelStreamerActor.h, declare an OverlapVolume that is VisibleAnywhere, BlueprintReadOnly, and has the AllowPrivateAccess meta flag.

In LevelStreamerActor.cpp, in the LevelStreamerActor constructor, create the OverlapVolume and make it the RootComponent.

Back in LevelStreamerActor.h, declare a protected OverlapBegins function, which will be bound to the BoxComponent's OnComponentBeginOverlap function. This binding means that OverlapBegins must be tagged with a UFUNCTION macro, and must have the same signature as OnComponentBeginOverlap.

Also in LevelStreamerActor.h, create a protected FName variable that is EditAnywhere called LevelToLoad. This will enable you to change the LevelToLoad on a per-instance basis.

We are going to use a few functions from the GameplayStatics library, so include it at the top of LevelStreamerActor.cpp.

Now you are ready to create your OverlapBegins functionality. In LevelStreamerActor.cpp, begin defining the function. You can use the GameplayStatics function GetPlayerCharacter to get the Character at index 0.

After getting MyCharacter, check it against the OtherActor overlapping your BoxComponent. Also, verify that LevelToLoad is not empty, then call LoadStreamLevel.

In your LevelStreamerActor constructor, bind OverlapBegins to your BoxComponent's OnComponentBeginOverlap.

Your final LevelStreamerActor.h should look like:

Your final LevelStreamerActor.cpp should look like:

Compile your code, then switch back to the editor.

Place your LevelStreamer Actor into your level, and adjust the placement and scale until it encompasses the part of the persistent world you want your Character to be in to begin streaming, as well as the entire walkable volume where the streaming level will be.

Enter SunTemple_Streaming as the Level to Stream.

Use Play In Editor to test out your streaming level.

Unloading Levels With C++

To unload the level as your Character exits the BoxComponent, you will create an OverlapEnds function that calls UGameplayStatics::UnloadStreamLevel and bind it to OnComponentEndOverlap. Add the following code snippets to your LevelStreamerActor:

In LevelStreamerActor.h:

In LevelStreamerActor.cpp:

In the constructor:

Activating World Composition

Levels Hierarchy

Levels Composition

Layers

Minimap

UI Key

Level Details

Tile Settings

LOD Settings

World Origin Shifting

Big Worlds and Multiplayer

Creating Landscape Levels

Tiled Landscape Import

World Composition has been designed to simplify managing large worlds. One of the goals is to avoid using a persistent level to store streaming information as it becomes a bottleneck when a team of level designers want to work on levels simultaneously. The persistent level does not store any streaming information and instead scans a folder and treats all found levels as streaming levels. Each streaming level has information stored in the package header, which World Composition can read without loading the level into memory. Initially, all levels except the persistent level are unloaded in World Composition. You can load or unload any part of the world manually at any time.

World Composition relies on a world origin shifting feature which, when used with distance based level streaming, allows you to create worlds which are not limited to the WORLD_MAX constant value hard-coded into the engine.

Activating World Composition

World Composition managed worlds can be activated by switching on Enable World Composition flag in World Settings.

You can also disable world origin shifting by switching off Enable World Origin Rebasing flag in World Settings.



Levels Hierarchy

After you have activated World Composition, all the levels in your project will be visible in the Levels window. To open this window, click on the Windows menu, and then select Levels.

The entries in the Levels window represent your world hierarchy.



The level with its name in blue text is the current level. Currently loaded levels will have their names in white text, while levels that are unloaded have grayed-out names.

To load a level in the world composition, just double-click its name. Using drag-and-drop, you can establish relationships between individual levels. Child levels store position relative to the parent level, so when you change the parent level's position all child levels will recalculate their position accordingly.

In the Levels window, you can lock and save levels, as well as open the Level Blueprint for each level, with buttons to the right of the level name.

Levels Composition

When Enable World Composition is on, there is a button to open World Composition at the top of the Levels window.



Here, you can see the layout of your world.



Layers

By default, all levels are assigned to an Uncategorized layer. Layers hold information about streaming distances, so levels assigned to a particular layer will inherit that streaming distance. Levels assigned to a layer with streaming distance disabled will be excluded from distance streaming, and can instead be controlled using Blueprints.

You can create new layers by clicking the Add (+) button to the right of the existing layer names. Each level can only be assigned to one layer at a time.

Layers cannot be deleted or edited, so if you would like to change streaming distance settings, create a new layer with your desired settings and assign levels to it. Layers which have no assigned levels will be deleted automatically the next time you open a level.

You can filter your levels by layer by clicking on the layer name above the minimap. You can toggle multiple layers by using Control+Mouse Click. When there are no layers toggled on, no filtering is performed.

Minimap

Each level except the persistent level has an image and position in the world, which are displayed in the minimap. The image of the level is updated every time content in the level is changed. This map allows you to preview your world from the top and arrange the position of levels by dragging them. When dragging levels, they will snap to the edges of other levels. Holding the Control key will cause the level movement to use the Level Editor's snapping settings. Note that level position is stored as integer coordinates, so for exact matching of adjacent level tiles, your levels must have integer bounds sizes.

Levels based on Landscape Actors have snapping based on the base landscape component size. This is done to enable seamless editing between Landscape Actors in different levels.

All Landscape Actors will have transformations disabled in the Editor Viewport to ensure that the landscape cannot be moved by an arbitrary amount and lose its ability to be aligned with other landscape levels.

The first time a level is loaded in World Composition, a new Level Bounds Actor is automatically created in the level. The Level Bounds Actor is used to calculate the size of the level.

By default, the Level Bounds Actor automatically resizes to include all Actors found in the level. However, some Actors, like skyboxes, can have very large bounding boxes, which will result in overly large level tiles in the world minimap. If you have Actors like this that you do not want to include in the level bounds calculations, you can disable automatic level bounds calculations and set a fixed size for the Level Bounds Actor.



Currently, Realtime must be enabled in the viewports for the Level Bounds Actor to function.

The minimap has a yellow square indicating the safe edit area. The safe edit area's size is equal to the WORLD_MAX constant in the engine. Levels outside of this area will be hidden automatically, and their level images will reflect this. World Composition tries to keep levels you are working on close to the Editor world origin. This feature is called "focusing" and may shift the current world origin to a new position if you begin editing a level outside of the safe edit area. Shifted levels still preserve their Actors' original transformations when they are saved, so saving a level that is currently shifted will not change the Actors' absolute positions.

UI Key



Number

Status Bar

Description

1

Layers

Click on a layer name to toggle filtering by that layer, or click on the + to create a new layer.

2

WORLD_MAX

Bar indicating the scale of the WORLD_MAX constant.

3

World Origin

Current position of the world origin.

4

Current Level

Name of the current level.

5

Mouse Cursor Position

Current world position of the mouse cursor.

6

Marquee Selection

Size of the marquee selection box in the world units.

7

World Size

Size of the world, calculated as the sum of all level bounding boxes.

Level Details

To see the details for any level in the Level window, select it and then click on the magnifying glass icon in the toolbar. This will summon the Level Details window, where you can also swap between available levels' information with a dropdown menu.



Tile Settings

Setting

Description

Package Name

Package name of the selected level. This information is read-only.

Parent Package Name

Package name of the parent level. If the level has specified a parent, its position becomes relative to the parent level.

Position

Level offset from the zero world origin, stored as an integer 2D vector. All Actors in the level will be shifted by this value when the level is added to the world (becomes visible), and shifted back when the level is removed from the world (hidden).

Absolute Position

Absolute position of the level. This is the same as Position when the level has no parent. This information is read-only.

Z Order

Defines Z sorting order of the level tile in the minimap. This can be useful when there are several overlapping tiles and you want to sort them in a specific order.

LOD Settings

Each level in the world composition can have up to 4 LOD streaming levels. LOD streaming levels are similar to mesh LOD. Depending on streaming distance settings streaming level will be replaced with corresponding LOD level. LOD levels automatically discovered by World Composition using pattern [Package name]_LOD#. Where number should be from 1 to 4. LOD levels can be created manually or with automatic LOD map generator.

Setting

Description

Num LOD

Number of LOD levels for selected level.



LOD[1..4]



Generate

Generates simplified version of an original level to merge Static Mesh Actors found in the level into one simplified proxy mesh. Landscape Actors will be converted to Static Meshes using highest landscape LOD. In general, a level with landscape, an Actor, and a bunch of Static Mesh Actors will result in LOD level which contain 2 simplified Static Mesh Actors. This operation will overwrite previous LOD level if it exists on the disk.

Distance

Distance relative to original level streaming distance. For example, if original level has streaming distance = 1000, and LOD1 level has distance 1500, then LOD1 level will be visible at [1000..2500] range and original at [0..1000] range.

Details percentage

Percent of details to preserve when reducing original meshes.

World Origin Shifting

The World Composition editor supports shifting of the world origin by some arbitrary amount. Shifting the world origin results in adding an offset vector to all registered Actors in the world. Each Actor has an ApplyWorldOffset function which can be overridden in the child classes to do additional things. In case you have created a new AActor derived class and store absolute position values in it, you have to override ApplyWorldOffset function to make it work correctly with world origin changes and shift your absolute values in it. Rendering and physics primitives will be shifted in parallel to Actors in game thread.

Big Worlds and Multiplayer

Right now world origin shifting is not supported in the multiplayer games. Here are two solutions that can be implemented for your specific needs:

Implement your own server solution. MMO licensees mostly do this.

Implement some layer between clients and unreal dedicated servers which will transform shifted absolute positions from the clients and route them to the right dedicated server, which only holds part of the world where client is.

However if you disable world origin, shifting you can run a tiled world with a dedicated server. Dedicated servers will load all distance dependent levels, and each connected client will work as usual loading only level that satisfy streaming distance settings. A server holds a list of visible levels for each client and filters Actor replication by this list.

Creating Landscape Levels

Right-clicking on a level tile to summon the context menu which has a Landscape Actor inside will bring an option for adding adjacent levels with landscape proxy Actors in them. This requires the adjacent levels landscapes have size equal to source Landscape size.

Tiled Landscape Import

In the Levels panel toolbar you can find an option for importing tiled landscape. Tiled landscapes are created from a tiled heightmap, where each heightmap tile will represent a level with a landscape Actor in it. Tiled heightmaps/weightmaps can be exported from an application like World Machine. Adjacent heightmaps tiles should share border vertices ("Share edge vertices" in World Machine). And, each tile resolution should follow the recommendations from this page Creating Landscapes.



Setting

Description

Select Heightmap Tiles...

Allows you to select multiple heightmap tiles you want to import.

Flip Tile Y Coordinate

Whether tiles should be imported with Y coordinate flipped. This option should be turned on when importing tiles created in World Machine.

Tile Coordinates Offset

Offset in tiles from origin. If set to zero, tile with coordinates x0_y0 will be created at world origin.

Import Configuration

Generates all possible landscape configurations depending on resolution of selected tiles.

Landscape Scale

How much to scale the tiled landscape by.

Material

Material to use. When a material has be chosen, you will be able to assign weightmap tiles for each landscape layer found in the material and how each layer is blended.

When you have imported a tiled landscape, you can reimport heightmaps and weightmaps for selected levels using the right-click context menu on the minimap.

Streaming In Levels with Volumes

We want to start streaming in the patio level here, so that by the time the player rounds the corner and begins approaching the patio, the streaming level will be loaded and visible.



As part of the setup, we have two levels, SunTemple_Persistent and SunTemple_Streaming. Our Player Start is in SunTemple_Persistent, and our player in the game is represented by a Character.

Open SunTemple_Persistent in the Content Browser.

Move the Player Start to the very beginning of the temple.



Click on Windows, then select Levels.

Click on the Levels dropdown menu, then select Add Existing... to add a new sublevel.



Select SunTemple_Streaming to add in the Open Level dialog, then click on Open.



Right-click on Persistent Level and select Make Current from the dropdown menu.

Streaming In Levels with Volumes

In the Place Actors panel, select the Volumes tab and then drag a Level Streaming Volume into your level.



Arrange the Level Streaming Volume to encompass the whole walkable area of SunTemple_Streaming.

Keep in mind that the logic for Level Streaming Volumes tracks where your active camera is, so if you have a camera placed at a distance from your player's Pawn or Character, you may need to adjust the size and placement of the Level Streaming Volume accordingly.

Click on Windows, then select Levels.



Select SunTemple_Streaming, then click on the Level Details icon.



Next to Streaming Volumes, click on the plus sign (+) to add a new volume. Then, use the dropdown menu or the eyedropper to select the Level Streaming Volume you just placed in the level.

Ensure that the Initially Loaded and Initially Visible checkboxes are unchecked, then close the Level Details panel.

Back in the Viewport, select the Level Streaming Volume. In the Details panel, set the following properties of the volume: Editor Pre Vis Only and Disabled should be unchecked, and Streaming Usage should be set to SVB Visibility Blocking on Load.



Use Play in Editor to test out your streaming level.





Starting Out

The Virtual Scouting tools give filmmakers new ways to navigate and interact in virtual production environments, helping them make better creative decisions. Directors and DOPs can easily find locations, compose shots, set up scene blocking, and get accurate representations of filming locations. Artists and set designers can experience the location in VR while building it, using measurement and interaction tools to check distances and modify the world. You can also capture images from the virtual world, helping the whole production team track decisions made during the VR session. In addition, controllers and settings can be customized in Blueprint without the need to go into C++ and rebuild the engine.

Starting Out



With Virtual Scouting, filmmakers can scout a digital environment in virtual reality.



How to use the VR camera and light tools for virtual scouting.



How to use the VR editing tools for virtual scouting.



Describes how to enable the Virtual Scouting tools.



VR Editing Tools

VR Camera and Light Tools

Menu

Virtual Scouting Settings

Navigation

Grip Controls

Bookmark

World Scale

The Virtual Scouting tools give filmmakers new ways to navigate and interact in virtual production environments, helping them make better creative decisions. Directors and cinematographers can easily find locations, compose shots, set up scene blocking, and get accurate representations of filming locations. Artists and set designers can experience a location in virtual reality (VR) while building it, and use measurement and interaction tools to check distances and modify the world. Images can be captured from the virtual world, and the whole production team can use those images to track decisions made during a VR session.

The Project Spotlight video below shows some of the advantages of using real-time virtual production tools in filmmaking, and some of the features of Virtual Scouting.

The Virtual Production Utilities plugin comes with a set of controls custom-tailored for filmmakers. This document describes these tools and how to use them. You can also dynamically customize the Virtual Scouting controls using Blueprints to suit specific requirements, without having to modify the underlying C++ code and rebuild the engine.

Virtual Scouting is compatible with the HTC Vive, HTC Vive Pro, Oculus Rift, and Oculus Rift S VR HMDs.

Menu

Virtual Scouting has a menu designed specifically to support virtual production scenarios. Navigation, Viewfinder, and other useful tools can be easily accessed from the menu.

You can toggle the Virtual Scouting menu on or off using the Menu button on your motion controller. The Menu button is just above the trackpad on the HTC Vive motion controller and is mapped to the A button on the right Oculus Touch controller and the X button on the left Oculus Touch controller.



Virtual Scouting Settings

You can modify the settings for some of the Virtual Scouting tools while in VR by accessing them in the panel. In the Virtual Scouting menu panel, navigate to the upper right corner and select the Settings button.



The Settings panel opens in front of the menu. The table below describes what settings you can change on your Virtual Scouting tools.



Settings Option

Description

Grip Inertia

When this option is enabled, you glide to a stop when navigating with the Grip buttons. The distance traveled is based on how fast you move with the Grip Nav.

Transform Gizmo

When this option is enabled, the 3D Move, Rotate, and Scale Gizmos appear after selecting objects in VR.



Help System

When this option is enabled, you can raise your motion controller in front of your HMD to see tooltips for the controller's buttons.



Unit Scale

A toggle button to switch between Metric and Imperial units.

Live Editing

When this option is enabled, keyframes are created when you interact with objects on different Sequencer frames. These keyframes can be edited from the visible overlay. For more details, see the Live Editing with Sequencer section.

Exit VR Mode

Selecting this option returns you to the UE4 standard editor window. This is the same as the Shift+V keyboard shortcut.

Flight Nav Speed

A slider to specify how fast you move when you use the Navigation tool.

Grip Nav Speed

A slider to specify how fast you move when you use the Grip buttons to navigate.

Navigation

You can fly around the scene with the Navigation tool while in Virtual Scouting Mode. Navigation is the default tool when you switch to Virtual Scouting in VR Mode. There are two ways to switch to the Navigation tool:

You can select the Navigation option in the Virtual Scouting menu.



You can hold down the menu button on your motion controller for two seconds.





Vive

Oculus Touch

To move around the scene with your Vive motion controller, point the motion controller in the direction you want to fly and press the trigger on the motion controller. To fly with the Oculus Touch controller, move the joystick in the direction you want to move. The harder you press the trigger on the Vive motion controller or the thumbstick on the Oculus Touch controller, the faster you fly. You can adjust the maximum speed in the Virtual Scouting Settings.





Changing the Navigation flight maximum speed

Grip Controls

The previous methods of navigating in the scene require having the Navigation tool selected. Even when you are using other VR tools, you can also navigate through the scene by pressing and holding the Grip button on one of the motion controllers. With one Grip button pressed down, move your hand towards yourself, as if you're pulling yourself forward, and release the button.





Vive

Oculus Touch

Turn off World Movement Options

By default in Virtual Scouting mode, using the Grip buttons on your motion controller brings up a colored grid, the World Movement Grid. This grid automatically darkens the level around you. You can turn this feature off by disabling the Grid and Post Process settings.

Navigate to Edit > Editor Preferences.

Select VR Mode.

On the VR Mode settings page, modify the World Movement settings.



Teleport In addition to being able to fly around to navigate your scene, you can teleport to jump to another location in the level.

To use the teleport function, rest your thumb over the bottom section of the Vive motion controller's trackpad or hold down either the B or Y button on the Oculus Touch controllers.

Once the green locator appears in the scene showing you the teleport destination, you can move your motion controller around to move the locator's position in the scene.

Pressing down on the top section of the Vive trackpad or releasing the Touch's B or Y buttons while this locator is visible in the scene teleports you to the locator's position.







Vive

Oculus Touch

Bookmark

With the Bookmark tool, you can place a location flag in your scene that you can return to at any point or that others can teleport to. To switch to the Bookmark tool, select the Bookmark option in the Virtual Scouting menu.



With the Bookmark tool equipped, press the trigger on your motion controller to place a location flag in your scene.



To view the location flags that exist in the scene, open the Virtual Scouting menu and in the right panel select the Bookmarks tab. Selecting a flag in the list teleports you to that location flag in the scene.



World Scale

You can change your world scale in the level to make yourself larger or smaller. Your world scale can range from 0.1 to 60. While you're scaling yourself, the backside of your virtual controller shows a readout for how much you've scaled yourself.

The following steps explain how to change your virtual scale within a scene while holding down the Grip buttons:

Scaling yourself larger:

Start with your hands far apart in front of you.

Press and hold the grip buttons on both controllers.

Bring your hands together in front of you and release the grip buttons.

Scaling yourself smaller:

Start with your hands close together in front of you.

Press and hold the grip buttons on both controllers.

Move your hands horizontally away from each other and release the grip buttons.

You can reset your world scale to 1.0 by double tapping one of the Grip buttons twice. Teleporting anywhere in the scene also resets your scale to 1.0.





Vive

Oculus Touch



Viewfinder

Virtual Camera

Camera Context Menu

Camera Monitor

Camera Marks

Tripod

Handheld

Dolly

Using the VR Camera

Mounting the Motion Controller to a Real Camera Rig

Camera Viewfinder and UI Panel Brightness

Camera Operating and Gizmos

How to Change the Camera Filmback

How to Change Lens Kit Information

Gaffer

Light Context Menu

Viewfinder



With the Viewfinder tool you can view the environment through a virtual lens and then spawn a virtual camera in the scene with the same viewport. The initial viewfinder display is only visible to you. For others to see your composition, you can create a camera in the scene easily with this tool. To activate this tool, open the Virtual Scouting menu and select the Viewfinder option.



The initial viewport monitor has a few features available from the trackpad or thumbstick on your motion controller.

The upper-left and upper-right sections of the Vive motion controller's trackpad can be clicked to change the lens: left switches to a shorter lens and right switches to a longer lens.

Moving the Rift thumbstick left or down switches to a shorter lens and right or up switches to a longer lens. The lens selections are determined by the Lens Kit.

The bottom area of the Vive Trackpad or the Rift's B or Y buttons takes a snapshot of the current viewfinder display. This is helpful when wanting to show other users in a Multi-User scouting session with you a particular composition.

Snapshots are also saved to the Content/Snapshots/[Level Name] folder on your computer. These snapshots can be useful for storyboards or shot planning.





Vive

Oculus Touch

An example of a snapshot (the image frame on the left) taken from the Viewfinder tool.



Virtual Camera

To spawn a virtual camera in the scene, press the trigger on your motion controller while the Viewfinder tool is active.

You can change the lens of the new camera using the same controls as the viewfinder display.

You can also select and operate the camera with your controller using this tool.

While you can also operate the camera with the Interaction tool, you won't be able to adjust the lenses unless you use the camera's context menu.



Camera Context Menu



You can make changes to the camera's settings directly in VR with the Camera Context Menu. Click the menu button on your motion controller while the camera is highlighted to bring up the Context Menu. The settings you can modify on the virtual camera are listed below.

Delete: Removes the camera from the level.

Mark: Spawns a camera location flag at the camera's current position. See the Camera Marks section for more.

Focal Length: Opens an additional HUD with lens options for the camera.

F-Stop: Opens an additional HUD with aperture options that can be used to adjust the focus range on the camera.

F-Stop adjustments do not affect exposure.

Snapshot: Takes a snapshot image from the camera's current position.

If using the Focal Length or F-Stop context menu options, click the left or right sections on the Vive motion controller's trackpad or move the Oculus Touch controller's thumbstick to the left or right. This adjusts the camera's settings using what is in the Lens Kit settings.



Camera Monitor

Floating above the virtual camera object when the camera is selected is a camera monitor to show what the camera sees. You can interact with this camera monitor to pin or move it. The following are ways you can interact with the camera monitor:

On the bottom left of the camera monitor is the Pin button. Selecting this keeps the camera monitor visible even when you deselect the camera or select other objects in the scene.



On the bottom right of the camera monitor is a toggle button. This option toggles between the camera monitor being locked to the camera or to you. If attached to you, the camera view stays in front of you as you navigate around the scene.



While the camera monitor is attached to you, you can select the bar underneath the monitor to reposition it. Moving your motion controller moves the camera monitor.



You can anchor the monitor in its current location and detach from you. To anchor the monitor in the level, select the arrow button to the left of the monitor bar.



Camera Marks



Use Camera Marks to save the position of the camera as well as its lens settings. You can return the camera to this position and these settings at any time to recreate the same shot composition. This feature is also helpful for communicating the start and end position of the camera for a moving shot, such as with a dolly.

You can teleport to the position of a camera mark by opening the Virtual Scouting menu and selecting the Camera Marks tab on the right panel. Press the trigger on your motion controller when the camera mark to which you want to teleport is highlighted.



Tripod



With the Tripod tool active, you can connect the virtual camera to your motion controller to operate the camera's pan and tilt rotation. The instructions below explain how to activate and use the tool:.

Open the Virtual Scouting menu and select the Tripod option to activate this tool. A virtual tripod appears and is connected to your motion controller.



Press the trigger on your motion controller to have your virtual camera attach to the tripod rig. Your motion controller drives the motion of the tripod, so you cannot detach your controller from the tripod while in this mode.



Press the trigger on your motion controller again to detach the camera from the tripod.





Handheld



With the Handheld tool you can connect your virtual camera to your motion controller to operate the camera. This movement tracking includes translations, along with pan, tilt, and roll.

Follow these instructions to activate and use the tool:.

Open the Virtual Scouting menu and select the Handheld option to activate the Handheld tool. A handheld camera rig appears and is connected to your controller.



Press the trigger on your motion controller to have a virtual camera attach to the handheld camera rig. Your motion controller drives the motion of the rig, so you cannot detach your controller from the rig while in this mode.





Press the trigger on your motion controller again to detach the camera from the tripod.

Dolly



With the Dolly tool active, you can create a dolly track in VR and have the virtual camera move along the track. Open the Virtual Scouting menu and select the Dolly option to activate the tool.



When using the Vive motion controller to add dolly points to the level, click the top section on the trackpad. After two or more points have been created, click the bottom section of the trackpad to spawn the rails into the level.

When using the Oculus Touch controller to add dolly points to the level, press the B or Y button. After two or more points have been created, press down on the thumbstick to spawn the rails into the level.





Vive

Oculus Touch

After the rails have been spawned, the dolly points can be edited to adjust the shape and path of the track. To edit the dolly points, select a dolly point and press the trigger on the motion controller.



In order to connect cameras to the dolly track, you must parent the camera to the rails in the Editor. This cannot be done in VR.



You can drive the position of the camera along the track with a custom Blueprint setup. With this custom setup, you can move the virtual camera using a physical dolly tracked in three-dimensional space.

Using the VR Camera

Mounting the Motion Controller to a Real Camera Rig

You can mount your motion controller onto a real tripod or handheld rig when using the Tripod and Handheld tools. This way, if desired, when you move your real tripod or handheld rig you can have more realistic camera motions using professional equipment.

To account for the variance of mounting positions of your motion controller to your physical rig, you can adjust the pivot point between your motion controller and the virtual camera.

With the virtual camera attached to the rig, use the Interaction tool with your other motion controller to select the camera with the interaction pointer.

Hold down the trigger on your motion controller to reposition the pivot point on the rig.

Release the camera with the Interaction tool to save the new pivot point for the virtual camera on the rig.

Camera Viewfinder and UI Panel Brightness

You can adjust the brightness on your viewfinder or camera monitor if it is too bright or dark by following these steps.

Navigate to Edit > Editor Preferences.

Select VR Mode.

On the VR Mode settings page, modify the UI Panel Brightness setting.



Camera Operating and Gizmos

Manipulating the camera in a single axis is easier with the Transform Gizmo enabled. You may find it preferable to disable the Transform Gizmo if you plan to operate the camera directly with your motion controller.





With Transform Gizmo enabled

With Transform Gizmo disabled

How to Change the Camera Filmback



Any virtual camera added to the level with the Viewfinder tool is going to have a set of film backs that can be used on that camera. You can edit the list of film back options and aspect ratio for each.

Open your project's Engine > Config > DefaultEngine.ini file in a text editor.

Edit the options in the FimbackPresets array.

Edit the DefaulFilmbackPresetName to change the default film back for the Viewfinder tool.



If the preset values are edited, it is recommended to distribute that DefaultEngine.ini to any other machines that are going to be used together for a Multi-User Virtual Scouting session.

How to Change Lens Kit Information



Any virtual camera added to the level with the Viewfinder tool is going to have a set of lenses that can be used on that virtual camera. You can add to or edit this list of lenses that the virtual camera can use while Virtual Scouting.

Open your project's Engine > Config > DefaultEngine.ini file in a text editor.

Edit the options in the LensPresets array.

Edit the DefaultLensPresetName within the lens kit array to change the default lens for the Viewfinder tool.



Prime and Zoom lenses can be defined but the Viewfinder tool will only switch between the possible Prime lens options.

Gaffer



With the Gaffer tool, you can spawn a light in your scene. You can move and adjust this light as if it were a real light on set.

Open the Virtual Scouting menu and select the Gaffer option to activate the Gaffer Tool.



Press the trigger on your motion controller to make a light appear in your level.



Move your motion controller inside the light's collision layer to make moving and rotating the light more natural.

You can adjust the spread and brightness of the light using the trackpad on your Vive motion controller or the thumbstick on your Oculus Touch controller.

The top section of the trackpad or thumbstick makes the light brighter and the bottom section of the trackpad or thumbstick makes the light dimmer.

The left section of the trackpad or thumbstick widens the spread and the right section of the trackpad or thumbstick narrows the spread.





Vive

Oculus Touch

Light Context Menu

Using the Light Context Menu you can edit the light's intensity and spread as well as settings for the light's temperature. To view the Light Context Menu, select the light and press the Menu button on your motion controller.





Click down on the trackpad or thumbstick to select the options in the menu. This opens a HUD with the following settings. Choose an option in the HUD using the trackpad or thumbstick.

Delete: Removes the selected light from the scene.

Intensity: Brings up an additional HUD with Brightness options for the light.

Spread: Brings up an additional HUD with throw angle options for the light. These are visible from the angle of the panels attached to the light.

Temperature: Brings up an additional HUD with color temperature options in Kelvin for the light.

Duplicate: Spawns a copy of the light in the scene.



Interaction

Transformation Gizmos

Object Context Menu

Marker

Measure

Multi-User Editing

Flare

Sequencer

Live Editing with Sequencer

Interaction

The Interaction tool allows you to transform and manipulate objects in your scene. When in Interact mode, a ray always appears from your virtual controller indicating where you are pointing in the scene. Direct this pointer at an object in the scene in order to interact with it by translating, scaling, or rotating the object in the scene. There are two ways to switch to the Interact tool:

Select the Interact option in the Virtual Scouting menu.



Double tap the menu button on one of your motion controllers.





Vive

Oculus Touch

Select an object by directing the pointer at the object and then pressing and releasing the trigger on your motion controller.

When an object is selected, it is highlighted in the scene.

After an object is selected, press and hold the trigger to move it around at the end of the pointer.

Scroll up or down on the Vive motion controller's trackpad to move the object away from or toward you, respectively, along the pointer ray.

You can also select an object by holding your virtual controller inside the object's collision layer. With your virtual controller still inside the object's collision layer, press and hold the trigger to grab the object and move it around the scene.



Transformation Gizmos

The Interaction tool includes the ability to transform objects by scaling, rotating, and translating them.

The Vive motion controller's trackpad is divided into four sections:.

Press the top section of the trackpad to fly through the scene while holding an object.

As with the Navigation tool, use the bottom section of the Vive motion controller's trackpad to teleport.

The right side of the trackpad cycles through the standard transformation gizmos—translation, rotation, and scaling. These transformations can occur along all three axes with ways to constrain movement to a combination of two axes.

The left side of the trackpad toggles between the selected gizmo and the Universal Gizmo.

Translation, rotation, and scaling are separate gizmos and occur along all three axes with ways to constrain movement to a combination of two axes.

The Universal Gizmo combines translation, rotation, and scaling into one gizmo.



The Oculus Touch controllers are organized as follows:

Move the thumbstick on the Oculus Touch controller in the direction you want to fly.

As with the Navigation tool, you can teleport by pressing the B or Y buttons on the Oculus Touch controller.

Clicking down on the Oculus Touch controller's thumbstick cycles through the standard transformation gizmos as well as the Universal Gizmo.

Translation, rotation, and scaling are separate gizmos and occur along all three axes with ways to constrain movement to a combination of two axes.

The Universal Gizmo combines translation, rotation, and scaling into one gizmo.







Universal Transform Gizmo

Standard Translation Gizmo

Object Context Menu

When an object is selected, you can open a context menu to quickly perform a series of actions. To open the context menu, press the Menu button on the motion controller. For most objects the context menu buttons default to the two options below. Cameras and lights have other options. Refer to the Camera Context Menu in the Viewfinder tool section and the Light Context Menu in the Gaffer tool section of the VR Camera and Light Tools for more.

Delete: Removes the selected object from the scene.

Duplicate: Makes a copy of the selected object in the scene.



To use the gizmos, you must enable the Transform Gizmo option in the Virtual Scouting menu.



Marker



With the Marker tool, you can spawn a colored ribbon in your scene for making notations in the scene. These marks are also visible to other users in a Multi-User Virtual Scouting session. To switch to the Marker tool, open the Virtual Scouting menu and select the Marker option.



With the Marker tool equipped, press the trigger on your motion controller to draw a three-dimensional ribbon in the scene with the tip of the virtual controller.

To change the color of the marker, rest your thumb on the Vive motion controller's trackpad or move the Oculus Touch controller's thumbstick to select a color in the color wheel.

Clicking down on the Vive motion controller's trackpad or the Oculus Touch controller's thumbstick selects the color to which the white circle is pointing.







Vive

Oculus Touch

You can erase the marks you make with the Marker tool.

Select the eraser icon in the middle of the color wheel to switch the marker into an eraser.

To delete a mark, move the tip of the virtual controller to the mark and press the trigger on the motion controller.

Marks can also be deleted with the Undo option in the Virtual Scouting menu or with the Undo gesture.



Measure





Measure tool example with metric units

Measure tool example with imperial units

With the Measure tool, you can measure the distance between objects or specific locations in your scene, in either metric or imperial units. To switch to the Measure tool, open the Virtual Scouting menu and select the Measure option.



With the Measure tool equipped, a pointer ray projects from your virtual controller.

A small gold cube appears at the end of the ray when there is an object from which that you can measure the distance from. Press the trigger on your motion controller to trace a light blue line to another object.

Release the trigger to measure the length of the light blue line. A heads-up display (HUD) appears with the measurement between the two points.

To switch the measurement units in the HUD, open the Settings panel in the Virtual Scouting menu and toggle between metric and imperial unit scale.



In addition to measuring the distance between objects, you can place custom flags to measure between different locations in your scene. Placing multiple flags shows the distance between neighboring flags as well as the total distance from end to end.



To place these flags in your scene, use the top section of the Vive motion controller's trackpad or the B or Y buttons on the Oculus Touch controller with the Measure tool active.

To remove an existing flag, move the virtual controller towards the flag until it interacts with it. Then, click the bottom half of the Vive motion controller's trackpad or pull the Oculus Touch controller's thumbstick down.

Flags also disappear when you switch away from the Measure tool.





Vive

Oculus Touch

Multi-User Editing

Virtual Scouting as a workflow concept makes heavy use of the Multi-User Editor so all of the key members of a production can explore a scene together. All tools, unless otherwise noted, will have their changes reflected to all users in the multi-user session.

When multiple users are in a session, their names will appear in the left section of the menu. You can teleport to another user's location by selecting that user in this list.

Not all users have to be in virtual reality to participate. Sessions often work best when one of the artists is working from the desktop, performing complex actions that are hard to do in VR but straightforward when sitting in front of a computer.

For more information on multi-user editing, see Multi-User Editing.



Pointer

You can create a pointer ray from your virtual controller that is visible to other users in your Multi-User scouting session in order to direct their attention to a particular part of the scene. To use the pointer function, activate the Navigation tool and either press on the top section of the Vive motion controller's trackpad or press the trigger on the Oculus Touch controller.

Flare

To show where you are in the level to other users who are in a Multi-User scouting session with you, hold both controllers up over your head until they are close together. A red flare appears from the tip of your virtual controller.





Sequencer

Using the Sequencer tool, you can play back a sequence within your scene. To activate the tool, open the Virtual Scouting Menu and select the Sequence panel at the bottom of the menu.



You must have a sequence already added to your level and the Sequencer window / tab must be open in UE4 for this tool to function properly. See the Sequencer Overview for more information on adding a sequence to your level.

To scrub the sequence timeline, press and hold the trigger on your motion controller and move the motion controller to your right or left.

To play or pause the sequence, press the B or Y buttons on your Oculus Touch controller or press down on the center of your Vive controller's trackpad.

You can slowly track the playhead forward or back.

Using the Vive motion controller, slide your thumb over the trackpad in a clockwise or counter-clockwise direction.

Using the Oculus Touch controller, move the thumbstick on to the left or right.





Vive

Oculus Touch

Live Editing with Sequencer



Live Editing provides the ability to animate objects and keyframe objects in real time while in VR. This requires that your level have a sequence associated with it so the additional keys can be saved within that sequence.

Live Editing must be enabled in the Virtual Scouting Settings to use this feature.

To set keys and manipulate objects in your scene over time, you need to make changes to the position, rotation, or scale of your object on different frames in your sequence. Move the sequence to the frame number you wish to modify and edit the objects using the Interaction tool. When you scrub the sequence, you can see the edit you made to the object in the playback.



The Sequencer tool is important for this workflow.

Editing: Turn Off Snapping

When interacting directly with objects in VR, disabling snapping features can provide a better experience because movements will be smoother. You can disable these settings by following these steps.

Navigate to Edit > Editor Preferences.

Select the Viewports section.

Disable Grid Snapping, Rotation Snapping, and Scale Snapping.



Virtual Scouting Overview

Steps

End Result

Virtual Scouting is compatible with the HTC Vive, HTC Vive Pro, Oculus Rift, and Oculus Rift S VR HMDs. See SteamVR Prerequisites and Oculus Prerequisites for connecting your headsets to Unreal Engine.

In this how-to guide, you will configure a project to enable access to the Virtual Scouting tools.

Steps

With your project open, select Edit > Plugins from the main menu.

From the Plugins menu, under Virtual Production, enable the Virtual Production Utilities plugin.



Restart the editor when prompted.



Select Edit > Project Settings from the main menu.

In Project Settings > Plugins > Virtual Production Editor > Virtual Production, set the Virtual Scouting User Interface to Virtual Scouting Widget.



If the Virtual Production Utilities plugin is enabled, but the Virtual Scouting User Interface is not set to VirtualScoutingWidget, it may affect VR Editor behavior. This will be resolved in a future release.

Select Edit > Editor Preferences from the main menu.

In General > VR Mode > Motion Controllers, set the Interactor Class to VirtualScoutingInteractor.



Select Edit > Editor Preferences from the main menu.

In Editor Preferences > General > VR Mode > Motion Controllers, set the Teleporter Class to VirtualScoutingTeleporter.



Select Edit > Editor Preferences from the main menu.

In Editor Preferences > General > VR Mode > World Movement, uncheck Show World Movement Grid and Show World Movement Post Process.





Select Edit > Editor Preferences from the main menu.

In Editor Preferences > Level Editor > Viewports > Grid Snapping, uncheck Enable Grid Snapping, Enable Rotation Snapping, and Enable Scale Snapping.





Enter VR Mode.



End Result

Once you are in VR Mode, pressing the Menu button on your VR controller will make the Virtual Scouting panel appear, giving you access to the various Virtual Scouting tools. For more information about the individual tools, see the Virtual Scouting Overview.



Landscape Splines

Starting Out

Reference



Below are links to the documentation pages that cover Blueprint Spline Components and Blueprint Spline Mesh Components.

Starting Out

Blueprint Spline Components Overview

Reference

Blueprint Spline Component Property Reference

Blueprint Spline Mesh Component Property Reference

At their core, a Blueprint Spline Component is just a path for you to define and use positional data. You can use it to move Actors (or other Components) around the world, or place a series of Actors (or other Components) along the spline. They are fully editable in the Blueprint Viewport and in the Level Editor, with the ability to add/remove/duplicate Spline Points, change their tangent types, and even animate them on tick. Further, they are also editable using the Blueprint Construction Script, taking in edits made in the Blueprint Viewport or Level Editor, and mofifying them further.



Blueprint Spline Mesh Components have a completely different use case. These deform a single Static Mesh along a two point spline. You cannot add more Spline Points to a Blueprint Spline Mesh Component, but the two points are completely controllable through Blueprints.



While their use cases are very different, they share the same procedures for adding them to a Blueprint, and use the same editing tools.

Properties

Transform

Sockets

Spline

Advanced

Editor

Selected Points

Tags

Activation

Events

This page contains a reference listing of properties available on Blueprint Spline Components. The properties displayed will be slightly different if the Blueprint Spline Component is selected in the Blueprint Editor, is a Root Component, or if the component is selected in the Level Editor.

Properties

Transform



Property

Description

Location

The location of the Actor or Component in World Space or Relative to its parent.

Rotation

The rotation of the Actor or Component in World Space or Relative to its parent.

Scale

The Scale of the Actor or Component in World Space or Relative to its parent.

Sockets



Property

Description

Parent Socket

When this component is the Child of a Skeletal Mesh Component (or Static Mesh Component with a Socket), you can specify a Socket or Joint to attach this component to.

Spline



Property

Description

Duration

Override Construction Script

Input Spline Points to Construction Script

Draw Debug

Closed Loop

Default Up Vector

Advanced



Property

Description

Reparam Steps Per Segment

Stationary Endpoints

Editor



Property

Description

Editor Unselected Spline Segment Color

Color of an unselected spline component segment in the editor.

Editor Selected Spline Segment Color

Color of a selected spline component segment in the editor.

Should Visualize Scale

Whether or not scale visualization should be displayed in the editor.

Scale Visualization Width

Width of the spline when scale visualization is enabled in the editor.

Selected Points



Property

Description

Input Key

This is the index of the selected Curve Point on the curve.

Position

This is the location of the selected Curve Point in local space.

Arrive Tangent

This is the vector that defines the tangent of the curve as it approaches the selected Curve Point.

Leave Tangent

This is the vector that defines the tangent of the curve as it departs the selected Curve Point.

Rotation

Rotation can be applied to a Curve Point to modify its tangents. This value is applied separately from the tangents, so both can be modified to create the desired results.

Scale

Scale can be applied to a Curve Point to modify its tangents. This value is applied separately from the tangents, so both can be modified to create the desired results.

Type

Defines the type of curve at the selected Curve Point.

Type

Description

Linear

From the selected Curve Point to the next, the curve will be straight. This affects the tangent coming into the selected Curve Point as well as the tanget departing the next.

Curve

Default value. The locations of the Curve Points (before and after the selected one) define the tangents of the selected Curve Point.

Constant

Like Linear but doesn't affect the tangent coming into the selected Curve Point as well as the tanget departing the next.

CurveClamped

Like Curve but it clamps the tangents of the curve.

CurveCustomTangent

If you adjust any tangent on a Curve Point, it is set to this value.

Tags



Property

Description

Component Tags

Activation



Property

Description

Auto Activate

Events



Property

Description

On Component Hit

On Component Begin Overlap

On Component End Overlap

On Component Wake

On Component Sleep

On Begin Cursor Over

On End Cursor Over

On Clicked

On Released

On Input Touch Begin

On Input Touch End

On Input Touch Enter

On Input Touch Leave

Physics Volume Changed

Delegate that will be called when PhysicsVolume has been changed.

Properties

Static Mesh

Materials

Spline Mesh

Advanced

Spline

Physics

Collision

Lighting

Advanced

Rendering

Advanced

Mobile

This page contains a reference listing of properties available on Blueprint Spline Mesh Components. The properties displayed will be slightly different if the Blueprint Spline Mesh Component is selected in the Blueprint Editor, is a Root Component, or if the component is selected in the Level Editor.

Properties

Transform



Property

Description

Location

The location of the Actor or Component in World Space or Relative to its parent.

Rotation

The rotation of the Actor or Component in World Space or Relative to its parent.

Scale

The Scale of the Actor or Component in World Space or Relative to its parent.

Sockets



Property

Description

Parent Socket

When this component is the Child of a Skeletal Mesh Component (or Static Mesh Component with a Socket), you can specify a Socket or Joint to attach this component to.

Static Mesh



Property

Description

Static Mesh

Specifies the Static Mesh to render for this component.

Materials



Property

Description

Element #

Once a Static Mesh has been specified in the Static Mesh Property, a number of additional Material Properties will appear. These will be named based on the Material IDs applied to the Static Mesh.

Spline Mesh



Property

Description

Start Pos

Start Tangent

End Pos

End Tangent

Spline Up Dir

Forward Axis



Property

Description

Start Scale

Start Roll

Start Offset

End Scale

End Roll

End Offset

Smooth Interp Roll Scale

Spline Boundary Min

Spline Boundary Max

Spline



Property

Description

Allow Spline Editing Per Instance

Physics

Physics



Property

Description

Double Sided Geometry

If enabled, the physics triangle mesh will use double-sided faces when doing scene queries. This is useful for planes and single-sided meshes that need traces to work on both sides.

Simple Collision Physical Material

Physical material to use for simple collision on this body. Encodes information about density, friction, and so on.

Physics Type

Simulated: Object will use physics simulation.

Kinematic: Object will not be affected by physics, but can interact with physically simulated bodies.

Default: Object will inherit from OwnerComponent's behavior.

Mass in KG

Mass of the body in KG.

Linear Damping

'Drag' force added to reduce linear movement.

Angular Damping

'Drag' force added to reduce angular movement.

Enable Gravity

If the object should have the force of gravity applied.

Advanced



Property

Description

Start Awake

If the object should start awake, or if it should initially be sleeping.

Center Of Mass Offset

User specified offset for the center of mass of this object, from the calculated location.

Mass Scale

Per-instance scaling of mass.

Max Angular Velocity

The maximum angular velocity for this instance.

Sleep Family

The set of values used in considering when to put this body to sleep. Normal, Sensitive, Custom.

Inertia Tensor Scale

Per-instance scaling of inertia (larger values mean more difficulty rotating)

Walkable Slope Override

Custom walkable slope setting for this body.

See the Walkable Slope documentation for usage information.

Walkable Slope Behavior

Behavior of this surface (whether we affect the walkable slope).

Walkable Slope Angle

Override a walkable slope, applying the rules of the Walkable Slope Behavior.

Custom Sleep Threshold Multiplier

If the Sleep Family is set to Custom, multiply the natural sleep threshold by this amount. A higher number will cause the body to sleep sooner.

Stabilization Threshold Multiplier

The stabilization factor for this body if Physics stabilization is enabled. A higher number will cause more aggressive stabilization at the risk of loss of momentum at low speeds. A value of 0 will disable stabilization for this body.

Update Mass when Scale Changes

If true, it will update the mass when the scale changes.

Generate Wake Events

Determines whether 'wake/sleep' events should fire when this object is woken up or put to sleep by the physics simulation.

Collision

Collision



Property

Description

Never Needs Cooked Collision Data

To do chaos this is to opt out of CreatePhysicsMeshes for certain meshes. Better a long term mesh is not to call CreatePhysicsMesh until is known there is a mesh instance that needs it.

Collision Complexity

Collision Trace behavior - by default, it will keep simple (convex) and complex (per-poly) separate.

Collision Responses

See the Collision Response Reference documentation for more information.

Simulation Generates Hit Events

Should 'Hit' events fire when this object collides during physics simulation.

Phys Material Override

Allows you to override the PhysicalMaterial to use for simple collision on this body.

Advanced



Property

Description

Use CCD

If true Continuous Collision Detection (CCD) will be used for this component

Ignore Analytic Collisions

If true, ignore analytic collisions and treat objects as a general implicit surface.

Smooth Edge Collisions

Remove unnecessary edge collisions to allow smooth sliding over surfaces composed of multiple actors/components.

Lighting



Property

Description

Cast Shadow



Property

Description

Affect Dynamic Indirect Lighting

Affect Distance Field Lighting

Cast Dynamic Shadow

Cast Static Shadow

Cast Volumetric Translucent Shadow

Self Shadow Only

Cast Far Shadow

Cast Inset Shadow

Cast Cinematic Shadow

Cast Hidden Shadow

Cast Shadow as Two Sided

Light as if Static

Light Attachments as Group

Indirect Lighting Cache Quality

Single Sample Shadow From Stationary Lights

Lighting Channels

Rendering



Property

Description

Visible

Hidden in Game



Property

Description

Texture Streaming

Property

Description

Force Mip Streaming

LOD

Property

Description

Min Draw Distance

Desired Max Draw Distance

Current Max Draw Distance

Allow Cull Distance Volume

Detail Mode

Render In Main Pass

Receives Decals

Owner No See

Only Owner See

Treat As Background for Occlusion

Use As Occluder

Render CustomDepth Pass

CustomDepth Stencil Value

Translucency Sort Priority

Translucent objects with a lower sort priority draw behind objects with a higher priority. Translucent objects with the same priority are rendered from back-to-front based on their bounds origin.

Lpv Bias Multiplier

Bounds Scale

Use Attach Parent Bound

Tags



Property

Description

Component Tags

Activation



Property

Description

Auto Activate

Events



Property

Description

On Component Hit

On Component Begin Overlap

On Component End Overlap

On Component Wake

On Component Sleep

On Begin Cursor Over

On End Cursor Over

On Clicked

On Released

On Input Touch Begin

On Input Touch End

On Input Touch Enter

On Input Touch Leave

Physics Volume Changed

Delegate that will be called when PhysicsVolume has been changed.

Mobile



Property

Description

Receive Combined Static and CSM Shadows from Stationary Lights

New Rendering Features and Tools in Unreal Engine 5.0

Art Setup and Tools

Lighting Concepts and Features

General Rendering Features

Visuals and System Tools

Performance and Debugging

Mobile Rendering and Visualization

Visualization Tools

Third-Party Tools

Graphics Programming

Unreal Engine's rendering system is the core of its industry-leading visuals for designing interactive real-time experiences. Here, you'll learn about the features, concepts, and tools used to design and develop your projects that can scale from cinematic film and television quality to next-gen console and mobile platforms with remarkable fidelity.

The topics below can help you in setting up and managing your textures and materials applied to surfaces, learning about conceptual lighting techniques that can be applied when building your virtual worlds, creating stunning visual effects, optimizing and debugging content for performance, and much more.

New Rendering Features and Tools in Unreal Engine 5.0



A high level overview of Lumen's dynamic global illumination and reflections features.



An overview of technical capabilities and specifications of the Lumen Global Illumination and Reflections system.



Overview of Unreal Engine 5's virtualized geometry system to achieve pixel scale detail and high object counts.



Overview of using high resolution shadowing designed with film-quality assets and large dynamically lit open worlds in mind.



An overview of the features of the Path Tracer rendering mode.



A multi-platform command that dumps intermediary RDG textures and buffers to disk for investigating and debugging rendering issues.



An immediate-mode API which records render commands into a graph data structure to be compiled and executed.

Art Setup and Tools



Topics that discuss how and where texture assets are used.



Controlling the appearance of surfaces in the world using shaders.



An overview of the primary physically based Material inputs and how best to use them.



Save high resolution screenshots using a Blueprint tool to bake results to textures.



Save high resolution screenshots using a Blueprint tool to bake the results to textures.

Lighting Concepts and Features



Topics that demonstrate features and tools for lighting scenes.



A collection of topics on the global illumination options available to choose from.



A high level overview of Lumen's dynamic global illumination and reflections features.



An overview of technical capabilities and specifications of the Lumen Global Illumination and Reflections system.



Overview of using high resolution shadowing designed with film-quality assets and large dynamically lit open worlds in mind.



A collection of topics around the supported features of ray tracing and path tracing.



An overview of the various properties and features that lights support.



The available types of lights to choose from and how their mobility settings affect lighting in the scene.



Components and tools that enable users to build immersive worlds with environment lighting from fog, clouds, sky and atmosphere.



An overview of Mesh Distance Fields and its available features that you can use when developing your games.



Systems for how reflections are captured and displayed on reflective surfaces.



An overview of available shadowing methods and the properties they support.

General Rendering Features



Rendering subsystem including lighting and shadowing, materials and textures, visual effects, and post processing.



A high-level overview of the rendering paths available for Skeletal Meshes.



A how-to guide for configuring the Unreal Engine Movie Render Queue feature to get high-quality cinematics—particularly when using ray tracing.



Setting up materials to work with Landscape terrains



How To Create and Use LODs.



Techniques and guidelines for setting up lightmap UVs for Static Meshes.



An overview of generating your own lightmap UVs in Unreal Engine.

Visuals and System Tools



Effects applied to the whole rendered scene prior to being rendered.



Use Unreal Engine's Niagara visual effects system to create and preview particle effects in real time.



Describes the advantages of using the Forward Shading Renderer.

Performance and Debugging



Concepts and approaches to optimizing and debugging your projects for real-time rendering with features and tools available in Unreal Engine.



Overview of Unreal Engine 5's virtualized geometry system to achieve pixel scale detail and high object counts.



A high level overview of the Anti Aliasing options available in Unreal Engine.



An overview of the available virtual texturing methods in Unreal Engine.



An overview of available visibility and occlusion culling methods.



RenderDoc is a standalone open-source graphics debugger that you can use to perform single-frame captures and inspect them.



A multi-platform command that dumps intermediary RDG textures and buffers to disk for investigating and debugging rendering issues.



System for loading and unloading textures into and out of memory during gameplay.

Mobile Rendering and Visualization



Learn about Unreal Engine's mobile rendering path and its support for graphics features.



Previewing your games inside the Unreal Engine is based on the selected Mobile Platforms.

Visualization Tools



An overview of the features of the Path Tracer rendering mode.



A Blueprint tool to quickly set up product visualization using an HDR image projection with real-time lighting and shadowing.



A tool that provides a time of day system that is geographically accurate for location, date, and time.



A tool giving you fine control over the Sun's geographic location based on latitude, longitude, date, and time.

Third-Party Tools



A listing of third-party tools and plugins that are available.

Graphics Programming

FShaderCache

Mesh Drawing Pipeline

Graphics Programming Overview

Parallel Rendering Overview

Render Dependency Graph

Shader Development

Adding Global Shaders to Unreal Engine

Debugging the Shader Compile Process

Shader Debugging Workflows

AsyncCompute

Shaders in Plugins

Overview of Shaders in Plugins

Creating a New Global Shader as a Plugin

Threaded Rendering

Rendering Tools for Artists

Unreal Engine contains some in-editor tools and provides some for DCC applications to aid in content creation. Generally, these tools have been developed with specific intention and by technical artists with specific purposes in mind.

The tools and workflows listed in this page will help with creating content or achieving some goal for your own projects.

Rendering Tools for Artists

The tools in this section are useful for those creating content from within the Unreal Editor and for those using specified DCC Applications.



A landing page for the Pivot Painter Tool



Guide to the Pivot Painter 2.0 MAXScript, which stores model pivot and rotation data within vertices for interactive animation.

Pivot Painter Tool 1.0

Pivot Painter Tool 2.0



The Pivot Painter Tool is a MAXScript that stores model pivot and rotation information in the model's vertex data. That information can then be referenced inside of Unreal's shader system to create interactive effects.

Pivot Painter Tool 1.0



Guide to the Pivot Painter 1.0 MAXScript, which stores model pivot and rotation data within vertices for interactive animation.

Pivot Painter Tool 2.0



Guide to the Pivot Painter 2.0 MAXScript, which stores model pivot and rotation data within vertices for interactive animation.



Property reference for Pivot Painter 2.0.

Installation

Prep Tools

Hierarchy Painter

Per Object Painter

3ds Max Example File

Requirements

Other Notes

The latest version of the Pivot Painter Tool can be found here. Version 2.0 offers a simplified pipeline to create interactive foliage.

The Pivot Painter Tool is a MAXScript that stores model pivot and rotation information in the model's vertex data. That information can then be referenced inside of Unreal's shader system to create interactive effects.

The motion shown in the sample video is generated in real-time using vertex shaders. Each blade of grass rotates and bends around its root. The trees branches and leaves form a hierarchy and animate around their individual pivots points, while inheriting the parent's motion. The sub-objects rotation is stored as well, which allows for realistic dynamic reactions to wind forces.

Creating these shaders has been made much simpler with the addition of the Pivot Painter material functions. Sample content also helps by showing how an animation, like the one featured above, can be generated. Retrieving sub-object pivot points is now simply a matter of processing a mesh in 3ds Max with the Pivot Painter script, importing the file and creating a material using the Pivot Painter functions. The material functions contain pivot point outputs for both two level hierarchies and single level hierarchies.

Creating motion this way has its benefits. A model processed using this technique is only 18% larger in terms of memory than a standard Static Mesh. Animations are far less expensive than skeletal animations because they do not need to be stored as they are calculated on the fly. Vertex shader instruction counts are generally less of a performance concern than pixel instruction counts, due to the number of vertices on a model compared to the number of pixels on the screen.

The example shaders in the link below are only the tip of the iceberg in terms of what is possible. Experimenting with the information available may entice one to explore the other possible uses. Player interaction, interesting wind sources, non-foliage related motion and other effects are all possible when given access to sub-object level information.

Installation

You can find the Pivot Painter script in the following location:

This video covers installing the script and creating a keyboard shortcut and menu to open the Pivot Painter tool.

Prep Tools

This video will cover the "Prep Tools" section of the script as well as workflow tips and information about the overall process. Prep Tools contains options to detach model elements as separate objects and several tools to help create new pivot points easily.

The Prep Tools are designed to separate a given models elements into a series of new models and to move their pivots into ideal locations. It is not necessary to use these tools. They are simply provided for convenience. If the model being processed is already separated, its pivot is located at the point from which it is supposed to rotate, and the models X axis is facing down the length of the model, then your model is good to go to the next step.

Example: A clump of grass should be separated into its individual blades. A given blade of grass should rotate around its base when blown around by wind. So its pivot point should be located at the grass models base and the x axis of the pivot should point down the length of the model - in most cases with grass that would be upward.

Hierarchy Painter

This video covers the "Hierarchy Painter" segment of the script. This portion of the tool is used to store child parent relationships like the relation between a branch and leaf for instance, as well as the model pivot and rotation information in the meshes.

Models should only be processed with the "Hierarchy Painter" section of the script if the model requires a hierarchy. A tree with leaves is a good use case whereas grass is not. Grass should be painted with the "Per Object Painter" section.

Also, branches/parent pivots need to be positioned within a box as described by "Max dist for parent piv". For instance: if "Max dist for parent piv" is set to 4096 when the model is painted, then a branch/parent objects pivot point can be located anywhere within negative or positive 2048 in x and y and from 0 to 4096 on the z axis. Additionally, if "Max dist for parent piv" is set to anything other than 4096 during the model processing stage, that same number should be used within the models shader in unreal.



Per Object Painter

This video goes over the options available under the "Per Object Painter" script section. It also discusses some of the possible uses and some information about how the data is stored on the model.

3ds Max Example File

The file contains a copy of the tree used in the video tutorials.

Tree.max (right-click, then select Save As to download)

Requirements

3ds Max - The script has been tested using 3ds Max versions 2010 and 2012.

The Pivot Painter material functions. It is possible to use the script without the functions but they make the data far easier to use.

Other Notes

You should only process your models with either the "Hierarchy Painter" or "Per Object Painter" section of the script but not both. If you paint your model with "Hierarchy Painter", then the "PivotPainter_HierarchyData" material function should be used within the objects material. If the "Per Object Painter" section of the script is used, then "PivotPainter_PerObjectData" should be used to decode the pivot information within the material.

What's New for Pivot Painter 2.0

3ds Max Version and Script Information

Importing Assets

Writing Shaders

Troubleshooting

The Pivot Painter 2.0 MAXScript stores the pivot and rotational information in the model's textures. Those textures can then be referenced inside of Unreal's shader system to create interactive effects.

The motion shown in the sample video is procedurally generated in real-time using vertex shaders. The Pivot Painter material function forms motion inheritance information for each of the model's leaves and branches. Each element is animated using its individual pivot point, direction vector, bounds size and inherited motion. The results are fluid and realistic.

Creating these types of materials has been made much simpler with the addition of the Pivot Painter 2's Material Functions. Sample content, like that provided in Content Examples also helps by showing how an animation, like the one featured above, can be generated. Retrieving sub-object pivot points is now simply a matter of processing a mesh in 3D Studio Max with the Pivot Painter script, importing the files and creating a material using the available Pivot Painter functions. The sample foliage motion material function provides support for hierarchies up to 4 levels deep and 30,000 model elements.

Creating motion this way has its benefits. A model processed using this technique uses only one additional UV channel more than a standard Static Mesh, but its animations are far less expensive than skeletal animations because they are calculated in real time. Vertex shader instruction counts are generally less of a performance concern on the graphical side than pixel instruction counts, due to the number of vertices on a model generally being significantly lower than the number of pixels that the model draws.

If you'd like to explore some of the examples demonstrated in this page, you can download the Content Examples project from the Epic Games Launcher and open the PivotPainter2 map.



What's New for Pivot Painter 2.0

With Pivot Painter 2.0's release, you'll notice that there have been some improvements and changes to the MAXScript. While some options have been removed (Hierarchy Painter) or renamed (Per Object Painter to Vertex Alpha Painter), this is an improvement to the overall workflow to simplify the process of creating these types of detailed assets. This is all in service of expanding the capabilities of Pivot Painter 2 to get even better results than before, ultimately giving you the widest range of options when developing your own content! Read on below to read about the additional improvements that have been added.

Workflow Improvements

The rigging pre-processing step is now done through the standard Link tool in Autodesk 3ds Max. Simply model your tree as separate, logical elements like leaves and branches. Ensure that their pivots are ideally located and oriented (X-axis down the object's length) and then link them together as one would in a traditional rig.

Ultimately, this makes producing complex foliage far simpler. You can rig one branch, duplicate it, and then place it. A re-parented branch will retain its children's hierarchical arrangement as well.

Once your tree is rigged and modeled, simply select any element within the tree and under the Render Options sections, press the Process The Selected Object Hierarchy button. The script will automatically traverse the selected element's hierarchy to find its root and then go back up the chain to collect and process all of its children, finally, rendering the textures using whatever data was chosen from the available Render Options.



This method supports both individual and linked elements at the same time. In the case of combined grass and tree models, you would select every blade at once and then an element from the tree before pressing the Process Selected Object Hierarchy button.

Texture Coordinate Control

You now have control over which UV set is written to, enabling you to combine this system with others like the Vertex Animation tools. Also, the preferences chosen in Pivot Painter 2.0 are noted in the final output texture name as a helpful reminder.

The automated naming convention is as follows:

An example final output would look something like this.

Extensibility

The processing and rendering code has been thoroughly abstracted, resulting in a minimal amount of effort needed to add new rendering options in the future.

New Rendering Options

As part of the improvements with the MAXScript, there is a new bit-shifting algorithm used behind the scenes that stores integers as float data. This enables the hierarchy depth and max object count to increase from 3,000 to 30,000, which is vital for representing complex foliage.

This particular tree asset contains 14,431 sub-models.

16-bit RGB:

Pivot Point Location

Origin Positon

Origin Extents

8-bit RGB:

Object Basis Vectors (one vector at a time)

16-bit Alpha:

Parent Index (Int as float)

Number of Steps From Root

Random 0-1 Value Per Element

Bounding Box Diameter

Selection Order (Int as float)

Normalized 0-1 Hierarchy Position

Object X,Y, Z Bound Lengths From Pivot Location

Parent Index (Float - Up to 2048)

8-bit Alpha:

Normalized 0-1 Position in the Hierarchy

Random 0-1 Value Per Element

Object X,Y, Z Bounds Length (Up To 2048)

Recreating Bounding Boxes

When using 3ds Max, the model's bounding boxes are expanded as its sub-object geometry shifts during the modeling process. The object's bounding box is left no longer being oriented or aligned to the mesh during this process. The same thing can happen when you alter the meshes' pivot transform. To counteract this, the Recreate Bounding Boxes section will replace the bounding box of the selected meshes with one that is properly aligned and oriented to the meshes pivot point, which is very useful for the scripts other data gathering features (Vertex Alpha Painter and Bound information).



On the left, the model's pivot transform has been altered but the bounding box is not aligned and oriented properly. After using the Process Selected Objects button under the Recreate Bounding Boxes section, the rightmost model's bounding box has been properly aligned and oriented.

Merge Selected Model's Normals

The Merge Selected Model's Normals feature averages out normals on multiple models where open edge vertices happen to lay on top of each other. This option will fix the normal seam issues that occur when a single model is broken into multiple pieces specifically for use with Pivot Painter.







Press the Merge Mesh Normals button to adjust the normal of any open faces that meet.

Before the Normals are merged they are aligned to each face. After they are merged the they are more closely aligned so that the edges blend together more naturally.

3ds Max Version and Script Information

This tool has been tested with 3ds Max 2015 and 2016 currently. Other versions of 3ds Max have not been specifically tested, so be aware that you may run into issues when using these versions of 3ds Max.

To install the MAXScript, just drag-and-drop it from its location in [UE5Directory]/Engine/Extras/3dsMaxScripts/PivotPainter2.ms right into the 3ds Max viewport and the script will launch itself.

If you find that you are using this script a lot, you can always add it to one of the tool bars or quad menus. If you are unfamiliar how to do this the Autodesk site has a very detailed walk through that will explain the process.

3ds Max Unit Setup

Before you begin to use the tool you will need to first ensure that the units of measurement 3ds Max uses is set up to correctly match the units of measurement that Unreal Engine uses. This way, you can ensure that the data the tool exports from 3ds Max will work in the same manner inside the editor. Since the editor uses centimeters as its default unit of measurement, you will need to ensure that 3ds Max uses this as well. To change this setting in 3ds Max, do the following:

Open up 3ds Max and from the Main Toolbar select Customize > Unit Setup.

Next, click on the System Unit Setup button and under the System Unit Scale section. Use the drop-down, changing the setting from inches to centimeters. Then click the OK button.

Finally, change the Display Unit Scale to Generic Units and then press the OK button.

Importing Assets

When importing your assets, there are a few things you should be aware of to get the best results. Follow the setups for your Static Meshes* and textures** below.

Static Meshes

In the Import Options window, make sure to uncheck Skeletal Mesh and to enable the option for Combined Meshes.



Static Mesh Import Options





Click image for full size view

Skeletal Mesh: unchecked

Combine Meshes: Enabled



[OPTIONAL] Static Mesh Build Settings





Click image for full size view

If you've enabled Mesh Distance Fields for your project, you may want to enable Generate Distance Field as if Two-Sided from the Static Mesh Editor Build Settings. Depending on the content, you may not want distance fields enabled at all. If that's the case you should set the Distance Field Resolution Scale to 0 or from the Level Details panel you can uncheck the option for Affect Distance Field Lighting.

For some content, you may need to enable Full Precision UVs if you notice leaves are straying from their location.

It is recommended to do a "full" reimport (overwrite the previous model) whenever updating, instead of using the Reimport option. This is the safest method to prevent any material issues.

Textures

Once you import your generated textures created with Pivot Painter 2.0, make sure to open the Texture asset and set the following:



8-bit BMP Texture Settings





Click image for full size view

Mip Gen Settings: NoMipMaps

Compression Settings: VectorDisplacementMap(RGBA8)

sRGB: Unchecked

Filter: Nearest



16-bit EXR Texture Settings





Click image for full size view

Mip Gen Settings: NoMipMaps

Compression Settings: HDR (RGB, no sRGB)

sRGB: Unchecked

Filter: Nearest

Writing Shaders

All of the textures rendered from Pivot Painter provide us with the tools to create simple mathematical representations of our trees' sub-object (branches and leaves). With that information, we can then start to approximate each sub-asset's reaction to a wind source enabling us to create very detailed elemental hierarchies to produce naturalistic motion.

If you desire to write your own shader, you will need to know that some of the data types need to be unpacked. These unpacking functions use the following naming convention:

The PivotPainter2FolaigeShader Material Function, as it stands, can operate as a useful Material in itself, if it fits your needs, or it can act as the scaffolding for your own version of a foliage shader. For additional information about the Material Functions available for Pivot Painter, visit the Pivot Painter Material Functions reference page.

Pivot Painter 2 Foliage Shader

To implement Pivot Painter 2.0 animation within a Material is now fairly simple, with a lot of the back-end work already set up for you! Simply insert the PivotPainter2FoliageShader into your Material's code before making the final connection to the Material Attributes input pin. You'll also want to make sure to disable Tangent Space Normals in the Material Details panel.



This Material Function assumes that you've processed the asset with Pivot Painter's default UV and texture settings.

Once you create a Material Instance, you will have access to the available Wind Settings that enable you to control the sub-object hierarchy. In order to make use of these, you will first need to enable the Wind Setting for the level(s) that you want to affect.



When a Wind Setting is enabled, the available options for that hierarchy depth will be visible and editable.

You'll now have access to the Shared Wind Settings that allows you to assign the rendered textures from Pivot Painter.



Position and Index Texture: Assign your rendered Pivot Positional texture to this slot.

X-Vector and X-Extent Texture: Assign your rendered X-Vector and X-Extent texture to this slot.

With the correct textures assigned, you can now open the Wind Settings groups and enable the desired features. Each Wind Setting group controls the meshes at a specific hierarchical depth. In the example of a tree, Wind Setting 1 would control the trunk, the next group, the branches and so on.

Wind Turbulence and Gusts

This should enable you to produce fairly nice foliage animations. If they aren't tailored to your liking, you can create a new wind turbulence and gust magnitude texture. To do this, the RGB values of a vector are used to offset the wind vector and the alpha is then used to control the strength of the wind. These two channel sets are each sampled separately in the shader.

Use a texture to control vector offsets and strength of the wind for variety.

Optimizations

It is helpful to understand how the material works when attempting to optimize the results. The PivotPainter2FoliageShader Material Function has been designed in a generic fashion. It executes the same wind reaction code 4 times. Each time another set of settings is used it is done so on a hierarchy level that is one step deeper. You can see how this works by opening the PivotPainter2FoliageShader Material Function.

Should you open the PivotPainter2FolaigeShader Material Function, you will find this network of shader functionality for the Wind Hierarchy Depths that is exposed when you create a Material Instance.

Now, you can use the sections below to understand optimizations techniques you can use.

When all the shader features are enabled you can produce a fairly expensive Material. The shader can be optimized by disabling the Wind Settings groups (or hierarchy levels of a tree) that do not need to animate. For instance, you could simply enable Wind Setting 4 to animate the model's leaves on their own. Grouping wind reaction settings by hierarchy depth mean that the model's elements should be grouped in the same fashion. All leaves should be "X" number of steps away from the root object. All branches that behave similarly should be grouped together as well. For this reason, it is recommended to set up a "parent" or "master" Material Instance for assets like trees, where you can easily have multiple hierarchies.



The base Material is instanced to create your "master" Material Instance, which is used to define all of your wind settings all in one place. Then use additional Material Instances to define the pixel shader components of your hierarchy, like the base color textures for trunk, branches, and leaves. This way, you can also disable and optimize any properties not needed for that hierarchy depth.

As an example, the leaf Material Instance needs to simulate the trunk, both sets of branches, and the leaves themselves so that they properly move with the rest of the tree. The trunk, on the other hand, only needs to simulate the trunk animation, which means that you can disable the other hierarchies for the leaves and branches because they are not needed.

Another optimization to consider, especially if you're writing your own shader or plan to edit this one is, the method that we use to bend normals. The PivotPainter2FoliageShader Material Function performs actual rotations to the surface Normals when the user chooses to update the normals within the shader. This could be done more cheaply (with the risk of artifacts) using custom UVs and the BlendAngleCorrectedNormals Material Function.

Additional Use Example

Using the positional information and the hierarchical depth, you can create your own procedural growth or building animations like the ones below. You can also take a look at the Content Examples map PivotPainter2 for an example of how to set these types of examples up.

These examples can be found in the Content Examples project available from the Learn tab of the Epic Games Launcher. Open up the PivotPainter2.umap to explore these and other examples.

Troubleshooting

If the models seem to be animating poorly, attempt the following solutions:

Reimport the assets.

Check the model and texture settings.

Make sure that the Materials have Tangent Space Normals disabled.

Non-uniformly scaled meshes within 3ds Max will return incorrect transform values and will result in broken results. If this appears to be the case attempt a "Reset XForm" operation. It's always safer to non-uniformly scaled meshes via the sub-objects rather than at the object-level. It's recommended to do this before you start duplicating, parenting and placing model elements.

Some mesh warping appears due to optimizations are done within the shader. To properly calculate wind's effect on a branch, we would need to calculate the wind's effect on each leaf's pivot and its vector before executing each mesh rotation. Every rotation and offset operation is expensive, so we perform the mesh rotation for each element within its local space (before the other rotations are factored in). The resulting mesh offset from the rotation is then added to the other transformations. The result is less accurate but far cheaper. Sometimes the reduced accuracy will cause the foliage scale to alter a little based on the combination of offsets. So if this occurs you can try the following:

Reduce the intensity of the wind simulation.

Animate fewer hierarchical levels.

Rotate the mesh so that the coincidence occurs less frequently.

Prep Tools

Render Options

Vertex Alpha Painter

Package Model

This page will cover the various properties of the Pivot Painter 2 3DS Max script. This tool is used to create very complex animations by storing pivot and rotational information about the model inside of its textures. This MAXScript can be used create complex hierarchies of animations all driven by Material's inside of Unreal Engine 4.



Prep Tools



Property

Description

Detach Selected Model's Elements

This will detach every element in an object as its own object.

Preserve Custom Normals (Slow)

This will duplicate the model as many times as there are model elements and then delete all but one element from each copy. This is to preserve the meshes custom normals.

This method can potentially be very time-consuming depending on the number of elements being detached since the model will be duplicated for each element there is. It is recommended to only use this is absolutely necessary.





Detach Elements Based on Penetration



Pick Selected Obj

Pick an editable polygon object without any modifiers applied. Do not pick the same object for both the "selection object" and the "model to process" options. (Note: The selection mesh cannot have any holes.)

Pick Model to Proc

Pick an editable polygon object without any modifiers applied. Do not pick the same object for both the "selection object" and the "model to process" options. (Note: The selection mesh cannot have any holes.)

Detach Model Elements That Touch

This will separate any elements that touch or penetrate the selection object's geometry into its own separate object. (Note: This tool will not work properly if the selection object has any holes.)



Generate New Pivot Points



Pick Your Model Selection Set

Use this drop-down to select your model selection set.

Property

Description

Update

Press this to get the latest selection sets from 3DS Max.

Manage

Press this to manage your selection sets.



Pick Leaf Pivot Obj

Choose whether you would like to construct your pivots based off of the knots in a spline or the vertices in an editable poly object. This will enable the button selections for Pick Spline or Pick Mesh

Property

Description

Pick Spline

Use this button to pick a spline from the scene viewport. The script will find the closest vertex pair between each model and each knot in the spline. Then it will move the object's pivot to the location of that vertex and orient the axis to match the model. The x-axis will point toward the center of the model from the desired vertex. The z-axis will point along the surface's normal. Processing time will increase as vertex counts rise. (Warning: Do not use the H list hotkey. The object must be picked from the viewport.) (Tip: For grass use a single or two-knot spline placed well below your grass to increase calculation speeds.)

Pick Mesh

Use this button to pick a mesh from the scene viewport. The script will find the closest vertex match between the model's pivot and model's vertices. Then it will orient the leaf's axis to the polygonal orientation and vertex position. Warning: Do not use the H list hotkey. The object must be picked from the viewport.) (Tip: For grass use a single or two-knot spline placed well below your grass to increase calculation speeds.)



Num of Face Norms to Avg Near Pivot

Enter a value to specify the number of face normals you want to average near a pivot point. This enables you to control the number of normals you're affecting or you can simply enable the Average All checkbox to include all available face normals nearest the pivot.

Create New Pivots

This will generate a new pivot point for every editable polygon object in the selection set. The pivot will rest on the model vertex closest to a knot in the selected spline or vertex in the chosen editable poly object. The x-axes of the pivots will be oriented toward the averaged center of the meshes. The meshes' bounds will also be recreated and aligned with the new pivot.



Recreate Bounding Boxes



Process Selected Objects

As a model changes from via sub-object manipulation, its bounding box expands to fix the model elements but does not re-align itself with the model's pivot point. This function recreates the object's bounding box so that it aligns with the model's basis vectors. It is necessary to have a correctly constructed bounding box to successfully utilize the axis tools in the processing section along with the vertex alpha painting tools.

Property

Description

Update

Press this to get the latest selection sets from 3DS Max.

Manage

Press this to manage your selection sets.

Property

Description

Pick Spline

Use this button to pick a spline from the scene viewport. The script will find the closest vertex pair between each model and each knot in the spline. Then it will move the object's pivot to the location of that vertex and orient the axis to match the model. The x-axis will point toward the center of the model from the desired vertex. The z-axis will point along the surface's normal. Processing time will increase as vertex counts rise. (Warning: Do not use the H list hotkey. The object must be picked from the viewport.) (Tip: For grass use a single or two-knot spline placed well below your grass to increase calculation speeds.)

Pick Mesh

Use this button to pick a mesh from the scene viewport. The script will find the closest vertex match between the model's pivot and model's vertices. Then it will orient the leaf's axis to the polygonal orientation and vertex position. Warning: Do not use the H list hotkey. The object must be picked from the viewport.) (Tip: For grass use a single or two-knot spline placed well below your grass to increase calculation speeds.)

Render Options



Property

Description

Process The Selected Object Hierarchy

Select your mesh and then press paint. This script will locate all the editable polygon meshes that are connected to the selected mesh via their shared hierarchy. (One can connect one object to another via the 3DS Max Link tool.) After locating the meshes the script will then alter the UV channel you've chosen to act as the basis for the ensuing textures which will be generated. The default texture contains model information like pivot location in the images RGB channels and an index in the alpha. The index can be used to locate the current meshes parent mesh. This is made simple Pivot Painter 2.0 Material Functions in Unreal Engine 4.

UVs

Texture Coordinate Location

Paint

Custom Textures

Texture 1 RGB

Selection

Do not render

This option will prevent Texture 1 from being written.

Pivot Position (16-bit)

Write HDR pivot position information to the RGB channels of a texture. This information needs to be decoded using the ms_PivotPainter2_DecodePosition function when referenced inside a shader.

Origin Position (16-bit)

Write HDR object bounds center point information to the RGB channels of the texture. This information needs to be decoded using the ms_PivotPainter2 function when referenced inside a shader.

Origin Extents (16-bit)

Store the maximum length of the model at every basis vector from the origin of the model; stored as three floats. The local values can be referenced directly but should use ms_PP2_DecodeOriginExtent when referenced in a shader.

X Vector (8-bit)

Stores the models X-axis basis vector. It needs to be decoded with ms_PivotPainter2_DecodeAxisVector when referenced in a material.

Y Vector (8-bit)

Stores the models Y-axis basis vector. It needs to be decoded with ms_PivotPainter2_DecodeAxisVector when referenced in a material.

Z Vector (8-bit)

Stores the models Z-axis basis vector. It needs to be decoded with ms_PivotPainter2_DecodeAxisVector when referenced in a material.

Texture 1 Alpha

Selection



Available 16-Bit Selection Options



Parent Index (Int as float)

Pivot Painter 2 enables users to re-create complex hierarchies within the Unreal Engine's material system. It does so by iteratively sampling points within a texture, reconstructing the hierarchy with the information that it gathers in the process. The "Parent Index" option enables us to read a pixel and then to pinpoint where its parent object's pivot information is located within the same texture. Referencing this data directly is considered advanced. In most cases, it is expected that you will process models with the default texture settings which can then be used with the PivotPainter2FoliageShader function. This function recreates hierarchies up to four levels deep and provides many of the animation controls that you would need while animating foliage. For those that are interested in creating their own complex networks, the data in this channel is an integer that should be decoded to float form before being referenced via ms_PivotPainter2_UnpackIntegerAsFloat. That information can then be used in ms_PivotPainter2_ReturnParentTextureInfo to return the UV location of the object's parent object. A Is Child? (see Note section below) output pin will return a black or white value indicating whether or not the pixel points to another pixel as its parent or if it points to itself (meaning that it is the root object). Explore the PivotPainter2FoliageShader function if you would like more information.

The Render Options between Texture 1 and 2 are the same. Picking a 16-bit RGB option will show 16-bit Alpha options and hide the 8-bit Alpha options. Conversely, picking an 8-bit RGB option will show those and hide the 16-bit options.



Number of Steps From Root

This float value can be referenced without any additional decoding steps. It represents the number of steps that the current object is from being the root.

Random 0-1 Value Per Element

This will store a randomly generated 0-1 number per item and can be referenced without using additional decoding material functions.

Bounding Box Diameter

Store the local space diameter of the objects being processed as float values. This can be transformed into world space scale by multiplying the output by an output of the ObjectScale material function.

Selection Order (Int as float)

The order in which objects were selected inside 3DS Max that is stored as an integer when this option is selected. Use ms_PivotPainter_UnpackIntegerAsFloatPivotPainter2

Normalized 0-1 Hierarchy Position

When selected, the 3DS MAXScript will find the total depth of the hierarchy of the object selected, then find the object's depth within that hierarchy and then normalize the object's current depth by dividing it by the total depth. This information is stored as a 0-1 float value and does not need to be decoded.

Object X Width

This returns a float value that's equal to the total length of the object being processed in 3DS Max along its local X vector.

Object Y Depth

This returns a float value that's equal to the total length of the object being processed in 3DS Max along its local Y vector.

Object Z Height

This returns a float value that's equal to the total length of the object being processed in 3DS Max along its local Z vector.



Available 8-Bit Selection Options



Normalized 0-1 Hierarchy Position

When selected, the 3DS MAXScript will find the total depth of the hierarchy of the object selected, then find the object's depth within that hierarchy and then normalize the object's current depth by dividing it by the total depth. This information is stored as a 0-1 float value and does not need to be decoded.

Random 0-1 Value Per Element

This will store a randomly generated 0-1 number per item and can be referenced without using additional decoding material functions.

X Extent Divided by 2048 - 2048 Max

This returns an 8-bit float value that's equal to the total length of the object being processed in 3DS Max along its local X vector. These values use ms_PivotPainter2_Decode8BitAlphaAxisExtent to decode the value.

This format can represent values between 8-2048 in increments of 8.



Y Extent Divided by 2048 - 2048 Max

This returns an 8-bit float value that's equal to the total length of the object being processed in 3DS Max along its local Y vector. These values use ms_PivotPainter2_Decode8BitAlphaAxisExtent to decode the value.

This format can represent values between 8-2048 in increments of 8.



Z Extent Divided by 2048 - 2048 Max

This returns an 8-bit float value that's equal to the total length of the object being processed in 3DS Max along its local Z vector. These values use ms_PivotPainter2_Decode8BitAlphaAxisExtent to decode the value.

This format can represent values between 8-2048 in increments of 8.



Texture 2 RGB

Selection

Do not render

This option will prevent Texture 1 from being written.

Pivot Position (16-bit)

Write HDR pivot position information to the RGB channels of a texture. This information needs to be decoded using the ms_PivotPainter2_DecodePosition function when referenced inside a shader.

Origin Position (16-bit)

Write HDR object bounds center point information to the RGB channels of the texture. This information needs to be decoded using the ms_PivotPainter2 function when referenced inside a shader.

Origin Extents (16-bit)

Store the maximum length of the model at every basis vector from the origin of the model; stored as three floats. The local values can be referenced directly but should use ms_PP2_DecodeOriginExtent when referenced in a shader.

X Vector (8-bit)

Stores the models X-axis basis vector. It needs to be decoded with ms_PivotPainter2_DecodeAxisVector when referenced in a material.

Y Vector (8-bit)

Stores the models Y-axis basis vector. It needs to be decoded with ms_PivotPainter2_DecodeAxisVector when referenced in a material.

Z Vector (8-bit)

Stores the models Z-axis basis vector. It needs to be decoded with ms_PivotPainter2_DecodeAxisVector when referenced in a material.

Texture 2 Alpha

Selection



Available 16-Bit Selection Options



Parent Index (Int as float)

Pivot Painter 2 enables users to re-create complex hierarchies within the Unreal Engine's material system. It does so by iteratively sampling points within a texture, reconstructing the hierarchy with the information that it gathers in the process. The "Parent Index" option enables us to read a pixel and then to pinpoint where its parent object's pivot information is located within the same texture. Referencing this data directly is considered advanced. In most cases, it is expected that you will process models with the default texture settings which can then be used with the PivotPainter2FoliageShader function. This function recreates hierarchies up to four levels deep and provides many of the animation controls that you would need while animating foliage. For those that are interested in creating their own complex networks, the data in this channel is an integer that should be decoded to float form before being referenced via ms_PivotPainter2_UnpackIntegerAsFloat. That information can then be used in ms_PivotPainter2_ReturnParentTextureInfo to return the UV location of the object's parent object. A Is Child? (see Note section below) output pin will return a black or white value indicating whether or not the pixel points to another pixel as its parent or if it points to itself (meaning that it is the root object). Explore the PivotPainter2FoliageShader function if you would like more information.

The Render Options between Texture 1 and 2 are the same. Picking a 16-bit RGB option will show 16-bit Alpha options and hide the 8-bit Alpha options. Conversely, picking an 8-bit RGB option will show those and hide the 16-bit options.



Number of Steps From Root

This float value can be referenced without any additional decoding steps. It represents the number of steps that the current object is from being the root.

Random 0-1 Value Per Element

This will store a randomly generated 0-1 number per item and can be referenced without using additional decoding material functions.

Bounding Box Diameter

Store the local space diameter of the objects being processed as float values. This can be transformed into world space scale by multiplying the output by an output of the ObjectScale material function.

Selection Order (Int as float)

The order in which objects were selected inside 3DS Max that is stored as an integer when this option is selected. Use ms_PivotPainter_UnpackIntegerAsFloatPivotPainter2

Normalized 0-1 Hierarchy Position

When selected, the 3DS MAXScript will find the total depth of the hierarchy of the object selected, then find the object's depth within that hierarchy and then normalize the object's current depth by dividing it by the total depth. This information is stored as a 0-1 float value and does not need to be decoded.

Object X Width

This returns a float value that's equal to the total length of the object being processed in 3DS Max along its local X vector.

Object Y Depth

This returns a float value that's equal to the total length of the object being processed in 3DS Max along its local Y vector.

Object Z Height

This returns a float value that's equal to the total length of the object being processed in 3DS Max along its local Z vector.



Available 8-Bit Selection Options



Normalized 0-1 Hierarchy Position

When selected, the 3DS MAXScript will find the total depth of the hierarchy of the object selected, then find the object's depth within that hierarchy and then normalize the object's current depth by dividing it by the total depth. This information is stored as a 0-1 float value and does not need to be decoded.

Random 0-1 Value Per Element

This will store a randomly generated 0-1 number per item and can be referenced without using additional decoding material functions.

X Extent Divided by 2048 - 2048 Max

This returns an 8-bit float value that's equal to the total length of the object being processed in 3DS Max along its local X vector. These values use ms_PivotPainter2_Decode8BitAlphaAxisExtent to decode the value.

This format can represent values between 8-2048 in increments of 8.



Y Extent Divided by 2048 - 2048 Max

This returns an 8-bit float value that's equal to the total length of the object being processed in 3DS Max along its local Y vector. These values use ms_PivotPainter2_Decode8BitAlphaAxisExtent to decode the value.

This format can represent values between 8-2048 in increments of 8.



Z Extent Divided by 2048 - 2048 Max

This returns an 8-bit float value that's equal to the total length of the object being processed in 3DS Max along its local Z vector. These values use ms_PivotPainter2_Decode8BitAlphaAxisExtent to decode the value.

This format can represent values between 8-2048 in increments of 8.



Vertex Alpha Painter



Property

Description



Alpha Channel Falloff Controls



3D dist to piv multiplier

This multiplies a distance calculation from the pivot to the current vertex.

3D dist to piv contrast

The contrast option is used as the exponent of a power function applied to a distance based on a gradient between the object's pivot point and the current vertex position.

XYZ Multiplier

Selectively increase and decrease the influence of local space gradients on X, Y, and Z. The gradient is formed by finding the distance between vertices and the object's center line, as defined by the object's pivot point and an axis direction.

XYZ Contrast

The exponent of a power function applied to the XYZ gradient results.

Paint Current Selection

This paints the editable polygon objects in the selection set using the parameters above. The objects that aren't collapsed editable polygon objects will be ignored.

Solid Value Painting

Value

Use any value between 0 to 1 to be used to paint the selected meshes a solid color. A value of 0 will be black with 1 being full white.

Paint Selected Meshes a Solid Value

Fill the vertex alpha with a value of zero. This value can be referenced in an Unreal shader to isolate or remove animation from certain elements.



Preview on Selected Objects



Diffuse

Click on the active viewport to view this new channel.

Alpha

Click on the active viewport to view this new channel.

Color

Click on the active viewport to view this new channel.

Package Model



Property

Description

Merge Selected Model's Normals

Select several models that contain touching, open edges. This feature will average out their normals to form a continuous surface.

Topics

Rendering features of Unreal Engine often overlap with other systems and individual features found in the editor. Here, you will find a collection of topics that affect other features, such as Skeletal Meshes for animations, Movie Render Queue for rendering out high quality images through Sequencer, world building tools like Hierarchical Level of Detail and Geometry tools, and much more.

Topics



A listing of topics related to general rendering feature usage with other features and tools of Unreal Engine.



A high-level overview of the rendering paths available for Skeletal Meshes.



A how-to guide for configuring the Unreal Engine Movie Render Queue feature to get high-quality cinematics—particularly when using ray tracing.



Setting up materials to work with Landscape terrains



How To Create and Use LODs.



Techniques and guidelines for setting up lightmap UVs for Static Meshes.



An overview of generating your own lightmap UVs in Unreal Engine.

How Skeletal Meshes are Rendered

Sections and Chunks

8-bit and 16-bit Bone Indexes

Max Bones Per Section

GPU Skinned Vertex Factory

Enabling Unlimited Bone Influence Mode

Skin Cache System

Overriding Skin Cache on Skeletal Meshes

Ray Tracing and Hair Strand Skin Cache Rendering Requirements

Recompute Tangents

Tips for Debugging Skin Cache

Deformer Graph Plugin

There are several ways that Skeletal Meshes are rendered in Unreal Engine using different paths. In this page, you will learn about these different paths and how to use them in your projects.

How Skeletal Meshes are Rendered

Skeletal Meshes have three rendering paths:

GPUSkinVertexFactory

Skin Cache System

Mesh Deformer with Deformer Graph Plugin

Sections and Chunks

Skeletal Meshes are divided in two ways: Sections or Chunks. Each Section of a Skeletal Mesh is associated with a Material. If the geometry of one Section is too complex — meaning it has too many different bones influencing the section vertices — it's further divided into Chunks by the Geometry Pipeline, which corresponds to the number of draw calls the mesh will create.

When looking at a Skeletal Mesh Asset in the Skeletal Mesh Editor, the Details panel can give you a sense of how the mesh's Materials are divided. Under each LOD category, expand Sections to see the list of Materials and Chunks.

Below are two examples. The first, the most common result, shows a list of Materials (or Sections) for each Skeletal Mesh and its LODs. The second is a more advanced breakdown that shows when a Section (1) has been broken into Chunks (2). Generally speaking, Sections in the Skeletal Mesh Editor map to Materials. At runtime, Sections in rendering code refer to Chunks.





Skeletal Mesh Asset with only Materials Sections

Skeletal Mesh Asset with Sections (1) and Chunks (2)

8-bit and 16-bit Bone Indexes

When importing Skeletal Meshes, they can have either 8-bit or 16-bit bone indexes, which sets how many bones a Section can support. An 8-bit bone index supports up to 256 bones per Section where a 16-bit bone index supports anything above 256 bones.

By default, all meshes are imported using an 8-bit bone index. In the Project Settings under Engine > Rendering > Skinning, check the box for Support 16-bit Bone Index to support more bones per section.



When enabling this setting:

You need to restart the editor for this change to take effect.

Skeletal Meshes already in your project before this change must be re-imported for them to be updated.

Imported Skeletal Meshes will use 8 or 16-bit depending on whether Sections have up to 256 bones or more.

Max Bones Per Section

Skeletal Meshes allow a maximum limit of bones per Section for any source mesh being imported. The number of bones allowed per Section is the number of bones that can be skinned on the GPU in a single draw call. If the source mesh exceeds the maximum limit of bones per Section, the Geometry Pipeline divides the Section into smaller Chunks that fit within that limit.

A typical use case for controlling the maximum number of bones per Section is when your project supports both high-end and mobile platforms. You can use the Project Settings to set a Maximum bones per Sections for all platforms or individual ones in Engine > Rendering > Skinning.

By default, the maximum bones per Section is set to 65536. Mobile platforms have a capped maximum of 75 bones per Section.



You can override this setting per-platform by clicking the Add (+) icon and selecting a platform from the list.



The per-platform is clamped to the global setting Compat.MAX_GPUSKIN_Bones. By default, it is set to 65536 and should not exceed this value. If 16-bit index mode is not enabled, the limit is clamped to 256 (or an 8-bit bone index).

Use the console command SkeletalMeshReport to output a log of stats that breaks down each Skeletal Mesh in the project. The breakdown includes information about their set up and memory usage.



GPU Skinned Vertex Factory

The GPU Skinned Vertex Factory skins positions and normals / tangents using a Vertex Shader, and the results are stored as needed on the GPU. Each Vertex Factory supports both Default Bone Influences and Unlimited Bone Influences.

Default Bone Influences controls whether each vertex can be skinned by either 4 or 8 bone influences. The number of bone influences is fixed such that if a Skeletal Mesh is rendered with four bones per vertex, if a vertex is using only one bone, the remaining three slots are filled with zero weights and are still used for skinning computation. The bone indices and weights are bound to vertex streams, making this mode suited for lower end hardware and platforms.

Unlimited Bone Influences removes the fixed number of bone influences per vertex allowing a variable number of bone influences to be used instead. Instead of bone indices / weights being bound directly to the vertex streams, each vertex stores an index offset and bone influence count packed into a single integer. This value is used to look up into a vertex buffer containing the bone indices and weights data.

Enabling Unlimited Bone Influence Mode

The Unlimited Bone Influence mode is enabled from the Project Settings under the Engine > Rendering > Skinning section.



There are two settings that must be set:

Use Unlimited Bone Influences enables any newly imported (or re-imported) Skeletal Mesh to use the unlimited bone buffer instead of the default maximum bone influences for rendering. This setting cannot be changed at runtime and requires a restart of the editor when enabled.

Unlimited Bone Influences Threshold uses a fixed bone influence per buffer until the max default bone influence of the mesh exceeds that limit.

While the maximum number of influences per vertex is unlimited, in theory, in practice the maximum number of influences is capped to 12 because of the way Skeletal Mesh source data is stored.

When using Unlimited Bone Influences mode, we recommend enabling Unlimited Bone Influences and setting the Unlimited Bone Influences Threshold to 8. Skeletal Meshes with bone influences between 9 and 12 are rendered with the Unlimited Bone Influences path, and bone influences between 0 to 8 are rendered with the fixed 4 / 8 bone influences path.

Skin Cache System

The Skin Cache system skins positions and normals / tangents using a Compute Shader, and the results are cached in vertex buffers then passed to GPUSkinPassThroughVertexFactory — a variation of LocalVertexFactory — for rendering.



You can enable the Skin Cache system in the Project Settings under the Engine > Rendering > Optimizations section using the Support Compute Skin Cache setting.



The system provides flexibility to define behavior at the project level and for individual Skeletal Meshes to override its behavior.

Use the following Project Settings to set Skin Cache behavior and support:

Default Skin Cache Behavior controls Skeletal Meshes go through Skin Cache or GPUSkinVertexFactory path. There are two behaviors to choose from:

Inclusive includes all Skeletal Meshes in Skin Cache by default. Individual Skeletal Meshes can opt out and use the GPUSkinVertexFactory path instead.

Exclusive excludes all Skeletal Meshes from Skin Cache and uses GPUSkinVertexFactory by default. Individual Skeletal Meshes can opt in to use Skin Cache.

Maximum memory for Compute Skin Cache per world (MB) sets the maximum amount of memory (in megabytes) per world / scene allowed for the Compute Skin Cache to generate output vertex data and recompute tangents. Each world has its own Skin Cache object where Skeletal Meshes are inserted into Skin Cache on a first come, first serve basis.

The order of insertion is game dependent. If the Skin Cache is full and cannot accommodate another Skeletal Mesh, that mesh instead goes through the GPUSkinVertexFactory path. This can create a situation with level of detail (LOD) when a mesh switches from higher (lower-detailed) LOD to lower (higher-detailed) LOD, Skin Cache unloads the higher LOD but then cannot accommodate the lower LOD due to heavier memory requirements.

You can use the following console commands:

r.SkinCache.Mode sets whether Skin Caching is enabled or disabled. By default, it is enabled (1).

r.SkinCache.SkipCompilingGPUSkinVF reduces GPU Skin Vertex Factory variants by skipping compiling their shader permutations when the Skin Cache system is enabled.

0 Compiles all GPU Skin Vertex Factory variants. (Default)

1 Does not compile all GPU Skin Vertex Factory shader permutations.

Overriding Skin Cache on Skeletal Meshes

Individual Skeletal Mesh LODs can override Skin Cache behavior with the Skin Cache Usage dropdown selection.



Choose between:

Auto: Uses the global behavior set in the Project Settings for Default Skin Cache Behavior.

Disabled: This mesh will not use the Skin Cache. If Hardware Ray Tracing is enabled on the mesh, it implies Skin Cache is enabled.

Enabled: This mesh will use the Skin Cache.

Ray Tracing and Hair Strand Skin Cache Rendering Requirements

Rendering features such as Hardware Ray Tracing and Hair Strand rendering require the Skin Cache path for rendering. However, the Skin Cache path isn't used when a Deformer Graph is used to drive displacement. Ray Tracing and Hair Strand rendering will still work whenever a Deformer Graph is used.

With Hardware Ray Tracing, all Skeletal Meshes automatically go through the Skin Cache path and are rendered into ray tracing effects. You can disable Skeletal Meshes for Hardware Ray Tracing with r.RayTracing.Geometry.SupportSkeletalMeshes, which saves GPU memory and time resources. This cannot be changed at runtime.

Meshes also have the option of using a separate ray-traced LOD from a traditional raster LOD. You can control this using a combination of setting the Global Ray Tracing LOD Bias (r.RayTracing.Geometry.SkeletalMeshes.LODBias) and the individual Skeletal Mesh setting Ray Tracing Min LOD. The higher LOD index is chosen between Raster LOD Index and Global Ray Tracing LOD Index, and the set Ray Tracing Min LOD.



Recompute Tangents

Recompute Tangents is an optional step of Skin Cache after the skinning pass. Skin Cache recomputes the normals and tangents using the skinned triangles and does so in two compute shader steps:

A Triangle Pass where each triangle computes its normal and tangent from skinned vertex positions and accumulates the result to each of its three vertices.

A Vertex Pass where each vertex normalizes the accumulated normal and tangent. One of the mesh's vertex color buffer channels is optionally used as a blend mask between skinned normals / tangents and recomputed normals / tangents.

You can set recompute tangents globally for the project or per Skeletal Mesh.

Global Settings:

r.SkinCache.RecomputeTangents

1 forces recompute tangents on all Skeletal Meshes.

2 only recompute tangents on Skeletal Meshes that have enabled them on their Sections. (Default)

Per Mesh Settings:

Under the LOD [n] category, use the Sections to set how Recompute Tangents is handled for each Material Section.



Choose from the following:

None: Do not recompute tangents.

All: Recompute tangents for all color channels and use recomputed results.

Red / Green / Blue: Recompute tangents and lerp with skinned results using R/G/B vertex color buffer channel as a blending mask.

One limitation of Recompute Tangents is that each Chunk is processed independently from other Chunks of the mesh. Therefore, the vertices of a Chunk connected with adjacent Chunk(s) have no awareness of their connectivity. As a result, along the borders of two Chunks, there can be visible seams.

Tips for Debugging Skin Cache

Use the following to debug Skin Caching in your project.

Use profilegpu to capture a GPU frame with details of individual Skin Cache entries and the Skeletal Meshes they belong to.

Use r.SkinCache.PrintMemorySummary to output a breakdown of the memory usages of all Skin Cache entries.

0 disables the summary. (Default)

1 prints the summary on frames when memory exceeds the limit set by r.SkinCache.SceneMemoryLimitInMB or Maximum memory for Compute Skin Cache per world (MB) in the Project Settings.

2 prints the summary every frame.

Use the View Modes dropdown to one of the debug visualizations from the GPU Skin Cache list to visualize individual Skeletal Meshes with colorization..



You can use these visualization modes when launching the project with the -game command line argument when entering the console command r.SkinCache.Visualize followed by Overview, Memory, or RayTracingLODOffset. Disable the visualization by following the command with None. These view modes are disabled in packaged builds.

The Overview visualization shows Actors in the scene which have Skin Cache and Recompute Tangents enabled or disabled.



The top-left of the viewport displays color reference for the Actors in the scene.



The Memory visualization shows low, mid, and high Skin Cache memory usages for raster and ray tracing combined.



The top-left of the viewport displays Skin Cache memory information.



You can override the memory threshold per project by editing the values for GPUSkinCacheVisualizationLowMemoryThresholdInMB and GPUSkinCacheVisualizationHighMemoryThresholdInMB under the [/Script/Engine.Engine] section of the DefaultEngine.ini configuration file.

The RayTracingLODOffset visualization shows the LOD index difference between a ray-traced Skin Cache entry and a raster Skin Cache entry, which is useful when ray tracing uses separate LODs from ones used for rasterization.



This visualization mode is only available when Hardware Ray Tracing is enabled in the Project Settings.

The top-left of the viewport displays the color codes for the ray tracing LOD offset for the Actors in the scene.



Deformer Graph Plugin

This feature is currently in Beta.

The Deformer Graph plugin is an editor that enables you to construct vertex deformation pipelines that run exclusively on the GPU. It provides graph editing features for plug-and-play and setting up the required data flow to modify mesh vertex points according to some input it receives.



Designing Visuals, Rendering, and Graphics

Atmospheric Fog Component

Exponential Height Fog Component

Billboard Component

Material Billboard Component

Cable Component

Custom Mesh Component

Poseable Mesh Component

Decal Component

Instanced Static Mesh Component

Particle System Component

Post Process Component

Scene Capture 2D Component

Scene Capture Cube Component

Spline Mesh Component

Text Render Component

Atmospheric Fog Component

AtmosphericFogComponents are used to create fogging effects such as clouds or ambient fog in a level. There are several settings that can be adjusted for this Component that can affect how the effect is generated in your level when placed.

Examples of this type of Component in use with varying values for its Decay Height setting (which controls fog density decay height, ie. lower values cause the fog to be denser, while higher values thin the fog, causing less scatter) are portrayed below. For more information, see the Atmospheric Fog User Guide page.





Density Decay Height of 0.5 (8 km)

Density Decay Height of 0.35 (2.744 km)





Density Decay Height of 1.0 (64 km) and Max Scattering of 4

Density Decay Height of 1.0 (64 km) and Max Scattering of 1

Exponential Height Fog Component

The ExponentialHeightFogComponent is used to create fog effects but with a density that is related to the height of the fog.

Exponential Height Fog creates more density in low places of a map and less density in high places. The transition is smooth so you never get a hard cutoff as you increase altitude. Exponential Height Fog also provides two fog colors, one for the hemisphere facing the dominant directional light (or straight up if none exists), and another color for the opposite hemisphere.



See Exponential Height Fog User Guide for more information and settings that can be adjusted.

Billboard Component

The BillboardComponent is a 2D Texture that will be rendered always facing the camera and functions similarly to an ArrowComponent in that it can be used for a method of placement and easy selection. For example in the fog sheet that was created below, the only Component added is a BillboardComponent (the actual fog effect is a material that is dynamically created through script).



Inside the level, you can manipulate the fog sheet by selecting the BillboardComponent icon (which is a texture that you can specify).



For an example of how this Fog Sheet was created, see the Fog Sheet and Light Beams documentation.

Material Billboard Component

The MaterialBillboardComponent is a 2D Material that will be rendered always facing the camera. One example of where this type of Component could be used is in the form of 2D grass or foliage. Rather than using Static Meshes to represent pockets of growing grass or even individual grass blades, using a MaterialBillboardComponent with a Material used to convey growing grass, there is no need to have a 3D representation of grass as the billboard will automatically turn and face the player giving the illusion of three dimensional grass.

Cable Component

A CableComponent allows you attach two Components together while rendering a cable between them. On the cable itself, you can assign a Material and define parameters that affect the way the cable is displayed. To read more about how to use the cable component, check out the link below.





Custom Mesh Component

The CustomMeshComponent allows you to specify custom triangle mesh geometry.

Poseable Mesh Component

The PoseableMeshComponent allows bone transforms to be driven by a Blueprint.

Decal Component

A DecalComponent is a material that is rendered onto the surface of a mesh (a kind of "bumper sticker" for a model). Decals can be used for any number of purposes, such as bullet impact decals on a wall when shot, a skid mark decal for a car that breaks along a road, blood that splatters on the ground when being shot, etc. (an example decal is provided below).



There are several pages you can refer to for more information on working with Decals.

See Decal Actor User Guide.

See 1.1 - Basic Decal.

See Decals Content Examples.

Instanced Static Mesh Component

An InstancedStaticMeshComponent is a Component that efficiently renders multiple instances of the same Static Mesh. This type of Component is particularly useful for procedural level or room creation, as instead of placing hundreds (or even thousands) of Static Mesh Actors in your level, you can place one Instanced Static Mesh and add multiple instances of the Static Mesh (floors or walls for example) at a much lower performance cost.

See the Procedural Room Generation training stream on our Wiki for an example of working with InstancedStaticMesh Components and procedurally generating a random room.

Particle System Component

A ParticleSystemComponent allows you to add a particle emitter as a sub-object to another object. Adding a ParticleSystemComponent could be used for several reasons, from adding an explosion effect to something that gets destroyed to adding a fire effect to something you can set on fire. By adding this type of Component to another Object, through script you can access and set any of the parameters of the Particle Effect during gameplay (ie. turning the effect on or off).

For example, below we have a security camera and have added a ParticleSystemComponent for a spark effect.



Through script we could state that the spark effect is off by default, but activated when the camera is shot.



See Cascade Particle Systems for more information.

Post Process Component

PostProcessComponets enable Post Process controls for Blueprints. It will use a parent UShapeComponent to provide volume data if available. This type of Component could be used to shift the tone of your level, when Post Process Settings are applied to it. For example suppose you defined a default Post Process Setting to use for your game, when the player is damaged (or potentially killed), you could through script change the settings to a black/white tone for the Scene Color Tint.

For more information see the Post Processing Content Examples or Post Process Effects documentation.

Scene Capture 2D Component

The SceneCapture2DComponent is used to capture a "snapshot" of the scene from a single plane and feed it to a Render Target. There are settings for controlling the Field of View when capturing as well as specifying the Render Target texture (among other settings). An example of using this would be in the case of creating a mirror (shown below) or security camera view on a monitor (see Security Camera Switcher Button.)



Above we have created a Blueprint with a SceneCapture2DComponent and assigned a Render Target texture which was then used as a Material that we applied to the piece of geometry in the level. For more information, see Scene Capture 2D Content Example.

Scene Capture Cube Component

A SceneCaptureCubeComponent is used to capture a "snapshot" of the scene from 6 planes and feed it to a Render Target.



In most instances the SceneCapture2DComponent should accomplish most of your scene capturing needs, however in the event that you need a 3D capture of an environment you could use this type of Component. Be aware of your usage however as these are very expensive performance wise and should only be used when absolutely necessary. See the Reflections for more information on the different the methods that can be used to create reflections in your levels.

Spline Mesh Component

SplineMeshComponents can be used to stretch and bend a Static Mesh asset. With SplineMeshesComponents, you must provide vectors for the position and tangent for the start and end of the spline. Below, a SplineMeshComponent has been added to a Blueprint and a pipe Static Mesh has been assigned as the asset to affect.



While you specify the vectors for the position and tangent on the Component itself, you can use script to set these as variables and make them public so that they can be edited inside the Editor Viewport as seen below.



Above we can move the Start Transform and End Transform independently of moving the entire Actor, allowing us to stretch or rotate it as we desire. This example and setup can be found inside the Blueprint Splines Content Examples Content Examples map.

Text Render Component

A TextRenderComponent renders text in the world with the given font. Contains usual font related attributes such as Scale, Alignment, Color, etc. You might use this Component to indicate to a player that an object is intractable in your levels.

For example, suppose you had a chair in your level that players can sit down in when they approach it if they press a button. You could add a TextRenderComponent containing the instructions needed to execute the command of sitting (visibility set to off) along with a BoxComponent used as a trigger which will set visibility of the text to true when the player enters it (shown below).



In game when the player enters the trigger, the TextRenderComponent text is displayed informing the player how to sit.





Using Post Process Volumes

Post Process Features and Properties

Lens

Depth of Field

Bloom

Exposure and Local Exposure

Chromatic Aberration

Dirt Mask

Camera

Lens Flare

Image Effects: Vignette

Color Grading and Tonemapper

Color Grading

Film

Global Illumination

Lumen Global Illumination

Screen Space Global Illumination

Ray Tracing Global Illumination

Reflections

Lumen Reflections

Screen Space Reflections

Ray Tracing Reflections

Rendering Features

Post Process Materials

Ambient Cubemap

Ambient Occlusion

Ray Tracing Ambient Occlusion

Motion Blur

Ray Tracing Translucency

Path Tracing

Film Grain

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Post-processing effects enable artists and designers to define the overall look and feel of the scene through a combined selection of properties and features that affect coloring, tonemapping, lighting, and more. A special type of volume, called a Post Process Volume, can be added to a Level to access these features. Multiple volumes can be placed to define the look of a specific area, or it can be set to affect the entire scene.

Using Post Process Volumes

You can add a Post Process Volume into your Level using the Place Actors panel.



Click image for full size.

Once placed in the Level, use the Details panel to access all the available properties and features. You'll find that they are broken up into categories for the type of feature they are and what they affect.



Click image for full size.

The Post Process Volume Settings are specific settings for this placed volume and how it interacts with the scene and with any other Post Process Volumes it may overlap with. For example, you can toggle the Infinite Extent property to make this Post Process Volume affect everywhere in the scene, or leave it unchecked to have it affect only a certain area. When Volumes overlap, you can control how they interact with one another to blend from one to another, which is useful when you have radically different looks between them.

Property

Description

Priority

Specifies the priority of this volume. In the case of overlapping volumes, the one with the highest priority overrides the lower priority ones. The order is undefined if two or more overlapping volumes have the same priority.

Blend Radius

Sets the radius (in world units) around the volume that is used for blending. For example, when walking into a volume, the look can be different than that outside of the volume. The blend radius creates a transitional area around the volume.

Blend Weight

The amount of influence the volume's properties have. A value of 1 has full effect, while a value of 0 has no effect.

Enabled

Whether this volume affects post processing or not. If enabled, the volume's settings are used for blending.

Infinite Extent (Unbound)

Whether the bounds of the volume are taken into account. If enabled, the volume affects the entire scene, regardless of its volume's bounds. When not enabled, the volume only has an effect within its bounds.

Post Process Features and Properties

Access a Post Process Volume's properties and settings by selecting one placed in the Level. The Details panel will list the available categories and their available properties.

Unreal Engine uses some default post processing settings, even if you don't have a placed Post Process Volume in your Level. These default post process settings can be found and configured in the Project Settings in the Rendering > Default Settings section.

Configuring these options can be useful for Level Editing to stabilize auto exposure or bloom before you start working on defining the look of the scene.

Lens

The Lens category contains properties and settings that simulate common real-world effects from a camera lens.

Depth of Field

Similar to what happens with real-world cameras, Depth of Field applies a blur to a scene based on the distance in front of, or behind, a focal point. The effect is used to draw the viewer's attention to a specific subject in the shot based on depth. It also adds an aesthetic which makes the rendered image appear more like a photograph, or film.





There are two depth of field options available:

Cinematic Depth of Field is used for desktop and console platforms. It provides a filmic look with properties that align with those found on real-world cameras. The Post Process Volume provides some settings, but primarily the camera properties found on a Cinematic Camera Actor should be used to control depth of field.

Mobile Depth of Field is an optimized, low-cost option that works for mobile platforms. It uses gaussian blurring to set a focal region with near and far transition areas.

For more information, see Depth of Field

Bloom

Bloom is a lighting artifact of real-world cameras that also adds to the perceived realism of the rendered image by reproducing glow around lights and reflective surfaces. Bloom is an effect that works with other effects, like lens flares and dirt masks, but those are not covered by the general bloom properties.





For more information, see Bloom

Exposure and Local Exposure

The engine automatically controls exposure — though it's sometimes called eye adaptation — which adjusts how bright, or dark, the scene becomes for the current view based on current scene luminance. This effect recreates the experience of human eyes adjusting to different lighting conditions, like when walking from a dimly lit interior to a brightly lit exterior, or the other way around.

The Exposure category contains properties to select the type of exposure method to use and to specify how bright or dark it should allow the scene to become over a given time.

There is an additional control for exposure called Local Exposure that has its own category or properties. These properties apply local adjustments to exposure (within artist-controlled parameters) using edge-aware data structure while preserving luminance detail. This makes it particularly useful in challenging high contrast scenes, such as indoor scenes with very bright outdoors that are visible through doors and windows.

For more information, see Exposure

Chromatic Aberration

Chromatic Aberration is an effect that simulates the color shifts in real-world camera lenses. It's a phenomena where light rays enter a lens at different points causing separation of RGB colors.





Property

Description

Intensity

The amount of aberration/camera fringe, or camera imperfection, to simulate an artifact that happens in real-world camera lenses.

Start Offset

A normalized distance to the center of the framebuffer where the effect takes place.

Dirt Mask

The Dirt Mask is a texture-driven effect that brightens up the Bloom in defined areas of the screen. It can be useful to create a specific look of a camera lens and its imperfections, or something like dirt and dust that has gotten on the lens.





Property

Description

Dirt Mask Texture

Texture that defines the dirt on the camera lens where the light of very bright objects is scattered.

Dirt Mask Intensity

The intensity of the dirt mask.

Dirt Mask Tint

Apply an RGB color value to the dirt mask texture.

Camera

A set of properties controlling the camera shutter and cinematic depth of field.

Full properties and physically based properties of the camera should be set on the Cinematic Camera Actor.

Property

Description

Shutter Speed (1/s)

The camera shutter speed in seconds.

ISO

The camera sensor sensitivity to light.

Aperture (F-stop)

Defines the opening of the camera lens. Aperture is 1/f-stop. Typical lenses go down to f/1.2 (a large opening). Small numbers have a larger aperture opening, blurring more of the foreground and background. Larger values have a smaller aperture, blurring less of the foreground and background.

Maximum Aperture (min F-stop)

Defines the maximum opening of the camera lens to control the curvature of blades of the diaphragm. set it to 0 to get straight blades.

Number of diaphragm blades

Defines the number of blades of the diaphragm within the lens (between 4 and 16). This defines the shape of the bokeh.

Lens Flare

The Lens Flare effect is an image-based technique that simulates the scattering of light when viewing bright objects due to imperfections in the camera lens.



Property

Description

Intensity

Brightness scale of the image cased lens flares.

Tint

Tint color for the image based lens flares.

BokehSize

Size of the lens blur (in percent of the view width) that is done with the Bokeh texture.

Performance cost is radius x radius.



Threshold

Minimum brightness the lens flare starts having effect.

This should be as high as possible to avoid the performance cost of blurring content that is too dark to see.



BokehShape

Defines the shape of the Bokeh when the image based lens flares are blurred. It cannot be blended.

Tints

The RGB defines the lens flare color. The Alpha (A) is its position.

Image Effects: Vignette

Vignette is an image-based effect that creates a borderless window that fades the image out towards the edges.





Vignette Intensity controls darkening of the screen corners to create a borderless window from the rendered image to the edge of the window. Larger values increase the amount of vignetting. 0 is no vignetting.

Color Grading and Tonemapper

Color Grading and Film are two categories that work together to define a large part of the look of your project. The Color Grading category contains properties that allow for color correction of the rendered scene.

Color Grading

The Color Grading category includes properties to control the contrast, color, saturation, and much more for full artistic control of the look of the scene.

You'll find sections for:

Color temperature control

Color balance properties for global, shadows, midtones, and highlights

Additional miscellaneous properties, such as expanded gamut and look-up tables (Luts)

For more information, see Coloring Grading and Filmic Tonemapper

Film

The Film category includes properties that meet the Academy Color Encoding System (ACES) for television and film. These properties ensure that consistent color is preserved across multiple formats and displays while also future proofing the source material to not have to adjust it for each new medium that comes along.

The properties in this category enable you to set values that mimic different types of film stock.

Property

Description

Slope

Sets the steepness of the S-curve used for the tonemapper. Larger values make the slope steeper making the image darker, while lower values lessen the steepness making the image lighter.

Toe

Sets dark colors of the tonemapper.

Shoulder

Sets the bright colors of the tonemapper.

Black Clip

Sets where the crossover happens where black colors start to cut off their value.

Ideally, this shouldn't ever need to be adjusted.



White Clip

Sets where the crossover happens where white colors start to cut off their value. Changes to this value are subtle in most cases.

For more information, see Coloring Grading and Filmic Tonemapper

Global Illumination

The Post Process Volume Settings for Global Illumination enable you to select the type of dynamic global illumination to use, advanced properties enable you to adjust the intensity and color of some global illumination methods, such as precomputed lighting.

Dynamic global illumination methods can be selected from from the Method dropdown menu:

Lumen Global Illumination and Reflections

Screen Space Global Illumination

Ray Tracing Global Illumination

Under the Advanced section, the Indirect Lighting Color and Indirect Lighting Intensity to use a color picker to adjust the color of the indirect lighting and intensity will increase or lessen the amount of indirect lighting being applied.

For more information, see Global Illumination.

Lumen Global Illumination

Lumen Global Illumination is a fully dynamic global illumination system that works with all lights, emissive materials casting light, and sky light occlusion. It renders diffuse interreflection with infinite bounces and indirect specular reflections in large, detailed environments at scales ranging from millimeters to kilometers.





The only property available is the Final Gather Quality property that scales Lumen's the amount of noise artifacts that are visible. Larger scales reduce noise, but greatly increase GPU cost.

Screen Space Global Illumination

Screen Space Global Illumination is a low-cost dynamic global illumination method, but it is limited to information visible on the screen. It's best used as an additive feature with precomputed lighting data from CPU Lightmass or GPU Lightmass.





There are not any properties to adjust in the Post Process Volume settings, but you can increase the quality using console commands found under r.SSGI.*.

Ray Tracing Global Illumination

Ray Traced Global Illumination (RTGI) is deprecated and may be removed in a future release.

Requires that Support Hardware Ray Tracing and DirectX 12 be enabled for the project.

Ray Tracing Global Illumination

Property

Description

Type

Sets the ray tracing global illumination type:

Brute Force: A slower, but more accurate ray-traced global illumination method. It requires multiple bounces and increased sample counts to produce a good looking result with fewer artifacts, but comes at greater GPU cost.

Final Gather: A faster, less accurate ray-traced global illumination method. It uses only a single bounce of indirect lighting with a high number of samples per pixel. It amortizes the cost over multiple frames, trading quality for runtime performance.

Max Bounces

The maximum number of indirect diffuse lighting to ray trace.

Samples Per Pixel

Sets the number of samples per pixel to use for indirect lighting. Higher samples produce better quality and accuracy but at added GPU cost. Lower values should be used for real-time performance.

Reflections

The Post Process Volume settings enable you to select from the types of dynamic reflections you want to use with the Method dropdown selection.

Choose between:

Lumen Global Illumination and Reflections

Screen Space Reflections

Standalone Ray Traced Reflections

For more information, see Reflections Environment

Lumen Reflections

Lumen reflections are part of the dynamic lighting system Lumen Global Illumination and Reflections. It works the vast majority of features to support all lights, emissive materials casting light, and sky lighting.

Lumen only has a single Quality property which scales the reflection noise quality. Larger scales reduce the amount of noise in reflections, but greatly increases GPU cost.

Screen Space Reflections

Screen Space Reflections are a low-cost, view-dependent reflection system, but it is limited to information present within the current screen view.





Property

Description

Intensity

How much screen space reflections should affect the scene. Lower values fade out screen space reflections, falling back to either no reflections or placed Reflection Captures.

Quality

Controls the quality of the reflections. 0 is no soft transition, 50 (default for better performance) is some transition, and 100 is maximum quality with better reflection representation.

Max Roughness

Controls at what roughness screen space reflections are faded out. 0.8 works well, and smaller values give better performance

Ray Tracing Reflections

Ray Tracing Reflections is deprecated and may be removed in a future release.

Requires that Support Hardware Ray Tracing and DirectX 12 be enabled for the project.

Ray Tracing Reflections simulate physical light properties with multiple bounces of light on surfaces.





Property

Description

Max Roughness

Sets the maximum roughness until which ray tracing reflections will be visible. (A lower value is faster) Reflection contribution is smoothly faded when close to roughness threshold.

Max Bounces

Sets the maximum number of ray tracing reflection bounces from hit surfaces. Larger numbers of bounces allows for reflections in reflections, but at added GPU cost.

Samples Per Pixel

Sets the number of samples per pixel to use for reflections. Higher samples produce better quality and accuracy but at added GPU cost. Lower values should be used for real-time performance.

Shadows

Sets the type of ray traced shadows should appear in reflections: none, hard shadows, or soft area shadows. The quality of area shadows is dependent on the number of samples per pixel that are used and costs more to render than hard shadows.

Include Translucent Objects

Enables Ray Tracing Translucency in ray-traced reflections.

Rendering Features

The following are general rendering features that are set and controlled by the Post Process Volume.

Post Process Materials

Post Process Mateirals allow for materials that have their Domain set to Post Process to create visual screen effects. These can be used for just about anything you can do in a material and have that affect gameplay or the visual look of the scene. For example, it can be used for applying a damage effect, creating a stylized or video effect to the screen.



For more information, see Post Process Material

Ambient Cubemap

The Ambient Cubemap lights the scene from a provided cubemap texture. The image is mapped to a sphere in the far distance (implemented as a cubemap texture with mipmaps storing pre-blurred versions of the image). The pre-blurred versions of the cubemap are computed in a way that they can be used for specular highlighting with varying glossiness (sharp versus blurry reflections), and they can be used for diffuse lighting as well. This effect is independent of the position a material is lit from. Viewer position, material roughness (for specular effects), and the material surface normal are all taken into account.

The Ambient Cubemap has limited local shadowing (screen space ambient occlusion only). Use a Sky Light instead when representing the sky's lighting. The Ambient Cubemap is only intended to be used for a subtle directional ambient term (useful in games with completely dynamic lighting), or for model viewer applications. Because light comes from many directions, it cannot simply use shadowmaps for this light type. Screen Space Ambient Occlusion is applied to get contact shadows from nearby geometry.

Property

Description

Tint

Use a RGB color value to apply a color on top of the assigned cubemap texture.

Intensity

Scales the brightness of the assigned Ambient Cubemap texture. 0 is off.

Cubemap Texture

Assign a cubemap to this Post Process Volume that blends additively to objects in the scene.

Ambient Occlusion

The Ambient Occlusion properties control the screen space effect called Screen Space Ambient Occlusion (SSAO), which approximates the attenuation of light due to self-occlusion. This is a screen space effect that is limited to information available within the current view. Ambient Occlusion is generally used as a subtle effect, in addition to global illumination, that darkens corners, crevices, and other features to bring a more natural, realistic look to the scene.





Property

Description

Intensity

Defines how much ambient occlusion affects non-direct lighting after the base pass.

Radius

Affects the distance around objects that surfaces are affected. Larger values affect distance objects.



Advanced Properties



Static Fraction

Affects how much ambient occlusion affects Static lighting. 1 affects static lighting, and 0 is free, meaning no extra rendering pass is used.

Radius in WorldSpace

When enabled, ambient occlusion Radius is measured in world space units, opposed to locked to the view space in 400 units.

Fade Out Distance

The distance at which ambient occlusion disappears in the distance. This can avoid artifacts and ambient occlusion effects happening on large objects.

Fade Out Radius

The radius at which ambient occlusion starts to fade out before the Fade out Distance property.

Power

Controls the strength of the darkening effect that is computed.

Bias

Adjusts the amount of ambient occlusion detail. Some bias is needed to avoid precision artifacts in the distance. A value of 3 works well for flat surfaces, but can reduce details.

Quality

Adjusts the quality and perceived accuracy of screen space ambient occlusion.

Mip Blend

Affects the blend over the multiple mips (or lower resolution versions). 0 uses full resolution. 1 uses only low resolution. values in between find a balance.

Mip Scale

Affects the ambient occlusion Radius scale over multiple mips.

Mip Threshold

Adjusts the bilateral upsampling when using multiple mips.

Temporal Blend Weight

How much to blend the current frame with the previous frames when using Ground Truth Ambient Occlusion with temporal accumulation.

Ray Tracing Ambient Occlusion

Requires that Support Hardware Ray Tracing and DirectX 12 be enabled for the project.

Ray Tracing Ambient Occlusion (RTAO) accurately shadows areas to ground objects in the environment. Similarly to baked lighting, ambient shadowing is not screen space dependent. RTAO adds depth to the scene, producing natural looking shadowing in indirectly lit areas, such as under objects, or in corners and crevices.





Property

Description

Enabled

Whether ray tracing ambient occlusion should be enabled for this Post Process Volume.

Samples Per Pixel

Sets the number of samples to use per pixel for ray tracing ambient occlusion.

Intensity

Scales the ray tracing ambient occlusion in the scene for this Post Process Volume.

Radius

Defines (in world space units) the search radius for occlusion rays for this Post Process Volume.

For more information, see Hardware Ray Tracing.

Motion Blur

Motion Blur is the blurring of objects based on its motion. In photography and film (like with a sequence of frames), motion blur is the result of an object moving before the image has been captured, creating the blurring effect that is seen. Depending on how fast the object is moving can determine how much motion blur there is for the object.



The motion blur system in the engine uses a full screen velocity map, and objects are blurred based on their contribution to this map. The following properties control the contribution of objects in the scene to the velocity map.

Property

Description

Amount

The strength of motion blur. 0 is off.

Max

The maximum distortion caused by motion blur (in percent of the screen width). 0 is off.

Target FPS

Defines the target frames per second (fps) for motion blur. It makes motion blur independent of actual frame rate and relative to the specified target FPS results in shorter frames, which means shorter shutter times and less motion blur. Lower FPS means more motion blur. A value of 0 makes the motion blur dependent on the actual measured frame rate.

Per Object Size

The minimum projected screen radius for a primitive to be drawn in the velocity pass for motion blur consideration. The radius is a percentage of screen width. Smaller radii cause more draw calls. The default is 4%.

Motion blur is visualized in the editor using the Level Viewport Show > Visualize > Motion Blur.

Ray Tracing Translucency

This feature of ray tracing is deprecated and may be removed in a future release.

Requires that Support Hardware Ray Tracing and DirectX 12 be enabled for the project.

The Post Process Volume settings enable you to decide how you want translucency to be rendered, with traditional raster translucency or ray-traced. Ray Tracing Translucency uses rays to trace the path of light through translucent materials based on real-world physical properties.





For more information, see Hardware Ray Tracing.

Path Tracing

The Path Tracer is a progressive, hardware-accelerated rendering mode that produces physically correct global illumination, reflections, refractions, and more. It shares the same ray tracing architecture as Hardware Ray Tracing to create comparable results to offline renders.

When path tracing is enabled for the Level Viewport (View Modes > Path Tracing), the properties in the category enables you to configure how the path tracer accumulates samples and renders the frame.

For more information, see Path Tracer

Film Grain

Film Grain is an optical effect that simulates the look of processed photographic film. It can appear as tiny, randomized particles and adds a filmic look to the rendered frame.

Property

Description

Film Grain Intensity

The amount of grain to apply to the scene. 0 is no film grain, and 1 is full film grain.

Film Grain Intensity Shadows

The amount of film grain to apply to shadowed areas of the scene.

Film Grain Intensity Midtones

The amount of film grain to apply to mid-toned areas of the scene.

Film Grain Intensity Highlights

The amount of film grain to apply to areas with highlights in the scene.

Film Grain Shadows Max

Sets a maximum range for film grain to be applied to shadowed areas of the scene.

Film Grain Highlights Max

Sets a maximum range for film grain to be applied to highlighted areas of the scene.

Film Grain Texel Size

Size of the texel of the film grain on the screen.

Film Grain Texture

Defines a texture to use for the film grain being applied. It can be used to create a specific look to the noise that film grain has.

Blendable

The Blendables Container

Blendable in the package, as part of the object (e.g. volume) or dynamically created in the Blueprint

How to create your own Blendable (in C++)

Blueprint

Future

A Blendable is an asset that has properties which can be smoothly interpolated (blended) with other blendables. We mostly used blendables for PostProcessMaterials but the system can be used for anything that should be depending on the view (usually dependent on the camera position).

Blendable

We have Blendables in the engine for a while but only used for PostprocessMaterils / PostprocessMaterialInstances. But the concept is more general purpose as it allows to blend arbitrary data (linear values or colors are best suitable) to some final data. Any subsystem can pickup the data in the view and affect rendering. As the data is blended per view it means in the splitscreen case you can have different settings blended for each view (e.g. hit indicator affecting post process).

A Blendable is an object that has the IBlendableInterface and currently that is implemented by those asset types:

PostprocessMaterials

PostprocessMaterialInstances

LightPropagationVolumeBlendable (see below)

The Blendables container can be found in the PostProcessSettings which is embedded in the following objects:

PostProcessVolume

PostProcessComponent

SceneCaptureActor

CameraComponent

The LightPropagationVolumeBlendable asset was created to demonstrate on how to create new blendables and to show how we can replace the existing PostProcessSettings. The existing system worked well when it was small but the large amount of settings showed the need for a more sophisticated system.



Blendable assets show up in the content browser in the Blendable category. You can use the Add New or filter asset by this category.

The benefits of the new system:

Easier to extend and maintain with engine changes (no need to change the one central structure, can be in it's own module)

Indirection over packages allows to adjust the content without level access (version control)

Indirection means a single asset can be reused in many occasions (less redundancy, more power)

Custom UI for each blendable is possible (much harder to do with a single struct)

Each Blendable reference can have its own weight, the asset can have a weight (see LightPropagationVolumeBlendable) and a per-property-weight would be easy to do.

Breaking up the large struct make interaction with Blueprints more efficient and simpler.

The Blendables Container

The container is implemented as an array of weights and Blendable Interface references.

When you open the PostProcessVolume setting and look at the blendables array you see an array of weightes with references to a blendable asset. The weights are usually in the 0..1 range and the reference can be to an asset living in a package (created with the content browser) or living in the object that contains the blendables array.



The blendables container can be found in the post process settings (here in a postprocess volume). The array here has three elements, a LightPropagationVolumeBlendable (living in the volume object), a not yet used array element and a reference to a an asset (living an in a package) called LPV0. The weights are 1.0 for both blendables.

When you create new elements in the array you can choose to create a blendable of a specitic type or using an asset reference (e.g. Material, Material Instance). Over time we intend to create more blendable types (e.g. Bloom, SceneColor, DepthOfField, ...). The reference can be of any type that is a Blendable (implements the IBlendableInterface). The order in the array is opposite to how layers stack because their blending is applied from top to bottom and blending is overwriting the data that was there before. Keep in mind the data of many volumes (or other objects) are getting combined taking weight and priority into account.

Note: It's a good practice to have a unbound PostProcessVolume with lower priority in the level called "global". To get get full control over an existing level you can add an unbound volume with high priority. To check if a blendable has effect you can quickly adjust it's weight to 0 and back.

Blendable in the package, as part of the object (e.g. volume) or dynamically created in the Blueprint

It's your choice but we suggest the package (referencing a named asset in the package) as it allows for easier bulk adjustments later on minimizing version control conflicts. For maximum programability it's possible to create a blendable in a Blueprint. As Blueprints are a form of programming this is simialar to putting settings in a UI or hard coding them in the code. The code method is more involved and makes it harder for others tweaking the settings.



The LightPropagationVolumeBlendable details as they can be seen in the editor. No matter if the blendable was created in the content browser (left) or created in the object (e.g. post process volume) the user interface is similar. It's good practice to give each property a checkbox (weight=0 or weight=1) and give the whole struct a blend weight.

How to create your own Blendable (in C++)

At the moment we suggets to copy the LightPropagationVolumeBlendable plugin. After creating the asset you can pick up the blended data the same way the Light Propagation System is doing that. The method GetSingleFinalDataConst() is used to get the data after it was blended. For best performance you might want to avoid calling this function unneccessarily (too often).

Blueprint

The AddOrUpdateBlendable Blueprint function is exposed where you can find PostProcessSettings. It allows convenient access to the blendables container. You pass in the object that has the Blendables container, the weight and a reference to the blendable. If the reference was already found in the container it simply updates the weight. It doesn't remove container elements as that could confuse other code traversing the container and has implications to the garbage collection. There is no real performance cost a blendable reference of a weight of 0 as removing the element should never be needed.

Here you can see how to reference a blendable asset in the content browser:



The variable 'BlendableVar' of the type LightPropagationVolumeBlendable (Object Reference) is used to reference an LightPropagationVolumeBlendable asset called 'LPV0'.

With the ConstructObjectFromClass Blueprint function you can create a new blendable in the Blueprint. By setting the Outer of the new object to the object that has the blendables container you get the same behavior as if you would created the object in the UI (create the blendable as part of the object).



Here we create an object of the type LightpropagationVolumeBlendable, get the settings and set some members with the SetMembersIn... function.

Note: At the moment you need to manually put the override flag to true (checked checkbox), otherwise the property with the same name would not get picked up.

Future

The context sensitive feature when browsing the function AddOrUpdateBlendable doesn't work yet (workaround: disable the 'context sensitive' checkbox).

We intend to break up all PostprocessSettings into object like the LightPropagationVolumeBlendable so one day the PostProcessSettings can be removed. Old levels can be converted on load without any data loss. In order to avoid a lot of assets spaming the content packages we would create the objects as part of the level.

We want to further polish the Blueprint interaction to make it easier to use.

We could easily expose a Blendable array in the world settings and the project settings.

In order to get more transparency which Blendable are getting applied we should have some debug view showing the weights and asset/object names and types.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Bloom Convolution

Bloom Dirt Mask

Training Streams

Bloom is a real world light phenomena that can greatly add to the perceived realism of a rendered image at a moderate render performance cost. Bloom can be seen by the naked eye when looking at very bright objects that are on a much darker background. Even brighter objects also cause other effects (streaks, lens flares), but those are not covered by the classic bloom

Because our displays (TV, TFT, etc.) usually do not support HDR (high dynamic range), we cannot really render very bright objects. Instead we simulate the effects that happen in the eye (retina subsurface scattering), when light hits the film (film subsurface scattering), or in front of the camera (milky glass filter). The effect might not always be physically correct but it can help to hint the relative brightness of objects or add realism to the LDR (low dynamic range) image that is shown on the screen.



Bloom can be implemented with a single Gaussian blur. For better quality, we combine multiple Gaussian blurs with different radius. For better performance, we do the very wide blurs in much lower resolution. In UE3, we had 3 Gaussian blurs in the resolution 1/4, 1/8, and 1/16. We now have multiple blurs name Blur1 to 5 in the resolution 1/2 (Blur1) to 1/32 (Blur5).

We combine the blurs differently to get more control and higher quality. For best performance, the high resolution blurs (small number) should be small and wide blurs should mostly make use of the low resolution blurs (large number).

Property

Description

Intensity

Scales the color of the whole bloom effect (linear). Possible uses: fade in or out over time, darken.







0.0

1.0

5.0



Threshold

Defines how many luminance units a color needs to have to affect bloom. In addition to the threshold, there is a linear part (one unit wide) where the color only partly affects the bloom. To have all scene colors contributing to the bloom, a volume of -1 needs to be used. Possible uses: tweak for some not real HDR content, dream sequence.







#1#2#3#4#5 Tint

Modifies the brightness and color of each bloom. Using a black color will not make this pass faster but that can be done.

#1#2#3#4#5 Size

The size in percent of the screen width. Is clamped by some number. If you need a larger number, use the next lower resolution blur instead (higher number).











#1

#2

#3

#4

#5



Bloom Convolution

The Bloom Convolution effect enables you to add custom bloom kernel shapes with a texture that represent physically realistic bloom effects whereby the scattering and diffraction of light within the camera or eye that give rise to bloom is modeled by a mathematical convolution of a source image with a kernel image.





In this example, the bloom technique produces a continuum of responses ranging from star-like bursts to diffuse glowing regions.

The kernel represents the response of the optical device to a single point source in the center of the viewing field. Each pixel in the source contributes some of its brightness to neighbors as prescribed by the kernel image. The brighter the source pixel the more visible the bloom it produces. Under the hood this energy conserving scatter is formulated as a convolution operations and accelerated by use of a Fast Fourier Transform (FFT).

Bloom Convolution is designed for use with with in-game or offline cinematics or on high-end hardware, while the Standard bloom should be used for most game applications. In assessing the trade off, the Standard bloom has a significant performance advantage but it is not conservative (it can result in an overall brightening of the image) and it lacks the visual complexity of the Bloom Convolution.

To enable Bloom Convolution, navigate to the Lens section of the Post Process Volume and next to Method use the selection box to choose Convolution.



Property

Description

Convolution Kernel

Use this to select the texture that defines the kernel.



Advanced Properties



Convolution Scale

This indicates the relative size of the Convolution Kernel image in units of the viewport, defaults to 1. Primarily used to decrease the size of the bloom.

Convolution Center

In UV coordinates, defaults to (1/2, 1/2). Ideally the Convolution Kernel image is a perfectly centered response to a brighter source, but generally small tweaks will be required. Offsets here will result in full offsets of the bloom image.

Convolution Boost

Boosts the intensity of select pixels prior to applying the convolution bloom filter. This consists of a minimum value, a maximum value and a multiplier. The brightness delta above the minimum value will be amplified by the multiplier. By default this boost is disabled and should be used with caution.

Convolution Buffer

Implicit buffer region as a fraction of screen size to insure the bloom does not wrap around the image. Increasing this value has adverse performance impact.

Kernel Image Best Practices

The additional realism generated by the image-based convolution is the result of its ability to use a visually interesting, non-symmetric kernel images. When creating your kernel images and setting them up for use with Bloom Convolution, there are a few things that you should keep in mind.

The kernel image should be fully present on the GPU and available at full resolution, otherwise a low resolution version of the kernel may be used and will result in serious degradation of quality. To do this, set the following properties in the Texture Editor for the kernel image:



Mips Gen Setting: No Mipmaps

Never Stream: Enabled

Bloom is a whole image filter, so with Convolution Bloom the hottest part of the image should be the considerably brighter than the rest of the image (.exr format works well for this), otherwise the filter will have a strong blurring effect over the screen.

The system expects the hottest point to be at the center of your kernel image, however, this can be adjusted by using the Convolution Center controls.

A good bloom kernel structure should fill most of the kernel image. If you look at the default kernel image in Photoshop, you'll see that the radial lines that diverge from the center spread out for a considerable amount of the image.





Large changes in the Convolution behavior should be done by changing the kernel image with minor tweaks done using the Bloom Convolution Advanced properties.

Bloom Dirt Mask

The Bloom Dirt Mask effect uses a texture to brighten up the bloom in some defined screen areas. This can be used to create a war camera look, more impressive HDR effect, or camera imperfections.





To enable Bloom Dirt Mask, navigate to the Lens section of the Post Process Volume and enable the option for Dirt Mask Texture. Use the Texture selection to apply the texture for your Dirt Mask.



Property

Description

Dirt Mask Texture

Use the selection box to assign a Texture2D to be used for your Dirt Mask. Keep in mind that this property cannot be blended with other Post Process Volumes.

Dirt Mask Intensity

Scales the color of the bloom dirt mask effect (linear). This property is used to tweak dirt mask brightness.

Dirt Mask Tint Color

Used to darken or color tint the dirt mask texture. This can be used to tweak the dirt mask brightness and color.

Dirt Mask Image Best Practices

When creating your Dirt Mask textures and setting them up for use with Bloom Dirt Mask, there are a few things you should keep in mind.

The texture should be fully present on the GPU and available at the full resolution. To do this, set the following property in the Texture Editor:



Mips Gen Setting: No Mipmaps

Never Stream: Enabled

This Post Process property cannot be blended with other Post Process Volumes in your level.

When constructing your Dirt Mask Texture, keep the following in mind:





Example Dirt Mask Texture used in Vehicle Game.



It is recommended to use a non-power of two image size. This avoids Mip creation and streaming, so these should be set automatically, however, if you use a power of two texture size, you'll need to set these in the Texture Editor properties.

You can use a low-resolution texture as this is usually sufficient to represent dirt or scratches on the camera and these are likely to be out of focus and blurry anyway. If you're getting compression artifacts you can try a higher resolution image.

You can create the texture using Photoshop (or similar image editing software) using Lens blur.

Use chromatic aberration (color fringe), in the texture, to help improve the look of the dirt mask.

Training Streams

Tone Mapping

Academy Color Encoding System (ACES) Filmic Tonemapper

Legacy Tonemapper

Film Settings

Color Correction

Color Correction Properties

Workflow for Good Color Correction

Training Streams

Within the Unreal Engine, the term Color Grading covers the Tone Mapping function (HDR to LDR transformation) that is used with High Dynamic Range (HDR) display output and further the color correction (LDR color to screen color transformation) processing of the image.

Tone Mapping

The purpose of the Tone Mapping function is to map the wide range of high dynamic range (HDR) colors into low dynamic range (LDR) that a display can output. This is the last stage of post processing that is done after the normal rendering during post processing. The process of tone mapping can be thought of as a way to simulate the response that film has to light.

Academy Color Encoding System (ACES) Filmic Tonemapper

The Filmic tonemapper that is used with Unreal Engine matches the industry standard set by the Academy Color Encoding System (ACES) for television and film. This ensures that consistent color is preserved across multiple formats and displays while also as a way to future proof the source material since it will not have to be adjusted for each medium that comes along. The filmic tonemapper also uses the same global tonemapper that was previously used in Unreal Engine, with the exception that there is now a filmic response meaning that the S-curve shape now better simulates film stock for a better overall look.

Two places you'll immediately notice a difference is with Bloom and Exposure Levels.

Emissive values are now physically correct so that as the emissive power increases the color will become lighter, similarly to how colored lights work in the real world. As color gets tone mapped, if the final color is bright enough to start saturating the film / sensor, it will become white.





In this example, the legacy tonemapper is compared to the new filmic tonemapper. With a high enough emissive power, the color will start to become white, unlike the legacy tonemapper where values would just become overly saturated causing areas of the material to lose its detail. With the filmic tonemapper, you can even see that the Bloom in this scene retains its physical correctness as well as it is never overly saturated, thus retaining it's reflective primary color value.

Exposure levels are physically correct so that colors will continue to have shape to them rather than lose detail.



In this example, there are a variety of colors and material types with varying roughness and metalness. The Exposure Bias is also set to 0.





In this comparison, the Exposure Bias has been increased to a value of 3 so really show the response of the Filmic tonemapper compared to the legacy tonemapper implementation. Also, a value of three means that the processed image will be eight times brighter than the default value of 0 shown in the previous example above.

As the exposure level is increased, the difference between the filmic and the legacy tonemapper will become more apparent. The spheres in the filmic example will continue to have shape to their color and shading, even as they appear to look brighter. The sphere using the legacy tonemapper will start to have their colors blend with the shading. The spheres become really bright as a solid color, but you can't necessarily tell that they have a high exposure value, whereas the filmic tonemapper takes this into account. The filmic response looks like a natural camera effect if you were to increase its exposure.

Legacy Tonemapper

With Unreal Engine 4.15, the Filmic tonemapper using the ACES standard is enabled by default. Because of this change, there may be differences in appearance to your existing content. While there is no timeframe in which we plan to remove the legacy tonemapper, it will be deprecated and removed at some point in a future Unreal Engine release.

For comparison, this is the difference in an average scene taken from the Sun Temple example project available on the Epic Games Launcher under the Learn tab.





If you want to maintain the look of the legacy tonemapper for your project, we recommend using a Post Process Volume and setting the following values under the Film section:

Slope: 0.98

Toe: 0.3

Shoulder: 0.22

Black Clip: 0

White Clip: 0.025





Film Settings

In the Film section of the Post Process Volume enables you to tonemap your scene using properties that match the ACES standardized film stock. You can adjust these controls to emulate other types of film stock for your project.

It is recommended that changes to these properties be used project-wide for a specific look and not changed dynamically or on a shot-by-shot basis. Instead, you should use the Color Grading properties for any artistic adjustments.



Slope: This will adjust the steepness of the S-curve used for the tonemapper, where larger values will make the slope steeper (darker) and lower values will make the slope less steep (lighter). Value is in the range of [0.0, 1.0]. [0.0, 1.0].*













Toe: This will adjust the dark color in the tonemapper. Value is in the range of [0.0, 1.0]. [0.0, 1.0].













Shoulder: This will adjust the bright color in the tonemapper. Value is in the range of [0.0, 1.0]













Black Clip: This will set where the crossover happens where black's start to cut off their value. In general, this value should not be adjusted. Value is in the range of [0.0, 1.0]













White Clip: This will set where the crossover happens where white's start to cut off their values. This will appear as a subtle change in most cases. Value is in the range of [0.0, 1.0]













If you'd like to test different tonemapper values in a real-time graph like the ones above, you can use the default UE4 Tonemapper example here.

Color Correction

Color correction, or color grading, is used to alter or enhance the overall color of light in your scene. With the advent of HDR displays, the need to preserve color before it's processed is very important. It ensures that the color will be properly displayed.

In the past, the color correction would have been implemented through Lookup Tables (LUTs), which happens in LDR and on the final color that was output to the monitor in sRGB color space. This presents a problem when working with HDR displays because the LUT is just a snapshot in time of the currently supported display it is being adjusted for and cannot be used to the same effect on an HDR display. To solve these types of issues, the color correction controls do their work in Scene Referred Linear Space, which means all colors are captured before they are tone mapped. This makes it possible to only adjust your colors on one HDR display for any color correction to look correct on all displays the image is being outputted to, whether they are HDR or LDR.

You can learn more about the HDR pipeline and how this works for the benefit of your content in the High Dynamic Range Display Output page.

Color Correction Properties

In the Color Grading section of the Post Process Volume, you'll find the properties that enable you to have the most artistic control over the scene.





RGB

HSV

Under each section, you can use the color wheel to select and drag the color values around. You also can choose between the following modes:

RGB - This will adjust the Red, Green, Blue values.

HSV - This will adjust the Hue and Saturation values.

For more precise control over the slider values, you can hold the Shift key while dragging them.



Property

Description



Temperature



The properties in this section are used to adjust the colors in the scene so that whites appear truly white. This allows for other colors in the scene to be correctly lit under the given lighting in the scene.

Temperature Type

Select a type of temperature calculation to use.

White Balance: Uses the Temperature value to control the virtual camera's White Balance. This is set by default.

Color Temperature: Uses the Temperature value to adjust the color temperature of the scene, which is the inverse of the White Balance operation.

Temp

This will adjust the white balance in relation to the temperature of the light in the scene. When the light temperature and this one match the light will appear white. When a value is used that is higher than the light in the scene it will yield a "warm" or yellow color, and, conversely, if the value is lower, it would yield a "cool" or blue color.

Tint

This will adjust the white balance temperature tint for the scene by adjusting the cyan and magenta color ranges. Ideally, this setting should be used once you've adjusted the white balance Temp property to get accurate colors. Under some light temperatures, the colors may appear to be more yellow or blue. This can be used to balance the resulting color to look more natural.



Global



The properties in this section are a global set of color corrections you can use for your scene.

Saturation

This will adjust the intensity (purity) of the colors (hue) that are being represented. A higher saturation intensity will result in colors appearing more like their purest forms (red, green, blue) and when saturation is lowered colors will appear more gray or washed-out.

Contrast

This will adjust the tonal range of light and dark color values in your scene. Lowering the intensity will remove highlights and lighten the image resulting in a washed-out appearance, whereas a higher intensity will tighten the highlights and darken the overall image.

Gamma

This will adjust the luminance intensity of the image's mid-tones to accurately reproduce colors. Lowering or raising this value will result in the image being washed-out or too dark.

Gain

This will adjust the luminance intensity of the image's whites (highlights) to accurately reproduce colors. Raising or lowering this value will result in the image highlights being washed-out or too dark.

Offset

This will adjust the luminance intensity of the image's blacks (shadows) to accurately reproduce colors. Raising or lowering this value will result in the image shadows being washed-out or too dark.



Shadows



The properties in this section are used to adjust the color correction values for shadows in the scene.

Saturation

This will adjust the intensity (purity) of the colors (hue) that are being represented. A higher saturation intensity will result in colors appearing more like their purest forms (red, green, blue) and when saturation is lowered colors will appear more gray or washed-out.

Contrast

This will adjust the tonal range of light and dark color values in your scene. Lowering the intensity will remove highlights and lighten the image resulting in a washed-out appearance, whereas a higher intensity will tighten the highlights and darken the overall image.

Gamma

This will adjust the luminance intensity of the image to accurately reproduce colors. Raising or lowering this value will result in the image mid-tones being washed-out or too dark.

Gain

This will adjust the luminance intensity of the image's whites (highlights) to accurately reproduce colors. Raising or lowering this value will result in the image highlights being washed-out or too dark.

Offset

This will adjust the luminance intensity of the image's blacks (shadows) to accurately reproduce colors. Raising or lowering this value will result in the image shadows being washed-out or too dark.

Shadows Max

This is a multiplier of the properties that affect the color correction properties that have been adjusted in the Shadows section.



Mid-tones



The properties in this section are used to adjust the color correction values for mid-tones in the scene.

Saturation

This will adjust the intensity (purity) of the colors (hue) that are being represented. A higher saturation intensity will result in colors appearing more like their purest forms (red, green, blue) and when saturation is lowered colors will appear more gray or washed-out.

Contrast

This will adjust the tonal range of light and dark color values in your scene. Lowering the intensity will remove highlights and lighten the image resulting in a washed-out appearance, whereas a higher intensity will tighten the highlights and darken the overall image.

Gamma

This will adjust the luminance intensity of the image to accurately reproduce colors. Raising or lowering this value will result in the image mid-tones being washed-out or too dark.

Gain

This will adjust the luminance intensity of the image's whites (highlights) to accurately reproduce colors. Raising or lowering this value will result in the image highlights being washed-out or too dark.

Offset

This will adjust the luminance intensity of the image's blacks (shadows) to accurately reproduce colors. Raising or lowering this value will result in the image shadows being washed-out or too dark.



Highlights



The properties in this section are used to adjust the color correction values for Highlights in the scene.

Saturation

This will adjust the intensity (purity) of the colors (hue) that are being represented. A higher saturation intensity will result in colors appearing more like their purest forms (red, green, blue) and when saturation is lowered colors will appear more gray or washed-out.

Contrast

This will adjust the tonal range of light and dark color values in your scene. Lowering the intensity will remove highlights and lighten the image resulting in a washed-out appearance, whereas a higher intensity will tighten the highlights and darken the overall image.

Gamma

This will adjust the luminance intensity of the image to accurately reproduce colors. Raising or lowering this value will result in the image mid-tones being washed-out or too dark.

Gain

This will adjust the luminance intensity of the image's whites (highlights) to accurately reproduce colors. Raising or lowering this value will result in the image highlights being washed-out or too dark.

Offset

This will adjust the luminance intensity of the image's blacks (shadows) to accurately reproduce colors. Raising or lowering this value will result in the image shadows being washed-out or too dark.

HighLights Min

This is a multiplier of the properties that affect the color correction properties that have been adjusted in the Highlights section.



Misc



Blue Correction

Correction for artefacts with "electric" blues due to the ACES color space. Bright blue desaturates instead of going violet.

Expand Gamut

Expand bright saturated colors outside the sRGB gamut to fake wide gamut rendering.

Tone Curve Amount

Allows effects of Tone Curve to be reduced. Set Tone Curve Amount and Expand Gamut to 0 to full disable tone curve.

Scene Color Tint

This is a multiplier for color that is a filter color applied to the HDR scene color.

Color Grading LUT Intensity

A scaling factor that controls the effect of the color correction.

Color Grading LUT

The LUT texture to use as a lookup table for color correction.



Click image for full size.



Click image for full size.



Click image for full size.









Workflow for Good Color Correction

These are some good habits that should be used when working with the color grading tools in your Post Process Volume.

The Film controls should be set for a project-wide look. Ideally, these properties should not be adjusted and certainly should not be adjusted dynamically or on a shot-by-shot basis. Use the Color Grading properties for this.

Start by using the Global color correction properties and doing an initial pass on your scene before touching any of the other properties. The majority of your color grading changes should be done with these properties.

You should not try to use the Gain property to adjust exposure for your scene. This should be used for fine tweaks for different colors. Instead use the Exposure Bias in the Lens > Auto-Exposure section.

Use Offset in minor amounts to make your shadowed or darkened areas a little lighter. If you want things to look a little hazy or have more bloom, then you can set a higher value, conversely if your scene is overly hazy or has too much bloom you can lower the value to subtract color from the scene.

Instead of using a Lookup Table (LUT) for coloring the scene, since that happens after tone mapping, you should use the Color Grading properties to get the look you want so that it's consistent on all displays you output to (LDR and HDR). However, it can be a good practice to quickly get a look to set the tone with a LUT and then adjust the color correction to get a similar look.

Training Streams

Enabling HDR Output

Low Dynamic Range (LDR) UI support in HDR

HDR Hardware and Setup Considerations

Notes and Limitations

Reference Material

You can output to High Dynamic Range (HDR) displays to take advantage of features such as higher contrast and wider color gamut! The goal here is to give the displayed images the characteristics that are more like natural light conditions experienced in the "real world". This is part of the move to the Academy Color Encoding System (ACES) standard that is a pipeline to ensure consistent color is preserved across multiple formats and displays, and also as a way to future-proof the source material used without having to adjust it for another medium.





This example is simulated and purely for demonstration purposes only. It is impossible to convey HDR differences on an LDR screen.

With the current implementation, the full processing of the rendered scene is handled through what is known as the ACES Viewing Transform. This process works by using scene-referred and display-referred images.

Scene-referred images maintain the original linear light values of the source materials without limiting the exposure range.

Display-referred is the final image transformed into the color space of the display being used.

By using this pipeline, the original source files do not have to be edited each time they are used with a different display in order to guarantee correct coloring. Instead, the display being output to maps it to the correct color space.

The ACES Viewing Transform works in the following order in the viewing pipeline:

Look Modification Transform (LMT) - This part of the process takes the ACES color-encoded image that has had a creative "look" (color grading and correction) applied to it and then outputs the images rendered with ACES in combination with the Reference Rendering Transform (RRT) and an Output Device Transform (ODT).

Reference Rendering Transform (RRT) - Then, this part takes the scene-referred color values and converts them to display-referred. In this process, it enables the rendered images to not rely on a specific display and, instead, can ensure a larger gamut and dynamic range that is correct for the specific display it's being output to, including ones that have yet to be created.

Output Device Transform (ODT) - Finally, this takes the HDR Data output of the RRT to then match it with the different devices and color spaces they can display. Because of this, each target requires its own ODT to be matched against (eg Rec709, Rec2020, DCI-P3, etc.).

For additional information on the ACES Viewing Transform, you can download the PDF documentation from the ACES GitHub page or follow the links in the Reference Material section of this page.

Enabling HDR Output

You can enable HDR output at runtime by toggling the console variables or by using the GameUserSettings node in Blueprints.



The Game User Settings controls will automatically clamp to the closest available match for the current output device and set all flags accordingly. Alternatively, you can use the following console variables to enable and change the available options for the HDR device and color gamut output needed.

Console Variable

Description

r.AllowHDR

Creates an HDR compatible swap-chain and enable HDR display output on platforms that supports it. Takes values 0 (disabled) and 1 (enabled).

r.HDR.EnableHDROutput

When set to 1, this recreates the swap-chain and enables HDR output.

r.HDR.Display.OutputDevice

This is the device format of the output display

0

sRGB (LDR) (default)

1

Rec709 (LDR)

2

Explicit gamma mapping (LDR)

3

ACES 1000-nit ST-2084 (Dolby PQ) (HDR)

4

ACES 2000-nit ST-2084 (Dolby PQ) (HDR)

5

ACES 1000-nit ScRGB (HDR)

6

ACES 2000-nit ScRGB (HDR)



r.HDR.Display.ColorGamut

This is the color gamut of the output display.

0

Rec709 / sRGB, D65 (default)

1

DCI-P3, D65

2

Rec2020 / BT2020, D65

3

ACES, D60

4

ACEScg, D60



Once you've setup the Blueprint or C++ call for GameUserSettings, you can run any cooked project, use the command line argument -game mode, use Standalone game mode, or Play-in-Editor (PIE) in a new window using exclusive fullscreen (press Alt + Enter or use the command fullscreen from the console window).

Using borderless window or windowed mode will not currently work for HDR output.

Low Dynamic Range (LDR) UI support in HDR

This particular feature is experimental and may change in a future release.

When HDR output has been enabled your User Interface (UI) may not look correct. We've added experimental support for LDR UI composition for this reason. It attempts to match the LDR look as closely as possible, although, it's recommended to boost the UI slightly to avoid looking washed out next to the vibrancy of the main scene.

To do this, you can use the following console variables:

Console Variable

Description

r.HDR.UI.CompositeMode

When set to 1, this enables HDR UI composition, which attempts to preserve LDR visuals and blending.

r.HDR.UI.Level

This adjusts the brightness of the composited UI. It is recommended to use a value of 1.5 or 2.

HDR Hardware and Setup Considerations

With the many different types of displays and TVs that are available, along with console and PC considerations, you may find that you need to use a specific piece of hardware or change a setting to get HDR output to work properly. The following are some things to consider when you're running through your setup process:

Make sure that your system is connected to the HDR display using a high-speed HDMI 2.0 cable so that you can take advantage of the transfers speeds. (HDMI 1.4 may work, but may have issues displaying the content.) Not all HDMI ports may accept HDMI 2.0 and HDR. Refer to your display's manual if you're unsure.

Ensure that the TV port is HDR enabled. Sometimes this may be listed in your TV or display settings as "HDMI Deep Color" or "Enhanced Format." Refer to your display's manual if you're unsure.

With some consoles, like the PS4, you may need to disable the system setting for Enable HDCP for HDR output to work properly.

For some displays, you may need to adjust display settings to get the correct output.

With NVIDIA GPUs, use the NVIDIA Control Panel and adjust the display resolution Output Color Format to use RGB and the Output Color Depth to use 10-bit or 12-bit. Depending on your hardware you may only have certain options available. Refer to your display's manual if you're unsure.



Click image for full size view.

Notes and Limitations

By default, the film-mapping curve is disabled during HDR output due to poor compatibility with LDR controls.

Currently, only paths for 1000-nit and 2000-nit display outputs are implemented.

D3D11 restrictions limit HDR output to exclusive fullscreen support only. With D3D12 support in Windows 10, this can likely be extended to enable individual viewports for HDR Output. The implementation on Mac currently supports this, already.

Reference Material

"ACES." Oscars.org | Academy of Motion Picture Arts and Sciences. N.p., 06 Feb. 2017. Web. 05 June 2017.

"Aces Documentation." Oscars.org | Academy of Motion Picture Arts and Sciences. N.p., 26 Sept. 2016. Web. 05 June 2017.



Using a LUT Texture

Creating Your Own LUT Texture

Additional Notes

A Lookup Table (LUT) can be used to achieve color correction using a Post Process Volume. Instead of using three one-dimensional (1D) lookup tables, a single three-dimensional (3D) Lookup Table is used. This offers more sophisticated color transformation, which can be used for something like desaturation.





Color Neutral LUT

Sepia Toned LUT

A Lookup Table used in Unreal Engine is a 16x16x16 color neutral LUT unwrapped to a 256x16 texture. These examples show a color neutral and a sepia toned one. If you were to apply the neutral LUT, you wouldn't see any changes to a default scene, however, if you used the sepia toned one, you'd get something like this:





Using a LUT Texture

To make use of a LUT, use the following properties to assign the LUT texture to the Post Process Volume you want to use it with and adjust its intensity.

Property

Description

Color Grading LUT Intensity

A scaling factor that controls the effect of the color correction.

Color Grading LUT

The LUT texture to use as a lookup table for color correction.





Click image for full size.







Click image for full size.







Click image for full size.











Creating Your Own LUT Texture

To create your own LUT texture, you'll first need an image editing application (like Photoshop or GIMP) that can make color adjustments to a captured image. For this demonstration, the Sun Temple project available in the Epic Games Launcher via the Learn tab will be used, and Photoshop will be the application of choice for the LUT image editing. Some terms may be specific to Photoshop in this example.

Start by taking at least one screenshot that is representative of your scene that you want to apply color correction too. You can use the Screenshot Tool available in the Editor to capture a high-resolution image of your scene.



Open the screenshot in Photoshop and proceed to add your own Adjustment layers from the Adjustments tab located above the Layers panel on the right. Here you'll find many different icons that represent the various types of changes you can make to your images, such as brightness and contrast, hue, saturation, and many others.





Click image for full size.



From the Adjustments panel, click any of the icons to add a layer to the Layers panel. You can use these to make specific color corrections to the final image. For this example, Vibrance and Brightness/Contrasts have been added and adjusted. Once these are added to your Layers panel, select them from the list to expose their properties, or if these aren't visible, you can right-click and choose Edit Adjustment to expose them.



Any adjustments you make will be visible in the viewport. Adjust the properties of the Adjustment layers until you get the color correction you desire. In the example below, the adjustments for Vibrance and Brightness/Contrast have been adjusted to give the captured screenshot more color saturation and definition for visual appeal.





Now that you've achieved your desired look with the Adjustment layers, you'll need to open a copy of the Neutral Color LUT on its own. The adjustment layers that were created for your screenshot can be dragged onto the neutral color LUT.

If you do not have a Neutral Color LUT available to use, you can use the RGBTable16x1.png image shown in the introduction to this page.

LUT Texture Example - right-click and Save as

With your Screenshot with the adjustment layers and the Neutral Color LUT opened, drag and drop the Adjustment layers from your Screenshot Layers panel onto the Neutral Color LUT image. You should now see them populate in the LUT's Layer panel.

Now, navigate to File > Save As and give your LUT with the color corrections a name.

Import your color corrected LUT into the Editor using the drag and drop method into the Content Browser or by using the Import button that is also available in the Content Browser.



For the best results using your LUT in a Post Process Volume, open the LUT image in the Texture Editor and set the following properties:



Mip Gen Settings: NoMipMaps

Texture Group: Color Lookup Table

Next, in the Post Process Volume, use the Details panel and under the Color Grading > Global section, enable Color Grading LUT and apply your LUT.







Additional Notes

The following are some things you should be aware of when using LUTs in your projects:

Since LUTs happen in Low Dynamic Range (LDR) and on the final image color that was output to the monitor in sRGB space, this means that it's just a snapshot in time for what display support is and will not necessarily look the same on any display its output to, unlike High Dynamic Range (HDR) which is processed so that any color correction happens before tone mapping. For this reason, it is recommended to use the latest Color Grading color correction tools available in Unreal Engine 4.16 and later in place of using LUTs.

LUTs can be a good way to quickly target a particular look for your project on your current display but then you should make final adjustments using the color correction properties found under the Color Grading section of the Post Process Volume to guarantee the look is consistent across different types of displays.

Consistency is lost when using a LUT because any color corrections that have taken place will not work for an HDR display. The color grading properties in the Post Process Volume all operate in what is referred to as Scene Referred Linear Space. It means that the colors are consistent because they happen before tone mapping and before they are transformed into a particular display's color space. For example, if you wanted to output to a tv that uses Rec709 instead of sRGB, the color corrections would not carry over if using a LUT since color correction happens after the image has already been output to the display. For this reason, LUTs are being moved away from as a way of doing color correction image processing.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Depth of Field Types

Implementation

Visualizing Depth of Field

Using Depth of Field in the Editor

Using Cinematic Camera's Debug Focus Plane

Similar to what happens with real-world cameras, Depth of Field (DOF) applies a blur to a scene based on the distance in front of, or behind, a focal point. The effect can be used to draw the viewer's attention to a specific subject of the shot based on depth and adds an aesthetic to make the rendering appear more like a photograph, or film.

Depth of Field Types

There are several methods of performing depth of field effects in Unreal Engine that you can use. These have been broken into two categories:

Cinematic: This method provides a cinematic and filmic look to a depth of field effects. Adjustments for this method align more with common camera options available in photography and cinematography. This option works for Desktop and Console platforms.

Mobile: This method provides optimized and lower-cost DOF options that work for Mobile platforms.

Select from the methods below to learn more about their features:



Setting up and using depth of field on desktop and console platforms.



Setting up and using depth of field on mobile platforms.

Implementation

Depth of Field is broken up into three layers (or region); Near, Far, and Focal Region. Each of these is processed separately and then later composited together to achieve the final image effect. Objects in the Near and Far layers are always fully blurred. They are blended with the non-blurred scene to achieve the final result.



Objects within the Focal Region (Black) use the non-blurred scene layer. This layer can be very narrow—like here, where it is only focused on the character— or very wide, encompassing more of the scene's foreground and background.

Objects in the Near (Green) or Far (Blue) that are outside any transition areas between the Focal Region and the Near or Far regions are fully blended to the blurred layer meaning they are out-of-focus.

Objects within the transition area—like the area to the left of the car—are blended linearly between the non-blurred scene layer (for Near and Far) and their blurred layer based on their position within the transition of the Focal Region.

Visualizing Depth of Field

These layers, including transition regions, can be visualized using the Depth of Field Layers show flag in the Level Viewport under Show > Visualize.





Visualizing the Depth of Field Layers also includes useful information relevant to the DOF method being used, such as values that are currently set or when moving the mouse around the scene, the distance from the camera to the Actor is displayed next to the mouse cursor.



Using Depth of Field in the Editor

Using Depth of Field in Unreal Editor can be done in a few different ways; by placing a Post Process Volume, using a Camera Actor. Each of these has access to DOF properties via the Post Process Volume and Camera. For Cine Camera, there are some additional industry-standard settings for cameras and lenses.

The majority of settings used can be accessed under the Lens tab in the Camera and Depth of Field sections.



Click the image for full size.

When using a Cine Camera Actor, replacing properties that affect depth of field can be found under the Current Camera Settings in the Lens Settings section.



Click the image for full size.

If you're using a Camera or Cine Camera Actor, you can inhabit them using Actor Piloting in the Level Viewport by selecting the Perspective and choosing from one of the placed Cameras in the scene.



Click the image for full size.

The Level Viewport will snap to the camera's view and indicate that you are piloting and viewing what that camera sees.



Any properties that are changed in the Camera or Post Process Volume (if the Camera is within it) will immediately take effect in the viewport.

To achieve similar results as the shot above, the key is to use a low Aperture (F-stop) to get a large Bokeh shape, move the camera or viewport position closer to an object and change the Field of View (FOV) to be lower. Then, adjust the Focus Distance to get some scene content to be out of focus in front and behind the focus plane.

Using Cinematic Camera's Debug Focus Plane

While using the Cine Camera Actor, enable Draw Debug Focus Plane to see where the focus is placed in your level.



Click the image for full size.

When enabled, the focus plane will be drawn at the currently set Manual Focus Distance from the camera. In this case, the character is the focal point where everything is sharp and in focus. Anything in front or behind the focus plane will be out of focus.





Use Debug Focus Plane Color to customize the RGBA color values for the focus plane being drawn. This is helpful in scenes where it may be hard to see the focus plane being drawn.

Cinematic

Focus on the Shot's Subject

Aperture

Focal Length

Focus Distance

Procedural Diaphragm Simulation

Number of Diaphragm Blades

Aperture and Max Aperture

Cinematic DOF Settings

Cinematic Camera

Post Process Volume and Camera Actor

Useful Console Variables for Optimization

Bokeh DOF Method (Legacy)

Adaptive Depth of Field for Bokeh DoF

Bokeh DOF Settings

External Resources

The following depth of field methods provides a cinematic look that closely resembles photography and film for desktop and console platforms using the Deferred Shading renderer and Clustered Forward renderer.

Cinematic

Cinematic DOF closely matches real-world cameras, similarly to Circle and Bokeh DOF, you can see circular-shaped Bokeh (out-of-focus areas) with sharp High Dynamic Range (HDR) content. This method uses a procedural Bokeh simulation that provides dynamic resolution stability and alpha channel support while being faster, scalable, and optimized for projects developing on desktops and consoles.





Focus on the Shot's Subject

The key to achieving an aesthetically pleasing depth of field effect is all in how the subject(s) of the shot is focused. There are three core factors that affect setting up Depth of Field for any given shot:

Decide on the Lens Focal Length to use.

Choose an appropriate Aperture (f-stop number).

Choose a Distance to your Subject(s) from the camera.

Let's break down the elements that make up the camera and scene being captured to understand what's going on when we adjust these settings:



Points in the Scene

Red: Out of Focus

Blue: Perfectly in Focus

Green: Marginally in Focus

Focus Distance to Shot's Subject (1. ii)

Camera Lens

Lens Diaphragm (measured in F-Stop)

Lens Focal Length

Filmback / Image Sensor

Final Image Result

Take note that the rendered image on the right is inverted through the camera lens. Red is part of the background and more out of focus, and Green is part of the foreground and marginally out of focus.

Here we have the multiple points (1) representing objects captured by the camera to a defined Focus Distance (2), in this case, the blue subject. The Aperture (4) defines how blurred objects in the foreground and background will be that are not in focus, and, finally, the Focal Length (5) of the lens controls the field of view, or how zoomed in the image will be.

The Aperture defines how sharp or blurred the foreground and background are based on the diameter of the Diaphragm which is controlled in f-stop.



Camera Lens

Lens Aperture Diaphragm measured in F-stop

This diagram demonstrates the Diaphragm (2) blocking light passing through the Lens (1). The size of the Aperture (or f-stop number) sets how much light passes through the Lens in turn controlling how much the foreground and background are blurred based on the Focus Distance of the shot.

Two elements make up the Aperture; the F-stop number and the Diaphragm.



The Aperture is the diameter of the opening through which light passes. The Aperture is defined by Focal Length divided by an F-stop number.

The Diaphragm is a mechanical structure made up of multiple blades used to block light. It opens and closes based on the supplied F-stop.

The lens Aperture is defined by the diameter of the Diaphragm which decreases as the F-stop number increases controlling how shallow or deep the depth of field effect is. See Focus Distance for a diagram showing this effect.

To demonstrate how the Aperture works, drag the slider to change the F-stop number between 1.4, 2.8, and 5.6. Smaller F-stop numbers create a shallower DOF with more background and foreground blur. Larger F-stops increase the depth of DOF with less blur.

Note that only the F-stop is being changed here, the Focus Distance and Focal Length remain constant at 7m and 75mm, respectively.



Drag the slider to change the Aperture F-stop.

Normally when you would adjust the Aperture settings of a real camera, you'd have to also adjust the Exposure settings at the same time to maintain the same light intensity received by the filmback/image sensor. However, in Unreal Engine this is not a real camera, so adjusting the F-stop and Diaphragm does not control the light intensity.

The Focal Length is the distance from the center of the lens to the Filmback (or image sensor) measured in millimeters (mm).



Camera Lens

Focal Length

To demonstrate how this works, drag the slider to change the Lens Focal Length to be between 50mm, 75mm, and 100mm. Notice how effectively it changes the shot's Field of View (FOV); as the focal length increases, the FOV decreases. You can think of the focal length as being similar to zooming in with a camera, except when doing so, the out-of-focus areas of the shot in the background and foreground are becoming more pronounced. In the example below, you can see this when changing between a focal length of 50mm and 100mm; the shot appears mostly in focus throughout the foreground but when using a 100mm focal length, it's easier to see that the background is more out of focus and the foreground has a minimal amount of blur too.

Note that the diagram and example here are only changing the lens Focal Length; the Focus Distance and F-stop remain constant at 7m and f/2.8, respectively.



The Focus Distance is the distance from the center of the camera lens to the subject of the shot that is put into focus, creating a focal plane. The closer the camera is to the subject, the more the background will end up out-of-focus.



Focal Points in the Scene

Red: Out of Focus

Blue: Perfectly in Focus

Green: Marginally in Focus

Focus Distance to the Subject (1b)

Camera Lens

This diagram demonstrates objects (1) that make up the scene; background, shot subject, and foreground. The distance from the Lens (3) to the focal subject (2) - in this case the blue dot - is the Focus Distance. Areas in the background and foreground are blurred depending on the F-stop used and the Lens Focal Length.

We can visualize the DOF Layers by using the Show dropdown in the Viewport to select Advanced > Depth of Field Layers. In this instance, Green represents the foreground objects, Black is the area where objects are focused, and Blue is part of the background.





To demonstrate how this works, drag the slider to change the Focus Distance between 4m, 7m, and 10m. Adjusting the Focus Distance adjusts the Focal Plane (purple dotted line) in the scene, indicating where the in-focus region of the shot is. The blue reference point in the diagram uses the Character as the focal subject here, so as the camera shifts shot focus (black/gray area above) to different parts of the scene, objects in the foreground and background will shift too. Starting with 4m, the Police car in the foreground is in sharp focus and the character is out of focus in the background. The blue reference in the diagram indicates this with its focal point intersection in front of the filmback. At 7m, the character is completely in focus with background and foreground objects out of focus. At 10m, the construction barriers are in sharp focus and the character and a Police car are out of focus in the foreground. The blue reference in the diagram indicates this since the intersection point extends beyond the filmback. Through all these Focus Distance changes, the DOF effect increases or decreases depending on an object being in the foreground or background.

Note that only the Focus Distance is being changed here; the F-stop and Focal Length remain constant at f/1.4 and 75mm, respectively.



Procedural Diaphragm Simulation

The job of Depth of Field is to apply focal importance to a subject(s) in your scene. Just as importantly, out-of-focus areas can be as important. Unreal Engine 4's depth of field simulates the lens diaphragm by enabling you to aesthetically control the shape of the Bokeh (out-of-focus areas) by adjusting the number and curvature of diaphragm blades.



For performance reasons, the diaphragm simulation is only supported on Engine Scalability settings of Epic and Cinematic. Lower quality settings will fall back to circle Bokeh shapes of equal area to ensure similar behavior with auto exposure functionality, in turn disabling the diaphragm blade simulation.

The Diaphragm (or Iris) is a mechanism made up of blades that can adjust to aesthetically inform the look of Bokeh shapes. Using a lower number of blades will result in a polygon-shaped diaphragm whereas a higher number of blades improves the curvature of the diaphragm to appear more natural with rounded out-of-focus Bokeh.



The number of diaphragm blades directly influences the shape of the Bokeh when the Maximum Aperture is increased (minimum F-stop number is decreased).



The Aperture is the opening of the lens controlled by the diameter of the Diaphragm which is measured in F-stops. The amount of light allowed to pass through the lens is controlled by the size of the aperture. Adjusting the size of the aperture sets the focal plane to adjust how in-focus or out-of-focus areas outside of the focal region are.

The following chart shows the correlation between aperture size (f-stop number), max aperture (min f-stop number), and depth of field effects.



A larger aperture (lower f-stop number) has a shallow focal region, causing the foreground and background to become more out-of-focus. A small aperture (higher f-stop number) has a deeper focal region that includes more objects in focus in the foreground and background.

Aperture F-stops: 1.4, 2.0, 2.8, 4.0, 5.6, 8.0



While the Aperture can be as small as you'd like, it can only ever be as large as the maximum size of the lens. The Maximum Aperture (measured in f-stop) defines how large the lens can be. This also defines the curvature of the blades that make up the diaphragm by limiting the size that the aperture can open; limiting the size of the aperture shortens the effective focal region which limits how out-of-focus areas can be.

5 Diaphragm Blades with Different Max Aperture Values



In this example, the Number of Diaphragm Blades is set to 5. With a smaller Aperture, the blades of the diaphragm become more visible in the Bokeh shapes. Using a larger Aperture (f-stop is equal to minimal f-stop) the Bokeh shapes will begin to become circular.

In this example, a Cine Camera Actor is being used with the following values:

Min F-Stop: 1.4

Max F-Stop: 4.0

Diaphragm Blade Count: 5

Current Aperture: 1.4 - 4.0

With these values, the F-stop can only accept values between 1.4 and 4.0. As the depth of field effect is deepened with a larger F-stop (smaller aperture), the diaphragm blades become more visible in the Bokeh shapes.

Keep in mind that the aperture is not controlling the light intensity. This choice has been made so that you don't have to continually adjust the exposure at the same time as with a real camera.

Cinematic DOF Settings

The following settings are specific to the Cinematic Camera Actor. Note that you have access to the Camera and Depth of Field settings as well.

Property

Description



Filmback



Sensor Width

Sets the horizontal size of the filmback or digital sensor (measured in millimeters (mm)).

Sensor Height

Sets the vertical size of the filmback or digital sensor (measured in millimeters (mm)).

Sensor Aspect Ratio

Read-Only. Computed from Sensor dimensions.



Lens Settings



Min Focal Length

Sets the minimum focal length for the lens (measured in millimeters (mm)).

Max Focal Length

Sets the maximum focal length for the lens (measured in millimeters (mm)).

Min FStop

The maximum aperture for this lens. For example, 2.8 for an f/2.8 lens. This will also define the curvature of the blades of the diaphragm.

Max FStop

The minimum aperture for this lens. For example, 8.0 for an f/8.0 lens.

Diaphragm Blade Count

The number of blades that make up the diaphragm mechanism.



Focus Settings



Focus Method

Select the camera focus method to use:

None: Disables DOF entirely.

Manual: Allows for specifying or animating exact focus distances.

Tracking: Locks focus on a specific object in the shot.

Manual Focus Distance

Set the manually-controlled focus distance. This is only available when the Focus Method is set to Manual.

Draw Debug Focus Plane

Enable to draw a translucent plane at the current focus depth. This enables a visual way to track where the focus is for the shot.

Debug Focus Plane Color

When this setting is enabled, it sets a color for Draw Debug Focus Plane.

Smooth Focus Changes

Enable this to use interpolation to smooth out changes in focus distance. When disabled, the focus changes will be instantaneous.

Focus Smoothing Interp Speed

Controls the interpolation speed when smoothing focus distance changes. This option is ignored if Smooth Focus Changes is not enabled.

Focus Offset

This adds offset to focus depth which can be used to manually tweak focus if the chosen focus method needs adjustment.

Current Focal Length

Controls the current focal length of the camera which controls the field of view (FOV) and zoom.

Current Aperture

Sets the current aperture size based on an f-stop number. Note that this setting only accepts values that are within the Min FStop and Max FStop range.

Current Focal Distance

Displays a read-only value that is used by the Focus Settings.

Current Horizontal FOV

Displays a read-only value that is used by Current Focal Length and Filmback Settings.

The following settings are available with the Cine Camera Actor, Camera, and Post Process Volumes.

Property

Description



Camera Settings



Shutter Speed (1/s)

The camera shutter in seconds.

ISO

The camera sensor sensivity.

Aperture (F-stop)

Defines the opening of the camera lens. The aperture is 1/f-stop with a typical lens going down to f/1.2 (larger opening). Larger numbers will reduce the DOF effect.

Maximum Aperture (minimum f-stop)

Defines the maximum opening of the camera lens to control the curvature of the diaphragm. Set this to 0 to get straight blades.

Number of Diaphragm Blades

Defines the number of blades of the diaphragm within the lens. Values between 4 and 16 can be used.



Depth of Field Settings



Focal Distance

The distance in which the depth of field effect should be sharp. This value is measured in Unreal Units (cm).

Depth Blur km for 50%

Defines the distance at which the pixel is blurred with a radius half of the Depth blur Radius. This is particularly useful to emulate cheap atmospheric scattering.

Depth Blur Radius

Radius in pixels at 1080p resolution to apply according to distance from the camera to emulate atmospheric scattering.

Useful Console Variables for Optimization

The challenge of DOF is that it can vary depending on your content and how much importance has been given to the artistic direction of your game with DOF. With that in mind, the DOF implementation offers a variety of console variables ready to be customized per platform for developers to better control the performance budget allocated.

Below are some console variables that can be useful for binding Cinematic DOF performance.

r.DOF.Kernel.MaxBackgroundRadius: The maximum size of the background blurring radius in horizontal screen space.

r.DOF.Kernel.MaxForegroundRadius: The maximum size of the foreground blurring radius in horizontal screen space.

r.DOF.Scatter.MaxSpriteRatio: The maximum ratio of scattered pixel quads as sprites. Useful to control DOFs scattering upper bound.

Note that these are a good starting point and additional console variables can be found under r.DOF..

Bokeh DOF Method (Legacy)

As of Unreal Engine 4.23, Bokeh DOF has been removed from Unreal Engine and the source code. If using 4.22 and 4.21, Bokeh DOF has been deprecated for the Deferred Desktop Renderer and the Forward Rendering path.

Bokeh DOF refers to the name of the shape that can be seen in photos or movies when objects are out of focus. This method renders a textured quad for each pixel using a user-specified texture to define a shape with which to reproduce the effect of a camera lens.

The implementation only uses half-resolution to perform this intensive effect. It attempts to save render performance in areas where the effect is not noticeable by using Adaptive Depth of Field. Bokeh DOF is more costly than other DOF methods available in Unreal Engine making this a prime candidate for cinematics and showcases where appealing visuals often outweigh any performance concerns in those situations.





Adaptive Depth of Field for Bokeh DoF

Bokeh DOF is rendered at quarter resolution (half resolution in each direction) by default for performance reasons. In most cases, the downsampling is barely noticeable, which is perfectly acceptable; however, in some situations, it can lead to artifacts and unwanted results. Adaptive Depth of Field resolves these types of artifacts where possible.





The characters being blurred in the background appear blocky when using only the downsampled DOF technique. Also, some artifacts appear around the horns of the character in the foreground. Adaptive DOF eliminates these types of artifacts, and the background characters have a much smoother appearance.

Adaptive DOF can be visualized by using the Adaptive Depth of Field to show the flag in the Level Viewport under Show > Visualize. When enabled, an overlay is shown where the downsampled effect is being used (green) and where the full-resolution effect is being used (red). The regular scene color is shown where no blurring is being applied.



In general, you want the Adaptive DOF to display all green. The more red shown by the visualization, the more expensive the scene is to render each frame.





Bokeh DOF Settings

The following settings are available with the Cine Camera, Camera, and Post Process Volumes, located under the Lens tab in the Depth of Field section.

Property

Description

Focal Distance

The distance in which the depth of field effect should be sharp. This value is measured in Unreal Units (cm).

Near Transition Region

The distance in Unreal Units from the focal region on the side nearer to the camera over which the scene transitions from focused to blurred when using Bokeh or Gaussian DOF.

Far Transition Region

The distance in Unreal units from the focal region on the side farthest from the camera over which the scene transitions from focused to blurred when using Bokeh or Gaussian DOF.

Scale

An overall scaling factor for Bokeh-based blurring.

Max Bokeh Size

The maximum size (in percent of the view width) of the blur for the Bokeh-based DOF.

Note that performance scales with the size.

Shape Texture

A texture that defines the shape of the Bokeh when objects get out of focus.

Note that these cannot be blended with other Post Process Volumes.

Occlusion

Controls how much the blurred geometry extends beyond its usual silhouette and its opacity. A value of 0.18 gives a fairly natural occlusion result. A value of 0.4 may be necessary to solve layer color leaking issues. Very small values (less than 0.18) generally result in negating the blur effect, though can work well when objects are very near to the camera.

Color Threshold

Controls the threshold where adaptive DOF switches to using full resolution based on color. Smaller values cause more of the scene to use full-resolution processing.

Size Threshold

Controls the threshold where adaptive DOF switches to using full-resolution based on size. Larger values cause more of the scene to use full-resolution processing.

External Resources

SIGGRAPH 2018 - "A Life of a Bokeh" by Guillaume Abadie (PowerPoint presentation ~150 Mb)

Diaphragm (Optics))

Aperture

F-Number

Understanding Factors that affect Depth of Field

Gaussian

Visualizing Depth of Field

Focal Distance

Available Settings

The following depth of field (DOF) method provides an optimized and low-cost depth of field effect for mobile platforms using the Forward rendering path.

Gaussian

Gaussian depth of field has been removed for use with the Deferred Renderer and Desktop Forward Renderer and only supports mobile platforms. To use this Gaussian DOF while working in Editor on a desktop computer, enable one of the mobile platform previewers using the Mobile Previewer.

The Gaussian depth of field method blurs the scene using a standard Gaussian blur (or smoothing) function. Gaussian DOF blur foreground and background uses a fixed-size Gaussian blur kernel, which is very fast on lower-end hardware, such as mobile. This enables performance to be maintained with lower overhead costs where performance is critical.





Visualizing Depth of Field

These layers, including transition regions, can be visualized using the Depth of Field layers show flag in the Level Viewport under Show > Visualize.





Visualizing the Depth of Field Layers also includes useful information relevant to the DOF method selected by including the properties and their currently set values.



Focal Distance

The Focal Distance represents the focal region and the angle of view that will be captured. A longer focal length has a shallow depth of field causing objects to be more blurred outside of the focal region while shorter focal lengths have a wider depth of field with sharper focus and fewer objects out of focus. The f-stop number can stay the same and changing the lens size adjusts how shallow or wide the depth of field effect is.



Click image for full size.

Once you've set the Focal Distance and the Focal Region, you can use the Near Transition and Far Transition to adjust the distance between the focal region and the fully blurred scene. In addition, you can even adjust the Near Blur Size and the Far Blur Size to further tweak the look of Gaussian DOF.



Gaussian DOF with adjusted values for Near/Far Transition and Blur Size to produce a nice depth of field effect.

In this example, the following values have been set to produce a soft depth of field effect for near and far regions.

Focal Distance: 215

Scale: 2500

Near Transition: 500

Far Transition: 400

Near Blur Size: 2.0

Far Blur Size: 2.5

Available Settings

The Gaussian DOF settings and properties can be found under the Post Process Volume's Details panel in the Lens category under Mobile Depth of Field.

Property

Description

High Quality Gaussian DOF on Mobile

Enables HQ Gaussian on high-end mobile platforms.

Focal Region

Artificial region where all content is in focus starting after DepthOfFieldFocalDistance. This value is measured in Unreal Units (cm).

Near Transition Region

The distance in Unreal Units from the focal region on the side nearer to the camera over which the scene transitions from focused to blurred when using Bokeh or Gaussian DOF.

Far Transition Region

The distance in Unreal units from the focal region on the side farthest from the camera over which the scene transitions from focused to blurred when using Bokeh or Gaussian DOF.

Scale

This blends the DOF in the scene. A value of 0 turns it off.

Near Blur Size

The maximum size (in percent of the view width) of the near blur for Gaussian-based DOF.

Note that performance cost scales with size.

Far Blur Size

The maximum size (in percent of the view width) of the far blur for Gaussian-based DOF.

Note that performance cost scales with size.

Occlusion

The occlusion tweak factor of 1. Using a value of 0.18 gets natural occlusion and a value of 0.4 solves layer color leaking issues.

Sky Distance

Artificial distance to allow the skybox to be in focus (for example, 200000 units), where values less than 0 will disable the feature.

Note that this feature can cost performance.

Vignette Size

Artificial circular mask to (near) blur content outside the radius diameter in percent of the screen width.

It adds performance costs if the mask is used.

Exposure Metering Modes

Histogram and Basic Algorithm

Manual Algorithm

Local Exposure

Key Concepts and Features

Exposure Compensation Curve

Exposure Metering Mask

Exposure Change Speed and Movement

Extend Default Luminance Range for EV100

Pre-Exposure

Mobile Usage

Game Settings

Auto Exposure Histogram Settings

Auto Exposure Basic Settings

Manual Settings

Local Exposure Settings

Editor Viewport Override

Visualization and Debugging

Histogram Chart

Histogram Debug Visualization Mode

The Post Process Volume provides controls for setting up Exposure (more commonly called eye adaptation), which automatically adjusts how bright or darker the scene looks. This effect recreates the experience of human eyes adjusting to different lighting conditions, like when walking from a dimly lit interior to a brightly lit exterior, or the other way around.

Exposure Metering Modes

The engine offers several types of metering modes to choose from when setting up auto exposure in your scenes. These different metering modes provide settings that accurately mimic real-world cameras, giving you control over exposure in your scenes through the post process.



Auto Exposure Histogram mode provides finer control over auto exposure with advanced settings constructed from a 64-bin histogram. This is the default exposure metering mode in Unreal Engine.

Auto Exposure Basic mode provides fewer settings, but is a faster method that computes single values by downsampling exposure.

Manual mode enables the use of Camera settings within the Post Process and Cameras settings to control exposure, rather than using only the settings found in the Exposure category.

Histogram and Basic Algorithm

Auto Exposure Basic and Auto Exposure Histogram metering modes both calculate the overall luminance of the scene, and brighten or darken the scene to an expected value, but they differ in how they calculate scene luminance.

The Auto Exposure Basic algorithm uses the average of the log luminance of the scene to determine the target exposure value.

The Auto Exposure Histogram mode first calculates a histogram of the log luminance scene. Then, the histogram is analyzed to determine the average luminance value.

The Basic and Histogram modes use different algorithms to calculate the average luminance of the scene. However, once the average luminance value is determined, both algorithms treat that luminance as middle gray. In photography, this middle gray point is sometimes referred to as "18% gray" or "18% middle gray," referring to the amount of light that is reflected by a gray card.

Manual Algorithm

The Manual metering mode allows the user to select a single, fixed exposure value that is unaffected by the luminance in the scene. If Apply Physical Camera Exposure is disabled in the post process settings, the exposure value will be linear brightness:

If Apply Physical Camera Exposure is applied, EV100 is calculated as the following formula. Otherwise, it is 0.

Exposure in the following formula defines the relationship between the scene surface luminance (L, which is measured in cd/m2) and pixel brightness (B) before the tonemapper and exposure compensation are applied.

You can verify this formula's result by disabling the tonemapper through the viewport show flags (Show > Post Processing), and inspect the scene brightness using the Pixel Inspector. Also note that the editor EV100 override setting directly sets the EV100 exposure used in this equation.

The Exposure Compensation (also called ExpComp for short) defines an additional scale of 2^ExpComp on top of the exposure computed from the current metering mode, except when using the EV100 editor override.

Local Exposure

Local Exposure is a technique that automatically applies local adjustments to exposure — within artist-controlled parameters — to preserve both highlight and shadow detail on top of the existing global exposure system. This is especially useful for projects with challenging high dynamic range scenes using dynamic lighting, in which applying a single global exposure adjustment is not enough to avoid blown out highlights and completely dark shadows.

Projects using dynamic time-of-day systems can encounter scenes with both under and over exposed areas in the final image, such as indoor scenes with very bright outdoors visible through a door or window, which can be problematic for gameplay. For example, the scene below is an example where there are under and over exposed areas.





Local Exposure helps achieve a more consistent final image when carefully crafted lighting per scene is not feasible, and it should always be set up when using Lumen Global Illumination.

Local Exposure settings are found in the Post Process Volume settings under the Lens > Local Exposure category.



Use the Local Exposure visualization mode to see how it is being applied to the scene. You can enable this visualization in the Level Viewport under the Show > Visualization menu.



Key Concepts and Features

The following key concepts, features, and best practices should be taken into consideration when setting up and working with auto exposure in the levels for your project.

Exposure Compensation Curve

The Exposure Compensation Curve Asset slot provides artists with finer control over exposure compensation in their scenes. The curve asset provides direct control over the X and Y axes. When using the high dynamic range visualization mode HDR (Eye Adaptation), these values can be pulled from the information displayed on the screen.





Post Process Settings

Curve Asset Graph

Add your own curves by using the Content Browser to select the Add New button and navigating to the Miscellaneous category to select a Curve Asset type. In the Pick Curve Class window, select a Curve Float type.

In the Level Viewport with the "HDR (Eye Adaptation)" visualization mode enabled, the X-axis is presented by the Average Scene EV100 value (1) and the Actual (purple) line (1) on the histogram chart. The Y-axis is represented by the Exposure Compensation (Curve) value (2).



The example scene above shows the Average Scene EV100 is 0.548, which translates to the plugged-in value of the X-axis of the Curve Asset (shown below). This also returns the value of 0.864 for the Exposure Compensation (Curve) value.



Click image for full size.

The Exposure Compensation values are split into their own settings and curve values, giving you more precise control over how you adjust them. They also provide an explanation why the exposure compensation is behaving in a specific way by separating these values.

The relevant values are:

Average EV100 is the calculated target EV100 value, and is represented by the target (blue) line in the histogram.

Exposure Compensation (Settings) is the exposure compensation value set in the post process settings.

Exposure Compensation (Curve) is the resulting Y-axis value in a Curve Asset assigned to the Exposure Compensation Curve slot in the post process.

Exposure Compensation (All) is the sum of the settings and curve exposure compensation values resulting in the final exposure compensation value.

Exposure Metering Mask

The Exposure Metering Mask gives artists an optional texture slot to control the influence of auto exposure for the whole screen, where each pixel is weighted in importance by the assigned texture mask. Giving importance to pixels toward the center of the screen rather than along the edges helps stabilize auto exposure (see the example below).





Post Process Settings

Exposure Metering Mask Example Texture

By weighting pixels in the mask toward the center of the screen, bright objects appearing along the edges of the screen have less potential to cause abrupt changes in the expected exposure.





The console command r.EyeAdaptation.Focus was removed from Unreal Engine 4.25 and newer. This command applied weighting values uniformly across the screen, providing similar functionality that is now handled by creating your own metering mask. Also, this command only supported Auto Exposure Basic metering mode, while the exposure metering mask supports both Histogram and Basic metering modes.

Exposure Change Speed and Movement

The rate at which exposure compensation adapts to the current scene is done in logarithmic steps that perceptually move up and down the curve at the same rate of speed. The exposure compensation moves along the curve toward its Target value in f-stops per second.

To handle this perceptual movement, the adaptation algorithm traverses the curve with linear and exponential movement. Using both traversal methods improves two side effects of using only exponential movement:

It reduces jittery behavior from adapting quickly to small fluctuations in luminance.

It makes it possible to create slow transitions from dark to bright areas.

In the example below, the traversal along the curve starts out linearly (2) when far away from the Target exposure value. Once it's closer, the traversal transitions to exponential movement (1) that maintains continuity of the first derivative.



When getting close to the Target exposure value, there is a set transition distance where the curve switches from linear to exponential movement. By default, this transition happens at 1.5 f-stops from the Target value. You can set the transition distance (in f-stops per second) using the command r.EyeAdaptation.ExponentialTransitionDistance.

The Speed Up and Speed Down properties in the post process controls how quickly or slowly the exposure adjusts from the Actual (purple) to the Target (blue) value. These settings let you set a time frame (in f-stops per second) for your eyes to adjust when moving between different luminance ranges, such as moving from a dark environment to a bright one.

When setting these values, consider how long it should take for your eyes to adjust to lighting changes. Use the recommendations below when setting these properties:

The Speed Up parameter should use higher values when mimicking eye adaptation behavior. This allows for quicker transitions when moving from dark areas to brightly lit ones. It also mimics natural eye behavior by contracting the iris, allowing less light into the pupils. Longer transition times keep exposure high, and the image is overly bright.

The Speed Down parameter should use lower values when mimicking eye adaptation behavior. This allows for slower transitions when moving from brightly lit areas to darker ones. It also mimics natural eye behavior by expanding the iris, allowing more light into the pupils. Longer transition times keep exposure low, and the image is overly dark.

Extend Default Luminance Range for EV100

By default, the engine uses pixel luminance (cd/m2) for the Max Brightness and Min Brightness settings found in the Post Process Volume. When attempting to set physically accurate lighting ranges, the default luminance range for auto exposure can be extended to express luminance in EV100 (also called ISO 100). This means that you can use correct lux values for lights in your scene and have them respected by auto exposure without causing the image to be blown out.

You can enable this option from the Project Settings in the Rendering > Default Settings section by placing a check next to Extend default luminance range in Auto Exposure settings.

Enabling this setting changes the default Post Process Volume values for the Min Brightness and Max Brightness, along with the Histogram Log Min and Histogram Log Max names to reflect EV100.





Engine Default Settings

With Extended Luminance Range Enabled

Pre-Exposure

The amount of exposure applied in the shader is called pre-exposure. The previous frames's scene exposure is applied within the shader before writing to the scene color. This enables the engine to remap the range of the scene color around the camera exposure to render the scene within a range similar to one of the final color (after exposure). It reduces the risk of arithmetic overflow for low-precision render target formats when using very bright lights by limiting the render target range required to support HDR lighting values. It also has the effect of increasing the quality of Auto Exposure Basic metering mode when enabled.

Pre-exposure can be enabled in the Project Settings in the Rendering > Default Settings section with Apply Pre-exposure before writing to the scene color.

Mobile Usage

Auto Exposure on mobile devices that support feature level ES3.1 or higher share feature parity with desktop and console platforms. For mobile, memory cost is trivial, and performance cost should be minor depending on your scene.

For any Unreal Engine project which has Mobile HDR enabled in the project settings has Auto Exposure enabled by default. Should it not be, you can set the following:

Enable Mobile HDR in the project settings under the Engine - Rendering - section.

Set the console variable r.Mobile.EyeAdaptation to be 1. This should be enabled by default.

Set the console variable r.EyeAdaptationQuality should be set to a value greater than 0.

Configure these console variables in your BaseScalability.ini configuration file under the [PostProcessQuality] section. When using defined profiles for specific devices, set the console variable sg.PostProcessQuality in the BaseDeviceProfiles.ini. Note that all devices are enabled by default, except Android_Low.

Game Settings

The default auto exposure post processing and Post Process Volumes control the in-game settings for auto exposure. The auto exposure is on by default and is available for the Level Viewport and Asset Editor viewports.

Auto Exposure settings can be accessed from the Lens category under the Exposure dropdown.





Post Process Volume Settings

Asset Editor Preview Scene Settings

The Post Process Settings available in the Level Viewport Details panel and the Asset Editor Preview Scene Settings panel contains the relevant settings needed to adjust auto exposure for your scenes. The selected Metering Mode gives access to different sets of properties within the post process. Each mode sets the luminance computation method to be used for auto exposure.

Choose from the following metering modes:

Auto Exposure Histogram constructs a 64-bin, histogram enabling finer control over auto exposure with advanced settings.

Auto Exposure Basic is a faster method that computes single values by down sampling.

Manual enables the use of Camera post process settings within to control exposure rather than using its Exposure properties.

Auto Exposure Histogram Settings



Property

Description

Exposure Compensation

Logorithmic adjustment for exposure, and is only used if a tonemapper is specified. When set to 0, there will be no adjustment, -1 is two times darker, -2 is four times darker, 1 is two times brighter, and 2 is four times brighter.

Apply Physical Camera Exposure

This toggle only affects Manual metering mode. When enabled, brightness of the scene is affected by the Camera settings (ISO, Shutter Speed, and Aperture). When disabled, the camera uses default values of ISO 100, Aperture 1.0, and Shutter Speed 1.0. Most scenes will be significantly darker when this flag is enabled.

Exposure Compensation Curve

This slot takes a Curve Asset, which is used for finer control over exposure compensation in the scene. The X and Y-axis values in the Curve graph translate to the Average Scene EV100 and Exposure Compensation (Curve) values.

Exposure Metering Mask

Use your own texture mask to meter exposure. Bright spots on the mask will have high influence on auto exposure metering, and dark spots will have low influence.

Min Brightness

The minimum brightness for auto exposure that limits the lower brightness the camera can adapt within. Value must be greater than 0 and should be less than or equal to Max Brightness. A good value should be a positive near 0 and should be adjusted in a dark lighting situation. If this value is too small, the viewport image appears too bright. If too large, the image appears too dark. Actual values depend on the HDR range of the content being used. If Min Brightness is equal to Max Brightness, auto exposure is disabled.

Max Brightness

The maximum brightness for auto exposure that limits the upper brightness the camera can adapt within. Value must be greater than 0 and should be greater than or equal to Min Brightness. A good value should be positive (2 is a good starting point), and should be adjusted in a bright lighting situation. If this value is too small, the viewport image appears too bright. If too large, the image appears too dark. Actual values depend on the HDR range of the content being used. If Max Brightness is equal to Min Brightness, auto exposure is disabled.

Min EV100

Replaces Min Brightness when the project setting Extend default luminance range in Auto Exposure settings is enabled. The minimum brightness limit for auto exposure adaptation, expressed in pixel luminance (cd/m2). Value is typically negative and should be less than or equal to Max EV100. As this value increases, the scene view gets darker. If Min EV100 is equal to Max EV100, auto exposure is disabled.

Max EV100

Replaces Max Brightness when the project setting Extend default luminance range in Auto Exposure settings is enabled. The maximum brightness limit for auto exposure adaptation, expressed in pixel luminance (cd/m2). Value should be positive and should be greater than or equal to Min EV100. As this value decreases, the scene view gets brighter. If Max EV100 is equal to Min EV100, auto exposure is disabled.

Speed Up

The speed at which the adaptation occurs from a dark environment to a bright environment.

Speed Down

The speed at which adaptation occurs from a bright environment to a dark environment.



Advanced



Low Percent

Auto exposure adapts to a value extracted from the luminance histogram of the scene color. The value is defined as having X percent below this brightness. Higher values give bright spots on the screen more priority, but can lead to less stable results. Lower values give the medium and dark values more priority, but might cause burnout of bright spots. Values should be greater than 0 and less than 100. A good starting range is 70 to 80.

High Percent

Auto exposure adapts to a value extracted from the luminance histogram of the scene color. The value is defined as having X percent below this brightness. Higher values give bright spots on the screen more priority, but can lead to less stable results. Lower values give the medium and dark values more priority, but might cause burnout of bright spots. Values should be greater than 0 and less than 100. A good starting range is 80 to 95.

Histogram Log Min

Defines the lower bounds for the brightness range of the generated histogram when using the HDR (Eye Adaptation) visualization mode.

Histogram Log Max

Defines the upper bounds for the brightness range of the generated histogram when using the HDR (Eye Adaptation) visualization mode.

Histogram Min EV100

Replaces Min Brightness when the project setting Extend default luminance range in Auto Exposure settings is enabled. Defines the lower bounds for the brightness range of the generated histogram when using the HDR (Eye Adaptation) visualization mode.

Histogram Min EV100

Replaces Min Brightness when the project setting Extend default luminance range in Auto Exposure settings is enabled. Defines the upper bounds for the brightness range of the generated histogram when using the HDR (Eye Adaptation) visualization mode.

Auto Exposure Basic Settings



Property

Description

Apply Physical Camera Exposure

This toggle only affects Manual metering mode. When enabled, brightness of the scene is affected by the Camera settings (ISO, Shutter Speed, and Aperture). When disabled, the camera uses default values of ISO 100, Aperture 1.0, and Shutter Speed 1.0. Most scenes will be significantly darker when this flag is enabled.

Exposure Compensation

Logarithmic adjustment for exposure, and is only used if a tonemapper is specified. When set to 0, there will be no adjustment, -1 is two times darker, -2 is four times darker, 1 is two times brighter, and 2 is four times brighter.

Exposure Compensation Curve

This slot takes a Curve Asset which is used for finer control over exposure compensation in the scene. The X and Y-axis values in the Curve graph translate to the Average Scene EV100 and Exposure Compensation (Curve) values.

Exposure Metering Mask

Use your own texture mask to meter exposure. Bright spots on the mask will have high influence on auto exposure metering, and dark spots will have low influence.

Min Brightness

The minimum brightness for auto exposure that limits the lower brightness the camera can adapt within. Value must be greater than 0 and should be less than or equal to Max Brightness. A good value should be a positive near 0 and should be adjusted in a dark lighting situation. If this value is too small, the viewport image appears too bright. If too large, the image appears too dark. Actual values depend on the HDR range of the content being used. If Min Brightness is equal to Max Brightness, auto exposure is disabled.

Max Brightness

The maximum brightness for auto exposure that limits the upper brightness the camera can adapt within. Value must be greater than 0 and should be greater than or equal to Min Brightness. A good value should be positive (2 is a good starting point), and should be adjusted in a bright lighting situation. If this value is too small, the viewport image appears too bright. If too large, the image appears too dark. Actual values depend on the HDR range of the content being used. If Max Brightness is equal to Min Brightness, auto exposure is disabled.

Min EV100

Replaces Min Brightness when the project setting Extend default luminance range in Auto Exposure settings is enabled. The minimum brightness for auto exposure adaptation, expressed in pixel luminance (cd/m2). Value is typically negative and should be less than or equal to Max EV100. As this value increases, the scene view gets darker. If Min EV100 is equal to Max EV100, auto exposure is disabled.

Max EV100

Replaces Max Brightness when the project setting Extend default luminance range in Auto Exposure settings is enabled. The maximum brightness for auto exposure adaptation, expressed in pixel luminance (cd/m2). Value is typically positive and should be greater than or equal to Min EV100. As this value decreases, the scene view gets brighter. If Max EV100 is equal to Min EV100, auto exposure is disabled.

Speed Up

The speed at which the adaptation occurs from a dark environment to a bright environment.

Speed Down

The speed at which adaptation occurs from a bright environment to a dark environment.

Manual Settings



Property

Description



Exposure



Exposure Compensation

Logarithmic adjustment for exposure, and is only used if a tonemapper is specified. When set to 0, there will be no adjustment, -1 is two times darker, -2 is four times darker, 1 is two times brighter, and 2 is four times brighter.

Apply Physical Camera Exposure

This toggle only affects Manual metering mode. When enabled, brightness of the scene is affected by the Camera settings (ISO, Shutter Speed, and Aperture). When disabled, the camera uses default values of ISO 100, Aperture 1.0, and Shutter Speed 1.0. Most scenes will be significantly darker when this flag is enabled.

Exposure Metering Mask

Use your own texture mask to meter exposure. Bright spots on the mask will have high influence on auto exposure metering, and dark spots will have low influence.



Camera



Shutter Speed (1/s)

Defines the camera shutter speed in seconds.

ISO

This value represents the camera sensor sensitivity.

Aperture (F-stop)

Defines the size of the opening for the camera lens. Larger values reduce the depth of field (DOF) effect.

Local Exposure Settings



Property

Description

Highlight Contrast Scale

Controls the contrast of highlights. Local exposure decomposes luminance of the frame into a base layer and a detail layer. Contrast of the base layer is reduced based on this value. Good values are usually found between 0.6 and 1.

Shadow Contrast Scale

Controls the contrast of shadows. Local exposure decomposes luminance of the frame into a base layer and a detail layer. Contrast of the base layer is reduced based on this value. Good values are usually found between 0.6 and 1.

Detail Strength

Controls the strength of detail applied to the scene. Local exposure decomposes luminance of the frame into a base layer and a detail layer. Values different than 1 enable local exposure. This value shoul dbe set to 1 in most cases.

Blurred Luminance Blend

Blends between bilateral filtered and blurred luminance as a base layer. Blurred luminance helps preserve image appearance and specular highlights, and reduces ringing. Good values are usually in the range of 0.4 and 0.6.

Blurred Luminance Kernel Size Percent

The percentage of the screen (or kernel size) used to blur frame luminance.

Middle Grey Bias

Logarithmic adjustment for what Local Exposure considers Middle Grey (the tone that is perceptually halfway between black and white). 0 is equal to no adjustment, -1 is twice as dark, -2 is four times as dark, 1 is twice as bright, and 2 is four times as bright.

Editor Viewport Override

Each editor viewport provides an option to override default auto exposure settings or ones set in your Post Process Volume.

Access the exposure override from the View Mode dropdown in the Level Viewport or any Asset Editor viewport and disable the checkbox next to Game Settings or Auto to use the EV100 slider.





Level Viewport Override

Asset Editor Override

Visualization and Debugging

The HDR (Eye Adaptation) visualization mode provides a histogram representation of the exposure values measured in the current scene view along with quick reference to values set in the Post Process Volume and Curve Asset.



A list of exposure and curve values set in the Post Process Volume and Curve Asset.

The focal point meter with NIT (measured in cd/m2) and LUX values.

The histogram chart with set min and max ranges.

Enable this visualization mode using the Level Viewport to select Show > Visualize > HDR (Eye Adaptation).

Histogram Chart

The histogram chart consists of a range of exposure values measured in the current view. Within the chart are colored lines that represent the target, actual, and final exposure values are always adapting to the measured exposure of the current camera view.



The blue line represents the target EV100 exposure for the current view.

This is where the average scene exposure is at in the histogram.

The purple line is the actual EV100 exposure for the current view.

This is the current exposure that exists within this view. The actual exposure value will always be moving toward the target exposure value as it changes with the view.

The white line is the final EV100 exposure value after adjusting the exposure compensation in the post process settings.

This is the actual exposure value in the current view after exposure compensation. The white and purple lines will maintain a distance set by the exposure compensation. In the example above, there is an exposure compensation of 2 where the white and purple lines keep that distance from one another.

In this example scene, if the Exposure Compensation is changed in the Post Process Volume Exposure settings, that value is reflected in the list of exposure settings in the Level Viewport. The difference offset for exposure compensation is reflected in the chart by the separation of the actual exposure (purple) and final exposure (white) lines.

In the chart, the far edges represents the auto exposure adaptation ranges set by Histogram Log Min and Histogram Log Max (or Histogram Min EV100 and Histogram Max EV100 when the project setting Extend default luminance range in Auto Exposure settings is enabled).

Histogram Debug Visualization Mode

This mode provides a visualization of different pixel values to ensure that very bright pixels (like the sun) and very dark pixels (like deep shadows) are not involved in the HDR calculation that is happening for auto exposure.



Red pixels represent anything below the auto exposure adaptation ranges set by Histogram Log Min (or Histogram Min EV100). Blue pixels represent anything above the auto exposure adaptation ranges set by Histogram Log Max (or Histogram Max EV100). These pixel ranges ensures that the values set for Low Percent and High Percent are removing these unwanted pixels from being calculated.

This debug visualization mode requires that the HDR (Eye Adaptation) visualization mode first be enabled.

Enable this visualization mode using the command r.EyeAdaptation.VisualizeDebugType 1.

Configuration

Straight lines

Center Bluriness

References

Configuration

By default, Unreal Engine is using a perspective projection. However this projection model create distortions of the geometry when working with a wide field of view. It is very noticeable for instance here with sphere and a FOV = 120.



Therefore Unreal Engine provides a optional post processing pass that attempt to fix this issue using a Panini

The idea of this post processing is to displaced the rendered pixel at the location where they should using the panini projection instead of the perspective projection. To set up, the only thing you need to do is setting up r.Upscale.Panini.D > 0. This post process effect is done in the Upscaling pass. It means this pass is then going to be used if r.ScreenPercentage != 100 or r.Upscale.Panini.D > 0. For further understanding of this parameter, you can refer directly to the original research paper referenced at the bottom of this page.



r.Upscale.Panini.D > 0 directly emphasizes the effect. However it is not the only parameter. r.Upscale.Panini.S lerp with the paper's hardcompression. And if still some sphere still looks eclipsed in the corners, then this parameter can also be tweaked as well. However, for r.Upscale.Panini.S < 0, start shows unrendered black looking pixels in the corners.



To have more understanding of how this effect works, r.Upscale.ScreenFit can be modified as well. One thing to have in mind is that some of the perspective projected pixels are at the end being not show at the screen near the top and bottom of the screen.



Straight lines

The panini projection brings several guarantees on the lines. Firstly the vertical lines are guaranteed to stay straight for any r.Upscale.Panini.D and r.Upscale.Panini.S. Secondly, the lines going through the center of the screen is guaranteed to stay straight as well for any r.Upscale.Panini.D, but r.Upscale.Panini.S = 0. This mathematical property is therefore ideal in First-Person-Shooter game because the panini projection of a weapon directed towards the center of the screen is going to keep its straight lines going towards the center.



Center Bluriness

One issue of this post processing effect is that a blur phenomena at the center of the screen kicks in as r.Upscale.Panini.D increase. The panini projection has been implemented in the upscale pass especially to take advantage of the sharpening filter to fight against this phenomena. However it can quickly become not enough to fix this issue. Therefore you may need to increase r.ScreenPercentage to help fixing that issue but that is going to have a cost on all your rendering performance because increasing the number of pixels to draw. You may consider choosing a better trade of by then choosing a lower value of r.Upscale.Panini.D on hardware that can't afford an higher screen percentage, and still have this effect by only relying on the upscale pass's sharpening filter.



Another way to use the panini projection is through a Material function outputting a world position offset to be plugged-in into the material's world position offset input pin. This actually what Unreal Tournament uses instead of rendering the weapon at a different FOV to fix the perspective projection

You may want to have a look at it in the UT's github repository.

References

Original article's website.

Original article's direct link.

Post Processing Graph

Using a Post Process Material

Critical Settings for Post Process Materials

Blending Between Different Material Instances

The Material Expression "SceneTexture"

Using GBuffer Properties

CustomDepth

CustomDepth Stencil

Temporal Anti-Aliasing or Why the GBuffer Jitters

UV and ScreenPosition

Filtered texture lookups

Replacing the Tonemapper

Known Issues

FAQ

Post Process Materials enable you to set up materials that can be used with your post process to create visual screen effects for damage, area type effects, or overall look for your game that can only be achieved via Post Process Materials.

In the following sections, you'll learn about setting up Post Process Materials, the available settings you can use, along with some examples of how to setup some of your own Post Process Materials using different buffers, blending between Post Process Materials, and more.

Post Processing Graph

The engine already features complex post processing based on a graph of post processing nodes. The Post Processing Materials can be additionally inserted in some specific position. See Frequently Asked Questions section for r.CompositionGraphDebug to get a dump of the full graph. The graph is actually not only doing post processing but also some parts of the lighting.

Most of the time the graph is automatically creating intermediate render targets. This means if you want to blend with the former color, you need to do the blending in the shader (using the input from PostProcessInput0).

Post Process Materials should be used sparingly and only when you really need them. Whenever possible, such as for color correction or adjustments, bloom, depth of field, and various other effects, you should use the settings inherent to the Post Process Volume, which have been optimized and are more efficient.

Using a Post Process Material

Through post process settings (usually defined with post process volumes or camera settings) it is possible to blend (so called) blendable assets. At the moment, only Materials and Material Instances are blendable assets. The engine provides a few post process materials but with this feature you can create your own custom post processing without any programmer help.

Simply assign one or more post process materials to a post process volume in the Blendables section. First press the + to add new slots, select a material in the Content Browser, and press the left arrow to assign it. The order here is not important and unused slots are simply ignored.



Critical Settings for Post Process Materials

A post processing material needs to specify the material domain post process:



The material should only use Emissive Color to output the new color. Additionally, you can define where during the post processing this pass should be applied and, if there are multiple, in which order they should be processed (Priority):



Blendable Location

Description

Before Tonemapping

All lighting is provided in HDR with scene color when Scene Texture expression's Post Process Input 0 is used. It fixes issues with temporal anti-aliasing (TAA) and GBuffer lookups. For example, issues that can happen when using depth and normals.

After Tonemapping

This option indicates that post processing will take place after tonemapping and color grading has been completed. It is the preferred location for performance since the color is LDR and requires less precision and bandwidth. When this option is selected, the SceneTexture expression's Post Process Inputs 2 and 3 are used to control where Scene Color is in the pipeline. Input 2 applies scene color before tonemapping. Input 3 applies scene color after tonemapping.

Before Translucency

This is even earlier in the pipeline than 'Before Tonemapping' before translucency was combined with the scene color. Note that SeparateTranslucency is composited later than normal translucency.

Replacing the Tonemapper

PostProcessInput0 provides the HDR scene color, PostProcessInput1 has the SeparateTranslucency (Alpha is mask), PostprocessInput2 has the low resolution bloom input.

The typical postprocess input comes from the pass before. That color can be accessed through the SceneTexture material expression when using PostProcessInput0. Using SceneColor might not give you the right results.

Blending Between Different Material Instances

Using A Post Process Material

With postprocess volumes, it is easy to setup soft transitions between multiple postprocess materials. Here we use one volume that is marked unbound and one volume that has larger blend radius (e.g. 1000):





Post Process Set to Unbound

Post Process Bound Volume

Each volume we specify a different material instance of the same material. The color is specified as a material parameter which allows different settings for the two material instances.







Material Instance RED

Material Instance GREEN

Depending on the camera position the setting of one volume is used and blended when within the Blend Radius' range:







Unbound Post Process Volume Material Instance (RED) set to 0.75

Blend Radius of 1000

Post Process Volume Material Instance (GREEN) set to 0.75

With camera movement, you can perceive soft linear transition between the two effects setting.

The following shows a top down view of a level that has how two volumes. The large unbound volume has a red material instance and the small volume has a green material instance specified as blendable. The smaller volume has a higher priority. The material params are getting blended depending on the camera position. The fuzzy borders are defined by the Blend Radius property specified in the volumes and extend the volume shape.

With the correct setup all blending happens as expected.





The difference between the both setup is the default value specified on the material (scalar or vector) parameters. The good setup has values that make the pass appear to not have any effect (e.g. multiply with white or lerp with 0).

In both setup we see this: When the camera is outside the influence of either volume the postprocess pass is not getting rendered (visualize by the grey grid). If we are fully inside either of the volumes we also see the correct blending.

The bad setup : When the camera enters the influence radius we see a hard transition but because is uses the wrongly specified default parameters.

The good setup : The transition of entering the camera the influence radius is well hidden and we see a smooth transition to the volume colors.

All material instances properties are blended, no matter if the property checkbox is checked or not (in that case it blends the property from the parent). This is different from the post processing settings where an unchecked property is not having any effect. This means if you blend a material instance, all properties are getting blended.

The Material Expression "SceneTexture"

You can add the SceneTexture material expression into your material and choose which texture you want to reference in the expression properties:



The node has an optional input and multiple outputs:



The UV input allows you to specify where you want to make a texture lookup (only used for the Color output). The color output is a 4 channel output (actual channel assignment depends on the scene texture id). Size is a 2 component vector with the width and height of the texture. The inverse of that (1/width, 1/height) is available in the InvSize output. It is handy when referencing neighbor samples like in the example below:



The material expression computes the depth difference of the current pixel to a neighbor pixel (e.g. In = 0,1 to return the delta to the pixel below).

Using GBuffer Properties

A GBuffer consists of multiple textures that store material (e.g. subsurface/specular color, roughness, ...) and object attributes (e.g. normal, depth) without lighting to compute shading (how light interacts with a material). In a deferred renderer, we first render the GBuffer and then compute all lighting (deferred) with the GBuffer attributes. If using the deferred shading path (e.g. DirectX 11 or high end OpenGL), we can get access to those buffers during post processing.

Anti-Aliasing generally makes this a bit more difficult as a GBuffer pixel/texel is no longer 1:1 associated with an output pixel (see section below).

CustomDepth

This separate feature enables masking of certain objects by rendering them into another depth buffer (called custom depth buffer). This adds extra draw calls but no more materials. The rendering is fairly cheap as we only output depth. The feature can be activated on the mesh (e.g. Static Mesh Properties / Render Custom Depth):



In this scene, we activated the feature on two objects but without a post processing pass visualizing the content, this feature remains invisible:



Here we can see how a visualization of the Custom Depth looks like:



This is the material we used to visualize it:



CustomDepth Stencil

Custom Depth Stencil is an extension of Custom Depth where you can use a stencil, or cutout, of your rendered object to then do visually interesting things like the example below that enables you to visualize occlude objects, draw object outlines, or only be visible from certain viewing angles. There is a lot of potential with what you can do by having access to the stencil of an Actor in your

Using the following settings to enable and assign a stencil value.



In this scene, Custom Depth is enabled on three objects and a Custom Depth Stencil Value is set for each, but without any post processing pass to visualize the content, this feature remains invisible.



Once you've setup your Post Process Material you will be able to visualize how the Custom Depth Stencil looks, The occluded objects render with a randomly assigned color based on the Custom Depth Stencil Value used.



This is a setup of the Material we used to visualize it:



Click image for full size.

This is by no means, the only way to use Custom Depth Stencil and in this particular Material setup the stencil is being divided so that it uses values between 1 and 255, a mask is being used for any value that is between these values, a random color is being created for these values as well so as the Custom Depth Stencil Value changes so does the color, and finally the mask that is created is being used in a way that only colors the stencil if the object is occluded.

Temporal Anti-Aliasing or Why the GBuffer Jitters

Temporal anti-aliasing is a unique Unreal Engine feature that greatly improves image quality with a very moderate performance cost.

By default, a post process material is inserted in the end of the post processing graph (after tone mapper). This means you get the final LDR color after tone mapping, color grading and after the temporal anti-aliasing was applied. This is the best spot for many simple post processing effects - for performance and ease of use.

Here you can see how we used the custom depth input to visualize a silhouette around specific objects:



Notice that the former image has no anti-aliasing on the silhouette but in motion you also would see the silhouette jittering around 1 pixel. This is because temporal anti-aliasing moves the rendering of the whole scene by a sub pixel each frame. Multiple frames together are getting combined to produce the final anti-aliased image. We can however move the material to an earlier spot in the post processing graph to fix this issue.

This is the result:



We get a stable and anti-aliased image. In motion we might see some artifacts with the temporal anti-aliasing. This feature is using the depth buffer to replace old images. With the border rendered inside the object it works ok but outside the object we would also need to adjust the depth buffer (not done yet, costs extra performance) but ideally this should not be.

UV and ScreenPosition

With post process materials you can look up into screen aligned buffers, but you need to know the right UVs. The ScreenPosition material expression with the mapping option set to ViewportUV outputs the UV with 0,0 at the left top of the viewport and 1,1 at the bottom right. In contrast, using the SceneTextureUV mapping in this material expression might give you different results. This is because the actual texture (more correctly it is a render target) is potentially larger than the viewport. It can be larger in editor because we share this texture for multiple viewports and the largest extent is used for all viewports. Even in game it can be larger in some cases (e.g. SceneCaptureActors might have a smaller viewport, Matinee black borders, Splitscreen, VR, ...). The SceneTextureUV option gives you the UV for this larger texture. If you only need a relative offset (e.g. pixel sized edge detection) you need to scale with the right size. The SceneTexture material expression has outputs for the size and the inverse of the size (efficient and useful for pixel offsets). To test all that, you can use the console variable r.ViewPortTest which allows you to test various viewport configurations.

Filtered texture lookups

The SceneTexture material expression has a checkbox to get [bilinear] filtered lookups. Using this option can results in a slower rendering so it should be only used if needed. Many of the screen space textures do not support filtering (e.g. GBuffer). Not exposing this property allows the engine to compress the data if needed (packing prevents filtering).

Replacing the Tonemapper

It is possible to override the in engine tonemapper with your own one by using the "Replacing the Tonemapper" blendable location. This is a work in progress feature meaning it will likely change and it does not have all the functionality yet.



We started exposing some Post process setting parameters to the tonemapper but that part is likely to change quite a bit. The values are exposed as material parameters and need to have the exact name.

Vector parameter:

Scalar parameter:

In order to get the parameters you need to create a material instance from the post process material.

You still can use your own parameters and get them blended like other post process material settings.

Known Issues

The following issues still need to be fixed:

Material expression SceneTexture

SeparateTranslucency does not work.

Certain lookups do not work in certain passes (e.g. some we might not fix because they would cost too much performance).

MaterialFunction might report an error but it still can be used in a Material with the Post Process domain.

Material

UV in the PostProcesMaterial might not be in 0-1 range (e.g. in editor when reducing viewport size), this aligns with the lookup but makes it hard to implement something like a vignette effect.

The asset thumbnail of a post process material does not look right.

Outputting alpha is not yet supported (should go through Opacity).

The preview material in the material editor does not look right.

There has been a case where a material change was not resulting in a change in the post process. Workaround: restart editor.

The Content Browser should allow easy filtering for post process materials.

Blending

When blending two post process volumes with a blend radius, it is possible to see a non-soft transition. This can be prevented by using an unbound volume with a material instance setting that represents the default.

FAQ

Can I have the "Lighting only mode" texture as input?

No, we do not have this data available as an intermediate step. For this view mode, we generate it by ignoring the material

To make this a fast option, it would require restructuring a large part of the rendering code.

Why a SceneColor lookup shows banding but when using PostProcessInput0, I do not see that?

When SceneColor is used we create a lower quality copy of the scene to allow a lookup into a texture that we currently write to (General case is rendering any mesh where this is not possible). In Post Processing, you should use PostProcessInput0.

How much memory do I pay for a post process?

Memory cost depends on screen resolution. Before tone mapping we use HDR (8bytes per pixel), after we use LDR (4 bytes per pixel).

How can I lower the render cost for post processing?

Measure on the target platform, keep the texture lookup count low, do less math operations and reduce dependent texture lookups, avoid randomized texture lookup (can be slower due to texture cache misses).

How many passes I can use?

Each pass adds to the performance cost. Try to combine passes and activate passes only if needed. General game features e.g. noise could be added to the engine passes for better performance.

How much CPU performance do I pay per post process and for blending?

Blending materials is very cheap. All material instances properties are getting blended and only one post process material pass with those settings gets rendered.

I need to use "Before Tonemapper" to get proper TemporalAA. When I use a color, it is tone mapped and therefore looks different. How can I prevent that?

There is no easy solution. You would need to do an inverse tonemaping operation (expensive). The color also might appear different depending on eye adaptation. You could expose the EyeAdaptation level to the SceneTextures to compensate for that.

How can I get a full dump of the post processing graph?

r.CompositionGraphDebug can log the graph into the console. Example:

Getting Started Optimizing Your Project

Rendering Pipeline Optimization

Configuration Files and Scalability Optimizations

Asset Optimization

Debugging and Profiling Tools

Other Topics

Optimizing a project is not always a straightforward task and getting the maximum performance can be challenging because it can, at times, be where milliseconds matter most.

Getting Started Optimizing Your Project

There are multiple places you can start looking to improve performance by optimizing your project. This can start with improving content creation workflows, performing profiling captures to know where time is being spent to render each frame, and using built-in editor tools.

Unreal Engine already does a lot of heavy-lifting to optimize your project for performance without needing to set up anything. But, that doesn't mean that these built-in systems can't be adjusted to fit your project's needs more closely.

The guide below will help you get started in identifying common performance issues and where to look for them. You'll also learn about some of the tools available in the editor that you can use to optimize and improve performance.



Optimization and development best practices for real-time rendering.

Rendering Pipeline Optimization

The choice of some optimizations can directly affect the rendering pipeline that Unreal Engine uses. They can improve performance for the project in general or may be well-suited for a specific platform you want to develop for.

For example, Unreal Engine offers multiple rendering paths with a Deferred path (default) and a Forward renderer. For platforms like VR and Mobile, the Forward Renderer can improve performance but it does not support all rendering features of the engine.

In other cases, changes to the rendering pipeline can improve performance by rendering at a lower resolution and upscaling rather than rendering at native resolution, all while maintaining the same visual fidelity as the native resolution.



Describes the advantages of using the Forward Shading Renderer.



An overview of using Screen Percentage with Temporal Upsampling.



A method of dynamically adjusting the screen percentage to improve performance.

Configuration Files and Scalability Optimizations

Through console commands and configuration files, you can set properties that scales your project for the type of experience or platform your application is developed for.

Console commands are used to call and set specific properties. These can be used in configuration files and scalability settings to improve quality and performance of the rendered image for development of the project or for the final shipped product. Configuration files can store these callable scalability settings to automatically set them for the project, and they can even be platform-specific.

For example, a configuration file can be set up which has multiple scalability options for a user to select from to make the application run better on lower end hardware, or the configuration file can store presets that are designed for specific platforms to use that best optimize the application to run on it.



A high level overview of the Anti Aliasing options available in Unreal Engine.



A selection of topics for improving performance of ray tracing features in your projects.



A collection of topics to aid with development of projects using hardware ray tracing features.



An overview of Scalability options and considerations for content creators, testers, programmers, and managers.



Scalability options, properties, and console variables.



Console commands specific to displaying game statistics

Asset Optimization

Optimization of assets in your project starts with the workflows you choose when developing the project. Sometimes this can mean creating those assets in ways that work best with Unreal Engine's tools. Other times, the built-in editor tools can do this work for you.

For example, manually creating level of detail (LOD) meshes for every object can be a time-consuming process. Unreal Engine provides its own automatic tool to generate LODs for your meshes. You can even configure the properties for how LODs are generated manually or let it perform the task automatically.

The built-in tools and systems below can help you to improve performance during development of your project.



Overview of Unreal Engine 5's virtualized geometry system to achieve pixel scale detail and high object counts.



An overview of available visibility and occlusion culling methods.



System for loading and unloading textures into and out of memory during gameplay.



An overview of the available virtual texturing methods in Unreal Engine.



Information on the Hierarchical Level of Detail system in Unreal Engine



How To Create and Use LODs.



How to set up LOD's on a per-platform basis.



How To use the Automatic LOD Generation system in UE5.



The Proxy Geometry tool set was developed as a way to increase your Unreal Engine 4 (UE4) projects performance while keeping the visual quality of your project uneffected.

Debugging and Profiling Tools

Unreal Engine provides its own debugging and profiling tools and offers plugins for some external applications. These tools are useful for inspecting and identifying areas to improve performance.

For example, using the visualization modes of the Level Editor can visually identify costs of materials currently being rendered on screen. Profiling tools for the CPU and GPU can capture individual frames and breakdown millisecond cost of what is being rendered. With this type of information, you can see what is taking the longest to render in a single frame. By investigating high-cost line items, it may be possible to optimize those elements further.

The tools below will help you debug and profile elements of your project to look for performance optimization opportunities.



RenderDoc is a standalone open-source graphics debugger that you can use to perform single-frame captures and inspect them.



Profile your project with Unreal Insights



A multi-platform command that dumps intermediary RDG textures and buffers to disk for investigating and debugging rendering issues.

Other Topics



Learn how to fix a GPU driver crash in Windows by editing your registry keys.

Anti-Aliasing Methods

Anti-Aliasing Scalability Settings

Choose an Anti-Aliasing Method

Temporal Super Resolution

Temporal Anti-Aliasing Upsampling

Fast Approximate Anti-Aliasing

Multi-Sample Anti-Aliasing

Anti-Aliasing is the process of removing jagged, or stair-stepped, lines on edges and objects that should otherwise be smooth. There are different methods of anti-aliasing used to reduce these types of visual artifacts. Some are developed for use with specific renderers and platforms, while others are ideal for improving performance and fidelity.





Anti-Aliasing Methods

Many different methods of anti-aliasing have been developed. Unreal Engine provides several methods to choose from depending on the needs and requirements of your project. You can choose between anti-aliasing methods for desktop / console and mobile platforms.

Unreal Engine provides the following methods of anti-aliasing for your projects.

Anti-Aliasing Method

Desktop / Console: Deferred Renderer

Desktop / Console: Forward Renderer

Mobile: Deferred Renderer

Mobile: Forward Renderer

Temporal Super Resolution (TSR)

Y

Y

N

N

Temporal Anti-Aliasing Upsampling (TAAU)

Y

Y

Y

N

Fast Approximate Anti-Aliasing (FXAA)

Y

Y

Y

N

Multi-Sample Anti-Aliasing (MSAA)

N

Y

N

Y

Use the image slider below to switch between no anti-aliasing and the available anti-aliasing methods to compare their result. These are single frame captures that show a static scene. To see the clearest results of anti-aliasing, you should test in a scene where you have different types of assets and materials and where you can freely move around.

IMAGE SEQUENCE NO AA, TSR, TAA, FAA, MSAA

Drag the slider to see the scene when using no anti-aliasing, TSR, TAA, FAA, or MSAA (Forward Renderer).



Anti-Aliasing Scalability Settings

Anti-aliasing settings have their own scalability group in the Engine Scalability Settings to scale GPU costs directly related to the anti-aliasing quality for each of the methods. The scalability group controls the console variables for each of the respective anti-aliasing methods.

You can access the Anti-Aliasing scalability settings from the Settings dropdown menu under Engine Scalability Settings.



You can control the quality by choosing an option between Low**to Cinematic, or use Auto** if you want the editor to test your system and choose the best options. Alternatively, you can adjust the quality of specific features, such as anti-aliasing or shadows.



Each of the Engine Scalability Settings entries corresponds to a set of configurable console variables found in the DefaultScalability.ini file. You can edit these to better fit your project based on the quality settings you want.

Refer to Scalability Settings for more information on setting up and configuring console variables. This is an advanced workflow.

Choose an Anti-Aliasing Method

Open the Project Settings from the main menu under Window. In the Project Settings, anti-aliasing settings are found in the Engine > Rendering settings.

For Desktop / Console platforms, anti-aliasing settings are located under the Default Settings section.



For Mobile platforms, anti-aliasing settings are located under the Mobile section.



Temporal Super Resolution

Temporal Super Resolution (or TSR) is a platform-agnostic temporal upscaler using an algorithm that focuses primarily on investing more GPU cycles of a frame into temporal upscaling quality to save total GPU frame cost. It does this by rendering a significantly lower internal resolution than what Temporal Anti-Aliasing Upsampling in Unreal Engine 4 could do.

TSR provides a native high-quality upsampling technique that meets the demand of next-generation games through the amount of detail and fidelity possible with Nanite micropolygon geometry.

The comparison below demonstrates the quality and performance difference of captured frames rendered at native 4K resolution with 1080p resolution upscale to 4K. TSR makes it possible to achieve image quality near 4K resolution while also reducing GPU frame time by half.





4k frames rendered at native 4K resolution -- frame time: 57.50ms / 4k frames rendered at 1080p resolution (r.ScreenPercentage=50) -- Frame Time 33.37ms

Each of the images in the comparison above are 4K images that are limited to the width of this page. To see their fully uncompressed resolution, right-click on either and save them to your computer, or open them in a new browser window.

Temporal Super Resolution has the following properties:

Rendered frames approach the quality of native 4K with input resolutions as low as 1080p.

Less "ghosting" artifacts against high-frequency backgrounds than were visible with Unreal Engine 4's default Temporal Anti-Aliasing method.

Reduced flickering on geometry with high complexity.

Supports Dynamic Resolution scaling on console platforms.

Runs on any hardware that supports D3D11, D3D12, Vulkan, Metal, PlayStation 5, and Xbox Series S | X.

Shaders are optimized specifically for PlayStation 5 and Xbox Series S | X GPU architectures.

In the rendering chain, TSR happens after depth of field and everything that follows is upscaled.



GPU Cost Scalability

You can use Temporal Super Resolution across supported platforms, but you will want to customize the upscaling settings of each platform based on the needs of your project.

Explore the sections below to learn some of the ways you can go about checking TSR in your project and then scaling it appropriately.

The Engine Scalability Settings scale the quality of TSR across all platforms. They use predefined scalability groups from Low to Cinematic. Each group is defined by a set of console variables that affect anti-aliasing.

You can edit the DefaultScalability.ini to configure scalability settings specifically for your project. You can edit, add, and remove console variables from the different scalability quality groups. You can explore the configurable TSR console variables in the editor by opening the console and searching r.TSR.

An example of an adjustment you may want to make for your project is that TSR includes a spatial anti-aliasing algorithm used whenever the history needs to be rejected to avoid stale data that could introduce error to the current frame. Game projects that still want to render at higher resolution, or frame rate, may not need this option since the aliasing seen may not be subject to rejection.

History rejection for TSR is controlled using the console command r.TSR.RejectionAntiAliasingQuality.

The primary goal of TSR is upscaling. The majority of its GPU work scales based on the resolution it is given.

Open the GPU statistical display from the console using stat GPU. With this open, you can adjust the primary Screen Percentage to see the difference in performance when rendering at 100 percent versus 50% screen percentage, like the examples taken below from the Valley of the Ancients sample project.





~0.79ms at r.ScreenPercentage=100

~0.43ms at r.ScreenPercentage=50

Click image for full size.

Click image for full size.

Cinematic TSR

Temporal Super Resolution includes Cinematic scalability options that sets its resolution to approximately two times larger than the output resolution of when TSR history screen percentage is set to 200.

Automatic View Texture Mip Bias

Screen percentage causes geometry to render at a lower pixel density, which means when temporal upsample requires more texture information from the Surface and Deferred Decal Material Domains to maintain the same output sharpness.

With a Texture Sample node selected in the Material Graph, you can use its Details panel to enable using Automatic View Mip Bias to set whether the texture should be sampled with per-view Mip biasing for sharper output with Temporal Anti-Aliasing methods like TSR and TAAU.



Automatic View Mip Bias can become problematic for textures with lots of small or high-frequency detail when combined with lower primary screen percentages, as sharper detail can be lost. You can compensate by setting MipValueMode to MipBias to apply some value to the Bias input on the Texture Sample or to the Const Mip Value in the Details panel, or you can opt out of Automatic View Mip Bias completely.



Automatic View Mip Bias only happens when either TAAU or TSR is enabled. Other anti-aliasing methods, such as MSAA and FXAA, do not use this setting.

Post Process Materials After TSR

Post Process Materials must select a Blendable Location from where they will be used. The options for After Tonemapping and Replacing the Tonemapper happens after TSR in the rendering chain. This means that they are running at full resolution and are different from the view size.

The View Property Expression includes options for View Size and Render Target Size that returns the resolution of the view before TSR happens in the pipeline, even though it's actually happening after TSR. To know what the view size and the texel UV size are after TSR, use the Scene Texture Expression with PostProcessInput0 with the outputs for Size and InvSize.



If you want to recompute the viewport UV from the pixel position, multiply SceneTexture:PostProcessInput0 by ScreenPosition, like the example below.



Hidden Additional GPU Costs of Temporal Upscaling

Temporal Super Resolution and any other temporal upscaler happens in the middle of the post-processing chain of the renderer. This means that passes, such as Motion Blur or Tonemapper, running after TSR are no longer scaling with the primary Screen Percentage. In the absence of a secondary screen percentage with a spatial upscaler, the primary screen percentage runs exactly at the display resolution rather than rendering resolution.

With TSR enabled by default, a lot of effort is focused on reducing the hidden temporal upscaling costs of passes that happen after TSR.

Motion Blur optimizations combine for 3x motion blur GPU performance cost improvements on PlayStation 5 and Xbox Series X, platforms that always display 2160p backbuffer, even on lower resolution televisions.

Increased TSR costs when using stat gpu:

TSR cost may increase slightly when using stat gpu when comparing Motion Blur enabled and disabled.

When Motion Blur is enabled, TSR takes over its Velocity Flatten pass that normally runs at input resolution. This is controlled using the console command r.MotionBlur.AllowExternalVelocityFlatten and is enabled by default.

TSR outputs half-resolution Scene Color to reduce bottlenecks in memory bandwidth that can occur in large directional blur kernels. This is controlled using the console command r.MotionBlur.HalfResInput and is enabled by default.

Half-resolution on directional blur:

Directional blur happening at display resolution is optimized to automatically run at half-resolution on very large movements. Enabling this feature will reduce VALU cost of motion blur.

Enable this optimization using the console command r.MotionBlur.HalfResGather 1.

Motion Blur Half and Quarter Resolution:

Motion Blur is able to output half or quarter resolution, This is of importance for Guassian and Convolution Bloom, Lens Flare, Eye Adaptation (Auto Exposure), and Local Exposure that all run after Motion Blur.

Supported Platforms

Temporal Super Resolution is available on desktop renderers across all desktop hardware that supports Shader Model 5. Temporal Super Resolution is supported on on the following platforms:

Windows D3D11 SM5, D3D12 SM5, D3D12 SM6, and Vulkan SM5

Linux Vulkan SM5

Mac Metal SM5

PlayStation 5 and Xbox Series S | X

TSR's upscaling quality and behavior is strictly identical across all supported platforms. However, TSR has been specifically optimized for AMD RDNA GPUs used in PlayStation 5 and Xbox Series S | X consoles, taking advantage of 16-bit types and packed instructions.

Temporal Anti-Aliasing Upsampling

Temporal Anti-Aliasing Upsampling (or TAAU) samples different locations within each frame and uses past frames to blend samples together to remove and smooth jagged edges.





The quality of TAAU is controlled using the console variable r.TemporalAA.Quality. You can choose from the following values:

0: Disables input filtering.

1: Enables input filtering.

2: Enables input filtering with mobility-based anti-ghosting (default)

You can use the Engine Scalability Settings to change the quality of anti-aliasing.

In the rendering chain, TAAU uses the Temporal Upscaler configuration with Screen Percentage by default.



Disabling Temporal Upsampling

To simplify the process of migrating projects from Unreal Engine 4 to Unreal Engine 5, Temporal Upsampling can be disabled to use the Spatial Upscaler for primary Screen Percentage.

To do so, in the UE5 Project Settings under Engine > Rendering > Default Settings, disable the Temporal Upsampling setting.



When disabling the setting, the rendering chain for Temporal Anti-Aliasing will look like this:



TAAU-Specific Shader Permutations for Screen Percentage

TAAU includes its own shader permutation for primary Screen Percentage ranges:

50 - 70 renders faster because it uses a smaller LDS tile in memory.

71 - 100 is useful for "normal" DPI rendering on desktop and base consoles.

You can set the primary Screen Percentage in the Level Editor Viewport Options dropdown menu.



Fast Approximate Anti-Aliasing

Fast Approximate Anti-Aliasing (or FXAA) is a spatial-only anti-aliasing technique that is a post-processing effect that uses a high contrast filter to find edges and smooth them by blending (dithering) between the pixel edges. As the name suggests for this technique, it is fast to render and well-suited for low-end devices and desktops.

While this technique is fast to render, the final image can lose fidelity when compared to other anti-aliasing techniques.





The dithering quality of FXAA is controlled using the console variable r.FXAA.Quality. You can set how many samples are used for dithering to remove jagged edges. More samples equals higher fidelity but at increased GPU cost.

Choose from the following:

0: Console

1: PC Medium dithering using 3 samples

2: PC Medium dithering using 5 samples

3: PC Medium dithering using 8 samples

4: PC Low dithering using 12 samples (Default)

5: PC Extreme dithering using 12 samples.

You can also use the Engine Scalability Settings to change the quality of anti-aliasing.

In the spatial and temporal upsampling chain, the Spatial Upscaler happens at the end of the post processing chain for the primary Screen Percentage.



Multi-Sample Anti-Aliasing

This anti-aliasing technique is only available on Mobile and Desktop / Console when using the Forward Renderer.

Multi-Sample Anti-Aliasing (or MSAA) is a technique that only smooths parts of the frame. MSAA primarily looks at areas that are issue-prone, like the edges of geometry. Where aliasing problems can occur on edges, MSAA manipulates their color to be between the color of the two pixels that make up the edge. The dithering effect gives the illusion of smoother edges.





The quality of MSAA is dependent on the number of samples it uses to blend colors along edges that it determines to have aliasing. More samples equal better visual quality, but at the cost of higher GPU processing.

You can set the number of samples MSAA uses in the Project Settings under the Engine > Rendering > Default Settings with the MSAA Sample Count setting. This setting controls the sample count for desktop / console and mobile. Alternatively, you can use the console variable r.MSAA.Quality to set the quality.



Choose between 2, 4, and 8 samples.

Drag the slider to increase the number of samples that Multi-Sample Anti-Aliasing uses.



Unlike other anti-aliasing techniques, MSAA is not controlled by the Engine Scalability Settings and must be set using the console variable or its project setting.

In the rendering chain, MSAA primarily resolves geometry aliasing along edges before the Spatial Upscaler. Aliasing from materials, textures, and transparent surfaces are not affected by MSAA.



Enabling Dynamic Resolution

Enabling Dynamic Resolution At Runtime

Controlling Dynamic Resolution With Operation Mode

Pausing and Resuming Dynamic Resolution

Using Stats for Dynamic Resolution

Stat Unit

Stat UnitGraph and Stat Raw

Dynamic Resolution Cruising

Over Budget Panic

Testing Content with different Primary Screen Percentages

Supported Platforms for Dynamic Resolution

Replacing Dynamic Resolution Heuristic in C++

Limitations of Dynamic Resolution

Frequently Asked Questions



Dynamic Resolution adjusts the primary screen percentage according to the previous frames' GPU workload. The resolution adjusts (as needed) based on a heuristic, for example, when there are too many objects on the screen, or if there is an expensive effect that suddenly enters the frame. The GPU rendering time will increase, and the resolution of the screen will be lowered to maintain the targeted frame rate.

Enabling Dynamic Resolution

Enabling Dynamic Resolution At Runtime

Dynamic Resolution can be enabled by getting a boolean on the Game User Settings node. It can be set when using either Blueprint or C++.

In Blueprint, enable dynamic resolution by using the Game User Settings node to opt into the feature like so:



In C++, the boolean value can be set in UGameUserSettings like so:

Use false for SetEnabled to disable it.

Game thread logic has the final programmatic control over when to actually enable or disable dynamic resolution, so if it's enabled at runtime using Blueprint that will take precedent over setting it in code. To restore game user settings to its original state, use the following:

Controlling Dynamic Resolution With Operation Mode

You can use Operation Mode to set how Dynamic Resolution can be overridden and used in your game. To control this, in your project's per-platform configuration profile (or device profile) for your platform (Xbox One, PlayStation 4, etc), you can use the following console command:

Use one of the following values to set how the Operation Mode works for your project's platform:

1 enables Dynamic Resolution based on the Game User Settings state (set in C++ or in Blueprint).

2 enables Dynamic Resolution regardless of the Game User Settings state.

After enabling Dynamic Resolution, the following console variables set the minimum and maximum screen percentages, and the maximum budget of any given frame before it lowers the resolution. There are default values that are in place until you do set them:

Console Variable

Default Value

Description

r.DynamicRes.MinScreenPercentage

50

Sets the minimum screen percentage to use.

r.DynamicRes.MaxScreenPercentage

100

Sets the maximum primary screen percentage that is used to allocate render targets.

r.DynamicRes.FrameTimeBudget

33.3

Sets the budget of the frame (in milliseconds).

You can use the Device Profiles window in Unreal Engine to set up the configuration files and manage them for you. You can access this window through the file menu by selecting Edit > Developer Tools > Device Profiles.

Pausing and Resuming Dynamic Resolution

At times, you may need dynamic resolution enabled for project but not in areas like the main lobby. Dynamic resolution can be paused and resumed alongside Operation Mode. The following console variable can be used to set the Operation Mode of Dynamic Resolution:

Value

Description

0

Disabled (Default)

1

Enabled based on the setting used in GameUserSettings.

2

Enabled regardless of the setting used by GameUserSettings.

The table below outlines the different states that are available when a specific operation mode is enabled or disabled and how GameUserSettings is affected:

Game User Settings = False

Game User Settings = True







Paused





Not Paused





Paused





Not Paused



OperationMode=0

No

No

No

No

OperationMode=1

No

No

No

Yes

OperationMode=2

No

Yes

No

Yes

In C++, you can use the following functions to control and check the status of dynamic resolution:

Action

C++ Function

Pause

GEngine->PauseDynamicResolution();

Resume

GEngine->ResumeDynamicResolution();

Check Status (Disabled/Enabled or Paused)

GEngine->GetDynamicResolutionStatus();

In Blueprint, the functionality provided by the C++ functions in this table for Pause and Resume can be achieved by enabling or disabling the node Set Dynamic Resolution Enabled. To check the status, use the node Is Dynamic Resolution Enabled.

Using Stats for Dynamic Resolution

There are several stat screens that you can enable to debug performance with Dynamic Resolution. You can enable them by opening the console using the backtick ( ` ) key and entering one of the following commands:

Stat Unit is used to look at the overall frame time as well as the game thread, rendering thread, and GPU times.

Stat UnitGraph is used to see a graph with the Stat Unit data.

Stat Raw outputs unfiltered data using Stat UnitGraph.

Stat Unit

When Stat Unit is called, you can immediately see if dynamic resolution is enabled for your scene by referencing the DynRes line.



Once enabled, DynRes label will show the Primary Screen Percentage and the Secondary Screen Percentage :



The primary screen percentage is displayed here for the X and Y so that you don't forget that it is scaled on both axes. The number of pixels drawn by the GPU is actually proportional to Screen Percentage x Screen Percentage.

An example would be 1920x1080 or 1280x720.

Stat UnitGraph and Stat Raw

When Stat UnitGraph is called, a graph will be drawn to show the Primary Screen Percentage chosen by dynamic resolution.



Timings (Filtered or Raw)

Target Frame Time Threshold

Dynamic Resolution Max Screen Percentage

Dynamic Primary Screen Percentage Curve

The UnitGraph can show the primary screen percentage that is chosen by Dynamic Resolution. However, that curve is proportional to the amount of pixels drawn by the GPU using Screen Percentage x Screen Percentage.

Additionally, you can get unfiltered (raw) timings in the UnitGraph by using Stat Raw to toggle between filtered and unfiltered. The timings label of the graph will change to indicate that it's displaying raw timings.



Raw Timings



Filtered Timings

Toggle between filtered and unfiltered timings by using the console window. Before Stat Raw can toggled, Stat UnitGraph must first be entered.

Dynamic Resolution Cruising

The implementation of Dynamic Resolution in Unreal Engine is a little different than others that have been used before because we allow for the resolution to change as needed within a given range rather than being constrained to a single resolution (1080p, 900p, 720p). In this example graph, this model demonstrates what the console variables control. It demonstrates how dynamic resolution automatically adjusts within a given range (3) when everything is running fine and not over budget for the given frame. Think of this range as the cruising altitude for an airplane where it can move freely around this altitude range for an ideal speed to get to its destination. Like the airplane, the resolution does the same thing by going up and down as need to maintain a good balance of resolution and adequate performance.

This model is for demonstration and doesn't consider everything that is happening in a given scene. For example, it does not capture what the GPU not being synced with the CPU would look like, or even that the heuristic is making the right guess of how much to change the resolution. It's purpose is to clearly demonstrate the "ideal" circumstances to show how the dynamic resolution console variables operate.



Reference Number

Console Variable

Description

1

r.DynamicRes.FrameTimeBudget

The frame's time budget measured in milliseconds (ms).

2

r.DynamicRes.TargetedGPUHeadRoom

The headroom left for the GPU to increase before going over budget (in percentages of the frame's budget). This will likely depend on the shipping platform or according to what rendering features are enabled. For example, motion blur needs additional room for cost to account for fast rotation of camera movements.

3

r.DynamicRes.ChangePercentageThreshold

The minimal changes that are required in percentage to actually resize the allocation. It is useful to not constantly change between a very close resolution size. If the value is too small, it may end up constantly changing the resolution, and if it's too large, it may cause a higher risk to go over the GPU budget.

4

r.DynamicRes.MinResolutionChangePeriod

The minimum number of frames before any resolution changes are allowed. This command has multiple purposes. These include having a better reliability of the heuristic to model the GPU consumption at a given primary screen percentage despite the measurements noise, being able to avoid Temporal Upsample's input sample offset interference that can occur between per-frame offset jittering, and the changing resolution that can be responsible for anti-aliasing divergence.

You can also use the following console variables to adjust the history of the heuristic used for dynamic resolution and a screen percentage to use if you're CPU bound instead of GPU bound:

Console Variable

Description

r.DynamicRes.HistorySize

The number of frames in the heuristic frame history. If it's too short, the history may be too noisy for the heuristic to be reliable, or if it's too long there may be very delayed adjustments.

r.DynamicRes.CPUBoundScreenPercentage

The primary screen percentage that should be targeted when you are bound by the CPU. It's useful to set a lower screen percentage to decrease the resolution on platforms where the CPU and GPU are sharing the same memory bandwidth.

Over Budget Panic

If you find that dynamic resolution is going over budget very quickly, like during a camera cut or when an expensive visual effect happens, the heuristic that is used can't actually predict when this will happen. In these cases, a "panic" switch is used to quickly lower the resolution when it does happen to reduce the number of frames that are over budget. If the heuristic finds that N (some number) consecutive frames with the available GPU timings is over budget, it is going to immediately adapt the resolution to combat these over budget timings. It will also perform an automatic history reset so that the previously less expensive frame timings do not influence the heuristic for the more expensive frames.

Use the following console command to control the maximum number of consecutive frames the GPU can be over budget before flipping the "panic" switch to lower the resolution:

In this graph, the frame receives a sudden jump that puts it over the set budget of 33.3 ms for more than two frames consecutively. The panic switch is activated to quickly lower the resolution so that the frame is no longer over budget.



Max Consecutive GPU Frames that are over budget.

The frame latency between detection and resolution change caused by the GPU being not synchronized with the render thread.

Panic detection happens to trigger the drop in frames.

The resolution change occurs for the given frames.

In the following captures (taken from the Infiltrator demo that is available on the Learn tab of the Epic Games Launcher), the Stat Raw command is used to clearly identify scene behavior when there is a camera cut or when an expensive visual effect happens on the screen:



Click image for full size.

After the camera cut, the frame becomes significantly more expensive to render, at least for a few frames.

Dynamic resolution has a panic reaction and quickly lowers the resolution to compensate before gradually rising back to normal again.



Click image for full size.

A visual effect happens that is more expensive to render causing a spike that is the allotted frame budget for more than a couple of frames.

Dynamic resolution acts quickly by lowering the resolution before gradually rising back to normal again.

Testing Content with different Primary Screen Percentages

If your project has enabled dynamic resolution, you'll need to test it and make sure that it doesn't look significantly different than intended when using a lower primary screen percentage. At lower resolutions, some details can be lost and your assets may not retain the look that you intend them to have. For this very reason, all Editor Viewport can set a Screen Percentage using a slider for testing.



Click image for full size.

Use the slider to apply a higher or lower screen percentage to the viewport and check your level content accordingly. Artists, particularly, should use the slider to check their content at the high and low ranges of the screen percentages that will be used for the project.





When adjusting the screen percentage slider, the viewport (lower-right) will display any value for Screen Percentage that is higher than 100. This is meant as a reminder that the viewport screen percentage value has been changed to one that is not default and can potentially cause performance issues since it's using a higher than normal resolution.



Screen Percentage values higher than the default value can cause sluggishness or a decrease in performance for the Editor. When this happens, try resetting the value to the default of 100.

Supported Platforms for Dynamic Resolution

The following platforms are supported

Microsoft's Xbox One, Xbox Series S, and Xbox Series X

PlayStation 4 and PlayStation 5 (excluding PSVR)

Nintendo Switch

Oculus VR

Additional platform support is planned for future Engine releases.

Enabling dynamic resolution for non-whitlisted platforms is dangerous and can have unintended consequences. This could include having the wrong GPU timings which could unnecessarily drop the resolution or increase the resolution too much and drop frames. Ultimately, it could ruin the gameplay experience. By default, the Engine does not allow you to use non-whitelisted platforms.

Replacing Dynamic Resolution Heuristic in C++

The engine-provided render thread heuristic is completely self-contained within DynamicResolution.cpp. The architecture is set up so that it allows the heuristic to be fully replaceable by Plugins in game code.

For example, if your project needs to replace the default heuristic because you want to do something like game play code giving hints of what is going to happen in the next frame, you can rewrite the entire heuristic to do just that. By implementing IDynamicResolutionState and ISceneViewFamilyScreenPercentage, you can replace the default dynamic resolution states, like the example below:

The renderer will now work with ResolutionFraction to avoid the divide by 100 everywhere in the screen percentage math. It is named fraction instead of "scale" because the upscale ratio is done by the TAA upsample or the spatial upscale is actually represented by 1 divided by the Resolution Fraction, like so:

Limitations of Dynamic Resolution

The following are some current limitations of Dynamic Resolution:

It is not supported for use with multi-world Play-In-Editor by design.

When TAAU is enabled, it will work with VR. Multi-Sample Anti-Aliasing (MSAA) support will follow in a future release.

The API is fully compatible with the mobile renderer. However, there hasn't been an effort to maintain the view size not being equal to the render target buffer size that is set by the primary screen percentage upper bound.

Gaussian Depth of Field (DoF) and Distance Field Ambient Occlusion (DFAO) have issues with resolution changes.

Frequently Asked Questions

The following are some general frequently asked questions regarding dynamic resolution:

Can the heuristic for Dynamic Resolution be replaced?

Yes, it was designed to be modular and pluggable in C++. Unreal Engine only maintains a single heuristic, but the architecture allows for the creation of a standalone custom heuristic with custom game thread events that could be triggered by gameplay code or Sequencer.

Does dynamic resolution work with any arbitrary secondary screen percentage?

This can be achieved by using the console variable r.SecondaryScreenPercentage.GameViewport.

For additional information, see the Screen Percentage with Temporal Upsample page.

Is it possible to control the dynamic resolution of the secondary screen percentage?

No, it's not possible and is by design. You would not want to change the size of Temporal Anti-Aliasing history and is why you should not need to dynamically change the secondary screen percentage.

Why is the function in FPostProcessSettings for ScreenPercentage ignored by dynamic resolution?

This was part of the previous mechanism where screen percentage could be configured in the settings for a Post Process Volume to manually scale up or down. With dynamic resolution, there is no need to set that any longer since it is automatically handled according to the GPU workload.

Why is there not an optional show flag for dynamic resolution in the Editor?

Because it happens globally and at game thread discretion. The screen percentage show flag will only toggle the Primary Screen Percentage.

Why is dynamic resolution not supported in Editor viewports?

Currently, dynamic resolution is only supported for Xbox One ,PlayStation 4, and Nintendo Switch which don't use PIE. When it is available for platforms (Vulkan, D3D12), you will be able to use it in the Editor with PIE.

Can the Primary and Secondary Screen Percentages be accessed in Materials?

No they cannot. Materials should be rendering independently of the resolution.

What a GPU Crash Looks Like

Why a GPU Crash Happens

Debugging GPU Crashes

Resolving GPU Out-Of-Memory (OOM) Issues

Understanding GPU Time Outs Caused by Expensive Operations (TDR Event)

TDR Events with Ray Tracing

How to Resolve TDR Events

Investigating Bugs in the Engine Code, Drivers and Operating Systems

What a GPU Crash Looks Like

When working in graphics-heavy projects, it is possible that you may encounter a GPU crash. When this happens, you will see a window like the following.



It is often followed by a Unreal Engine Crash Reporter window.



Click image for full size.

Why a GPU Crash Happens

Windows has implemented a safeguard to prevent applications from locking up by using too much memory, when processes take too long to complete, and various other reasons. In these situations, Windows will kill the GPU driver, resulting in an application crash.

When you get a GPU crash, the callstack and logs may have messaging such as "GPUCrash - exiting due to D3D device being lost - D3D Hung" and "DXGI_ERROR_DEVICE_REMOVED with Reason: DXGI_ERROR_DEVICE_HUNG."

GPU crashes can occur for various reasons, such as:

Running out of memory (OOM)

Times out while doing an expensive operation (TDR event)

A bug in the engine code

A bug in the driver

A bug in the Operating System

A problem in the hardware

For these reasons, in an application like Unreal Engine, it is not possible to always know why a crash occurs and may be impossible to avoid a crash at the application level. The sections below provide you with some debugging options to help identify the root cause and some preventative measures you can take.

Debugging GPU Crashes

When a crash occurs in Unreal Engine, you may want to start by looking at the callstack generated by Crash Reporter and log files that contain information to help in understanding what is happening. However, when a GPU crash happens, the CPU callstack does not really point to the real cause of the crash but just indicates what the CPU was doing when the GPU crash happened. Therefore, it provides no actionable information.

There are two debugging command line arguments that you can use to output logs with useful information.

-gpucrashdebugging collects GPU progress and tracks the current GPU state when debugging GPU crashes.

-d3ddebug provides information about the D3D pipeline.

We strongly recommend not using these command line arguments together. You should run the engine with each of the flags separately to generate logs.

After running the engine with each of these command lines and getting the crash, the logs are saved in [Your Project]/Saved/Logs folder.

When an application crashes in Windows, it generates dump files that can also be helpful in diagnosing a crash. You can learn more about these on Microsoft's Visual Studio documentation for using Dump files in the Visual Studio debugger.

Resolving GPU Out-Of-Memory (OOM) Issues

If the GPU runs out of memory, it could potentially cause a crash. It largely depends on the RHI being used, some are more resilient than others and in the case of an OOM event, they may get slow instead of dying.

To understand why an out of memory crash may be occuring, start with the Windows Task Manager and use the Performance tab. Here, you can select your GPU (1) and see its availble memory and how much it is currently consuming (2).



Windows Tasks Manager displaying the current stats for the GPU that include its available memory and current amount consumed.

With your project open and running, you can see how much GPU memory is being consumed versus what is availble. If you are close to the available memory limit, it is most likely the problem causing the crash. In this case try the following:

Close other programs that may be consuming large amounts of GPU memory.

Simplify the scene using lower resolution textures, lower resolution meshes, culling to reduce objects in the scene, and so on.

Use a lower screen resolution.

While working in the editor, you can use the Level Viewport Screen Percentage to render at a lower resolution.

While working in the editor, if you have multiple viewports open, close all but one.

Avoid disabling primary features like Niagara or Ray Tracing.

Bypassing these components changes many things, which could lead to invalid conclusions as to the cause of the GPU crash.

Understanding GPU Time Outs Caused by Expensive Operations (TDR Event)

When the CPU sends a command to the GPU for computing something, the CPU sets a timer to count how much time the GPU needs to complete the operation. If the CPU detects the operation is taking too much time (by default, it is two seconds in Windows), it resets the driver causing a GPU crash to occur. This is called a TDR event (or Timeout Detection and Recovery).

Ideally, the engine should never send the GPU such an amount of work that triggers a TDR event. Instead, the engine should be able to split the task into smaller chunks so that TDR is avoided. In order to avoid these types of events, you can increase the amount of time it takes for a timeout to occur by editing the Windows Registry (see steps below for How to Resolve TDR Events).

TDR Events with Ray Tracing

Hardware Ray Tracing is particularly costly and is more likely to trigger TDR events when it is enabled. Some expensive ray tracing passes (such as Ray Tracing Global Illumination at very large resolutions) could take a long time to render and could trigger a TDR event.

The most expensive ray tracing passes (global illumination, and reflections) provide a way to render the passes in tiles instead of a single pass using the following console variables:

r.RayTracing.GlobalIllumination.RenderTileSize

r.RayTracing.Reflections.RenderTileSize

When the tile size of a pass is greater than 0, these passes are rendered N x N pixel tiles, where each tile is submitted as a separate GPU command buffer. This allows high quality rendering without triggering timeout detection.

How to Resolve TDR Events

One way of avoiding TDR events is to increase the amount of time it takes for Windows to trigger one by editing the Windows registry keys. In this guide, you are going to create two new registry keys: TdrDelay and TdrDiDelay.

TdrDelay sets a timeout threshold. It is the number of seconds the GPU delays the preempt request from the GPU scheduler that handles processing and memory (VRAM).

TdrDdiDelay sets the amount of time the operating system (OS) allows threads to leave the driver. After that time has elapsed, a timeout delay failure occurs.

To learn more about registry keys, consult Microsoft's documentation about Tdr Registry Keys.

Changing the registry keys on your Windows operating system can have unexpected consequences and require a full reinstallation of Windows. Although adding or editing the registry keys in this tutorial should not result in those consequences, we recommend you backup your system prior to proceeding. Epic Games takes no responsibility for any damage caused to your system by modifying the system registry.

You need to add two registry keys to your graphics drivers. Follow these steps to add the registry keys.

Type ‘run' into the Windows operating system search bar. Open the Run application.



Click image for full size.

In the search field, type ‘regedit'. Click OK to open the Registry Edit Tool.



Click image for full size.

Navigate to the GraphicsDrivers section of the navigation on the left side of the Registry Edit tool. The location for this is Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers.



Click image for full size.

The registry keys need to be added to the GraphicsDrivers folder, not any of its children. Be sure to select the correct folder.

The registry key you need is called TdrDelay. If this registry key already exists, double-click to edit it. If it does not already exist, right-click in the pane on the right and select New > DWORD (32-bit) Value.



Set the Base to Decimal. Set the Value of TdrDelay to 60. Click OK to finish.



You need a second registry key called TdrDdiDelay. If this registry already exists, double-click to edit it. If it does not already exist, right-click in the right hand pane and select New > DWORD (32-bit) Value to create it.

Set the Base to Decimal. Set the Value of TdrDdiDelay to 60. Click OK to finish.



Your registry should now include both TdrDelay and TdrDdiDelay.



Click image for full size.

Close the Registry Editor.

Restart your computer for these changes to take effect.

By adding these registry keys, Windows will now wait for 60 seconds prior to determining that the application has taken too long for its process.

Although this is a good way to curb GPU crashes based on rendering, this will not resolve all crashes. If you try to process too much data at once, the GPU may time out regardless of how long you set the timeout delay. This solution is only designed to give your graphics card a little extra time.

Investigating Bugs in the Engine Code, Drivers and Operating Systems

Bugs in the engine code, drivers, or operating systems can also cause GPU crashes. These are some common things you can do to start investigating the cause of a GPU crash when OOM and TDR events have been eliminated as the root cause.

Run the engine with -gpucrashdebugging and -d3ddebug (separately as described in earlier).

Run the engine with -onethread and -forcerhibypass to force the engine to run with only one thread. This helps determine if the underlying problem is a threading / timing issue.

Run the engine with r.RDG.Debug=1 to provide information about render passes that have not been properly set.

Run the engine with r.RDG.ImmediateMode=1 to force the Render Dependence Graph (RDG) to execute passes immediately after creation. It can give you more meaningful callstacks. Note that this could give you misleading clues since it changes other things as well. It's still worth using for investigative purposes.

Switch to a different RHI. For example, if you are using DirectX 12 (DX12), you can switch to DirectX 11 (DX11). If the crash only happens in one of them, that could help identify if the problem is at a higher or lower level. Note that some features only work with a specific RHI (such as Hardware Ray Tracing only being supported by DX12).

Use A/B Testing for your scene:

Turn rendering passes on and off to check if the crash occurs. Many times, the problem is a faulty pass and doing this type of check can give good clues on what is going on.

Turn rendering features on and off, such as Lumen, Nanite, Ray Tracing. Note that some of these may require a system restart.

Hide / Show specific objects in the scene. This could isolate if problems are related to a specific asset.

When considering if a GPU crash is related to a specific driver, all of the above information applies and you should also get the most up-to-date drivers available. You may also want to check with the manufacturer for known issues this driver may cause.

When considering if a GPU crash is related to the operating system, all of the above information applies. Also, for Windows, we strongly recommend using version 20H2. You can find out which version of Windows you are using by pressing the Windows key and typing in winver.

Enabling Forward Shading

Enabling Multisample Anti-Aliasing

Performance and Features

Supported Features

Known Issues & Common Questions

By default, Unreal Engine uses a Deferred Renderer as it provides the most versatility and grants access to more rendering features. However, there are some trade-offs in using the Deferred Renderer that might not be right for all VR experiences. Forward Rendering provides a faster baseline, with faster rendering passes, which may lead to better performance on VR platforms. Not only is Forward Rendering faster, it also provides better anti-aliasing options than the Deferred Renderer, which may lead to better visuals.

Enabling Forward Shading

To enable the Forward Shading Renderer:

In the Edit menu, open the Project Settings.

Select the Rendering tab on the left and locate the Forward Shading category.

Enable Forward Shading.



You will be prompted to restart the editor where after the restart, you can begin using the Forward Renderer options and features.

Enabling Multisample Anti-Aliasing

To use Multisample Anti-Aliasing (MSAA):

In the Edit menu, open the Project Settings.

Select the Rendering tab on the left and locate the Default Settings category.

Set the Anti-Aliasing Method property to MSAA.



The forward renderer supports both MSAA and Temporal Anti-Aliasing (TAA) and in most cases, TAA is preferable because it removes both geometric aliasing and specular aliasing. In VR however, the constant sub-pixel movement introduced by head tracking generates unwanted blurriness, making MSAA a better choice. Projects that choose to use MSAA will want to build content to mitigate specular aliasing. Additionally, the Normal to Roughness feature can help reduce specular aliasing from detailed normal maps and automatic LOD generation for static meshes can flatten features on distant meshes to help reduce aliasing from small triangles.

In our tests, using MSAA instead of TAA increases GPU frame time by about 25% (actual cost will depend on your content).

Below an example is given with Temporal AA enabled versus 4X MSAA enabled.





You can use the console variable r.MSAACount to control how many MSAA samples are computed for every pixel. r.MSAACount 1 disables MSAA. Assigning r.MSAACount 0 will fall back to using Temporal AA, which allows for convenient toggling between Anti-Aliasing methods.

Performance and Features

Switching from the Deferred Renderer to the Forward Renderer may provide you with an increase in performance for your project.

The forward renderer can be faster than the deferred renderer for some content. Most of the performance improvement comes from features that can be disabled per material. By default, only the nearest reflection capture will be applied without parallax correction unless the material opts-in to High Quality Reflections, height fog is computed per-vertex, and planar reflections are only applied to materials that enable it.



Leveraging these options in Epic's new VR game, Robo Recall, the forward renderer is about 22% faster than the deferred renderer on an NVIDIA 970 GTX.



The Forward Renderer works by culling lights and Reflection Captures to a frustum-space grid. Each pixel in the forward pass then iterates over the lights and Reflection Captures affecting it, sharing the material with them. Dynamic Shadows for Stationary Lights are computed beforehand and packed into channels of a screen-space shadow mask, leveraging the existing limit of 4 overlapping Stationary Lights.

Be sure to use Unreal Engine's [Profiling]() Tools to gauge the performance of your game when switching from the Deferred Renderer to the Forward Renderer. You will want to pay special attention to [Profiling GPU]() to see where GPU cost is going, as well as using the [Stat Commands]() to aid with your profiling efforts.

Supported Features

This list comprises the currently supported features of the Forward Renderer:

Full support for Stationary Lights, including Dynamic Shadows from Movable objects which blend together with precomputed environment shadows

Multiple Reflection Captures blended together with parallax correction

Planar Reflections of a partial scene composited into Reflection Captures

DBuffer Decals

Precomputed Lighting and Sky Lights

Any number of unshadowed Movable Lights

Capsule Shadows

Alpha-to-coverage for Masked Materials

Instanced Stereo Compatible

Up to 4 overlapping Shadow Casting Movable Lights

Light Functions on shadow casting lights

Known Issues & Common Questions

The following features are not supported while using the Forward Renderer:

Screen Space Techniques (SSR, SSAO, Contact Shadows)

Dynamically Shadowed Translucency

Translucency receiving environment shadows from a Stationary Light

MSAA on D-Buffer Decals and Motion Blur

Below are some common questions/issues that may arise when using the Forward Renderer.

My Material is broken when switching to the Forward Renderer, something about GBuffer scene textures?

Access to the GBuffer is not available for texture sampling in the Forward Renderer and is only available with the Deferred Renderer.

Does the Forward Renderer allow fewer texture samples than the Deferred Render?

The Forward Renderer packs all features into one shader so there are fewer texture samplers available for your material.

You can usually solve this by using Shared Samplers.

How come I have issues with MSAA not being able to find samples against Atmospheric Fog?

Atmospheric Fog does not handle MSAA correctly yet.

For Height Fog, you can get around with Vertex Fogging (which is enabled by default when enabling Forward Shading).

This means it is computed in the Forward BasePass and therefore anti-aliased correctly.

Atmosphere is still computed in a Deferred Pass off of resolved scene depths so it does not anti-alias correctly (which we hope to fix in future updates).

Dumping Process

Save Location of GPU Dumps

Mobile Platform Dump Save Location

Dump Settings

How the DumpGPU Command Copies the GPUDumpViewer

The GPU Dump Viewer

Title Bar and Panels

Infos Panel

CVars Panel

Log Panel

Viewers

Pass Viewer

Texture Viewer

Texture Descriptor

WebGL 2.0 Visualization Shader

Passes being Modified and Read

Buffer Viewer

DumpGPU is a platform-agnostic console command that dumps the intermediary rendering resource binaries of a captured frame to disk. The dump is stored with .json and .bin files that can then be browsed using a lightweight webpage viewer.



This command serves several purposes:

It is available for all builds without the need to install a third party GPU debugging tool or restart the editor.

Dumps can come from any supported platforms:

Windows D3D11, D3D12, Vulkan

Linux Vulkan

Mac Metal, AGX

PlayStation 4 and PlayStation 5

XboxOne, Xbox Series X/S

Nintendo Switch

iOS and Android

The interface is browsable from any platform that supports Chrome and a WebGL 2.0-capable GPU.

Simple and platform-agnostic, which enables anyone to produce a GPU dump when encountering an artifact.

Ideal for artists that run into unexpected and hard-to-reproduce problems while working in the editor.

Minimizes frictions of browsing a resources binary.

Platform GPU captures often require the correct SDK, and a dev kit to be able to analyze the resource. The GPUDump viewer enables developers to better triage bugs, but also to look at resources from any platforms with the required context of an issue.

For graphics programmers writing new renderer functionality, this tool provides a faster iterative workflow for analyzing what may be happening.

Dumping Process

To initiate the process of creating a GPU dump of the frame, enter the command DumpGPU into the console window, or use the keyboard shortcut CTRL + Shift + /.

Once the command is initiated, it needs to copy the intermediary rendering resources to disk. To handle this, capture speed is traded for memory to limit out of memory failures from occurring. This ensures that the dump can reliably gather data of artifacts that are rare or difficult to reproduce without crashing a process that was able to reproduce it.

The amount of persistent memory needed for a dump to know whether a resource has been already dumped or not is negligible.

If the amount of memory required to dump a resource is larger than the available memory in the system, the resource will not be dumped. Instead, a warning is placed in the log.

The DumpGPU command is available on Debug, DebugGame, Development, and Test builds, but it can be enabled on Shipping builds with the Project.Target.cs.

These should be used for debugging testing purposes shipping only rendering problems and should not be enabled when actually shipping the project.

Save Location of GPU Dumps

When a GPU dump is performed, it is stored in the project's root directory under the Saved/GPUDumps by default. On Desktop platforms, the file explorer will open a window to this dump location automatically on completion.



For Staged builds, they are saved in the Stage's Saved directory, with the path format: [Staged Directory] / [Platform Name] / [Project Name] / Saved / GPUDumps.

All dumps are uncompressed raw resources, which means they can take up a lot of disk space. However, it is highly compressible as a Zip file. For example, the Matrix: Awakens technical demo produced dumps that were approximately 8Gb uncompressed, and 2.2Gb once zipped.

Zipping dumps can be useful when sharing data with others.

For Mobile platforms, the GPU dumps are saved in the following locations:

Mobile Platform

Save Location File Path

iOS

[Path to App Container]/Documents/[ProjectName]/Saved/GPUDumps/

Android

/storage/emulated/0/UnrealGame/[ProjectName]/[ProjectName]/Saved/GPUDumps/

Stencil buffer will be empty on Android OpenGL.



Dump Settings

The GPU dumps created can be tailored to your needs with the following commands:

Console Variable

Description

r.DumpGPU.Root

Selects a subset of Render Dependency Graph (RDG) passes to dump based on their draw events and the parent scopes they belong to. Enabling this can significantly speed up the dumping process by only dumping the passes you need when iterating on isolated rendering functionality. For example, to only dump post processing passes, enter r.DumpGPU.Root="PostProcessing".

r.DumpGPU.Viewer.Visualize

Automatically opens a specific resource based on its name in the viewer. For example you would enter `r.DumpGPU.Viewer.Visualize ""

r.DumpGPU.Directory

GPU dumps can take up large amounts of disk space. You can specify the directory to save all GPU dumps in a single location using this command in your ConsoleVariables.ini configuration file. You would specify the location like so, `r.DumpGPU.Directory="[X:/File/Path/Name]".

How the DumpGPU Command Copies the GPUDumpViewer

The GPUDumpViewer source code is available with the engine source and can be found in /Engine/Extras/GPUDumpViewer.

On non-Shipping builds, the GPUDumpViewer is automatically copied into the staging directory. Then, when the DumpGPU command is called to dump the frame, the files are copied from the staged directory to the dumping directory.

If you have a Shipping staged build, the GPUDumpViewer's HTML source may not be copied into the dumping directory because it is missing in the staged directory. In this case, you can copy your repository's //Engine/Extras/GPUDumpViewer application into your dumping directory to open the dump.

The GPU Dump Viewer

The GPU Dump Viewer is an HTML web-based application. From this viewer, you can access information about how the Unreal Engine renderer works.

To get started, once a GPU dump has occurred, the operating system will open the folder location of the saved dump. The viewer can be opened in Chrome by double-clicking the OpenGPUDumpViewer.bat file.



Once initiated, a new Chrome window will open with the GPUDumpViewer running.



GPUDumpViewer web application opens in a new Chrome Incognito window.

The GPUDumpViewer is a web application and functions similarly to any browser-based page or application. The following are some quick tips about working in the GPUDumpViewer:

Any link is clickable and can be opened in its own tab for quick access.

Navigation with the forward and back buttons will move between any previously viewed pages.

If sharing a capture with someone, you can share the link after the # part to link them directly to a panel and part of the dump. For example, #display_output_resource(96,'0000000067e1bfa0.mip0');

When you open GPUDumpViewer, you can cycle through a bunch of tips and tricks in the main viewing area.



Title Bar and Panels

Pass and Resource Tree

Viewer

Title Bar and Panels

The main title bar provides quick reference information about the name of the project, operating system, RHI, and build that was used when the dump was created. It also includes clickable information panels for general information about the project, console variables used, and a copy of the project's log.



The Infos panel contains a summary of the GPU Dump. You'll find useful information about the system, drivers, and engine build, along with a screenshot of the final image from the back buffer.



The CVars panel includes a searchable list of any rendering console variables — ones that begin with .r.* or .sg.*, or contain the RHI keyword — that were run before the dump occured.



Console variables are captured at the beginning of the frame. Therefore, some might be subject to changes if gameplay toggles cvars at runtime.

The Log panel provides a copy of the project's log, which gets saved along with the dump once the dump is completed. This is where you can also inspect whether there has been any warning issued in the dumping process.



Viewers

The viewing area displays information about the different Passes, Textures, and Buffers when selected.

When clicking on a Pass in the draw event hierarchy, only the resources that the pass reads and modifies will be shown. It automatically opens up the first output resource, whether it's a texture or the buffer.



Next to the pass name (at the top of the viewer), you will find the Pass Parameters button.



Clicking this will display the raw pass parameters. More often than not, the pass parameters are shader parameters. For example, when FComputerShaderUtils::AddPass() or FPixelShaderUtils::AddPass() are used.

Pass Parameters enable you to verify that no instances of NaN from the CPU affects your shader through the shader parameters.



When a Texture is selected in the Pass view's Input Resources or Output Resources list, you can visualize its pixels in the viewer.



WebGL 2.0's canvas makes it possible to view textures by loading the raw resource binary (the RHI has copied into the dump's directory), and displaying it using a simpler WebGL pixel shader. For formats not supported by WebGL, such as 32 bit UINT textures, additional work behind the scenes is done to accurately simulate the pixel format.

The Texture Viewer includes several buttons along the top of the displayed texture:



Set the size of the texture being displayed in the viewer or simply fit it to the window.

Use Copy to clipboard to copy the currently displayed texture and relevant resource information to your clipboard. When you paste it into a text editor, or email, you should see something like this:



There are three buttons to change the texture view mode: Visualization for standard texture view mode, or NaN (not a number) and Inf (infinity) viewing modes for identifying those types of pixel errors.

Hovering the mouse over the texture returns the current RGBA values of the cursor texel position. Left-clicking the mouse will capture and hold the texel RGBA position value.

The value displayed for the Cursor Texel Pos and Selected Texel Pos includes many more digits than the precision allowed by the pixel format encoding. This is because the webpage decodes the texel in javascript using double precision floating point format.

For parts of the texture you want to examine more closely, you can use the mouse wheel to zoom in and out of the texture. When zoomed in, you can right-click and drag to move around the texture.



The area below the displayed texture provides key information about the texture and how it is being rendered.



Texture Descriptor

WebGL 2.0 visualization shader to customize

Passes that modify the resource

Passes that read the resource

The Texture Descriptor displays information about the currently displayed texture. This is the one set up on FRDGBuilder::CreateTexture().



At this time, the DumpGPU command only dumps FRDGTexture and only supports non-MSAA Texture2D. This includes depth, stencil, and mip levels. Texture2DArray, Texture2DMS, Texture3D, TextureCube, TextureCubeArray are metadata like HTILE, CMask & cie are not supported yet

The WebGL 2.0 Visualization Shader displays the code fragment that gets compiled to display the texture in the top window. Below it, the compilation log window displays any compilation errors that may occur.



The WebGL 2.0 canvas window is an editable text box that can be used to write any WebGL 2.0 GLSL. It can be customized to visualize and decode the texture, like when your image is compressing multiple bits of information per channel, or using a different color space. Any code typed in this field will automatically recompile and display any errors.

The syntax for WebGL 2.0 shaders differs from those that Unreal Engine uses with its Unreal Shader Format (.usf) and Unreal Shader Header (.ush) files used to write internal rendering code with HLSL. A link to the WebGL 2.0 quick reference card for GLSL syntax is linked at the bottom of the compilation window.

The fetchTexel(uv) is not standard GLSL. Instead, it is a custom function that automatically handles pixel formats that are not normally supported by WebGL2.0.

At the very bottom are two windows, one for the Passes that are modifying the selected resource and Passes that are reading from the selected resource. In either Passes list, click on any Pass to display them in the viewer.



Once a texture is selected for viewing in the Pass Input Resources or Output Resources lists, the Buffer view will list its descriptor and visualization contents.



The Buffer Descriptor lists general information about the selected resource, such as its name, size, description, usage, and more.



The Buffer Visualization lists addresses in the buffer with decimal or 0x prefix hexadecimal values.



Use the Address text field to jump to a specific address that is either decimal or with a 0x prefix.



The format of the list can be customized and supports the following:

Float, Half

Int, short, char

Uint, ushort, char

Hex(), or bin(), which displays any of the above formats in hexadecimal or binary.

Because the GPUDumpViewer doesn't know how the data should be interpreted, the buffer defaults to data visualization using the hex(uint) format unless it has the DrawIndirect usage flag, in which case the Uint format is used.

The templated FRDGBufferDesc::Create*() function can be used to create your FRDGBuffer with a shader parameter structure, making it more convienent to browse the buffer's content.



The buffer automatically switches to displaying members per-column instead of per-row when the descriptor NumElements is greater than 1.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Benefits of Nanite

Differences Between a Nanite Mesh and Static Mesh

How does Nanite work?

What Types of Meshes Should Nanite Be Used For?

Enabling Nanite Support on Meshes

Supported Features of Nanite

Nanite Fallback Mesh and Precision Settings

Working with Nanite-Enabled Content

Hybrid Non-Nanite and Nanite Content Workflows

Data Size

Visualization Modes

Console Variables and Commands

Nanite is Unreal Engine 5's virtualized geometry system which uses a new internal mesh format and rendering technology to render pixel scale detail and high object counts. It intelligently does work on only the detail that can be perceived and no more. Nanite's data format is also highly compressed, and supports fine-grained streaming with automatic level of detail.



Benefits of Nanite

Multiple orders of magnitude increase in geometry complexity, higher triangle and objects counts than has been possible before in real-time

Frame budgets are no longer constrained by polycounts, draw calls, and mesh memory usage

Now possible to directly import film-quality source arts, such as ZBrush sculpts and photogrammetry scans

Use high-poly detailing rather than baking detail into normal map textures

Level of Detail (LOD) is automatically handled and no longer requires manual setup for individual mesh's LODs

Loss of quality is rare or non-existent, especially with LOD transitions

Although the advantages can be game-changing, there are practical limits that still remain. For example, instance counts, triangles per mesh, material complexity, output resolution, and performance should be carefully measured for any combination of content and hardware. Nanite will continue to expand its capabilities and improve performance in future releases of Unreal Engine.

Differences Between a Nanite Mesh and Static Mesh

A Nanite mesh is a Static Mesh with Nanite enabled on it. A Nanite mesh is still essentially a triangle mesh at its core with a lot of level of detail and compression applied to its data. On top of that, Nanite uses an entirely new system for rendering that data format in an extremely efficient way.

All that is required for a Static Mesh to take advantage of Nanite is a flag to enable it. Authoring content for Nanite is no different than traditional meshes except that Nanite can handle orders of magnitude more triangles and instances than is possible for traditionally rendered geometry. Move the camera close enough and Nanite will draw the original source triangles that were imported.

Nanite meshes support multiple UVs and vertex colors. Materials are assigned to sections of the mesh such that those materials can use different shading models and dynamic effects which can be done in the shaders. Material assignment can be swapped dynamically, just like any other Static Mesh, and Nanite doesn't require any process to bake down materials.

Virtual Textures are not required to be used with Nanite, but they are highly recommended. Virtual Textures are an orthogonal Unreal Engine feature with similar goals for texture data that Nanite achieves with mesh data.

Working with Nanite should be familiar to workflows for Static Meshes, but there are many things not yet supported. See the Supported Features section of this page for more details.

How does Nanite work?

Nanite integrates as seamlessly as possible into existing engine workflows, while using a novel approach to storing and rendering mesh data.

During import — meshes are analyzed and broken down into hierarchical clusters of triangle groups.

During rendering — clusters are swapped on the fly at varying levels of detail based on the camera view, and connect perfectly without cracks to neighboring clusters within the same object. Data is streamed in on demand so that only visible detail needs to reside in memory. Nanite runs in its own rendering pass that completely bypasses traditional draw calls. Visualization modes can be used to inspect the Nanite pipeline.

Since Nanite relies on the ability to rapidly stream mesh data from disk on demand. Solid State Drives (or SSDs) are recommended for runtime storage.

What Types of Meshes Should Nanite Be Used For?

Nanite should generally be enabled wherever possible. Any Static Mesh that has it enabled will typically render faster, and take up less memory and disk space.

More specifically, a mesh is an especially good candidate for Nanite if it:

Contains many triangles, or has triangles that will be very small on screen

Has many instances in the scene

Acts as a major occluder of other Nanite geometry

Casts shadows using Virtual Shadow Maps

An example of an exception to these rules is something like a sky sphere: its triangles will be large on screen, it doesn't occlude anything, and there is only one in the scene. Typically these exceptions are rare and performance loss for using Nanite with them is fairly minimal so the recommendation is to not be overly concerned about where Nanite shouldn't be enabled if Nanite supports the use case.

Some use cases are not supported by Nanite currently. See the Supported Features section of this page for more details.

Enabling Nanite Support on Meshes

Nanite can be enabled on supported geometry in the following ways:

On import

Using individual mesh editors

Batched selection in the Content Browser

Converting geometry to Nanite requires some processing time for each mesh. On large projects, use of a shared Derived Data Cache (DDC) is especially helpful if there are many Nanite Assets. Please refer to the Shared DDC documentation for more information.

Importing a Static Mesh

When importing a mesh intended for us with Nanite, check the box for Build Nanite.



It is recommended to disable Generate Lightmap UVs property when not using precomputed lighting with Lightmass.

When this property is enabled, highly detailed geometry adds significant time to importing and building of Static Mesh data. The property also adds an additional UV channel, which includes a significant amount of data for very dense meshes. If your project doesn't require baked lighting, there's no need to incur either cost.

Enabling Nanite on Assets

In cases where you already have your project populated with content that you want to enable Nanite on, you have two options: enabling assets in batches using the Content Browser, or enabling individual assets through their own editors.

For batches of Static Mesh Assets that you want to enable Nanite for, use the Content Browser to select them all. Right-click and choose Nanite > Enable from the context menu.



Open the editor of any mesh that supports Nanite, such as Static Meshes and Geometry Collections (Chaos physics-driven fracture meshes) and enable Nanite through the Details panel.

In the Static Mesh Editor, locate the Nanite Settings and check the box for Enable Nanite Support.



In the Geometry Collections Editor, locate the Nanite section and check the box for Enable Nanite.



Supported Features of Nanite

This section describes how best to work with Nanite in an Unreal Engine project with details on what is and is not supported and possible limitations.

Geometry

Nanite can be enabled on Static Meshes and Geometry Collections.

A Nanite-enabled mesh can be used with the following Component types:

Static Mesh

Instanced Static Mesh

Hierarchical Instanced Static Mesh

Geometry Collection

Foliage Painter

Landscape Grass

Nanite has limited support for deformation of rigid meshes. Nanite supports dynamic translation, rotation, and non-uniform scaling of these meshes, whether it is dynamic or staic. This means moving any position of a Nanite mesh in a way taht is more complex than can be expressed in a single 4x3 matrix multiply, uniformly applied to the entire mesh.

Deformation is limited with:

(Beta) World Position Offset in Materials

The bounding boxes used for occlusion cull clusters does not update or expand their bounding boxes based on deformation. This means that any time a surface is displaced outwards, such that it would cover where it previously was, there is a good chance it could occlude itself and look broken.

Foliage using WPO is less problematic because foliage is filled with holes and cannot really occlude itself.

Deformation is not supported with:

Skeletal animation

Morph Targets

Spline meshes

Nanite-enabled meshes do not currently support:

Custom depth or stencil

Vertex painting on instances

This specifically means per-instance painted colors using the editor's Mesh Paint mode, but Nanite does support vertex colors on the original mesh.

The maximum number of instances that can be present in the scene is hard-locked to 16 million instances, which includes all instances that are streamed in, not just ones enabled for use with Nanite. Only instances streamed in are counted towards the total.

Per vertex tangents are not stored from the Static Mesh when it is enabled for Nanite. Instead, tangent space is implicitly derived in the pixel shader. Tangent data is not stored in order to reduce data size. This difference in tangent space using this approach could cause discontinuities at edges. However, this particular issue has not shown to be significant, and there are plans to support vertex tangents in a future release.

Materials

Nanite supports materials which have their Blend Mode set to Opaque and Masked. When an unsupported material type is detected, a default material is assigned to the Nanite-enabled mesh and a warning is placed in the Output Log with additional information.

Additional material features notes:

Nanite-enabled meshes can receive decals projected onto their surfaces but does not support Mesh Decals, which require materials to use a Translucent Blend Mode.

Wireframe checkbox is not supported.

The Vertex Interpolator node and Custom UVs are supported but will be evaluated three times per pixel.

Rendering

The following rendering features are not currently supported:

View-specific filtering of objects using:

Minimum Screen Radius

Distance culling

Forward Rendering

Stereo rendering for Virtual Reality

Split Screen

Multisampling Anti-Aliasing (MSAA)

Lighting Channels

Ray-tracing against Nanite meshes

The Fallback Mesh is used for Nanite-enabled meshses by default. Lower the Fallback Relative Error parameter in the Static Mesh Editor to use more of the source meshe's triangles.

(Experimental) Initial support for native ray-tracing of Nanite meshes is enabled with the console variable r.RayTracing.Nanite.Mode 1. This preserves all detail while using significantly less GPU memory than zero-error Fallback Meshes.

Some visualization view modes do not yet support displaying Nanite meshes

Use caution with some visualization modes in the Static Mesh Editor when viewing highly detailed geometry. Viewing Normals and UV can cause problems with editor performance.

Supported Platforms

Nanite is currently supported on PlayStation 5, Xbox Series S|X, and PCs with graphics cards meeting these specifications, using the latest drivers with DirectX 12 with Shader Model 6 (SM6):

NVIDIA: Maxwell-generation cards or newer

AMD: GCN-generation cards or newer

All newer versions of Windows 10 (newer than version 1909.1350) and Windows 11 with support for DirectX 12 Agility SDK are supported.

Windows 10 version 1909 — The revision number should exceed or be equal to .1350.

Windows 10 version 2004 and 20H2 — The revision number should exceed or be equal to .789.

DirectX 12 with Shader Model 6.6 atomics, or Vulkan (VK_KHR_shader_atomic_int64)

Latest Graphics Drivers

PlayStation 4 and Xbox One also support Nanite, but support on these platforms is currently considered experimental. It is expected that the performance of Nanite on these platforms with very high fidelity content may not meet the requirements of a shippable game.

Nanite Fallback Mesh and Precision Settings

Static Meshes include additional properties that control the precision of the Nanite representation and the Fallback Mesh generated from the full-detail mesh.

These settings are located in the Static Mesh Editor Details panel under the Nanite Settings section.



Nanite settings include the following properties:

Property

Description

Enable Nanite Support

Enables this mesh to be used with Nanite and to generate a Fallback Mesh in situations where Nanite cannot be used.

Preserve Area

Enables Nanite meshes that would lose surface area due to simplification to redistribute that lost area to the remaining triangles by dilating out the open boundary edges. This is most useful for foliage where leaves tend to become disjoint triangles and quads through simplicication. The effect of this setting is to scale each leaf up. For geometry ribbons, like blades of grass, it has the effect of thickening them. This setting should be enabled on all foliage meshes and nothing else.

Position Precision

Choose the precision this mesh should use when generating the Nanite mesh. Auto determines the appropriate precision based on the size of the mesh. The precision can be overridden to improve precision or optimize disk footprint.

Minimum Residency

Sets the memory byte size this mesh should always keep in memory, and has the rest streamed in. Higher values require more memory, but for some meshes, this can mitigate streaming pop-in issues from occurring.

Keep Triangle Percent

The percentage of triangles to keep from the source mesh. Reduce this percentage to optimize disk size.

Trim Relative Error

Sets the maximum amount of relative error that is allowed to be removed for the Nanite mesh. All detail in the source mesh with less visual impact than this relative error amount is removed. The relative error does not have a unit size and is relative to the size of the mesh. By default, Nanite stores all of the original source mesh's triangles.

Fallback Triangle Percent

Sets the percentage of triangles that remain when reducing the source mesh for Nanite. This becomes the coarse representation (or Fallback Mesh) used when the full detail Nanite data cannot be, such as platforms which do not support Nanite rendering, or when it is impractical to use Nanite data like with complex collision.

Fallback Relative Error

Sets the maximum amount of relative error that is allowed to be removed for the Fallback Mesh. All detail in the generated Fallback Mesh with less visual impact than this relative error amount is removed. The relative error does not have a unit size and is relative to the size of the mesh.

Source Import Filename

The file path used to import a High Res mesh to be used with Nanite. The high resolution version of the mesh is used in place of LOD0 by systems that can benefit from more detailed geometry, such as Nanite and Geometry Modeling in Unreal Engine.

Vertex Precision

Nanite quantizes mesh vertex positions to maximize memory density and minimize disk footprint. The quantization step size is a power of two that can be selected to match the requirements of individual meshes using the Position Precision property. By default, Auto picks the appropriate precision based on the size of the mesh and its triangle density. You can manually override by selecting a precision size to improve precision or optimize disk footprint.



Qantinization is a form of lossy compression. Lossy compression is particularly challenging when working with modular mesh pieces, or other meshes that have shared boundaries. Especially when those boundaries need to align perfectly to not introduce holes or cracks in the geometry.

To ensure consistency, quantization happens in unnormalized object coordinates centered around the mesh origin. This ensures that the quantization never causes cracks when the mesh uses the same precision setting, and the translation between the mesh center is a multiple of that precision.

Trimming data

There are times when you'll need to reduce the amount of data Nanite stores to optimize for disk size. Nanite includes settings which allow you to trim the detail data from a stored Nanite mesh at any time during production, meaning that you can safely overshoot quality up front and adjust accordingly later on.

To trim the detail data, you will want to use the Keep Triangle Percent and Trim Relative Error properties. You can think of them like a pre-decimate option before being stored as a Nanite mesh. In Nanite's case, detail doesn't need to be uniform across the mesh. It removes the least significant data first and is more akin to lossy compression.

Use Keep Triangle Percent to set the percentage of triangles to keep from the source mesh.

Use Trim Relative Error to set the maximum amount of relative error that is allowed when trimming the data from the source mesh. Any triangle that if removed would incur a relative error less than this amount is removed. Or another way to think about this is all detail with less visual impact than this value is trimmed. Relative error does not have a unit size and is relative to the size of the mesh.

The defaults for both of these properties are such that nothing is trimmed by default, and Nanite stores all of the original source mesh's triangles.

Trimming data is important to reducing disk size (in other words, download size), not for improving performance. See Data Size section below for more on this topic.

Fallback Mesh

Many parts of Unreal Engine need access to the traditional vertex buffer provided by traditionally rendered meshes. When Nanite is enabled for a Static Mesh, it generates a coarse representation (called a Fallback Mesh) of the highly detailed mesh that is accessible and used where Nanite data cannot be. The Fallback Mesh is the generated mesh used when Nanite rendering is not supported. It is also used in situations where it wouldn't be ideal to use the full-detail mesh, like when complex collision is needed, using lightmaps for baked lighting is required, and for hardware ray tracing reflections with Lumen.

The Fallback Triangle Percent property represents the percentage of triangles from the original source mesh that are used to generate the Fallback Mesh. You can specify the percentage of triangles to keep between 0 and 100 percent, where large percentages keep more of the original mesh's detail.

The Fallback Relative Error sets the maximum amount of relative error that is allowed when removing details from the source mesh. Any triangles that if removed would incur a relative error less than this amount are removed with detail of less visual impact being first to go. The relative error does not have a unit size and is relative to the size of the mesh.

For example, if you wanted your mesh to not have any decimation at all, you would use a Fallback Triangle Percentage of 100 and a Fallback Relative Error of 0.

In the comparison below, there is the highly detailed Nanite mesh created from the original source mesh which is compared with default settings of a generated Nanite Fallback Mesh.





Use the Fallback Relative Error to specify how much of the original detail is retained from the original source mesh, and the Fallback Percentage to set how much of that detail is used.

In the comparison below, the Fallback Mesh keeps 100 percent of the Fallback Triangle Percent but adjusts the Fallback Relative Error to use more of the triangles from the original source mesh. When adjusting these values, you can use the Nanite details for Nanite Triangles in the viewport as an indicator when changing their values.





In the Static Mesh Editor, you can toggle between the fully detailed Nanite mesh and the Nanite Fallback Mesh using the viewports Nanite Fallback option in the Show dropdown menu. Alternatively, you can use the hotkey Ctrl + N to quickly toggle between the two visualization options.



The Fallback Mesh is used for engine features, such as complex per-poly collision, ray tracing, light baking, and so on. It is also used for platforms which do not support Nanite. When generating the Fallback Mesh, a Nanite-enabled mesh always uses the LOD0 slot of the source mesh for auto-generating the fallback mesh. However, there are times when it is desirable to use a manually specified fallback mesh, or a series of traditional LODs, rather than an auto-generated one.

This level of control would allow you to use Nanite in a project but also directly control the geometry seen in ray-traced reflections, or on platforms which do not support Nanite.

Follow the steps below to specify your own custom fallback mesh, or to use a series of LODs:

Set the Fallback Triangle Percent to 0 so that the fallback mesh is as small as possible since it will be ignored when using this approach.

Add one or more LODs to the mesh using this traditional LOD setup procedure.

Use the LOD Import dropdown to Import LOD Level 1 from the LOD Settings section.

Set the Minimum LOD to 1 under the LOD Settings section. This causes the Nanite-generated Fallback Mesh to be ignored.

Complex Collision presents a special case. Use the LOD for Collision property under General Settings to specify which LOD should be used for collision. Any LOD can be used for collision, including LOD0.

This particular approach may not be feasible to make Nanite projects automatically compatible with non-Nanite-supporting platforms, and should be tested and evaluated for your project.

Nanite efficiently handles very large numbers of instances, but if Nanite is disabled, there could be an overwhelming number of draw calls for the traditional render pipeline. You can test this in your project for feasibility using the r.Nanite 0 to toggle Nanite support off and on.

See the Console Variables and Commands section of this page for more information.

Working with Nanite-Enabled Content

In most cases, Nanite scales extremely well within screen resolution. It does so based on two techniques: fine-grained level of detail and occlusion culling. Typically this means, regardless of geometric complexity of the source data in the scene, the number of triangles Nanite attempts to actually draw to the screen is consistent and proportional to the number of pixels.

Nanite follows the design principle that there is no use in drawing far more triangles than there are pixels.

However, there are some cases of content that breaks the techniques Nanite uses to scale, but this doesn't mean it should not be used at all for this content, or that it will not render faster than the traditional rendering pipeline. It only means that for this type of content, scaling with pixels — and not scene complexity — no longer applies to them. Use the Profiling features provided by Unreal Engine to monitor these types of situations when they occur.

Aggregate Geometry

Aggregate geometry is geometry that has many disjointed parts that become a volume in the distance, such as hair, leaves on trees, and grass. This type of geometry breaks the level of detail and occlusion culling techniques of Nanite.

Nanite is inherently a hierarchical level of detail structure that relies on being able to simplify small triangles into larger triangles and choosing the coarser one when it determines the difference is smaller than can be perceived. For continuous surfaces, this works well, but not for aggregate geometry that from a distance appear more like a partial opaque cloud than a solid surface.

As such, Nanite is more likely to determine it cannot reduce aggregate geometry nearly as aggressively as it would typical solid surfaces, thus resulting in more triangles being drawn for the same number of pixels covered.

Another optimization that aggregate geometry breaks is Occlusion Culling. Although it is very fine-grained, its granularity is not per pixel. Geometry that is filled with holes — and worse yet, layers upon layers of geometry filled with holes — causes excessive overdraw because many depth layers need to build up before that area on screen will block anything behind it. One way to think about this is to consider an 8x8 pixel region on screen and how many depth layers need to be drawn before every pixel is filled. Excessive overdraw means that for the same number of pixels covered, Nanite attempts to draw more triangles causing it to render slower.

Foliage is the most obvious case for causing problems with occlusion culling, but even then, it does not mean that Nanite should not be used on foliage-type meshes at all. Refer to the Foliage Using Nanite section below for more.

It is good to experiment with different use cases and see what works well for your projects. Use profiling tools to confirm good performance from Nanite with these types of meshes.

Closely Stacked Surfaces

Occlusion culling with traditional meshes makes kitbashing workflows nearly impossible on a large scale due to practical limitations. The fine-grained nature of occlusion culling with Nanite makes it possible to use these types of workflows during development with less concern.

As is explained in the Aggregate Geometry section above, overdraw can come from hidden surfaces being very close to visible surfaces below them. If any geometry is buried well below the visible surface, Nanite detects and culls it fairly cheaply, such that it can mostly be considered free of cost. However, when there is stacked geometry that is close together near the top-most surface, Nanite is not able to determine which is on top or bottom, causing both to be drawn simultaneously.

This particular issue with culling is a worst case scenario where Nanite does not know which surface is on top, and just draws all the layers instead. Imprecision like this scales with screen size and distance, so while 10 centimeters may separate layers and look fine while close to the surface, farther distances away can cause the difference in distance to be smaller than a pixel, resulting in overdraw.





In the example below, if the camera is moved to look downward on the area where the character is standing, the Nanite Overdraw visualization shows how these stacked surfaces are being rendered. Brighter areas indicate more overdraw is happening in those areas than others.



The Overdraw visualization is the most effective way to find issues of overdraw. While some amount of overdraw should be expected, excessive amounts of it result in Nanite culling and rasterization costs becoming higher, and Nanite's scaling independently of scene complexity will become less effective in the process.

Faceted and Hard-edge Normals

One issue to be mindful of is when importing highly detailed meshes that have faceted normals, meaning that the normal between two different polygons was not smoothed. This issue is common and easy to miss and caution should be taken to avoid this particular issue because low amounts of vertex sharing in a mesh can become significantly more expensive both in rendering performance and data size.

Ideally, the number of vertices for a mesh should be less than the number of triangles it has. If the ratio is 2:1 or higher, then there is likely a problem, especially if this results in a high triangle count. Having a ratio of 3:1 means the mesh is completely faceted where every triangle has its own three vertices, none of which are shared with another triangle. Most often, this is caused by the normals not being the same because they are not smoothed.

With that in mind, more vertices means more data to store. It also means more vertex transform work, and ratios higher than 2:1 fall down some slow rendering paths. Intentional use in hard surface modeling shouldn't cause any issues, and there is no reason not to use them. However, accidental 100% facet very dense meshes are far more expensive than intended. Another thing to watch out for is imported normals on dense organic-type surfaces generated in other DCC packages that have hard normal thresholds that might be sensible on lower polygon meshes, but can add unnecessary expense with Nanite.

For example, In the two meshes below, the mesh on the left has faceted normals while the one on the right has smoothed normals. When comparing these using the Nanite Triangles visualization, there are noticeable differences in the number of triangles used by Nanite to draw them. The faceted one on the left draws significantly more triangles than the smoothed one on the right.





Nanite-enabled meshes with faceted (left) and smoothed (right) normals

Nanite Triangle Visualization of Nanite-enabled meshes with faceted (left) and smoothed (right) normals

Click image for full size.

Click image for full size.

Foliage Using Nanite

Foliage using Nanite is considered Beta and is beting actively researched and developed. This section provides some guidance on using foliage with Nanite in Unreal Engine 5.1.

For assets like trees with default Nanite settings you might find that the canopies tend to thin out with distance. These cases are a particular form of Aggregate Geometry where each disjoint part (a leaf or grass blade) has open edges at its boundary. Enabling Preserve Area is useful to prevent this thinning out when Nanite is enabled. When Nanite simplifies the geometry in the distance by reducing the number of triangles, it eventually needs to start removing some of these disjoint elements completely. Without Nanite having more information the result will look thinned out because there was major surface area loss. Preserve Area will redistribute that lost area to the remaining triangles by dilating out the open boundary edges. Dilation for symmetric shapes like leaves has the same effect as scaling them up. In non-symmetric cases like ribbons, for example blades of grass, it has the effect of thickening them.

Preserve Area is recommended for all foliage meshes, but not for meshes that are not foliage.





The Nanite Cluster visualization provides a clearer look at how Preserve Area redistributes lost area.





Below are some recommendations when using and authoring foliage assets with Nanite in mind. We are still experimenting and learning ourselves what are the best approaches. So far, we have seen that foliage using Nanite should be authored differently than before but if you play to its strengths you can get faster, higher quality results using Nanite.

Use Preserve Area (enabled in the Static Mesh Editor).

Use geometry instead of masked cards.

Masked materials are fairly expensive compared to Opaque ones. Fastest results are likely obtained by not using them at all.

The traditional card approach (many elements are represented with a single card) with Nanite can be slower than non-Nanite. Do not expect that enabling Nanite on card-based foliage will always be a performance improvement.

Masked out pixels cost nearly as much as drawn pixels. Overdraw is already an issue with aggregates in Nanite. If a masked material is used, the Nanite overdraw visualization will not tell you the entire story in terms of cost. Overdraw is a complex concept in this case and the visualization only shows a particular aspect of it.

Geometry foliage has shown to be faster with Nanite than card approaches, both Nanite cards and non-Nanite cards. It also looks better.

The Megascans: Grass pack on the Unreal Engine Marketplace offers good examples for testing. The pack offers both masked and high-poly geometry where each element is independent and masked low-poly cards where many elements are represented by a single card.

When using World Position Offset (WPO), more vertices equal higher cost. WPO logic must be limited and monitored.

The issues explained in the Aggregate Geometry section of this page still apply. Dense forests (like the examples above) will render much slower than the same scene with all meshes replaced with solid shapes of the same triangle count.

Hybrid Non-Nanite and Nanite Content Workflows

The following sections highlight workflows you can use in your Nanite-enabled projects that need to also support non-Nanite features and platforms without duplicating assets.

Importing a High Resolution Mesh for Nanite

You can import a high resolution mesh to be your Nanite representation for any existing non-Nanite Static Meshes through the Content Browser or the Static Mesh Editor.

From the Content Browser, you can use the right-click context menu on a Static Mesh Asset to select Level of Detail > High Res > Import High Res and navigate to the file you want to import.



Alternatively, you can use the Static Mesh Editor to import a high resolution mesh using the Nanite Settings in the Details panel. Click Import and navigate to the file you want to import.



Using this workflow, the pre-existing Static Mesh and its level of detail (LOD) chain become the Fallback Mesh rather than having the import process automatically generate a Fallback Mesh from the Nanite geometry.

This workflow respects the Disallow Nanite setting on Static Mesh Actors in your scenes and is explained more in the Static Mesh Component Options section below.

Material Workflows

There are two ways you can improve your non-Nanite and Nanite workflows with materials: by using a node in the material graph to break up logic paths, or by using an override material only used for rendering with Nanite.

The Nanite Pass Switch node allows you to define specialized behavior in a material graph when rendered with Nanite.



Use the Default input when rendering into non-Nanite passes, to handle the material as it would be normally. Use the Nanite input for any material logic you want to simplify or be specifically rendered to Nanite passes. For example, in cases where a material uses a feature not supported by Nanite, you could keep the same logic for the Default input and use a friendlier logic for the Nanite input.

The Nanite Override Material slot is available on Materials and Material Instances. When you set an override material, any Nanite-enabled meshes that have the Material or Material Instance assigned will use the referenced Nanite Override Material instead. This means that you can create materials specific to Nanite workflows rather than managing logic directly inside the material graph using the Nanite Pass Switch node.



In Material Instances, the Nanite Override Material slot is forcibly defaulted to None so that setting the override in a parent Material will not cause it to automatically be inherited in any of the child instances of that material.

In the example below, the Static Mesh Asset for the statue has Nanite enabled and it has a Material Instance applied. The Material Instance has its Nanite Override Material set with some simple color changes for demonstration purposes. The Static Mesh Actor on the left displays the Nanite Override Material since the mesh is being rendered with Nanite. The Static Mesh Actor on the right displays the same material until Disallow Nanite is set on the actor, disabling the Nanite Override Material to show the non-Nanite base material of the Material Instance.

Static Mesh Component Option: Disallow Nanite

You can set when Nanite-enabled Static Meshes should use their Nanite representation using the Disallow Nanite setting on individual scene actors. This means you can have a mix of Nanite and non-Nanite actors which use the same Static Mesh Asset.



The example below shows a single Nanite-enabled Static Mesh Asset where the left is the Nanite mesh representation and the right has Disallow Nanite enabled.



Landscape Terrain

This is an experimental feature.

To use Nanite with your Landscape terrain, select it and use the Details panel to check the box next to Enable Nanite.



There are two ways to build the Nanite mesh representation from Landscape data:

Click the Rebuilt Data button in the Landscape's Details panel under the Nanite section.

Use the Build menu to select Build Nanite Only.

Depending on the size of the Landscape, or number of tiles, it can take a moment for it to generate its Nanite representation. When complete, you can check it out in the Nanite visualization modes.



The following console variables are useful when working with Nanite-enabled Landscapes:

Landscape.LiveRebuildNaniteOnModification triggers a rebuild of the Nanite representation immediately when a modification is performed. (Default 0)

Landscape.RenderNanite sets whether the Landscape should render using Nanite or not. (Default 1)

Nanite-enabled Landscapes have the following limitations:

When using live modification of Nanite-enabled Landscapes (Landscape.LiveRebuiltNaniteOnModification 1), it makes landscape sculpting almost unusable because it rebuilds the Nanite representation of all Landscape Actors at every frame.

The maximum resolution of the Nanite mesh is the same as LOD0 for Landscape. No resolution increase should be expected by using Nanite over a normal Landscape. In its current state, this is purely a runtime optimization.

Saving Landscape Actors with Nanite enabled when Nanite mesh has not been updated is slower since Nanite meshes have to be built before saving.

Technical considerations:

Nanite Landscapes are currently streamed in on top of the usual Landscape data streaming because both Nanite and non-Nanite data are necessary at runtime, with the latter required for Runtime Virtual Textures, water rendering, and more. This means twice the data has to be streamed in — one set of data with Nanite streaming, and the other with the texture streaming — and resident in memory when Nanite is enabled.

Runtime performance is improved with Nanite rendering, especially with regards to shadow passes, but no visual improvement (or downgrade) should be expected since the source data is identical.

Hierarchical Level of Detail (HLOD)/streaming is expected to behave identically to non-Nanite Landscape.

When editing Nanite-enabled Landscapes, we advise to keep the live rebuilding of Nanite meshes off (Landscape.LiveRebuiltNaniteOnModification 0). Landscape rendering relies on non-Nanite Landscapes until the Nanite mesh is rebuilt (either on save or when using the Build Nanite Only / Build All Landscapes in the Build menu) and up-to-date, in which case it will use that version for rendering. Since no major visual difference should exist between Nanite and non-Nanite Landscapes, it does mean that in-editor performance while the non-Nanite Landscape is in use is not representative of the runtime performance in your project.

Performance of Typical Content

For comparison purposes, the following GPU timings were taken from the Unreal Engine 5 technical demo Lumen in the Land of Nanite on a PlayStation 5:

Average render resolution of 1400p temporally upsampled to 4K.

~2.5 millisecond (ms) to cull and rasterize all Nanite meshes (which was nearly everything in this demo)

Nearly all geometry used was a Nanite mesh

Nearly no CPU cost since it is 100% GPU-driven

~2ms to evaluate materials for all Nanite meshes

Small CPU cost with 1 draw call per material present in the scene.

When considering these GPU times together, it's approximately 4.5ms combined for what would be equivalent to Unreal Engine 4's depth prepass plus the base pass. This makes Nanite well-suited for game projects targeting 60 FPS.

Numbers like these should be expected from content that doesn't suffer from the aforementioned performance pitfalls in previous sections. Very high instance counts and large numbers of unique materials can also cause increased costs and is an area of Nanite development that is being actively worked on.

Data Size

Because of the micro detail that Nanite is able to achieve, it might be assumed that it means a large increase in geometry data resulting in larger game package sizes and downloads for players. However, the reality isn't that dire. In fact, Nanite's mesh format is significantly smaller than the standard Static Mesh format because of Nanite's specialized mesh encoding.

For example, using the Unreal Engine 5 sample Valley of the Ancients, Nanite meshes average 14.4 bytes per input triangle. This means an average one million triangle Nanite mesh will be ~13.8 megabytes (MB) on disk.

Comparing a traditional low poly mesh plus its Normal map to a high poly Nanite mesh, you would see something like:

Low Polygon Mesh

Triangles: 19,066

Vertices: 10,930

Num LODs: 4

Nanite: Disabled

Static Mesh Compressed Packaged Size: 1.34MB

Nanite Mesh

Triangles: 1,545,338

Vertices: 793,330

Num LODs: n/a

Nanite: Enabled

Static Mesh compressed package size: 19.64MB





The compressed package size isn't the entire size of the asset though. There are also unique textures only used by this mesh that have to be accounted for. Many of the materials used by meshes have their own unique textures made up of different Normal, BaseColor, Metallic, Specular, Roughness, and Mask textures.

This particular asset only uses two textures (BaseColor and Normal) and thus is not as costly on disk space as one with many other unique textures. For example, note the size of the Nanite mesh with ~1.5 million triangles is smaller in size (at 19.64MB) than a 4k normal map texture is.

Texture Type

Texture Size

Size on Disk

BaseColor

4k x 4k

8.2MB

Normal

4k x 4k

21.85MB

The total compressed package size for this mesh and its textures is:

Low Poly Mesh: 31.04MB

High Poly Mesh: 49.69MB

Because the Nanite mesh is very detailed already we can try replacing the unique normal map with a tiling detail normal that is shared with other assets. Although this results in some loss in quality in this case, it is fairly small and certainly much smaller than the difference in quality between the low and high poly version. So a 1.5M triangle Nanite mesh can both look better and be smaller than a low poly mesh with 4k normal map.

Total compressed package size for the Nanite-enabled mesh and textures: 27.83MB





There are plenty of experiments that can be done with texture resolution and detail normal maps, but this particular comparison is to demonstrate that the data sizes of Nanite meshes are not too dissimilar from data that artists are already familiar with.

Lastly, we can compare the Nanite compression to the standard Static Mesh format using the high poly, where both are identical at LOD0.

High Poly Static Mesh

Triangles: 1,545,338

Vertices: 793,330

Num LODs: 4

Nanite: Disabled

Static Mesh Compressed Packaged Size: 148.95MB

Nanite Mesh

Triangles: 1,545,338

Vertices: 793,330

Num LODs: n/a

Nanite: Enabled

Static Mesh compressed package size: 19.64MB

Comparing the Nanite compression from earlier with a size of 19.64MB is 7.6x smaller than the standard Static Mesh compression with 4 LODs.

Nanite compression and data sizes are a key area that will be improved in future releases of Unreal Engine.

General Advice on Data Size

Nanite and Virtual Texturing systems, coupled with fast SSDs, have lessened concern over runtime budgets of geometry and textures. The biggest bottleneck now is how to deliver this data to the user.

Data size on disk is an important factor when considering how content is delivered — on physical media or downloaded over the internet — and compression technology can only do so much. Average end user's internet bandwidth, optical media sizes, and hard drive sizes have not scaled at the same rate as hard drive bandwidth and access latency, GPU compute power, and software technology like Nanite. Pushing that data to users is proving challenging.

Rendering highly detailed meshes efficiently is less of a concern with Nanite, but storage of its data on disk is now the key area that must be kept in check.

Visualization Modes

Nanite includes a number of visualization modes to inspect its data in the current scene.

In the Level viewport under the View Modes dropdown, hover over Nanite Visualization and choose from the selection.



The Overview visualization displays the rendered scene in the center of the image with select Nanite visualizations around the screen for reference.



The following Nanite visualization modes are available to choose from:

Nanite Visualization

Description

Mask

Visualization that marks Nanite (green) and Non-Nanite (red) geometry.

Triangles

Displays all triangles of the Nanite meshes in the current scene.

Clusters

Displays colored representations of all grouping of triangles being rendered in the current scene view.

Primitives

Visualization that colors components all the same color for all instances in an Instance Static Mesh (ISM).

Instances

Visualization that applies a different color for each instance in the scene.

Overdraw

Displays the amount of overdraw happening for scene geometry. Smaller objects that are closely stacked together create more overdraw than larger ones.

Material ID

Displays separate colors for each Material ID of individual Nanite meshes.

Lightmap UV

Visualization that displays the UV coordinates of Nanite mesh surfaces.

Evaluate WPO

Colors Nanite-enabled geometry that are using world position offest (green) versus ones that are not (red).

Nanite includes an Advanced visualizations mode that enables additional visualization options in the Nanite Visualization menu. These visualizations are useful for programmers who are debugging or profiling various low level aspects of Nanite.

Enable this advanced visualization mode with the console variable r.Nanite.Visualize.Advanced 1.

Console Variables and Commands

The following stats and console variables are available for use in debugging and configuring Nanite.

Nanite rendering can be enabled and disabled globally at runtime using the console variable r.Nanite 0. Disabling Nanite is a good way to emulate platforms where it is not supported.

Nanite Fallback Rendering Modes

Nanite provides fallback mesh rendering modes for when Nanite is either disabled or unsupported by a platform. You can control which mode is used with the console variable r.Nanite.ProxyRenderMode.

0 is the default mode and falls back to rendering fallback meshes, or screen space-driven LODs, if set. This includes the recognition of Min LOD in the Static Mesh Editor properties (described in the Fallback Mesh section above).

1 disables all rendering of Nanite-enabled meshes.

2 works similarly to mode 1 but allows the Show > Nanite Fallback visualization in the Static Mesh Editor to render a Nanite fallback.

The Fallback render modes 1 and 2 are useful for scenes that have far more instances than could possibly be supported without Nanite. They allow the scene to be opened in the editor on non-Nanite-supporting platforms.

For example, in the Unreal Engine 5 Valley of the Ancients sample project, disabling Nanite would cause there to be tens of thousands of regular draw calls happening, making it difficult to open the map on a non-supporting platform.

Nanite Stats Command

The command Nanitestats adds an overlay of Nanite culling statistics to the top-right of the viewport.

Command arguments are used to specify what stats Nanite displays on screen. When no argument is provided, the primary view is used.

Use Nanitestats List to show all available views in the debug output:

Primary

VirtualShadowMaps

You may also see other stats available for ShadowAtlas and CubemapShadows when available. Select a view by entering the command followed by that stat list name you want to view. For example, you would enter NaniteStats VirtualShadowMaps.

For views that use two-pass occlusion culling, the statistics are split into separate buckets for Main and Post pass.

Controlling Nanite Streaming Pool Size

Control the amount of memory dedicated to holding Nanite streaming data with the console variable r.Nanite.Streaming.StreamingPoolSize. Using larger pools reduces IO and decompression work when moving around the scene but at the cost of a larger memory footprint.

If the pool is not large enough to fit all the data needed for a view, cache thrashing can occur where streaming never settles even for a static view.

This console variable cannot be changed at runtime and must be specified in a configuration (.ini) file.

Setting Maximum Clusters in a Single Pass

You can specify the maximum number of candidate and visible clusters used in a single pass with the console variable r.Nanite.MaxCandidateClusters and r.Nanite.MaxVisibleClusters. Their values are used for sizing intermediate buffers and their default values have been chosen to work for common rendering scenarios.

There is no mechanism for dynamically resizing either of these buffers, or automatically scaling down quality on overflow, which can result in rendering artifacts from them being too small for scene complexity, and typically manifesting as missing or blinking geometry. When these types of artifacts occur, use Nanitestats to determine conservative bounds for candidates and visible clusters. More specifically, look at the stats for ClustersSW and ClustersHW. The memory cost of a candidate cluster is currently 12 bytes and a visible cluster is 16 bytes.

This console variable cannot be changed at runtime and must be specified in a configuration (.ini) file.

Knowing Your Performance Budget

Console Commands for Displaying Performance Stats

Common Performance Factors

Best Practices for High-Resolution Normal Maps

Draw Calls

Reducing Mesh Count

Reducing Material ID Count

Materials

Optimizing Texture Resolution

Package Size and Boot Time

Recommended Streaming Settings

Recommended Packaging Settings

Analyzing Package Size on Disk

Size Map

Statistics

Memory Reports

Analyzing Boot Time

This page provides guidelines and best practices for how to identify and optimize performance while getting the best possible fidelity from real-time rendering features.

In this page, you'll learn:

What factors contribute to your performance budget

Best practices for packaging projects

Walk through of available toolls to guage performance bottlenecks

Knowing Your Performance Budget

When developing your project, the target platform for your application has a finite amount of resources available, both for keeping objects in memory and processing them. When building your project, you must decide what to spend those resources on. Being familiar with the platform's capabilities in terms of speed, threads, and bandwdith for your CPU and GPU, as well as potential memory, graphics memory, and available disk space are all important factors to consider.

It is also important that you benchmark your project against any platform you intend to ship on to understand how it will run and where it will encounter performance bottlenecks. You can benchmark a platform or device by running a demanding application or technical demo on it, then observcing its performance stats. It's important to test and benchmark your own projects on a regular basis in this same manner.

Console Commands for Displaying Performance Stats

You can check performance statistics using a series of console commands while running your project. These can be entered through the console window when the project has been launched or has been packaged as a Development build.



The console window displayed in a mobile application.

The console and the four-finger tap command are only available in Development builds. It is not available in Shipping or Testing builds.

Within the console, you can enter commands to display debug information to the screen. The following table includes a list of commands that provide performance information:

Command

Description

Stat GPU

Displays the amount of time in milliseconds used by the GPU for different processes.

Stat Unit

Displays the amount of time in milliseconds used by the CPU for different processes. Also displays the game thread, rendering thread, and GPU times.

Stat UnitGraph

Displays a graph showing CPU and GPU utilization over time. This can help identify spikes.

Stat TextureGroup

Displays the amount of memory used by different pools of textures.

For more console commands you can use to analyze your application's performance on-device, refer to [Stat Commands]().

Common Performance Factors

Having identified where to look for performance data, this section will familiarize you with some common factors that most often affect performance. By understanding which of these elements is impacting your project and how, you can start to identify and address them using engine's built-in diagnostic tools.

Best Practices for High-Resolution Normal Maps

Baking high-resolution vertices into a normal map for a low-poly model can be a complex process, and many factors can reduce the quality of a normal map texture by the time it is inside the engine. There are many tool sets for baking normal maps, but we recommend XNormal. The process we use for Xnormal is roughly as follows:

Bake the normal map in Xnormal as an 8k TIFF with 4xAA.

Import the TIFF into photoshop, then downres it to a 1k texture.

Apply a Guassian Blur with a value of .35px.

Convert the image from 16-bit to 8-bit.

Export the image to a 24-bit TGA.

Import the final normal map into Unreal.

To ensure the surface normals used in the baking process are the same as what is present in the engine, you should export the optimized normals from inside Unreal. Import the baking model into Unreal, choose to create its own normals, then export the baking model from Unreal to be baked in Xnormal. This is an important step when creating high quality normal maps, as Xnormal needs to be aware of the surface normals of the mesh to apply the offsets from the high resolution model.

Finally, there are two options that will reduce artifacts when rendering static meshes:

Use Full Precision UVs

Use High Precision Tangent Basis

Both of these settings are available in the Static Mesh Editor in the Details panel under the LODs section.



Draw Calls

Draw calls are lookups for assets, which happen every frame. The number of draw calls your application uses depends on the number of unique meshes in your scene, as well as the number of unique material IDs each mesh is using. Currently, a high number of draw calls are the biggest contributor to low graphical performance, and you should reduce them as much as possible.

As an example, a highly optimized car model might only have five or six separate meshes, and each one of those components might only have a single material.

A good target for draw calls in an optimized scene is roughly 700 on a Galaxy Tab S6, and less than 500 on lower-end hardware. In projects for HMI, which tend to use highly unique or complex materials, 100 draw calls would be a good target on a Galaxy Tab S6, while less than 50 would be preferable.

You can output your draw call count with the console command Stat RHI.

Keep in mind that draw call count will change based on whether you are in PIE or on device. |

The easiest way to reduce draw calls is to reduce the number of unique meshes being rendered in the world. This can be done in a couple of ways: using built-in tools in the engine to combine meshes, and using visibility culling.

Combining Unique Meshes

Meshes can be combined manually using an external DCC application, like a modeling program.

Alternatively, in-editor world building tools like Hierarchical Level of Detail meshes can be generated in the level automatically by combining meshes and textures to reduce draw calls.

Visibility Culling

The engine uses multiple methods of Visibility and Occlusion culling to reduce the number of meshes being rendered. Cull Distance Volumes are placed volumes that can remove additional meshes specified by their size and distance from the player camera.

There are several possible options for reducing the number of unique materials on a mesh.

The simplest method is to use a program like Substance Painter, which integrates multiple materials into the same texture. This enables you to take advantage of a vast number of material types in a very simple Unreal material, which you can then use as the basis for Material Instances with simple texture inputs. This can also reduce material instruction counts, which further improves performance.



The second method uses masking for a more procedural approach. Materials can denote certain characteristics of a surface, like color, roughness, or metallic qualities. Instead of using a separate material for different parts of a mesh, you can use masks to separate parts of a mesh's UVs and apply different settings to each section. You can create a basic mask using a black and white texture, but it is more efficient to use Vertex Color.





In the example below, vertex colors are used to define different material types, and the material defines parameters which can influence the look of those pieces individually. Vertex color masking is more efficient and creates a sharper separation, as it does not rely on texture resolution.



A material using vertex colors to separate different material types.

Materials

The complexity of a material can increase the pixel cost of a rendered frame. The more material instructions there are for each pixel, the more time the render needs to spend calculating its final value. Opaque materials are the least expensive but can differ greatly based on the shading model or the base shader code.

You can find a readout on the instruction count of a material in the Stats window inside the Material Editor.



The Stats window displaying instruction count.

The instruction count will also increase depending on the number of math functions there are in a material. The more nodes there are, the more expensive the material will be to render. Some specific operations also have a higher cost. Try to limit the instruction count when building more complex materials.

Translucent materials are some of the most expensive material types. Individual layers of translucency have an expensive per-pixel cost, and when multiple layers of transparency are stacked and rendered, there is a much greater cost. This is known as overdraw.

Head lights and tail lights for vehicles are examples of problem areas with transparency. In many cases, hand-painted texture maps are used to reduce material complexity. Complex shapes and depth can be illustrated well, even with a flat texture.



Optimizing Texture Resolution

There are couple of ways you can go about optimizing textures for your project. You can use the built-in Virtual Texturing which enable you to use nearly any size texture and only render the parts that are needed on screen, or you can use standard texturing methods.

For standard textures not enabled as a virtual texture can require a lot of space, both to be stored in memory and on disk, especially for high resolution textures. While they can increase fidelity, there are diminishing returns to texture size given the screen resolution and viewing angle of the texture. It is important to use the smallest texture possible to obtain the desired level of fidelity.

To determine your texture needs, first you need to finalize the camera location and the field of view (FOV) from which you will view your model. This helps determine the screen space of all the meshes and materials to be used.

Once the camera location is determined, you can use a special debug texture that examines mipmaps to determine the texture resolution to use for various materials. Using a debug mipmap texture is useful for determining what resolution is necessary for different components, applying different colors to each mipmap. This makes it clearer to identify which mip the material is using, and what texture resolution it should be.

When creating a test material, plug the mipmap debug texture into the Emissive channel of an Unlit material, then apply that material to your mesh. When viewing the mesh from a proper camera distance, the color coding will indicate which mip level the engine is using to render. The highest level observed should be the native texture size of your Normal and Ambient Occlusion maps.



Example of a mesh with a debug mipmap material applied.

Package Size and Boot Time

When packaging an Unreal Engine project and its assets, there is a tradeoff between package size on disk and runtime bootup performance.

When ZLib compression is enabled, the package size of your application will be smaller. However, this requires more CPU time loading the application, which can slow down bootup speed. For optimal boot time, you can disable compression.



You can find Zlib compression settings in Project Settings > Packaging.

Recommended Streaming Settings

The following streaming settings are recommended in DefaultEngine.ini. These provide extra time at the start of an application for asynchronous loading of assets, which can improve startup time.

Recommended Packaging Settings

The following packaging settings are recommended in DefaultEngine.ini. These settings reduce the amount of compression being utilized when packaging assets, as uncompressed .pak files load significantly faster than ZLib compressed files on startup.

Analyzing Package Size on Disk

Unreal Engine features several useful tools that can provide insight into the data footprint of assets.

Size Map

The Size Map reads and compares the relative memory consumption of assets in the editor. To use it, you must enable the AssetManagerEditor plugin. After that, you can access it by right-clicking on a folder in the Content Browser and selecting Size Map from the context menu.



The Size Map displays a window with icons representing the amount of memory that folders and files consume. The larger the icon, the more space a file consumes.



For more information about using the Size Map, refer to Cooking and Chunking.

The Size Map reads the footprint of assets as they are used within the editor. After you package your project, memory consumption will be different. This is due to the different types of compression which happen during the cook process. As a rule of thumb, the size map will represent the largest possible size that an asset could take up.

Statistics

The Statistics tool offers more detailed information about asset usage within a Level. You can locate it in the Window main menu.



The Statistics window breaks down the number of assets in your level files, and can display either all levels or only specific levels. Primitive Stats lists information about the number of triangles, memory consumption, and count.



The Statistics Window displaying Primitive Stats.

Other data displayed in this list includes texture usage and static mesh lighting information. The Statistics window's list mode can quickly illustrate which assets are consuming the most memory. The Cooker Stats data is also extremely useful as it lists all the assets which were cooked in the last package process.

Memory Reports

While the Statistics and Size Map tools show you the data footprint of your files inside the Unreal Editor, the console command Memreport -full can be used from an installation of your application launched on a target device. This provides a detailed and accurate look at your files' size as they will exist with your device's compression settings.

Once the app is built in Development configuration and loaded to the device, you can pull up the console window and enter the command. This memory snapshot is saved within the project's directory, on the device. The directory will usually be UE5Game/[YourApp]/[YourApp]/Saved/Profiling/Memreports/, but this can vary.

The .memreport file is a text file which can be read in most text editors. The beginning of the text includes some information about the allocated memory and pool sizes, while the bulk of the text shows a record of what levels were loaded, RHI stats, render targets, scene information, and more. All of this information is valuable as it represents the actual data which made it through the cooking and packaging process.

If you search for the term Listing all textures, you will find a list of every texture in your application, along with detailed information about the texture type, group, size, and memory footprint. The list is sorted by memory size, with larger textures presented first. This is a quick and easy way to spot what textures are consuming the most memory.

Analyzing Boot Time

The factors that affect boot time include:

The amount of time required to load and decompress initial assets

The overall size of your application

Any plugins that need to be activated in your user's installation

The amount of string data that needs to be parsed

Any memory allocation or fragmentation on the user's device

There are several different tools available to analyze your application's boot time, but Unreal Insights is the most recommended, as it can profile performance data remotely from a target device. For full information about this toolset, refer to the Unreal Insights section.

Installing RenderDoc

Enabling RenderDoc Plugin

Performing a Frame Capture

RenderDoc Plugin

RenderDoc Application

Project Settings

Additional Notes and Resources

RenderDoc is a free standalone open-source graphics debugger that you can use to perform single-frame captures of an application, such as Unreal Engine. The capture is loaded into RenderDoc to inspect what is happening on the GPU through the events, API, and much more, in full detail.

Installing RenderDoc

RenderDoc is an open-source graphics debugger that is free, and available to download and install from RenderDoc.org.

The list of supported operating systems and APIs below reflect what RenderDoc currently supports, which may differ from what Unreal Engine supports. For the latest updates, see RenderDoc's FAQ page.



Supported Operating Systems



Windows 7 and 10

Linux

Android

Google Stadia

Nintendo Switch



Supported APIs



Vulkan

D3D11

D3D12

Open GL3.2+

Open GL ES 2.0 - 3.2

Enabling RenderDoc Plugin

The RenderDoc plugin does not need to be enabled to use RenderDoc with an Unreal Engine project. The standalone RenderDoc works with the UE executable. See RenderDoc Documentation to follow their setup guide.

Unreal Engine 4 provides a plugin that makes it easy perform a next-frame capture from within the Editor and automatically open that in RenderDoc. Use the steps below to enable it in your project:

Navigate to the main menu and select Edit > Plugins to open the Plugins browser.

You can find the RenderDoc Plugin under the Rendering category, or simply use the search bar at the top of the Plugins browser window.



Place a check in the box next to Enabled, and when prompted, restart the editor.

Once the Editor restarts, the Level Viewport will contain a new UI button on the top right. You can use this to perform a capture.



Performing a Frame Capture

The steps below describe at a high level how to perform a single-frame capture with your Unreal Engine project using the integrated RenderDoc plugin or directly from RenderDoc application.

Further details on functionality and use of RenderDoc can be found in RenderDoc Documentation.

RenderDoc Plugin

The following steps are used to capture a frame using Unreal Engine's RenderDoc Plugin:

Enable the RenderDoc plugin for your project.

Open your project and scene where you want to perform a capture.

Click the RenderDoc Capture button in the Level Viewport.





Click image for full size.



RenderDoc Application

The following are the high-level steps required to capture a frame using Unreal Engine with the standalone RenderDoc executable:

Configure RenderDoc to launch your game or the UEEditor.exe with the appropriate command line arguments.

Enable Capture Child Processes when launching with the UEEditor.exe.

Launch the executable.

Press the F12 hotkey to perform a frame capture.

For full details on setting up RenderDoc, launching an application and performing a frame capture, see the RenderDoc Getting Started Guide.

Project Settings

Use the Project Settings window to set additional RenderDoc Plugin settings. From the main menu, select Edit > Project Settings and then under the Plugins category, select RenderDoc.



Property

Description



Frame Capture Settings



Capture all activity

When enabled, RenderDoc captures all activity in all viewports and Editor windows for the entire frame instead of only the current viewport.

Capture all call stacks

When enabled, RenderDoc captures call stacks for all API calls.

Reference all resources

When enabled, RenderDoc includes all rendering resources in the capture, even those that have not been used during the frame.

Enabling this property will significantly increase capture size.



Save all initial states

When enabled, RenderDoc always captures the initial state of all rendering resources, even if they are not likely to be used during the frame.

Enabling this property will significantly increase capture size.





Advanced Settings



Show help on startup

When enabled, a help window with RenderDoc is shown on Editor startup.

Use the RenderDoc crash handler

If enabled, the RenderDoc crash handler is used if a crash occurs.

This should only be used if you know the problem is with the RenderDoc application and would like to notify the RenderDoc developers.



RenderDoc executable path

Sets the path to the RenderDoc executable to use.

This should automatically fill in when with the correct path when RenderDoc is installed.



Additional Notes and Resources

See RenderDoc Documentation for further reading on RenderDoc use and analysis of frame captures.

The RenderDoc Plugin was created and developed by Fredrik Lindh ("Temaran") for Unreal Engine. For additional information, see the RenderDoc GitHub respository.



Modern games need to run on a wide range of hardware and need to adapt the game performance for various needs, such as split screen or some special gameplay mode. Tuning the game's graphics is generally the easiest to scale without affecting gameplay much.

The following sections will describe the features Unreal Engine implements for scalability, how to use them, and the things different disciplines of developers should be aware of.



An overview of Scalability options and considerations for content creators, testers, programmers, and managers.



Scalability options, properties, and console variables.

General

Artists and Designers

QA

Programmers

Leads, Producers, and Managers

Scalability is more than just graphics settings, it is about choosing a target platform and making decisions about art, gameplay, sound, AI, and any number of other systems, to fit that platform. For consoles, the platform is fixed, and this is more straightforward. However, for the PC, the number of different equipment combinations makes it impossible to focus on a single hardware specification.

This is where the Scalability options come into play, but even before they need tweaking, the individual developer can do a lot to make sure the application they are producing will run on their chosen minimum specification.

General

Different machines can have different performance/memory/quality characteristics such as:

Hard drive size/latency/bandwidth

Main memory size/latency/bandwidth, running 32bit instead of 64bit can limit this further

CPU (one or more main processors, hyper-threading, SSE features, branch prediction)

GPU (memory, Multi GPU, bandwidth, features, shared memory)

Resolution (modern notebooks have high resolution displays but slow GPUs)

Graphics is generally the easiest to scale without affecting gameplay much. The players generally accept the concept of scalability but only very few actively go to the options menu and adjust them properly. Option screens are often overwhelming in quantity of options and full of intimidating names. Still, there are options to give the player control over a lot of decisions that are subjective and have tradeoffs:

Frames per second

Resolution

Image quality

Motion Blur

Texture details

Flickering (anti-aliasing)

Battery life

Artists and Designers

Unreal Engine gives a lot of power into the hands of content creators and with that comes a responsibility. Performance and memory requirements are directly connected to content count and quality. This is a very complex problem:

Content is often created without the target hardware.

A complex matrix of hardware properties (low memory but fast, fast GPU but slow CPU).

The engine code is still under development and optimized on needs driven by content.

New hardware and drivers change the equation.

Development time constraints limit optimization efforts.

In order to make this manageable, it is best to have some good practices:

Plan and verify budgets (triangle/object/material/light count, texture/mesh/sound memory, ...).

Add scalability options to non-gameplay relevant content, test with lower and higher settings.

e.g. hide clutter objects on lower spec, use simpler material shading, object level of detail.

Restrict player abilities.

e.g. visibility blocker, cannot build arbitrary complex structures, limit destruction.

Understand performance characteristics.

e.g. many dynamic objects with many point lights, mesh particles vs. sprite particles.

Mix different components in similar ratios (some hardware might be only slow in some feature) bad: many objects simple material, few objects many lights with complex materials.

Understand in-engine profiling tools.

QA

A wide range of scalability costs more QA time. A few good practices can help:

Document low/recommended/high spec.

Test on a wide matrix (low/med/high GPU, low/high CPU, low/high memory).

Define performance levels on reproducible scenes.

Document and communicate changes over time.

Disabling stuff is a powerful way to isolate a performance issue (e.g. show console command).

If you run in lowest quality settings and something looks quite better than expected - it might miss a scalability setting (fixing this could mean more players can enjoy the game).

Test usability of the scalability: report anything if you find it confusing and wrong.

At any time the user interface should be readable and functional. Please test low resolution and lowest quality settings and look for unreadable fonts and elements outside of the screen.

If some artifact only happen at some specific scalability level (e.g. only on "low") you can isolate the issue further (e.g. shadows are likely affected by "shadow quality") going down to the actual console variable setting (look into Scalability.ini file).

Know how to quantify performance (stat fps, stat unit, ...), milliseconds are more useful than fps ("it became 10fps faster" is not meaningful but "it became 5ms faster" is).

Some notebooks have multiple GPUs (e.g. Intel HD4000 integrated graphics to save battery and NVIDIA 580m for performance). By default, you want to run on the faster GPU but it is best to run test both (use the driver setting to change that). When running on battery, it might pick the slower one or even switches it at runtime.

Programmers

A player might have an advantage seeing the shadow of a player earlier or having a higher frame rate gives you a faster response time. Staying within the offered scalability settings is not cheating but some scalability settings could be abused to cheat. A console variable might offer a wider range of values than needed for the scalability or a combination of console variable settings can lead to problems. Some multiplayer games address that by giving control to the server administrator overriding problematic setting to offer all players the equal chances.

Example: Hiding in deep grass can be a good gameplay tactic. However, if grass is no longer rendered in larger view distances this can feel very unfair to the player trying to hide.

Ideally no scalability setting would affect gameplay.

Leads, Producers, and Managers

What managers/leads should know? Developing a game that needs to scale to a wide range of hardware is harder; it costs more time and QA efforts. A few good practices could help:

Define a low Spec and a recommended Spec early in the project development.

A good "auto" feature is important as most players never use the options menu. To get this feature right, you need a lot of iterations and testing.

A smaller scalability range makes development easier (bad: High end PC to low end mobile).

Having a second low Spec machine can help in every discipline (code, design, and art). When balancing tasks, it is generally better to optimize than to create more scalability.

Performance is one part of scalability but it also can affect stability. E.g. If you run out of memory on a lower Spec, it might be best to grey out the high resolution texture option.

Scalability on low end means more players can play the game. Scalability on high end means the game can look better, especially in screenshots and tests.

Scalability Settings

Resolution Scale

View Distance

Anti-Aliasing

Post Processing - sg.PostProcessQuality

Shadows - sg.ShadowQuality

Textures - sg.TextureQuality

Effects - sg.EffectsQuality

Detail Mode

Material Quality Level

Skeletal Mesh LOD Bias

Grass and Foliage Scalability

Customizing Scalability Settings

The Scalability settings allow you to adjust the quality of various features in order to maintain the best performance for your game on different platforms and hardware.

Scalability Settings

Accessing the Scalability settings in the editor is done through the Settings menu in the toolbar. The Engine Scalability Settings contains shortcuts to the most commonly used setting defined in the BaseScalability.ini file, while Material Quality Level sets the global material quality setting.



Resolution Scale

Unreal Engine 4 can render a scene in lower resolution and scale the image up to the target resolution. As 2D User interfaces usually costs less performance and suffers more from lower resolution, Unreal Engine 4 does not apply this technique to UI. There is a minor cost for the up-sampling pass, but usually, it is worth the effort.



Left: 50% no AA, Middle: 50% with AA, Right: 100% (no resolution scale) with AA

Having a softer input image helps the up-sampling step. This means this scalability options benefits from another scalability option: the anti-aliasing quality.

This setting can be accessed with the r.ScreenPercentage console variable. It takes in a value from 10-100 with -1 also equaling 100%.

View Distance

Objects can be culled based on their distance to the viewer. By default, all objects are not distance culled (Desired max draw distance of 0). On top of the designer specified value, there is a global scalability setting working like a multiplier (r.ViewDistanceScale). Here you can see some grass objects (Desired max draw distance of 1000):



left: r.ViewDistanceScale 0.4, middle: r.ViewDistanceScale 0.7, right: r.ViewDistanceScale 1.0 (default)

Anti-Aliasing



From the left: r.PostProcessAAQuality 0 to 6. The first 3 equal the Low, Medium, High, Epic settings in the View -> Scalability Options -> AA settings.

Adjusting the Anti-Aliasing quality level using the r.PostProcessAAQuality console command will adjust the quality of whichever Anti-Aliasing method you are using (FXAA or Temporal AA). For either Anti-Aliasing method, a value of 0 used with r.PostProcessAAQuality will disable the effect. For FXAA, the effect of values 2, 4, and 6, can be seen in the above image; the smoothing of jagged edges becomes better and better. Values above 6 have no effect.

For Temporal AA, there is a trade off between fill speed of the effect and quality, the higher the value you use. r.PostProcessAAQuality 2 with Temporal AA is fast to settle but jitter caused by the effect will be more pronounced. r.PostProcessAAQuality 4 will settle slower but will not jitter.

Post Processing - sg.PostProcessQuality



sg.PostProcessQuality set from 0 on the left to 3 on the right.

The View -> Engine Scalability Settings -> Post Processing option adjusts the quality of the Post Processing effects in accordance with the settings found in the BaseScalability.ini file located in [UE_InstallPath]/Engine/Config folder. With the Low setting equating to sg.PostProcessQuality 0 and Epic to sg.PostProcessQuality 3.

sg.PostProcessQuality 0

sg.PostProcessQuality 1

r.MotionBlurQuality=0

r.MotionBlurQuality=3

sg.PostProcessQuality 2

sg.PostProcessQuality 3

r.MotionBlurQuality=3

r.MotionBlurQuality=4

Shadows - sg.ShadowQuality



sg.ShadowQuality set from 0 on the left to 3 on the right.

The View -> Engine Scalability Settings -> Shadows option adjusts the quality of dynamic shadows in accordance with the settings found in the BaseScalability.ini file located in [UE_InstallPath]/Engine/Config folder. With the Low setting equating to sg.ShadowQuality 0 and Epic to sg.ShadowQuality 3.

sg.ShadowQuality 0

sg.ShadowQuality 1

r.LightFunctionQuality=0

r.LightFunctionQuality=1

sg.ShadowQuality 2

sg.ShadowQuality 3

r.LightFunctionQuality=1

r.LightFunctionQuality=1

Textures - sg.TextureQuality

A modern rendering engine requires a lot more GPU memory (textures, meshes, GBuffer, Depth Buffer, Shadow maps). Some of those scale with the screen resolution (e.g. GBuffer), others with specific quality settings (e.g. Shadow maps). Another large amount comes from the used textures (usually compressed and streamed). You can instruct the streaming system to be more aggressive in management (smaller pool size, culling unused textures) or to have less or more detail in the mip level computation. This can have effects on the image quality, how much you can notice texture streaming artifacts and how smooth the game runs (updates require expensive memory transfers). The results can vary, depending on the media (e.g. faster/lower hard drive /SSD). Streaming from a DVD/Blu-Ray adds much more latency so you should try to avoid that.

The texture quality also affects the texture filtering mode (r.MaxAnisotropy). Limiting the anisotropic sample count reduces texture bandwidth, but does not save texture memory.

sg.TextureQuality 0

sg.TextureQuality 1

r.Streaming.MipBias=2.5

r.Streaming.MipBias=1

sg.TextureQuality 2

sg.TextureQuality 3

r.Streaming.MipBias=0

r.Streaming.MipBias=0

The effect of this feature is heavily dependent on your game and hardware. If you do not have many textures, to the point where loading and using the full resolution mip maps does not use all of the memory pool Unreal Engine 4 has devoted to textures, you will not actually see a difference between high and low settings (outside of the change to the Anisotropy settings).

Effects - sg.EffectsQuality

The View -> Engine Scalability Settings -> Effects option adjusts the quality of many different types of effects in accordance with the settings found in the BaseScalability.ini file located in [UE_InstallPath]/Engine/Config folder. With the Low setting equating to sg.EffectsQuality 0 and Epic to sg.EffectsQuality 3.

sg.EffectsQuality 0

sg.EffectsQuality 1

r.TranslucencyLightingVolumeDim=24

r.TranslucencyLightingVolumeDim=32

sg.EffectsQuality 2

sg.EffectsQuality 3

r.TranslucencyLightingVolumeDim=48

r.TranslucencyLightingVolumeDim=64

Detail Mode

Each placed Actor has a Detail Mode property in the Rendering category. Essentially this setting defines the minimum detail level for an Actor to render.



The scalability mode can be changed from the console:

With r.DetailMode 0 = low, r.DetailMode 1 = medium and, r.DetailMode 2 = high detail modes.



It is easy to use this to disable decals, detail objects, lights or individual particle effects. Make sure to only use this on objects that have no effect on gameplay, otherwise, you will run into problems with network gameplay, save games, or consistency.

Material Quality Level



Materials can use the Quality Switch Material Expression node to disable some expensive Material parts that have a minor effect on the final look. To see the effect of this, you need to toggle to the Low Quality mode.



Whatever the Material Quality Level is set to, low or high, will determine which expressions get evaluated for this material (the low or high pin). The default pin will fill in either high or low (or both) if they have no inputs. This material contains 2 reasonably high-cost Perlin noise operations when set to high:

This example is to simply show off the Material Switch Node. The Noise nodes are really expensive making them really good for this example, but they should be used sparingly as there are cheaper ways to get this effect.

Material Quality Level -> Low

Material Quality Level -> High





Above, Shader Complexity mode shows us that our high quality material is more costly than other shaders, with darker greens meaning more costly shaders.

Using the quality switch causes more shaders to be compiled (shader permutation).

This feature is not for distance LOD as you cannot have two quality levels at the same time. The feature can be used to reduce:

Shader computations (e.g. disable fuzz layer).

Use Shader Complexity (Alt+8 in the editor) mode and instruction count to verify your optimization.

Texture lookups (e.g. no detail bump map).

Memory bandwidth (e.g. using fewer textures).

You would need to profile on actual hardware to verify this.

Most material editor outputs only affect the pixel shader. World position offset and all tessellation outputs affect the other shader types. Pixels shaders only cost a lot if they occupy large portions of the screen (skybox for example), while other shaders only matter if the object is not culled (inside the view, not hidden behind opaque objects).

Skeletal Mesh LOD Bias



Skeletal meshes can have static Level of Details models. With the console variable r.SkeletalMeshLODBias, it is possible to globally bias the LOD level. Depending on the quality of your first or second LOD, it might be a good idea to have this option in the scalability settings. Here you can see the scalability setting on top of the distance dependent LOD.

Grass and Foliage Scalability

The View -> Engine Scalability Settings -> Foliage option adjusts how many foliage meshes are rendered at one time in accordance with the settings found in the BaseScalability.ini file located in [UE_InstallPath]/Engine/Config folder. With the Low setting equating to FoliageQuality 0 and Epic to FoliageQuality 3.

For Foliage Static Meshes to work with the Scalability settings you must enable the Enable Density Scaling option. You can read more about how to set this up in the Foliage Instanced Meshes documentation.

FoliageQuality 0

FoliageQuality 1

[FoliageQuality@0]

[FoliageQuality@1]

FoliageQuality 2

FoliageQuality 3

[FoliageQuality@2]

[FoliageQuality@3]

Customizing Scalability Settings

You can customize any of the Scalability Settings that are used in your Unreal Engine project. In the following example we will add and the change the Scalability Settings for the Foliage by doing the following:

Go to your projects Config folder and create a new .INI file called DefaultScalability.ini.



Open up the newly created DefaultScalability.ini file and add the following lines of code to it.

Save the file and now when the Scalability settings for Foliage are changed, the amount of Foliage and Landscape Grass Static Meshes that are spawned will be reduced or increased based on which setting was picked.

Primary Screen Percentage

Spatial Upscale Quality

Temporal Anti-Aliasing Upsample

Enabling Temporal Upsample

Additional Examples

Automatic View Texture Mip Bias

Shader Performance Permutations for Anti-Aliasing Quality

Material Improvements

View Size and Render Target Size

Screen Position High-Precision Pixel Position Output

Post Process Material after Temporal Upsample

Secondary Spatial Upscale

DPI Editor Viewport Scaling

VR Pixel Density

Screen Percentage is a resolution scaling technique used to render a lower or higher resolution image than what is actually being presented. Being able to adjust the screen percentage enables your games to maintain a balance between performance and image resolution quality.

Prior to Unreal Engine 4 (UE4) version 4.19, you only had to change the screen percentage, but it has now been split into two types of scaling during the rendering pipeline: Primary and Secondary Spatial Upscaling.

Primary Spatial Upscaling is the same screen percentage that has been used previously. It is based on the idea of rendering a frame at a lower resolution and then upscaling it before the user interface (UI) is drawn.

Secondary Spatial Upscaling does a second and final spatial upscale pass, independently of the Primary upscaling pass.

Primary Screen Percentage

The Primary Spatial Upscale (or primary screen percentage) works by rendering the screen resolution at a percentage of the screen and then scaling it to fit your current screen resolution. Using a lower screen percentage (or lower resolution) and then upscaling it is called upsampling. Or, when the screen percentage is increased (rendering at a higher resolution), it is scaled down to your current screen's resolution, which is called super sampling. All of this takes place before the user interface (UI) is drawn and can have an impact on performance.

The conceptual idea of how screen percentage works for all the buffer render targets that make up the image rendered on screen for a single GPU frame can be shown as follows:



For each GPU frame, all the render targets use their full resolution throughout the pipeline.



With Spatial Upscaling, anything drawn before the UI is at a lower or higher resolution based on the Screen Percentage used. The screen percentage has been lowered (indicated by the narrower render targets before UI), creating a lower resolution image for the render targets. Spatial Scaling happens before the UI, scaling the image to the screen resolution it will be output to. For example, if the current resolution is set to 1920x1080 and a screen percentage of 83% is used, the render targets will be resized to an approximate resolution of 1600x900 before being upscaled back to 1920x1080.

Spatial Upscale Quality

When upscaling the render targets, the quality of the upscale can be defined by using the following console variable:

It controls the quality in which screen percentage and Windowed Fullscreen mode scales the 3D rendering.

Upsample Quality Value

Upsample Result

0

Nearest Filtering

1

Simple Bilinear

2

Directional blur with unsharp mask upsample

3

5-tap Catmull-Rom bicubic, approximating Lanczos 2 (default)

4

13-tap Lanczos 3

5

36-tap Gaussian-filtered unsharp mask (very expensive, but good for extreme upsampling)

Alternatively, you can control how the tonemapper pass is handled by using the following console variable:

The tonemapper integrates a simple bilinear color space spatial upscale that can be used for performance reasons when enabled using a value of 1. However, if a Post Process Material is inserted after the tonemapper, the tonemapper won't do the upscale. It will fall back to using the primary spatial upscale as if it were disabled.

Temporal Anti-Aliasing Upsample

In addition to Primary Spatial Upscale, a second upscaling technique is also supported for the primary screen percentage: Temporal Upsample. Instead of performing temporal integration with the Temporal Anti-Aliasing (TAA) and then doing a primary spatial upscale, both happen at the same time in the Temporal Anti-Aliasing Upsample (TAAU) shader. It also allows them to converge to sharper images than what a spatial-only upscale could provide but comes at a higher cost since a larger number of post processes run at a higher resolution. It also allows for primary screen percentage changes to be hidden by dynamic resolution allowing it change more often to match the GPU budget as closely as possible.



TAAU happens earlier in the pipeline causing the passes that follow to render at a higher resolution, leading to higher costs with sharper images.

It should be noted that with the temporal upsample, the ordering of the different post processes has not changed with the addition of TAAU, it simply replaced TAA. The difference now is that any process before TAAU will use a lower resolution before being upsampled to the resolution after the TAAU pass. Before 4.19, the resolution was assumed to be the same everywhere in the post processing.

As the primary screen percentage decreases, the convergence to a clean full-resolution output changes. Therefore, some existing TAA artifacts would be more noticeable. For example, aliasing can become an issue for very thin geometry increasing the probability to miss this geometric detail as the primary screen percentage is lowering.

Enabling Temporal Upsample

To use Temporal Anti-Aliasing Upsample, you'll need to opt into the Project Setting for Temporal Upsampling or more simply by using the following console variable:

A lower primary screen percentage with spatial upscale can lose significant detail when using lower resolutions. For example, for something like a chain-link fence or the grill on the front of a car, the detail can become harder to see at farther distances when Temporal Anti-Aliasing is used. Enabling TAAU, this can be reduced while still using a lower screen percentage.





In the comparison, the primary screen percentage has been set to 70 and the camera has been moved to a far enough distance to effectively see how TAA affects high-frequency geometry and materials. The temporal upsample enables this detail to be seen, even when lower resolutions are used to maintain this detail as much as possible.

Additional Examples

In this first set of comparisons, a default scene that has only lowered the screen percentage is compared to one using the same screen percentage except it has the temporal upsample enabled. The difference may seem minute for these screenshots but on larger screens the areas with dense geometry or high-frequency textures can regain some lost detail, like with the fencing on the top of the house, or the tree fronds on the trees (close and far ones).





In this one, the default screen percentage of 100 without any temporal upsample can be compared to the lower screen percentage that is using temporal upsample. While some specular highlights and some material detail is lost, the temporal upsample does a really good job of maintaining geometry detail even though the screen percentage has been lowered.





Automatic View Texture Mip Bias

Because screen percentage causes geometry to render at a lower pixel density, temporal upsample requires more texture information from the Surface and Deferred Decal Material Domains to maintain the same output sharpness. For this purpose, the Texture Sample expression can use, by default, Automatic View Mip Bias.

The Texture Sample expression can use Automatic View Mip Bias to toggle whether the texture should be sampled with per-view Mip biasing for sharper output with Temporal Anti-Aliasing.



For high-frequency textures (like the example below), the automatic Mip bias can become problematic at lower screen percentages.



In this case, you can compensate with a Mip bias input, or opt-out of the Automatic View Mip Bias.



Automatic View Mip Bias only happens when TAAU is enabled. Normal Anti-Aliasing methods (TAA, MSAA, and FXAA) won't be able to use this option.

Shader Performance Permutations for Anti-Aliasing Quality

Like TAA, Temporal Upsample comes with faster shader permutations for Post Process Quality 3 and 4. The shader permutations are traded against some amount of quality to ship a title at 60Hz on consoles. The quality settings are similar to what is already used when setting Post Process Quality. Also, keep in mind that TAAU needs more work than TAA since it runs at a higher resolution along with the post processes that follow the TAAU pass.

The following console variable can be used to adjust the Post Process Quality:

It is worth noting that post processing after temporal upsampling runs at full resolution, so disabling TAA will make them run at a lower resolution because they will be spatially upscaled at the end making post processing faster as a result. Use the command profileGPU to investigate the breakdown of GPU performance per pass, what passes are being used, and where most of the budget is spent.

The table below is an indication of what you could expect when using setting a primary screen percentage value between these ranges:

Screen Ranges

Percentage

Notes

50%

71%

This is the fastest approach to performance because it uses a smaller Local Data Storage (LDS) tile in memory. It's ideal for targeting temporal upsampling to 4K on desktop and consoles.

71%

100%

Ideal for normal DPI (Dots Per-Inch) rendering on desktop and consoles.

100%

200%

This would be ideal to give Dynamic Resolution the theoretical possibility to go over 100%, if it's not limited by the GPU memory for the render targets.

Material Improvements

There have been some improvements with how Materials use the Scene Texture expression to sample the scene. It has been simplified so that the view size is always equal to that of the render target being used. There is a new output on the Screen Position expression that enables accurate pixel position within the view size. There are some additional things listed to consider when using post process materials after TAAU as well.

The view size will now always equal the render target size in a material. Prior to UE4, version 4.19, when sampling a scene texture, the material had to work with the complexity of Scene Texture UV, which is different from the Viewport UV. For example, the Screen Position expression would output both of these values and View Property would also expose a Render Target Size that was not necessarily equal to the View Size. That was due to the renderer actually rendering the viewport in possibly larger render targets.



Click image for full size.

With that complexity removed, the Material will always behave as if the Render Target Size is equal to the View Size. The Screen Position expression will now always return the Viewport UV and the Scene Texture expression takes the Viewport UV as an input.



An example setup of how Screen Position returns the ViewportUV size for a Scene Texture expression.

The Screen Position expression now includes a second input for Pixel Position, which is the Viewport UV multiplied by the size of the pass. The View Property's View Size will always return the resolution before TAAU, even in a post process material running after TAAU.

Pixel Position is used to give the material the most accurate pixel position within the View Size, which is critical for effects such as custom pixel dithering that is synchronized with TAA. The following is an example how the Viewport UV is computed:



When creating a Post Process Material, you can select the Blendable Location to use. The After Tonemapping and Replacing the Tonemapper locations are after TAAU in the pipeline, meaning that they are actually running at full resolution and are different from the View Size.



The View Property expression's View Size and Render Target Size will still return the resolution of the view before TAAU, even though it's happening after that.To know what the view size and texel UV size are after TAAU, the Scene Texture expression using PostProcessInput0 can use the outputs for Size and InvSize.



Recomputing Viewport UV from Pixel Position can be done like so:



Now that Scene Texture expressions only accept Viewport UV, it's possible to sample in any arbitrary scene textures without possible errors while doing UV viewport conversion.

Secondary Spatial Upscale

In addition to the Primary Spatial Upscale, there is the Secondary Spatial Upscale taking place after the TAAU pass. This can be problematic for high DPI monitors where the GPU may not be able to keep up depending on scene complexity rendered at the higher resolution. For that purpose, the renderer supports using a secondary screen percentage that drive the second and final upscale pass. This pass is independent of the primary screen percentage.

Note that unlike the primary spatial upscale, the secondary spatial upscale is static and cannot be changed dynamically in-game.



You can set the secondary screen percentage by using the following console variable in your configuration (.ini) file:

If we know that the backbuffer resolution is 1080p, we can target a lower resolution of 900p by entering the percentage of that for the secondary screen percentage.

For example, we use a value of 83.33 when targeting 60hz on Xbox One for Fortnite Battle Royale and set it by using the following:

Adding the secondary screen percentage to your config file will override the Editor and any platforms it is set for. Also keep in mind that using the console variable r.SetRes controls the backbuffer resolution. It's best to leave that at 1080p or 4k so that the UI always renders at native resolution for the target platform.

DPI Editor Viewport Scaling

When working in the Editor, all viewports are rendered with a secondary screen percentage that is divided by the operating system's (OS) DPI scale. The following equation is used to determine the secondary screen percentage:

The scene scaling (or quality) is adjusted for high DPI monitors to ensure consistent performance with very large render targets. It also prevents allocation of an intermediary render target that could be too large for your system's GPU, which could crash the Editor and lose your work. By default, the Editor adjusts the scene scaling for high DPI monitors to ensure consistent performance with very high pixel density. However, this can be customized by enabling the setting Disable DPI Based Editor Viewport Scaling in the Editor Preferences. It will enable the secondary screen percentage to default to 100, rendering at full resolution for all of the Editor Viewports.



Changing this option only affects the Editor and the game build's secondary screen percentage will equal 100% by default.

VR Pixel Density

Prior to Unreal Engine 4.19, the screen percentage console variable was used to determine the resolution that the Head Mounted Display (HMD) screen should render your VR project at. This often was a "magic" number that had to be adjusted (and remembered) depending on the HMD being used to display the project.

Now, the resolution of the screen is controlled by Pixel Density. It removes the need to use "magic" numbers for screen percentages, making it easier to develope for multiple HMDs. By default, the eye views are going to be rendered at the HMD's recommended resolution to avoid the HMD compositor from doing any upscaling that normally is a cause of blurriness. You'll use the following console variable to give a higher or lower pixel density from the recommended resolution of the screen:



In this diagram, you can see that the ideal resolution of the HMD is used and VR Pixel Density enables you to adjust an arbitrary number to raise or lower the ideal HMD resolution as needed. This change allows independent control of the primary screen percentage to temporal upscale to the view resolution that is handed off to the HMD compositor in this pipeline.

For more information, read about VR Pixel Density here.

Getting Started

Reference

The texture streaming system, or texture streamer, is the part of the engine responsible for increasing and decreasing the resolution of each texture. This enables you to have good visual quality while managing the available memory efficiently.

Getting Started



Basics of the system used to calculate which textures should be streamed in at what times and viewpoints.

Reference



How to build texture streaming data and visualize its accuracy.



Use stat commands to report texture streaming metrics.



System for loading and unloading textures into and out of memory during play.

Migrating Streaming Data to 4.15

Inspecting The Material Data

Build Accuracy

Limitations & Known Issues

Every time a Material or Material Instance is modified and resaved, it recomputes texture streaming data related to each texture that is used. Per-texture data includes the UV Channel Index and Scale, where the UV Channel Index is used to sample the texture, and the Scale is the multiplication factor applied to the channel prior to being sampled.

This, however, does not cover all cases, as the sampling could be based on world position, mesh vertex color, or any combination of UV channels. This would make the analysis fail to find the related data, and the engine will assume a dependency on UV Channel 0 and a Scale of 1.

The analysis is run at different steps, depending on what is being edited:

Material: This runs when the user applies or saves a modification.

Material Instance: This runs when the Material Instance Editor is closed, or when the package holding the Material Instance is saved.

Level: This runs for every used Material when the user runs "Build Texture Streaming". This is to ensure that every Material is up-to-date. The reason for materials not being up-to-date are:

Materials prior to 4.15 not having any data.

Material Parent has changed and the instance data is outdated.

There have been improvements done after the Material was last saved.

There is a bug fix.

For a given primitive component, the data required to accurately compute the required resolution of each used texture comes from:

The bounds of the primitive

The texture coordinate sizes of the mesh

The material texture coordinate scale for sampling each texture

When this information is missing, conservative heuristics will be used.

To build Texture Streaming data:

Click on the dropdown arrow next to the Build button in the Toolbar.

Click on Build Texture Streaming.



This will generate component and level data to be used at runtime.



Note that this generates the data to be used for all material quality levels and platform feature levels, using the highest quality level and supported feature level.

At runtime, if the component is using fewer textures than those that were used in the build process, the unused ones will be ignored.

Migrating Streaming Data to 4.15

Because any materials edited before 4.15 did not have any texture streaming data stored with the material, it won't have any data until they are modified and resaved. This includes resaving the child instances of a material as well. To migrate the data quickly, you can use the console command BuildMaterialTextureStreamingData.

This will parse all materials currently loaded in memory and generate any missing data. Updated materials will then be marked for resaving.

Inspecting The Material Data

The data that is built can be inspected in the Material Texture Scales viewmode. This viewmode will only show what has been computed successfully and any fallback cases will be shown as undefined. This viewmode shows the accuracy of the material scales and is used to validate changes in the analysis. It also identifies possible culprits when there are quality issues related to texture streaming.

To inspect the material texture streaming data, you can either select a Material from the Content Browser, or select primitives in the scene view. The Texture tab in the main viewport shows where the selection comes from by adding "(Scene Selection)" or "(Content Browser)" to the end of the tab's label.

When using Scene Selection the individual materials can not be selected and the UI will group data from all materials.







Nothing Selected

Material from Content Browser

Scene Selected Actor

When using Scene Selection, the individual materials cannot be selected and the UI will group data from all materials. When you hover over one of the texture selections from the dropdown you can see in the tooltip all the listed textures.





Single Object Scene Selection

Multiple Object Scene Selection

When using the Content Browser selection, the textures are identified by their texture index, the material name (if several Materials are selected), and the texture name. The texture index is an identifier within each material. The displayed accuracy is computed by comparing the GPU value used, with the value computed in the material analysis. in the material analysis.





Single Material Content Browser Selection

Multiple Material Content Browser Selection

In the All Textures mode, the worst cases are shown from all used textures. If the global value is accurate (light gray), then all textures have accurate values. Unfortunately, there is a limitation in this mode; whereas if the same texture is sampled several times with different scales, this will usually show up as over streaming. This is due to the fact that only the scale requiring the most resolution is used, and the scale requiring less resolution gets ignored in the analysis. This limitation doesn't apply in the per-texture view.

Build Accuracy

The accuracy of the data computed during the texture streaming build can be inspected by looking at the texture streaming accuracy view modes:



These view modes will show the accuracy of the built data. When the accuracy result is too low or too high (red or green), it is sometimes possible to correct the data with manual configuration changes. The texture streaming build aims at generating the best data without requiring manual tweaks.



The above image is the scene used to build the texture data shown below. For all the view modes, use the following legend:

Red: 2X+ mips missing

Yellow: 1 mip missing

White: Good data

Cyan: 1 extra mip

Green: 2X+ extra mips

Primitive Distance Accuracy

This shows the accuracy of the view-mesh distance computed by the streamer compared to the real GPU distance. The streamer computes the distance from the viewpoint to the texture instance axis-aligned bounding box (AABB). This bounding box is computed in the build process by summing up the component LOD-section AABBs that are using the texture.

When the viewpoint gets very close to, or enters the AABB, this mode will always show as 2X+ over, unless the geometry fits the AABB. This is because the streamer computed distance becomes a zero value, while the GPU distance is typically a non-zero value. The ratio between the streamer computed distance and the GPU distance, therefore, becomes very big. This is not an error and there is no need to fix it at this time.



The value displayed here can be adjusted by changing the mesh component's Streaming Distance Multiplier.



Mesh UV Density Accuracy

This view mode shows the accuracy of the mesh world texture coordinate (texcoord) size used by the streamer, being compared with the real GPU value. This size relates the variation of texcoords by unit of world space. It is used by the streamer to evaluate the impact of the texcoord on the sampling of the texture.



This view mode is relatively viewpoint agnostic, and when a mesh has bad values, they are usually not scene related but rather mesh related. This means that if any mesh has the wrong data, any component using this mesh is likely be incorrect as well. This value can be changed within the Static Mesh or Skeletal Mesh Editors by tweaking the StreamingDistanceMultiplier until the mesh is in the Good range.

Material Texture Scale Accuracy

Most of the textures used in a material are sampled using a scaled value of one of the Mesh UV Densities. The texture streaming build tries to compute which texture coordinate is used and what scale is applied to each sampled texture. This could fail for many reasons, in which case, the streamer assumes that the texture was sampled with texcoord 0 and a scale of 1.



In addition to the standard legend, a black and white checkerboard indicates that the build could not generate the required shader for some reason. Also, because the material samples many textures, this view mode shows the worst error across all sampled textures. The two extrema (under-streaming and over-streaming) are displayed via the checkerboard: one shows the worst oversampling, while the other shows the worst undersampling.

Individual errors per texture can be investigated by using the console command r.Streaming.AnalysisIndex X, where X is a value between 0 and 31.

Required Texture Resolution

In this viewmode, the relationship between the currently streamed texture resolution and the required texture resolution can be shown.



This viewmode has some similarities with Material Texture Scales, but rather than showing the accuracy of the texture streaming data, it shows the usefulness of the currently loaded texture resolution in an absolute way.

The resolution loaded at any time for a texture comes from a combination of logics and metrics. For example, a texture could be missing resolution because there is not enough space available to load it, or it could have too much resolution because its higher mips are cached in the texture pool waiting for future use. Also, the streamer is usually driven by the component requiring the highest resolution, so investigating the behavior of a texture on one component only makes sense if it is the component that is driving its resolution.

Because of all of this, this viewmode is best used to investigate the behavior of the texture streamer in controlled environments. A useful setup for this is to set:

r.Streaming.DropMips 2

This tells the streamer to only keep visible mips, therefore disabling caching and prefetching. By moving the Camera around, you will see if the streamer loads/unloads the right mips at the right time.

Please note that the texture selection menu will present a per-texture selection if there are less than 32 textures selected in the selected components materials. When a texture is selected in this manner, it will be shown on all scene components using it.



Limitations & Known Issues

Not all Materials are supported by the analysis. Currently, Decal and Landscape materials are not supported. There are also cases where the engine fails to generate the shader that is used for analysis. In this case, the primitives will be seen with a uniform dark gray color. Detailed logs of all issues can be enabled through the console command: log TextureStreamingBuild level all.

Material Instances can have deprecated data if their parents were changed and resaved while the child instances were not resaved. This is because the texture streaming data is stored in the materials, and modifying parent materials does not trigger a resave of the child material instances.

At runtime, the engine uses the texture names to access the material streaming data. This is to prevent hard references to the assets at runtime while still giving good performance. This means that if several textures with the same names are used in a material, the required resolution coming from both data will apply to both textures.

The shaders used in the Material Texture Scales viewmode are not persistent, and can be missing or deleted if certain kinds of operations are performed, such as compiling shaders, or loading maps. Selecting the viewmode again will regenerate the missing shaders.

After checking the accuracy of your built texture streaming, you may want to adjust the texture streamer's behavior and priorities. The parameters below can be adjusted through configuration files, and most of them can also be updated at runtime from the console window.

Command

Description

r.TextureStreaming

This enables or disables the texture streamer. When it is disabled, all texture mips will get fully loaded in memory, even if the texture is never used for rendering. You can toggle this option at runtime, if needed.

r.Streaming.PoolSize

The pool size in MB available for textures in the engine. This pool contains UI textures, NeverStream textures, cubemaps and streaming textures. On some platforms, this pool can also hold non texture resouces like GPU particle buffers and vertex buffers. When set to 0, the pool size will be unlimited.

r.Streaming.UseFixedPoolSize

When using a non-zero value, the texture pool size can be changed at runtime.

r.Streaming.FramesForFullUpdate

The number of frames between each full update of the texture streamer. Each update recomputes the required resolution of each texture and generate mip load or unload requests. Higher values reduce the texture streamer CPU usage while lower values increase its reactivity.

r.Streaming.UseNewMetrics

For compatibility only. When set to false, the texture streamer will proceed as per 4.12 version.

r.Streaming.MaxTempMemoryAllowed

The amount of temporary memory in MB allowed for updating the textures. This should be big enough to avoid starving the texture streamer while being small enough to prevent wasting (unused) memory.

r.Streaming.HLODStrategy

This controls the loading strategy for hierarchical LOD textures :

0 : Allow streaming of all mips

1 : Only stream the last mip. The other mips are always loaded.

2 : Don't stream any mips. All mips are always loaded.



r.Streaming.HiddenPrimitiveScale

This controls a scale applied to the "wanted" resolution when the component referring to a texture is not visible (i.e. its bounding box is occluded). This only affects the resolution before it gets clamped by the max available resolution to avoid downgrading textures that are already limited. In other words, it only affects textures that have appropriate resolutions for the viewpoint.

r.Streaming.MaxEffectiveScreenSize

When non-zero, this will limit the screen size considered by the streamer when computing the "wanted" resolution of textures. This will prevent high resolutions from requiring significantly bigger streaming pools.

r.Streaming.Boost

This is a global boost affecting the "wanted" resolution of textures.

r.Streaming.MipBias

This is a global mip bias used to prevent the streamer from loading the biggest mips for each texture. It is used to accommodate a low streaming pool. This also affects which mips the streamer tries to load for any viewpoints, as with a small r.Streaming.Boost or a limiting r.Streaming.MaxEffectiveScreenSize.

There are a few exceptions to how this bias is applied :

Terrain & Landscape textures : bias has no effect.

Hierarchical LOD textures : bias does not limit max resolution.

Lightmaps & Shadowmaps : bias only limits max resolution.



r.Streaming.UsePerTextureBias

This is used to limit the effect of the global mip bias by limiting its effect to the max allowed mip and not the "wanted" mips from any viewpoint. It will then apply it to textures only in order to fit in the streaming pool. Each texture has its own mip bias, ranging from 0 to MipBias, depending on the budget computation.

r.Streaming.DropMips

This is a debug option used to prevent keeping mips in memory even if the streaming pool allows it:

0 : Drop no mips.

1 : Drop cached mips.

2 : Drop cached and hidden mips.

The purpose of this is to assets the accuracy of the wanted mip computation, as the displayed resolution can be affected by previous load requests or hidden primitives.



r.Streaming.FullyLoadUsedTextures

This will stream all used textures to their max available resolution and keep them in memory for as long as the application is opened. This should be used as an alternative to disabling texture streaming completely, which would load textures that are never used and ultimately, requiring more memory usage.

r.Streaming.UseAllMips

Whether or not to remove all resolution limitations coming from texture group settings and cinematic settings. This should only be used when showcasing art or making promotional material.

r.Streaming.AnalysisIndex

This is used in Material Texture Coordinate Scale Accuracy View Mode to investigate the accuracy for individual textures.

r.Streaming.CheckBuildStatus

If enabled, the engine will check if texture streaming needs to be rebuilt, displaying a warning when simulating or in Play in Editor (PIE) mode.

r.Streaming.DefragDynamicBounds

If enabled, unused dynamic bounds will be removed from the update loop.

r.Streaming.LimitPoolSizeToVRAM

If enabled, the texture pool size will be limited to how much GPU memory is available.

r.Streaming.MinMipForSplitRequest

When non 0, this allows the texture streamer to first load the visible mips from a texture when non visible mips must also be loaded. This improves the visual quality by prioritizing visible mips over force loaded mips or hidden mips that could become visible.

r.Streaming.NumStaticComponentsProcessedPerFrame

If non-zero, this sets the number of components the engine will incrementally load per frame before the level is visible. This applies to components with their mobility set to static. The default value is set to 50.

r.Streaming.ScaleTexturesByGlobalMyBias

Whether the streaming texture's "wanted" resolution will be scaled down by the global mip bias.

r.Streaming.UseMaterialData

Whether the material texture scales and the coordinates will be used for texture streaming.

Improvements in 4.15



The texture streaming system, or streamer, is the part of the engine responsible for increasing and decreasing the resolution of each texture. This enables you to have good visual quality while managing the available memory effectively. This is in part done with Mips, or Mipmaps, that are pre-calculated sequences of images for your texture resolutions. You can think of these like LODs for your textures. For more information on Mips you can read about it on our Texture Format Support and Settings page.

The streamer has its own view of the world, and its update cycle consists of:

Updating the world view

Computing which resolution would be ideal for each texture

Choosing which resolution is actually possible based on the streaming pool size

Choosing which textures to update

Generating load / unload requests

To achieve those tasks, the streamer uses an async worker thread to reduce the workload on the game thread, so that only the first and last tasks above need to be done in the game update loop. The world view consists of the list of all the textures used by each primitive component, and for each, world bounds and texel world sizes. From that information and a given viewpoint, it is possible to compute what resolution would be required to get a good texel per pixel ratio. Additional information is then taken into consideration like whether this component was actually visible onscreen or not. This ends up defining the ideal resolution for each texture. The streamer then computes if the streaming memory pool is big enough to hold those resolutions. If not, the streamer will reduce the planned quality for selected textures, dropping one mip at a time, until the planned solution gets under budget.

The order in which textures are processed when dropping mips is defined by the retention priority, and follows these rules in order:

Keep landscape textures, forced load textures, and textures already missing resolutions

Keep mips that are visible on screen

Keep character textures and textures that don't take much memory

Drop mips that are not visible, dropping the last recently seen first

Once the streamer has determined what resolution it will load for each texture, it then computes which textures should be updated first according to the load order priority. The priority is defined by several criteria evaluated in order:

Load visible mips first

Load forced load textures, landscape textures, and character textures first

Load textures which are far from their target resolutions first

For those that are not visible, load the most recently seen first

The final step is to generate a batch of update requests, each of those either increasing or decreasing the current texture resolution. The amount of memory updated for a single batch is limited by the temporary pool size, in order to keep the number of inflight requests low.

Improvements in 4.15

The Texture Streaming system has been optimized to reduce CPU usage, memory usage, and load times while elemintating low resolution artifacts and automatically handling limitations of varying memory budges of different platforms.

Texure Memory Usage Improvements

Texture Loading Time Improvements

CPU Time Reduction:

Game thread update time is reduced by 50%

Texture processing stalls for streaming levels are reduced up to 98%

Low Resolution Artifact Reduction

Automatic Memory Budgeting

Texture Streaming Debugging Visualization Viewmodes

Primitive Distance Accuracy

Mesh UV Density Accuracy

Material Texture Scales Accuracy

Required Texture Resolution

To learn more about these latest improvements and debugging methods for your games continue on to our Building Texture Streaming Data and Reporting Texture Streaming Metrics pages.

Incremental Processing of Newly Loaded Levels

Performance

You can profile texture streaming stats with the STAT STREAMING console command. This reports the performance, memory usage, and other metrics used by the texture streamer.

STAT STREAMING sortby=name maxhistoryframes=1



When reading memory data, the term "pool" refers to the conceptual (reserved) memory, and does not relate to the actual memory taken. The word "mips" maps to memory currently used by textures, rather than to expected or future usage. The memory metrics are classified in three main pools:

Texture

Streaming

Wanted

These pool sizes are indicated on the right of each line in the Memory Counters category.

Stat

Description



Cycle Counters



Game Thread Update Time

The time taken by the streamer update function. This accounts for most of the texture streaming work. Only a few tasks are processed outside the texture streamer, like removing reference to a texture, a component, or a level. During a game thread update, the streamer performs one step toward the full update. The full update takes several frames and relates to r.Streaming.FramesForFullUpdate. There are different update steps, as defined in the Counter section of the stats.



Memory Counters



Texture Pool

The total memory availabe for texture resources. This includes non-streaming resources like render targets, GPU particle buffers, cubemaps, UI textures, and non-streamable textures. On some platforms, this memory can be used to store non-texture resources like Static Meshes. Texture Pool is approximately equal to Safety Pool + Temporary Pool + Streaming Pool + NonStreaming Mips (only the amount of the fluctuation, if any, up to the size of the safety pool)

Safety Pool

This value is set in the Engine configuration file, under [TextureStreaming], as MemoryMargin. It is memory reserved for unexpected (non-streaming) allocations. If the memory available fluctuates cyclically by an amount under this value, the texture streamer will stabilize its streaming pool to the maximum taken by this fluctuation. If a normal (expected) fluctuation takes more than the safety pool size, then the texture streamer will constantly adapt its budget, possibly creating infinite cycles of streaming textures in and out.

Temporary Pool

This value is controlled by r.Streaming.MaxTempMemoryAllowed and specifies how much extra memory the streamer is allowed to use when resizing textures. When changing the mip count of a texture, the engine has to create a new texture, either smaller or larger, which will hold the future mip data. This indirectly controls the amount of inflight requests since the streamer sends to the IO system as many requests as the temporary pool allows.

Note that the temporary pool must be at least as large as the largest resource to stream, but setting it too large will waste memory (as it is reserved for that purpose). On the other hand, setting it too small could slow down the streaming speed (not generating enough work for the IO system, making it idle). Note also that the streamer has very little control on the processing order within the inflight requests. That means using a relatively small temporary pool gives better control of what is loaded first.



Streaming Pool

The amount of memory available to the texture streamer. The streamer will usually take all its available memory to either stream new mips, or to keep previously streamed mips in memory as long as possible. The Streaming Pool contains Visible Mips, Hidden Mips, Force Mips and Cached Mips. Streaming Pool is approximately equal to Visible Mips* + Hidden Mips + Forced Mips + Cached Mips (*: when fully used, otherwise unused space must be accounted for)

NonStreaming Mips

The amount of memory used by non-streaming allocations. If those allocations regularly fluctuate by more than the safety pool value, this will affect the streaming pool budget, and should be avoided (by either decreasing the allocations or increasing the safety pool).

Required Pool

The amount of mip data the texture streamer needs to load according to its metrics. This can exceed 100% of the texture streaming pool, in which case some compromise will be made and some texture(s) will not be loaded to their required resolution.

Visible Mips

The wanted memory currently taken by visible texture mips. This does not include forced mips.

Hidden Mips

The wanted memory currently taken by non-visible texture mips. This does not include forced mips. To prevent seeing low resolution textures the first time a texture is shown, the streamer prestreams textures in advance, althought usually with one less mip than required (see r.Streaming.HiddenPrimitiveScale).

Forced Mips

The wanted memory currently taken by textures that are forced in. Textures are usually forced in through gameplay mechanisms for a small period of time. This does not include textures that are flagged as non-streamable.

Cached Mips

Memory taken by texture mips that are not needed anymore. They will be kept cached unless their memory is needed by other wanted mips.

Wanted Pool

The part of the required pool that will eventually be streamed in.

Wanted Mips

How much of the wanted pool is actually streamed in. Once it reaches 100%, the streamer has stopped sending IO requests to load new mips. Wanted Mips* is equal to Visible Mips + Hidden Mips + Forced Mips**

Inflight Requests

How much memory has still to be processed by the IO. When 0, all previous requests have been processed at the time of creating new requests. If this happens when the streamer is streaming content, that would be an indication that the streamer is not using all of the available bandwidth. The bandwith could be increased by increasing r.Streaming.MaxTempMemoryAllowed (at the expense of more wasted memory and less load order control), or by decreasing r.Streaming.FramesForFullUpdate (at the expense of longer update times).

IO Bandwidth

The size of loaded mips completed since the last update, divided by the time since the last update. This is not an accurate IO bandwidth measurement but can still be used to get an idea of how fast the system loads requests.



Counters



Setup Async Task

The time taken to prepare the data for the async streamer task. It runs as the first step of the full update loop.

Update Streaming Data

This is the time used to incrementally update the streaming data. This includes refreshing the visibility, updating the texture states, updating the bounds of any used dynamic components. The step will run several frames in a row, as defined by r.Streaming.FramesForFullUpdate.

Streaming Texture

The time taken to prepare and send the load and cancellation requests.

Incremental Processing of Newly Loaded Levels

Starting with Unreal Engine 4.15, the texture streamer processes the level data incrementally, so just a little bit each frame, between the time they are loaded and the moment they become visible. Previously, this processing would happen in the frame the level became visible and could generate some noticeable hitches while doing so.

The amount of work processed each frame is controlled by r.Streaming.NumStaticComponentsProcessedPerFrame, which has a default value of 50. Setting 0 for this value will disable the incremental work and it will make the system behave as it did prior to 4.15.

It's important to mention that the incremental level processing will only apply to components with their Mobility set to Static. Movable components have always been processed incrementally in the engine tick.

Once the incremental processing completes, no more processing will be required before the level becomes visible. If it becomes visible before the incremental processing completes, then all pending work needs to be finished immediately and there could be a small hitch when this happens.

You can investigate incremental processing by running the console command:

The cost gets included in the category Update Streaming Data.

Performance

With the improvements to the texture streamer in 4.15, the following information lists describe the targeted improvements with some concrete metrics about how things were improved.

Reducing The Number Of Textures Taken By the Texture Streamer

This has been improved by handling per-component visibility. Textures that are used by non-visible and hidden components are streamed with one fewer mips, as a prefetch. The addition of the per-material texture streaming data also helped by computing correctly the scales applied to the UV Channels for things like detail maps.

Finally, the other improvements here came from computing (smaller) per-material bounds for static geometry.

The metrics below were taken from Paragon using three different viewpoints around the level.

Required Texture Pool

Before

After

Amount Visible

Startup

678 MB

564 MB

370 MB

Side Lane of Map

796 MB

597 MB

308 MB

Middle Lane of Map

1086 MB

674 MB

271 MB

Reducing Time For Visible Textures To Stream In

In order to reduce the amount of time it takes to stream in visible textures (aside from reducing the global texture budget); the streamer keeps a table of visible versus budgeted mips. By keeping track of the visible mips from those that are budgeted, the streamer is able to stream in perceptible data prior to streaming in prefetch and forced load data.

The metrics below were taken from Paragon using three different viewpoints around the level.

Loading Visible MIPs

Before

After

Startup

20s

10s

Side Lane of Map

19s

9s

Middle Lane of Map

20s

6s

Reducing CPU Time Taken By The Streamer

The CPU time taken has been improved by moving the dynamic component processing to the async texture streaming task. Other things have also been moved, like the handling of overbudget situations and the determining texture load order.

In the example below, this shows the improvement of the Worst Update Frame from Paragon.

Game Thread Update Cost

Before

After

Worst Update Frame

1.1 ms

0.6 ms

Another key improvement in this area is the incremental processing of newly loaded level streaming data while the level is loaded but not yet visible.

Game Thread Level Loaded Cost

Before

After

Incemental Update

150 ms

3 ms

Eliminating Low Quality and Bad Behaviors

Mesh UV densities are computed per material instead of per-mesh. This new data takes into account LODs as well. This resolved most issues where the texture would appear low-resolution.

Also, there is now a wider texture streaming support from the component, including Particle Systems and Instanced Meshes. This resolves other low resolution issues and, sometimes, high memory consumption.

Eliminating Manual Tweaks for Different Memory Budgets

The texture streamer can automatically fit different memory budgets without the hassle of manual tweaks. The streamer will select which textures need to be reduced using different heuristics to minimize visual impact.

Only the least amount of textures will be affected and the effect is localized so that in different locations the sacrifices will not be the same.

Virtual Texturing Methods

Runtime Virtual Texturing

Streaming Virtual Texturing

Virtual Texture Topics

Virtual Texture support for your project enables you to create and use large-sized textures for a lower—and more consistent—memory footprint at runtime.

Virtual Texturing Methods

Unreal Engine supports two virtual texturing methods: Runtime Virtual Texturing (RVT) and Streaming Virtual Texturing (SVT).

Runtime Virtual Textures

Streaming Virtual Textures

Supports larger texture resolutions.

Texel data cached in memory on demand.

Texel data generated by the GPU at runtime.

Well suited for texture data that can be rendered on demand, such as procedural textures or composited layered materials.

Supports larger texture resolutions.

Texel data cached in memory on demand.

Texel data cooked and loaded from disk.

Well suited for texture data that takes time to generate, such as lightmaps or large, detailed artist created textures.

Runtime Virtual Texturing

RVT supplies an efficient way to render complex, procedurally generated, or layered materials. This makes RVT ideal for rendering complex materials for Landscapes. It enables improved rendering performance and workflows for Landscape Splines, decals for meshes and materials, along with general Landscape and object blending.

For additional information, see Runtime Virtual Textures.

Streaming Virtual Texturing

Streaming Virtual Texturing reduces texture memory overhead when using larger texture sizes, including support for virtual texture lightmaps and UDIM (U-Dimension). Streaming virtual textures is an alternative way to stream textures from disk compared to existing mip-based texture streaming.

For additional information, see Streaming Virtual Textures.

Enabling support for virtual texture lightmaps can improve streaming performance and quality of lightmap bakes.

Enable virtual texture support for lightmaps from the Project Settings by going to Engine > Rendering and setting Enable virtual texture lightmaps.



Enable the following console variables to control how virtual texture lightmaps are used in your project:

Console Variable

Description

r.IncludeNonVirtualTexturedLightmaps

Controls whether non-VT lightmaps are generated/saved. Including non-VT lightmaps will constrain the atlas size, which removes some of the benefit of VT lightmaps.

r.VT.EnableLossyCompressLightmaps

Enables lossy compression of virtual texture lightmaps. Lossy compression has lower quality on lightmap textures compared to regular color textures.

Virtual Texture Topics



Overview of GPU memory allocation with the virtual textures physical memory pool.



Reference information for project settings, console commands, and Actor settings for virtual textures.



A walkthrough of setting up runtime virtual textures with a material applied to a landscape.

Understanding the Behavior of Physical Memory Pools

Configuring the Physical Memory Pools

Residency of Physical Memory Pools

Residency MipMap Bias

Physical Memory Pool Heads-Up Display

Debugging the Residency of Physical Memory Pool

Pool Memory Sizes

Oversubscription

The Virtual Texture system has two main types of GPU memory allocation: Page Table Memory and a Physical Memory Pool.

Page Table Memory provides indirection from texture coordinates to the texture data, and is allocated on demand. It can grow over time and generally is not released from memory unless all of its contents are released. There are no user controls for this memory type.

Physical Memory Pool contains the currently resident texture data, and is made up of a number of individual pools. Each texture format that the Virtual Texture system sees has its own associated memory pool. Each pool is allocated on the first instantiation of a virtual texture with the matching format. Each pool has a fixed size and cannot grow. Users can control the size of each pool.

This document describes how virtual texture physical memory pools can be defined and debugged.

Understanding the Behavior of Physical Memory Pools

The physical memory pools are each made up of pages. Each page contains the data for one tile of virtual texture. The pool acts as a least recently used cache. As the Virtual Texture system requests a tile, it is streamed or rendered into an available page in the pool. If there are no available pages, then the page containing the least recently seen tile is evicted to make room for the new one.

If a view has more virtual texture tiles visible than can fit in the virtual texture memory pools, the system will not be able to render that view correctly. In those cases, the virtual texture memory pool sizes need to be tuned to match the data usage.

Configuring the Physical Memory Pools

The Memory Pool Sizes for virtual texturing are set up in the BaseEngine.ini configuration file.

The pools are set up per-Texture Format Group and Tile Size. They can be overridden per project, or per platform, by setting up your own [Configuration File]() in your project.

All configuration settings for Virtual Texture Memory Pools are found under the /Script/Engine.VirtualTexturePoolConfig heading.

The following example sets up any virtual texture memory pool containing BC7 textures to be 100 Megabytes (MB) in size. The size is approximate, and the system actually allocates the largest pool size less than 100 MB that is square and fits an integer number of pages.

Formats that don't have a corresponding entry in the configuration use the default pool size. The default can be expressed by defining a pool without a texture group format.

Some pools contain multiple layers, each with its own format. This is true for most Runtime Virtual Texture setups. In this case, the matching layer formats are required for the configuration file entry.

For example, a Runtime Virtual Texture that uses the Base Color, Normal, Roughness, Specular type in a Material would be set up as follows:

Any memory pool configuration entry can have additional settings, which are:

Memory Pool Configuration Settings

Description

bAllowSizeScale

Allows an additional scale factor to be applied to the pool memory size through a scalability console variable r.VT.PoolSizeScale.Group <X>.

ScalabilityGroup

Sets the group index (0-2) that bAllowSizeScale works with. Having multiple groups allows for different scalability to be set per pool.

bEnableResidencyMipMapBias

Enables the behavior where a mipmap bias is applied to virtual textures when this pool is oversubscribed.

Residency of Physical Memory Pools

The current usage of the virtual texture memory pools is referred to as Residency. When a pool has all its pages allocated by tiles that are currently visible, residency is 100%.

At a residency of 100%, a pool is oversubscribed and will drop data for visible tiles. This leads to unwanted IO and screen flickering as texture data is repeatedly loaded and evicted from memory.

You can enable an on-screen notification to be shown when the memory pool is oversubscribed. Enable the notification with the console command r.VT.Residency.Notify 1.



This warning indicates you should either increase your memory pool sizes in the configuration file, or change your virtual texture or Material. See the section below for tips on resolving these types of issuesnote

Residency MipMap Bias

If a pool has been configured with the bEnableResidencyMipMapBias setting enabled, a mipmap bias is set to reduce residency when it is oversubscribed. This prevents unwanted IO and screen flickering at the cost of rendering virtual textures with a reduced resolution.

This setting is useful if residency is very rarely oversubscribed and you don't want to allocate memory for the rare chance this could happen. The on-screen message for oversubscription includes any mipmap bias that is being applied.

The mipmap bias that comes from residency is global. The maximum current bias from all of the physical memory pools is applied to all virtual texture sampling.

Physical Memory Pool Heads-Up Display

Setting a good memory pool size is important to monitor residency and reduce oversubscription from happening. You can use the onscreen heads-up display (HUD) to show the current residency of each virtual texture physical memory pool.

It is enabled with r.VT.Residency.Show 1.



Virtual texture physical memory pool HUDs display the current residency of each texture format and their allocated memory.



Each graph on the screen represents one of the virtual texture physical memory pools. There are three line graphs:

Red is the current pool occupancy from 0-100%.

Yellow is the fixed pool occupancy from 0-100%.

This is the occupancy from pages that are marked as locked. There is usually one page locked for every virtual texture. A very large number of loaded virtual texture assets can reduce the available pool space even if the virtual textures are not visible.

Green is the mipmap bias being applied to keep residency below 100%.

Debugging the Residency of Physical Memory Pool

The following are some areas to start debugging and checking content when virtual texture memory pools are oversubscribed.

Pool Memory Sizes

When it comes to virtual texture pool sizes, you'll want to check the following:

Check that pool sizes are large enough to hold an expected full working set of virtual texture data.

The pool size should be bigger for pools that have larger page sizes. For example, a pool with texture format PF_A32B32G32R32F has a much bigger memory requirement than a pool with texture format PF_DXT1. Similarly, a pool that contains multiple layers has a bigger memory requirement.

When rendering a higher output resolution, pool sizes should be larger.

A higher resolution output generally requests more higher resolution mip tiles.

Larger tile sizes may require a bigger pool size.

The default tile size for Streaming Virtual Textures is 128 texels. However, that can be overridden.

The tile size of Runtime Virtual Textures can be up to 1024 texels. Larger tile sizes often incur wasted space in the pool.

Oversubscription

One particular cause of oversubscription is the application of a negative mip bias when sampling virtual textures. Systematically sampling higher resolution mips requires more pool memory. Negative mip bias comes from explicitly setting mip level or bias on a Texture Sample node in the Material Graph.

Oversubscription can also come from unexpected sources, such as when sampling a texture with zero gradient because the UVs are invariant for a triangle or mesh. The material graph snippet below is an example of this. This specific case can be solved by using a Mip Value setting of "Ignore Input WorldPosition" on the Runtime Virtual Texture Sample node.



Use the console command r.VT.DumpPoolUsage to help locate any textures that are taking up more space in the pool than expected due to mip bias, or other issues. This command dumps out the number of pages that each virtual texture asset currently allocates in each memory pool. The dump is sorted by page count so that the first entries should be checked to see if they are reasonable.

Note that in the following dump, the first entry is significantly higher than the others. So, materials that reference T_Ground_Sand_F_basecolor_CANYON should be checked for any mip bias issues.

Streaming Virtual Texture Settings

Project Settings

Texture Editor

Runtime Virtual Texture Settings

Runtime Virtual Texture Asset

Runtime Virtual Texture Sample Material Node Settings

Runtime Virtual Texture Volume

Actor Properties

This page contains information about requirements, settings, and console commands for the Virtual Texturing system.

Streaming Virtual Texture Settings

The following settings and properties are used in setting up and working with Streaming Virtual Texturing.

Project Settings

When you have activated Enable virtual texture support in your project, you'll have access to the following settings in the Project Settings window, under the Editor and Rendering categories.



The available rendering settings are located under the Engine > Rendering > Virtual Textures category in the Project Settings window.

Properties

Description

Enable virtual texture support

When enabled, Textures can be streamed using the Virtual Texture system. Changing this setting requires restarting the editor.

Enable virtual texture lightmaps

Lightmaps will be baked to Virtual Textures. This means lightmaps will have all the advantages (and disadvantages) of Streaming Virtual Textures. Compared to traditional lightmap textures atlas sheets, VT enables all lighting for a level to fit into a single texture, increasing batching efficiency. Lighting must be rebuilt for the project for this change to take effect. Changing this setting requires restarting the editor.

Tile size

The size in pixels for Virtual Texture Tiles. All values not a power of 2 will be rounded to the next power of 2 value. Changing this setting requires restarting the editor.

Tile border size

The size in pixels for Virtual Texture Tile Borders. All values not a power of 2 will be rounded to the next power of 2 value. Larger borders enable a higher degree of anisotropic filtering but uses more disk/cache memory. Changing this setting requires restarting the editor.

Feedback resolution factor

Lower factors will increase Virtual Texture Feedback Resolution, which increases CPU/GPU overhead. However, it may decrease streaming latency, especially if Materials use many Virtual Textures.

Enable Zlib compression

Enables use of Zlib to compress Virtual Textures. This makes VT textures smaller on disk I/O cost (number of reads or writes) but adds CPU cost to decompress. Changing this setting requires restarting the editor.

Enable Crunch compression

Enables use of Crunch library to compress Virtual Textures. Crunch is an open-source compression library designed to further compress GPU block-compressed textures (using DXT/BC/ETC compression). It makes data much smaller than Zlib, and decreases CPU cost to decompress. However, compression is lossy so the image quality will be reduced. When enabled, Crunch will only be used for supported texture formats. The degree of lossy compression applied can be controlled per-VT Asset by changing the Lossy Compression Amount property in the Texture Editor. The default value will apply minimal compression, resulting in the highest quality and largest memory usage—which is still lower than Zlib. Lossy compression can also be disabled, or increased to reduce memory usage at the cost of quality. Changing this setting requires restarting the editor.

The available Editor settings are located under the Editor > Texture Import > Virtual Textures category in the Project Settings window.

Properties

Description

Auto Virtual Texturing Size

Automatically enable the Virtual Texture Streaming texture setting for textures larger than or equal to this size. This setting will not affect existing textures in the project.

Texture Editor

Use the Texture Editor to set and control lossy compression amounts and whether a Texture supports SVT.



Click image for full size.

Properties

Description



Compression



Lossy Compression Amount

How aggressively any relevant lossy compression should be applied. use one of the available options, from lowest with no lossy compression at all, to the highest, which gives the worst image quality but with the smallest file size.



Texture



Virtual Texture Streaming

Whether this texture should be streamed in using Virtual Texturing. Note that this parameter is enabled by default for any textures imported that are equal to or larger than the Auto Virtual Texturing Size set in the Project Settings under Editor > Virtual Texturing.

Runtime Virtual Texture Settings

Use the following settings and properties to set up and work with Runtime Virtual Texturing in your project.

Runtime Virtual Texture Asset

When opening a Runtime Virtual Texture Asset, use this window to set parameters for the generated RVT in your scene with any Runtime Virtual Texture Volume that is referencing it. You can create an RVT Asset from the Add New menu under Materials & Textures.



Properties

Description



Details



Page Table Texture Memory (estimated)

Estimated page table texture memory that this Virtual Texture Asset is consuming.

Physical Texture Memory (estimated)

Estimated physical memory that this Virtual Texture Asset is consuming.



Size



Size of the virtual texture in tiles

The size of this RVT in tiles. The final resolution of the RVT is this value multiplied by the Tile Size. A maximum of 4096 tiles is currently supported. This value is applied to the largest of either width or height from the associated RVT Volume. The size of the smaller axis will be chosen to match the aspect ratio of the RVT Volume.

Size of each virtual texture tile

The tile size used by this RVT. Virtual texture data is rendered and stored in tiles. Using a smaller tile size means that each tile is cheaper to generate, but more tiles need to be generated.

Border padding for each virtual texture tile

The number of padding texels used for each tile. A higher number has a small impact on memory and performance. A value of 0 will cause shading seams from bilinear sampling artifacts at tile edges. A value of 2 should fix this, and higher values are needed to enable anisotropic sampling.



Layout



Virtual texture content

Choose what Material Attributes will be stored in this RVT:

Base Color: Stores only the base color. When compression is enabled, it is stored in BC1 format.

Base Color, Normal: Stores base color and normal. When compression is enabled, the base color is stored in BC1 format and the normal is stored as BC5.

Base Color, Normal, Roughness, Specular: Stores base color, normal, roughness, and specular. When compression is enabled, the base color is stored in BC1 format, and the other attributes are packed into BC3.

Base Color, Normal, Roughness, Specular, Mask: This is the same as above but with an additional generic 8-bit mask channel.

World Height: Stores a 16-bit height value. The value is stored normalized in the range of the minimum and maximum z coordinate from the RVT volume.

This setting needs to match settings in the associated Material Assets for the RVT to work correctly.

Enable BC texture compression

Enables texture compression of the data stored in the RVT. This reduces memory cost by a factor of four to eight times, and improves sampling performance. Using uncompressed is only recommended for debugging and quality comparisons.

Enable clear before render

When this is set each tile is cleared before rendering to it. Disabling this can be an optimization if you know that the texture will always be fully covered by rendering.

Enable packed page table

When this is set the RVT uses an optimized page table setup. This reduces page table memory and update cost but can reduce the ability to share physical memory with other virtual textures.

Enable private page table

When this is set the RVT will allocate its page table resources individually instead of from a globally shared page table atlas. This can reduce total page table memory allocation but can also reduce the total number of virtual textures supported.

Enable adaptive page table

When this is set the RVT uses a sparse adaptive page table. This supports tile counts that are larger than the page table size. This in turn means that larger virtual texture resolutions are possible. There is a small performance cost when sampling an adaptive page table, so this should be set only when large tile counts are required.

Enable continuous page updates

When this is set the RVT will refresh some number pages each frame that have already been generated. The number is controlled by the r.VT.MaxContinuousUpdatesPerFrame CVar. Enabling this can provide a simple solution to visual problems caused when some RVT pages are generated before their dependent textures have been fully streamed.

Low Mips to Remove

The number of low mips to remove from this RVT. Low mips cover the most area and therefore can be the most expensive to render. Removing them can therefore improve performance. However, without the low mips available we can introduce mip shimmering artifacts in the final render. Using streaming low mips is usually a better alternative to this option.

Texture Group

Each RVT can belong to a LOD Texture Group that can be configured to override tile count or tile size per platform.

Runtime Virtual Texture Sample Material Node Settings

The following properties are available on some of the Runtime Virtual Texture Material Expressions in the Material Editor.

Property

Description





Virtual Texture

The Runtime Virtual Texture Asset to sample.

Virtual Texture Content

How to interpret the virtual texture contents. Note that the bound Virtual Texture Asset should have the same setting for sampling to work correctly.

Enable packed page table

Enable page table channel packing. Note that the bound Virtual Texture Asset should have the same setting for sampling to work correctly.

Enable adaptive page table

Enable sparse adaptive page table sampling. Note that the bound Virtual Texture Asset should have the same setting for sampling to work correctly.



Texture Sample



Mip Value Mode

Defines how the Mip Value property on a Runtime Virtual Texture expression is applied to the virtual texture lookup.

None (use computed mip level): Uses hardware computed sample's mip level with automatic anisotropic filtering support.

MipLevel (absolute, 0 is full resolution): Explicitly computes the sample's mip level. It disables anisotropic filtering.

MipBias (relative to the computed mip): Bias the hardware computed sample's mip level. It disables anisotropic filtering.

Extreme settings here can have an impact on performance. For example, a large negative MipBias or forcing a MipLevel of 0 will require that more virtual texture pages need to be resident. This can cause thrashing of the physical pool

Runtime Virtual Texture Volume

Use the Runtime Virtual Texture Volume to assign a Runtime Virtual Texture Asset to generate an RVT in your scene from Landscape Actors and scene Primitives that use the same RVT Asset.



Properties

Description



Virtual Texture



Virtual Texture

The Runtime Virtual Texture Asset to use.

Scalability Group

The Scalability Group to use for this RVT Volume. This selects which r.VT.RVT.TileCountBias.Group CVar will apply to the RVT set on this volume.

Hide Primitives

Enable this to hide associated primitives in the main pass. This will apply to all primitives that are set to render to the RVT on this volume and which have their "Draw in Main Pass" virtual texture setting set to "From Virtual Texture".

Streaming Texture

The Streaming Virtual Texture Asset to use for the low mips of this virtual texture.

Enable Crunch

Enables use of Crunch library to compress the Streaming Virtual Texture. Crunch is an open-source compression library designed to further compress GPU block-compressed textures (using DXT/BC/ETC compression). It makes data much smaller than Zlib, and decreases CPU cost to decompress.

View Streaming Mips in Editor

Enable this to show the Streaming Virtual Texture for the low mips when in editor. This is disabled by default because the Streaming Virtual Texture is only updated manually with the "Build" button and so can be out of sync during editing sessions.

Actor Properties

Use the following settings and properties for scene Primitives and Landscapes.

Settings and properties specific to the Actors in your scene.



Properties

Description



Virtual Texture



Render to Virtual Textures

An array of runtime virtual textures into which the mesh is rendered for the selected Actor. The Material also needs to be set up to output to a Virtual Texture.

Draw in Main Pass

Render to the main pass based on the selected virtual texture settings:

Never: Never render this Actor in the Main Pass. If there is no RVT in the scene, it will not render at all. Use this for items where it doesn't matter if they are removed if there is no virtual texture support enabled.

Always: Renders the Actor to the RVT and in the Main Pass regardless of virtual texture support. Use this for items that need to both read and write the virtual texture. For example, Landscape setups require this.

Virtual Texture LOD Bias

Bias to the level of detail (LOD) selected for rendering to Runtime Virtual Textures.

Virtual Texture Skip Mips

The number of lower mips in the Runtime Virtual Texture to skip for rendering this primitive. Larger values reduce effective draw distance in the Runtime Virtual Texture. The culling method doesn't consider primitive size or virtual texture size.

Virtual Texture Min Coverage

Set the minimum pixel coverage before culling from the Runtime Virtual Texture. Larger values reduce the effective draw distance in the Runtime Virtual Texture.

Settings and properties specific to Landscape Actors in your scene.



Properties

Description



Virtual Texture



Render to Virtual Textures

An array of runtime virtual textures into which the mesh is rendered for the selected Actor. The Material also needs to be set up to output to a Virtual Texture.

Virtual Texture Pass Type

Render to the main pass based on the selected virtual texture settings:

Never: Never render this Actor in the Main Pass. If there is no RVT in the scene, it will not render at all. Use this for items where it doesn't matter if they are removed if there is no virtual texture support enabled.

Always: Renders the Actor to the RVT and in the Main Pass regardless of virtual texture support. Use this for items that need to both read and write the virtual texture. For example, Landscape setups require this.

Virtual Texture Num LODs

Number of mesh levels to use when rendering Landscape into a runtime virtual texture. Set this value only if the Material used to render the virtual texture requires interpolated vertex data, such as height. Higher values use more tessellated meshes, and are expensive when rendering the runtime virtual texture.

Virtual Texture LOD Bias

Bias to the level of detail (LOD) selected for rendering to the runtime virtual textures.

Settings and properties specific to Landscape Spline Actors in your scene.



Properties

Description



Virtual Texture



Render to Virtual Textures

An array of runtime virtual textures into which the mesh is rendered for the selected Actor. The Material also needs to be set up to output to a Virtual Texture.

Virtual Texture Pass Type

Render to the main pass based on the selected virtual texture settings:

Never: Never render this Actor in the Main Pass. If there is no RVT in the scene, it will not render at all. Use this for items where it doesn't matter if they are removed if there is no virtual texture support enabled.

Always: Renders the Actor to the RVT and in the Main Pass regardless of virtual texture support. Use this for items that need to both read and write the virtual texture. For example, Landscape setups require this.

Virtual Texture Num LODs

Number of mesh levels to use when rendering Landscape into a runtime virtual texture. Set this value only if the Material used to render the virtual texture requires interpolated vertex data, such as height. Higher values use more tessellated meshes, and are expensive when rendering the runtime virtual texture.

Virtual Texture LOD Bias

Bias to the level of detail (LOD) selected for rendering to the runtime virtual textures.

Virtual Texture Skip Mips

The number of lower mips in the RVT to skip for rendering this primitive. Larger values reduce the effective draw distance in the RVT. This culling method doesn't consider primitive size or virtual texture size.

Max Draw Distance in Main Pass

The desired cull distance in the main pass if Draw in Main Pass is set to Always. A value of 0 has no effect.

Workflow

Runtime Virtual Texturing Components

Scene Actor Output Properties

Streaming Virtual Texture Build

Optimizations, Statistics, and Debugging

Additional Notes and Limitations

A Runtime Virtual Texture (RVT) creates its texel data on demand using the GPU at runtime, and works similarly to traditional texture mapping. The RVT caches shading data over large areas, making them a good fit for Landscape shading that uses decal-like materials and splines that are well suited to conform to the terrain.

Workflow

Use the following high-level steps to set up and use runtime virtual texturing in your project:

Create a Runtime Virtual Texture Asset(s) in the Content Browser. It is used to link all the components (Actors, RVT Volume, and RVT Materials) together to render the runtime virtual texture.

Add a Runtime Virtual Texture Volume to the scene from the Modes panel. This is used to place the RVT Asset in the scene.

Configure your Materials to write to the RVT Asset.

Configure Materials to sample from the RVT Asset.

Set up one or more Primitives or Landscape Actors to render to the RVT Asset.

For a step-by-step guide to setting up RVT, see the Runtime Virtual Texturing Quick Start. In this guide, you'll set up a Landscape material and additional scene Actors to work with runtime virtual texturing.

Runtime Virtual Texturing Components

Use the following components to setup and work with runtime virtual textures in your Unreal Engine projects.

Runtime Virtual Texture Asset

The Runtime Virtual Texture Asset contains the configuration details that will be used when creating the RVT in the scene. Think of this as the linchpin in the RVT system that connects your Materials and Actors in the scene that are rendered to the RVT.

The RVT Asset is referenced by the following components:

Each Runtime Virtual Texture Volume placed in the scene is assigned a single RVT Asset.

Individual scene Actors are assigned any number of RVT Assets. When they are within the bounds of a volume that uses one of their assigned RVT Assets, they are rendered to the runtime virtual texture.

Before an Actor is rendered to the RVT through the RVT Volume, its Materials must use the Virtual Texture Material Domain or use properly setup RVT Material Expressions.

Create a new RVT Asset from the Content Browser using the right-click context menu or the Add New button. Under the Materials & Textures category, select a Runtime Virtual Texture.





Click image for full size.



Double-click the Asset to open and configure its settings in its own Editor window:



Use this window to define the size, tile size, and type of Material Attributes supported by the runtime virtual texture.

For details and usage of these settings, see Virtual Texture Settings page.

From the right-click context menu, you have a couple of actions that can help you manage your RVT Assets in Materials:



Find Materials Using This will find and highlight in the Content Browser all the Materials that reference this RVT Asset.

Fix Material Usage provides an automated way to fix all Materials after changing an RVT Asset Material Type. It finds all Materials and Material Functions that contain a Runtime Virtual Texture Sample node which references this RVT Asset. If the Virtual Texture Material Type in the node does not match the Material Type in the RVT Asset, then the Material Type in the node is fixed to match the RVT Asset.

Runtime Virtual Texture Material Types

When setting up your RVT Material, there are four options to choose from:

Material Type

Description

Compressed Format

Base Color

Stores only the base color.

BC1

Base Color, Normal, Roughness, Specular

Stores the base color, normal, roughness, and specular. When compression is enabled, two BC3 textures are used to hold the data. One texture contains base color and the normal X. The other contains roughness, specular, normal Z direction, and normal Y.

BC3 + BC3

YCoCg Base Color, Normal, Specular

Stores base color, normal, roughness, and specular. When compression is enabled, three textures are used; a BC3 texture holds the base color encoded in YCoCg format, a BC5 texture holds the normal X and Y, and a BC1 texture holds roughness, specular, and normal Z direction.

BC3 + BC5 + BC1

YCoCg Base Color, Normal, Specular, Mask

This is the same as YCoCg Base Color, Normal, Specular but with an additional 8 bit "mask" channel intended for general use. When compression is enabled the mask is packed into the alpha channel of a BC3 format.

BC3 + BC5 + BC3

World Height

Stores a height value. The value is stored normalized in the range of the minimum and maximum z coordinate from the RVT volume.

R16_UNORM

The Base Color, Normal material type available in Unreal Engine 4.23 has been removed. Assets using it are automatically converted to use the Base Color, Normal, Roughness, Specular material type in 4.24.

The YCoCg Base Color, Normal, Roughness, Specular material type enables a different encoding of the Base Color in the RVT.

By default, the Base Color is stored as RGB and compressed to BC1. This type of encoding can lead to color shifts and banding in the stored data. This is most apparent with Base Color data that has smooth gradients. The YCoCg material type helps reduce these types of artifacts. However, using it comes at the cost of 25% extra memory and some additional performance sampling and decoding of the virtual texture data.





Normals are stored with X and Y values in a BC5 texture, or in the alpha channels of two BC3 textures, giving them the same precision as BC5. The Z direction of the normal is also used to store world space normals.

There are two ways to write a normal to a RVT from a Material Graph:

Using a Runtime Virtual Texture Output node

Using a standard material output node

When the material writes from a Runtime Virtual Texture Output node, there are no hidden transforms applied to the output. Whatever is input into the node is written to the RVT (with some encoding to store in the texture).

When the material writes from a standard material output node, an implicit transform is applied. Note that in 4.24 this behavior has changed from previous engine versions. Originally, the default behavior when writing to the RVT from a material output node was to transform the output normal into a shared tangent space defined by the orientation of the RVT volume. In 4.24, the default behavior is to transform the normal into world space.

In 4.26 the ability to write to a RVT from a standard material output was removed. All outputs now need to be written from the Runtime Virtual Texture Output node. Legacy materials are automatically converted to use a RVT Output node.

The recommended way to store normals in an RVT is in world space. The use of this common space should allow for better blending behavior when multiple primitives are writing and reading from the RVT.

Runtime Virtual Texture Volume

The Runtime Virtual Texture Volume is used to place the RVT Asset in the scene. This volume should encompass the Actor that it will render to when the Material is set up. Generally, this should be a Landscape or surface terrain-like primitive.



Any primitives sampling from, or writing to, the runtime virtual texture should be inside the bounds of the volume. When placing the RVT Volume, use the Transform from Bounds parameters in the Level Details panel to quickly position and scale the volume to a selected Actor. Typically, this would be something like a Landscape in your scene.

From the Place Actors panel, drag in a Runtime Virtual Texture Volume to the scene.

With the volume selected, use the level Details panel to locate the Transform from Bounds category and use the Source Actor asset selection (or the eyedropper) to select an Actor in the scene.

Use the Set Bounds button to quickly position, scale, and rotate the volume.

Later when other actors have been set to write to this RVT, Set Bounds will also scale the volume so that the volume bounds include all the relevant actor bounds.

Objects that render to the RVT are rendered using an Orthographic projection in the Negative-Z direction of the RVT Volume.

Runtime Virtual Texture Material Expressions

Scene Actors that have an assigned Runtime Virtual Texture Asset must use the following Material Expressions to enable the Actors to be composited into the generated runtime virtual texture in the scene.

To write to and sample from an RVT in your scene, you must first setup some RVT expressions to handle this for your material:

The Runtime Virtual Texture Output expression is used to define a single material that both writes to and samples the virtual texture. Existing material logic should be plugged into this node.



The Runtime Virtual Texture Sample expression takes in the assigned RVT Asset to sample and outputs that for this material.



The Runtime Virtual Texture Sample Parameter expression works like the Runtime Virtual Texture Sample node but exposes the RVT Asset being sampled as a parameter for Material Instances to override.



Like other parameters, you can create this node directly or by right-clicking a Runtime Virtual Texture Sample node and selecting Convert to Parameter from the context menu.

When using a Material Instance to override the RVT Asset, the RVT Asset assigned must match the Material Type set in the Runtime Virtual Texture Sample Param expression's Details panel.

This is an example Landscape material that writes to and samples the bound RVT Asset. It also uses logic to fall back to traditional landscape rendering when a platform doesn't support Virtual Texturing:





Click image for full size.



Materials are compiled in one of two contexts for use with RVT:

To render to the RVT

To render to other passes

The Runtime Virtual Texture Replace expression is ideal when wanting part of your material logic to render to the RVT.



The View Property expression also has a couple of RVT-specific options:

The Virtual Texture Output Level node outputs the RVT mip level currently being rendered.



The Virtual Texture Output Derivative node outputs the X and Y size of world space covered by a single texel of the current virtual texture output.



The Virtual Texture Max Level node outputs the number of mip levels in the RVT currently being rendered.



An example use case of these expressions would be to mimic the use of some distance-based shading in the RVT. Because RVT shading is camera-independent, this type of shading cannot be expressed directly. However, something similar is achievable by making the shading mip level-dependent. The Runtime Virtual Texture Replace node can be used to implement a mip level-dependent shading path only for the Runtime Virtual Texture Output node.

The Virtual Texture Feature Switch is useful when setting up material logic to fallback to an alternative path when virtual texturing is not supported.

Scene Actor Output Properties

Any Actor placed in the scene can render to an RVT. The following Actor-types are good candidates:

Ideal Actor Candidates

Non-Ideal Actor Candidates

Landscape and Landscape Splines

Static Meshes and Instanced Static Meshes

Foliage Instances (for decal scattering)*

Skeletal Meshes

Movable Static Meshes

Animated Meshes

Because RVT content is effectively a shading cache, it isn't fully updated on every frame, meaning that the objects rendered to it are expected to have their mobility be Static. Skinned and animated primitives are not good candidates for rendering to an RVT.

Use the Render to Virtual Textures array in the Actor Details panel to specify which RVT Assets it can render to in the scene. An actor can be assigned to multiple RVTs. Rendering to an RVT only happens when the RVT Asset has been assigned to a placed RVT Volume in the scene and once the Actor's Materials have been set up correctly.

See the Runtime Virtual Texture Quick Start for an example. Also see the Virtual Texture Setting Reference

Use the sections that follow to further Actor behavior when rendering to an RVT in the scene.

Virtual Texture Pass Type

The Draw in Main Pass options enable you to control the main pass rendering for objects that are set to render to an RVT:

These options enable you to control object rendering to an RVT:



Selection

Description

Never

Never render this Actor in the Main Pass. If there is no RVT in the scene, it will not render at all. This option should be used for items that aren't necessary (such as decal-type materials) when there is no virtual texture support. For example, using a Static Mesh plane with a material outputting to an RVT will write the material like a decal to the RVT landscape material. If a platform or feature level doesn't support virtual texturing, the Static Mesh plane would not render to the Main Pass.

From Virtual Texture

Renders the Actor to either the RVT or the Main Pass, depending on virtual texture support and settings. The actor will not render to the main pass if all of the following are true:

The support for virtual texturing is enabled.

One of the RVT assets referenced by the actor is placed in the scene with an RVT volume.

One of the relevant RVT volumes are set to "Hide Primitives."

For example, a Landscape spline rendering a road mesh and material should write to the RVT to apply its material along the spline. However, if there is no valid RVT in the scene or there is no feature level support for virtual texturing, the spline road mesh will still be visible on the Landscape.

Always

Renders the Actor to the RVT and in the Main Pass regardless of virtual texture support. This is ideal for objects (such as a Landscape) that need to both write to and sample from the RVT. For example, a Landscape material that is set up to both write data to the RVT and render the final RVT should always be visible.

It's recommended to disable collision for primitives that are only being rendered to an RVT. This is not automatically disabled.

Setting LOD and Mips

Use the Virtual Texture Advanced rollout properties to control how Actors render to the RVT by setting level of detail (LOD) and culling behavior. Access these parameters from the Actor's level Details panel:

For Primitives in the scene, adjust the following properties:



Property

Description

Virtual Texture LOD Bias

This sets the LOD to render into the RVT. It is selected automatically based on how much of the virtual texture page the rendered primitive covers. A further bias can be applied using this option. Higher values will force a lower detailed LOD to be used.

Virtual Texture Skip Mips

This is the number of lowest mips in the RVT to skip rendering this primitive. This option removes the cost of rendering into the RVT if it is known that a primitive doesn't need to be rendered beyond some set draw distance.

Virtual Texture Min Coverage

If this value is set, the Virtual Texture Skip Mips parameter is ignored and instead cull (or remove) the primitive from an RVT mip based on its estimated projected size in the mip. This value is in units of pixels but in log space. For example, setting a value of 3 will cull (or remove) a primitive if its projected size is less than 8 pixels.

For Landscapes in your scene, adjust the following properties:



Property

Description

Virtual Texture Num LODs

The number of LODs used to render Landscape components into the RVT. A setting of 0 means that each Landscape component is rendered into the RVT as a single quad. A setting of 0 is optimal for the GPU. Higher values are required if the Landscape Material requires high frequency vertex interpolated data.

Virtual Texture LOD Bias

A bias applied to the selected LOD for rendering to the RVT.

Object Sort Priority

Rendering multiple primitives to the RVT in the scene presents a potential problem for object layer sorting. Since Z-buffering isn't used and the Actor's material can have alpha blending, it means that the sort order may need to be defined.

Use the level Details panel for any selected Actor in the scene to set its Translucency Sort Priority.



All Actors have a default value of 0. Smaller values always render first (or on the bottom layer) and larger ones render last (or on top).





The render order of Actors with the same value is undefined. If an Actor is missing from the RVT in your scene, check the Translucency Sort Priority first.

Streaming Virtual Texture Build

When an RVT covers a large world with many Actors, rendering to the low resolution mips of the RVT can be a slow operation. Also, in this scenario, world Actors need to be permanently resident to be available to render to low mips that represent distant parts of the world. Just keep in mind that this can be expensive for memory.

In this situation, it's more efficient to bake and stream the low resolution mips of an RVT. The higher resolution mips can still be rendered at runtime. In this way, a single virtual texture can make the best use of both Streaming Virtual Texturing and Runtime Virtual Texturing approaches.

Enabling SVT with RVT

To add streaming virtual texture support to an RVT, set the number of low mips that you would like to stream.

In the RVT Volume set the number of Streaming Levels that you would like to stream.



Click image for full size.

A higher number low mip value generates a larger streaming virtual texture that will be used at a closer distance to the camera.

Next you will need to create the streaming virtual texture asset. In the RVT Volume component click the Build below the Streaming Levels property. On first use this will create a new Virtual Texture Builder asset which holds the streaming virtual texture.



Click image for full size.

After editing you'll need to update the streaming virtual texture. This can be achieved in two ways:

Using the Build menu in the Editor Toolbar and selecting the Build Virtual Textures. This option builds all virtual textures in the currently opened Level.



Click image for full size.

Using the RVT Volume component and clicking the Build next to the Use Streaming Low Mips in Editor property. This option builds only the streaming virtual texture assigned to the selected RVT Volume. This option builds only the streaming virtual texture assigned to the selected RVT Volume.

By default, the Editor always renders with runtime generated RVT data and doesn't render with the streaming virtual texture data. This avoids the need to update the streaming virtual texture after each relevant edit.

To render with the streaming virtual texture in the RVT low mips, select the Use Streaming Low Mips in Editor property in the RVT Volume Details panel.

When some RVT asset settings change then any associated SVT asset will no longer match and will be disabled. This could lead to performance problems in game. The RVT volume UI shows when this is the case with a warning icon next to the Build button. The condition is also flagged during Map Check.



Optimizations, Statistics, and Debugging

Use the following sections to explore ways to optimize and debug runtime virtual texturing in your projects.

Stats

Open the console using the backtick (`) key and enter the following commands to enable their stats information:

Use stat virtualtexturing to give you feedback about the virtual texturing scene for cost in milliseconds (ms) and counters for page tables.



Use stat virtualtexturememory to display relevant memory counters related to the use of virtual texturing in the current scene.



Streaming Virtual Texture Low Mips Debugging

To help visualize the distance at which the streaming virtual texture is being used, use the Build Debug checkbox in the RVT Volume Details panel. This can be found next to the Use Streaming Low Mips in Editor property.



When this option is set the streaming virtual texture rebuilds data with a tint so that it's easy to see where the streaming virtual texture mips are being used.

Memory Pools

The Memory Pool Sizes for virtual texturing are set up in the BaseEngine.ini configuration file. The pools are set up per-texture format group and tile size. Configuration of the pool size is driven by specifying the maximum memory budget for your project. You'll find these settings under the [/Script/Engine.VirtualTexturePoolConfig].

A ScalabilityGroup option has been added to specify which r.VT.PoolSizeScale scalability setting applies to a memory pool.

Debugging

Use the following console variables for debugging virtual texturing in your project:

Console Variable

Description

r.VT.Flush

Use this command to flush all the physical caches in the Virtual Texturing system. It can be useful when you suspect an issue that could be caused by a bad cache invalidation.

r.VT.MaxUploadsPerFrame

Use this command to set the maximum number of page uploads per-frame (default is 64 in Editor and 8 in game). It can be useful when you want to throttle the number of Runtime Virtual Texture Tiles being updated in a frame to prevent performance spikes.

Console Variables and Scalability

The following console variables can be tuned per-project and per-platform or scalability level.

Console Variable

Description

r.VT.MaxUploadsPerFrame

The maximum number of virtual texture page uploads per frame. Reducing this can improve performance at the expense of slower visual updates.

r.VT.MaxUploadsPerFrameInEditor

The maximum number of page uploads per frame when in Editor mode. This is independent of the command r.VT.MaxUploadsPerFrame because in the Editor it's better to trade some runtime performance for a cleaner visualization while working.

r.VT.MaxContinuousUpdatesPerFrame

The maximum number of continuous page uploads per frame. Each of these uploads refreshes a single random page that is already mapped. This only occurs for RVT assets set for continuous upload and when we haven't used the MaxUploadsPerFrame budget with other page updates.

r.VT.MaxContinuousUpdatesPerFrameInEditor

The maximum number of continuous page uploads per frame when in Editor mode.

r.VT.RVT.TileCountBias

This is a bias to apply to the RVT Asset Size in Tiles property. A value of -1 will halve the RVT resolution. A value of 1 will double the RVT resolution.

r.VT.RVT.TileCountBias.Group<x>

This applies the tile count bias only to RVT volumes that have been set to Scalability Group . Note that the variation of the CVar without a Group specified maps to Scalability Group 0..

r.VT.PoolSizeScale

The scale factor to apply to the virtual texture physical pool sizes. A value of less than 1 will reduce the texture pool sizes. This may be necessary on platforms that are more memory constrained.

r.VT.PoolSizeScale.Group<x>

This applies the scale factor only to virtual texture physical memory pools that have been set to Scalability Group . Note that the variation of the CVar without a Group specified maps to Scalability Group 0.

r.VT.MaxAnisotropy

This is the specific MaxAnisotropy setting for Virtual Texture sampling.

Additional Notes and Limitations

Sampling a virtual texture from the Vertex Shader stage is possible. However, use this with extreme caution since no virtual texture GPU feedback will be generated by the vertex shader.

1 - Project Setup

2 - Creating a Runtime Virtual Texture Asset

3 - Creating a Runtime Virtual Texture Material

Required Material Setup

Writing to the Runtime Virtual Texture Asset

Sampling from the Runtime Virtual Texture Asset

4 - Placing a Runtime Virtual Texture Volume

5 - Rendering Actors to a Runtime Virtual Texture

6 - On Your Own!

This guide refers to materials found in the Content Examples project available from the Epic Games Launcher under the Samples tab. While the materials are not required to do the steps below, setting up the landscape to function properly with painted landscape materials is. See the Landscape Quick Start Guide before continuing, or open the Content Examples project Landscapes map under the Samples tab for use with this guide.

In this Runtime Virtual Texturing (RVT) quick start, we'll walk through the process of setting up and using RVT for your Landscape and non-Landscape components in your projects.

Before starting this guide, it's important to understand that Runtime Virtual Textures work best with Landscape terrains for a few reasons:

Complex Landscape materials cache the shading results for a performance win.

Improved quality and variation are achievable with spline and decal-type effects.

Blending of non-Landscape Actors with your Landscape is handled by the same RVT Asset.

After going through this guide, you'll have a better understanding of:

Setting up a Runtime Virtual Texture Asset and how it connects to different components.

Enabling Runtime Virtual Texturing for a Landscape Material.

Setting up a Runtime Virtual Texture Volume in your Level.

Setting up additional Actors to render to the Runtime Virtual Texture.

1 - Project Setup

Before you can use Runtime Virtual Textures, you must first enable it for your project. Follow these steps:

From the main menu, select the Edit menu and select Project Settings. Under the Engine > Rendering > Virtual Textures category, set Enable virtual texture support to true.



Restart the Project.

2 - Creating a Runtime Virtual Texture Asset

The Runtime Virtual Texture Asset contains the configuration details for the RVT Asset assigned to a Runtime Virtual Texture Volume. The RVT Asset also works by linking Materials and other Actors in your scene that need to share data.

In the Content Drawer, use the right-click context menu or the +Add button to create a Runtime Virtual Texture Asset from the Textures category.



Give the Runtime Virtual Texture Asset a name. For this guide, it is named VT_Test.

Double-click the Asset to open the Runtime Virtual Texture Asset Editor where you can configure its properties.



From this window, you can define the size, tile size, and type of Material Attributes the runtime virtual texture supports. These properties can be adjusted in real-time while working in the editor to see their changes take effect.

For details and usage of these settings, see Virtual Texture Settings page.

3 - Creating a Runtime Virtual Texture Material

For details and usage of these settings, see Virtual Texture Settings page.

In this step, we'll be using a simple Landscape material for runtime virtual texturing support. In addition, we'll set up logic using some RVT-specific Material Expressions that allow for the material to fall back to its original use when virtual texturing isn't available on a supported platform.

Setting up your material to work with RVT requires that two contexts be considered:

Part of the material will write to the RVT Asset.

Part of the material will sample from the RVT asset and apply further logic.

This example landscape material, taken from the Content Examples project, has a simple layer blend setup for Snow, Grass, and Rock.





Click the image for full size.



If you're not using the material from Content Examples, you can recreate it as shown above. However, keep in mind that you'll still need to properly set up the Material for use with a Landscape. Follow the Landscape Quick Start Guide if you need a starting point.

The sections that follow will break down parts of this Material to demonstrate how we're writing to and sampling from the RVT Asset.

Required Material Setup

Setting up a Landscape material for use with an RVT Asset is the same as setting up a traditional one, with one exception; Use Material Attributes should be enabled. This option enables us to use Make Material Attributes expressions to rebuild and output the material for different use cases supported.

Open your existing or available Landscape material. Right-click in the graph and search for a Make Material Attributes expression. Add one to your graph.

Move the wire connections from the Main Attributes node to the Make Material Attributes node. You should have something that looks like this:





Click the image for full size.



Now, with the Main Attributes node selected, use the Details panel to enable Use Material Attributes.



Pull off the output of the Make Material Attributes node and create a Virtual Textures Feature Switch node. This should plug it into the No input. Connect that to the Material Attributes output.



Your material should now look like this:

[



Click the image for full size.



Writing to the Runtime Virtual Texture Asset

Next, the material needs to write to the RVT Asset through the Runtime Virtual Texture Output expression. This node references the RVT Asset created earlier in this guide and enables corresponding Material Attributes (such as Base Color, Roughness, and Normal) to be used as input attributes of this node.

Right-click and add a Runtime Virtual Texture Output node to the graph.





Click the image for full size.



Connect the node wires for each material attribute input that is listed on the node. For ones not used in your base material, use a constant value in its place.



Your material should now look like this:





Click the image for full size.



The first part of this material is where all the layer blending and logic is happening. It is all the camera-independent shading that can be cached to the RVT Asset. Other objects (such as splines and decals) are expected to be composited to the output of this node by the RVT System.

Sampling from the Runtime Virtual Texture Asset

Next, the material needs to sample from the RVT Asset using the Runtime Virtual Texture Sample expression.

During this part of the graph, the RVT Asset is sampled and applies camera-dependent or additional shading operations here. The RVT Asset attributes are sampled and routed to the final Material output, so the less work is done during this part of the graph, the cheaper the rendering for this material will be.

Right-click and add a Runtime Virtual Texture Sample node.





Click the image for full size.



Right-click and create another Make Material Attributes node. Connect the outputs of the Runtime Virtual Texturing Sample node to the corresponding inputs of the Make Material Attributes node.



Connect the output of the Make Material Attributes node to the Yes input of the Virtual Texture Feature Switch node.





Click the image for full size.



Select the Runtime Virtual Texture Sample node. In the Details panel, use the Virtual Textures Asset selection box to assign the RVT Asset you created earlier in this guide.



Connect the output of the Virtual Texture Feature Switch node to the input of the main Material Attributes node.



Save and Close this Material.

Your material should now look like this:





Click the image for full size.



4 - Placing a Runtime Virtual Texture Volume

Now that your material is set up to support runtime virtual texturing, you can move to your Level where you will place a Runtime Virtual Texture Volume to apply the RVT material to a surface, in this case, a landscape terrain.

In the Place Actors panel, search for a Runtime Virtual Texture Volume under the Volumes category and drag it into the scene.





Click the image for full size.



With the RVT Volume selected, under the Virtual Texture section, set the Virtual Texture material assignment box to use the Runtime Virtual Texture Asset created in Step 2 of this guide.



The RVT Volume is not yet properly scaled to cover the areas you want to apply the RVT material. Select the RVT Volume, and in its Details panel in the Transform from Bounds section, set the Source Actor to the one you want to use. In this example, Landscape_2 is used.



Click the Set Bounds button to scale the Runtime Virtual Texture Volume to the bounds of the selected Actor.



Any Actor sampling from or writing to the Runtime Virtual Texture must be within the RVT Volume's bounds.

Select the scene Actor (Landscape_2) and in the Details panel under the Virtual Texture section, click the Add Element icon next to Draw in Virtual Textures.



Use the Asset assignment dropdown to select your Runtime Virtual Texture Asset.



With the Runtime Virtual Texture Volume placed and scaled around the landscape terrain and the Runtime Virtual Texture Asset assigned to the landscape, the terrain material should immediately become visible. If something is not set up correctly, the landscape will render black.

5 - Rendering Actors to a Runtime Virtual Texture

With your landscape's material set up, other scene Actors can be set up to render into the runtime virtual texture, such as the road spline following the terrain. Any Actors that are set up to output to a runtime virtual texture and are within the placed RVT Volume will be captured and rendered as part of the Runtime Virtual Texture Asset applied to the landscape.

The spline in this section of the guide is a Landscape Spline that is already set up in Content Examples. The steps shown here can be applied to other scene Actors and their Materials to achieve the same effect.

Navigate to the Modes dropdown menu, select Landscape.



On the Landscape toolbar, click on Splines.



In the Level Viewport, select any part of the spline. In the level Details panel, click the Segments button to select all segments that make up this spline.



Under the Landscape Spline Meshes category, expand the Spline Meshes array. The Static Mesh SM_Street should be assigned. Double-click on it to open the Static Mesh Editor.



Under its Material Slots, double-click on Element 0 M_Street material to open it in the Material Editor.



For this Static Mesh and Material assigned, Element 0 was chosen because it is the parent Material used for slots 0 and 1, with Element 1 being a child Material Instance of Element 0. Keep in mind that any Material that is to be rendered to the RVT Asset needs to be set up to render into a runtime virtual texture using the steps that follow.

In the material graph, right-click and add a Runtime Virtual Texture Output node. Connect the Color and Roughness node outputs to the BaseColor and Roughness inputs on the Runtime Virtual Texture Output node.



Save and Close for both the Material and Static Mesh Editors.

In the Level Viewport, select any part of the Landscape Spline. In the Details panel, click the Segments button to select all attached spline segments.



With the spline segments still selected, scroll down in the Details panel to the Virtual Texture section, and click the Add Elements (+) icon. Select your Runtime Virtual Texture Asset from the assignment dropdown.



The primitive (or landscape spline in this demonstration) is now rendered into the RVT. However, the primitive is still visible. If you don't want the primitive to be visible in the main pass and to only have it rendered to the RVT, place the Level Viewport back into Select mode using the Modes dropdown and select the Runtime Virtual Texture Volume placed in the Level. Under the Virtual Texture section's advanced properties, enable Hide Primitives.



In the Level Viewport when in Game View, the Landscape Spline should be rendered into the Runtime Virtual Texture Asset and applied to the terrain's surface, and the spline primitive should no longer be visible.





Here's a closer look at the spline material being applied to the surface of the landscape using RVT.





6 - On Your Own!

Now that you've worked through this guide and set up a Landscape material to use a Runtime Virtual Texture, you can start to explore applying your own Actor's materials to be rendered to the RVT. Use some of the suggestions below to get started:

Add another Static Mesh to the RVT that can be applied like a decal. Look at how you can use a Static Mesh Plane with a masked material to add decal-like details to your terrain.

Use Foliage instances to paint meshes that can render to the RVT to create unique variations to your terrain.

Use multiple Runtime Virtual Texture Assets to manage different types of Actors, and how they render to your Runtime Virtual Texture Volume.

Use the Translucency Sort Priority to set the layer order for how Actors are rendered to the RVT. For example, 0 would be the bottom layer and higher values would stack on top of each other.

Enabling Virtual Texturing

Converting Textures and Materials

Conversion Menu Option

Manual Conversion

UDIM Support

Performance and Cost

Stat Virtual Texturing

Streaming Virtual Texturing Visualization

Material Lookups and Stacks

Additional Material Notes

Limitations

Streaming Virtual Texturing (SVT) is an alternative way to stream textures in your project from disk. SVT has several advantages—along with some disadvantages—when compared to existing mip-based Texture Streaming in Unreal Engine.

Traditional mip-based texture streaming performs offline analysis of material UV usage and then at runtime decides which mip levels of a texture to load based on object visibility and distance. This process can be limiting because streaming data considered is the full texture mip levels.

When using high-resolution textures, loading a higher mip level of a texture can potentially have significant performance and memory overhead. Also, the CPU makes mip-based texture streaming decisions using CPU-based object visibility and culling.

Visibility is more conservative—meaning your system is more likely than not to load something—to avoid objects popping into view. So, if even a small part of the object is visible, the entire object is considered visible. The object loaded including any associated textures that may be required to stream in.

In contrast, the virtual texturing system only streams in parts of the textures that UE requires for it be visible. It does this by splitting all mip levels into tiles of a small, fixed size. The GPU determines which of the visible tiles are accessed by all visible pixels on the screen. This means that when UE considers an object to be visible, it's communicated to the GPU which loads the required tiles into a GPU memory cache. No matter the size of the texture, the fixed tile size of the SVTs only considers the ones that are visible. Tile GPU computes visibility using standard depth buffers causing SVT requests to only happen for visible parts that affect pixels.

Enabling Virtual Texturing

In the Project Settings under Engine > Rendering > Virtual Textures, check the box next to Enable virtual texture support.





Click image for full size.



Under the Editor > Texture Import > Virtual Textures category in the Project Settings, you can specify a minimum texture size to consider newly imported textures for SVT. If a texture meets that minimum size, Virtual Texture Streaming will be enabled for that Texture Asset automatically.

For information on these settings, see Virtual Texturing Reference page.

Converting Textures and Materials

Enabling virtual texturing for your project means that Textures and Materials require some setup to work correctly; the Texture must enable Virtual Texture Streaming support, and the Material's Texture Samples are required to use a Virtual Sampler Type instead of a non-Virtual one.

Choose from the options below to properly set up your textures and materials for use with SVT.

Conversion Menu Option

Select any Texture Asset in the Content Browser that you want to convert to use SVT.

Right-click to open the context menu and select Convert to Virtual Texture.



This menu option also enables you to convert from a virtual texture to a regular texture as well.

The Convert To window lists any Texture(s) that you have selected and any Materials that reference them.



Click Ok to start the conversion process.

During the conversion process, Texture Assets will have Virtual Texture Streaming enabled for them in their Texture Editor settings. Materials that reference the selected texture(s) will convert the Texture Sample nodes to use the Virtual Sampler Type instead of the non-Virtual Sampler Type.

Manual Conversion

Open the Texture Editor for a given Texture Asset by double-clicking it in the Content Browser.

In the Details panel under Texture, enable Virtual Texture Streaming.



Enabling this without using the conversion menu option above will immediately invalidate any existing Materials that reference a converted texture. You should open any Materials that reference the offending texture and set the Texture Sample node to use the correct Virtual Sampler Type. For example, a virtual texture should use a Sampler Type of Virtual Color instead of Color.

When you encounter a Texture Sample node that is not using the correct Sampler Type, UE will display an error message in the Stats panel and along the bottom of the node, like this:



The error message identifies the wrong Sampler Type for the assigned VT Texture Sample expression.

Change the Texture Sample's Sampler Type to be one of the Virtual types.

The VT Texture Sample correctly renders, indicated by the "VT" in the lower-right of the expression.

When adding a virtual texture to a Material Graph, UE assigns the Virtual sampler type automatically. However, should you make the expression a Texture Sample Parameter that you can use in Material Instances, keep in mind that the base material applies the Virtual sampler type to all child instances. Remember that you cannot assign a virtual texture to a texture parameter slot that's not already of Virtual type in the base Material.

UDIM Support

U-Dimension (or "UDIM") is a texture naming convention that enables multiple texture images to map to separate UV regions on a Static Mesh or Skeletal Mesh model. When using the UDIM naming convention, UE will import groups of image files as a single Virtual Texture Asset.

Virtual texturing support for UDIMs is beneficial for a couple of reasons:

It works with many separate, smaller textures instead of extremely large textures.

Each UDIM image can have a different resolution enabling virtual textures that have non-uniform pixel density.

For example, if you import a UDIM virtual texture made up of four image files—two 2048x2048 and two 128x128 textures—arranged in a 2x2 pattern, the virtual texture logically samples these images like a single 4098x4098 texture. UE will stretch the smaller 128x128 images to fill the same area as the larger 2048x2048 images without disk or runtime memory usage affected. Having the smaller 128x128 textures fill a 2048x2048 texture resolution doesn't consume any memory in this case.

For additional information on UDIM workflows, see The Foundry's UDIM Workflow tutorial.

Start using UDIM textures with virtual texturing in your own projects by using this naming convention::

For example:

When UE imports an image matching this naming convention, it scans the source folder for any additional images matching the same BaseName followed by a different coordinate number. For each image that is located, the four-digit number defines the location where UE should map the image. Importing traditional textures map to the mesh UVs in the range of 0-1, however, UDIM image maps to a UV 0-1 space based on its defined UV coordinate.

This grid represents UV mappings to different four-digit coordinates that you can use to store your images:



UVs 0-1 map to the image at 1001 giving you the named texture MyTexture.1001.png. The UDIM index 1001 is the root for this image. If the U coordinate goes from 1-1, you'd have MyTexture.1002.png. If the V coordinate goes from 1-2, you'd have MyTexture.1011.png.

Performance and Cost

Measure the performance and cost of virtual texturing in your project using the sections below:

Stat Virtual Texturing

Open the console using the backtick (`) key and enter the following commands to enable their stats information:

Use stat virtualtexturing to see details about the virtual texturing scene cost in milliseconds (ms) and counters for page tables.



Use stat virtualtexturememory to display relevant memory counters related to the use of virtual texturing in the current scene.



Streaming Virtual Texturing Visualization

Use the console command r.VT.Borders 1 to draw a mip visualization grid on Materials that use streaming virtual textures.



Use r.VT.Borders 0 to hide the grid when you no longer need it.

Material Lookups and Stacks

Sampling from a virtual texture in your materials is more expensive than sampling a traditional texture. You can break the cost of virtual texturing into two categories:

Lookups happen for each Virtual Texture your project samples in the Material Graph.

Stacks combine Virtual Textures when your project uses the same UVs and Sampler Source.

Virtual Textures will always be more expensive than traditional textures sample. There will always be at least two texture fetches and some math instructions. However, some of that cost is amortized by combining the stacks (up to 8) for the VT texture samples that use the same UVs and Sampler Source.

In this simple Material example, UE is sampling two VT Texture Sample expressions using default UVs. A Virtual Texture Lookup is added for each lookup of that texture sample and since both are using a single UV, they are combined into a single Virtual Texture Stack:



However, if your project uses different UVs, the cost increases with two Virtual Texture Stack fetches:



The first example uses three texture fetches total: two lookups and one stack. Because the VT samples use the same UVs, UE combines their stacks to save a texture fetch. In the second example, there is a total of four texture fetches: two lookups and two stacks. The VT Texture Samples use different UVs for the Base Color and Normal Texture Samples meaning they cannot be combined into a single stack.

Additional Material Notes

UE splits streaming virtual textures into fixed size tiles for each texture, no matter its size. It also limits the lowest resolution mip by the tile size. In many cases, this won't be an issue, however, textures with a lot of noise or high detail may exhibit aliasing or Moiré effects due to lack of low-resolution mips. Keep in mind that this also poses potential GPU performance cost, although that can be difficult to measure in practice.

Limitations

In general, virtual textures are interchangeable with regular textures with exception that there are some limitations and added cost:

Texture dimensions must be a power of 2 but UE does not require them to be square by nature. However, they utilize memory more efficiently in the current implementation.

Support for trilinear filtering between mips is done in a stochastic manor. When using Temporal Anti-Aliasing (TAA), it is nearly indistinguishable from regular trilinear filtering but can introduce some visible noise in cases.

UE limits support for anisotropic filtering by the size of the Tile Border setting. The default value of 4 allows for less anisotropic filtering than is typical for textures but increasing this value increases memory usage.

VT streaming is reactive by nature, meaning that the CPU doesn't know it needs to load a given VT tile until after it has already been required by a rendered frame. So, as the camera moves through the scene, some visible popping in may occur, especially as higher resolution VT tiles are loaded.

How Culling Works

Testing Visibility with an Actor's Bounds

Culling Methods

Distance

Per-Actor Instance

Cull Distance Volumes

View Frustum

Precomputed Visibility

Dynamic Occlusion

Hardware Occlusion Queries

Hierarchical Z-Buffer Occlusion

Round Robin Occlusion for VR

Performance Statistics

Debugging Culling

Visualizing Occluded Actors

Freezing Rendering of the Scene

Using Game View Mode

Unreal Engine provides methods of culling for visibility and occlusion. These culling methods are useful for optimizing game performance. Each method works to reduce the number of visible Actors in the Level by setting whether they should be drawn to the screen or not. Some of these methods (such as View Frustum and Hardware Occlusion Queries) can work simultaneously or are better suited to specific devices and platforms (such as Round Robin Occlusion for virtual reality).

How Culling Works

To get a sense of what Unreal Engine offers by default without any setup, we'll look specifically at View Frustum culling and Hardware Occlusion Queries.

The general idea of visibility and occlusion culling methods is to reduce the number of visible objects at any given time with the goal of gaining performance.

For example, if we start with only what the camera can see from its position, there are only a handful of objects visible (Scene View). However, we know that is not entirely the case because there are a lot of objects around that make up the scene that just are not visible from this position (Top Down Scene View).



Scene View



Top Down Scene View

The objects outside of the camera's field of view (the view frustum) aren't visible, and can be culled (objects outlined in red).





Culled objects outside of the camera's view frustum are no longer rendered, leaving only a handful of objects within this view that are occluded by another object that need to be checked for visibility. So, during this pass, a query will be sent to the GPU to test each of these object's visibility state. Those that are occluded by another are culled from view (objects outlined in blue).





All objects that are outside of the view frustum or that are occluded are now culled from view. The final scene view now matches the objects we know to be visible in the scene from the camera's position.



Unreal Engine provides a number of culling methods, each with their own advantages and disadvantages where some are available for specific platforms.

For additional information, see Culling Methods below.

Testing Visibility with an Actor's Bounds

Each Actor placed in a Level has a set of bounds using a box and a sphere that is used for various things in the Engine. One of those being specifically to test whether an it is visible or not. The bounds of an Actor is made up of two parts: a sphere and a box. The bounding sphere is used for fast collision detection with a simple distance test, and, more often than not, it's greater in size than the object it contains. On the other hand, the bounding box is a closer match to the shape of the object and provides more accurate results.

Visualize bounds of Actors in the Level Viewport by selecting Show > Advanced > Bounds. Alternatively, in the Skeletal Mesh Editor you can select Character > Bounds and in the Static Mesh Editor, select Bounds in the main toolbar.



An Actor with its bounds (sphere and box) displayed.

Each Static Mesh and Skeletal Mesh has its own bounding box and sphere that automatically scales to the size of the geometry when imported, or when scaled or rotated in the viewport.

You can edit an Actor's bounds using the following ways:

By setting the Bounds Scale from its Details panel when it's selected in a Level or in a Blueprint. The Bounds Scale uniformly scales the bounds of an Actor, acting as a multiplier of the original scale values.



Click image for full size.

By opening the Static Mesh or Skeletal Mesh Editors to apply non-uniform scaling for Positive Bounds Extension and Negative Bounds Extensions using the Details panel.

Increasing an Actor's bounds can potentially impact performance and shadow quality by keeping the Actor from being culled sooner than it would otherwise have been.

Culling Methods

A culling method is used to track the visibility state of each Actor in your level. The scene's data is culled and tested against whichever method(s) are being employed by your project.

The following culling methods are applied in this order based on their cost:

Distance

View Frustum

Precomputed Visibility

Dynamic Occlusion

Unreal Engine uses View Frustum culling and Hardware Occlusion Queries (Dynamic Occlusion) by default for any project. If your project has a lot of Actors this can come at a cost to GPU performance, especially in instances where there are a lot of Actors visible within the scene view.

Distance

Distance culling methods, like per-Actor settings and Cull Distance Volumes, render or don't render Actors based on the Actor's distance from the camera.

Each Actor in the level has its own settings for draw distance that can be set using the Details panel. There, you can set a minimum and maximum draw distance from the camera (in Unreal Units) for which this Actor should be rendered.



Set the following with the Actor's draw distance settings:

The Minimum Draw Distance an Actor should be visible from the camera. It is the closest you can get to an Actor before it is no longer rendered.

The Maximum Draw Distance an Actor should be visible from the camera. It is the farthest you can get from an Actor before it is no longer rendered.

And you can view (but not edit) the Current Maximum Draw Distance. It displays the stored cull distance set by a Cull Distance Volume, if one exists.

Cull Distance Volumes use an array of distances and sizes to set whether an Actor is rendered or not when within the volume. This culling method is ideal for large outdoor levels where you would have buildings or structures of some type with detailed interiors where you'd wanted to cull those objects that are too small to consider important at far distances.

For additional information, see Cull Distance Volumes.

View Frustum

View Frustum culling uses the visible screen area of the camera's field of view (FOV) to cull objects not within this space. The view frustum is a pyramidal shape that includes a near and far clipping plane which defines the closest and farthest any object should be visible within this space. All other objects are removed to save processing time.



The Near Clipping Plane is the closest point to the camera that objects will be visible.

The Camera Frustum is the pyramidal shaped representation of the visible viewing area between the near and far clip planes.

The Far Clipping Plane is the farthest point from the camera that objects will be visible.

Visualize the view frustum while editing in the Level Viewport by selecting Show > Advanced and enable Camera Frustum.



Camera frustum visualization enabled.

For additional information, see the How Culling Works section above.

Precomputed Visibility

Precomputed Visibility Volumes store the visibility state of non-movable Actors in cells placed above shadow casting surfaces. This culling method generates visibility data offline (during a lighting build) and works best for small to medium-sized levels. Precomputed visibility is ideal for lower-end hardware and mobile devices. For such hardware and devices, when considering performance costs, you'll gain the most by trading rendering thread costs that are more expensive for runtime memory ones where there is more flexibility with regards to performance.

For additional information, see Precomputed Visibility Volumes.

Dynamic Occlusion

The dynamic occlusion system comes with several culling methods to choose from. Each of these methods track the visibility states of Actors in a level within the camera's view frustum (or field of view) that are occluded by another Actor. Queries are issued to the GPU or CPU to check the visibility state of each Actor. A heuristic is used to reduce the number of visibility checks needed, in turn, increasing overall culling effectiveness and performance.

Unreal Engine uses the scene depth buffer when issuing occlusion queries. It enables longer view distances since it relies on approximate distances rather than a maximum draw distance (or far clipping plane). Using the depth buffer enables Actors which are movable or non-movable to occlude or be occluded by another Actor, including those using materials with opaque or masked blend modes.

The primary dynamic occlusion method employed is Hardware Occlusion Queries, which issues visibility checks to the GPU each frame as a query per-Actor. The Actor's visibility is read back one frame later—which can sometimes have the adverse effect of causing them to "pop" in if the camera is moving very fast. The cost of hardware occlusion scales with the number of queries performed on the GPU. Use Distance and Precomputed Visibility methods to reduce the number of queries performed each frame by the GPU.

Hardware occlusion queries are enabled by default and will work on any platform that supports it, including some higher-end mobile devices that support ES 3.1 or higher on iOS and Vulkan on Android. Devices that do not support hardware occlusion queries can disable it from the Project Settings under Rendering > Culling by unchecking Occlusion Culling or by setting the following console variable in a device config file:

For additional information on the cost of dynamic occlusion, see Performance Statistics below.

Hierarchical Z-Buffer (HZB) occlusion works just as Hardware Occlusion Queries does, except that it is more conservative in the way that it culls objects, meaning fewer objects are culled as a result. It uses a Mip mapped version of the Scene Depth render target to check the bounds of an Actor. It requires fewer texture fetches when sampling from a lower MIP, also.

HZB Occlusion can be enabled by using the following console command:

Round Robin Occlusion is one of the dynamic occlusion query methods to improve stereo rendering performance by alternating between one eye each frame instead of both. There is an added frame of latency to occlusion data which could result in incorrect rendering in the the periphery with the trade off being that Round Robin Occlusion saves an entire frame's worth of queries. The trade off in savings can help most with scenes that are draw call or visibility bound.

Enable Round Robine Occlusion in your .ini config file or at runtime using the following console variable:

Performance Statistics

No matter the size of your game, one of the most important development passes to do is performance optimization. Culling objects from your scene is a good way to go about doing that. The statistics window enables you to look at various stats reflective of how visibility and occlusion culling are performing.

For example, for Precomputed Visibility, you would want to keep an eye on how much memory is being used at runtime to load culled object data. For Hardware Occlusion Queries, you'd want to check how many primitives are being sent to the GPU during any given frame if you're experiencing performance issues, like hitching or sluggishness.

Call the stats window by entering stat initviews into the console window.



Scene stats taken from the Infinity Blade Grasslands that is available on the Epic Games Marketplace.

The stats displayed are broken up into two sections: Cycle Counters and Counters. The Cycle Counter stats focus on the number of rendering cycles in milliseconds (ms) that it took to process primitives. There you'll focus on the View Visibility, Occlusion Cull, View Relevance, and Frustum Cull. The Counter stats add all the primitives that have been processed in the current view.

Keep the following in mind when testing visibility and occlusion culling:

Occlusion culling is disabled in Wireframe view mode.

Use the hotkey G to switch to gamemode view while working in the viewport to see some culling methods, like Cull Distance Volumes or Precomputed Visibility Volumes.

For the most accurate results, use Stat InitViews statistics when in Play-In-Editor (PIE) or Standalone Game. Geometry for the Actors that represent Lights, Cameras, and others will be included when calculating visibility and occlusion culling results.

Keep an eye on Visible Static Mesh Elements because it is the single biggest contributor to rendering thread time and should be carefully watched and optimized.

Stat Name

Description



Cycle Counters



View Visibility

The amount of frame time spent to process Actor visibility queries.

Occlusion Cull

The amount of frame time spent to query the scene for Actors within the view frustum that were occluded by other Actors.

Frustum Cull

The amount of frame time spent to query if an Actor's bounds were within the view frustum.

Decompress Occlusion

The amount of frame time it took to load the precomputed visibility.



Counters



Processed Primitives

The total number of Actors that are being processed in the scene.

Frustum Culled Primitives

The number of primitives culled when not within the view frustum FOV.

Occluded Primitives

The number of Actors that are occluded by other Actors from within the view frustum FOV.

Occlusion Queries

The number of scene occlusion queries sent to the GPU based on the number of Actors visible within the view frustum.

Visible Dynamic Primitives

The number of dynamic primitives in the scene that have their mobility set to Movable, like Particle Systems and Foliage instances.

Visible Static Mesh Primitives

The number of visible meshes that have their mobility set to Static within the scene.

Debugging Culling

Below are debugging options you can use for visibility and occlusion culling.

Visualizing Occluded Actors

You can use a visualization command while working in the Editor to check if an Actor is occluded.

When enabled, a green bounding box is drawn around any occluded Actor.

If you have a lot of Actors in your Level, this visualization may not be a useful debugging method without hiding some parts of your Level and their contained Actors.





In this example, note that only Actors fully occluded by the walls and doors are occluded. The ones on the right visible through the hole in the wall are not fully occluded.

Freezing Rendering of the Scene

You can "freeze" the rendering state for Actors in your Level while working in the Editor so that you can freely move around within the Level viewport and inspect occlusion results.

Enter the command FreezeRendering from the view you want, like the example below.



Once entered, freely move around the scene to see the occlusion result. When moving the view to be behind the wall, objects fully occluded are not rendered and the Actors that were not fully occluded still are.





Use the following commands to freeze rendering states for other types of Actors:

Console Command

Description

FreezeRendering

Pauses / Unpauses the current rendering state of occluded and visible Actors in the Level based on the camera view.

Foliage.Freeze

Pauses the current rendering state of occluded and visible painted foliage clusters in Level based on the camera view.

Foliage.Unfreeze

Unpauses the rendering state of occluded and visible painted foliage clusters in the Level.

FX.FreezeParticleSimulation

Pauses / Unpauses any CPU sprite particle simulations in the Level.

FX.FreezeGPUSimulation

Pauses / Unpauses any GPU sprite particle simulations in the Level.

Using Game View Mode

You can use Game View mode to get a sense of what the game will look like while you are working in the Editor. Using this view mode gives you the visual of your game during any play mode, like Play-in-Editor (PIE) mode or Standalone Game, while still enabling you to move around the world and edit objects freely.

Enable Game View using the keyboard shortcut G or use the viewport dropdown menu and select Game View while working in the Editor.





When Game View is enabled, Actor icons are hidden (like they would be in-game), such as those for Lights and Particle Systems. If you're using Cull Distance Volumes or Precomputed Visibility Volumes (and are in the cell), you'll immediately see the culling results of those volumes depending on their culling aggressiveness.

Setup and Usage

Inserting, Deleting, and Duplicating Cull Distance Pairs

Example Scene and Setup

Best Practices

Cull Distance Volumes are a useful optimization tool that defines what distance to draw (or make visible) any Actor within the volume. These volumes store any number of size and distance combinations called Cull Distance Pairs. These are mapped to the bounds of an Actor (along its longest dimension) and then assigned to that Actor instance in the level. Cull Distance Volumes are most useful for optimizing large outdoor levels that have detailed interiors. The interiors can be culled when they are small enough to be considered unimportant.

Setup and Usage

Cull Distance Volumes can be added to your level through the Place Actors panel in the Editor, and you can scale it to fit the level.



With the volume selected, use the Details panel to access the Cull Distance pairs array. Each Cull Distance pair includes a value for Size and Cull Distance. Click the plus (+) sign to add a new Cull Distance pair to the bottom of the array elements list.



By default, there are two Cull Distances pairs added; one to edit as your first entry but with no set size or distance yet, and another that will be keep objects larger than 10000 units from ever being culled because those objects have a distance of 0. By setting cull distances pair that is large, you can keep objects in the far distance, like large buildings or mountains, from being culled.

Inserting, Deleting, and Duplicating Cull Distance Pairs

Use the dropdown next to each array element to insert, delete, or duplicate a Cull Distance pair element.



Insert adds a new Cull Distance pair above the element selected.

Delete removes an existing Cull Distance pair element from the list.

Duplicate copies the selected Cull Distance pair to a new array element below.

You can have as many or as few Cull Distance array elements as you'd like and there is no requirement that they be in sequential order for them to work properly.

Example Scene and Setup

In this example using the Infinity Blades Grasslands project, a few Cull Distance pairs have been set up to cull different sized objects from the camera's position.

The values used here are an extreme example to quickly see how the Cull Distance pairs are working with Actors in the level. Additional pair values and testing would improve the "popping" visible in the example.

The following values have been used for the demonstration that define a few Cull Distances and Sizes:



Objects within the volume that have a size closest to 200 units will be culled from view when they are 1000 units or more from the Camera.

Objects within the volume that have a size closest to 500 units will be culled from view when they are 2000 units or more from the Camera.

Objects within the volume that have a size closest to 1000 units will never be culled. This ensures that very large objects are treated as infinity, meaning the camera can never get far enough away to cull them.

When setting up Cull Distance pairs, keep the following in mind:

The Cull Distance pairs array is not linearly interpolated.

This means you won't have to use dummy pairs and in the event of overlapping Cull Distance pairs, the engine will pick the most aggressive settings (or the lowest that is larger than 0) to assign to an Actor.

You can have as many Cull Distance Pairs as needed.

For organizational purposes, it's best to keep pairs in a sequential order (like highest to lowest), but it is not required.

When adding new pairs, keep in mind you can always add pairs later using the Insert dropdown.

Cull Distance pairs are assigned to Actors with bounds diameters closest to their size. Use the Current Max Draw Distance of an Actor to see what cached draw distance group it's being assigned to based on Cull Distance pair values.

These are some suggested pair values to help get you started:



Best Practices

The following suggestions can help you achieve an effective result:

Use a single Cull Distance Volume to encompass the entirety of the level.

Include a variety of Cull Distance pairs that represent the majority of your level.

For areas within the volume, you can use additional Cull Distance Volumes to have additional, more aggressive control over culling.

When setting up Cull Distance pairs, start with large size and distances to get a sense of the upper and lower limit you want to use.

With the Level Viewport in "Game" view, move around your level to see if there is any visible "popping" in of objects.

Make alterations and possibly add some new Cull Distance pairs between existing ones. Select offending Actors and use their Cached Cull Distance to get an idea of which Cull Distance pair grouping some Actors are falling into.

Keep in mind that Cull Distance pair groups are only used if lower than the Max Draw Distance of the individual Actor.

If you have some Actors that should never be culled by a Cull Distance Volume, use the Actor Details panel and disable Allow Cull Distance Volume.

Keep in mind that if you have a lot of Actors that require this to be disabled, consider having the last Cull Distance pair be your "too large for cull distance" value with a large value for Size and a Cull Distance of 0. This prevents really large objects, such as mountains or buildings, from being culled.

Setup and Usage

Visibility Cells

Setting Cell Play Area Height for Gameplay

Using Precomputed Visibility Override Volumes

Placement

Relevant Statistics

Stat Initviews

Stat Memory

Limitations

Like other culling methods, Precomputed Visibility Volumes are used for performance optimization for small to medium-sized worlds and typically for Mobile where dynamic occlusion culling is limited depending on hardware. Precomputed Visibility Volumes store the visibility state of Actor's locations in the world based on where the player or camera is. For this reason, precomputed visibility is most useful for projects with mostly statically lit environments, restricted player movement, and somewhat 2D play areas.

Visibility cells are generated during a lighting build above shadow casting geometry. Actor visibility is stored from each cells position. Because precomputed visibility is generated offline, you're trading rendering thread time, normally taken up by hardware occlusion queries, at the cost of increasing runtime memory and lighting build time. With that in mind, it is recommended to only place the volumes in player or camera accessible areas to maintain visibility culling.





Setup and Usage

To get started, you'll first need to enable Precomputed Visibility for your Level. Do this by opening the World Settings and locate the Precomputed Visibility section. Once there, enable the checkbox next to Precompute Visibility.



From the Modes panel, drag a Precomputed Visibility Volume into the Level and scale it to fit the playable area.

See Placement below for tips and suggestions to get the best result.



Before precomputed visibility will work, you will first need to Build Lighting and use the Level viewport to enable precomputed visibility cells (blue boxes) by going to Show > Advanced > Precomputed Visibility.

When you are placing volumes, do so in player-accessible areas and not with a single all encompassing volume. This way you're not storing and loading visibility data at run time that can never be used.





If you've already built lighting, you can use the Build dropdown from the main toolbar, then select Precompute Static Visibility to generate visibility cells without re-building lighting each time.



Visibility Cells

After building lighting information at least once for your Level, you can place any number of Precomputed Visibility Volumes and generate the visibility cells that populate the surface of any static shadow casting Actor. You can generate the static visibility by selecting the Precompute Static Visibility option from the Build dropdown menu off the main toolbar.





Use r.ShowRelevantPrecomputedVisibilityCells to only show visibility cells near the camera when the show flag for Show Precomputed Visibility Cells is enabled. This can be helpful to reduce a lot of cells being on screen at once.

In the case of this scene, the precomputed visibility volumes has been placed (green), lighting built, and there are some Actors occluded by the walls and doorway.

Below, to give you a sense of how precomputed visibility works by storing Actor locations in cells, some of the walls and doorway have been hidden. Drag the slider to move the camera position and see the visibility state change based on where the camera is and the cell it's located in.

The precomputed visibility cells are not visible in the example image, to better display the visibility state of the Actors being occluded.



Once precomputed visibility has been generated, the cells store what Actors should be visible from that cell's location. In this example, because the cell knows what should be visible or not, occluding Actors (like the walls and doors) can be hidden and Actors occluded will not be visible as long as the camera is within the precomputed visibility cell, making this culling method well-suited as a trade-off for some game types and platforms.

Setting Cell Play Area Height for Gameplay

One thing to keep in mind when using precomputed visibility is that scale is game-dependent and because of this, parameters for visibility will need to be set accordingly for each game.

To do this, you'll change settings in the BaseLightmass.ini file in [Unreal Engine Root Directory]/Engine/Config folder. Locate the DevOptions.PrecomputedVisibility section.

Of these settings, you'll want to focus on setting PlayAreaHeight. This value is the height (in Unreal Units) above a surface that the visibility cell will be. For your game, this should be the highest the camera can ever be above a surface and is usually the tallest players' eye height plus their jump height.

Setting the PlayAreaHeight or any other settings in the configuration file does not require a restart of the engine. You can make the edit and save the .ini file, then use Precompute Static Visibility in the Build menu dropdown of the main toolbar.





Using the ThirdPerson template, there are a couple of things we need to consider to determine what the PlayAreaHeight should be for this game type:



Finding the Camera's highest rotational point.

The camera can be rotated 360 degrees around the character in the ThirdPerson template. At its highest point, it's approximately 395 units above the ground surface.

Jump height of the player.

The player can jump approximately 210 units high.

Maximum height the camera can ever be.

Adding the highest camera position (365 units) to the player's jump height (210 units), the maximum height the camera can be without going outside of the cell is 615 units.

Knowing the PlayAreaHeight must atleast be 615 units to keep the camera (at any vertical rotation), a little bit of a buffer is added to keep the camera within the visibility cells. The height with the buffer will be 650 units. For this game type and camera movement, it makes sense to have such a large height for the cells. However, keep in mind that larger PlayAreaHeight values require more runtime memory because more Actor visibility states must be stored.

Using Precomputed Visibility Override Volumes

Precomputed Visibility Override Volumes let you manually override the visibility of Actors for their location in the world if the auto generated result of a Precomputed Visibility Volume is undesired. These are also used for performance optimization and should only be placed in areas where the Player can access.

Placement

To use this volume, use the Modes panel to drag a Precomputed Visibility Override Volume into the Level and scale it to fit the playable area.



Use the plus (+) button to add any number of elements to the array list.



For each element added, use the eyedropper or dropdown selection to add an Actor or Level.



For additional information, see Visibility and Occlusion Culling Settings.

Relevant Statistics

When checking performance of precomputed visibility, you'll want to start by looking at some of the stats for Initviews and ones for Memory. These two stat panels inform you how well precomputed visibility is performing and how much memory it's using at runtime in the process.

Stat Initviews

Use the command stat initviews to see how effective precomputed visibility is in your Levels.



Click image for full size.

Stat

Description

Statically Occluded Primitives

Displays how many primitives were determined invisible by precomputed visibility after frustum culling took place. This will only be visible when the camera view is inside a visibility cell.

Occluded Primitives

Displays how many primitives were determined invisible by both precomputed visibility and the dynamic occlusion system.

Decompress Occlusion

Displays how much time was spent decompressing precomputed visibility. Large volumes or smaller cell sizes can increase the memory used which will affect the time it takes to decompress.

If you don't see any values, it's likely the camera is outside of the visibility cell or precomputed visibility has not been generated.



If the Statically occluded primitives is lower than expected, check World Settings > Precomputed Visibility and look at the Visibility Aggressiveness. More aggressive settings cull more Actors but cause more visibility errors to occur, like Actors popping in around corners.

Stat Memory

Use the command stat memory to get an idea of the memory usage being allocated for your game, and more specifically, precomputed visibility.



Click image for full size.

The stat Precomputed Visibility Memory displays the actual runtime memory usage currently being used for precomputed visibility.



This stat is not reliable in Play-in-Editor (PIE) mode since memory usage is being counted for both the Editor and PIE simultaneously. Instead, only use the Editor in Game View mode or Standalone Game to get the most accurate result.

Limitations

The following limitations apply to precomputed visibility:

Does not handle movable Actors.

Does not handle non-opaque Materials, such as translucent or masked materials.

Cells are only placed above surfaces. Projects with flying modes won't get much benefit.

Does not handle streaming levels efficiently. All data is stored in the persistent Level.

Only static shadow casting triangles will occlude.

Project Settings

Actor Settings

Cull Distance Volume

Precomputed Visibility World Settings

Precomputed Visibility Override Volume

In this page, you'll find settings for your project and different volume types that are used for visibility and occlusion culling in your Unreal Engine projects.

Project Settings

The Project Settings contains culling settings that affect the entirety of your project, such as support for Hardware Occlusion Queries, the screen size that lights should be culled, and more.

You can view these settings by opening the Project Settings window, select Rendering and locate the Culling section.



Click image for full size.

Property

Description

Occlusion Culling

Allows occlusion query methods (such as Hardware, Software, and Round Robin Occlusion Queries) to cull Actors. This setting does not disable distance-based culling methods, like Cull Distance or Precomputed Visibility Volumes.

Disabling occlusion culling can have significant performance implications for your project and levels depending on the number of Actors being rendered.

Min Screen Radius for Lights

Sets the minimum screen radius at which lights are culled from view. Larger values can improve performance by culling lights more quickly. However, very large values can degrade performance if large occluders are not rendered.

Min Screen Radius for Early Z Pass

Sets the minimum screen radius for objects to be culled by the Early-Z Pass. Larger values can improve performance by culling objects more quickly. However, very large values can degrade performance if large occluders are not rendered.

Min Screen Radius for Cascaded Shadow Maps

Sets the minimum screen radius for objects to be culled for Cascaded Shadow Map depth passes. Larger values can improve performance. However, they can cause artifacts as objects stop casting shadows at closer distances from the camera.

Warn about no precomputed visibility

Enables a warning when there is no precomputed visibility data available for the current camera location. It can be a helpful reminder if your project relies on precomputed visibility for occlusion.

Actor Settings

Selected Actors in a Level or Blueprint contain distance settings accessed through their Details panel. They enable per-instance distances to be set or whether the Actor is culled using a Cull Distance Volume.



Click for full size image.

Property

Description

Min Draw Distance

Sets the minimum draw distance at which the object will be rendered in the scene. This is measured in world space units (centimeters) from the center of the object's bounding sphere to the camera position.

Desired Max Draw Distance

Sets the maximum draw distance for Level Designers. The "real" max distance is Min Draw Distance (disregarding 0).

Current Max Draw Distance

A read-only distance that the object will be culled at. This value is representative of either the Min Draw Distance or one of the Cull Distances set by a Cull Distance Volume for reference. When a value of 0 is shown, it indicates that this object should not be culled.

Never Distance Cull

When enabled, this object will not be culled by distance. It is also ignored if it's a child of a Hierarchical Level of Detail (HLOD) mesh.

Allow Cull Distance Volume

Whether to accept cull distance volume's cull distance values to modify cached cull distance.

Treat as Background for Occlusion

Enables this object to be treated as part of the background for occlusion purposes. This can be used as an optimization to reduce the cost of rendering skyboxes and large ground planes that are part of the vista.

Use as Occluder

Whether to render the primitive in the depth-only pass. This should generally be true for all objects and let the renderer make decisions about whether to render objects in the depth-only pass.

Cull Distance Volume

Cull Distance Volumes enable you to specify a range of sizes and cull distances that Actors should no longer be drawn.



Property

Description

Cull Distances

A array listing of Size and Cull Distance pairs used to set the draw distance of objects based on their size within a Cull Distance Volume. The code will calculate the sphere diameter of a object's bounding box and look for a best fit in this array to determine which cull distance to assign to an object.

Size --- The size to associate with cull distance.Cull Distance --- The distance to associate with an Actor's bounds size.

Enabled

Whether the volume is currently enabled or not.

Precomputed Visibility World Settings

In the World Settings under Precomputed Visibility you'll have access to settings that change how precomputed visibility is generated.



Property

Description

Precomputed Visibility

Whether to place visibility cells inside Precomputed Visibility Volumes and along camera tracks for this level. Precomputing visibility reduces rendering thread time at the cost of some runtime memory and somewhat increased lighting build times.

Place Cells Only Along Camera Tracks

When this is enabled visibility cells will only be placed along the camera track.

Visibility Cells

World space size of precomputed visibility cells in the x and y. Smaller sizes produce more effective occlusion culling at the cost of increased runtime memory usage and lighting build times.

Visibility Aggressiveness

Determines how aggressive precomputed visibility should be. More aggressive settings cull more objects, but also cause more visibility errors like popping.

For additional information, see Precomputed Visibility Volumes.

Precomputed Visibility Override Volume

Precomputed Visibility Override Volumes enable you to override visibility control of Actors and Levels within an existing Precomputed Visibility Volumes.



Property

Description

Override Visible Actors

An array of Actors that will always be considered visible by precomputed visibility when viewed from inside this volume.

Override Invisible Actors

An array of Actors that will always be considered invisible by precomputed visibility when viewed from inside this volume.

Override Invisible Levels

An array of level names whose Actors will always be considered invisible by precomputed visibility when viewed from inside this volume.

For additional information, see Precomputed Visibility Volumes.

The Renderer module in the engine manages and renders scenes, which hold the renderable information associated with each world. It includes the definition of all drawing policies and shader.

The RHI module, which is the interface for rendering APIs, is another key module for graphics programming. The Graphics Programming Overview covers many key classes, settings, and variables to investigate, while the other subpages below cover specific rendering topics.

FShaderCache

Mesh Drawing Pipeline

Graphics Programming Overview

Parallel Rendering Overview

Render Dependency Graph

Shader Development

AsyncCompute

Shaders in Plugins

Overview of Shaders in Plugins

Creating a New Global Shader as a Plugin

Threaded Rendering

Overview

Use

Integration Steps

Handling Updates/Invalidation

Region/Stream Batching

Overview

The FShaderCache provides mechanisms for reducing shader hitching in-game. It supports the OpenGLDrv and MetalRHI RHIs, and works on Mac, Linux, and Windows platforms.

There are a number of console commands that can be used to enable or disable FShaderCache functionality.

Console Command

Description

r.UseShaderCaching [0/1]

Early submission during shader deserialisation rather than on-demand.

Tracking of bound-shader-states so that they may be pre-bound during early submission.

r.UseShaderDrawLog [0/1]

Tracking of RHI draw states so that each bound-shader-state can be predrawn.

r.UseShaderPredraw [0/1]

Predrawing of tracked RHI draw states to eliminate first-use hitches.

r.PredrawBatchTime [Time in (ms)]

Control over time spent predrawing each frame to distribute over many frames if required. Use -1 for all.

r.UseShaderBinaryCache 0/1

Accumulation of all shader byte code into a single cache file

r.UseAsyncShaderPrecompilation 0/1

Asynchronous precompilation of shader code during gameplay

r.TargetPrecompileFrameTime [Time in (ms)]

The target maximum frame time to maintain when r.UseAsyncShaderPrecompilation is enabled. Use -1 to precompile all shaders at once.

r.AccelPredrawBatchTime [Time in (ms)]

An option to temporarily accelerate predrawing when in a non-interactive mode such as a load screen. Use 0 to use r.PredrawBatchTime.

r.AccelTargetPrecompileFrameTime [Time in (ms)]

An option to accelerate asynchronous precompilation when in a non-interactive mode such as a load screen. Use 0 to use r.TargetPrecompileFrameTime.

r.InitialShaderLoadTime [Time in (ms)]

A maximum amount of time to spend loading the shaders at launch before moving on to asynchronous precompilation. Use -1 to load synchronously)

Use

The cache should be populated by enabling r.UseShaderCaching and r.UseShaderDrawLog on a development machine. Users/players should then consume the cache by enabling r.UseShaderCaching and r.UseShaderPredraw. Draw logging (r.UseShaderDrawLog) adds noticeable fixed overhead so avoid enabling it in shipped products if possible. The binary shader cache can either be accumulated during play through or (currently Mac targets only) during cooking by specifying the shader platforms to cache in the CachedShaderFormats array within the /Script/MacTargetPlatform.MacTargetSettings settings group of Engine.ini. For OpenGL the binary cache contains enough data about shader pipelines to construct fully linked GL programs or GL program pipelines (depending on availability of GL_ARB_separate_shader_objects) but not enough for pipeline construction on any other RHI. This can help reduce the amount of hitching on OpenGL without first playing through the game, though this is still advisable for maximum effect. Since the caching is done via shader hashes, it is also advisable to only use this as a final optimization tool when content is largely complete as changes to shader hashes will result in unused entries accumulating in the cache, increasing cache size without reducing hitches.

The code will first try and load the writable cache, then fall back to the distribution cache if needed.

Cache Type

Cache Location

Writable

<Game>/Saved/DrawCache.ushadercache, <Game>/Saved/ByteCodeCache.ushadercode

Distribution

<Game>/Content/DrawCache.ushadercache, <Game>/Content/ByteCodeCache.ushadercode

Integration Steps

While there are a number of console commands you can use to reduce hitching in your project, there is a recommended priority order to enable options to maximize performance while avoiding additional project work.

Enable r.UseShaderCaching & r.UseShaderPredraw in the project configuration for all users.

If possible, enable r.UseShaderDrawLog only for internal builds & ensure that shader draw states are recorded during final QA for each release. When not feasible (e.g. an extremely large and/or streaming game), enable for all users.

Test whether this setup is sufficient to reduce hitching to an acceptable level, as the additional optimizations require more work and have significant side effects.

If the above is insufficient, then also enable r.UseShaderBinaryCache and configure the CachedShaderFormats to ensure population of the binary cache (currently Mac only).

All shader code will now be loaded at startup and all predraw operations will occur on the first frame, so if the loading times are too extreme also set r.PredrawBatchTime to a value greater than 0 in ms to spend predrawing each frame.

You may also wish to specify a larger value for r.AccelPredrawBatchTime that can be applied when showing loading screens or other non-interactive content.

To inform the shader cache that it may accelerate predrawing at the expense of game frame rate, call FShaderCache::BeginAcceleratedBatching, and when it is necessary to return to the less expensive predraw batching, call FShaderCache::EndAcceleratedBatching.

A call to FShaderCache::FlushOutstandingBatches will cause all remaining shaders to be processed in the next frame.

If the project still takes too long to load initially, then enable r.UseAsyncShaderPrecompilation and set r.InitialShaderLoadTime to a value > 0. As the initial shader load time increases, the work that must be done while the game is running decreases.

You can tweak the desired target frame time while asynchronously precompiling shaders by modifying the value of r.TargetPrecompileFrameTime.

As with predraw batching, a more aggressive value can be specified for precompilation by setting r.AccelTargetPrecompileFrameTime to a larger value and then calling FShaderCache::BeginAcceleratedBatching (and FShaderCache::EndAcceleratedBatching afterwards).

With r.UseAsyncShaderPrecompilation enabled, a call to FShaderCache::FlushOutstandingBatches will also flush any outstanding compilation requests.

Handling Updates/Invalidation

When the cache needs to be updated and writable caches invalidated the game should specify a new GameVersion. Call FShaderCache::SetGameVersion before initializing the RHI (which initializes the cache). This will cause the contents of a cache generated by a previous version to be ignored. At present you cannot carry over cache entries from a previous version.

Region/Stream Batching

For streaming games, or where the cache becomes very large, calls to FShaderCache::SetStreamingKey should be added with unique values for the currently relevant game regions/streaming levels (as required). Logged draw states will be linked to the active streaming key. This limits predrawing to only those draw states required by the active streaming key on subsequent runs.

Cached and Dynamic Mesh Batches

FMeshPassProcessor

Shader Bindings

FMeshDrawCommand Performance Hazards

Pass Types

FParallelMeshDrawCommandPass

DrawDynamicMeshPass

Cached Mesh Draw Commands

Cache Invalidation

Resource Lifetime Management

Draw Call Merging

Dynamic Instancing

GPU Scene

Instancing Efficiency

Mesh Drawing Parallelism

Console Variables

The information contained in this page is targeted at programmers who want to add custom mesh passes, or want to understand Unreal Engine's mesh drawing performance characteristics.

The Mesh Drawing Pipeline is based around a concept of retained mode, where all scene draws are prepared in advance instead of building them every frame. It also features aggressive caching and draw call merging in order to exploit properties of Static Meshes which change infrequently and can be reused across frames.



The journey of a draw.

Mesh rendering starts from FPrimitiveSceneProxy, which is the render thread representation for the game thread's UPrimitiveComponent. FPrimitiveSceneProxy is responsible for submitting FMeshBatch's to the renderer through the callbacks to GetDynamicMeshElements and DrawStaticElements.

FMeshBatch decouples the FPrimitiveSceneProxy implementation (user code) from mesh passes (private renderer module). It contains everything the pass needs to figure out final shader bindings and render state, so the proxy never knows what passes it will be rendered in.

The next step is to convert FMeshBatch into a mesh pass specific FMeshDrawCommand. FMeshDrawCommand is an interface between FMeshBatch and the RHI. It's a fully stateless draw description that stores everything that the RHI needs to know about a mesh draw:

Which shaders to use.

Their resource bindings.

Draw call parameters.

This enables caching and merging the draw calls just above the RHI level. FMeshDrawCommand is created from a FMeshBatch by a mesh pass specific FMeshPassProcessor.

Finally, SubmitMeshDrawCommands is used to convert FMeshDrawCommand into a series of RHI commands set on a RHICommandList.

Cached and Dynamic Mesh Batches

FPrimitiveSceneProxy has two paths for generating FMeshBatches — a cached and a dynamic one. FPrimitiveSceneProxy implementations control which path is used each frame through the GetViewRelevance() function.



FMeshBatch code paths. Orange arrows are operations that have to be done every frame, while the blue arrow indicates an operation that is done once before being cached.

The Cached path builds and reuses FMeshBatch and is preferred for fast rendering of draws which don't change every frame, like Static Meshes. It is implemented by DrawStaticElements, which is called when a proxy is added to the scene. Created FMeshBatches are stored inside FPrimitiveSceneInfo::StaticMeshes and reused every frame until the proxy is removed from the scene.

The Dynamic path recreates FMeshBatch every frame. This is the most flexible path and is used for draws which often change from frame to frame — for example, particles. It's implemented by GetDynamicMeshElements. This function is called every frame from InitViews and creates a temporary FMeshBatch for every view.

FMeshPassProcessor

Specific pass mesh processors are derived from the FMeshPassProcessor base class and are responsible for converting the FMeshBatch into mesh draw commands for a given pass. This is where final draw filtering happens, the appropriate shader is selected and shader bindings are collected.

In order to create a custom mesh pass processor, it must be derived from FMeshPassProcessor and AddMeshBatch function needs to be overridden.

AddMeshBatch implements:

Draw filtering - For example, if a Material has a translucent draw mode then don't process it in FDepthPassMeshProcessor

Selecting shaders and pipeline state (depth/stencil/blend state)

Finally calling BuildMeshDrawCommands() which gathers shader bindings for the pass/material/vertex factory/primitive and adds the new draw command to the appropriate list.

Shader Bindings

Shader Bindings in Unreal Engine can be Uniform Buffers, Samplers, Textures, ShaderResourceViews or loose parameters (FShaderParameter).

A FMeshPassProcessor does not send shader bindings directly to the RHI with RHICmdList.SetShaderParameter, it merely records them into the FMeshDrawSingleShaderBindings class. The BuildMeshDrawCommands() function which is shared code between all passes will call GetShaderBindings() on the pass shaders.

Shader Bindings fall into a few categories:

Pass-constant uniform buffers like ViewUniformBuffer or DepthPassUniformBuffer

Vertex Factory bindings

Material bindings

Primitive bindings

Pass specific bindings which change between draws.

Note that setting different bindings per-draw prevents draw call merging. Also, setting loose parameters — shader parameters that are not in a Uniform Buffer — prevents draw call merging, forcing slow constant buffer updates between draws.

Since each FMeshPassProcessor must go through BuildMeshDrawCommands() to call the pass shader's GetShaderBindings(), we need a mechanism to pass arbitrary data from the FMeshPassProcessor to the GetShaderBindings() call. This is accomplished with the ShaderElementData parameter to BuildMeshDrawCommands().

FMeshDrawCommand Performance Hazards

A number of inline allocators are used in FMeshDrawCommand to store variable length arrays without extra heap allocations. Overflowing these causes a performance hazard, as each mesh draw command must construct/destruct/copy the heap allocation along with cache misses on traversal of the commands.

FMeshDrawShaderBindings assumes 2 shader frequencies (Vertex + Pixel):

FMeshDrawCommand assumes 10 shader bindings among all frequencies:

FMeshDrawCommand assumes 4 vertex streams from the vertex factory:

Pass Types

There are three ways to use a FMeshPassProcessor for drawing:

Pass Types

Description

EMeshPass::Type enum

Adding an entry here allocates an FParallelMeshDrawCommandPass inside FScene. This enables the FScene to cache mesh draw commands for the pass at AddToScene time. An FMeshPassProcessor must be registered to their enum with FRegisterPassProcessorCreateFunction. Pass setup and dispatch happens in a task.

Manual Pass

Using a manual pass where FParallelMeshDrawCommandPass is stored as a variable in an arbitrary class. This is used when there are a variable number of passes each frame (for example, shadow depth pass). This type of pass cannot cache commands at FScene::AddToScene time, but still gets the benefit of pass set up and dispatch happening in a task.

DrawDynamicMeshPass

This is used for immediate mode drawing and is the slowest, but most convenient approach. Pass set up and dispatch happen immediately within the caller thread.

Note that the renderer has not been made extensible to plugins at this time, and with the exception DrawDynamicMeshPass, adding a new pass requires changing renderer module code.

FParallelMeshDrawCommandPass

In order to add a custom mesh pass, first we need to add a new entry to EMeshPass enum. Next, inside FRelevancePacket::MarkRelevant(), and based on relevance flags, add Static Meshes to the list of visible mesh draw commands. For example this snippet adds a mesh draw command into depth pass if it is relevant for depth pass:

Mark EMeshPass relevance for dynamic draws inside ComputeDynamicMeshRelevance:

Use FParallelMeshDrawCommandPass::DispatchDraw to draw this specific pass:

It is also possible to set up a Parallel Command List set in order to draw this pass in parallel:

DrawDynamicMeshPass

FParallelMeshDrawCommandPass is the default path for common mesh passes. It should be used for performance critical mesh passes, as it's the only path which supports mesh draw command caching and parallel rendering. On the other hand performance requirements enforce a very strict design — for example, it is not possible to modify mesh draw commands or shader bindings after InitViews.

For certain use cases, like drawing a few meshes inside the Editor, DrawDynamicMeshPass may be a simpler solution. It provides immediate mode mesh drawing and is the most flexible rendering path. Unreal Engine uses DrawDynamicMeshPass for some Editor-only passes and Canvas rendering.

Drawing with DrawDynamicMeshPass is quite simple, it just requires to pass a lambda which will fill a temporary list of mesh draw commands:

Cached Mesh Draw Commands

Cached mesh draw commands are built-in FPrimitiveSceneInfo::AddToScene inside FPrimitiveSceneInfo::CacheMeshDrawCommands. Drawing with these is very efficient, as we simply need to select the appropriate pre-built commands each frame (FDrawCommandRelevancePacket::AddCommandsForMesh). Cached draw commands can only be used when draw state doesn't change every frame and all shader bindings can be set up inside AddToScene.



Mesh Draw Command caching paths. Orange arrows are operations that have to be done every frame, while blue arrows indicates an operation that is done once and cached.

In order to support cached mesh draw commands:

The pass must be using an entry in EMeshPass::Type

EMeshPassFlags::CachedMeshCommands flag must be passed when registering custom mesh processor

The mesh pass processor needs to be able to set up all shader bindings without relying on FSceneView, as during caching it will be null

In order for the shader to access per-frame data with cached mesh draw commands we bind scene-wide uniform buffers (see FScene::UniformBuffers) and then use RHIUpdateUniformBuffer to change their contents before the draw.

Currently, only FLocalVertexFactory (UStaticMeshComponent) can be cached because all other vertex factories require a view to set up for their shader bindings.

Cache Invalidation

Any data that a Mesh Pass Processor reads in AddMeshBatch is a dependency of the cached mesh draw commands. When that dependency changes, the cached commands must be invalidated. A single primitive's cached commands can be invalidated with FPrimitiveSceneInfo::BeginDeferredUpdateStaticMeshes. The entire scene's cached commands can be invalidated by setting Scene->bScenesPrimitivesNeedStaticMeshElementUpdate to true. This is a heavyweight operation and should be avoided during gameplay as it will cause a hitch in larger scenes.

For example, FBasePassMeshProcessor::AddMeshBatch uses Scene->SkyLight to decide whether to select the Skylight shader permutation or not. When Scene-SkyLight changes, we must invalidate cached mesh draw commands.

To achieve good performance with this caching scheme, it's important to put data in persistent Uniform Buffers. Then, you need to update those buffers rather than invalidating the cached commands frequently. For example, the skylight case could be changed to a dynamic branch in the shader based on PassUniformBuffer contents rather than selecting a different shader permutation.

Resource Lifetime Management

FMeshDrawCommand is not responsible for maintaining the lifetime of any of the resources it references, so special care must be taken with cached mesh draw commands to invalidate the commands which might reference a particular resource. For example, when recreating a Uniform Buffer referenced by a cached mesh draw command will cause a crash when traversing the cached mesh draw commands for rendering. The Uniform Buffer should either be updated or the cached mesh draw commands must be invalidated.

VALIDATE_UNIFORM_BUFFER_LIFETIME can be used to track down cases where a Uniform Buffer is deleted which is still referenced by a cached mesh draw command.

Draw Call Merging

Since FMeshDrawCommands capture all of the state a draw needs just above the RHI level, we can easily compare them for compatibility with draw call merging. The only form of draw call merging currently implemented is based around the D3D11 feature set, which enables merging of draw calls which have identical shader bindings into an instanced draw. More advanced RHIs like D3D12 enable more aggressive merging of draws but this is not yet implemented.

Dynamic Instancing

In order to merge two draws into an instanced one, they must have identical shader bindings (FMeshDrawCommand::MatchesForDynamicInstancing). Only InstanceID in the shader will vary between them, or vertex streams setup at instance frequency.

Shader parameters must be carefully crafted to enable dynamic instancing. This is achieved through various means depending on the parameter frequency:

Pass Types

Description

Pass Parameters

These are placed in the pass uniform buffer, where any draws in the pass can merge.

FLocalVertexFactory Parameters

These are placed in a uniform buffer owned by UStaticMesh where any draws with the same UStaticMesh can merge.

Material Instance Parameters

These are palced in a material uniform buffer where any draws using the same Material Instance can merge.

Lightmap Resource Parameters

These are placed in a LightmapResourceCluster uniform buffer where any draws using the same LightmapTexture can merge.

Primitive Parameters

These are placed in a scene-wide primitive data buffer called GPUScene and indexed in the shader using PrimitiveID.

GPU Scene

In order to have different primitives in the same instanced draw with primitive-specific parameters, supporting platforms (UseGPUScene) upload them to a scene-wide buffer (UpdateGPUScene) and index into it with a PrimitiveId. For FLocalVertexFactory, PrimitiveId comes from a instance-frequency vertex input stream. This must be passed to the pixel shader, which must use GetPrimitiveData(Parameters.PrimitiveId).Member to access Primitive shader parameters, instead of accessing the primitive uniform buffer directly (Primitive.Member).

Instancing Efficiency

Currently, only cached mesh draw commands can be merged with dynamic instancing, which limits dynamic instancing to FLocalVertexFactory.

Certain edge cases also prevent merging:

Lightmaps making small textures — adjust MaxLightmapRadius in DefaultEngine.ini

Per-component vertex colors

SpeedTree Wind node

To investigate dynamic instancing efficiency in a level, use the r.MeshDrawCommands.LogDynamicInstancingStats 1 console command and inspect the output in the log.

Note that the Depth Prepass and Shadow Depth passes achieve higher merging efficiency because they frequently override with the default material's shaders when possible.

Mesh Drawing Parallelism

Most of the work of mesh drawing is in tasks to stay off the critical path of the Rendering Thread. In InitViews at the beginning of the RT frame, FParallelMeshDrawCommandPass issues one task per pass for pass setup (dynamic command generation, sorting and draw call merging). As the RenderingThread progresses through the frame and arrives at a mesh pass (for example, RenderBasePass), it kicks off multiple FDrawVisibleMeshCommandsAnyThreadTasks per pass for draw dispatch (recording the RHICmdList), depending on how many cores the system has and how many draws there are to be dispatched.

Setting r.MeshDrawCommands.ParallelPassSetup to 0 will disable the pass setup task and cause the work to be done on the RenderingThread, which can be useful for debugging.

Setting r.RHICmdBasePassDeferredContexts to 0 will disable the parallel tasks for base pass draw dispatch, causing those to happen on the RenderingThread.

These tasks are kicked off as early as possible with a dependency chain so they can be executed in parallel with the Rendering Thread for a frame. The Rendering Thread only blocks on the completion of these tasks at the end of a frame in FSceneRenderer::WaitForTasksClearSnapshotsAndDeleteSceneRenderer.

Console Variables

These are some useful console variable for diagnosing issues inside the mesh drawing pipeline:

Console Variable

Description

r.MeshDrawCommands.ParallelPassSetup

Toggles mesh draw command processing tasks, which is useful for diagnosing mesh pass threading issues.

r.MeshDrawCommands.UseCachedCommands

Forces all mesh draw commands to be dynamic when disabled, which is useful for diagnosing issues with stale data inside cached mesh draw commands.

r.MeshDrawCommands.DynamicInstancing

This toggles dynamic instancing. It's useful for diagnosing dynamic instancing issues.

r.MeshDrawCommands.LogDynamicInstancingStats

This is useful for inspecting dynamic instancing efficiency.

r.GPUScene.UploadEveryFrame

Forces GPU Scene to be fully updated every frame, which is useful for diagnosing issues with stale GPU Scene data.

r.GPUScene.ValidatePrimitiveBuffer

This downloads GPU Scene to the CPU and validates its contents against primitive uniform buffers.

Getting Started

Modules

Scene representation

Primary scene classes

Material classes

Primitive components and proxies

FPrimitiveSceneProxy and FPrimitiveSceneInfo

Important FPrimitiveSceneProxy methods

Scene rendering order

Relevance

Drawing Policies

Drawing Policy methods

Rendering paths

Dynamic rendering path

Static rendering path

High level Rendering order

Render Hardware Interface (RHI)

Rendering state grouping

Rendering state defaults

Getting Started

There is a lot of rendering code in Unreal Engine so it is hard to get a quick high level view of what is going on. A good place to start reading through the code is FDeferredShadingSceneRenderer::Render, which is where a new frame is rendered on the rendering thread. It is also useful to do a profilegpu command and look through the draw events. You can then do a Find in Files in Visual Studio on the draw event name to find the corresponding C++ implementation.

See Shader Development for information on working with shaders.

See Coordinate Spaces for an explanation of Coordinate Space terminology used in Unreal Engine.

Useful console commands when working on rendering (Usually you get help when using ? as parameter and the current state with no parameters):

Console Command

Description

stat unit

Shows overall frame time as well as the game thread, rendering thread, and GPU times. Whichever is the longest is the bottleneck. However, GPU time contains idle time, so is only the bottleneck if it is the longest and stands alone.

Ctrl+Shift+. or recompileshaders changed

Recompile shaders that have changed since you last saved the .usf file. This will automatically happen on load.

Ctrl+Shift+; or profilegpu

Measure GPU timings for the view being rendered. You can view the results in the UI that pops up or in the engine log.

Vis or VisualizeTexture

Visualize the contents of various render targets with the ability to save as bmp.

show x

Toggles specified show flag. Use show to get the list of showflags and their current state. In the editor, use the viewport UI instead.

pause

Pauses the game, but continues rendering. Any simulation rendering work will stop.

slomo x

Changes the game speed. Can be very useful for slowing down time without skipping simulation work, when profiling. For example slomo .01

debugcreateplayer 1

For testing splitscreen.

r.CompositionGraphDebug

Execute to get a single frame dump of the composition graph of one frame (post processing and lighting).

r.DumpShaderDebugInfo

When set to 1, will cause any shaders that are then compiled to dump debug info to GameName/Saved/ShaderDebugInfo.

r.RenderTargetPoolTest

Clears the texture returned by the rendertarget pool with a special color to track down color leaking bugs.

r.SetRes

Set the display resolution for the current game view. Has no effect in the editor.

r.ViewportTest

Allows to test different Viewport rectangle configuations (in game only) as they can happen when using Matinee/Editor.

Useful command lines when working on rendering:

Commandline

Description

-d3ddebug

Enables the D3D11 debug layer, useful for catching API errors.

-sm4

Forces Feature Level SM4 with the D3D11 RHI.

-opengl3 / -opengl4

Forces use of OpenGL RHI at the specified feature level.

-dx11

currently the default on windows

-dx12

experimental

-featureleveles2

Ignored when running with editor, there the UI has to be used

-featureleveles31

Ignored when running with editor, there it needs to be enabled in Editor Preferences

-ddc=noshared

Prevents the use of network (shared) Derived Data Cache. Can be useful when debugging shader caching issues.

Modules

The renderer code exists in its own module, which is compiled to a dll for non-monolithic builds. This allows faster iteration as we do not have to relink the entire application when rendering code changes. The Renderer module depends on Engine because it has many callbacks into Engine. However, when the Engine needs to call some code in the Renderer, this happens through an interface, usually IRendererModule or FSceneInterface.

Scene representation

The scene as the renderer sees it is defined by primitive components and the lists of various other structures stored in FScene. An Octree of primitives is maintained for accelerated spatial queries.

There is a Rendering Thread, which operates in parallel with the game thread. Most classes that bridge the gap between the game thread and rendering thread are split into two parts based on which thread has ownership of that state.

The primary classes are:

Class

Description

UWorld

A world contains a collection of Actors and Components that can interact with each other. Levels can be streamed in and out of the world, and multiple worlds can be active in the program.

ULevel

Collection of Actors and Components that are loaded / unloaded together and saved in a single map file.

USceneComponent

Base class of any object that needs to be added to an FScene, like lights, meshes, fog, etc.

UPrimitiveComponent

Base class of anything that can be rendered or interact with physics. Also acts as the granularity of visibility culling and rendering property specification (casts shadows, etc). Just like all UObjects, the game thread owns all variables and state and the rendering thread should not access it directly.

ULightComponent

Represents a light source. The Renderer is responsible for computing and adding its contribution to the scene.

FScene

Renderer version of the UWorld. Objects only exist to the renderer once they are added to the FScene, which is called registering a component. The rendering thread owns all states in the FScene -the game thread cannot modify it directly.

FPrimitiveSceneProxy

Renderer version of UPrimitiveComponent, mirrors UPrimitiveComponent state for the rendering thread. Exists in the engine module and intended to be subclassed to support different types of primitives (skeletal, rigid, BSP, etc). Implements some very important functions like GetViewRelevance, DrawDynamicElements, etc.

FPrimitiveSceneInfo

Internal renderer state (specific to the FRendererModule implementation) that corresponds to a UPrimitiveComponent and FPrimitiveSceneProxy. Exists in the renderer module, so the engine cannot see it.

FSceneView

Engine representation of a single view into an FScene. A scene can be rendered with different views in different calls to FSceneRenderer::Render (multiple editor viewports) or with multiple views in the same call to FSceneRenderer::Render (splitscreen in game). A new View is constructed for each frame.

FViewInfo

Internal renderer representation of a view, exists in the renderer module.

FSceneViewState

The ViewState stores private renderer information about a view which is needed across frames. In game, there is one view state per ULocalPlayer.

FSceneRenderer

A class created each frame to encapsulate inter-frame temporaries.

Here is a list of the primary classes arranged by which module they are in. This becomes important when you are trying to figure out how to solve linker issues.

Engine Module

Renderer Module

UWorld

FScene

UPrimitiveComponent / FPrimitiveSceneProxy

FPrimitiveSceneInfo

FSceneView

FViewInfo

ULocalPlayer

FSceneViewState

ULightComponent / FLightSceneProxy

FLightSceneInfo

And the same classes arranged by which thread has ownership of their state. It is important to always be mindful of what thread owns the state you are writing code for, to avoid causing race conditions.

Game Thread

Rendering Thread

UWorld

FScene

UPrimitiveComponent

FPrimitiveSceneProxy / FPrimitiveSceneInfo

FSceneView / FViewInfo

ULocalPlayer

FSceneViewState

ULightComponent

FLightSceneProxy / FLightSceneInfo

Class

Description

FMaterial

An interface to a material used for rendering. Provides access to material properties (e.g. blend mode). Contains a shader map used by the renderer to retrieve individual shaders.

FMaterialResource

UMaterial's implementation of the FMaterial interface.

FMaterialRenderProxy

A material's representation on the rendering thread. Provides access to an FMaterial interface and the current value of each scalar, vector, and texture parameter.

UMaterialInterface

[abstract] Game thread interface for material functionality. Used to retrieve the FMaterialRenderProxy used for rendering and the UMaterial that is used as the source.

UMaterial

A material asset. Authored as a node graph. Computes material attributes used for shading, sets blend mode, etc.

UMaterialInstance

[abstract] An instance of a UMaterial. Uses the node graph in the UMaterial but provides different parameters (scalars, vectors, textures, static switches). Each instance has a parent UMaterialInterface. Therefore a material instance's parent may be a UMaterial or another UMaterialInstance. This creates a chain that will eventually lead to a UMaterial.

UMaterialInstanceConstant

A UMaterialInstance that may only be modified in the editor. May provide scalar, vector, texture, and static switch parameters.

UMaterialInstanceDynamic

A UMaterialInstance that may be modified at runtime. May provide scalar, vector, and texture parameters. It cannot provide static switch parameters and it cannot be the parent of another UMaterialInstance.

Primitive components are the basic unit of visibility and relevance determination. For example, occlusion and frustum culling happen on a per-primitive basis. Therefore it is important when designing a system to think about how big to make components. Each component has a bounds that is used for various operations like culling, shadow casting, and light influence determination.

Components only become visible to the scene (and therefore the renderer) when they are registered. Game thread code that changes a component's properties must call MarkRenderStateDirty() on the component to propagate the change to the rendering thread.

FPrimitiveSceneProxy is the rendering thread version of UPrimitiveComponent that is intended to be subclassed depending on the component type. It lives in the Engine module and has functions called during rendering passes. FPrimitiveSceneInfo is the primitive component state that is private to the renderer module.

Function

Description

GetViewRelevance

Called from InitViews at the beginning of the frame, and returns a populated FPrimitiveViewRelevance.

DrawDynamicElements

Called to draw the proxy in any passes which the proxy is relevant to. Only called if the proxy indicated it has dynamic relevance.

DrawStaticElements

Called to submit StaticMesh elements for the proxy when the primitive is being attached on the game thread. Only called if the proxy indicated it has static relevance.

The renderer processes the scene in the order that it wants to composite data to the render targets. For example, the Depth only pass is rendered before the Base pass, so that Heirarchical Z (HiZ) will be populated to reduce shading cost in the base pass. This order is statically defined by the order pass functions are called in C++.

FPrimitiveViewRelevance is the information on what effects (and therefore passes) are relevant to the primitive. A primitive may have multiple elements with different relevance, so FPrimitiveViewRelevance is effectively a logical OR of all the element's relevancies. This means that a primitive can have both opaque and translucent relevance, or dynamic and static relevance; they are not mutually exclusive.

FPrimitiveViewRelevance also indicates whether a primitive needs to use the dynamic and/or static rendering path with bStaticRelevance and bDynamicRelevance.

Drawing policies contain the logic to render meshes with pass specific shaders. They use the FVertexFactory interface to abstract the mesh type, and the FMaterial interface to abstract the material details. At the lowest level, a drawing policy takes a set of mesh material shaders and a vertex factory, binds the vertex factory's buffers to the Rendering Hardware Interface (RHI), binds the mesh material shaders to the RHI, sets the appropriate shader parameters, and issues the RHI draw call.

Function

Description

Constructor

Finds the appropriate shader from the given vertex factory and material shader map, stores these references.

CreateBoundShaderState

Creates an RHI bound shader state for the drawing policy.

Matches/Compare

Provides methods to sort the drawing policy with others in the static draw lists. Matches must compare on all the factors that DrawShared depends on.

DrawShared

Sets RHI state that is constant between drawing policies that return true from Matches. For example, most drawing policies sort on material and vertex factory, so shader parameters depending only on the material can be set, and the vertex buffers specific to the vertex factory can be bound. State should always be set here if possible instead of SetMeshRenderState, since DrawShared is called less times in the static rendering path.

SetMeshRenderState

Sets RHI state that is specific to this mesh, or anything not set in DrawShared. This is called many more times than DrawShared so performance is especially critical here.

DrawMesh

Actually issues the RHI draw call.

Rendering paths

Unreal Engine has a dynamic path which provides more control but is slower to traverse, and a static rendering path which caches scene traversal as close to the RHI level as possible. The difference is mostly high level, since they both use drawing policies at the lowest level. Each rendering pass (drawing policy) needs to be sure to handle both rendering paths if needed.

The dynamic rendering path uses TDynamicPrimitiveDrawer and calls DrawDynamicElements on each primitive scene proxy to render. The set of primitives that need to use the dynamic path to be rendered is tracked by FViewInfo::VisibleDynamicPrimitives. Each rendering pass needs to iterate over this array, and call DrawDynamicElements on each primitive's proxy. DrawDynamicElements of the proxy then needs to assemble as many FMeshElements as it needs and submit them with DrawRichMesh or TDynamicPrimitiveDrawer::DrawMesh. This ends up creating a new temporary drawing policy, calling CreateBoundShaderState, DrawShared, SetMeshRenderState, and finally DrawMesh.

The dynamic rendering path provides a lot of flexibility because each proxy has a callback in DrawDynamicElements where it can execute logic specific to that component type. It also has minimal insertion cost but high traversal cost, because there is no state sorting, and nothing is cached.

The static rendering path is implemented through static draw lists. Meshes are inserted into the draw lists when they are attached to the scene. During this insertion, DrawStaticElements on the proxy is called to collect the FStaticMeshElements. A drawing policy instance is then created and stored, along with the result of CreateBoundShaderState. The new drawing policy is sorted based on its Compare and Matches functions and inserted into the appropriate place in the draw list (see TStaticMeshDrawList::AddMesh). In InitViews, a bitarray containing visibility data for the static draw list is initialized and passed into TStaticMeshDrawList::DrawVisible where the draw list is actually drawn. DrawShared is only called once for all the drawing policies that match each other, while SetMeshRenderState and DrawMesh are called for each FStaticMeshElement (see TStaticMeshDrawList::DrawElement).

The static rendering path moves a lot of work to attach time, which significantly speeds up scene traversal at rendering time. Static draw list rendering is about 3x faster on the rendering thread for Static Meshes, which allows a lot more Static Meshes in the scene. Because static draw lists cache data at attach time, they can only cache view independent state. Primitives that are rarely reattached but often rendered are good candidates for the static draw lists.

The static rendering path can expose bugs because of the way it only calls DrawShared once per state bucket. These bugs can be difficult to detect, since they depend on the rendering order and the attach order of meshes in the scene. Special view modes such as lighting only, unlit, etc will force all primitives to use the dynamic path, so if a bug goes away when forcing the dynamic rendering path, there is a good chance it is due to an incorrect implementation of a drawing policy's DrawShared and/or the Matches function.

High level Rendering order

Here is a description of the control flow when rendering a frame starting from FDeferredShadingSceneRenderer::Render:

Operation

Description

GSceneRenderTargets.Allocate

Reallocates the global scene render targets to be large enough for the current view, if needed.

InitViews

Initializes primitive visibility for the views through various culling methods, sets up dynamic shadows that are visible this frame, intersects shadow frustums with the world if necessary (for whole scene shadows or preshadows).

PrePass / Depth only pass

RenderPrePass / FDepthDrawingPolicy. Renders occluders, outputting only depth to the depth buffer. This pass can operate in several modes: disabled, occlusion only, or complete depths, depending on what is needed by active features. The usual purpose of this pass is to initialize Hierarchical Z to reduce the shading cost of the Base pass, which has expensive pixel shaders.

Base pass

RenderBasePass / TBasePassDrawingPolicy. Renders opaque and masked materials, outputting material attributes to the GBuffer. Lightmap contribution and sky lighting is also computed here and put in scene color.

Issue Occlusion Queries / BeginOcclusionTests

Kicks off latent occlusion queries that will be used in the next frame's InitViews. These are done by rendering bounding boxes around the objects being queried, and sometimes grouping bounding boxes together to reduce draw calls.

Lighting

Shadowmaps are rendered for each light and light contribution is accumulated to scene color, using a mix of standard deferred and tiled deferred shading. Light is also accumulated in the translucency lighting volumes.

Fog

Fog and atmosphere are computed per-pixel for opaque surfaces in a deferred pass.

Translucency

Translucency is accumulated into an offscreen render target where it has fogging applied per-vertex so it can integrate into the scene. Lit translucency computes final lighting in a single pass to blend correctly.

Post Processing

Various post process effects are applied using the GBuffers. Translucency is composited into the scene.

This is a fairly simplified and high level view. To get more details, look through the relevant code or the log output of a 'profilegpu'.

Render Hardware Interface (RHI)

The RHI is a thin layer above the platform specific graphics API. The RHI abstraction level in Unreal Engine is as low level as possible, with the intention that most features can be written in platform independent code and 'just work' on all platforms that support the required feature level.

Feature sets are quantized into ERHIFeatureLevel to keep the complexity low. If a platform cannot support all of the features required for a Feature Level, it must drop down in levels until it can.

Feature Level

Description

SM5

Generally corresponds with D3D11 Shader Model 5, except only 16 textures can be used because of OpenGL 4.3 limits. Supports tessellation, compute shaders and cubemap arrays. The deferred shading path is supported.

SM4

Corresponds to D3D11 Shader Model 4, which is generally the same as SM5, except no tessellation, compute shaders or cubemap arrays. The deferred shading path is supported. Eye Adaptation is not supported as it uses compute shaders.

ES3_1

Corresponds to the features supported by OpenGL ES3.1, Vulkan, and Metal.

Render states are grouped based on what part of the pipeline they affect. For example, RHISetDepthState sets all state relevant to depth buffering.

Since there are so many rendering states, it is not practical to set them all every time we want to draw something. Instead, Unreal Engine has an implicit set of states which are assumed to be set to the defaults (and therefore must be restored to those defaults after they are changed), and a much smaller set of states which have to be set explicitly. The set of states that do not have implicit defaults are:

RHISetRenderTargets

RHISetBoundShaderState

RHISetDepthState

RHISetBlendState

RHISetRasterizerState

Any dependencies of the shaders set by RHISetBoundShaderState

All other states are assumed to be at their defaults (as defined by the relevant TStaticState, for example the default stencil state is set by RHISetStencilState(TStaticStencilState<>::GetRHI()).

Threading Overview

Graphical Commands and the Command List

Synchronization

Debugging

Threading Overview

Originally, the renderer ran in the Render Thread, and commands for that thread were enqueued by the Game Thread to be run later in the frame. These commands made calls into the Render Hardware Interface (RHI) layer, which serves as our cross-platform interface into the different graphics APIs on the platforms we support.

In order to improve the efficiency of this process and take advantage of the capabilities of our supported platforms, the Render Thread now serves as a frontend that enqueues platform-agnostic graphical commands into the renderer's command list. Then, a new thread, the RHI Thread, translates (executes) them via the appropriate graphics API on the backend. This separation enables independent backend parallelization on platforms that support it, such as game consoles, DX12, and Vulkan. In general, anything generated in parallel on the frontend is translated in parallel on the backend.



There are certain commands which are carried out without the use of the command list system, such as Lock and Unlock operations. These commands are issued by the Render Thread directly. In these cases, the Engine will either flush the RHI Thread and wait for the operations to finish, or it will copy the data and queue it. This is implemented differently depending on the operation and the platform.



Graphical Commands and the Command List

The commands enqueued by the Render Thread are instances of structs derived from the FRHICommand template. They override the Execute function, which is called during the translation process, and store any data that they require. Commands can be submitted to the GPU differently on different platforms (for example, submitted multiple times per frame, all at once at the end of the frame, and so on) based on heuristics for that platform's optimal performance, or they can be submitted by issuing the FRHISubmitCommandsHint command.

The main interface used in translation is the IRHICommandContext. There is a derived RHICommandContext for each platform and API. During translation, the RHICommandList is given an RHICommandContext to operate on, and each command's Execute function calls into the RHICommandContext API. The command's context is responsible for state-shadowing, validation, and any API-specific details necessary to perform the given operation.

Synchronization

Synchronization of the renderer between the GameThread, RenderThread, RHI Thread, and the GPU is a complex topic. At the highest level, Unreal Engine 4 is normally configured as a "single frame behind" renderer. This means that the RenderThread is processing Frame N while the GameThread processes Frame N+1, except in cases where the RenderThread runs faster than the GameThread. The addition of the RHI Thread complicates this slightly, in that the RenderThread is able move ahead of the RHI Thread by completing visibility calculations for Frame N+1 while the RHI Thread is processing Frame N. The end result is that, while the GameThread is processing Frame N+1, the RenderThread may be processing commands for Frame N or Frame N+1, and the RHI Thread may also be translating commands from Frame N or Frame N+1, depending on execution times. These guarantees are arbitrated by FFrameEndSync and the FRHICommandListImmediate function called RHIThreadFence. It is also guaranteed that, regardless of how parallelization is configured, the order of submission of commands to the GPU is unchanged from the order the commands would have been submitted in a single-threaded renderer. This is required to ensure consistency and must be maintained if rendering code is changed.

Debugging

There are several console variables that you can use to control this behavior. Because many of these stages are orthogonal, they can be independently disabled for testing, and new platforms can be brought up in stages as time allows. For example:

Command

Description

r.rhicmdusedeferredcontexts

If set to 0, will disable parallelization of the backend. Default value is 1.

r.rhicmduseparallelalgorithms

If set to 0, will disable parallelization of the frontend. Default value is 1.

r.rhithread.enable

If Set to 0, will disable the RHI Thread completely. Command lists will still be generated, but they will be translated directly on the Render Thread at certain points.

r.rhicmdbypass

If set to 1, will completely disable command list generation and make the renderer behave like it originally did, directly calling the RHI commands on the Render Thread without a command list. Note that this will be ignored unless the RHI Thread is disabled.



Showing how parallel command list generation works in Unreal Engine.

RDG Programming Guide

Shader Parameter Structs

Uniform Buffers

Render Graph Builder

RDG Utilities Functions

RDG Resources and Views

Passes and Parameters

RDG Uniform Buffers

Upload Buffers

Memory Lifetimes

Performance Profiling

Conventions

Debugging and Validation

Resource Transition Debugging

Visualize Texture

Transient Allocator Debugging

RDG Insights Plugin

The Render Dependency Graph, also called Render Graph or RDG, is an immediate-mode application programming interface (API) which records render commands into a graph data structure to be compiled and executed. RDG simplifies high level rendering code by automating error-prone operations, and traverses the graph to optimize memory usage and parallelize render passes on the CPU and GPU.

Render Dependency Graph includes the following features:

Scheduling of asynchronous compute fences

Allocation of transient resources with optimal lifetimes and memory aliasing

Transitioning of sub-resources using split-barriers to hide latency and improve overlap on the GPU

Parallel command list recording

Culling of unused resources and passes in the graph

Validation of API usage and resource dependencies

Visualization of the graph structure and memory lifetimes in RDG Insights

The Render Graph API has been converted for both deferred and mobile renderers along with associated plugins. All high-level rendering code should be written using RDG, especially if any of the advanced features listed above are required.

RDG Programming Guide

For those writing low-level rendering features in C++ with some familiarity of shaders and the render hardware interface (RHI), this guide demonstrates use of the API through examples while explaining underlying concepts.

Shader Parameter Structs

RDG expresses graph dependencies through extensions to the shader parameters struct system.

Consider the following shader parameters declared in an HLSL source file.

Shader Inputs in an HLSL Source File:

These shader parameters can also be represented by a flat C++ data structure.

An ideal C++ Equivalent:

The shader parameters struct system employs a set of declaration macros to achieve this.

Shader Parameter Structs:

These macros generate an equivalent flat C++ data structure along with compile-time reflection metadata, which is accessible as a static member of the struct.

Compile-Time Reflection Metadata:

This metadata enables runtime traversal of the struct, which is necessary to dynamically bind parameters to the RHI. Information available for each member include the name, C++ type, HLSL type, and byte offset.

Refer to FShaderParametersMetadata::FMember for more information. RDG relies on this metadata to traverse pass parameters (later in this page).

A shader parameter struct is paired with an FShader to generate the bindings necessary to submit to an RHI command list.

You would do this by declaring the parameter struct as an FParameters type in your FShader derived class.

It can be done as either an inline definition or through a using / typedef directive. Then, use the SHADER_USE_PARAMETER_STRUCT macro to generate a constructor for the class which will register the bindings.

First Shader Class:

Binding shader parameters to an RHI command list is done by instantiating the struct, filling it with data, and calling the SetShaderParameters utility function.

Assigning Parameters:

Uniform Buffers

Uniform Buffers group shader parameters into an RHI resource which is, itself, bound as a shader parameter. Each uniform buffer defines a global namespace in HLSL. Uniform buffers are declared using the BEGIN_UNIFORM_BUFFER_STRUCT and END_UNIFORM_BUFFER_STRUCT macros.

Define Uniform Buffer:

Use the IMPLEMENT_UNIFORM_BUFFER_STRUCT in a C++ source file to register the uniform buffer definition with the shader system and generate its HLSL definitions.

Implement Uniform Buffer:

Uniform buffer parameters are automatically generated by the shader compiled and accessed using UniformBuffer.Member syntax.

Uniform Buffers in HLSL:

Now the SHADER_PARAMTER_STRUCT_REF macro can be used to include a uniform buffer as a parameter in the parent shader parameter struct.

SHADER_PARAMETER_STRUCT_REF:

Shader parameters are bound uniquely for each shader and each shader stage (for example, vertex and pixel) requires its own shader. Shaders are bound together as a Pipeline State Object (PSO) on an RHI command list using Set{Graphics, Compute}PipelineState.

Binding a pipeline state on the command list invalidates all shader bindings.

You are required to bind all shader parameters after setting the PSO. For example, consider the flow of commands for a typical set of draw calls sharing a PSO.

Set PSO A

For each draw call

Set vertex shader parameters

Set pixel shader parameters

Draw

Set PSO B

For each draw call

Set vertex shader parameters

Set pixel shader parameters

Draw

A problem with this approach is the Mesh Draw Commands in the renderer are cached and shared between multiple passes and views. It would be incredibly inefficient to generate a unique set of draw commands for each pass / view combination every frame. However, the Mesh Draw Command would also need to know the pass / view uniform buffer resources in order to properly bind them. To solve this, a Static binding model is used for Uniform Buffers.

When declared with static bindings, a uniform buffer is bound to a static slot directly to the RHI command list rather than to a unique slot for each individual shader. The command list pulls the binding directly from the static slot when the uniform buffer is requested by the shader. The binding now occurs at the pass frequency rather than the PSO frequency.

Consider the same example as above, but shader inputs are supplied from a Static Uniform Buffer instead:

Set Static Uniform Buffer

Set PSO A

For each draw call

Draw

Set PSO B

For each draw call

Draw

This model allows each draw call to inherit the shader bindings from the command list.

To define a uniform buffer with static binding, use the IMPLEMENT_STATIC_UNIFORM_BUFFER_STRUCT macro. An additional slot declaration is required. It is specified with the IMPLEMENT_STATIC_UNIFORM_BUFFER_SLOT macro.

Multiple static uniform buffers definitions can reference the same static slot, but only one of them may be bound at a time. It's best to reuse slots when possible to reduce the total number of them in the engine.

Static Uniform Buffers:

Use the RHICmdList.SetStaticUniformBuffers method to bind static uniform buffers. RDG automatically binds static uniform buffers to the command list prior to executing each pass. Any static uniform buffers should be included in the pass parameter struct.

Render Graph Builder

Render Dependency Graph is designed to be straightforward to use.

Instantiate an FRDGBuilder instance, create resources and add passes to set up the graph. Then, call FRDGBuilder::Execute to compile and execute the graph.

Create a texture with FRDGBuilder::CreateTexture or a buffer with FRDGBuilder::CreateBuffer.

These methods only allocate descriptors. The underlying RHI resources are allocated later during execution.

Add a pass using the FRDGBuilder::AddPass function, specifying a pass parameter struct and execution lambda as arguments.

Pass parameter structs extend shader parameter structs with parameters containing RDG resources.

RDG uses these parameters to derive dependencies between passes in the graph and lifetimes for transient resources.

Allocate pass parameters with GraphBuilder::AllocParameters and assign all relevant RDG resources used in the execution lambda.

The pass execution lambda records work to submit to an RHI command list during graph execution.

Use FRHIComputeCommandList for compute passes (the shared interface between asynchronous and graphics compute), or FRHICommandList for raster passes.

Avoid using FRHICommandListImmediate unless strictly necessary, as it disqualifies the pass from executing in parallel.

Ideally all pass lambdas are thread safe, but in reality a few passes still require creation or locking of RHI resources during execution, which must be done on the render thread. Use the immediate command list for these cases.

The example code snippet below is a starting example.

Graph Builder:

The graph builder API is single-threaded and only one instance may be instantiated at a time, precluding hierarchical or side-by-side graphs. Both the deferred and mobile renderers use a single builder instance for each scene render invocation.

RDG splits the render pipeline into two timelines: setup and execute.

The graph is built during the setup timeline. This is where resource creation and render pipeline configuration branching is done. All RHI commands are deferred into pass lambdas, which are called on the execute timeline.

Code specified in the pass lambdas should be free from side effects and simply record commands into the command list, as pass execution may be parallelized.



The diagram above depicts the render pipeline timeline with and without RDG.

In the diagram without RDG, rendering features are written on a single timeline where both setup and execution are done in place. RHI commands are recorded and submitted directly in line with pipeline branching and resource allocation.

With RGD, the setup code is separated from execution through user-supplied pass execution lambdas. RDG performs an additional compilation step prior to invoking the pass execution lambdas, and execution is performed across several threads, calling into the lambdas to record render commands into RHI command lists.

RDG Utilities Functions

Render Dependency Graph includes several helpful utility functions for adding common passes, located in RenderGraphUtils.h. These utilities should be used where possible to reduce boilerplate across the engine.

For example, use FComputeShaderUtils::AddPass for a compute shader pass for FPixelShaderUtils::AddFullscreenPass for a full screen pixel shader pass.

The examples that follow are written verbosely for educational purposes. Use utility functions where possible.

RDG Resources and Views

An RDG resource initially contains the RHI resource descriptor. The associated RHI resource is only accessible within the execution lambda of a pass which declares the resource as a pass parameter.All RDG resources provide an FRDGResource::GetRHI overload for the specific subclass type. Access to this method is restricted to pass lambdas and the validation layer will assert if the method is improperly called.

The following properties are specific to the Buffer and Texture resources:

A resource can be Transient, whereby its lifetime is constrained to the graph and the memory can potentially alias with other transient resources with disjointed lifetimes.

Alternatively, a resource can be External, whereby its lifetime extends outside the graph. This happens if the user registers an existing RHI resource into the graph, or extracts a resource out of the graph after the execution has completed.

An RDG buffer and texture may be specialized with an RDG unordered access or shader resource view. Like other RDG resources, the underlying RHI resource is allocated on demand during execution and access is only allowed for passes that declare it as a parameter. The code sample below demonstrates how to create textures, buffers, and views resources.

Resource Creation Examples:

RDG resource pointers are owned by the Graph Builder. They become invalid after it is destroyed. Any pointers after execution of the graph should be null.

Passes and Parameters

Pass parameters are allocated using the FRDGBuilder::AllocParameters function, which guarantees the correct memory lifetime. RDG extends the shader parameter struct system with its own macros. FRDGBuilder:AddPass consumes the custom RDG macros while ignoring shader parameter macros.

The coupling of pass parameters with shader parameters is intentional. The majority of pass parameters across the Unreal Engine are also shader parameters. Declaring them both using the same API reduces boilerplate.

The following specific examples best illustrate using passes and parameters.

This shader parameter example declares a simple hypothetical compute shader and binds some shader parameters to it without any RDG involvement at all.

This establishes a baseline that helps show how RDG is an extension of the shader parameter struct system.

Read the commented code to understand what is fully happening in this example.

HLSL Code Example:

C++ Code Example:

In this example, the code has been converted to RDG. The compute shader contains RDG resources in its FParameters struct, and a new RDG pass is added to bind the compute shader parameters.

C++ Code Example:

Continuing with this example, the code shows how some pass parameters do not have shader semantics by implementing a simple CopyTexture utility function in RDG.

This is useful in cases where the pass is not one-to-one with a shader, or when no shader is involved at all.

C++ Code Example:

RDG exposes fixed-function render targets for raster passes through the RENDER_TARGET_BINDING_SLOTS parameter. The RHI utilizes render passes to bind render targets to a command list. RDG handles all of this for you automatically by determining when to begin and end the render pass. You just need to supply the bindings for it to do so.

Binding a color or depth/stencil target requires specifying one or more Load Actions. These actions are used to control initial pixel values for each target. Tiled rendering hardware requires accurate actions to achieve the best performance.

The following are valid load actions:

Load: Preserves existing contents of the texture.

Clear: Clears the texture to its optimized clear value.

NoAction: May not preserve contents. This option is faster on some hardware if all valid pixels are being written to.

A unique load action is specified separately for depth and stencil. Depth stencil targets also require FExclusivieDepthStencil struct to control whether each plane has read or write access.

The following example shows a couple of different ways to clear render targets with RDG. The color target is manually cleared, while the depth and stencil target uses the hardware clear action.

C++ Code Example:

REG supports raster passes, which output to unordered access views (UAV) instead of fixed function render targets. The most straightforward way is with the FPixelShaderUtils::AddUAVPass utility that creates a custom render pass without any render targets and binds the RHI viewport for you.

C++ Code Example:

When a RDG resource is present on the pass parameter struct supplied to FRDGBuilder::AddPass, the associate may extend the lifetime of the resource, or create a dependency with a prior pass. Ideally, resources are declared only when necessary to reduce graph complexity, and unused resource parameters should be marked as null to remove them from the pass.

The challenge is that the shader dictates whether a resource is used since a permutation of the shader might compile out a resource or introduce a new one. To solve this problem, RDG includes the ClearUnusedGraphResources utility function which nulls out resources that are not used by the shader.

ClearUnusedGraphResources Utility Example:

ClearUnusedGraphresources(*ComputeShader, PassParameters); GraphBuilder.AddPass(

A version of the ClearUnusedGraphResources utility exists for multiple shaders. This variant only clears resources unused by any shader.

With all the major pieces in place, the code example in this section demonstrates how to generate a mipmap chain using both Raster and Compute passes. Multiple passes are chained together using texture unordered access views (UAV) and shader resource views (SRV) to express subresources.

The following is a simplified example taken from the Unreal Engine codebase that illustrates the use of utility functions to reduce boilerplate for simple fullscreen draws, or compute dispatches.

Raster Mipmap Generation Example:

Compute Mipmap Generation Example:

RDG supports asynchronous compute scheduling by inspecting graph dependencies and inserting fences at synchronization points.

Asynchronous compute is enabled by tagging a pass with the ERDGPassFlags::AsyncCompute flag and use the FRHIComputeCommandList type as the argument in the pass lambda.

Asynchronous compute must also be enabled by the platform and by RDG. Platforms which do not support asynchronous compute fall back to the graphics pipe. RDG support can be disabled explicitly with the console command r.RDG.AsyncCompute (which is enabled by default).

C++ Code Example:

For simple compute shaders, use the async compute variant of FComputeShaderUtils::AddPass.

Asynchronous compute work is scheduled using the dependency graph. When one or more passes are tagged, RDG traverses the graph to find the last producer on the graphics pipeline and inserts a fence. Likewise, asynchronous compute joins back to graphics when the work is first consumed on the graphics pipeline.

The diagram below depicts the scenario described above.



This diagram depicts the graphics and asynchronous compute queues, with time shown as the horizontal axis.

In the diagram above, Pass A is a producer for Pass C. So, a fence is introduced just after Pass A executes, which signals Pass C to start work. The asynchronous compute pipe runs until Pass D completes, at which time it synchronizes back with the graphics pipe so that the consumer — Pass E — sees the correct results.

Use the RDG Insights tool to visualize asynchronous compute events in the graph. The screenshot shows a similar view to the diagram above in the RDG Insights tool, but it is captured from an actual workload in the engine. See the RDG Insights section of this page for more information about using the tool.



A resource is considered external if its lifetime extends outside the graph, which can happen under two circumstances: if the resource is registered into the graph, or extracted out of the graph.

Registration into the graph is done using the FRDGBuilder::RegisterExternal{Texture, Buffer} methods. This creates a new RDG resource with a pre-allocated reference-counted pool RHI resource pointer: IPooledRenderTarget for textures, or FRDGPooledTexture for buffers.

Extraction from the graph fills a pooled resource pointer after execution completes. Registering a resource extends the lifetime of the RDG resource to the front of the graph. It is necessary considering the allocation occurs during graph setup. Extraction does the opposite whereby it extends the resource lifetime to the end of the graph since the user now holds a reference.

If the user does not hold a reference outside of the graph, registered or extracted resources can still technically share pooled memory with other RDG resources later, or earlier, in the frame.

The code excerpt below illustrates various ways of registering or extracting textures with the graph builder. Notice how registration and extraction use the same pooled texture type, allowing round-tripping from graph to graph.

C++ Code Example:

The code is effectively the same for buffers, except with the FRDGPooledBuffer class used instead.

An alternative approach to external resources is FRDGBuilder:ConvertToExternal{Texture, Buffer}. It performs an immediate allocation of the underlying pooled resource and returns it.

This method is useful in situations where it is not possible to wait until the end of the graph to extract the resource. The biggest difference between conversion and extraction is the lifetime extension. Conversion extends the lifetime to the beginning of the graph, while extraction extends it to the end of the graph, meaning the resource will not be able to share the underlying allocation with any other resource in the frame.

The Render Dependency Graph employs a transient resource allocator during graph compilation to plan allocations across the execution timeline. Resources with disjoint lifetimes may overlap in memory.

Platforms with a transient allocator implemented can achieve a significant reduction in the GPU memory watermark over the default resource pool approach. This is due to increased flexibility in aliasing the memory. The resource pools are forced to compare and match RHI descriptors to determine their reuse. Whereas the transient allocator can share underlying memory.

You can control whether the transient allocator is enabled or not with the console variable r.RDG.TransientAllocator.

This variable is useful to toggle when looking for aliasing-specific issues. In particular, it is important to not rely on well-defined prior contents of a resource. The resource pools typically mask these issues since it is often the same, or similar, resources being reused, but that's not the case with the transient allocator. Prior contents will be garbage.

RDG Uniform Buffers

RDG uniform buffers may contain RDG resources. As expected, RDG initializes the descriptor during graph setup and defers the creation of the underlying RHI uniform buffer until execution. If the resource is determined to be unused, it is culled and never initialized.

Creation of an RDG uniform buffer is done with FRDGBuilder::CreateUniformBuffer with a uniform parameter struct as input. The uniform parameter struct is an extension of the pass parameters and may contain RDG resources. FRDGBuilder::AddPass traverses child uniform parameters in addition to root pass parameters.

The current major downside to RDG uniform buffers is that they may not null resource parameters, and it is not possible for a shader to reflect and cull unused parameters. For the moment, resources must be manually pruned by creating a unique uniform buffer for each set of parameters.

See the Scene Textures Uniform Buffers in the Deferred Shading Renderer for a practical example.

RDG uniform buffers must be declared using SHADER_PARAMETER_RDG_UNIFORM_BUFFER on the pass parameter struct provided to FRDGBuilder:AddPass for the uniform buffer to be dereferencable in the pass lambda.

C++ Code Example:

Upload Buffers

If a RDG resource requires initial data from the CPU prior to executing the graph, the FRDGBuilder::QueueBufferUpload method is the most efficient way to schedule it. RDG batches uploads together during graph compilation and may be able to overlap the work with other compilation tasks.

The example code below demonstrates how to upload an array of CPU data to an RDG buffer.

Buffer Upload Example:

Consider the following when using upload buffers in RDG:

Do use RDG to perform uploads.

A manual lock / unlock using the immediate command list within a pass introduces a sync point and inhibits parallel execution.

Upload buffers are automatically marked as non-transient. Transient resources do not support CPU uploads.

Do use the most accurate ERDGInitialDataFlags.

Use NoCopy if data lifetime is sufficient to survive graph deferral. Otherwise, let RDG make a copy.

Memory Lifetimes

The setup and execution timeline split requires some care when dealing with memory lifetimes. A common mistake is to pass memory into RDG lambda that is not guaranteed to exist later when the graph is executed.

To assist with this, RDG includes its own linear allocator with proper lifetime guarantees. The API supports allocation of varying cost.

For POD types, use FRDGBuilder::AllocPOD.

If destructor tracking is required for a C++ object, use FRDGBuilder::AllocObject.

C++ Code Example:

Any allocated memory will persist until the graph builder instance is destroyed. It uses a linear allocator and is very fast.

Performance Profiling

RDG supports scope defines for various profilers in the engine:

Use RDG_EVENT_SCOPE to add a GPU profile scope around passes. These are consumed by external profilers like RenderDoc, as well as RDG Insights.

Use RDG_GPU_STAT_SCOPE to add a new scope for the stat gpu command.

Use RDG_CSV_STAT_EXCLUSIVE_SCOPE to add a new scope for the CSV profiler.

The RDG scopes take the builder as input and properly account for the separate setup and execute timelines.

Conventions

The following are general coding conventions to use when writing code using RDG. Following these conventions ensures consistency across the renderer.

Construct namespaces for resources separated by dots.

For example, TSR.History.ScreenPercentage. This simplifies name filtering in RDG insights and other tools.

Name graph builder instances: GraphBuilder

Name shader parameters inline on a shader instance: FParameters

Use RDG_EVENT_SCOPE as a namespace for passes.

Use utilities in RenderGraphUtils.h or ScreenPass.h where possible.

Debugging and Validation

The Render Graph system adds complexity by introducing a deferred-mode data structure. It can be difficult to find the pass setup location associated with its execution lambda when failure occurs during execution. That is further compounded when the RHI thread is enabled, as an executing RHI command is now two degrees removed from its setup location.

For example, if a crash occurs when setting an RHI shader parameter inside a platform RHI, it is not possible to deduce where the failure occurred just from the call stack location. Both RDG and the RHI have tools to help address these issues. RDG Immediate Mode is a debug feature which bypasses graph compilation in favor of executing the pass directly in the AddPass call.

Enable the following methods when using Debug or Development builds.

Method

Variable

Console Variable

r.RDG.ImmediateMode

Command Line Argument

-rdgimmediate

In another example, if there is a crash within the RDG pass lambda due to a null pointer in the pass parameter struct, the debugger breaks inside the lambda and at that point it is too late to inspect any of the setup code (where the real issue was introduced). The lambda is executed on the setup timeline when immediate mode is enabled, allowing the setup code to be inspected directly.

Using the console command r.RHICmdBypass disables parallel rendering and software command lists. Combined with RDG immediate mode, it removes all deferral mechanisms giving a single call stack for debugging.

Additional console variables exist to control RHI threading behavior and can be referenced in the Parallel Rendering Overview documentation.

All graph optimizations are disabled when in Immediate Mode, including transient allocation, graph culling, render pass merging, and so on. This will introduce side-effects from them being disabled.

Additionally, use the following CVars to disable individual features in RDG without invoking immediate mode to rule them out if issues arise.

Variable

Description

r.RDG.CullPasses

Disable to rule out whether a pass is being culled.

r.RDG.MergeRenderPasses

Disable to require a unique render pass per RDG raster pass.

r.RDG.ParallelExecute

Disable to run all passes serially on the render thread.

r.RDG.TransientAllocator

Disable to fall back to resource pooling.

RDG includes a validation layer which is enabled by default when using Debug or Development builds. This layer emits fatal checks with clearly marked resource / pass names as early as possible if RDG is used incorrectly. It adds additional CPU overhead and is compiled out in Test and Shipping builds.

Resource Transition Debugging

The resource transition API in the RHI assigns an ERHIAccess and ERHIPipeline mask to each subresource. RDG takes care of transitioning individual subresources between states across the graph, assuming the resources are properly declared using RDG pass parameters. RHI validation logs when a resource is improperly transitioned, but it can be difficult to debug transitions that occur within RDG, because the call stack location will always look the same.

RDG itself has been rigorously tested to ensure that it produces the correct transitions. Should the need arise, however, RDG transition logging can be mixed with RHI transition logging to spot inconsistencies.

RDG Transition Log:

Use -rdgtransitionlog or r.rdg.transitionlog X (where X is the number of frames to log) to log all transitions that occur within RDG.

Use r.RDG.Debug.ResourceFilter [ResourceName] to filter the log by resource name.

Use r.RDG.Debug.PassFilter PassName to filter the log by pass name.

RHI Transition Log:

Use -rhivalidation and -rhivalidationlog=ResourceName to log a specific resource.

By default, RDG prints transitions from the Render Thread, whereas the RHI prints transition logs from the RHI Thread. To make them line up you must specify -norhithread -forcerhibypass or -onethread. Unfortunately, disabling the RHI thread can mask certain cross-pipeline transition errors, but in most cases the issue will still reproduce.

For example, to log all RDG and RHI activity for SceneDepthZ, use the command line arguments:

-rhivalidation -rhivalidationlog=SceneDepthZ -rdgtransitionlog -rdgdebugresourcefilter=SceneDepthZ -onethread

Visualize Texture

RDG publishes all texture UAV or RTV writes to the vis command in Development builds. Use this command to visualize resources on the screen. Type ‘vis' into the command line to see the list of available resources and format of the command.

Transient Allocator Debugging

The transient allocator introduces a source of potential artifacts. Use r.RDG.TransientAllocator to enable or disable the system.

If disabling the system eliminates the artifact, consider the following additional tests:

Use .RDG.ClobberResources to force-initialize all resources to a known value. If this produces a similar artifact without the transient allocator enabled, then the likely explanation is that the resource was not properly initialized before being read.

Use r.RDG.Debug.ExtendResourceLifetimes to disable all aliasing within the graph. This is useful to rule out missing aliasing barriers or incorrect resource lifetimes.

Use r.RDG.Debug.DisableTransientResources to disable resources from the transient allocator.

For either of the above commands, use r.RDG.Debug.ResourceFilter to filter which resources are affected. This can help narrow down problematic resources.

RDG Insights Plugin

As an extension to the Unreal Insights tool, Render Dependency Graph has its own plugin called RDG Insights for real-time visualization of the RDG graph structure. Traces are captured and displayed as a track in the Timing Insights view alongside other CPU tracks.

Enable the RDG Insights plugin by going to the main menu and selecting Edit > Plugins > Insights.



The RDG Insights plugin can be used to inspect properties about the graph:

Resource lifetimes, pass associations, and resource pool allocation overlap

Asynchronous compute fences and overlap

Graph culling and render pass merging

Parallel execution pass ranges

Transient Memory Layouts

The RDG Insights plugin can also be used as a debugging and diagnostic tool to answer questions like:

Why aren't asynchronous compute passes overlapping with graphic passes?

How are resources being used across the frame?

Does a resource allocation overlap with other resources?

Which resources are used by post processing?

Which passes were culled?

Capturing a trace only requires enabling the RDG channel in Unreal Insights. When launching the client application, specifying the -trace=rdg,defaults argument is sufficient.

If connected to a Live Trace in Unreal Insights, enabling the RDG channel is sufficient.

RDG traces generate a lot of data.

For a more in-depth walkthrough of the tool, refer to the following slide deck.

Quick start

Shaders and Materials

Global shaders

Material and Mesh types

Vertex Factories

Material Shaders

Creating a material shader

Special Engine Materials

Shader compilation

Debugging shader compilers

Retrying on compile errors

Shader caching and cooking

Debugging

Dumping debug info

Iteration best practices

Cross compiler

AsyncCompute

Quick start

When working on shaders, be sure to enable r.ShaderDevelopmentMode by setting it to 1. The easiest way is to edit ConsoleVariables.ini so it is done every time you load. This will enable retry-on-error and shader development related logs and warnings.

Use Ctrl+Shift+., which executes the recompileshaders changed command. Executing this command should be performed after you have saved your changes to the Unreal Shader (.usf) file.

If you change a file that is included in many shaders (such as, common.usf), this can take a while. If you want to iterate on a material, you can trigger recompile of the material by making a small change to the material (e.g. move node) and using the 'Apply' in the material editor.

Shaders and Materials

Global shaders are shaders which operate on fixed geometry (like a full screen quad) and do not need to interface with materials. Examples would be shadow filtering, or post processing. Only one shader of any given global shader type exists in memory.

Materials are defined by a set of states that control how the material is rendered (blend mode, two sided, etc) and a set of material inputs that control how the material interacts with the various rendering passes (BaseColor, Roughness, Normal, etc).

Materials have to support being applied to different mesh types, and this is accomplished with vertex factories. A FVertexFactoryType represents a unique mesh type, and a FVertexFactory instance stores the per-instance data to support that unique mesh type. For example, FGPUSkinVertexFactory stores the bone matrices needed for skinning, as well as references to the various vertex buffers that the GPU skin vertex factory shader code needs as input. The vertex factory shader code is an implicit interface which is used by the various pass shaders to abstract mesh type differences. Vertex factories consist of mainly vertex shader code, but some pixel shader code as well. Some important components of the vertex factory shader code are:

Function

Description

FVertexFactoryInput

Defines what the vertex factory needs as input to the vertex shader. These must match the vertex declaration in the C++ side FVertexFactory.

FVertexFactoryIntermediates

Used to store cached intermediate data that will be used in multiple vertex factory functions. A common example is the TangentToLocal matrix, which had to be computed from unpacked vertex inputs.

FVertexFactoryInterpolantsVSToPS

Vertex factory data to be passed from the vertex shader to the pixel shader.

VertexFactoryGetWorldPosition

This is called from the vertex shader to get the world space vertex position. For Static Meshes this merely transforms the local space positions from the vertex buffer into world space using the LocalToWorld matrix. For GPU skinned meshes, the position is skinned first and then transformed to world space.

VertexFactoryGetInterpolantsVSToPS

Transforms the FVertexFactoryInput to FVertexFactoryInterpolants, which will be interpolated by the graphics hardware before getting passed into the pixel shader.

GetMaterialPixelParameters

This is called in the pixel shader and converts vertex factory specific interpolants (FVertexFactoryInterpolants) to the FMaterialPixelParameters structure which is used by the pass pixel shaders.

Shaders using FMaterialShaderType are pass specific shaders which need access to some of the material's attributes, and therefore must be compiled for each material, but do not need to access any mesh attributes. The light function pass shaders are an example of FMaterialShaderType's.

Shaders using FMeshMaterialShaderType are pass specific shaders which depend on the material's attributes AND the mesh type, and therefore must be compiled for each material/vertex factory combination. For example, TBasePassVS / TBasePassPS need to evaluate all of the material inputs in a forward rendering pass.

A material's set of required shaders is contained in a FMaterialShaderMap. It looks like this:

Vertex factories are included in this matrix based on their ShouldCache function, which depends on the material's usage. For example, bUsedWithSkeletalMesh being true will include the GPU skin vertex factories. FMeshMaterialShaderType's are included in this matrix based on their ShouldCache function, which depends on material and vertex factory attributes. This is a sparse matrix approach to caching shaders and it adds up to a large number of shaders pretty quick which takes up memory and increases compile times. The major advantage over storing a list of actually needed shaders is that no list has to be generated, so needed shaders have always already been compiled before run time on consoles. Unreal Engine mitigates the shader memory problem with shader compression, and the compile time problem with multicore shader compilation.

A material shader type is created with the DECLARE_SHADER_TYPE macro:

This declares the necessary metadata and functions for a material shader type. The material shader type is instantiated with IMPLEMENT_MATERIAL_SHADER_TYPE:

This generates the material shader type's global metadata, which allows us to do things like iterate through all shaders using a given shader type at runtime.

A typical material pixel shader type will first create a FMaterialPixelParameters struct by calling the GetMaterialPixelParameters vertex factory function. GetMaterialPixelParameters transforms the vertex factory specific inputs into properties like WorldPosition, TangentNormal, etc that any pass might want to access. Then a material shader will call CalcMaterialParameters, which writes out the rest of the members of FMaterialPixelParameters, after which FMaterialPixelParameters is fully initialized. The material shader will then access some of the material's inputs through functions in MaterialTemplate.usf (GetMaterialEmissive for the material's emissive input for example), do some shading and output a final color for that pass.

UMaterial has a setting called bUsedAsSpecialEngineMaterial that allows the material to be used with any vertex factory type. This means all vertex factories are compiled with the material, which will be a very large set. bUsedAsSpecialEngineMaterial is useful for:

Materials used with rendering viewmodes like lighting only.

Materials used as fallbacks when there is a compilation error (DefaultDecalMaterial, DefaultMaterial, etc).

Materials whose shaders are used when rendering other materials in order to cut down on the number of shaders that have to be cached. For example, an opaque material's depth-only shaders will produce the same depth output as the DefaultMaterial, so the DefaultMaterial's shaders are used instead and the opaque material skips caching the depth-only shader.

Shader compilation

Unreal Engine compiles shaders asynchronously using a streaming system. Compile requests are enqueued when materials load that do not have a cached shader map, and compile results are applied as they become available, without blocking the engine. This is optimal in terms of load time and compile throughout, but it does mean that there are quite a few layers between the actual platform shader compile and the material that requested it.

The actual compiling work is done in helper processes called the Shader Compile Workers, because the platform shader compile functions (D3DCompile) often contain critical sections within them that prevent multi-core scaling within a single process.

There are some settings to control how compilation is done which can simplify debugging of the shader compilers. These can be found in the [DevOptions.Shaders] section of BaseEngine.ini.

Setting

Description

bAllowCompilingThroughWorkers

Whether to launch the SCW to call the compiler DLL's or whether Unreal Engine should call the compiler DLL's directly. If disabled, compiling will be single-core.

bAllowAsynchronousShaderCompiling

Whether compiling should be done on another thread within Unreal Engine.

If you want to step into the shader compiler DLL's directly from Unreal Engine (CompileD3D11Shader for example), you should set both of these to false. Compilation will take a long time though, so make sure all other shaders have been cached.

With r.ShaderDevelopmentMode enabled, you will get the opportunity to retry on shader compile error. This is especially important for global shaders since it is a fatal error if they do not compile successfully.

In debug, with the debugger attached, you will hit a breakpoint and get the compile error in the Visual Studio output window. You can then Double-click the error log to be taken directly to the offending line.



Otherwise you will get a Yes/No dialog



Shader caching and cooking

Once shaders are compiled, they are stored in the Derived Data Cache. They contain, in their key, a hash of all the inputs to the compile, including shader source files. That means that changes to shader source files are automatically picked up every time you re-launch the engine or do a 'recompileshaders changed'.

When you are modifying FShader Serialize functions, there is no need to handle backward compatibility, just add a space to a shader file that is included by that shader.

When cooking assets, material shaders are inlined into the material's package, and global shaders are stored seperately in a global shader file which allows them to be loaded early in the engine startup.

Debugging

The primary method of debugging shaders is to modify a shader to output an intermediate, then visualize that with the appropriate VisualizeTexture command. This can allow fast iteration since you can compile on the fly without restarting the engine. For example, you can verify that WorldPosition is correct with something like:

Then verify that the scale is right, and the result is not view dependent. However this method does not scale very well to more complex shaders that build data structures.

You can also use r.DumpShaderDebugInfo=1 to get files saved out to disk for all the shaders that get compiled. It can be useful to set this in ConsoleVariables.ini just like r.ShaderDevelopmentMode. Files are saved to GameName/Saved/ShaderDebugInfo, including

Source files and includes

A preprocessed version of the shader

A batch file to compile the preprocessed version with equivalent commandline options to the compiler that were used

If you leave this setting on, it can fill your HD with many tiny files and folders.

Iteration best practices

If you are working on a global shader, recompileshaders changed or Ctrl+Shift+. is the fastest way to iterate. If the shader takes a long time to compile, you might consider specifying CFLAG_StandardOptimization as a compile flag in the shader's ModifyCompilationEnvironment.

If you are working on a material shader, like BasePassPixelShader.usf, it is much faster to iterate on a single material. Every time you click the Apply button in the material editor, it will re-read shader files from disk and recompile just that material.

Cross compiler

The HLSL Cross Compiler is used to automatically convert HLSL into GLSL for OpenGL platforms, allowing shaders to be authored only once for all platforms. It is run during offline shader compilation and performs various optimizations to the code that OpenGL drivers are frequently missing.

AsyncCompute

AsyncCompute is a hardware feature that is available on some APIs that work with certain GPUs. It allows interleaving to better utilize the hardware units in the GPU more efficiently.

Unreal Shader Files

Example Global Shader

Creating and Adding a New Shader

Class Declaration

Registering a Shader Type

Declaring the Pixel Shader

Writing a Simple Function

Additional Notes

Global Shaders are shaders that are not created using the Material Editor. Instead, they are created using C++, operate on fixed geometry and do not need to interface with materials or a mesh. Sometimes more advanced functionality is required to achieve a desired look and a custom shader pass is necessary to do this.

Some examples of Global Shaders would be rendering post-processing effects, dispatching compute shaders, and clearing the screen.

Unreal Shader Files

Unreal Engine uses Unreal Shader (.usf) files to store and read information about the shaders it uses. The source files of any new shaders created need to be stored in the Engine/Shaders folder. If a shader is part of a plugin, it should be stored in the Plugin/Shaders folder instead.

Use the command r.ShaderDevelopmentMode=1 in your ConsoleVariables.ini file to get detailed logs on shader compiles.

See Shader Development for more information.

Example Global Shader

As an example, we will create a simple pass-through Vertex Shader and a Pixel Shader that returns a custom Color.

Creating and Adding a New Shader

Create your own shader by creating a new text file in your Engine/Shaders folder. Rename its file extension to .usf and give it a name. The following example uses MyTest.usf.

Next, add the following code your MyTest.usf file:



MyTest.usf



Class Declaration

Now, to get Unreal Engine to recognize and start compiling the shader, you need to declare a C++ class. This example uses the Vertex Shader as that class:



MyTestVS.h



There are a few requirements when doing this:

This is a subclass of FGlobalShader. As such, it will end up in the Global Shader Map, meaning it doesn't need a material to find it.

Usage of DECLARE_EXPORTED_SHADER_TYPE() macro generates exports required for serialization of the shader type. The third parameter is a type for external linkage for the code module where the shader module will live, if required. For example, any C++ code that doesn't live in the Renderer Module.

There are two constructors: the default constructor, and the serialization constructor.

The ShouldCache() function is needed to determine if this shader should be compiled under certain circumstances. For example, you may not want to compile a compute shader on a non-compute shader capable RHI.

Registering a Shader Type

A Shader Type is a template or class that is specified by shader code, which maps to a physical C++ class. A Shader Type can be registered to Unreal Engine's list of types using the following code:

This macro maps the type (FMyTestVS) to the .usf file (MyTest.usf), the shader entry point (MainVS), and the frequency/shader stage (SF_Vertex). It also causes the shader to be added to the compilation list, as long as its ShouldCache() method returns true.

Whichever module you add your FGlobalShader to must be loaded before the engine starts, or you will get an assert, such as:

After a game or editor has launched, a dynamic module is not allowed to add its own shader type.

Declaring the Pixel Shader

Next, the Pixel Shader is declared using the following code:

In this class, the shader parameter MyColor from the .usf file is being exposed:

The FShaderParameter MyColorParameter member is added to the class, which holds information for the runtime to be able to find the bindings. This, in turn, allows the value of the parameter to be set at runtime.

In the serialization constructor, the Bind() function binds the parameter to the ParameterMap by name. This must match the .usf file's name.

The ModifyCompilationEnvironment() function is used when the same C++ class define for different behaviors, and to be able to set up #define values in the shader.

The Serialize() method is required. It is where the compile and cook time information from the shader's binding (matched during the serialization constructor) gets loaded and stored at runtime.

Lastly, the custom SetColor() method shows an example of how to set the MyColor parameter at runtime with a specified value.

Writing a Simple Function

The following code writes a simple function to draw a fullscreen quad using the specified Shader Types:

Test this in your codebase by clearing a console variable that can be toggled at runtime. Use the following code to do this:

Test the functionality of your added console variable by running your project and opening the console window using the tilde (~) key. Then type in the any one of the following commands to set the variable:

r.MyTest with a value of 1, 2, or 3, to change the color.

r.MyTest 0 to disable the shader pass.

Additional Notes

For information on debugging the compilation of your .usf file and/or want to see the processed file, see Debugging the Shader Compiling Process.

You can modify .usf files while an uncooked game or editor is running for quick iteration. Use the keyboard shortcut Ctrl + Shift + . (period), or open the console window and enter the command recompileshaders changed, to pick up and rebuild your shaders.

Enabling Dumping of Intermediate Shaders

Building ShaderCompileWorker in Debug Mode

Generating Intermediate Files

Folder Structure of Dumped Shaders

Using ShaderCompileWorker for Debugging

During development, it's a good idea to take a look at what exactly Unreal Engine is sending to the platform's shader compiler. The information contained in this page will enable you to debug any issues associated with it.

Enabling Dumping of Intermediate Shaders

To start debugging with your engine installation, you'll have to enable some predefined console variables in your ConsoleVariables.ini configuration file found in the Engine/Config folder. Under the [Startup] section, you'll find the following list of console variables, which should look like this:

Remove the ; (semi-colon) next each console variable to enable its usage, and so that it looks like the example code above.

Building ShaderCompileWorker in Debug Mode

By default, UnrealBuildTool (UBT) generates projects for tools, they always compile in Development mode. For the purposes of debugging, you'll want to build the engine and projects in Debug mode, which contains symbols for debugging your project's code.

To build your project in Debug mode, perform the following actions:



Change your solution properties in Visual Studio using the Configuration Manager, which can be opened from the Build menu.

Set the ShaderCompileWorker (SCW) dropdown to Debug_Program.

For additional information about these targets, see the Build Configuration Reference page.

Generating Intermediate Files

In order to debug your shaders, you'll first need to generate the files you want to actually debug. This requires enabling the console variables for dumping intermediate shaders to allow subsequent compilations to dump out generated files.

See the Enabling Dumping of Intermediate Shaders section of this page to see how to enable the appropriate console variables.

Force a rebuild of all shaders by adding a space, or making any inconsequential change, to the Common.usf file located in the Engine/Shaders folder. Then re-run the editor. This action will trigger a recompile of all shaders and dump all the intermediate files in your project's Saved/ShaderDebugInfo folder.

If you are debugging a particular Material, you can make any change, or an inconsequential change, such as moving a node to trigger a change. Use the toolbar to Save or Apply the changes to the Material to dump the shader files again.

Folder Structure of Dumped Shaders

The folder path generated by the dumped shader includes relevant information. Let's look at an example of a dumped shader's path and analyze its parts:

D:\UE4\Samples\Games\TappyChicken\Saved\ShaderDebugInfo\PCD3D_SM5\M_Egg\LocalVF\BPPSFNoLMPolicy\BasePassPixelShader.usf

The first part is the root path to your project. In this case, that's to a project named Tappy Chicken.

D:\UE4\Samples\Games\TappyChicken\

The next part of the path is where our dumped shaders are saved.

D:\UE4\Samples\Games\TappyChicken\ Saved\ShaderDebugInfo\

For every shader format and/or platform, a subfolder is created. This path creates one for PC D3D Shader Model 5.

D:\UE4\Samples\Games\TappyChicken\Saved\ShaderDebugInfo\ PCD3D_SM5\

A folder per material, and a special one called Global, is created. The debug shader being looked at here is for the M_Egg Material.

D:\UE4\Samples\Games\TappyChicken\Saved\ShaderDebugInfo\PCD3D_SM5\ M_Egg\

Shaders are grouped in maps ordered by vertex factories, which mostly end up corresponding to a mesh/component type. This path points to a LocalVF, which stands for Local Vertex Factory.

D:\UE4\Samples\Games\TappyChicken\Saved\ShaderDebugInfo\PCD3D_SM5\M_Egg\ LocalVF\

The final part of the path is the permutation of features used for the Material.

D:\UE4\Samples\Games\TappyChicken\Saved\ShaderDebugInfo\PCD3D_SM5\M_Egg\LocalVF\ BPPSFNoLMPolicy\

Because the console variable r.DumpShaderDebugShortNames=1 is set in the ConsoleVariables.ini file, the names are compacted to reduce file length.

For example, if the console variable were not enabled, the path would be:

D:\UE4\Samples\Games\TappyChicken\Saved\ShaderDebugInfo\PCD3D_SM5\M_Egg\FLocalVertexFactory\TBasePassPSFNoLightMapPolicy\

The shader dump folder contains a generated batch file, a text file, and the usf file.

The usf file is the final shader code that goes to the platform's compiler, which is run after the pre-processor.

The batch file is used to call the platform compiler to look at the intermediate code.

The text file, named DirectCompile.txt, contains the command line for debugging with ShaderCompileWorker.

Using ShaderCompileWorker for Debugging

ShaderCompileWorker is able to debug the call to the platform compiler using the following command line:

PathToGeneratedUsfFile is the final usf file from the ShaderDebugInfo folder.

ShaderFormat is the shader platform format you want to debug (in our case PCD3D_SM5).

ShaderType can be vs/ps/gs/hs/ds/cs, which each correspond to one of the shader types below:

Shortened Folder Name

Shader Type

vs

Vertex Shader

ps

Pixel Shader

gs

Geometry Shader

hs

Hull Shader

ds

Domain Shader

cs

Computer Shader

EntryPoint is the function name of the entry point for this shader in the usf file.

For example:

D:\UE4\Samples\Games\TappyChicken\Saved\ShaderDebugInfo\PCD3D_SM5\M_Egg\LocalVF\BPPSFNoLMPolicy\BasePassPixelShader.usf -format=PCD3D_SM5 -ps -entry=Main

If you add a breakpoint into the CompileD3D11Shader() function on D3D11ShaderCompiler.cpp, run SCW with this command line to step into how the engine calls the platform compiler.

This command line can be directly copied if you enabled the console variable r.DumpShaderDebugWorkerCommandLine=1 in the ConsoleVariables.ini file, which dumps a file called DirectCompile.txt next to the generated usf file.

Shader Debugging Workflows

Example: Using a Platform-Specific Shader Debugger

Example: Have Only the Build Machine Write Symbols to a Zip File

Example: Debugging Shaders Locally

Console Variable Summary

Platform Overrides

Changes from UE4

The primary route to debugging shaders is to enable the console variable r.Shaders.Symbols. This will trigger the engine to prepare shaders for debugging by platform-specific programs like RenderDoc and PIX.

You can override this console variable, along with the others listed below, on a per-platform basis. This is important to keep extra shader compilation under control.

Shader Debugging Workflows

Three shader debugging workflow examples are described below. In each case, you need to edit the engine configuration file for the platform you want to debug shaders on. For example, if you are debugging shaders for Android, you need to add console variables to the AndroidEngine.ini file.

Example: Using a Platform-Specific Shader Debugger

You want to use a platform-specific shader debugger to debug the shaders in a cooked game on that platform.

Add the following text to your [Platform]Engine.ini file:

Cook your game for that platform using the Editor or Unreal Build Tool (UBT). Create a GPU capture on that platform. If asked for a shader symbol path, direct it at the folder Path/To/My/Project/Saved/ShaderSymbols/Platform.

Example: Have Only the Build Machine Write Symbols to a Zip File

You want to always build shader symbols for a platform and only have the build machine write them to a .zip file.

Add the following text to your [Platform]Engine.ini file:

Now the build machine generates the following .zip file: Path/To/My/Project/Saved/ShaderSymbols/Platform/ShaderSymbols.zip.

Example: Debugging Shaders Locally

You have a graphics programmer working on a project with the same setup as Example 2, and they want to debug shaders locally.

In this case, the user should edit the [Platform]Engine.ini locally and add the following:

When they cook your project, the shaders will all be written loosely to Path/To/My/Project/Saved/ShaderSymbols/Platform.

Console Variable Summary

These are the console variables available for shader debugging.

Console Variable

Description

r.Shaders.Symbols

Enables debugging of shaders by generating symbols. If the platform requires external symbols, they are written to disk; otherwise, they are stored inside the shader data loaded at runtime. Can be overridden on a per-platform basis.

r.Shaders.ExtraData

Generates shader names and any other per-platform extra shader data. You can override this variable on a per-platform basis.

r.Shaders.GenerateSymbols

Generates symbols but does not write them to disk. You can override this variable on a per-platform basis.

r.Shaders.WriteSymbols

If the platform supports external symbols, write them to disk if they were generated. You can override this variable on a per-platform basis.

r.Shaders.SymbolPathOverride

If the platform supports external symbols, you can use this console variable to override the location they are written to.

r.Shaders.WriteSymbols.Zip

If the platform supports external symbols and they need to be written to disk, write them out into a single .zip file rather than individual files.

r.Shaders.AllowUniqueSymbols

If the platform supports external symbols, generate the symbol file names from the resulting shader and not its source files. We do not recommend enabling this as it can dramatically increase the size of your symbols.

Platform Overrides

You can override shader symbol console variables on a per-platform basis by adding special sections to the [Platform]Engine.ini files.

For example, if you want to override shader symbol console variables on the Android platform, add the following text to your AndroidEngine.ini:

Changes from UE4

In Unreal Engine 5, the console variables used for debugging shaders have changed. The table below highlights the old UE4 console variable and the new name being used in UE5. You need to update your configuration files that use these console variables when migrating your project to UE5 to continue using the generated data and debug shaders.

Old Name

New Name

Description

r.Shaders.KeepDebugInfo

r.Shaders.Symbols

Enables debugging of shaders by generating symbols and writing them to disk for consoles, PC symbols are still stored inline.

See note.

r.Shaders.ExtraData

Generates shader names and any other "extra" shader data.

r.Shaders.PrepareExportedDebugInfo

r.Shaders.GenerateSymbol

Generates symbols but does not write them to disk (note: symbols are stored in the DDC)

r.Shaders.ExportDebugInfo

r.Shaders.WriteSymbols

Writes symbols to disk if they have been generated.

r.Shaders.AllowUniqueDebugInfo

r.Shaders.AllowUniqueSymbols

Generates symbol associations based on shader source (off by default).

r.Shaders.ExportDebugInfo.Zip

.Shaders.WriteSymbols.Zip

Enables writing all symbols to disk as a single .zip file.

r.Shaders.KeepDebugInfo was split into r.Shaders.Symbols and r.Shaders.ExtraData to remove the changes to runtime shader data when only symbols are required. This is particularly useful for platforms that support exported debug info since this allows you to generate symbols for shipping builds without changing the final shader data.

API

Disabling/Enabling

PIX

Credit

The Rendering Hardware Interface (RHI) now supports asynchronous compute (AsyncCompute) for Xbox One. This is a good way to utilize unused GPU resources (Compute Units (CUs), registers and bandwidth), by running dispatch() calls asynchronously with the rendering. Async compute uses a separate context, and we provide RHI functions to synchronize the rendering and compute contexts. Dr PIX is useful for identifying areas which might benefit from async compute. For example, if half the CUs are unused during a particular rendering pass, those CUs could potentially be utilized by an asynchronous compute job. Async compute has some restrictions:

Buffers with UAV counters are not supported (this is a limitation of the XDK, and will generate a D3D warning)

Async compute jobs do not show up in PIX GPU captures (although they do appear in Timing Captures) PIX only captures the graphics immediate context (this is a platform limitation).

Automatic pipeline flushes are not provided by the driver. You need to explicitly call RHICSManualGpuFlush if flushes are needed (e.g. if one dispatch is dependent on the previous one)

API

RHIBeginAsyncComputeJob_DrawThread (EAsyncComputePriority Priority) Begins an async compute job from the rendering thread. The priority is used to determine the number of shader resources to allocate for the job (via ID3D11XComputeContext::SetLimits). There are currently two priorities available, AsyncComputePriority_High and AsyncComputePriority_Default.

RHIEndAsyncComputeJob_DrawThread Ends an async compute job. Returns a 32-bit Fence Index which can be used for synchronization, or -1 if compute is disabled or there is no active compute job

RHIGraphicsWaitOnAsyncComputeJob Inserts n command in the graphics immediate context to block until an async job is complete. Passing -1 causes this to early-out.

Between calls to RHIBeginAsyncComputeJob_DrawThread and RHIEndAsyncComputeJob_DrawThread, the RHI will be in the async compute state. During this time, supported RHI commands will be executed via the async compute context. Unsupported RHI functions will assert.

Disabling/Enabling

Async compute can be enabled or disabled at compile time with the #define USE_ASYNC_COMPUTE_CONTEXT. It can be disabled at runtime with the r.AsyncCompute console variable. When async compute is disabled, dispatches within async compute blocks are executed synchronously on the graphics command buffer. USE_ASYNC_COMPUTE_CONTEXT is defined to 0 on PC, since it's not supported in D3D11.1.

PIX

Async compute context jobs are not captured in GPU captures, so these captures can give a misleading picture of GPU performance when async compute is enabled. For graphics debugging purposes, async compute should be disabled using the above cvar. Async compute is supported by PIX timing captures. These show up in the timeline like this:



Credit

This feature was implemented by Lionhead Studios. We integrated it and indend to make use of it as a tool to optimize XboxOne rendering.

Topic List

The following documents will go over all of the various items that you need to be aware of when trying to create and use global shaders via a Plugin.

Topic List



Going over creating shaders in Plugins.



Creating and setting up a new Global shader via a Plugin.

Plugin Creation Tips

Render Thread

Unreal Shader Files

Shader File Preprocessing and Virtual File Path

First Global Shader

Engine/Public/Platform.usf

Shader Development Tips

Troubleshooting

Existing Renderer Convention

Additional Links

Please note that this document is not a guide on how to write HLSL code or GPU efficient shaders but merely to show you how to create a new shader using the Plugin system.

Adding new shaders for use in Unreal Engine can now be achieved via the Plugin system. Creating a shader via the Plugin system allows you to quickly and easily share what you have created with the one you want. In the following document, we will take a high-level look at what needs to done to create shaders in plugins.

For additional help, you can directly look at //Engine/Plugins/Compositing/LensDistortion's Plugin.

Plugin Creation Tips

When creating a new Plugin, you should be aware of the following things:

Use the Plugin Wizard to quickly create all of the needed files and folders for your Plugin.

Right now, it is not possible to make drastic changes, like adding a new shader model, to the Material Editor via Plugins.

Make sure you add all of your files and folder in the required location and then regenerate your Visual Studio solution files.

In your ProjectName.uplugin, make sure that the module's LoadingPhase to PostConfigInit (only for the modules that will have shader implementations) like in the following example:

Render Thread

As opposed to game-side API, the RHI render commands are (and should be) enqueued by a dedicated thread: the rendering thread. The game thread enqueues FIFO (first in, first out) commands through the ENQUEUE_RENDER_COMMAND to the rendering thread. The rendering thread, therefore, can be 0 or one frame behind the game thread. As a matter of CPU performance, the synchronization between them must be avoided at all cost in production runtime. To make sure your plugin's C++ function is called by the right thread, you can add multiple asserts such as check (IsInGameThread()); or check (IsInRenderingThread()); for improved threading robustness.

Unreal Shader Files

There are two different shader file types that you need to be aware of when developing new shaders for use in Unreal Engine. Each file has a different purpose which you will find listed below:

Unreal Shader Headers (.USH)

Only included by other USH or USF files

Unreal Shader Format (.USF)

Should be private data only

No backward compatibility is guaranteed in Private directories

Should contain shader entry points

Shader File Preprocessing and Virtual File Path

USF shader files, based on HLSL language, is Unreal Engine shader file format that contains the multi platform shader code. To achieve this multi platform support, the engine's shader compiler has added an extra platform-independent source file preprocessing pass before the platform-specific shader compiler (FXC, HLSLCC for GLSL cross compilation, etc.). As a result, all #define and #if are resolved at this very first preprocessing. Of course, each platform has built-in #define to know at shader preprocessing the targeted platform, such as VULKAN_PROFILE.

As same as C/C++ files, you can include usf files with #include "HelloWorld.usf," that would include the file named HelloWorld.usf stored in the same directory as the USF file you have the #include written in. To avoid multiple includes of the same file, you can add the #pragma once pre processing directive at the top of your file. For instance:

FooCommon.usf

FooBar.usf

FooBarComputeShader.usf

You can also do this from a Plugin or project module's shader to include a USF file by doing either of the following:

In the engine with #include /Engine/<FilePath>, where <FilePath> is a file path relative to //Engine/Shaders/ directory;

Or another plugin with #include /Plugin/<PluginName>/<PluginFilePath>, where <PluginName> is the name of an activated Plugin, and <PluginFilePath> is a file path relative to the Plugin's Shaders/ directory. It is the responsibility of the developer to add a dependency to the correct Plugin in the .uplugin.

First Global Shader

Global shaders inherit from the FGlobalShader in the following manner:

Engine/Public/Platform.usf

To have your shader compiling on all Unreal Engine platforms, you are required to include /Engine/Public/Platform.usf in all your shader files (directly or indirectly).

Shader Development Tips

You can customize locally using ConsoleVariables.ini to change some settings in the renderer to accelerate iteration process when writing shaders. For example, the following Console Variables will help you get detailed debug information about what your shader is doing:

r.ShaderDevelopmentMode = 1 To get detailed logs on shader compiles and the opportunity to retry on errors.

r.DumpShaderDebugInfo = 1 To dump preprocessed shaders in the Saved folder.

Warning: leaving this on for a while will fill your hard drive with many small files and folders so make sure to disable it when you are done.

Troubleshooting

If you are having issues getting your shader to compile or show up in the Unreal Engine editor, try the following:

If you get the error Can't compile: /Plugin/<MyPluginName>/<MyFile> not found.

Make sure to check your Plugin's module's LoadingPhase is set to PostConfigInit, and that there are no typo's in the Plugin's Shaders/ directory name.

If you get the error Can't #include "/Plugin/<ParentPluginName>/<MyFile>":

Make sure to check that the parent Plugin is activated and also check your Plugin dependency as this error means you are missing a Plugin dependency in your .uplugin or .uproject.

Existing Renderer Convention

In the renderer, we tend to have a convention on naming shader classes and shader entry point, especially with a shader domain suffix as shown in the following table:

Shader Domain

Suffix

Vertex Shader

VS

Hull Shader

HS

Domain Shader

DS

Geometry Shader

GS

Pixel Shader

PS

Compute Shader

CS

For example, in a C++ file, the call to FLensDistortionUVGenerationVS has VS at the end signaling that it is a Vertex Shader. Inside of a USF file the void MainVS(...) ends with a VS signaling that it is going to use the Vertex Shader. When dealing with Struct's in HLSL, the struct name should start with F like FBasePassInterpolators for example.

To read more about coding standards in Unreal Engine check out the Unreal Engine Coding Standards document for more information.

Additional Links

The following links contain more information about developing Global Shaders inside Unreal Engine.

FGlobalShader Base Class

Debugging the Shader Compiling Process

Adding Global Shaders to Unreal Engine

1 - Code Setup

End Result

2 - Blueprint Setup

End Result

The Unreal Engine Plugin system enables anyone to add a wide range of new functionality without the need to recompile and distribute the entire engine. In the following How - To we will recreate the Lens Distortion global shader plugin to demonstrate how you would go about implementing a global shader that is controllable via Blueprints.



Click for full image.

For this example, we will be re-creating the existing Lens Distortion plugin that can be found in Engine\Plugins\Compositing\LensDistortion to a new Plugin called Foo to demonstrate how you would implement this workflow.

The Shaders in Plugins Quick Start will walk you through creating and using global shader as a Plugin.

1 - Code Setup

Before you can start creating a new Plugin for Unreal Engine you will first need to make sure that you have Visual Studio installed. Visual Studio is required for this Quick Start as you will need to compile your Plugin's code so that it can run. If you are not sure how to go about doing this, check out the Setting Up Visual Studio for Unreal Engine documents for more help.

First, create a new Games project and select a Blank template. Make sure that you have Maximum Quality and No Starter Content enabled.

Once the project has been created, Visual Studio will open up and after it has, right- click on the ShadersInPlugins project and select the Build option to compile the project.



When the project has finished compiling, press the F5 key inside Visual Studio to launch the ShadersInPlugins project in the Unreal Engine Editor.

Once the Unreal Engine Editor has finished loading, open up the Plugins manager by going to Edit > Plugins and then click on the New Plugin option that is on the lower right-hand side of the Plugin window to bring up the New Plugin creation window.



Click for full image.

From the New Plugin window, select the Blank plugin and then input the name Foo for the name and keeping all of the settings as default. When all of that is completed, press the Create Plugin button to create all of the initial required content for the plugin.



Click for full image.

When that is completed, shut down Unreal Engine and Visual Studio and then go to the Plugins > Foo plugin folder that was created inside your project folder.

Inside the Foo plugins folder, add a new folder called Shaders and then inside of that folder, create a new folder called Private.



Click for full image.

Inside of the Private folder, create a new text file and call it MyShader.USF and then copy and paste the following HLSL code into this file, saving the file when completed.

Make sure that you change the file extension to .USF or Unreal Engine will not understand that this is a shader file.

Now, locate the Foo.uplugin file and open it up inside of a text editor and replace the information in that file with the following text, saving the file when done.

Next, go to Plugins\Foo\Source\Foo and create a new folder called, Classes and then copy both the LensDistortionAPI.h and LensDistortionBlueprintLibrary.h files from Engine\Plugins\Compositing\LensDistortion to this newly created folder.

The files that we will be copying can be found in Engine\Plugins\Compositing\LensDistortion.

Classes - Create New Folder

Copy - LensDistortionAPI.h

Copy - LensDistortionBlueprintLibrary.h



Then, go to the Private folder and copy both the LensDistortionBlueprintLibrary.cpp and the LensDistortionRendering.cpp files to this Private folder.

Private - Existing Folder

Copy - LensDistortionBlueprintLibrary.cpp

Copy - LensDistortionRendering.cpp



Now close both the Unreal Engine Editor and Visual Studio and then locate your projects .U project file. When located, right-click on it and select the Generate Visual Studio project files option.



Reopen your Visual Studio solution and then go to Foo > Classes and open up the LensDistortionAPI.h file. Inside this file replace FLensDistortionCameraModel with FFooCameraModel.

You should replace FLensDistortionCameraModel with FFooCameraModel four times in this file.

Next, open up the LensDistortionBlueprintLibrary.h file. This file controls how this node will show up in Blueprints so not only do we need to replace FLensDistortionCameraModel with FFooCameraModel, we also need to change the Category = "Lens Distortion" to Category = "Foo | Lens Distortion".

You should replace FLensDistortionCameraModel with FFooCameraModel six times in this file.

Now go to the Private folder and open up the LensDistortionBlueprintLibrary.cpp file and replace the following:

FLensDistortionCameraModel with FFooCameraModel

ULensDistortionBlueprintLibrary with UFooBlueprintLibrary

You should replace FLensDistortionCameraModel with FFooCameraModel two times and ULensDistortionBlueprintLibrary with UFooBlueprintLibrary four times.

Next, in the Private folder open up the LensDistortionRendering.cpp file and replace FLensDistortionCameraModel with FFooCameraModel

You should replace FLensDistortionCameraModel with FFooCameraModel six times in this file.

Finally, in the LensDistortionRendering.cpp file, at lines 155 and 156, change the following two lines of code to point to the new MyShader.USF file that was created earlier.

Change:

IMPLEMENT_SHADER_TYPE(, FLensDistortionUVGenerationVS, TEXT("/Plugin/LensDistortion/Private/UVGeneration.usf"), TEXT("MainVS"), SF_Vertex)

To:

IMPLEMENT_SHADER_TYPE(, FLensDistortionUVGenerationVS, TEXT("/Plugin/Foo/Private/MyShader.usf"), TEXT("MainVS"), SF_Vertex)

Change:

IMPLEMENT_SHADER_TYPE(, FLensDistortionUVGenerationPS, TEXT("/Plugin/LensDistortion/Private/UVGeneration.usf"), TEXT("MainPS"), SF_Pixel)

To:

IMPLEMENT_SHADER_TYPE(, FLensDistortionUVGenerationPS, TEXT("/Plugin/Foo/Private/MyShader.usf"), TEXT("MainPS"), SF_Pixel)

Now, go to the Foo/Source folder and open up the Foo.Build.cs file and in the Foo.Build.cs under the PublicDependencyModuleNames.AddRange section add the following lines of code:

Then, in the PrivateDependencyModuleNames.AddRange section of Foo.Build.cs remove Slate and SlateCore and when completed your Foo.Build.cs file should look like this:

Re-launch your projects Visual Studio solution file and then recompile your project by pressing CRTL + 5 and when the compile has completed, press F5 to launch the Unreal Engine Editor.

When the Unreal Engine Editor finishes loading, go to the Plugins manager by going to Edit > Plugins.



Inside of the Plugins manager, scroll down to the bottom and look for the Project section and in this section, you should see your Plugin.



If your plug is not enabled, enable it by clicking on the checkmark box next to its name and re-start the Unreal Engine editor.

To check to make sure everything is there, open up the Level Blueprint and right - click in the Event Graph inputting Foo into the search box. Once that is complete, you should now see all of the items that were added to the Foo Camera category.



Click for full image.

End Result

Congratulations, you have now successfully recreated and compiled a new version of the Lense Distortion Unreal Engine plugin. In the next step, you will learn how to invoke this new global shader from Blueprints and also see how it distorts Render Targets.

2 - Blueprint Setup

With the Plugin now verified to be working, in the following section you will be shown how to call the global shader using Blueprints.

To see how this works, right-click in the Content Browser and create a new Blueprint Class that has Actor as its parent class with the name, DrawUVDisToRenderTarget.



Next, create a new Render Target called RT_00 and a new Material called MAT_RT.



Open up MAT_RT Material and then add the RT_00 Render Target to the Material Graph, connecting its output to the Base Color input on the Main Material Node, pressing the Apply and Save button when done.



Click for full image.

Next, open up the DrawUVDisToRenderTarget Blueprint and create/add the following variables and nodes to the Event Graph.

Variables

Default Value

K1

1.0

K2

1.0

inc

1.0

Nodes

Default Value

W

N/A

S

N/A

Event Tick

N/A

Draw UVDisplacement to Render Target

Input 1 into FOV, Aspect Ratio, and Overscan Factor

Make FooCameraModel

N/A

Clear Render Target 2D

N/A



To easily demonstrate how the Draw UVDisplacement to Render Target will warp the supplied render target, you will need to setup your up Blueprint so that the values input into the K1 and K2 inputs on the Draw UVDisplacement to Render Target node can be increase or decrease by the press of a button. To accomplish this, setup the nodes in the Event Graph so that they match the following image:



You can copy and paste this Blueprint code directly into your Blueprint.

Do not forget to input your Render Target into the Output Render Target or you will not see anything happen.

With the required Blueprint logic now setup, make sure to Compile and Save your Blueprint and then drag your Blueprint from the Content Browser into a level. When completed, select the Blueprint and under Input change the Auto Receive Input from Disabled to Player 0.



Click for full image.

Next, select the floor and duplicate it by pressing CTRL + W and then rotate it -90 degrees in the X axis then drag the Material MAT_RT onto it so you can see the effect the of the Draw UVDisplacement to Render Target.



Click for full image.

With everything now setup, press the Play button and then press the W and S keys to warp the Render Target that was input into the Draw UVDisplacement to Render Target node like in the following video.

End Result

At this point you can now distort the content inside a render target from Blueprint to create all kinds of interesting shapes. Next, try and create a new Plugin or edit the existing one and see what kind of interesting images and effects you can create.

Rendering thread

Development approach

Thread specific data structures

Performance considerations

Inter-thread communication

Asynchronous

Blocking

Rendering resources

UObjects and Garbage Collection

Game thread FRenderResource handling

Static resources

Dynamic resources

Updating state vs Traversing the scene for rendering

Rendering thread

In Unreal Engine, the entire renderer operates in its own thread that is a frame or two behind the game thread.

When dealing with rendering things, you have to carefully consider every memory read and write to ensure not only thread safety, but also determinism in behavior. When functional behavior depends on execution speed differences between two threads, it is called a race condition. Avoiding race conditions is important because they are usually very difficult to reproduce, and may be machine, platform, debugger or configuration dependent because of speed differences. These kind of bugs can rarely be debugged and take something like 10x the time to fix compared to a normal reproducible bug.

Here is a simple example of a race condition / threading bug:

There is no way to exhaustively test to find race conditions. It is important to realize that you cannot create reliable threaded code by guess-and-checking or retroactively fixing bugs. The best approach is to completely understand the interactions of the game thread and rendering thread and use mechanisms to ensure determinism. You should be able to explain the order of events that will make every interaction deterministic, or else you are almost certainly creating race conditions.

For this reason, it is a good idea to have data in separate structures that are 'owned' by the different threads so that it is obvious who can modify what. This holds true for functions as well. It is best to always call each function from the same thread or things get really complicated. Most of Unreal Engine is structured this way, for example, UPrimitiveComponent is the base game thread class of anything that can be rendered, cast shadows, has its own visibility state, etc. The rendering thread can never touch the memory of UPrimitiveComponent directly since the game thread may be writing to its members at any time. The rendering thread has its own class to represent this functionality, which is FPrimitiveSceneProxy. The game thread can never touch the members of memory of an FPrimitiveSceneProxy after it is created and registered. UActorComponent::RegisterComponent adds a component to the scene and makes it visible to the renderer by creating a FPrimitiveSceneProxy. Once the component is registered, it will have FPrimitiveSceneProxy::DrawDynamicElements called on it for every pass that is needed if it is visible.

The game thread blocks at the end of each Tick() until the rendering thread catches up to either one frame or two frames behind. Since the rendering thread is so far behind, it is never acceptable during gameplay to block the game thread until the rendering thread catches up completely. Blocking during loading or GC of individual objects is also a bad idea, since Unreal Engine supports async streaming levels. There are asynchronous mechanisms for various operations to avoid blocking.

Inter-thread communication

The primary method of communication between the two threads is through the ENQUEUE_UNIQUE_RENDER_COMMAND_XXXPARAMETER macro. This macro creates a local class with a virtual Execute function that contains the code you enter into the macro. The game thread inserts the command into the rendering command queue, and the rendering thread calls the Execute function when it gets around to it.

FRenderCommandFence provides a convenient way to track the progress of the rendering thread on the game thread. The game thread calls FRenderCommandFence::BeginFence to begin the fence. The game thread can then call FRenderCommandFence::Wait to block until the rendering thread has processed the fence, or it can just poll the progress of the rendering thread by checking GetNumPendingFences. When GetNumPendingFences returns 0, the rendering thread has processed the fence.

FlushRenderingCommands is the standard method of blocking the game thread until the rendering thread has caught up. This is useful for offline (editor) operations which modify memory being accessed by the rendering thread.

FRenderResource provides the base rendering resource interface and provides hooks for initialization and releasing. Anything that derives from FRenderResource (FVertexBuffer, FIndexBuffer, etc) needs to be initialized before it is used for rendering and released before being deleted. FRenderResource::InitResource can only be called from the rendering thread, so there is a helper function (BeginInitResource) that can be called on the game thread to enqueue a rendering command to call FRenderResource::InitResource. RHI functions can only be called from the rendering thread (with the exception of a few for creating devices, viewports, etc).

Garbage Collection (GC) happens on the game thread and operates on UObjects. The game thread may delete a UObject while the rendering thread is processing a command that references it. For this reason, the rendering thread should never dereference a UObject pointer unless a mechanism is in place to make sure the UObject is not deleted until the rendering thread no longer references it. An example is UPrimitiveComponent, which uses a FRenderCommandFence called DetachFence to prevent GC from deleting the UObject before the rendering thread has processed the detach command.

There is two common scenarios of game thread rendering thread resource interaction to consider, the case of static resources (only modified on load or in the editor, like an index buffer) and dynamic resources, which need to be updated every frame with the latest results of the game thread simulation.

Here is how the static resource interaction is handled in Unreal Engine, using USkeletalMesh as an example.

USkeletalMesh::PostLoad gets called on load, which calls InitResources. This calls BeginInitResource on any static FRenderResources that it has like the index buffer. BeginInitResource enqueues a rendering command to call FRenderResource::InitResource. From this point on, the game thread can no longer modify the index buffer memory until it does something to take back ownership.

A component registers which starts rendering with the USkeletalMesh's index buffer.

GC determines that the component is no longer referenced at some point (level unload or no longer referenced) and detaches the component. Note that at this point, the game thread cannot delete the index buffer memory, because the rendering thread may not have processed the detach yet and may still be rendering with the index buffer.

GC calls USkeletalMesh::BeginDestroy, which is the game thread object's chance to enqueue commands to release the rendering resources, so it does BeginReleaseResource(&IndexBuffer); The game thread still cannot delete the memory of IndexBuffer because the rendering thread has not necessarily processed the release yet. We could block the game thread until the rendering thread catches up, but this would cause hitches and be slow, so we have an asynchronous mechanism instead. In order to track the rendering thread's progress of processing the release command we initiate a fence.

GC calls USkeletalMesh::IsReadyForFinishDestroy, and will not destroy the UObject until this function returns true. The function only returns true once the fence has been passed by the rendering thread, which means it is now safe to delete the index buffer memory from the game thread.

GC finally calls UObject::FinishDestroy which can be used to release memory in a central location. In the case of the index buffer, its memory gets freed when the USkeletalMesh destructor calls FRawStaticIndexBuffer's destructor, which calls the destructor of the TArray holding the index buffer memory, which frees the memory.

This mechanism works well because it is efficient (never blocks either thread, initializes in a central location instead of checking for whether initialization is needed every frame), and is deterministic.

The skeletal mesh bone transforms which are produced by the game thread animation each frame are a good example of dynamic resource updating. The goal is to get the transforms from the game thread after each animation update into an array on the rendering thread where they can be set as shader constants. The same would be true if you were updating an index or vertex buffer each frame. Here is the order of operations:

USkinnedMeshComponent::CreateRenderState_Concurrent allocates USkinnedMeshComponent::MeshObject. From this point on, the game thread can only write to the MeshObject pointer, but not to the memory of the FSkeletalMeshObject.

USkinnedMeshComponent::UpdateTransform gets called to update the component's movement at least once per frame. This calls FSkeletalMeshObjectGPUSkin::Update in the case of GPU skinning. At this point, we have up to date transforms on the game thread and need to get them over to the rendering thread. This is done by first allocating memory on the heap (FDynamicSkelMeshObjectData), then copying the bone transforms into it, and then passing off this copy to the rendering thread using ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER. The rendering thread now owns the copy and is responsible for deleting it. The ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER macro contains code to copy the transforms to their final destination so they can be set as shader constants. This is where you would lock and update a vertex buffer if updating vertex positions.

At some point, the component gets detached. The game thread enqueues rendering commands to release all of the dynamic FRenderResources and can now set the MeshObject pointer to NULL, however the actual memory is still being referenced by the rendering thread and cannot be deleted. This is where the deferred deletion mechanism comes in to play. Classes that derive from FDeferredCleanupInterface can be deleted in an asynchronous way that is thread safe. FSkeletalMeshObject implements this interface. The game thread wants to kick off the deferred deletion of the FSkeletalMeshObject so it calls BeginCleanup(MeshObject). The memory will eventually be deleted when it is safe to do so and cleanup is complete.

Updating state vs Traversing the scene for rendering

When developing a system that has distinct update and render operations, it is tempting to combine the two in DrawDynamicElements, however this is a poor design choice. A better solution is to separate the update out of the rendering traversal, for example enqueue the update command from within the game thread Tick.

DrawDynamicElements is called by the high level rendering code to draw the elements of a primitive component. The high level code assumes that no RHI state is being changed, and that it can call DrawDynamicElements as many times as it needs each frame, depending on shading passes, number of views, and scene captures in the scene. DrawDynamicElements may even be called, but then the underlying drawing policy discards the results for various reasons (for example a translucent FMeshElement submitted during the depth pass will be discarded). If the primitive component is actually not visible, the occlusion system may or may not actually call DrawDynamicElements, depending on the heuristic it is using. All of these factors can conflict with state updating which should happen once per frame.

A better solution is to separate the update from the rendering traversal. The game thread Tick can enqueue a rendering command to do the update operation. The rendering command can optionally skip updating based on visibility, if this is acceptable for the use case, by using LastRenderTime of the primitive scene info. If the update operation is enqueued separately in this manner, any RHI functions can be used including setting different render targets.

State caching (as opposed to updating) is an exception to this rule. State caching is storing an intermediate result of the rendering traversal as an optimization. It is closely tied with the traversal, and does not change RHI state, so it does not suffer the downsides mentioned before (as long as the determination of when to cache is done correctly).

Importing Textures

Texture Asset Editor

Texture Workflows and Optimizations

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Textures are image assets that are primiarly used in Materials but can also be directly applied outside of Materials, like when using an texture for a heads up display (HUD).

For Materials, textures are mapped to surfaces which the Material is applied to. Textures can be used for a variety of calculations within a Material by being applied directly to an input (such as, Base Color), used as a mask, or using the RGBA values for other calculations.

Materials may make use of several textures that are all sampled and applied for different purposes. For instance, a simple material may have a Base Color texture, a Specular texture, and a Normal Map texture. In addition, there may be a map for Emissive and Roughness stored in the alpha channels of one or more of these same textures. Packing multiple values in a single texture allows them to be used more readily while saving draw calls for performance and reducing disk space.

Importing Textures

Textures are imported into the engine through the Content Browser by using the Import button or by dragging-and-dropping images directly from your operating system's windows into the Content Browser.

A variety of image formats and file types are supported:

.bmp

.float

.jpeg

.jpg

.pcx

.png

.psd

.tga

.dds (Cubemap or 2D)

.exr (HDR)

.tif (TIFF)

.tiff (TIFF)

When importing your textures, consider the following suggestions for the dimensions of your textures:

Use power of two sizes when possible, such as 32, 64, 128, 2048, and so on.

Power of two values can be mipmapped and streamed. Non-power of two sizes are never streamed and do not generate mipmaps.

Some GPUs have hardware limits in the maximum size texture they can support. For example, some GPUs may not support texture sizes larger than 8192 pixels (8k).

Texture Asset Editor

The Texture Asset Editor is a standalone window where you can view and edit Texture Assets.



From this editor window, you can view the texture and its color channels. The Details panel provides additional information about the imported texture along with a set of properties to configure the texture. This includes being able to set the compression, adjust brightness and saturation, set level of detail, and much more.

Texture Workflows and Optimizations

The following topics details some common workflows and optimizations you do with textures in your projects.



Reference for supported texture formats and file types and their configuration.



System for loading and unloading textures into and out of memory during gameplay.



An overview of the available virtual texturing methods in Unreal Engine.

Texture Resolution

Engine Texture Resolution Limit

Compressed Texture Memory Requirements

Engine Config TextureGroup Properties

PC AppCompat Buckets

TEXTUREGROUP Properties

Filtering

TextureGroup, LODGroup and LODBias

Texture Properties

One of the biggest contributors to any digital projects memory footprint comes from the size and amount of Textures used. Luckily Unreal Engine has a very robust system for non-destructively reducing Texture size across all your projects Textures. In the following page we will take a look at these systems and how you can use them to reduce your projects Texture memory requirements.

Texture Resolution

Unreal Engine supports texture resolutions from 1x1 up to 8192x8192 with some slight modifications to .INI files. Current DirectX video adapters and game consoles support various texture resolutions from 1x1 to 2048x2048 and up to 8192x8192. The highest texture resolution supported by a specific hardware device varies by manufacturer, model and available texture memory. There are a number of features and settings in Unreal Engine 4 for managing the texture resolutions that are rendered for various areas such as world geometry or the user interface.

Engine Texture Resolution Limit

Unreal Engine 4 defaults to limiting the maximum number of texture mips to 14, which effectively limits the largest rendered texture to 8192 (1x1 to 8192x8192 is 14 mips).This has the side-effect that imported 8192 textures will only render up to mip1 of 4096. The constant MAX_TEXTURE_MIP_COUNT which defaults to 13 in the engine source files can be modified to a value of 14 to support 8192 texture rendering. This constant is defined in the following source files (as of QAMar09, be sure to verify on other QA versions).

With the release of UE 4.8 you can now modify your projects to use Textures up to 8192 in size without having to modify the C++ code by adding the following text to your projects BaseDeviceProfiles.ini file and setting the MaxLODsize to 8192

Once you have added the section you want to increase the size for, save the file and restart the Editor. When the Editor restarts any Textures that were imported at a size of 8192 should now show 8192 as the size of LOD 1, instead of being clamped to a maximum of 4096. In the following example image we have modified the BaseDeviceProfiles.ini file in a project to allow for the use of Textures that are up to 8192 in size. When the texture, Texture_8k_Test is loaded we can see that both the imported and displayed texture size are at 8192.



Click image for full size.

Compressed Texture Memory Requirements

DXT uses lossy compression based on packing pixels into 4x4 blocks with paletted colors and interpolated colors. This results in an 8:1 DXT1 and 4:1 DXT5 constant compression file size. Since video memory and texture pool resources are fixed for a specific platform and hardware, a balance must be struck between texture resolution and resource usage. The following table lists the texture memory requirements for DXT1 and DXT5 textures at various common resolutions with full mips (1x1 up to full native mip0). Note that the memory requirements are near-constant multiples of the texture resolution ratio, and that DXT5 textures require near-twice the memory of their DXT1 counterpart.

Since the resolution to compression ratio is a constant, to calculate the memory requirements for a texture resolution not listed here, simply multiply the resolution ratios. For example, a 1024x512 texture would be one-half the memory requirements of a 1024x1024 texture.

The table data was compiled from textures created by ATI's Compressonator using Box-Filter mip generation and DirectX Texture Compression.

Resolution

Total Mips from 1x1

DXT1

DXT5

16x16

5 mips

312 bytes

496 bytes

32x32

6 mips

824 bytes

1.48kb (1,520 bytes)

64x64

7 mips

2.80kb (2,872 bytes)

5.48kb (5,616 bytes)

128x128

8 mips

10.8kb (11,064 bytes)

21.4kb (22,000 bytes)

256x256

9 mips

42.8kb (43,832 bytes)

85.4kb (87,536 bytes)

512x512

10 mips

170kb (174,904 bytes)

341kb (349,680 bytes)

1024x1024

11 mips

682kb (699,192 bytes)

1.33MB (1,398,256 bytes)

2048x2048

12 mips

2.66MB (2,796,344 bytes)

5.33MB (5,592,560 bytes)

4096x4096

13 mips

10.6MB (11,184,952 bytes)

21.3MB (22,369,776 bytes)

8192x8192

14 mips

42.6MB (44,739,384 bytes)

85.3MB (89,478,640 bytes)

Engine Config TextureGroup Properties

The minimum and maximum LOD (mip) supported for specific game TextureGroups is defined in a number of engine configuration files.The source set of configuration settings files is located in the [Unreal Engine 4 Install Location]\Engine\Config\BaseDeviceProfiles.ini file under the [/Scripts/Engine.TextureLODSettings] section.

For developing games, the [your_game]\Config\DefaultDeviceProfiles.ini file also contains a mirror set of the base properties in the Engine\Config\ folder and should be the copy that is normally modified for your game's specific settings.

Note that there are independent sets of TextureGroup entries for the Unreal Editor and in-game. These two sets are respectively located in the [SystemSettingsEditor] and [SystemSettings] sections in the config files.

The TextureLODGroup settings entries in the DefaultDeviceProfiles.ini file will look similar to this. Note that older QA versions may not include the MinMagFilter and MipFilter properties for each setting.

PC AppCompat Buckets

AppCompat is used to override various SystemSettings based on objective and empirical evidence gathered at startup. When app compatibility is enabled (PC only), the system measures machine capability, and then overwrites the Engine.ini values with preset values from one of 5 "buckets". See BaseCompat.ini in the Engine\Config\ folder for an example of this usage.

AppCompat is intended to only be checked ONCE when the game is first run (not the editor). It detects this by checking for the existence of an [AppCompat] section in [game]Engine.ini, which contains the previously computed scores for the machine. If AppCompat has already been applied once, it is not changed again to allow custom changes to be made by users without being overwritten every time.

AppCompat is specifically disabled for the editor so machine specs do not affect how assets are viewed on various machines during development. This is the reason for the split between SystemSettings and SystemSettingsEditor.

You can effectively disable AppCompat by supplying an empty DefaultCompat.ini for your game, which causes it to initialize all buckets from [SystemSettings] in Engine.ini. In this case, the system operates exactly as it did before AppCompat was introduced.

TEXTUREGROUP Properties

Each TextureGroup entry defines the texture properties for a specific texture set as used in the game rendering. Grouping textures into common sets allows for better control over the texture memory pool use by various game texture resources.

Property

Description

MinLODSize

Minimum mip size that will be rendered, specified in pixels, range of 1 to 8192 as power-of-two's, must be less than MaxLODSize.

MaxLODSize

Maximum mip size that will be rendered, specified in pixels, range of 1 to 8192 as power-of-two's, must be greater than MinLODSize.

LODBias

A negative or positive value that determines the number of mip levels to offset prior to uploading for render, clamped within MinLODSize and MaxLODSize.

MinMagFilter

Specifies the texture filter type when textures are minified or magnified by the GPU. See the chart below.

MipFilter

Specifies whether the GPU should blend two mips together when viewing the texture from a distance or at a grazing angle. See the chart below.

NumStreamedMips

The number of mips that are allowed to be streamed in or out. If a texture has 10 mips and NumStreamedMips is 2, only the 2 highest mips will be allowed to stream in or out. The texture will therefore have 8-10 mips in memory at any given time. Setting NumStreamedMips to 0 means that no mips will be streamed and the textures using this LOD group will always be fully loaded. Setting NumStreamedMips to -1 means that all mips are allowed to be streamed in or out (there are still other restrictions that apply though). NumStreamedMips is an optional setting that defaults to -1.

Filtering

MinMagFilter

MipFilter

filter type

point

Point

linear

point

Bilinear

linear

Trilinear

aniso

point

Anisotropic Point

aniso

Anisotropic Linear

TextureGroup, LODGroup and LODBias

The TextureGroup and LODBias settings specified in the config ini files, along with the LODGroup and LODBias settings specified in the Texture Properties determine the final set of texture mips used for an individual texture.

An example TextureGroup entry in the [your_game]Engine.ini may look like this:

Any textures assigned to the TEXTUREGROUP_World LODGroup will use these settings to determine the mip range used for rendering.The additional LODBias setting in the Texture Properties is additive with the LODBias specified in the config ini file TextureGroup.

The LODBias biases or offsets which mip is chosen for rendering. The LODBias is calculated before the LODGroup Min/Max range. The LODBias in the Texture Properties is added to the LODBias in the TextureGroup to determine the final LODBias value used.A LODBias of 0 is the main (native) texture resolution. A LODBias of 1 is the first mip down for the texture, a LODBias of 2 is the second mip down, etc. For example, a 1024x1024 texture that has a LODBias of 1 results in the 512x512 mip being chosen for rendering.

The LODBias specified in the Texture Properties for each individual texture can be positive or negative, so that it can offset the TextureGroup's default LODBias to either higher or lower mip values.For example:

A TextureGroup LODBias of 0 and a Texture Properties LODBias of 0 would result in a final LODBias of 0.

A TextureGroup LODBias of 0 and a Texture Properties LODBias of 1 would result in a final LODBias of 1.

A TextureGroup LODBias of 1 and a Texture Properties LODBias of 1 would result in a final LODBias of 2.

A TextureGroup LODBias of 1 and a Texture Properties LODBias of -1 would result in a final LODBias of 0.

After the final LODBias is calculated, then the texture mip is checked to see that it fits into the TextureGroup's Min/Max LODSize range, and it is adjusted if necessary. This allows a simple config ini file change to effectively clamp a specific TextureGroup to within a set min/max LOD range.

For example, a 1024x1024 texture with LODBias of 1 uses the 512x512 mip, if it is in the TEXTUREGROUP_World LODGroup as shown above, it is then checked to see if it fits within the TextureGroup's Minimum and Maximum LODSize range, which in this case is 256 and 1024. Since each game title will have its own unique TextureGroup settings, artists and level designers should be aware of the MinLODSize and MaxLODSize for each group. It would increase distributable package size with no rendering quality benefit if a game shipped with 2048 textures assigned to a TextureGroup with a MaxLODSize of 1024.

Texture Properties

For an explanation of the meaning of the various texture properties, see the Texture Properties page.

Topics

Unreal Engine sometimes provides integrated third-party tools and plugins that are useful for development. These may include programming tools for debugging, gathering additional information, or ones that offer hardware benefits, like support for multiple linked GPUs.

Topics



Integration of NVIDIA Nsight™ Aftermath C++ library that enables post-mortem GPU crash analysis on NVIDIA GPUs.



Integration of NVIDIA's Alternate Frame Rendering technology that enables support for games using multiple GPUs with SLI.

Enabling NVIDIA Nsight™ Aftermath

Logs

Considerations

Unreal Engine supports NVIDIA's Nsight™ Aftermath C++ library for Windows-based developers, which provides additional data from NVIDIA GeForce-based GPUs after a crash occurs. This data contains crucial information about what the GPU was doing when the crash occurred, enabling you to track down what's happening with the GPU in your own projects.

Aftermath is a lightweight tool that is unobtrusive and reduces the performance footprint needed by some debugging tools. In fact, it's lightweight enough that it can even ship with finished games to provide the data you need from your customers' machines. Aftermath enables programmers to insert markers into their code that assist in tracking the root causes of crashes. This is now being used in the Unreal Engine Editor to track down and fix reported or captured issues.

For additional information and how to use it in your own project, visit NVIDIA's Nsight™ Aftermath documentation page.

Enabling NVIDIA Nsight™ Aftermath

Add the following console variable to your ConsoleVariables.ini configuration file to enable NVIDIA Nsight™ Aftermath in your project:tion file:

Or, you can enable it by passing it as a command line argument:

Logs

Once you've enabled NVIDIA Aftermath, you should see the following output in your log:

You can access your log in Unreal Engine 4 by going to File Menu > Window > Developer Tools > Output Log or by opening the log text file from your project folder.

When a crash happens, the log displays something similar to:

In this particular example, the GPU has crashed, and the resulting lines with the [Aftermath] preceeding indicate the current status and where in the frame the problem is so that you can investigate the root cause.

Considerations

For an average project that has approximately 200 to 300 markers, Aftermath is fast enough but slowdowns can happen when you have certain things like lots of per-object shadows that increase its cost. For this reason, the feature is not enabled by default.

Forcefully Enabling Alternate Frame Rendering

Unreal Engine supports NVIDIA's Alternate Frame Rendering (AFR) for packaged games running on NVIDIA SLI configurations. Alternate Frame Rendering works by alternating frames between the linked GPUs. One frame is rendered by GPU 1 with the next frame rendered by GPU 2, before repeating the procress. Using this method, image quality and performance are improved by using multiple GPUs on a single monitor.

Projects that intend to ship with support for Alternate Frame Rendering will need to work directly with NVIDIA to test their games and have it automatically switch over to use this functionality where possible.

For additional details, see NVIDIA documentation on their SLI modes, specifically Alternate Frame Rendering here.

Forcefully Enabling Alternate Frame Rendering

NVIDIA Control Panel allows for some applications to be manually added which support AFR forcibly enabling the SLI rendering mode. Add applications to the NVIDIA Control Panel using the following steps.

Open the NVIDIA Control Panel from your task tray, and navigate to Manage 3D Settings.

Click on the Program Settings tab. Under Select a program to cumstomize use the dropdown to select the program you want to add.

Next to SLI Rendering Mode, select Force Alternate Frame Rendering.



This feature is not guaranteed to improve the quality or performance of your applications. It is not intended for use with the Unreal Engine Editor, specifically. Should to want this for your developed and released project, you will need to talk with NVIDIA directly to set up this functionality with their drivers.

Getting Started

Material Workflow Concepts

Tutorials Index

Material Reference Pages

Additional Concepts and Tools

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Materials in Unreal Engine define the surface properties of the objects in your scene. In the broadest sense, you can think of a Material as the "paint" that is applied to a mesh to control its visual appearance.

In more technical terms, Materials tell the render engine exactly how a surface should interact with the light in your scene. Materials define every aspect of the surface including color, reflectivity, bumpiness, transparency, and so on. These calculations are done using data that is input to the Material from a variety of images (textures) and node-based Material expressions, as well as from various property settings inherent to the Material itself.

Getting Started

Material creation is a broad topic, and the node-based workflow allows you to create an almost infinite variety of surface types. Beginners are recommended to start with with the pages linked in this section. The Essential Material Concepts and Physically Based Materials pages introduce the theory and ideas that form the foundation of Material creation in Unreal. The Material Editor User Guide is a set of tool-based documentation that teaches practical aspects of using the Material Editor.



An introductory document on Materials in Unreal Engine.



An overview of the primary physically based Material inputs and how best to use them.



These pages provide an overview of how to use the Material Editor to create Materials.



An introductory document on Material Properties in Unreal Engine.



An in-depth look at the various inputs available on a Material and how they are used.



An introduction to the four types of float data in the Material Editor

Material Workflow Concepts

Once you understand the basic principles behind Material creation, the documents in this section are strongly recommended as a next step. Material Instances and Material Functions are foundational topics in Material creation, and help you optimize your workflow to save time and avoid doing the same work twice. Material Instances allow you or other artists on your team to quickly and easily customize Materials to produce multiple variations (or instances) from a single parent Material. Material Functions allow you to package parts of a Material graph into a single node, and share it to a common library for reuse in other Materials.



Hierarchical Material relationships that you to alter behavior and appearance of child Materials without shader recompilation.



Snippets of Material that you can save in packages and reuse across multiple Materials.



Two methods for layering Materials to create complex, unique surfaces.

Tutorials Index

The pages in this section are step-by-step, project based documents that walk you through some specific aspect of Material creation in Unreal. For example: Animating UV Coordinates, or Using Texture Masks.



Tutorials demonstrating various aspects of Material creation in Unreal Engine.

Material Reference Pages

The Material Editor provides dozens of Material Expressions and Functions, each meant to perform some specific task in your Material graph. If you are looking for information about how and when to use a specific node, start with the pages linked below. The Material Expression and Function reference pages are organized according to their categories in the Materials palette — for example, Blends, Gradients, Math, Coordinates, and so on.



Reference for all Material expressions available for use in the Material Editor.



Reference pages for each of the default Material Functions, organized by category.



A breakdown of the Material Editor user interface.



Guide to using the Material Instance Editor for modifying MaterialInstanceConstants.

Additional Concepts and Tools

Materials pages that do not fit more precisely into another category are found below. Many of these are intermediate to advanced topics that allow you to progress beyond the basics of Material creation and begin to develop more sophisticated Materials for your projects.



An overview of using Bent Normal maps in Unreal Engine.



How to achieve bump mapping from 3D procedural shaders where classic tangent space does not work.



Curve Atlases store a combination of Curve assets that enables you to access Curve Linear Color data through your Materials.



Feature that allows running calculations in the vertex shader to increase performance over running them per-pixel.



This page describes how to locate and use the Material Analyzer tool.



Overview of the Refraction Mode for Pixel Normal Offset in your Materials.



An overview of the Custom Primitive Data workflow for storing custom data per primitive that's accessible through Blueprint.



Explanation of how translucent surfaces are lit and cast shadows including self-shadows.

Shading Pipeline Overview

Materials

Materials Workflow Overview

Creating a New Material

Material Properties

Material Expression Nodes

Material Expression Properties and Values

Inline Editing of Values and Properties

The Main Material Node

Compile and Apply

Material Editor User Guide

Workflow Efficiency Concepts

Material Instances and Parameterization

Material Functions

Working with Color and Data

Materials in Unreal Engine define the surface properties of the objects in your scene. In the broadest sense, you can think of a Material as the "paint" that is applied to a mesh to control its visual appearance.

More specifically, Materials tell the engine exactly how a surface should interact with the light in your scene. Materials define every aspect of a surface, including color, reflectivity, roughness, transparency, and so on.

Shading Pipeline Overview

In a rendering pipeline, shaders are programs that define how each vertex or pixel should be rendered. Shaders in Unreal Engine are written in High Level Shading Language (HLSL). Shader code is then converted to a list of Assembly Language instructions that the GPU hardware can execute. This is how the final pixel colors are output to your display.

In the Unreal Editor you do not need to write HLSL code to create shaders for your project. Instead, you will create assets called Materials in a visual scripting interface called the Material Editor.

Materials

Materials are built by combining nodes called Material Expressions in a shader graph and passing the results into the inputs on the Main Material Node.



Behind the scenes, these node graphs are silently translated to HLSL. As a user, you can view the HLSL code but cannot edit it directly. This makes Material creation in Unreal Engine intuitive and approachable.



You can view the HLSL code of a Material by going to Window > Shader Code > HLSL Code in the Material Editor. Note that the HLSL Code tab is read-only. You cannot directly edit HLSL shader code within the Unreal Editor.

Materials Workflow Overview

This section provides a high-level overview of the Material creation process in Unreal Engine.

This is not a comprehensive step-by-step guide, but a broad conceptual overview. Read the pages in the Material Editor User Guide for detailed information about working in the Material Editor.

Creating a New Material

Materials in Unreal Engine are an asset class just like Static Meshes, Textures, or Blueprints. You can create new Materials from the Content Browser.

Right-click in the Content Browser

Select Material in the Create Basic Asset setion of the context menu.



A Material is created in the Content Browser. Give it a unique and descriptive name.



Double-click the Material asset to begin editing the Material. The Material Editor window opens as shown below.



Click the image to enlarge.

The highlighted region is called the Material Graph, and this is where you will do the majority of your work while creating Materials. The Material Graph in a new Material is empty except for the Main Material Node, which contains all the inputs that dicate the appearance and behavior of the Material.

For a detailed breakdown of the Material Editor UI, read here.

Material Properties

When the Main Material Node is selected, the global Material properties and settings display in the Details panel. You can also display the Material properties by clicking any empty space in the Material Graph.

Three of these settings are particularly important at the beginning of the Material creation process, as they form the underlying foundation of a Material and dictate how it can be used.



Material Domain – Defines what the Material will be used for in your project. For example, Surface, User Interface, and Post-process Materials are different Material Domains.

Blend Mode – Defines how the Material blends with the pixels behind it. For example, Opaque shaders completely occlude objects behind them, whereas Translucent and Additive shaders blend with the background in some way.

Shading Model – Defines how the Material interacts with light. Very often your Materials will simply use the Default Lit shading model. However, Unreal Engine includes specific Shading models for things like Hair, Cloth, and Skin which provide context-specific inputs to make it easier to create those types of surfaces.

These properties determine exactly which inputs are enabled on the Main Material Node. In the image above, Opacity is grayed out because the Opaque blend mode does not support transparency.

If you select the Translucent Blend Mode, the Opacity input is enabled, and several inputs that were previously enabled are grayed out.



When you create a new Material, it is recommended that you configure these three properties first.

Read the Material Properties documentation for information about the rest of the properties in the Details panel.

Material Expression Nodes

If Material properties are the foundation, Material Expressions are the building blocks of a Material.



Each Material Expression performs a specific action in the Material Graph. Technically, a Material Expression is simply a visual representation of a snippet of HLSL code. When you combine Material Expressions you are writing an HLSL shader without ever seeing the code itself.

Data is passed between Material Expressions by dragging a cable connection from the output pin of one node to an input pin of another.



Simple surfaces might only require a few Material Expressions to define the Material, as below where the three texture samples carry most of the weight. The only other nodes in this graph are there to give artists finer control over the Roughness strength.



This could be a finished Material, or you could continue refining the surface using math and logic in the Material Graph. Understanding how to combine Material expressions to achieve specific results in your Materials is the basis of Material Creation in Unreal.

Read here to learn how to place Material Expressions in your graph.

Unreal Engine includes dozens of Material Expression nodes. Most of them have mouseover tooltips, but you can read the Material Expressions Reference pages to learn what each node is used for.

Material Expression Properties and Values

Each Material Expression has a set of properties and values you can view and modify in the Details Panel when the node is selected. In some cases these values are also editable directly on the node itself in the Material Graph.

Material Expression properties generally fall into a few categories.

These values reflect the data stored by the node or used in the operation performed by the Material Expression. Examples include the values defined by Constant Material Expressions, or the arithmetic operators in Math Material Expressions. You can set these values in the Details Panel, inline on the node itself, or by passing data into the input pins on the node.



Values set in the Details Panel or inline are automatically overidden if data is passed into the input pin associated with that property.



The Multiply node on the left performs the operation 1 * 2 and outputs a value of 2.

When Constants are plugged into that same Multiply node, the values connected to inputs A and B supercede the values in the Details Panel. This node performs the operation 2 * 3 and outputs a value of 6.

Material Expression properties also include toggles and dropdown menus to enable or disable features of that node or alter the way the node functions. For example, the View Property node has a dropdown selector to choose which View Property is output by the node. Similarly, the Component Mask node has a set of toggles that determine which data is allowed to pass through the outputs.



In some cases nodes will contain variables that enable you to reference the data in that Material Expression elsewhere, such as in Blueprint or code. Parameter names, Sort Priority, and Custom Primitive Data Index are examples of this kind of property. These values are usually integers or text strings.

Inline Editing of Values and Properties

Many of the most commonly used Material Expressions include the ability to edit constant values and properties on the node itself in the Material graph. For these expressions, you no longer need to select the node and edit values in the Details Panel, but can modify values using input fields on the node itself.



Click image to enlarge.

Some Material Expressions have inline properties that are not visible by default. You can click the dropdown caret at the bottom of a Material Expression to expand the node and display additional properties.

The Main Material Node

Data flows from left to right in the Material Graph, and the Main Material Node is the end-point of every Material network.

The Main Material Node contains the final input pins that determine what information is compiled with the Material. Material Expressions in your graph do not affect the Material unless they are part of a chain that connects to the Main Material Node.

In the video above, notice that the Material preview only updates once the Texture Samples are connected to their corresponding inputs on the Main Material Node.

Every input on the Main Material node defines a specific aspect of the overall Material. These two pages will help you understand what each input is used for:

Physically Based Materials – Explains the principles and best practices of a Unreal's Physically Based Materials workflow.

Material Inputs – Explains what each input on the Main Material Node does.

Compile and Apply

Changes to a Material cannot be seen in the level until the Material is compiled. To compile a Material, click the Apply or Save button in the toolbar at the top of the Material Editor.



After compilation, you can drag a Material directly from the Content Browser onto any Actor in your level.



Compilation can take a few seconds, or up to several minutes for complex Materials. This can potentially bottleneck your efforts when developing and testing Materials, but there are several ways to minimize compilation delays.

Material Instancing is one strategy to improve iteration time and avoid lengthy compilation delays while you work. Read more about instancing below.

Material Editor User Guide

The procedure outlined above covers the basic Materials workflow in Unreal Engine. Each one of the steps discussed above is documented more comprehensively in the Material Editor User Guide.

It is recommended you read these pages to get started with Material creation:

Material Editor User Interface

Placing Material Expressions and Functions

Using the Main Material Node

Previewing and Applying Materials

Organizing a Material Graph

Workflow Efficiency Concepts

The Materials you create are very rarely single-use assets. Authoring an entirely new Material for every Actor in your project is inefficient, particularly because similar assets tend to require very similar Materials.

Material Instances and Material Functions make it easier to customize and reuse Materials so that you can iterate faster and avoid doing the same work twice.

Material Instances and Parameterization

Material Instances provide a way to quickly create multiple variations, or instances, from a single parent Material.

Instances are used when a group of related assets require the same basic Material, but with different superficial characteristics. An example might be a piece of furniture that has several color variations.



Material Instancing lets you create a single parent Material for the furniture set. You would then create a Material Instance for each color, as shown above on the chairs.

There are several advantages gained from using instances:

You can customize Material Instances without recompiling the parent Material. This means changes you make to instances are visible immediately, in all viewports.

You can expose parameters to artists in the Material Instance Editor. This means they can quickly and intuitively create variations of a Material without ever editing the more complicated node graph.

Read the Material instances learning track here.

Material Functions

Material Functions enable you to package parts of a Material graph into a reusable asset that you can share to a common library and easily insert into other Materials.

Their purpose is to streamline Material creation by giving instant access to commonly used networks of Material nodes.

For example, the Blend_Overlay function shown below contains the entire Material expression network shown on the right side of the image. Instead of constructing this node network over and over, you can insert it directly into your graph from the function library.



The Unreal Editor includes several dozen premade Material Functions. You can edit any Material Function to alter its behavior or create your own functions directly in the editor.

Read more about creating and using Material Functions here.

Working with Color and Data

Unreal Engine uses the RGBA color model, meaning every pixel is defined by four values which represent the Red, Green, Blue, and Alpha channels.

For example, RGBA values of (0.0, 0.0, 1.0, 1.0) describe a pixel that is pure blue and fully opaque. In the Material Editor, a set of four values like this is called a float4, because it stores four floating-point values.

All the information that travels through a Material Graph is represented by floating-point values, but values are not always stored in sets of four as in the example above. There are four data types in the Material Editor:

Data Type

Definition

Example

Float

Stores a single floating-point value

(1.0)

Float2

Stores two floating-point values

(1.5, 2.0)

Float3

Stores three floating-point values

(0.0, 1.0, 3.5)

Float4

Stores four floating-point values

(0.5, 1.0, 0.2, 0.9)

Nodes and input pins in the Material Editor are generally designed to accept a specific kind of data. For example, many Material Expressions that perform per-channel operations will only work when the correct data type is passed into their inputs.

Because of this, it is crucially important to understand the four data types listed above, and know the techniques and strategies you can use to manipulate data and control the way information flows through your graph. The two pages linked below are strongly recommended as you continue your introduction to Unreal Engine Material creation.

Material Data Types

Data Flow and Arithmetic

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Float Data Types

Float

Constant Material Expression

Scalar Parameter

Examples

Float2

Constant2Vector

Float3

Constant3Vector

Parameterizing a Constant3Vector

Float4

Constant4Vector

Vector Parameter

Further Reading

Understanding how data is represented and manipulated in the Material Editor is one of the principle concepts in Unreal Engine Material creation. The inputs on the Main Material Node, which define the physical attributes of a Material, are each programmed to accept a specific type of data. Similarly, many of the Material Expression nodes used to build Materials will fail to compile unless they receive a specific kind of data on their inputs.

This page provides an overview of the four data types available in the Material Editor and examples of how they are frequently used.

Float Data Types

In computer graphics, a float is a data type that stores a single numeric value, positive or negative. Float is short for floating-point, which means the number contains a decimal place and does not need to be a whole number (or integer). Examples of float values might include 1.0, -0.5, or 2.0.

Ultimately all the data types in the Material Editor are variations of the float variable. Where they differ is in the quantity of values they store. Whereas a float represents a single number, a float2 stores two discrete floating-point values. For example: (1.0, 0.5).

The following table breaks down the four data types available in the Material Editor.

Data Type

Material Expression(s)

Data Structure

Common Uses

Float

Constant, Scalar Parameter

(r)

Metallic, Roughness, arithmetic operations

Float2

Constant2Vector

(r, g)

UV or XY coordinates, Scale

Float3

Constant3Vector

(r, g, b)

Color (r, g, b) or 3D coordinates (x, y, z)

Float4

Constant4Vector, Vector Parameter, Textures

(r, g, b, a)

Color with alpha channel, Textures (r, g, b, a)

Float

As described above, a float stores a single floating-point value. It can be positive or negative and contains a decimal place. There are two Material Expressions you can use to define a float.

A Constant Material Expression node stores a single constant float value. Because it is a constant, this value does not change after the Material is compiled. The image below shows a Constant node which holds a value of 1.0.



A Scalar Parameter also stores a float. Unlike a Constant, the Scalar Parameter also becomes a named variable that you can modify in a Material Instance after the Material is compiled, or even at runtime. The image below shows a Scalar Parameter with a name of Roughness, and a default value of 0.6. You could use this to define the Material's roughness attribute, while providing artists a way to override the value in a Material instance.



For more information about when and how to use Scalar Parameters instead of Constants, read the Instanced Materials documentation.

Certain inputs on the Main Material Node are defined by a float. For example, the Metallic, Specular, and Roughness inputs all accept a float value between 0 and 1. Therefore, you can pass a Constant Material Expression or Scalar Parameter directly into the Main Material Node to define these attributes.



Constants and Scalar Parameters are often used to control the magnitude of some effect. Below, a Scalar Parameter named Emissive Power is multiplied by a solid color and passed into the Emissive Color input. Changing the value in the Emissive Power parameter makes the emissive output brighter or dimmer.



Float2

A Float2 stores two numeric values. For example: (2.0, 3.0).

In the Material Editor, the Constant2Vector Material Expression is used to define a float2. Below, a Constant2Vector is shown with values of 2.0 and 3.0 in each of its two channels.



The Constant2Vector is useful anytime you need to define or modify an attribute that requires two-channel data. In the details panel, the two values are labeled R and G, referring to the red and green channels in rgb color, but that is only one possible use. Coordinates (UV, XY) and scale (width, height) are other attributes you could define with a Constant2Vector.

In the example below, a Constant2Vector is added to a Texture Coordinates node to modify the position of the texture on a plane. In the first slide, the values in the Constant2Vector are (0, 0), so the texture position is unchanged.

The values in the Constant2Vector control the texture position.



When the R value is changed to 0.5, the texture shifts along the horizontal axis, because it is being added to the U coordinate of the texture. This causes the texture to wrap around the left and right edges of the plane. When the G value is changed to 0.5, the texture shifts vertically. The center of the texture is now at the four corners of the plane.

Float3

A float3 stores three numeric values. In the Material Editor, the Constant3Vector node defines a float3.



In Unreal Engine, the color of a pixel is defined by three values representing the red, green, and blue color channels. Therefore, one common use for a float3 is to define a solid color.

If you double-click a Constant3Vector node, a color picker dialog appears, letting you select a color with the wheel or eyedropper tool. The color picker also provides fields to enter RGB, HSV, or Hex values if you need to create a specific color. You can also launch the color picker by clicking the color swatch in the details panel.



A second use case for a float3 is to define (x, y, z) coordinates. For example, the World Position Offset input accepts three values, which define how many units the Material is offset on the x, y, and z axes in world space.

In the four slides below, the values in a Constant3Vector are each changed to 800. You can see how the position of the sphere changes, first on the x-axis, then the y-axis, then on the z-axis in the third slide.

World Position Offset takes three values, to offset the Material along the x, y, and z axes.



You can parameterize a Constant3Vector by right-clicking it and choosing Convert to Parameter from the context menu. This converts the node into a Vector Parameter. The Vector Parameter node actually stores four values (r, g, b, a), making it a float4.

However, any input that requires a float3 will simply use the first three values and discard the fourth. For example, the Base Color input accepts a float3. If you connect a Vector Parameter to Base Color, it will use the R, G, and B channels and discard the fourth value (the alpha channel). Because Unreal Engine knows which channel to discard, you can safely use a Vector Parameter when you need to parameterize a float3, even though the node is technically a float4.

Float4

A float4 stores four floating-point values. For example: (50.0, 0.0, 100.0, 0.5). There are two Material Expressions commonly used to define a float4.

The Constant4Vector stores four constant values. The Constant4Vector is most often used to represent RGBA color, that is color with an alpha channel. Like the Constant3Vector, you can double-click the node or click the swatch in the details panel to access a color picker.



A Vector Parameter is a parameterized float4. You can create a Vector Parameter directly from the palette, or can. The most common use for a Vector Parameter is to create color parameters in a Material that artists can easily override in Material Instances. For example, multiplying a Vector Parameter on top of a texture is one way to add a tint control to some aspect of a Material (Base Color and Emissive, for example).



In addition to its utility in a parameterized Material workflow, Vector Parameter has an additional advantage. Unlike any prior examples on this page, each individual data channel within a Vector Parameter is accessible through the five output pins on the right side of the node. As labeled above, these are:

RGBA - Outputs all the values in the float4. In the example above: (0.0, 1.0, 0.5, 0.0).

R — Outputs the value in the R channel only.

G — Outputs the value in the G channel only.

B — Outputs the value in the B channel only.

A — Outputs the value in the A channel only.

This emphasizes an important aspect of Material creation. Ultimately the information that flows through a Material graph is just floating-point values packaged and represented in different ways. Even though the channels of a Vector Parameter are labeled RGBA in the Details panel, it does not mean they need to be used that way in your Material.

Beyond representing color, you could use a Vector Parameter to parameterize four discrete but related values. One such use of the node is in the Megascans parent Material, where a Vector Parameter is used to parameterize the UV tiling and offset of the Material.



Notice that the RGBA channels were renamed in this example to Tiling X, Tiling Y, Offset X, and Offset Y. You can rename the channels of a Vector Parameter in the Details panel under Parameter Customization > Channel Names. These names are visible in the Material Instance Editor when an artist overrides parameter values.

Read more about the Vector Parameter node here, and learn more about Material parameterization on these pages.

Further Reading

The four data types introduced on this page form the basis of all information that travels through a Material Graph. It is important to understand that data types are not necessarily immutable. For example, you can combine two floats to form a float2. Similarly, you can extract or isolate a single float from a larger data type.

Continue reading about manipulating data types and rules for performing arithmetic in a Material graph here: Material Data Manipulation and Arithmetic.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Manipulating Data Types

AppendVector

AppendMany

Component Mask

Material Graph Arithmetic

Compatible and Incompatible Data Types

Arithmetic Rules Between Data Types

Conclusion

The Material Data Types page introduced the four ways data is represented in the Material Editor. To create Materials effectively it is necessary not only to know these data types, but also how to manipulate data and control the way information travels through your Material Graph.

Two topics are discussed in this document.

Manipulating data types: How to combine floats into a multi-channel vector, and conversely, how to isolate information out of a larger data type.

Material Graph arithmetic: Rules and processes for performing arithmetic operations in a Material with different data types.

Manipulating Data Types

Just because a piece of information originates as one data type does not mean it needs to stay that way. For example, you can combine or Append two Scalar Parameters (floats) into a two-channel vector (float2) in order to pass them into an input that requires two-channel data. Conversely, you can use a ComponentMask to retrieve a specific subset of channels out of a larger vector.

The Material Expressions documented in this section provide ways to combine and separate data to control the way information flows through your Material Graph.

AppendVector

An AppendVector Material Expression combines the data in Input A with the data in Input B*, and outputs a multi-channel vector (float2, float3, or float4). In this example, two Constants are appended together to output a float2: (1, 2)**.



The Append node is often useful when you want the ability to modify two values independently of one another, but need to pass them into an input that requires multi-channel data. The graph below gives artists a way to control the Tiling or UV scale of a texture in a Material Instance, but only uniformly.



The shortcoming in this example is that the Material Graph only contains one parameter, but UV Coordinates have two channels. With this solution you cannot control the width and height of the texture independently.

You can solve this by using an AppendVector. Create a separate Scalar Parameter for each axis and then pass them into the Append node. The Append node combines the two parameters into a float2, which is then multiplied by the Texture Coordinates.



Since Tiling X and Tiling Y are parameterized separately, you can now control the width and height of the texture independently.

The AppendVector expression combines data in the order it is attached to the node. The data in Input B is always appended to the end of the data in Input A. Consider the two images below.



In the first slide, the appended result is (0.05, 0.2, 0.8), or light blue as the node preview shows.

In the second slide, the appended result is (0.8, 0.05, 0.2), or pink as the node preview shows.

AppendMany

AppendMany is a Material Function that works the same way as the AppendVector expression, but can combine up to four separate float/scalar values into a multi-channel vector.



One added benefit of the AppendMany function is that it provides three different output pins. This gives you access to some or all of the appended channels, depending on what you need for a given situation.

The AppendMany node only accepts float/scalar values on its inputs. If you pass a float2, float3, or float4 into the AppendMany node, all but the first value is discarded.

Component Mask

The Component Mask Material Expression serves the opposite purpose to the Append nodes documented above. Instead of combining data, a ComponentMask provides a way to separate data into its component parts or channels.

A Component Mask functions like a gate. For any data connected to its input, you can choose exactly which channels are allowed to pass through the output. The image below shows a Constant4Vector containing values of (0, 1, 0.7, 0.5). When you select the Mask node in the graph, four check-boxes are displayed in the Details Panel.



These check-boxes determine which channels the node will output. Currently none are checked, so the Mask node will not output any information. If you attempt to plug it into a downstream input, the node will display an error.



These checkboxes give you a way to filter out information and only use the channels that you need.

Suppose you wanted to use the value in the A channel to control the opacity of a Material. You would enable the A channel by checking the box, then connect the output pin of the Mask to the Opacity Input.



The ComponentMask discards the R, G, and B channels because they are unchecked, and outputs only the value in the A channel — in this case 0.5.

Material Graph Arithmetic

The second main way of manipulating data in a Material Graph is through mathematical operations. All common arithmetic operations are available in the Material Editor.



The four arithmetic Material Expressions. Read more on the Math Material Expressions page.

The basic purpose of the arithmetic nodes should be relatively self-evident. For example, if you plug constant values of 0.3 and 0.2 into an Add node, the Add node calculates 0.3 + 0.2 and outputs a value of 0.5. Arithmetic between two constant values is simple and straightforward.



However, as demonstrated on the data types page, information does not always travel through the Material Graph as individual float values. Because of this, it is important to understand the rules and processes for performing arithmetic between various data types in a Material. There are two major areas of concern.

Not all data types are compatible with one another for arithmetic operations.

Arithmetic operations work differently depending on the data types involved.

Compatible and Incompatible Data Types

The example above showed a simple addition operation between two float values, or 0.3 + 0.2 = 0.5. This operation works because both values are the same kind of data. What happens if a different data type is passed into one of the inputs? These three points summarize compatibility between data types:

Arithmetic between equivalent data types is always valid. For example, float2 + float2 returns a new float2.

Arithmetic between a float and any larger float is valid. For example, float + float3 returns a new float3.

Arithmetic between two inequivalent data types is invalid. For example, float2 + float3 is invalid and returns an error.

In other words, arithmetic across two different data types is possible, but only if one of the data types is a float. In the graph below, the operation 0.3 + (1,2) is valid. The float is added to both values in the float2, and the result is a new float2 with values of 1.3, 2.3).



However, arithmetic between inequivalent float2, float3, or float4 data returns an error.



The table below summarizes data type compatibility for Material Graph arithmetic.

Data Type

Compatible Data Types for Arithmetic

Float

Any

Float2

Float, Float2

Float3

Float, Float3

Float4

Float, Float4

Arithmetic Rules Between Data Types

It's also necessary to understand how arithmetic calculations are performed between different data types. The two scenarios below demonstrate how arithmetic works when one or both of the data types are larger than a float.

When arithmetic occurs between equivalent data types (float2 + float2 for example) each value in Input A is operated on by the corresponding value in Input B. The example below shows addition between two Constant2Vector Expressions.



Written out in long form, there are two separate addition operations. The first values in each node are added together: (1 + 2). Then the second values in each node are added (3 + 3). The result is a new float2: (2, 6).

The chart below shows an arithmetic example for each of the four data types.

Input A, Input B

Input Data

Math Notation

Resulting Data

Float, Float

(4) / (2)

4 / 2 = 2

8

Float2, Float2

(1, 3) + (2, 3)

(1 + 2), (3 + 3)

(3, 6)

Float3, Float3

(3, 2, 0.5) * (2, 1, 2)

(3 x 2), (2 x 1), (0.5 x 2)

(6, 2, 1)

Float4, Float4

(2, 2, 2, 3) - (1, 1, 2, 2,)

(2 - 1), (2 - 1), (2 - 2), (3 - 2)

(1, 1, 0, 1)

When arithmetic occurs between a float and any larger data type, the float is used repeatedly for each separate calculation. In the image below a Constant and a Constant3Vector are multiplied together.



As shown in the illustration, the value in the Constant is multiplied by each value in the Constant3Vector. There are three separate multiplication expressions: (2 3), (2 1), and (2 *2). The product is a float3: (6, 2, 4).

Whether the float is in Input A or Input B has no bearing on multiplication and addition, but of course matters for division and subtraction.



In the image above, the value in the Constant (2) is subtracted from each value in the Constant3Vector (6, 4, 3). Written out in math notation: (6 - 2), (4 - 2), (3 - 2). The resulting float3 is (4, 2, 1).

If you were to reverse the input order, the results would be different.



Since the float is now the top number in the subtraction node, each arithmetic operation is inverted: (2 - 6), (2 - 4), (2 - 3). The resulting float3 is (-4, -2, -1).

Conclusion

The concepts and techniques on this page are a key component in most of the Material Graph logic you will use to create Materials. The reference pages linked below can help you increase your understanding of math and data manipulation operations in the Material Editor.

Math Material Expressions

Vector Operation Expressions

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

What Does Physically Based Mean?

PBR Material Attributes

Base Color

Roughness

Metallic

Specular

Cavity Maps

References



This document is designed to provide guidelines and best practices for working within Unreal Engine's physically based Materials system. It assumes that you have some familiarity with the Material creation process in Unreal. If you are completely new to Materials in Unreal, you may prefer to start with the Essential Material Concepts page.

This page focuses only on the Material attributes that are directly related to the physically based shading workflow. For a complete breakdown of all inputs on the Main Material node, see the Material Inputs page.

What Does Physically Based Mean?

Physically based rendering (PBR) means that surfaces approximate the way light behaves in the real world, as opposed to the way we intuitively think it should. Materials that adhere to PBR principles are more accurate and typically more natural looking than a shading workflow that relies fully on artist intuition to set parameters.

Physically based Materials work equally well in all lighting environments. In addition, Material values can be less complex and interdependent, resulting in a more user-friendly Material creation workflow. These benefits are applicable even for non-photorealistic rendering, as evident in films from Pixar [4] and Disney [3].

For an in depth technical look at Unreal Engine's physically based Material and shading model, refer to this SIGGRAPH presentation 2.

PBR Material Attributes

These are the Material attributes that are directly related to the physically based aspect of Unreal Materials.

Base Color

Roughness

Metallic

Specular

All of these inputs are designed to accept values between 0 and 1. In the case of Base Color this means a color or texture sample with RGB values that fall between 0 and 1.

Physically based values can be measured from real world Materials. Some examples are given below.

Base Color

Base Color defines the overall color of the Material. The Base Color input accepts a Vector3 (RGB) value where each channel is automatically clamped between 0 and 1.



If taken from the real world, this is the color when photographed using a polarizing filter (polarization removes the specular of nonmetals when aligned).

Measured BaseColor values for nonmetals (intensity only):

Material

BaseColor Intensity

Charcoal

0.02

Fresh asphalt

0.02

Worn asphalt

0.08

Bare soil

0.13

Green grass

0.21

Desert sand

0.36

Fresh concrete

0.51

Ocean Ice

0.56

Fresh snow

0.81

Measured BaseColors for metals:

Material

BaseColor (R, G, B)

Iron

(0.560, 0.570, 0.580)

Silver

(0.972, 0.960, 0.915)

Aluminum

(0.913, 0.921, 0.925)

Gold

(1.000, 0.766, 0.336)

Copper

(0.955, 0.637, 0.538)

Chromium

(0.550, 0.556, 0.554)

Nickel

(0.660, 0.609, 0.526)

Titanium

(0.542, 0.497, 0.449)

Cobalt

(0.662, 0.655, 0.634)

Platinum

(0.672, 0.637, 0.585)

Roughness

The Roughness input controls how rough or smooth a Material's surface is. In the Material this manifests as how sharp or blurry reflections appear on the Material.

Rough Materials scatter reflected light in more directions than smooth Materials, which results in diffuse, sometimes subtle reflections. Smooth surfaces reflect light more uniformly, resulting in clear, focused reflections or specular highlights.

A Roughness of 0 (smooth) results in a mirror reflection.

A Roughness of 1 (rough) results in a diffuse or matte surface.



Roughness values from 0 to 1. Nonmetal top, metal bottom.

Roughness values from 0 to 1.



Roughness is frequently mapped on objects using a grayscale texture to add physical variation to a surface. Dark areas on a roughness map appear mirrorlike on the Material, while light areas are rough and appear less reflective.

The video below shows the Roughness value increasing from 0 to 1, with a perlin texture controlling the distribution of light (rough) and dark (smooth) values. At 0, the Material preview is completely mirrorlike. At 1, the Material is perfectly matte. In-between values are more interesting, as parts of the surface appear smooth and parts appear rough.

Roughness maps are frequently used to add scruffs, smudges, or other imperfections to Materials like plastic and metal.

The interplay between roughness and specular is an important point to understand, particularly if you were working in Unreal Engine before the PBR workflow was adopted.

Specularity refers to the amount of specular light reflected by a surface. This value is inherent to the Material type, and usually the default value of 0.5 is accurate. The Specular input is not used for reflection/specularity maps or to add surface variation. These should be handled in the Roughness map.

Metallic

The Metallic input accepts a value between 0 and 1, and defines whether your Material behaves as a metal or nonmetal.

In most cases, you should treat Metallic as a binary property in Unreal Engine. For pure surfaces, such as pure metal, pure stone, pure plastic, and so on, you should set Metallic to either 0 or 1, not anything in between. When creating hybrid surfaces like corroded, dusty, or rusty metals, you may find that you need some value between 0 and 1.

Nonmetals have a Metallic value of 0. This is the default value.

Metals have a Metallic value of 1.



Metallic values 0 to 1.

You may be reluctant at first to make any Material completely metallic. Resist the impulse to use partial values unless you have a good reason.

This example shows how a surface changes when Metallic is increased from 0 to 1 on a Material with relatively low Roughness.

Metallic values from 0 to 1.



Metals and nonmetals are often present in the same Material. Consider a metal panel, with a coat of paint covering some or all of the metal.

Paint is a nonmetal, so the Metallic value should be 0 in any regions covered by paint. Anywhere the metal panel is visible, the Metalic value should be 1.

This should be handled with a black and white mask passed into the Metallic input. Paint does not blend with metal, it sits on top of it. Your Metallic map should not contain intermediate grayscale values, only black and white. You could also use Material Layers to achieve similar results.

Specular

The Specular input takes a value between 0 and 1, and controls how much specular light the surface reflects.

A Specular value of 0 is fully non-reflective.

A Specular value of 1 is fully reflective.

Unreal Engine uses a default Specular of 0.5, which represents approximately 4% specular reflection. This value is accurate for a vast majority of materials.

For very diffuse Materials, you may be inclined to set this to zero. Resist! All Materials have specular, see this post for examples [5].. The correct way to make very diffuse Materials is to use a high Roughness value.

Cavity Maps

One reason to modify Specular is to add micro occlusion or small scale shadowing, say from cracks represented in the normal map. These are sometimes referred to as cavities. Small scale geometry, especially details only present in the high poly and baked into the normal map, will not be picked up by the renderer's real-time shadows.

To capture this shadowing, you can generate a cavity map, which is typically an AO map with very short trace distance. This is multiplied by the final BaseColor before output and multiplied with 0.5 (Specular default) as the Specular output.

To be clear this is BaseColor = Cavity*OldBaseColor, Specular = Cavity*0.5.

For advanced use, this can be used to control the index of refraction (IOR). We have not found this to be necessary for 99% of Materials. Below are Specular values based off of measured IOR.

Measured Specular Values:

Material

Specular

Glass

0.5

Plastic

0.5

Quartz

0.570

Ice

0.224

Water

0.255

Milk

0.277

Skin

0.35

Specular values from 0 to 1





Example measured Materials. Top: Charcoal, fresh concrete, worn asphalt. Bottom: Copper, iron, gold, aluminum, silver, nickel, titanium

References

1. Lagarde, Feeding a physically based shading model

2. Karis, Real Shading in Unreal Engine 4

3. Burley, Physically-Based Shading at Disney

4. Smits, Reflection Model Design for WALL-E and Up

5. Hable, Everything is Shiny

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Physical Material

Material

Physical Material Mask

Translucency

Translucency Self Shadowing

Usage

Mobile

Forward Shading

Post Process Material

Refraction

Lightmass

Previewing

Import Settings

This document breaks down the properties available on a Material. These properties are displayed in the Details panel of the Material Editor when the Main Material Node is selected.

Material properties include:



Physical Material

Material Properties

Physical Material Mask

Translucency and Translucency Self Shadowing

Usage Flags

Mobile

Forward Shading

Group Sorting

Post Process Material

Refraction

Lightmass Settings

Previewing

Import Settings

The properties listed above determine how what a Material can and cannot do, how it interacts with light and blends with the pixels behind it.. These properties are described below, presented in the order in which they appear in the Details panel.

Physical Material



Property

Description

Phys Material

The Physical Material associated with this Material. Physical Materials provide a definition of physics properties, such as how much energy is retained on collision (bounciness) and other physics-based aspects. A Physics Material has no influence over how a Material appears visually.

Phys Material Mask

A physical Material mask used for this graphics Material. Used for sounds, effects, and more.

Material



Property

Description

Material Domain

Material Domain allows you to define how you will use the Material. Certain Material uses (such as decals) require additional instructions for the render engine to consider. Because of this, it is important to set the Material Domain accurately, particularly when the Material is intended for something other than a surface. Material Domain includes the following options:

Domain

Description

Surface

This setting defines the Material as something that will be used on an object's surface. Think metal, plastic, skin, or any physical surface. This is the default setting, and the one you will use most of the time.

Deferred Decal

When making a Decal Material, you will use this setting.

Light Function

Used when creating a Material for use with a Light Function.

Volume

Used when describing the Material's attributes as a 3D volume.

Post Process

Select this option when creating a Post Process Material.

User Interface

Select this option when creating Materials for a UMG or Slate user interface.

Virtual Texture

Used when making a Runtime Virtual Texture.

Blend Mode

Blend Modes describe how the output of the current Material will blend over what is already being drawn in the background. Put more technically, it allows you to control how the engine will combine this Material (Source color) with what is already in the frame buffer (Destination color) when rendered. The available blending modes are:

Mode

Description

BLEND_Opaque

Final color = Source color. This means that the Material will draw on top of the background. This blend mode is compatible with lighting.

BLEND_Masked

Final color = Source color if OpacityMask > OpacityMaskClipValue, otherwise the pixel is discarded. This blend mode is compatible with lighting.

BLEND_Translucent

Final color = Source color Opacity + Dest color (1 - Opacity). This blend mode is NOT compatible with dynamic lighting.

BLEND_Additive

Final color = Source color + Dest color. This blend mode is NOT compatible with dynamic lighting.

BLEND_Modulate

Final color = Source color x Dest color. This blend mode is NOT compatible with dynamic lighting, or fog, unless this is a decal material.

AlphaComposite

Used for Materials with textures that have premultiplied alpha. That is, the color channel has already been multiplied by the alpha so when blending with the frame buffer, the GPU can skip the (SrcAlpha * SrcColor) arithmetic that is typically used with alpha blending. Can improve the visual appearance of additive blending.

AlphaHoldout

Lets you "hold out" the alpha of a Material, punching a hole through Translucent objects directly behind it in view space.

For more information on these Blend Modes, read the Blend Modes documentation.

Shading Model

Shading Models determine how Material inputs (e.g. Emissive, Diffuse, Specular, Normal) are combined to make the final color.

Model

Description

Unlit

The Material is defined by the Emissive and Opacity inputs only. It does not respond to light.

Default Lit

The default shading model. Perfect for most solid objects.

Subsurface

Used for subsurface scattering Materials, such as wax and ice. Activates the Subsurface Color input.

Preintegrated Skin

Used for Materials similar to human skin. Activates the Subsurface Color input.

Clear Coat

Used for Materials that have a translucent coating on top like clear coat car paint or lacquer. Activates the Clear Coat and Clear Coat Roughness inputs.

Subsurface Profile

Used for Materials similar to human skin. Requires the use of a Subsurface Profile in order to work correctly.

Two Sided Foliage

Used for Materials that create natural looking foliage with accurate lighting and light transmission through surfaces, such as throug leaves on a tree.

Hair

Used for Materials that create realistic looking hair that accurately lights the hair shafts and handles speular highlight.

Cloth

Used for Materials that need to create realistic looking cloth and fuzz along its surface.

Eye

Used for Materials that recreate the natural look of humanoid eyes.

Single Layer Water

Eenables you to achieve the effect of a transparent water surface while using an Opaque Blend Mode. This reduces the cost and complexity of using Materials that require the Transparent Blend Mode.

Thin Translucent

Used for Materials that create physically based glass, such as colored or tinted glass. It properly handles white specular from light sources and tinted background objects.

From Material Expression

Used for handling multiple shading models in a single material.

For more information on these Shading Models, read the Shading Model documentation.

Two Sided

When Two Sided is enabled, the normal is flipped on back faces, which means lighting is calculated for both the front faces and the back faces. This is commonly used on foliage to keep from having to double up the number of polygons. Two Sided does not work correctly with static lighting, since the mesh still uses only a single UV set for light mapping. As a result, two sided Materials with static lighting are shaded the same on both sides.

Use Material Attributes

This checkbox causes the Material's primary node to be condensed down to a single input labeled "Material Attributes." This is useful when you need to blend multiple Materials using Layered Materials, or when defining multiple Material types using a Make Material Attributes expression node. See the Layered Materials[LINK NEEDED] documentation for more information.

Cast Ray Traced Shadows

This checkbox enables this Material to cast ray traced shadows when Ray Tracing features are enabled in the Project Settings.

Subsurface Profile

This allows you to change what Subsurface Profile is used in the Material.

Advanced Material Properties



Property

Description

Decal Response

This defines how the Material reacts on DBuffer decals(Affects look, performance, and texture/sample usage). Non DBuffer Decals can be disabled on the primitive(e.g. static mesh)

Cast Dynamic Shadow as Masked

Whether the Material should cast shadows as masked even though it has a translucent blend mode set.

Opacity Mask Clip Value

This is the reference value which the OpacityMask input of masked Materials will clip against per-pixel. Any value higher than OpacityMaskClipValue will pass and the pixel will be drawn (opaque), any value lower will fail and the pixel will be discarded (transparent).

Dithered LOD Transition

Whether meshes rendered with this material should support dithered LOD transitions.

Dither Opacity Mask

When combined with Temporal Anti-Aliasing, this can provide a form of limited translucency which supports all lighting features.

Allow Negative Emissive Color

Whether the Material should allow outputting negative emissive color values. This is only allowed on Unlit Materials.

Num Customized UVs

This sets the number of Customized UV inputs to display. Unconnected customized UV inputs will pass through the vertex UVs.

Generate Spherical Particle Normals

This produces surface normals that remain spherical as you rotate around a Particle System that uses this Material. This is useful for volumetric Particle Systems, since the sprites always rotate to face the camera. With this option, they will have a more spherical volume appearance.

Tangent Space Normal

Tangent space normals are calculated from the surface of the object, with the Z-Axis (blue) always pointing directly away from the surface. World space normals use the world coordinate system to calculate pixel angle, ignoring the surface's original orientation. Tangent space calculations are slightly more costly in terms of performance, but are generally more convenient, as these are usually the types of normal maps you can create in 2D applications such as Photoshop. Visually, tangent-space normal maps tend to look primarily blue-ish, while world-space maps are more vividly rainbow-colored.

Emissive (Dynamic Area Light)

If enabled, the Material's Emissive color is injected into the Light Propagation Volume.

Fully Rough

Forces the material to be completely rough. This saves a number of material instructions and one sampler.

Normal Curvature to Roughness

Reduces the roughness based on screen space normal changes.

Wire Frame

Enables a wire frame view of the mesh the Material is applied to.

Shading Rate

Select what shading rate to apply for platforms that have variable rate shading.

Is Sky

Unlit and Opaque blend modes used in materials can be used as a Sky Material on a sky dome mesh. When enabled, these meshes will not recieve any contribution from the aerial perspective. Height and Volumetric Fog effects are still applied.

Asset User Data

An array of user data stored with the asset.

Physical Material Mask



Property

Description

Physical Material Map

An array of Physical Material Maps for use with this Material. The mask slots are used to apply sounds, effects, or some other type of Physical Material to a desired color channel.

Translucency



Property

Description

Screen Space Reflections

Enabling this supports screen space reflections (SSR) on translucent Materials.

Contact Shadows

Enabling this supports contact shadows on translucent Materials.

Translucency Lighting Mode

This allows for control over the lighting mode used by Translucency within this Material. This is especially useful for Particle Systems that are making use of Translucency, such as self-shadowing smoke or steam.

Mode

Description

Volumetric NonDirectional

Lighting is calculated for a volume, without directionality. Use this on particle effects like smoke and dust. This is the cheapest lighting method, however, the material normal is not taken into account.

Volumetric Directional

Lighting is calculated for a volume, with directionality so that the normal of the material is taken into account. Note that the default particle tangent space is facing the camera, so enable bGenerateSphericalParticleNormals to get a more useful tangent space.

Volumetric PerVertex NonDirectional

Same as Volumetric NonDirectional, but lighting is only evaluated at vertices so the pixel shader cost is significantly less. Note that lighting still comes from a volume texture, so it is limited in range. Directional lights become unshadowed in the distance.

Volumetric PerVertex Directional

Same as Volumetric Directional, but lighting is only evaluated at vertices so the pixel shader cost is significantly less. Note that lighting still comes from a volume texture, so it is limited in range. Directional lights become unshadowed in the distance.

Surface Translucency Volume

Lighting is calculated for a surface. The light is accumulated in a volume so the result is blurry, limited distance but the per pixel cost is very low. Use this on translucent surfaces like glass and water. Only Diffuse lighting is supported.

Surface Forward Shading

Lighting is calculated for a surface. Use this on translucent surfaces like glass and water. This is implemented with forward shading so Specular highlights from local lights are supported, however, many deferred-only features are not. This is the most expensive translucency lighting method as each light's contribution is computed per-pixel.

See Lit Translucency for more information on translucency usage in your Materials.

Directional Light Intensity

Useful for artificially increasing the influence of the normal on the lighting result for translucency. A value lareger than 1 increases the influence of the normal, a value smaller than 1 makes the light more ambient.

Apply Fogging

When enabled, translucent Materials are fogged.

Compute Fog Per Pixel

When enabled, translucent Materials have fog computed for every pixel, which costs more but fixes artifacts due to low tessellation.

Output Velocity

When enabled, translucent Materials will output motion vectors in the velocity pass.

Advanced Translucency Properties



Property

Description

Render After DOF

Indicates that the Material should be rendered in the Separate Translucency Pass (not affected by DOF, and requires "AllowSeparateTranslucency" to be set in the .ini file).

Responsive AA (anti-aliasing)

Small moving objects, especially particles, can sometimes get obliterated by anti-aliasing. By setting this property to true, a different AA algorithm is used which provides more definition. Put another way, if you create a blizzard or similar particle system but cannot clearly see the snowflakes, this option should improve clarity. You should only use this option on small moving objects, because it creates aliasing artifacts on the background.

Mobile Separate Translucency

Enable this option to render the Material in the Separate Translucency Pass. This means that the Material is not affected by DOF and also requires you to set bAllowSeparateTranslucency in the .INI files).

Disable Depth Test

Allows the Material to disable depth tests, which is only meaningful with translucent blend modes. Disabling depth tests will make rendering significantly slower since no occluded pixels can get Z-culled.

Write Only Alpha

Whether the translucency pass should write its alpha, and only the alpha, into the framebuffer.

Allow Custom Depth Writes

Allows you to use a translucent Material with custom depth writing by compiling additional shaders.

Translucency Self Shadowing



Translucent self shadowing is a nice way to create a volumetrically lit translucent object, such as a pillar of smoke or steam. The self shadowing is broken into two primary parts: Self Shadow Density and Second Self Shadow Density. The two parts exist to allow for variations. You can define the density of each independently and use the difference between the two to get interesting patterns throughout the self shadow.

Property

Description

Shadow Density Scale

Sets the density of the shadow cast onto other surfaces by this translucent Material. This acts a bit like a master scale for shadowing; if set to 0, there is no shadowing whatsoever. As you increase the value to 1 and beyond, both the cast shadow and the self shadow will get darker.

Self Shadow Density Scale

Sets the density of the shadow this Material casts on itself. Consider shadows within a pillar of smoke.

Second Density Scale

This is a second self shadow density that can be set for variation. An internal gradient is created between this value and the Translucent Self Shadow Density Scale.

Second Opacity

This sets the opacity value for secondary self shadowing., serving as a way to scale the gradient effect between self shadow and second self shadow.

Backscattering Exponent

This controls the backscattering that is used when employing the Subsurface shading model along with Translucency. Larger values give a smaller, brighter backscattering highlight. This value is only used within volumetric translucent shadows formed from a directional light.

Multiple Scattering Extinction

This gives a colored extinction value for objects that have a volumetric translucent shadow, such as smoke or steam. This amounts to a tinited or colored shadow.

Start Offset

This is a world-space offset for the self shadow created within a translucent volume. The higher the number, the farther the shadow moves away from the lighting source.

Usage



The Usage flags tell the Engine what sort of surface you intend to apply the Material on. These settings allow the Engine to compile special versions for each application. These are only valid when using the Surface Material Domain setting.

In the editor, these flags are set automatically for any objects that already exist within your maps. For instance, if you have a Particle System that uses your Material placed somewhere in a level, when you load that map in the editor, it will automatically set the Used with Particle System flag. You must save the Material asset to allow the game to use the Material on that specific mesh.

If you do not have the appropriate usage flag set, the default world grid material will be used in-game instead. This will have an appropriate message in the log of the game client.

Property

Description

Used with Skeletal Mesh

Set this if the Material will be placed on a Skeletal Mesh.

Used with Editor Compositing

Set if the Material will be used with the Editor UI.

Used with Particle Sprites

Used if this Material will be placed on a Particle System.

Used with Beam Trails

Set if the Material will be used with Beam Trails.

Used with Mesh Particles

Indicates that the Material and its instances can be used with mesh particles. This will result in the shaders required to support mesh particles being compiled which will increase shader compile time and memory usage.

Used with Niagara Sprites

Set if the material will be used with Niagara Sprites.

Used with Niagara Ribbons

Set if the material will be used with Niagara Ribbons.

Used with Niagara Mesh Particles

Set if the material will be used with Niagara Mesh Particles.

Used with Geometry Cache

Set if the material will be used with Geometry Cache.

Used with Morph Targets

Set if this Material will be applied to a Skeletal Mesh that utilizes a Morph Target.

Used with Spline Meshes

Set if the Material will be applied to Landscape Spline meshes.

Used with Instanced Static Meshes

Set if the Material is intended to be applied to Instanced Static Meshes.

Used with Geometry Collections

Set if the material is intended to be used with geometry collections.

Used with Clothing

This should be set if the Material will be applied to Apex physically simulated clothing.

Used with Water

Used with materials that are intended to be used with Water mesh surfaces.

Used with Hair Strands

Used with materials that are intended to be used with hair grooms.

Used with Lidar Point Cloud

Used with materials that are intended to be used with Lidar Point Clouds.

Used with Landscape

Set if the Material will be used on a Landscape surface.

Used with UI

This indicates that this Material and any Material Instances can be used with Slate UI and UMG.

Automatically Set Usage in Editor

Whether to automatically set usage flags based on what the Material is applied to in the Editor. The default option for this is enabled.

Mobile



Property

Description

Use Full Precision

Forces this Material to use full (highp) precision in the pixel shader. It is slower than the default (mediump) but provides a workaround for precision-related rendering errors. This setting has no effect on older mobile devices that do not support high precision.

Use Lightmap Directionality

This will use lightmap directionality and per pixel normal's. If disabled, lighting from lightmaps is flat but cheaper.

Forward Shading



Property

Description

Preintegrated For Simple IBL

Forward (including mobile) renderer uses preintegrated GF LUT for simple IBL, but will use one more sampler.

High Quality Reflections

The forward renderer enables multiple parallax-corrected reflection captures that blend together. The Mobile forward renderer blends between the nearest three reflection captures, but reduces the number of samplers available to the Material as two more samplers are used for reflection cubemaps.

Planar Reflections

Enables planar reflection when using the forward renderer or on mobile. Enabling this setting reduces the number of samplers available to the Material as one additional sampler is used for planar reflection.

Post Process Material



Property

Description

Blendable Location

If this Material is used as a Post Process Material, this property allows you to control whether the Material is calculated before or after Tonemapping. This is important if your Material is used to modify the color of the Post Process.

Output Alpha

If enabled, the blendable will output alpha.

Blendable Priority

If multiple nodes with the same type are inserted at the same point, this defines the order and whether or not they get combined. Only used if Material domain is set to PostProcess.

Is Blendable

Allows blendability to be turned off. It is only used if the Material Domain is set to Post Process.



Advanced Properties



Enable Stencil Test

Selectively executes post process Material only for pixels that pass the stencil test against the Custom Depth/Stencil buffer. Pixels that fail the stencil test are filled with the previous post process Material output or scene color.

Stencil Compare

Use the dropdown to compare the stencil test.

Stencil Ref Value

Set a stencil reference value.

Refraction



Property

Description

Refraction Mode

This controls the type of refraction that will be employed by your Material.

Mode

Description

Index Of Refraction

Refraction is computed based on the camera vector entering a medium whose index of refraction is defined by the Refraction material input. The new medium's surface is defined by the Material's normal. With this mode, a flat plane seen from the side will have a constant refraction offset. This is a physical model of refraction but causes reading outside the scene color texture. so is a poor fit for large refractive surfaces, like water.

Pixel Normal Offset

The refraction offset into scene color is computed based on the difference between the per-pixel normal and the per-vertex nromal. With this mode, a material whose normal is the default (0,0,1) will never cause any refraction. This mode is only valid with tangent space normals. The refraction material input scales the offset, although a value of 1.0 maps to no refraction, and a value of 2 mapts to a scale of 1.0 on the offset. This is a non-physical model of refraction, but is useful on large refractive surfaces like water, since offsets have to stay small to avoid reading outside scene color.

Refraction Depth Bias

This property offsets the depth of the refraction test. This is useful when refraction values are causing unwanted nearby objects (typically in front of the translucent object) to render into the Material surface. Higher values will offset distortion to separate refractions. However, this causes a visible break between the surface and the refracted objects. This property is not enabled unless you have connected some expression node into the Refraction input.

Lightmass



Property

Description

Diffuse Boost

A multiplier for the amount of influence the diffuse component of the Material has on static lighting.

Export Resolution Scale

A multiplier for the resolution at which this Material's attributes are exported. This should be increased when details are needed.

Cast Shadow as Masked

If true, lit translucent objects will cast shadows as if they were using Masked lighting mode. This can help get sharper shadows on translucent objects.

Previewing



Property

Description

Preview Mesh

Sets a Static Mesh used to preview the Material in the Preview viewport.

Import Settings



Property

Description

Asset Import Data

A selection of import data types and options relevant to the selection for use with this Material. For example, selecting Fbx Texture Import Data provides its own set of properties that affect this import type.

Shading Models determine how Material inputs (e.g. Emissive, Diffuse, Specular, Normal) are combined to make the final color.

Model

Description

Unlit

The Material is defined by the Emissive and Opacity inputs only. It does not respond to light.

Default Lit

The default shading model. Perfect for most solid objects.

Subsurface

Used for subsurface scattering Materials, such as wax and ice. Activates the Subsurface Color input.

Preintegrated Skin

Used for Materials similar to human skin. Activates the Subsurface Color input.

Clear Coat

Used for Materials that have a translucent coating on top like clear coat car paint or lacquer. Activates the Clear Coat and Clear Coat Roughness inputs.

Subsurface Profile

Used for Materials similar to human skin. Requires the use of a Subsurface Profile in order to work correctly.

Two Sided Foliage

Used for Materials that create natural looking foliage with accurate lighting and light transmission through surfaces, such as throug leaves on a tree.

Hair

Used for Materials that create realistic looking hair that accurately lights the hair shafts and handles speular highlight.

Cloth

Used for Materials that need to create realistic looking cloth and fuzz along its surface.

Eye

Used for Materials that recreate the natural look of humanoid eyes.

Single Layer Water

Eenables you to achieve the effect of a transparent water surface while using an Opaque Blend Mode. This reduces the cost and complexity of using Materials that require the Transparent Blend Mode.

Thin Translucent

Used for Materials that create physically based glass, such as colored or tinted glass. It properly handles white specular from light sources and tinted background objects.

From Material Expression

Used for handling multiple shading models in a single material.

For more information on these Shading Models, read the Shading Model documentation.

Blend Modes describe how the output of the current Material will blend over what is already being drawn in the background. Put more technically, it allows you to control how the engine will combine this Material (Source color) with what is already in the frame buffer (Destination color) when rendered. The available blending modes are:

Mode

Description

BLEND_Opaque

Final color = Source color. This means that the Material will draw on top of the background. This blend mode is compatible with lighting.

BLEND_Masked

Final color = Source color if OpacityMask > OpacityMaskClipValue, otherwise the pixel is discarded. This blend mode is compatible with lighting.

BLEND_Translucent

Final color = Source color Opacity + Dest color (1 - Opacity). This blend mode is NOT compatible with dynamic lighting.

BLEND_Additive

Final color = Source color + Dest color. This blend mode is NOT compatible with dynamic lighting.

BLEND_Modulate

Final color = Source color x Dest color. This blend mode is NOT compatible with dynamic lighting, or fog, unless this is a decal material.

AlphaComposite

Used for Materials with textures that have premultiplied alpha. That is, the color channel has already been multiplied by the alpha so when blending with the frame buffer, the GPU can skip the (SrcAlpha * SrcColor) arithmetic that is typically used with alpha blending. Can improve the visual appearance of additive blending.

AlphaHoldout

Lets you "hold out" the alpha of a Material, punching a hole through Translucent objects directly behind it in view space.

For more information on these Blend Modes, read the Blend Modes documentation.

Material Domain allows you to define how you will use the Material. Certain Material uses (such as decals) require additional instructions for the render engine to consider. Because of this, it is important to set the Material Domain accurately, particularly when the Material is intended for something other than a surface. Material Domain includes the following options:

Domain

Description

Surface

This setting defines the Material as something that will be used on an object's surface. Think metal, plastic, skin, or any physical surface. This is the default setting, and the one you will use most of the time.

Deferred Decal

When making a Decal Material, you will use this setting.

Light Function

Used when creating a Material for use with a Light Function.

Volume

Used when describing the Material's attributes as a 3D volume.

Post Process

Select this option when creating a Post Process Material.

User Interface

Select this option when creating Materials for a UMG or Slate user interface.

Virtual Texture

Used when making a Runtime Virtual Texture.

This allows for control over the lighting mode used by Translucency within this Material. This is especially useful for Particle Systems that are making use of Translucency, such as self-shadowing smoke or steam.

Mode

Description

Volumetric NonDirectional

Lighting is calculated for a volume, without directionality. Use this on particle effects like smoke and dust. This is the cheapest lighting method, however, the material normal is not taken into account.

Volumetric Directional

Lighting is calculated for a volume, with directionality so that the normal of the material is taken into account. Note that the default particle tangent space is facing the camera, so enable bGenerateSphericalParticleNormals to get a more useful tangent space.

Volumetric PerVertex NonDirectional

Same as Volumetric NonDirectional, but lighting is only evaluated at vertices so the pixel shader cost is significantly less. Note that lighting still comes from a volume texture, so it is limited in range. Directional lights become unshadowed in the distance.

Volumetric PerVertex Directional

Same as Volumetric Directional, but lighting is only evaluated at vertices so the pixel shader cost is significantly less. Note that lighting still comes from a volume texture, so it is limited in range. Directional lights become unshadowed in the distance.

Surface Translucency Volume

Lighting is calculated for a surface. The light is accumulated in a volume so the result is blurry, limited distance but the per pixel cost is very low. Use this on translucent surfaces like glass and water. Only Diffuse lighting is supported.

Surface Forward Shading

Lighting is calculated for a surface. Use this on translucent surfaces like glass and water. This is implemented with forward shading so Specular highlights from local lights are supported, however, many deferred-only features are not. This is the most expensive translucency lighting method as each light's contribution is computed per-pixel.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Opaque

Masked

Translucent

Additive

Modulate

AlphaComposite

AlphaHoldout

Blend Mode Forumulas

Blend Modes describe how the output of the current Material will blend over what is already being drawn in the background. Put more technically, it allows you to control how the engine will combine this Material (Source color) with what is already in the frame buffer (Destination color) when this Material is rendered in front of other pixels.

Blend Mode options are found in the Details panel with the rest of the base Material Properties:



This document uses a sphere placed between the camera and a wall to demonstrate the various Blend Modes. By changing the Blend Mode on the sphere Material you can see how the object blends with the pixels behind it.



Opaque

The Opaque Blend Mode is the most straightforward, and probably the one you will use most often. It defines a surface through which light neither passes nor penetrates. This is perfect for most plastics, metals, stone, and the larger percentage of other surface types. From the perspective of the camera, the golden sphere completely occludes the wall behind it.



Masked

The Masked Blend Mode is used when you need to selectively control visibility in a binary (on/off) fashion. For example, consider a Material that simulates a chain link fence or grate. You will have some areas that look solid while others are invisible. Such Materials are perfect for the Masked Blend Mode.

A Masked Material graph is shown below, with a black and white striped texture plugged into the Opacity Mask input. White parts of the mask are rendered, while black parts are invisible. There are no intermediate levels of opacity when using a Masked Material.



Here is that Material from the camera's perspective:



It is important to keep in mind the difference between transparent and not rendered. A transparent surface, such as glass, still interacts with light in the form of reflections (specularity). Pixels that are culled in Masked mode simply do not draw; you will not see any reflections in those areas. If you want to retain reflections or specular aspects, you would do well to use the Translucent Blend Mode, or consider making a Layered Material.

Further, since these features don't render in the masked area, they aren't calculated at all, leading to performance savings on the GPU.

Opacity Clip Mask

When using Masked Blend Mode, you need to pay special attention to the Opacity Mask Clip Value property. This property holds a 0-1 scalar value which controls what value of the opacity mask texture will be used as a cutoff point, beyond which all darker pixels will not render.



Opacity Mask Clip Value (Drag the slider to preview.)

In the example above, the Material has its Two Sided property set to True (checked), which is why you can see the inside of the box.

Also, despite the interactive example shown here, the Opacity Mask Clip Value property is not designed to be changed at runtime.

Translucent

The Translucent Blend Mode is used for objects that require some form of transparency. This differs from the Masked Blend Mode in that it allows varying levels of translucency.



This Blend Mode works by taking in an Opacity value or texture and applying it to the surface such that black areas are completely transparent, white areas are completely opaque, and the varying shades of gradation between result in corresponding transparency levels. In the example, a black to white gradient is plugged into the Opacity input, resulting in a sphere that is fully transparent at the top of the mesh and gradually reaches full opacity at the bottom.



An important consideration when using Translucent Materials is that they do not currently support specularity. This means that you will see no reflections along the surface. However, such reflections can be faked using a Cubemap in a node network similar to this. The Cubemap texture is simply added on top of the Base Color.



Additive

The Additive Blend Mode simply takes the pixels of the Material and adds them to the pixels of the background. This is very similar to the Linear Dodge (Add) Blend Mode in Photoshop. This means that there is no darkening; since all pixel values are added together, blacks will just render as transparent. This Blend Mode is useful for various special effects such as fire, steam, or holograms.



As with the Translucent Blend Mode, this Blend Mode does not respect specularity (i.e. reflections). The additive nature of the blending probably means you will not use it anyway, but it is possible to simulate a reflection-like effect using the Cubemap method shown above in the Translucent section.

In the image below a second sphere was added to the scene. Note that where the two spheres overlap, the pixels are added together and therefore brightened.



One drawback of Additive Materials is that they are often difficult to see against light colored backgrounds. A side view of the spheres demonstrates this.



A solution is to use the AlphaComposite Blend Mode instead, with a texture that has a premultiplied alpha channel. This improves saturation and visibility in bright scenes.

Modulate

The Modulate Blend Mode multiplies the value of the Material against the pixels of the background. The behavior is very similar to the Multiply Blend Mode in Photoshop, and produces a darkening effect.



In the graph above, the Material Shading Model is set to Unlit and the Blend Mode to Modulate. A Constant3 Vector is plugged into the Emissive input to define the surface color.



Notice again that with multiple spheres, the pixels that overlap are multiplied together and become darker.

The Modulate blend mode is best suited for certain particle effects, but care must be taken as it does not support lighting or Separate Translucency.

AlphaComposite

AlphaComposite is used in Materials that have textures with premultiplied alpha, meaning the RGB color channels were premultiplied by the alpha channel before the image was stored. The AlphaComposite Blend Mode is a useful alternative to the Additive or Translucent Blend Modes for brightly colored particles and VFX.

Compared to additive blending, AlphaComposite Materials have better visiblity and maintain more color saturation against light colored backgrounds. Bright regions of the Material are less likely to blow out to pure white due to additive build-up.

The video below shows an AlphaComposite Material with an opacity parameter. At low opacity levels the Material works more like an additive blend, whereas at opacity levels 0.5 and higher it resembles Translucent blending, creating an interesting transitional effect near the edges of the mask.

The VFX of Diablo - Julian Love (Skip to 20:00)

AlphaComposite Forum Thread.

AlphaHoldout

The AlphaHoldOut blend mode lets you "hold out" the alpha of a Material, punching a hole through the objects directly behind it in view space. The following image shows the camera and scene layout for an AlphaHoldout implementation.



The camera.

A Static Mesh in the foreground acts as the "hole-punching" object. The AlphaHoldout Material is applied to this mesh. This Material must use the Unlit Shading Model.

A receiving surface (which you intend to punch a hole through) is placed behind the AlphaHoldout object; in this case, a brick wall. The Material on the receiving surface MUST use either the Translucent, Additive, Modulate, or AlphaComposite Blend Modes. An AlphaHoldout Material cannot act upon an Opaque Material.

The background of the scene, which will be visible through the hole.

From the camera's perspective, you will see a transparent hole through the receiving surface, making the objects behind it visible.



Because the AlphaHoldOut material is on a separate Static Mesh Asset, you can easily move it around in-editor or animate it in game.

Blend Mode Forumulas

Mode

Description

BLEND_Opaque

Final color = Source color. This means that the Material will draw on top of the background. This blend mode is compatible with lighting.

BLEND_Masked

Final color = Source color if OpacityMask > OpacityMaskClipValue, otherwise the pixel is discarded. This blend mode is compatible with lighting.

BLEND_Translucent

Final color = Source color * Opacity + Dest color * (1 - Opacity). This blend mode is NOT compatible with dynamic lighting.

BLEND_Additive

Final color = Source color + Dest color. This blend mode is NOT compatible with dynamic lighting.

BLEND_Modulate

Final color = Source color x Dest color. This blend mode is NOT compatible with dynamic lighting, or fog, unless this is a decal material.

BLEND_AlphaComposite

Final Color = Source Color + Dest Color * (1 - Source Opacity).

BLEND_AlphaHoldout

Final Color = Dest Color * (1 - Source Opacity). This blend mode is **NOT** compatible with dynamic lighting.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Unlit

Default Lit

Subsurface

Preintegrated Skin

Clear Coat

Dual-Normal Clear Coat

Subsurface Profile

Two Sided Foliage

Hair

Cloth

Eye

Single Layer Water

Thin Translucent

From Material Expression

Shading Models control how your Material reflects incoming light. Or, put another way, it controls how the input data that makes up the Material is used to create the final look.



Unreal Engine has many Shading Models designed to achieve specific looks for the Materials you set up. For instance, the Default Lit Shading Model is a general purpose model you will likely use for most of your surfaces. Unreal also includes Shading Models designed for specific surface types. For example, the Clear Coat, Hair, and Cloth Shading Models are tailored to provide natural results for those specific types of Materials.

Unlit

The Unlit Shading Model only outputs Emissive for color, making this perfect for special effects such as fire or any light emitting object. Note that in this example, the Material is not casting light into the scene. Instead, its high Emissive value results in a glow effect, which is also picked up by the dirt mask applied to the camera. It appears to illuminate, but no lighting or shadows are cast by this object. Emissive Materials can cast light into the scene if Lumen is enabled, or with Lightmass when Use Emissive for Static Lighting is turned on.



When using the Unlit Shading Model, you have access to the following inputs:

Emissive Color

World Position Offset

Pixel Depth Offset

Default Lit

Default Lit is the default shading model and is likely the one that you will use most often. This shading model makes use of direct and indirect lighting, as well as specularity for reflections.



When using the Default Lit Shading Model, you have access to the following inputs:

Base Color

Metallic

Specular

Roughness

Emissive Color

Normal

World Position Offset

Ambient Occlusion

Pixel Depth Offset

Subsurface

The Subsurface Shading Model simulates the effect of subsurface scattering. This is a real-world phenomenon in which light penetrates a surface and then diffuses throughout it. Subsurface scattering is readily apparent on objects such as ice, wax candles, and skin.

The Subsurface model (as well as the Preintegrated Skin model described below) relies on the Subsurface Color input. This input defines the color of the matter just beneath the surface of the object. When light scatters through the surface, the Subsurface Color becomes visible.

For human skin, you can often get good results using a dark red color, which simulates blood circulating beneath the surface. In the Ice Elemental below, a dark blue-green color (with a variety of calculations based on lighting) is used to give a sense of translucent depth to the surface.

For more information, see the Subsurface Shading Model documentation.



When using the Subsurface Shading Model, you have access to the following inputs:

Base Color

Metallic

Specular

Roughness

Emissive Color

Opacity

Normal

World Position Offset

Subsurface Color

Ambient Occlusion

Pixel Depth Offset

Preintegrated Skin

The Preintegrated Skin Shading Model is very similar to the Subsurface model, but prioritizes lower performance cost while sacrificing some accuracy. While not physically perfect, this Shading Model often gives nice results for human skin with better performance than the Subsurface method. In the image below, the character's flesh uses the Preintegrated Skin Shading Model.



When using the Preintegrated Skin Shading Model, you have access to the following inputs:

Base Color

Metallic

Specular

Roughness

Emissive Color

Opacity

Normal

World Position Offset

Subsurface Color

Ambient Occlusion

Pixel Depth Offset

Clear Coat

The Clear Coat Shading Model is used to better simulate multilayer Materials that have a thin translucent layer of film over the surface of a standard Material. This Shading Model was specifically designed to model smooth colored films over a non-colored metal. However, you can use this Shading Model with both metal and non-metal surfaces.

Some examples include acrylic or lacquer clear coats, and colored films over metals such as soda cans and car paint.



Note that the flecks were done in the Material Editor and are not part of the Shading Model

Dual-Normal Clear Coat

The Clear Coat Shading Model also has an option to add a second Normal Map for the surface that is below the clear coat layer. This enables the Material to more accurately model complex Materials such as carbon fiber and car paints, which have a different geometric or reflective surface than the clear coat layer.





Clear Coat with Bottom Normal

Actual Photograph

When using the Clear Coat Shading Model, you have access to the following inputs:

Base Color

Metallic

Specular

Roughness

Emissive Color

Normal

World Position Offset

Clear Coat

Clear Coat Roughness

Ambient Occlusion

Pixel Depth Offset

Subsurface Profile

The Subsurface Profile Shading Model is very similar in nature to both the Subsurface and Preintegrated Skin Shading Model, but it is geared towards higher-end skin rendering. If you are trying to simulate skin, especially human skin, this is the highest quality Shading Model to use for that purpose.





When using the Subsurface Profile Shading Model, you have access to the following inputs:

Base Color

Metallic

Specular

Roughness

Emissive Color

Opacity

Normal

World Position Offset

Ambient Occlusion

Pixel Depth Offset

Two Sided Foliage

The Two Sided Foliage Shading Model allows light transmission through the surface of the Material creating natural, uniform looking results, like light passing through the leaves of a tree. The subsurface color is used to define the amount of light transmission and is used for creating masks for things such as the stems and veins of the leaves.

The Two Sided Foliage Shading Model helps eliminate some issues present in the Subsurface scattering model, which works well on skin or thicker surfaces, but is not as accurate for thin surfaces like leaves. Similarly, using the Default Lit shading model for foliage can lead to incorrect looking results. In the example below, the Default Lit result appears almost black on the underside surfaces because it does not simulate any sort of light transmission, which is critical for natural looking foliage.





When using the Two Sided Foliage Shading Model, you have access to the following inputs:

Base Color

Metallic

Specular

Roughness

Emissive Color

Normal

World Position Offset

Subsurface Color

Ambient Occlusion

Pixel Depth Offset

Hair

The Hair Shading Model enables you to create natural looking hair that simulates multiple specular highlights: one representing the color of light, and another representing a mix of hair and light color.



When using the Hair Shading Model, you have access to the following inputs:

Base Color

Scatter

Specular

Roughness

Emissive Color

Tangent

World Position Offset

Backlit

Ambient Occlusion

Pixel Depth Offset

Cloth

The Cloth Shading Model enables you to create Materials that mimic the properties of cloth more accurately. This includes a thin "fuzz" layer across the cloth surface, better simulating the way light interacts with these types of Materials.



When using the Cloth Shading Model, you have access to the following inputs:

Base Color

Metallic

Specular

Roughness

Emissive Color

Opacity

Normal

World Position Offset

Fuzz Color

Cloth

Ambient Occlusion

Pixel Depth Offset

Eye

The Eye Shading Model is designed to simulate the surface of an eye, exposing artistic controls for the iris shape and distance. This Shading Model is highly technical and has been developed in a way that produces very strong dependencies between the shader code, the Material, the shape of the geometry, and its UV layout.

Building an eye Material on your own is not recommended without extensive experience in shader development. If you are interested in creating realistic humanoid eyes, Epic recommends extracting the eye geometry from the Digital Humans example project available on the Epic Games Launcher in the Learn tab. Use the Material assigned to the eye geometry in that project as-is, replacing the necessary textures to suit your purpose.



When using the Eye Shading Model, you have access to the following inputs:

Base Color

Metallic

Specular

Roughness

Emissive Color

Opacity

Normal

World Position Offset

Iris Mask

Iris Distance

Ambient Occlusion

Pixel Depth Offset

Single Layer Water

The Single Layer Water Shading Model enables you to achieve the effect of a transparent water surface while using an Opaque Blend Mode. This reduces the cost and complexity of using Materials that require the Transparent Blend Mode.





When using the Single Layer Water Shading Model, you have access to the following inputs:

Base Color

Metallic

Specular

Roughness

Emissive Color

Opacity

Normal

World Position Offset

Ambient Occlusion

Refraction

Pixel Depth Offset

For more information, see Single Layer Water Shading Model.

Thin Translucent

The Thin Translucent Shading Model supports physically based translucent Material types, enabling you to create true tinted or colored glass that handles specular and background objects accurately.

For example, when creating a tinted glass Material, both the white specular highlight and the tinted background are needed. This Shading Model renders both in a single pass with a physically based shader that accounts for light bounces from the air into the glass, and from the glass into the air.





When using the Thin Translucent Shading Model, you have access to the following inputs:

Base Color

Metallic

Specular

Roughness

Emissive Color

Opacity

Normal

World Position Offset

Ambient Occlusion

Pixel Depth Offset

From Material Expression

The From Material Expression (or Per-Pixel) shader model is an advanced feature enabling you to combine multiple Shading Models into a single Material (or Material Instance) through logic in the Material Graph.

When the Shading Model is set to From Material Expression, the Shading Model input is enabled and you can use the Shading Model node in your Material Graph to set it.





When using the From Material Expression Shading Model, you have access to the following inputs:

Base Color

Metallic

Specular

Roughness

Emissive Color

Normal

World Position Offset

Ambient Occlusion

Pixel Depth Offset

Shading Model

For additional information and example use cases, see From Material Expression shading model.

Shading Models

Usage

Used Shading Models in the Material

Blending Multiple Shading Models

Blending Material Attributes

If-Statements

Switch Nodes

Material Instancing

Additional Information

The From Material Expression Shading Model is an advanced feature enabling you to combine multiple Shading Models within a single Material (or Material Instance) through logic in the Material Graph.



When the From Material Expression Shading Model is enabled, you can blend between Shading Models on a per-pixel basis using alpha masks, or with conditional logic like Switch Expressions and If statements.

Usage

To use multiple Shading Models in a single Material, you must first set the Shading Model property to From Material Expression in the Details panel.

Click anywhere in the background of the Material Graph, or select the Main Material Node to display the Material Properties in the Details panel.

In the Details Panel, use the Shading Model drop-down menu to select From Material Expression. When From Material Expression is selected, the Shading Model pin on the Main Material Node changes to white, indicating that it is enabled.



Right-click in the Material Graph and search for "Shading Model" in the context menu. Add a Shading Model Material Expression to your graph.



Select the Shading Model node in the graph. In the Details Panel, use the drop-down menu to choose the Shading Model you want to use.



Connect the Shading Model node to the Shading Model input pin on the Main Material Node. This Material is now using the Clear Coat Shading Model, as derived from the Shading Model Material Expression.



The primary benefit of this workflow is that you can blend between multiple Shading Models within a single Material. Read the sections below for usage examples.

Used Shading Models in the Material

When multiple Shading Models are used in your Material Graph, they are convienently listed next to Used Shading Models in the Details panel properties.



This example shows a Material that is using both the Default Lit and Clear Coat Shading Models.

Keep in mind that this list only shows Shading Models set in the Material Graph and does not always represent what is actually compiled. Switch nodes can be used to remove entire parts of the graph, including Shading Models. For examples of this, see the Material Switch Nodes section below.

Blending Multiple Shading Models

The following sections provide three different ways to blend between Shading Models in a Material.

Blending Material Attributes

The most straightforward way to create a per-pixel blend between two different Shading Models is to use a Set Material Attributes expression to define each surface, and then blend them using the BlendMaterialAttriutes node.

This example assumes some knowledge of how to use the Material Attributes workflow to define the physical attributes of a Material. If you are unfamilar with this process, read the documentation on Material Attributes Expressions.

In the example below, a checkerboard texture is plugged into the Alpha input on the BlendMaterialAttriubtes node to mask between the Default Lit and Clear Coat Shading Models in each set of Material Attributes.





Click image for full size.



Use the following steps to create a Material like the one above.

In the Details Panel, set the Shading Model to From Material Expression. In the same section, enable the Use Material Attributes option. When this option is checked, the Main Material Node disappears and is replaced by a Material Attributes output node.



Use the SetMaterialAttributes Expression to define each of the two surface types. Select the SetMaterialAttributes node in the Material Graph, and click the Add Element icon in the Details panel. Add a Shading Model input pin to both SetMaterialAttributes nodes in your graph. After you define both Materials, add a BlendMaterialAttributes node to blend between the two sets of attributes. Connect the BlendMaterialAttributes expression to the Material Attributes output node. This process is shown in the video below.

The full Material Graph used in this example is pictured below. The carbon fiber normal map texture used in the Clear Coat part of the graph is available for download on the Clear Coat with Dual Normals page.





Click image for full size.



When the Material is applied to a Static Mesh, it uses only a single draw call to render both shading models instead of two draw calls. With the Alpha mask applied, you can clearly see the two Shading Models mapped to different regions on the sphere.

If-Statements

You can also use an If Material Expression to blend between Shading Models within the same set of Material Attributes. The If expression compares the float values in the A and B inputs, and outputs a different results based on whether the value in A is greater than, equal to, or less than B. In the example below, this logic is used to select between the two Shading Models in the graph.



If no value is set for B, it defaults to a value of 0. You can set a hardcoded value in the Details panel, use another float vlaue derived from a texture, constant, or Scalar parameter for the B input to control it within a Material Instance. This example uses a Constant value of 0.5 for the B value.

In the comparison below, the If expression evaluates the value of B against A to set the shading model to either Default Lit or Clear Coat. If the float value of A is greater than that of B, Default Lit is used, if A is less than B, Clear Coat is used.





Switch Nodes

Use the available Switch nodes below to control functionality and quality of your Material.



A Shading Path Switch is useful for specifying what part of your material logic should be used for a render path.

A Quality Switch is useful when using the engine's quality levels to control material logic.

A Feature Level Switch is useful when setting up a material for use on different devices.

A Static Switch or Static Switch Parameter is useful to exclude entire branches of your material in a base material or controllable through a Material Instance.

In the graph and comparison below, a Static Switch expression sets the shading model to Default Lit when set to True and Clear Coat when set to False.





Click image for full size.







Material Instancing

Material Instancing is fully supported enabling you to setup and use logic in your Material Graph to drive parameters and variables to set which shading model(s) is used.

Keep in mind that the Material Instance's shading model is shown as From Material Expression and it can be overridden to a static shading model. However, you cannot override a Material Instance's shading model to be From Material Expression. It will silently fail and do nothing.

Additional Information

Shading Model Input Always Shown Enabled

When Use Material Attributes is enabled and using the Set, Get, Make, or Break Material Attributes nodes, the Shading Model input will always be shown enabled (not grayed out) even though From Material Expression may not be set as the selected shading model. The pin will not do anything unless From Material Expression is set as the shading model for the Material. This does not affect the Main Material Inputs node that is default.

Material Instance Overrides

Overriding the Shading Model of a Material Instance works as expected, however, setting it to From Material Expression will silently fail and do nothing unless the Parent Material uses it.

Unlit Shading Model

There is a lot of information that is compiled out, which means means that shading path cannot be properly supported without introducing regressions.

Technical Details

Material Input Channels

Limitations

Materials have a new subsurface shading model (MLM_Subsurface) which is intended for materials like wax or jade which appear opaque, but lighting scatters inside them allowing a portion of the light from the opposite side of the surface to show through.



Subsurface scattering (SSS) is often used for creating realistic skin for humans or other creatures; however, the effect from this shading model is lower quality and cheaper than what would generally be used for skin rendering.

Technical Details

The two components of subsurface lighting are a wrap-around N dot H term and a light backscattering term, which shows up when the light is on the other side of an SSS object. Both of these are masked by translucent self shadowing from exponential shadow maps.

Material Input Channels

The SubsurfaceColor input channel defines the color inside the material which affects SSS lighting.

The Opacity channel of the material takes on a slightly different meaning when the material is using subsurface scattering and the MLM_Subsurface shading model. Since these types of surfaces are completely opaque, the Opacity, in this case, controls how dense the material is when it scatters light as well as:

How much the normal affects the subsurface lighting, a more opaque material gets more normal influence.

How far lighting makes it through the material due to self-shadowing, a smaller opacity causes light to travel further.

How soft the shadow is on the material, a smaller opacity results in softer shadows, but softness is clamped.

Be sure to set the Opacity for any subsurface materials to a reasonable value, e.g. 0.1. The default opacity is 1, which does not produce a very convincing subsurface-type effect.

Limitations

Additionally there are some limitations with the current implementation:

Point light shadowing not yet supported.

Cascaded Shadow Map seams.

SSS materials can still receive leaked lighting through fully opaque materials if they are close enough to the shadow caster.

Soft shadows from low opacity are limited in how soft they can be and have aliasing.

Water System

Single Layer Water's Implementation

Single Layer Water Low-end Systems and Mobile Support

Using Single Layer Water Material Output

Scattering Coefficients

Absorption Coefficients

PhaseG Function

Color Scale Behind Water

Water Opacity

The Single Layer Water material shading model is a material that provides a cost-effective translucency method using a single depth layer. It is a physically-based shading model that supports proper light scattering, absorption, reflection and refraction, and shadowing on water surfaces.

Single Layer Water's Implementation

The Single Layer Water shading model uses a custom render pass to achieve its transparent result, and it can do so while using a Blend Mode that is either Opaque or Masked. The translucency of the material runs after the base pass and deferred lighting, but before regular translucency rendering, post-processing, and everything else that comes in the rendering pipeline.

Single Layer Water shading is a homogeneous volume of a participating medium that uses scattering and Schlick Phase Functions with contributions from the Opaque or Masked water surface. The transparency of the surface is implicit in the volume shading model. Refraction is also handled by the volume function, which reads the depth and color below the surface before distorting the samples.

In the Material Editor, the Single Layer Water Material node has four inputs: Scattering Coefficients, Absorption Coefficients, PhaseG, and Color Scale Behind Water. These inputs define the look of the water. How translucent the water is is handled by the main material node's Opacity input, whereby it controls the ratio between the volume's bi-directional scattering distribution function (BSDF) and the surface's bi-directional reflectance distribution function (BRDF).

You can use RenderDoc to perform a frame capture that allows you to see where the Single Layer Water pass happens in the GPU capture. When the Single Layer Water pass happens, the BasePass has already been rendered and lit. The fully lit scene and depth are used as input to the Single Layer Water pass, and reading the buffers is how refraction and translucency is achieved for an Opaque or Masked material.



Prior to the first item in the list, you can use an optional step to downsample the scene color and depth buffer for the refraction reads. This can speed up rendering but gives a slightly blurry (or low resolution) appearance to objects rendered below the water's surface.

All objects with SingleLayerWater are rendered into the GBuffer (including depth) using the user-defined material.

A compute shader is run to tile-classify all of SingleLayerWater based on the MaterialID in the GBuffer.

Generated screen tiles are used for an indirect draw screen space reflections (SSR) pass, which is run and output to a separate buffer.

Generated screen tiles are used again to run an indirect draw full screen pass to composite reflection captures, sky, and newly computed screen space reflections on top of the water's surface.

Single Layer Water Low-end Systems and Mobile Support

In situations where lower-end systems and platforms, such as mobile and low-end desktop, an alternative render path is used that skips some of the features of Single Layer Water in favor of performance. The simplest alternative reverts the material to a simple translucent material with no volume integration, or screen space reflections.

Using Single Layer Water Material Output

When creating a material, set the following in the Details panel:



Blend Mode: Opaque or Masked

Shading Model: SingleLayerWater

Add a Single Layer Water Material output node to the Material Graph. This output expression defines the look of water for light scattering and absorption, anisotropic or isotropic directionality (PhaseG), and color contribution on surfaces that are below the water surface (for example, caustics and shadows).



Scattering Coefficients

The Scattering Coefficients input represents the rate at which light scatters on particles within a medium — in this case, water. The amount of light scattering that takes place within the medium determines how light and color look for objects within the medium. When there is a low amount of scattering through the medium, such as glass or a bottle of water, the medium appears clear. Light will not scatter as much through the medium, allowing light to pass through more readily. In cases where there is a high amount of scattering, light scatters more preventing it from passing through the medium. This causes the medium to appear thicker, or more opaque, like orange juice or milk.

The amount of scattering affects how light travels through the medium, and that directly impacts the way things look when an object is within its volume. For example, if there are three cubes (red, green, and blue) that are within the medium, and the material is set to only scatter blue light, notice how the scattered blue light affects the color of all the cubes (left) compared to a material where no scattering is happening (right).





Blue light scattering in the medium

No light scattering happening

Applying this concept to the default Water Body material, notice how it looks when some amount of scattering is applied, compared to no scattering at all. When there is no scattering, light doesn't bounce or get dispersed in the same way, so the cubes are visible farther down than they are when light is scattered.

Using a higher amount of scattering gives a thicker appearance and consistency to the water. Light scatters much more through the medium, making it more difficult to see objects the deeper they travel. The example below demonstrates the effect of having different amounts of light scattering, from a lower amount to a very high amount, and then to the point where it is impossible to see any part of the cubes below the surface.

Drag the slider to see incemental Scattering values increase their scattering result: 0.5, 1, 2, 4, 8, 16, 32



Absorption Coefficients

The Absorption Coefficient input defines how easily light penetrates the volume of water (or participating medium). Each color channel (RGB), or wavelength of light, penetrates water differently, some better than others. When light is absorbed by the medium it's traveling through, it goes extinct, meaning it loses its color. The farther an object travels into a medium with a high absorption coefficient, the more likely its color will dissipate.

Absorption coefficients control what colors of light are likely to be absorbed more quickly in a medium. Small coefficients allow for light to transmit easily through the medium, giving it a more transparent appearance. Large coefficients attenuate light more quickly as it passes through the medium, giving it a less transparent appearance.

The example below shows three cubes (red, green, and blue) moving farther into the medium. When using a moderate absorption coefficient for these primary colors (Red =0.0033, Green = 0.0016,Blue = 0.0011), the results show how each color dissipates as they move deeper into the medium. First red goes extinct, then green, and finally blue.

Using the same values and setup as above with the default water material, the three primary-colored cubes each lose their coloring as they submerge and travel deeper into the water. Their colors become extinct in the same order.

When using the default water material, the absorption coefficient values are reversed. Larger values cause colors to go extinct quicker than lower values. The distance light travels through the volume is expressed in reciprocal meters, meaning that it is expressed by dividing 1 by the absorption distance in your material.

The distance setup used looks like this:



PhaseG Function

The PhaseG parameter controls the overall forward or backward direction that light scatters in water. More specifically, this parameter controls the anisotropic directionality of scattered light relative to the direction of the sun.

PhaseG takes in values that are positive or negative, where positive values increase how much light is scattered toward (forward) the sun and negative values increase how much light is scattered away (backward) from the sun. This can have the effect of water looking brighter or darker depending on the current view and where the sun is in the sky.





PhaseG: -0.75

PhaseG: 0.5

When the PhaseG value is 0, its light directionality is isotropic, meaning that light scatters the same in all directions.

The phase function gives water a more defined shape, especially when there are waves present. This is because after refraction occurs, the view ray changes directions, adding variation to the amount of light being scattered through the water.

Color Scale Behind Water

The Color Scale Behind Water input multiplies the luminance of the surfaces below the water. This type of effect is used within your material to drive how bright or dark caustics or shadows can be.

The comparison below demonstrates how visible caustics can be on surfaces below the water.





This is simply a visual effect of the material, which is visible above the water material. Moving below the surface of the water does not change the brightness of surfaces behind the water nor does it actually project caustics or shadowing on these surfaces.

Water Opacity

When using a material setup to use Single Layer Water, the Opacity input on the main material node controls the visible parameter of water. The amount of opacity controls how much light is allowed into the volume and scattered. It also controls how far you're able to see through the volume. Larger opacity values are more opaque, not allowing light to penetrate the surface. Lower values allow all light to pass through the surface so you can see much farther into the water.

Having low, or no, opacity also allows for the other properties of the Single Layer Water Material output expression to work unencumbered. In the table below, having no, some, or maximum values for the opacity of the water material allows all, some, or no light to pass through the volume. Having a completely opaque material (Opacity = 1) has a dark appearance as no light is allowed through the surface to scatter through the water.







Water Opacity: 0

Water Opacity: 0.5

Water Opacity: 1

Samples and Tutorials

What is a Subsurface Profile

Enabling, Creating, and Using a Subsurface Profile

Creating A Subsurface Profile

Enabling Subsurface Profile

Burley SubSurface Profile

Material Input Channels

Full-Resolution Skin Shading

Compatibility

Limitations

Performance Considerations

Technical Details

Scalability and Console Commands

Subsurface Profile Property Reference

Special Thanks

Unreal Engine offers a specific shading method for rendering realistic skin or wax surfaces, which is called Subsurface Profile shading.

The Subsurface Profile shading method is similar to the Subsurface method, but with a fundamental difference in how it renders: Subsurface Profile is based in screen space. This is because screen space rendering is a more effective to display the subtle subsurface effects seen in human skin, where backscattering is a secondary effect only seen in few cases, such as ears. In the following document will cover what Subsurface Profiles are and how you can use them in your work.





Special thanks to Lee Perry-Smith and his company Infinite Realities for their assistance with this documentation, also for providing the 3D scanned head model.

What is a Subsurface Profile

The Subsurface Scattering Profile data is an asset that can be created, shared, and saved in the Content Browser. The data is intended to be authored by artists and controls the distance the light in the Subsurface should scatter, the color of the Subsurface, and the falloff color of the light once it has exited the object. This data can then be applied to a Subsurface Material. Subsurface Profile data can also be tweaked interactively, meaning that you do not need to re-compile the material to see the results of edits.

Enabling, Creating, and Using a Subsurface Profile

There are many different ways of using Sub Surface profiles in Unreal Engine. In the following section, we will take a look at each of these ways.

Creating A Subsurface Profile

To create a Subsurface Profile, first Right-click inside of the Content Browser. Then select the Materials & Textures option and then select the Subsurface Profile option.



You can edit Subsurface Profiles by Double-clicking on them with the Left Mouse Button in the Content Browser to open it up. Once open, you can adjust the individual properties of the Subsurface Scattering Profile by either inputting a number using the keyboard or by using the Left Mouse Button to Click on the color bar to expose the color picker.

Enabling Subsurface Profile

To use a Subsurface Profile in a Material, you must first enable it by setting the Materials Shading Model to Subsurface Profile in the Details panel of the Material. Once enabled, you can override the default Subsurface Profile that is used by inputting a new one into the Subsurface Profile input.

The default settings for the Subsurface Profile are close to the Caucasian skin type. Please note that this is just one component to getting a realistic looking skin. Always make sure the base color of your texture fits your Subsurface scattering profile.



The Subsurface Profile can also be overridden in a Material Instance. To do this go the Details pannel of the Material Instance and enable the Override Subsurface Profile. Once enabled, supply the Subsurface profile you want to use in the Subsurface Profile input.



Remember that the whole computation is energy-conserving, so it is not possible to create additional light through scattering.

Burley SubSurface Profile

Burley subsurface scattering uses a screen space model using the Burley algorithm. It is more physically accurate and aims to improve the quality of skin shading while simplifying setup using physically based material properties. It targets high-end skin rendering at much higher quality than the traditionall separable SSS algorithm, which has a cleaner, more accurate fall off.





To use this subsurface scattering model, place a check next to Enable Burley in the SubSurface Profile Asset.

This method requires Temporal Anti-Aliasing to display properly.

Material Input Channels

The Screen Space Subsurface shading profile does not differ much from the Lit shading mode, with the main difference being that the Metallic input has been repurposed and is not available to be used.

Base Color Input: The Base Color input is used as usual for Diffuse lighting. There is no extra Subsurface Scattering color as the Screen Space Subsurface Scatter is not supposed to change color or brightness, it is just redistributing the lighting to nearby pixels. So, if a material should scatter in a specific color, it needs to be expressed as part of the Base Color. The Base Color should be the final color as if the material is viewed from a large distance where the scattering cannot be distinguished from diffuse lighting.

Human skin is a thin layer that blocks a certain amount and color of light, and it covers vibrant, red-colored flesh below its surface. The visible scatter distance for light-colored human skin is about 1.2 CM.

Metallic Input: The Metallic input channel is not available when using a Subsurface Profile because the GBuffer space for the Metallic input has been repurposed to accommodate the Subsurface Profile data.

Opacity Input: The Opacity input channel is used to mask the Subsurface scattering contribution. It works by using a value in the 0 to 1 range to allow for smooth transitions between different areas of Subsurface scattering intensity, where 0 is no scattering, and 1 is full scattering.

To better control where the Subsurface scattering is stronger or weaker, it is best to use a mask texture.Areas in the mask Texture that have values closer to 1, or white, will have the strongest Subsurface scattering effect while areas that are closer to 0, or black, will have less of an effect. Adjusting the Subsurface Color will help to compensate if areas get too dark. Remember that using brighter colors results in more Subsurface scattering.

Here you can see how the mask can be used to render two surface types with one material. Note that the transition is soft and not limited to triangle borders.



Click for full image.

Full-Resolution Skin Shading

Unreal Engine supports full-resolution skin shading for the Subsurface Profile shading model. This provides high-fidelity lighting for surface details, such as pores and wrinkles.





Previously, lighting on the skin was represented using a checkerboard pattern, where half the pixels used only Diffuse lighting and the other half used Specular lighting. The lighting was recombined during a final Subsurface profile fullscreen pass. That approach gave good results for Subsurface lighting (which is low-frequency by nature), but it could result in lower-fidelity lighting for surface details. With the new approach, every pixel contains Diffuse and Specular lighting information, packed into an RGBA encoding. This allows us to reconstruct full-resolution lighting during the final Subsurface profile fullscreen pass, giving better results for surface details and more stable behavior with Temporal Antialiasing.

Compatibility

Full-resolution skin shading requires at least a 64-bit scene color format with a full alpha channel. The default FloatRGBA Scene Color format works fine, but 32-bit representations such as FloatRGB are not supported. If the scene color format is not compatible with full resolution skin, we fall back to checkerboard-based lighting.

This behavior can be overridden using the r.SSS.Checkerboard console variable. The possible values for this are:

Property Name

Value

Description

r.SSS.Checkerboard

0

Checkerboard disabled

r.SSS.Checkerboard

1

Checkerboard enabled (old behavior)

r.SSS.Checkerboard

2

Automatic (default) - Full resolution lighting will be used if the scene color pixel format supports it.

Limitations

It's worth noting that the full-resolution skin shading is an approximation. It works well in the vast majority of cases, but certain material features can be problematic due to the encoding method. In particular:

Metallic Materials

Emissive Materials

These features will work, but you may notice differences in output compared to checkerboard due to the packed RGBA diffuse/specular encoding. It is possible to work around some issues when authoring materials by setting the Opacity to 0 in areas where skin shading is not desirable. Pixels with an Opacity of zero are treated as default lit for shading.

Masking non-opaque pixels in this way is also worthwhile for performance reasons since these pixels are bypassed by the Subsurface Postprocess.

Performance Considerations

If your title has a 64-bit scene color format, full-resolution Subsurface lighting will typically be faster than checkerboard due to the reduced number of Texture fetches. However, if your title has a 32-bit scene color, the performance gain from the reduced Texture bandwidth will likely outweigh the benefits (although this is hardware dependent).

Technical Details

Currently, e Subsurface scattering profile shading model does not differ much from Lit (Lambert diffuse, GGX for specular, no Metallic). Most of the effect happens in a post process after all lighting has been computed.

The Subsurface scattering profile is based on work from Jorge Jimenez. Make sure to check out his web page for useful tips on how to make your 3D images look more realistic.

We separate the non-specular (non-view dependent) lighting contributions to support a specular on top of Subsurface Material and down sample for better performance. Similar to a Gaussian blur, we filter the image with a two-pass (assuming a separable kernel) post process. The filter kernel depends on the Subsurface scattering profile which is stored in the GBuffer (Max 255 active profiles per scene). The kernel has colored weights and specific sample positions which can be scaled in the profile (defined in units/cm). In the final step, we recombine the scattered light contribution with the full resolution image. To separate the view-dependent and non-view-dependent lighting, we store a weighting value in the scene color alpha channel. This approximation requires a 64-bit render target (see r.SceneColorFormat), and this approximation works for most cases.

It successfully takes out the specular, but you get a more desaturated on view dependent color for those specular pixels. This can be improved by using two 32-bit render targets for all lighting passes. That has the same memory bandwidth, but on some hardware, this might be slower. This might be something we want to change (added code complexity).

Here we have an example where the Specular was removed before the blurring was applied. Notice how the Specular reflection is crisp and smooth in the end image (image on the far right). This is the effect we wanted to achieve.



Click for full image.

Here we have an example where the Specular was not removed before the blurring was applied. Notice how the Specular reflection is dull and looks a bit stretched in the end image (image on the far right). This is not the correct way to render this effect.



Click for full image.

Scalability and Console Commands

There are some scaling and performance console commands that you can use to help you get a good trade off between high quality visuals and better performance.

r.SSS.Scale: Can be used to scale the effect for quick experiments. Setting this to 0 will disable the effect. Setting numbers higher than 0 will increase the effect that can be seen in the image sequence below.

Dragging the slider will show what happens when r.SSS.Scale is set from 0 to a value of 10.



r.SSS.SampleSet: Sets the number of samples used. Decreasing this will cause the effect to run faster. However, this will mean that the effect will have a lower quality, and rendering artifacts could show up.





The following image shows a bit more of the internals of the system. This view can be enabled using ShowFlag.VisualizeSSS 1.



Click for full image.

While the Subsurface scattering profile shading model is a step forward when it comes to rendering skin, there are some limitations in what it can do. Please note that as this system becomes more and more polished, this list could change.

The feature does not work in the non-deferred (mobile) rendering mode.

Setting a large screen to scatter radius will show banding artifacts in extreme lighting conditions.

Currently, there is no backscatter of light.

Currently, a gray outline appears when non-SSS Materials occlude SSS Materials.

Subsurface Profile Property Reference



Property Name

Description



Burley Normalized



Surface Albedo

This should be set to match the base color of the corresponding material as closely as possible.

Mean Free Path Color

Controls how far light goes into the subsurface in the red, green, and blue channel. It is scaled by the Mean Free Path Distance.

Mean Free Path Distance

Controls the distance that Mean Free Path Color goes into subsurface.

World Unit Scale

Controls the scale of world/Unreal Units in centimeters (cm).

Enable Burley

Effective only when Burley



Subsurface Profile



Scatter Radius

The distance in world space units to perform the scatter.

Subsurface Color

The Subsurface Color can be used as a weight for the Subsurface effect. Black means there is no Subsurface scattering. White means all lighting is entering the material and gets scattered around. A non-grayscale value gives more control over what color contributions are entering the surface, resulting in a more complex looking shading.

Falloff Color

The Falloff Color defines the material scattering color once the light has entered the material. You should avoid using a vivid color here if you want to get a more complex shading variation over the area where you see the scattering.

Boundary Color Bleed

Controls how one subsurface material blends into another.



Transmission



Extinction Scale

Controls the absorption scale.

Normal Scale

Controls the normal contribution to transmission.

Scattering Distribution

Controls the scattering distribution for the transmission results.

IOR

Sets the index of refraction on the transmission results.

Transmission Tint Color

Controls the transmission tint by multiplying it on the transmission results. Requires that Enable Burley box to be enabled in the Burley Normalized category.



Dual Specular



Roughness 0

Controls the softer lobe's roughness.

Roughness 1

Controls the tighter lobe's roughness.

Lobe Mix

Controls roughness values for two separate lobes that are combined for the final results. When combined these provide a nice subpixel micro frequencies in the skin for a natural look. Use Roughness 0 and Roughness 1 to control the separate lobes for Dual Specular

Special Thanks

Special thanks to Lee Perry-Smith and his company Infinite Realities for providing the head model and assistance. Also a very special thanks to Jorge Jimenez for releasing his implementation as this feature is based on his work.

Special thanks to Mike Seymore and 3Lateral for their contributions with the "Meet Mike" digital scan.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Inputs and Material Properties

Base Color

Metallic

Specular

Roughness

Anisotropy and Tangent

Emissive Color

Opacity

Opacity Mask

Normal

World Position Offset

Subsurface Color

Custom Data

Hair

Cloth

Eye

Clear Coat

Ambient Occlusion

Refraction

Pixel Depth Offset

Shading Model

This page documents all the available inputs on the Main Material Node. By feeding data (by way of constants, parameters, and textures) into these inputs, you can define the surface properties of your Material and create an almost infinite variety of physical surfaces.

Not all inputs are required for every Material, and some Material types require inputs that are not visible on the Main Material Node by default.

Inputs and Material Properties

When you change certain Material properties in the Details panel, you will notice that some inputs on the Main Material Node turn white (indicating that they are enabled), while others are grayed out.

Three material properties control which inputs are enabled in the Material:

Blend Mode - This controls how your Material blends with the pixels behind it.

Shading Model - This defines how light is calculated for the surface of the Material.

Material Domain - This dictates how the Material is intended to be used. For instance, whether it is meant to be part of a surface, a Light Function, or a Post Process Material.

If an input you need for your Material is disabled, it is because one or more of the above properties is set incorrectly. For example, if you are trying to make a pane of glass, but the opacity input is disabled. The solution in that example is to change the Blend Mode to Translucent.

Base Color

Base Color defines the overall color of the Material. In principle, Base Color should represent the diffuse light reflected off a surface, minus any specular reflections/highlights.

If taken from the real world, base color textures should be photographed using a polarizing filter. Polarization removes the specular of nonmetals when aligned.



Metallic

The Metallic input controls how 'metal-like' your surface will be. Metallic accepts any value between 0 and 1, but in a majority of cases Metallic is considered an either/or property.

Nonmetals have a Metallic value of 0.

Metals have a Metallic value of 1.

For pure surfaces, such as pure metal, pure stone, or pure plastic this value will be 0 or 1, not anything in between. When creating hybrid surfaces like corroded, dusty, or rusty metals, you may find that you need some value between 0 and 1.

Metallic values of 0, 0.5, and 1.



When using metallic masks, the values in the texture should be pure black or pure white. Only use grayscale values if you specifically mean to create a blend (corroded metal, for example).

Specular

Specularity is a measure of how much light a surface reflects. The Specular input takes a value between 0 and 1, and defines the extent to which a surface is reflective:

Value of 0 - Fully non-reflective

Value of 1 - Fully reflective

The default value is 0.5, which represents approximately 4% reflectivity.

Specular values of 0, 0.5, and 1



Roughness

The Roughness input controls how rough or smooth a Material's surface is. Rough Materials scatter reflected light in more directions than smooth Materials. This value controls how blurry or sharp a reflection is (or how broad or tight a specular highlight is).

A Roughness of 0 (smooth) results in a mirror-like reflection.

A Roughness of 1 (rough) results in a diffuse or matte surface.

Roughness values of 0, 0.5, and 1.



Most surfaces are not uniformly rough or smooth. Roughness is a property that is frequently mapped on your objects in order to add physical variation to the surface.

Scratches on metal, scuffs on a wood floor, or fingerprints on plastic are examples of materials that would require a roughness map.



Anisotropy and Tangent

The Anisotropy and Tangent inputs enable you to control how anisotropic the roughness of the Material is and its light directionality. These two inputs are used to recreate the anisotropic effect of something like brushed metal.



Without using the Anisotropic and Tangent inputs, materials have an isotropic response. This is also true when the anisotropic input has a value of 0.





The anisotropic response is controllable using a value between -1.0 and 1.0, where a value of 0 has no anisotropic effect.

Anisotropic materials are enabled by default but can be disabled using the console command r.AnisotropicMaterials. When enabled, anisotropy works with supported Gen5 platforms, and when scalabiltiy settings are High, Epic, or Cinematic.

Dragging the slider shows the anisotropic response positively increasing from 0.0 to 1.0.



Use the Tangent input to define light directionality with a texture or Vector expression.

Emissive Color

The Emissive Color input controls which parts of your Material will glow or emit light, and the brightness of the emission. Ideally this input will receive a masked texture (mostly black except the areas that need to glow).

Values greater than 1 are allowed as HDR lighting is supported.



Opacity

The Opacity input is enabled when the Translucent Blend Mode is selected, typically for Translucent, Additive, and Modulated Materials.

0.0 represents a completely transparent Material.

1.0 represents a fully opaque Material.

Fractional values between 0 and 1 produce semi-transparent or translucent Materials.

Opaque and masked blend modes also use Opacity when using one of the subsurface shading models.



Opacity is mostly used for Translucent, Additive, and Modulated Materials.

Opacity Mask

Opacity Mask is similar to Opacity, but is only available when using the Masked Blend Mode.

Unlike the opacity input, the opacity mask does not allow for partial or intermediate transparency levels. When using an opacity mask, regions of the Material are either fully visible, or fully invisible. This makes it a good solution when you need Materials that define complex solid surfaces such as wire mesh, chain link faces, and so on.



The Opacity Mask Clip Value property allows you to set the value at which clipping takes place. For example, if the Opacity Mask Clip Value is set to 0.5:

Pixels with a value greater than 0.5 on the Opacity Mask become fully opaque.

Pixels with a value lower than 0.5 on the Opacity Mask become fully transparent.

See the Masked Blend Mode documentation for more details.

Normal

The Normal input takes in a normal map, which is used to add significant physical detail to the surface by modifying the "normal," or facing direction, of each individual pixel.



In the image above, both weapons are using the same Static Mesh. The lower one employs a highly detailed normal map, which provides additional detail. This gives the illusion that the surface contains many more polygons than are actually being rendered.

Typically, normal maps are often created from high-resolution modeling packages.



World Position Offset

The World Position Offset input allows a Material to manipulate the vertices of a mesh in world space. This is useful for making objects move, change shape, rotate, and a variety of other effects. World Position Offset is often used for subtle, ambient animation.

The above network causes the sphere to grow and shrink along its vertex normals with a sinusoidal period of one second.

When using World Position Offset to expand your object beyond its original bounds, keep in mind that the renderer still uses those original bounds. This means that you may see culling and shadowing errors. You may go into the properties of a mesh and set its Scale Bounds property to compensate, though this has a draw on performance and may lead to shadowing errors.

Subsurface Color

The Subsurface Color input is only enabled when the Shading Model property is set to Subsurface. This input allows you to add a color to your Material to simulate shifts in color when light passes through the surface.

For example, human skin shaders often use a red Subsurface Color to simulate blood beneath the surface. Subsurface skin effects are most noticeable in extremities like the tip of the nose, fingers or earlobes when backlit by a strong light source.



Custom Data

The Custom Data Material inputs are disabled by default, and are only enabled when certain Shading Models are in use. The Custom Data slots are populated with context-specific inputs that support the unique needs of some Shading Models.

For example, if you select the Eye shading model, the Custom Data inputs become Iris Mask and Iris Distance.



Shading Models that use the Custom Data inputs include:

Clear Coat

Subsurface Profile

Hair

Cloth

Eye

Hair

The Hair Shading Model is used to better simulate the translucent nature of hair. This shading model approximates the way light passes through hair, accounting for the fact that strands of hair are not perfectly cylindrical.

Additionally, instead of rendering a unified specular highlight, the specular reflections are independently placed based on the direction that the hair is pointing.



When the hair shading model is selected, three inputs are enabled on the Main Material Node:

Scatter: This input controls the amount of light scatter that is allowed to happen through the hair.

Tangent: This input replaces the Normal input and is used to control the normal direction along the U and V texture coordinates.

Backlit: This input controls the amount of backlighting that affects this hair material.

For an example of hair set up using this Shading Model, see the Digital Humans documentation and sample project available on the Epic Games Launcher in the Learn tab.

Cloth

The Cloth Shading Model can be used to better simulate cloth-like materials that have a thin layer of fuzz over the surface of the Material.



The Cloth Shading Model opens up two inputs on the Main Material node:

Fuzz Color: This input enables you to add color to your Material to simulate shifts in color when light passes through the surface.

Cloth: This input enables you to control the strength of the Fuzz Color as a mask. A value of 0 indicates no fuzz color contribution to the Base Color, whereas a value of 1 blends fully over the Base Color.

Eye

This is an advanced shading model that is highly technical and has very strong dependencies between shader code, the Material, the shape of the geometry and its UV layout. Epic recommends using our Digital Humans sample project as a starting point when developing your own eye assets or migrating them directly from this project.

The Eye Shading Model is designed to simulate that of an eye's surface.



The Eye Material Instance below has been set up to expose artistic cotnrol over the different biological parts of the eye shader that can be found in the Digital Humans sample project.



Click image for full size.

The Eye Shading Model adds two additional inputs to the Main Material node:

Iris Mask: This helps control the index of refraction and depth of the iris.

In the Material M_EyeRefractive in the Digital Humans sample project, see the IOR and Depth Scale parameters.

Iris Distance: This controls the concavity of the refracted iris.

In the Material M_EyeRefractive in the Digital Humans sample project, see the Iris Concavity Scale and Iris Concavity Power parameters.

Clear Coat

The Clear Coat Shading Model is used to better simulate multilayer materials that have a thin translucent layer of film over the surface of the Material. You can use Clear Coat with either metal or non-metal surfaces.

Examples of clear coat Materials include lacquer clear coats (used on furniture, for example), or colored films over uncolored metal, such as with car paint or soda cans.



The Clear Coat Shading Model enables two new Material inputs on the Main Material Node:

Clear Coat: Amount of clear coat layer, 0 acts like the standard shading model, 1 is the full clear coat model. This is useful for masking.

Clear Coat Roughness: Roughness for the clear coat layer. Our approximation is accurate for small values. Very rough clear coat layers are supported but will not be very accurate compared to their real world counterparts.

Ambient Occlusion

The Ambient Occlusion input is used to help simulate the self-shadowing that happens within the crevices of a surface. Generally this input will be connected to an ambient occlusion texture map of some kind, which is often created within 3D modeling packages such as Maya, 3ds Max, or Zbrush.



Note that this input relies on light sources using Static or Stationary mobility to generate built lighting. This material input is silently ignored when its Material is used in conjunction with any Movable light sources.

Refraction

The Refraction input takes in a texture or value that simulated the index of refraction of the surface. This is useful for things like glass and water, which refract light passing through them.

In the graph pictured above a Fresnel Material function is used to blend between two different IOR values.



Common Indices of Refraction

Air

1.00

Water

1.33

Ice

1.31

Glass

1.52

Diamond

2.42

Pixel Depth Offset

The Pixel Depth Offset input is used to control pixel depth in the shader graph using logic you set up. This enables you to create your own logic to blend or fade objects based on their scene depth.



In this comparison, using Pixel Depth Offset with the DitherTemporalAA Material Function enables you to set an "offset" value that blends the ground with the object intersecting it using a stipple pattern texture.





Shading Model

This input requires you to select the From Material Expression Shading Model in the Material Details panel.

The Shading Models input enables you to use logic in your Material Graph to select from a list of available Shading Models to use for part of your Material. This input is useful when you have a single object that needs to use multiple shading models, like Clear Coat and Default Lit. This can reduce the number of Materials required, in turn, saving performance and draw calls. All of this can be driven by logic in your Material using the Shading Model expression node and some texture masks.

The following is a simple example using an If expression to choose between Shading Models.



Using this example, when A is greater than B, the resulting shading model is Default Lit. When A is less or equal to B, a texture mask is used to display Default Lit and Clear Coat shading models on parts of the mesh.





For more information and examples of this inputs usage, see the From Material Expression page.

Material Expressions Reference

Material Editor UI

Placing Material Expressions and Functions

Using the Main Material Node

Previewing and Applying your Materials

Organizing a Material Graph

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Material Creation Workflow

Creating a new Material

Using the Material Editor

Live Update Options

Compiler Errors

Material Graph Search

The Material Editor is a node-based graph interface that enables you to create shaders or Materials for your project. Materials define the appearance and surface properties of the objects in your scene, including Static and Skeletal Meshes, Landscapes, UI, and VFX.

The pages of this user guide will introduce you to the Material Editor interface while providing a high level overview of Material creation in Unreal Engine.

It is recommended that you read the Essential Material Concepts page before continuing below. This page provides critical background information about the Materials workflow in Unreal.

Material Creation Workflow

A very simple demonstration of the Material creation process is shown in the video below.

As shown above, these are the steps to create a simple Material:

Create a new Material asset in the Content Browser.

Open the Material Editor.

Place Material Expressions and Functions in the Material Graph.

Connect Material Expressions to inputs on the Main Material Node to define the Material's attributes.

Compile and Save the Material.

Apply the Material to objects in the Level.

The bulk of the Material creation process occurs during steps three and four, and this is where you perform most of the work that goes into defining a specific type of surface and adding your creative touches. Material Expressions and Functions are the building blocks of Unreal Materials, with each one performing a specific action in the Material graph. By combining these nodes in unique ways you can define an endless array of physical surfaces.

Creating a new Material

There are two ways to create a new Material asset:

Click the Add (+) button on the left side of the Content Browser and select Material from the list.



You can also right-click anywhere in the background of the Content Browser and select Material from the context menu.



A Material is created in the Content Browser. Rename the Material and then double-click the thumbnail to open the Material Editor.



The Material Editor opens.



Using the Material Editor

The five pages linked here provide detailed information about how to use the various parts of the Material Editor. These documents elaborate on the steps shown in the video at the top of the page, and are meant to teach you the practical mechanics of Material creation. It is recommended you read them in the order presented below to gain a thorough understanding of how to interact with the tools available in the Material Editor.



A breakdown of the Material Editor user interface.



Guide for placing Material Expressions and Functions inside the Material graph.



Guide for setting up and using the Main Material Node



A guide for previewing Materials and applying them to Actors.



How to use commenting, reroutes, and other strategies to organize Material Graphs and keep them easy to read and edit.

Live Update Options



When making changes to a Material network, it is useful to see immediate feedback from each change in realtime. The Material Editor offers three options under the Live Update menu to control which elements in the Material Editor update in real time — Preview Material, Realtime Nodes, and All Node Previews.

Each of these options gives you the ability to toggle instantaneous feedback for a different part of the Material Editor.

Preview Material - This option allows for any changes to update automatically in the Material Preview viewport in real time without having to use the Save or Apply buttons.

Realtime Nodes - Nodes affected by time-based functions, such as panners, will update in realtime.

All Node Previews - This option allows for each node within the network to have its shader recompiled whenever a change is made. These changes include creation of new nodes, deletion of nodes, node connections and disconnections, and changes in properties. This recompilation is necessary so that the Material Preview drawn at that node is up to date. However, recompiling these intermediate shaders can be time-consuming, especially if your Material contains a large network. If you're experiencing long wait times after every change, you may want to deactivate All Node Previews option.

Consider the example below, in which a panning grid texture is multiplied by a vector expression, which supplies color.

In this example, activating Realtime Nodes causes the texture to pan in real time in the node's preview thumbnail. If Realtime Nodes is deactivated, the texture remains stationary even though the Panner is telling it to move. You may, however, notice small updates as you move your mouse around the graph area.

If you change the color in the vector expression, the change only appears in downstream nodes if All Node Previews is enabled. With this option disabled, the change in color does not propagate to node thumbnails even though the color in the vector expression indeed changed.

When All Node Previews is deactivated, you can force-update all previews manually by pressing Spacebar. Fast iteration can be achieved by disabling All Node Previews and then pressing spacebar whenever you want to view your changes.

Compiler Errors

Each time a change is made to the Material network, the Material must be compiled to see the changes. Compiler errors occur if any required inputs on an expresssion within the Material networks are passed the wrong type of data, or do not receive any connections.

These types of errors are indicated in two places.

The node that is generating the error will display "ERROR!" along its bottom.

The Stats panel will also display an error message that identifies what is causing the compiler to fail. If your Stats window is not opened, you can open it by going to Window > Stats.

Compiler errors let you know that a problem exists and provide information about the type of Material expression they occurred on and the description of the error.



Sine node displays an error message becuase a required input is not receiving any data. This error is also displayed in the Stats panel.

Material Graph Search

The search functionality in the Material Editor enables you to quickly find any nodes (including comments) within the Material network that contain a specific piece of text in their description or certain other properties specific to individual types of nodes. This makes it easy to add identifying keywords to nodes and jump to them at a later time without sifting through the network of nodes in your graph haphazardly.

You can open this tab by going to Window > Find Results.

Typing a full or partial keyword into the search box will perform a search against the properties of the nodes present within you your material graph. The currently selected result will be brought into view and highlighted.

Searches are performed against the following property values:

Searched Properties

Expression Type

Desc

All Nodes

Texture

Texture Sample

ParamName

Parameters

Text

Comment

Font

Font Sample

Material Function

MaterialFunctionCall

You can also search for specific types of expressions by using the NAME= switch with your search. For example, to find all texture samples, you could use the following search:

When a new match is clicked in the Search panel, it is brought into view in the graph table if it is not already visible.

To clear a search, click the Clear (X) button.

Material Inputs

Material Editor User Guide

Material Editor UI

Essential Material Concepts

Material Properties

Menu Bar

File

Edit

Asset

Window

Tools

Help

Toolbar

Viewport Panel

Details Panel

Material Graph Panel

Palette Panel

Stats Panel

HLSL Code Panel

Platform Stats

Graph Controls

Mouse Controls

Keyboard Controls

Hotkeys

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

The Material Editor UI consists of a menu bar, a toolbar, and the five main regions shown below.



Number

Description

1

Menu Bar

2

Toolbar

3

Viewport Panel

4

Details Panel

5

Material Graph Panel

6

Stats Panel

7

Palette Panel

You can close any panel by clicking the small "X" in the upper-right corner of the tab. You can also hide any panel by right-clicking on the tab, and then clicking Hide Tab in the context menu that appears. To once again display a panel that you have closed, click that panel's name in the Window menu.

Pressing F1 displays the Unreal Engine Materials documentation.

Menu Bar



File

Open Asset - Opens the Global Asset Picker to quickly find an asset and open the appropriate editor.

Save All - Saves all unsaved levels and assets for your project.

Choose Files to Save - Brings up a dialog box that allows you to choose which levels and assets you want to save for your project.

Save - Saves the asset you are currently working on.

Save As - Saves this asset under a different name.

Edit

Undo - Undoes the most recent action.

Redo - If it was the last action taken, this option redoes the most recent Undo.

Undo History - Shows the history of the Undo actions.

Editor Preferences - Gives you a list of options, any of which open that part of the Editor Preferences window, where you can modify your Unreal Editor preferences.

Project Settings - Gives you a list of options, any of which open that part of the Project Settings window, where you can modify various settings for your Unreal Engine project.

Plugins - Opens the Plugins Browser tab.

Asset

Find in Content Browser - Locates and selects the current asset in the Content Browser.

Reference Viewer - Launches the reference viewer showing the selected assets' references.

Size Map - Displays an interactive map showing the approximate size of this asset and everything it references.

Audit Assets - Opens the Asset Audio UI and displays information about the selected assets.

Shader Cook Statistics - Opens the Shader Cook statistics UI.

Window

Graph - Toggles the Graph panel display.

Viewport - Toggles the Viewport panel display.

Details - Toggles the Details panel display.

Palette - Toggles the Palette panel display.

Find Results- Allows you to search for items in the Material Graph.

Preview Scene Settings - Opens a tab that allows you to change the Material preview viewport options.

Parameters- Toggles displaying the Materials global parameters.

Custom Primitive Data- Opens a tab that displays all parameters in the current Material with Custom Primitive Data enabled.

Layer Parameters- Displays all Material Layers added to the current Material.

Platform Stats - Toggles displaying the Material cost per platform.

Stats - Toggles the Material cost.

Shader Code - Toggles displaying the Material HLSL code for the selected platform.

HLSL Code - Toggles displaying the HLSL code.

Desktop - Toggles displaying the HLSL code for the various desktop renders.

DirectX SM5 - Toggles displaying the HLSL code for Windows SM5.

DirectX SM6 - Toggles displaying the HLSL code for Windows SM6.

DirectX ES 3.1 - Toggles displaying the HLSL code for ES 3.1.

Vulkan SM5 - Toggles displaying the HLSL code for Vulkan SM5.

Metal SM5 - Toggles displaying the HLSL code for Metal SM5.

OpenGL SM4 - Toggles displaying the HLSL code for OpenGL SM4**.

Android - Toggles displaying the HLSL code for the various Android renders.

Android GLES 3.1 - Toggles displaying the HLSL code for Android GLES 3.1.

Android Vulkan - Toggles displaying the HLSL code for Android Vulkan**.

Android Vulkan SM5 - Toggles displaying the HLSL code for Android Vulkan SM5.

iOS - Toggles displaying the HLSL code for the various iOS renders.

Metal SM5 - Toggles displaying the HLSL code for Metal.

Metal MRT - Toggles displaying the HLSL code for Metal MRT.

Cinematics - Open the Cinematics Sequence Recorder, Takes Recorder, or Takes Browser in a new window.

Content Browser - Opens the Content Browser in a separate window.

Virtual Production - Open the LIve Link streaming manger tab.

Reset Layout - Resets your layout to a default arrangement. Requires the editor to restart after saving your changes and creating a backup of your settings.

Save Layout - Saves the current layout of the panels as the new default layout.

Remove Layout - Removes the current layout.

Enable Fullscreen - Enables fullscreen mode for the application, expanding across the entire monitor.

Tools

New C++ Class - Adds C++ code to the project. This code can only be compiled if you have Visual Studio installed.

Generate Visual Studio Project - Generates your C++ code project in Visual Studio.

Find in Blueprints - Find references to functions, events and variables in all Blueprints.

Cache Statistics - Displays statistics about the Derived Data Cache.

Class Viewer - Displays all classes that exist in this project.

CSV to SVG - Opens a tool for generating vector line graphs from comma-separated value files generated from CSV profiles.

Localization Dashboard - Opens the localization dashboard for this project.

Merge Actors - Opens the Merge Actors dialog.

Project Launcher - Opens the Project Launcher tab.

Resource Usage - Displays derived data resource usage breakdown.

Session Frontend - Opens the session frontend tab.

Struct Viewer - Displays all structures that exist in this project.

Virtual Assets - Displays statistics about any virtual assets within this project.

Debug - Debugging tools for Blueprints, collisions, Niagara and more.

Profile - Open the Profile Data Visualizer or the Trace Data Filtering tab.

Audit - Open the Asset Audit window or the Material Analyzer.

Platforms - Open the Device Manager or Device Profiles UI.

Source Control - Connect to Source Control, view changelists, or submit content.

Run Unreal Insights - Run the Unreal Insights standalone application.

Help

Material Editor Documentation - Opens a browser window and navigates to the documentation about this tool.

Documentation Home - Opens a browser window and navigates to the documentation home page.

Online Learning - Opens a browser window and navigates to the Unreal Online Learning home page.

Forums - Go to the Unreal Engine forums to view announcements and engage in discussions with other developers.

Answer HUB - Go to the AnswerHub to ask questions, search existing answers, and share your knowledge with other Unreal Engine developers.

Support - Opens a browser window to the Unreal Developers Network (UDN) forum page where you can ask a question about the Unreal Engine.

Report a Bug - Opens a browser window and navigates to the Unreal Engine Bug submission form.

Issue Tracker - Opens a browser window and navigates to a searchable database of Unreal Engine issues and fixes.

About Unreal Editor - Displays application credits, copyright information, and build information.

Credits - Displays application credits.

Visit UnrealEngine.com - Navigates to UnrealEngine.com where you can learn more about Unreal Technology.

Toolbar



The following table lists the options in the Toolbar and what they do.

Icon

Description



Saves the current asset.



Finds and selects the current asset in the Content Browser.



Applies any changes made in the Material Editor to the original Material and any uses of that Material in the world.



Finds expressions and comments in the current Material.



Centers the Main Material node in the Material Graph panel.



Displays a list of all Material Instances using the current Material as a parent.



Toggle which elements in the Material Editor UI will update in realtime.



Deletes any Material nodes that are not connected to the Material.



Preview the graph state for a given feature level, Material quality, or static switch value.



Hides all nodes that are not related to the selected nodes.



Shows or hides Material statistics in the Stats panel.



Toggles the window that shows Material stats and compilation errors for multiple platforms.

Viewport Panel



The Viewport panel displays the Material that you are currently editing.

You can navigate in the Viewport panel by using the options in the following table.

Action

Description

Drag with the left mouse button

Rotate the mesh.

Drag with the middle mouse button

Pan

Drag with the right mouse button

Zoom

Hold down L and drag with the left mouse button

Rotate the light direction.

You can change the viewport preview mesh using the associated toolbar controls (the five shape buttons in the bottom-right corner of the viewport). To use a custom preview mesh, select a Static Mesh actor in the Content Browser and click the brick icon in the viewport. The viewport mesh is saved with the Material so that the next time the Material is opened in a Material Editor, it will display the same mesh.

This table details the options available in the Material Editor preview viewport:

Icon

Description



Shows the result of your current Material on the respective primitive shape in the Preview panel.



Toggles the Material Viewport Options



Changes the type of Viewport that is used.



Changes the type of lighting the Viewport is using.



Enables additional options to the Material Viewport.

Details Panel



This panel contains a property window for all currently selected Material expression and function nodes. If no nodes are selected, the base properties of the Material are displayed.

See Material Properties for descriptions of all Material properties.

Material Graph Panel



This panel contains a graph of all Material expressions that belong to this Material. By default, each Material contains a single base Material node. This node has a series of inputs, each associated with a different aspect of the Material that other Material nodes can connect to.



See Material Inputs for descriptions of the various inputs on the Main Material node.

Palette Panel



The Palette panel contains a categorized list of all the Material nodes you can drag into your Material. To place a new Material node, drag it from the Palette into the Material Graph panel.

The Palette is hidden by default. Click the Palette tab in the upper-right corner of the Material Editor to display the Palette. Click the Pin icon if you want the Palette to remain visible while you work.



You can filter the Material nodes listed in the Palette panel by choosing either Expressions or Functions in the Category drop-down list.

For more information about Material functions, see Material Functions.

Stats Panel



The number of shader instructions used in the Material as well as any Compiler Errors are displayed in this panel. The fewer the number of instructions, the less costly the Material. Material expression nodes that are not connected to the base Material node do not contribute to the instruction count (cost) of the Material.

HLSL Code Panel



This panel shows the High Level Shader Language (HLSL) code that is generated by the current Material. Be aware that this is not an editor; you will not be able to change the HLSL code. Rather, this is merely a viewer to allow you to visualize the code defined by your Material network.

By default the Code View panel is not visible. To display the Code View panel, open the Window menu and click on HLSL Code.

Platform Stats

You can view the cost of your Material on various platforms by clicking on the Platform Stats icon.



You can view stats for each rendering API Unreal Engine suports by clicking on the Settings option and then selecting the renderer you want to see stats for.



In order to see stats for Android you will need to first install Mali Offline Compiler by doing the following:

Download and install the Mali Offline Compiler.

After installing the Mali Offline Compiler go to Edit > Editor Preferences in the menu bar.



Under Content Editors select Material Editor



Click the three dots to the right of the Mali Offline Compiler option, and then locate the malisc.exe file that was installed with the Mali Offline Compiler. The default file path is shown below.



After the previous steps are complete, you can see stats for the various Android renderers supported by Unreal Engine.



You cannot see the Android Platform stats without installing the Mali Offline Compiler.

Graph Controls

Controls in the Material Editor generally match the controls of other tools in the Unreal Editor. For example, you can navigate the Material Expression graph as with other node-based object editors (Blueprints). You can orient the Material preview mesh as per other mesh tools.

Mouse Controls

Control

Action

RMB drag on background

Pan Material expression graph

LMB drag on background

Box select

Rotate Mouse Wheel

Zoom in and out

LMB + RMB drag

Zoom in and out

LMB click on object

Select expression/comment

Ctrl + LMB on object

Toggle selection of expression/comment

LMB click + drag

Move current selection/comment

Ctrl + LMB drag

Box select (add to current selection)

LMB drag on connector

Create connection (release on connector)

Ctrl + LMB drag from connection

Move connection (release on same type connector)

Shift + single-click LMB on connector

Marks the connector. Performing the action again with a connector marked will create connection between the two connectors. This is a quick way of making connections over large distances.

RMB on background

Bring up New Expression menu

RMB on object

Bring up Object menu

RMB on connector

Bring up Object menu

Alt + LMB on connector

Break all connections to connector

Ctrl + LMB on connector

Add a new node along connector

Keyboard Controls

Control

Action

Ctrl + B

Find in Content Browser

Ctrl + C

Copy selected expressions

Ctrl + S

Save Material

Ctrl + V

Paste

Ctrl + D

Duplicate selected objects

Ctrl + Y

Redo

Ctrl + Z

Undo

Delete

Delete selected objects

Spacebar

Force update all Material expression previews

Enter

(same as clicking apply)

Hotkeys

You can use hotkeys to place commonly used Material expression types. Hold down the hotkey and left-click to drop in the node. The hotkeys are as follows:

Hotkey

Expression

A

Add

B

BumpOffset

C

Comment

D

Divide

E

Power

F

MaterialFunctionCall

I

If

L

LinearInterpolate

M

Multiply

N

Normalize

O

OneMinus

P

Panner

R

ReflectionVector

S

ScalarParameter

T

TextureSample

U

TexCoord

V

VectorParameter

1

Constant

2

Constant2Vector

3

Constant3Vector

4

Constant4Vector

Shift + C

ComponentMask

Material Expressions Reference

Material Functions Reference

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Material Expressions

Differences Between Expressions and Functions

Placing Material Expressions

Drag and Drop from the Palette

Right-Click Context Menu

Drag From An Input or Output Pin

Keyboard Shortcuts

Placing Material Functions

Placing Material Functions from Content Browser

Connecting Material Nodes

Conclusion

Continue Reading

Material Expressions and Material Functions are the building blocks used to create fully functional Materials in Unreal Engine. Each Expression or Function is a self-contained node in the Material graph. These nodes run small snippets of HLSL code on their inputs and output the results.

This page demonstrates the various ways to insert Material Expressions and Functions into your Material graph.

Material Expressions

Each Material Expression node contains a small set of HLSL instructions to perform a very specific task in the Material. Materials are built by combining Expressions and Functions to achieve a desired visual result.

For example, if you want to change the scale of a texture on your mesh, you can use a Multiply node. By multiplying a Constant value by the Texture Coordinates of a Material, you can manipulate the scale of the texture.

When the multiplication value is changed from 1 to 3, the texture is tiled three times across the surface instead of once.



This is a simple, but versatile piece of Material logic. When small node networks like this are combined you can ultimately create very sophisticated surface effects.

Differences Between Expressions and Functions

The main difference between Material Expressions and Functions is that Material Expressions are created directly in the source code of the engine, while Material Functions exist as editable assets in the Content Browser.

Material Expressions are static pieces of code that can only do what they are programmed to do. A Multiply node is programmed to multiply two values together. The only way you could alter its utility is to change it in the source code. There were four Material Expressions in the earlier example:



Constant — Holds a single numeric (float) value.

Multiply — Multiplies input A and input B and outputs the product.

Texture Coordinates — Outputs the UV texture coordinates of the Material in the form of a two-channel vector value.

Texture Sample — References an image texture and outputs the color value(s) of the texture.

Material Functions are more dynamic because you can configure them to perform any type of calculation you want. You can create and edit Material Functions without having to make source code changes.

If you double-click a Material Function node, the Material Function Editor opens. Within a Material Function you will find a self-contained node graph made up of Material Expressions.



A CameraDepthFade Material Function contains the Material graph pictured to the right.

Material Functions are one way to condense complicated Material logic into a single, easy to read node that can be used across multiple Materials. Functions are an excellent way to package repetitive Material graphs so that they can be shared and reused by other team members.

Placing Material Expressions

There are four ways to insert Material Expressions into the Material graph.

Drag and drop from the Palette

Right-click context menu

Drag from an input or output pin

Keyboard shortcuts

Drag and Drop from the Palette

The Palette is a collapsible sidebar panel on the right side of the Material Editor window. Click on Palette to expand the panel if it is not visible.



To keep the Palette visible at all times, click the pin icon.



Click the pin again to unpin the Palette. When unpinned, the Palette collapses after every action.

The Palette contains a list of all Material Expressions and Material Functions available in UE5. These are sorted into categories according to their general purpose.



You can search the Palette by typing a query in the search bar. The search filter updates progressively as you type and automatically highlights the closest match.



The Category menu lets you filter which node types are visible in the Palette.



Select Expressions to only show only Material Expressions in the palette.

Select Functions to show only Material Functions and hide Expressions.

All Material Expressions and Functions are visible by default.

You can drag any Material Expression or Function from the palette directly into your Material graph.

Left-click the name of a Material Expression in the palette and drag it into the Material graph with the left mouse button held down.



Release the left mouse button and the Material Expression is inserted at the pointer.



Right-Click Context Menu

You can also add Material nodes to your graph from the right-click menu. Like the Palette, the right-click menu contains a categorized list of all Material Expressions and Functions. The right-click menu has a search bar, but does not have a way to filter out Expressions or Functions.

Right-click anywhere in the background of the Material graph.



Browse the categories, or type a query into the search bar to find an Expression or Function.

Left-click the name of a Material Expression or Function to place it in your graph.



You can also press the Enter key to insert whichever Material Expression is currently highlighted in blue. Use the up and down arrows to select from the list, or refine your search terms.

Drag From An Input or Output Pin

A second way to access the context menu is to left-click and drag a wire from any input or output pin on an existing node in your graph. Release the left mouse button anywhere in the graph and the context menu appears. Use the search bar or browse the categories to find and spawn a node. One advantage to this method is that the Material Expression or Function is already wired correctly when it spawns, saving you a step.

Keyboard Shortcuts

There are a number of Keyboard shortcuts that you can use to quickly insert commonly used Material Expressions. To insert a Material Expression hold down a keyboard shortcut and left-click anywhere in the Material graph.

This table shows the default Material Expression keyboard shortcuts.

Keyboard Shortcut Key

Material Expression

A

Add Material Expression

B

Bump Offset Material Expression

1

Constant Material Expression

2

Constant2Vector Material Expression

3

Constant3Vector Material Expression

4

Constant4Vector Material Expression

D

Divide Material Expression

I

If Material Expression

L

Linear Interpolate Material Expression

F

Material Function Material Expression

M

Multiply Expression

N

Normalize Expression

O

One Minus Expression

P

Panner Expression

E

Power Expression

R

Reflection Vector WS Expression

S

Scalar Parameter Expression

S

Texture Sample Expression

U

Texture Coordinate Expression

V

Vector Parameter Expression

You can change the Material Expression keyboard shortcuts by going to Edit > Editor Preferences > Keyboard Shortcuts > Material Editor Spawn Nodes.

Placing Material Functions

In most cases you will use the same methods as above to place Material Functions in your graph. The Palette and right-click menu work the same for Material Functions as they do for Expressions.

There is one additional way to place Material Functions in your graph.

Placing Material Functions from Content Browser

One thing that is exclusive to Material Functions is that you can also drag and drop them from the Content Browser into your Material.

Find the Material Function you want to use in the Content Browser, then left-click and drag the asset into the Material graph. You can access the Content Browser from the Content Drawer at the bottom of the Material Editor, or from the main UE5 Editor window.

To find Material Functions in the Content Browser, you need to look in the Engine folder, which is not visible by default.

To display the Engine folder, click the Settings icon on the right side of the Content Browser, and check Show Engine Content.



Material Functions are found in the Content Browser at the path All > Engine > Content > Functions.



Connecting Material Nodes

Use the following steps to connect any two nodes in your Material graph.

Left-click and drag a wire from an input or output pin on the first node.



Release the left mouse button over a pin on the second node.

To delete a connection, hold the Alt key and click the wire between two nodes. You can also left-click the wire and press Delete.

You can move an existing wire from one pin to another. Ctrl+Click the connection you want to move and drag it to a different input or output.

Conclusion

Material Expressions and Functions are the primary building blocks of UE5 Materials. The engine includes hundreds of Material nodes, each designed to hold a specific type of data or execute a set of HLSL instructions. You will most likely find yourself using a small number of nodes very frequently. For example, the Material Expressions with keyboard shortcuts documented above are all fundamental to Material creation in UE5.

Material Expressions and Functions usually have tooltips to summarize their purpose, and most are documented on the Materials reference pages.

Material Expressions Reference

Material Functions Reference

Since Material Expressions are often pure HLSL code, you can also read the official Microsoft HLSL documentation for technical background information.

Continue Reading

Using the Main Material Node

Previewing and Applying your Materials

Material Inputs

Material Editor User Guide

Material Editor UI

Essential Material Concepts

Material Properties

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Material Inputs

Understanding Material Inputs

Enabled and Disabled Inputs

Nodes Connected to Disabled Inputs are Ignored

Main Material Node Details Panel Properties

Using the Main Material Node

Previewing and Applying Materials

Materials are created using a specialized coding language called High Level Shading Language or HLSL. HLSL allows Materials to send instructions directly to the graphics hardware, giving artists and coders control over what is displayed on screen. Inside Unreal Engine 5 (UE5) the Material Expression nodes that are used to create Materials contain small snippets of this HLSL code.

The inputs on the Main Material Node are the last stop in a UE5 Material graph. Whatever combination of Material Expression nodes is connected to the inputs on the Main Material Node is what determines the overall appearance of the final Material when it is compiled and used in your Level.



The Main Material Node with default inputs.



Material Inputs

Each input on the Main Material Node defines a single unique aspect of the appearance and surface properties of your Material. For example, if you connect a Constant3Vector to the Base Color input and give it a value of (1,0,0), you can make the Material red.



This Material graph only explicitly defines a single aspect of the Material—its Base Color.

However, the overall appearance of the Material is the collective result of all the enabled inputs in the Main Material Node. Enabled input pins are white on the Main Material Node, and disabled inputs are grayed out.



Inputs that do not receive any data from Material expressions in the graph simply revert to their default values. For example, even though there is nothing plugged into Metallic, Specular, or Roughness, these properties still contribute to the appearance of the Material.



Metallic defaults to 0 (non-metallic).

Specular defaults to 0.5.

Roughness defaults to 0.5.

Therefore, a Material with those values plugged into Metallic, Specular, and Roughness looks exactly the same as the one shown previously.

Slider: Note that the preview render does not change when default values are connected the the Main Material Node.



By changing the values, you can alter the appearance and surface properties of the Material. In the third image, the roughness value is changed from 0.5 to 0.07, and the Material appears more polished. Changing the values in the Constant3Vector to (0,0,1) makes the Base Color blue instead of red.

Understanding Material Inputs

UE5 uses a Physically Based Rendering (PBR) workflow for Materials, meaning Materials closely approximate the way surfaces interact with light in the real world. To create Materials effectively it is important to understand exactly how each input affects the final Material. These two pages provide foundational information about the PBR Materials workflow in Unreal Engine 5.

Read the Physically Based Materials overview to learn best practices for creating Materials in a PBR workflow.

Read the Material Inputs page for examples and descriptions of what each input on the Main Material Node does.

Enabled and Disabled Inputs

Some of the input pins in the Main Material Node are enabled by default, while others are disabled. The following properties in the Details Panel determine which inputs are enabled.

Material Domain

Blend Mode

Shading Model



Modifying any of these three Material properties can change the inputs that are enabled and disabled in the Main Material Node.

In the middle example, changing the Blend Mode from Opaque to Translucent enables the Opacity and Refraction inputs. It also disables any inputs that are not used by translucent Materials.



On the far right, selecting the Clear Coat Shading Model enables the inputs for Clear Coat and Clear Coat Roughness.

You must select the Main Material Node to access these properties in the Details panel. To select the Main Material Node, click it with the left mouse button or click anywhere in the background of the Material graph.

Nodes Connected to Disabled Inputs are Ignored

When switching between Blend Modes or Shading Models, some inputs may become disabled. Material Expressions remain connected to disabled inputs, but are ignored when the Material is compiled.

In this example, a constant value was connected to Opacity. The Blend Mode was changed from Translucent to Opaque, causing the Opacity input to become disabled.



The constant node remains connected to the Opacity input, but the cable and input are grayed out to indicate that the input is disabled. Nodes connected to disabled inputs do not affect the compiled Material in any way.

Main Material Node Details Panel Properties

When the Main Material Node is selected in the Material Editor, the Details panel displays a list of all editable properties relating to how the Material can be used.

As demonstrated above, properties like Blend Mode and Shading Model directly influence which inputs are enabled in the Main Material Node. Other sections let you modify how the Material interacts with specific platforms or rendering features.

Here is a brief breakdown of what each section in the Main Material Node Details panel does:



Section Name:

Description

Physical Material

This allows you to specify what type of Physical Material is used for this Material.

Material

This is where you will spend most of your time when editing Materials. The Material section is where you can change the Material Domain, Blend Mode, and Shading Model along with many more options.

Physical Material Mask

An array of Physical Material Maps to be used for this Material.

Translucency

This is where you can adjust how Translucency in this Material will function. Please note that this is only editable if the Material Blend Mode is set to Translucent.

Translucency Self Shadowing

This is where you can adjust how Translucent self shadowing looks and behaves. Please note that this is only editable if the Material Blend Mode is set to Translucent.

Usage

This is where you set what type of objects this Material will work with. Usage flags are usually set automatically by the editor. However if you know that this Material is supposed to be used with a certain object type, make sure you enable it here to avoid any future mistakes

Mobile

This is where you set how this Material should work when used on a mobile device like a smart phone.

Forward Shading

Per-material overrides for when the Forward Shading Renderer is in use.

Group Sorting

Allows you to change the order of Parameter Groups in your Material.

Post Process Material

This is where you define how this Material should work with Post Process and Tone Mapping. Please note that this is only editable if the Material Domain is set to Post Process.

Refraction

Properties to change the refraction mode and refraction depth bias.

Lightmass

This is where you can adjust how this Material will interact with Lightmass.

Previewing

Change the Static Mesh used to preview the Material in the Material Editor viewport.

Import Settings

A selection of import data types and options relevant to the selection for use with this Material.

Read more about these settings on the Material Properties page.

Using the Main Material Node

Inputs on the Main Material Node work exactly like any other Material Expression or Function in the Material graph.

To connect a Material Expression to an input in the Main Material Node:

Left-click the output pin of a Material Expression and drag the mouse to an input pin on the Main Material Node.



Release the left mouse button over the input pin when the green check icon appears.



If you do not know how to place Material Expressions and Functions in your Material graph, read here.

Previewing and Applying Materials

The Main Material node is the end-point of a UE5 Material graph. The information that you pass into the inputs on the Main Material node is what ultimately determines the appearance of the Material. As you connect Material expressions to the Main Material node, the preview in the Material Editor viewport updates continuously so you can evaluate your changes and make sure you are getting the desired results.

Continue reading about the various ways to preview Materials and how to apply them to the Actors in your Level.

Material Editor User Guide

Material Inputs

Material Editor UI

Material Properties

Essential Material Concepts

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Previewing in the Material Editor Viewport

Preview Scene Settings

Previewing a Specific Node in the Material Graph

Previewing Materials on a Custom Mesh

How to Apply Your Materials

Compile and Save

Drag-and-Drop

Apply a Material from the Details Panel

Previewing Material Parameters in the Level

Conclusion

Previewing and applying your Materials is of critical importance to the Material creation process because it allows you see the results of the changes you make in the Material Graph. This is something you should do quite often to make sure that you are getting the exact results you want. This guide explains how to preview your Materials in the Material Editor viewport, and then shows how to apply a Material to meshes in Unreal Engine.

Previewing in the Material Editor Viewport

The easiest way to preview a Material is in the Material Editor viewport window. The viewport window has a number of different options to customize the look and feel of the preview environment. The image below shows a breakdown of the viewport and its various options.



Number

Property

Description

1

Viewport Options

This menu contains a toggle to turn the Realtime preview on and off. Also contains viewport statistics, layout options, and field of view (FOV) settings.

2

Viewport Types

Switch between perspective and orthographic viewports.

3

View Modes

Choose from available View Modes and change exposure settings.

4

Viewport Show Flags

Show or hide the background, grid, and viewport stats.

5

Preview Mesh

This is a preview mesh that you can use to examine how your Material will look on different objects.

6

Preview Mesh Options

Select from five different preview mesh options: cylinder, sphere, plane, cube, or a custom mesh.

While inside the Material Editor, hover your mouse cursor over any icon to display a tooltip description explaining what each of the properties does. Some of these tooltips contain links to relevant documentation.

While you are creating your Materials in the Material Editor, the viewport window will show your changes immediately if you have the Realtime option enabled. Realtime is enabled by default. You can toggle this option on and off from the Viewport Options menu.



Adjust the values in any Material Expression currently hooked up to the Main Material Node to preview changes in the viewport.

When making changes to your Material Network, it can take some time for the changes to render correctly in the viewport. The more complex a Material becomes, the longer it can take for the preview window to update. If you find that you need a quicker update, consider making your Material into a Material Instance.

Preview Scene Settings

The Preview Scene Settings panel enables you to quickly preview your Materials in a variety of different environments and lighting conditions. This gives you a better understanding of how your Material will interact with light as the conditions change.

Go to Window > Preview Scene Settings in the menu bar enable the panel.



The Preview Scene Settings panel opens in the bottom left corner of the Material Editor next to the Details tab.



Preview Scene Settings contains options to alter the color, direction, and intensity of the viewport lighting. You can also change the background, and add basic post-processing effects.

This lets you view a Material under very different lighting conditions without changing anything in the Level.





Previewing a Specific Node in the Material Graph

There are times when you may want to see the results of a single node in your Material graph. For example, if you are creating a Material that uses the Fresnel Material expression, you might want to preview the node so you can accurately fine-tune the falloff of the Fresnel effect.

Right-click a Material Expression and choose Start Previewing Node from the menu to preview that node in the viewport.



The Fresnel node turns blue to indicate that it is currently being previewed. In the preview viewport you can clearly see the boundary of the Fresnel effect without any visual interference from other attributes like textures or reflections.



To stop previewing a node, right-click it and choose Stop Previewing Node.



Previewing Materials on a Custom Mesh

The Material Editor viewport provides four built-in preview mesh options: cylinder, sphere, plane, and cube. You can also preview your Material on a custom mesh.

Select any Static Mesh in the Content Browser.



Click the teapot icon in the bottom right corner of the Material Editor viewport to use the selected Static Mesh as the preview object.



How to Apply Your Materials

Compile and Save

The Material Editor viewport preview updates continually as you make changes to the Material network. However, before you can apply a Material to an object and view it within your level, it needs to be compiled. To compile a Material, click the Apply or Save button on the left side of the Material Editor toolbar.



This will update the Material to include the changes you were just previewing. You can then apply it to a mesh and view it in the Level.

There are two main ways that you can apply Materials to objects in Unreal Engine:

Drag-and-Drop

Select a Material from the Content Browser and then drag it directly onto any object in the Level.

Left-click and drag a Material from the Content Browser onto an object. Release the left mouse button while hovering over an object to apply the Material.



The new Material is applied to the object.



Apply a Material from the Details Panel

You can also apply a Material from the object's Details panel by clicking the Use selected asset from Content Browser button like in the following example:

Select a Material in the Content Browser.



Select an Actor in the viewport.



Click the Use Selected Asset from Content Browser button in the Materials section of the object's Details panel.



The new Material is applied to the object.



Previewing Material Parameters in the Level

The following feature requires you to use Scalar or Vector parameters, which can be updated dynamically without recompiling a Material. Read the documentation about Material Instances to learn about parameterization.

You can adjust Scalar and Vector parameters inside the Material Editor and see the results instantly in all 3D viewports.

This is especially useful for Material Functions that implement layers, as you can see the results of a tweak to the layer on all the Materials using that function instantly instead of having to wait for the Material to recompile.

To preview parameters in the Level, create a parameterized Material using Scalar or Vector Parameters and apply it to an object in your scene.

First make sure that the Material that you want to preview is applied to something in the level.

Inside the Material, make sure that you are using Scalar or Vector Parameters as inputs for the properties you want to change. Previewing like this will not work with Constant Material Expression nodes. Only parameters can be previewed in the Level without recompiling the Material. Make sure your parameters have unique, descriptive names.

To see the changes happen in real time in the Level viewport, adjust the value of the Scalar or Vector parameters inside the Material. The adjustments that you make are displayed, in real time, in the Level viewport.

Conclusion

As you can see, there are a number of different ways to preview and apply your Unreal Materials to ensure you are getting the desired results. Make sure you preview your Materials often, and consider adjusting the Preview Scene settings to see your Material in different lighting conditions. Remember that when you are finished editing a Material, you must click Apply and Save in the Toolbar to recompile, otherwise you run the risk of losing your work.



Material Expressions Reference

Material Functions Reference

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Material Editor Organization Tools

Commenting

Node Description

Comment Box

Comment color

Reroute Nodes

Named Reroutes

Creating Named Reroutes

Adding Named Reroute Usage Nodes

Convert Back to Traditional Reroute

Reroute Selection Options

Align and Distribute

Align

Distribution

Collapse Nodes

How to Collapse Nodes

Editing Collapsed Nodes

Expanding Collapsed Nodes

As Materials increase in complexity, the node graph can quickly become difficult to read and interact with. Complicated, unorganized graphs can be slow to edit, and difficult to comprehend when a Material is handed off from the primary author to another artist or developer.

Material Editor Organization Tools

Unreal Engine includes several tools to improve the organization of your Material graphs.

Commenting

Reroute Nodes

Named Reroutes

Align and Distribute

Collapse Nodes

Commenting

Comments are the easiest way to improve the readability of a Material graph. This Material isn't overwhelmingly complicated, but without annotations it would take a moment or two to interpret if it was passed off to a second artist.

A Material Graph network with and without comments.



Drag the slider to see the same Material annotated with comments. It is immediately apparent from the labels what each group of nodes is doing.

There are two ways to add comments to Materials.

Node Description

You can add a comment or description to any individual Material Expression or Function in the node graph.

Hover the mouse pointer over a node in the Material graph.

Left-click the Toggle Comment Bubble icon.



Enter a comment in the field.



Click the pin icon if you want the comment to remain visible as you zoom in and out of the Material Graph. This keeps the comment at a readable scale, even when zoomed out. You can click the Toggle Comment Bubble icon again to hide the comment.



Anything you type in the Comment Bubble will also appear in the Desc field in the Details panel for that node. This description remains visible even when the Comment Bubble is hidden.



Comment Box

You can use a comment box to group a selection of related nodes.



Select all the nodes you want to place in a comment box.

Press the C key to create a comment box around the selected nodes.

Type a name in the header field.

Comment boxes let you move all the nodes within the box as a single group. Left-click and drag the header bar to move a comment box.

You can add and remove nodes by dragging them in or out of the comment box.

Resize a comment box by dragging the corners or edges.

You can nest comment boxes within one another.

Comment color

Comment boxes have a color property in the Details panel.

Click the header bar of a comment box to access its Details properties.



Click the Comment Color swatch and choose a new color in the Color Picker dialog.



Reroute Nodes

Reroute nodes provide a way to modify the path of the wire between two Material expression nodes. You can also use a reroute node to split a wire in order to connect it to multiple inputs.

Double-click anywhere along the length of a wire to add a Reroute node.



To modify the path of the wire, hover over the Reroute node until the mouse displays a move icon.



Left-click and drag the node to a new location. Reroutes allow you to redirect wires around nodes that are in the way of the original path.



In this video a Reroute node is used to split a wire in order to feed it into three downstream inputs.

Named Reroutes

Named Reroutes let you simplify a Material graph by eliminating wire connections and routing information through input and output nodes instead. A Named Reroute is like a tunnel or portal from one region of the Material graph to another.

For example, this small cluster of nodes related to the Roughness map creates a relatively long wire across the middle of the Material graph. Using a Named Reroute you can eliminate the wire without affecting the flow of data.



Creating Named Reroutes

Double-click along a wire to add a Reroute node.



Right-click the node and choose Convert to Named Reroute from the context menu.



The wire connection disappears and two Named Reroute nodes are created at the beginning and end of the connection. Shown side by side you can see how a Named Reroute resembles a tunnel. Data flows into the first node, and exits through the second, which is called a Named Reroute Usage node.



The first node in a reroute is called the Named Reroute Declaration. It is extremely important to give this node a unique, descriptive name in the Details panel.



Select the Named Reroute Declaration node and enter a description in the Name field. You can also change the Node Color property if you want to color-code your reroutes.

Named Reroute output nodes can be passed into multiple inputs further downstream, or can be duplicated and used multiple times.

For example, earlier we used a Reroute node to pass the Global UV Controls into three downstream inputs.



If this pin is converted to a Named Reroute, three Usage nodes spawn instead of one.



Everything within the Global UV Controls comment box is now physically detached from the rest of the node network. You can move it anywhere in the graph and the data will still flow through the Named Reroute into the Albedo, Roughness, and Base Normal UVs.



Or if you prefer you could use a single Named Reroute output node and feed it into all three UV inputs.



Adding Named Reroute Usage Nodes

You can add additional Named Reroute Usage nodes from the right-click menu or the Palette.

Any Named Reroutes in your Material appear at the very top of the menu. You can also duplicate existing reroute nodes by selecting them and pressing Ctrl+D.



Convert Back to Traditional Reroute

You can convert any Named Reroute back to an unnamed Reroute pin if you decide it is beneficial to see the wire connection.

The Roughness Named Reroute is converted back to a traditional Reroute pin.



Right-click a Named Reroute Declaration or Usage Node (either one works).

Choose Convert to Reroute from the menu.



The wire is restored and an unnamed Reroute pin is left behind. You can select the pin and press delete if it is no longer needed.



Reroute Selection Options

There are selection options for Named Reroute nodes that let you find and select corresponding Reroute nodes in the Material Graph.

Right-click a Named Reroute Declaration node and click Select Named Reroute Usages to select all the downstream output nodes for that reroute.



Right-click a Named Reroute Usage node and click Select Named Reroute Declaration to select the upstream origin node of the reroute.



Align and Distribute

The Material Editor has several options in the right-click menu to align and distribute nodes in your Material graph.

Select two or more nodes that you want to align.



Right-click one of the nodes and open the Alignment sub-menu.



Select one of the options to align or distribute the selected nodes.



In this example, Align Left was used to line up the left edge of the selected nodes. Distribute Vertically was then used to create equal spacing between them on the vertical axis.

Align

The options in the Align menu let you align nodes along six different axes. You can also straighten the connection wire between two nodes.

Option

Result

Shortcut

Align Top

Align the top edge of selected nodes.

Shift+W

Align Middle

Align selected nodes at their vertical middles.

Alt+Shift+W

Align Bottom

Align the bottom edge of selected nodes.

Shift+S

Align Left

Align the left edge of selected nodes.

Shift+A

Align Center

Align selected nodes at horizontal centers.

Alt+Shift+S

Align Right

Align the right edge of selected nodes.

Shift+D

Straighten Connection

Straightens the wire between two nodes so that it is perfectly horizontal.

Q

Distribution

The Distribution options allow you to create equal spacing between the selected nodes on either the horizontal or vertical axis.

Option

Result

Distribute Horizontally

Create equal horizontal spacing between selected nodes.

Distribute Vertically

Create equal vertical spacing between selected nodes.

Collapse Nodes

You can use the Collapse Nodes option to condense multiple Material Expressions or Functions into a single node.

There are a few reasons you might want to do this.

If a large group of related nodes is getting too complicated, collapsing them can free up space in the graph and make the Material easier to read.

A second use case is if a set of nodes is so commonplace or repetitive that you don't need to see the full node network to understand its purpose.

For example, the Detail Normal Tiling nodes shown below use a familiar method for controlling the scale of a texture.



To simplify the graph, you could collapse everything within the Detail Normal Tiling box .

How to Collapse Nodes

Select all the Material nodes you want to collapse.



. Right-click one of the nodes and choose Collapse Nodes from the context menu.



The selected Material Expressions are replaced by a single node with the default name Collapsed Nodes.



Left-click the name at the top of the node, and enter a descriptive name in the field.



The Detail Normals section of the graph is greatly simplified.



Editing Collapsed Nodes

Nothing has changed about the Material Graph. The Collapsed Node simply acts as a container for the node network within it.

If you mouse over a Collapsed Node you will see a preview of the Material graph stored inside.



Double-click a Collapsed Node to view and edit the contents. This opens a sub-graph within the same Material Editor tab.

Click Material Graph in the breadcrumb navigation at the top of the Material Editor to stop viewing the collapsed nodes and return to the main graph.



Expanding Collapsed Nodes

You can expand collapsed nodes back to their previous configuration in the Material Graph.

Right-click a collapsed node.

Click Expand Node in the context menu.



The collapsed nodes are restored to their original position.



This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Material Inheritance

Material Parameterization

Types of Parameters

Scalar Parameters

Vector Parameters

Texture Parameters

Static Parameters

Constant and Dynamic Instances

Material Instance Constant

Material Instance Dynamic

Creating and Using Material Instances

Material instancing in Unreal Engine is used to change the appearance of a Material without incurring an expensive recompilation of the Material.

Whereas a typical Material cannot be changed without recompiling (something that must happen prior to gameplay), a parameterized Material can be edited in a Material instance without such recompilation. This has numerous workflow advantages, and can improve Material performance.





A Material instance open in the Material Instance Editor. You can customize the attributes listed under Parameter Groups from this interface.



Certain types of instanced Materials can even change during gameplay in response to in-game events (such as a tree whose Material blackens and chars while it burns). This allows tremendous visual flexibility in your artistic elements.

Material Inheritance

The relationship between Materials and Material instances is a hierarchical parent-child relationship. A Material instance inherits all of its attributes from the parent (or master) Material. For example, this is the Material graph for one of the chair props found in the starter content:



Any Material instances created from M_Chair inherit all the attributes from the graph shown above.



Note the naming conventions used above. This is a good practice to adopt so that you can easily identify parent Materials and Material instances in the Content Browser.

The prefix M_ denotes a parent Material, as in M_Chair.

The prefix MI_ denotes a Material instance, as in the two examples pictured right.

Because they inherit their attributes from the parent, newly created Material instances appear identical to the parent Material when applied to objects in the Level. In the image below, the chair on the far left has the parent Material applied while the center and right chairs use unaltered Material instances.



The key workflow benefit of Material instances is that you can very rapidly customize them the Material Instance Editor without ever editing the node graph or recompiling the Material.

In the video below, the two Material instances are opened from the Content Browser, and edited in the Material Instance Editor. Changes appear in the main viewport immediately, whereas a standard Material could take up to a minute to recompile, depending on the complexity.

Material Parameterization

It is important to know that you cannot edit every single characteristic of a Material instance by default. To make Material attributes editable within an instance, you must designate them as parameters in the parent Material. This is called parameterizing your Material.

A parameter is created like any other data node in the Material Editor, and contains the same information as its non-parameterized counterpart.

For example, a Constant expression contains a single floating-point value, and is frequently used to control Material inputs like Roughness and Metallic. The parameterized version of this node is called a Scalar Parameter.



Constant Material expression (1) and Scalar Parameter (2).



Note that the Scalar Parameter also becomes a named value which serves as a conduit to send data values into a Material instance. It is important that you give every parameter a unique, descriptive name in the Details panel. Select the node in the Material Graph to access its properties in the Details panel.



In the above example the parameter's name is Roughness, and it has a default value of 0.25.

In the simple parameterized Material shown below, a Vector Parameter is connected to the Base Color input, while Scalar Parameters are plugged into Metallic and Roughness.



To further illustrate the idea of parameterization, there is also a constant value of 0.5 passed into the Specular input.

When opened in the Material Instance Editor, the three parameters are exposed and editable, whereas the constant is not. Values you want to expose to artists should be parameters, and values that you don't want anyone to change should remain as constants.



The parameters for Base Color, Metallic, and Roughness are editable in the Material Instance Editor, while the contant value is not exposed to artists.



Types of Parameters

Parameters can be used anywhere in your Material graph to drive a wide range of Material effects.

Some of the key parameter types are documented below, and a full list of Parameter Expressions is found here.

Scalar Parameters

A ScalarParameter is a parameter that contains a single floating-point value. Scalar parameters can drive any effect based on single values, as seen in the Roughness and Metallic examples above.

Scalar parameters are also frequently used to control the multiplication factor of an attribute.



In this graph, a Scalar parameter is multiplied by a solid color, and the result is plugged into the Emissive Color input. The value in the Scalar Parameter controls the strength of the emissive effect. Higher values increase the emission brightness.

Vector Parameters

A VectorParameter is a parameter that contains a 4-channel vector value, or four floating-point values.



These are generally used to provide configurable colors, but could also be used to represent positional data or drive any effect that requires multiple values.

Texture Parameters

The most commonly used texture parameter is the TextureSampleParameter2D, which allows you to change textures within a Material instance.



There are several additional types of texture parameters available. Each one is specific to the type of texture that it accepts or the manner in which it is being used. For example:

TextureSampleParameterCube accepts a TextureCube or cubemap.

TextureSampleParameterFlipbook accepts a FlipbookTexture.

TextureSampleParameterMeshSubUV accepts a Texture2D that is used for sub-uv effects with a mesh emitter.

TextureSampleParameterMeshSubUV accepts a Texture2D that is used for sub-uv blending effects with a mesh emitter.

See the Material Expression Reference for a complete list of texture parameters.

Static Parameters

Static parameters are applied at compile-time, so they can be edited in the Material Instance Editor but not from script or at runtime.

They can be used to mask out branches of a Material. For example, a StaticSwitch parameter takes two inputs. It outputs the frst value if the parameter value is true, and the outputs the second if false. This produces more optimal code as the branch that was masked out by a static parameter is not executed at runtime.



See Static Switch Parameter and Static Component Mask Parameter for information on the specific static parameter types.

A new Material is compiled for every combination of static parameters in the base Material that are used by instances.

This can lead to an excessive number of shaders that must compile. Try to minimize the number of static parameters in the Material and the number of permutations of those static parameters that are actually used.

Constant and Dynamic Instances

There are two types of Material instances available in Unreal Engine:

Material Instance Constant — Only calculated prior to runtime.

Material Instance Dynamic — Can be calculated (and edited) at runtime.

Material Instance Constant

A Material Instance Constant is an instanced Material that calculates only once, prior to runtime. This means that it cannot change during gameplay. Although they remain constant throughout your game, they still have the performance advantage of not requiring compilation.

For instance, if your game has a variety of cars with different paint jobs whose colors will not change during gameplay, the best practice approach is to create a master Material that represented the base aspects of a generic car paint. Then create Material Instance Constants to represent the variations for different types of car, such as different colors, varying levels of roughness, and so on. This approach was demonstrated with the chair example earlier on this page.

Material Instance Constants are created within the Content Browser and are edited from the Material Instance Editor.

Material Instance Dynamic

A Material Instance Dynamic (MID) is an instanced Material that can be calculated during gameplay (at runtime). This means that as you play, you can use script (either compiled code or Blueprint visual script) to change the parameters of your Material, thereby altering your Material throughout the game. The possible applications for this are endless, from showing different levels of damage to changing paint colors in an architectural visualization.

MIDs are created within script, either from a parameterized Material or a Material Instance Constant. In Blueprint, one would take a given Material that had parameterized properties, and feed it through a Create Dynamic Material Instance node. The result of that node is then applied to the object in question with a Set Material node. This produces a new Material that can be changed during gameplay.



Creating and Using Material Instances

Creating and using Material instances is a two step process. First you must create a parent Material that uses parameter expressions for the properties you want to be able to override in a Material instance. Then you can create a Material Instance and customize the properties in the Material Instance Editor.

To learn how to create a parameterized Material and use it in a Material instance, read here: Creating and Using Material Instances.

Instanced Materials

Material Editor UI

Material Inputs

Essential Material Concepts

Material Properties

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Material Instancing

Creating Material Instances is a Two Step Process

Creating a Parameterized Material

Adding Parameter Nodes from the Material Palette

Converting a Node into a Parameter

Parameterized Material Example

Creating a Material Instance

Editing a Material Instance

Adjusting Material Parameters

Using Parameter Groups

How to Use Parameter Groups

Ordering Parameters Within Groups

Ordering Parameter Groups

Changing the Parent Material of a Material Instance

Conclusion

Creating and editing standard Materials in Unreal Engine can be a time consuming process. To help speed up and streamline the Material creation workflow, Unreal Engine offers a special type of Material called a Material instance. This tutorial demonstrates how to set up and use Material instances in your projects.

Material Instancing

Material instancing is a way to create a parent Material that you can use as a base to make a wide variety of different looking children (Material instances).

To achieve this flexibility, Material instancing uses a concept called inheritance: the properties of the parent Material are passed to its children. Properties that are designated as parameters in the parent Material are exposed to artists in the Material Instance Editor.



Using Material instances, you can create numerous variations from a single base Material:



Creating Material Instances is a Two Step Process

First create a parameterized Material that you will use as the parent Material for your instances.

Create a Material Instance Constant in the Content Browser. You can then customize the Material in the Material Instance Editor.

For additional background information about Material instancing, read the overview here.

Creating a Parameterized Material

A Material instance inherits all the attributes of its parent Material, but not all of these attributes can be customized in the Material Instance Editor by default.

To make Material attributes editable in a Material instance, you must designate certain attributes as parameters by using parameter nodes instead of regular Material Expressions.

There are two ways to add parameter nodes to your Material graph.

Adding Parameter Nodes from the Material Palette

If you search for the word "parameter" in the Material Palette, or from the right-click menu in the Material Editor, you can find all of the parameter nodes that are available.

You can drag and drop these parameter nodes from the Palette or select them in the right-click menu to add them to your Material graph.



Parameters in the right-click menu (left) and the Materials Palette (right).



Two of the most commonly used Material parameters have keyboard shortcuts in the Material Editor:

Scalar Parameter - Hold the s key and left-click in the Material graph to place a Scalar Parameter. A Scalar Parameter is the parameterized version of a Constant, and contains a single numeric value.

Vector Parameter - Hold the v key and left-click in the Material graph to place a Vector Parameter. A Vector Parameter is the parameterized version of a Constant 4 Vector and contains four floating-point values.

Use the shortcut or palette to place a Scalar parameter in your Material graph:



Name the parameter Roughness and connect it to the corresponding Material input.

If you want to set a default value for the parameter or limit the value range, you can do so in the Details panel.



For example, the Roughness input accepts a value from 0 to 1. To make sure the Roughness parameter always stays within this expected range, set the Slider Min and Slider Max values to 0 and 1.

If you want a default Roughness value other than 0, enter it in the Default Value field.

Select the Roughness parameter and press Ctrl+D to duplicate the node. Rename the second scalar parameter Metallic and connect it to the appropriate input. Your graph should now look like this:



Converting a Node into a Parameter

You can also convert standard Material Expressions into parameters within an existing Material graph.

For the sake of demonstration, place a Constant3Vector node in your Material graph. This is a standard (non-parameterized) Material expression, which is often used to define the Base Color of a Material.



To convert this node into a parameter, right-click the node and choose Convert to Parameter from the contextual menu.



Remember to give the parameter a unique, descriptive name like BaseColor. The naming field is selected automatically when you convert a node.



You can change the color in the Default Value field shown above, or you can double click the BaseColor node to open the color picker.



You cannot parameterize every Material node in Unreal Engine, but the Convert To Parameter option is available from the right-click menu for any Material expression that can be parameterized.

Parameterized Material Example

Your Material graph should now contain a Vector parameter plugged into BaseColor and two Scalar parameters, plugged into the Metallic and Roughness inputs:



These three parameters will allow you to change the color, roughness, and metallic properties of the Material once you create a Material instance.

Click Apply in the upper left corner of the Material Editor to compile the Material, and then click Save.



Creating a Material Instance

Now that you have a simple parameterized Material, you can create Material instances and customize them in the Material Instance Editor.

To create a Material instance, right-right click your Material in the Content Browser and choose Create Material Instance from the menu.



Your Material instance will derive its name from the Material that you are using to create it. You can rename the Material instance by selecting it and pressing F2 or by single-clicking the name field.



Editing a Material Instance

Double-click the Material instance in the Content Browser to open the Material Instance Editor.



The Material Instance Editor is the interface where you can customize Material parameters to produce different looking variations of your parent Material.





A Material instance in the Material Instance Editor.



Adjusting Material Parameters

Material Parameters are found in the Details panel on the right side of the Material Instance Editor. Note that these parameters take their names from the parameter nodes in your original Material graph.

Use the following steps to edit a parameter:



Place a check in the box next to the parameter to enable it for editing.

Type a new value in the field or left-click and drag to slide the value up and down. For Vector parameters, left-click the color swatch to activate the color picker.

To reset a parameter to its default value, click the arrow icon pictured here.

As you adjust parameters, the Material preview will update in real-time in the Material Instance Editor, and in the Level if the Material is currently applied to any Actors.

Using Parameter Groups

You can sort your parameters into Parameter Groups to improve the organization and readability of your Material instances.

While the above example with only three parameters is easy to read, heavily parameterized master Materials can be inefficient to interact with if you do not use parameter groups.

The slider below shows a Material instance with and without groups. In the example without parameter groups, scalar parameters appear in a single unorganized list. The instance with parameter groups is neatly organized by Material attribute.





How to Use Parameter Groups

Parameter groups are configured within the parent Material, not within the Material instance. This is done in the details panel of the Material Editor.

Select a Material parameter node in your Material graph.



In the Details panel, type a name into the Group field. You can name your groups however you wish, but one suggestion is to group parameters by the Material attribute they control.



Once you assign a parameter group name to one Material parameter expression, that name will appear in the drop-down menu next to the Group field.

For the rest of your parameters, you can either type in new group names or select one of the existing parameter groups from the drop-down menu.



Ordering Parameters Within Groups

You can use the Sort Priority field to change the order that parameters are listed within a group. By default all parameters are listed alphabetically, which can lead to clumsy or inefficient ordering in the Material Instance Editor. In the slider below, the UV tiling and offset controls are broken up when listed alphabetically, but by assigning a sort priority value to each parameter the experience is improved.





To change order of a parameter, select the node and enter a new value in the Sort Priority field in the Details Panel.



Ordering Parameter Groups

By default, parameter groups appear alphabetically in the Material Instance Editor.

There are two ways to change the order of your parameter groups. One solution is to simply add numbers to your group names.

The Megascans parent Material uses this approach, with parameter groups numbered from 00 – 07.



This allows the parameter groups to display in the same order they appear in the Main Material Node.

You can also use the Group Sort Priority property in the details panel to change the order of your parameter groups. This property is found in the parent Material, not in the Material Instance.

Deselect all nodes in the Material Graph to access its Material Properties.

In the Details Panel, expand Group Sorting, and then Parameter Group Data.

The array in this section lists all the parameters in your Material. Expand each Index and change the Group Sort Priority to modify the order of the groups.



Changing the Parent Material of a Material Instance

You can easily change the parent Material used by a Material instance, in the Material Instance Editor.

To change the parent Material, open a Material instance in the Material Instance Editor. Under the General section in the Details panel, find the Parent property.



Use the drop-down menu to search for and select a different parent Material. You can also select a Material in the Content Browser and click the Use Selected Asset in Content Browser button (left-facing arrow).

Note that if you change the parent Material it can completely change the appearance and properties of the Material instance. The parameters you were using before may no longer be available in the new parent.



For example, if you select the M_Metal_Gold Material from the drop-down list, the three parameters that were present in the M_Parameterized example (roughness, metallic, base color) are no longer available in the gold instance.



Conclusion

Material Instancing is a powerful tool that you can use across all aspects of your project. From helping to add some variation to weapons and props, to helping artists make better use of available Materials, Material Instances can help to streamline and unify how Materials are created and used in your project.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Opening the Material Instance Editor

Material Instance Editor Interface

Toolbar

Hierarchy Menu

Viewport

Viewport Display Options

Details Panel

Parameter Groups

General

Previewing

Overriding Material Instance Parameters

Overriding Material Instance Lightmass Settings

Overriding Parent Material Properties

The Material Instance Editor is used for modifying parameters in Material Instances. If you are unfamiliar with Material parameterization and instancing, read the following pages:

Material Instances Overview

Creating and Using Material Instances

Opening the Material Instance Editor

Double-click a Material Instance asset in the Content Browser to open the Material Instance Editor.



You can also Right-click the Material Instance thumbnail in the Content Browser and choose Edit from the context menu.

Material Instance Editor Interface

The Material Instance Editor is comprised of these regions:



Toolbar - Save your asset, locate it in the Content Browser, show hidden parameters, display inheritance hierarchy and platform stats.

Viewport - A realtime viewport showing a preview of the Material instance.

Viewport display options - Allows you to edit the camera and display settings in the viewport, and change the mesh used for the Material preview.

Details Panel - All exposed Material parameters and properties are found here.

Toolbar

Icon

Description



Saves the current asset.



Finds and selects the Material instance in the Content Browser.



Displays inactive parameters that are hidden behind static swtiches.



Shows the inheritance hierarchy of the Material instance. See below.



Opens a window displaying render statistcs for different target platforms.

The Hierarchy menu displays the inheritance chain for the current Material instance. Since Material instances can be used as the parent for other Material instances, both parents and children are listed in the Hierarchy menu.



Parents of the current Material Instance are listed under Parent Chain. If there are multiple parents, the first one listed is at the top of the inheritance hierarchy.

Children of the current Material Instances are listed under Material Instances.

Selecting a parent Material or Material instance from the Hierarchy menu opens that asset in a new tab of the Material Instance Editor window.



Viewport



The viewport shows a preview of your Material instance applied to a Static Mesh. The Material preview updates in real time as you make changes to the parameters in your Material Instance.

You can interact with the viewport using these controls:

Click and drag the left mouse button to rotate the preview mesh.

Click and drag the middle mouse button to pan the camera.

Click and drag the right mouse button to zoom in an out, or use your scroll wheel.

Rotate the light direction by holding down the L key and dragging with the left mouse button.

Viewport Display Options

Icon

Description



Contains toggle to enable real time preview, display FPS, and change FOV of the preview window.



Switch between Perspective and Orthographic viewport cameras.



lContains standard view modes like Lit, Unlit, Wireframe and others. Also contains an exposure override.



Enable or disable rendering stats, the grid and the background.



Preview the Material instance on a cylinder.



Preview the Material instance on a sphere.



Preview the Material instance on a plane.



Preview the Material instance on a cube.



Preview the Material instance on a custom Static Mesh.

You can change the Material preview mesh by clicking one of the shape icons at the bottom of the Viewport.



To preview your Material instance on a custom mesh, select a Static Mesh asset in the Content Browser, and then click the brick icon. The preview mesh is saved with the Material instance so that the next time it is opened it will appear on the same preview mesh.



The Viewport also displays statistics about the Material, such as instruction counts for the various shader types as well as the number of Texture samples used by the Material.



To preview any sort of movement or animation in your Material Instance, you must enable the Realtime Viewport option. Click the hambuerger menu to open Viewport options and make sure Realtime is checked. This option is enabled by default.



You can also press Ctrl+R to toggle real-time rendering.

Details Panel

The Details panel is where you can override the parameters and settings in your Material Instance. All of the changes you make to your Material instance will occur in this interface.



There are three main subsections in the Details Panel:

Material attributes that you have exposed through parameters in your parent Material are listed here. To override the value in a parameter, check the box to the left of the parameter name and modify the value in the field. See here for more information about overriding parameters.

The General section allows you to select a different Parent Material, or Physical Material. You can also adjust how this Material Instance will influence the Lightmass build and override some of the properties inherited from the parent Material. Read more about these settings here.

This section provides another input to change the static mesh used for the Material Instance preview.

Overriding Material Instance Parameters

Parameters are listed under the Parameter Groups section in the Details panel. To override a Material parameter:

Place a check in the box to the left of the parameter name.

Type a new value into the field or use the color picker to set a new value.



Any parameter that is checked is currently overridden in the Material Instance. Unchecked parameters use the value from the parent Material, even if there is a different value in the field:



Remember to Save your Material instance when you are finished editing parameters so that your work is not lost. For memory conservation, values in unchecked fields will be lost when the Material Instance Editor window is closed.

To reset a parameter to its default value, click the Reset button to the right of the parameter.



Overriding Material Instance Lightmass Settings

You can override the way your Material interacts with Lightmass under the General > Lightmass Settings section.

For example, if you increase the Emissive Boost attribute of an emissive Material, the Material will contribute more emissive light to the static lighting solution produced by Lightmass. This makes the result brighter.



Overriding Parent Material Properties

The Material Property Overrides section allows you to override some of the Material Properties in the parent Material of your instance.

For example, if you need an instance of your Material to render on both the front and back side of a surface, you can enable the Two Sided option.



The advantage of overriding these properties in the Material Instance Editor instead of editing the parent is that it only affects a single instance of the Material. Every other instance will inherit settings from the parent.

Materials

Instanced Materials

Material Editor User Guide

Creating and Using Material Instances

Creating and Editing Material Parameter Collections

Using Material Parameter Collections in Materials

Testing the Material Parameter Collection

Updating Material Parameters Collections Through Blueprints

Limitations and Performance Characteristics



A MaterialParameterCollection is an asset that stores an arbitrary set of scalar and vector parameters which you can reference in an Material. It is a powerful tool that artists can use to pass global data into multiple Materials at once. You can also use Material Parameter Collections to drive per-level effects, such as snow amount, destruction amount, wetness, and so on, which would otherwise require settig individual parameter values within many different Material Instances in your Level.



In the example above, global parameters stored in a Material Parameter Collection are used to control the following aspects of the scene.

The flower morph states along with the speed and strength of the wind.

The player's position is tracked and fed into the foliage. That position information is used to move the flowers and grass away from the player as they walk nearby.

The sun angle and color is also tracked and used to correctly colorize the water crests and limit the effect to only times when light shines directly through the wave crests (when the player is looking toward the sun).

The coloration of effect across the time of day and overall diffuse lighting color for the water are also being controlled.

Creating and Editing Material Parameter Collections

MaterialParameterCollections are a discrete asset type created in the Content Browser. Use the following steps to create a MaterialParameterCollection and add a parameter.

Right-click in the Content Browser, and expand the Material subcategory in the Create Advanced Asset section. Select MaterialParameterCollection in the context menu.



Rename the MaterialParameterCollection asset to describe the types of parameters it will contain. This example uses the name MPC_GlobalParams. Double-click the asset to edit the MaterialParameterCollection.



A new window opens displaying the Scalar and Vector Parameters contained within the MaterialParameterCollection.



To add parameters to the collection, click the Add Element (+) icon in either the Scalar or Vector Parameter section. For this example, add a Scalar Parameter. Name it GlobalEmissivePower and change the default value to 1.0.



Add any additional Scalar or Vector Parameters as needed. A single Material Parameter Collection can hold up to 1024 Scalar Parameters and 1024 Vector Parameters.

Using Material Parameter Collections in Materials

You can now use the parameters in your MaterialParameterCollection to define the attributes in your Materials. One of the main benefits of Material Parameter Collections is that the parameter values are stored in a separate asset from the Materials themselves. This means you can reference a Material Parameter Collection in as many Materials as you want, and when you change the values in the Material Parameter Collection, it automatically affects every Material that references it.

Use the following steps to reference your Material Parameter Collection in a base Material.

Right-click in the Content Browser and click Material in the Create Basic Asset section of the context menu. Give the Material a descriptive name.



In the Content Browser you should now have a Material, as well as the MaterialParameterCollection you created in the previous section. Double-click the Material to open it in the Material Editor.



This Material will be a simple emissive surface that uses a Fresnel expression to make the Material glow slightly brighter around the edges. Add the following Material Expression nodes to your Material Graph.

Material Expression Type

Name

Default Value

Vector Parameter

Base Color

1,0,0,0

Vector Parameter

Emissive Color

0.1,0.01,0.14,0

Multiply - x2

n/a

n/a

Fresnel

n/a

n/a

Connect the Material Expressions as shown in the image below.



Select the Fresnel node in the Material Graph. In the Details Panel set the Exponent to 6 and the Base Reflect Fraction to 0.1. These properties control the falloff of the rim lighting effect. Experiment with a higher or lower Exponent to influence how much of the surface is affected by the Fresnel node.



Right-click in the Material Graph and search for "collection" and add a CollectionParameter to your graph. This node is used to bring infromation from your MaterialParameterCollection into the Material Graph.



Select the Collection Parameter node in the Material Graph. In the Details Panel, use the Collection drop-down menu to select the MPC_GlobalParameters collection you created earlier.



Use the Parameter Name drop-down menu to select the EmissivePower parameter.



Connect the 'EmissivePower' node to the open B input on the Multiply node as pictured below.



Click Save in the Material Editor Toolbar to compile and save the Material. After saving the asset you can close the Material Editor.



Testing the Material Parameter Collection

To demonstrate the Material Collection Parameter's usefulness in controlling the attributes of multiple Materials, you can create one or more Material Instances and apply them to different objects in the scene.

Right-click your base Material and choose Create Material Instance from the context menu.



Apply the base Material and the Material Instance to two different objects in your level. You can change the Base Color and Emissive Color parameters in the Material Instance so you can tell the two apart.



Now when you open the Material Parameter Collection and change the EmissivePower value, the new value will immediately propagate to both the base Material and the Material Instance.

Updating Material Parameters Collections Through Blueprints

You can also interact with Material Parameter Collections through Blueprints. This is an extremely powerful tool, as it means players can manipulate the appearance of a Material during game play. The example below demonstrates how to change the EmissivePower of the two Materials in response to a keystroke. At runtime, pressing the B key will make the emissive value brighter, and pressing the D key will make it dimmer. Releasing either key sets the parameter back to its original value of 1.

In the toolbar above the main Editor viewport, expand the Blueprints drop-down menu, and select Open Level Blueprint from the list.



Right-click in the Level Blueprint and search for keyboard event. Add a B Keyboard Event from the context menu. Repeat this action and add a D Keyboard Event.



Right-click in the Level Blueprint and add a Set Scalar Parameter Value node to the Blueprint. Use the Collection drop-down menu to reference your MPC_GlobalParams Material Parameter Collection.



Use the Parameter drop-down to reference the EmissivePower Parameter.



Duplicate the Set Scalar Parameter Value Node twice, so you have three copies in your Blueprint. Wire up the nodes so your Blueprint Graph looks like the image below. The Pressed output on the B and D Keyboard Event nodes should connect to the input on the first and third Set Scalar Parameter Value nodes. The Released outputs on both Keyboard Event nodes should connect to input on the second Set Scalar Parameter Value node.



The final step is to set a Parameter Value for the EmissivePower in response to each Keyboard Event. In this example, when the B key is pressed, the EmissivePower increases to 50. When the D key is pressed the Emissive Power decreases to 0.05. When both keys are released, the Parameter is set to its original value of 1.



Click Compile in Blueprint Editor toolbar to compile the Level Blueprint. You can now test the changes in-game.

Click the Play in Editor icon in the Editor toolbar, and test the Blueprint by pressing and releasing the B and D keys. The results are shown in the video below.

Limitations and Performance Characteristics

A Material can reference, at most, two different MaterialParameterCollections. One is typically used for game-wide values while the other can be used for level specific parameters. A collection can have up to 1024 scalar parameters and 1024 vector parameters.

Modifying the number of parameters in a collection will cause a recompile of all Materials that reference that collection. If you need to add numerous parameters, it can be faster to add a lot of parameters up front in an empty map.

If you rename a parameter, any Materials referencing that parameter will continue to work as expected. However, any Blueprint referencing that parameter will now be broken. You must reassign the ParameterName of the Blueprint function which operates on the collection to fix this.

Updating values in a MaterialParameterCollection is much more efficient than setting many different parameters on various Material instances.

Functions Reference

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Material Functions let you package parts of a Material graph into a reusable asset that you can share to a library and easily insert into other Materials. Their purpose is to streamline Material creation by giving instant access to commonly used networks of Material nodes. Material Functions allow you to abstract complex Material logic into a single node, making Material creation easier for artists.

A secondary benefit of Material Functions is that edits to a single function propagate throughout all Material networks which use it. So if you need to make a fix or change how a Material Function works, you will not have to make further edits to the many Materials which may be using that function. These two pages provide information about how to create and use Material Functions in Unreal Engine.



An overview of how Material functions work and some critical concepts for their use.



A guide to the process of creating and using Material Functions.

Functions Reference

The reference pages below provide information and usage examples for all the default Material Functions included with Unreal Engine. These are organized according to the categories in the Material Editor palette.



Material Functions designed to allow utilization of the Pivot Painter MAXScript.



Functions designed to blend one color with another, similar to blend modes in popular image editing applications.



Procedurally generated gradients to add to your materials, eliminating the need for textures and saving memory.



Functions for making adjustments to existing image textures, such as shifting contrast or hue.



Material Functions which perform preconfigured mathematical operations such as the calculation of pi, addition of vector components, and others.



Misc Material Functions that do not fall into existing categories.



Functions to handle opacity values within a Material network.



Specialized functions designed to aid setting up the look of complex particle networks.



Procedurally generated textures and operations, such as the creation of normal maps from existing height maps.



Functions for aiding in the calculation of values for a variety of reflection types.



Functions for handling special shading types, such as Fuzzy Shading networks.



A wide variety of functions designed to aid in working with textures, such as reprojecting UVs, cropping, and many more.



Functions built to handle vector mathematics, such as calculating a Fresnel effect.



Functions for handling vertex manipulation using world position offset.



Material Functions designed to enable utilization of the Pivot Painter 2 MAXScript in an Unreal shader network.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Material Function Library

Function Related Nodes

Input and Output

FunctionInput Nodes

FunctionOutput Nodes

Input Types

Common Properties

Previewing

Function Input Preview

Parameters

Texture Parameters

Static Bool Parameter

Organization

Function Desctiption

Input and Output Descriptions

Propagation

Nesting Functions

Compilation Errors

Default Material Functions

Material Functions let you package parts of a Material graph into a reusable asset that you can share to a library and easily insert into other Materials. Their purpose is to streamline Material creation by giving instant access to commonly used networks of Material nodes.

For example, the Blend_Overlay function shown below contains the entire Material Expression network shown on the right side of the image. Instead of constructing this node network over and over, you can insert it directly into your graph from the Material Function library.



Functions are edited in the Material Editor like a normal Material, but with some restrictions on what nodes you can use. When used properly, they can reduce Material redundancy which in turn reduces artist maintenance effort. Material Functions keep duplicate expressions in sync, preventing the inevitable bugs that arise when one duplicate is missed during a modification.

Material Functions are a distinct asset class in the Content Browser. Their graphs are similar to Materials, but differ in one major regard. Instead of a Main Material node, Material Functions have FunctionOutput nodes, which appear as output pins on the final Material Function node when it is used in a Material.

It may help to think of a Material function like an electronics project enclosure. You can add as many inputs and outputs as you deem necessary. The heart of the function is the Material Expression network between those inputs and outputs. This example takes two layers and blends them together like a Photoshop screen blend. The function abstracts the details from an artist, so they do not have to actually know the math of a screen blend to use a screen blend operation.



Material Function input (1) and output (2) nodes.

As you can see above, what happens between the input and the output is entirely up to you and will be defined by any network of standard Material expression nodes. Once you insert a Material Function into a Material, you will only see the Matrial Function Call node with its inputs and outputs. The rest of the graph is hidden within the function.



Material Function Library

When your Material Function is finished, you can publish it to the Material Function library for easy access during Material creation. The Material Function library is found within the Palette on the right side of the Material Editor. The Palette contains a categorized and filterable list of available Material Functions. This list is populated from any loaded functions, but also from any deault Material Functions found in the Content Browser Database.



You can hover over these entries to see their Description as a tooltip, or drag and drop one into your Material.

In order for a Material function to appear in the Material Function Library, its Expose to Library property must be checked. In the Material Function editor, deselect all nodes by clicking an empty space in the graph to show the base properties for the Material Function. The Expose to Library option is found in the Details panel.

For a full listing of the existing functions within the Material Function Library by default, please see the Material Function Reference.

Function Related Nodes

Below are the Material expression nodes that relate to Material Functions, along with their purpose:

MaterialFunctionCall - Allows using an external function from another Material or function. The external function's input and output nodes become inputs and outputs of the function call node.

FunctionInput - Can only be placed in a Material Function, where it defines one of the function's input pins.

FunctionOutput - Can only be placed in a Material Function, where it defines one of the function's output pins.

TextureObject - Useful for providing a default texture for a texture function input within a function. This node does not actually sample the texture, so it must be used in conjunction with a TextureSample node.

TextureObjectParameter - Defines a texture parameter and outputs the texture object, used in Materials that call a function with texture inputs. This node does not actually sample the texture, so it must be used in conjunction with a TextureSample node.

StaticSwitch - Performs a compile time choice between two inputs, based on the input value.

StaticBool - Useful for providing a default bool value for a static bool function input within a function. This node does not switch between anything, so it must be used in conjunction with a StaticSwitch node.

StaticBoolParameter - Defines a static bool parameter and outputs the static bool value, used in Materials that call a function with static bool inputs. This node does not switch between anything, so it must be used in conjunction with a StaticSwitch node.

Input and Output

Since Material functions are encapsulated networks of nodes, it is up to the user to make sure that data can flow into and out of them. This is handled by way of FunctionInput and FunctionOutput nodes. Understanding these nodes is critical for using Material functions.

Within the Material Function itself, FunctionInput and FunctionOutput nodes appear like so:



When the Material Function is used in a Material, the FunctionInput and FunctionOutput nodes appear as input and output pins on the Material Function node:



FunctionInput Nodes

As stated, FunctionInput nodes serve as the gateway through which data enters a Material Function. A given function may have any number of these input nodes, each corresponding with an input pin on the Material Function Call node.



FunctionInput nodes have the following properties and data pins:

Item

Description



Properties



Input Name

The name of the input, which is visible as an output pin on the Material Function when it is used within a Material.

Description

A description of the input, which is visible as a tooltip when you mouse over the corresponding input pin on the Material Function node.

Input Type

This defines what type of data the input accepts. See Input Types below.

Preview Value

This serves as a means of testing and a way to help visualize that the function is doing during the construction process. Any value entered here is used as if it was passed in from an input outside the function.

Use Preview Value as Default

This checkbox allows the data set in the preview value to act as the default value. This is useful if you do not want to force the user to provide an input into the function for this value.

Sort Priority

This number is used to control the order in which input pins are displayed on the Material Function node. The order is lowest to highest.



Input Pins



Preview

Data passed into this input supersedes the Preview Value property. As with its associated property, this is useful for testing the function during construction and setting up default values.



Output Pins



(Unlabled)

This provides the output for the incoming data that will be processed by the function.

FunctionOutput Nodes

A FunctionOutput node provides the means by which data within a Material Function exits the function for further use in a Material. In other words, it outputs final result of the Material function. As with FunctionInput nodes, a function may have any number of output nodes, leading to any number of potential output pins.



When a FunctionOutput node is selected, the following properties are accessible in the Details panel.

Item

Description



Material Expression Function Output



Output Name

The name of the output, which is visible as an output pin on the Material Function when it is used within a Material.

Description

A description of the output, which displays as a tooltip when you mouse over the corresponding output pin on the Material Function node.



Material Expression



Sort Priority

This number is used to control the order in which output pins are displayed on the Material Function node. The order is lowest to highest.

Description

This description field defines the text in Comment Bubble of the node. This is only visible within the Material Function editor.



Output Pins



(Unlabled)

This provides the output for the incoming data that will be processed by the function.

Input Types

Inputs have a specified type that is required of any expressions connected to them. To set the Input Type, select a FunctionInput node in the Material Function editor, and use the Input Type dropdown to select an option.



When called in a Material, the input type is displayed as an abbreviation next to the input connectors. In this case, both the inputs were Vector3's so V3 is displayed. Anything connected to an input when used in a Material must be convertible to the correct input type, or you will receive an error.



Below are the available input types and their associated abbreviations:

Input Type

Abbreviation

Scalar

S

Vector2

V2

Vector3

V3

Vector4

V4

Texture2D

T2D

TextureCube

TCube

Texture2DArray

T2dArr

VolumeTexture

TVol

StaticBool

B

MaterialAttributes

MA

TextureExternal

TExt

Common Properties

While editing a Material Function, deselecting all nodes or clicking in the background of the Material Graph will make the base properties of the function visible in the Details panel.

Item

Description



Properties



Description

This description will display as a tooltip when users mouse over the Material Function in the palette, or mouse over the body of the Function Call node within the Material Editor.

Expose to Library

If this box is checked, the Material Function will appear within the Material Functions list inside the Material Editor palette so that you can insert it into Materials. You may need to restart the editor for a new function to appear.

Library Categories

This array holds all of the categories of the Material Functions tab under which this function will appear.

Previewing

When editing a Material Function, the preview viewport shows whichever node is being previewed. You can right-click on any node and choose Start Previewing Node to preview the results of the Material network up to that point.



Most of the time you will want to preview the function output, or the end result of the Material Function. The Material Function output node is previewed by default.



Function Input Preview

Function Input nodes have some options for specifying preview values, since they do not know the actual values that artists will use within the Material. Each input has a built-in Preview Value that you can use to show a constant for float input types. Function inputs also have a 'Preview' connector which allows you to override the built-in value with any value that matches the input type. In this example, texture samples are used to provide a preview value for the two Vector3 inputs.



Note that the input has an option in the details panel to Use Preview Value As Default. When this is enabled, the preview value is used any time the function is called in a Material and nothing is connected to that input. The preview value acts as a fallback, and prevents compilation errors when nothing is connected to the input. This makes the input an optional input, so it is drawn in gray.

Parameters

You can use Parameters in a Material Function like you would in a regular Material. These parameters are passed directly to any Material for use. There are some slight differences in the procedure for using texture parameters.

Texture Parameters

To use a texture parameter within a Material Function, create a FunctionInput* node and change the data type to Texture2D. Connect it to the texture object override pin in a Texture Sample** node.



When you use that Material Function in a Material, place a TextureObjectParameter node and connect it to the Texture2D input pin on the Material Function.



Static Bool Parameter

Similarly for Static Switch parameters, create a FunctionInput and change the Input Type to StaticBool. Connect it to a StaticSwitch node:



In the Material that uses the function, place a StaticBoolParameter node and connect it to the input that accepts a Static Bool (Enable Tiling in this example).



Organization

By design, Material Functions are often used by many artists and teamates who did not have a hand in creating the function itself. Therefore, it is important to provide good documentation of what the functions do, and what values are needed for their inputs and outputs. For this reason, functions have several documentation fields on top of the function name and input/output names:

Function Desctiption

Material Functions have a Description field where you can document what the function does. To add a description, click on an empty area in the Material Graph while editing a Material Function. This will display the function's properties in the Details panel, where you can enter a description in the field.



The description text displays as a tooltip when you mouse over the Material Function Call node within a Material Graph.



Input and Output Descriptions

You can add a name and description for the input and output pins on your Material Function. While editing a Material Function select an input or output node in the Material Graph. In the details panel, fill out the Input Name and Description fields.



When this Material Function is used in a Material, the each input pin displays the name you entered, and the description is shown as a tooltip whe you mouse over the input.



While you are editing a Material Function, all tools for organizing and documenting your Material Graph are available to you. Read here about organizing a Material Graph.

Propagation

When you edit a Material Function and click the Save button to recompile and apply the changes, the new version propagates to any loaded Materials or functions which reference this Material Function. Any unloaded Materials which reference the function will be updated with the changes when they are next loaded.

When an input or output is deleted from a function and the changes are propagated, any links to these deleted connectors in Materials that use the function will be broken! It is important to consider this before you recompile a Material Function, because the propagation cannot be undone. The more Materials a function is used in, the bigger the potential for breakage, so be careful.

All loaded Materials that use the function will be marked dirty when the function change is propagated, which can be used to see which packages could be resaved to prevent increased load times. You can find all the loaded Materials which use a function by right-clicking in the Content Browser and choosing Find Materials Using This.



Nesting Functions

You can nest Material functions within other functions, and chain them together arbitrarily. The only caveat is that Material Functions cannot be nested in such a way that creates a circular dependency.

Compilation Errors

If there are errors within a Material Function, a compilation error dialog is generated when you attempt to compile the Material. A red error message also appears on top of the Material Function that did not compile correctly. You can hover the mouse over the error message to see a tooltip that describes the compilation error. In this example, the Material Function is not receiving data in either of its inputs, which causes the compilation to fail.



You can avoid the above errors by supplying preview values for your inputs and then activating each input's Use Preview Value as Default property. However, this practice may serve as a double-edged sword, as there will be no highly obvious alert (such as an error message) to remind you that you have left an input unplugged.

Default Material Functions

Unreal Engine includes several dozen premade default Material functions. These are accessible from the Material Editor Palette, or the right-click search menu.

If you would like to edit one of the default Material Functions, you can find the assets in the Content Browser within the Engine > Content > Functions folder.

If any changes are made and saved to a default Material function, those changes will exist in all instances of the function. For this reason, it is strongly recommended that you make a duplicate copy of default functions when you want to make changes.

For more information about the default Material Functions included with Unreal Engine, please see the Material Function Reference.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Material Functions Overview

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Creating Material Functions

Editing Material Functions

Publishing Your New Function

Using Material Functions

From Material Palette

Unspecified Function Node

Creating Material Functions

Use the following steps to create a new Material Function:

Right-click in the Content Browser. In the context menu under the Create Advanced Asset section, open the Materials sub-menu and select Material Function from the list.



Rename the Material Function after it appears in the Content Browser. Your name should be as descriptive as possible so that when someone looks at it they can easily understand what it does. This example ses the name Custom_Fresnel. You can re-name your Material Function by selecting it in the Content Browser, pressing F2 on the keyboard, and typing a new name.



Editing Material Functions

After you create a new Material Function, you need to open it in the Material Editor to begin constructing the Material Expression network. You can also open existing Material Functions if you would like to change their behavior. There are two ways to open a Material Function for editing:

Double-click a Material Function asset in the Content Browser to open it in a separate Material Editor tab. You can then edit the Material Expression network within the Material Function to modify its behavior



Double-click a Material Function node within an existing Material, and the Material Function will open in a new Material Editor Tab.



When double-clicked, the Material Function opens in a new tab of the Material Editor, showing the Material Expression network contained within the function. You can then edit the graph to your liking.



It is important to note that any changes made and saved to a Material Function will propagate to all instances of that Material Function moving forward. For example, if you made a change to the internal network of a Radial Gradient Material Function, all existing instances of that function would receive the update, as well as all new instances moving forward.

For this reason, unless you are certain that your change needs to propagate throughout all other instances of the function, it may be wise to make a copy of an existing function in the Content Browser (right-click and choose Duplicate from the context menu) rather than editing the original material function.

Once you make changes to a function you must click the Apply button to propagate the changes to the function asset and any Materials using the function. Once done, be sure to save your asset in the Content Browser.



Publishing Your New Function

In order to use your Material Function , you need to make sure that it shows up within the Material Function Library in the Material Editor Palette. In order to do this, you must set the Expose to Library property to true.

Deselect all nodes within your function by clicking in the background of the Material Graph. This will display the function's base properties in the Details panel.



Add a description. This is critical, as putting a description here will cause that description to appear as a tooltip when users mouse over the function in the Material Function Library as well as in Material Editor. Adding descriptions to your Input and Output nodes is certainly good practice, but if you had to choose only one place to comment in your expression, this is by far the most important one.



Library Categories Text lets you choose which category your Material Function will appear in. You can add additional categories by clicking Insert, and typing a new category name. However, it is wise to be as concise as possible and not add any more categories than are absolutely needed.



Using Material Functions

From Material Palette

Once you have created your Material Function and published it to the library, you can use it in an existing Material by dragging it directly from the Material Editor Palette. In addition to user-created Material Functions, the Palette contains all the default Material Functions included with the engine.



Default Material Functions are sorted into a wide range of categories. User-created Material Functions are placed in the Misc category by default, but you can change their categorization in the Details panel properties for the function. Drag a Material Function into your Material Graph, and a Material Function Call node is created, containing the various inputs and outputs defined by the input and output nodes within the function.



You can also add Material Functions to your Material by right-clicking in the Material Editor and searching for them in the context menu.

Unspecified Function Node

A third way to use Material Functions is by placing an Unspecified Function node in your Material Graph, and then assigning a Material Function to it in the Details panel.

Hold the F key and left-click in the Material Graph to place an Unspecified Function node.



Assign a Material Function to the Unspecified Function node in the Details panel. You can search for a Material Function in the dropdown menu in the Details Panel, or you can select a Material Function asset in the Content Browser and click the Use Selected Asset from Content Browser button.



The Unspecified Function node is replaced by the selected Material Function – Blend Angle Corrected Normals in this example.



This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

The reference pages below provide information and usage examples for all of the default Material Functions included with Unreal Engine. These are organized according to the categories in the Material Editor palette.



Material Functions designed to allow utilization of the Pivot Painter MAXScript.



Functions designed to blend one color with another, similar to blend modes in popular image editing applications.



Procedurally generated gradients to add to your materials, eliminating the need for textures and saving memory.



Functions for making adjustments to existing image textures, such as shifting contrast or hue.



Material Functions which perform preconfigured mathematical operations such as the calculation of pi, addition of vector components, and others.



Misc Material Functions that do not fall into existing categories.



Functions to handle opacity values within a Material network.



Specialized functions designed to aid setting up the look of complex particle networks.



Procedurally generated textures and operations, such as the creation of normal maps from existing height maps.



Functions for aiding in the calculation of values for a variety of reflection types.



Functions for handling special shading types, such as Fuzzy Shading networks.



A wide variety of functions designed to aid in working with textures, such as reprojecting UVs, cropping, and many more.



Functions built to handle vector mathematics, such as calculating a Fresnel effect.



Functions for handling vertex manipulation using world position offset.



Material Functions designed to enable utilization of the Pivot Painter 2 MAXScript in an Unreal shader network.

Pivot Painter Tool

Pivot Painter Tool 1.0

Pivot Painter Functions

PivotPainter_HierarchyData

PivotPainter_PerObjectData

PivotPainter_PerObjectFoliageData

PivotPainter_TreeData

Pivot Painter Material Functions allow you to tap into the Pivot Painter MAXScript, which stores rotation information within the vertices of a mesh. This is a great way to handle dynamic motion on Static Meshes.

Although the data provided by Pivot Painter can be utilized without these functions, they do make the process much easier.

Pivot Painter Functions

The following is a list of all the functions underneath the Pivot Painter category.

These functions are used to process and organize world position and angle information stored in the model's UVs by the Pivot Painter MAXScript.

PivotPainter_HierarchyData

This particular function is specifically designed to work with object hierarchies.

Item

Description



Inputs



Max Dist for Parent Piv (Scalar)

This value should match the value that was used in the MAXScript "Max Dist for Parent Piv" spinner while painting your asset.



Outputs



Parent Piv Position

Returns the pivot point information for each parent in world space. Children return the pivot point information of the parent they are attached to.

Parent X Axis Vector

Returns a normalized vector pointing down the parent's x-axis.

Child Piv Position

Return the pivot position information in world space for each child. Parents return a value of (0,0,0).

Child X-Axis Vector

Returns a normalized vector pointing down the parent's x-axis.

Object Pivot Point

Location of the object's pivot point.

Object Orientation

The orientation of the object.

Object Scale

The scale of the object.

Object Black Mask

(Currently non-functional) Returns a black value for surfaces that are painted black by the Pivot Painter tool.



The outputs labeled "-----------------" exist as separators in the list and are not intended to be used.

PivotPainter_PerObjectData

This particular function is designed to work on a per-object basis.

Item

Description



Outputs



Pivot Position

Returns the pivot point information for each element in world space.

Child X-Axis

Returns a normalized vector pointing down the element's X-Axis, which points from the pivot point toward the averaged center of the mesh.

Random Value Per Element

Returns a random value per element in the 0-1 range.

Custom Alpha Values

Returns the custom falloff values stored in the vertex alpha channel of the model.

Object Scale

Returns a scalar value that is equal to the object's uniform scale.



PivotPainter_PerObjectFoliageData

This function is designed to work specifically with individual foliage objects.

Item

Description



Inputs



Wind Vector (Vector4)

Takes in the incoming vector for the wind's direction and magnitude.

Optimized for Foliage Placement (StaticBool)

Set to true if you processed the mesh using Pivot Painter with the "Optimize for Foliage Placement" option checked. Default is false.

Optimized Vector (Vector3)

Enter a local vector to be used as the element's rotation axis. This is only viable if the Optimized for Foliage Placement input is set to true.



Outputs



Piv Position

Returns the pivot point information for each element in world space.

Element Rot Axis

Returns a rotation axis for branches to be used with the "RotateAboutAxis" node. Leaves return the same information. Note: The angle is found by transforming a vector along the branch's x-axis from local to world space. Then the cross product is found between the wind direction and the transformed vector.

Element X-Axis

Returns a normalized vector pointing down the elements X-Axis. Which points from the pivot point toward the averaged center of the mesh.

Random Value Per Element

Returns a random value per element in the 0-1 range.

Custom Alpha Values

Returns the custom falloff values stored in the vertex alpha channel of the model.

Normalized Wind Vector

The vector for the wind direction and magnitude normalized to 0-1.

Wind Speed

Outputs wind speed multiplied by time multiplied by -1.

Wind Strength

Returns wind strength. The magnitude of the wind vector found by calculating distance from the wind vector to 0.

Object Scale XYZ

Returns a scalar value that is equal to the object's uniform scale.

Uniform Object Scale

Returns a scalar value that is equal to the object's uniform scale.



PivotPainter_TreeData

The outputs starting with tree process the model's UV information as it would be stored by the Pivot Painter MAXScript. The outputs starting with Leaf process the UV information as it would be stored by the per-object pivot painting section of the script.

Item

Description



Inputs



WindVector (Vector3)

This is the direction that the wind will be blowing.

Max Dist for Parent Piv (Scalar)

This value should match the value that was used in the max script "Max Dist for Parent Piv" spinner while painting your asset.



Outputs



Branch Piv Position

Returns the pivot point information for each branch in world space. Leaves return the pivot point information of the branch they are attached to.

Branch Wind Rot Axis

Returns a rotation axis for branches to be used with the "RotateAboutAxis" node. Leaves return the same information. Note: The angle is found by transforming a vector along the branch's x-axis from local to world space. Then the cross product is found between the wind direction and the transformed vector.

Branch X-Axis Vector

Returns a normalized vector pointing down the branches x-axis. This is not typically needed for foliage animations unless it is needed for custom vector calculations.

Branch Flow Grad

Returns a gradient value in the direction of the blowing wind.

Branch Flow Grad 90 Deg

Returns a gradient value across world space at a 90 degree angle to the wind.

Leaf Piv Position

Return the pivot position information in world space for each leaf. Branches return a value of (0,0,0).

Leaf Rot Axis

Returns a rotation axis for leaves to be used with the "RotateAboutAxis" node. Branches return (0,0,0). Note: The angle is found by transforming a vector along the leaf's x-axis from local to world space. Then the cross product is found between the wind direction and the transformed vector.

Leaf X-Axis Vector

Returns a normalized vector pointing down the branches x-axis. This is not typically needed for foliage animations unless it is needed for custom vector calculations.

Leaf Mask

Returns a white mask for leaves. All branches are black.

Leaf Flow Grad

Returns a gradient value in the direction of the blowing wind.

Leaf Flow Grad 90 deg

Returns a gradient value across world space at a 90 degree angle to the wind.

Object Pivot Point

Returns the pivot point location of the object.

Object Orientation

Returns the orientation of the object.

Object Rotation Axis

Returns the rotation axis for the object.

Object Scale

Returns the scale of the object.

Object Flow Grad

Gradient aligned with the wind vector at object level in world space.

Object Flow Grad 90 deg

Gradient aligned with the wind vector at object level in world space, rotated 90 degrees.

WindStrength

Returns wind strength. The magnitude of the wind vector found by calculating distance from the wind vector to 0.

Normalized Wind Vector

Returns a normalized wind vector with a magnitude between 0-1.

WindSpeed

Wind speed multiplied by time.

Black Mask

Returns a black value for surfaces that are painted black by the pivot painter tool. This mask only works in the vertex shader.



The outputs labeled "-----------------" exist as separators in the list and are not intended to be used.

Blend Functions

Blend_ColorBurn

Blend_ColorDodge

Blend_Darken

Blend_Difference

Blend_Exclusion

Blend_HardLight

Blend_Lighten

Blend_LinearBurn

Blend_LinearDodge

Blend_LinearLight

Blend_Overlay

Blend_PinLight

Blend_Screen

Blend_SoftLight

A Blend is a type of function that performs mathematical calculations in the color information of a texture so that one texture can blend into another in a particular manner.

Blends will always have a Base and a Blend input, both of which are Vector3. These will each take in a texture and the two will be blended in some way. The manner in which the blend takes place depends on the type of blend function used.

Blend Functions

Below is a list of all of the blend material functions.

Blend_ColorBurn

Blend_ColorBurn blends the textures in such a way that the darker the Blend color the more of that color will be used in the final result. If the Blend color is white, no change takes place.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_ColorDodge

Blend_ColorDodge lightens the result by inverting the Base color and dividing it by the Blend color.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_Darken

Blend_Darken works by choosing the darker value for each pixel of the Base and Blend colors. A white Blend color does not produce a change.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_Difference

Blend_Difference creates a sort of inversion-style effect by subtracting the Base from the Blend and then taking the absolute value of the result.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_Exclusion

Blend_Exclusion halves both the Base and Blend textures, combines them, and then does a partial inversion on the result.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_HardLight

Like a harsher version of Blend_Overlay, Blend_HardLight will either screen or multiply the Base and Blend together. The function does a comparison on the Blend color such that wherever the Blend is brighter than 50% gray, the Base and Blend will be combined via a Screen operation. If the Blend is darker than 50% gray, the Base will be multiplied by the Blend as in the Multiply function. The contrast of the final result is then boosted for a harsh output.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_Lighten

Blend_Lighten compares each pixel of the Base and Blend colors and returns the brighter result.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_LinearBurn

Blend_LinearBurn adds Base color to the Blend color and then subtracts 1 from the result.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_LinearDodge

Blend_LinearDodge adds the Base color to the Blend color.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_LinearLight

Blend_LinearLight is a linear version of Blend_Overlay, providing harsher results. The function does a comparison on the Blend color such that wherever the Blend is brighter than 50% gray, the Base and Blend will be combined via a Screen operation. If the Blend is darker than 50% gray, the Base will be multiplied by the Blend as in the Multiply function.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_Overlay

Blend_Overlay will either screen or multiply the Base and Blend together. The function does a comparison on the Blend color such that wherever the Blend is brighter than 50% gray, the Base and Blend will be combined via a Screen operation. If the Blend is darker than 50% gray, the Base will be multiplied by the Blend as in the Multiply function.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_PinLight

Like Blend_Overlay, Blend_PinLight will either lighten or darken the Base and Blend together. The function does a comparison on the Blend color such that wherever the Blend is brighter than 50% gray, the Base and Blend will be combined via a Screen operation. If the Blend is darker than 50% gray, the Base will be multiplied by the Blend as in the Multiply function. The contrast is softened, making this a less harsh version of Overlay.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_Screen

Blend_Screen lightens the Base by the Blend color. It does this by doing a "one minus" on both colors, multiplying them together, and taking a one-minus of the result.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Blend_SoftLight

Blend_SoftLight is a softer version of Overlay. The function does a comparison on the Blend color such that wherever the Blend is brighter than 50% gray, the Base and Blend will be combined via a Screen operation. If the Blend is darker than 50% gray, the Base will be multiplied by the Blend as in the Multiply function. The contrast is softened, making this a less harsh version of Overlay.

Item

Description



Inputs



Base (Vector3)

The base, or original texture that will be blended with the Blend texture in some way.

Blend (Vector3)

The blend texture, which is combined with the base in some way based on the type of blend operation taking place.









Base

Blend

Result

Gradient Functions

Radial Gradient Exponential

Diamond Gradient

Linear Gradient

Smooth Curve

Value Step

The Gradient functions produce procedurally generated gradients made from Texture coordinate expressions. They save memory over having to create a texture-based gradient.

Gradient Functions

Below is a list of the gradient functions.

Radial Gradient Exponential

The RadialGradientExponential function uses UV channel 0 to produce a radial gradient, giving the user the ability to adjust the radius and offset the center point.

Item

Description



Inputs



UVs (Vector 2)

Allows the ability to control where the gradient resides and how much it covers of the 0-1 space.

CenterPosition (Vector2)

A 0-1 based offset for the position of the gradient's center.

Radius (Scalar)

The size of the radial gradient from its center. The default of 0.5 puts the edges of the gradient at about the edge of the texture space.

Density (Scalar)

Adjusts the hardness of the resultant gradient generated by the Function. The higher the number means the sharper the gradient.

Invert Density (Boolean)

Inverts white into black and black into white for the gradient.





Default Output Result

Diamond Gradient

The DiamondGradient function uses UV channel 0 to produce a radial gradient, giving the user the ability to adjust the falloff rate of the gradient.

Item

Description



Inputs



Falloff (Scalar)

Boosts gradient contrast by controlling how quickly the gradient shifts from white to black.





Default Output Result

Linear Gradient

The LinearGradient function uses UV channel 0 to generate a linear gradient in either the U or V direction, depending on which output is used.

Item

Description



Outputs



UGradient

Outputs a linear gradient in the U direction.

VGradient

Outputs a linear gradient in the V direction.





Default U Output Result



Default V Output Result

Smooth Curve

The SmoothCurve function takes in an existing texture channel or gradient and uses a procedural curve to control the transition from dark to light. The user can adjust the tangents of this curve to change the result.

Item

Description



Inputs



Tangent 1 (Scalar)

Controls the angle of the second tangent of the curve.

X (Scalar)

The incoming texture channel or gradient.

Tangent 0 (Scalar)

Controls the angle of the first tangent of the curve.





Default Output Result

Value Step

The ValueStep function takes in an existing texture channel or gradient and outputs a pure black and white image based on inputs from the user. The result is a mask that represents what portion of the gradient equals the value of the inputs.

Item

Description



Inputs



Mask Offset Value (Scalar)

Offsets where the black spots are placed on the result.

Number Before White Result (Scalar)

Controls the upper limit of values that output to black. For example, if you have a gradient that goes from 0-10 and you set this value to 9, then all values between 0-9 will be black. 10 will be white.

Gradient (Scalar)

Takes in a gradient with values above 1.





Default Output Result

3ColorBlend

CheapContrast

CheapContrast_RGB

SCurve

3PointLevels

HueShift

SmoothThreshold

The Image Adjustment functions exist as a way to perform basic color correction operations on textures. They are useful in that they allow corrective actions or variations on a texture without having to worry about the overhead of loading a separate version into memory.

3ColorBlend

The 3ColorBlend function blends between 3 input colors based on a grayscale alpha, in the following manner:



Alpha Tone

Color

Dark Tones

Color A

Midtones

Color B

Highlights

Color C

Inputs

Description

Color A (3Vector)

This color will be applied wherever the alpha supplies dark tones to blacks.

Color B (3Vector)

This color will be applied wherever the alpha supplies midtones.

Color C (3Vector)

This color will be applied wherever the alpha supplies highlights to whites.

Alpha (Scalar)

This maps out where each color will be applied, as per above.

CheapContrast

The CheapContrast function boosts the contrast of an input by remapping the high end of the histogram to a lower value, and the low end of the histogram to a higher one. This is similar to applying a Levels adjustment in Photoshop, and pulling the black and white flags in a bit. The user may control the degree to which the contrast is boosted.

Inputs

Description

In (Scalar)

The channel or black and white image having its contrast boosted.

Contrast (Scalar)

How much to boost contrast. 0 is default, or no change.

This function takes in a scalar value rather than RGB, meaning it is particularly suited to black and white images or single channels. For contrast boost on full-color images, use CheapContrast_RGB.



CheapContrast_RGB

The CheapConstrast_RGB function boosts the contrast of an input by remapping the high end of the histogram to a lower value, and the low end of the histogram to a higher one. This is similar to applying a Levels adjustment in Photoshop, and pulling the black and white flags in a bit. The user may control the degree to which the contrast is boosted.

Unlike the regular CheapContrast function, this function can take in a Vector3 as the input, allowing it to perform contrast operations on a color image.

Inputs

Description

In (Scalar)

The base image having its contrast boosted.

Contrast (Scalar)

How much to boost contrast. 0 is default, or no change.



SCurve

The SCurve function boosts contrast of an image by interpolating the values of each channel values of an image along an S-curve. This is similar to applying a Curves adjustment in Photoshop and setting the RGB curve to an S-curve or using the Increase Contrast (RGB) preset.

Inputs

Description

In (Scalar)

The base image having its contrast boosted.

Power (Scalar)

How much to boost contrast. 1 is default, or no change.

Examples of the SCurve Function with different Power values.



3PointLevels

The 3PointLevels function takes in an image and remaps the values of each channel across 3 points (white, black, middle). This is similar to applying a Levels adjustment in Photoshop. However, unlike the CheapContrast functions, this function provides full control in that it gives the user ability to adjust interpolation of lights, darks, and grays (gamma). By default, the three remapping points are interpolated linearly. However, you may input your own custom interpolation curve if you wish.

Inputs

Description

Texture (Scalar)

The input texture.

New Black Value (Scalar)

Set the new value for the previous value of 0.

New Middle Value (Scalar)

Replaces the old value that matches the Middle Point input value.

New White Value (Scalar)

Set the new value for the previous value of 1.

Middle Point (Scalar)

Pick a value from the input image that will get replaced with the value from Middle Point.

Define Interpolation Curve (StaticBool)

Set to true if you want to define your own interpolation curve using the Interpolation Power input.

Interpolation Power (Scalar)

A power node applied to the interpolation. This controls the interpolation between the three points (black, white, and middle).

Invert Interpolation Power

Set to true if you want to invert the power curve (this generally lowers contrast instead of boosting it).



The "-------------" inputs of this node are merely separators in the list of inputs for sake of clarity. They are not intended to receive actual connections.

Like the CheapContrast function, this node takes in a scalar by default, meaning it is suited for single channels or black and white images.

HueShift

The HueShift function offsets the current hue value of an input color by a given percentage. This percentage is 1-based and centered around the color wheel. For instance, a shift of 0.5 (50%) will shift to a complimentary hue, or the hue on the opposite side of the color wheel. A shift of 1.0 (100%) gives no change, as this is the equivalent of rotating completely around the color wheel.

Inputs

Description

Hue Shift Percentage (Scalar)

How far around the color wheel to shift the incoming hue.

Texture (Vector3)

The incoming texture having its hue shifted.



SmoothThreshold

The SmoothThreshold function takes in a gradient, an interpolation rate, and a threshold value (Cutoff Value). It then applies a smooth contrast to the gradient, based on the inputs. Here is a breakdown of what each input does:

Inputs

Description

Cutoff Value

Gradient input values that fall below the cutoff value will be affected by the operation.

Lerp Value

Add a negative or positive number to smoothly ramp to from the original values. Ramping occurs in values lower than the cutoff value.

Gradient

This value serves as the base for the contrast operation.



Add Components

Pi

LinearSine

VectorToRadialValue

Math functions perform basic math equations on the values of pixels within a Material network.

Add Components

The AddComponents function takes in a Vector2, a Vector3, or a Vector4, combines their components together and then outputs the result. You must use the appropriate output for the corresponding input. For example, if you input an image into f3 (Vector3), then you must use the f3 output.

Item

Description



Inputs



f2 (Vector2)

Takes in a Vector2 value so that its components can be added together and sent to the f2 output.

f3 (Vector3)

Takes in a Vector3 value so that its components can be added together and sent to the f3 output.

f4 (Vector4)

Takes in a Vector4 value so that its components can be added together and sent to the f4 output.



Outputs



f2 (Vector2)

Outputs the combined value of the components from the f2 input.

f3 (Vector3)

Outputs the combined value of the components from the f3 input.

f4 (Vector4)

Outputs the combined value of the components from the f4 input.



Since each input is calculated individually for its corresponding output, you may use all three inputs on a single node, so long as you also use an output for each one. For instance, you may use one AddComponents function node to combine the components of a Vector2, utilizing the f2 output, and use the same node to combine the components of a Vector3, utilizing the f3 output.

Pi

The Pi function serves as a constant for Pi, as calculated to the 6th decimal place (3.141592). The node also comes with an input for a multiplier.

Inputs

Description

Multiplier (Scalar)

Input a value that will be multiplied times pi.



LinearSine

The LinearSine function takes in a scalar value and outputs the linear sine (or rounded linear sine) of that value, running between 0 and 1. If you connect a Time expression to the value input and use the Linear Sine, you can see animation in the output that coincides with a linear sine wave.

Item

Description



Inputs



Value (Scalar)

This is the incoming value to which the linear sine function will be applied. If this value changes over time, the output will be a wave.

Period (Scalar)

Period controls the time required to make one full transition. Input values higher than 1 to slow the wave down.

-1 to 1 (StaticBool)

Setting this to true scales and offsets the wave to run between -1 and 1, rather than 0-1.

Sine Phase (StaticBool)

Setting this true will output normal sine behavior rather than linear behavior.



Outputs



Linear Sine

This outputs a linear sine wave.

Rounded Linear Sine

Outputs a linear sine with rounded edges.

Direction

Outputs 0 or 1, depending on whether the sine wave is traveling downward (0) or upward (1).

VectorToRadialValue

The VectorToRadialValue function transforms the vector of a Vector2 into an angle, or transforms UV coordinate data into radial coordinates. In the case of a vector, the angle will output in one channel and the length of the vector in the other.

Item

Description



Inputs



Vector or UVs (Vector2)

Takes in either a Vector2 or a set of UV coordinates.

Swizzle Coordinate Output (StaticBool)

Flips the U and V components of the output.



Outputs



Radial Coordinates

Returns the radial coordinates of the input. In the case of a vector, the angle is on one channel and the distance is on the other.

Vector Converted to Angle

Returns the angle of the input vector or a radial gradient in the case of UVs.

Linear Distance

Returns the linear length of the input vector, or in the case of UVs, outputs a radial gradient of distances.



TimeWithSpeedVariable

OffsetAndScaleTo1

PassThrough

SplitComponents

Flipbook

The Misc Material functions category includes a variety of one-off functions that do not readily fit into any of the other existing categories. They are placed here to avoid too many categories with only one function inside.

TimeWithSpeedVariable

The TimeWithSpeedVariable functions just like a time node, but with an optional input for a multiplier. This function can output the multiplied result, or has an optional Frac Time output for only outputting the decimal places of the multiply operation.

Item

Description



Inputs



Speed (Scalar)

Takes in a multiplier to adjust the rate at which time plays out. Values greater than 1 will speed up the result. Values between 1 and 0 will slow it down.



Outputs



Frac Time (Scalar)

This outputs just the numbers after the decimal once the multiplier has been applied. The result is ramp wave behavior running between 0 and 1.

Time (Scalar)

The result of time multiplied by the Speed input.



The Output Result will preview the node by default. In this case, the node will flicker.

OffsetAndScaleTo1

The OffsetAndScaleTo1 function takes in a value, offsets it by a given amount, and then scales the result back down to the 0-1 range.

Inputs

Description

Original Value (Scalar)

The value that will be offset by the Offset Amount and then scaled back to the 0-1 range.

Offset Amount (Scalar)

This controls the amount of offset before the result is scaled back to 0-1.



PassThrough

As its name suggests, this node serves merely as a pass-through. Whatever is passed into it is returned unchanged via the output. It exists more for organizational purposes than anything else, as it would allow you have labeled nodes (via the Desc property) that connect much closer to another node, which is useful if the required node is far across the graph.

SplitComponents

The SplitComponents function busts apart the components of an incoming color or image, giving you individual access to the red, green, or blue channels.

Item

Description



Inputs



Color

Takes in a given color or texture.



Outputs



RGB

Outputs the combined RGB components of a given color.

R

Outputs only the red component of the input color or texture.

G

Outputs only the green component of the input color or texture.

B

Outputs only the blue component of the input color or texture.



Flipbook

The Flipbook function takes in a Texture2D, such as a grid of sprite frames, and outputs an animation of them playing back in order.

Item

Description



Inputs



Animation Phase (0-1) (Scalar)

If this receives a static input, then the result will give the nearest frame of the flipbook as if the frames were numbered between 0 and 1. If no input is given, time is automatically used.

Number of Rows (Scalar)

This takes in the number of rows of the flipbook texture.

Number of Columns (Scalar)

This takes in the number of columns of the flipbook texture.

Texture (Texture2D)

Takes in a Texture2D containing a sprite sheet, or grid of frames of an animated texture.

UVs (Vector2)

Takes in a set of UV coordinates to assist in tiling.



Outputs



Result

Outputs an image as the result of the flipbook.

UVs

Outputs the UV coordinates corresponding with a given frame of the texture sheet.



SoftOpacity

Opacity Material Functions exist to speed up the handling of complex opacity calculations.

SoftOpacity

The SoftOpacity function takes in an Opacity value and then runs a variety of calculations on it to give it a softer feel. It applies a Fresnel effect, depth-based alpha, and pixel depth. The end result causes the object to fade away as the camera approaches it.

Item

Description



Inputs



DepthFadeDistance (Scalar)

The depth at which objects have completely faded away. Only viable if using the OutputUsesDepthBias output.

OpacityIn (Scalar)

This is the incoming opacity value.

FadeDistance (Scalar)

How close you should get to the surface before it starts fading out.



Outputs



OutputUsesDepthBias

This output causes the object to fade completely away to complete transparency by the time it reaches the distance set in the DepthFadeDistance input.

OutputNoDepthBias

This output causes the object to fade completely away as it reaches the camera, meaning there is no offset. This output is 12 instructions less expensive than OutputUsesDepthBias.



In this example, the cylinder appears more transparent along the edges, where the mesh curves away from the camera. This is due to the Fresnel effect in the Material Function.

Particle Functions

3dParticleOpacity

Particle functions are designed to aid in complex material generation for particle systems.

Particle Functions

The following is a list of all the functions underneath the Particles category.

3dParticleOpacity

The purpose of this function is to help setup particles such that they fade away as they move away from the camera.

Item

Description



Inputs



Depth Texture (Scalar)

Takes in an inverted z-depth render (black near the camera and white values in the background). Be sure that the texture's SRGB switch is disabled in the texture properties window.



Depth Texture Options



Use dynamic or explicit texture depth settings (StaticBool)

The default setting (true) is dynamic texture depth. Using explicit texture settings (false) will allow you to specify exactly how many world units your depth texture represents. For example, 512 units would make the texture 512 units deep. The dynamic texture depth option will use the ratio between the particle's size and its depth to scale the depth for differently scaled particles. For example, if your ratio was set to 1, a square particle that was 512 units would set the 512 unit depth texture. A ratio value of 0.5 would generate a texture depth of 256. This helps the effect scale properly with various particle sizes.

Dynamic Texture Depth Ratio (Scalar)

Enter the ratio of the height texture's depth to the height texture's width (use 3ds Max world unit measurements). For instance, if you create a plane in a 3D application that is 512x512 and you render a height texture from that plane that represents 256 units away from the plane then you would calculate this number by dividing 256/512, which would be a ratio of 0.5.

Explicit Texture Depth Ratio (Scalar)

World space scale of the depth texture. A value of 256 will make the depth texture 256 units deep.

Depth Texture Falloff Softness (WS)(1/n) (Scalar)

The distance in world space units across which the object's opacity gradually fades. Enter 1 divided by the number of world space units across which you would like the transition to take place. For instance, enter 1/16 in the input field and Unreal will convert that number to 0.062500. Doing this ahead of time removes an instruction from the effect.



Camera Falloff Group



Use Near Camera Falloff (StaticBool)

Setting this to true makes the particles falloff as they approach the camera. The default value is false.

Near Camera Falloff Start Distance (Scalar) -

The distance in world space units from the camera where the object maintains its remains transparent.

Near Camera Fade Distance (1/n) (Scalar)

The distance from the camera where the opacity fades to 0. Enter the reciprocal of the target distance. For example, to fade the particle out over 256 units enter 1/256, which Unreal will convert into 0.003906.

Use Depth In Camera Falloff Calculation (StaticBool)

Makes closer pixels (according to the depth map) fade out before farther pixels. The default value is false.



Particle Alpha Group



Use Particle Alpha (StaticBool)

Multiplies the result by the particle color alpha channel. The default value is false.



WPO Group



Camera Offset (Scalar)

This value should be the same value as Texture Depth. The Texture Depth value is used as this input's default value.



Outputs



Opacity

Provides the final opacity calculation after falloff.

World Position Offset

Emulates what camera offset does in the Particle Editor.



Any input prefixed by "--------" is intended to be a separator in the input list and is not meant to receive actual inputs.

GeneratedBand

GeneratedOffsetBands

NormalFromHeightmap

NormalFromHeightmapChaos

The Procedural Material functions provide a quick way to make simple procedurally generated textures and masks. This saves memory over having to use imported textures.

GeneratedBand

The GeneratedBand function generates a horizontal or vertical band from the default TextureCoordinates.

Inputs

Description

Width (Scalar)

A 0-1 value that calculates the width of the procedural band. The default is 0.25.

Sharpness (Scalar)

This controls the falloff of the band's edges. A setting of 100 will produce a very sharp band with aliasing.

Offset (Scalar)

This value will slide the band around the texture space.

Direction Switch (StaticBool)

Setting this to true will cause the band to be vertical instead of horizontal. Default is false, or horizontal.

Compare (Scalar)

This is the value the texture coordinate is compared against in order to produce the band. The default is 0.5.

Input Coordinates (Vector2)

Takes in a custom set of UVs rather than the default ones already built into the function.



GeneratedOffsetBands

Like the GeneratedBand function, GeneratedOffsetBands creates procedurally generated bands of texture across the UV space. However, this function can produce multiple bands instead of just one.

Inputs

Description

Width (Scalar)

A 0-1 value that calculates the width of the procedural band. The default is 0.25.

Sharpness (Scalar)

This controls the falloff of the band's edges. A setting of 100 will produce a very sharp band with aliasing.

Offset (Scalar)

This value will slide the band around the texture space.

Direction Switch (StaticBool)

Setting this to true will cause the band to be vertical instead of horizontal. Default is false, or horizontal.

Compare (Scalar)

This is the value the texture coordinate is compared against in order to produce the band. The default is 0.5.

Bands (Scalar)

This modifies the total number of bands.

Input Coordinates (Vector2)

Takes in a custom set of UVs rather than the default ones already built into the function.



NormalFromHeightmap

This function serves as a quick way to make a normal map out of an existing black and white heightmap, rather than having to load a separate texture into memory.

This function takes in a TextureObject (T2d) expression node, rather than a TextureSample.

Inputs

Description

Coordinates (Vector2)

Takes in the coordinates for proper scaling/tiling of the heightmap.

Height Bias (Scalar)

This is the spread used to derive a proper height from the heightmap. Default value is 0.005.

Height (Scalar)

This controls the final strength of the normal map. Default is 8.

Heightmap In (TextureObject)

Takes in the heightmap texture from a TextureObject expression node.



NormalFromHeightmapChaos

The NormalFromHeightMapChaos function takes a heightmap and pans it in 4 directions, then blends the result back together to make a chaotically animated normal map.

This function is considered expensive and should be used with care.

Inputs

Description

Coordinates (Vector2)

Takes in the coordinates for proper scaling/tiling of the heightmap.

Height Bias (Scalar)

This is the spread used to derive a proper height from the heightmap. Default value is 0.005.

Height (Scalar)

This controls the final strength of the normal map. Default is 8.

At the time of this writing, there is currently no input for a heightmap. Such an input can be added using the steps below. However, if you see a heightmap input, then this has been corrected and the steps below are not needed.



Double-click on the NormalFromHeightmapChaos function node to open it in a new Material Editor tab.

Locate the Texture Object (T2d) expression node. It should currently have the default texture inside it.

Create a FunctionInput expression node and connect it to the Texture (T2d) inputs on the 3 Motion_4WayChaos function nodes.

In the properties for the new FunctionInput expression, set the Input Type property to FunctionInput_Texture2D.

Set the Input Name property to "Heightmap In" to label the input.

Connect the original Texture Object (T2d) expression node into the Preview input of the new FunctionInput expression node.



ViewAlignedReflection

WorldAlignedReflection

CustomReflectionVector

This example shows off the real-time reflection capabilities of Unreal Engine. The scene shows a subway terminal with a lot of water leaks, grimy ceramic tiles, dilapidated pipe work, and other worn-out environment details. In this document, we will give an overview of some of the Functions that you can use to manipulate reflections like these.

ViewAlignedReflection

This function takes in a spherical reflection texture and aligns it to the view. The calculation can be offset by inputting a custom reflection vector.

Inputs

Description

ReflectionVector (Vector 3)

Takes in an existing reflection vector that needs to be aligned to the view.

ReflectionTexture (TextureObject)

Takes in an existing reflection texture, which needs to be spherical.



Outputs



Texture

Outputs the resulting view-based reflection texture.

UVs

Outputs the UV coordinates of the reflection texture so they can be reapplied elsewhere.



WorldAlignedReflection

This function takes in an incoming sphere-based reflection texture and aligns it to the world coordinates. The calculation can be offset by inputting a custom reflection vector.

Inputs

Description

ReflectionVector (Vector 3)

Takes in an existing reflection vector that needs to be aligned to the view.

ReflectionTexture (TextureObject)

Takes in an existing reflection texture, which needs to be spherical.



Outputs



WorldReflection

Outputs the world-based reflection texture.

WorldReflectionShadowed

Outputs a more highly contrasted version of the texture that can be applied in shadowed areas.



CustomReflectionVector

This function uses a normal map to generate a reflection vector independent of the default reflection vector and the normal's input on the base shader.

Inputs

Description

Normal (Vector3)

Takes in a normal map to be used as the basis for the custom reflection vector.



FuzzyShading

FuzzyShadingGrass

The Shading Material functions provide for specialized shading operations, such as fuzzy shading and adjusting the shape of a specular highlight.

FuzzyShading

This function emulates a surface similar to velvet or moss, and is similar to a Fresnel calculation. Incidentally, it is also useful for shader effects such as a scanning electron microscope.

Inputs

Description

Diffuse (Vector3)

Takes in a texture to be used as the diffuse color.

Normal (Vector3)

Takes in a normal map used to perturb the surface of the fuzzy result.

CoreDarkness (Scalar)

Value used to darken the object wherever its normals become parallel to the camera, generally toward the center. The higher the number, the darker the core. Default is 0.8.

Power (Scalar)

Controls the rate of falloff from the core to the edge. Default is 6.0.

EdgeBrightness (Scalar)

Controls how bright the surface becomes as its normals become perpendicular to the camera, generally toward the edges.



FuzzyShadingGrass

This function is designed to provide the diffuse portion of grass shading. Similar to FuzzyShading, this function allows you to blend in a new color at the edges by first desaturating by a given percentage and then applying a custom color to the desaturated area.

Inputs

Description

EdgeDesat (Scalar)

0-1 number controlling how much the edges of the object should be desaturated to make way for the edge color.

EdgeColor (Vector3)

This color will be applied to the edge area. Use EdgeDesat to desaturate that area if too much color mixing is taking place.

Diffuse (Vector3)

Takes in a texture to be used as the diffuse color.

Normal (Vector3)

Takes in a normal map used to perturb the surface of the fuzzy result.

CoreDarkness (Scalar)

Value used to darken the object wherever its normals become parallel to the camera, generally toward the center. The higher the number, the darker the core. Default is 0.8.

Power (Scalar)

Controls the rate of falloff from the core to the edge. Default is 6.0.

EdgeBrightness (Scalar)

Controls how bright the surface becomes as its normals become perpendicular to the camera, generally toward the edges.



CylindricalUVs

DetailTexturing

LocalAlignedTexture

ZWorldSpaceFlow

TextureCropping

WorldAlignedNormal

WorldAlignedTexture

3DSandMayaUVCoordinates

CustomRotator

HeightLerp

CameraWorldBlend

LocalSpaceSurfaceMirroring

SubUV_Function

TwoSidedTexturing

WorldCoordinate3Way

Texturing functions provide for specialized handling of texture-based actions, such as adjusting UVs of a texture, cropping textures, and many others. The following is the list of Texturing Functions.

CylindricalUVs

This function tiles a texture around an object using cylindrically projected UVs centered around the object's center.

Inputs

Description

TextureObject (Texture Object)

The texture to be projected via Cylindrical UVs.

In (Scalar)

This takes in the height of the projection cylinder in world space units.

Normal (Vector3)

Input a vector to rotate the projection cylinder.



Outputs



Cylinder Projection

Outputs the resulting texture as if it was projected from a cylinder. There are no caps, however, so the texture will tend to pinch at the top and bottom.

Cylinder Projection w Top

Outputs the resulting texture as if it was projected from a cylinder, complete with caps.



DetailTexturing

The DetailTexturing function simplifies the process of creating detail textures for your material. Detail texturing allows you to give the illusion of more detail in a texture by bringing in a more highly repeated diffuse and normal map combination which layers over the original diffuse and normal for an object. This gives the illusion of greater detail at close range.

Inputs

Description

Scale (Scalar)

Controls the tiling of the detail normal and diffuse.

Diffuse (Vector3)

The original diffuse texture that requires more detail.

DetailDiffuse (Texture Object)

The diffuse texture for the added detail.

DiffuseIntensity (Scalar)

How much you want the detail diffuse to blend into the original diffuse.

Normal (Vector3)

The original normal which requires more detail.

DetailNormal (Texture Object)

The detail normal which will be used to add more detail to the original normal map.

NormalIntensity (Scalar)

How much the detail normal will show through over the original.



Outputs



Diffuse

The result of the original diffuse texture blended with the detail diffuse texture.

Normal

The result of the original normal texture blended with the detail normal texture.



LocalAlignedTexture

The LocalAlignedTexture function tiles a texture on an object in local space.

Although this function has an input for a normal, at this time the input is nonfunctional.

Inputs

Description

Normal (Vector3)

This takes in a normal to use as the object's surface reference. At this time, this input is nonfunctional.

TextureObject (Texture Object)

Takes in a texture to be tiled in world space.



Outputs



XY Texture

The result of the texture as tiled across the world X and Y coordinates.

XYZ Texture

The result of the texture as tiled across the world X, Y, and Z coordinates.

Z Texture

The result of the texture as tiled across the world Z coordinate.



ZWorldSpaceFlow

The ZWorldSpaceFlow function pushes a texture along the tangent space of an object, causing that texture to look like it is "flowing" along that surface. It works by making two variations of the texture panning in the same direction, but each with a slight offset from the other. It then blends each one over the other in a repeating fashion.

Inputs

Description

FlowTexture (Texture Object)

This is the texture that you want to have flowing across the surface of your object.

FlowStrength (Scalar)

Controls the amount of blend that takes place as the two panning versions of the texture blend into one another. Fine tune this to control the surface area over which blending takes place.

FlowDirection (Vector2)

The 2D vector that controls the direction the texture will flow.

UVs (Vector2)

Any existing UVs for the texture to control tiling.

FlowSpeed (Scalar)

How fast the texture will flow across the surface.

TextureCropping

The TextureCropping function allows you to crop down a given texture to a smaller and offset location on the texture coordinate plane. This is perfect for placing a block of color on top of an emissive texture region.

This function does not actually perform a true cropping operation such as one might be used to in image editing packages such as Photoshop. Rather, it remaps the existing texture to new coordinates in UV texture space, which is a lot more like scaling than cropping. However, the function is still highly useful for generating masks and adding color to texture regions.

Inputs

Description

UVs (Vector2)

The texture coordinates used on the newly cropped texture.

TextureIn (Texture Object)

The texture that is to be cropped.

UpperLeftCorner (Vector2)

The location for the new upper-left corner of the texture in 0-1 texture space.

LowerRightCorner (Vector2)

The location for the new lower-right corner of the texture in 0-1 texture space.



Outputs



Cropped

The result of the crop function. This will look a lot like a tiling operation.

CroppedMasked

This gives the result of the crop function, but while blacking out (masking) the areas outside the region defined by UpperLeftCorner and LowerRightCorner.

Crop UVs

The UV coordinates of the newly cropped region.

Crop Mask

A white area on a black background (mask) representing the area being cropped.



WorldAlignedNormal

WorldAlignedNormal takes in a normal map and aligns its texture to the world, rather than locally to the object. It also allows for scaling in world units, rather than as a percentage of the texture size.

Because this function tiles the texture in world space, it is important to note that any animated objects textured in this manner will experience texture "swimming," in which the texture remains in place while the object slides underneath it.

Inputs

Description

TextureObject (Texture Object)

This takes in the texture that will be tiled in world space.

TextureSize (Vector3)

The size of the texture in world units, along the X, Y, and Z axes.

Normal (Vector3)

This allows you to specify a normal direction for the world's up axis, thereby rotating the coordinates that this function uses. Defaults to 0,0,1, or Z-up.

WorldPosition (Vector3)

Provides an offset for the start point of the texture in 3D world space.



Outputs



XY Texture

The result of the texture projected in world X and Y.

XYZ Texture

The result of the texture projected in world X, Y, and Z.

XYZFlatTop

The result of the texture projected in world X, Y, and Z, with an added contrast boost.

Z Texture

The result of the texture projected in world Z.



Notice the texture is still aligned to world coordinates, even though the floor is rotated.

WorldAlignedTexture

The WorldAlignedTexture function serves as a way to tile a texture across the surface of an object in world space, independently of that object's size or rotation. This function allows you to specify the direction in which the texture will be projected, and offers scaling in world units rather than as a percentage of the texture size.

Because this function tiles the texture in world space, it is important to note that any animated objects textured in this manner will experience texture "swimming," in which the texture remains in place while the object slides underneath it.

Inputs

Description

TextureObject (Texture Object)

This takes in the texture that will be tiled in world space.

TextureSize (Vector3)

The size of the texture in world units, along the X, Y, and Z axes.

WorldPosition (Vector3)

Provides an offset for the start point of the texture in 3D world space.

ExportFloat 4 (StaticBool)

Whether or not to utilize the alpha channel of the incoming texture. Defaults to false.

World Space Normal (Vector3)

This allows you to specify a normal direction for the world's up axis, thereby rotating the coordinates that this function uses. Defaults to 0,0,1, or Z-up.

ProjectionTansitionContrast (Vector3)

When projecting in X, Y, and Z, this controls the contrast of the blend where two projection planes meet one another.



Outputs



XY Texture

The result of the texture projected in world X and Y.

Z Texture

The result of the texture projected in world Z.

XYZ Texture

The result of the texture projected in world X, Y, and Z.



Notice the texture remains aligned to world coordinates, even when the plane is rotated.

3DSandMayaUVCoordinates

This function flips the green channel of incoming UVs to place the 0,0 coordinate in the lower-left corner (as it is in 3ds Max and Maya) instead of the upper-left. This is important for models coming in from these applications, as it prevents you from having to flip textures.

Item

Description



Inputs



UVChannel0 - V-flipped UVs from UV channel 0.

UVChannel0 - V-flipped UVs from UV channel 1.

UVChannel0 - V-flipped UVs from UV channel 2.

UVChannel0 - V-flipped UVs from UV channel 3.



CustomRotator

The CustomRotator function allows you to rotate a texture. However, it stands apart from the basic Rotator expression node in that it exposes a center point around which the image rotates. It also changes the rotation system to be 0-1 based, so that a value of 1 is considered a complete rotation, or 360 degrees. On a standard Rotator, a complete rotation requires a Time input of approximately 25.1.

Inputs

Description

UVs (Vector2)

Takes in the existing coordinates for the texture.

Rotation Center (Vector2)

Location in texture space 0-1 that serves as the center of rotation.

Rotation Angle (0-1) (Scalar)

Rotation of the image in 0-1 format, with 1 being a full rotation.



Note in the video how the center of rotation changes when the Rotation Center values are changed in the Material Graph.

HeightLerp

The HeightLerp function allows you perform a linear interpolation between 2 textures based on a heightmap and a transition phase value. This allows you to adjust the value along the hightmap that the lerp takes place.

Inputs

Description

A (Vector3)

First texture of the lerp calculation.

B (Vector3)

Second texture of the lerp calculation.

Transition Phase (Scalar)

The value which defines the region of the heightmap where transition takes place. Leaving this at 0.5 performs a standard lerp, while adjusting the values toward 0 and 1 gives a bias toward the bottom or top of the heightmap, respectively.

Height Texture (Scalar)

The heightmap used for the lerp operation.

Contrast (Scalar)

Applies a contrast boost to the heightmap using the CheapContrast function.



Outputs



Results

The blended result of the HeightLerp function.

Alpha

The alpha value used in the lerp, with contrast boosting applied.

Lerp Alpha No Contrast

The alpha value used in the lerp, without any contrast boosting applied.



CameraWorldBlend

Outputs falloff results for the 3 primary world vectors based on the camera angle. Can be used to blend between textures based on direction the camera is looking.

This function appears to still be in development and may not give expected results.

Inputs

Description

Blend Power (Scalar)

The rate at which the textures blend from one to the other.

Use Reflection Vector (StaticBool)

If true, uses ReflectionVector instead of CameraVector (Material's Normal input will affect results). This defaults to false. However, at this time, as there is no false input data for the switch, leaving this set to false will yield no result.

Use Smoothable Normals (StaticBool)

If true, uses ReflectionVector instead of CameraVector (Material's Normal input will affect results). This defaults to false. However, at this time, as there is no false input data for the switch, leaving this set to false will yield no result.

Smooth Reflection Percentage (Scalar)

How much to smooth the normals being applied to the surface prior to blend.



Outputs



XY True

The falloff results which blend toward white as the surface aligns to the XY plane.

XZ True

The falloff results which blend toward white as the surface aligns to the XZ plane.

YZ True

The falloff results which blend toward white as the surface aligns to the YZ plane.



Notice that the green texture blends in wherever the surface aligns to the XY plane, with red everywhere else.

LocalSpaceSurfaceMirroring

The LocalSpaceSurfaceMirroring function applies mirroring to all faces of a surface that are oriented toward a given local axis. Other areas on the surface area masked out. These masks can be offset via a scalar input, and the entire calculation can be perturbed by a normal map. This is useful when you need to produce mirroring based on a surface's topology.

Inputs

Description

Use NormalMap (StaticBool)

Sets whether to calculate the direction of the surface after applying a normal map.

Normal Map (Vector 3)

Takes in a normal map that is used to perturb the object's surface prior to the local topology calculation.

In (Scalar)

This is an offset value that moves the resulting mask around.



Outputs



Local X

Outputs a masked mirror effect that only affects those surfaces facing the local X axis.

Local Y

Outputs a masked mirror effect that only affects those surfaces facing the local Y axis.

Local Z

Outputs a masked mirror effect that only affects those surfaces facing the local Z axis.

SubUV_Function

SubUV_Function is perfect for handling animation across a sprite sheet or texture with multiple frames. The function takes in a texture object, and based on the outputs can show a blended-frame animation of the frames on that texture.

Inputs

Description

Texture (Texture Object)

The incoming sprite sheet texture.

UVs (Vector2)

The UV coordinates for the texture, in case any tiling is needed.

SubImages (Vector2)

The number of frames on the texture, horizontally and vertically.

Frame (Scalar)

The current frame of the animation. This is zero-based and will blend on decimal values. For instance, a value of 2.35 would produce a 35% blend between the third and fourth frame.



TwoSidedTexturing

The TwoSidedTexturing function provides individual texture inputs for both sides of a two-sided material. This function does nothing if the material's Two Sided property is not active.

Inputs

Description

Texture Side A (Vector3)

The texture used on the positive side (outside) of the polygons.

Texture Side B (Vector3)

The texture used on the negative side (inside) of the polygons.

Use Surface Normals (StaticBool)

Tells the shader whether it should be using an incoming normal map to aid in calculating positive and negative sides of the mesh.

A different texture is applied to each side of the plane.



WorldCoordinate3Way

The WorldCoordinate3Way function projects a texture onto the surface of an object in world coordinates. The user has control over how multiple textures blend together at the edges, and a normal map can be added to perturb the surface prior to the calculation.

Because these textures are projected along world coordinates, any motion or rotation of the given object will cause the textures to "swim" along the surface.

Inputs

Description

XY Texture (Texture Object)

The texture that will be projected onto the XY plane.

YZ Texture (Texture Object)

The texture that will be projected onto the YZ plane.

XZ Texture (Texture Object)

The texture that will be projected onto the XZ plane.

XY Scale (Scalar)

Scaling applied to the texture that is being projected onto the XY plane.

YZ Scale (Scalar)

Scaling applied to the texture that is being projected onto the YZ plane.

XZ Scale (Scalar)

Scaling applied to the texture that is being projected onto the XZ plane.

Blend Exponent Y Z (Scalar)

Controls the rate of transition between the textures being projected along Y and Z.

Blend Mult Y Z (Scalar)

Multiplies the blend between the sides.

Blend Exponent X (Scalar)

Controls the rate of transition between the textures being projected along X.

Blend Mult X (Scalar)

Multiplies the blend between the sides.

Single Texture (StaticBool)

When set to true, this uses only the texture applied to the XY Texture input and projects it on all 3 sides.

Normal (Vector3)

This brings a normal map into the blend calculation, using it to determine what direction the surface is facing.

WorldPosition (Vector3)

This optional output allows you to offset the location of the projection center.



Outputs



XYZ Output

Outputs all 3 textures, projected from each plane, blending them at the edges.

XY

Outputs only the texture being projected along the XY plane.

XZ

Outputs only the texture being projected along the XZ plane.

YZ

Outputs only the texture being projected along the YZ plane.



Fresnel

The VectorOps category contains special Material functions for applying various vector-based math equations.

Fresnel

Unlike the regular Fresnel Material expression node, the Fresnel function allows you to designate your own set of vectors used to calculate the equation, as well as make other adjustments to the blend.

Item

Description



Inputs



Normal Vector (Vector3)

The first vector used in the Fresnel operation. Typically, this is the surface normal.

Camera Vector (Vector3)

The vector of the camera's direction.

Invert Fresnel (StaticBool)

This inverts the operation, reversing the way normals are calculated to yield results.

Power (Scalar)

This value controls how quickly color falls off between the core and the edges.

Use Cheap Contrast (StaticBool)

This activates an internal CheapContrast function to boost the contrast of the Fresnel's result.

Cheap contrast dark (Scalar)

When using cheap contrast, this controls how much the dark value shows in the result. Has no effect when not using cheap contrast.

Cheap contrast bright (Scalar)

When using cheap contrast, this controls how much the bright value shows in the result. Has no effect when not using cheap contrast.

Clamp Fresnel Dot Product (B)

Clamps the result of the Fresnel Dot Product between 0 and 1. This is true by default, but you can override it with a Static Bool set to false.

Using a Static Bool to invert the Fresnel effect.



SimpleGrassWind

SplineThicken

CameraOffset

ObjectPivotPoint

ObjectScale

PivotAxis

RotateAboutWorldAxis_cheap

StaticMeshMorphTargets

Wind

The WorldPositionOffset category contains special functions for applying manipulating vertices of a mesh by using the world position offset input. These functions can be chained together for additive effects.

SimpleGrassWind

The SimpleGrassWind function applies a basic wind operator to foliage, giving the ability to specify a weight map and wind strength. This is a non-directional wind that just gives a very general movement to foliage. This should be the last WPO node you add.

Inputs

Description

WindIntensity (Scalar)

Controls how much the wind affects the mesh.

WindWeight (Scalar)

This is a grayscale map that controls how much the mesh's vertices will respond to the wind.

WindSpeed (Scalar)

This controls the speed of the wind.

AdditionalWPO (Vector3)

Takes in any additional world position offset networks or functions.



This is what the effect looks like in motion.

SplineThicken

The SplineThicken function serves as a way to make very thin polygons look thicker at render time. This is perfect for cables, hair, grass, and other such objects.

Objects using this function should be extremely thin and have a normalized UV layout. Objects should be imported with "Remove Degenerate Triangles" disabled.

Inputs

Description

WidthBase (Scalar)

This sets the width of a single polygon object at its base.

WidthTip (Scalar)

Sets the width of a polygon object at its tip.

WorldPosition (Vector3)

World Position takes in any existing world position offset functions and adds this function to them.

UVs for Projection (Vector2)

This is the texture coordinate to use in the expansion of the spline.

UVs for Thickness (Vector2)

This is the texture coordinate to use for the Thickness mapper if projecting from U, it will the Y component of the specified UV index for the thickness blending.

UVs for texturing (Vector2)

This is the UV channel for texturing. This must be the same UV channel you want to have the 3D-parallax correction.

Expand U or V UV Channel (StaticBool)

Sets whether to expand the mesh in U or V. Defaults to true, which is U.

DriveNormalZ (Boolean)

This will use DeriveNormalZ to make a perfectly round normal map.

AngleCorrectedNormal (Boolean)

Uses DerivedNormalZ to make perfectly round normal map. Requires a center tesselation vertex otherwise the value of Z will be 0 for the entire face, causing harsh lighting.

AdditionalNormal (Vector3)

This will add a texture normal to the normalmap transform.

FlattenPixelNormal (Boolean)

UVs For NormalShading (Vector2)



Outputs



Normal

The outgoing normal of the adjusted geometry.

WorldPositionOffset

This is the output that you can add to other world position offset calculations.

UVs with Parallax



CameraOffset

The CameraOffset function is great to assist with depth sorting, as it allows you to move an object in camera space, either toward or away from the camera.

Inputs

Description

OffsetAmount (Scalar)

Enter a negative or positive number to offset your model in the direction of the camera. Note that positive values will bring the model closer to the camera and cause rendering errors if the mesh greatly exceeds the models bounding box.

Clamp Padding (Scalar)

The amount of padding to prevent the clamped version of the offset value from clipping into the camera.

WorldPosition (Vector3)

Enter the model's vertex world position. The Default Value = World Position.



Outputs



Clamped Camera Offset

The Camera offset is clamped to avoid early camera intersections. Adjust the padding to change the amount of space reserved to avoid camera intersection.

Camera Offset

Either add this value to other World Position offset code or enter it directly into the world position offset master material to offset your mesh.



When the Offset parameter in this graph is overidden in the Material Instance Editor, the sphere is moved toward or away from the camera.

ObjectPivotPoint

The ObjectPivotPoint function returns the object's pivot point in world space. This is not compatible with the pixel shader.

Outputs

Description

Object Pivot Location

Returns the object's pivot point in world space. This only works with the vertex shader and is incompatible with the pixel shader.



This graph uses the Object Pivot Point function and a bit of math to scale an object from its pivot point using a parameter in the Material Instance Editor. The results are shown below.

ObjectScale

The ObjectScale function returns the object's XYZ scale together and seperately. This is not compatible with the pixel shader.

Outputs

Description

Scale XYZ

Returns a float3 value that is equal to the objects XYZ scale. This is not compatible with the pixel shader.

Scale X

Returns a scalar value that is equal to the object's X-scale. This is not compatible with the pixel shader.

Scale Y

Returns a scalar value that is equal to the object's Y-scale. This is not compatible with the pixel shader.

Scale Z

Returns a scalar value that is equal to the object's Z-scale. This is not compatible with the pixel shader.

In the video below, the ScaleXYZ output is used as a multiplier for the Emissive input. When the size of the sphere is increased, the emissive value also increases and the sphere glows brighter.

PivotAxis

The PivotAxis function creates a common pivot location on arbitrary axes. This is helpful for creating flag motion. Instead of using a single pivot point near the top of the flag, use a shared Z point and unique X and Y location data to create a more realistic connection along the object's width.

This shader node only supports uniform scaling. Also, the rotate about axis axis and the pivot axis/pos should not coincide.

Inputs

Description

Pivot Axis/Pos (Vector3)

Enter a number to use as both your local axis line axis and position. If you would like to lock off your model, enter on its local z axis near its pivot enter (0,0,1). If you would like to lock of the top of the model, enter your model's height in as (0,0,model height).



Outputs



Pivot

This can be used as the pivot point in the rotate about axis node.

RotateAboutWorldAxis_cheap

The RotateAboutWorldAxis_cheap function cheaply rotates objects around world axes. Input the angle you would like to use and attach the output to world position offset.

Inputs

Description

Rotation Amount (Scalar)

A value of one is equal to one full rotation.

PivotPoint (Vector3)

World space location of pivot point to rotate around. The default value is the model's pivot point.

WorldPosition (Vector3)

World space location of individual vertices. The WorldPosition node is typically used.



Outputs



X-Axis

Cheaply rotates the object around the world X-axis.

Y-Axis

Cheaply rotates the object around the world Y-axis.

Z-Axis

Cheaply rotates the object around the world Z-axis.

The video below shows an example Material which rotates a cube about its own pivot point. Note how the axis of rotation changes when each of the three output pins are used.

StaticMeshMorphTargets

The StaticMeshMorphTargets function unpacks morph target data that was added into a via 3ds Max's Morph Packer MAXScript.

Outputs

Description

Morph Target 1 Normals

The surface normals that are associated with Morph Target 1.

Morph Target 1 WPO

World position offset for Morph Target 1.

Morph Target 2 WPO

World position offset for Morph Target 2.



Wind

The Wind function provides separate outputs for wind strength, speed multiplied by time and a normalized wind vector.

Inputs

Description

WindActor (Vector4)

This will take in a Wind actor (in development). At this time you may use a Vector4 to designate direction and strength of the wind.



Outputs



Normalized Wind Vector

The wind vector, normalized to 0-1 space.

WindStrength

Returns wind strength. The magnitude of the wind vector found by calculating distance from the wind vector to 0.

WindSpeed

Wind speed multiplied by time.

WindActor

Standard WindActor node.



Pivot Painter Tool 2.0

Pivot Painter Tool 2.0 MAXScript Reference

Pivot Painter 2 Functions

PivotPainter2FoliageShader

ms_PivotPainter2_CalculateMeshElementIndex

ms_PivotPainter2_Decode8BitAlphaAxisExtent

ms_PivotPainter2_DecodeAxisVector

ms_PivotPainter2_DecodePosition

ms_PivotPainter2_ReturnParentTextureInfo

ms_PivotPainter2_UnpackIntegerAsFloat

Pivot Painter 2 Material Functions enable you to tap into and decode useful model information stored by Pivot Painter 2 MAXScript using textures. Each texture output by the MAXScript can be referenced directly in a Material but without applying the proper steps after sampling the texture the values would be incorrect. These Material Functions found in this page make it easy to quickly decode the texture information.

A lot of the Material Functions included in this page will enable you to use the Pivot Painter 2 pivot and rotational information to do specific effects via your Material, however, one of the greater benefits of Pivot Painter 2 is its ease of use with the provided sample shader for foliage; PivotPainter2FoliageShader. This specific Material Function enables you to quickly setup your model and its Pivot Painter 2 generated textures with your foliage to quickly create wind and turbulence without having to create your own Material network.

Pivot Painter 2 Functions

The following is a list of all the functions related to Pivot Painter 2.0.

PivotPainter2FoliageShader



This Material Function contains texture and numeric parameters that should be altered to fit your particular asset.

For this particular function, you should create a Material Instance of your Material so that you can access the Material Function's already setup parameters for wind and turbulence.

Also, for this particular function, it is suggested that you create a Material Instance, where the Material Function's parameters will be accessible to make changes to your Pivot Painter 2 shader.



Click image for full size view

Item

Description



Inputs



Material Attributes

Make sure that you are using tangent space normals within your material and that the Use Tangent Space Normals option is unchecked. The normals will be transformed to world space internally.

Pivot Painter Texture Coordinate

Takes an input to reference which texture coordinate UV is being used.



Outputs



Final Material with World Space Normals

This output material attribute replaces the input material attribute's world position offset and normal output if Animate Level "X" Normals is enabled in the Material Instance.

Updating the model's normals is fairly expensive and can be done selectively.



Modified World Space Normal Component

This output returns the modified asset normals by itself.

World Position Offset Component

This output returns the new world position offset values.

ms_PivotPainter2_CalculateMeshElementIndex



This Material Function pulls the model's Element ID from the model's UVs.

Item

Description



Inputs



Data Texture Dimensions

Use the texture property node to gather the texture's dimensions.

Pivot Painter UV Coordinates

Pulls the model elements element ID from the model's UVs.



Outputs



Index

This output pulls the model element ID from the model's UVs.

ms_PivotPainter2_Decode8BitAlphaAxisExtent



This Material Function rescales 8-bit axis extent texture data information from Pivot Painter 2 MAXScript into world space data.

Item

Description



Inputs



8 Bit Alpha Extent Value

Insert a Pivot Painter 2 alpha texture component from a texture with an 8-bit alpha extent value. This can be generated by selecting the appropriate option from the alpha output drop-down option in the Pivot Painter 2 MAXScript under the Render Options.



Outputs



Rescaled Extent

The output value represents the chosen models' length along a given axis starting at the object's pivot points. The return value can represent values between 8 to 2048 in increments of 8.

ms_PivotPainter2_DecodeAxisVector



This Material Function transforms Pivot Painter 2's local space vector information into world space vectors.

Item

Description



Inputs



Axis Vector RGB

Input RGB vector information from a Pivot Painter 2 texture that output those values.



Outputs



Result

The input axis vector information has now been transformed to world space.

ms_PivotPainter2_DecodePosition



This Material Function transforms Pivot Painter 2's local space information into world position information.

Item

Description



Inputs



Position RGB

Insert the RGB values of a texture that contain Pivot Painter 2 Pivot Position (16-bit) data.



Outputs



Result

The output value is the world space location of each model's pivot point position as it was captured by Pivot Painter 2.

ms_PivotPainter2_ReturnParentTextureInfo



This Material Function reads a parent sub-object's texture data using Pivot Painter 2's Parent Index (Integer as Float) texture data.

Item

Description



Inputs



Parent Index As Float

This input assumes that the data is in float form. If you're reading from a parent index "int as float" texture, first decode the asset using the Material Function ms_PivotPainter2_UnpackIntegerAsFloat.

Texture Dimensions

The current dimensions of the texture.

Current Index

Providing this value is only necessary if you would like to determine if this asset is a child of another component.



Outputs



Parent UVs

This outputs the UV coordinates for the element's parent element pixel location.

Is Child?

This returns 1 if the object is a child of another object. It returns 0 otherwise. This requires that the current index to be entered in the Current Index input. The current index can be found by using ms_PivotPainter2_CalculateMeshElementIndex if you are referencing your textures using the model's UVs.

ms_PivotPainter2_UnpackIntegerAsFloat



This Material Function decodes Pivot Painter 2's Integer as Float texture data.

Item

Description



Inputs



Integer as Float

This decodes the integer data for conversion to float data.



Outputs



Result

This outputs Pivot Painter integer as float data.

Layering Materials with Material Functions

Material Layers

Unreal Engine provides two main ways to layer your Materials and create complex blends between unique surface types. These workflows give you a way to apply distinct Material properties to different regions of a single mesh. While you could achieve similar results in a regular Material using texture masks and other per-pixel logic, the two systems documented here produce easier to read Material graphs and a more artist-friendly editing workflow when changes to the Material are needed.

The two workflows for layering Materials are listed below.

Layered Materials as an extension of the Material Functions system.

Material Layers as implemented in the Material Instance Editor.

Layering Materials with Material Functions

This approach to layering Materials works as an extension of the Material Functions system. Each Material type you wish to use as a layer is fully defined within its own Material Function using the Material Attributes expressions. You then create a base Material which contains all the logic needed to blend between your various layers. Read the two pages below to learn how to use this workflow.



An introductory document on using Material Functions to create complex layered Materials.



An introductory document on the Layered Materials technique in Unreal Engine.

Material Layers

The Material Layers system makes it easier to edit layered Materials by providing a user-inteface tab in the Material Instance Editor. This Layer Parameters tab allows artists intuitively swap layers in and out of a Material Instance, change the order of the layer stack, and modify the way layers are blended without ever editing the node graph in the base Material.

While the Layered Material Functions workflow documented above is still a valid approach, the Material Layers system typically provides a faster and more iterative user experience for artists and designers who may not have the technical background needed to edit the node graph. Learn how to use Material Layers below.



Build complex layered and blended Materials that take advantage of Material instancing.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Key Benefits

Blend Types

Instancing Layered Materials

Caveats

This document is an overview of the original Layered Materials workflow, which uses Material Functions to create complex layer blends. For information about the newer Material Layers feature in the Material Instance Editor, read here.

Layered Materials provide a means to create a single Material that has a series of sub-Materials (or layers) that you can place across the surface of your objects using per-pixel operations such as masks. They are perfect for handling complex blending between unique surface types. In the image of the rockets below, the rocket on the far right is using a separate layer for the chrome, aluminum, and copper parts of the rocket. These are blended across the Material on a per-pixel basis.



As a feature, Layered Materials exist as an extension of Material Functions. Material Functions are self-contained node networks that perform a specific operation, such as a complex math equation. You can then reuse these functions at will in any number of Materials. Using the Make Material Attributes and Break Material Attributes nodes, you can define a full set of Material attributes entirely within a Material Function. You can then call these Material Functions in a base Material, and blend between them using Material Layer Blend Functions.



The image above shows a simple chrome Material defined entirely within a Material Function using the Make Material Attributes node. You can use this function as a layer in your base Material, and blend it with other Material Functions (layers).

It is important to realize that since Material Functions cannot be applied directly to a surface, you need to insert each Material Function layer into a standard base Material, which you can then apply to static meshes. You can use Material Functions to create as many layers as you wish, blending them together however you see fit.

At a high level, the workflow looks like this:

Create a new Material Function and edit the node graph to perfection. This function will act as a layer when you call it in your base Material.

Connect your node network to a new Make Material Attributes node, and connect it to the Function output.

Save the Material Function.

Repeat this process for any other Material Function layers you wish to create.

Create a new Material and open it in the Material Editor.

Drag your Material Functions from the Content Browser into the new Material to use as layers.

Blend multiple Material Functions together using the Material Layer Blend functions.

Your final object can now have multiple distinct Materials blended across its surface.

Key Benefits

Layered Materials allow you to create what would otherwise be a very complicated Material, and keep it much more manageable from a future editability standpoint.

For instance, it is possible to create the effect of layered Materials using a conventional Material graph (without layers or functions). However, this would require complex networks to blend between different textures and values for each Material input. Since most Materials make use of multiple inputs, the complexity of such a Material would increase significantly.



Consider the complexity of the network below, which uses no Material layers and blends a chrome and copper effect, as seen on the rocket above.

A traditional Material graph without layers.



Click image to enlarge.

With a layered Material, each distinct Material type is contained within its own node. This makes blending much simpler and far easier for an artist to edit and debug. By using the Make Material Attributes and Break Material Attributes nodes, you can connect each of the Material Function layers directly without having to worry about wiring up individual properties.

The network below achieves the same result as the one above, but the chrome and copper Materials are modularized into their own Material Functions.

This is the same Material using Material Functions as layers.



Click image to enlarge.

Another benefit of a layered Material approach is that since they utilize Material Functions, each layer is reusable. This allows you to set up a library of Material archetypes, or Materials that define a basic real-world surface type. For example, you can create layers that represent generic surfaces such as aluminum, steel, leather, plastic, rubber, and so on. You can then use a layered Material to blend between them. This is very useful when wanting to create a detailed object, such as a character, without having to create a massive set of Materials to apply separately to the surface.



Blend Types

Within the Material Functions list in the Material Editor palette is a list of various Material Layer Blend functions. These exist to help you blend Materials without needing to recreate complex node-graphs every time. Different types allow for specialized types of blends, such as with the ability to override specific Material features.



Material Layer Blend Functions

MatLayerBlend_AO

Blends an ambient occlusion (AO) map over the surface to remove reflection.

MatLayerBlend_BaseColorOverride

Allows the Base Color to be replaced.

MatLayerBlend_BreakBaseColor

Outputs the Base Color from an incoming Material Layer.

MatLayerBlend_BreakNormal

Outputs the Normal from an incoming Material Layer.

MatLayerBlend_Decal

Blends a decal sheet over the Material using the 2nd UV channel.

MatLayerBlend_Decal_UV3

Blends a decal sheet over the Material Layer using the 3rd UV channel.

MatLayerBlend_Emissive

Blends an Emissive texture over the Material Layer.

MatLayerBlend_GlobalNormal

Blends a Normal texture over the Material Layer.

MatLayerBlend_LightmassReplace

Replaces the Base Color in Lightmass, allowing for changes to indirect lighting results.

MatLayerBlend_ModulateRoughness

Multiplies the Material Layer's Roughness by an incoming texture. Useful for a "greasy" look.

MatLayerBlend_NormalBlend

Blends a Normal texture across the surface, but by way of a mask texture, allowing for control of where the normal will appear.

MatLayerBlend_NormalFlatten

Diminishes the effect of the Normal map.

MatLayerBlend_RoughnessOverride

Replaces the Roughness texture of a Material Layer.

MatLayerBlend_Simple

Provides a simple linear interpolation (Lerp) blending solution for 2 Material Layers. Does not blend Normal; instead, retains Normal of the Base Material.

MatLayerBlend_Stain

Blends the Top Material over the Base Material as a stain, meaning that only the Base Color and Roughness values from the Top Material are used.

MatLayerBlend_Standard

Blends all attributes of two Material Layers.

MatLayerBlend_Tint

Allows for tinting of a Material Layer by inputting a tint color and a mask to control the tint's location. Useful for making partial color changes.

MatLayerBlend_TintAllChannels

Similar to Tint, but also affects Specular. This is a very special case function; generally, you will not need it.

MatLayerBlend_TopNormal

Blends all attributes of both Materials but only uses the Normal of the Top Material.

Instancing Layered Materials

Because Layered Materials are essentially Material Functions, parameterizing them for instancing requires some extra forethought. To make better use of Scalar and Vector Parameters, you can create a Function Input expression as part of a Material Layer. You can then connect a parameter into this input from the top-level Material. See the Material Functions overview for more information.

The flow works something like this:



Material Parameter (Scalar Parameter, Vector Parameter, etc.)

Material Layer (Function)

Function Input expression

Some network to define the Material Layer

Function Output

Final Material

Some helpful tips:

When pasting your Material Expressions into a function to create your layer, replace all parameters with appropriately named Function Input nodes.

When you bring your new Material Function into a Material, connect new parameter nodes into the inputs.

You can now instance the final Material, and your parameters will drive the appropriate aspects of your layers.

Make sure to supply default values for your Function Inputs. This speeds up the workflow for those who do not need to make changes.

Caveats

Although Layered Materials are useful for handling multi-Material setups, you must take care when employing them. They can be heavy in terms of performance, particularly if the Materials used in the layer functions are complex themselves.

Keep in mind that all your layers are rendered simultaneously, and then blended. For instance, if you have four layers in a Material, for each pixel of your object the engine must test to see which of the four is blended and then reject any not in use. This added calculation makes the Material more performance intensive.

Your first impulse may be to use Layered Materials any time you wish to have multiple surface types on an object. For example, on an automobile you may want to have a distinct layer for paint, another for steel, for rubber, for glass, and so on. Instead, it is more efficient to separate many of those layers at the geometry level. This creates more Material Elements on your objects, which increases draw calls, but is generally much more efficient. In short, if you can apply multiple Materials instead of using a Layered Material, then do so. If you must have per-pixel control over where Materials are placed, then use layered Material functions or Material Layers.

Although condensing multiple individual Materials down to one will reduce draw calls, the resulting Layered Material is generally too heavy for this to be used on mobile platforms.

Simple Chrome

Chrome Material Network

Simple Snow

Snow Layer Network

Layered Material

Layered Material Network

Instancing a Layered Material

This tutorial demonstrates the process of creating a simple Layered Material comprised of two layers: chrome and snow. The final Layered Material uses a world-aligned blend to automatically place snow on the upward facing surfaces of the mesh, effectively switching between the two Materials. The blend function always checks for the top surface, meaning even as you rotate the object, the snow Material remains on top, as shown in the image below:



Generally when creating Layered Materials, it is common to create each layer as a Material and copy/paste your node network into a new Material Function. To save time, this tutorial builds each layer within Functions to begin with.

Simple Chrome

Chrome Textures





T_ExampleLayers_Metal_1_BC.png

T_ExampleLayers_Metal01_N.png

(Right-click and Save As)

(Right-click and Save As)

The base layer is a simple chrome Material with some subtle surface imperfections to add visual interest. To help demonstrate editability, the Material includes several inputs that allow you to fine-tune the overall look.

Right-click in the Content Browser, click Materials and select Material Function in the context menu.



Name the Material Function Layer_Chrome.



Double-click the Material Function to open it in the Material Editor.



Right-click in the Material Graph, and then search for and select Make Material Attributes in the context menu.



Connect the Make Material Attributs node to the Output Result node.



Chrome Material Network

The Material Graph for the chrome layer is shown below, with a breakdown beneath the image so you can replicate it easily. The two textures used are T_ExampleLayers_Metal_1_BC.png for the Base Color and Roughness, and T_ExampleLayers_Metal01_N.png for the normal map, both downloadable at the top of this page.



Click to enlarge image.

See the following notes explaining the four comment blocks in the Material Graph.

Base Color - For the Base Color, a Linear Interpolate (LERP) is used to blend between the base chrome color and a very dark gray value (0.3). For the base color, create a Function Input node and name it Tint. Make sure the input type is set to Vector3 in the Details Panel, which allows you to input a color into the function to change the tint of the chrome. The red channel of the T_ExampleLayers_Metal_1_BC texture is used to drive the interpolation between the two values.



Metallic - Since this is a metal Material, a value of 1 is passed into the Metallic input.

Roughness - Roughness should generally be very low for a chrome Material, but some subtle variation can add depth to the overall look of the Material. In this case, the red channel of the chrome texture is used to LERP between values of 0.2 and 0.4. This means darker areas on the texture map will have slightly higher roughness than the light areas.

Customizable Normal - This network simply takes in a tangent space normal map and separates the green and red channels, which control the bulk of the map's detail. Each channel is multiplied by a value supplied from another Function Input. This input is set to a Scalar type and named Normal Multiplier, with a default value of 1.0. Using an AppendVector node, the results are appended together and then appended to the blue channel of the normal map. The result is that the user has the power to adjust the height of the normal by changing the Normal Multiplier value.

Make sure you compile and save your Material Function when finished.

Simple Snow

Snow Textures





T_Cave_Ice_Tiling_D.png

T_Cave_Ice_Noise_N.png

(Right-click and Save As)

(Right-click and Save As)

Download the two textures above and import them into Unreal Engine. Follow the steps below to create a second Material Function for the snow layer.

Right-click in the Content Browser, click Materials and select Material Function in the context menu.



Name the Material Function Layer_Snow.



Double-click the Material Function to open it in the Material Editor.



Right-click in the Material Graph, and search for Make Material Attributes in the context menu, and add it to the graph.



Connect the Make Material Attributs node to the Output Result node.



Snow Layer Network

Below is a simple breakdown of the snow Material Graph. This layer uses the T_Cave_Ice_Tiling_D.png and T_Cave_Ice_Noise_N.png textures, both downloadable at the top of this page.



Base Color - This is the only relatively sophisticated part of the network, and only because it uses the FuzzyShading Material Function. This function simply keeps the texture from getting too dark when the Material is receiving light. This is similar to the way light passes through fibrous surfaces. This makes it perfect for velvet, moss, or in this case, snow. Some contrast is removed from the Base Color texture (T_Cave_Ice_Tiling_D.png) by raising it to the power of 0.3.

Next, plug the result into a FuzzyShading Material Function, which you can insert from the Functions tab in the Material Editor palette. Set Core Darkness to 0, Power to 1, and**EdgeBrightness** to 0.5. Finally, multiply the whole thing by a very pale blue color (R=0.8, G=0.9, B=0.95) to give it a cold, icy color cast.

Metallic - This is a non-metallic surface, so Metallic is set to 0.

Roughness - Snow should shine a little bit when the light hits it just right, so the red channel of the T_Cave_Ice_Tiling_D.png texture is used to drive a Lerp between 0.6 and 0.3.

Normal - The normal map on its own is a little bit too strong. One way to reduce the effect of the tangent space normal map is to double the strength of the blue channel. This is done by multiplying the normal map by a Constant3 Vector with a value of (1,1,2).

Save your result when finished!

Layered Material

You can now create a Material and blend the two layer functions together. This example is configured so that the snow always appears on the top of the surface. The Material also contains some parameters to make it customizable in Material instances.

In the Content Browser, click the Add New button and choose Material from the context menu.



Name your new Material Mat_SnowyChrome.



Double-click the Material to open it in the Material Editor.



Drag your Layer_Chrome and Layer_Snow Material Functions from the Content Browser into the Material Graph.



Click in the background of the Material Graph to display the base Material Properties in the Details panel. Enable Use Material Attributes by checking the box.



From the Palette, add a MatLayerBlend_Simple Material Function, as well as a WorldAlignedBlend Function. The MatLayerBlend_Simple will execute the transition from chrome to snow, and the World_Aligned_Blend will power the Layer Blend based on the direction the surface is pointed.

Layered Material Network

Below is a breakdown of the Mat_SnowyChrome Material network, along with descriptions for each of the commented areas.



Chrome Setup - Two parameters are connected to the Layer_Chrome Material Function. The first is a Scalar Parameter named Chrome Normal, which is used to drive the NormalMultiplier input. The second is a Vector Parameter named ChromeTint that is driving the Tint input. These parameters allow you to alter the strength of the normal map, and change the tint of the chrome when the Material is instanced later.

Snow Setup - No additional nodes are needed. The Layer_Snow Material Function is plugged directly into the blend node.

World Aligned Blend Setup - The WorldAlignedBlend node controls the position and sharpness of the Material blend. Set the Blend Sharpness value to 10. Then create a Scalar Parameter named BlendBias and connect it to the Blend Bias input. This allows you to adjust the vertical position on your mesh where the blend occurs.

MatLayerBlend - This node contains the logic used to drive the blend. In this case, the base Material is Layer_Chrome and the top Material is Layer_Snow. The WorldAlignedBlend is plugged into the Alpha input to drive the the transition.

Save your Material when done!

Instancing a Layered Material

Since this Material contains two parameters, you can now create a Material Instance and customize aspects of the Material Layers.

If you included the Starter Content in your project, you will have a set of chairs and a table to apply the new Material to. If not, feel free to place some of your own assets in the scene.



Right-click on the Mat_SnowyChrome Material and choose Create Material Instance in the context menu. The default name should be fine.



Drag the Material Instance asset from the Content Browser onto one of the objects in the scene.



Double-click the Material Instance to open it in the Material Instance Editor. You can override the tint of the chrome, the depth of the chrome's normal map, and how much snow has fallen on top of it.

Key Benefits

Using Material Layers

Material Layer Asset Types

Material Layer Blend Asset

Base Material Graph

Instancing Material Layers and Blends

Additional Resources

The Material Layers system in Unreal Engine is a powerful tool that allows you to layer and blend textures and properties together to create unique Materials for the objects in your levels. Material Layers are similar to the Layered Materials workflow using Material Functions, however this alternative approach simplifies the process and provides far more flexibility to artists.

Unlike traditional Layered Materials, which must be edited directly in the Material node graph, the Material Layers system provides a user interface tab in the Material Instance Editor. This interface allows artists to quickly and easily swap out layers in Material Instances. Because Material Layers are exposed in the Instance Editor, this workflow drastically reduces the technical knowledge and time required to customize a layered Material, leading to a more iterative user experience.

Key Benefits

One of the benefits to using Material Layers is the ability to create what would otherwise be an overly complicated Material, while keeping it much more manageable from a future editability standpoint. While it's possible to create the same type of Material using the Layered Materials workflow or in a conventional Material (without layers and Material Functions), the Material Layers workflow provides better control, flexibility, and reduced complexity.

For instance, the images below show the difference between a traditional Layered Material using the graph-based approach, and one using GUI-based Material Layers (pictured right). It is readily apparent that using Material Layers reduces the amount of work required in the base Material, leaving the work and functionality to be done in the assets themselves.





Base Material using Material Function workflow

Base Material using Material Layers workflow

Due to limitations in the way Material Functions work when creating Material Instances, parameters created in a Material Function cannot be referenced in an instanced Material without first being duplicated in the base Material. In contrast, you can instance any parameters set up in a Material Layer Asset, and only the base Material Layer needs to be referenced in the base Material for the input that it will affect.

When opening a Material Layer or Material Layer Blend Asset, the node graph is similar to the one in the Material Editor. This is where you can set up and employ all of the logic for this Material, including the parameterization of attributes. This allows you to control things such as texture inputs, vector and constant values, and more. Setting up your logic primarily in the Material Layer Asset means that it's less complicated to manage when making big or small changes in your Materials. It also means that you can use similar Material Layers across multiple Materials without duplicating your work. This is similar to how Material Functions work, but with much more flexibility in application and usage.



The Material Graph for a single Material Layer asset.

All of the parameters set up here are referenced in the Layers added to the stack in a Material Instance of a base Material that is using Material Layers. This means there is no need to duplicate any of these parameters in your base Material when creating its Material Instance. When you open the Material Instance, the Layer Parameters tab displays all the Material Layers and parameters that you have added to this instance.



Click image for full size.

The Material Layer Blend Asset is used to control masking for the Layers referenced in this Material Instance. Each Layer can have its own Material Layer Blend; you are not limited to a single blend asset for all layers in the stack. Without a blend asset assigned to a layer, the topmost layer without a blend asset will always override any layers below it. Like the Material Layer Asset, Material Layer Blends have their own node graph where you can set up your own blending and masking logic for defaults and parameterization, which you can instance and reuse across multiple Materials.



Click image for full size.

This workflow lets you simplify a portion of your material logic to a single asset while affording you the flexibility to reuse this for any other Materials you may create.

Using Material Layers

The following steps are the high-level procedure to create and use Material Layers for the Materials in your project.

Create your Material Layer Asset(s).

Create your Material Layer Blend Asset(s).

Create a conventional Material Asset, which will act as your base Material.

Add a Material Attribute Layers expression to evaluate the active Material Layer stack and output the merged attributes.

Create a Material Instance of your base Material.

Use the Layer Parameters tab to add, edit, and manage layers for your Material.

Material Layer Asset Types

The Material Layers system is composed of two asset types:

A Material Layer Asset is used to create a layer that you can blend with other layers in the Material.

A Material Layer Blend Asset is used to create a mask for blending two layers together.

You can add both of these asset types to your project from the Content Browser. Click the Add button, or right-click in the Content Browser and expand the Materials sub-category under Create Advanced Assets. Choose Material Layer or Material Layer Blend from the context menu.



The Material Layer Asset, like a Material Function, has its own Material Graph where you can set up your node graph logic and preview it for the Material. For each type of Material that you want to create, you can use the Make or Set Material Attributes expresion to handle the logic and output that result. For instance, if you wanted to create a chrome or emissive Material, you'd set up your textures and parameters in this graph like you would in any normal base Material graph.



The Material Graph for a simple chrome-like Material Layer.

Material Layer Blend Asset

The Material Layer Blend Asset, like a Material Function, has its own graph where you can set up your node graph logic and preview it for the Material. Material Layer Blend assets automatically include an Input Bottom Layer and Input Top Layer setup with a BlendMaterialAttributes expression. You can apply additional logic for those inputs or simply use the Alpha input to drive your own masks and blends for the layers in the Material Instance layer stack.



A simple Material Graph using a mask to drive the alpha for the BlendMaterialAttributes expression in the Material Layer Blend graph.

Click image for full size.

Base Material Graph

When using the Material Layers system most of the node logic is handled in the Material Layer and Material Layer Blend assets. The graph of the base Material will usually contain relatively little Material logic, which reduces the amount of management required in your base Materials.

When using Material Layers, you must make sure you enable Use Material Attributes by selecting the Main Material Node and checking the box it in the Details panel.



A Material Attribute Layer expression is used to reference the many Material attributes that can be associated with a particular Material layer. These are then used for your base Material's output. For example, you can have a chrome Material that gets and sets Material attributes when using a Material Attribute Layer expression.



The Material Attributes Layer expression is used to evaluate the active Material Layer Stack. When you select the Material Attribute Layers expression, you can use the Details panel to set the default layers to be used with any Material Instance that is created. In this example there is only a Background Material, which references the Chrome Material Layer asset. You can add additonal layers by clicking the Add Element button (+).



When you create your Material Instance or apply this Material directly to an object in your project, the default Material Layers are used.

For more complex Materials that you set up, the Get Material Attributes and Set Material Attributes expressions can add and accept Material Attributes you want to set up in your base Material rather than setting it up specifically in the Material Layer. In this example, an additional Normal map is blended with the Normal Map from the Material Layer. The Set Material Attributes node accepts the new blended normals, and outputs the updated Material Attributes. Read more about Material Attribute expressions here.



Click image to enlarge.

Instancing Material Layers and Blends

Just like you can instance a Material to create unique Material instances from specified parameters, you can also instance Material Layers and Material Layer Blends. This provides access to any parameterized expressions in the node graph.

You can create an instance of a Material Layer or Material Layer Blend by right-clicking it in the Content Browser and selecting Create Layer Instance or Create Blend Instance, respectively.



Click image to enlarge.

When you parameterize nodes in your base Material Layer graph, those parameters become accessible to any child Material Instances you create. For Material Layers and Blends, you'll find you parameters listed in the Layer Parameters tab in the Material Instance Editor. All parameters for any given Material Layer are listed here.



Each layer's parameters are exclusive to that layer. If you have multiple layers in the stack using the same Material Layer, setting an overridden parameter value in one layer in the stack will not override that Material Layer's parameters elsewhere in the same layer stack.

There are multiple ways to pass parameters from your Material Layers and Blends into Materials and Material Instances. Most of these suggestions apply to both Material Layers and Blends.

Parameters added within Material Layer and a Material Layer Blend graphs are unique to that layer or blend. For example, the Material Layer below is using a Vector Parameter, a Texture parameter for a roughness map, and two scalar parameters for metallic and roughness. These are set up just like they would be in a standard Material or Material Function.



When a standard Material that uses Material Layers is instanced, and this layer is added to the Layer Parameters tab of that Material Instance, you will find that all the parameters are available for editing.



In your standard Material graph, this takes another Material Attribute as input using the Set Material Attributes expression, which will be piped to every layer added to the Material Attribute Layers expression stack.

In this example, a base normal texture is passed into the Material Attribute Layers stack.



Then, within the Material Layer Asset, the input and blend in can be set using the Set Material Attributes expression. Additionally, each layer can use or ignore the base stack material attributes input



In the Layer Parameters tab of the Material Instance Editor, you can toggle the visibility of Material Layers, assign new Material Layer Blend Assets, or rearrange the layers in the stack for top-down dependency.



Click image for full size.

From the Layer Parameters tab, you can override and edit any parameters exposed for that Material Layer or Material Layer Blend. These parameters are exclusive to the layer. So, even if you were to add the same Material Layer to this layer stack multiple times, the parameters would be uniquely set for that layer in the panel.



Click image for full size.

Additionally, you can toggle visibility of each layer in the stack without removing or losing any work you've created. Click the Eye icon to toggle visibility of any layer in the stack.



Toggling visibility of a layer disables it and displays the next layer in the stack based on layer blend and parameter settings already used in the stack by other layers. The example below disables a Material Layer with its own unique properties and blend mask for the sides of the chest plate. When disabled, the next layer displays the chrome material used by other parts of the chest plate.





You can drag and drop layers to arrange the order, with the top-most layer taking priority over any below it. Lastly, each layer in the stack can be dragged and dropped with the top-most layer taking priority over any below it. Note that you cannot move the Background layer. The Background layer is set in the base parent Material as the default material when no other Material Layers are present.

Additional Resources

Parameters

Material Expression Properties

Material Expression Types

Expression Index

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

This page is a reference index for all Material expression nodes available in the Material Editor. Material Expressions are the building blocks for creating fully functional Materials in Unreal Engine.

Each Material expression is a self-contained black box that either outputs a set of one or more specific values, or performs a single operation on one or more inputs and then outputs the results of that operation.

Parameters

Certain Material expressions are parameters, meaning you can modify their values (dynamically during runtime in some cases) in a Material Instance of the base material containing the parameter.

You should assign all parameters a unique name using the Parameter Name details property. This name is used to identify each specific parameter when you edit an instance in the Material Instance Editor.

If two parameters of the same type have the same name within a Material, they are treated as the same parameter. Changing the value of one parameter in the Material Instance would change the value of both parameter expressions in the Material. You can set a default value for your parameters in the Details Panel. This default value is used in the Material Instance unless it is overridden and modified there.

Material Expression Properties

All Material Expression nodes contain the same properties that provide different kinds of information. Below, we use a Texture Sample node to highlight these on properties.



Number

Property Name

Description

1

Description

All materials expressions have a common Desc (Description) property, which is accessible from the Details Panel. Any text entered into this in this property displays in the Material Editor just above the expression in the workspace. It can be used for any purpose, but usually serves as a good way to leave short notes about the purpose or function of the expression.

2

Title bar

Displays the name and/or pertinent information about the the Material Expression.

3

Inputs

Links to any values used by the Material Expression.

4

Outputs

Links that output the results of the Material Expression operation.

5

Preview

Displays a preview of the values that are output by the Material Expression. This updates automatically when realtime update is enabled and can be manually updated using the Spacebar.

Material Expression Types

These reference pages are organized according to the categories in the Material Editor palette.



Material Expressions that affect fog and other atmospheric level effects.



Material expressions that perform actions on color inputs.



Material Expressions whose outputs generally do not change once set in the Editor or when play begins.



Expressions that perform actions on texture coordinates or output values that can be used as, or to modify, texture coordinates.



Material expressions that allow the use of custom, plain shader code.



Material expressions that deal with depth of the pixel being rendered.



Material Expressions that sample and output font assets.



Material expressions that are used to create or execute Materials Functions.



Material expressions for creating Materials apply to Landscape terrains.



These expression nodes serve as a way to separate or combine various Material attributes, which is particularly useful when creating Layered Materials.



Expressions that perform mathematical operations on one or more inputs.



Expressions that expose properties to Material Instances to be overridden in child instances or modified at runtime.



Expressions used for creating Materials for emitters in Particle Systems.



Expressions that sample and output textures.



Material expressions that perform various utility operations on one or more inputs.



Material expressions that output a vector value, such as a position or normal.



Material Expressions that perform operations on vector input values.

Expression Index

This is a reference list of many, but not all, Material Expressions. All links shown here can also be accessed through the Expression Types pages listed above. Additionally, you can use Ctrl+F to find the expression node you need and follow the link to its description.

Atmosphere

AtmosphericFogColor

Color

Desaturation

Constants

Constant

Constant2Vector

Constant3Vector

Constant4Vector

DistanceCullFade

PerInstanceFadeAmount

PerInstanceRandom

Time

TwoSidedSign

VertexColor

Coordinates

ActorPositionWS

CameraPositionWS

LightmapUVs

ObjectOrientation

ObjectPositionWS

ObjectRadius

Panner

ParticlePositionWS

PixelNormalWS

Rotator

SceneTexelSize

ScreenPosition

TextureCoordinate

VertexNormalWS

ViewSize

WorldPosition

Custom

Custom

Depth

DepthFade

PixelDepth

SceneDepth

Font

FontSample

FontSampleParameter

Functions

FunctionInput

FunctionOutput

MaterialFunctionCall

StaticBool

StaticSwitch

TextureObject

MaterialAttributes

BreakMaterialAttributes

MakeMaterialAttributes

Math

Abs

Add

AppendVector

Ceil

Clamp

ComponentMask

Cosine

CrossProduct

Divide

DotProduct

Floor

Fmod

Frac

If

LinearInterpolate

Multiply

Normalize

OneMinus

Power

Sine

SquareRoot

Subtract

Parameters

CollectionParameters

DynamicParameter

FontSampleParameter

ScalarParameter

StaticBoolParameter

StaticSwitchParameter

StaticComponentMaskParameter

VectorParameter

TextureObjectParameter

TextureSampleParameter2D

TextureSampleParameterSubUV

TextureSampleParameterCube

TextureSampleParameterMovie

Particles

DynamicParameter

ParticleColor

ParticleDirection

ParticleMacroUV

ParticleMotionBlurFade

ParticlePositionWS

ParticleRadius

ParticleRelativeTime

ParticleSize

ParticleSpeed

SphericalParticleOpacity

ParticleSubUV

TextureSampleParameterSubUV

Terrain

LandscapeLayerBlend

LandscapeLayerCoords

LandscapeLayerSwitch

Texture

FontSample

FontSampleParameter

SceneColor

TextureObject

TextureSample

Utility

BlackBody

BumpOffset

ConstantBiasScale

DDX

DDY

DepthFade

DepthOfFieldFunction

Desaturation

Distance

Fresnel

LightmassReplace

LinearInterpolate

Noise

QualitySwitch

RotateAboutAxis

SphereMask *Thin Translucent

AntialiasedTextureMask

VectorOps

AppendVector

ComponentMask

CrossProduct

DeriveNormalZ

DotProduct

Normalize

Transform

TransformPosition

Vectors

ActorPositionWS

CameraPositionWS

CameraVectorWS

Constant2Vector

Constant3Vector

Constant4Vector

LightVector

ObjectBounds

ObjectOrientation

ObjectPositionWS

ParticlePositionWS

PixelNormalWS

ReflectionVectorWS

VertexNormalWS

Atmospheric Fog Color

Atmospheric Fog Color

The Atmospheric Fog Color Material Expression allows you to query the current color of the level's Atmospheric Fog, at any position in World Space. If no World Position is fed into it, then the world position of the pixel in question is used. This is useful when you need Materials to appear to fade into a distant fog color.

In the example below, The Base Color is being set using an Atmospheric Fog node, with the World Position receiving a simple network that queries the location that is always 50,000 units behind the object, relative to the position of the camera.



The Atmospheric Fog Color Material Expression is deprecated in Unreal Engine 5, and should not be used. Instead, you should use the Sky Atmosphere Component, which is documented on this page. You may also want to consider using Volumetric Fog.

Desaturation

Desaturation

The Desaturation expression desaturates its input, or converts the colors of its input into shades of gray, based a certain percentage.

Item

Description



Properties



Luminance Factors

Specifies the amount that each channel contributes to the desaturated color. This is what controls that green is brighter than red which is brighter than blue when desaturated.



Inputs



Fraction

Specifies the amount of desaturation to apply to the input. Percent can range from 0.0(full original color, no desaturation) to 1.0 (fully desaturated).



Programmers: Define desaturated color D, input color I and luminance factor L. The output will be O = (1 - Percent)*( D.dot( I )) + Percent * I

Constant

Constant2Vector

Constant3Vector

Constant4Vector

Distance Cull Fade

PerInstanceFadeAmount

PerInstanceRandom

Time

TwoSidedSign

VertexColor

View Property

Precomputed AO Mask

Material Expressions whose outputs generally do not change once set in the Editor or when play begins.

Constant

The Constant Material Expression outputs a single float value. It is one of the most commonly used expressions and is compatible with any input, regardless of the number of channels the input expects.

For instance, if you connect a Constant to an input expecting a 3-channel vector, the constant value is used for all 3 elements. When supplying a single number, it can be useful to collapse the node using the small triangle icon in the description area.

Property

Description

R

Specifies the float value the expression outputs.

Examples: 0.7, -0.24, 1.1



You can quickly create a Constant expression by holding the 1 key and left-clicking in the background of the Material Graph in the Material Editor.

Constant2Vector

The Constant2Vector expression outputs a two-channel vector value, in other words, two constant numbers.

Property

Description

R

Specifies the float value of the red (first) channel of the vector the expression outputs.

G

Specifies the float value of the green (second) channel of the vector the expression outputs.

Examples: (0.4, 0.6), (1.05, -0.3)

Example Usage: The Constant2Vector is useful for modifying texture scale or offset, as UV coordinates require two-channel values.



To quickly create a Constant2Vector node, hold the 2 key and left-click anywhere in the background of the Material Graph.

Constant3Vector

The Constant3Vector expression outputs a three-channel vector value, in other words, three constants numbers. A Constant3Vector is often used to define a solid RGB color, where each channel is assigned to a color (red, green, blue). You can double-click the Constant3Vector node in the Material Graph to summon a color picker dialog.

Property

Description

R

Specifies the float value of the red (first) channel of the vector the expression outputs.

G

Specifies the float value of the green (second) channel of the vector the expression outputs.

B

Specifies the float value of the blue (third) channel of the vector the expression outputs.

Examples: (0.4, 0.6, 0.0), (1.05, -0.3, 0.3)

In this example an Constant3Vector is multiplied by a Texture Sample to change the tint of the texture.



To quickly create a Constant3Vector node, hold 3 key and left-click anywhere in the Material Graph.

Constant4Vector

The Constant4Vector expression outputs a four-channel vector value, in other words, four constant numbers. You can use the Constant4Vector expression to define RGBA color, where each chanel is assigned to a color (red, green, blue, alpha).

Property

Description

R

Specifies the float value of the red (first) channel of the vector the expression outputs.

G

Specifies the float value of the green (second) channel of the vector the expression outputs.

B

Specifies the float value of the blue (third) channel of the vector the expression outputs.

A

Specifies the float value of the alpha (fourth) channel of the vector the expression outputs.

Examples: (0.4, 0.6, 0.0, 1.0), (1.05, -0.3, 0.3, 0.5)

In the example below, a Constant4Vector expression is used to define both the Base Color and Opacity of the Material. The top pin outputs the RGB color, while the bottom pin outputs the value in the alpha channel. The alpha value of 0.5 results in a semi-transparent Material.



To quickly create a Constant4Vector, hold the 4 key and left-click anywhere in the background of the Material Graph.

Distance Cull Fade

The DistanceCullFade expression outputs a scalar value that fades from black to white and can be used to smoothly fade an object in once it passes within the cull distance. This node is primarily used to prevent Static Meshes from abruptly "popping" in and out of visibility when they fall outside the cull distance.

In this example, a sphere is placed within a CullDistanceVolume with a cull distance of 3000 units. The Material shown on the right is applied to the sphere.



When playing the level in the Editor, the sphere smoothly fades in and out as the camera moves in and out of the cull distance.

ParticleColor

The ParticleColor expression ties into the current color of a given particle based on any per-particle color data defined within Cascade. This must be plugged into the appropriate channel (Emissive Color).

Item

Description



Outputs



RGB

Outputs the combined RGB vector data.

R

Outputs the red channel data.

G

Outputs the green channel data.

B

Outputs the blue channel data.

A

Outputs the alpha channel data.



In this example, you can see where the ParticleColor expression is providing color to the particles as defined within the particle system.

ParticleDirection

The ParticleDirection expression outputs Vector3 (RGB) data on a per-particle basis, representing the direction a given particle is currently traveling.



You can see in the comparison below how the color of the particles is changing based on the current direction each particle is traveling.

Note how the color changes as the particles change directions.



ParticleMotionBlurFade

The ParticleMotionBlurFade expression outputs a value representing the amount of fade on a particle as a result of motion blur. A value of 1 represents no blur, black represents complete blur.



ParticleRadius

The ParticleRadius expression outputs the radius in Unreal units of each particle individually. This allows, for example, for changes to be made to a material once the radius has reached a certain point.



In this image, the particles are shifting from green to red as their radius exceeds 7 units.

ParticleRelativeTime

The ParticleRelativeTime expression outputs a number between 0 and 1 representing a particle's age, with 0 being the moment of birth and 1 being the moment of death.



In this example, you can see the particle relative time fed into the emissive color, resulting in particles that are fading from black at the moment of birth to white as they approach death.

ParticleSize

The Particle Size expression outputs the X and Y size of a particle sprite. This can then be used to drive some aspect of a Material.





Click image for full view.

In the example above, Particle Size is being multiplied into Particle Color. Notice that we are masking the output so that we only use the Green channel, which corresponds to the Y-Axis, or the length of the particles. This means that as the particles stretch out, they become brighter in color. As they shrink, they will become dimmer.

ParticleSpeed

ParticleSpeed outputs the current speed each particle is traveling, measured in Unreal units per second.



In this example, particle speed is feeding the color of the particles, which is then divided by 10 provide more meaningful results. The particles become black as they slow down.

PerInstanceFadeAmount

The PerInstanceFadeAmount expression outputs a float value from 0 to 1 based on the cull distance applied to an instanced Static Mesh, such as foliage. It is constant, but can be a different number for each individual instance of a mesh. The node is often used to fade foliage in and out gradually, rather than having it abruptly pop in or out of the scene when the cull distance on the InstancedFoliageActor is reached.

This rock Material uses the Translucent Blend Mode, with a PerInstanceFadeAmount expression plugged into the Opacity input. The Cull Distances on the InstancedFoliageActor are set to 1000 and 2500.



Note how the rock instances fade out with distance when the camera flies over the scene. This improves performance in levels with heavy amounts of foliage.

This only works when applied to an InstancedStaticMesh Actor or other Actor which utilizes InstancedStaticMeshComponents.

PerInstanceRandom

The PerInstanceRandom expression outputs a different random float value per Static Mesh instance to which the Material is applied. InstancedStaticMeshComponent sets a random float for instance, which is exposed so that it can be used for whatever is desired (random light levels behind a window, for example). It is constant, but different, for each instance of the mesh.

The output value is a whole number between 0 and RAND_MAX for the target platform. This Material uses the PerInstanceRandom expression to provide a random emissive value per instance.



When the Material is applied to a sphere and instanced with the foliage system, each instance of the sphere has a different emissive value.

This only works when applied to an InstancedStaticMesh Actor or other Actor which utilizes InstancedStaticMeshComponents.

Time

The Time node is used to add the passage of time to a Material. It is used with Material Expressions that change over time, such as a Panner, Cosine, or other time-dependent operations.

Property

Description

Ignore Pause

If true, time will continue to march on even if the game is paused.

Period

If true, this will be the amount at which to wrap around time. On Mobile Materials, this will perform the Period computation on the CPU at full-precision, whereas on the GPU it will run at half precision (potentially having issues on periods longer than a minute).



The Material network shown in the image above creates a Material that changes over time, constantly exhibiting a sinusoidal transition between white and black. When period is enabled, setting period to 0 effectively stops the transition. A value of 1 is the same as if the period property is false. Setting the number closer to 0 makes the Material change at a more rapid pace. The results of the graph are shown in the video below.

TwoSidedSign

The TwoSidedSign expression is useful for flipping the normal on the backfaces of two sided custom lighting Materials to match the functionality of Phong Shading: +1 for frontfaces, -1 for backfaces of a Two Sided Material.

In this graph, the normal map is multiplied by a TwoSidedSign expression.



The comparison image below shows both sides of the Material with and without the TwoSidedSign expression.



Top row - Without the TwoSidedSign node, the normals are inverted on the backface and the bricks render incorrectly. The highlights are on the bottom-right corner of each brick instead of the top-left.

Bottom row - When the Normal map is multiplied by a TwoSidedSign expression (as shown in the graph above), the normals on the backface are correct and the bricks render exactly as they do on the front face.

VertexColor

The VertexColor Material expression enables a Material to utilize Vertex Color data from the Static Mesh on which the Material is applied.

Outputs

Description

RGB

Outputs the combined three-channel RGB vector value of the vertex colors.

R

Outputs the red channel of the mesh's vertex colors.

G

Outputs the green channel of the mesh's vertex colors.

B

Outputs the blue channel of the mesh's vertex colors.

A

Outputs the alpha channel of the mesh's vertex colors.

The VertexColor node is often used as an alpha mask to blend between two or more textures in Mesh Paint Mode.



This network uses the red channel of the Vertex Colors to Lerp between the two Texture Samples. When you paint on the red channel in Mesh Paint Mode the gravel texture is revealed.

View Property

The ViewProperty expression outputs a view dependant constant property such as the field of view or render target size. You can configure which View Property is accessed by selecting the node and using the drop-down menu in the Details Panel.



The data type of the output depends on the property selected in the Details Panel. For example, when View Size is selected, the node outputs a two channel vector representing the width and heigh of the viewport in pixels. This is demonstrated below by passing the output through a DebugFloat2Values Material Function. The width and height of the viewport are shown in the preview viewport.



Precomputed AO Mask

The PrecomputedAOMask node provides access to Lightmass-calculated ambient occlusion (AO) in your Material. This is useful for procedural texturing or for adding in aging effects and dirt in areas where it would slowly accumulate over time.

The Precomputed AO Mask only works with baked lighting. Before you can see the results of the Precomputed AO Mask, you need to build the lighting of the level with Lightmass.



The above screenshot uses an AO mask to blend a dirt layer automatically into corners of the environment. To use AO masks, you'll need to enable both Use Ambient Occlusion and Generate Ambient Occlusion Material Mask under World Settings -> Lightmass settings, and then build lighting. The other AO controls like Max Occlusion Distance can be useful to tweak the look of the AO. Also make sure to set both Direct and Indirect Occlusion Fraction to 0, so that this AO will not be applied to the actual level lighting.



You can access the AO in any Material by using the PrecomputedAOMask Material Expression node. The PrecomputedAOMask works as a 0 to 1 mask with 1 denoting areas that are affected by AO and 0 for areas that are not.

The image below shows how to set up a Material to use the Precomputed AO Mask.



Click image to enlarge.

LightmapUVs

ObjectRadius

Panner

Rotator

SceneTexelSize

ScreenPosition

TextureCoordinate

VertexTangentWS

ViewSize

WorldPosition

ActorPositionWS

ActorPositionWS outputs Vector3 (RGB) data representing the location of the object with this material on it in world-space.



In this example, ActorPositionWS is passed directly into the Base Color of the Material. As a result, each of the objects with the Material applied to them show a different color as they are moved to different locations in 3D space. Note that the result of the ActorPositionWS node is being divided by 1600 to create a nice blend-in color, rather than an abrupt pop.

CameraPositionWS

The CameraWorldPosition expression outputs a three-channel vector value representing the camera's position in world space.

In the example below, Camera Position is passed into the base color of the Material. Note how the preview sphere changes color as the camera position changes.

LightmapUVs

The LightmapUVs expression outputs the lightmap UV texture coordinates in the form of a two-channel vector value. If lightmap UVs are unavailable, it will output a two-channel vector value of (0,0).

ObjectOrientation

The ObjectOrientation expression outputs the world-space up vector of the object on which the Material is applied. In other words, the object's local positive z-axis is pointing in this direction.



ObjectPositionWS

The ObjectPositionWS expression outputs the world-space center position of the object's bounds. Each sphere in the image below displays a different color as they are moved to a different position in space. The RGB color channels correspond to the X, Y and Z axes in the level. This node is useful when creating spherical lighting for foliage.



ObjectRadius

The Object Radius outputs a value equal to the radius of a given object in Unreal units. Scaling is taken into account and the results can be unique for each individual object.



In this example, both meshes are receiving this material in which the ObjectRadius is fed into Diffuse. The ObjectRadius output is being divided by 512 to provide a more meaningful visual result.

Panner

The Panner expression outputs UV texture coordinates that can be used to create panning, or moving, textures.

Item

Description



Properties



SpeedX

Specifies the speed to pan the coordinates in the U direction.

SpeedY

Specifies the speed to pan the coordinates in the V direction.



Inputs



Coordinate

Takes in base UV texture coordinates the expression can then modify.

Time

Takes in a value used to determine the current panning position. This is usually a Time expression to provide a constant panning effect, but a Constant or Scalar Parameter can be used as well to set a specific offset or to control the panning through Matinee or Blueprints.

Panner generates UVs that change according to the Time input. The Coordinate input can be used to manipulate (e.g. offset) the UVs generated by the Panner node.

ParticlePositionWS

The ParticlePositionWS expression outputs Vector3 (RGB) data representing each individual particle's position in world space.



In this image, ParticlePositionWS is being fed into emissive color to visualize the data. The particle system has been scaled up to show how the color is changing based on position.

PixelNormalWS

The PixelNormalWS expression outputs vector data representing the direction that pixels are facing based on the current normal.



In this example, PixelNormalWS is fed into Base Color. Notice how the normal map is used to give the per-pixel result.

Rotator

The Rotator expression outputs UV texture coordinates in the form of a two-channel vector value that can be used to create rotating textures.

Item

Description



Properties



CenterX

Specifies the U coordinate to use as the center of the rotation.

CenterY

Specifies the V coordinate to use as the center of the rotation.

Speed

Specifies the speed to rotate the coordinates clockwise.



Inputs



Coordinate

Takes in base UV texture coordinates the expression can then modify.

Time

Takes in a value used to determine the current rotation position. This is usually a Time expression to provide a constant rotation effect, but a Constant or Scalar Parameter can be used as well to set a specific offset or to control the rotation through Matinee or Blueprints.

SceneTexelSize

The SceneTexelSize expression allows you to offset by texel sizes, as you would when using the SceneColor and SceneDepth expressions. This is useful for edge detection in multi-resolution systems, as without this calculation you would be forced to use a small static value, resulting in inconsistent results at lower resolutions.

ScreenPosition

The ScreenPosition expression outputs the screen-space position of the pixel currently being rendered.



TextureCoordinate

The TextureCoordinate expression outputs UV texture coordinates in the form of a two-channel vector value allowing materials to use different UV channels, specify tiling, and otherwise operate on the UVs of a mesh.

Item

Description



Properties



Coordinate Index

Specifies the UV channel to use.

UTiling

Specifies the amount of tiling in the U direction.

VTiling

Specifies the amount of tiling in the V direction.

Un Mirror U

If true, undo any mirroring in the U direction.

Un Mirror V

If true, undo any mirroring in the V direction.

Example Usage: To access the second UV channel of a mesh, create a TextureCoordinate node, set its CoordinateIndex to 1 (0 - first channel, 1 - second channel, etc), and connect it to the UVs input of a TextureSample node.



VertexNormalWS

The VertexNormalWS expression outputs the world-space vertex normal. It can only be used in material inputs that are executed in the vertex shader, like WorldPositionOffset. This is useful for making a mesh grow or shrink. Note that offsetting position along the normal will cause the geometry to split apart along UV seams.

In the example above, the preview sphere would seem to scale up and down with sinusoidal motion, as each of the vertices moved in their own normal directions.

VertexTangentWS

The VertexTangentWS expression outputs the world-space vertex tangents. Like VertexNormalWS, this is useful for manipulating the vertex positions of a mesh to produce subtle ambient animation through the World Position Offset input.

In the above example, each vertex on the sphere moves in a sinusoidal motion along the vertex tangent in world space. This gives an impression that the sphere is twisting to the left and right. On the plane, it causes the plane to wobble left and right along the vertex tangents.

ViewSize

The ViewSize expression outputs a 2D vector giving the size of the current view in pixels. This is useful for causing various changes in your materials based on the current resolution of the screen.

In this example, ViewSize is connected to Base Color and the result is divided by 2,400 to make the result more visible. When the size of the preview window increases or decreases, the color of the sphere changes.

WorldPosition

The WorldPosition expression outputs the position of the current pixel in world space. To visualize, simply plug the output into Emissive:



Common uses are to find the radial distance from the camera to a pixel (as opposed to the orthogonal distance from PixelDepth). WorldPosition is also useful to use as a texture coordinate and have unrelated meshes using the texture coord match up when they are near each other. Here is a basic example of using WorldPosition.xy to planar map a texture:



Using the Custom Material Expression

Known Issues

Input Arguments Are Function-Local

Syntax Errors When Using HLSLcc Compiler

Warnings

The Custom Material Expression enables you to write custom HLSL shader code operating on an arbitrary amount of inputs and outputting the result of the operation.

You can insert the Custom expression from the Custom category in the Material palette or from the right-click search menu in the Material Graph.



When the Custom node is selected, the following properties display in the Details Panel.



Property

Description

Code

Contains the shader code the expression will execute. (See warnings below)

Output Type

Specifies the type of the value output by the expression.

Description

Specifies the text to display in the title bar of the expression in the Material Editor.

Inputs

The array of inputs used by the expression.

Input Name

Specifies the name of the input. This is the name displayed on the expression in the Material Editor as well as the name used within the HLSL code to reference the input's value.

Additional Outputs

Enables you to define additional output pins to appear on the custom expression. When you add an output you must expand the array element and specify its Output Name and Output Type properties.

Additional Defines

Enables you to add additional Defines required by your custom HLSL code. When you add an element to the array you must specify the Define Name and Define Value properties.

Include File Paths

Specifies the file path to shader code you would like to include from source files outside the common shader paths Unreal Engine already provides.

Using the Custom Material Expression

Add as many inputs as you need to the Inputs array, and name them. Then type or paste your HLSL code in the Code property field. You can type either a full function body with return statements as shown in the example, or a simple expression such as Input.bgr. You must also specify the output data type in OutputType.

The example shown below is a Custom expression that can blur a Texture Object based on the value in a Scalar Parameter.



Click for full image.

Here is the code that was used above so that you can try the Custom node for yourself. Copy and paste the following text into the Code field in the Details Panel properties.

The following video shows the creation and result of a Custom expression using the above HLSL code.

Known Issues

The following sections detail some common pitfalls to be aware of when writing custom Material expressions.

Input Arguments Are Function-Local

Note that Custom expressions always have a return value because they are wrapped inside another function. All input arguments (like Tex, UV, r, and dist in the above example) are declared as parameters of that outer function, so their scope of visibility is function-local.

Sometimes developers write structures with member functions and expect these parameters to be accessible inside that structure, but they cannot access function-local parameters. Therefore, you must copy those parameters by hand when member functions are used inside the Custom expression.

The example below would fail to compile (assuming the same example as above).

Syntax Errors When Using HLSLcc Compiler

Some shader backends that use the older HLSLcc compiler report syntax errors on HLSL types such as vector and matrix. Try to be explicit with your data types and use float4 or float4x4 respectively. We keep fixing those bugs but at the same time we are moving our efforts to the new DirectXShaderCompiler (DXC).

Warnings

Using the custom node prevents constant folding and may use significantly more instructions than an equivalent version done with built in nodes! Constant folding is an optimization that Unreal Engine employs under the hood to reduce shader instruction count when necessary. For example, an expression chain of Sin >Mul by parameter > Add to something can and will be collapsed by Unreal Engine into a single instruction, the final add. This is possible because all of the inputs of that expression (parameter) are constant for the whole draw call, they do not change per-pixel. Unreal Engine cannot collapse anything in a custom node, which can produce less efficient shaders than an equivalent version made out of existing nodes. As a result, it is best to only use the custom node when it gives you access to functionality not possible with the existing nodes.

Shader code written in a custom node must be valid HLSL.

DepthFade

PixelDepth

SceneDepth

DepthFade

The DepthFade Material Expression is used to hide unsightly seams that occur when translucent objects intersect with opaque ones.

Property

Description

Fade Distance

World space distance over which the fade should take place. This is used if the FadeDistance input is unconnected.



Inputs



Opacity

Takes in the existing opacity for the object prior to the depth fade.

FadeDistance

World space distance over which the fade should take place.

In the comparison below, a translucent sphere intersects an opaque one (green). Note the smoother transition when DepthFade is used.





The Material network for this example is pictured below.



PixelDepth

The PixelDepth Material Expression outputs the depth, or distance from the camera, of the pixel currently being rendered.

This expression supports positive values, and not negative ones. This is because the renderer relies on the Conservative Depth optimization to maintain good performance on modern hardware. This has the added benefit that if depth can move away from the camera, hardware depth rejection can be reused from the vertex shader output. Otherwise, allowing pixel depth offset to move toward the camera could cause objects to poke through anything, and the pixel shader would have to run the pixel shader for all pixels regardless of whether they are occlude without pixel depth offset or not.





Result

Material Graph (Click to enlarge.)

In this example, the Material network was applied to the floor. Notice how the linear interpolation blends between the two colors as the floor recedes beyond 2048 units. A Power expression was used to boost the contrast between the two colors and yield a more meaningful visual result.

SceneDepth

The SceneDepth Material Expression outputs the existing scene depth. This is similar to PixelDepth, except that PixelDepth can sample the depth only at the pixel currently being drawn, whereas SceneDepth can sample depth at any location.

Only translucent materials may utilize SceneDepth.

Inputs

Description

UVs

Takes in UV texture coordinates used to determine how the depth "texture" is sampled.





Result

Material Graph (Click to enlarge.)

In this example, we have applied the material network to a translucent sphere. Notice how the SceneDepth node is reading the pixels behind the sphere, rather than the ones on its surface.

The resulting normalized depth is linear in the 0.0 to 1.0 range.

FontSample

FontSampleParameter

FontSample

The FontSample expression enables you to sample the texture pages out of a font resource as regular 2D textures. The alpha channel of the font will contain the font outline value. Only valid font pages can be specified.

Item

Description



Properties



Font

Holds the default font asset (from the Content Browser) to be held within the expression.

Font Texture Page

The current font texture page to be used as a part of the texture.



FontSampleParameter

The FontSampleParameter expression provides a way to expose a font-based parameter in a Material Instance Constant, making it easy to use different fonts in different instances. The alpha channel of the font will contain the font outline value. Only valid font pages can be specified.

Item

Description



Properties



Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Font

Holds the default font asset (from the Content Browser) to be held within the expression.

Font Texture Page

The current font texture page to be used as a part of the texture.



FunctionInput

FunctionOutput

MaterialFunctionCall

StaticBool

StaticSwitch

TextureObject

FunctionInput

The FunctionInput expression can only be placed in a material function, where it defines one of the function's inputs.

Item

Description



Properties



Input Name

The input's name, which will be displayed on MaterialFunctionCall expressions that use the material function containing the input.

Description

A description of the input, which will be displayed as a 'tooltip' when the connector for this input on a MaterialFunction Call expression is hovered over with the mouse.

Input Type

The type of data this input expects. Data passed to this input will be cast to this type, throwing a compiler error if the cast fails because the data is not compatible.

Preview Value

The value to use as a preview for this input when editing the material function containing it.

Use Preview Value As Default

If enabled, Preview Value will be used as the default value for this input if no data is passed in.

Sort Priority

Specifies the priority for this input to use when determining the order of the inputs to be displayed on a MaterialFunctionCall expression.

This node is used with Material Functions.

FunctionOutput

The FunctionOutput expression can only be placed in a material function, where it defines one of the function's outputs.

Item

Description



Properties



Output Name

The output's name, which will be displayed on MaterialFunctionCall expressions that use the material function containing the output.

Description

A description of the output, which will be displayed as a tooltip when the connector for this output on a MaterialFunction Call expression is hovered over with the mouse.

Sort Priority

Specifies the priority for this output to use when determining the order of the outputs to be displayed on a MaterialFunctionCall expression.

This node is used with Material Functions.

MaterialFunctionCall

The MaterialFunctionCall expression allows you to use an external Material Function from another material or function. The external function's input and output nodes become inputs and outputs of the function call node. If a MaterialFunction is selected in the Content Browser when placing one of these expressions, it will automatically be assigned.

Shortcut: F + Left Mouse Click

Item

Description



Properties



Material Function

Specifies the Material Function to be used.

This node is used with Material Functions.

StaticBool

The StaticBool expression is used to provide a default bool value for a static bool function input within a function. This node does not switch between anything, so it must be used in conjunction with a StaticSwitch node.

Item

Description



Properties



Value

The value of the bool, True (checked) or False.

This node is used with Material Functions.

StaticSwitch

The StaticSwitch expression works like a StaticSwitchParameter, except that it only implements the switch and does not create a parameter.

Item

Description



Properties



Default Value

The default bool value of the parameter that determines which input is active, True (checked) or False.



Inputs



True

The input that is used when the Value of the switch is True.

False

The input that is used when the Value of the switch is False.

Value

Takes in a bool value that determines which input is active.

This node is used with Material Functions.

TextureObject

The TextureObject expression is used to provide a default texture for a texture function input within a function. This node does not actually sample the texture, so it must be used in conjunction with a TextureSample node.

Item

Description



Properties



Texture

The texture from the Content Browser that will be applied to this node.

Sampler Type

The type of data that will be output from the node.

LandscapeLayerBlend

LandscapeLayerCoords

LandscapeLayerSwitch

LandscapeLayerWeight

LandscapeVisibilityMask

LandscapeLayerBlend

The LandscapeLayerBlend node enables you to blend together multiple Textures or Material networks so that they can be used as Landscape layers. The LandscapeLayerBlend uses an array to store information about the Landscape layers. To add layers to this array, select the plus sign icon.



Click image for full size.

When you add multiple layers to the LandscapeLayerBlend node, the Layer Names populate in the LandscapeLayerBlend node.



Click image for full size.

Number

Property

Description

1

Layers

The list of layers the node contains. You can add layers by clicking the plus icon ( ).

2

Additional Layers

These are what additional layers look like when they are collapsed.

3

Layer Name

The unique name that you give the layer. The Layer Name corresponds to the layer name used in Paint mode in the Landscape tool window.

4

Blend Type

Either LB_AlphaBlend, LB_HeightBlend, or LB_WeightBlend. See Landscape Layer Blend Types on this page.

5

Preview Weight

This is the weight value for the layer to preview the blending in the Material Editor.

6

Const Layer Input

This is for supplying a numeric value as a color to use in case you do not want to use a texture. This is mainly used for debugging a layer if there is an issue.

7

Const Height Input

This is for supplying a numeric value as a height in case you do not want to use a texture.

The following table details the Layer Blend node inputs and outputs.



Click image for full size.

Number

Item

Description

1

Layer *LayerName

Each layer adds an input for the layer to blend together. This input is only available after layers are added and named in the Details panel.

2

Height *LayerName

This is where you supply a height map to blend with. This input is only visible on layers that have their Blend Type property set to LB_HeightBlend.

3

Unlabeled Output

The result of the layers blended together.

Blending Layers

When using certain combinations of layer blend modes you could end up with black spots all over your Landscape where different layers meet. This problem is especially prevalent when using the LB_HeightBlend mode for multiple Landscape layers. LB_HeightBlend works by modulating the blend factor, or weight, for the layer using the specified height value. When you have multiple layers painted on an area and they all are set to LB_HeightBlend, it is possible that all the layers painted in a particular area will simultaneously have a 0 height value, so the desired blend factor for each layer becomes 0.

Because there is no implicit or explicit ordering, the result will be black spots because no layers will have any contribution to that area. The situation is worse when you are blending a Normal map, because it results in a Normal value of (0,0,0) which is not valid and will cause rendering problems with the lighting. The solution to this problem is to use LB_AlphaBlend for one of the layers like in the example below.

In the left image, all layers are LB_HeightBlend, causing some areas to be black. On the right, the red "1" layer has been changed to use LB_AlphaBlend, which solves the problem.



Click image for full size.

Below is an example of the properties of the Landscape Layer Blend node for all the layers being blended together. Make sure to note how the Soil layer has its blend mode set to LB_AlphaBlend while the other layers have theirs set to LB_HeightBlend. This is to stop the issue mentioned above (having black spots where layers meet) from happening.



Click image for full size.

If you need to delete a layer, click the drop-down arrow to the right of the layer's element number to open the menu, and select Delete.



Click image for full size.

LandscapeLayerCoords



Click image for full size.

Number

Property

Description

1

Mapping Type

The ELandscapeCoordMappingType that specifies the orientation to use when mapping the Material (or network) to the Landscape.

2

Custom UVType

The mapping place to use on the terrain. The CustomUVType outputs the UV coordinates to map the Material to the Landscape based on the given property values.

3

Mapping Scale

Applies uniform scaling to the UV coordinates.

4

Mapping Rotation

Applies the rotation, in degrees, to the UV coordinates.

5

Mapping Pan [U]

Applies the offset in the [U] direction to the UV coordinates.

6

Mapping Pan [V]

Applies the offset in the [V] direction to the UV coordinates.

7

Unlabeled Output

Outputs the UV coordinates to map the material to the Landscape based on the given property values.

LandscapeLayerSwitch

The LandscapeLayerSwitch node allows you to exclude some Material operations when a particular layer is not contributing to a region of the Landscape. This allows you to optimize your Material by removing calculations that are not necessary when a particular layer's weight is zero.



Click image for full size.

Number

Property

Description

1

Parameter Name

The unique name that you give to the parameter.

2

Preview Used

If checked, uses a preview.

3

LayerUsed

When the layer specified in the node's properties is in use by the current region of the Landscape.

4

LayerNotUsed

When the layer is not used by the current region of the Landscape and has a weight of zero.

5

Unlabeled Output

Either the LayerUsed or LayerNotUsed inputs, depending on whether or not the layer contributes to the particular region of the Landscape.

LandscapeLayerWeight

The LandscapeLayerWeight expression allows Material networks to be blended based on the weight for the associated layer obtained from the Landscape the Material.The weight for this layer is used as the alpha value for blending the two input networks.



Click image for full size.

Number

Property

Description

1

Parameter Name

The unique name that you give to the parameter.

2

Preview Weight

The weight to use for preview purposes in the Material Editor.

3

Const Base

You can specify a base color here that you would like for your Landscape to have

4

Base

The network to blend this layer with. This is generally the result of any previous layer blending, but can be empty if this is the first layer.

5

Layer

The network to blend together to create this layer.

6

Unlabeled Output

Outputs the result of the blending between the Base and Layer inputs based on the layer weights of the layers involved.

LandscapeVisibilityMask

The LandscapeVisibilityMask node removes visible parts of your Landscape, so you can create holes in your landscape to, for example, create caves.



Click image for full size.

Number

Property

Description

1

Unlabeled Output

Outputs the visibility mask properties.

Make sure the output is connected to the Opacity Mask slot of your Material and that the Materials Blend Mode is set to Masked. Otherwise the node may not work correctly.



Click image for full size.

Make Material Attributes

Set Material Attributes

Break Material Attributes

Get Material Attributes

Blend Material Attributes

Make Material Attributes

The Make Material Attributes node allows you to define any of the standard Material attributes found on the Main Material Node, bundle them together, and pass them along through a single output. This is useful when creating Layered Materials, as it allows you to define an entire Material within a Material Function and then utilize that data in a parent Material. You can also use it in complex Material setups in which you want to define multiple Material types and blend them together, all within one Material asset.



When connecting a Make Material Attributes node to a Material, you must make sure that the Use Material Attributes option is set to true (checked) in the Material properties. This will collapse the Main Material Node down to a single input, which accepts the incoming data from a Make Material Attributes node.



Make Material Attributes is superseded by the Set Material Attributes node, and in most cases you should use that instead.

Set Material Attributes

The Set Material Attributes expression serves the same purpose as Make Material Attributes. It allows you to define a set of Material Attributes, and pass them along as bundled data through a single wire.

Unlike the Make Material Attributes node, which displays all standard Material Attributes by default, the inputs that appear on the Set Material Attributes node are user-defined in the Details panel. This allows you to incorporate only the Material Attributes that you need.



For example, the Material Function shown below only requires four attributes — Base Color, Metallic, Roughness, and Normal. Using the Set Material Attributes expression instead of Make Material Attributes takes up less space and results in a more concise Material Graph.

In most cases, Set Material Attributes is preferred to Make Material Attributes.

The only drawback is that the node is not context sensitive, meaning the user must know which attributes they need to add to the array for various combinations of Blend Mode and Shading Model. If you are unsure, you can use the Make Material Attributes node, which contains all necessary inputs.

Break Material Attributes

The Break Material Attributes expression splits up an incoming set of Material Attributes, and outputs each individual attribute through a separate pin.

This is useful when creating Layered Materials, because it allows you to access the individual attributes within a Material Layer function. This enables you choose which attributes you want to plug into the Main Material node, and gives you the ability to selectively modify the attributes with additional logic in the Material Graph.



In the example above, Break Material Attributes is used to split up the attributes from a generic chrome Material Layer Function. The Metallic, Specular, Roughness and Normal attributes are passed into the Main Material Node unchanged, but the Base Color attribute is not used. Instead, a Vector 3 parameter is added to the Roughness texture and this result is passed into the Base Color input.

Get Material Attributes

Get Material Attributes performs the same task as Break Material Attributes, but offers significant workflow benefits. Instead of fully breaking apart the incoming Material Attributes, Get Material Attributes allows you to pull out only the attributes you need. Select the node and then click the Add Element icon in the Details Panel to add output pins.



You can use the dropdown menus to define which Material Attribute is targeted by each array element.



The Material shown below recreates the tinted chrome example from the Break Material Attributes section, but uses the Get and Set Material Attributes expressions instead. Note that the graph is cleaner and requires fewer wires.



In this case, only the Roughness data is broken out of the Material Attributes. A tint parameter is then added to the Roughness map to create some surface variation and the result is passed into Base Color with a Set Material Attributes node. The rest of the Material Attributes simply pass through unmodified.



Blend Material Attributes

The Blend Material Attributes expression takes two sets of Material Attributes, and blends them together using per-pixel operations defined in the Alpha input.

For example, this Material Layer Blend takes a top and bottom set of Material Attributes, and blends between them using a mask texture.



Click image to enlarge.

Abs

Add

AppendVector

Arccosine

ArccosineFast

Arcsine

ArcsineFast

Arctangent

Arctangent2

Arctangent2Fast

ArctangentFast

Ceil

Clamp

ComponentMask

Cosine

CrossProduct

Divide

DotProduct

Floor

Fmod

Frac

If

LinearInterpolate

Logarithm10

Logarithm2

Max

Min

Multiply

Normalize

OneMinus

Power

Round

Saturate

Step

SmoothStep

Sign

Sine

SquareRoot

Subtract

Tangent

Truncate

Abs

Abs is an abbreviation for the mathematical term "absolute value". The Abs expression outputs the absolute, or unsigned, value of the input it receives. Essentially, this means it turns negative numbers into positive numbers by dropping the minus sign, while positive numbers and zero remain unchanged.

Examples: Abs of -0.7 is 0.7; Abs of -1.0 is 1.0; Abs of 1.0 is also 1.0

Example Usage: Abs is commonly used with Dot Product to determine the angular relationship between two vectors: whether they are parallel, perpendicular, or somewhere in between. Normally, when you get the dot product of two vectors, the value is interpolated between 1.0 (for two parallel vectors) and -1.0 (for two exactly opposite vectors), with the midpoint of 0 indicating that the two vectors are perpendicular. When you take the absolute value of this dot product, the positive values remain unchanged, but the negative values are converted into positive numbers by dropping the minus sign. The result is therefore interpolated between 0 (for perpendicular vectors) and 1.0 (for parallel vectors, regardless of whether the vectors point in the same direction or opposite directions). This tells you simply how far the two vectors are from being orthogonal.



Add

The Add expression takes two inputs, adds them together, and outputs the result.

If you pass values with multiple channels, each channel is added separately. For example, if you pass RGB color values to each input, the R channel of the first input is added to the R channel of the second input and the result is stored in the R channel of the output; the G channel of the first input is added to the G channel of the second input and the result is stored in the G channel of the output, and so on.

Both inputs must have the same number of values, unless one of the values is a single Constant value. In that case, each channel of the multi-channeled input is added to the single float value, and the result is stored in a separate channel of the output value.

Property

Description

Const A

Takes in the value(s) to add to. Only used if the A input is not used.

Const B

Takes in the value(s) to be added. Only used if the B input is not used.



Inputs



A

Takes in the value(s) to add to.

B

Takes in the value(s) to be added.

Examples: Add of 0.2 and 0.4 is 0.6; Add of (0.2,-0.4,0.6) and (0.1,0.5,1.0) is (0.3,0.1,1.6); Add of (0.2,-0.4,0.6) and 1.0 is (1.2,0.6,1.6)

Example Usage: Add is often used to brighten/darken colors or to offset UV texture coordinates.



AppendVector

The AppendVector expression enables you to combine channels together to create a vector with more channels than the original. For example, you can take two individual Constant values and append them to make a two-channel Constant2 Vector value. This can be useful for reordering the channels within a single texture or for combining multiple grayscale textures into one RGB color texture.

Input

Description

A

Takes in the value(s) to append to.

B

Takes in the value(s) to be appended.

Examples: Append of 0.2 and 0.4 is (0.2,0.4); Append of (0.2,0.4) and (1.0) is (0.2,0.4,1.0).



Arccosine

The Arccosine expression outputs the inverse cosine function.

This is an expensive operation that is not reflected by the instruction count. Use ArccosineFast for a faster but less accurate alternative.



The image above shows two different visualizations of the result of applying this expression:

The top bar shows the result as an output color. The left end of the bar shows the color that results from using this expression on an input value of -1, and the right end of the bar shows the results for a value of 1.

In the graph, the X axis represents input values ranging from -1 to 1. The Y axis shows the results of using this expression on those input values, again ranging from -1 to 1.

ArccosineFast

The ArccosineFast expression outputs an approximation of the inverse cosine function that is faster to calculate than the more accurate Arccosine expression. Input must be between -1 and 1.

See the Arccosine expression above for a visualization of the output values.

Arcsine

The Arcsine expression outputs the inverse sine function.

This is an expensive operation that is not reflected by the instruction count. Use ArcsineFast for a faster but less accurate alternative.



The image above shows two different visualizations of the result of applying this expression:

The top bar shows the result as an output color. The left end of the bar shows the color that results from using this expression on an input value of -1, and the right end of the bar shows the results for a value of 1.

In the graph, the X axis represents input values ranging from -1 to 1. The Y axis shows the results of using this expression on those input values, again ranging from -1 to 1.

ArcsineFast

The ArcsineFast expression outputs an approximation of the inverse sine function that is faster to calculate than the more accurate Arcsine expression. Input must be between -1 and 1.

See the Arcsine expression above for a visualization of the output values.

Arctangent

The Arctangent expression outputs the inverse tangent function.

This is an expensive operation that is not reflected by the instruction count. Use ArctangentFast for a faster but less accurate alternative.



The image above shows two different visualizations of the result of applying this expression:

The top bar shows the result as an output color. The left end of the bar shows the color that results from using this expression on an input value of -1, and the right end of the bar shows the results for a value of 1.

In the graph, the X axis represents input values ranging from -1 to 1. The Y axis shows the results of using this expression on those input values, again ranging from -1 to 1.

Arctangent2

The Arctangent2 expression outputs the inverse tangent of x / y where input signs are used to determine quadrant.

This is an expensive operation that is not reflected by the instruction count. Use Arctangent2Fast for a faster but less accurate alternative.



The image above shows two different visualizations of the result of applying this expression:

The top bar shows the result as an output color. The left end of the bar shows the color that results from using this expression on an input value of -1, and the right end of the bar shows the results for a value of 1.

In the graph, the X axis represents input values ranging from -1 to 1. The Y axis shows the results of using this expression on those input values, again ranging from -1 to 1.

Arctangent2Fast

The Arctangent2Fast expression outputs an approximation of the inverse tangent of X / Y where input signs are used to determine quadrant. It is faster to calculate but less accurate than the Arctangent2 expression.

See the Arctangent2 expression above for a visualization of the output values.

ArctangentFast

The ArctangentFast expression outputs an approximation of the inverse tangent function that is faster to calculate than the more accurate Arctangent expression.

See the Arctangent expression above for a visualization of the output values.

Ceil

The Ceil expression takes in value(s), rounds them up to the next integer, and outputs the result. See also Floor and Frac.

Examples: Ceil of 0.2 is 1.0; Ceil of (0.2,1.6) is (1.0,2.0).



Clamp

The Clamp expression takes in value(s) and constrains them to a specified range, defined by a minimum and maximum value. A minimum value of 0.0 and maximum value of 0.5 means that the resulting value(s) will never be less than 0.0 and never greater than 0.5.

Property

Description

Clamp Mode

Selects the type of clamp to be used. CMODE_Clamp will clamp both ends of the range. CMODE_ClampMin and CMODE_ClampMax will only clamp their respective ends of the range.

Min Default

Takes in the value to use as the minimum when clamping. Only used when the Min input is unused.

Max Default

Takes in the value to use as the maximum when clamping. Only used when the Max input is unused.



Inputs



Min

Takes in the value to use as the minimum when clamping.

Max

Takes in the value to use as the maximum when clamping.

Examples: Clamping an input range of (0.0) to (1.0) 0.3 with Min 0.0 and Max 1.0 yields 0.3; Clamping 1.3 with Min 0.0 and Max 1.0 yields 1.0.



ComponentMask

The ComponentMask expression enables you to select a specific subset of channels (R, G, B, and/or A) from the input to pass through to the output. Attempting to pass a channel through that does not exist in the input will cause an error, unless the input is a single constant value. In that case, the single value is passed through to each channel. The current channels selected to be passed through are displayed in the title bar of the expression.

Property

Description

R

If checked, the red (first) channel of the input value will be passed through to the output.

G

If checked, the green (second) channel of the input value will be passed through to the output.

B

If checked, the blue (third) channel of the input value will be passed through to the output.

A

If checked, the alpha (fourth) channel of the input value will be passed through to the output.

Examples: ComponentMask with an input of (0.2,0.4,1.0) and the G channel will produce an output of (0.4), which appears as a 40% bright grayscale value when used as a color vector.



Cosine

The Cosine expression outputs the value of a cosine wave over the input range of [0, 1] and the output range of [-1, 1], both repeating. Most commonly, this is used to output a continuous oscillating waveform by connecting a Time expression to its input, but it can also be used to create ripples in worldspace or screenspace, or any other application where a continuous, smooth cycle is needed. A visual representation of the wave is shown below, scaled to the [0, 1] output range:



Property

Description

Period

Specifies the period of the resultant wave. In other words, this is how long one full oscillation takes to occur, or the time between each successive crest or each successive trough in the waveform. For example, in the image above, the period is one second.

Example Usage: This expression is useful anytime an oscillating effect is needed. The speed and amplitude of the oscillation can easily be controlled dynamically by multiplying the time input (speed) or the output (amplitude).



Click for full image.

In the example above, the color would oscillate with co-sinusoidal frequency.

CrossProduct

The CrossProduct expression computes the cross product of two three-channel vector value inputs and outputs the resulting three-channel vector value. Given two vectors in space, the cross product is a vector that is perpendicular to both of the inputs.

Input

Description

A

Takes in a three-channel vector value.

B

Takes in a three-channel vector value.

Example Usage: CrossProduct is often used to compute directions which are perpendicular to two other directions.



Divide

The Divide expression takes two inputs, divides the first input by the second, and outputs the result.

If you pass values with multiple channels, each channel is divided separately. For example, if you pass RGB color values to each input, the R channel of the first input is divided by the R channel of the second input and the result is stored in the R channel of the output; the G channel of the first input is divided by the G channel of the second input and the result is stored in the G channel of the output, and so on.

Both inputs must have the same number of values, unless one of the values is a single float value. In that case, each channel of the multi-channeled input is divided by the single float value, and the result is stored in a separate channel of the output value.

If the divisor is between 0 and 0.00001 in any channel, it is raised to 0.00001. If the divisor is between 0 and -0.00001 in any channel, it is lowered to -0.00001. This avoids the possibility of division by zero errors. However, it also means that the output value for the channel may be very large.

Property

Description

Const A

Takes in the value(s) to be divided, the dividend. Only used if the A input is unused.

Const B

Takes in the value(s) to divide by, the divisor. Only used if the B input is unused.



Inputs



A

Takes in the value(s) to be divided, the dividend.

B

Takes in the value(s) to divide by, the divisor.

Examples: Using Divide with A=(1.0) and B=(5.0) outputs (0.2), which appears as a dark gray.



DotProduct

The DotProduct expression computes the dot product, which can be described as the length of one vector projected onto the other, or as the cosine between the two vectors multiplied by their magnitudes. This calculation is used by many techniques for computing falloff. DotProduct requires both vector inputs to have the same number of channels.

Input

Description

A

Takes in a value or vector of any length.

B

Takes in a value or vector of the same length as A.



Floor

The Floor expression takes in value(s), rounds them down to the previous integer, and outputs the result. See also Ceil and Frac.

Examples: Floor of 0.2 is 0.0; Floor of (0.2,1.6) is (0.0, 1.0).



Fmod

The Fmod expression returns the floating-point remainder of the division operation of the two inputs. The Dividend (input "A") can be any value, but negative Dividends will result in negative results. The Divisor (second input) should not be zero as this implies a division by zero, but whether the Divisor is negative or positive will not affect the result. A common use case is to make a material that brightens up to a maximum value, then immediately drops back to the minimum value on the next frame, only to begin climbing toward the maximum again.



Click for full image.

In this example, FMod takes a zero-to-one UV progression and converts it into a repeating cycle every 0.2 UV units on the X axis in the green channel.

Frac

The Frac expression takes in values and outputs the fractional portion of those values. In other words, for an input value "X", the result is "X minus Floor of X". The output value will range from zero to one, inclusive on the low end, but not the high end. See also Ceil and Floor.

Examples: Frac of (0.2) is (0.2). Frac of (-0.2) is (0.8). Frac of (0.0,1.6,1.0) is (0.0,0.6,0.0).



In this example, the Frac node is converting time into a series of repeating 0 - 1 progressions, causing the color to fade (via the Lerp) from green to red, then snap back to green, repeating indefinitely.

If

The If expression compares two inputs and then passes through one of three other input values based on the result of the comparison. Both compared inputs must be single float values.

Input

Description

A

Takes in a single float value.

B

Takes in a single float value.

A > B

Takes in the value(s) to output if the value of A is greater than the value of B.

A = B

Takes in the value(s) to output if the value of A is equal to the value of B.

A < B

Takes in the value(s) to output if the value of A is less than the value of B.



In this example, the If expression takes in a heightmap and outputs either red or green based on whether the height falls under or over a value of 0.45.

LinearInterpolate

The LinearInterpolate expression blends between two input value(s) based on a third input value used as a mask. This can be thought of as a mask to define transitions between two textures, like a layer mask in Photoshop. The intensity of the mask Alpha determines the ratio of color to take from the two input values. If Alpha is 0.0, the first input is used. If Alpha is 1.0, the second input is used. If Alpha is between 0.0 and 1.0, the output is a blend between the two inputs. Keep in mind that the blend happens per channel. So, if Alpha is an RGB color, Alpha's red channel value defines the blend between A and B's red channels independently of Alpha's green channel, which defines the blend between A and B's green channels.

Property

Description

Const A

The value mapped to 0.0. Only used if the A input is unconnected.

Const B

The value mapped to 1.0. Only used if the B input is unconnected.

Const Alpha

Takes in the value to use as the mask alpha. Only used if the Alpha input is unconnected.



Inputs



A

Takes in the value(s) mapped to 0.0.

B

Takes in the value(s) mapped to 1.0.

Alpha

Takes in the value to use as the mask alpha.

Programmers: LinearInterpolate does a per-channel lerp between A and B based on the parametric value Alpha.



Logarithm10

The Logarithm10 node returns the base-10 logarithm, also called the common logarithm, of the input value. That is, if you take a base value of 10 and raise it to the power of the number returned by this expression, you would get the input value.

Only use positive input values for this expression.



Click for full image.

Logarithm2

The Logarithm2 node returns the base-2 logarithm of the input value. That is, if you take a base value of 2 and raise it to the power of the number returned by this expression, you would get the input value.

Only use positive input values for this expression.



Click for full image.

Max

The Max expression takes in two inputs and outputs the higher of the two.

When you use this node with color inputs, the result is similar to the Lighten layer blending mode in Photoshop.



In the example above, A is "0" and B is "1"; therefore, "1" (white) is the resulting base color.

Property

Description

Const A

Takes in the first value(s). Used only if the A input is unused.

Const B

Takes in the second value(s). Used only if the B input is unused.



Inputs



A

Takes in the first value(s) to compare.

B

Takes in the second value(s) to compare.

Min

The Min expression takes in two inputs and outputs the lower of the two.

When you use this node with color inputs, the result is similar to using the Darken layer blending mode in Photoshop.



In the example above, A is "0" and B is "1"; therefore, "0" (black) is the resulting base color.

Property

Description

Const A

Takes in the first value(s). Used only if the A input is unused.

Const B

Takes in the second value(s). Used only if the B input is unused.



Inputs



A

Takes in the first value(s) to compare.

B

Takes in the second value(s) to compare.

Multiply

The Multiply expression takes two inputs, multiplies them together, and outputs the result. When you pass color values as input, the results are similar to the results of the Multiply layer blending mode in Photoshop.

If you pass values with multiple channels, each channel is multiplied separately. For example, if you pass RGB color values to each input, the R channel of the first input is multiplied by the R channel of the second input and the result is stored in the R channel of the output; the G channel of the first input is multiplied by the G channel of the second input and the result is stored in the G channel of the output, and so on.

Both inputs must have the same number of values, unless one of the values is a single float value. In that case, each channel of the multi-channeled input is multiplied by the single float value, and stored in a separate channel of the output value.

Property

Description

Const A

Takes in the first value(s) to multiply. Used only if the A input is unused.

Const B

Takes in the second value(s) to multiply. Used only if the B input is unused.



Inputs



A

Takes in the first value(s) to multiply.

B

Takes in the second value(s) to multiply.

Do not forget that Materials in Unreal Engine are not limited to [0,1]. If colors/values are greater than 1, Multiply will actually brighten colors.

Examples: Multiply of 0.4 and 0.5 is 0.2; Multiply of (0.2,-0.4,0.6) and (0.0,2.0,1.0) is (0.0,-0.8,0.6); Multiply of (0.2,-0.4,0.6) and 0.5 is (0.1,-0.2,0.3).

Example Usage: Multiply is often used to brighten or darken colors/textures, or manipulate the UVs of a texture.

Note how texture scale changes when the UVs are multiplied by one and then two.



Normalize

The Normalize expression calculates and outputs the normalized value of its input. Normalized vectors (also called "unit vectors") have an overall length of 1.0. This means each component of the input is divided by the total magnitude (length) of the vector.

Examples: Passing either (0,2,0) or (0,0.2,0) through Normalize will output (0,1,0). Passing (0,1,-1) through Normalize will output (0, 0.707, -0.707). The only special case is an all-zero vector, which will be unchanged.





It is not necessary to normalize an expression that plugs into the Normal material output.

OneMinus

The OneMinus expression takes an input value "X" and outputs "One Minus X". This operation is performed per channel.

Examples: OneMinus of 0.4 is 0.6; OneMinus of (0.2,0.5,1.0) is (0.8,0.5,0.0); OneMinus of (0.0,-0.4,1.6) is (1.0,1.4,-0.6).

Example Usage: When the input colors are in the range [0,1], OneMinus has the same effect as what is commonly called "invert" -- that is, OneMinus returns the complementary color that when added to the input will produce white.

Adding a OneMinus node inverts the values in the Texture Sample.



Power

The Power expression takes two inputs: a base value (Base) and an exponent (Exp). It raises the base value to the power of the exponent and outputs the result. In other words, it returns Base multiplied by itself Exp times.

Property

Description

Const Exponent

Takes in the exponent value. Used only if the Exp input is unused.



Inputs



Base

Takes in the base value.

Exp

Takes in the exponent value.

Examples: Power of Base 0.5, Exp 2.0 is 0.25.

Example Usage: If the colors you pass to Power are in [0,1], Power can behave as a sort of contrast adjustment, where very bright values are dimmed slightly, but darker values are decreased drastically.

Adding a Power node increases the contrast in the Texture Sample.



Round

The Round expression rounds the input value to the nearest whole number. If the fractional part of the input value is 0.5 or greater, then the output value is rounded up. Otherwise, the output value is rounded down.





Examples:

A value of 1.1 will be rounded down to a value of 1.

A value of 1.4 will be rounded down to a value of 1.

A value of 1.5 will be rounded up to a value of 2.

A value of 1.85 will be rounded up to a value of 2.

Saturate

The Saturate node clamps the value between 0 and 1. Values less than 0 are raised to 0; values greater than 1 are lowered to 1; values between 0 and 1 inclusive remain unchanged. The instruction cost of Saturate is almost free on most modern graphics hardware, so you can use this node any time you need to clamp an input or output value between 0 and 1 without effect on your material's performance.



Example Usage: This node should be used whenever you need to clamp an output or input value between 0 and 1.

Step

The Step Material Expression returns 0 or 1 for every value of X, depending on whether it is greater than or less than the reference value in Y.

Below, a linear gradient (0 to 1) is plugged into the X input. The value in Y (0.25) acts as the reference value. Every value on the gradient below 0.25 on the returns a 0 (black), every value greater than or equal to 0.25 returns a 1 (white).

Note that the threshold between black and white moves when you increase the value in Y .



The Step expression is useful when an abrupt on/off effect is needed. For example, you could also use a Step expression to simplify a grayscale texture into a black and white mask.

SmoothStep

SmoothStep lets you interpolate between 0 and 1 for values between a Min and Max threshold. SmoothStep takes three arguments:

Min defines the lower edge of the interpolation. SmoothStep returns 0 (black) for values less than or equal to Min.

Max defines the upper edge of the interpolation. Smoothstep returns 1 (white) for values greater than or equal to Max.

Value defines the source value(s) for interpolation. For example, a gradient or a grayscale texture map.

This expression is useful for transitions where you want the edge to have some degree of smoothness.

Below a LinearGradient is passed into the Value input, and the Min and Max values are set at 0.1 and 0.9. This results in a relatively smooth gradient where 0.1 is black and 0.9 is white.

The Min and Max values control where interpolation begins and ends.



On the second slide, the Min and Max are set to 0.6 and 0.8, resulting in a much more abrupt transition. Everything below 0.6 is black, everything above 0.8 is white, with a smooth gradient in between.

Sign

The Sign node indicates whether a numeric input is negative, positive, or exactly 0.

If the input is negative, this node outputs -1.

If the input is exactly 0, this node outputs 0.

If the input is positive, this node outputs 1.



Click for full image.

Sine

The Sine expression outputs the value of a Sine wave over the input range of [0, 1] and the output range of [-1, 1], both repeating. The difference between this and the output of the Cosine expression is the output waveform is offset by one-quarter of the period, meaning that Cos(X) is equal to Sin(X + 0.25). Most commonly, this is used to output a continuous oscillating waveform by connecting a **Time**expression to its input, but it can also be used to create ripples in worldspace or screenspace, or any other application where a continuous, smooth cycle is needed. A visual representation of the wave is shown below, scaled to the [0, 1] output range:



Property

Description

Period

Specifies the period of the resultant wave. In other words, this is how long one full oscillation takes to occur, or the time between each successive crest or each successive trough in the waveform. For example, in the image above, the period is one second.

Example Usage: This expression is useful anytime an oscillating effect is needed. The speed and amplitude of the oscillation can easily be controlled dynamically by multiplying the time input (speed) or the output (amplitude).



Click for full image.

SquareRoot

The SquareRoot expression outputs the square root of the input value. If applied to a vector, each component will be handled individually.

For textures in the 0 to 1 range, this reduces the apparent contrast of the image. For example, on the calibration texture below, dark values become brighter and white values shift toward gray.



Subtract

The Subtract node takes in two inputs, subtracts the second input from the first, and outputs the difference.

If you pass values with multiple channels, each channel is subtracted separately. For example, if you pass RGB color values to each input, the R channel of the second input is subtracted from the R channel of the first input and the result is stored in the R channel of the output; the G channel of the second input is subtracted from the G channel of the first input and the result is stored in the G channel of the output, and so on.

Both inputs must have the same number of values, unless one of the values is a single Constant value. In that case, each channel of the multi-channel input has the Constant value subtracted from it, and the result stored in a separate channel of the output value.

Property

Description

Const A

Takes in the value(s) of the minuend. Used only if the A input is unused.

Const B

Takes in the value(s) of the subtrahend. Used only if the B input is unused.



Inputs



A

Takes in the value(s) of the minuend.

B

Takes in the value(s) of the subtrahend.

Examples: Subtract of 0.5 and 0.2 is 0.3; Subtract of (0.2,-0.4,0.6) and (0.1,0.1,1.0) is (0.1,-0.5,-0.4); Subtract of (0.2,0.4,1.0) and 0.2 is (0.0,0.2,0.8).

Example Usage: Subtract can be used to darken colors and offset UVs.



Tangent

The Tangent node outputs the tangent of the specified value.



The image above shows two different visualizations of the result of applying this expression:

The top bar shows the result as an output color. The left end of the bar shows the color that results from using this expression on an input value of -1, and the right end of the bar shows the results for a value of 1.

In the graph, the X axis represents input values ranging from -1 to 1. The Y axis shows the results of using this expression on those input values, again ranging from -1 to 1.

Truncate





The Truncate node truncates a value by discarding the fractional part while leaving the whole number untouched.

Examples:

An input value of 1.1 will be truncated to 1.

An input value of 1.4 will be truncated to 1.

An input value of 2.5 will be truncated to 2.

An input value of 3.1 will be truncated to 3.

Collection Parameters

DynamicParameter

ScalarParameter

StaticSwitchParameter

StaticBoolParameter

StaticComponentMaskParameter

VectorParameter

TextureObjectParameter

TextureSampleParameter2D

TextureSampleParameterCube

TextureSampleParameterMovie

Collection Parameters

A Collection Parameter Expression is used to reference a Material Parameter Collection asset. These are groups of parameters that you can easily reuse in many different assets such as Materials, Blueprints, and more.

They enable you to modify a global value once in the Parameter Collection, and have it propagate to mulitple Materials that reference the collection. For more information, read the Material Parameter Collections documentation.



Click to enlarge image.

A Material can reference, at most, two different MaterialParameterCollections. One is typically used for game-wide values while the other can be used for level specific parameters. A collection can have up to 1024 scalar parameters and 1024 vector parameters.

DynamicParameter

The DynamicParameter expression provides a conduit for particle emitters to pass up to four values to the Material to be used in any manner. These values are set in Cascade by means of a ParameterDynamic module placed on an emitter.

Property

Description

Param Names

An array of the names of the parameters. The values here will determine the text displayed on the outputs of the expression in the Material Editor and will be the names used to reference the parameters in the ParameterDynamic module in Cascade.

Default Value

Specifies the initial values that the parameter outputs (Vector4).



Outputs



Param1

Outputs the value of the first parameter in the Param names property. The name of this output can change based on the values in the Param Names property.

Param2

Outputs the value of the second parameter in the Param names property. The name of this output can change based on the values in the Param Names property.

Param3

Outputs the value of the third parameter in the Param names property. The name of this output can change based on the values in the Param Names property.

Param4

Outputs the value of the fourth parameter in the Param names property. The name of this output can change based on the values in the Param Names property.

FontSampleParameter

The FontSampleParameter expression provides a way to expose a font-based parameter in a Material Instance Constant, making it easy to use different fonts in different instances. The alpha channel of the font will contain the font outline value. Only valid font pages can be specified.

Item

Description



Properties



Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Font

Holds the default font asset (from the Content Browser) to be held within the expression.

Font Texture Page

The current font texture page to be used as a part of the texture.



ScalarParameter

The ScalarParameter expression outputs a single float value (constant) that you can access and change in a Material Instance or on the fly by Blueprint or code.

Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Default Value

Specifies the initial value that the constant takes on.

You can update the value in a Scalar Parameter, and immediately see the results without recompiling the Material.

Scalar parameter updated from 0 to 10.



StaticSwitchParameter

The StaticSwitchParameter expression takes in two inputs, and outputs the first if the value of the parameter is true, and the second otherwise.

This parameter is named static because it cannot change at runtime; it can only be set in the Material Instance Editor. Static Switches are applied at compile time, not at runtime. This means that whatever branch of the Material was dropped is never executed, so static switches are effectively free at runtime. On the other hand, a new version of the Material must be compiled for every used combination of static parameters in a Material, which can lead to a massive increase in shader permutations if abused. Try to minimize the number of static parameters in the Material and the number of permutations of those static parameters that are actually used.

Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Default Value

If true, the first input is output. Otherwise, the second input is output.

Extended Caption Display

If true, the title bar of the expressions displays the value of the expression.



Inputs



A

Takes in a value of any number of channels.

B

Takes in a value of any number of channels.

Example Usage: You can use Static Switches to remove an entire branch of a Material with no runtime cost. Material Instances can have different values, making it possible to have a templated shader setup with no performance loss.

Static Switch updated from True to False.



StaticBoolParameter

The StaticBoolParameter works like a StaticSwitchParameter, except that it only creates a bool parameter and does not implement the switch. You can use a StaticBoolParameter to pass a default value into a boolean input on a Material Function.



Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Default Value

The default bool value of the parameter, True (checked) or False.

Static Switches are applied at compile time (not at runtime), meaning you can override the parameter in the Material Instance Editor, but it cannot change during gameplay. Whatever branch of the Material was dropped is never executed, which means static switches are effectively free at runtime. On the other hand, a new version of the Material must be compiled for every used combination of static parameters in a Material, which can lead to a massive increase in shader permutations if abused. Try to minimize the number of static parameters in the Material and the number of permutations of those static parameters that are actually used.

This node is used with MaterialFunctions.

StaticComponentMaskParameter

The StaticComponentMaskParameter expression behaves like an ordinary Component Mask, except that you can override the mask values in a Material Instance.

This parameter is named static because it cannot change at runtime; it can only be set in the Material Instance Editor. Static Switches are applied at compile time, not at runtime. This means that whatever branch of the Material was dropped will never be executed, so static switches are effectively free at runtime. On the other hand, a new version of the Material must be compiled out for every used combination of static parameters in a Material, which can lead to a massive increase in shader permutations if abused. Try to minimize the number of static parameters in the Material and the number of permutations of those static parameters that are actually used.

Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Default R

If checked, the red, or first, channel of the input value is passed through to the output.

Default G

If checked, the green, or second, channel of the input value is passed through to the output.

Default B

If checked, the blue, or third, channel of the input value is passed through to the output.

Default A

If checked, the alpha, or fourth, channel of the input value is passed through to the output.

Example Usage: You can use Static Component Masks to let instances dictate which channel of a mask texture to use. If the mask is static (does not need to change at runtime) then this approach should always be used instead of multiplying a texture lookup by a Vector Parameter to mask out channels, since the latter wastes texture bandwidth and shader instructions.

Checked channels pass through to the output, while unchecked channels are discarded.



VectorParameter

The VectorParameter expression is identical to the Constant4Vector, except that it is a parameter you can modify in instances of the Material and through code. One nicety of the VectorParameter is that you can set its value using the Color Picker.

Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Default Value

R

G

B

A



The vector to output by default unless overridden by a MaterialInstanceConstant.

Specifies the float value of the red, or first, channel of the vector the expression outputs.

Specifies the float value of the green, or second, channel of the vector the expression outputs.

Specifies the float value of the blue, or third, channel of the vector the expression outputs.

Specifies the float value of the alpha, or fourth, channel of the vector the expression outputs.





VertexColor is mutually exclusive with the Transform node due to limited interpolators. If you use both a Transform node and VertexColor, then VertexColor will come out all white.

Programmers: For sprite particles, colors are communicated to the shader per vertex, whereas colors for mesh particles are set as shader constants.

TextureObjectParameter

The TextureObjectParameter expression defines a texture parameter and outputs the texture object. This expression is frequently used to pass texture parameters into a Material Function with texture inputs. Texture inputs on a Material Function node are not compatible with Float3 data from a TextureSample 2D node, so the Texture Object (T2d) is required. This node does not actually sample the texture, so it must be used in conjunction with a TextureSample node.



Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Texture

Specifies the texture sampled by the expression.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.

This node is used with MaterialFunctions.

TextureSampleParameter2D

The TextureSampleParameter2D expression is identical to the TextureSample except that it is a parameter that you can modify in Material Instances and through Blueprint or code.



Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Texture

Specifies the texture sampled by the expression.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

Takes in UV texture coordinates to use for the texture. If no values are input to the UVs, the texture coordinates of the mesh the material is applied to are used.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically illegal, will always result in zero (black).

TextureSampleParameterSubUV

The TextureSampleParameterSubUV expression is identical to the ParticleSubUV except that it is a parameter that can be modified in instances of the material and through code.

Item

Description



Properties



Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Blend

Blends together each frame of the SubUV sprite layout, rather than instantly "popping" from one frame to the next.

Texture

Specifies the texture sampled by the expression.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

The UV input is ignored and does nothing.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically illegal, will always result in zero (black).

TextureSampleParameterCube

The TextureSampleParameterCube expression is identical to the TextureSample except that it only accepts cubemaps and it is a parameter that can be modified in instances of the material and through code.

Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Texture

Specifies the texture sampled by the expression.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

Takes in UV texture coordinates to use for the texture. If no values are input to the UVs, the texture coordinates of the mesh the Material is applied to are used. This input accepts a two-channel vector value.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically invalid, will always result in zero (black).

TextureSampleParameterMovie

The TextureSampleParameterMovie expression is identical to the TextureSample except that it only accepts movie textures (Bink movies) and it is a parameter that you can modify in instances of the Material and through code.

Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Texture

Specifies the texture sampled by the expression.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

Takes in UV texture coordinates to use for the texture. If no values are input to the UVs, the texture coordinates of the mesh the Material is applied to are used.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically illegal, will always result in zero (black).

DynamicParameter

ParticleColor

ParticleDirection

ParticleMacroUV

ParticleMotionBlurFade

ParticlePositionWS

ParticleRadius

ParticleRelativeTime

ParticleSize

ParticleSpeed

SphericalParticleOpacity

ParticleSubUV

TextureSampleParameterSubUV

DynamicParameter

The DynamicParameter expression provides a conduit for particle emitters to pass up to four values to the Material to be used in any manner. These values are set in Cascade by means of a ParameterDynamic module placed on an emitter.

Property

Description

Param Names

An array of the names of the parameters. The values here will determine the text displayed on the outputs of the expression in the Material Editor and will be the names used to reference the parameters in the ParameterDynamic module in Cascade.

Default Value

Specifies the initial values that the parameter outputs (Vector4).



Outputs



Param1

Outputs the value of the first parameter in the Param names property. The name of this output can change based on the values in the Param Names property.

Param2

Outputs the value of the second parameter in the Param names property. The name of this output can change based on the values in the Param Names property.

Param3

Outputs the value of the third parameter in the Param names property. The name of this output can change based on the values in the Param Names property.

Param4

Outputs the value of the fourth parameter in the Param names property. The name of this output can change based on the values in the Param Names property.

ParticleColor

The ParticleColor expression ties into the current color of a given particle based on any per-particle color data defined within Cascade. This must be plugged into the appropriate channel (Emissive Color).

Item

Description



Outputs



RGB

Outputs the combined RGB vector data.

R

Outputs the red channel data.

G

Outputs the green channel data.

B

Outputs the blue channel data.

A

Outputs the alpha channel data.



In this example, you can see where the ParticleColor expression is providing color to the particles as defined within the particle system.

ParticleDirection

The ParticleDirection expression outputs Vector3 (RGB) data on a per-particle basis, representing the direction a given particle is currently traveling.



You can see in the comparison below how the color of the particles is changing based on the current direction each particle is traveling.

Note how the color changes as the particles change directions.



ParticleMacroUV

The ParticleMacroUV expression outputs UV texture coordinates that can be used to map any 2d texture onto the entire particle system in a continuous way, meaning the texture will be seamless across particles. The UVs will be centered around MacroUVPosition (specified in Cascade on the ParticleSystem, under the MacroUV category) and MacroUVRadius determines the world space radius that the UVs should tile at. The ParticleMacroUV node is useful for mapping continuous noise onto particles to break up the pattern introduced by mapping a texture onto each particle with normal texture coordinates.

Item

Description



Properties



Use View Space

If true, effectively offsets the coordinates based on the depth of each sprite and creates a parallax effect, which can be useful for giving explosions a radial blur look



ParticleMotionBlurFade

The ParticleMotionBlurFade expression outputs a value representing the amount of fade on a particle as a result of motion blur. A value of 1 represents no blur, black represents complete blur.



ParticlePositionWS

The ParticlePositionWS expression outputs Vector3 (RGB) data representing each individual particle's position in world space.



In this image, ParticlePositionWS is being fed into emissive color to visualize the data. The particle system has been scaled up to show how the color is changing based on position.

ParticleRadius

The ParticleRadius expression outputs the radius in Unreal units of each particle individually. This allows, for example, for changes to be made to a material once the radius has reached a certain point.



In this image, the particles are shifting from green to red as their radius exceeds 7 units.

ParticleRelativeTime

The ParticleRelativeTime expression outputs a number between 0 and 1 representing a particle's age, with 0 being the moment of birth and 1 being the moment of death.



In this example, you can see the particle relative time fed into the emissive color, resulting in particles that are fading from black at the moment of birth to white as they approach death.

ParticleSize

The Particle Size expression outputs the X and Y size of a particle sprite. This can then be used to drive some aspect of a Material.





Click image for full view.

In the example above, Particle Size is being multiplied into Particle Color. Notice that we are masking the output so that we only use the Green channel, which corresponds to the Y-Axis, or the length of the particles. This means that as the particles stretch out, they become brighter in color. As they shrink, they will become dimmer.

ParticleSpeed

ParticleSpeed outputs the current speed each particle is traveling, measured in Unreal units per second.



In this example, particle speed is feeding the color of the particles, which is then divided by 10 provide more meaningful results. The particles become black as they slow down.

SphericalParticleOpacity

The SphericalParticleOpacity expression creates a procedural opacity map to cause sprite particles to appear spherical. This can be much simpler than having to create an import a texture map for a similar effect.

Item

Description



Inputs



Density

This 0-1 value controls the density of the sphere map. Lower values result in more transparent spheres. Default is 1.







ParticleSubUV

The ParticleSubUV expression is used to render sub-images of a texture to a particle. ParticleSubUV is similar to a flipbook, except that ParticleSubUV allows the texture animation to be manipulated in Cascade.

Item

Description



Properties



Blend

Blends together each frame of the SubUV sprite layout, rather than instantly "popping" from one frame to the next.

Texture

Specifies the texture to use.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

The UV input is ignored and does nothing.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically illegal, will always result in zero (black).



TextureSampleParameterSubUV

The TextureSampleParameterSubUV expression is identical to the ParticleSubUV except that it is a parameter that can be modified in instances of the material and through code.

Item

Description



Properties



Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Blend

Blends together each frame of the SubUV sprite layout, rather than instantly "popping" from one frame to the next.

Texture

Specifies the texture sampled by the expression.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

The UV input is ignored and does nothing.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically illegal, will always result in zero (black).

SceneColor

SpriteTextureSampler

TextureSample

TextureProperty

FontSample

The FontSample expression enables you to sample the texture pages out of a font resource as regular 2D textures. The alpha channel of the font will contain the font outline value. Only valid font pages can be specified.

Item

Description



Properties



Font

Holds the default font asset (from the Content Browser) to be held within the expression.

Font Texture Page

The current font texture page to be used as a part of the texture.



FontSampleParameter

The FontSampleParameter expression provides a way to expose a font-based parameter in a Material Instance Constant, making it easy to use different fonts in different instances. The alpha channel of the font will contain the font outline value. Only valid font pages can be specified.

Item

Description



Properties



Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Font

Holds the default font asset (from the Content Browser) to be held within the expression.

Font Texture Page

The current font texture page to be used as a part of the texture.



SceneColor

The SceneColor Material expression outputs the existing scene color.

Property

Description

OffsetFraction

Takes in a 2D vector that offsets the scene color in screen space. Setting this to either 0,1 or 1,0 will provide a slightly brighter version of the scene color. Setting it to 1,1 will provide an even brighter result.



SpriteTextureSampler

A custom sprite Material can be created by duplicating one of the existing ones, or creating a new Material in the Content Browser. When a sprite is rendered, the texture defined in a sprite asset will be piped into any texture parameters named "SpriteTexture" in the Material. The SpriteTextureSampler node can be placed to do this automatically.



Sprite instances will pass in their color as a vertex color, but it can be used for anything in the material, not just tinting.

Property

Description

Texture

Specifies the texture sampled by the expression. To set the texture, first select a texture in the Content Browser. Then, select the Texture property in the expression's property window and click the 'Use Current Selection' button.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

Takes in UV texture coordinates to use for the texture. If no values are input to the UVs, the texture coordinates of the mesh the material is applied to are used.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically illegal, will always result in zero (black).

TextureObject

The TextureObject expression is used to provide a default texture for a texture function input within a function. This node does not actually sample the texture, so it must be used in conjunction with a TextureSample node.

Item

Description



Properties



Texture

The texture from the Content Browser that will be applied to this node.

Sampler Type

The type of data that will be output from the node.

TextureSample

The TextureSample expression outputs the color value(s) from a texture. This texture can be a regular Texture2D (including normal maps), a cubemap, or a movie texture.

Property

Description

Texture

Specifies the texture sampled by the expression. To set the texture, first select a texture in the Content Browser. Then, select the Texture property in the expression's property window and click the 'Use Current Selection' button.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

Takes in UV texture coordinates to use for the texture. If no values are input to the UVs, the texture coordinates of the mesh the Material is applied to are used. If the TextureSample represents a cubemap texture, the UVs coordinate must be a three-channel value rather than just a two-channel value.

DDX(UVs)

Takes the DDX of UVs input for anisotropic filtering. By default, the hardware automatically do it, and faster. But there is some cases where you may need to explicitly to set it avoiding the DDX Material expresion to avoid artifacts like the 2x2 pixels block artifact of the deferred decal. Only available with MipValueMode = Derivative.

DDY(UVs)

Takes the DDY of UVs input for anisotropic filtering as same as DDX(UVs) takes the DDX of the UVs input.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically illegal, will always result in zero (black).



For a better understanding of the DDX(UVs) and DDY(UVs) inputs, you can set the MipValueMode to Derivative and configure the graph like the image below. Keep in mind that this has the exact same output as with MipValueMode = None, but is slower. The DDX(UVs) and DDY(UVs) should only be used when you actually need to overide the default hardware computation because computing those values by a different way than using the DDX/DDY material expression.



TextureProperty

The TextureProperty exposes a texture's property of your choice such as the texture's size or texel size.



ParticleSubUV

The ParticleSubUV expression is used to render sub-images of a texture to a particle. ParticleSubUV is similar to a flipbook, except that ParticleSubUV allows the texture animation to be manipulated in Cascade.

Item

Description



Properties



Blend

Blends together each frame of the SubUV sprite layout, rather than instantly "popping" from one frame to the next.

Texture

Specifies the texture to use.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

The UV input is ignored and does nothing.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically illegal, will always result in zero (black).



TextureObjectParameter

The TextureObjectParameter expression defines a texture parameter and outputs the texture object. This expression is frequently used to pass texture parameters into a Material Function with texture inputs. Texture inputs on a Material Function node are not compatible with Float3 data from a TextureSample 2D node, so the Texture Object (T2d) is required. This node does not actually sample the texture, so it must be used in conjunction with a TextureSample node.



Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Texture

Specifies the texture sampled by the expression.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.

This node is used with MaterialFunctions.

TextureSampleParameter2D

The TextureSampleParameter2D expression is identical to the TextureSample except that it is a parameter that you can modify in Material Instances and through Blueprint or code.



Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Texture

Specifies the texture sampled by the expression.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

Takes in UV texture coordinates to use for the texture. If no values are input to the UVs, the texture coordinates of the mesh the material is applied to are used.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically illegal, will always result in zero (black).

TextureSampleParameterSubUV

The TextureSampleParameterSubUV expression is identical to the ParticleSubUV except that it is a parameter that can be modified in instances of the material and through code.

Item

Description



Properties



Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Blend

Blends together each frame of the SubUV sprite layout, rather than instantly "popping" from one frame to the next.

Texture

Specifies the texture sampled by the expression.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

The UV input is ignored and does nothing.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically illegal, will always result in zero (black).

TextureSampleParameterCube

The TextureSampleParameterCube expression is identical to the TextureSample except that it only accepts cubemaps and it is a parameter that can be modified in instances of the material and through code.

Property

Description

Parameter Name

Specifies the name used to identify the parameter in instances of the Material and through code.

Group

Provides a way to organize parameter names into groups, or categories, within a MaterialInstanceConstant. All parameters within a Material that have the same Group property name will be listed underneath that category in the Instance Editor.

Texture

Specifies the texture sampled by the expression.

Sampler Type

The type of data that will be sampled and output from the node.

MipValueMode

Selects how to customize the sample's mip-level or derivatives from the default hardware computed. Affects the look and performance.



Inputs



UVs

Takes in UV texture coordinates to use for the texture. If no values are input to the UVs, the texture coordinates of the mesh the Material is applied to are used. This input accepts a two-channel vector value.



Outputs



RGB

Outputs the three-channel RGB vector value of the color.

R

Outputs the red channel of the color.

G

Outputs the green channel of the color.

B

Outputs the blue channel of the color.

A

Outputs the alpha channel of the color. If a texture does not contain an alpha channel, connecting the 'alpha' channel to something, while not technically invalid, will always result in zero (black).

AntialiasedTextureMask

BlackBody

BumpOffset

ConstantBiasScale

DDX

DDY

DepthFade

DepthOfFieldFunction

Desaturation

Distance

DistanceFieldGradient

DistanceToNearestSurface

FeatureLevelSwitch

Fresnel

GIReplace

LightmassReplace

LinearInterpolate

Noise

Previous Frame Switch

QualitySwitch

RotateAboutAxis

SphereMask

Thin Translucent

Vector Noise

Utility Material Expressions are nodes that can affect Materials in a number of different ways than one might be used to. For example the GIReplace node will replace an object's indirect bounce color with a given value you input, while the Linear Interpolate node will help blend between two textures based on an Alpha input. On the following page you will find detailed descriptions for all of the Utility expressions are available in the Material Editor.

AntialiasedTextureMask

The AntialiasedTextureMask expression allows you to create a Material using a soft (anti-aliased) transition mask. The mask can be used to blend between two complex Material properties or to fade out an alpha blended Material (works well with SoftMasked). Specify a texture with the mask specified in one channel (red, green, blue, or alpha), set the used channel in the expression and specify the comparison value. Assuming the channel stores a grayscale value in the range 0 = black to 1 = white the comparison function defines if the resulting mask should be 0 or 1. This expression is a parameter, allowing the Texture property to be overridden by child MaterialInstances.

Item

Description



Properties



Threshold

Specifies the value used as the cutoff point in pixel coverage. Pixel coverage values less than this become black; values greater become white.

Channel

Specifies the channel of the Texture to use as the mask.

Texture

Specifies the mask texture to use.



Inputs



UVs

Takes in texture coordinates to apply to the texture mask.

Pseudo code:

The actual implementation is quite a bit more complicated as it tries to return values between 0 and 1 depending on the actual pixel coverage to avoid aliasing.

Example (this tiny 128x128 texture, uncompressed for best quality):



Was used as a normal texture (left top) and used with the described material expression (bottom right):



The technique works best in magnification and with blurred input content. Compression hurts the quality a lot so try to use uncompressed low resolution textures.

BlackBody

The BlackBody expression simulates the effects of black body radiation within your Material. The user inputs a temperature (in Kelvin) and the resulting color and intensity can be used to drive Base Color and Emissive values to get a physically accurate result.



BumpOffset

BumpOffset is the Unreal Engine 4 term for what is commonly known as 'Parallax Mapping'. The Bump Offset expression allows a material to give the illusion of depth without the need for additional geometry. BumpOffset materials use a grayscale heightmap to give depth information. The brighter the value in the heightmap, the more 'popped out' the material will be; these areas will parallax (shift) as a camera moves across the surface. Darker areas in the heightmap are 'further away' and will shift the least.

Item

Description



Properties



HeightRatio

Multiplier for the depth taken from the heightmap. The larger the value, the more extreme the depth will be. Typical values range from 0.02 to 0.1.

ReferencePlane

Specifies the approximate height in texture space to apply the effect. A value of 0 will appear to distort the texture completely off the surface, whereas a value of 0.5 (the default) means that some of the surface will pop off while some areas will be sunken in.



Inputs



Coordinate

Takes in base texture coordinates to be modified by the expression.

Height

Takes in the texture (or a value) to be used as the heightmap.

HeightRatioInput

Multiplier for the depth taken from the heightmap. The larger the value, the more extreme the depth will be. Typical values range from 0.02 to 0.1. If used, this input supersedes any value in the Height Ratio property.



ConstantBiasScale

The ConstantBiasScale expression takes an input value, adds a bias value to it, and then multiplies it by a scaling factor outputting the result. So for example, to convert input data from [-1,1] to [0,1] you would use a bias of 1.0 and a scale of 0.5.

Properties

Description

Bias

Specifies the value to be added to the input.

Scale

Specifies the multiplier for the biased result.



DDX

The DDX expression exposes DDX derivative calculation, a GPU hardware feature used in pixel shader calculation.

DDY

The DDY expression exposes DDX derivative calculation, a GPU hardware feature used in pixel shader calculation.

DepthFade

The DepthFade expression is used to hide unsightly seams that take place when translucent objects intersect with opaque ones.

Item

Description



Properties



Fade Distance

World space distance over which the fade should take place. This is used if the FadeDistance input is unconnected.



Inputs



Opacity

Takes in the existing opacity for the object prior to the depth fade.

FadeDistance

World space distance over which the fade should take place.





The Material network for this example is pictured below.



DepthOfFieldFunction

The Depth of Field Function expression is designed to give artists control over what happens to a Material when it is being blurred by Depth of Field. It outputs a value between 0-1 such that 0 represents "in focus" and 1 represents "completely blurred." This is useful for interpolating between sharp and blurry versions of a texture, for instance. The Depth input allows for the existing results from the scene's Depth of Field calculations to be overridden by other calculations.







Click image for full size view.

Desaturation

The Desaturation expression desaturates its input, or converts the colors of its input into shades of gray, based a certain percentage.

Item

Description



Properties



Luminance Factors

Specifies the amount that each channel contributes to the desaturated color. This is what controls that green is brighter than red which is brighter than blue when desaturated.



Inputs



Fraction

Specifies the amount of desaturation to apply to the input. Percent can range from 0.0 (full original color, no desaturation) to 1.0 (fully desaturated).



Programmers: Define desaturated color D, input color I and luminance factor L. The output will be O = (1 - Percent)*( D.dot( I )) + Percent * I

Distance

The Distance expression computes the (Euclidian) distance between two points/colors/positions/vectors and outputs the resulting value. This works on one, two, three and four component vectors, but both inputs to the expression must have the same number of channels.

Item

Description



Inputs



A

Takes in a value or vector of any length.

B

Takes in a value or vector of any length.

Note how the color changes as the camera distance increases.



Pseudo code:

Low level HLSL code:

DistanceFieldGradient

The DistanceFieldGradient Material Expression node, when normalized, outputs the X,Y,Z direction an object would move with in the distance field. This makes the Distance Field Gradient Material Expression node well-suited for Materials that need to simulate the flow of liquids.

Generate Mesh Distance Fields must be enabled in Project Settings under Rendering for this expression to work correctly.

Item

Description

Position

Defaults to current World Position if nothing is input.

Here is an example of how to use the DistanceFieldGradient Material Expression in your Materials. In this example below make sure to note that the DistanceFieldGradient was first normalized and then input into a Mask Channel node. The reason for this is because without normalizing the DistanceFieldGradient first you can not get directional data. The Mask Channel Parameter was added to allow for easier RGB channel switching with in the Material Instance.



Click image for full size view.

Here is an example of the DistanceFieldGradient in action. The image below shows what data the DistanceFieldGradient will use when the various RGB are enabled.



Click image for full size view.

Number

Description

1

Enabling the R channel and disabling all other channels.

2

Enabling the G channel and disabling all other channels.

3

Enabling the B channel and disabling all other channels.

DistanceToNearestSurface

The Distance To Nearest Surface Material Expression node allows Materials to sample any point in the levels Global Distance Field. This Material Expression works by outputting the signed distance in world space units from the distance field to the nearest occluders in the scene.

Generate Mesh Distance Fields must be enabled in Project Settings under Rendering for this expression to work correctly.

Item

Description

Position

Defaults to current World Position if nothing is input.

Here is an example of the Distance To Nearest Surface Material Expression in action.



Click image for full size view.



In this example the Distance To Nearest Surface was fed into the Opacity input on a Material and that Material was applied to a Static Mesh plane that was placed just above the levels floor. What the Distance To Nearest Surface is doing is telling the Material to only color areas red were the Static Meshes plane will start to intersect other Static Meshes placed in the scene.

FeatureLevelSwitch

The Feature Level Switch node allows you to make simplified materials for lower powered devices.

Example Usage: You might have a material with 10 textures overlapping and complex math, but just a single static texture for mobile (feature level ES2).

Inputs

Description

Default

The default Feature Level.

ES2

Feature Level defined by the core capabilities of OpenGL ES2.

ES3.1

Feature Level defined by the capabilities of Metal-level devices.

SM4

Feature Level defined by the core capabilities of DX10 Shader Model 4.

SM5

Feature Level defined by the core capabilities of DX11 Shader Model 5.

Fresnel

The Fresnel expression calculates a falloff based on the dot product of the surface normal and the direction to the camera. When the surface normal points directly at the camera, a value of 0 is output. When the surface normal is perpendicular to the camera, a value of 1 is output. The result is clamped to [0,1] so you do not have any negative color in the center.

Item

Description



Properties



Exponent

Specifies the how quickly the output value falls off. Larger values mean tighter or quicker falloff.

Base Reflect Fraction

Specifies the fraction of specular reflection the surface is viewed from straight on. A value of 1 effectively disables the Fresnel effect.



Inputs



ExponentIn

Specifies the how quickly the output value falls off. Larger values mean tighter or quicker falloff. If used, value will always supersede the Exponent property value.

Base Reflect Fraction

Specifies the fraction of specular reflection the surface is viewed from straight on. A value of 1 effectively disables the Fresnel effect. If used, value will always supersede the Exponent property value.

Normal

Takes in a three-channel vector value representing the normal of the surface, in world space. To see the results of a normal map applied to the surface of the Fresnel object, connect the normal map to the Normal input of the material, then connect a PixelNormalWS expression to this input on the Fresnel. If no normal is specified, the tangent normal of the mesh is used.



GIReplace

GIReplace allows artists to specify a different, usually simpler, expression chain when the material is being used for GI.

Example Usage: Lightmass static GI and LPV dynamic GI use it.

Inputs

Description

Default

The default GI.

StaticIndirect

Used for baked indirect lighting.

DynamicIndirect

Used for dynamic indirect lighting.

LightmassReplace

The LightmassReplace expression simply passes through the Realtime input when compiling the material for normal rendering purposes, and passes through the Lightmass input when exporting the material to Lightmass for global illumination. This is useful to work around material expressions that the exported version cannot handle correctly, for example WorldPosition.

Inputs

Description

Realtime

Takes in the value(s) to pass through for normal rendering.

Lightmass

Takes in the value(s) to pass through when exporting the material to Lightmass.

LinearInterpolate

The LinearInterpolate expression blends between two input value(s) based on a third input value used as a mask. This can be thought of as a mask to define transitions between two textures, like a layer mask in Photoshop. The intensity of the mask Alpha determines the ratio of color to take from the two input values. If Alpha is 0.0, the first input is used. If Alpha is 1.0, the second input is used. If Alpha is between 0.0 and 1.0, the output is a blend between the two inputs. Keep in mind that the blend happens per channel. So, if Alpha is an RGB color, Alpha's red channel value defines the blend between A and B's red channels independently of Alpha's green channel, which defines the blend between A and B's green channels.

Item

Description



Properties



Const A

The value mapped to 0.0. Only used if the A input is unconnected.

Const B

The value mapped to 1.0. Only used if the B input is unconnected.

Const Alpha

Takes in the value to use as the mask alpha. Only used if the Alpha input is unconnected.



Inputs



A

Takes in the value(s) mapped to 0.0.

B

Takes in the value(s) mapped to 1.0.

Alpha

Takes in the value to use as the mask alpha.

Programmers: LinearInterpolate does a per-channel lerp between A and B based on the parametric value Alpha.



Noise

The Noise expression creates a procedural noise field, giving you control over how it is generated.

Item

Description



Properties



Scale

Changes the overall size of the noise cells. Lower numbers make the noise bigger.

Quality

A look/performance setting. Lower values are faster but may look worse, higher values are slower but may look better.

Function

Function

Description

Simplex

Texture Based

High quality for direct use and bumps about 77 instructions per level, 4 Texture lookups, Can not tile.

Gradient

Texture Based

High quality for direct use and bumps. Non-tiled: about 61 instructions per level, 8 Texture lookups. Tiling: about 74 instructions per level, 8 Texture lookups. Even "non tiled' mode has a repeat of 128. Useful repeat size range <= 128. Formerly labeled as Perlin Noise.

Fast Gradient

3D Texture

High quality for direct use, BAD for bumps. about 16 instructions per level, 1 Texture lookup. Always tiles with a repeat of 16, "Tiling" mode is not an option for Fast Gradient noise.

Gradient

Computational

High quality for direct use and bumps. Non-tiled: about 80 instructions per level, no Textures. Tiling: about 143 instructions per level, no Textures.

Value

Computational

Low quality, but pure computation. Non-tiled: about 53 instructions per level, no Textures. Tiling: about 118 instructions per level, no Textures. Formerly mislabeled as Gradient noise.

Voronoi

Also know as Worley or Cellular noise. Quality = 1 searches 8 cells, Quality = 2 searches 16 cells, Quality = 3 searches 27 cells, Quality = 4 searches 32 cells. All are about about 20 instructions per cell searched.

Turbulence

With Turbulence on, each noise octave will add only absolute values to the result. Changes the visual characteristics and can great shapes resembling sharp mountain ridges

Levels

How many different levels of noise at different scales to combine, multiplies the computational cost by the number of levels.

Output Min

The lowest value output by the noise calculation.

Output Max

The highest value output by the noise calculation.

Level Scale

Level scale is always active and determines how much the scale changes for each new octave.

Tiling

For noise functions that support it, allows noise to tile. This is more expensive, but useful when baking noise into a seamless wrapping texture.

Repeat Size

When tiling, how often should the noise repeat.



Inputs



Position

Allows the texture size to be adjusted via a 3D vector.

FilterWidth

In effect, controls how much blur will be applied to the noise texture.



Previous Frame Switch

The Previous Frame Switch Material Expression enables you to support complex vertex animations implemented in your materials to generate correct motion vectors so that they can work correctly with Temporal AA and Motion Blur.

Materials that are only a function of time already work without modification, however, they cannot account for other variables, such as Material Parameters, that can affect the animation. The Previous Frame Switch Material Expression enables Artists to solve these types of problem manually by tracking how these parameters change, for instance, in Blueprints, where they can manually provide expressions for motion vector generation that is caused by changes in World Position Offset between frames.

Velocities from vertex deformation must be enabled in Project Settings under Rendering for this expression to work:

4.24 and later versions use Accurate velocities from Vertex Deformation

4.25 and future versions use Output velocities from vertex deformation

Item

Description

Current Frame

Directional Vector used as the starting position reference.

Previous Frame

Directional Vector used as the XYZ reference for the amount of blur to add.

Here is an example using Previous Frame Switch Material Expression in a Material.



In this example, the Previous Frame Switch is using a constant value to control the directional blur through a Multiply node.

In this example, you can see how this is being used in Epic's own games, like Fortnite, to control the motion blur with a Vertex Animation that assembles on screen. The animation on the right is using Previous Frame Switch to add some motion blur, while the animation on the left is not.

QualitySwitch

The QualitySwitch expression allows for the use of different expression networks based on the engine is switched between quality levels, such as using lower quality on lower-end devices.

Inputs

Description

Default

This input is used for networks designed for default visual quality.

Low

This input is used for networks designed for lower visual quality.

High

This input is used for networks designed for higher visual quality.

RotateAboutAxis

The RotateAboutAxis expression rotates a three-channel vector input given the rotation axis, a point on the axis, and the angle to rotate. It is useful for animations using WorldPositionOffset that have better quality than simple shears.

Inputs

Description

NormalizedRotationAxis

Takes in a normalized (0-1) vector which represents the axis about which the object will rotate.

RotationAngle

The angle of rotation. A value of 1 equals a full 360-degree rotation.

PivotPoint

Takes in the three-channel vector representing the pivot point about which the object will rotate.

Position

Takes in the three-channel vector representing the position of the object. When the RotateAboutAxis expression is created, a WorldPosition expression is automatically created and connected to this input.



In the above example, the preview plane would appear to spin on its vertical axis.

SphereMask

The SphereMask expression outputs a mask value based on a distance calculation. If one input is the position of a point and the other input is the center of a sphere with some radius, the mask value is 0 outside and 1 inside with some transition area. This works on one, two, three, and four component vectors

Item

Description



Properties



Attenuation Radius

Specifies the radius to use for the distance calculation.

Hardness Percent

Specifies the transition area size. This works like the Photoshop brush hardness value. 0 means the transition is hard, 100 means the transition area is maximal(soft).



Inputs



A

Takes in the value representing the position of the point to check.

B

Takes in the value representing the center of the sphere.

The node outputs a value of 1 until the camera passes beyond a certain distance, after which it outputs 0.



Thin Translucent

The Thin Translucent Material Output expression accurately represents physically based transparent materials in a single pass. This enables you to create true tinted or colored transparent materials that accurately respond to lighting and shading.



Click image for full size.

When creating a tinted glass material, a white specular highlight and tinted background are needed. These are rendered in a single pass with a physically based shader that accounts for light bounces from the air into the glass and the glass into the air.





Enable Thin Translucent material output by setting the following in the Material Details panel:

Blend Mode: Translucent

Shading Model: Thin Translucent

Lighting Mode: Surface ForwardShading

Vector Noise



The Vector Noise Material expression adds several more 3D or 4D vector noise results to use in your Materials. Due to the run-time expense of these functions, it is recommended that once a look is developed with them, all or part of the computation be baked into a Texture using the Render Targets feature.

These Material graph Expressions allow procedural looks to be developed in the engine on final assets, providing an alternative to creating procedurally generated Textures with an external tool. Inside the Vector Noise Material Expression, you will find the following Vector Noise types.

Image

Item

Description



Cellnoise

Returns a random color for each cell in a 3D grid (i.e. from the mathematical floor operation applied to the node input). The results are always consistent for a given position, so can provide a reliable way to add randomness to a Material. This Vector Noise function is extremely cheap to compute, so it is not necessary to bake it into a Texture for performance.



Perlin 3D Noise

Returns a random color for each cell in a 3D grid (i.e. from the mathematical floor operation applied to the node input). The results are always consistent for a given position, so can provide a reliable way to add randomness to a Material. This Vector Noise function is extremely cheap to compute, so it is not necessary to bake it into a Texture for performance.



Perlin Gradient

Computes the analytical 3D gradient of a scalar Perlin Simplex Noise. The output is four channels, where the first three (RGB) are the gradient, and the fourth (A) is the scalar noise. This noise type is useful for bumps on a surface or for flow maps.



Perlin Curl

Computes the analytical 3D curl of a vector Perlin Simplex Noise (aka Curl Noise). The output is a 3D signed curl vector and is useful for fluid or particle flow.



Voronoi

Computes the same Voronoi noise as the scalar Noise material node. The scalar Voronoi noise scatters seed points in 3D space and returns the distance to the closest one. The Vector Noise version returns the location of the closest seed point in RGB, and the distance to it in A. Especially coupled with Cellnoise, this can allow some randomized behavior per Voronoi cell.

Below is a simple stone bed Material using the distance component of the Voronoi Vector Noise to modulate some surface bumps and blend moss into the cracks. The seed position together with Vector Noise > Cellnoise is used to change the color and bump height per rock.



The derivative-based operations Perlin Curl and Perlin Gradient can be added together in octaves, just as regular Perlin noise can. For derivatives of more complex expressions, it is necessary to compute the gradient of the result of the expression. To help with this, place the expression to compute into a Material Function and use it with the following helper nodes.

Item

Description

Prepare3DDeriv

Uses positions offset in a tetrahedral pattern to compute 3D derivatives. Evaluate the same 3D function at each offset position produced by this function, then feed the resulting values into Compute3DDeriv.

Compute3DDeriv

Uses positions offset in a tetrahedral pattern to compute 3D derivatives. Use with Prepare3DDeriv.

GradFrom3DDeriv

Computes 3D gradient vector from result of Prepare3DDeriv/Compute3DDeriv.

CurlFrom3DDeriv

Computes curl of a 3D vector field from result of Prepare3DDeriv/Compute3DDeriv.

These helper Material Functions use four evaluations of the base expression spaced in a tetrahedral pattern to approximate these derivative-based operations.

Below you will find descriptions of the various noise functions you will find in the Vector Noise Material Expression.

Item

Description



Properties



Function

Function

Description

Cellnoise

Random color for each integer grid cell in 3D space. About 10 instructions.

Perlin 3D Noise

Computational Perlin noise with 3D output, each channel output ranges from -1 to 1. About 83 instructions if only the red channel is used, 125 instructions if all three channels are used

Perlin Gradient

Computes the gradient of a Perlin noise function. RGB output contains the gradient vector, A is the scalar noise. About 106 instructions.

Perlin Curl

Computes a 3D curl noise. The output is the mathematical curl of Perlin 3D Noise. About 162 instructions.

Voronoi

The same algorithm and instruction counts as the Voronoi function in the Noise expression, but RGB is the location of the closest seed point in each Voronoi cell, and A is the distance to that seed point.

Quality

A look/performance setting. Lower values are faster but may look worse, higher values are slower but may look better.

Tiling

For noise functions that support it this allows noise to tile. This is more expensive, but useful when baking noise into a seamless wrapping texture.

Tile Size

When tiling, how often should the noise repeat. For Perlin noise variants, the Tile Size must be a multiple of three.



Inputs



Position

Allows the texture size to be adjusted via a 3D vector.

Cell Noise Material Example:



Click for full image.

Perlin Gradient Material Example:



Click for full image.

Voronoi Material Example:



Click for full image.

ActorPositionWS

CameraPositionWS

CameraVectorWS

LightVector

Object Bounds

ObjectOrientation

ObjectPositionWS

PixelNormalWS

Pre-Skinned Local Normal

Pre-Skinned Local Position

ReflectionVectorWS

VertexNormalWS

Vector Noise

This page documents the available Vector Material Expressions that output vector values mapped to RGBA. These are useful for many different spatial Material effects, including getting an object's position in world space so that the Material can react, or transitioning colors on a character when they enter a specific area. There are many others that enable you to control local Material effects that you can learn more about in the examples below.

ActorPositionWS

ActorPositionWS outputs Vector3 (RGB) data representing the location of the object with this material on it in world-space.



In this example, ActorPositionWS is passed directly into the Base Color of the Material. As a result, each of the objects with the Material applied to them show a different color as they are moved to different locations in 3D space. Note that the result of the ActorPositionWS node is being divided by 1600 to create a nice blend-in color, rather than an abrupt pop.

CameraPositionWS

The CameraWorldPosition expression outputs a three-channel vector value representing the camera's position in world space.

In the example below, Camera Position is passed into the base color of the Material. Note how the preview sphere changes color as the camera position changes.

CameraVectorWS

The CameraVector expression outputs a three-channel vector value representing the direction of the camera with respect to the surface. In other words, the direction from the pixel to the camera.

Example Usage: CameraVector is often used to fake environment maps by connecting the CameraVector to a ComponentMask and using the X and Y channels of the CameraVector as texture coordinates.



Constant2Vector

The Constant2Vector expression outputs a two-channel vector value, in other words, two constant numbers.

Property

Description

R

Specifies the float value of the red (first) channel of the vector the expression outputs.

G

Specifies the float value of the green (second) channel of the vector the expression outputs.

Examples: (0.4, 0.6), (1.05, -0.3)

Example Usage: The Constant2Vector is useful for modifying texture scale or offset, as UV coordinates require two-channel values.



To quickly create a Constant2Vector node, hold the 2 key and left-click anywhere in the background of the Material Graph.

Constant3Vector

The Constant3Vector expression outputs a three-channel vector value, in other words, three constants numbers. A Constant3Vector is often used to define a solid RGB color, where each channel is assigned to a color (red, green, blue). You can double-click the Constant3Vector node in the Material Graph to summon a color picker dialog.

Property

Description

R

Specifies the float value of the red (first) channel of the vector the expression outputs.

G

Specifies the float value of the green (second) channel of the vector the expression outputs.

B

Specifies the float value of the blue (third) channel of the vector the expression outputs.

Examples: (0.4, 0.6, 0.0), (1.05, -0.3, 0.3)

In this example an Constant3Vector is multiplied by a Texture Sample to change the tint of the texture.



To quickly create a Constant3Vector node, hold 3 key and left-click anywhere in the Material Graph.

Constant4Vector

The Constant4Vector expression outputs a four-channel vector value, in other words, four constant numbers. You can use the Constant4Vector expression to define RGBA color, where each chanel is assigned to a color (red, green, blue, alpha).

Property

Description

R

Specifies the float value of the red (first) channel of the vector the expression outputs.

G

Specifies the float value of the green (second) channel of the vector the expression outputs.

B

Specifies the float value of the blue (third) channel of the vector the expression outputs.

A

Specifies the float value of the alpha (fourth) channel of the vector the expression outputs.

Examples: (0.4, 0.6, 0.0, 1.0), (1.05, -0.3, 0.3, 0.5)

In the example below, a Constant4Vector expression is used to define both the Base Color and Opacity of the Material. The top pin outputs the RGB color, while the bottom pin outputs the value in the alpha channel. The alpha value of 0.5 results in a semi-transparent Material.



To quickly create a Constant4Vector, hold the 4 key and left-click anywhere in the background of the Material Graph.

LightVector

When used with a Deferred Decal Material and Decal actor, the LightVector Material Expression outputs Vector (RGB) data, which represents the normalized (in a range between 0 and 1) position of the current pixel relative to decal projection box, in the decal's coodinate space.

If used with a LightFunction Material, the LightVector Material Expression outputs Vector (RGB) data representing the vector from the light to the pixel, in the light's coordinate space.

In other Material Domains, the LightVector expression is unused.

The LightVector Material Expression should only be used with the Deferred Decal or LightFunction Material Domains.

Example

You can use the LightVector Material Expression to create a linear falloff effect for a Deferred Decal. In the graph below, there are two parameters which control the depth and falloff of the blend between the decal and the receiving surface.



The result is shown below.

Object Bounds

The Object Bounds expression outputs the size of the object on which the Material is applied for each axis. The expression outputs a float3, representing the X, Y, and Z axis. If this node is plugged into Base Color, the axes correspond to R, G, and B, respectively.



In the video below, note how the Material changes color when the object is scaled on each axis.

ObjectOrientation

The ObjectOrientation expression outputs the world-space up vector of the object on which the Material is applied. In other words, the object's local positive z-axis is pointing in this direction.



ObjectPositionWS

The ObjectPositionWS expression outputs the world-space center position of the object's bounds. Each sphere in the image below displays a different color as they are moved to a different position in space. The RGB color channels correspond to the X, Y and Z axes in the level. This node is useful when creating spherical lighting for foliage.



ParticlePositionWS

The ParticlePositionWS expression outputs Vector3 (RGB) data representing each individual particle's position in world space.



In this image, ParticlePositionWS is being fed into emissive color to visualize the data. The particle system has been scaled up to show how the color is changing based on position.

PixelNormalWS

The PixelNormalWS expression outputs vector data representing the direction that pixels are facing based on the current normal.



In this example, PixelNormalWS is fed into Base Color. Notice how the normal map is used to give the per-pixel result.

Pre-Skinned Local Normal

The Pre-Skinned Local Normals Vector Expression outputs a three-channel vector value representing the local surface normal for Skeletal and Static Meshes. This enables you to achieve locally-aligned tri-planar Materials and mesh aligned effects in your Materials.

In this example, the Material below is using a tri-planar texture aligned to the mesh's local surface normal.



Click to enlarge image.





Tri-Planar Pre-Skinned Local Normal Vector Expression

Tri-Planar Material

Pre-Skinned Local Position

The Pre-Skinned Local Position Vector Expression outputs a three-channel vector value that gives access to a Skeletal Mesh's default pose position data for use in per-vertex outputs. This enables you to have localized effects on an animated character. This vector expression can also be used with Static Meshes, which will return the standard local position.



Click to enlarge image.

In this example, the Skeletal Mesh's default pose is used for mapping versus the default UV mapping on the right.





Pre-Skinned Local Position Vector Expression

Skeletal Mesh's Default UV Layout

ReflectionVectorWS

The ReflectionVectorWS expression is similar in spirit to CameraVectorWS, but it outputs a three-channel vector value representing the camera direction reflected across the surface normal.

Example Usage: ReflectionVector is commonly used in environment maps, where the Reflection Vector is passed into the UV coordinates of a cubemap texture. This enables you to create arbitrary reflections on a Material which do not match the physical environment. You can also use the Reflection Vector to create cheap, fake reflections on translucent Materials that do not have Surface TranslucencyVolume or Surface ForwardShading enabled.



VertexNormalWS

The VertexNormalWS expression outputs the world-space vertex normal. It can only be used in material inputs that are executed in the vertex shader, like WorldPositionOffset. This is useful for making a mesh grow or shrink. Note that offsetting position along the normal will cause the geometry to split apart along UV seams.

In the example above, the preview sphere would seem to scale up and down with sinusoidal motion, as each of the vertices moved in their own normal directions.

Vector Noise



The Vector Noise Material expression adds several more 3D or 4D vector noise results to use in your Materials. Due to the run-time expense of these functions, it is recommended that once a look is developed with them, all or part of the computation be baked into a Texture using the Render Targets feature.

These Material graph Expressions allow procedural looks to be developed in the engine on final assets, providing an alternative to creating procedurally generated Textures with an external tool. Inside the Vector Noise Material Expression, you will find the following Vector Noise types.

Image

Item

Description



Cellnoise

Returns a random color for each cell in a 3D grid (i.e. from the mathematical floor operation applied to the node input). The results are always consistent for a given position, so can provide a reliable way to add randomness to a Material. This Vector Noise function is extremely cheap to compute, so it is not necessary to bake it into a Texture for performance.



Perlin 3D Noise

Returns a random color for each cell in a 3D grid (i.e. from the mathematical floor operation applied to the node input). The results are always consistent for a given position, so can provide a reliable way to add randomness to a Material. This Vector Noise function is extremely cheap to compute, so it is not necessary to bake it into a Texture for performance.



Perlin Gradient

Computes the analytical 3D gradient of a scalar Perlin Simplex Noise. The output is four channels, where the first three (RGB) are the gradient, and the fourth (A) is the scalar noise. This noise type is useful for bumps on a surface or for flow maps.



Perlin Curl

Computes the analytical 3D curl of a vector Perlin Simplex Noise (aka Curl Noise). The output is a 3D signed curl vector and is useful for fluid or particle flow.



Voronoi

Computes the same Voronoi noise as the scalar Noise material node. The scalar Voronoi noise scatters seed points in 3D space and returns the distance to the closest one. The Vector Noise version returns the location of the closest seed point in RGB, and the distance to it in A. Especially coupled with Cellnoise, this can allow some randomized behavior per Voronoi cell.

Below is a simple stone bed Material using the distance component of the Voronoi Vector Noise to modulate some surface bumps and blend moss into the cracks. The seed position together with Vector Noise > Cellnoise is used to change the color and bump height per rock.



The derivative-based operations Perlin Curl and Perlin Gradient can be added together in octaves, just as regular Perlin noise can. For derivatives of more complex expressions, it is necessary to compute the gradient of the result of the expression. To help with this, place the expression to compute into a Material Function and use it with the following helper nodes.

Item

Description

Prepare3DDeriv

Uses positions offset in a tetrahedral pattern to compute 3D derivatives. Evaluate the same 3D function at each offset position produced by this function, then feed the resulting values into Compute3DDeriv.

Compute3DDeriv

Uses positions offset in a tetrahedral pattern to compute 3D derivatives. Use with Prepare3DDeriv.

GradFrom3DDeriv

Computes 3D gradient vector from result of Prepare3DDeriv/Compute3DDeriv.

CurlFrom3DDeriv

Computes curl of a 3D vector field from result of Prepare3DDeriv/Compute3DDeriv.

These helper Material Functions use four evaluations of the base expression spaced in a tetrahedral pattern to approximate these derivative-based operations.

Below you will find descriptions of the various noise functions you will find in the Vector Noise Material Expression.

Item

Description



Properties



Function

Function

Description

Cellnoise

Random color for each integer grid cell in 3D space. About 10 instructions.

Perlin 3D Noise

Computational Perlin noise with 3D output, each channel output ranges from -1 to 1. About 83 instructions if only the red channel is used, 125 instructions if all three channels are used

Perlin Gradient

Computes the gradient of a Perlin noise function. RGB output contains the gradient vector, A is the scalar noise. About 106 instructions.

Perlin Curl

Computes a 3D curl noise. The output is the mathematical curl of Perlin 3D Noise. About 162 instructions.

Voronoi

The same algorithm and instruction counts as the Voronoi function in the Noise expression, but RGB is the location of the closest seed point in each Voronoi cell, and A is the distance to that seed point.

Quality

A look/performance setting. Lower values are faster but may look worse, higher values are slower but may look better.

Tiling

For noise functions that support it this allows noise to tile. This is more expensive, but useful when baking noise into a seamless wrapping texture.

Tile Size

When tiling, how often should the noise repeat. For Perlin noise variants, the Tile Size must be a multiple of three.



Inputs



Position

Allows the texture size to be adjusted via a 3D vector.

Cell Noise Material Example:



Click for full image.

Perlin Gradient Material Example:



Click for full image.

Voronoi Material Example:



Click for full image.

AppendVector

ComponentMask

DeriveNormalZ

Transform

TransformPosition

AppendVector

The AppendVector expression enables you to combine data channels together to create a vector with more channels than the original. For example, you can take two individual Constant values and append them to make a two-channel Constant2Vector value. AppendVector is also useful for reordering the channels within a single texture or for combining multiple grayscale textures into one RGB color texture.

Input

Description

A

Takes the value(s) to append additional data to.

B

Takes in the value(s) that will be appended to A.

Example

AppendVector works in order of input, meaning the data in input B is appended to the end of the data in input A. In the example below there are two separate append operations. First 0.2 and 0.4 are appended together, resulting in a two-channel vector (0.2, 0.4). In the second Append node, a constant value of 1 is appended to the end of (0.2, 0.4). The final result is a three-channel vector (0.2, 0.4, 1). In this example it is used as an RGB value to define the base color of the Material.



ComponentMask

The ComponentMask expression enables you to select a specific subset of channels (R, G, B, and/or A) from the input to pass through to the output. Attempting to pass a channel through that does not exist in the input will cause an error, unless the input is a single constant value. In that case, the single value is passed through to each channel. The current channels selected to be passed through are displayed in the title bar of the expression.

Select the ComponentMask expression in the Material Graph, and use the check-boxes in the Details Panel properties to choose which channels are allowed to pass through to the output.



Property

Description

R

If checked, the red (first) channel of the input value is passed through to the output.

G

If checked, the green (second) channel of the input value is passed through to the output.

B

If checked, the blue (third) channel of the input value is passed through to the output.

A

If checked, the alpha (fourth) channel of the input value is passed through to the output.

The example below shows a ComponentMask with an input of (0.2,0.4,1.0). Only the G channel is enabled in the details panel, so the node outputs a value of 0.4. This appears as a 40% bright grayscale value when passed into the Material's Base Color input.



CrossProduct

The CrossProduct expression computes the cross product of two three-channel vector value inputs and outputs the resulting three-channel vector value. Given two vectors in space, the cross product is a vector that is perpendicular to both of the inputs.

Input

Description

A

Takes in a three-channel vector value.

B

Takes in a three-channel vector value.

Example Usage: CrossProduct is often used to compute directions which are perpendicular to two other directions.



DeriveNormalZ

The DeriveNormalZ Expression derives the Z component of a tangent space normal given the X and Y components, and outputs the resulting three-channel tangent space normal. Z is calculated as Z = sqrt(1 - (x * x + y * y));

Input

Description

InXY

Takes in the X and Y components of the tangent space normal in the form of a two-channel vector value.



DotProduct

The DotProduct expression computes the dot product, which can be described as the length of one vector projected onto the other, or as the cosine between the two vectors multiplied by their magnitudes. This calculation is used by many techniques for computing falloff. DotProduct requires both vector inputs to have the same number of channels.

Input

Description

A

Takes in a value or vector of any length.

B

Takes in a value or vector of the same length as A.



Normalize

The Normalize expression calculates and outputs the normalized value of its input. Normalized vectors (also called "unit vectors") have an overall length of 1.0. This means each component of the input is divided by the total magnitude (length) of the vector.

Examples: Passing either (0,2,0) or (0,0.2,0) through Normalize will output (0,1,0). Passing (0,1,-1) through Normalize will output (0, 0.707, -0.707). The only special case is an all-zero vector, which will be unchanged.





It is not necessary to normalize an expression that plugs into the Normal material output.

Transform

The Transform Material Expression converts a three-channel vector value from one reference coordinate system to another.

By default, all shader calculations in a Material are done in tangent space. The vector constants, camera vector, light vector, and so on are all transformed to tangent space before being used in a Material. The Transform expression allows you to transform these vectors from tangent space to the world-space, local-space, or view-space coordinate systems. Additionally, it enables world-space and local-space vectors to be transformed to any of the other reference coordinate systems.

When the Transform node is selected in the Material Graph, the following properties display in the details panel.

Property

Description

Source

Specifies the current coordinate system to transform the vector from. This can be one of: World, Local, or Tangent.

Destination

Specifies the target coordinate system to transform the vector to. This can be one of: World, View, Local, or Tangent.

The Transform node accounts for mirrored UVs, thus allowing, for example, highlights that only affect the right edge of a character.

The Transform node is useful for generating world space normals for sampling a cubemap. A normal map can be transformed to world space. Below is an example of transforming normals from tangent space to world space in order to sample a cubemap.



Click image for full size.

Transforming normals to view space is useful for creating edge-on effects. This can be achieved by using mesh normals to generate texture coordinates (commonly referred to as "Sphere Mapping"). With this method, normals facing directly at the camera will map to the center of the texture coordinates, and normals facing perpendicular to the camera will map at the edge of the texture coordinates. For example, you could use the Transform expression to map a bullseye texture so that it always faces the camera.



A Constant3vector with a value of (0,0,1) is fed into the Transform node set to Tangent Space to View Space. This is then passed through a ComponentMask (passing only R and G). Since the Transform will output a range of values from -1 to 1, we bias the values to put them into the 0-1 range. This is done by multiplying by 0.5, and then adding 0.5. Then simply plug that into the Coordinates of the bullseye texture.



When orbiting around the static mesh, the bullseye always remains centered in view space. By changing the Destination property in the Transform node to World Space instead of View Space, you can project the texture along the Z-axis instead.

VertexColor is mutually exclusive with the Transform node due to limited interpolators. If you use both a Transform node and VertexColor, then VertexColor will come out all white.

The transform node currently does not handle non-uniform scaling correctly.

TransformPosition

The TransformPosition expression can transform any position from screen space to the destination space specified by the expression's TransformType variable. Currently only transforming into world space is supported. This expression can be used to get world space coordinates in the material. To visualize world position, you can plug it straight into emissive:

Starting Out

Essential Material Workflows

Doing More with Materials

Putting It All Together

The following step-by-step guides walk you through a wide range of topics designed to help you create and use Materials in your projects.

Starting Out

The tutorials in this section provide an introduction to the Unreal Engine Material Editor, covering the basic tools and processes needed to create Materials in Unreal.



Guide for placing Material Expressions and Functions inside the Material graph.



Guide for setting up and using the Main Material Node



A guide for previewing Materials and applying them to Actors.



How to use commenting, reroutes, and other strategies to organize Material Graphs and keep them easy to read and edit.

Essential Material Workflows

These pages continue to introduce foundational principles in Unreal Material creation. Material Instances provide a way to quickly and easily customize Materials, and the rest of the tutorials in this section provide information about how to create a few common Material types.



Guide for setting up and using Material Instances.



A guide to the process of creating and using Material Functions.



This page describes how to use Texture Masking in your Materials.



A tutorial for using the Emissive Material input inside the Material Editor.



This page explains how to use transparency in your Materials.



A guide for using Refraction in your Materials.



A guide for making shiny Materials

Doing More with Materials

The tutorials in this section move further into the principles of Material logic, introducing workflows and techniques to create more sophisticated and interesting Materials.



A guide for animating UV Coordinates in a Material



Guide for using the Bump Offset node in your Materials.



A guide for using dual Normal Maps in your Clear Coat Materials.



Guide for setting up and using Colored Translucent Shadows



A guide for using detail textures in Materials to improve appearance at close distances.



A guide to working with and using mesh decals in your projects.



An introductory document on the Layered Materials technique in Unreal Engine.



Description and technical details of the Subsurface Profile shading model available in Materials.



Guide for using the Subsurface Shading Model in your Materials.

Putting It All Together



This page explains how to use the Fresnel Material node.



This page describes how to set up Radial Motion Blur in a Material.



Guide for setting up Human Skin Materials.

Coordinates Material Expressions

Customized UVs

Light Functions

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

What is Animating UV Coordinates

Panner Node Breakdown

How to Animate UV Coordinates in your Material

Tips and Tricks

Conclusion

The ability to add motion to your Materials is a vital skill, as it provides a way to recreate effects such as fire, water, or smoke. A very cheap and effective way to do this is to use the Panner Material Expression node. The Panner node generates UV coordinates that change over time, moving textures in either the U or V direction, or in a combination of both.

What is Animating UV Coordinates

Animating UV coordinates or UV panning means to move a texture's UV coordinates either horizontally (in the U direction), or vertically (in the V direction), to give the illusion that complex animation is taking place. In the following example, the T_Fire_Tiled_D texture from the Starter Content is panning in the U direction (horizontally), making the fire look like it is moving.

Panner Node Breakdown

You can add a Panner Material Expression to the Material Graph by searching for Panner in the Palette or right-click context menu. You can also hold down the P key and left-click anywhere in the Material Graph to insert a Panner at the mouse pointer. The Panner Material Expression takes two inputs — Coordinates and Time.



Property

Description

Coordinate

Takes in base UV texture coordinates which the expression can then modify.

Time

Takes in a value used to determine the current panning position. This is usually a Time expression to provide a constant panning effect, but you can use a Constant or Scalar Parameter as well to set a specific offset or to control the panning through Blueprints.



Property

Description

Speed X

Speed to move the texture coordinates in the horizontal or X direction.

Speed Y

Speed to move the texture coordinates in the vertical or Y direction.

Const Coordinate

Only used if Coordinate is not hooked up.

Fractional Part

Output only the fractional part of the pan calculation for greater precision. Output is greater than or equal to 0 and less than 1.

How to Animate UV Coordinates in your Material

Use the following steps to create a Material that uses UV panning to animate a texture.

This tutorial uses a texture found in the Unreal Engine Starter Content. If you did not include the Starter Content in your project, look at the Migrating content page for information about how to move content between projects. This way you can add the Starter Content to your project and not have to make a new one.

First create a new Material. Right-click in the Content Browser and select Material in the Create Basic Asset section of the context menu.



Double-click the Material thumbnail in the Content Browser to open it in the Material Editor.



In the Starter Content folder, search for T_Fire. Left-click and drag the texture T_Fire_Tiled_D texture directly into your Material Graph from the Content Browser.



Add a Panner Material Expression to your graph. You can hold down the hotkey (P) and left-click in the Material Graph, or search for "panner" in the Palette. Your graph should look like this.



Connect the output of the Panner to the UVs input on the Texture Sample. Pass the RGB output of the texture into the Base Color input on the Main Material Node.



To make the texure pan, first select the Panner Material Expression and then in the Details panel, set the Speed X parameter to 0.1.



As soon as you change Speed X to 0.1, you should see the Fire Texture begin to move horizontally in the preview window.

Compile and Save the Material so you can apply it to objects in your level.



Tips and Tricks

Using panning in combination with other Material Expressions is a great way to add extra control to how the panning works. In the example below, three Scalar Parameters were added to the Material to control texture Tiling, Speed X, and Speed Y. Because they are parameters, artists can override their values in Material Instances to customize the apearance of the Material.



You can also stack Panner Material Expressions to make the illusion of movement even more complex. Layering numerous texures and panning them at different speeds, or blending them through masks can produce sophisticated results, useful for smoke, water, and visual effects.

In this example, a copy of the all the original Material Expression nodes was created by first selecting all the Material Expression nodes and pressing CTRL + D on the keyboard. The scale, panning direction, and speed of the newly created nodes was changed to give an impression of layered motion. The new cluster of nodes was passed into Emissive Color instead of Base Color to give the Material more of a fiery appearance.

Conclusion

Animating UV coordinates is a great way to introduce motion into your Materials. It is also extremely useful for visual effects that require complex motion like smoke or fire. However keep in mind that animating UV coordinates works best on objects that have contiguous UV setups. Any gaps or seams in a mesh's UV coordinates will show up when the UV coordinates are animated.

Utility Material Expressions

Bump Offset

Finding the Bump Offset Material Expression

Using the Bump Offset Material Expression

Conclusion

The Bump Offset Material Expression can improve the illusion of depth on a surface by modifying the UV coordinates of a Material. Bump Offset displaces texels on the surface of an object, creating an impression of parallax and giving an illusion that the surface has more details than it actually does. The Bump Offset expression is typically used alongside a normal map, and can improve upon the impression of depth provided by the normal map alone.

This tutorial demonstrates how to use the Bump Offset node in your Materials.

Bump Offset

Bump Offset is the Unreal Engine term for what is commonly known as parallax mapping. The Bump Offset expression is one way to improve the illusion of depth in a Material without adding additional polygons. Bump Offset Materials use a grayscale height map to provide depth information. The brightest values in the height map are displaced toward the camera, and receive the most parallax (shift) when the camera moves across the surface. Darker areas in the height map appear further away, and shift the least.

Finding the Bump Offset Material Expression

You can find the Bump Offset Material Expression by searching for it in the Palette search box, or by right-clicking in the Material Graph and selecting it in the context menu.



Bump Offset also has a Material Editor hotkey. Hold down the B key and left-click anywhere in the Material Graph to spawn a BumpOffset node.

When searching for the Bump Offset Material Expression, you will see another Material Expression called BumpOffset_Advanced. Bump Offset Advanced is a Material Function that was created to add some extra controls that are not available in the regular Bump Offset node. Although Bump Offset Advanced has additional inputs and outputs, they both use the same underlying principles to manipulate the UVs of a surface and create an illusion that the object has more detail than it actually does.

Using the Bump Offset Material Expression

Use the following steps to create a Material that uses Bump Offset.

This tutorial uses textures from the Unreal Engine Starter Content. If you did not include the Starter Content in your project, read the migrating content page for information about how to move assets between projects. This way you can import the Starter Content into your current project.

Right-click in the Content Browser and choose Material from the Create Basic Asset section in the context menu. Rename the Material something like 'BumpOffset'.



Double-click the Material asset in the Content Browser to open it in the Material Editor.



This example uses three texture samples to pass data into the Base Color, Roughness, and Normal inputs. In the Content Browser, navigate to Content > Starter Content > Textures and find the three textures listed below.

T_Brick_Clay_New_D

T_Brick_Clay_New_M

T_Brick_Clay_New_N

Drag all three textures from the Content Browser into your Material Graph to add them as Texture Samples. Your graph should look like the image below.



Connect the texture samples to the Main Material Node as shown in the image below.



Connect the RGB output of T_Brick_Clay_New_D to the Base Color input.

Connect the Red channel of the T_Brick_Clay_New_M texture to the Roughness input. Make sure in this case you use the R output pin and not the RGB.

Connect the RGB output of T_Brick_Clay_New_N to the Normal input.

Use one of the three methods above to add a Bump Offset Material Expression to your graph.



The Bump Offset expression will modify the UVs of the three Texture Samples already in your graph. Connect the output pin of the BumpOffset node to the UVs pin on the Texture Samples. Your graph should look like the one below.



When you first connect from the Bump Offset Material Expression to the UVs input on any of the three textures, an error message will appear along the bottom of the BumpOffset node. The Bump Offset Material Expression requires a height map to function correctly, and one has not yet been provided. After you connect a texture to the Height input, this error will disappear.

The Bump Offset Material Expression requires a black and white height map in its Height input. The T_Brick_Clay_New_D Texture Sample used for the Material's Base Color also has height information stored in its Alpha channel. Select the T_Brick_Clay_New_D texture sample and press Ctrl + D to duplicate the node. Move the node to the left side of the graph and then connect the A output to the Height input on the BumpOffset node.

It is necessary to modify the settings in the Bump Offset expression to prevent an effect known as "UV swimming" where the parallax effect is too strong, causing the textures to appear to slide across the surface of the mesh when the camera moves. Select the BumpOffset node in the graph, and in the Details Panel change the Height Ratio value from 0.05 to 0.005.



Once the Height Ratio is set, make sure to compile your Material by clicking Save or Apply in the toolbar. Once the Material is compiled and saved, you can apply it to objects in your level.



Move the slider back and forth to see the sphere with and without Bump Offset. Note how the illusion of depth on the bricks is enhanced when Bump Offset is used. This effect is even more apparent when the camera is in motion.

A brick Material before and after BumpOffset is added.



Conclusion

Using the Bump Offset Material Expression is a cheap and very effective way to add additional depth information to your Materials without adding extra 3D geometry. However keep in mind that the Bump Offset Material Expression does not actually modify the silhouette of a mesh or change the geometry. The illusion of depth is effective most of the time, but can break down in situations where the viewer can move their camera in such a way that it is parallel to the surface on which the Bump Offset Material is applied.

What the Second Normal Does

Required Files

Enabling the Clear Coat Second Normal Option

Using the Clear Coat Second Normal Option

When using the Clear Coat Shading Model, you can enable an option to use a second normal map for the surface beneath the clear coat layer. This option provides a more accurate model for complex Materials like carbon fiber, in which the underlying layer has different geometric surface properties than the clear coat layer. This tutorial covers how you can enable dual normals in the Clear Coat Shading Model and how to use this feature in your projects.

What the Second Normal Does

The comparison below shows what happens when a second normal map is added to a carbon fiber Material using the Clear Coat Shading Model.





In the image on the left, Clear Coat Bottom Normal is turned off. While the surface under the Clear Coat is interacting with the lighting, the light is only affecting the surface in one direction. This makes the surface appear flat and smooth, which is inaccurate for carbon fiber which should have an alternating woven pattern.

In the image on the right, Clear Coat Bottom Normal is enabled. You will notice that the light is now interacting with the carbon fiber weave, producing an alternating pattern of highlights and shadows with a sense of directionality.

Required Files

To follow this tutorial, you will need to download, extract, and then import the following texture files into your Unreal Engine project. If you are unfamilar with how to do this, read the Texture Import Guide for more information.

Required Textures Download (Right-click and save link as.)

Enabling the Clear Coat Second Normal Option

To use two sets of normals in the Clear Coat Shading Model, you will need to enable the feature in the Project Settings.

From the Main Toolbar go to Edit > Project Settings.



In the Project Settings window, go to Rendering > Materials and then check the box next to Clear Coat Enable Second Normal option to enable the feature.



You must restart the Editor to finish enabling the feature. Click Restart Now in the dialog when prompted.



Using the Clear Coat Second Normal Option

Use the following steps to create a Clear Coat Material that uses a second normal map for the underlying layer.

Right-click in the Content Browser and select Material in the Create Basic Asset section of the context menu.



Give the Material asset a descriptive name like like ClearCoat_DualNormals. Double-click the Material to open it in the Material Editor.



In the Material Editor, click anywhere in the Material Graph to display the Material Properties in the Details Panel. Change the Shading Model of the Material from Default Lit to Clear Coat.



Add four Scalar Parameter Expression nodes to the Material Graph. Give them the follwing names and Default Values, then connect them to the Main Material Node so they match the image below.

Material Expression Type

Name

Default Value

Scalar Parameter

Base Color

0.04

Scalar Parameter

Metallic

1.0

Scalar Parameter

Clear Coat

1.0

Scalar Parameter

Clear Coat Roughness

0.1225



To setup the Roughness section of the Material, add the following Material Expressions to the graph. Change the name and default value of each Scalar Parameter so they match the table below. After renaming the parameters, connect all the Material Expressions so your graph matches the image beneath the table.

Material Expression Type

Name

Default Value

Scalar Parameter

Roughness Scaling

30.0

Scalar Parameter

Roughness Min

0.1

Scalar Parameter

Roughness Max

1.349

Texture Sample

N/A

T_CarbonFiber_R_00

Texture Coordinate

N/A

N/A

Multiply

N/A

N/A

Linear Interpolate

N/A

N/A



Since this Material uses two normal maps, you will need to create two different Normal map sections in the Material Graph. The first section will define the normals of the Clear Coat surface and will require the following Material Expression nodes. Rename the Scalar Parameters and set their Default Values according to the table. Connect the Material Expressions so they match the image below.

Material Expression Type

Name

Default Value

Scalar Parameter

Clear Coat Normal Strength

0.98

Scalar Parameter

Clear Coat Normal Scaling

30.0

Texture Sample

N/A

T_CarPaint_N_00

Texture Coordinate

N/A

N/A

Multiply

N/A

N/A

FlattenNormal

N/A

N/A



The second normal map will define the carbon fiber surface that is beneath the clear coat. Add the Material Expressions listed below, and give them the following names and default values. Connect the Material Expression nodes so that they match the image below.

Material Expression Type

Name

Default Value

Scalar Parameter

Carbon Fiber Scaling

30.0

Scalar Parameter

Carbon Fiber Strength

0.5

Texture Sample

N/A

T_CarbonFiber_N_00

Texture Coordinate

N/A

N/A

Multiply

N/A

N/A

FlattenNormal

N/A

N/A

ClearCoatBottomNormal (ClearCoatNormalCustomOutput)

N/A

N/A



Make sure you have added the ClearCoatBottomNormal Material Expression node to the Material Graph and that you have connected the Normal map you want to use to its input. Failing to do this will result in you not being able to see the second Normal map in your Material.

With all the individual sections of the Material Graph now complete, connect the output of the Lerp in the Roughness section to the Roughness input on the Main Material Node. Connect the output of the FlattenNormal node to the Normal input on the Main Material Node. You do not need any additional connections for the carbon fiber normal map, because it is already connected to the ClearCoatBottomNormal custom output node. The final Material Graph is pictured below.



Click image for full size.

Click Apply and Save in the Material Editor toolbar to compile the Material and save the asset. The finished carbon fiber Material should look like the preview shown below.



Material Blend Modes

Lightmass Basics

Opacity Material Functions

Lit Translucency

Translucent Shadow Color

Compatibility with Various Lighting Systems

Disabling Lumen in UE5

Lighting Setup

Material Setup

Material Properties

Creating a Lit Translucent Material

Build Lighting

Shadow Sharpness

Material Variations

Opacity and Shadow Saturation

Masked Opacity

Colored Shadows with the Path Tracer

This tutorial explains how to configure an Unreal Engine Material to cast colored translucent shadows. There are many applications where this feature is useful, but a common example is the colored light transmitted through stained glass windows.



Translucent shadow color in Unreal Engine.

Translucent Shadow Color

Translucent Shadow Color is the term used to describe how shadows can be tinted by the color of translucent surfaces they travel through. This is also known as transmission. The amount of colored light that is transmitted through a Material is determined by its Opacity value between 0 and 1, and the intensity of the light cast onto the Material.

For example, if the Opacity value is set to 0, the Material is fully transparent and would not transmit any color or cast any shadows.

If the Opacity is set to 1, the Material is fully opaque and transmits no light at all.

When the Opacity value is something between 0 and 1, the light transmitted through that object is tinted by the Base Color of the Material, and the shadows inherit some of the color.

Compatibility with Various Lighting Systems

Translucent Shadow Color is not supported by every one of Unreal Engine's lighting and global illumination systems. The chart below breaks down which lighting features support translucent colored shadows.

Lighting System

Translucent Colored Shadows

CPU Lightmass

Yes, Static lights only

GPU Lightmass

Yes, Static lights only

Lumen Global Illumination

No

Hardware Ray Tracing

No

Path Tracer

Yes, requires Thin Translucent Shading Model

The notable omission on this list is Lumen Global Illumination, which does not currently support translucent shadow color.

Because Lumen Global Illumination is enabled by default in all new UE5 projects, this means you will need to manually disable Lumen in either the Project Settings or PostProcessVolume if you want to use colored translucent shadows in your Level.

The sections below explain how to setup a scene and Material to cast translucent colored shadows.

Disabling Lumen in UE5

Use the following steps to disable Lumen Global Illumination in the current Level.

Click the Create icon in the toolbar and select Volumes > PostProcessVolume.



Select the PostProcessVolume in the Level, and in the Details Panel search for "extent". Enable the Infinite Extent (Unbound) setting so the PostProcessVolume affects the whole Level.



Search for Global Illumination in the Details Panel. Enable the Method setting, and use the drop-down to change the Global Illumination Method from Lumen to None.



This setting disables dynamic Global Illumination in the current Level, however you can still use Lightmass to bake Global Illumination from Static lights.

Lighting Setup

The most important consideration with regard to lighting is that you can only cast colored translucent shadows from a Light Actor with its Mobility set to Static. You can use any of the following light types.

Directional Light

Point Light

Spot Light

Rect Light

All examples on this page use a Directional Light in the Unreal Engine Time of Day Level template. Select the Directional Light in the Outliner, and change the Mobility to Static in the Details Panel.



Indirect lighting can wash out colored shadows, making them appear less saturated than the Base Color of the Material. If you are having trouble seeing colored translucent shadows in your Level, consider reducing the Indirect Lighting Intensity of your light source, or try using a dimmer environment.

Material Setup

Material Properties

You can use any of the Blend Modes and Shading Models listed below to cast colored translucent shadows.

Blend Mode: Translucent, Additive, AlphaComposite, or Modulate

Shading Model: Default Lit, Unlit, or Thin Translucent

Using the Modulate Blend Mode will require you to disable Mobile Separate Translucency in the Details Panel properties.

Enabling the Two Sided property is optional, but it is necessary if you intend the player to view both sides of the mesh with the Material. If Two Sided is disabled, the light must be cast onto the visible side of the Material in order for it to cast colored shadows.

Creating a Lit Translucent Material

Create a new Material asset and open it in the Material Editor. Click anywhere in the Material Graph to display the Material Properties in the Details Panel.

In the Details Panel, change the Blend Mode to Translucent.



Enable the Two Sided Material property (optional).



Scroll down and expand the Translucency section. Set the Lighting Model to Surface Translucency Volume.



Add a Texture Sample to the Material Graph. This example uses a colorful geometric pattern to simulate a stained glass window, but any colorful texture will work. Images with highly saturated colors will produce more vibrant shadows than images with low saturation. Connect the RGB Output of the Texture Sample to the Base Color input on the Main Material Node.



Create a Scalar Parameter and rename it Opacity. Select the Scalar Parameter and set the Default Value to a value between 0 and 1 in the Details Panel. You can also set the Slider Max value to 1 to limit the value range of the Opacity slider.



Connect the Scalar Parameter to the Opacity input. Your Material Graph should look like the image below.



Click Apply and Save in the Toolbar to compile the Material and save the asset.



Build Lighting

Close the Material Editor and apply the Material to a Static Mesh in your Level. This example uses a simple plane from the Unreal Engine Starter Content. The Directional Light is angled roughly perpendicular to the plane so the shadow will fall directly onto the ground below.

In the Toolbar go to Build > Build Lighting Only to bake your lighting. Colored translucent shadows should appear when the Lightmass build finishes.



Shadow Sharpness

Several things can affect the sharpness of the shadows, including the lightmap resolution of the mesh receiving the transmitted shadow color, the source angle of the light, and the quality of the texture sample. If your result is blurry and unfocused like the image below, it is very likely the lightmap resolution is too low on the receiving mesh.



Select the Static Mesh upon which the shadows are falling—in this case the Floor asset. In the Details Panel, scroll down to the Lighting section. Enable the Overriden Light Map Res setting, and enter new Light Map resolution.



Depending on the size of the static mesh, you may need a relatively large resolution to see sharp shadows. The slider below shows what happens when the Light Map resolution is gradually increased.

Light Map resolution increased from 256 to 1024, 2048 and finally 3072.



In this case there is a drastic improvement from 256 up to 2048, but diminishing returns when the resolution is pushed to 3072. Larger Light Maps have a performance cost, so be careful not to use a higher resolution than is necessary.

Material Variations

Opacity and Shadow Saturation

The Opacity value of the Material will affect the saturation and intensity of the shadows. In the comparison below, the three slides show what happens when the Opacity value is increased from 0.2 to 0.9. In an outdoor environment like this, the colored shadows are easier to see with higher Opacity values. However, in a dim interior lower opacity values may yield better results.

Material Opacity at 0.2, 0.5, and 0.9.



Masked Opacity

Opacity masks work as expected when casting colored translucent shadows. You can use the alpha channel of a texture, or plug a black and white texture into the Opacity input to control which parts of the Material are visible and cast shadows. If you are unfamiliar with the process, read more about texture masking here.

The example below shows a masked Material casting colored translucent shadows. None of the Material properties were changed, but the Material graph was modified as shown below.



Instead of plugging the Opacity Scalar Parameter directly into the Main Material Node, it is multiplied by a black and white Texture Sample. The black regions of the mask are transparent, while the white circular region is visible.

This is the result after the lighting is rebuilt.



Colored Shadows with the Path Tracer

The Path Tracer is Beta feature and requires several settings to be enabled in Project Settings. Read about enabling the Path Tracer on this page.

Dynamic colored shadows are supported by the Path Tracer, but only when the Material uses the Thin Translucent Shading Model. Follow the steps below to modify the above Material so it can cast colored translucent shadows with the Path Tracer.

Click anywhere in the background of the Material Graph to display the Material Properties in the Details Panel.

Change the Shading Model to Thin Translucent.



Scroll down to the Translucency section and change the Lighting Mode to Surface Forward Shading.



Search for "thin translucent" in the right-click menu or Material Palette and add a ThinTranslucentMaterialOutput node to your graph.



Drag a second connection from the RGB output of the Texture Sample to the Transmittance Color input on the Thin Translucent Material node. The rest of the graph is unchanged from previous examples, and should look like the image below.



Compile the Material and apply it to a mesh in your Level.

The video below shows the results of the Thin Translucent stained glass Material when the Path Tracer is enabled. The colored shadows are fully dynamic in Path Tracing mode and update immediately if the plane or light source are rotated. The video also demonstrates what happens when changes are made to the Opacity of the Material and Source Angle of the Directional Light.

Guides

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Available guides and topics on using Decals in Unreal Engine.

Guides



A guide to working with and using mesh decals in your projects.

Mesh Decal versus Masked Material

Authoring Content

Notes

Limitations

Unreal Engine now has support for Mesh Decals, enabling you to use the properties of Deferred Decals on separate surface geometry for added detail to your Static and Skeletal Meshes. Because Deferred Decals rely on projection, you are limited to mostly planar surface details that shear and distort when not aligned with the surface it's projecting onto. Mesh Decals afford you decals that do not follow a simple projection and instead can be used with geometry that wraps around edges, being used with spline meshes, ultimately enhancing the look of your characters.

Mesh Decal versus Masked Material

Mesh Decals are a mix of translucent blend mode and deferred decals in that they do not render to depth but do update the GBuffer or DBuffer after the opaque geometry has been rendered. In contrast to using a masked Material, there is no cost for EarlyZ pass, you don't get shadows or proper occlusion, but with the trade-off, you get the soft transitions in the Material.

Mesh Decals provide several differences to Deferred Decal Actors that you should be aware of:

Since large Deferred Decals often do front and back facing draw calls, there are fewer draw calls.

Since there are fewer pixels covered and flat back facing decals cover 0 pixels, it's quite faster.

Since you can use a custom UV, You have the ability to do more complex projections.

You have the ability to have properly normal mapped decals wrapping around surfaces (or stretching along splines).





Authoring Content

Authoring content for use as Mesh Decal geometry is in line with any model creation. Since this geometry will not rely on projection (like a Deferred Decal Actor), the geometry needs only to stay in front of the surface you want to affect. With this in mind, the decal geometry should "hug" the underlying surface, but it does not have to match it very closely because there is already a small depth bias applied to account for this small offset. Also, using a bit of geometry that feathers out from the decal can be good to create the soft transitions for the decal, which is something you cannot attain with a masked Material.





Base Mesh and Decal Geometry (Isolated)

Composited Mesh

Another thing to keep in mind when developing your content, is that Mesh Decals can be a challenge with Levels of Detail (LOD), or long view distances when there is limited depth buffer precision, because geometry will intersect (or not match-up) as intended. However, you can either change the mesh to account for this (in most cases), or you can use World Position Offset in your Material to adjust the offset without having to return to your modeling application.







In this example, the decal geometry is close enough to the base mesh, such that the depth cannot account for the offset. Using a small negative offset value pushes the geometry out just enough so that it does not intersect with the underlying geometry.

Notes

DBuffer and non-DBuffer use the same container.

Sort by depth to avoid artifacts when there are many layers overlapping.

Parallel Rendering isn't yet hooked up. There are some CPU savings if this feature is used extensively.

Limitations

Material Editor Preview is not visible.

There is no artist specified sort order.

Tangent Space support is not yet implemented.

Shader Overdraw/Overdraw functionality is missing.

Since it assumes base pass usage, the Material Editor does not currently show the correct instructions count.

There is no easily adjustable DepthBias. Currently, you have to use an offset in the mesh from the surface it's above, or control with World Position Offset in the Material.

Coordinates Material Expressions

Customized UVs

Texturing Material Functions

Texture Material Expressions

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Detail Texturing

Detail Texturing Node Breakdown

Converting Texture Sample to Texture Objects

How to Use Detail Texturing in your Material

Using The Detail Texturing Material Function

Setting Up Detail Texturing Manually

Detail Texturing Tip & Tricks

Distance Based Detail Texturing

Conclusion

When viewing a Material very closely, you will notice that the textures used in the Material can break down and become pixelated. To optimize performance, textures are often scaled to a resolution that looks good from moderate distances, but may not hold up to close scrutiny.

To address this issue, you can use what is known as a detail texture to prevent a Material from looking pixelated when it is viewed very closely.

Detail Texturing

Detail texturing allows you to give the illusion of more detail in a texture by layering a highly repeated diffuse and normal texture over the object's original diffuse and normal textures. This gives the illusion of greater detail at close range than usually would be possible.

Here is an example of detail texturing in action.



On the left side (labeled 1), the Material uses a detail texture to add additional high-frequency details to the surface. On the right side (labeled 2) the Material does not use a detail texture. Note that the image on the left appears sharper and more detailed than the image on the right.

Detail Texturing Node Breakdown

If you search in the Palette or context menu for "detail texturing", you will find a Detail Texturing Material Function. While this is not the only way that you can apply detail textures to Materials, it is the fastest from a workflow perspective, since all the logic is contained within the Material Function. All you need to provide is texture inputs.



Property

Description

Scale (S)

This sets the scale of the detail texture. Bigger numbers result in more titling smaller numbers results in less titling.

Diffuse (V3)

This is the input for the Diffuse Texture.

DetailDiffuse (T2d)

This is the input for the Diffuse Detail Texture. This input can only accept a Texture Object.

DiffuseIntensity (S)

This controls the intensity of the Detail Diffuse Texture.

Normal (V3)

This is the input for the Normal Map Texture.

DetailNormal (T2D)

This is the input for the Normal Map Detail Texture. This input can only accept a Texture Object.

NormalIntensity (S)

This controls the intensity of the Detail Normal Map Texture.

Converting Texture Sample to Texture Objects

In order for the Detail Texturing Material Function to work correctly, you will need to convert the Textures you want to use as the Detail Textures from regular Texture Samples into Texture Objects. Use the following steps to do this.

Find the Texture Sample you want to use as a detail texture.



Right click on the Texture Sample node and select Convert To Texture Object from the context menu.



The Texture Sample is converted to a Texture Object.



How to Use Detail Texturing in your Material

There are two ways you can configure a Material to use Detail Texturing, and both of these are documented below. The main difference between the two methods is whether to use the premade Detail Texturing Material Function, or to create the detail texturing logic manually in the Material graph. Neither option is better or worse, as they produce the same results in the end. The method you choose to use depends on the needs of the specific Material and project.

All of the content used in the following sections is available in the Unreal Engine Starter Content. While the techniques that are shown here will work with any Textures, if you want to follow along, make sure your project includes the Starter Content.

Create a new Material to use for testing. Right-click in the Content Browser and choose Material from the Create Basic Asset section in the context menu. Give the Material a descriptive name like DetailTexturing.



Using The Detail Texturing Material Function

Open the Material by double-clicking the asset in the Content Browser. The Material Editor opens.

Find the following four textures in the Starter Content. Drag them from the Content Browser into your Material graph.

T_Brick_Clay_Old_D

T_Brick_Clay_Old_N

T_Ground_Gravel_D

T_Ground_Moss_N

When completed, your Material Graph should look like this:



Right-click in the Material graph and search for "Detail Texturing" in the context Menu. Click on DetailTexturing under the Misc category to add the Material Function to your graph.



A DetailTexturing Material Function is created in the Material Graph.



In this example the T_GroundGravel_D and T_Ground_Moss_N will be used as detail textures. In order to connect detail textures to the Material Function they must be converted to Texture Objects. Right-click on T_GroundGravel_D and T_Ground_Moss_N and convert them to Texture Objects.



Connect all the nodes as shown below. The two brick textures should connect to the Diffuse and Normal inputs, and the two Texture Objects should connect to the DetailDiffuse and DetailNormal pins. Pass the Diffuse output into Base Color and the Normal output into the Normal input on the Main Material Node.



Additonal values are needed to control the scale and intensity of the textures. You could use either a Constant Material Expression or Scalar Parameter for these inputs. This example uses three Scalar Parameters named Scale, Diffuse Intensity, and Normal Intensity. The default value in all three of these nodes is set to 1.



Connect the Scalar Parameters to their corresponding inputs. When completed, your Material Graph should look like this.



By adjusting the values in the Scalar Parameters, you can modify how the Detail Textures will look. Here is an example of what happens when you set the Scale to a value of 1, then 5, and finally 10. The detail texture tiles more times across the mesh, meaning the texture itself appears smaller or finer.



Setting Up Detail Texturing Manually

If for whatever reason you cannot use the Detail Texturing Material Function, you can build this functionality inside the Material Graph using Material Expression nodes and the directions below.

Duplicate the first Material in the Content Browser by right-clicking the thumbnail and choosing Duplicate from the context menu. Rename the new Material DetailTexturing_02 and double-click to open it in the Material Editor.



Delete everything except the four textures. You also need to convert the two Texture Objects back to Texture Samples. Right click each Texture Object node and choose Convert to Texture Sample from the context menu.



The following Material Expression nodes are needed to create detail texturing manually. You can find each of the following by searching for them in the Palette or using the search bar in the right-click context menu.

Texture Coordinate x 1

Clamp x 1

Scalar Parameter x 2

Add x 2

Multiply x 3

When completed, the Material Graph should look like this.



After you add all the nodes to your graph, begin connecting them as shown. The image below shows the correct configuration for the Base Color portion of the graph. When completed, the Material Graph should look like this.



Click image to enlarge.

The logic created in the Base Color section to control texture scale can be reused with the normal maps. Connect the nodes as shown below.



Click image to enlarge.

With the Base Color and Normal map now all connected together, the Material is now ready to be compiled, saved, and used.



Click image to enlarge.

Detail Texturing Tip & Tricks

The following section covers some tips and tricks on different ways you can use detail texturing in your Materials.

Distance Based Detail Texturing

When dealing with large surfaces, such as terrain, you may notice that even though your textures tile seamlessly there is noticeable repetition that weakens the appearance of the texture, especially when viewed in the distance.

To fix this, you can modify the Detail Material that was created previously to allow it to display one texture when the camera is close and another texture when the camera is far away. This is often referred to as distance-based texture blending. You can implement this by following the instructions below.

First duplicate the DetailTexturing_02 Material and rename it DistanceFade. Open the Material.

You can delete most of the node connections from the original Material, but do not delete the four textures. You should also keep the section labeled Scale Controls below. Search for and add the following Material Expressions to your graph.

World_Position x 1

Camera_Position_WS x 1

Distance x 1

Divide x 1

Power x 1

Clamp x 1

Constant x 2

When completed, the Material Graph should look like this.



Change the values in the two Constant Material expressions to 512 and 4, and then connect the nodes in the configuration shown below. The distance at which the texture blend occurs is controlled by the first Constant that is plugged into the Divide Material expression (set to 512 in the example image). The Material graph shown below provides all the logic needed to blend textures based on distance.



You can now connect the distance fade logic to the rest of the gaph. First add two Linear Interpolate (Lerp) nodes to the graph. The Alpha input on the Lerp nodes will drive the transition between the two textures. Finish wiring up the Material as shown below.



To preview the effect, hold down the Right Mouse Button in the Material preview viewport and move the mouse up and down to zoom in and out. When the camera is 512 units away from the sphere, the Material will transition from brick to gravel. If you can't see this happening, you can adjust the value in the Constant plugged into the Divide node. Reducing the value from 512 to something smaller will cause the transition to occur sooner.

Conclusion

Detail Texturing is a very powerful tool that can improve the appearance of Materials by supplementing the base textures with highly repeated detail textures. Keep in mind that Detail Texturing can only help to hide pixilation to a certain point, and allowing the player's camera to zoom into objects to an unreasonable degree can negate the benefits of detail texturing. Also remember that adding detail texturing could add two or more additional texture lookups to your Material, which may present performance or memory issues, especially on mobile platforms.

Material Inputs

Shading Models

Bloom

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Emissive Lighting

Lit and Unlit Emissive Materials

Creating a Fully Emissive Material

Creating a Masked Emissive Material

Creating a Test Map

Emissive Materials with Lumen

Emissive Materials with Static Lighting

Emissive and GPU Lightmass

Emissive Influence & Bloom

Multiple Bounces of Indirect Lighting

During the course of project development, the need might arise for a self-illuminated, or glowing Material. In Unreal Engine, self-illuminated Materials are known as emissive Materials. In the following tutorial, you will learn how to create Materials that use the Emissive Color input, and how you can create emissive Materials that actually cast light into the world you are creating.

Emissive Lighting

In Unreal Engine, emissive Materials give artists a very cheap and effective way to create the impression that a surface is glowing or casting light without using using any of Unreal's standard Light Types. Depending on your settings, Emissive Materials can act as a real light source that casts illumination into the environment around them, or they can self-illuminate without emitting light into the scene.

Emissive Materials are created by inputting values higher than 1.0 into the Emissive Color input on the Main Material Node. This pushes the Material into the HDR range, producing a bloom effect.

Lit and Unlit Emissive Materials

Emissive Materials are self-illuminating, which means you can use them with both the Lit and Unlit Shading Models. When you create a Material that is fully emissive, you can use the Unlit Shading Model, as it will result in a shader that is cheaper to render. You can use the Default Lit Shading Model in cases where you need some aspect of the Material to receive illumination from the scene.



When to use the Unlit Shading Model: You should use the Unlit Shading Model if your Emissive Material does not need to interact with the lighting in the Level. For example, if you are using the emissive Material strictly to simulate a light source, such as a light card or the surface area of a light bulb.

When to use the Default Lit Shading Model: You should use the Lit Shading Model if you need your Emissive Material to use any of the other shader inputs on the Main Material Node. For example, if you are using texture masks so that only part of the Material is emissive. If you were creating a Material for a gun that had lights on it, you would use the Default Lit Shading Model so the Normal Map, Base Color, and other shader inputs still work. You must use theDefault Lit Shading Model if you want your emissive Material to illuminate the objects around it.

Creating a Fully Emissive Material

This section demonstrates how to create a fully emissive Material, used strictly to simulate a light source. The Material will have two parameters to control the color and brightness of the light.

Right-click in the Content Browser and select Material in the Create Basic Asset section of the context menu. Rename the new Material EmissiveLightSource.



Add the following nodes to your Material Graph.

Vector Parameter

Scalar Parameter

Multiply

Rename the Vector Parameter Emissive Color, and rename the Scalar Parameter Emissive Strength. When finished your graph should look like the image below.



Connect the nodes as shown in the image below and connect the Multiply output to the Emissive Color input. Select each parameter and set a default value in the Details Panel. In the example below the Emissive Color set to red and the Emissive Strength is set to 6.



Click Save in the toolbar to compile the Material and save the asset. Close the Material Editor.



Right-click the EmissiveLightSource Material in the Content Browser and select Create Material Instance.



Double-click the EmissiveLightSource_Inst asset to open it in the Material Instance Editor. Enable both parameters by checking the box next to the parameter name. Once enabled, you can override the Emissive Color and Emissive Strength values in real time.

Creating a Masked Emissive Material

This example shows how to create a Material that uses a texture mask to define which parts of the Material are emissive. Since this Material is only partially emissive, it is necessary to use the Default Lit Shading Model.

This tutorial uses assets from the Unreal Engine Starter Content. The techniques shown here will work with any textures, but if you want to recreate the example make sure to include the Starter Content in your project. If you did not include the Starter Content when your project was created, read the Migrating Assets page to learn how to migrate the content into your current project.

Create a new Material and open it in the Material Editor. This Material should use the Default Lit Shading Model.



Add the following Material Expressions to your graph.

Vector Parameter x 2

Scalar Parameter x 2

Texture Sample - T_Tech_Panel_M

Texture Sample - T_Tech_Panel_N

Multiply x 4

Add x 1

The parameters will be used to control the emissive intensity and color, as in the previous example. Rename the Vector Parameters Emissive Color 1 and Emissive Color 2. Rename the Scalar Parameters Emissive Power 1 and Emissive Power 2. Change the default values to colors and powers of your choosing.



The T_Tech_Panel_M Texture contains four different image masks in each of its channels. This Material will use the Red and Blue channels to create two different emissive sections on the Material.



Connect the nodes as shown in the image below. This logic works because the texture masks contain pure black and white values. When the color parameters are multiplied against the values in the texture mask, any black pixel in the mask will output an emissive value of 0. Only the white parts of the mask are emissive, as shown in the preview below. You can independently change the color and intensity of each of the two emissive regions in a Material Instance.



Click the image to enlarge.

Click Save in the toolbar to compile the Material and save the asset. Close the Material Editor.



Right-click the EmissiveMaterialMasked asset in the Content Browser and select Create Material Instance.



Double-click the EmissiveMaterialMasked_Inst asset to open it in the Material Instance Editor. Check the box next to all four parameters to override them in the Material Instance. Once enabled, you can individually control the appearance of the two emissive regions, including turning them on or off by setting the Emissive Power parameters to 0.

Creating a Test Map

In the rest of the examples, the simple test map shown below is used to demonstrate how emissive light propagates through an Unreal environment.



Use the following steps to create a similar test map. All the assets in this scene are from the Unreal Starter Content.

Create a new level by going to File > New Level and select the Time of Day option in the New Level dialog.



You can also create a new level by pressing CRTL + N on the keyboard.

The demo scene was created with the assets listed below.

Wall_500x500 - Five instances arranged in the shape of a room, as shown below.

M_Brick_Clay_New - Material applied to all five wall instances.

Shape_sphere - Placed in the center of the test room.



When the room is completed, save your map by pressing CTRL + S on the keyboard.

Emissive Materials with Lumen

Whem Lumen Global Illumination is enabled, light from emissive Materials propagates through the scene automatically with no additional performance cost. This is a powerful and highly dynamic approach to lighting, however you should be cautious when using emissive light sources that are very small or very bright, as both can cause noise artifacts.

Lumen Global Illumination is enabled by default in newly-created Unreal Engine 5 projects. If you are converting an older UE4 project to UE5, you will need to manually enable Lumen. Read about enabling Lumen here.

The video below shows how emissive Materials cast illumination into in a scene with Lumen enabled. One thing to note is how the size of an emissive light source changes the apparent brightness and falloff distance of the illumination.

Emissive Materials with Static Lighting

Emissive Materials can cast light into the level when you are using Static Lighting, however this functionality is not enabled by default. If a CPU Lightmass build is created with no other lighting in the scene, the self-illuminated portions of the emissive Material are visible, but the Material does not illuminate any of the objects around it.



To make this Material cast light into the scene, you must enable a setting in the Details Panel. Select the Static Mesh on which the emissive Material is applied. In this case, the cube.

In the Details Panel search for "emissive", and under Lightmass Settings, check the box to enable Use Emissive for Static Lighting.



There is also an Emissive Boost setting. If you create a Lightmass build and the emissive light is too dim, you can input a value higher than 1 to boost the result. Another way to increase the brightness is to increase the Emissive Power parameter in the Material Instance.

The slider below shows how the static lighting changes when the Use Emissive for Static Lighting option is turned on, and then boosted to 2.

(1) Use Emissive for Static Lighting off, (2) Emissive for Static Lighting enabled, (3) Emissive Boost set to 2.



Emissive and GPU Lightmass

The Use Emissive for Static Lighting setting is not necessary when baking lighting with GPU Lightmass. Light from Emissive Materials automatically propagates into the GPU Lightmass result. If you need to increase or decrease the brightness of emissive lighting in a GPU Lightmass bake, you can modify the brightness values in the Material or Material Instance.

Emissive Influence & Bloom

As you increase the brightness of an emissive Material, the post-process Bloom effect that is generated from the emissive sections of the Material will get brighter and brighter. There are times when you may want to increase emissive values in the Material, but don't want the bloom effect to overwhelm the image.

You can control the Bloom effect indenpent of the emissive power in the Post Process Volume. This gives you a way to keep the Bloom effect at a reasonable level while you either increase or decrease the emissive brightness.



Adjusting this value will help to compensate when you push the Emissive values very high to get more static light from an Emissive Material cast in the world.

In the video below, one of the Emissive Power values is increased to 100, and the Bloom effect becomes quite overwhelming. To compensate you can select the Post Process volume, search for "bloom" and reduce the value to get a more visually appealing result. You can also change the Bloom setting to Convolution to mimic a camera starburst effect.

Multiple Bounces of Indirect Lighting

When Use Emissive for Static Lighting is enabled, you can use multiple bounces of indirect light to smooth out and improve the lighting. In the World Settings* panel, expand Lightmass Settings and increase the Num Sky Lighting Bounces nces** value.





Example scene with emissive static lighting providing multiple bounces of indirect lighting.

Vector Ops Material Functions

Material Editor UI

Utility Material Expressions

Fresnel

Fresnel Node Breakdowns

Fresnel Material Expression

Fresnel Material Function

How to Use Fresnel in your Material

Fresnel and Normal Maps

Input Blending

Often when creating a film or cinematic, you need a way to better highlight the silhouette of a character or set piece. This lighting technique is referred to as rim lighting, or edge lighting, and involves adding additional lights to help differentiate the character's silhouette from the background. While this works nicely for film, adding additional lights to any 3D scene adds extra complexity that can quickly become difficult to manage.

Unreal Engine offers a solution to this at the Material level. Using Fresnel, artists can simulate rim lighting in the Material of a character or prop, giving them more control over the look and feel of the effect. Fresnel is an inherent property of many naturally occuring Materials, including glass, water, and some types of fabric and paint. The techniques in this tutorial will help you simulate those Materials more accurately.

Fresnel

Fresnel is the term used to describe how the light you see reflects at different intensities based on the angle of view. For example, if you are standing over a pool looking straight down, you will not see a lot of reflections on the water. As you move your head so that the water in the pool becomes parallel to your eye level, you will begin to notice more and more reflections on the surface of the water. Water and glass both exhibit strong Fresnel tendencies, meaning they appear relatively transparent when viewed straight-on, and reflect more light at glancing angles.

Note how the glass in the picture frames is transparent when viewed straight on, and shows more reflections when viewed from the side.



In Unreal Engine, the Fresnel Material Expression calculates a falloff based on the dot product of the surface normal and the direction to the camera. When the surface normal points directly at the camera, a value of 0 is output meaning there should be no Fresnel effect happening. When the surface normal is perpendicular to the camera, a value of 1 is output meaning the full effect of the Fresnel should be taking place. The result is then clamped to [0, 1] so you do not have any negative color in the center. The following image demonstrates this concept.



In the middle of the sphere (labeled 0), there is no Fresnel effect. This is because the camera is pointing directly at the surface normal. Toward the edges of the sphere (labeled 1), the surface normals are increasingly perpendicular to the camera and the Fresnel effect becomes more and more visible. This creates an impression that the edges of the sphere are illuminated.

Fresnel Node Breakdowns

When searching for "Fresnel" in the Palette or contex menu, you will find there is a Fresnel Material Expression under Utility and a Material Function under Vector Ops. While these two nodes are used for the same purpose, they differ in how you set them up for use.



Fresnel Material Expression

The Fresnel Material Expression found under Utility is the one used in this tutorial, and is the simpler out of the two options to configure. It is highly recommended you use this version to begin with, and only use the Fresnel Material Function once you better understand how the node works.



Property

Description

ExponentIn

This input controls the falloff of the Fresnel Effect.

BaseReflectFractionIn

This specifies the fraction of specular reflection when the surface is viewed from straight on. Setting this to a value of 1 effectively disables Fresnel.

Normal

You can input a normal map to change the way the Fresnel effect is rendered. Normal maps must be Transformed from Tangent Space to World Space (see below).

There are three ways to adjust the values in the Fresnel Material Expression.

When the node is selected in the Material Graph you can enter values in the Details Panel.



You can also connect Constant or Scalar Parameters to the inputs.



You can attach a normal map to the Normal input to change the appearance of the fresnel effect. If you use a normal map texture, you must pass it through a TransformVector expression before connecting it to the Normal input. This will transform the normal map from Tangent Space to World Space. Without this Transform, the normal map may not influence the Fresnel the way you intend.



Click to enlarge image.

Fresnel Material Function

The Fresnel_Function Material Function in the Vector Ops category is a highly customizable version of Fresnel that provides control over several different aspects of the Fresnel effect. This added functionality has its drawbacks, as incorrect settings could lead to artifacts or errors in how the Fresnel effect is rendered.

You should only use this Material Function if the Fresnel Material Expression under Utility does not yield the results you are looking for.



Property

Description

Normal Vector (V3)

Here you can input a Normal to modify the way the Fresnel effect is rendered. You must pass a normal map through a Transform node (Tangent Space to World Space) for accurate results.

Camera Vector(V3)

Manually change the camera vector that is used to determine the Dot Product between the Camera and the surface normal.

Invert Fresnel(B)

Inverts the effect of the Fresnel. This is useful if you want the Fresnel to only be applied in the center or at the edges.

Power(S)

Input a Scalar to control the extent (or falloff) of the Fresnel effect. Entering larger numbers will tighten up the areas affected. Smaller numbers mean the Fresnel node affects a larger portion of the surface.

Use Cheap Contrast(B)

When enabled, the Fresnel node uses a cheaper method for calculating contrast between lights and darks.

Cheap Contrast Dark (S)

This controls how dark the Fresnel will be. This will only have an effect if Use Cheap Contrast is enabled.

Cheap Contrast Bright (S)

This controls how bright the Fresnel effect will be. This will only have an effect if Use Cheap Contrast is enabled.

Clamp Fresnel Dot Product (B)

Clamps the result of the Fresnel Dot Product between 0 and 1. This is true by default, but you can override it with a Static Bool set to false.

How to Use Fresnel in your Material

Use the following steps to create a Material that uses Fresnel.

Right-Click in the Content Browser and select Material from the Create Basic Asset section in the context menu. Once the Material is created, name it FresnelMaterial.



Open the new Material by double-clicking the thumbnail in the Content Browser.



Expand the Palette or right-click in the Material Graph to display the context menu. Search for the following Material Expression nodes and add them to your graph.

Node Name

Amount

Vector Parameter Node

2

Scalar Parameter Node

2

Fresnel Node

1

When completed, your Material Graph should look like this.



When you search for the Fresnel Material Expression, you will find two different Fresnel nodes to choose from. This tutorial uses the Fresnel Material Expression found in the Utility category.

Rename all the Scalar and Vector Parameter nodes, and set their default values in the Details Panel.

Name

Default Value

Fresnel Color

1.0, 0.0, 0.0, 0.0

Base Color

0.5, 0.5, 0.5, 0

Fresnel Falloff

8

Roughness

0.5



Add a Multiply node to the graph and then connect all the Material Expressions, using the image below as a guide.



Click image to enlarge.

Click Apply in the toolbar to compile the Material, and then click Save.



After you compile and save the Material, close the Material Editor and locate the FresnelMaterial asset in the Content Browser. Right-click the thumbnail and select Create Material Instance in the context menu.



Double-click the Instance to open it in the Material Instance Editor. Enable the parameters you want to override by checking the box next to each parameter name. Once the parameters are enabled, you can modify the values to change color and appearance of the Fresnel effect.

Remember that inputting larger numbers into Fresnel Falloff will push the Fresnel effect closer and closer to the edges, while lower numbers will bring the effect closer to the center. Here is an example of what happens when the Fresnel Falloff value is increased from 0 to 10. Notice how as the number increases, the blue color is pushed closer and closer to the edges of the sphere.



Fresnel and Normal Maps

Because Fresnel is calculated based on the surface normal of a face, you can use a normal map to influence the way the Fresnel effect is distributed across your Material. The Fresnel node works by checking whether or not the surface normal is perpendicular to the camera. If it is perpendicular to the camera, the Fresnel effect is visible. On a smooth sphere, this means the Fresnel effect only occurs at the edges.

However, when a Normal map is introduced, the surface normals are modified in such a way that there may be undulations and contours within the silhouette of a mesh. This means the Fresnel effect can highlight or emphasize details that would not be visible if the surface normals were smooth.

For a visual example of how this works, consider the two images below. The image on the left (1) shows what the Fresnel node will output with a flat surface normal. The Fresnel effect is only visible at the edges of the sphere. On the right (2), a normal map is input, which drastically changes the surface normals of the mesh. The Fresnel effect is now visible along the contours defined in the normal map.



The image below shows how different normal maps affect the Fresnel in different ways.



The Material used in the comparison above was the same Material that was created before but with the following modifications.

The Material's Blend Mode was changed from Opaque to Translucent.

In the Details Panel, the Translucency Lighting Mode was changed from Volumetric Non Directional to Surface Translucency Volume.

The Multiply output that was plugged into the Emissive Color input was also plugged into the Opacity input.

A new 2D Texture Sampler was added and plugged into the Normal input. Tech_Hex_Tile_N from the Starter Content was used as the Normal texture.

A new Scalar Parameter was added and multiplied by a Texture Coordinates expression to implement some basic uniform titling on the Normal map.



You can also pass a normal map into the Normal input on the Fresnel node. This is particularly useful if you want the normals of the Fresnel effect to be different from the normals of the underlying Material. For example, you could use the Fresnel node to display something like an energy shield on a Material, but still have that Material look normal when the shield is not active.

To achieve this using the Material above, make the following modifications to the Material.

Add the T_Brick_Clay_New_D texture from the Starter Content, and plug it into Base Color and Roughness.

Change the Normal input so that it uses T_Brick_Clay_New_N, which you can also find in the Starter Content.

Search for a Transform Material Expression node and add it to the Material graph. Make sure that it is set to transform from Tangent Space to World space.

Connect the old Normal map texture node into the input of the Transform node and connect its output into the Normal input on the Fresnel node.

When completed, your Material should look like the graph below.



Now the surface normals in the Fresnel node are completely different from the surface normals in the brick texture. The Fresnel effect looks like a translucent layer on top of the bricks. If you think the effect is too strong, you can go one step further by adding a Multiply node and Scalar Parameter to control the intensity of Fresnel effect. Here is how you can implement an intensity control in the Material.



By adjusting the Fresnel Intensity parameter, you can control the intensity of the Fresnel effect on the surface. Setting the value to 0 turns off the effect, and setting it to anything else will gradually increase the visibility of the Fresnel effect like below.



Input Blending

The Fresnel node is a versatile utility for alpha blending between two different inputs in a Lerp node.

In the image below the Fresnel node in the Alpha input controls the transition between the red and green colors in Input A and B on the Lerp.



By that same logic you could use Fresnel to control the placement of different Roughness values on your mesh. In the image below the Fresnel is used to transition between Roughness values of 0.1 at the edges and 0.9 toward the center of the sphere. This creates an illusion that the sphere is more reflective near the edges, similar to the way glass behaves.



Content Examples

Materials

Using Subsurface Scattering

Subsurface Profile Shading Model

Subsurface Shading Model

Setup

Material

Base Color

Roughness

Specular

Normal

Opacity

Pores

Using a Subsurface Profile

Useful links

Conclusion





Getting Human skin to look correct when rendered is a very complex topic with no single perfect solution for getting correct results. Because of this, please treat the following information as a starting point for your work as many things are needed in order to achieve a realistic looking image. This is because our eyes are very well trained at detecting subtle details in human faces. Getting it right is challenging but once the tools are mastered, they can be applied in many other cases.

Setup

Before we get to making the Material, first we should gather some reference. This is because it is usually best to start with multiple photo references that have multiple lighting situations so you can verify how the material looks under different lighting conditions. If at all possible, having scanned and calibrated source data would be ideal as this will help to make sure that you are getting the best possible results. When viewing your content inside the editor, make sure to disable the Editor Eye Adaptation for a more controlled environment: Edit Menu > Project Settings > Rendering > Default Post Processing Settings > Auto Exposure

A calibrated environment can be helpful in making sure that you get the colors correct but it is not required.

For the following example, we will be working with the Skin Rendering Content example. If have not done so, please go ahead and download the Content Examples from the Marketplace now and open up the Skin Rendering Map. Also please keep in mind that the images in this document are explicitly low resolution and are not meant to be used as source work.

It is extremely important that you make sure the Normal Map is correctly setup for use inside Unreal Engine. Some engines use a Normal Map where the green channel has been inverted. You can check to see if the green channel of your Normal Map has been inverted or not by comparing the colors in the following image to your Normal.



Here is a list of some things that you need to be aware of before you begin to create your Skin Textures and Materials.

Remember that when creating textures, it would be ideal if you start with very high resolution textures (e.g. 2Kx2K or higher) as this will give the best results.

For faster iteration, it is best to create a Material Instance and expose Scalar and Vector Parameters for faster and easier tweaking as the Material does not need to be recompiled during tweaking.

Keep in mind that assets should be verified in multiple lighting conditions to ensure that they are correct. Even having Eye Adaptation enabled in the Post Process Volume can make a huge difference in how things look in the end.

To avoid shadow artifacts will require extra effort because you will need to tweak things like shadow bias or use a more focused spot light cone for better lighting resolution.

When tweaking, it might be useful to zoom in by adjusting the editor FOV as there will be no clipping through geometry and less distortions.

The editor Field Of View(FOV) can be adjusted by clicking on the Drop Down Arrow that is next to the icon that says Perspective and then adjusting the FOC value using the mouse.



When viewing your work, you might notice that the streaming system does not take the zoom into account and could blur your texture when you do not want to. This was an intentional design decision made for 3D games but this could change at some point in the future. To prevent this from happening, you can change the texture Streaming Distance Multiplier on the mesh instance.

Material

Below is an image of the completed Material from the Content Example map. While this Material does look complex, we will be breaking down what each section of the Material does in the following sections.



Click image for full size.

Base Color



One of the first things that needs to be understood is that from a very far distance, the Subsurface Scattering effect is harder to perceive. This means that it is best to have the Base Color of your texture looking right when viewed in the distance. You could also use a grayscale texture to darken the base color and the specular (caused by occlusion) to give an overall better look to the skin. You can also add some Vector and Scalar controls to adjust the color and power of the skin to help you further tweak to get the look you are after.

Roughness



For skin, it is best to start with a constant Roughness value of around 0.4 and tweak from there. Keep in mind that the actual value depends on scale/distance, age, and wet/dryness of the skin that you are trying to simulate.

Unlike other textures, we explicitly want to have the mip maps look different. This is how such a mip chain can look like:



Notice that the smaller mips have a brighter grey value meaning the material transitions towards a more rougher material. Also keep in mind that this texture can be put into a channel of another texture (saving a texture lookup and texture memory). Ideally this texture should have the same resolution as the Normal Map texture.

Specular



The Specular value for the skin is set at a value 0.35. The number 0.35 was used as it was derived from real world Specular values that were measured and then converted into ranges that we use.

Normal



Click image for full size.

In order for your Normal Map to work correctly for skin, you need to make sure that your Normal map meets the following criteria.

The Normal Map that is used for the face should only contain details about wrinkles. Pore details should be done with a tiling texture as you can get better results this way.

When combining the object's Normal map with the Detail Normal map, make sure that you use the Material Function BlendAngleCorrectedNormals to combine as you will yield better results. It is also very useful to expose parameters to adjust the mixing of the Normal maps. You can take the detail normal map value, add some scalar value to the z component and normalize. This way you can transition to a flat detail Normal Map from your regular one.

As skin has different shading properties in different areas, it is best to combine the Roughness with an object mapped (non-tiled) texture. As the detail Normal map causes the roughness to go up in the distance, we need to compensate for that. We also need to verify the shading at multiple scales / view distances to ensure that it looks good at all distances from the camera.

Modern real-time rendering implements shading with per pixel lighting. Normally this leads to very high quality results but for very detailed Normal maps. By using Mip Maps, we avoid shimmering and get a better performance but Mip Mapping does not work well for Normal maps as details in lower mips simply do not exist and the surface appears much more shiny than it should be. To counter that effect, we can adjust the roughness accordingly. This does not capture anisotropic details but for non-directional features, it is a good approximation.

Opacity



The Opacity input controls that amount of Subsurface Scattering that is taking place. A value of 1 or pure white means that the Subsurface Scattering should come through at full power. A value of 0 or pure black means no Subsurface Scattering should come through.

Pores



Click image for full size.

Having the Pores in the skin is a very important detail in getting realistic looking skin. However because the pore detail needs to be very fine, it is very difficult to get the needed quality by just adding the Pores to the base Normal Map.

Adding the Pores as separate tillable textures makes them stand out better but also makes adjusting them is much easier.

For the Pore tiling detail variation in this shader, a TexCoord Material Expression was multiplied with a Scalar Parameter so that inside of the Material Instance we would be able to title the Pores as needed.

Here is a look at what the Pore Mask and Normal Texture Maps look like when viewed close up.



Because pores are little sunken in to the surface areas when viewed from a grazing angle they are actually less visible. We can mimic that fading out the pore contribution based on the angle the surface is viewed. This computation is similar to Fresnel and was implemented like this in the SkinMaster Material.



The Material graph components for the skin pores and fresnel effect are blended back into the broader graph using the logic shown below.



Click image for full size.

Using a Subsurface Profile

The Subsurface Profile is what makes the skin really look like skin. To use a Subsurface Profile in your Material, you just need to supply your Material or Material Instance with the Subsurface Profile that you want to use.

To change this in a Material, all you need to do is supply the Subsurface Profile that you wish to use in the Details panel of Material Editor.



To change what Subsurface Profile is used inside of a Material Instance all you need to do is first check the Override Subsurface Profile and then supply the Subsurface Profile that you want to use in the Subsurface Profile section of the Material Instance.



Click image for full size.

Useful links

The following links are to external sites that contain a wealth of information on how to create very realistic looking character for games.

Next Generation Character Rendering

Conclusion

Setting up and getting skin to render correctly is a long and involved process that will take some time to get just right. Remember that this guide should only be used to help point you in the right direction when it comes to setting up skin. If you find that by using a slightly different setup than what was presented here gives you the results you are looking for that is okay. Again the above information is not something that you have to follow to the letter when setting up skin but should be considered more like guidelines to follow.

Textures

Texture Format Support and Settings



Texture Material Expressions

Using the Emissive Material Input

Instanced Materials

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Texture Masks

Creating a Texture Mask

Exporting a Texture Mask

Using Texture Masks

Emissive Mask

Material Masking

Masking Tips & Tricks

Texture Masking and Material separate

Masking and Channel Artifacts

sRGB and Mask Textures

Conclusion

When creating 3D assets, you might find that you need the ability to define different surface types within the same Material. A simple and cheap way to achieve this is to use a Texture Mask that defines which parts of a surface should be affected by which section of the Material.

This tutorial covers how you can use texture masking inside your Unreal Engine Materials.

Texture Masks

A Texture Mask is a grayscale texture, or a single channel (R, G, B, or A) of a texture, used to limit the area of an effect inside a Material.

Masks are frequently contained within a single channel of another texture, such as the Alpha Channel of the Diffuse or Normal map. In other cases, a single image file often contains the Roughness, Metallic, and Ambient Occlusion masks, each one occupying a single channel.

This is called channel packing, and is a good way to improve Material performance by reducing the number of texture samples required by the Material. Technically, any channel of any texture can be thought of and used as a texture mask.

Here is an example of what the Texture Mask for the SM_Chair Static Mesh from the Starter Content looks like.



In fact, this image file contains a different black and white mask in each of the four color channels (RGBA).



Creating a Texture Mask

You can create a texture mask in any 2D image manipulation program. You can also bake masks directly from geometry in your primary content creation program, or with a dedicated texturing tool like Marmoset Toolbag, Xnormal, or Substance Painter/Designer.

When creating masks by hand, you will generally start with an image that shows the UV layout of your mesh. In this example, the intent is to mask the seat cushions. The coresponding UVs are highlighted in the image below. To mask a specific part of the model, you need to paint that region of the image pure white, while leaving all the other areas black.



As shown above, this allows you to apply specific surface properties to the masked region. In this case, the mask is used to give the cushions an orange color.



When creating a Texture Mask you should always use either pure black or white and never color information. Using any other type of color could result in strange artifacts when using the mask inside Unreal.

Exporting a Texture Mask

When you are done painting your mask texture, you can either export it as a single image or you can pack multiple masks together into the R, G, B, and A channels of a single image and export that. This is commonly referred to as RGB channel packing and is the preferred method when creating masks, as it offers considerable performance and memory savings with very little extra work.

If do you pack something into the alpha channel of a texture, make sure that you remember to enable alpha exporting in whatever 2D image manipulation software you use. If not, you run the risk of the alpha channel not being exported with the texture.

Using Texture Masks

You can use mask textures a number of different ways inside the Unreal Material Editor. Common uses include defining an emissive light source, defining which parts of a mesh are metal and non-metal, or mapping different colors to different portions of a model as shown in the chair example.

The following section demonstrages soem of the most common ways to use texture masking in Unreal Engine.

Emissive Mask

One of the most common uses for a mask texture, is to control the emissive sections of a Material. This is usually done by first creating an emissive mask texture, which uses pure white to define the sections of the Materail that should emit light. Two parameters usually accompany an emissive mask:

To change the color of the light emission, you can multiply the emissive mask by a color defined by a Vector Parameter.

To change the intensity of the emissive light, you can multiply it by a Scalar Parameter. Increase the value in the Scalar parameter to increase the brighness of the emission.

The four nodes highlighted in the graph below show an emissive mask multiplied by parameters that control the color and brighness of the light. The sphere only emits light in regions that correspond to the white parts of the emissive mask. The rest of the sphere displays the base color texture.



Material Masking

A second common use for texture masks is to store different kinds of texture information within the individual R, G, B, and Alpha channels of the. The Material on the SM_Chair Static Mesh that comes with the Starter Content is a perfect example of this technique.

You can find SM_Chair and all the content that goes with it by first selecting the Starter Content folder in the Content Browser and then entering "chair" into the search box. This will display all the content that is related to the chair. If you do not see the chair, it probably means that you did not include the Starter Content with your project. To fix this, you will need to either create a new project or try the Migrating Assets Tool to move the chair content from another project into this one.

Opening up the chair Material, M_Chair, we can see a perfect example of Texture Mapping in action.



In this Material, the mask texture, T_Chair_M is used to map specific surface properties to different regions on the mesh. The texture mask helps define which sections are metal or non-metal, and is also used to assign different roughness and color values to different parts of the chair.

In the following image, you can see a breakdown of how each channel in the mask texture is used. On the left side is the composite RGB image, or what the image looks like if you view it as a texture. The middle column shows the black and white masks contained in each color channel (R, G, B, A from top to bottom.) The images on the far right show which part of the chair the mask targets; the white parts of the chair correspond to the white secion in the mask.



Here is a breakdown of what type of information is stored inside each channel of the chair mask texture.

Red Channel: Ambient Occlusion information. In the Material, this is used to help add subtle contact shadows where two surfaces are close together.

Green Channel: Metallic Mask. In the Material, this is used to define which parts are supposed to be metal. This is also used to help define what color the metal should be. !

Blue Channel: Non-Metallic Mask. In the Material, this is used to define which parts are non-metal. This mask also helps to define the color of the non-metal parts.

Alpha Channel: Whole object Mask. This is not currently used by the Material.

All put together, the chair looks like this in an Unreal level:



Masking Tips & Tricks

Texture masking is a very powerful tool, especially when combined with other tools in Unreal Engine. The following section presents some tips and tricks for making the most of texture masking in your work.

Texture Masking and Material separate

Using texture masking and Material Instances together is a great way to add an almost endless amount of variety to any assets. For example, you can use a texture mask to define which areas should have certain properties, like color, and then use different Material Instances to customize these properties in the Instance Editor. Read more about Material Instancing here.



When Material masks are used along with Material Instancing, you can allow artists to quickly and easily change color and other values within the Material. This approach produces highly customizable assets, as seen with the SM_Chair in the image above.

Masking and Channel Artifacts

Because of a quirk with DirectX, the green channel of a texture will often offer the best compression. If any of your masks suffer greatly from compression artifacts, first try placing the information into the green channel of the image to see if that helps. If that does not fix the issue, then try using the Alpha channel to store the mask.

Be careful when trying to use the Alpha channel of a texture to store Mask information. Adding an Alpha channel to a texture will greatly increase the memory footprint of that texture and if you do this enough, you could lose all the saving you gained by packing different masks in to the RGB channels of the texture.

sRGB and Mask Textures

When packing multiple Mask Textures into a single texture, you should uncheck sRGB in the Texture Editor, as masks should not be gamma corrected.



If you disable sRGB for a texture that was previously sampled in a Material, the sample type is not automatically updated in existing 2D Texture Sampler nodes. You need to make sure that you adjust the node type in any existing 2D Texture Sampler Nodes. If you do not change the Sampler Type, your Material will fail to compile and the following message is displayed in the Stats log.



To fix this error, all you need to do is to change the Sampler Type from the default of Color to Linear Color and the warning will go away. For good measure, you should re-compile the Material to make sure that the changes were successful. Once completed, the warning will go away.

Conclusion

Texture Masking is a very powerful concept that once mastered allows you to create an almost endless amount of variation with very little source content. Remember that you only have four available channels in any image file to use for texture masks, so use each channel wisely. Do not forget to disable sRGB on your mask textures, as it can greatly help to increase the mask's sharpness.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Content Browser Interface

Migrating Assets

Previewing and Applying your Materials

Instanced Materials

Material Instance Editor UI

Required Setup

Steps

Result



The standard Motion Blur that Unreal Engine supports assumes that a point on an object's surface moves in a straight line from frame to frame, and then uses information from where that point was located during the previous frame to apply the blur effect.

This works well for an object moving from one position to another. However, this method produces visual errors when applied to an object that is rotating 180 degrees within a single frame, like a very quickly rotating wheel on a car. In this instance, the Motion Blur looks at a point on one side of the wheel, then assumes it traveled to the opposite side of the wheel in a straight line rather than moving around the circumference.

To help address this issue, a special Radial Motion Blur Material was developed and released in the free Unreal Engine Content Examples project. You can use this Material to make an object look as if it were rotating quickly by applying a radial instead of linear motion blur. In the example image below you can see the results of using standard Motion Blur on a rotating object (left) compared with the results of using the Radial Motion Blur Material (right).



This tutorial will walk you through the process of setting up the Radial Motion Blur Material in your own projects.

Required Setup

This tutorial requires assets found in the Content Examples sample project. If you do not already have this sample project, download and install it from the Learn tab in the Epic Games Launcher.



Click for full image.

In the Content Examples Project, you can find a working example of Radial Motion Blur in the Materials_Advanced map.

Due to its complexity, it is beyond the scope of this tutorial to rebuild the base M_RadialMotionBlur Material from scratch. However, if you would like to examine the base Material Graph, you can find the Material asset in the Content Browser under Content > Example Content > Materials > Materials.



For the purpose of this tutorial we will rebuild the Radial Motion Blur example using the following assets in the Content Browser.

SM_Wheel - Static Mesh

SM_Wheel_Blur - Static Mesh

MI_RadialMotionBlur - Material Instance

To use the Radial Motion Blur Material in your own project, you can right-click the MI_RadialMotionBlur Material Instance in the Content Browser, and select Asset Actions > Migrate in the context menu.



The Migrate Assets tool will automatically include both MI_RadialMotionBlur and the base RadialMotionBlur Material in the migration. For more information on this topic, see the guide on Migrating Assets.

Steps

Make sure the Unreal Editor is closed. Inside your project folder, navigate to the Config folder and locate DefaultEngine.ini.



Click image to enlarge.

Open DefaultEngine.ini with a text editor, and in the [/Script/Engine.RendererSettings] section add r.CustomDepth=3.



Radial Motion Blur requires two Static Meshes: The mesh that you want to apply the Radial Motion Blur to, and a "dummy" mesh that will cover it. The dummy Mesh needs to not only cover the object that will be blurred, it also needs to completely cover the space that it will sweep through while rotating, and it should wrap around that swept space as tightly as possible without intersecting with the original object's geometry.



Click image to enlarge.

In the example image above, the Mesh that we want to apply the blur to has its standard Material applied, while the "dummy" mesh is a hull wrapped around it, visualized with a yellow wireframe. Note that it fits closely over the Static Mesh but does not penetrate through it. You may decide to use your own Meshes, but for the purposes of this guide we will be using the assets SM_Wheel and SM_Wheel_Blur, which you can find in the Content Examples project under Content > ExampleContent > Materials > Meshes.



Create a new StaticMeshActor by dragging SM_Wheel into the scene.



Click image to enlarge.

In the Details Panel for this StaticMeshActor, click the Create Blueprint from Selection button to create a new Blueprint based on this Actor. Name the Blueprint BP_StaticMesh_MotionBlur and save it to your Blueprints folder. The Static Mes is converted to a Blueprint Actor type and the Blueprint Editor will automatically open.



Click image to enlarge.

In the Blueprint Editor, locate the Components Panel and select the StaticMeshComponent for your Mesh. Then, in the Details Panel, expand the Advanced section under Rendering. Set Render Custom Depth Pass to True, then set Custom Depth Stencil Value to 5.



Click for full image.

In the Components Panel, click the Add Component button. Select Static Mesh in the drop-down list to add a new StaticMeshComponent as a child of the base Mesh. Re-name this Mesh "MotionBlur Mesh".



In the Details Panel, set the Static Mesh for your MotionBlur Mesh to SM_Wheel_Blur. Rotate it 90° on the x-axis so that it fits over the base Mesh. In the Materials section, ensure that it has the MI_RadialMotionBlur Material Instance applied.



Click for full image.

Result

With the MI_RadialMotionBlur Material Instance applied, your base Mesh should now appear as if it is rotating very quickly. The image below demonstrates a normal, stationary Static Mesh (left), versus a Mesh with the RadialMotionBlur applied to a dummy Mesh surrounding the base Mesh (right).



Note that you do not need to rotate your base Mesh or Actor in order to achieve this effect. Instead, the RadialMotionBlur Material itself creates the illusion that the object is rotating. You can adjust the effect using the Angle and RimRadius parameters that are found in the MI_RadialMotionBlur Material Instance.



The following two image sequences show how the visuals of the Radial Blur are affected when you adjust the Angle and RimRadius Material inputs.

This Angle parameter is used to control the intensity of the Radial Blur. The higher it is, the faster the object will look like it is rotating.



The RimRadius parameter is used to limit what will be blurred by the Radial Blur. You should set the RimRadius to match the radius of the mesh that is used for the Radial Blur.



You can reuse this new Actor type that you've created to make all kinds of objects that use the Radial Motion Blur effect. Change the Static Mesh used for both the base Mesh and the dummy Mesh, and ensure that the dummy Mesh uses a Material Instance of the RadialMotionBlur Material. Remember that the dummy mesh should fit as closely as possible to the area that would be swept by the base mesh when it rotates.



Finally, if you want different objects to have different settings, create new Material Instances based on the RadialMotionBlur Material and give them the desired settings accordingly. For more information about how to create Material Instances, see the guide on Creating and Using Material Instances.

Content Examples

Material Inputs

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Refraction

Index of Refraction or IOR

Using Refraction in Materials

Refraction Tips & Tricks

Refraction & Normal Maps

Refraction and Movement

Refraction Depth Bias

Conclusion

When light passes from one medium to another, say from air to water, the direction that that light is traveling is altered where the two mediums meet. This lighting phenomenon is referred to as refraction and happens because the speed of a light wave can change when the light passes into a different type of Material. In Unreal Engine you can simulate this lighting phenomena in your Materials by using the Refraction input on the Main Material Node.

Refraction

Refraction is the term used to describe the change in direction of a light wave due to a change in its transmission medium. In other words, when light comes in contact with certain surfaces, like water or glass, the light is bent or redirected because those surfaces affect the speed at which light travels through them.

You can see a classic example of refraction by dipping a pencil into a bowl of water. The pencil will appear to bend or change directions at the spot where the pencil intersects the water. The illustration below shows how refraction works.



X shows the true physical position of the pencil when it is dipped in water. The light rays from the submerged portion of the pencil are refracted at the air-water interface, changing speed and direction. From the camera's perspective, the pencil appears to bend at the surface of the water, with the tip appearing at position Y instead of its true position X.

Index of Refraction or IOR

Index of Refraction or IOR is an optical measurement that describes the extent to which light is bent, or refracted, when it enters a particular Material. Index of refraction can be measured, and real-world values for common surfaces are well known. When creating refractive Materials in Unreal Enging, it is best to use real-world IOR values to give your Materials a better sense of realism. The table below lists measured IOR values for some common surface types.

Material

IOR Value

Air

1.00

Water

1.33

Ice

1.31

Plexiglass

1.49

Glass

1.52

Diamond

2.42

Using Refraction in Materials

Follow the instructions below to create a Material that uses refraction.

This tutorial uses assets from the Unreal Engine Starter Content. If you did not include the Starter Content in your project, read the Migrating Assets page to learn how to migrate the Starter Content into your current project.

Right-click in the Content Browser and select Material from the Create Basic Asset section in the context menu. Rename the Material RefractionMaterial.



Double-click the Material asset to open it in the Material Editor.



In the Details Panel, change the Blend Mode from Opaque to Translucent. Expand the Translucency section and change the Lighting Model from Volumetric Non Directional to Surface Translucency Volume. Changing these settings will enable the Refraction pin on the Main Material Node. When completed, your Details panel properties should look like this.



Search for the following Material Expression nodes and add them to your graph in the quantites listed below. Your Material Graph should look like the image below.

Constant x 3

Scalar Parameter x 2

Lerp x 1

Fresnel x 1



Begin wiring up the Material as shown below. Change the Constant value flowing into Base Color and Metallic to 1. Rename one of the Scalar Parameters Opacity, give it a default value of 0.3 and connect it to the Opacity input.



Rename the second Scalar Parameter IOR and change its default value to 1.52 (the IOR of glass). Finish wiring up the Material as shown in the outlined portion of the image.



Because glass does not refract light the same way from all viewing angles, a Fresnel Material Expression is used to blend between the two values in the Lerp node. Glass does not refract as much light when viewed straight-on, but produces noticeable refraction at glancing angles. The Fresnel node reproduces this effect — the Constant value in input A is mapped to the center of the Material, and the IOR parameter in input B is mapped to the edges where the sphere curves away from the camera.

Read the page on Using Fresnel in Materials for a better understanding of how the Fresnel Material Expression works.

Click Apply and Save in the Toolbar to compile the Material and save the asset. After the Material is saved you can close the Material Editor.



Find the RefractionMaterial asset in the Content Browser, right-click on the thumbnail and select Create Material Instance from the context menu.



Drop a few objects into your scene to test the Material. The example below uses assets from the Shapes folder in the Starter Content, but any object is suitable. Drag the RefractiveMaterial_Inst asset from the Content Browser onto the meshes in your scene. Note how the sphere appears to refract light at the edges, but not in the center where the geometry is directly in front of the camera. This is the result of the Fresnel logic described above.



Double click on the RefractionMasterial_Inst to open it in the Material Instance Editor. Enable the IOR parameter by checking the box next to the parameter name. Once enabled, you can set the IOR to different values to simulate different surface interaction. The video below shows how the refraction changes when the value is set to 1.0 (air), 1.33 (water), 1.52 (glass), and 2.42 (diamond).

Refraction Tips & Tricks

This section presents some ways you can use Refraction in combination with other aspects of the Material Editor to create complex and interesting refractive surfaces.

Refraction & Normal Maps

Adding an option to use a normal map with your refractive Material will yield some very interesting results, especially in areas where the Normal map has a lot of interesting detail. Follow the steps below to modify the RefractiveMaterial created above so that it works with normal maps.

First find a normal map to use. For this example, T_Water_N from Starter Content was used, however any normal texture will work. Open the RefractionMaterial asset and drag the normal texture from the Content Browser into the Material Graph.



Right-click on the normal map Texture Sampler and select Convert to Parameter. Rename the parameter Normal Map and connect it to the Normal input on the Main Material Node. By parameterizing the texture, you give artists a way to override it in a Material Instance without editing the parent Material.

Click Apply and Save in the Toolbar and then close the Material.



In the Material Instance Editor you should now see the Normal Map parameter listed under Global Texture Parameter Values. You can override the Normal Map by enabling the parameter and choosing a different texture from the drop-down menu.



By changing the Normal map, you can change the Material's refraction in interesting ways. Here are some examples using only the Normal maps you can find in the Textures folder of the Starter Content.



Refraction and Movement

Combining refraction with motion is a key component in many types of Materials. Ripples on water are one example, but the technique is similarly useful in a lot of VFX Materials such as heat haze, distortion from a large explosion, or energy effects.

The graph below shows one way to add organic looking motion to the normals. Duplicate the normal map, and connect them to the A and B inputs on a Lerp node. Add two Panner Material Expressions to the graph and connect them to the UVs of the normal map textures.



Change the values in the Panner nodes to add motion to the textures. Making some of the values negative moves the texture in the opposite direction, and is a good way to create organic, random looking motion. Here are the values used for the two Panners in this example.



The result is shown in the video below. In its current state it resembles an oily, metallic looking fluid, but with some modifications it could be the basis for a water Material.

Refraction Depth Bias

Refraction depth bias is a way to prevent closer objects from rendering into the distorted surface at acute viewing angles. However this can increases the disconnect between the surface and where the refraction starts. You can adjust the Refraction Depth Bias in the following two places.

Material Editor - You can find the Refraction Depth Bias in the Details panel under the Material section. You will need to press the white triangle (Highlighted in Green) to expose this property.



Material Instance Editor - You can find the Refraction Depth Bias in the General section of the Details panel.



Conclusion

Adding refraction to your Materials is a great way to get realistic looking results for translucent Materials like glass and water. Remember to consult the choart at the top of the document and use correct IOR values for the type of surface you are trying to simulate. IOR values come from real world measurements, so pushing the IOR higher or lower than what it is supposed to be is not recommend if you are striving for realism. In VFX and other looser applications of refraction, you can of course experiment and use values that suit your desired aesthetic.

Physically Based Materials

Material Expressions Reference

Material Functions Reference

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Shininess

Roughness & Shininess

Metallic & Shininess

Specular & Shininess

Using Shininess in Materials

Conclusion

Every object in the real world has some degree of shininess to it. In some cases this shininess (or reflectivity) is obvious, as with mirrors, chrome, or glass. Other times it is more subtle, as with painted wood, or smooth but unpolished stone / concrete.

In Unreal Engine, you can simulate the shininess of objects using the Metallic, Specular, and Roughness Material inputs. This tutorial demonstrates a few common ways to introduce shininess in your Materials.

Shininess

When light strikes a surface in the real world, some of it is absorbed, some of it is scattered, and some is directly reflected. Scattered light is referred to as a diffuse reflection. When you see an object in the world that does not appear reflective, like a tree trunk, you are mostly seeing scattered or diffuse light. Light that is directly reflected is known as specular reflection. When you see your image reflected on a chrome faucet, or in a puddle of water, you are seeing specular reflections.

Shininess in Unreal Engine is not a technical term, but an aesthetic one. In this tutorial shininess is referring to the ability of a surface to produce coherent, mirror-like reflections. The exact properties of these reflections are defined by the Metallic, Specular, and Roughness inputs.

Roughness & Shininess

Roughness plays a major role in determining the shininess of a Material. The Roughness input takes a value from 0 to 1.



The lower the Roughness value, the more mirror-like the Material will appear. When Roughness is 0, the Material behaves like a perfect mirror.

The higher the Roughness value, the less shiny a surface will appear. When Roughness is 1, the Material appears fully diffuse.

Below is a demonstration of how Roughness can affect the shininess of a Material. In this case, the sphere is in an empty environment so the highlight seen on the model is a direct reflection of the light source.



The sphere on the far left has a Roughness value of 0, and the light source is reflected as a sharp, precise highlight. As the Roughness value is increased from 0 to 1, the highlight becomes blurrier and the sphere appears less shiny.

Metallic & Shininess

The apparent shininess of Metallic objects is also determined by the Roughness value. Low Roughness values produce a shiny Metallic Material and high Roughness values produce a Material that appears less shiny. The key difference between a metal and non-metal Material is in the way the color of the specular reflection is calculated.

When the Metallic value is 0, specular highlights reflect the color of the environment and light sources.

When the Metallic value is 1, specular highlights are tinted by the Base Color of the Material.

Note how the color of the reflections is influenced by the Base Color when the Metallic value changes from 0 to 1.



The example below shows how the Roughness value affects a metallic Material. This Material has a Metallic value of 1, which stays constant through all the images. There is also a solid blue color passed into the Base Color input to show how Base Color influences the color of reflections on a metallic Material.



Roughness values from 0 to 1 on a metallic Material.

On the far left, the sphere has a Roughness value of 0 and appears fully mirror-like. As the Roughness value increases from 0 to 1 the sphere appears less shiny. Note how the Base Color of the Material influences the color of the reflections.

Specular & Shininess

In 99 percent of cases, you will not need to adjust the Specular input. The default value of 0.5 is suitable (and accurate) for most Materials.

The Specular input can also have an effect on the shininess of a Material. Pushing the Specular value closer to 1 will make the reflections or specular highlights of a Material appear brighter and stronger. Lowering that value closer to 0 will weaken the specular reflections until they are almost invisible.

Here is an example showing how the intensity of the reflections and specular highlight are affected as the Specular value is changed from 0 to 1.



Roughness affects the shininess of a Material regardless of the Specular value. Even when the Specular value is set to 1, the specular highlight will still be blurred to invisibility when the Roughness value is 1. Adjusting the Specular value will have no effect on the Material if Metallic is enabled.

The default specular value of 0.5 accurately reproduces the measured specularity of the vast majority of real-world objects. Therefore, you should not need to modify the Specular value for most of the Materials you make. You can of course increase or decrease the specular value as an artistic choice, but straying too far from 0.5 can make the Material less physically plausible.

Using Shininess in Materials

Use the following steps to create a shiny Material.

This tutorial uses textures from the Unreal Engine Starter Content. If you did not include the Starter Content in your project, read the Migrating content page for information about how to move content between projects. This way you can add the Starter Content to your current project.

Right-click in the Content Browser and choose Material from the Create Basic Asset section in the context menu.



Name the Material ShinyMaterial and then double-click the thumbnail to open it in the Material Editor.



With the Material open, add the following Textures and Material Expression Nodes to the Material Graph. You can find the textures in the StarterContent > Textures folder in the Content Browser.

Texture Sample: T_Metal_Gold_D x 1

Texture Sample: T_Metal_Gold_N x 1

Scalar Parameter x 3

Multiply x 1



Each Scalar Parameter needs a unique name and default value. Select each Scalar Paramater, then rename them and set their Default Value in the Details Panel as shown below.

Metallic: Default Value 0

Specular: Default Value 0.5

Roughness: Default Value 0.5



Connect all of the Material Expression nodes to their corresponding inputs on the Main Material Node. When completed, the Material Graph should look something like this:



Click the Apply and Save buttons in the toolbar to compile the Material and then close the Material Editor.



Find the ShinyMaterial asset in the Content Browser, right-click it and select the Create Material Instance option from the context menu.



Double-click the Material Instance in the Content Browser to open it in the Material Instance Editor. In the Instance Editor, enable all three Global Scalar Parameter Values by checking the box next to each parameter name.



With the Scalar Parameter Values enabled, you can change the values and immediately see your changes in the preview viewport. For example, if you set Metallic to 1 and then set Roughness to 0.2, you will get a very shiny metal that looks like gold, with some surface imperfections from the normal map.



If you increase the Roughness value to 0.7 you can see that the reflection becomes blurred and the surface loses some luster, but the reflections do not disappear completely.



Finally, if you set Metallic to 0 and Roughness to 0.15 the surface stops resembling a metal and looks more like scuffed plastic or paint.



Conclusion

When you configure the Roughness value for your Materials remember that most objects have some degree of shininess. Even surfaces that you wouldn't normally think of as reflective tend to show some kind of specular highlight when hit by a strong enough light source.

Most of the time you should avoid using 0 or 1 for your Roughness value, and instead use a value that falls somewhere between the two extremes. Texture masks are often used to add variation and noise to the Roughness value. This produces surfaces that are not uniformely shiny or dull, but some interesting combination of both. Read about texture masking here.

Remember to consider the performance cost of reflective Materials, and be mindful when using a lot of Metallic surfaces in close proximity. Materials can have a high performance cost when Metallic objects reflect one another, or reflect one another's reflections.

Material Blend Modes

Opacity Material Functions

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Transparency

Transparency and Opacity

Using Transparency in Materials

Transparency & Reflections

Tinted or Colored Transparency

Translucent Colored Shadows

Transparency & Performance

Translucency Sort Priority

Conclusion

When creating certain surface types such as water or glass, you need the ability to make the surface not only see through, but also give the surface a sense of depth and color. In the real world, these properties are referred to as Transparency or Opacity and the two often used interchangeably to describe the same thing. In Unreal Engine, Transparency and Opacity have two distinct meanings.

Transparency is used to define whether or not a surface can be seen through.

Opacity is used to define degree to which a surface transmits light. In other words, the opacity value determines how transparent or opaque (how see-through / hon see-through ) a surface is.

In the following tutorial you will learn everything you need to know about how to use transparency in your Unreal Engine Materials.

Transparency

Transparency is the term used to describe a surface's ability to block or allow the passage of light. For example, a brick is an object that has no transparency. Stained glass transmits some but not all light, and therefore it is a surface with transparency. You can use transparency to simulate a variety of different real world surface types, including those listed below.

Hair

Glass

Water

Smoke or Fire Visual Effects

Clouds

Impact Decals

Foliage

Transparency and Opacity

In Unreal Engine, transparency works by assigning each pixel an Opacity value between 0 and 1. When Opacity is 1, the surface is fully opaque, meaning it blocks 100% of the light that hits it. When Opacity is 0, the surface allows all light to pass through. Opacity values between 0 and 1 yield pixels that are partially see-through. The image below shows opacity values increasing from 0 to 1 on a Static Mesh.



You can also define opacity with a greyscale texture. The image below demonstrates how a texture can help define which parts of a mesh should have transparency and how transparent they should be. The texture is a gradient that goes from black at the top (or fully transparent) to white at the bottom (or fully opaque). The areas in the middle have a varying degree of opacity based on how close to black or white the pixel in the texture is.



Using Transparency in Materials

You can set up transparent Materials using the following steps:

This tutorial uses assets from the Unreal Engine Starter Content. If you did not include the Starter Content in your project, read the Migrating content page for information about how to move content between projects. This way you can add the Starter Content to your current project and not have to make a new one.

First Right-Click in the Content Browser and then select Material from the Create Basic Asset section of the context menu.



Name the Material TransparentMaterial and then open it by Double-Clicking the Material thumbnail in the Content Browser. The Material Editor opens.

Click in the background of the Material Graph to display the Material properties in the Details panel. Under the Material section change the Blend Mode from Opaque to Translucent.



Now that the Blend Mode has been correctly set, add the following Material expressions to your graph. You can find the nodes by typing their names into the search bar in the Material palette. Once found Left-click and drag them from the palette into the Material Graph.

Vector Parameter x 1

Scalar Parameter x 1



Rename the Vector Parameter node to BaseColor and give it a color value. Connect the output of the Vector Parameter node into the Base Color input on the Main Material Node.

Rename the Scalar Parameter to Opacity and give it a default value of 0.5. Plug the Scalar Parameter into the Opacity input on the Main Shader Node.



Click Apply and then Save in the Material Editor toolbar to compile the Material and save the asset.



Find the TransparentMaterial asset in the Content Browser, right-click the thumbnail and select Create Material Instance in the context menu.



Inside the Content Browser, navigate to the Shapes folder in the Starter Content. Left-click and drag the Shape_Sphere Static Mesh into the viewport and release the left mouse button to spawn it in the level.



Find the TransparentMaterial_Instance asset in the Content Browser. Left-click and drag the Material instance onto the sphere and release the left mouse button to apply it to the mesh.



Open the Material Instance by Double-Clicking on it in the Content Browser. In the Material Instance Editor, override the OpacityAmount parameter by checking the box next to the parameter name. Once enabled you can adjust the value of OpacityAmount to change how transparent the object will be.

Transparency & Reflections

Objects that make use of transparency can display scene reflections if the following options are set. However keep in mind that having a lot of translucent Materials that have reflections enabled could cause performance issues.

Open the TransparentMaterial that was created above by double-clicking it in the Content Browser. In the Details panel under the Translucency category, change the Lighting Mode from Volumetric NonDirectional to Surface TranslucencyVolume.



Inside the Material Graph, select the OpacityAmount parameter and duplicate it twice by pressing CTRL + D on the keyboard. When completed, your Material Graph should look something like this.



Rename the new Material Expression nodes to Metallic and Roughness. Set the default value of the Metallic Material Expression to 1.0 and set the default value of Roughness to 0. Then connect each Material Expression node to the corresponding input on the Main Material Node.



Click Apply and Save the Material Editor toolbar and then close the Material Editor.



You should now be able to see reflections on the spheres in your level.



By adjusting the parameters of the Material Instance, you can make the Transparency have extremely different looking results.



Tinted or Colored Transparency

With the Thin Transparent Shading Model and Material expression, you can accurately represent tinted and colored transparent Materials, such colored glass and plastics. This Shading Model enables white specular highlights with correctly tinted background color for transparent surfaces.





An example of a Thin Translucent Material Graph is shown below.



Click to enlarge image.

Configure the Material with the following properties in the Details panel:

Change the Blend Mode to Translucent.

Change the Shading Model to Thin Translucent.

In the Translucency category, change the Lighting Mode to Surface ForwardShading.

Add a Thin Translucent Material expression to the graph and connect a Constant3Vector or a Vector Parameter to the input. This node controls color tint of the transparent surface.

Translucent Colored Shadows

Translucent Materials are able to cast colored shadows with light transmission in some cases. The amount of light that passes through the Material is determined by its opacity values and how much light is being cast onto the Material.



Translucent colored shadows is currently only achievable with Static Lighting and Lightmass.

For additional information and usage, see Using Colored Translucent Shadows.

Transparency & Performance



Transparency, especially lit transparency, can quickly become a performance bottleneck if there are too many transparent objects in a scene. The term used to describe this problem is overdraw. Overdraw occurs when you have lots of objects with Transparency rendering on top of one another. The reason overdraw causes such a performance problem is because the cost of redering transparency becomes more and more expensive for each successive layer of transparency that you introduce.

To help you better identify whether this issue is happening and where, Unreal Engine has a special view mode called Shader Complexity mode. Shader Complexity mode shows you how complex a given surface is to render by using colors to show complexity. The more green that you see, the cheaper things are to render. The more red that you see, the more expensive that frame is to render. Use the following steps to enable Shader Complexity view mode.

To enable Shader Complexity, click the View Mode option at the top of the Editor Viewport. By default the view mode is set to Lit.



Select the Shader Complexity option from the context menu.



After activating the Shader Complexity view mode, the level viewport should look like the video below.

Overdraw is demonstrated very clearly in the video as the camera rotates around the transparent spheres in the level. When the spheres are all displayed side by side, there is no overdraw and the viewport is mostly green. When all six spheres are all in the same line of sight, the areas with the most overlap turn bright red to indicate overdraw. While it is not 100 percent possible or advisable to get rid of all overdraw, this view mode can make it very helpful when trying to figure out exactly where your performance issues could be coming from.

Translucency Sort Priority

When there are multiple transparent objects in a scene close together, you may notice that the engine sometimes has issues determining which object to render in front or behind the other transparent objects. The following example demonstrates this happeing using the Materials from above and the lit steam VFX from the Starter Content.

Notice how the steam initially renders in front of the meshes and then suddenly pops behind each sphere. To prevent this from happening, the Translucency Sort Priority needs to be set so that the VFX of the smoke will always render on top of other translucency in the scene. To change the Translucency Sort Priority on the VFX, do the following.

First select the object or objects that you want to render on top of all other Translucency in the level. In this case, select the VFX particle system.



In the Details panel, navigate to the Rendering section and then expand the Advanced subcategory.



From the new list of options, look for Translucency Sort Priority and then input a value of 100.



By default, everything that is added to a level has a Translucency Sort Priority of 0. If you want something that is transparent to always draw over the top of everything else that is transparent, use positive numbers. If you want something that is transparent to always draw behind everything else that is transparent, use negative numbers.

Now check out the steam VFX in the scene. With a Translucency Sort Priority set to 100, the steam will always draw on top of the other translucent objects.

Setting the Translucency Sort Priority to -100 makes it so that the steam always draws behind other translucent objects.

While adjusting the Translucency Sort Priority can fix sorting issue in the level, it could introduce new sorting issues when spawning effects or objects during game play. Because of this, it is a good idea to define what Translucency Sort Priority number to use and where. For example, you could say that all spawned effects will have a Translucency Sort Priority of 100. So, if there are some sorting issues in the level, you can adjust the objects in the levels Translucency Sort Priority to be any number up to 99. This way, the spawned game effects will always render on top of everything else no matter what Translucency Sort Priority objects in the level have.

Conclusion

Transparency is a very powerful tool that can help to make your 3D projects come to life. Remember to try and keep the number of transparent objects that use reflections to a minimum whenever possible, as this can easily affecct performance. Finally, make sure to regularly check Shader Complexity mode both in the editor and during game play to make sure that transparency overdraw is kept to a minimum.

Subsurface Profile Shading Model

Subsurface Shading Model

Enabling Materials to use Subsurface Profiles

Creating Subsurface Profiles

Creating a Material that Uses a Subsurface Profile

Using a Subsurface Profile in a Material Instance

Applying a Subsurface Profile Material

Adjusting a Subsurface Profile

Tips & Tricks

Scatter Radius

Combining a Material Instance with a Subsurface Profile

The ability to render realistic looking human skin is a must for any modern Video Game engine. To fulfill this need, Unreal Engine now offers a shading method specifically for skin or wax like surfaces called Subsurface Profile. While the Subsurface Profile shading model has similar properties to the Subsurface shading model, its key difference is in how it renders. SubsurfaceProfile uses a rendering approach that is based in Screen Space because this helps to better display the subtle subsurface effects seen in human skin where backscattering is a secondary effect only seen in few cases like ears for example. The following document will cover what a Subsurface Profile is and how you can use them in your work.

Enabling Materials to use Subsurface Profiles

Enabling your Material to use a Subsurface Profile can be done in the following few steps.

First create a new Material by Right-Clicking in the Content Browser and then selecting Material from the Create Basic Asset list. Once created, make sure that you name the Material. For this example, the Material will be named M_Subsurface_Profile. When completed, your Content Browser should look like this.



Double-click the Material in the Content Browser to open it in the Material Editor.

Now with the Material open, we need to change the Material's Shading Model from Default Lit to Subsurface Profile in the Details panel.



At this time, you can assign a Subsurface Profile by inputting one into the Subsurface Profile section in the Details panel.



Now the Material is ready to be used with a Subsurface Profile.

Creating Subsurface Profiles

Creating Subsurface Profiles is something that can be accomplished in the following steps.

First Right-Click in the Content Browser, open the Materials context menu, and select the Subsurface Profile option.



Once the Subsurface Profile has been selected and created, you can name it. For this example, we will name our Subsurface Profile SSP_00. Once completed, you should have something that looks like this.



Creating a Material that Uses a Subsurface Profile

Now that the Material and Subsurface Profile have been created, it is now time to fill them in with data. In the following steps, we will be creating a Material and a Material Instance that can make use of a Subsurface Profile.

Open the M_Subsurface_Profile Material in the Material Editor if you do not already have it opened.

With the Material open, it is time to place down some Material Expression nodes. For this tutorial, we are going to make use of the following nodes.

Vector Parameter x 1

Scalar Parameter x 2



Now that we have the Material Expression parameter nodes added to the graph, you will need to name them and fill in their default values. For this example, we will be giving the nodes the following names and default values.

Property Name

Value

BaseColor

R: 1.0 G: 1.0 B: 1.0

Roughness

0.35

SubsurfaceAmount

0.5

Connect each of the nodes to their corresponding input on the Main Material Node. When everything has been filled in, your shader graph should look something like this.



Now that everything is wired up, you can add your Subsurface Profile to the Material. To do this, first find the Subsurface Profile input in the Material section of the Details panel. Use the drop-down menu to select the SSP_00 asset you created earlier, or drag it from the Content Browser directly onto the input.



If you do not provide a Subsurface profile, a default one will be used. The default one that is used is a close approximation to Caucasian skin.

With the Subsurface Profile applied and the Material expressions linked to the main Material node, it is now time to compile the shader and get ready to make a Material Instance out of this Material. When completed with the Material, it should look something like this.



Using a Subsurface Profile in a Material Instance

With the Material now created and compiled, it is now time to make some Material Instances to make tweaking of parameters faster. To make a Material Instance from our Material, first locate the Material in the Content Browser and then Right-Click on it and select the Create Material Instance option. When completed, your Content Browser should look something like this.



Now that the Material Instance has been created, open it up by using the Left Mouse Button to Double-Click on it in the Content Browser. Once open, you should see something that looks like this.



To change the Subsurface Profile in a Material Instance, you can enable the Subsurface Profile override by checking the box, and then use the drop-down menu to select a different Subsurface Profile asset. Once you click on the input you should see the Subsurface Profiles that are available to choose from.



If you have already supplied a Subsurface Profile in the Parent Material, then you do not need to override it in the Material Instance. This is only if you wish you use a different Subsurface Profile than what is already being used.

Applying a Subsurface Profile Material

Now that the Material Instance has been created, it is now time to test out our new Material. To do this, we first need to create a new blank level to work in by going to the main menu and under the File option select New Level. When prompted what type of level to select, select the Empty Level.



To test the Material, we will use a Static Mesh from the Starter Content, lit from the front by a Point Light, and from behind with a very bright Spot Light. This strong backlighting will help demonstrate how Subsurface Profile Materials can transmit and scatter light. The lighting configuration should look something like the image below.



Find the SM_Statue Asset in the Content Browser under StarterContent > Props and add it to your Level. The location and rotation settings in our example are shown below.

Property Name

Value

Location:

X:0, Y: 0, Z:0

Rotation:

X:0, Y: 0, Z:-23

Open the Place Actors menu and add both a Point Light and a Spot Light to your level.



Select the Point light and configure it with the following settings in the Details Panel.

Property Name

Value

Location:

X:380, Y: 0, Z:80

Intensity:

8.0 cd



Select the Spot Light and configure it with the following settings in the Details Panel.

Property Name

Value

Location:

X:-650, Y: 100, Z:-75

Rotation:

X:0, Y:20, Z:0

Intensity:

1500 cd



Apply the M_Subsurface_Profile_Inst Material instance to the statue by dragging it from the Content Browser onto the Static Mesh in the Level, or onto both of the statue's Material Elements in the Details panel. Make sure you drag it onto both pieces of the sculpture.



The effect of the Subsurface Profile is most obvious along the edges of the highlight, where the spotlight falls into shadow. Along this contour, you can see the reddish-pink subsurface color coming through, in contrast to the lavender base color of the statue and the intense white highlight.

Adjusting a Subsurface Profile

Once the Material Instance has been applied to the statue, you can adjust the Subsurface Profile settings. To do this, open the Subsurface Profile by double-clicking the SSP_00 asset in the Content Browser. You should see something like this being displayed.



You can adjust the properties of the Subsurface Profile by changing the values or colors in the editor.

Surface Albedo: Should match the base color of the corresponding Parent Material as closely as possible.

Mean Free Path Color: Controls how far light penetrates into the surface for the red, green, and blue channels, and determines the color of the region where light is scattered beneath the surface. Lighter values allow more transmission, black effectively turns off the subsurface scattering.

Mean Free Path Distance: A distance in world/Unreal units (cm), which scales how far light will penetrate into the surface. Decreasing makes the subsurface region tighter/sharper, increasing this value makes the subsurface region larger and blurrier.

Keep in mind that you can adjust the parameters of the Subsurface Profile in real time as demonstrated below.

Tips & Tricks

Because of how Subsurface Profiles render, there are a few Tips & Tricks to getting the most out of using them.

Scatter Radius

Setting the Mean Free Path Distance of the Subsurface profile to a really big number will result in rendering errors as you can see in the following image.

In the image on the Left, the Mean Free Path Distance was set to 50. Notice how it looks like there are multiple images rendered on the surface. Now take a look at the image on the Right. In this image the Mean Free Path Distance was set to 5.0. Notice how the image looks softer and more natural. This is the type of effect we are trying to achieve.

Combining a Material Instance with a Subsurface Profile

Combining a Material Instance with a Subsurface profile is a great way to get the most control over your results for a number of reasons.

A Material Instance allows you to tweak values in real time which makes seeing your results much quicker.

You can use the Opacity input to dampen the Subsurface contribution to the surface. However it is recommended that you keep this value at 1 and adjust the parameters inside the Subsurface Profile. Only adjust this value if you find that you cannot get the results you are looking for when adjusting the Subsurface Profile.

The Value slider of each color picker controls the influence of the Subsurface effect. The closer that this value is set toward white, the more prominent the effect will be. While the closer the value is set to black, the less visible the effect will be.

Subsurface Profile Shading Model

Subsurface Shading Model

Content Examples

Enabling the Subsurface Shading Model

Setting up a Subsurface Material

Testing the Subsurface Material

Working with the Subsurface Material

Opacity Controls

Subsurface Color Value

Using a Texture as a Subsurface Influence Mask

Subsurface scattering is the term used to describe the lighting phenomenon where light scatters as it passes through a translucent / semi translucent surface.

Unreal Engine offers a special Shading Model called Subsurface that is used specifically for Materials that need this interaction like skin or wax.

The following tutorial will walk you through all you need to know about how to use subsurface scattering in your Materials.

Enabling the Subsurface Shading Model

Enabling a Material to use the Subsurface shading model can be done a few steps.

First create a new Material by Right-Clicking in the Content Browser and then selecting Material from the Create Basic Asset list. Give the Material a descriptive name like M_Subsurface_Scattering. When completed, your Content Browser should look like this.



Open up the Material by Double-Clicking the asset in the Content Browser.

In the Details Panel of the Material Editor, change the Material's Shading Model from Default Lit to Subsurface.



The Material is now ready to be used as a Subsurface Material.

Setting up a Subsurface Material

Continuing with our Material from above that has Subsurface Scattering enabled, let's setup a basic Material so that we can see the Subsurface scattering in action in a level.

We need to place down some Material Expression nodes so that we have something to work with. For this example, we are going to be adding the following nodes.

Vector Parameter x 2

Scalar Parameter x 2



The reason that we are using Parameter Material nodes instead of regular Material nodes is so that we can make a Material Instance out of this Material for easier tweaking inside the editor.

Before we start to connect the nodes, we first need to name them as well as set default values for them. The names and default values for the nodes are as follows.



Property Name

Value

Base_Color

r:1.0, g:1.0, b:1.0

Roughness

0.35

Opacity

0.5

Subsurface_Color

r:1.0, b:0, g:0

After renaming all four parameter expressions and setting their default values, connect them to their corresponding inputs on the Main Material Node as shown above.

Once the nodes have been connected, make sure that you compile the Material by pressing the Apply button, and Save the Material. Once compiled, you should have something that looks like this.



Once the Material has been compiled, you can close the Material Editor window. Then inside of the Content Browser, select the Material, Right-Click on it, and then select the Create Material Instance option from the menu.



Testing the Subsurface Material

Now that the Material Instance has been created, you can test the Material in a Level.

To do this, you first need to create a new blank level to work in by going to the main menu and under the File option select New Level. When prompted what type of level to select, select the Empty Level.



To test the Material, we will use a Static Mesh from the Starter Content, lit in front by a Point Light, and from behind with a very bright Spot Light. This strong backlighting will help demonstrate how Subsurface Materials can transmit and scatter light. The lighting configuration should look something like the image below.



Find the SM_Statue Asset in the Content Browser under StarterContent > Props and add it to your Level. The location and rotation settings in our example are shown below.

Property Name

Value

Location:

X:0, Y: 0, Z:0

Location:

X:0, Y: 0, Z:-23

Apply the M_Subsurface_Scatterin_Inst Material instance to the statue by dragging it from the Content Browser onto the Static Mesh in the level, or onto both of the statue's Material Elements in the details panel.



Open the Place Actors menu and add both a Point Light and a Spot Light to your level.



Select the Point light and configure it with the following settings in the Details Panel.

Property Name

Value

Location:

X:380, Y: 0, Z:80

Intensity:

8.0 cd



Select the Spot Light and configure it with the following settings in the Details Panel.

Property Name

Value

Location:

X:-650, Y: 100, Z:-75

Rotation:

X:0, Y:20, Z:0

Intensity:

1500 cd



Working with the Subsurface Material

Now that the Subsurface Material has been applied, it is time to tweak the settings of the Material Instance.

In the following sections, we will go over how we can control how our Subsurface Material will look and how to tweak the various options in the Material Instance to get the results that we want.

Opacity Controls

In the current setup of our Subsurface Material, the Opacity input controls the amount of light that we want our object to scatter.

A setting of 0 will allow all light to scatter where a setting of 1 will let no light scatter. The following example shows light being scattered through the statue mesh with the Opacity value set at 0 in the image on the left, 0.35, 0.65, and and 1.0 in the image on the right. Notice as the numbers go from 0 to 1, the amount of light we see passing through the object becomes less and less.



While the Opacity does help to get rid of a lot of the scattered light, you might notice that there is still some Subsurface scattering happening. To get completely rid of the effect, you are also going to have to adjust the Value of the Subsurface Color (More on this in the Subsurface Color Value section below.)

Subsurface Color Value

While you can adjust the amount of Subsurface scattering that happens via the Opacity input, you can also adjust this using the Value slider in the Color Picker.

For example, setting the Opacity to a value of 1.0 and setting the Subsurface Colors Value from White to Black will effectively turn off Subsurface Scattering like in the example below.

Subsurface color value at 0, 0.5, and 1.0.



Here is an example of adjusting the value in real time. Notice how as the Value of the color is adjusted from Red to Black, the amount of Subsurface scattering influence is affected.

Using a Texture as a Subsurface Influence Mask

You can use a Texture as a Mask to have more control over what areas receive or do not receive Subsurface scattering. To do this, all you need to do is plug the Texture you want to use as the Mask into the Opacity Channel of your Material. In the following example, not only are we using a Mask texture, we are also using a Scalar value to control the intensity of the Mask so that we can have more control over the amount of Subsurface scattering that is happening.



Mask textures work based on values going from Black to White. Values that are closer to Black will allow the Subsurface effect to come through while values that are closer to White will not allow the Subsurface effect to come through.

Here is what the Material above, using the Mask Texture, looks like in the level. Notice the Black spots on the cube. Those Black spots are the result of using a pure white value in the Mask Texture.



Benefits to Using Bent Normals

Bent Normal Creation

Using Bent Normals in Unreal Engine

Reflection Occlusion





Using Bent normals within Materials can help improve how they react to lighting and shading. In the following document, you will find all the information you need to start using Bent normals in your Unreal Engine projects.

Benefits to Using Bent Normals

Below, you will find some of the benefits to using Bent normals.

One of the biggest impacts Bent normals tend to have is to reduce the amount of light leaking that happens after a light build.

Bent normals can also be used with Ambient Occlusion (AO) to improve Diffuse indirect lighting. It does this by making the Diffuse indirect light closer match Global illumination (GI) by using the Bent normals for indirect lighting instead of the Normals.





Bent Normal Creation

To get the highest quality Bent Normal map, and to match Unreal Engine's assumptions on how Bent Normal maps should be calculated, make sure to adhere to the following information when creating your Bent Normal maps:

Use Cosine Distribution when creating the Bent Normal map.

You can use Substance Designer 6 to generate the Bent Normal map just like a standard normal map or an AO map.

When generating your Bent normal, make sure your character is in a T-Pose.

The Bent normal and the AO should use the same distance setup.

The Bent normal should be in the same space as your Normal map. Consult the following chart for more information:

World Space Type

Normal Map Type

Bent Normal Type

World

World

World

Tangent

Tangent

Tangent

Using Bent Normals in Unreal Engine

Using Bent Normal maps inside of a Material is very similar to setting up and using Normal maps. All you need to do is add the Bent Normal custom output node to the Material graph and then connect your Bent Normal map to the input like in the following image. Also, make sure that there is an AO map input into the Ambient Occlusion input.



Click for full image.

Reflection Occlusion

Bent Normal maps are also used in a powerful but less traditional way, and that is for Reflection Occlusion / Specular Occlusion. An Ambient Occlusion (AO) map occludes Diffuse indirect light, while Reflection Occlusion is a similar concept, but applied to Specular indirect lighting. Reflection Occlusion works by intersecting the Specular lobe with the visible cone or a cone representing the unoccluded part of the hemisphere described by the Bent normal as the cone axis and the AO amount as the cone angle. This results in significantly reduced Specular light leaking especially when Screen Space Reflection (SSR) data is not available.

Multi-bounce approximation for occlusion is also supported. This means that instead of AO or Reflection Occlusion shadowing the first bounce, we can use an approximation of what many bounces will produce. With multi-bounce approximation, brighter Materials will lose less light, and colored Materials will be made more saturated.





ddx and ddy

Bump Mapping Material Functions

ComputeFilterWidth

PerturbNormalLQ

PerturbNormalHQ

PreparePerturbNormalHQ

Single function instead of 3 functions

Using Textures

Notes

Performance

Issues

Future Work

References

Bump mapping is an old trick of graphics programmers (1978 James Blinn) that creates the illusion of bump surfaces through an adjusted shading computation without adding more geometry. Instead of using the surface normal, a new normal is used for shading. The new normal can be adjusted by a 1d function (e.g. Perlin noise, grayscale texture). This trick is much faster than doing real displacement mapping with minor short comings (e.g. silhouettes, occlusion, shadows).







Without Bump Mapping

With Bump Mapping

With Bump and Normal Mapping

In real-time rendering, we usually use a variant of bump mapping called normal mapping (bluish textures). Normal maps store a color in each pixel of the texture which is actually a 3d vector with the length of 1.

There are two ways to generate a normal map:

Create a normal map from a grayscale image - Precompute the difference of each pixel to its vertical and horizontal neighbors. Convert the two resulting numbers (derivative) to a unit normal and store as color.

Bake the normal down from a high poly 3d model - Associate each pixel of a texture with a 3d surface location on the high poly object and store its normal encoded as color.

In order to make the resulting texture reusable at any rotations, the normal vectors stored must be in tangent space, which consists of 3 vectors generally referred to as: normal, tangent and binormal. It defines how the surface is oriented. So by converting all normal into the tangent space, we can reuse them as they are now defined relative to the

Tangent space mapping depends on the UV mapping of the object because the x and y direction in the texture defines two vectors of the tangent space (tangent and binormal) in world space. It is difficult and takes time to produce good UV mapping without seeing tangent space artifacts.

What if we want to use a 3d grayscale function like Perlin noise? The function does not require any UV mapping and could improve the nearby detail rendering of bump surfaces. Implementing bump mapping without requiring tangent space makes this possible.

ddx and ddy

In order to implement bump mapping without tangent space, we added two new material expressions to the material editor: ddx and ddy. Each of these expressions returns an approximation of the derivative of its input. The graphics hardware calculates this approximate derivative by shading two pixels and subtracting the results (ddx = right - left, ddy = bottom - top).

These functions can only be used in the pixel shader and are generally only useful in Material Functions for implementing larger effects.

Item

Description



Inputs



Value

The value to calculate the derivative of.



Outputs



Out

The approximate derivative of the input. The type will match that of the input. For example, a scalar results in a scalar output, a 2d in a 2d output, and so on.

ddx and ddy are computed for a 2x2 block and therefore show some blocky artifacts when used with high frequency input.

Bump Mapping Material Functions

Several Material Functions are provided to implement bump mapping in your materials without relying on tangent-space normal maps.

ComputeFilterWidth



This function makes use of ddx and ddy to compute how quickly a value is changing over the screen. This allows to fade out a procedural shader in the distance where it would start getting noisy. The fading results in less shimmering which is even more noticeable in motion and extremely important for bump mapping as specularity on bumpy surfaces can produce extreme aliasing artifacts.

The following example images show how a procedural bump map function can be faded out in the distance.





Item

Description



Inputs



In

The value to compute the filter width for.



Outputs



Result

How quickly the input changes from pixel to pixel.

PerturbNormalLQ

The PerturbNormalLQ function converts a grayscale bump map input into a world-space normal. However, because it uses ddx and ddy, which have the aforementioned 2x2 block artifacts, the output world-space normal is of low quality.





Item

Description



Inputs



Bump

The scalar bump value (grayscale) to compute the world-space normal from.



Outputs



WS Normal

The computed world-space normal.

In order to use the world-space normal this function outputs, the tangent-space normal setting on the Material node must be false.

This function exists only as a reference and is not exposed to the Material Function Library. Use the PerturbNormalHQ function instead.

PerturbNormalHQ

The PerturbNormalHQ function provides higher quality by calculating a more precise derivative than ddx and ddy provide. It does this by computing the scalar function multiple times using three sample positions.

Item

Description



Inputs



Bump one pixel right

The scalar bump value (grayscale) one pixel to the right of the current position.

Bump center

The scalar bump value (grayscale) at the current position.

Bump one pixel down

The scalar bump value (grayscale) one pixel down from the current position.

WS Normal

A world-space normal that is combined with the bump map. A tangent-space normal can be converted to a world-space normal with a Vector Transform expression.



Outputs



WS Normal

The combined world-space normal.

In order to use the world-space normal this function outputs, the tangent-space normal setting on the Material node must be false.

PreparePerturbNormalHQ

The PreparePerturbNormalHQ function computes the three sample positions needed by the PerturbNormalHQ function to compute the world-space normal.



Item

Description



Inputs



Value

The scalar bump value (grayscale) at the current position.



Outputs



Value one pixel right

The scalar bump value (grayscale) one pixel to the right of the current position.

Value

The scalar bump value (grayscale) at the current position.

Value one pixel down

The scalar bump value (grayscale) one pixel down from the current position.

FilterWidth

It also computes the filter width which is useful to fade out details in the distance.

Single function instead of 3 functions

You can create a material function that encapsulate your bump mapping function and evaluate it 3 times in your other function. This hides the complexity to a certain degree.

Using Textures

Textures can be used with the bump mapping Material Functions for better performance; however, artifacts may be introduced due to the way in which the graphics card handles filtering textures. A normally filtered color is interpolated with a linear interpolation, the derivative of that is a constant. That means using a grayscale texture provides you with normals that are not smoothly interpolating of the surface.

Notes

The described method is based on the work from Morten S. Mikkelsen (see references).

Performance

Procedural shaders can cost quite some performance and are hard to implement without aliasing (compared to texture mapping). We currently provide Perlin noise and although this material expression can be optimized, it will always be a heavy operation. Using the levels feature for n levels requires most of the computations being done n times. Evaluating the function 3 times for bump mapping hurts even more. Be aware that the cost scales with pixel count. You can make use of all those features but we suggest them only for prototyping or in controlled situations.

Issues

Flipped/Mirrored UV are not handled correctly yet.

Future Work

This method can be used to replace the explicit stored tangent space. To go in that direction, we need to get more experience. The current implementation not only enables artists to use this for bump mapping, but it also provides a way to do research.

References

Bump Mapping Unparametrized Surfaces on the GPU (Morten S. Mikkelsen)

Bump Mapping Unparametrized Surfaces on the GPU

Derivative Maps (Mikkelsen and 3D Graphics blog)

mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html

Curve Linear Color Asset

Curve Atlas Asset

Using a Curve Atlas with Materials

Accessing Curve Atlases through Blueprint



Curve Atlases store a combination of Curve assets which enable you to access Curve Linear Color data through your Materials. The Curve Atlas stores any number of Curves in a texture that can be used with Materials. When creating Material Instances and changing Material Instance Dynamics (MIDs) through Blueprint, you are able to set a curve as an override, enabling you to quickly iterate and change RGBA curve values without changing your base Material.

Curve Linear Color Asset

A Curve Linear Color asset is used to store the interpolated RGBA points that are evaluated over a given range, producing a color gradient that can be used with Materials.



Example of a Curve Gradient created with a Curve Linear Color asset

Right-click in the Content Browser, and select Miscellaneous > Curve to create a new Curve Asset.



In the Pick Curve Class dialog, select CurveLinearColor.



A new Curve Linear Color asset is added to the Content Browser displaying a preview of its current gradient. Double-click the thumbnail to open the Curve Asset Editor, where you can add, subtract, and adjust keys for the individual RGBA curves in the graph.



When you open the Curve in its Asset Editor, you'll be able to set the individual RGBA curves, adjust color values for the Curve, and preview the Curve Gradient Result.



Click image for full size.

The Curve Gradient Result shows you the resulting gradient.

The Curve Graph is where you add, adjust, and subtract any keys for the individual RGBA curves.

The Color panel is where you adjust color values that affect all keys.

To add a key to an individual curve, click the curve with the Middle Mouse Button. A key is inserted at the mouse pointer. If you right-click in the empty graph and choose Add Key from the context menu, you can add a key on all curves at the point on the x-axis where you clicked.

Curve Atlas Asset

A Curve Atlas asset is used to store and access multiple Curve assets, enabling management of gradient lookup tables (LUT). The Curve Atlas Asset Editor is similar to the Texture Editor, enabling you to make adjustments for Brightness, Vibrance, Hue, and more.

Example of the Curve Atlas LUT

The curves assigned to the Curve Atlas as Gradient Curves make up the atlas. The Material Graph uses the texture created to perform the lookup for Materials applied to Actors.

You can create a new Curve Atlas by right-clicking in the Content Browser and selecting Miscellaneous > Curve Atlas.



When you open the Curve Atlas in its Asset Editor, you can set the number of curves it can store, assign your curves, and adjust color values for all assigned curves. This is similar to the functionality of the Texture Editor.



Click image for full size.

The main viewport displays the Curve Atlas lookup table, which displays all assigned Gradient Curves for the Texture Size that is applied.

The Curves panel is where you sets the Texture Size for the number of Gradient Curves you need. The default is 256. The Gradient Curves subcategory is where you can add Gradient Curve assets to your asset.

The Adjustments panel makes texture adjustments to all Gradient Curves assigned to the Curve Atlas.

For maximum texture efficiency, it's best to use a power of 2 value (such as 32, 64, 128). You can uncheck Square Resolution and change the Texture Height to eliminate vertical white space.

The Texture Size used can have an impact on the fidelity of your gradients, so it's best not to use a small atlas size for a complex curve. However, you can save texture size by using a small atlas for a set of simple curves.

To add a new Gradient Curve to the Curve Atlas, click the Plus (+) icon to add array elements. You can use the Trash Can icon to remove all elements from from the array.



Use the drop-down menu next to the new array element, and in the context menu select the Curve Asset you want to add to the Curve Atlas.



Each Gradient Curve you add to your Curve Atlas is displayed as a row in the Curve Atlas lookup table.



Using a Curve Atlas with Materials

After creating your Curves and applying them to a Curve Atlas, you can create a Material that references the Curve Atlas and retrieves one of the curves assigned to the atlas.

To sample one of the curves in the atlas, create a new Material and in the graph, right-click and add a Curve Atlas Row Parameter node.



This node is similar to a Scalar Parameter in that it enables you to work with Material Instance Dynamics (MIDs). These can then be used through Blueprint for the V-axis of the atlas UVs, but the node will do the sampling for you and return a Vector 3, along with R, G, B, and A, masks.

Select the Curve Atlas Row Parameter expression to display its Details Panel properties. Here you can assign the Atlas and select a Curve from that atlas to use with this Material by default.



The Curve Atlas bakes down when it is compiled, which means there is currently no runtime support for changing what is in the atlas or the curve data that is stored in the atlas at runtime. However, you can store a large amount of data in a single Curve Atlas, and use Blueprint to override the curve being sampled from a Material Instance.

As an example, here is a "Rock" Material that samples one of the curves assigned to a Curve Atlas.



Click image for full size.

When you create any Material Instances, you can override the Curve Scalar Parameter to reference a different Curve in the Curve Atlas that is applied to your mesh.

The examples here show a Material Instance applied and the Curve that is being referenced from the Curve Atlas.









Base

Curve 1

Curve 2

Curve 3

Accessing Curve Atlases through Blueprint

In Blueprint, you can set the Scalar Parameter value on a Dynamic Material Instance using the Get Curve Position node. Get Curve Position takes the Curve Atlas as an input, passes the scalar value to the Set Scalar Parameter Value, and returns a Boolean indicating whether the curve was found in the atlas.



Click image for full size.

Volumetric effects

Casting Shadows & Self-Shadowing

Static shadowing

Translucent Surfaces

Reflection Captures

Per-Pixel Translucent Lighting

Thin Translucency

Limitations

Translucent effects generally fall into a few categories: volumetric, volumetric but dense enough to have normal information, and surfaces. Different lighting techniques are needed for each of these, so a material must specify the Translucency Lighting Mode that should be used.

Lit translucency gets most of its lighting through a series of cascaded volume textures oriented around the view frustum. This allows lighting to be known in a single forward pass for any point inside the volumes, but has the downside that the volume texture is fairly low resolution, and can only cover a limited depth range from the viewer.

The volume is configured through cvars that can be set differently based on the scalability level:

r.TranslucencyLightingVolumeDim, which defaults to 64. Raising this by a factor of 2 increases the cost to light volume by a factor of 8.

r.TranslucencyLightingVolumeInnerDistance, which defaults to 1500. Raising this increases lighting volume coverage but reduces effective resolution.

r.TranslucencyLightingVolumeOuterDistance, which defaults to 5000. Raising this increases lighting volume coverage but reduces effective resolution.

Shadowed direct lighting from all movable light types is injected into the translucency lighting volume. Light functions are also taken into account.



Translucent materials receive diffuse GI from the Indirect Lighting Cache. Only one lighting sample is interpolated, at the center of the object's bounds. There is only one sample taken for the whole object, even if it is a large particle system. The indirect lighting interpolates over time if the bounds center changes, so it does not pop.



The left sphere is lit translucency using the Indirect Lighting Cache, the right sphere is opaque with baked lighting from Lightmass.

Volumetric effects

Casting Shadows & Self-Shadowing

Translucency can cast shadows onto the opaque world and onto itself and other lit translucency Actors. This is implemented with Fourier Opacity maps, which do a great job for shadowing from blobby volumes, but have severe ringing artifacts with more opaque translucent surfaces. Translucency self shadowing goes through the lighting volume for point and spot lights, so it is often not visible due to low resolution unless the effect is very large and dense. Directional lights however do translucent self shadowing per-pixel, and get much higher quality. Directional lights also have subsurface shading for lit materials using the subsurface shading model.

Translucent self-shadowing uses per-object shadows, which means that it needs user specified fixed particle system bounds and they need to be correct. The easiest way to set this up is to author your particle movement, then right-click on the 'show bounds' button on the Cascade toolbar, which will pop up a dialog that allows you to generate fixed bounds. Very large self-shadowing particle systems will get reduced shadowmap resolution, since the shadowmap is stretched to cover the system bounds. Verify that your bounds are reasonable by enabling Show Bounds, which can be found under Show -> Advanced -> Bounds. Then select the emitter in the editor and it will draw the bounding box and sphere.





Static shadowing

Translucency can receive static shadowing from stationary lights through a special static shadow depth map generated by Lightmass at lighting build time.

Translucent Surfaces

Reflection Captures

TLM_Surface materials receive image based reflections (specular GI) from the reflection captures placed in the level. Unlike opaque materials, only one reflection capture's cubemap is applied (no blending) which currently causes a pop if the object moves closer to another reflection capture. The cubemap is also applied as if it lies at infinity, instead of nearby, which can cause artifacts on large flat surfaces.



The left sphere is translucent, the right is opaque, and they are both setup as metals, which means 100% of the lighting comes from specular.

Per-Pixel Translucent Lighting

In the deferred renderer, the Forward Shading functionality can be used on translucent surfaces to get specular highlights from multiple lights and image-based reflections from parallax-corrected reflection captures.

To enable Per-Pixel Translucent Lighting set the Lighting Mode to Surface ForwardShading and then make sure that Screen Space Reflections are enabled.



Thin Translucency

The Thin Translucent Shading Model and its material output expression enables you to accurately represent physically based transparent materials, such as tinted or colored transparent materials that accurately respond to lighting and shading. The transparent material is able to display white specular highlights and properly tint the background in a single pass.





Enable Thin Transparency output in your materials by setting the following in the Material Details panel:



Click image for full size.

Blend Mode: Translucent

Shading Model: Thin Translucent

Lighting Mode: Surface ForwardShading

In the Material Graph, you'll want to use the Thin Translucent Material output expression node to control the color transmittance of the transparency.

Limitations

Lit translucent surfaces are missing direct specular.

Lit translucent surfaces get all their direct lighting through the translucency volume lighting texture, which causes them to be lower resolution than needed for most surface materials (glass, water).

Properties

Non-Linear Math

Linear Math

How it works

General Performance

Mobile specific

On GPU's, the vertex shader is run for every vertex, and the pixel shader is run for every pixel. Almost all the material nodes in Unreal Engine 4 are run for every pixel. While a UV Coordinate node can be either part of the vertex or pixel shader, the CustomizedUVs feature is only run in the vertex shader, and offers a performance increase over running the same calculations in the pixel shader. This offers an excellent way to speed up even just tiling a texture. While the system is not limited in the math you run on the UVs, the result will depend on the tessellation of your mesh.

Note: Customized UVs are currently only implemented for certain component types: Static Meshes, Skeletal Meshes, BSP, landscape, and mesh particles. Notably Sprite particles do not support Customized UVs yet.

Properties

In the Material Editor, you can set the number of CustomizedUVs input pins by selecting the main material node and editing the Num Customized UVs property in the Material category. If Num Customized UVs is set to a number greater than 0, CustomizedUVs pins will show on the main material node.



Non-Linear Math

The general rule is that if the computation you are doing is using constants (camera position, time, vector parameters, etc.) or varies linearly with per-vertex attributes, then doing that work in the vertex shader will give the same results as doing them in the pixel shader. Varying linearly means only operations that will result in straight lines, no curves, such as multiplication and addition. Squaring a variable, using sine, cosine, or operations like length will result in a non-linear equation.

Whether or not non-linear math will produce a desirable result will depend on the detail of the mesh it is being applied to:



The mesh on the left is a 9x9 polygon grid, while the one on the right is a 4x4 polygon grid.



Click to enlarge image.

In contrast, if this same math is directly inputted into a texture, it will be evaluated in the pixel shader producing the same result regardless of mesh detail.





Click to enlarge image.

Linear Math

Scaling (multiplying) UVs by a parameter will work the same in both. The UVs are per-vertex attributes, and scaling is a linear operation. The images below show when doing linear operations, CustomizedUVs, which are calculated in the vertex shader, produce the same effect as doing the same calculation in the pixel shader.

In this example the result is the same whether the UV tiling is caluculated in the vertex shader (with customized UVs) or in the pixel shader.



How it works

The CustomizedUV pins pass through the texture coordinates (UVs) in the mesh by default. Then when you place a Texcoord node in a pixel shader input (like BaseColor), you are still getting the mesh's texture coordinates. However, if you do something in CustomizedUV0 and then use Texcoord 0 in the BaseColor input, you will get the modified UV value. Note that Texture sample nodes use TexCoord 0 by default.

Shader Model 5 on PC can use 8 custom UVs, while OpenGL ES2 on mobile can only use 3.

Here is an example, the original material is mapping a texture using world space y and z.



This material is doing the same thing, the logic in Customized UV 0 is passed through as Texcoord0 to the BaseColor pixel shader input. However, the calculation for Texcoord0 was done in the vertex shader.



The Texture Sample node has an implicit TexCoord0 node inside.

General Performance

Most of the time, there are substantially fewer vertices than pixels, and moving any math to the vertex shader can be a big performance benefit. Note that if you are making a mesh with a very high poly count, or not making any use of LOD with high poly meshes, the extra vertex shader work can be the bottleneck. This is because the vertex shader work is the same no matter whether the mesh is off in the distance covering 4 pixels or filling up the screen.

Mobile specific

On mobile, any texture sample that manipulates the texture coordinates in any way takes a slow path. These are called dependent texture fetches. By using the customized UV inputs, you can still implement tiling or world space texture mapping while keeping all the texture fetches independent, which is the fast path.

Additionally, everything in the pixel shader on mobile is evaluated with half precision floats. This causes blocky looking textures and some other artifacts, when pixel shader math is done on texture coordinates. The Customized UV inputs however are done with full precision so they get around this problem.

Here is a cave material setup to use tiling at two different rates, but still only have independent texture samples.



Opening the Material Analyzer

Viewing the Suggestion List

Create a Local Collection

Viewing the Static Switch Parameters List

Reparenting Material Instances

The Material Analyzer is a developer tool that helps you identify and analyze all Materials, or Material instances, in your project. This enables you to make changes that can provide savings in shader permutations and data storage. When you select a Material or Material instance to analyze, the tool will find all descendants of that Material (or all descendants of the Material instance's parent Material). The tool also identifies all of the base property overrides, static switches, and static component mask parameters.

Opening the Material Analyzer

In the menu bar, click Tools > Audit > Material Analyzer. The Material Analyzer window opens.

Click the dropdown menu next to Material to Analyze. Use the list or search bar to select the Material or Material instance you want to analyze.

The Material Analyzer tool displays a list of all instances of the Material you selected.



Click to enlarge image.

Viewing the Suggestion List

Below the Material instance hierarchy is a suggestion list. The suggestion list groups all Material instances with the same set of static overrides. You can click the arrow next to each line to see the specific instances identified.

Create a Local Collection

Each suggestion list has a Create Local Collection button. Click this button to place all the related instances into a local collection, so you can easily find them and update them to have more efficient parameter setups.

Viewing the Static Switch Parameters List

To see the static switch parameters for a Material instance, click the arrow next to the Static Switch Parameters column to display the full list. The columns are resizable, so you can move them if the text is cut off.

Reparenting Material Instances

You can reparent these Material instances to a new instance that has those same static overrides, so that the reparented Material instances only change their unique overrides. This can provide a savings in shader permutations and data storage. Make sure to remove all the static parameter overrides from the Material instances you have reparented, or else the additional data is still stored.

Materials

Using Refraction

Physical vs Non-Physical Refraction Model

Pixel Normal Offset and Glass

By default, Unreal Engine uses a physically based refraction model derived from Index of Refraction values. The physical Index of Refraction model mimics the way light rays refract as they transfer between mediums. This works well for small objects, like jars, glasses, and other curved surfaces. However, when used with large flat surfaces it can produce unpredictable results and artifacts as the scene color is being read from off screen.

Pixel Normal Offset is an alternative Refraction Mode available in the Material Editor. It uses the vertex normal as a reference and then computes the refraction offset by calculating how different the per-pixel normal is from the vertex normal. This is useful for large flat surfaces, like water, where you do not want a constant offset that is reading data from off screen.

Physical vs Non-Physical Refraction Model

You can change the Refraction Mode of your Material in the Details Panel. Scroll down and expand the Refraction section, and then choose between the two options in the Refraction Mode drop-down. All Materials use Index of Refraction by default.

For additional information about the physical model of refraction, and how to use it in your Materials, you can read the page on Using Refraction.





Physical Refraction Model: Index of Refraction

Non-Physical Refraction Model: Pixel Normal Offset

The comparisons below demonstrate the differences in how the normal is read in the Material when the Refraction Mode is changed from Index of Refraction to Pixel Normal Offset.





Above you will notice that the image is shifted when using the Index of Refraction mode compared to the Pixel Normal Offset mode where you do not read from off screen so much. Note that Index of Refraction will work without a Normal map plugged into the Material, whereas with Pixel Normal Offset, if there is no Normal map you will not get any refraction.





When you add a Normal map to your Material with a value greater than 1 plugged into the Refraction input, the normal will translate along the surface when using Pixel Normal Offset. However, you will notice that with Index of Refraction, you will still have an offset that reads from off screen, which is not a desirable effect for flat surfaces using refraction.

Final Result

In this example, the refraction amount is adjusted between a value of 1.0, which is no refraction at all, to a value of 2.0, for some refraction along the surface without shifting the image while using Pixel Normal Offset.

Pixel Normal Offset and Glass

Pixel Normal Offset is also beneficial for large flat glass surfaces, such as the windows in the cafe scene below. The first image in the slider uses the default Index of Refraction setting. The window refraction is chaotic and contains an artifact in the bottom right corner. When the refraction mode is changed to Pixel Normal Offset, the windows appear much more true to life and the artifact disappears.

Move the slider to see how the glass changes when the Refraction Mode is changed from Index of Refraction (image 1) to Pixel Normal Offset (image 2).



In Pixel Normal Offset mode, the refraction in this example is extremely slight because the normal map for this glass only contains micro abrasions and minor surface imperfections. This is an expected result for clean architectural glass.

However if you wanted a textured or patterned glass effect you could use a more representative normal map and raise the Refraction value to something around 1.52.



This is how the normal map affects the refraction in the glass windows.



Instanced Materials

Mesh Drawing Pipeline

Usage and Workflow

Material Setup

Blueprint Usage

Actor Defaults Usage

Example Setup

Material Example Setup

Blueprint Example Setup

Example Result

Material Instance Dynamic Comparison

Performance

Additional Notes

With the Custom Primitive Data (CPD) workflow, you can use your Materials to store custom data in an index array that is accessible through Blueprint and code. You can use this data to effect changes for scene primitives at runtime.

This is similar to the way Material Instance Dynamics (MID) function, providing a way for you to control parts of your Material graph dynamically at runtime through Scalar and Vector Parameters. The difference is that Custom Primitive Data has the advantage of storing data on the primitives themselves rather than with the Material Instance. This lowers the number of draw calls for similarly placed geometry in your Levels (such as walls, floors, or other duplicated geometry).

Usage and Workflow

The steps below summarize how you can use Custom Primitive Data to interact with scene primitives.

Create Scalar and Vector Material Parameters to control parts of your Material logic. Enable Use Custom Primitive Data on each parameter you want to set and control dynamically.

Give each parameter with Custom Primitive Data enabled a unique Primitive Data Index in the Details Panel. You will reference this index in either Blueprint or code.

Use the Set Custom Primitive Data nodes in Blueprint to set and control the Material Parameters for the values stored in the custom data array.

Material Setup

Add Scalar and Vector Parameter expressions to your graph to control attributes of the Material, like you would in a Material Instance.

With a Parameter selected, find the Use Custom Primitive Data property in the Details Panel and enable it.



Once enabled, the parameter displays "Custom Primitive Data" below its given name along with its assigned value in the Primitive Data Index. This value is also shown on the node itself.



The Primitive Data Index value sets the assigned index this parameter is stored in. This index is used to reference the parameter in Blueprint and code.

When assigning an index on a Scalar (float) parameter, the index is a single value. When doing the same on a Vector parameter, each channel in the parameter is assigned a different value in the Primitive Data Index. In the image above, the Scalar Parameter is assigned to Index 0, while the Vector Parameter is assigned to Index 1, 2, 3, and 4. One index value for each RGBA output.

Blueprint Usage

You can access scene primitives that use Custom Primitive Data through Blueprint with the following nodes.

Set Custom Primitive Data Float

Set Custom Primitive Data Vector

These nodes require no string-matching to parameter names. Instead, they use the assigned Primitive Data Index to set and get data in the array per primitive.



Accessing custom data in this array from a Material is similar to working with Material Parameters in a Material Instance. The difference is that on Parameter nodes, the parameter in the Material must be a string-matched uniform rather than matching a numbered index.

Actor Defaults Usage

You can setup Custom Primitive Data Default values for an Actor by selecting its Static Mesh Component in the Details panel and expanding the Custom Primitive Data Defaults section. Use the Plus (+) icon to add elements to the array. The array will populate with named Custom Data Parameters from your Material, along with their Primitive Data Index value.



Each numbered array element references the Custom Primitive Data Index with the corresponding value. If an index does not exist for the array element, it is ignored. Setting defaults using this method is ideal when you want to manually adjust some values without attaching a Blueprint or making a Material Instance to control them.

Example Setup

The following example demonstrates use with a simple Material that is driven by several parameters—both Scalar and Vector—to randomly select a color from a Vector Parameter and set the emissivity and object scale of the mesh in the scene. Blueprint is used to drive these three parameters for the stored custom data.

Material Example Setup

For the Material setup, Use Custom Primitive Data is enabled on three parameters in this Material graph.





Click image for full size.



The Base Color and Emissive intensity are driven by two parameters; a Vector 4 Parameter called "Color Param", and a Scalar Parameter called "Emissive Power."





Click image for full size.



The second part of this graph uses logic to uniformly scale the mesh it's assigned to in the Level. The scalar parameter called "Scale_XYZ" controls how much the assigned object is scaled.





Click image for full size.



Blueprint Example Setup

Custom Data on parameters, much like Material Instance Dynamics, provide a way to make changes using Blueprint or code at runtime. The graph below sets and updates values in these Material parameters to randomize the color, emissivity, and initial scale during gameplay.





Click image for full size.



On Event BeginPlay, Set Custom Primitive Data nodes are used to set the initial values for the color, scale, and emissivity parameters. The Data Index property determines which Material Parameter is targeted by that node.





Click image for full size.



For example, the Emissive Power parameter is assigned to Index 4, so its value will be set by the Blueprint node that targets Data Index 4.



On Event Tick, the Set nodes reference the Primitive Data Index for each Custom Primitive Data Parameter. A new color, emissive intensity, and scale are set at the interval defined in the Delay node. The color is set by combining three random float values into a Vector 4. The emissive power and scale are randomized with the Random Float in Range nodes.





Click image for full size.



Be careful when setting up and using Event Tick. For the purposes of this demonstration, it's good for quick tests and debugging, but is not always best for continuous use at runtime.

Example Result

The result of this example is a Material with three Custom Primitive Data parameters that are controlled by Blueprint to set the color, emissive power, and scale of the Mesh. The values are set at runtime, and then updated randomly every 0.5 seconds, as defined in the Blueprint.

Material Instance Dynamic Comparison

The setup and usage of Custom Primitive Data is similar to that of Material Instance Dynamics. This section compares the Material and Blueprint setup required for each of these to better demonstrate how they are alike and different.

When creating Material Instance Dynamics, the name of the parameter is all that is needed later in Blueprint. The Custom Primitive Data workflow requires that the Use Custom Primitive Data option is enabled on each parameter, and that a unique Primitive Data Index value is assigned, which is referenced in Blueprint later.





MID Material Parameters

Custom Primitive Material Parameters

The following images compare the Blueprint setups for Material Instance Dynamics and Custom Primitive Data.

Material Instance Dynamics Workflow:





Click image for full size.



For additional information on instancing with Materials, see Instanced Materials.

Custom Primitive Data Workflow:





Click image for full size.



The workflow is similar, with the exception that there are some additional steps to take in Blueprint. The MID workflow requires the Create Dynamic Material Instance node and some Set Parameter Value nodes that reference the string-matched Parameter Name found in the Material for the wanted parameter.

If both of these setups are compared in the Level at runtime, they are visually identical. However, Custom Primitive Data comes with performance-saving benefits using the mesh drawing refactor that is covered in the section below.

The cluster of four spheres on the left side of the video use Custom Primitive Data, while the four spheres on the right use Material Instance Dynamics. Note that the result is visually identical.

Performance

The Custom Primitive Data workflow has the advantage of significantly reducing draw calls for similar geometry in your Level when it is using a Material set up with custom data. Draw calls are reduced using the Mesh Drawing refactor that automatically dynamically instances scene primitives.

To check how well dynamic instancing is working for your Level, open the console (`) and enter the command stat scenerendering.

This command shows general rendering statistics for your current scene view. It is a good starting point to finding general areas of slow performance in the rendering process, along with counters for the number of mesh draw calls and lights in the scene.



Default Level scene rendering stats

While working in the Level viewport, press the G key to toggle Game View mode, or choose to Play-In-Editor (PIE) or Simulation to get more accurate results. When not using one of these options, other draw calls are being attributed to Editor-only geometry, like icons for the Directional Light.

In this example scene, we start with a floor mesh, the sky sphere mesh in the background, and several duplicated meshes using custom data in their Materials.



The scenerendering stats shows the number of draw calls registered in this current view—14 in total.



Because the engine automatically dynamically combines draw calls with the Mesh Drawing Policy, it's good to disable dynamic instancing to see how well it's currently working for this scene. Disable it with the following command:

Notice that the number of Mesh draw calls has increased with just a few primitives:



To see a more dramatic difference, let's duplicate the meshes some more that are using Custom Primitive Data; 25 spheres with varying sizes, in this case.



With dynamic instancing disabled, there are 94 Mesh draw calls. Using Material Instance Dynamics will give you a similar result because they are not instanced liked Custom Primitive Data.



Reenabling dynamic instancing now shows 46 Mesh draw calls.



When storing custom data in your Materials and using similar geometry in your Level, you can clearly get a difference in the number of draw calls, even over using alternative methods like Material Instance Dynamics.

Additional Notes

Float Limit of 32

In a future release, we'll look at making this a Project Setting as a configurable setting.

Support for user-defined default and override of Custom Primitive Data parameter values

Currently, when setting up a Custom Primitive Data parameter in your Material, the default value is always 0. If you want an initial value set while working in the editor, you can do this using the Construction Script in Blueprint for the mesh that the Material is assigned to.

Top Rendering Features of UE5 Quick Reference

Post Processing

General Engine Features

Lighting Features

Light Type and Mobility Features

Materials and Textures

The tables found in this page lists features of Unreal Engine 5 and the rendering paths they support.

The features listed in this page are intended to give you a general idea of what features are supported by the different rendering paths available in Unreal Engine 5. Some features may not fully support a rendering path, even if it indicates it does. It's recommended to check the documentation for each feature in cases where it may not be clear. For example, in the case of Lumen, Nanite, Virtual Shadow Maps, and Ray Tracing.

Top Rendering Features of UE5 Quick Reference

The following table is a quick reference of selected new Unreal Engine 5 features and their supported rendering paths.

Some features of Unreal Engine 5 require DirectX 12 with Shader Model 6 (SM6) to work, such as Nanite and Virtual Shadow Maps. Refer to Hardware and Software Specifications more specific requirements.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Lumen Global Illumination: Software Ray Tracing

Y

Y

N

Y

N

Lumen Global Illumination: Hardware Ray Tracing

Y

N

N

Y

N

Nanite Virtualized Geometry

Y

N

N

Y

N

Virtual Shadow Maps

Y

N

N

Y

N

Temporal Super Resolution

Y

Y

N

Y

Y

Path Tracer

Y

N

N

N

N

Post Processing

Post Processing enables artists to control the overall look and feel of their scene using placed volumes. Each volume contains lighting and rendering features that affect the look of the scene for things such as type of global illumination and reflections that are used, color grading, amongst other lighting effects.

See Post Process Effects to learn more about the available post-processing options.

Lens

The Lens category contains properties that affect the look of the scene that can be created by a camera lens. For example, things like lens flare, depth of field, exposure, and other similar types of effects.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Mobile Depth of Field Properties

N

N

N

N

N

Mobile Depth of Field: High Quality Gaussian

N

N

N

N

N

Bloom: Standard

Y

Y

Y

Y

Y

Bloom: Convolution

Y

Y

Y

Y

Y

Exposure

Y

Y

Y

Y

Y

Chromatic Aberration Properties

Y

Y

Y

Y

Y

Dirt Mask Properties

Y

Y

Y

Y

Y

Camera Properties

Y

Y

Y

Y

Y

Local Exposure

Y

Y

Y

Y

Y

Lens Flare Properties

Y

Y

Y

Y

Y

Image Effects: Vignette

Y

Y

Y

Y

Y

Depth of Field Properties

Y

Y

Y

Y

Y

Color Grading

The Color Grading category enables color styling and color palettes to be applied on top of the rendered scene without making direct changes to the content in the scene itself. Artistic choices can be made to adjust things such as color temperature, saturation, contrast, and more. Color grading can also be used to adjust those highlights, midtones, or even shadows without being destructive to the content in the scene.

See Color Grading to learn more.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Color Grading Properties

Y

Y

Y

Y

Y

Film

The Film category enables artistic choices to map the scene colors to match those of the Academy Color Encoding System (or ACES) standard.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Film Properties

Y

Y

Y

Y

Y

Post Process Global Illumination

The Global Illumination category primarily contains properties for selecting the type of global illumination to use for the Post Process Volume.

For general support of Global Illumination features, see the General Engine Features section of this page.

Post Process Reflections

The Reflections category primarily contains properties for selecting the type of reflections to use for the Post Process Volume.

For general support of Reflections features, see the General Engine Features section of this page.

Rendering Features

The Rendering Features category contains features that are specific to the Post Process Volume, such as controlling motion blur, screen space reflection, and ambient occlusion. It also provides configurable settings for features such as Hardware Ray Tracing and the Path Tracer.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Post Process Material Properties

Y

Y

Y

Y

Y

Ambient Cubemap Properties

Y

Y

N

Y

N

Ambient Occlusion Properties

Y

Y

Y

Y

Y

Global Illumination Properties

Y

Y

Y

Y

Y

Reflections Properties

Y

Y

Y

Y

Y

Motion Blur Properties

Y

Y

Y

Translucency Type: Raster

Y

Y

Y

Y

Y

Translucency Type: Ray Tracing

Y

N

N

N

N

Ray Tracing Translucency Properties

Y

N

N

N

N

Path Tracing Properties

Y

N

N

N

N

For Ray Tracing and Path Tracer features that have additional requirements, see Hardware Ray Tracing and Path Tracing for complete specifications.

Film Grain

The Film Grain category contains properties that give an intentionally film-like appearance to the scene. Film grain can be a purely visual choice that adds realism to your project with a cinematic look.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Film Properties

Y

Y

Y

Y

Y

General Engine Features

The following are listings of features supported across the various rendering paths available in Unreal Engine.

Anti-Aliasing

Anti-Aliasing techniques are used to smooth or remove the jagged edges in a rendered image. There are multiple anti-aliasing techniques to choose from, with some being better suited for specific hardware and platforms.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Temporal Super Resolution

Y

Y

Y

Y

Y

Fast Approximation Anti-Aliasing (FXAA)

Y

N

Y

N

Y

Multi-Sample Anti-Aliasing (MSAA)

Y

Y

Y

Y

Y

Temporal Anti-Aliasing (TAA)

Y

Y

Y

Y

Y

Systems and Tools Features

The following are general features of Unreal Engine 5 that work in conjunction with other parts of the engine, for example materials and lighting.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Nanite Virtualized Geometry

Y

N

N

N

N

Hardware Ray Tracing Features

Y

N

N

Y

N

Path Tracer

Y

N

N

N

N

Texture Streaming

Y

Y

Y

Y

Y

Virtual Textures: Streaming

Y

Y

Y

Y

Y

Virtual Textures: Runtime

Y

Y

Y

Y

Y

Mesh Decals

Y

Y

Y

Y

Y

Mesh Distance Fields

Y

Y

Y

Y

Y

Water System

Y

Y

Y

Y

Y

Hair and Fur Grooms

Y

Y

Y

Y

Y

Level of Detail

Level of Detail (or LOD) is an optimization whereby lowering geometric detail of objects at specified distances from the camera has the potential to improve performance. This includes material-based transitions that can reduce the visual switching (or popping that occurs) when swapping between the levels of detail.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Level of Detail

Y

Y

Y

Y

Y

Hierarchical Level of Detail

Y

Y

Y

Y

Y

Dither LOD Transition

Y

Y

Y

Y

Y

Visibility and Occlusion Culling

Different Visibility and Occlusion Culling methods are used to reduce the number of rendered objects in the scene to improve performance. Culling is handled in a few different ways depending on the chosen method: size and distance, and visibility from the player camera. Some methods are only available — even, better suited — for some platforms over others. Some culling methods can be used in conjunction with another method.

See Visibility and Occlusion Culling to learn more about them.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Cull Distance Volumes

Y

Y

Y

Y

Y

Precomputed Visibility Volumes

Y

Y

Y

Y

Y

Hardware (GPU) Occlusion Queries

Y

Y

Y

Y

Y

Lighting Features

The following lighting features are supported across Unreal Engine's rendering paths.

To learn more about all of Unreal Engine's lighting features, see Lighting the Environment.

Environmental Lighting and Effects

Lighting for large open worlds requires features that seamlessly work together to create a unified experience. These include components for creating atmosphere, clouds, fog, and fully supported dynamic lighting from the sun and moon.

See Environmental Lighting to learn more about them.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Sky Atmosphere

Y

Y

Y

Y

Y

Volumetric Clouds

Y

Y

Y

Y

Y

Exponential Height Fog

Y

Y

Y

Y

Y

Volumetric Fog

Y

Y

Y

Y

Y

Global Illumination

Global Illumination simulates lighting interactions with geometry and material surfaces to add accurate-looking lighting to a scene. Unreal Engine provides precomputed and dynamic global illumination methods. See Global Illumination to learn more about them.

See Global Illumination to learn more about them.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Lumen Global Illumination: Software Ray Tracing

Y

Y

N

N

N

Lumen Global Illumination: Hardware Ray Tracing

Y

N

N

N

N

Precomputed Global Illumination with Lightmass

Y

Y

Y

Y

Y

Screen Space Global Illumination

Y

Y

N

Y

N

Ray Tracing Global Illumination (Deprecated)

Y

N

N

Y

N

Some features of Hardware Ray Tracing have been deprecated and may be removed in later versions of the engine. Lumen Global Illumination is the replacement for these features.

Shadowing

Shadows enables objects to feel grounded in the world, while providing a sense of depth and space. Unreal Engine provides different methods for shadowing objects in your projects, with some shadowing methods being better suited specific platforms and hardware.

See Shadowing to learn more about them.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Standalone Hardware Ray Traced Shadows

Y

N

N

Y

N

Virtual Shadow Maps

Y

N

N

Y

N

Modulated Shadows

Y

Y

Y

Y

Y

Capsule Shadows

Y

Y

N

Y

N

Contact Shadows

Y

Y

N

Y

N

Precomputed Translucent Shadows

Y

Y

Y

Y

Y

Dynamic Translucent Shadows

Y

Y

N

Y

N

Reflections

Reflections are another way to ground objects in the world and add a sense of realism. Reflections start with rough or smooth the materials applied to surfaces are. The smoother a material, the more a surface can reflect light that hits it.

Unreal Engine provides different methods of reflections for materials that include precomputed static reflections and fully dynamic reflections to choose from for your project. Not all reflection systems are exclusive to itself and some can be used together with one another.

See Reflections Environment to learn more about them.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Reflection Captures (Box/Sphere)

Y

Y

Y

Y

Y

Scene Capture Cubemap

Y

Y

Y

Y

Y

Scene Capture 2D

Y

Y

Y

Y

Y

Planar Reflections

Y

Y

Y

Y

Y

Screen Space Reflections

Y

Y

N

Y

N

Standalone Hardware Ray Traced Reflections (Deprecated)

Y

N

N

N

N

High Precision Normals

Y

Y

Y

Y

Y

Reflection Capture Resolution

Y

Y

Y

Y

Y

HDR Cubemaps

Y

Y

Y

Y

Y

Some features of Hardware Ray Tracing have been deprecated and may be removed in later versions of the engine. Lumen Global Illumination is the replacement for these features.

Light Type and Mobility Features

When thinking about how to light your project, you want to consider all the various types of lights you may need and whether they need to be fully, partially static and dynamic, or fully dynamic. When deciding the type of light to use, it is just as important to think about how that light will be used and if it needs to dynamically change or not, which can have an impact on how your project looks and interacts with objects being lit, and with performance.

See Light Types and Their Mobility for more information on using the different types of lights and how their mobility affects them.

Static Lighting

This section includes a breakdown of what types of lights and their common features are supported when using precomputed Static Light Mobility.

For more details, see Static Light Mobility.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward



Static Mobility: Light Types



Directional Light

Y

Y

Y

Y

Y

Sky Light

Y

Y

Y

Y

Y

Point Light

Y

Y

Y

Y

Y

Spot Light

Y

Y

Y

Y

Y

Rect Light

Y

Y

Y

Y

Y



Static Mobility: General Lighting Features



Indirect Lighting Intensity

Y

Y

Y

Y

Y

Lighting Channels

Y

Y

Y

Y

Y

Light Transmission

Y

Y

N

Y

N

Light Functions

Y

Y

N

Y

N



Static Mobility: Directional Light Features



Source Angle

Y

Y

Y

Y

Y

Light Shafts

Y

Y

N

Y

N

Modulated Shadows

N

N

N

N

N



Static Mobility: Sky Light Features



SLS Captured Scene

Y

Y

Y

Y

Y

SLS Specified Cubemap

Y

Y

Y

Y

Y

Specified Cubemap Resolution

Y

Y

Y

Y

Y



Static Mobility: Point, Spot, Rect Light Features



IES Textures

Y

Y

Y

Y

Y

Rect Light: Source Texture

Y

Y

Y

Y

Y

Stationary Lighting

This section includes a breakdown of what types of lights and their common features are supported when using Stationary Light Mobility.

For more details, see Stationary Light Mobility.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward



Stationary Mobility: Light Types



Directional Light

Y

Y

Y

Y

Y

Sky Light

Y

Y

Y

Y

Y

Point Light

Y

Y

Y

Y

Y

Spot Light

Y

Y

Y

Y

Y

Rect Light

Y

Y

Y

Y

Y



Stationary Mobility: General Lighting Features



Indirect Lighting Intensity

Y

Y

Y

Y

Y

Lighting Channels

Y

Y

Y

Y

Y

Light Transmission

Y

Y

N

Y

N

Light Functions

Y

Y

N

Y

N



Stationary Mobility: Directional Light Features



Source Angle

Y

Y

Y

Y

Y

Cascaded Shadow Maps

Y

Y

Y

Y

Y

Light Shafts

Y

Y

N

Y

N

Modulated Shadows

N

N

N

N

N



Stationary Mobility: Sky Light Features



SLS Captured Scene

Y

Y

Y

Y

Y

SLS Specified Cubemap

Y

Y

Y

Y

Y

Specified Cubemap Resolution

Y

Y

Y

Y

Y



Stationary Mobility: Point, Spot, Rect Light Features



IES Textures

Y

Y

Y

Y

Y

Rect Light: Source Texture

Y

Y

Y

Y

Y

Movable Lighting

This section includes a breakdown of what types of lights and their common features are supported when using Movable Light Mobility.

For more details, see Movable Light Mobility.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward



Movable Mobility: Light Types



Directional Light

Y

Y

Y

Y

Y

Sky Light

Y

Y

Y

Y

Y

Point Light

Y

Y

Y

Y

Y

Spot Light

Y

Y

Y

Y

Y

Rect Light

Y

Y

Y

Y

Y



Movable Mobility: General Lighting Features



Indirect Lighting Intensity

Y

Y

Y

Y

Y

Lighting Channels

Y

Y

Y

Y

Y

Light Transmission

Y

Y

N

Y

N

Light Functions

Y

Y

N

Y

N



Movable Mobility: Directional Light Features



Source Angle

Y

Y

N

Y

N

Cascaded Shadow Maps

Y

Y

Y

Y

Y

Light Shafts

Y

Y

N

Y

N

Modulated Shadows

N

N

N

N

N

Distance Field Shadows

Y

Y

Y

Y

Y



Movable Mobility: Sky Light Features



SLS Captured Scene

Y

Y

Y

Y

Y

SLS Specified Cubemap

Y

Y

Y

Y

Y

Specified Cubemap Resolution

Y

Y

Y

Y

Y



Movable Mobility: Point, Spot, Rect Light Features



IES Textures

Y

Y

Y

Y

Y

Rect Light: Source Texture

Y

Y

N

Y

N

Materials and Textures

Materials and Textures are applied to surfaces to control the visual representation of a surface and typically how it interacts with lighting. There are a variety of material and texture types that can be used in your projects.

See Materials and Textures to learn about them.

Material Domain

The Material Domain defines what the material will be used for in your project.

See Material Properties for more information.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Surface

Y

Y

Y

Y

Y

Deferred Decal

Y

Y

Y

Y

Y

Light Function

Y

Y

N

Y

N

Volume

Y

Y

Y

Y

Y

Post Process

Y

Y

Y

Y

Y

User Interface

Y

Y

Y

Y

Y

Material Blend Mode

The Blend Mode describes how the output of the current material will blend over what is already being drawn in the background. It allows you to control how the engine will combine this material (source color) with what is already in the frame buffer (destination color) when rendered.

See Material Properties for more information.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Opaque

Y

Y

Y

Y

Y

Masked

Y

Y

Y

Y

Y

Translucent

Y

Y

Y

Y

Y

Additive

Y

Y

Y

Y

Y

Modulate

Y

Y

Y

Y

Y

Alpha Composite (Premultiplied Alpha)

Y

Y

Y

Y

Y

Alpha Holdout

Y

Y

Y

Y

Y

Material Shading Model

The Shading Model determines how material inputs are combined to make the final color.

See Shading Models for more information.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Unlit

Y

Y

Y

Y

Y

Default Lit

Y

Y

Y

Y

Y

Subsurface

Y

Y

Y

Y

Y

Preintegrated Skin

Y

Y

Y

Y

Y

Clear Coat

Y

Y

Y

Y

Y

Subsurface Profile

Y

Y

Y

Y

Y

Two Sided Foliage

Y

Y

Y

Y

Y

Hair

Y

Y

Y

Y

Y

Cloth

Y

Y

Y

Y

Y

Eye

Y

Y

Y

Y

Y

Single Layer Water

Y

Y

Y

Y

Y

Thin Translucent

Y

Y

Y

Y

Y

From Material Expression

Y

Y

Y

Y

Y

Material Inputs

Material Inputs are the inputs being fed data through the Main Material node to define surface properties and how they interact with light. The types of inputs available are determined by the materials set domain, blend mode, and shading model.

See Material Inputs to learn more about them.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Base Color

Y

Y

Y

Y

Y

Metallic

Y

Y

Y

Y

Y

Specular

Y

Y

Y

Y

Y

Roughness

Y

Y

Y

Y

Y

Anisotropy

Y

Y

Y

Y

Y

Emissive Color

Y

Y

Y

Y

Y

Opacity

Y

Y

Y

Y

Y

Normal

Y

Y

Y

Y

Y

Tangent

Y

Y

Y

Y

Y

World Position Offset

Y

Y

Y

Y

Y

Cloth

Y

Y

Y

Y

Y

Fuzz Color

Y

Y

Y

Y

Y

Iris Mask

Y

Y

Y

Y

Y

Iris Distance

Y

Y

Y

Y

Y

Subsurface Color

Y

Y

Y

Y

Y

Custom Data 0 – 7

Y

Y

Y

Y

Y

Ambient Occlusion

Y

Y

Y

Y

Y

Refraction

Y

Y

Y

Y

Y

Pixel Depth Offset

Y

Y

Y

Y

Y

Shading Model

Y

Y

Y

Y

Y

Clear Coat

Y

Y

Y

Y

Y

Clear Coat Roughness

Y

Y

Y

Y

Y

Backlit (for Hair)

Y

Y

Y

Y

Y

Textures

Textures are image assets that are primarily used in Materials but can also be directly applied to components in some situations. For Materials, textures are mapped to surfaces which the material is applied to. Textures can be used for a variety of calculations within a Material, such as a base color, normal map, and mask.

See Textures for more information on using them.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Default (DXT 1/5, BC ⅓ on DX11)

Y

Y

Y

Y

Y

Normal Map (DXT 5, BC5 on DX11)

Y

Y

Y

Y

Y

Masks (no sRGB)

Y

Y

Y

Y

Y

Grayscale (R8, RGB8, sRGB)

Y

Y

Y

Y

Y

Displacement Map (8/16-bit)

Y

Y

Y

Y

Y

Vector Displacement Map (RGBA8)

Y

Y

Y

Y

Y

HDR (RGB, no sRGB)

Y

Y

Y

Y

Y

User Interface 2D (RGBA)

Y

Y

Y

Y

Y

Alpha (no sRGB, BC4 on DX11)

Y

Y

Y

Y

Y

Distance Field Font (R8)

Y

Y

Y

Y

Y

HDR Compressed (RGB, BC6H, DX11)

Y

Y

Y

Y

Y

BC7 (DX11, optional A)

Y

Y

Y

Y

Y

Half Float (R16F)

Y

Y

Y

Y

Y

Decals

Decals are Materials that are projected surfaces in your Level. Decals can even be applied to some geometry as a placed mesh decal.

Property

Desktop Deferred (SM5/SM6: DirectX 12, macOS, Vulkan Desktop)

Desktop Deferred (SM5: DirectX 11, macOS Metal, Vulkan Desktop)

Desktop Forward

Desktop XR Deferred

Desktop XR Forward

Mesh Decals

Y

Y

Y

Y

Y

Material Decal Response (DBuffer): Color Normal Roughness

Y

Y

Y

Y

Y

Material Decal Response (DBuffer): Color

Y

Y

Y

Y

Y

Material Decal Response (DBuffer): Color Normal

Y

Y

Y

Y

Y

Material Decal Response (DBuffer): Color Roughness

Y

Y

Y

Y

Y

Material Decal Response (DBuffer): Normal

Y

Y

Y

Y

Y

Material Decal Response (DBuffer): Normal Roughness

Y

Y

Y

Y

Y

Material Decal Response (DBuffer): Roughness

Y

Y

Y

Y

Y

Getting Started and Tutorials

Niagara Features

Debugging and Optimization in Niagara

Reference

The Niagara VFX System is the primary tool to do visual effects (VFX) inside Unreal Engine 5 (UE5).

This page links to documentation regarding the Niagara VFX system, including an Overview and a Quick Start guide to get you up and running. If you are new to Niagara, it is recommended that you check out the Getting Started section which includes a high-level overview of the Niagara Editor, the Quick Start Guide, and a page that lays out the Key Concepts and design philosophy behind Niagara.

You can also check out the Tutorials section, which has step-by-step project guides.

The Reference section has the System and Emitter Module Reference, the Niagara Editor UI Reference, and the Niagara Script Editor UI Reference.

Getting Started and Tutorials

The Getting Started page will help you learn Niagara for the first time. Here you will find pages such as an overview of Niagara, key concepts that describe the architecture, and quickstart tutorials to start your very first projects.

To go a step further, check out more tutorials that will walk you step-by-step in creating a few projects. By practicing with some different effects, you can quickly get the hang of how to build Niagara systems.



This page collects all the getting started learning materials for Niagara.



A collection of tutorials for creating projects with the Niagara visual effects system.

Niagara Features

Explore these Niagara features in more depth to learn about the capabilities of the system. Learn about Fluids, or the experimental GPU Raytracing Collisions module.

For advanced users, the modules that are supplied with Niagara to start with may not be sufficient to achieve the full effect you are looking for. You can use the Niagara Script Editor to adjust existing modules or create your own.



Learn how to create real-time fluid effects like fire, smoke, gas, and more.



Learn all about collisions in Niagara.



This page collects all the pages that will teach you how to create custom modules in Niagara.

Debugging and Optimization in Niagara

As you start to play around with the tools, you may want to start to refine your Niagara simulations. The Debug Drawing tool helps to visualize some components of supported modules. The Niagara Debugger runs real-time analyses of performance on simulations in your level.



Learn how to debug and optimize your Niagara simulations.

Reference

Finally, for any detailed questions you may have about the user interface, specific buttons, or modules, check out the Reference pages.



This page collects all the reference pages for Niagara.

Niagara Overview Pages

Niagara Quick-Start Tutorials

Additional Information to Get You Started

To get started in Niagara, the following materials are available to you.

Niagara Overview Pages

These page goes over the basics of Niagara. They describes the basic building blocks of Niagara systems, emitters, and modules. They also provide some information on how to create Niagara systems and emitters. Read them to learn all about the design philosophy.



This page gives an overview of the Niagara VFX system in Unreal Engine 5.



This page explains the key concepts and design philosophy behind Niagara.



This page gives basic information about using Events and Event Handlers in Niagara.

Niagara Quick-Start Tutorials

These Quick Start guides are step-by-step tutorials that take you through creating your first Niagara projects. Learn how to create an effect and attach it to an animation. Learn how to bake a Niagara system into a flipbook.



A guide to help you quickly start using the Niagara visual effects system.



A quick start guide for creating Niagara flipbooks in Unreal Engine.

Additional Information to Get You Started

These pages are targeted for users with different types of projects. Check the Cascade to Niagara Converter Plugin page if you are migrating from Cascade. Read through the Large World Coordinates page if you are planning to create a large project.



This page discusses and demonstrates the plugin to convert Cascade particle systems to Niagara particle systems.



An overview of how to use the Large World Coordinate System with Niagara.

Core Niagara Components

Systems

Emitters

Modules

Parameters and Parameter Types

Templates, Wizards, and Behavior Examples

System Wizard

Emitter Wizard

Niagara VFX Workflow

Create Systems

Create or Add Emitters

Create or Add Modules

Niagara Paradigms

Inheritance

Dynamic Inputs

Micro Expressions

Events

Data Interfaces

Houdini

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Niagara is Unreal Engine's next-generation VFX system. With Niagara, the technical artist has the ability to create additional functionality on their own, without the assistance of a programmer. The system is adaptable and flexible. Beginners can start out by modifying templates or behavior examples, and advanced users can create their own custom modules.

Core Niagara Components

In the Niagara VFX system, there are four core components:

Systems

Emitters

Modules

Parameters

Systems

A Niagara system is a container for everything you will need to build that effect. Inside that system, you may have different building blocks that stack up to help you produce the overall effect.

You can modify some system-level behaviors that will then apply to everything in that effect.



The Timeline panel in the System Editor shows which emitters are contained in the system, and can be used to manage those emitters.

Emitters

Emitters are where particles are generated in a Niagara system. An emitter controls how particles are born, what happens to that particles as they age, and how the particles look and behave.

The emitter is organized in a stack. Inside that stack is several groups, inside which you can put modules that accomplish individual tasks. The groups are as follows.



Emitter Spawn

This group defines what happns when an emitter is first created on the CPU. Use this group to define initial setups and defaults.

Emitter Update

This group defines emitter-level modules that occur every frame on the CPU. Use this group to define spawning of particles when you want them to continue spawning on every frame.

Particle Spawn

This group is called once per particle, when that particle is first born. This is where you will want to define the initialization details of the particles, such as the location where they are born, what color they are, their size, and more.

Particle Update

This group is called per particle on each frame. You will want to define here anything that needs to change frame-by-frame as the particles age. For example, if the color of the particles is changing over time. Or, if the particles are affected by forces like gravity, curl noise, or point attraction. You may even want the particles to change size over time.

Event Handler

In the Event Handler group, you can create Generate events in one or more emitters that define certain data. Then you can create Listening events in other emitters which trigger a behavior in reaction to that generated event.

Render

The last group is the Render group. This is where you define the display of the particle and set up one or more renderers for your particles. You may want to use a Mesh renderer if you want to define a 3D model as the basis of your particles, upon which you could apply a material. Or, you may want to use a sprite renderer and define your particles as 2D sprites. There are many different renderers to choose from and experiment with.

Modules

Modules are the basic building blocks of effects in Niagara. You add modules to groups to make a stack. Modules are processed sequentially from top to bottom.



You can think of a module as a container for doing some math. You pass some data into the module, then inside the module you do some math on that data, and then you write that data back out at the end of the module.

Modules are built using High-Level Shading Language (HLSL), but can be built visually in a Graph using nodes. You can create functions, include inputs, or write to a value or parameter map. You can even write HLSL code inline, using the CustomHLSL node in the Graph.

You can double-click any module from an emitter in Niagara to take a look at the math that's happening inside. You can even copy and create your own modules. For example, if you double-click on the Add Velocity module to take a look inside, you can inspect the data flow.



Click image for full size.

The script starts by retrieving inputs - the velocity input and the coordinate space. It then gets the current velocity of the particles, as well as an inputted scaling factor. Then, the input velocity is scaled, transformed in the correct coordinate space, and added to the current velocity of the particles. Once that work is complete, the new particle velocity is written back out so that any modules that need velocity information further on down the stack can retrieve it.

All modules are built with that basic methodology, though for some the internal math may be more complex.

Parameters and Parameter Types

Parameters are an abstraction of data in a Niagara simulation. Parameter types are assigned to a parameter to define the data that parameter represents. There are four types of parameters:

Primitive: This type of parameter defines numeric data of varying precision and channel widths.

Enum: This type of parameter defines a fixed set of named values, and assumes one of the named values.

Struct: This type of parameter defines a combined set of Primitive and Enum types.

Data Interfaces: This type of parameter defines functions that provide data from external data sources. This can be data from other parts of UE4, or data from an outside application.



You can add a custom parameter module to an emitter by clicking the Plus sign icon (+) and selecting Set new or existing parameter directly. This adds a Set Parameter module to the stack. Click the Plus sign icon (+) on the Set Parameter module and select Add Parameter to set an existing parameter, or Create New Parameter to set a new parameter.

Templates, Wizards, and Behavior Examples

When you first create a Niagara emitter or Niagara system, a dialog displays offering several options for what kind of emitter or system you want to create.

You can change any of the parameters in the template. You can add, modify or delete any of the modules. In a system template, you can also add, modify or delete any of the emitters. Templates are just there to jumpstart your creativity and give you something that you can work with immediately.

System Wizard

To create a new Niagara system, right-click in the Content Browser and locate FX > Niagara System.



Click image for full size.

The System Wizard offers the following options for creating a new system:

New system from selected emitters: If you select this option and click Next, a list of available emitters displays. This list includes both existing emitters in your project and template emitters. Select the emitters you want to include in the new system, and click the green Plus sign icon (+) to add them. Then click Finish to create the system. If you choose an existing emitter, the system will inherit from those emitters. If you choose a template emitter, the system will have no inheritances. Also, the template emitter is an instance that can either be strictly local to that system, or you can save it as a separate emitter asset.



Click image for full size.

New system from a template or behavior example: If you select this option and click Next, you can choose from a list of templates or behavior examples that represent several commonly used effect systems. As with emitter templates, this list can be curated by art leads or creative directors. If you are new to UE, this option will give you an example of how FX systems are built in Niagara. Behavior Examples are simple examples designed to feature one, isolated aspect of the Niagara system you can examine to help demystify that behavior.



Click image for full size.

Copy existing system: If you select this option and click Next, a list of existing systems displays. Choose one of them to copy, then click Finish.



Click image for full size.

Create empty system: If you select this option, your system contains no emitters or emitter templates. This option is useful if you want to create a system that is totally different from your other systems.



Click image for full size.

Emitter Wizard

To create a new emitter, right-click in the Content Browser and select FX > Niagara Emitter.



Click image for full size.

The Emitter Wizard offers the following options for creating a new emitter:

New emitter from a template: If you select this option, you can choose from a list of templates that present several types of commonly used effects. In a large development studio, art leads or creative directors can curate the list of templates, ensuring that the company's best practices are baked into the templates. These templates also offer a great starting place if you are new to UE.



Click image for full size.

Inherit from an existing emitter: If you select this option, you can create a new emitter that inherits properties from an existing emitter. This option makes the new emitter a child of the existing emitter you selected. If you need many emitters that all have certain properties in common, this is a good option to choose. You can make changes to the parent emitter, and all child emitters will reflect those changes. Select from a parent emitter to use this option.



Click image for full size.

Copy existing emitter: If you select this option, you can create a new emitter that is a copy of an emitter you already created. This can be useful if you need to create several similar emitters. Click Next after selecting this option, and a list of available emitters displays. You can then choose which one you want to copy.



Click image for full size.

Niagara VFX Workflow

Create Systems

First create a Niagara System in which you can add one or more emitters. You can then set up the properties of each emitter.

Create or Add Emitters

In the Niagara Editor, you can adjust your emitter by changing the properties of the modules already in it, or add new modules for the desired effect. You can also copy emitters and add multiple emitters into a single Niagara system. For an example of this, see the Sparks tutorial.

Create or Add Modules

In your emitter, you can add existing modules from Niagara by clicking on the Plus (+) of the group where you want to add the module. Niagara comes with a lot of pre-existing modules, and for the majority of circumstances you will be able to create your effects without needing to do any custom module design.

However, if you want to create your own modules, it can be helpful to understand how the data flows through a module.



Data flow through a module. Click image for full size.

Modules accumulate to a temporary namespace, then you can stack more modules together. As long as they contribute to the same attribute, the modules will stack and accumulate properly.

When writing a module, there are many functions available for you to use:

Boolean operators

Math expressions

Trigonometry expressions

Customized functions

Nodes that make boilerplate functions easier

Once you create a module, anyone else can use it.

Modules all use HLSL. The logic flow is as follows:



HLSL logic flow. Click image for full size.

Remember that each module, emitter and system you create uses resources. To conserve resources and improve performance, look through the modules already included in Niagara to see if you can accomplish your goal without creating a new module. Dynamic Inputs can be used to great effect here.

Niagara Paradigms

Inheritance

With a flat hierarchy, you cannot effectively locate and use the assets you already have in your library, which leads to people recreating those assets. Duplication of effort lowers efficiency and increases costs.

Hierarchical inheritance increases discoverability and enables effective reuse of existing assets.

Anything inherited can be overridden for a child emitter in a system.

Modules can be added, or can be reverted back to the parent value.

This is also true with emitter-level behaviors such as spawning, lifetime, looping, bursts, and so on.

Dynamic Inputs

Dynamic inputs are built the same way modules are built.

Dynamic inputs give users infinite extensibility for inheritance.

Instead of acting on a parameter map, dynamic inputs act on a value type.

Any value can be driven by Graph logic and user-facing values.

Dynamic inputs have almost the same power as creating modules, but can be selected and dropped into the stack without actually creating new modules.

Existing modules can be modified and customized in many ways by using and chaining Dynamic Inputs; this can reduce module bloat and improve performance.

Micro Expressions

Any inline value can be converted into an HLSL expression snippet.

Users can access any variable in the particle, emitter, or system, as well as any HLSL or VM function.

This works well for small, one-off features that do not need a new module.

Events

Events are a way to communicate between elements (such as particles, emitters, and systems).

Events can be any kind of data, packed into a payload (such as a struct) and sent. Then anything else can listen for that event and take action.

Options you can use:

Run the event directly on a particle by using Particle.ID.

Run the event on every particle in a System.

Set particles to spawn in response to the event, then take some action on those particles.

Events are a special node in the graph (structs). How to use the Event node:

Name the event.

Add whatever data you want to it.

Add an Event Handler into the Emitter stack.

Set the options for the Event Handler.

There is a separate execution stack for events.

You can put elaborate graph logic into Event Handlers.

You can have a whole particle system set up, with complex logic, and then have a whole separate set of behaviors that occur when the event triggers.

Data Interfaces

There is an extensible system to allow access to arbitrary data.

Arbitrary data includes mesh data, audio, external DDC information, code objects, and text containers.

Data interfaces can be written as plugins for greater extensibility moving forward.

Users can get any data associated with a skeletal mesh by using a skeletal mesh data interface.

Houdini

Using Houdini, you can calculate split points, spawn locations, impact positions, impact velocity, normals and so on.

You can then export that data from Houdini to a common container format (CSV).

You can import that CSV into Niagara in your UE4 project.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Niagara Design Philosophy

Why Reinvent Visual Effects for Unreal Engine?

Our Goals for a New VFX System

How Niagara Achieves Our Goals

Data Sharing

Particle Payload

Many Types of Data Can Be Added

Combining the Graph Paradigm and the Stack Paradigm

Hierarchy for Niagara's Hybrid Structure

Modules

Emitters

Systems

Niagara Selection Stack and Stack Groups

Stages, Groups, Namespaces and Data Encapsulation

Niagara Design Philosophy

Why Reinvent Visual Effects for Unreal Engine?

Unreal Engine is expanding its user base, and is now used in many industries outside of the game development space. Examples are:

Architectural visualization

Industrial design, such as automotive designs

Virtual TV and film production

Our users are more diverse than ever before—from design students, to small indie developers, to large professional studio teams, to individuals and companies outside the game industry. As we move forward, Epic developers will not know everything about every industry using Unreal Engine. We wanted to create a visual effects (VFX) system that would work for all our users, across industries.

Our Goals for a New VFX System

We wanted to create a new system that would give all users the flexibility to create the effects they need. Our goals for our new VFX system were:

It puts full control in the hands of the artists.

It is programmable and customizable on every axis.

It provides better tools for debugging, visualization, and performance.

It supports data from other parts of Unreal Engine, or from external sources.

It gets out of the way of the user.

How Niagara Achieves Our Goals

Total user control starts with access to data. We want the user to be able to use any data from any part of Unreal Engine, as well as use data from other applications. So we decided to expose everything to the user.

In order to expose all this data to the user, we have to establish how someone can use that data. Namespaces provide containers for hierarchical data. For example, Emitter.Age contains data for an emitter; Particle.Position contains data for a particle. Our parameter map is the particle payload that carries all of the particle's attributes. As a result of this, everything becomes optional.

Any type of data can be added as a particle parameter. You can add complex structs, transform matrices, or Boolean flags. You can add these or any other data type, and use that in your effects simulation.

There are advantages to both the stack paradigm (such as that used in Cascade) and to the graph paradigm (such as is used in Blueprints). Stacks provide users with modular behavior and readability. Graphs give users more control over behavior. Our new effects system combines the advantages of both of these paradigms.

Hierarchy for Niagara's Hybrid Structure

Modules

Modules work in a graph paradigm—you can create modules with HLSL in the Script Editor using a visual node graph. Modules speak to common data, encapsulate behaviors, and stack together.

Emitters

Emitters work in a stack paradigm—they serve as containers for modules, and can stack together to create various effects. An emitter is single-purpose, but it is also reusable. Parameters transfer up to the emitter level from modules, but you can modify modules and parameters in the emitter.

Systems

Like emitters, systems work in a stack paradigm, and also work with a Sequencer timeline — which you can use to control how the emitters in the system behave. A system is a container for emitters. The system combines these emitters into one effect. When editing a system in the Niagara Editor, you can modify and override any parameter, module or emitter that is in the system.

Niagara Selection Stack and Stack Groups

Particle simulation in Niagara conceptually operates as a stack — simulation flows from the top of the stack to the bottom, and executes modules in order. Crucially, every module is assigned to a group that describes when the module is executed. For example, modules that initialize particles or that act when a particle spawns are in the Particle Spawn group.

Within each group, there may be multiple stages, which are called at particular points in a system's life cycle. Emitters, systems, and particles all have Spawn and Update stages by default. Spawn stages are invoked in the first frame where that group exists. For example, systems invoke their Spawn stage when the system is first instantiated in the level and activated. Particles invoke their Spawn stage whenever the emitter emits a particle, and Spawn instructions will be executed for each new particle that is created. Update stages are invoked in every frame where the system, emitter or particle is active.

There are also advanced stages, such as Events and Simulation Stages, that can be added onto the Spawn and Update flow. Events are invoked whenever a particle generates a new event and an emitter is set to handle that event. Where possible, the event handler stages occur in the same frame, but after the originating event. Simulation Stages are an advanced GPU feature. This feature enables multiple Spawn and Update stages to happen in sequence, and is useful for constructing complex structures like fluid simulations.

A module is an item, but an item is not a module. Modules are editable assets a user can create. Items refer to parts of a system or emitter that the user cannot create. Examples of items are system properties, emitter properties, and renderers.

Stages, Groups, Namespaces and Data Encapsulation

By adding each module to a stage (Update, Spawn, Event, or Simulation) in a group (System, Emitter, or Particle), you can control when a module executes as well as what data a module operates on. Stack groups are associated with Namespaces that define what data the modules in that group can read or write to.

For example, modules that execute in the System Group can read and write to parameters in the System Namespace, but can only read from parameters that belong to the Engine or User Namespaces. As execution goes down the stack from the System Group to the Emitter Group, modules executing in the Emitter Group can read and write to parameters in the Emitter Namespace, but can only read from parameters in the System, Engine and User Namespaces. Modules in the Particle Group can only read from parameters in the System and Emitter Namespaces.

Because modules in the Emitter groups may read from parameters in the System Namespace, simulation that is relevant for all emitters can be performed once by modules in the System group, and the results of that (stored in the System Namespace) can be read by the Emitter group modules in each individual emitter. This continues with Particle group modules which can read from parameters in the System and Emitter Namespaces. Refer to the table below for a more concise representation of these relationships.

Module Group

Read From Namespaces

Write To Namespaces

System

System, Engine, User

System

Emitter

System, Emitter, Engine, User

Emitter

Particle

System, Emitter, Particle, Engine, User

Particle

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Installing Unreal Engine

Creating a New Project

Enable the Niagara Plugin

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Goals

Objectives

1 - Setting Up Your Project

2 - Creating Your Effect

3 - Editing the Module Settings

4 - Attaching the Niagara Effect to a Character

5 - Reviewing the End Result

6 - On Your Own

Goals

The Niagara Quick Start is designed to get you acquainted with creating visual effects (VFX) in Unreal Engine using Niagara. You will create a puff of smoke effect and attach it to your character's footsteps. It will look like the following.

Objectives

Set up your project with meshes and materials for use with Niagara.

Create a basic smoke effect using a Niagara system.

Attach the smoke effect to a character's run animation.

1 - Setting Up Your Project

For the duration of this guide, use the Blueprint Third Person Template project with Starter Content enabled. If you have not created a project in Unreal Engine, see Create a Project.

Launch Unreal Engine from the Epic Games Launcher.

Click Games, then select the Third Person Template. Enable Starter Content.

If needed, Browse to a new Project Path.

Give your project a Project Name.

Click Create to create your project.



Click image for full size.

Before you start creating your Niagara effect, you need to set up your project with some basic materials and assets that you will be using in the rest of this guide. After you complete this section, you will have everything you need to create your Niagara effect.

Create or Import a Mesh Shape

The first thing you need for your project is a mesh shape for your effect. The shape you want to create or import is a cloud. There are a few ways of bringing in a mesh object into Unreal Engine:

Create your model in the 3D software of your choice, then export it as an .fbx file to easily import it into Unreal Engine.

Browse for a free cloud model on a site like Sketchfab, then import it into Unreal Engine.

Model the cloud directly in Unreal Engine using the Modeling Mode tools.

Create or download a cloud model similar to the following.



Click image for full size.

The cloud asset used in this tutorial is from Sketchfab. This model is called CLOUD high poly, created by and copyrighted to gaelinix. This model is licenced under the Creative Commons Attribution license.

You can download the model here.

You can also model your own cloud. Even if you do not have access to a high-end 3D modeling application like 3DS Max or Maya, you can use an open-source 3D modeling application such as Blender.

Once you have the model created or downloaded, create a place to store that model in the Content folder for easy organization.

In the Content Browser, right-click and select New Folder to create a folder for your assets. Name it Cloud.



Click image for full size.

Drag and drop your 3D model into the Content Browser to import it into your project.

For more information on how to import your model into Unreal Engine, see Importing Content.

Create and Configure a Material

When you imported your cloud model, Unreal Engine may have created a Material for that model automatically. If not, you must create your own.

Right-click in the Content Drawer and select Material. You can skip this step if Unreal Engine imported a material when you imported the model.



Click image for full size.

Name the new material CloudMaterial.



Click image for full size.

Double-click the material to open it in the Material Editor.

With the main Material node selected, locate the Material section in the Details panel. Change the Blend Mode to Translucent. Check the box for Two Sided. Leave the other settings at their default.



Click image for full size.

If you imported a model and you are using that material, there may already be something connected to the Base Color of the material. Delete this, as you will use the Niagara system's Particle Color setting to drive the material's color instead. If your material has nothing connected to Base Color, you can skip this step.



Click image for full size.

Right-click in the graph and type particle in the search bar. Select Particle Color to add the node.



Click image for full size.

Plug the top output of the Particle Color node into the Base Color input on the main Material Node.



Click image for full size.

If you imported a model, it may have automatically created a Texture Sample node and connected it. If there isn't one, create your own. You can do this by holding T and clicking inside the Node Graph.



Click image for full size.

You will add some noise from the Starter Content to the texture to make it appear more like smoke. With the Texture Sample node selected, locate the Material Expression Texture Base section in the Details panel. Next to Material, click the dropdown, then type Noise in the search bar. Select the T_Perlin_Noise_M texture.



Click image for full size.

Right-click in the graph and type dynamic in the search bar. Select Dynamic Parameter to add that node.



Click image for full size.

With the Dynamic Parameter node selected, locate the Material Expression Dynamic Parameter section in the Details panel. In Array 0, change the name to Erode.



Click image for full size.

Right-click in the graph and type step in the search bar. Select Value Step to add that node.



Click image for full size.

Drag off the R output of the Texture Sample node, and plug it into the Gradient input of the Value Step node.



Click image for full size.

Drag off the Erode output of the Dynamic Parameter node, and plug it into the Mask Offset Value input of the Value Step node.



Click image for full size.

Drag off the Results output of the Value Step node, and plug it into the Opacity input of the main Material node.



Click image for full size.

Click Apply and Save, then close the Material Editor.

You have now imported a mesh model of a cloud. You have also set up the material. You are now ready to create the Niagara effect.

2 - Creating Your Effect

Create the System

Next you will create your Niagara system.

Right-click in the Content Drawer and select Niagara System.



Click image for full size.

Select New system from selected emitters. Then click Next.



Click image for full size.

Under Template, select Simple Sprite Burst. Click the Plus sign icon (+) to add the emitter to the list of emitters to add to the system. Then click Finish.



Click image for full size.

Name the system FX_DustCloud. Double-click to open it in the Niagara Editor.



Click image for full size.

The emitter instance in your new system has the default name of SimpleSpriteBurst. You can rename it, however. Double-click the name of the emitter instance in the System Overview, and the field will become editable. Name the emitter FX_DustCloud.



Click image for full size.

If you only have one emitter in your Niagara System, renaming it is optional. However, if you create a Niagara system with more than one emitter, naming them is important for organization and clarity.

Configure the Render Group

The Emitter is set up as a vertical stack, broken up into groups. The default groups in the emitter are:

Emitter Spawn

Emitter Update

Particle Spawn

Particle Update

Render

To find out more about Emitter Groups and how they work, see the Niagara Overview page.

Because you are using a 3D model to generate the effect, you need to set up the Render group first in order to see the preview.

In the System Overview, select Render to open the Render group in the Selection panel.



Click image for full size.

Because you are using a 3D model, you need a Mesh Renderer and not a Sprite Renderer. Click the Trashcan icon to delete the Sprite Renderer. Selection panel.



Click image for full size.

With the Render group selected, in the Details panel, click the Plus sign icon (+). Select Mesh Renderer from the list to add this module to the Render group.



Click image for full size.

For Facing Mode, click the dropdown and select Velocity.

Click the triangle next to Meshes to expand the array. This array is where you can add one or more mesh objects to the renderer. Click the dropdown next to Index (0) in the array, then select the mesh you imported in the Project Setup section.



Click image for full size.

Click to the checkbox Enable Override Materials. You can then specify the material to apply to the mesh. The default is 0 Array elements. Click the Plus sign (+) icon to add an array element.



Click image for full size.

Click the dropdown next to Explicit Mat, then select the material you made in the Project Setup section.



Click image for full size.

From the Content Browser, drag your Niagara system into your Level. Position it near the foot of the Player Character, so you can check the size and shape of the effect in relationship to the character.

When you make a particle effect, it is always a good idea to drag your system into your level. This gives you a chance to see every change and edit in context.

After completing this section, you have a Niagara system and an emitter instance, and you have dragged the system into the Level so you can preview it next to the Player Character. In the next part, you will edit the settings in the Niagara system to create the dust cloud effect.

3 - Editing the Module Settings

The Niagara Editor displays each emitter as a stack, with several groups of settings. You will edit the modules in each group one at a time.

This effect does not have any modules in the Emitter Spawn group, so you will skip that section. For more information on the different groups and what they do, see the Niagara Overview page.

Configure the Emitter Update Group

First you will edit the modules in the Emitter Update group. Modules placed in this group will update every frame as the system ages.

In the System Overview, click the Emitter Update group to open it in the Selection panel.



Click image for full size.

Expand the Emitter State module. By default, the Life Cycle Mode should be set to Self.

Change the Emitter State settings to the following values. This will give you a dust poof that appears once and then dissipates.



Click image for full size.

Parameter

Value

Life Cycle Mode

Self

Inactive Response

Complete

Loop Behavior

Once

Loop Duration Mode

Fixed

Loop Duration

1

Expand the Spawn Burst Instantaneous module. Set the Spawn Count to 10. A spawn count of 10 gives us a dust cloud that is big enough to be visible, but small enough to be plausible.



Click image for full size.

Configure the Particle Spawn Group

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click the Particle Spawn group to open it in the Selection panel.



Click image for full size.

Expand the Initialize Particle module. Under Point Attributes, locate the Lifetime Mode dropdown. Use the dropdown to select Random. This adds Minimum and Maximum fields to the Lifetime value. This will add some variation in how long each particle displays. Set the Minimum and Maximum fields to the following.



Click image for full size.

Setting

Value

Minimum

.4

Maximum

.6

Locate the Color setting. In the example, the Color is set to a light tan color that looks like dust. Click on the color swatch, then use a color picker to choose a color. This value is saved to Particle Color, that you already connected to the material in the Project Setup step.



Click image for full size.

You will add some variation to the size of the particles by adding a random factor to the mesh scale. Under Mesh Attributes, locate the Mesh Scale Mode dropdown. Select Random Uniform. Set the following values for Mesh Uniform Scale Min and Mesh Uniform Scale Max.



Click image for full size.

Setting

Value

Mesh Uniform Scale Min

1.0

Mesh Uniform Scale Max

2.0

With the Particle Spawn group selected, click the Plus sign icon (+) to add a new module to this group. Select Orientation > Initial Mesh Orientation. This contains rotation settings for your particle mesh. You want to add some rotation to the shape so it is less uniform. This will make the dust cloud look a little more natural.



Click image for full size.

Under Rotation, click to enable initial rotation in the module. Click the downward arrow next to Rotation, then select Dynamic Inputs > Random Ranged Vector.



Click image for full size.

Minimum and maximum values generate a random factor to the initial rotation. Leave the Minimum and Maximum values at their default.



Click image for full size.

With the Particle Spawn group selected, click the Plus sign icon (+) to add a new module. Select Location > Shape Location. The Shape Location module lets you set a region in which new particles are created when they are born.



Click image for full size.

For this example, set Shape Primitive to Cylinder. You can experiment with different shapes in future examples depending on the look you want to achieve. For now, you want the dust cloud to stay close to the ground, so change the Cylinder Height to 1. You do not want the dust cloud to be too much bigger than the foot, so change the Cylinder Radius to 10.



Click image for full size.

Setting

Value

Shape Primitive

Cylinder

Cylinder Height

1.0

Cylinder Radius

10.0

With the Particle Spawn group selected, click the Plus sign icon (+) to add a new module to this group. Select Velocity > Add Velocity. When you add velocity in the Particle Spawn group, it adds an initial velocity to the particles at the moment of their birth, at the specified speed.



Click image for full size.

Set the Velocity Mode to From Point. This will apply velocity radially outwards from the origin point of the Niagara system. Set the Velocity Speed to 20. you do not want the particles to spread too far, just enough to represent dust that is disturbed by the runner's footsteps. You can adjust this value as needed to achieve the look you like.



Click image for full size.

With the Particle Spawn group selected, click the Plus sign icon (+) to add a new module to this group. Select Forces > Acceleration Force. You are going to use this to give the dust cloud a small amount of upward momentum, so the dust cloud spreads out and up from the character's footstep.



Click image for full size.

An error displays after you add a velocity or force module, because added modules are always positioned at the bottom of the group's stack. That positioning places them after the Solve Forces and Velocity module. All velocity and force modules need to be placed above the solver to be properly computed.

Click Fix Issue to resolve this error. Alternatively, You could manually move the module above Solve Forces and Velocity by dragging it up in the stack.



Click image for full size.

In the Acceleration Force module, set the Acceleration to X:0, Y:0, and Z:200. Now the dust cloud spreads out and up, but the upward momentum is a little too much. In the Particle Update step, you will add drag to slow down the upward momentum of the dust particles on each frame.



Click image for full size.

Configure the Particle Update Group

Finally, you will edit the settings in the Particle Update group. These behaviors are calculated on each particle every frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

Click the Trashcan icon to delete the Scale Color module. You will not need it for this effect.



Click image for full size.

With the Particle Update group selected, click the Plus sign icon (+) to add a new module. Select Materials > Dynamic Material Parameters. This is how you will connect to the Erode Dynamic Parameter in your Material.

You can drag to reorder modules in the emitter in the System Overview. However, you cannot reorder modules in the Selection panel.



Click image for full size.

In the Dynamic Material Parameters module, you see the Erode parameter you set up in your material. Click the downward arrow for Erode, and select Dynamic Inputs > Float from Curve.



Click image for full size.

In the curve editor, click the Drop Off template to apply that style to the curve. This will make the material fade out over time.



Click image for full size.

With the Particle Update group selected, click the Plus sign icon (+) to add a module to this group. Select Forces > Drag.

An error displays after you add a velocity or force module, because added modules are always positioned at the bottom of the group's stack. That positioning places them after the Solve Forces and Velocity module. Click Fix Issue to resolve this error.



Click image for full size.

In the Drag module, set the Drag to 8. The Drag setting interacts with the acceleration force and keeps the dust cloud's upward movement from seeming too unrealistic.



Click image for full size.

You have created the dust effect, and you should be able to see it in your level, next to the Player Start model. If the effect does not look right to you, you can adjust the various module settings until you like the look of the effect.

4 - Attaching the Niagara Effect to a Character

Now you are going to add this effect to a character's run animation. In this example, you will attach the effect to the generic Quinn character included in the Third Person template. However, you can use these steps to add a Niagara effect to any character you have set up in Unreal Engine.

In the Content Drawer, navigate to Content > Characters > Mannequins > Animations > Quinn. Double-click the MF_Run_Fwd animation to open it in the Animation Editor.



Click image for full size.

In the Animation timeline, click Pause to pause the looping animation. Use the scrub pointer to find the moment the character's right foot hits the ground. You are going to put your dust effect right at that spot.



Click image for full size.

Locate the Notifies section. With a notify, you are marking the animation with a location for an effect. To keep your timeline organized, create a new track to put the Niagara events on. Click on Track, then select Add Notify Track. Name it Niagara.



Click image for full size.

You will see a line that runs down from the scrub bar in the timeline. Right-click where the playhead intersects with the Niagara notify track. Select Add Notify > Play Niagara Particle Effect. A marker is placed at that point in the animation, with the default label PlayNiagaraEffect.



Click image for full size.

With the PlayNiagaraEffect notify selected, locate the Anim Notify section in the Details panel. This is where you select the Niagara System you want to add to the animation. Click the dropdown next to Niagara System, and select the FX_DustCloud system you created in Niagara. The label on the notify changes to FX_DustCloud.



Click image for full size.

Repeat the above steps for the left foot. You can also copy and paste Notifies directly in the timeline. To refine the look further, you can offset the location of the cloud to match the position of each foot where it hits the ground. With the Anim Notify selected, locate the Location Offset values. Adjust the values as needed.



Click image for full size.

Click Play in the Timeline to see a preview of the effect, and refine values as needed.

Close the Animation Editor. In the Level Editor, click the Play button to preview the level. Run around and see your effect in action.

You have attached the Niagara effect to your character's run animation. Congratulations!

Refining the Look of the Smoke Cloud

You may want to continue tweaking the values to get the final look that you want. Here are some ideas of things you can try to go back and play around with, now that your scene is set up:

Try adjusting the color in the Initialize Particle module.

Add a Scale Mesh Size module to the Particle Update group. Set the Scale Factor to Vector from Curve, and play around with different shapes to change the size of the cloud over time.

Refine the size of the model in the Mesh Renderer.

Refine the location of the cloud in the Anim Notify.

5 - Reviewing the End Result

You have finished making the effect in the Quick Start guide. It should look similar to the following.

6 - On Your Own

Now that you have created a basic effect and attached it to a character, you can try some other related tutorials to do more with this character. You can also make more effects in Niagara.

You can use a Ribbon to create a trail behind your character as it runs.

You can check out our Animation tutorials to learn how to create or modify additional animations for your character.

You can learn how to use Animation Blueprints to do even more with your character.

Position Data in UE4 and UE5

How to Enable or Disable Large World Coordinates in Niagara

Large World Coordinates in the Project

Large World Coordinates in a System

How to Test Large World Coordinates in Niagara

Move the Effect Very Far Away

Change the Constant for Tile Size

Updating Existing Projects

Particles.Position in HLSL

Custom Modules

Changing the Type of an Existing Vector Input

Converting Between Vector and Position in a Node Graph

Export Particle Data Interface

Dynamic Material Parameters

Custom Data Interfaces

Custom Renderers

Large World Coordinates are now implemented across Unreal Engine. To understand its implementation in the main engine, reference this Large World Coordinates page. In brief, the data type FVector is now double instead of float.

The Niagara implementation differs from the main engine's. Because calculations need to be done efficiently, whether on the CPU or the GPU, there are limitations that prevent working in doubles. Instead, there is a new way of storing position data in Niagara.

A sufficiently large world will be divided into a grid of tiles. When we conceive of a position in space, it has its own relative position within a tile unit, and also that tile's position in the world. See the following diagram for a conceptual representation of what this might look like.



Click image for full size.

Previously, Niagara positions were interchangeable with vectors, defined as the direction and distance away from the world origin. Now, for the information to be meaningful, additional data is required to locate the emitter relative to the tile it is in.

In UE5, to save not just the position relative to the origin but also the information of which tile the system is in, we need a new data format. This way, we can distinguish between other types of vectors, and positions that carry this additional data.

Position Data in UE4 and UE5

The main difference between UE4 and UE5 is how we store the position data of particles, that is, Particles.Position.

UE4

UE5

Particles.Position type

Vector

Position

Local space emitter

Particles.Position is relative to the Niagara system's origin in the game

Particles.Position is relative to the Niagara system's origin in the game (unchanged)

World space emitter

Particles.Position is relative to the game's origin (0,0,0)

Particles.Position is relative to the system's position when it activated. For small coordinates, this is still the game's origin. For larger coordinates, this may be an arbitrary number.

How to Enable or Disable Large World Coordinates in Niagara

Large World Coordinates in the Project

By default, Large World Coordinates are turned on in new projects. The system will automatically convert your projects when you open them in UE5.

If your project is not large enough to require large world coordinate support, you can turn it off completely in Edit > Project Settings. Under Plugins > Niagara, locate the setting System Support Large World Coordinates, then disable it for your project.



Click image for full size.

Large World Coordinates in a System

You may want to have Large World Coordinates turned on for the project, but disabled for a specific, individual system. In this case, you can edit your Niagara system in the Niagara Editor. In the System Properties, under the Rendering section, you can disable Support Large World Coordinates.



Click image for full size.

How to Test Large World Coordinates in Niagara

When you first update a project file from UE4 to UE5, or as you begin to test your system, you may want to validate that your Niagara systems behave properly in large world coordinates. To test whether a Niagara system works with large world coordinates, you need to move it outside of the first tile. There are several ways to do this, as outlined below.

Move the Effect Very Far Away

You can move your effect very far away from the origin, then play the effect and validate the behavior. This is the only way to test this without making any changes in the engine code itself. For example, you could move the system 3000000 units away from the origin, and this will place it in a tile outside the original tile.

Change the Constant for Tile Size

You can also change the tile size for the large world coordinate tiles in the constant definition. In Engine/Source/Runtime/Core/Private/Misc/LargeWorldRenderPosition.cpp, change UE_LWC_RENDER_TILE_SIZE to something very small, for example 10 units. Now, when you place your effect in the level, so long as it is more than 10 units away from the origin, it will be in a new tile.

Updating Existing Projects

Particles.Position in HLSL

If you wrote custom scripts in HLSL for your project, you need to update these to work with large world coordinates. In previous versions, you may have used HLSL to directly set Particles.Position to a fixed value. This does not work with large world coordinates.

Instead, you can either disable large world coordinate support for that asset or convert the worldspace vector to a position.



Click image for full size.

If you need to know what tile you are in, this is stored in Engine.Owner.LWCTile.

Custom Modules

Using the Niagara Script Editor, or the Scratch Pad, you can create your own custom modules. If you already created custom modules in a previous version, they may not work implicitly when converted to a project using large world coordinates.

The reason for this is the difference between position data, that includes the tile information, and normal vectors, that do not. Core parameters like Particles.Position are automatically converted to the type position, but custom vector inputs connected to them are not.

In the following example, Box Origin uses Particles.Position as a default binding. However, it is not, itself, a position type.



Click image for full size.

To maintain backwards compatibility, the existing connections are kept and the position type is converted to a normal vector type.

In a Niagara Script, if you have existing modules you may want to update some parameters to be of type position. To change the type of an existing vector input or output to a position type, do the following:

Open the module script in the Niagara Script Editor.

In the Parameter tab, right-click the parameter(s) whose type you want to change.

Select Change Type > Position from the contextual menu.



Click image for full size.

If you change a parameter to type position, and it is connected to a parameter of a different type, it will create an orphaned pin connection. This way, you can decide what to do next: whether to change the other parameter type as well, or convert the data from one type to another.

You can only change parameters that are owned by this script. If you are inheriting a parameter from outside, you will see that parameter is locked and the type cannot be changed.

If you connect together a vector and a position in a node graph, the system will add in a convert node, Position -> Vector or Vector -> Position. However, be aware this copies the values without taking into account the large world transformation if it takes place outside the origin tile. This could result in a loss of crucial information.



Click image for full size.

If you want to convert a position type to a worldspace vector, you can use the function Position to Vector. In the reverse, to convert a worldspace vector to a position, you can use Vector to Position.



Click image for full size.

Whenever you convert from a position to a vector or the reverse, there's potentially a loss of data. This can result in a loss of precision, or some unpredictable behaviors when outside of the origin tile. To be safe, from start to end you should use positions without converting. Conversions to world space should ideally only take place in data interfaces or renderers.

Export Particle Data Interface

You can use the Export Particle data interface to send position data to blueprints. If you already used this previously, you will need to update your blueprint for large world coordinates.



Click image for full size.

There is a parameter in the Receive Particle Data event node node called Simulation Position Offset. This stores the offset data for the tile that you are in. You can add this at the end of a script to the simulation position to convert from simulation space back to world space.

Dynamic Material Parameters

Position data carries additional information about the tile offset that cannot be linked directly to a vector that does not carry this information. If your project is set up so that you are exporting position data to a material by using a dynamic input to bind to that material in the renderer, then this will not work with large world coordinates. To fix this, you can convert the position data to a world space vector.



For large coordinates, the additional offset information of which tile you are in is lost, so this can result in an overflow for large coordinates.

If you still have a Material binding to use, you can link it to Engine.Owner.LWCTile to add this offset information back in again.

[

Click image for full size.

In the Material itself, you can also use the ConvertNiagaraPositionToWorldspace Material function to add the tile offset to the simulation position.



Click image for full size.

Custom Data Interfaces

If you have created any custom data interfaces that contain functions that work with world space positions, then these will need to be updated.

As needed, replace existing functions to use FNiagaraPosition type instead of FVector for their inputs and outputs. You can override UNiagaraDataInterface::UpgradeFunctionCall to upgrade existing function usages.

To transform simulation positions, you can get a helper object from the system instance:

For GPU data interface functions, you can get the system's large world coordinate tile from the FNiagaraDataInterfaceArgs supplied to the shader context. If you need to see an example of this, you can check existing usages like the camera data interface.

Custom Renderers

Any custom renderer reading position data also needs to be updated. Similar to data interfaces, you can get a converter from the system instance. The only difference is that you also need to know if you're rendering a localspace emitter or not:

Any particle position you read can then be transformed into worldspace using the following:

Please check existing Niagara renderers for examples of how this is already implemented.

Events

Location Events

Death Events

Collision Events

Event Handlers

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

In many cases, you will want several emitters in one system to interact with each other to create the effect you want. This usually means that one emitter generates some data, and then other emitters listen for that data, and perform some behavior in reaction to that data. In Niagara, this is done using Events and Event Handlers. Events are the modules that generate specific events that occur in the lifetime of a particle. Event Handlers are modules that listen for those generated events, and then initiate a behavior in response to that event.

Currently, events with GPU simulations will not work. Events only work with CPU simulation.

Events

In order to use events, make sure to enable Requires Persistent IDs in the Emitter Properties of your emitters.

Because events happen dynamically as the particle ages, events are added to the Particle Update group. If you click on the Plus (+) next to Particle Update, you will see a section called Events in which you can add event modules to the stack.



There are several types of event modules available:

Location

Death

Collision

Location Events

When you place a Generate Location Event module into the Particle Update group of your emitter, each particle spawned in that emitter will generate location data during its lifecycle. You can then set an Event Handler to receive that location data and trigger another behavior.

For example, if you want to create a trail effect for a fireworks rocket, you can place a Generate Location Event module into the Particle Update group of your rocket emitter. Then the trail emitter can spawn particles that follow the rocket by using the location data.



Click image for full size.

Death Events

When you place a Generate Death Event module into the Particle Update group of your emitter, each particle spawned in that emitter will generate an event at the end of its lifetime. There are many ways to use this data. You can trigger another emitter's particle effect when the first emitter's particles die, or you can create chain reactions where each emitter spawns their effect when the previous emitter's particles die. You can also combine Location and Death events to create intricate interactions.

To use our fireworks example, you can generate an explosion effect to spawn at the end of the rocket particle's life. The Location event determines where the rocket particle is, which is where the explosion occurs. The Death event determines when the particle's lifetime ends, which is when the explosion effect is spawned.



Click image for full size.

Collision Events

When you place a Generate Collision Event module into the Particle Update group of your emitter, particles will generate an event when they collide with an Actor, such as a static mesh or skeletal mesh. For example, if you want to change the firework effect into a weapon effect, you could have the explosion spawn when the rocket particles collide with a static or skeletal mesh.



Click image for full size.

You need to add a Collision module to an emitter before you can add a Generate Collision Event to that emitter. This enables the emitter's particles to collide with objects in the world.

Event Handlers

Event Handlers consist of two parts: Event Handler Properties, and a Receive Event. For each event you want the emitter to respond to, you will add an Event Handler Properties item, and a Receive Event module.

If you click the Plus (+) next to Emitter Properties, you will be able to add an Event Handler stage to your emitter.



Click image for full size.

In Event Handler Properties, set the Source of the event with a dropdown that lists all of the Generate Event modules that are available. Then you can choose what particles are affected by the event, how many times the event occurs per frame, and if the event spawns particles you can select how many are spawned.



Click image for full size.

After you set the properties for the Event Handler, click the Plus (+) next to Event Handler to add a Receive Event module. It must match the generated event module you placed in the Particle Update group of the emitter that generates the event.



Click image for full size.

For example, if you placed a Generate Location Event in an emitter, you would select the Receive Location Event module for your Event Handler.



Click image for full size.

Goals

Objectives

Set Up the Capture

Navigating the User Interface

Frame the Niagara Preview

Adjust the Timing

Adjust the Texture Size

Set Additional Texture Properties

Perform a Capture

Use the Flipbook Texture in an Emitter

Add the Sub UV Animation Module

Adjust the Settings on the Sprite Renderer

Final Result

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Niagara systems create visually stunning effects. However, when designing simulations it's important to balance the visual look with the performance. At times, you may create a nice effect, but find it takes up too much memory to use on a target device.

One solution to this is to bake out the Niagara simulation to a flipbook. This creates a tiled image that can then be loaded onto any material.

For example, you want to create a 3D fluid effect, but you are not able to run it in realtime on your target platform. So, after creating the 3D fluid effect, you can use the Baker to bake it to a flipbook, and then apply this back to a 2D sprite emitter. This way, you have very efficient performance for games or for non-hero effects that may be farther in the background.

Goals

In this tutorial, use the Niagara Baker to export a flipbook from a simulation.

Objectives

Set up the capture for the flipbook

Perform the capture

Connect the flipbook to a new emitter

Set Up the Capture

Open an existing Niagara system in the Niagara Editor. In this example, the Grid 3D Gas Colored Smoke example is used, however you can use any Niagara system. To use Grid 3D Gas Colored Smoke, right-click in the Content Drawer and select Create Basic Asset > Niagara System.



Click image for full size.

Create a flipbook from a Niagara Fluids template. These templates are available when you have the Niagara Fluids plugin enabled. However, a flipbook can be generated from any Niagara system. Select New system from a template or behavior example, then Grid 3D Gas Colored Smoke.



Click image for full size.

On the main toolbar, there is a new button called Baker. Select Open Baker Tab to display the Baker panel.



Click image for full size.

Navigating the User Interface

The Baker panel user interface has the following parts.



Click image for full size.

Bake button

Niagara Preview

Flipbook Preview

Playback Toolbar

Flipbook Options

Frame the Niagara Preview

To get started, you need to frame the simulation within the Niagara Preview window. It will bake out the simulation to a series of flat, 2D frames, so make sure that you set up the desired angle and size.

To adjust the framing, you can click and drag directly in the Niagara Preview window.

Left-click and drag to orbit.

Middle-click and drag to pan.

Right-click and drag to zoom.

Click F to center the frame on the system origin.

You can also enter the values numerically in the Camera settings. Select the Camera Viewport Mode as desired, then edit the numerical values in the corresponding field.



Click image for full size.

Adjust the Timing

Use the Playback Toolbar to play, pause, step forward, and step backward in the simulation to preview what will be baked out.



Click image for full size.

You can also adjust the timing in the Timeline settings, so that you only bake out a portion of the simulation. For example, adjust Start Seconds to start the flipbook partway through the simulation playback. Adjust Duration Seconds to change when it will end.

Set the Frames Per Second to adjust the tick rate of the component. You usually should not need to adjust this value. Set it to the same value as for the content you author. The Niagara System Editor defaults to 30 fps. Setting this value too low can result in the same flipbook frame being rendered multiple times, for example if you were to render a flipbook over 1 second with 30 frames captured and you set the Frames Per Second to 20 you would only record 20 unique frames rather than 30.

Adjust the Texture Size

The way the flipbook bakes, it will export a tiled image where each tile represents a frame of the flipbook. You need to set how many tiles you want to map onto the texture, as well as the total texture size. By default, the texture is set up with 8 tiles along the X axis, 8 tiles along the Y axis, and a total texture size of 1024 x 1024 pixels.



Click image for full size.

That means that each tile will be a size of 128 x 128 pixels. You can adjust these values under the Texture settings.



Click image for full size.

Set the number of tiles by adjusting Frames Per Dimension. Adjust the size of the overall texture by changing Texture Size.

The baker does not scale your tiles to fit into the final resolution. For an ideal result, make sure that the number of tiles divides evenly into the overall texture size.

For example, if you set Frames Per Dimension to be 10 x 10, but kept the Texture Size at 1024 x 1024, then the system would try to map 10 tiles into 1024. However, that would result in each tile being 102.4 pixels wide, and the system cannot account for a partial pixel. Therefore, it would map each tile to a size of 102, and you would end up with 4 extra pixels of padding at the right and bottom of your texture.

This can cause the sub UV mapping to be slightly off, and cause your atlas to jitter as it plays. For ideal behavior, set your Texture Size to be a power of 2, and the Frames Per Dimension to be a number that divides evenly into that texture size.

Set Additional Texture Properties

By default, when Source Binding is set to None, the Baker will output the SceneColorHDR values. Usually, this is the desired outcome. However, all available GBuffers and particle attributes are available, and you can choose from any of them from the dropdown menu for Source Binding.



Click image for full size.

Before you generate your first flipbook, the Generated Texture is set to None. After you perform your first capture, this is replaced by the new texture that you create.

Perform a Capture

Now that you have set up the texture to look the way you want, with the correct framing and timing, you can perform a capture.

From the Niagara Preview window, click Bake.



Click image for full size.

You now see a progress bar as the system renders out the flipbook. When complete, a dialog opens and you can name your texture file.



Click image for full size.

Now that it has rendered out, your new texture replaces the active texture in the Texture settings of the Baker window.



Click image for full size.

If you generate another capture, with this texture selected under Generated Texture, it will overwrite this texture.

If you would like to generate a new variation of the texture, click the dropdown for the Generated Texture, then select Clear. You can then adjust any of the settings and create a new texture.



Click image for full size.

Now that you exported the texture, you can add it into any new emitter. You can also see the final preview of what the flipbook texture looks like.



Use the Flipbook Texture in an Emitter

To use the flipbook in an emitter, you must use a Sprite Renderer.

To set this up, right-click in the Content Drawer and create a new Niagara System.

Select New system from selected emitter(s), and then Simple Sprite Burst.

Click plus (+) to add the emitter, then click Finish.



Click image for full size.

Add the Sub UV Animation Module

To add in your flipbook, you need to add a new module in the Particle Update group, as well as adjust some parameters on the Sprite Renderer.

First, click plus (+) next to Particle Update, and select Sub UVAnimation. This will add the module to the stack.



Click image for full size.

Adjust the start frame and end frame in the module properties to match the number of frames in your animation. In this example, there were 8 x 8 frames, for a total of 64. Since the frame starts on frame 0, leave the settings at 0 and 63.



Click image for full size.

Adjust the Settings on the Sprite Renderer

Select the Sprite Renderer to adjust the properties. In the Sub UV section, specify the number of tiles in the grid in the Sub Image Size field. In this example, leave this as 8 x 8.



Click image for full size.

Now you need to create a new Material to link your Sub UV texture to, and add that into the Sprite Renderer. Click the dropdown menu next to Material, then select Create New Asset > Material.



Click image for full size.

A dialog box appears. Name your Material and choose where to save it.



Click image for full size.

Double-click the Material in the Content Browser to open it in the Material Editor. In the Details panel, set the Blend Mode to Translucent.



Click image for full size.

In the Material Editor, right-click and search for ‘texture sample' to add the TextureSample node.



Click image for full size.

Select the TextureSample node. In the Details panel, set the Texture to be the one you saved from the flipbook baker.



Click image for full size.

By default, the color channels are premultiplied with black. To avoid black fringing around the sprites, you can use a divide node to remove this from the RGB channels.

Right-click to add a Divide node.

Conenct the RGB value from the TextureSample node to the A pin on Divide node, and the alpha A from the TextureSample value to the B pin on Divide node.

Connect the output of the Divide node to Emissive Color.

Finally, connect the alpha A value from the TextureSample to the Opacity on the material.



Click image for full size.

Final Result

Now that your Material is properly set in the Sprite Renderer, open the Niagara System in the Niagara Editor. You now see the flipbook that you rendered out playing in the Preview window.



Cascade To Niagara Converter Plugin

Enabling The Cascade To Niagara Converter Plugin

Using The Cascade To Niagara Converter Plugin

Types Of Errors And Warnings

Cascade To Niagara-Supported Conversion Operations

Extending The Capabilities Of Cascade To Niagara Converter Plugin

Cascade To Niagara Converter Plugin

The Cascade to Niagara Converter plugin is a utility designed to convert any of your existing Cascade Particle Systems assets. The plugin includes a Blueprint function library to generate both Niagara Emitter and Niagara System assets programmatically, as well as a Python scripting layer to translate Cascade Systems into the new Niagara Systems.

This plugin is ideal for those looking to convert existing content from Cascade to Niagara. It is meant as a starting point for upgrading to the latest tools used by Unreal Engine, and will continue to be updated until Cascade is deprecated and removed in a future release of the engine.

Enabling The Cascade To Niagara Converter Plugin

To enable the Cascade to Niagara Converter plugin for your project, perform the following steps below:

Navigate to Edit >Plugins in the main menu to open the Plugins Browser tab.

From the Built-In category side menu, navigate to FX >Cascade To Niagara Converter plugin, and enable the Plugin.



Click image for full size.

When prompted, click Restart Now for your changes to take effect.



Click image for full size.

Using The Cascade To Niagara Converter Plugin

Convert your desired Cascade Particle Systems to a Niagara System by right-clicking on a Cascade Particle in the Content Browser and selecting Convert to Niagara System from the context menu.



Click image for full size.

In the example above, we have used the Cascade Particle System P_Steam_Lit"from the Starter Content Folder.

A new Niagara System is created in the same directory as the source Cascade System with the suffix _Converted.



Click image for full size.

Your newly generated Niagara System creates a conversion report which can be viewed by opening the new Niagara System and observing the Niagara Log window. We recommend reviewing the converted Niagara Systems by opening the asset in the editor and resolving any warnings or errors that may be contained in the conversion report.



Click image for full size.

The Niagara Log provides a warning that it has skipped converting the Boolean value bApplyGlobalSpawnRateScale.

Types Of Errors And Warnings

Upon conversion of your Cascade System to a Niagara System asset, you may notice some errors and warnings that may be displayed on the Niagara System Overview Window. Hovering your mouse cursor over any of these symbols will display a brief description of any issues that may be in conflict.

– Icon to indicate a Error.

– Icon to indicate a Warning.



Click image for full size.

The image above displays a brief description of two errors denoting that a dependency has been unmet in the Particle Update field.

Selecting any of these properties will open the Selection details window on the right-hand side of your screen; enabling you to observe a more detailed explanation of the issues. Depending on the type of issue, a fix issue prompt may be provided to resolve it automatically.





Errors

Warnings

The Selection details window displays an additional detailed description of unmet dependency errors for the Acceleration Force, and Drag modules as well as suggestions on how to remedy them. Selecting Fix issue will result in the plugin adjusting the order of the module stack group

The Selection details window displays the warning Unspecified Error to indicate that the variable bApplyGlobalRateScale has been skipped in the conversion process.

Cascade To Niagara-Supported Conversion Operations

The Cascade To Niagara Converter supports converting general representations of Cascade Particle Systems; however, there are some modules and properties which are not entirely supported. The table below lists those which are not yet supported or which are partially supported.

Feature

Supported (Y/N/Partially)

Additional Notes



Event Modules



Event Generator

N

EventReceiver Kill all

N

EventReceiver Spawn

N



Emitter to Emitter Modules



Particle Attractor

N

Source Movement

N

Emitter Initial Location

N

Emitter Direct Location

N

Seeded Mofules

N

Beam and AnimTrail Renderers

N

Ribbon Renderers

Partially

Ribbon UVs are not guaranteed to be equivalent for the converted Niagara System.

Cascade Emitter LODs

Partially

Conversion will only operate on all modules at LOD 0.

If a Cascade Particle System with unsupported modules or renderers is converted, the generated Niagara System will log the skipped module or renderer conversion in its Niagara Log Window.



Click image for full size.

Niagara Log displays a message to indicate which cascade modules have been skipped during the conversion.

Extending The Capabilities Of Cascade To Niagara Converter Plugin

The plugin supports extending the conversion process by modifying the python scripts located in the Cascade To Niagara Converter plugin's Python directory see:Engine/Plugins/FX/CascadeToNiagaraConverter/Content/Python.

For users who have created their own custom modules, renderers, and properties in Cascade. New converter scripts for each can be created by extending from the relative interface and adding the new script to the relevant directory, under CascadeToNiagaraConverter/Content/Python. For example, to add support for converting a custom module, create a new script under the ModuleConversionScripts directory, and extend a new class in the script from the ModuleConverterInterface class. For more details or examples please refer to source code for the associated interface script.

Getting Started With Niagara Fluids

Further Reading

Reference Guides

Niagara Fluids brings real-time fluid effects to Unreal Engine. By enabling the Niagara Fluids plugin, you will have access to standard fluids templates that help you get started with effects like fire, smoke, gas, and more. Take advantage of 2D templates that are optimized for games, or 3D templates designed for cinematics.

Fluid simulation methods give natural, realistic results compared with more simple particle-based setups. Fluids are built on top of the Niagara infrastructure. Advanced users can modify them without needing to write code, plugins, or data interfaces.

Getting Started With Niagara Fluids

To get started with Niagara Fluids, start by reading the Fluid Simulation Overview document. Then, follow the Niagara Fluids Quick-Start Guide to learn how to add the templates to your project.



Overview of Fluid Simulation in Unreal Engine.



A quick start guide for using the Niagara Fluids plugin to create real-time fluid simulation.

Further Reading

Niagara Fluids are built upon existing Niagara infrastructure. Fluids simulations can be heavy. You may want to create a Fluids emitter, and then bake the results out to a flipbook that you can use on any Material. Find out more about how to do that in the Niagara Flipbook Baker Quick Start Guide.

Fluids scenes can be graphically intensive, and may result in a GPU crash on Windows. If you experience this, you can find out how to fix it below.



A quick start guide for creating Niagara flipbooks in Unreal Engine.



Learn how to fix a GPU driver crash in Windows by editing your registry keys.

Reference Guides

To learn about each of the parameters that you can control within a Niagara Fluids template, read through the Niagara Fluids Reference Guide.



Reference guide for the Niagara Fluids plugin.

Goals

Objectives

1 - Enable the Niagara Fluids Plugin

2 - Create the Niagara System

3 - Add an Actor to Collide With

4 - Adjust the Look of the Explosion

End Result

Further Reading

Pre-Requisite Tasks:

Create a New Project

Enable the Niagara Plugin

Niagara Fluids is a plugin that you can enable to add templates to your project for real-time fluid simulation.

Goals

In this tutorial, you will learn how to enable the Niagara Fluids plugin and create your first project.

Objectives

Enable the Niagara Fluids plugin

Create a new Niagara System from a Fluids template

Modify the parameters to achieve a new look

1 - Enable the Niagara Fluids Plugin

To begin working, first enable the Niagara Fluids plugin.

Click on Edit > Plugins.



Click for full size.

Search for Niagara in the search bar. Click the checkbox to the left of Niagara Fluids.



Click for full size.

A warning message is displayed, because this plugin is still in Beta. Click Yes to enable the plugin.



Click for full size.

You are then prompted to restart Unreal Engine. Click Restart Now.



Click for full size.

The fluids templates will now be available to you when you create a new Niagara system.

2 - Create the Niagara System

Next, you will create a new Niagara system from a Fluids template.

Right-click in the Content Drawer. Under the Create Basic Asset section, select Niagara System.



Click for full size.

Select the second option, New system from a template or behavior example. Because Fluids templates consist of more than one emitter, selecting this option adds all the emitters you need for the full effect.



Click for full size.

Select the template you are interested in trying out. For this example, select Grid 3D Gas Explosion. Click Finish.



Click for full size.

Rename the Niagara system to Grid3DGasExplosion.



Drag the Niagara system into your level. The explosion triggers in the scene when you drop it.



Click for full size.

3 - Add an Actor to Collide With

The first place you can adjust the actor is within the level itself. For this example, you are using a simple sphere.

Select the Niagara system in the level.

In the Details panel, under Override Parameters, adjust any of the exposed parameters as needed. Since this system does not loop, toggle on and off Show Overlays to force the explosion to restart. This is a good way to test as you adjust the parameters.



Click for full size.

Parameter

Description

Collide_GeometryCollection, Collide_PhysicsAsset, Collide_StaticMesh

Use these data interfaces to add actors in your level to affect your simulation.

DirectionalLight1, DirectionalLight2

Link up to two directional lights to your system. In this way, you can use lights that are already in your level to illuminate your simulation.

If you leave these empty, the system sets some default values.

ResolutionMaxAxis

Set the resolution of your simulation. Try to keep this as small as possible to preserve memory and performance.

ShowOverlays

Toggle the bounds of the system on and off.

SourceOffset

Position the explosion inside the system's bounding box. By default, this is set to the center of the domain.

WorldSpaceSize

Change the size of the bounding box for the simulation.

Set the WorldSpaceSize to 300, 300, 600.

To show how to have the explosion interact with an object, add a simple sphere to the scene and position it above the explosion. Click the Quick Add Content button, then select Shapes > Sphere.



Click for full size.

Move the sphere into position above your explosion, but within its bounding box.



Click for full size.

To reduce the pixelation of the simulation, you need to increase the resolution. Select the simulation, then in the Details panel, in the Override Parameters section, adjust the ResolutionMaxAxis to 300.



Click for full size.

Next, you need to add a tag to the sphere to indicate to the level that it is a collider object.

Click the sphere to select it.

In the Details panel, search for ‘tag'.

Under the Actor section, in Advanced > Tags, click plus(+) to add a new tag.

Type in ‘collider' for the name of the tag. The explosion will now collide with the sphere.



Click for full size.

4 - Adjust the Look of the Explosion

Next, you fine-tune the look of the explosion.

Double-click on the Niagara system in the Content Drawer to open it in the Niagara Editor.

You should see the explosion playing in the Preview panel. In the System Overview, there are two emitters set up. If you don't see them right away, click F to fit them in the window.



Click for full size.

The emitter on the left, ParticleSourceEmitter, injects values into the simulation. The emitter on the right, Grid3D_Gas_CONTROLS_Emitter, is known as a Controls emitter. This is the primary emitter you will use to adjust the look. Click on Emitter Summary to view the parameters you can adjust.



Click for full size.

Shift-click the triangle to the left of a section heading to collapse all sections.

First, adjust the dissipation values. Dissipation defines how quickly the data fades over time. The higher the number, the faster the data will drop to zero. Lowering the number will maintain the values for longer. Set the values to the following for a shorter, burst-like explosion.



Click for full size.

Parameter

Value

Density Dissipation

3.0

Temperature Dissipation

1.5

Velocity Dissipation

0.8

Next, adjust the buoyancy values. In this simulation, buoyancy from temperature causes the simulation to rise. Buoyancy from density causes the simulation to fall. Velocity can be added to the simulation by adjusting the density and/or the temperature values. If you change the direction of the Gravity parameter, then the buoyancy adapts to the new direction. To make the explosion rise more quickly, change the Temperature Buoyancy value to 3.5.



Click for full size.

To finalize the look, adjust the parameters in the Render section. By default, Render Density is set to Linear. This means that the values defined by Render Density Range will start at 0.0 opacity, and ramp up to an opacity of 1.0 when rendered. You can change the opacity overall by adding to the Render Density Gain value. For this example, set it to 0.5.



Click for full size.

By default, the colors transition from black, to red, orange, and then white, using a black body curve. This black body curve is a physically plausible mapping that gives a realistic look. It is based on the color of the wavelengths of light emitted by a hot black body at different temperatures.

Change Render Temperature to Curve. This property is where you can input your own custom values for the color.



Click for full size.

Expand the Render Temperature Curve, then Curve. Adjust the colors freely to achieve the look you want.



Click for full size.

When you are satisfied with the look, Save and then close the Niagara system. In the Level Editor, you now see the explosion in your scene with the adjustments you made.

End Result

Your final result now looks like the following.



Further Reading

To continue learning more about the parameters you can adjust, read the Niagara Fluids Reference Guide.

Create a Niagara Fluids Simulation from a Template

Inheritance

Fluids Emitter Summary

Grid

Simulation

Render

Debug

Scalability

Source

Texture

Niagara Fluids is a plugin that provides you with templates to easily add real-time simulations to your projects. There are several different types of templates available:

2D Gas

2D Liquid

3D Gas

3D Liquid

Shallow Water

2D simulations are more efficient and better suited for games and real-time use. 3D simulations have a more realistic look, but a tradeoff in higher memory and GPU cost. As such, 3D simulations are best for hero effects or cinematics. If needed, the results can also be baked into a flipbook and applied to textures for increased performance in real-time use.

This reference guide gives an overview of the Grid 3D Gas Fire template as an example of the design principles.

Create a Niagara Fluids Simulation from a Template

To create a new Niagara Fluids simulation, right-click in the Content Drawer and select Niagara System. In the wizard, select the option New system from a template or behavior example. This way, the fluids templates are already set up with the proper inheritance and it will add all the emitters you need to the system. To learn more about enabling the plugin and creating your first project, see the Niagara Fluids Quick Start.

You will see a variety of different 3D Gas examples to choose from.



Click image for full size.

Inheritance

Fluid emitters use inheritance to progressively add functionality. For example, see the following diagram that shows the inheritance structure in the 3D Gas emitters.



Click image for full size.

The purpose of each emitter is the following:

Emitter

Purpose

Grid3D_Gas_Emitter

This is the core simulation.

Grid3D_Gas_Controls_Base_Emitter

This emitter adds a centralized controller, debug slice functionality, and better render support. These controls are exposed in the Emitter Summary.

Grid3D_Gas_CONTROLS_Emitter

This emitter adds particle source support. Density, temperature, and velocity are injected into the simulation from a second emitter.

Grid3D_Gas_CONTROLS_CINE_Emitter

This is an alternative controls emitter that uses a slower, deterministic form for the particle source algorithm. It includes advanced texture coordinates and is designed for cinematic use.

Fluids Emitter Summary

All the parameters you want to adjust to change the look and behavior of your simulation will be available in the Emitter Summary. For ease of organization, the summary has been broken down into the following sections:

Grid

Simulation

Render

Debug

Scalability

Source



Click image for full size.

This reference guide describes the parameters available in each of these sections.

Grid

Gas simulations are represented by a grid that is split into cells. Each cell contains information about the density, temperature, and velocity of the medium at that location. Smaller grid cells will increase the quality of the simulation, however with a cost in performance.



Click image for full size.

Parameter

Description

Grid Bounds Overlay

Adds a toggle to the Override Parameters when you click the simulation in the Level Editor. From there, you can toggle the visibility of the red box around the simulation.

Cell Size Guides

Adds a toggle to the Override Parameters when you click the simulation in the Level Editor. From there, you can toggle the visibility of the guide cells on each major axis.

World Space Size

Adds a set of fields for the user to set in the Override Parameters when you click the simulation in the Level Editor. From there, you can change the size of the container box for the simulation.

Local Pivot

Change the offset for where the simulation origin should be.

Resolution Max Axis

Adds a toggle to the Override Parameters when you click on the simulation in the Level Editor. From there, you can set the resolution of the simulation, based on its longest side. A higher resolution will result in a more accurate look, but it will decrease performance.

Open Boundary +/- X/Y/Z

Toggle these options to adjust whether the edges of the simulation should be treated as a solid wall that particles can't travel through.

Simulation

The simulation section is broken down into three sub-sections: simulation, collide against, and turbulence. All of these parameters affect how the simulation changes over time based on properties like density, temperature, buoyancy, and more.



Click image for full size.



Click image for full size.

Parameter

Description

Override Delta Time

Set this value to override the engine's delta time with a fixed delta time.

Delta Time Scale

If Override Delta Time is not enabled, then the system uses the engine delta time. Enter a value in Delta Time Scale to modify the engine delta time by this amount.

Vorticity Confinement

Vorticity defines the spin of the simulation. Enter a value to amplify the vorticity in the simulation by this amount.

Pressure Relaxation

This value defines the pressure solver convergence. Enter a value between 0 and 1. We recommend keeping this value close to 1.

Pressure Solve Iterations

The more iterations you perform in the solver, the more accurate, however the slower it will be. Enter a value here that provides enough accuracy without a compromise in performance.

Density Dissipation

This value defines how quickly the density will dissipate to zero. The higher the number, the more quickly it will dissipate.

Temperature Dissipation

This value defines how quickly the temperature will dissipate to zero. The higher the number, the more quickly it will dissipate.

Velocity Dissipation

This value defines how quickly the velocity will dissipate to zero. The higher the number, the more quickly it will dissipate.

Density Buoyancy

This value defines the amount of downward velocity applied to the simulation based on its density. The higher this value, the more downward velocity.

Temperature Buoyancy

This value defines the amount of upward velocity applied to the simulation. The higher the number, the more upward velocity.

Gravity

Set the direction and magnitude of gravity in the simulation.

You can have your simulation react to actors in your level. The most common way is to have those actors collide if they come into contact with the simulation. Enabling or disabling the parameters in the Collide Against section adds or removes data interfaces for those types of objects.

When Collide Against is enabled, select the simulation in the Level Editor to adjust the Override Parameters and select specific actors. Those actors will then collide with the simulation. See an example of this in the [Niagara Fluids Quick Start]() [link].



Click image for full size.

You can enable three bands of turbulence in the emitter. Seed Turbulence is applied on the initialization frame only. Turbulence 1 and 2 are applied while the simulation runs.



Click image for full size.

Parameter

Description

Seed Turbulence Gain

Set the strength of the turbulence. This is applied on the initialization frame only.

Seed Turbulence Frequency

This sets the size of the turbulence features. The smaller the number, the larger the features will look. This is applied on the initialization frame only.

Seed Turbulence Speed

Set how quickly the turbulence should move. This is applied on the initialization frame only.

Seed Turbulence Local Space

When enabled, the turbulence will follow the local space of the simulation. When disabled, turbulence will be fixed in world space. This is applied on the initialization frame only.

Turbulence Density Gain

Set the strength of the turbulence. This can be set as density and / or temperature.

Turbulence Density Band

Limit the turbulence between a defined range of densities.

Turbulence Temperature Gain

Set the strength of the turbulence. This can be set as density and / or temperature.

Turbulence Temperature Band

Limit the turbulence between a defined range of temperatures.

Turbulence Frequency

This sets the size of the turbulence features. The smaller the number, the larger the features will look.

Turbulence Speed

Set how quickly the turbulence should move.

Turbulence Bias

Bias the noise away from zero to give the turbulence direction.

Turbulence Local Space

When enabled, the turbulence will follow the local space of the simulation. When disabled, turbulence will be fixed in world space.

Render

Render properties are broken up into two sub-sections: Render and Lights.



Click image for full size.

Parameter

Description

Render Step Size Mult

The simulation is calculated by breaking up the volume into cells, and then sampling the simulation in those cells. By default, the step size through the volume matches the size of the cells.

If you decrease the value in this multiplier, you will sample the simulation multiple times per cell. This is useful when a texture is modulating the simulation data, or if you are rendering detailed fire.

Render Density

This option controls whether to render the density or not. You can choose between None, Linear, or Curve. Linear mapping will map the data in the grid to the opacity of the gas. Or, you can set a curve for greater control.

Render Density Range

Set a density range to be rendered. The first value should be the density value that you want to be transparent, and the second should be the density value that gives the highest opacity.

Render Density Curve

If you set Render Density to Curve, then you can set the curve using this parameter. Expand the field to access the curve editor.

Render Density Gain

This value adds a multiplier on top of the final density being rendered.

Render Density Albedo

This value is a float which colors the smoke from black to white.

Shadow Quality

Baked shadows are calculated by breaking the volume up into cells, then stepping through the volume to sample the simulation in those cells. Adjust this value to sample the simulation multiple times per cell.

Shadow Max Steps

Limit the number of steps to take when sampling for shadows.

Render Temperature

Choose how to render the Temperature component. You can choose from None, Black Body, or Curve.

None will not render the Temperature values.

Black Body will render an environmentally realistic fire, from black, to red, orange, yellow, then white.

Curve will let you set your own custom color values.

Render Temperature Range

Set a range of temperature values to map to the Render Temperature. This only applies when Render Temperature is set to Black Body or Curve.

Render Temperature Curve

If Render Temperature is set to Black Body, the alpha component of this curve defines the opacity of the fire.

If Render Temperature is set to Curve, this curve defines both the color and the opacity of the gas.

Render Temp Color Gain

Add an additional multiplier to the gas color.

Render Temp Opacity Gain

Add an additional multiplier to the opacity of the gas.

The Lights section contains data interfaces to bring in any directional lights that you set up in your level through Override Parameters. If no lights are connected to these data interfaces, then default lighting is applied. To adjust the properties of the default lighting, click the Show Advanced button.



Click image for full size.

Parameter

Description

Light1/2

This data interface reads the attributes from a light you have connected to the Override Parameters of the Niagara system in the Level Editor.

Lgt1/2 Shadow Density

Set how much light the density component should occlude.

Lgt1/2 Default Intensity

Set the intensity of the default light.

Lgt1/2 Default Color

Set the color of the default light.

Lgt1/2 Default Direction

Set the direction of the default light. This direction is a vector that is set in world space.

Debug

Use these options to debug your simulation.



Click image for full size.

Parameter

Description

Debug Sources

Enable this option to overwrite grid data on every frame with the source data. By doing this, you will see what the sources are introducing to the simulation.

Render Debug Slice

Enable this option to render a 2D slice inside the grid. Density is rendered in the red channel. Temperature is rendered in the green channel. Combined light intensity is rendered in the blue channel.

Render Debug Slice Axis

Choose which axis to orient the slice to.

Render Debug Slice Offset

Set how far along the axis to render the slice. This value should be between 0 and 1, with 0.5 being the center point.

Render Debug Slice Lights

Enable this option to render the light intensity in the blue channel.

Scalability

Use the scalability settings to override the parameters that depend on the Quality setting of your simulation. By default, scalability overrides are applied when the engine is running in Cinematic quality.

An example of when you might want to use a scalability override is when you want to render a cinematic sequence with Movie Render Queue. There is a setting in Movie Render Queue called Game Overrides that automatically changes the quality level to Cinematic when rendering. This way, you can set your Scalability Override quality to Cinematic, but you can work interactively in the scene at a lower quality, but faster, setting. Then, when you press the Render button in Movie Render Queue, the high quality settings will take effect.



Click image for full size.

Source

Adjust source parameters to change information based on incoming particles.



Click image for full size.

Parameter

Description

Particle Attribute Reader

This data interface reads from another emitter in the system.

Scale Emission by dt

Enable this to ensure that the source data remains consistent, even if the engine tick rate varies.

Use Falloff

Enable this to anti-alias data at the edges of particles. This keeps sourcing consistent, even if the resolution changes.

Scatter Density

Enable this to look for the density attribute on the incoming particle source, fluids_source_density.

Scatter Temperature

Enable this to look for the temperature attribute on the incoming particle source, fluids_source_temperature.

Scatter Velocity

Enable this to look for the velocity attribute on the incoming particle source, fluids_source_velocity.

Use Radius

Enable this to overlap all cells in the simulation based on the particle radius, fluids_source_radius. This keeps the sourcing consistent, even if the resolution changes.

Density Mult

Enter a value to multiply the incoming particle density attribute by.

Splat Size Density

If Use Radius is disabled, enter a value to set how many cells should be stamped with the particle density data. Enter 1 to indicate the closest cell, or 2 to indicate the closest cell and the cells touching the closest cell. As you increase this number, the number of cells being written to increases significantly.

Temperature Mult

Enter a value to multiply the incoming particle temperature attribute by.

Splat Size Temperature

If Use Radius is disabled, enter a value to set how many cells should be stamped with the particle temperature data. Enter 1 to indicate the closest cell, or 2 to indicate the closest cell and the cells touching the closest cell. As you increase this number, the number of cells being written to increases significantly.

Local Space Particles

Enable this value to set the particles to be local to this simulation.

Velocity Mult

Enter a value to multiply the incoming particle velocity attribute by.

Splat Size Velocity

If Use Radius is disabled, enter a value to set how many cells should be stamped with the particle velocity data. Enter 1 to indicate the closest cell, or 2 to indicate the closest cell and the cells touching the closest cell. As you increase this number, the number of cells being written to increases significantly.

Texture

There is an additional set of parameters in the template for Grid 3D Gas Explosion Cine. Select the Emitter Summary on the Grid3D_Gas_CONTROLS_CINE_Emitter. Then, select the All tab, and locate the Texture section.

This emitter includes a simulation stage that advects texture coordinates through the simulation. The included MI_RayMarch_Fire_Ramps_Tex material will use these coordinates to modulate the render with noise.



Click image for full size.

Parameter

Description

Texture Smoke Density Gain

Enter a value to modulate the density with noise.

Texture Smoke Color Gain

Enter a value to modulate the smoke albedo with noise.

Texture Fire Density Gain

Enter a value to modulate the opacity of the fire contribution with noise.

Texture Fire Color Gain

Enter a value to modulate the fire color intensity with noise.

Texture Scale

Enter a value to adjust the size of the noise pattern.

Texture Remap To 0

This parameter performs a fit operation. Enter a value that will be remapped to 0, adding contrast and bias to the effect.

Texture Remap To 1

This parameter performs a fit operation. Enter a value that will be remapped to 1, adding contrast and bias to the effect.

Value Data

Choose whether to limit the influence of the texture to Density or Temperature. The option you choose here will determine how to apply the following parameters: Value Band Min, Value Band Max, and Value Band Sharpness.

Value Band Min

Set the lower value of the simulation data to which the texture will be applied.

Value Band Max

Set the upper value of the simulation data to which the texture will be applied.

Value Band Sharpness

Set how the texture will transition within the band. Enter a sharpness value of 0 to have the transition happen slowly within the band, reaching full influence at the midpoint of Value Band Min and Value Band Max. Enter a sharpness value of 1 to have it influence immediately as soon as the data falls anywhere within the band.

Loop Duration

The coordinates reset and transition back and forth to avoid stretching. Enter a value to adjust the loop duration. The higher the loop duration, the more stretching you will see.

Debug Texture

Enable this option to override the material and only show the texturing value.

GPU Ray Tracing Collisions (Experimental)

Collisions in Niagara can be achieved in a variety of ways using the Collision module. Check back on this page in future, since more documentation will be available soon.

GPU Ray Tracing Collisions (Experimental)

Using this experimental feature, you can use hardware ray tracing to create more accurate collisions for GPU simulations.



Learn how to enable GPU Raytracing Collisions in Niagara.

Adjust Your Project Settings

Set Up the Collision Module

Set Up A Fallback (Optional)

In Unreal Engine, you can set up a particle system to collide with objects in the level using the Collision module.

In previous versions of Unreal Engine, when using a GPU emitter, you had several options in this module. Typically, most used the Depth Buffer option, which generates a simulation of the environment. This is a low-cost, but also low-accuracy solution. The shapes are not accurately portrayed, and if a particle goes off the screen it disappears immediately.

GPU Raytracing Collisions is an experimental option in the Collision module, so you can use hardware ray tracing on the GPU. No matter whether the emitter and its particles are on-screen or off, or hidden behind an object, the collision will use raytracing to calculate an accurate result.



The calculation is asynchronous, so the Niagara collision will be one frame behind.

Adjust Your Project Settings

To use this feature, your project must be set to DirectX 12 and your GPU must have hardware ray tracing enabled. To turn on these options, follow these instructions:

Open Edit > Project Settings.

Search for rhi.

Adjust the Default RHI option to DirectX 12.



Click image for full size.

Next, enable ray tracing, also in your Project Settings.

Search for ray tracing.

Enable the options Support Hardware Ray Tracing and Ray Traced Shadows.



Click image for full size.

Set Up the Collision Module

In the Collision module, adjust the settings to use this experimental feature. Set the GPU Collision Type to GPU Ray Traces (Experimental).

The Trace Provider is set to Project Settings by default, which picks the best from an array of options. However, you can also manually set this to HW Ray Tracing.



Set Up A Fallback (Optional)

You can set up a fallback in case ray tracing is not available. To do this, open Edit > Project Settings.

In the Plugins > Niagara section of the settings, there is a setting called Async Gpu Trace DI. It has an array set up with two options in it, HW Ray Tracing and Global Signed Distance Fields. When your options are set up like this, the system will first try to use ray tracing, but if ray tracing is not available then it will fall back to use distance fields instead. These are the default settings.



You can add elements to the array or rearrange as needed. However, in most cases, the default settings will be sufficient.

Niagara Debugger

Performance Budgeting Using Effect Types

How to Fix a GPU Crash

Unreal Engine provides several different tools you can use to help debug what's going on in your simulations.

Niagara Debugger

If you need to further debug Niagara simulations after they've been added to your level, then you can use the Niagara Debugger. This lets you turn on a heads-up display (HUD) that outputs detailed information about the simulations in your level, such as the number of particles being generated, the amount of memory being used, and more. You can also capture a snapshot of information and then analyze that output.



Use the Niagara Debugger to analyze your Niagara systems in a level.

Performance Budgeting Using Effect Types

Create a new type of asset called a Niagara Effect Type to configure a variety of settings to help you manage budgeting in your level. Any Niagara Systems that use this Effect Type will inherit the rules you set. This way, you can improve performance by, for example, culling systems that are a certain distance away.



Use Effect Types to set up ways to improve the performance of your Niagara systems.

How to Fix a GPU Crash

As some Niagara simulations can be graphically intensive, working in those scenes in Windows could cause a GPU crash. Visit this page to find out more about how to resolve it.



Learn how to fix a GPU driver crash in Windows by editing your registry keys.

Niagara Debugger

How to Open the Debugger from the Top Menu

How to Open the Debugger by Watching an Emitter

How to Open the Debugger by Watching a Parameter

Niagara Debugger Layout

Debug HUD

Debug Overview

Debug Filters

Debug System

Debug Particles

Wildcard Searching

Console Commands

fx.Niagara.Debug.Hud

fx.Niagara.Debug.PlaybackMode

fx.Niagara.Debug.PlaybackRate

Show Global Budget info related commands

FX Outliner

FX Outliner Interface

State View

Worlds

Systems

System Instances

Emitters

Performance View

Performance

Session Browser

Debug Spawn

Niagara Debugger

The Niagara Debugger gives you a suite of tools to help you review detailed data about the simulations currently in your level. There are several ways to open the debugger:

From the Top Menu

By watching an emitter

By watching a parameter

If you open the debugger from the Top Menu, the interface opens without any pre-set options. If you open the debugger by watching a system or parameter, the interface opens with pre-set options for tracking the system or parameter you selected.

How to Open the Debugger from the Top Menu

To enable the Niagara Debugger from the Top Menu, from the Level Editor select Tools > Debug > Niagara Debugger. This displays a panel that you can dock where you prefer.



Click image for full size.

How to Open the Debugger by Watching an Emitter

Open in the Niagara Editor the system that contains the emitter you would like to watch. Right-click the emitter, then select Watch Emitter in Niagara Debugger.



Click image for full size.

How to Open the Debugger by Watching a Parameter

From the Niagara Editor, locate the parameter you would like to watch in the Parameters panel. Right-click the parameter, then select, Watch Parameter in Niagara Debugger.



Click image for full size.

Niagara Debugger Layout

The Niagara Debugger is organized into the following sections:



Click image for full size.

Niagara Debugger Panel

Playback Options

Debugger Tabs

Debugger Options

First, there is a top section that provides you with playback controls. Here you can select Play, Pause, Loop, Step, and Speed.



Parameter

Description

Refresh

Refresh the settings on the selected device. Use this when something gets out of sync.

Play

Play all Niagara simulations in the level.

Pause

Pause all Niagara simulations in the level.

Loop

Loop all Niagara simulations in the level. When paired with the Loop Time settings, single-fire systems like bursts can be made to loop.

Step

Step forward all Niagara simulations by one single frame per click.

Speed

Adjust the speed of Niagara simulations in the level. This only affects the playback speed of Niagara simulations, any other elements in your level will play back at normal speed.

Underneath the playback controls, you will see different tabs. Clicking a tab gives you access to the different tools within the Debugger.



Parameter

Description

Debug HUD

Debug Hud lets you turn on a heads-up display to view detailed information about the simulations in your level.

FX Outliner

The FX Outliner gives you debugging and profiling data on Niagara as it runs on a device or in PIE.

Performance

Use various performance testing tools to analyze your Niagara simulations.

Session Browser

Set the Debugging options to a different session, for example to a console, or PIE.

Debug HUD

The first tab in the Debugger is the Debug HUD tab. You can turn on the Debug HUD to show a heads-up display directly in the Viewport of your level. You can then choose what information to display by adjusting the options.

To turn on the Debug HUD, select the Debug HUD Enabled option from the Debug HUD tab.



Click image for full size.

Once the Debug HUD is enabled, you will see a printout of various values in the Viewport.



Click image for full size.

The settings that you select in the Debug HUD tab will be saved between sessions. You can choose to display a variety of data. This data is broken up into several groups.



Click image for full size.

Parameter

Description

Debug Overview

This section lets you turn on an overview section at the top of the Debug HUD that includes the total number of systems, total scalability, total number of active emitters, total number of particles, and total memory.

Debug Filters

This section lets you set filters so that you only display information about actors, components, systems, or emitters that match that filter. For example, you can type in *fountain* to display objects that contain fountain anywhere in the name. Leaving these filters to (*) includes all assets.

For more information, see Wildcard Searching.

Debug System

This section displays detailed information for each system in the Viewport of the Level Editor.

Debug Particles

This section lets you show detailed information on individual particles in the Viewport. Given that you may have thousands of particles, you can also limit the amount of data displayed to a maximum number of particles.

Click Debug Overview Enabled to turn on the display of these values in the Viewport.



Click image for full size.

This shows a printout of the following information in the Viewport:

Total number of systems

Total scalability

Total number of active emitters

Total number of particles

Total memory



Click image for full size.

Clicking the Overview Font option will let you choose whether you want to view the Small or Normal sized font. You can also adjust the position of the overview in the Viewport using the Overview Location values.

The filters that you have active help you to control what information you see printed out in the Debug HUD. By default, each of these filters is set to (*), meaning show everything.

You can click the checkbox next to any of the filters to enable it. You can choose to filter out Actors, Components, Systems, or Emitters.

To set a filter, type in what you would like to filter between asterisks. For example, if you want to filter out Systems with the word System in the name, click on the checkbox next to System Filter to enable it and then type in *System* into the text entry field.



Click image for full size.

In the Debug HUD you will then see the systems matching the filter highlighted in yellow.



Click image for full size.

For more information, see Wildcard Searching.

You can enable a display of debug information for each system in the Viewport using this section.

This information will only be displayed if at least one filter is enabled and at least one system passes the filter.

Set the following options to adjust the display of system information in the Viewport.



Click image for full size.

Parameter

Description

System Debug Verbosity

None - displays only the system's bounds (if enabled) and the location and orientation of the system

Basic - displays the system's bounds (if enabled), the location and orientation of the system, and the component and system name. Also displays if a system is culled out by scalability and why.

Verbose - displays the system's bounds (if enabled), the location and orientation of the system, the component and system name. Displays if a system is culled out by scalability and why. Shows the system's active state. Displays the amount of memory that system is using. Shows if the system has an Effect Type.

System Emitter Verbosity

None - no additional information is displayed.

Basic - displays the number of emitters and particles.

Verbose - shows each emitter found in the system, the state of that emitter, and the number of particles owned by it.

System Show Bounds

Displays the system bounds. If the system has fixed bounds, this size will be constant. If the bounds are not fixed, the bounds will dynamically resize to encompass the system's particles.

System Show Active Only in World

When this option is enabled, you will only see information displayed for visible systems.

When disabled, you will see a display of systems that have been culled by scalability. Culled systems are represented by a black locator.

Show System Attributes

As long as the System Debug Verbosity is set to Basic or Verbose, you can use System Attributes to display additional information in the Debug HUD. For example, you can add an array of one or more specific attributes such as System.Age. Or you could could use an asterisk to show all attributes containing a word, such as System.* or *.Age.

For more information, see Wildcard Searching.

System Text Options

Use these options to adjust the display of text with respect to the origin of the system.

Font: Adjusts the size (Small or Normal).

Horizontal Alignment: Left, Center, or Right aligned with the system origin.

Vertical Alignment: Top, Center, or Bottom aligned with the system origin.

Screen Offset: Makes adjustments to the left or right using coordinates.

System Options are printed in the Viewport next to the origin of each system according to the options set above.



If you choose to enable the option System Show Bounds, it will draw a dynamically-updating box around the bounds of the system.



Click image for full size.

Using the Debug HUD you can display per-particle information directly in the viewport to help you debug your scene.

Remember when using Debug Particles that it can be helpful to use the playback controls to Pause, Skip, and Play.



Click image for full size.

In order for Particle Attributes to be displayed, the System Debug Verbosity must be set to Basic or Verbose.

Parameter

Description

Show Particle Attributes

Enable this option to show a visual display of attributes per particle. You can then use the array element to add particle attributes to display. Like in the System Attributes, you can use an asterisk to filter a range of attributes using a string or you can type in the exact name of the attribute, for example Color.

For more information, see Wildcard Searching.

Enable GPU Readback

First, you must enable the Show Particle Attributes option. Then, if you enable this option, you will see a display of particle attributes for GPU emitters.

When using this option, data is gathered from the GPU and sent back to the CPU for processing so there is a latency of a few frames.

There is a memory cost for using this option, since we readback everything for each system.

Particle Attributes

Enter in attributes into an array to print them out in the Viewport next to the particles. You can enter in more than one attribute, but you must have at least one attribute set in order to have something displayed.

Example: In the above screenshot, there are 2 attributes added to the array: Color and Position.

Particle Text Options

Choose the options here to adjust the display of the text in the viewport. By default, each particle has the text printed next to it individually, and the text will follow the movement of the particle from one frame to the next.

Font: Small or Normal.

Horizontal Alignment: Left, Center, or Right of the particle.

Vertical Alignment: Top, Center, or Bottom of the particle.

Show Particle Attributes With System

Enabling this option overrides the default behavior of Particle Text Options. Instead of the text being printed next to each particle, the text is appended to the System Stats.

Use Max Particles to Display

This option determines the number of particles to display information about in the viewport.

If Enabled, this shows the number of particles you set in the Max Particles to Display field.

If Disabled, this shows all of the visible particles in the level for all Niagara systems. If you have thousands of particles in your level, this could cause performance issues and out-of-memory errors on some workstations.

Show Global Budget Info

This option shows an additional widget with the global budget information. This displays the global FX time, budget in ms, and the time/budget ratio.

Once you have set up the options to your liking, you will see a printout per particle in the Viewport with the attributes that you selected in the array for Particle Attributes.



Click image for full size.

When filtering, sometimes you want to filter or search using an exact string. At other times, you may want to search or filter for all items that contain a string. Use the following guidelines for how to use the asterisk (*) for wildcard searching.

Syntax

Description

mystring

Return the exact string mystring

*mystring

Return any item that ends with mystring

mystring*

Return any item that starts with mystring

*mystring*

Return any item that contains mystring somewhere in the text, for example WootMyStringIsGreat

my*string

Return any item that starts with my and ends with string but contains anything in between, for example MyGreatestEverString

Console Commands

All options present in the Debug HUD tab can be run manually with the console commands.

In order to run console commands, you need to enter them into the Output Log's console.

The main console commands to modify the HUD, with values you can set, are:

fx.Niagara.Debug.Hud displays the list of available commands.

Enabled=1 will enable the HUD (0 will disable it).

ValidateSystemSimulationDataBuffers=1 enable or disable (0 will disable it) validation on system data buffers.

bValidateParticleDataBuffers=1 enable or disable (0 will disable it) validation on particle data buffers.

OverviewEnabled=1 enable or disable (0 will disable it) the main overview display.

OverviewLocation=30,50 sets the location of the HUD in the Editor Viewport. First value corresponds to the X axis and the second corresponds to the Y axis.

ShowGlobalBudgetInfo=1 enables Global budget information widget (0 will disable it).

EnableGpuParticleReadback=1 will allow us to readback GPU data for particle display (0 will disable it).

SystemDebugVerbosity=0 sets the system verbosity level. 0 corresponds to None, 1 to Basic, and 2 to Verbose.

SystemEmitterVerbosity=0 sets the in world system emitter debug verbosity. 0 corresponds to None, 1 to Basic, and 2 to Verbose.

SystemShowBounds=1 shows all filtered systems bounds (0 will disable it).

SystemShowActiveOnlyInWorld=1 will only show in world display for active components (0 will disable it).

SystemFilter=*Flop* sets the wildcard system filter for in world display, this would match anything that contains flop in the name.

ComponentFilter=MyComp will filter in world display to all components that match MyComp.

ShowSystemVariables=1 enables System variables visibility (0 will disable it).

SystemVariables=Position,*Color would display any variable that matches "Position" and all variables that contain "Color".

ShowParticlesVariablesWithSystem=1 when enabled, particle variables are shown with the system display, when disabled (set to 0), it's attached to the component in world display.

MaxParticlesToDisplay=32 limits the display to 32 particles, this is purely to avoid destroying the frame rate / memory.

ShowParticleVariables=1 enables Particle variables visibility (0 will disable it).

ParticlesVariables=*Pos,Color will display any variable that contains "Pos" and any variable that matches "Color".

Sets the playback mode for all Niagara effects.

fx.Niagara.Debug.PlaybackMode 0 will play all simulations.

fx.Niagara.Debug.PlaybackMode 1 will pause the simulation.

fx.Niagara.Debug.PlaybackMode 2 will step a single frame then pause all simulations.

Playback Rate is a modifier to delta time for all Niagara simulations.

fx.Niagara.Debug.PlaybackRate 0.5 will run all simulations at half speed.

fx.budget.enabled 1 enables Global Budget tracking (0 will disable it).

fx.Budget.GameThread displays the Budget (in ms) for all combined FX work that runs only on the gamethread. As this budget is approached or exceeded, various FX systems will attempt to scale down more and more aggressively to remain in budget.

fx.Budget.GameThreadConcurrent displays the Budget (in ms) for all combined FX work that runs on the gamethread or on a concurrent task spawned from the game thread. As this budget is approached or exceeded, various FX systems will attempt to scale down more and more aggressively to remain in budget.

fx.Budget.RenderThread displays the Budget (in ms) for all combined FX work that runs on the Render Thread. As this budget is approached or exceeded, various FX systems will attempt to scale down more and more aggressively to remain in budget.

FX Outliner

The FX Outliner is the second tab you will find in the Niagara Debugger panel. This tab provides you with the ability to capture data from the Niagara simulations in your level so that you can analyze it.

This feature is still in development and will continue to evolve in future versions.

To open the FX Outliner, click the tab in the Niagara Debugger.



Click image for full size.

To start, click the Capture button. The FX Outliner will wait the number of frames specified in the Delay field and then start to run. You will then see the output in the section below.



Click image for full size.

The FX Outliner interface is laid out as follows.



Click image for full size.

Toolbar

World Row

System Row

System Instance Row

Emitter Row

Inline Data

Details of selected row

The FX Outliner toolbar is where you can select the options for the tool.



Parameter

Description

Capture

Click to trigger a capture on the currently connected device. To change the device being used, click the Session Browser tab in the Debugging panel.

Perf

Toggle this button on or off to capture performance data in this capture.

Delay

Set the number of frames to delay before capturing data. You may want to set a delay for example if you need to perform a specific action in-game.

This value also sets the duration of the capture.

View Mode

Choose which view mode for the capture area below. There are two view modes, State and Performance.

State displays the execution state, the number of particles, the number of particles, and whether the sim target is the CPU or the GPU.

Performance displays performance information when available. Currently performance is gathered at a system and system instance level. Emitters only display state data.

Filters

Clicking this will let you select various filtering options for the capture data.

System Execution State: show only systems that are active / inactive / inactive clear / complete.

Emitter Execution State: show only systems that are active / inactive / inactive clear / complete.

Active systems and/or emitters will run all scripts and allow spawning.

Inactive systems and/or emitters will run all scripts but not allow spawning.

Inactive Clear systems and/or emitters will clear all existing particles and move to inactive.

Complete is when the systems and/or emitters have finished executing.

Emitter Sim Target can be filtered by CPU or GPU.

System Cull State shows only systems that have or have not been culled by scalability.



You can also filter by string using the search box.



Descending

Toggle Ascending or Descending to change how the entries are sorted based on the value for the Sort Mode.

Sort Mode

Sets how the entries are sorted.

Auto chooses the default mode for the current view mode. If you are in State View, this will sort by the number of entries that match the current filters. In Performance View, it will sort by the Average Game Thread Time.

Filter Matches will sort by the number of entries that match the filter criteria.

Average Time will sort by the average game thread time.

Max Time will sort by the maximum game thread time.

Units

View time values in performance mode in microseconds, milliseconds, or seconds. The default value is microseconds.

The state view displays data on the state of the line item. Depending on whether that line represents a World, System, System Instance, or Emitter, the type of data that will be displayed is different.



Click image for full size.

World

System

System Instance

Emitter

Parameter

Description

World Type

Shows the data source. Examples: Editor, Game, PIE.

Net Mode

Shows whether this is a client, a dedicated server, or standalone.

Has Begun Play

Returns True or False.

Number of Systems

This is the number of systems in the world that match the current search filters.

Systems currently only output the number of system instances that match the current search filters.

Parameter

Description

Pooling Method

Returns one of None, InUse, or FreeInPool.

Execution State

Shows whether the system as a whole is Active, Inactive, or Complete.

Number of Emitters

Shows the number of emitters in this system instance that match the current search filters.

Uninitialized

If a component is created but has not yet been fully initialized it will display Uninitialized.

Parameter

Description

Execution State

This shows the emitter's current state, Active, Inactive, or Complete.

Sim Target

Displays whether this emitter is a CPU or GPU emitter.

Number of Particles

Shows the number of particles.

Performance View will display any performance data that was captured. The numbers are displayed in the selected units, which defaults to microseconds.



Click image for full size.

Each block of numbers is split into two. On the left you will see the game thread cost, on the right is the render thread cost.

All values are calculated over the capture time that is set by the Delay value.

Average total frame time for all effects.

Maximum total frame time for all effects.

Average per instance cost for this system.

Maximum per instance cost for this system.

Average total cost for all instances of this system.

Maximum total cost of all instances of this system.

Average cost for this instance.

Maximum cost for this instance.

No information is captured on individual emitters, so you will only see State data for emitters.

Performance

This section of the tool is highly experimental and subject to change.



Click image for full size.

Parameter

Description

Toggle ParticlePerf

This option turns on the CPU cost when running performance tests.

Run Performance Test

Clicking this will run a performance test for the duration of frames indicated. After the test has been run, the output will be pasted in text format into the Output Log. The data is in .csv format and can be copy-pasted from the Output Log into a spreadsheet for further analysis if needed.

Toggle Baseline

Each Effect Type has a baseline that is set in the System Properties of the Niagara System. When enabled, as a performance test is run it will measure the cost of the system in the level against the baseline cost of that Effect Type.

Enable Async Simulation

Click to enable for all Niagara simulations in the level. Quickly enabling or disabling this setting can help to determine whether an issue you're experiencing is related to this setting.

Disable Async Simulation

Click to disable for all Niagara simulations in the level. Quickly enabling or disabling this setting can help to determine whether an issue you're experiencing is related to this setting.

Session Browser

The 4th tab in the Niagara Debugger is the Session Browser.



Click image for full size.

The Session Browser drives where all tests are run on the other tabs of the Niagara Debugger. In the Session Browser you will see any sessions that are active at that moment. In the case of this screenshot, the only available session is on the application running on the local device.

If you have sessions running on a console, or other devices, you can output the Niagara Debugger information onto those devices by selecting them in the Session Browser.

You can then return to the Debug HUD tab to adjust the display settings.

Debug Spawn

This section of the tool is highly experimental and subject to change.



Click image for full size.

When to Use Performance Budgeting

How to Create an Effect Type Asset

Effect Type Budgeting Options

When to Use Performance Budgeting

When building a game, you can have a lot of variability in the FX workload depending on the scene composition. Sometimes you may want to take actions to help manage the performance, such as culling instances outside a certain range, or instances that exceed a specified budget usage.

Effect Type assets allow you to configure a variety of settings once, then apply them across a collection of Niagara systems.

How to Create an Effect Type Asset

To create an Effect Type asset, right-click in the Content Browser and select FX > Niagara Effect Type.



Click image for full size.

Effect Type Budgeting Options

In the Effect Type asset, you can set several different methods to cull systems that are exceeding your budget usage. These options are all available under the heading Budget Scaling.



Click image for full size.

Max Global Budget Usage: This option lets you set up a budget above which any system is culled. You will normally set this to a value between 0 and 1, which represents a percentage from 0-100%. You can set it to 1.5 if you want the system to be more permissive. What this means is, as soon as any system reaches this percentage of your budget, it is culled. This is the best option if you are favoring performance over visuals.



Click image for full size.

Max Distance Scale by Global Budget Use: This option lets you set up a curve to define how the distance at which you cull systems decreases as your budget use increases. For example, if your budget use is very high, then Niagara only renders systems that are close and not those that are far away.

Max Instance Count Scale by Global Budget Use: This option lets you set up a curve that defines how as your budget use increases, the number of instances in your level is scaled down. This scales down all instances of all systems that match this Effect Type.

Max System Instance Count Scale by Global Budget Use: This option lets you set up a curve that defines how as your budget use increases, the number of instances in your level is scaled down. However, in this option, instead of culling all instances in all systems, you are culling a number of instances per system.

For each of those 3 options that take Start X, Start Y, End X, and End Y values, those values define a linearly interpolated curve. Anything above that curve will be culled. For an example, see the following diagram of what the curve would look like.



Click image for full size.

Niagara Script Editor Reference

Versioning Modules in Niagara

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Niagara gives you the full flexibility of being able to create your own custom modules. You can use the Niagara Script Editor to define your own logic flow, save your modules, and then apply them in a Niagara stack.

Niagara Script Editor Reference

To understand how to use the Script Editor, refer to the Niagara Script Editor Reference page.



This page describes the user interface (UI) of the Niagara Script Editor.

Versioning Modules in Niagara

When you are iterating on creating new versions of modules, it's a good idea to work with versioning enabled so that you don't end up breaking any scenes that are using an outdated version of your modules. This page can teach you more.



Niagara has a built-in versioning system for people that are creating their own custom modules and emitters.

We will continue to add more documentation about creating custom modules in Niagara soon. In the meantime, check out the Content Samples as a good place to pick apart existing modules and understand the logic of how they are built.

Overview

Module Versioning

Emitter Versioning

How to Enable Versioning

Version Details

Creating New Versions

Using Different Versions

Python Integration

Direct Text Entry

Adding an External Script

Writing Python Scripts

Python API Listing

Overview

Niagara gives you the ability to create your own custom modules using Niagara Scripts. When you create your own module, you may want to roll that module out to a team, or use it in many projects. As you iterate on a module to add or improve functionality, you want to make sure that you don't break existing assets that already use those modules.

For custom modules that do not use versioning, the default behavior is that changes are pushed directly to assets that use this module. In contrast, enabling versioning means that users will need to manually upgrade to new versions of that module when they become available.

For this reason, you can now create versions of modules directly within Niagara. This is not intended to replace a version control system such as Git or Perforce, but rather is an internal versioning system built directly into Niagara.

You can also save emitters as assets, then apply Niagara versioning to those emitters in the same way you would with Niagara scripts.

Module Versioning

To enable versioning, first open up the module in the Script Editor. Any module can be opened by double-clicking on that module from the System Overview in the Niagara Editor, or by double-clicking the Niagara Script from the Content Browser.

On the toolbar, click the Versioning button.



Click image for full size.

Emitter Versioning

Like modules, you can also version an emitter for reuse in multiple projects. You must save your emitter as an asset to use this function. There are two ways to do this:

Create a new emitter: From the Content Browser, create a new Emitter asset by right-clicking then selecting FX > Niagara Emitter.

Convert an existing emitter: From inside a Niagara system, right-click on an emitter and select Create Asset From This.

From the emitter asset, you can then locate the Versioning button in the top toolbar to enable versioning. This works the same way that it does from a Niagara script asset.



Click image for full size.

How to Enable Versioning

If this is your first time setting up versioning for this module, a popup dialog will appear. This dialog explains that after enabling versioning, any users of a module will need to upgrade to new versions manually when changes are made. Click Enable Versioning to accept.



Click image for full size.

Now, you can edit the properties of your versions or create new versions.

Version Details

Each version that you create has some version details for you to set.



Click image for full size.

Parameter

Description

Is Exposed Version

Enable so this version also becomes the default for any time this module is used. Anyone using this module will be able to see this version in the version selector.

Change Description

Write some text to give clarity to users on what is new in this version.

Is Visible in Version Select

Enable to make this version available to users in the version selector. You can leave this unchecked when you are iterating and testing new versions of a module, but don't want anyone to have access to it yet.

Creating New Versions

To create a new version, from the Niagara Script view, click the Versioning button to open the panel. Click on Add version.



Click image for full size.

When you create a version, you first need to indicate whether it is a major version or a minor version. A minor version should be used for small changes that would not be a breaking change. A major version is for changes where, once you migrate to that version, you cannot migrate back to the old version without breaking the properties that have already been set up.

There is no internal difference between a minor and a major version, this is simply a language distinction to help users identify the risk involved in upgrading.

Select New major version or New minor version to continue. You can then set the Version Details. While you're working on setting up your new version, it's best to leave Is Exposed Version unchecked. You can also uncheck Is Visible in Version Selector if you don't want anyone to be aware that you're working on a new version. Once you're satisfied with your changes, you can enable these options to propagate them out.

Once you create a new version, you can close the window to return to the Niagara Script Editor. At any time, you can switch the active version that you are editing from the three-dots menu in the toolbar.



Click image for full size.

Using Different Versions

In the Niagara Editor, when you select a module in the stack that uses versioning, you will see a version selector icon in the Selection panel. If the module has versioning enabled, but there is no new version, the version icon shows up as grey.



Click image for full size.

As soon as a new minor version is available, the icon turns orange.



Click image for full size.

If a new major version is available, then there is also a message printed out notifying users of the new version.



Click image for full size.

Any version description notes will show up in the Selection panel until dismissed.



Click image for full size.

At any time you can click on the version button in the Selection Panel to change from one version of the module to another. If you hover over the version number, you will see a tooltip with the description for that version.



Click image for full size.

When a new major version is available, you will also be informed by a warning icon in the Emitter stack. The warning icon shows up on the right side of the module, as well as the group that the module is in.



Click image for full size.

Once you switch to a new version of a module, it is not always possible to go back. It's a good idea to save your project first, then switch to the new version and validate that everything is working properly.

To switch to a new version, in the System Overview, select the custom module you want to update. Click the version switcher, then select the version you would like to use. If the new version is a major version, you can also upgrade to this version directly from the Selection panel by clicking on Fix Issue.



Click image for full size.

Python Integration

This feature is still experimental and may change in the future.

When you upgrade from one module version to another, the system will do its best to map the properties of the old version to the new version. However, if the desired outcome is not clear you might want to write your own upgrade script to tell the system how to properly upgrade the version. This will ensure that users don't have to redo all their work after upgrading.

To provide an update script, click the Versioning button on the Niagara Script toolbar to open the versioning panel. You will see a section of this panel called Scripting. By default, Upgrade Script Execution is set to None, meaning that you are not providing a script.



Click image for full size.

There are two ways to enter a script:

Copy and paste the text directly into the Versioning panel.

Link to an external asset.

Direct Text Entry

To copy and paste directly, first click Upgrade Script Execution and select Direct Text Entry. You can now copy and paste your script into the field Python Update Script.



Click image for full size.

Adding an External Script

To link to an external script, first click Upgrade Script Execution and select Script Asset. You can now click the three dots menu to the right of the Script Asset field to browse to your script file.



Click image for full size.

Writing Python Scripts

You can use a python script if it's not clear from one version to another how the pre-existing Niagara script should map to the new one. For example, if the old version takes a bool input and the new version instead uses an enum that has more than two values, the upgrade script can map the existing bool input to two enum values. Here is an example script that does that:

Get bool input, set new input as enum

The upgrade_context variable is provided to the script and contains the old as well as the new inputs.

Calling get_old_input(string input_name) on it returns an input object you can use to get the current stack values. Similarly, you can use set_XXX_input(string input_name, XXX value) to provide a value for a new input.

Any print() calls you make will show up as warnings in the stack after the script is done.

For more in-depth documentation on what you can do with python in Unreal, check out Scripting the Editor using Python.

Python API Listing

See below the Niagara Versioning object API. Click here for the full Unreal Python API Documentation.

upgrade_context API

This returns a UNiagaraPythonScriptModuleInput (see below). If the input does not exist this will return a blank default object instead of throwing an error.

To set a new input by type:

UNiagaraPythonScriptModuleInput API

This returns true when the user sets a value.

This returns true when the input is set to a local value and not a linked attribute or dynamic input.

If bool is_local_value() returns true, then you can convert the input to a python value as follows:

Foundation

Level 1 Tutorials - Beginner

Level 2 Tutorials - Intermediate

The Niagara Tutorials pages provide step-by-step examples on how to work with the Niagara Editor to create visual effects inside Unreal Engine 5.

Whether you want to learn how to create simple ambient effects for the environment, or setup up complex particle interactions, these pages will guide you each step of the way. Reference links are also included to provide more detailed documentation of the systems and content being outlined in each guide. Click the links to visit each page.

Foundation

Niagara comes installed and enabled by default in Unreal Engine 5. If you are not seeing the Niagara options, learn how to manually enable the Niagara plugin.



Describes how you can enable the Niagara Plugin.

Level 1 Tutorials - Beginner

Start here to follow step-by-step tutorials of the basics of Niagara. Create Niagara systems to do simple environment effects like smoke.



This document describes how you can create a smoke effect using sprite particles in Niagara.



This document describes how you can use your GPU to spawn millions of sprite particles.



This document describes how you can use a static mesh to create a balloon effect using Niagara.



How to create particles that emit light in your Niagara system.



This document describes how you can create a ribbon visual effect using Niagara.



This tutorial shows how to modify the sprite smoke effect to create a dark smoke effect.



This how-to describes how to create a steam effect using Niagara.



This page shows how to create a beam effect that simulates lightning.



How to play audio effects within a Niagara simulation

Level 2 Tutorials - Intermediate

Once you are familiar with the basics, these tutorials go a bit further. Learn how to use more than one emitter in a Niagara System.



This tutorial shows how to create a sparks effect using Niagara. It shows how to use more than one emitter in a Niagara system.

How to Enable the Niagara Plugin

End Result

In Unreal Engine 5, the Niagara plugin is installed and enabled by default. However, if you are unable to see the Niagara options then you can check to make sure the plugin is enabled.

How to Enable the Niagara Plugin

First open the Plugins menu by going to Edit > Plugins.



Click image for full size.

In the Plugins menu, locate the FX section. You will see Niagara listed in this section. If the checkbox is checked, Niagara is already enabled. If the checkbox is unchecked, click on it to enable Niagara.



Click image for full size.

If you had to enable Niagara, it will prompt you that a restart is required. Click Restart Now to relaunch the Unreal Editor with the Niagara plugin enabled.



Click image for full size.

End Result

Once the UE4 Editor has restarted, when you right-click in the Content Browser you will have a new FX section that will have all of the Niagara options.



Click image for full size.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Enable the Niagara Plugin

Project Setup

Create the System and Emitter

Change Renderer Settings

Edit the Emitter Update Group Settings

Particle Spawn Group Settings

Particle Update Group Settings

End Result

A commonly used visual effects (VFX) technique is rendering Texture and Materials to 2D camera-facing planes, which are called sprites. In the following tutorial, you will set up a Niagara Emitter to work with sprites. When you place the Niagara System containing the Niagara Emitter into a Level, you will see the effect displayed in that Level.

Prerequisite Steps:

This how-to uses the M_smoke_subUV Material, which can be found with the Starter Content. If you have not done so already, make sure that this Material or the Starter Content has been added to your project.

Project Setup

First, make a new folder in the Content Browser to hold the assets for your effect. Make sure you are at the top level (Content), then right-click in the Content Browser and select New Folder. Name your folder something like SpriteEffect.

If you are going to create multiple Niagara effects in your project, you might want to create a folder called NiagaraFX (or something similar), and then create a sub-folder for your sprite effect.

Before you can create this effect, you need to make or locate a material to use for the sprites in our emitter. For this example, you will use a material from the Starter Content. It is possible to pull in this material without locating it or moving it anywhere, but in some cases you might want to make a copy of the original and put that either in the folder for your effect, or in a separate Materials folder you have previously created. To do so, follow these steps:

Type m_smoke in the search bar of the Content Browser. You should see the M_smoke_subuv material in your search results.



Click image for full size.

To put a copy of it in another folder, just click and drag that material to the desired folder, and in the popup menu select either Move Here or Copy Here. Moving it will delete the original material in its previous location, and move it to the new location. Copying it will create a copy in the new location, while leaving the original in its original location. If you want to create your own material for the sprite, see pages in the Materials section of our documentation.



Create the System and Emitter

Next you will create a Niagara system, and inside it an emitter. The system is a container within which you can put one or more emitters. The emitter is the source of new particles that are generated.

First, create a Niagara System by right-clicking in the Content Browser, and from the displayed menu select FX > Niagara System. The Niagara System wizard displays.



Click image for full size.

Select New system from selected emitters. Then click Next.



Click image for full size.

Under Template, select Simple Sprite Burst. Click the Plus sign icon (+) to add the emitter to the list of emitters to add to the system. Then click Finish.



Click image for full size.

Name the new system SmokeSystem. Double-click to open it in the Niagara Editor.



The emitter instance in your new system has the default name of SimpleSpriteBurst. You can rename it, however. Click the name of the emitter instance in the System Overview, and the field will become editable. Name the emitter FX_Smoke.



Click image for full size.

Change Renderer Settings

In this guide, you will go through the Emitter module groups as they appear in the stack. However, until you set your material in the Renderer you won't see anything in your preview or in your Level. So first, in the System Overview select the Sprite Renderer to open it in the Selection panel.



Click image for full size.

This is where you select the material for our effect. Since the material is a SubUV material, you need to tell the renderer how many images are in the image grid. Set the following properties to the following values.



Click image for full size.

Property Name

Value

Material

M_smoke_subUV

Sub Image Size

X: 8.0, Y: 8.0

Sub UV Blending Enabled

Checked

Drag the SmokeSystem into your Level.

When you make a particle effect, it is always a good idea to drag your system into your Level. This gives you a chance to see every change and edit in context. Any changes you make to the system automatically propagate to the instance of the system in your Level.

Edit the Emitter Update Group Settings

First you will edit the modules in the Emitter Update group. These are behaviors that apply to the emitter, and that update each frame.

In the System Overview, click the Emitter Update group to open it in the Selection panel.



Click image for full size.

You want to create a constant column of smoke, not a burst of smoke. Click the Trashcan icon to delete the Spawn Burst Instantaneous module.



Click image for full size.

Add the Spawn Rate module to the Emitter Update group by clicking the Plus sign icon (+) and selecting Spawn Rate.



Click image for full size.

In the Spawn Rate module, set the Spawn Rate to 50. This will give us a good-sized puffy shape made of smoke. This is a good start to your effect.



Click image for full size.

For now, while you are building the effect, you want to set the simulation to run on an infinite loop. This gives you more time to evaluate how the settings are affecting the effect. In the Emitter State module, click the dropdown for Life Cycle Mode and select Self. Then click the dropdown for Loop Behavior, and select Infinite.



Click image for full size.

Particle Spawn Group Settings

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click the Particle Spawn group to open it in the Selection panel.



Click image for full size.

Expand the Initialize Particle module. This module collects several related parameters together in one module, minimizing clutter in your stack. Under Point Attributes, locate the Lifetime parameter. This parameter determines how long particles will display before they disappear. You want a little randomness in the Lifetime parameter to better simulate real smoke. Set Lifetime Mode to Random, Lifetime Min to 2, and Lifetime Max to 3.



Click image for full size.

Property Name

Value

Lifetime Mode

Random

Minimum

2.0

Maximum

3.0

You are going to adjust the size of the sprite particles, to continue making the smoke effect more realistic. The original bundle of particles is rather small, so you are now going to increase the size. You will also make the size a little random, so the sprite particles overlap and make a more consistent smoke effect. Under Sprite Attributes, locate the Sprite Size parameter and make sure it is enabled. Set Sprite Size Mode to Random Uniform. Enter the following values for Minimum and Maximum.



Click image for full size.

Property Name

Value

Sprite Size Mode

Random Uniform

Uniform Sprite Size Min

75

Uniform Sprite Size Max

200

You now have a larger mass of smoke. Now you are going to add some rotation, to add more variation to the particles' shape. Additionally, you will add randomness to the rotation to increase the variation. Set the dropdown next to Sprite Rotation Mode to Direct Normalized Angle (0-1). This means the rotation angle is calculated as a number between 0 and 1 instead of degrees.



Click image for full size.

Now click the dropdown arrow next to Sprite Rotation Angle, and select Dynamic Inputs > Random Range Float. This adds Minimum and Maximum fields to the Normalized Angle. The particles will rotate a random number of degrees when they spawn.



Click image for full size.

Set the Minimum and Maximum values as shown below.



Click image for full size.

Property Name

Value

Minimum

0.25

Maximum

0.5

So now you have a fairly good size cloud of smoke, but it is just spinning in place. You want the smoke particles to start moving as soon as they spawn. So now you will add some initial velocity. Add the Add Velocity module to the Particle Spawn group by clicking the Plus sign (+) icon and selecting Velocity > Add Velocity.



Click image for full size.

Click the dropdown arrow next to Velocity and select Dynamic Inputs > Random Range Vector. This adds Minimum and Maximum fields to the Velocity. Again, the slight randomness adds variation and naturalness to the effect.



Click image for full size.

Set the Velocity Minimum and Maximum values as shown below.



Click image for full size.

Property Name

Value

Minimum

X: 0, Y: 0, Z: 50

Maximum

X: 1, Y: 1, Z: 200

Shape location controls the shape and origin of where sprites spawn. By adding a Shape Location module, you can have the sprites spawn in different shape primitives. Add the Shape Location module to the Particle Spawn group by clicking the Plus sign (+) icon and selecting Location > Shape Location.



Click image for full size.

Set Shape Primitive to Sphere. By indicating a radius, you can set the size of the sphere shape. Set the Sphere Radius to 64. Make sure the Sphere Distribution is set to Random.



Click image for full size.

The sprite material that we are using for this smoke effect uses a sprite sheet, which has multiple images that are designed to be strung together and animated. When you do not account for this, your renderer will only use the first sprite on the sheet. You can add a SubUV Animation module to solve this problem. Click the Plus sign (+) icon for Particle Spawn and select Sub UV > SubUV Animation.



Click image for full size.

In the Sub UV Animation module, click the dropdown for SubUV Animation Mode and select Linear. For Start Frame type 0, and for End Frame type 63. The sprite sheet has an 8x8 grid of images, so the total number of images is 64.



Click image for full size.

Particle Update Group Settings

Now you will edit the modules in the Particle Update group. These behaviors apply to particles, and update each frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

The velocity you added in Particle Spawn gave the particles some movement when they initially spawn. Now you want to add movement over time, and you want the smoke to rise. Now you will add movement over time, and make the smoke rise. Add the Acceleration Force module by clicking the Plus sign (+) icon for Particle Update and selecting Forces > Acceleration Force.



Click image for full size.

Leave the X and Y values set to 0, and the Z value to 500. This will give the smoke significant upward movement over time. You can adjust this setting, or even remove this module, depending on the type of smoke effect you want to create.



Click image for full size.

If you want to be able to reuse the smoke emitter in your system, you can save it as a separate asset. Click the Gear icon to open the Emitter Settings menu, and select Create Assset From This. The result is an independent Niagara Emitter asset.



Click image for full size.

Then click the Save button to apply and save the changes.

End Result

Congratulations! You have created a simple smoke effect using sprites.



In order to understand and use the content on this page, make sure you are familiar with the following topics:

Enable the Niagara Plugin

Create the System and Emitter

Emitter Settings - Emitter Properties

Emitter Update Group Settings

Particle Spawn Group Settings

Particle Update Group Settings

End Result

For some effects, you may need to spawn tens of thousands of particles. However, using the standard CPU to generate this many particles can cause performance issues. In this guide, we will show you how to create a sprite particle effect that uses the GPU instead of the CPU to run the simulation.

Create the System and Emitter

Niagara emitters and systems are independent. The current recommended workflow is to create a system from existing emitters or emitter templates.

First, create a Niagara System by right-clicking in the Content Browser, and from the displayed menu select FX > Niagara System. The Niagara System wizard displays.



Click image for full size.

Select New system from selected emitters. Then click Next.



Click image for full size.

Under Templates, select Simple Sprite Burst.



Click image for full size.

Click the Plus icon (+) to add the emitter to the list of emitters to add to the system. Then click Finish.



Click image for full size.

Name the new system GPUSprite. Double-click to open it in the Niagara Editor.



Click image for full size.

The emitter instance in your new system has the default name of SimpleSpriteBurst, but you can rename it. Click the name of the emitter instance in the System Overview, and the field will become editable. Name the emitter FX_GPUSprite.



Click image for full size.

Drag the GPUSprite system into your Level.

When you make a particle effect, it is always a good idea to drag your system into your Level. This gives you a chance to see every change and edit in context. Any changes you make to the system automatically propagate to the instance of the system in your Level.

Emitter Settings - Emitter Properties

First, you need to change some settings in the Emitter Properties. This is where you switch from CPU simulation to GPU simulation.

In the System Overview, click Emitter Settings to open it in the Selection panel.



Click image for full size.

Expand Emitter Properties. Locate the Sim Target field. This is where you tell Unreal Engine to use the GPU for the simulation. Click the dropdown and select GPUComputeSim.



Click image for full size.

You may trigger a warning about the Fixed Bounds not being set. Click the box for Fixed Bounds. This will resolve the error. Leave the Minimum and Maximum set to the default values.

Because the particle simulation is done on the GPU, the system cannot read how big the effect is. This is why it is necessary to set fixed bounds. You can do so in the emitter, as shown in this step, or you can set fixed bounds for the entire system in the System Properties item.

Emitter Update Group Settings

Next, you will edit the modules in the Emitter Update group. These are behaviors that apply to the emitter, and that update each frame.

In the System Overview, click Emitter Update to open it in the Selection panel.



Click image for full size.

Expand the Emitter State module. This module controls time and scalability for this emitter. Because you used the Simple Sprite Burst template, the Life Cycle Mode is set to Self. Normally this is used for complete customization of emitter life cycle logic for this specific emitter, but it is not needed for this effect. Click the dropdown and set the Life Cycle Mode to System. This enables your system to calculate the life cycle settings, which usually optimizes performance. By default, the system loops infinitely on a 5 second interval.



Click image for full size.

The Spawn Burst Instantaneous module creates a large burst of particles when the emitter spawns. This module is included in the Simple Sprite Burst template. Set the Spawn Count to 2500. Because Spawn Time is set to 0, the burst occurs immediately upon startup.



Click image for full size.

For this effect, you need more than just a burst of particles when the emitter spawns. The Spawn Rate module creates a continuous stream of particles while the emitter is active. Add the Spawn Rate module by clicking the Plus sign icon (+) for Emitter Update and selecting Spawning > Spawn Rate.



Click image for full size.

Set the Spawn Rate to 500. This will spawn particles at the rate of 500 per second, which will provide a continuous stream of particles after the initial burst.



Click image for full size.

Particle Spawn Group Settings

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click Particle Spawn to open it in the Selection panel.



Click image for full size.

Expand the Initialize Particle module. This module collects several related parameters together in one module, minimizing clutter in your stack. Under Point Attributes, locate the Lifetime parameter.

The Lifetime parameter determines how long particles will display before they disappear. For this effect you want a constant value, so that the particles will display for the entire duration of the effect. Set the Lifetime to 5.



Click image for full size.

You will make the sprite size randomized in another part of this guide, but here we will set the base size of the sprite. Under Sprite Attributes, locate the Sprite Size parameter and make sure it is enabled. Set the Sprite Size to the following.



Click image for full size.

Size Vector

Value

X

5

Y

5

Sphere location controls the shape of the location where sprites spawn. Add the Sphere Location module by clicking the Plus sign icon (+) for Particle Spawn and selecting Location > Sphere Location.



Click image for full size.

By adding the Sphere Location module, the sprites spawn in a sphere shape, and you can set the size of the sphere shape by indicating a radius. Select Sphere from the drop down menu Shape Primitive > Sphere.



Click image for full size.

Particle Update Group Settings

Now you will edit the modules in the Particle Update group. These behaviors apply to an emitter's particles and update each frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

In the Initialize Particle module of the Particle Spawn group, you picked the base size of the sprites. You can randomize the size of the sprites by adding the Scale Sprite Size module. This applies a scaling factor to the base size. Add the Scale Sprite Size module by clicking the Plus sign icon (+) and selecting Size > Scale Sprite Size.



Click image for full size.

Select Non-Uniform from the drop down menu Scale Sprite > Non-Uniform.



Click image for full size.

The default values for Scale Sprite Size are X: 1 and Y: 1. Changing these default values will uniformly make all the particles bigger or smaller. However, random size variation is more visually interesting than a static size. Click the downward arrow next to the Scale Factor field, and select Dynamic Inputs > Vector2D from Float.



Click image for full size.

Notice that the value for Scale Factor has changed to one static value. There are several ways to add a float value, depending on what you want the particles to look like. For a flowing and gradual size change, a curve is ideal. Click the downward arrow next to Value, and select Dynamic Inputs > Float from Curve.



Click image for full size.

Open the Scale Sprite Size module. Click on the Ramp Up Down curve template to apply that shape to the curve.



Click image for full size.

Just click on the template that matches that curve.



Click image for full size.

Right now, your current settings just create a ball of particles that is not very interesting. You can add some additional elements that increase the variation and movement of the particles. Click the Plus sign icon (+) for Particle Update, and select Forces > Curl Noise Force.



Click image for full size.

There are a lot of things you can do with Curl Noise Force. Noise Strength controls how large the overall noise field is (in other words, how much the noise disrupts the original sphere of particles). Noise Frequency controls how often the curl noise is applied to the particles: the smaller the number, the more warped the sphere location of the particles will become. Use the settings below for now, but later you can experiment with these to get a different look.



Click image for full size.

Parameter

Value

Noise Strength

72

Noise Frequency

.02

Now you will see that the particles swirl at first, then just move outward continuously until they die. For this effect, the particles should move outward and then back in toward their origin point, to make a swirling mass. The Point Attraction Force module makes the particles move toward a single point (by default, this point is the emitter's position). Click the Plus sign icon (+) for Particle Update, and select Forces > Point Attraction Force.



Click image for full size.

Attraction Strength is the amount of force pulling the particles to the attractor point. Attraction Radius delineates the size of the field in which the point attraction force applies to the particles. The Falloff Exponent controls how much the sphere spreads; the smaller the number, the more the sphere of particles spreads out. The Kill Radius sets the size of the area where the particles dissolve at the end of their life cycle. Set the Attraction Strength, Attraction Radius, Falloff Exponent, and Kill Radius to the following values.

Click the triangle at the bottom of the module to display the Kill Radius parameter. Check the box to enable it, if it is not already checked.



Click image for full size.

Parameter

Value

Attraction Strength

5.5

Attraction Radius

300.0

Falloff Exponent

0.6

Kill Radius

4.0

Now for changing the color. Add the Color module by clicking the Plus sign icon (+) for Particle Update and selecting Color > Color.



Click image for full size.

Click the downward arrow next to Color, and select General > Dynamic Inputs > Color from Curve.



Click image for full size.

You can add a color stop to the curve by clicking the space above the colored bar, and you can change the color by double clicking a stop to open the Color Picker.



Click image for full size.

To set an opacity stop, click in the space below the bar.



Click image for full size.

To set the time, click in the space below the bar.



Click image for full size.

Set the colors and opacity as shown below.



Click image for full size.

Color or Opacity Stop

Time

Values



Color



Stop 1

0.0

R: 1, G: 0, B: 1

Stop 2

.35

R: .08, G: 0, B: 1

Stop 3

..60

R: .2 , G: 1, B: .8

Stop 4

.8

R: 1, G: .96, B: .3



Opacity



Stop 1

0

1

Stop 2

.7

1

Stop 3

1

0

End Result

Congratulations! You've created a cool sprite effect that uses the GPU instead of the CPU.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Enable the Niagara Plugin

Create a Material

Create the System and Emitter

Change the Renderer

Edit Emitter Update Group Settings

Edit Particle Spawn Group Settings

Edit Particle Update Group Settings

End Result

Spawning a Static Mesh instead of a camera-facing sprite can increase the realism of the effects you are creating. In the following tutorial, we will show how to set up a Niagara Emitter to spawn Static Meshes instead of sprites.

Prerequisite Step: This tutorial uses an imported balloon mesh. You can find free meshes online by doing a simple search. Otherwise, you can practice by using the Shape_Sphere static mesh, which is found with the Starter Content. If you have not done so already, make sure that you have added your own mesh for the balloon to this project, or add the Starter Content to your project.

Create a Material

The effect in this guide is meant to look like a cloud of balloons being released. To enhance this effect, you will make a simple material that makes the mesh look like a rubber balloon.

Right-click in the Content Browser and under Create Basic Asset select Material.



Click image for full size.

Name the new Material Balloon_Material. Double-click it to open in the Material Editor.



Click image for full size.

In the Palette panel, type Particle in the search bar. Select Particle Color and drag it into the Graph to add a Particle Color node.



Click image for full size.

Drag off the RGB output and connect the wire to the Base Color input on the Material node.



Click image for full size.

While holding down the 1 key, click in the Graph. This creates a Constant node. Copy and paste it twice, for a total of three Constant nodes.



Click image for full size.

Connect the output on one Constant node to the Metallic input on the Material node.



Click image for full size.

You can set the Value of a selected constant in the Details panel, under Material Expression Constant. This material is not metallic, so leave the Metallic constant's value at 0.



Click image for full size.

Connect the output on the second Constant node to the Specular input on the Material node.



Click image for full size.

With the Specular constant node selected, set the Specular Value in the Details panel to 0.7. This will give the material a slightly reflective surface.



Click image for full size.

Connect the output on the third Constant node to the Roughness input on the Material node.



Click image for full size.

With the Roughness constant node selected, set the Roughness Value in the Details panel to 0.2. This will create a mostly smooth surface.



Click image for full size.

Your final result for the Material should look like the image below.



Create the System and Emitter

Niagara emitters and systems are independent. The current recommended workflow is to create a system from existing emitters or emitter templates.

First, create a Niagara System by right-clicking in the Content Drawer and selecting FX > Niagara System. The Niagara Emitter wizard displays.



Click image for full size.

Select New system from selected emitters. Then click Next.



Click image for full size.

Under Templates, select Fountain.



Click image for full size.

Click the Plus sign (+) icon to add the emitter to the list of emitters to add to the system. Then click Finish.



Click image for full size.

Name the new system Balloon_System. Double-click to open it in the Niagara Editor.



Click image for full size.

The emitter instance in your new system has the default name of Fountain, but you can rename it. Click the name of the emitter instance in the System Overview, and the field will become editable. Name the emitter Balloons.



Click image for full size.

Drag your MeshSystem into your Level.



Click image for full size.

When you make a particle effect, it is always a good idea to drag your system into a Level. This gives you a chance to see every change and edit in context. Any changes you make to the system automatically propagate to the instance of the system in your level.

Change the Renderer

The Render group is last in the stack, but you need to change some things so that the effect displays the way it is supposed to. In this case, the template contains a Sprite Renderer, and this effect needs a Mesh Renderer.

In the System Overview, click Render to open it in the Selection panel.



Click image for full size.

To make a mesh particle effect you need a Mesh Renderer module, but the template has a Sprite Renderer module. Click the Trashcan icon to delete the Sprite Renderer.



Click image for full size.

Click the Plus sign (+) icon for Render and select Mesh Renderer.



Click image for full size.

Click the dropdown for Particle Mesh and select your mesh. If you imported your own balloon model, select that. Or to test, you can select Shape_Sphere from the sample material.



Click image for full size.

Your mesh may be too small or too big to show up well in your level. If needed, adjust the size here. Your mesh may have a default material applied to it. By enabling Override Materials, you can use the custom material you created instead. Click to enable Override Materials, then click the Plus sign (+) icon to add an element to the array.



Click image for full size.

Click the dropdown for Explicit Mat, and select the material you created earlier, Balloon_Material.



Click image for full size.

Edit Emitter Update Group Settings

First, you will edit the modules in the Emitter Update group. These are behaviors that apply to the emitter, and that update each frame.

In the System Overview, click the Emitter Update group to open it in the Selection panel.



Click image for full size.

Expand the Emitter State module. Because you used the Fountain template, the Life Cycle Mode is set to Self. Click the dropdown and set the Life Cycle Mode to System. This enables your system to calculate the lifecycle settings, which usually optimizes performance.



Click image for full size.

The Spawn Rate module creates a continuous stream of particles while the emitter is active. This module is already present in the Fountain template. Set the Spawn Rate to 100.



Click image for full size.

Edit Particle Spawn Group Settings

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click the Particle Spawn group to open it in the Selection panel.



Click image for full size.

Expand the Initialize Particle module. This module collects several related parameters together in one module, minimizing clutter in your stack. Under Point Attributes, locate the Lifetime parameter. This parameter determines how long particles will display before they disappear. For Lifetime Mode, select Random. Set the Minimum and Maximum values to the following.



Click image for full size.

Setting

Value

Minimum

2.0

Maximum

4.0

Locate the Color parameter. You can choose to have all your balloons be one solid color, or use one of the other modes to add some variety. In this example, you can set the Color Mode to Random Range. This will create your balloons in random colors that fall in a range between two set colors. Change the RGB values until you achieve the look you like. The colors you set here are applied to the material you created earlier. In this example, the colors are set to red and blue.



Click image for full size.

Setting

Color Minimum

Color Maximum

Red

1.0

0.0

Green

0.0

0.0

Blue

0.0

1.0

Under Sprite Attributes, set Sprite Size Mode, Sprite Rotation Mode, and Sprite UV Mode to Unset. Since you are using a mesh, these attributes are not needed for this effect.



Click image for full size.

When you first set your mesh, you may have resized it at that time. But you may want some variation in the size, so some balloons are larger than others. Under Mesh Attributes, set Mesh Scale Mode to Random Uniform. Set the Mesh Uniform Scale Min to 0.7 and Mesh Uniform Scale Max to 1.0. If you used a sphere instead of a balloon mesh, you may want to set the Mesh Scale Mode to Random Non-Uniform to give some irregularity to the shape of your spheres.



Click image for full size.

The Add Velocity in Cone module is not needed for the effect you are making. You don't want the balloons to spread out in a cone shape. Click on the trash can to remove this module from your stack.



Click image for full size.

The Add Velocity module will give the particles movement as soon as they spawn. Add the Add Velocity module to the Particle Spawn section by clicking the Plus sign (+) icon and selecting Add Velocity.



Click image for full size.

Because this effect is meant to look like balloons being released, some randomness to the speed of the particles is needed. Click the downward arrow next to the Velocity value fields, and select Random Range Vector. This adds minimum and maximum velocity fields so that each balloon can be assigned a velocity value from within this range, adding randomness.



Click image for full size.

Set the Velocity Minimum and Maximum values to the following. This gives the effect a small amount of movement on the X and Y axes, and a larger amount of movement on the Z axis.



Click image for full size.

Setting

Value

Minimum

X: 15, Y: 25, Z: 50

Maximum

X: 30, Y: 30, Z: 100

The Sphere Location module module controls the shape of the location where sprites spawn. You can have the sprites spawn in a sphere shape, and you can set the size of the sphere shape by indicating a radius. Set the Sphere Radius to 200. This spreads the particles out more, as balloons would do when released.



Click image for full size.

Edit Particle Update Group Settings

Now you will edit the modules in the Particle Update group. These behaviors apply to an emitter's particles and update each frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

Typically, you would use the Gravity Force module to simulate how gravity affects objects. You can also use it more generally to add acceleration to your particles. Set the Gravity Force X, Y and Z values to the following.



Click image for full size.

Setting

Value

X

10

Y

10

Z

40

The Drag module applies drag to the particles, which slows them down. Set the Drag to 1.0.



Click image for full size.

The Scale Color module is part of the Fountain template, but this effect does not require it. Click the Trash can icon to remove the Scale Color module.



Click image for full size.

End Result

Congratulations! You've made a mesh particle effect in Niagara. You learned how to create a material, apply the particle color to that material, and use a static mesh as your particles. Continue to explore the options in the modules to refine the effect.



In order to understand and use the content on this page, make sure you are familiar with the following topics:

Enable the Niagara Plugin

Create the System and Emitter

Edit the Emitter Update Group Settings

Edit the Particle Spawn Group Settings

Edit the Particle Update Group Settings

Add the Light Renderer

End Result

When you give particles the ability to illuminate the world around them, it can add an extra layer of realism to any of your project's visual effects. In the following tutorial, we will take a look at setting up a Niagara emitter so that particles and lights are spawned at the same time. The final result of this tutorial will look like the following.



Prerequisite step: This tutorial uses the M_Radial_Gradient Material, which is found with the Starter Content. You should create a new project that includes the Starter Content, or use a project that was created with Starter Content included.

Create the System and Emitter

Niagara emitters and systems are independent. The current recommended workflow is to create a system from existing emitters or emitter templates.

First, create a Niagara System by right-clicking in the Content Browser, and from the displayed menu select FX > Niagara System. The Niagara Emitter wizard displays.



Click image for full size.

Select New system from selected emitters, then click Next.



Click image for full size.

Under Templates, select Fountain.



Click image for full size.

Click the Plus sign (+) icon to add the emitter to the list of emitters to add to the system, then click Finish.



Click image for full size.

Name the new system ParticleLights. Double-click to open it in the Niagara Editor.



The emitter instance in your new system has the default name of Fountain. You can rename it, however. Click the name of the emitter instance in the System Overview, and the field will become editable. Name the emitter FX_ParticleLight.



Click image for full size.

Drag your ParticleLight system into your Level.

When you make a particle effect, it is always a good idea to drag your system into a Level. This gives you a chance to see every change and edit in context. Any changes you make to the system automatically propagate to the instance of the system in your level.

Edit the Emitter Update Group Settings

First, you will edit the modules in the Emitter Update group. These are behaviors that apply to the emitter, and that update each frame.

In the System Overview, click the Emitter Update group to open it in the Selection panel.



Click image for full size.

Expand the Emitter State module. Because you used the Fountain template, the Life Cycle Mode is set to Self. Click the dropdown and set the Life Cycle Mode to System. This enables your system to calculate the lifecycle settings, which usually optimizes performance.



Click image for full size.

The Spawn Rate module creates a continuous stream of particles while the emitter is active. This module is already present in the Fountain template. Set the Spawn Rate to 500.



Click image for full size.

Edit the Particle Spawn Group Settings

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click the Particle Spawn group to open it in the Selection panel.



Click image for full size.

Expand the Initialize Particle module. This module collects several related parameters together in one module, minimizing clutter in your stack. Under Point Attributes, locate the Lifetime Mode dropdown and set to Random. This parameter determines how long particles will display before they disappear. For this effect, you will use a dynamic input called Random Ranged Float to randomize how long the particles display. Random Ranged Float is already applied to the Lifetime parameter in the Fountain template. Set the Minimum and Maximum values to the following.



Click image for full size.

Setting

Value

Lifetime Mode

Random

Minimum

1.75

Maximum

2.5

Also under Point Attributes, locate the Color parameter. This sets the initial color of the particles when they spawn. Set the RGB fields to the following values.

The Unreal Engine Color Picker normalizes RGB color values to an integer between 0 and 1. However if you set a color value greater than 1, it becomes emissive color. The particles will glow that color when the system is placed in the Level.



Click image for full size.

Setting

Value

Red

0.1

Green

0.3

Blue

50

Under Sprite Attributes, locate the Sprite Size parameter. To add some randomness to the size of the fountain particles, adjust the Sprite Size Mode. Click on the dropdown menu and select Random Uniform. This adds Minimum and Maximum fields to the Value. Set the Sprite Size Minimum and Maximum values to the following.



Click image for full size.

Setting

Value

Sprite Size Mode

Random Uniform

Minimum

2.5

Maximum

8.0

Sphere location controls the shape and origin of where sprites spawn. You can set the size of the sphere shape by indicating a radius. The Sphere Location module is included in the Fountain template. Set the Sphere Radius to 15.



Click image for full size.

The Fountain template also contains the Add Velocity in Cone module. This adds movement to the particles when they spawn. The point of the cone is at the particle spawn point, and you can set X, Y, and Z values to determine in which direction the cone expands. The Velocity Strength has a dynamic input called Random Ranged Float applied. Set the Minimum and Maximum values to the following. Leave the other settings at their default values.



Click image for full size.

Setting

Value

Minimum

300

Maximum

600

Edit the Particle Update Group Settings

Now you will edit the modules in the Particle Update group. These behaviors apply to an emitter's particles and update each frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

The Gravity Force module simulates how gravity affects objects. The Drag module applies drag to the particles, which slows them down. The default settings for Gravity Force and Drag work for this effect, so you can leave them that way.

Without setting up collision, the particles in your effect will just fall through the floor or any other solid objects in the level. To add a Collision module, click the Plus sign (+) icon for Particle Update and select Collision > Collision.



Click image for full size.

The Collision module is inserted at the bottom of the stack, after the Solve Forces and Velocity module. This causes an error. Click Fix Issue to move the Collision module and resolve the error.



Click image for full size.

Leave the default settings for the Collision module in place.

Add the Light Renderer

Now you will add the Light Renderer to the fountain effect.

In the System Overview, click the Render group to open it in the Selection panel.



Click image for full size.

Click the Plus sign (+) icon for Render, and select Light Renderer.



Click image for full size.

Set the Radius Scale to 5.0. This determines how far from the particle spawn point the light spreads.



Click image for full size.

The Color Add values enable you to change the color of the light emitted by the effect. These values are labeled with X, Y, and Z; however they correspond to RGB values, with X=Red, Y=Green, and Z=Blue. To match the light color with the particle color, set the values to the following.

Setting

Value

Red

0

Green

0

Blue

15

End Result

Congratulations! You have created an effect that includes a particle light, and that emits light in your scene.



In order to understand and use the content on this page, make sure you are familiar with the following topics:

Enable the Niagara Plugin

Create System and Emitter

Change Renderer

Edit the Emitter Update Group Settings

Edit the Particle Spawn Group Settings

Edit the Particle Update Group Settings

End Result

Prerequisite Step: This tutorial uses the DefaultRibbonMaterial, which is included in the content for the Niagara plugin. However, you can also use the M_Balloon material you created in the Create a Mesh Particle Effect tutorial if you have already completed it.

Simulating natural phenomena is challenging, especially when using sprite or mesh-based particles to simulate smoke or vapor trails. Ribbon Emitters are an excellent solution for simulating these objects. In the following tutorial, you will learn how to set up a Niagara Emitter to create a continuous ribbon-style particle effect into the world. Your end result will look like the following.



Create System and Emitter

Unlike in Cascade, Niagara emitters and systems are independent. The current recommended workflow is to create a system from existing emitters or emitter templates.

First, create a Niagara System by right-clicking in the Content Drawer, and selecting FX > Niagara System.



Click image for full size.

Select New system from selected emitters. Then click Next.



Click image for full size.

Under Templates, select Simple Sprite Burst.

Using a template will place an emitter instance in your new system, and that emitter instance will have no inheritance.



Click image for full size.

Click the Plus sign icon (+) to add the selected emitter to the list of emitters to add to the system. Then click Finish.



Click image for full size.

Name the new system RibbonSystem.



Drag the RibbonSystem into your Level. Double-click to open the system in the Niagara Editor.

When you make a particle effect, it is always a good idea to drag your system into a Level. This gives you a chance to see every change and edit in context. Any changes you make to the system automatically propagate to the instance of the system in your Level.

The emitter instance in your new system has the default name of SimpleSpriteBurst, but you can rename it. Click the name of the emitter instance in the System Overview, and the field will become editable. Name the emitter FX_Ribbon.



Click image for full size.

Change Renderer

The Render group is last in the stack, but you need to change some things so that the effect displays the way it is supposed to. The original template used a Sprite Renderer, but this effect needs a Ribbon Renderer.

In the System Overview, click Render to open it in the Selection panel.



Click image for full size.

To make a ribbon effect, you need a Ribbon Renderer module. But the template has a Sprite Renderer module. Click the Trashcan icon to delete the Sprite Renderer.



Click image for full size.

Click the Plus sign icon (+) for Render and select Ribbon Renderer.



Click image for full size.

The material you want is not displayed by default. Click the dropdown for Material, and click View Options to open a list of options. Check the boxes for Show Engine Content and Show Plugin Content. Now you will be able to see the material.



Click image for full size.

Click the dropdown for Material and select DefaultRibbonMaterial.

If you completed the Create a Mesh Particle Effect tutorial, you can select the M_Balloon material instead. This will give you an opaque ribbon, rather than the translucent one created by the DefaultRibbonMaterial.



Click image for full size.

Edit the Emitter Update Group Settings

First, you will edit the modules in the Emitter Update group. These are behaviors that apply to the emitter, and that update each frame.

Even after adding a Ribbon Renderer and editing the settings in the Emitter Update group, you will not see a ribbon appear. This is normal! When you get to the Particle Spawn section of this document, you will start to see the actual ribbon.

In the System Overview, click the Emitter Update group to open it in the Selection panel.



Click image for full size.

Expand the Emitter State module. This module controls time and scalability for this emitter. Because you used the Simple Sprite Burst template, the Life Cycle Mode is set to Self. Normally this is used for complete customization of emitter life cycle logic for this specific emitter, but it is not needed for this effect. Click the dropdown and set the Life Cycle Mode to System. This enables your system to calculate life cycle settings, which usually optimizes performance. By default, the system loops infinitely on a 5 second interval.



Click image for full size.

The Spawn Rate module creates a continuous stream of particles while the emitter is active. Add the Spawn Rate module by clicking the Plus sign icon (+) for Emitter Update and selecting Spawning > Spawn Rate.



Click image for full size.

Set the Spawn Rate to 100.



Click image for full size.

Edit the Particle Spawn Group Settings

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click the Particle Spawn group to open it in the Selection panel.



Click image for full size.

Under Point Attributes, locate the Lifetime parameter. This parameter determines how long particles will display before they disappear. Set the Lifetime to 5.



Click image for full size.

For the Color parameter, set it to a color of your choosing. You can do this either by typing in RGB values, or by clicking on the swatch to open a color picker.



Click image for full size.

Set the Mass parameter to 10. This will affect how the ribbon spreads outward, as well as how quickly it falls.



Click image for full size.

Under Ribbon Attributes, set the Ribbon Width to 10.



Click image for full size.

To make the ribbon spin in a spiral, you can add a Shape Location module. Location modules affect the shape of the location where the particles spawn. Click the Plus sign icon (+) for Particle Spawn and select Location > Shape Location.



Click image for full size.

Under Shape, click the dropdown for Shape Primitive and select Ring / Disk.



Click image for full size.

Set the Ring Radius to 50. The Ring Radius determines how large the primary ring shape is.



Click image for full size.

Under Distribution, click the dropdown for Ring Distribution Mode and select Direct.



Click image for full size.

Now you will add some velocity to the ribbon. Click the Plus sign icon (+) for Particle Spawn and select Velocity > Add Velocity.



Click image for full size.

Click the dropdown to Velocity Mode and select From Point.



Click image for full size.

Set the Velocity Speed to 50. Now you will see the ribbon start to spiral! This happens because as the position is moving around the Large Radius, the velocity pushes the ribbon outward from the original ring.



Click image for full size.

Edit the Particle Update Group Settings

Now you will edit the modules in the Particle Update group. These behaviors apply to an emitter's particles and update each frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

This effect has a single color, so the Scale Color module is not needed. Click the Trashcan icon to delete it.



Click image for full size.

Add the Acceleration Force module. This is what makes the spiraling ribbon fall down, simulating gravity. Click the Plus sign icon (+) for Particle Update and select Forces > Acceleration Force.



Click image for full size.

Set the Z value of the Acceleration to -200. A positive Z value would make the ribbon spiral upwards; using a negative value makes it drop downward in a parabolic shape.



Click image for full size.

End Result

Congratulations! You have created a Niagara ribbon effect.



Create System and Emitter

Edit the Emitter Update Settings

Edit the Particle Spawn Settings

Edit the Particle Update Settings

End Result

You created a basic sprite effect by completing the Create a Sprite Smoke Effect in Niagara tutorial. In this tutorial, learn how to duplicate an emitter, create a Niagara system from a pre-existing emitter, and make further adjustments to change the look of the smoke.

Prerequisite Steps:

This how-to uses the M_smoke_subUV Material, which can be found with the Starter Content. If you have not done so already, make sure that your project includes the Starter Content. This how-to also uses the FX_Smoke emitter created in the tutorial Create a Sprite Smoke Effect in Niagara.

Create System and Emitter

You can create a Niagara system from scratch by right-clicking in the Content Drawer as has been done in previous tutorials. However, if you already have a saved emitter to use as a starting point, it's also possible to duplicate it and start from there.

Create a new folder for this tutorial in the Content folder for your project.

Make a copy of the FX_Smoke emitter you created in Create a Sprite Particle Effect in Niagara.



Click image for full size.

Drag this duplicate emitter to the folder you created in step 1. In the popup context menu, select Move.

Rename the copied emitter FX_DarkSmoke. This distinguishes it from the smoke effect created in the Create a Sprite Smoke Effect in Niagara tutorial.



Right-click on your new smoke emitter, and select Create Niagara System.



There are multiple ways to create new Niagara systems. Because you are starting with an emitter you have already created, the method used here quickly creates a system containing that emitter.

Name the system DarkSmoke. This is to distinguish it from the smoke effect created in the Create a Sprite Smoke Effect in Niagara tutorial.



Drag the DarkSmoke system from the Content Drawer into your Level, so you can preview the changes in the context of your project's world.



Click image for full size.

When you make a particle effect, it is always a good idea to drag your system into your Level. This gives you a chance to see every change and edit in context. Any changes you make to the system automatically propagate to the instance of the system in your Level.

Double-click the FX_DarkSmoke emitter to open it in the Niagara Editor. After you have edited the settings in the emitter, you will need to save the DarkSmoke system also.

Edit the Emitter Update Settings

First you will edit the modules in the Emitter Update group. These are behaviors that apply to the emitter itself, and that update each frame.

In the System Overview, click the Emitter Update group to open it in the Selection panel.



Click image for full size.

Expand the Emitter State module. This module controls time and scalability for this emitter. Because you used the Simple Sprite Burst template, the Life Cycle Mode is set to Self.

Normally this is used for complete customization of emitter life cycle logic for this specific emitter, but it is not needed for this effect. Click the dropdown and set the Life Cycle Mode to System. This enables your system to calculate life cycle settings, which usually optimizes performance. By default, the system loops infinitely on a 5 second interval.



Open the Spawn Rate module. Set the Spawn Rate to 25.



Click image for full size.

Edit the Particle Spawn Settings

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click the Particle Spawn group to open it in the Selection panel.



Click image for full size.

Open the Initialize Particle module. Under Point Attributes, expand Lifetime. The Lifetime parameter determines how long particles will display before they disappear. Change the Lifetime Mode, Minimum and Maximum values to the following.



Click image for full size.

Parameter

Value

Lifetime Mode

Random

Minimum

3.0

Maximum

5.0

Expand Color. You can set the smoke to a single color, or change the Color Mode to Random Range to get some variability in the color of each particle. Change the RGB values to the following:



Click image for full size.

Color

Minimum

Maximum

Red

0.5

0.205

Green

0.5

0.205

Blue

0.5

0.205

Under Sprite Attributes, expand Sprite Size. Make sure Sprite Size Mode is set to Random Uniform, which gives minimum and maximum values. New particles will be created at a random size between these values. Change the Minimum and Maximum values to the following:



Click image for full size.

Parameter

Value

Minimum

50

Maximum

90

Open the Add Velocity module. In the previous tutorial, we had set the Velocity to Random Range Vector. This adds Minimum and Maximum values. Each new particle that is created has a random value between these two ranges set for its initial velocity. Change the Velocity Minimum and Maximum values to the following:



Click image for full size.

Value

Minimum

Maximum

X

12

32

Y

0

0

Z

5

7

Open the Sphere Location module. New particles are generated within the sphere when they are first created. Change the Sphere Radius value to 30.



Click image for full size.

Edit the Particle Update Settings

Now you will edit the modules in the Particle Update group. These behaviors apply to an emitter's particles and update each frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

Open the Acceleration Force module. Set the Acceleration Z value to 20.



Click image for full size.

Open the Scale Color module. Make sure the Scale Mode is set to RGB and Alpha Separately. You only want to adjust the alpha values so that the color fades in and then pulses out as the particle ages. Scale Alpha should be set to Float from Curve. Click on the Pulse template in the curve editor to quickly apply this shape to the curve.



Click image for full size.

End Result

After following these steps, the Smoke system in your level will produce a smoke effect similar to the one in the image below.



Create the Steam Emitter and System

Edit the Emitter Update Settings

Edit the Particle Spawn Settings

Edit the Particle Update Settings

End Result

Prerequisite Steps:

This How-To uses the M_smoke_subUV Material, which can be found with the Starter Content. If you have not done so already, make sure that your project includes the Starter Content. This how-to also uses the FX_Smoke emitter created in Create a Sprite Particle Effect in Niagara.

Create the Steam Emitter and System

Niagara emitters and systems are independent. The current recommended workflow is to create a system from existing emitters or emitter templates. However, since you are duplicating an existing emitter, the process will be slightly different.

Create a new folder for this How-To in the Content folder for your project.

Locate the FX_Smoke emitter you saved when working through Create a Sprite Particle Effect in Niagara. Right-click on the emitter, and select Duplicate Emitter.



Click image for full size.

Drag this duplicate emitter to the folder you created in step 1. In the popup context menu, select Move.

Rename the copied emitter FX_Steam.



Now create a system for your steam effect. Right-click on your new steam emitter, and select Create Niagara System.



Click image for full size.

There are multiple ways to create new Niagara systems. Because you are starting with an emitter you have already created, the method used here quickly creates a system containing that emitter. However, as you saw in the Create a Sprite Particle Effect how-to, there are emitter and system wizards that give you many other options for creating and setting up a Niagara system.

Name the system Steam.



Open your Level in the Level Editor, if it isn't open already. Drag the Steam system into your level.



Click image for full size.

When you make a particle effect, it is always a good idea to drag your system into your level. This gives you a chance to see every change and edit in context. Any changes you make to the system automatically propagate to the instance of the system in your level.

Edit the Emitter Update Settings

First you will edit the modules in the Emitter Update group. These are behaviors that apply to the emitter itself, and that update each frame.

In the System Overview, click the Emitter Update group to open it in the Selection panel.



Click image for full size.

Expand the Emitter State module.This module controls time and scalability for this emitter. Because you used the Simple Sprite Burst template, the Life Cycle Mode is set to Self. Normally this is used for complete customization of emitter life cycle logic for this specific emitter, but it is not needed for this effect. Click the dropdown and set the Life Cycle Mode to System. This enables your system to calculate life cycle settings, which usually optimizes performance. By default, the system loops infinitely on a 5 second interval.



Click image for full size.

Expand the Spawn Rate module. Change the Spawn Rate setting to 30.



Click image for full size.

Edit the Particle Spawn Settings

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click the Particle Spawn group to open it in the Selection panel.



Click image for full size.

Open the Initialize Particle module. Under Point Attributes, expand Lifetime. Change the Minimum and Maximum values to the following:



Click image for full size.

Parameter

Value

Minimum

3.0

Maximum

7.0

Expand Color. Change the RGB values to the following:



Click image for full size.

Parameter

Value

Red

1.0

Green

1.0

Blue

1.0

Under Sprite Attributes, expand Sprite Size. Change the Minimum and Maximum values to the following:



Click image for full size.

Parameter

Value

Minimum

100

Maximum

200

Open the Add Velocity module. Change the Velocity Minimum and Maximum values to the following:



Click image for full size.

Parameter

Value

Minimum

X: 16, Y: -5.0, Z: 35

Maximum

X: 32, Y: 5.0, Z: 50

Open the Sphere Location module. Change the Sphere Radius value to 20.



Click image for full size.

Edit the Particle Update Settings

Now you will edit the modules in the Particle Update group. These behaviors apply to particles and update each frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

Open the Acceleration Force module. Set the Acceleration Minimum and Maximum values to the following:



Click image for full size.

Parameter

Value

Minimum

X: 25, Y: -10.0, Z: 15

Maximum

X: 55, Y: 10.0, Z: 25

Open the Scale Color module. Click on the Pulse Out curve template to apply that shape to the curve.



Click image for full size.

Just click on the template that matches that curve.



Click image for full size.

Click the Plus sign icon (+) in the Particle Update group, and select Forces > Drag to add the Drag module.



Click image for full size.

Because Niagara adds new modules to the bottom of the group's stack, you will get an error stating "The module has unmet dependencies." That is because the Drag module was placed after the Solve Forces and Velocity module. Click the Fix Issue button to move the module and resolve the error.



Click image for full size.

Set the Drag to .8.



Click image for full size.

End Result

After following these steps, the Steam system in your level will produce a steam effect similar to the one in the image below.

Create the Smoke Emitter and the Sparks System

Smoke Emitter - Edit the Emitter Update Settings

Smoke Emitter - Edit the Particle Spawn Settings

Smoke Emitter - Edit the Particle Update Settings

Add the Spark Burst Emitter to the System

Spark Burst Emitter - Edit Render Settings

Spark Burst Emitter - Edit the Emitter Update Settings

Spark Burst Emitter - Edit the Particle Spawn Settings

Spark Burst Emitter - Edit the Particle Update Settings

Add the Radial Sparks Emitter to the System

Radial Sparks Emitter - Edit Render Settings

Radial Sparks Emitter - Edit the Emitter Update Settings

Radial Sparks Emitter - Edit Particle Spawn Settings

Radial Sparks Emitter - Edit the Particle Update Settings

End Result

Prerequisite Steps:

This tutorial uses the M_smoke_subUV, M_Spark, and M_Radial_Gradient materials, which can be found with the Starter Content. If you have not done so already, make sure that your project includes the Starter Content. This tutorial also uses the FX_Smoke emitter created in the how-to Create a Sprite Particle Effect in Niagara.

To create the Sparks effect included in the Starter Content, you will need to make three Niagara emitters: one for the fountain of sparks, one for the spark at the center, and one for the small stream of smoke rising from the fountain of sparks.

The final effect will look like the following.



You will start with the smoke emitter, because you can create it using a copy of an existing emitter.

Create the Smoke Emitter and the Sparks System

Niagara emitters and systems are independent. The current recommended workflow is to create a system from existing emitters or emitter templates.

Create a new folder for this tutorial in the Content folder for your project.

Make a copy of the FX_Smoke emitter you created in Create a Sprite Particle Effect in Niagara.



Click image for full size.

Drag this duplicate emitter to the folder you created in step 1. In the popup context menu, select Move.

Rename the copied emitter FX_Sparks_Smoke.



Now create a system for your spark effect. Right-click on your new smoke emitter, and select Create Niagara System.



Click image for full size.

There are multiple ways to create new Niagara systems. Because you are starting with an emitter you have already created, the method used here quickly creates a system containing that emitter. However, as you saw in the Create a Sprite Particle Effect tutorial, there are emitter and system wizards that give you many other options for creating and setting up a Niagara system.

Name the system SparksSystem.



Open your Level in the Level Editor, if it isn't open already. Drag the SparksSystem tile from the Content Drawer into your Level.

When you make a particle effect, it is always a good idea to drag your system into your level. This gives you a chance to see every change and edit in context. Any changes you make to the system automatically propagate to the instance of the system in your level.





Click image for full size.

Smoke Emitter - Edit the Emitter Update Settings

In the System Overview, click the Emitter Update group to open it in the Selection panel.



Click image for full size.

Open the Emitter State module. This module controls time and scalability for this emitter. Click the dropdown and set the Life Cycle Mode to System. This enables your system to calculate life cycle settings, which usually optimizes performance. By default, the system loops infinitely on a 5 second interval.



Click image for full size.

Open the Spawn Rate module. Change the Spawn Rate setting to 20.



Click image for full size.

Smoke Emitter - Edit the Particle Spawn Settings

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click the Particle Spawn group to open it in the Selection panel.



Click image for full size.

Open the Initialize Particle module. Under Point Attributes, expand Lifetime. Change the Minimum and Maximum values to the following.



Click image for full size.

Parameter

Value

Lifetime Mode

Random

Minimum

2.0

Maximum

3.0

Locate the Color parameter. Change the RGB values to the following.



Click image for full size.

Parameter

Value

Red

0.3

Green

0.3

Blue

0.3

Under Sprite Attributes, expand Sprite Size. Set the Sprite Size Mode to Non-Uniform. Set the Minimum and Maximum values to the following.



Click image for full size.

Parameter

Value

Sprite Size Mode

Random Uniform

Minimum

20.0

Maximum

40.0

Open the Add Velocity module. Change the Velocity Minimum and Maximum values to the following.



Click image for full size.

Velocity

Minimum

Maximum

X

0.0

1.0

Y

0.0

1.0

Z

25.0

35.0

Open the Shape Location module. Change the Sphere Radius value to 5.



Click image for full size.

Smoke Emitter - Edit the Particle Update Settings

Now you will edit the modules in the Particle Update group. These behaviors apply to an emitter's particles and update each frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

Open the Scale Color module. Click to deselect the box next to Scale RGB. Above the curve for Scale Alpha, click the Smooth Ramp Down template to apply that shape to the curve.



Click image for full size.

Open the Acceleration Force module. Set the Acceleration values to X: 0, Y: 0, Z: 20.



Click image for full size.

At this stage in the process, you have finished configuring the first emitter in the system. It should look similar to the following.



Add the Spark Burst Emitter to the System

Next, you will create the spark burst at the center of the effect.

Right-click in the System Overview of your SparkFountain system. Click Add Emitter, and a list of existing emitters will display. From the list of emitters, select the Simple Sprite Burst template.



Click image for full size.

The default name for the template emitter is SimpleSpriteBurst, but you can rename it. Click on the emitter name, and the field becomes editable. Name the new emitter FX_SparkBurst.



Click image for full size.

Spark Burst Emitter - Edit Render Settings

The Render group is last in the stack, but you need to change the material so that the effect displays the way it is supposed to.

In the System Overview, click the Render group to open it in the Selection pane.



Click image for full size.

Under Sprite Renderer, click the dropdown for Material, and select the M_Spark material from the Starter Content.



Click image for full size.

Spark Burst Emitter - Edit the Emitter Update Settings

First, you will edit the modules in the Emitter Update group. These are behaviors that apply to the emitter, and that update each frame.

In the System Overview, click the Emitter Update group to open it in the Selection panel.



Click image for full size.

Remove the Sprite Burst Instantaneous module by clicking the Trashcan icon.



Click image for full size.

Open the Emitter State module. This module controls time and scalability for this emitter. Because you used the Simple Sprite Burst template, the Life Cycle Mode is set to Self. Normally this is used for complete customization of emitter life cycle logic for this specific emitter, but it is not needed for this effect. Click the dropdown and set the Life Cycle Mode to System. This enables your system to calculate life cycle settings, which usually optimizes performance. By default, the system loops infinitely on a 5 second interval.



Click image for full size.

Click the Plus sign (+) for Emitter Update, and select Spawning > Spawn Rate.



Click image for full size.

Open the Spawn Rate module. Set the Spawn Rate to 50.



Click image for full size.

Spark Burst Emitter - Edit the Particle Spawn Settings

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click the Particle Spawn group to open it in the Selection panel.



Click image for full size.

Under Point Attributes, set the Lifetime to .2.



Click image for full size.

Set the Mass Mode to Random and the Minimum and Maximum values to the following:



Click image for full size.

Parameter

Value

Mass Mode

Random

Minimum

0.6

Maximum

1.0

Under Sprite Attributes, expand Sprite Size. Set the Sprite Size Mode to Random Non-Uniform. Set the Sprite Size Minimum and Maximum values to the following:



Click image for full size.

Sprite Size

Minimum

Maximum

X

10.0

30.0

Y

10.0

25.0

Click the box next to Sprite Rotation to enable it. Set the Sprite Rotation Mode to Direct Angle (Degrees). Click the dropdown next to the Value field, and select Dynamic Inputs > Random Range Float.



Click image for full size.

Set the Minimum and Maximum to the following:



Click image for full size.

Parameter

Value

Minimum

-10.0

Maximum

30.0

Click the Plus sign (+) for Particle Spawn, and select Velocity > Add Velocity.



Click image for full size.

Open the Add Velocity module. Click the dropdown next to the value, and select Dynamic Inputs > Random Range Vector.



Click image for full size.

Set the Velocity Minimum and Maximum to the following:



Click image for full size.

Velocity

Minimum

Maximum

X

0.0

5.0

Y

0.0

5.0

Z

0.0

5.0

Click the Plus sign (+) for Particle Spawn, and select Location > Shape Location.



Click image for full size.

Open the Shape Location module. Set the Sphere Radius to 5.



Click image for full size.

Spark Burst Emitter - Edit the Particle Update Settings

Now you will edit the modules in the Particle Update group. These behaviors apply to an emitter's particles and update each frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

Open the Scale Color module. For Scale RGB, set the RGB values to the following. Under Scale Alpha, select the Smooth Ramp Down template.



Click image for full size.

Color

Value

R

2.0

G

6.0

B

25.0

Click the Plus sign icon (+) for Particle Update, and select Size > Scale Sprite Size. You can also type scale in the search bar, as shown below.



Click image for full size.

Open the Scale Sprite Size module. Click the dropdown next to the Scale Factor value field, and select Dynamic Inputs > Random Range Vector 2D. You can also type random in the search bar.



Click image for full size.

Set the Scale Factor Minimum and Maximum to the following:



Click image for full size.

Scale

Minimum

Maximum

X

1.0

3.5

Y

2.5

5.0

At this stage in the process, you have finished configuring the second emitter in the system. It should look similar to the following.



Add the Radial Sparks Emitter to the System

Right-click in the System Overview of your SparkFountain system. Click Add Emitter, and a list of existing emitters will display. From the list of emitters, select the Simple Sprite Burst template.



Click image for full size.

The default name for the template emitter is SimpleSpriteBurst, but you can rename it. Click on the emitter name, and the field becomes editable. Name the new emitter FX_Sparks_Radial.



Click image for full size.

Radial Sparks Emitter - Edit Render Settings

The Render group is last in the stack, but you need to change the material so that the effect displays the way it is supposed to.

In the System Overview, click the Render group to open it in the Selection panel.



Click image for full size.

Click the dropdown for Material, and select the M_Radial_Gradient material from the Starter Content. To locate it, type radial in the search bar, as shown below.



Click image for full size.

Click the dropdown for Alignment and select Velocity Aligned.



Click image for full size.

Radial Sparks Emitter - Edit the Emitter Update Settings

First, you will edit the modules in the Emitter Update group. These are behaviors that apply to the emitter, and that update each frame.

In the System Overview, click the Emitter Update group to open it in the Selection panel.



Click image for full size.

Remove the Sprite Burst Instantaneous module by clicking the Trashcan icon.



Click image for full size.

Open the Emitter State module. This module controls time and scalability for this emitter. Because you used the Simple Sprite Burst template, the Life Cycle Mode is set to Self. Normally this is used for complete customization of emitter life cycle logic for this specific emitter, but it is not needed for this effect. Click the dropdown and set the Life Cycle Mode to System. This enables your system to calculate life cycle settings, which usually optimizes performance. By default, the system loops infinitely on a 5 second interval.



Click image for full size.

Click the Plus sign icon (+) for Emitter Update, and select Spawning > Spawn Rate.



Click image for full size.

Open the Spawn Rate module. Set the Spawn Rate to 500.



Click image for full size.

Radial Sparks Emitter - Edit Particle Spawn Settings

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click the Particle Spawn group to open it in the Selection panel.



Click image for full size.

Open the Initialize Particle module. Under Point Attributes, expand Lifetime. Set the Lifetime Mode to Random and the Minimum and Maximum values to the following:



Click image for full size.

Parameter

Value

Lifetime Mode

Random

Minimum

0.2

Maximum

0.7

Expand Color. Set the Color Mode to Direct Set and the RGB values to the following:



Click image for full size.

Parameter

Value

Red

2.0

Green

8.0

Blue

20.0

Alpha

1.0

Expand Mass. Set the Mass Mode to Random and the Minimum and Maximum values to the following:



Click image for full size.

Parameter

Value

Mass Mode

Random

Minimum

0.3

Maximum

0.6

Under Sprite Attributes, set the Sprite Size Mode to Non-Uniform. Set the following values: X: 0.25, Y: 0.5.



Click image for full size.

Leave the Sprite Rotation Mode and Sprite UV Mode as Unset.

Click the Plus sign icon (+) for Particle Spawn, and select Mass > Calculate Size and Rotational Inertia by Mass. You can also type calc in the Search bar, as shown below.



Click image for full size.

Open the Calculate Size and Rotational Inertia by Mass module. Under Density, set Density by Material Type to Water.



Click image for full size.

Under Proportions, change the Height to 0.5 and Depth to 0.0.



Click image for full size.

Click the Plus sign icon (+) for Particle Spawn, and select Velocity > Add Velocity. You can also type velocity in the Search bar.



Click image for full size.

Open the Add Velocity module. Click on the dropdown menu and select Dynamic Inputs then Random Range Vector.



Click image for full size.

Set the Velocity Minimum and Maximum to the following.



Click image for full size.

Velocity

Minimum

Maximum

X

-100.0

90.0

Y

-100.0

90.0

Z

300.0

500.0

Click the Plus sign icon (+) for Particle Spawn, and select Location > Shape Location. You can also type sphere in the Search bar.



Click image for full size.

Open the Shape Location module. Set the Sphere Radius to 2.0.



Click image for full size.

Radial Sparks Emitter - Edit the Particle Update Settings

Now you will edit the modules in the Particle Update group. These behaviors apply to an emitter's particles and update each frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

Click the Plus sign icon (+) for Particle Update, and select Velocity > Scale Velocity.



Click image for full size.

Set the Scale Velocity to X: 3.0, Y: 4.0, Z: 1.0.



Click image for full size.

Click the Plus sign icon (+) for Particle Update, and select Forces > Gravity Force.



Click image for full size.

Open the Gravity Force module. Change the Z value to -4500.



Click image for full size.

Click the Plus sign icon (+) for Particle Update, and select Forces > Drag.



Click image for full size.

Open the Drag module. Set the Drag value to 1.7.



Click image for full size.

Click the Plus sign (+) for Particle Update and select Collision > Collision. This module will make sure any sparks that hit something like a floor will collide and bounce back.



Click image for full size.

Open the Collision module. Under Bounce, set the Restitution value to 0.4.



Click image for full size.

Under Friction, set the Friction value to 0.2.



Click image for full size.

Remove the Scale Color module by clicking the Trashcan icon.



Click image for full size.

Click the Plus sign (+) and select Size > Scale Sprite Size by Speed.



Click image for full size.

Open the Sprite Size Scale by Speed module. Set the Scale Factor Minimum and Maximum to the following.



Click image for full size.

Sprite Size Scale by Speed

Minimum

Maximum

X

0

0.5

Y

3

6

Set the Velocity Threshold value to 2000.



Click image for full size.

End Result

Congratulations! After following these steps, the Sparks effect is complete. You can check the final results back in your level, and make any adjustments you like to fine-tune it.



In order to understand and use the content on this page, make sure you are familiar with the following topics:

Enable the Niagara Plugin

Create System and Emitter

Change Renderer Settings

Edit the Emitter Update Group Settings

Edit the Particle Spawn Group Settings

Edit the Particle Update Group Settings

Adjusting the Beam's End Position

End Result

Prerequisite Step: This how-to uses the DefaultRibbonMaterial, which is included in the content for the Niagara plugin. However, you can use the M_Balloon material used in the Create a Mesh Balloon Effect how-to if you have already completed that tutorial.

In Niagara, the Ribbon Renderer is used along with specific modules that indicate that the ribbon is being used as a beam. In this guide, you will learn how to create a beam that simulates lightning.

Create System and Emitter

In Niagara, systems and emitters are independent. The current recommended workflow is to create a system from existing emitters or emitter templates.

First, create a Niagara System by right-clicking in the Content Browser, and selecting FX > Niagara System.



Click image for full size.

Select New system from selected emitters. Then click Next.



Click image for full size.

Under Templates, select Static Beam. Click the plus sign (+) to add this template. Then, click Finish.



Click image for full size.

Name the new system BeamSystem. Double-click to open it in the Niagara Editor.



Drag your **BeamSystem into your Level.



Click image for full size.

When you make a particle effect, it is always a good idea to drag your system into a Level. This gives you a chance to see every change and edit in context. Any changes you make to the system automatically propagate to the instance of the system in your Level.

The emitter instance in your new system has the default name of StaticBeam, but you can rename it. Click the name of the emitter instance in the System Overview, and the field will become editable. Name the emitter FX_Beam.



Click image for full size.

Change Renderer Settings

The Render group is last in the stack, but you need to change some things so that the effect displays the way it is supposed to.

In the System Overview, click Render to open it in the Selection panel.

[ ]

Click image for full size.

The emitter template in this system already has a ribbon renderer included. You will add specific modules later in this guide to indicate that the ribbon is used as a beam.

The Material used for this renderer is the DefaultRibbonMaterial. If you want to use a different material, you can click the dropdown to search for and select that Material.

If you scroll past the settings in the Ribbon Rendering section, you will find a section called Tessellation. In that section, set the Curve Tension to .5. This will affect how spikey the lightning effect is. You can raise or lower that value to vary your effect.



Click image for full size.

Edit the Emitter Update Group Settings

First, you will edit the modules in the Emitter Update group. These are behaviors that apply to the emitter, and that update each frame.

In the System Overview, click the Emitter Update group to open it in the Selection panel.



Click image for full size.

The Static Beam emitter template has the Life Cycle Mode set to Self by default. This means the life cycle and loop behavior of the emitter is set directly, instead of being handled by the System. For this effect, you will add some randomness to the Loop Duration by adding a float to the value. Click the dropdown arrow for Loop Duration, and select Dynamic Inputs > Random Ranged Float. This adds Minimum and Maximum fields under Loop Duration.



Click image for full size.

Set the Loop Duration Minimum and Maximum values to the following.



Click image for full size.

Setting

Value

Minimum

.1

Maximum

.2

The first module that indicates this effect uses a beam is the Beam Emitter Setup module. Since you started with the Static Beam template, this module is already included. For Beam Start and Beam End, leave the position at its default. Check the boxes to enable Absolute Start and Absolute End.

The start position of the beam is defined by the position of the Niagara system in the scene. The end position is defined by the static coordinates set in Beam End, which you can change by editing the values directly. At the end of the tutorial you will learn how to connect the end point of the beam to an actor.





Click image for full size.

To add an arc or curve to the effect, check the box to enable Use Beam Tangents. This displays the Beam Start Tangent and Beam End Tangent settings. Click the Reset to Default (small yellow arrow) icon for Beam Start Tangent to change the value to Multiply Vector by Float.



Click image for full size.

Set the Beam Start Tangent Vector and Float to the following values.



Click image for full size.

Setting

Value

Vector

X: 0, Y: 0, Z: 1

Float

.5

Set the Beam End Tangent Vector and Float to the following values.



Click image for full size.

Setting

Value

Vector

X: 0, Y: 0, Z: 1

Float

1

In the Spawn Burst Instantaneous module, set the Spawn Count to 35.



Click image for full size.

Edit the Particle Spawn Group Settings

Next, you will edit the modules in the Particle Spawn group. These are behaviors that apply to particles when they first spawn.

In the System Overview, click the Particle Spawn group to open it in the Selection panel.



Click image for full size.

In the Initialize Particle module, locate the Lifetime parameter. This parameter determines how long particles will display before they disappear. Set the Lifetime to .2. This short Lifetime will cause the beam to flicker, which will make the lightning more realistic.



Click image for full size.

The Spawn Beam module is the second beam-specific module. You do not need to set anything with this module, it just needs to be present.

The third beam-specific module is the Beam Width module. The Beam Width is set to Float from Curve. Select the Ramp Up Down template to apply this shape to the curve.



Click image for full size.

Below the Curve diagram you will see some additional settings. Set the Scale Curve to 5.

Edit the Particle Update Group Settings

Now you will edit the modules in the Particle Update group. These behaviors apply to an emitter's particles and update each frame.

In the System Overview, click the Particle Update group to open it in the Selection panel.



Click image for full size.

In the Color module, set the RGB values to the following.



Click image for full size.

To break up the curve and make the beam crackle and jump like lightning, add the Jitter Position module by clicking the Plus sign (+) icon for Particle Update and selecting Location > Jitter Position.



Click image for full size.

To make the Jitter Position module work correctly, you need an Update Beam module. Add the Update Beam module by clicking the Plus sign (+) icon for Particle Update and selecting Beam > Update Beam. In the System Overview, drag the Update Beam module to a position above the Jitter Position module in the stack.



Click image for full size.

Now go back to the Jitter Position module. The default setting for Jitter Amount is 10, and the default for Jitter Delay is .25. However, if you decrease the Jitter Delay to .1 you will start to see the beam bend with an angular, jagged motion. With the value at .1 you can still see the original arc shape under the jagged beam, which is not ideal. To fix this, you have to set the Jitter Delay to a negative number. Set the Jitter Delay to -.01. Set the Jitter Amount to 15.



Click image for full size.

Adjusting the Beam's End Position

You can set the Start and End positions of the beam in the Beam Emitter Setup module, which is in the Emitter Update group. By default, the end position of the beam is set to a static world location value, which you can edit manually by adjusting the value.

However, it could be useful to be able to link that end position to an actor in your scene. This way, when you want to edit the end position of the beam, you simply move that actor. One way of doing this would be to use Blueprints. Another, more simple way, would be to use a Scratch Pad to set a dynamic input.

Click the Beam Emitter Setup module to select it in the Selection panel.



Click image for full size.

Click the dropdown arrow next to Beam End, then search for scratch and select New Dynamic Scratch Input.



Click image for full size.

This will open a scratch pad with a basic setup. It consists of an input, a Map Get that you can use to pull in some values, and an output. Right-click on the default input and select Remove Pin as this default input will not be needed.

Click on the plus sign (+) to add a new pin. Search for actor and select Make New > Actor Component Interface. This will add a section to the Details Panel in the Level Editor when you select your Niagara object, so that you can select the object you would like to link it to.



Click image for full size.

Drag the pin from New Actor Component Interface and release. Select Get Transform. This will provide the transformation information of the object it's linked to.



Click image for full size.

Connect the Position value to the Output.



Click image for full size.

The system automatically adds a Position -> Vector3f node. This helps to transform vecctors to the proper format for large world coordinates. You can organize your canvas to make sure they don't overlap.



Click image for full size.

Now that the scratch is complete, in order for the changes to propogate back out into the Niagara system, you must hit Apply.



Click image for full size.

In the Niagara Editor, select again the Beam Emitter Setup module. You will notice now there is a New Actor Component Interface linked to the Beam End. Click on the dropdown arrow, then select Make > Read from new User parameter. This will create a new user parameter that you will be able to set from outside the Niagara system.



Click image for full size.

By default, the system creates a User Parameter with the name of the object and the name of the parameter, so it's quite long. If you'd like to rename this, go to the Parameters panel.



Click image for full size.

Double-click to rename New Actor Component Interface_Beam End to something shorter, such as Beam_End.



Click image for full size.

Save your Niagara System and close the editor to return to the Level Editor. You should see the beam system that you had dragged in the level earlier. You can already manipulate the start position of the beam by moving the Niagara system's start point. However the end point is fixed. What we will do next is to attach it to an object in the scene.

First, create a basic sphere to link the end point to. From the Create menu, select Shapes > Sphere.



Click image for full size.

In the Outliner, select your sphere and double-click to rename it to Sphere_BeamEnd.



Click image for full size.

In the Outliner, select your Niagara system BeamSystem. In the Details panel, scroll down to the Override Parameters section. Here, you should see the Beam_End user parameter that you set up when you created the scratch module. Select the dropdown menu for Source Actor, then select Sphere_BeamEnd. Alternatively, you can use the eye dropper to select any object in your level. Now, when you move that object, the beam end position moves with it.



Click image for full size.

End Result

Congratulations! You have created a beam effect that simulates lightning. In the video below, you can see an example of the lightning beam effect. You can use beams for all kinds of visual effects: lasers, weapon rays, tesla coils and so on.



Using the Play Audio Module

Audio Module Example

Using the Play Persistent Audio Module

Using the Audio Component Renderer

Exporting Particle Data to Blueprint

An audio effect is when you want to play some sound within a Niagara simulation. For example, when a particle simulation collides with something, then a sound plays. There are several ways to accomplish this within the Niagara system.

Each method has its pros and cons. Following is a brief overview of each.

You can find samples of these methods in the Content Examples project on the Epic Games Launcher: Unreal Engine > Learn > Engine Feature Samples > Content Examples.

Using the Play Audio Module

For a one-off sound effect, the Play Audio module is the simplest way to play sound effects from Niagara. It is useful for event-driven effects, such as a reaction to a particle collision. It is also the cheapest solution in terms of memory usage.

Add the Play Audio module to your emitter. You can add this to the Particle Update group so that this module is evaluated as the particles age.



Click image for full size.

From Sound to Play, select a sound from the dropdown. If you have the Content Examples project open, there are already some sounds added to the project.

Set up the Play Audio condition.

This fires a one-time effect using the configured values for pitch, volume, and more. Once an effect is triggered, it cannot be changed or stopped, and continues to play even if the particle simulation is stopped.

Play Audio Module

Pros

Cons

Most performant solution (for both memory and CPU usage)

Sound properties like volume or pitch are fixed once the sound starts playing

Easiest to set up

Sounds cannot update their positions over time as a particle moves

Audio Module Example

Download the Content Examples project, then open it.

In the Content Drawer, search for Play Audio.



Click image for full size.

Double-click PlayAudio Example to open the Niagara System example.



Click image for full size.

There are different types of audio examples in this project. You will find one emitter called Play_Sound_On_Collision that uses the Play Audio module. The emitter called Mesh_Rotational_Velocity uses a different method, the Play Persistent Audio module.



Click image for full size.

Using the Play Persistent Audio Module

This module is similar to Play Audio, but keeps a reference to each spawned sound effect so it can be updated over time.



Click image for full size.

This module also allows for some advanced features, like fading or setting sound cue parameters. However, is a bit trickier to set up than the first method because to work, it requires two modules—Play Persistent Audio and Update Persistent Audio.

Use the same audio player reference in both modules.

You can create an audio player data interface as an emitter attribute and bind it to the modules. In the screenshot above, the Emitter.AudioPlayer reference is in both modules.



Click image for full size.

The chain symbol to the left of EMITTER indicates that they are referencing an existing attribute.

By default, each module creates its own object that cannot be shared with other modules. If you want the modules to use the same object, you must create it in the emitter or system spawn script, then reference it in the modules.

To see how the Play Persistent Audio module works, in the Content Samples file, from the Content Drawer search for Play Audio, then double-click PlayAudio Example to open. Locate the emitter called Mesh_Rotational_Velocity. You will find on this emitter a module called Play Persistent Audio.



Click image for full size.

Double-click Play Persistent Audio to open the Node Graph.



Click image for full size.

This method is useful when sound properties need to change during the simulation, such as when a sound needs to travel with the particle position.

Play Persistent Audio Module

Pros

Cons

Change volume, pitch, location and rotation at runtime

More complex to set up

Set sound cue parameters and end sound when simulation stops

Less performant than Play Audio

Filter sounds based on camera distance

Using the Audio Component Renderer

The Audio Component Renderer is experimental. Use it as you would any experimental feature in Unreal Engine.

The Audio Component Renderer can be used to spawn audio components. To add the Audio Component Renderer, click on the Plus Sign (+) in the Render group. Select Component Renderer.

Once the Component Renderer has been added, from the Selection panel, click the Component Type dropdown menu, then select AudioComponent.



Click image for full size.

This is a very flexible approach, since it gives full control over the audio component, but you would need to reimplement any features from the Play Audio modules in the particle simulation (such as fading or distance-based filtering). It also does not support setting sound cues without first creating a custom audio component subclass.

Aside from special use cases where the modules do not provide enough control, the component renderer is not recommended.

Audio Component Renderer

Pros

Cons

Very flexible

Missing many features

Provides more control over audio

Less performant

Cannot set sound cue parameters

Exporting Particle Data to Blueprint

If none of the other approaches are flexible enough for your needs, you can export particle data to Blueprint or C++ and implement your audio logic there.

To do this, use the Export Particle Data interface. To see an example in the Content Examples project, search for export particle in the Content Drawer.



Click image for full size.

Double-click ExportParticleDataExample blueprint for a detailed explanation on how to export data from your particle simulation.



Click image for full size.

One advantage of the export data interface is that it also works on GPU emitters (with some added latency). And once you have the data you need in Blueprint, you can use it not only to play audio, but also to drive any number of components, such as post processing or user interface (UI) widgets.

Although this is the most flexible way to play audio, it is also the slowest and most complex to set up. You are also somewhat limited by the amount of data you can export, and need to do any mapping between audio component and particle data yourself.

Export Particle Data to BP

Pros

Cons

Most flexible approach

Slowest performance

Works on GPU

Any module features need to be reimplemented in BP logic

Setup is complex

Niagara Editor UI Reference

Niagara System and Emitter Module Reference

Niagara Script Editor Reference

You may want to understand more detailed information about the Niagara user interface, modules, and script editor.

Niagara Editor UI Reference

This page explains the details of the Niagara editor user interface. It goes into details about the buttons on the UI, the panels available, and actions you can perform.



This page describes the user interface (UI) of the Niagara Emitter and System Editor.

Niagara System and Emitter Module Reference

These pages detail descriptions of key modules you can find in systems and emitters in Niagara.



This page links to documents that are part of the Niagara System and Emitter Module Reference.

Niagara Script Editor Reference

You can use the script editor to modify existing modules or to create new modules of your own. This reference guide explains the interface.



This page describes the user interface (UI) of the Niagara Script Editor.

Overview

Menu

File

Edit

Asset

Window

Tools

Toolbar

Preview Panel

Parameters Panel

System Overview Panel

System Node

Emitter Nodes

Scratch Pad Panel

Selection Panel (the Stack)

Groups in the Selection Panel

Modules in the Selection Panel

Timeline Panel

Curves Panel

Niagara Log Panel

Other Optional Panels

Attribute Spreadsheet Panel

Preview Scene Settings Panel

Generated Code Panel

Overview

The Niagara Editor can be opened by double-clicking on any Niagara emitter or system, or through the context menu by right-clicking on a Niagara emitter or system and selecting Edit. This document identifies and describes the parts of the Niagara Editor. Because the user interface (UI) of the editor is mostly the same for both emitters and systems, descriptions for both have been included.



Click image for full size.

Menu Bar

Tool Bar

Preview Panel

Parameters Panel

System Overview

Scratch Pad Panel

Selection Panel (the Stack)

Curves Panel

Niagara Log Panel

Timeline Panel

Menu



Click image for full size.

The tables below only describe commands that apply to the Niagara Editor itself; there may be additional commands displayed in those menus that open Asset editors or other parts of Unreal Editor.

File



Click image for full size.

Command

Description

Save

Saves the current emitter.

Save As

Saves the current emitter under a different name.

Open Asset

Displays a window to select other assets.

Save All

Saves all assets and levels in this project.

Choose Files to Save

Displays a dialog with options for saving assets and levels.

Edit



Click image for full size.

Command

Description

Undo

Undoes the last action.

Redo

Redoes an action that was undone.

Undo History

Displays a dialog listing all undone actions.

Editor Preferences

Opens the Editor Preferences window to enable you to adjust the preferences of the editors.

Project Settings

Opens the Project Settings window to enable you to adjust the setting of the Project.

Plugins

Opens the Plugins windows for you to enable or disable plugins.

Asset



Click image for full size.

Command

Description

Find in Content Browser

Switches to most recently used Content Browser, and selects the current Asset in that Content Browser.

Reference Viewer

Displays a dialog that shows all of the current Asset's references.

Size Map

Displays an interactive map showing the approximate size of the Asset and everything it references.

Audit Assets

Opens the Asset Audit UI and displays information about the selected assets.

Shader Cook Statistics

Displays shader cook statistics.

Window



Click image for full size.

Command

Description

Preview

Shows or hides the Preview panel.

Curves

Shows or hides the Curves panel.

Timeline

Shows or hides the Timeline panel.

Parameters

Shows or hides the Parameters panel.

Legacy Parameters

Open the Legacy Parameters window.

Selection

Shows or hides the Selection panel.

Attribute Spreadsheet

Shows or hides the Attribute Spreadsheet.

Preview Scene Settings

Shows or hides the Preview Scene Settings.

Generated Code

Shows or hides the Generated Code panel.

Niagara Log

Shows or hides the Niagara Log panel.

System Overview

Shows or hides the System Overview panel.

Scratch Pad

Shows or hides the Scratch Pad panel.

Script Stats

Shows or hides the Script Stats panel.

Baker

Opens the Baker window.

Cinematics

Opens the Sequence Recorder panel as a new window.

Content Browser

Opens the selected Content Browser as a new window.

Device Output Log

Open the Device Output Log window.

Interchage Results Browser

Open the Interchage Results Browser window.

Message Log

Open the Message Log window.

Output Log

Open the Output Log window.

Open Marketplace

Opens the Open Marketplace.

Quixel Bridge

Opens the Quixel Bridge.

Load Layout

Click on a layout to load a previously saved layout.

Save Layout

Save a new layout.

Remove Layout

Click on a layout to remove a previously saved layout.

Enable Fullscreen

Click to toggle on Fullscreen Mode.

Tools



Click image for full size.

Command

Description

New C++ Class

Adds C++ code to the project. The code can only be compiled if you have Visual Studio installed.

Generate Visual Studio Project

Generates your C++ code project in Visual Studio.

Find in Blueprints

Opens the selected Find In Blueprints panel as a new window.

Cache Statistics

Shows the Derived Data Cache Statistics window.

Class Viewer

Displays all classes that exist within this project.

CSV to SVG

Tool for generating vector line graphs from comma-separated value files generated from CSV profiles.

Localization Dashboard

Opens the experimental Localization Dashboard window.

Merge Actors

Open the Merge Actors window.

Nanite Tools

Shows the Tools for auditing and optimizing Nanite assets window.

Project Launcher

Opens the Project Launcher window.

Resource Usage

Shows the Derived Data Resource Usage window.

Session Frontend

Open the Session Frontend window.

Struct Viewer

Displays all structs that exist within this project.

Virtual Assets

Open the Virtual Assets Statistics.

Debug

Enables you to open up various different Debug Tools.

Profile

Enables you to open up various different Profile Tools.

Audit

Enables you to open up various different Audit Tools.

Platforms

View and manage connected devices.

View Changelists

Opens a dialog displaying current changelists.

Submit Content

Opens a dialog with check in options for content and levels.

Connect to Source Control

Displays a dialog where you can connect to source control, allowing source control functions to be performed on content.

Run Unreal Insights

Run the Unreal Insights standalone application.

Toolbar



Click image for full size.

Tool Name

Description

Save



Saves the current emitter.

Browse



Switches to the most recent Content Browser and selects the current emitter.

Compile



Compiles all the modules in the emitter. You can also change the Auto-Compile settings by clicking the dropdown arrow. Click the dropdown to select the following options:

Full Build: Triggers a full rebuild of this system, ignoring the change tracking.

Auto-Compile: Automatically compiles when the Graph changes.

Thumbnail



Generates a thumbnail image of the Asset.

Bounds



Shows the bounds of the scene in the Preview panel. Click the dropdown to Set Fixed Bounds.

Performance



Click the dropdown to see the following Performance Options:

Clear Stats: Clear all existing stat captures.

GPU Profiling: Enable this to measure the GPU runtime cost of scripts. Can be expensive for simulation stages with lots of iterations.

Display Average: Enable this to display the average of captured stats.

Display Maximum: Enable this to display the maximum of captured stats.

Display Relative Values: Enable this to display the captured stats in percent of the parent script.

Display Absolute Values: Enable this to display the captured module stat times directly.

Debug



Click the dropdown to see the following Debug Options:

Debug HUD: Open the Niagara Debug HUD.

FX Outliner: Open the Niagara FX Outliner.

Attribute Spreadsheet: Open the Niagara Debug Outliner.

Simulation



Click the dropdown to see the following Simulation Options:

Auto-Play: Enable this to make simulation auto-play when you open the Asset in the Niagara Editor, and also when you modify the Asset.

Reset on Change: Enable this to make the simulation reset whenever you make a change to the Asset in the Niagara Editor.

Resimulate When Paused: Enable this to make the simulation rerun to the current time when you make changes while it is paused.

Baker



Click the dropdown to see the following Baker Options:

Open Baker Tab: Opens the flip book window.

Bake: Runs the bake process.

Preview Panel



Click image for full size.

Menu Item

Description



Viewport Options



Realtime

Toggles real-time rendering in the viewport. Changes you make in the emitter stack will immediately be shown in the viewport, even if the emitter is not compiled.

Show Stats

Toggles showing stats in the viewport. If Realtime is not enabled, Show Stats automatically enables it.

Show FPS

Toggles showing the frames per second in the viewport. If Show Stats is not enabled, Show FPS automatically enables it.

Field of View

Changes the FOV of the viewport camera. This effectively zooms the lens of the camera in and out.

Far View Plane

Choose the distance to use as your far view plane. Setting this to zero acts as an infinite far view plane.

Screen Percentage

Sets the percentage of the screen your Preview panel uses.



Viewpoint Type



Perspective

The default viewpoint used in the viewport.

Orthographic

Choose Top, Bottom, Left, Right, Front or Back. Selecting one of these changes the View Mode to Wireframe.



View Mode



Lit

The default setting; it renders the scene with normal lighting.

Unlit

Renders the scene with no lights. No light maps, dynamic lights, static lights, or emissive materials affect the scene.

Wireframe

Renders the scene in brushed wireframe. This displays the raw triangles of everything in the viewport, and turns off the back faces to make the scene more readable.

Detail Lighting

Renders the scene with detail lighting only. This means only lighting with normal data pulled from materials will be used. Color emitted from lights will affect the scene.

Lighting Only

Renders the scene with lighting only, and no textures. Only the vertex normals of the scene will be taken into account.

Reflections

Renders the scene with reflections only. This includes both reflection captures and Screen Space Reflections.

Player Collision

Renders a color-coded view of what a Player or Pawn can collide with. Static Mesh collision displays as green, Volumes as pink, and Brushes as a grayish-violet.

Visibility Collision

This setting will render a color-coded view of what Actors in the scene will block visibility traces. Static mesh collision displays as green, volumes as pink, and brushes as a grayish-violet.

Optimization Viewmodes

Select from the following options:

Light Complexity: Renders a view showing where raw light overlaps.

Lightmap Density: Renders a view of lightmap density in the scene, with blue being the least dense and red being the most dense.

Stationary Light Overlap: Renders a view of where stationary lights overlap.

Shader Complexity: Renders a view of the shader complexity in a scene. Light green is the least complex, moving to darker greens as complexity increases, and the most complex areas are in red.

Shader Complexity and Quads: Renders a view with both shader complexity and quad overdraw displayed.

Quad Overdraw: Renders a view with just quad overdraw complexity displayed.

Material Texture Scales: Visualize the accuracy of the material texture scales used for texture streaming.

Virtual Texture Pending Mips: Visualize the ratio between the currently streamed virtual texture level and the level wanted by the GPU.

Level of Detail Coloration

Select from the following options:

Mesh LOD Coloration: Renders the scene using LOD color visualization.

Hierarchical LOD Coloration: Renders the scene using HLOD color visualization.

Player Collision

Renders player collision visualization.

Visibility Collision

Renders visibility collision visualization.

Auto

If enabled, enables automatic exposure.

EV100

Sets the exposure value of the camera using the specified EV100.



Show



Grid

Toggles the viewport's grid.

Instruction Counts

Toggles the display of instruction counts in the upper left corner of the viewport.

Particle Counts

Toggles the display of particle counts in the viewport.

Emitter Execution Order

Toggles the display of the order that emitters are executed in the viewport.

Parameters Panel



Click image for full size.

This panel lists all the user exposed, system, emitter, particle, and engine-provided parameters (also called attributes) that are used by the active emitter or system.

From the Parameters panel, you can drag and drop parameters to any appropriate node in the System Overview, or to any appropriate module parameter in the Selection panel. The number of times a parameter is referenced is shown on the right, enabling you to spot errors and make decisions on how to change your variables. If you have other emitters open, this panel pulls in data from those open emitters. This enables the user to share data between emitters. The Namespace for a parameter is displayed with a prominent icon, and you can see a tooltip that explains that Namespace when you mouse over the icon. To see more advanced Namespaces, such as parameter collections, click the Eye icon next to the Search bar.

System Overview Panel



Click image for full size.

The System Overview panel gives a high-level overview of the system or emitter being edited, combining a pan-and-zoom Graph view with compact versions of the system or emitter stack. This panel makes it easier to navigate between different parts of the data, and it gives you a high level view when you open an emitter or system for the first time.

In a system, select an emitter in the Timeline panel and it will display the full stack for that emitter in the Selection panel. In this full stack view, the system information is on top, followed by the emitter module groups below. You can also get a full stack view of an emitter node or the system node by clicking on that node in the System Overview panel. However, if you want a less cluttered or more focused view, you can select an individual group or module within the emitter node in the System Overview to see just that group or module in the Selection panel.

System Node



Click image for full size.

The System Node has icons that identify each group of modules, as well as having colored dots next to modules that identify what that module or parameter affects.

Emitter Nodes



Click image for full size.

Emitter Properties has an icon that identifies whether the simulation is run on the CPU or the GPU. Other icons and colored dots on the emitter node help you identify the group, module, or parameter quickly.

Scratch Pad Panel



Click image for full size.

With the Scratch Pad, you can create reusable modules or dynamic inputs that are contained locally in the active emitter or system Asset. This makes it easier to design and implement new custom modules or dynamic inputs, because you can see the results immediately within the emitter or system. You can keep or discard these at will. Once you have the result you are looking for, you can copy-paste the script to an existing Asset. You can also save it as a new Asset by right-clicking Scratch Script Selector and selecting Create Asset. The Scratch Pad also allows you to make something that is very specific to the active emitter or system, and does not need to be made into its own Asset.

There are two ways to open the Scratch Pad panel in the Niagara Editor. You can open it from the Windows menu, the way you would show or hide any other panel. The disadvantage to this method is that when you use the Scratch Pad to build a custom module, you need to manually add that module to your overall emitter or system script in the System Overview. You also have to add the module or dynamic input starting shell yourself, by clicking the Plus sign icon (+) next to Modules or Dynamic Inputs.



Click image for full size.

The second way to open the Scratch Pad panel is to use the Plus sign icon (+) and selecting New Scratch Pad Module. This places a Scratch Pad module in your stack (wherever the new module will belong), which is automatically added to your script. You will also see that a shell for the new module or dynamic input is automatically added to your Scratch Pad Graph.



Click image for full size.

Selection Panel (the Stack)



Click image for full size.

In the Emitter Nodes and the Selection panel, the various groups are color-coded.

Orange is for Emitter-level modules. Orange sections are:

Emitter Settings: the Emitter Properties item is in this group.

Emitter Spawn: what happens on the first frame.

Emitter Update: what happens after the first frame, as the emitter is updated.

Green is for Particle-level modules. Green sections are:

Particle Spawn: what happens when the Particle is created.

Particle Update: what happens during the Particle's lifetime.

Update Age and Solve Forces and Velocity are normally low-level, boilerplate modules that everyone uses. But these can be removed and are completely optional.

Red is for Renderer items. Niagara decouples simulation from rendering. This means you can create simulation behavior once, then assign multiple renderers to that simulation.

If you select the System node in the System Overview, you will see system-related groups that are colored Blue.

System Settings: this group includes the User Parameters and System Properties items.

System Spawn: what happens when the system is created.

System Update: what happens during the system's lifetime.

The UI of the Niagara Editor is somewhat complex. The next two sections will highlight some specific elements of the UI that might be confusing to new users.

Groups in the Selection Panel



Click image for full size.

When you click on a group in an emitter or system node, that entire group is displayed in the Selection panel. To the right of the group name, you will see a Plus sign icon (+), colored to match the group. When you click that icon, a list of available module categories displays. Click the dropdown next to the category name to expand it and see the modules in that category. Selecting the name of a module adds that module to the group.

You can also click the Plus sign icon in the emitter or system node, directly in the System Overview. The same list will display.

Modules in the Selection Panel



Click image for full size.

Depending on the module, you may want to modify a parameter value to achieve a specific outcome. To add a dynamic input, expression, or link to another attribute you can click on the dropdown arrow to the right of the value field you want to modify. A list of available categories displays. When you expand the category, you can select from a list of available options and the selected option will be applied to that value field. For example, to randomize a value you can click the dropdown and select Dynamic Inputs > Random Ranged Float.

If you don't see a module or dynamic input you have created in the list, try unchecking Library Only.

Timeline Panel



Click image for full size.

With the Timeline panel, you can manage looping, loop count, bursts, random starts and stops, and spawn rate. All of these elements can interact right in the Timeline.

In a system, the Timeline panel lists all emitters active in that System, with metadata about what kind of renderers they use and the ability to toggle which emitters are active. You can control looping behavior using the Timeline, and you can set spawn burst keys in it as well. This is driven by module metadata, which can be extended by users if needed.

For more information on using Sequencer, see Sequencer Editor.

Curves Panel



Click image for full size.

This panel provides a Curve Editor that enables the user to adjust any values that need to change during the life of a particle, or across the life of an emitter. In order for any property to be editable within the Curve Editor, that property will need to have a Distribution type that utilizes a curve, such as FloatfromCurve. See the Curve Editor User Guide page for more details on using the Curve Editor.

Niagara Log Panel



Click image for full size.

If there are any warnings or errors when compiling a script, emitter or system, they appear here. For many errors and warnings, you can click it in the Niagara Log panel and jump to the error's location in the Niagara Editor.

Other Optional Panels

There are some additional panels that are not displayed by default, but that can be opened using the Window menu. By default, these panels will display as tabs in the area where the Selection panel displays, but you can drag and drop them to dock them somewhere else.

Attribute Spreadsheet Panel



Click image for full size.

With the Attribute Spreadsheet, you can filter and debug information coming from the CPU or GPU simulation. For all CPU VM-based effects, you can take advantage of the attribute debugger. It allows you to see the inputs to the simulation as well as the per-particle computed values.

The Attribute Spreadsheet targets the emitter or system previewed in the Preview panel. You can also target systems in a level by setting the in-level system to Force Solo, then selecting that system as a target in the Attribute Spreadsheet while you are in PIE (Play In Editor) mode.

Preview Scene Settings Panel



Click image for full size.

This panel contains settings for modifying the Preview panel.

Generated Code Panel



Click image for full size.

This panel displays the generated HLSL and Assembly code for the selected emitter and owning system. This enables you to view and search that code. This tool is for advanced users who need to debug problems that may be difficult to spot with other methods.

You can select the HLSL or Assembly code being displayed using the Scripts dropdown menu. To view a specific emitter's generated HLSL or Assembly code, follow these steps.

Select the emitter in the System Overview or Timeline panel.

Select the desired script under the Scripts dropdown menu in the Generated Code panel.

Niagara Selection Stack Model

Execution State Management

Settings, Groups and Renderers

This page contains some basic reference information about how modules work in Niagara. Below this reference information, there are links to pages describing each group of items and modules that are included with the Niagara plugin.

Niagara Selection Stack Model

Particle simulation in Niagara operates as a stack simulation flows from the top of the stack to the bottom, executing programmable code blocks called modules in order. Crucially, every module is assigned to a group that describes when the module is executed.

Modules that are part of the System groups execute first, handling behavior that is shared with every emitter. Then, modules and items in the Emitter groups execute for each unique emitter. Following this, parameters in the Particle groups execute for each unique particle in an individual emitter. Finally, Render group items describe how to render each emitter's simulated particle data to the screen.

For more information on the Stack, see the Niagara Selection Stack and Stack Groups section in Niagara Key Concepts.

A module is an item, but an item is not a module. Modules are editable assets a user can create. Items refer to parts of a system or emitter that the user cannot create. Examples of items are system properties, emitter properties, and renderers.

Execution State Management

Niagara systems and emitters have a distinct Execution State that defines how their simulation is run. Emitters that are part of a system each have a unique Execution State independent of the owning system, so they can change how they are being executed independent of that owning System. The possible Execution States are:

Active: The System or Emitter simulates and allows spawning.

Inactive: The System or Emitter simulates but does not allow any new spawning.

InactiveClear: The System or Emitter destroys all Particles it owns, and then moves to the Inactive Execution State.

Complete: The System or Emitter does not simulate and does not render.

Settings, Groups and Renderers



This page contains reference information for the Emitter Settings group in a Niagara emitter.



This document provides reference information for modules in the Emitter Spawn group.



This document provides reference information for Emitter Update modules in a Niagara emitter.



This page provides reference information for modules in the Particle Spawn group.



This page provides reference information for modules in the Particle Update group.



This document provides reference information for the Renderer group in a Niagara Emitter.



This page contains reference information for the System Settings group in a Niagara system.



This document provides reference information for modules in the System Spawn group.



This document provides reference information for modules in the System Update group.



This document provides reference information for modules in the Add Event Handler group.

Emitter Properties Item

Emitter Properties Item



By default, the Emitter Properties item is included in every created emitter, even if you create an empty one. The Emitter Properties item contains the following base parameters.

Parameter

Description



Emitter



Local Space

This setting toggles whether the particles within this emitter are relative to this emitter or to the global space.

Determinism

This setting toggles whether the random number generator (RNG) will be deterministic or non-deterministic globally. Any random calculation that is set to the emitter defaults will inherit this setting. You can still set individual random numbers to be deterministic or non-deterministic. In this case, deterministic means that the RNG will return results for the same configuration of the emitter, as long as the delta time is not variable. Any changes to the emitter's individual scripts will adjust the results.

Random Seed

If the Determinism setting is enabled, this is an emitter-based seed for the deterministic random number generator.

Sim Target

This determines whether the simulation is performed on the CPU or the GPU.

Fixed Bounds

This setting determines whether the fixed bounds can be edited. If it is enabled, there are Minimum and Maximum X, Y, and Z settings that can be adjusted.

Interpolated Spawning

When this setting is enabled, this emitter will spawn using interpolated parameter values, and it will perform a partial update at spawn time. This has a significant additional cost for spawning, but it will produce much smoother spawning for high spawn rates, erratic frame rates, and fast moving emitters.

Requires Persistent ID

When this is enabled, all particles emitted will be assigned a persistent ID.

Combine Event Spawn

This setting allows event based spawning to be combined into a single spawn.



Scalability





For Scalability, there are five general settings: Low, Medium, High, Epic, and Cinematic. You can click to enable or disable a category for a particular emitter. Each category also has a dropdown menu listing various platforms that can display graphics at a particular level. You can include or exclude specific platforms in a category, instead of just enabling or disabling that category.

Consoles and some mobile platforms will not be displayed unless you set up the appropriate configuration and device profiles.



Setting

Platforms to Include or Exclude

Low

Windows

Mac

Linux

Android

Medium

Windows

iOS

Mac

Linux

Android

High

Windows

Mac

Linux

Epic

Windows

TVOS

Mac

Linux

Cinematic

Windows

Mac

Linux



Asset Options





Library Visibility

This setting allows you to change if this emitter is exposed to the library , or should be explicitly hidden.

Template Specification

This setting toggles whether this emitter is a standart parent emitter, a template or a behaviour example.

Template Asset Description

If you identify this emitter as a Template Asset, you can click the icon on the right to find additional settings for Inline Text and Referenced Text.

Category

You can add the category to collate this emitter into for 'add new emotter dialogs'.

Location Module

MAX Scripts Module

Spawning Modules

New Scratch Pad Module

Set New or Existing Value Directly

Add Parameter

Create New Parameter

Emitter Spawn modules occur once, when the emitter is created on the CPU. Modules in this section should initialize defaults or perform initial setup. Modules are executed in order from the top to the bottom of the stack.

Each of the module types in the Emitter Spawn group has its own section in this document, with tables that list and describe the default options available for that type of module. Keep in mind that you can create custom modules for any part of a Niagara emitter. The ones listed here are just the ones that are automatically included with Unreal Engine 4.

Location Module

Module

Description

Spawn Particles in Grid

This spawns particles based on user-defined grid resolution settings.

MAX Scripts Module

Module

Description

Spawn MS Vertex Animation Tools Morph Target

This spawns and samples Morph Target textures that were created with the Vertex Animation Tool. The Vertex Animation Tool generates textures that represent Morph Target blend shapes. This module spawns one particle for every vertex that was captured by the tool. This module is meant to be used with the Update MS Vertex Animation Tools Morph Target module.

Update MS Vertex Animation Tools Morph Target

This takes the particles spawned by the Spawn MS Vertex Animation Tools Morph Target module and places them at a location you choose.

Spawning Modules

Module

Description

Spawn Per Unit

This module spawns particles based on distance traveled in Unreal units.

Spawn Rate

This module spawns particles continuously at a particular rate.

New Scratch Pad Module

Selecting this item in the Add (Plus sign) menu opens the Scratch Pad panel (by default this docks next to the System Overview) and places a Scratch Pad module in the Selection panel. You can also open the Scratch Pad panel by using Windows > Scratch Pad. However, by placing a Scratch Pad module in the stack, any modules or dynamic inputs you create in the Scratch Pad are automatically connected to your script. If you open the Scratch Pad panel using the Windows menu, any items you create there will have to be added to your script manually.

Set New or Existing Value Directly

Selecting this item from the Add menu places a Set Parameter module in the Selection panel. Click the Plus sign (+) icon to select Add Parameter or Create New Parameter.

Add Parameter

When you select Add Parameter, you select from the parameters listed. This adds that parameter to the Set Parameter module in the Emitter Spawn group.

Some of these parameters can be set or modified in other modules. Some are only set using a Set Parameter module.



Parameter

Description

Emitter.Age

This parameter defines the age of this emitter.

Emitter.CurrentLoopDelay

This parameter defines the current amount of delay before the emitter's current loop repeats.

Emitter.CurrentLoopDuration

This parameter defines the duration of the current emitter loop.

Emitter.ExecutionState

This affects the state of the emitter. Valid value choices are:

Active

Inactive

InactiveClear

Complete

Emitter.ExecutionStateSource

This indicates the source of an execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

Emitter.LocalSpace

This parameter defines whether the position of particles is respective to the world origin or the owning Niagara Component's location.

False: Particle position is in WorldSpace and will be relative to the World origin. A particle with position 0,0,0 will render at the World origin.

True: Particle position is in LocalSpace and will be relative to the owning Niagara Component's location. A particle with position 0,0,0 will render at the owning Niagara Component's location.

Emitter.LoopCount

This parameter defines how many times the emitter's loop repeats.

Emitter.LoopedAge

This parameter calculates the age of the emitter relative to its current loop. For example, if an emitter has been active for 8 seconds and it loops every 5 seconds, the emitter's LoopedAge will be 3 seconds. LoopedAge returns to 0 every time an emitter loops.

Emitter.NormalizedLoopAge

This parameter calculates the age of the emitter relative to its current loop, normalized from 0 to 1. NormalizedLoopAge is expressed as LoopedAge divided by CurrentLoopDuration. If an emitter has been active for 8 seconds and it loops every 5 seconds, the emitter's LoopedAge will be 3. The emitter's NormalizedLoopAge will be 0.6.

System.ExecutionState

This affects the state of the system. Valid value choices are Active, Inactive, InactiveClear, Complete, Disabled, and Num.

System.ExecutionStateSource

This indicates the source of a system execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

Create New Parameter

When you select Create New Parameter, you select from the parameters listed. This adds that parameter to the Set Parameter module in the Emitter Spawn group.

Parameter

Type

Description

Audio Oscilloscope

Data interface

This adds a new Audio Oscilloscope data interface module to the emitter. The Audio Oscilloscope module can directly access the waveform data of the audio signal.

Audio Spectrum

Data interface

This adds a new Audio Spectrum data interface module to the emitter. The Audio Spectrum module can drive a visualization based on how loud the audio is at specific frequencies.

Bool

Primitive

This adds a Set Variable module that has a true/false checkbox.

Camera Query

Data Interface

This adds a new Camera Query data interface module to the emitter. This data interface can be used to retrieve camera information (camera position, rotation, FOV, etc) for the specified controller index.

Collision Query

Data Interface

This adds a collision data interface to the emitter stack. This is usually used in conjunction with Collision modules.

Curl Noise

Data Interface

This adds a curl noise data interface to the emitter stack. If you use this in conjunction with Curl Noise Force modules, this data interface injects different types of noise into your simulation.

Curve for Colors

Data Interface

This adds a four-channel color curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying color.

Curve for Floats

Data Interface

This adds a single-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying float value.

Curve for Vector 2Ds

Data Interface

This adds a two-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying pair of floats.

Curve for Vector 3s

Data Interface

This adds a three-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying set of floats.

Curve for Vector 4s

Data Interface

This adds a four-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying set of floats.

ENiagaraBooleanLogicOps

Enum

This is an enumeration used by various modules and dynamic inputs that want to test using boolean logic:

Greater Than

Greater Than Or Equal To

Equal To

Not Equal To

ENiagaraCoordinateSpace

Enum

This is an enumeration used by various modules and dynamic inputs to distinguish between coordinate spaces:

Simulation: If the emitter is set to local, use local. Otherwise, use World.

World: In the world space of the game.

Local: In the coordinate space of the owning component.

ENiagaraExecutionState

Enum

This enumeration type is used by parameters that manage system or emitter execution states, such as Emitter.ExecutionState or System.ExecutionState.

ENiagaraExecutionStateSource

Enum

This indicates the source of an execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

ENiagara ExpansionMode

Enum

This enumeration is used by location modules to determine where the origin point of expansion is:

Inside

Centered

Outside

ENiagaraOrientationAxis

Enum

This is an enumeration used by several modules to determine which axis to do calculations with:

X Axis

Y Axis

Z Axis

ENiagaraRandomnessMode

Enum

This sets the type of random number generation used by this emitter. Valid choices are:

Simulation Defaults

Deterministic

Non-Deterministic

Float

Primitive

This creates a float value variable.

Grid2D Collection

Data Interface

This is used with simulation stages. It enables the user to read or write to a 2D array of data, and then iterate over each pixel in the grid during a simulation stage.

Int32

Primitive

This creates an integer variable.

Linear Color

Primitive

This creates an RGBA color variable, represented as a color picker.

Matrix

Primitive

This creates a 4x4 matrix variable.

Mesh Tri Coordinate

Struct

This is a simple struct containing a triangle index along with a barycentric coordinate on the face of that triangle.

Neighbor Grid 3D

Data Interface

This is used with simulation stages. It enables the user to read or write to a 3D array of data, and then iterate over each pixel in the volume during a simulation stage.

Niagara ID

Struct

This is a two-part struct used to track particles. It allows fast access to this particle's data. It is always unique among currently living particles, but will be reused after the particle dies. AcquireTag is a unique tag for when this ID was acquired. It allows us to differentiate between particles when one dies and another particle reuses the dead particle's index.

Occlusion Query

Data Interface

This adds a new Occlusion Query data interface module to the emitter. The data interface is used to read depth buffer occlusion information.

This can only be used with GPU emitters.



Particle Attribute Reader

Data Interface

This adds a new Particle Attribute Reader data interface to the emitter. The data interface can be used to query particle payload values from other emitters, and can sometimes be easier to use than Events.

Quat

Primitive

This creates a quaternion variable, used to represent rotations.

Simple Counter

Data Interface

This adds a new Simple Counter data interface module to the emitter. This data interface enables you to increment a thread-safe counter.

This can only be used with CPU emitter.



Skeletal Mesh

Data Interface

This is a data interface with functions to interact with a skeletal mesh's bones or sockets and skinned geometry.

Spawn Info

Struct

This is a structure used in spawning to specify the Count of particles to create, InterpStartDt or offset from the current frame begin time to start spawning, IntervalDt defining the time gap between particles being spawned, and SpawnGroup allowing spawned particles to belong to different categories.

Spline

Data Interface

This is a data interface that interacts with a Spline Asset.

Static Mesh

Data Interface

This is a data interface with functions to interact with a static mesh's surface.

Texture Sample

Data Interface

This is a data interface with functions to interact with a texture on the GPU.

Vector

Primitive

This creates a three-channel set of floats.

Vector 2D

Primitive

This creates a two-channel set of floats.

Vector 4

Primitive

This creates a four-channel set of floats.

Vector Field

Data Interface

This is a DataInterface with functions to query a vector field.

Volume Texture Sample

Data Interface

This adds a new Volume Texture data interface module to the emitter. You can use this to sample a volume texture.

Beam Modules

Chaos Modules

Emitter State

Location Module

MAX Scripts Module

Spawning Modules

Utility Module

New Scratch Pad Module

Set New or Existing Value Directly

Add Parameter

Create New Parameter

Emitter Update modules occur every time the emitter ticks on the CPU. Modules in this group should compute values for Particle Spawn or Update parameters in this frame. Modules are executed in order from the top to the bottom of the stack.

Each of the module types in the Emitter Update group has its own section in this document, with tables that list and describe the default options available for that type of module. Keep in mind that you can create custom modules for any part of the Niagara emitter. The ones listed here are just the ones that are automatically included with Unreal Engine 4.

Beam Modules

Module

Description

Beam Emitter Setup

This module sets up and manages start points, endpoints and tangents for a beam emitter.

Chaos Modules

Module

Description

Spawn from Chaos

This module causes particles to spawn in response to a Chaos event.

Emitter State

Parameter

Description

Life Cycle Mode

This setting determines whether life cycle (looping, age and death) is managed by the emitter itself, or by the system that owns the emitter. Settings are:

System: When you select this option, the owning system will calculate all life cycle functions. In most cases, having systems calculate life cycle increases optimization. Selecting this option hides the other fields.

Self: When you select this option, the emitter itself will calculate life cycle functions. Selecting this option makes the other settings below available.

Inactive Response

This setting determines what happens when the emitter enters the Inactive state. Inactive means the emitter is dormant and no longer able to spawn or manage particles. Options are:

Complete: Particles will finish, then the emitter is killed.

Kill: Emitter and particles are both killed immediately.

Continue: Emitter is deactivated, but does not die until the system does.

Loop Behavior

This determines the behavior of the emitter. You can select from the following:

Once: the emitter plays the animation once.

Multiple: the emitter plays the animation a fixed number of times.

Infinite: the emitter plays the animation infinitely.

Loop Duration

This determines how long the loop lasts.

Loop Duration Mode

This determines whether the loop is finite or infinite.

Loop Delay

This setting delays the next loop by a given amount.



Scalability



Scalability Mode

This determines whether the emitter will take scalability settings from the system, or if it will have its own unique scalability settings. You can choose from the following:

System: When you select this option, the owning system will calculate all life cycle functions. In most cases, having systems calculate life cycle increases optimization. Selecting this option hides the other fields.

Self: When you select this option, the emitter itself will calculate life cycle functions. Selecting this option makes the other settings below available.

Enable Distance Culling

Check this box to enable. This enables the culling of emitters based on the emitter's distance from the camera. Emitters can go to sleep, reawaken, be killed, and so on when they are a certain distance from the camera.

Enable Visibility Culling

Check this box to enable. This enables the culling of emitters based on whether they are visible to the camera. Emitters can go to sleep, reawaken, be killed, and so on based on whether they are onscreen or offscreen.

Reset Age on Awaken

Check this box to enable. When this emitter reawakens after being put to sleep by a scalability setting, this setting will reset the emitter's age. This means spawn bursts will refire, and the emitter's life cycle will restart.

Location Module

Module

Description

Spawn Particles in Grid

This spawns particles based on user-defined grid resolution settings.

MAX Scripts Module

Module

Description

Spawn MS Vertex Animation Tools Morph Target

This spawns and samples Morph Target textures that were created with the Vertex Animation Tool. The Vertex Animation Tool generates textures that represent Morph Target blend shapes. This module spawns one particle for every vertex that was captured by the tool. This module is meant to be used with the Update MS Vertex Animation Tools Morph Target module.

Spawning Modules

Module

Description

Spawn Burst Instantaneous

This module spawns a burst of particles spontaneously.

Spawn Per Frame

This module spawns a burst of particles in each frame.

Spawn Per Unit

This module spawns particles based on distance traveled in Unreal units.

Spawn Rate

This module spawns particles continuously at a particular rate.

Utility Module

Module

Description

Emitter Frame Counter

Enabling Increment Counter in this module sets up a counter which increments with each frame in the emitter's animation.

New Scratch Pad Module

Selecting this item in the Add (Plus sign) menu opens the Scratch Pad panel (by default this docks next to the System Overview) and places a Scratch Pad module in the Selection panel. You can also open the Scratch Pad panel by using Windows > Scratch Pad. However, by placing a Scratch Pad module in the stack, any modules or dynamic inputs you create in the Scratch Pad are automatically connected to your script. If you open the Scratch Pad panel using the Windows menu, any items you create there will have to be added to your script manually.

Set New or Existing Value Directly

Selecting this item from the Add menu places a Set Parameter module in the Selection panel. Click the Plus sign (+) icon to select Add Parameter or Create New Parameter.

Add Parameter

When you select Add Parameter, you select from the parameters listed. This adds that parameter to the Set Parameter module in the Emitter Update group.

Some of these parameters can be set or modified in other modules. Some are only set using a Set Parameter module.



Parameter

Description

Emitter.Age

This parameter defines the age of this emitter.

Emitter.CurrentLoopDelay

This parameter defines the current amount of delay before the emitter's current loop repeats.

Emitter.CurrentLoopDuration

This parameter defines the duration of the current emitter loop.

Emitter.ExecutionState

This affects the state of the emitter. Valid value choices are:

Active

Inactive

InactiveClear

Complete

Emitter.ExecutionStateSource

This indicates the source of an execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

Emitter.LocalSpace

This parameter defines whether the position of particles is respective to the world origin or the owning Niagara Component's location.

False: Particle position is in WorldSpace and will be relative to the World origin. A particle with position 0,0,0 will render at the World origin.

True: Particle position is in LocalSpace and will be relative to the owning Niagara Component's location. A particle with position 0,0,0 will render at the owning Niagara Component's location.

Emitter.LoopCount

This parameter defines how many times the emitter's loop repeats.

Emitter.LoopedAge

This parameter calculates the age of the emitter relative to its current loop. For example, if an emitter has been active for 8 seconds and it loops every 5 seconds, the emitter's LoopedAge will be 3 seconds. LoopedAge returns to 0 every time an emitter loops.

Emitter.NormalizedLoopAge

This parameter calculates the age of the emitter relative to its current loop, normalized from 0 to 1. NormalizedLoopAge is expressed as LoopedAge divided by CurrentLoopDuration. If an emitter has been active for 8 seconds and it loops every 5 seconds, the emitter's LoopedAge will be 3. The emitter's NormalizedLoopAge will be 0.6.

System.ExecutionState

This affects the state of the system. Valid value choices are Active, Inactive, InactiveClear, Complete, Disabled, and Num.

System.ExecutionStateSource

This indicates the source of a system execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

Create New Parameter

When you select Create New Parameter, you select from the parameters listed. This adds a Set Parameter module to the Emitter Update group.

Parameter

Type

Description

Audio Oscilloscope

Data interface

This adds a new Audio Oscilloscope data interface module to the emitter. The Audio Oscilloscope module can directly access the waveform data of the audio signal.

Audio Spectrum

Data interface

This adds a new Audio Spectrum data interface module to the emitter. The Audio Spectrum module can drive a visualization based on how loud the audio is at specific frequencies.

Bool

Primitive

This adds a Set Variable module that has a true/false checkbox.

Camera Query

Data Interface

This adds a new Camera Query data interface module to the emitter. This data interface can be used to retrieve camera information (camera position, rotation, FOV, etc) for the specified controller index.

Collision Query

Data Interface

This adds a collision data interface to the emitter stack. This is usually used in conjunction with Collision modules.

Curl Noise

Data Interface

This adds a curl noise data interface to the emitter stack. If you use this in conjunction with Curl Noise Force modules, this data interface injects different types of noise into your simulation.

Curve for Colors

Data Interface

This adds a four-channel color curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying color.

Curve for Floats

Data Interface

This adds a single-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying float value.

Curve for Vector 2Ds

Data Interface

This adds a two-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying pair of floats.

Curve for Vector 3s

Data Interface

This adds a three-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying set of floats.

Curve for Vector 4s

Data Interface

This adds a four-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying set of floats.

ENiagaraBooleanLogicOps

Enum

This is an enumeration used by various modules and dynamic inputs that want to test using boolean logic:

Greater Than

Greater Than Or Equal To

Equal To

Not Equal To

ENiagaraCoordinateSpace

Enum

This is an enumeration used by various modules and dynamic inputs to distinguish between coordinate spaces:

Simulation: If the emitter is set to Local, use Local. Otherwise, use World.

World: In the world space of the game.

Local: In the coordinate space of the owning component.

ENiagaraExecutionState

Enum

This enumeration type is used by parameters that manage system or emitter execution states, such as Emitter.ExecutionState or System.ExecutionState.

ENiagaraExecutionStateSource

Enum

This indicates the source of an execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

ENiagara ExpansionMode

Enum

This enumeration is used by location modules to determine where the origin point of expansion is:

Inside

Centered

Outside

ENiagaraOrientationAxis

Enum

This is an enumeration used by several modules to determine which axis to do calculations with:

X Axis

Y Axis

Z Axis

ENiagaraRandomnessMode

Enum

This sets the type of random number generation used by this emitter. Valid choices are:

Simulation Defaults

Deterministic

Non-Deterministic

Float

Primitive

This creates a float value variable.

Grid2D Collection

Data Interface

This is used with simulation stages. It enables the user to read or write to a 2D array of data, and then iterate over each pixel in the grid during a simulation stage.

Int32

Primitive

This creates an integer variable.

Linear Color

Primitive

This creates an RGBA color variable, represented as a color picker.

Matrix

Primitive

This creates a 4x4 matrix variable.

Mesh Tri Coordinate

Struct

This is a simple struct containing a triangle index along with a barycentric coordinate on the face of that triangle.

Neighbor Grid 3D

Data Interface

This is used with simulation stages. It enables the user to read or write to a 3D array of data, and then iterate over each pixel in the volume during a simulation stage.

Niagara ID

Struct

This is a two-part struct used to track particles. Index in the indirection table for this particle. It allows fast access to this particle's data. It is always unique among currently living particles, but will be reused after the particle dies. AcquireTag is a unique tag for when this ID was acquired. It allows us to differentiate between particles when one dies and another particle reuses the dead particle's Index.

Occlusion Query

Data Interface

This adds a new Occlusion Query data interface module to the emitter. The data interface is used to read depth buffer occlusion information.

This can only be used with GPU emitters.



Particle Attribute Reader

Data Interface

This adds a new Particle Attribute Reader data interface to the emitter. The data interface can be used to query particle payload values from other emitters, and can sometimes be easier to use than Events.

Quat

Primitive

This creates a quaternion variable, used to represent rotations.

Simple Counter

Data Interface

This adds a new Simple Counter data interface module to the emitter. This data interface enables you to increment a thread-safe counter.

This can only be used with CPU emitter.



Skeletal Mesh

Data Interface

This is a data interface with functions to interact with a skeletal mesh's bones or sockets and skinned geometry.

Spawn Info

Struct

This is a structure used in spawning to specify the Count of particles to create, InterpStartDt or offset from the current frame begin time to start spawning, IntervalDt defining the time gap between particles being spawned, and SpawnGroup allowing spawned particles to belong to different categories.

Spline

Data Interface

This is a data interface that interacts with a Spline Asset.

Static Mesh

Data Interface

This is a data interface with functions to interact with a static mesh's surface.

Texture Sample

Data Interface

This is a data interface with functions to interact with a texture on the GPU.

Vector

Primitive

This creates a three-channel set of floats.

Vector 2D

Primitive

This creates a two-channel set of floats.

Vector 4

Primitive

This creates a four-channel set of floats.

Vector Field

Data Interface

This is a DataInterface with functions to query a vector field.

Volume Texture Sample

Data Interface

This adds a new Volume Texture data interface module to the emitter. You can use this to sample a volume texture.

Beam Modules

Camera Modules

Chaos Modules

Color Modules

Event Modules

Forces Modules

Initialization Modules

Kill Modules

Location Modules

Mass Modules

Materials Modules

Math/Blend Modules

Mesh Modules

Orientation Modules

Physics Modules

SubUV Modules

Texture Modules

Utility Modules

Vector Field Modules

Velocity Modules

New Scratch Pad Module

Set New or Existing Value Directly

Add Parameter

Create New Parameter

Particle Spawn modules occur once for each created particle. Modules in this section set up initial values for each particle. If Use Interpolated Spawning is set, some Particle Spawn modules will be updated in the Spawn stage instead of in the Particle Update stage. Modules are executed in order from the top to the bottom of the stack.

Each of the module types in the Particle Spawn group has its own section in this document, with tables that list and describe the default options available for that type of module. Keep in mind that you can create custom modules for any part of the Niagara Emitter. The ones listed here are just the ones that are automatically included with Unreal Engine 4.

Beam Modules

Module

Description

Beam Width

This module controls the width of the spawned beam and writes that width to the Particles.RibbonWidth parameter. To vary the width along the length of the beam, use a curve indexed into the Particles.RibbonLinkOrder as provided from the default spawn beam module.

Spawn Beam

This module places particles along a bezier spline, or simply along a line between two points. This is useful for sprite facing along a beam-style path, or for using with the ribbon renderer for a classic-style beam. Spawn Beam creates a static beam that does not recalculate the start and endpoints each frame.

Camera Modules

Module

Description

Camera Offset

This module offsets the particle along the vector between the particle and the camera.

Maintain in Camera Particle Scale

This retains the in-camera particle size by taking into account the camera's FOV, the particle's camera-relative depth, and the render target's size.

Chaos Modules

Module

Description

Apply Chaos Data

This sets the particle position, velocity, and color from a Chaos solver.

Color Modules

Module

Description

Color

This module directly sets the Particles.Color parameter, with scale factors for the Float3 Color and Scalar Alpha components.

Event Modules

Module

Description

Generate Location Event

This generates an event that contains the position of the particle. The event payload for each particle also contains the particle velocity, a particle ID which can be used to create a Ribbon ID per particle, the age of the particle generating the event, and a random number that can be used in various ways.

This module is placed after the Solve Forces and Velocity module, so that the event can contain both position and velocity data.



Forces Modules

Module

Description

Acceleration Force

This adds to the Physics.Force parameter, which will translate into acceleration within the solver.

Apply Initial Forces

This module converts rotational and linear forces, such as Curl Noise Force, into rotational and linear velocity.

Curl Noise Force

This adds to the Physics.Force parameter using a curl noise field. Samples a medium resolution baked tiling curl noise field by default, but can optionally sample a perlin-derived curl function directly at increased cost.

Drag

This applies the Drag value directly to particle velocity and rotational velocity, irrespective of mass. It accumulates into Physics.Drag and Physics.RotationalDrag, which are solved in the Solve Forces and Velocity and Solve Rotational Forces and Velocity modules.

Gravity Force

This applies a gravitational force (in cm/s) to the Physics.Force parameter.

Limit Force

This scales the Physics.Force parameter down to the magnitude specified if it exceeds the Force Limit.

Line Attraction Force

This accumulates a pull toward the nearest position on a line segment. It then adds that value to Transient.PhysicsForce.

Linear Force

This adds a force vector (in cm/s) to the Physics.Force parameter in a specific coordinate space.

Mesh Rotation Force

This adds a rotational force as described by the newtons applied on the yaw, pitch and roll axes, and accumulates that value to the Physics.RotationalForce parameter.

Point Attraction Force

This accumulates a pull toward AttractorPosition into the Physics.Force parameter.

Point Force

This adds force from an arbitrary point in space with optional falloff. Uses the vector between the velocity origin and the Particles.Position parameter in order to determine the force vector. If positions have not been initialized (that is, the particle position and velocity origin are on top of each other), the module will inject random velocity. You should place this module after any location modules in the stack, to make sure that the particle positions have already been initialized.

Vector Noise Force

This introduces random noise into the Physics.Force parameter.

Vortex Force

This takes a velocity around a vortex axis (with an optional additional pull towards the vortex origin) and injects it into the Physics.Force parameter.

Wind Force

This applies a wind force to particles, with an optional Air Resistance parameter. If the particle is moving faster than the wind speed in the direction of the wind, no additional force is applied.

Initialization Modules

Module

Description

Initialize Particle

This module contains several common particle parameters, which you can enable or disable as needed. There are Point Attributes such as Lifetime, Position, Mass and Color; Sprite Attributes such as Sprite Size and Sprite Rotation; and Mesh Attributes such as Mesh Scale. This module should be at the top of the stack in the Particle Spawn group.

Initialize Ribbon

This module contains several common parameters for ribbons. It has the same Point Attributes as the Initialize Particles module, and additionally has Ribbon Attributes such as Ribbon Width and Ribbon Twist. This module should be at the top of the stack in the Particle Spawn group.

Kill Modules

Module

Description

Kill Particles

This switch kills all particles if set to True (the box is checked). It allows for particles to be dynamically killed, based on this boolean, at any point in the execution stack.

Kill Particles in Volume

Interpolated Spawn

Location Modules

Module

Description

Box Location

This spawns particles in a rectangular box shape.

Cone Location

This spawns particles in a cone shape.

Cylinder Location

This spawns particles in a cylinder shape, with lathe-style controls to modify the profile of the cylinder.

Grid Location

This spawns particles in an even distribution on a grid.

Jitter Position

This jitters a spawned particle in a random direction, on a delay timer.

Rotate Around Point

This module will find a position on a forward vector-aligned circle around a user-defined center point. The radius and position along the circle can be modified over time.

Skeletal Mesh Location

This places particles on a bone, socket, triangle or vertex of a Skeletal Mesh.

Sphere Location

This spawns particles in a spherical shape, with options for hemisphere shaping and density.

Static Mesh Location

This spawns particles from the surface of a static mesh.

System Location

This spawns particles from the system's location.

Torus Location

This spawns particles in a torus shape.

Mass Modules

Module

Description

Calculate Mass and Rotational Inertia by Volume

This parameter calculates the mass and rotational inertia based on the particle's bounds and a density value. The density is measured in kilograms per cubic meter.

Calculate Size and Rotational Inertia by Mass

Calculates the particle's scale and rotational inertia based on user-driven mass and density values. The density is measured in kilograms per cubic meters.

Materials Modules

Module

Description

Dynamic Material Parameters

These write to the Dynamic Parameter Vertex Interpolator node in the Material Editor. To use Indices 1-3, change the Parameter Index on the node itself in the Material Editor to the corresponding number. This allows the use of up to four unique dynamic parameter nodes in a given material.

Math/Blend Modules

Module

Description

Cone Mask

This module defines a cone in 3D space and checks if the position input lies inside the cone. If the position lies inside the cone, it returns 1; otherwise it returns 0.

Lerp Particle Attributes

This module enables linear interpolation (lerp) of all default particle parameters. You can select the specific parameter to interpolate each default particle parameter against, and also the interpolation factor for each default particle parameter.

Recreate Camera Projection

This module recreates the camera-relative world position of a 2D scene capture's pixel. The projector transform fields allow you to reposition and rotate the projected positions.

Temporal Lerp Float

This module performs a slow linear interpolation (lerp) according to the user's specified Current Value over time. The convergence rate is specified through the Rate of Change input.

Temporal Lerp Vector

This module performs a slow linear interpolation (lerp) according to the user's specified Current Value over time. The convergence rate is specified through the Rate of Change input.

Mesh Modules

Module

Description

Initialize Mesh Reproduction Sprite

This module first chooses a random location on a skeletal mesh. Then, using the chosen triangle, it calculates an ideal particle size, UV scale, sprite alignment, and so on. To properly align a particle to a mesh surface, set the sprite's Render Alignment to Custom Alignment, and set the Facing Mode to Custom Facing. Then set the Custom Facing Vector Mask to 1, 1, 1.

If the mesh does not animate, you can check the box for Overwrite Intrinsic Variables to set all of the particle system's intrinsic parameters. If you want the Facing Mode to update during the effect, do not check the Overwrite Intrinsic Variables box. Instead, add the Update Mesh Reproduction Sprite module to the Particle Update group. Within your material, use Niagara_MeshReproductionSpriteUVs to sample the mesh's UVs.

Both the Initialize Mesh Reproduction Sprite module and the Update Mesh Reproduction Sprite module assume that the skeletal mesh UVs are square, and not compressed on one axis.

Sample Skeletal Mesh Skeleton

This module samples the bone or socket positions of a skeletal mesh, and then writes those sampled values to particle parameters. These particle parameters can then be used later in the stack.

Sample Skeletal Mesh Surface

This module samples the surface of a skeletal mesh, and then writes those sampled values to particle parameters. Those particle parameters can then be used later in the stack.

Sample Static Mesh

This module samples a static mesh, and then writes those sampled values to particle parameters. Those particle parameters can then be used later in the stack.

Update Mesh Reproduction Sprite

This module is used along with the Initialize Mesh Reproduction Sprite module. To recreate the effect in the Niagara level of Content Examples, follow these steps:

Place the Initialize Mesh Reproduction Sprite module in the Particle Spawn group.

Place the Update Mesh Reproduction Sprite module into the Particle Update group.

In the Sprite Renderer, set Alignment to Custom Alignment; set Facing Mode to Custom Facing Vector; set Custom Facing Vector Mask to 1, 1, 1.

In your Material, use Niagara Mesh Reproduction Sprite UVs to sample the mesh's UVs.

If Module.OverwriteIntrinsicVariables is set to False, make sure that this module's output variables drive the particle's attributes (such as position, alignment and so on).

Orientation Modules

Module

Description

Align Sprite to Mesh Orientation

This module aligns sprites to a mesh particle's orientation. This enables you to use the Mesh Rotation and Rotational Velocity modules to control a sprite's alignment in relation to the world. Make sure that the Alignment and Facing Mode settings in the Sprite Renderer are set to Custom Alignment and Custom Facing. Set your Custom Facing Vector Mask to 1, 1, 1.

Initial Mesh Orientation

This module aligns a mesh to a vector, or rotates it in place using a rotational vector.

Orient Mesh to Vector

This module aligns a mesh to an input vector.

Physics Modules

Module

Description

Add Rotational Velocity

This module adds to the Rotational Velocity value in a user-defined space.

Find Kinetic and Potential Energy

This module returns the following:

A particle's kinetic energy, based on the particle's velocity.

A particle's potential energy, which is the sum of all force modules that write to Physics.PotentialEnergy.

The sum of 1 and 2.

SubUV Modules

Module

Description

SubUVAnimation

Some sprites are made in a grid, with each individual sprite representing an animation frame. This module accepts the total number of sprites that are to be animated, and plots those sprites along a curve so that they animate smoothly.

Texture Modules

Module

Description

Sample Pseudo Volume Texture

This module samples the color of a pseudo volume texture, based on UVW coordinates.

Utility Modules

Module

Description

Do Once

This module keeps track of whether its trigger condition has ever been true in a previous frame. If not, Particles.Module.Execute returns True. If the trigger condition has returned True in a previous frame, Particles.Module.Execute returns False.

Increment Over Time

This module increases a value each frame. The counter variable increments using the tick delta value and multiplying it by a user-specified rate.

Update MS Vertex Animation Tools Morph Targets

This module reads morph target texture data, and outputs positions and normal vectors for a given pixel-per-particle index. Pipe the module's world space normal output into the asset's material, with tangent space normals disabled within the material in order to reproduce the mesh's surface.

For more information on generating morph target textures, see Vertex Animation Tool.

This module can directly set a particle's position. If you use it this way, do not use another module that directly sets a particle's position.



Vector Field Modules

Modules

Description

Apply Vector Field

This module takes the vector samples by a vector field sampler, and applies it as a force or velocity.

Sample Vector Field

This module samples a vector field, applying a per-particle intensity factor and an optional falloff factor, that fades the influence of the vector field towards the edges of the bounding box. This can optionally apply a local translate, rotate or scale transformation.

Velocity Modules

Module

Description

Add Velocity

This module assigns a velocity to spawned particles. You can add various dynamic inputs to modify the values you enter in this module.

Add Velocity from Point

This module adds velocity from an arbitrary point in space, with optional falloff. It uses the vector between the velocity origin and the particle's position to determine the velocity vector. If particle positions have not been initialized (causing the particle position and velocity origin to be too close together), the module will inject random velocity. For the most accurate results, place this module below any location modules in the stack. This ensures that particle positions have been initialized.

Add Velocity in Cone

This module adds velocity to the Particles.Velocity parameter in a cone shape, with parameters for cone angle, and for velocity distribution along the cone axis.

Inherit Velocity

This module adds inherited velocity from another source. This defaults to the position of the system that owns the current emitter.

Scale Velocity

This module multiplies Particles.Velocity by a separate vector in a specific coordinate space.

Static Mesh Velocity

This module adds velocity based on the normals from a static mesh, as well as adding the inherited velocity of a static mesh.

Vortex Velocity

This module calculates an angular velocity around a vortex axis, and injects it into the Particles.Velocity parameter. This is added to the initial velocity the particle has when spawned.

New Scratch Pad Module

Selecting this item in the Add (Plus sign) menu opens the Scratch Pad panel (by default this docks next to the System Overview) and places a Scratch Pad module in the Selection panel. You can also open the Scratch Pad panel by using Windows > Scratch Pad. However, by placing a Scratch Pad module in the stack, any modules or dynamic inputs you create in the Scratch Pad are automatically connected to your script. If you open the Scratch Pad panel using the Windows menu, any items you create there will have to be added to your script manually.

Set New or Existing Value Directly

Selecting this item from the Add (Plus sign) menu places a Set Parameter module in the Selection panel. Click the Plus sign (+) icon to select Add Parameter or Create New Parameter.

Add Parameter

When you select Add Parameter, you select from the parameters listed. This adds that parameter to the Set Parameter module in the Particle Spawn group.

Some of these parameters can be set or modified in other modules. Some are only set using a Set Parameter module.

Parameter

Description

DataInstance.Alive

This parameter is used to determine whether or not this particle instance is still valid, or if it can be deleted.

Particles.Age

This defines the age of a particle.

Particles.CameraOffset

This sets the Camera Offset for a particle. The Camera Offset determines the distance between the particle and the camera.

Particles.Color

This directly sets the color of the particle.

Particles.DynamicMaterialParameter

This is a four-float vector used to send data to the renderer.

Particles.DynamicMaterialParameter1

This is a four-float vector used to send data to the renderer.

Particles.DynamicMaterialParameter2

This is a four-float vector used to send data to the renderer.

Particles.DynamicMaterialParameter3

This is a four-float vector used to send data to the renderer.

Particles.ID

This is an engine-managed attribute that provides a persistent ID to each spawned particle.

Particles.Initial.Color

This sets the initial color of a particle.

Particles.Lifetime

This is the lifetime of a spawned particle in seconds.

Particles.LightRadius

This parameter determines the radius of emitted light when you are using a Light Renderer.

Particles.Mass

This parameter determines the mass of a spawned particle.

Particles.MaterialRandom

This parameter is used to drive the Particle Random node in the Material Editor. When this is not set, any Particle Randoms will get 0.0.

Particles.MeshOrientation

This determines the axis-angle rotation that is applied to a spawned mesh particle.

Particles.NormalizedAge

This is the value of Particles.Age (in seconds) divided by the value of Particles.Lifetime (in seconds). This is useful for animation, because the value generated is between 0 and 1.

Particles.Position

This sets the position of a spawned particle.

Particles.PreviousVelocity

This is used with the Solve Forces And Velocity module to calculate a particle's position in response to force and velocity. Previous velocity is needed to solve for acceleration.

Particles.RibbonFacing

This sets the facing vector of the ribbon at the ribbon particle's position, or the side vector that the ribbon's width is extended along, depending on which Facing Mode is selected.

Particles.RibbonID

This assigns a Ribbon ID to a ribbon particle. Particles with the same Ribbon ID are connected into a ribbon.

Particles.RibbonLinkOrder

This sets an explicit order for linking particles within a ribbon. Particles with the same Ribbon ID are connected into a ribbon in incrementing order according to this value.

Particles.RibbonTwist

This sets the amount of twist a ribbon particle has, in degrees.

Particles.RibbonWidth

This sets the width of a ribbon particle, in UE4 units.

Particles.Scale

This sets the XYZ scale of a non-sprite particle.

Particles.SpriteAlignment

This makes the texture point toward the sprite's selected alignment axis. When using this parameter, the Sprite Renderer's Alignment must be set to Custom Alignment.

Particles.SpriteFacing

This makes the surface of the sprite face towards a custom vector. To use this parameter, the Sprite Renderer's Facing Mode must be set to Custom Facing Vector, and values must be provided in the Sprite Renderer's Custom Facing Vector Mask setting.

Particles.SpriteRotation

This sets the screen-aligned roll of the particle, in degrees.

Particles.SpriteSize

This determines the size of the sprite particle's quad.

Particles.SubImageIndex

This sets a value which ranges from 0 to a value equal to the number of entries in the table of SubUV images.

Particles.UniqueID

This is an engine-managed attribute that serves as a unique ID for each spawned particle. The ID is incremented for each new particle spawned.

Particles.UVScale

This is used to multiply the generated UVs for Sprite Renderers.

Particles.Velocity

This determines the velocity of a particle in centimeters per second (cm/s).

Create New Parameter

When you select Create New Parameter, you select from the parameters listed. This adds that parameter to the Set Parameter module in the Particle Spawn group.

Parameter

Type

Description

Audio Oscilloscope

Data Interface

This adds a new Audio Oscilloscope data interface module to the emitter. The Audio Oscilloscope module can directly access the waveform data of the audio signal.

Audio Spectrum

Data Interface

This adds a new Audio Spectrum data interface module to the emitter. The Audio Spectrum module can drive a visualization based on how loud the audio is at specific frequencies.

Bool

Primitive

This adds a Set Variable module that has a true/false checkbox.

Camera Query

Data Interface

This adds a new Camera Query data interface module to the emitter. This data interface can be used to retrieve camera information (such as camera position, rotation, or FOV) for the specified controller index.

Collision Query

Data Interface

This adds a collision data interface to the emitter stack. This is usually used in conjunction with Collision modules.

Curl Noise

Data Interface

This adds a curl noise data interface to the emitter stack. If you use this in conjunction with Curl Noise Force modules, this data interface injects different types of noise into your simulation.

Curve for Colors

Data Interface

This adds a four-channel color curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying color.

Curve for Floats

Data Interface

This adds a single-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying float value.

Curve for Vector 2Ds

Data Interface

This adds a two-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying pair of floats

Curve for Vector 3s

Data Interface

This adds a three-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying set of floats.

Curve for Vector 4s

Data Interface

This adds a four-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying set of floats.

ENiagaraBooleanLogicOps

Enum

This is an enumeration used by various modules and dynamic inputs that want to test using boolean logic:

Greater Than

Greater Than Or Equal To

Equal To

Not Equal To

ENiagaraCoordinateSpace

Enum

This is an enumeration used by various modules and dynamic inputs to distinguish between coordinate spaces:

Simulation: If the emitter is set to local, use local. Otherwise, use World.

World: In the world space of the game.

Local: In the coordinate space of the owning component.

ENiagaraExecutionState

Enum

This enumeration type is used by parameters that manage system or emitter execution states, such as Emitter.ExecutionState or System.ExecutionState.

ENiagaraExecutionStateSource

Enum

This indicates the source of an execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

ENiagaraExpansionMode

Enum

This enumeration is used by location modules to determine where the origin point of expansion is:

Inside

Centered

Outside

ENiagaraOrientationAxis

Enum

This is an enumeration used by several modules to determine which axis to do calculations with:

X Axis

Y Axis

Z Axis

ENiagaraRandomnessMode

Enum

This sets the type of random number generation used by this emitter. Valid choices are:

Simulation Defaults

Deterministic

Non-Deterministic

Float

Primitive

This creates a float value variable.

Grid 2D Collection

Data Interface

This is used with simulation stages. It enables the user to read or write to a 2D array of data, and then iterate over each pixel in the grid during a simulation stage.

Int32

Primitive

This creates an integer variable.

Linear Color

Primitive

This creates an RGBA color variable, represented as a color picker.

Matrix

Primitive

This creates a 4x4 matrix variable.

Mesh Tri Coordinate

Struct

This is a simple struct containing a triangle index along with a barycentric coordinate on the face of that triangle.

Neighbor Grid3D

Data Interface

This is used with simulation stages. It enables the user to read or write to a 3D array of data, and then iterate over each pixel in the volume during a simulation stage.

Niagara ID

Struct

This is a two-part struct used to track particles. It allows fast access to this particle's data. It is always unique among currently living particles, but will be reused after the particle dies. AcquireTag is a unique tag for when this ID was acquired. It allows us to differentiate between particles when one dies and another particle reuses the dead particle's index.

Occlusion Query

Data Interface

This adds a new Occlusion Query data interface module to the emitter. The data interface is used to read depth buffer occlusion information.

This can only be used with GPU emitters.



Particle Attribute Reader

Data Interface

This adds a new Particle Attribute Reader data interface to the emitter. The data interface can be used to query particle payload values from other emitters, and can sometimes be easier to use than Events.

Quat

Primitive

This creates a quaternion variable, used to represent rotations.

Simple Counter

Data Interface

This adds a new Simple Counter data interface module to the emitter. This data interface enables you to increment a thread-safe counter.

This can only be used with CPU emitters.



Skeletal Mesh

Data Interface

This is a data interface with functions to interact with a skeletal mesh's bones/sockets and skinned geometry.

Spawn Info

Struct

This is a structure used in spawning to specify the Count of particles to create, InterpStartDt or offset from the current frame begin time to start spawning, IntervalDt defining the time gap between particles being spawned, and SpawnGroup allowing spawned particles to belong to different categories.

Spline

Data Interface

This is a data interface that interacts with a Spline Asset.

Static Mesh

Data Interface

This is a data interface with functions to interact with a static mesh's surface.

Texture Sample

Data Interface

This is a data interface with functions to interact with a texture on the GPU.

Vector

Primitive

This creates a three-channel set of floats.

Vector 2D

Primitive

This creates a two-channel set of floats.

Vector 4

Primitive

This creates a four-channel set of floats.

Vector Field

Data Interface

This is a data interface with functions to query a vector field.

Volume Texture Sample

Data Interface

This adds a new Volume Texture data interface module to the emitter. You can use this to sample a volume texture.

Beam Modules

Camera Modules

Collision Modules

Color Modules

Constraints Modules

Events Modules

Forces Modules

Kill Modules

Lifetime Module

Location Modules

Mass Modules

Materials Modules

Math/Blend Modules

Mesh Modules

Orientation Modules

Physics Modules

Post-Solve Modules

Ribbon Modules

Size Modules

SubUV Modules

Texture Modules

Utility Modules

Vector Field Modules

Velocity Modules

New Scratch Pad Module

Set New or Existing Value Directly

Add Parameter

Create New Parameter

Particle Update modules are called every frame, per particle. Modules in this section should update new values for this frame. Modules are executed in order from the top to the bottom of the stack.

Each of the module types in the Particle Update group has its own section in this document, with tables that list and describe the default options available for that type of module. Keep in mind, you can create custom modules for any part of a Niagara system or emitter. The ones listed here are just the ones that are automatically included with Unreal Engine.

Beam Modules

Module

Description

Beam Width Scale

This module scales the initial beam width by a user-defined scale factor.

Update Beam

This module places particles along a bezier spline, or simply along a line between two points. Useful for sprite facing along a beam-style path, or to be used with the ribbon renderer for a classic-style beam. Update Beam recalculates the spline positions in each frame, to allow for beams with dynamically changing start and end points.

Camera Modules

Module

Description

Camera Offset

This module offsets the particle along the vector between the particle and the camera.

Maintain in Camera Particle Scale

This retains the in-camera particle size by taking into account the camera's FOV, the particle's camera-relative depth, and the render target's size.

Collision Modules

Module

Description

Align Particles with Collision Plane

This module aligns a sprite to a plane over time. By default, the plane is defined by the collision module's returned collision plane. When using this module, the Alignment setting in the Sprite Renderer must be set to Custom Alignment; the Facing Mode must be set to Custom Facing Vector; and the Custom Facing Vector Mask must be set to 1, 1, 1.

Collision

This module must be placed immediately before the solver module. When used in CPU emitters, the module will cast rays in order to calculate its collision with the world. When used with GPU emitters, the module will either use the scene depth or the global distance field to find collision surfaces.

Color Modules

Module

Description

Color

This module directly sets the Particles.Color parameter, with scale factors for the Float3 Color and Scalar Alpha components.

Scale Color

By default, this module accepts the initial color (as determined in the Particle Spawn group) and scales the RGB and Alpha components separately.

Scale Color by Speed

This module scales particle color according to the magnitude of the particle's velocity vector, with minimum and maximum speed thresholds.

Constraints Modules

Module

Description

Maintain a Set Distance Between Two Points

This module takes in two different positions: the particle's position, and the target position. The module will project a point in space away from the initial position, to a location on a vector between the two positions. This vector's length is set in Ideal Distance. For certain situations, you might want to switch the target position and particle position variables.

Pendulum Constraint

This module introduces a non-physically correct pendulum constraint that interacts with forces. Add the Gravity Force module to have it interact with gravity; add the Acceleration Force module to have it interact with an acceleration force other than gravity; Add the Drag Force module to have it interact with viscous friction drag.

You must have the Pendulum Setup module in order to use the Pendulum Constraint module.



Pendulum Setup

This module introduces a non-physically correct pendulum constraint that interacts with forces. Add the Gravity Force module to have it interact with gravity; add the Acceleration Force module to have it interact with an acceleration force other than gravity; Add the Drag Force module to have it interact with viscous friction drag.

Events Modules

Module

Description

Generate Collision Event

This module generates a collision event in the emitter. This can later be used by an Event Handler in another emitter, to cause actions in the system.

Generate Death Event

This module generates a death event in the emitter. This can later be used by an Event Handler in another emitter, to cause actions in the system.

Generate Location Event

This module generates a location event in the emitter. This can later be used by an Event Handler in another emitter, to cause actions in the system.

Forces Modules

Module

Description

Acceleration Force

This adds to the Physics.Force parameter, which will translate into acceleration within the solver.

Apply Initial Forces

This module converts rotational and linear forces, such as Curl Noise Force, into rotational and linear velocity.

Curl Noise Force

This adds to the Physics.Force parameter using a curl noise field. It samples a medium resolution, baked tiling curl noise field by default. However it can optionally sample a perlin-derived curl function directly at increased cost.

Drag

This applies the Drag value directly to particle velocity and rotational velocity, irrespective of mass. It accumulates into Physics.Drag and Physics.RotationalDrag, which are solved in the Solve Forces and Velocity and Solve Rotational Forces and Velocity modules.

Gravity Force

This applies a gravitational force (in cm/s) to the Physics.Force parameter.

Limit Force

This scales the Physics.Force parameter down to the magnitude specified, if it exceeds the Force Limit.

Line Attraction Force

This accumulates a pull toward the nearest position on a line segment. It then adds that value to Transient.PhysicsForce.

Linear Force

This adds a force vector (in cm/s) to the Physics.Force parameter in a specific coordinate space.

Mesh Rotation Force

This adds a rotational force as described by the newtons applied on the yaw, pitch and roll axes, and accumulates that value to the Physics.RotationalForce parameter.

Point Attraction Force

This accumulates a pull toward AttractorPosition into the Physics.Force parameter.

Point Force

This adds force from an arbitrary point in space with optional falloff. It uses the vector between the velocity origin and the Particles.Position parameter in order to determine the force vector. If positions have not been initialized (that is, the particle position and velocity origin are on top of each other), the module will inject random velocity. You should place this module after any location modules in the stack, to make sure that the particle positions have already been initialized.

Vector Noise Force

This introduces random noise into the Physics.Force parameter.

Vortex Force

This takes a velocity around a vortex axis (with an optional additional pull towards the vortex origin) and injects it into the Physics.Force parameter.

Wind Force

This applies a wind force to particles, with an optional Air Resistance parameter. If the particle is moving faster than the wind speed in the direction of the wind, no additional force is applied.

Kill Modules

Module

Description

Kill Particles

This switch kills all particles if set to True (the box is checked). It allows for particles to be dynamically killed based on this boolean, at any point in the execution stack.

Kill Particles in Volume

This module kills particles if they are inside an analytical shape. This shape can be a box, a plane, a slab (two planes facing inwards), or a sphere. The result can also be inverted. This module must be used with Interpolated Spawn enabled, or else any spawned particles will appear for one frame and then die.

Lifetime Module

Module

Description

Particle State

This module handles killing a particle from the simulation when the particle's lifetime has elapsed.

Location Modules

Module

Description

Box Location

This spawns particles in a rectangular box shape.

Cone Location

This spawns particles in a cone shape.

Cylinder Location

This spawns particles in a cylinder shape, with lathe-style controls to modify the profile of the cylinder.

Grid Location

This spawns particles in an even distribution on a grid.

Jitter Position

This jitters a spawned particle in a random direction, on a delay timer.

Rotate Around Point

This module will find a position on a forward vector-aligned circle around a user-defined center point. The radius and position along the circle can be modified over time.

Skeletal Mesh Location

This places particles on a bone, socket, triangle or vertex of a Skeletal Mesh.

Sphere Location

This spawns particles in a spherical shape, with options for hemisphere shaping and density.

Static Mesh Location

This spawns particles from the surface of a static mesh.

System Location

This spawns particles from the system's location.

Torus Location

This spawns particles in a torus shape.

Mass Modules

Module

Description

Calculate Mass and Rotational Inertia by Volume

This calculates the mass and rotational inertia based on the particle's bounds and a density value. The density is measured in kg/m&sup3.

Calculate Size and Rotational Inertia by Mass

This calculates the particle's scale and rotational inertia based on user-driven mass and density values. The density is measured in kg/m&sup3.

Update Velocity on Mass Change

This alters the particle's angular and linear velocity based on the mass delta. In other words, if the particle's mass increases, the particle slows down; if the particle's mass decreases, the particle speeds up.

Materials Modules

Module

Description

Dynamic Material Parameters

These write to the Dynamic Parameter Vertex Interpolator node in the Material Editor. To use Indices 1-3, change the Parameter Index on the node itself in the Material Editor to the corresponding number. This allows the use of up to four unique dynamic parameter nodes in a given material.

Math/Blend Modules

Module

Description

Cone Mask

This module defines a cone in 3D space and checks if the position input lies inside the cone. If the position lies inside the cone, it returns 1; otherwise it returns 0.

Lerp Particle Attributes

This module enables linear interpolation (lerp) of all default particle parameters. You can select the specific parameter to interpolate each default particle parameter against, and also the interpolation factor for each default particle parameter.

Recreate Camera Projection

This module recreates the camera-relative world position of a scene capture 2D's pixel. The projector transform fields allow one to reposition and rotate the projected positions.

Temporal Lerp Float

This module performs a slow linear interpolation (lerp) according to the user's specified Current Value over time. The convergence rate is specified through the Rate of Change input.

Temporal Lerp Vector

This module performs a slow linear interpolation (lerp) according to the user's specified Current Value over time. The convergence rate is specified through the Rate of Change input.

Mesh Modules

Module

Description

Sample Skeletal Mesh Skeleton

This module samples the bone or socket positions of a skeletal mesh, and then writes those sampled values to particle parameters. These particle parameters can then be used later in the stack.

Sample Skeletal Mesh Surface

This module samples the surface of a skeletal mesh, then writes those sampled values to particle parameters. These particle parameters can then be used later in the stack.

Sample Static Mesh

This module samples a static mesh, and then writes those sampled values to particle parameters. These particle parameters can then be used later in the stack.

Update Mesh Reproduction Sprite

This module is used along with the Initialize Mesh Reproduction Sprite module. To recreate the effect in the Niagara level of Content Examples, follow these steps:

Place the Initialize Mesh Reproduction Sprite module in the Particle Spawn group.

Place the Update Mesh Reproduction Sprite module into the Particle Update group.

In the Sprite Renderer, set Alignment to Custom Alignment; set Facing Mode to Custom Facing Vector; set Custom Facing Vector Mask to 1, 1, 1.

In your Material, use Niagara Mesh Reproduction Sprite UVs to sample the mesh's UVs.

If Module.OverwriteIntrinsicVariables is set to False, make sure that this module's output variables drive the particle's attributes (such as position, alignment and so on).

Orientation Modules

Module

Description

Align Sprite to Mesh Orientation

This module aligns sprites to a mesh particle's orientation. This enables you to use the Mesh Rotation and Rotational Velocity modules to control a sprite's alignment in relation to the world. Make sure that the Alignment and Facing Mode settings in the Sprite Renderer are set to Custom Alignment and Custom Facing. Set your Custom Facing Vector Mask to 1, 1, 1.

Orient Mesh to Vector

This module aligns a mesh to an input vector.

Sprite Rotation Rate

This module rotates a sprite over time. The default input is in degrees. You can add the Dynamic Input Normalized Angle to Degrees if you want an input range from 0-1.

Update Mesh Orientation

This module rotates the Mesh Orientation parameter over time.

Physics Modules

Module

Description

Add Rotational Velocity

This module adds to the Rotational Velocity value in a user-defined space.

Find Kinetic and Potential Energy

This module returns the following:

A particle's kinetic energy, based on the particle's velocity.

A particle's potential energy, which is the sum of all force modules that write to Physics.PotentialEnergy.

The sum of 1 and 2.

Post-Solve Modules

Module

Description

Calculate Accurate Velocity

This module calculates an accurate velocity from a previous position to the current position. This is useful if a constraint was applied that altered the expected position of a particle outside the framework of the solver.

Ribbon Modules

Module

Description

Scale Ribbon Width

This controls the width of the spawned ribbon, and writes to Particles.RibbonWidth.

Size Modules

Module

Description

Scale Mesh Size

This module takes the initial mesh size scale, as set in the Particle Spawn group, and increases the scale by a user-set factor.

Scale Mesh Size by Speed

This module scales the initial mesh size scale by the magnitude of the velocity vector.

Scale Sprite Size

This module takes the initial sprite size scale, as set in the Particle Spawn group, and increases the scale by a user-set factor.

Scale Sprite Size by Speed

This module scales the Particles.SpriteSize parameter by the magnitude of the velocity vector.

SubUV Modules

Module

Description

SubUVAnimation

Some sprites are made in a grid, with each individual sprite representing an animation frame. This module accepts the total number of sprites that are to be animated, and plots those sprites along a curve so that they animate smoothly.

Texture Modules

Module

Description

Sample Pseudo Volume Texture

This module samples the color of a pseudo volume texture, based on UVW coordinates.

Utility Modules

Module

Description

Do Once

This module keeps track of whether its trigger condition has ever been true in a previous frame. If not, Particles.Module.Execute returns True. If the trigger condition has returned True in a previous frame, Particles.Module.Execute returns False.

Generate Grid Ribbon IDs

You can use this module to produce the output particle parameters used to produce a 3D grid with 3 ribbon emitters. In the Ribbon Renderer, replace RibbonID with Particles.RibbonID1, Particles.RibbonID2, and Particles.RibbonID3. Set the Ribbon Link Order to 1, 2 and 3. For a 2D grid, do the above, but with only 2 ribbon emitters.

Increment Over Time

This module increases a value each frame. The counter variable increments using the tick delta value and multiplying it by a user-specified rate.

Time Based State Machine

This module outputs a float parameter (Particles.Module.OnOffPercentage) that indicates if the particle is in the On state (1) or Off state (2).

Update MS Vertex Animation Tools Morph Targets

This module reads morph target texture data, and outputs positions and normal vectors for a given pixel-per-particle index. Connect the module's world space normal output into the asset's material, with tangent space normals disabled within the material in order to reproduce the mesh's surface.

For more information on generating morph target textures, see Vertex Animation Tool.

This module can directly set a particle's position. If you use it this way, do not use another module that directly sets a particle's position.



Vector Field Modules

Module

Description

Apply Vector Field

This module takes the vector samples by a vector field sampler, and applies it as a force or velocity.

Sample Vector Field

This module samples a vector field, applying a per-particle intensity factor and an optional falloff factor, that fades the influence of the vector field towards the edges of the bounding box. This can optionally apply a local translate, rotate or scale transformation.

Velocity Modules

Module

Description

Add Velocity

This module assigns a velocity to spawned particles. You can add various dynamic inputs to modify the values you enter in this module.

Add Velocity from Point

This module adds velocity from an arbitrary point in space, with optional falloff. It uses the vector between the velocity origin and the particle's position to determine the velocity vector. If particle positions have not been initialized (causing the particle position and velocity origin to be too close together), the module will inject random velocity. For the most accurate results, place this module below any location modules in the stack. This ensures that particle positions have been initialized.

Add Velocity in Cone

This module adds velocity to the Particles.Velocity parameter in a cone shape, with parameters for cone angle, and for velocity distribution along the cone axis.

Align Velocity to Random Axis

This module takes a velocity vector and maintains its magnitude, while picking a random axis to align it to, with an optional time interval between updates (in seconds).

Inherit Velocity

This module adds inherited velocity from another source. This defaults to the position of the system that owns the current emitter.

Scale Velocity

This module multiplies Particles.Velocity by a separate vector in a specific coordinate space.

Static Mesh Velocity

This module adds velocity based on the normals from a static mesh, as well as adding the inherited velocity of a static mesh.

Vortex Velocity

This module calculates an angular velocity around a vortex axis, and injects it into the Particles.Velocity parameter. This is added to the initial velocity the particle has when spawned.

New Scratch Pad Module

Selecting this item in the Add (Plus sign) menu opens the Scratch Pad panel (by default this docks next to the System Overview) and places a Scratch Pad module in the Selection panel. You can also open the Scratch Pad panel by using Windows > Scratch Pad. However, by placing a Scratch Pad module in the stack, any modules or dynamic inputs you create in the Scratch Pad are automatically connected to your script. If you open the Scratch Pad panel using the Windows menu, any items you create there will have to be added to your script manually.

Set New or Existing Value Directly

Selecting this item from the Add(Plus sign) menu places a Set Parameter module in the Selection panel. Click the Plus sign (+) icon to select Add Parameter or Create New Parameter.

Add Parameter

When you select Add Parameter, you select from the parameters listed. This adds that parameter to the Set Parameter module in the Particle Update group.

Some of these parameters can be set or modified in other modules. Some are only set using a Set Parameter module.

Parameter

Description

DataInstance.Alive

This parameter is used to determine whether or not this particle instance is still valid, or if it can be deleted.

Particles.Age

This defines the age of a particle.

Particles.CameraOffset

This sets the Camera Offset for a particle. The Camera Offset determines the distance between the particle and the camera.

Particles.Color

This directly sets the color of the particle.

Particles.DynamicMaterialParameter

This is a four-float vector used to send data to the renderer.

Particles.DynamicMaterialParameter1

This is a four-float vector used to send data to the renderer.

Particles.DynamicMaterialParameter2

This is a four-float vector used to send data to the renderer.

Particles.DynamicMaterialParameter3

This is a four-float vector used to send data to the renderer.

Particles.ID

This is an engine-managed attribute that provides a persistent ID to each spawned particle.

Particles.Initial.Color

This sets the initial color of a sprite used by a particle.

Particles.Lifetime

This is the lifetime of a spawned particle in seconds.

Particles.LightRadius

This parameter determines the radius of emitted light when you are using a Light Renderer.

Particles.Mass

This parameter determines the mass of a spawned particle.

Particles.MaterialRandom

This parameter is used to drive the Particle Random node in the Material Editor. When this is not set, any Particle Randoms will get 0.0.

Particles.MeshOrientation

This determines the axis-angle rotation that is applied to a spawned mesh particle.

Particles.NormalizedAge

This is the value of Particles.Age (in seconds) divided by the value of Particles.Lifetime (in seconds). This is useful for animation, because the value generated is between 0 and 1.

Particles.Position

This sets the position of a spawned particle.

Particles.PreviousVelocity

This is used with the Solve Forces And Velocity module to calculate a particle's position in response to force and velocity. Previous velocity is needed to solve for acceleration.

Particles.RibbonFacing

This sets the facing vector of the ribbon at the ribbon particle's position, or the side vector that the ribbon's width is extended along, depending on which Facing Mode is selected.

Particles.RibbonID

This assigns a Ribbon ID to a ribbon particle. Particles with the same Ribbon ID are connected into a ribbon.

Particles.RibbonLinkOrder

This sets an explicit order for linking particles within a ribbon. Particles with the same Ribbon ID are connected into a ribbon in incrementing order according to this value.

Particles.RibbonTwist

This sets the amount of twist a ribbon particle has, in degrees.

Particles.RibbonWidth

This sets the width of a ribbon particle, in UE4 units.

Particles.Scale

This sets the XYZ scale of a non-sprite particle.

Particles.SpriteAlignment

This makes the texture point toward the sprite's selected alignment axis. When using this parameter, the Sprite Renderer's Alignment must be set to Custom Alignment.

Particles.SpriteFacing

This makes the surface of the sprite face towards a custom vector. To use this parameter, the Sprite Renderer's Facing Mode must be set to Custom Facing Vector, and values must be provided in the Sprite Renderer's Custom Facing Vector Mask setting.

Particles.SpriteRotation

This sets the screen-aligned roll of the particle, in degrees.

Particles.SpriteSize

This determines the size of the sprite particle's quad.

Particles.SubImageIndex

This sets a value which ranges from 0 to a value equal to the number of entries in the table of SubUV images.

Particles.UniqueID

This is an engine-managed attribute that serves as a unique ID for each spawned particle. The ID is incremented for each new particle spawned.

Particles.UVScale

This is used to multiply the generated UVs for Sprite Renderers.

Particles.Velocity

This determines the velocity of a particle in centimeters per second (cm/s).

Create New Parameter

When you select Create New Parameter, you select from the parameters listed. This adds that parameter to the Set Parameter module in the Particle Update group.

Parameter

Type

Description

Audio Oscilloscope

Data Interface

This adds a new Audio Oscilloscope data interface module to the emitter. The Audio Oscilloscope module can directly access the waveform data of the audio signal.

Audio Spectrum

Data Interface

This adds a new Audio Spectrum data interface module to the emitter. The Audio Spectrum module can drive a visualization based on how loud the audio is at specific frequencies.

Bool

Primitive

This adds a Set Variable module that has a true/false checkbox.

Camera Query

Data Interface

This adds a new Camera Query data interface module to the emitter. This data interface can be used to retrieve camera information (such as camera position, rotation, or FOV) for the specified controller index.

Collision Query

Data Interface

This adds a collision data interface to the emitter stack. This is usually used in conjunction with Collision modules.

Curl Noise

Data Interface

This adds a curl noise data interface to the emitter stack. If you use this in conjunction with Curl Noise Force modules, this data interface injects different types of noise into your simulation.

Curve for Colors

Data Interface

This adds a four-channel color curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying color.

Curve for Floats

Data Interface

This adds a single-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying float value.

Curve for Vector 2Ds

Data Interface

This adds a two-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying pair of floats.

Curve for Vector 3s

Data Interface

This adds a three-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying set of floats.

Curve for Vector 4s

Data Interface

This adds a four-channel curve data interface for the simulation. This curve can be sampled by dynamic inputs or other modules to create a time-varying set of floats.

ENiagaraBooleanLogicOps

Enum

This is an enumeration used by various modules and dynamic inputs that want to test using boolean logic:

Greater Than

Greater Than Or Equal To

Equal To

Not Equal To

ENiagaraCoordinateSpace

Enum

This is an enumeration used by various modules and dynamic inputs to distinguish between coordinate spaces:

Simulation: If the emitter is set to local, use local. Otherwise, use World.

World: In the world space of the game.

Local: In the coordinate space of the owning component.

ENiagaraExecutionState

Enum

This enumeration type is used by parameters that manage system or emitter execution states, such as Emitter.ExecutionState or System.ExecutionState.

ENiagaraExecutionStateSource

Enum

This indicates the source of an execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

ENiagaraExpansionMode

Enum

This enumeration is used by location modules to determine where the origin point of expansion is:

Inside

Centered

Outside

ENiagaraOrientationAxis

Enum

This is an enumeration used by several modules to determine which axis to do calculations with:

X Axis

Y Axis

Z Axis

ENiagaraRandomnessMode

Enum

This sets the type of random number generation used by this emitter. Valid choices are:

Simulation Defaults

Deterministic

Non-Deterministic

Float

Primitive

This creates a float value variable.

Grid 2D Collection

Data Interface

This is used with simulation stages. It enables the user to read or write to a 2D array of data, and then iterate over each pixel in the grid during a simulation stage.

Int32

Primitive

This creates an integer variable.

Linear Color

Primitive

This creates an RGBA color variable, represented as a color picker.

Matrix

Primitive

This creates a 4x4 matrix variable.

Mesh Tri Coordinate

Struct

This is a simple struct containing a triangle index along with a barycentric coordinate on the face of that triangle.

Neighbor Grid3D

Data Interface

This is used with simulation stages. It enables the user to read or write to a 3D array of data, and then iterate over each pixel in the volume during a simulation stage.

Niagara ID

Struct

This is a two-part struct used to track particles. It allows fast access to this particle's data. It is always unique among currently living particles, but will be reused after the particle dies. AcquireTag is a unique tag for when this ID was acquired. It allows us to differentiate between particles when one dies and another particle reuses the dead particle's index.

Occlusion Query

Data Interface

This adds a new Occlusion Query data interface module to the emitter. The data interface is used to read depth buffer occlusion information.

This can only be used with GPU emitters.



Particle Attribute Reader

Data Interface

This adds a new Particle Attribute Reader data interface to the emitter. The data interface can be used to query particle payload values from other emitters, and can sometimes be easier to use than Events.

Quat

Primitive

This creates a quaternion variable, used to represent rotations.

Simple Counter

Data Interface

This adds a new Simple Counter data interface module to the emitter. This data interface enables you to increment a thread-safe counter.

This can only be used with CPU emitters.



Skeletal Mesh

Data Interface

This is a data interface with functions to interact with a skeletal mesh's bones/sockets and skinned geometry.

Spawn Info

Struct

This is a structure used in spawning to specify the Count of particles to create, InterpStartDt or offset from the current frame begin time to start spawning, IntervalDt defining the time gap between particles being spawned, and SpawnGroup allowing spawned particles to belong to different categories.

Spline

Data Interface

This is a data interface that interacts with a Spline Asset.

Static Mesh

Data Interface

This is a data interface with functions to interact with a static mesh's surface.

Texture Sample

Data Interface

This is a data interface with functions to interact with a texture on the GPU.

Vector

Primitive

This creates a three-channel set of floats.

Vector 2D

Primitive

This creates a two-channel set of floats.

Vector 4

Primitive

This creates a four-channel set of floats.

Vector Field

Data Interface

This is a data interface with functions to query a vector field.

Volume Texture Sample

Data Interface

This adds a new Volume Texture data interface module to the emitter. You can use this to sample a volume texture.

Component Renderer

Light Renderer

Mesh Renderer

Ribbon Renderer

Sprite Renderer



Niagara Renderers describe how Unreal Engine should display each spawned particle. Note that this does not have to be visual. Unlike modules, the placement of the renderer in the stack is not necessarily relevant to draw order. Five types of renderers are currently supported:

Component Renderer

Light Renderer

Mesh Renderer

Ribbon Renderer

Sprite Renderer

The following sections list the parameters available in each type of renderer, along with a description of what that parameter does.

Component Renderer

Features are sometimes made available in an Experimental state so you can try them out, provide feedback, and see what we are planning. We do not recommend shipping projects with Experimental features. Please keep in mind that we do not guarantee backward compatibility for assets created at the experimental stage, the APIs for these features are subject to change, and we may remove entire Experimental features or specific functionality at our discretion.

The Component Renderer provides a way for you to spawn any type of component, and update its properties with data from the particle simulation.

The Component Type sets which component is used (for example, a Point Light) for the particle simulation and displays properties and settings relevant to it under the Component Properties category within the Details panel. The properties can be edited directly from this list, and all components spawned by the renderer will be constructed based on these properties.

To inject particle data into the components, use the dropdown menu to the right of a property and select the particle attribute to bind to this property (see the example below). Some component types require a special class as their parent. This means they will not work with the Component Render, but instead may be a subclass of SceneComponent. They can be either a C++ class or a Blueprint. An example of this is the Landscape Component, which needs a LandscapeProxy Actor as its parent.



This example uses a Point Light component. The properties displayed vary according to the component selected.

Because the configured bindings are evaluated and updated at the end of every tick after the particle simulation is finished, the Component Renderer can be an expensive operation to run. It should be used with caution.

Currently, only basic Niagara data types can be bound (float, bool, vector, and so on). Structs, objects, and enum properties can be set dynamically.

When using components in your Niagara systems, it's best to keep the component count as low as possible (unless you are working in an environment where performance is less of a concern, such as a cutscene rendered with Sequencer). Since each component has its own tick each frame in addition to the Niagara system, spawning a lot of effects with Component Renderers can impact performance.

In cases where a component does not expose properties, or the one you want to bind to is inside a nested struct, you can create a custom subclass of the component and add the property yourself. An example would be not being able to bind a value to the lighting channels of a Point Light component because they use a custom FLightingChannels struct.



However, you can subclass the Point Light component and add the channel properties yourself, then set the active light channels on the component's tick function, like the example below:



This enables you to then bind particle values to your properties in the Component Renderer.



The following properties are part of the Component Renderer before setting a Component Type.

Parameter

Description

Component Type

The scene component class to spawn with this renderer.

Component Count Limit

The maximum number of components that this emitter will spawn or update each frame.

Enabled Binding

Determines which attribute is used to check if component rendering should be enabled for a particle. This can be used to control the spawn-rate on a per-particle basis. If the binding does not exist, all particles spawn a component.

Assign Components on Particle ID

If true, then a component will not be automatically assigned to the first particle available, but will try to stick to one particle over its lifetime. Disabling this option is faster, but a particle can get a different component each tick, which can lead to problems with motion blur or flickering.

Only Create Components on Particle Spawn

If true, then new components can only be created on newly spawned particles. If a particle is not able to create a component on its first frame (for example, because the component limit was reached) then it will be blocked from spawning a component on subsequent frames.

Visualize Components

If true, then the editor visualization is enabled for the component; this has no effect in a shipped game. For example, the light component shows the active bounds in the editor viewport when this is enabled.

Light Renderer

The Niagara Light Renderer module has the following base parameters.

Parameter

Description



Light Rendering



Use Inverse Squared

This determines whether to use physically-based inverse squared falloff from the light. If this is unchecked, the value from the Light Exponent BindingInverse Squared Falloff

Affects Translucence

This determines whether lights from this renderer affect translucency. Use with caution: if you enable this, create only a few particle lights; the larger and more numerous they are, the more it will cost.

Radius Scale

This factor is used to scale each particle light radius.

Color Add

This is a static color shift that is applied to each rendered light. You can set values for the X, Y, and Z axes. These axes correspond to the R, G, and B color values (X=R, Y=G, Z=B); they do not indicate position.



Sort Order



Sort Order Hint

By default, emitters are drawn in the order they are added to the stack in a Niagara system. The Sort Order Hint value allows you to control the draw order in a more detailed way. Materials of the same type will draw in order from lowest Sort Order value to highest within the system. The default value is 0.



Bindings



Light Rendering Enabled Binding

This defines the attribute used to check whether or not light rendering should be enabled for a particle. By default, this uses the Particles.LightEnabled variable if it exists; otherwise it uses the default of None.

Light Exponent Binding

This defines the attribute used for the light's exponent when Inverse Squared Falloff is disabled. By default, this uses the variable Particles.LightExponent if it exists; otherwise it uses the default of 10.

Position Binding

This defines the attribute used for positioning when generating lights. By default, this uses the Particles.Position variable if it exists; otherwise it uses the default Engine.Owner.Position variable. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Color Binding

This defines the attribute used for color when generating lights. By default, this uses the Particles.Color variable if it exists; otherwise it uses the default of R: 1, G: 1, B: 1, A: 1.

Radius Binding

This defines the attribute used for light radius when generating light. By default, this uses the Particles.LightRadius variable if it exists; otherwise it uses the default of 100. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Volumetric Scattering Binding

This defines the attribute used for the intensity of the volumetric scattering from this light. It scales the light's intensity and color. By default, this uses the Particles.LightVolumetricScattering variable if it exists; otherwise it uses the default of 1.

Mesh Renderer

The Niagara Mesh Renderer has the following base parameters.

Parameter

Description



Mesh Rendering



Particle Mesh

This determines which Static Mesh will be instanced when rendering mesh particles. By default, the Static Mesh's Material is used. The Material must have the Niagara Mesh Particles flag checked.

Override Materials

When this is checked, it defines an array of Materials that are used instead of the Static Mesh's Material. All Override Materials must have the Niagara Mesh Particles flag checked. If the Particle Mesh requires more Materials than exist in this array, or if any entry in this array is set to None, the emitter uses the Particle Mesh's existing Material instead.

Facing Mode

This setting determines how the instanced Mesh orients itself relative to the camera.

Default: This ignores the camera altogether. The mesh aligns its local-space X-axis with the particle's local-space X-axis, after transforming by the Particles.Transform vector (if it exists).

Velocity: The mesh aligns its local-space X-axis with the particle's Particles.Velocity vector.

Camera Position: The mesh local-space X-axis points toward the camera.

Camera Plane: The mesh local-space X-axis points towards the closest point on the camera view plane.





Sorting



Sort Mode

This determines how particles are sorted prior to rendering. Choices are:

None: There is no particle sorting.

View Depth: This sorts by depth to the camera's near plane.

View Distance: This sorts by the distance to the camera's origin.

Custom Ascending: This sorts according to a per-particle attribute; lower values are rendered before higher values.

Custom Descending: This sorts according to a per-particle attribute; higher values are rendered before lower values.



Sort Only When Translucent

If this is checked, particles are only sorted when using a translucent material.



Bindings



Position Binding

This defines the attribute used for positioning when generating instanced meshes. By default, this uses the Particles.Position variable if it exists; otherwise it uses the default Engine.Owner.Position variable. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Color Binding

This defines the attribute used for color when generating instanced meshes. By default, this uses the Particles.Color variable if it exists; otherwise it uses the default of R: 1, G: 1, B: 1, A: 1.

Velocity Binding

This defines the attribute used for velocity when generating instanced meshes. By default, this uses the Particles.Velocity variable if it exists; otherwise it uses the default of X: 0, Y: 0, Z: 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Mesh Orientation Binding

This defines the attribute used for orienting meshes when generating instanced meshes. By default, this uses the Particles.MeshOrientation variable if it exists; otherwise it uses the default of X: 0, Y: 0, Z: 0, W: 1.

Scale Binding

This defines the attribute used for scale when generating instanced meshes. By default, this uses the Particles.Scale variable if it exists; otherwise it uses the default of X: 1, Y: 1, Z: 1. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Dynamic Material Binding

This defines the attribute used for dynamic material parameters when generating instanced meshes. By default, this uses the Particles.DynamicMaterialParameter if it exists; otherwise it uses the default of X: 1, Y: 1, Z: 1, W: 1.

Dynamic Material 1Binding

This defines the attribute used for dynamic material parameters when generating instanced meshes. By default, this uses the Particles.DynamicMaterialParameter1 if it exists; otherwise it uses the default of X: 1, Y: 1, Z: 1, W: 1.

Dynamic Material 2Binding

This defines the attribute used for dynamic material parameters when generating instanced meshes. By default, this uses the Particles.DynamicMaterialParameter2 if it exists; otherwise it uses the default of X: 1, Y: 1, Z: 1, W: 1.

Dynamic Material 3Binding

This defines the attribute used for dynamic material parameters when generating instanced meshes. By default, this uses the Particles.DynamicMaterialParameter3 if it exists; otherwise it uses the default of X: 1, Y: 1, Z: 1, W: 1.

Material Random Binding

This defines the attribute used for material randoms when generating instanced meshes. By default, this uses the Particles.MaterialRandom variable if it exists; otherwise it uses the default of 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Custom Sorting Binding

This defines the attribute used for custom sorting. By default, this uses the Particles.NormalizedAge variable if it exists; otherwise it uses the default of 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Normalized Age Binding

This defines the attribute used for normalized age. By default, this uses the Particles.NormalizedAge variable if it exists; otherwise it uses the default of 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.



Sort Order



Sort Order Hint

By default, emitters are drawn in the order they are added to the stack in a Niagara system. The Sort Order Hint value allows you to control the draw order in a more detailed way. Materials of the same type will draw in order from lowest Sort Order value to highest within the system. The default value is 0.

Ribbon Renderer

The Niagara Ribbon Renderer has the following base parameters.

Parameter

Description



Ribbon Rendering



Material

Select the material used to render the ribbon.

Facing Mode

This setting determines how the ribbon orients itself relative to the camera.

Screen: The ribbon faces the screen.

Custom: This uses Particles.RibbonFacing as the facing vector.

Custom Side Vector: Use Particles.RibbonFacing as the side vector, and calculate the facing vector from that.

Using Ribbon Twist with this mode is not supported.





UV0 Tiling Distance

This setting tiles UV channel 0 based on the distance traversed by the ribbon. This disables the offsetting of UVs by age.

UV0 Scale

This setting defines the scale of UV channel 0 when you are using Tiling Distance.

UV0 Offset

This setting defines the offset used for UV channel 0 when you are using Tiling Distance.

UV0 Age Offset Mode

This setting defines the mode to use when offsetting UV channel 0 by age. This enables smooth texture movement when particles are added and removed at the end of the ribbon. This is not used when the Ribbon Link Order Binding is in use, or when Tiling Distance is in use.

UV1 Tiling Distance

This setting tiles UV channel 1 based on the distance traversed by the ribbon. This disables the offsetting of UVs by age.

UV1 Scale

This setting defines the scale of UV channel 1 when you are using Tiling Distance.

UV1 Offset

This setting defines the offset of UV channel 1 when you are using Tiling Distance.

UV1 Offset Mode

This setting defines the mode to use when offsetting UV channel 1 by age. This enables smooth texture movement when particles are added and removed at the end of the ribbon. This is not used when the Ribbon Link Order Binding is in use, or when Tiling Distance is in use.

Draw Direction

Draw Direction determines whether the ribbon is rendered Front to Back (from a point far from the camera to a point near the camera), or Back to Front (from a point near the camera to a point far from the camera). However this usually only makes a difference if the material is translucent and the ribbon folds on itself.



Tessellation



Curve Tension

This setting defines the curve tension, or how long the curve's tangents are. The setting's value ranges from 0 to 1. The higher the value, the sharper the curve becomes.

Mode

This setting defines the tessellation mode allowing custom tessellation parameters, or disabling tessellation entirely.

Automatic: This uses the default tessellation parameters.

Custom: This allows customized tessellation parameters.

Disabled: This disables tessellation.



Max Tessellation Factor

If the Mode is set to Custom, this defines the custom tessellation factor. Settings range from 1 to 16. Larger values increase the amount of tessellation.

Use Constant Factor

If this is checked, the Max Tessellation Factor is used. Otherwise, the tessellation factor is adaptively selected based on the parameters below.

Tessellation Angle

This setting defines the angle (in degrees) at which the tessellation occurs. Settings range from 1 to 180. Smaller values increase the amount of tessellation. If the setting is 0, the Max Tessellation Factor is used.

Screen Space

If this is checked, use the ribbon's screen space percentage to adaptively adjust the tessellation factor.



Sort Order



Sort Order Hint

By default, emitters are drawn in the order they are added to the stack in a Niagara system. The Sort Order Hint value allows you to control the draw order in a more detailed way. Materials of the same type will draw in order from lowest Sort Order value to highest within the system. The default value is 0.



Bindings



Position Binding

This defines the attribute used for positioning when generating ribbons. By default, this uses the Particles.Position variable if it exists; otherwise it uses the default Engine.Owner.Position variable. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Color Binding

This defines the attribute used for color when generating ribbons. By default, this uses the Particles.Color variable if it exists; otherwise it uses the default of R: 1, G: 1, B: 1, A: 1.

Velocity Binding

This defines the attribute used for velocity when generating ribbons. By default, this uses the Particles.Velocity variable if it exists; otherwise it uses the default of X: 0, Y: 0, Z: 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Normalized Age

This defines the attribute used for normalized age when generating ribbons. By default, this uses the Particles.NormalizedAge variable if it exists; otherwise it uses the default of 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Ribbon Twist Binding

This defines the attribute used for ribbon twist when generating ribbons. By default, this uses the Particles.RibbonTwist variable if it exists; otherwise it uses the default of 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Ribbon Width Binding

This defines the attribute used for ribbon width when generating ribbons. By default, this uses the Particles.RibbonWidth variable if it exists; otherwise it uses the default of 1. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Ribbon Facing Binding

This defines the attribute used for ribbon facing when generating ribbons. By default, this uses the Particles.RibbonFacing variable if it exists; otherwise it uses the default of X: 0, Y: 0, Z: 1. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Ribbon Id Binding

This defines the attribute used for ribbon ID when generating ribbons. Uses the Particles.RibbonID attribute if it exists, otherwise it uses the default Index: 0 AcquireTag: 0.

Ribbon Link Order Binding

This defines the attribute used for ribbon link order when generating ribbons. By default, this uses the Particles.RibbonLinkOrder variable if it exists; otherwise it uses the default of 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Material Random Binding

This defines the attribute used for material randoms when generating ribbons. By default, this uses the Particles.MaterialRandom variable if it exists; otherwise it uses the default of 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Dynamic Material Binding

This defines the attribute used for dynamic material parameters when generating instanced ribbons. Use the Particles.DynamicMaterialParameter if it exists, otherwise use the default of X: 1, Y: 1, Z: 1, W: 1.

Dynamic Material 1Binding

This defines the attribute used for dynamic material parameters when generating instanced ribbons. Use the Particles.DynamicMaterialParameter1 if it exists, otherwise use the default of X: 1, Y: 1, Z: 1, W: 1.

Dynamic Material 2Binding

This defines the attribute used for dynamic material parameters when generating instanced ribbons. Use the Particles.DynamicMaterialParameter2 if it exists, otherwise use the default of X: 1, Y: 1, Z: 1, W: 1.

Dynamic Material 3Binding

This defines the attribute used for dynamic material parameters when generating instanced ribbons. Use the Particles.DynamicMaterialParameter3 if it exists, otherwise use the default of X: 1, Y: 1, Z: 1, W: 1.

Sprite Renderer

The Niagara Sprite Renderer has the following base parameters.

Parameter

Description



Sprite Rendering



Material

Select the material used to render the particle. The material selected must have the Use with Niagara Sprites flag checked.

Alignment

This setting defines how the particle alignment is affected by other parameters. For example, the Unaligned setting indicates that only Particle.SpriteRotation and FacingMode parameters affect the alignment of the particle.

Facing Mode

This setting defines how the sprite particle orients itself relative to the camera. For example, the Face Camera setting indicates that the particle's origin will always attempt to align its axes to the camera's axes.

Custom Facing Vector Mask

This is used as a per-axis interpolation factor, along with the CustomFacingVector mode, to determine how the sprite particle orients itself to the camera. You can set the X, Y, and Z axes separately. A setting of 1.0 means the sprite particle is fully facing the custom vector. A setting of 0.0 uses the standard facing strategy.

Pivot in UVSpace

This setting determines the location of the pivot point for this particle. It follows the Unreal Engine's UV space, which has the upper left of the image at 0,0 and the bottom right of the image at 1,1 with the halfway point being at 0.5,0.5.

Remove HMD Roll

Check this box to remove the HMD view roll in VR.

Minimum Facing Camera Blend Distance

The distance at which the FacingCameraDistanceBlend is fully FacingCamera.

Maximum Facing Camera Blend Distance

The distance at which FacingCameraDistanceBlend is fully FacingCameraPosition.



Sorting



Sort Mode

This determines how particles are sorted prior to rendering. Choices are:

None: There is no particle sorting.

View Depth: This sorts by depth to the camera's near plane.

View Distance: This sorts by the distance to the camera's origin.

Custom Ascending: This sorts according to a per-particle attribute; lower values are rendered before higher values.

Custom Descending: This sorts according to a per-particle attribute; higher values are rendered before lower values.



Sort Only When Translucent

If this is checked, particles are only sorted when you are using a translucent material.



Sub UV



Sub Image Size

When you use Subimage lookups for your particles, this setting provides the number of columns (X) and rows (Y).

Sub UV Blending Enabled

If this is checked, the Sub Image UV lookup is blended with its next adjacent member, using the fractional part of the SubImageIndex float value as the linear interpolation factor (lerp).



Bindings



Position Binding

This defines the attribute used for positioning when generating sprites. By default, this uses the Particles.Position variable if it exists; otherwise it uses the default variable Engine.Owner.Position. The dropdown shows other variables that have the same data type as Particles.Position; however, those options probably do not make sense to use here.

Color Binding

This defines the attribute used for color when generating sprites. By default, this uses the Particles.Color variable if it exists; otherwise it uses the default of R: 1, G: 1, B: 1, A: 1. You can use any other attribute of a compatible type instead if you want to customize the data being fed into this renderer.

Velocity Binding

This defines the attribute used for velocity when generating sprites. By default, this uses the Particle.Velocity variable if it exists; otherwise it uses the default of X: 0, Y: 0, Z: 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Sprite Rotation Binding

This defines the attribute used for rotation (in degrees) when generating sprites. By default, this uses the Particles.SpriteRotation if it exists; otherwise it uses the default of 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Sprite Size Binding

This defines the attribute used for size when generating sprites. By default, this uses the Particle.SpriteSize variable if it exists; otherwise it uses the default of X: 50, Y: 50. You can use any other attribute of a compatible type instead if you want to customize the data being fed into this renderer.

Sprite Facing Binding

This defines the attribute used for facing when generating sprites. By default, this uses the Particles.SpriteFacing variable if it exists; otherwise it uses the default of X: 1, Y: 0, Z: 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Sprite Alignment Binding

This defines the attribute used for alignment when generating sprites. By default, this uses the Particles.SpriteAlignment variable if it exists; otherwise it uses the default of X: 1, Y: 0, Z: 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Sub Image Index Binding

This defines the attribute used for sprite sub image indexing when generating sprites. By default, this uses the Particles.SubImageIndex variable if it exists; otherwise it uses the default of 0. You can use any other attribute of a compatible type; however, the options available in the dropdown may or may not make sense to use for this binding.

Dynamic Material Binding

This defines the attribute used for dynamic material parameters when generating sprites. By default, this uses the Particles.DynamicMaterialParameter if it exists; otherwise it uses the default of X: 1, Y: 1, Z: 1, W: 1.

Dynamic Material 1Binding

This defines the attribute used for dynamic material parameters when generating sprites. By default, this uses the Particles.DynamicMaterialParameter1 if it exists; otherwise it uses the default of X: 1, Y: 1, Z: 1, W: 1.

Dynamic Material 2Binding

This defines the attribute used for dynamic material parameters when generating sprites. By default, this uses the Particles.DynamicMaterialParameter2 if it exists; otherwise it uses the default of X: 1, Y: 1, Z: 1, W: 1.

Dynamic Material 3Binding

This defines the attribute used for dynamic material parameters when generating sprites. By default, this uses the Particles.DynamicMaterialParameter3 if it exists; otherwise it uses the default of X: 1, Y: 1, Z: 1, W: 1.

Camera Offset Binding

This defines the attribute used for camera offset when generating sprites. By default, this uses the Particles.CameraOffset variable if it exists; otherwise it uses the default of 0. You can select other compatible attributes from the dropdown menu.

UVScale Binding

This defines the attribute used for UV scale when generating sprites. By default, this uses the Particles.UVScale variable if it exists; otherwise it uses the default of X: 1, Y: 1. You can select other compatible attributes from the dropdown menu.

Material Random Binding

This defines the attribute used for material randoms when generating sprites. By default, this uses Particles.MaterialRandom if it exists; otherwise it uses the default of 0. You can select other compatible attributes from the dropdown menu.

Custom Sorting Binding

This defines the attribute used for custom sorting. By default, this uses the Particles.NormalizedAge variable if it exists; otherwise it uses the default of 0. You can select other compatible attributes from the dropdown menu.

Normalized Age Binding

This defines the attribute used for custom sorting. By default, this uses the Particles.NormalizedAge variable if it exists; otherwise it uses the default of 0. You can select other compatible attributes from the dropdown menu.



Cutout



Use Material Cutout Texture

If this is checked, use the cutout texture from the Material Opacity Mask; if none exist, use the cutout texture from Material Opacity.

Cutout Texture

Select the texture to create the bounding geometry from.

Bounding Mode

Set the number of bounding vertices. More bounding vertices results in reduced overdraw, but adds more triangle overhead. The eight vertex mode is best used when the Sub UV texture has a lot of space to cut out that is not captured by the four vertex mode, and when the particles using the texture will be few and large.

Opacity Source Mode

This setting has the following options:

OSM Alpha

OSM Color Brightness

OSM Red Channel

OSM Green Channel

OSM Blue Channel



Alpha Threshold

Alpha channel values larger than the threshold are considered occupied and will be contained in the bounding geometry. Raising this threshold slightly can reduce overdraw in particles using this animation Asset.



Sort Order



Sort Order Hint

By default, emitters are drawn in the order they are added to the stack in a Niagara system. The Sort Order Hint value allows you to control the draw order in a more detailed way. Materials of the same type will draw in order from lowest Sort Order value to highest within the system. The default value is 0.

User Parameters

System Properties Item

The System Settings group contains User Parameters, and System Properties.

User Parameters

User Parameters can only be set from outside the Niagara simulation, such as from Blueprint logic or C++ code. This section displays User Parameters that have been created.

System Properties Item

By default, the System Properties item is included in every created system, even if you create an empty one. The System Properties item contains the following base parameters.

Parameter

Description



Debug



Dump Debug System Info

This checkbox indicates whether the debug information for the System is written to the log each frame. This is useful for tracking down really strange behavior but is very verbose.

Dump Debug Emitter Info

This checkbox indicates whether the debug information for the Emitter is written to the log each frame. This is useful for tracking down really strange behavior but is very verbose.



System



Effect Type

Click the dropdown to select an Effect Type to apply to the system. Effect Types are a useful way of organizing settings for a class of visual effects. For example, you might want to control the scalability settings for all Weapon Impacts, and those settings can be stored in a Weapon Impact Effect Type asset.

Scalability Overrides

This is where you can set overrides related to performance on different platforms.

These are overrides of the defaults specified in the Effect Type above.



Fixed Bounds

This checkbox enables or disables fixed bounds. If this is enabled, you can set the minimum and maximum fixed bounds for the entire system. It is also possible to set fixed bounds for individual emitters in their Emitter Properties item.



Performance



Auto Deactivate

This checkbox enables or disables automatic deactivation of emitters in the system. If enabled, it will deactivate the system if all the emitters in the system are not spawning particles, regardless of particle lifetime settings.

Max Pool Size

This value is the maximum number of components of this system that are kept resident in the world component pool.



Warmup



Warmup Time

This is the system warmup time in seconds. This value is used to calculate the Warmup Tick Count setting, if Warmup Tick Count is not set manually. It rounds down to the nearest multiple of the Warmup Tick Delta value.

Be careful using this, because it can lead to hitches.



Warmup Tick Count

This is the number of ticks to process for warmup. You can set this manually, or have it set by using the Warmup Time setting.

Be careful using this, because it can lead to hitches.



Warmup Tick Delta

This is the delta time to use for Warmup Ticks.



Asset Options



Expose to Library

If this setting is enabled, this system is exposed to the library. This means that by default it will show up in the menu when you add a module.

Is Template Asset

If this setting is enabled, it indicates that this system is a template that is exposed in the new System Wizard. Assets created from templates will not inherit from a parent Emitter, so these assets start without any inheritance connections.

Template Asset Description

This is the description displayed next to the System or Emitter in the new System Wizard.



Emitter



Bake Out Rapid Iteration

This checkbox enables or disables baking rapid iteration parameters into a normal compile. Making this change can improve performance, but will make iterating on the asset significantly more difficult.

Spawning Modules

New Scratch Pad Module

Set New or Existing Value Directly

Add Parameter

Create New Parameter

System Spawn modules occur once per created system. Modules in this section set up initial values for each system. Modules are executed in order from the top to the bottom of the stack.

Each of the module types in the System Spawn group has its own section in this document, with tables describe how that module functions. Keep in mind that you can create custom modules for any part of a Niagara system or emitter. The ones listed here are just the ones that are automatically included with Unreal Engine.

Spawning Modules

Module

Description

Spawn Burst Instantaneous

This module causes all emitters to spawn a burst of particles spontaneously.

New Scratch Pad Module

Selecting this item in the Add (Plus sign) menu opens the Scratch Pad panel (by default this docks next to the System Overview) and places a Scratch Pad module in the Selection panel. You can also open the Scratch Pad panel by using Windows > Scratch Pad. However, by placing a Scratch Pad module in the stack, any modules or dynamic inputs you create in the Scratch Pad are automatically connected to your script. If you open the Scratch Pad panel using the Windows menu, any items you create there will have to be added to your script manually.

Set New or Existing Value Directly

Selecting this item from the Add (Plus sign icon) menu places a Set Parameter module in the Selection panel. Click the Plus sign (+) icon to select Add Parameter or Create New Parameter. Choices for each of these are in the sections below.

Add Parameter

When you select Set Specific Parameter, you select from the parameters listed. This adds a Set Parameter module to the System Spawn group.

Some of these parameters can be set or modified in other modules. Some are only set using a Set Variable module.



Parameter

Description

System.Age

This parameter defines the age of the named system.

System.LoopedAge

This parameter calculates the age of the system relative to its current loop. For example, if a system has been active for 8 seconds and it loops every 5 seconds, the system's LoopedAge will be 3 seconds. LoopedAge returns to 0 every time a system loops.

System.NormalizedLoopAge

This parameter calculates the age of the system relative to its current loop, normalized from 0 to 1. NormalizedLoopAge is expressed as LoopedAge divided by CurrentLoopDuration. If a system has been active for 8 seconds and it loops every 5 seconds, the system's LoopedAge will be 3. The system's NormalizedLoopAge will be 0.6.

System.CurrentLoopDelay

This parameter defines the current amount of delay before the named system's current loop repeats.

System.CurrentLoopDuration

This parameter defines the duration of the named system's loop.

System.ExecutionState

This affects the state of the system. Valid value choices are:

Active

Inactive

InactiveClear

Complete

System.ExecutionStateSource

This indicates the source of an execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

System.LocalSpace

This parameter defines whether the position of particles is respective to the world origin or the owning Niagara Component's location. Settings are:

False: Particle position is in WorldSpace and will be relative to the World origin. A particle with position 0,0,0 will render at the World origin.

True: Particle position is in LocalSpace and will be relative to the owning Niagara Component's location. A particle with position 0,0,0 will render at the owning Niagara Component's location.

System.LoopCount

This parameter defines how many times the system's loop repeats.

System.ExecutionState

This affects the state of the system. Valid value choices are:

Active

Inactive

InactiveClear

Complete

System.ExecutionStateSource

This variable is linked to the ENiagaraExecutionStateSource parameter, which indicates the source of a system execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

Create New Parameter

When you select Create New Parameter, you select from the parameters listed. This adds that parameter to the Set Parameter module in the System Spawn group.

Parameter

Type

Description

Audio Oscilloscope

Data interface

This adds a new Audio Oscilloscope data interface module to the emitter. The Audio Oscilloscope module can directly access the waveform data of the audio signal.

Audio Spectrum

Data interface

This adds a new Audio Spectrum data interface module to the emitter. The Audio Spectrum module can drive a visualization based on how loud the audio is at specific frequencies.

Bool

Primitive

This adds a Set Variable module that has a true/false checkbox.

Camera Query

Data Interface

This adds a new Camera Query data interface module to the emitter. This data interface can be used to retrieve camera information (camera position, rotation, FOV, etc) for the specified controller index.

ENiagaraBooleanLogicOps

Enum

This is an enumeration used by various modules and dynamic inputs that want to test using boolean logic:

Greater Than

Greater Than Or Equal To

Equal To

Not Equal To

ENiagaraCoordinateSpace

Enum

This is an enumeration used by various modules and dynamic inputs to distinguish between coordinate spaces:

Simulation: If the emitter is set to Local, use Local. Otherwise, use World.

World: In the world space of the game.

Local: In the coordinate space of the owning component.

ENiagaraExecutionState

Enum

This enumeration type is used by parameters that manage system or emitter execution states, such as Emitter.ExecutionState or System.ExecutionState.

ENiagaraExecutionStateSource

Enum

This indicates the source of an execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

ENiagaraExpansionMode

Enum

This enumeration is used by location modules to determine where the origin point of expansion is:

Inside

Centered

Outside

ENiagaraLegacyTrailMode

Enum

This enum controls the way that the width scale property affects animation trails. This is only used for Legacy Anim Trail support when converting from Cascade to Niagara.

ENiagaraOrientationAxis

Enum

This is an enumeration used by several modules to determine which axis to do calculations with:

X Axis

Y Axis

Z Axis

ENiagaraRandomnessMode

Enum

This sets the type of random number generation used by this emitter. Valid choices are:

Simulation Defaults

Deterministic

Non-Deterministic

Float

Primitive

This creates a float value variable.

Grid2D Collection

Data Interface

This is used with simulation stages. It enables the user to read or write to a 2D array of data, and then iterate over each pixel in the grid during a simulation stage.

Int32

Primitive

This creates an integer variable.

Linear Color

Primitive

This creates an RGBA color variable, represented as a color picker.

Matrix

Primitive

This creates a 4x4 matrix variable.

Mesh Tri Coordinate

Struct

This is a simple struct containing a triangle index along with a barycentric coordinate on the face of that triangle.

Neighbor Grid 3D

Data Interface

This is used with simulation stages. It enables the user to read or write to a 3D array of data, and then iterate over each pixel in the volume during a simulation stage.

Niagara ID

Struct

This is a two-part struct used to track particles. It allows fast access to this particle's data. It is always unique among currently living particles, but will be reused after the particle dies. AcquireTag is a unique tag for when this ID was acquired. It allows us to differentiate between particles when one dies and another particle reuses the dead particle's index.

Occlusion Query

Data Interface

This adds a new Occlusion Query data interface module to the emitter. The data interface is used to read depth buffer occlusion information.

This can only be used with GPU emitters.



Quat

Primitive

This creates a quaternion variable, used to represent rotations.

Simple Counter

Data Interface

This adds a new Simple Counter data interface module to the emitter. This data interface enables you to increment a thread-safe counter.

This can only be used with CPU emitters.



Particle Attribute Reader

Data Interface

This adds a new Particle Attribute Reader data interface to the emitter. The data interface can be used to query particle payload values from other emitters, and can sometimes be easier to use than Events.

Spawn Info

Struct

This is a structure used in spawning to specify the Count of particles to create, InterpStartDt or offset from the current frame begin time to start spawning, IntervalDt defining the time gap between particles being spawned, and SpawnGroup allowing spawned particles to belong to different categories.

Vector

Primitive

This creates a three-channel set of floats.

Vector 2D

Primitive

This creates a two-channel set of floats.

Vector 4

Primitive

This creates a four-channel set of floats.

Vector Field

Data Interface

This is a data interface with functions to query a vector field.

Volume Texture Sample

Data Interface

This adds a new Volume Texture data interface module to the emitter. You can use this to sample a volume texture.

System State Module

New Scratch Pad Module

Set New or Existing Value Directly

Add Parameter

Create New Parameter

System Update modules are called in every frame, per system. Modules in this section should update new values for this frame. Modules are executed in order from the top to the bottom of the stack.

Each of the module types in the System Update group has its own section in this document, with tables that describe how that module functions. Keep in mind that you can create custom modules for any part of a Niagara system or emitter. The ones listed here are just the ones that are automatically included with Unreal Engine 4.

System State Module

Below is a table describing the various parameters that can be set for the System State module.

Parameter

Description

Inactive Response

This setting determines what happens when the emitter enters the Inactive state. Inactive means the emitter is dormant and no longer able to spawn or manage particles. Options are:

Complete: Emitters will finish, then the system is killed.

Kill: System and emitters are both killed immediately.

Loop Behavior

This setting indicates how many times the loop repeats.

Loop Duration

This setting establishes the duration of the life cycle. It can be initialized with a random number, but by default the initial duration value persists as the duration of all the following loop iterations.

Recalculate Duration Each Loop

Check this box if you want to calculate a new duration for each loop iteration.

Loop Delay

If you want to delay the loop, check this box and enter a value for how long the loop lasts.

New Scratch Pad Module

Selecting this item in the Add (Plus sign) menu opens the Scratch Pad panel (by default this docks next to the System Overview) and places a Scratch Pad module in the Selection panel. You can also open the Scratch Pad panel by using Windows > Scratch Pad. However, by placing a Scratch Pad module in the stack, any modules or dynamic inputs you create in the Scratch Pad are automatically connected to your script. If you open the Scratch Pad panel using the Windows menu, any items you create there will have to be added to your script manually.

Set New or Existing Value Directly

Selecting this item from the Add (Plus sign icon) menu places a Set Parameter module in the Selection panel. Click the Plus sign (+) icon to select Add Parameter or Create New Parameter.

Add Parameter

When you select Set Specific Parameter, you select from the parameters listed. This adds a Set Parameter module to the System Update group.

Some of these parameters can be set or modified in other modules. Some are only set using a Set Variable module.



Parameter

Description

System.Age

This parameter defines the age of the named system.

System.CurrentLoopDelay

This parameter defines the current amount of delay before the named system's current loop repeats.

System.CurrentLoopDuration

This parameter defines the duration of the named system's loop.

System.ExecutionState

This affects the state of the system. Valid value choices are:

Active

Inactive

InactiveClear

Complete

System.ExecutionStateSource

This indicates the source of an execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

System.LocalSpace

This parameter defines whether the position of particles is respective to the world origin or the owning Niagara Component's location. Settings are:

False: Particle position is in WorldSpace and will be relative to the World origin. A particle with position 0,0,0 will render at the World origin.

True: Particle position is in LocalSpace and will be relative to the owning Niagara Component's location. A particle with position 0,0,0 will render at the owning Niagara Component's location.

System.LoopCount

This parameter defines how many times the system's loop repeats.

System.LoopedAge

This parameter calculates the age of the system relative to its current loop. For example, if a system has been active for 8 seconds and it loops every 5 seconds, the system's LoopedAge will be 3 seconds. LoopedAge returns to 0 every time a system loops.

System.NormalizedLoopAge

This parameter calculates the age of the system relative to its current loop, normalized from 0 to 1. NormalizedLoopAge is expressed as LoopedAge divided by CurrentLoopDuration. If a system has been active for 8 seconds and it loops every 5 seconds, the system's LoopedAge will be 3. The system's NormalizedLoopAge will be 0.6.

System.ExecutionState

This affects the state of the system. Valid value choices are:

Active

Inactive

InactiveClear

Complete

System.ExecutionStateSource

This variable is linked to the ENiagaraExecutionStateSource parameter, which indicates the source of a system execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

Create New Parameter

When you select Create New Parameter, you select from the parameters listed. This adds a Set Parameter module to the System Update section.

Parameter

Type

Description

Audio Oscilloscope

Data interface

This adds a new Audio Oscilloscope data interface module to the emitter. The Audio Oscilloscope module can directly access the waveform data of the audio signal.

Audio Spectrum

Data interface

This adds a new Audio Spectrum data interface module to the emitter. The Audio Spectrum module can drive a visualization based on how loud the audio is at specific frequencies.

Bool

Primitive

This adds a Set Variable module that has a true/false checkbox.

Camera Query

Data Interface

This adds a new Camera Query data interface module to the emitter. This data interface can be used to retrieve camera information (camera position, rotation, FOV, etc) for the specified controller index.

ENiagaraBooleanLogicOps

Enum

This is an enumeration used by various modules and dynamic inputs that want to test using boolean logic:

Greater Than

Greater Than Or Equal To

Equal To

Not Equal To

ENiagaraCoordinateSpace

Enum

This is an enumeration used by various modules and dynamic inputs to distinguish between coordinate spaces:

Simulation: If the emitter is set to Local, use Local. Otherwise, use World.

World: In the world space of the game.

Local: In the coordinate space of the owning component.

ENiagaraExecutionState

Enum

This enumeration type is used by parameters that manage system or emitter execution states, such as Emitter.ExecutionState or System.ExecutionState.

ENiagaraExecutionStateSource

Enum

This indicates the source of an execution state setting. It is used to allow scalability to change the state, but only if the state has not been defined by something with higher precedence.

ENiagaraExpansionMode

Enum

This enumeration is used by location modules to determine where the origin point of expansion is:

Inside

Centered

Outside

ENiagaraOrientationAxis

Enum

This is an enumeration used by several modules to determine which axis to do calculations with:

X Axis

Y Axis

Z Axis

ENiagaraRandomnessMode

Enum

This enumeration is used by location modules to determine where the origin point of expansion is:

Inside

Centered

Outside

Float

Primitive

This creates a float value variable.

Grid2D Collection

Data Interface

This is used with simulation stages. It enables the user to read or write to a 2D array of data, and then iterate over each pixel in the grid during a simulation stage.

Int32

Primitive

This creates an integer variable.

Linear Color

Primitive

This creates an RGBA color variable, represented as a color picker.

Matrix

Primitive

This creates a 4x4 matrix variable.

Mesh Tri Coordinate

Struct

This is a simple struct containing a triangle index along with a barycentric coordinate on the face of that triangle.

Neighbor Grid 3D

Data Interface

This is used with simulation stages. It enables the user to read or write to a 3D array of data, and then iterate over each pixel in the volume during a simulation stage.

Niagara ID

Struct

This is a two-part struct used to track particles. It allows fast access to this particle's data. It is always unique among currently living particles, but will be reused after the particle dies. AcquireTag is a unique tag for when this ID was acquired. It allows us to differentiate between particles when one dies and another particle reuses the dead particle's index.

Occlusion Query

Data Interface

This adds a new Occlusion Query data interface module to the emitter. The data interface is used to read depth buffer occlusion information.

This can only be used with GPU emitters.



Quat

Primitive

This creates a quaternion variable, used to represent rotations.

Simple Counter

Data Interface

This adds a new Simple Counter data interface module to the emitter. This data interface enables you to increment a thread-safe counter.

This can only be used with CPU emitters.



Particle Attribute Reader

Data Interface

This adds a new Particle Attribute Reader data interface to the emitter. The data interface can be used to query particle payload values from other emitters, and can sometimes be easier to use than Events.

Spawn Info

Struct

This is a structure used in spawning to specify the Count of particles to create, InterpStartDt or offset from the current frame begin time to start spawning, IntervalDt defining the time gap between particles being spawned, and SpawnGroup allowing spawned particles to belong to different categories.

Vector

Primitive

This creates a three-channel set of floats.

Vector 2D

Primitive

This creates a two-channel set of floats.

Vector 4

Primitive

This creates a four-channel set of floats.

Vector Field

Data Interface

This is a data interface with functions to query a vector field.

Volume Texture Sample

Data Interface

This adds a new Volume Texture data interface module to the emitter. You can use this to sample a volume texture.

Event Handler Properties

Receive Event Modules

An Event Handler determines how an emitter responds to incoming events. For each event, you create an Event Handler Properties item and a Receive Event item. There can be multiple events in each emitter.



Events currently do not work with GPU simulation. They can only be used with CPU simulations.



In order to use an Event Handler, you need to first place an Event Module in the Particle Update group of the emitter that is generating the event. For example, if you want the particles in Emitter B to follow the particles in Emitter A, you would place a Generate Location Event module in the Particle Update group of Emitter A. Then you would add an Event Handler to Emitter B, along with a Receive Location Event item, to listen for that location event.

In order to use events properly, make sure to enable Requires Persistent IDs in the Emitter Properties item of any emitter that is generating events.

Event Handler Properties

Parameter

Description

Source

Click the dropdown to select the source emitter and event.

Execution Mode

This controls which particles have the event script run on them. Available options are:

Spawned Particles: The event script is run only on particles that were spawned in response to the current event in the emitter.

Every Particle: The event script is run on every existing particle in the emitter.

Be careful with this mode, as it can lead to a large amount of runtime work.



Max Events Per Frame

This sets the number of events that are consumed by this event handler. If the number of events generated is greater than this value, those additional events will be ignored.

Spawn Number

This controls whether or not particles are spawned as a result of handling this event. If Random Spawn Number is checked, this indicates the maximum number of particles spawned.

Min Spawn Number

If Random Spawn Number is checked, this indicates the minimum number of particles spawned.

Random Spawn Number

Check this box to randomly generate the number of particles that spawn as a result of handling this event.

Receive Event Modules

Module Name

Description

Receive Collision Event

This is required to listen for a generated collision event (created by the Generate Collision Event module in the Particle Update group). Optionally, you can enable Inherited Collision Velocity Scale to determine how much of the parent velocity particles will inherit.

Receive Death Event

This is required to listen for a generated death event (created by the Generate Death Event module in the Particle Update group). Optionally, you can enable Inherited Velocity Scale to determine how much of the parent velocity particles will inherit.

Receive Location Event

This is required to listen for a generated location event (created by the Generate Location Event module in the Particle Update group). The Receive Location Event has the following settings:

Inherited Velocity: This determines how much of the parent velocity the particles inherit.

Use Acceleration: Extrapolate from the incoming event's acceleration to determine the new position.

Inherit Parent Normalized Age: This sends the maximum of either the receiving particle lifetime or the parent particle lifetime.

Spawn Count: This indicates how many particles are spawning as a result of this event.

Overview

Menu Bar

File

Edit

Asset

Window

Toolbar

Script Details Panel

Parameters Panel

Stats Panel

Node Graph

Niagara Message Log Panel

Selected Details Panel

Overview

You can use the Niagara Script Editor to create new modules, dynamic inputs, or other scripts to use in Niagara systems and emitters. You can open the Script Editor by double-clicking in the header of any module. This document describes the user interface (UI) of the Script Editor, broken down into the following parts.



Click image for full size.

Menu Bar

Toolbar

Script Details Panel

Parameters Panel

Stats Panel

Node Graph

Niagara Message Log Panel

Selected Details Panel

Menu Bar



The tables below only describe commands that apply to the Niagara Editor itself; there may be additional commands displayed in those menus that open asset editors or other parts of the Unreal Editor.

File

Command

Description

Save

Saves the current emitter.

Save As

Saves the current emitter under a different name.

Open Asset

Displays a window to select other assets.

Save All

Saves all assets and levels in this project.

Choose Files to Save

Displays a dialog with options for saving assets and levels.

Connect to Source Control

Displays a dialog where you can connect to source control, allowing source control functions to be performed on content.

Edit

Command

Description

Undo

Undoes the last action.

Redo

Redoes an action that was undone.

Undo History

Displays a dialog listing all undo actions.

Asset

Command

Description

Find in Content Browser

Switches to most recently used Content Browser, and selects the current asset in that Content Browser.

Reference Viewer

Displays a dialog that shows all of the current asset's references.

Size Map

Displays an interactive map showing the approximate size of the asset and everything it references.

Audit Assets

Opens the Asset Audit UI and displays information about the selected assets.

Shader Cook Statistics

Displays statistics for the shader cook process.

Window

Command

Description

Toolbar

Shows or hides the Toolbar.

Node Graph

Shows or hides the Node Graph.

Script Details

Shows or hides the Script Details panel.

Selected Details

Shows or hides the Selected Details panel.

System Details

Shows or hides the System Details panel.

Parameters

Shows or hides the Parameters panel.

Stats

Shows or hides the Stats panel.

Niagara Message Log

Shows or hides the Niagara Message Log panel.

Toolbar



Tool Name

Description

Save



Saves the current script.

Browse



Switches to the most recent Content Browser and selects the current Asset.

Apply



Applies unsaved changes to the current Asset.

Compile



Compiles all changes made to the script.

Refresh



Refreshes panels to correctly depict dependencies.

Script Details Panel



Click image for full size.

Setting

Description

Module Usage Bitmask

Use this dropdown to select the kinds of scripts that are appropriate to reference this module. You can select more than one.

Category

Use this field to indicate what category this module or script will be listed under when the user opens the add menu. Click the small downward arrow to display advanced text settings for this text field.

Provided Dependencies

Use this to create an array of the IDs of any dependencies this module provides to other modules. Add elements to the array by clicking the Plus sign icon (+).

Required Dependencies

This array contains dependencies this module requires from other modules in the stack. Each array element contains four members:

ID: This is the unique ID of the required dependent module.

Type: This indicates whether the dependency belongs before or after this module.

Script Constraints: Specifies constraints related to the source script for modules providing dependencies.

Description: Enter a description of the required dependency. Click the small downward arrow to display advanced text settings for this text field.

Deprecated

This box is checked if the module is no longer used. Enabling this setting activates the next two settings. If this box is unchecked, the next two settings are unavailable.

Deprecation Message

Enter the message you want displayed when this module is deprecated. Click the small downward arrow to display advanced text settings for this text field.

Deprecation Recommendation

This is the module you want to recommend in place of the deprecated module. Click the dropdown to select the recommended module.

Conversion Utility

Use this to write or select custom logic to convert the contents of an existing script assignment to this script.

Experimental

Check this box to label this module as experimental (and therefore less supported). If this box is checked, the next setting becomes active; if left unchecked the next setting is unavailable.

Experimental Message

If this module is experimental, you can use this setting to enter a message you want displayed when the module is selected. Click the small downward arrow to display advanced text settings for this text field.

Expose to Library

Check this box to expose this module to the library.

Description

Use this to enter a description for this module. Click the small downward arrow to display advanced text settings for this text field.

Keywords

This is a text field where you can enter a list of space-separated keywords that can be used to find this module in editor menus.

Highlights

Use this to choose which color-coded icons appear in the module when it is displayed in the System Overview. The list is structured as an array. You can add to the array by clicking the Plus sign icon (+).

Script Metadata

Use this to create maps, which are associative, unordered containers that pair a set of keys with a set of values.

Input Parameters

This lists the input parameters included in this script. You can add parameters by clicking the Plus sign icon (+).

Output Parameters

This lists the output parameters included in this script. You can add parameters by clicking the Plus sign icon (+).

Parameters Panel



This panel lists all the parameters that are used by the module you are editing. When you are building your script, you can drag and drop parameters from this panel into the Node Graph. The following table lists the categories, along with a description of that category. You can click the Plus sign (+) icon to display a menu of parameters to add to that category. You can also drag and drop parameters from this panel into the Graph while you are building a script.

Parameter Category

Description

System Attributes

Persistent attributes that are written in the System stage, and can be read anywhere.

Emitter Attributes

Persistent attributes that are written in the Emitter stage, and can be read in the Emitter and Particle stages.

Particle Attributes

Persistent attributes that are written in the Particle stage, and can be read in Particle stages.

Module Inputs

Values that expose a module input to the System and Emitter Editor.

Static Switch

Values that can only be set at edit time.

Modules Locals

Transient values that can be written to and read from within a single module. Transient values do not persist from frame to frame, or between stages.

Engine Provided

Read-only values that are provided by the Engine. The source of these values can be the simulation itself, or the owner of the simulation.

Stats Panel



Node Graph



Similar to other types of Node Graphs used in UE4, this is a visual representation of the HLSL script you are building. You can right-click anywhere in the Graph to open a menu of nodes to choose from. You can also drag off an input or output on one of the existing nodes to open the same menu.

Niagara Message Log Panel



If there are any warnings or errors that occur when you compile your script, they will appear here.

Selected Details Panel



This panel displays details about a specific node that you have selected in the Node Graph.



Not all selected nodes will have information displayed in this panel.



Getting Started

Development Setup

Unreal Engine Architecture

Gameplay Architecture

Gameplay Guides

Unreal Engine API Reference

System Guides

Automated Builds

Asset Handling Reference Guides

Unreal Engine provides two toolsets for programmers which can also be used in tandem to accelerate development workflows. New gameplay classes, Slate and Canvas user interface elements, and editor functionality can be written with C++, and all changes will be reflected in Unreal Editor after compiling with either Visual Studio or XCode. The Blueprint visual scripting system is a robust tool which enables classes to be created in-editor through wiring together function blocks and property references.

C++ classes can be used as a base for Blueprint classes, and in this way programmers can set up fundamental gameplay classes that are then sub-classed and iterated on by level designers.

Getting Started



Create your first code project and add a new C++ class.

Create your first code project and add a new C++ class.

Development Setup



Tips, tricks, and techniques for setting up Visual Studio to work with Unreal Engine

Tips, tricks, and techniques for setting up Visual Studio to work with Unreal Engine



Guide for installing, setting up, and using the UnrealVS extension for Visual Studio.

Guide for installing, setting up, and using the UnrealVS extension for Visual Studio.



Useful tips and tricks for working on Unreal Engine content in Visual Studio

Useful tips and tricks for working on Unreal Engine content in Visual Studio





Steps for connecting to the source code repository and downloading the latest build of Unreal Engine.

Steps for connecting to the source code repository and downloading the latest build of Unreal Engine.



Describes how to update your fork of the Unreal Engine source code to get the latest fixes and newest features.

Describes how to update your fork of the Unreal Engine source code to get the latest fixes and newest features.



Describes how to use the GitHub Pull Request mechanism to submit changes you've made to the Unreal Engine source back to Epic.

Describes how to use the GitHub Pull Request mechanism to submit changes you've made to the Unreal Engine source back to Epic.



Compiling Unreal Engine from source code.

Compiling Unreal Engine from source code.



Reference guide for solution and project build configurations.

Reference guide for solution and project build configurations.



Add code to your project and generate project files for IDEs.

Add code to your project and generate project files for IDEs.



An overview of the C++ Class Wizard in Unreal Engine.

An overview of the C++ Class Wizard in Unreal Engine.



Compiling individual game projects using Visual Studio on Windows, or Xcode on Mac.

Compiling individual game projects using Visual Studio on Windows, or Xcode on Mac.



Recompile and patch your game's binaries at runtime.

Recompile and patch your game's binaries at runtime.



Applications, tools, and add-ins that are useful for programmers working with Unreal Engine.

Applications, tools, and add-ins that are useful for programmers working with Unreal Engine.



The Sparse Class Data system eliminates wasted memory from redundant properties.

The Sparse Class Data system eliminates wasted memory from redundant properties.



Track memory usage in your Unreal Projects.

Track memory usage in your Unreal Projects.

Unreal Engine Architecture

Whether you are programming with C++, Blueprints, or a combination of the two, the underlying Unreal Engine architecture is the same.



Reference for Unreal Engine's Assert Functionality

Reference for Unreal Engine's Assert Functionality



Reference for creating and implementing gameplay classes.

Reference for creating and implementing gameplay classes.



Reference for creating and implementing functions for gameplay Classes

Reference for creating and implementing functions for gameplay Classes



Collections of gameplay classes belonging to a game project compiled into DLLs.

Collections of gameplay classes belonging to a game project compiled into DLLs.



Reference to creating and implementing interfaces.

Reference to creating and implementing interfaces.



Metadata keywords used when declaring UClasses, UFunctions, UProperties, UEnums, and UInterfaces to specify how they behave with various aspects of Unreal Engine and the editor

Metadata keywords used when declaring UClasses, UFunctions, UProperties, UEnums, and UInterfaces to specify how they behave with various aspects of Unreal Engine and the editor



Reference for creating and implementing properties for gameplay classes.

Reference for creating and implementing properties for gameplay classes.



Reference to creating and implementing structs for gameplay classes.

Reference to creating and implementing structs for gameplay classes.



Step-by-step instructional guides for hands-on learning of programming in Unreal Engine.

Step-by-step instructional guides for hands-on learning of programming in Unreal Engine.



A How To Guide for Referencing Actors in Unreal Engine.

A How To Guide for Referencing Actors in Unreal Engine.

Gameplay Architecture



Methods for loading and unloading assets during runtime.

Methods for loading and unloading assets during runtime.



A collection of arguments that can be passed to the engine's executable to configure options controlling how it runs.

A collection of arguments that can be passed to the engine's executable to configure options controlling how it runs.



Core Redirects enable remapping classes, enums, functions, packages, properties, and structs at load time.

Core Redirects enable remapping classes, enums, functions, packages, properties, and structs at load time.



Developers can extend this system to validate assets with custom-scripted rulesets.

Developers can extend this system to validate assets with custom-scripted rulesets.



Modules are the building blocks of Unreal Engine's software architecture. You can organize your code into modules to create more efficient and maintainable projects.

Modules are the building blocks of Unreal Engine's software architecture. You can organize your code into modules to create more efficient and maintainable projects.



Control how an asset is referenced and loaded into memory.

Control how an asset is referenced and loaded into memory.



How assets are discovered by the editor and how to make it know more about asset types before they are loaded.

How assets are discovered by the editor and how to make it know more about asset types before they are loaded.



An overview of the string classes available in Unreal with reference guides for FName, FText, and FString.

An overview of the string classes available in Unreal with reference guides for FName, FText, and FString.



An Overview of the Tasks System.

An Overview of the Tasks System.



Using customized serialization code and versioning to control how Objects are loaded from Assets and Packages.

Using customized serialization code and versioning to control how Objects are loaded from Assets and Packages.



Methods of creating new instances of Objects in gameplay code.

Methods of creating new instances of Objects in gameplay code.



Overview of the features of the UObject system.

Overview of the features of the UObject system.

Gameplay Guides

Unreal Engine API Reference



Unreal Engine C++ API Reference

System Guides



Guide to creating new nodes for use within graphs in Anim Blueprints.

Guide to creating new nodes for use within graphs in Anim Blueprints.



Overview of the automation system used for unit testing, feature testing, and content stress testing.

Overview of the automation system used for unit testing, feature testing, and content stress testing.



Technical guide for programmers working with Blueprints.

Technical guide for programmers working with Blueprints.



Learn how to use online subsystems and services in Unreal Engine, including Epic Online Services.

Learn how to use online subsystems and services in Unreal Engine, including Epic Online Services.



An overview of Online Subsystem Steam, including how to set up your project for distribution on Valve's Steam platform.

An overview of Online Subsystem Steam, including how to set up your project for distribution on Valve's Steam platform.



Information for graphics programmers working with the rendering systems and writing shaders.

Information for graphics programmers working with the rendering systems and writing shaders.



Program user interfaces with Unreal Engine's Slate framework.

Program user interfaces with Unreal Engine's Slate framework.



Reference material for Unreal Engine's build pipeline

Reference material for Unreal Engine's build pipeline

Automated Builds



Learn syntax to write BuildGraph script conditions.

Learn syntax to write BuildGraph script conditions.



Learn about BuildGraph Elements.

Learn about BuildGraph Elements.



Learn about valid data types for BuildGraph attributes.

Learn about valid data types for BuildGraph attributes.



Customize your builds with the BuildGraph scripting system.

Customize your builds with the BuildGraph scripting system.



This page provides sample BuildGraph Script usage.

This page provides sample BuildGraph Script usage.

Asset Handling Reference Guides



Methods for loading and unloading assets during runtime.

Methods for loading and unloading assets during runtime.



How assets are discovered by the editor and how to make it know more about asset types before they are loaded.

How assets are discovered by the editor and how to make it know more about asset types before they are loaded.



Developers can extend this system to validate assets with custom-scripted rulesets.

Developers can extend this system to validate assets with custom-scripted rulesets.

Getting Started

Development Setup

Unreal Engine Architecture

Gameplay Architecture

Gameplay Guides

Unreal Engine API Reference

System Guides

Automated Builds

Asset Handling Reference Guides

Unreal Engine provides two toolsets for programmers which can also be used in tandem to accelerate development workflows. New gameplay classes, Slate and Canvas user interface elements, and editor functionality can be written with C++, and all changes will be reflected in Unreal Editor after compiling with either Visual Studio or XCode. The Blueprint visual scripting system is a robust tool which enables classes to be created in-editor through wiring together function blocks and property references.

C++ classes can be used as a base for Blueprint classes, and in this way programmers can set up fundamental gameplay classes that are then sub-classed and iterated on by level designers.

Getting Started



Create your first code project and add a new C++ class.

Create your first code project and add a new C++ class.

Development Setup



Tips, tricks, and techniques for setting up Visual Studio to work with Unreal Engine

Tips, tricks, and techniques for setting up Visual Studio to work with Unreal Engine



Guide for installing, setting up, and using the UnrealVS extension for Visual Studio.

Guide for installing, setting up, and using the UnrealVS extension for Visual Studio.



Useful tips and tricks for working on Unreal Engine content in Visual Studio

Useful tips and tricks for working on Unreal Engine content in Visual Studio





Steps for connecting to the source code repository and downloading the latest build of Unreal Engine.

Steps for connecting to the source code repository and downloading the latest build of Unreal Engine.



Describes how to update your fork of the Unreal Engine source code to get the latest fixes and newest features.

Describes how to update your fork of the Unreal Engine source code to get the latest fixes and newest features.



Describes how to use the GitHub Pull Request mechanism to submit changes you've made to the Unreal Engine source back to Epic.

Describes how to use the GitHub Pull Request mechanism to submit changes you've made to the Unreal Engine source back to Epic.



Compiling Unreal Engine from source code.

Compiling Unreal Engine from source code.



Reference guide for solution and project build configurations.

Reference guide for solution and project build configurations.



Add code to your project and generate project files for IDEs.

Add code to your project and generate project files for IDEs.



An overview of the C++ Class Wizard in Unreal Engine.

An overview of the C++ Class Wizard in Unreal Engine.



Compiling individual game projects using Visual Studio on Windows, or Xcode on Mac.

Compiling individual game projects using Visual Studio on Windows, or Xcode on Mac.



Recompile and patch your game's binaries at runtime.

Recompile and patch your game's binaries at runtime.



Applications, tools, and add-ins that are useful for programmers working with Unreal Engine.

Applications, tools, and add-ins that are useful for programmers working with Unreal Engine.



The Sparse Class Data system eliminates wasted memory from redundant properties.

The Sparse Class Data system eliminates wasted memory from redundant properties.



Track memory usage in your Unreal Projects.

Track memory usage in your Unreal Projects.

Unreal Engine Architecture

Whether you are programming with C++, Blueprints, or a combination of the two, the underlying Unreal Engine architecture is the same.



Reference for Unreal Engine's Assert Functionality

Reference for Unreal Engine's Assert Functionality



Reference for creating and implementing gameplay classes.

Reference for creating and implementing gameplay classes.



Reference for creating and implementing functions for gameplay Classes

Reference for creating and implementing functions for gameplay Classes



Collections of gameplay classes belonging to a game project compiled into DLLs.

Collections of gameplay classes belonging to a game project compiled into DLLs.



Reference to creating and implementing interfaces.

Reference to creating and implementing interfaces.



Metadata keywords used when declaring UClasses, UFunctions, UProperties, UEnums, and UInterfaces to specify how they behave with various aspects of Unreal Engine and the editor

Metadata keywords used when declaring UClasses, UFunctions, UProperties, UEnums, and UInterfaces to specify how they behave with various aspects of Unreal Engine and the editor



Reference for creating and implementing properties for gameplay classes.

Reference for creating and implementing properties for gameplay classes.



Reference to creating and implementing structs for gameplay classes.

Reference to creating and implementing structs for gameplay classes.



Step-by-step instructional guides for hands-on learning of programming in Unreal Engine.

Step-by-step instructional guides for hands-on learning of programming in Unreal Engine.



A How To Guide for Referencing Actors in Unreal Engine.

A How To Guide for Referencing Actors in Unreal Engine.

Gameplay Architecture



Methods for loading and unloading assets during runtime.

Methods for loading and unloading assets during runtime.



A collection of arguments that can be passed to the engine's executable to configure options controlling how it runs.

A collection of arguments that can be passed to the engine's executable to configure options controlling how it runs.



Core Redirects enable remapping classes, enums, functions, packages, properties, and structs at load time.

Core Redirects enable remapping classes, enums, functions, packages, properties, and structs at load time.



Developers can extend this system to validate assets with custom-scripted rulesets.

Developers can extend this system to validate assets with custom-scripted rulesets.



Modules are the building blocks of Unreal Engine's software architecture. You can organize your code into modules to create more efficient and maintainable projects.

Modules are the building blocks of Unreal Engine's software architecture. You can organize your code into modules to create more efficient and maintainable projects.



Control how an asset is referenced and loaded into memory.

Control how an asset is referenced and loaded into memory.



How assets are discovered by the editor and how to make it know more about asset types before they are loaded.

How assets are discovered by the editor and how to make it know more about asset types before they are loaded.



An overview of the string classes available in Unreal with reference guides for FName, FText, and FString.

An overview of the string classes available in Unreal with reference guides for FName, FText, and FString.



An Overview of the Tasks System.

An Overview of the Tasks System.



Using customized serialization code and versioning to control how Objects are loaded from Assets and Packages.

Using customized serialization code and versioning to control how Objects are loaded from Assets and Packages.



Methods of creating new instances of Objects in gameplay code.

Methods of creating new instances of Objects in gameplay code.



Overview of the features of the UObject system.

Overview of the features of the UObject system.

Gameplay Guides

Unreal Engine API Reference



Unreal Engine C++ API Reference

System Guides



Guide to creating new nodes for use within graphs in Anim Blueprints.

Guide to creating new nodes for use within graphs in Anim Blueprints.



Overview of the automation system used for unit testing, feature testing, and content stress testing.

Overview of the automation system used for unit testing, feature testing, and content stress testing.



Technical guide for programmers working with Blueprints.

Technical guide for programmers working with Blueprints.



Learn how to use online subsystems and services in Unreal Engine, including Epic Online Services.

Learn how to use online subsystems and services in Unreal Engine, including Epic Online Services.



An overview of Online Subsystem Steam, including how to set up your project for distribution on Valve's Steam platform.

An overview of Online Subsystem Steam, including how to set up your project for distribution on Valve's Steam platform.



Information for graphics programmers working with the rendering systems and writing shaders.

Information for graphics programmers working with the rendering systems and writing shaders.



Program user interfaces with Unreal Engine's Slate framework.

Program user interfaces with Unreal Engine's Slate framework.



Reference material for Unreal Engine's build pipeline

Reference material for Unreal Engine's build pipeline

Automated Builds



Learn syntax to write BuildGraph script conditions.

Learn syntax to write BuildGraph script conditions.



Learn about BuildGraph Elements.

Learn about BuildGraph Elements.



Learn about valid data types for BuildGraph attributes.

Learn about valid data types for BuildGraph attributes.



Customize your builds with the BuildGraph scripting system.

Customize your builds with the BuildGraph scripting system.



This page provides sample BuildGraph Script usage.

This page provides sample BuildGraph Script usage.

Asset Handling Reference Guides



Methods for loading and unloading assets during runtime.

Methods for loading and unloading assets during runtime.



How assets are discovered by the editor and how to make it know more about asset types before they are loaded.

How assets are discovered by the editor and how to make it know more about asset types before they are loaded.



Developers can extend this system to validate assets with custom-scripted rulesets.

Developers can extend this system to validate assets with custom-scripted rulesets.

The UCLASS Macro

Properties And Function Types

UObject Creation

Functionality Provided by UObjects

The Unreal Header Tool

Header File Format

Updating Objects

Destroying Objects

Release 5.1 Changes

Unreal has a robust system for handling game objects. The base class for objects in Unreal is UObject. The UCLASS macro can be used to tag classes derived from UObject so that the UObject handling system is aware of them.

The UCLASS Macro

The UCLASS macro gives the UObject a reference to a UCLASS that describes its Unreal-based type. Each UCLASS maintains one Object called the Class Default Object(CDO). The CDO is essentially a default 'template' Object, generated by the class constructor and unmodified thereafter. Both the UCLASS and the CDO can be retrieved for a given Object instance, although they should generally be considered read-only. The UCLASS for an Object instance can be accessed at any time using the GetClass() function.

A UCLASS contains a set of properties and functions that define the class. These are normal C++ functions and variables available to standard C++ code, but tagged with Unreal Engine-specific metadata that controls how they behave within the Object system. For more details about the tagging syntax, refer to the Programming Reference.

A UObject class can include native-only properties that are not marked for reflection with UFUNCTION or UPROPERTY specifiers. However, only functions and properties that are marked with specifier macros will get listed within their corresponding UCLASS.

Properties And Function Types

UObjects can have member variables (known as properties) or functions of any type. However, for the Unreal Engine to recognize and manipulate those variables or functions, they must be marked with special macros and must conform to certain type standards. For details on those standards, refer to the Properties and UFunctions reference pages.

UObject Creation

UObjects do not support constructor arguments. All C++ UObjects are initialized on engine startup, and the engine calls their default constructor. If there is no default constructor, your UObject will not compile.

UObject constructors should be lightweight and only used to set up default values and subobjects, no other functionality should be called at construction time. For Actors and Actor Components, initialization functionality should be put into the BeginPlay() method instead.

UObjects should only be constructed using NewObject at runtime, or CreateDefaultSubobject for constructors.

Method

Description

NewObject<class>

Creates a new instance with optional parameters for all available creation options. Offers a wide range of flexibility, including simple use cases with an automatically generated name.

CreateDefaultSubobject<class>

Creates a component or subobject that provides a method for creating a child class and returning the parent class.

When creating a default subobject, because they are constructed at engine startup the class constructor of a UObject should only work with local data or load static assets.



UObjects should never use the new operator. All UObjects are memory managed by Unreal Engine and garbage collected. When you manually manage your memory by using new or delete, you can cause corruption to your memory.

Functionality Provided by UObjects

It is not required or even appropriate to use this system in all cases, but there are many benefits to doing so, including:

Garbage collection

Reference updating

When PendingKill is disabled by default, developers will not need to worry about reference updating, the line can be removed in that UE version.

Reflection

Serialization

Automatic updating of default property changes

Automatic property initialization

Automatic editor integration

Type information available at runtime

Network replication

Most of these benefits apply to UStructs, which have the same reflection and serialization capabilities as UObjects. UStructs are considered value types and are not garbage collected. For more detail on each of these systems, refer to the Unreal Object Handling documentation.

The Unreal Header Tool

To harness the functionality provided by UObject-derived types, a preprocessing step needs to be run on the header files for these types to collate the information it needs. This preprocessing step is performed by the UnrealHeaderTool, or UHT for short. UObject-derived types have a certain structure that needs to be adhered to.

Header File Format

While a UObject's implementation in a source (.cpp) file is just like any other C++ class, its definition in a header (.h) file must adhere to a certain basic structure in order to work properly with Unreal Engine. Using the editor's New C++ Class command is the easiest way to set up a correctly-formatted header file. A basic header file for a UObject-derived class might look like this, assuming the UObject derivative is called UMyObject and the project in which it was created is called MyProject:

The Unreal-specific parts of this are as follows:

This line is expected to be the the last #include directive in the file. If this header file needs to know about other classes, they can be forward declared anywhere in the file, or included above MyObject.generated.h.

The UCLASS macro makes UMyObject visible to Unreal Engine. The macro supports a variety of Class Specifiers that determine which features are turned on or off for the class.

Specifying MYPROJECT_API is necessary if MyProject wishes to expose the UMyObject class to other modules. This is most useful for modules or plugins that will be included by game projects and which deliberately expose classes to provide portable, self-contained functionality across multiple projects.

The GENERATED_BODY macro takes no arguments, but sets up the class to support the infrastructure required by the engine. It is required for all UCLASS and USTRUCT.

Unreal Header Tool supports a minimal set of C++. When wrapping parts of a UCLASS with custom #ifdefs macros, UHT will ignore macros that do not contain WITH_EDITOR or WITHEDITORONLY_DATA macros.

Updating Objects

Ticking refers to how Objects are updated in Unreal Engine. All Actors have the ability to be ticked each frame, providing you a way to perform any update calculations or actions that are necessary.

Actors and ActorComponents have their Tick functions called automatically when registered to do so, however, UObjects do not possess any built-in update ability. When it is necessary for your project, this can be added by inheriting from the FTickableGameObject class using the inherits class specifier. They can then implement the Tick() function, which will be called each frame by the engine.

Most in-game Objects will be Actors, which can tick at user-set minimum intervals rather than once per frame.

Destroying Objects

Object destruction is handled automatically by the garbage collection system when an Object is no longer referenced. This means that no UPROPERTY pointers, engine containers, TStrongObjectPtr, or class instances should have any strong references to them.

Note that Weak Pointers have no impact on whether an Object is garbage collected or not.

When the garbage collector runs, unreferenced Objects found are removed from memory. In addition, the function MarkPendingKill() can be called directly on an Object. This function sets all pointers to the Object to NULL and removes the Object from global searches. The Object is fully deleted on the next garbage collection pass.

Smart pointers are not intended to be used with UObjects.

Release 5.1 Changes

Object->MarkPendingKill() has been replaced with Obj->MarkAsGarbage(). This new function is now only for tracking stale objects, If gc.PendingKillEnabled=true then it will not clear references to garbage objects as it did previously.

Strong references keep UObjects alive. If you don't want these references to keep the UObject alive, then those references should convert to using weak pointers, or be a normal pointer that is manually cleared by a programmer (if performance is critical.)

You can replace Strong pointers with weak pointers and dereference them once during a gameplay operation as garbage collection only runs between frames.

IsValid() is for checking if it's null or garbage, but most usages of IsValid can be replaced with proper programming conventions like clearing pointers to Actors when they have their OnDestroy event called.

If PendingKill() is disabled, MarkGarbage()will flag to the owner of the object that it wants the object destroyed, but the object itself will not get garbage collected until all references to it are released.

In the case of Actors, even if the Actor had Destroy() called on them, and they were removed from the level, then it will not be Garbage Collected until all references to it are released.

The Main difference for licensees is that using the function MarkPendingKill() to force expensive objects to garbage collect will no longer work.

Existing checks for nullptr should be replaced with IsValid() calls if you're not clearing them manually, since pointers will no longer get automatically cleared by the garbage collector through MarkPendingKill().

NewObject

NewNamedObject

ConstructObject

Object Flags

NewObject

NewObject() is the simplest UObject factory method. It takes in an optional outer object and class and creates a new instance with an automatically generated name.

Parameter

Description

Outer

(Optional) A UObject to set as the Outer for the Object being created.

Class

(Optional) A UClass specifying the class of the Object to be created.

Return Value

A pointer to the spawned instance of the specified class.

NewNamedObject

NewNamedObject() expands on NewObject() by allowing a name for the new instance as well as Object Flags and a template object to be specified as an argument.

Parameter

Description

Outer

A UObject to set as the Outer for the Object being created.

Name

An FName to set as the Name for the new Object.

Flags

(Optional) An FObjectFlags enum value describing the new Object.

Template

(Optional) A UObject to use as a template when creating the new Object.

Return Value

A pointer to the spawned instance of the specified class.

ConstructObject

For complete flexibility, new instances of UObjects can be created using the ConstructObject() function. This function calls StaticConstructObject(), which allocates the Object, executes the ClassConstructor, and performs any initialization such as loading config properties, loading localized properties, and instancing components.

Parameter

Description

Class

A UClass specifying the class of the Object to be created.

Outer

(Optional) A UObject to set as the Outer for the Object being created.

Name

(Optional) An FName to set as the Name for the new Object.

SetFlags

(Optional) An EObjectFlags enum value describing the new Object.

Template

(Optional) A UObject to use as a template when creating the new Object.

bCopyTransientsFromClassDefaults

(Optional) A bool that determines whether to copy transient properties from the class default object instead of the passed-in archetype pointer. If true, the class default object's transients are used.

FObjectInstancingGraph

(Optional) An FObjectInstancingGraph struct that contains the mappings of instanced objects and components to their templates. Used when for instancing components owned by the new Object.

Return Value

A pointer to the spawned instance of the specified class.

Object Flags

The EObjectFlags enumeration is used to quickly and succinctly describe an Object. There are various flags to describe the type of Object, how it is handled by garbage collection, the stage the Object is at in its lifetime, etc. There are also special all or none masks and predefined groups of flags.

Flag

Value

Description

Object Type

RF_Public

0x00000001

The Object is visible outside of the package it is contained within.

RF_Standalone

0x00000002

The Object is kept around for editing even if is not referenced by anything.

RF_Native

0x00000004

The Objectis native. This is only used for UClass objects.

RF_Transactional

0x00000008

The Object is transactional.

RF_ClassDefaultObject

0x00000010

The Object is the default object for its class, i.e. the default template that new instances of that class use when being created.

RF_ArchetypeObject

0x00000020

The Object is a template for another object. It is treated like a class default object.

RF_Transient

0x00000040

The Object is not saved to disk.

Garbage Collection

RF_RootSet

0x00000080

The Object is not garbage collected even if it is not referenced by anything.

RF_IsLazyReferenced

0x00000100

The Object is referenced by a lazy pointer and requires additional cleanup upon deletion.

RF_Unreachable

0x00000200

The Object is not reachable on the object graph.

RF_TagGarbageTemp

0x00000400

The Object is marked for use by various utilities that use garbage collection. This flag is not interpreted by the garbage collector itself.

Object Lifetime

RF_NeedLoad

0x00000800

The Object needs loading.

RF_AsyncLoading

0x00001000

The Object is being loaded asynchronously.

RF_NeedPostLoad

0x00002000

The Object needs to be post-loaded.

RF_NeedPostLoadSubobjects

0x00004000

The Object still needs to instance sub-objects and fix up serialized component references

RF_PendingKill

0x00008000

The Object is pending destruction. Marks the Object as being invalid for gameplay purposes, but still a valid Object.

RF_BeginDestroyed

0x00010000

The Object has had BeginDestroy() called on it.

RF_FinishDestroyed

0x00020000

The Object has had FinishDestroy() called on it.

Special Masks

RF_AllFlags

0x0003ffff

The Object has all flags. Used mainly for error checking.

RF_NoFlags

0x00000000

The Object has no flags. Used to avoid a cast.

Predefined Groups

RF_Load

RF_Public | RF_Standalone | RF_Native | RF_Transactional | RF_ClassDefaultObject | RF_ArchetypeObject

Flags loaded from Unreal files.

RF_PropagateToSubobjects

RF_Public | RF_ArchetypeObject | RF_Transactional

Flags inherited by sub-objects from their super-objects.

Networking and Multiplayer

Properties

TArray: Arrays in Unreal Engine

Automatic Property Initialization

Automatic Updating of References

Serialization

Updating of Property Values

Editor Integration

Run-Time Type Information and Casting

Garbage Collection

Network Replication

Marking classes, properties, and functions with the appropriate macros turns them into UClasses, UProperties, and UFunctions. This gives Unreal Engine access to them, which allows for a number of under-the-hood handling features to be implemented.

Automatic Property Initialization

UObjects are automatically zeroed on initialization, before the constructor is called. This happens for the whole class, UProperties and native members alike. Members can subsequently be initialized with custom values in the class constructor.

Automatic Updating of References

When an AActor or UActorComponent is destroyed or otherwise removed from play, all references to it that are visible to the reflection system (UProperty pointers and pointers stored in Unreal Engine container classes such as TArray) are automatically nulled. This is beneficial in that it prevents dangling pointers from persisting and causing trouble down the road, but it also means that AActor and UActorComponent pointers can become null if some other piece of code destroys them. The ultimate advantage of this is that null-checking is more reliable, as it detects both standard-case null pointers and cases where a non-null pointer would have been pointing at deleted memory.

It is important to realize that this feature applies only to UActorComponent or AActor references marked with UPROPERTY or stored in an Unreal Engine container class. An Object reference stored in a raw pointer will be unknown to the Unreal Engine, and will not be automatically nulled, nor will it prevent garbage collection. Note this does not mean that all UObject* variables must be UProperties. If you want an Object pointer that is not a UProperty, consider using TWeakObjectPtr. This is a "weak" pointer, meaning it will not prevent garbage collection, but it can be queried for validity before being accessed and will be set to null if the Object it points to is destroyed.

Another case where a referenced UObject UProperty will be automatically null'ed is when using 'Force Delete' on an asset in the editor. As a result, all code operating on UObjects which are assets must handle these pointers becoming null.

Serialization

When a UObject is serialized, all UProperty values are automatically written or read unless explicitly marked as "transient" or unchanged from the post-constructor default value. For example, you could place an AEnemy instance in a level, set its Health to 500, save it and successfully reload it without writing a single line of code beyond the UClass definition.

When UProperties are added or removed, loading pre-existing content is handled seamlessly. New properties get default values copied from the new CDO. Removed properties are silently ignored.

If custom behavior is required, the UObject::Serialize function can be overridden. This can be useful to detect data errors, check version numbers, or perform automatic conversions or updates if the data format has changed.

Updating of Property Values

When the Class Default Object (or CDO) of a UClass has changed, the engine will try to apply those changes to all instances of the class when they are loaded. For a given Object instance, if the updated variable's value matches the value in the old CDO, it will be updated to the value it holds in the new CDO. If the variable has any other value, the assumption is that the value was set intentionally, and those changes will be preserved.

As an example, let us say you saved a level with several of your AEnemy Objects placed in it, and you had set the default Health value in the AEnemy constructor to 100. Let us also assume you set the health for Enemy_3 to 500, because they are particularly tough. Now imagine you changed your mind and increased the default value of Health to 150. When you next load your level, Unreal will realize you have changed the CDO and will update all instances of AEnemy with the old default Health value (100) to have a Health value of 150. Enemy_3's Health will remain at 500 because it wasn't using the old default value.

Editor Integration

UObjects and UProperties are understood by the Editor, and the Editor can expose these values automatically for editing without the need to write special code. This can optionally include integration into the Blueprint visual scripting system. There are many options to control the accessibility and exposure of variables and functions.

Run-Time Type Information and Casting

Because UObjects are part of the Unreal Engine's reflection system, they always know what UClass they are, and type-related decisions and casts can be made at runtime.

In native code, every UObject class has a custom Super typedef set to its parent class, which allows easy control of overriding behavior. As an example:

As you can see, calling Speak will result in the MegaBoss saying "Powering up! Time to fight!".

Also, you can safely cast an Object from a base class to a more derived class using the templated Cast function, or query if an Object is of a particular class using IsA. A quick example follows:

Here we have used Cast to attempt to cast the AEnemy to an AMegaBoss. If the Object in question is not actually an AMegaBoss (or a child class thereof), the cast will return a null pointer and we can react appropriately. In the code above, the Incinerate function will only be called against the MegaBoss.

Garbage Collection

Unreal implements a garbage collection scheme whereby UObjects that are no longer referenced or have been explicitly flagged for destruction will be cleaned up at regular intervals. The engine builds a reference graph to determine which UObjects are still in use and which ones are orphaned. At the root of this graph is a set of UObjects designated as the "root set". Any UObject can be added to the root set. When garbage collection occurs, the engine can track all referenced UObjects by searching the tree of known UObject references, starting from the root set. Any unreferenced UObjects, meaning those which are not found in the tree search, will be assumed to be unneeded, and will be removed.

One practical implication here is that you typically need to maintain a UPROPERTY reference to any Object you wish to keep alive, or store a pointer to it in a TArray or other Unreal Engine container class. Actors and their Components are frequently an exception to this, since the Actors are usually referenced by an Object that links back to the root set, such as the Level to which they belong, and the Actor's Components are referenced by the Actor itself. Actors can be explicitly marked for destruction by calling their Destroy function, which is the standard way to remove an Actor from an in-progress game. Components can be destroyed explicitly with the DestroyComponent function, but they are usually destroyed when their owning Actor is removed from the game.

Garbage collection in Unreal Engine 4 is fast and efficient, and has a number of built-in features designed to minimize overhead, such as multithreaded reachability analysis to identify orphaned Objects, and unhashing code optimized to remove Actors from containers as quickly as possible. There are other features that can be adjusted to gain more precise control over how and when garbage collection is performed, most of which are found in Project Settings under Engine - Garbage Collection. The following settings are commonly used to tune garbage collector performance for a project:

Setting(s)

Feature Description

Create Garbage Collector UObject Clusters

This can be turned on or off (it is on by default) in the project's settings. If turned on, related Objects will be grouped together in a garbage collection cluster, so that only the cluster itself needs to be checked, rather than each individual Object. This means that reachability is performed faster because an entire cluster can be treated as one object, but it also means that individual items in that cluster will all be unhashed and prepared for deletion in the same frame, potentially causing a hitch if the cluster is large enough. In the general case, cluster creation improves garbage collection performance and decreases time spent in reachability analysis.

Merge GC Clusters

Cluster merging can be enabled to cause clusters to join together when an object from one cluster references an object in another. Note that clearing the reference that caused the merge will not cause the newly-merged cluster to dissolve or break up in any way. Create Garbage Collector UObject Clusters must also be turned on for this feature to work. This will lead to the garbage collector unhashing and destroying objects less frequently, but larger numbers of objects will be unhashed and destroyed at once. In addition, there may be some cases where garbage collection will not happen with merged clusters when it would have happened without them, since any reference to any object in the cluster will keep the entire cluster from being garbage-collected.

Actor Clustering Enabled

Actors can be put into clusters by turning on this option in Project Settings, and by either setting the bCanBeInCluster variable to true, or overriding the CanBeInCluster function in code so that it returns true. By default, Actors and Components have this turned off, except for Static Mesh Actors and Reflection Capture Components. This feature is useful for grouping Actors that are expected to be destroyed all at once, usually static meshes placed in a level that cannot be destroyed except by unloading the sublevel that contains them.

Blueprint Clustering Enabled

A Blueprint's UBlueprintGeneratedClass and related data, such as the shared UPROPERTY and UFUNCTION data, can be clustered by turning this setting on. It is important to recognize that this clustering refers to the Blueprint Generated Class itself, not individual instances of the Blueprint.

Time Between Purging Pending Kill Objects

The frequency of garbage collection activity can be adjusted in the project's settings. This high-level control is especially useful in preventing hitches. By shortening the time between collections, you decrease the likely amount of unreachable objects that will be discovered on the next reachability analysis pass, and can avoid the hitches that can happen when a lot of Actors are cleaned up at the same time.



The Garbage Collection settings within Project Settings.



Network Replication

The UObject system includes a robust set of functionality to facilitate network communication and multiplayer games.

UProperties can be tagged to tell the Engine to replicate their data during network play. A common model here is that a variable gets changed on the server, and the Engine then detects this change and sends it reliably to all clients. Clients can optionally receive a callback function when the variable changes from replication.

UFunctions can also be tagged to execute on a remote machine. A "server" function, for example, when called on a client machine, will cause the function to execute on the server machine for the server's version of the Actor. A "client" function, on the other hand, can be called from the server and will run on the owning client's version of that Actor.

TSubclassOf is a template class that provides UClass type safety. For instance, let's imagine that you are creating a projectile class that allows the designer to specify the damage type. You could just create a UPROPERTY of type UClass and hope the designer always assigns a class derived from UDamageType or you could use the TSubclassOf template to enforce the choice. The sample code below illustrates the difference:

Vs.

In the second declaration, the template class tells the editor's property windows to list only classes derived from UDamageType as choices for the property. In the first declaration any UClass can be chosen. The image below illustrates this.



Example from StrategyGame's projectile Blueprint

In addition to this UPROPERTY safety, you get type safety at the C++ level too. If you try to assign incompatible TSubclassOf types to each other you'll get a compilation error. In the case you are trying to assign a generic UClass, it will perform a runtime check to verify that it can do the assignment. If the runtime check fails, the resulting value is nullptr.

Objects

Smart Pointer Types

Benefits of Smart Pointers

Helper Classes and Functions

Smart Pointer Implementation Details

Speed

Intrusive Accessors

Casting

Thread Safety

Tips and Limitations

The Unreal Smart Pointer Library is a custom implementation of C++11 smart pointers designed to ease the burden of memory allocation and tracking. This implementation includes the industry standard Shared Pointers, Weak Pointers, and Unique Pointers. It also adds Shared References which act like non-nullable Shared Pointers. These classes cannot be used with the UObject system because Unreal Objects use a separate memory-tracking system that is better-tuned for game code.

Smart Pointer Types

Smart Pointers can affect the lifespan of the object they contain or reference. Different Smart Pointers have different limitations and effects on the object. The following table can be used to help determine when it is appropriate to use each type of Smart Pointer:

Smart Pointer Type

Use Case

Shared Pointers (TSharedPtr)

A Shared Pointer owns the object it references, indefinitely preventing deletion of that object, and ultimately handling its deletion when no Shared Pointer or Shared Reference (see below) references it. A Shared Pointer can be empty, meaning it doesn't reference any object. Any non-null Shared Pointer can produce a Shared Reference to the object it references.

Shared References (TSharedRef)

A Shared Reference acts like a Shared Pointer, in the sense that it owns the object it references. They differ with regard to null objects; Shared References must always reference a non-null object. Because Shared Pointers don't have that restriction, a Shared Reference can always be converted to a Shared Pointer, and that Shared Pointer is guaranteed to reference a valid object. Use Shared References when you want a guarantee that the referenced object is non-null, or if you want to indicate shared object ownership.

Weak Pointers (TWeakPtr)

Weak Pointers are similar to Shared Pointers, but do not own the object they reference, and therefore do not affect its lifecycle. This property can be very useful, as it breaks reference cycles, but it also means that a Weak Pointer can become null at any time, without warning. For this reason, a Weak Pointer can produce a Shared Pointer to the object it references, ensuring programmers safe access to the object on a temporary basis.

Unique Pointers (TUniquePtr)

A Unique Pointer solely and explicitly owns the object it references. Since there can only be one Unique Pointer to a given resource, Unique Pointers can transfer ownership, but cannot share it. Any attempts to copy a Unique Pointer will result in a compile error. When a Unique Pointer goes out of scope, it will automatically delete the object it references.

Making a Shared Pointer or Shared Reference to an object that a Unique Pointer references is dangerous. This will not suspend the Unique Pointer's behavior of deleting the object upon its own destruction, even though other Smart Pointers still reference it. Similarly, you should not make a Unique Pointer to an object that is referenced by a Shared Pointer or Shared Reference.

Benefits of Smart Pointers

Benefit

Description

Prevents memory leaks

Smart Pointers (other than Weak Pointers) automatically delete objects when there are no more shared references.

Weak referencing

Weak Pointers break reference cycles and prevent dangling pointers.

Optional Thread safety

The Unreal Smart Pointer Library includes thread-safe code that manages reference counting across multiple threads. Thread safety can be traded out for better performance if it isn't needed.

Runtime safety

Shared References are never null and can always be dereferenced.

Confers intent

You can easily tell an object owner from an observer.

Memory

Smart Pointers are only twice the size of a C++ pointer in 64-bit (plus a shared 16-byte reference controller). The exception to this is Unique Pointers, which are the same size as C++ pointers.

Helper Classes and Functions

The Unreal Smart Pointer Library provides several helper classes and functions to make using Smart Pointers easier and more intuitive.

Helper

Description

Classes

TSharedFromThis

Deriving your class from TSharedFromThis adds the AsShared or SharedThis functions. These functions enable you to acquire a TSharedRef to your object.

Functions

MakeShared and MakeShareable

Creates a Shared Pointer from a regular C++ pointer. MakeShared allocates a new object instance and the reference controller in a single memory block, but requires the object to offer a public constructor. MakeShareable is less efficient, but works even if the object's constructor is private, enables you to take ownership of an object you didn't create, and supports customized behavior when deleting the object.

StaticCastSharedRef and StaticCastSharedPtr

Static cast utility function, typically used to downcast to a derived type.

ConstCastSharedRef and ConstCastSharedPtr

Converts a const Smart Reference or Smart Pointer to a mutable Smart Reference or Smart Pointer, respectively.

Smart Pointer Implementation Details

Smart Pointers in the Unreal Smart Pointer Library all share some general characteristics in terms of functionality and efficiency.

Speed

Always keep performance in mind when considering using Smart Pointers. Smart Pointers are well-suited for certain high-level systems, resource management, or tools programming. However, some Smart Pointer types are slower than raw C++ pointers, and this overhead makes them less useful in low-level engine code, such as rendering.

Some of the general performance benefits of Smart Pointers are:

All operations are constant time.

Dereferencing most Smart Pointers is just as fast as raw C++ pointers (in shipping builds).

Copying Smart Pointers never allocates memory.

Thread-safe Smart Pointers are lockless.

Performance drawbacks of Smart Pointers include:

Creating and copying Smart Pointers involves more overhead than creating and copying raw C++ pointers.

Maintaining reference counts adds cycles to basic operations.

Some Smart Pointers use more memory than raw C++ pointers.

There are two heap allocations for reference controllers. Using MakeShared instead of MakeShareable avoids the second allocation, and can improve performance.

Intrusive Accessors

Shared pointers are non-intrusive, which means the object does not know whether or not a Smart Pointer owns it. This is usually acceptable, but there may be cases in which you want to access the object as a Shared Reference or Shared Pointer. To do this, derive the object's class from TSharedFromThis, using the object's class as the template parameter. TSharedFromThis provides two functions, AsShared and SharedThis, that can convert the object to a Shared Reference (and from there, to a Shared Pointer). This can be useful with class factories that always return Shared References, or when you need to pass your object to a system that expects a Shared Reference or Shared Pointer. AsShared will return your class as the type originally passed as the template argument to TSharedFromThis, which may be a parent type to the calling object, while SharedThis will derive the type directly from this and return a Smart Pointer referencing an object of that type. The following example code demonstrates both functions:

Do not call AsShared or SharedThis from constructors, since the shared reference is not initialized at that time and will cause a crash or assert.

Casting

You can cast Shared Pointers (and Shared References) through several support functions included in the Unreal Smart Pointer Library. Up-casting is implicit, as with C++ pointers. You can const cast with the ConstCastSharedPtr function, and static cast (often to downcast to derived class pointers) with StaticCastSharedPtr. Dynamic casting is not supported, as there is no run-type type information (RTTI); static casting should be used instead, as in the following code:

Thread Safety

By default, Smart Pointers are only safe to access on a single thread. If you need multiple threads to have access, use the thread-safe versions of Smart Pointer classes:

TSharedPtr<T, ESPMode::ThreadSafe>

TSharedRef<T, ESPMode::ThreadSafe>

TWeakPtr<T, ESPMode::ThreadSafe>

TSharedFromThis<T, ESPMode::ThreadSafe>

These thread-safe versions are a bit slower than the defaults due to atomic reference counting, but their behavior is consistent with regular C++ pointers:

Reads and copies are always thread-safe.

Writes and resets must be synchronized to be safe.

If you know your pointer will never be accessed by more than one thread, you can get better performance by avoiding the thread-safe versions.

Tips and Limitations

Avoid passing data to functions as TSharedRef or TSharedPtr parameters where possible, as these will incur overhead by dereferencing and reference-counting. Instead, pass the referenced object, preferably as a const &.

You can forward-declare Shared Pointers to incomplete types.

Shared Pointers are not compatible with Unreal objects (UObject and its derived classes). The Engine has a separate memory management system (see Object Handling documentation) for UObject management, and the two systems have no overlap with each other.

Declaration and Initialization

Converting Between Shared Pointers and Shared References

Comparison

Dereferencing and Accessing

Custom Deleters

Shared Pointers are Smart Pointers that are both strong and nullable. Shared pointers inherently include all the benefits of basic Smart Pointers in that they prevent memory leaks, dangling pointers, and pointers to uninitialized memory, but they also provide additional features, such as:

Shared Ownership: Reference counting enables multiple Shared Pointers to ensure that the data object they reference will never be deleted as long as any of them still points to it.

Automatic Invalidation: Volatile objects can be safely referenced without worrying about dangling pointers.

Weak References: Weak Pointers can break reference cycles.

Indication of Intent: Distinguishes owners (see Shared References) from observers and provides non-nullable references.

Shared pointers have some basic characteristics worth noting, including:

Very robust syntax

Non-intrusive (but reflection is possible)

Thread-safe (conditionally)

Good performance, light on memory

Shared Pointers are similar to Shared References, the main distinction being that Shared References are not nullable and therefore always reference valid objects. When choosing between Shared References and Shared Pointers, Shared References are the preferred option unless you need an empty or nullable object.

Declaration and Initialization

Because Shared Pointers are nullable, you can initialize them with or without a data object. Here are some examples of creating new shared pointers:

In the second example, NodePtr effectively owns the new FMyObjectType object, since no other Shared Pointer references that object. If NodePtr goes out of scope without another Shared Pointer or Shared Reference pointing to the object, the object will be destroyed.

When you copy a Shared Pointer, the system adds one reference to the object that it references.

The object will persist until no more Shared Pointers (or Shared References) reference it.

You can reset a Shared Pointer with the Reset function, or by assigning a null pointer to them, as follows:

You can transfer the contents of one Shared Pointer to another, leaving the original Shared Pointer empty, with the MoveTemp (or MoveTempIfPossible) function:

MoveTemp and MoveTempIfPossible differ only in that MoveTemp includes static asserts to enforce that it can only execute on a non-const left-value (lvalue).

Converting Between Shared Pointers and Shared References

Converting between Shared Pointers and Shared References is a common practice. Shared References implicitly convert to Shared Pointers, and provide the additional guarantee that the new Shared Pointer will reference a valid object. Conversion is handled by the normal syntax:

You can create a Shared Reference from a Shared Pointer with the Shared Pointer function, ToSharedRef, as long as the Shared Pointer references a non-null object. Attempting to create a Shared Reference from a null Shared Pointer will cause the program to assert.

Comparison

You can test Shared Pointers against each other for equality. In this context, equality is defined as both Shared Pointers referencing the same object.

The IsValid function and the bool operator will establish whether or not the Shared Pointer references a valid object. You can also call Get and see if it returns a valid (non-null) object pointer.

Dereferencing and Accessing

You can dereference, call methods, and access members in the same way you would with regular C++ pointers. You should also perform null-checking as you would for any C++ pointer, by calling the IsValid function or using the overloaded bool operator, before dereferencing it.

Custom Deleters

Shared Pointers and Shared References support custom deleters for the objects they reference. To run custom deletion code, provide the lambda function you wish to run as a parameter when creating your Smart Pointer, like this:

Declaration and Initialization

Converting Between Shared Pointers and Shared References

Comparison

A Shared Reference is a strong, non-nullable Smart Pointer for data objects outside of the Engine's UObject system. This means you cannot reset a Shared Reference, assign a null object to it, or create an empty one. Because of this, Shared References always contain a valid object, and do not even have an IsValid method. When choosing between Shared References and Shared Pointers, Shared References are the preferred option unless you need an empty or nullable object. If you need potentially-empty or nullable references, you should use Shared Pointers instead.

Unlike a standard C++ reference, a Shared Reference can be reassigned to another object after creation.

Declaration and Initialization

Shared References are non-nullable, so initialization requires a data object. Attempting to create a Shared Reference without a valid object will not compile, and attempting to initialize a Shared Reference to a null pointer variable.

Attempting to create a Shared Reference without a valid object will not compile:

Converting Between Shared Pointers and Shared References

Converting between Shared Pointers and Shared References is a common practice. Shared References implicitly convert to Shared Pointers, and provide the additional guarantee that the new Shared Pointer will reference a valid object. Conversion is handled by the normal syntax:

You can create a Shared Reference from a Shared Pointer with the Shared Pointer function, ToSharedRef, as long as the Shared Pointer references a non-null object. Attempting to create a Shared Reference from a null Shared Pointer will cause the program to assert.

Comparison

You can test Shared References against each other for equality. In this context, equality means referencing the same object.

Declaration, Initialization, and Assignment

Converting To Shared Pointers

Dereferencing and Accessing

Breaking Reference Cycles

Usage Warnings

Weak Pointers store a weak reference to an object. Unlike Shared Pointers or Shared References, a Weak Pointer will not prevent destruction of the object it references.

Before accessing the object that a Weak Pointer references, you should use the Pin function to produce a Shared Pointer. This guarantees that the object will continue to exist while you are using it. If you only need to establish whether or not the Weak Pointer references an object, you can compare it to nullptr or call IsValid on it.

Using Weak Pointers can help confer intent — a Weak Pointer indicates an observation of the referenced object without ownership of it, and does not control its lifetime.

Declaration, Initialization, and Assignment

You can create empty Weak Pointers, or build them from Shared References, Shared Pointers, or other Weak Pointers.

Weak Pointers do not prevent objects from being destroyed. In our example, resetting ObjectOwner will destroy the object, regardless of whether or not ObjectObserver is still in scope:

Weak Pointers can be copied around safely, just like Shared Pointers, regardless of whether or not they reference a valid object:

You can reset a Weak Pointer when you are done with it:

Converting To Shared Pointers

The Pin function creates a Shared Pointer to the Weak Pointer's object. As long as the Shared Pointer is in scope and references the object, the object will remain valid. In addition, Shared Pointers (including the one returned by the Pin function) can evaluate as type bool in conditionals, where true indicates a valid object. The following code pattern checks to see if the Weak Pointer references a valid object, and if so, guarantees that it will continue to be valid at least until the Shared Pointer (created by the Pin function) goes out of scope or is explicitly cleared.

Dereferencing and Accessing

To access a Weak Pointer's object, first promote it to a Shared Pointer with the Pin function. You can then access it through the Get function on either the Shared Pointer or the Weak Pointer. This method ensures that the object remains valid while you are working with it.

Breaking Reference Cycles

A reference cycle exists whenever two or more objects use Smart Pointers to keep strong references to each other. In these situations, the objects protect each other from deletion, as each one is always being referenced by one other object, and so neither can be deleted while the other still exists. If no outside object references either of the objects in the reference cycle, they will effectively leak. Weak Pointers can break these reference cycles, because Weak Pointers do not preserve the objects they reference. Use Weak Pointers when you want to reference objects without claiming ownership over them and potentially extending their lifespans.

Usage Warnings

Weak Pointers are useful in cases where you don't want to guarantee that the data object will continue to exist, but this very property can be dangerous. The following situations require caution when using Weak Pointers:

Usage as keys in Sets or Maps. Because Weak Pointers can become invalid at any time, and will not notify the container, Shared Pointers or Shared References are better-suited to act as keys. Weak Pointers are safe to use as values.

Although Weak Pointers provide an IsValid function, checking IsValid does not guarantee that the object will remain valid for any length of time. This is especially true with thread-safe Shared Pointers, as they can become invalid at any time due to activity on another thread. The Pin function is the preferred method for any check that will lead to dereferencing or accessing the stored object, as the Shared Pointer that Pin returns will keep the object alive until your code clears it, or it goes out of scope.

TArray

Creating and Filling an Array

Iteration

Sorting

Queries

Removal

Operators

Heap

Slack

Raw Memory

Miscellaneous

The simplest container class in Unreal Engine is TArray. TArray is responsible for the ownership and organization of a sequence of other objects (called "elements") of the same type. As a TArray is a sequence, its elements have a well-defined order and its functions are used to deterministically manipulate those objects and their order.

TArray

TArray is the most common container class within Unreal Engine. It is fast, memory efficient, and safe. TArray types are defined by two properties: Element type, and an optional allocator.

The element type is the type of the objects that will be stored in the array. TArray is what is called a homogenous container, meaning that all of its elements are strictly the same type; you cannot store elements of different types in a single TArray.

The allocator is quite frequently omitted and will default to one which is appropriate for most use cases. It defines how the objects are laid out in memory and how the array should grow to accommodate more elements. There are a number of different allocators you can use if you decide that the default behavior is not for you, or you can write your own. More on this later.

TArray is a value type, meaning that it should be treated similarly as any other built-in type, like int32 or float. It is not designed to be extended, and creating or destroying TArray instances with new and delete is not a recommended practice. The elements are also value types, and the array owns them. Destruction of a TArray will result in the destruction of any elements it still contains. Creating a TArray variable from another will copy its elements into the new variable; there is no shared state.

Creating and Filling an Array

To create an array, define it like this:

This creates an empty array designed to hold a sequence of integers. The element type can be any value type that is copyable and destructible according to normal C++ value rules, like int32, FString, TSharedPtr, and so on. No allocator has been specified, so the TArray will use the default, heap-based allocator. At this point, no memory has been allocated.

TArrays can be populated in several ways. One way is with the Init function, which will fill an array with a number of copies of an element:

Add and Emplace functions can create new elements at the end of the array:

The array's allocator provides memory as needed when new elements are added to the array. The default allocator adds enough memory for multiple new elements whenever the current array size is exceeded. Add and Emplace do much the same thing but with a subtle difference:

Add (or Push) will copy (or move) an instance of the element type into the array.

Emplace will use the arguments you give it to construct a new instance of the element type.

In the case of our TArray<FString>, Add will create a temporary FString from the string literal and then move the contents of that temporary FString into a new FString inside the container, whereas Emplace will just create the new FString directly using the string literal. The end result is the same, but Emplace avoids creating a temporary variable, which is often undesirable for non-trivial value types like FString.

In general, Emplace is preferable to Add, in that it avoids creating unnecessary temporary variables at the call site which are then copied or moved into the container. As a rule of thumb, use Add for trivial types and Emplace otherwise. Emplace will never be less efficient than Add, but Add may read better.

Append adds multiple elements at once from either another TArray, or a pointer to a regular C array and the size of that array:

AddUnique only adds a new element to the container if an equivalent element doesn't already exist. Equivalence is checked by using the element type's operator==:

Insert, like Add, Emplace and Append, adds a single element or a copy of an array of elements at a given index:

The SetNum function can directly set the number of array elements, with new elements being created using the element type's default constructor if the new number is greater than the current one:

SetNum will also remove elements if the new number is less than the current one. More detailed information on element removal will come later:

Iteration

There are several ways to iterate over the elements of your array, but the recommended way is to use the C++ ranged-for feature:

Regular index-based iteration is also possible, of course:

Finally, arrays also have their own iterator type for more control over your iteration. There are two functions called CreateIterator and CreateConstIterator which can be used for read-write or read-only access to the elements respectively:

Sorting

Arrays can be sorted simply by calling the Sort function:

Here, the values are sorted by means of the element type's operator<. In FString's case, this is a case-insensitive lexicographical comparison. A binary predicate can also be implemented to provide different ordering semantics, like this:

Now the strings are sorted by their lengths. Note how the three strings with the same length - "Hello", "Brave" and "World" - have changed order relative to their positions in the array beforehand. This is because Sort is unstable and the relative order of equivalent elements (those strings are equivalent here because the predicate only compares length) is not guaranteed. Sort is implemented as a quicksort.

The HeapSort function, with or without a binary predicate, can be used to perform a heap sort. Whether or not you choose to use it depends on your particular data and how efficiently it sorts compared to the Sort function. Like Sort, HeapSort is not stable. If we had used HeapSort instead of Sort above, this would be the result (the same, in this case):

Finally, StableSort can be used to guarantee the relative order of equivalent elements after sorting. If we had called StableSort instead of Sort or HeapSort above, the result would have been as follows:

That is, "Brave", "Hello" and "World" remain in their same relative order after previously having been lexicographically sorted. StableSort is implemented as a merge sort.

Queries

We can ask the array how many elements it holds by using the Num function:

If you need direct access to the array memory, perhaps for interoperability with a C-style API, you can use the GetData function to return a pointer to the elements in the array. This pointer is only valid as long as the array exists and before any mutating operations are made to the array. Only the first Num indices from the StrPtr are dereferenceable:

If the container is const, then the returned pointer will also be const.

You can also ask the container how big the elements are:

To retrieve elements, you can use the indexing operator[] and pass it a zero-based index to the element you want:

Passing an invalid index — less than 0 or greater than or equal to Num() — will cause a runtime error. You can ask the container if a particular index is valid using the IsValidIndex function:

operator[] returns a reference, so it can also be used to mutate the elements inside the array, assuming your array isn't const:

Like the GetData function, operator[] will return a const reference if the array is const. You can also index from the end of the array backward by using the Last function. The index defaults to zero. The Top function is a synonym for Last, except it doesn't take an index:

We can ask the array if it contains a certain element:

Or ask the array if it contains an element which matches a specific predicate:

We can find elements by using the Find family of functions. To check if an element exists and return its index, we use Find:

This sets Index to be the index of the first element found. If there are duplicate elements and we instead want to find the index of last element, we use the FindLast function instead:

Both of these functions return a bool to indicate whether or not an element was found, while also writing the index of that element into a variable when it was found.

Find and FindLast can also return an element index directly. They will do this if you do not pass the index as an explicit argument. This can be more succinct than the above function, and which function you use depends on what suits your particular need or style.

If no element was found, the special INDEX_NONE value is returned:

IndexOfByKey works similarly, but allows comparison of the elements with an arbitrary object. With the Find functions, the argument is actually converted to the element type (FString in this case) before the search begins. With IndexOfByKey, the key is compared directly, supporting searches even when the key type isn't directly convertible to the element type.

IndexOfByKey works for any key type for which operator==(ElementType, KeyType) exists. IndexOfByKey will return the index of the first found element, or INDEX_NONE if no element was found:

The IndexOfByPredicate function finds the index of the first element that matches the specified predicate, again returning the special INDEX_NONE value if none was found:

Instead of returning indices, we can return pointers back to the elements we find. FindByKey works like IndexOfByKey, comparing the elements to an arbitrary object, but returning a pointer to the element it finds. If it does not find an element, it will return nullptr:

FindByPredicate can be used like IndexOfByPredicate, except that it returns pointer instead of an index:

Finally, you can retrieve an array of elements matching a particular predicate with the FilterByPredicate function:

Removal

You can erase elements from the array using the Remove family of functions. The Remove function removes all elements that are considered equal to the element you provide, according to the element type's operator== function. For example:

You can also use RemoveSingle to erase the first matching element in the array. This is useful if you know your array may contain duplicates and you only want to erase one, or as an optimization if you know that your array can only ever contain one matching element:

We can also remove elements by their zero-based index by using the RemoveAt function. You may wish to use IsValidIndex to verify that the array has an element with the index you plan to provide, as passing an invalid index to this function will cause a runtime error.:

We can also remove elements which match a predicate by using the RemoveAll function. For example, removing all values which are a multiple of 3:

In all of these cases, when elements were removed, the elements that followed were shuffled down into lower indices, as there can never be holes left in the array.

The shuffling process has an overhead. If you don't really care what order the remaining elements are left in, this overhead can be reduced by using the RemoveSwap, RemoveAtSwap and RemoveAllSwap functions, which work like their non-swapping variants except that they don't guarantee the order of the remaining elements, enabling them to complete their tasks more quickly:

Finally, the Empty function will remove everything from the array:

Operators

Arrays are regular value types and as such can be copied by the standard copy constructor or assignment operator. As arrays strictly own their elements, copying an array is deep and so the new array will have its own copy of the elements:

As an alternative to the Append function, you can concatenate arrays with operator+=:

TArray also supports move semantics, which can be invoked using the MoveTemp function. After a move, the source array is guaranteed to be left empty:

Arrays can be compared using the operator== and operator!=. The order of the elements are important — two arrays are only equal if they have the same number of elements in the same order. Elements are compared using their own operator==:

Heap

TArray has functions that support a binary heap data structure. A heap is a type of binary tree in which any parent node is equivalent to or ordered before all of its child nodes. When implemented as an array, the root node of the tree is at element 0 and the indices of the left and right child nodes of a node at index N are 2N+1 and 2N+2 respectively. The children are not in any particular order with respect to one another.

Any existing array can be turned into a heap by calling the Heapify function. This is overloaded to take a predicate or not, where the non-predicated version will use the element type's operator< to determine ordering:

This is a visualization of the tree:



The nodes in the tree can be read from left-to-right, top-to-bottom as the order of the elements in the heapified array. Note that the array isn't necessarily sorted after being transformed into a heap. While a sorted array would also be a valid heap, the heap structure definition is loose enough to allow multiple valid heaps for the same set of elements.

New elements can be added to the heap via the HeapPush function, reordering other nodes to maintain the heap:



The HeapPop and HeapPopDiscard functions are used to remove the top node from the heap. The difference between the two is that the former takes a reference to an element type to return a copy of the top element, and the latter simply removes the top node without returning it in any way. Both functions result in the same change to the array, and the heap is again maintained by reordering other elements appropriately:



HeapRemoveAt will remove an element from the array at a given index, and then reorder elements to maintain the heap:



HeapPush, HeapPop, HeapPopDiscard and HeapRemoveAt should only be called when the structure is already a valid heap, such as after a Heapify

Each of these functions, including Heapify, can take an optional binary predicate to determine the order of the node elements in the heap. By default, heap operations use the element type's operator< to determine order. When using a custom predicate, it is important to use the same predicate on all heap operations.

Finally, the top node of the heap can be inspected using HeapTop, without changing the array:

Slack

Because arrays can resize, they use a variable amount of memory. To avoid reallocation every time elements are added, allocators usually provide more memory than was requested so that future Add calls don't pay a performance penalty for reallocation. Likewise, removing elements doesn't usually free memory. This leaves the array with slack elements, which are effectively pre-allocated element storage slots that are not currently in use. The amount of slack in an array is defined as the difference between the number of elements stored in the array and the number of elements that the array could store with the amount of memory it has allocated.

As a default-constructed array allocates no memory, the slack will initially be zero. You can find out how much slack there is in an array by using the GetSlack function. The maximum number of elements that the array can hold before the container reallocates can be obtained by the Max function. GetSlack is equivalent to the difference between Max and Num:

The amount of slack in a container after a reallocation is decided by the allocator, so users should not rely on slack remaining constant.

Although slack management is not required, you can use it to your advantage to give the array optimization hints. For example, if you know you are about to add 100 new elements to the array, you can ensure you have a slack of at least 100 before adding, so that the array will not need to allocate memory while adding the new elements. The Empty function, mentioned above, takes an optional slack argument:

There is a Reset function which works similarly to Empty, except that it doesn't free memory if the requested slack is already provided by the current allocation. However, it will allocate more memory if the requested slack is larger:

And finally, you can remove all slack with the Shrink function, which will resize the allocation to be the minimum size required to hold the current elements. Shrink does not have any effect on the elements in the array:

Raw Memory

TArray is ultimately just a wrapper around allocated memory. It can be useful to treat it as such by direct modification of the bytes of the allocation and by creating elements yourself. TArray will always try to do the best it can with the information it has, but sometimes you may need to drop to a lower level.

TArray

The AddUninitialized and InsertUninitialized functions will add some uninitialized space to the array. They work like the Add and Insert functions, respectively, but they will not call the constructor of the element type. This can be useful to avoid calling constructors. You might do this in cases like the following example, where you plan to overwrite the entire struct with a Memcpy call:

You can also use this feature to reserve memory for objects which you plan to construct yourself:

AddZeroed and InsertZeroed work similarly, except they also zero the bytes of the added/inserted space:

There are also SetNumUninitialized and SetNumZeroed functions which work like SetNum except that, in the case where the new number is greater than the current one, the space for the new elements will be left uninitialized or bitwise-zeroed respectively. As with the AddUninitialized and InsertUninitialized functions, you should ensure that, if necessary, new elements are properly constructed into the new space if they need to be:



Use the "Uninitialized" and "Zeroed" families of functions carefully. If an element type includes a member that needs construction, or that doesn't have a valid bitwise-zeroed state, it can result in invalid array elements and undefined behavior. These functions are most useful on arrays of types that will likely never change, like FMatrix or FVector.



Miscellaneous

The BulkSerialize function is a serialization function that can be used as an alternative operator<< in order to serialize the array as a block of raw bytes, rather than doing per-element serialization. This can improve performance with trivial elements, like a built-in type or a plain data struct.

The CountBytes and GetAllocatedSize functions are used to estimate how much memory is currently being utilized by the array. CountBytes takes an FArchive, while GetAllocatedSize can be called directly. These functions are typically used for stats reporting.

The Swap and SwapMemory functions both take two indices and will swap the value of the elements at those indices. They are equivalent except that Swap does some extra error checking on the indices and will assert if the indices are out of range.

TMap

Creating and Filling a Map

Iteration

Queries

Removal

Sorting

Operators

Slack

KeyFuncs

Miscellaneous

After TArray, the most commonly used container in Unreal Engine is TMap. TMap is similar to TSet in that its structure is based on hashing keys. However, unlike TSet, this container stores data as key-value pairs (TPair<KeyType, ValueType>), using keys only for storage and retrieval.

There are two types of map: TMap and TMultiMap. The difference between these two is that TMap keys are unique, while TMultiMap supports storing multiple, identical keys. When adding a new key-value pair to a TMap with a key that matches an existing pair, the new pair will replace the old one. In a TMultiMap, the container will store both the new pair and the old.

TMap

In a TMap, key-value pairs are treated as the element type of the map as if each pair were an individual object. In this document, element means a key-value pair, while individual components are referred to as the element's key or the element's value. The element type is actually a TPair<KeyType, ElementType>, though it should be rare to need to refer to the TPair type directly.

Like TArray, TMap is a homogeneous container, meaning that all of its elements are strictly the same type. TMap is also a value type, and supports the usual copy, assignment, and destructor operations, as well as strong ownership of its elements, which will be destroyed when the map is destroyed. The key and value must also be value types.

TMap is a hashing container, which means that the key type must support the GetTypeHash function and provide an operator== for comparing keys for equality. Hashing is covered in more detail later.

TMap can also take an optional allocator to control the memory allocation behavior. However, unlike TArray, these are set allocators rather than the standard UE4 allocators like FHeapAllocator and TInlineAllocator. Set allocators, (class TSetAllocator), define how many hash buckets the map should use and which standard UE4 allocators should be used for hash and element storage.

The final TMap template parameter is KeyFuncs, which tells the map how to retrieve the key from the element type, how to compare two keys for equality and how to hash the key. These have defaults which will just return a reference to the key, use operator== for equality, and call the non-member GetTypeHash function for hashing. If your key type supports these functions, you can use it as a map key without supplying a custom KeyFuncs.

Unlike TArray, the relative order of TMap elements in memory is not reliable or stable, and iterating over the elements is likely to return them in a different order from the order in which they were added. Elements are also unlikely to be laid out contiguously in memory. The backing data structure of a map is a sparse array, which is an array that efficiently supports gaps between its elements. As elements are removed from the map, gaps in the sparse array will appear. Adding new elements into the array can then fill these gaps. However, even though TMap doesn't shuffle elements to fill gaps, pointers to map elements may still be invalidated, as the entire storage can be reallocated when it is full and new elements are added.

Creating and Filling a Map

You can create a TMap like this:

FruitMap is now an empty TMap of strings that are identified by integer keys. We have specified neither an allocator nor a KeyFuncs, so the map will do standard heap allocation and compare the key (of type int32) using operator== and hash it using GetTypeHash. No memory has been allocated at this point.

The standard way to populate a map is to call the Add function with a key and a value:



While the elements are listed here in the order of insertion, there is no guarantee as to their actual order in memory. For a new map, they are likely to be in order of insertion, but as more insertions and removals happen, it becomes increasingly unlikely that new elements will appear at the end.



This is not a TMultiMap, so keys are guaranteed to be unique. The following is the result of attempting to add a duplicate key:

The map still contains three elements, but the previous "Grapefruit" value with a key of 2 has been replaced with "Pear".

The Add function can accept a key without a value. When this overloaded Add is called, the value will be default-constructed:

Like TArray, we can also use Emplace instead of Add to avoid the creation of temporaries when inserting into the map:

Here, the key and value are passed directly to their respective type constructors. While this isn't meaningful for the int32 key, it does avoid the creation of a temporary FString for the value. Unlike TArray, it's only possible to emplace elements into a map with single-argument constructors.

You can also merge two maps with the Append function, which will move all elements from one map into the other:

In the above example, the resulting map is equivalent to using Add or Emplace to add each element of FruitMap2 individually, emptying FruitMap2 when the process is complete. This means that any element from FruitMap2 that shares its key with an element already in FruitMap will replace that element.

If you mark the TMap with the UPROPERTY macro and one of the "editable" keywords (EditAnywhere, EditDefaultsOnly, or EditInstanceOnly), you can add and edit elements in the Editor.

Iteration

Iteration over TMaps is similar to TArrays. You can use the C++ ranged-for feature, remembering that the element type is a TPair:

You can also create iterators with the CreateIterator and CreateConstIterators functions. CreateIterator will return an iterator with read-write access, while CreateConstIterator returns a read-only iterator. In either case, you can use the Key and Value functions of these iterators to examine the elements. Printing the contents of our example "fruit" map using iterators would look like this:

Queries

To find out how many elements are currently in the map, call the Num function.

In order to determine whether or not a map contains a specific key, call the Contains function, as follows:

If you know that your map contains a certain key, you can look up the corresponding value with operator[], using the key as the index. Doing this with a non-const map will return a non-const reference, while a const map will return a const reference.

operator[]

If you are unsure whether or not your map contains a key, you could check with the Contains function, and then use operator[]. However, this is suboptimal, since a successful retrieval involves two lookups on the same key. The Find function combines these behaviors with a single lookup. Find returns a pointer to the value of the element if the map contains the key, or a null pointer if it does not. Calling Find on a const map will cause the pointer it returns to be const as well.

Alternatively, to ensure that you get a valid result from your query, you can use FindOrAdd or FindRef. FindOrAdd will return a reference to the value associated with the key you provide. If the key was not in the map, FindOrAdd will return a newly-created element, with your key and the default-constructed value, that it will also add to the map. Because it can potentially modify the map, FindOrAdd is only available for non-const maps. FindRef, despite its name, will return a copy of the value associated with your key, or a default-constructed value if your key is not found in the map. FindRef does not create a new element, and thus is available for use with both const and non-const maps. Because FindOrAdd and FindRef succeed even when the key isn't found in the map, you can safely call them without the usual safety procedures like checking Contains in advance, or null-checking the return value.

Because FindOrAdd can add new entries to the map, as it does when initializing Ref8 in our example, previously-obtained pointers (from Find) or references (from FindOrAdd) could become invalid. This is a result of the addition operation allocating memory and moving existing data if the map's backend storage needs to expand to contain the new element. In the example above, Ref7 may be invalidated after Ref8 after the call to FindOrAdd(8).

The FindKey function performs a reverse lookup, meaning that a supplied value is matched to a key, and returns a pointer to the first key that's paired to the provided value. Searches for a value that isn't present in the map will return a null key.

Lookups by value are slower (linear time) than lookups by key. This is because the map is sorted by key, not by value. In addition, if a map has multiple keys with the same value, FindKey may return any of them.

The GenerateKeyArray and GenerateValueArray functions populate a TArray with a copy of all the keys and values respectively. In both cases, the array being passed is emptied before population, so the resulting number of elements will always equal the number of elements in the map.

Removal

Elements can be removed from maps by using the Remove function and providing the key of the element to remove. The return value is the number of elements that were removed, and can be zero if the map didn't contain any elements matching the key.

Removing elements can leave holes in the data structure, which you can see when visualizing the map in Visual Studio's watch window, but they have been omitted here for clarity.

The FindAndRemoveChecked function can be used to remove an element from the map and return its value. The "checked" part of the name indicates that the map will call check (UE4's equivalent of assert) if the key does not exist.

The RemoveAndCopyValue function is similar to Remove, but copies the value of the removed element out to a reference parameter. If the key you specified is not present in the map, the output parameter will be unchanged and the function will return false.

Finally, you can remove all elements from the map with the Empty or Reset functions.

Empty and Reset are similar, but Empty can take a parameter to indicate how much slack to leave in the map, while Reset

Sorting

A TMap can be sorted. After sorting, iteration over the map will present the elements in sorted order, but this behavior is only guaranteed until the next time you modify the map. Sorting is unstable, so equivalent elements in a MultiMap may appear in any order.

You can sort by key or by value using the KeySort or ValueSort functions, respectively. Both functions take a binary predicate which specifies the sort order.

Operators

Like TArray, TMap is a regular value type, and can be copied with the standard copy constructor or assignment operator. Maps strictly own their elements, so copying a map is deep; the new map will have its own copy of the elements.

TMap supports move semantics, which can be invoked using the MoveTemp function. After a move, the source map is guaranteed to be empty:

Slack

Slack is allocated memory that doesn't contain an element. You can allocate memory without adding elements by calling Reserve, and you can remove elements without deallocating the memory they were using by calling Reset or by calling Empty with a non-zero slack parameter. Slack optimizes the process of adding new elements to the map by using pre-allocated memory instead of having to allocate new memory. It can also help with element removal since the system does not need to deallocate memory. This is especially efficient when you are emptying a map that you expect to repopulate immediately with the same number of elements or fewer.

TMap does not provide a way of checking how many elements are preallocated the way the Max function in TArray does.

In this code, the Reserve function preallocates our map to contain up to ten elements.

To remove all slack from a TMap, use the Collapse and Shrink functions. Shrink removes all slack from the end of the container, but this will leave any empty elements in the middle or at the start.

Shrink only removed one invalid element in the code above because there was only one empty element at the end. To remove all slack, the Compact function should be called first, so that the empty spaces will be grouped together in preparation for Shrink.

KeyFuncs

As long as a type has an operator== and a non-member GetTypeHash overload, you can use it as a key type for a TMap without any changes. However, you may want to use types as keys without overloading those functions. In these cases, you can provide your own custom KeyFuncs. To create KeyFuncs for your key type, you must define two typedefs and three static functions, as follows:

KeyInitType — Type used to pass keys around.

ElementInitType — Type used to pass elements around.

KeyInitType GetSetKey(ElementInitType Element) — Returns the key of an element.

bool Matches(KeyInitType A, KeyInitType B) — Returns true if A and B are equivalent, false otherwise.

uint32 GetKeyHash(KeyInitType Key) — Returns the hash value of Key.

KeyInitType and ElementInitType are typedefs to the normal passing convention of the key type and element type. Usually these will be a value for trivial types and a const reference for non-trivial types. Remember that the element type of a map is a TPair.

An example of a custom KeyFuncs might look like this:

FMyStruct features a unique identifier, as well as some other data that does not contribute to its identity. GetTypeHash and operator== would be inappropriate here, because operator== should not ignore any of the type's data for general-purpose usage, but would simultaneously need to do so in order to be consistent with the behavior of GetTypeHash, which only looks at the UniqueID field. The following steps will help to create a custom KeyFuncs for FMyStruct:

First, inherit BaseKeyFuncs, as it helpfully defines some types, including KeyInitType and ElementInitType.

BaseKeyFuncs takes two template parameters: the element type of the map, and the type of our key. As with all maps, the element type is a TPair, taking FMyStruct as its KeyType and the template parameter of TMyStructMapKeyFuncs`as its ValueType. The replacement KeyFuncs is a template, so that you can specify ValueType on a per-map basis, rather than needing to define a new KeyFuncs every time you want to create a TMap keyed on FMyStruct. The second BaseKeyFuncs argument is the type of the key, not to be confused with the KeyType from TPair, the Key field of the element stores. Since this map should use UniqueID (from FMyStruct) as its key, FString` is used here.

Next, define the three required KeyFuncs static functions. The first is GetSetKey, which returns the key for a given element type. Our element type is TPair, and our key is UniqueID, so the function can simply return UniqueID directly.

The second static function is Matches, which takes the keys of two elements (retrieved by GetSetKey), and compares them to see if they are equivalent. For FString, the standard equivalence test (operator==) is case-insensitive; to replace this with a case-sensitive search, use the Compare function with the appropriate case-comparison option.

Finally, the GetKeyHash static function takes an extracted key and returns a hashed value for it. Because the Matches function is case-sensitive, GetKeyHash must also be. A case-sensitive FCrc function will calculate the hash value from the key string.

Now that the structure supports the behaviors that TMap requires, you can create instances of it.

KeyFuncs parameter is last, and this TMap

TMap assumes that two items that compare as equals using Matches will also return the same value from GetKeyHash. In addition, modifying the key of an existing map element in a way which will change the results from either of these functions is considered undefined behavior, as this will invalidate map's internal hash. These rules also apply to the overloads of operator== and GetKeyHash when using the default KeyFuncs

Miscellaneous

The CountBytes and GetAllocatedSize functions estimate how much memory the internal array is currently utilizing. CountBytes takes an FArchive parameter, while GetAllocatedSize does not. These functions are typically used for stats reporting.

The Dump function takes an FOutputDevice and writes out some implementation information about the contents of the map. This function is usually used for debugging.

TSet

Creating and Filling a Set

Editing UPROPERTY TSets

Iteration

Queries

Removal

Sorting

Operators

Slack

DefaultKeyFuncs

Miscellaneous

TSet is similar to TMap and TMultiMap, but with an important difference: Rather than associating data values with independent keys, a TSet uses the data value itself as the key, through an overridable function that evaluates the element. TSet is very fast (constant time) for adding, finding, and removing elements. By default, TSet does not support duplicate keys, but this behavior can be activated with a template parameter.

TSet

TSet is a fast container class to store unique elements in a context where order is irrelevant. For most use cases, just one parameter — the element type — is needed. However, TSet can be set up with different template parameters to change its behavior and make it more versatile. You can specify a derived struct based on DefaultKeyFuncs to provide hashing functionality, as well as permit multiple keys with the same value to exist in the set. Finally, like the other container classes, you can provide a custom memory allocator for its data storage.

Like TArray, TSet is a homogeneous container, meaning that all of its elements are strictly the same type. TSet is also a value type, and supports the usual copy, assignment, and destructor operations, as well as strong ownership of its elements, which are destroyed when the TSet is. The key type must also be a value type.

TSet uses hashes, which means that the KeyFuncs template parameter, if provided, tells the set how to determine the key from an element, how to compare two keys for equality, how to hash the key, and whether or not to permit duplicate keys. These have defaults that will return a reference to the key, use operator== for equality, and the non-member GetTypeHash function for hashing. By default, the set will not permit duplicate keys. If your key type supports these functions, it is usable as a set key without the need to provide a custom KeyFuncs. To write a custom KeyFuncs, extend the DefaultKeyFuncs struct.

Finally, TSet can take an optional allocator to control memory allocation behavior. Standard Unreal Engine 4 (UE4) allocators (such as FHeapAllocator and TInlineAllocator) cannot be used as allocators for TSet. Instead, TSet uses set allocators, which define how many hash buckets the set should use, and which standard UE4 allocators to use for element storage. See TSetAllocator for more information.

Unlike TArray, the relative order of TSet elements in memory is not reliable or stable, and iterating over the elements is likely to return them in a different order from the order in which they were added. Elements are also unlikely to be laid out contiguously in memory. The backing data structure of a set is a sparse array, which is an array that efficiently supports gaps between its elements. As elements are removed from the set, gaps in the sparse array will appear. Adding new elements into the array can then fill these gaps. However, even though TSet doesn't shuffle elements to fill gaps, pointers to set elements may still be invalidated, as the entire storage can be reallocated when it is full and new elements are added.

Creating and Filling a Set

You can create a TSet like this:

This creates an empty TSet that will hold FString data. The TSet will compare elements directly with operator==, hash them using GetTypeHash, and use the standard heap allocator. No memory has been allocated at this point.

The standard way to populate a set is to use the Add function and provide a key (element):



While the elements are listed here in the order of insertion, there is no guarantee as to their actual order in memory. For a new set, they are likely to be in order of insertion, but as more insertions and removals happen, it becomes increasingly unlikely that new elements will appear at the end.



Since this set uses the default allocator, keys are guaranteed to be unique. The following is the result of attempting to add a duplicate key:

The set now contains four elements. "Pear" brought the count up to four from three, but the new "Banana" didn't change the number of elements in the set because it replaced the old "Banana" entry.

Like TArray, we can also use Emplace instead of Add to avoid the creation of temporaries when inserting into the set:

Here, the argument is passed directly to the constructor of the key type. This avoids the creation of a temporary FString for the value. Unlike TArray, it's only possible to emplace elements into a set with single-argument constructors.

It's also possible to insert all the elements from another set by using the Append function to merge them:

In the example above, the resulting set is equivalent to using Add or Emplace to add the elements individually. Duplicate keys from the source set will replace their counterparts in the target.

Editing UPROPERTY TSets

If you mark the TSet with the UPROPERTY macro and one of the "editable" keywords (EditAnywhere, EditDefaultsOnly, or EditInstanceOnly), you can add and edit elements in Unreal Editor.

Iteration

Iteration over TSets is similar to TArrays. You can use the C++ ranged-for feature:

You can also create iterators with the CreateIterator and CreateConstIterators functions. CreateIterator will return an iterator with read-write access, while CreateConstIterator returns a read-only iterator. In either case, you can use the Key and Value functions of these iterators to examine the elements. Printing the contents of our example "fruit" set using iterators would look like this:

Queries

To find out how many elements are currently in the set, call the Num function.

In order to determine whether or not a set contains a specific element, call the Contains function, as follows:

You can use the FSetElementId struct to find the index of a key within the set. You can then use that index with operator[] to retrieve the element. Calling operator[] on a non-const set will return a non-const reference, and calling it on a const set will return a const reference.

If you are unsure whether or not your set contains a key, you could check with the Contains function, and then use operator[]. However, this is suboptimal, since a successful retrieval involves two lookups on the same key. The Find function combines these behaviors with a single lookup. Find returns a pointer to the value of the element if the set contains the key, or a null pointer if it does not. Calling Find on a const set will cause the pointer it returns to be const as well.

The Array function returns a TArray populated with a copy of all the elements in the TSet. The array that you pass in will be emptied at the beginning of the operation, so the resulting number of elements will always equal the number of elements in the set:

Removal

Elements can be removed by index with the Remove function, though this is recommended only for use while iterating through the elements. The Remove function returns the number of elements removed, and will be 0 if the key provided was not contained in the set. If a TSet supports duplicate keys, Remove will remove all matching elements.

Removing elements can leave holes in the data structure, which you can see when visualizing the set in Visual Studio's watch window, but they have been omitted here for clarity.

Finally, you can remove all elements from the set with the Empty or Reset functions.

Empty and Reset are similar, but Empty can take a parameter to indicate how much slack to leave in the set, while Reset

Sorting

A TSet can be sorted. After sorting, iteration over the set will present the elements in sorted order, but this behavior is only guaranteed until the next time you modify the set. Sorting is unstable, so equivalent elements in a set that supports duplicate keys may appear in any order.

The Sort function takes a binary predicate which specifies the sort order, as follows:

Operators

Like TArray, TSet is a regular value type and as such can be copied with the standard copy constructor or assignment operator. Sets strictly own their elements, so copying a set is deep; the new set will have its own copy of the elements.

Slack

Slack is allocated memory that doesn't contain an element. You can allocate memory without adding elements by calling Reserve, and you can remove elements without deallocating the memory they were using by calling Reset or by calling Empty with a non-zero slack parameter. Slack optimizes the process of adding new elements to the set by using pre-allocated memory instead of having to allocate new memory. It can also help with element removal, since the system does not need to deallocate memory. This is especially efficient when you are emptying a set that you expect to repopulate immediately with the same number of elements or fewer.

TSet does not provide a way of checking how many elements are preallocated, like the Max function in TArray does.

The following code removes all elements from the set without deallocating any memory, resulting in the creation of slack:

To create slack directly, such as to preallocate memory before adding elements, use the Reserve function.



Preallocating the slack has caused the new elements to be added in reverse order. Unlike arrays, sets do not attempt to maintain element order, and code dealing with sets should not expect element order to be stable or predictable.



To remove all slack from a TSet, use the Collapse and Shrink functions. Shrink removes all slack from the end of the container, but this will leave any empty elements in the middle or at the start.

Shrink only removed one invalid element in the code above because there was only one empty element at the end. To remove all slack, the Compact or CompactStable function should be called first, so that the empty spaces will be grouped together in preparation for Shrink. As its name implies, CompactStable maintains element order while consolidating empty elements.

DefaultKeyFuncs

As long as a type has an operator== and a non-member GetTypeHash overload, TSet can use it, since the type is both the element and the key. However, it may be useful to use types as keys where it is undesirable to overload those functions. In these cases, you can provide your own custom DefaultKeyFuncs. To create KeyFuncs for your key type, you must define two typedefs and three static functions, as follows:

KeyInitType — Type used to pass keys around. Usually drawn from the ElementType template parameter.

ElementInitType — Type used to pass elements around. Also usually drawn from the ElementType template parameter, and therefore identical to KeyInitType.

KeyInitType GetSetKey(ElementInitType Element) — Returns the key of an element. For sets, this is usually just the element itself.

bool Matches(KeyInitType A, KeyInitType B) — Returns true if A and B are equivalent, false otherwise.

uint32 GetKeyHash(KeyInitType Key) — Returns the hash value of Key.

KeyInitType and ElementInitType are typedefs to the normal passing convention of the key/element type. Usually, these will be a value for trivial types and a const reference for non-trivial types. Remember that the element type of a set is also the key type, which is why DefaultKeyFuncs uses only one template parameter, ElementType, to define both.

TSet assumes that two items that compare equal using Matches (in DefaultKeyFuncs) will also return the same value from GetKeyHash (in KeyFuncs).

operator== and GetKeyHash when using the default implementation of DefaultKeyFuncs

Miscellaneous

The CountBytes and GetAllocatedSize functions estimate how much memory the internal array is currently utilizing. CountBytes takes an FArchive parameter, while GetAllocatedSize does not. These functions are typically used for stats reporting.

The Dump function takes an FOutputDevice and writes out some implementation information about the contents of the set. There is also a DumpHashElements function that lists all elements from all hash entries. These functions are usually used for debugging.

Gameplay Programming Reference Directory

When programming gameplay elements using C++ code, each module can contain many C++ classes.



Each class defines a template for a new Actor or Object. Within the class header file, the class and any class functions and properties are declared. Classes can also contain structs, data structures that help with organization and manipulation of related properties. Structures can also be defined on their own. Interfaces allow additional gameplay behavior to be implemented by different classes.

When programming with Unreal Engine, it is possible to have standard C++ classes, functions, and variables. These can be defined using standard C++ syntax. However, UCLASS(), UFUNCTION(), and UPROPERTY() macros can be used to make Unreal Engine aware of the new classes, functions, and variables. For instance, a variable with a declaration prefaced by a UPROPERTY() macro can be garbage collected by the engine, and can be displayed and edited within Unreal Editor. There are also UINTERFACE() and USTRUCT() macros, and keywords for each macro that can be used to specify the behavior of the class, function, property, interface, or struct within Unreal Engine and Unreal Editor.

In addition to the above macros, there is a UPARAM() macro that is primarily used when exposing C++ code to Blueprints. To see examples of UPARAM() being used, see the Exposing Gameplay Elements to Blueprints documentation.

Gameplay Programming Reference Directory

Gameplay Classes

UFunctions

Properties

Structs

Interfaces

Check

Verify

Ensure

Usage Examples

In C and C++ programming, assert helps to detect and diagnose unexpected or invalid runtime conditions during development. These conditions are often checks that a pointer is non-null, a divisor is non-zero, a function isn't running recursively, or other important assumptions that the code requires, but that would be inefficient to check every time. In some cases, assert discovers bugs that cause delayed crashes before the actual crash happens, such as deleting an object that will be required in a future tick, assisting the developer at discovering the root cause of an eventual crash. A key feature of assert is that it doesn't exist in shipping code, meaning it has no performance impact on a shipped product, but also must not have any side effects. The simplest way to think of assert is that whatever is "asserted" must be true, or the program will stop running.

Unreal Engine provides three different families of assert equivalents: check, verify, and ensure. If you would like to examine the code behind these features, you can find the relevant macros in Engine/Source/Runtime/Core/Public/Misc/AssertionMacros.h. Each one behaves slightly differently, but they all serve the same general role as diagnostic tools for use during development.

Check

The Check family is the closest to the base assert, in that members of this family halt execution when the first parameter evaluates to a false value, and do not run in shipping builds by default. The following Check macros are available:

Macro

Parameters

Behavior

check or checkSlow

Expression

Halts execution if Expression is false

checkf or checkfSlow

Expression, FormattedText, ...

Halts execution if Expression is false and outputs FormattedText to the log

checkCode

Code

Executes Code within a do-while loop structure that runs once; primarily useful as a way to prepare information that another Check requires

checkNoEntry

(none)

Halts execution if the line is ever hit, similar to check(false), but intended for code paths that should be unreachable

checkNoReentry

(none)

Halts execution if the line is hit more than once

checkNoRecursion

(none)

Halts execution if the line is hit more than once without leaving scope

unimplemented

(none)

Halts execution if the line is ever hit, similar to check(false), but intended for virtual functions that should be overridden and not called

Check macros operate in Debug, Development, Test, and Shipping Editor builds, except those ending in "Slow", which only operate in Debug builds. Defining USE_CHECKS_IN_SHIPPING to hold a true value (generally 1), makes Check macros operate in all builds. This can be useful if you suspect that code inside a Check macro is altering a value, or you have Shipping-only bugs that are hard to track down, and that you suspect would be caught by your existing Check macros. Projects should ship with USE_CHECKS_IN_SHIPPING set to its default value of 0.

Verify

The Verify family behaves identically to the Check family in most builds. However, Verify macros evaluate their expressions even in builds where Check macros are disabled. This means that you should use Verify macros only when the expression needs to run independently of diagnostic checks. For example, if you have a function that performs an action and then returns a bool indicating whether that action succeeded or failed, you should use Verify rather than Check to make sure that the action was successful. This is because, in shipping builds, Verify will ignore the return value, but will still perform the action. Check, however, will simply not call the function at all in shipping builds, resulting in different behavior.

Macro

Parameters

Behavior

verify or verifySlow

Expression

Halts execution if Expression is false

verifyf or verifyfSlow

Expression, FormattedText, ...

Halts execution if Expression is false and outputs FormattedText to the log

Verify macros operate fully in Debug, Development, Test, and Shipping Editor builds, except those ending in "Slow", which only operate in Debug builds. Defining USE_CHECKS_IN_SHIPPING to hold a true value, generally 1, overrides this behavior. In all other cases, Verify macros will evaluate their expressions, but will not halt execution or output text to the log.

Ensure

The Ensure family is similar to the Verify family, but works with non-fatal errors. This means that if an Ensure macro's expression evaluates as false, the Engine will inform the crash reporter, but will continue running. In order to avoid flooding the crash reporter, Ensure macros will only report once per Engine or Editor session. If your use case requires that an Ensure macro report every time its expression evaluates as false, use the "Always" version of the macro.

Macro

Parameters

Behavior

ensure

Expression

Notifies the crash reporter on the first time Expression is false

ensureMsgf

Expression, FormattedText, ...

Notifies the crash reporter and outputs FormattedText to the log on the first time Expression is false

ensureAlways

Expression

Notifies the crash reporter if Expression is false

ensureAlwaysMsgf

Expression, FormattedText, ...

Notifies the crash reporter and outputs FormattedText to the log if Expression is false

Ensure macros evaluate their expressions in all builds, but only contact the crash reporter in Debug, Development, Test, and Shipping Editor builds.

Usage Examples

The following hypothetical situations demonstrate use cases where Check, Verify, and Ensure can help to clarify your code or assist with debugging.

Adding Classes

Class Headers

Class Declaration

Class Specifiers

Class Implementation

Class Constructor

Constructor Format

Constructor Statics and Helpers

Asset References

Class References

Components and Sub-Objects

Every gameplay class in Unreal Engine consists of a class header file (.h) and a class source file (.cpp). The class header contains the declarations of the class and its members, such as variables and functions, while the class source file is where the functionality of the class is defined by implementing the functions that belong to the class.

Classes in Unreal Engine have a standardized naming scheme so that you know instantly what kind of class it is simply by looking at the first letter, or prefix. The prefixes for gameplay classes are:

Prefix

Meaning

A

Extends from the base class of spawnable gameplay objects. These are Actors, and can be spawned directly into the world.

U

Extend from the base class of all gameplay objects. These cannot be directly instanced into the world; they must belong to an Actor. These are generally objects like Components.

Adding Classes

The C++ Class Wizard sets up the header file and source file you need for your new class, and also updates your game module accordingly. The header file and source file automatically include the class declaration and class constructor, as well as Unreal Engine-specific code like the UCLASS() macro.

Class Headers

Gameplay classes in Unreal Engine generally have separate and unique class header files. These files are usually named to match the class being defined within, minus the A or U prefix, and using the .h file extension. So, the class header file for the AActor class is named Actor.h. Although Epic code follows these guidelines, no formal relationship between class name and source file name exists in the current engine.

Class header files for gameplay classes use standard C++ syntax in conjunction with specialized macros to simplify the process of declaring classes, variables, and functions.

At the top of each gameplay class header file, the generated header file (created automatically) needs to be included. So, at the top of ClassName.h, the following line must appear:

Class Declaration

The class declaration defines the name of the class, what class it inherits from and, thus, any functions and variables it inherits. The class declaration also defines other engine and editor specific behavior that may be desired via class specifiers and metadata.

The syntax for declaring a class is as follows:

The declaration consists of a standard C++ class declaration for the class. Above the standard declaration, descriptors such as class specifiers and metadata are passed to the UCLASS

These are used to create the UClass for the class being declared, which can be thought of as the engine's specialized representation of the class. Also, the GENERATED_BODY() macro must be placed at the very beginning of the class body.

When declaring classes, Class Specifiers can be added to the declaration to control how the class behaves with various aspects of the Engine and Editor.

Class Specifier

Effect

Abstract

The Abstract Specifier declares the class as an "abstract base class", preventing the user from adding Actors of this class to Levels. This is useful for classes which are not meaningful on their own. For example, the ATriggerBase base class is abstract, while the ATriggerBox subclass is not abstract and can be placed in a Level.

AdvancedClassDisplay

The AdvancedClassDisplay Specifier forces all properties of the class to show only in the advanced sections of any details panel where they appear. To override this on an individual property, use the SimpleDisplay specifier on that property.

AutoCollapseCategories=(Category1, Category2, ...)

The AutoCollapseCategories Specifier negates the effects, for the listed categories, of the AutoExpandCategories Specifier on a parent class.

AutoExpandCategories=(Category1, Category2, ...)

Specifies one or more categories that should be automatically expanded in the Unreal Editor Property window for Objects of this class. To auto-expand variables declared with no category, use the name of the class which declares the variable.

Blueprintable

Exposes this class as an acceptable base class for creating Blueprints. The default is NotBlueprintable, unless inherited otherwise. This Specifier is inherited by subclasses.

BlueprintType

Exposes this class as a type that can be used for variables in Blueprints.

ClassGroup=GroupName

Indicates that Unreal Editor's Actor Browser should include this class and any subclass of this class within the specified GroupName when Group View is enabled in the Actor Browser.

CollapseCategories

Indicates that properties of this class should not be grouped in categories in Unreal Editor Property windows. This Specifier is propagated to child classes, and can be overridden by the DontCollapseCategories Specifier.

Config=ConfigName

Indicates that this class is allowed to store data in a configuration file (.ini). If there are any class properties declared with the config or globalconfig Specifiers, this Specifier causes those properties to be stored in the named configuration file. This Specifier is propagated to all child classes and cannot be negated, but child classes can change the config file by re-declaring the config Specifier and providing a different ConfigName. Common ConfigName values are "Engine", "Editor", "Input", and "Game".

Const

All properties and functions in this class are const and are exported as const. This Specifier is inherited by subclasses.

ConversionRoot

A root convert limits a subclass to only be able to convert to child classes of the first root class going up the hierarchy.

CustomConstructor

Prevents automatic generation of the constructor declaration.

DefaultToInstanced

All instances of this class are considered "instanced". Instanced classes (components) are duplicated upon construction. This Specifier is inherited by subclasses.

DependsOn=(ClassName1, ClassName2, ...)

All classes listed will be compiled before this class. The class names provided must indicate classes in the same (or a previous) package. Multiple dependency classes can be identified using a single DependsOn line delimited by commas, or can be specified using a separate DependsOn line for each class. This is important when a class uses a struct or enum declared in another class, as the compiler only knows what is in the classes it has already compiled.

Deprecated

This class is deprecated and Objects of this class will not be saved when serializing. This Specifier is inherited by subclasses.

DontAutoCollapseCategories=(Category, Category, ...)

Negates the AutoCollapseCategories Specifier for the listed categories inherited from a parent class.

DontCollapseCategories

Negates a CollapseCatogories Specifier inherited from a base class.

EditInlineNew

Indicates that Objects of this class can be created from the Unreal Editor Property window, as opposed to being referenced from an existing Asset. The default behavior is that only references to existing Objects may be assigned through the Property window). This Specifier is propagated to all child classes; child classes can override this with the NotEditInlineNew Specifier.

HideCategories=(Category1, Category2, ...)

Lists one or more categories that should be hidden from the user entirely. To hide properties declared with no category, use the name of the class which declares the variable. This Specifier is propagated to child classes.

HideDropdown

Prevents this class from showing up in property window combo boxes.

HideFunctions=(Category1, Category2, ...)

Hides all functions in the specified category from the user entirely.

HideFunctions=FunctionName

Hides the named functions from the user entirely.

Intrinsic

This indicates that the class was declared directly in C++, and has no boilerplate generated by Unreal Header Tool. Do not use this Specifier on new classes.

MinimalAPI

Causes only the class's type information to be exported for use by other modules. The class can be cast to, but the functions of the class cannot be called (with the exception of inline methods). This improves compile times by not exporting everything for classes that do not need all of their functions accessible in other modules.

NoExport

Indicates that this class's declaration should not be included in the automatically-generated C++ header file by the header generator. The C++ class declaration must be defined manually in a separate header file. Only valid for native classes. Do not use this for new classes.

NonTransient

Negates a Transient Specifier inherited from a base class.

NotBlueprintable

Specifies that this class is not an acceptable base class for creating Blueprints. This is the default and is inherited by subclasses.

NotPlaceable

Negates a Placeable Specifier inherited from a base class. Indicates that Objects of this class may not be placed into a Level, UI scene, or Blueprint in the Editor.

PerObjectConfig

Configuration information for this class will be stored per Object, where each object has a section in the .ini file named after the Object in the format [ObjectName ClassName]. This Specifier is propagated to child classes.

Placeable

Indicates that this class can be created in the Editor and placed into a level, UI scene, or Blueprint (depending on the class type). This flag is propagated to all child classes; child classes can override this flag using the NotPlaceable Specifier.

ShowCategories=(Category1, Category2, ...)

Negates a HideCategories Specifier (inherited from a base class) for the listed categories.

ShowFunctions=(Category1, Category2, ...)

Shows all functions within the listed categories in a property viewer.

ShowFunctions=FunctionName

Shows the named function in a property viewer.

Transient

Objects belonging to this class will never be saved to disk. This is useful in conjunction with certain kinds of native classes which are non-persistent by nature, such as players or windows. This Specifier is propagated to child classes, but can be overridden by the NonTransient Specifier.

Within=OuterClassName

Objects of this class cannot exist outside of an instance of an OuterClassName Object. This means that creating an Object of this class requires that an instance of OuterClassName is provided as its Outer Object.

When declaring classes, interfaces, structs, enums, enum values, functions, or properties, you can add Metadata Specifiers to control how they interact with various aspects of the engine and editor. Each type of data structure or member has its own list of Metadata Specifiers.

Metadata only exists in the editor; do not write game logic that accesses metadata.

Classes can use the following Metatag Specifiers:

Class Meta Tag

Effect

BlueprintSpawnableComponent

If present, the component Class can be spawned by a Blueprint.

BlueprintThreadSafe

Only valid on Blueprint function libraries. This specifier marks the functions in this class as callable on non-game threads in animation Blueprints.

ChildCannotTick

Used for Actor and Component classes. If the native class cannot tick, Blueprint-generated classes based on this Actor or Component can never tick, even if bCanBlueprintsTickByDefault is true.

ChildCanTick

Used for Actor and Component classes. If the native class cannot tick, Blueprint-generated classes based on this Actor or Component can have the bCanEverTick flag overridden, even if bCanBlueprintsTickByDefault is false.

DeprecatedNode

For behavior tree nodes, indicates that the class is deprecated and will display a warning when compiled.

DeprecationMessage="Message Text"

Deprecated classes with this metadata will include this text with the standard deprecation warning that Blueprint Scripts generate during compilation.

DisplayName="Blueprint Node Name"

The name of this node in a Blueprint Script will be replaced with the value provided here, instead of the code-generated name.

DontUseGenericSpawnObject

Do not spawn an Object of the class using Generic Create Object node in Blueprint Scripts; this specifier applies only to Blueprint-type classes that are neither Actors nor Actor Components.

ExposedAsyncProxy

Expose a proxy Object of this class in Async Task nodes.

IgnoreCategoryKeywordsInSubclasses

Used to make the first subclass of a class ignore all inherited ShowCategories and HideCategories Specifiers.

IsBlueprintBase="true/false"

States that this class is (or is not) an acceptable base class for creating Blueprints, similar to the Blueprintable or 'NotBlueprintable` Specifiers.

KismetHideOverrides="Event1, Event2, .."

List of Blueprint events that are not allowed to be overridden.

ProhibitedInterfaces="Interface1, Interface2, .."

Lists Interfaces that are not compatible with the class.

RestrictedToClasses="Class1, Class2, .."

Blueprint function library classes can use this to restrict usage to the classes named in the list.

ShortToolTip="Short tooltip"

A short tooltip that is used in some contexts where the full tooltip might be overwhelming, such as the Parent Class Picker dialog.

ShowWorldContextPin

Indicates that Blueprint nodes placed in graphs owned by this class must show their World context pins, even if they are normally hidden, because Objects of this class cannot be used as World context.

UsesHierarchy

Indicates the class uses hierarchical data. Used to instantiate hierarchical editing features in Details panels.

ToolTip="Hand-written tooltip"

Overrides the automatically generated tooltip from code comments.

Class Implementation

All gameplay classes must use the GENERATED_BODY macro in order to be implemented properly. This is done in the class header (.h) file that defines the class and all of its variables and functions. A best practice is for the class source and header files to be named to match the class being implemented, minus the A or U prefix. So, the source file for the AActor class is named Actor.cpp, and its header file is named Actor.h. This is handled automatically for classes created by the "Add C++ Class" menu option within the editor.

The source file (.cpp) must include the header file (.h) that contains the C++ class declaration, which is usually generated automatically but can also be created manually (if desired). For example, the C++ declaration for the AActor class is automatically generated in the EngineClasses.h header file. This means the Actor.cpp file must include the EngineClasses.h file or another file that in turn includes it. Generally, you just include the header file for your game project, which will include the headers for the gameplay classes in your game project. In the case of AActor and EngineClasses.h, the EnginePrivate.h header is included, which includes Engine.h - the header file for the Engine project - and that includes the EngineClasses.h header file.

You may also need to include additional files if you reference other classes in the implementation of the class's functions that are not included simply by the inclusion of that one file.

Class Constructor

UObjects use Constructors to set default values for properties and other variables as well as perform other necessary initialization. The class constructor is generally placed within the class implementation file, e.g. the AActor::AActor constructor is in Actor.cpp.

Some constructors may be located in a special "constructors" file on a per-module basis. For example, the AActor::AActor constructor may be found in EngineConstructors.cpp. This is the result of an automatic conversion process from the previous use of a DEFAULTS block to the use of constructors. Over time, these will be moved to their respective class source files.

It is also possible to place the constructor inline in the class header file. However, if the constructor is in the class header file, the UClass must be declared with the CustomConstructor specifier as this prevents the automatic code generator from creating a constructor declaration in the header.

The most basic form of a UObject constructor is shown below:

This constructor initializes the Class Default Object (CDO), which is the master copy on which future instances of the class are based. There is also a secondary constructor that supports a special property-altering structure:

Although neither of the above constructors actually perform any initialization, the engine will have already initialized all fields to zero, NULL, or whatever value their default constructors implement. However, any initialization code written into the constructor will be applied to the CDO, and will therefore be copied to any new instances of the object created properly within the engine, as with CreateNewObject or SpawnActor.

The FObjectInitializer parameter that is passed into the constructor, despite being marked as const, can be configured via built-in mutable functions to override properties and subobjects. The UObject being created will be affected by these changes, and this can be used to change the values of registered properties or components.

In the above case, the superclass was going to create the subobjects named "SomeComponent" and "SomeOtherComponent" in its constructor, but it will not do so because of the FObjectInitializer. In the following case, SomeProperty will default to 26 in the CDO, and thus in every fresh instance of AUTDemoHUD.

Setting values for more complex data types, especially class references, names, and asset references, requires defining and instantiating a ConstructorStatics struct in the constructor to hold the various property values needed. This ConstructorStatics struct is only created the first time the constructor is run. On subsequent runs, it just copies a pointer, which makes it extremely fast. When the ConstructorStatics struct is created, the values are assigned to the members of the struct for accessing when assigning the values to the actual properties themselves later on in the constructor.

ContructorHelpers is a special namespace defined in ObjectBase.h that contains helper templates that are used to perform common actions specific to constructors. For instance, there are helper templates for finding references to assets or classes as well as creating and finding components.

Ideally, asset references in classes do not exist. Hardcoded asset references are brittle and the preferred method is to use Blueprints for configuring asset properties. However, hardcoded references are still fully supported. We do not want to search for assets every time we construct an object, so these searches are only done once. This is accomplished via a static struct which ensures that we do our asset searches only once:

ConstructorHelpers::FObjectFinder finds a reference to the specified UObject using StaticLoadObject. This is generally used to reference assets stored in content packages. Reports failure if the object is not found.

ConstructorHelpers::FClassFinder finds a reference to the specified UClass and reports a failure if the class is not found.

In many cases, you can just use USomeClass::StaticClass() and skip the complexity of the ClassFinder altogether. For example, you can use the method below in most circumstances:

For cross-module references, it is probably better to use the ClassFinder method.

Creating component subobjects and attaching them to the actor's hierarchy can also be done inside of the constructor. When spawning an actor, its components will be cloned from the CDO. In order to ensure that components are always created, destroyed, and properly garbage-collected, a pointer to every component created in the constructor should be stored in a UPROPERTY of the owning class.

Modifying a component belonging to the parent class is generally not necessary. However, a current list of all attached components, including components created by the parent class, is available by calling GetAttachParent, GetParentComponents, GetNumChildrenComponents, GetChildrenComponents, and GetChildComponent on any USceneComponent, including the root component.

Metadata Specifiers

When declaring classes, Class Specifiers can be added to the declaration to control how the class behaves with various aspects of the Engine and Editor.

Class Specifier

Effect

Abstract

The Abstract Specifier declares the class as an "abstract base class", preventing the user from adding Actors of this class to Levels. This is useful for classes which are not meaningful on their own. For example, the ATriggerBase base class is abstract, while the ATriggerBox subclass is not abstract and can be placed in a Level.

AdvancedClassDisplay

The AdvancedClassDisplay Specifier forces all properties of the class to show only in the advanced sections of any details panel where they appear. To override this on an individual property, use the SimpleDisplay specifier on that property.

AutoCollapseCategories=(Category1, Category2, ...)

The AutoCollapseCategories Specifier negates the effects, for the listed categories, of the AutoExpandCategories Specifier on a parent class.

AutoExpandCategories=(Category1, Category2, ...)

Specifies one or more categories that should be automatically expanded in the Unreal Editor Property window for Objects of this class. To auto-expand variables declared with no category, use the name of the class which declares the variable.

Blueprintable

Exposes this class as an acceptable base class for creating Blueprints. The default is NotBlueprintable, unless inherited otherwise. This Specifier is inherited by subclasses.

BlueprintType

Exposes this class as a type that can be used for variables in Blueprints.

ClassGroup=GroupName

Indicates that Unreal Editor's Actor Browser should include this class and any subclass of this class within the specified GroupName when Group View is enabled in the Actor Browser.

CollapseCategories

Indicates that properties of this class should not be grouped in categories in Unreal Editor Property windows. This Specifier is propagated to child classes, and can be overridden by the DontCollapseCategories Specifier.

Config=ConfigName

Indicates that this class is allowed to store data in a configuration file (.ini). If there are any class properties declared with the config or globalconfig Specifiers, this Specifier causes those properties to be stored in the named configuration file. This Specifier is propagated to all child classes and cannot be negated, but child classes can change the config file by re-declaring the config Specifier and providing a different ConfigName. Common ConfigName values are "Engine", "Editor", "Input", and "Game".

Const

All properties and functions in this class are const and are exported as const. This Specifier is inherited by subclasses.

ConversionRoot

A root convert limits a subclass to only be able to convert to child classes of the first root class going up the hierarchy.

CustomConstructor

Prevents automatic generation of the constructor declaration.

DefaultToInstanced

All instances of this class are considered "instanced". Instanced classes (components) are duplicated upon construction. This Specifier is inherited by subclasses.

DependsOn=(ClassName1, ClassName2, ...)

All classes listed will be compiled before this class. The class names provided must indicate classes in the same (or a previous) package. Multiple dependency classes can be identified using a single DependsOn line delimited by commas, or can be specified using a separate DependsOn line for each class. This is important when a class uses a struct or enum declared in another class, as the compiler only knows what is in the classes it has already compiled.

Deprecated

This class is deprecated and Objects of this class will not be saved when serializing. This Specifier is inherited by subclasses.

DontAutoCollapseCategories=(Category, Category, ...)

Negates the AutoCollapseCategories Specifier for the listed categories inherited from a parent class.

DontCollapseCategories

Negates a CollapseCatogories Specifier inherited from a base class.

EditInlineNew

Indicates that Objects of this class can be created from the Unreal Editor Property window, as opposed to being referenced from an existing Asset. The default behavior is that only references to existing Objects may be assigned through the Property window). This Specifier is propagated to all child classes; child classes can override this with the NotEditInlineNew Specifier.

HideCategories=(Category1, Category2, ...)

Lists one or more categories that should be hidden from the user entirely. To hide properties declared with no category, use the name of the class which declares the variable. This Specifier is propagated to child classes.

HideDropdown

Prevents this class from showing up in property window combo boxes.

HideFunctions=(Category1, Category2, ...)

Hides all functions in the specified category from the user entirely.

HideFunctions=FunctionName

Hides the named functions from the user entirely.

Intrinsic

This indicates that the class was declared directly in C++, and has no boilerplate generated by Unreal Header Tool. Do not use this Specifier on new classes.

MinimalAPI

Causes only the class's type information to be exported for use by other modules. The class can be cast to, but the functions of the class cannot be called (with the exception of inline methods). This improves compile times by not exporting everything for classes that do not need all of their functions accessible in other modules.

NoExport

Indicates that this class's declaration should not be included in the automatically-generated C++ header file by the header generator. The C++ class declaration must be defined manually in a separate header file. Only valid for native classes. Do not use this for new classes.

NonTransient

Negates a Transient Specifier inherited from a base class.

NotBlueprintable

Specifies that this class is not an acceptable base class for creating Blueprints. This is the default and is inherited by subclasses.

NotPlaceable

Negates a Placeable Specifier inherited from a base class. Indicates that Objects of this class may not be placed into a Level, UI scene, or Blueprint in the Editor.

PerObjectConfig

Configuration information for this class will be stored per Object, where each object has a section in the .ini file named after the Object in the format [ObjectName ClassName]. This Specifier is propagated to child classes.

Placeable

Indicates that this class can be created in the Editor and placed into a level, UI scene, or Blueprint (depending on the class type). This flag is propagated to all child classes; child classes can override this flag using the NotPlaceable Specifier.

ShowCategories=(Category1, Category2, ...)

Negates a HideCategories Specifier (inherited from a base class) for the listed categories.

ShowFunctions=(Category1, Category2, ...)

Shows all functions within the listed categories in a property viewer.

ShowFunctions=FunctionName

Shows the named function in a property viewer.

Transient

Objects belonging to this class will never be saved to disk. This is useful in conjunction with certain kinds of native classes which are non-persistent by nature, such as players or windows. This Specifier is propagated to child classes, but can be overridden by the NonTransient Specifier.

Within=OuterClassName

Objects of this class cannot exist outside of an instance of an OuterClassName Object. This means that creating an Object of this class requires that an instance of OuterClassName is provided as its Outer Object.

Metadata Specifiers

When declaring classes, interfaces, structs, enums, enum values, functions, or properties, you can add Metadata Specifiers to control how they interact with various aspects of the engine and editor. Each type of data structure or member has its own list of Metadata Specifiers.

Metadata only exists in the editor; do not write game logic that accesses metadata.

Classes can use the following Metatag Specifiers:

Class Meta Tag

Effect

BlueprintSpawnableComponent

If present, the component Class can be spawned by a Blueprint.

BlueprintThreadSafe

Only valid on Blueprint function libraries. This specifier marks the functions in this class as callable on non-game threads in animation Blueprints.

ChildCannotTick

Used for Actor and Component classes. If the native class cannot tick, Blueprint-generated classes based on this Actor or Component can never tick, even if bCanBlueprintsTickByDefault is true.

ChildCanTick

Used for Actor and Component classes. If the native class cannot tick, Blueprint-generated classes based on this Actor or Component can have the bCanEverTick flag overridden, even if bCanBlueprintsTickByDefault is false.

DeprecatedNode

For behavior tree nodes, indicates that the class is deprecated and will display a warning when compiled.

DeprecationMessage="Message Text"

Deprecated classes with this metadata will include this text with the standard deprecation warning that Blueprint Scripts generate during compilation.

DisplayName="Blueprint Node Name"

The name of this node in a Blueprint Script will be replaced with the value provided here, instead of the code-generated name.

DontUseGenericSpawnObject

Do not spawn an Object of the class using Generic Create Object node in Blueprint Scripts; this specifier applies only to Blueprint-type classes that are neither Actors nor Actor Components.

ExposedAsyncProxy

Expose a proxy Object of this class in Async Task nodes.

IgnoreCategoryKeywordsInSubclasses

Used to make the first subclass of a class ignore all inherited ShowCategories and HideCategories Specifiers.

IsBlueprintBase="true/false"

States that this class is (or is not) an acceptable base class for creating Blueprints, similar to the Blueprintable or 'NotBlueprintable` Specifiers.

KismetHideOverrides="Event1, Event2, .."

List of Blueprint events that are not allowed to be overridden.

ProhibitedInterfaces="Interface1, Interface2, .."

Lists Interfaces that are not compatible with the class.

RestrictedToClasses="Class1, Class2, .."

Blueprint function library classes can use this to restrict usage to the classes named in the list.

ShortToolTip="Short tooltip"

A short tooltip that is used in some contexts where the full tooltip might be overwhelming, such as the Parent Class Picker dialog.

ShowWorldContextPin

Indicates that Blueprint nodes placed in graphs owned by this class must show their World context pins, even if they are normally hidden, because Objects of this class cannot be used as World context.

UsesHierarchy

Indicates the class uses hierarchical data. Used to instantiate hierarchical editing features in Details panels.

ToolTip="Hand-written tooltip"

Overrides the automatically generated tooltip from code comments.

Function Specifiers

Delegates

Gameplay Timers

UFunction Declaration

Function Specifiers

Function Parameter Specifiers

Delegates

Timers

UFunction Declaration

A UFunction is a C++ function that is recognized by the Unreal Engine reflection system. Any UObject or Blueprint function library can declare a member function as a UFunction by placing the UFUNCTION macro on the line above the function declaration in the header file. The macro will support Function Specifiers to change how Unreal Engine interprets and uses a function.

With Function Specifiers, you can expose UFunctions to Blueprint Visual Scripting graphs, which provide a way for developers to call or extend UFunctions from Blueprint Assets without having to alter C++ code. UFunctions are able to bind to Delegates in the default properties of a Class, enabling them to perform such tasks as associating actions with user inputs. They can also act as network callbacks, meaning you can use them to receive a notification and run custom code whenever a certain variable is affected by a network update. You can even create your own console commands (often called debug, configuration, or cheat code commands) that you can call from the game console in development builds, or add buttons with custom functionality to game objects in the Level Editor.

Function Specifiers

When declaring functions, Function Specifiers can be added to the declaration to control how the function behaves with various aspects of the engine and the editor.

Function Specifier

Effect

BlueprintAuthorityOnly

This function will only execute from Blueprint code if running on a machine with network authority (a server, dedicated server, or single-player game).

BlueprintCallable

The function can be executed in a Blueprint or Level Blueprint graph.

BlueprintCosmetic

This function is cosmetic and will not run on dedicated servers.

BlueprintImplementableEvent

The function can be implemented in a Blueprint or Level Blueprint graph.

BlueprintNativeEvent

This function is designed to be overridden by a Blueprint, but also has a default native implementation. Declares an additional function named the same as the main function, but with _Implementation added to the end, which is where code should be written. The autogenerated code will call the _Implementation method if no Blueprint override is found.

BlueprintPure

The function does not affect the owning object in any way and can be executed in a Blueprint or Level Blueprint graph.

CallInEditor

This function can be called in the editor on selected instances via a button in the Details panel.

Category = "TopCategory|SubCategory|Etc"

Specifies the category of the function when displayed in Blueprint editing tools. Define nested categories using the | operator.

Client

The function is only executed on the client that owns the Object on which the function is called. Declares an additional function named the same as the main function, but with _Implementation added to the end. The autogenerated code will call the _Implementation method when necessary.

CustomThunk

The UnrealHeaderTool code generator will not produce a thunk for this function; it is up to the user to provide one with the DECLARE_FUNCTION or DEFINE_FUNCTION macros.

Exec

The function can be executed from the in-game console. Exec commands only function when declared within certain Classes.

NetMulticast

The function is executed both locally on the server, and replicated to all clients, regardless of the Actor's NetOwner.

Reliable

The function is replicated over the network, and is guaranteed to arrive regardless of bandwidth or network errors. Only valid when used in conjunction with Client or Server.

SealedEvent

This function cannot be overridden in subclasses. The SealedEvent keyword can only be used for events. For non-event functions, declare them as static or final to seal them.

ServiceRequest

This function is an RPC (Remote Procedure Call) service request. This implies NetMulticast and Reliable.

ServiceResponse

This function is an RPC service response. This implies NetMulticast and Reliable.

Server

The function is only executed on the server. Declares an additional function named the same as the main function, but with _Implementation added to the end, which is where code should be written. The autogenerated code will call the _Implementation method when necessary.

Unreliable

The function is replicated over the network but can fail due to bandwidth limitations or network errors. Only valid when used in conjunction with Client or Server.

WithValidation

Declares an additional function named the same as the main function, but with _Validate added to the end. This function takes the same parameters, and returns a bool to indicate whether or not the call to the main function should proceed.

When declaring classes, interfaces, structs, enums, enum values, functions, or properties, you can add Metadata Specifiers to control how they interact with various aspects of the engine and editor. Each type of data structure or member has its own list of Metadata Specifiers.

Metadata only exists in the editor; do not write game logic that accesses metadata.

Function Meta Tag

Effect

AdvancedDisplay="Parameter1, Parameter2, .."

The comma-separated list of parameters will show up as advanced pins (requiring UI expansion).

AdvancedDisplay=N

Replace N with a number, and all parameters after the Nth will show up as advanced pins (requiring UI expansion). For example, 'AdvancedDisplay=2' will mark all but the first two parameters as advanced).

ArrayParm="Parameter1, Parameter2, .."

Indicates that a BlueprintCallable function should use a Call Array Function node and that the listed parameters should be treated as wild card array properties.

ArrayTypeDependentParams="Parameter"

When ArrayParm is used, this specifier indicates one parameter which will determine the types of all parameters in the ArrayParm list.

AutoCreateRefTerm="Parameter1, Parameter2, .."

The listed parameters, although passed by reference, will have an automatically created default if their pins are left disconnected. This is a convenience feature for Blueprints, often used on array pins.

BlueprintAutocast

Used only by static BlueprintPure functions from a Blueprint function library. A cast node will be automatically added for the return type and the type of the first parameter of the function.

BlueprintInternalUseOnly

This function is an internal implementation detail, used to implement another function or node. It is never directly exposed in a Blueprint graph.

BlueprintProtected

This function can only be called on the owning Object in a Blueprint. It cannot be called on another instance.

CallableWithoutWorldContext

Used for BlueprintCallable functions that have a WorldContext pin to indicate that the function can be called even if its Class does not implement the GetWorld function.

CommutativeAssociativeBinaryOperator

Indicates that a BlueprintCallable function should use the Commutative Associative Binary node. This node lacks pin names, but features an Add Pin button that creates additional input pins.

CompactNodeTitle="Name"

Indicates that a BlueprintCallable function should display in the compact display mode, and provides the name to display in that mode.

CustomStructureParam="Parameter1, Parameter2, .."

The listed parameters are all treated as wildcards. This specifier requires the UFUNCTION-level specifier, CustomThunk, which will require the user to provide a custom exec function. In this function, the parameter types can be checked and the appropriate function calls can be made based on those parameter types. The base UFUNCTION should never be called, and should assert or log an error if it is.

To declare a custom exec function, use the syntax DECLARE_FUNCTION(execMyFunctionName) where MyFunctionName is the name of the original function.

DefaultToSelf

For BlueprintCallable functions, this indicates that the Object property's named default value should be the self context of the node.

DeprecatedFunction

Any Blueprint references to this function will cause compilation warnings telling the user that the function is deprecated. You can add to the deprecation warning message (for example, to provide instructions on replacing the deprecated function) using the DeprecationMessage metadata specifier.

DeprecationMessage="Message Text"

If the function is deprecated, this message will be added to the standard deprecation warning when trying to compile a Blueprint that uses it.

DeterminesOutputType="Parameter"

The return type of the function will dynamically change to match the input that is connected to the named parameter pin. The parameter should be a templated type like TSubClassOf<X> or TSoftObjectPtr<X>, where the function's original return type is X* or a container with X* as the value type, such as TArray<X*>.

DevelopmentOnly

Functions marked as DevelopmentOnly will only run in Development mode. This is useful for functionality like debug output, which is expected not to exist in shipped products.

DisplayName="Blueprint Node Name"

The name of this node in a Blueprint will be replaced with the value provided here, instead of the code-generated name.

ExpandEnumAsExecs="Parameter"

For BlueprintCallable functions, this indicates that one input execution pin should be created for each entry in the enum used by the parameter. The parameter must be of an enumerated type that has the UENUM tag.

HidePin="Parameter"

For BlueprintCallable functions, this indicates that the parameter pin should be hidden from the user's view. Only one pin per function can be hidden in this manner.

HideSelfPin

Hides the "self" pin, which indicates the object on which the function is being called. The "self" pin is automatically hidden on BlueprintPure functions that are compatible with the calling Blueprint's Class. Functions that use the HideSelfPin Meta Tag frequently also use the DefaultToSelf Specifier.

InternalUseParam="Parameter"

Similar to HidePin, this hides the named parameter's pin from the user's view, and can only be used for one parameter per function.

KeyWords="Set Of Keywords"

Specifies a set of keywords that can be used when searching for this function, such as when placing a node to call the function in a Blueprint Graph.

Latent

Indicates a latent action. Latent actions have one parameter of type FLatentActionInfo, and this parameter is named by the LatentInfo specifier.

LatentInfo="Parameter"

For Latent BlueprintCallable functions, indicates which parameter is the LatentInfo parameter.

MaterialParameterCollectionFunction

For BlueprintCallable functions, indicates that the material override node should be used.

NativeBreakFunc

For BlueprintCallable functions, indicates that the function should be displayed the same way as a standard Break Struct node.

NotBlueprintThreadSafe

Only valid in Blueprint function libraries. This function will be treated as an exception to the owning Class's general BlueprintThreadSafe metadata.

ShortToolTip="Short tooltip"

A short tooltip that is used in some contexts where the full tooltip might be overwhelming, such as the Parent Class Picker dialog.

ToolTip="Hand-written tooltip

Overrides the automatically generated tooltip from code comments.

UnsafeDuringActorConstruction

This function is not safe to call during Actor construction.

WorldContext="Parameter"

Used by BlueprintCallable functions to indicate which parameter determines the World in which the operation takes place.

Function Parameter Specifiers

Parameter Specifier

Description

Out

Declares the parameter as being passed by reference, allowing it to be modified by the function.

Optional

With the optional keyword, you can make certain function parameters optional, as a convenience to the caller. The values for optional parameters which the caller does not specify depend on the function. For example, the SpawnActor function takes an optional location and rotation, which defaults to the location and rotation of the spawning Actor's root component. The default value of optional arguments can be specified by adding = [value]. For example: function myFunc(optional int x = -1). In most cases, the default value for the type of variable, or zero (0, false, "", none), is used when no value is passed to an optional parameter.

Delegates

See the Delegates page for reference and usage information.

Timers

Timers schedule actions to be performed after a delay, or over a period of time. For example, you may want to make the player invulnerable after obtaining a power-up item, then restore vulnerability after 10 seconds. Or you may want to apply damage once per second while the player moves through a room filled with toxic gas. Such actions can be achieved through the use of timers.

See the Gameplay Timers page for reference and usage information.

Metadata Specifiers

When declaring functions, Function Specifiers can be added to the declaration to control how the function behaves with various aspects of the engine and the editor.

Function Specifier

Effect

BlueprintAuthorityOnly

This function will only execute from Blueprint code if running on a machine with network authority (a server, dedicated server, or single-player game).

BlueprintCallable

The function can be executed in a Blueprint or Level Blueprint graph.

BlueprintCosmetic

This function is cosmetic and will not run on dedicated servers.

BlueprintImplementableEvent

The function can be implemented in a Blueprint or Level Blueprint graph.

BlueprintNativeEvent

This function is designed to be overridden by a Blueprint, but also has a default native implementation. Declares an additional function named the same as the main function, but with _Implementation added to the end, which is where code should be written. The autogenerated code will call the _Implementation method if no Blueprint override is found.

BlueprintPure

The function does not affect the owning object in any way and can be executed in a Blueprint or Level Blueprint graph.

CallInEditor

This function can be called in the editor on selected instances via a button in the Details panel.

Category = "TopCategory|SubCategory|Etc"

Specifies the category of the function when displayed in Blueprint editing tools. Define nested categories using the | operator.

Client

The function is only executed on the client that owns the Object on which the function is called. Declares an additional function named the same as the main function, but with _Implementation added to the end. The autogenerated code will call the _Implementation method when necessary.

CustomThunk

The UnrealHeaderTool code generator will not produce a thunk for this function; it is up to the user to provide one with the DECLARE_FUNCTION or DEFINE_FUNCTION macros.

Exec

The function can be executed from the in-game console. Exec commands only function when declared within certain Classes.

NetMulticast

The function is executed both locally on the server, and replicated to all clients, regardless of the Actor's NetOwner.

Reliable

The function is replicated over the network, and is guaranteed to arrive regardless of bandwidth or network errors. Only valid when used in conjunction with Client or Server.

SealedEvent

This function cannot be overridden in subclasses. The SealedEvent keyword can only be used for events. For non-event functions, declare them as static or final to seal them.

ServiceRequest

This function is an RPC (Remote Procedure Call) service request. This implies NetMulticast and Reliable.

ServiceResponse

This function is an RPC service response. This implies NetMulticast and Reliable.

Server

The function is only executed on the server. Declares an additional function named the same as the main function, but with _Implementation added to the end, which is where code should be written. The autogenerated code will call the _Implementation method when necessary.

Unreliable

The function is replicated over the network but can fail due to bandwidth limitations or network errors. Only valid when used in conjunction with Client or Server.

WithValidation

Declares an additional function named the same as the main function, but with _Validate added to the end. This function takes the same parameters, and returns a bool to indicate whether or not the call to the main function should proceed.

Metadata Specifiers

When declaring classes, interfaces, structs, enums, enum values, functions, or properties, you can add Metadata Specifiers to control how they interact with various aspects of the engine and editor. Each type of data structure or member has its own list of Metadata Specifiers.

Metadata only exists in the editor; do not write game logic that accesses metadata.

Function Meta Tag

Effect

AdvancedDisplay="Parameter1, Parameter2, .."

The comma-separated list of parameters will show up as advanced pins (requiring UI expansion).

AdvancedDisplay=N

Replace N with a number, and all parameters after the Nth will show up as advanced pins (requiring UI expansion). For example, 'AdvancedDisplay=2' will mark all but the first two parameters as advanced).

ArrayParm="Parameter1, Parameter2, .."

Indicates that a BlueprintCallable function should use a Call Array Function node and that the listed parameters should be treated as wild card array properties.

ArrayTypeDependentParams="Parameter"

When ArrayParm is used, this specifier indicates one parameter which will determine the types of all parameters in the ArrayParm list.

AutoCreateRefTerm="Parameter1, Parameter2, .."

The listed parameters, although passed by reference, will have an automatically created default if their pins are left disconnected. This is a convenience feature for Blueprints, often used on array pins.

BlueprintAutocast

Used only by static BlueprintPure functions from a Blueprint function library. A cast node will be automatically added for the return type and the type of the first parameter of the function.

BlueprintInternalUseOnly

This function is an internal implementation detail, used to implement another function or node. It is never directly exposed in a Blueprint graph.

BlueprintProtected

This function can only be called on the owning Object in a Blueprint. It cannot be called on another instance.

CallableWithoutWorldContext

Used for BlueprintCallable functions that have a WorldContext pin to indicate that the function can be called even if its Class does not implement the GetWorld function.

CommutativeAssociativeBinaryOperator

Indicates that a BlueprintCallable function should use the Commutative Associative Binary node. This node lacks pin names, but features an Add Pin button that creates additional input pins.

CompactNodeTitle="Name"

Indicates that a BlueprintCallable function should display in the compact display mode, and provides the name to display in that mode.

CustomStructureParam="Parameter1, Parameter2, .."

The listed parameters are all treated as wildcards. This specifier requires the UFUNCTION-level specifier, CustomThunk, which will require the user to provide a custom exec function. In this function, the parameter types can be checked and the appropriate function calls can be made based on those parameter types. The base UFUNCTION should never be called, and should assert or log an error if it is.

To declare a custom exec function, use the syntax DECLARE_FUNCTION(execMyFunctionName) where MyFunctionName is the name of the original function.

DefaultToSelf

For BlueprintCallable functions, this indicates that the Object property's named default value should be the self context of the node.

DeprecatedFunction

Any Blueprint references to this function will cause compilation warnings telling the user that the function is deprecated. You can add to the deprecation warning message (for example, to provide instructions on replacing the deprecated function) using the DeprecationMessage metadata specifier.

DeprecationMessage="Message Text"

If the function is deprecated, this message will be added to the standard deprecation warning when trying to compile a Blueprint that uses it.

DeterminesOutputType="Parameter"

The return type of the function will dynamically change to match the input that is connected to the named parameter pin. The parameter should be a templated type like TSubClassOf<X> or TSoftObjectPtr<X>, where the function's original return type is X* or a container with X* as the value type, such as TArray<X*>.

DevelopmentOnly

Functions marked as DevelopmentOnly will only run in Development mode. This is useful for functionality like debug output, which is expected not to exist in shipped products.

DisplayName="Blueprint Node Name"

The name of this node in a Blueprint will be replaced with the value provided here, instead of the code-generated name.

ExpandEnumAsExecs="Parameter"

For BlueprintCallable functions, this indicates that one input execution pin should be created for each entry in the enum used by the parameter. The parameter must be of an enumerated type that has the UENUM tag.

HidePin="Parameter"

For BlueprintCallable functions, this indicates that the parameter pin should be hidden from the user's view. Only one pin per function can be hidden in this manner.

HideSelfPin

Hides the "self" pin, which indicates the object on which the function is being called. The "self" pin is automatically hidden on BlueprintPure functions that are compatible with the calling Blueprint's Class. Functions that use the HideSelfPin Meta Tag frequently also use the DefaultToSelf Specifier.

InternalUseParam="Parameter"

Similar to HidePin, this hides the named parameter's pin from the user's view, and can only be used for one parameter per function.

KeyWords="Set Of Keywords"

Specifies a set of keywords that can be used when searching for this function, such as when placing a node to call the function in a Blueprint Graph.

Latent

Indicates a latent action. Latent actions have one parameter of type FLatentActionInfo, and this parameter is named by the LatentInfo specifier.

LatentInfo="Parameter"

For Latent BlueprintCallable functions, indicates which parameter is the LatentInfo parameter.

MaterialParameterCollectionFunction

For BlueprintCallable functions, indicates that the material override node should be used.

NativeBreakFunc

For BlueprintCallable functions, indicates that the function should be displayed the same way as a standard Break Struct node.

NotBlueprintThreadSafe

Only valid in Blueprint function libraries. This function will be treated as an exception to the owning Class's general BlueprintThreadSafe metadata.

ShortToolTip="Short tooltip"

A short tooltip that is used in some contexts where the full tooltip might be overwhelming, such as the Parent Class Picker dialog.

ToolTip="Hand-written tooltip

Overrides the automatically generated tooltip from code comments.

UnsafeDuringActorConstruction

This function is not safe to call during Actor construction.

WorldContext="Parameter"

Used by BlueprintCallable functions to indicate which parameter determines the World in which the operation takes place.

Module Creation

INI File Setup

Multiple Gameplay Modules

Limitations

In the same manner that the engine itself is composed of a collection of modules, each game is made up of one or more gameplay modules. These are similar to packages in previous versions of the engine in that they are containers for a collection of related classes. In Unreal Engine 4, since gameplay is all done in C++, modules are actually DLLs instead of proprietary package files.

If your game project is not already created, see Creating a Game Project for instructions on creating and setting up a project for your game.

Module Creation

Gameplay modules must contain, at the very least, a header file (.h), C++ file (.cpp), and a build file (*.Build.cs). The header file must be located in the Public folder of the module's directory, i.e. [GameName] \Source\ [ModuleName]\Public. This file includes any header files - including the module's auto-generated headers - necessary to compile the classes contained within the module.

The C++ file is placed in the Private folder of the module's directory, i.e. [GameName] \Source\ [ModuleName]\Private, registers and implements the module.

At least one module in your game must be registered using IMPLEMENT_PRIMARY_GAME_MODULE. Additional modules can use the alternative IMPLEMENT_GAME_MODULE method. See the Multiple Gameplay Modules section for more details on using more than one gameplay module in a game project.

The build file is placed in the root directory of the gameplay module, i.e. [GameName] \Source\ [ModuleName], and it defines certain pieces of information used by the UnrealBuildTool to compile the module.

INI File Setup

Because the new gameplay modules will have UObject code, some configuration is necessary.

The module needs to be added in several areas of the DefaultEngine.ini file:

The EditPackages array in the [UnrealEd.EditorEngine] section:

The [Launch] section:

The NativePackages array of the [/Script/Engine.UObjectPackages] section:

Multiple Gameplay Modules

There are philosophical choices about game DLL modularity. Splitting a game up into a lot of DLL files may be more trouble than it is worth, but this is a decision to be made by each individual team based on their needs and principles. Using multiple gameplay modules will result in better link times and faster code iteration, but with more modules you will need to deal with DLL exports and/or interface classes more often. This trade-off is the correct one for engine and editor code, but it is questionable for gameplay.

You can create a primary game module, then any number of additional game-specific modules. You can create *.Build.cs files for these new modules, then add references to these modules to your game's Target.cs file (OutExtraModuleNames array). Be sure to use the appropriate macro for the game modules in the C++ code. At least one module must use the `IMPLEMENT_PRIMARY_GAME_MODULE` macro, while all others should use the `IMPLEMENT_GAME_MODULE` macro. UBT should then automatically discover the modules and compile additional game DLL files.

Limitations

We do support creating modules that are cross-dependent (both export and import functions and data from each other -- e.g., Engine and UnrealEd modules), but this is not ideal for compile-times and may sometimes cause problems with static initialization of variables. Gameplay modules that are not cross-dependent are harder to design and maintain, but the code may be cleaner for it.

Interface Declaration

Interface Specifiers

Implementing Your Interface in C++

Declaring Interface Functions

C++ Only Interface Functions

Blueprint Callable Interface Functions

BlueprintCallable

BlueprintImplementableEvent

BlueprintNativeEvent

Determining If a Class Implements Your Interface

Casting To Other Unreal Types

Blueprint Implementable Classes

Interface classes are useful for ensuring that a set of (potentially) unrelated classes implement a common set of functions. This is very useful in cases where some game functionality may be shared by large, complex classes that are otherwise dissimilar. For example, a game might have a system whereby entering a trigger volume can activate traps, alert enemies, or award points to the player. This might be implemented by a "ReactToTrigger" function on traps, enemies, and point-awarders. However, traps may be derived from AActor, enemies from a specialized APawn or ACharacter subclass, and point-awards from UDataAsset. All of these classes need shared functionality, but have no common ancestor other than UObject. In this case, an interface is recommended.

Interface Declaration

Declaring an interface class is similar to declaring a normal Unreal class, but with two main differences. First, an interface class uses the UINTERFACE macro instead of the UCLASS macro, and inherits from UInterface instead of UObject directly.

Second, the UINTERFACE class is not the actual interface. It is an empty class that exists only for visibility to Unreal Engine's reflection system. The actual interface that will be inherited by other classes must have the same class name, but with the initial "U" changed to an "I".

In your .h file (e.g. ReactToTriggerInterface.h):



ReactToTriggerInterface.h



The "U-prefixed" class needs no constructor or any other functions, while the "I-prefixed" class will contain all interface functions and is the one that will actually be inherited by your other classes.

Blueprintable

Interface Specifiers

Interface Specifier

Meaning

BlueprintType

Exposes this class as a type that can be used for variables in Blueprints.

DependsOn=(ClassName1, ClassName2, ...)

All classes listed will be compiled before this class. ClassName must specify a class in the same (or a previous) package. Multiple dependency classes can be specified using a single DependsOn line delimited by commas, or can be specified using a separate DependsOn line for each class. This is important when a class uses a struct or enum declared in another class as the compiler only knows what is in the classes it has already compiled.

MinimalAPI

Causes only the class's type information to be exported for use by other modules. The class can be cast to, but the functions of the class cannot be called (with the exception of inline methods). This improves compile times by not exporting everything for classes that do not need all of their functions accessible in other modules.

Implementing Your Interface in C++

To use your interface in a new class, simply inherit from your "I-prefixed" interface class (in addition to whatever UObject-based class you are using).



Trap.h



Declaring Interface Functions

There are several methods you can use to declare functions in your interfaces, each of which is implementable or callable in different contexts. All of them must be declared in the "I-prefixed" class for your interface, and they must be public in order to be visible to outside classes.

C++ Only Interface Functions

You can declare a virtual C++ function in your interface's header file, with no UFUNCTION specifiers. These functions must be virtual so that you can override them in classes that implement your interface.



ReactToTrigger.h



You can then provide a default implementation either within the header itself or within the interface's .cpp file.

ReactToTrigger.cpp



When you implement your interface in an Actor class, you can then create and implement an override specific to that class.



Trap.h





Trap.cpp



However, these C++ interface functions will not be visible to Blueprint.

Blueprint Callable Interface Functions

To make a Blueprint callable interface function, you must provide a UFUNCTION macro in the function's declaration with the BlueprintCallable specifier. You must also use either the BlueprintImplementableEvent or BlueprintNativeEvent specifiers, and the function must not be virtual.



ReactToTrigger.h





ReactToTrigger.h



Functions using the BlueprintCallable specifier can be called in C++ or Blueprint using a reference to an object that implements the interface.

Functions using BlueprintImplementableEvent can not be overridden in C++, but can be overridden in any Blueprint class that implements or inherits your interface.

Functions using BlueprintNativeEvent can be implemented in C++ by overriding a function with the same name, but with the suffix _Implementation added to the end.



Trap.h





Trap.cpp



This specifier also allows implementations to be overridden in Blueprint.

Determining If a Class Implements Your Interface

For compatibility with both C++ and Blueprint classes that implement your interface, use any of the following functions:

If the StaticClass function is not implemented in the "I-prefixed" class, attempting to use Cast on the "U-prefixed" class will fail, and your code will not compile.

Casting To Other Unreal Types

Unreal Engine's casting system supports casting from one interface to another, or from an interface to an Unreal type, where appropriate.

Blueprint Implementable Classes

If you want Blueprints to be able to implement this interface, you must use the Blueprintable metadata specifier. Every interface function that your Blueprint class is intended to override, must be a BlueprintNativeEvent or a BlueprintImplementableEvent. Functions marked as BlueprintCallable will still be able to be called, but not overridden. All other functions will be inaccessible from Blueprints.

Class Metadata Specifiers

Enum Metadata Specifiers

Interface Metadata Specifiers

Struct Metadata Specifiers

Function Metadata Specifiers

Property Metadata Specifiers

When declaring classes, interfaces, structs, enums, enum values, functions, or properties, you can add Metadata Specifiers to control how they interact with various aspects of the engine and editor. Each type of data structure or member has its own list of Metadata Specifiers.

Metadata only exists in the editor; do not write game logic that accesses metadata.

To add Metadata Specifiers, use the word meta, followed by a list of the specifiers and, if appropriate, their values, to your UCLASS, UENUM, UINTERFACE, USTRUCT, UFUNCTION, or UPROPERTY macro, as follows:

To add Metadata Specifiers to a specific value within an enumerated type, add the UMETA tag to the value itself before the separating comma (if one exists). It should look like:

Class Metadata Specifiers

Classes can use the following Metatag Specifiers:

Class Meta Tag

Effect

BlueprintSpawnableComponent

If present, the component Class can be spawned by a Blueprint.

BlueprintThreadSafe

Only valid on Blueprint function libraries. This specifier marks the functions in this class as callable on non-game threads in animation Blueprints.

ChildCannotTick

Used for Actor and Component classes. If the native class cannot tick, Blueprint-generated classes based on this Actor or Component can never tick, even if bCanBlueprintsTickByDefault is true.

ChildCanTick

Used for Actor and Component classes. If the native class cannot tick, Blueprint-generated classes based on this Actor or Component can have the bCanEverTick flag overridden, even if bCanBlueprintsTickByDefault is false.

DeprecatedNode

For behavior tree nodes, indicates that the class is deprecated and will display a warning when compiled.

DeprecationMessage="Message Text"

Deprecated classes with this metadata will include this text with the standard deprecation warning that Blueprint Scripts generate during compilation.

DisplayName="Blueprint Node Name"

The name of this node in a Blueprint Script will be replaced with the value provided here, instead of the code-generated name.

DontUseGenericSpawnObject

Do not spawn an Object of the class using Generic Create Object node in Blueprint Scripts; this specifier applies only to Blueprint-type classes that are neither Actors nor Actor Components.

ExposedAsyncProxy

Expose a proxy Object of this class in Async Task nodes.

IgnoreCategoryKeywordsInSubclasses

Used to make the first subclass of a class ignore all inherited ShowCategories and HideCategories Specifiers.

IsBlueprintBase="true/false"

States that this class is (or is not) an acceptable base class for creating Blueprints, similar to the Blueprintable or 'NotBlueprintable` Specifiers.

KismetHideOverrides="Event1, Event2, .."

List of Blueprint events that are not allowed to be overridden.

ProhibitedInterfaces="Interface1, Interface2, .."

Lists Interfaces that are not compatible with the class.

RestrictedToClasses="Class1, Class2, .."

Blueprint function library classes can use this to restrict usage to the classes named in the list.

ShortToolTip="Short tooltip"

A short tooltip that is used in some contexts where the full tooltip might be overwhelming, such as the Parent Class Picker dialog.

ShowWorldContextPin

Indicates that Blueprint nodes placed in graphs owned by this class must show their World context pins, even if they are normally hidden, because Objects of this class cannot be used as World context.

UsesHierarchy

Indicates the class uses hierarchical data. Used to instantiate hierarchical editing features in Details panels.

ToolTip="Hand-written tooltip"

Overrides the automatically generated tooltip from code comments.

Enum Metadata Specifiers

Enumerated types can use the following Metadata Specifiers:

Enumerated Type Meta Tag

Effect

Bitflags

Indicates that this enumerated type can be used as flags by integer UPROPERTY variables that are set up with the Bitmask Metadata Specifier.

Experimental

Labels this type as experimental and unsupported.

ScriptName="Display Name"

The quoted string will be used as the name of this enumerated type in the editor, rather than the default name generated by Unreal Header Tool.

ToolTip="Hand-written tooltip"

Overrides the automatically generated tooltip from code comments.

Individual values within an enumerated type have their own Metadata Specifiers. These differ slightly from other Metadata Specifiers in that they use top-level keyword UMETA, and are specified after the value they modify, rather than before.

Enumerated Value UMeta Tag

Effect

DisplayName="Enumerated Value Name"

This value's name will be the text provided here, rather than the code-generated name.

Hidden

This value will not appear in the Editor.

ToolTip="Hand-written tooltip."

Overrides the automatically generated tooltip from code comments.

Interface Metadata Specifiers

Interfaces can use the following Metatag Specifier:

Ensure that Blueprint events are only allowed in implementable interfaces. Internal only functions allowed Ensure that if this interface contains Blueprint callable functions that are not Blueprint defined, that it must be implemented natively

Interface Meta Tag

Effect

CannotImplementInterfaceInBlueprint

This interface may not contain BlueprintImplementableEvent or BlueprintNativeEvent functions, other than internal-only functions. If it contains Blueprint-callable functions that are not blueprint-defined, those functions must be implemented in native code.

Struct Metadata Specifiers

Structs can use the following Metatag Specifiers:

Struct Meta Tag

Effect

HasNativeBreak="Module.Class.Function"

Indicates that this struct has a custom Break Struct node. The module, class, and function name must be provided.

HasNativeMake="Module.Class.Function"

Indicates that this struct has a custom Make Struct node. The module, class, and function name must be provided.

HiddenByDefault

Pins in Make Struct and Break Struct nodes are hidden by default.

ShortToolTip="Short tooltip"

A short tooltip that is used in some contexts where the full tooltip might be overwhelming, such as the Parent Class Picker dialog.

ToolTip="Hand-written tooltip

Overrides the automatically generated tooltip from code comments.

Function Metadata Specifiers

Function Meta Tag

Effect

AdvancedDisplay="Parameter1, Parameter2, .."

The comma-separated list of parameters will show up as advanced pins (requiring UI expansion).

AdvancedDisplay=N

Replace N with a number, and all parameters after the Nth will show up as advanced pins (requiring UI expansion). For example, 'AdvancedDisplay=2' will mark all but the first two parameters as advanced).

ArrayParm="Parameter1, Parameter2, .."

Indicates that a BlueprintCallable function should use a Call Array Function node and that the listed parameters should be treated as wild card array properties.

ArrayTypeDependentParams="Parameter"

When ArrayParm is used, this specifier indicates one parameter which will determine the types of all parameters in the ArrayParm list.

AutoCreateRefTerm="Parameter1, Parameter2, .."

The listed parameters, although passed by reference, will have an automatically created default if their pins are left disconnected. This is a convenience feature for Blueprints, often used on array pins.

BlueprintAutocast

Used only by static BlueprintPure functions from a Blueprint function library. A cast node will be automatically added for the return type and the type of the first parameter of the function.

BlueprintInternalUseOnly

This function is an internal implementation detail, used to implement another function or node. It is never directly exposed in a Blueprint graph.

BlueprintProtected

This function can only be called on the owning Object in a Blueprint. It cannot be called on another instance.

CallableWithoutWorldContext

Used for BlueprintCallable functions that have a WorldContext pin to indicate that the function can be called even if its Class does not implement the GetWorld function.

CommutativeAssociativeBinaryOperator

Indicates that a BlueprintCallable function should use the Commutative Associative Binary node. This node lacks pin names, but features an Add Pin button that creates additional input pins.

CompactNodeTitle="Name"

Indicates that a BlueprintCallable function should display in the compact display mode, and provides the name to display in that mode.

CustomStructureParam="Parameter1, Parameter2, .."

The listed parameters are all treated as wildcards. This specifier requires the UFUNCTION-level specifier, CustomThunk, which will require the user to provide a custom exec function. In this function, the parameter types can be checked and the appropriate function calls can be made based on those parameter types. The base UFUNCTION should never be called, and should assert or log an error if it is.

To declare a custom exec function, use the syntax DECLARE_FUNCTION(execMyFunctionName) where MyFunctionName is the name of the original function.

DefaultToSelf

For BlueprintCallable functions, this indicates that the Object property's named default value should be the self context of the node.

DeprecatedFunction

Any Blueprint references to this function will cause compilation warnings telling the user that the function is deprecated. You can add to the deprecation warning message (for example, to provide instructions on replacing the deprecated function) using the DeprecationMessage metadata specifier.

DeprecationMessage="Message Text"

If the function is deprecated, this message will be added to the standard deprecation warning when trying to compile a Blueprint that uses it.

DeterminesOutputType="Parameter"

The return type of the function will dynamically change to match the input that is connected to the named parameter pin. The parameter should be a templated type like TSubClassOf<X> or TSoftObjectPtr<X>, where the function's original return type is X* or a container with X* as the value type, such as TArray<X*>.

DevelopmentOnly

Functions marked as DevelopmentOnly will only run in Development mode. This is useful for functionality like debug output, which is expected not to exist in shipped products.

DisplayName="Blueprint Node Name"

The name of this node in a Blueprint will be replaced with the value provided here, instead of the code-generated name.

ExpandEnumAsExecs="Parameter"

For BlueprintCallable functions, this indicates that one input execution pin should be created for each entry in the enum used by the parameter. The parameter must be of an enumerated type that has the UENUM tag.

HidePin="Parameter"

For BlueprintCallable functions, this indicates that the parameter pin should be hidden from the user's view. Only one pin per function can be hidden in this manner.

HideSelfPin

Hides the "self" pin, which indicates the object on which the function is being called. The "self" pin is automatically hidden on BlueprintPure functions that are compatible with the calling Blueprint's Class. Functions that use the HideSelfPin Meta Tag frequently also use the DefaultToSelf Specifier.

InternalUseParam="Parameter"

Similar to HidePin, this hides the named parameter's pin from the user's view, and can only be used for one parameter per function.

KeyWords="Set Of Keywords"

Specifies a set of keywords that can be used when searching for this function, such as when placing a node to call the function in a Blueprint Graph.

Latent

Indicates a latent action. Latent actions have one parameter of type FLatentActionInfo, and this parameter is named by the LatentInfo specifier.

LatentInfo="Parameter"

For Latent BlueprintCallable functions, indicates which parameter is the LatentInfo parameter.

MaterialParameterCollectionFunction

For BlueprintCallable functions, indicates that the material override node should be used.

NativeBreakFunc

For BlueprintCallable functions, indicates that the function should be displayed the same way as a standard Break Struct node.

NotBlueprintThreadSafe

Only valid in Blueprint function libraries. This function will be treated as an exception to the owning Class's general BlueprintThreadSafe metadata.

ShortToolTip="Short tooltip"

A short tooltip that is used in some contexts where the full tooltip might be overwhelming, such as the Parent Class Picker dialog.

ToolTip="Hand-written tooltip

Overrides the automatically generated tooltip from code comments.

UnsafeDuringActorConstruction

This function is not safe to call during Actor construction.

WorldContext="Parameter"

Used by BlueprintCallable functions to indicate which parameter determines the World in which the operation takes place.

Property Metadata Specifiers

Property Meta Tag

Effect

AllowAbstract="true/false"

Used for Subclass and SoftClass properties. Indicates whether abstract Class types should be shown in the Class picker.

AllowedClasses="Class1, Class2, .."

Used for FSoftObjectPath properties. Comma delimited list that indicates the Class type(s) of assets to be displayed in the Asset picker.

AllowPreserveRatio

Used for FVector properties. It causes a ratio lock to be added when displaying this property in details panels.

ArrayClamp="ArrayProperty"

Used for integer properties. Clamps the valid values that can be entered in the UI to be between 0 and the length of the array property named.

AssetBundles

Used for SoftObjectPtr or SoftObjectPath properties. List of Bundle names used inside Primary Data Assets to specify which Bundles this reference is part of.

BlueprintBaseOnly

Used for Subclass and SoftClass properties. Indicates whether only Blueprint Classes should be shown in the Class picker.

BlueprintCompilerGeneratedDefaults

Property defaults are generated by the Blueprint compiler and will not be copied when the CopyPropertiesForUnrelatedObjects function is called post-compile.

ClampMin="N"

Used for float and integer properties. Specifies the minimum value N that may be entered for the property.

ClampMax="N"

Used for float and integer properties. Specifies the maximum value N that may be entered for the property.

ConfigHierarchyEditable

This property is serialized to a config (.ini) file, and can be set anywhere in the config hierarchy.

ContentDir

Used by FDirectoryPath properties. Indicates that the path will be picked using the Slate-style directory picker inside the Content folder.

DisplayAfter="PropertyName"

This property will show up in the Blueprint Editor immediately after the property named PropertyName, regardless of its order in source code, as long as both properties are in the same category. If multiple properties have the same DisplayAfter value and the same DisplayPriority value, they will appear after the named property in the order in which they are declared in the header file.

DisplayName="Property Name"

The name to display for this property, instead of the code-generated name.

DisplayPriority="N"

If two properties feature the same DisplayAfter value, or are in the same category and do not have the DisplayAfter Meta Tag, this property will determine their sorting order. The highest-priority value is 1, meaning that a property with a DisplayPriority value of 1 will appear above a property with a DisplayPriority value of 2. If multiple properties have the same DisplayAfter value, they will appear in the order in which they are declared in the header file.

DisplayThumbnail="true"

Indicates that the property is an Asset type and it should display the thumbnail of the selected Asset.

EditCondition="BooleanPropertyName"

Names a boolean property that is used to indicate whether editing of this property is disabled. Putting "!" before the property name inverts the test.

The EditCondition meta tag is no longer limited to a single boolean property. It is now evaluated using a full-fledged expression parser, meaning you can include a full C++ expression.



EditFixedOrder

Keeps the elements of an array from being reordered by dragging.

ExactClass="true"

Used for FSoftObjectPath properties in conjunction with AllowedClasses. Indicates whether only the exact Classes specified in AllowedClasses can be used, or if subclasses are also valid.

ExposeFunctionCategories="Category1, Category2, .."

Specifies a list of categories whose functions should be exposed when building a function list in the Blueprint Editor.

ExposeOnSpawn="true"

Specifies whether the property should be exposed on a Spawn Actor node for this Class type.

FilePathFilter="FileType"

Used by FFilePath properties. Indicates the path filter to display in the file picker. Common values include "uasset" and "umap", but these are not the only possible values.

GetByRef

Makes the "Get" Blueprint Node for this property return a const reference to the property instead of a copy of its value. Only usable with Sparse Class Data, and only when NoGetter is not present.

HideAlphaChannel

Used for FColor and FLinearColor properties. Indicates that the Alpha property should be hidden when displaying the property widget in the details.

HideViewOptions

Used for Subclass and SoftClass properties. Hides the ability to change view options in the Class picker.

InlineEditConditionToggle

Signifies that the boolean property is only displayed inline as an edit condition toggle in other properties, and should not be shown on its own row.

LongPackageName

Used by FDirectoryPath properties. Converts the path to a long package name.

MakeEditWidget

Used for Transform or Rotator properties, or Arrays of Transforms or Rotators. Indicates that the property should be exposed in the viewport as a movable widget.

NoGetter

Causes Blueprint generation not to generate a "get" Node for this property. Only usable with Sparse Class Data.

Property Declaration

Core Data Types

Integers

As Bitmasks

Floating Point Types

Boolean Types

Strings

Property Specifiers

Property Declaration

Properties are declared using standard C++ variable syntax, preceded by the UPROPERTY macro which defines property metadata and variable specifiers.

Core Data Types

Integers

The convention for integral data types is "int" or "uint" followed by the size in bits.

Variable Type

Description

uint8

8-bit unsigned

uint16

16-bit unsigned

uint32

32-bit unsigned

uint64

64-bit unsigned

int8

8-bit signed

int16

16-bit signed

int32

32-bit signed

int64

64-bit signed

Integer properties can now be exposed to the Editor as bitmasks. To mark an integer property as a bitmask, just add "bitmask" to the meta section, as follows:

Adding this meta tag will cause the integer to be editable as a drop-down list of generically-named flags ("Flag 1", "Flag 2", "Flag 3", etc.) that can be turned on or off individually.



You can also make integer parameters to Blueprint-callable functions behave as bitmasks, by adding the Bitmask meta tag (no value necessary) to a UPARAM Specifier for the parameter.

In order to customize the bitflags' names, we must first create a UENUM with the "bitflags" meta tag:

The supported value range for a bitmask enumerated type is 0 to 31, inclusive. This corresponds to the bits (starting at bit 0) of a 32-bit integer variable. In the example above, bit 0 is ECB_Red, bit 1 is ECB_Green, and bit 2 is ECB_Blue.

As an alternate declaration style, you can use the ENUM_CLASS_FLAGS to turn your enumerated type into a bitmask after defining it. In order to use the flag selector in the editor, we must also add the meta field UseEnumValuesAsMaskValuesInEditor and set it to true. The key difference is that this method uses the mask values directly, instead of the bit numbers. The equivalent enumerated type, made using this method, would look like this:

After creating this UENUM, we can reference it with the "BitmaskEnum" meta tag, like this:

Following this change, the bitflags listed in the drop-down box will take on the names and values of the enumerated class entries. In the example above, ECB_Red is value 0, meaning it will activate bit 0 (adding 1 to ColorFlags) when checked. ECB_Green corresponds to bit 1 (adding 2 to ColorFlags), and ECB_Blue corresponds to bit 2 (adding 4 to ColorFlags).



Similarly, you can add BitmaskEnum and the appropriate enumerated type name to the meta section of your UPARAM tag to customize it.

While enumerated types can contain more than 32 entries, only the first 32 values will be visible in a bitmask association in the Property Editor UI. Similarly, while explicit-value entries are accepted, entries with explicit values not between 0 and 31 will not be included in the drop-down.

Floating Point Types

Unreal uses the standard C++ floating point types, float, and double.

Boolean Types

Boolean types can be represented either with the C++ bool keyword or as a bitfield.

Strings

Unreal Engine 4 supports three core types of strings.

FString is a classic "dynamic array of chars" string type.

FName is a reference to an immutable case-insensitive string in a global string table. It is smaller and more efficient to pass around than an FString, but more difficult to manipulate.

FText is a more robust string representation designed to handle localization.

For most uses, Unreal relies on the TCHAR type for characters. The TEXT() macro is available to denote TCHAR literals.

For more on the three string types, when to use each one, and how to work with them, see the String Handling documentation.

Property Specifiers

When declaring properties, Property Specifiers can be added to the declaration to control how the property behaves with various aspects of the Engine and Editor.

Property Tag

Effect

AdvancedDisplay

The property will be placed in the advanced (dropdown) section of any panel where it appears.

AssetRegistrySearchable

The AssetRegistrySearchable Specifier indicates that this property and its value will be automatically added to the Asset Registry for any Asset class instances containing this as a member variable. It is not legal to use struct properties or parameters.

BlueprintAssignable

Usable with Multicast Delegates only. Exposes the property for assigning in Blueprints.

BlueprintAuthorityOnly

This property must be a Multicast Delegate. In Blueprints, it will only accept events tagged with BlueprintAuthorityOnly.

BlueprintCallable

Multicast Delegates only. Property should be exposed for calling in Blueprint code.

BlueprintGetter=GetterFunctionName

This property specifies a custom accessor function. If this property isn't also tagged with BlueprintSetter or BlueprintReadWrite, then it is implicitly BlueprintReadOnly.

BlueprintReadOnly

This property can be read by Blueprints, but not modified. This Specifier is incompatible with the BlueprintReadWrite Specifier.

BlueprintReadWrite

This property can be read or written from a Blueprint. This Specifier is incompatible with the BlueprintReadOnly Specifier.

BlueprintSetter=SetterFunctionName

This property has a custom mutator function, and is implicitly tagged with BlueprintReadWrite. Note that the mutator function must be named and part of the same class.

Category="TopCategory|SubCategory|..."

Specifies the category of the property when displayed in Blueprint editing tools. Define nested categories using the | operator.

Config

This property will be made configurable. The current value can be saved to the .ini file associated with the class and will be loaded when created. Cannot be given a value in default properties. Implies BlueprintReadOnly.

DuplicateTransient

Indicates that the property's value should be reset to the class default value during any type of duplication (copy/paste, binary duplication, etc.).

EditAnywhere

Indicates that this property can be edited by property windows, on archetypes and instances. This Specifier is incompatible with any of the "Visible" Specifiers.

EditDefaultsOnly

Indicates that this property can be edited by property windows, but only on archetypes. This Specifier is incompatible with any of the "Visible" Specifiers.

EditFixedSize

Only useful for dynamic arrays. This will prevent the user from changing the length of an array via the Unreal Editor property window.

EditInline

Allows the user to edit the properties of the Object referenced by this property within Unreal Editor's property inspector (only useful for Object references, including arrays of Object reference).

EditInstanceOnly

Indicates that this property can be edited by property windows, but only on instances, not on archetypes. This Specifier is incompatible with any of the "Visible" Specifiers.

Export

Only useful for Object properties (or arrays of Objects). Indicates that the Object assigned to this property should be exported in its entirety as a subobject block when the Object is copied (such as for copy/paste operations), as opposed to just outputting the Object reference itself.

GlobalConfig

Works just like Config except that you cannot override it in a subclass. Cannot be given a value in default properties. Implies BlueprintReadOnly.

Instanced

Object (UCLASS) properties only. When an instance of this class is created, it will be given a unique copy of the Object assigned to this property in defaults. Used for instancing subobjects defined in class default properties. Implies EditInline and Export.

Interp

Indicates that the value can be driven over time by a Track in Sequencer.

Localized

The value of this property will have a localized value defined. Mostly used for strings. Implies ReadOnly.

Native

Property is native: C++ code is responsible for serializing it and exposing it to Garbage Collection.

NoClear

Prevents this Object reference from being set to none from the editor. Hides the clear (and browse) button in the editor.

NoExport

Only useful for native classes. This property should not be included in the auto-generated class declaration.

NonPIEDuplicateTransient

The property will be reset to the default value during duplication, except if it's being duplicated for a Play In Editor (PIE) session.

NonTransactional

Indicates that changes to this property's value will not be included in the editor's undo/redo history.

NotReplicated

Skip replication. This only applies to struct members and parameters in service request functions.

Replicated

The property should be replicated over the network.

ReplicatedUsing=FunctionName

The ReplicatedUsing Specifier specifies a callback function which is executed when the property is updated over the network.

RepRetry

Only useful for struct properties. Retry replication of this property if it fails to be fully sent (for example, Object references not yet available to serialize over the network). For simple references, this is the default, but for structs, this is often undesirable due to the bandwidth cost, so it is disabled unless this flag is specified.

SaveGame

This Specifier is a simple way to include fields explicitly for a checkpoint/save system at the property level. The flag should be set on all fields that are intended to be part of a saved game, and then a proxy archiver can be used to read/write it.

SerializeText

Native property should be serialized as text (ImportText, ExportText).

SkipSerialization

This property will not be serialized, but can still be exported to a text format (such as for copy/paste operations).

SimpleDisplay

Visible or editable properties appear in the Details panel and are visible without opening the "Advanced" section.

TextExportTransient

This property will not be exported to a text format (so it cannot, for example, be used in copy/paste operations).

Transient

Property is transient, meaning it will not be saved or loaded. Properties tagged this way will be zero-filled at load time.

VisibleAnywhere

Indicates that this property is visible in all property windows, but cannot be edited. This Specifier is incompatible with the "Edit" Specifiers.

VisibleDefaultsOnly

Indicates that this property is only visible in property windows for archetypes, and cannot be edited. This Specifier is incompatible with any of the "Edit" Specifiers.

VisibleInstanceOnly

Indicates that this property is only visible in property windows for instances, not for archetypes, and cannot be edited. This Specifier is incompatible with any of the "Edit" Specifiers.

When declaring classes, interfaces, structs, enums, enum values, functions, or properties, you can add Metadata Specifiers to control how they interact with various aspects of the engine and editor. Each type of data structure or member has its own list of Metadata Specifiers.

Metadata only exists in the editor; do not write game logic that accesses metadata.

Property Meta Tag

Effect

AllowAbstract="true/false"

Used for Subclass and SoftClass properties. Indicates whether abstract Class types should be shown in the Class picker.

AllowedClasses="Class1, Class2, .."

Used for FSoftObjectPath properties. Comma delimited list that indicates the Class type(s) of assets to be displayed in the Asset picker.

AllowPreserveRatio

Used for FVector properties. It causes a ratio lock to be added when displaying this property in details panels.

ArrayClamp="ArrayProperty"

Used for integer properties. Clamps the valid values that can be entered in the UI to be between 0 and the length of the array property named.

AssetBundles

Used for SoftObjectPtr or SoftObjectPath properties. List of Bundle names used inside Primary Data Assets to specify which Bundles this reference is part of.

BlueprintBaseOnly

Used for Subclass and SoftClass properties. Indicates whether only Blueprint Classes should be shown in the Class picker.

BlueprintCompilerGeneratedDefaults

Property defaults are generated by the Blueprint compiler and will not be copied when the CopyPropertiesForUnrelatedObjects function is called post-compile.

ClampMin="N"

Used for float and integer properties. Specifies the minimum value N that may be entered for the property.

ClampMax="N"

Used for float and integer properties. Specifies the maximum value N that may be entered for the property.

ConfigHierarchyEditable

This property is serialized to a config (.ini) file, and can be set anywhere in the config hierarchy.

ContentDir

Used by FDirectoryPath properties. Indicates that the path will be picked using the Slate-style directory picker inside the Content folder.

DisplayAfter="PropertyName"

This property will show up in the Blueprint Editor immediately after the property named PropertyName, regardless of its order in source code, as long as both properties are in the same category. If multiple properties have the same DisplayAfter value and the same DisplayPriority value, they will appear after the named property in the order in which they are declared in the header file.

DisplayName="Property Name"

The name to display for this property, instead of the code-generated name.

DisplayPriority="N"

If two properties feature the same DisplayAfter value, or are in the same category and do not have the DisplayAfter Meta Tag, this property will determine their sorting order. The highest-priority value is 1, meaning that a property with a DisplayPriority value of 1 will appear above a property with a DisplayPriority value of 2. If multiple properties have the same DisplayAfter value, they will appear in the order in which they are declared in the header file.

DisplayThumbnail="true"

Indicates that the property is an Asset type and it should display the thumbnail of the selected Asset.

EditCondition="BooleanPropertyName"

Names a boolean property that is used to indicate whether editing of this property is disabled. Putting "!" before the property name inverts the test.

The EditCondition meta tag is no longer limited to a single boolean property. It is now evaluated using a full-fledged expression parser, meaning you can include a full C++ expression.



EditFixedOrder

Keeps the elements of an array from being reordered by dragging.

ExactClass="true"

Used for FSoftObjectPath properties in conjunction with AllowedClasses. Indicates whether only the exact Classes specified in AllowedClasses can be used, or if subclasses are also valid.

ExposeFunctionCategories="Category1, Category2, .."

Specifies a list of categories whose functions should be exposed when building a function list in the Blueprint Editor.

ExposeOnSpawn="true"

Specifies whether the property should be exposed on a Spawn Actor node for this Class type.

FilePathFilter="FileType"

Used by FFilePath properties. Indicates the path filter to display in the file picker. Common values include "uasset" and "umap", but these are not the only possible values.

GetByRef

Makes the "Get" Blueprint Node for this property return a const reference to the property instead of a copy of its value. Only usable with Sparse Class Data, and only when NoGetter is not present.

HideAlphaChannel

Used for FColor and FLinearColor properties. Indicates that the Alpha property should be hidden when displaying the property widget in the details.

HideViewOptions

Used for Subclass and SoftClass properties. Hides the ability to change view options in the Class picker.

InlineEditConditionToggle

Signifies that the boolean property is only displayed inline as an edit condition toggle in other properties, and should not be shown on its own row.

LongPackageName

Used by FDirectoryPath properties. Converts the path to a long package name.

MakeEditWidget

Used for Transform or Rotator properties, or Arrays of Transforms or Rotators. Indicates that the property should be exposed in the viewport as a movable widget.

NoGetter

Causes Blueprint generation not to generate a "get" Node for this property. Only usable with Sparse Class Data.

Metadata Specifiers

When declaring properties, Property Specifiers can be added to the declaration to control how the property behaves with various aspects of the Engine and Editor.

Property Tag

Effect

AdvancedDisplay

The property will be placed in the advanced (dropdown) section of any panel where it appears.

AssetRegistrySearchable

The AssetRegistrySearchable Specifier indicates that this property and its value will be automatically added to the Asset Registry for any Asset class instances containing this as a member variable. It is not legal to use struct properties or parameters.

BlueprintAssignable

Usable with Multicast Delegates only. Exposes the property for assigning in Blueprints.

BlueprintAuthorityOnly

This property must be a Multicast Delegate. In Blueprints, it will only accept events tagged with BlueprintAuthorityOnly.

BlueprintCallable

Multicast Delegates only. Property should be exposed for calling in Blueprint code.

BlueprintGetter=GetterFunctionName

This property specifies a custom accessor function. If this property isn't also tagged with BlueprintSetter or BlueprintReadWrite, then it is implicitly BlueprintReadOnly.

BlueprintReadOnly

This property can be read by Blueprints, but not modified. This Specifier is incompatible with the BlueprintReadWrite Specifier.

BlueprintReadWrite

This property can be read or written from a Blueprint. This Specifier is incompatible with the BlueprintReadOnly Specifier.

BlueprintSetter=SetterFunctionName

This property has a custom mutator function, and is implicitly tagged with BlueprintReadWrite. Note that the mutator function must be named and part of the same class.

Category="TopCategory|SubCategory|..."

Specifies the category of the property when displayed in Blueprint editing tools. Define nested categories using the | operator.

Config

This property will be made configurable. The current value can be saved to the .ini file associated with the class and will be loaded when created. Cannot be given a value in default properties. Implies BlueprintReadOnly.

DuplicateTransient

Indicates that the property's value should be reset to the class default value during any type of duplication (copy/paste, binary duplication, etc.).

EditAnywhere

Indicates that this property can be edited by property windows, on archetypes and instances. This Specifier is incompatible with any of the "Visible" Specifiers.

EditDefaultsOnly

Indicates that this property can be edited by property windows, but only on archetypes. This Specifier is incompatible with any of the "Visible" Specifiers.

EditFixedSize

Only useful for dynamic arrays. This will prevent the user from changing the length of an array via the Unreal Editor property window.

EditInline

Allows the user to edit the properties of the Object referenced by this property within Unreal Editor's property inspector (only useful for Object references, including arrays of Object reference).

EditInstanceOnly

Indicates that this property can be edited by property windows, but only on instances, not on archetypes. This Specifier is incompatible with any of the "Visible" Specifiers.

Export

Only useful for Object properties (or arrays of Objects). Indicates that the Object assigned to this property should be exported in its entirety as a subobject block when the Object is copied (such as for copy/paste operations), as opposed to just outputting the Object reference itself.

GlobalConfig

Works just like Config except that you cannot override it in a subclass. Cannot be given a value in default properties. Implies BlueprintReadOnly.

Instanced

Object (UCLASS) properties only. When an instance of this class is created, it will be given a unique copy of the Object assigned to this property in defaults. Used for instancing subobjects defined in class default properties. Implies EditInline and Export.

Interp

Indicates that the value can be driven over time by a Track in Sequencer.

Localized

The value of this property will have a localized value defined. Mostly used for strings. Implies ReadOnly.

Native

Property is native: C++ code is responsible for serializing it and exposing it to Garbage Collection.

NoClear

Prevents this Object reference from being set to none from the editor. Hides the clear (and browse) button in the editor.

NoExport

Only useful for native classes. This property should not be included in the auto-generated class declaration.

NonPIEDuplicateTransient

The property will be reset to the default value during duplication, except if it's being duplicated for a Play In Editor (PIE) session.

NonTransactional

Indicates that changes to this property's value will not be included in the editor's undo/redo history.

NotReplicated

Skip replication. This only applies to struct members and parameters in service request functions.

Replicated

The property should be replicated over the network.

ReplicatedUsing=FunctionName

The ReplicatedUsing Specifier specifies a callback function which is executed when the property is updated over the network.

RepRetry

Only useful for struct properties. Retry replication of this property if it fails to be fully sent (for example, Object references not yet available to serialize over the network). For simple references, this is the default, but for structs, this is often undesirable due to the bandwidth cost, so it is disabled unless this flag is specified.

SaveGame

This Specifier is a simple way to include fields explicitly for a checkpoint/save system at the property level. The flag should be set on all fields that are intended to be part of a saved game, and then a proxy archiver can be used to read/write it.

SerializeText

Native property should be serialized as text (ImportText, ExportText).

SkipSerialization

This property will not be serialized, but can still be exported to a text format (such as for copy/paste operations).

SimpleDisplay

Visible or editable properties appear in the Details panel and are visible without opening the "Advanced" section.

TextExportTransient

This property will not be exported to a text format (so it cannot, for example, be used in copy/paste operations).

Transient

Property is transient, meaning it will not be saved or loaded. Properties tagged this way will be zero-filled at load time.

VisibleAnywhere

Indicates that this property is visible in all property windows, but cannot be edited. This Specifier is incompatible with the "Edit" Specifiers.

VisibleDefaultsOnly

Indicates that this property is only visible in property windows for archetypes, and cannot be edited. This Specifier is incompatible with any of the "Edit" Specifiers.

VisibleInstanceOnly

Indicates that this property is only visible in property windows for instances, not for archetypes, and cannot be edited. This Specifier is incompatible with any of the "Edit" Specifiers.

Metadata Specifiers

When declaring classes, interfaces, structs, enums, enum values, functions, or properties, you can add Metadata Specifiers to control how they interact with various aspects of the engine and editor. Each type of data structure or member has its own list of Metadata Specifiers.

Metadata only exists in the editor; do not write game logic that accesses metadata.

Property Meta Tag

Effect

AllowAbstract="true/false"

Used for Subclass and SoftClass properties. Indicates whether abstract Class types should be shown in the Class picker.

AllowedClasses="Class1, Class2, .."

Used for FSoftObjectPath properties. Comma delimited list that indicates the Class type(s) of assets to be displayed in the Asset picker.

AllowPreserveRatio

Used for FVector properties. It causes a ratio lock to be added when displaying this property in details panels.

ArrayClamp="ArrayProperty"

Used for integer properties. Clamps the valid values that can be entered in the UI to be between 0 and the length of the array property named.

AssetBundles

Used for SoftObjectPtr or SoftObjectPath properties. List of Bundle names used inside Primary Data Assets to specify which Bundles this reference is part of.

BlueprintBaseOnly

Used for Subclass and SoftClass properties. Indicates whether only Blueprint Classes should be shown in the Class picker.

BlueprintCompilerGeneratedDefaults

Property defaults are generated by the Blueprint compiler and will not be copied when the CopyPropertiesForUnrelatedObjects function is called post-compile.

ClampMin="N"

Used for float and integer properties. Specifies the minimum value N that may be entered for the property.

ClampMax="N"

Used for float and integer properties. Specifies the maximum value N that may be entered for the property.

ConfigHierarchyEditable

This property is serialized to a config (.ini) file, and can be set anywhere in the config hierarchy.

ContentDir

Used by FDirectoryPath properties. Indicates that the path will be picked using the Slate-style directory picker inside the Content folder.

DisplayAfter="PropertyName"

This property will show up in the Blueprint Editor immediately after the property named PropertyName, regardless of its order in source code, as long as both properties are in the same category. If multiple properties have the same DisplayAfter value and the same DisplayPriority value, they will appear after the named property in the order in which they are declared in the header file.

DisplayName="Property Name"

The name to display for this property, instead of the code-generated name.

DisplayPriority="N"

If two properties feature the same DisplayAfter value, or are in the same category and do not have the DisplayAfter Meta Tag, this property will determine their sorting order. The highest-priority value is 1, meaning that a property with a DisplayPriority value of 1 will appear above a property with a DisplayPriority value of 2. If multiple properties have the same DisplayAfter value, they will appear in the order in which they are declared in the header file.

DisplayThumbnail="true"

Indicates that the property is an Asset type and it should display the thumbnail of the selected Asset.

EditCondition="BooleanPropertyName"

Names a boolean property that is used to indicate whether editing of this property is disabled. Putting "!" before the property name inverts the test.

The EditCondition meta tag is no longer limited to a single boolean property. It is now evaluated using a full-fledged expression parser, meaning you can include a full C++ expression.



EditFixedOrder

Keeps the elements of an array from being reordered by dragging.

ExactClass="true"

Used for FSoftObjectPath properties in conjunction with AllowedClasses. Indicates whether only the exact Classes specified in AllowedClasses can be used, or if subclasses are also valid.

ExposeFunctionCategories="Category1, Category2, .."

Specifies a list of categories whose functions should be exposed when building a function list in the Blueprint Editor.

ExposeOnSpawn="true"

Specifies whether the property should be exposed on a Spawn Actor node for this Class type.

FilePathFilter="FileType"

Used by FFilePath properties. Indicates the path filter to display in the file picker. Common values include "uasset" and "umap", but these are not the only possible values.

GetByRef

Makes the "Get" Blueprint Node for this property return a const reference to the property instead of a copy of its value. Only usable with Sparse Class Data, and only when NoGetter is not present.

HideAlphaChannel

Used for FColor and FLinearColor properties. Indicates that the Alpha property should be hidden when displaying the property widget in the details.

HideViewOptions

Used for Subclass and SoftClass properties. Hides the ability to change view options in the Class picker.

InlineEditConditionToggle

Signifies that the boolean property is only displayed inline as an edit condition toggle in other properties, and should not be shown on its own row.

LongPackageName

Used by FDirectoryPath properties. Converts the path to a long package name.

MakeEditWidget

Used for Transform or Rotator properties, or Arrays of Transforms or Rotators. Indicates that the property should be exposed in the viewport as a movable widget.

NoGetter

Causes Blueprint generation not to generate a "get" Node for this property. Only usable with Sparse Class Data.

Structs are data structures that help you organize and manipulate related properties. In the Unreal Engine, they're recognized by the Engine's reflection system, but are not part of the UObject ecosystem. As a result, they are faster to create than a UObject with the same data layout, and support UProperties, but will not be managed by the Garbage Collection system and cannot provide UFunctions. Keep in mind that UStructs cannot be used inside classes.

To make a struct into a UStruct, use the USTRUCT tag above the struct's definition, and include GENERATED_BODY() as the first line within the definition, as follows:

1 - Place Cameras in the World

2 - Control Camera View in C++

3 - Place a Camera Director in the World

4 - On Your Own!

This tutorial will show you how to activate a camera, and change your active camera from one to another.

1 - Place Cameras in the World

If you are new to Unreal Engine, you might want to read our Programming Quick Start first. For this tutorial, we will assume you are familiar with creating a project, adding C++ code to it, compiling your code, and adding Components to Actors in Unreal Engine.

We will begin by creating a new Basic Code project, with starter content, named "HowTo_AutoCamera". The first thing we'll need to do is create two cameras in our world. Since there are multiple ways to set up cameras, we'll go with the two most common ways here. For our first camera, go to the Place Actors panel and select the All Classes tab, you'll find a Camera actor. Drag this into the Level Editor and position it so that it has a good view of our scene.



When this is done, the Level Editor window will have a picture-in-picture view of what our new Camera Actor can see as long as we have the Camera Actor selected.



For our second camera, we'll use a method that goes a little more in-depth and gives us a little more control. Start by clicking the Basic tab in the Place Actors panel, then drag a Cube into the Level Editor window.



We can use almost any actor class for this step. The MyActor class we created in the Quick Start tutorial might be interesting to substitute for the Cube.

When our Cube actor is placed, add a CameraComponent by clicking the + Add Component button in the Details panel for the Cube. You can now set the position and rotation of that CameraComponent to give us a different view of the scene than the CameraActor we placed earlier.



We should customize our CameraComponent by turning on Constrain Aspect Ratio so that it matches the setting on our CameraActor. This will make transitions between camera views smoother, but it is not required.



With our world set up, we're now ready to create the class that will control our camera view.

2 - Control Camera View in C++

We're ready to create a C++ class to control our camera view. For this tutorial, we can extend Actor into a new class which we'll call CameraDirector.



In CameraDirector.h, add the following code to the bottom of the ACameraDirector class definition:

The UPROPERTY macro makes our variables visible to Unreal Engine. This way, values set in these variables will not be reset when we launch the game or reload our level or project in a future work session. We have also added the EditAnywhere keyword, which will allow us to set CameraOne and CameraTwo in the Unreal Editor.

In CameraDirector.cpp, add the following line of code to the top of the file, right underneath the other #include lines:

The GameplayStatics header file gives us access to some useful general-purpose functions, one of which we will need for this tutorial. When that is done, add the following code to the bottom of ACameraDirector::Tick:

This code will cause us to switch the default player's view between two different cameras every three seconds.

Our code is now ready to be compiled, so we can return to the Unreal Editor and press the Compile button.

No further code is needed. We can set up our CameraDirector in our world now.

Finished Code

CameraDirector.h

CameraDirector.cpp

3 - Place a Camera Director in the World

Once our code has compiled, we can drag an instance of our new class from the Content Browser into the Level Editor.



Next, we'll need to set the CameraOne and CameraTwo variables. Find our CameraDirector in the World Outliner and edit it in the Details Panel.



Click on the dropdown boxes labeled "None" and set our variables to the Cube and the CameraActor that we created earlier.



If we press Play, we will see the camera snap to this view:



And then blend smoothly to this view:



Where it will wait a few seconds before snapping back.

We now have a system that moves the player's camera based purely on game logic. This code can be modified for use in any game where the player does not have direct control over the camera, or where blending between camera views is useful.

Finished Code

CameraDirector.h

CameraDirector.cpp

4 - On Your Own!

Using what you have learned, try to do the following:

Attach a Camera to a moving Actor to create a crane or dolly shot.

Use a single Array variable to store your cameras, instead of CameraOne and CameraTwo, so you can go through a sequence of any number of cameras, instead of just two.

Instead of using



As for the specifics covered in this tutorial:

For more information on Cameras and ways to control them, see the Camera framework page, or try the Player-Controlled Cameras tutorial.

For further tutorials, see the C++ Programming Tutorials page.

1. Creating and Attaching Components

Work-In-Progress Code

2. Configuring Input and Creating a Pawn Movement Component

3. Coding Our Pawn Movement Component's Behavior

Work-In-Progress Code

4. Using Our Pawn and Components Together

Finished Code

5. Playing in Editor

6. On Your Own!

This tutorial will show you how to create Components, put them into a hierarchy, control them during gameplay, and use them to move your Pawn around a world that contains solid objects.

1. Creating and Attaching Components

If you are new to Unreal Engine, you might want to read our Programming Quick Start first. For this tutorial, it is assumed that you are familiar with creating a project and adding C++ code to it, as well as configuring input in Unreal Editor.

If you are unfamiliar with creating your own Pawn class or configuring input, the Player Input tutorial might be a good place to start.

Begin by creating a new C++ project with starter content, named HowTo_Components. The first thing we need to add to this project is a customized Pawn that will hold our Components, move around our level, and collide with solid objects. For this tutorial, name it CollidingPawn.





In your code editor (usually Visual Studio or Xcode), open CollidingPawn.h and add the following code to the bottom of our class definition:

This variable keeps track of a Particle System Component that we will create later. We can create Components without making variables to track them, but if we want to use those Components in our code, we should store them in class member variables.

We can now open CollidingPawn.cpp and edit the constructor function, ACollidingPawn::ACollidingPawn, by adding code that will spawn a variety of useful Components and arrange them in a hierarchy. We will create a Sphere Component to interact with the physical world, a Static Mesh Component to represent our collision shape visually, a Particle System Component that we can turn on or off at will, and a Spring Arm Component that we can use to attach a Camera Component to control our in-game perspective. Before we do that, we should include the header files that we will eventually need to use these Components. Underneath the line that includes the class header file, we can add:

Decide which Component will be the root of the hierarchy. In this tutorial, we use the Sphere Component, since it is the physical presence that can interact and collide with our game world. An Actor can have multiple physics-enabled Components in its hierarchy, but for this tutorial, we only need one.

Next, we will create and attach a visible sphere from a Static Mesh Asset that has a radius of 50. Since this doesn't perfectly line up with the 40-radius Sphere Component we just created, scale it down to 80%. We also need to move it down by 40 units in order to have its center line up with the center of the Sphere Component.

Hard-coding Asset paths, like the Static Mesh for the sphere in this example, is not generally considered a best practice; we would usually create the Component in the constructor, make it editable, then create a Blueprint Asset in Unreal Editor and set up the Static Mesh Asset there. However, it is possible to do this directly in code, and could be faster for programmers debugging or building new features.

We can now attach an inactive Particle System Component to our hierarchy. We can manipulate this Component in code, and will later set up an input to turn it on or off. Notice that the Particle System Component is attached directly to the Static Mesh Component, not to the root. It is also slightly offset from the bottom-center of the mesh so that it will be more visible during play.

A Spring Arm Component can provide a smoother attachment point for our camera by allowing our camera to accelerate and decelerate more slowly than the Pawn it is following. It also has a built-in feature that prevents the camera from going through solid objects, for situations such as when a player backs into a corner in a third-person game. While it isn't necessary, the Spring Arm Component can be a very fast and easy way to get smoother camera work into a game.

The actual Camera Component is easy to create, and doesn't require any special settings for our use case. The Spring Arm Component has a special built-in socket that we can attach to, rather than attaching directly to the Component's base.

Now that our Components are created and attached, we should set this Pawn to be controlled by the default player. The following code is all we need:

Our new Pawn now has a collection of useful Components attached to it, and is ready to be configured for user control. We can now return to Unreal Editor.

Work-In-Progress Code

CollidingPawn.h

CollidingPawn.cpp

2. Configuring Input and Creating a Pawn Movement Component

Returning to Unreal Editor, it's time to configure our project's input settings. These settings can be found under Project Settings in the Edit dropdown menu.



Once there, we can select Input from the Engine section in the left panel. We will need an Action Mapping to set up our particle-system toggle, two Axis Mappings to move our Pawn, and one more Axis Mapping to turn our Pawn.

Action Mapping

ParticleToggle

Space Bar

Axis Mapping

MoveForward

W

1.0

S

-1.0

MoveRight

A

-1.0

D

1.0

Turn

Mouse X

1.0



Instead of handling all our movement in our Pawn class directly, we will create a Movement Component to manage it for us. For this tutorial, we'll extend the Pawn Movement Component class. We'll start by selecting the Add Code to Project command from the File dropdown menu.



Unlike our Pawn class, Pawn Movement Component is not visible by default. To find it, we need to check the Show All Classes option.



Typing "movement" into the search bar can help narrow the list quickly.



Pawn Movement Components have some powerful, built-in features to help with common physics functionality, and are a good way to share movement code between many Pawn types. Using Components to separate functionality is a good practice to reduce clutter as your project grows and your Pawns become more complex.

Since we called our Pawn class CollidingPawn, let's call this CollidingPawnMovementComponent.



We have just defined our input configuration and created a custom Pawn Movement Component. We're ready to go back to our code editor and write code to define how Pawns will move when our Pawn Movement Component is in use.

3. Coding Our Pawn Movement Component's Behavior

We can go back to our code editor now and program our customized Pawn Movement Component. All we really need to write is a TickComponent function (similar to an Actor's Tick function) to tell us how to move each frame. In CollidingPawnMovementComponent.h, we'll need to override TickComponent in the class definition:

We'll define this function in CollidingPawnMovementComponent.cpp:

This code will move our Pawn smoothly around the world, sliding off of surfaces where appropriate. There is no gravity applied to our Pawn, and its maximum speed is hard-coded to 150 Unreal Units per second.

This TickComponent function makes use of a few of the powerful features offered by the UPawnMovementComponent class.

ConsumeInputVector reports and clears the value of a built-in variable that we will use to store our movement inputs.

`SafeMoveUpdatedComponent uses Unreal Engine physics to move our Pawn Movement Component while respecting solid barriers.

SlideAlongSurface handles the calculations and physics involved with sliding smoothly along collision surfaces like walls and ramps when a move results in a collision, rather than simply stopping in place and sticking to the wall or ramp.

There are more features included in Pawn Movement Components that are worthy of examination, but they are not needed for the scope of this tutorial. Looking at other classes, such as Floating Pawn Movement, Spectator Pawn Movement, or Character Movement Component, could provide additional usage examples and ideas.

With our Pawn Movement Component's behavior defined, we can now write the code that will tie it all together in our customized Pawn class.

Work-In-Progress Code

CollidingPawn.h

CollidingPawn.cpp

CollidingPawnMovementComponent.h

CollidingPawnMovementComponent.cpp

4. Using Our Pawn and Components Together

In order to use our custom Pawn Movement Component, we will first need to add a variable to our Pawn class to keep track of it. At the bottom of our class definition in CollidingPawn.h, near where we added the OurParticleSystem variable, we should add:

Once we have a place to keep track of it, we will need to create a Colliding Pawn Movement Component to store in our new variable, so let's open CollidingPawn.cpp and add the following to the top of the file, underneath the line that includes GameFramework/Pawn.h line, so that our code will be able to reference our new class:

Be sure that the last header file included is the one ending with "generated.h"; you can encounter compiler errors if it is not.

Creating a Pawn Movement Component and associating it with our Pawn is simple. At the bottom of ACollidingPawn::ACollidingPawn, we can add this code:

Unlike the other Components we've seen so far, we don't need to attach this Component to our own Component hierarchy. This is because our other Components are all types of Scene Components, which inherently require physical locations. Movement Controllers, however, are not Scene Components and do not represent physical objects, so the concept of existing at a physical location or being physically attached to another Component does not apply to them.

Pawns have a function called GetMovementComponent that is used to enable other classes in the engine to access the Pawn Movement Component that the Pawn is currently using. We will need to override that function so that it returns our custom Pawn Movement Component. In the class definition in CollidingPawn.h, we need to add:

And in CollidingPawn.cpp, we need to add the definition of our overridden function, as follows:

With our new Pawn Movement Component set up, we can create code to handle the input that our Pawn will receive. We will start by declaring a few functions in our class definition in CollidingPawn.h:

In CollidingPawn.cpp, we will add the definitions of those functions as follows:

All that remains is to bind our functions to our input events. Let's add the following code to ACollidingPawn::SetupPlayerInputComponent:

We are done programming and can now return to Unreal Editor and press the Compile button to load our changes.

Our programming work is done, and we can now place our custom Pawn in the world and move it around.

Finished Code

CollidingPawn.h

CollidingPawn.cpp

CollidingPawnMovementComponent.h

CollidingPawnMovementComponent.cpp

5. Playing in Editor

In Unreal Editor, we can press the Compile button to load our code changes.



We need to drop an instance of our CollidingPawn into the world. We can find the class in the Content Browser under "C++ Classes/HowTo_Components/CollidingPawn".





Press Play and our sphere will move with WASD, turn with the mouse, and collide-and-slide along world objects, such as our table and chairs, or any other physical objects you might want to place in the world. It can also light itself on fire (or put itself out) with the space bar!



Unreal Engine offers a wide variety of Components - we've only scratched the surface with a few of the more common ones. Try exploring the built-in Components, or writing some of your own! They are flexible, powerful, and help to keep your project's code organized and reusable.

6. On Your Own!

Using what you have learned, try to do the following:

Create a Component that automatically orbits its parent.

Build a Component that spawns up to three children, each of which despawn on their own after a set amount of time.

Learn how to attach complete Actors to other Actors via Components.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Installing Unreal Engine

Content Browser Interface

Setting Up Visual Studio

1. Required Setup

2. Create a New C++ Class

3. Edit Your C++ Class

4. Compile and Test Your C++ Code

5. End Result

6. On Your Own!

Sample Code



In this Quick Start Guide, you will learn how to set up a C++ project in the Unreal Engine and program your first C++ gameplay class in Visual Studio. By the time you've completed this tutorial, you will know how to do the following:

Create a new C++ Project

Create a new Actor class in C++

Edit that C++ class in your development environment, adding visual representation and functionality

Compile your project

Test your new Actor in the Unreal Editor

This guide assumes that you have already set up Visual Studio as your programming environment. If not, please refer to Setting Up Visual Studio for the Unreal Engine for instructions on how to install it and get it set up for programming with the Unreal Engine. We also assume that you have some familiarity with using the Unreal Editor before starting this guide, but for your convenience we will walk through all the steps necessary to create and manage C++ classes from the editor. The end product of this guide will be a cube that floats softly in mid-air and continually rotates, giving you a simple object to test as you learn to use the development environment for programming.

This guide assumes that you have already set up XCode as your programming environment. We also assume that you have some familiarity with using the Unreal Editor before starting this guide, but for your convenience we will walk through all the steps necessary to create and manage C++ classes from the editor. The end product of this guide will be a cube that floats softly in mid-air and continually rotates, giving you a simple object to test as you learn to use the development environment for programming.

1. Required Setup

Launch the Unreal Editor. When the Project Browser comes up, click Games Project category and select a Blank template. Make sure that you have C++ and Starter Content enabled, choose your preferred Save Location and Name for this project, and then click Create Project. In our instance, we're naming our project QuickStart.

This will automatically create a simple, blank project with only essential C++ code in the solution, and it will automatically open inside both the Unreal Editor and Visual Studio. For more information on managing and creating Projects, please refer to the Project Browser page.

This will automatically create a simple, blank project with only essential C++ code in the solution, and it will automatically open inside both the Unreal Editor and XCode. For more information on managing and creating Projects, please refer to the Project Browser page.

Any Blueprint project can be converted to a C++ project. If you have a Blueprint project that you want to add C++ to, create a new C++ class per the next section, and the editor will set up your code environment for you. Also note that using a C++ project does not prevent you from using Blueprint. C++ projects simply set up the base classes for your project in C++ instead of Blueprint.

2. Create a New C++ Class

In the Unreal Editor, click the File drop-down menu, then select the New C++ Class... command.



Click image for full size.

The Choose Parent Class menu will display. You can choose an existing class to extend, adding its functionality to your own. Choose Actor, as it is the most basic type of object that can be placed in the world, then click Next.



Click image for full size.

In the Name Your New Actor menu, name your Actor FloatingActor and click Create Class.



Click image for full size.

The Unreal Engine will automatically compile and reload with our new class selected in the Content Browser, and your programming environment will automatically open with FloatingActor.cpp.

3. Edit Your C++ Class

Now that we have created our C++ Class, we're going to switch over to Visual Studio and edit our code.

In Visual Studio, locate the Solution Explorer, which by default is on the left side of the window, then use it to locate FloatingActor.h. In our project, it will be located under Games > QuickStart > Source > QuickStart.



Double-click FloatingActor.h to open it and bring it into focus in the text editor.



This is a header file. You can think of it as being sort of like a table of contents for a C++ class. Before we can start building any new functionality, we must declare any new Variables or Functions that we're using in this file.

Add the following code underneath the declaration for AFloatingActor():

Here we're declaring a StaticMeshComponent, which will act as our visual representation for our object. Note that it uses a UProperty macro, which makes it visible inside the Unreal Editor. For more information on UProperty and its specifiers, see the page on Properties.

Now open FloatingActor.cpp and add the following code inside of AFloatingActor::AFloatingActor(), just before the closing bracket:

This function is the constructor, and it tells the class how to initialize itself when it is first created. The code we have added will fill our VisualMesh reference in with a new StaticMeshComponent, attach it to our Actor, and set it to the cube mesh from the Starter Content assets. For more information about attaching components in code, refer to our guide for Creating and Attaching Components.

Add the following code inside of AFloatingActor::Tick(float DeltaTime), just before the closing bracket:

The Tick function is where we add code that we want to execute in real-time. In this case, it will make our cube simultaneously rotate while also floating up and down. For more information about Ticking actors, see



Now that we have created our C++ Class, we're going to switch over to XCode and edit our code.

In XCode, locate the Project Navigator, which by default is on the left side of the window, then use it to locate FloatingActor.h. In our project, it will be located under Games > QuickStart > Source > QuickStart.



Double-click FloatingActor.h to open it and bring it into focus in the text editor. This is a header file. You can think of it as a table of contents for a C++ class. Before we can start building any new functionality, we must declare any new Variables or Functions that we're using in this file.

Add the following code underneath the declaration for AFloatingActor():

Here we're declaring a StaticMeshComponent, which will act as our visual representation for our object. Note that it uses a UProperty macro, which makes it visible inside the Unreal Editor. For more information on UProperty and its specifiers, see the page on Properties.

Now open FloatingActor.cpp and add the following code inside of AFloatingActor::AFloatingActor(), just before the closing bracket:

This function is the constructor, and it tells the class how to initialize itself when it is first created. The code we have added will fill our VisualMesh reference in with a new StaticMeshComponent, attach it to our Actor, and set it to the cube mesh from the Starter Content assets. For more information about attaching components in code, refer to our guide for Creating and Attaching Components.

Add the following code inside of AFloatingActor::Tick(float DeltaTime), just before the closing bracket:

The Tick function is where we add code that we want to execute in real-time. In this case, it will make our cube simultaneously rotate while also floating up and down. For more information about Ticking actors, see



4. Compile and Test Your C++ Code

Save your work in both FloatingActor.h and FloatingActor.cpp. Then, in the Solution Explorer, right-click the project, click the Build command in the context menu, and wait for the project to finish compiling.



You should see a message that says "Succeeded" in the Output log at the bottom of the window.



Alternatively, you can go back to the Unreal Editor and click the Compile button in the toolbar at the top of the screen.



You should always save your work before attempting to compile, otherwise the changes you make in your code will not take effect.

In the Unreal Editor, go back to the Content Browser, unfold C++ Classes, and then locate FloatingActor. It will be located in the folder that has the same name as your project, in our case, QuickStart.



Click and drag FloatingActor into the Perspective Viewport to create an instance of FloatingActor. It will be selected in the World Outliner as "FloatingActor1" and its properties will be visible in the Details Panel.



For more information about navigating the Viewport and placing Actors in the World, refer to the Level Designer Quick Start.

In the Details Panel for FloatingActor1, set your Actor's Location to (-180, 0, 180). This will place it directly over the table in the default scene.



Alternatively, you can use the Move gizmo to move it there manually.



Press the Play In Editor button at the top of the screen.



Save your work in both FloatingActor.h and FloatingActor.cpp. Then, click the Product drop-down menu at the top of the screen, select the Build command, and wait for the project to finish building.



You should see a message that says "Succeeded" in the Output log at the bottom of the window. Alternatively, you can go back to the Unreal Editor and click the Compile button in the toolbar at the top of the screen.



You should always save your work before attempting to compile, otherwise the changes you make in your code will not take effect.

In the Unreal Editor, go back to the Content Browser, unfold C++ Classes, and then locate FloatingActor. It will be located in the folder that has the same name as your project, in our case, QuickStart.



Click and drag FloatingActor into the Perspective Viewport to create an instance of FloatingActor. It will be selected in the World Outliner as "FloatingActor1" and its properties will be visible in the Details Panel.



For more information about navigating the Viewport and placing Actors in the World, refer to the Level Designer Quick Start.

In the Details Panel for FloatingActor1, set your Actor's Location to (-180, 0, 180). This will place it directly over the table in the default scene.



Alternatively, you can use the Move gizmo to move it there manually.



Press the Play In Editor button at the top of the screen.



5. End Result

You should now see your cube gently floating up and down over the table while it slowly rotates.

Congratulations! You've created your first Actor class entirely with C++! While this represents a very simple object and only scratches the surface of what you can do with C++ source code, you have at this point touched on all the essentials of creating, editing, and compiling C++ code for your game. You are now ready for more complex gameplay programming challenges, and we suggest a few below.

6. On Your Own!

Now that you know how to build a simple C++ Actor, try making it more configurable. For instance, you can add variables to control its behavior:

In FloatingActor.h:

In FloatingActor.cpp:

By adding these variables in the header and replacing the float values we were using to scale DeltaHeight and DeltaRotation in the .cpp, we can now edit the float and rotation speed in the Details Panel when we select our Actor.



You can experiment by adding other kinds of behavior to the Tick function using Location, Rotation, and Scale.

You can also try attaching other kinds of components in C++ to create a more complex object. Refer to the Creating and Attaching Components guide for examples of different types of components you have available, and try adding a Particle System Component to add a bit of flare to your floating object.



Finally, if you right-click your own Actor class in the Content Browser, you will find the option to extend it, either in C++ or in Blueprint, enabling you to create new variations of it.



You can have a whole library of FloatingActors, each substituting different Meshes or parameters as you so choose.



Sample Code

FloatingActor.h

FloatingActor.cpp

1. Attach a Camera to a Pawn

Work-In-Progress Code

2. Configure Input to Control the Camera

3. Write C++ Code to React to Input

Finished Code

4. On Your Own!

Attaching a spring arm and a camera to a Pawn provides the capability to adjust how our camera follows a Pawn in the world.

1. Attach a Camera to a Pawn

Begin by launching Unreal Engine and creating a new blank Template.



Select a new Games Project. In the Project Settings window, we will change the default code from Blueprint to C++, with starter content enabled. Choose the directory where you want your unreal project to save in, then name your project HowTo_PlayerCamera and click Create Project.



From the sources panel, navigate to your C++ Classes folder. You should notice a single class containing your Game mode base class. Right click on the adjacent gray space, and from the drop down window, select New C++ class



Select Pawn as your Parent Class and click Next. Name your new Pawn PawnWithCamera.



in Visual Studio, Navigate to the PawnWithCamera.h file and add the following code to the protected namespace of your class definition:

These variables are used to create a SpringArmComponent with a CameraComponent attached to the end. Spring arms provide a simple way to attach cameras (or other Components) so that its motion is smooth and fluid as they move with the object they observe.

Navigate to PawnWithCamera.cpp and declare the following includes:

Now, you will need to create your static mesh, spring arm and camera components. Declare the following code to PawnWithCamera.cpp from inside the class constructor APawnWithCamera::APawnWithCamera: Add the following code:

This creates a SceneComponent as the root of our Component List Hierarchy, then creates and attaches a StaticMeshComponent to it. Afterwards, both a SpringArmComponent and a Camera Component is created and the Camera Component is attached to the end of the Spring ArmComponent's socket length. The Spring Arm is set to a default pitch of -60 degrees and a position of 50 units above the root. We also establish a few values specific to the SpringArmComponent class that will determine its length and the smoothness of its motion.

Finally, we will set the default Player Controller to possess our Pawn from the constructor.

We now have a simple Pawn that will allow us to control our camera comfortably. Next, we'll configure our input in the Unreal Engine editor and create code that reacts to it.

Work-In-Progress Code

PawnWithCamera.h

PawnWithCamera.cpp

2. Configure Input to Control the Camera

You will need to decide the input keys that control your camera and pawn, then set up the inputs accordingly. For this project sample, let us allow our follow distance to shorten and field of view to zoom in when the right mouse button is held down.

Let's also control our viewing angle with the mouse, and our Pawn's movement with the WASD keys. To do this, we'll open the Project Settings from the Edit dropdown menu in the Unreal Engine editor.



From the Project Settings window, navigate to Engine>Input>Bindings. From here, click the + signs next to Action and Axis mappings to add a new key map.



You will want to define the following input Action Mapping and Axis Mapping, which will be used to control our input logic.

Action Mapping:

ZoomIn

Right Mouse Button

Axis Mapping:

MoveForward

W

1.0

S

-1.0

MoveRight

A

-1.0

D

1.0

CameraPitch

MouseY

1.0

CameraYaw

MouseX

1.0



If you would like to understand more about how input mappings work, you may want to consult the Player Input and Pawns tutorial.

Now that you've defined your inputs, return to Visual Studio to proceed onward to the next steps.

3. Write C++ Code to React to Input

You will write the code necessary to utilize your input mappings by setting up member variables to store the input data you will receive. During the Event Tick Update, you will need to know the values of your movement and mouse-looking axes, each of which are two-dimensional vectors.

You will also want to know whether you should be moving toward a zoomed-in or zoomed-out camera view, and how far between those two states your camera currently is.

Begin by adding the following code to your protected namespace in the class definition of PawnWithCamera.h:

You will need to create functions to track your input, begin by adding the following to your class definition in PawnWithCamera.h:

Now you will want to navigate to your PawnWithCamera.Cpp file, where you will begin to implement your function logic by adding the following code:

We haven't done anything with ZoomFactor yet. That variable will be updated during our Pawn's Tick function, since its value changes constantly over time based to the state of a button.

Now that you have created the code necessary to store your input data, the next step is to tell the engine when to call your code. Binding functions to input events for Pawns can be accomplished by adding code to APawnWithCamera::SetupPlayerInputComponent method, as follows:

Finally, you can use those values in your Tick function to update your Pawn and Camera each frame. The following code blocks should all be added to APawnWithCamera::Tick in PawnWithCamera.cpp:

This code uses several hard-coded values, like the half-second and quarter-second zoom times, the 90-degree zoomed-out and 60-degree zoomed-in field of view values, and the 400 zoomed-out and 300 zoomed-in camera distances. Values like this should generally be exposed to the editor as variables tagged with UPROPERTY(EditAnywhere) In our example, we used the UPROPERTY(EditAnywhere) specifier tag, which provides additional functionality to non-programmers who can change their values. This also enables programmers to change them without recompiling code, or dynamically while playing the game in the editor.

This block of code rotates our Pawn's yaw directly with the mouse's X axis, but only the camera system responds to the pitch changes from the mouse's Y axis. Rotating any Actor or Actor subclass actually rotates the root-level Component, which indirectly affects everything attached to it.

Using GetActorForwardVector and GetActorRightVector allows us to move relative to the direction the actor is facing. Since the camera faces the same way as the actor, this ensures that our forward key is always forward relative to what the player sees.

Congratulations! We have finished coding. You can now compile your code and drag an instance of your new class from the Content Browser into the Level Editor window inside the Unreal Engine editor.



Feel free to add a Static Mesh or other visual Component, or play without one. You should feel a smooth acceleration and deceleration to your camera's movement as it follows you around the level, but your rotation should feel tight and instantaneous. Try changing some of the properties on the SpringArmComponent to see how they affect the feel of your controls, such as adding "Camera Rotation Lag" or increasing or decreasing Camera Lag.



The Completed functionality of the code provided should look as it does below:

Camera Pitch/Yaw



Move Forward/Right



Zoom In/Out



Finished Code

PawnWithCamera.h

PawnWithCamera.cpp

4. On Your Own!

Using what you have learned, try to do the following:

Give the player a run key to hold down that will increase the Pawn's movement speed.

Experiment with different ways to mix automatic and input-driven camera movement. This is a very deep area of game development with a lot of room to explore!

Increase, decrease, or remove the lag from your Spring Component to get a better understanding of how much lag can affect your camera's overall feel.

Implement a small amount of periodic motion, possibly slightly randomized or using a Curve asset, to create a handheld feel to your camera.

Give your Camera some amount of automatic turning, so that the camera gradually gets behind the moving player object and faces the direction the player is moving.

As for the specifics covered in this tutorial:

For more information on Cameras and ways to control them, see the Camera framework page.

To learn more about Components, try the Components tutorial.

1 - Customize a Pawn

2 - Configure Game Input

3 - Program and Bind Game Actions

4 - On Your Own!

Over the course of this tutorial, you will learn to react to player input by extending the Pawn class.

1 - Customize a Pawn

If you are new to Unreal Engine, you might want to read our Programming Quick Start first. For this tutorial, we will assume you are familiar with creating a project, adding C++ code to it, and compiling your code.

We will begin by creating a new, Basic Code project, with starter content, named HowTo_PlayerInput. Then, we'll add a customized Pawn class, which we will call MyPawn, to the project.

A Pawn is a type of Actor that is designed to be controlled by human players or AI.





The first thing we're going to do is set our MyPawn to respond to player input automatically upon the game starting. The Pawn class provides a variable we can set during initialization that handles this for us. In MyPawn.cpp, add the following code to AMyPawn::AMyPawn:

Next, we'll build a few basic Components. If you want to learn more about adding and managing Components in code, as well as some common types of Components you will encounter, try reading our Components Tutorial. In order to keep track of the Component we will create, we should add the following code to MyPawn.h, at the bottom of our class definition:

This variable is tagged as a UPROPERTY so that it will be visible to Unreal Engine. This is important because it prevents the variable from being reset when the game is launched, or when the project or level is closed and reloaded.

And back in MyPawn.cpp, we should add the following code to AMyPawn::AMyPawn:

We are now ready to save our changes and compile with the Build command in Visual Studio or the Compile button in the Unreal Editor.

Now that we have a customized Pawn to react to our game's input, we'll need to define what that input will be. To do this, we'll configure our project's Input Settings in the Unreal Editor.

Work-In-Progress Code

MyPawn.h

MyPawn.cpp

2 - Configure Game Input

There are two types of input mappings: Action and Axis.

Action Mappings are useful to think of as "yes or no" inputs, like the buttons on a mouse or joystick. They report when they are pressed, released, double-clicked, or held down for a short time. Discrete actions like jumping, shooting, or interacting with objects are good candidates for this type of mapping.

Axis Mappings are continuous - think of them as "how much" inputs, like the stick on a joystick, or the position of a mouse cursor. They report their value every frame, even if they're not moving. Things with magnitude or direction, such as walking, looking around, and steering a vehicle are usually handled this way.

While input mappings can be defined directly in code, the usual method is to define them in the Unreal Engine editor, so that's how we'll do it in this tutorial.

In the Unreal Engine editor, under the Edit dropdown menu, we'll click the Project Settings option.



From there, we'll select the Input option from the Engine section on the left. We can then expand the Bindings category that appears on the right, and add one Action Mapping and two Axis Mappings.

The plus sign next to the Action Mapping or Axis Mapping section headings will add a new mapping. The expander arrow on the left can be used to show or hide our mappings. To add an additional input to a mapping, click the plus sign next to that mapping. Following are the mappings and inputs we will need. Take note of the negative values for the S and A inputs.

Action Mapping

Grow

Space Bar

Axis Mapping

MoveX

W

1.0

S

-1.0

MoveY

A

-1.0

D

1.0



Now that our input is configured, let's set up a MyPawn in our level. The MyPawn class will appear in our Content Browser, and is ready to be dragged into the Level Editor.





One more step is needed to set up our MyPawn. We'll need to give it a Static Mesh so that we can see it in the game. We can do this by selecting the MyPawn we just created, selecting the component called OurVisibleComponent (Inherited) in the Details Panel, and assigning an asset to it through the dropdown box in the Static Mesh category. For this tutorial, Shape_Cylinder is a good asset to use.



We can now save our level and return to Visual Studio to write code that will make the MyPawn we placed react to the inputs we defined.

We're now ready to finish coding our MyPawn class in Visual Studio.

3 - Program and Bind Game Actions

We'll switch over to MyPawn.cpp and program the four functions we just declared. Add the following code:

We use FMath::Clamp to constrain the values we get from our inputs to the range of -1 to +1. Although it's not an issue in this example, if there were multiple keys that could affect an axis in the same way, the values would be added together if a player pressed those inputs at the same time. For example, if both W and Up Arrow were mapped to MoveX with scales of 1.0, pressing both would result in an AxisValue of 2.0, which would let the player move at double speed if we didn't clamp it.

You may notice that the two "Move" functions take axis values as floats, while the "Grow" functions do not. This is because they will be mapped to MoveX and MoveY, which are Axis Mappings, and therefore will have a floating-point parameter. Action Mappings do not have this parameter.

Now that we have our input functions defined, we'll need to bind them so that they will react to the appropriate inputs. Add the following code inside of AMyPawn::SetupPlayerInputComponent:

We now have variables that are updated by the inputs we configured. All we have left to do is write code to do something with them. Let's add the following code to AMyPawn::Tick:

After compiling our code, we can return to the Unreal Editor and press Play. We should have control of our Pawn with the WASD keys, and we should be able to make it grow by holding Space Bar, and watch it shrink when we let go.



Finished Code

MyPawn.h

MyPawn.cpp

4 - On Your Own!

Using what you have learned, try to do the following:

Implement directional controls that increase speed after being held for a certain period of time.

Create a special input sequence that instantly expands the object to full scale when the user presses an Action Mapping immediately after starting to press an Axis Mapping.

As for the specifics covered in this tutorial:

For more information about Input, try the Input page.

For further tutorials, see the C++ Programming Tutorials page.

1. Creating an Actor that Uses a Timer

Work-In-Progress Code

2. Exposing Variables and Functions to the Editor

Finished Code

3. Extend and Override C++ with Blueprints

4. On Your Own!

This tutorial will show you how to expose variables and functions to the editor, use timers to delay or repeat code execution, and use events to communicate between Actors.

1. Creating an Actor that Uses a Timer

If you are new to Unreal Engine, you might want to read our Programming Quick Start first. For this tutorial, we will assume you are familiar with creating a project and adding C++ code to it.

We will begin by creating a new, Basic Code project, with starter content, named HowTo_VTE, and then adding an Actor class to it. We'll name it Countdown in this tutorial.





We'll start by creating a simple countdown timer that we can see in-game. In Countdown.h, add the following lines to the end of our class definition:

In Countdown.cpp, we can create our renderable text Component and initialize our countdown time to 3 seconds. We can also turn Ticking off for this type of Actor, since we will not need it. To do this, we must add the header for the Component at the top of the file, making the "include" section look like this:

With the header included, we can write ACountdown::ACountdown. It should look like this:

ACountdown::UpdateTimerDisplay should update our text display to show the time remaining, or zero if the time is up. This code should run when we first spawn our ACountdown into the game, and once per second until our CountdownTime variable hits zero.

Whenever we assign a Timer to run a function, we are given a Timer Handle. We need to hold onto that handle so that we can shut the Timer down when the countdown finishes. Let's add the function to count time down, and the Timer Handle we'll need to control it, to the class definition in Countdown.h. While we're there, let's also add a function to do something special when the countdown ends:

We can also write the body of ACountdown::AdvanceTimer and ACountdown::CountdownHasFinished in Countdown.cpp now:

Let's initialize the text display in ACountdown::BeginPlay by adding a call to our new update function, and setting a timer to advance and update the countdown once per second:

We are updating the display in ACountdown::BeginPlay rather than ACountdown::ACountdown because values set to variables in the Unreal Editor will be assigned after the constructor, but before BeginPlay. We will want to respect those values later, when we expose CountdownTime to the editor.

Let's check our progress so far by going to the Unreal Editor and pressing Compile.



We can then drop our updated ACountdown class from the Content Browser into the Level Editor.





Because we set our countdown text during ACountdown::BeginPlay and not ACountdown::ACountdown, the default Text is shown in the Level Editor.

When we press Play, the countdown will progress as expected, saying 3, 2, 1, and finally GO!

At this point, we've already created a simple class that uses a timer. Non-programming users would get much more out of it if they could set the countdown time, or change the behavior when the countdown finishes. Next, we'll expose these features to the editor.

Work-In-Progress Code

Countdown.h

Countdown.cpp

2. Exposing Variables and Functions to the Editor

Our countdown timer is currently hard-coded to use a value of 3 seconds. It would be more useful if we could set the countdown time to any value we want in the editor, and this is easy to do. In Visual Studio, we can open Countdown.h and find the line that says:

In order to expose this variable to Unreal Engine, we need to make it a UPROPERTY. This enables the engine to preserve the value of the variable when launching the game or loading a saved level. The UPROPERTY tag, with empty parentheses, is added right above the variable it affects:

UPROPERTY supports arguments that change how Unreal Engine will use the variable. Since we want our variable to be editable, we can add the EditAnywhere argument:



We can also add a comment to our variable in C++, and our comment will become the description of the variable in the Unreal Editor, like this:



There is a lot more we can do with UPROPERTY, and looking into other Specifiers such as BlueprintReadWrite and Category might be good next steps, but we have all that we need at the moment.

When we return to the Unreal Editor and press Compile, our variable will appear in the Details Panel for the ACountdown we placed earlier, and we can test out different timer values by changing this number and pressing Play.

In addition to changing the value of the timer, let's also enable non-programming developers to change what happens when the timer is up. In Visual Studio, we'll open Countdown.h and find the following line:

We can expose this function to the Unreal Engine by making it a UFUNCTION, like this:

Just like the UPROPERTY macro, we need to provide information about what can be done with it in order to enable more features and access for non-programming developers. There are three options to consider:

BlueprintCallable functions are written in C++ and can be called from the Blueprint Graph, but cannot be changed or overridden without editing C++ code. Functions marked this way are usually features that have been programmed for non-programmer use, but that are not supposed to be changed or wouldn't make sense to change. An easy example of this would be any kind of math function.

BlueprintImplementableEvent functions are set up in a C++ header (.h) file, but the body of the function is written entirely in the Blueprint Graph, not in C++. These are usually created to give a non-programmer the ability to create custom reactions to special situations that have no expected default action or standard behavior. An example of this might be an event that happens when a powerup touches the player's ship in a spaceship game.

BlueprintNativeEvent functions are like a combination of BlueprintCallable and BlueprintImplementableEvent functions. They have default behaviors programmed in C++, but these can be supplemented or replaced by overriding in the Blueprint Graph. When programming these, the C++ code always goes in a virtual function with _Implementation added to the end of the name, as shown below. This is the most flexible option, so we will use it for this tutorial.

To grant non-programmers the ability to call our C++ function and to override it with Blueprints, we need to make the following changes to Countdown.h:

Then, in Countdown.cpp, we will need to change the line that says:

To:

We have now made a variable and a function accessible to, and alterable by, non-programmers, while providing our own default value and functionality in C++. To see how a non-programmer might use this, we'll make a Blueprint extension of our ACountdown class and modify it ourselves.

Finished Code

Countdown.h

Countdown.cpp

3. Extend and Override C++ with Blueprints

This section of the tutorial involves using Blueprints to extend the functionality of C++ classes. However, it is only intended as a test that our C++ code was written correctly, not as a Blueprint tutorial. For a proper introduction to Blueprints, we recommend the Blueprints Quick Start Guide.

To change the behavior of our ACountdown instance, called Countdown1, in the editor, we must first make an editable Blueprint version of it. To do this, we can select it from the World Outliner and click the Blueprint/Add Script button in the Details Panel.



From there, we can provide a path and name for the Blueprint asset that will contain our modified ACountdown class.



This will create a new asset that represents a Blueprint version of Countdown1. It will also replace Countdown1 with an instance of this new Blueprint, so that changes we make to the Blueprint will affect Countdown1 in the game.

The Unreal Editor will automatically take us to our new asset in the Content Browser, and we can Right-click it and choose "Edit..." to modify its Blueprint Graph, Component hierarchy, and Default Values.





Functions and events can be found in the Event Graph tab, so we'll select that first.



Then, by Right-clicking anywhere in the Event Graph window, we can add our CountdownHasFinished function as an event node to define its behavior.



We can now add any additional functionality we would like by left-clicking and dragging off of the white (execution) pin on the right side of our new node.



When we release the left mouse button, we will be asked what function or event we would like to execute. For this tutorial, let's spawn a Particle System when the countdown finishes. We'll want a Spawn Emitter At Location node, so select that from the list. It can save time to type a partial phrase, like spawn loc, into the search field. We can then left-click and drag the yellow "Location" pin and attach it to a Get Actor Location function.



Now we just need to select what effect we'd like to see. By clicking Select Asset under Emitter Template, we can get a list of appropriate effect assets. P_Explosion is a good one, so we'll pick that.



Click the Compile button at the top left of the Blueprint Editor to save the changes.

If we press Play now, we'll see our countdown take place, and our explosion will happen when our countdown number hits zero.



However, we programmed our countdown to say GO! at the end, not 0. This is no longer happening because we have completely replaced our C++ functionality with our Blueprint visual scripting. This is not what we intended to do in this case, so we need to add a call to the C++ version of this function, which can be done by right-clicking the Countdown Has Finished node and selecting Add call to parent function from the context menu.



When this is done, a node labeled Parent: Countdown Has Finished will be placed in the Event Graph. The typical place to connect a parent node is directly to the event node, which is what we will do here. This is not required, though, as the parent-call node is like any other and can be called anywhere we like, even multiple times.



Note that this will replace the connection to Spawn Emitter At Location, so we'll need to connect our **Parent: programming-and-scripting/programming-language-implementation/cpp-in-unreal-engine/unreal-engine-cpp-tutorials



Now when we run our game, we should see both the word GO! (from our C++ code) and an explosion (from our Blueprint Graph) after the countdown finishes!



4. On Your Own!

Using what you have learned, try to do the following:

Create an Actor that moves or rotates to a target transform when an Event is run. This could be used as a moving platform or door in a game. Make the Event start a Timer that will trigger a second Event which moves the Actor back to its original location. Use exposed variables (that is, exposed through UPROPERTY) instead of hard-coded values wherever appropriate.

Make a lit torch that burns out (perhaps by deactivating a fiery Particle System Component) by using a Timer handle and a few custom Events. For example, an AddFuel Event could extend the burning time of the torch. A DouseWithWater Event could shut it off immediately and prevent AddFuel from working in the future. Both of these features can be written without using a Tick, simply by modifying a running Timer through its handle.

As for the specifics covered in this tutorial:

For more information about Timers, try the Gameplay Timers page.

For a complete reference using the UPROPERTY tag with variables in your classes or structs, look at the Properties page.

To learn more about UFUNCTIONS and Event creation, check the UFunctions page.

For further tutorials, see the C++ Programming Tutorials page.

Implementation Guide

By establishing reference to an Actor, you can access its Properties, Variables, Events, or Functions (if applicable) during gameplay through Blueprints or C++ and alter them to suit your gameplay needs.

Say for example you want a light to turn on when a player enters a Trigger Box, having reference to the light and the Trigger Box will allow you to do so by tying the light Actor to the OnComponentBeginOverlap Event of the Trigger Box (in which case you could turn on the light).

Getting proper reference to an Actor is also important for communication between Actors, as incorrectly specifying a reference will result in failed communication and undesirable results.

Implementation Guide

The Blueprint Visual Scripting system in Unreal Engine is a complete gameplay scripting system based on the concept of using a node-based interface to create gameplay elements from within Unreal Editor. As with many common scripting languages, it is used to define object-oriented (OO) classes or objects in the engine.

This system is extremely flexible and powerful as it provides the ability for designers to use virtually the full range of concepts and tools generally only available to programmers. In addition, Blueprint-specific markup available in Unreal Engine's C++ implementation enables programmers to create baseline systems that can be extended by designers.

Getting Started



Get up and running by creating your first Blueprint.



Overview of using the Blueprint visual scripting system for gameplay.

General Scripting



Overview of using the Blueprint visual scripting system for gameplay.

Building Blueprints



The User Guide is the go-to source to learn the different parts of Blueprints and nodes that are available to use within Blueprint graphs.



The User Guide is the go-to source to learn the different parts of Blueprints and nodes that are available to use within Blueprint graphs.



The Blueprint How-To page provides several short step-by-step guides for working with Blueprints.



Reference covering Blueprint shortcuts and useful actions.



Tips and tricks to help you make decisions about when to use Blueprints and how best to set them up.

Blueprint Communication



Overview of when to use different methods of Blueprint Communications.



Allows a Blueprint Class to report on its state to the Level Blueprint.



Blueprints that declare functions to define an interface between Blueprints.

Topics



An overview of Blueprint Namespaces.



Technical guide for programmers working with Blueprints.



If you are just getting started with Blueprints, this provides a high-level overview of what they are and what they can do.



Pause Blueprint execution using Breakpoints to inspect graphs and the values of their variables.

Declaring Delegates

Binding Delegates

Payload Data

Executing Delegates

Example Usage

Delegates can call member functions on C++ objects in a generic, type-safe way. A delegate can be bound dynamically to a member function of an arbitrary object, calling the function on the object at a future time, even if the caller does not know the object`s type. Delegates are safe to copy. You can also pass them by value, but this is not recommended because this process will allocate memory on the heap; whenever possible, pass delegates by reference. There are three types of delegates supported by the Engine:

Single

Multicast

Dynamic (UObject, serializable)

Declaring Delegates

To declare a delegate, use one of the macros below; select the macro based on the signature of the function (or functions) that you intend to bind to the delegate. Each macro features parameters for the new delegate type name, as well as the function's return type (if not void) and its parameters. Currently, delegate signatures support any combination of the following:

Functions returning a value

Functions declared as const

Up to four "payload" variables

Up to eight function parameters

Use this table to find the declaration macro to use to declare your delegate.

Function signature

Declaration macro

void Function()

DECLARE_DELEGATE(DelegateName)

void Function(Param1)

DECLARE_DELEGATE_OneParam(DelegateName, Param1Type)

void Function(Param1, Param2)

DECLARE_DELEGATE_TwoParams(DelegateName, Param1Type, Param2Type)

void Function(Param1, Param2, ...)

DECLARE_DELEGATE_<Num>Params(DelegateName, Param1Type, Param2Type, ...)

<RetValType> Function()

DECLARE_DELEGATE_RetVal(RetValType, DelegateName)

<RetValType> Function(Param1)

DECLARE_DELEGATE_RetVal_OneParam(RetValType, DelegateName, Param1Type)

<RetValType> Function(Param1, Param2)

DECLARE_DELEGATE_RetVal_TwoParams(RetValType, DelegateName, Param1Type, Param2Type)

<RetValType> Function(Param1, Param2, ...)

DECLARE_DELEGATE_RetVal_<Num>Params(RetValType, DelegateName, Param1Type, Param2Type, ...)

Delegate functions support the same Specifiers as UFunctions, but use the UDELEGATE macro instead of UFUNCTION. For example, the following code adds the BlueprintAuthorityOnly Specifier to the FInstigatedAnyDamageSignature delegate

Variations of the macros above for multi-cast, dynamic, and wrapped delegates are as follows:

DECLARE_MULTICAST_DELEGATE...

DECLARE_DYNAMIC_DELEGATE...

DECLARE_DYNAMIC_MULTICAST_DELEGATE...

DECLARE_DYNAMIC_DELEGATE...

DECLARE_DYNAMIC_MULTICAST_DELEGATE...

Delegate signature declarations can exist at global scope, within a namespace, or even within a class declaration. These declarations may not exist within the body of a function.

See Dynamic Delegates and Delegates for more information on declaring these types of delegates.

Delegate functions support The same Specifiers as UFunctions, but use the UDELEGATE macro instead of UFUNCTION.

Binding Delegates

The delegate system understands certain types of objects, and additional features are enabled when using these objects. If you bind a delegate to a member of a UObject or shared pointer class, the delegate system can keep a weak reference to the object, so that if the object gets destroyed out from underneath the delegate, you will be able to handle these cases by calling IsBound or ExecuteIfBound functions. Note the special binding syntax for the various types of supported objects.

Function

Description

Bind

Binds to an existing delegate object.

BindStatic

Binds a raw C++ pointer global function delegate.

BindRaw

Binds a raw C++ pointer delegate. Since raw pointers do not use any sort of reference, calling Execute or ExecuteIfBound after deleting the target object is unsafe.

BindLambda

Binds a functor. This is generally used for lambda functions.

BindSP

Binds a shared pointer-based member function delegate. Shared pointer delegates keep a weak reference to your object. You can use ExecuteIfBound to call them.

BindUObject

Binds a UObject member function delegate. UObject delegates keep a weak reference to the UObject you target. You can use ExecuteIfBound to call them.

UnBind

Unbinds this delegate.

See DelegateSignatureImpl.inl (located in ..\UE4\Engine\Source\Runtime\Core\Public\Templates\) for the variations, arguments, and implementations of these functions.

Payload Data

When binding to a delegate, you can pass payload data along. These are arbitrary variables that will be passed directly to any bound function when it is invoked. This is really useful as it allows you to store parameters within the delegate itself at bind-time. All delegate types (except for "dynamic") support payload variables automatically.This example passes two custom variables, a bool and an int32 to a delegate. Then when the delegate is invoked, these parameters will be passed to your bound function. The extra variable arguments must always be accepted after the delegate type parameter arguments.

Executing Delegates

The function bound to a delegate is executed by calling the delegate`s Execute() function. You must check if delegates are "bound" before executing them. This is to make the code more safe as there may be cases where delegates have return values and output parameters that are uninitialized and subsequently accessed. Executing an unbound delegate could actually scribble over memory in some instances. You can call IsBound() to check if the delegate is safe to execute. Also, for delegates that have no return value, you can call ExecuteIfBound(), but be wary of output parameters that may be left uninitialized.

Execution Functions

Description

Execute

Executes a delegate without checking its bindings

ExecuteIfBound

Checks that a delegate is bound, and if so, calls Execute

IsBound

Checks whether or not a delegate is bound, often before code that includes an Execute call

See Multi-cast Delegates for details on executing multi-cast delegates.

Example Usage

Suppose you have a class with a method that you would like to be able to call from anywhere:

To call the WriteToLog function, we will need to create a delegate type for that function`s signature. To do this, you will first declare the delegate using one of the macros

For example, here is a simple delegate type:

DECLARE_DELEGATE_OneParam(FStringDelegate, FString);

This creates a delegate type called FStringDelegate that takes a single parameter of type FString.

Here is an example of how you would use this FStringDelegate in a class:

This allows your class to hold a pointer to a method in an arbitrary class. The only thing the class really knows about this delegate is its function signature.

Now, to assign the delegate, simply create an instance of your delegate class, passing along the class that owns the method as a template parameter. You will also pass the instance of your object and the actual function address of the method. So, here we will create an instance of our FLogWriter class, then create a delegate for the WriteToLog method of that object instance:

You have just dynamically bound a delegate to a method of a class! Pretty simple, right?

Note that the SP part of BindSP stands for shared pointer, because we are binding to an object that is owned by a shared pointer. There are versions for different object types, such as BindRaw() and BindUObject().

Now, your WriteToLog method can be called by FMyClass without it even knowing anything about the FLogWriter class! To call your delegate, just use the Execute() method:

If you call Execute() before binding a function to the delegate, an assertion will be triggered. In many cases, you will instead want to do this:

Declaring Dynamic Delegates

Dynamic Delegate Binding

Executing Dynamic Delegates

Dynamic delegates can be serialized, their functions can be found by name, and they are slower than regular delegates.

Declaring Dynamic Delegates

Dynamic delegates are declared in the same manner as you declare standard delegates except they use the macro variations specific to dynamic delegates.

Declaration Macro

Description

DECLARE_DYNAMIC_DELEGATE[_RetVal, ...]( DelegateName )

Creates a dynamic delegate.

DECLARE_DYNAMIC_MULTICAST_DELEGATE[_RetVal, ...]( DelegateName )

Creates a dynamic multi-cast delegate.

Dynamic Delegate Binding

Helper Macro

Description

BindDynamic( UserObject, FuncName )

Helper macro for calling BindDynamic() on dynamic delegates. Automatically generates the function name string.

AddDynamic( UserObject, FuncName )

Helper macro for calling AddDynamic() on dynamic multi-cast delegates. Automatically generates the function name string.

RemoveDynamic( UserObject, FuncName )

Helper macro for calling RemoveDynamic() on dynamic multi-cast delegates. Automatically generates the function name string.

Executing Dynamic Delegates

The function bound to a delegate is executed by calling the delegate`s Execute() function. You must check if delegates are "bound" before executing them. This is to make the code more safe as there may be cases where delegates have return values and output parameters that are uninitialized and subsequently accessed. Executing an unbound delegate could actually scribble over memory in some instances. You can call IsBound() to check if the delegate is safe to execute. Also, for delegates that have no return value, you can call ExecuteIfBound(), but be wary of output parameters that may be left uninitialized.

Execution Functions

Description

Execute

Executes a delegate without checking its bindings

ExecuteIfBound

Checks that a delegate is bound, and if so, calls Execute

IsBound

Checks whether or not a delegate is bound, often before code that includes an Execute call

See Multi-cast Delegates for details on executing multi-cast delegates.

Declaring Multi-Cast Delegates

Binding Multi-Cast Delegates

Multi-Cast Execution

Multi-cast delegates have most of the same features as single-cast delegates. They only have weak references to objects, can be used with structs, can be copied around easily, etc.Just like regular delegates, multi-cast delegates can be loaded/saved, and triggered remotely; however, multi-cast delegate functions cannot use return values. They are best used to easily pass a collection of delegates around.

Events are a specialized type of multi-cast delegate with restricted access to the Broadcast(), IsBound(), and Clear() functions.

Declaring Multi-Cast Delegates

Multi-cast delegates are declared in the same manner as you declare standard delegates except they use the macro variations specific to multi-cast delegates.

Declaration Macro

Description

DECLARE_MULTICAST_DELEGATE[_RetVal, ...]( DelegateName )

Creates a multi-cast delegate.

DECLARE_DYNAMIC_MULTICAST_DELEGATE[_RetVal, ...]( DelegateName )

Creates a dynamic multi-cast delegate.

Binding Multi-Cast Delegates

Multicast delegates can have multiple functions bound that all get called when the delegate fires. As a result, the binding functions are more array-like in semantics.

Function

Description

Add()

Adds a function delegate to this multi-cast delegate's invocation list.

AddStatic()

Adds a raw C++ pointer global function delegate.

AddRaw()

Adds a raw C++ pointer delegate. Raw pointer does not use any sort of reference, so may be unsafe to call if the object was deleted out from underneath your delegate. Be careful when calling Execute()!

AddSP()

Adds a shared pointer-based (fast, not thread-safe) member function delegate. Shared pointer delegates keep a weak reference to your object.

AddUObject()

Adds a UObject-based member function delegate. UObject delegates keep a weak reference to your object.

Remove()

Removes a function from this multi-cast delegate's invocation list (performance is O(N)). Note that the order of the delegates may not be preserved!

RemoveAll()

Removes all functions from this multi-cast delegate's invocation list that are bound to the specified UserObject. Note that the order of the delegates may not be preserved!

RemoveAll() will remove all registered delegates bound to the provided pointer. Keep in mind that Raw delegates that are not bound to an object pointer will not be removed by this function!

See DelegateSignatureImpl.inl (located in ..\UE4\Engine\Source\Runtime\Core\Public\Delegates\) for the variations, arguments, and implementations of these functions.

Multi-Cast Execution

Multi-cast delegates allow you to attach multiple function delegates, then execute them all at once by calling the multi-cast delegate's Broadcast() function. Multi-cast delegate signatures are not allowed to use a return value.

It is always safe to call Broadcast() on a multi-cast delegate, even if nothing is bound. The only time you need to be careful is if you are using a delegate to initialize output variables, which is generally very bad to do.

The execution order of bound functions when calling Broadcast() is not defined. It may not be in the order the functions were added.

Function

Description

Broadcast()

Broadcasts this delegate to all bound objects, except to those that may have expired.

Getting Started

General Scripting

Building Blueprints

Blueprint Communication

Topics

The Blueprint Visual Scripting system in Unreal Engine is a complete gameplay scripting system based on the concept of using a node-based interface to create gameplay elements from within Unreal Editor. As with many common scripting languages, it is used to define object-oriented (OO) classes or objects in the engine.

This system is extremely flexible and powerful as it provides the ability for designers to use virtually the full range of concepts and tools generally only available to programmers. In addition, Blueprint-specific markup available in Unreal Engine's C++ implementation enables programmers to create baseline systems that can be extended by designers.

Getting Started



Get up and running by creating your first Blueprint.



Overview of using the Blueprint visual scripting system for gameplay.

General Scripting



Overview of using the Blueprint visual scripting system for gameplay.

Building Blueprints



The User Guide is the go-to source to learn the different parts of Blueprints and nodes that are available to use within Blueprint graphs.



The User Guide is the go-to source to learn the different parts of Blueprints and nodes that are available to use within Blueprint graphs.



The Blueprint How-To page provides several short step-by-step guides for working with Blueprints.



Reference covering Blueprint shortcuts and useful actions.



Tips and tricks to help you make decisions about when to use Blueprints and how best to set them up.

Blueprint Communication



Overview of when to use different methods of Blueprint Communications.



Allows a Blueprint Class to report on its state to the Level Blueprint.



Blueprints that declare functions to define an interface between Blueprints.

Topics



An overview of Blueprint Namespaces.



Technical guide for programmers working with Blueprints.



If you are just getting started with Blueprints, this provides a high-level overview of what they are and what they can do.



Pause Blueprint execution using Breakpoints to inspect graphs and the values of their variables.

Level Blueprints vs. Blueprint Classes

Class Variables vs. Local Variables

Functions vs. Macros

Blueprint Communication Types

General Tips

Working in the Blueprint Editor

Setting Up Your Graph

You can do many things with Blueprints. Everything from making a small game or procedural content tools, to prototyping new functionality, to tweaking and polishing things made by programmers, is possible with the Blueprint visual scripting system.

However, there are certain things that will impact your performance more if they are done in Blueprints. If you have a Blueprint that's doing a lot of operations and complex math every tick, you might want to consider using native C++ code. Blueprints are best suited to making event-driven functionality, such as handling damage taking, controls, and other things that don't get called every frame.

If you would like to read more about coding for Blueprints, or the technical details of Blueprint compiling, see the Blueprints Technical Guide.

Even if your functionality is well-suited for Blueprints, there are decisions you can make in setting up your Blueprints that will make things go more smoothly. This guide will go over some of the more common decisions you will have to make, as well as tips and tricks for Blueprint users.

Level Blueprints vs. Blueprint Classes

Level Blueprints may be very familiar to users of UE3's Kismet, because you can select objects directly in the level, and operate on them. They're great for one-off prototypes, and getting familiar with the Blueprints system, but they are specific to the level that they're used in. This does mean that Level Blueprints can be great places to set up functionality specific to the level, or Actors in it. Some examples would be kicking off a cinematic when a certain trigger is touched, or opening a particular door after you kill all the enemies.

In general, Blueprint Classes are the best way to get reusable behavior in your project. If you create a Blueprint Class, you can add it to any of your levels, and you can also add as many copies as you would like to the level, without needing to copy script around.

If you do start out in the Level Blueprint, and then decide to move behavior into a Blueprint Class, this should be a pretty simple process. When you copy functions from a Level Blueprint that operate on Actors (say, calling Set Brightness on a light), and paste them into a Blueprint Class based off of a Light Actor, the functions will update to be in the proper scope.

Read More:

Level Blueprint

Blueprint Class

Class Variables vs. Local Variables

When you're working in your Blueprint, you have the ability to add variables using the Blueprint Editor My Blueprint Panel

When you're inside a function though, you'll see an additional section of the My Blueprint tab for Local Variables.



Local variables are scoped, which means that they only exist where you define them. So, a local variable in a function is only visible to that function, and not to other functions, or the Event Graph. This helps to reduce clutter for things that are only relevant within the context of that function. You can consider local variables a "scratch pad" to work within a function. You can use them to help perform what the function needs to, but they get tossed away after the function has completed.

Class variables are for things that you are potentially going to be interested in accessing from multiple places in the Blueprint. So, things like references to meshes or other components, or variables that need to be public so you can access them from other Blueprints, should be class variables. They're the things you don't want to forget about after you use them.

Functions vs. Macros

Functions and Macros both accomplish the same goal externally: they let you send input into a node, something happens to it, and then outputs come out. They accomplish these in two different ways, but they have some similarities:

Both have a central place where you can edit the functionality of what the node does (macros in their macro graph, and functions in their function graph), and every node that calls the function or macro will be updated whenever that central place is changed.

Both are reusable.

Both allow for local variables. Macros use "anonymous" local variables, which don't have a specific name, but just hold a value.

Both are awesome ways to encapsulate functionality for reusability and clarity.

There are some key differences that will become more apparent as you get into more advanced use cases.

Functions are actually called when you place nodes to call the function. That means you can target them (i.e. "call a function on another object"), and they allow for communication between Blueprints.

Macros take the nodes from the macro graph, and actually replace the macro node with a copy of all those nodes. Basically, when the Blueprint is compiled, the macro copies all the graph nodes, and pastes them in where the macro node is.

Because of how they work under the hood, that means there are a few differences in what you can do:

Macros can use any node for the class they're scoped to (the class you pick when you create a new Macro Blueprint, or if it's a local macro, the class the macro is defined in).This means that you have a little more versatility in the nodes you can put in a macro.

One of the biggest differences between a function and a macro is that you can place latent nodes in a macro, but not in a function.

Functions allow you to override their functionality in child Blueprints. For instance, suppose you had a car Blueprint that had a function "PlayerInteractedWithMe". In that function, you might play a horn honk. Now, suppose you had two children of the car Blueprint, for a police car and a fire truck. In the police car, you could override the function to play a siren noise and turn on the lights. In the fire truck, you could have it squirt water. That sort of overriding functionality isn't possible with macros.

Since macros are just copy-and-pasted into the graph at compile-time, you can have multiple execution wires in and out of a macro. You can't do that in a function.

In general, a good rule of thumb might be to use a macro if there's a quick bit of functionality that you want to reuse everywhere. But, if you might want to tweak that behavior in children of the Blueprint, or you want to access it directly from another Blueprint, it's better to use a function!

Read More:

Functions

Macros

Blueprint Communication Types

There are several different methods for communicating between two Blueprints. While the most common use case is direct Blueprint communication, sometimes the functionality you are going for means that you will use Event Dispatchers or Blueprint Interfaces instead. For an overview of each type of communication, some example use cases, and tutorials to help you get started, see Blueprint Communication Usage.

General Tips

Working in the Blueprint Editor

When working in the Blueprint Editor, there are a few tricks you can use to find the nodes that you want to use, as well as nodes and comments you've already created.

Use the Search button in the Blueprint Editor when you're looking for something in an existing Blueprint, whether it's a variable, function, or comment. It searches all Blueprints, even unloaded ones, if you uncheck the Find in Current Blueprint only box, so it can help you track down just where you implemented something.



The context menu only shows nodes that you can connect to the pin you dragged from (e.g. when you drag from a light, it shows you functions relevant to the light).When you're trying to discover all the possible functionality available to act on a variable or component, just browse through the context menu and see what is available.



Whether you're in the context menu or the palette, the search bar can be very helpful. We tag functions with lots of keywords to help you find what you're looking for, even if you don't know what it's called!



Setting Up Your Graph

While everyone has their own graph setup preferences, here are a few tips that can help you keep things organized and easy to follow:

Keep things tidy from the get go! It's much harder to clean up after you've made a bunch of code than to work clean as you go.

If you find yourself using the same set of nodes more than twice in a graph, consider making it a function or a macro so you can reuse it.

You can stack nodes with their context, because it keeps things more spatially compact. For example, if you have a reference to a light, then you access its point light component, you can stack those two nodes one on top of the other, and think of them as a single block.



Use comments often! Also, don't forget that you can change the color of comment boxes, for extra help identifying sections of your graph.

Blueprint Namespaces

Using the Feature

Importing Namespaces

Setting the Blueprint Namespace

Modifying the Editor Preferences or Project Settings

Implicitly Importing a Namespace

Filtering Non-Imported Types and Actions

Blueprint Namespaces

Blueprint Namespaces optimize the time it takes to open a Blueprint Asset in the editor by preventing unnecessary Assets from loading. This behavior is useful for large projects because the Engine performs initialization tasks by loading all Blueprint Function Libraries and Macro Library assets regardless of whether the Blueprint you were opening was referencing those Libraries.

By grouping Assets into Blueprint Namespaces, you can defer loading the Asset until its is needed. This provides an additional benefit when working inside the Blueprint Editor, as any actions that a Blueprint Asset can take from its context menu will be filtered into its Blueprint Namespace.

Using the Feature

To see a working example of this feature, follow the steps below:

Begin by creating a new Games > Blank Project > with Starter Content enabled named BlueprintNamespaces.



Click the Content Drawer to open it, then navigate to StaterContent > Blueprints and double-click the Blueprint_CeilingLight Blueprint to open its Class Defaults.



From the Toolbar, click the Class Settings, then navigate to the Details panel Blueprint Options category. In the Blueprint Namespace variable, type your namespace into the text field.



In our sample we named the Blueprint Namespace "BlueprintNamespaces.StarterContent"



When entering your namespace into the Blueprint Namespace text field, the editor will validate the string to ensure it does not contain any incompatible characters such as "#" or ",".

Click Compile and Save the Blueprint.



Navigate to the Content Browser, and hover your mouse over the Blueprint_CeilingLight asset to read the tooltip displaying your namespace data.



After launching the editor, you can see which library assets have already been assigned a namespace by searching for "BlueprintNamespace=StarterContent" in the Content Browser.



When you open a Blueprint asset that contains a reference to one of your newly-created assets, it is loaded as a package import dependency of the referencing Blueprint. The same behavior occurs if you base a new Blueprint on a parent Blueprint class that already references one of these assets.

Importing Namespaces

Importing is a similar process to adding an "#include" for a library header in a .cpp source file. When working with Blueprint Namespaces You can import a namespace through any of the following methods:

Setting the Blueprint Namespace

You can add the Blueprint Namespace to the namespace group you want to have access to in the Editor, by following the steps below:

Open the Content Drawer, then double-click your Blueprint to open it's Class Defaults.



From the ToolBar, click the Class Settings and navigate to the Details panel Blueprint Options > Blueprint Namespace category, then type your namespace into the text field.



From the Toolbar, click Compile and Save.



When you open your Blueprint, any shared library assets set to the same namespace are automatically imported when the Blueprint editor initializes.

Modifying the Editor Preferences or Project Settings

If you prefer a workflow where your shared library assets are automatically imported for all Blueprint assets, you can modify the Editor Preferences or Project Settings to ensure your specified subset of shared library assets is imported by the Editor, regardless of whether the Blueprint opened will belong to or import that namespace.

To set up a default import set for your local editor instance:

From the Toolbar, navigate to Edit > Editor Preferences > Content Editors > Blueprint Editor > Experimental, and from the Namespaces to Always Include field, click the Add(+) button to add your namespace as an element to the list.



Navigating to Editor Preferences provides you with the ability to locally modify the Global Namespace set for the Blueprint Editor.



To customize your project for all users to ensure a certain subset of shared library assets is always imported project-wide, you can enable the feature by following the steps below:

Navigate to the Edit > Project Settings > Editor > Blueprint Project Settings > Experimental, then in the Namespaces to Always Include Array List, click Add(+) to add your namespace to the list:



In the Project settings, we have edited the Blueprint Project Settings to include a Namespace called "BlueprintNamespaces.StarterContent".



You can choose to explicitly import one or more namespaces for your Blueprint by clicking the Add(+) button.

Adding an import will immediately load any shared libraries that are currently assigned to the namespace.

Removing an import does not have any negative performance effects in the editor, however you will no longer have the type and action menu filtering behavior associated with that namespace.

Implicitly Importing a Namespace

You can implicitly import a namespace by selecting a non-imported type or action item in the context menu. When you select an unloaded type picker, then that type's package is loaded on the selection of a strong reference type.

To see this feature working:

Create a new Blueprint asset named TestType, then navigate to the Class Settings > Details > Blueprint Options and assign it to a namespace called "YourNameSpace.AutoImportTest":



In our example we named our Blueprint Namespace as BlueprintNamespaces.AutoImportTest.



Click Compile and Save, then re-launch the editor.



Click the Content Drawer, then navigate to Content > StarterContent > Blueprints and double click Blueprint_CeilingLight to open its Class Defaults.



You can open any of your existing Blueprints, or create a new one. In our example, we chose to use the existing Blueprint_CeilingLight.

From the Class Defaults, navigate to My Blueprint > Variables and click Add(+) to create a new variable named TestTypeVar.



Click the Boolean drop-down arrow to bring up the pin type selector, then In the text field search and select TestType then choose Object Reference.



Click the Class Settings, then navigate to the Details panel > Imports > Imported Namespaces, and you will see YourNamespace.AutoImportTest is now listed among the Imported Namespaces category.



Using Auto-import doesn't require the type to be unloaded. Your namespace (if non-global and not yet imported) is auto-imported upon selection. Enabling namespace import features will auto-import that asset's namespace into the Blueprint.

If you change a default value on any function input argument, then the local variable will import any namespace associated with the value.

Changing the default value of a struct or container type will import any namespace associated with the container's inner value and struct child member property.

Adding any new component in the Components panel will automatically import any namespace associated with that selected component type. This behavior also applies to non-imported component types.

Filtering Non-Imported Types and Actions

By default, non-imported types and actions are displayed in the context menu, but if you wish to enable an additional layer of filtering for non-imported types:

Click the Content Drawer, then click Add(+) > Create an Advanced Asset > Blueprints > Blueprint Function Library named Bp_FilterFunctionLibrary.



Double-click the Bp_FilterFunctionLibrary to open its Class Defaults. From the My Blueprint panel, navigate to the Functions category and rename NewFunction_0 to FilteredFunction_0. Class Settings and navigate to Details > Blueprint Options > Blueprint Namespaces, then enter "YourNamespace.FilterTest".



In our example, this becomes "BlueprintNamespaces.FilterTest".



Click the Add(+) button to create a new function named FilteredFunction_1.



Click the Class Settings then from the Details panel, navigate to Blueprint Options > Blueprint Namespace, then select Your namespace from the drop down menu "YourNamespace.FilterTest" (in the example shown below, this becomes "BlueprintNamespaces.FilterTest").



Click Compile and Save.



Navigate to Content > StarterContent > Blueprints and double click the Blueprint_CeilingLight to open its Class Defaults.



From the Class Defaults, navigate to the Event Graph then right click to open the Actions menu. When you search for your Filtered Function it will appear in the context menu.





Interface Breakdown

Blueprint visual scripting is a system that is used throughout Unreal in different ways. Blueprints can drive level-based events, control internally scripted behaviors for in-game Actors, and be used to control complex animations across highly realistic game character systems. For each of these Blueprint applications, the location where you edit that Blueprint script, as well as the tools available to you, will change depending on your needs. This means that there are multiple places and different ways within Unreal Engine that the Blueprint Editor can appear. However, no matter the differences, the Blueprint Editor can create and edit powerful visual scripts to drive various aspects of your game.

The Blueprint Editor is a node-based graph editor. It is your primary tool for creating and editing visual scripting node networks, commonly referred to as Blueprints. The Blueprint Editor includes a context sensitive design that helps you access functionality for the objects you need specifically when you need them, while also providing flexibility for those times when you need to do something a bit unconventional.

Here are some critical things to know about the Blueprint Editor:

It includes several tools and panels tools to help you create your own variables, functions, arrays, and more.

It has a variety of debugging and analysis tools built into it to help you quickly debug and improve data flow in your networks.

Within Unreal Engine, the Blueprint Editor comes in a variety of different specialized forms depending on the types of Blueprint networks you are editing.

Before you get too far into the Blueprint Editor, you should make sure you have a solid understanding of Blueprints themselves. For more information, refer to Getting Started with Blueprints, and Blueprints Overview.

Interface Breakdown

The Blueprint Editor's location and available toolset will be different based on the type of Blueprint you are currently editing, our goal in this document is to allow you the freedom to choose whether you want to see a UI breakdown for a specific form of the Blueprint Editor, or if you would just like to get a sequential list of everything available.

If you are completely new to Blueprint editing, or are unsure what type of Blueprint you are currently working on, it will be useful to familiarize yourself with the various Blueprint Types.



A breakdown of the UI elements of the Blueprint Editor when working on Level Blueprints.



A breakdown of the UI elements of the Blueprint Editor when working on Blueprint Classes.



A breakdown of the UI elements of the Blueprint Editor when working on Blueprint Interfaces.



A breakdown of the UI elements of the Blueprint Editor when working on Blueprint Macro Libraries.



Animation Blueprint UI

An overview of the Animation Blueprint Editor and its user interface.

Creating Bookmarks

Viewing and Using Bookmarks

Quick Jump Bookmarks

With Blueprint Bookmarks you can create named Bookmarks in any function graph in the Blueprint Editor. This bookmark will capture the position and zoom level of the Viewport and the active tab you were viewing when you created the bookmark. Bookmarks are stored locally on your machine, so they won't affect the Blueprint itself, and syncing your content will not overwrite your Bookmarks with another user's Bookmarks.

Creating Bookmarks

To create a Blueprint Bookmark:

With the Graph and Zoom position you wish to Bookmark, click the Star icon in the upper-left of the graph.



In the New Bookmark dialog box, enter your desired name and click the Add button.



Viewing and Using Bookmarks

To view or use a previously created Bookmark, select the Bookmarks option from the Window menu.



This will open the Bookmarks menu that displays all the Bookmarks for the current asset as well as any Comment Nodes.



In the Bookmarks window, clicking the Eye icon in the upper-right corner will expand additional options. Disabling Show Comment Blocks removes Comment Nodes from being displayed in the menu.



Enabling Show Bookmarks for Current Graph Only will show Bookmarks for your active Graph, while disabling it will show all Bookmarks for the asset while on any Graph.

For Bookmarks displayed in the window, you can right-click on a Bookmark (or Comment) to expand additional options.

The right-click context menu enables you to Delete or Rename Bookmarks, as well as to jump directly to the selected Bookmark (or Comment).

Double-click on a Bookmark or Comment Node block to jump to that section of your Graph.



When jumping to a Bookmark, the Star icon in the upper-left of the Graph will also be filled indicating you are at the Bookmark.

Quick Jump Bookmarks

In addition to creating Bookmarks, you can create a Quick Jump Bookmark, similarly to how Bookmarks work in the Level Editor Viewport. As with labeled Bookmarks in the Blueprint Editor, Quick Jump Bookmarks will persist across Editor sessions and are local to the user and machine where they were created.

To assign and use a Quick Jump Bookmark:

With a Graph open, press Ctrl + 0-9 (any number key) to remember your current Blueprint, Graph location and Zoom level.

Inside any Graph, press Shift + 0-9 (the same number from previous step) to return to that Blueprint, Graph location and Zoom level.

Quick Jump Bookmarks do not require you to have the asset open. They will automatically open the asset, Graph location and Zoom level.

Get Class Defaults

The Class Defaults tab contains information about the Blueprint's default settings and properties, and about any variables the Blueprint contains. You can modify these settings to suit your needs.



The Class Defaults tab contains the following sections:

Item

Description

Default

Lists any variables and their values if you do not specify a different category than Default when you create them. Note that you must compile the Blueprint in order to display its variables on the Class Defaults tab.

Rendering

Contains information about properties related to how (and whether) an Actor based on the Blueprint is rendered in the game.

Replication

Contains information about properties that dictate how your Actor behaves in a networked game, such as its network priority and relevancy to other clients.

Input

Contains information about how Actors based on this Blueprint respond to input.

Actor

Contains information about Actors based on this Blueprint, such as whether they can be damaged. Note that for Level Blueprints, only the Tags properties are relevant in this section.

If you create custom categories for variables, the Class Defaults tab will display those categories too, after the Blueprint is compiled.

Get Class Defaults

The properties defined inside the Class Defaults can also be accessed at runtime through the use of the Get Class Defaults Blueprint node. Targeted use case is for data-only Blueprint Class types and other cases where you may not necessarily need/want to create an instance in order to access default property values.

To Access the Get Class Defaults Node

Right-click inside your Blueprint Class or Function Graph and enter GetClassDefaults from the context menu.



Choose the class to access via the class picker drop-down menu.



You can also wire in a class type result from a function call or variable instead as shown in the example below.



With the node selected, you can show/hide pins via the Details panel.



Usage Notes

Output pins (accessible class properties) are shown by default and can be optionally hidden (similar to Struct Break/Set Nodes).

Parent class properties are currently hidden by default to reduce the number of output pins.

Properties tagged as Advanced View are also hidden by default in the Advanced node section.

Object reference property default values are not currently exposed.

This means you currently cannot, for instance, access the default property values of component templates or other archetypes within a Blueprint Class.

This is because we do not currently enforce read-only reference types in a Blueprint, and we'd need to do that in order to ensure that the internal state of the referenced object cannot be changed.\

Only BlueprintVisible or BlueprintReadOnly properties are currently exposed for defaults access.

This matches the behavior of "normal" variable Get nodes exposed through the context menu.

Currently the Class input drop-down lists all UOBject-derived class types (including engine classes).

This may be limited in the future to exclude engine-specific class types.

Adding a GetClassDefaults node to an Actor-based Blueprint class (for example) will currently default the input class pin's value to match the current Blueprint Class type when placed.

A Data-Only Blueprint is a Blueprint Class that contains only the code (in the form of node graphs), variables, and components inherited from its parent. These allow those inherited properties to be tweaked and modified, but no new elements can be added. These are essentially a replacement for archetypes and can be used to allow designers to tweak properties or set items with variations.

Data-Only Blueprint are edited in a compact property editor, but can also be "converted" to full Blueprints by simply adding code, variables, or components using the full Blueprint Editor.

Blueprint Interface Editor UI

A Blueprint Interface is a collection of one or more functions - name only, no implementation - that can be added to other Blueprints. Any Blueprint that has the Interface added is guaranteed to have those functions. The functions of the Interface can be given functionality in each of the Blueprints that added it. This is essentially like the concept of an interface in general programming, which allows multiple different types of Objects to all share and be accessed through a common interface. Put simply, Blueprint Interfaces allow different Blueprints to share with and send data to one another.

Blueprint Interfaces can be made by content creators through the editor in a similar fashion to other Blueprints, but they come with certain limitations in that they cannot:

Add new variables

Edit graphs

Add Components

Blueprint Interface Editor UI

When you first open a Blueprint Interface, the UI will look extremely simple, consisting only of the following:



Default Visible UI Components

Available in the Window Menu

Menu

Toolbar

My Blueprint

Details

Graph Editor

Debug

Compiler Results

Find Results

It is important to note that the Graph View in this case is a bit different than the Graph Editor usually available within the Blueprint Editor. You might notice that it is grayed out and that you can neither navigate it nor can you add any nodes to it. That is because this is more of a visualization tool than it is a way to edit the graph. Keep in mind that an Interface holds no functionality in and of itself, so there is no need to create an actual functioning network in this case. Think of this view as just a preview of what your inputs and outputs will be.

For more information on creating and working with Blueprint interfaces, please see Blueprint Interface.

Interface

A Level Blueprint is a specialized type of Blueprint that acts as a level-wide global event graph. Each level in your project has its own Level Blueprint created by default that can be edited within the Unreal Editor, however new Level Blueprints cannot be created through the editor interface.

Events pertaining to the level as a whole, or specific instances of Actors within the level, are used to fire off sequences of actions in the form of Function Calls or Flow Control operations. Those familiar with Unreal Engine 3 should be very familiar with this concept as this is very similar to how Kismet worked in Unreal Engine 3.

Level Blueprints also provide a control mechanism for level streaming and Sequencer as well as for binding events to Actors placed within the level.

Interface

The Blueprint Editor contains the following sections when editing Level Blueprints:



Default Visible UI Components

Available in the Window Menu

Menu

Toolbar

My Blueprint

Details

Graph Editor

Compiler Results

Debug

Find Results

Palette

Viewport

Interface

A Blueprint Macro Library is a container that holds a collection of Macros or self-contained graphs that can be placed as nodes in other Blueprints. These can be time-savers as they can store commonly used sequences of nodes complete with inputs and outputs for both execution and data transfer.

Macros are shared among all graphs that reference them, but they are auto-expanded into graphs as if they were a collapsed node during compiling. This means that Blueprint Macro Libraries do not need to be compiled. However, changes to a Macro are only reflected in graphs that reference that Macro when the Blueprint containing those graphs is recompiled.

For more information on Macro Libraries and how to use them, please see the Blueprint Macro Library documentation.

Interface

Much like with Blueprint Interfaces, when you first open the Blueprint Editor for a Macro Library, you will see a simplified UI without a graph:



Default Visible UI Components

Available in the Window Menu

Menu

Toolbar

My Blueprint

Details

Graph Editor

Debug

Find Results

Palette

Interface

Opening the Compiler Results Panel

Error and Warning Navigation



The Compiler Results panel provides feedback on the compiling of your Blueprint scripts, telling you whether a Blueprint script compile was successful or if there were errors or warnings. Whenever errors or warnings are found, the Compiler Results panel gives information on the error and provides hyperlink access, enabling you to jump the graph view directly to the source of the problem.

Interface

The UI of the Compiler Results panel is very simple, consisting primarily of a self-populated list of compile successes, warnings, and errors (failures). Each entry can be moused over for further information, where applicable, and any warnings or errors will also offer a hyperlink, which will take you to the source of the message.



Result List - This self-populated list shows the results of your compile. Any hyperlinks to errors and warnings will appear. If the compile was successful, you will also see the total compile time in milliseconds.

Pop-up Help - By mousing over any entry in the list, you can get more information about the nature of the entry. In the case of hyperlinks, you will get the path directly to the problematic node.

Clear Button - This simply clears out the existing list of results.

Opening the Compiler Results Panel

The Compiler Results panel will not always be available by default, but can be found within the Window menu of the Blueprint Editor. The panel will also open automatically whenever a Blueprint compile results in errors or warnings. Generally, the panel will appear at the bottom of the current Graph panel.

Error and Warning Navigation

Whenever your compile process results in a warning or error, the Compiler Results panel enables you to do the following:

Mouse over a message to see further detail.



Mouse over the hyperlink at the end of a message to see a link to the problematic node.



Click on a message to jump the graph view directly to the problematic node or part of the visual script.



Click the Clear button at the bottom right corner of the panel to clear out any existing messages.



Interface

The Debug panel provides a list of all debug tools currently in use for the Blueprint, such as Breakpoints and Watch Values. During Play-In-Editor, it also provides access to the Execution Trace, showing you each node execution taking place within a given Blueprint.

For more information on debugging Blueprints, please see Blueprint Debugger.

Interface

The interface for the Debug panel changed depending on whether or not you are playing or simulating in the Editor.

When not playing or simulating:



When not playing, the Debug panel lists off any watch values and breakpoints within your current Blueprint.

When playing or simulating:



When playing or simulating the Debug panel shows debug info, as well as the Execution Trace, which shows how long each node is taking to execute.

Interface

The Details panel is a context-sensitive area that provides editing access to the properties of selected items within the Blueprint Editor. It is composed of a search bar for fast access to specific properties, and will generally contain one or more collapsible categories to organize the included properties.

The Details panel is also where you will handle many Blueprint editing tasks, including:

Editing process for Blueprint variables, including changing name, type, and whether the variable is an array.

Implement Blueprint interfaces after clicking the Blueprint Props button.

Adding inputs and outputs for Blueprint functions.

Add Events for selected Components.

Interface



Search Filter - Type the name of the property you need and the properties below filter down.

Property Matrix - Opens the Property Matrix panel for spreadsheet-like editing of available properties.

Visibility Filter - Allows you to show or hide modified or advanced properties, as well as collapse or expand all categories.

Collapsible Categories - These areas are used to group together related properties, and can be expanded and collapsed using the small white triangle to the left of the name.

Each of these areas are context sensitive. In any case where one of these areas does not apply to the currently selected item, the area simply will not appear. It is normal with many Blueprint nodes, for example, to see a primarily blank Details panel.

Interface

The Find Results panel is a powerful search tool within the Blueprint Editor that allows you to quickly track down a variety of objects based on the following criteria:

Node name

Pin name

Node Comment

Property name

Property value

As the Find Results panel tracks down search matches, it will display a list of results, each of which works like a hyperlink that will jump the graph view to the resulting node. This makes it an excellent way to track down a specific node or piece of information that may be buried somewhere within a complex network of Blueprint scripting nodes.

Much like searching in a web browser, the Find Results panel is available by pressing Ctrl-F while working in the Blueprint Editor. By default, the panel will appear along the bottom of the Graph Panel. If the Compiler Results panel is showing, then the Find Results panel will dock alongside it.

Unlike many search fields in Unreal Engine 4, the Find Results panel does not filter results actively while you type, due to the sheer volume of possible results. Once you press Enter, the list will populate.

Interface



Results list - This lists all nodes, pins, property names, comments, and property values that match the search criteria.

Search filter - This is where you type in what you are looking for.

Property values - Explicitly set property values will appear in parentheses in the middle of the results.

Comments - Node comments, if they exist, will appear in yellow text on the right side of the panel.

Find in Current Blueprint Only - When active, the search is limited only to the current Blueprint. When deactivated, the search looks through all Blueprints in the project.

Graph Editor Controls

The Graph Editor panel is the heart of the Blueprint system. It is here that you will create the networks of nodes and wires that will define your scripted behavior. Nodes can quickly be selected by clicking on them and repositioned via dragging.



Graph Area - This is where you will actually lay out all of your nodes.

Forward and Back Buttons - These allow you to jump between different graphs very much as you would navigate a web browser.

Tabs area - As you open different graphs, tabs for each one will open here, allowing you to quickly jump between different graphs.

Breadcrumbs - These show a progression of graphs and subgraphs. As you step down into functions or collapsed graphs, this will show you where you are within your network.

Zoom Factor - This simply shows the current zoom ratio in the graph editor.

Blueprint label - This shows the type of Blueprint you are editing. As you edit Blueprint Interfaces, Animation Blueprints, Macros, and other types, this label will update.

Graph Editor Controls

The Graph Editor tab can be navigated using the controls below:

Control

Action

Right-Click + Drag

Pans the Graph.

Mouse Scroll

Zooms the Graph.

Right-Click

Brings up context menu.

Click on node

Selects the node.

Click + Drag in empty space

Selects the nodes inside the marquee select box.

Ctrl + Click + Drag in empty space

Toggles selection of the nodes inside the marquee select box.

Shift + Click + Drag in empty space

Adds the nodes inside the marquee select box to the current selection.

Click + Drag on node

Move node.

Click + Drag from pin to pin

Wires the pins together.

Ctrl + Click + Drag from pin to pin

Moves wires from origin pin to destination pin.

Click + Drag from pin to empty space

Brings up context menu showing only relevant nodes. Wires the original pin to a compatible pin on the created node.

Alt + Click on a pin

Remove all wires connected to the selected pin.

StaticMesh, SoundCue, SkeletalMesh, and ParticleSystem assets can be dragged from the Content Browser and dropped on the Graph Editor tab to create a new AddComponent function call with the asset automatically assigned.



File

Edit

Asset

View

Debug

Window

The Menu is displayed at the top of the Blueprint Editor by default.

File

Command

Description

Load and Save

Save

Saves the Blueprint.

Open Asset...

Summons the asset picker window.

Save All

Saves all unsaved levels and assets.

Choose Files to Save...

Opens a dialog with save options for content and levels.

Connect to Source Control...

If Source Control is enabled, opens a dialog with check-in options for content and levels.

Blueprint

Compile

Compiles the Blueprint.

Refresh All Nodes

Refreshes all nodes in the graph to account for external changes.

Reparent Blueprint

Change the parent of the open Blueprint.

Diff

Diff against previous revisions. Requires source control to be active.

Developer

Open the Developer Menu, where you can change compiler settings and recompile modules like the Graph Editor.

Edit

Command

Description

History

Undo

Undo the last action.

Redo

Redo the last undone action.

Undo History

Displays the entire Undo History.

Search

Search

Find references to functions, events, variables, and pins in the current Blueprint.

Find in Blueprints

Find references to functions, events, variables, and pins in ALL Blueprints.

Delete Unused Variables

Deletes any variables that are never used.

Configuration

Editor Preferences

Opens the settings for the Editor.

Project Settings

Opens the settings for the current project.

Plugins

Opens the Plugin Browser tab.

Asset

Command

Description

Find in Content Browser...

Summons the Content Browser and navigates to this asset.

Reference Viewer...

Launches the reference viewer to show what the current asset references and what references the current asset.

Size Map...

Displays an interactive map showing the approximate size of this asset and everything it references.

View

Command

Description

Pin Visibility

Show All Pins

Shows all pins on all nodes.

Hide Unused Pins

Hides all pins with no connections and no default values.

Hide Unconnected Pins

Hides all pins with no connections. This option will hide input pins for inputs that have been set directly on the node.

Zoom

Zoom to Graph Extents

Fits the current view to the entire graph.

Zoom to Selection

Fits the current view to the selection.

Debug

Command

Description

Breakpoints

Disable All Breakpoints

Disables all breakpoints in all graphs of the current Blueprint or Level Blueprint.

Enable All Breakpoints

Enables all breakpoints in all graphs of the current Blueprint or Level Blueprint.

Delete All Breakpoints

Removes all breakpoints in all graphs of the current Blueprint or Level Blueprint.

Watches

Delete All Watches

Removes all watch values in all graphs of the current Blueprint or Level Blueprint.

Window

The Window menu in the Blueprint Editor has a specific subsection for displaying Blueprint Editor-specific tabs. Not all tabs will be present in the menu while the Blueprint Editor is in the Defaults and Components modes.

Command

Description

Toolbar

Shows the Toolbar if it is currently not visible.

Details

Shows the Details pane if it is currently not visible.

Debug

Shows the Debug pane if it currently not visible.

Palette

Shows the Blueprint Editor Palette pane if it is not currently visible.

My Blueprint

Shows the Blueprint Editor My Blueprint Panel pane if it is not currently visible.

Compiler Results

Shows the Compiler Results pane if it is not currently visible.

Find Results

Shows the Find Results pane if it is not currently visible.

Components

Shows the Components panel if it is not currently visible.

Viewport

Shows the Preview Viewport pane if it is not currently visible.

Content Browser

Opens a sub-menu with access to all four Content Browsers.

Developer Tools

Sub-Menu Item

Description

Blueprint Debugger

Opens the Blueprint Debugger, which shows you the current "stack" of commands that is being run in a Blueprint along with all watched values.

Collision Analyzer

Shows the Collision Analyzer.

Debug Tools

Show the Debug Tools panel, which contains an assortment of functions for common debug tasks (reloading textures, showing texture atlases, gamma correction, etc...)

Message Log

Opens the Message Log. This is where errors or warnings from the Editor will go.

Output Log

Opens the Output Log. If you are debugging something using Print it will appear here.

Visual Logger

Opens the Visual Logger.

Class Viewer

Opens the Class Viewer.

Device Manager

Opens the Device Manager.

Device Profiles

Opens the Device Profiles Tab.

Session Frontend

Shows the Session Frontend. Please see the Unreal Frontend documentation for more information.

Widget Reflector

Opens the Widget Reflector. This enables you to see the various Slate elements that make up the interfaces within the Editor interface.

Project Launcher

Shows the Project Launcher which enables you to run your project on any appropriately setup and connected devices.

Plugins

Shows the Plugin Tab where you can load/unload plugins.

Reset Layout...

Restores the default layout for the entire Unreal Engine 4 Editor. This requires the Editor to restart, but it will re-open the current project.

Save Layout

Saves the current interface layout.

Enable Fullscreen

Enables fullscreen mode for the Main Editor window.

Creation Buttons

My Blueprint Sections

Searching in My Blueprint

The My Blueprint tab displays a tree list of the graphs, scripts, functions, macros, etc. contained within the Blueprint. This is essentially an outline of the Blueprint that lets you easily view existing elements of the Blueprint, as well as create new ones.

Different types of Blueprints will have different types of items shown in the My Blueprint tab tree list.



For example, a normal Blueprint will always have a ConstructionScript and an EventGraph. In addition, any functions created within the Blueprint will be displayed. A Level Blueprint will only have an EventGraph and any functions created within it. An Interface will only display the functions created within it. A Macro Blueprint will display the macro functions created within it.

Creation Buttons

The My Blueprint tab has shortcut buttons (the at the end of each heading) for creating new variables, functions, macros, event graphs, and event dispatchers.

Button

Name

Description



New Variable

Creates a new variable when clicked. The properties of that variable immediately appear in the Details tab. There, you can change the name, type, and other properties.



New Function

Creates a new function, then immediately puts focus on the Name field of the Details tab so that it can be named. A new graph view will also be opened where you can define the node network for the function.



New Macro

Creates a new macro, then immediately puts focus on the Name field of the Details tab so that it can be named. A new graph view will also be opened where you can define the node network for the macro.



New Event Graph

Creates a new function, then immediately puts focus on the Name field of the Details tab so that it can be named. The new graph appears and is ready to have a node network defined within it.



New Event Dispatcher

Creates a new event dispatcher, then immediately puts focus on the Name field of the Details tab so that it can be named.

These same buttons can also be accessed by Right-clicking in the My Blueprint tab. The Right-click menu also includes an option for creating a new enum asset.



Finally, you can use the Add New button at the top of the My Blueprint Panel



My Blueprint Sections

The My Blueprint tab is divided up into 6 sections: The Add New, Graphs, Functions, Macros, Variables, and Event Dispatchers sections.



The 5 lower sections will organize elements of your Blueprint into their respective groups. While the top section gives you quick access to create new Graphs, Variables, etc... and search the entire My Blueprint panel.

Searching in My Blueprint

The My Blueprint tab contains a text box used for searching the graphs belonging to the Blueprint. This works the same way as the contextual action menu that you use for adding new nodes, but is limited to searching items found within My Blueprint. You can search based on name, comment, and other data. So, if you know you have a node that is SetActorHidden, you can type that in the box, and the explorer will show you all the SetActorHidden nodes in your graph.

Interface

Class Filtering

The Palette panel displays a list of all functions and variables that can be used in Blueprints. It is fully searchable, contains a Favorites panel that you can populate with the nodes you find yourself using the most, and you can filter it to search for nodes that are compatible with a specific class type. Nodes from the Palette panel can be added into your networks by simply dragging and dropping them from the list.

Interface



Favorites - This shows your favorite and frequently used nodes. You can add nodes to this area by Right clicking them within the Palette panel and choosing Add to Favorites.

Palette list - This is a list of all available functions, filterable by class and searchable.

Favorites search bar - Actively filters the Favorites list while you type.

Class Filter - This filters the Palette panel to only show nodes which are compatible with a specific class. See Class Filtering for more details.

Palette search bar - Actively filters the Palette list while you type.

Class Filtering

Sometimes it is useful to filter down the Palette to only show those nodes that are compatible with a given class type. This is done using the Class Filter dropdown. When clicked, it shows a list of all classes available in your project, similar to the Class Viewer panel. It also contains a search bar that you can use to actively filter down the list.



Toolbar Buttons

The Toolbar is displayed at the top-left of the Blueprint Editor by default. The Blueprint Editor Toolbar buttons provide easy access to common commands needed when editing Blueprints. The Toolbar provides different buttons depending on which mode is active and which Blueprint type you are currently editing.



The Toolbar contains two sections:

Toolbar options - Tools for working with your Blueprint.

Mode buttons - Buttons that you can use to switch which mode your Blueprint is in.

Toolbar Buttons

Button

Description



Compilation was successful. Clicking the button compiles the Blueprint being edited. Output from the compiling process is displayed in the Blueprint Log of the Message Log. This button will be inactive during debugging.



The Blueprint needs to be recompiled. Clicking the button compiles the Blueprint being edited. Output from the compiling process is displayed in the Blueprint Log of the Message Log. This button will be inactive during debugging.



There was a warning during compilation. Clicking the button compiles the Blueprint being edited. Output from the compiling process is displayed in the Blueprint Log of the Message Log. This button will be inactive during debugging.



Compilation failed. Clicking the button compiles the Blueprint being edited. Output from the compiling process is displayed in the Blueprint Log of the Message Log. This button will be inactive during debugging.



Saves the current Blueprint.



Summons the Content Browser and navigates to this asset.



Finds references to functions, events, variables, and pins in the current Blueprint.



Opens the Blueprint Properties in the Details pane.



Shows the Class Defaults Panel in the Details Tab



Starts the game in simulation mode. See the Simulate In Editor section for more information.



Starts the game in normal play mode. Clicking the arrow displays the Play Options menu. See the Play In Editor section for more information.



Pauses simulation. When the simulation is paused, the Resume and Frame Skip buttons will appear on the toolbar.



Resumes execution after a breakpoint is hit or the Pause button is pressed.



Advances a single frame, or tick. This button appears when simulation is paused, or when a breakpoint is hit.



Halts execution of the game and exits Simulate In Editor mode.



Switches from Simulate In Editor mode to Play In Editor mode. Attaches to the player controller, allowing normal gameplay controls. Toggles with Eject.



Switches from Play In Editor mode to Simulate In Editor mode. Detaches from the player controller, allowing regular editor controls. Toggles with Possess.



Steps through execution of the graph one node at a time. This button appears during simulation after a breakpoint is hit.



If you have one or more instances of a Blueprint in a level, this dropdown allows you to select which instance to debug.

The View Menu

In the Viewport, in the Blueprint Editor, you can view and manipulate your Blueprint's components.



You can also manipulate a selected component by adjusting its values manually in the Details panel.

Selecting a component in the Component list selects that component in the Viewport too, and populates the Details panel with its property information.

You can use the transformation widgets in the Viewport to adjust the location, rotation, and scale of selected components. For more information about transformation widgets, see Interactive Transforms.

You can navigate in the Blueprint Editor's Viewport in the same ways in which you navigate in the Level Editor's Viewport. For more information, see Viewport Controls.

The View Menu

The View drop-down menu, in the Viewport's upper-left corner, has somewhat different options than the Level Editor's Viewport menus.



Item

Description

Reset Camera

Refocuses the camera on the components.

Realtime

Toggles realtime rendering of the viewport.

Show Floor

Toggles whether a floor is displayed to assist with the placement of components.

Show Grid

Toggles viewport grid.

For more information about the Level Editor Viewport, see the Main Editor Viewports documentation.

B

C

E

F

I

P

Quick Jump: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

B

Generic term that can refer to the visual scripting system as a whole or a standard class Blueprint that defines a new class or type of Actor.

C

Event defined through the Blueprint Editor that can be executed via nodes in an EventGraph.

E

Executable method defined through code that has no return value and does not have any output parameters. Events are the starting points for execution and, thus, have only an output exec pin. These are executed from native code. Also see Custom Events.

F

Executable method defined either through code or through the Blueprint Editor that has at least one output parameter or return a value. Functions can either be Pure or Impure.

Node that can be placed in an EventGraph to execute a Function.

I

Function that is free to modify state or members of the class. See the Pure vs Impure section for more details.

P

Variable that is only editable in the Class Defaults, and is reset to that default value each time the construction scripts are run. Private variables can be used to keep track of state within the Blueprint.

Variable that is editable individually on each instance of the Blueprint, but is considered constant within the graphs of the Blueprint. Public variables can be used to allow designers to tweak the look or behavior of a Blueprint on a per-instance basis.

Function that promises not to modify state or members of the class. See the Pure vs Impure section for more details.

Blueprints are a powerful new feature introduced in Unreal Engine 4. Blueprints are a way to create new UClasses without the need for writing or compiling code. When you create a Blueprint, you can choose to extend a C++ class or another Blueprint class. You can then add, arrange, and customize Components, implement custom logic using a visual scripting language, respond to Events and interactions, define custom Variables, handle Input, and create a fully custom object type.

Each Blueprint has a Construction Script, analogous to a constructor in C++, which is run when the object is created. This script can dynamically construct the Actor instance based on any number of factors, such as a fence that automatically sizes itself to fill a gap between buildings. In this sense, a Blueprint can be thought of as a very powerful prefab system.



Information about Blueprint Function Libraries for C++ in Unreal Engine.



The steps of the Blueprint compilation process



Technical guide for gameplay programmers exposing gameplay elements to Blueprints.



Tips and tricks for how best to write a Blueprint-friendly API

Often during the development of your project, you may discover the need for a set of functions that make development easier. These functions typically are stateless and reused across a variety of gameplay code. This need may present itself when building with Blueprints. In a previous section of this manual, you saw how to expose your game objects' functions and properties to Blueprints. However, if you want to expose shared utility functions, you don't necessarily want to tie them to a specific gameplay object type. For those cases, we have Blueprint Function Libraries.

Blueprint Function Libraries are a collection of static functions that provide utility functionality not tied to a particular gameplay object. These libraries can be grouped into logical function sets, e.g. AI Blueprint Library, or contain utility functions that provide access to many different functional areas, e.g. System Blueprint Library.

Creating a Blueprint Function Library is very similar to exposing functions to Blueprints using the UFUNCTION() macro. Instead of deriving from an Actor or directly from UObject all Blueprint Libraries inherit from UBlueprintFunctionLibrary. They should also contain only static methods. The code below is a snippet from the Analytics Blueprint Library, showing how to setup your library class.

As you can see in the example above, a Blueprint Function Library is indirectly a UObject derived and therefore requires the standard UCLASS() and GENERATED_UCLASS_BODY() macros. It decorates the functions that are to be callable from Blueprints with the UFUNCTION() macro. Functions in a Blueprint Function Library can be designated as BlueprintCallable or BlueprintPure depending on whether the calls have side effects or not.

See Engine/Plugins/Runtime/Analytics/AnalyticsBlueprintLibrary for the full source code.

Below is the implementation of the StartSession() function:

The implementation above interacts with a non-UObject derived singleton object. This is a good way to expose 3rd party library functions to Blueprints or to interact with C++ classes that don't have UObject support. The code below is an example of a Blueprint Function Library method that performs some common work to find the AIController for a controlled actor:

This function takes what would be multiple Blueprint nodes and rolls that into a single node. Of course, you could have made a function in Blueprints for this, but if it's called often the C++ version will yield better performance.

Terminology

Compilation Process

Blueprints, like regular C++ classes, need to be compiled before they can be used in-game. When you hit the Compile button in the Blueprint Editor, the process of converting the properties and graphs of a Blueprint asset into a class is performed.

Terminology

The class that does the work of compilation. A new instance is spawned for each compile. Stores reference to the class being compiled, the blueprint, etc.

Holds the information for compiling a single function, like a reference to the associated graph, properties, and generated UFunction.

A helper class that handles processing one class of node in the compiler (a singleton). Contains functions for registering pin connections, and generating compiled statements.

Unit of work in the compiler. The compiler translates nodes into a set of compiled statements, which the backend translates into bytecode operations.

A terminal in the graph (literal, const, or variable reference). Each data pin connection is associated with one of these! You can also make your own terms in a NodeHandlingFunctor for scratch variables, intermediate results, etc.

Compilation Process

The basic process of compiling a Blueprint is outlined below:

(Click item to view)

Clean the Class

Create Class Properties

Create Function List

Bind and Link the Class

Compile Functions*

Finish Compiling Class

Backend Emits Generated Code*

Copy Class Default Object Properties



Reinstance



*Full Compile Only

Clean the Class

Classes are compiled in place, which means the same UBlueprintGeneratedClass is cleaned and reused over and over, so that pointers to the class do not have to be fixed up. CleanAndSanitizeClass() moves properties and functions off the class and into a trash class in the transient package, and then clears any data on the class.

Create Class Properties

The compiler iterates over the Blueprint's NewVariables array, as well as some other places (construction scripts, etc.) to find all of the UProperties needed by the class and then creates UProperties on the UClass's scope in the function CreateClassVariablesFromBlueprint().

Create Function List

The compiler creates the function list for the class by processing the event graphs, processing the regular function graphs, and pre-compiling the functions, i.e. calling PrecompileFunction() for each context.

Processing of the event graphs is performed by the CreateAndProcessUberGraph() function. This copies all event graphs into one big graph, after which nodes are given a chance to expand. Then, a function stub is created for each Event node in the graph, and an FKismetFunctionContext is created for each event graph.

Processing of the regular function graphs is done by the ProcessOneFunctionGraph() function, which duplicates each graph to a temporary graph where nodes are given a chance to expand. A FKismetFunctionContext is created for each function graph as well.

Pre-compiling of the functions is handled by the PrecompileFunction() of each context. This function performs the following actions:

Schedules execution and calculates data dependencies.

Prunes any nodes that are unscheduled or not a data dependency.

Runs the node handler's RegisterNets() on each remaining node.

This creates the FKismetTerms for values within the function.

Creates the UFunction and associated properties.

Bind and Link the Class

Now that the compiler is aware of all of the UProperties and UFunctions for the class, it can bind and link the class, which involves filling out the property chain, the property size, function map, etc. At this point, it essentially has a class header - minus the final flags and metadata - as well as a Class Default Object (CDO).

Compile Functions

The next step consists of generating FKismetCompiledStatment objects for the remaining nodes which is accomplished through the node handler's Compile() function, using AppendStatementForNode(). This function can create FKismetTerm objects in the compile function as long as they are only used locally.

Finish Compiling Class

To finish compiling the class, compiler finalizes the class flags and propagates flags and metadata from the parent class before finally performing a few final checks to make sure everything went alright in the compile.

Backend Emits Generated Code

The backends convert the collection of statements from each function context into code. There are two backends in use:

FKismetCompilerVMBackend - Converts FKCS to UnrealScript VM bytecode which are then serialized into the function's script array.

FKismetCppBackend - Emits C++-like code for debugging purposes only.

Copy Class Default Object Properties

Using a special function, CopyPropertiesForUnrelatedObjects(), the compiler copies the values from the old CDO of the class into the new CDO. Properties are copied via tagged serialization, so as long as the names are consistent, they should properly be transferred. Components of the CDO are re-instanced and fixed up appropriately at this stage. The GeneratedClass CDO is authoritative.

Re-instance

Since the class may have changed size and properties may have been added or removed, the compiler needs to re-instance all objects with the class that were just compiled. This process uses a TObjectIterator to find all instances of the class, spawn a new one, and then uses the CopyPropertiesForUnrelatedObjects() function to copy from the old instance to the new one.

For details, see the FBlueprintCompileReinstancer class.

Exposing C++ to Blueprints

Making Classes Blueprintable

Readable and Writable Properties

Executable and Overridable Functions

As a programmer, working with Blueprints offers you many benefits by making your code extremely flexible. For example, a gameplay designer might want a new type of weapon implemented in the game. As the programmer, you code the weapon as you traditionally would except that you expose some important functionality, such as the fire rate and the Fire() function. After play testing, the designer decides that they need to change the fire rate of the gun to work on a curve. Rather than having to recode the fire rate of the gun and recompile the game, the designer can simply go into the Blueprint and change the fire rate directly, saving both the designer and the programmer time.

For more details about optimizing the C++/Blueprints distribution in your project, or tips to keep in mind when creating an API exposed to Blueprints, see the Exposing C++ to Blueprints.

Making Classes Blueprintable

In order to create Blueprints that extend from a class, that class must be defined as Blueprintable; which involves adding this keyword inside the UCLASS() macro preceding the class definition. This keyword makes the Blueprint system aware of the class so that it shows in the class list of the New Blueprint dialog and can be selected as the parent for the Blueprint being created.

The simplest form of declaration for a Blueprintable class is similar to the following:

Keyword

Description

Blueprintable

Exposes this class as an acceptable base class for creating Blueprints. The default is NotBlueprintable, unless inherited otherwise. This is inherited by subclasses.

BlueprintType

Exposes this class as a type that can be used for variables in Blueprints.

NotBlueprintable

Specifies that this class is NOT an acceptable base class for creating Blueprints. Negates the effect of a parent class having the Blueprintable keyword specified.

Readable and Writable Properties

In order to expose a variable defined in a C++ class to a Blueprint extending from that class, that variable must be defined using one of the keywords listed below inside the UPROPERTY() macro preceding the variable definition. These keywords make the Blueprint system aware of the variable so that it shows in the My Blueprint panel and its value can be set or accessed.

Keyword

Description

BlueprintReadOnly

This property can be read by blueprints, but not modified.

BlueprintReadWrite

This property can be read or written from a Blueprint.

Multicast Delegate Keywords

BlueprintAssignable

Property should be exposed for assigning in Blueprints.

BlueprintCallable

Property should be exposed for calling in Blueprint graphs.

Executable and Overridable Functions

In order to call a native function from a Blueprint, that function must be defined using one of the keywords listed below inside the UFUNCTION() macro preceding the function definition. These keywords make the Blueprint system aware of the function so that it shows in the context menu or Palette and can be added to a graph and executed - or, in the case of events, so that they can be overridden and executed.

The simplest form of declaration for a BlueprintCallable Function is similar to the following:

When creating your function's signature, note that making a parameter pass by reference will make it an output pin on the Blueprint node. To make a parameter pass by reference and still display as an input, use the UPARAM() macro.



You can also use UPARAM() to change the display name of a pin. For example, the MakeRotator function in KismetMathLibrary uses UPARAM() and the DisplayName keyword to change how the Roll, Pitch, and Yaw parameters appear in Blueprints.



Keyword

Description

Blueprint to Native Communication

BlueprintCallable

This is a native function that can be called from a Blueprint, which executes native code that changes something about the object it is being called on, or some other global state. This means it has to be "scheduled," or told explicitly the order in which it executes relative to other nodes. We do this by the white execution line. All Blueprint callable functions will be called in the order in which they appear along the white execution line.

BlueprintPure

This is a native function that can be called from a Blueprint, which executes native code that does not change anything about the object it is being called on, or any other global state. This means that nothing is changed by calling this node, it just takes input, and tells you an output. These are things like math nodes (+, - , *, etc), or variable getters, or anything that does not change anything permanently. These do not need to be scheduled, and do not have a connection for the white execution line. They are automatically figured out by the compiler, based on which BlueprintCallable nodes need the data produced by these nodes.

Native to Blueprint Communication

BlueprintImplementableEvent

This is the primary way we allow native functions to call up into Blueprints. They are like virtual functions that you implement in the Blueprint themselves. If there is no implementation, the function call is ignored. It is important to note that if a BlueprintImplementableEvent does not have a return value or an out parameter, it will appear as an event, available by Right-clicking and selecting it in the event graph of the Blueprint. If it does have a return value or any out parameters, it will be listed in the My Blueprints tab, and can then be overridden by Right-clicking and selecting implement function. Note that BlueprintImplementableEvents do not have a native implementation of the function.

BlueprintNativeEvent

These are the same as above, except there is a native default implementation of the function that is called if the Blueprint does not override the function. This is useful for things where you want some sort of default behavior if the Blueprint does not implement it, but want the Blueprint to be able to override the functionality if desired. These are more costly, so we only put them in where the functionality is needed. When you override the BlueprintNativeEvent, you can still call the native implementation, if desired, by Right-clicking on the event or function entry node, and selecting "Add call to parent".

Exposing Gameplay Elements to Blueprints

Speed

Complexity

There are two driving considerations when deciding to use C++ or Blueprints:

Speed

Complexity of expression

Beyond those two factors, a lot of it comes down to the complexity of the game, and the composition of the team. If you have many more artists than programmers, you'll probably have significantly more Blueprints than C++ code. In contrast, if you have a lot of programmers, they're probably keen to keep things in C++. We expect people to fall somewhere in the middle. At Epic, a lot of the workflow is that content creators will make a very complex Blueprint, and a programmer can see how they can compress a lot of that work into C++ by coding a new Blueprint node, so they move that chunk of functionality into a new C++ function. A good practice to follow would be to use Blueprints extensively, and then push things into C++ as they reach a complexity where that would enable a more concise expression of the functionality (or it becomes too complex for a non-programmer), or speed of execution dictates a move to C++.

Speed

For speed, the fact is that Blueprint execution is slower than C++ execution. That's not to say performance is bad, but if you're doing something that requires a lot of calculations, or operates at a high frequency, it might be better to use C++ instead of Blueprints. However, it is possible to combine the two in the way that works best for your team and your project's performance. If you have a Blueprint that has a lot of functionality, you can push some of that functionality into C++ to speed it up, but keep the rest in Blueprints to retain the flexibility.If your profiling shows that one operation is taking a lot of time in Blueprints, consider moving just that section into C++, while keeping the rest in Blueprints.

An example of a system that would take a lot of time to execute if done with Blueprint visual scripting is a crowd system that controls a thousand Actors In this case, it would be better for performance to handle decision making, pathing, and other crowd functionality in C++, and then maybe expose some tweaking parameters and controlling functions to Blueprints.

Complexity

For complexity of expression, there are just some things that are easier to do in C++ than in Blueprints. Blueprints do a lot of things well, but some things are just not very easy to express in nodes. Operating on large sets of data, doing string manipulation, complex math over large data sets, etc. are all very complex, and aren't easy to follow in a visual system. Those things are better kept in C++ than in Blueprints, just because they're easier to look at and figure out what's going on. Complexity of expression is another reason a crowd system would be better to implement in C++ code than in Blueprints.

Examples

Since there are different pieces of functionality that are best handled in C++ or in Blueprints, here are some examples of how C++ programmers and Blueprint authors can work together while creating a game.

The programmer could create a Character class in C++ that defines some custom events, and then Blueprints could be used to extend that Character class and actually assign meshes and set defaults. Check out the player character and the enemy bots in the ShooterGame sample project to see implementations like this.

A ability system where the base class is implemented in C++ but then designers can create Blueprints which actually do something. In the StrategyGame sample, there is a base turret defined in C++, but the behavior of the flamethrower, cannon, and arrow turrets is all defined in those Blueprints.

A pickup where the "Collect" or "Respawn" functions are Blueprint Implementable Events that can be overridden for designers to spawn different particle emitters and sound effects. Both ShooterGame and StrategyGame have examples of pickups created this way.

Creating a Blueprint API : Tips and Tricks

Here are some points to consider as a programmer creating a Blueprint-exposed API:

Optional parameters are handled well in Blueprints:

Favor functions with lots of return parameters over functions that return structs. Here's a snippet showing how to create multiple output pins on your node:

Adding new parameters to an existing function is fine, but if you need to remove or change them, you should deprecate the original and add a new function. Make sure to use the deprecation metadata so the information about the new function will show up in Blueprints:

If a function needs to take an enum, consider using the 'expand enum as execs' metadata, as this can make the node easier to use.

Many operations that take time to complete (e.g. move here) should be latent functions.

Consider putting functions in a shared library if possible. This makes them easy to use across multiple classes, and avoids a 'target' pin.

Remember to mark nodes as pure if possible, as this will avoid needing an execution pin on a node that requires wiring.

Marking a function as const will also cause the Blueprint node to not have execution pins:

How Do Blueprints Work?

Commonly Used Blueprint Types

Level Blueprint

Blueprint Class

What Else Can Blueprints Do?

Create Customizable Prefabs with Construction Scripts

Create A Playable Game Character

Create A HUD

Blueprint Editors and Graphs

Blueprint Samples and Tutorials

Choose your operating system:

Windows

macOS

Linux

The Blueprint Visual Scripting system in Unreal Engine is a complete gameplay scripting system based on the concept of using a node-based interface to create gameplay elements from within Unreal Editor. As with many common scripting languages, it is used to define object-oriented (OO) classes or objects in the engine. As you use Unreal, you'll often find that objects defined using Blueprint are colloquially referred to as just "Blueprints."

This system is extremely flexible and powerful as it provides the ability for designers to use virtually the full range of concepts and tools generally only available to programmers. In addition, Blueprint-specific markup available in Unreal Engine's C++ implementation enables programmers to create baseline systems that can be extended by designers.

Please see the Blueprint Overview for more information about Blueprint anatomy and a discussion of how Blueprints relate to UE3's Kismet and UnrealScript.

How Do Blueprints Work?

In their basic form, Blueprints are visually scripted additions to your game. By connecting Nodes, Events, Functions, and Variables with Wires, it is possible to create complex gameplay elements.

Blueprints work by using graphs of Nodes for various purposes - object construction, individual functions, and general gameplay events - that are specific to each instance of the Blueprint in order to implement behavior and other functionality.

Commonly Used Blueprint Types

The most common Blueprint types you will be working with are Level Blueprints and Blueprint Classes.

These are just two of the Types of Blueprints, which also include Blueprint Macros and Blueprint Interfaces.

Level Blueprint



The Level Blueprint fills the same role that Kismet did in Unreal Engine 3, and has the same capabilities. Each level has its own Level Blueprint, and this can reference and manipulate Actors within the level, control cinematics using Matinee Actors, and manage things like level streaming, checkpoints, and other level-related systems. The Level Blueprint can also interact with Blueprint Classes (see the next section for examples of these) placed in the level, such as reading/setting any variables or triggering custom events they might contain.

Blueprint Class



Blueprint Classes are ideal for making interactive assets such as doors, switches, collectible items, and destructible scenery. In the image above, the button and the set of doors are each separate Blueprints that contain the necessary script to respond to player overlap events, make them animate, play sound effects, and change their materials (the button lights up when pressed, for example).

In this case, pressing the button activates an event inside the door Blueprint, causing it to open - but the doors could just as easily be activated by another type of Blueprint, or by a Level Blueprint sequence. Because of the self-contained nature of Blueprints, they can be constructed in such a way that you can drop them into a level and they will simply work, with minimal setup required. This also means that editing a Blueprint that is in use throughout a project will update every instance of it.

What Else Can Blueprints Do?

You have read about Level Blueprints and Blueprint Classes, listed below are a handful of examples that can be accomplished with the Blueprint system.

Create Customizable Prefabs with Construction Scripts



The Construction Script is a type of graph within Blueprint Classes that executes when that Actor is placed or updated in the editor, but not during gameplay. It is useful for creating easily customizable props that allow environment artists to work faster, such as a light fixture that automatically updates its material to match the color and brightness of its point light component, or a Blueprint that randomly scatters foliage meshes over an area.

In the Content Examples maps, the long rooms that contain each example (pictured above) are actually a single Blueprint made up of many components. The Blueprint's Construction Script creates and arranges the various Static Meshes and lights according to parameters exposed in the Blueprint's Details panel. With each Content Example map we created, we were able to drop in the demo room Blueprint, set values for the length, height, and number of rooms that would be generated (and a few other options), and have a complete set of rooms ready in moments.

A Blueprint like this can be time-consuming to create initially, but if you know you will use it often, the time saved when building a level and the ease of making changes can make it very worthwhile.

Create A Playable Game Character



Pawns are a type of Blueprint Class, and it is possible to put together every element you need for a playable Character in the Blueprint graph. You can manipulate Camera behavior, set up input events for mouse, controller, and touch screens, and create an Animation Blueprint asset for handling skeletal mesh animations.

When you create a new Character Blueprint, it comes with a character component that has much of the behavior needed for moving around, jumping, swimming, and falling built-in, and all that is required is to add some input events in accordance with how you want your character to be controlled.

Refer to Setting Up Character Movement tutorial for additional documentation.

Create A HUD



Blueprint script can be used to create a game's HUD as well, which is similar to Blueprint Classes in that it can contain event sequences and variables, but is assigned to your project's GameMode asset instead of being added directly to a level.

You can set up a HUD to read variables from other Blueprints and use them to display a health bar, update a score value, display objective markers, and so on. It is also possible to use the HUD to add hit-boxes for elements like buttons that can be clicked on or, in the case of mobile games, can respond to touch input.

While possible with Blueprint, the



Blueprint Editors and Graphs

Whether you are building a Level Blueprint or a Blueprint Class, you will be using Blueprint Elements assembled in a Blueprint Editor.





Different types of Blueprint Editor are available depending on the type of Blueprint you are working with. The core feature of most Blueprint Editors is the Graph mode, with its central Graph tab for laying out the network of your Blueprint.

Blueprint Samples and Tutorials

Below are additional resources you can use to learn more about the Blueprint system.

Samples and Tutorials

Blueprint Lift Tutorial

Blueprint Power-Up Tutorial

Variables

Execution Flow

Blueprints provide a visual approach to a scripting language. As such, the system shares many of the nuances of a standard written scripting language, such as data typed variables, arrays, structs, etc. Execution flow also works as it does in a typical scripting language, although Blueprints require explicit linear execution for each node. Each of the pages below go into more detail about different variable types, working with those variables, and execution of nodes within the graph.

Variables

Variables can be created in a variety of different types, including data types such as Boolean, integer, and float. They are color-coded for easy identification within your Blueprint. Blueprint variables can also be reference types for holding things like Objects, Actors, and Classes.



Properties that hold a value or reference an Object or Actor in the world.



Using Actor Reference to move different Actors around in a level.

Execution Flow

In Blueprints, the first node to execute is an event, and then execution flows through the white execution wire from left to right. You can visualize the execution flow while your game is running in the editor, which can help with debugging. Data also flows through wires colored to match the variable types. Input pins are evaluated when the node executes, tracing the data wires back from right to left until the final result is calculated and supplied to the node.

Nodes with execution pins (impure nodes) store the values of their output pins when they execute, while nodes without execution pins (pure nodes) reevaluate their outputs every time a node connected to their outputs executes.



Examples of the ways to connect nodes together in Blueprints.



Nodes that are called from gameplay code to begin execution of an individual network within the EventGraph.



Nodes that allow for controlling the flow of execution based on conditions.



Node graph that uses events and function calls to perform actions in response to gameplay events associated with the Blueprint.

Types of Blueprints

Blueprint Class

Data-Only Blueprint

Blueprint Interface

Blueprint Macro Library

Blueprint Utilities

Blueprint Anatomy

Components Window

Construction Script

Event Graph

Functions

Variables

The Blueprint Visual Scripting system in Unreal Engine is a complete gameplay scripting system based on the concept of using a node-based interface to create gameplay elements from within Unreal Editor. As with many common scripting languages, it is used to define object-oriented (OO) classes or objects in the engine. As you use Unreal, you'll often find that objects defined using Blueprint are colloquially referred to as just "Blueprints."

This system is extremely flexible and powerful as it provides the ability for designers to use virtually the full range of concepts and tools generally only available to programmers. In addition, Blueprint-specific markup available in Unreal Engine's C++ implementation enables programmers to create baseline systems that can be extended by designers.

Does that mean Blueprints are a replacement for UnrealScript? Yes and no. Gameplay programming and everything that UnrealScript was used for in the past can still be handled through code using C++. At the same time, while Blueprints are not meant as a replacement for UnrealScript, they do serve many of the same purposes that UnrealScript handled, such as:

Extending classes

Storing and modifying default properties

Managing subobject (e.g. Components) instancing for classes

The expectation is that gameplay programmers will set up base classes which expose a useful set of functions and properties that Blueprints made from those base classes can use and extend upon.

The table below provides a comparison of how various aspects would be handled in UnrealScript (from Unreal Engine 3), C++, and Blueprints to help those transitioning from previous versions of the engine as well as show how native code and Blueprints compare.

UnrealScript (UE3)

Blueprints (UE5)

C++ (UE5)

.uc file

Blueprint Asset

.h/.cpp files

UClass

UBlueprintGeneratedClass

UClass

extends [ClassName]

ParentClass

: [ClassName]

Variable

Variable

UProperty()

Function

Graphs/Events

UFunction()

defaultproperties{}

Class Defaults

native constructor

Default Components

Components List

native constructor

Types of Blueprints

Blueprints can be one of several types that each have their own specific use from creating new types to scripting level events to defining interfaces or macros to be used by other Blueprints.

Blueprint Class

A Blueprint Class, often shortened as Blueprint, is an asset that allows content creators to easily add functionality on top of existing gameplay classes. Blueprints are created inside of Unreal Editor visually, instead of by typing code, and saved as assets in a content package. These essentially define a new class or type of Actor which can then be placed into maps as instances that behave like any other type of Actor.

Data-Only Blueprint

A Data-Only Blueprint is a Blueprint Class that contains only the code (in the form of node graphs), variables, and components inherited from its parent. These allow those inherited properties to be tweaked and modified, but no new elements can be added. These are essentially a replacement for archetypes and can be used to allow designers to tweak properties or set items with variations.

Data-Only Blueprint are edited in a compact property editor, but can also be "converted" to full Blueprints by simply adding code, variables, or components using the full Blueprint Editor.

Refer to Class Blueprint for additional documentaion.

A Level Blueprint is a specialized type of Blueprint that acts as a level-wide global event graph. Each level in your project has its own Level Blueprint created by default that can be edited within the Unreal Editor, however new Level Blueprints cannot be created through the editor interface.

Events pertaining to the level as a whole, or specific instances of Actors within the level, are used to fire off sequences of actions in the form of Function Calls or Flow Control operations. Those familiar with Unreal Engine 3 should be very familiar with this concept as this is very similar to how Kismet worked in Unreal Engine 3.

Level Blueprints also provide a control mechanism for level streaming and Sequencer as well as for binding events to Actors placed within the level.

Refer to Level Blueprint for additional documentaion.

Blueprint Interface

A Blueprint Interface is a collection of one or more functions - name only, no implementation - that can be added to other Blueprints. Any Blueprint that has the Interface added is guaranteed to have those functions. The functions of the Interface can be given functionality in each of the Blueprints that added it. This is essentially like the concept of an interface in general programming, which allows multiple different types of Objects to all share and be accessed through a common interface. Put simply, Blueprint Interfaces allow different Blueprints to share with and send data to one another.

Blueprint Interfaces can be made by content creators through the editor in a similar fashion to other Blueprints, but they come with certain limitations in that they cannot:

Add new variables

Edit graphs

Add Components

Refer to Blueprint Interface and Inteface QuickStart Guide for additional documentaion

Blueprint Macro Library

A Blueprint Macro Library is a container that holds a collection of Macros or self-contained graphs that can be placed as nodes in other Blueprints. These can be time-savers as they can store commonly used sequences of nodes complete with inputs and outputs for both execution and data transfer.

Macros are shared among all graphs that reference them, but they are auto-expanded into graphs as if they were a collapsed node during compiling. This means that Blueprint Macro Libraries do not need to be compiled. However, changes to a Macro are only reflected in graphs that reference that Macro when the Blueprint containing those graphs is recompiled.

Refer Macro Library and Making Macrosfor additional documentaion.

Blueprint Utilities

A Blueprint Utility (or Blutility for short), is an editor-only Blueprint that can be used to perform editor actions or extend editor functionality. These can expose Events with no parameters as buttons in the UI and have the ability to execute any functions exposed to Blueprints and act on the current set of selected Actors in the viewport.

Blueprint Anatomy

The functionality of Blueprints is defined using various elements; some of which are present by default, while others can be added on an as-needed basis. These provide the ability to define Components, perform initialization and setup operations, respond to events, organize and modularize operations, define properties, and more.

Components Window

With an understanding of Components, the Components window inside the Blueprint Editor allows you to add Components to your Blueprint. This provides a means of adding collision geometry via CapsuleComponents, BoxComponents, or SphereComponents, adding rendered geometry in the form of StaticMeshComponents or SkeletalMeshComponents, controlling movement using MovementComponents, etc. The Components added in the Components list can also be assigned to instance variables providing access to them in the graphs of this or other Blueprints.

Construction Script

The Construction Script runs following the Components list when an instance of a Blueprint Class is created. It contains a node graph that is executed allowing the Blueprint Class instance to perform initialization operations. This can be extremely powerful as actions like performing traces into the world, setting meshes and materials, and so on can be used to achieve context-specific setup. For instance, a light Blueprint could determine what type of ground it is placed upon and choose the correct mesh to use from a set of meshes or a fence Blueprint could perform traces extending out in each direction to determine how long of a fence is needed to span the distance.

Event Graph

The EventGraph of a Blueprint contains a node graph that uses events and function calls to perform actions in response to gameplay events associated with the Blueprint. This is used to add functionality that is common to all instances of a Blueprint. This is where interactivity and dynamic responses are setup. For example, a light Blueprint could respond to a damage event by turning off its LightComponent and changing the material used by its mesh. This would automatically provide this behavior to all instances of the light Blueprint.

Refer to EventGraph for additional documentation.

Functions

Functions are node graphs belonging to a particular Blueprint that can be executed, or called, from another graph within the Blueprint. Functions have a single entry point designated by a node with the name of the Function containing a single exec output pin. When the Function is called from another graph, the output exec pin is activated causing the connected network to execute.

Variables

Variables are properties that hold a value or reference an Object or Actor in the world. These properties can be accessible internally to the Blueprint containing them, or they can be made accessible externally so that their values can be modified by designers working with instances of the Blueprint placed in a level.

1 - Required Project Setup

2 - Construct your Launchpad

3 - Convert Your Actor to a Blueprint Class

4 - Create Your Starting Point

5 - Test the Overlapping Actor

6 - Launch Your Character

7 - On Your Own!

This quick start guide will walk you through building an Actor in the level with different Components, then turning it into a Blueprint Class you can add launching behavior to so your Character will fly around the level! Making it into a Blueprint Class also means you can create as many launchpads in your world as you want, just by dragging into the level from the Content Browser.

1 - Required Project Setup

From the New Project tab of the Unreal Project Browser, create a new project from the Games category that uses the following settings:

Side Scroller

Blueprint

With Starter Content

Choose whatever scalability and quality settings work best for your setup.

If you are unsure of what settings are right for you, you can find more information in the Project Settings section.

Name your project, then create it by clicking the Create Project button.

You should now be ready to jump into and start adding to the side-scroller level that appears.



2 - Construct your Launchpad

In the Level Editor, you will build a launchpad, then convert it to a Blueprint Class so you can add your gameplay behavior to it.

First, move around in the viewport until you are looking at the top platforms in the level.



We are going to create the container to hold all the parts of our launchpad by using the Empty Actor. The two parts (or Components) you will need are a shape to represent the launchpad, and a trigger for when the character overlaps it.

In the Main Toolbar, press the Modes button, and from the dropdown click on Select to display the Place Actors panel.

In the Place Actors panel, click on Basic, then find the Empty Actor.



Drag it into the level so that it is sitting on one of the top platforms.



Now that you have the Actor selected in the level, its properties are visible in the Details panel. At the top of the Details panel, you can rename it. Go ahead and click in the box to enter a new name, like LaunchPad.



In the Details panel, click the Add Component button, then select Cube under Common.



Click and drag the newly added Cube to the DefaultSceneRoot to make the Cube the new root.



With the Cube component selected, change the Scale to (X: 1.0, Y: 1.0, Z: 0.1)



Now, we will add a Box Collision Component, which will fire off an event whenever something overlaps it. In the Details panel, click the Add Component button, then (under Collision) select Box Collision.



Change the Box Collision scale to ( X: 1.25, Y: 1.25, Z: 9.75) and location to ( X: 0, Y: 0, Z: 200) so the box covers and extends above the launch pad.



If at any time you need to change your Actor's properties, you can click on LaunchPad (Instance), found in the Details panel, under the Add Components button.

Now that you have your Actor the way you want it, we will turn it into a Blueprint Class. You can add more components inside the Blueprint Editor, and tweak them just like you can in the Level.

3 - Convert Your Actor to a Blueprint Class

When you make changes inside the Blueprint, each time you make a new launchpad in the Level, it will have the look and feel that you have created in the Blueprint Editor. While you could simply duplicate your LaunchPad Actor around the level, any changes you make on a particular launchpad would only affect that one copy.

In the Details panel, click on the Blueprint/Add Script button.



The Create Blueprint from Selection dialog box appears. We are going to edit the default path of the Blueprint.



Change the path from Game/SideScrollerBP to Game/SideScrollerBP/Blueprints.

At this point, you could rename your Blueprint, or leave it as the default LaunchPad_Blueprint.

Click on Create Blueprint.

Your Blueprint is now visible in the Content Browser. Right now, you could drag and drop from the Content Browser into the level to create lots of copies of your platform mesh and trigger, but there will not be any behavior on it yet. In the next step, you will start setting up the graph nodes inside of your Blueprint to launch your Character when it crosses the launchpad.



4 - Create Your Starting Point

To start adding behavior to your Blueprint Class, you will need to open it in the Blueprint Editor.

Double-click the Blueprint Class in the Content Browser.

The Blueprint Editor will open, and you can see your Cube and Box components in a viewport. At this point, if you adjust the Box Component's placement, it will be applied to all launchpads you make from this Blueprint Class. Just like when you were working with components on your LaunchPad Actor, you can select the Box component in the Components list and adjust the location. Try a location of (X: 0, Y: 0, Z: 350).



Docked next to the Viewport tab is a Construction Script tab and an Event Graph tab. Since you are going to be creating gameplay behavior, you should start with the Event Graph. Click on that tab now.



Events are the starting point of your Blueprint graph's execution, and can be associated with a number of different gameplay situations. A selection of the most commonly used events are visible right away, seen as translucent Event nodes. Though certainly useful for many of your Blueprint graphs, we will be making one of our very own.

We want an event that will execute when anything overlaps our Box component. First, select the Box component in the Components tab.

Right-click in an empty spot in your graph to bring up the context menu of nodes you could add to the graph.

To move around in the graph, right-click and drag around. At this point, you could drag the graph to the left, moving the pre-placed event nodes off the left side of the screen and creating more blank space to create your launchpad logic in.



We are adding an event for this Component, so expand the Add Event for Box dropdown, and then Collision. You could also use the search box, using "Component Begin Overlap" to filter the menu.

Select On Component Begin Overlap.



Your graph now has an OnComponentBeginOverlap node. Any nodes connected to this event will execute when something overlaps the Box component of your launchpad.



In the next step of this guide, you will begin connecting nodes to the output pins of this node, and learn more about working with nodes in Blueprints.

5 - Test the Overlapping Actor

Right now, that OnComponentBeginOverlap event will execute when anything overlaps the Box trigger. We only want to actually execute our launching behavior, though, if the overlapping thing is our avatar, or Pawn. Think of it as asking "Is the Actor overlapping the Box trigger the same Actor as our Pawn?"

We will do that by working with the Other Actor output from the OnComponentBeginOverlap event.

From the OnComponentBeginOverlap event, click on the Other Actor pin , drag into an empty spot on the graph, and release to display the context menu.



The context menu is adaptive, filtering by the pin you are currently working with to show you only nodes that are compatible.

Type = into the search box to filter the available nodes, then select Equal (Object).



We could set Side Scroller Character as the other input to the Equal node, but then if we changed the Character we were using, we would need to re-open this Blueprint and manually update that. Instead, let's get a reference to the current Pawn we are using.

Right-click in an empty part of the graph to bring up the context menu.

Type Player Pawn in the menu's search box, then (under Game) select Get Player Pawn.



Connect the Return Value output on Get Player Pawn to the second input on the Equal node.



Now that we have got a node that will tell us if the Other Actor is the Pawn our player controls, we will use the answer to change the execution flow of our graph. That is, we will direct the execution flow as it leaves the On Component Begin Overlap node. For that, we want to use a Flow Control node, specifically the Branch node.

Drag off of the execution pin on the OnComponentBeginOverlap node and release in an empty part of the graph.



Type Branch in the search, then select Branch from the context menu.



Connect the output pin of the Equals node to the input Boolean pin on the Condition node.



The graph is now ready for you to set up different behavior to execute depending on whether the overlapping Actor is your Pawn or not. In the next step, we will do just that, and set up Blueprint nodes to launch our Character if the result of the Equals comparison is True.

6 - Launch Your Character

Our launchpad is going to work by using a function called Launch Character. The Launch Character function adds the velocity you specify to the Character's current velocity, allowing you to throw it in whichever direction you would like. It only works on Characters, though, so we need to make sure that our Pawn (avatar) is a Character (humanoid avatar).

We do this by casting. Casting attempts to convert your input into a different type, so you can access specific functionality that is only allowed for that particular type. It will succeed if your input is based on that type.

Everything you can place in your level is an Actor, in addition to any other specialized behavior added on later. That means that you can get a reference to anything in your level, cast it to Actor, and it will succeed. However, not everything in your level is the Pawn representing you in the game, so casting something to Pawn may or may not succeed.

From the Get Player Pawn node, drag off of the Return Value pin.

Begin typing Cast to Character in the search field of the context menu to find the node of the same name.



From the Cast to Character node, drag off of the As Character pin.

Type "Launch" into the search box, then select Launch Character in the context menu.



Click image for full size.

Notice that the output execution pin for successfully casting automatically connected to the input execution pin of Launch Character.

Type 3000 into the Z field of the Launch Character node.

Finally, connect the Branch node True execution pin to the Cast to Character node's input execution pin, so that Cast to Character and Launch Character only occur if the overlapping Actor is our Pawn.



Click image for full size.

At this point, Compile and Save the Blueprint using the toolbar buttons, then close the Blueprint Editor.

Drag several of the launchpads into your Level from the Content Browser.



Click on Play in the toolbar, then run around the Level (using WASD) and jump (using the Spacebar). Land on one of the platforms and watch as you go flying through the air!

7 - On Your Own!

Using what you have learned over the course of this Quick Start guide, try to do the following:

Play a sound when your Character is launched using an Audio Component.

Create a variable to store your Launch Velocity, and expose it so you can set it on each copy in the level.

Add a



Add an Arrow Component and use its rotation to define the direction to launch the character.

Using Timelines, add some animation to the Box Mesh to represent it launching the character.

For more information on Blueprint Visual Scripting, see the Blueprints page.

As for specifics covered in this quick start:

For a quick overview of different types of Blueprint Classes you can make, see Blueprints Getting Started

For more information on Blueprint Classes, see: Blueprint Classes

For more short tutorials on creating and working with Blueprint Classes, see: Blueprints How-To

For more information on the Blueprint Editor, see: Blueprint Editor

Functions

Function Calls

Functions are node graphs belonging to a particular Blueprint that can be executed, or called, from another graph within the Blueprint. Functions have a single entry point designated by a node with the name of the Function containing a single exec output pin. When the Function is called from another graph, the output exec pin is activated causing the connected network to execute.

The steps below will guide you through creating a Function which will print text to the screen when a button is pressed.

Inside the Content Browser, click the New Button then select Blueprint Class.



In the Pick Parent Class window, select Actor.



Name the Blueprint, then Double-click on it to open it up in the Blueprint Editor.



Right-click in the graph and search for and add the Event Begin Play Event.



This node will execute once when the game is launched, along with any script that follows it.

Right-click in the graph and search for and add the Get Player Controller node.



This will get the currently assigned player controller and allow us to Enable Input for this Blueprint.

Right-click in the graph and search for and add the Enable Input node.



This is the node which will allow input to be received for this Blueprint.

Connect the nodes as shown below.



When the game is launched, we get the player controller and enable input from it in this Blueprint.

In the MyBlueprint window, click the Add New Function button.



Select the new function in the My Blueprint window and press F2 to rename it.



Give the Function a name such as "Print Text".

In the Function's graph, drag off the Print Text pin and search for and add a Print String node.



In the In String box, you can leave or change the text to the text you want to display in-game.



Click the Event Graph tab to return to the Event Graph.



Right-click in the graph and search for and add an F Key Event.



Drag off the Pressed pin and search for and add your Print Text function.



When F is pressed, it will call the Print Text function which is set to print text to the screen using a Print String.

If you do not see your function, try clicking the Compile button from the Toolbar then try your search again.

Your network should look similar to below.



Click the Compile button then close the Blueprint.



Drag the Blueprint into the level, then click the Play button to play in the Editor.



Press F and the Function will be called and print your text to the screen.



While this example Function only prints text to the screen when a key is pressed, you could add more script to the Function which would be executed by the assigned key press.

For example, your Function could be used to cast a spell when the key is pressed and the script containing the spawning of the spell and its location, the effects associated with the spell and how it affects the world, or if it damages other Actors could all be contained within the function leaving your Event Graph free from all that script which would be contained neatly within the Function.

There are other ways Functions can be used and accessed, for more on Functions please see the Related Topics section below.

Macros

Blueprint Macro Library

Blueprints Visual Scripting

Creating Macros

End Result

Macros are essentially the same as collapsed graphs of nodes. They have an entry point and exit point designated by tunnel nodes. Each tunnel can have any number of execution or data pins which are visible on the macro node when used in other Blueprints and graphs.

Creating Macros

In this tutorial, you will create a Macro to check if a Character has enough energy to jump. If they do have enough energy, then your macro will deplete energy from the player, print their current value to the screen, then call the jump function. If they do not have enough energy, your macro will print to the screen that "they are out of energy", and prevent them from jumping.

For this example, we are using the



After Creating and Launching your project, navigate to the Content/ThirdPerson/Blueprints folder, and open the BP_ThirdPersonCharacter Blueprint.



Navigate to the My Blueprint window, then click the Add Macro button.



A new macro is created, select it and press F2 to rename it to EnergyCheck.



With the macro selected, navigate to Details > Inputs, click Add(+) to create a new Input named BeginCheck, then change its type to Exec** (Execution pin)



Navigate to Details > Outputs, and click Add(+) to create two new Outputs. Name one HasEnergy and the other NoEnergy, then set the Exec pin types.



This will create Input / Output nodes on the Macro Node itself that can be used to pass data to and from the Macro.

For the Input, use an Exec pin called BeginCheck to start the Macro. Next, create a script that checks if the player has enough energy to jump and if so, execute the HasEnergy pin. If the player does not have enough energy, execute the NoEnergy pin.

Inside the My Blueprint window, click the Add Variable button to create a new float variable named Energy.



On the Toolbar, click Compile, then select Energy and navigate to the Details panel to set its value to 100.



In the Energy graph, click B + Left-click to create a Branch node.



Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_0" bCanHaveOutputs=True NodePosX=-80 NodePosY=192 NodeGuid=4500150646970605E70A60A3C13D1FAA CustomProperties Pin (PinId=98F7CAA84E2A27C812123FBDF41F03E1,PinName="BeginCheck",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="BeginCheck",PinType=(PinCategory="exec"),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_1" bCanHaveInputs=True NodePosX=512 NodePosY=64 NodeGuid=B25A99B147860ECA426757B2CFA92EE4 CustomProperties Pin (PinId=6D264E70477F620620962AA38813CEE1,PinName="HasEnergy",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F9B1BBB04D96332C2C709AAF8E579689,PinName="NoEnergy",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWr

While holding Ctrl, drag the Energy float variable from the My Blueprint tab into the macro graph, click and drag off the output pin to search for a Greater operator node, then connect the output pin to the Branch.

.png)

In the image, we are using a Branch to determine If Energy is > 0, and if so True is executed; if not False is executed.

Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_0" bCanHaveOutputs=True NodePosX=-80 NodePosY=192 NodeGuid=4500150646970605E70A60A3C13D1FAA CustomProperties Pin (PinId=98F7CAA84E2A27C812123FBDF41F03E1,PinName="BeginCheck",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 5D71C7E4443ED94B5AEDD4A6E9A4F787,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="BeginCheck",PinType=(PinCategory="exec"),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=128 NodePosY=192 NodeGuid=85E9DC52476273CDA995849E4CC9B0DA CustomProperties Pin (PinId=5D71C7E4443ED94B5AEDD4A6E9A4F787,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_0 98F7CAA84E2A27C812123FBDF41F03E1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=30D9E9634E4640AF8FFFAABD46197487,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.Cont

While holding Alt, drag in the Energy variable to add a Set node.



Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_0" bCanHaveOutputs=True NodePosX=-80 NodePosY=192 NodeGuid=4500150646970605E70A60A3C13D1FAA CustomProperties Pin (PinId=98F7CAA84E2A27C812123FBDF41F03E1,PinName="BeginCheck",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 5D71C7E4443ED94B5AEDD4A6E9A4F787,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="BeginCheck",PinType=(PinCategory="exec"),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=128 NodePosY=192 NodeGuid=85E9DC52476273CDA995849E4CC9B0DA CustomProperties Pin (PinId=5D71C7E4443ED94B5AEDD4A6E9A4F787,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_0 98F7CAA84E2A27C812123FBDF41F03E1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=30D9E9634E4640AF8FFFAABD46197487,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.Cont

Ctrl drag in Energy again and connect it to a Subtact(-) node, set to 10 and connect it to the Set node.



Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_0" bCanHaveOutputs=True NodePosX=-80 NodePosY=192 NodeGuid=4500150646970605E70A60A3C13D1FAA CustomProperties Pin (PinId=98F7CAA84E2A27C812123FBDF41F03E1,PinName="BeginCheck",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 5D71C7E4443ED94B5AEDD4A6E9A4F787,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="BeginCheck",PinType=(PinCategory="exec"),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=128 NodePosY=192 NodeGuid=85E9DC52476273CDA995849E4CC9B0DA CustomProperties Pin (PinId=5D71C7E4443ED94B5AEDD4A6E9A4F787,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_0 98F7CAA84E2A27C812123FBDF41F03E1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=30D9E9634E4640AF8FFFAABD46197487,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.Cont

With this script, we define if Energy is > 0, subtract 10 from the current Energy value.

Right-click in the graph and add a Print String node, then connect the Set Energy node to the In String pin.



Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_0" bCanHaveOutputs=True NodePosX=-80 NodePosY=192 NodeGuid=4500150646970605E70A60A3C13D1FAA CustomProperties Pin (PinId=98F7CAA84E2A27C812123FBDF41F03E1,PinName="BeginCheck",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 5D71C7E4443ED94B5AEDD4A6E9A4F787,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="BeginCheck",PinType=(PinCategory="exec"),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=128 NodePosY=192 NodeGuid=85E9DC52476273CDA995849E4CC9B0DA CustomProperties Pin (PinId=5D71C7E4443ED94B5AEDD4A6E9A4F787,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_0 98F7CAA84E2A27C812123FBDF41F03E1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=30D9E9634E4640AF8FFFAABD46197487,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.Cont

A Conversion node is added which converts the value of Energy into a string printed to the screen, displaying its value.

Off the False pin of the Branch, add another Print String node and enter the text "Out of Energy!" in the box. Then connect the first and second Print String nodes to the HasEnergy and NoEnergy pins, respectively.



Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_0" bCanHaveOutputs=True NodePosX=-80 NodePosY=192 NodeGuid=4500150646970605E70A60A3C13D1FAA CustomProperties Pin (PinId=98F7CAA84E2A27C812123FBDF41F03E1,PinName="BeginCheck",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 5D71C7E4443ED94B5AEDD4A6E9A4F787,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="BeginCheck",PinType=(PinCategory="exec"),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_1" bCanHaveInputs=True NodePosX=848 NodePosY=240 NodeGuid=B25A99B147860ECA426757B2CFA92EE4 CustomProperties Pin (PinId=6D264E70477F620620962AA38813CEE1,PinName="HasEnergy",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_2 641BE2884B719D44EE1F7F8951AC28CF,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F9B1BBB04D96332C2C709AAF8E579689,PinName="NoEnergy",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueT

The macro is now set up to check (and if applicable, subtract from) the Energy variable and print if the player has enough energy or not, which is used to determine if the player can jump or not. Now, you need to implement the macro after pressing the "Jump" key, but before the Jump action is executed.

On the EventGraph, drag off the Pressed pin of InputAction Jump node and search for EnergyCheck.

You should see that the macro you created is listed under Utilities and has the Macro icon next to its name.

When the macro is added, the Jump script should look similar to below.



Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_1193" FunctionReference=(MemberName="Jump",bSelfContext=True) NodePosX=768 NodePosY=-144 ErrorType=1 NodeGuid=8A83DB3F49050555B45F79B064C3822E CustomProperties Pin (PinId=13FD260E4EE18FD0AA5F7085F9B509D6,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 AAA4A8A04AE7F5E0D61D86BDEC4C3CB8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B759CF2E40AB318E19979C8B6179C1E5,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C70870CA40D142BE7CF87785CB510A0D,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nCharacter Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Character"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectW

Click the Compile and Save buttons, then close the Blueprint.



Click Play on the main Toolbar in the Editor.



When you press the Spacebar to jump, in the upper left corner of the screen the value of Energy is printed to the screen. When Energy is 0, you should no longer be able to jump.

End Result



This is a basic example of using a Macro to execute and consolidate a script into a single node, improving the readability of our Event Graph and main character script. Additionally, you could call this Macro in other instances. For example, if you have some other action that reduces the player's energy, and you want to check if they have enough energy to perform the action (like attacking), you could run this Macro to check if the player has enough energy to Attack after pressing your Attack key then execute an attack off of the HasEnergy exec pin.

Macros

Blueprint Macro Library

Blueprints Visual Scripting

Creating a Macro Library

Creating the "Scale Up" Macro

Creating the "Add Health" Macro

End Result

Creating Macros

A Macro Library is a container that holds a collection of Macros or self-contained graphs that can be placed as nodes in other Blueprints. These can be time-savers as they can store commonly used sequences of nodes complete with inputs and outputs for both execution and data transfer.

A Blueprint Macro Library cannot contain variables, inherit from other Blueprints, or be placed in levels. Changes to macros in a Blueprint Macro Library will not take effect until client Blueprints are recompiled.

Creating a Macro Library

In this example you will create a Macro Library consisting of two macros, one of which is used to add to a "Health" variable and the other is used to adjust the size of an Actor.

For this example, we are using the



From the Content Browser, Select Add > Blueprints > Blueprint Macro Library

(programming-and-scripting/blueprints-visual-scripting/UserGuide/Types/MacroLibrary).



In the Pick Parent Class, select Actor as your Parent Class.



Enter a name for your Macro Library, then Double-click on it to open it up.



This will display the Blueprint Macro interface.



Creating the "Scale Up" Macro

Navigate to the MyBluprint window and rename the default macro to ScaleUp by selecting it and pressing F2.

In the Details panel, navigate to the Inputs category and click the Add (+) button to create two new inputs. Name the first input to In and set it to the Exec type, then name the other InActor and set to the Actor type.



Navigate to the Outputs category and click the Add (+) button to create a new output named Out and set it to the Exec type.



In the graph for the ScaleUp macro, copy or recreate the Blueprint scripts below.



Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_0" bCanHaveOutputs=True NodePosX=-64 NodePosY=-32 NodeGuid=29B55D6B4EF1A876A95E82AD2F9D8B4F CustomProperties Pin (PinId=FFB23B2D4EB3DD8F265E94862144A88B,PinName="In",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_1 11EB9E894BC56B61768BB89A11FE2EDB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FB06C9664603BB34512581A82CA8E640,PinName="InActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 F76E3C744FC81EF2C49FBE9BC37908A4,K2Node_CallFunction_1 835CCB5E456DDBE2D412DEA8F07287E0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="In",PinType=(PinCategory="exec"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="InActor",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_1" bCanHaveInputs=True NodePosX=672 NodePosY=-32 NodeGuid=7B55AB5C46160E9716C434AF9C38F550 CustomProperties Pin (PinId=3F0D9569416C50658BE770AF2F7D442D,PinName="Out",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_1 1826F31E45841B2D05CEC1B982173485,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="Out",PinType=(PinCategory="exec"),DesiredPinDirection=EGPD_Input) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" bIsPureFunc=True bIsConstFunc=True FunctionReference=(MemberName="GetActorScale3D",bSelfContext=True) NodePosX=48 NodePosY=64 NodeGuid=74E9237145C9DEAA109A37BE9618CF8E CustomProperties Pin (PinId=F76E3C744FC81EF2C49FBE9BC37908A4,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nActor Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_0 FB06C9664603BB34512581A82CA8E640,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CC987D3D4F0475146FD6C8B808FCE544,PinName="ReturnValue",PinToolTip="Return Value\nVector\n\nReturns the Actor\'s world-space scale.",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_PromotableOperator_1 EA45C78A4AA1D7393909BB973C3DD4DC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_1" FunctionReference=(MemberName="SetActorScale3D",bSelfContext=True) NodePosX=464 NodePosY=-48 NodeGuid=C42C760A438366D1D2D1E19713C9B9F1 CustomProperties Pin (PinId=11EB9E894BC56B61768BB89A11FE2EDB,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_0 FFB23B2D4EB3DD8F265E94862144A88B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1826F31E45841B2D05CEC1B982173485,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_1 3F0D9569416C50658BE770AF2F7D442D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=835CCB5E456DDBE2D412DEA8F07287E0,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nActor Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_0 FB06C9664603BB34512581A82CA8E640,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A7D3932F416B867C1CAB3CB58263E516,PinName="NewScale3D",PinToolTip="New Scale 3D\nVector",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",LinkedTo=(K2Node_PromotableOperator_1 D32A02594AD6C7AFE304C083262365FB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_1" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Multiply_VectorVector") NodePosX=288 NodePosY=96 NodeGuid=2CF8D2B14BCD06924A7D94A6914D09AD CustomProperties Pin (PinId=EA45C78A4AA1D7393909BB973C3DD4DC,PinName="A",PinToolTip="A\nVector",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 CC987D3D4F0475146FD6C8B808FCE544,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A8862BFF467CA9980B9C48908ECE99F5,PinName="B",PinToolTip="B\nFloat (single-precision)",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="1.250000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D32A02594AD6C7AFE304C083262365FB,PinName="ReturnValue",PinToolTip="Return Value\nVector\n\nElement-wise Vector multiplication (Result = {A.x*B.x, A.y*B.y, A.z*B.z})",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.Vector"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_1 A7D3932F416B867C1CAB3CB58263E516,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

When this macro is called it will get the Actor provided as the InActor and get its current scale to multiply by 1.25, then it will set the new scale 3D for the Target (the Actor specified as the InActor.) You can now use this macro with any Actor and affect their scale through the use of this macro.

Creating the "Add Health" Macro

Add another macro from the MyBlueprint window called AddHealth.



In the Details panel for AddHealth, navigate to the Inputs category and click the Add (+) button to create two new inputs. Name the first input to In and set it to the Exec type, then name the other GetHealth and set it to the float type.



Navigate to the Outputs category and click the Add (+) button to create two new outputs. Name the first output to Out and set it to the Exec type, then name the other SetHealth and set it to the float type.



Above we are taking in a float value called GetHealth which we will add to before we pass it through to the SetHealth output node.

In the graph for the AddHealth macro, recreate the node network indicated below.



Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_0" bCanHaveOutputs=True NodePosX=-32 NodePosY=-16 NodeGuid=82FC12F9456C1D6043EB139365DA21C2 CustomProperties Pin (PinId=FD753FC94537DB3146AACA8B22A3D672,PinName="In",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_1 477587F5483F8018083A7E8A10265009,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=315FBAAF4AB75D21FDB572AE378DFB00,PinName="GetHealth",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_0 B6FF0AAF4EB951BB6A84A1B8AF258F41,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="In",PinType=(PinCategory="exec"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="GetHealth",PinType=(PinCategory="real",PinSubCategory="double"),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Tunnel Name="K2Node_Tunnel_1" bCanHaveInputs=True NodePosX=288 NodePosY=-16 NodeGuid=D16FD0624CCEE73A5D3DE58B2FCA4228 CustomProperties Pin (PinId=477587F5483F8018083A7E8A10265009,PinName="Out",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_0 FD753FC94537DB3146AACA8B22A3D672,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=886FC0AC42CB2582CBABA2953FC90885,PinName="SetHealth",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_0 704FD98349A7226CE23CFBB33425E964,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="Out",PinType=(PinCategory="exec"),DesiredPinDirection=EGPD_Input) CustomProperties UserDefinedPin (PinName="SetHealth",PinType=(PinCategory="real",PinSubCategory="double"),DesiredPinDirection=EGPD_Input) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_0" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Add_DoubleDouble") NodePosX=96 NodePosY=80 NodeGuid=F626F7A4467ADBE2CC2B0CB142767A98 CustomProperties Pin (PinId=B6FF0AAF4EB951BB6A84A1B8AF258F41,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_0 315FBAAF4AB75D21FDB572AE378DFB00,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=73389E054F97E43B79951E8E68315F63,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="50.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=704FD98349A7226CE23CFBB33425E964,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nAddition (A + B)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Tunnel_1 886FC0AC42CB2582CBABA2953FC90885,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Above we are adding 50 to the float value provided as the GetHealth value before outputting the resulting value to SetHealth.

Save and close the Blueprint Macro Library.

Inside the Content/ThirdPerson/Blueprints folder, open the BP_ThirdPersonCharacter Blueprint.



In the MyBlueprint window, navigate to the Variables category and click the Add (+) to create a new Float variable named Health, then click Compile.



In the Event Graph below, copy or recreate the Blueprint scripts.

In the logic below, we are calling the AddHealth macro whenever Q is pressed which takes in the Health variable (performs the macro script of increasing it) and updates it with the out pin SetHealth before printing it to the screen. We then use E and check if Health is greater than 100 before we call the ScaleUp macro on the Actor Self which is the ThirdPersonCharacter.



Begin Object Class=/Script/BlueprintGraph.K2Node_InputKey Name="K2Node_InputKey_0" InputKey=Q NodePosX=2704 NodePosY=176 NodeGuid=E5A6981B4B7E9AAF2F97DFB76CDEBC70 CustomProperties Pin (PinId=2875808747CDC79CA568268E89221657,PinName="Pressed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 3BE1E4D84315BB0E0C825498D65DAF43,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3E496EEF45436D5BF43D47B06CC03737,PinName="Released",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AE69AEC448E0314BBD992B804DCC36BD,PinName="Key",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/InputCore.Key"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_0" MacroGraphReference=(MacroGraph=EdGraph'"/Game/ExampleMacroLibrary.ExampleMacroLibrary:AddHealth"',GraphBlueprint=Blueprint'"/Game/ExampleMacroLibrary.ExampleMacroLibrary"',GraphGuid=0E2D850F497D22DFA649599A52271D92) NodePosX=2864 NodePosY=176 NodeGuid=E33E97954E477070F03B59B4573FE598 CustomProperties Pin (PinId=3BE1E4D84315BB0E0C825498D65DAF43,PinName="In",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_InputKey_0 2875808747CDC79CA568268E89221657,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=143E16804EEF3C23A2BCF8B66DC8F916,PinName="GetHealth",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_0 C5E66A664E2761EF76FFE88E674B6223,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CBE298A74DBD79676B0A3283BF97A387,PinName="Out",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_0 FAACC7804C0A991726DD6A9C61F7C5FA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=02B33E4146DE45D36F1F3282DAAF8C75,PinName="SetHealth",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_0 C1A920C94F853E11F870CA9479A60B2F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_0" VariableReference=(MemberName="Health",MemberGuid=C0A66D7649DAC99E39B814A31AFC8047,bSelfContext=True) NodePosX=2688 NodePosY=304 NodeGuid=79ABC4DA43969B8CC5F251988A40EEA3 CustomProperties Pin (PinId=C5E66A664E2761EF76FFE88E674B6223,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_MacroInstance_0 143E16804EEF3C23A2BCF8B66DC8F916,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=42A088D1499E339D876A1580D947FFCD,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.BP_ThirdPersonCharacter_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_0" VariableReference=(MemberName="Health",MemberGuid=C0A66D7649DAC99E39B814A31AFC8047,bSelfContext=True) NodePosX=3120 NodePosY=192 NodeGuid=5E61E9D84F63E32EFCCED68EB374A8B5 CustomProperties Pin (PinId=FAACC7804C0A991726DD6A9C61F7C5FA,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CBE298A74DBD79676B0A3283BF97A387,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6AA291F74312AFA1194BD0976727494F,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 CF3A94574E1321C5E96A6A97159C1B97,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C1A920C94F853E11F870CA9479A60B2F,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_MacroInstance_0 02B33E4146DE45D36F1F3282DAAF8C75,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0761EFD14A7BB8C1A2AFB595D8B290BA,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.BP_ThirdPersonCharacter_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=80BE8C1242D4CF91D2E3EF9C90CA6023,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_0 A7E7124C4258922F0B97859CC93DC840,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_4" FunctionReference=(MemberParent=Class'"/Script/Engine.KismetSystemLibrary"',MemberName="PrintString") NodePosX=3424 NodePosY=176 AdvancedPinDisplay=Hidden EnabledState=DevelopmentOnly NodeGuid=F78EA4F74AAD59667F78EABCF7A48063 CustomProperties Pin (PinId=CF3A94574E1321C5E96A6A97159C1B97,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_0 6AA291F74312AFA1194BD0976727494F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=285A41114DA0EBB02E392386FA397F52,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6CEC617742290B838255DFBB984E6855,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetSystemLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C8F38F074818DA4BD8711F8F0DDD8C29,PinName="WorldContextObject",PinToolTip="World Context Object\nObject Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=676324DC46F0DAF1B10EAB86053D234A,PinName="InString",PinToolTip="In String\nString\n\nThe string to log out",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",LinkedTo=(K2Node_CallFunction_0 E77420E64E5FC68380EF968267F02413,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D098577A493D2E87F2969CA6C9A036D9,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBoolean\n\nWhether or not to print the output to the screen",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=162436F647CD3130474359B8C33FA5E7,PinName="bPrintToLog",PinToolTip="Print to Log\nBoolean\n\nWhether or not to print the output to the log",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=0177100D4515167F83F48E8191C0C5D8,PinName="TextColor",PinToolTip="Text Color\nLinear Color Structure\n\nThe color of the text to display",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.LinearColor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=DACCE443410317D4917E88AC3B26DEE9,PinName="Duration",PinToolTip="Duration\nFloat (single-precision)\n\nThe display duration (if Print to Screen is True). Using negative number will result in loading the duration time from the config.",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=432DBD2C4ECA766E15E2A7874F3F7969,PinName="Key",PinToolTip="Key\nName\n\nIf a non-empty key is provided, the message will replace any existing on-screen messages with the same key.",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetStringLibrary"',MemberName="Conv_DoubleToString") NodePosX=3280 NodePosY=240 NodeGuid=3056D3D14EA8E2D766417E907931D2A1 CustomProperties Pin (PinId=FE167DCF459E5043B65DB8BEF26A21B6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet String Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetStringLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetStringLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A7E7124C4258922F0B97859CC93DC840,PinName="InDouble",PinToolTip="In Double\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_VariableSet_0 80BE8C1242D4CF91D2E3EF9C90CA6023,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E77420E64E5FC68380EF968267F02413,PinName="ReturnValue",PinToolTip="Return Value\nString\n\nConverts a double value to a string",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 676324DC46F0DAF1B10EAB86053D234A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_InputKey Name="K2Node_InputKey_1" InputKey=E NodePosX=2704 NodePosY=416 NodeGuid=C17DDABC4F571126206118A84DD0B955 CustomProperties Pin (PinId=E6C91F8F41AD4E5437C805BC57D9CA85,PinName="Pressed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 C8870ADC4892BE5F3FB378833D34E8AA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AEA5C18745BCA7148D371BBCBE5C0778,PinName="Released",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4549DD394AEE351A49DEA4A5967A8517,PinName="Key",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/InputCore.Key"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=2944 NodePosY=416 NodeGuid=60634007443CBB2C649D70883C0CEC8E CustomProperties Pin (PinId=C8870ADC4892BE5F3FB378833D34E8AA,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_InputKey_1 E6C91F8F41AD4E5437C805BC57D9CA85,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A06DD8A4472D13B93B0439A054CD30C,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_PromotableOperator_2 A5F6D4F74E4320C8479EDDA458AAAD3B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=69CDCE5D48CAAC022A3806B58ADD50FE,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_1 C12114A84F781CF2255C0D921404AF97,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=51C85A7E44416B39FE37269A99542199,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_1" VariableReference=(MemberName="Health",MemberGuid=C0A66D7649DAC99E39B814A31AFC8047,bSelfContext=True) NodePosX=2624 NodePosY=560 NodeGuid=81106325481B08B5F7B526BCA959B936 CustomProperties Pin (PinId=FF2971FA42F695EB81D9AA935F70BB8B,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_2 204BD1E54B3F505D7FBE32B0F84E2C42,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=16B8A191403F8D5FD89A888860E4CF1A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.BP_ThirdPersonCharacter_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_2" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Greater_DoubleDouble") NodePosX=2784 NodePosY=544 NodeGuid=496EE77C435B6A5CFEDA28851CF9F110 CustomProperties Pin (PinId=204BD1E54B3F505D7FBE32B0F84E2C42,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_1 FF2971FA42F695EB81D9AA935F70BB8B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E6E0AC614411CE85D898EE95E63E54D7,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="100.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A5F6D4F74E4320C8479EDDA458AAAD3B,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nReturns true if A is greater than B (A > B)",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 5A06DD8A4472D13B93B0439A054CD30C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D84E3ACC47E1C71E7AD77884454F3DE2,PinName="ErrorTolerance",PinToolTip="Error Tolerance\n",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_1" MacroGraphReference=(MacroGraph=EdGraph'"/Game/ExampleMacroLibrary.ExampleMacroLibrary:ScaleUp"',GraphBlueprint=Blueprint'"/Game/ExampleMacroLibrary.ExampleMacroLibrary"',GraphGuid=A9FBEA5D476F420729FBD6A7867990AE) NodePosX=3328 NodePosY=416 NodeGuid=119A34204569D0B78E82589AABE4A771 CustomProperties Pin (PinId=C12114A84F781CF2255C0D921404AF97,PinName="In",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 69CDCE5D48CAAC022A3806B58ADD50FE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=571BBCBA46B6858BFBCCEEAE2D481F8C,PinName="InActor",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Self_0 1095198443A1536C7B4852A8F613E369,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=22D784C34A52D4FA4CC74FB3AFEE5CB8,PinName="Out",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Self Name="K2Node_Self_0" NodePosX=3152 NodePosY=480 NodeGuid=15CBC8464E459AFDAD01ECBE8BB7F763 CustomProperties Pin (PinId=1095198443A1536C7B4852A8F613E369,PinName="self",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="self",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_1 571BBCBA46B6858BFBCCEEAE2D481F8C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Compile and Play in the editor.

End Result



In the video above, we press the E key to call the ScaleUp macro. The Blueprint logic will first check the Health value which by default we set to 0, then we press Q to call the AddHealth macro to increase the Health variable by 50. After a few key presses, you can see the character increase values in both health and scale. These macros can be called from any other Blueprints provided the inputs for Health and the Target Actor are supplied.

Creating Macros

Macros are essentially the same as collapsed graphs of nodes. They have an entry point and exit point designated by tunnel nodes. Each tunnel can have any number of execution or data pins which are visible on the macro node when used in other Blueprints and graphs.

Refer to Making Macros for an example on creating a macro.

Working with Assets

In Unreal Engine 5, you can create, delete, and manage Assets directly from the Content Browser. This page describes common Asset workflows, and explains what Asset references are and how to handle moving or deleting your Assets in the editor. Further, you will explore how to export some types of Assets from Unreal Engine into a format that other applications can import.

Creating Assets

To create a new Asset, right-click inside a blank area of the Content Browser. Then, from the context menu that appears, choose the Asset you want to create. This creates a blank Asset of the type you specified. For some Assets, like Blueprints, you can select additional options, like the Blueprint's parent class.



The options in this menu may differ based on your version of Unreal Engine and which plugins you have enabled for your project. Click the image for full size.

Unlike importing Assets, which brings something you made in an external application into Unreal Engine, this method creates a blank Asset which you can populate with content.

Asset References

If an Asset makes use of another Asset in some way, we say that the Assets reference (or have a reference to) each other. For example, if a Cube Actor uses a Color Material, the Actor references that Material. This is why it is important to make sure that references are updated whenever you move or rename an Asset, and that you remove any references to an Asset before you delete it.

Viewing Asset References

To view an Asset's references, right-click the Asset in the Content Browser. Then, from the context menu that appears, select Reference Viewer. A new window will open that displays a visual representation of the Asset's references.



Reference Viewer window for a Material Asset. Click the image for full size.

For more information about the Reference Viewer, refer to the Finding Asset References page.

Copying Asset References

To copy one or more Assets' references to the clipboard, select the Asset or Assets in the Content Browser. Then, right-click your selection and, from the context menu that appears, select Copy Reference.

References contain the Asset type and the path to the .uasset file. They will look similar to the examples below:

This is useful if you need to paste the Asset's reference in a text field, or if you need to generate an external list of Assets.

Replace References Tool

The Replace References Tool provides a way to combine multiple Assets into a single one.

To learn more about this tool, refer to the Replace References tool page.

Managing Assets

To perform common Asset actions, right-click the Asset and select the desired action from the context menu that appears. These actions include:

Action

Description

Edit

Opens the selected Asset in its Editor. For example, performing this action on a Blueprint opens it in the Blueprint Editor.

Rename

Makes the Asset's name editable. To rename the Asset, type a new name and press Enter. After you rename the Asset, Unreal Engine will update all references to the Asset to its new name.

Duplicate

Creates a copy of the selected Asset at the current location. To relocate the copy, drag it to another folder.

Save

Saves the selected Asset.

Show in Folder View

Highlights the Asset's parent folder in the folder tree. Useful for finding the actual location of Assets that are part of a collection.

Show in Explorer (Windows) / Show in Finder (Mac)

Opens an instance of Windows Explorer or Finder at the Asset's location on disk. This is the location of the .uasset file.

Never move, copy, or delete Assets directly on disk, as this might break functionality in your project and lead to data corruption or data loss. Always manage .uasset files through Unreal Editor.

If you need to move an Asset from one project to another, refer to the Migrating Assets page to learn how to do this.

Moving and Copying Assets

You can move or copy Assets and folders in your project through the Content Browser.

The steps to moving or copying an Asset are:

Click the Asset you want to move, then drag it to another folder in the Content Browser or folder tree. As you drag the Asset, a popup window will follow your mouse cursor, indicating which Asset you are trying to move.



When you release the mouse button, a menu will appear.



The menu confirms the folder name and contains a list of three options:

Option

Description

Move Here

Moves the Asset to the new location.

Copy Here

Creates a copy of the Asset at the new location, and leaves the original Asset at its current location.

Advanced Copy Here

Creates a copy of the Asset at the new location, and attempts to automatically resolve all of that Asset's references and dependencies. This option includes an additional save dialog where you need to confirm that you want to save the Asset you copied.

Deleting Assets

To delete an Asset, you can either:

Right-click it in the Content Browser. Then, from the context menu that appears, select Delete.

Select the Asset in the Content Browser, World Outliner, or Level Viewport, then press Delete on your keyboard.

This action will bring up a confirmation window. If your Asset isn't being referenced anywhere (that is, it's not being used anywhere in your Unreal project), click the Delete button to confirm:



If your Asset is being referenced somewhere, the confirmation window will notify you of this and ask you what you want to do. There are two types of referencing that can happen:

If the Asset is referenced by other Assets, it means that another Asset in your project is using this one. For example, if you are trying to delete a Material, and a Static Mesh uses that Material, you will see this warning.

If the Asset is referenced in memory, it could be open in a separate editor window, or it might have been used recently and is still cached in memory.

If you are seeing zero Asset References, but at least one Memory Reference, close all other editor windows and try again. If that doesn't work, save your work and restart Unreal Engine.

In this situation, you have two options:



If you select Replace References, you can choose another Asset to replace this one wherever it is referenced in your project. For example, if a Static Mesh uses a Material, and you want to delete that Material, you can choose a different Material that the Static Mesh will use after the deletion.

If you select Force Delete, the Asset will be deleted without any additional corrections being performed.

This can cause data corruption and data loss. At a minimum, Assets that reference the deleted one will no longer work correctly, but this can break your entire project.

Exporting Assets

Assets in your project are stored on disk as .uasset files, which is a file format specific to Unreal Engine. Exporting an Asset saves it to disk in a format that can then be read by other applications.

To export an Asset from your project, right-click it in the Content Browser. Then, from the context menu that appears, select Asset Actions > Export. This will open a window where you can name your exported Asset and select the location where to save it.

The file type available for export will change depending on the type of Asset you selected. For example, for a Static Mesh Asset, you will see the options to export it as an FBX, OBJ, COPY, or T3D file.

Not all Assets can be exported.

Follow the steps below for an example of Setting and Getting reference to an Actor.

For this example, we are using a new Blueprint Third Person Template with Starter Content enabled.

From the Place Actors panel in the Basic tab, drag a Box Trigger into your level.



We are going to use this to trigger movement in another Actor in the level.

In the Details panel for the Box Trigger, select the Convert to Class Blueprint option.



We are going to create a Blueprint out of this Actor and assign a variable within it which will store the reference Actor.

Give the Blueprint a name then select Create Blueprint (the Blueprint Editor will open).

In the Blueprint Editor, under My Blueprint, click the Add Variable button.



Click on the variable, then in the Details panel, click the Variable Type button and select Actor under Object Reference.



Here we are specifying that the reference is of the Actor type and is an Object in our level.

Name the variable TargetActor and click the Instance Editable checkbox.



This indicates that the variable is set to Public which allows it to be accessed and set outside of this Blueprint via the Details panel in the Main Editor window. This is useful in situations where you want to modify the variable without having to go into the Blueprint to modify it.

Enter text in the Tooltip field explaining what the variable does or is intended for. In this case, it reads "The Actor to Target."

Click the Compile button in the upper left portion of the Blueprint Editor window.



It will change to a green check mark after compiling.



Minimize the Blueprint and return to the Main Editor window then select the Box Trigger Blueprint in your level.

In the Details panel for the window, you should see under Default the Target Actor variable and tooltip.



From the Content Browser, under Content/StarterContent/Shapes add three Shape_Cubes to the level.



If you are using your own project, you can add any Actor, Static Mesh, or Blueprint to the level instead.

Whatever you add to the level, in the Details panel for each Actor, set their mobility to Moveable.



This will allow us to move them via Blueprint script.

Click on the Box Trigger Blueprint in the level.

In the Details panel, click the None box under Target Actor and search for Shape (or the name of the Actor(s) added).



When clicking None all Actors currently in the level are displayed, however we are going to target one of the cubes we added.

Click the eye dropper icon next to the magnifying glass icon.



This will allow you to select an Actor from your level as the Target Actor by clicking on it in the viewport.

Move the eye dropper icon over one of the cubes (or other asset you have added) and click it to make it the Target Actor.



When you select an Actor, the Target Actor variable will update with the selected Actor in the Details panel.



Here we have Set reference to an Actor which will be our Target Actor.

Open the Box Trigger Blueprint, then in the MyBlueprint window, click the eye icon and enable Show Inherited Variables.



This will allow us to add events on the Components that were inherited when we first converted the Trigger Box to a Class Blueprint.

Under Trigger Base, Right-click on CollisionComponent and choose Add Event then Add OnComponentBeginOverlap.



This will create a new Event node on the graph.

Hold Control and drag the TargetActor variable into the graph.



This creates a Get node which will get whatever is assigned to the variable which we have set to an Actor in our level.

Drag off the TargetActor node, search for and add an Add Actor Local Offset node.



This will allow us to add to the current target's transform (allowing us to move it from its current position).

Connect the nodes as shown below and set the Z value on the Add Actor Local Offset node to 500.0.



This will get the target's current location and move it up by 500 along the Z axis whenever the trigger box is overlapped.

In the Components window, click TriggerBox_Blueprint so it is selected.



If you do not see the Components window, you can enable it from the Window menu option.



In the Details panel for the Trigger Box, under Rendering, un-check the Actor Hidden In Game option.



This will make the trigger box visible in-game so that you can see where it is to enter it with your player.

Click Compile and Save, then close the Blueprint.

From the Main Editor Window, click the Play icon to play in the editor.

When you enter the Trigger Box, your selected Actor should move up by 500 units. Each time you enter the Trigger Box, the box will move up by another 500 units. By establishing a reference, the variable knows which Actor to affect in the Trigger Box script. Try affecting a different Actor in the level using this script.

From the Main Editor window, inside the Level Viewport click the Box Trigger Blueprint.

In the Details panel for the Box Trigger, click the eye dropper icon next to Target Actor.



In the level viewport, click a different Actor than the one you used before.

Play in the editor again.

This time the new Actor selected should move up along the Z axis by 500 units each time you enter the Trigger Box. By using the Target Actor variable in our Box Trigger script, we are not locked into a specific Actor associated with the script and can modify it and change the Actor it affects without having to modify the Blueprint itself.

While this example illustrates how to move different objects around, instead of moving an object you could use this method to open doors when the player presses a button, turn on/off different lights, spawn items for the player to pick up or destroy or any number of other possibilities.

This is also one of multiple ways you can get reference to an Actor, for example if you wanted to get Reference to the Player Character which cannot be explicitly set via the Main Editor window, you would take a different approach (see the Related Links section below).

Connecting Nodes

Blueprint Basic User Guide

Specialized Blueprint Node Groups

On this page, you will learn how you can place nodes on your graphs in Blueprints.

Drag-and-Drop

Context Menu Search

Keyboard Shortcuts

Drag-and-Drop

The first method uses a Drag-and-drop procedure where you add nodes to your graph by dragging and dropping nodes from the MyBlueprint window onto your graph. For example, below we have several variables where we drag the PlayerHealth variable into and drop it in our graph so that we can use it in our script.



By Left-clicking on and dragging a variable into the Graph window, we are presented with two options, Get or Set. Selecting Get will create a Getter node which will get the variable or value of the variable while selecting Set will create a Setter node which will allow you to set the value of the variable. Depending upon the type of node, there may be instances where Get is the only option available.



In the image above, the top node is a Getter while the bottom node is a Setter. The Getter, for example, could be used as a condition for elements in your games (such as getting the Player Health and checking if that value is above a specified range and if not, killing the player). The Setter on the other hand, using the previous example, could be used to increase the Player's Health as you are telling the Player Health variable what its value should be by setting it.

You can also drag in any Functions or Macros you have created into your graph in the same manner.



See Functions or Macros for more information.

There are some special context actions that become available when dragging in an Event Dispatcher as illustrated below.



You can select the action you wish to perform from the context menu that appears when dragging in an Event Dispatcher.

See Event Dispatchers for more information.

Context Menu Search

Most of the time when placing nodes, you will use the Context Menu which can be accessed by Right-clicking inside a Blueprint graph.



From the menu above, you can expand any category (or sub category) and select the node you wish to add to the graph.

There is also an option in the upper right corner of the window called Context Sensitive that is enabled by default but can be disabled which automatically filters the options presented in the menu based on the current context.



As you can see below, when Right-clicking and searching for Animation with Context Sensitive on, you are presented with a filtered list.



However, if you un-check Context Sensitive and search for Animation, you are presented with everything related to animation.



While Right-clicking in the graph brings up the Context Menu, you can drag off an existing node to access the Context Menu as well.



Above, we have a Character Movement Component Reference and by dragging off its out pin, we can add nodes that contextually make sense and are relevant to the node we are dragging off of as seen in the example below.



Above we can set the character's Max Walk Speed by searching for Set Max Walk then choosing Set Max Walk Speed from the menu.

Keyboard Shortcuts

You can also use Keyboard Shortcuts to place (and work with) nodes, increasing your productivity.

See Blueprint Editor Cheat Sheet for more information.

Specialized Blueprint Node Groups

Functions

Macros

This page covers several ways in which you can collapse your Blueprint graphs into a single node, into a Function or into a Macro which can help clean up any large graphs you may have by consolidating them into a linked graph.

Collapsing Nodes

Collapsing to Function

Collapsing to Macro

Collapsing Nodes

The easiest method of collapsing which is illustrated below is through Collapsing Nodes into a linked graph. These are primarily used for organization and keeping things nice and neat inside your Event Graph.

On the Graph of a Blueprint, locate the nodes that you want to collapse.



Here we have some nodes that reduce the player's energy after they jump.

Select all the nodes that you want to collapse by Left-clicking and dragging over the nodes.



You can also Control + Left-click to add/subtract nodes to your selection.

Once you have the nodes you wish to collapse, Right-click on any node in the selection and choose Collapse Nodes.



The nodes will be collapsed into a single Collapsed Graph node, which you can then assign a name.



If you mouse over the Collapsed Graph node, you will see a preview window of the node network.



Double-clicking on the Collapsed Graph will open up a new graph with your selected nodes.



Inside the Collapsed Graph, you can add pins to the Inputs or Outputs nodes from the Details panel.



Execute is added by default when collapsing, here we have added two Execute Out Pins: OutOfEnergy and CanJump.

We also modified the graph to check if the player is out of energy before subtracting from the overall energy the player has.



And our Event Graph with the collapsed node would look something like below.



By Right-clicking on the collapsed node, you can select Expand Node to revert the nodes to their original state.



Collapsing to Function

Another method that can be used to collapse your nodes is to collapse them to a Function. The benefit of collapsing your nodes to a Function versus to a Collapsed Graph is that not only can you can call the Function in another area of script based on whatever parameters you wish to specify, but you can also call the Function from inside a different Blueprint (as long as you provide a reference to the Blueprint that contains the Function you wish to call).

Below are the steps you can take to collapse your nodes to a Function.

With the nodes you want to collapse selected, Right-click on a node and select Collapse to Function.



A new Function will be created, which you can re-name from the MyBlueprint window by pressing F2 on it.





Here you can re-name your Function.

Double-clicking on the Function will open it up in a new graph window.



Similar to Collapsed Graphs, you can click on the Inputs or Outputs nodes and add pins to them via the Details panel.

You can call the Function by its name off any condition you wish to specify.



Here we are calling the Remove Energy Function whenever F is pressed.

You can revert this collapsing by Right-clicking on the Function and selecting the Expand Node option.

For more information about Using or Calling Functions, see the Functions documentation.

Collapsing to Macro

In addition to collapsing to a Collapsed Graph or Function, you can also collapse nodes to a Macro. The best way to think of a Macro is that it allows you to take several nodes that are connected and consolidate them into a single node that does everything you need it to do all in one. It is particularly useful for anything that you do frequently, like a complex math equation.

See below for steps on collapsing nodes to a Macro.

With the nodes you wish to collapse selected, Right-click on a node and select Collapse to Macro.



A new Macro node will be created, which you can rename via the MyBlueprint window by pressing F2 on it.



You can open the Macro by Double-clicking on it.



As with the other method of collapsing nodes, you can add Input or Output pins as needed.

Here is our Event Graph which implements the Macro with the additional pins.



By Right-clicking on your Macro, you can select Expand Node to revert the collapsing of the nodes.

For more information about Macros, see the Macros documentation.

Placing Nodes

Blueprint Basic User Guide

Specialized Blueprint Node Groups

Blueprint Editor Cheat Sheet

This page covers the various methods in which you can connect nodes together on your graphs in Blueprints.

Pin to Pin Connection

Node to Node Connection

Drag-and-Drop Connection

Reroute Connections

Pin to Pin Connection

The most common method of connecting nodes together is through Pin to Pin connection.

Using the Left Mouse Button, drag from one pin onto another compatible pin.



A green check mark will appear when hovering over a compatible pin.

When attempting to connect two non-compatible pins, an icon will appear along with the reason why you cannot connect the nodes.



Typically pins are color coded to reflect the type of connection they take in.



There are instances where you can connect two different pin types together, in which case a Conversion Node is created.



Above we have taken a Integer output and connected it to a String input. You can see it will convert via the tooltip.

After connecting, a new conversion node is added between the two pins.



If you drag off a pin into an empty space in the graph, you can place a new node.



When releasing the Left Mouse Button, the context menu will appear.



See Placing Nodes for more information on the Context Menu.

After selecting a node to place, the nodes will automatically become connected.

You can also take an existing connection and connect it to another compatible pin.



In the example image above, holding Control and clicking on a pin and dragging to another input...



This will allow you to move the connection from one pin to another without having to re-wire it.

Pin Actions

There are some additional pin related actions that can be taken for nodes as outlined in the table below.



Action

Command

Pin-specific Context Menu

Right-Click on Pin

Emphasize Connected Wires

Mouse Hover over Pin

Connect to Another Pin

Left-Click + Drag to Pin

Filtered Action Menu for Pin

Left-Click + Drag to graph

Break All Connections

Alt + Left-Click on Pin

Move All Connections

Ctrl + LMB Drag to Pin

Node to Node Connection

There are some Node to Node connections that are available when working with variables, which can save you a bit of time.

Say for example you have a Set variable node (in which you are setting the value of the variable to something) which is connected in your script somewhere and you want to swap it out for another variable without rewiring your script. You can drag another variable on top of the variable you wish to change and it will automatically swap it out and keep everything connected.



Above, we have an Event Begin Play which then sets the Boolean Variable to false and we want to change it out to set a Float Variable we have created instead. We can drag the Float variable onto the Set variable and you can see that the tooltip will inform you of the action you are taking which is to change the node to write Float Variable or Set it.



After confirming as indicated above, your node will be swapped with the new node and the connections will remain.

You can do the same for Get nodes which are connected already (below we are swapping one Bool variable out for another).



Drag-and-Drop Connection

Another shortcut you can take when working with variables is performing Drag-and-Drop (or Node to Pin) connections.

In the example below, upon Event Begin Play we want to set the light color of a Point Light. The Set Light Color node itself asks for the New Light Color which we have created a Linear Color Variable for. In the MyBlueprint window, we can drag-and-drop that variable directly onto the pin in the graph.



When doing so, the variable is automatically connected to the node.



Doing so this way eliminates the process of adding the node to the graph, then performing a pin to pin connection.

Reroute Connections

When working with complex or large Blueprints, you may run into situations where your wires are all over the place and you want to change the way they appear in the graph for visual clarity. There is an option to add a Reroute node, which will allow you to move the wires around by adding an "extension cord" of sorts to your out pin.

Here we have an out pin's wire that is hidden behind another node which is outlined in the box.



By dragging off the out pin that we want to reroute, we can select the Add Reroute Node option.



This will create a new pin in your graph that your original pin is connected to.



You can then drag off the new pin and connect it to your target as shown below.



The Reroute node acts as the original pin and can be dragged off of and new nodes can be connected to it.



Using Reroute nodes will help keep your Blueprints clean, allowing anyone who accesses them the ability to see the connections clearly.

Searching Blueprints

Advanced Search Syntax

The All Subfilter

Searching Blueprints

When in the Blueprint Editor, you can click on Search in the Toolbar or use Ctrl+F to bring up the Find Results window. Here, you can search your Blueprints for nodes, pins, pin values, graphs, variables, and variable values that match your search query. You are also able to search animation graphs.

Right-clicking on a node in a Blueprint or an element in the My Blueprint window and clicking on Find References will also open the Find Results window, with the search field populated with the name of the element as well as the MemberGuid of the element. This ensures that you are searching for that specific variable or function, even if you have multiple instances of that name in other parts of your project.

Searching is an asynchronous process, meaning it will not prevent you from using the editor as the search completes. You can also make multiple searches in different Blueprints at the same time. It leverages the Asset Registry for the searchable data, so the most recently indexed data is always with the asset file.

By default, this tool searches your current Blueprint, but by unchecking the Find in Current Blueprint Only checkbox, you can search all Blueprints in the project. When Blueprints are not indexed in the system, it will inform you, as in the below image:



Clicking Index All results in an extremely slow process that will stall the editor, as it loads all un-indexed Blueprints and re-saves them to cache searchable data. If you do not wish to re-save the content, or the content is protected by source control and cannot be checked out, it will simply load all Blueprint assets to cache the latest searchable data in memory. However, if you do not re-save the content, Index All will need to be done each time you open the editor.



Advanced Search Syntax

Filters are an advanced search feature for targeting searches to specific subsets of data in Blueprints. For example, you can isolate only Blueprints that have nodes named something specific or properties with certain names and flags set. These can be nested and combined to form advanced queries for very specific needs. Certain filters can only be used within other filters, but all filters can be used as a starting point. Below is a non-exhaustive list of searchable tags and with what sort of data that are used for. All tags can be searched for without the use of filters.

Some items can only be searched using tags to help prevent clutter when doing searches without tags. These items are marked below using (Explicit). Currently, filtering is limited to user-added member variables.

An example search string is Nodes(Name=Coin), which will find all nodes in the Blueprint that contain "coin" in the name.

Filter

Searchable Tags

Subfilters

Blueprint

Name

ParentClass (Explicit)

Path (Explicit)

Interfaces (Explicit)

Graphs

Functions

Macros

EventGraphs

Nodes

Pins

Variables/Properties

Components

Graphs

Functions

Macros

EventGraphs

Name

Description

Nodes

Pins

Variables/Properties (for local variables)

Nodes

Name

ClassName (Explicit)

Comment

Pins

Pins

Variables/Properties

Components

Name

DefaultValue

IsArray (Explicit)

IsReference (Explicit)

IsSCSComponent (Explicit)

PinCategory (Explicit)

ObjectClass (Explicit)

PinCategory is the type of pin, "bool", "string", "Actor", "MyBlueprint". ObjectClass is the struct or object represented by the pin/variable/component.

The All Subfilter

All is a special subfilter. When nested in another filter, it will allow any data contained within it to be tested against all children of any objects that pass the filter otherwise.

Example: Graphs(Name=MyFunction && All(Return))

Any graph that contains the name "MyFunction" will test all of its children (nodes, local variables, and pins) for the string "Return".

Blueprint Classes

Components

Graphs

Organizing and Reusing Script

Blueprint Classes

A Blueprint Class, often shortened as Blueprint, is an asset that allows content creators to easily add functionality on top of existing gameplay classes. Blueprints are created inside of Unreal Editor visually, instead of by typing code, and saved as assets in a content package. These essentially define a new class or type of Actor which can then be placed into maps as instances that behave like any other type of Actor.

Blueprint Basic User Guide

Components

Blueprints do not always need to contain scripted behavior. For example, a lightpost in your level may not be interactive, and would just need a mesh to represent the post and a light. Using Components to build up reusable Blueprints would accelerate your level design process. Of course, you could then work with those Components in a graph to allow your players to interact with the lights or have a time-of-day system adjust them accordingly.

Graphs

Graphs contain the design-time and game-time behavior of your Blueprints. The Construction Script runs following the Components list when an instance of a Blueprint Class is created, enabling you to dynamically adjust the look and feel of the new Object or Actor.

The EventGraph of a Blueprint contains a node graph that uses events and function calls to perform actions in response to gameplay events associated with the Blueprint. This is used to add functionality that is common to all instances of a Blueprint. This is where interactivity and dynamic responses are setup. For example, a light Blueprint could respond to a damage event by turning off its LightComponent and changing the material used by its mesh. This would automatically provide this behavior to all instances of the light Blueprint.



EventGraph

Graphs

EventGraph

Graphs

Organizing and Reusing Script

As you create more script in your Blueprints, you may find there are certain sections of script you frequently reuse. Functions and Macros both enable you to reuse sections of script, although each method has different strengths and use cases. For more on the key differences between Functions and Macros, see the Blueprint Best Practices guide.

You can also collapse sections of your Graph into nested Graphs for organization.

Functions

Function Calls

Creating Functions

Macros

Making Macros

Collapsing Graphs

Working with Graphs



The EventGraph of a Blueprint contains a node graph that uses events and function calls to perform actions in response to gameplay events associated with the Blueprint. This is used to add functionality that is common to all instances of a Blueprint. This is where interactivity and dynamic responses are setup. For example, a light Blueprint could respond to a damage event by turning off its LightComponent and changing the material used by its mesh. This would automatically provide this behavior to all instances of the light Blueprint.

The EventGraph of a Level Blueprint contains a node graph that uses events and function calls to perform actions in response to gameplay events. This is used to handle events for the level as a whole and to add functionality for specific instances of Actors and Blueprints within the world.

In either case, an EventGraph is used by adding one or more events to act as entry points and then connecting Function Calls, Flow Control nodes, and Variables to perform the desired actions.

Working with Graphs

The Graph tab displays the visual representation of a particular graph of nodes as it shows all of the nodes contained in the graph as well as the connections between them. It provides editing capabilities for adding and removing nodes, arranging nodes, and creating links between nodes. Breakpoints can also be set in the Graph tab to aid in debugging Blueprints.

See the Blueprint Editor Graph Editor for a detailed guide to working with the EventGraph and other Graphs with Blueprints.

Graph Types

Event Graphs

Construction Script

Functions

Macros

Working with Graphs

A Graph is a network of nodes that can be connected to one another in order to define the flow of execution for the network. Graphs are the basis for implementing functionality in Blueprints. Each Blueprint can contain one or more graphs, depending on the type of Blueprint, that define the implementation of a particular aspect of the Blueprint. Each graph within a Blueprint can also contain sub-graphs, which are essentially collections of nodes collapsed into their own separate graph, mainly for organizational purposes. There are specialized types of Graphs that have unique properties, but the key principles of adding variable references, adding and connecting Nodes, and debugging will apply throughout.

Graph Types

Event Graphs



Event Graphs are the most general type of Blueprint graph. Each new Blueprint Class will contain one Event Graph when it is created, although more can be added. These additional Event Graphs can help to organize your Blueprint networks. Event Graphs generally contain the networks for the gameplay behavior of the Blueprint, with Events, CustomEvents, and Input nodes serving to initiate the flow of execution through the Event Graph.

For more information about this section, see EventGraph

Construction Script



Construction Scripts are unique to Blueprint Classes, with only one ConstructionScript graph present in each Blueprint Class. Construction Scripts are useful for Blueprint Class initialization, as they run right after the Components list is set up for the Blueprint Class.

For more information about this section, see Construction Script

Functions



Functions are node graphs belonging to a particular Blueprint that can be executed, or called, from another graph within the Blueprint. Functions have a single entry point designated by a node with the name of the Function containing a single exec output pin. When the Function is called from another graph, the output exec pin is activated causing the connected network to execute.

For more information about this section, see Functions

Macros



Blueprint Macros, or Macros, are essentially the same as collapsed graphs of nodes. They have an entry point and exit point designated by tunnel nodes. Each tunnel can have any number of execution or data pins which are visible on the macro node when used in other Blueprints and graphs.

For more information about this section, see Macros

Working with Graphs

Whether your Graph is a Construction Script, EventGraph, Function, or Macro, you will edit it in the Graph mode of the Blueprint Editor Reference. Fundamentally, all Graphs contain networks of Nodes connected by Wires.

Blueprints Visual Scripting

Introduction to Blueprints

Specialized Blueprint Node Groups

Blueprint Editor Cheat Sheet

Making Interactive Experiences

Creating Blueprints

Placing Blueprints in Levels

Placing Blueprint Nodes

Connecting Blueprint Nodes

Creating Variables

This page aims to quickly get you started using Blueprints by covering the most basic use cases and commonly used actions.

For more detailed information on Blueprints, refer to the Blueprints Visual Scripting documentation.

Creating Blueprints

There are several methods in which you can create Blueprints, the first is through the Content Browser using the Add New button:

In the Content Browser, click the Add New button.



Select Blueprint Class from the Create Basic Asset section of the dropdown menu.



You can create several different types of Blueprint Assets from the Blueprints option under Create Advanced Asset.

Choose a Parent Class for your Blueprint Asset. See Parent Classes for more information.



After you select your class, a new Blueprint asset will be added to the Content Browser which you can then assign a name.



Create Blueprint Using Assets

You can also create a Blueprint by Right-clicking on an asset in the Content Browser, then under Asset Actions, selecting the Create Blueprint Using This... option.



This option is only available for assets that support it - Static Meshes, Skeletal Meshes, Particle Effects, Sound Cues or Sound Waves, etc. If the option is not available for the selected asset, it will appear grayed out.

After selecting the Create Blueprint Using This... option, you will be prompted on where you want to save the Blueprint. After confirming your save location, the Blueprint will automatically open in the Blueprint Editor.

Placing Blueprints in Levels

To place a Blueprint in your level, you can either...

Drag-and-drop it from the Content Browser into your level.



Or with the Blueprint selected in the Content Browser, you can Right-click in the level and select Place Actor from the context menu.



Placing Blueprint Nodes

There are several methods in which you can place nodes while in Graph Mode (see Placing Nodes for more information), this section will show you the most common method as well as how to connect nodes together.

Most of the time when placing nodes, you will use the Context Menu which can be accessed by Right-clicking inside a Blueprint graph.



From the menu above, you can expand any category (or sub category) and select the node you wish to add to the graph.

There is also an option in the upper right corner of the window called Context Sensitive that is enabled by default but can be disabled which automatically filters the options presented in the menu based on the current context.



As you can see below, when Right-clicking and searching for Animation with Context Sensitive on, you are presented with a filtered list.



However, if you un-check Context Sensitive and search for Animation, you are presented with everything related to animation.



While Right-clicking in the graph brings up the Context Menu, you can drag off an existing node to access the Context Menu as well.



Above, we have a Character Movement Component Reference and by dragging off its out pin, we can add nodes that contextually make sense and are relevant to the node we are dragging off of as seen in the example below.



Above we can set the character's Max Walk Speed by searching for Set Max Walk then choosing Set Max Walk Speed from the menu.

Connecting Blueprint Nodes

To connect nodes, drag off one pin and connect it to another pin of the same type (there are some instances where a conversion node will be created, for example, connecting a Float output to a Text input will create a conversion node between the two and automatically convert and connect the two nodes).

Here is a basic connection between two nodes where the input/output pins are of the same type.



And here is an example of a conversion in progress.



See Blueprint Editor Cheat Sheet for additional node based actions and shortcuts.

Creating Variables

Variables are properties that hold a value or reference an Object or Actor in the world. These properties can be accessible internally to the Blueprint containing them, or they can be made accessible externally so that their values can be modified by designers working with instances of the Blueprint placed in a level.

You can create variables for your Blueprints from the MyBlueprint window, by clicking on the Add Button (+) on the variable list header.



Once you have created a variable, you will need to be able to define the properties of the variable.

See Blueprint Variables for more information on variable types and more on working with them.

Working with Graphs



The EventGraph of a Blueprint contains a node graph that uses events and function calls to perform actions in response to gameplay events associated with the Blueprint. This is used to add functionality that is common to all instances of a Blueprint. This is where interactivity and dynamic responses are setup. For example, a light Blueprint could respond to a damage event by turning off its LightComponent and changing the material used by its mesh. This would automatically provide this behavior to all instances of the light Blueprint.

The EventGraph of a Level Blueprint contains a node graph that uses events and function calls to perform actions in response to gameplay events. This is used to handle events for the level as a whole and to add functionality for specific instances of Actors and Blueprints within the world.

In either case, an EventGraph is used by adding one or more events to act as entry points and then connecting Function Calls, Flow Control nodes, and Variables to perform the desired actions.

Working with Graphs

The Graph tab displays the visual representation of a particular graph of nodes as it shows all of the nodes contained in the graph as well as the connections between them. It provides editing capabilities for adding and removing nodes, arranging nodes, and creating links between nodes. Breakpoints can also be set in the Graph tab to aid in debugging Blueprints.

See the Blueprint Editor Graph Editor for a detailed guide to working with the EventGraph and other Graphs with Blueprints.

Comments can be added directly to single Blueprint nodes, or they can be added as comment boxes to group related nodes and provide descriptions about their functionality. These can be used solely for organizational purposes to make the Graphs more readable, but they can also be used for informational purposes as they allow for textual descriptions to be added just like adding comments to code.

Node Comments

Creating Node Comments

Editing and Removing Node Comments

Comment Boxes

Creating Comment Boxes

Editing Comment Box Text

Deleting Comment Boxes

Comment Box Properties

Node Comments

Creating Node Comments

To add a comment directly to a node in a Blueprint graph:

Right-click on the node.

Type a comment into the Node Comment text box in the menu that appears, then press Enter.



Your comment will appear in a small comment bubble above the node. Node comments will not scale when the graph zooms.



Editing and Removing Node Comments

Right-click on the node again and change the text in the Node Comment text box in the Right-click menu to change the comment. Deleting the text and pressing Enter will remove the comment.

Comment Boxes

Creating Comment Boxes

Creating a comment box is easy:

Select a group of nodes you would like to comment. It is also possible to create an empty comment box first and then arrange the comment box around nodes later or use it as a floating comment in a given area.

Right-click and choose Create Comment from Selection (or Add Comment... if no nodes are selected). A new comment box will appear.



You can also press C to create a comment.

Enter your comment into the header of the comment box that appears.



The comment box can be resized by dragging the lower right corner. Note that if trying to move the comment box, any nodes that are within the boundaries of the box will move along with it. This serves as a very useful way to rearrange coordinated groups of nodes. This behavior can be changed per-comment in the Details tab for the comment box.



Note that the text of comment boxes will scale as the graph is zoomed, so these can be very helpful for at-a-glance overviews of a zoomed-out graph's functionality.



Editing Comment Box Text

Right-click on the header of the comment box, and change the text in the Node Comment text box of the Right-click menu to change the text of your comment. Press Enter to save your new comment.



Alternatively:

Press F2 with the comment box selected to edit the comment.

Double-click on the header of the comment box to edit the comment.

Deleting Comment Boxes

Click on any comment box and press the Delete key, or Right-click on the header of the comment box and select Delete from the Right-click menu. Both of these options will delete the comment box but have no effect on the nodes contained within the comment box.

Comment Box Properties

These comment box properties can be adjusted in the Details tab for each comment box. Simply click on the comment box to show its properties in the Details tab.

Item

Description

Properties

Comment Color

This allows you to change the background color of the comment box. Remember to use Alpha to adjust the transparency of the background.

Color Comment Bubble

If this is checked, the Comment Color is applied to the comment box.

Move Mode

This allows you to set whether moving the comment also moves nodes within the comment (Group Movement) or whether the comment can be moved independently without affecting the nodes within it (Comment).

Graphs

Blueprint Variables

Events

Functions

Components Window

Adding Components

Removing Components

Transforming Components

Component Assets

Renaming Component Instance Variables

Component Events and Functions

A Component is a piece of functionality that can be added to an Actor.

When you add a Component to an Actor, the Actor can use the functionality that the Component provides. For example:

A Spot Light Component will make your Actor emit light like a spot light.

A Rotating Movement Component will make your Actor spin around.

An Audio Component will give your Actor the ability to play sounds.

Components must be attached to an Actor and can't exist by themselves.

For more information on Components, please see the Components Overview documentation.

Components Window

With an understanding of Components, the Components window inside the Blueprint Editor allows you to add Components to your Blueprint. This provides a means of adding collision geometry via CapsuleComponents, BoxComponents, or SphereComponents, adding rendered geometry in the form of StaticMeshComponents or SkeletalMeshComponents, controlling movement using MovementComponents, etc. The Components added in the Components list can also be assigned to instance variables providing access to them in the graphs of this or other Blueprints.



Adding Components

To add a Component to a Blueprint from the Components window:

Select the type of Component you want to add from the dropdown list, i.e. a CameraComponent.



After selecting a Component from the list, you will be prompted to enter a name for your Component.



Components can also be added by dragging-and-dropping assets from the Content Browser into the Components window.



Assets this method applies to include: StaticMeshes, SoundCues, SkeletalMeshes, and ParticleSystems.

Removing Components

To remove a Component from the Components window, Right-click on the Component's name and select Delete.



You can also select the Component in the window and press the Delete key to remove it as well.

Transforming Components

Components, when added to an instance in your level, are placed by default at the location of that instance. However, they can be Transformed, Rotated, and Scaled as necessary in either the Details panel or the Viewport similar to the method in which you can Transform Actors.

You can select Components for transformation either by clicking on their name in the Components window or by clicking directly on the Component in the Viewport. When Transforming, Rotating, and Scaling your Components in the Viewport, hold Shift to enable snapping. This snapping requires that snapping be enabled in the Level Editor and uses the Snap Grid settings from the Level Editor (see Actor Snapping for more information on Grid Snapping).

Exact values can also be entered for Location, Rotation, and Scale in the Details panel for your selected component.



Transforming, Rotating, or Scaling a parent component will propagate the transformation down to all child components as well.

Component Assets

Once you have added a Component, you may need to specify the asset to occupy the Component (such as assigning a Static Mesh to use for a StaticMeshComponent). There are a couple of different ways you can assign an asset to use for a Component type as described below.

Assigning Component Assets

To assign an asset to a Component in the Components window:

With the Component selected, in the Details panel find the section that corresponds to your Component type.



Above we have added a StaticMeshComponent and under StaticMesh is where we would assign the asset to use.

Click the Static Mesh drop-down box, then select the asset to use from the context menu.



Another method of assigning an asset can be done using the Content Browser:

Select the asset you would like to assign as the asset to use with your Component in the Content Browser.



With the Component selected, in the Details panel find the section that corresponds to your Component type.



Above we have added a StaticMeshComponent and under StaticMesh is where we would assign the asset to use.

Instead of clicking the Static Mesh box, since an asset is selected in the Content Browser, click the button.



This will assign the asset selected in the Content Browser as the asset to use in the Component.

Removing Component Assets

To clear an assigned asset from a Component:

In the Details panel for the Component, click the button next to the currently assigned asset.



Or, click the Current Asset box for your asset, then select the Clear from the context menu.



In either method, the asset will be removed as being assigned to the Component.

Browsing to Component Assets

You can also browse to a currently assigned asset of a Component, jumping to and locating in the Content Browser:

In the Details panel for the Component, press the button next to the currently assigned asset.



The Content Browser opens showing the assigned asset selected.



Renaming Component Instance Variables

Components created in the Components window will have an automatically generated instance variable name based on their type.

To change the name of these variables:

Select the component in the Components window and its details will appear in the Details panel.



Enter a new name for the component in the Variable Name field in the Details panel and confirm by pressing Enter.

You can quickly rename a Component by selecting it in the Components window then pressing F2.

Component Events and Functions

You can quickly add events and/or functions based on a Component to the Event Graph of the Blueprint through different methods. Any events or functions created in this manner are specific to that particular function and do not have to be tested to verify which Component is involved.

Add a Component for which events can be created, such as a BoxComponent.



Provide a name for your Component, here we called it Trigger.



In the Details panel, click the Add Event button and select your desired event type.



You can also Right-click on the Component in the Components window and select your event from the Add Event context menu.



In either manner, a new event node (based on the type you selected) will be added to the Event Graph which will automatically open.



Events and Functions can also be added for a Component from the Event Graph through the My Blueprint window:

In the My Blueprint window, under Components, select your Component.

Right-click in the graph to bring up the context menu.



If the component has any associated events or functions, they will be listed at the top.

Not all Components have associated events. For instance, a PointLightComponent only has functions.

You can also Right-click on the Component in the My Blueprint window to access the Add Event context menu.





Implementing Blueprint Interfaces

Blueprint Communication Usage

Creating Event Dispatchers

Setting Properties

Using Event Dispatchers

An example on Event Dispatchers from the Blueprint Actor Communication page demonstrates both languages of Blueprint and C++ in a feature-oriented way. This page should be considered a supplemental helper for Blueprint Scripting.

By binding one or more events to an Event Dispatcher, you can cause all of those events to fire once the Event Dispatcher is called. These events can be bound within a Blueprint Class, but Event Dispatchers also allow events to be fired within the Level Blueprint.

Creating Event Dispatchers

Event Dispatchers are created in the Blueprint Editor's Blueprint Editor My Blueprint Panel tab.

To create a new Event Dispatcher:

In the My Blueprint panel click on the Event Dispatcher category: .

Enter a name for the Event Dispatcher in the name field that appears at the end of the list in the My Blueprint tab.



Setting Properties

By selecting the Event Dispatcher in the My Blueprint panel, you can edit its properties in the Details panel. You can set the tooltip and category for your Event Dispatcher, as well as add inputs.

Adding inputs to your Event Dispatcher allows you to send variables to each event bound to your Event Dispatcher. This allows data flow not only within your Blueprint Class, but also between your Blueprint Class and the Level Blueprint.

The process to add inputs to your Event Dispatcher is similar to the workflow for adding inputs and outputs to functions, custom events, and macros. If you would like to use the same inputs as another event, you can use the Copy Signature from dropdown to indicate the event. To add your own inputs to the Event Dispatcher:

Click New in the Inputs section of the Details pane.



Name the new input and set its type using the dropdown menu. In this example, there is a String input parameter named MyStringParam.



You can also set a default value and indicate whether or not to pass the parameter by reference by expanding the entry for the parameter.



Details

Using Event Dispatchers

After creating the Event Dispatcher, you can add event nodes, bind nodes, and unbind nodes linked to it. Although you can double-click on the Event Dispatcher entry in the My Blueprint tab to open the Event Dispatcher's graph, the graph is locked and you cannot modify the Event Dispatcher directly. The bind, unbind, and assign methods enable you to add events to the Event Dispatcher's event list, while the call method activates all the events stored in the event list.

Event, bind, and unbind nodes can be added in both the Blueprint Class and the Level Blueprint. Except for the Event node, each node has a Target input pin:

In the Blueprint Class, this pin is automatically set to Self. This means that the event list is changed for the class, so every instance of the class will be changed.

In the Level Blueprint, this pin must be connected to a reference to an instance of the class in the level. This means that the event list will only be changed for that particular instance of the class. The Level Blueprint documentation explains how to create any Actor references you might need.



Adding and removing events from an Event Dispatcher's events list.



Calling the Event Dispatcher executes all of the currently bound events in the events list.



Creating events that can be bound and added to the Event Dispatcher's events list.

Creating Bind, Unbind, and Unbind All Nodes

In Blueprint Classes

In Level Blueprints



Calling the Event Dispatcher will have no effect if there are no events bound to it. Consider that each Event Dispatcher has a list of events associated with it. The way to add an event to this list is by using a Bind Event node, and the way to remove an event from this list is by using an Unbind Event node. It is also possible to unbind all of the events currently bound to an Event Dispatcher with an Unbind All Events node.

Each event can be bound only once, even if the Bind Event node is executed multiple times. Also, events in the Blueprint Class and the Level Blueprint are both added to the same event list, so an Unbind All Events node will unbind events in both the Blueprint Class and the Level Blueprint.

An Unbind All Events node executed in the Blueprint Class will unbind events in both the Blueprint Class and the Level Blueprint for all instances of the class.

An Unbind All Events node executed in the Level Blueprint will unbind events in both the Blueprint Class and the Level Blueprint, but just for the Target supplied.

Creating Bind, Unbind, and Unbind All Nodes

The processes for creating Bind Event, Unbind Event, and Unbind All Events nodes are very similar. The steps below explain how to create a Bind Event node, but Unbind Event and Unbind All Events nodes can be created by choosing the respective menu items at the appropriate steps.

In Blueprint Classes

Drag off of the Event Dispatcher's name in the My Blueprint tab, and drop into the graph you are working in.

Select Bind in the menu that appears.



Alternatively:

Right-click in the graph.

Search for Bind Event to [EventDispatcherName] and select the entry from the context menu.



In Level Blueprints

Add a reference to the Actor in your level you would like to call the Event Dispatcher for.



Drag off of the output pin of the reference node and release to show the context menu.



Navigate to Event Dispatcher > Bind Event to [EventDispatcherName] in the context menu. Searching for "Bind [EventName]" should quickly bring up the correct entry.



The Call node will appear, with the Actor reference already wired to the Target pin.



Calling in Blueprint Classes

Calling in Level Blueprints



Calling an Event Dispatcher with a Call node causes all of the events bound to the Event Dispatcher to fire. You can have more than one Call node for each Event Dispatcher, and you can also call the Event Dispatcher in both Blueprint Classes and Level Blueprints.

Calling in Blueprint Classes

Drag off of the Event Dispatcher's name in the My Blueprint tab, and drop into the graph you are working in.

Select Call in the menu that appears.



Alternatively:

Right-click in the graph.

Expand Event Dispatcher in the context menu that appears.



Select Call [EventDispatcherName] under Event Dispatcher.



Calling in Level Blueprints

Add a reference to the Actor in your level you would like to call the Event Dispatcher for.



Drag off of the output pin of the reference node and release to show the context menu.



Navigate to Event Dispatcher > Call [EventDispatcherName] in the context menu. Searching for "Event Call" should quickly bring up the correct entry.



The Call node will appear, with the Actor reference already wired to the Target pin.



Creating Event Dispatcher Event Nodes

In Blueprint Classes

In Level Blueprints



Using the Event option on the Event Dispatcher's menu creates a custom event with the correct signature so that it can be bound to the Event Dispatcher. While the event node appears similar to a Custom Event node, without being connected to a Bind node, this event will never be triggered when the Call [EventDispatcherName] node is executed.

Creating Event Dispatcher Event Nodes

Event Dispatcher Event nodes are connected to Bind Event nodes by wiring the red square pin on their upper right corner to the red square Event input pin on the Bind Event node. So, if you already have a Bind Event node for a particular Event Dispatcher and would like to create the event node for it:

Drag off of the Event input pin and release to show the context menu.

Select Add Custom Event for Dispatcher in the context menu.



An event node will be created and automatically wired correctly to the Bind Event node. Enter a name for your event.



Selecting Assign from either the Event Dispatcher menu or the context menu will also create a Bind Event node and a corresponding Event node, already wired together.

In Blueprint Classes

Drag off of the Event Dispatcher's name in the My Blueprint tab, and drop into the graph you are working in.

Select Event in the menu that appears.



Enter a name for your event.



In Level Blueprints

A special type of Event Dispatcher event can be set up in the Level Blueprint, and it is the one case where an event is automatically bound to the Event Dispatcher. These events are created with the same steps as the default events such as OnClicked or OnOverlap events. The Level Blueprint documentation provides a walkthrough for this process.

These particular events are unique, and are automatically bound at the start of gameplay. As a result, an Unbind All node executed at any point will unbind these events as well. It is possible to rebind them, however, by wiring their delegate pins to Bind Event nodes that are executed at other points in gameplay.

Event Level Reset

Event Actor Begin Overlap

Event Actor End Overlap

Event Hit

Event Any Damage

Event Point Damage

Event Radial Damage

Event Actor Begin Cursor Over

Event Actor End Cursor Over

Event Begin Play

Event End Play

Event Destroyed

Event Tick

Event Receive Draw HUD

Custom Event

Events are nodes that are called from gameplay code to begin execution of an individual network within the EventGraph. They enable Blueprints to perform a series of actions in response to certain events that occur within the game, such as when the game starts, when a level resets, or when a player takes damage.

Events can be accessed within Blueprints to implement new functionality or to override or augment the default functionality. Any number of Events can be used within a single EventGraph; though only one of each type may be used.

An event can only execute a single object. If you want to trigger multiple actions from one event, you will need to string them together linearly.



Event Level Reset

This Blueprint Event node is only available in the Level Blueprint.

This Blueprint Event node executes only on the server. For single player games, the local client is considered the server.



The Level Reset event sends out an execution signal when the level restarts. This is useful when you need something to be triggered once a level has reloaded, such as in a gaming situation when the player has died but the level does not need to reload.



Event Actor Begin Overlap



This event will execute when a number of conditions are met at the same time:

Collision response between the actors must allow Overlaps.

Both Actors that are to execute the event have Generate Overlap Events set to true.

And finally, both Actors' collision starts overlapping; moving together or one is created overlapping the other.

For more information on collision, see: Collision Responses.



When this Blueprint Actor overlaps the Actor stored in the Player Actor variable, it will increment the Counter integer variable.



Item

Description



Output Pins



Other Actor

Actor - This is the Actor that is overlapping this Blueprint.

Event Actor End Overlap



This event will execute when a number of conditions are met at the same time:

Collision response between the actors must allow Overlaps.

Both Actors that are to execute the event have Generate Overlap Events set to true.

And finally, both Actors' collision stop overlapping; moving apart or if one is destroyed.

For more information on collision, see: Collision Responses.



When this Blueprint Actor stops overlapping any other Actor except the Actor stored in the Player Actor variable, it will destroy the Actor that overlapped it.



Item

Description



Output Pins



Other Actor

Actor - This is the Actor that is overlapping this Blueprint.

Event Hit



This event will execute as long as the collision settings on one of the Actors involved have Simulation Generates Hit Events set to true.

If you are creating movement using Sweeps, you will get this event even if you don't have the flag selected. This occurs as long as the Sweep stops you from moving past the blocking object.

Item

Description



Output Pins



My Comp

PrimitiveComponent - The Component on the executing Actor that was hit.

Other

Actor - The other Actor involved in the collision.

Other Comp

PrimitiveComponent - The component on the other Actor involved in the collision that was hit.

Self Moved

Boolean - Used when receiving a hit from another object's movement (if false), the directions of Hit Normal and Hit Impact Normal will be adjusted to indicate force from the other object against the object being hit.

Hit Location

Vector - The location of contact between the two colliding Actors.

Hit Normal

Vector - The direction of the collision.

Normal Impulse

Vector - The force that the Actors collided with.

Hit

Struct HitResult - All the data collected in a Hit, you can pull off and "break" this result to gain access to the individual bits of data.



Hit

Event Any Damage

This Blueprint Event node executes only on the server. For single player games, the local client is considered the server.



This event is passed along when general damage is to be dealt. Like drowning or environmental damage, not specifically point damage or radial damage.

Item

Description



Output Pins



Damage

Float - The amount of damage being passed into the Actor.

Damage Type

Object DamageType - This is the object that contains additional data on the Damage being dealt.

Instigated By

Actor - The Actor that is responsible for the damage. This would be the Actor that fired a gun or threw the grenade to deal the damage.

Damage Causer

Actor - The Actor that caused the damage. This would be like a bullet or explosion.





Here if the damage being dealt to the Actor is coming from Water, it will subtract health and print a warning to the screen.



Event Point Damage

This Blueprint Event node executes only on the server. For single player games, the local client is considered the server.



Point Damage is meant to represent damage dealt by projectiles, hit scan weapons, or even melee weaponry.

Item

Description



Output Pins



Damage

Float - The amount of damage being passed into the Actor.

Damage Type

Object DamageType - This is the object that contains additional data on the Damage being dealt.

Hit Location

Vector - The location of where the damage is being applied.

Hit Normal

Vector - The direction of the collision.

Hit Component

PrimitiveComponent - The Component on the executing Actor that was hit.

Bone Name

Name - The name of the bone that was hit.

Shot from Direction

Vector - The direction the damage came from.

Instigated By

Actor - The Actor that is responsible for the damage. This would be the Actor that fired a gun or threw the grenade to deal the damage.

Damage Causer

Actor - The Actor that caused the damage. This would be like a bullet or explosion.





In this example, when any damage is received, the damage dealt is subtracted from the Actor's health, but if the Head of the Actor is hit then the Actor's health is set to -1.



Event Radial Damage

This Blueprint Event node executes only on the server. For single player games, the local client is considered the server.



The Radial Damage Event is called whenever the parent Actor for this sequence receives radial damage. This is useful for handling events based on explosion damage, or damage caused indirectly.

Item

Description



Output Pins



Damage Received

Float - The amount of damage received from the event.

Damage Type

Object DamageType - This is the object that contains additional data on the Damage being dealt.

Origin

Vector - This gives the location in 3D space where the damage originated.

Hit Info

Struct HitResult - All the data collected in a Hit, you can pull off and "break" this result to gain access to the individual bits of data.

Instigated By

Controller - The Controller (AI or Player) that instigated the damage.

Damage Causer

Actor - The Actor that caused the damage. Could be a bullet, rocket, laser, or a character punching another.



Event Actor Begin Cursor Over



When using the mouse interface, when the mouse cursor is moved over an Actor, this event will execute.



Once the mouse passes over this Actor it sets the scalar Parameter named Highlight on the Dynamic Material Instance to 1.0.



Event Actor End Cursor Over



When using the mouse interface, when the mouse cursor is moved off an Actor, this event will execute.

Target Notification

Event Begin Play



This event is triggered for all Actors when the game is started, any Actors spawned after the game is started will have this called immediately.



When beginning play, this Actor will set its Health to 1000 and Score to 0.



Event End Play



This event is executed when the Actor ceases to be in the World.



Once this Actor is no longer in the World, a String will output to indicate the reason for the Event being called.



Item

Description



Output Pins



End Play Reason

enum EEndPlayReason - An enum indicating the reason for why Event End Play is being called.

Event Destroyed



This event is executed when the Actor is Destroyed.

Score is being set to Value plus Score

The Destroyed Event will be deprecated in a future release! The functionality of the Destroyed function has been incorporated into the EndPlay function.

Event Tick



This is a simple event that is called on every frame of gameplay.

Item

Description



Output Pins



Delta Seconds

Float - This outputs the amount of time between frames.



This example uses Delta Seconds to form a countdown timer that displays in the log with the final tick being "Blast Off!"



Event Receive Draw HUD

This Event is only available to Blueprint Classes that inherit from the HUD class.



This is a specialized event that enables Blueprints to draw to the HUD. The HUD draw nodes require this event to be the one that creates them.

Item

Description



Output Pins



Size X

Int - The width of the render window in pixels.

Size Y

Int - The height of the render window in pixels.



Hit Box

Custom Event



The Custom Event node is a specialized node with its own workflow.

To learn more:

Custom Events: Create your own events that can be called at any point in your Blueprint's sequence.

Calling Events through Sequencer: Create events to be triggered at specific times during the playback of a cinematic sequence.

Access Specifiers

Pure vs. Impure

Creating Functions

Within A Blueprint

In a Blueprint Interface

Editing Functions

Input and Output Parameters

Defining Functionality

Calling Functions

Calling Functions from External Blueprints

Troubleshooting Functions

Functions are node graphs belonging to a particular Blueprint that can be executed, or called, from another graph within the Blueprint. Functions have a single entry point designated by a node with the name of the Function containing a single exec output pin. When the Function is called from another graph, the output exec pin is activated causing the connected network to execute.

See the Delegates page for reference and usage information.

Access Specifiers

When creating Functions, you have the ability to specify what other objects can and cannot access those Functions. This is done by setting the Access Specifier property, which is available within the Details panel for any selected Function.



The property contains the following settings:

Setting

Description

Public

A setting of Public means that any other object can call this Function. This is the default setting.

Protected

A setting of Protected means that the Function can only be called by the current Blueprint, as well as any Blueprints that derive from the current Blueprint.

Private

A setting of Private means that the Function can only be called from within the current Blueprint.

Pure vs. Impure

Functions can either be Pure or Impure. The main difference is that Pure Functions promise not to modify state or the members of the class in any way, while Impure Functions are free to modify state. Pure Functions are generally used for getter Functions or operators that just output a data value.

Impure Functions must be explicitly executed by connecting exec wires to Function Call nodes in an EventGraph. Impure Functions are designated using one of these methods:

Specifying the BlueprintCallable keyword in the UFUNCTION declaration for UFUNCTIONs defined in code.

Leaving the Pure checkbox unchecked for Functions added through the Blueprint Editor.

Pure Functions are wired to Data Pins and are automatically executed by the compiler when the data relying on them is required. This means that a Pure Function will be called one time for each node it is connected to. Pure Functions are designated using one of these methods:

Specifying the BlueprintPure keyword in the Function declaration for Functions defined in code.

Checking the Pure checkbox for Functions added through the Blueprint Editor.

Creating Functions

Within A Blueprint

To create a Function inside a Blueprint Class or Level Blueprint:

In the My Blueprint tab create a new function, by clicking on the Add Button on the Functions list header.

Enter a name for your Function.



Your Function will open in a new tab in the Graph Editor tab of the Blueprint Editor.

You can also create a Function by Right-clicking in the My Blueprint tab and selecting Function.



In a Blueprint Interface

Functions created in a Blueprint Interface are created with the same method as Functions in a Blueprint Class or Level Blueprint, but the implementation is very different.

To create a Function inside a Blueprint Interface:

In the My Blueprint tab create a new function, by clicking on the Add Button on the Functions list header.

Enter a name for your Function.



Your Function will open in a new tab in the Graph Editor tab of the Blueprint Editor.

You can also create a Function by Right-clicking in the My Blueprint tab and selecting Function.



See the Gameplay Timers page for reference and usage information.

Editing Functions

Once a Function has been created, you then need to define its functionality. This is a two-step process:

Create the necessary input and output parameters.

Create a node network in between your input and output to define Function behavior.

You can set a Description, Category, Access Specifier, and whether or not the Function is Pure in the Details tab.

To open the Details tab for your Function, you can:

Select your Function in the My Blueprint tab.

Select the Function node in the graph where it is being called.

Select the Function entry (or result) node in the Function's graph.



Input and Output Parameters

You can set the input and output parameters in the Details tab for your Function as well.

To add input or output parameters:

Click on the New button in either the Inputs or Outputs section of the Details pane.

Name the new parameter and set its type using the dropdown menu. In this example, there are two vector data inputs named VectorA and VectorB, and a float data output called Distance.



Unlike Blueprint Macros, you can only add data inputs and outputs to Functions.

The entry and result nodes in the Function graph will automatically update with the correct pins, as will any Function call nodes.





You can also set a default value by expanding the entry for the parameter, as well as select whether or not the value should be passed by reference.



To change the location of the pin for this parameter on the edge of the node, use the up and down arrows in the expanded Details pane entry.

Your Function is now ready to have its functionality defined. We will do this by creating a node network between the entry and result nodes.

Defining Functionality

Your Function can be defined by creating a Blueprint graph that connects between the input and output nodes. In this example, we will have created the necessary network to apply the 3D version of the Pythagorean Theorem (illustrated below), returning the distance between 2 points in 3D space.

Converted to a node network in Blueprints...



Click image for full view.

Calling Functions

Once you have created and defined your Function, it is time to call it in your EventGraph. To create a node that will call your Function:

Drag your Function from the My Blueprint tab to an empty spot in your EventGraph.

Right-click in the EventGraph or drag from an appropriate execution or data pin to open the context menu. Search within the context menu for your Function, and then select it to add the Function call node.

The network below takes two vector variables, and on every tick, calculates the distance between them and prints the distance to the screen.



In this example, we have created 2 public vector variables. In the settings for each one, we set Show 3D Widget to True. Now, after adding the Blueprint to the level, 3D widgets will appear at the positions defined by Point A and Point B. The 3D widgets allow us to easily change the values of Point A and Point B by moving them in the viewport.



Now when we test the map, the distance between the two points is logged on every tick, proving that our Function is working.



Calling Functions from External Blueprints

You can also call a Function in a Blueprint from inside another Blueprint, as long as you have reference to the Blueprint that contains the Function you want to call.

Take for example below, we have a Function in our Character Blueprint (which is called MyCharacter) called Take Damage which reduces a variable called PlayerHealth by 10 whenever it is called.



Inside another Blueprint, which is a projectile that gets spawned when the player fires a weapon from the MyCharacter Blueprint, we have some script for what happens when the projectile hits something.



The script, which is the default MyProjectile Blueprint that is included with the Blueprint First Person Template Project, already does something when the projectile hits something that is simulating physics and adds impulse at the location it was hit. Say we wanted to check if we hit the player and if we did, to call the Take Damage Function.

We can do so by dragging off the Other pin of the Event Hit and Casting To our MyCharacter Blueprint.



Once we do that, we have a reference to our player character and can then drag off the As My Character pin and call the Function Take Damage that resides in that Blueprint.



We could then hook up the rest of the script to destroy the projectile after it hits the player as so:



And if we were to play in the editor, we would see something similar to below.

We have hooked the PlayerHealth variable up to a PrintString node so that we can show its current value. By default it's set to 100 and when the player shoots into the wall and it bounces back and hits the player, you can see that the Take Damage function is being called and reduces the PlayerHealth variable by 10 each time they are hit.

Troubleshooting Functions

If you get a Warning! bar on your Function call node with an "Unable to find function with name [FunctionName]" message, Compile your Blueprint.



If you change the number of input or output parameters on your Function, you will also need to Compile your Blueprint.

Functions

Self

Other

Pure

Function Calls are actions that can be formed within Blueprints that correspond to functions belonging to a targeted Actor or Object. In the case of Level Blueprints, the associated Actor in many cases is the Level Blueprint itself. Function Calls are displayed as boxes with titles that show the name of the function. Different types of function calls have different color titles.

Self

Self Function Calls are functions that belong to the Blueprint itself, by way of being declared in the class the Blueprint derives from or a parent class.

Other

Other Function Calls are functions that belong to other Objects or Actors besides the Blueprint. For example, the Blueprint might have a StaticMeshComponent that can have its mesh changed via a SetStaticMesh function call. Since this function belongs to the StaticMeshComponent and not the Blueprint, it is an Other Function Call.

Pure

Pure Function Calls are special actions that can be performed that do not directly affect the world or the Objects in it. These are generally things like functions that output a property value, or mathematical operations such as adding, subtracting, multiplying, dividing, etc. two values, the results of which have no impact on anything. It is the assigning or use of the result that generates an effect on the world.





Standard

Compact

B

C

E

F

I

P

Quick Jump: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

B

Generic term that can refer to the visual scripting system as a whole or a standard class Blueprint that defines a new class or type of Actor.

C

Event defined through the Blueprint Editor that can be executed via nodes in an EventGraph.

E

Executable method defined through code that has no return value and does not have any output parameters. Events are the starting points for execution and, thus, have only an output exec pin. These are executed from native code. Also see Custom Events.

F

Executable method defined either through code or through the Blueprint Editor that has at least one output parameter or return a value. Functions can either be Pure or Impure.

Node that can be placed in an EventGraph to execute a Function.

I

Function that is free to modify state or members of the class. See the Pure vs Impure section for more details.

P

Variable that is only editable in the Class Defaults, and is reset to that default value each time the construction scripts are run. Private variables can be used to keep track of state within the Blueprint.

Variable that is editable individually on each instance of the Blueprint, but is considered constant within the graphs of the Blueprint. Public variables can be used to allow designers to tweak the look or behavior of a Blueprint on a per-instance basis.

Function that promises not to modify state or members of the class. See the Pure vs Impure section for more details.

Blueprints are a powerful new feature introduced in Unreal Engine 4. Blueprints are a way to create new UClasses without the need for writing or compiling code. When you create a Blueprint, you can choose to extend a C++ class or another Blueprint class. You can then add, arrange, and customize Components, implement custom logic using a visual scripting language, respond to Events and interactions, define custom Variables, handle Input, and create a fully custom object type.

Each Blueprint has a Construction Script, analogous to a constructor in C++, which is run when the object is created. This script can dynamically construct the Actor instance based on any number of factors, such as a fence that automatically sizes itself to fill a gap between buildings. In this sense, a Blueprint can be thought of as a very powerful prefab system.



Information about Blueprint Function Libraries for C++ in Unreal Engine.



The steps of the Blueprint compilation process



Technical guide for gameplay programmers exposing gameplay elements to Blueprints.



Tips and tricks for how best to write a Blueprint-friendly API

Often during the development of your project, you may discover the need for a set of functions that make development easier. These functions typically are stateless and reused across a variety of gameplay code. This need may present itself when building with Blueprints. In a previous section of this manual, you saw how to expose your game objects' functions and properties to Blueprints. However, if you want to expose shared utility functions, you don't necessarily want to tie them to a specific gameplay object type. For those cases, we have Blueprint Function Libraries.

Blueprint Function Libraries are a collection of static functions that provide utility functionality not tied to a particular gameplay object. These libraries can be grouped into logical function sets, e.g. AI Blueprint Library, or contain utility functions that provide access to many different functional areas, e.g. System Blueprint Library.

Creating a Blueprint Function Library is very similar to exposing functions to Blueprints using the UFUNCTION() macro. Instead of deriving from an Actor or directly from UObject all Blueprint Libraries inherit from UBlueprintFunctionLibrary. They should also contain only static methods. The code below is a snippet from the Analytics Blueprint Library, showing how to setup your library class.

As you can see in the example above, a Blueprint Function Library is indirectly a UObject derived and therefore requires the standard UCLASS() and GENERATED_UCLASS_BODY() macros. It decorates the functions that are to be callable from Blueprints with the UFUNCTION() macro. Functions in a Blueprint Function Library can be designated as BlueprintCallable or BlueprintPure depending on whether the calls have side effects or not.

See Engine/Plugins/Runtime/Analytics/AnalyticsBlueprintLibrary for the full source code.

Below is the implementation of the StartSession() function:

The implementation above interacts with a non-UObject derived singleton object. This is a good way to expose 3rd party library functions to Blueprints or to interact with C++ classes that don't have UObject support. The code below is an example of a Blueprint Function Library method that performs some common work to find the AIController for a controlled actor:

This function takes what would be multiple Blueprint nodes and rolls that into a single node. Of course, you could have made a function in Blueprints for this, but if it's called often the C++ version will yield better performance.

Terminology

Compilation Process

Blueprints, like regular C++ classes, need to be compiled before they can be used in-game. When you hit the Compile button in the Blueprint Editor, the process of converting the properties and graphs of a Blueprint asset into a class is performed.

Terminology

The class that does the work of compilation. A new instance is spawned for each compile. Stores reference to the class being compiled, the blueprint, etc.

Holds the information for compiling a single function, like a reference to the associated graph, properties, and generated UFunction.

A helper class that handles processing one class of node in the compiler (a singleton). Contains functions for registering pin connections, and generating compiled statements.

Unit of work in the compiler. The compiler translates nodes into a set of compiled statements, which the backend translates into bytecode operations.

A terminal in the graph (literal, const, or variable reference). Each data pin connection is associated with one of these! You can also make your own terms in a NodeHandlingFunctor for scratch variables, intermediate results, etc.

Compilation Process

The basic process of compiling a Blueprint is outlined below:

(Click item to view)

Clean the Class

Create Class Properties

Create Function List

Bind and Link the Class

Compile Functions*

Finish Compiling Class

Backend Emits Generated Code*

Copy Class Default Object Properties



Reinstance



*Full Compile Only

Clean the Class

Classes are compiled in place, which means the same UBlueprintGeneratedClass is cleaned and reused over and over, so that pointers to the class do not have to be fixed up. CleanAndSanitizeClass() moves properties and functions off the class and into a trash class in the transient package, and then clears any data on the class.

Create Class Properties

The compiler iterates over the Blueprint's NewVariables array, as well as some other places (construction scripts, etc.) to find all of the UProperties needed by the class and then creates UProperties on the UClass's scope in the function CreateClassVariablesFromBlueprint().

Create Function List

The compiler creates the function list for the class by processing the event graphs, processing the regular function graphs, and pre-compiling the functions, i.e. calling PrecompileFunction() for each context.

Processing of the event graphs is performed by the CreateAndProcessUberGraph() function. This copies all event graphs into one big graph, after which nodes are given a chance to expand. Then, a function stub is created for each Event node in the graph, and an FKismetFunctionContext is created for each event graph.

Processing of the regular function graphs is done by the ProcessOneFunctionGraph() function, which duplicates each graph to a temporary graph where nodes are given a chance to expand. A FKismetFunctionContext is created for each function graph as well.

Pre-compiling of the functions is handled by the PrecompileFunction() of each context. This function performs the following actions:

Schedules execution and calculates data dependencies.

Prunes any nodes that are unscheduled or not a data dependency.

Runs the node handler's RegisterNets() on each remaining node.

This creates the FKismetTerms for values within the function.

Creates the UFunction and associated properties.

Bind and Link the Class

Now that the compiler is aware of all of the UProperties and UFunctions for the class, it can bind and link the class, which involves filling out the property chain, the property size, function map, etc. At this point, it essentially has a class header - minus the final flags and metadata - as well as a Class Default Object (CDO).

Compile Functions

The next step consists of generating FKismetCompiledStatment objects for the remaining nodes which is accomplished through the node handler's Compile() function, using AppendStatementForNode(). This function can create FKismetTerm objects in the compile function as long as they are only used locally.

Finish Compiling Class

To finish compiling the class, compiler finalizes the class flags and propagates flags and metadata from the parent class before finally performing a few final checks to make sure everything went alright in the compile.

Backend Emits Generated Code

The backends convert the collection of statements from each function context into code. There are two backends in use:

FKismetCompilerVMBackend - Converts FKCS to UnrealScript VM bytecode which are then serialized into the function's script array.

FKismetCppBackend - Emits C++-like code for debugging purposes only.

Copy Class Default Object Properties

Using a special function, CopyPropertiesForUnrelatedObjects(), the compiler copies the values from the old CDO of the class into the new CDO. Properties are copied via tagged serialization, so as long as the names are consistent, they should properly be transferred. Components of the CDO are re-instanced and fixed up appropriately at this stage. The GeneratedClass CDO is authoritative.

Re-instance

Since the class may have changed size and properties may have been added or removed, the compiler needs to re-instance all objects with the class that were just compiled. This process uses a TObjectIterator to find all instances of the class, spawn a new one, and then uses the CopyPropertiesForUnrelatedObjects() function to copy from the old instance to the new one.

For details, see the FBlueprintCompileReinstancer class.

Exposing C++ to Blueprints

Making Classes Blueprintable

Readable and Writable Properties

Executable and Overridable Functions

As a programmer, working with Blueprints offers you many benefits by making your code extremely flexible. For example, a gameplay designer might want a new type of weapon implemented in the game. As the programmer, you code the weapon as you traditionally would except that you expose some important functionality, such as the fire rate and the Fire() function. After play testing, the designer decides that they need to change the fire rate of the gun to work on a curve. Rather than having to recode the fire rate of the gun and recompile the game, the designer can simply go into the Blueprint and change the fire rate directly, saving both the designer and the programmer time.

For more details about optimizing the C++/Blueprints distribution in your project, or tips to keep in mind when creating an API exposed to Blueprints, see the Exposing C++ to Blueprints.

Making Classes Blueprintable

In order to create Blueprints that extend from a class, that class must be defined as Blueprintable; which involves adding this keyword inside the UCLASS() macro preceding the class definition. This keyword makes the Blueprint system aware of the class so that it shows in the class list of the New Blueprint dialog and can be selected as the parent for the Blueprint being created.

The simplest form of declaration for a Blueprintable class is similar to the following:

Keyword

Description

Blueprintable

Exposes this class as an acceptable base class for creating Blueprints. The default is NotBlueprintable, unless inherited otherwise. This is inherited by subclasses.

BlueprintType

Exposes this class as a type that can be used for variables in Blueprints.

NotBlueprintable

Specifies that this class is NOT an acceptable base class for creating Blueprints. Negates the effect of a parent class having the Blueprintable keyword specified.

Readable and Writable Properties

In order to expose a variable defined in a C++ class to a Blueprint extending from that class, that variable must be defined using one of the keywords listed below inside the UPROPERTY() macro preceding the variable definition. These keywords make the Blueprint system aware of the variable so that it shows in the My Blueprint panel and its value can be set or accessed.

Keyword

Description

BlueprintReadOnly

This property can be read by blueprints, but not modified.

BlueprintReadWrite

This property can be read or written from a Blueprint.

Multicast Delegate Keywords

BlueprintAssignable

Property should be exposed for assigning in Blueprints.

BlueprintCallable

Property should be exposed for calling in Blueprint graphs.

Executable and Overridable Functions

In order to call a native function from a Blueprint, that function must be defined using one of the keywords listed below inside the UFUNCTION() macro preceding the function definition. These keywords make the Blueprint system aware of the function so that it shows in the context menu or Palette and can be added to a graph and executed - or, in the case of events, so that they can be overridden and executed.

The simplest form of declaration for a BlueprintCallable Function is similar to the following:

When creating your function's signature, note that making a parameter pass by reference will make it an output pin on the Blueprint node. To make a parameter pass by reference and still display as an input, use the UPARAM() macro.



You can also use UPARAM() to change the display name of a pin. For example, the MakeRotator function in KismetMathLibrary uses UPARAM() and the DisplayName keyword to change how the Roll, Pitch, and Yaw parameters appear in Blueprints.



Keyword

Description

Blueprint to Native Communication

BlueprintCallable

This is a native function that can be called from a Blueprint, which executes native code that changes something about the object it is being called on, or some other global state. This means it has to be "scheduled," or told explicitly the order in which it executes relative to other nodes. We do this by the white execution line. All Blueprint callable functions will be called in the order in which they appear along the white execution line.

BlueprintPure

This is a native function that can be called from a Blueprint, which executes native code that does not change anything about the object it is being called on, or any other global state. This means that nothing is changed by calling this node, it just takes input, and tells you an output. These are things like math nodes (+, - , *, etc), or variable getters, or anything that does not change anything permanently. These do not need to be scheduled, and do not have a connection for the white execution line. They are automatically figured out by the compiler, based on which BlueprintCallable nodes need the data produced by these nodes.

Native to Blueprint Communication

BlueprintImplementableEvent

This is the primary way we allow native functions to call up into Blueprints. They are like virtual functions that you implement in the Blueprint themselves. If there is no implementation, the function call is ignored. It is important to note that if a BlueprintImplementableEvent does not have a return value or an out parameter, it will appear as an event, available by Right-clicking and selecting it in the event graph of the Blueprint. If it does have a return value or any out parameters, it will be listed in the My Blueprints tab, and can then be overridden by Right-clicking and selecting implement function. Note that BlueprintImplementableEvents do not have a native implementation of the function.

BlueprintNativeEvent

These are the same as above, except there is a native default implementation of the function that is called if the Blueprint does not override the function. This is useful for things where you want some sort of default behavior if the Blueprint does not implement it, but want the Blueprint to be able to override the functionality if desired. These are more costly, so we only put them in where the functionality is needed. When you override the BlueprintNativeEvent, you can still call the native implementation, if desired, by Right-clicking on the event or function entry node, and selecting "Add call to parent".

Exposing Gameplay Elements to Blueprints

Speed

Complexity

There are two driving considerations when deciding to use C++ or Blueprints:

Speed

Complexity of expression

Beyond those two factors, a lot of it comes down to the complexity of the game, and the composition of the team. If you have many more artists than programmers, you'll probably have significantly more Blueprints than C++ code. In contrast, if you have a lot of programmers, they're probably keen to keep things in C++. We expect people to fall somewhere in the middle. At Epic, a lot of the workflow is that content creators will make a very complex Blueprint, and a programmer can see how they can compress a lot of that work into C++ by coding a new Blueprint node, so they move that chunk of functionality into a new C++ function. A good practice to follow would be to use Blueprints extensively, and then push things into C++ as they reach a complexity where that would enable a more concise expression of the functionality (or it becomes too complex for a non-programmer), or speed of execution dictates a move to C++.

Speed

For speed, the fact is that Blueprint execution is slower than C++ execution. That's not to say performance is bad, but if you're doing something that requires a lot of calculations, or operates at a high frequency, it might be better to use C++ instead of Blueprints. However, it is possible to combine the two in the way that works best for your team and your project's performance. If you have a Blueprint that has a lot of functionality, you can push some of that functionality into C++ to speed it up, but keep the rest in Blueprints to retain the flexibility.If your profiling shows that one operation is taking a lot of time in Blueprints, consider moving just that section into C++, while keeping the rest in Blueprints.

An example of a system that would take a lot of time to execute if done with Blueprint visual scripting is a crowd system that controls a thousand Actors In this case, it would be better for performance to handle decision making, pathing, and other crowd functionality in C++, and then maybe expose some tweaking parameters and controlling functions to Blueprints.

Complexity

For complexity of expression, there are just some things that are easier to do in C++ than in Blueprints. Blueprints do a lot of things well, but some things are just not very easy to express in nodes. Operating on large sets of data, doing string manipulation, complex math over large data sets, etc. are all very complex, and aren't easy to follow in a visual system. Those things are better kept in C++ than in Blueprints, just because they're easier to look at and figure out what's going on. Complexity of expression is another reason a crowd system would be better to implement in C++ code than in Blueprints.

Examples

Since there are different pieces of functionality that are best handled in C++ or in Blueprints, here are some examples of how C++ programmers and Blueprint authors can work together while creating a game.

The programmer could create a Character class in C++ that defines some custom events, and then Blueprints could be used to extend that Character class and actually assign meshes and set defaults. Check out the player character and the enemy bots in the ShooterGame sample project to see implementations like this.

A ability system where the base class is implemented in C++ but then designers can create Blueprints which actually do something. In the StrategyGame sample, there is a base turret defined in C++, but the behavior of the flamethrower, cannon, and arrow turrets is all defined in those Blueprints.

A pickup where the "Collect" or "Respawn" functions are Blueprint Implementable Events that can be overridden for designers to spawn different particle emitters and sound effects. Both ShooterGame and StrategyGame have examples of pickups created this way.

Creating a Blueprint API : Tips and Tricks

Here are some points to consider as a programmer creating a Blueprint-exposed API:

Optional parameters are handled well in Blueprints:

Favor functions with lots of return parameters over functions that return structs. Here's a snippet showing how to create multiple output pins on your node:

Adding new parameters to an existing function is fine, but if you need to remove or change them, you should deprecate the original and add a new function. Make sure to use the deprecation metadata so the information about the new function will show up in Blueprints:

If a function needs to take an enum, consider using the 'expand enum as execs' metadata, as this can make the node easier to use.

Many operations that take time to complete (e.g. move here) should be latent functions.

Consider putting functions in a shared library if possible. This makes them easy to use across multiple classes, and avoids a 'target' pin.

Remember to mark nodes as pure if possible, as this will avoid needing an execution pin on a node that requires wiring.

Marking a function as const will also cause the Blueprint node to not have execution pins:

Class Setup

A Blueprints Class allows you to set up new classes using the Blueprints Visual Scripting system. After you create a new Blueprint Class, you can add components, set up functions and other gameplay or design behavior with visual scripting, and set default values for class variables. The LightSwitch class set up using only Blueprints is named LightSwitch_BPOnly, and is explained below.

Class Setup

The LightSwitch_BPOnly class was created in the Content Browser, and Actor was selected as the parent class.

Components are added to the Blueprint either statically in the Blueprint Editor's Components tab, or dynamically through visual scripting in the Graph Editor. Because the LightSwitch class will always have the PointLightComponent and the SphereComponent, in this case the components have been added statically in Components tab.

The Components tab was used to add the PointLightComponent, named PointLight1, as the root component, and the SphereComponent, named Sphere1, attached to the PointLightComponent. Components added to the class in the Blueprint Editor have light blue icons, while components inherited from the parent class have dark blue icons.



In the Blueprint Editor, you can add new variables, functions, and macros in the Blueprint Editor My Blueprint Panel tab. You also have access to all the graphs contained within the Blueprint Class. In graphs, nodes are wired together to create design-time and gameplay functionality that can be driven by class variables, gameplay events, and even an Actor's surroundings.

The float variable DesiredIntensity was added to the LightSwitch_BPOnly class using the My Blueprint tab. The My Blueprint tab also displays the components added in Components Window, so they can be accessed in graphs if desired.



There are two graphs used to set up the LightSwitch_BPOnly class behavior. The first is the Construction Script function graph, which contains the Construction Script function entry node. This event executes when an Actor is added to the level, or when an existing Actor is moved within the level. In the LightSwitch_BPOnly class, the Construction Script event is connected to a Set Intensity node, so that the intensity of Point Light 1 (the PointLightComponent) is set to the value of DesiredIntensity when the Actor is added to or moved within the level.



The other graph set up in the LightSwitch_BPOnly class is the EventGraph. Execution in the EventGraph begins from events, such as the OnComponentBeginOverlap and OnComponentEndOverlap events. These events execute when some other Actor within the level overlaps or leaves the SphereComponent. Both events are connected to the Toggle Visibility node, so the visibility of the PointLightComponent is toggled when those events execute. For more on events and working with graphs, see the Events, EventGraph, and Graph Editor documentation.



If you cannot find the Toggle Visibility from Right-click menu un-check context sensitive or try searching for it in the Find a Node Menu. You can also get the same results by simply dragging out a line from the Point light variable node and then searching for Toggle Visibility.

If you cannot find the OnComponentEndOverlap for Sphere1 make sure that you have the Sphere variable selected and then use the add event from the Event->Add Event or from the Right-click menu Add Event->Collision->View OnComponentBeginOverlap / OnComponentEndOverlap.

The DesiredIntensity variable is set to Editable in the variable's settings, so it is visible in the Blueprint Editor's Class Defaults and can be edited. This also means that the variable can be changed for each instance of the class, so each Actor can have its own DesiredIntensity.



Blueprinted classes can be extended with other Blueprint Classes, either using the dropdown button next to the class in the Class Viewer to create a new Blueprint, or by Right-clicking on the Blueprint and selecting Create New Blueprint Based on This.

The Blueprint Class LightSwitch_BPOnly is in the Content Browser, and can be dragged into the level from there. It is also in the Class Viewer. For more information on placing Actors in a level using the Content Browser or Class Viewer, see the Placing Actors documentation.

Class Setup

C++ classes can be extended with Blueprints, allowing programmers to set up new gameplay classes in code that can be built upon and changed with Blueprints by level designers. There are a number of specifiers that change how a C++ class interacts with the Blueprint system, and some of them will be highlighted in this example.

Class Setup

For the first section of the class setup, a class called LightSwitchBoth is created using the C++ Class Wizard.

Most of the code setup in the LightSwitchBoth class is similar to the code in the C++ Only LightSwitch example. While you could extend the LightSwitchCodeOnly class with a Blueprint, the components, variables, and functions created in that class would not be accessible to Blueprint graphs. This example will go over the UPROPERTY() and UFUNCTION() specifiers that make LightSwitchBoth work as a template for the Blueprint that will derive from it.

You may find it helpful to first refer to the C++ Only LightSwitch example, to see how the header file and source file are set up to create the LightSwitchComponent, SphereComponent, DesiredIntensity variable, and OnOverlap function.

This header file is adapted from the C++ Only LightSwitch example to add the following functionality:

The PointLightComponent and the SphereComponent are BlueprintReadOnly, and will show up in the category Switch Components in the My Blueprint tab.

OnOverlapBegin and OnOverlapEnd are now BlueprintNativeEvents, and will show up in the category Switch Functions in the My Blueprint tab.

DesiredIntensity is BlueprintReadWrite, and will show up in the category Switch Variables in the My Blueprint tab.

DesiredIntensity is now EditAnywhere instead of VisibleAnywhere.

There is a Blueprintable specifier for the UCLASS() macro. It is not necessary in this case because LightSwitchBoth inherits directly from Actor, which is Blueprintable, and the Blueprintable specifier is inherited.

With the additional specifiers in the UPROPERTY() and UFUNCTION() macros, the header file for the LightSwitchBoth class looks like:

LightSwitchBoth.h

In the source file for LightSwitchBoth, the constructor remains the same. However, a change needs to be made to the OnOverlapBegin and OnOverlapEnd functions. These functions are now a BlueprintNativeEvent. This means that in a Blueprint derived from this class, events can be placed that override OnOverlapBegin and OnOverlapEnd, and are executed when the function would normally be called.

If one of those events does not exist, the C++ implementation of the function executes instead. To make this setup work, the C++ functions need to be renamed OnOverlapBegin_Implementation and OnOverlapEnd_Implementation, respectively. The Blueprint setup will be covered later in this example.

With the change to the OnOverlapBegin and OnOverlapEnd definitions, the source file for LightSwitchBoth looks like:

LightSwitchBoth.cpp

If this is the first code class you have added to a blank project, you need to close Unreal Editor, compile the project in Visual Studio or Xcode, and then open Unreal Editor and re-open the project to ensure that the game module is created and loaded properly. Also, it is important to make sure that the Build Configuration matches the version of the Unreal Editor executable you are using to open the project. Read more about build configurations and compiling projects in the Compiling Game Projects documentation.

If you are adding code to an existing C++ project, you can use the Hot Reload functionality to compile the new code within Unreal Editor.

After compiling this new class, it is possible to create a new Blueprint Class. In this case, LightSwitchBoth is chosen as the parent class for the Blueprint, which will be named LightSwitchBoth_BP.



The PointLightComponent and SphereComponent added in C++ also show in the Components tab in the Blueprint Editor. Their icons are dark blue to indicate that they are native components, inherited from the parent LightSwitchBoth class. Any new components added just to the LightSwitchBoth_BP Blueprint would have light blue icons instead. To learn more about adding and arranging components using the Components tab, refer to the Components tab documentation.



The Blueprint Editor's Graph panel is the core of Blueprint editing. In the Graph panel, you can add new variables, functions, and macros in the Blueprint Editor My Blueprint Panel tab. You also have access to all the graphs contained within the Blueprint Class. In graphs, nodes are wired together to create design-time and gameplay functionality that can be driven by class variables, gameplay events,and even an Actor's surroundings.

The My Blueprint tab in the Graph panel displays the PointLightComponent and the SphereComponent added in C++ to the LightSwitchBoth class. This is because of the BlueprintReadOnly specifier. Nodes for these components can be added to a graph by clicking and dragging from their names in the My Blueprint tab into the graph. These nodes can then be connected to nodes that change variables like visibility or light color. The DesiredIntensity variable also appears in the My Blueprint tab. Because it is a variable and not a component, the BlueprintReadWrite specifier can be used. This means it is possible to create nodes to both get and set the value of DesiredIntensity in a Blueprint graph. Refer to the Blueprint Editor My Blueprint Panel documentation for general usage information.

The components and variables from the parent LightSwitchBoth class might not display by default. The Show inherited variables checkbox at the bottom of the My Blueprint tab shows variables inherited from the parent class when checked.

Showing All Variables

Showing Only User-Created Variables









There are two graphs used to set up the LightSwitchBoth_BP class behavior. The first is the Construction Script graph, which contains a specialized Construction Script event. Without the Construction Script setup, a new LightSwitchBoth_BP Actor would just use the LightSwitchBoth constructor. However, the Construction Script executes when the Actor is moved within the level, as well as when DesiredIntensity is changed. Using the Construction Script means that Actor variables exposed to Blueprints can be changed easily and the effects of these changes can be seen quickly.

In the LightSwitchBoth_BP class, the Construction Script event is connected to a Set Intensity node, so that the brightness of Point Light 1 (the PointLightComponent) is set to the value of DesiredIntensity when the Actor is added to or moved within the level or DesiredIntensity changes.



The other graph set up in the LightSwitch_BPOnly class is the EventGraph. Execution in the EventGraph begins from events. In this case, the OnOverlap event executes whenever the C++ function OnOverlap would be called. In the LightSwitchBoth source file, delegates were setup so OnOverlap will execute when an Actor enters or leaves the SphereComponent:

The OnOverlap event node is connected to a Set Light Color node. Whenever the event executes, it will cause the light color of the PointLightComponent to be set to a random color. This overrides the OnOverlap_Implementation function in the source file, which toggles the visibility of the PointLightComponent.

For more on events and working with graphs, refer to the Events, EventGraph, and Blueprint Class UI documentation.



The DesiredIntensity variable is set to EditAnywhere in the LightSwitchBoth header file, so it is visible in the Blueprint Editor's Defaults and can be edited by clicking the Class Defaults button to show the Class Defaults in the Details Panel. This also means that the variable can be changed for each instance of the class, so each Actor can have its own DesiredIntensity. Because DesiredIntensity is also BlueprintReadWrite and used in the Construction Script, updating it also causes the Construction Script to execute again.



Blueprinted classes can be extended with other Blueprint Classes, either using the dropdown button next to the class in the Class Viewer to create a new Blueprint, or by Right-clicking on the Blueprint and selecting Create New Blueprint Based on This.

The Blueprint Class LightSwitchBoth_BP is in the Content Browser, and can be dragged into the level from there. It is also in the Class Viewer. For more information on placing Actors in a level using the Content Browser or Class Viewer, refer to the Placing Actors documentation.

Class Setup

Using the C++ Class Wizard, you can easily add new C++ classes to your project. After you choose the class you would like your new class to derive from, the wizard sets up the necessary header file and source file. If this is the first code you have added to the project, the project is converted to a code project, which creates the game module that contains your source code. It also lets Unreal Editor know that the game module exists, so it can load your C++ changes from Visual Studio or Xcode, and minor code changes can be compiled within Unreal Editor.

The LightSwitch class set up using only C++ is named LightSwitchCodeOnly, and is explained below.

Class Setup

The LightSwitchCodeOnly class was created by using the C++ Class Wizard, and selecting Actor as the parent class.

The header file, LightSwitchCodeOnly.h, contains the class declaration.

Class declarations created with the C++ Class Wizard are automatically preceded by the UCLASS() macro. The UCLASS() macro makes the engine aware of the class, and can also be used with keyword specifiers to set the class's behavior within the engine.

The class declaration contains any variable and/or function declarations. These can be preceded with UPROPERTY() and UFUNCTION() macros, respectively, which serve similar functions to the UCLASS() macro. Components are set up with UPROPERTY() macros as well.

In LightSwitchCodeOnly.h, C++ is used to:

Declare the PointLightComponent and the SphereComponent. The PointLightComponent and the SphereComponent are made VisibleAnywhere. This means that their properties will be visible in the Details tab of a LightSwitchCodeOnly Actor.

Declare your constructor, so you can set default values for your components and variables:

Declare OnOverlapBegin and OnOverlapEnd, the functions that will be called when another Actor enters or leaves the SphereComponent. Note that these have different signatures.

Declare ToggleLight, a function that toggles the visibility of the PointLightComponent.

Declare the DesiredIntensity variable and make it visible anywhere with the VisibleAnywhere specifier. It will show up in the category Switch Variables in the Details tab of a LightSwitchCodeOnly Actor. For variables that are not subobjects, like this float value, the VisibleAnywhere specifier just makes the variable show in the Details tab. There is an EditAnywhere specifier that can be used as well, but because the DesiredIntensity variable is only used right as the Actor is added to the level, the variable does not need to be editable.

The resulting header file looks like:

LightSwitchCodeOnly.h

The C++ Class Wizard also creates the source file for the class, in this case LightSwitchCodeOnly.cpp. By default, the source file has basic includes set up.

You will begin by adding the class constructor.

In the LightSwitchCodeOnly constructor, C++ is used to:

Set the DesiredIntensity variable's value to 3000.

Create the PointLightComponent, set its variables (including setting its intensity to the value of DesiredIntensity), and make it the root component.

Create the SphereComponent, set its variables, and attach it to the PointLightComponent.

Designate the OnOverlap function as a delegate called when an Actor overlaps or leaves the SphereComponent.

The source file is also where you can define any functions you declared for your class. For instance, LightSwitchCodeOnly.cpp has implementations of OnOverlapBegin and OnOverlapEnd, which toggle the visibility of the PointLightComponent by calling ToggleLight. Combined with the class constructor, the source file looks like:

LightSwitchCodeOnly.cpp

BasicClasses.h is referring to the name of the project that the class has been set up in.

If this is the first code class you have added to a blank project, you will need to close Unreal Editor, compile the project in Visual Studio or Xcode, and then open Unreal Editor and re-open the project to ensure that the game module is created and loaded properly. Also, it is important to make sure that the Build Configuration matches the version of the Unreal Editor executable you are using to open the project. Read more about build configurations and compiling projects in the Compiling Game Projects documentation.

If you are adding code to an existing C++ project, you can use the Hot Reload functionality to compile the new code within Unreal Editor.

C++ classes can be extended with C++ classes as well as with Blueprint Classes - they show up after checking the Show All Classes checkbox in the C++ Class Wizard and in the Custom Classes section of the Pick Parent Class window during Blueprint Class creation.

The LightSwitchCodeOnly class is in the Class Viewer, and can be dragged into the level from there. For more information on placing Actors in a level using the Class Viewer, see the Placing Actors documentation.

What is a Console Variable?

Creating / Registering a Console Variable

Getting the State of a Console Variable

How to Track Console Variable Changes

Intended Console Variable Behavior and Style

Loading Console Variables

Command line

Priority

Unregistering Console Variables

A Console Command is a string sent to the engine, often typed in by the user at the in-game console, that the engine recognizes and can react to in some way (for example, a console / log response, a changing internal state, and so on). A Console Variable can be used to store state information that can be viewed or changed through the console. The in-game console also supports auto-completion and enumeration for Console Commands and Console Variables that have been registered with the Console Manager (console command Help or DumpConsoleVariables). Because of this, you should avoid the old Exec interface. The Console Manager is the central point to control all those things and more (for example, user input history).

What is a Console Variable?

A Console Variable is a variable of a simple data type (for example, float, int32, FString) that has an engine-wide state. The user can read and write to the state. The Console Variable is identified by a unique name, and the in-game console will assist the user with auto-completion while typing into the console. Some examples:

User console input

Console output

Description

MyConsoleVar

MyConsoleVar = 0

The current state of the variable is printed into the console.

MyConsoleVar 123

MyConsoleVar = 123 LastSetBy: Constructor

The state of the variable is changed and the new state printed into the console.

MyConsoleVar ?

Possibly multi line help text.

Print the console variable help text into the console.

Creating / Registering a Console Variable

All Console Variables are registered when the engine is created. The following example has been taken from engine code:

Here we register a Console Variable of the type int32, with the name r.RefractionQuality, the default value of 2 and some multi-line help text and flags. The help text is shown when the user types "?" after the Console Variable's name. The names and descriptions of flags available (from the EConsoleVariableFlags enumerated type) can be found on the EConsoleVariableFlags API Reference page..

There are other entries in the EConsoleVariableFlags enumerated type, but all other flags are intended for internal use only.

If needed, you also can generate a console variable inside a function:

IConsoleManager::Get() is the global access point. There you can register a Console Variable or find an existing one. The first parameter is the name of the Console Variable. The second parameter is the default value, and depending on the type of this constant, a different Console Variable type is created: int, float, or string (!FString). The next parameter defines the Console Variable help text.

It is also possible to register a reference to an existing variable. This is convenient and fast but bypasses multiple features (for example, thread safety, callback, sink, cheat) so we suggest to avoiding this method. Here is an example:

Here they type is deducted from the variable type.

Getting the State of a Console Variable

Getting the state of a Console Variables created with RegisterConsoleVariableRef can be done efficiently by using the variable that it was registered with. For example:

Using Getter functions (that is,!GetInt(), !GetFloat(), !GetString()) to determine a Console Variable's state results in a slightly slower implementation (virtual function call, possibly cache miss, and so on). For best performance you should use same type the variable was registered with. To get the pointer to the variable, you can either store the return argument of the register function or call FindConsoleVariable just before you need the variable. For example:

The static there ensures the name search (implemented as map) is only done the first time this code is called. This is correct as the variable will never move and only gets destructed on engine shutdown.

How to Track Console Variable Changes

If you want to execute some custom code if a Console Variable changes, you have 3 methods you can choose from.

Often the simplest method is the best: You can store the old state in your subsystem and check each frame if they differ. Here you control when this happens very freely; for example, on the render thread, game thread, or streaming thread, before / after tick or rendering. When you detect the difference, you copy the console variable state and do your custom code. For example:

You also can register a console variable sink. For example:

The sink is called at a specific point on the main thread before rendering. The function does not get the console variable name/pointer as this often would lead to the wrong behavior. If multiple console variables (for example, r.SceneColorFormat, r.GBufferFormat) should all trigger the change, it is best to call the code after all have been changed, not one after another.

The last method, using the callback, you should avoid as it can cause problems if not used carefully:

A cycle can cause a deadlock (we could prevent the deadlock but which callback to favour is not clear).

The callback can come back at any point in time whenever !Set() is getting called. You code has to work in all cases (during init, during serialization). You can assume it is always on the main thread side.

We do not recommend using this method unless you cannot solve it with the other methods mentioned.

For example:

Intended Console Variable Behavior and Style

Console variable should reflect the user input, not necessarily the state of the system (e.g. !MotionBlur 0/1, some platforms might not support it). The variable state should not be changed by code. Otherwise the user might wonder if they mistyped because the variable does not have the state they specified or they might not be able to change a console variable because of the state of some other variable.

Always provide a good help explaining what the variable is used for and what values make sense to specify.

Most console variables are intended for development only so specifying the ECVF_Cheat flag early would be a good idea. Even better might be to compile out the feature using defines (for example, #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)).

The variable name should be as minimal as possible while being descriptive, negating meaning should be avoided (for example, bad names would be !EnableMotionBlur, !MotionBlurDisable, MBlur, !HideMotionBlur). Use upper and lower case to make the name easier to read and consistent (for example, !MotionBlur).

For indentation, you can assume fixed width font (non proportional) output.

It is important to register the variable during engine initialization so that auto completion and !DumpConsoleCommands and !Help can work.

Please read IConsoleManager.h for find more details on this.

Loading Console Variables

On engine startup, the state of Console Variables can be loaded from the file Engine/Config/ConsoleVariables.ini. This place is reserved for the local developer - it should not be used for project settings. More details can be found in the file itself:

You also can put the settings in Engine/Config/BasEngine.ini, for example:

Setting can also come from Script/Engine.RendererSettings. These project settings are exposed like this:

Those settings can be changed in the editor UI. Project settings should not intermix with scalability settings (to prevent priority issues).

Other settings can come from the Scalability feature. Look at Config/BaseScalability.ini or the Scalability documentation for more info.

Command line

The command line allows to set console variables, call console commands or exec commands. For example:

Here we execute 3 commands. Note that setting a console variable this way requires you to omit the '=' you would need in an ini file.

Priority

Console variables can be overridden from various sources, for example user / editor / project settings, command line, consolevariables.ini, and so on. To be able to reapply some settings (for example, project settings can be changed in the editor UI) while keeping the specified overrides (for example, from the command line), we introduced a priority. Now all settings can be applied in any order.

see IConsoleManager.h:

In some cases, you might see this log printout:

It might be intended (for example, the command line forces a user setting) or caused by some code issue. The priority is also helpful to see who set the variable the last time. You can get this information when getting the console variable state. e.g.

Unregistering Console Variables

The UnregisterConsoleVariable method allows you to remove the Console Variable. At least, this is what is happening from the user's perspective. The variable is still kept (with the unregistered flags) to not crash when pointers access the data. If a new variable is registered with the same name, the old variable is restored and flags get copied from the new variable. This way DLL loading and unloading can work even without losing the variable state. This will not work for console variable references.

Creating Gameplay Tags

Manually Adding Tags

Editing .ini Files Directly

Data Table Assets

Managing Gameplay Tags

Gameplay Tag Editing Restriction

Gameplay Tag Test Operations

Gameplay Tag Queries

Using Gameplay Tags In Your Game

Quickly Accessing Gameplay Tags in C++

Gameplay Tags are conceptual, hierarchical labels with user-defined names. These tags can have any number of hierarchical levels, separated by the "." character; for example, a Gameplay Tag with three levels would take the form of "Family.Genus.Species", with "Family" being the broadest identifier in the hierarchy, and "Species" being the most specific. Note that the existence of "Family.Genus.Species" implicitly means that "Family.Genus" and "Family" Gameplay Tags also exist. Individual tags are lightweight and use the type FGameplayTag. Since game objects frequently have multiple tags, Gameplay Tag Containers (using the type FGameplayTagContainer) are provided and can handle a variety of additional queries. Gameplay Tags (or Gameplay Tag Containers) can be added to any project, associating objects with conceptual labels that can then be used to identify, match, categorize, or filter them (as needed) for your project.

Creating Gameplay Tags

Gameplay Tags must be added to the central tag dictionary for the engine to be aware of them. This can be done in three ways via editor functionality. You can create (or delete) Tags in three ways:

By manually adding or removing them in the Project Settings menu.

By creating and editing .ini files in the "GameplayTags" folder.

By building Data Table Assets.

All three methods are set up under Project Settings, by opening the Gameplay Tags tab under the Project section.



Manually Adding Tags

The easiest way to add Gameplay Tags is to enter them manually in the Project Settings menu. By checking the Import Tags From Config option, Config/DefaultGameplayTags.ini will be loaded, as well as all Gameplay Tags in any .ini files found under the Config/Tags path. An option labeled Add New Gameplay Tag will appear, and this option can be used to add new Gameplay Tags to any existing Gameplay Tag .ini files, including the default file. Tags added in this way will also have an optional field for entering a brief description, which will appear as a tooltip in the editor.



Editing .ini Files Directly

To add tags using your own .ini files, the Import Tags From Config option must be enabled. Gameplay Tags will then be loaded from each of the .ini files found your project's Config/Tags/ path, which are easy to hand-edit. If these edits are made while the editor is running, turning the Import Tags From Config option off and back on will reload the files. The format within these files looks like this:

This method is convenient for your teammates to add their own tags, since .ini files in Config/Tags are easily-edited text files that can be named with any file-naming convention you like.

A "Developer Tag" config file can be used by going to the Gameplay Tags Developer menu within Project Settings, and filling in the Developer Config Name with your desired filename. If enabled, this will save all of the tags that were added to the default .ini file (by you), into an .ini file that you specify. Your .ini file will reside in the Config/Tags folder and can be passed to other developers or submitted to your source control system without further modification. This can be useful on large projects with thousands of tags, or as a way to separate tags created by specific developers or for use with specific game features. This is entirely optional, but it can be helpful for some teams and workflows to have certain tags stored in separate files.

Data Table Assets

Finally, tags can be added via DataTable assets with the row type GameplayTagTableRow. This is especially useful for importing Gameplay Tags from an external source, such as an Excel spreadsheet file, but you can create your own without a file to import and work with it in-editor. Once your asset is created, add it to the GameplayTagTableList in the Project Settings menu and all tags contained within it will be added to the Gameplay Tag Manager. Note that this system supports multiple assets being listed, so you can separate out your project's tags into different spreadsheets (if this helps your workflow or organization).



Data Table Assets use Unreal Engine assets rather than .ini files, and can be viewed and changed while the editor is running, similar to other game assets.

Managing Gameplay Tags

After your Gameplay Tags have been added, you can manage them by searching for references to them, deleting them, or renaming them. All of these actions can be accessed with the caret dropdown next to a tag in the Project Settings menu. Tags can only be deleted in this menu if they were added via a .ini file (either hand-edited or added via the Project Settings menu), and are not referenced by anything else. Renamed tags will cause additions to be made to the GameplayTagRedirects list, and any renamed tags will be silently fixed on load.



Gameplay Tags can be edited in Project Settings via a caret dropdown.

Gameplay Tag Editing Restriction

The Gameplay Tag Editor supports the ability to restrict editing of gameplay Tags at any level in the hierarchy, based on a list of authoritative users. To use Gameplay Tag Editing Restriction, open Project Settings and, under the GameplayTags section, expand the Advanced Gameplay Tags hierarchy. To restrict editing on a set of Gameplay Tags, you must first specify an .ini file in which to store the Tags other than "DefaultGameplayTags.ini". The owners of the restricted Tags should also be specified, so that users will know who to contact if they wish to make edits. Finally, the Gameplay Tags themselves can be added to the Restricted Tag List, where they will be marked with a checkbox indicating whether or not unlisted users are permitted to add children to them. If a user (other than the listed owners) attempts to edit the Restricted Tag List, a warning will pop up, asking the user to confirm that they have permission from the owners. If the user does not choose "Yes", the edit will not be made.



The interface for adding restricted Gameplay Tags. The checkboxes indicate the places where users may add child Tags.

Users (other than those listed as owners) will receive a warning when attempting to modify the Restricted Tag List.



The warning/confirmation window that appears when a user who doesn't own a Restricted Tag List tries to make edits to it.

Once your Restricted Tag List is set up, the normal Gameplay Tag List will contain your restricted Gameplay Tags. However, restricted Tags will not feature the "rename" or "delete" options in the caret dropdown, and the "+" button will only appear next to Tags where you checked the box in the Restricted Tag List.



The standard Gameplay Tag List drops the "+" button for restricted Tags that the current user doesn't own.



Any Tags created in the Restricted Tag List will feature only the search option in their caret menus; "Rename" and "Delete" options are not available.

Currently, restricted Tags cannot be deleted in the Editor once they are created, even in the Restricted Tag List. They can, however, be deleted from .ini files. The following is the "RestrictedTags.ini" file that corresponds to the restricted Tags used in this example. Deleting a Tag from this file is as simple as removing the line with the appropriate "Tag" entry.

Gameplay Tag Test Operations

There are a number of test operations, all based on the concept of matching tags to other tags, that can be performed on Gameplay Tags and Gameplay Tag Containers. Each of these functions will be called on a Gameplay Tag or Gameplay Tag Container and will take a single Gameplay Tag or Gameplay Tag Container as a parameter.

The following table details the operations available for tags and tag containers. In this table, the format "A.1" represents a single Gameplay Tag, while "{A.1}" represents that same tag as part of a Gameplay Tag Container. A container with multiple tags will be of the format "{A.1, B.1}".

Source

Function/Operation

Input Parameter

Return Value

A.1

MatchesTag

A

true

A.1

MatchesTagExact (or ==)

A

false

A.1

MatchesAny

{A, C}

true

A.1

MatchesAnyExact

{A, C}

false

A.1

MatchesAll

{A}

true

A.1

MatchesAllExact

{A}

false

{A.1, B.1}

HasTag

A

true

{A.1, B.1}

HasTagExact

A

false

{A.1, B.1}

HasAny

{A, C}

true

{A.1, B.1}

HasAnyExact

{A, C}

false

{A.1, B.1}

HasAll

{A, B}

true

{A.1, B.1}

HasAllExact

{A, B}

false

Note that providing empty or default Gameplay Tag Containers as the input parameter will cause all operations to return false, except for HasAll, HasAllExact, MatchesAll, and MatchesAllExact. The justification for this is that there are no tags in the parameter container that are missing from the source set.

As an example, the following Blueprint will use some of the above-named operations to detect whether a Gameplay Tag Container has TestTag.One or TestTag.Three, but not both tags, and not TestTag.Two (when the test Actor is spawned into a game). For this test, we will use literal container values in our Blueprint for our test, but use a Blueprint (or C++) variable for our Actor's container.

TagOperationsInBP.png



Click image for full size.

Gameplay Tag Queries

Gameplay Tag Query variables in encapsulate certain types of tests that can be performed on Gameplay Tag Containers. You can use them to make your tests data-driven, perform the same test in many places without having to edit more than one variable or piece of code, and speed tests up by having native code perform most of the work. Gameplay Tag Queries can perform any of the following three types of tests:

Any Tags Match succeeds if at least one tag from the query is found in the container.

All Tags Match succeeds if there are no tags in the query that are not also found in the container. This includes the case that no tags are present in the query.

No Tags Match succeeds if there are no tags in the query that are also found in the container. This includes the case that no tags are present in the query.

However, those tests can be combined together via three larger expressions, each of which contains an array of additional expressions or tests:

Any Expressions Match succeeds when any of its sub-expressions or tests succeeds.

All Expressions Match succeeds when none of its sub-expressions or tests fail. This includes the case that no sub-expressions or tests are present in the query.

No Expressions Match succeeds when none of its sub-expressions or tests succeed. This includes the case that no sub-expressions or tests are present in the query.

Note that all three test types refer to "exact" matching as per the table of operations above.

We can recreate our earlier test example where we required either TestTag.One or TestTag.Three (but not both) to be in the source container, having required that TestTag.Two not be, using a single Gameplay Tag Query. For this test, we will use Blueprint (or C++) variables exclusively, although literal values are also supported. Here is our test query variable:



With this query set up, we can evaluate our Gameplay Tag Container against it in our test Actor's Blueprint as follows:



Click image for full size.

Using Gameplay Tags In Your Game

To apply the tags you have created to objects in your game, add Gameplay Tags (C++ type FGameplayTag) or Gameplay Tag Containers (C++ type FGameplayTagContainer) properties to the objects. You can also add Gameplay Tag Queries (C++ type FGameplayTagQuery) to your objects as desired, or you can use the tag operations directly in Blueprints or C++ code. Once these properties have been added, you can edit them from the code or editor, like any other variable.

Quickly Accessing Gameplay Tags in C++

The IGameplayTagAssetInterface can be implemented in C++. Doing so, and overriding the GetOwnedGameplayTags function, will create a Blueprint-accessible way to populate a Gameplay Tag Container with the tags associated with that object. In most cases, this just means copying the tags from the base class into a new container, but your implementation of the class could gather tags from multiple containers, or call a Blueprint function to get access to Blueprint-declared tags, or whatever your object requires. The advantage of this interface is that it enables you to interact with a variety of disparate object types in a standardized way, so that you can get an object's tags without explicitly casting the object and then writing custom code for each possible type to get the correct tag variable (or variables). This is especially useful on larger projects, where it can help to avoid (hard-to-reproduce) bugs and make code cleaner, faster, and easier to maintain.

Overview

Interfaces

The Online Services plugin and its interfaces provide a common way to access the functionality of various online services. The design of the Online Services plugin ensures that the only changes developers need to make when working on a game that ships on multiple platforms, or supports multiple online services, are configuration adjustments for each supported service.

Overview



Learn about the Online Services Interfaces and how to configure them for use in Unreal Engine.

Interfaces



Read and update player achievements.



Authenticate and verify a local user with online services.



Purchase and redeem game content outside of gameplay.



Determine whether your game is connected to your platform's online services.



Display and update leaderboards from within your game.



Create and manage online lobbies.



Access the presence and joinability status of friends and followers.



Access player privileges including online and crossplay as well as voice and text chat.



Create and manage online game sessions.



Manage relationships with friends and blocked users.



Upload stats and data to online services and complete stats queries.

Online Subsystem

Design Philosophy

Interfaces

Functions

Using Online Services or Online Subsystem

Configuration

Use an Interface

The Online Services plugin and its interfaces provide a common way to access the functionality of various online services such as Playstation Network, Xbox Live, Epic, Steam, and so on. The design of the Online Services plugin ensures that the only changes developers need to make when working on a game that ships on multiple platforms, or supports multiple online services, are configuration adjustments for each supported service.

Design Philosophy

The Online Services plugin is organized into modular, service-specific Interfaces that group supported features. For a list of interfaces and the feature groups each supports, refer to the Interfaces table on this page.

The Online Services plugin is designed to handle asynchronous communication with a variety of services. Interactions with these systems take an unpredictable amount of time due to fluctuating network connection speeds, server delays, and unknown backend services times. To overcome these problems, the Online Services Interfaces return a TOnlineAsyncOpHandle for all remote operations that guarantees the OnComplete event callback to the handle will be called.

Interfaces are provided for every feature group, on each online service that supports them. Specific functions that a particular online service does not support will return Errors::NotImplemented from the OnComplete callback. This functionality ensures that developers can use the same code for all online services.

Event Callback and Listening

The OnComplete callback provides the following functionalities:

It responds to requests as they finish.

It can query in-flight requests.

It uses a single code path.

This last point is important as it removes the need for developers to write custom code to catch different success or failure conditions.

Depending on the way developers pass in the parameters for the OnComplete callback (the event callback of Online Services) or event listening, the appropriate delegate is constructed automatically. Different delegate-creation functions will be called depending on the type of this in the following example using the QueryStats function from the Stats Interface:

Or in this example using OnStatsUpdated:

In either of these examples, we have the following behavior:

If this is a UObject, the underlying delegate's CreateUObject is called.

If this derives from TSharedFromThis, CreateThreadSafeSP or CreateSP (if it is a non-thread safe shared pointer) is called.

In any other case, CreateRaw is called.

In general, the safest delegate-creation function call will be used.

Interfaces

The following interfaces are included in the Online Services plugin.

Interface

Feature group description

Achievements

List all achievements in a game, unlock achievements, and check your own unlocked achievements, as well as those of other users.

Auth

Authenticate and verify a local user with the online services.

Commerce

Retrieve the categories and specific offers available for in-game purchase.

Connectivity

Get or get notified of the connection status of online services.

ExternalUI

Open the built-in user interfaces for specific hardware platforms or online services. In some cases, services grant access to certain core features exclusively through this interface.

Leaderboard

Access online leaderboards, including registering your own scores and checking leaderboards for scores from your friends list or other players from around the world.

Lobbies

Create and join lobbies to play with friends.

Presence

Set the way that a user's online status and joinability will appear to other users. Status' include "Online", "Offline", "Away", and so on.

Privileges

Query the privileges of a user such as age restrictions, communication restrictions, crossplay settings, and so on.

Session

Create, destroy, and manage online game sessions, including searching for sessions and matchmaking systems.

Social

Add users to your friends list, block users, unblock users, and list players you have recently met online.

Stats

Upload stats to the backend to complete corresponding features such as stats queries, achievements progress, leaderboards standings, and so on.

Title File

Enable titles to read files that are not packaged with the shipping title, but are uploaded to the backend services and downloaded to the current title at runtime.

User File

Interface with user file storage.

User Info

Collect metadata about a user.

Functions

Each interface contains a variety of synchronous and asynchronous functions. We now give a brief overview on how to pass parameters to a function and process the result when a function returns.

Parameters

Parameters for Online Services Interface functions are created using the Params member of each function's associated struct. These parameters are then passed to the relevant function with MoveTemp, UE's equivalent of std::move, or through a {}-delimited list.

Return Types

Functions defined in the Online Services interfaces have three different return types:

TOnlineResult

TOnlineAsyncOpHandle

TOnlineEvent

Synchronous functions return a TOnlineResult<T> where T is the struct associated with the function in question. To determine whether the return was successful, we call IsOk or IsError. Both of these return a boolean value of whether the result is ok to access or resulted in an error. Lastly, if IsOk returns true, the T::Result can be accessed with a call to GetOkValue. Similarly, if IsError returns true, the FOnlineError can be accessed with a call to GetErrorValue.

Functions that require asynchronous communication return a TOnlineAsyncOpHandle<T>. Adding an OnComplete callback on this handle will listen to any final change in state for this handle — whether successful completion, failure, timeout, or otherwise. The callback's TOnlineResult<T> parameter will contain either the successful result data or an FOnlineError describing why the function failed. This callback accepts a unique function, so unique pointers and heavy data types may be moved into the capture scope of the lambda if a lambda function is used.

Functions used for event listening return a TOnlineEvent<T>. Similar to a TOnlineAsyncOpHandle, you can listen to the event callback with the Add function. Add will then fire that callback with signature T whenever an event matching the conditions is detected. Multiple callbacks can be added to the same event. Calling Add will return a FOnlineEventDelegateHandle — this delegate callback will be unbound if this handle is destructed, so make sure to keep it alive for the lifecycle of your system that is listening to this event, and to properly destruct/call Unbind on this handle alongside the destruction of the associated system.

Using Online Services or Online Subsystem

Unreal Engine (UE) now provides two frameworks for accessing online services: Online Services and Online Subsystem. Read on to determine which is right for your project.

Online Services

The Online Services plugins have not been tested in shipping titles. As of UE 5.1, the Online Services plugins are an API-complete version for developers to use with the intention that they will be shipping on a future version of the engine. We also recommend using Online Services for developers targeting their own backend, or those who will be incorporating a number of UE upgrades beyond 5.1 into their project before shipping.

Online Subsystem

Use the Online Subsystem for any title shipping in the near future, or when you do not plan to incorporate any engine upgrades beyond UE 5.1 into the project.

Configuration

The base module for the Online Services plugins is OnlineServices. This module defines and registers service-specific modules with UE. All access to online services will go through this module. OnlineServices tries to load the default online service module specified in DefaultEngine.ini during initialization. Add the following code to your DefaultEngine.ini file to enable online services and specify a default online service:

DEFAULT_PLATFORM_IDENTIFIER is a variable that you must substitute with one of the following supported platform identifiers:

Null

Epic

Xbox

PSN

Nintendo

Steam

Google

GooglePlay

Apple

AppleGameKit

Samsung

Oculus

Tencent

The DefaultServices specified in DefaultEngine.ini is available using the function UE::Online::GetServices when no parameter is specified:

Additional online services are loaded on-demand when a call to UE::Online::GetServices requests them. Invalid identifiers or failure to load the module will return null.

Use an Interface

The header files for the various Online Services interfaces are located in the engine directory:

We encourage you to consult the header files in this directory for more information about Online Services and its various interfaces.

Each of the Online Services Interface documentation pages contains either code examples or a sample process flow to help you get started using the Online Services plugins.

Run an Interface with a Console Command

You can also run an Online Services Interface using a console command. The syntax for running an interface with a console command is:

where NUM, INTERFACE, FUNCTION, PARAM_1, PARAM_2, PARAM_3, and so on, are variables you must substitute with your desired values:

NUM: The index number of the OnlineServices.

INTERFACE: The interface whose functionality you want to use.

FUNCTION: The function within the specified interface that you want to use.

PARAM_1, PARAM_2, PARAM_3...: Parameters for the specified function.

Online Subsystem

Achievements Interface

API Overview

Configure Automatic Title-Managed Achievements

Read

More Information

An achievement is a goal or trophy, awarded outside of a game environment, unlocked or rewarded for accomplishing in-game tasks. Achievements give you a way to incentivize, challenge, and reward players. You can use them to:

Guide players through a game

Increase a game's replay value

Support rivalries between players

The Online Services Achievements Interface provides you with tools to read achievement definitions as well as read and update the achievement state for players. The achievements interface does not handle the creation, deletion, or modification of achievements. Each online service has its own backend systems to manage these aspects of achievements.

You can set up the following mechanisms to unlock achievements depending on the interface's configuration:

Platform-service Managed: Achievements are automatically unlocked by the platform service when associated stats reach predefined thresholds.

Title-managed (automatic): Achievements are automatically unlocked by the title when associated stats reach predefined thresholds. See the Configure Automatic Title-Managed Achievements section below for more information.

Title-managed (manual): Achievements are manually unlocked by the title according to title logic and the UnlockAchievements function.

The availability of these three options varies depending on the online service implementation/platform that you use. Consult the documentation for your particular online service implementation for more information.

API Overview

Functions

The following table provides a high-level overview of the functions provided by the Achievements Interface:

Function

Definition

QueryAchievementDefinitions

Query all achievement definitions for this title.

GetAchievementIds

Retrieve the achievement IDs for achievements cached by QueryAchievementDefinitions.

GetAchievementDefinition

Retrieve an achievement definition with the provided achievement ID cached by QueryAchievementDefinitions.

QueryAchievementStates

Query the state of all achievements for the provided player.

GetAchievementState

Retrieve the state of an achievement by ID for the provided player.

UnlockAchievements

Manually unlock provided achievements.

DisplayAchievementUI

Launch the platform UI for the provided achievement.

OnAchievementStateUpdated

Event triggered when a player's achievement state changes.

Primary Structs

The achievements interface communicates its functionality primarily through three structs: FAchievementDefinition, FAchievementStatDefinition, and FAchievementState, in addition to the function specific structs for passing parameters and return values.

Member

Type

Description

AchievementId

FString

Unique achievement ID.

UnlockedDisplayName

FText

Localized display name of this achievement used once it is unlocked.

UnlockedDescription

FText

Localized description of this achievement used once it is unlocked.

LockedDisplayName

FText

Localized display name of this achievement used while it is locked.

LockedDescription

FText

Localized description of this achievement used while it is locked.

FlavorText

FText

Localized flavor text.

UnlockedIconUrl

FString

URL of the icon for this achievement used once it is unlocked.

LockedIconUrl

FString

URL of the icon for this achievement used while it is locked.

bIsHidden

bool

Whether or not this achievement is hidden until it is unlocked.

StatDefinitions

TArray<FAchievementStatDefinition>

The stats that relate to this achievement.

Member

Type

Description

StatId

FString

Unique ID of the stat.

UnlockThreshold

uint32

Threshold value a user must meet with the associated stat for the achievement to auto unlock.

Member

Type

Description

AchievementId

FString

Achievement this state relates to.

Progress

float

Progress toward unlocking this achievement as a percentage between 0.0 and 1.0. Any value less than 1.0 means that the achievement is locked. A value of 1.0 means the achievement is unlocked.

UnlockTime

FDateTime

If unlocked, the time this achievement was unlocked.

Configure Automatic Title-Managed Achievements

The achievements interface does not require engine configuration when achievements are either platform-service managed or title-managed and manually unlocked. You must configure the engine if your achievement progress is title-managed and you want achievements to automatically unlock when one or more stats reach a predefined threshold.

For automatically-unlocking, title-managed achievements, the achievements interface works in conjunction with the Stats Interface. You must configure the engine for this mechanism to set up unlock rules for achievements and establish conditions based on stats defined with stats interface configuration.

General Syntax

DefaultEngine.ini

For automatically-unlocking, title-managed achievements to update based on stats changes, you must set the bIsTitleManaged flag to true. This flag configures the client to listen for the Online Services Stats Interface's FStatsUpdated event to automatically update achievement state in response to stats changes. The bIsTitleManaged flag's default value is false. If you do not set this flag to true, achievements will not automatically update based on stat changes configured in the achievements definitions in DefaultEngine.ini.

The list of Conditions within UnlockRules contains individual condition pairs. Achievements can depend on one or more stats coupled with an UnlockThreshold. An achievement unlocks only after every stat in its associated Conditions list has met or exceeded the predefined threshold.

Field

Type

Description

AchievementId

String

ID of the achievement that this unlock rule is associated with.

Conditions

List

List of conditions under which this achievement unlocks.

Field

Type

Description

StatName

String

Name of the stat to associate an unlock threshold for this achievement.

UnlockThreshold

Colon delimited Type:Value pair

A pair of the form <Type>:<Value> where Type is the type of this stat and Value is the threshold value at which this condition is met for this achievement to unlock.

Configuration Example

Below is an achievements interface example configuration with two different achievements. The first achievement is dependent on a single stat named Total_Distance that records the total distance a player has traveled in meters. The second achievement is dependent on three different stats to unlock: Distance_Run, Distance_Swim, and Distance_Cycle, all measured in meters.

DefaultEngine.ini

Read

The purpose of the achievements interface is to read achievement definitions and state. Below is a high-level description of the steps involved in reading definitions and state. For code examples, the process of querying and getting information using any Online Services interface is very similar to the example outlined in the Stats Interface documentation to query and get stats.

Achievement Definition

The Achievements interface can read the definition of any achievements configured on the platform services by following these steps:

QueryAchievementDefinitions populates the local interface cache with achievement definitions.

GetAchievementIds retrieves the list of IDs for the cached achievements from step 1.

GetAchievementDefinition obtains the full definition associated with each ID from step 2.

The FAchievementDefintion struct represents achievement definitions. For platform service managed achievements, the definition includes the stats associated with the achievement and their unlock thresholds, above which, the achievement automatically unlocks.

Achievement State

After you query and retrieve a player's achievement definitions as explained in the Achievement Definition section, use QueryAchievementStates and GetAchievementState to read player achievement states:

QueryAchievementStates populates the local interface cache with achievement state information.

GetAchievementState retrieves the current progress toward unlocking the achievement if it is still locked, or the unlock time if the achievement is unlocked.

For title managed achievements, the progress is a binary 0.0 (locked) or 1.0 (unlocked). For platform-service managed achievements with stat-based unlock rules, the progress may accurately reflect the current progress toward the achievement as a percentage between 0.0 and 1.0.

More Information

Header File

Consult the Achievements.h header file directly for more information as needed. The Achievements Interface header file Achievements.h is located in the directory:

For instructions on how to obtain the UE source code, see our documentation on Downloading Unreal Engine Source Code.

Function Parameters and Return Types

See the Functions section of the Online Services Overview page for an explanation of function parameters and return types, including how to pass parameters and processing the results when functions return.

Identity Interface

API Overview

Process Flow

Example

Converting Code from Online Subsystem

More Information

The Online Services Auth Interface provides an API to authenticate and verify local users with online services. Authentication of a local user returns an account ID, which your project can use to interact with many other online service features.

API Overview

Functions

The following table provides a high-level description of the functions included in the Auth Interface.

Function

Description

Login

Authenticate a local user.

Logout

Conclude the auth session for a local user.

ModifyAccountAttributes

Modify attributes associated with an authenticated account.

QueryExternalServerAuthTicket

Query a ticket to make server-to-server calls on behalf of the signed-in user. Tickets are intended to be single use. Users must call the API again to retrieve a new ticket when making repeated calls where a ticket is required.

QueryExternalAuthToken

Retrieve a token for linking the service account with a service account of a different service type.

QueryVerifiedAuthTicket

Retrieve a ticket to create a verified authentication session on a remote client.

CancelVerifiedAuthTicket

Cancel ticket associated with the verified auth session and clean up any resources associated with the ticket.

Session

BeginVerifiedAuthSession

Start a verified auth session for a remote user.

EndVerifiedAuthSession

Clean up the remote verified auth session and any associated resources.

Get Users

GetLocalOnlineUserByOnlineAccountId

Retrieve a logged in user account using Online Account ID.

GetLocalOnlineUserByPlatformUserId

Retrieve a logged in user account using Platform User ID.

GetAllLocalOnlineUsers

Retrieve all logged in user accounts.

Event Listening

OnLoginStatusChanged

Event triggers as a result of a change in user login status.

OnPendingAuthExpiration

Event triggers as a result of a soon-to-expire auth token.

OnAccountAttributesChanged

Event triggers as a result of a change to additional attributes associated with an authenticated account.

Helper

IsLoggedIn

Query the login status of a local user.

Enumeration Classes

The Auth Interface defines three enumeration classes that represent a user's login status, auth ticket audience, and auth token method.

Enumerator

Description

NotLoggedIn

Player is not logged in or has chosen a local profile.

UsingLocalProfile

Player is using a local profile, but is not logged in.

LoggedInReducedFunctionality

Player is logged in, but may have reduced functionality with online services.

LoggedIn

Player is logged in and validated by the platform specific authentication service.

Enumerator

Description

Peer

Generate a ticket appropriate for peer validation.

DedicatedServer

Generate a ticket appropriate for dedicated server validation.

Enumerator

Description

Primary

Acquire an external auth token using the primary method provided by the auth interface.

Secondary

Acquire an external auth token using the secondary method provided by the auth interface.

Primary Struct

Member

Type

Description

AccountId

FAccountId

The account ID of this user. This represents the user's online platform account.

PlatformUserId

FPlatformUserId

The platform user ID associated with this online user.

LoginStatus

ELoginStatus

Login status of this current user.

Attributes

TMap<FSchemaAttributeId, FSchemaVariant>

Additional account attributes.

Process Flow

Login

Login authenticates a local user with the chosen online services. Upon success, Login returns an FAccountInfo struct. The FAccountInfo struct contains an FAccountId, which is necessary to use many other functions included in the Auth interface. A successful login also sets the user's LoginStatus to ELoginStatus::LoggedIn. After a user logs in to their account, the status could change to ELoginStatus::UsingLocalProfile or ELoginStatus::LoggedInReducedFunctionality in the future based on other conditions.

If there are multiple local users that require login, each user must login individually. Furthermore, platform services may not require an explicit login. On these services, the user or users are implicitly logged in when the application starts. Refer to the specific platform services documentation for more information.

Authenticate with an External Server

Frequently, games have custom web services that provide game-specific functionality. These services need to verify the caller's identity before providing access. QueryExternalServerAuthTicket retrieves a single-use ticket for authenticating a user with an external server.

Many games need to make use of more than one online service. Common cases include a platform service paired with another service which extends the first's functionality. QueryExternalAuthToken returns a token appropriate for authentication with a different online service to avoid requiring the user from having to provide separate login credentials for secondary services.

On most platforms, this token is an OpenId token, which provides a guarantee of user identity. This token is then provided to the Login method of the secondary service by setting CredentialsType to ExternalAuth and passing the token as CredentialsToken.

Users need to prove their identity and allow for authentication session tracking when connecting to a game server or peer-to-peer network. On the client side, QueryVerifiedAuthTicket retrieves a single-use ticket to be sent to the game server proving the user's identity. CancelVerifiedAuthTicket cancels this ticket when the play session on the game server has concluded.

Since tickets obtained from a call to QueryVerifiedAuthTicket are single-use tickets, QueryVerifiedAuthTicket must be called each time a user begins a new verified auth session. The same logic applies to CancelVerifiedAuthTicket. CancelVerifiedAuthTicket must be called for every ticket that the user has created.

The game server calls BeginVerifiedAuthSession with the client supplied ticket when the client connects. Successful completion begins a verified auth session for the user associated with the supplied ticket. EndVerifiedAuthSession cleans up associated resources when the game has concluded.

This process for a user client connecting to a remote game server is summarized as:

The client obtains a session auth ticket with a call to QueryVerifiedAuthTicket.

The client sends the session auth ticket, the ticket ID, and their account ID to the server.

The server receives this information and uses it to begin a verified auth session with a call to BeginVerifiedAuthSession.

At the end of the session, the client cancels their auth ticket with CancelVerifiedAuthTicket and the server ends the auth session with EndVerifiedAuthSession.

In a peer-to-peer network model the above process is different. Each user client creates a new authentication ticket for each remote client it is connecting to. The steps for authenticating with a game server then apply for each remote peer:

Each new remote peer calls QueryVerifiedAuthTicket and retrieves a single-use ticket to authenticate with every other existing peer.

Every existing peer calls BeginVerifiedAuthSession to begin a verified auth session for the new remote peer.

Not all interface implementations have peer-to-peer support. Refer to your platform services documentation for more information.

Modify Account Attributes

Game code may store additional custom attributes in the FAccountInfo struct as needed with a call to ModifyAccountAttributes.

Modified attributes persist in the user's data until Logout is called. These attributes will not persist after the auth session is ended. Logout destroys the user's FAccountInfo struct which contains these attributes.

Logout

Logout ends the current authentication session for the local user and cleans up associated resources and structures.

Example

Login with Platform Services

Retrieve the default online services by calling GetServices with no parameters, then access the Auth interface:

Instantiate the parameters necessary to login the user:

Handle the Login.OnComplete callback by registering the account info upon successful login or processing the resulting error:

Converting Code from Online Subsystem

The Online Services Auth Interface is responsible for all code owned by the Online Subsystem Identity Interface.

More Information

Header File

Consult the Auth.h header file directly for more information as needed. The Auth Interface header file Auth.h is located in the directory:

For instructions on how to obtain the UE source code, refer to our documentation on Downloading Unreal Engine Source Code.

Function Parameters and Return Types

Refer to the Functions section of the Online Services Overview page for an explanation of function parameters and return types, including how to pass parameters and processing the results when functions return.

Purchase Interface

Store Interface

API Overview

Process Flow

Converting Code from the Online Subsystem

More Information

The Online Services Commerce Interface is Unreal Engine's foundation for any game service that provides players the ability to purchase or redeem game content outside of gameplay. The Commerce Interface consists of two primary components:

Transactions: the process of purchasing store items with platform currency.

Once the transaction is complete, the interface will grant the player the appropriate entitlements.

Entitlements: content that a player is entitled to receive or use.

A player may receive or use an entitlement because they purchased an item or redeemed a game code.

API Overview

The following table provides a high-level description of the functions included in the Commerce Interface.

Function

Description

Offers

QueryOffers

Fetch the list of all available offers from the store and cache them in the interface. This includes any available downloadable content (DLC), bundles, items, and so on.

QueryOffersById

Fetch the list of available offers from a list of supplied IDs and cache them in the interface.

GetOffers

Retrieve offers from the interface cached by QueryOffers.

GetOffersById

Retrieve offers from a list of supplied IDs cached with the interface.

Store

ShowStoreUI

Show the native store UI for the user to view store information or process transactions outside of the game client.

Checkout

Checkout

Initiate the purchase process with one or more purchase offers retrieved with GetOffers or GetOffersById.

Event Listening

OnPurchaseCompleted

Event that fires whenever a local user completes a transaction. This can be initiated either internally by Checkout or externally through the native store UI.

Entitlements

QueryTransactionEntitlements

View the in-game entitlements corresponding to a successful Checkout call to provide these benefits to the player.

QueryEntitlements

Fetch the list of already acquired entitlements for the specific user from the store and cache them in the interface.

GetEntitlements

Retrieve entitlements from the interface cached by QueryEntitlements.

RedeemEntitlement

Mark an entitlement as "redeemed". The entitlement will then have the redeemed flag when later queried. This is useful for when there is no external game service managing entitlements.

Verification

RetreiveS2SToken

Return a token that can be sent to game services backends to communicate with the platform and verify the ownership of the given entitlements.

Process Flow

We now provide an example process flow using the Online Services Commerce Interface that regulates the flow of a user launching a game, entering the in-game store to make a purchase, and verifying that purchase for use.

Launch Game

After a user launches the game and successfully authenticates with their desired online service, the game calls QueryEntitlements. The game compares the data cached by QueryEntitlements against the registered entitlements in the user's save data to see which entitlements have been granted while the user was offline and appropriately applies them to the user. Simultaneously, the game uses the OnPurchaseCompleted event to listen for a message if the user completes a purchase in the future.

Enter In-Game Store Interface

The user opens the menu for the store while in-game. The game shows a loading screen for the user opening the store while it calls QueryOffers. Once the query resolves, the game then calls GetOffers to get local copies of the data. The local copies are then passed on to the UI framework to render and display the game offers.

Perform Transaction

Upon viewing the items on offer, the user decides to purchase a specific product, we will refer to this as PRODUCT_A. The user adds PRODUCT_A to their in-game cart (handled by the in-game UI) and confirms the transaction. After authenticating the user, the game calls Checkout with the ID of PRODUCT_A. This leads into the platform UI for final confirmation and payment handling.

Once Checkout successfully resolves and an OnPurchaseCompleted event fires, the game calls QueryTransactionEntitlements on the given transaction ID to obtain the in-game entitlement IDs granted to the user as part of the transaction, and applies them to the user's save game. If PRODUCT_A is not something that should be granted to the user's gameplay globally, the game then calls RedeemEntitlement to ensure that the entitlement for PRODUCT_A is not duplicated.

Verify Transaction

After successfully purchasing and redeeming PRODUCT_A, the user decides to enter online play with their newly purchased PRODUCT_A. While authenticating the game server, the game notices that the local user is claiming a new entitlement and requests a verification token to ensure that the product is legitimate. The game calls RetrieveS2SToken on the IDs provided for verification and obtains a JSON Web Token (JWT), which the backend service then uses to connect to the platform service and verify the ownership of the product. Once this returns successfully, the user is then permitted to enter online play with their newly purchased item.

Converting Code from the Online Subsystem

The Online Services Commerce Interface is responsible for all code owned by both the Store (read-only code) and Purchase (read / write code) interfaces from the Online Subsystem. The following table shows the correspondence between objects from the Online Systems Commerce Interface and their counterparts from the older Online Subsystem.

Online Services

Online Subsystem

Interface

Object

Interface

Object

Commerce

Offer

Store

Offer

Commerce

Entitlement

Purchase

Entitlement

More Information

Header File

We welcome you to consult the Commerce.h header file directly for more information as needed. The Commerce Interface header file Commerce.h is located in the following directory:

For a step-by-step guide on how to obtain the UE source code, refer to our documentation on Downloading Unreal Engine Source Code.

Function Parameters and Return Types

Refer to the Functions section of the Online Services Overview page for an explanation of function parameters and return types, including how to pass parameters and processing the results when functions return.

Online Subsystem

API Overview

Connection Status

More Information

The Online Services Connectivity Interface provides you with tools to determine whether your game is connected to your platform's backend online services.

API Overview

Functions

The following table provides a high-level overview of the functions provided by the Connectivity Interface:

Function

Description

GetConnectionStatus

Retrieve the connection status for the provided online service.

OnConnectionStatusChaned

The event triggered when an online service connection status changes.

Enumerated Classes

Online service connection status is represented by the EOnlineServicesConnectionStatus enumerated class.

Value

Description

Connected

Connected to the online services.

NotConnected

Not connected to the online services.

Connection Status

GetConnectionStatus returns the current connection status for the provided online service. Some online services consist of multiple underlying microservices. Use the name of one of these microservices as a parameter for GetConnectionStatus to determine the particular microservice's connection status. If you don't specify an online service parameter, GetConnectionStatus returns EOnlineServicesConnectionStatus::Connected only if all underlying microservices are connected.

You can bind OnConnectionStatusChanged to events to inform you when the connection status of an online service or one of its microservices changes.

The organization of an online service and the accessibility of its particular microservices varies by platform. Consult your platform's online services documentation for more information.

More Information

Header File

Consult the Connectivity.h header file directly for more information as needed. The Connectivity Interface header file Connectivity.h is located in the directory:

For instructions on how to obtain the UE source code, see our documentation on Downloading Unreal Engine Source Code.

Function Parameters and Return Types

Refer to the Functions section of the Online Services Overview page for an explanation of function parameters and return types, including how to pass parameters and processing the results when functions return.

Online Subsystem

Leaderboard Interface

API Overview

Configuration

Read Leaderboard Entries

More Information

A leaderboard is a list of players ranked by an in-game statistic. Leaderboards encourage competition between players, their friends, and the rest of the world, for the top score in your game. Games can feature multiple modes that award scores. Each of these modes can have its own leaderboard or leaderboards.

Leaderboards can rank entries in the following ways:

Ascending: Lower scores are ranked better than higher scores.

The Fortnite wins leaderboard is organized in descending order since more wins is desirable.

Descending: Higher scores are ranked better than lower scores.

Lap time leaderboards in racing games are organized in ascending order since faster lap times are more desirable.

The Online Services Leaderboards Interface provides developers with tools to display and update leaderboards from within their games. Leaderboard data can be very large since each leaderboard your game supports could have an entry for every user account that has played your game. For this reason, the leaderboards interface retrieves data in chunks. Games that implement the leaderboards interface can request chunks of the leaderboard in different ways as described below in the Functions section and, in more detail, in the Read Leaderboard Entries section.

API Overview

Functions

The following table provides a high-level overview of the functions provided by the leaderboards interface:

Function

Description

ReadEntriesForUsers

Read leaderboard entries for specific users.

ReadEntriesAroundRank

Read leaderboard entries around a specified rank index.

ReadEntriesAroundUser

Read leaderboard entries around the specified user.

Primary Struct

The leaderboards interface's functionality is primarily communicated through the FLeaderboardEntry struct:

Member

Type

Description

AccountId

FAccountId

Account ID of this leaderboard entry.

Rank

int32

Rank of this account in this leaderboard.

Score

int64

Score of this account in this leaderboard.

Configuration

To update a leaderboard score using stats, you must configure the leaderboards interface in the engine configuration files, such as DefaultEngine.ini. The leaderboards interface works in conjunction with the Stats Interface to track stats for leaderboard rankings.

General Syntax

DefaultEngine.ini

In order for leaderboards to update based on stats changes, you must set the bIsTitleManaged flag to true. This flag configures the client to listen for the Online Services Stats Interface's FStatsUpdated event to automatically update leaderboards in response to stats changes. The bIsTitleManaged flag's default value is false. If you do not set this flag to true, leaderboards will not automatically update based on stat changes configured in the leaderboard definitions in DefaultEngine.ini.

The following Leaderboard Definition table explains the syntax for adding a leaderboard definition to an engine configuration file.

Field

Type

Description

Name

String

Name of the stat that determines ranking. This must be the same as the name of a stat configured with the stats interface.

Id

int

ID number to associate with this leaderboard. This is not related to the stats ID from the stats interface.

UpdateMethod

KeepBest or Force

The method used to update this leaderboard entry. KeepBest keeps the best value for this stat that has been achieved. Force updates the leaderboard entry to the latest stat value, regardless of how it changes a player's rank.

OrderMethod

Ascending or Descending

Determines whether a lower or higher stat value gives a better ranking. Ascending means a lower stat value gives a higher rank. Descending means a higher stat value gives a higher rank.

Configuration Example

Suppose that you have a simple game with a single leaderboard titled "Total Game Points" tracked by a statistic of the same name configured with the stats interface:

DefaultEngine.ini

In this configuration, the leaderboard:

keeps the best score for the Total_Game_Points statistic for each player, and

is organized in descending order, since higher point totals are more desirable.

Read Leaderboard Entries

There are three different ways to read leaderboard entries with the leaderboards interface. Leaderboard entries can be read in the following ways:

For specific users

Around a particular rank

Around a given user

Below we show a visual representation of what each of these methods retrieves with the "Total Game Points" leaderboard configured in the configuration example above.

For Specific Users

Use the ReadEntriesForUsers function to retrieve leaderboard entries for specific users. This function takes in a list of user IDs for the individual users whose rank you wish to query.

Suppose that you have the leaderboard below titled "Total Game Points" and call ReadEntriesForUsers with the following parameters:

If the call returns successfully, you can access the columns marked as retrieved in the returned TOnlineResult:

Total Game Points

Account ID

Rank

Score

Retrieved?

3CN9H8E-VNO3G3C

1

1,901

Y

LLV54WB-3C678QQ

2

151

OHB8RA2-OHSEBSE

3

17

Y

9P8H4GQ-HNO5GA4

4

3

Y

9HQGQER-ILASDFH

5

1

Around a Particular Rank

Use the ReadEntriesAroundRank function to retrieve leaderboard entries around a particular leaderboard rank. This function takes in:

a rank at which you want to start reading leaderboard entries, and

a limit for the number of entries to read.

Suppose that you have the leaderboard below titled Total Game Points and call ReadEntriesAroundRank with the following parameters:

If the call returns successfully, you can access the columns marked as retrieved in the returned TOnlineResult:

Total Game Points

Account ID

Rank

Score

Retrieved?

3CN9H8E-VNO3G3C

1

1,901

LLV54WB-3C678QQ

2

151

OHB8RA2-OHSEBSE

3

17

Y

9P8H4GQ-HNO5GA4

4

3

Y

9HQGQER-ILASDFH

5

1

From a programming perspective, the rank of the top of a leaderboard is 0, not 1. As a result of this, to retrieve the entry in third place, ReadEntriesAroundRank needs to be called with Params.Rank = 2.

Around a Given User

Use the ReadEntriesAroundUser function to retrieve leaderboard entries around a particular user. This function takes in:

the user around which you want to read entries,

an offset to indicate where to start reading entries, and

a limit for the total number of entries to read.

The offset can exceed the limit. In this case, the provided user will not be present in the returned array of leaderboard entries. This can be useful when organizing leaderboard entries into pages for viewing.

Suppose that you have the leaderboard below titled Total Game Points and call ReadEntriesAroundUser with the following parameters:

If the call returns successfully, you can access the columns marked as retrieved in the returned TOnlineResult:

Total Game Points

Account ID

Rank

Score

Retrieved?

3CN9H8E-VNO3G3C

1

1,901

Y

LLV54WB-3C678QQ

2

151

Y

OHB8RA2-OHSEBSE

3

17

Y

9P8H4GQ-HNO5GA4

4

3

9HQGQER-ILASDFH

5

1

More Information

Header File

Consult the Leaderboards.h header file directly for more information as needed. The Leaderboards Interface header file Leaderboards.h is located in the directory:

For instructions on how to obtain the UE source code, see our documentation on Downloading Unreal Engine Source Code.

Function Parameters and Return Types

See the Functions section of the Online Services Overview page for an explanation of function parameters and return types, including how to pass parameters and processing the results when functions return.

Online Subsystem

API Overview

Configuration

Process Flow

Leader Actions

Member Actions

Converting Code from Online Subsystem

More Information

The Online Services Lobbies Interface provides an API for creating and managing lobbies. A lobby is a group of players within the context of a client application where all of the players have some shared state. This could mean that they are all playing in the same online match together or all waiting for the same match to begin. Both the lobby and its members have attributes used to share this state. Changes to a lobby's attributes or the attributes of any of its members are seen by all joined lobby members in real-time.

The lobby leader may change a lobby's attributes, and each member (including the leader) may change their own attributes at any time. A lobby schema defines these attributes, along with their types and value constraints, that are then used to create a lobby. This lobby schema is defined in the application config files and is validated when the application starts. You are not required to define all attributes to create a lobby, but if you define an attribute that fails schema validation, lobby creation will fail.

A common use of Lobbies is to group players together before proceeding into a match. Several game matches may be played within the lifetime of a single lobby. Below is an example lifecycle of a lobby:

A player creates a new lobby with the desired privacy settings and attributes. This player is designated the lobby leader.

Additional players locate and join the lobby through public search, invitation, or social presence.

Players share attributes within the lobby through attribute updates.

Once the lobby chooses to play a match, the lobby leader records the match session ID as a lobby attribute.

Other lobby members see this session ID and join the same game session.

Players join or leave the lobby throughout the lifetime of multiple game matches.

API Overview

Functions

The following table provides a high-level overview of the functions provided by the Lobbies Interface:

Function

Description

Operations

CreateLobby

Create and join a new lobby.

FindLobbies

Search for lobbies that fit the provided parameters.

RestoreLobbies

Try to rejoin previously joined lobbies.

JoinLobby

Join a lobby with the provided lobby ID.

LeaveLobby

Leave a joined lobby.

InviteLobbyMember

Invite a player to join a lobby.

DeclineLobbyInvitation

Decline an invitation to join a lobby.

KickLobbyMember

Kick a member from the target lobby.

PromoteLobbyMember

Promote another lobby member to leader. The local player calling PromoteLobbyMember must be the current lobby leader to promote another member.

Mutations

ModifyLobbySchema

Change the schema applied to the lobby and member attributes.Only the lobby leader may change the schema. Existing attributes not present in the new schema will be cleared.

ModifyLobbyJoinPolicy

Change the join policy applied to the lobby. Only the lobby leader may change the join policy.

ModifyLobbyAttributes

Change the attributes applied to the lobby. Only the lobby leader may change the lobby attributes. Attributes are validated against the lobby schema before an update can succeed.

ModifyLobbyMemberAttributes

Change the attributes applied to a lobby member. Lobby members may only change their own attributes. Attributes are validated against the lobby schema before an update can succeed.

Accessors

GetJoinedLobbies

Retrieve the list of joined lobbies for the target local player.

GetReceivedInvitations

Retrieve the list of received invitations for the target local player.

Event Listening

OnLobbyJoined

Event triggered when a player joins a lobby.

OnLobbyLeft

Event triggered when all local members leave a lobby.

OnLobbyMemberJoined

Event triggered when a lobby member joins, either as a result of a local player creating or joining a lobby, or when a remote player joins.

OnLobbyMemberLeft

Event triggered when a lobby member leaves a joined lobby.

OnLobbyLeaderChanged

Event triggered when the lobby's leadership changes.

OnLobbySchemaChanged

Event triggered when the lobby's attribute schema changes.

OnLobbyAttributesChanged

Event triggered when a lobby's attributes change.

OnLobbyMemberAttributesChanged

Event triggered when a lobby member's attributes change.

OnLobbyInvitationAdded

Event triggered when a lobby member receives an invitation.

OnLobbyInvitationRemoved

Event triggered when a lobby member addresses an invitation or the invitation expires.

OnUILobbyJoinRequested

Event triggered when a player requests to join the lobby through an external mechanism.

Enumeration Classes

The Lobbies Interface provides enumeration classes to reflect Lobby Join Policy and Lobby Member Leave Reasons:

Enumerator

Description

PublicAdvertised

Users can find the lobby through searches based on attribute matching, lobby ID, or invitation.

PublicNotAdvertised

Users can join the lobby by lobby ID or invitation.

InvitationOnly

Users can only join the lobby by invitation.

Enumerator

Description

Left

Lobby member chose to leave the lobby.

Kicked

Lobby member was kicked out of the lobby by the lobby owner.

Disconnected

Lobby member left unexpectedly.

Closed

Lobby was destroyed by the online services and all members have left.

Primary Structs

The Lobby Interface functionality is primarily communicated through two structs: FLobbyMember and FLobby, in addition to the function specific structs for passing parameters and return values.

Member

Type

Description

AccountId

FAccountId

Account ID of this lobby member.

PlatfromAccountId

FAccountId

Platform account ID of this lobby member.

PlatfromDisplayName

FString

Platform display name of this lobby member.

Attributes

TMap<FSchemaAttributeId, FSchemaVariant>

Attributes of this lobby member as defined in the configuration.

bIsLocalMember

bool

Whether this lobby member is a local player on this client. (Default value is false.)

Member

Type

Description

LobbyId

FLobbyId

ID of this lobby.

OwnerAccountId

FAccountId

Account ID of the lobby member that is the current owner of this lobby.

LocalName

FName

Local name of this lobby.

SchemaId

FSchemaId

ID of the schema applied to this lobby.

MaxMembers

int32

Maximum number of members who can be in this lobby at any given time.

JoinPolicy

ELobbyJoinPolicy

Join policy setting for this lobby.

Attributes

TMap<FSchemaAttributeId, FSchemaVariant>

Attributes of this lobby as defined in the configuration.

Members

TMap<FAccountId, TSharedRef<const FLobbyMember>>

Dictionary of lobby members where the keys are account IDs and the values are pointers to their corresponding lobby member struct.

Configuration

Lobbies use a schema system to define the structure and properties of the lobby as well as lobby member attributes. A game may declare multiple individual schema definitions to support many different types of lobbies. All lobby schemas must derive from the LobbyBase schema.

The LobbyBase schema contains all attributes players can use to search for a lobby. This inheritance structure means that the Lobbies interface knows which game-provided schema to apply to a search result. SchemaCompatibilityId is a special attribute within LobbyBase that exists to ensure that a schema is compatible between two clients.

A game must declare a definition for each schema attribute present in a schema definition. Schemas are defined in a project's configuration files (*.ini) files. These definitions include an attribute's type, maximum size, and visibility, as well as additional behaviors such as whether the attribute is available as a search parameter.

In general, a schema has categories which contain attribute definitions. The Lobbies interface schema has two categories: Lobby and LobbyMember. These categories contain attribute definitions which apply to the lobby object and lobby member objects, respectively.

Example

Here is an example configuration for the Lobbies interface:

DefaultEngine.ini

Process Flow

Create

A player initiates lobby creation, and will be designated the lobby leader once the lobby is created. The creating player decides the initial lobby settings. These settings can include:

Visibility

Join Policy

Schema ID

Lobby Attributes

Lobby Member Attributes

Other players can see the public attributes when they search for a lobby. The lobby leader has additional privileges as outlined in the Leader Actions section of this page. All lobby members, including the leader, can change their personal attributes or invite players to join the lobby. These actions are summarized in the Member Actions section.

Upon successful lobby creation, the creating player receives an OnLobbyJoined event followed by an OnLobbyMemberJoined for themselves, since they are now the designated lobby leader. As long as this player is designated as the lobby leader, they will receive additional OnLobbyMemberJoined and OnLobbyMemberLeft events as players join and leave the lobby.

Find

To join a lobby, a player first needs to know the lobby's ID. Players can find the ID by:

Search

Invite

Both search and invitation provide a snapshot of the lobby data to the client application. Attributes within the snapshot are not updated until the player has joined the lobby.

Lobby search allows a player to specify attributes to find lobbies which match their desired configuration. Players can search for lobbies by:

Attribute filters

Target player

Specific lobby ID

Depending on a lobby's privacy setting, lobby members may invite additional players to join the lobby. When an invitation is sent, the target player receives an OnLobbyInvitationAdded event to notify them of the waiting invitation. The OnLobbyInvitationRemoved event triggers when the invitation is addressed or expires.

Some online service implementations allow players to join a friend's lobby through a social user interface, such as the Online Services Presence Interface. When a player chooses to join in this way, an OnUILobbyJoinRequested event triggers the application to indicate the player's desire to join the lobby.

Join

Once a player knows the ID of the lobby they wish to join, calling JoinLobby starts the process of adding the local player. The local player must provide their initial LobbyMember attributes, which are shared with the other existing lobby members upon joining the lobby.

After successfully joining a lobby, the player receives an OnLobbyJoined event. Every existing member of the lobby receives an OnLobbyMemberJoined event notifying them a new player has joined. While a player remains in this lobby, they receive additional OnLobbyMemberJoined and OnLobbyMemberLeft events as other players join and leave the lobby.

Leave

When a player no longer wishes to remain in a lobby, LeaveLobby removes the player from the lobby with the supplied lobby ID and stops notifications. Once a player leaves a lobby, all other players in the lobby receive an OnLobbyMemberLeft notification. This notifies them a player has left the lobby. These notifications are followed by an OnLobbyLeft event sent to the player who has left the lobby..

Restore

RestoreLobbies restores all lobbies previously joined by the calling player. This is typically done by a game at application startup to rejoin the local player to lobbies they were in when the application last exited.

Leader Actions

The lobby leader has additional, exclusive privileges they can use to help maintain the lobby.

Promote Member

The lobby leader can promote another lobby member to become the leader with a call to PromoteLobbyMember. This action triggers an OnLobbyLeaderChanged event for all lobby members. The player who was previously the leader becomes a normal lobby member.

Kick Member

The lobby leader can remove a target member from the lobby with a call to KickLobbyMember. This action triggers an OnLobbyLeft event for the kicked lobby member and an OnLobbyMemberLeft event for all other lobby members.

Update Lobby Attributes

The lobby leader can change the attributes of the lobby object. This is handled with a call to ModifyLobbyAttributes. When the lobby attributes change, all lobby members receive an OnLobbyAttributesChanged event to notify them of the changed attributes.

Change Lobby Join Policy

The lobby's join policy affects whether the lobby appears in search results, is invitation only, or can be joined by social presence. The lobby leader can change this setting with a call to ModifyLobbyJoinPolicy.

Member Actions

Lobby members are limited to two actions. Members can update their own attributes and invite other members to join the lobby.

Change Member Attributes

Lobby members can change their own attributes with a call to ModifyLobbyMemberAttributes. An OnLobbyMemberAttributesChanged event notifies other lobby members of this change.

Invite Players to Join the Lobby

If the lobby join policy currently allows invitations, lobby members can invite additional players with a call to InviteLobbyMember. The target of the invitation receives an OnLobbyInvitationAdded event that notifies them of the pending invitation. The invited player chooses to join the lobby with a call to JoinLobby or rejects the invitation with DeclineLobbyInvitation.

Converting Code from Online Subsystem

Lobbies is a new interface for the Online Services and does not have a direct counterpart from the Online Subsystem.

More Information

Header File

Consult the Lobbies.h header file directly for more information as needed. The Lobbies Interface header file Lobbies.h is located in the directory:

For instructions on how to obtain the UE source code, see our documentation on Downloading Unreal Engine Source Code.

Function Parameters and Return Types

See the Functions section of the Online Services Overview page for an explanation of function parameters and return types, including how to pass parameters and processing the results when functions return.

Presence Interface

API Overview

Examples

Converting Code from Online Subsystem

More Information

When logged into an online service, you may want to look for information about your friends and other users you have met online. For example, on many online services, you can see whether other users are online, what game they are currently playing, if they are available to join matches, and so on. The Online Services Presence Interface encompasses all functionality related to platform-specific user states across online services, including querying and updating a user's presence as well as listening for changes.

This document provides an API overview and code examples as well as tips for converting code from the Online Subsystem Presence Interface.

API Overview

Functions

The following table provides a high-level description of the functions included in the Presence Interface.

Function

Description

Query

QueryPresence

Fetch the presence of the user with the supplied TargetAccountId.

BatchQueryPresence

Fetch the presence for every user in the supplied list of TargetAccountIds.

Get

GetCachedPresence

Retrieve the presence of the user with the supplied TargetAccountId cached in the interface.

Update

UpdatePresence

Update the presence of the user.

PartialUpdatePresence

Update the presence of the user with only the specified presence settings.

Event Listening

OnPresenceUpdated

Event will trigger as a result of updates to a user's presence.

Enumeration Classes

The Presence Interface defines three enumeration classes that represent a user's status, joinability, and game status. These enumeration classes represent three primary members of the FUserPresence struct. For more information, refer to the Primary Struct section of this page.

Enumerator

Description

Offline

User is offline.

Online

User is online.

Away

User is away.

ExtendedAway

User has been away for at least two hours (may be platform dependent).

DoNotDisturb

User does not want to be disturbed.

Unknown

Default user presence status.

Enumerator

Description

Public

Anyone can discover and join this session.

FriendsOnly

Anyone trying to join must be a friend of a lobby member.

InviteOnly

Anyone trying to join must be invited first.

Private

User is not currently accepting invitations.

Unknown

Default user presence joinability status.

Enumerator

Description

PlayingThisGame

User is playing the same game as you.

PlayingOtherGame

User is playing a different game than you.

Unknown

Default user presence game status.

Primary Struct

The FUserPresence struct is the primary object in the Presence interface and consists of all necessary information pertaining to a user's presence.

Member

Type

Description

AccountId

FAccountId

User whose presence this is.

Status

EUserPresenceStatus

User presence state. (Default value is EUserPresenceStatus::Unknown.)

Joinability

EUserPresenceJoinability

User session state. (Default value is EUserPresenceJoinability::Unknown.)

GameStatus

EUserPresenceGameStatus

User game state. (Default value is EUserPresenceGameStatus::Unknown.)

StatusString

FString

String representation of user presence state.

RichPresenceString

FString

Game-defined representation of the current game state.

Properties

FPresenceProperties

Session keys.

The type FPresenceProperties is a typedef for TMap<FString, FPresenceVariant> where FPresenceVariant is an FString.

Examples

We now provide an example demonstrating UpdatePresence, QueryPresence, and GetPresence. UserA updates their presence with the default platform services, then UserB queries the presence of UserA after it has been updated. If the query successfully returns, then UserB retrieves the presence of UserA.

Code

UserAPresence.cpp

UserBPresence.cpp

Walkthrough

Both users retrieve the default online services by calling GetServices with no parameters specified and access the Presence Interface:

UserAPresence.cpp and UserBPresence.cpp

UserA initializes an FUserPresence struct named Presence. Notice that we are using two of the aforementioned enumerations provided by the Presence Interface: EUserPresenceStatus and EUserPresenceJoinability.

UserAPresence.cpp

UserA initializes an FUpdatePresence::Params struct named Params with the parameters that will be passed to UpdatePresence:

UserAPresence.cpp

UserA calls UpdatePresence and processes the result with an OnComplete callback:

UserAPresence.cpp

UserB queries the presence of UserA. Inside the queries' OnComplete callback, UserB first checks to ensure QueryPresence returned an "Ok" status. If it did, then UserB is safe to retrieve the presence of UserA and process the result or error of GetPresence accordingly:

UserBPresence.cpp

If all function calls return without error, UserB now sees the updated status of UserA and UserB can choose to make decisions based on this status. For example, UserB could access the GetPresenceResult to see UserA is online and their joinability status is public. Upon setting this status UserB could decide to join UserA and "Explore the Great Citadel" together.

Converting Code from Online Subsystem

The Online Services plugins are an updated version of the Online Subsystem plugins and will exist alongside one another for the foreseeable future. The API functionality of the Online Services Presence Interface maps approximately one-to-one with the API functionality of the Online Subsystem Presence Interface. A few caveats include:

SetPresence was renamed to UpdatePresence to better represent the function's asynchronicity.

UpdatePresence and QueryPresence are no longer overloaded.

We recommend using their renamed functions PartialUpdatePresence and BatchQueryPresence instead.

The overloads for UpdatePresence and QueryPresence were renamed to PartialUpdatePresence and BatchQueryPresence, respectively.

QueryPresence was given the bListenToChanges parameter.

This adds a specific user to the OnPresenceUpdated event.

The parameter is set to true by default.

More Information

Header File

Consult the Presence.h header file directly for more information as needed. The Presence Interface header file Presence.h is located in the directory:

For instructions on how to obtain the UE source code, refer to our documentation on Downloading Unreal Engine Source Code.

Function Parameters and Return Types

Refer to the Functions section of the Online Services Overview page for an explanation of function parameters and return types, including how to pass parameters and processing the results when functions return.

Online Subsystem

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Online Services Overview

API Overview

User Privilege

More Information

The Online Services Privileges Interface manages a player's online privileges. Privileges refer to a player's ability to:

Play online.

Participate in crossplay.

Communicate with other players.

Use community generated content.

API Overview

Functions

The following table provides a high-level overview of the function provided by the Privileges Interface:

Function

Description

QueryUserPrivilege

Query a given privilege for the provided user.

Enumerated Classes

The privileges interface communicates user privileges and user privilege status' through two enumerated classes., while privileges status is given by EPrivilegeResults.

A user privilege is represented by a EUserPrivileges enumerated class:

Value

Description

CanPlay

Specifies whether the user can play the game — online or offline.

CanPlayOnline

Specifies whether the user can play in online modes.

CanCommunicateViaTextOnline

Specifies whether the user can use text chat.

CanCommunicateViaVoiceOnline

Specifies whether the user can use voice chat.

CanUseUserGeneratedContent

Specifies whether the user can use content generated by other users.

CanCrossPlay

Specifies whether the user can ever participate in crossplay.

User privileges status is given by one or more EPrivilegeResults:

Value

Description

NoFailures

User has the requested privilege.

RequiredPatchAvailable

Patch required before the user can use privilege.

RequiredSystemUpdate

System update required before the user can use privilege.

AgeRestrictionFailure

Privilege restricted due to parental control failure.

AccountTypeFailure

Privilege requires a premium account.

UserNotFound

Invalid user.

UserNotLoggedIn

User must be logged in to use privilege.

ChatRestriction

User restricted from chat.

UGCRestriction

User restricted from User Generated Content (UGC).

GenericFailure

Platform failed for an unknown reason and handles its own dialogues.

OnlinePlayRestricted

Online play is restricted.

NetworkConnectionUnavailable

Check failed because the network is unavailable.

User Privilege

Call QueryUserPrivilege to determine whether a user is permitted to use a particular online feature or privilege in your game. QueryUserPrivilege requires that you provide the local account ID of the user and the privilege in question as parameters. QueryUserPrivilege returns a result that indicates whether the user you specified is permitted the privilege you specified. If the user is not permitted to use the queried privilege, the result contains the reasons why.

It is possible there are multiple reasons why a user is not permitted to use a privilege. Consequently, the structure of the result is a cumulative bitwise OR of EPrivilegeResults values that represent the reasons why this user is not permitted to use the provided privilege. If the user is permitted to use this privilege, then the query returns EPrivilegeResults::NoFailures, which indicates there is nothing preventing the user from using the desired privilege.

Certain privileges can change when the game is suspended. It is important to re-query user privileges each time the game returns to an active state as certain game options could no longer be available.

More Information

Header File

Consult the Privileges.h header file directly for more information as needed. The Privileges Interface header file Privileges.h is located in the directory:

For instructions on how to obtain the UE source code, see our documentation on Downloading Unreal Engine Source Code.

Function Parameters and Return Types

See the Functions section of the Online Services Overview page for an explanation of function parameters and return types, including how to pass parameters and how to process the results when functions return.

Session Interface

API Overview

Process Flow

Examples

Converting Code from Online Subsystem

More Information

The Online Services Session Interface handles the creation, destruction, and management of online game sessions. A session is the representation of an online match in a game, running on either a player's machine or a dedicated server. Sessions can have the following join policies:

Invite Only: Players with an invitation can join the session.

Friends Only: Friends of any session member can join the session.

Public: Anyone can find and join the session.

You can define a public session using a set of properties that act as filters, allowing players to search for specific game modes or maps.

API Overview

The following table provides a high-level description of the functions included in the Sessions Interface.

Function

Description

Get Sessions

GetAllSessions

Retrieve an array of references to all sessions the user is part of.

GetSessionByName

Retrieve a reference to the session with the supplied name.

GetSessionById

Retrieve a reference to the session with the supplied ID handle.

Presence

GetPresenceSession

Retrieve a reference to the session currently set as the user's presence session.

IsPresenceSession

Determine whether the session with the given ID is set as the user's presence session.

SetPresenceSession

Set the session with the given ID as the user's presence session.

ClearPresenceSession

Clear the user's presence session.

Session Management

CreateSession

Create a new session using the supplied parameters.

UpdateSessionSettings

Update settings for the session identified by the supplied name.

LeaveSession

Leave and optionally destroy the session identified by the supplied name.

FindSessions

Query the session service for sessions matching the supplied parameters.

JoinSession

Join the session with the supplied session ID.

StartMatchmaking

Start the matchmaking process. This searches for and joins a session that matches the given search filters, or, if no such session is found, creates a session using the supplied parameters.

AddSessionMember

Add the user as a new session member to the session identified by the supplied name.

RemoveSessionMember

Remove the user from the session identified by the supplied name.

Invites

SendSessionInvite

Send an invite to the session identified by the supplied name to all supplied users.

GetSessionInviteById

Get a reference to the session invite identified by the supplied invite ID.

GetAllSessionInvites

Get an array of references to all the session invites the user has received.

RejectSessionInvite

Reject the session invite identified by the supplied invite ID.

Event Listening

Event will trigger as a result of:

OnSessionJoined

Joining a session.

OnSessionLeft

Leaving or destroying a session.

OnSessionUpdated

Updating a session's settings or whenever a session update event is received.

OnSessionInviteReceived

Receiving a session invite.

OnUISessionJoinRequested

Accepting a session invite or joining a session through the platform UI.

Process Flow

Session Lifecycle

Create a new session using the desired settings.

At any point during the lifetime of a session, you can update the session to reflect changes in the properties of the online match it represents. These changes can include:

Altering parameters regarding how the session appears in searches, or whether it shows up at all.

Restricting new players from joining the session once the game is in progress.

Players that discover the session can join it.

Using information obtained by joining the session, new players can connect to the session host or dedicated server.

After connecting, the players need to get registered with the session. This process will be automatically handled by the engine in future releases.

Play the game.

When the game is over, the player can leave the session or destroy it (if the player is the owner or host).

Disconnecting from the host or server needs to be followed by unregistering the player or players from the session. This process will be automatically handled by the engine in future releases.

The first step in the session lifecycle is creating a session using the desired parameters. These parameters include some that remain constant throughout the lifetime of the session (like bIsLANSession and bAllowSanctionedPlayers from the CreateSession function) and some you can update at any time (like the options provided by the function SessionSettings).

At most one session per user can be set as the Presence Session. This means it will appear in the user's Presence information and be visible to friends and followers as exposed through the Presence Interface. If a user is a member of many sessions, which session appears as the presence session can be changed by SetPresenceSession (this functionality might not be available in all platform implementations).

A user can discover new sessions in a few different ways:

FindSessions allows users to define search parameters such as tags that match a desired session's custom settings or a specific user ID to find the session that their friend is in. This returns a list of session IDs each representing cached session information, which the user can search and access with GetSessionById.

Users can receive session invitations from other users. After receiving an invitation, a user can view the information about the session by accessing the invitation with GetSessionInviteById. Afterwards, the user decides whether to join the session with the session ID provided by the invite information.

Specific platform UIs may show users information about sessions their friends have joined.

Once a user has information about a session obtained either through search, invitation, or presence, they can attempt to join it by calling JoinSession. They can also choose if they want to set this new session as their presence session with SetPresenceSession.

Another way you can join a session is by calling StartMatchmaking. This function acts as a combination of CreateSession and FindSessions. StartMatchmaking looks for sessions matching a predefined set of search filters and it will create a session using the given information if it cannot find any.

Once you have joined a session, you can call IOnlineServices::GetResolvedConnectString, which returns the platform specific connection information needed to join the match. The string obtained from this function can then be passed to APlayerController::ClientTravel or UWorld::ServerTravel to send the player into the match. If the travel succeeds, the player will be added to the session and AddSessionMember is called to register the player with the session.

After joining a session, either by creating it or joining it, you can send the session information to other players with SendSessionInvite. This is a good way to get friends together in the same online match. Once a player receives an invite, they can access its information using GetAllSessionInvites to access all invites for a given user, or GetSessionInviteById to get the information about a particular invite. They can also reject session invites using a call to RejectSessionInvite by passing the corresponding invite ID as a parameter.

You can update session settings at any point during the session's lifetime by calling UpdateSessionSettings. These settings include, but are not limited to:

Maximum number of players in session

Join policy for the session:

Invite Only

Friends Only

Public

Restrict access to new players

Add, modify, or remove custom settings and user-defined parameters

You can leave a session by calling LeaveSession. The owner of the session can set the additional parameter bDestroySession to true if they want to remove the session from the backend services as they leave. This forces all other members of the session to leave as well.

Examples

You can access the Sessions Interface through a reference to an OnlineServices instance. From here, the functionality of the Sessions Interface is exposed. We provide a few examples of accessing the Sessions Interface and performing synchronous and asynchronous operations.

Get Session By Name

Use the default online services by calling GetServices with no parameters specified:

Access the Sessions interface for the default online services:

Initialize a FGetSessionByName struct using the necessary parameters to call GetSessionByName:

Call GetSessionByName passing in the parameters from the previous step and save the result:

Process the result of the call to GetSessionByName after ensuring the function call did not throw an error and the result can be accessed:

Update Session Settings

Use the default online services by calling GetServices with no parameters specified and access the Sessions interface for the default online services:

Initialize a struct using the necessary parameters to call UpdateSessionSettings:

Handle the UpdateSessionSettings.OnComplete callback by processing the error or the queried stats if it resulted in an error, or the result if it returns okay with a lambda function:

Converting Code from Online Subsystem

The Online Services Sessions Interface is responsible for all code owned by the Online Subsystem Sessions Interface.

More Information

Header File

Consult the Sessions.h header file directly for more information as needed. The Sessions Interface header file Sessions.h is located in the directory:

For instructions on how to obtain the UE source code, refer to our documentation on Downloading Unreal Engine Source Code.

Function Parameters and Return Types

Refer to the Functions section of the Online Services Overview page for an explanation of function parameters and return types, including how to pass parameters and processing the results when functions return.

Online Subsystem

Friends Interface

API Overview

Process Flow

Converting Code from Online Subsystem

More Information

The Online Services Social Interface manages relationships between users. This includes:

Retrieving and viewing a player's friends list.

Sending friend invites.

Accepting/Rejecting friend invites.

Viewing a list of blocked players.

Blocking other players.

API Overview

Functions

The following table provides a high-level overview of the functions provided by the social interface:

Function

Description

View

QueryFriends

Query the player's friends list.

GetFriends

Retrieve a friends list cached by QueryFriends.

Invite

SendFriendInvite

Send a friend invite.

AcceptFriendInvite

Accept a friend invite.

RejectFriendInvite

Reject a friend invite.

Block

QueryBlockedUsers

Query the blocked users list.

GetBlockedUsers

Retrieve blocked users list cached by QueryBlockedUsers.

BlockUser

Block a specified user.

Event Listening

OnRelationshipUpdated

Event triggered by updating friends list.

Primary Struct

The social interface communicates its functionality primarily through the FFriend struct in addition to the function specific structs for passing parameters and return values.

Member

Type

Description

FriendId

FAccountId

Account ID of this friend.

DisplayName

FString

Display the name of this friend.

Nickname

FString

Local nickname for this friend.

Consult the documentation for your platform's online services for availability.



Relationship

ERelationship

Relationship to this friend.

Enumerated Classes

The ERelationship enumerated class holds the relationship status between the local user and the online user represented by the FFriend struct through which it is accessed.

Value

Description

Friend

Friend

NotFriend

Not a friend

InviteSent

Invite sent to a user.

InviteReceived

Invite received from a user.

Blocked

Local user has blocked this user.

Process Flow

View Friends

Upon starting your game, the player views which friends are online. To accomplish this, QueryFriends caches the player's friends list with the social interface, then GetFriends retrieves the previously cached friends list for reading. The player can now view their friends list to decide whether to invite their friends to join a lobby and enter a game session together.

Invite Friends

After playing with their friends and other online players, the player meets several other players they enjoy playing with. The player decides to send friend invites to two of these online players. SendFriendInvite sends a friendship invitation to a single provided player each time it is called. One of the online players sees the invitation and rejects it. The game calls RejectFriendInvite to reject the player's invitation.

Meanwhile, the second online player accepts the invitation. A call to AcceptFriendInvite accepts the player's invitation. This friendship acceptance triggers an OnRelationshipUpdated event for both the player who sent the invitation and the online player who accepted the invitation.

Block Users

While playing with their new friend, the player meets another online player. This time, the player decides they do not wish to interact with this online player in the future. The player proceeds to block this online player. The player can see the online players they have blocked by querying their blocked list. QueryBlockUsers caches the information in the interface and a subsequent call to GetBlockedUsers retrieves the list of blocked players. If the online player in question does not appear in this list, a call to BlockUser adds the online player to the player's blocked list.

Depending on your platform, the Invite and Block APIs may bring up a platform dialogue to perform the associated action. Consult the documentation for your particular platform for more information.

Converting Code from Online Subsystem

The Online Services Social Interface is responsible for all code previously handled by the Online Subsystem Friends Interface.

More Information

Header File

Consult the Social.h header file directly for more information as needed. The social interface header file Social.h is located in the directory:

For instructions on how to obtain the UE source code, see our documentation on Downloading Unreal Engine Source Code.

Function Parameters and Return Types

See the Functions section of the Online Services Overview page for an explanation of function parameters and return types, including how to pass parameters and processing the results when functions return.

API Overview

Configuration

Examples

Reset Stats Data

More Information

The Online Services Stats Interface is used to upload stats and data to online services and complete stats queries. Stats Interface functionality is also used by other interfaces that rely on user gameplay statistics such as the Online Services' Achievements and Leaderboards Interfaces.

API Overview

The following table provides a high-level description of the functions included in the Stats Interface.

Function

Description

Update

UpdateStats

Upload stats to the platform

Query

QueryStats

Query the stats of a user and cache the result in the interface.

BatchQueryStats

Query the stats of a group of users and cache the results in the interface.

Get

GetCachedStats

Retrieve the cached user stats stored after a call to QueryStats or BatchQueryStats.

Event Listening

OnStatsUpdated

An event will fire as a result of changes to user stats.

Configuration

You can use the Stats Interface with either a corresponding platform backend or a StatsNull implementation. To use the Stats Interface, you must first configure the Stats Interface in your DefaultEngine.ini file:

DefaultEngine.ini

Stat Definitions consist of the following fields:

Name: The name of the stat.

This is the name that will be used to update and query stats with UpdateStats and QueryStats respectively.

Id: The ID of the stat.

This is the corresponding configured stat ID in the platform portal.

ModifyMethod: Method prescribing how the stat will be updated.

For non-StatsNull implementations, the Modify Method is configured in the platform portal.

The Modify Method is used by the Achievements Interface on all implementations when using Title Managed achievements to determine whether an achievement meets the prescribed unlock rules.

To unlock achievements and update leaderboards with stats, you must specify corresponding stats in the Achievements and Leaderboards config sections of DefaultEngine.ini.

Examples

This section contains a variety of code examples that guide you on how to:

Query Stats

Get Cached Stats

Listen for an event

Execute a Console Command

Query Stats

Use the default online services by calling GetServices with no parameters specified:

Access the Stats Interface for the default online services:

Instantiate the parameters necessary to query the StatNames of the TargetAccountId:

Handle the QueryStats.OnComplete callback by processing the error or the queried stats:

To bind to a member function, always prefer to use a UObject-derived class or a class that inherits from TSharedFromThis and use

This automatically selects CreateUObject, CreateThreadSafeSP, or CreateSP. The safest delegate creation call will be used. For more information, refer to the Callback Format section of the Online Services Overview page.

Get Cached Stats

Use the default online services by calling GetServices with no parameters specified and access the Stats Interface:

Retrieve the cached stats through the Stats Interface with Stats->GetCachedStats:

Handle the CachedStats by processing the error or the cached stats data:

Listen for an Event

Event listening is handled differently than synchronous and asynchronous functions. An FOnlineEventDelegateHandle is created to handle the result of the OnStatsUpdated event, then Unbind must be called in your shutdown code to ensure proper destruction.

Declare an event handle in your class for the Stat interface.

In your init code, initialize the default online services, access the Stats interface, and process the stats when an event happens.

Ensure that you unbind the event handler in your shutdown code.

Execute a Console Command

For the general command-line syntax to run an async interface with a console command, refer to the Online Services Overview documentation.

To run the QueryStats function, execute the following console command:

This command calls QueryStats from the Stats Interface with the default online services for the zeroth local user. In particular, the above command queries the default online services for StatA and StatB of this user.

Reset Stats Data

During development and testing, the ResetStats function resets all provided player stats for the current title. Although policies vary across online services, you should not expect this function to work outside a testing environment. Be sure to remove any code that uses ResetStats from shipping builds, or use compile-time logic to mask the code like this:

More Information

Header File

Consult the Stats.h header file directly for more information as needed. The Stats Interface header file Stats.h is located in the directory:

For instructions on how to obtain the UE source code, refer to our documentation on Downloading Unreal Engine Source Code.

Function Parameters and Return Types

Refer to the Functions section of the Online Services Overview page for an explanation of function parameters and return types, including how to pass parameters and processing the results when functions return.

Design Philosophy

Basic Structure and Usage

Interfaces

The Online Subsystem and its interfaces provide a common way to access the functionality of online services such as Steam, Xbox Live, Facebook, and so on. When working on a game that ships on multiple platforms, or with support for multiple online services, the Online Subsystem ensures that the only changes developers need to make are configuration adjustments for each supported service.

Design Philosophy

The Online Subsystem is fundamentally designed to handle asynchronous communication with a variety of online services. Since network connection speeds, server delays, and the running times of backend services are all unknown to the local machine, interactions with these systems take an unpredictable amount of time. To deal with this, the Online Subsystem uses Delegates for all remote operations and guarantees that those Delegates will be called whenever a supported, asynchronous feature is used. In addition to providing the ability to respond to requests as they finish, and query in-flight requests. Delegates also provide a single code path to follow, removing the need for developers to write custom code to catch different success or failure conditions.

Modular, service-specific interfaces group supported features together. For example, the Friends Interface handles everything related to friends lists, the Achievements Interface handles listing, checking, and awarding Achievements, and so on. Interfaces exist for each feature group on each online service that supports it, although specific functions that a service does not support may simply return false. This design ensures that developers can write the same code for all online services.

At a higher level, more complex operations use the Online Asynchronous Task Manager to support sequential tasks, or tasks that run on different threads. Asynchronous tasks can describe their dependencies, enabling unrelated tasks to run independently and in parallel, while sequential tasks run serially. All interfaces within the Online Subsystem schedule tasks in this fashion to preserve consistency of operation.

Basic Structure and Usage

The base module, OnlineSubsystem, defines and registers service-specific modules with the Engine. During initialization, the Online Subsystem will try to load the default online service module specified in the "Engine.ini" file. All access to an online service will go through this module.

If successful, the default online subsystem will be available via the static accessor when no parameter is specified.

Additional services load on-demand, when calls to this function request them. Invalid identifiers or failures to load the module will gracefully return null.

Interfaces

The following interfaces are included in the Online Subsystem.

Some interfaces exist only for certain online services, depending on what functionality each service supports.

Interface

Feature Group Description

Achievements

Listing all achievements in a game, unlocking Achievements, and checking your own unlocked Achievements and those of other users.

External UI

Opening the built-in user interfaces for specific hardware platforms or online services. In some cases, services grant access to certain core features exclusively through this interface.

Friends

Anything related to friends and friends lists, such as adding users to your friends list, blocking and unblocking users, and listing players you have recently met online.

Leaderboard

Accessing online leaderboards, including registering your own scores (or times), and checking leaderboards for scores from your friends list or players around the world.

Online User

Collecting metadata about a user.

Presence

Setting the way that a user's online status will appear to other users, such as "Online", "Away", "Playing a game", and so on.

Purchase

Making in-game purchases and reviewing the history of past purchases.

Session

Creating, destroying, and managing online game sessions. Also includes searching for sessions and matchmaking systems.

Store

Retrieving the categories and specific offers available for in-game purchase.

User Cloud

Provides the interface for per user cloud file storage.

Voice Chat (EOS)

Using Epic Online Services as a Voice Chat provider.

Getting Achievement Data

Retrieving Achievement Data

Examining Achievement Data

Setting Achievement Data

Writing Achievement Data

Resetting Achievement Data

Achievements give developers a way to incentivize, reward, or challenge players, guide them to experience more of what the game has to offer, increase the game's replay value, or even support rivalries between players and their friends. Many online services offer the ability to award Achievements, and the Online Subsystem provides the Achievements Interface to support this.

Although the term achievements is not common to every online service, the Unreal Engine uses this term to describe this concept and its support systems.

The Online Subsystem provides in-game functionality for using the Achievement system, but does not handle functionality related to creating, deleting, or otherwise modifying the Achievements themselves. Each online service has its own backend systems to support Achievement management.

Getting Achievement Data

Achievement data includes both player-specific data, namely, which Achievements have been unlocked (or partially unlocked) by the player in question, and general data, such as what an Achievement is called, or what icon represents it.

Retrieving Achievement Data

Achievement data is available upon request through asynchronous calls to the online service. However, this data is broken into two pieces: The Achievement's ID and completion percentage for a particular player, and the Achievement's description, which is related to the Achievement itself and thus is common to all players. To receive the list of available Achievements, call QueryAchievements with the FUniqueNetId of the player whose information you want. Once your delegate (of type FOnQueryAchievementsCompleteDelegate) is called with a successful result, the Achievements' IDs and completion percentages (for that player) will be cached. Before information about these Achievements can be displayed or used effectively, you will need their full descriptions. These can be requested through FOnQueryAchievementsCompleteDelegate, which also calls a provided delegate of type FOnQueryAchievementsCompleteDelegate upon completion.

Examining Achievement Data

Once data has been cached, you can examine it with a few function calls. GetCachedAchievements is the best place to start, as it will return an array containing all known Achievement IDs. These IDs can then be used to call GetCachedAchievement with a specific player's FUniqueNetId to check that player's completion percentage for that Achievement, or as a parameter to GetCachedAchievementDescription, which will return the full Achievement description (of type FOnlineAchievementDesc).

Setting Achievement Data

Achievements can be unlocked, completely or partially, for a given user. For example, a player who completes a game might receive a "beat the game" Achievement, while a player who performs a special technique might receive a tenth of a percent of a "perform this technique 1000 times" Achievement. In addition, during testing, most online services will support resetting a player's Achievements for the game so that testers don't have to make a new account every time they want to perform a fresh test of the game.

Writing Achievement Data

The WriteAchievements function takes one or more Achievement updates and sends them to the online service, resulting in a call to a provided delegate of type FOnAchievementsWrittenDelegate upon completion. Each update is a reference type containing a single FOnlineAchievementsWrite, which acts as a wrapper around an FOnlineStats object. The key-value pairs sent through the Properties fields should contain keys matching the Achievement ID, and a float value containing the completion percentage, ranging from 0.0 to 100.0 percent. Most online services will reject attempts to change a player's completion percentage on any Achievement to an equal or lower value than what has already been recorded, so be sure to check the current completion percentage before sending an update.

Resetting Achievement Data

During development and testing, the ResetAchievements function will reset all of the provided player's Achievements for the current title. Although policies can vary between online services, this function should not be expected to work outside of a testing environment.

In Shipping builds, this function does not exist, so be sure to remove any code that calls it, or use compile-time logic to mask that code out, like this:

Setup

EOS Settings

Artifact Settings

EOS Plus Plugin Settings

Project Settings

Engine Settings

EOS Plus Settings (Optional)

EOS Voice Communications

Login

Login with OnlineSubsystemEOS

Account Portal

Developer

Exchange Code

Login successful

AutoLogin with OnlineSubsystemEOS

Login with OnlineSubsystemEOSPlus

External Authentication

Using Cross Platform User IDs

Using Epic Account Services

Epic Online Services (EOS) is an engine-agnostic system that provides a range of cross-platform online features, including: player-centric features such as achievements and leaderboards, commercial features such as the ability to purchase in-game items, and social features such as voice communication and friends lists.

Unreal Engine can help you implement EOS in your project through its Online Subsystem (OSS) plugin, without the need to write code using the EOS SDK directly. The Online Subsystem plugin provides a common interface across all exposed online services in Unreal Engine. To use this feature, developers must register and configure their products with Epic Account Services (EAS), and then enable and configure a few plugins to expose EOS functionality through the OSS interface.

For more information on EAS and EOS, please see the Epic Online Services developer documentation.

Setup

To begin leveraging EOS in your project, you must first enable the EOS OSS plugins. You can find them by going to the Edit menu and selecting Plugins to open the Plugin Browser.

Within the Plugin Browser, locate and enable Online Subsystem EOS and EOS Shared. If you want to add voice chat support through EOS, enable the EOS RTC IVoiceChat plugin as well.

After enabling the plugins, you will need to configure them. Some of the following configuration steps require product-related settings or identifiers received after registering your product with EOS.

If you have not registered your product with EOS, you can register it on the Epic Developer Portal.

EOS Settings

The following settings relate to EOS' platform-specific configuration. For more detail, see the EOS API Reference page about the Platform Options data structure.

Cache Dir: This is the location in which EOS stores temporary data.

Default Artifact Name: Games shipped on the Epic Games Store and that run through the Epic Games Launcher use an artifact name to look up settings data. This field specifies a default name.

Tick Budget in Milliseconds: This setting establishes a per-tick time limit on EOS' operations. You can remove the limit by setting this value to zero.

Enable Overlay: Use this to enable or disable all overlays. Some overlays may be platform-specific, such as the e-commerce overlay which is only valid for titles shipping on the Epic Games Store.

Enable Social Overlay: The social overlay shows information about friends, achievements, and extra authentication steps. You can disable this overlay individually while leaving other overlays enabled. This setting has no effect if Enable Overlay is turned off.

Require Being Launched by Epic Games Store: For titles that ship on the Epic Games Store, activating this setting causes the game to verify ownership before launching, and requires launching through the Epic Games Launcher. If the end user attempts to launch the game using any other method, the game's process will terminate and relaunch itself through the Epic Games Launcher.

Artifacts: The Epic Games Store supports multiple artifacts for a single product. For example, your product can have separate internal artifacts for development, testing, and for the released version that your customers use. This array contains settings for each named artifact. There must be at least one artifact in the array, and the Default Artifact Name value must match the name of one of the array elements. See Artifact Settings for more information about these settings.

Artifact settings that you configure here should match the settings for your registered product. You can find settings for your products on the Developer Portal (requires login).

Artifact Name: This is the name of the artifact. For example, MyGameStaging or MyGameRelease.

Client ID: This ID should start with "xyz" as the first 3 characters.

Client Secret: This is the password that is used to verify your Client ID.

Product ID: The EOS SDK uses this ID to identify your product.

Sandbox ID: The artifact belongs to the sandbox with this ID value. Typically, the product has only a single Sandbox ID.

Deployment ID: Deployment IDs differ for each artifact. For example, if you have MyGameStaging and MyGameRelease artifacts, they will each have their own Deployment IDs.

Encryption Key: When you upload data to an EOS service, this 64-byte hexadecimal string is used to encrypt it. Unlike other settings, EOS does not manage this Encryption Key and it is not stored in your product settings. The key is unique to your game and not known to Epic Games, to protect users' data privacy.

EOS Plus Plugin Settings

EOS Plus is an experimental OSS plugin that combines the features of the EOS SDK with those of another online platform (such as Xbox Live, PlayStation, Steam, and so on) into a single, crossplay-compatible Online Subsystem.

To use this plugin, you must first register and configure your product in the Developer Portal for each platform you want to support. The platform-specific versions of EOS SDK contain detailed instructions for using the features of the platform they support.

EOS OSS converts all stat names to uppercase before passing them to EOS. When you configure your project in the EOS Developer Portal, make sure to configure them as upper case names to ensure compatibility with EOS OSS.

Before using this plugin, you must configure the following settings:

Use Epic Account for EOS login (requires account linking): When enabled, the EOS OSS plugin will use the platform-specific authentication token to sign the user into their Epic Account automatically. This requires that the user has linked their Epic Account to their account from the other platform; if they have not, the logs will report this event as an error. You can redirect the user to the account linking page to complete this process, where they can log in and complete the account linking process on their own through the Accounts tab.

Use Crossplatform User IDs for EOS Login (doesn't use Epic Account): This setting enables EOS Connect features with the platform specific authentication token.

Mirror Stats to EOS: If this option is enabled, EOS Plus will send a duplicate of all Stats information to the EOS OSS plugin.

Mirror Achievements to EOS: If this option is activated, EOS Plus will send a duplicate of all Achievement data to the EOS OSS plugin.

Use Crossplay Sessions: This setting is required to play cross-platform network games. It also makes the EOS Sessions Interface the primary session interface.

Mirror Presence to EAS: This option determines whether the EOS Plus plugin will also send Presence data to the EOS OSS plugin. Presence data is only available when using Epic Account Services.

Project Settings

Once you have set up your product on the Developer Portal and configured the plugins, there are a few settings you need to configure in the project's DefaultEngine.ini file.

Follow these steps to configure your project to use the Online Subsystem EOS plugin:

In the [OnlineSubsystemEOS] section, verify or add the following line to ensure that the Online Subsystem EOS is enabled:

In the [OnlineSubsystem] section, verify or add the following line to ensure that EOS is your default platform:

In the [/Script/Engine.GameEngine] section, verify or add the following line to ensure that the engine will use the EOS NetDriver:

If you intend to use EOS' P2P socket functionality for player hosted matches, verify or add the following line to the [/Script/OnlineSubsystemEOS.NetDriverEOS] section:

Your DefaultEngine.ini file should now contain the following lines within their respective sections:

If you want to configure your project to implement crossplay between EOS and another online platform, make these additional modifications:

Verify that the EOS Plus plugin is enabled by looking for the following line in the [OnlineSubsystemEOSPlus] section:

In the [OnlineSubsystem] section, change your default online platform from EOS to EOSPlus, and add the name of the other online platform. In this example, we will use Steam as our second platform. When you are finished, you should have these lines:

The engine needs to know that EOS and EOSPlus network ID types are compatible in order to enable interaction between the platforms. Add the following lines to the [/Script/OnlineSubsystemUtils.OnlineEngineInterfaceImpl] section:

Your DefaultEngine.ini file should now contain the following lines within their respective sections. You may also need to replace Steam with a different online platform name:

The DefaultPlatformService setting in the [OnlineSubsystem] section replaces the value that you set earlier.

EOS Voice Communications

You can configure Lobby sessions to create a linked voice chat room. Users who join the lobby (including the lobby creator) will automatically join the voice chat room. To configure this, set both the FOnlineSessionSettings::bUseLobbiesIfAvailable and FOnlineSessionSettings::bUseLobbiesVoiceChatIfAvailable values to true.

Individual users can control their interaction with voice chat rooms using their IVoiceChatUser interface instances, which you can retrieve using FOnlineSubsystemEOS::GetVoiceChatUserInterface.

The IVoiceChatUser interface enables interaction with local hardware, online chat rooms, and other voice chat users. You can select input or output devices, change volume levels, block or mute specific users, and register for events such as players joining or leaving the channel, starting or stopping talking, and so on.

When using FOnlineSubsystemEOS::GetVoiceChatUserInterface, the system will handle the initializing, connecting, and log in automatically. However, depending on how you integrate IVoiceChat, you can still manually join and leave trusted server channels. Refer to the EOSVoiceChat plugin documentation for more information.

Login

The method to process user authentication varies depending on whether the basic OnlineSubsystemEOS Plugin is being used, or if it's being used along with OnlineSubsystemEOSPlus. There are two methods to start the login process in the Online Identity Interface.

Method

Description

AutoLogin

Requires a local user number to be passed.

Login

Requires a FOnlineAccountCredentials object.

In this next section, you will understand how to get a user logged in using both methods in both of the aforementioned plugins.

Login with OnlineSubsystemEOS

In addition to providing a valid local user number, the Login method also requires a FOnlineAccountCredentials object to be passed. This struct has three fields:

Type

Id

Token

These three fields indicate which method of authentication the OnlineSubsystemEOS Plugin should use, depending on their values. These are examples of how to set up all the different types of authentication:

Account Portal

Type: AccountPortal

Id:

Token:

With this method, a browser window will open when the Login call is made, and the user will be asked to input their epic account information. If the user is already logged in to Epic Games in that browser, they will be asked to accept the access scopes for the product in question. This method does not require Dev Auth Tool to be running.

Developer

Type: Developer

Id: localhost: (where is the port specified in Dev Auth Tool)

Token: CredentialsName

This method requires the EOS Developer Authentication Tool(Dev Auth Tool) to be running. See the following Developer Authentication Tool.

After setting up the Dev Auth Tool, remember which Port and Credentials Name you used since they will be required to fill the Id and Token fields of the FOnlineAccountCredentials object as indicated above.

This login method will open when the Login call is made, and the user will be asked to input their Epic Games account information.

If the user is already logged in to Epic Games in that browser, they will be asked to accept the access scopes for the product in question (this step will only occur the first time a user logs in).

This is the recommended method to use during development using OnlineSubsystemEOS in desktop platforms.

Exchange Code

Type: "ExchangeCode"

Id:

Token: "<exchange code>" (where <exchange code> is the exchange code provided by the Epic Launcher)

This method should only be used if the application is being launched from the Epic Launcher, as it needs the exchange code provided by it. This method does not require Dev Auth Tool to be running and is what you would use with the shipping version of your game.

Login successful

If any of these methods are completed successfully, the login process will end by registering all the necessary EOS notification services (login status, friends and own presence updates, and auth refresh) and triggering the following registered delegates:

Method

Description

OnLoginComplete

parameters include if the login was successful, and the UniqueNetId for the newly authenticated user.

OnLoginStatusChanged

parameters correspond with previous and current login status, and the UniqueNetId for the newly authenticated user.

AutoLogin with OnlineSubsystemEOS

For the AutoLogin method to work in OnlineSubsystemEOS, it requires command line parameters to be added to the game's execution, which translate directly to the three fields in the FOnlineAccountCredentials object otherwise passed to the Login method.

All three parameters need to be set for AutoLogin to work, even if some won't be used (like in the Account Portal or Exchange Code methods). The parameters are as follows:

Type = AUTH_TYPE

Id = AUTH_LOGIN

Token = AUTH_PASSWORD

Below are some examples of the parameters needed for all three login methods that explained in the previous section. If these are added to the game execution command, then the login will process successfully, however it is subject to the requirements explained in the previous section. (Dev Auth Tool, Epic Games Launcher)

Developer

ExchangeCode

Login with OnlineSubsystemEOSPlus

There is no difference between using AutoLogin and Login in OnlineSubsystemEOSPlus. Login only needs specific values to be set in the FOnlineAccountCredentials objects for a few selected platforms.

External Authentication

The login method that OnlineSubsystemEOSPlus uses to process EOS authentication is different from those used by OnlineSubsystemEOS.

It starts by making a copy of the FOnlineAccountCredentials object passed on to the Login method (in case any of the optional values were set). Then, the system will start the native platform's user login process (in case this hasn't been done already). This means logging in with the active platform account, or asking for user selection if needed on a console platform. The login process will stop if this initial platform login is not successful, triggering the registered OnLoginComplete delegates with information about the error.

After this first platform login succeeds, if any of the two settings mentioned in the previous section is enabled, EOS login is initiated with the credentials we saved at the beginning. Regardless of which was set, the first part of this new login process is the same: we will query the native platform subsystem for an external authentication token.

Using Cross Platform User IDs

If this setting is enabled and Using Epic Account Services is not, the external authentication token will be added to the set of credentials needed for the login method, and EOS will try to authenticate by calling the EOS_Connect_Login method.

Here's where some more setup in the EOS Project Dev Portal is needed. For EOS authentication to complete successfully, the platform in question needs to have been added to the Identity Providers list as described in this article. With the Identity Provider set correctly, EOS authentication should complete successfully, unlocking access to all EOS game features.

Using Epic Account Services

If this setting is enabled, the login process will continue as if Using Cross Platform User IDs were enabled too. The external authentication token will be added to the set of credentials needed for the login method, and EOS will try to authenticate by calling the EOS_Auth_Login method. This method requires an Epic Games account to be linked beforehand with the platform account that is going to be used for EOS authentication.

At the moment, Account linking during the login process is only available in the Steam platform, and attempting login in any other platform will result in the following authentication error to appear in the log:

Log Error

This functionality will be available in other platforms in future releases. In the meantime, manual account linking can be done via the Accounts tab in the Connections section of the Epic Games Account Settings.

The Epic account that was used in the linking process needs to accept the application access scopes (as described in the section Login with OnlineSubsystemEOS) or this other error will appear in the log:

Log Error

Once the account is linked, and the access scopes accepted, and if EOS authentication has been configured properly as well, login will complete successfully and the application will be able to use all of EAS' additional features.

Using External User Interfaces

Showing a Message Box

Viewing a User Profile

Logging In

Using the Friends List

Sending an Invitation

Sending a Message to Another User

Viewing Achievements

Creating or Upgrading an Account

Visiting the Store

Visiting External Websites

Some online services, especially those which run on proprietary devices such as game consoles, have built-in, standardized user interfaces that they bring up whenever certain operations are launched. For example, adding a friend, sending an invitation to join a match, or registering a credit card may bring up a game-independent form, overlay, screen, or workflow that the user must navigate to access that feature. This is generally done to ensure that certain sensitive interactions are always handled the same way, and are controlled by the company that owns the online service, rather than individual third-party developers. These features are also not standard across every online service, and in some cases, may only exist on one particular service or system. To handle these disparate features, the Online Subsystem collects them all and provides the External UI Interface to interact with them.

Using External User Interfaces

External user interfaces will notify the Online Subsystem when they close by calling various delegates specific to the External UI Interface. In addition, changes that they make may result in calls to delegates from other parts of the Online Subsystem, such as the Login Interface. Because any given function of the External UI Interface is likely not to be implemented on most online services, it is important to pay attention to the return values of these functions. A return value of false indicates that the given user function is not supported on the current online service, or otherwise failed to open. This type of failure will not cause any delegates to be called, as there is no operation to perform.

Showing a Message Box

If you wish to display a message in the platform's built-in style, call ShowPlatformMessageBox. This is commonly done to show "system" messages (as opposed to "game" messages), such as informing users of patches or other updates, or providing feedback on errors like trying to activate multiplayer-only features while offline. This operation does not fire a delegate when complete.

Viewing a User Profile

To view the user profile overlay, call ShowProfileUI with the FUniqueNetId of the user requesting to see the profile, and the user who owns the profile. When overlay closes, your provided delegate (of type FOnProfileUIClosedDelegate) will be called.

Logging In

While the Identity Interface is the usual place to handle authentication functionality, certain platforms may require that you go through their user interface flow, or it may simply be more convenient (and more consistent) than writing your own login user interface flow. The ShowLoginUI will use the current online service's standard login UI, if it exists. When the user closes the interface, a provided delegate of type FOnLoginUIClosedDelegate will be called. Changes to the user's login status will still call delegates through the Identity Interface.

Using the Friends List

The ShowFriendsUI will bring up the Friends list, if the online service includes a built-in feature to do so. For more direct interaction with the Friends list, refer to the Friends Interface page. Changes made by the user through the external Friends list UI will still result in calls to the appropriate Friends Interface delegates.

Sending an Invitation

To display the built-in UI that provides a list of friends to invite to a game session, call ShowInviteUI with the name of the session. For more information, refer to the Sessions and Matchmaking page.

Sending a Message to Another User

On services that provide a "mailbox" feature, ShowSendMessageUI will open the UI to send a message. A delegate of type FOnShowSendMessageUIClosedDelegate can be provided, and will be called when the message UI closes. A provided FShowSendMessageParams parameter will initialize the interface.

Viewing Achievements

The ShowAchievementsUI function, called with the local user's index, will bring up the built-in interface to review the specified local user's unlocked achievements and compare them with other users. To manage a user's Achievements, use the Achievements Interface.

Creating or Upgrading an Account

Some online services, particularly on consoles, feature the ability to create and upgrade accounts without going to their websites. To open the user interfaces for these features, use ShowAccountCreationUI and ShowAccountUpgradeUI. ShowAccountCreationUI will call a provided FOnAccountCreationUIClosedDelegate upon completion.

Visiting the Store

ShowStoreUI takes a user to the online service's store. If supported by the online service, developers can also provide a category to browse or a particular product to view within the store by specifying the category name or product ID in an FShowStoreParams data structure. When the store UI closes, your provided delegate (of type FOnShowStoreUIClosedDelegate) will be called.

Visiting External Websites

If your game sends users to an external website, you can use ShowWebURL to open the site within the system's default browser, and CloseWebURL to close the site when the game determines that the user no longer needs to view the site. When the site closes, either by user or as the result of a call to CloseWebURL, the FOnShowWebUrlClosedDelegate that was provided to the ShowWebURL function will be called.

When calling ShowWebURL, you can specify much more than just the URL to open. See the API page for FShowWebUrlParams for further information.

Managing Friends

Retrieving Friends Lists

Examining Friends Lists

Inviting a Friend

Accepting or Rejecting an Invitation

Deleting a Friends List

Deleting a Friend

Dealing with Players Met Online

Retrieving the List of Recently-Met Players

Examining Recently-Met Players

Managing the Block List

Listing Currently-Blocked Users

Blocking and Unblocking Users

Playing games with your friends and meeting new players online is an important part of many online services. The Friends Interface contains features to manage a user's list of social contacts, including adding, removing, and blocking other users.

Managing Friends

Friends lists are stored on the online service's servers, and can change during a session as friends are added or removed, join and leave games and sessions, or log in and out of the service. As a result, managing these lists involves querying the server for the latest information, then caching that information and using it in your game.

Retrieving Friends Lists

The first step in dealing with a user's friends lists is generally to call ReadFriendsList, which retrieves the most up-to-date version of a named friends list belonging to a specified local user. Valid list names can be found in the EFriendsList enumerated type, and can be converted into strings by the provided ToString`function. Because it queries a remote machine, the ReadFriendsList is asynchronous and will call a delegate of type FOnReadFriendsListComplete` when complete.

On success, this call caches the list so that it can be examined later without repeatedly querying the remote machine, or requiring developers to write their own caching code. It also updates presence status data for the users on the list. The data returned by FOnReadFriendsListComplete only contains information regarding the success or failure of the ReadFriendsList operation.

Examining Friends Lists

After a successful call to ReadFriendsList retrieves and caches a list, developers can use GetFriendsList to get a copy of the list itself, or GetFriend to retrieve an individual friend from the list. In addition, a known user's FUniqueNetId can be passed to the IsFriend function to check a specified list for that user.

Friends lists can change at any time, both from in-game events like meeting new players, and from out-of-game events like the user modifying the account from a separate system. Calling ReadFriendsList to keep the cached lists up-to-date should be considered.

Inviting a Friend

The SendInvite function will send an invitation to another user, identified by that user's FUniqueNetId. Upon acceptance, the user will be added to the specified list by the online service. A delegate of type FOnSendInviteComplete will be called when this operation finishes, but this only means that the invitation has been sent (or has failed to send), not that the intended recipient has received or responded to it. Some online services may have custom user interfaces for sending invitations, and these may open automatically when SendInvite is called.

All SendInvite calls will eventually trigger the FOnSendInviteComplete delegate. This includes cases where an external UI is opened and the user cancels it.

Accepting or Rejecting an Invitation

When an invitation from another user has arrived, a delegate of type FOnInviteReceivedDelegate will be called, containing the FUniqueNetId of the sender and the recipient. The invited user can then call AcceptInvite or RejectInvite to respond, specifying the name of the list where the new friend should appear. AcceptInvite uses a delegate of type FOnAcceptInviteComplete to communicate the results of the operation, while RejectInvite uses an FOnRejectInviteComplete delegate.

Deleting a Friends List

The online service can be instructed to delete a friends list through the asynchronous DeleteFriendsList function. When complete, a delegate of type FOnDeleteFriendsListComplete will be called.

Deleting a Friend

To remove a friend from a list belonging to a local user, call the DeleteFriend function. When the operation is complete, a delegate of type FOnDeleteFriendComplete will be called. It may be possible for a friend to exist in multiple lists on some online services; if this is the case, this function will only remove the friend from the specified list.

Dealing with Players Met Online

Online services often keep a separate list of players that a user has encountered recently, such as in a public gaming session, but has not added to the friends list or blocked. Like friends lists, the list of recently-met players is handled by querying the online service and then caching the list.

Retrieving the List of Recently-Met Players

The QueryRecentPlayers makes an asynchronous call to the online service, calling a delegate of type FOnQueryRecentPlayersComplete upon completion. If successful, the Friends Interface will cache the list locally.

Examining Recently-Met Players

Once a successful call to QueryRecentPlayers has retrieved the list of recently-met players, the GetRecentPlayers function will return the cached array. The individual elements of the array contain the user's data as well as a function to tell when the player was last seen online.

Managing the Block List

Many online services provide the ability for a user to prevent specific other users from contacting or playing with them through the service. The Friends Interface can retrieve and cache a list of blocked users, as well as utilize the online service's block and unblock features.

Listing Currently-Blocked Users

To retrieve the list of blocked users, call the QueryBlockedPlayers function. This function is asynchronous, and will call a delegate of type FOnQueryBlockedPlayersComplete when it completes. In addition, any changes made to the list of blocked users will result in notification through an FOnBlockListChange delegate.

Blocking and Unblocking Users

The BlockPlayer and UnblockPlayer functions will make asynchronous calls to the online service, requesting that a specific player, identified by an FUniqueNetId, be blocked or unblocked by a local player. When these operations complete, they will return success or failure information through delegates of type FOnBlockedPlayerComplete and FOnUnblockedPlayerComplete, respectively.

Authentication Functions

Login

Logout

Checking Current Login Status

Player Identification And Information

Converting Between Identity Systems

User Account Information

Retrieving Locally-Known Accounts

Player Display Names

User Privilege

Connecting to game sessions and interacting with other players over the Internet usually requires logging in to a registered account on a third-party online service. These services can be run by social media sites, hardware platform owners, or gaming services. In Unreal Engine (UE), the Identity Interface handles account-related interactions with these services, providing the ability to authenticate users and obtain access tokens.

Authentication Functions

Login

The Login function takes a local player's account credentials (FOnlineAccountCredentials) and attempts to login to an online service. To generate account credentials automatically, or from command-line arguments, the AutoLogin function can be called instead. Once the online service responds, whether the login attempt succeeds or fails, the FOnLoginCompleteDelegate will be called. In addition, the FOnLoginStatusChangedDelegate will be called whenever login status for a specific local player changes.

Each local user logs in separately. This is especially important in games with local multiplayer, so that players can compete online, earn scores for leaderboards, invite friends, and earn achievements under their own individual account names.

If a call to Login fails, the ExternalUI interface can help by giving the user a chance to log in manually through the online service's built-in user interface. Not all online platforms use FOnlineAccountCredentials as part of their authentication process; in some cases, the built-in user interface may be the only supported way to log in.

Logout

To log a user out of an online service, use the Logout function. When the action has completed, FOnLogoutCompleteDelegate will be called. In addition, the FOnLoginStatusChangedDelegate will be called whenever login status for a specific local player changes.

Checking Current Login Status

A local player can be logged in online, logged into a local profile (but not online), or not logged in at all. To find the player's current status, use the GetLoginStatus function. Since login status is determined based on the most recent communication with the online service, there are no delegates to bind. However, if you are waiting for a specific status change, such as the player logging in, and don't want to poll this function periodically, binding FOnLoginStatusChangedDelegate can help.

On some systems, users can reassign physical input devices to different players, which will change their local player index values within the Unreal Engine. This can switch the local user index values of logged-in users without actually changing any user's login status. The OnControllerPairingChanged delegate will be called in this case, providing the controller's index and the FUniqueNetId values of the users involved.

Player Identification And Information

Converting Between Identity Systems

Within Unreal Engine's networking environment, an opaque FUniqueNetId value is associated with a local player automatically upon a successful login attempt. In addition to being used throughout Unreal Engine's networking code, it also serves as an abstraction for the proprietary identity data types of each online service.

If you need to replicate a user's FUniqueNetId, FUniqueNetIdRepl provides a ToString method that converts an FUniqueNetId to a replication-safe string, which can then be converted back by CreateUniquePlayerId.

The Identity Interface has a few functions that can bridge the gap between these different systems and identity types. You can retrieve a player's FUniqueNetId either by calling CreateUniquePlayerId with that player's service-specific identity, or through GetUniquePlayerId, called with the player's local user index. Using the player's FUniqueNetId, you can call GetPlatformUserIdFromUniqueNetId to get the player's service-specific identity (of type FPlatformUserId), although this should not be needed in most cases. All of these functions use locally-available information, and thus there are no delegates or callbacks involved.

The GetSponsorUniquePlayerId will return the sponsoring player's FUniqueNetId, but this function is only implemented for the Xbox Live service.

User Account Information

The abstract class, FOnlineUser, represents the base information for user accounts related to any online subsystem, and serves as the common interface for accessing publicly-visible information for local or remote users. An extension of this class, FUserOnlineAccount, provides access to all available information for local, logged-in users.

In some cases, an online system's FOnlineUser child class may be extended to suit the needs of a specific online service. The base class supports functionality for returning the user's FUniqueNetId, real and displayed name (depending on the online service being used), and any string-based attributes that may be associated with the user, although storing these attributes must be implemented in child classes.

The FUserOnlineAccount class is also abstract, but establishes a framework for setting user attributes and storing metadata about a local, logged-in user, including a service-specific access token or other data. Some subsystems use these tokens to access features, and you can use them to make RESTful calls, or coordinate with your own backend services.

Retrieving Locally-Known Accounts

Many online services keep track of user accounts that have logged in from (or were created on) the local machine. For services that do this, the function GetAllUserAccounts will be implemented to return an array listing all of these known accounts. These accounts will be returned as FUserOnlineAccount data. In order to see if a specific player is on the list, GetUserAccount can be called to map the player's FUniqueNetId to a known FUserOnlineAccount, if one is present in the list.

Player Display Names

Some online services provide the option for users to enter "display names" or "nicknames" that differ from their account login names. This name may be preferred over the account name for use in your game's chat, scoreboard, character labels, or similar user-facing displays. Using a player's FOnlineUser, call GetDisplayName to retrieve that player's display name or nickname from locally-cached user account data.

User Privilege

Online services can act as a gateway, granting or denying access to certain online features, most notably the ability to play games online with other service users. The GetUserPrivilege function reports whether or not a user has a specific privilege (defined in EUserPrivileges). This function requires contacting the online service, and will respond to user requests through FOnGetUserPrivilegeCompleteDelegate, returning a result of type EPrivilegeResults.

Scoring Methods

Retrieving Leaderboard Data

Uploading Leaderboard Data

Leaderboards give players a way to compete with their friends or the rest of the world for the top score in your game. Games can feature multiple modes that award scores, and each mode can have its own leaderboard. Scoring modes can be ranked highest-to-lowest, as in traditional point-based games, or lowest-to-highest, such as in timed or racing games. The Leaderboard Interface provides developers with the tools they need to display and update leaderboards from within their games.

Scoring Methods

There are three different aspects to defining the way a leaderboard treats scores, each defined within an enumerated type.

ELeaderboardSort dictates whether scores are sorted at all, and if so, if they are in ascending or descending order.

ELeaderboardFormat controls formatting. Scores can be raw numbers (like points), or time, either in seconds or milliseconds.

ELeaderboardUpdateMethod indicates whether the leaderboard should keep a player's most recent score, or that player's best score (according to the sorting method).

Retrieving Leaderboard Data

Leaderboard data can be fairly large, as there may be an entry in each leaderboard your game supports for each user account that has ever played. For this reason, retrieval is done in chunks, and games can request portions of the leaderboard in a few different ways. All methods of retrieving leaderboard data will take a parameter of type FOnlineLeaderboardRead (see FOnlineLeaderboardRead for the relevant data type) that holds the definitions of the tables you want the online service to send back, and will call a delegate of type FOnLeaderboardReadComplete with a bool to indicate success or failure upon completion. The following querying options are supported:

Function

Query Description

ReadLeaderboards

Takes an explicit list of users (by FUniqueId) and requests the leaderboard scores for only those users.

ReadLeaderboardsForFriends

Given a local user index, find the leaderboard scores for each of that user's friends.

ReadLeaderboardsAroundRank

Accepts a rank and a range, useful for browsing the list of the top players worldwide. The request will retrieve the leaderboard scores above and below that rank by the range. For example, rank 100 and range 50 would request the records for the 50th to 150th ranked players.

ReadLeaderboardsAroundUser

Similar to ReadLeaderboardsAroundRank, but replaces the explicit rank with a user's FUniqueNetId, and finds the records within the specified range of that user's rank. This method is convenient for showing a player where they stand in the global rankings without making multiple calls.

Uploading Leaderboard Data

To write a score for an individual player, use WriteLeaderboards to cache an update (of type FOnlineLeaderboardWrite) that will later be transmitted to the online service. Each FOnlineLeaderboardWrite object is associated with a session name and a player (identified by an FUniqueNetId). When the game is ready to commit the session data to the online service's records, FlushLeaderboards will send the cached data and clear it from the local system, calling the Online Subsystem's OnLeaderboardFlushComplete delegate upon completion.

Only five updates can be cached by WriteLeaderboards at a time. Any updates beyond that will be discarded, so be sure to call FlushLeaderboards before that happens.

Presence Status

Defining Presence

Retrieving Information About Other Users

Setting a User's Presence

When logged into an online service, users can often see information about their friends and other users they've met online, such as whether these users are online, what they're doing, if they're available to join matches, and so on. The Presence Interface provides the Online Subsystem with access to these features.

Presence Status

Most online services recognize several basic presence states for each user, such as "online", "offline", and "away", as well as game-specific states like "In the lobby" or "Playing a match on (Map)". However, these settings are not always visible, or may be visible to some users but not others, due to service-specific privacy policies and account settings. The Online Subsystem does not interact with these policies or settings, but the information that it retrieves will be affected by them.

Defining Presence

The FOnlineUserPresence class contains all information related to a user's presence. In addition to basic information like whether or not the user is currently online, and whether or not the user is playing a game, the user's presence (using the FOnlineUserPresenceStatus class) stores more in-depth information. This generally includes a localized string for display, an enumerated value (of type EOnlinePresenceState) to describe the user's basic state, and a set of key-value pairs to hold any game-specific custom data, which can be used when building the exact presence display message.

Retrieving Information About Other Users

The basic flow for collecting presence information about a specific user begins with making a request to the online service through QueryPresence, specifying that user by FUniqueNetId. Once that operation finishes, the provided FOnPresenceTaskCompleteDelegate will be called, indicating the user and whether the request succeeded or failed. If successful, the local presence information cache will contain up-to-date presence information, which is available through the GetCachedPresence function.

Some online services proactively notify the Online Subsystem about user presence. On these services, although you don't actually have to call QueryPresence or wait for its delegate, the usual code flow should remain unchanged so that it will work across multiple services.

Setting a User's Presence

The SetPresence function sets the presence status of a local user through the online service. This is an asynchronous call due to the need to verify the new status with the online service, and a delegate of type FOnPresenceTaskCompleteDelegate will be called upon completion. Presence status itself is described by the FOnlineUserPresenceStatus class.

In-Game Purchases

Ability to Purchase

Making a Purchase

Reviewing Past Purchases

Two interfaces power your game's ability to support user purchases: The Store Interface, which provides the ability to make offers to your users, and the Purchase Interface, which enables users to accept these offers. With the Purchase Interface, you can:

Check to see whether a user is able to make purchases.

Begin the process of purchasing.

See the history of past purchases.

To retrieve or filter a list of available offers that a user might purchase, use the Store Interface.

In-Game Purchases

Purchases (in the sense of the Purchase Interface) involve the transfer of real money—not in-game currency—in exchange for access to in-game items or content. However, the Purchase Interface itself does not handle financial details like taking credit card information or setting up parental controls. Instead, those details are left to the online service. The Purchase Interface checks for user ability to make purchases, starts the process of purchases, and can check with the online service to get a list of previously-made purchases.

Ability to Purchase

Before attempting to make a purchase, you can check to see if the user is able to do so. Some online services have account restriction features, such as parental controls, that prevent users from making purchases. You can check this information before showing offers to the user, so that you can hide or alter buttons in your user interface, or provide error messages if the user attempts to buy something without the ability to do so. To check whether a user is able to make purchases, use the IsAllowedToPurchase function. The Online Subsystem will have already cached this information, so this function returns a bool directly rather than using a delegate.

Making a Purchase

Once you're ready to make a purchase, and have selected an offer (as defined in the Store Interface), call the Checkout function with an FPurchaseCheckoutRequest. This will generally bring up a user interface specific to the online service, and will eventually call your provided delegate, of type FOnPurchaseCheckoutComplete. The delegate will contain success or failure information, and, if the purchase succeeded, a purchase receipt (class FPurchaseReceipt).

The purchase receipt contains the offer or offers that the user has purchased, using the FReceiptOfferEntry data structure. Within each FReceiptOfferEntry there are one or more line items (type FLineItemInfo), each containing an opaque string generated by the online service, and referring to one specific transaction that has been taken place. Once the item has been unlocked, credited to the user, or does whatever it does in the game, a call to FinalizePurchase with this ID string will confirm the sale with the online service and perform the transfer of funds.

Be sure that you have given the item to the user and saved it to their account (if appropriate) before calling FinalizePurchase. On some platforms, failure to do this can result in your game charging a user real-world money for an item they do not receive.

Reviewing Past Purchases

Past purchases can be reviewed by looking over the user's receipts. Call QueryReceipts, which will request the receipts for a specific user. When complete, a user-provided delegate of type FOnQueryReceiptsComplete will receive the resulting success or failure information. Upon success, receipts for the user account will be cached locally and can be accessed through the GetReceipts function in the form of an array of FPurchaseReceipt elements. This list will include a list of all non-consumable purchases, as well as pending purchases of consumables.

Session Interface

Session Settings

Session Management

Creating Sessions

Updating Sessions

Destroying Sessions

Matchmaking - Finding sessions

Searching Sessions

Cloud-Based Matchmaking

Following and Inviting Friends

Joining Sessions

Matchmaking is the process of matching players with sessions. A session is basically an instance of the game running on the server with a given set of properties which is either advertised so that it can be found and joined by players wanting to play the game or private so only players who are invited or notified of it in some way can join.

Picture an online game lobby that lists all of the games currently being played. Each game in the list is a session, or individual online match. Players are matched with sessions either by searching or some other means and then join the session to play the match.

The basic lifetime of a session is:

Create a new session with desired settings

Wait for players to request to join the match

Register players who want to join

Start the Session

Play the match

End Session

Unregister the players

Either:

Update the Session if you want to change the type of match and go back to waiting for players to join

Destroy the Session

Session Interface

The Session Interface, IOnlineSession, provides platform-specific functionality for setting up the pieces behind the scenes that are necessary in order to perform matchmaking as well as other methods of allowing players to find and join online games. This includes session management, finding sessions though search or other means, as well as joining and leaving those sessions. The session interface is created and owned by the OnlineSubsystem. This means it only exists on the server.

There is one session interface class per platform. When adding support for a new platform, a new type of session interface must be created. Platforms, in this sense, refer to hardware platforms. As such, only one session interface will ever exist at a time - the session interface for the platform the engine is currently running on.

While the session interface performs all of the session handling, the game doesn't generally interact directly with it. Instead, the Game Session, AGameSession, acts as a game-specific wrapper around the session interface and the game code makes calls to it when it needs to interact with the session. The game session is created and owned by the game mode, AGameModeBase, and also only exists on the server when running an online game.

Each game can potentially have multiple game session types, but only one will ever be used at a time. The most common case for a game having more than one type of game session is to add a type of game session for when the game is using a dedicated server.

Session Settings

The Session Settings, defined by the FOnlineSessionSettings class, are a set of properties that determine the characteristics of the session. In the base implementation, these are things like:

Number of players allowed

Is the session advertised or private

Is the session a LAN match

Is the server dedicated or player-hosted

Are invites allowed

Etc.

Using the online game lobby example, each of those games is a session and has its own session settings. For example, some sessions may be player versus player (PvP) while others are cooperative multiplayer (Co-Op). Different sessions could be playing different maps or playlists, or require different numbers of players, etc.

Session Management

One of the main duties of the session interface is session management, including session setup, updating, and destruction.

Creating Sessions

In order for players to find a session and potentially join it, you need to create a session and set up its properties, as well as decide which of those properties will be visible so they can be searched.

Sessions are created using IOnlineSession::CreateSession() which takes in a set of session settings that are used to configure the new session. Once the session is created, the OnCreateSessionComplete delegate is fired.

Updating Sessions

Updating a session is done when you want to change the settings of an existing session and is performed using the IOnlineSession::UpdateSession() function. For example, the session may be set up currently to only allow 8 players, while it needs to allow 12 players for the next match. To update the session, UpdateSession() would be called, passing it new session settings that specify a 12 player maximum.

When the request to update a session has completed, the OnUpdateSessionComplete delegate is fired. This provides an opportunity to perform any configuration or initialization necessary to handle the session settings changing.

Updating a session is generally performed between matches on the server, but it is also performed on the client in order to keep the session information in sync.

Destroying Sessions

When a session ends and is no longer needed, the session is destroyed using the IOnlineSession::DestroySession() function. When the destruction operation has completed, the OnDestroySessionComplete delegate is fired enabling you to perform cleanup operations.

Matchmaking - Finding sessions

The Online Subsystem provides the basic building blocks necessary to match players up to active sessions. It does not provide any specific type of matchmaking built-in with the base implementation. However, implementations on platforms that provide matchmaking services do expose access to those services. This is essentially the process of finding a session for the player to join. Once that session is found, the player can join the session.

Searching Sessions

The simplest way to find sessions is to search for sessions that match some desired subset of settings. This could be in response to the player choosing a collection of filters in a user interface, or it could be done automatically behind the scenes based on the player's skill and other factors, or it could be a combination of both methods.

The most basic form of searching for sessions is the classic server browser that shows all available games and allows the player to filter those based on the type of game they want to play and then choose one to join one of the sessions that match those criteria.

To search for sessions, use IOnlineSession::FindSessions() and pass it a reference to the session settings to search for as an FOnlineSessionSearch object. The SearchResults member of the session settings reference is populated with the matching sessions. When the search is completed, the OnFindSessionsComplete delegate is fired. From this delegate, you can iterate through the search results.

Cloud-Based Matchmaking

Cloud-based matchmaking refers to built-in matchmaking services that are available, and are generally platform-specific. An example of this type of service is the TrueSkill system available through Microsoft's Xbox Live service.

To initiate matchmaking on platforms that support it, you call IOnlineSession::Startmatchmaking() and pass it the controller number of the player to matchmake for, the session name, session settings to use if creating a new session, and settings to search against. The OnMatchmakingComplete delegate is fired when matchmaking is complete. This provides a bool specifying whether the process was successful and the name of the session to join in that case.

A matchmaking action in process can be canceled by calling IOnlineSession::CancelMatchmaking() and passing it the controller number of the player and the session name that was passed to the call to start matchmaking in the first place. The OnCancelMatchmakingComplete delegate is fired when the cancel operation is completed.

Following and Inviting Friends

On platforms that support the concept of friends, players can follow friends into a session or invite friends to join them in a session.

Following a friend into a session is done by calling IOnlineSession:FindFriendSession() and passing it the number of the local player that wants to join the session and the ID of the friend already in the session. The OnFindFriendSessionComplete delegate is fired when the session is found and it contains a search result that can be used to join the session.

A player can also invite one or more friends to join them in their current session using IOnlineSession:SendSessionInviteToFriend() or IOnlineSession::SendSessionInviteToFriends() and passing in the local player number, session name, and ID(s) of the player(s) to be invited. When a friend accepts an invitation, the OnSessionUserInviteAccepted delegate containing the search result of the session to join is fired.

Joining Sessions

Once you have determined a session for the player to join, the process of joining is initiated by calling IOnlineSession::JoinSession() and passing it the number of the player and the name and search result of the session to join. When the joining process completes, the OnJoinSessionComplete delegate is fired. This is where the logic to get the player into the match is performed. First, you need to call IOnlineSession::GetResolvedConnectString() which returns the platform specific connection information needed to join the match. The string obtained from this function can then be passed to APlayerController::ClientTravel() or UWorld::Servertravel() to send the player into the match.

Meeting Valve's Requirements

Downloading Steamworks

Setting up the Steamworks SDK

Steam App ID

Shipping Builds

Configuring your Application's Settings

Steps

Using Sessions

End Result

Finished Settings

Servers and Lobbies

Lobby Details

Server Details

Steam Online Authentication

Enabling SteamAuth

SteamAuth Delegates

Additional Notes

Using IPNetDriver

Module Setup

Steam Overlay on Mac

Choose your operating system:

Windows

macOS

Linux

Contributors: Valve

The Online Subsystem Steam API enables you to ship Unreal Engine (UE) applications to Valve's Steam platform. The main purpose of the Steam module is to help you distribute your application with a set of features (such as matchmaking and leaderboards) to Steam users. Additionally, the Steam module implements several of the interfaces being exposed by the Online Subsystem, supporting most of what is offered by the Steamworks Software Development Kit (SDK).

Some of the available Steam Interfaces include:

Matchmaking (Lobbies and GameServer APIs)

Leaderboards

Achievements

Voice

UserCloud

SharedCloud

External UI

Reference our Online Subsystem Steam API Reference for a more complete listing of currently available Steam Interfaces.

Meeting Valve's Requirements

The Steam Subsystem requires additional setup through Valve Steamworks. Please contact Valve and reference their Steamworks SDK Documentation to make sure that your application meets Valve's requirements before attempting to use Steam with UE.

Downloading Steamworks

If your application meets Valve's requirements, go ahead and download the latest version of the Steamworks SDK. The SDK needs to be unzipped and copied to /YourUnrealEnginePath/Engine/Source/ThirdParty/Steamworks/Steam[Current Version]/sdk

If you're updating your project's Steamworks SDK, make sure to update the [Current Version] in your project's Steamworks path:/YourUnrealEnginePath/Engine/Source/ThirdParty/Steamworks/Steam[Current Version]/sdkYou'll also need to update Steamworks.build.cs, which is located in the project directory. In this example, the [Current Version] is formatted as v139.

Setting up the Steamworks SDK

Using Steam against the precompiled version of the engine should only require copying some of the dynamically linked libraries from Valve's SDK into the appropriate folders. If you intend to recompile the engine against the source, putting the SDK in the right place is required as well. Now, copy the relevant redistributable files from the /redistributable_bin/ directory of the SDK to the following locations:

Some of the 64 bit libraries can be found in your Steam client directory (at the time of this writing, Valve didn't include all of the libraries in the SDK).

/YourUnrealEnginePath/Engine/Binaries/ThirdParty/Steamworks/Steam[Current Version]/Win64

steam_api64.dll

steamclient64.dll

tier0_s64.dll

vstdlib_s64.dll

/YourUnrealEnginePath/Engine/Binaries/ThirdParty/Steamworks/Steam[Current Version]/Win32

steam_api.dll

steamclient.dll

tier0_s.dll

vstdlib_s.dll

Both tier0_s.dll and vstdlib_s.dll files are only required when explicitly linking against them using the "-force_steamclient_link" flag for dedicated server builds. Client builds never need these files.

In UE version 4.22 and earlier: /YourUnrealEnginePath/EngineOrGameFolder/Binaries/Mac/YourGame.app/Contents/MacOS

libsteam_api.dylib (from /redistributable_bin/osx32 - the dynamic library (*.dylib) has both 32 and 64 bit support)

Starting in UE version 4.23, Mac users must also run the following command: /YourUnrealEnginePath/Engine/Binaries/ThirdParty/Steamworks/Steam[Current Version]/Mac/

libsteam_api.dylib, generated by running the following command:

install_name_tool -id @rpath/libsteam_api.dylib /redistributable_bin/osx32/libsteam_api.dylib

Linux users must link and ship the following files alongside the executable.

/YourUnrealEnginePath/Engine/Binaries/ThirdParty/Steamworks/Steam[Current Version]/i686-unknown-linux-gnu/libsteam_api.so

redistibutable_bin/linux32/libsteam_api.so

/YourUnrealEnginePath/Engine/Binaries/ThirdParty/Steamworks/Steam[Current Version]/x86_64-unknown-linux-gnu/libsteam_api.so

redistibutable_bin/linux64/libsteam_api.so

Steam App ID

All games using the Steam Online Subsystem must have a valid application ID because the Steamworks API won't initialize if it doesn't know your application's Steam App ID. Before initializing Steam, UE will generate steam_appid.txt (during a graceful shutdown of the engine, UE deletes this file). It's important to note that steam_appid.txt must be located in the same directory as your application's executable file because Steam will look for the text file in the current working directory. Additionally, the file should not be included in any Steam images.

If you open steam_appid.txt, you'll see a SteamDevAppId entry, which is a field that hints your application's ID to Steam. This makes it unnecessary to launch the game using the Steam client (although it must be running).

If you want to test your application, you can use a SteamDevAppId of 480, which is a test App ID that is shared by all developers. Although you can test most Steam Interfaces with the aforementioned test App ID, your application will need a Steam App ID before being shipped.

Shipping Builds

In shipping builds, the engine will check to make sure that the logged-in user is properly subscribed to the game and will shutdown if the engine's test returns false (this is one way to help secure the game). Additionally, using Steam DRM (see the Steamworks SDK) should further protect the game from being tampered with.

Configuring your Application's Settings

If you're creating a new project using the Unreal Project Browser, Online Subsystem settings shouldn't exist in DefaultEngine.ini; however, if you're modifying one of our Sample Projects, the Online Subsystem settings might already exist.

Now that you've set up the Steamworks SDK for your application (along with setting up the Steam App ID), you're ready to configure your application's settings to use Online Subsystem Steam.

Steps

Open your project's DefaultEngine.ini file and add the following setting:

NetDriverDefinitions describes the net drivers available to UE with the following properties being defined:

DefName is the unique name of this net driver definition.

DriverClassName is the class name of the primary net driver.

DriverClassNameFallBack is the class name of the fallback net driver if the primary net driver class fails to initialize.

To tell UE to use Online Subsystem Steam, add the following setting:

Now that you've told UE that you want your application to use the Steam Online Subsystem, you'll need to configure the OnlineSubsystemSteam module by adding the following settings:

Specify the Steam class to the Net Driver for the application's connections:

After this, the next steps depend on whether you are using Sessions or Lobbies for your game.

Using Sessions

If you are using Sessions in your game, add the following under OnlineSubsystemSteam:

If you are using Lobbies, you do not need to set this value.

You need to enable the bInitServerOnClient setting for users to be able to create and join sessions. If you do not enable this setting, the Steam online subsystem will not initialize correctly. The Create Session Blueprint node and equivalent C++ functions will not work, and you will not be able to join sessions.

End Result

At the end of this brief guide, your application's DefaultEngine.ini file should look like the following setting block. If you want to see how other projects set up and use the Online Subsystem, please refer to our library of Sample Projects.

DefaultEngine.ini

Servers and Lobbies

Steam supports peer-to-peer matchmaking (for both dedicated and listen server games) through lobbies, and provides the ability to run dedicated servers. Lobbies give users the ability to learn information about game servers, and are usually used to convey game-specific information about listen server games, such as what map or mode is being played. Users can also see the number of other users connected to a lobby without joining, through the matchmaking system. Dedicated servers are separate binaries from lobbies, as their task is to run and host the server-side portion of the game. For more information about Steam's features, implementation, or developer interface, please refer to the partner documentation on the Steam site.

Lobby Details

Lobbies are essentially chat rooms that exist as peer-to-peer instances on Steam's backend service. Unlike servers, no information about a lobby is available before joining, such as ping times or current number of other users. They are typically used for listen servers. To set up a lobby, set the bUsesPresence flag and the bUseLobbiesIfAvailable flag to true. You can set these in the FOnlineSessionSettings object passed to the IOnlineSession::CreateSession method in your C++ code.

Server Details

To set up a server instance, make sure the bUsesPresence flag is false. Dedicated servers require the following three macros, and all three must match the values from Steam's dedicated server tool page, found on the partner panel. The Steam network will not show the dedicated server if these values do not match:

UE Macro

Steam Name

Description

UE_PROJECT_STEAMPRODUCTNAME

STEAMPRODUCTNAME

Valve recommends that this be a build ID, although it is typical to use your AppID (as a string), or a light product name without any extra symbols.

Changing this field, such as when updating your build ID, will cause Steam to ignore all active servers with the old name for matchmaking purposes, and will require you to modify your tool information in the partner backend.



UE_PROJECT_STEAMGAMEDIR

STEAMGAMEDIR

This is usually the folder name of your game, and cannot contain spaces or symbols. It is not required for this to be a folder name at all, as long as it is a name without spaces or symbols.

UE_PROJECT_STEAMGAMEDESC

STEAMGAMEDESC

Valve recommends that you set this as the full name of your product.

UE_PROJECT_STEAMSHIPPINGID

N/A

To launch outside of Steam in UE version 4.22 and higher, this macro must contain the product's Steam ID.

In UE version 4.22, you can specify these values in your game's Target.cs file. You can also write the Steam ID into a build by defining UE_PROJECT_STEAMSHIPPINGID. All build configurations require this, and you cannot launch outside of Steam without it.

For versions before 4.22, edit OnlineSessionAsyncServerSteam.cpp so that it contains your game's values.

For information about distributing a dedicated server build, please refer to Steam's partner documentation.

Steam Online Authentication

Steam features a special authentication system that controls access to some of the unique server-related functionality the platform offers, such as advertising servers and player counts, retrieving and reacting to ban lists (both publisher and Valve Anti-Cheat bans), and performing license checks. Unreal Engine provides the ability to interface with this functionality through the FOnlineAuthSteam class. Once your application is set up to use the Steam Online Subsystem, it is ready to take advantage of these features by enabling the SteamAuth packet handler component.

Enabling SteamAuth

To enable SteamAuth, add the following to "DefaultEngine.ini", or to the platform-specific engine .ini file (such as "WindowsEngine.ini", "LinuxEngine.ini", or "MacEngine.ini") for each platform that is intended to support Steam Online Authentication:

Once enabled, the Steam Online Subsystem interface (SteamOSS) function, GetAuthInterface, can be used to access SteamAuth functionality.

Enabling SteamAuth will cause the application to run authentication procedures (against the Steam service) for all joining players. By default, SteamAuth will kick players who fail this check, but this behavior can be overridden.

SteamAuth Delegates

There are two Delegates in the SteamAuth system that developers may wish to override: OverrideFailureDelegate and OnAuthenticationResultDelegate.

OverrideFailureDelegate is called with the FUniqueNetId of a player when that player attempts to join the server without Steam authentication, or when that player loses Steam authentication during the session. By default, SteamAuth will kick the player from the game. However, if this Delegate is bound, the default behavior will be suspended, so developers will have to kick the player manually if that behavior is still desired.

OnAuthenticationResultDelegate handles responses from Steam's authentication service, providing the FUniqueNetId of the player and a boolean indicating whether the authentication attempt succeeded.

Additional Notes

Using IPNetDriver

By default, UE's Steam OSS uses Steam Networking as the default socket subsystem. In 4.22, you can disable this behavior by setting OnlineSubsystemSteam.bUseSteamNetworking to false. To do this, add the following to "DefaultEngine.ini", or to the platform-specific engine .ini file (such as "WindowsEngine.ini", "LinuxEngine.ini", or "MacEngine.ini") for each platform you support:

In versions prior to 4.22, modify SocketSubsystemSteam.cpp where the RegisterSocketSubsystem function is called and change the bool parameter to be false. You will also need to change the netdrivers in your project configuration files.

Module Setup

Make sure to include the Unreal Engine Steam module as part of your project (reer to UnrealBuildTool Target Files for additional help). Specifically, adding the following line in the constructor for mygame.build.cs should be enough to make sure that the Steam module is built along with your game.

Steam Overlay on Mac

The Steam Overlay on Mac requires launching your games through the Steam client. For this, you first need to add the game to your library using the "Add a Non-Steam Game to My Library" option from Steam's "Games" menu.

Offers and Categories

Retrieving Offers and Categories

Examining Offer Data

Two interfaces power your game's ability to support user purchases: The Store Interface, which provides the ability to make offers to your users, and the Purchase Interface, which enables users to accept these offers. With the Store Interface, the game can retrieve offers from the online service, place them into categories, filter them, and manage them on an individual basis. To execute a purchase, use the Purchase Interface.

An offer (class FOnlineStoreOffer) contains all necessary data about anything a user can purchase through the game. This includes information like the description, the price, and the release and expiration dates. Categories (class FOnlineStoreCategory) hold much simpler data, containing only a name and a list of subcategories. The online services themselves handle setup and management of offers, while the Store Interface takes care of retrieval and filtration.

Offers and Categories

The Store Interface retrieves offer and category data from the online service's servers. Because this operation involves contacting a remote machine, it is broken into two phases: Retrieval and caching of data, which is asynchronous, and accessing that locally-cached data. The Store Interface itself will automatically update the cache whenever a request completes, keeping only the results of the most recent query.

Retrieving Offers and Categories

The first step in retrieving offer information is to retrieve the list of categories that the store contains. The QueryCategories function handles this, and calls a provided delegate of type FOnQueryOnlineStoreCategoriesComplete when it finishes. If successful, the Store Interface will have a cache containing all available category IDs. At this point, the developer can begin querying for offers by making a filter (of type FOnlineStoreFilter) that includes certain categories, and excludes others. With a filter, QueryOffersByFilter can retrieve offer IDs based on their category membership. Once the Store Interface has retrieved and cached the offer IDs, developers can make queries for information about specific offers with the QueryOffersById function. Both QueryOffersByFilter and QueryOffersById will use a provided delegate of type FOnQueryOnlineStoreOffersComplete to indicate success or failure, and the Store Interface's cache of offers will update following either operation completing successfully.

Examining Offer Data

The "query" functions retrieve data about categories and offers into the Store Interface's cache. To access this data, call GetCategories for the category cache, or GetOffers for the offer cache. If you have a known offer ID, the GetOffer function will return information about the corresponding (cached) offer.

These functions all act on the local cache, so they do not have a callback. However, they will only be useful if the cache has been populated. These functions will not update the cache, so any live changes to categories or offers on the online service's store will not be reflected.

IOnlinePlatformData

Functions

FUniqueNetId

FSharedContentHandle

FSessionInfo

FEmsFile

FTitleFile

EOnlineAsyncTaskState

This document serves to define the different data structures that are used throughout the online subsystem.

IOnlinePlatformData

IOnlinePlatformData is the base class for anything meant to be opaque so that the data can be passed around without consideration for the data it contains. A human-readable version of the data is available via the ToString() function; otherwise, nothing but platform code should try to operate directly on the data.

There are often platform-specific representations of various constructs that, while they need to be handled by the game, do not need their details exposed. This allows the game to hold onto the data and replicate it to other machines without understanding the details.

Classes deriving from IOnlinePlatformData:

FUniqueNetId

FSharedContentHandle

FSessionInfo

FUniqueNetId

FUniqueNetId contains a profile service online ID and can represent anything from an individual player, friend or a session.

FSharedContentHandle

FSharedContentHandle contains a profile service shared file handle. This handle can be passed around and used to access shared content from anywhere, given proper permissions.

FSessionInfo

FSessionInfo contains a session's platform-specific info. In most cases, this would be information such as a session identifier, host address, or other means of identifying and connecting to a created session.

See: Session Interface

FEmsFile

FEmsFile is metadata about a given downloadable file. This structure is used when enumerating available data from a given service.

Contains the following elements:

Hash - the hash value of the given file contents.

Filename - the filename as downloaded.

Logical name - the name that maps to the downloaded filename.

File size - size of the file.

FTitleFile

FTitleFile is the internal structure that holds the data used in downloading a file asynchronously from the online service.

Contains the following elements:

Filename - the filename as downloaded.

Async state - the state of the downloaded file. (see: Async States )

Data - a buffer containing the file contents.

EOnlineAsyncTaskState

EOnlineAsyncTaskState is a simple enum representing the possible states for an asynchronous operation.

Retrieving and Examining User Metadata

Mapping External User IDs

The OnlineUser Interface is the central repository for all cached information and metadata about users, both remote and local. This interface also provides reverse-lookup functionality, enabling developers to search for user IDs based on their display names or email addresses and map them back to Unreal Engine's native FUniqueId system.

Retrieving and Examining User Metadata

To access user metadata, you must first request and cache that data from the online service. Call QueryUserInfo with a list of FUniqueNetId values for the users whose information you want, as well as the index of the local user making the request. This is an asynchronous process, and will call a delegate of type OnQueryUserInfoComplete when it finishes. After a successful query populates the cache with user information, the GetAllUserInfo function will return all collected data. If you have the FUniqueNetId of a specific user whose data you want, you can call GetUserInfo with that FUniqueNetId to get just that user's data.

Mapping External User IDs

Most online services support searching for users by their display names or email addresses. The OnlineUser Interface mirrors this functionality with QueryUserIdMapping, which takes a display name or email address and attempts to map it, through the online service, to an FUniqueNetId. Since this procedure involves contacting the online service, it is asynchronous, and will call FOnQueryUserMappingComplete upon completion. Unlike most information requests, this function does not update a cache. Instead, when the operation is successful, the delegate's payload will contain the known display name or email address that was searched, and the resulting FUniqueNetId that the online service found.

User Management

Creating and Destroying

Code Flow Reference

Configuring User Settings

Blocking and Muting

Managing Audio Devices

Identifying and Selecting Devices

Changing Volume and Muting

Communicating with Other Users

Joining and Leaving

Transmitting

Voice communication between players is a common feature that provides a quick and way easy to communicate with others. However, the specific implementation of voice chat varies between different online services and platforms. With the Voice Chat Interface, you can easily operate voice communications over a variety of different services without having to write custom code for each one, including Epic Online Services (EOS), Vivox, and modern gaming consoles. The Voice Chat Interface provides an agnostic API that supports all the features needed to integrate voice chat into your product: joining voice channels, selecting input and output devices, muting or blocking other users, and transmitting and receiving audio data.

If you plan to use EOS as a voice communication provider, read the EOS Voice Chat Plugin documentation for specific information about configuring it to work with your product.

User Management

The Voice Chat Interface identifies individual users by instantiating one Voice Chat User Interface for each of them. This separation enables the system to support multiple local users, as well as make distinctions between system-wide and per-user behaviors and settings.

Creating and Destroying

Since voice communication occurs between users, you must create at least one local Voice Chat User with the CreateUser function. If you are using a service or platform that supports multiple users on the same system, you can call CreateUser more than once, and each call will return a new IVoiceChatUser interface. Your Voice Chat User Interface instance performs all voice chat interactions specific to an individual user. Remember to call ReleaseUser on each Voice Chat User Interface when you no longer need it. See the following reference subsection for more specific detail.

To create your own IVoiceChat and IVoiceChatUser instances, follow this lifecycle. Begin by creating and initializing a single IVoiceChat instance, and using it to create one IVoiceChatUser instance for each local user (or player). With the IVoiceChatUser instance, the user can freely enter and leave any trusted server channels manually, and can communicate with other users. When you are ready to end voice communication, generally during application shutdown, uninitialize any instances you created. This flow involves the following functions, which must be called in order:

Function

Usage

IVoiceChat::Initialize

Initialize an IVoiceChat instance. You must call this on any instance you create before using it.

IVoiceChat::Connect

Connect to the pre-configured voice server.

IVoiceChat::CreateUser

Create an IVoiceChatUser interface instance. Each local user that intends to join a channel needs its own instance to log in. Unlike the other functions in this flow, you can call CreateUser at any time.

IVoiceChatUser::Login

Log a local user into the voice chat server. The PlayerName parameter is the EOS Product ID of the user, stringified with the EOS_ProductUserId_ToString API and converted to an FString with UTF8_TO_TCHAR or similar. It is not required that the EOS Product Id in question actually be logged in via the connect interface of the platform instance used by EOSVoiceChat, just that it is a valid EOS Product Id. The required auth is provided by the trusted server in the form of channel join credentials which are then passed to IVoiceChatUser::JoinChannel.

IVoiceChatUser::JoinChannel

Join a channel after logging into the server. The user can join multiple channels at a time, and can leave and rejoin a channel; each channel will continue to follow the flow individually from this point forward. This process requires credentials; See the section on joining a channel below for information about obtaining them.

IVoiceChatUser::LeaveChannel

(Optional) Cause the local user to leave a channel that they previously joined with JoinChannel.

IVoiceChatUser::Logout

(Optional) Log a local user out of the voice chat server. Doing this will also cause the user to leave all channels. After logging out, you can call Login to log back in without having to create a new interface instance.

IVoiceChat::Disconnect

(Optional) Disconnect from the voice server. This will also effectively log out and leave any channels the user has joined.

IVoiceChat::Uninitialize

Shut down the IVoiceChat interface instance. Calling this function also leaves any channels the user has joined, logs out, and disconnects from the voice chat server. This is usually called during application shutdown.

Configuring User Settings

Voice chat services may have settings that you can configure on a per-user basis. The specific settings and acceptable values vary from one service to another, but the Voice Chat Interface wraps this functionality with the SetSetting and GetSetting functions. Both of these functions use FString as the key and value type.

Blocking and Muting

Use BlockPlayers and UnblockPlayers with a list of player names to block or unblock, respectively, all the players on the list. If you want to mute or unmute a player use SetPlayerMuted. You can check to see whether or not a specific player is muted with IsPlayerMuted.

Managing Audio Devices

Managing a user's audio input and output devices is straightforward. You can query the devices on the user's system if you want to give the user options about which device to use, or select a different input or output device from the default. You can also adjust the volume of a device, including the option to mute it.

Use GetInputDeviceInfo and GetOutputDeviceInfo to identify the current input and output devices, respectively. You can also call GetDefaultInputDeviceInfo and GetDefaultOutputDeviceInfo to get the identity of the default devices, or GetAvailableInputDeviceInfos and GetAvailableOutputDeviceInfos to get a listing of all available devices. Once you know what device you want to use, call SetInputDeviceId or SetOutputDeviceId to select it.

You can use SetAudioInputVolume and SetAudioOutputVolume to adjust the volume of your devices, or GetAudioInputVolume and GetAudioOutputVolume to check the current values. Similarly, SetAudioInputDeviceMuted and SetAudioOutputDeviceMuted can mute (or unmute) your devices, while GetAudioInputDeviceMuted and GetAudioOutputDeviceMuted report whether or not your devices are currently muted.

Communicating with Other Users

Voice communication between users requires that they are all logged in, and that the Voice Chat Interface itself is connected to a voice chat server.

Joining and Leaving

There are three layers of connection involved in communication with other users. The Voice Chat Interface must be connected to a voice communication server, the Voice Chat User Interface must log in, and finally, the Voice Chat User interface must join a channel with other users.

Begin by calling Login on your Voice Chat User, followed by the Voice Chat Interface Connect function, and wait for your FOnVoiceChatConnectCompleteDelegate callback function to confirm that you have successfully connected. You can also check on the status of your connection at any time by calling IsConnected. If you are not currently connected, IsConnecting will inform you of whether or not you are attempting to connect at that moment.

While connected, you can query the server's channel listing with GetChannels, and use the JoinChannel and LeaveChannel functions to participate in different group conversations.

When you are finished, disconnect from the server by calling Disconnect. This will disconnect the Voice Chat Interface from the server, which will stop all local users from communicating. If you only want to log a specific user out, call the Logout function on that user's Voice Chat User Interface. Before shutting down, you should disconnect and log each user out.

Functions that affect the entire local system, like connecting to or disconnecting from a server, operate on the Voice Chat Interface. Operations that relate to only one local player, such as joining or leaving a channel, or interacting with audio hardware, are part of the Voice Chat User Interface.

Transmitting

The system will transmit a user's audio input to other users through the channels that the user has joined. You can set the user to transmit to all channels that they are currently in with TransmitToAllChannels, or to a specific channel with TransmitToSpecificChannel. Use TransmitToNoChannels to cease all channel transmissions.

Setup

Integrating with the EOS Voice Interface

Using the Lobbies Method

Using the Trusted Server Method

Trusted Server Engine Configuration

Code Flow

Joining a Channel

Mixing the Lobbies and Trusted Server Methods

Testing and Debugging

Console Commands

Log Output

With the EOS Voice Chat plugin, developers can leverage the Epic Online Services (EOS) Voice Interface to add voice communication to their products, including using the familiar IVoiceChat and IVoiceChatUser interfaces from the engine's Online Subsystem (OSS). In addition, developers who were previously using VivoxVoiceChat can easily migrate to the EOS backend.

Setup

The EOS Voice Chat plugin implements the IVoiceChat and IVoiceChatUser interfaces. To begin, open the Plugin Browser from the editor's Edit menu, then find and enable the plugin.



Once you have enabled the plugin in your project, you can integrate it through the Lobbies method, or the Trusted Server method. These methods are not mutually exclusive; you can mix them together to gain the benefits and capabilities of each method.

Although both methods are based on the way that EOS works, you will not need to program with the EOS SDK directly. However, you can read the EOS Voice Interface documentation if you want to gain a better understanding of how it works. While reading, bear in mind that IVoiceChat Channels are equivalent to EOS Rooms, and the two terms should be considered interchangeable.

Integrating with the EOS Voice Interface

The two main integration methods, Lobbies, and Trusted Server offer different capabilities. We recommend that you consider which works better for your project, or if a mixed approach is best. With the Lobbies method, the system will automatically join voice chat through EOS without the IVoiceChatUser::JoinChannel function, and you will receive an IVoiceChatUser instance from EOS. The Trusted Server method requires you to call the IVoiceChatUser::JoinChannel function with credentials from a trusted server, but along with this requirement comes the ability to choose which channels to join or leave. This method also gives you control over your IVoiceChat and IVoiceChatUser instances, rather than requiring you to use an instance that EOS provides. You can mix the two integration methods if you would like the OnlineSubsystemEOS plugin to manage lobby voice channels for you automatically, while you manually manage trusted server channels with the IVoiceChat and IVoiceChatUser interfaces. Mixed integration method developers can also reuse the IVoiceChatUser instance from the Lobbies method with the channels that the user has joined through the Trusted Server method.

To get started, you will need to configure your application on the EOS Developer Portal. If you are using the Lobbies integration method, you will also need to enable the OnlineSubsystemEOS plugin in your project.

Using the Lobbies Method

The Lobbies method leverages EOS to handle most of the work involved in joining a channel. This means that if you are using this integration method, you do not need to implement the usual IVoiceChat flow for initializing, connecting, logging in, and joining a channel, because EOS will do this for you.

After setting up OnlineSubsystemEOS with your project, you will be able to join and host EOS lobby sessions. Follow these steps to enable automatic joining of the corresponding voice channels:

Navigate to the EOS Developer Portal and configure your application by enabling voice support.

Set FOnlineSessionSettings::bUseLobbiesVoiceChatIfAvailable to true when creating lobby sessions.

Call FOnlineSubsystemEOS::GetVoiceChatUserInterface to get an IVoiceChatUser interface instance associated with a given local user.

Once the user has logged into EOS, you can get an instance of the IVoiceChatUser interface with the GetVoiceChatUserInterface function. Although you do not need to manage channels, you can use this to interact with the other aspects of the system, such as the user's selected input and output devices, or their list of blocked players. Use this interface instance to register event notification callbacks. As long as the user stays logged in, the OnlineSubsystemEOS plugin will automatically join and leave the associated voice channels for any lobbies the user joins or leaves. As this happens, EOSVoiceChat will broadcast OnVoiceChatChannelJoined and OnVoiceChatChannelExited delegates in response.

The OnlineSubsystemEOS plugin will automatically update the EOS Voice Chat plugin with information about lobby sessions, including notifications about creating, destroying, joining, and leaving them. The EOS Voice Chat plugin broadcasts the OnVoiceChatChannelJoined and OnVoiceChatChannelExited delegates in response to these events.

Using the Trusted Server Method

For situations that favor manual channel management, you will need to use the Trusted Server integration method. As an example, if you use a party system that is not built on EOS Lobbies, creating channels for your party requires this method. The Trusted Server method provides greater control over the user's channel connections, but it requires users to retrieve login credentials from a trusted server in order to join a channel.

If you are reusing an IVoiceChatUser interface instance from a Lobbies integration, then you can skip this section.

If you are not using a Lobbies integration, or if you want to use a separate IVoiceChatUser interface instance, then you will need to add the following section to your Engine.ini file and populate with information about your product:

Fill out each line with the appropriate value for your product. You can find these values by opening your product on the EOS Developer Portal. EOSVoiceChat uses these values to create an EOS Platform Interface instance.

If you are working with the Trusted Server integration method, observe the same code flow as described in the Voice Chat Interface documentation. If your project uses both integration methods, and you are reusing one or more IVoiceChatUser instances from OSS EOS for trusted server channels, these requirements do not apply; the Lobbies integration handles most of the IVoiceChat flow (including instance lifespan management) automatically, and provides a logged in IVoiceChatUser instance.

Although your code does not need to interface with the EOS SDK, the process of joining a channel will ultimately go through the EOS Voice Interface. If you would like to gain a greater understanding of that system, we recommend reading the documentation for it on the EOS documentation site.

Joining a channel requires a client base URL and a participant token from your trusted server. Provide this information to EOS Voice Chat by filling in an FEOSVoiceChatChannelCredentials struct and serializing it to JSON, similar to the sample below:

Mixing the Lobbies and Trusted Server Methods

The Lobbies and Trusted Server integration methods are fully compatible with each other. If you want to gain the advantages of both methods, you can either reuse the IVoiceChatUser interface from the Lobbies method to join, leave, and interact with your trusted server channels, or you can create separate interface instances.

Testing and Debugging

Console Commands

Command

Description

eosvoicechat list

Lists all EOSVoiceChat instances along with their instance ID, debug name (which is useful for telling them apart), and number of created user interfaces.

eosvoicechat info instanceid=<instanceid>

Dumps the current state of the instance and all associated user interfaces to the log.

eosvoicechat initialize instanceid=<instanceid>

Initializes this instance.

eosvoicechat uninitialize instanceid=<instanceid>

Uninitializes this instance.

eosvoicechat connect instanceid=<instanceid>

"Connects" this instance. This should always succeed on EOS Voice Chat, as EOS Voice handles connections per-channel.

eosvoicechat disconnect instanceid=<instanceid>

Disconnects this instance.

eosvoicechat createuser instanceid=<instanceid>

Creates a new IVoiceChatUser interface.

eosvoicechat releaseuser instanceid=<instanceid>

Releases an IVoiceChatUser interface created with createuser.

eosvoicechat createsingleuser instanceid=<instanceid>

This is a convenience method for non-splitscreen games. You can create a single user interface and avoid passing UserIndex=<UserIndex> in commands that require it.

eosvoicechat input setvolume instanceid=<instanceid> userindex=<userindex> volume=<volume>

Sets the volume of the input device. Takes a float value between 0.0 and 1.0.

eosvoicechat input mute instanceid=<instanceid> userindex=<userindex>

Mutes the input device.

eosvoicechat input unmute instanceid=<instanceid> userindex=<userindex>

Unmutes the input device.

eosvoicechat input listdevices instanceid=<instanceid> userindex=<userindex>

Lists the available input devices.

eosvoicechat input setdevice instanceid=<instanceid> userindex=<userindex> deviceid=<deviceid>

Selects a specific input device. You can get a list of valid deviceid values from the listdevices command.

eosvoicechat input setdefaultdevice instanceid=<instanceid> userindex=<userindex>

Reverts to using the default input device.

eosvoicechat output setvolume instanceid=<instanceid> userindex=<userindex> volume=<volume>

Sets the volume of the output device. Takes a float value between 0.0 and 1.0.

eosvoicechat output mute instanceid=<instanceid> userindex=<userindex>

Mutes the output device.

eosvoicechat output unmute instanceid=<instanceid> userindex=<userindex>

Unmutes the output device.

eosvoicechat output listdevices instanceid=<instanceid> userindex=<userindex>

Lists the available output devices.

eosvoicechat output setdevice instanceid=<instanceid> userindex=<userindex> deviceid=<deviceid>

Selects a specific output device. You can get a list of valid deviceid values from the listdevices command.

eosvoicechat output setdefaultdevice instanceid=<instanceid> userindex=<userindex>

Reverts to using the default output device.

eosvoicechat login instanceid=<instanceid> userindex=<userindex> playername=<playername>

Logs a user in on this interface. The playername parameter is the stringified EOS Product ID of the user.

eosvoicechat logout instanceid=<instanceid> userindex=<userindex>

Logs a user out from this user interface.

eosvoicechat channel join instanceid=<instanceid> userindex=<userindex> channelname=<channelname> channeltype=<channeltype>

Joins a named channel. This command will not query a trusted server for the client base URL or participant token; it will use the InsecureClientBaseUrl from the configuration file, and a generated participant token. See FEOSVoiceChatUser::InsecureGetJoinToken. The channeltype parameter is optional. There is a feedback channel named "echo" that is helpful for single user testing.

eosvoicechat channel leave instanceid=<instanceid> userindex=<userindex> channelname=<channelname>

Leaves a named channel.

eosvoicechat channel transmit instanceid=<instanceid> userindex=<userindex> channelname=<channelname>

Transmits only to a specific, named channel.

eosvoicechat channel transmitall instanceid=<instanceid> userindex=<userindex>

Transmits to all channels.

eosvoicechat channel transmitnone instanceid=<instanceid> userindex=<userindex>

Transmits to no channels.

eosvoicechat player mute instanceid=<instanceid> userindex=<userindex> playername=<playername>

Mutes the named remote player. Although you cannot hear them, they can still hear you. To stop sending input to them also, see the block command.

eosvoicechat player unmute instanceid=<instanceid> userindex=<userindex> playername=<playername>

Unmutes the named remote player.

eosvoicechat player block instanceid=<instanceid> userindex=<userindex> playername=<playername>

Blocks the named remote player, rendering you inaudible to each other.

eosvoicechat player unblock instanceid=<instanceid> userindex=<userindex> playername=<playername>

Unblocks the named remote player.

Log Output

The LogEOSVoiceChat log category contains all log output coming from the EOSVoiceChat plugin itself, including the above console commands, while the LogEOSSDK log category contains log output coming from the underlying EOS SDK. Changing the verbosity level of the LogEOSSDK log category will also update the log verbosity setting on the EOS SDK Logging Interface, so the two are always in sync.

FSoftObjectPaths and TSoftObjectPtr

The Asset Registry and Object Libraries

StreamableManager and Asynchronous Loading

There are several methods in Unreal Engine (UE) that simplify the process of asynchronously loading asset data. These methods work identically in development and with cooked data on devices, so you do not need to maintain two code paths for loading data on demand. There are two general methods you can use to refer to and load data on demand:

FSoftObjectPaths and TSoftObjectPtr

The easiest way to have an artist or designer reference an asset is to create a UProperty of a hard pointer and give it a category. In UE, if you have a hard UObject pointer property referencing an asset, that asset will be loaded when the object containing the property is loaded (either by being placed in a map, or referenced from something like a gameinfo). If you are not careful, you can end up loading 100% of your assets at game startup time. If you want artists/designers to be able to make references to specific assets using the same UI as a hard pointer, without always loading the referenced asset, use a FSoftObjectPath or TSoftObjectPtr.

A FSoftObjectPath is a simple struct that contains a string with the full name of an asset. If you make a property of that type in your class, it shows up in the editor as if it was a UObject * property. It also properly handles cooking and redirects, so if you have a SoftObjectPath, it is guaranteed to work properly on a device. A TSoftObjectPtr is basically a TWeakObjectPtr that wraps around a FSoftObjectPath, and will template to a specific class so you can restrict the editor UI to only allow selecting certain classes. If the referenced asset exists in memory, TSoftObjectPtr.Get() will return it. If it does not, you can call ToSoftObjectPath() to find out the asset that it refers to, load that using the method described below, then call TSoftObjectPtr.Get() again to dereference it.

TSoftObjectPtrs and Soft Object Paths are great if an artist or designer is setting up references manually, but if you want to do something like a query to find an asset satisfying certain requirements, without loading all of those assets, you want to use the asset registry and object libraries.

The Asset Registry and Object Libraries

The asset registry is a system that stores metadata about assets and allows searches and queries about those assets. It is used by the editor to display the information in the Content Browser, but you can also use it from gameplay code to query metadata about gameplay assets that are not currently loaded. To make data about an asset searchable, you need to add the AssetRegistrySearchable tag to the property. Queries to the asset registry return objects of type FAssetData, which contains information about the object as well as a map of key-value pairs containing the properties marked as searchable.

The easiest way to work with groups of unloaded assets is with an ObjectLibrary. An ObjectLibrary is an object that contains a list of either loaded objects or FAssetData for unloaded objects, that inherit from a shared base class. You load an object library by giving it a path to search, and it will add all assets in that path. This can be very useful, because you can designate parts of your content folder for different types, and artists/designers can add new assets without having to edit some manual master list. Here is an example of how you would load AssetData off disk using an object library:

In this example, it creates a new object library, associates a base class, then loads all asset data in a given path. It then optionally loads the actual assets. You want to fully load the assets either if the assets are small, or if you are cooking and need to make sure that they all get cooked. As long as you perform an asset registry query during cooking, and load the assets returned, your object library will work identically with cooked data on a device as in development. Once you have the asset data contained in an ObjectLibrary, you can do queries and selectively load certain assets. Here is an example of how you would do a query:

In this example, it searches the object library for anything that has a TypeName field containing "FooType", then returns the first it finds. Once you have that AssetData, you can call ToStringReference() to convert that to an FSoftObjectPath, which you can then load asynchronously using the next system:

StreamableManager and Asynchronous Loading

Now that you have a FSoftObjectPath that refers to an asset on disk, how do you actually load it asynchronously? FStreamableManager is the easiest way to do this. First, you will need to create an FStreamableManager, I would suggest putting it in some sort of global game singleton object, such as one specified using GameSingletonClassName in DefaultEngine.ini. Then, you can pass your FSoftObjectPath into it and start a load. SynchronousLoad will do a simple, blocking load and return the object. This method may be fine for smaller objects, but it could potentially stall your main thread for too long. In that case, you will need to use RequestAsyncLoad, which will asynchronously load a group of assets and call a delegate after completion. Here is an example:

In this example, ItemList is a TArray< TSoftObjectPtr<UGameItem> > that was modified by designers in the editor. The code iterates that list, converts them to StringReferences, and queues up a load of them. When all of those items are loaded (or fail to load because they are missing), it calls the passed in delegate. That delegate then iterates the same list of items, dereferences them, and gives them to a player. StreamableManager keeps hard references to any assets it loads until the delegate is called, so you can safely know that none of the objects you wanted to asynchronously load will be garbage collected before the delegate is called. It releases those references after the delegate is called, so you need to hard reference them somewhere else if you want to ensure they will stay around.

You can use the same method to asynchronously load a FAssetData, just call ToStringReference on them, add them to an array, and call RequestAsyncLoad with a delegate. The delegate can be anything you want, so you can pass along payload information if you want. By combining the methods described above, you should be able to set up a system that allows efficient loading of any asset in your game. It will take some time to convert your gameplay code that does direct memory accesses to handle asynchronous loading, but afterwards, your game will have far fewer stalls and much lower memory usage.

Modes

URL Parameters

General Options

Server Options

Switches

Developer

Rendering

Network

User

Server Switches

Game Stats/Database

INI/Config Files

Debugging

Misc.

Command-Line Arguments are strings of keywords that you can pass when running the executable via the command line or a shortcut to the executable. Their purpose is to customize the manner in which the engine runs to suit the needs of the developer or user. This can be as simple as causing the editor to run instead of the game, or it can be much more involved such as starting up the game with a certain map running at a specified resolution and framerate while dumping out each frame to individual image files.

Modes

These arguments are used to force the main editor executable (UnrealEditor.exe) to run as the game or a server using uncooked content.

These commands are not case sensitive.

Example:

Argument

Description

-game

Launch the game using uncooked content.

-server

Run the game as a server using uncooked content.

URL Parameters

URLs can be passed to the executable to force the game to load a specific map upon startup. These can also be used in conjunction with the SERVER or EDITOR modes to run the editor or a server with a specific map. Passing a URL is optional, but must immediately follow the executable name or any mode switch if one is present.

A URL consists of two parts: a map name or server IP address and a series of optional additional parameters. A map name can be any map located within the Maps directory. The inclusion of a file extension (.umap) here is optional. To load a map not found in the Maps directory, an absolute path or a relative path from the Maps directory can be used. In this case, the inclusion of the file extension is mandatory. The server IP address is a standard four-part IP address consisting of four values between 0 and 255 separated by periods. The additional options are specified by appending them to the map name or server IP address. Each option is prefaced by a '?', and can set a value with '='. Starting an option with '-' will remove that option from the cached URL options.

Examples:

General Options

Argument

Description

game

Tells the engine what GameInfo class to use (overriding default).

name

Tells the engine the Player name to use.

Server Options

Argument

Description

listen

Specifes the server as a listen server.

bIsLanMatch

Sets whether multiplayer game is on the local network (e.g. bIsLanMatch=0).

bIsFromInvite

Specifies that the player joining was invited.

spectatoronly

Starts the game in spectator mode.

Switches

These arguments can be passed to either the game or the editor, depending on the specific keyword and its intended usage. Some arguments are plain switches (-UNATTENDED) while others are setting switches that are key=value pairs (-LOG=MyLog.txt). These commands are not case sensitive. The syntax for passing plain switches is to preface each argument with a minus '-' and then the argument immediately afterward. Setting switches need no leading '-', with the exception of the server switches.

Example:

Developer

ABSLOG: Same as LOG= but without a filename length check.

ALLUSERS: Add the game for all users when INSTALLGE is specified.

AUTO: Assume yes on all questions. (for example during compile)

AUTOCHECKOUTPACKAGES: Automatically checkout packages that need to be saved.

AutomatedMapBuild: Perform an automated build of a specified map.

BIASCOMPRESSIONFORSIZE: Override compression settings with respect to size.

BUILDMACHINE: Set as build machine. Used for deciding if debug output is enabled.

BULKIMPORTINGSOUNDS: Use when importing sounds in bulk. (Content Browser specific.)

CHECK_NATIVE_CLASS_SIZES: Enable checking of native class sizes. Note: Native classes on console platforms will cause native class size checks to fail even though they are assumed to be correct.

CODERMODE: Enables Coder mode.

COMPATSCALE: Set compatibility settings manually to override PCCompat tool settings.

CONFORMDIR: Directory to use when conforming packages.

COOKFORDEMO: Specify as cooking packages for the demo.

COOKPACKAGES: Tag to specify cooking packages.

CRASHREPORTS: Always report crashes of the engine.

D3DDEBUG: Use a d3d debug device.

DEVCON: Disable secure connections for developers. (Uses unencrypted sockets.)

DUMPFILEIOSTATS: Track and log File IO statistics.

FIXEDSEED: Initialize the random number generator with a fixed value, 0.

FIXUPTANGENTS: Fix legacy tangents in distributions automatically.

FORCELOGFLUSH: Force a log flush after each line.

FORCEPVRTC: Force pvrtc texture compression for mobile platform.

FORCESOUNDRECOOK: Force a complete re-cook of all sounds.

GENERICBROWSER: Use the Generic Browser.

INSTALLED: For development purposes, run the game as if installed.

INSTALLFW / UNINSTALLFW: Set whether the handling of the firewall integration should be performed.

INSTALLGE: Add the game to the Game Explorer.

CULTUREFORCOOKING: Set language to be used for cooking.

LIGHTMASSDEBUG: Launch lightmass manually with -debug and allow lightmass to be executed multiple times.

LIGHTMASSSTATS: Force all lightmass agents to report detailed stats to the log.

LOG: When used as a switch (-log), opens a separate window to display the contents of the log in real time. When used as a setting (LOG=filename.log), tells the engine to use the log filename of the string that immediately follows.

LOGTIMES: Print time with log output. (Default, same as setting LogTimes=True in the [LogFiles] section of *Engine.ini.)

NOCONFORM: Tell the engine not to conform packages as they are compiled.

NOCONTENTBROWSER: Disable the Content Browser.

NOINNEREXCEPTION: Disable the exception handler within native C++.

NOLOADSTARTUPPACKAGES: Force startup packages not to be loaded. You can use this if objects in a startup package must be deleted from within the editor.

NOLOGTIMES: Do not print time with log output. (Same as setting LogTimes=False in the [LogFiles] section of *Engine.ini.)

NOPAUSE: Close the log window automatically on exit.

NOPAUSEONSUCCESS: Close the log window automatically on exit as long as no errors were present.

NORC: Disable the remote control. Used for dedicated servers.

NOVERIFYGC: Do not verify garbage compiler assumptions.

NOWRITE: Disable output to log.

SEEKFREELOADING: Only use cooked data.

SEEKFREEPACKAGEMAP: Override the package map with the seekfree (cooked) version.

SEEKFREELOADINGPCCONSOLE: Only use cooked data for PC console mode.

SEEKFREELOADINGSERVER: Only use cooked data for server.

SETTHREADNAMES: (Xbox only) Force thread names to be set. This can mess up the XDK COM API which is why it must be explicitly set to be performed if desired.

SHOWMISSINGLOC: If missing localized text, return error string instead of English text.

SILENT: Disable output and feedback.

TRACEANIMUSAGE: Trace animation usage.

TREATLOADWARNINGSASERRORS: Force load warnings to be treated as errors.

UNATTENDED: Set as unattended. Disable anything requiring feedback from user.

UNINSTALLGE: Remove the game from the Game Explorer.

USEUNPUBLISHED: Force packages in the Unpublished folder to be used.

VADEBUG: Use the Visual Studio debugger interface.

VERBOSE: Set compiler to use verbose output.

VERIFYGC: Force garbage compiler assumptions to be verified.

WARNINGSASERRORS: Treat warnings as errors.

Rendering

ConsoleX: Set the horizontal position for console output window.

ConsoleY: Set the vertical position for console output window.

WinX: Set the horizontal position of the game window on the screen.

WinY: Set the vertical position of the game window on the screen.

ResX: Set horizontal resolution for game window.

ResY: Set vertical resolution for game window.

VSync: Activate the VSYNC via command line. Pprevents tearing of the image but costs fps and causes input latency.)

NoVSync: Deactivate the VSYNC via command line.

BENCHMARK: Run game at fixed-step in order to process each frame without skipping any frames. This is useful in conjunction with DUMPMOVIE options.

DUMPMOVIE: Dump rendered frames to files using current resolution of game.

EXEC: Executes the specified exec file.

FPS: Set the frames per second for benchmarking.

FULLSCREEN: Set game to run in fullscreen mode.

SECONDS: Set the maximum tick time.

WINDOWED: Set game to run in windowed mode.

Network

LANPLAY: Tell the engine to not cap client bandwidth when connecting to servers. Causes double the amount of server updates and can saturate client's bandwidth.

Limitclientticks: Force throttling of network updates.

MULTIHOME: Tell the engine to use a multihome address for networking.

NETWORKPROFILER: Enable network profiler tracking.

NOSTEAM: Set steamworks to not be used.

PORT: Tell the engine to use a specific port number.

PRIMARYNET: Affect how the engine handles network binding.

User

NOHOMEDIR: Override use of My Documents folder as home directory.

NOFORCEFEEDBACK: Disable force feedback in the engine.

NOSOUND: Disable any sound output from the engine.

NOSPLASH: Disable use of splash image when loading the game.

NOTEXTURESTREAMING: Disable texture streaming. Highest quality textures are always loaded.

ONETHREAD: Run the engine using a single thread instead of multi-threading.

PATHS: Set what paths to use for testing wrangled content. Not used for shipping releases.

PREFERREDPROCESSOR: Set the thread affinity for a specific processor.

USEALLAVAILABLECORES: Force the use of all available cores on the target platform.

Server Switches

LOGIN: Set username to use when logging in.

PASSWORD: Set password to use when logging in.

Game Stats/Database

NODATABASE: Do not use database, and ignore database connection errors.

NOLIVETAGS: Skip loading unverified tag changes from SQL database. Only load for current user.

INI/Config Files

ENGLISHCOALESCED: Revert to the default (English) coalesced .ini if the language-localized version cannot be found.

NOAUTOINIUPDATE: Suppress prompts to update .ini files.

NOINI: Do not update the .ini files.

REGENERATEINIS: Forces .ini files to be regenerated.

Use Aaother command-line argument to temporarily override which INIs are loaded by the game or editor. For example, if a custom MyGame.ini is to be used instead of MyOldGame.ini, the argument would be -GAMEINI=MyGame.ini. This table lists the arguments used to override the different INI files used in UE4:

Command-Line Argument

INI Override

DEFEDITORINI=

Default Editor

EDITORINI=

Editor

DEFEDITORUSERSETTINGSINI=

Default EditorUserSettings

EDITORUSERSETTINGSINI=

EditorUserSettings

DEFCOMPATINI=

Default Compat

COMPATINI=

Compat

DEFLIGHTMASSINI=

Default Lightmass

LIGHTMASSINI=

Lightmass

DEFENGINEINI=

Default Engine

ENGINEINI=

Engine

DEFGAMEINI=

Default Game

GAMEINI=

Game

DEFINPUTINI=

Default Input

INPUTINI=

Input

DEFUIINI=

Default UI

UIINI=

UI

Debugging

BugLoc (e.g. BugLoc=(X=1798.8569,Y=475.9513,Z=-8.8500))

BugRot (e.g. BugRot=(Pitch=-1978,Yaw=-7197,Roll=0))

Misc.

timelimit (e.g. timelimit=[time])

goalscore (e.g. goalscore=[score])

numbots (e.g. numbots=[num])

Supported Core Redirect Types

Name Flexibility and Specificity

Substring Matching

During development, there are occasions when an existing class, property, function name, or similar code member needs to be renamed. If there are a high number of Assets affected by these changes, though, simply renaming the code member and recompiling your project will cause considerable data loss, because Unreal Engine (UE) will no longer recognize existing Assets. To address this issue, the Engine uses Core Redirects. Core Redirects should be configured in your project's DefaultEngine.ini file, or, in the case of a Plugin, the prefixed, self-named .ini file for that Plugin (for example, BasePaper2D.ini for the Engine's Paper2D Plugin, or Default<GamePluginName>.ini for a game Plugin). In either case, the Core Redirects will be placed in the "[CoreRedirects]" section. These Core Redirects will automatically remap obsolete data while loading Assets, thus preventing data loss resulting from the renaming process. For examples of Core Redirects currently in effect, check the BaseEngine.ini file.

Supported Core Redirect Types

When specifying a name of a class or struct in an Core Redirect, the name should be written as it appears to the Unreal Engine's reflection system, meaning the prefix letter is dropped. For example, AMyActor would be written as MyActor, and FMyStruct would be written as MyStruct. Since Unreal Engine's reflection system does not use a prefix for enumerated types, enumerated type names appear in Core Redirects exactly as they do in code. For example, ESampleEnum would remain ESampleEnum when referenced by a Core Redirect.

The following Core Redirect formats are currently supported:

ClassRedirects - Changes objects and properties using an obsolete (or removed) UCLASS to refer to a new UCLASS.

Field

Type

Purpose

OldName

String

Specifies the name of the obsolete (or removed) UCLASS.

NewName

String

Specifies the name of the new UCLASS.

MatchSubstring

Bool

(Optional) If present and set to true, this Core Redirect will apply to any class containing the value of OldName, rather than requiring an exact match.

OverrideClassName

String

(Optional) Specifies a change to the underlying class of the UCLASS. This is generally used to change a Blueprint class to a native class (/Script/CoreUObject.Class).

InstanceOnly

Bool

(Optional) If present and set to true, indicates that the original class still exists and can be referenced, but any existing instances of the old class (such as Actors or Components placed in Levels) should be remapped to the new class. This is especially useful when your project has a specialized version of a class that exists in the engine, but your Levels are full of instances of the original class, and you want to change them all to the project-specific version.

ValueChanges

List of String pairs

(Optional) Renames instances of the old class that match the first String of a pair. The new name will be the second String of that pair.

EnumRedirects - Remaps obsolete UENUM types and/or obsolete values within an enumerated type.

Field

Type

Purpose

OldName

String

Specifies the name of the obsolete UENUM (if NewName is specified), or the name of the existing UENUM (if only remapping values).

NewName

String

(Optional) Specifies the name of the new UENUM, if remapping from an obsolete UENUM to a new one.

MatchSubstring

Bool

(Optional) If present and set to true, this Core Redirect will apply to any enumerated type containing the value of OldName, rather than requiring an exact match.

ValueChanges

List of String pairs

The first string in the pair is the old enumerated value, and the second string is the new value. If both values are in the same class, the old value must no longer exist in code.

FunctionRedirects - Remaps an obsolete UFUNCTION to a new one.

Field

Type

Purpose

OldName

String

Specifies the name of the obsolete (or removed) UFUNCTION. The function name is period-delimited so that the class name is included.

NewName

String

Specifies the name of the new UFUNCTION. The function name can be period-delimited, which makes it possible to remap a function from one class to another class.

MatchSubstring

Bool

(Optional) If present and set to true, this Core Redirect will apply to any function containing the value of OldName, rather than requiring an exact match.

PackageRedirects - Remapping from one package to another, or suppressing warnings about references to a deleted package (references will be cleared or set to null).

Field

Type

Purpose

OldName

String

Specifies the name of the obsolete or deleted package.

NewName

String

(Optional) If remapping is desired, this specifies the name of the package that replaces the obsolete or deleted package. If this is not present, Removed should be present and set to true.

MatchSubstring

Bool

(Optional) If present and set to true, this Core Redirect will apply to any package containing the value of OldName, rather than requiring an exact match.

Removed

Bool

(Optional) If present and set to true, the named package has been removed. References to any of the removed content will be set to null without generating warnings or errors. The NewName argument should not be present if this is the case.

PropertyRedirects - Remaps removed properties to new properties.

Field

Type

Purpose

OldName

String

The name of the removed property. This name is period-delimited so that the class name and any sub-variable names are included, For example, MyActor.MyStruct.MyProperty.

NewName

String

The name of the new property. This name can be fully period-delimited like OldName, or it can be just the variable name if it exists in the same namespace as OldName.

MatchSubstring

Bool

(Optional) If present and set to true, this Core Redirect will apply to any property containing the value of OldName, rather than requiring an exact match.

StructRedirects - Changes properties using an obsolete (or removed) USTRUCT to refer to a new USTRUCT.

Field

Type

Purpose

OldName

String

Specifies the name of the obsolete (or removed) USTRUCT.

NewName

String

Specifies the name of the new USTRUCT.

MatchSubstring

Bool

(Optional) If present and set to true, this Core Redirect will apply to any struct containing the value of OldName, rather than requiring an exact match.

Name Flexibility and Specificity

Names used when describing classes, structs, properties, and functions can be written with varying degrees of specificity. Additionally, the Core Redirects system will use as much (or as little) information as you provide. The following table provides some examples of these levels of specificity.

Example Format

Scope of application

/Script/MyModule.MyActor.MyFunctionOrProperty

Will apply only to the function or property called MyFunctionOrProperty within the MyActor class in the MyModule module.

MyActor.MyFunctionOrProperty

Will apply to any function or property called MyFunctionOrProperty within the MyActor class, regardless of what module that class and function exist in.

MyFunctionOrProperty

Will apply to any function or property called MyFunctionOrProperty in any class, within any module.

Some obsolete Core Redirects can be found in certain .ini files in games and samples older than version 4.16. While the formats they use are still supported for backward-compatibility purposes, it is not recommended that they be used as templates for writing your own Core Redirects going forward. Instead, use only the formats specified on this page.

Substring Matching

The MatchSubstring argument can be used in any Core Redirect type. If present and set to true, the OldName and NewName fields will be treated as substrings rather than requiring exact matches. This enables multiple matches with a single Core Redirect. In the following example, we will start with a struct and a class.

Original code and values:



This is the original code and the original set of values we're saving into our AMyActor Asset.

After creating and saving an AMyActor Asset with the values shown above, we can close the Editor and alter the the code in the .h file and the Core Redirects in the game's .ini file. We will change the code to read as follows, changing the names of our int32 properties:

With this change, we can examine the effects of a Core Redirect, and in particular the impact of MatchSubstring. Results follow:



The properties were renamed in code, but no Core Redirect was created. As a result, no data values have migrated to the new properties.



PropertyRedirects=(OldName="TestInt",NewName="TestInteger") causes only the two preoperties with exact name matches to migrate their data.



PropertyRedirects=(OldName="TestInt",NewName="TestInteger",MatchSubstring=true) causes all four of our properties to migrate, due to substring matching.

Because MatchSubtring requires checking incoming Assets much more thoroughly, it can impact startup times. MatchSubstring is intended to be used temporarily as a fixup when making sweeping changes. It is recommended that Assets involved in these changes be resaved immediately and checked into your project's source control database with any related code changes, and that the Core Redirect be deleted without entering source control.

Plugin Verification

Editor Usage

Command Line Usage

Validation Rules

The Unreal Engine (UE) Editor features a Data Validation plugin for developers to validate assets with custom-scripted rulesets. Common validation use cases include:

Checking that assets meet name conventions

Enforcing space and performance budgets

Catching non-cyclic dependencies

Plugin Verification

To verify that the built-in Data Validation plugin is enabled by default, from the main menu, select Edit > Plugins, and from the Plugins menu, search for Data Validation.



Editor Usage

Developers can use the Data Validation system in many ways, from testing a single asset to validating all of a project's assets.

Validation Use Case

Usage

Notes

Asset

In the Content Browser, right-click an asset and select Asset Actions > Validate Assets

Validates a specific asset; however, it is possible to select multiple assets for validation.

Assets and dependencies

In the Content Browser, right-click an asset and select Asset Actions > Validate Assets and Dependencies

Validates a specific asset and its dependencies; however, it is possible to validate multiple assets at once.

Folder's assets

In the Content Browser, right-click a folder and select Validate Assets in Folder

Validates a specific folder; however, it is possible to validate multiple folders at once.

Project's assets

From the main menu, select File > Validate Data...

Validates all of the assets in a project's content directory.

Command Line Usage

Running the plugin from the command line is useful to developers who want to validate assets as part of a Continuous Integration System (CIS). Perform command line validation with the following commandlet:

UnrealEditor-Cmd.exe <PROJECT_NAME>.uproject -run=DataValidation

The Data Validation system only runs C++ validation rules by default.

Developers can extend the Data Validation system to support Blueprint and Python validation rules.

Validation Rules

Currently, there are two ways to create validation rules:

Have a custom UObject-derived class that overrides IsDataValid. This works best for custom classes for your project.

This method provides access private/protected class data and functions that the UEditorValidatorBase method would not.

Because you are implementing your own class in this case, you can also set up a BlueprintImplementableEvent to be called by IsDataValid, so you can have some validation logic in C++ and further validation logic in Blueprints or Python.

Creating a UEditorValidatorBase derived class using C++, Blueprints, or Python. The two key functions here are CanValidateAsset and ValidateLoadedAsset, both of which take a UObject pointer as an argument to validate. This system lets you validate any asset, whether it is based on a default engine class or a custom class.

ValidateLoadedAsset must call AssetPasses or AssetFails for each of its execution paths.

Validators can be enabled by overriding IsEnabled. By default, this returns the protected variable bIsEnabled which is exposed to Details panels as well.

C++ and Blueprint validators will be discovered automatically on editor startup, while Python validators will need to register themselves with the UEditorValidatorSubsystem using AddValidator.

By default, Blueprint validator auto-registration is disabled in Fortnite for performance reasons.

Both types of validation are run by CIS, on asset save (enabled by default), and through menu options in the editor and Content Browser. When validation fails, messages will be displayed in the Message Log in the editor, and in the console in CIS.

If you are implementing your own calls to UEditorValidatorSubsystem, you will need to handle the display of the ValidationErrors FText array yourself. The functions needed to validate an asset from its FAssetData or the loaded UObject are available to scripting as well.

This section references these APIs, read them to learn more:

IsDataValid

DataValidation

Benefits of Using Modules

Setting Up a Module

Understanding the Structure of a Module

Configuring Dependencies in the Build.cs File

Private and Public Dependencies

Using the Private and Public Folders

Implementing the Module in C++

Using Modules in Your Projects

Controlling How Modules Load

Modules are the basic building block of Unreal Engine's (UE) software architecture. These encapsulate specific editor tools, runtime features, libraries, or other functionality in standalone units of code.

All projects and plugins have their own primary module by default, however, you can define other modules outside of these to organize your code.

This page provides an overview of how modules are structured and how they can benefit your Unreal Engine projects.

Unreal Engine modules are not related to C++ 20 modules.

Benefits of Using Modules

Organizing your project with modules provides the following benefits:

Modules enforce good code separation, providing a means to encapsulate functionality and hide internal parts of the code.

Modules are compiled as separate compilation units. This means only modules that have changed will need to compile, and build times for larger projects will be significantly faster.

Modules are linked together in a dependency graph and limit header includes to code that is actually used, per the Include What You Use (IWYU) standard. This means modules that are not used in your project will be safely excluded from compilation.

You can control when specific modules are loaded and unloaded at runtime. This provides a way to optimize the performance of your project by managing which systems are available and active.

Modules can be included or excluded from your project based on certain conditions, such as which platform the project is being compiled for.

In summary, if you observe best practices with modules, your project's code will be better organized, will compile more efficiently, and will be more reusable than if you put all of your project's code into a single module.

Setting Up a Module

The following is an overview of how to build and implement a module from scratch. If you follow these steps, you will create a gameplay module separate from the primary module that your project includes by default.

Create a directory for your module at the top level of your project's Source folder. This directory should have the same name as your module.

You can place modules in any subdirectory within your Source folder, at any number of levels deep. This makes it possible to use subdirectories to group modules.

Create a [ModuleName].Build.cs file inside your module's root directory and use it to define dependencies with other modules. This makes it possible for the Unreal build system to discover your module.

Create Private and Public subfolders inside your module's root directory.

Create a [ModuleName]Module.cpp file in the Private subfolder for your module. Use this to provide methods for starting up and shutting down your module, as well as other common functions that Unreal Engine uses to manage modules.

To control how and when your module loads, add configuration information for your module in your .uproject or .uplugin file. This includes the name, type, compatible platforms, and loading phase of the module.

List your module as a dependency in the Build.cs file for any module that will need to use it. This may include the Build.cs file for your project's primary module.

Generate the solution files for your IDE any time you modify your [ModuleName].Build.cs file or move source files between folders. You can use any of the following methods to do this:

Run GenerateProjectFiles.bat.

Right-click the .uproject file for your project, then click Generate Project Files.

In the Unreal Editor, click File > Refresh Visual Studio Project.

For more details on these components and how to configure them, continue reading this page. For a more detailed walkthrough of setting up a module, refer to Creating a Gameplay Module.

Understanding the Structure of a Module

All modules should be placed in the Source directory for either a plugin or project. The module's root folder should have the same name as the corresponding module.

There should also be a [ModuleName].Build.csfile for each module in its root folder, and its C++ code should be contained in Private and Public folders.

The following is an example of the recommended folder structure for a module:

[ModuleName]

Private

[ModuleName]Module.cpp

All .cpp files and private headers

Public

All public headers

[ModuleName].Build.cs

Configuring Dependencies in the Build.cs File

The Unreal build system builds projects according to Target.cs files in your projects and the Build.cs files in your modules, not according to the solution files for your IDE.

The IDE solution is generated automatically when editing code, but the Unreal Build Tool (UBT) will ignore it when compiling projects.

All modules require a [ModuleName].Build.cs file placed in the module's root directory for the Unreal build system to recognize them.

Inside your [ModuleName].Build.cs file, you need to define your module as a class inherited from the ModuleRules class. Below is an example of a simple Build.cs file:

Sample ModuleTest.Build.cs File

When configuring your Build.cs files, you will mainly use the PrivateDependencyModuleNames and PublicDependencyModuleNames lists. Adding module names to these lists will set the modules that are available to your module's code.

For example, if you add the "Slate" and "SlateUI" module names to your private dependencies list, you will be able to include Slate UI classes within your module.

Private and Public Dependencies

You should use the PublicDependencyModuleNames list if you use the classes from a module publicly, such as in a public .h file. This will make it possible for other modules that depend on your module to include your header files without issues.

You should put a module's name in the PrivateDependencyModuleNames list if they are only used privately, such as in .cpp files. Private dependencies are preferred wherever possible, as they can reduce your project's compile times.

You can make many dependencies private instead of public by using forward declarations in your header files.

Using the Private and Public Folders

If your module is a regular C++ module (meaning the ModuleType is not set to External in your .uproject or .uplugin), its C++ files should be placed in the Private and Public subfolders inside your module's root directory.

These do not have any relation to the Private, Public, or Protected access specifiers in your C++ code. Instead, they control the availability of the module's code to other modules. If you use these folders, all .cpp files should be placed in the Private folder. Header (.h) files should be placed in the Private and Public folders per the guidelines below.

If you place a header file in the Private folder, its contents will not be exposed to any modules outside its owning module. Classes, structs, and enums in this folder will be accessible to other classes inside the same module, but they will not be available to classes in other modules.

If you place a header in the Public folder, the Unreal build system will expose its contents to any other module that has a dependency on the current module. Classes in outside modules will be able to extend classes contained in the Public folder, and you will be able to create variables and references using classes, structs, and enums in the Public folder as well. The Private, Public, and Protected specifiers will take effect as normal for functions and variables.

If you are working on a module that will not be made a dependency for others, you do not need to use the Private and Public folders. Any code outside of these folders will behave as if it were Private. A typical example of this would be your game's primary module, which will likely be at the end of the dependency chain.

You can further organize your code by creating subfolders within the Public and Private folders. For any new folder you create within Public, create a corresponding folder with the same name in Private. Similarly, for any header file you place in Public, make sure its corresponding .cpp files are always in the corresponding folder in Private.

If you create new classes with the New Class Wizard in Unreal Editor, it will automatically ensure parallel construction between these folders.

Implementing the Module in C++

To expose a module to the rest of your C++ project, you need to create a class extending IModuleInterface, then provide that class to the IMPLEMENT_MODULE macro.

For the simplest implementation, you can create a .cpp file in the module's Private directory, and name it [ModuleName]Module.cpp, where [ModuleName] is the name of your module. Go on to call the IMPLEMENT_MODULE macro after all other #include declarations, and provide FDefaultModuleImpl as the class.

ModuleTestModule.cpp

FDefaultModuleImpl is an empty class that extends IModuleInterface. For a more detailed implementation, you can write your own class to implement in this .cpp file.

IModuleInterface features several functions that trigger when your module loads and unloads, similar to the Startup and Shutdown functions in the GameInstance** **class.

Using Modules in Your Projects

Anytime you make a new Unreal Engine project or plugin, it will automatically set up a primary module of its own, which you can find in the project's Source folder. You can include outside modules in your project by adding them to the Build.cs file for your project's primary module.

For example, to use the Gameplay Tasks system in a project titled MyProject, you need to open MyProject.Build.cs, then add the "GameplayTasks"` module as a dependency.

To optimize compilation speeds, Unreal Build Tool only compiles modules found in the dependency chain for your project. This means that if a module isn't included in any Build.cs files that are used by your project, that module will be skipped during compilation.

Controlling How Modules Load

Your .uproject and .uplugin files contain a Modules list defining which modules are included in your project and how they will load.

When you regenerate your project files, entries for your modules will be added to this list automatically if they are not already present, provided that you have included them in the dependency chain. Entries in this list will look similar to the following:

Most gameplay modules will simply list their Name, while their Type will be set to Runtime. If their LoadingPhase is not defined it will be set to Default. There are a variety of other module types, loading phases, and additional parameters that control which platforms a module will and won't load on.

For information about the available module types, refer to the API documentation for EHostType::Type

The most common module types are Runtime and Editor, which are used for in-game classes and editor-only classes, respectively.

For more information about loading phases, refer to the API documentation for ELoadingPhase::Type

While the Default loading phase is suitable for most gameplay modules in your project, plugins sometimes need to load earlier. If you frequently see errors from Unreal Editor trying to find C++ classes in a plugin, try setting them to PreDefault.

The other parameters used by this list include the following:

Parameter

Description

IncludelistPlatforms / ExcludelistPlatforms (Array)

Include or exclude the module for compiling on the listed platforms. Example platform strings include Win32, Win64, Mac, Linux, Android and IOS.

IncludelistTargets / ExcludelistTargets (Array)

Include or exclude the module for compiling on the listed build targets. The available build targets are Game, Server, Client, Editor, and Program.

IncludelistTargetConfigurations / ExcludelistTargetConfigurations (array)

Include or exclude the module for compiling on the listed build configurations. The available target configurations are Debug, DebugGame, Development, Shipping, and Test.

IncludelistPrograms / ExcludelistPrograms (array):

Include or exclude the module for compiling under specific program names.

AdditionalDependencies (array):

Specifies additional dependencies needed by the module. You should specify this in your Build.cs files instead.

1. Required Setup

2. Setting Up Your Directories

3. Creating the Build.cs File

4. Implementing Your Module in C++

5. Compiling Your Module

6. Including Your Module In Your Project

7. Adding Code to Your Module

8. Extending Code From Your Module

Final Result

Unreal Engine (UE) Modules are a useful way to organize your code, improve your project's build times, and configure its loading and unloading processes for systems and code. This guide will cover the steps necessary to implement a new runtime module from scratch in C++. This module will be separate from the primary module for your project.

The module in this example is named ModuleTest.

1. Required Setup

To follow this guide, start by creating a new project named MyProject, and make sure it is a C++ project. If you are following along with a Blueprint-only project, create a new piece of C++ code in Unreal Editor to convert it to a C++ project.

2. Setting Up Your Directories

First, you need to set up directories to contain the module and its code.

Navigate to your project's root directory, then open the Source folder.

Inside your project's Source folder, make a new folder named ModuleTest. This will serve as your module's root directory.

Inside your module's root directory, create two new folders called Private and Public.

Your directory structure should resemble this:

MyProject

Source

MyProject.Target.cs

MyProjectEditor.Target.cs

MyProject (Primary game module folder)

Private

Public

MyProject.Build.cs

Other C++ classes in your game module

ModuleTest

Private

Public

3. Creating the Build.cs File

When Unreal Build Tool (UBT) looks through your project's directories for dependencies, it ignores your IDE solution file and instead looks at the Build.cs files in your Source folder. Every module must have a Build.cs file, or else UBT will not discover it.

To set up your Build.cs file, follow these steps:

Create a file called ModuleTest.Build.cs in your module's root directory. Open this file and add the following code:

ModuleTest.Build.cs

This will make your module visible to the Unreal build system.

Edit the constructor so that it reads as follows:

ModuleTest.Build.cs

This will add the Core, CoreUObject, and Engine modules as private dependencies for your module. This will make several classes available to this module for later steps in this guide.

Now when you add code to this module's folders, that code will be discovered both when UBT builds the project and whenever you generate your IDE project files.

4. Implementing Your Module in C++

While the Build.cs file makes your module discoverable to UBT, your module also needs to be implemented as a C++ class so that the engine can load and unload it.

Fortunately, Unreal Engine includes macros that can streamline this process for most common implementations. To make a quick implementation file, follow these steps:

Navigate to your module's root directory and open the Private folder. Create a new file called ModuleTestModule.cpp inside this folder. It is not necessary to make a .h file for this class.

[ModuleName]Module is the typical naming convention for module implementation files in Unreal Engine source code. This is useful for keeping track of them in a large codebase.

Inside ModuleTestModule.cpp, add the following code:

ModuleTestModule.cpp

This provides a default implementation for your module that makes it available to C++ code.

You can create more detailed implementations by manually writing the class for your module, its constructor, and the Startup and Shutdown functions for it. However, for most gameplay modules, this default implementation will be sufficient to load and unload your module.

5. Compiling Your Module

After defining and implementing your module, the process to compile it is very simple.

Right-click MyProject.uproject and click Generate Visual Studio Files to regenerate your IDE solution.

This will ensure that your new module becomes visible in your IDE and within Unreal Editor.

Any time you re-organize your module's code or change the contents of its Build.cs file, you should regenerate your IDE solution to make sure it stays up to date.

Compile your project in Visual Studio. Your new module will be compiled alongside it.

Any time you add a new module manually, change your module's directory structure, move or rename C++ files, or change your module's dependencies, you should regenerate your project files to update your Visual Studio solution, then compile your project again.

Although you can compile your project while Unreal Editor is running, sometimes you will need to close Unreal Editor, then restart it after compiling for major changes or new classes to take effect.

6. Including Your Module In Your Project

Your module should be able to compile, but to use any code from your module in your project, you need to register it with your .uproject file, then make a dependency for your game's primary module.

Open the MyProject root directory, then open MyProject.uproject in a text editor and edit your "Modules" list as follows:

MyProject.uproject

You can use this list entry to configure which Loading Phase it will load up on and its Type. This example is a runtime module, so it can be used when the project is running as a standalone application or in the editor.

By comparison, Editor modules can only run in the editor. It also uses the Default loading phase, which initializes after game modules are loaded. Depending on the specifics of your module, you might need to use earlier loading phases to make sure other modules that depend on it don't throw errors looking for unloaded code.

Navigate to your MyProject/Source folder, then open the MyProject.Build.cs file. Add ModuleTest to your PublicDependencyModuleNames list. It should as follows:

MyProject.Build.cs

Now it will be possible to include code from your module in your primary game module.

7. Adding Code to Your Module

You can add C++ files to the Public and Private directories in your module manually, or you can add them in Unreal Editor.

These steps will guide you through using the New Class Wizard to add code to a module:

Open your project in Unreal Editor.

In the Content Browser, click Add, then click New C++ Class.

Choose Actor as the parent class, then click Next.

Locate the dropdown next to the Name field. It should read MyProject (Runtime) by default. Click this dropdown, then change it to ModuleTest (Runtime).

If you do not see MyModule (Runtime) as an option, review the previous sections to ensure you followed the steps correctly.

Name the class ModuleActorBase, set the Class Type to Public, then click Create Class.

Your class's .h and .cpp files will open automatically in your IDE. Your class's .cpp file will be added to your module's Private folder, while its .h file will be added to the Public folder.

Open ModuleActorBase.cpp, then add the following line to the AModuleActorBase::BeginPlay function:

ModuleActorBase.cpp

Save your code and compile your module.

This class defines a simple Actor that outputs an on-screen debug message when the game starts. You can test this by using the Place Actors tool in Unreal Editor.

8. Extending Code From Your Module

Finally, follow the steps below to test your new Actor class and your primary game module's ability to see it.

Open your project in Unreal Editor. Create a New Blueprint Class, then expand the All Classes list.

Choose ModuleActorBase as the parent class. Name your Blueprint class ModuleActorBP.

Drag a copy of ModuleActorBP from the Content Browser into your game's world. Click the Play button.

If you do not see ModuleActorBase in the list of classes, make sure its header is in the Public folder, that it has the BlueprintType UCLASS specifier, and that you have added the ModuleTest module to your project's dependencies.

Final Result

When you click Play, your project will start playing in editor, and the on-screen debug message "Hello, world!" will display in blue text. This Blueprint-based Actor extends a class that is defined in a separate gameplay module. When you write modules in the future, you will now be prepared to create extensible classes as a foundation for gameplay-specific code.

Direct Property Reference

Construction Time Reference

Indirect Property Reference

Find/Load Object

Unreal Engine (UE) provides a number of mechanisms to control how an asset is referenced and by extension loaded into memory. You can think of references in two ways: a hard reference where object A refers to object B and causes object B to be loaded when object A is loaded; and a soft reference where object A refers to object B via an indirect mechanism such as the string form of the path to the object. The first two sections following cover hard references with the remaining sections exploring soft references.

Direct Property Reference

This is the most common case for asset references and is exposed via the UPROPERTY macro. Your gameplay class exposes a UPROPERTY that lets your designers specify a particular asset on either the archetype via Blueprint inheritance or via an instance placed in the world. For instance, the code below is from the AStrategyBuilding contained in the StrategyGame sample and allows the designer to select which sound is played when a building of a type is constructed.

This property can only be set as part of the default properties for an object (the EditDefaultsOnly keyword controls this). The designer creates a new Blueprint class that extends from AStrategyBuilding. Then the sound the designer wants can be saved for that Blueprint. Whenever that designer created Blueprint is loaded, the sound that it references as part of that UPROPERTY is automatically loaded too.

Construction Time Reference

The second type of hard reference you will encounter is when the programmer knows the exact asset that needs to be loaded for a given property and sets that property as part of the object's construction. This is done using a special class, ConstructorHelpers, which finds objects and classes for an object during the construction phase. Again from the StrategyGame sample, here's a snippet of the HUD assigning assets that it wants to use as part of its rendering.

In the constructor above, the ConstructorHelpers class attempts to find the asset in memory and loads it if not found. Note the full path to the asset is used to specify what to load. If the asset doesn't exist or can't be loaded due to an error, the property will be set to nullptr. When this happens, the code that tries to access the texture will crash. It's better to assert that the asset loaded correctly if the later code assumes the reference is valid.

The declaration of the UPROPERTY appears the same as the previous hard reference example. They function the same way with the only difference being how they are initially set. One consideration about hard references is that as objects are loaded and instantiated the hard referenced assets are loaded too. Careful consideration needs to happen or your memory footprint can balloon due to many assets being loaded at once. If you want to defer that loading or determine what to load at runtime, then the following sections help with that.

Indirect Property Reference

One easy way to control when an asset is loaded is to use a TSoftObjectPtr. To the designer, they can work with it just like the direct property reference. However, instead of a direct pointer reference, the property is stored as a string with template code to enable safe checking of whether the asset has been loaded yet or not. Use the IsPending() method to check if the asset is ready to be accessed or not. Note that using TSoftObjectPtr requires you to manually load the asset when you want to use it. You can use the templated LoadObject<>() method, StaticLoadObject(), or the FStreamingManager to load your object (see Asynchronous Asset Loading for more information). The first two methods load the asset synchronously which can cause frame rate spikes, so should only be used if you know it will not affect the gameplay.

The code above uses a TSoftObjectPtr of UStaticMesh to lazy load the mesh at runtime. The asset is checked to see if the object has been loaded or not. If it has not, a synchronous load happens using the FStreamingManager. Otherwise, the UStaticMesh pointer within the TSoftObjectPtr is returned to the caller.

If you want to defer loading a UClass, you use the same approach as the TSoftObjectPtr substituting the class specific version TSoftClassPtr template type. This functions the same as referring to a specific asset, but instead refers to the UClass for the asset instead of an instance.

Find/Load Object

So far these examples have all been UPROPERTY based. However, what if you want to build a string at runtime and use that to get a reference to an object? There are two options that you can use. If you want to use the UObject only if it has already been loaded or created, then the right choice is FindObject<>(). If you want to load the object if it is not already loaded, then using LoadObject<>() is the right choice. Note that LoadObject<>() does the equivalent of FindObject under the covers, so it's not necessary to try to find the object first and then load it. Here are some examples of using each function.

There is a specialization of LoadObject available when loading a UClass. This is just an easier way to load the class and provides an automatic verification of the type. The code snippet below illustrates this.

Is the same as

Obtaining a List of Assets

Converting FAssetData to UObject*

Creating a Filter

Tags and Values

Asynchronous Data Gathering

The Asset Registry is an editor subsystem which gathers information about unloaded assets asynchronously as the editor loads. This information is stored in memory so the editor can create lists of assets without loading them. The information is authoritative and is kept up to date automatically as assets are changed in memory or files are changed on disk. The Content Browser is the primary consumer for this system, but it may be used anywhere in editor code.

Obtaining a List of Assets

To form a list of assets by class, simply load the Asset Registry module then invoke Module.Get().GetAssetsByClass()

This will return a list of FAssetData objects which describe assets that may be loaded or unloaded. FAssetData objects hold information about an asset that can be determined before it is loaded.

Here is a list of its members and descriptions:

Member

Description

FName ObjectPath

The object path for the asset in the form Package.GroupNames.AssetName.

FName PackageName

The name of the package in which the asset is found.

FName PackagePath

The path to the package in which the asset is found.

FName GroupNames

The '.' delimited list of group names in which the asset is found. NAME_None if there were no groups.

FName AssetName

The name of the asset without the package or groups.

FName AssetClass

The name of the asset's class.

TMap<FName, FString> TagsAndValues

The map of values for properties that were marked AssetRegistrySearchable. See Tags and Values for more information.

You can also form lists using other criteria by invoking one of the following functions:

Function

Description

GetAssetsByPackageName()

Returns a list of assets from a particular package.

GetAssetsByPath()

Returns a list of assets in a specified path.

GetAssetByObjectPath()

Returns a list of assets with the specified object paths.

GetAssetsByTagValues()

Returns a list of assets with the specified set of tags and values.

GetAllAssets()

Returns a list of all assets. This can be slow.

If you need to form a list of assets using multiple criteria, use GetAssets() and supply a FARFilter struct as described in the Creating a Filter section.

Converting FAssetData to UObject*

FAssetData objects have a function named GetAsset() which will return the UObject* that the FAssetData represents. This will load the asset if needed then return it.

If you just want to check if an asset is loaded, use IsAssetLoaded() instead.

Creating a Filter

A FARFilter can be supplied when invoking GetAssets() to create a list of assets which are filtered down by multiple criteria. A filter is comprised of multiple components:

PackageName

PackagePath

Collection

Class

Tags/Value pairs

A component may have more than one element. An asset passes a filter if it satisfies ALL components. To satisfy a component, an asset must match ANY of the elements within.

For example, if a StaticMesh asset exists whose path is /Game/Meshes/BeachBall:

The asset will pass if the filter includes only the PackagePath /Game/Meshes. There is only one component which has one element.

The asset will pass if the filter includes the PackagePath /Game/Meshes and Classes UParticleSystem AND UStaticMesh. There are two components where the first has one element and the second has two.

The asset will fail if the filter includes the PackagePath /Game/Meshes and ONLY the Class UParticleSystem. There are two components that each have one element.

The asset will fail if the filter includes the PackagePath /Game/NotMeshes and the Class UStaticMesh. This filter also uses two components that each have one element.

An example of using a filter with two components, Class and PackagePath:

Tags and Values

FAssetData objects returned from the Asset Registry contain a name and value map called TagsAndValues. This is a list of property names and associated values for the asset the FAssetData represents. This information is gathered when an asset is saved and stored in the header of the UAsset file that contains the asset. The Asset Registry reads this header and fills out the TagsAndValues map accordingly. The Asset Registry only gathers properties that are marked with the AssetRegistrySearchable UPROPERTY() flag.

For example (from UTexture):

Once this flag was added to the Filter property of UTexture, all UTextures that were saved thereafter now have an entry in their FAssetData's TagsAndValues map whose key is Filter and whose value is the string representation of the enum value, such as "TF_Linear".

This requires assets to be resaved before their properties will be discovered by the Asset Registry.

If you want the Asset Registry to be able to search for information that is not directly a UProperty, your asset's class can implement the virtual function: GetAssetRegistryTags() to manually add key/value pairs to the TagsAndValues map. GetAssetRegistryTags is inherited from UObject.

Asynchronous Data Gathering

The Asset Registry reads UAsset files asynchronously and may not have a complete list of all assets at the time that you request it. If your editor code requires a complete list, the Asset Registry provides delegate callbacks for when assets are discovered/created, renamed, or removed. There is also a delegate for when the Asset Registry has completed its initial search which is useful for many systems.

You may sign up for these delegates by loading the Asset Registry module, then using the functions provided in IAssetRegistry:

For example:

The Asset Registry can be used in commandlets, but gathers information synchronously

The LoadModule() call will block until the gather is complete.

If your code waits for assets to be discovered asynchronously and has a Slate UI frontend, it should contain an SAssetDiscoveryIndicator widget to convey progress to the user.

FName

FText

FString

Printf

FName

When you name a new asset in the Content Browser, change a parameter in a Dynamic Material Instance, or access a bone in a Skeletal Mesh, you are using FNames. FNames provide a very lightweight system for using strings, where a given string is stored only once in a data table, even if it is reused.

FNames are case-insensitive. They are immutable, and cannot be manipulated. The storage system and static nature of FNames means that it is fast to look up and access FNames with keys. Another feature of the FName subsystem is the use of a hash table to provide fast string to FName conversions.

FName Reference Guide

FText

In Unreal Engine (UE) the primary component for text localization is the FText class. All user-facing text should use this class, as it supports text localization by providing the following features:

Creating localized text literals.

Formatting Text (to generate text from a placeholder pattern).

Generating text from numbers.

Generating text from dates and times.

Generating derived text, such as making text upper or lower case.

FText also features the AsCultureInvariant function (or the INVTEXT macro), which creates non-localized, or "culture invariant" text. This is useful for things like converting a player name from an external API into something you can display in your user interface.

You can create a blank FText using either FText::GetEmpty(), or by using just FText().

FText Reference Guide

FString

Unlike FName and FText, FString can be searched, modified, and compared against other strings. However, these manipulations can make FStrings more expensive than the immutable string classes. This is because FString objects store their own character arrays, while FName and FText objects store an index to a shared character array, and can establish equality based purely on this index value.

FString Reference Guide

Printf

The FString function, Printf, can create FString objects the format argument specifiers as the C++ printf function. Similarly, the UE_LOG macro prints a printf formatted string to the screen, log output, and log files, depending on what type of UE4 build is running.

Remember that to use these strings and conversion you will need to include the necessary header files. A list of which header files are needed can be found on the API reference page for each string.

Conversions

From

To

Example

FName

FString

TestHUDString = TestHUDName.ToString();

FName

FText

TestHUDText = FText::FromName(TestHUDName);

FName -> FText is valid in some cases, but be aware that the FNames's content will not benefit from the FText's "auto localization".



FString

FName

TestHUDName = FName(*TestHUDString);

FString -> FName is dangerous as the conversion is lossy as FName's are case insensitive.



FString

FText

TestHUDText = FText::FromString(TestHUDString);

FString -> FText is valid in some cases, but be aware that the FString's content will not benefit from the FText's "auto localization".



FText

FString

TestHUDString = TestHUDText.ToString();

FText -> FString is dangerous as it is a potentially lossy conversion for some languages.



FText

FName

There is no direct conversion from FText to FName. Instead, convert to FString and then to FName.

FText -> FString -> FName is dangerous as the conversion is lossy as FName's are case insensitive.



FString

int32

int32 TestInt = FCString::Atoi(*MyFString);

FString

float

float TestFloat = FCString::Atof(*MyFString);

int32

FString

FString TestString = FString::FromInt(MyInt);

float

FString

FString TestString = FString::SanitizeFloat(MyFloat);

Encoding

In general, you should be using the TEXT() macro when setting string variable literals. If you do not specify the TEXT() macro, your literal will be encoded using ANSI, which is highly limited in what characters it supports. Any ANSI literals being passed into FString need to undergo a conversion to TCHAR (native Unicode encoding), so it is more efficient to use TEXT().

For more about encoding, see the Character Encoding documentation.

Text Formats

The Case for Binary

The Case for Text

The Case for UTF-8

The Case for UTF-16

UE Internal String Representation

Text Files Loaded by UE

Text Files Saved by UE

Recommended Encoding for Text Files Used by UE

INT and INI Files

Source Code

C++ Source Code

Storing UTF-16 Text Files in Perforce

Conversion Routines

ToUpper() and ToLower() Non-Trivial in Unicode

Notes about C++ Source Code Specific to East Asian Encodings

This document provides an overview of character encodings used in Unreal Engine (UE).

Assumed knowledge: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

Text Formats

There are several formats that can be used to represent text and strings. Understanding these formats and their inherent pros and cons can help in making decisions on what formats to use in your projects.

These are not the technical definitions of formats, but rather simplified versions suitable for this page.

Characters between 32 and 126 inclusive, and 0, 9, 10, and 13. (P4 type text) (This is validated with a P4 trigger on check-in)

ASCII and the current codepage (e.g. Western European high ASCII) needs to be stored as binary on the P4 server.

A string made up of single bytes which can use special character sequences to get non-ANSI characters. (a superset of ASCII) (P4 type Unicode)

A string made up of 2 bytes per character with a BOM. (although can go to 4 bytes with astral characters) (P4 type UTF-16) (This is validated with a P4 trigger on check-in)

The Case for Binary

Pros

Cons

Internal format is not defined; each file can be loaded no matter what format it is.

Non mergable. Requires all files of this type to be exclusive checkout.

Internal format is not defined; each file could be in a different format.

P4 stores the entirety of each version, which can unnecessarily bloat the depot size.

The Case for Text

Pros

Cons

Merge-able. Exclusive checkout is not required.

Very limiting; only ASCII characters allowed.

The Case for UTF-8

Pros

Cons

Simple access to all characters we will ever need.

Has a different memory profile for Asian languages.

Uses less memory.

P4 type Unicode is not enabled on our Perforce server.

Is a superset of ASCII; a plain ASCII string is a perfectly valid UTF-8 string.

String operations more complicated; have to parse the string to do something as simple as a length calculation.

Still works when the game detects the string is ASCII and outputs it as such.

MSDev does not handle anything other than ASCII very well in Asian regions. This is why we validate text as ASCII during check-in.

If we did have a Unicode enabled server, the files would be merge-able and exclusive checkout would not be required.

Can detect whether a string is UTF-8 by parsing it (with or without a BOM).

The Case for UTF-16

Pros

Cons

Simple access to all characters we will ever need.

Uses more memory.

Memory usage is twice the number of characters (for characters we use, which are all in the Basic Multilingual Plane).

Difficult to detect this format if it does not have a BOM.

String operations can split/combine without having to parse the strings.

Does not work when the game detects the string is ASCII and outputs it as such (this is now detected on check-in with the UTF-16 validator).

Same as the format used in game, no translation, parsing or memory operations required.

MSDev does not handle anything other than ASCII very well in Asian regions. This is why we validate text as ASCII during check-in.

Merge-able. Exclusive checkout is not required.

C# uses UTF-16 internally.

UE Internal String Representation

All strings in UE are stored in memory in UTF-16 format as FStrings or TCHAR arrays. Most code assumes 2 bytes is one codepoint so only the Basic Multilingual Plane (BMP) is supported so Unreal's internal encoding is more correctly described as UCS-2. Strings are stored in the endian-ness appropriate for the current platform.

When serializing to packages to/from disk or during networking, strings with all TCHAR characters less than 0xff are stored as a series of 8-bit bytes, and otherwise as 2-byte UTF-16 strings. The serialization code can deal with any endian conversion as necessary.

Text Files Loaded by UE

When UE loads an external text file (for example reading a .INT file at runtime) it is almost always done with the appLoadFileToString() function found in UnMisc.cpp. The main work occurs in the appBufferToString() function.

This function recognizes the Unicode byte-order-mark (BOM) in a UTF-16 file and if present, will load the file as UTF-16 in either endian-ness.

What happens when the BOM is not present depends on the platform.

On Windows, it will attempt to convert the text to UTF-16 using the default Windows MBCS encoding (eg Windows-1252 for US English and Western Europe, CP949 for Korean and CP932 for Japanese) and uses MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS...). This was added around the July 2009 QA build.

If this conversion fails on platforms other than Windows, it will just read each byte and pad it to 16-bits to make an array of TCHAR.

Note that there is no code to detect or decode UTF-8 encoded text files loaded with appLoadFileToString().

Text Files Saved by UE

Most text files generated by the engine will be saved using appSaveStringToFile().

Strings with all TCHAR characters representable by a single byte will be stored as a series of 8-bit bytes, and otherwise as UTF-16 unless the bAlwaysSaveAsAnsi flag is passed in as true, in which case it will be converted to the default Windows encoding first. This is currently only done on shader files, to work around an issue a shader compiler had with UTF-16 files.

Recommended Encoding for Text Files Used by UE

INT and INI Files

UTF-16 in either endian. While the default MBCS encoding for an Asian language (eg CP932) will work on Windows, these files need to be loaded on PS3 and Xbox360 and the conversion code only runs on Windows.

Source Code

In general, we do not recommend string literals inside C++ source code and we recommend this data goes in INT files.

UTF-8 or default Windows encoding. MSVC, the Xbox360 compiler and gcc should all be happy with UTF-8 encoded source files. Latin-1 encoded files with characters with the high bit set, for example copyright, trademark or degree symbols should be avoided in source code where possible because the encoding will break on systems with different locales. Some instances of this in 3rd party software are unavoidable (eg copyright notices) so for MSVC we disable warning 4819, which would otherwise occur when compiling on Asian Windows.

Storing UTF-16 Text Files in Perforce

Do not use 'Text'

If a UTF-x file is checked in and stored as text, it will be corrupted after syncing.

If you use 'Binary', mark the files as exclusive checkout

People can check in ASCII, UTF-8, UTF-16 and it will work in engine.

However, binary files cannot be merged, so if the files are not marked as exclusive checkout, changes will be stomped upon.

If you use 'UTF-16', make sure no one checks in a file that is not UTF-16

The 'Unicode' type is UTF-8, and of no use to us here.

Conversion Routines

We have a number of macros to convert strings to and from various encodings. These macros use a class instance declared in local scope and allocate space on the stack, so it is very important you do not retain pointers to them! They are intended only for passing strings to function calls.

TCHAR_TO_ANSI(str)

TCHAR_TO_OEM(str)

ANSI_TO_TCHAR(str)

TCHAR_TO_UTF8(str)

UTF8_TO_TCHAR(str)

These use the following helper classes from UnStringConv.h:

typedef TStringConversion<TCHAR,ANSICHAR,FANSIToTCHAR_Convert> FANSIToTCHAR;

typedef TStringConversion<ANSICHAR,TCHAR,FTCHARToANSI_Convert> FTCHARToANSI;

typedef TStringConversion<ANSICHAR,TCHAR,FTCHARToOEM_Convert> FTCHARToOEM;

typedef TStringConversion<ANSICHAR,TCHAR,FTCHARToUTF8_Convert> FTCHARToUTF8;

typedef TStringConversion<TCHAR,ANSICHAR,FUTF8ToTCHAR_Convert> FUTF8ToTCHAR;

It is also critical that when using TCHAR_TO_ANSI you do not assume the number of bytes will be the same as the TCHAR string length. Multiple byte character sets could require multiple bytes per TCHAR character. If you need to know the length of the resulting string in bytes, you can use the helper class instead of the macros. For example:

The objects that these macros declare have very short lifetimes. The intended use case for them is as function parameters, and they are suited to this situation. Do not assign a variable to the contents of the converted string, as the object will go out of scope and the string will be released. This can cause crashes if your code continues to access the pointer to released memory.

ToUpper() and ToLower() Non-Trivial in Unicode

UE4 currently only handles ANSI (ASCII | code page 1252 | | Western European).

The least worst method to do this for all languages seems to be mentioned here en.wikipedia.org/wiki/ISO/IEC_8859

ISO/IEC 8859-1 for English, French, German, Italian, Portuguese, and both Spanishes

ISO/IEC 8859-2 for Polish, Czech, and Hungarian

ISO/IEC 8859-5 for Russian

The mappings from ftp.unicode.org/Public/MAPPINGS/ISO8859/ contain the conversion rules for the above mentioned languages. 'CAPITAL LETTER' and 'SMALL LETTER' info would be cross referenced with the appropriate unicode character to get the desired result.

Notes about C++ Source Code Specific to East Asian Encodings

Both UTF-8 and the default Windows encodings can cause problems with the C++ compiler, as follows:

Default Windows encoding

Take care when compiling C++ source code on Windows with running with a single byte character code page (e.g. CP437 United States), if the source code has an East Asian double byte character encoding such as CP932 (Japanese), CP936 (Simplified Chinese), or CP950 (Traditional Chinese).

These East Asian character encoding systems uses 0x81-0xFE for first byte, and 0x40-0xFE for second byte. A value of 0x5C in the second byte will be interpreted as backslash in ASCII/latin-1, and that has a special meaning for C++. (Escape sequence inside a string literal, and line continuation if used at the end of a line).When compiling that source code on single-byte code page Windows, the compiler does not care about the East Asian double byte character encoding, and this could cause either a compile error or worse, create a bug in the EXE.

Single-line comments:These can cause difficult-to-find bugs or errors caused by a missing line, if in the end of East Asian comment has 0x5c.

Inside a string literal:This can cause a broken string or an error with an recognized 0x5c escape sequence.

If the character following 0x5c does specify a escape sequence, compiler converts escape sequence character set to single specified character.(If does not specify, the result is implementation defined, but MSVC removes 0x5c, and warns "unrecognized character escape sequence".)In the above case, the end of string has a 0x5c backslash and next character is a double quote, so the escape sequence \" is converted to a double quote in the string data, and compiler continues to make string data before next double quote or end of file, and causes an error.

Examples of dangerous characters:CP932 (Japanese Shift-JIS) "?" is 0x955C, and so many CP932 characters have 0x5C.CP936 (Simplified Chinese GBK) "?" is 0x815C, and so many CP936 characters have 0x5C.CP950 (Traditional Chinese Big5) "?" is 0xA55C, and so many CP950 characters have 0x5C.CP949 (Korean, EUC-KR) is OK, because EUC-KR does not use 0x5C for the second byte.

UTF-8 without BOM (Some text editors describe BOM as signature)

Take care for compiling C++ source code on East Asian code page CP949 (Korean), CP932 (Japanese), CP936 (Simplified Chinese) or CP950 (Traditional Chinese) Windows, if that source code has an East Asian character stored as UTF-8.

UTF-8 character encoding uses three bytes for East Asian characters: 0xE0-0xEF for the first byte, 0x80-0xBF for the second byte and 0x80-0xBF for the third byte. Without the BOM, East Asian Windows' default encoding recognizes the three UTF-8 encoded bytes and the following byte as two 2-byte East Asian encoded characters, pairing of first and second bytes for one first East Asian character, and the third byte and following byte paired to form the second East Asian character.Problems can occur if the character following the UTF-8 encoded three bytes has special meaning in the string literals or comments.

Eg In in-line comment:Causes hard-to-find bugs or errors with missing code, if the comment text contains an odd number of East Asian characters, and next character marks the end of the comment.

The compiler on East Asian code page Windows recognizes the last byte of the UTF-8 decoded East Asian character comment and asterisk * as a single East Asian character, and next characters is treated as still part of the comment. In above case, compiler removes important_function() as it seems to be part of the comment.This behavior is very dangerous and it is difficult to find the missing code.

In single-line comment:Using backslash '\' at the end of an East Asian comment causes hard-to-find bugs or errors without missing lines.

This is a very rare case, because programmers should not intentionally write backslashes '\' at the end of comments.

Inside string literals:This causes broken strings, errors or warnings when an odd number of UTF-8 encoded East Asian characters are inside a string literal and the following character has special meaning.

The C++ compiler on East Asian code page Windows interprets the last byte of the UTF-8 decoded East Asian character string and next character as a single East Asian character. If you are lucky, compiler warning "C4819" (if not disabled) or an error will alert you to the problem. If unlucky, the string would be broken.

Conclusion

You can use UTF-8 or default Windows encoding for C++ source code, but please be aware of these problem. Again, we do not recommend string literals inside C++ source. Please make sure to use East Asian as your default code page if you have to use East Asian character encoding in C++ source code.Another good way is to use UTF-8 with BOM (some text editors describes the BOM as a Unicode signature).

We tested a few compilers with UTF-8 and UTF-16 on 18 Feb 2010.

MSVC for PC and Xbox 360, and gcc or slc for PS3 are able to compile UTF-8-encoded source code (with and without BOM). But UTF-16 (little-endian/big-endian) is supported only by MSVC.

Perforce is able to work with both UTF-16 and UTF-8, but p4 diff displays the BOM in UTF-8 files as a visible character.

External reference: Code Pages Supported by Windows

Creating FStrings

Conversions

String Variables

Numeric and Other Variables

Comparisons

Searching

Building FStrings

Concatenation

Printf

Manipulating FStrings

FStrings in HUDs

Canvas

Debug Messaging

Print to Viewport

Print to Output Log

Encoding Conversion Macros

Unlike FName and FText, FString can be searched, modified, and compared against other strings. However, these manipulations can make FStrings more expensive than the immutable string classes. This is because FString objects store their own character arrays, while FName and FText objects store an index to a shared character array, and can establish equality based purely on this index value.

Creating FStrings

You can declare an FString using the following syntax:

Conversions

String Variables

From

To

Example

FString

FName

TestHUDName = FName(*TestHUDString);

FString -> FName is dangerous as the conversion is lossy as FName's are case insensitive.



FString

FText

TestHUDText = FText::FromString(TestHUDString);

FString -> FText is valid in some cases, but be aware that the FString's content will not benefit from the FText's "auto localization".



From

To

Example

FName

FString

TestHUDString = TestHUDName.ToString();

FText

FString

TestHUDString = TestHUDText.ToString();

FText -> FString is dangerous as it is a potentially lossy conversion for some languages.



Numeric and Other Variables

Variable Type

Conversion from String

String Format

float

FString::SanitizeFloat(FloatVariable);

int

FString::FromInt(IntVariable);

bool

InBool ? TEXT("true") : TEXT("false");

either 'true' or 'false'

FVector

VectorVariable.ToString();

'X= Y= Z='

FVector2D

Vector2DVariable.ToString();

'X= Y='

FRotator

RotatorVariable.ToString();

'P= Y= R='

FLinearColor

LinearColorVariable.ToString();

'(R=,G=,B=,A=)'

UObject

(InObj != NULL) ? InObj->GetName() : FString(TEXT("None"));

UObject's FName

For other numeric conversions, you can use the FString::Printf() function with the appropriate arguments.

Conversions also exist from FString to int and float numeric variables, as well as to boolean variables.

Variable Type

Conversion from String

Notes

bool

TestHUDString.ToBool();

int

FCString::Atoi(*TestHUDString);

float

FCString::Atof(*TestHUDString);

Comparisons

The overloaded == operator can be used to compare two FStrings, or to compare an FString to an array of TCHAR*s. There is also the FString::Equals() method, which takes the FString to test against and the ESearchCase enum for whether or not the comparison should ignore case as arguments. If you want the comparison to ignore case, use ESearchCase::IgnoreCase, and if not, use ESearchCase::CaseSensitive.

Searching

When searching within FStrings, there are two search types. The first, FString::Contains(), returns true if the substring is found, and false otherwise. FString::Contains() can search for either an FString or a TCHAR*s substring. The ESearchCase enum can be used to specify whether or not the search should ignore case. Also, the ESearchDir enum can be used to specify the direction of the search. The default is to ignore case, and to begin searching at the start.

The second, FString::Find(), returns the index of the first found instance of the substring. FString::Find() can search for either an FString or a TCHAR*s substring. Just like with FString::Contains(), you can specify the case sensitivity and the search direction, and the defaults are to ignore case and begin at the start of the string. You can also optionally set an index within the string where the search should begin. If FString::Find() does not find the substring, it returns -1.

Building FStrings

There are two methods to construct strings out of substrings or other variable types. The first, concatenation, only takes FStrings as arguments. You will need to convert other types of variables to FStrings before concatenating them. The second, Printf, can take numeric inputs like int and float, and also allows you to set the formatting of the inputs as they are added to the string.

Concatenation

There are two operators for concatenating strings:

Operator

Description

Usage

+=

Appends the supplied string to the FString object.

StringResult += AddedString;

+

Creates a new FString object and appends the supplied string.

Printf

FStrings constructed with FString::Printf can be stored into FStrings, as well as displayed to the screen with UE_LOG debug messaging. The format argument has the same specifiers as the C++ printf function, as seen in the below example.

When using %s parameters to include FStrings, the * operator must be used to return the TCHAR* required for the %s parameter.

Manipulating FStrings

There are many functions for manipulating strings. Some will be covered here, but for the full list of available FString functions, see UnrealString.h or the API documentation on FString. There are functions for copying subsections of strings: Left, Right, and Mid. You can split a string into two strings at the location of a found substring. This is done using the Split method. Another method for splitting strings is the ParseIntoArray, which splits a string into an array of strings separated by a specified delimiter. Case conversion is done by using ToUpper and ToLower, converting the string to upper and lower case respectively.

FStrings in HUDs

Canvas

To display an FString in a HUD using Canvas, call the FCanvas::DrawText() function:

You must call the DrawText() function within your HUD class's DrawHUD() function, or call it in a function chain that begins with DrawHUD().

Debug Messaging

FStrings can be printed to the Viewport as well as to the Output Log for debugging purposes.

Print to Viewport



To print debug messages to the Viewport, use UEngine::AddOnScreenDebugMessage(). This function takes the following four parameters (in order):

Parameter Name

Parameter Type

Description

Key

int

A unique key to prevent the same message from being added multiple times. Use -1 as the key to have your debug message be transient.

TimeToDisplay

float

How long to display the message, in seconds.

DisplayColor

FColor

The color to display the text in.

DebugMessage

FString

The message to display (FString).

Example:

Print to Output Log



UE_LOG uses printf markup for parameterization.

LogClass is the log category. You can use an existing category (set with the DECLARE_LOG_CATEGORY_EXTERN macro in OutputDevices.h) or define your own using DEFINE_LOG_CATEGORY_STATIC.

Log is the verbosity level to use. Verbosity is defined in the ELogVerbosity enum. Valid values are Fatal, Error, Warning, Display, Log, Verbose, or VeryVerbose.

The next argument is the text you wish to output, including the markup for the parameters.

This example uses a %s parameter, so the * operator is used to return the TCHAR* required for a %s parameter.

Messages printed with UE_LOG can be found in the Output Log (Window > Output Log in Unreal Editor).

Encoding Conversion Macros

The FString class is built upon a TArray of TCHARs. There are multiple macros available to convert an application string (TCHAR*) to either ANSI or UNICODE character sets and vice versa. The macro definitions are found in Engine\Source\Runtime\Core\Public\Containers\StringConv.h.

If the string is relatively small, the allocation is made on the stack as part of the converter class; otherwise the heap is used to allocate a temporary buffer. The size before using the heap is a template parameter, so you can tune this to your application. This is safe within loops because the scoping of the class pops off the stack allocation.

The common conversion macros are:

TCHAR_TO_ANSI - Converts an engine string (TCHAR*) to an ANSI one.

ANSI_TO_TCHAR - Converts an ANSI string to an engine string (TCHAR*).

The objects these macros declare have very short lifetimes. They are meant to be used as parameters to functions. You cannot assign a variable to the contents of the converted string as the object will go out of scope and the string will be released.

The parameter you pass in must be a proper string, as the parameter is typecast to a pointer. If you pass in a TCHAR instead of a TCHAR*, it will compile and then crash at runtime.

Usage: SomeApi(TCHAR_TO_ANSI(SomeUnicodeString));

Creating FNames

Conversions

From FName

To FName

Comparisons

Using FNames

Searching the Name Table

When you name a new asset in the Content Browser, change a parameter in a Dynamic Material Instance, or access a bone in a Skeletal Mesh, you are using FNames. FNames provide a very lightweight system for using strings, where a given string is stored only once in a data table, even if it is reused.

FNames are case-insensitive. They are immutable, and cannot be manipulated. The storage system and static nature of FNames means that it is fast to look up and access FNames with keys. Another feature of the FName subsystem is the use of a hash table to provide fast string to FName conversions.

FNames are case-insensitive, and are stored as a combination of an index into a table of unique strings and an instance number.

Creating FNames

Conversions

FNames can only be converted to FStrings and FText, and can only be converted from FStrings.

From FName

From

To

Example

FName

FString

TestHUDString = TestHUDName.ToString();

FName

FText

TestHUDText = FText::FromName(TestHUDName);

FName -> FText is valid in some cases, but be aware that the FNames's content will not benefit from the FText's "auto localization".



To FName

From

To

Example

FString

FName

TestHUDName = FName(*TestHUDString);

FString -> FName is dangerous as the conversion is lossy as FName's are case insensitive.



FText

FName

There is no direct conversion from FText to FName. Instead, convert to FString and then to FName.

FText -> FString -> FName is dangerous as the conversion is lossy as FName's are case insensitive.



When doing these conversions, be aware that they may contain characters that are not valid for the type of FName you are creating. The INVALID_NAME_CHARACTERS macro in NameTypes.h defines which characters are invalid for FNames, and several functions within FName (such as IsValidObjectName()) check the validity of FNames for particular use cases.

Comparisons

The == operator can be used to compare two FNames, and returns true or false. Rather than doing string comparisons, this compares the values in Index, which is a significant CPU savings.

FName::Compare can also be used to compare two FNames, and it will return less than 0 if this less than Other, 0 if this equal to Other, and greater than 0 if this greater than Other.

Using FNames

Using an FName is pretty straightforward. Let us say that you wanted to get the bone named pelvis from the Skeletal Mesh Component of an Actor. The C++ code below shows the use of an FName constructed on the fly while being passed to GetBoneRotation().

This creates an FName that is passed to GetBoneRotation(), which returns the FRotator for that corresponding bone. The name of the bone gets loaded into the FName table when the package loads, so the constructor for the FName finds the bone's name in the hash table, avoiding an allocation.

Searching the Name Table

If you want to determine if an FName is in the name table, but you do not want to automatically add it, you can supply a different search type to the FName constructor:

If the name does not exist in the name table, the Index of the FName is set to NAME_None. Note that we are not checking a pointer for null as you would with a normal string.

Text Localization

Localization

Conversion

Comparison

Using FText in User Interfaces

Slate/UMG

HUD/Canvas

In Unreal Engine (UE) the primary component for text localization is the FText class. All user-facing text should use this class, as it supports text localization by providing the following features:

Creating localized text literals.

Formatting Text (to generate text from a placeholder pattern).

Generating text from numbers.

Generating text from dates and times.

Generating derived text, such as making text upper or lower case.

FText also features the AsCultureInvariant function (or the INVTEXT macro), which creates non-localized, or "culture invariant" text. This is useful for things like converting a player name from an external API into something you can display in your user interface.

You can create a blank FText using either FText::GetEmpty(), or by using just FText().

Conversion

FText can be converted to and from FString. However, because FText contains character strings linked to localization data, while FString only contains a character string, these methods are inherently lossy and will discard (or fail to create) localization data. An alternative method, Text Value Marshalling provides lossless conversion, although this method produces data more suitable for internal marshalling than human consumption.

The following conversion functions produce FText strings, but without localization data:

FText Function

Description

AsCultureInvariant

Creates a non-localized and culture invariant FText instance from an existing FString.

FromString

Creates a non-localized FText instance from an existing FString.

This is identical to AsCultureInvariant in non-editor builds. In editor builds, this function does not flag the text as culture invariant, which means it could still become localizable if assigned to an FText property in a saved Asset.

FromName

Creates a non-localized FText instance from an existing FName. This is the same as calling FromString on the output of the FName parameter's ToString function.

To convert from FText to FString, use the ToString function. The resulting FString will hold the string data from the FText, but not the localization data.

Comparison

Because FText data is more complex than simple strings, it does not support overloaded-operator comparisons. Instead, it provides several functions to perform comparisons that recognize the nuanced data that it contains. The following comparison functions are available:

FText Function

Description

EqualTo

This function takes an ETextComparisonLevel value to determine what comparison rules to use. It returns a bool indicating whether or not the calling FText matches the other under those comparison rules.

EqualToCaseIgnored

This function is a wrapper for calling EqualTo with an ETextComparisonLevel value of Second. The return value comes directly from EqualTo.

CompareTo

This function takes an ETextComparisonLevel value to determine what comparison rules to use. It returns an int32 like most string- or memory-comparison functions, where zero indicates equality, and negative or positive values indicate that the calling FText sorts lower or higher, respectively, relative to the FText parameter.

CompareToCaseIgnored

This function is a wrapper for calling CompareTo with an ETextComparisonLevel value of Second. The return value comes directly from CompareTo.

Using FText in User Interfaces

Slate/UMG

Slate and UMG use FText attributes or arguments for any built-in Widgets that show or manage user-facing text. We recommend using FText for any custom Widgets that you build.

HUD/Canvas

To display FText through the HUD system with Canvas, create a new FCanvasTextItem and set its Text variable to the text you want to display, as in the following example code:

When using Canvas in a HUD, you must call DrawItem within the DrawHUD function, or call it in a function chain that begins with DrawHUD.

Launching

Technical Details

Waiting for Task Completion

Busy-waiting

Prerequisites

Nested Tasks

Pipes

Task Events

Debugging and Profiling

Tasks System is a job manager that provides the capability to execute your gameplay code asynchronously. It supports building and running a directed acyclic graph of dependent tasks. It improves on the TaskGraph, the job manager used in Unreal Engine (UE). Tasks System and TaskGraph both use the same backend (the scheduler and worker threads).

The main features are:

Launching a task by providing a callable object that needs to be executed asynchronously.

Waiting for task completion and/or retrieving the task execution result.

Specifying task prerequisites — other tasks that must be completed before the task execution starts.

Launching nested tasks from inside a task. A parent task is not completed until all its nested tasks are completed.

Building task chains, also known as pipes.

Using task events for synchronization and signaling between tasks.

All code samples assume using the namespace UE::Tasks for brevity.

Launching

To Launch a task, you will need to provide the task's debug name and a callable object "task body". For example:

The code above launches a task that will execute the given function asynchronously. The first parameter is the task's debug name (preferably unique). Its purpose is to help debug tasks and assist in finding the code that launched the task.

UE_SOURCE_LOCATION is a macro that generates a string in the format file name of the source file and the line where it is used. This example shows a "fire and forget" task, this means that you don't need to care what happens to the task after it has been launched because it is eventually executed.

Often you will need to wait for task completion or retrieve its execution result. This can be done by using the Task object returned by the Launch call:

A task execution can return a result. FTask is an alias of TTask<void>, a specialization of generic TTask<ResultType>. ResultType should match the type of the result returned by the task body:

Tasks are executed asynchronously and potentially concurrently with the launching thread, so their execution order is undefined. Though we can still affect the tasks execution order by specifying task priority. Task priorities are "high", "normal" (default), "background high", "background normal", and "background low". Tasks with higher priority are executed before tasks with lower priority.

A lambda function is typically used as a task body, though any callable object can be used too.

Technical Details

FTask is a handle of an actual task, which is similar to a smart pointer. It uses reference counting to manage its lifetime. Launching a task starts its lifetime and allocates the required resources. To release a held reference you can "reset" the task handle using the following:

Releasing a task handle doesn't immediately lead to task destruction. The system holds its own reference used to execute the task. This reference is released after task completion.

Refer to Launch for additional information.

Waiting for Task Completion

You may often need to know if a task is completed, to wait for its completion, or to retrieve its execution result.

Task Command

Implementation Method

Check if a task is completed

Example:

Wait for task completion

Example:

Wait for task completion with timeout

Example:

Wait until all tasks are completed

Example:

Retrieve task execution result. The call is blocked until the task is completed and its result is ready.

Example:

Waiting should be avoided if possible, as it limits scalability. Instead, we recommend you build task graphs by defining dependencies between tasks and designing task-based asynchronous APIs. See Wait, and GetResult() for more information.

Busy-waiting

A problem of waiting for task completion is that it blocks the current thread, therefore it isn't useful. An alternative approach is to use Busy-waiting. When using Busy-waiting, the thread will attempt to execute other tasks until the task that is being waited for is completed.

While Busy-waiting can be useful in a controlled environment, it has its own set of issues and should be used with caution. The main issue is that it isn't possible to control which tasks are picked by the scheduler to be executed during Busy-waiting.

This can lead to deadlocks(meaning a thread is busy waiting and has locked a non-reentrant mutex while a task picked up by the scheduler had tried to lock the same mutex), or result in worse performance where the scheduler picks up a long-running task while busy-waiting for a shorter one on the critical path.

Refer to BusyWait() for additional information.

Prerequisites

Tasks can have dependencies on other tasks. If task A can be executed only after task B is completed, then task B is called a prerequisite of task A and task A is called a subsequent of task B. This allows for building a directed acyclic graph of tasks.

The main advantage of using task dependencies is that it doesn't block the worker threads. Additionally, dependencies allow you to force the task execution order, which is not normally guaranteed. The code below builds a simple Prerequisite to Subsequent dependency:

In the code example below, the Prerequisites() is a helper function:



Refer to Launch for additional information.

Nested Tasks

Nested tasks are similar to prerequisites, but while prerequisites are execution dependencies, nested tasks are completion dependencies. Consider task A that launches task B during its execution, and task A can be completed only when its execution is finished and task B is completed. This is a common pattern when a system exposes a task-based async interface, but task B is part of the implementation therefore it's undesirable to leak this task.

The simplest implementation would be the following:

This is a basic implementation to accomplish the task, but it is inefficient as the worker thread executing task A is blocked waiting for task B completion, therefore it is not used to execute other tasks.

The solution is to use nested tasks. In our example, task A is a parent task, and task B is a nested task because its execution should be nested inside task A's execution:

AddNested adds the given task as nested to the task being executed by the current thread. It asserts if it isn't called from inside a task.

Refer to AddNested() for more information.

Pipes

A Pipe is a chain of tasks that are executed one after another (not concurrently). Consider a shared resource accessed from multiple threads. A classic approach to synchronize the access is to "lock" the resource by locking a mutex. This often brings a significant performance penalty as the thread gets blocked, especially if there is resource contention.

For complex resources, it is desirable to provide an async interface that allows initiating an async operation to work on the resource and an ability to check if the operation is completed(or is to subscribe to a completion notification).

Implementing an async interface often is not a trivial task. Pipes were designed to streamline this. The intention is to have a pipe per a shared resource. All accesses to the shared resource are performed inside tasks launched by the pipe. For example:

FThreadSafeResource provides a public thread-safe async interface based on tasks. It encapsulates a thread-unsafe resource. The implementation is straightforward and consists of boilerplate code. Any access to the thread-unsafe resource happens inside piped tasks.

As those piped tasks are executed sequentially, there's no need for any additional synchronization. Pipes are lightweight objects, therefore they don't store a collection of their tasks. It's possible to have thousands of pipes without a significant drop in performance.

To make a task piped, it needs to be launched by a pipe:

TaskA and TaskB will not be executed concurrently, so they don't need to synchronize with each other to access a shared resource. While most of the time the order of execution is predictable, the order in which the tasks are launched is not guaranteed.

Piped tasks support the same features that other tasks do, for example, they can have dependencies and follow the order of behavior. First, dependencies are resolved then a task is piped. This means that a task with pending dependencies doesn't block a pipe execution and that dependencies can alter the piped tasks' execution order.

You can consider pipes to be green threads. Those green threads are executed by the worker threads, and can "jump threads". For instance, In the previous example, TaskA and TaskB can be executed by different threads.

Pipes API is thread-safe.

Pipe objects are non-copyable and non-movable.

It is not possible to launch a task in multiple pipes.

Refer to FPipe for additional information.

Task Events

Task events are a special task type that doesn't have a task body and can't do any execution. A significant difference is that task events initially are not launched (signaled), and need to be explicitly triggered. Task events are useful as a synchronization and signaling primitive. They are similar to the one-time FEvent. They can be used as a prerequisite or subsequent of other tasks.

Below is a table that provides some examples of what can be done using Task Events.

Task Event Example

Implementation Method

Launch a task but hold its execution until explicitly released.

Example:

The event is used as a prerequisite for the task. Initially, the event is in a non-signaled state, therefore it hasn't been completed, which means that the task has a pending dependency and won't be scheduled and executed until it is resolved. Task events are switched to the signaled state by triggering them.

Use a task event as a joiner task.

Example:

The joiner depends on TaskA and TaskB. Waiting for it means waiting for all its dependencies instead of waiting for them individually.

Prerequisites() is a helper function.

Stop task execution in the middle and wait for an event to happen.

Example:

In general, waiting in the middle of a task is not the best idea for performance and scalability reasons. If you find yourself in such a situation, consider redesigning with prerequisites if possible.

Execute a task but don't flag it as completed automatically. Instead, "complete" it explicitly when it's convenient

Example:

See also: FTaskEvent

Debugging and Profiling

Every task, task event, or pipe has a user-provided debug name. This allows the capability to identify them during runtime in the debugger. Visual Studio native visualizers are provided for examining their internal state.

Unreal Insights adds the task trace channel that enables visualization of tasks and their lifetime events. Such as when a task was launched, scheduled, executed, and completed.

Refer to the Unreal Insights documentation for details.

Debugging and profiling are active areas of development and will be further improved in the future.

FTaskEvent

FPipe

Tasks System resides in the UE::Tasks namespace. To use Tasks System you will need to include the Tasks/Task.h library. You can refer to the Tests/Tasks/TasksTest.cpp class for usage examples. The reference table below provides a few examples to the key functions of the Tasks System.

Reference

Description

TTask<ResultType>

A handle of an actual task. It uses reference counting to manage the task's lifetime.

The task is created when it's launched.

Releasing the last user-held reference doesn't necessarily release the task as the system can still hold an internal reference used to execute the task.

FTask is an alias for tasks that do not return results (TTask);

TTask<ResultType>::IsValid()

The function:

Returns true if the task handle references a task. A default-constructed task handle is "empty" and so is "not valid". A task is constructed when it's launched. For example:

Task<ResultType>::Launch

Launches a task for asynchronous execution. In the Code example below launch is used on a task and returns its handle:

Prerequisites are other tasks that must be completed before the task that depends on them is executed. Once all prerequisites are completed, the task is automatically scheduled for execution.

Parameters:

DebugName - a (preferably) unique name for task identification in debugger and profiler. UE_SOURCE_LOCATION macro can be used, that generates a string [Filename]:[Lineno] of the source location where it's used.

TaskBody - a callable object that will be executed asynchronously, e.g. a lambda, a function pointer or a class with operator();

Prerequisites - an iterable collection of TTask. Their result type is not required to match the result type of the task.

Priority - task priority that affects the order in which tasks are executed.

Example:

template<typename... TaskTypes> TPrerequisites<TaskTypes...> Prerequisites(TaskTypes&... Tasks); is a helper function to pass a variable number of prerequisites to Launch() and FTaskEvent::AddPrerequisites(). For additional examples, you can observe the tasks: IsCompleted(), Wait(),GetResult().

TTask<ResultType>::IsCompleted

Returns true if the task is completed or is not valid.

A task is completed if its execution is finished and all its nested tasks are completed.

Example:

For additional examples, you can observe the tasks: Launch(), Wait() and GetResult().

TTask<ResultType>::Wait

Blocks the current thread until the task(s) is completed or waiting timed out. Returns false on timeout. Waiting can take longer than the specified timeout value. The task(s) is completed if Wait() returns true. Returns true immediately if the task is not valid:

Example:

If the task execution is not started yet (it's blocked by a prerequisite, or wasn't picked up by a worker thread yet), waiting for it will "retract" the task and execute it locally (inline). As the task execution hasn't started yet, the waiting thread would need to be blocked while a worker thread executes the task. Executing the task by the waiting thread is not slow process but can be faster, and doesn't occupy a worker thread. Task retraction follows task dependencies, so-called "deep task retraction". If task execution is blocked by prerequisites, task retraction will try to unblock the task by retracting and executing its prerequisites, recursively. If task retraction fails for any reason(the task execution already started) it falls back to blocking waiting.

Example:

The sample above launches three tasks, where Task2 is a prerequisite of Task3. Waiting for Task3 completion may retract Task3 and/or its prerequisite Task2 and execute them online, however this will not apply to Task1.

TTask<ResultType>::BusyWait

Busy waiting for a task is the execution of other unrelated tasks while waiting for the task's completion. This can improve the system throughput but should be used cautiously. Busy waiting can take longer than blocking waiting and could affect latency-sensitive task-chains. In the function below, the task executes other ready for execution tasks until the task that is waited for is completed. Next, the task is completed after BusyWait Returns.

In the code sample below, we execute other ready for execution tasks until the task(s) that is waited for is completed, or waiting timed out. Next, we Return false on timeout. Waiting can take longer than the specified timeout value. The task(s) is completed if BusyWait returns true.

Before executing unrelated tasks, busy waiting first tries to retract the task that is waited for.

TTask<ResultType>::GetResult

Returns a reference to an object returned by the task as a result of its execution (the value returned by task body execution).



This exists only for tasks with non-void ResultType.



If the task is completed, the call returns immediately. Otherwise, it blocks until the task is completed. The result object gets destroyed when the task object is destroyed, which is when the last reference to the task object is released. The call asserts if the task is not valid.

Example:

AddNested()

Registers the given task as "nested" to the "current" task (parent task). The current task is a task that is being executed by the current thread.

The Parent task is not completed until all nested tasks are completed.

Asserts if is called not from inside another task.

Example:

FTaskEvent

FTaskEvent shares a part of its API with TTask<ResultType>. For example, IsValid(), IsCompleted(), waiting and busy-waiting API is the same. This section describes only FTaskEvent specific API.

Reference Task Event

Description

FTaskEvent Constructor

Creates a task event object with the given debug name. In contrast with TTask, task events are "valid" after construction IsValid() == true, and incomplete IsCompleted() == false. Debug name is used to identify a task event object for debugging purposes.

A task event must be triggered before it's destroyed.

Example:

Constructs a pipe object with the given debug name. Debug name is used for debugging purposes, to identify a pipe object.

Pipes are lightweight non-copyable and non-movable objects. The construction of a pipe doesn't allocate dynamic memory and doesn't do any costly processing

FTaskEvent::AddPrerequisites

Adds other tasks (or task events) as prerequisites. Can be called only before triggering the task event. Only when all prerequisites are completed and the task event is triggered does it become "completed" ("signaling").

Example:

FTaskEvent::Trigger

A task event is incomplete ("non-signaling") until it's triggered. Triggering a task event doesn't necessarily make it signaling, only when all its prerequisites are completed and the task event is triggered does it become completed.

Every task event must be triggered. Otherwise, its destructor will assert that the task event is not completed.

FPipe

Pipes are lightweight non-copyable and non-movable objects. The construction of a pipe doesn't allocate dynamic memory and doesn't perform costly processing.

Reference Name

Description

FPipe constructor

Creates a task event object with the given debug name. In contrast with TTask, task events are "valid" after construction IsValid() == true, and incomplete IsCompleted() == false. Debug name is used to identify a task event object for debugging purposes.

A task event must be triggered before it's destroyed.

Example:

Constructs a pipe object with the given debug name. Debug name is used for debugging purposes, to identify a pipe object.

Pipes are lightweight non-copyable and non-movable objects. The construction of a pipe doesn't allocate dynamic memory and doesn't do any costly processing

FPipe destructor

Checks if the pipe has any non completed tasks. A pipe must not have any non completed tasks upon destruction.

HasWork()

Checks if the pipe has any non completed tasks. A pipe must not have any non-completed tasks upon destruction.

WaitUntilEmpty()

This call will block until all pipe's tasks are completed.

Refer to the function HasWork() for an additional example.

Launch()

Launches a task in the pipe. Tasks launched in the same pipe are executed not concurrently (one after another), but can be executed by different worker threads.

IsInContext()

Returns true if called from inside a task that belongs to this pipe. Can be used to check if it's safe to access a shared resource protected by a pipe, such as when the code doesn't have scope of being executed by a piped task.

Versioning of Binaries

Engine Version

Assets and Packages

Coding with Engine Version

Updating the Engine Version

UpdateLocalVersion Commandlet

Object Version

Engine-Level Serialization and Versioning

Object-Level Serialization and Versioning

Custom Serialization Function

Object Version Code Examples

Versioning of Binaries

Unreal Engine (UE) has multiple versioning systems that define and ensure compatibility between the Engine and the code and data it consumes. Versioning can be used not only to detect incompatible code or data, but also to manage custom serialization and data conversion. We will break UE versioning into three main systems: Engine Version, Serialization Version, and Build ID.

Engine Version

The Engine Version is the highest-level and most user-visible form of versioning within UE. This part of the Engine's versioning system ensures backward compatibility and protects against data loss by controlling the saving and loading of Assets. The Engine Version appears in the About Unreal Editor section of the Help menu within the Editor.



The Engine Version, as displayed in the Editor.

The actual Engine Version contains five components: major version, minor version, and patch version, followed by the changelist and the name of the branch from which it was built. In code, these five components exist in the FEngineVersion class and its parent class, FEngineVersionBase.

Component

Type

Example Value (see screenshot above)

Major Version

uint16

5

Minor Version

uint16

0

Patch Version

uint16

3

Changelist Number

uint32

20979098

Branch Name

FString

+++UE5+Release-5.0

The individual numerical components do not decrease in value over time, except when a higher-order value increases. This means that any two Engine Versions can be compared, component by component, to determine whether they are identical, or which is newer. In addition, a licensee-created changelist will always be considered newer than an Epic changelist, provided that the major version, minor version, and patch version values all match. The branch name is not used for compatibility checks, and exists primarily for display purposes.

Incompatible Engine Versions will cause the Engine to fail to load Assets. In some cases, this will cause an operation to fail in an obvious way, but note that Assets saved in a newer version of the Engine will simply not show up in the Content Browser, and any references to them will be treated as null. Saving the referencing Asset can be dangerous, as the now-null reference will be saved in the process, effectively losing that information without notifying the user.

Assets and Packages

Assets contain the Engine Version of the Editor used to save them. By checking this value at load time, the Engine gracefully handles properties that have been added to, or removed from, serialized data via code changes. A removed field found during deserialization (such as while loading an Asset) will be unrecognized and ignored, while a newly-added field will be missing from the serialized data, but will hold its default value. Upon serializing the Asset's data to save it to disk, data for removed fields will have already been discarded, and data for newly-added fields will exist and be serialized along with all other properties. The end result of this is that, as data structures are changed over time, the serialized representations of those structures will smoothly discard obsolete fields while adding in new ones. For this reason, serialized data from any given version of the Engine will be legible only to the same or newer versions. This rule prevents data loss errors that would arise from older versions of the Engine discarding newer properties and then serializing data back to an on-disk format.

Engine Versions with Changelist 0 are considered compatible with all other Engine Versions. This facilitates engine development by engineers, but should not be used to save Assets to disk. Instead, content creators should use a distributed, binary build of the Editor, so that they can work with Assets that carry accurate Engine Version data and take advantage of the protections against data loss that it provides.

Coding with Engine Version

The FEngineVersion class provides access to Engine Version information in your projects. It is recommended that these functions be called when you need to display your Engine Version or check for compatibility.

Function Name

Static/Instance

Effect

Current

Static

Gets the build's Engine Version. Typically used for display purposes rather than actual compatibility checks.

CompatibleWith

Static

Gets the earliest (lowest) Engine Version that the current build is compatible with. Intended for compatibility checks, such as those involving Assets, Modules, and network data.

IsCompatibleWith

Instance

Indicates whether or not the current Engine Version is compatible with the FEngineVersionBase input parameter you supply.

Compatibility is possible if the current Engine Version is the same or newer than the Engine Version being checked. For example, any 4.19 Editor build will be compatible with any 4.18 Asset, but a 4.18 Editor build will not be compatible with an Asset saved in a 4.19 build. The exception to this is that two Engine Versions are always considered compatible if either has a Changelist component of 0. This is done to support the live development environment, as code-based builds of the Engine that were not synced via Unreal Game Sync are marked as Changelist 0, creating a more permissive environment with regard to version checks. When cooking a build, however, these Assets will cause warnings, so working with "Changelist 0" Assets is not recommended.

To disable warnings that appear during cooking a build with "Changelist 0" Assets, add ZeroEngineVersionWarning=0 in the [Core.System] section of your project's DefaultEngine.ini file.

Updating the Engine Version

The Engine Version of a build is controlled by the values defined within the /Build/Build.version file in the Engine. This file can be updated by editing it manually, by running the UpdateLocalVersion commandlet, or by syncing with Unreal Game Sync. The following fields are read from the /Build/Build.version file:

Field Name

Notes

MajorVersion

Controls the major version of the Engine.

MinorVersion

Controls the minor version of the Engine.

PatchVersion

Controls the patch version of the Engine.

Changelist

Defined manually. Can be updated manually, or by build systems using the UpdateLocalVersion AutomationTool command. This will use the depot path name of the build, replacing slashes with pluses.

CompatibleChangelist

This is the lowest (or earliest) value of Changelist that will be considered compatible with this Engine Version. It is often zero, such as for local builds of the Engine, but Epic's publicly-released binary builds, or binary builds distributed internally, will have nonzero values and will therefore be incompatible with locally-compiled versions.

IsLicenseeVersion

Should be 0 for locally-compiled builds synced from source control, but will be set to 1 by build systems through the UpdateLocalVersion AutomationTool command. Setting this to 1 is appropriate for promoted builds and will enable tighter version checking, although Hot Reload will be disabled.

IsPromotedBuild

Indicates that this is a promoted build. Default value is "1".

BranchName

A string used to describe the branch from which the build was compiled. Used for display purposes, or to uniquely identify a build. Does not affect compatibility checks.

BuildId

When compiling, the Engine and Modules are all tagged with this value. The Engine will consider any Module without this value to be incompatible. It is recommended that this be left blank, which will cause a new, unique value to be generated on each compile. See the Build ID section below for more information.

UpdateLocalVersion Commandlet

The UpdateLocalVersion commandlet is useful for cases where manually editing the Build/Build.version file is not desired, such as when compiling on a dedicated build machine. The /Build/BatchFiles/RunUAT.bat file can be used to launch the UpdateLocalVersion commandlet as follows:

These parameters are interpreted as follows:

Parameter

Type (Default Value)

Interpretation

CL

Integer (0)

Controls the Changelist field in Build.version.

CompatibleCL

Integer (0)

Controls the CompatibleChangelist field in Build.version.

Build

String (empty)

Replaces the build version string in the engine by updating the BUILD_VERSION macro in source code.

SkipHeader

Bool (false)

If present, the Engine's header files will not be updated.

Licensee

Bool (false)

Controls the IsLicensee field in Build.version. If this parameter is present, will be treated as true.

Promoted

Bool (false)

Controls the IsPromotedBuild field in Build.version. Any non-zero integer value for this parameter will be considered true and will write 1 to the field.

Branch

String (empty)

Controls the BranchName field in Build.version.

Object Version

UObject-derived classes are subject to compatibility checks based on Engine Version, but they also have a separate, two-part versioning system, Object Version, which features both an Engine-level version and any number of custom, Object-level versions. Object serialization is often customized to improve performance (such as Assets containing a lot of bulk data), implement data format changes (such as performing unit conversions), or to save space (such as by writing Object data to disk in a compressed format). Implementing custom serialization requires overriding the UObject function, Serialize, changing the data format depending on your project's needs, and including checks based on the Object Version in the new code. Doing this will enable you to maintain backward compatibility across serialization changes, while preventing data loss, in the same way that Engine Version does.

Engine-Level Serialization and Versioning

At the Engine level, a global enumerated type, EUnrealEngineObjectUE5Version, is used to version custom serializer functions. Whenever a custom serializer is changed, a new entry should be added into EUnrealEngineObjectUE5Version. Since this enumerated type is modified by Epic in official Unreal Engine releases, a parallel global enumerated type, EUnrealEngineObjectLicenseeUEVersion, exists for licensees to add their own Engine-level versioning. All future packages saved will have the incremented values of both enumerated types saved into the package, and serializing (and deserializing) code can perform logic with these values to determine how to read or write data.

The Engine will automatically check these version values against itself, and will fail to load any package with a version number higher than that of the Engine.

This method is not ideal for developers who have multiple teams working on different areas of the Engine. It is impossible to update the version enumeration in multiple places, and reordering the constants when merging will corrupt or invalidate Assets saved with those version numbers. Object-level serialization is recommended for developers with multiple teams writing custom serialization code.

Object-Level Serialization and Versioning

To support parallel development (especially when using different branches), the Engine provides Object-level versioning via FGuid-based custom versions. The FGuid structure contains an integer version number, which can be increased over time like any other version number would (generally implemented as a custom enumerated type), but also contains a global unique identifier (GUID) which makes it possible to have as many different, parallel custom versions as your team needs. Keeping a separate custom version for each system or branch makes it easy to update the custom version in one branch without causing conflicts when merging code from other branches.

To register a new FGuid, create a global object of type FCustomVersionRegistration with your GUID and current version number. For example, the following line of code creates the AnimGraphVer FGuid in Engine/Source/Runtime/AnimGraphRuntime/Private/AnimationCustomVersion.cpp:

At the Object level, each UObject-derived class can choose to serialize one or more FGuid structures in its Serialize by calling the FArchive function, UsingCustomVersion. Custom code can then perform logic based on the version number from any registered FGuid to determine what data to read or write. Because the version number associated with any FGuid registered this way is assumed never to decrease, this also enables the Engine to ensure that Assets from a new version are not loaded, protecting against data loss while preserving backward compatibility in the same manner as Engine Version.

Custom Serialization Function

Objects can override the UObject function called Serialize to control the exact data representation they have on disk. This function both reads and writes data, using the FArchive class, meaning you only have to lay out your data format once. The following FArchive functions are useful when writing version-based logic in serialization code:

Function Name

Usage

UEVer

Returns the (Epic) Engine-level version number. This value will match up to an entry in EUnrealEngineObjectUE5Version.

LicenseeUEVer

Returns the (licensee) Engine-level version number. This value will match up to an entry in EUnrealEngineObjectLicenseeUEVersion.

CustomVer

Returns the Object-level custom version number for the current Object, based on the FGuid provided. This function will return -1 if UsingCustomVersion (see below) was not called with this FGuid when the Object was saved.

UsingCustomVersion

Registers an FGuid with the Object to track its custom version number.

Object Version Code Examples

Wheeled vehicles in the PhysXVehicles Plugin (included with the Engine) use both Engine Object Version and Custom Version to maintain backward compatibility with Assets built prior to certain changes to physics code.

Here, a Custom Version is used to set a variable that will change how the offset to the physics spring object representing the wheel's suspension will be calculated later. The specific Custom Version value used is taken from an enumerated type that was created by the team that maintains physics code.

In the following example, unit conversion is performed in response to a physics change that caused angular velocity to be measured in revolutions per second rather than radians per second. Since these angular velocities were stored as floating-point values (without units), old Assets now require load-time conversion. In this case, we will only modify the angular velocity variable when loading the Asset. Any Asset of this type that we save will already have its angular velocity in revolutions per second, and will be saved with the current Engine version number, avoiding the need to run conversion code the next time that Asset is loaded.

Changing the UEVer function call to LicenseeUEVer will change the code to use the licensee's version number, rather than the official Epic version number. This is recommended for non-Epic users who maintain their own version of Unreal Engine.

Versioning of Binaries

Read the Versioning of Binaries reference page to learn more.

Version Compatibility

New Visual Studio Installation

Recommended Settings

Unreal Engine (UE) is designed to integrate smoothly with Visual Studio (VS), allowing you to make code changes in your projects quickly and easily, and immediately see results upon compilation. Setting up VS to work with UE can help improve efficiency and the overall user experience for developers using UE.

This document covers the basics for setting up your Unreal Engine-to-Visual Studio workflow.

Version Compatibility

The following table lists which versions of VS are integrated with the binary version of UE.

Unreal Engine Version

Visual Studio Version

5.1 or Later

VS 2019 (Default) / VS 2022

4.25 to 5.0

VS 2019 (Default)

As of UE 5.1, Unreal Build Tool (UBT) will now generate the Visual Studio solution file for the latest version of Visual Studio installed, unless you have a Platform SDK installed that does not support the latest version. In this case, UBT will generate the Visual Studio solution file for the latest version of Visual Studio that supports the Platform SDK in question.

Unreal Engine Prerequisite Installer

When installing UE from the Epic Launcher — or if you clone it from GitHub — the UE prerequisite installer runs automatically. However, if you install or sync UE from Perforce, you will need to manually run the prerequisite installer before running any UE tools you have built locally. This installer is located at UNREAL_ENGINE_ROOT\Engine\Extras\Redist\en-us\ in the code base.

New Visual Studio Installation

If you are installing VS for the first time, you will want to make sure that you have the following options enabled.

Visual Studio Workloads

Unreal Engine development with VS requires installing the following optional Workloads:

.NET desktop development

Desktop development with C++

Universal Windows Platform development

Game development with C++

C++ Tools

To add C++ tools to your VS installation, make sure you select Game development with C++ under Workloads, as well as these additional options.

C++ profiling tools

C++ AddressSanitizer

Windows 10 SDK (10.0.18362 or Newer)

Unreal Engine installer



Recommended Settings

The following settings are recommended for developers using VS with UE.

If the version of VS below looks a little different, it is because the theme was changed to Dark. You can do this by going to Tools > Options > Environment > General > Color theme.

Increase the Width of Solution Configurations Dropdown Menu

Launch VS. If you open VS for the first time Get Started window appears. Click Continue without code.



Click to enlarge image.

Right-click the toolbar and select Customize at the bottom of the menu that appears.



Click to enlarge image.

Click the Commands tab and select the Toolbar radio button.

In the dropdown next to the Toolbar, choose Standard.

In the Preview list, select the Solution Configurations control (you may need to scroll down), then click Modify Selection.

Set the Width to 200, then click OK.

Click Close on the Customization . Your toolbar should update immediately.

Add the Solution Platforms Dropdown

Locate the far right button on the Standard toolbar (if you hover the mouse over it, it is labeled Standard Toolbar Options).

Click the dropdown button, choose Add or Remove Buttons, then click on Solution Platforms to add the menu to the toolbar (this may be enabled by default).

Turn Off the Error List Window

Typically, the Error List window pops up automatically when you have an error in your code. However, when working with UE, the Error List window can display false error information. It's best to disable the Error List window and use the Output window to see real code errors when working with UE. The following steps show how to turn off the Error List window.

Close the Error List window if it is open.

From the Tools menu, open the Options dialog.

Select Projects and Solutions and disable Always show Error List if build finishes with error.

Click OK.

Here are some other configuration settings you might find useful:

Turn off Show Inactive Blocks. If you do not, chunks of code may appear grayed out in the text editor. Go to Tools > Options > Text Editor > C/C++ > View to turn off this setting.

Set Disable External Dependencies Folders to True to hide unneeded folders in the Solution Explorer. Find Disable External Dependencies Folder in Tools > Options > Text Editor > C/C++ > Advanced.

Turn off Edit & Continue features; you do not need them. Go to Tools > Options > Debugging > Edit and Continue.

Turn on IntelliSense.

Installation and Setup

Install UnrealVS Visual Studio Extension

Setting the Startup Project

Building the Startup Project

Binding the Command to a Hotkey

Iterating on a Single Source File

Command Line Arguments

Refresh Projects

Batch Builder

Quick Build Menu

The UnrealVS extension for Visual Studio (VS) can be used for easy access to common actions when developing with Unreal Engine (UE). This document will explain how to install the extension and how to use it with your project.

Content Covered:

Extension installation and setup

Setting the Startup Project

Bindable command for building the Startup Project

Setting the command line arguments

Batch building projects

Quick Build project menu

The UnrealVS extension does not work with Visual Studio Express. It is only compatible with Visual Studio Community and Professional editions.

Installation and Setup

The following installation and setup steps were drafted while using VS Community 2022 Version 17.4.1. Depending on which version of VS you are using, these steps might vary.

Install UnrealVS Visual Studio Extension

Find the extension for your version of Visual Studio located at <UNREAL_ENGINE_ROOT>\Engine\Extras\UnrealVS\VS_VERSION\UnrealVS.vsix For example, C:\Program Files\Epic Games\UE5\Engine\Extras\UnrealVS\VS2019\UnrealVS.vsix.

Run the UnrealVS.vsix file by double-clicking it to begin the installation.

The UnrealVS extension should detect and target your version of VS. Check that the installer is targeting the correct version of VS and that the box is ticked. If everything looks good, click Install to proceed.



Click the Close button once the installation is complete.

Run VS and in Extensions > Manage Extensions > Installed you should see the extension.



If Visual Studio is already running, you will need to restart before the extension will be loaded and displayed. The extension is also shown in the Installed Products list in the Help > About Microsoft Visual Studio dialog.

Go to View > Toolbars (or Right-click the Visual Studio toolbar area) and select UnrealVS to display the extension's toolbar.



By default the toolbar appears as above. However, its contents can be customized by going to Tools > Customize... > Commands tab > Toolbar radio button > UnrealVS.



In the Customize box, choose Add Command... and select Extensions from the Categories list to see a list of UnrealVS commands that can be added to the toolbar. When you have finished adding commands, click OK.



Now you can add various commands, such as the Startup Project, various command line arguments, Refresh Projects, Batch Builder, and the Quick Build Menu.

Setting the Startup Project

The Startup Project dropdown is a means of quickly setting or switching between startup projects. It automatically lists all available projects that build executables in the solution. Selecting a project from the list sets that as the current startup project.

You can change which projects are listed in the UnrealVS options. To show only Game projects, go to Tools > Options... and select UnrealVS. Click the dropdown next to Hide Non-Game Startup Projects and select True. Then click OK.



Building the Startup Project

The extension also contains a command for building the current startup project which can be bound to a hotkey or other means of running custom commands.

Binding the Command to a Hotkey

Go to Tools > Options... and select Keyboard under the Environment tree. Under Apply the following additional keyboard mapping scheme click the dropdown and select Visual C++ 6.

Select the UnrealVS.BuildStartupProject command in the commands list.



You can type "Unreal" in the search box to filter the list.

With the command selected, click in the Press Shortcut Keys box and then press the combination of keys you want to use to perform the command (for example, Ctrl + Shift + Alt + B is shown in the example below).



You should choose a combination of keys not already assigned to another command. The Shortcut currently used by box will alert you to the fact that the chosen combination is already in use.

Press the Assign button to bind the keys to the command. The key combination is displayed under Shortcuts for selected command.



Press the OK button to save the changes. Now, when you use the shortcut, the project set as the startup project will automatically build.

Iterating on a Single Source File

If you are used to iterating on updates to a single source (.cpp) file using Ctrl+F7 in Visual Studio, you can bind Ctrl+F7 to the UnrealVS.CompileSingleFile command. This will build your active project with the current solution configuration, platform, and the -singlefile=PATH/TO/OPEN/FILE argument.

Command Line Arguments

The Command-Line control is used to set the Command Arguments for the current project when running a debugging session. You can use this shortcut rather than setting them through the project Properties. In fact, changes made here will be reflected automatically in the Properties.

Enter the arguments in the text box or choose from a list of recent arguments using the dropdown list. These arguments will be passed to the executable when a debugging session is started.



Project configurations for game projects that build Unreal Editor add the project name to the command line automatically, to tell the editor executable which project you are using.

For example, if you build QAGame using the build config 'Debug Editor', the command line will have QAGame.uproject added to the command arguments without the need to type it in the box. To launch the editor for QAGame, you can leave the command-line control empty and the editor will still know which project you are running.

Refresh Projects

Project files can be generated inside of Visual Studio using the Automatic Project File Generation. This makes it much quicker to sync and update all the project files, since you do not have to navigate to the .bat file and run it manually.

To refresh project files:

Press the Refresh Projects button on the UnrealVS toolbar.



The project generation process will be displayed in the Output window as it occurs.

Reload any projects that require it, as you are prompted.

Batch Builder

Create and run custom sets of build jobs with UnrealVS Batch Builder. It is more versatile than the Build > Batch Build... option in Visual Studio.

To open the Batch Builder window:

Press the Batch Builder button on the UnrealVS toolbar or use a keyboard shortcut that you have assigned to the command UnrealVS.BatchBuilder (see Build Startup Project above for instructions on setting up keyboard shortcuts with UnrealVS commands).



The UnrealVS Batch Builder window appears.



Create a Build Job by selecting from the Project, Config, Platform, and then clicking the radio button for the job type.

Add/remove jobs with the > and < buttons.

In the Build Jobs list, move selected jobs up or down the list with the arrow buttons on the right.

Select the Job Set you want to edit in the dropdown under the Build Jobs list.

To create a new Job Set, type a new name into the field.

The Delete button deletes the selected Job Set from the list.

Start or Stop the batch build task on the current Job Set with the Start button.

Job Sets are stored for next time in the .suo file for the loaded solution.

When you click Start, the Output tab displays, showing the progress of the batch build.



The Build Jobs in the running set are shown in the output list. The current executing build job is shown in bold.

= Queued job

= Job complete, succeeded

= Failed job

= Cancelled job

A busy animation, and the Stop button, are shown when a batch build is running.

You can view the output from individual Build Jobs by double-clicking an item in the Output tab, or by right-clicking and selecting Show Output from the context menu.



Batch Builder output for individual items is shown in the Visual Studio Output window, in a pane named UnrealVS - BatchBuild. This is not to be confused with the Build pane that shows the output of the current/last build job.

Quick Build Menu

Use the Quick Build menu to build a project using any config and platform combination, without having to change the main solution build config.

Right-click a Project node in the Solution Explorer.

The UnrealVS Quick Build menu contains sub-menus for the available platforms, and build configs, in the Unreal Engine solution.

Select an item to build the selected project, platform, and config. This method is much quicker than changing the Solution Configuration and Solution Platform in the IDE, starting a build, then switching the config and platform back again.

This method is much quicker than changing the Solution Configuration and Solution Platform in the IDE, starting a build, then switching the config and platform back again.

Immediate Window

Quick Reference

Disabling/Enabling Optimizations

Debug Lines

Debug Text

Enum to String

Fixing the Configuration Combobox Width

Speeding up Visual Studio 2019

Debugging Is Slow

Perforce Visual Studio history Shows Above Every Method

Visual Studio Is Slow when Opening Solutions or Debugging

Immediate Window

Command

Description

**{,,UnrealEditor-Core}::PrintScriptCallstack()**

Blueprint callstack

**{,,UnrealEditor-Core}::GFrameNumber**

Current frame number (also works as breakpoint condition)

**{,,UnrealEditor-Core}::GPlayInEditorID**

PIE ID (useful for multiplayer, also works as breakpoint condition)

**UnrealEditor-Engine!GPlayInEditorContextString**

PIE window name (useful for multiplayer)

Quick Reference

Disabling/Enabling Optimizations

The following macros will disable and enable compiler optimization for the file you add them to:

When optimization is disabled, code will execute exactly as you wrote it without removing temporary or debugging variables you would need during traces or step-by-step debug sessions. This is useful when you want to selectively debug files without using a full Debug build.

Debug Lines

Debug lines refer to lines drawn in the viewport, usually to show the path of line traces or paths. To use them, you need to include DrawDebugHelpers.h. The following code illustrates how to use DrawDebugLine:

DrawDebugHelpers has numerous debug drawers in addition to standard debug lines. These include:

Primitive Shapes

DrawDebugBox

DrawDebugSphere

DrawDebugCapsule

DrawDebugCylinder

DrawDebugPlane

DrawDebugCone

DrawDebugPoint

Solid Shapes

DrawDebugSolidBox

DrawDebugSolid Plane

Other Common Shapes

DrawDebugFrustrum

DrawDebugCamera

DrawDebugCrosshairs

Meshes

DrawDebugMesh

Debug Text

The following code provides an example of how to write debug text to the screen. This mirrors the functionality in the Print String Blueprint node.

The FString::Printf function can take string format parameters, providing a way to quickly compose strings that include variables. You need to include Engine.h to gain access to GEngine so you can call AddOnScreenDebugMessage. For more information on how to use string formatting, refer to String Handling in Unreal Engine.

Enum to String

Enums can be converted to strings by calling GetNameStringByValue from a static UEnum and providing it with the value you want to get the name of. You must initialize the UEnum with a StaticEnum of the same type as the enum whose value you are passing in.

Fixing the Configuration Combobox Width

The default solution configuration combobox is too small to see the full name of the option currently selected. To fix that, right-click on the toolbar, select Customize, select the Commands tab, select the radio Toolbar > Standard, scroll down to the Solution Configurations, click on Modify Selection, and put in the width you would like. A width of 200 is typically useful.



Speeding up Visual Studio 2019

Visual Studio 2019 can be slow when working with Unreal projects. The following are a few strategies that might improve performance for you:

Debugging Is Slow

Try disabling the following settings in Option > Debugging > General:

Uncheck Enable Diagnostic Tools while debugging.

Uncheck Show elapsed time PerfTip while debugging.

Perforce Visual Studio history Shows Above Every Method



To stop the Perforce Visual Studio history from showing above every method, uncheck Tools > Options > Text Editor\All Languages\CodeLens > Enable CodeLens.

Visual Studio Is Slow when Opening Solutions or Debugging

If you are using another plugin for symbol searching, such as Visual Assist, you can disable the Intellisense database to prevent it from parsing the solution. This can be done from: Tools > Options > Text Editor > C/C++ > Advanced > Set Disable Database = true.

Required Setup

Installing VS Code and Required Extensions for Your OS

Installing the Compiler Toolset

Setting Up IntelliSense for VS Code

Building and Launching Projects in VS Code

While Unreal Engine (UE) supports Microsoft Visual Studio as its default IDE for C++ projects in Windows, it also supports Visual Studio Code (VS Code) as a more lightweight, free, open-source alternative. Although VS Code does not have the same capabilities as Visual Studio out of the box, it is highly extensible, and is available for Windows, MacOS, and Linux, providing a common ground for developers working in multiple platforms.

However, VS Code requires extra manual setup to give it equivalent functionality to Visual Studio for Windows. This guide will walk you through these extra steps so that your VS Code environment is fully equipped for UE development.

You do not need a full Visual Studio installation to use VS Code.

Required Setup

This guide assumes that you have installed Unreal Engine and created a C++ project with it.

Installing VS Code and Required Extensions for Your OS

Download and install VS Code as well as the official C/C++ extension pack and C# extension for VS Code. These are required for reading the source code for both Unreal Engine and its Build Tools.

Download and install the compiler toolset for your OS.

Windows: The Microsoft Visual C++ (MSVC) compiler toolset.

Mac: LLVM/Clang.

Linux: LLVM/Clang.

For details about how to set up these components, refer to Installing the Compiler Toolset.

If you are debugging on Mac or Linux, download and install the LLDB extension.

If you need to set VS Code as your default IDE, open Unreal Editor and go to Edit > Editor Preferences > General > Source Code, then set your Source Code Editor to Visual Studio Code. Restart the editor for the change to take effect. This is not necessary to generate a VS Code solution (see step 5c), but it becomes the default instead of Visual Studio.



Click image to enlarge.

Generate your VS Code workspace. There are three ways you can do this:

Open Unreal Editor and click Tools > Refresh Visual Studio Code Project.



On Windows and Mac, right-click your project's .uproject file and click Generate Project Files. When complete, you should see a .code-workspace file in your project's folder.



In a command line, run /GenerateProjectFiles.bat -vscode. Adding the -vscode parameter will make a .vscode workspace instead of a Visual Studio .sln. If you use this method, you do not need to change your default source code editor.

Installing the Compiler Toolset

Each desktop OS uses a different compiler toolset to compile projects in VS Code. The installation process for each one is straightforward, but each requires you to look in a different place to initiate setup.

Compiler Toolset for Windows

VS Code uses the Microsoft Visual C++ compiler (MSVC) toolset on Windows.

Open the Microsoft Visual Studio Downloads page.

Scroll down to the All Downloads section, then expand Tools for Visual Studio.

Click the Download button next to Build Tools for Visual Studio 2022 and install it.



Click image to enlarge.

Compiler Toolset for MacOS

Unreal Engine uses LLVM/Clang as its compiler toolset on MacOS. Refer to Microsoft's documentation on Using Clang for Visual Studio Code for full instructions on how to install and enable it.

Compiler Toolset for Linux

Unreal Engine uses the LLVM/Clang toolset for Linux. To set it up, follow these steps:

Open a Terminal and run the following command:

Run SetupToolchain.sh. This is located in your Engine's install directory under Build/BatchFiles/Linux.

Run GenerateProjectFiles.sh to build your VS Code workspace.

Setting Up IntelliSense for VS Code

VS Code can use IntelliSense for code hinting, but using it for Unreal Engine requires extra setup steps to expose your project's code to it.

In the Explorer, open .vscode/c_cpp_properties.json.



Add the includePath property as follows:

This exposes these paths in your project to IntelliSense so it can discover your project's code.

${workspaceFolder} is not placeholder text. It is a shortcut indicating your workspace's current directory, which removes the need for absolute paths when editing these files.

Open the Extensions panel. Click the gear icon for the C/C++ extension, then click Extension Settings.



Click image to enlarge.

Locate the entry for C_Cpp: IntelliSense Engine Fallback. Click the dropdown and set it to Enabled.



Click image to enlarge.

Set your configuration in the status tray to match the name of your configuration in c_cpp_properties.json.

You now see a small database icon in the VSCode status tray (blue bar) located in the lower-right side of the VS Code window. Mouse over this icon to see IntelliSense's progress parsing your project.



The following is an example of a working c_cpp_properties.json file:

Once you are finished, IntelliSense provides code hinting for your project, including context-sensitive auto-complete functionality.

Building and Launching Projects in VS Code

Before you can build your project, make sure VS Code is set to the correct build configuration, otherwise it will attempt to build and run a standalone or shipping build of your game instead of the editor.

Open the Run and Debug panel by clicking the play button tab on the left side of the window, or by pressing CTRL+SHIFT+D.

Click the dropdown next to RUN AND DEBUG at the top of the panel. Choose the Development Editor configuration for your project. For example, if your project is named TestGame, you would choose Launch TestGameEditor (Development) (TestGame).



Refer to the Build Configuration Reference page for more information about these options.

Click the Play button or press F5 to start building your project in Editor mode. The project compiles, and when it finishes it opens Unreal Editor. Make sure you do not already have Unreal Editor open.

After you choose your Build Configuration, you can press F5 or click Run > Start Debugging in the toolbar to build and debug your project regardless of whether you are using the Run and Debug panel.

Source Code Branches

Release Branch

Main Branch

Downloading the Source Code

Additional target platforms

Licensing and Contribution

Next Steps

Choose your operating system:

Windows

macOS

Linux

This page provides detailed instructions for subscribers to download the source code for Unreal Engine (UE) from the Unreal Engine GitHub repository, and to get started working with the code.

Before you can access the repository at https://github.com/EpicGames/UnrealEngine, you must:

be an Unreal Engine subscriber,

have a GitHub account, and

have associated your GitHub account with your Unreal Engine account as described on the UE on GitHub page.

You are not required to download the source code to work with Unreal Engine. If you'd rather simply download and install the binary version of Unreal, read our Installing Unreal Engine documentation to learn how to Get Unreal. However, you may find that having access to the source code can be extremely valuable for you and your project. For example:

You will get access to all the latest features and bug fixes that Epic engineers make every day, practically up to the minute.

If you find a bug that we haven't fixed yet, but that is crucial to your project, you can unblock your project by making the fix in your own version of the source code and rebuilding your own binaries.

You can improve the engine and help the whole Unreal community by submitting your fixes and features back to Epic.

If you are an Unreal Engine licensee, you can access the source code through our Perforce server instead of the public GitHub repository.

Source Code Branches

You'll notice that we've published UE's source code in several branches.



Branches whose names contain dev, staging, and test are typically for internal Epic processes, and are rarely useful for end-users Other short-lived branches may appear from time to time as we stabilize new releases or hotfixes.

Release Branch

The Release branch always reflects the current official release. These are extensively tested by our QA team, so they make a great starting point for learning Unreal Engine and for making your own projects. We work hard to make releases stable and reliable, and aim to publish a new release every few months.

Main Branch

Most active development on UE happens in the ue5-main branch. This branch reflects the latest release of the engine and may be buggy or it may not compile. We make it available for developers who are eager to test new features or work in lock-step development with us.

If you choose to work in this branch, be aware that it is likely to be ahead of the branches for the current official release and the next upcoming release. Therefore, content and code that you create to work with the ue5-main branch may not be compatible with public releases until we create a new branch directly from ue5-main for a future official release.

Downloading the Source Code

Please follow these instructions to download the Unreal Engine source code.

Refer to our Setting Up Visual Studio to ensure that you have a version of Visual Studio that is compatible with your desired version of Unreal Engine.

Install GitHub for Windows then fork and clone our repository.

To use Git from the command line, see the Setting up Git and Fork a Repo articles.

If you'd prefer not to use Git, you can get the source with the 'Download ZIP' button on the right. The built-in Windows zip utility will mark the contents of zip files downloaded from the Internet as unsafe to execute, so right-click the zip file and select 'Properties...' and 'Unblock' before decompressing it. Third-party zip utilities don't normally do this.

Install Visual Studio.

All desktop editions of Visual Studio can build UE, including Visual Studio Community, which is free for small teams and individual developers. Refer to the Setting Up Visual Studio page to ensure that you have downloaded all of the necessary VS components for working with UE.

Open your source folder in Explorer and run Setup.bat.

This will download binary content for the engine, as well as installing prerequisites and setting up Unreal file associations. On Windows, a warning from SmartScreen may appear. Click More info, then Run anyway to continue.

A clean download of the engine binaries may take some time to complete. Subsequent checkouts only require incremental downloads and will be much quicker.

Run GenerateProjectFiles.bat to create project files for the engine. It should take less than a minute to complete.

Load the project into Visual Studio by double-clicking on the UE5.sln file. Set your solution configuration to Development Editor and your solution platform to Win64, then right click on the UE target and select Build. It may take anywhere between 10 and 40 minutes to finish compiling, depending on your system specs.

After compiling finishes, you can load the editor from Visual Studio by setting your startup project to UE5 and pressing F5 to debug.

Install a Git client like GitHub for Mac, then fork and clone our repository.

To use Git from the Terminal, see the Setting up Git and Fork a Repo articles. If you'd rather not use Git, use the 'Download ZIP' button on the right to get the source directly.

Install the latest version of Xcode.

Open your source folder in Finder and double-click on Setup.command to download binary content for the engine. You can close the Terminal window afterwards.

If you downloaded the source as a .zip file, you may see a warning about it being from an unidentified developer (because .zip files on GitHub aren't digitally signed). To work around it, right-click on Setup.command, select Open, then click the Open button.

In the same folder, double-click GenerateProjectFiles.command. It should take less than a minute to complete.

Load the project into Xcode by double-clicking on the UE5.xcworkspace file. Select the ShaderCompileWorker for My Mac target in the title bar, then select the 'Product > Build' menu item. When Xcode finishes building, do the same for the UE5 for My Mac target. Compiling may take anywhere between 15 and 40 minutes, depending on your system specs.

After compiling finishes, select the 'Product > Run' menu item to load the editor.

Our developers and support teams currently use the latest version of Ubuntu; as a result, we may not be able to provide support for other Linux distributions (including other versions of Ubuntu).

Install a visual Git client and fork our repository. If you'd prefer not to use Git, use the Download ZIP button on the right to get the source as a zip file.

Open your source folder and run Setup.sh to download binary content for the engine.

Both cross-compiling and native builds are supported.

Cross-compiling is handy when you are a Windows (Mac support planned too) developer who wants to package your game for Linux with minimal hassle, and it requires a cross-compiler toolchain to be installed (refer to the Linux cross-compiling page).

Native compilation is discussed in a separate README.

This page shows Licensees how to download and build Unreal Engine from our source code repository on GitHub. If you'd like to download the binary version of Unreal Engine, read our Installing Unreal Engine documentation to learn how to Get Unreal.

Additional target platforms

Android support will be downloaded by the setup script if you have the Android NDK installed. See the Android Quick Start guide.

iOS development requires a Mac. Instructions are in the iOS Quick Start guide.

Development for consoles and other platforms with restricted access, like Sony PlayStation, Microsoft Xbox, and Nintendo Switch, is only possible if you have a registered developer account with those third-party vendors.

Depending on the platform, additional documentation or guidance may be available in the Unreal Developer Network support site, or as a downloadable archive in the section of the Unreal Engine Forums that is dedicated to your platform.

If you don't have access to these resources, first register a developer account with the third party vendor. Then contact your Epic Games account manager if you have one, or fill out and submit the Console Development Request form for Unreal Engine if you don't. Epic will contact you with a formal agreement to digitally sign. Once this is approved, you will receive instructions on how to access source code, binaries, and additional instructions for your platform.

Licensing and Contribution

Your access to and use of Unreal Engine on GitHub is governed by the Unreal Engine End User License Agreement. If you don't agree to those terms, as amended from time to time, you are not permitted to access or use Unreal Engine.

We welcome any contributions to Unreal Engine development through pull requests on GitHub. Most of our active development is in the master branch, so we prefer to take pull requests there (particularly for new features). We try to make sure that all new code adheres to the Epic coding standards. All contributions are governed by the terms of the EULA.

Next Steps

Now that you've downloaded and set-up Unreal Engine, you're ready to build the engine from source.

The first time you start the editor from a fresh source build, you may experience long load times. The engine is optimizing content for your platform to the derived data cache, and it should only happen once.

Your private forks of the Unreal Engine code are associated with your GitHub account permissions. If you unsubscribe or switch GitHub user names, you'll need to re-fork and upload your changes from a local copy.

Contributing to Unreal Engine

Use an Upstream Remote

Set up an Upstream Remote

Bring Changes Into Fork

Use a GitHub Pull Request

One of the biggest benefits of working from source is that you always have access to the very latest improvements and new features that our team adds to Unreal Engine (UE). As we make changes in the source code and issue new official releases, we continuously update the various branches of the Unreal Engine GitHub repository. You will probably want to pick up these changes periodically: perhaps every time we publish a new official release, or any time there is an update relevant to your needs.

This page describes two different approaches you can use to update a branch of your fork so that it matches the latest changes in the main Unreal Engine repository.

Use an Upstream Remote

In this approach, you add the original Epic Games Unreal Engine repository to your local copy of your fork as a new remote repository. This is usually referred to as the upstream remote. You pull changes from that upstream remote into your local branch. Then you can push those changes back up to your own fork on GitHub, usually referred to as the origin remote.

Although this may at first seem trickier than using a GitHub pull request as described below, we recommend this approach. It has a couple of advantages:

Once you have set up your upstream remote, you never have to set it up again as long as you keep using the same local clone of your fork. This makes it convenient to pick up new changes as frequently as you feel is necessary for your project.

Each time you use a GitHub pull request to update your fork, you create a new commit in your branch and a new pull request in your project's history. This is usually harmless, but it is better to avoid these unnecessary entries.

The instructions below show you how to use the Git command-line tools to add the new remote and pick up changes. If you use a Graphical User Interface (GUI) Git client, the steps should be roughly the same. Refer to your tool's documentation for details.

If you use GitHub Desktop, the upstream remote is automatically created for you when you clone your fork. You only need to merge the changes from the upstream branch into your local branch, then push those changes up to your origin repository.

Set up an Upstream Remote

If you have not already done so, clone your fork to your computer.

Open a command prompt, and navigate to the folder that contains your repository.

Add the base Epic Games repository as a new remote, named upstream.

Bring Changes Into Fork

Checkout the branch you want to update. For example:

Pull the changes from the upstream remote into your local branch.

Push the changes up to your origin remote.

Use a GitHub Pull Request

In a web browser, go to your repository's home page on GitHub. This typically follows the format https://github.com/<USERNAME>/UnrealEngine, where <USERNAME> is your GitHub user name.

Choose the branch you want to update from the Branch menu. The Epic Games Unreal Engine GitHub page README.md contains information about the available branches.



Typically, as long as you have not made changes to this branch in your fork, GitHub informs you that the Epic Games repository already has all the commits from your repository.



Selecting Sync Fork informs you of any changes that exist in the Epic Games repository that have not been synced to your fork. To inspect the changes, click Compare.



If you know that there are no changes in your fork and you do not wish to review the changes that are available for sync from the Epic Games repository, but you simply wish to update to all of the latest changes, click Update Branch.

After you have selected Compare, GitHub displays the commits that are present in the Epic Games repository, but are missing from your fork. If there are no changes that have conflicts, the branches are able to be automatically merged. To begin the process of merging changes, click Create Pull Request.



Enter a brief description to indicate what branch your pull request is updating. When you are done, click Create Pull Request.



GitHub displays the changes contained in this pull request. At the bottom of the list of changes, click Merge Pull Request.



Click Confirm Merge.



When the merge is done, your fork's branch will be up-to-date on GitHub. You can now use the Git command line or your choice of visual tools to checkout the branch and pull the latest changes to your local computer.

Updating to the Latest Changes from Epic

Plan Your Submission

Set Up your Branch

Start your Pull Request

Next Steps

If you have made a fix or new feature in the Unreal Engine (UE) source code, you can contribute your changes back to Epic Games and get them published into the next release of Unreal Engine.

Over the years, we've already welcomed thousands of contributions from the community. There are many good reasons to join in, for example:

Merging your fixes and features into the main source code repository can make it easier for you to pick up the latest changes to Unreal Engine. You won't have to keep merging your local changes with newer engine source, or risk that your custom fixes might not compile or work as expected against the latest engine code.

Improving the Unreal Engine and editing tools helps to strengthen the wider Unreal community, which makes your knowledge and expertise even more valuable.

If we accept your changes, we'll also list your name and GitHub handle in our Release Notes as a contributor.

We use the GitHub Pull Request mechanism to manage, track, and evaluate submissions. This page tells you everything you need to know to get started.

Plan Your Submission

It's easy to create a pull request in GitHub, but it takes a little forethought to create a pull request that we can evaluate easily and integrate quickly into our own repository.

Keep the following suggestions in mind if you want to increase the chances of your submission being accepted, and to avoid us asking you to do any extra work or changes.

Keep it focused. Each pull request should ideally fix a single specific bug, or add a single, self-contained feature. Your pull request may involve changes to multiple files, and it may be made up of any number of commits, but all of those changes should be made to achieve a single aim.If you have multiple things you want to contribute at the same time, don't hesitate to create multiple pull requests. It's easier for us to validate and bring in multiple separate requests than to break one large submission down into separate component parts.

Start from master. Although it's possible for us to merge in changes that you make on top of other branches, it's easiest if you make your changes in a clean, new branch that you create in your fork from a master branch that is even with the original Unreal Games repository.

Keep it universal. The Unreal Engine and editing tools are used across a potentially limitless spectrum of real-time content projects in a variety of industries and use cases. When you design a new feature, it's important to give some thought to making it as generic as possible, so that it will be useful to the widest possible audience. Avoid making assumptions about specific types of gameplay or content.

Follow our coding standard. The Unreal Engine Coding Standard describes the conventions that we try to adhere to when writing our own code. Please do your best to follow these conventions in the code you submit. If you don't, it may take us longer to integrate your fixes, or we may ask you to go back and update your pull request to make it conform.

Describe your changes well. Give some thought in advance to the best way to tell us about the intent of your changes. Don't wait until you're filling out the pull request form on the GitHub web page to start getting your thoughts down into words.If your changes fix a bug, how would we reproduce it? How can we tell if your change fixes the problem? Why did you choose this approach over other possible fixes?If you want to add a new feature, who is it for? How is it supposed to work? Is it entirely your own work, or is it derived from another product or the work of another developer?

Keep in mind that we don't guarantee that we'll accept your submission, even if you've done everything right on your side. The Epic engineers who review your submission often have inside knowledge about upcoming development plans, other engine subsystems or plugins that might be affected, third-party considerations, and so on. If they determine that we can't accept your submission for some reason, they'll let you know why in the pull request conversation.

Set Up your Branch

Use the following steps to get your changes applied to a new branch in your fork.

Update the master branch in your fork with the latest changes in the master branch of the original Epic Games Unreal Engine repository.For details, see Updating to the Latest Changes from Epic.

Create a new branch in your fork to hold your changes, based on the master branch. You can do this on the GitHub page for your fork, or you can do it on your local computer using the Git command-line tool or any visual Git tool.

On your local computer, fetch the latest changes from your fork if necessary, and checkout your new branch.

Make your changes in your local copy of the Unreal Engine source code.

Compile the Unreal Engine and test to make sure your fix or feature is working as intended.

Please do not skip this step! It may be tempting, especially if you're making a very small fix. But the master branch receives frequent updates, and any of them could potentially interfere with the changes you want to make.

Commit your changes to your local branch, then push them back up to your GitHub repository.

Start your Pull Request

Once you have your changes in a new branch in your fork, you can create a new pull request on the GitHub web site to ask us to merge those changes back into the original Unreal Engine repository.

In a web browser, go to your repository's home page on github.com.This typically follows the format https://github.com/<username>/UnrealEngine, where <username> is your GitHub user name.

You may see a notification that your new branch was recently modified. If so, you can click the green Compare & pull request button.



If not, select the branch that contains your changes from the Branch drop-down list, and click New Pull Request.



On the Open a Pull Request page, click the base drop-down list and select the master branch. This sets the branch you want to merge your changes into.



With the master branch selected, you should see that your branch is Able to merge (1), and the list of commits at the bottom of the page (2) should contain only the changes that you have made in your branch.



Click for full image.

This is your opportunity to tell us everything we need to know about the intent and scope of your changes. Set a brief description for your pull request, and use the text box to provide more detailed information.

When you're satisfied that you've given us all the information we'll need in order to understand your changes, click Create pull request.

You'll be taken to a page for your new pull request, which is assigned a unique number. You can edit your title or description here, or add new comments in the conversation history. If you make any more commits to your custom branch, your pull request is automatically updated to include those changes too.



Click for full image.

To get back here easily in future, either:

bookmark the URL, or

go to the Pull Requests tab on the Epic Games Unreal Engine repository page. You can use the Filters drop-down list to easily find the pull requests you've created in the list.

Next Steps

The Epic engineering team will look over your new pull request as soon as possible, but your part is not necessarily done yet.

We may need to ask you some follow-up questions, or request that you make some additional changes. If so, we'll use the Conversation tab of your pull request to communicate. Keep an eye on the pull request, or subscribe to e-mail notifications from the GitHub site, so that you don't miss any messages from us.

If we do integrate your fix into our repository, your pull request will be set to Closed rather than Merged. This is normal and to be expected. The commit that integrates your changes will normally tag your pull request, so that there will be a record of your contribution.

Understanding the Basics

Programming Quick Start

Level Designer Quick Start

Unreal Build Pipeline

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Downloading Unreal Engine Source Code

Installing Unreal Engine

Building Unreal Engine from Source

Running the Editor

Getting Started with Unreal Engine

Choose your operating system:

Windows

macOS

Linux

Building Unreal Engine from Source

Read about Hardware and Software Specifications, and make sure that Microsoft Visual Studio is installed prior to building Unreal Engine (UE) from source. Also, depending on your system's specifications, it may take between 10 and 40 minutes to compile the Engine.

Inside the root directory, where you downloaded and adjusted the UE Source Code run GenerateProjectFiles.bat to set-up your project files.



All project files are intermediate ([UERoot]\Engine\Intermediate\ProjectFiles). You must generate project files each time you sync a new build to ensure they are up to date. If you delete your Intermediate folder, you must regenerate project files using the GenerateProjectFiles batch file.

Load the project into Visual Studio by double-clicking UE5.sln.



Set your solution configuration to Development Editor.



Set your solution platform to Win64.



Right-click the UE5 target and select Build.



Read about Hardware and Software Specifications, and make sure that XCode is installed prior to building Unreal Engine (UE) from source. Also, depending on your system's specifications, it may take between 10 and 40 minutes to compile the Engine.

Inside the root directory, run GenerateProjectFiles.command to set up your project files.

Load the project into XCode by double-clicking UE5.xcodeproj.

To set your build target, select UnrealEditor - Mac for My Mac in the title bar.



To build the project, select Product > Build.



Unreal Engine (UE) development and support teams currently use the latest version of Ubuntu; as a result, we may not be able to provide support for other Linux distributions (including other versions of Ubuntu). Additionally, read about Hardware and Software Specifications, and make sure your system has at least one hundred (100) gigabytes of disk space before performing the following steps.

Inside the root directory, run Setup.sh from the terminal to setup the files needed to generate the project files.



Now, run GenerateProjectFiles.sh from the terminal to generate your project files.



To build the project, run make from the terminal.



Depending on your system's specifications, it may take anywhere from ten minutes to over an hour to compile the Engine. If you want to shorten the time it takes to compile the Engine from source, we recommend compiling the source code on a machine that has at least eight (8) gigabytes of RAM, with a multi-core processor having at least eight (8) cores (including hyperthreading).

Running the Editor

Set your startup project by right-clicking the UE5 target and selecting Set as StartUp Project.



Right-click the UE5 project, then select Debug > Start New Instance to launch the Editor.



Alternatively, you can press the F5 key on your keyboard to start a new instance of the Editor.

Congratulations! You've compiled and launched the Engine from source.

Select Product > Run to launch the Editor.



Congratulations! You've compiled and launched the Engine from source.

Navigate to the Editor's binary path by entering cd Engine/Binaries/Linux/ into the terminal.

Run UnrealEditor to launch the editor.



Congratulations! You've compiled and launched the Engine from source.

Getting Started with Unreal Engine

Learn how to use Unreal Engine by referring to the Understanding the Basics documentation!

If you're looking to quickly get started with UE, refer to the following tutorials:

Programming Quick Start

Level Designer Quick Start

UE's in-editor help features are a great way to get your questions answered.

Installing Unreal Engine

Building Unreal Engine from Source

Compiling Game Projects

What's New

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Hardware and Software Specifications

Build Configuration Descriptions

Build Configuration for UE Solution

Build Configuration for UE Project

Choose your operating system:

Windows

macOS

Linux

Build Configuration Descriptions

Unreal Engine (UE) uses a custom building method via the Unreal Build Tool (UBT). This tool processes the information necessary to build the engine's reflection system, integrating your C++ code with Blueprints, replication, serialization, and garbage collection.

Every build configuration contains two keywords, and the first keyword indicates the state of the engine and your game project. For instance, if you compile using a Debug configuration, you will be able to debug your game's code. The second keyword indicates the target you are building for. For example, if you want to open a project in Unreal, you need to build with the Editor target keyword.

Build Configuration - State

Description

Debug

This configuration contains symbols for debugging. This configuration builds both engine and game code in debug configuration. If you compile your project using the Debug configuration and want to open the project with the Unreal Editor, you must use the -debug flag in order to see your code changes reflected in your project.

DebugGame

This configuration builds the engine as optimized, but leaves the game code debuggable. This configuration is ideal for debugging only game modules.

Development

This configuration enables all but the most time-consuming engine and game code optimizations, which makes it ideal for development and performance reasons. Unreal Editor uses the Development configuration by default. Compiling your project using the Development configuration enables you to see code changes made to your project reflected in the editor.

Shipping

This is the configuration for optimal performance and shipping your game. This configuration strips out console commands, stats, and profiling tools.

Test

This configuration is the Shipping configuration, but with some console commands, stats, and profiling tools enabled.

Build Configuration - Target

Description

Game

This configuration builds a stand-alone executable version of your project, but requires cooked content specific to the platform. Please refer to the Packaging Projects Reference page to learn more about cooked content.

Editor

To open a project in Unreal Editor and see all code changes reflected, the project must be built in an Editor configuration.

Client

If you are working on a multiplayer project using UE networking features, this target designates the specified project as being a Client in UE's client-server model for multiplayer games. If there is a <GAME_NAME>Client.Target.cs file, the Client build configurations will be valid.

Server

If you are working on a multiplayer project using UE networking features, this target designates the specified project as being a Server in UE's client-server model for multiplayer games. If there is a <GAME_NAME>Server.Target.cs file, the Server build configurations will be valid.

Build Configuration for UE Solution

When compiling a UE solution, you are compiling our engine's source code together with your project's source code. The following build configurations are available when building your project this way:

Debug

DebugGame

Development

Shipping

Test

Game

✓

✓

✓

✓

✓

Editor

✓

✓

✓

Client

✓

✓

✓

✓

✓

Server

✓

✓

✓

✓

✓

Build Configuration for UE Project

When compiling a UE project, you are only compiling your project's source code. The following build configurations are available when building your project this way:

Debug

DebugGame

Development

Shipping

Test

Game

✓

✓

✓

Editor

✓

✓

Client

Server

Debug

DebugGame

Development

Shipping

Test

Game

✓

✓

✓

Editor

✓

✓

Client

Server

We do not currently provide a binary installer of Unreal Engine for Linux.Linux users should refer to the Build Configuration for UE Solution section.Refer to our Installing Unreal Engine documentation to learn how to build Unreal Engine from source.

User Project Files

Native Projects

Foreign Projects

Change a Project's Unreal Engine Version

Adding Code to Projects

C++ Class Wizard

Development Environment

Opening Projects in the Development Environment

Generating Project Files

.uproject files

Choose your operating system:

Windows

macOS

Linux

User Project Files

Unreal Engine (UE) recognizes two different types of projects: native and foreign.

Native Projects

Native projects are projects that exist within the same root directory as the engine that was used to create them. As a result, they have the following directory structure:

With this structure PROJECT1 and PROJECT2 are both native projects. Projects with this directory structure do not require any extra configuration in order to determine which editor to use, these projects will automatically detect the editor that is built within the root directory. This is true whether you are using a source build or a binary build of UE.

Projects can be put into either the root folder, or any subfolder that has been defined in Default.uprojectdirs (for example, ROOT/Games). The .uprojectdirs file is a helper file that directs the engine to discover projects in subdirectories of ROOT. You can have multiple .uprojectdirs files in the same ROOT directory. These files are not required to be named Default.uprojectdirs, they can have any name you wish as long as the file extension is .uprojectdirs.

Foreign Projects

Foreign projects are those where your project directory is in some location other than under the same root directory as the engine directory. An example of this would be:

When a foreign project is created from a launcher (binary) build, the EngineAssociation field in its .uproject file is set to the version number of the launcher engine that was used to create it. In case you created the project from a source-built version of the Unreal Editor it will put in the Globally Unique Identifier (GUID) of that editor. This GUID is automatically generated and saved on your computer the first time you launch your source-built editor. The locations where these are stored on different operating systems are:

Windows:

Registry: Computer\HKEY_CURRENT_USER\SOFTWARE\Epic Games\Unreal Engine\Builds

Mac:

File: ~Library/Application Support/Epic/UnrealEngine/Install.ini

Linux:

File: ~/.config/Epic/UnrealEngine/Install.ini

For example, say PROJECT1 was created from a source-built version of the Unreal Editor, then the PROJECT1.uproject file contains something of the form:

where 5FFE8984-EA6F-49EC-859E-6CB8C10FE54D is the GUID associated with the source-built version of the Unreal Editor used to create the project. In contrast, suppose PROJECT2 was created from a UE 5.1 launcher version of the Unreal Editor, then the PROJECT2.uproject file contains:

Change a Project's Unreal Engine Version

You can change the Unreal Engine version that is used to open a project by first right clicking on the project's .uproject file and choosing Switch Unreal Engine version... This will bring up a dialogue box with a dropdown menu where you can select the version of UE with which to open this project. When this dialogue box first appears, it will display the current Unreal Engine distribution that is set to open this project. Launcher builds in this dropdown menu are identified by their version number (for example, 4.27 or 5.0) and source builds are identified as Binary build or Source build followed by the build's directory. This directory is the value associated with the GUID key associated with the EngineAssociation field in the .uproject file. To switch the engine version, select your desired Unreal Engine distribution from the dropdown menu. The system will then regenerate project files to implement this change.

Adding Code to Projects

C++ Class Wizard

The C++ Class Wizard provides a fast and easy way to add native C++ code classes into your project for you to extend with your own functionality, if you wish. This converts a content-only project into a code project. You can access the C++ Class Wizard and create a new C++ class by following these steps:

Check Setting Up Visual Studio to ensure that you have a compatible version of Visual Studio installed before proceeding. For information about the correct version of Xcode, refer to the Unreal Engine Release Notes.

In the main editor, select Tools > New C++ Class...



The C++ Class Wizard will appear and show Common Classes by default. If you do not see the class you are looking for, you can view the entire Class hierarchy listing by selecting All Classes.





Common Classes

All Classes

Choose the Class you want to add. For the purposes of this demonstration, we will choose to create a new Actor Class. Select the Actor Class, then click Next >.



You will then be prompted to enter a Name for your new Class. Do so, then click Create Class. This will create the header (.h) and source (.cpp) files.



Class names can only contain alphanumeric characters and cannot contain spaces. The field will notify you if you enter an invalid name.

In Unreal Engine, Live Coding is now enabled by default. A Live Coding window will appear and compile the new class files that were created.



The code will immediately open in Visual Studio, ready for editing.



The code will immediately open in Xcode, ready for editing.



For instructions on compiling your Class when finished editing, please see the Compiling Projects documentation.

Development Environment

Code files can be created through Visual Studio and added to the game project through the Solution Explorer in the usual manner. You can also add code files to the appropriate folders outside of Visual Studio and rebuild the solution and project files automatically. This makes it easy to add lots of files quickly through the operating system UI, and also makes working on teams easier as the solution and project files do not need to be synced between members of the team. Each person can just sync the code files and rebuild the project files locally.

Code files can be created through Xcode and added to the game project through the Project Navigator in the usual manner. You can also add code files to the appropriate folders outside of Xcode and rebuild the project file automatically. This makes it easy to add lots of files quickly through the operating system UI, and also makes working on teams easier as the solution and project files do not need to be synced between members of the team. Each person can just sync the code files and rebuild the project files locally.

Opening Projects in the Development Environment

If your project is already open in the Unreal Editor, you can easily open it in Visual Studio by selecting Open Visual Studio from the Tools menu.



You can also open the project in Visual Studio through Windows Explorer or Visual Studio's File > Open > Project/Solution.

If your project is inside the UE root directory:

Open the UE5.sln Visual Studio solution located in the UE root directory.

If your project is outside of the UE root directory:

Open the PROJECT_NAME.sln Visual Studio solution located in the root of the project's directory.

If your project is already open in the editor, you can easily open it in Xcode by selecting Open in Xcode from the File menu.



You can also open the project in Xcode through Finder or Xcode's File > Open.

Open the PROJECT_NAME.xcodeproj Xcode project located in the root of the project's directory.

Generating Project Files

The project files are considered intermediate files - located in PROJECT_DIRECTORY\Intermediate\ProjectFiles. This means if you delete your Intermediate folder, you must regenerate the project files.

.uproject files

Navigate to the location of PROJECT_NAME.uproject in Windows Explorer.

Ensure that PROJECT_NAME.uproject is highlighted by Left-clicking once. Now, Right-click on the PROJECT_NAME.uproject file and select Generate Visual Studio Files.



UnrealBuildTool updates the project files and the solution, including generating Intellisense data.



Open the PROJECT_NAME.sln Visual Studio solution located in the root of the project's directory to view the game project in Visual Studio.

Navigate to the location of PROJECT_NAME.uproject in Finder.

Right-click on the PROJECT_NAME.uproject file and select Generate Xcode Files.



UnrealBuildTool updates the project



Open the PROJECT_NAME.xcodeproj Xcode project located in the root of the project's directory to view the game project in Xcode.

Setting Up Visual Studio

Coding Standard

Building Unreal Engine from Source

Compiling Game Projects

Choose your operating system:

Windows

macOS

Linux

The C++ Class Wizard provides a fast and easy way to add native C++ code classes into your project for you to extend with your own functionality, if you wish. This converts a content-only project into a code project. You can access the C++ Class Wizard and create a new C++ class by following these steps:

Check Setting Up Visual Studio to ensure that you have a compatible version of Visual Studio installed before proceeding. For information about the correct version of Xcode, refer to the Unreal Engine Release Notes.

In the main editor, select Tools > New C++ Class...



The C++ Class Wizard will appear and show Common Classes by default. If you do not see the class you are looking for, you can view the entire Class hierarchy listing by selecting All Classes.





Common Classes

All Classes

Choose the Class you want to add. For the purposes of this demonstration, we will choose to create a new Actor Class. Select the Actor Class, then click Next >.



You will then be prompted to enter a Name for your new Class. Do so, then click Create Class. This will create the header (.h) and source (.cpp) files.



Class names can only contain alphanumeric characters and cannot contain spaces. The field will notify you if you enter an invalid name.

In Unreal Engine, Live Coding is now enabled by default. A Live Coding window will appear and compile the new class files that were created.



The code will immediately open in Visual Studio, ready for editing.



The code will immediately open in Xcode, ready for editing.



For instructions on compiling your Class when finished editing, please see the Compiling Projects documentation.

Build Configuration

Building with Visual Studio

Setting the Build Configuration

Setting the Solution Platform

Building the Project

Visual Studio Known Issues

Building with Xcode

Building the Project

Xcode Known Issues

Unreal Engine (UE) uses a custom building method using the UnrealBuildTool (UBT) which handles all the complex aspects of compiling the project and linking it with the engine. This process occurs transparently allowing you to simply build the project through the standard Visual Studio build workflow.

UnrealBuildTool uses the *.build.cs and *.target.cs files to build the game project. These are automatically generated when a project is created using a C++ template, or when the CPP Class Wizard is used to add code to a project created from a Blueprints Only template.

Build Configuration

Unreal projects have multiple targets, including Editor, Client, Game, and Server, described by *.target.cs files. Furthermore, each of these can be built to different configurations. In Visual Studio, this manifests as a Visual Studio *.vcxproj file with different configurations for each target. The solution configurations are named as [Configuration][Target Type] (for example, "DevelopmentEditor" for the default editor target, and "Development" for the default standalone game target). The configuration you use will be determined by the purposes of the build you want to create.

Every build configuration contains two keywords, and the first keyword indicates the state of the engine and your game project. For instance, if you compile using a Debug configuration, you will be able to debug your game's code. The second keyword indicates the target you are building for. For example, if you want to open a project in Unreal, you need to build with the Editor target keyword.

Build Configuration - State

Description

Debug

This configuration contains symbols for debugging. This configuration builds both engine and game code in debug configuration. If you compile your project using the Debug configuration and want to open the project with the Unreal Editor, you must use the -debug flag in order to see your code changes reflected in your project.

DebugGame

This configuration builds the engine as optimized, but leaves the game code debuggable. This configuration is ideal for debugging only game modules.

Development

This configuration enables all but the most time-consuming engine and game code optimizations, which makes it ideal for development and performance reasons. Unreal Editor uses the Development configuration by default. Compiling your project using the Development configuration enables you to see code changes made to your project reflected in the editor.

Shipping

This is the configuration for optimal performance and shipping your game. This configuration strips out console commands, stats, and profiling tools.

Test

This configuration is the Shipping configuration, but with some console commands, stats, and profiling tools enabled.

Build Configuration - Target

Description

Game

This configuration builds a stand-alone executable version of your project, but requires cooked content specific to the platform. Please refer to the Packaging Projects Reference page to learn more about cooked content.

Editor

To open a project in Unreal Editor and see all code changes reflected, the project must be built in an Editor configuration.

Client

If you are working on a multiplayer project using UE networking features, this target designates the specified project as being a Client in UE's client-server model for multiplayer games. If there is a <GAME_NAME>Client.Target.cs file, the Client build configurations will be valid.

Server

If you are working on a multiplayer project using UE networking features, this target designates the specified project as being a Server in UE's client-server model for multiplayer games. If there is a <GAME_NAME>Server.Target.cs file, the Server build configurations will be valid.

Building with Visual Studio

Setting the Build Configuration

The build configuration can be set in the Visual Studio toolbar. This settings you can find as following.



Setting the Solution Platform

The solution platform can be set in the Visual Studio toolbar.

When working with Unreal Engine, you will typically use the Win64 platform. This is the only one included by default when generating project files; the Project Files for IDEs page has instructions for generating project files for additional platforms.



Building the Project

Make sure you are running Visual Studio 2019 or higher for Windows Desktop installed before proceeding. If you are using Mac, make sure to have Xcode 9.0 or higher installed.

Set the Solution Configuration to the configuration you want to build. In this example, it is set to Development Editor. Refer to the Build Configuration section for descriptions of each available configuration.



Right-click your game project and choose Rebuild to recompile.



You can now run Unreal Engine with your compiled project.

When running UE, it is important to use the Unreal Engine executable that matches the build configuration you rebuilt your project in. For example, if you compiled your project in the DebugGame Uncooked build configuration, you would run the UnrealEditor-Win64-DebugGame.exe executable with your game information as an argument. More information on the binary naming convention can be found on the Building Unreal Engine page.

When running Unreal Engine, it is important to add the -game flag if you rebuilt your project in any Uncooked configuration, and the -debug flag if you rebuilt your project in any Debug configuration.

Visual Studio Known Issues

Issue

Solution

"Project is out of date" message always appears

Visual Studio thinks the project is out of date when it really is up to date. You can safely suppress this message by checking the Do not show this dialog again box and pressing No.

No Debugging Information window appears when using the Debug configuration

The reason for this is that the UnrealEditor.exe was compiled using the Development configuration. Your game project will still be debuggable when compiled using the Debug configuration despite this warning. You can safely suppress this message by checking the Do not show this dialog again box and pressing Yes.

Building with Xcode

When building in Xcode, you are only compiling the game project, not the Editor.

Building the Project

The Unreal Engine Xcode project is configured to build Debug configuration when you use Xcode's Product > Build option and Development configuration when you use Product > Build For > Profiling. You can edit this behavior by editing the target schemes.

You can now run Unreal Engine with your compiled project.

When running the binary Editor, it is important to add the -game flag if you rebuilt your project in any Uncooked configuration, and the -debug flag if you rebuilt your project in any Debug configuration.

Xcode Known Issues

Issue

Solution

Xcode does not stop at breakpoints

Xcode's LLDB debugger needs to be configured to correctly handle breakpoints in Unreal Engine projects. You need to create (or edit, if you already have it) a .lldbinit file in your home folder and add the following line to it:

How to Use Live Coding

Changing Default Values for Variables With Live Coding

Configuration

General Live Coding Settings

Modules

Object Reinstancing With Live Coding

Unreal Engine (UE) supports Live Coding using an integration of Live++. Live Coding is a system that can rebuild your application's C++ code and patch its binaries while the engine is running. This functionality is available during the following scenarios:

Editing your application in Unreal Editor.

Running your application with Play In Editor (PIE).

Running a packaged Desktop build of your application attached to the editor for debugging.

This means that without interrupting playtesting sessions or work in the editor itself, you can make changes to C++ classes, compile, and immediately see those changes take effect. This provides significant benefits for iterative development when using C++ runtime logic, such as gameplay code or frontend user interactions. Although the Hot Reload system is still available as an alternative, Live Coding is significantly faster and more flexible.

How to Use Live Coding

Live Coding is enabled by default for all new Unreal Engine installations. When you open your IDE the Live Coding Console will start automatically but remain hidden. If the console is hidden, it will open when you initiate a Live Coding build.



The Live Coding console provides an output log for compilation status. This is separate from the standard Output Log, and only shows Live Coding build information.

To start a build, press CTRL+ALT+F11 on your keyboard while using either your IDE or Unreal Engine. A notification will appear in the lower-right corner of the screen to show the status of your build. You can continue working in the editor or testing your project uninterrupted while the build runs.



If your build succeeds, you will immediately see changes according to your code.

Live Coding is available when Unreal Editor is open, when using PIE, and when attached to a packaged build in your native desktop environment. It is not available when launching on consoles and mobile devices.

Changing Default Values for Variables With Live Coding

When changing default values for variables, values set in the constructor implemented in the .cpp file will not update in existing instances of objects. However, if you change them in your .h file, you will see the change take place.

Configuration

You can find the settings for Live Coding in Editor Preferences > General > Live Coding.



General Live Coding Settings



The General settings control how Live Coding will behave in your development environment.

Setting

Description

Enable Live Coding

When enabled, Live Coding is Unreal Editor's compilation method. If disabled, Unreal Editor falls back to using Hot Reload instead.

Startup

Controls how Live Coding behaves when Unreal Editor starts, including whether the console is active or visible.

Enable Reinstancing

Controls whether or not Live Coding uses Object Reinstancing. When enabled, instances of objects are replaced so that large-scale changes in their code can take effect. Disabling this setting is not recommended, as these kinds of changes can be unstable without it. See Object Reinstancing With Live Coding for more details.

Automatically Compile Newly Added C++ Classes

When enabled, adding C++ classes will automatically prompt Live Coding to compile them and add them to your application.

Modules



The Modules section designates which modules should be pre-loaded for Live Coding when you run the editor or your application. This makes Live Coding's performance when iterating on these modules faster, but the more modules that you set to pre-load, the longer it will take for the editor or your game to start.

Option

Description

Engine Modules

Modules that are part of Unreal Engine's source code.

Engine Plugin Modules

Modules associated with plugins in your Engine's install directory, under Engine/Plugins.

Project Modules

Modules that are part of the current project's source code. This includes your primary module as well as any additional modules you create in your Source directory.

Project Plugin Modules

Modules associated with plugins located in your project's directory, under (Project Name)/Plugins.

You should avoid preloading Engine modules unless you are actively iterating on the engine's source code.

In addition to these sets of modules, you can use the Preload Named Modules array to choose specific modules that you want to load. This is useful if you are working only in a few specific modules within a large project, or if you want to load specific engine modules without loading the entire engine.

For more information about using Modules, refer to the Unreal Engine Modules guide.

Object Reinstancing With Live Coding

Object Reinstancing is an additional system that replaces existing instances of objects throughout the application and the editor. This means those objects can immediately take on any large, structural changes from code compiled through Live Coding. Reinstanced objects will include anything that uses the UCLASS, UFUNCTION, USTRUCT, UENUM, and UDELEGATE macros, as well as objects that Unreal Header Tool generates using those macros, such as Blueprint nodes.

Object Reinstancing is enabled by default. If you disable Object Reinstancing, Live Coding can still easily handle small changes to code such as changes in variable values or minor changes to existing functions. However, large-scale changes to code, such as new functions, new sets of variables, or dramatic re-factors, will behave unpredictably when you attempt to compile them without Object Reinstancing. This will usually result in crashes.

However, when Object Reinstancing is enabled, you need to follow additional steps to clean up pointers. If your code maintains pointers to objects that can be reinstanced, you need to use ReloadReinstancingCompleteDelegate and ReloadCompleteDelegate to update these pointers or invalidate caches so they can be repopulated later.

Hot Reload is more likely to tolerate reinstanced objects being improperly dereferenced, but Live Coding will cause crashes when the editor is being shut down. This is due to the fact that there can only be one version of any given class's destructor, and lingering instances of objects that haven't been cleaned up will cause conflicts between the old and new versions of reinstanced objects' destructors.

Implementation Example

The Sparse Class Data system saves memory by eliminating redundant data on commonly-used Actor types. While developing a game, Blueprint-exposed properties provide a great way for designers to iterate on Actor behavior. However, by the time the game ships, many of these properties may effectively be constants if their values do not vary across Actor instances or change during gameplay. With Sparse Class Data, you can transfer those properties into a single shared struct instance, keeping only one copy of the property in memory, while retaining the ability for designers to access its value in Blueprint graphs and edit it in the class defaults. To determine if a property is a good candidate for Sparse Class Data, use the following three-prong test. The property is a good candidate if:

It is a member of an Actor class that has many instances in-game at the same time, meaning that a significant amount of memory is tied up in redundant copies.

It does not change on placed Actor instances. In other words, the property does not need the EditInstanceOnly or EditAnywhere UProperty Specifiers, because no instance of the Actor overrides or changes its base value.

C++ code does not modify it. Any C++ code that directly accesses the variable must be replaced with calls to an accessor function.

Implementing the Sparse Class Data feature requires native (C++) code. Any Blueprint-declared variables must move to C++ code to become eligible for this process.

Implementation Example

Once you have decided to use Sparse Class Data for one of your classes, you must identify the candidate properties. Any property tagged with EditAnywhere, EditInstanceOnly, or BlueprintReadWrite is not a candidate for Sparse Class Data. Similarly, any property that changes in native C++ code is ineligible to participate in the Sparse Class Data system. This is because the property could have a different value on one Actor instance from another, either through per-instance editing in the Level Editor, or by Blueprint Scripting or native code altering its value on a single Actor instance during a game session. The following example class contains several properties, some of which are candidates for Sparse Class Data:

After identifying candidate variables, create a struct to contain them, and mark the struct with the BlueprintType UStruct Specifier. Each property in the struct must include the EditDefaultsOnly Specifier.

FMySparseClassData

The original class needs some modification to use this struct. There are three specific changes that the process requires:

Tell the class to use this struct as its Sparse Class Data type.

Add #if WITH_EDITORONLY_DATA precompiler directive blocks around the properties that are moving to the new struct, and mark them with _DEPRECATED suffixes in the original class. Additionally, remove all UProperty Specifiers and set the properties to private access. Do not change other portions of your code to use the _DEPRECATED names; those lines will be replaced with accessor calls into the Sparse Class Data struct.

In editor builds (#if WITH_EDITOR), override the MoveDataToSparseClassDataStruct function. This function will preserve the existing data values by performing a one-time copy from the original class to the Sparse Class Data struct.

After making these changes, your class should look like this:

The following function copies the existing values of all shared properties:

Engine/BlueprintGeneratedClass.h

At this point, Sparse Class Data is in place. Users editing or accessing the affected properties in the editor will not notice any difference in behavior, and memory usage in shipping builds will be reduced. If the properties are referenced in C++ code, replace any attempts to access the variable with a call to a getter function. For example, anywhere that the code used to access the MyFloatProperty variable should now call GetMyFloatProperty instead. UHT will automatically generate this function for you. If you have a non-trivial getter function and need to keep its behaviors, the NoGetter UProperty Metadata Specifier will instruct UHT not to generate its own getter functions. For variables that you want to access by const reference instead of by value, use the GetByRef UProperty Metadata Specifier.

LLM Trackers

LLM Setup

LLM Tags

Custom Tags

Tag Sets (Experimental)

Technical Implementation Details

Additional Technical Details

The Low-Level Memory Tracker (LLM) is a tool that tracks memory usage in Unreal Engine (UE) projects. LLM uses a scoped-tag system to keep an account of all memory allocated by the Unreal Engine and the OS. LLM supports all platforms used by Unreal Engine.

LLM Trackers

There are currently two trackers in LLM. Each tracker has its own allocation map and tag stack. The Default Tracker is for all allocations from the Engine. It is the higher-level of the two, and records allocations made through the FMemory class function, Malloc. This is the tracker that supplies the stats for the stat LLM and stat LLMFULL Console Commands. The Platform Tracker is the lower-level version, and it records all allocations made from the OS. For example, it will track the internal allocations made by functions like Binned2. The Default Tracker stats are therefore a subset of the platform tracker stats.

LLM Setup

To enable LLM in your project, use the following command-line arguments and Console Commands.

Command Line Argument

Description

-LLM

Enables LLM

-LLMCSV

Continuously writes out all values to a CSV file. Automatically enables -LLM.

-llmtagsets=Assets

Experimental Feature. Shows the total allocated by each asset.

-llmtagsets=AssetClasses

Experimental Feature. Shows the totals for each UObject class type.

Console Commands

Description

stat LLM

Shows the LLM summary. All lower level engine stats are grouped under a single Engine stat.

stat LLMFULL

Shows all LLM stats.

stat LLMPlatform

Shows stats for all memory allocated from the OS.

stat LLMOverhead

Shows the memory used internally by LLM.

When using the -LLMCSV command-line argument, the .CSV file will be written out to saved/profiling/llm/. The file will contain a column for each tag showing the current value in MB. A new line is written every 5 seconds (by default). The frequency can be changed using the LLM.LLMWriteInterval Console Variable.

LLM Tags

Every memory allocation made by the Engine (including game code) is assigned a tag value identifying the category to which it belongs. This means that all memory is tracked once and only once, nothing is missed, and nothing is counted twice. The total of all of the categories will add up to the total amount of memory used for the game.

The tags are applied using tag-scope macros. Any allocation made within that scope will be given the specified tag. LLM maintains a stack of tag scopes and applies the top tag to the allocation. LLM stats can be viewed in-game using the stat LLM or stat LLMFULL Console Commands. The current total for each tag will be shown in MB. LLM also writes out the stat values to a .CSV file, so that the values can be analyzed. The following Tag Categories currently exist within the Engine:

Tag Name

Description

UObject

This includes any class that inherits from UObject and anything that is serialized by that class including properties. UObject is a catch-all for all Engine and game memory that is not tracked in any other category. Note that this stat doesn't include Mesh or Animation data which are tracked separately. It corresponds to the number of Objects placed in the Level.

EngineMisc

Any low-level memory that is not tracked in any other category.

TaskGraphTasksMisc

Any task that is kicked off from the task graph that doesn't have its own category. This should generally be fairly low.

StaticMesh

This is the UStaticMesh class and related properties, and does not include the actual mesh data.

Custom Tags

When profiling memory usage for your project with Unreal Insights, you may discover that there is allocated memory tagged as LLM Untracked in Memory Insights. The LLM_DECLARE_TAG and LLM_DEFINE_TAG macros are used to create custom tags to help you discover untracked memory allocations. These macros do not require modifying the engine files and can be done in game modules or plugins. When you want to use the custom tag you created, use the LLM_SCOPE_BYTAG macro. The steps are summarized as follows:

Declare a custom LLM tag in your header file with LLM_DECLARE_TAG.

Define your custom LLM tag in the associated .cpp file with LLM_DEFINE_TAG.

Use the LLM_SCOPE_BYTAG where you wish to track memory usage in your .cpp file with LLM_SCOPE_BYTAG.

Refer to the Example below for a small example declaring and using a custom tag.

The LLM_DECLARE_TAG macro declares a tag which is defined elsewhere that can be used in LLM_SCOPE_BYTAG or referenced by name in other LLM_SCOPE s.

Parameters

UniqueName: The name of the tag for looking up by name. Must be unique across all tags passed to LLM_DEFINE_TAG, LLM_SCOPE, or ELLMTag.

The LLM_DEFINE_TAG macro defines a tag which can be used in LLM_SCOPE_BYTAG or referenced by name in other LLM_SCOPE s.

Parameters

UniqueNameWithUnderscores: Modified version of the name of the tag. Used for looking up by name. Must be unique across all tags passed to LLM_DEFINE_TAG, LLM_SCOPE, or ELLMTag. The usual separator for parents (/) must be replaced with (_) in `LLM_DEFINE_TAG`s.

DisplayName: (Optional) The name to display when tracing the tag joined with (/) to the name of its parent if it has a parent or NAME_None to use the UniqueName.

ParentTagName: (Optional) The unique name of the parent tag or NAME_None if it has no parent.

StatName: (Optional) The name of the stat to populate with this tag's amount when publishing LLM data each frame or NAME_None if no stat should be populated.

SummaryStatName: (Optional) The name of the stat group to add on this tag's amount when publishing LLM data each frame or NAME_None if no stat group should be added to.

CustomTagExample.h

CustomTagExample.cpp

Tag Sets (Experimental)

To use Tag Sets, define LLM_ALLOW_ASSETS_TAGS in LowLevelMemTracker.h. When using Tag Sets, each allocation will additionally store the Asset name or the Object class name.

Using Tag Sets will add overhead to both memory usage and runtime performance.



Technical Implementation Details

LLM works by maintaining a map of all allocations indexed by a pointer. The map currently contains the size of each allocation and its assigned Tag. Games can have as many as 4 million live allocations at any one time, so it is important to keep the memory overhead as small as possible. The current implementation uses 21 bytes per allocation:

Allocation

Size

Pointer

8 bytes

Pointer Hash Key

4 bytes

Size

4 bytes

Tag

1 byte

Hash Map Index

4 bytes

When an allocation is tracked with the OnLowLevelAlloc function, the tag on the top of the tag stack becomes the current tag and is stored in the allocation map with that pointer as its key. To avoid contention, the frame deltas of each tag are tracked in a separate FLLMThreadState class instance. At the end of a frame, these deltas are summed and published to the stats system and .CSV file.

LLM is initialized very early on, which means that it must be enabled by default. If LLM isn't enabled on the command line, it will shut itself down and clean up all memory, ensuring there is no overhead. LLM is completely compiled out in Test and Shipping builds.

LLM can be run without the stats system (for example in the Test config). It won't be possible to show the stats on screen, but the stats will still be written out to the .CSV file. LLM will need to be enabled by modifying ENABLE_LOW_LEVEL_MEM_TRACKER in LowLevelMemTracker.h.

Tags are applied using the scope macros. The two main macros are:

LLM_SCOPE(Tag)

LLM_PLATFORM_SCOPE(Tag)

These set the current scope of the Default Tracker and Platform Tracker, respectively. There are platform-dependent versions of these scopes, for example, LLM_SCOPE_[Console](Tag), which use the platform-specific tag enumerated types. The scope macros that use stats, such as LLM_SCOPED_TAG_WITH_STAT, are considered deprecated at the moment, and should not be used.

All memory used by LLM internally is managed by the platform-supplied LLMAlloc and LLMFree functions. It is important that LLM doesn't make allocations in any other way, so that it doesn't track its own memory usage (and cause infinite recursion).

Additional Technical Details

The following section contains various notes and additional information you should be aware of when using LLM.

Because the overhead of LLM can be 100MB or more it is strongly advised to run in large memory mode on consoles.

LLM in the Test config won't show the on-screen stats page, but it will write out the .CSV file. LLM is completely disabled in Shipping.

Asset tag tracking is still in an early experimental state.

Class Organization

Copyright Notice

Naming Conventions

Examples

Inclusive Word Choice

Racial, ethnic, and religious inclusiveness

Gender inclusiveness

Slang

Overloaded Words

Word List

Blacklist

Whitelist

Master

Slave

Portable C++ code

Use of standard libraries

Comments

Guidelines

Const Correctness

Example Formatting

Modern C++ Language Syntax

static_assert

override and final

nullptr

The 'auto' Keyword

Range-Based for

Lambdas and Anonymous Functions

Strongly - Typed Enums

Move Semantics

Default Member Initializers

Third Party Code

Code Formatting

Braces

If - Else

Tabs and Indenting

Switch Statements

Namespaces

Physical Dependencies

Encapsulation

General Style Issues

API Design Guidelines

Platform-Specific Code

At Epic, we have a few simple coding standards and conventions. This document is not meant to be a discussion, but rather, reflects the state of Epic's current coding standards. Following the coding standards is mandatory.

Code conventions are important to programmers for a number of reasons:

80% of the lifetime cost of a piece of software goes to maintenance.

Hardly any software is maintained for its whole life by the original author.

Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly.

If we decide to expose source code to mod community developers, we want it to be easily understood.

Many of these conventions are actually required for cross-compiler compatibility.

The coding standards below are C++-centric, but the spirit of the standards are expected to be followed no matter which language is used. A section may provide equivalent rules or exceptions for specific languages where it's applicable.

Class Organization

Classes should be organized with the reader in mind rather than the writer. Since most readers will be using the public interface of the class, that should be declared first, followed by the class's private implementation.

Copyright Notice

Any source file (.h, .cpp, .xaml, etc.) provided by Epic for distribution must contain a copyright notice as the first line in the file. The format of the notice must exactly match that shown below:

If this line is missing or not formatted properly, CIS will generate an error and fail.

Naming Conventions

All code and comments should use U.S. English spelling and grammar.

The first letter of each word in a name (such as type name or variable name) is capitalized, and there is usually no underscore between words. For example, Health and UPrimitiveComponent are correct, but not lastMouseCoordinates or delta_coordinates.

Type names are prefixed with an additional upper-case letter to distinguish them from variable names. For example, FSkin is a type name, and Skin is an instance of a FSkin.

Template classes are prefixed by T.

Classes that inherit from UObject are prefixed by U.

Classes that inherit from AActor are prefixed by A.

Classes that inherit from SWidget are prefixed by S.

Classes that are abstract interfaces are prefixed by I.

Epic's concept-alike class types (used as the first argument to the TModels type trait) are prefixed by C.

Enums are prefixed by E.

Boolean variables must be prefixed by b (for example, bPendingDestruction, or bHasFadedIn).

Most other classes are prefixed by F, though some subsystems use other letters.

Typedefs should be prefixed by whatever is appropriate for that type: F if it's a typedef of a struct, U if it's a typedef of a UObject and so on.

A typedef of a particular template instantiation is no longer a template, and should be prefixed accordingly, for example:

Prefixes are omitted in C#.

UnrealHeaderTool requires the correct prefixes in most cases, so it's important to provide them.

Type template parameters and nested type aliases based on those template parameters are not subject to the above prefix rules, as the category of type is unknown.

Prefer a Type suffix after a descriptive term.

Disambiguate template parameters from aliases by using an In prefix:

Type and variable names are nouns.

Method names are verbs that describe the method's effect, or describe the return value of a method that has no effect.

Macro names should be fully-capitalized with words separated by underscores, and prefixed with UE_ (see Namespaces).

Variable, method, and class names should be clear, unambiguous, and descriptive. The greater the scope of the name, the greater the importance of a good, descriptive name. Avoid over-abbreviation.

All variables should be declared one at a time, so that a comment on the meaning of the variable can be provided. Also, the JavaDocs style requires it. You can use multi-line or single line comments before a variable, and the blank line is optional for grouping variables.

All functions that return a bool should ask a true/false question, such as IsVisible() or ShouldClearBuffer().

A procedure (a function with no return value) should use a strong verb followed by an Object. An exception is, if the Object of the method is the Object it is in. Then the Object is understood from context. Names to avoid include those beginning with "Handle" and "Process" because the verbs are ambiguous.

Though not required, we encourage you to prefix function parameter names with "Out" if they are passed by reference, and the function is expected to write to that value. This makes it obvious that the value passed in this argument will be replaced by the function.

If an In or Out parameter is also a boolean, put the "b" before the In/Out prefix, such as bOutResult.

Functions that return a value should describe the return value. The name should make clear what value the function will return. This is particularly important for boolean functions. Consider the following two example methods:

Examples

Inclusive Word Choice

When you work in the Unreal Engine codebase, strive at all times to be respectful, inclusive, and professional in your use of language.

This applies when you name anything, like classes, functions, data structures, types, variables, files and folders, plugins, and so on. It applies when you write snippets of user-facing text for the UI, error messages, and notifications. It also applies when writing about code, such as in comments and changelist descriptions.

The following sections provide guidance and suggestions that can help you to choose words and names that are more respectful and appropriate for all situations and audiences, and to be a more effective communicator.

Racial, ethnic, and religious inclusiveness

Do not use metaphors or similes that reinforce stereotypes.

This includes those that contrast black and white, such as blacklist / whitelist.

Do not use words that refer to historical trauma or lived experience of discrimination.

This includes slave, master, and nuke.

Gender inclusiveness

Refer to hypothetical people using the pronouns they, them, and their, even in the singular.

When you refer to anything that is not a person, always use it and its. For example: a module, plugin, function, client, server, or any other software or hardware component.

Do not assign a gender to anything that doesn't have one.

Do not use collective nouns like guys that assume gender.

Avoid colloquial phrases that contain arbitrary genders, like "a poor man's X".

Slang

Remember that your words will be read by a global audience that may not share the same idioms and attitudes, and who may not understand the same cultural references.

Avoid slang and colloquialisms, even if you think it's funny or harmless. These may be hard to understand for people whose first language is not English, and may not translate well.

Do not use profanity.

Overloaded Words

Many terms that we use for their technical meanings also have other uses outside of technology. For example: abort, execute, or native. When you use words like these, always be precise and examine the context in which they appear.

Word List

The following list identifies some terminology that we have used in the Unreal codebase in the past, but that we believe should be replaced with better alternatives.

Alternatives: deny list, block list, exclude list, avoid list, unapproved list, forbidden list, permission list

Alternatives: allow list, include list, trust list, safe list, prefer list, approved list, permission list

Alternatives: primary, source, controller, template, reference, main, leader, original, base

Alternatives: secondary, replica, agent, follower, worker, cluster node, locked, linked, synchronized

We are actively working to bring our code in line with the principles laid out above.

Portable C++ code

bool for boolean values (NEVER assume the size of bool). BOOL will not compile.

TCHAR for a character (NEVER assume the size of TCHAR).

uint8 for unsigned bytes (1 byte).

int8 for signed bytes (1 byte).

uint16 for unsigned "shorts" (2 bytes).

int16 for signed "shorts" (2 bytes).

uint32 for unsigned ints (4 bytes).

int32 for signed ints (4 bytes).

uint64 for unsigned "quad words" (8 bytes).

int64 for signed "quad words" (8 bytes).

float for single precision floating point (4 bytes).

double for double precision floating point (8 bytes).

PTRINT for an integer that may hold a pointer (NEVER assume the size of PTRINT).

Use of C++'s int and unsigned int types—whose size may vary across platforms, but which is guaranteed to be at least 32 bits in width—is acceptable in code where the integer width is unimportant. Explicitly-sized types must still be used in serialized or replicated formats.

Use of standard libraries

Historically, UE has avoided direct use of the C and C++ standard libraries. There have been several reasons for this, including: replacing slow implementations with our own, allowing additional control over memory allocation, adding new functionality before it's widely available, making desirable but non-standard behavioral changes, having consistent syntax across the codebase, or avoiding constructs which are incompatible with UE's idioms. However, in recent years, the standard library has grown more stable and more mature, and includes functionality that we don't want to wrap with an abstraction layer or reimplement ourselves.

If there is a desire to use a new standard library component that hasn't been used before, the case should be made to the Coding-Standards group for evaluation. This also allows us to keep this list of allowed components up-to-date when they are accepted.

When there is a choice between a standard library feature instead of our own, prefer the option which gives superior results, but bear in mind that consistency is also valued highly. If a legacy UE implementation is no longer serving a purpose, we may choose to deprecate it and migrate all usage towards the standard library.

Avoid mixing UE idioms and standard library idioms in the same API.

<atomic>: should be used in new code and old migrated when touched. Atomics are expected to be implemented fully and efficiently on all supported platforms. Our own TAtomic is only partially implemented, and it isn't in our interest to maintain and improve it.

<type_traits>: should be used where there's overlap between a legacy UE trait and a standard trait. Traits are often implemented as compiler intrinsics for correctness, and compilers can have knowledge of the standard traits and select faster compilation paths instead of treating them as plain C++. One concern is that our traits typically have an upper case Value static or Type typedef, whereas standard traits are expected to use value and type. This is an important distinction, as a particular syntax is expected by compositional traits, e.g. std::conjunction. New traits we add should be written with lowercase value or type to support composition, and existing traits should be updated to support either case.

<initializer_list>: must be used to support braced initializer syntax. This is a case where the language and the standard libraries overlap, and there is no alternative if you want to support it.

<regex>: may be used directly, but its use should be encapsulated within editor-only code. We have no plans to implement our own regex solution.

<limits>: std::numeric_limits can be used in its entirety.

<cmath>: all the floating point functions from this header may be used.

<cstring>: memcpy() and memset() may be used instead of FMemory::Memcpy and FMemory::Memset respectively, when they have a demonstrable performance benefit.

Standard containers and strings should be avoided except in interop code.

Comments

Comments are communication and communication is vital. The following sections detail some things to keep in mind about comments (from Kernighan & Pike The Practice of Programming).

Guidelines

Write self-documenting code:

Write useful comments:

Do not comment bad code - rewrite it:

Do not contradict the code:

Const Correctness

Const is documentation as much as it is a compiler directive, so all code should strive to be const-correct.

This includes:

Passing function arguments by const pointer or reference if those arguments are not intended to be modified by the function,

Flagging methods as const if they do not modify the object,

and using const iteration over containers if the loop isn't intended to modify the container.

Example:

Const should also be preferred on by-value function parameters and locals. This tells a reader that the variable will not be modified in the body of the function, which makes it easier to understand. If you do this, make sure that the declaration and the definition match, as this can affect the JavaDoc process.

Example:

One exception to this is pass-by-value parameters, which will ultimately be moved into a container (see "Move semantics"), but this should be rare.

Example:

Put the const keyword on the end when making a pointer itself const (rather than what it points to). References can't be "reassigned" anyway, and so can't be made const in the same way.

Example:

Never use const on a return type, as this inhibits move semantics for complex types, and will give compile warnings for built-in types. This rule only applies to the return type itself, not the target type of a pointer or reference being returned.

Example:

Example Formatting

We use a system based on JavaDoc to automatically extract comments from the code and build documentation, so there are some specific comment formatting rules that need to be followed.

The following example demonstrates the format of class, method, and variable comments. Remember that comments should augment the code. The code documents the implementation, and the comments document the intent. Make sure to update comments when you change the intent of a piece of code.

Note that two different parameter comment styles are supported, shown by the Steep and Sweeten methods. The @param style used by Steep is the traditional multi-line style, but for simple functions it can be clearer to integrate the parameter and return value documentation into the descriptive comment for the function, as in the Sweeten example. Special comment tags like @see or @return should only be used to start new lines following the primary description.

Method comments should only be included once, where the method is publicly declared. The method comments should only contain information relevant to callers of the method, including any information about overrides of the method that may be relevant to the caller. Details about the implementation of the method and its overrides, that are not relevant to callers, should be commented within the method implementation.

What does a class comment include?

A description of the problem this class solves.

Why was this class created?

What do all those parts of the multi-line method comment mean?

Function purpose: This documents the problem this function solves. As has been said above, comments document intent, and code documents implementation.

Parameter comments: Each parameter comment should include:

units of measure,

the range of expected values,

"impossible" values,

and the meaning of status/error codes.

Return comment: This documents the expected return value, just as an output variable is documented. To avoid redundancy, an explicit @return comment should not be used if the sole purpose of the function is to return this value and that is already documented in the function purpose.

Extra information: @warning, @note, @see, and @deprecated can optionally be used to document additional relevant information. Each should be declared on their own line following the rest of the comments.

Modern C++ Language Syntax

Unreal Engine is built to be massively portable to many C++ compilers, so we are careful to use features that are compatible with the compilers we might be supporting. Sometimes features are so useful that we will wrap them up in macros and use them pervasively. However, we usually wait until all of the compilers we might be supporting are up to the latest standard.

Unreal Engine requires a minimum language version of C++17 to build, and we use many modern language features that are well-supported across modern compilers. In some cases, we can wrap up usage of these features in preprocessor conditionals. However, sometimes we decide to avoid certain language features entirely, for portability or other reasons.

Unless specified below, as a modern C++ compiler feature we are supporting, you should not use compiler-specific language features unless they are wrapped in preprocessor macros or conditionals and used sparingly.

static_assert

This keyword is valid for use where you need a compile-time assertion.

override and final

These keywords are valid for use, and their use is strongly encouraged. There might be many places where these have been omitted, but they will be fixed over time.

nullptr

nullptr should be used instead of the C-style NULL macro in all cases.

One exception to this is that nullptr in C++/CX builds (such as for Xbox One) is actually the managed null reference type. It is mostly compatible with nullptr from native C++ except in its type and some template instantiation contexts, and so you should use the TYPE_OF_NULLPTR macro instead of the more usual decltype(nullptr) for compatibility.

The 'auto' Keyword

You shouldn't use auto in C++ code, although a few exceptions are listed below. Always be explicit about the type you're initializing. This means that the type must be plainly visible to the reader. This rule also applies to the use of the var keyword in C#.

C++17's structured binding feature should also not be used, as it is effectively a variadic auto.

When is it acceptable to use auto?

When you need to bind a lambda to a variable, as lambda types are not expressible in code.

For iterator variables, but only where the iterator's type is verbose and would impair readability.

In template code, where the type of an expression cannot easily be discerned. This is an advanced case.

It's very important that types are clearly visible to someone who is reading the code. Even though some IDEs are able to infer the type, doing so relies on the code being in a compilable state. It also won't assist users of merge/diff tools, or when viewing individual source files in isolation, such as on GitHub.

If you're sure you are using auto in an acceptable way, always remember to correctly use const, & or * just like you would with the type name. With `auto`, this will coerce the inferred type to be what you want.

Range-Based for

This is preferred to keep the code easier to understand and more maintainable. When you migrate code that uses old TMap iterators, be aware that the old Key() and Value() functions, which were methods of the iterator type, are now simply Key and Value fields of the underlying key-value TPair.

Example:

We also have range replacements for some standalone iterator types.

Example:

Lambdas and Anonymous Functions

Lambdas can be used freely. The best lambdas should be no more than a couple of statements in length, particularly when used as part of a larger expression or statement, for example as a predicate in a generic algorithm.

Example:

Be aware that stateful lambdas can't be assigned to function pointers, which we tend to use a lot.

Non-trivial lambdas should be documented in the same manner as regular functions. Don't be afraid to split them over a few more lines in order to include comments.

Explicit captures should be used rather than automatic capture ([&] and [=]). This is important for readability, maintainability and performance reasons, particularly when used with large lambdas and deferred execution. It declares the intent of the author and so mistakes can more easily be caught during code review. Incorrect captures can have negative consequences which are more likely to become a problem as the code is maintained over time.

By-reference capture and by-value capture of pointers (including the this pointer) can cause accidental dangling references, if execution of the lambda is deferred.

By-value capture can be a performance concern if it makes unnecessary copies for a non-deferred lambda.

Accidentally captured UObject pointers are invisible to the garbage collector.Automatic capture captures this implicitly if any member variables are referenced, even though [=] gives the impression of the lambda having its own copies of everything.

Explicit return types should be used for large lambdas, or when you are returning the result of another function call. These should be considered in the same way as the auto keyword:

Automatic captures and implicit return types are acceptable for trivial, non-deferred lambdas, such as in Sort calls, where the semantics are obvious and being explicit would make it overly verbose.

The capture initializer feature from C++14 may be used:

Strongly - Typed Enums

Enum classes should always be used as a replacement for old-style namespaced enums, both for regular enums and UENUMs. For example:

These are also supported as UPROPERTYs, and replace the old TEnumAsByte<> workaround. Enum properties can also be any size, not just bytes:

However, enums exposed to Blueprints must continue to be based on uint8.

Enum classes used as flags can take advantage of the ENUM_CLASS_FLAGS(EnumType) macro to automatically define all of the bitwise operators:

The one exception to this is the use of flags in a truth context - this is a limitation of the language. Instead, all flags enums should have an enumerator called None which is set to 0 for comparisons:

Move Semantics

All of the main container types—TArray, TMap, TSet, FString—have move constructors and move assignment operators. These are often used automatically when passing/returning these types by value, but can be explicitly invoked by using MoveTemp, which is UE's equivalent of std::move.

Returning containers or strings by value can be a win for expressivity, without the usual cost of temporary copies. Rules around pass-by-value and use of MoveTemp are still being established, but can already be found in some optimized areas of the codebase.

Default Member Initializers

Default member initializers can be used to define the defaults of a class inside the class itself:

Code written like this has the following benefits:

It doesn't need to duplicate initializers across multiple constructors.

It isn't possible to mix the initialization order and declaration order.

The member type, property flags and default values are all in one place, which helps readability and maintainability.

However, there are also some downsides:

Any change to the defaults will require a rebuild of all dependent files.

Headers can't change in patch releases of the engine, so this style can limit the kinds of fixes that are possible.

Some things can't be initialized in this way, such as base classes, UObject subobjects, pointers to forward-declared types, values deduced from constructor arguments, and members initialized over multiple steps.

Putting some initializers in the header, and the rest in constructors in the .cpp file, can reduce readability and maintainability.

Use your best judgment when deciding whether to use them. As a rule of thumb, default member initializers make more sense in game code than engine code. Also consider using config files for default values.

Third Party Code

Whenever you modify the code to a library that we use in the engine, be sure to tag your changes with a //@UE4 comment, as well as an explanation of why you made the change. This makes merging the changes into a new version of that library easier, and lets licensees easily find any modifications we have made.

Any third party code included in the engine should be marked with comments formatted to be easily searchable. For example:

Code Formatting

Braces

Brace wars are foul. Epic has a long standing usage pattern of putting braces on a new line. Please adhere to that usage.

Always include braces in single-statement blocks. For example.:

If - Else

Each block of execution in an if-else statement should be in braces. This is to prevent editing mistakes - when braces are not used, someone could unwittingly add another line to an if block. The extra line wouldn't be controlled by the if expression, which would be bad. It's also bad when conditionally compiled items cause if/else statements to break. So always use braces.

A multi-way if statement should be indented with each else if indented the same amount as the first if; this makes the structure clear to a reader:

Tabs and Indenting

Here are the standards for indenting your code.

Indent code by execution block.

Use tabs, not spaces, for whitespace at the beginning of a line. Set your tab size to 4 characters. However, spaces are sometimes necessary and allowed for keeping code aligned regardless of the number of spaces in a tab. For example, when you are aligning code that follows non-tab characters.

If you are writing code in C#, please also use tabs, and not spaces. The reason for this is that programmers often switch between C# and C++, and most prefer to use a consistent setting for tabs. Visual Studio defaults to using spaces for C# files, so you will need to remember to change this setting when working on Unreal Engine code.

Switch Statements

Except for empty cases (multiple cases having identical code), switch case statements should explicitly label that a case falls through to the next case. Either include a break, or include a falls-through comment in each case. Other code control-transfer commands (return, continue, and so on) are fine as well.

Always have a default case, and include a break just in case someone adds a new case after the default.

Namespaces

You can use namespaces to organize your classes, functions and variables where appropriate. If you do use them, follow the rules below.

Most UE code is currently not wrapped in a global namespace. Be careful to avoid collisions in the global scope, especially when using or including third party code.

Namespaces are not supported by UnrealHeaderTool, so they should not be used when defining UCLASSes, USTRUCTs and so on.

New APIs which aren't UCLASSes, USTRUCTs etc, should be placed in a UE:: namespace at least, and ideally a nested namespace, e.g. UE::Audio::. Namespaces which are used to hold implementation details which are not part of the public-facing API should go in a Private namespace, e.g. UE::Audio::Private::.

Using declarations:

Do not put using declarations in the global scope, even in a .cpp file (it will cause problems with our "unity" build system.)

It's okay to put using declarations within another namespace, or within a function body.

If you put using declarations within a namespace, this will carry over to other occurrences of that namespace in the same translation unit. As long as you are consistent, it will be fine.

You can only use using declarations in header files safely if you follow the above rules.

Note that forward-declared types need to be declared within their respective namespace. If you don't do this, you will get link errors.

If you declare a lot of classes/types within a namespace, it can be difficult to use those types in other global-scoped classes (for example, function signatures will need to use explicit namespace when appearing in class declarations).

You can use using declarations to only alias specific variables within a namespace into your scope (for example, using Foo::FBar). However, we don't usually do that in Unreal code.

Macros cannot live in a namespace, but should be prefixed with UE_ instead, e.g. UE_LOG.

Physical Dependencies

File names should not be prefixed where possible; for example, Scene.cpp instead of UScene.cpp. This makes it easy to use tools like Workspace Whiz, or Visual Assist's Open File in Solution, by reducing the number of letters needed to identify the file you want.

All headers should protect against multiple includes with the #pragma once directive. Note that all compilers we use support #pragma once.

In general, try to minimize physical coupling. In particular, avoid including standard library headers from other headers.

If you can use forward declarations instead of including a header, do so.

When including, be as fine grained as possible. For example, do not include Core.h--include the specific headers in Core that you need definitions from.

Try to include every header you need directly, to make fine-grained inclusion easier.

Don't rely on a header that is included indirectly by another header you include.

Don't rely on being included through another header. Include everything you need.

Modules have Private and Public source directories. Any definitions that are needed by other modules must be in headers in the Public directory. Everything else should be in the Private directory. Note that in older Unreal modules, these directories may still be called "Src" and "Inc", but those directories are meant to separate private and public code in the same way, and are not meant to separate header files from source files.

Don't worry about setting up your headers for precompiled header generation. UnrealBuildTool can do a better job of this than you can.

Split up large functions into logical sub-functions. One area of compilers' optimizations is the elimination of common subexpressions. The bigger your functions are, the more work the compiler has to do to identify them. This leads to greatly inflated build times.

Don't use too many inline functions, because they force rebuilds even in files which don't use them. Inline functions should only be used for trivial accessors and when profiling shows there is a benefit to doing so.

Be even more conservative in the use of FORCEINLINE. All code and local variables will be expanded out into the calling function, and this will cause the same build time problems caused by large functions.

Encapsulation

Enforce encapsulation with the protection keywords. Class members should almost always be declared private unless they are part of the public/protected interface to the class. Use your best judgment, but always be aware that a lack of accessors makes it hard to refactor later without breaking plugins and existing projects.

If particular fields are only intended to be usable by derived classes, make them private and provide protected accessors.

Use final if your class is not designed to be derived from.

General Style Issues

Minimize dependency distance. When code depends on a variable having a certain value, try to set that variable's value right before using it. Initializing a variable at the top of an execution block, and not using it for a hundred lines of code, gives lots of space for someone to accidentally change the value without realizing the dependency. Having it on the next line makes it clear why the variable is initialized the way it is and where it is used.

Split methods into sub-methods where possible. It is easier for someone to look at a big picture, and then drill down to the interesting details, than it is to start with the details and reconstruct the big picture from them. In the same way, it is easier to understand a simple method, that calls a sequence of several well-named sub-methods, than it is to understand an equivalent method that simply contains all the code in those sub-methods.

In function declarations or function call sites, do not add a space between the function's name and the parentheses that precede the argument list.

Address compiler warnings. Compiler warning messages mean something is wrong. Fix what the compiler is warning you about. If you absolutely can't address it, use #pragma to suppress the warning, but this should only be done as a last resort.

Leave a blank line at the end of the file. All .cpp and .h files should include a blank line, to coordinate with gcc.

Debug code should either be generally useful and polished, or not checked in. Debug code that is intermixed with other code makes the other code harder to read.

Always use the TEXT() macro around string literals. Without it, code that constructs FStrings from literals will cause an undesirable string conversion process.

Avoid repeating the same operation redundantly in loops. Move common subexpressions out of loops to avoid redundant calculations. Make use of statics in some cases, to avoid globally-redundant operations across function calls, such as constructing an FName from a string literal.

Be mindful of hot reload. Minimize dependencies to cut down on iteration time. Don't use inlining or templates for functions which are likely to change over a reload. Only use statics for things which are expected to remain constant over a reload.

Use intermediate variables to simplify complicated expressions. If you have a complicated expression, it can be easier to understand if you split it into sub-expressions, that are assigned to intermediate variables, with names describing the meaning of the sub-expression within the parent expression. For example:

should be replaced with

Pointers and references should only have one space, which is to the right of the pointer or reference. This makes it easy to quickly use Find in Files for all pointers or references to a certain type.

Use this:

Not these:

Shadowed variables are not allowed. C++ allows variables to be shadowed from an outer scope, but this makes usage ambiguous to a reader. For example, there are three usable Count variables in this member function:

Avoid using anonymous literals in function calls. Prefer named constants which describe their meaning:

This makes intent more obvious to a casual reader as it avoids the need to look up the function declaration to understand it.

Avoid defining non-trivial static variables in headers, as this will cause an instance to be compiled into in every translation unit that includes that header:

should be replaced with

API Design Guidelines

bool function parameters should be avoided, particularly for flags passed to functions. These have the same anonymous literal problem as mentioned previously, but they also tend to multiply over time as APIs get extended with more behavior. Instead, prefer an enum (see the advice on use of enums as flags in the Strongly-Typed Enums section):

This form prevents the accidental transposing of flags, avoids accidental conversion from pointer and integer arguments, removes the need to repeat redundant defaults, and is more efficient.It is acceptable to use bools as arguments when they are the complete state to be passed to a function like a setter, such as void FWidget::SetEnabled(bool bEnabled). Though consider refactoring if this changes.

Avoid overly-long function parameter lists. If a function takes many parameters then consider passing a dedicated struct instead:

Avoid overloading functions by bool and FString, as this can have unexpected behavior:

Interface classes (prefixed with "I") should always be abstract, and must not have member variables. Interfaces are allowed to contain methods that are not pure-virtual, and can even contain methods that are non-virtual or static, as long as they are implemented inline.

Use the virtual and override keywords when declaring an overriding method. When declaring a virtual function in a derived class that overrides a virtual function in the parent class, you must use both the virtual and the override keywords. For example:

There is a lot of existing code that doesn't follow this yet, due to the recent addition of the override keyword. The override keyword should be added to that code when convenient.

Platform-Specific Code

Platform-specific code should always be abstracted and implemented in platform-specific source files in appropriately named subdirectories, for example:

In general, you should avoid adding any uses of PLATFORM_[PLATFORM] (e.g PLATFORM_XBOXONE) to code outside of a directory named [PLATFORM].

Instead, extend the hardware abstraction layer to add a static function, e.g. in FPlatformMisc:

Platforms can then override this function, returning either a platform-specific constant value or even using platform APIs to determine the result.

If you force-inline the function it will have the same performance characteristics as using a define.

In cases where a define is absolutely necessary, create new #defines that describe particular properties that can apply to a platform, for example PLATFORM_USE_PTHREADS. Set the default value in Platform.h and override for any platforms which require it in the platform-specific Platform.h file.

For example, in Platform.h we have:

Windows/WindowsPlatform.h has:

Cross-platform code can then use the define directly without needing to know the platform.

Reasoning: centralizing the platform-specific details of the engine allows for such details to be contained entirely within platform-specific source files. Doing so makes it easier to maintain the engine across multiple platforms and also to port the code to new platforms without the need to scour the codebase for platform-specific defines.

Keeping platform code in platform-specific folders is also a requirement for NDA platforms such as PlayStation, Xbox and Nintendo Switch.

It is important to ensure the code compiles and runs regardless of whether the [PLATFORM] subdirectory is present. In other words, cross platform code should never be dependent on platform-specific code.

How to Read This Page

Motivation

Core Tenets

Polling Data Flow and Delegates

Attributes and Arguments

Performance Considerations

Invalidation vs Polling

Child Slots

Widget Roles

Layout

Pass 1: Cache Desired Size

Pass 2: ArrangeChildren

Drawing Slate : OnPaint

Anatomy of a SWidget

Composition

Declarative Syntax

How to Read This Page

Core ideas guiding Slate design are found here. They are found in no particular order. There is no rigid structure or grand theory here; it is just a collection of principles that arise from UI tinkering experience.

You may find it helpful to re-read this page from time to time as you gain experience with Slate.

Motivation

The motivations for Slate arise from observations about off-the-shelf UI solutions available at the time. Some follow here:

Building up UIs from widgets is already easy in most toolkits. What is hard:

UI Design and iteration.

Controlling the flow of data: usually thought of as binding between widgets (view) and underlying data (model).

Learning a foreign language for describing UIs.

IMGUI : Immediate Mode Graphics User Interface

Pros:

Programmers like that UI description is "close" to the code; easy to get at the data.

Invalidation is usually a non-issue; just poll data directly.

Easy to procedurally build interfaces.

Cons:

Adding animation and styling is harder.

UI description is imperative code, so no chance to make it data-driven.

Desired Slate Characteristics:

Easy access to model's code and data.

Support procedural UI generation.

UI description should be hard to screw up.

Must support animation and styling.

Core Tenets

Design for developer efficiency where possible. A programmer's time is expensive; CPUs are fast and cheap.

Avoid opaque caches and duplicated state. Historically, UIs cache state and require explicit invalidation. Slate uses following approaches (from preferred to least preferred):

Polling

Transparent caches

Opaque caches with low-grain invalidation

When UI structure is changing, prefer polling to notification. (When notification is necessary, prefer low-grain notifications to fine-grain notifications.)

Avoid feedback loops. E.g. all layout is computed from programmer settings; never rely on previous layout state.

Only exceptions are when UI state becomes the model; e.g. ScrollBars visualize UI state.

This is done for correctness and programmer sanity rather than performance.

Plan for the messy, ad-hoc UIs that require a ton of one-offs to work. Generalize these into nice systems later, when the use-cases are understood.

Polling Data Flow and Delegates

UIs visualize and manipulate Models. Slate uses delegates as a flexible conduit for widgets that need to read and write the Model's data. Slate widgets read the Model's data when they need to display it. When a user performs some actions, Slate widgets invoke the write delegate in order to modify the data.

Consider STextBlock - a Slate widget that displays text. The STextBlock must be told where to get the data to display. The data could be set statically. However, a more flexible way to accomplish this is a delegate (a function specified by the user). The STextBlock uses a delegate called Text for this purpose.

The STextBlock reads the framerate as a string.

Consider also that in the example above the Text is a string, while the framerate is most likely stored as a float or an integer. The use of delegates offers us the flexibility to perform the conversion whenever the value is read. This immediately conjures up performance concerns which are addressed in the Performance Considerations section below.

SEditableText is a Slate widget responsible for both input and output. Just like STextBlock, it uses the Text delegate for visualizing data. The user types some text into the editable text field, and when they hit enter, SEditableText invokes the OnTextChanged delegate. The assumption is that the programmer has attached the functionality appropriate for validating the input and mutating the Model's data to OnTextChanged.

The SEditable text reads the item name. When the user hits enter, the new text is sent to OnTextChanged where it will be validated and assigned to item name if appropriate.

During the next frame, the SEditableText will read from the Model's data. In the example above, item name will have been mutated by the OnTextChanged delegate and will be read for visualization via the Text delegate.

Attributes and Arguments

Using a delegate is not always desirable. Depending on the use case, the arguments to Slate widgets may need to be constant values or functions. We encapsulate this notion via the TAttribute < T > class. An attribute can be set to a constant or to a delegate.

Performance Considerations

After reading the Polling Data Flow and Delegates section, one might have serious concerns about performance.

Consider the following observations:

UI complexity is bounded by the number of live widgets.

Scrolling content is virtualized whenever possible; this mostly avoids live widgets off-screen.

Large numbers of off-screen widgets can easily tank Slate performance.

Assumption: users with big screens have beefy machines to drive those screens; they can handle a large number of widgets.

Invalidation vs Polling

Sometimes polling is either not performant or functionally incorrect. This is often the case with non-trivial values that cannot be expressed as a combination of simpler, trivial values. We usually invalidate in scenarios where the structure of the Model changes drastically. It is then reasonable to scrap an existing UI and recreate it. However, doing so assumes state loss, so we should not do it unless necessary.

Invalidation is - as a rule - reserved for infrequent, low-granularity events.

Consider the example of the Blueprint Editor, which displays nodes on a graph. When an update is requested, all the Graph Panel widgets are cleared and re-created. This is preferable to fine-grain invalidation because it is simpler and more maintainable.

Child Slots

All Slate widgets store children in child slots. (As opposed to storing a plain array of child widgets.) Child slots always store a valid widget; by default they store the SNullWidget, which is a widget with no visualization or interaction. Each type of widget can declare its own type of child slot, which caters to its specific needs. Consider that SVerticalSlot arranges its children completely differently than an SCanvas, which is quite different from SUniformGridPanel. The Slots allow each type of panel to ask for a set of per-child settings that affect the arrangement of the children.

Widget Roles

Widgets come in three flavors.

Leaf Widgets - widgets with no child slots. e.g. STextBlock displays a piece of text. It has native knowledge of how to draw text.

Panels - widgets with a dynamic number of child slots. e.g. SVerticalBox arranges any number of children vertically given some layout rules.

Compound Widgets - widgets with a fixed number of explicitly named child slots. e.g. SButton has one slot called Content which contains any widgets inside the button.

Layout

Slate layout is accomplished in two passes. The two-pass breakdown is an optimization, but unfortunately not a transparent one.

Pass 1: Cache Desired Size - the relevant functions are SWidget::CacheDesiredSize and SWidget::ComputeDesiredSize

Pass 2: ArrangeChildren - the relevant function is SWidget::ArrangeChildren

In more detail:

The goal of this pass is to figure out how much space each widget wants to occupy. Widgets with no children (i.e. leaf widgets) are asked to compute and cache their desired size based on their intrinsic properties. Widgets that combine other widgets (i.e. compound widgets and panels) use special logic to determine their desired size as a function of the size of their children. Note that each type of widget is only required to implement ComputeDesiredSize(); the caching and traversal logic are implemented by Slate. Slate guarantees that when ComputeDesiredSize() is called on a widget, its children have already computed and cached their desired size. Thus, this is a bottom-up pass.

In the below example, we examine a horizontal box that arranges two children - a piece of text and an image.

A horizontal box arranges two children - a text block and an image.

An STextBlock widget would compute its desired size by measuring the string that it is displaying. The SImage widget would determine its size based on the image data it is showing. Assume that the text inside the textblock requires 14 slate units of space, and the image requires 8. The horizontal panel arranges widgets horizontally, and therefore requires 14 + 8 = 22 units of space.

ArrangeChildren is a top-down pass. Slate begin at the top-level windows and asks each window to arrange its children based on the constraints provided by the programmers. When the space allotted for each child is known, Slate can recur and arrange the children's children. The recursion continues until all the children are arranged.

A horizontal panel arranges two children, a text block and an image.

In the example above, the panel was allotted 25 units by its parent. The first slot indicates that it wants to use the desired size of the child, and is allotted 14 units of space. The second slot indicates that it wants to fill the available width, and is allotted the balance (11 units of space). Note that in the actual SHorizontalBox widget, the alignment of the SImage within its slot would be driven by the HAlign property, which can be Left, Center, Right, or Fill.

In practice, Slate never performs a full ArrangeChildren pass. Instead, this functionality is used to implement other functionality. Key examples are hit detection and painting.

Drawing Slate : OnPaint

During the paint pass, Slate iterates over all the visible widgets and produces a list of draw elements which will be consumed by the rendering system. This list is produced anew for every frame.

We begin at the top level windows and recur down the hierarchy, appending the draw elements of every widget to the draw list. Widgets tend to do two things during paint: they output actual draw elements or figure out where a child widget should exist and ask the child widget to paint itself. Thus, we can think of a simplified general-case OnPaint function as being:

Anatomy of a SWidget

The key functions that define an SWidget's behavior in Slate are:

ComputeDesiredSize() - responsible for desired size.

ArrangeChildren() - responsible for arrangement of children within the parent's allotted area.

OnPaint() - responsible for appearance.

Event handlers - these are of the form OnSomething. These are functions that may be invoked on your widget by Slate at various times.

Composition

Composition is the notion that any slot should be able to contain arbitrary widget content. This affords users of Slate a great deal of flexibility. Composition is used whenever possible in core Slate widgets.

If you are ever thinking that you want a widget to take a string argument to be used as a label, ask yourself if it would not be better off taking an SWidget instead.

Specific use-cases often demand that widgets contain children of a specific type, in which case composition requirements no longer apply. These should never be widgets in the core of slate, but rather domain-specific widgets that are not intended for reuse outside of that domain.

Declarative Syntax

We wanted Slate to be accessible directly from code. Experience dictated that we needed a declarative language for describing UI, but we also wanted it to be compile-time checked for binding to C++ functions.

The solution was to build a declarative UI-description language as a subset of C++.

Examples abound in the codebase.



Declarative Syntax

Composition

Styles

Input

Output

Layout Primitives

User Driven Layout

Developer tools

Engine Access

Slate is a completely custom and platform agnostic user interface framework that is designed to make building the user interfaces for tools and applications such as Unreal Editor, or in-game user interfaces, fun and efficient. It combines a declarative syntax with the ability to easily design, lay out, and style components that allows for easily creating and iterating on UIs.

The Slate UI solution makes it extremely easy to put together graphical user interfaces for tools and applications and iterate on them quickly.

Declarative Syntax

Slate's declarative syntax makes building UIs accessible to programmers without adding layers of indirection. A complete set of macros are provided to simplify the process of declaring and creating new widgets.

Composition

Slate's composition framework makes it simple to re-arrange UI elements quickly for prototyping and iteration.

Here is an example of a piece of the UI being composed:

The composition above creates the UI elements below:



Styles

Styles can be created and applied to the various parts of a widget. This makes it easy to iterate on the look of the components in the UI, as well as share and reuse styles.

Styles used in composition:

Input

Slate has support for accepting mouse and keyboard input. It provides a flexible key binding system that makes it possible to bind any key combination to any command; including the ability to dynamically modify those bindings.

Output

Slate uses target agnostic rendering primitives allowing it to potentially run on any platform. It currently targets the Unreal Engine 4 (UE4) Rendering Hardware Interface (RHI) so it can run on any platform that UE4 runs on.

Layout Primitives

Layout Primitives make it easy to build static and dynamic layouts.

The layout above creates the UI below:



User Driven Layout

Slate's docking framework puts the power into the user's hands by allowing its tabbed panels to be rearranged and docked into virtually any layout imaginable. The ability to customize their environment lets the user work with the tools they want to work with the way they want to work with them.

Floating tab:



Drag tab to docking target:



Docked tab:



Developer tools

The Slate Widget Reflector provides a means of debugging and analyzing the UI and associated code. This helps track down bugs and undesirable behavior as well as profile and optimize your user interface.



Engine Access

The Slate UI system provides direct access to engine and editor for programmers; making it much easier to implement new features and tools to accommodate the workflow of any development team and requirements of any project.

Module Dependencies

In order to use the Slate User Interface (UI) Framework, your project must be set up properly so that it is aware of the

This allows you to include the Slate.h header and reference the various elements of the framework necessary for building a UI with slate.

Module Dependencies

The Slate framework is stored in a few modules. In order to make your project aware of these, some dependencies must be set up in the *.build.cs file for your project.

The modules your project needs access to are:

Module

Dependency Type

InputCore

Public

Slate

Private

SlateCore

Private

To set up the Slate module dependencies:

Open the [ProjectName].build.cs file for your project. It is located in the [ProjectDir]/[ProjectName]/Source/[ProjectName] directory.

Add the InputCore public dependency by adding "InputCore" to the PublicDependencyModuleNames.

The InputCore module is set as a public dependency by default when code projects are created.

Add Slate and SlateCore private dependencies. A line exists in the *.build.cs file for adding private dependencies:

Add the SlateCore and Slate modules to that line:

Depending on when you created your project, and with what version of the engine, it may already have the Slate dependencies set up in the *.build.cs files but commented out. You can uncomment the appropriate lines to set up the dependencies.

Clipping

What's New

Conversion Guide from 4.16 and Earlier to 4.17 and Later

Enabling Clipping of Widgets

Deprecated APIs

Custom Clipping

Wrapped Clipping States

Culling Changes

Debugging Clipping

With the release of Unreal Engine 4.17, the new Slate Clipping System will break backward compatibility for versions 4.16 and earlier that update. See the Conversion Guide section of this page to update your project.

The Unreal Engine 4 (UE4) uses Slate's clipping system to restrict graphics or text to a region of your screen. This is done by creating a clipping rectangle (or clipping rect) around the objects and panels that are created. This system is used throughout the Editor and the UMG UI Designer tools. Slate enables users to move panels and resize them as needed in the Editor, and the clipping system enables the text and graphics to be confined to their clipping rect. With UMG, this enables better render transforms that clip appropriately for your UI.

What's New

Unreal Engine 4.17 overhauled the clipping system to be much more flexible than it has in previous versions. This creates a potential to add more rendering effects for tool systems like UMG to use for your project's UI. The clipping system used in prior versions was limited and only axis-aligned for layout-space which lead to noticeable difficulties with render transforms, generally around edges, like in the example below:





This example shows that while the Widget is rotated the clipping rect (white dots) is not, which causes the graphic not to render even though it is within the Canvas panel bounds.

Below is comprised list of differences between version 1.0 and 2.0 of the Clipping System:

Clipping 1.0 (4.16 and earlier)

Clipping 2.0 (4.17 and later)

Axis-aligned clipping - Only functions in layout space

Every Widget gets clipped

All clipping is done in the pixel shader (requires six floats per vertex)

Allowed batching across clipping rects, since the rects are part of the batch data

Render Transforms are "special" in that they allow rendering outside the clipping rect provided by the parent, with side effects when the layout rect is clipped

A clipping that is an arbitrary quad

Axis-aligned clipping zone using Scissor Rects to clip - which avoids unnecessary pixel shader operations

Complex clipping zones use the stencil buffer to compose an arbitrary stack of clipping zones into the stencil buffer that is then used to clip draw calls

Very few widgets clip now (by default), consisting mostly of scroll panels and editable text fields

Render Transforms are no longer "special," so any transform can allow you to render outside of another widget, provided it doesn't clip.

Slate can no longer batch across clipping zones. This frees up six floats in the Slate vertex format, and no longer need to clip in the pixel shader

Because the new system supports clipping in the render space of the widgets instead of requiring axis-alignment, the system no longer needs to be concerned with clipping issues (left), and instead clips the outermost widget. Now, any transform that is applied to the inner widgets will be correctly clipped at the edges (right).





4.16 and earlier clipping and transforms.

4.17 and later, clipping applied at edges

along with transforms to the children.

For the most part, you shouldn't need to worry about changing the clipping state of a widget. If you were to consider game UI as an example, you wouldn't really need to adjust the widget in UMG and mostly would change this for something like a scroll panel, or in cases, like the Editor, where you can't control the length of the text and need to clip it for resizing the windows or parts of the panel.



Here are a few examples of what you might see with various clipping setups:

Left - No clipping is enabled on the button or the text.

Center - Clipping is enabled on the text

Right - Clipping is enabled on the button.

Take note of the difference it makes when clipping is assigned to different objects. Since the system clips to bounds, things like padding do not factor in here, so if the button is set to clip (right), the contents will run all the way to the edge before it is cut off, whereas if the text is responsible for handling the clipping (center), then the text clips based on things like the button content padding that reduces the space the text has to fit into.

In addition to the simple axis-aligned examples of clipping, the system also supports arbitrary clipping quads that are stacked on top of each other.





While this example is extreme, being able to combine multiple arbitrary clipping zones is a prerequisite to being able to introduce 3D transforms and projections, since any widget being clipped with a projection would need to perform clipping in projected space.

Conversion Guide from 4.16 and Earlier to 4.17 and Later

The changes to the Slate clipping system in 4.17 will break compatibility with previous versions, so you'll want to use the sections below to update your project to avoid any conversion issues and to learn about the new methods you can use to debug Widgets in your project.

Enabling Clipping of Widgets

For all your UMG Widgets, you can adjust the Clipping property located in the Details panel of the selected Widget.



You can learn more about Clipping with UMG UI Designer here.

To enable clipping in your code, you'll set the clipping property for EWidgetClipping to one of the following states:

Inherit

ClipToBounds

ClipToBoundsWithoutIntersecting

ClipToBoundsAlways

OnDemand

Here's a code example:

Deprecated APIs

The following APIs have been deprecated as of 4.16. If your project was using these, consider if you would even need to use them now. Not every Widget clips, so you may no longer need any code that was possibly tricking the clipping system to allow you to move the clipping zone.

FSlateDrawElement::Make___(...) - there is no longer need to pass a clipping rect into every draw call, so you only need to remove the function call, and you'll automatically be using the new version.

SScissorRectBox - This is no longer necessary since every axis-aligned clipping rect is now a scissor rect. Make sure to delete these and replace the job it was doing by making its most direct child widget have clipping enabled.

Custom Clipping

There are cases where you may need to clip internally in your widget. For example, a SProgressBar may need to clip the progress bar drawing at arbitrary locations based on its progress. To add your clipping, you would do the following in OnPaint:

The FSlateClippingZone is the arbitrary clipping area in window space that can be initialized using several methods that should allow for a straightforward conversion of your existing code.

If you also need your custom clipping to affect Hit Testing, you will need to push your clipping zone onto the Hit Test Grid by setting up the following:

The clipping rect for the Hit Test Grid is using cached geometry, instead of the AllotedGeometry. In OnPaint, AllotedGeometry is in window space, while the Hit Test Grid is in desktop space, so you have to use geometry that you'd get in Tick.

Wrapped Clipping States

In some instances, a widget that has a clipping state isn't going to be responsible for clipping. For example, the SScrollBox lets you publically change the clipping state like any other widget, however, when the SScrollBox was constructed, it set bClippingProxy to true. This makes it so that when Slate goes to render that widget, it will ignore its clipping state.

Internally, the SScrollBox informs another nested widget that it needs to clip or perform whatever clipping state it was told to do. Additionally, when users change the clipping state, the SScrollBox overrides the SWidget function called OnClippingChanged so that it knows when to mirror the new clipping state to the nested private widgets.

Culling Changes

Although clipping is performed in render space, the engine still performs culling using a simple bounding box. However, that box is based on the bounding box of the render-transformed clipping zone. Additionally, clipping and culling might become more nuanced over time, so if you have a custom panel and were doing MyClippingRect.IntersectionWith to identify and cull widgets that can't possibly be drawn, you should now use the SWidget function IsChildWidgetCulled. The following is an example of this:

Any place where you're taking in MyClippingRect in your OnPaint call should be renamed to MyCullingRect.

Even with the changes to the clipping system, Slate's culling approach hasn't changed. In the example below, you'll need to keep in mind that if the parent widget (blue) is culled when outside the clipping zone (green), the child widget (yellow) will also be culled, even if it has a transform that allows it to render entirely outside of the bounds of the parent. This is true even when the clipping property Clip to Bounds - Without Intersecting is enabled since the flag would only be checked by the direct parent widget.





Debugging Clipping

The Widget Reflector indicates the clipping state for selected Widgets inside the Editor.





A text block has been selected using the Widget Reflector that indicates the Clipping state to be set to On Demand.



To open the Widget Reflector, navigate to the file menu and select Window > Developer Tools > Widget Reflector.

Below are the available console variables that can be used to debug clipping and culling states for any Widget in the Editor:

Console Variable

Description

Slate.ShowClipping

When enabled, this shows yellow outlines for all axis-aligned clipping rects (Scissor Rects) and red outlines for all stencil clipping quads.





Click image for full size view.





Slate.DebugCulling

When enabled, this helps you to better understand how the culling in a panel is working or why it isn't working correctly. It disables clipping on the GPU, but everything continues as normal, so it enables you to see all the things rendering outside the bounds of clip zones and see if they are being culled when you expect them to be.

Slate.EnableDrawEvents

When enabled, draw events will be enabled so that when you're debugging with RenderDoc or something similar that it's easier to understand the batches or clipping state transitions. This is enabled by default when using a Debug build.

Common Slate Arguments

Visibility

Alignment

Box Panels

Slot Attributes

Uniform Grid Panels

Wrap Boxes

Radio Buttons

Menus and Toolbars

Menus

Context Menus

Toolbars

Item Views

List Views

Tree Views

Tile Views

Common Slate Arguments

The following arguments are common to every single widget that is created.

IsEnabled - This will specify whether or not the widget is able to be interacted with. If it is disabled, it will be greyed out.

ToolTip - This will specify what kind of custom SToolTip widget will be used for this widget's tool tip. If not specified, it will not appear.

ToolTipText - This will specify what kind of text will show up as a simple tooltip for this widget's tool tip. If not specified, or if the ToolTip attribute was used, it will not appear.

Cursor - This will specify what cursor will appear while the mouse is hovering over this widget.

Visibility - See the Visibility section below.

The following arguments are not on every single widget, but they are on most widgets.

Text - This will specify the text that this widget will have, if applicable.

Content - This will specify what widget should be placed in the content section of the widget, if applicable.

ReadOnly - This will prevent this widget from being editable if true.

Style - This will specify the style of images or text font used by the widget. How this is applicable varies by widget.

[...]ColorAndOpacity - The color and opacity of the widget or of the specified system.

Padding - The padding of a widget amount of spacing in slate units around the left, top, right, and bottom parts of the widget within its parent. These can be specified as a single value for all four parts, or as a horizontal and vertical value, or as four separate values.

HAlign - The horizontal alignment of content within the widget.

VAlign - The vertical alignment of content within the widget.

Visibility

The visibility of a widget determines how the widget will appear, as well as its interactivity.

Visible (Default) - The widget will appear normally.

Collapsed - The widget will not be visible and will take up no space in the layout. It will not be interactive.

Hidden - The widget will not be visible, but will take up space in the layout. It will not be interactive.

HitTestInvisible - Visible to the user, but only as art. It will not be interactive.

SelfHitTestInvisible - Same as HitTestInvisible, but does not apply to child widgets.

Alignment

The alignment of a widget determines the location of the widget within its parent. If a widget's parent is the same size (excluding padding) as the widget, then alignment is meaningless. This will happen by default with box slots, when you specify "Fill" for the widget, or a box slot specifies a Fill Size.

The possible alignments are listed below:

HAlign_Fill/VAlign_Fill

HAlign_Left

VAlign_Top

HAlign_Center/VAlign_Center

HAlign_Right

VAlign_Bottom

Box Panels

SHorizontalBox and SVerticalBox are the most common widgets for arranging your layout. These box panels are declared as widgets, but then they have slots inserted into them. SHorizontalBoxes have these slots arranged with the first widget on the left and the last to the right, while SVerticalBoxes have these slots arranged from top to bottom.

SScrollBox functions similar to SVerticalBox, with the exception that it allows vertical scrolling of the child slots.

Slot Attributes

Width or Height Settings (The following options are mutually exclusive):

Auto Size (Default) - This will specify that the slot will fill up as much space as it needs, but no more. Alignment within slots does not matter here.

Fill Size - Specifying a fill coefficient will cause it to fill up the space based on the fill coefficients of other slots. Alignment of the slot in the same orientation does not matter here.

Max Size - This will specify the maximum size that the slot can be in slate units.

Padding - This will specify the padding of the slot within the panel.

Alignment - This will determine how the child widget will be aligned within the slot. This option is meaningless with Fill Size specified in the same orientation.

Below is an example of both autosized horizontal boxes and fill sized horizontal boxes nested within a scrollbox. Also shown is how the alignment can be used with these slots.

Uniform Grid Panels

SUniformGridPanel is a panel that distributes its child widgets evenly both vertically and horizontally. Its child slots are specified using a pair of integers which specify the index of the child. Below is such a uniform grid panel.

Wrap Boxes

SWrapBox is a box that lays out widgets horizontally until these widgets exceed a width, at which point they will be placed on the next line, and so on. Below is an example of such.

Radio Buttons

Radio Buttons are check boxes in slate, because check boxes require a delegate for how to determine whether they are checked. To make a series of radio buttons, the easiest way to do this is to create an enum which determines which check box is checked. Save an instance of the enum which determines the current choice. Then, for the checking delegate, pass in a function which compares a passed in payload of the correct enum with the current choice. On changing the selection, the current choice needs to be updated.

Menus and Toolbars

Menus

To create menus or toolbars, use multiboxes. Commands should use Slate's UI_COMMAND system, though this cannot be done with dynamically generated buttons/controls.

To create a menu, create an FMenuBarBuilder with an FUICommandList passed in. Finally, you can call MakeWidget() on the menu bar builder to get a widget to place.

In the menus that are created, you can add menu headers, entries, separators, submenus, editable text, or custom widgets to the menu that gets created.

Context Menus

To summon one of these menus as a context menu, get the widget generated from an FMenuBuilder, and pass it into the PushMenu() function, as shown here.

Toolbars

To create a toolbar, use an FToolBarBuilder instead. For children, you can add tool bar buttons, combo buttons, plain buttons, and pull down menus.

Item Views

These views take a template argument of a shared pointer to some sort of data. They are populated by a TArray or TSharedPtr's to the data type. Their internal widgets are populated dynamically with the OnGenerateRow or OnGenerateTile delegate passed in, and different widgets are generated for each column.

List Views

List views are widgets which store a list of child widgets. They are made as SListView<...>.

Tree Views

Tree views, made as STreeView<...>, are similar to list views, except that they support parenting widgets to other widgets in the list. To determine which widgets are parented to which, the OnGetChildren delegate is used to pass back the children of the passed in item.

Tile Views

Tile views, made as STileView<...>, are similar to list views, except the child widgets are laid out in a grid rather than a list. Because of this, they do not support columns or column headers.

1. Project Setup

2. Creating a Window Plugin

3. Creating a Slate Widget For the Menu

4. Populating Your Menu With Widgets

5. Binding Events to Interactive Widgets

6. Adding Your Menu to the Window

Final Result

On Your Own

This is a step-by-step guide on how to create a simple editor window that responds to user input using Slate, Unreal Engine's UI framework. This page does not provide a comprehensive guide on how Slate interacts with other systems. Rather, it focuses on the fundamentals of how Slate's syntax relates to the layout of your UI, and the basics of making your UI respond to events.

1. Project Setup

This guide uses a new project called SlateQuickstartGame with the following settings:

Template: Third-Person Project

C++ Project

You can also follow this guide using an existing project. This project does not depend on any specific target platform, as it focuses on editor functionality.

2. Creating a Window Plugin

To get started on your new editor window quickly, open the Edit > Plugins window, then click the + Add button to create a new plugin. Choose Editor Standalone Window as the plugin type, then call it SlateQuickstartWindow. Click Create Plugin to finish.



Click to enlarge image.

This automatically creates the Plugin module with the necessary C++ classes to support a basic editor window. Close the editor and recompile your project, then open the project again. You can find your new editor window under the Window dropdown.



Click to enlarge image.

When you initially view this window, it will display placeholder text but no interactive elements.

Understanding the Window's Code

Before continuing to build your menu, you should review the code in SlateQuickstartWindowModule.cpp for a quick preview of how to use Slate's declarative syntax. The Slate code is contained in the OnSpawnPluginTab function. When you initially view it, the function reads as follows:

This function performs the following steps:

Builds a string called WidgetText using FText::Format to combine several strings.

Defines a new SDockTab using the SNew function. This represents the dockable window.

Fills the SDockTab with an SBox element which can contain content. This box has HAlign and VAlign parameters that align it to the center of the window.

Adds a new STextBlock to the SBox and sets its text to the value of WidgetText.

Returns the SDockTab containing all these UI elements.

The best way to understand how this works is to think of how you would create a similar user interface in UMG. To re-create this in UMG, you would drag a box widget onto the stage as the root UI element, then place a Text widget inside of it and change its alignment to center. The stage and hierarchy would resemble the following image.



Click to enlarge image.

In the case of the SlateQuickstartWindow, the viewport stage is replaced with the SDockTab widget. When you review the code, the square brackets define what elements are nested inside a given widget, while periods set the value of the parameters you would see in the Details panel.

For more information about Slate's declarative syntax, refer to the Slate Overview.

3. Creating a Slate Widget For the Menu

You can add Slate widgets directly to the FSlateQuickstartWindowModule class generated by the Plugin wizard. However, there are some limitations to how you can handle your widgets' callbacks if you do this. Therefore, you should create a dedicated Slate widget to hold the menu's contents, then add that widget to the FSlateQuickstartWindowModule class.

In the Content Drawer, click the C++ Classes folder, then right-click and click New C++ Class.



Click to enlarge image.

In the Add C++ Class window, select Slate Widget, then click Next.

Change your new C++ class's settings as follows:



Click to enlarge image.

Class Type: Public

Name: QuickStartWindowMenu

Module: SlateQuickstartWindow (Editor)

Click Create Class to finish.

Make sure you set the Module drop-down to the SlateQuickstartWindow module before you click Create Class. This adds the class to your plugin's code. If you don't do this, the wizard will put it in your game's code, and your Slate widget will not be visible to the plugin.

The wizard creates a new C++ class called SQuickStartWindowMenu in your plugin's Source folder, then regenerates your project's Visual Studio solution.

4. Populating Your Menu With Widgets

To add Slate widgets to your menu, open SQuickStartWindowMenu.cpp and add them to the Construct function. When you initially view this function, it reads as follows:

Follow these steps to populate the window:

Delete the commented-out code inside the Construct function.

Inside the Construct function, add a new SVerticalBox with the SNew function. Follow that with two +SVerticalBox::Slot() elements. Give both slots the .AutoHeight() property.

Inside the first Vertical Box slot, add a SHorizontalBox with two slots. Give both slots the .VAlign(VAlign_Top) property.

This will nest the horizontal box inside the vertical box, effectively dividing this first slot into two columns.

In the first horizontal slot, add a new STextBlock widget. Set the .Text to FText::FromString("Test Button").

Whenever you display user-facing text, you should use FText instead of FString or other methods of displaying text, as it provides support for localization. For more information, refer to Text Localization.

In the second horizontal slot, add a new SButton widget. Set its .Text to FText::FromString("Press Me").

In the second Vertical Box slot, create another Horizontal Box with two slots. Give the first horizontal slot a STextBlock widget that reads "Test Checkbox", then add a SCheckBox widget to the second horizontal slot.

The full definition of your Slate window should now read as follows:

Save and compile your code, then open your project in Unreal Editor and open your window.

You can't compile Slate windows while Live Coding is active and your project is open in Unreal Editor. Make sure to close Unreal Editor before trying to compile your code.

When you open your window, it should look like this:



Neither the button or the checkbox do anything yet, but you will add functionality to them in the next section.

5. Binding Events to Interactive Widgets

Interactive Slate widgets use events to respond to interactions like clicking or toggling. In this section, you will create several delegates to drive the interaction for the checkbox and button from the previous section.

Open SQuickStartWindowMenu.h and declare the following functions and variables:

The functions will contain the logic that runs when you click the test button and test checkbox. The checkbox will use the IsTestBoxChecked function to determine what state it should display, and bIsTestBoxChecked will cache that state.

In SQuickStartWindowMenu.cpp, provide the following implementations for the checkbox's functions:

These provide a getter and setter for the checkbox's current state. The OnTestCheckboxStateChanged function will set the value of bIsTestBoxChecked depending on what the user changes the checkbox's state to. Meanwhile, the IsTestBoxChecked function will read that variable and translate it back into an ECheckBoxState.

Add the .OnCheckStateChanged parameter to the SCheckBox widget, and provide a reference to the FSlateQuickstartModule::OnTestCheckboxStateChanged function. Then, add the IsChecked parameter, and provide a reference to the SQuickStartWindowMenu::IsTestBoxChecked function.

You now have a mechanism to track when the user checks and unchecks the SCheckBox widget.

Provide the following implementation for the OnTestButtonClicked function:

This function outputs a short message to the output log stating whether the checkbox is checked.

Add the .OnClicked parameter to the SButton, then provide a reference to the SQuickStartWindowMenu::OnTestButtonClicked function.

6. Adding Your Menu to the Window

Finally, you need to add the Slate widget you created to the menu tab's code.

Open SlateQuickstartWindowModule.cpp and delete the contents of the SDockTab. Its code should now read as follows:

Add your SQuickStartWindowMenu widget inside the SDockTab.

Save and compile your code, then open Unreal Editor and test your window.

Final Result

When you click the test button, your console log should print the message "Hello, world! The checkbox is unchecked." If you check the check box, it should print the message "Hello, world! The checkbox is checked." This provides a basic working example of a Slate window which you can expand on to create custom editor windows.

On Your Own

For examples of different Slate widgets and the many ways they can bind delegates, refer to STestSuite.cpp. You can find this in your engine's install directory under Source\Runtime\AppFramework\Private\Widgets\Testing. You can experiment with these widgets to create different layouts and interactive elements. You can also experiment with using Slate UI elements to interact with assets or data in your project, or the World in the level editor.

The Details panel is now fully customizable. You can rearrange properties via a simple system, or you can fully customize them using Slate UI Programming. You can also add other UI to the details using Slate syntax.

Setup instructions

Customizing

Multibox Style Layout

Property Handles

Slate Layout

Customization Dos and Dont's

Advanced Tips

Accessing complicated properties.

Accessing Arrays

Hiding properties

Setup instructions

Create a class for customizing properties in. This must inherit from ILayoutDetails.

You implement one function: void LayoutDetails( IDetailLayoutBuilder& ).

The purpose of this class is to encapsulate customization for a classes properties. One instance of the class will be created for each Details panel that requires it.

Set up a delegate that will be called when the Details panel recognizes properties for a specific class.

The sole purpose of this delegate is to create an instance of your customization class for a specific UObject that has properties. Remember that there often are multiple details views up at any point and each instance of the details view gets its own customization class instance. This allows you to store per detail instance data on your layout class.

Example (more examples are located in DetailCustomizations.cpp):

Implement your customization in the LayoutDetails function of the class you made in step 1.

If this is an engine class, you should add your customization class (if it does not already exist) to the DetailCustomizations module. This module can be recompiled and reloaded without restarting the editor, making it useful for fast tweaking of properties.

Bind your delegate in FDetailCustomizationsModule.StartupModule and unbind it in FDetailCustomizationsModule.ShutdownModule.

Game specific classes should use a game specific module.

See examples in this document and the DetailCustomizations module (such as PrimitiveComponentDetails.cpp and StaticMeshComponentDetails.cpp).

Customizing

You handle all customization inside the LayoutDetails function of your customization class. This function accepts an IDetailLayoutBuilder, which is your interface to properties and how you pass back customization widgets.

The primary function of IDetailLayoutBuilder is to create categories where properties and other details reside. There are some other minor functions on this class which are self explanatory (most of them you will not need). The documentation for those can be found in DetailLayoutBuilder.h.

The first step in customizing is to edit a category:

The EditCategory function takes an FName for the category where properties will reside and an optional localized display name. If the display name is specified, it will override any existing display name. The category name does not have to be the same category name specified in the UPROPERTY macro, although it will reuse the UPROPERTY category if the names are the same. The macro category name is used as the default category if the property is not customized and in the tree view.

EditCategory returns an IDetailCategoryBuilder& which is what you use to add properties to a category. There are a two ways to do this:

Using simple multibox style layout, which is quick for rearranging properties.

Using Slate syntax which offers the most robust customization options.

Multibox Style Layout

An easy example using the LightingCategory created above:

This is the most basic example. It adds 3 properties stacked vertically and overrides their display names. (The text in the examples is not localized to save space, but should always be localized in general practice.)

Note that customized properties and categories always appear above non-customized ones. You can use this simple syntax to reorganize important properties which may otherwise be buried.

The result:



A slightly more advanced example (located in PrimitiveComponentDetails.cpp):

BeginGroup is used to create a new group of properties. It takes a name to display for the group, an optional image name (Slate brush name) to display next to the name, and an optional edit condition property which if false will hide the entire group from view so its properties cannot be changed. These edit conditions are the same as the UPROPERTY macro style edit conditions except they operate on a group of properties instead of just one. More things like this could be added in the future!

AddProperty adds a property using its default look. It usually only needs one parameter which is the property name. More complicated properties such as properties inside structs need additional information. See the Advanced Tips section or the documentation in DetailCategoryBuilder.h if you need this.

BeginLine creates a new line of properties. By default, all properties added via AddProperty are created on a new line. BeginLine ensures all properties added until the next BeginLine or EndLine are on the same line.

The result:



It is not very powerful, but more features will be added as needed. It is currently designed to be for quick reorganization.

The slate layout will require more advanced access to properties, specifically property handles, especially if you need to customize their look.

Property Handles

The two main functions of property handles are to read and write the value of a property and to identify the property to Slate customization widgets. How properties are accessed by the details view/property tree is somewhat complicated, so property handles hide all that away and handles undo/redo, pre/post edit change, package dirtying, world switching etc., for you.

To get a property handle, you must ask the IDetailCategory where you want to customize it for one. You do this by calling IDetailCategory::GetProperty. Usually you simply pass in the name of the property as follows:

Now you have a handle to the bool property bOverrideLightmapRes.

From here, you can read and write the value of that property and/or pass it to a slate widget for customization.

Useful property handle functions (For the complete documented list see PropertyHandle.h):

Function

Description

IPropertyHandle::SetValue(const ValueType& InValue) and IPropertyHandle::GetValue(ValueType& OutValue)

Writes and reads property values. These are overloaded for many built in types (including vectors and rotators). For complicated types like user structs, will need to get a child handle. See the advanced section at the end of this document.

ResetToDefault()

Resets a property to its default.

IsValidHandle()

Returns whether or not you have a valid property handle.

AsArray()

Array property values are special. See the advanced section at the end of this document.

Other notes:

The handle returned from GetProperty may be invalid if the property could not be found or is not going to appear in the details view. Check IsValidHandle() to be sure. Calling functions on invalid handles will not crash.

You should not store property handles outside of your layout class unless they are weak pointers. Internally the data they access is a weak pointer so it will not crash if you try to set or get a value on an invalid property but you have a reference to a useless object if you store it and it is not cleaned up.

If you try to read / write access a value type for an unsupported property (e.g., a float for a String property ), it will fail but no data will be corrupted.

Handling failure cases when accessing values.

Remember that detail views can view multiple objects at once and it is not uncommon for users to select hundreds of Actors at once. In cases like these, you will undoubtedly have multiple values for one property. GetValue and SetValue return an FPropertyAccess::Result to help you determine whether or not accessing a value was successful. FPropertyAccess::MultipleValues will be a common return value.

If you are customizing a low level typed property like an int or float, you must handle the multiple values case somehow.

If MyResult is FPropertyAccess::MultipleValues, MyInteger will not be set. Sending that to a widget that displays it will show garbage value and initializing it before hand is not much better because it is still not the correct value. How this is handled is up to the customizer. For numeric types, using SNumericEntryBox is recommended which allows you to optionally return no value in its value attribute. It will then display a label you provide instead. See SNumericEntryBox.h.

Slate Layout

Slate layout allows you to completely customize the look and arrangement of properties. You pass your layout back to a category via IDetailCategoryBuilder::AddWidget which takes an arbitrary widget from Slate. To assist you in this, there are some customization widgets available to you:

This is the customization widget. You use this widget to customize a property and/or embed the property in other slate declarative syntax. You create an SProperty using SNew but you also provide a handle to the property so it knows what to build. The handle is a non-optional parameter to SNew: SNew( SProperty, HandleToTheProperty )

Example:

The result:



SProperty by default will generate a widget for the property. There are some basic customization attributes on SProperty for customizing the default look (such as the name). If you want to customize a property, you use the CustomWidget slot. Once you use the CustomWidget slot, SProperty no longer knows anything about how to set and get the value since you have made a custom widget. You need to use your property handle to get and set the value.

Example:

SProperty always displays reset to default even if you make a custom widget. There is an argument on the SProperty which toggles this behavior. For example, if you have a row of properties, you may want to tell it not to display a reset to default for each one but make a big menu at the end. See SResetToDefaultMenu below.

If you pass an invalid handle to SProperty, it will simply not show up.

In addition to SProperty there are some other customization widgets that can be used.

SAssetProperty is an SProperty that displays a thumbnail of the asset as well as an entry box for changing the asset. You can change the size of the thumbnail as well. You can use this on UObject properties that have renderable thumbnails. If you use this on other types, it will not display anything.



SFilterableDetail is a widget that does not draw anything but filters everything in its content slot when a user types in the search box of the details view. This widget is useful for non-property based details. SProperty is already filtered so you do not need to set up an SFilterableDetail for those unless you want to group their filtering.

SResetToDefaultMenu is a menu which displays the yellow reset to default arrow. By default, SProperty adds a reset to default menu, but sometimes it makes sense to group more than one property into the same menu. (e.g Vector properties). You can add SProperty widgets to an SResetToDefaultMenu to handle this for you. Simply call AddProperty on SResetToDefaultMenu and then place the menu in any declarative syntax!

This widget allows you to customize an array of properties. You create one just like SProperty and also hook up a delegate which is called each time a widget for an array element is needed.

Example:

The result:



Customization Dos and Dont's

Do check error cases when customizing properties and reading/writing values. Remember that details views can often be viewing multiple objects at once where each object has different values. Customized properties should be able to handle the common case of multiple values.

Do store any data about the selection on your customization class. Some non-property details will need the selected Actors for a customization. You can get the selected Actors from IDetailLayoutBuilder. You can store this selection set or anything selection sensitive on your customization class. It is guaranteed to be around while the selection remains the same in its details view.

Do not use FActorIterator, FSelectedActorIterator, or GEditor->GetSelectedActorIterator. Remember that the Details panel can be locked and these things operate on global selection sets or lists of Actors which is not the same as the selected Actors in a Details panel if it is locked! Using these will access different data. You can get the list of selected Actors valid for you from IDetailLayoutBuilder.

Do not hold a strong reference to your layout class or property handles (you should not need to anyway). Remember that details views (especially level editor ones) can change at any time based on user selection so any references you have to layout classes can easily become invalid. The shared pointers to layout classes are checked for uniqueness when customizing details to prevent this from happening.

Advanced Tips

Accessing complicated properties.

A complicated property is defined as anything that cannot be resolved with just a property name. Usually this involves properties inside structs.

There are two ways to access complicated properties:

Functions that return a property handle or add a property to a category take optional parameters for resolving properties.

Example:

Parameter

Description

Path

The path to the property. Can be just a name of the property or a path in the format outer.outer.value[optional_index_for_static_arrays].

ClassOutermost

Optional outer class if accessing a property outside of the current class being customized.

InstanceName

Optional instance name if multiple UProperty's of the same type exist (Such as two identical structs, the instance name is one of the struct variable names).

Examples:

To access StaticArray at index 2 from Struct2 in MyActor, your path would be "MyStruct.StaticArray[2]" and your instance name is "Struct2".

To access the same StaticArray outside of MyActor customization functions you would do the same as above but ClassOutermost would be MyActor::StaticClass().

To access MyFloat in MyActor you can just pass in "MyFloat" because the name of the property is unambiguous.

If you have a property handle, you can get a child property handle by name from it:

Parameter

Description

ChildName

The property name of the child. This will recurse until found. Paths are not supported and children of arrays cannot be accessed in this way.

Accessing Arrays

You can access arrays via IPropertyHandle::AsArray. If the property handle is an array, this will return an IPropertyHandleArray which has functions for adding, removing, inserting, duplicating, and getting the number of elements of an array.

Hiding properties

You can hide properties altogether by calling IDetailLayoutBuilder::HideProperty. It takes either a name/path or a property handle.

Project Setup

Displaying Widgets

Accessing the Game Viewport

Adding the Widget to the Viewport

Removing Widgets from the Viewport

You can use Slate widgets to create Heads Up Displays (HUDs) or other User Interface (UI) elements, such as menus. These UI consist of one or more container widgets, each of which may be hold several other types of widgets that are responsible for a particular aspect of the UI.

For example, you may have a single overall widget for your game's HUD, as well as widgets for the main menu, options menu, pause menu, scoreboard, and so on. Each of these widgets would then be made up of a combination of other custom widgets, labels, text boxes, images, and other types of elements.

Each of these container widgets can then be added or removed to the user's Viewport depending on the circumstances in the game:

When the game starts, it adds a main menu widget to the viewport.

When the user chooses one of the options in the menu, the main menu widget would then be removed from the viewport.

If the option opens another menu, the new menu is added to the viewport.

If the player pauses the game at any point, the pause menu widget would be added to the viewport.

When the game is resumed, the pause menu widget is removed from the viewport.

When the HUD for the player is initialized, the HUD widget would be added to the viewport.

Project Setup

In order to use the Slate User Interface (UI) Framework, your project must be set up properly so that it is aware of the

This allows you to include the Slate.h header and reference the various elements of the framework necessary for building a UI with slate.

Module Dependencies

The Slate framework is stored in a few modules. In order to make your project aware of these, some dependencies must be set up in the *.build.cs file for your project.

The modules your project needs access to are:

Module

Dependency Type

InputCore

Public

Slate

Private

SlateCore

Private

To set up the Slate module dependencies:

Open the [ProjectName].build.cs file for your project. It is located in the [ProjectDir]/[ProjectName]/Source/[ProjectName] directory.

Add the InputCore public dependency by adding "InputCore" to the PublicDependencyModuleNames.

The InputCore module is set as a public dependency by default when code projects are created.

Add Slate and SlateCore private dependencies. A line exists in the *.build.cs file for adding private dependencies:

Add the SlateCore and Slate modules to that line:

Depending on when you created your project, and with what version of the engine, it may already have the Slate dependencies set up in the *.build.cs files but commented out. You can uncomment the appropriate lines to set up the dependencies.

Displaying Widgets

To display a Slate widget in your game, You must add it to the game's viewport. Overlaid widgets are ordered according to the Z-order specified when adding them, with larger Z-order values appearing on top of smaller Z-orders.

Accessing the Game Viewport

The game's viewport is an instance of the GameViewportClient class. You can access a reference to the current game viewport using the GameViewport member of UEngine, which can be accessed using the GEngine global pointer to the current UEngine instance for the game.

For example:

GEngine and GameViewport can be NULL so you should always check their values before trying to access them or any of their members.

Adding the Widget to the Viewport

Slate widgets are added to the viewport by passing a reference (a TSharedref<SWidget>) to the widget to GameViewportClient::AddViewportWidgetContent(). This function takes in both a widget and a Z-order, which determines the sorting order for the new widget as mentioned previously. The Z-order is optional, however, and defaults to a value of 0.

The reference to the widget you want to add to the viewport can be stored as a member of some class, such as your HUD, or it can be created and passed in at the time of calling the function.

Passing a reference to a widget stored in a member variable (as a TSharedPtr):

Creating the widget using SNew() when passing it to GameViewportClient::AddViewportWidgetContent():

Or using SAssignNew() to create it, assign it to a TSharedPtr member, and pass it in:

Removing Widgets from the Viewport

You can remove Slate widgets from the viewport individually by passing a reference to a previously added widget to GameViewportClient::RemoveViewportWidgetContent().

For example:

In addition, you can remove all widgets from the viewport at once by calling GameViewportClient::RemoveAllViewportWidgets()

For example:

GEngine and GameViewport can be NULL so you should always check their values before trying to access them or any of their members.



Invalidation Box



In order to understand and use the content on this page, make sure you are familiar with the following topics:

Playing and Simulating

Slate Overview

SlateDebugger

Event Commands

Invalidate Commands

Paint Commands

Update Commands

While developing the user-interface (UI) for applications, UI developers sometimes need to debug Slate, which is where the Console Slate Debugger can help. Console Slate Debugger hooks into the available systems in FSlateDebugging to print internal Slate data. Additionally, as the UI focus changes (or attempts to change), developers will need to know what system is handling those focus updates.



Console Slate Debugger



Extensions for Console Slate Debugger include the following:

GlobalInvalidation, which helps to identify the widgets responsible for a costly frame.

A paint option that displays widgets that were painted in a given frame.

An additional routing option to see how the system chooses a widget as the event handler.

Additional filter and event console commands.

This page's screenshots are taken from the Lyra Sample Game project. To test SlateDebugger commands in Lyra, use the command Slate.EnableGlobalInvalidation 1 to enable



SlateDebugger

While running the project in PIE mode, press the tilde (~) key to open the PIE Console, and type SlateDebugger.





SlateDebugger logs are typically written to a [ProjectName].txt log file under [ProjectName]/Saved/Logs.

Event Commands

Slate Debugger offers a lot of different commands to pinpoint specific information like enabling or disabling specific logs and filtering events. If more information is needed CaptureStack can also provide the call stack of the triggered event.

SlateDebugger.Event

Command Description

Start

Alias for SlateDebugger.Event.Start that starts the Slate Console Debugger.

Stop

Alias for SlateDebugger.Event.Stop that stops the Slate Console Debugger.

SetInputFilter

Enables or disables specific input filters.

SetFocusFilter

Enables or disables specific focus filters.

LogWarning

Logs warning events.

LogInputEvent

Logs input events.

LogFocusEvent

Logs focus events.

LogExecuteNavigationEvent

Logs execute navigation events.

LogCaptureStateChangeEvent

Logs cursor state change events.

LogCursorChangeEvent

Logs cursosr change events.

LogAttemptNavigationEvent

Logs attempt navigation events.

InputRoutingModeEnabled

If enabled, outputs the route taken by an input event.

EnableAllInputFilters

Enables all input filters.

DisableAllInputFilters

Disables all input filters.

EnableAllFocusFilters

Enables all focus filters.

DisableAllFocusFilters

Disables all focus filters.

CaptureStack

If enabled, captures the stack when there are events.

Invalidate Commands

These commands allow you to use the Invalidate command to show on-screen widgets that are invalidated. Each invalidated widget will be highlighted in different colors based on the type of invalidation.



SlateDebugger.Invalidate displays the state of each widget during the invalidation process.



SlateDebugger.Invalidate

Command Description

Enable

Starts the Invalidation Widget debug tool and display when widgets invalidate or stop the Invalidation Widget debug tool, depending on the current status.

Start

Starts the Invalidation Widget debug tool and displays when widgets invalidate.

Stop

Stops the Invalidation Widget debug tool.

SetInvalidateRootReasonFilter

SetInvalidateRootReasonFinder [None][ChildOrder][Root][ScreenPosition][Any]

SetInvalidateWidgetReasonFilter

SetInvalidateWidgetReasonFinder [None][ChildOrder][Root][ScreenPosition][Any][None][Layout][Paint][Volatility][ChildOrder][RenderTransform][Visibility][Any]

ToggleLegend

Displays the color legend.

ToggleLogInvalidateWidget

Logs the invalidated widget to the console.

ToggleWidgetNameList

Displays the name of the invalidated widget.

Paint Commands

This command is used to highlight widgets that are painted in each frame. This can be useful to identify widgets that are painted even if they did not change. Note that volatile widgets are painted every frame.



SlateDebugger.Paint displays which widgets are re-drawing on the screen.



SlateDebugger.Paint

Command Description

Enable

Starts the Paint Widget debug tool and display when widgets paint or stop the Paint Widget debug tool, depending on the current status.

Start

Starts the Paint Widget debug tool and displays when widgets paint.

Stop

Stops the Paint Widget debug tool.

LogOnce

Logs the widgets that paint once during the last update

LogWarningIfWidgetIsPaintedMoreThanOnce

Logs a warning if a widget paints more than once in the same frame.

MaxNumberOfWidgetDisplayedInList

Displays the maximum number of widgets that will display when DisplayWidgetNameList is active.

ToggleWidgetNameList

Displays painted widget names.

Update Commands

This command is used to highlight widgets that are updated more often than needed. Since Widget Update can be overridden or executed in Blueprint, it is a common source of poor performance if the widget code was not designed correctly.



SlateDebugger.Update displays which widgets are updating with color coded information. This image is set to filter for only Repaint events, which use yellow.



SlateDebugger.Update

Command Description

Enable

Starts the Update Widget debug tool and displays when widgets update, or stops the Update Widget debug tool, depending on the current status.

Start

Starts the Update Widget debug tool and display when widgets update.

Stop

Stops the Update Widget debug tool.

SetInvalidationRootIdFilter

Only display widgets that are part of an invalidation root.

SetWidgetUpdateFlagsFilter

SetWidgetUpdateFlagsFilter [None][Tick][ActiveTimer][Repaint][VolatilePaint][Any]

ToggleLegend

Displays the color legend.

ToggleUpdateFromPaint

Displays widgets that do not have an update flag but which are still updated as a side effect of another widget.

ToggleWidgetNameList

Displays the names of Update Widgets.

Console Slate Debugger

Widget Type Reference

Get Started

User Interface

Demo Mode

Atlases

Texture Atlas

Font Atlas

Window

Application Scale

Flags

Show Clipping

Debug Culling

Widget Caching

Widget Hierarchy

Pick Painted Widgets

Hit Test Grid

Show Focus

Snapshot Widget Picker

Widget Events

The Unreal Editor's UI was built using the Slate UI framework, and the Widget Reflector tool enables developers to identify the Slate API being used to render the different Widgets for the toolset.



Widget Reflector running in Unreal Editor.



Widget Reflector is built-into the editor by default, and if you are a developer wanting to optimize and debug your project's UI, keep reading to get started.

Get Started

To open Widget Reflector while the editor is running, select Tools > Debug > Widget Reflector. Alternatively, type Ctrl+Shift+W or enter WidgetReflector into the console to open the tool.



Widget Reflector is available in the editor and as a standalone application.



User Interface

When using the tool for the first time, the following interface is displayed.





Click for full image.



Area

Description

1

The main menu area, featuring demo modes, atlases, and windows.

2

The application scale and Slate Debug Options area.

3

The Widget Hierarchy area enables users to visualize Widget hierarchies, foreground visibility, and focus, clipping, source, and address information. Additionally, users can take and load snapshots of their Unreal application from here.

4

The tab menu area, which enables users to visualize and debug snapshot Widgets, Widget Events, and Hit Test Grids.

5

The Widget Details area.

Demo Mode

Demo Mode Options

Usage

Mouse Click

Enabling this option allows users to demonstrate mouse click events, ideal for visualizing cursor events for demonstrations or recording presentations.

Key

Enabling this option allows users to demonstrate keypress events, ideal for visualizing key presses for demonstration or recording presentations.

Atlases

Atlases Options

Usage

Display Texture Atlases

Selecting this option opens a NxN atlas of textures.

Display Font Atlases

Selecting this option opens a NxN atlas of fonts.





Window

Window Options

Usage

Slate Debug Options

Console Slate Debugger

Widget Hierarchy

The Widget Hierarchy displays the parents and children of widgets, including whether those widgets are visible or in focus. Users can also Pick Hit-Testable widgets, enable UMG root as a hierarchy filter, take or load snapshots of the application's UI, and if available, point to the Slate source code for the widget.

Sanpshot Widget Picker

After taking a snapshot from the Widget Hierarchy area, the application's UI snapshot displays in the Snapshot Widget Picker tab.

Widget Details

When available, additional widget details appear in this area. Users may optionally dock other menus in this area.

Widget Events

Filtered events, such as focus, input, navigation, bab, warnings, or mouse capture events appear in the Widget Events area.

Hit Test Grid

When debugging hit tests, navigation and event information will appear in the Hit Test Grid tab.

Application Scale

To change your application's scale for presentations, screenshots, or debugging purposes, either enter a new value or use the slider belonging to Widget Reflector's Application Scale.







Adjusting the application's scale.



Flags







Adjusting the application's scale.



To begin debugging your application's UI, set any of the following Flags.

Invalidation Debugging

Invalidation Root Debugging

Update Debugging

Paint Debugging

Slate Debugger Console Reference

Show Clipping

The Show Clipping flag displays how a widget was clipped. For example, this flag is useful for identifying when a big widget is clipped by a smaller panel.

Debug Culling

Debug Culling provides a way for developers to debug when a widget is culled by another widget, such as a panel.

Widget Caching

The InvalidationBox caching system enables Widget Caching, and it is always disabled when in GlobalInvalidation mode.

Widget Hierarchy

To inspect hierarchical information about your widgets, you can either Pick Painted Widgets, Pick Hit-Testable Widgets, or Show Focus widgets.

Pick Painted Widgets

To Pick Painted Widgets, perform the following steps:

From the Widget Hierarchy area, select Pick Painted Widgets.



Move the mouse cursor over your application's UI until you find the widget you want to inspect.





Hit the escape key to mantain focus on the widget you want to inspect.



From the Widget Hierarchy area, you can inspect the following properties.

Property

Property

Description

Widget Name

This is the widget's name, and it can reveal if you or one of your UI developers named a widget incorrectly.

FG Visibility

Foreground (FG) visibility is used to help determine if a widget should be visible in the foreground or not.

Focus?

This is useful to help determine if a widget should be in focus.

Clipping

This property helps identify if a widget is being clipped.

Source

This is a link to the source code, and it is the location where the widget was creative. When your application is connected to an IDE (such as a C++ debugger), you can click the hyperlink to open the file at the correct location.

Address

Knowing a widget's address is useful when setting a conditional breakpoint in the C++ debugger.

Hit Test Grid

The Hit Test Grid is useful for developers wanting to visualize and inspect a widget's hitbox. To use this feature, perform the following steps.

Select Pick Hit-Testable Widgets.



Hover the mouse cursor over the widget you want to hit, and press the ESC key to retain focus over the widget.

In addition to the available options in the Hit Test Grid feature, the following flags may be set.

Flag

Description

Visualize on Navigation

This setting is only available when performing a Snapshot, and it enables the Hit Test Grid feature to pick the widget inside the Widget Reflector.

Reject Widget Reflector navigation events

This setting tells the Hit Test Grid feature to reject navigation events originating from the Widget Reflector.

Show Focus

If you want to show the widget that has focus, perform these steps:

Select Show Focus.



Select the widget with your mouse cursor, and press the ESC key to retain focus over the widget.

Snapshot Widget Picker

Snapshot Widget Picker saves an image and the current state of all widgets in the application. To take a snapshot of the application's UI, perform the following steps.

In the Widget Hierarchy area, click Options.

Enable Navigation Event Simulation.





This option enables developers to simulate navigation events for widgets captured by the snapshot. Also, this setting is optional, and it should only be enabled when necessary.



Select the application to snapshot.



Click Take Snapshot.





From here, users can use Hit Test Grid from the snapshot, and the result will display in the Widget Hierarchy panel. The snapshot saves the state of the application's UI to help developers identify bugs that need to be fixed. Additionally, developers can debug your UI and simulate your application's navigation events from the Snapshot area.



Snapshots can only be taken from the editor's PIE mode and from a Standalone application.



Widget Events

The Widget Events system flushes messages to an output log in the Widget Reflector while the user navigates over the UI.

Active Timers

Common Use Cases

FCurveSequence and Active Timers

Testing Slate Sleeping

Slate is an "immediate mode" UI framework, meaning it redraws the entire UI each frame. This is great for very dynamic interfaces that are rich with graphics and animations, but results in unnecessary processor usage when nothing in the UI needs to change. Using the Active Timer system in Slate allows it to enter a Sleep state when no UI needs to update. The Active Timer feature should be utilized when working on editor UI, but not when working on UI for a game with a real-time viewport.

Slate sleeps whenever both of the following are true for a given frame:

There is no user action, and

No active timer need to execute

A user action is any mouse movement, click, or key press.

The following diagram illustrates how the Slate application now ticks each frame:



This diagram shows how the editor's processor time changes once Slate sleeping is implemented.



Active Timers

An active timer is a delegate function explicitly registered by a widget that causes a Slate tick/paint pass upon execution, even in the absence of user action (thus the "active" nature of the timer). Active timers will continue to execute indefinitely at the frequency determined by their execution period until unregistered.

The original Tick() function is still present as a "passive" tick. It will be called by Slate as before, but only when Slate is awake. At some point in the future, it may be renamed to PassiveTick() while Tick() is deprecated to more clearly reflect this.

To register an active timer:

Define a function with the following signature:EActiveTimerReturnType Foo(double InCurrentTime, float InDeltaTime)

Bind it to an FWidgetActiveTimerDelegate.

Pass the delegate and the time period between timer executions (0 to call every frame) to SWidget::RegisterActiveTimer().

There are three methods that can be used to unregister an active timer.

Return EActiveTimerReturnType::Stop from the delegate.

Pass the FActiveTimerHandle that was returned by SWidget::RegisterActiveTimer() to SWidget::UnRegisterActiveTick().

Destroy the widget that the active timer is registered under.

Currently active timers are an all-or-nothing situation, so if a single active timer needs to execute, all of Slate will be ticked. Furthermore, there is no limit to the number of active timers a widget can have registered concurrently. This can be extremely useful, but also introduces the possibility of duplicate registrations. To prevent them, track registration status in one of the following ways:

Keep a flag in the widget to track whether the active timer is registered.

Search for bIsActiveTimerRegistered in the UE4 codebase for examples.

Store a weak pointer to the FActiveTimerHandle returned by RegisterActiveTimer() and only register when it's invalid.

Search for TWeakPtr<FActiveTimerHandle> ActiveTimerHandle in the UE4 codebase for examples.

To save memory, only use this method if the active timer ever needs to be explicitly unregistered.

Common Use Cases

For the following common use cases, here are some suggested active timer setups:

When triggering some action:

Register an active timer w/ period 0 that always returns EActiveTimerReturnType::Stop.

When performing some sort of animation or interpolation that is not controlled by an FCurveSequence:

When inertial scrolling begins, register an active timer with period 0 to update the scroll each frame.

Until the destination is reached, return EActiveTimerReturnType::Continue.

Upon reaching the target destination, return EActiveTimerReturnType::Stop to unregister.

An example of this is inertial scrolling; see SScrollBox for an example.

When taking action after a delay, like opening a different sub-menu, or docking a tab:

Register with a positive non-zero delay

The period on an active timer cannot be changed once registered. To "reset" the delay before execution, the active timer must be explicitly unregistered and re-registered.

When performing an action periodically and indefinitely:

Register with a positive non-zero period and just keep returning EActiveTimerReturnType::Continue.

FCurveSequence and Active Timers

The API of FCurveSequence has been updated to simplify the process of registering active ticks when a widget is being animated. Playing the sequence now requires a reference to the widget that will be animated by it. An empty active tick is automatically registered on behalf of the passed widget for the duration of the sequence playback. Whether the sequence should loop is now specified when playing the sequence. However, doing so will register the active tick indefinitely, so use it with caution. Whether looping or not, the active tick will unregister when calling Pause(), JumpToStart(), or JumpToEnd().

Testing Slate Sleeping

There are two console variables related to Slate sleeping:

Slate.AllowSlateToSleep controls whether Slate can ever enter a sleep state. It is currently enabled by default.

Slate.SleepBufferPostInput specifies some amount of time following the last user action that Slate will continue to stay awake. It defaults to 0. This should only be used for debugging, as it may not be a permanent feature of the sleep system.

Since the goal is to make Slate that can sleep indistinguishable from Slate that never sleeps, it can be hard to tell if Slate is sleeping. Currently, the best way to monitor this is to show the editor frame rate (Editor Settings->Miscellaneous->Show Frame Rate and Memory). When it freezes, Slate is sleeping.

Text To Speech Plugin

Screen Reader Plugin

Slate Screen Reader Plugin

Choosing Which Plugin to Use

Enabling the Plugins

Visual interfaces can pose significant barriers for people who find it hard to see them. There are a number of strategies you can use to make your interfaces more accessible, including size and contrast, but there's one in particular that is essential for people with no vision: text-to-speech.

This means the visual information about your interfaces is communicated by synthesized speech, ideally covering both the text within the interface and also information about types of interface element and what state they're in.

This functionality is standard in other industries and rapidly spreading in game development. It is useful for blind gamers, gamers with low vision (e.g. wanting to save their eye strain for gameplay), and people with some cognitive conditions, and can help to meet some areas of CVAA compliance too.

CVAA is accessibility legislation that applies to all games for sale in the USA that have voice, text, and/or video chat functionality.

To learn more about the legal requirements of CVAA, refer to the Demystifying CVAA page on the IGDA Game Accessibility SIG (IGDA-GASIG) website.

Unreal Engine 5 provides three plugins to assist developers in complying with CVAA requirements for blind users. These plugins are:

Text To Speech

Screen Reader

Slate Screen Reader

Text To Speech Plugin

Text to speech (TTS) is a software technology that is used to provide auditory output in the form of a digital, synthesized, spoken voice. An example of TTS is a GPS device where the digital voice calls out directions when navigating to a destination. Another example is a smart assistant on your phone who reads out answers to you .

Unreal Engine's Text To Speech plugin provides basic functionality that supports accessibility for blind users by vocalizing text strings in your project. For example, you can use this plugin to read out the label, type and of an interface element (for example, "volume, slider, 30%"), or to vocalize the incoming messages in a text chat for an online game.

Currently, the TTS plugin only supports English across all platforms. We plan to support additional languages in the future.

Screen Reader Plugin

A screen reader is a piece of assistive technology that helps blind users interact with a software application. It conveys visual information on screen, such as text or images, using non-visual means such as text to speech or Braille. It also offers blind users alternative means of interacting with user interface (UI) elements on-screen. For example, instead of using a mouse, a blind user can use special key combinations on a keyboard to change the focused object on the screen.

Screen readers can simulate actions that could be difficult for a blind user to do, such as right-clicking a UI element or scrolling the mouse wheel while inside the bounds of a UI element.

Unreal Engine's Screen Reader plugin takes text to speech functionality and expands it to provide a richer set of features. It offers a base framework that you can use to implement your own custom screen reader solution.

Features of this plugin include:

Requests for text to be vocalized via TTS.

Queueing a series of accessible announcements to be vocalized via TTS.

Requesting the contents of accessible UI elements be vocalized to the user.

When this plugin is enabled, the Text To Speech plugin is automatically enabled as well.

If you are using Slate to implement your UI, consider using the Slate Screen Reader plugin instead.

Slate Screen Reader Plugin

The Slate Screen Reader plugin is built on the base framework provided by the Screen Reader plugin. You can refer to this plugin as a sample for how to implement a screen reader for your own custom UI solution, or use it as-is if you are using Slate to implement your UI.

The goal of the plugin is to be "plug-and-play" for accessibility. When the plugin is enabled, all currently supported accessible Slate and UMG UI elements will have their contents vocalized when a user focuses on a UI element.

When this plugin is enabled, the Text to Speech and Screen Reader plugins are automatically enabled.

The plugin currently supports the following types of widgets:

Button

Check box

Combo box

Hyperlink

Image

Layout

Scroll bar

Slider

Text

Text (editable)

Window

List

List item

Unknown

Choosing Which Plugin to Use

Use the information below to choose the right accessibility plugin for your project.

If you use a simple UI that doesn't require complex user interaction, consider the Text To Speech plugin as a lightweight solution to provide basic accessibility for blind users.

If you use Slate as your UI solution, use the Slate Screen Reader plugin.

If you use a UI solution other than Slate, you may need to implement your own custom screen reader. Use the Screen Reader plugin as a base framework for this.

You can refer to the Slate Screen Reader plugin for a sample implementation to guide your own custom screen reader development.

Enabling the Plugins

You can enable all three plugins from the main menu (Edit > Plugins). If you need more information about how to enable plugins, refer to the Working with Plugins page.

Before you can enable the Screen Reader and Slate Screen Reader plugins, you need to enable accessibility features for your project and / or Unreal Engine installation.

The steps to do this are the same, but the configuration file you need to edit are different based on whether you want to enable accessibility features for one specific project or for all of UE:

Project only: Open the Config\DefaultEngine.ini file.

All of UE: Go to the C:\Program Files\Epic Games\UE_[Version]\Engine\Config folder, then open either BaseEditorSettings.ini or BaseEngine.ini.

Add the following line to the .ini file you opened:

Accessibility.Enable=1

Save and close the file. If Unreal Engine is running, you may have to restart it before your changes take effect.

Required Knowledge and Setup

Create a New Widget Blueprint

Add Your Widget to the Level Blueprint

Add Text to Speech Strings

Test your Widget

This guide describes how to create and enable a simple Text To Speech widget with two buttons. Each button vocalizes a text string when a user clicks it.

Required Knowledge and Setup

Before you can complete the steps outlined on this page:

Make sure you're familiar with the basic principles of the Unreal Motion Graphics (UMG) UI Editor.

Create a new Unreal Engine project. You can use any template you like.

Enable the Text To Speech plugin for your project. If you need more help with completing this step, refer to the Working with Plugins page.

Create a New Widget Blueprint

In this step, you will create a widget that displays on-screen.

In the Content Browser or Content Drawer, right-click an empty area. In the context menu, select User Interface > Widget Blueprint.



Select the User Widget class, then click Select to create your widget.



Name your new widget MyWidget.

Double-click the Widget Blueprint to open it in the Widget Editor, then create a simple layout with two buttons, as shown below. The size and placement of the buttons is not important for the purpose of this tutorial, as long as you can click them easily.



Compile and Save your Widget, then minimize the Widget Editor.

Add Your Widget to the Level Blueprint

Next, add your widget to the Level Blueprint so that it will be drawn on-screen when the game starts.

From the Main Toolbar, open the Level Blueprint.



In the Level Blueprint, drag from the Event BeginPlay node's execute pin. Search for and select Create Widget, then press the Enter key to create the node.





Drag from the Create Widget node's execute pin and create an Add to Viewport node.



Drag from the Add to Viewport node's execute pin and create a Set Input Mode UI Only node.



This node tells your Widget the only game element that responds to player input is the UI. Any other input from the user will not translate to gameplay actions, even if an action is bound to that control.

Right-click in a free area of the Blueprint Editor and create a Get Player Controller node.



Connect the Return Value pin of the Construct Widget node you created in step 2 to the following pins:

Target on the Add to Viewport node.

In Widget to Focus on the Set Input Mode UI Only node.

Connect the Return Value pin of the Get Player Controller node you created in step 5 to the Player Controller pin on the Set Input Mode UI Only node.

At this stage, your Level Blueprint should look like the image below.



Drag from the Return Value pin of the Get Player Controller node and create a Set Show Mouse Cursor node. Enable the Show Mouse Cursor checkbox for this node.

Connect the Set Input Mode UI Only node output pin to the Set Show Mouse Cursor node input pin.



Set the Class value of the Create Widget node to the MyWidget widget you created in the previous section.



Compile and Save your Blueprint.

Your finished Level Blueprint should look like this:



Click the image for full size.

You can now close the Level Blueprint.

Add Text to Speech Strings

Next, create a channel for each button to "speak" on, and enter the text strings that will be vocalized.

Return to the Widget Editor for your widget. If you closed it, double-click the MyWidget widget in the Content Browser to open it again.

Click one of the buttons you created. Then, in the Details panel on the right, scroll down to Events and click (+) plus to add a new On Clicked event.



This action will open the Widget's Graph and create a new On Clicked node for this button.

Right-click in the graph and create a new Get TextToSpeechEngineSubsystem node.



If you can't see this node, make sure that the Text To Speech plugin is enabled for your project.

Drag from the Text to Speech Engine Subsystem node and create a new Add Default Channel node. Connect the On Clicked event to the Add Default Channel node input pin.



In the Add Default Channel node, right-click the New Channel ID property and select Promote to Variable from the context menu.



In the Details panel on the right, using the Variable Name property, name the variable Channel One.



Drag again from the Text to Speech Engine Subsystem node and create a new Activate Channel node. Connect the Add Default Channel node output pin to the Activate Channel node input pin.



Connect the Channel One variable you created in step 4 to the Channel ID pin on the Activate Channel node.

At this stage, your Blueprint should look like this:



Click the image for full size.

Drag again from the Text to Speech Engine Subsystem node and create a new Speak on Channel node. Connect the Activate Channel node output pin to the Speak on Channel node input pin.



Connect the Channel One variable you created in step 4 to the Channel ID pin on the Activate Channel node.

Drag from the String to Speak pin on the Speak on Channel node and create a new To String (Text) node.



Drag from the input pin of the to String (Text) node you created in the previous step and create a new Format Text node.



In the Format box of the Format Text node, enter the text you want to be spoken.



Repeat steps 1-12 above for the second button you created, changing Channel One to Channel Two where appropriate.

You can click and drag to select multiple Blueprint nodes, then copy and paste them. This reduces the need for manual step duplication.

Compile and Save the Blueprint.

Your finished Widget Blueprint should now look like this:



Click the image for full size.

Test your Widget

Now, it's time to test your widget.

In the Level Viewport, on the Main toolbar, click the Play button to enter Play in Editor mode.



You should now see your widget drawn inside the viewport. Click a button to hear its string vocalized.



Starting Out

Essentials

Behavior Trees assets in Unreal Engine 5 (Unreal Engine) can be used to create artificial intelligence (AI) for non-player characters in your projects. While the Behavior Tree asset is used to execute branches containing logic, to determine which branches should be executed, the Behavior Tree relies on another asset called a Blackboard which serves as the "brain" for a Behavior Tree.

The Blackboard contains several user-defined Keys that hold information used by the Behavior Tree to make decisions. For example, you could have a Boolean Key called Is Light On which the Behavior Tree can reference to see if the value has changed. If the value is true, it could execute a branch that causes a roach to flee. If it is false, it could execute a different branch where the roach maybe moves randomly around the environment. Behavior Trees can be as simplistic as the roach example given, or as complex as simulating another human player in a multiplayer game that finds cover, shoots at players, and looks for item pickups.

If you are new to Behavior Trees in Unreal Engine, it is recommended that you go through the Behavior Tree Quick Start guide to quickly get an AI character up and running. If you are already familiar with the concept of Behavior Trees from other applications, you may want to check out the Essentials section which contains an overview of how Behavior Trees work in Unreal Engine, a User Guide to working with Behavior Trees and Blackboards, as well as reference pages for the different types of nodes available within Behavior Trees.

Starting Out



This guide shows how to use Behaviour Trees to set up an AI character that will patrol or chase a player.

Essentials



Describes the concepts behind Behavior Trees in Unreal Engine and how they differ from traditional Behavior Trees.



Describes how to create and edit Behavior Trees and Behavior Tree related assets.



Outlines the different types of nodes available when working in the Behavior Tree Editor.

1 - Required Project Setup

2 - Blackboard Setup

3 - Behavior Tree Layout

4 - Task Setup - Chase Player

5 - Task Setup - Find Random Patrol

6 - AI Controller Setup

7 - Decorator and Final Setup

8 - Own Your Own!

In the Behavior Tree Quick Start Guide, you will learn how to create an enemy AI that responds to seeing the Player and proceeds to chase them. When losing sight of the Player, after a few seconds (which can be adjusted based on your preference), the AI will give up chasing and randomly move around the environment until seeing the Player again as seen in the example video below.

By the end of this guide, you will have an understanding of the following systems:

Blueprint Visual Scripting

AI Controllers

Blackboards

Behavior Trees

Behavior Tree Services

Behavior Tree Decorators

Behavior Tree Tasks

1 - Required Project Setup

In this first step, we set up our project with the assets we'll need for our AI character to get around the environment.

For this guide, we are using a new Blueprint Third Person Template project.

Open the Content Drawer, then right-click on the ThirdPerson folder and create a New Folder called AI.



In the ThirdPerson > Blueprints folder, drag the BP_ThirdPersonCharacter onto the AI folder and select Copy Here.



In the AI folder, create a new Blueprint Class based on the AIController class.



Name the AIController Blueprint Enemy_Controller and the BP_ThirdPersonCharacter Blueprint Enemy_Character.



Open Enemy_Character, then delete all the script from the graph.

Select the Character Movement component then set Max Walk Speed in the Details panel to 120.0.



Click image for full view.

This reduces the speed of our AI Character's movement around the environment when patrolling and not chasing the Player.

Select Class Defaults from the Toolbar, then in the Details panel, assign the Enemy_Controller as the AI Controller Class.



Click image for full view.

We are going to place our AI in the world. If you spawn the AI after the world is loaded, change the Auto Possess AI setting to Spawned.

From the Content Drawer, drag the Enemy_Character into the Level.

From the Place Actors panel, drag a NavMeshBoundsVolume into the Level.



With the NavMeshBoundsVolume selected, press R and scale the volume to encapsulate the entire Level.



This will generate a Navigation Mesh that enables our AI character to move around the environment. You can press the P key to toggle the display of the NavMesh in the Viewport (green areas indicate possible navigation locations).

During gameplay, you can use the Show Navigation console command to toggle the display of the NavMesh on/off.

Our project setup is complete, in the next step we will set up our Blackboard asset.

2 - Blackboard Setup

In this step, we create our Blackboard asset, which is essentially the brain of our AI. Anything we want our AI to know about will have a Blackboard Key that we can reference. We'll create keys for keeping track of the Player, whether or not the AI has a line of sight to the Player, and a location where the AI can move to when it is not chasing the Player.

In the Content Drawer, click +Add and under Artificial Intelligence, select Blackboard and call it BB_Enemy.



Inside the BB_Enemy Blackboard, click the New Key button and select Object.



The Blackboard asset consists of two panels: the Blackboard, which enables you to add and keep track of your Blackboard Keys (variables to monitor), and Blackboard Details, which enables you to name and specify the type of Keys.

For the Object key, enter EnemyActor as the Entry Name and Actor as the Base Class.



Add another Key with the Key Type set to Bool called HasLineOfSight.



This will be used to keep track of whether or not the AI has a line of sight to the Player.

Add another Key, with the Key Type set to Vector called PatrolLocation.



This will be used to keep track of a location in the Level where the AI can move when it is not chasing the Player.

Our Blackboard is set up with the things we need to track. In the next step, we will lay out our Behavior Tree.

3 - Behavior Tree Layout

In this step, we will lay out the flow of our Behavior Tree and the states that we want our AI to enter. Laying out your Behavior Tree with the states you anticipate your AI could be in as a visual flow will give you an idea of what type of logic and rules you will need to create to enter those states.

In the Content Drawer, click +Add and under Artificial Intelligence, select Behavior Tree and call it BT_Enemy.



Naming conventions may vary, but it's generally good practice to add an acronym of the asset type to the name.

Open the BT_Enemy and assign the BB_Enemy as the Blackboard Asset.



If you do not see the Blackboard Keys we created, clear the Blackboard Asset by clicking the yellow arrow, then re-assign the Enemy_BB to refresh the keys.

The Behavior Tree consists of three panels: the Behavior Tree graph, where you visually layout the branches and nodes that define your behaviors, the Details panel, where properties of your nodes can be defined, and the Blackboard, which shows your Blackboard Keys and their current values when the game is running and is useful for debugging.

In the graph, left-click and drag off the Root and add a Selector node.



Composites are a form of flow control and determine how the child branches that are connected to them execute.

Composites

Description

Selector

Executes branches from left-to-right and is typically used to select between subtrees. Selectors stop moving between subtrees when they find a subtree they successfully execute. For example, if the AI is successfully chasing the Player, it will stay in that branch until its execution is finished, then go up to the selector's parent composite to continue the decision flow.

Sequence

Executes branches from left-to-right and is more commonly used to execute a series of children in order. Unlike Selectors, the Sequence continues to execute its children until it reaches a node that fails. For example, if we had a Sequence to move to the Player, check if they are in range, then rotate and attack. If the check if they are in range portion failed, the rotate and attack actions would not be performed

Simple Parallel

Simple Parallel has two "connections". The first one is the Main Task, and it can only be assigned a Task node (meaning no Composites). The second connection (the Background Branch) is the activity that's supposed to be executed while the main Task is still running. Depending on the properties, the Simple Parallel may finish as soon as the Main Task finishes, or wait for the Background Branch to finish as well.

For the Selector node, in the Details panel, change the Node Name to AI Root.



Renaming nodes in the graph is a good way to easily identify, from a high-level, what the node accomplishes. In this example, we name it AI Root as this is the real "Root" of our Behavior Tree which will switch between our child branches. The default Root node that is automatically added when creating a Behavior Tree is used to configure properties of the Behavior Tree as well as assign the Blackboard asset it's using.

Left-click and drag off AI Root and add a Sequence node named Chase Player.



Click image for full view.

We use a Sequence node here as we plan to tell the AI to do a sequence of actions: rotate towards the player, change their movement speed, then move to and chase the Player.

Left-click and drag off the AI Root node and add a Sequence node called Patrol.



Click image for full view.

For our AI, we will use the Sequence node to find a random location on the map, move to that location, then wait there for a while before repeating the process of finding a new location to move to.

You may also notice the numbers in the upper-right corner of the nodes:



This indicates the order of operation. Behavior Trees execute from left-to-right and top-down, so the arrangement of your nodes is important. The most important actions for the AI should usually be placed to the left, while the less important actions (or fallback behaviors) are placed to the right. Child branches execute in the same fashion and should any child branch fail, the entire branch will stop executing and will fail back up the tree. For example, if Chase Player failed, it would return up to AI Root before moving on to Patrol.

Drag off AI Root then add a Wait Task to the right of Patrol with Wait Time set to 1.0.



Click image for full view.

You will notice that this node is purple, indicating that it is a Task node. Task nodes are the actions that you want the Behavior Tree to perform. The Wait Task acts as a catch-all if the Behavior Tree fails both Chase Player and Patrol.

Drag off the Chase Player and add a Rotate to Face BBEntry node.



Click image for full view.

This particular Task enables you to designate a Blackboard Entry that you want to rotate and face, in our case the Enemy Actor (Player). Once you add the node, if you look in the Details panel, the Blackboard Key will automatically be set to EnemyActor because it filters for the Actor blackboard variable and it is the first one in the list. You can adjust the Precision option if you want to tune the success condition range as well as change the Node Name.

From the Toolbar, click the New Task button.



In addition to using the built-in Tasks, you can create and assign your custom Tasks that have additional logic that you can customize and define. This Task will be used to change the movement speed of the AI so that it runs after the Player. When you create a new Task, a new Blueprint will automatically be created and opened.



Click image for full view.

In the Content Drawer, rename the new asset as BTT _ChasePlayer.



It's a good practice to immediately rename any newly created Tasks, Decorators or Services when you create them. Proper naming conventions would be to prefix the name of the asset with the type of asset you create such as BTT for Behavior Tree Tasks, BTD for Behavior Tree Decorators, or BTS for Behavior Tree Services.

Inside the BT_Enemy, add the BTT_ChasePlayer Task followed by a Move To.



Click image for full view.

Our new Task has no logic in it yet, but we will come back and add the logic for changing the movement speed of our AI character after which, the AI will Move To the EnemyActor (Player).

Create a new Task and rename it BTT_FindRandomPatrol, then connect it to Patrol.



Click image for full view.

Add a Move To Task and set the Blackboard Key to PatrolLocation.



Click image for full view.

This will instruct the AI to Move To the PatrolLocation which will be set inside the BTT_FindRandomPatrol Task.

Add a Wait Task following Move To with Wait Time to 4.0 and Random Deviation to 1.0.



Click image for full view.

This instructs the AI to wait at PatrolLocation for 3-5 seconds (Random Deviation adds + or - a second to Wait Time).

The framework for our Behavior Tree is complete. In the next step, we will add the logic for changing the movement speed of the AI, finding a random location to navigate to when the AI is patrolling, and the logic for determining when the AI should be chasing the player or patrolling.

4 - Task Setup - Chase Player

In this step, we set up our Chase Player Task to change the movement speed when chasing the Player.

Inside BTT_ChasePlayer, right-click and add an Event Receive Execute AI node.



The Event Receive Execute AI node is fired when this Task is activated inside the Behavior Tree.

You should always select the AI version of Event Receive Execute, Event Receive Abort, and Event Receive Tick if the Agent is an AI Controller. If both generic and AI event versions are implemented, only the more suitable one will be called, meaning the AI version is called for AI, and the generic one otherwise.

Off the Controlled Pawn pin, use a Cast to Enemy_Character node.



Here, we are accessing the Character Blueprint for our AI called Enemy_Character by using a Cast node.

Inside the Content Drawer, open the Enemy_Character Blueprint and add a Function called Update Walk Speed.



This function will be called from our Behavior Tree and will be used to change the AI's movement speed.

Technically we could access the Character Movement Component off the Cast node in our Chase Player Task and adjust the movement speed from within the Task, however having the Behavior Tree directly change properties of sub-objects is not a recommended best practice. Instead, we will have the Behavior Tree call a function inside the Character which will then make the modifications we need.

In the Details panel for the Update Walk Speed function, add a Float input called NewWalkSpeed.



Drag the CharacterMovement Component off the Components tab.



Click and drag off the pin of Character Movement and from the actions menu type in Set Max Walk Speed, then click Set Max Walk Speed from the menu.



Use Set Max Walk Speed and connect as shown below.



When we call this function from the Behavior Tree, we can pass through a value to be used as the new speed.

Back inside the BTT_ChasePlayer Task, from the As Enemy Character node, call Update Walk Speed set to 500.0 and connect as shown.



Don't see the Update Walk Speed function you created? You may need to Compile the Enemy_Character Blueprint before trying to add it to the Chase Player Task.

Following Update Walk Speed, add two Finish Execute nodes and connect as shown below.



Here we mark the Task as successfully finishing when we successfully cast to the Enemy_Character. If the controlled Pawn is not Enemy_Character, we need to handle this case so we mark the Task as unsuccessful which will abort the Task.

Right-click the New Walk Speed pin, then promote it to a variable and call it ChaseSpeed.



For ChaseSpeed, make sure to enable Instance Editable.



By promoting this to an Instance Editable variable, the value of Max Walk Speed can be set from outside of this Blueprint and will be available as a property inside our Behavior Tree.



We can now easily change the value of Chase Speed that is being sent to the Enemy_Character Blueprint enabling us to tune and tweak how fast our AI chases the Player.

Our Chase Player Task is complete, in the next step, we will set up the Find Random Patrol Task logic to get a random location for the AI to move to.

5 - Task Setup - Find Random Patrol

In this step, we set up our Find Random Patrol Task so our AI moves to a random location when it is not chasing the Player.

Implementing a Blueprint Behavior Tree Task is a clever way to quickly iterate, but, if performance is a concern, you may decide to move to a native Behavior Tree Task.

Inside BTT_FindRandomPatrol, use Event Receive Execute AI and Cast to Enemy_Character and connect them.



Off As Enemy Character, call Update Walk Speed and promote New Walk Speed to a variable called Patrol Speed with the following settings:



Click image for full view.

- Variable Name to PatrolSpeed- Instance Editable to Enabled- Patrol Speed (Default Value) to 125.0

Here we are lowering the enemy movement speed while patrolling.

Off Controlled Pawn, Get Actor Location then GetRandomReachablePointInRadius with the Return Value connected to a Branch.

Promote the Radius on GetRandomReachablePointInRadius to a variable with the following settings:



Click image for full view.

- Variable Name to PatrolRadius- Instance Editable to Enabled- Patrol Radius (Default Value) to 1000.0

Here we are finding a random location within 1000 units of the enemy character's current location. We are also using a Branch node to handle the edge case that a random point to move to is not found.

Off the Random Location pin, use Set Blackboard Value as Vector with the Key promoted to a variable called PatrolLocation.

Use another Set Blackboard Value as Vector node with the Value coming from Get Actor Location.

Continuing from the previous step, connect as shown below with both nodes resulting in Finish Execute marked Success.



Click image for full view.

If the enemy finds a random position to move to, it will be stored in the Blackboard as the location to move to. If a location is not found, it will use its current location and stay put before trying a new location. We still need to handle the edge case that the Controlled Pawn is not Enemy_Character.

Off the Cast Failed pin of the Cast node, use Finish Execute with Success disabled.



Click image for full view.

If the Controlled Pawn is not Enemy_Character, this Task will be marked as unsuccessful and will be aborted.

Our Find Random Patrol Task is complete. In the next step, we will learn more about Decorators and how they can be used as conditionals as well as set up our AI Controller.

6 - AI Controller Setup

In this step, we do a little bit of work inside the AI Controller in preparation for the final step, setting up a Decorator to determine which branch of our Behavior Tree to enter.

In the Content Drawer, open the Enemy_Controller Blueprint and add an Event On Possess node.

Off Event On Possess, add a Run Behavior Tree node with BTAsset set to BT_Enemy.



Run Behavior Tree is a contextual functional call that targets AI Controller Class Blueprints and enables you to execute the assigned Behavior Tree asset.

In the Components window, click + Add and search for and add an AIPerception Component.



The AI Perception Component is used to create a stimuli listener within the AI Perception System and gathers registered stimuli (in our case, we can use Sight) that you can respond to. This will give us the ability to determine when the AI actually sees the Player and can react accordingly.

In the Details panel for the AIPerception Component, add an AI Sight config and enable Detect Neutrals.



The Detection by Affiliation properties enable you to set up team-based AI that fights alongside teammates of the same affiliation and attack members of the opposing affiliation. Actors by default are not assigned an affiliation and are considered neutral.

Currently, you cannot assign affiliation through Blueprint, therefore we are enabling the Detect Neutral flag to detect the Player. As an alternative, we are going to use Actor Tagging to determine which Character is the Player and force AI Character(s) to only chase Actors tagged as Player.

In the Events section for AIPerception, click the + sign next to On Target Perception Updated.



Off On Target Perception Updated in the graph, add an Actor Has Tag node with Tag set to Player.



Off the Stimulus pin, add a Break AIStimulus node.

Add a Branch node with the Condition shown below.



Here we are checking if the Actor was successfully Sensed and if that Actor has the Tag of the Player.

You can select the Break AIStimulus node and in the Details panel use Hide Unconnected Pins to hide all pins that are not connected so your graph looks similar to the one above.

Off the False of the Branch, use Set Timer by Event with Time set to 4.0.

Right-click and promote Time to a variable and call it Line Of Sight Timer.



Click image for full view.

This Variable and the value assigned will determine how long before the AI gives up chasing the Player at which point, the attached Event will execute.

Right-click on the Return Value of Set Timer by Event and promote it to a Variable called EnemyTimer.



Click image for full view.

This stores a reference to the Timer by way of a Handle. This Handle can be called upon through script to invalidate itself and clear any associated Events (preventing the associated Event from being executed). We can use this later in the event the AI sees the player again before the Line of Sight Timer runs out, which stops the AI from losing sight of the player and giving up the chase.

Create a Custom Event and call it StartEnemyTimer and connect it to the Event pin of Set Timer by Event.



Click image for full view.

Right-click, then under Variables > AI, add a Get Blackboard node.



Off Blackboard, use Set Value as Bool and Set Value as Object and connect as shown below.



This enables us to update the Blackboard Keys defined with new Values.

Right-click and promote both Key Names to Variables called HasLineOfSight and EnemyActor respectively.

Compile the Blueprint and set the Default Values for both Key Names to HasLineOfSight and EnemyActor respectively.



Click image for full view.

Off the True of the Branch, use Get EnemyTimer then Clear and Invalidate Timer by Handle.



Click image for full view.

When the AI sees the Player, it will clear the Line Of Sight Timer until it loses sight of the Player again (where a new Line Of Sight Timer will start).

Copy and Paste the Blackboard node, Set Value as, and Key Name nodes as shown.



Click image for full view.

On the Set Value as Bool node, enable the Bool Value and drag the Actor pin to the Object Value as shown.



Click image for full view.

This sets the Blackboard Key Values for Has Line Of Sight to True and EnemyActor to the Actor we perceived (which we have set up to only trigger if it is the Player).

Click Compile to compile then close the Blueprint.



Click image for full view.

The final graph should look similar to the above.

7 - Decorator and Final Setup

In this final section, we adjust a few settings on the Player Character and Enemy Character Blueprints. We also set up our Decorator in our Behavior Tree which will determine what branch we can enter based on a specified condition.

Inside the Content Drawer under Content > ThirdPersonBP > Blueprints, open the ThirdPersonCharacter Blueprint.

In the Details panel, search for and add a Tag set to Player.

![ In the Details panel search for and add a Tag set to Playerbtqs-step-6-18.png)

By setting adding this Tag of Player, the AI can now perceive and react to the Player.

Open up the Enemy_Character Blueprint inside your AI folder.

In the Details panel, search for Rotation and enable Use Controller Rotation Yaw.



This will cause the AI to rotate properly when the Rotate to Face BB Entry is called from our Behavior Tree.

Don't see the Pawn options? You may need to click the Class Defaults button from the Toolbar first.

Open up the BT_Enemy and right-click on Chase Player, then under Add Decorator.., select Blackboard.



Click image for full view.

When you right-click on a node in a Behavior Tree, you can add subnodes that provide additional functionality:

Subnode

Description

Decorator

Also known as conditionals. These attach to another node and make decisions on whether or not a branch in the tree, or even a single node, can be executed.

Service

These attach to both Task and Composite nodes, and will execute at their defined frequency as long as their branch is being executed. These are often used to make checks and to update the Blackboard. These take the place of traditional Parallel nodes in other Behavior Tree systems.

We are going to use the Blackboard Decorator to determine the value of a Blackboard Key, which when valid, is going to allow this branch to execute.

Select the Blackboard Based Condition that was added and set the following settings in the Details panel.



Click image for full view.

Observer aborts to Both

Blackboard Key to HasLineOfSIght

Node Name to Has Line of Sight?

Here we are stating that when the HasLineOfSight value Is Set (or is true), execute this Chase Player branch. The Observer aborts setting of Both states that when the Blackboard Key we assigned changes, abort our self (Chase Player) and any lower priority Tasks. This means that when the value of HasLineOfSight changes and is not set, abort self (Chase Player), at which point the next branch (Patrol) will execute. When the HasLineOfSight value becomes Is Set , the observer will abort lower priority Tasks as well enabling the Chase Player branch to be executed.

Compile and close the Behavior Tree then Play in the Editor.

End Result

You should now be able to test your AI and it will follow you when it sees you.

When the AI loses sight of you, it will still attempt to track you down and regain line of sight. After the time you have entered the Line Of Sight Timer value, it will give up chasing you and return to patrolling.

You can watch the Behavior Tree in action as you are playing to see how it switches between the different branches. The variables can also be watched inside the Behavior Tree as you are playing to get an idea of what values the AI current has.

8 - Own Your Own!

Now that your AI Character will chase the Player and return to patrolling after losing sight of the Player for a specified duration of time, try to add some of the following elements to your Behavior Tree on your own!

In the Behavior Tree, for both Move To Tasks, add a new Service that incorporates the functionality from the Task that precedes it.

Our original Behavior Tree uses a separate Task for adjusting the movement speed (in the case of chasing the Player) and finding a random location to patrol to and decreasing movement speed (in the case of patrolling). Convert these to Services that are attached to the Move To Task.

Hint: The script in the Services will be similar to the script in each Task, however instead of Event Receive Execute AI, you want to use Event Receive Activation AI. Because they are a Service, you will also not need a Finish Execute node.

Instead of using a random patrol point to move to, create a Patrol Path Blueprint that contains an array variable of vector values that AI can move between.

Hint: Cycle through and get the next entry in the array to move the AI between the locations, then update the Blackboard Key value PatrolLocation based on the current entry in your array.

When losing line of sight to the Player, move the AI to the last known location of the Player rather than getting the current location of the Player.

Hint: On the Move To command for Turning and Chasing the Player, you will need to specify a location instead of EnemyActor as it is currently set to get the location of EnemyActor (which retrieves the Player's current location).

Add attacking functionality to the AI once they reach the Player.

Hint: Add a new Composite node as the Background Task for Turning and Chasing the Player. Once the AI reaches the Player, add a Task node for an Attack animation.

Basics of Behavior Trees

Differences in Unreal Engine Behavior Trees

Behavior Trees are Event-Driven

Conditionals are not Leaf Nodes

Concurrent Behaviors

Creating artificial intelligence (AI) in Unreal Engine 5 (Unreal Engine) for characters can be done in many different ways. You can use Blueprint Visual Scripting to instruct a character to "do something" such as play an animation, move to a specific location, react when being hit by something, and more. When you want AI characters to do their thinking and make their own decisions, this is where Behavior Trees can help! An example of a Behavior Tree is illustrated below where an AI character switches between patrolling and chasing the player.



Click image for full view.

Basics of Behavior Trees

Behavior Trees are created in a visual way similar to Blueprint by adding and connecting a series of nodes that have some functionality attached to them to a Behavior Tree Graph. While a Behavior Tree executes logic, a separate asset called a Blackboard is used to store information (called Blackboard Keys) the Behavior Tree needs to know about to make informed decisions. A typical workflow would be to create a Blackboard, add some Blackboard Keys, then create a Behavior Tree that uses the Blackboard asset (pictured below, a Blackboard is assigned to a Behavior Tree).



Behavior Trees in Unreal Engine execute their logic from left-to-right, and top-to-bottom. The numerical order of operation can be viewed in the upper-right corner of nodes placed in the graph. In the image below, a sample of a branch placed in the left-most portion of a Behavior Tree graph has some nodes that instruct an AI to chase after a Player if the Blackboard Key HasLineOfSight is set.



The blue node in the image above is referred to as a Decorator (or a Conditional in other Behavior Tree systems). It is attached to a Composite node and used to validate whether the Blackboard Key is true or not. This determines whether the rest of the branch can be executed. The purple nodes are Task nodes and are the actions the AI can perform.

Please see Behavior Tree User Guide for more information on creating and editing Behavior Trees.

Once you have created your Behavior Tree and logic, you will need to run the Behavior Tree during gameplay. Usually, you will have a Pawn (or "body" for the AI that is either a character or some other entity) and that Pawn will have an associated AI Controller which will be used to take control of and direct the Pawn in performing actions (one of which is to run the Behavior Tree). Below, we have assigned a custom AI Controller class to our Pawn.



And in our AI Controller, when the Controller takes "possession" of the Pawn, we run a Behavior Tree:



For your Pawn to navigate around the environment, you will need to add a NavMeshBoundsVolume to the Level.

Please see the Behavior Tree Quick Start for a more detailed step-by-step guide in setting up AI using a Behavior Tree.

Differences in Unreal Engine Behavior Trees

This section outlines some of the differences in Unreal Engine Behavior Trees when compared to traditional Behavior Tree systems.

Behavior Trees are Event-Driven

One of the ways Unreal Engine Behavior Trees differ from other Behavior Tree systems is that Unreal Engine Behavior Trees are event-driven to avoid doing unnecessary work every frame. Instead of constantly checking whether any relevant change has occurred, the Behavior Tree passively listens for "events" that can be used to trigger changes in the tree. In the image below, an event is used to update the Blackboard Key HasLineOfSight? . This causes any lower priority Task to be aborted in favor of executing our left-most branch which has higher priority.



Click image for full view.

Having an event-driven architecture grants improvements to both performance and debugging. However, to take the most advantage of these improvements, you will need to understand the other differences to Unreal Engine Behavior Trees and structure your Behavior Trees appropriately. Since the code does not have to iterate through the entire tree every tick, performance is much better. Conceptually, instead of constantly asking "Are we there yet?", we can just rest until we are prodded and told, "We are there!"

When stepping forward and backward through a Behavior Tree's execution history to visually debug the behavior, it is ideal to make the history show relevant changes and not show irrelevant ones. In the event-driven implementation in Unreal Engine, it is not necessary to filter out irrelevant steps that iterated over the tree and chose the same behavior as before, because that additional iteration never had to happen in the first place. Instead, only changes to the location of execution in the tree or Blackboard values matter, and it is those differences that are shown.

Conditionals are not Leaf Nodes

In the standard model for Behavior Trees, conditionals are Task leaf nodes, which simply do not do anything other than succeed or fail. Although nothing prevents you from making traditional conditional tasks, it is highly recommended that you use Decorators for conditionals instead.

Making conditionals Decorators rather than Tasks has a couple of significant advantages:

Conditional Decorators make the Behavior Tree UI more intuitive and easier to read.

Since all leaves are action Tasks, it is easier to see what actual actions are being ordered by the tree.

Since conditionals are at the root of the sub-tree they are controlling, you can immediately see what part of the tree is "closed off" if the conditionals are not met. Also, since all leaves are action Tasks, it is easier to see what the actions are. In a traditional model, conditionals would be among the leaves, so you would have to spend more time trying to figure out which leaves are conditionals and which leaves are actions.



In the section of a Behavior Tree above, the Decorators Close Enough and Blackboard can prevent the execution of the Sequence node's children. Another advantage of conditional Decorators is that it is easy to make those Decorators act as observers (waiting for events) at critical nodes in the tree. This feature is critical to gaining full advantage from the event-driven nature of the trees.

Concurrent Behaviors

Standard Behavior trees often use a parallel composite node to handle concurrent behaviors and the parallel node begins execution on all of its children simultaneously. Special rules determine how to act if one or more of those child trees finish (depending on the desired behavior).

Parallel nodes are not necessarily multi-threading (executing tasks at the same time). They are just a way to conceptually perform several tasks at once. Often they still run on the same thread and begin in some sequence. That sequence should be irrelevant since they will all happen in the same frame, but it is still sometimes important.

Instead of complex parallel nodes, Unreal Engine Behavior Trees use Simple Parallel nodes, a special node type called Services, and the property Observer Aborts on Decorators to accomplish the same sorts of behaviors.



Simple Parallel nodes have only two children: one which must be a single Task node (with optional Decorators), and the other of which can be a complete sub-tree. Think of the Simple Parallel node as "While doing A, do B as well." For example, "While attacking the enemy, move toward the enemy." A is a primary task, and B is a secondary or filler task while waiting for A to complete.

While there are some options as to how to handle the secondary task (Task B), the node is relatively simple in concept compared to traditional parallel nodes. Nonetheless, it supports much of the most common usage of parallel nodes. Simple Parallel nodes allow easy usage of our event-driven optimizations while full parallel nodes would be much more complex to optimize.

Services are special nodes associated with any Composite node (Selector, Sequence, or Simple Parallel), which can register for callbacks every specified amount of seconds and perform updates of various sorts that need to occur periodically.

For example, a service can be used to determine which enemy is the best choice for the AI Pawn to pursue while the Pawn continues to act normally in its Behavior Tree toward its current enemy.

Services are active as long as execution remains in the sub-tree of the Composite node where the service has been added.

One common usage case for standard parallel nodes is to constantly check conditions so that a task can abort if the conditions it requires becomes false.

For example, if you have a cat that performs a sequence, such as "Hiss" and "Pounce", you may want to give up immediately if the mouse escapes into its mouse hole. With parallel nodes, you would have a child that checks if the mouse can be pounced on, and then another child that the sequence would perform. Since Unreal Engine Behavior Trees are event-driven, we instead handle this by having our conditional Decorators observe their values and abort when necessary. In this example, you would have a "Mouse Can Be Pounced On?" Decorator on the Sequence, with "Observer Aborts" set to "Self".

There are three main advantages to the way Unreal Engine handles concurrent behaviors:

Clarity - Using Services and Simple Parallel nodes creates simple trees that are easier to read and understand.

Ease of Debugging - Clearer graphs are easier to debug. Also, having fewer simultaneous execution paths makes it easier to see what is being executed.

Easier Optimization - Event-driven graphs are easier to optimize if they do not have a lot of sub-trees simultaneously executing.

Creating Behavior Tree Assets

Creating a Behavior Tree

Creating a Blackboard

Creating a Behavior Tree Task

Creating a Behavior Tree Decorator

Creating a Behavior Tree Service

Editing a Blackboard

Editing a Behavior Tree

Assigning a Blackboard

Working with Nodes

Node Decorators and Services

Creating Behavior Tree Assets

This section illustrates how to create the various Behavior Tree assets within Unreal Engine 5.

Creating a Behavior Tree

Behavior Trees are essentially the AI's processor and can make decisions and execute various branches based on the outcome of those decisions. Behavior Trees are created inside the Content Drawer in the following manner:

Click the +Add button, then under Create Advanced Asset select Artificial Intelligence and Behavior Tree.



The new Behavior Tree asset will be added to the Content Drawer where you can define its name.





You can also use the right-click context menu and select +Add > Artificial Intelligence > Behavior Tree.

Creating a Blackboard

The Blackboard asset can be considered as the "brain" of the AI and stores Key values that the Behavior Tree uses to make its decisions. Blackboard assets can be created using the following methods:

Click the +Add button, then under Create Advanced Asset select Artificial Intelligence and Blackboard.



The new Blackboard asset will be added to the Content Drawer which you can rename to your desired name.



Another method in which you can create a Blackboard is inside a Behavior Tree:

Inside the Behavior Tree Editor from the Toolbar by clicking the New Blackboard button.



This will also create a new Blackboard asset inside the Content Drawer.

Creating a Behavior Tree Task

A Task is an "action" you want the AI to perform, such as move to a location or rotate to face something.

If optimization is a concern, you may want to consider switching Blueprint Behavior Tree Tasks to native Behavior Tree Tasks.

In addition to the existing Tasks available, you can create custom Tasks with your own logic:

Click the New Task button from the Toolbar inside the Behavior Tree Editor.



This will open a new Blueprint of the BTTask_BlueprintBase class where you can provide your Task logic.



The Task Blueprint will be created inside the Content Drawer in the same location as your Behavior Tree asset.

Whenever you create a new Task from the Behavior Tree Editor, it's a good practice to go into the Content Drawer and rename the asset instead of using the default name.

When creating a new Task, you can use an existing Behavior Tree Task as the Parent Class to inherit functionality by selecting it from the drop-down menu.



Creating a Behavior Tree Decorator

Decorators (also known as conditionals) attach to nodes inside Behavior Trees and can be used to make decisions on whether a branch (or even a single node) in the tree can be executed. There are several default Decorators that you can use in your Behavior Trees, however, you can also create custom ones:

Click the New Decorator button from the Toolbar inside the Behavior Tree Editor.



This will open a new BTDecorator_BlueprintBase class where you can provide your Decorator logic.



The Decorator Blueprint will be created inside the Content Drawer in the same location as your Behavior Tree asset.

Whenever you create a new Decorator from the Behavior Tree Editor, it's a good practice to go into the Content Drawer and rename the asset instead of using the default name.

When creating a new Decorator, you can use an existing Behavior Tree Decorator as the Parent Class to inherit functionality from by selecting it from the drop-down menu.



Creating a Behavior Tree Service

Services attach to Composite nodes and will execute at their defined frequency as long as their branch is being executed. These are often used to make checks and to update the Blackboard and take the place of traditional Parallel nodes in other Behavior Tree systems. While there are a few Services available by default, you will more than likely want to create your own custom Services that assist in determining how your Behavior Tree is executed.

If optimization is a concern, you may want to consider switching Blueprint Behavior Tree Services to native Behavior Tree Services.

Click the New Service button from the Toolbar inside the Behavior Tree Editor.



This will open a new BTService_BlueprintBase class where you can provide your Service logic.



The Service Blueprint will be created inside the Content Drawer in the same location as your Behavior Tree asset.

Whenever you create a new Service from the Behavior Tree Editor, it's a good practice to go into the Content Drawer and rename the asset instead of using the default name.

When creating a new Service, you can use an existing Behavior Tree Service as the Parent Class to inherit functionality by selecting it from the drop-down menu.



Editing a Blackboard

Usually, you'll create a Blackboard before your Behavior Tree as the Behavior Tree references the Blackboard in its decision-making process (you can always add Keys later as you need them). You can edit a Blackboard asset by double-clicking on the asset in the Content Drawer to open it up in the Blackboard Editor.



If you are editing a Behavior Tree that has an assigned Blackboard, you can switch to the Blackboard by clicking the tab in the upper-right corner of the window.



In the Blackboard Details panel, you can assign a different Blackboard as the Parent, inheriting Keys from it.



You can add Keys by clicking the New Key button in the Blackboard window.



Please see Blueprint Variables for a breakdown of variable types that can be stored as Keys.

When a Key has been created, you can define properties associated with the Key in the Blackboard Details panel.



Property

Description

Entry Name

The user defined name of the Key.

Entry Description

Optional description to explain what this Blackboard Key does.

Key Type

Defined when you create the Key, however ,Object and Class Keys provide the additional option of defining a specific Class. This enables you to store any type of data that inherits from Object (such as Actors) in them.

Instance Synced

This is used to determine if the Key will be synchronized across all instances of the Blackboard.

To Rename or Delete Key, right-click a Key to bring up the context menu, or press F2 or Delete on a Key.



For Class and Object Keys, you can click the little triangle beside Key Type which enables you to define the Base Actor Class to use.



For Enum Keys, there are additional properties that can be set by clicking the little triangle beside Key Type.



Property

Description

Enum Type

The assigned Enumeration to use.

Enum Name

The name of the enum defined in C++ code will take priority over the asset assigned under Enum Type.

Is Enum Name Valid

Set when Enum Name override is valid and active.

Editing a Behavior Tree

To edit a Behavior Tree, you will need to open a Behavior Tree asset:

Double-click a Behavior Tree asset in the Content Drawer to enter Behavior Tree Mode.



Or by switching over to Behavior Tree Mode:

Click the Behavior Tree tab in the upper-right corner of the Behavior Tree Editor.



To switch over to Behavior Tree Mode, you will need to have a currently opened Behavior Tree asset and are switching from Blackboard Mode.

Assigning a Blackboard

In order for the Behavior Tree to access a Blackboard, you must assign a Blackboard asset:

Select the Root node in the graph (or deselect all nodes), then in the Details panel, set your desired Blackboard Asset.



After assigning a Blackboard, the Blackboard panel will update with its associated Blackboard Keys.



Working with Nodes

To add Composites or Tasks to the graph of your Behavior Tree, right-click the graph to bring up the context menu and select your desired node.



Only Composite nodes can be connected to the Root node of a Behavior Tree.

You can also drag off a node and select a node to add from the context menu.



To remove nodes from the graph, select a node (or nodes) and press Delete (or right-click and select Delete).



To connect nodes together, left-click and drag from the output pin, to input pin on another node.



Connecting nodes in Behavior Trees only work by connecting an output to an input (you cannot connect from an input to an output).

To disconnect nodes, right-click a node (or define a selection of nodes) and select your desired Break All Pin Link(s) method.

Break All Pin Link(s) can be used to break a single link or multiple nodes that are pinned. Break link to... will break the connection to the specified node.

You can also press alt + left-click on an input or output pin to break the connection.

To edit a node, select a node, then in the Details panel, you can adjust its properties.



You can also copy and paste selected nodes and their settings. To do this, select a node (or drag a selection box around a selection of nodes) then press ctrl+c (to copy) and ctrl+v (to paste).



Node Decorators and Services

You can add Decorators or Services to a node in your Behavior Tree graphs from the node context menu.

To do this, right-click a Composite or Task node, then select the Decorator or Service you want to add to the node.



To remove a Decorator or Service from a node, select a Decorator or Service then press the Delete key or use the right-click context menu.



To edit a Decorator or Service attached to the node, first, select the Decorator or Service, then you can adjust your desired properties in the Details panel.



Composite Decorators that are added to a node, can be opened up for editing.

To open a Composite Decorator, double-click a Composite Decorator to open a graph that returns a Boolean (true or false) value.



Click image for full view

Any Task, Decorator, or Service created from the toolbar, can be opened up in Blueprint for editing.

After creating a custom Task, Decorator, or Service and adding it to your graph, double-click it to open it for editing:



You can also open any custom Task, Decorator, or Service in the Content Drawer.

Double-click a custom Task, Decorator, or Service in the Content Drawer to open it in Blueprint for editing.



You can also copy Decorators or Services and paste them onto other nodes.

Select a Decorator or Service and press ctrl+c (to copy) and ctrl+v (to paste) onto another node.



Behavior Tree Node Types

Behavior Tree Node Instancing Policy

Behavior Tree Nodes (base class UBTNode) perform the main work of Behavior Trees, including tasks, logic flow control, and data updates.

Behavior Tree Node Types

The node that serves as the starting point for a Behavior Tree is a Root node. This is a unique node within the tree, and it has a few special rules. It can have only one connection, and it does not support attaching Decorator Nodes or Service Nodes. Although the Root node has no properties of its own, selecting it will show the properties of the Behavior Tree in the Details panel, where you can set the Behavior Tree's Blackboard Asset.



Aside from Root Nodes, there are four types of Behavior Tree nodes:

Node Type

Description

Composite Nodes

These are the nodes that define the root of a branch and the base rules for how that branch is executed.

Task Nodes

These are the leaves of the Behavior Tree, these nodes are the actionable things to do and don't have an output connection.

Decorator Nodes

Also known as conditionals. These attach to another node and make decisions on whether or not a branch in the tree, or even a single node, can be executed.

Service Nodes

These attach to Composite nodes and will execute at their defined frequency as long as their branch is being executed. These are often used to make checks and to update the Blackboard. These take the place of traditional Parallel nodes in other Behavior Tree systems.

Behavior Tree Node Instancing Policy

Behavior Tree Nodes (referred to here as "nodes") exist as shared objects, meaning that all agents using the same Behavior Tree will share a single set of node instances. This improves CPU performance while reducing memory usage, but also prevents nodes from storing agent-specific data. However, for cases where agents need to store and update information related to a node, Unreal Engine provides three solutions:

Instancing Nodes

The node's bCreateNodeInstance variable, when set to true, will grant each agent using the Behavior Tree a unique instance of the node, making it safe to store agent-specific data at the cost of some performance and memory usage. Certain Unreal Engine node classes, including UBTTask_BlueprintBase, UBTTask_PlayAnimation, and UBTTask_RunBehaviorDynamic, use this feature.

Storing on the Blackboard

A common solution is to store variables on the Blackboard. To do this, expose the name of the variable from your node, then fetch and store the Blackboard Key using that name during the node's initialization. You can then use the Blackboard Key to get and set the variable's value on your agent's Blackboard instance. This method supports variables of bool, float, FVector, int32, enum (stored as uint8) and UObject* types.

Storing on the Behavior Tree Node

You can create a custom struct or class to store variables inside the node's memory. The UBTTask_MoteTo class, for example, uses FBTMoveToTaskMemory. You can find the following code in BTTask_MoteTo.h:

Many virtual functions in UBTNode take a uint8* parameter to the node's memory. This parameter indicates a block of memory allocated for an agent, the size of which will be returned by your overridden version of GetInstanceMemorySize. Nodes will allocate this amount of memory for each agent and will store this memory in a single contiguous block to optimize performance. However, this memory is not part of the UObject ecosystem, not part of Unreal Engine's reflection system, and is not visible to Garbage Collection. Because of this, UPROPERTY support is unavailable, and TWeakObjectPtr is recommended to store any UObject pointers that you may need.

Selector

Sequence

Simple Parallel

Composite nodes define the root of a branch and the base rules for how that branch is executed. They can have Decorators applied to them to modify entry into their branch, or even cancel out mid-execution. Also, they can have Services attached to them that will only be active if the children of the Composite are being executed.

Only Composite nodes can be attached to the Root node of a Behavior Tree.

Selector



Selector nodes execute their children from left to right. They stop executing when one of their children succeeds. If a Selector's child succeeds, the Selector succeeds. If all the Selector's children fail, the Selector fails.

Property

Description

Apply Decorator Scope

If set, all Decorators in the branch below will be removed when execution flow leaves the branch (Decorators on this node are not affected).

Node Name

The name the node should display in the Behavior Tree graph.

Sequence



Sequence nodes execute their children from left to right. They stop executing when one of their children fails. If a child fails, then the Sequence fails. If all the Sequence's children succeed, then the Sequence succeeds.

Property

Description

Apply Decorator Scope

If set, all Decorators in the branch below will be removed when execution flow leaves the branch (Decorators on this node are not affected).

Node Name

The name the node should display in the Behavior Tree graph.

Simple Parallel



The Simple Parallel node allows a single main Task node to be executed alongside of a full tree. When the main Task finishes, the setting in Finish Mode dictates if the node should finish immediately, aborting the secondary tree, or if it should delay for the secondary tree to finish.

Property

Description

Finish Mode

Immediate

Once the main Task finishes, the background tree will be aborted.

Delayed

The background tree will be permitted to finish once the main Task has finished.

Node Name

The name the node should display in the Behavior Tree graph.

Blackboard

Check Gameplay Tag Condition

Compare BBEntries

Composite

Conditional Loop

Cone Check

Cooldown

Custom Decorators

Does Path Exist

Force Success

Is At Location

Is BBEntry Of Class

Keep in Cone

Loop

Set Tag Cooldown

Tag Cooldown

Time Limit

Decorator, also known as conditionals in other Behavior Tree systems, are attached to either a Composite or a Task node and define whether or not a branch in the tree, or even a single node, can be executed.

Blackboard



The Blackboard node will check to see if a value is set on the given Blackboard Key.

Property

Description

Notify Observer

On Result Change

Reevaluate only when the condition has changed.

On Value Change

Reevaluate only when the observed Blackboard Key changes.

Observer Aborts

None

Do not abort anything.

Self

Abort self and any subtrees running under this node.

Lower Priority

Abort any nodes to the right of this node.

Both

Abort self, any subtrees running under this node, and any nodes to the right of this node.

Blackboard Key

The Blackboard Key the Decorator will work on.

Key Query

Is Set

Is the value set?

Is Not Set

Is the value not set?

Node Name

The name the node should display in the Behavior Tree graph.

Check Gameplay Tag Condition



Property

Description

Actor to Check

The Blackboard Key that contains the reference to the Actor to check.

Tags to Match

Should the Decorator match Any or All of the Tags listed in the property Gameplay Tags.

Gameplay Tags

Loads the Gameplay Tag editor to select the tags that should be used in this Decorator.

Inverse Condition

If the result of this Decorator be inversed where false becomes true and true becomes false.

Node Name

The name the node should display in the Behavior Tree graph.

Compare BBEntries



The Compare BBEntries (Blackboard Entries) node will compare the values of two Blackboard Keys and will block or allow the execution of a node based on if the result is equal to or not equal to.

Property

Description

Observer Aborts

None

Do not abort anything.

Self

Abort self and any subtrees running under this node.

Lower Priority

Abort any nodes to the right of this node.

Both

Abort self, any subtrees running under this node, and any nodes to the right of this node.

Operator

Is Equal To

Are the two Keys equal to each other?

Is Not Equal To

Are the two Keys different from each other?

Blackboard Key A

The first Key to use in this comparison.

Blackboard Key B

The second Key to use in this comparison.

Node Name

The name the node should display in the Behavior Tree graph.

Composite



The Composite Decorator node enables you to set up more advanced logic than the built-in nodes but not as complex as a full Blueprint. Once you have added a Composite Decorator to a node, double-click the Composite Decorator to bring up the Composite's Graph. By right-clicking in the graph area you can add Decorator nodes as standalone nodes, then wire them together through AND nodes, OR nodes, and NOT nodes, to create more advanced logic:



Click image for full view.

Property

Description

Composite Name

The name the node should display in the Behavior Tree graph.

Show Operations

This will cause the operations to be listed on the node in plain text.

Using a Composite Decorator in this manner will impact memory and performance. It is possible to create a Decorator in C++ that will do the same custom behavior but in a more efficient way.

Conditional Loop

As long as the Key Query condition is met, this Decorator will have the node it's attached to the loop.



Property

Description

Blackboard Key

The Blackboard Key the Decorator will work on.

Key Query

Is Set

Is the value set?

Is Not Set

Is the value not set?

Node Name

The name the node should display in the Behavior Tree graph.

Cone Check



The Cone Check Decorator takes in three Vector Keys: the first for the location to start the cone, the second to define the direction the cone points, and the third for the location to check if it is inside the cone. You define the angle of the cone by using the Cone Half Angle property.

Property

Description

Observer Aborts

None

Do not abort anything.

Self

Abort self and any subtrees running under this node.

Lower Priority

Abort any nodes to the right of this node.

Both

Abort self, any subtrees running under this node, and any nodes to the right of this node.

Cone Half Angle

The half angle of the cone. For example, for a 90-degree cone, this value should be set to 45 degrees.

Cone Origin

The location where the cone should start (the tip of the cone).

Cone Direction

The direction in which the mouth of the cone should point.

Observed

The location or Actor that is being checked to see if it is in the cone.

Inverse Condition

If the result of this Decorator is inversed where false becomes true and true becomes false.

Node Name

The name the node should display in the Behavior Tree graph.

Cooldown



The Cooldown node will lock the execution of a node or branch until the cooldown time expires.

Property

Description

Observer Aborts

None

Do not abort anything.

Self

Abort self and any subtrees running under this node.

Lower Priority

Abort any nodes to the right of this node.

Both

Abort self, any subtrees running under this node, and any nodes to the right of this node.

Cooldown time

The time, in seconds, the Cooldown Decorator should lock the execution of this node.

Node Name

The name the node should display in the Behavior Tree graph.

Custom Decorators



You can create new Decorators with your own custom Blueprint logic and (or) parameters by clicking the New Decorator button.



The following parameters will also be included with your custom logic.

Property

Description

Observer Aborts

None

Do not abort anything.

Self

Abort self and any subtrees running under this node.

Lower Priority

Abort any nodes to the right of this node.

Both

Abort self, any subtrees running under this node, and any nodes to the right of this node.

Show Property Details

Show detailed information about properties on the node.

Node Name

The name the node should display in the Behavior Tree graph.

Inverse Condition

If the result of this Decorator is inversed where false becomes true and true becomes false.

Does Path Exist



The Does Path Exist node checks to see if a path can be made from the two vectors: Blackboard Key A and Blackboard Key B.

Property

Description

Observer Aborts

None

Do not abort anything.

Self

Abort self and any subtrees running under this node.

Lower Priority

Abort any nodes to the right of this node.

Both

Abort self, any subtrees running under this node, and any nodes to the right of this node.

Blackboard Key A

The first location in the path.

Blackboard Key B

The second location in the path.

Path Query Type

NavMesh Raycast 2D

Really Fast

Hierarchical Query

Fast

Regular Path Finding

Slow

Inverse Condition

If the result of this Decorator is inversed where false becomes true and true becomes false.

Filter Class

Which navigation data should be used? If set to None the default navigation data will be used.

Node Name

The name the node should display in the Behavior Tree graph.

Force Success



The Force Success Decorator changes the node result to success.

Property

Description

Node Name

The name the node should display in the Behavior Tree graph.

Is At Location



The Is At Location Decorator node checks if the AI-controlled Pawn is at the given location.

Property

Description

Acceptable Radius

The distance threshold to accept as being at location.

Parametrized Acceptable Radius

A parameter based Acceptable Radius (such as Random Number).

Geometric Distance Type

With Path Finding Based Test disabled, this enables you to set the distance type to 3D, 2D, or Z values.

Use Nav Agent Goal Location

If moving to an Actor and this Actor is a Nav Agent, then we will move to their Nav Agent Goal Location.

Path Finding Based Test

If enabled, the result will be consistent with tests done while following paths. If disabled, use Geometric Distance as configured with Distance Type.

Inverse Condition

If the result of this Decorator is inversed where false becomes true and true becomes false.

Blackboard Key

The Blackboard Key value to test against.

Node Name

The user defined-name of the node.

Is BBEntry Of Class



The Is BBEntry Of Class Decorator node is used to determine if the designated Blackboard Key is of a specified Class.

Property

Description

Observer Aborts

None

Do not abort anything.

Self

Abort self and any subtrees running under this node.

Lower Priority

Abort any nodes to the right of this node.

Both

Abort self, any subtrees running under this node, and any nodes to the right of this node.

Test Class

The Class type that is tested against the Class of the Object of the Blackboard Key property.

Blackboard Key

The Blackboard Key that is tested.

Node Name

The name the node should display in the Behavior Tree graph.

Keep in Cone



The Keep in Cone Decorator node bases its condition on whether the observed position is still inside a cone. The cone's direction is calculated when the node first becomes relevant.

Property

Description

Observer Aborts

None

Do not abort anything.

Self

Abort self and any subtrees running under this node.

Lower Priority

Abort any nodes to the right of this node.

Both

Abort self, any subtrees running under this node, and any nodes to the right of this node.

Cone Half Angle

The half angle of the cone. For example, for a 90-degree cone, this value should be set to 45 degrees.

Cone Origin

The location where the cone should start (the tip of the cone)

Observed

The location or Actor to keep in the cone.

Node Name

The name the node should display in the Behavior Tree graph.

Loop



The Loop Decorator loops the node or branch a number of times, or infinitely.

Property

Description

Num Loops

The number of loops to run.

Infinite Loop

Should this loop run indefinitely?

Infinite Loop Timeout Time

Timeout value if Infinite Loop is enabled (a negative value will loop forever).

Node Name

The name the node should display in the Behavior Tree graph.

Set Tag Cooldown



The Set Tag Cooldown node enables you to set a cooldown duration for a Gameplay Tag.

Property

Description

Cooldown Tag

The GameplayTag that will be used for the Cooldown.

Cooldown Duration

How long the Cooldown is in seconds.

Add to Existing Duration

If there is an existing Cooldown on the given GameplayTag, should we add more?

Node Name

The name the node should display in the Behavior Tree graph.

Tag Cooldown



A Decorator node that bases its condition on whether a cooldown timer from a Gameplay Tag has expired.

Property

Description

Observer Aborts

None

Do not abort anything.

Self

Abort self and any subtrees running under this node.

Lower Priority

Abort any nodes to the right of this node.

Both

Abort self, any subtrees running under this node, and any nodes to the right of this node.

Cooldown Tag

The GameplayTag that will be used for the Cooldown.

Cooldown Duration

How long the Cooldown is in seconds.

Add to Existing Duration

If there is an existing Cooldown on the given GameplayTag, should we add more?

Adds/Sets Cooldown on Deactivation

Whether or not we are adding/setting to the CooldownTag's value when the decorator deactivates.

Node Name

The name the node should display in the Behavior Tree graph.

Time Limit



The Time Limit Decorator will give a branch or node a set amount of time to finish before stopping it and failing out. The timer is reset every time the node gains focus.

Property

Description

Observer Aborts

None

Do not abort anything.

Self

Abort self and any subtrees running under this node.

Lower Priority

Abort any nodes to the right of this node.

Both

Abort self, any subtrees running under this node, and any nodes to the right of this node.

Time Limit

The time limit before the node fails out, in seconds.

Node Name

The name the node should display in the Behavior Tree graph.

Default Focus

Run EQS

Custom Services

Services attach to Composite or Task nodes and will execute at their defined frequency as long as their branch is being executed. These are often used to make checks and to update the Blackboard. These take the place of traditional Parallel nodes in other Behavior Tree systems.

Default Focus



The Default Focus creates a shortcut to accessing an Actor in your Blueprints and Code by setting the focus of the AI Controller. By setting the focus of the AI Controller to an Actor, you can directly access it from the AI Controller instead of accessing a Blackboard key.

Property

Description

Blackboard Key

This takes in an Actor Key (an Object Key with its base class set to Actor) to be quickly referenced by the AI Controller using GetFocusActor.

Node Name

The name the node should display in the Behavior Tree graph.

Run EQS



The Run EQS Service node can be used to regularly execute an Environmental Query System (EQS) template at assigned intervals and can update a specified Blackboard Key.

Property

Description

Query Template

The EQS asset to run.

Query Config

Optional array of additional parameters to include in the query.

EQSQuery Blackboard Key

Option to use a Blackboard Key that stores an EQS Query Template instead of a specified EQS Query Template.

Run Mode

Single Best Item

Pick the first item with the best score.

Single Random Item from Best 5%

Pick a random item with a score 95% to 100% of max.

Single Random Item from Best 25%

Pick a random item with a score 75% to 100% of max.

All Matching

Get all items that match conditions.

Update BBOn Fail

Updates the Blackboard when the EQS query fails.

Blackboard Key

The Blackboard Key the Service will write results into - either an FVector or an Actor.

Interval

Defines the time span between subsequent ticks of the Service.

Random Deviation

Adds a random range value to the Service's Interval value.

Call Tick on Search Start

Call Tick Event when Task search enters this node (Search Start will be called as well).

Restart Timer on Each Activation

If set, the next Tick time will be always reset to Service's Interval value when the node is activated.

Node Name

The name the node should display in the Behavior Tree graph.

Custom Services



You can create Services by clicking the New Service button from the toolbar that contains Blueprint logic and (or) parameters.



Blueprint Services are less performant than C++ Services. If optimization is a concern, you may want to use native Services.

The following properties are also available when creating a Service.

Property

Description

Show Property Details

Shows detailed information about properties when enabled.

Show Event Details

Shows detailed information about implemented Events when enabled.

Node Name

The name the node should display in the Behavior Tree graph.

Interval

Defines the time span between subsequent ticks of the Service.

Random Deviation

Adds a random range value to the Service's Interval value.

Call Tick on Search Start

Call Tick Event when Task search enters this node (Search Start will be called as well).

Restart Timer on Each Activation

If set, the next Tick time will be always reset to Service's Interval value when the node is activated.

Finish With Result

Make Noise

Move Directly Toward

Move To

Play Animation

Play Sound

Push Pawn Action

Rotate to face BB entry

Run Behavior

Run Behavior Dynamic

Run EQS Query

Set Tag Cooldown

Wait

Wait Blackboard Time

Custom Tasks

This is a reference page for the Task nodes available in the Behavior Tree Editor. Tasks are nodes that "do" things, like move an AI, or adjust Blackboard values. They can have Decorators or Services attached to them.

Finish With Result



The Finish With Result Task node can be used to instantly finish with a given result. This node can be used to force a branch to exit or continue based on the defined result.

Property

Description

Result

Succeeded

Finishes with success.

Failed

Finishes with failure.

Aborted

Finishes and aborts.

In Progress

Finishes as in-progress.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Make Noise



If the controlled Pawn has the PawnNoiseEmitter Component, the Make Noise Task will cause the Pawn to "produce a noise" (send a message) that other Pawns with the PawnSensing Component can hear (receive the message).

Property

Description

Loudness

How loud the generated sound is.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Move Directly Toward



The Move Directly Toward Task node moves the AI Pawn toward the specified Actor or Location (Vector) Blackboard entry in a straight line, without regard to any navigation system. If you need the AI to navigate, use the Move To Task node instead.

Property

Description

Acceptable Radius

How close does the Pawn have to be to the target for the Task to succeed.

Filter Class

Which navigation data should be used? If set to None the default navigation data will be used.

Allow Strafe

Whether to enable the AI's ability to strafe while moving towards the destination.

Reach Test Includes Agent Radius

If enabled, the radius of the AI's capsule will be added to the threshold between the AI and the goal location.

Reach Test Includes Goal Radius

If enabled, the radius of the goal's capsule will be added to the threshold between the AI and the goal location.

Allow Partial Path

If enabled, allow the AI to use an incomplete path when the goal cannot be reached.

Track Moving Goal

If enabled, the path to the goal Actor will update itself when the Actor moves.

Project Goal Location

If enabled, the goal location will be projected on the Nav Mesh before using.

Observe Blackboard Value

If the move goal in Blackboard changes, the move will be redirected to the new location.

Blackboard Key

The Key to check. This is most useful for data types that can return None such as Objects, as other types may return their initialized values (for example 0, false, {0,0,0}).

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Move To



A Move To Task will cause a Pawn with a Character Movement component to move using the NavMesh to a Vector Blackboard key.

Property

Description

Acceptable Radius

How close does the Pawn have to be to the target for the Task to succeed.

Filter Class

Which navigation data should be used? If set to None the default navigation data will be used.

Allow Strafe

Whether to enable the AI's ability to strafe while moving towards the destination.

Reach Test Includes Agent Radius

If enabled, the radius of the AI's capsule will be added to the threshold between the AI and the goal location.

Reach Test Includes Goal Radius

If enabled, the radius of the goal's capsule will be added to the threshold between the AI and the goal location.

Allow Partial Path

If enabled, allow the AI to use an incomplete path when the goal cannot be reached.

Track Moving Goal

If enabled, the path to the goal Actor will update itself when the Actor moves.

Project Goal Location

If enabled, the goal location will be projected on the Nav Mesh before using.

Observe Blackboard Value

If the move goal in Blackboard changes, the move will be redirected to the new location.

Blackboard Key

The Key to check. This is most useful for data types that can return None such as Objects, as other types may return their initialized values (for example 0, false, {0,0,0}).

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Play Animation



The Play Animation node can be used to play the specified animation asset.

The animation selected must match the Skeleton of the Pawn the Behavior Tree is controlling.

Property

Description

Animation to Play

Animation asset to play.

Looping

If enabled, the animation will continually loop playback.

Non Blocking

If enabled, the Task will trigger the animation and instantly finish.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Play Sound



The Play Sound node will play the sound given in the Sound to Play property.

Property

Description

Sound to Play

The Sound Cue asset to play.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Push Pawn Action



The Push Pawn Action node enables you to push the specified action to the Pawn's Controller.

Property

Description

Action

The type of action to push to the Pawn's Controller.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Rotate to face BB entry



The Rotate to face BB entry Task causes the associated Pawn to rotate towards the specified Blackboard Key.

The Pawn must have Use Controller Rotation Yaw enabled to successfully rotate.

Property

Description

Precision

The amount in degrees to be considered as a success condition.

Blackboard Key

The Blackboard Key to get the target to turn toward. This can be either a Vector, Object, or Actor.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Run Behavior



The Run Behavior Task enables you to run another Behavior Tree by pushing sub-trees onto the execution stack. One limitation to consider however is that the subtree asset cannot be changed during runtime. This limitation is caused by support for the subtree's Root-level Decorators, which are injected into the Parent tree. Also, the structure of the running tree cannot be modified at runtime.

You can use Run Behavior Tree Dynamic if you need a subtree that can be changed at runtime.

Property

Description

Behavior Asset

The Behavior Tree asset to run.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Run Behavior Dynamic



The Run Behavior Dynamic Task enables pushing subtrees on the execution stack. Subtree Asset can be assigned at runtime with the SetDynamicSubtree function on a Behavior Tree Component.

This does not support a subtree's Root-level Decorator.

Property

Description

Injection Tag

Opens the Gameplay Tag Editor that you can use to identify this Task for subtree injection.

Default Behavior Asset

The initial Behavior Tree asset to run.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Run EQS Query



The Run EQS Query node runs the specified Environment Query System (EQS) asset when the Task node is executed.

Property

Description

Query Template

The EQS asset to run.

Query Config

The additional parameters to include as part of the EQS test.

EQSQuery Blackboard Key

Optional Blackboard Key storing an EQS Query Template to use instead of specifying one under the Query Template.

Run Mode

Single Best Item

Pick the first item with the best score.

Single Random Item from Best 5%

Pick a random item with a score 95% to 100% of max.

Single Random Item from Best 25%

Pick a random item with a score 75% to 100% of max.

All Matching

Get all items that match conditions.

Update BBOn Fail

Updates the Blackboard when the EQS query fails.

Blackboard Key

The Blackboard Key value to update based on the EQS results.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Set Tag Cooldown



Sets a Cooldown Tag value and is used with Cooldown Tag Decorators to prevent Behavior Tree execution.

Property

Description

Cooldown Tag

The GameplayTag that will be used for the Cooldown.

Cooldown Duration

How long the Cooldown is in seconds.

Add to Existing Duration

If there is an existing Cooldown on the given GameplayTag, should we add more?

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Wait



The Wait Task can be used in the Behavior Tree to cause the tree to wait on this node until the specified Wait Time is complete.

Property

Description

Wait Time

How long to wait, in seconds.

Random Deviation

Allows adding a random time (plus or minus) to the Wait Time property.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Wait Blackboard Time



Works just like the Wait Task node, except it will pull a Blackboard value for how long it should wait.

Property

Description

Blackboard Key

The float Blackboard Key to reference how long to wait.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Node Name

The name the node should display in the Behavior Tree graph.

Custom Tasks



You can create new Tasks with your custom Blueprint logic and (or) parameters by clicking the New Task button.



Blueprint Tasks are slower than native Tasks. If you are looking to optimize your content, switch to using native Tasks.

The following parameters will also be included with your custom logic.

Property

Description

Interval

Defines the time span between subsequent ticks of the Task.

Ignore Restart Self

If enabled, Task search will be discarded when this Task is selected to execute but is already running.

Show Property Details

Show detailed information about properties on the node.

Node Name

The name the node should display in the Behavior Tree graph.

Overview

System Inputs

System Outputs

System Execution

UMassMovingAvoidanceProcessor

UMassStandingAvoidanceProcessor

UMassNavigationObstacleGridProcessor

UMassZoneGraphLaneCacheBoundaryProcessor

System Settings

Debugging Mass Avoidance

Visual Logger

Enabling the Visual Logger

Gameplay Debugger

Enabling the Gameplay Debugger

Overview

Mass Avoidance is a force-based avoidance system integrated with MassEntity. The system provides high performance avoidance for any Entity using the MassEntity system.

The system uses the UMassMovingAvoidanceProcessor to process various inputs and outputs a steering force into the FMassForceFragment. This output force is used to steer the Entity away from other entities in the environment.

System Inputs

Input

Description

FMassForceFragment

Represents the force applied to the Entity to steer it away from other Entities.

FMassNavigationEdgesFragment

Provides a list of edges (walls) used for avoidance by the Entity.

FMassMoveTargetFragment

Represents the target destination for the Entity. It also contains additional information, such as forward direction and current status (standing still, moving, etc)

FDataFragment_Transform

Represents the Entity's transform.

FMassVelocityFragment

Represents the Entity's velocity.

FDataFragment_AgentRadius

Represents the Entity's radius.

System Outputs

Output

Description

FMassForceFragment

The final steering force applied to the Entity.

System Execution

UMassMovingAvoidanceProcessor

The UMassMovingAvoidanceProcessor computes the sum of the separation forces and avoidance forces for each Entity. These forces originate from nearby Entities and obstacles.

Other Entities are represented as colliders (see FMassAvoidanceColliderFragment) and can have a capsule or pill shape, used for humans and vehicles respectively. You can adjust several settings to balance the effect of these forces.

Nearby Entities are gathered by using FNavigationObstacleHashGrid2D (owned by the UMassNavigationSubsystem) and only the closest Entities are considered. Obstacles are represented as edges and originate from FMassNavigationEdgesFragment. Avoidance forces are predictive, meaning that their directions are computed from future impact positions. Separation forces are perpendicular forces aiming to keep a loose distance from the environment.

UMassStandingAvoidanceProcessor

The UMassStandingAvoidanceProcessor is a similar version of the processor used when Entities are standing in place.

UMassNavigationObstacleGridProcessor

The UMassNavigationObstacleGridProcessor is used to update the grid position of obstacles into the FNavigationObstacleHashGrid2D.

UMassZoneGraphLaneCacheBoundaryProcessor

The UMassZoneGraphLaneCacheBoundaryProcessor is used in conjunction with ZoneGraph and it builds edges from the current cached lane segments being followed (see the FMassZoneGraphCachedLaneFragment and FMassZoneGraphPathFollowTask).

These edges are added to the FMassNavigationEdgesFragment.

System Settings

The Mass Avoidance settings are stored in FMassMovingAvoidanceParameters and FMassStandingAvoidanceParameters. To see a detailed description of all the settings available, refer to MassAvoidanceFragments.h in your project files.

Debugging Mass Avoidance

You can debug the Mass Avoidance system by using the Visual Logger and the Gameplay Debugger.

Visual Logger

You can use the Visual Logger to display the following categories in the editor:

Category

Description

LogAvoidance

Displays basic information, such as initial and final steering force and current Entity.

LogAvoidanceVelocity

Displays the current velocity and the desired velocity for the Entity.

LogAvoidanceAgents

Displays the obstacle edges, predicted collisions, and the forces associated with the Entities.

Click Tools > Debug > Visual Logger to open the Visual Logger window.



Select the MassSimulationSubsystem track from the list.



Go to Edit > Editor Preferences to open the Editor Preferences window. Click the Visual Logger category and enable the Stick to Recent Data checkbox to display real-time data.



Press the ~ key to open the command line and enter ai.debug.mass.DebugEntity or ai.debug.mass.SetDebugEntityRange to set the Entities that will be displayed while debugging.

Press the Play Settings menu button and click Simulate to see the debug visualizations in the editor.





To learn more about using the Visual Logger, refer to the Visual Logger documentation.

Gameplay Debugger

You can use the Gameplay Debugger to display information such as MoveTarget, Steering, and Colliders for the Entities in the editor.

During gameplay, press the ` key to activate the Gameplay Debugger. Then, press Shift+O to see the Entity Overview, or Shift+V to display avoidance.



Open the GameplayDebuggerCategory_Mass.cpp source file for further information about how to use the Gameplay Debugger with Mass Avoidance.

Basic Concepts

Processing the Entities

MassCommandBuffer

EntityView

Subsystems

MassEntity Manager

Entity Template

Traits

Basic Concepts

MassEntity is a framework for data-oriented calculations available in Unreal Engine 5.

MassEntity's primary data structure is the Fragment, which represents an atomic piece of data used in calculations. Common examples for Fragments include Transform, Velocity and LOD Index. Fragments can be grouped into collections, and an instance of such a collection can be associated with an ID. This collection instance is called an Entity.

Creating an Entity is similar to class instancing in object-oriented programming. However, instead of strictly declaring a class and its functionality, Entities are built by Fragment composition. These compositions can be changed at runtime. For example, an Entity's composition can include two Fragments such as a Transform and a Velocity.

It is important to note that Fragments and Entities are data-only elements which do not contain any logic.

Archetypes are a collection of Entities of identical composition. Each Archetype is composed of different types of Fragments in a specific configuration. For example, an Archetype can have the Fragment composition of [Transform, Velocity]. This means that all Entities associated with this Archetype will have the same Fragment composition.

Entities in an Archetype are organized in memory Chunks. This ensures best performance when retrieving Fragments associated with Entities of the same Archetype from memory.



Processors are stateless classes that supply the processing logic for Fragments. Processors use EntityQuery to specify which types of Fragments they need to perform their operations. EntityQueries provide batches of Fragments to the Processor without regard to individual Entity identifiers.



A Tag is a trivial Fragment that contains no data. The existence or absence of Tags is used as data itself. Tags are part of an Entity's composition.

A ChunkFragment is a Fragment associated with a Chunk, instead of an Entity. ChunkFragments are used to store per-Chunk data used in managerial processing, such as Level of Detail (LOD) calculations. ChunkFragments are part of an Entity's composition.

Processing the Entities

MassCommandBuffer

Processors can change an Entity's composition by adding or removing Fragments or Tags. However, changing the composition of an Entity while it is being processed would result in that Entity being moved from one Archetype to another.

Processors can request a composition change by using the MassCommandBuffer command. These commands are batch-processed at the end of the current processing batch to avoid the issues mentioned above.

EntityView

Serial processing of Fragments is the most efficient way of performing operations on Entities. However, it is sometimes necessary to access other Entities that are not currently being processed. Processors can accomplish this by using the EntityView command.

EntityView provides a safe and optimized way of accessing data of other Entities not currently in the processing queue.

Subsystems

The MassEntity framework is divided into several subsystems for encapsulation and code organization. All of the subsystems are World subsystems, which means their lifetime is bound to that of the World where they were created.

MassEntity Manager

The MassEntity Manager is the most important part of the MassEntity framework. It creates and hosts the Entity Archetypes.

The manager serves as the interface to Entity operations, such as adding and removing Fragments. It is also responsible for moving Entities between Archetypes. Other subsystems can use the MassCommandBuffer command to asynchronously call this functionality.

Entity Template

Entity Templates are generated from data in the MassEntityConfig assets created in the Unreal Engine Editor. These assets can declare a set of Traits that can be added to an Entity during its creation. In addition, MassEntityConfig assets can have a parent asset and inherit Traits from it.

Traits

A Trait is a collective name for Fragments and Processors supplying a given functionality. Any number of Trait instances can be added to an Entity. Each Trait instance is responsible for adding and configuring Fragments in a way that results in the Entity exhibiting the behavior supplied by the Trait. Common examples for Traits include Avoidance behavior, Look-At Target, and using State Tree.

Overview

Subsystems

Mass Representation

Mass Spawner

Mass LOD

Mass (Representation/Visualization) LOD

Mass Simulation LOD

Mass Replication LOD

Mass Replication (Experimental)

Mass StateTree

Mass Signals

Mass Movement

Mass SmartObject

Overview

Mass Entity is a framework for data-oriented calculations available in Unreal Engine. This framework is divided into several plugins responsible for specific functionality within the system.

The Mass Gameplay plugin is derived from the Mass Entity plugin directly, and it includes functionality for in world representation, spawning, Level of Detail (LOD) mechanics, replication, and StateTree.

This document describes the available subsystems in the MassGameplay plugin. Learn more about MassEntity by reading the MassEntity Overview.

Subsystems

Mass Representation

The Mass Representation subsystem is responsible for managing the different visual aspects of the Mass Entities.

For each representation LOD value, the subsystem provides a choice between four types of representation:

A high resolution Actor

A low resolution Actor

An Instanced Static Mesh (ISM)

No representation.

The ISM is the cheapest way of representing the Actor and it can be moved and animated using vertex animation. To learn more about how the ISM Actors are animated, you can download the City Sample from the Unreal Engine Marketplace.

Instanced Static Mesh animation is considered experimental in MassGameplay, as it is not yet fully supported in all use cases.

The subsystem handles the transitions between each representation type and it works directly with the MassActorSpawner subsystem and MassLOD subsystems. In addition, this subsystem can recycle and pool spawned Actors automatically.

Mass Spawner

The Mass Spawner subsystem spawns and manages the Entities based on the MassSpawner objects and procedural calls. This subsystem owns a Mass Entity Template Registry instance that hosts information on available Entity templates.

To start using this subsystem, you create a MassSpawner Actor and place it in your Level. You can specify which Actor type to spawn by adding a Mass Entity Definition Asset, and where to spawn those Actors by adding a Mass Entity Distribution Instance Generator.



Mass LOD

The Mass LOD subsystem calculates the Level Of Detail (LOD) necessary for each Mass Entity.

The system outputs four LOD values: High, Medium, Low, and Off. For each LOD level, you can configure distances at which the level is relevant and a maximum count of Entities per level.

There are three systems that are clients of this subsystem:

Mass (Representation/Visualization) LOD

MassSimulationLOD

MassReplicationLOD

MassLOD can also calculate an LOD significance floating point value from 0.0f (High) up to 3.0f (Off).

Mass (Representation/Visualization) LOD is specifically designed to handle visual LODs. It calculates, not only the LODs from distances, but also whether it is visible or not. You can also provide different LOD distances whether or not the entity is within the camera frustum.

The system groups all entities into different chunks whether they are culled by distance, culled by frustum, or whether they can be seen. The following graphic represents the different groupings:



Mass Simulation LOD is an implementation for load balancing all the entity calculations. The system groups all entities into chunks that have the same LOD, which is useful when using filters on your queries. It also provides the option to give a variable frequency update for all your calculations.

Mass LOD Replication uses the LOD framework to know the relevancy of each entity for replication purposes. Unlike Mass (Representation/Visualization) LOD and Mass Simulation LOD, this system calculates an LOD for each entity per connected client (viewer). This system helps to optimize bandwidth over the network.

Mass Replication (Experimental)

The Mass Replication subsystem replicates entities over the network in a client-server manner. It performs one-way replication from the server to its clients.

This subsystem handles the relevancy and update frequency of entities to limit bandwidth consumption via the Mass Replication LOD system.

Mass Replication is considered experimental for Unreal Engine 5.1. The system requires a C++ implementation to replicate custom values.

Mass StateTree

The Mass StateTree subsystem is used to integrate the StateTree system with Mass Entity. It allows you to configure StateTrees for each entity, and update each entity's StateTree based on signals sent from other Mass systems.

The StateTree logic is only used to configure or set data for the entities, so the right Processors run for specific behaviors.

Mass Signals

The Mass Signal subsystem provides a way to send a named signal to tell an entity it has some processing to do. This subsystem is currently used in Mass StateTree to wake it up when there is some processing to do.

The signal is similar to an event without a payload sent to an entity. Since the Mass framework mostly focuses on a pulling pattern, this subsystem is very useful when you need to update something frequently.

Mass Movement

The Mass Movement subsystem defines a simple movement model for Mass agents. The Fragments and Processors are set up so that other Traits can modify the velocity or force directly. These values are combined to an end movement value used by the Mass agents.

For example, when steering the agent, the system may set the initial steering force, and avoidance can alter it to avoid collisions during movement.

Mass SmartObject

The Mass SmartObject subsystem is used to integrate the SmartObject system with Mass Entity. It provides the required Traits, Fragments, and Processors to perform Smart Object queries and execute simple behaviors on agents represented by MassEntities.

The Unreal Engine Navigation System allows artificial intelligence Agents to navigate the Level using pathfinding.

The system generates a Navigation Mesh from the collision geometry in the Level and divides the mesh into tiles. These tiles are then divided into polygons to form a graph that is used by Agents when navigating to their destination. Each polygon is assigned a cost which Agents use to determine the optimal path with the overall lowest cost.

The Navigation System includes a variety of components and settings that can modify the way the Navigation Mesh is generated, such as the cost assigned to polygons. This, in turn, affects the way Agents navigate through your Level. You can also connect areas of the Navigation Mesh that are not contiguous, such as platforms and bridges.

The Navigation System includes three Generation Modes: Static, Dynamic, and Dynamic Modifiers Only. These modes control the way the Navigation Mesh is generated in your project and provide a variety of options to suit your needs.

The system also provides two methods of avoidance for Agents: Reciprocal Velocity Obstacles (RVO), and the Detour Crowd Manager. These methods allow Agents to navigate around dynamic obstacles and other Agents during gameplay.

In the following guides you will learn about the different components and settings of the Navigation System and how you can use them to create interactive artificial intelligence Agents for your project.

You can download the Navigation System sample project here. It contains sample levels covering the guides below.



This guide shows how to use the Navigation System in Unreal Engine.



Describes the different ways you can modify Navigation Mesh generation in Unreal Engine.



This guide shows how to use Custom Areas and Query Filters with the Navigation System.



This guide shows how to use avoidance with the Navigation System.



This guide shows how to use Navigation Invokers.



A How-To guide on how to optimize the Navigation Mesh generation speed.



An overview of how to use a Navigation Mesh with World Partition.

Overview

Goals

Objectives

1 - Required Setup

Section Results

2 - Building the Navigation Mesh

Section Results

3 - Visualizing the Navigation Mesh

Section Results

4 - Creating your First Agent

Section Results

Overview

The Unreal Engine Navigation System provides pathfinding capabilities to Artificial Intelligence Agents.

To make it possible to find a path between a start location and a destination, a Navigation Mesh is generated from the world's collision geometry. This simplified polygon mesh represents the navigable space in the Level. Default settings subdivide the Navigation Mesh into tiles to allow rebuilding localized parts of the Navigation Mesh.

The resulting mesh is made of polygons and a cost is associated with each polygon. While searching for a path, the pathfinding algorithm will attempt to find an optimal path with the lowest cost to the destination.

The system includes a variety of features that you can use to customize the Agent's navigation behavior based on your specific needs.

Goals

In this Quick Start guide, you will learn how to create a simple Agent that will use the Navigation System to roam around the Level.

Objectives

Use a Navigation Mesh Actor in your Level to build the navigation.

Learn to visualize the navigation mesh in your Level and adjust it to cover your needs.

Modify the ThirdPersonCharacter Blueprint to roam around the Level using the Navigation System.

1 - Required Setup

In the New Project Categories section of the Unreal Project Browser, select Games and the Third Person template.



Select the Blueprint and No Starter Content options and click Create.



Section Results

You have created a new Third Person project and are now ready to learn about the Navigation System.

2 - Building the Navigation Mesh

In this section, you will use a Navigation Mesh Bounds Volume to specify the area in your Level where navigation needs to be generated. This information is used by Agents to navigate the Level and get to their destinations.

On the default ThirdPersonExampleMap of your project, go to the Place Actors panel, search for NavMeshBoundsVolume, and drag it into your Level.



With the NavMeshBoundsVolume selected, go to the Details panel and scale the volume to X = 20, Y= 20, and Z = 5. Move the volume so it covers the entire play area, as seen below.





Select the BP_ThirdPersonCharacter Blueprint in the Outliner window and remove it from the Level.



Press the P key on your keyboard to visualize the Navigation Mesh in your Level. As you can see from the image below, the Navigation Mesh is visualized with the color green by default.

Unreal Engine automatically generates the Navigation Mesh as soon as a Nav Mesh Bounds Volume Actor is added to the Level or is resized.



Notice how the Navigation Mesh contains visual artifacts on the stairs. This can happen because the Navigation Mesh is a simplified representation of the collision in the Level. Select the RecastNavMesh-Default Actor in the Outliner window and go to the Details panel. Go to the Display section and set the Draw Offset value to 50. This adjusts the height offset where the Navigation Mesh is drawn for better readability.



Section Results

In this section, you added a Nav Mesh Bounds Volume Actor to your Level and scaled it to fit the play area. You also learned how to visualize the final Navigation Mesh by pressing the P key.

3 - Visualizing the Navigation Mesh

In this section, you will learn how to modify various Navigation Mesh settings, as well as how to change the way you can visualize the mesh in the Level.

Go to the Outliner and select the RecastNavMesh-Default Actor.



With the Actor selected, go to the Details panel and scroll down to the Display section. Here you will find a variety of options to better visualize the generated Navigation Mesh. In the example below, I selected the Draw Poly Edges to see the polygons that make up the mesh.



You can also visualize the individual Navigation Tiles by enabling the Draw Tile Bounds checkbox.



You can modify the way the Navigation Mesh is generated by going to the Generation section and changing its options.

Section Results

In this section, you learned how to change the Display settings of your Navigation Mesh and how you can influence its generation by adjusting a variety of options.

4 - Creating your First Agent

In this section, you will create a simple Agent that will roam around your Level by selecting a random location nearby and navigating to it. The Agent will wait a few seconds when it arrives at its destination before repeating the process.

In the Content Drawer, right-click and select New Folder to create a new folder. Name the folder NavigationSystem.

In the Content Drawer, go to ThirdPerson > Blueprints and select the BP_ThirdPersonCharacter Blueprint. Drag it to the NavigationSystem folder and select the option Copy Here.



Go to the NavigationSystem folder and rename the Blueprint to BP_NPC_NavMesh. Double-click the Blueprint to open it and go to the Event Graph. Select all input nodes and delete them.

Right-click the Event Graph, then search for and select Add Custom Event. Name the event MoveNPC.



Right-click the Event Graph, then search for and select Get Actor Location.



Drag from the GetActorLocation node and search for and select Get Random Reachable Point In Radius. Set the Radius to 1000 units.



Drag from the Random Location pin of the GetRandomReachablePointInRadius node and select Promote to variable.



Connect the MoveNPC node to the RandomLocation node you just created.



Right-click the Event Graph, then search for and select AI Move To. Connect the RandomLocation node to the AI Move To node.



Right-click the Event Graph and search for and select Get a reference to self.



Connect the Self node to the Pawn pin of the AI Move To node. Connect the yellow pin of the Random Location node to the Destination pin of the AI Move To node, as seen below.



Drag from the On Success pin of the AI Move To node, then search for and select Delay. Set the Duration of the nodeto 4. Drag from the Completed pin of the Delay node, then search for and select MoveNPC, as seen below.



Repeat the steps above to add the nodes to the On Fail pin of the AI Move To node. Set the Duration of the Delay node to 0.1.



Right-click the Event Graph, then search for and select Event Begin Play. Drag from the Event Begin Play node, then search for and select MoveNPC.





Compile and Save the Blueprint.

Drag your BP_NPC_NavMesh Blueprint to your Level and click Simulate. You should see your Agent roam around the Level.





Section Results

In this section, you learned how to create a simple Agent that roams around the Level using the Navigation Mesh.

Unreal Engine's Navigation System provides pathfinding capabilities to Artificial Intelligence Agents. To make it possible to find a path between a start location and a destination, a Navigation Mesh is generated from the world's collision geometry. These guides will teach you how to modify the Navigation Mesh generation in Unreal Engine.

The Preparation Guide will create the sample Level required to follow the Modifying the Navigation Mesh guide. Alternatively, you can download the full sample project, which includes the completed Level named LevelMod_Navigation_0.



This guide covers the preliminary steps needed to learn about modifying the Navigation Mesh.



This guide shows how to modify the Navigation Mesh in Unreal Engine.

Overview

Objectives

1 - Required Setup

Section Results

2 - Creating Your Test Level

Section Results

3 - Creating Your Agent

Section Results

Overview

This document will guide you through the preliminary steps of creating a Level and AI Agent to demonstrate the different ways you can modify the Navigation Mesh.

Alternatively, you can download the full sample project, which includes all the material covered in this guide.

Objectives

Create a simple Level and add navigation by placing a Nav Mesh Bounds Volume Actor in the Level.

Modify the ThirdPersonCharacter Blueprint to roam around the Level using the Navigation System.

1 - Required Setup

In the New Project Categories section of the menu, select Games > Third Person template.



Select the Blueprint and No Starter Content options and click Create.



Section Results

You have created a new Third Person project and are now ready to build a basic Level with a Navigation Mesh.

2 - Creating Your Test Level

Click File > New Level on the Menu Bar.



Select the Basic Level and click Create.



Select the Floor Static Mesh Actor in the Outliner and from the Details panel, set the Scale to X = 10, Y = 10, Z = 1.





Inside the Content Drawer, go to LevelPrototyping > Meshes and drag the TemplateFloor Static Mesh into the Level.



Go to the Place Actors panel and search for Nav Mesh Bounds Volume. Drag it into the Level and place it above the floor mesh.



With the NavMeshBoundsVolume selected, go to the Details Panel and set the Scale to X = 20, Y = 20, Z = 5 to cover the entire floor area. Unreal Engine will automatically generate navigation inside the navigation bounds by default. A Navmesh Actor RecastNavMesh-Default should have also been added to the Level. Press the P key to visualize the Navigation Mesh in the Level.

If no navigation is generated, go to Project Settings > Navigation System and enable the Auto Create Navigation Data checkbox.





Go to the Place Actors panel and under the Shapes category drag the Cube Static MeshActor into your Level.



With the Cube selected, go to the Details Panel and set the Scale to X = 1, Y = 1, Z = 5.





Drag three more Cubes into the level and scale them like the one above. Place them around your floor to create four pillars as seen below.



Next, add a stair and a platform in the middle. Inside the Content Drawer, go to ThirdPerson > Meshes and drag the Linear_Stair_StaticMesh into the Level.



With the stairs selected, go to the Details Panel and set the Scale to X = 1.5, Y = 1, Z = 1.3.



With the stairs selected, drag the mesh while holding the Alt key to duplicate it.



Go to the Place Actors panel and under the Shapes category drag the Cube Static MeshActor into your Level. Go to the Details Panel and set the Scale to X = 14, Y = 4, Z = 0.1. Place the Actor on the edge of the stairs to create a platform, as seen below.



Go to the Place Actors panel and under the Basic category drag the Sphere Static MeshActor into your Level.



With the Sphere selected, go to the Details Panel and from the Collision section, set the Collision Presets to No Collision.



Finally, duplicate the spheres and place them around your Level as shown below.



Section Results

In this section, you created a simple Level and added a Nav Mesh Bounds Volume. You also added five spheres that will serve as target Actors for the Agent.

3 - Creating Your Agent

In this section, you will create an AI Agent that will move between a list of target Actors.

In the Content Drawer, right-click and select New Folder to create a new folder. Name the folder NavigationSystem.

In the Content Drawer, go to ThirdPerson > Blueprints and select the BP_ThirdPersonCharacter Blueprint. Drag it into the NavigationSystem folder and select the option Copy Here.



Go to the NavigationSystem folder and rename the Blueprint to BP_NPC_ModNavMesh. Double-click the Blueprint to open it in the Blueprint Editor and go to the Event Graph. Select all input nodes and delete them.

Right-click the Event Graph, then search for and select Add Custom Event. Name the event MoveNPC.



Go to the My Blueprint panel and click the Add (+) button next to Variables to create a new variable. Name the variable TargetList.



Go to the Details panel and click the dropdown next to Variable Type. Search for and select Actor > Object Reference.



Click the blue sphere icon next to the Actor selection and click the Array option, as shown below. Click the Instance Editable checkbox to enable it.





Drag the TargetList variable to the Event Graph and select the option Get TargetList.

Drag from the TargetList node, then search for and select Last Index.



Drag from the TargetList node and search for and select Get (a copy).



Drag from the green pin of the Get node, then search for and select Random Integer in Range. Connect the green pin of the Last Index node to the Max pin of the Random Integer in Range node, as seen below.





Drag from the Get node, then search for and select Promote to variable. Name the variable CurrentTarget and connect it to the MoveNPC node.





Drag from the CurrentTarget node, then search for and select Is Valid. Connect the IsValid macro node to the Set CurrentTarget node.





Drag the CurrentTarget variable to the Event Graph, then select Get Current Target. Drag from the CurrentTarget node, then search for and select Get Actor Location.



Drag from the Return Value of the GetActorLocation node, then search for and select Get Random Reachable Point In Radius. Set the Radius value to 100.





Drag from the Random Location pin of the GetRandomReachablePointInRadius node and select Promote to variable. Name the variable RandomLocation. Connect the RandomLocation node to the IsValid node as shown below.





Drag from the RandomLocation node, then search for and select AI MoveTo.



Drag from the Pawn pin of the AI MoveTo node, then search for and select Get a reference to self. Connect the yellow pin of the RandomLocation node to the Destination pin of the AI MoveTo node. Finally, set the Acceptance Radius of the AI MoveTo node to 50, as seen below.





Drag from the On Success pin of the AI Move To node, then search for and select Delay. Set the Duration of the nodeto 4. Drag from the Completed pin of the Delay node, then search for and select MoveNPC, as seen below.



Repeat the steps above to add the nodes to the On Fail pin of the AI Move To node. Set the Duration of the Delay node to 0.1.



Right-click the Event Graph, then search for and select Event Begin Play. Drag from the Event Begin Play node, then search for and select MoveNPC.





Compile and Save the Blueprint.

Drag your BP_NPC_ModNavMesh Blueprint into your Level and under the Details panel find the Target List and click the Add (+) button to add a new target Actor.





Click the dropdown, then search for and select the Sphere Actor you created earlier.



Repeat the step above to add the remaining four Sphere Actors.



Click Simulate to see your Agent roam between goals in your Level.



Section Results

In this section, you created an Agent that roams between a list of target Actors. You can now move on to learning about Modifying the Navigation System.

Overview

Goals

Objectives

1 - Required Setup

2 - Using Navigation Modifier Volumes

Section Results

Available Nav Modifier Volume Area Classes

3 - Using Navigation Link Proxies

Section Results

Using a Nav Link Proxy to Allow Your Agent to Fall from a Platform

Section Results

Using a Nav Link Proxy to Allow Your Agent to Jump to Its Goal

Section Results

4 - Generating the Navigation Mesh at Runtime

Using the Runtime Generation (Dynamic Modifiers Only)

Section Results

Using the Runtime Generation (Dynamic)

Section Results

Overview

Unreal Engine's Navigation System provides pathfinding capabilities to Artificial Intelligence Agents. To make it possible to find a path between a start location and a destination, a Navigation Mesh is generated from the world's collision geometry.

Default settings subdivide the Navigation Mesh into tiles to allow localized parts of the Navigation Mesh to be rebuilt. The resulting mesh is made of polygons with a cost assigned to each polygon. While determining the optimal path, the pathfinding algorithm will attempt to determine the path with the lowest cost to the destination.

The Navigation System includes a variety of components and settings that modify the way the Navigation Mesh is generated, including the cost of polygons. This, in turn, affects the way Agents navigate through your Level.

Goals

In this Quick Start guide, you will learn how to modify the Navigation Mesh using Navigation Modifier Volumes, Navigation Proxy Links, and Blueprint Actors that affect navigation at runtime.

Objectives

Use Navigation Modifier Volumes to alter the Navigation Mesh cost in specific areas

Use Navigation Proxy Links to create connections between two areas that are otherwise inaccessible

Use Smart Proxy Links to allow your Agents to jump between platforms toward their goal

Create moving Blueprint Actors to learn how the Navigation Mesh can be regenerated dynamically at runtime

1 - Required Setup

Follow the Modifying the Navigation System preparation guide or download the full sample project and open the LevelModNavigation_0 Levelbefore proceeding to the next section.

2 - Using Navigation Modifier Volumes

A Navigation Modifier Volume applies a Navigation Area Class to the Navigation Mesh using a volume shape. This can be used to change the properties of the polygons within the volume space to modify their traversal cost.

The polygon properties are defined by the appropriate Area Class of the Navigation Modifier Volume. This class determines the effect on the Navigation Mesh. You can use the built-in classes to modify the mesh or create your custom implementations.

You will now start by using the built-in classes to modify the Navigation Mesh in your Level.

Go to the Place Actors panel and search for Nav Modifier Volume. Drag the Nav Modifier Volume Actor into your Level. Notice that by default, no Navigation Mesh is generated inside the volume.



Move and scale the volume to cover the area shown below. Notice how you are now forcing the Agent to reach the bottom sphere by moving around the volume on the left side of the Level. This area could represent any obstacle the Agent is not allowed to cross in your game.



Repeat the step above and create another area on the opposite side of the map. When you scale the volume, leave space on both sides for the Agent to navigate.



Drag another Nav Modifier Volume into your Level. Navigate to the Details panel and click the dropdown next to Area Class. Select the NavArea_Obstacle class from the list. This built-in class assigns the area inside the volume a higher cost of navigation compared to the default value (NavArea_Default in green). This will cause your Agent to avoid the area unless it cannot find a cheaper path to its destination.





Duplicate the volume twice to form the following shape around the sphere. This will force the Agent to navigate around the volumes to reach the sphere.



If you completely block the area around the sphere with another volume, the Agent will still reach its destination because the volumes represent a valid path. In contrast, if you were to change the Area Class of the volumes to NavArea_Null, the Agent will not be able to reach its destination as it will not be able to find a suitable path to its target. This is because the NavArea_Null applies an infinite cost which causes the Navigation Mesh to not be generated in the affected area.

Click Simulate and notice how your Agent moves between the spheres. This illustrates how your changes have affected the way the Navigation Mesh was generated.



Section Results

In this section, you learned how to use Nav Modifier Volumes to change the way the Navigation Mesh is generated. You also learned about some of the built-in Area Classes available in Unreal Engine.

Available Nav Modifier Volume Area Classes

Area Class

Description

NavArea_Default

Assigns the same navigation cost to the area inside the volume and the Navigation Mesh by default.

NavArea_LowHeight

Represents an area that matches the conditions for traversal with a low height that prevents an Agent from traversing it. The Navigation Mesh will not generate navigation data inside this volume.

NavArea_Null

Represents an empty area inside the volume. The Navigation Mesh will not generate navigation data inside this volume.

NavArea_Obstacle

Assigns a high navigation cost to the area inside the volume.

3 - Using Navigation Link Proxies

Navigation Link Proxies connect two areas of the Navigation Mesh that don't have a direct navigation path. While a path is being searched, Navigation Link Proxies are used as extra connections that Agents can use to reach their destination.

Navigation Link Proxies are commonly used to build bridges between areas with separate Navigation Meshes and to instruct Agents that they can fall or jump from a platform towards their goal when there is no continuous navigation path available.

Creating Bridges to Connect Two Areas

Select the first Nav Modifier Volume and resize it so it covers the entire length of the floor, as seen below. This blocks the Agent from reaching the bottom sphere in the Level.



Go to the Place Actors panel and drag a Cube Actor into the Level. Scale it to X = 4, Y = 1, Z =0.2 and place it as shown below.



Duplicate the cube and move it to the other side of the Level, as shown below.



These Cube Actors serve as a visual representation of the Navigation Link Proxies in the Level. You are not required to use them in conjunction with Navigation Link Proxies.

Go to the Place Actors panel and search for Nav Link Proxy. Drag the Nav Link Proxy Actor into your Level.



With the Nav Link Proxy selected, click the PointLinks[0].Left handle and move it so it's placed on one side of the mesh. Click the PointLinks[0].Right handle and move it so it's placed on the opposite side of the mesh, as shown below.

The green arrow will disappear if the Nav Link Proxy doesn't connect with the surface of the Navigation Mesh.



Now that you have created a connection, the Agent will be able to navigate through the Nav Link Proxy, even though there is no navigation data in between.

With the Nav Link Proxy selected, go to the Details panel and expand the section labeled 0 under Point Links to find the Direction dropdown. You can choose to have the Direction be Both Ways, Left to Right, or Right to Left. For this example, select Left to Right.



Duplicate the Nav Link Proxy and move it to the other side of the level. For this example, set the Direction to Right to Left.



Click Simulate and notice how your Agent can now reach the sphere by entering from the left side and exiting from the right side.



Section Results

You used Nav Link Proxies to connect two areas of the Navigation Mesh that did not have a viable path. You also learned that you could configure the Nav Link Proxies to have different directions, such as Both Ways, Left to Right, or Right to Left.

Using a Nav Link Proxy to Allow Your Agent to Fall from a Platform

Drag another Nav Link Proxy into your Level and place it at the end of the raised platform, as seen below.



Select the PointLinks[0].Left and place it at the platform's edge and select the PointLinks[0].Right and place it at the bottom overlapping the floor.



Navigate to the Details panel, expand the section labeled 0 under Point Links and select Left to Right as the Direction.



Click Simulate and notice how your Agent is now able to fall from the platform to reach its goal.



In this section, you used a Nav Link Proxy to allow your Agent to fall from a platform to reach its goal.

Using a Nav Link Proxy to Allow Your Agent to Jump to Its Goal

In this section, you will learn how to use a Smart Link on a Nav Link Proxy to allow your Agent to jump from one platform to another.

Select the platform mesh and drag it while holding the Alt key to the side to duplicate it.



Resize the new platform and move it higher, as shown below.



Duplicate a Sphere Actor and place it on top of the platform.



Inside the Content Drawer, right-click and select Blueprint Class from the Create Basic Asset section.



Inside the Pick Parent Class window, go to the All Classes section and expand the arrow. Search for and select Nav Link Proxy and click Select. Name the Blueprint BP_NavProxyLink.





Open BP_NavProxyLink by double-clicking it. Inside the Event Graph, right-click then search for and select Event Receive Smart Link Reached.



Drag from the Agent pin of the Event Receive Smart Link Reached node then search for and select Cast to Character.



Drag from the As Character pin of the Cast to Character node and select Promote to variable.



Drag from the execution pin of the As Character node then search for and select Suggest Projectile Velocity Custom Arc.



Drag from the blue pin of the As Character node then search for and select Get Actor Location. Connect the Return Value pin of the Get Actor Location node to the Start Pos pin of the SuggestProjectileVelocityCustomArc node.



Drag from the Destination pin of the Event Receive Smart Link Reached node and connect it to the End Pos pin of the SuggestProjectileVelocityCustomArc node.



Drag the As Character variable into the Event Graph and select Get As Character. Drag from the node then search for and select Launch Character. Enable the XYOverride and ZOverride checkboxes.



Drag from the SuggestProjectileVelocityCustomArc node then search for and select Delay. Set the Duration to 0.1. Connect the Completed pin of the Delay node to the Launch Character node.



Drag from the Out Launch Velocity pin of the SuggestProjectileVelocityCustomArc node then search for and select vector * float.



Connect the yellow pin of the Multiplication node to the Launch Velocity pin of the Launch Character node. Right-click the green pin of the Multiplication node and select Promote to variable.



With the New Var 0 node selected, go to the Details panel and rename the variable to JumpBoost. Set the default value to 1. Enable the Instance Editable checkbox, as shown below.



Compile and Save your Blueprint.



Select the BP_NPC_ModNavMesh character in your Level and under the Details panel, click on the Add (+) button next to Target List to add a new entry. Search for and select the last Sphere Actor you added to the platform.



Drag the BP_NavProxyLink Blueprint Actor onto the platform and adjust the connections, as seen below.



With the BP_NavProxyLink Blueprint Actor selected, go to the Details panel and click the Copy End Points from Simple Link to Smart Link button. Enable the Smart Link Is Relevant checkbox.



Click Simulate and watch as your Agent can now jump to reach the last sphere.



Nav Link Proxies can only connect adjacent Navigation Mesh tiles. You can visualize the tiles by selecting the RecastNavMesh-Default Actor and enabling the Draw Tile Bounds checkbox.

Section Results

In this section you learned how to create a custom Nav Proxy Link Blueprint and how it can be used to get your Agent to jump to a platform.

4 - Generating the Navigation Mesh at Runtime

Unreal Engine comes with three Navigation Mesh generation modes:

Generation Mode

Description

Static

The Navigation Mesh is generated offline and is saved with the Level. The Navigation Mesh is loaded at runtime and cannot change.

Dynamic

The Navigation Mesh is generated offline and is saved with the Level or built at runtime. At runtime, the navigation-relevant data used by the Navigation Mesh can be updated and the generation is performed on the tiles affected by the change in the data.

Dynamic Modifiers Only

The Navigation Mesh is generated offline and is saved with the Level. At runtime, only Navigation Modifiers such as Navigation Areas, Navigation Links, and dynamic objects, can modify the existing Navigation Mesh by changing the cost or block areas. No new Navigation Mesh surfaces are generated at runtime.

This method allows the Navigation Mesh to cache collision data and can result in up to 50% cheaper processing of the affected tiles.

Advanced users should use this mode after careful consideration of its benefits and limitations.

By default, the Navigation Mesh is configured to be Static. However, you can set your Navigation Mesh generation to one of the dynamic modes so it can change at runtime.

Using the Runtime Generation (Dynamic Modifiers Only)

To change the Runtime Generation settings, go to Settings > Project Settings on the menu bar.



Go to the Navigation Mesh settings and under the Runtime section, click the Runtime Generation dropdown. Select Dynamic Modifiers Only for this example.



Inside the Content Drawer, right-click and select Blueprint Class under the Create Basic Asset section.



Select the Actor class under the Common section. Name the Blueprint BP_RotatingActor.





Double-click the BP_RotatingActor Blueprint to open it. Click the +Add dropdown, then search for and select Cube. Scale the Cube to X = 4, Y = 1.5, Z = 1.





Click the +Add dropdown, then search for and select Rotating Movement.



Compile and Save the Blueprint.

Drag the BP_RotatingActor Blueprint Actor into your Level and click Simulate. Notice how the Navigation Mesh does not update with the rotating mesh. This is because the Dynamic Modifier Only Runtime Generation mode will only work if the Actor has a NavModifier component.



Go back to the BP_RotatingActor Blueprint and click the +Add dropdown. Search for and select Nav Modifier.



Compile and Save the Blueprint. Click Simulate to see the difference. You should now see the Navigation Mesh correctly updating as the mesh rotates in the Level.

Notice how no new Navigation Mesh is being generated in the Level (the tiles being generated are displayed in red). The Navigation Modifier is simply changing the existing Navigation Mesh.



Section Results

In this section, you learned how to make the Navigation Mesh regenerate during gameplay by using the Runtime Generation Dynamic Modifiers Only. You also tested the results using a simple rotating Blueprint Actor with the NavModifier component.

Using the Runtime Generation (Dynamic)

Inside the Content Drawer, right-click and select Blueprint Class from the Create Basic Asset section.



Select the Actor class under the Common section. Name the Blueprint BP_MovingActor.





Double-click the BP_MovingActor Blueprint to open it. Click the +Add dropdown, then search for and select Sphere. Scale the Sphere to X = 2, Y = 2, Z = 2.



In the Event Graph, right-click, then search for and select Add Custom Event. Name the event MoveForward. Repeat these steps and create another event named MoveBackwards.





Drag from the MoveForward node then search for and select Add Timeline. Name the Timeline TM_MoveObject. Connect the MoveBackwards node to the Reverse pin of the TM_MoveObject node.





Double-click the TM_MoveObject node to open it. Click the +Track button to create a new Float Track. Name the track Alpha.





Right-click inside the graph and select Add key to CurveFloat_1. Enter Time = 0 and Value = 0.





Repeat the previous step and enter Time = 5, Value = 1.

Drag the Sphere component into the Event Graph to create a node. Drag from the Sphere node, then search for and select Set Relative Location.



Connect the Update pin of the TM_MoveObject node to the SetRelativeLocation node. Right-click the New Location pin of the SetRelativeLocation node and select Split Struct Pin.



Drag from the New Location X pin of the SetRelativeLocation node, then search for and select Lerp. Connect the Alpha pin of the TM_MoveObject node to the Alpha pin of the Lerp node.





Right-click the B pin of the Lerp node and select Promote to Variable. Go to the Details panel and name the variable Distance. Select the Instance Editable checkbox.





Compile and Save the Blueprint. Set the default value for Distance to 1000.

Drag from the Finished pin of the TM_MoveObject Timeline, then search for and select Delay. Set the Duration to 1.



Drag from the Completed pin of the Delay node and search for and select Branch.



Right-click the Condition pin of the Branch node and select Promote to Variable. Go to the Details panel and rename the variable to Forward.





Drag the Forward variable to the Event Graph and select Set Forward. Connect the True pin of the Branch to the Set Forward node. Drag from the Set Forward node, then search for and select Move Backwards.



Drag the Forward variable to the Event Graph and select Set Forward. Connect the False pin of the Branch to the Set Forward node. Enable the Forward checkbox of the Set Forward node. Drag from the Set Forward node, then search for and select Move Forward.



Right-click in the Event Graph, then search for and select Event Begin Play. Drag from the Event Begin Play node, then search for and select Move Forward.





Compile and Save your Blueprint. You can see the completed Blueprint below.



Drag the BP_MovingActor Blueprint Actor into your Level and click Simulate. Notice how the Navigation Mesh does not update with the Actor's movement.



Click Settings > Project Settings and go to the Navigation Mesh settings.



Under the Runtime section, click the Runtime Generation dropdown and select Dynamic.



Go back to the Level and click Simulate. You should now see the Navigation Mesh update correctly.

The examples used in this section force the constant runtime generation of the Navigation Mesh which has a high computational cost. These examples do not represent best practices and are used for demonstration purposes only.







Section Results

In this section, you learned that you can make the Navigation Mesh regenerate during gameplay using the Dynamic Runtime Generation setting. You also tested the results by creating a Blueprint that moves a Sphere mesh in the Level and forces constant Navigation Mesh regeneration.

Unreal Engine's Navigation System allows Agents to traverse the Level using a Navigation Mesh for pathfinding.

The Agent determines the most optimal route to its destination by comparing the cost of each navigation polygon within the Navigation Mesh. If all polygons along the route are of equal cost, then the Agent will choose the shortest path to its target (usually a straight line).

You can influence the cost of the navigation polygons using Navigation Modifier Volumes and Navigation Query Filters.

The Preparation Guide will create the sample Level required to follow the Custom Navigation Areas and Query Filters guide. Alternatively, you can download the full sample project, which includes the completed Level named LevelCustomZones.



This guide covers the preliminary steps needed to learn about Custom Navigation Areas and Query Filters.



This guide shows how to use Custom Areas and Query Filters with the Navigation System.

Overview

Objectives

1 - Required Setup

Section Results

2 - Creating Your Test Level

Section Results

3 - Creating Your Agent

Section Results

Overview

This document will guide you through the preliminary steps of creating a Level and AI Agent to learn about the Custom Areas and Query Filters in the Navigation System.

You can also download the full sample project, which includes all the material covered in this guide.

Objectives

Create a new Level and set up navigation by placing a Navigation Mesh Actor in the Level.

Modify the ThirdPersonCharacter Blueprint to navigate toward its target by using specific Query Filters.

1 - Required Setup

In the New Project Categories section of the Unreal Project Browser, select Games > Third Person template.



Select the Blueprint and No Starter Content options and click Create.



Section Results

You have created a new Third Person project and are now ready to learn about creating Area Classes and Navigation Query Filters.

2 - Creating Your Test Level

Click File > New Level on the Menu Bar.



Select the Basic Level and click Create.



Select the Floor Static Mesh Actor in the Outliner and on the Details panel, set the Scale to X = 10, Y = 10, Z = 1.





Go to the Place Actors panel and search for NavMeshBoundsVolume. Drag it into the Level and place it on the floor mesh.



With the NavMeshBoundsVolume selected, go to the Details panel and set the Scale to X = 5, Y = 10, Z = 1.



Go to the Place Actors panel and go to the Shapes category. Drag a Sphere Actor into the Level.



Section Results

In this section, you created a new Level and added a Navigation Mesh and a Sphere Actor. You are now ready to create an Agent that will walk toward the sphere goal.

3 - Creating Your Agent

In this section, you will create an Agent that navigates to its target Actor.

In the Content Drawer, right-click and select New Folder to create a new folder. Name the folder NavigationSystem.

In the Content Drawer, go to ThirdPersonBP > Blueprints and select the BP_ThirdPersonCharacter Blueprint. Drag it to the NavigationSystem folder and select the option Copy Here.



Navigate to the NavigationSystem folder and rename the Blueprint to BP_NPC_CustomZone. Double-click the Blueprint to open it and go to the Event Graph. Select all input nodes and delete them.

Right-click the Event Graph, then search for and select Add Custom Event. Name the event MoveNPC.



Go to the My Blueprint panel and click the Add (+) button next to Variables to create a new variable. Name the variable Target.



Go to the Details panel and click the Variable Type dropdown. Search for Actor and select the Object Reference. Enable the Instance Editable checkbox.





Drag the Target variable to the Event Graph and select the option Get Target. Drag from the Target node, then search for and select the Is Valid macro, as shown below.



Right-click the Event Graph, then search for and select Get reference to self.



Drag from the Self node, then search for and select Get AIController.



Drag from the AI Controller node, then search for and select Move to Actor.



Connect the Is Valid pin of the Is Valid node to the Move to Actor node. Set the Acceptance Radius of the Move to Actor node to 50. Drag the Target variable and connect it to the Goal pin of the Move to Actor node.



Right-click the Filter Class pin of the Move to Actor node and select Promote to Variable. Go to the Details panel and enable the Instance Editable checkbox.





Right-click the Event Graph, then search for and select Event Begin Play. Drag from the Event Begin Play node and search for and select MoveNPC.





Compile and Save the Blueprint. The final Blueprint should look like the image below.



Drag the BP_NPC_CustomZone Blueprint into your Level. Navigate to the Details panel and click the dropdown next to Target. Search for and select Sphere, as seen below.





Press Simulate and watch as your Agent moves toward the Sphere.



Section Results

In this section, you created an Agent that navigates toward its goal and can use a Navigation Query Filter. You are now ready to learn about adding Custom Navigation Areas and Query Filters.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Custom Navigation Areas and Query Filters Preparation Guide

Overview

Goals

Objectives

1 - Creating Custom Area Classes

Section Results

2 - Creating Navigation Query Filters

Section Results

Overview

Unreal Engine's Navigation System allows Agents to traverse the Level using a Navigation Mesh for pathfinding.

The Agent determines the most optimal route to its destination by comparing the cost of each navigation polygon within the Navigation Mesh. If all polygons along the route are of equal cost, then the Agent will choose the shortest path to its target (usually a straight line).

You can influence the cost of the navigation polygons using Navigation Modifier Volumes and Navigation Query Filters.

Navigation Modifier Volumes use Area Classes to determine the Default Cost multiplier of navigation within the volume. Area Classes also define the Fixed Area Entering Cost, which is the initial cost applied when the Agent enters the area. You can create as many Area Classes as needed to influence how your Agents navigate your Level.

Navigation Query Filters contains information about one or more Area Classes and can override the cost values if needed. You can create as many Query Filters as needed to further customize how your Agents navigate your Level.

Goals

In this Quick Start Guide, you will learn to create and use your Navigation Areas and Query Filters to influence how different Agents traverse the same Navigation Mesh toward their targets.

Objectives

Create three custom Area Classes to use with Navigation Modifier Volumes.

Create two Navigation Query Filters to be used by Agents.

1 - Creating Custom Area Classes

Go to the Place Actors panel and search for Nav Modifier Volume. Drag the Nav Modifier Volume Actor into your Level and place it on the Floor mesh. Go to the Details panel and set the Scale to X = 2, Y = 6, Z = 1.





Inside the Content Drawer, right-click and select Blueprint Class under the Create Basic Asset section.



Inside the Pick Parent Class window, go to the All Classes section and expand the arrow. Search for and select Nav Area. Click Select and name the Blueprint BP_Area_Neutral.





Repeat the previous two steps twice and name these Blueprints BP_Area_Lane1 and BP_Area_Lane2.

Double-click the BP_Area_Lane1 Blueprint to open it. You can modify the Default Cost multiplier when navigating inside the volume and the Fixed Area Entering Cost. For this example, leave the settings at their default values.

Click the Draw Color bar and select a blue color. Compile and Save.



Repeat the step above for the BP_Area_Lane2 Blueprint and change its Draw Color to red.

Select the Nav Modifier Volume in your Level, and on the Details panel, click the Area Class dropdown and select BP_Area_Neutral.





Duplicate the Nav Modifier Volume and follow the steps above to change the Area Class to BP_Area_Lane1. Move the volume to the side to create a lane as seen below.



Repeat the previous step to duplicate the Nav Modifier Volume and set the Area Class to BP_Area_Lane2. Move the volume to the side to create a lane as seen below.



You can now experiment by changing the values of each Area Class to influence the Agent's path to its target. In the example below, the Default Cost of BP_Area_Neutral and BP_Area_Lane1 are both set to 4.



In this example, the Default Cost of BP_Area_Neutral and BP_Area_Lane2 are both set to 4.



Section Results

In this section, you created three custom Area Classes and placed them in your Level. You also changed the Default Cost values of these Area Classes to influence the Agent's navigation towards its target.

2 - Creating Navigation Query Filters

Inside the Content Drawer, right-click and select Blueprint Class under the Create Basic Asset section.



Inside the Pick Parent Class window, go to the All Classes section and expand the arrow. Search for and select Navigation Query Filter. Click Select and name the Blueprint BP_QueryFilter1.





Double-click the BP_QueryFilter1 Blueprint to open it. Click on the Add (+) button next to the Areas section to expand it.



Click the dropdown next to Area Class and search for and select BP_Area_Neutral. Enable the Travel Cost Override checkbox and enter 100.





Repeat the previous step to add BP_Area_Lane1 and BP_Area_Lane2 to the list. For BP_Area_Lane2, enable the Travel Cost Override checkbox and enter 100.



In the Content Drawer, right-click the BP_QueryFilter1 Blueprint and select Duplicate.

Double-click the BP_QueryFilter2 Blueprint to open it. For the Area Class BP_Area_Lane1, enable the Travel Cost Override checkbox and set its value to 100. For the Area Class BP_Area_Lane2, disable the Travel Cost Override checkbox.



Compile and Save the Blueprint.

Select the BP_NPC Blueprint in your Level and on the Details panel, click the Filter Class dropdown, then search for and select BP_QueryFilter1.



Click Simulate and observe how the Agent is now using the Navigation Query Filter to determine the best route to its destination. Since BP_QueryFilter1 has the BP_Area_Lane1 as the cheapest route, the Agent uses it to reach the Sphere.



Select the BP_NPC Blueprint and change the Filter Class to BP_QueryFilter2. Click Simulate and observe how the Agent now uses BP_Area_Lane2 area to reach its destination.



Section Results

In this section, you created two Navigation Query Filters and added the three previous Area Classes. You also changed the cost values associated with the Area Classes to modify the Agent's navigation when using different Navigation Query Filters.

Overview

High-Level Comparison of Avoidance Methods

Goals

Objectives

1 - Required Setup

Section Results

2 - Creating Your Test Level

Section Results

3 - Creating Your Agent

Section Results

4 - Adding Reciprocal Velocity Obstacles Avoidance to Your Agent

Section Results

5 - Adding Detour Crowd Avoidance to Your Agent

Section Results

Overview

Unreal Engine's Navigation System allows Agents to traverse the Level using a Navigation Mesh for pathfinding.

While pathfinding can determine a path around objects that don't move, avoidance algorithms are better suited to handle moving obstacles. There are two methods of avoidance the Agents can use to navigate around dynamic obstacles and each other, Reciprocal Velocity Obstacles (RVO) and Detour Crowd Manager.

The Reciprocal Velocity Obstacles (RVO) system calculates the velocity vectors for each Agent to avoid a collision with nearby Agents. This system looks at the nearby Agents and assumes they are traveling with a constant velocity within each time step of the calculation. The optimal velocity vector chosen is the closest match to the Agent's preferred velocity in the direction of its target.

Unreal Engine's implementation of RVO includes optimizations to reduce frame rate dependencies. It also includes improvements to avoid constant path recalculation and a priority system to help resolve potential collisions. RVO does not use the Navigation Mesh for avoidance, so it can be used separately from the Navigation System for any Character. The system is included in the Character Movement component of the Character class.

The Detour Crowd Manager system handles avoidance between Agents by using an adaptive RVO sampling calculation. It does this by calculating a coarse sample of velocities with a bias toward the Agent's direction that allows for a significant improvement in the quality of the avoidance over the traditional RVO method. This system also uses visibility and topology path corridor optimizations to further improve collision avoidance.

The Detour Crowd Manager system is highly configurable with options to specify sampling patterns, the maximum number of Agents, and Agent Radius. The system is included in the DetourCrowd AI Controller class and can be used with any Pawn class.

Both systems work independently and should be used exclusively in your project.

High-Level Comparison of Avoidance Methods

Method

Description

Limitations

Reciprocal Velocity Obstacles

Agents avoid obstacles by using velocity vectors within a specified radius.

Included in the Character Movement component of the Character class.

Less configurable compared to the Detour Crowd Manager.

Limited to the Character class.

Does not use the Navigation Mesh for avoidance so Agents can potentially go "out of bounds".

Detour Crowd Manager

Agents avoid obstacles by using path optimizations along with velocity vectors within a specified radius.

Included in the DetourCrowd AI Controller class. | Has a fixed maximum number of Agents defined in the project settings.

Has a fixed maximum number of Agents defined in the project settings.

Goals

In this guide, you will learn how to use the Reciprocal Velocity Obstacles and Detour Crowd avoidance methods by comparing the behavior of several Agents interacting with each other.

Objectives

Modify the ThirdPersonCharacter Blueprint so it navigates toward a target.

Modify the Agent Blueprint to use RVO avoidance.

Modify the Agent Blueprint to use Crowd Detour avoidance.

1 - Required Setup

In the New Project Categories section of the Unreal Project Browser, select Games > Third Person template.



Select the Blueprint and No Starter Content options and click Create.



Section Results

You created a new Third Person project and are now ready to learn about the avoidance methods available in Unreal Engine.

2 - Creating Your Test Level

Click File > New Level on the Menu Bar.



Select the Default Level.



Select the Floor Static Mesh Actor in the Outliner and under the Details panel, set the Scale to X = 10, Y = 10, Z = 1.





Go to the Place Actors panel and search for NavMeshBoundsVolume. Drag it into the Level and place it on the floor mesh. Scale the NavMeshBoundsVolume to X = 7, Y=10, Z = 1.





Go to the Place Actors panel and from the Shapes category, drag two Sphere Actors into the Level.



Section Results

In this section, you created a new Level and added a Navigation Mesh. You also added two Sphere Actors that will serve as targets for your Agents.

3 - Creating Your Agent

In the Content Drawer, right-click and select New Folder to create a new folder. Name the folder NavigationSystem.

In the Content Drawer, go to ThirdPerson > Blueprints and select the BP_ThirdPersonCharacter Blueprint. Drag it into the NavigationSystem folder and select the option Copy Here.



Navigate to the NavigationSystem folder and rename the Blueprint to BP_NPC_NoAvoidance. Double-click the Blueprint to open it and go to the Event Graph. Select all input nodes and delete them.

Right-click the Event Graph, then search for and select Add Custom Event. Name the event MoveNPC.



Go to the My Blueprint panel and click the Add (+) button next to Variables to create a new variable. Name the variable Target.



Go to the Details panel and click the Variable Type dropdown. Search for Actor and select the Object Reference. Enable the Instance Editable checkbox.





Drag the Target variableinto the Event Graph and select Get Target. Drag from the Target node, then search for and select the Is Valid macro, as shown below.



Right-click the Event Graph, then search for and select Get reference to self.



Right-click the Event Graph, then search for and select AI Move To.



Connect the Is Valid pin of the Is Valid node to the AIMoveTo node. Connect the Self node to the Pawn pin of the AIMoveTo node. Drag the Target variable and connect it to the Target Actor pin of the AIMoveTo node.



Right-click the Event Graph, then search for and select Event Begin Play. Drag from the Event Begin Play node, then search for and select MoveNPC.





Compile and Save the Blueprint. The final Blueprint should look like the image below.



Drag the BP_NPC_NoAvoidance Blueprint into your Level and from the Details panel, click the dropdown next to Target, then search for and select the Sphere Actor in front of the Agent.





Duplicate the BP_NPC_NoAvoidance Blueprint as seen below.



Repeat the last two steps to create another group of Agents on the opposite side of the Level with the Sphere placed in front of them as their target.

Click Simulate and watch as the Agents navigate toward their goals. Notice how the lack of avoidance creates collisions in the center of the Level.



Section Results

In this section, you created an Agent that navigates toward its goal without using avoidance.

4 - Adding Reciprocal Velocity Obstacles Avoidance to Your Agent

In the Content Drawer, right-click the BP_NPC_NoAvoidance Blueprint and select Duplicate. Name the new Blueprint BP_NPC_RVO.



Double-click the BP_NPC_RVO Blueprint to open it in the Blueprint editor. Select the Character Movement component and in the Details panel, navigate to the Character Movement: Avoidance section.





Enable the Use RVOAvoidance checkbox and set Avoidance Consideration Radius to 100.



Compile and Save the Blueprint. Reciprocal Velocity Obstacles avoidance is now enabled in your Agent.

Drag several BP_NPC_RVO Blueprints to your Level and follow the same configuration as before. Click Simulate to see the results.



Section Results

In this section, you learned how to add Reciprocal Velocity Obstacles avoidance to your Agent.

5 - Adding Detour Crowd Avoidance to Your Agent

In the Content Drawer, right-click the BP_NPC_NoAvoidance Blueprint and select Duplicate. Name the new Blueprint BP_NPC_DetourCrowd.



Double-click the BP_NPC_DetourCrowd Blueprint to open it. Go to the Details panel and search for AI Controller.



Click the dropdown next to AI Controller Class and select DetourCrowdAIController.



Compile and Save your Blueprint. Detour Crowd avoidance is now enabled in your Agent.

Drag several BP_NPC_DetourCrowd Blueprints to your Level and follow the same configuration as before. Click Simulate to see the results.



You can adjust the Detour Crowd Manager settings by going to Settings > Project Settings and navigating to the Crowd Manager section.



In this section, you can adjust several settings for the Detour Crowd Manager system, such as the Max Agents used by the system and the Max Agent Radius used for the avoidance calculation.



Section Results

In this section, you learned how to add Detour Crowd avoidance to your Agent.

Overview

Goals

Objectives

1 - Required Setup

Section Results

2 - Creating Your Test Level

Section Results

3 - Creating your Agent

Section Results

Overview

Unreal Engine's Navigation System allows Agents to navigate the Level using a Navigation Mesh for pathfinding. In addition to the various Runtime Generation methods for the Navigation Mesh, the system also includes a way to only build the navigation locally around specific targets.

Navigation Invokers are Blueprint Actor components that generate the Navigation Mesh around the Agent at runtime. Using Navigation Invokers removes the need to build the Navigation Mesh in the editor and can also limit the number of tiles generated at runtime.

Navigation Invokers are ideal for big Levels where building the Navigation Mesh in the editor is impractical.

Goals

In this guide, you will learn to use Navigation Invokers with your Agents to generate the Navigation Mesh during gameplay.

Objectives

Create a new Level and configure the Navigation System to use Navigation Invokers.

Modify the ThirdPersonCharacter Blueprint to roam around the Level using Navigation Invokers.

1 - Required Setup

In the New Project Categories section of the Unreal Project Browser, select Games > Third Person template.



Select the Blueprint and No Starter Content options, then click Create.



Section Results

You created a new Third Person project and are now ready to learn about Navigation Invokers.

2 - Creating Your Test Level

Click File > New Level from the Menu Bar.



Select the Basic Level.



Select the Floor Static Mesh Actor in the Outliner and go to the Details panel. Set the Scale to X = 100, Y = 100, Z = 1.





Click Settings > Project Settings and go to the Navigation System category. Enable the Generate Navigation Only Around Navigation Invokers checkbox.





Go to the Navigation Mesh category and scroll down to the Runtime section. Click the Runtime Generation dropdown and select Dynamic.



Go to the Place Actors panel and search for NavMeshBoundsVolume. Drag it into the Level and place it on the floor mesh. Scale the NavMeshBoundsVolume to X = 500, Y=500, Z = 10.





Section Results

In this section, you created a new Level and configured the Navigation System to use Navigation Invokers.

3 - Creating your Agent

In the Content Drawer, right-click and select New Folder to create a new folder. Name the folder NavigationSystem.

In the Content Drawer, go to ThirdPerson> Blueprints and select the BP_ThirdPersonCharacter Blueprint. Drag it into the NavigationSystem folder and select the option Copy Here.



Navigate to the NavigationSystem folder and rename the Blueprint to BP_NPC_Invoker. Double-click the Blueprint to open it and go to the Event Graph. Select all input nodes and delete them.

Right-click the Event Graph, then search for and select Add Custom Event. Name the event MoveNPC.



Right-click the Event Graph, then search for and select Get Actor Location.



Drag from the GetActorLocation node and search for and select Get Random Reachable Point In Radius. Set the Radius to 1000.



Drag from the Random Location pin of the GetRandomReachablePointInRadius node and select Promote to variable.



Connect the MoveNPC node to the RandomLocation node you just created.



Right-click the Event Graph, then search for and select AI Move To. Connect the RandomLocation node to the AI Move To node.



Right-click the Event Graph, then search for and select Get a reference to self.



Connect the Self node to the Pawn pin of the AI Move To node. Connect the yellow pin of the Random Location node to the Destination pin of the AI Move To node, as seen below.



Drag from the On Success pin of the AI Move To node, then search for and select Delay. Set the Duration of the nodeto 4. Drag from the Completed pin of the Delay node, then search for and select MoveNPC, as seen below.



Repeat the steps above to add these nodes to the On Fail pin of the AI Move To node. Set the Duration of the Delay node to 0.1.



Right-click the Event Graph, then search for and select Event Begin Play. Drag from the Event Begin Play node, then search for and select MoveNPC.





Go to the Components tab, click the +Add dropdown, then search for and select Navigation Invoker.



With the Navigation Invoker component selected, go to the Details panel and find the Navigation section. Here you can change the Tile Generation Radius (radius around the actor used to generate Navigation Mesh tiles) and Tile Removal Radius (radius from the actor used to remove Navigation Mesh tiles). For this example, set these values to 3000 and 5000, respectively.



Compile and Save the Blueprint.

Drag several BP_NPC_Invoker Blueprints to your Level and click Simulate to see the navigation generating around each Agent.



If you don't see the navigation, press P on your keyboard to visualize the Navigation Mesh.



Section Results

In this section, you created an Agent that roams around the Level and uses the Navigation Invoker component to build the Navigation Mesh around itself.

Overview

Use the Highest Cell Size and Cell Height Possible

Recommendation

Limit the Tile Size

Recommendation

Use Simplified Collision for Your Meshes

Recommendation

Reduce the Number of Objects That Affect the Navigation Mesh

Recommendation

Useful Developer Tools to Manage Navigation Generation

Locking and Unlocking the Navigation Mesh Generation at Strategic Times

Enable Multi-threaded Navigation Mesh Generation

Use Dynamic Obstacles with Full Dynamic Navigation Mesh Generation

Use Data Chunk Streaming for Static Navigation Meshes Loaded in Sublevels

The latest version of this guide can be found in your local installation of Unreal Engine under the following directory: Engine\Source\Runtime\NavigationSystem\DevDocs\How To Optimize Navmesh Generation.md

Overview

Unreal Engine's Navigation System provides pathfinding capabilities to Artificial Intelligence Agents. To find a path between a start location and a destination, a Navigation Mesh is generated from the collision geometry of the world.

The Navigation Mesh is divided into tiles which are used to rebuild localized parts of the Navigation Mesh at runtime.

The Navigation System provides a variety of settings that advanced users can use to modify the way navigation is computed in the Level. This guide provides recommendations to optimize the generation speed of the Navigation Mesh.

Use the Highest Cell Size and Cell Height Possible

The Cell Size and Cell Height properties define the size of the voxels used to generate the Navigation Tiles. The smaller the voxels, the more precision is gained and the more accurate the navigation will be around obstacles. However, the smaller the voxels, the more processing is required when rebuilding the Navigation Mesh at runtime.

For this reason, it is important to balance the size of the cells (voxels) with the amount of navigation precision needed in your project.

Follow these steps to adjust the Cell Size and Cell Height properties of your Navigation Mesh:

Click Settings > Project Settings to open the Project Settings window.



Go to the Navigation Mesh section and scroll down to the Generation section. You can increase the Cell Size and Cell Height values to improve generation speed. Note that increasing the Size and Height values will decrease the Navigation Mesh precision in your level.



Alternatively, you can adjust individual Navigation Meshes inside your Level by selecting the RecastNavMesh-Default Actor in the Outliner and going to the Details panel.



In this example the Cell Size was changed from 19 to 64. Notice how precision is reduced and the Navigation Mesh is less accurate around the objects in the level. The new Cell Size of 64 prevents navigation generation between the wall and the box (see the arrow in the image below).





Recommendation

Make the cells as large as possible while maintaining the required precision for your Agents.

In the example above, setting the Cell Size to 64 caused the path between the wall and the box to be removed. If this path is needed for your Agent, you can either continue to adjust Cell Size until a path is generated or move the box further from the wall.

Limit the Tile Size

The Navigation Mesh is divided into tiles which are used to rebuild localized parts of the Navigation Mesh at runtime. Since each tile is built from cells, rebuilding a Navigation Tile will result in the recreation of all its cells with the new collision information.

Larger tiles contain more cells and are more expensive to rebuild than smaller tiles. However, when processing a tile, the system also processes the contiguous cells on the edges of the tile. You should consider this overhead cost when setting the size of your tiles, as there can be situations where the overhead cost of processing many smaller tiles is greater than the cost of rebuilding a single large tile.

Recommendation

The Tile Size should be set between 32 to 128 cells per side. This will provide the best performance when rebuilding tiles at runtime.

In the previous example the Cell Size was set to 64. In that case, the Tile Size UU should be set between 2048 (64*32) and 8192 (64*128).



Use Simplified Collision for Your Meshes

The Navigation System uses each object's collision data to generate the Navigation Mesh. Simpler object collision results in faster processing compared to higher triangle count collision data.

Recommendation

Use Simple Collision when possible for Static Meshes. The lower the triangle count used in the collision mesh, the faster the generation will be.

Reduce the Number of Objects That Affect the Navigation Mesh

By default, Blueprint Actors and Static Meshes in your Level affect navigation. The number of objects that affect a Navigation Tile has a direct impact on the cost of generating that tile.

Recommendation

Smaller objects that should not affect the Navigation Mesh should be configured so they don't affect navigation. Select your Actor in the Level and go to the Details panel. Scroll down to the Collision section and disable the Can Ever Affect Navigation checkbox.



This setting should be disabled for any Actor that should not affect the Navigation Mesh, such as moving objects in inaccessible areas of the Level.

If possible, you should avoid affecting large tile areas or multiple tiles at the same time.

Useful Developer Tools to Manage Navigation Generation

Locking and Unlocking the Navigation Mesh Generation at Strategic Times

It is possible to stop the automatic generation of the Navigation Mesh before loading many assets that might affect it. You can unlock the generation once all the assets have completed loading. This method prevents the Navigation System from rebuilding the same tile several times.

To lock the Navigation Mesh generation, set your navigation system's bInitialBuildingLocked to True. To unlock the generation, call the function ReleaseInitialBuildingLock(). Once unlocked, the Navigation Mesh will rebuild all the tiles marked as dirty by the loaded assets. To prevent this, you can call DefaultDirtyAreasController.Reset() before unlocking the generation.

Enable Multi-threaded Navigation Mesh Generation

You can control multi-threaded Navigation Mesh generation by setting the MaxSimultaneousTileGenerationJobsCount property in the Navigation System. Note that this is limited by the total number of worker threads in FRecastNavMeshGenerator::Init().

Use Dynamic Obstacles with Full Dynamic Navigation Mesh Generation

You can mark Static Meshes and other Actors in your Level as Dynamic Obstacles. Dynamic Obstacles mark the Navigation Mesh surface where generation needs to be rebuilt. This prevents the entire Navigation Tile from being rebuilt.

Using this method is less costly than generating the full Navigation Tile and should be used when a Navigation Mesh surface is not needed on top of moving obstacles.



Use Data Chunk Streaming for Static Navigation Meshes Loaded in Sublevels

If the only changes to the Navigation Mesh come from loading and unloading sublevels, you can set the Navigation Mesh Generation Method to Static and use NavMesh Data Chunk Streaming, instead of using a dynamic Navigation Mesh.

With this method, the Navigation Mesh will be fully built in the editor and only the relevant parts will be loaded in and out at runtime.

Overview

World-Partitioned Navigation Mesh

Runtime Generation

Dynamic Modes

Base Navigation Mesh and Data Layers

What is included in the Base Navmesh?

External Packaging

Create a World Partitioned Navigation Mesh

1 - Required Setup

Section Results

2 - Configuring the Navigation Mesh to use World Partition

Section Results

3 - Configuring the Editor

Section Results

4 - Building the Navigation Mesh

Section Results

5 - Building the Navigation Mesh with the World Partition Navigation Data Builder

6 - Additional settings for your Navigation Mesh

Section Results

7 - World Partition Settings

8 - Viewing your results

Section Results

Overview

This document provides an overview of how to use a world-partitioned Navigation Mesh with Unreal Engine's World Partition system.

World Partition is an automatic data management and distance-based level streaming system that provides a complete solution for large world management. The system removes the need to divide large levels into sublevels by storing your world in a single persistent level separated into grid cells, and provides an automatic streaming system to load and unload those cells based on distance from a streaming source.

Learn more about the system by reading the World Partition documentation.

World-Partitioned Navigation Mesh

A World Partition Navmesh is split into several Navmesh chunk Actors that are loaded / unloaded like other world partitioned resources.

A World Partition Navmesh only makes sense in the context of a world partitioned map. To convert a map so it uses World Partition, refer to the World Partition documentation.

Alternatively, you can create a world partitioned map by creating a new Level and selecting the Open World template.

Runtime Generation

World Partition Navigation Meshes support all available generation modes: Static, Dynamic Modifiers Only, and Dynamic.

Dynamic Modes

When using the Dynamic generation mode, the Navmesh tile generation will occur at runtime. However, navigation dirtiness (the need to rebuild the navigation) is ignored for objects that are loaded and unloaded which are part of the base Navmesh (see below). This prevents excessive dirtiness as a result of the loading and unloading of the world.

Dynamic tile building is limited to the loaded space when using a World Partition Dynamic Navmesh.

Base Navigation Mesh and Data Layers

All runtime navigation generation modes use a Base Navmesh. This refers to the initial Navmesh that gets loaded via streaming as cells are loaded.

In Static mode, this Navmesh will not change. However, in the Dynamic modes, spawned Actors that are relevant to the navigation will dirty the Base Navmesh and trigger the rebuilding of navigation tiles.

What is included in the Base Navmesh?

Navigation-relevant objects outside of Data Layers will be included in the Base Navmesh (i.e. baked in the initial Navmesh). In addition, any objects in editor Data Layers are also included.

Finally, any layers (including runtime Data Layers) in the Base Navmesh Data Layers list will also be considered in the Base Navmesh.

Learn more about World Partition Data Layers by reading the Data Layers documentation.

External Packaging

When building a World Partitioned Navmesh, the navigation data actor (ANavigationData) is externally packaged. This means that building a World Partitioned Navmesh does not dirty the main map.

For more information on external packaging see the One File Per Actor documentation.

Create a World Partitioned Navigation Mesh

1 - Required Setup

Create a new project from a template in the Games category. In this example, we selected the Third Person template.



In the editor, click File > New Level. Select the Open World map type and click Create. Save the level.



The Open World default map type is designed as a starting point for creating large open-world maps and has the following features enabled by default:

World Partition

One File Per Actor

Data Layers

Hierarchical Levels of Detail

Go to the World Settings window and scroll down to the World Partition section.

Expand Runtime Settings > Grids > Index [0].

Change the Loading Range value to 12800. The smaller value will make it easier to visualize when the Navigation Mesh is loaded by World Partition.



In this section, you created a new project with a level set up to use World Partition. In the next section, you will configure a Navigation Mesh so it works with World Partition.

2 - Configuring the Navigation Mesh to use World Partition

Click Settings > Project Settings to open the Project Settings window.



Click the Navigation Mesh category and scroll down to the Runtime section. Click the Runtime Generation dropdown and select Static.



If your project has large worlds, you can limit memory utilization by going to the Generation section and enabling the Fixed Tile Pool Size checkbox, and adjusting the Tile Pool Size. The pool size will limit the memory size utilized by the Navigation Mesh.

The number of tiles in the pool must be large enough to allow you to add:

The maximum number of tiles required to load the Navmesh Actors in the loading bubble at runtime.

The maximum number of tiles you want to visualize in the editor when loading parts of the world partitioned map.



Click Add + > Volumes > NavMeshBoundsVolume to add a Navigation Mesh volume actor to your level.



Select the NavMeshBoundsVolume actor in the Outliner window and go to the Details panel.

Scale the actor so it covers the playable space in the level.

Press P to see the navigation being built in the viewport.





Select the RecastNavMesh-Default actor in the Outliner window and go to the Details panel. Scroll down to the Generation section and enable the Is World Partitioned Navmesh checkbox.





In this section, you added a Navigation Mesh Bounds volume to your level. You also configured the Navigation mesh to work with World Partition.

In the next section you will configure the editor to improve your workflow.

3 - Configuring the Editor

Since you are most likely working on a really big level, it is recommended that you disable automatic Navigation Mesh generation to improve your workflow.

To do so, follow these steps:

Click Edit > Editor Preferences to open the Preferences window.



Scroll down to the Level Editor section and click the Miscellaneous category. Scroll down to the Editing category and disable the Update Navigation Automatically checkbox.



In this section, you configured your Navigation Mesh so it does not update automatically. This generally improves your workflow as you work with large worlds using World Partition.

In the next section, you will build the Navigation Mesh in your level.

4 - Building the Navigation Mesh

When working with a world partitioned map, some assets are usually loaded while others are unloaded. Because of this, building the entire Navigation Mesh requires a different process.

To build the Navigation Mesh in your level, follow these steps:

Enter the following console command in the command line and press Enter: n.bNavmeshAllowPartitionedBuildingFromEditor 1



Click Build > Build Paths to build the Navigation Mesh in your level.



In the Build Navigation Settings window, click Ok to build the Navigation Mesh. You also have the following options available:

Verbose - Enable this checkbox if you want to see a more detailed log of the build process. You can find the output log named WPNavigationBuilderLog.txt in the Saved > Logs directory of your project.

Clean Packages - Enable this if you want to remove all world partitioned NavMesh actor packages from your project. This will not build the navigation.



Go to the Outliner window and notice that you now have four NavDataChunk Actors. These actors hold the navigation data loaded and unloaded by World Partition. The number of NavDataChunk Actors created depends on the size of the Data Chunk Grid (see section 6 for more details).



In this section, you learned how to build the navigation for your level. You also learned about the different Navigation Settings options and how NavDataChunk actors are created in your level.

In the next section, you will learn how to build navigation outside of the editor.

5 - Building the Navigation Mesh with the World Partition Navigation Data Builder

It is also possible to build a world partitioned static Navigation Mesh outside the editor by using the WorldPartitionBuilderCommandlet with the WorldPartitionNavigationDataBuilder.

Follow the instructions in the World Partition documentation, under the World Partition Navigation Data Builder section to learn how to do this.

6 - Additional settings for your Navigation Mesh

Go to the World Settings window and scroll down to the Navigation section to find the Navigation Mesh settings for the level.

The options are as follows:

Setting

Description

Navigation Data Chunk Grid Size

This defines the size of the data chunk actors loaded with each cell of World Partition. The smaller the number, the more granular the data.

Navigation Data Builder Loading Cell Size

This defines the size of the loading cells used to load the Navigation data into memory.

Set the Navigation Data Chunk Grid Size to 25600. This lower value better shows how the Navigation Mesh is loaded and unloaded by World Partition. This value should be adjusted based on your gameplay needs, loading range, and required granularity.



Click Build > Build Paths to build the Navigation Mesh in your level.

Go to the Outliner window and notice that you have many more NavDataChunk actors in the level. This is expected as the Chunk Grid Size is smaller than before.



In this section, you learned how to change the Navigation Data Chunk Grid Size and how it affects the number of NavDataChunk actors that are created in your level.

In the next section, you will see how the Navigation Mesh is loaded and unloaded as the player traverses the level.

7 - World Partition Settings

In addition to the Navigation Mesh settings, you can also use the following World Partition settings to set up your map.

Command

Description

wp.Runtime.RuntimeSpatialHashPlacePartitionActorsUsingLocation = 0

When set to 0, the Partition Actor will use its bounds (instead of its location) when checking if it should be loaded or not. This might be useful when using large landscape tiles with a small loading radius.

s.ForceGCAfterLevelStreamedOut = 1

This setting will force Garbage Collection after the level is streamed out. This will remove the Navigation Actors that have been unloaded by World Partition. Otherwise, it might take some time for the unloaded Actors to be collected.

8 - Viewing your results

Follow these steps to view how the Navigation Mesh is loaded and unloaded with the World Partition cells.

Enter the following Navigation Mesh Gameplay Debugger console commands in the command line and press Enter:

ai.debug.nav.RefreshInterval 0.3

ai.debug.nav.DisplaySize 100

These commands adjust the display size and how frequently the Navigation Mesh visualization is updated.



Press Play to start the game. Open the command line by pressing tilde (~), then enter the following World Partition debug commands:

wp.Runtime.ToggleDrawRuntimeHash2D

wp.Runtime.ShowRuntimeSpatialHashGridLevel 2

These commands display which World Partition cells are loaded around the player.



Press single-quotation (‘) to enable the Gameplay Debugger and press zero (0) to switch to the Navigation view. You can now see the Navigation Mesh loaded around the player.



Move around the level and see how the Navigation Mesh is loaded as each World Partition cell is loaded around the player.





In this section, you learned how to visualize when the Navigation Mesh is loaded and unloaded by World Partition.

Overview

Smart Object Elements

SmartObject Subsystem

SmartObject Collection

SmartObject Component

Smart Object Definition

Smart Object Behaviors Definition

Runtime Flow

Agent Data

Smart Object Data

Searching for a Smart Object

Claiming the Smart Object

Approaching the Smart Object

Releasing the Smart Object

Aborting the Process

Overview

Smart Objects are objects placed in a level that AI Agents and Players can interact with. These objects contain all the information needed for those interactions.

Smart Objects are part of a global database and use a spatial partitioning structure. This means that they can be queried at runtime by using filters such as location, proximity to the Agent, and tags.

At a high level, Smart Objects represent a set of activities in the level that can be used through a reservation system. It's important to note that Smart Objects do not contain execution logic. Instead, they provide all necessary information to the interactor to be able to perform the interaction, depending on its implementation. Each interactor (Agent or Player) does its own implementation logic for a Smart Object.

Smart Object Elements

SmartObject Subsystem

The SmartObject subsystem is responsible for keeping track of all Smart Objects available in the level. This is the link between the Smart Object components and the collection. This subsystem is automatically created in the level when the Smart Objects plugin is active, and will create the Smart Object collection if it's missing.

SmartObject Collection

The SmartObject Collection contains a list of all SmartObject components associated with the level. The collection works with persistent levels and must be built manually by the user.

This means that Smart Objects registered with a collection are kept alive, regardless of whether the Smart Object components are loaded or unloaded from the persistent level.

There is only one Smart Object collection per level.

SmartObject Component

The SmartObject component can be added to any Actor to mark it as a Smart Object in the level. The component points to a Smart Object Definition asset, which stores the configuration of a given Smart Object template.

The Actor containing the SmartObject component may be loaded and unloaded at runtime using Streaming. If the SmartObject component is included in the persistent world's Smart Object collection, a runtime instance will remain active in memory and will be considered as part of the simulation. If the Actor containing the SmartObject component is spawned at runtime, then it will not remain active in memory once it's unloaded.

Smart Object Definition

A Smart Object Definition is a data asset that contains the immutable data shared between multiple Smart Object runtime instances. A Smart Object Definition stores filtering information such as user-required tags, Activity tags, Object Activation tags, and the default set of Behavior Definitions that could be used to interact with the Smart Object.

A Smart Object Definition exposes one or more Slots that can be used by Agents or Players for the specific Smart Object. Each Slot includes the location and rotation relative to the parent anchor (baked from editor placement), as well as several overridable properties. Common examples of overridable properties include user-required tags and specific Behavior Definition per Slot.

Smart Object Behaviors Definition

Smart Object Behaviors Definitions contain the data needed by the Agent or Player for a given interaction. The following types of Behaviors Definitions are currently available:

Mass Entity Behavior - contains data used to configure Smart Objects that can be used by Mass Entities.

Gameplay Behavior - contains data used to configure Smart Objects that can be used by the Gameplay Behavior plugin.

Runtime Flow

In this section you will learn how Agents interact with a Smart Object in the level.

Agent Data

In order to search for Smart Objects, the Agent can use one or more Gameplay Tags, and it can also use a Tag Query (Activity Requirements) that contains the desired tags on the object. This information will be used when searching for matching Smart Objects in the level.

Smart Object Data

Smart Object Definitions can contain one or more Activity Tags that are used to describe the object. They can also contain a Tag Query with a list of desired tags. The Tag Query is an expression used to determine if the user requesting the use of the Smart Object is allowed to interact with it.

A Smart Object Definition contains a list of Default Behavior Definitions that will be used for all Slots. If a Slot has a specific Behavior Definition assigned to it, then the specific behavior will override the default behavior.

Searching for a Smart Object

The Agent searches for nearby Smart Objects on a specified interval. The Agent performs the search by calling the FindSmartObjects method in the Smart Object subsystem. This method contains the user tags, Activity Tags, Behavior Definition Class, and search area.

The Smart Object subsystem finds all Smart Objects within the search area that match the all provided filters.

The Smart Object subsystem returns the Smart Object Results to the Agent. The Smart Object Results are a Struct array containing all matching Smart Object handles and their free Slots.





In the image above you can see a vehicle Smart Object with one free Slot, denoted by the green-colored ring.

Claiming the Smart Object

The Agent selects a desired Smart Object Result and calls the ClaimSmartObject method in the Smart Object subsystem. This method will attempt to claim a Slot from the Smart Object.

The Smart Object subsystem attempts to claim a Slot from the Smart Object.

An available Slot is claimed in the Smart Object and its state is set to Claimed.

Smart Object subsystem returns a Claim Handle to the Agent.

The Agent checks if the Claim Handle is valid. If it is valid, the claim attempt was successful and it can proceed to the next step. However, if the Claim Handle is invalid, the Agent may attempt to claim another Smart Object Slot from the Smart Object Results.

The claimed Slot may not be claimed by another Agent until it is released by the Agent that claimed it.





In the image above, Slot 0 has been claimed by the Agent.

Approaching the Smart Object

The Agent calls the GetSlotLocation or GetSlotTransform method in the Smart Object subsystem and passes the Claim Handle. This method returns the location or transform of the claimed Slot.

Alternatively, users can use the follow C++ code to obtain the Slot transform:

The Smart Object subsystem returns the location or transform of the claimed Slot to the Agent.

The Agent can now start navigating to the Slot location in the Level. The Agent can use any desired navigation method to reach its destination.

The Agent arrives at the Slot location and calls the Use method in the Smart Object subsystem and passes the Claim Handle.

The Use method triggers a state change for the claimed Slot. The Slot's state is changed from Claimed to Occupied.

The Smart Object subsystem returns the Behavior Definition struct to the Agent. The Behavior Definition contains all the required data for the Agent to perform its desired behavior at the Slot location.





In the image above, the Agent arrives at the Slot and begins performing its desired behavior. The Slot is now Occupied, denoted by the red-color ring.

Releasing the Smart Object

The Agent performs the desired behavior described in the Behavior Definition.

Once the behavior is completed or aborted, the Agent calls the Release method with the Claim Handle in the Smart Object subsystem.

The Smart Object Subsystem changes the Slot state from Occupied to Free.

The Agent is now free to perform other tasks or search for another Smart Object.



Agents are responsible for releasing their claimed Slots. This can happen once their behavior is completed or interrupted.

Aborting the Process

The process described above can be interrupted or aborted by the Agent or the Smart Object at any time.

If the Smart Object's state changes it will automatically release all Claimed or Occupied Slots and will notify the corresponding Agents through the OnSlotInvalidatedDelegate callback. A common example is the Smart Object being destroyed during gameplay.

The Agent can also abort the process at any time for any reason. In this scenario, the Agent is responsible for releasing the Slot so other Agents can claim it. Common examples include the Agent dying or performing another task with a higher priority.

Overview

Goals

Objectives

1 - Required Setup

Section Results

2 - Create the AI Gameplay Behavior

Section Results

3 - Create the Smart Object Definition Data Asset

Section Results

4 - Create a Smart Object

Section Results

5 - Create the Behavior Tree for the AI Agent

Create the Behavior Tree and Blackboard

Create the Behavior Tree Tasks

6 - Create the AI Agent

7 - Test the Smart Objects

Overview

Smart Objects are objects placed in a Level that AI Agents and players can interact with. These objects contain all the information needed for those interactions.

At a high level, Smart Objects represent a set of activities in the Level that can be used through a reservation system. This system keeps track of all the Smart Objects in the Level and allows an AI Agent to "reserve" a Smart Object so no other Agent can use it until the Smart Object becomes available again.

Goals

In this Quick Start guide, you will learn how to create and use Smart Objects with an AI Agent.

Objectives

Create the AI Gameplay Behavior and Behavior Definition that the AI Agent can use when it reaches a Smart Object.

Create a Smart Object that holds the Behavior Definition to play an animation montage.

Create simple AI behavior with a Behavior Tree and Behavior Tree Tasks.

Create the AI Agent that can search for and use Smart Objects in the level.

1 - Required Setup

Create a new Blueprint project based on the Third Person template.

From the main menu, go to Settings > Plugins to open the Plugins window.



Go to the Gameplay section and enable the Smart Objects, AI Behaviors, and Gameplay Behavior Smart Objects plugins. Restart the editor if prompted.







Section Results

In this section, you created a new project and enabled the Smart Objects and AI Behaviors plugins. You are now ready to create the AI Gameplay Behavior for your AI Agent.

2 - Create the AI Gameplay Behavior

In this section, you will create the Gameplay Behavior and Gameplay Config Blueprints that define what your Agent will do when it reaches a Smart Object Slot.

In the Content Browser, right-click and select Blueprint Class from the Create Basic Asset section.



In the Pick Parent Class window, expand the All Classes section, then search for and select Gameplay Behavior. Click Select and name the new Asset BP_SO_Behavior_PlayMontage.



Create a new Blueprint class, then search for and select Gameplay Behavior Config. Click Select and name the new Asset BP_SO_BehaviorConfig.



In the Content Browser, double-click BP_SO_BehaviorConfig to open it. Go to the Details panel and click the Behavior Class dropdown. Select BP_SO_Behavior_PlayMontage. Compile and save the Blueprint.



In the Content Browser, double-click BP_SO_Behavior_PlayMontage to open it. Click the Override dropdown next to Functions and select OnTriggeredCharacter.



Right-click the Avatar pin of the Event OnTriggeredCharacter node and select Promote to Variable.



Drag the Avatar variable to the Event Graph and select Get Avatar. Drag from the Avatar node, then search for and select Get Component by Class.



Click the Component Class dropdown, then search for and select Skeletal Mesh Component.



Right-click in the Event Graph, then search for and select Play Montage.

Connect the Return Value pin of the Get Component by Class node to the In Skeletal Mesh Component pin of the Play Montage node.

Connect the Set Avatar node to the Play Montage node.





Click the Montage to Play dropdown on the Play Montage node. Select an animation montage from the list.



If you don't have animations available, you can get free animation asset packs from the Unreal Engine Marketplace, such as the Animation Starter pack. You can also convert any Animation Sequence to an Animation Montage by right-clicking it and selecting Create > Create AnimMontage.

Drag the Avatar variable to the Event Graph and select Get Avatar. Drag from the Avatar node, then search for and select End Behavior.



Connect the On Completed and On Interrupted pins from the Play Montage node to the End Behavior node.



Compile and save the Blueprint.

This example uses the Play Montage node, as opposed to the Play Anim Montage node to use the On Completed and On Interrupted pins to end the behavior. This ensures the Smart Object remains occupied until the animation finishes playing.

Section Results

In this section, you created the Gameplay Behavior and Gameplay Config Blueprints that the Agent will use to play an animation montage once it reaches a Smart Object Slot. You can now create the Behavior Definition that will be used by the Smart Object.

3 - Create the Smart Object Definition Data Asset

In this section, you will create the SmartObject Definition Data Asset that will define the behavior for each Slot of the Smart Object.

In the Content Browser, right-click and select Miscellaneous > Data Asset.

In the Pick Class for Data Asset Instance window, search for and select Smart Object Definition.

Click Select to create the Asset and name it SO_Definition_PlayMontage.





In the Content Browser, double-click SO_Definition_PlayMontage to open it. Scroll down to the Smart Object section and click the Add (+) button next to Slots to add a new Slot. This is the Slot that will be used by the AI Agent when performing the behavior.



Click the Add (+) button next to Default Behavior Definitions and select Gameplay Behavior Smart Object Behavior Definition for Index 0. Click the Gameplay Behavior Config dropdown and select BP_SO_BehaviorConfig.



Save and close the Blueprint.

Section Results

In this section, you created the SmartObject Definition Data Asset that defines each Slot of the Smart Object and its default behavior definition.

4 - Create a Smart Object

In this section, you will create a Smart Object that can be found and used by an Agent in the level.

In the Content Browser, right-click and select Blueprint Class from the Create Basic Asset section.



In the Pick Parent Class window, click the Actor class button to create the asset. Name the new Asset BP_SO_RunBT.



In the Content Browser, double-click BP_SO_RunBT to open it. Go to the Components window and click the + Add button. Search for and select Smart Object.



With the SmartObject component selected, go to the Details panel and scroll down to the Smart Object section. Click the Definition Asset dropdown and select SO_Definition_PlayMontage.



Compile and save the Blueprint.

Section Results

In this section, you created a Smart Object and added the Behavior Definition that defines the default behavior of its Slot.

5 - Create the Behavior Tree for the AI Agent

In this section, you will create the necessary behavior for the AI Agent to search for and use Smart Objects in the Level. You will use a simple Behavior Tree and two custom Behavior Tree Tasks to accomplish this.

Create the Behavior Tree and Blackboard

In the Content Browser, right-click and select AI > Blackboard. Name the Blackboard BB_SO_Agent.



Double-click BB_SO_Agent to open it. Click the New Key dropdown and select SO Claim Handle. Name the key ClaimHandle. Save and close the Blackboard.



In the Content Browser, right-click and select AI > Behavior Tree. Name the Behavior Tree BT_SO_Agent.



Create the Behavior Tree Tasks

Finding Smart Objects

In the Content Browser, right-click and select Blueprint Class from the Create Basic Asset section.



In the All Classes section, search for and select BT Task Blueprint Base, then click Select. Name the Blueprint BTT_FindSmartObject.



In the Content Browser, right-click BTT_FindSmartObject and select Duplicate. Name the new Blueprint BTT_UseSmartObject.



In the Content Browser, double-click BTT_FindSmartObject to open it. In the Event Graph, right-click, then search for and select Event Receive Execute AI.



Drag from the Owner Controller pin of the Event Receive Execute AI node, then search for and select Get Blackboard.

Right-click the Return Value pin of the Get Blackboard node and select Promote to Variable. Name the variable Blackboard.

Connect the Event Receive Execute AI node to the Set Blackboard node.





Drag from the Controlled Pawn pin of the Event Receive Execute AI node, then search for and select Get Actor Location.

Drag from the Return Value of the Get Actor Location node, then search for and select Subtract.

Drag from the Return Value of the Get Actor Location node, then search for and select Add.

Set the X, Y, and Z values of both nodes to 2000. This creates a search box of 4000 x 4000 units, or 40 x 40 meters around the Agent.





In the Event Graph, right-click then search for and select Make Box.

Connect the Subtract node to the Min pin of the Make Box node.

Connect the Add node to the Max pin of the Make Box node.





In the Event Graph, right-click then search for and select Get Smart Object Subsystem.

Drag from the Smart Object Subsystem node, then search for and select Find Smart Objects.

Drag from the Request pin of the Find Smart Objects node and select Make SmartObjectRequest.







Connect the Return Value pin of the Make Box node to the Query Box pin of the Make SmartObjectRequest node.

Drag from the Filter pin of the Make SmartObjectRequest node and select Make SmartObjectRequestFilter.

Drag from the Behavior Definition Classes pin and search for then select Make Array.

Click the dropdown of the Make Array node and select GameplayBehaviorSmartObjectBehaviorDefinition.

Connect the Set Blackboard node to the Find Smart Objects node.





This is what the Blueprint looks like so far.



Right-click the Out Results pin of the Find Smart Objects node and select Promote to Variable. Connect the Out Results node to the Blackboard node.

Drag from the pin of the Out Results node, then search for and select Is Valid Index.

Drag from the Is Valid Index node, then search for and select Branch. Connect the Out Results node to the Branch node.







Drag from the False pin of the Branch node, then search for and select Finish Execute. The Out Results will be invalid if no nearby Smart Objects match the search criteria.



Create a Smart Object Subsystem node in the Event Graph. Drag from the node, then search for and select Claim.

Connect the True pin of the Branch node to the Claim node.

Drag the Out Results variable to the Event Graph and select Get Out Results. Drag from the node, then search for and select Random Array Item.

Drag from the Random node and connect it to the Request Results pin of the Claim node.







Right-click the Return Value pin of the Claim node and select Promote to Variable. Name the variable ClaimHandle.

Drag from the Claim Handle node pin, then search for and select Is Valid Smart Object Claim Handle.

Drag from the Return Value of the Is Valid Smart Object Claim Handle node, then search for and select Branch.







Drag from the False pin of the Branch node, then search for and select Finish Execute.



Drag the Blackboard variable to the Event Graph and select Get Blackboard.

Drag from the Blackboard node, then search for and select Set Value as SOClaim Handle.

Connect the True pin of the Branch node to the Set Value as SOClaim Handle node.

Right-click the Key Name pin of the Set Value as SOClaim Handle node and select Promote to Variable.

With the Key Name variable selected, go to the Details panel and enable the Instance Editable checkbox. Set the Default Value to ClaimHandle.







Drag the ClaimHandle variable and connect it to the Value pin of the Set Value as SOClaim Handle node.



Drag from the Set Value as SOClaim Handle node, then search for and select Finish Execute. Enable the Success checkbox on the node.



Compile and save the Blueprint.

Use the Smart Object

In the Content Browser, double-click BTT_UseSmartObject to open it. In the Event Graph, right-click and search for then select Event Receive Execute AI.



Drag from the Owner Controller pin of the Event Receive Execute AI node, then search for and select Get Blackboard.



Drag from the Return Value pin of the Get Blackboard node, then search for and select Get Value as SOClaim Handle.



Right-click the Key Name pin of the Get Value as SOClaim Handle node and select Promote to Variable.

With the Key Name variable selected, go to the Details panel and enable the Instance Editable checkbox. Set the Default Value to ClaimHandle.



Drag from the Return Value pin of the Get Value as SOClaim Handle node, then search for and select Use Claimed Gameplay Behavior Smart Object.

Connect the Get Value as SOClaim Handle node to the Use Claimed Smart Object node.

Drag from the Owner Controller pin of the Event Receive Execute AI node and connect it to the Controller pin of the Use Claimed Smart Object node.





Drag from the On Succeeded pin of the Use Claimed Smart Object node, then search for and select Finish Execute. Enable the Success checkbox on the node.



Compile and save the Blueprint.

Create the Behavior Tree

In the Content Browser, double-click BT_SO_Agent to open it. Drag from the Root node and select Selector.



Drag from the Selector node and select Sequence.

Drag from the Selector node and select Wait. This node will have the Agent wait for 5 seconds before searching for a new Smart Object, if the initial search was unsuccessful.

Make sure the Sequence node is to the left of the Wait node. This ensures the Sequence will be executed first in the Behavior Tree.



Drag from the Sequence node and select BTT_FindSmartObjects.



Drag from the Sequence node and select BTT_UseSmartObjects.



Drag from the Sequence node and select Wait. With the node selected, set the Wait Time to 2.0 and Random Deviation to 0.5. This node will have the Agent wait between 1.5 and 2.5 seconds before searching for a new Smart Object.





Save and close the Behavior Tree.

Section Results

In this section, you created the Behavior Tree and Behavior Tree Tasks that allow the Agent to find and use Smart Objects in the Level.

6 - Create the AI Agent

In this section, you will create the AI Agent that will search for Smart Objects in the level.

In the Content Browser, double-click the BP_ThirdPersonCharacter Blueprint to open it.



Select all the nodes in the Event Graph and delete them. Right-click in the Event Graph, then search for and select Event Possessed.



Drag from the New Controller pin of the Event Possessed node, then search for and select Cast to AI Controller. Connect the Event Possessed node to the Cast to AIController node.



Drag from the As AIController pin of the Cast to AIController node, then search for and select Run Behavior Tree. Click the BTAsset dropdown and select BT_SO_Agent.



Compile and save the Blueprint.

Section Results

In this section, you created the AI Agent Blueprint that will search for Smart Objects in the Level. You also modified the animation Blueprint to make sure the animation montage can play correctly.

7 - Test the Smart Objects

You will now test the Agent to make sure it can find and use the Smart Objects in the Level.

From the Main Toolbar, click Add Content (+) > Volumes > NavMeshBoundsVolume to add a new Navigation Mesh actor to your Level. Scale the Mesh to cover your Level so the Agent can navigate to its destination.



Drag several BP_SO_RunBT Blueprints to your level.



Drag the ThirdPersonCharacter Blueprint to your Level.



Press Simulate to see the Agent find and use Smart Objects in the Level.



Section Results

In this section, you confirmed that the Agent can find and use Smart Objects in the Level.

StateTree is a general-purpose hierarchical state machine that combines the Selectors from behavior trees with States and Transitions from state machines. With StateTree, you can create highly performant logic that stays flexible and organized.

Learn more about StateTree by going through the guides below.



Overview of the StateTree system.



Quickstart guide on using the StateTree system in Unreal Engine.

Overview

Selection Flow

Selecting a new State

Executing the State Tasks

Data Flow

Blueprint Integration

Common Patterns

Grouping Similar Tasks

Sequences

Failure Handling

Hierarchical Data

Refining Behavior

Overview

StateTree is a general-purpose hierarchical state machine that combines the Selectors from behavior trees with States and Transitions from state machines. Users can create highly performant logic that stays flexible and organized.

StateTree contains States that are arranged in a tree structure. The State selection can be triggered at any location in the tree, but it initially starts from the root. During the selection process, each State's Enter Conditions are evaluated. If they pass, the selection advances to the State's child States, if available. If no child States are available, the current State is activated.

Selecting a State will activate all of the States from the root to the leaf State. Each state consists of Tasks and Transitions.

When a State is selected, the selected State and all its parent States become active. All Tasks are executed for all active States, starting from the root, down to the selected State.

Each Task provides an output to the StateTree. Common output examples include selecting a target, playing an animation, and looking at an object. Each State can have multiple Tasks, and all Tasks in a State run concurrently as long as the State remains active. The first Task that completes its execution triggers a Transition which can result in the selection of a new State.

As a simple example, you could create a time of day system using StateTree. You would create a State for each time of the day, and underneath each State you would create separate Tasks. Each Task could handle different elements, such as fog density, sky sphere color, and so on.

Another example would be having an AI Agent walk around the level and constantly check for hits while looking around. You could have a State for walking and looking around, and another for reacting to a hit.

A Transition in a StateTree can point to any other State in the tree. Transitions have Trigger Conditions that need to be met before the transition triggers the State selection process.

If the State selection succeeds, a new State will be selected. Some Transitions are monitored constantly, while others only execute on State completion. Transitions are evaluated starting from the leaf State and progressing upwards toward the root. During this process, the first Transition that succeeds and leads to State selection is selected. This hierarchy allows for grouping of common Transitions.

These are the different elements of the StateTree:



Legend

StateTree element

Description

1

Root

First State selected when the StateTree starts running.

2

Selector State

Refers to a State that has child States. This State will never be selected directly, and selection will continue to one of its child States.

3

State Enter Condition

Refers to the list of conditions that determine whether a State can be selected.

4

Task

Refers to a set of actions that belong to a State and are executed when the State becomes active.

5

Transition

Defines the conditions that trigger the State selection process. A Transition is triggered when a Task completes, succeeds, or fails, or when a monitored condition succeeds.

Selection Flow

Selecting a new State

StateTree selects active States similarly to a behavior tree. State selection starts from root on the first Tick, and it continues down the tree evaluating each State's Enter Conditions.

If the Enter Conditions do not pass, the selection proceeds to the next sibling State.

If the Enter Conditions pass, and the State is a leaf State, it is selected as a new State.

If the State has child States, the same process continues on to the first child State until a leaf State is found.

If a State has child States, yet none can be selected (their Enter Conditions fail), the State will not be selected even if all its Enter Conditions passed the test.

One of the big differences between behavior trees and state machines is that state machines usually commit State selection as the execution goes down the tree, compared to behavior trees which try to find a suitable leaf node.

In general terms, behavior trees keep executing the State selection logic even when a State has been selected. This is the only method for transitioning between States.

StateTree runs the State selection process on-demand, based on Transitions. On the first tick, there is an implicit transition to the root State, which will select the first State to run. Once that State has been selected, the Transitions dictate when and where the selection logic will be executed.

Executing the State Tasks

Once a State is selected, all its Tasks will begin executing concurrently. The Tasks will continue executing until a Transition triggers the selection process and a State is selected. The selected State can be the current State (the State continues executing) or a new State.

The most common Transition trigger is completion, which is executed once the first Task of the active State finishes. Other Transitions can be marked as Tick and are tested on each tick. If the conditional Transition passes the test, the State selection logic is executed and the selection process starts at the target State. If the target State has child States, the selection process will consider the child States as part of the selection logic.

Data Flow

State Trees use data binding to pass data within the tree. The data binding can be used to create conditions, or to configure Tasks to run. The data binding can access data passed into the State Tree, or between the nodes in a specific manner.

The common data types available to all nodes in the State Tree are:

Data Type

Description

State Tree Parameters

Users can add input parameters to the State Tree that can be referenced while the tree is running. These parameters provide the ability to customize the use of the tree depending on its usage. For example, a user could define an animation asset parameter that can be passed externally to the tree for use during gameplay.

Context Data

The Context Data refers to the predefined data available to the State Tree based on the selected State Tree Schema. This changes based on where the State Tree is used. For example, a State Tree used by an Actor will have that actor as its Context. However, if the same State Tree is used with a Smart Object behavior, the Context will refer to the Smart Object used and the Actor that uses it.

Evaluators

Evaluators provide a way to expose data to the State Tree that would otherwise not be possible to do with Parameters or Context Data. Evaluators are a separate class that can be executed in a State Tree during runtime. Evaluators contain variables and can execute custom code when the tree starts, stops, and on each Tick. The properties of an Evaluator can be bound to Parameters or Context Data, or other Evaluators that come before in the Evaluator list.

StateTree nodes can share data among themselves. The different elements in the StateTree can bind to data in the following manner:

StateTree Element

Data the element can bind to

Enter Conditions

Can bind to common data, and Tasks in all parent States.

Transition Conditions

Can bind to common data, and Tasks from the current State and all parent States.

Tasks

Can bind to common data, and earlier Tasks in the current State and all the parent States.

Blueprint Integration

StateTree is designed to be extended via Blueprint scripting. You can create custom Tasks, Evaluators, and Conditions by extending the following Blueprint classes:

Base Class

Description

UStateTreeTaskBlueprintBase

Base class for a StateTree Task.

UStateTreeEvaluatorBlueprintBase

Base class for a StateTree Evaluator.

UStateTreeConditionBlueprintBase

Base class for a StateTree Condition.

Following up with the example mentioned before, you could create a time of day system using StateTree and Blueprints. This system would change the fog density of the Level depending on the time. The system could also check for a storm spell to change the lighting conditions regardless of time.

For this example, you could create the following Blueprint classes:

Blueprint Class

Functionality

Task

Gradually changes the fog density over time. This Task can be added to all the States that represent a specific time of day.

Condition

Checks if a storm spell has been cast. This Condition can be evaluated at the root State. If true, it would move execution to a special Storm State.

Evaluator

Exposes the time of day to the Transitions and Enter Conditions.

Common Patterns

Grouping Similar Tasks



Tasks can be grouped under a common State. In the example above, there is a State that handles Smart Objects in the world. This State contains child States that handle Reaching the Smart Object and Using the Smart Object.

Each of these child States contains Tasks that execute when that State is selected. The Reach child State contains Tasks that find the Smart Object and move the AI Agent to the Smart Object.

When you use this grouping strategy, all Tasks share the same Transitions via the State.

Sequences



StateTree comes with the Next Transition, which simplifies creating and arranging a sequence of States.

In the example above, when the Reach State is selected, the Find SO Target, Move to SO, and Look Tasks are executed. Once the Tasks are completed, the Next Transition moves execution to the Use State below, where its Tasks can begin executing.

Failure Handling



StateTree handles Task completion failure in a hierarchical way, starting with the active Task and going up the tree.

In the example above, the Reach Slot State will move execution to the next State on success (Wait), or it will move execution to its parent State on failure (Wait at Intersection). The Wait at Intersection State will trigger a Transition to the Idling State if any of its child States fail.

The Wait State will move execution to itself indefinitely on success or failure until its parent State selects a different State.

Hierarchical Data



Tasks can share data between each other. The data exposed by a Task will be available to any other Task that belongs to an active State. This makes resource handling in the StateTree more efficient.

In the example above, the Crowd Claim Wait Slot Task will try to claim a Smart Object Slot for the AI Agent, and if it is successful, it will pass execution to the Move To Wait Slot Task. This Task will use the Slot location from the parent Task. If successful, it will pass execution to the Wait At Slot Task, which will use the Slot Location from its parent Task as well.

Refining Behavior



StateTree provides a way to organize Tasks such that contextual behaviors can be achieved easily.

In the example above, the Wait State handles the AI Agent's standing locomotion - the AI Agent looks around and reacts when hit. By default, the Wait Look State will be executed. If the State succeeds, it will return execution to its parent. However, if it fails, it will move execution to the Wait Hit State.

The Wait Hit State will execute the Mass LookAt and Mass Contextual Anim Tasks. These Tasks will then play the appropriate animation to the hit.

Overview

Goals

Objectives

1 - Required Setup

Section Results

2 - Create the State Tree

Section Results

3 - Create the Shooting Target Blueprint

Section Results

4 - Create the Idle and Dead States

Section Results

5 - Create a New State Tree Task

Section Results

6 - Finish the Dead State

Section Results

7 - Add a Spline Path

Section Results

8 - Add a State Tree Evaluator

Section Results

9 - Add a State Tree Task to Move Along Spline

Section Results

10 - Finalize the State Tree

Overview

StateTree is a general-purpose hierarchical state machine that combines the Selectors from behavior trees with States and Transitions from state machines. Users can create highly performant logic that stays flexible and organized.

You can learn more about State Trees by reading the State Tree Overview documentation.

Goals

In this guide you will use a State Tree to create a moving target the player can shoot and destroy.

Objectives

Create a Blueprint for a target Actor the player can shoot and destroy.

Create the State Tree that contains the logic to move and destroy the target actor.

Create State Tree Tasks and use them in the State Tree.

Create a State Tree Evaluator and use it in the State Tree.

1 - Required Setup

Create a new project then select the Games category and the First Person template. Enter your project's location and name. Click Create.



Click image for full size.

Click Settings > Plugins to open the Plugins window.



Search for and enable the GameplayStateTree and StateTree plugins. Restart the Unreal Engine editor.



Section Results

In this section, you created a new project and enabled the State Tree plugins. You are now ready to create the State Tree you will use in the target Actor.

2 - Create the State Tree

In this section, you will create a State Tree that will be used by the target Actor. This State Tree is intended to be used as a component of the target Actor, so you will use the State Tree Component Schema for this example.

In the Content Browser, right click and select Artificial Intelligence > StateTree.



Select the StateTreeComponentSchema class and click Select.



Name the State Tree ST_ShootingTarget.



Section Results

In this section, you created a State Tree with the Component Schema that will be used by a target Actor.

3 - Create the Shooting Target Blueprint

In this section, you will create the Blueprint for the target Actor that will move and receive damage from the player.

In the Content Browser, right click and select Blueprint Class from the Create Basic Asset section.

In the Pick Parent Class window, click the Actor button to create a new Actor Blueprint.

Name the Blueprint BP_ShootingTarget.







Open BP_ShootingTarget and go to the Components window. Click +Add and select Static Mesh.

Go to the Details panel and scroll down to the Static Mesh section.

Click the Static Mesh dropdown and select 1M_Cube.





Set the Scale of the Static Mesh to X = 0.2, Y = 2.0, Z = 2.0.



In the Components window, click +Add and select StateTree.

Go to the Details panel and scroll down to the AI section.

Click the State Tree dropdown and select ST_ShootingTarget.





If the State Tree does not appear in the dropdown, it means that the incorrect schema was selected. Make sure to select the StateTreeComponentSchema to use in the State Tree component.

Right-click the Static Mesh component and select Add Event > Add OnComponentHit.



Create a new variable and name it HitCount.

Go to the Details panel and set the Variable Type to Integer.





Drag the HitCount variable to the Event Graph and select Get HitCount.

Drag from the HitCount node and search for and select Increment Int.

Connect the On Component Hit node to the Increment Int node.



Section Results

In this section, you created the Shooting Actor Blueprint the player will shoot during gameplay. You are now ready to create the Idle and Dead States of the State Tree.

4 - Create the Idle and Dead States

Go back to ST_ShootingTarget and under the Schema section, click the Context Actor Class dropdown. Select BP_ShootingTarget.



Click + Add State to create a new State and name it Idle.



Go to the Details panel and scroll down to the Transitions section.

Expand the Go to State section and click the Transition To dropdown. Select Root. This will set the State Tree to transition back to the Root State once this State is completed.





Create another State and name it Dead.



Select the Idle State and add another Transition.

Click the Trigger dropdown and select On Tick.

Click the Transition To dropdown and select Dead.



Add a new Condition by clicking on the plus sign. Click the dropdown and select Integer Compare.

Expand the structure and click on the Left Bind dropdown and select Actor > Hit Count. This binds the value of Hit Count inside BP_ShootingTarget to the StateTree Condition.

Enter 5 as the value of the Right integer.







Section Results

In this section, you added the Idle and Dead States to the State Tree. You are now ready to create a State Tree Task that will handle the Dead State.

5 - Create a New State Tree Task

In this section, you will create a new State Tree Task that will destroy the Actor when the Dead State is executed.

In the Content Browser, right click and select Blueprint Class.

In the Pick Parent Class window, expand the All Classes dropdown and search for and select StateTreeTaskBlueprintBase.

Click Select to create the asset.

Name the Blueprint class STT_Destroy.







Open STT_Destroy by double-clicking it in the Content Browser. Go to the Functions section and click the Override dropdown. Select ExitState.



Create a new variable and name it Actor. Set its type to Actor Object Reference.

Go to the Details panel, and set its Category to Context.

Drag the Actor variable to the Event Graph and select Get Actor.

Drag from the Actor node and search for and select Destroy Actor.

Connect the Event ExitState node to the Destroy Actor node.







Section Results

In this section, you create a new State Tree Task that runs once the Dead State is executed. This Task destroys the Actor.

6 - Finish the Dead State

Go back to ST_ShootingTarget and select the Dead State. Add a new Task and select Debug Text Task from the dropdown.

Enter ‘Actor Destroyed' in the Text field.

Enter a Text Color and a Font Scale.



Add another Task and select Delay Task from the dropdown.

Enter 2.0 for the Duration.



Add a third Task and select STT_Destroy from the dropdown. This will destroy the Actor.



Create a new Transition and set the Trigger to On State Completed.

Set the Transition To dropdown to Tree Succeeded.



Drag BP_ShootingTarget to your Level and press Play. Shoot the Blueprint and confirm the State Tree is working.





Section Results

In this section, you completed the Dead State and tested that the Shooting Actor Blueprint can receive damage and be destroyed.

7 - Add a Spline Path

In this section, you will create an Actor with a Spline component. This spline will be used by the Shooting Target Blueprint to move in the Level.

In the Content Browser, right click and select Blueprint Class from the Create Basic Asset section.

In the Pick Parent Class window, click the Actor button to create a new Actor Blueprint.

Name the Blueprint BP_SplineActor.







Open BP_SplineActor and go to the Components window. Click +Add and select Spline.

Compile and Save the Blueprint.



Section Results

In this section, you created a generic Blueprint Actor that has a Spline component. This Spline will be used to create a moving path for the Shooting Actor in the Level.

8 - Add a State Tree Evaluator

Now you will create a State Tree Evaluator that will search for all Spline Actors in the Level and return the closest one to the State Tree.

In the Content Browser, right click and select Blueprint Class from the Create Basic Asset section.

In the Pick Parent Class window, expand the All Classes dropdown and search for and select StateTreeEvaluatorBlueprintBase.

Click Select to create the asset.

Name the Blueprint class STE_GetSpline.







Open STE_GetSpline and go to the Functions section of the My Blueprint panel.

Click the Override dropdown and select TreeStart.



Drag from the Event TreeStart node and search for and select Get All Actors of Class.

Click the Actor Class dropdown and select BP_SplineActor.



Create a new variable and name it Actor.

Go to the Details panel and set the Variable Type to Actor Object Reference.

Click the Category dropdown and enter ‘Context'.





Drag from the Out Actors pin of the Get All Actors from Class node and search for and select Find Nearest Actor.

Drag the Actor variable to the Event Graph and select Get Actor.

Drag from the Actor node and search for and select Get Actor Location.

Connect the Return Value of the Get Actor Location node to the Origin pin of the Find Nearest Actor node.



Drag from the Return Value pin of the Find Nearest Actor node and search for and select Cast to BP_SplineActor.

Right click on the As BP Spline Actor pin of the Cast to BP_SplineActor node and select Promote to Variable.

Name this variable to SplineActor and enter ‘Output' for its Category.

Compile and Save the Blueprint.





Go back to ST_ShootingTarget and under the StateTree window, click the plus sign next to Evaluators.

Click the dropdown and select STE_GetSpline.



Section Results

In this section, you created a State Tree Evaluator that will execute when the State Tree begins execution. This Evaluator checks for all Spline Actors in the Level and returns the closest one to the Shooting Actor.

9 - Add a State Tree Task to Move Along Spline

In this section, you will create a new State Tree Task that will move the Actor along the BP_SplineActor's spline.

In the Content Browser, right click and select Blueprint Class.

In the Pick Parent Class window, expand the All Classes dropdown and search for and select StateTreeTaskBlueprintBase.

Click Select to create the asset.

Name the Blueprint class STT_MoveAlongSpline.







Open STT_MoveAlongSpline and go to the Functions section of the My Blueprint panel. Click the Override dropdown and select Tick.



Create a new variable and name it Actor.

Go to the Details panel and set the Variable Type to Actor Object Reference.

Click the Category dropdown and enter ‘Context'.





Create a new variable and name it SplineActor.

Go to the Details panel and set the Variable Type to BP_SplineActor.

Enter ‘Input' as the Category.





Drag the Actor variable to the Event Graph and select Get Actor.

Drag from the Actor node and search for and select Set Actor Location.

Connect the Tick node to the Set Actor Location node.



Drag the SplineActor to the Event Graph and select Get Spline Actor.

Drag from the SplineActor node and search for and select Spline.

Drag from the Spline node and search for and select Get Location at Distance Along Spline.

Connect the Return Value of the Get Location at Distance Along Spline node and connect it to the New Location pin of the Set Actor Location node.

Right click the Distance pin of the Get Location at Distance Along Spline node and select Promote to Variable.



Drag from the Set Actor Location node and search for and select Branch.

Drag the Distance variable to the Event Graph and select Get Distance.

Drag from the Distance node and search for and select Less.

Connect the Less node to the Condition pin of the Branch node.



Drag the SplineActor to the Event Graph and select Get Spline Actor.

Drag from the SplineActor node and search for and select Spline.

Drag from the Spline node and search for and select Get Spline Length.

Connect the Return Value from the Get Spline Length node and connect it to the lower pin of the Less node.



Drag the Distance variable to the Event Graph and select Get Distance.

Drag from the Distance node and search for and select Add.

Create a new variable of type Float and name it MovementSpeed.

Connect MovementSpeed to the lower pin of the Add node.

Drag the Distance variable to the Event Graph and select Set Distance.

Connect the Add node to the Set Distance node.

Connect the True pin of the Branch node to the Set Distance node, as seen below.



Select the MovementSpeed variable and set its Default value to 5.0.



Drag the Distance variable to the Event Graph and select Set Distance.

Connect the False pin of the Branch node to the Set Distance node.

Connect both Set Distance nodes to the Return Node with a Return Value of Running.





Section Results

In this section, you create a State Tree Task that moves the Shooting Actor Blueprint along the spline path created with the Spline Actor Blueprint.

10 - Finalize the State Tree

Go back to ST_ShootingTarget and click +Add State. Name the new State MoveAlongSpline.

Click and drag the MoveAlongSpline State into the Idle State to parent it.





Go to the Details panel and add a new Task by clicking the + button.

Click the dropdown and select STT_MoveAlongSpline.

Click the Bind dropdown next to Spline Actor and select STE Get Spline > Spline Actor.







Drag BP_SplineActor to the Level.



Select the Spline component of BP_SplineActor. Alt-drag to create new spline points and create a closed shape.

Select the Spline component of the Spline Actor Blueprint and scroll down to the Spline section. Enable the Closed Loop checkbox to make the spline a closed shape.





Press Play and shoot at the target.



Starting Out

Essentials

The Environment Query System (EQS) is a feature within the Artificial Intelligence system in Unreal Engine 5 (Unreal Engine) that is used to collect data from the environment. Within EQS, you can ask questions about the data collected through a variety of different Tests which produces an Item that best fits the type of question asked.

An EQS Query can be called from a Behavior Tree and used to make decisions on how to proceed based on the results of your Tests. EQS Queries are primarily made up of Generators (which are used to produce the locations or Actors that will be tested and weighted) and Contexts (which are used as a frame of reference for any Tests or Generators). EQS Queries can be used to instruct AI characters to find the best possible location that will provide a line of sight to a player to attack, the nearest health or ammo pickup, or where the closest cover point (among other possibilities).

Once you have a general understanding of how Behavior Trees work in Unreal Engine and want to have your AI query the environment, you may want to start with the Environment Query System Quick Start guide which will walk you through an end-to-end example of having the AI find the best possible position to attack from a range against the player. Also refer to the Essentials section for an overview of EQS, a User Guide to working with EQS, and a node reference page that breaks down the available nodes and properties within EQS.

Starting Out



The Environment Query System Quick Start aims to get you up to speed on some of the systems and tools for working with EQS and AI.

Essentials



Overview page for Environment Query System.



Describes the common methods of creating and working with EQS assets.



Environment Query System Node Reference page.



Outlines how you can use the EQS Testing Pawn to debug and view what your EQS Queries are doing.

1 - Required Project Setup

2 - Environment Query Context

3 - EQS Setup

4 - Blackboard and Behavior Tree Setup

5 - Behavior Tree: Patrol Setup

6 - Behavior Tree: In Combat Setup

7 - AI Controller Setup

8 - Final Setup

9 - End Result

It is recommended that you proceed through the Behavior Tree Quick Start Guide or have some prior knowledge of Blueprints and Behavior Trees in Unreal Engine 5 before proceeding with this guide.

The Environment Query System (EQS) can be used within Behavior Trees to poll the environment through a variety of Tests, then based on the results of those Tests, can make decisions on how to proceed. Some example use cases for EQS could be to have an AI character find a cover location away from the Player or to find the nearest health or ammo in the Level.

An Environment Query is made up of several different pieces. You can call an Environment Query from a Behavior Tree, and then the actual Environment Query will use its Generator, reference its Contexts, and use its Tests to give the Behavior Tree the highest weighted result.

In this guide, we create an AI that randomly moves around the environment until seeing the player. When seeing the player, the AI uses the EQS system to find a location in the environment that provides the best vantage point while maintaining its distance. This can be useful in situations where you have an AI character that performs some form of ranged attack, as the AI will keep its distance from the player and try to retain a line of sight as seen in the example below.

By the end of this guide, you will have a basic understanding of the following systems:

Blueprint Visual Scripting

AI Controllers

Blackboards

Behavior Trees

Environmental Query System (EQS)

EQS Contexts

AI Debugging Tools

1 - Required Project Setup

In this step, we'll set up our project with some of the assets we'll need for our AI as well as enable the EQS system.

For this guide, we are using a new Blueprint Third Person Template project.

Inside your project, in the Settings > Plugins section, enable the Environment Query Editor option if necessary.



Enabling the EQS system will allow you to create and access EQS-related assets.

In the Content > ThirdPerson > Blueprints folder, copy the BP_ThirdPersonCharacter over to a new folder called AI.



In the AI folder, create the following three AI assets from the +Add > Create Advanced Asset > Artificial Intelligence option:



Blackboard named BB_Enemy

Behavior Tree named BT_Enemy

Environment Query named EQS_FindPlayer

Create a new Blueprint Class of the AIController type and call it AIC_Enemy.



Create a new Blueprint Class of the EnvQueryContext_BlueprintBase type and call it EQC_PlayerContext.



Contexts can be used in the EQS system for reference when applying various Tests, for example, "EQS, how close am I to the specified Context" is a Test we could run. This asset will be used to provide the Player Character as a Context when we perform Tests a little later in this guide.

2 - Environment Query Context

In this step, we establish a Context for the EQS system of the Player Character that will be used in Tests later in the guide.

Open the EQC_PlayerContext asset, then in the My Blueprint panel, override the Provide Single Actor function.



You can provide individual Actors or Locations as a Context as well as a set of Actors or Locations.

In the Provide Single Actor function, use a Get Player Character call as the Resulting Actor.



This will retrieve the Player Character at run-time as the Context.

While we are focusing on Blueprint, in this case, a more optimized approach would be to create the Context through C++.

3 - EQS Setup

In this step, we jump into the EQS editor and set up the Tests for finding a location that has a line of sight to the Player Character.

Inside EQS_FindPlayer, drag off the Root node in the graph and add a Points: Grid node.



Several different types of Generators are used to create Items about a Context. Those items are then used in Tests (for example, how far is Item X from Context Y). From the results of the Tests, Items are culled or scored and can be used to determine what is the "best" (highest or lowest scoring) option.

In this example, we will generate a series of points on a grid around the AI that will put it into a position where it can see the Player Character.

In the Details panel, change the GridHalfSize to 800 and the Space Between to 150.0.



These settings are used to define the possible number of points to test against and the distance between those points. For performance reasons, you will want to keep this to a manageable size, as having a grid too large may start to impact your game's performance.

Using the Generate Around field, you can determine where the grid should be placed (in this case, around the querier or AI character). While it will also work if we set Generate Around to use the Player Context we created, we don't want the AI to move up to a point on the grid near the Player if it already has a line of sight to the Player.

The Projection Data option provides additional fields for determining how the grid is generated, for this example, we can leave these as default but you can come back and adjust these settings if you desire.

Right-click on the SimpleGrid node and under Add Test select Trace.



The Trace Test will be used to determine if a point on the grid can see the Player Character.

The order in which you add Tests to a Generator is irrelevant. Tests get sorted by putting the Filters first (so that subsequent Tests deal with as small of an Item collection as possible) and also filter by cost (so the distance filter will be executed before the Line of Sight filter).

Right-click and add another Test, of the Distance type.



After the Trace Test returns points that can see the Player Character, the Distance Test will be used to score those points based on their proximity to the Player Character.

Select the Trace Test, then in the Details panel set the following options:



Test Purpose = Filter Only

Context = EQC_PlayerContext

Bool Match = Disabled

Here we are providing the Player Character as the point of reference (Context) in the Trace Test for visibility. By disabling the Bool Match option, we are stating that we want to filter out any points that cannot see the Player Character.

Select the Distance Test, then in the Details panel, change the Test Purpose to Score Only and the Scoring Factor to -1.0.



The Distance Test Purpose is to score the Items returned and the Scoring Factor of -1.0 scores points that are closer to the Player's Character. If we leave this as 1.0, it will return points that are furthest away from the player which may cause the AI to run right past the Player Character in an attempt to reach the furthest point.

There are additional scoring options such as clamping the scores to a minimum or maximum value, changing the Scoring Equation which changes the curve equation applied to the normalized score before being multiplied by the Scoring Factor, defining the Normalization Type or assigning a Reference Value used to normalize scores. For this example, we can leave these all at their default settings.

4 - Blackboard and Behavior Tree Setup

In this step, we set up the Blackboard Keys and lay out the branches of our Behavior Tree.

In the BB_Enemy Blackboard asset, create the following three Keys:



Bool named HasLineOfSight

Vector named MoveToLocation

Object with Base Class set to Actor named TargetActor

These Keys will be used to update and move between branches in our Behavior Tree.

Open the BT_Enemy Behavior Tree and create the graph below using Selectors, Sequences, and a Wait Task node:



Click image for full view.

Above, we have three main branches. The left most branch uses a Selector node (which we have named In Combat) to switch between two Sequence nodes (one called Attack and another called Move into Position). When the AI is not executing the "In Combat" branch, it will execute the next branch which we have named Patrolling. In the event for some reason, the AI is not in either combat or patrolling, we have a fail-safe task to wait (which we have set to 1 second) before trying to move to another branch.

5 - Behavior Tree: Patrol Setup

In this step, we set up the patrolling branch of the Behavior Tree.

Off the Patrolling Sequence node, add a Move To Task (set to MoveToLocation) and a Wait Task (set to 5 +/- 1 second).



This will instruct the AI to move to the Blackboard Key MoveToLocation and then wait the specified time, however, we still need to define the vector value for MoveToLocation.

From the Toolbar create a New Task, then in the Content Drawer, call it BTT_RandomLocation.



In BTT_RandomLocation, recreate the Blueprint Graph below:

Click for full image.

Using an Event Receive Execute AI node, off the Controlled Pawn you can Get Actor Location and use that as the Origin for the Get Random Reachable Point in Radius function (which we've set to 1000 as the Radius).

Use the Return Value from the GetRandomReachablePointInRadius node as a Branch condition. Off the True pin, use the Random Location value and Set Blackboard Value as Vector with the Key being a Blackboard Key Selector variable called MoveToLocation.

Off the False pin, Set Blackboard Value as Vector with Get Actor Location as the Value. This is if a random point is not found, we take the character's existing location before trying to find a new location. End the Task with both execution wires feeding into a Finish Execute node with Success enabled.

Before adding this as a Task in the Behavior Tree, we'll want to be able to set the value of MoveToLocation so we need to make sure that it is set to Instance Editable by clicking the eye icon in the My Blueprint panel.



In the Behavior Tree, add the BTT_RandomLocation Task (setting MoveToLocation in the Details panel) as the first node under Patrolling.



6 - Behavior Tree: In Combat Setup

In this step, we set up the tasks associated with the In Combat branch including our EQS_FindPlayer query used to find a location that has a line of sight to the Player Character.

Right-click on the In Combat Selector and add a Decorator of the Blackboard type with the following settings:



Observer aborts set to Lower Priority

Blackboard Key set to TargetActor

Here we are stating that once TargetActor becomes set, execute the In Combat branch aborting any lower priority tasks.

Right-click on the Attack Sequence and add a Decorator of the Blackboard type with the following settings:



Notify Observer set to On Value Change

Observer aborts set to Lower Priority

Blackboard Key set to HasLineOfSight

Here we are stating that if HasLineOfSight is Set, then execute the Attack branch. If HasLineOfSight is not set, execute a different branch until HasLineOfSight is set again.

Off the Attack node add a Rotate to face BB entry (set to TargetActor).



This will cause the AI to rotate towards the TargetActor while in the "attack" branch. For this example, we do not have an attack to give our AI however this is something you can add later on if you desire.

Off the Move Into Position node, use the Run EQSQuery node.



The Run EQSQuery node can be used to execute an EQS Query that will update the assigned Blackboard Key.

In the Details panel for the Run EQSQuery node, set the Blackboard Key to MoveToLocation and the Query Template to EQS_FindPlayer.



Add a MoveTo (set to MoveToLocation) and Rotate to face BB entry (set to TargetActor) following the Run EQS Query.



The Behavior Tree will run the EQS Query to update the Blackboard Key MoveToLocation and the AI will then move to that location and rotate to face the TargetActor (Player Character).

The full Behavior Tree should look like the following:



Click image for full view.

7 - AI Controller Setup

In this step, we set up our AI Controller to run our Behavior Tree as well as provide a way for the AI to see the Player Character using AI Perception.

In the AIC_Enemy Blueprint, add an Event On Possess and connect to a Run Behavior Tree (set to BT_Enemy).



Add an AIPerception component with the following AI Sight config settings:



Senses Config add an AI Sight config

Detect Neutrals set to enabled

This will enable the AI to sense other Actors and fire an event when an Actor has been perceived by the Perception system. Currently, by default, Players do not get assigned an affiliation and can only be assigned one through C++ code. To circumvent this, we are enabling neutrals to be detected by the Perception system and will use Actor tagging to only perceive Actors tagged as "Player".

For the AIPerception component, under Events, add an On Target Perception Updated then promote the Actor pin to a variable called Perceived Actor.



Click image for full view.

When the AI perceives something, that Actor will be stored as a variable which we will use later to update our Blackboard.

Add two Branch nodes with the following conditions:



Click image for full view.

1st Branch Condition set to Actor Has Tag with the Tag of Player and the Target beingthe Actor from Perception Updated.

2nd Branch Condition set to Successfully Sensed from the Stimulus pin of Perception Updated Event.

Above, if the perceived Actor has the Tag of Player, the Branch continues to check if that Actor was successfully sensed or not. If it doesn't have the Tag of Actor (another enemy perhaps) it does not proceed on.

Off the False pin of the 2nd Branch, add the 3 nodes shown below:



Above we have a Set Timer by Event node (set to 8.0) and promoted the Return Value to a variable called LostSightTimer. We then assign a Custom Event we created and called LostSight as the Event Delegate.

Create 2 Functions in the My Blueprint panel called: UpdateSightKey and UpdateTargetKey.



We will use these two functions to update our Blackboard Keys that are used to make decisions in our Behavior Tree.

For UpdateSightKey, add a Bool input called HasLineOfSight.



In UpdateSightKey right-click and get the Blackboard variable, then Set Value as Bool with Key Name using HasLineOfSight.



This enables us to use this function to pass through a bool value to our Blackboard Key, updating the HasLineOfSIght key.

For UpdateTargetKey, add an Actor input called TargetActor.



In UpdateTargetKey right-click and get the Blackboard variable, then Set Value as Object with Key Name using TargetActor.



Similar to the UpdateSightKey function, this is used to update the Blackboard Key TargetActor with whatever Actor we pass through.

Add UpdateSightKey and UpdateTargetActor functions to the False condition as shown:



When the AI Perception does not successfully sense the Actor who has the tag of Player, the false condition will start a timer (storing it in a handle for later) and will update the Blackboard Key HasLineOfSight to false. After the time specified (8.0 seconds), the Custom Event LostSight will execute, clearing the TargetActor Blackboard Key (meaning we no longer are targeting the Player and have lost sight of them).

You can tune and tweak the amount of time before the AI "gives up" chasing the Player Character by adjusting the Time value on the Timer.

Off the True pin of the 2nd Branch, use LostSIghtTimer and Clear and Invalidate Timer by Handle.



This will stop and reset the Timer used when losing sight of the Player Character.

Add the UpdateSightKey (set to enabled) and UpdateTargetKey (set to Perceived Actor).



The full graph should look similar to below:



Click image for full view.

Our AI Controller is now set up, runs our Behavior Tree, and updates our Blackboard Keys based on when we perceive an Actor with the tag Player through the AI Perception system.

8 - Final Setup

In this step, we set up the enemy AI Character Blueprint, add the Tag Player to the Player Character Blueprint so it can be perceived by the AI, and add a NavMeshBoundsVolume and some meshes so the AI knows how to move around the environment and we can break line of sight easier.

Open BP_Enemy, in the Details panel, enable Use Controller Rotation Yaw and set AI Controller Class to AIC_Enemy.



Click image for full view.

For the AI to execute the rotate task inside the Behavior Tree, we need to enable Controller Rotation Yaw. We also assign the custom AI Controller class that has our logic in it and runs the Behavior Tree. Optionally, we deleted all the script that was copied over from the Player Character (as well as the Camera Component) as we will not need it for the AI Character.

From the Modes panel, add a NavMeshBoundsVolume to the Level and scale it so it encapsulates the Level.



You can press the P key to toggle on/off the debug grid which shows navigatable paths in green. Or during gameplay with the console command show Navigation true (to display) or false (to hide).

Right-click on the BP_ThirdPersonCharacter in the Level, then select Edit BP_hirdPersonCharacter.



In the Details panel, search for Tag, then add a Tag called Player.



Inside our AIC_Enemy Blueprint when the AI Perception system perceives an Actor, this Actor has the tag of Player so our Branch will be evaluated as True.

Inside the Level, scale up and add multiple versions of the Cube Mesh to provide additional cover points to break the line of sight.



Click the Play button from the Toolbar to play in the Level.

9 - End Result

While playing in the Editor, the AI will patrol around randomly until seeing the Player. After seeing the Player, it will rotate and face the Player and attempt to move to a new location when losing sight of the Player. Using EQS, it will find a location that will provide a line of sight to the Player but remain a distance away. If it does not see the Player again while moving to a new location, after some time the AI will give up chasing and go back to patrolling as portrayed in the video below.

You can use the AI Debugging Tools to view any active EQS queries (in addition to Behavior Trees or Perception info). To activate AI Debugging at runtime, press the ' (apostrophe) key, then select 1 (for general AI debugging), 2 (for Behavior Trees), 3 (for EQS), or 4 (for AI Perception). Below, we activate AI Debugging and bring up the EQS Debugging tools.

While the EQS Debugging tools are running, you can see the points from our Grid test along with their score values. You will also see which point was selected, denoted with the text Winner. These tools are useful to see which points are being evaluated and why one point may have been selected over another point based on the score values.

In addition to using the EQS Debugging tools, there is a special type of Pawn called the EQS Testing Pawn that can be used to debug EQS queries while in the Editor. You can create this Pawn, by creating a new Blueprint Class of the EQS Testing Pawn Class.



Our current setup uses the Player Character as a Context for evaluation in our EQS Test. To test while the game is not running, we would need to make a slight modification to the EQS_PlayerContext Blueprint and override the Provide Actors Set function.



We can use Get All Actors of Class set to BP_ThirdPersonCharacter which provides the Resulting Actors Set:



When adding the EQS Testing Pawn to the Level, in the Details panel, you can assign the Query Template (which we've set to our EQS_FindPlayer query).



This enables you to see the results of your test while in you are in the Editor as seen below:

EQS Data is also being recorded through VisLog which you can reference. Please see Visual Logger for more information.

EQS Basics

Enabling EQS

Previewing an EQS Query

The Environment Query System (or EQS for short) is a feature within the AI Tools in Unreal Engine 5 (Unreal Engine) that can be used for collecting data about the environment. Then, through the use of a Generator, the system can ask questions about that data through a variety of user-defined Tests, returning the best Item that fits the types of questions being asked. Some example use-cases for EQS could be to find the closest health pickup or ammo, figure out which enemy is the highest threat, or find a line of sight to the Player (an example of which is shown below).



The conceptual idea and theory behind EQS come from Unreal Engine 3's Environment Tactical Query (ETQ) system which you can read more about in the following article, Asking the Environment Smart Questions.

EQS Basics

EQS Query assets can be created in the Content Drawer and can be edited inside a special Environmental Query Editor. The Environmental Query Editor is a node-based editor where you can add a Generator node to produce Items, add your desired Tests to run on those Items and the Context in which to run them. Unreal Engine supplies many Generator types by default, however, you can create your custom Generators through Blueprint (or C++ for even faster execution).



Above, we add a Distance Test to our existing Generator.

Similar to Generators, there are several different types of Tests you can run to filter and (or) score the Items returned. Unlike Generators, custom Tests can only be created through C++. Multiple Tests can be added to a Generator and is a common practice to narrow down the Item results that are returned. The order in which you add Tests to a Generator does not matter as filter Tests are done before scoring Tests. This is done so that fewer Items are returned and need to be scored. Refer to the table below for the type of tests.

Node Type

Description

Generator

This produces the locations or Actors, referred to as Items, that will be tested and weighted.

Contexts

These are a frame of reference for the various Tests and Generators.

Tests

These are how the Environment Query decides which Item from the Generator is the "best" option.

Please refer to the EQS Node Reference page for more information on each type.

Once you have set up your EQS Query, you can run it through a Behavior Tree using the Run EQS Query Task node.



For a full walk-through of creating and using an EQS Query, please see the EQS Quick Start Guide.

Enabling EQS

Before you can start working with EQS, you will need to enable it from the Project Settings menu.

Under the Settings > Plugins section, enable the Environment Query Editor option if necessary.



Previewing an EQS Query

You can preview the results of an EQS Query inside the Editor, where weighted/filtered results will be represented by debugging spheres.



In the image above, we debug an EQS Query that returns a location that provides a line of sight to the Player Character in the Level.

Please see AI Debugging or EQS Testing Pawn for more information.

Enabling EQS

Creating an EQS Query

Editing an EQS Query

Previewing an EQS Query

Using EQS with Behavior Trees

Using EQS with Native Code

This page covers the typical workflows for enabling, creating, and editing Environmental Query System (EQS) assets.

Enabling EQS

Before you can start working with EQS, you will need to enable it from the Project Settings menu.

Under the Settings > Plugins section, enable the Environment Query Editor option if necessary.



Creating an EQS Query

To create an EQS Asset:

Click the +Add button in the Content Drawer, then under Artificial Intelligence, select Environment Query.



Enter in a name for your new EQS asset.



In addition to Environment Query, you can create custom Generator and Context Blueprint assets in the Content Drawer.

Editing an EQS Query

Inside the EQS asset, you can use a Generator to produce the locations or Actors that will be tested and weighted, provide a Context or frame of reference, and Tests to determine which item from the Generator is the best option. The following section will illustrate how to create each of these within the EQS asset.

To add a Generator:

Right-click in the EQS Graph and select your desired Generator type.



After adding a Generator, drag off the Root node and connect it to your Generator.



While you can have more than one Generator connected to the Root, only the left-most Generator is used in the Query.

To add a Test:

Right-click on a Generator and select a Test to add.



After adding a Test, it will appear attached to the Generator. Select the Test to adjust properties in the Details panel.



To define a Context:

In the Details panel for a Test, change the EnvQueryContext to your desired Context.



The property name may vary based on the type of Test. Please see Tests for more information.

Previewing an EQS Query

You can preview the results of an EQS Query inside the Editor, where weighted/filtered results will be represented by debugging spheres.



In the image above, we debug an EQS Query that returns a location that provides a line of sight to the Player Character in the Level.

Please see AI Debugging or EQS Testing Pawn for more information.

Using EQS with Behavior Trees

After creating EQS Query, you can run the query inside a Behavior Tree as part of a Task.

Inside a Behavior Tree, right-click and add the Run EQS Query Task node.



For Run EQS Query, assign the Query Template (desired EQS asset) to execute, and the Blackboard Key it should return.



The Blackboard Key that is returned will be the highest weight result (Object or Vector). In the example above, we have an EQS Query that is used to locate the Player and provide that location back to a Blackboard Key called MoveToLocation.

You can optionally add parameters to pass to the EQS asset through the Query Config option.

Using EQS with Native Code

While EQS Queries generally run within Behavior Trees, you can also use them directly from native code. The following example shows a hypothetical query that finds a safe place for a character or item to spawn within a specific zone:

An Environment Query is made up of many different pieces. You must call an Environment Query from a Behavior Tree, and then the actual Environment Query will use its Generator, reference its Contexts, and use its Tests to give the Behavior Tree the highest weighted result.

Node Type

Description

Generator

Produces the locations or Actors, referred to as Items, that will be tested and weighted.

Contexts

Provides a frame of reference for the various Tests and Generators.

Tests

Establishes how the Environment Query decides which Item from the Generator is the best option.

Please refer to the links below for additional information on each subject.



Describes how Generators are used within the EQS system.



Describes how Contexts are used within Tests and Generators in the EQS system.



Describes how to use Tests within EQS to generate the "best" option.

Actors of Class

Composite

Current Location

Custom Generators

Points: Circle

Points: Cone

Points: Donut

Points: Grid

Points: Pathing Grid

Within the Environmental Query System (EQS), Generators are used to produce the locations or Actors (referred to as Items) that will be tested and weighted, with the highest weight location or Actor being returned to the Behavior Tree. There are different types of Generators that you can use to retrieve information and they can be created either in Blueprint or C++.

Actors of Class



The Actors of Class Generator finds all of the Actors of a given class within the specified Search Radius around the Search Center. The Actors returned can be used as Items in your tests.



Property

Description

Searched Actor Class

The Actor class to look for (for example, Pawn, Character).

Generate Only Actors in Radius

If enabled, this will only return Actors of the specified Searched Actor Class within the Search Radius. If disabled, it will return all Actors of the specified Searched Actor Class in the game world. You can also optionally include user-defined Data Bindings to go along with this option.

Search Radius

The max distance to look for the specified Searched Actor Class.

Zero and negative values will never return any results.

Search Center

The context to center to search for, such as from the Querier or perhaps some other context.

Option Name

This property is inherited from the base class of the Generator ActorsOfClass. It is mostly used when displaying the Name of this Generator (for example, HUDs or output messages).

Auto Sort Tests

If enabled, Tests will automatically be sorted for best performance before the query is run.

Composite



When setting up an EQS Query, there may be instances where you want to include more than one Generator in a test case. With the Composite node, you can add multiple Generators to an array, which can be used in your Tests.



Property

Description

Generators

Enables you to add multiple Generators to include in the test.

Allow Different Item Types

This allows tests to be performed on Generators with different Item types.

The generator will use ForcedItemType for raw data and you must ensure the proper memory layout of child Generators as they write to memory blocks through their Item types. For example, data must fit into blocks allocated by ForcedItemType while Tests will read item location/properties through ForcedItemType.

Forced Item Type

The Item type to use in Tests. For example Actor, Direction, or Point.

Option Name

This property is inherited from the base class of the Generator ActorsOfClass. It is mostly used when displaying the name of this Generator (for example, HUDs or output messages).

Auto Sort Tests

If enabled, Tests will automatically be sorted for best performance before the query is run.

Current Location



The Current Location Generator can be used to get the location of the specified Query Context to validate Tests.



Property

Description

Query Context

The Context to use in the Test and its current location.

Option Name

This property is inherited from the base class of the Generator ActorsOfClass. It is mostly used when displaying the Name of this Generator (for example, HUDs or output messages).

Auto Sort Tests

If enabled, Tests will automatically be sorted for best performance before the query is run.

Custom Generators

In addition to the Generator types provided by the Engine, you can create your custom Generators by creating a new Blueprint of the EnvQueryGenerator_BlueprintBase class type.



Generators developed in C++ will execute generally faster than that developed through Blueprint.

Once created, your custom Generator will be available within an Environmental Query:



Inside your custom Generator, there is a function you can override called Do Item Generation:



When you override this function, you'll get an array of locations that are the Context locations passed in from the Environmental Query.



Depending on the Context, the array may vary. For example, this could be an array of just a single entry containing the location of the Querier, or, it could be the locations of every health pickup inside your Level.

Since functions can only return one value, the Do Item Generation function has two arrays it can pass back to the Environment Query: Add Generated Actor and Add Generated Vector.



The Add Generated Actor node will add an Actor to the Actor return array. This node can also be used with the Add Generated Vector node (below) to also return location values. How the Generator determines what it is passing back to the Behavior Tree is based on what Blackboard key you are setting from the Environment Query node.



Points: Circle



The Points: Circle Generator radiates traces out from the Circle Center, returning the hits on the edge of the radius (of the generated Circle) as Items.



Property

Description

Circle Radius

The max radius of the circle that will expand out from the Circle Center context.

Spawn Between

The space (in centimeters) between the Items generated on the outer edge of the circle.

Number Of Points

The number of Items to be generated on a circle.

Arc Direction

Define the mode at which the arc direction is determined. You can choose between Two Points (direction from the location of one context to another) or Rotation (where the context's rotation will be used as a direction).

Arc Angle

Defines the angle at which the arc is measured in degrees.

Circle Center

The context used as the center for the circle.

Ignore Any Context Actors when Generating Circle

When enabled, ignore tracing into context Actors when generating the circle.

Circle Center ZOffset

Optional offset to apply to the context in the Z-axis.

Trace Data

Options related to how the trace is performed.

Property

Description

Trace Mode

Shape used for geometry tracing.

Navigation Filter

Navigation filter used for tracing.

Extent X

Shape parameter for the trace.

Projection Data

If the resulting Items should be projected onto the NavMesh (and which NavMesh data set to use).

Option Name

This property is inherited from the base class of the Generator ActorsOfClass. It is mostly used when displaying the Name of this Generator (for example, HUDs or output messages).

Auto Sort Tests

If enabled, Tests will automatically be sorted for best performance before the query is run.

Points: Cone



The Points: Cone radiates a trace out from the Center Actor in the shape of a cone with the specified Cone Degrees as Items.



Property

Description

Aligned Points Distance

The distance between each point on the same angle.

Cone Degrees

Maximum degrees of the generated cone.

Angle Step

The step of the angle increase. Angle step must be greater than or equal to one. Smaller values generate fewer Items.

Range

Distance to generate the cone from the context.

Center Actor

The Actor (or Actors) that will generate a cone in their facing direction.

Include Context Location

Whether to include Center Actor locations when generating Items.

This option skips the MinAngledPointsDistance parameter.

Projection Data

If the resulting Items should be projected onto the NavMesh (and which NavMesh data set to use).

Option Name

This property is inherited from the base class of the Generator ActorsOfClass. It is mostly used when displaying the Name of this Generator (for example, HUDs or output messages).

Auto Sort Tests

If enabled, Tests will automatically be sorted for best performance before the query is run.

Points: Donut



The Points: Donut Generator, creates a shape-based trace with the user specified Number Of Rings radiating from the Center Context.



Property

Description

Inner Radius

The minimum distance between point and context.

Outer Radius

The maximum distance between point and context.

Number of Rings

The number of rings to generate.

Points Per Rig

Number of Items to generate for each ring.

Arc Direction

Define the mode in which the arc direction is determined. You can choose between Two Points (direction from the location of one context to another) or Rotation (where the context's rotation will be used as a direction).

Arc Angle

Defines the angle at which the arc is measured in degrees.

Use Spiral Pattern

If enabled, the rings of the wheel will be rotated in a spiral pattern. If disabled, they will all be at a zero rotation, looking more like spokes on a wheel.

Center

The context to center the search on, such as from the Querier or perhaps some other context.

Projection Data

If the resulting Items should be projected onto the NavMesh (and which NavMesh data set to use).

Option Name

This property is inherited from the base class of the Generator ActorsOfClass. It is mostly used when displaying the Name of this Generator (for example, HUDs or output messages).

Auto Sort Tests

If enabled, Tests will automatically be sorted for best performance before the query is run.

Points: Grid



The Points: Grid Generator will generate a grid of Items around the specified querier assigned under Generate Around.



Property

Description

GridHalfSize

The height and width of the grid of Items to generate.

Space Between

The distance between the grid Items.

Generate Around

The context used to generate the grid around.

Projection Data

If the resulting Items should be projected onto the NavMesh (and which NavMesh data set to use).

This will move Items that may be inside walls or blocked, back onto the NavMesh, which can create bunching if a grid line happens to be just beyond the edge of the NavMesh.

Option Name

This property is inherited from the base class of the Generator ActorsOfClass. It is mostly used when displaying the Name of this Generator (for example, HUDs or output messages).

Auto Sort Tests

If enabled, Tests will automatically be sorted for best performance before the query is run.

Points: Pathing Grid



You can use Points: Pathing Grid to generate a grid around the given Context location.



Property

Description

Path to Item

If the pathfinding direction should be towards (enabled) or away (disabled) from the Item.

Navigation Filter

Navigation filter to use in pathfinding.

GridHalfSize

Half of square's extent (edge distance).

Space Between

Defines the generation density of points on the grid.

Generate Around

The context used to generate the grid around.

Projection Data

If the resulting Items should be projected onto the NavMesh (and which NavMesh data set to use).

This will move Items that may be inside walls or blocked, back onto the NavMesh, which can create bunching if a grid line happens to be just beyond the edge of the NavMesh.

Option Name

This property is inherited from the base class of the Generator ActorsOfClass. It is mostly used when displaying the Name of this Generator (for example, HUDs or output messages).

Auto Sort Tests

If enabled, Tests will automatically be sorted for best performance before the query is run.

Scan Range Multiplier

Multiplier for the max distance between point and context.

Common Test Properties

Distance

Dot

Gameplay Tags

Overlap

Pathfinding

Pathfinding Batch

Project

Trace

Within the Environmental Query System (EQS), a Test can be performed to determine which Item produced from a Generator is the "best" option, given the Context (or frame of reference). Several Tests are provided with the Engine that covers a good percentage of use cases, such as "can an Item trace (see) another Location" or "is the distance between and Item and its Context within a specified range". You can add multiple Tests to a Generator which can be an effective way to narrow down the results, giving you the best possible option.

If the default Engine Tests do not accomplish what you desire, you can create custom Tests through C++ code.

Common Test Properties

Each Test type has some unique properties to it that enables you to define how the Test is performed. However, for all Tests, some common properties are used to define what the purpose of the Test is and what to do with the results. For example, is the Test used for filtering out results, or is it being used to score results and weight them, or a combination of both? You can define the Test Purpose among other properties from the Details panel when selecting the Test in the EQS Editor.

Test Properties

Property

Description

Test Comment

Optional comment or explanation about what the Test is used for. This is useful when the purpose of the Test may not be clear, especially when there are multiple Tests of the same type.

Test Purpose

This defines what additional options are available in the Test and what the test should be used for.

Property

Description

Filter Only

Used to filter possible results. Items that fail the Test will be removed.

Score Only

Used to score possible results. Items returned are given a weight value.

Filter and Score

Used to filter and score results.

Filter Properties

The following options are available when Test Purpose is set to Filter (or set to Filter and Score):

Filtering is done before scoring to avoid calculating the score on filtered-out items.

Property

Description

Bool Match

This is the value (true or false) to match to grant a scoring factor. When performing a Test, not matching this value will not change the score. For example, on a Trace Test, true or false did we hit something? Or for Pathing does a path exist?

Multiple Context Filter Op

Defines the filtering operator when the Distance To Context returns multiple items. All Pass means all Contexts must pass while Any Pass states at least one Context must pass.

Float Value Min

Filter any value less than or equal to this value.

This option is only available for Distance and Dot Tests.

Float Value Max

Filter any value greater than or equal to this value.

This option is only available for Distance and Dot Tests.

Filter Type

Used to change the type of Filter applied to Minimum, Maximum, or a Range of values. Any values outside the values specified in the Float Value Min and/or Float Value Max properties will be culled out.

This option is only available for Distance and Dot Tests.

Score Properties

The following options are available when Test Purpose is set to Score (or set to Filter and Score).

Property

Description

Multiple Context Filter Op

Defines the filtering operator when the Distance To Context returns multiple items. All Pass means all Contexts must pass while Any Pass states at least one Context must pass.

Clamp Min Type

Defines whether a Specified Value should be used to normalize the raw test value before applying the scoring formula, or if the lowest value found (Tested) should be used.

This option is only available for Distance and Dot Tests.

Clamp Max Type

Defines whether a Specified Value should be used to normalize the raw test value before applying the scoring formula, or if the highest value found (Tested) should be used.

This option is only available for Distance and Dot Tests.

Scoring Equation

This modifies the score of the Test to adhere to a curve of the Constant, Linear, Square, Inverse Linear, or Square Root type.

This option is only available for Distance and Dot Tests.

Scoring Factor

The weight (factor) in which to multiply the normalized score after the scoring equation is applied. This value can be a negative number.

This option is only available for Distance and Dot Tests.

Normalization Type

Specifies how to determine the value span used to normalize score. Absolute (use 0 as the base of normalization range) or Relative to Scores (use the lowest Item score as the base of normalization range).

This option is only available for Distance and Dot Tests.

Reference Value

Used to normalize Test's results in such a way that the closer a value is to Reference Value the higher normalized result it will produce. The value farthest away from Reference Value will be normalized to 0, and all other values in between will get normalized linearly with the distance to Reference Value.

This option is only available for Distance and Dot Tests.

Distance



The Distance Test will return the direct distance between the Item and the chosen Distance To property. If Distance To is more than one location, it averages the results of each distance check.



Property

Description

Test Mode

The method used to test Distance: in 3D space, in 2D as an XY plane, along the Z or Z (absolute) axis.

Distance To

The Context that will be used to measure the distance to.

Dot



The Dot Test calculates the Dot Product of two vectors. These can be Context rotations or vector from one point to another. This Test is useful for determining if something is facing something else.



The following properties are available for the Dot Test:

Property

Description

Line A Mode

This is used to define the direction of the first line used by the Test. There are two methods you use to obtain the direction:

Property

Description

Rotation

The specified Context will be used as a direction.

Two Points

Direction from Location of one Context to another.

Line B Mode

This is used to define the direction of the second line used by the Test. There are two methods you can use to obtain the direction:

Property

Description

Rotation

The specified Context will be used as a direction.

Two Points

Direction from Location of one Context to another.

Test Mode

Whether the Test should calculate using the complete 3D vector or just the 2D heading vector of the Line A and Line B vectors.

Absolute Value

This will make the Test return the Absolute Value of the Dot Product (a Dot Product returns a value from -1.0 to 1.0).

Gameplay Tags



The Gameplay Tags Test enables you to specify a Tag to query and attempt to match in your Test.



Property

Description

Tag Query to Match

Opens the Gameplay Tags Editor where you can specify the Tags to validate against.

Reject Incompatible Items

Controls how to treat actors that do not implement IGamePlayTgAssetInterface. If true, actors that do not implement the interface will be ignored, meaning they will not be scored and will not be considered when filtering. If false, actors that do not implement the interface will be included in filter and score operations with a zero score.

Overlap



The Overlap Test can be used to determine if an Item (or Items) are within the bounds defined in the properties.



Property

Description

Extent X

Shape parameter for the overlap along the X-axis.

Extent Y

Shape parameter for the overlap along the Y-axis.

Extent Z

Shape parameter for the overlap along the Z-axis.

Shape Offset

Offset from the Item location at which to test the overlap. For example, you may need to offset vertically to avoid overlaps with flat ground.

Overlap Channel

Geometry trace channel used for overlap.

Overlap Shape

The shape used for geometry overlap (Box, Sphere, or Capsule).

Only Blocking Hits

if set, overlap will only look for blocking hits.

Overlap Complex

If set, overlap will only run on complex collisions.

Skip Overlap Querier

If set, overlap will skip querier context hits.

Pathfinding



The Pathfinding Test can be used to determine if a path exists to (or from) the Context, how expensive the path to (or from) the Context is, or how long the path is.



Property

Description

Test Mode

The method in which to apply the Test:

Property

Description

Path Exist

Does the path exist to (or from) the Context

Path Cost

How expensive is the path to (or from) the Context.

Path Length

How long is the path to (or from) the Context.

Context

This is the Context of the path to or from.

Path from Context

Should the pathfinder go to (false) or from (true) the Context.

Filter Class

The optional navigation filter to use in pathfinding.

Skip Unreachable

If set, Items with failed paths will be invalidated.

When Test Mode is set to Path Cost or Path Length, the Filter and Score sections of the Details panel change to provide the options typically only available to the common properties outlined for Dot and Distance tests.

Pathfinding Batch



The Pathfinding Test can be used to determine if a path exists to (or from) the Context, how expensive the path to (or from) the Context is, or how long the path is. Every processed Context (paths) will be scored depending on the defined Test Mode.



Property

Description

Test Mode

The method in which to apply the Test:

Property

Description

Path Exist

Does the path exist to (or from) the Context.

Path Cost

How expensive is the path to (or from) the Context.

Path Length

How long is the path to (or from) the Context.

Context

This is the Context that the AI should path to or from.

Path from Context

Should the pathfinder go to (false) or from (true) the Context.

Filter Class

The optional navigation filter to use in pathfinding.

Scan Range Multiplier

The multiplier for the max distance between point and Context.

Skip Unreachable

If set, Items with failed paths will be invalidated.

When Test Mode is set to Path Cost or Path Length, the Filter and Score sections of the Details panel change to provide the options typically only available to the common properties outlined for Dot and Distance tests.

Project



The Project Test can be used to project the resulting Items onto the NavMesh (and which NavMesh data set to use).

This will move Items that may be inside walls or blocked, back onto the NavMesh, which can create bunching if a grid line happens to be just beyond the edge of the NavMesh.



Property

Description

Trace Mode

This is the shape used for geometry tracing:

Property

Description

Navigation

Does the path exist to (or from) the Context.

Geometry by Channel

Determines how expensive the path is to (or from) the Context by using channel tracing.

Geometry by Profile

Determines how expensive the path is to (or from) the Context by using profile tracing.

Navigation Filter

The (optional) navigation filter class to used.

Extent X

Shape parameter for trace.

Project Down

Search height is defined below the specified point.

Project Up

Search Height is defined above the specified point.

Post Projection Vertical Offset

This value will be added to the resulting location's Z-axis.

This can be useful when projecting points on navigation since the Navmesh is just an approximation of Level geometry and items may end up being under collide-able geometry which would, for example, falsify visibility tests.

Trace



The Trace Test will trace to (or from) an Item or Context and return if it hit it or not something. You can invert the result using the Filter option, Bool Match. One typical use-case for this type of test is to determine if an enemy can (or cannot) see a Player in the Level.



Property

Description

Trace Mode

This is the shape used for geometry tracing:

Property

Description

Geometry by Channel

Determines how expensive the path is to (or from) the Context by using channel tracing.

Geometry by Profile

Determines how expensive the path is to (or from) the Context by using profile tracing.

Trace Channel

This is the channel to perform the trace against. By default, Visibility and Camera are the available options however, additional channels can be added in the Edit Menu > Project Settings > Physics > Trace Channels section of the Project Settings.

Trace Shape

The shape to perform the trace: Line, Sphere, Box, or Capsule.

Trace Complex

Whether the trace should be against the mesh (complex) or just the simple collision.

Only Blocking Hits

Whether the trace uses blocking or non-blocking traces in its results.

Trace from Context

The Context to trace from, such as the Querier, an Item, or any custom Contexts you may have created.

Context

This is the other end of the trace.

Item Height Offset

This will add a Z offset, in cm, to the Item the Test is tracing to (or from).

Context Height Offset

This will add a Z offset, in cm, to the Context the test is tracing to (or from).

EnvQueryContext_Item

EnvQueryContext_Querier

EnvQueryContext_BlueprintBase

Within the Environment Query System (EQS), Contexts provide a frame of reference for any Tests or Generators used. A Context can be as simple as the Querier (who is performing the Test) or more complex such as All Actors of a Type. A Generator, such as a Points: Grid, can use a Context that returns multiple locations or Actors. This will create a grid (of the defined size and density) at the location of each Context. In addition to Engine supplied Contexts, you can create custom Contexts in Blueprint with the EnvQueryContext_BlueprintBase class or through C++ code.

EnvQueryContext_Item

Items are created by the Generator, and if using the EQS Testing Pawn, they are the spheres that appear in the Editor. An EnvQueryContext_Item is either a location (FVector) or an Actor (AActor).

EnvQueryContext_Querier

The Querier is the Pawn that is currently possessed by an AI Controller and is executing the Behavior Tree that initiated the Environment Query. An example of where Querier as the Context could be used is if you want to search the environment around the AI character for an item they can use or find a place that provides cover from the player, or just to determine the current location of the AI performing the query.

In the Details panel for a Generator type, you can assign the Querier as a Context for the following properties:

Generator

Property

Actors of Class

Search Center



Current Location

Query Context



Points: Circle

Circle Center



Points: Cone

Center Actor



Points: Donut

Center



Points: Grid

Generate Around



Points: Pathing Grid

Generate Around



EnvQueryContext_BlueprintBase

You can create a custom Context through Blueprint using the EnvQueryContext_BlueprintBase Class. This provides four functions that can be overridden, enabling you to add your custom Contexts for use within Tests in a query.

To use a custom Context:

Create a new Blueprint of the EnvQueryContext_BlueprintBase class.

In EnvQueryContext_BlueprintBase, click Override and select the type of function you wish to use.

Refer to the table below for a description of each function override:

Function

Description

Provide Single Location

This returns a single location (vector). How you generate that location is up to you. For example, the function below will return the trace hit location of a random Actor (one that is found in the DesiredObjectType array, such as Pawn, Vehicle) found within 1500 cm of the Querier:



Click for the full image.

Provide Single Actor

This returns a single Actor. You can obtain that Actor through any method you desire. In this example, the function will return Player 0's controlled Actor:



Provide Locations Set

This returns an array of locations (vectors). How you generate these locations is up to you. In the example below, this function will trace from 16 evenly spaced locations on a circle with a radius of 1500 units, returning successful hits on the environment:



Click for the full image.

Provide Actors Set

This returns an array of Actors. You can use any desired method to obtain those Actors. In the example below, we use a Get All Actors of Class node to retrieve our specified class as the Actors to return:



Working with the EQS Testing Pawn

Evaluating Results

EQS Testing Pawn Properties

In addition to the AI Debugging tools, the Environment Query System has a specialized type of Pawn class called the Environment Query System Testing Pawn (EQSTestingPawn) that enables you to check out what your Environment Queries are doing. The exact makeup of your Environment Query will define the size and shape of what is created, but it will always be represented as colored spheres. Spheres that are on the color scale from green to red, indicate some level of the match for the various tests your Environment Query ran. Blue spheres indicate a failure or a boolean-type test that returned false, such as the Trace test.

Working with the EQS Testing Pawn

After enabling EQS and creating an EQS Query you can test the data while in the Editor using the EQS Testing Pawn.

In the Content Brawer, create a new Blueprint of the EQSTestingPawn class and give it any name.



Place the EQSTestingPawn in the Level, then in the Details panel, assign the EQS Query Template to test.

Click for full image.

Given the experimental nature of the Environment Query System, the EQSTestingPawn can be very processor intensive, and making changes to its active Query Template can cause your system to hang for extremely long times. It's best to clear the Query Template property while making edits to your Environment Query.

Depending upon the content of your query, when you have the EQSTestingPawn selected in the Level, debug spheres will appear in the Level that indicates the value of a match based on your conditions. Below we use the EQSTestingPawn and test a query that yields the best possible position in the Level that provides a line of sight to the Player Character. As we move the EQSTestingPawn around, the spheres update in color and value to indicate the new best match based on the position of the Player and EQSTestingPawn.

Evaluating Results

When evaluating the results of a Test using the EQSTestingPawn, the colored spheres and values indicate the level of the match an item has at a given location.

Blue Spheres: These spheres indicate that a Test has failed at that item, so the item is completely un-weighted and culled from the results. This usually occurs when a value is filtered out, such as using a Distance Test and filtering out any Item over (or under) a range. If you don't want a value to be culled completely, you can use the Clamp options in the scoring section. Below, we have a query that is running to find the line of sight to the Player. We have used a Visibility to cull out items where the AI would not have a line of sight to the Player (represented by the blue spheres).



Green to Red Spheres: Spheres range in color from green to red and indicate the desirability of the Item as the best match for the specified Test. Green is more desirable than red and the number shown is the weighted score of the Item. If previewing only one Debug Step, this value will be the final value from the selected Test. Below, we use a query to find the furthest point away from the player regardless of visibility.



EQS Testing Pawn Properties

With an EQSTestingPawn selected in the Level, the following properties are available inside the Details panel.

Property

Description

Query Template

The Environment Query that the EQSTestingPawn should use.

Query Config

Enables you to pass named values into the Environment Query to quickly adjust its settings.

Time Limit Per Step

If this value is set to anything greater than 0.0, it will cause the EQSTestingPawn to stop calculating a step at the time this property is set to. Helps to mitigate making adjustments to the Environment Query while using the EQSTestingPawn.

Note: This will not reduce the time it takes to calculate the locations for the Generator, such as using a large Simple Grid with a tight Density

Step to Debug Draw

Shows a single debug step. May not map to the order your steps appear in the Environment Query.

Highlight Mode

Determines if all spheres should be shown at the same size or if the best 5% or 25% of spheres should be shown (other spheres will be reduced in size).

Draw Labels

Enables drawing the weight or reason for failure on the debug spheres in the Viewport.

Draw Failed Items

Enables the culling of any failed tests, such as when a trace fails to find its target.

Re Run Query Only on Finished Move

Will only update the debug visualization in the Viewport when you stop moving the EQSTestingPawn. It's advised to keep this enabled unless you are working with a very quick Environment Query.

Should be Visible in Game

Makes the EQSTestingPawn, and its debug visualization, visible in the running game.

Tick During Game

Makes the EQSTestingPawn, and its debug visualization, tick during the running game.

Querying Mode

Changes what the debug view shows.

Value

Description

Single Result

Shows only the result for the item listed in the Step to Debug Draw property.

All Matching

Shows the final, filtered, and weighted score of the entire Environment Query.

Nav Agent Properties

Properties that determine how the Pawn navigates.

Value

Description

Nav Agent Radius

Radius of the capsule used for navigation/pathfinding.

Nav Agent Height

Total height of the capsule used for navigation/pathfinding.

Nav Agent Step Height

Step height to use, or -1 to use the default value from NavData's config settings.

Nav Walking Search Height Scale

Scale factor to apply to height of bounds when searching for NavMesh to project to when Nav Walking.

Preferred Nav Data

This property specifies the Navigation Data class type you want the Testing Pawn to perform its test against.

Can Crouch

If true, the Pawn is capable of crouching.

Can Jump

If true, the Pawn is capable of jumping.

Can Walk

If true, the Pawn is capable of walking or moving on the ground.

Can Swim

If true, the Pawn is capable of swimming or moving through fluid volumes.

Can Fly

If true, the Pawn is capable of flying.

AI Perception Component

AI Perception Properties

Perception Events

Perception Function Calls

Stimuli Source

Stimuli Properties

Stimuli Function Calls

AI Perception Debugging

In addition to Behavior Trees which can be used to make decisions on which logic to execute, and the Environmental Query System (EQS) used to retrieve information about the environment; another tool you can use within the AI framework which provides sensory data for an AI is the AI Perception System. This provides a way for Pawns to receive data from the environment, such as where noises are coming from, if the AI was damaged by something, or if the AI sees something. This is accomplished with the AI Perception Component which acts as a stimuli listener and gathers registered Stimuli Sources.

When a stimuli source is registered, the event On Perception Updated (or On Target Perception Updated for target selection) is called which you can use to fire off a new Blueprint Script and (or) update variables that are used to validate branches in a Behavior Tree.

AI Perception Component

The AI Perception Component is a type of Component that can be added to a Pawn's AIController Blueprint from the Components window and is used to define what senses to listen for, the parameters for those senses, and how to respond when a sense has been detected. You can also use several different functions to get information about what was sensed, what Actors were sensed, or even disable or enable a particular type of sense.

To add the AI Perception Component, click the +Add**button in your Blueprint and select AIPerception**.



Once the AI Perception Component has been added, you can access its properties inside the Details panel.

AI Perception Properties

In addition to the common properties available in the Details panel for the AI Perception Component, you can add the type of Senses to perceive under the AI Perception and Senses Config section. Depending on the type of Sense, different properties are available to adjust how the Sense is perceived.



The Dominant Sense property can be used to assign a Sense that should take precedence over other senses when determining a sensed Actor's location. This should be set to one of the senses configured in your Senses Config section or set to None.

If you want your AI to react to damage events such as Event Any Damage, Event Point Damage, or Event Radial Damage, you can use the AI Damage Sense Config. The Implementation property (which defaults to the engine class AISense_Damage) can be used to determine how damage events are handled, however, you can create your damage classes through C++ code.



Property

Description

Implementation

The AI Sense Class to use for these entry (defaults to AISense_Damage).

Debug Color

When using the AI Debugging tools, what color to draw the debug lines.

Max Age

Determines the duration in which the stimuli generated by this sense becomes forgotten (0 means never forgotten).

Starts Enabled

Determines whether the given sense starts in an enabled state or must be manually enabled/disabled.

The AI Hearing sense can be used to detect sounds generated by a Report Noise Event, for example, a projectile hits something and generates a sound that can be registered with the AI Hearing sense.



Property

Description

Implementation

The AI Sense Class to use for this entry (defaults to AISense_Hearing).

Hearing Range

The distance in which this sense can be perceived by the AI Perception system.

Lo SHearing Range

This is used to display a different radius in the debugger for Hearing Range.

Detection by Affiliation

Determines if Enemies, Neutrals, or Friendlies can trigger this sense.

Debug Color

When using the AI Debugging tools, what color to draw the debug lines.

Max Age

Determines the duration in which the stimuli generated by this sense becomes forgotten (0 means never forgotten).

Starts Enabled

Determines whether the given sense starts in an enabled state or must be manually enabled/disabled.

This asks the Perception System to supply the Requestor with PredictedActor's predicted location in PredictionTime seconds.



Property

Description

Debug Color

When using the AI Debugging tools, what color to draw the debug lines.

Max Age

Determines the duration in which the stimuli generated by this sense becomes forgotten (0 means never forgotten).

Starts Enabled

Determines whether the given sense starts in an enabled state or must be manually enabled/disabled.

The AI Sight config enables you to define parameters that allow an AI character to "see" things on your Level. When an Actor enters the Sight Radius, the AI Perception System signals an update and passes through the Actor that was seen (for example a Player enters the radius and is perceived by the AI who has Sight Perception).



Property

Description

Implementation

The AI Sense Class to use for this entry (defaults to AISense_Sight).

Sight Radius

The max distance over which this sense can start perceiving.

Lose Sight Radius

The max distance in which a seen target is no longer perceived by the sight sense.

Peripheral Vision Half Angle Degrees

How far to the side the AI can see in degrees. The value represents the angle measured to the forward vector, not the whole range.

You can use SetPeripheralVisionAngle in Blueprint to change the value at runtime.

Detection by Affiliation

Determines if Enemies, Neutrals, or Friendlies can trigger this sense.

This property can be used to set up Sight perception for teams. Currently, Affiliation can only be defined in C++. For Blueprints, you can use the Detect Neutrals option to detect all Actors, then use Tags to filter out Actor types.

Auto Success Range from Last Seen Location

When greater than zero, the AI will always be able to see the target that has already been seen as long as they are within the range specified here.

Point of View Backward Offset

Point of view move back distance for cone calculation. In conjunction with near clipping distance, this will act as a close by awareness and peripheral vision.

Near Clipping Radius

Near clipping distance, to be used with point of view backward offset. Will act as a close by awarness and peripheral vision.

Debug Color

When using the AI Debugging tools, what color to draw the debug lines.

Max Age

Determines the duration in which the stimuli generated by this sense become forgotten (0 means never forgotten).

Starts Enabled

Determines whether the given sense starts in an enabled state or must be manually enabled/disabled.

This notifies the Perception component owner that someone on the same team is close by (radius is sent by the gameplay code which sends the event).



Property

Description

Debug Color

When using the AI Debugging tools, what color to draw the debug lines.

Max Age

Determines the duration in which the stimuli generated by this sense becomes forgotten (0 means never forgotten).

Starts Enabled

Determines whether the given sense starts in an enabled state or must be manually enabled/disabled.

The AI Touch config setting gives you the ability to detect when the AI bumps into something or something bumps into it. For example, in a stealth-based game, you may want a Player to sneak by an enemy AI without touching them. Using this Sense you can determine when the Player touches the AI and can respond with different logic.



Property

Description

Debug Color

When using the AI Debugging tools, what color to draw the debug lines.

Max Age

Determines the duration in which the stimuli generated by this sense becomes forgotten (0 means never forgotten).

Starts Enabled

Determines whether the given sense starts in an enabled state or must be manually enabled/disabled.

Perception Events

The Events section enables you to define what happens when the AI Perception System receives an update or when the AI Perception Component is activated or deactivated.



Property

Description

On Perception Updated

This Event will fire when the Perception System receives an update and will return an array of Actors that signaled the update.

On Target Perception Info Updated

Notifies all bound objects that perception info has been updated for a given target. The notification is broadcasted for any received stimulus or on change of state according to the stimulus configuration.

On Target Perception Updated



This Event will fire when the Perception System receives an update and will return the Actor that signaled the update. It also returns an AI Stimulus struct that can be broken down to retrieve additional information.



Property

Description

Age

How long since the Stimulus occurred.

Expiration Age

How long before the Stimulus becomes invalid.

Strength

The weight defined in the Stimulus.

Stimulus Location

Where the Stimulus originated from.

Receiver Location

Where the Stimulus was registered by the AI Perception System.

Tag

Any Gameplay Tag associated with the Stimulus.

Successfully Sensed

Whether the Stimulus was sensed by the AI Perception System (returns True or False).

On Component Activated

An Event that is fired when the AI Perception Component is activated.

On Component Deactivated

An Event that is fired when the AI Perception Component is deactivated.

Perception Function Calls

The following functions can be called through Blueprint to get information from or affect the Perception System.

Function

Description

Get Actors Perception

Retrieves whatever has been sensed about a given Actor and returns a Sensed Actor's Data structure.

Get Currently Perceived Actors

Returns all Actors that are being perceived based on a given Sense. If no Sense is specified, all Actors currently perceived in any way will be returned.

Get Known Perceived Actors

Returns any Actors that have been perceived (and not yet forgotten) based on a given Sense. If no Sense is specified, all Actors that have been perceived will be returned.

Get Perceived Hostile Actors

Returns the list of Hostile Actors (any hostile Actors that had a stimulus sensed which is not expired or successfully sensed). The method can be overridden in Blueprint to return whatever Actors list the user wants.

Request Stimuli Listener Update

Manually forces the AI Perception System to update properties for the specified target stimuli listener.

Set Sense Enabled

Enable or Disable the specified Sense Class.

This only works if the given Sense has already been configured for the target component instance.

Stimuli Source

The AI Perception Stimuli Source Component gives the owning Actor a way to automatically register itself as a stimuli source for the designated Sense(s) within the Perception System. An example use case would be to have an AI character with an AI Perception Component set up to perceive stimuli based on Sight. You could then use the Stimuli Source Component in an Actor (such as an item pickup Actor) and register it as a stimuli for Sight (which would enable the AI to "see" the Actor in the Level).

To add the AI Perception Stimuli Source Component, click the +Add**button in your Blueprint and select AIPerception Stimuli Source**.



Once the AI Perception Stimuli Source Component has been added, you can access properties for it inside the Details panel.

Stimuli Properties

In the Details panel for the AI Perception Stimuli Source Component, the following two options are available for AI Perception:



Property

Description

Auto Register as Source

Whether to automatically register the stimuli for the specified sense with respect to the owning Actor.

Register as Source for Senses

An array of Senses to register as a source for. Click the + sign to add a Source, then click the drop-down and assign the desired Sense.



You can also assign any custom Senses that have been based on the AISense Class.

Stimuli Function Calls

The following functions can be called through Blueprint for the AI Perception Stimuli Source Component:

Function

Description

Register for Sense

Registers owning Actor as a stimuli source for the specified Sense class.

Register with Perception System

Registers owning Actor as a stimuli source for Senses specified in the Register as Source for Senses property and through the Register for Sense function call.

You do not need to call this function if the Auto Register as Source property is enabled.

Unregister from Perception System

Unregisters the owning Actor from being a source of Sense stimuli.

Unregister from Sense

Unregisters the stimuli for the specified sense with respect to the owning Actor.

AI Perception Debugging

You can debug AI Perception using the AI Debugging tools by pressing the '(apostrophe) key while your game is running, then pressing Numpad key 4 to bring up the Perception information.



Please see the AI Debugging tools page and the Perception section for more information.

Enabling AI Debugging

Nav Mesh

AI

Behavior Tree

EQS

Perception

Once you've created an AI entity you can diagnose problems or simply view what an AI is doing at any given moment using the AI Debugging Tools. Once enabled, you can cycle between viewing Behavior Trees, the Environment Query System (EQS), and the AI Perception systems all within the same centralized location.

To make the most of the AI Debugging tools, you will need a Pawn with an AI Controller in your Level that is running a Behavior Tree or has an AI Perception component. When your AI is executing an EQS, it will be reflected inside the AI Debugging tool when it is running.

Enabling AI Debugging

To enable AI Debugging, while your game is running, press the ' (apostrophe) key.



The following options are available while the AI Debugging Tools are enabled:

Command

Option

' (apostrophe key)

Closes the AI Debugging tools.

Numpad Keys (0-4)

Toggles the AI information that is being displayed:

Numpad Key

Debug Information

Numpad 0

Toggles the display of the currently available Nav Mesh data.

Numpad 1

Toggles the display of the general AI debug information.

Numpad 2

Toggles the display of the Behavior Tree debug information.

Numpad 3

Toggles the display of the EQS debug information.

Numpad 4

Toggles the display of the AI Perception debug information.

Ctrl + ` (tilde key)

Toggles the display of the HUD class being used (if applicable).

Ctrl + Tab

Toggles the display of any Debug Messages.

The Numpad values above and their associated debug information are for the default debugger. These values can be dynamically incremented from 0-9 on a project basis based on your project needs.

Nav Mesh

When the AI Debugging tools are enabled, pressing Numpad 0 will toggle the display of the possible locations the AI can currently navigate to from its current position using the Nav Mesh Bounds Volume (if one is placed in the Level).



You can also toggle the display of the Nav Mesh during gameplay with the console command show Navigation true (to display the Nav Mesh) or show Navigation false (to hide the Nav Mesh).

AI

With the AI Debugging tools enabled, pressing Numpad 1 will display the general AI debug information:



The AI category within the AI Debugging tools displays general information about the AI such as:

Option

Description

Controller Name

Displays the assigned AI Controller Class.

Pawn Name

Displays the assigned Pawn Class.

Movement Mode (Base)

Displays the current movement mode (and the Mesh it is currently moving on).

Nav Data (Path following)

Displays the Navigation Class (and if the AI is moving).

Behavior (Tree)

Displays if a Behavior Tree is running (and the Behavior Tree Class it is running).

Active task

Displays the currently ticking Task of the assigned Behavior Tree.

Gameplay tasks

Displays the number of queued Tasks. An example of Gameplay Tasks includes the GameplayAbilitySystem tasks.

Montage

Displays the currently active Anim Montage.

In addition to the options above, above the Pawn in the Level, you will see the assigned AI Controller Class and Pawn Class (also displayed in the upper-right corner of the Viewport).

Behavior Tree

When the AI Debugging tools are enabled, pressing Numpad 2 will toggle the display of the Behavior Tree information. -t

Behavior Tree debug information is split into two categories: the Behavior Tree information (left) and the Blackboard information (right). The Behavior Tree information displays the class of Behavior Tree being used and which branch of the tree is currently being executed (along with the nodes within that branch). The Blackboard debug information will display the Blackboard asset being used along with any Blackboard keys and their current values (which can be useful in determining why the AI is or is not performing an action based on the value of a key).

Inside the Behavior Tree asset, you can also add Breakpoints similar to normal Blueprints to pause the execution of the script when reaching a given node. This can help you diagnose what is occurring at any given time within your behaviors.

EQS

You can display information about active Environmental Queries by pressing Numpad 3 when the AI Debugging tools are enabled.



The Visual Logger records EQS data which can also be referred to. Please see the linked page for more details.

The EQS debug information will display the current Environmental Query that is being run along with the Generator used. In the example above, we are using a Simple Grid to determine the best possible location that provides a line of sight to the Player that is nearest the enemy AI character. For this example, we are also presented with the points on our grid (represented by spheres).

The green spheres are locations that pass our Test (has line of sight to the Player) while the blue spheres represent locations that fail our Test (does not have line of sight to the Player). Each sphere is weighted with a numerical value, and our highest weighted value is designated as the "winner" and location that the AI chooses to move to.

You can also press the / (divide) key to display a detailed table breakdown that shows the results of your Tests.



In the example image above, the gray float numbers in the right-most column are the distance in cm and the green ones are the normalized values (from what has been specified in the Test).

In addition to using the AI Debugging tools, EQS provides a way to debug queries while your game is not running by using a special type of Pawn. Please see EQS Testing Pawn for more information.

Perception

At runtime with the AI Debugging tools enabled, pressing 4 on the Numpad key will display Perception System information.



Above, we have an AI character that is set up for Sight (indicated by the green debug lines drawn from the character's head). In the image below, when the AI character sees our Player (which is a source of stimuli for Sight), that location is represented by a green sphere as the Last Known Location.



Any Senses that have been defined on the AI Perception Component under Senses Config will be displayed in the debug window.



Above, we are debugging both Sight (green) and Hearing (yellow) Senses.

You can change the debug color used for Senses on the AI Perception Component using the Debug Color property.

Artificial Intelligence

Pawn

Controllers



AI Perception Component

Pawn Noise Emitter Component

Pawn Sensing Component

AI Components are a type of component that enable Pawns receive sensory like data from the environment, such as where noises are coming from or if the Pawn can see something.

AI Perception Component

The AIPerceptionComponent is used to register as stimuli listener in the AIPerceptionSystem and gathers registered stimuli. UpdatePerception is called when component gets new stimuli (batched).

Pawn Noise Emitter Component

A PawnNoiseEmitterComponent tracks noise event data used by SensingComponents to hear a Pawn. This component is intended to exist on either a Pawn or its Controller. It does nothing on network clients.

Pawn Sensing Component

The Pawn SensingComponent encapsulates sensory (i.e. sight and hearing) settings and functionality for an Actor, allowing the Actor to see/hear Pawns in the world. It does nothing on network clients.

Data Tables

Data Curves

Curve Tables

Data Hookup

Data Usage (C++ Programmers Only)

Data driven gameplay helps mitigate the amount of work and complexity involved, as well as providing the ability to visualize and parameterize data creation and progression, for games that have an extended lifetime well beyond that of a typical boxed game, and require constant tweaking and balancing of data based on player feedback.

The ability to move data out to Microsoft Excel or other spreadsheet documents that can be maintained using proven tools and then imported to automatically take effect in the game. DataTables and CurveTables can be imported into Unreal Engine through Excel documents. These Excel documents are .xlsm (macro enabled Excel documents) that have macro based export buttons to enable easily exporting to the intermediate data format, comma separated variables (.csv).

These documents all reside in a single location to help make data easy to find and modify. You can download a sample .xlsm file by Right-clicking > Save as to download:

Example.xlsm

Data Tables

DataTables, as the name implies, is a table of miscellaneous but related data grouped in a meaningful and useful way, where the data fields can be any valid UObject property, including asset references. Before a designer can import a CSV file into a DataTable, a programmer has to create the row container telling the engine how to interpret the data.

These tables consist of column names that have a 1:1 mapping to a given code based UStruct and its variables, which must inherit from FTableRowBase to be recognized by the importer. The first column is expected to be named Name and contains the names by which each row is accessed for use in game.

Subsequent columns have a variable name for a heading and below, in the same column, the data for that row/column intersection. Given this format, a single row maps 1:1 directly to the structure inherited from FTableRowBase.

Example

As an example, here is a definition for level up experience data and the CSV document that supplies the data to the game:

CSV Document:

The double quotes around the asset type are important for the property importing pipeline. Without them, the text is imported as Texture2d.

Data Table Importing Process

Follow the steps below to Import a CSV file:

Save your file out of Excel or another spreadsheet software with the .csv extension.

Open Unreal Editor, and click on Import in the Content Browser.

Navigate and select the CSV file you want to import as a DataTable. You can choose from the following Import As options:

DataTable

CurveTable

Float Curve

Vector Curve

Linear Color Curve



You can choose the DataTable Row Type from the drop down list.



Additional Import Options are available to use:



Import Option

Description

Ignore Extra fields

Set to true to ignore extra fiels in the import data, if false it will warn about them

Ignore Missing Fields

Set to true to ignore any fields that are expected but missing, if false it will warn about them

Import Key Field

Explicit field in import data to use as key. If this is empty it uses Name for .JSON and the field field found for .CSV

This creates a DataTable object in the current directory of the Content Browser.



You can view the contents of the DataTable in the editor by Double-clicking on the object. You can update the object by Right-clicking on the object and selecting Reimport from the menu. Note that the original file path is used when reimporting the object. Here is the view of the data just after importing:



Data Curves

Data Curves work in a similar manner to DataTables, however they only support floating point types. As with DataTables, the first column is named "Name" and contains the names by which each row is accessed for use in game. Each column heading after the first stores the X-axis variable for a curve to be plotted. The data under this heading is the Y-axis value for the given row. Given this format, a single row corresponds to a curve that code can access and interpolate data along.

Example

Here is an example table for damage progression:

0

1

2

3

Melee_Damage

15

20

25

30

Melee_KnockBack

1

2

4

8

Melee_KnockBackAngle

10

45

60

65

Melee_StunTime

0

1

5

7

Curve Tables

Curve Tables are useful for defining two dimensional numeric data. You can edit Simple Curves and Rich Curves in the Curve Data Table Editor. When creating a Curve Table, you can open the editor to edit curves in the table or curve view without needing to go back to the external program you created them with.

You can create Curve Tables in the Content Browser by navigating to the Miscellaneous section.





Curve Table Importing Process

Follow the steps below to Import a CSV file:

Save your file out of Excel or another spreadsheet software with the .csv extension.

Open Unreal Editor, and click on Import in the Content Browser.

Navigate and select the CSV file you want to import as a Curve Table. You can choose from the following Import As options:

DataTable

CurveTable

Float Curve

Vector Curve

Linear Color Curve



Choose the Curve Table Type from the drop down list. Once selected, you will be prompted to choose your interpolation type between Constant, Linear, or Cubic.





Interpolation Type

Description

Constant

Values in Y Will not be interpolated between datapoints in X. They will clamp to the previous-known value of X.

Linear

Values in Y will be linrearly interpolated between datapoints in X.

Cubic

Values in Y will be cubic interpolated between datapoints in X.

This creates a Curve Table object in the current directory of the Content Browser.





You can double-click your Curve Table to open the Curve Table editor.





To see your Curve Table data in graph form, click the graph button.





The Curve Table View allows multiple curves to be displayed.





You can Rename and Delete curves by right-clicking on a curve.





Data Hookup

Hooking up data from these tables is quite easy. From a programmer's perspective, all you must do is place a Blueprint-exposed variable of either FDataTableRowHandle or FCurveTableRowHandle, depending on if you want a DataTable or CurveTable, respectively. From a content provider's point of view, this will expose a data field with two subfields:

Subfield

Description

DataTable/CurveTable

this is the content reference to the table that holds the data.

RowName

this is the name in the first column of the row you wish to get data from.

Data Usage (C++ Programmers Only)

Once you have the data hooked up, using the data is quite simple. The handle structures provide helper functions FindRow() and GetCurve() that provide you a way to retrieve either a struct or curve filled with data. In the case of a FCurveTableRowHandle, an FRichCurve pointer is returned. The FDataTableRowHandle, however, allows you to specify a structure in the template function call. This structure can be the final structure or any of its parents in the inheritance hierarchy.

One final note is that all structures and curves returned should not be cached further than the local scope of a function. This is to ensure that if the table is refreshed via re-import, the data changes take effect immediately and that no invalid pointers are accessed.

In the above DataTable example, the asset that is referenced is a lazy loaded asset (TSoftObjectPtr handles this). If the Asset field type was set to UTexture, all of the assets would be loaded whenever the DataTable was loaded.



Use Data Registries to store, combine, read, and manage data from various sources.

Data Sources

Data Registry Sources

Meta Data Registry Sources

Identifiers

Data Registry Asset Identifiers

Data Item Identifiers

Quick Function Reference

Integration with Game Features

Choose your implementation method:

Blueprints

C++

A Data Registry is an efficient global storage space for USTRUCT-tagged data structures. Data Registries support synchronous and asynchronous data access, and user-defined caching behaviors. They are intended to work with general read-only data.

Data Registries are part of a plugin. The Data Registries Quickstart can guide you through the process and familiarize you with some of the basic concepts.For specific session-based data such as progress in a story, or a character's current state, use the engine's Save Game system.

You can configure your Data Registry to load or generate data from a variety of different sources, and can populate it with Asset scanning and manual registration. Data Registries are similar to Composite Data Tables, but can store curve data in addition to standard table rows, and use an indirection layer rather than manually compositing multiple tables together.

Data Sources

Data Registries gather data items from two types of sources, Data Registry Sources and Meta Data Registry Sources. These sources are not the actual data items, instead the Data Registry uses them to find or generate data items. The order in which data sources appear within a Data Registry matters, if a specific data item is not found in one source, then the Data Registry will look in the sources that appear after it in the list.

This creates the potential for override and fallback behavior, and enables context-specific sources to override generic ones. The Data Registry plugin includes built-in Data Registry Sources and Meta Data Registry Sources that wrap Data Tables and Curve Tables.

Data Registries gather data items from two types of sources, Data Registry Sources and Meta Data Registry Sources. These sources are not the actual data items, instead the Data Registry uses them to find or generate data items. The order in which data sources appear within a Data Registry matters, if a specific data item is not found in one source, then the Data Registry will look in the sources that appear after it in the list.

This creates the potential for override and fallback behavior, and enables context-specific sources to override generic ones. The Data Registry plugin includes built-in Data Registry Sources and Meta Data Registry Sources that wrap Data Tables (UDataTable) and Curve Tables (UCurveTable).

Data Registry Sources

The Data Registry directly owns a set of Data Registry Source objects that you create and configure in an array within the Data Registry Asset. These objects represent interfaces to specific data sources where the Data Registry can find information, such as an individual data table or a web database. C++ developers can create Data Registry Source child classes to handle other types of data or implement different indirection rules to map identifiers to data items. If your project has one or more Data Registry Source child classes, they will appear in the list when adding new data sources to a Data Registry Asset.

The Data Registry directly owns a set of Data Registry Source objects that you can create and configure in an array within the Data Registry Asset. These objects represent interfaces to specific data sources where the Data Registry can find information, such as an individual data table or a web database. You can create child classes of UDataRegistrySource if you want to handle other types of data, or implement different indirection rules to map identifiers to data items.

Any child class you create will appear in the dropdown list when you add new data sources to a Data Registry Asset.

Meta Data Registry Sources

Meta Data Registry Sources create and own other data sources at runtime. Instead of explicitly list all data sources, Meta Data Registry Sources use generic rules, such as scanning a set of user-named paths, to locate Assets that contain data items. They can listen for manual registration of specific Assets. Meta Data Registry Sources are dynamically generated data sources (including the data items within those sources), because of this they discover load into the Data Registry at runtime.

Similar to Data Registry Sources, C++ developers can create Meta Data Registry child classes to handle other data types, create different scanning rules. If your project contains one or more Meta Data Registry Source child classes, they will appear in the dropdown list when you add new data sources to a Data Registry Asset.

Meta Data Registry Sources create and own other data sources at runtime. Rather than explicitly list all data sources, Meta Data Registry Sources use generic rules, such as scanning a set of user-named paths, to locate Assets that contain data items. They can also listen for manual registration of specific Assets. Because Meta Data Registry Sources are dynamically generated, data sources (and the data items within those sources) that they discover load into the Data Registry at runtime. Similar to Data Registry Sources, you can create your own child classes to handle other data types, create different scanning rules, and so on. To do this, override the UMetaDataRegistrySource class.

Any child classes you create will appear in the dropdown list as options when you add new Data Sources to a Data Registry Asset.

Identifiers

The Data Registry plugin uses its own identifier types to identify or look up Data Registries and the individual data items they contain. While these identifiers are string-based names, the FDataRegistryType (for Data Registry Assets) and FDataRegistryId (for individual items within a Data Registry) structures act as wrappers and provide useful in-editor functionality. FDataRegistryType identifies a Data Registry Asset, while FDataRegistryId identifies a Data Registry and a specific data item within it. You can use these identifier types when you need to find Data Registry Assets or retrieve individual data items from them.

Each Data Registry Asset must have a unique name in the Registry Type field. If two Data Registry Assets have the same name in this field, the system will only recognize and populate one of them. Similarly, if multiple data items share the same identifying value (name or Gameplay Tag), the registry will read all items, but retrieval operations will only access the first one that the Data Registry Asset loaded; see the section on data sources for information about the order in which data items load.

Developers using C++ can change this behavior by creating a child Data Registry class and overriding the ResolveDataRegistryId function.

Data Registry Asset Identifiers

While setting up a Data Registry Asset, developers must set the Registry Type field to a unique name value. This is the identifier for the Data Registry. After setting this value, all Registry Type fields across the editor will immediately add the new Data Registry name to their dropdown list.This prevents user error resulting from spelling mistakes when referencing the Data Registry in other Assets, and makes the selection process quicker and easier.

While setting up a Data Registry Asset, developers must set the Registry Type field to a unique name value. This is the identifier for the Data Registry. After setting this value, FDataRegistryType fields across the editor will immediately add the new Data Registry name to their dropdown list. This prevents user error resulting from spelling mistakes when referencing the Data Registry in other Assets, and makes the selection process quicker and easier.



Above, setting the Data Registry Asset's identifier.

Below, selecting the identifier, or a specific row within that Data Registry, on an Actor that needs to reference the Data Registry Asset.



Data Item Identifiers

Identifying an individual data item, such as a row within a Data Table, requires specifying the Data Registry Asset and the data item itself. The Data Registry ID contains both identifiers. Its Data Registry Type field will appear as a dropdown list, from which you can select any known Data Registry by its identifying name. After selecting a Data Registry's name from that dropdown list, the Data Registry ID field will change to accommodate the Data Registry.

If the Data Registry's ID Format uses a Gameplay Tag, the user interface will display a filtered list containing that Gameplay Tag and all of its children. If the Data Registry's ID Format did not use a Gameplay Tag, the user interface will display a dropdown list of all known rows that the Data Registry Asset contains.

Identifying an individual data item, such as a row within a data table, requires specifying the Data Registry Asset and the data item itself. The FDataRegistryId type contains both identifiers. Its Data Registry Type field will appear as a dropdown list, from which you can select any known Data Registry by its identifying name. After selecting a Data Registry's name from that dropdown list, the Data Registry ID field will change to accommodate the Data Registry.

If the Data Registry's ID Format uses a Gameplay Tag, the user interface will display a filtered list containing that Gameplay Tag and all of its children. If the Data Registry's ID Format did not use a Gameplay Tag, the user interface will display a dropdown list of all known rows that the Data Registry Asset contains.

If you edit a Data Registry Asset, your changes may not take effect immediately in other Assets that reference it using data item identifiers. If this happens, the data item identifiers could contain obsolete rows in its dropdown lists. Click the Compile button in the Asset that references the Data Registry (not the Data Registry Asset itself) to update the interface with current data item information.



On the left, item selection for a Data Registry Asset with an ID Format that uses a Gameplay Tag.

On the right, item selection for a Data Registry Asset that uses a simple name.

Because FDataRegistryId has an FDataRegistryType member (called RegistryType), you can find the Data Registry Asset that contains the row without needing a separate FDataRegistryType identifier.

The system looks up data items by searching for the Item Name of the Data Registry ID you supply. You can alter this behavior by creating a child Data Registry class in C++. Toggle to the C++ version of this page for more details.

Dynamic Identifier Resolution

By default, the system looks up data items by searching for the value of the ItemName field of the FDataRegistryId you supply. If this is not the ideal behavior for your project, you can create your own UDataRegistry subclass and override the MapIdToResolvedName function to include additional FDataRegistryResolverScope structs in the local scope. By overriding the ResolveIdToName function within your FDataRegistryResolverScope subclasses, you can remap the incoming row names, even using dynamic or player-specific information. After resolving an ID, the system produces an FDataRegistryLookup which is guaranteed to be unique (within the system) and is used as the caching unique ID.

Quick Function Reference

The following functions are helpful for getting started with Data Registries. This is not a complete reference, but these functions are the basics you will need to access your data after having set up Data Registries in your project.

Acquire Data Registry Item searches for a given item and loads it into the cache on success. This function is very important for data items coming from MetaDataRegistrySources, as the other Data Registry functions can only access cached data items. Call this function if you want to access a data item that you believe exists (or might exist) but is not currently in the cache.

When you call this function, it will resume execution immediately through the pin on the right side. The return value indicates whether or not the loading operation has started, not the result of that operation; failure means that the operation could not begin, and the callback function you have connected will not be called. Once the callback function runs, the search and load operations have finished, and you can use the other functions described in this section to attempt to retrieve your data from the cache, presuming it loaded successfully. If your data is not in the cache immediately at that point, it was not found.

If you successfully retrieve a data item once, but fail to retrieve it later on, it may have been removed from the cache. Call Acquire Data Registry Item again and retrieve it immediately upon entering the callback function. You may also consider making your own copy of the data, or adjusting the data item's cache behavior, based on the specific needs of your project.



Find Data Registry Item checks for an item in the Data Registry's cache, and branches based on whether or not the item was found. If it was found, you can access it through the right-side Out Item pin. This function returns immediately, so data items that exist but are not in the cache will not be found.



Get Data Registry Item is similar to Find Data Registry Item, but returns a success/failure value instead of branching, and automatically populates the variable connected to the left-side Out Item pin on success. This function returns immediately, so data items that exist but are not in the cache will not be found.



Evaluate Data Registry Curve looks for a cached curve. Like Find Data Registry Item, it is synchronous, so it will return immediately, but will fail to find a curve if that curve is not in the cache at the time of the function call. This function branches execution based on whether it succeeds or fails, and returns the default value that you provide on failure. You can use this feature in cases where you need an output value regardless of whether or not the curve data is available.



Function

Description

UDataRegistrySubsystem::Get

Returns a pointer to the UDataRegistrySubsystem instance. The only static function in the list, this function acts as the entry point to the subsystem.

UDataRegistrySubsystem::GetRegistryForType

Takes a name or FDataRegistryType (either standalone or from FDataRegistryId::RegistryType) and returns a UDataRegistry pointer to the matching Data Registry, if it exists.

UDataRegistrySubsystem::RegisterSpecificAsset

Searches for a Data Registry by FDataRegistryType, and adds a specific Asset to it. If you do not provide a valid FDataRegistryType, the subsystem will attempt to add the Asset to all Data Registries in the subsystem. Returns true if at least one Data Registry accepted the Asset.

UDataRegistry::GetCachedItem

Searches the Data Registry for the data item that corresponds to the FDataRegistryId you provide. If the item is not in the cache at the time of the function call, the function will return null. Otherwise, the function returns a const pointer to whichever struct type the Data Registry stores.

UDataRegistry::GetAllCachedItems

Populates a map with a pointer to the engine's UScriptStruct data (as a const uint8*) for each cached item in the Data Registry, using the item's FDataRegistryId as the key. Also provides the UScriptStruct itself through a separate output parameter. This is often useful for iterating over the cache as a debugging tool, such as using the UScriptStruct::ExportText function to log the contents of each cached item.

UDataRegistry::EvaluateCachedCurve

Finds the curve that corresponds to the FDataRegistryId you provide, and evaluates it for a given input value. This function will fail if the requested curve is not in the cache at the time of the call. The function's return value is of type FDataRegistryCacheGetResult, which provides information about the cached status of the curve you requested, and most importantly whether or not the curve was found. The curve's output value, of type float, comes through an output parameter.

UDataRegistry::AcquireItem

Similar to GetCachedItem, but finds the data item even if it is not cached at the time of the call. This function is asynchronous; it will run your callback function, of type FDataRegistryItemAcquiredCallback, when the search is complete. The function's return value is a bool that indicates success at scheduling the callback; a false return value means that there has been an error and your callback function will not run. A return value of true means that your callback function will run, but does not guarantee that the data item exists.

Caching struct pointers that you retrieve from a Data Registry can be unsafe. While some data items are always available, others load dynamically and the Data Registry can unload them without warning. If you are potentially dealing with data that can be unloaded, the recommended practice is to use the data immediately after retrieving it, or cache your own copy rather than keeping the pointer from the Data Registry.

Integration with Game Features

The Data Registry plugin can add both Data Registries and individual Data Registry Sources from Game Feature plugins. For details on how this process works, see the Game Features and Modular Gameplay page.

To begin using Data Registries, you will need to enable the Data Registry plugin, then you can create, configure, and populate your first Data Registry.

Enable the Data Registry plugin by navigating to Edit > Plugins. When the Plugins window appears, search or browse through the plugins to find the Data Registry plugin located in the Gameplay category. Once you have found the plugin, ensure that the Enabled checkbox is checked.

If the Plugins window indicates that you need to restart the editor for the plugin to take effect, do so before proceeding further.



Navigate the Project Settings window by choosing Edit > Project Settings



Under the Game section in the left panel, you will see a category labeled Data Registry.

If you do not see this category, ensure that you have enabled the Data Registry plugin, and have restarted the editor at least once since enabling it.



In the right-side panel, add at least one entry to the Directories to Scan array. This tells the system where to look to find Data Registry Assets. A typical entry might be /Game/DataRegistries, but you can add as many directories as you like, depending on the organizational scheme you prefer for your project. This is a good time to make sure that all of the directories you specified exist, and verify that any Data Registry Assets you have created are in the correct places.



Navigate to one of the directories you specified in Directories to Scan in the Content Browser and add a new Data Registry Asset. You can do this by right-clicking an empty space in the right-side panel and expanding Miscellaneous in the context menu. In the expanded context menu, select DataRegistry and then pick the appropriate subclass from the list that appears.



Name and open your new Data Registry Asset.

Enter a globally unique name in the Registry Type field. If you want to use [Gameplay Tags]() to identify Assets that should be part of this Data Registry, make sure to set it in the Base Gameplay Tag field under the ID Format category.



Set the Item Struct field to the type of struct that this Data Registry will contain. This is usually a DataTableRowHandle or a SimpleCurve, but can be any of a wide variety of data types.



Add one or more data sources to the Data Sources array. For each entry, you must choose what type of data you are adding, and specify where the data comes from. You can use the built-in data types, or add types that your project or any enabled plugin defines. At this point, you will need to have some data for the Data Registry to manage.

For simple source types like DataTable Source or CurveTable Source, which gather row data from known, pre-existing Assets, select the source Asset to read. The Table Rules section describes the caching behavior for data rows coming from the Asset you specified, so check that they are appropriate for your use case.

For meta source types like DataTable Meta Source or CurveTable Meta Source, which generate new data sources at runtime, there are a few more settings to handle. Select the source type to generate, any access or reference rules for the generated sources, and the scan or usage rules that determine how the system will find Assets. Meta sources can scan for Assets, accept registered Assets (from C++ code), or both.

As an example, you could specify the search path as /Game/SearchableDataTables, but exclude *PrivateData*; this exclusion would remove any path that contains the substring "PrivateData", so paths like /Game/SearchableDataTables/PrivateData/ and /Game/SearchableDataTables/SubPath/SomePrivateDataHere/ would not be scanned.

Once you have set up your data sources, configure the Cache Rules to meet the specific needs of your project. To find the settings that you can configure, expand the Cache section in the Data Registry editor.

Because the Data Registry feature is still in development, some of the settings might not work as expected.

This is a good time to ensure that the Data Registry contains the items that you expect. Click the Refresh button on the toolbar and review the contents of the Registry Preview tab, which shows a preview of every item currently known to the Data Registry. If the results do not match your expectation, modify the data source rules and click the Refresh button again.



Rows can appear multiple times in the list if multiple sources pull them in; this is not an error, and generally indicates that a meta source has found the same data as a simple source or another meta source. The order matters when you attempt to retrieve a data item that appears in multiple sources. Only the first instance that the Data Registry discovered will be accessible.

You can Browse the Runtime Sources category, below Data Sources in the left panel, to see the source of each instance of each item in the Data Registry, listed in load order.

Once everything looks correct, save your Data Registry. In future sessions, it will load and populate itself automatically during startup. If you make changes to your Data Registry, press the Refresh button to update the data items.

If you plan to use Data Registries from C++ code, open your project's Build.cs file. The actual file name will include the name of your project; for example, if your project's name is "MyProject", the file name will be MyProject.Build.cs. Find the line that sets up the PublicDependencyModuleNames variable, and add "DataRegistry" to the array. The final line should look something like this:

After completing these steps, your project will be set up to use Data Registries! For information on how Data Registries work and what benefits they offer, refer to the main Data Registries page.

Topics

The PlayerInput Object is responsible for converting input from the player into data that Actors (like PlayerControllers or Pawns) can understand and use. It is part of an input processing flow that translates hardware input from players into game events and movement with Player Input mappings and Input Components.

You can get started with the Input Overview or choose any of the topics below.

Topics



An overview of the Enhanced Input Plugin.



An overview of the Raw Input Plugin



How to set up user input



The Input object is responsible for converting input from the player into data in a form Actors can understand and make use of.



Using the vibration functionality of mobile devices and controllers to convey a force occuring in the game to the player.

Dynamic and Contextual input mappings

Creating Enhanced Input Assets

Core Concepts

Input Actions

Trigger States

Adding Input Listeners

Input Mapping Contexts

Input Modifiers

Directional Input

Input Triggers

Player Mappable Input Config (PMI)

Debug Commands

Injecting Input

Platform Settings

For Unreal Engine 5 (UE5) projects that require more advanced input features, like complex input handling or runtime control remapping, Enhanced Input provides developers with an upgrade path and backward compatibility from the default input system from Unreal Engine 4 (UE4).

This implements features like radial dead zones, chorded actions, contextual input, and prioritization, as well as the ability to extend your own filtering and processing of raw input data in an Asset-based environment.

Dynamic and Contextual input mappings

When you use Enhanced Input you can add and remove Mapping Contexts at runtime for the player. This makes it easier to manage a large number of Actions. You can change how certain inputs behave depending on the current state of the player.

For example, if you have a player character that can walk, sprint, and be prone. For each of those Character Movement types, you can swap the Mapping Context to have the CTRL key do different actions. While walking and you press the CTRL key, you should crouch. While sprinting and you press CTRL, then you should slide. While prone and you press CTRL you should stand back up.

Creating Enhanced Input Assets

Enhanced Input is enabled by default. You can create input assets from the Content Browser, by clicking Add(+) and navigating to the Input category.



Core Concepts

The Enhanced Input system has four main concepts, Input Actions, Input Mapping Contexts, Input Modifiers, and Input Triggers.

Input Actions

Input Actions are the communication link between the Enhanced Input system and your project's code. Input Actions are the conceptual equivalent to Action and Axis mapping names, except they are data assets. Each Input Action should represent something that the user can do, like "Crouch" or "Fire Weapon". You can add Input Listeners in either Blueprints or C++ when the Input Action's state changes.

Input Actions can be several different types that will determine their behavior. You can make a simple boolean action or a more complex 3D axis. The type of action determines the value. Boolean actions have a simple bool value, an Axis1D is a float value, an Axis2D is an FVector2D, and Axis3D is a whole FVector.



Input Actions can be different value types that will determine their behavior.

You should use bool actions for inputs that have an on or off state. This is the equivalent of the older Action mappings in the legacy input system. For controls like gamepad thumbstick values, you can use 2D axis actions to hold the X and Y value of the thumbstick position. You can use the 3D axis to hold more complex data, such as motion controller information.

As an example, a "pick up item" Action might only need an on / off state, indicating whether or not the user wants the character to pick something up, while a "walk" Action might require a 2D axis to describe the direction and speed at which the user wants the character to walk.



The different Input Actions used in the Lyra Game Sample.



A Trigger State represents the current state of an action, such as Started, Ongoing, Triggered, Completed, and Canceled. Often, you will use the "Triggered" state. You can bind to specific states in both C++ and Blueprint.

Triggered: The action was triggered. This means that it has completed the evaluation of all trigger requirements. For example, a "Press and Release" trigger is sent when the user releases the key.

Started: An event occurred that began trigger evaluation. For example, the first press of a "Double tap" trigger will call the "Started" state once.

Ongoing: The trigger is still being processed. For example, a "Press and hold" action is ongoing while the user is holding down the button before the specified duration is reached. Depending on the triggers, this event will fire every tick while the action is evaluated once it receives an input value.

Completed: The trigger evaluation process is completed.

Canceled: The triggering was canceled. For example, a user lets go of a button before a "Press and Hold" action can be triggered.

To add an Input action listener in Blueprints, you can right-click in the Blueprint's event graph and type in the name of your input action data asset.





Adding an Input Action Event and setting it to execute a Print String.

You can also bind input actions in C++

Input Mapping Contexts

Input Mapping Contexts are a collection of Input Actions that represents a certain context that the player can be in. They describe the rules for what triggers a given Input Action. Mapping Contexts can be dynamically added, removed, or prioritized for each user.

To create an Input Mapping Context, right-click the Context Browser, expand the Input option, and choose Input Mapping Context.



The basic structure of an Input Mapping Context is a hierarchy with a list of Input Actions at the top level. Under the Input Action level is a list of user inputs that can trigger each Input Action, such as keys, buttons, and movement axes.

The bottom level contains a list of Input Triggers and Input Modifiers for each user input, which you can use to determine how an input's raw value is filtered or processed, and what restrictions it must meet in order to drive the Input Action at the top of its hierarchy.



You can apply one or more of these Contexts to a local player through its Enhanced Input Local Player Subsystem, and prioritize them to resolve collisions between multiple Actions trying to consume the same input.

This is where you implement your actual Key to Input Action bindings and specify additional triggers or modifiers for each action. When you add an Input Mapping Context to the Enhanced Input subsystem, you can also give it priority. If you have multiple contexts mapped to the same Input Action, then, when the Input Action is triggered, the context with the highest priority will be considered and the others ignored.

As an example, you can give a character who can swim, walk, and drive vehicles multiple Input Mapping Contexts. One for common actions that are available and always mapped to the same user inputs, and another one for each individual mode of travel.

Developers can then place the vehicle-related Input Actions into a separate Input Mapping Context, which is added to the local player when entering a vehicle, and removed from the local player when exiting the vehicle.

Doing this helps to optimize and prevent bugs by ensuring that inappropriate Input Actions cannot run. Additionally, using mutually-exclusive Input Mapping Contexts will help avoid input collisions, which means when user input is used for different Input Actions the input will never accidentally trigger the wrong action.

You can add mapping contexts to the player in either Blueprints or C++



Input Modifiers

Input Modifiers are pre-processors that alter the raw input values that UE receives before sending them on to Input Triggers. The Enhanced Input Plugin has a variety of Input Modifiers to perform tasks like changing the order of axes, implementing "dead zones", and converting axial input to world space.

Input Modifiers are useful for applying sensitivity settings, smoothing input over multiple frames, or changing how input behaves based on the state of the player. Because you have access to the UPlayerInput class when making your own modifier, you can access the owning Player Controller and get any game state you want.



You can make your own Input Modifiers in C++ or Blueprints by creating a subclass of the UInputModifier class and overriding the ModifyRaw_Implementation function.

You can also create your own Input Modifier by creating a new Blueprint Child Class using Input Modifier as the parent.



Next, navigate to My Blueprint > Functions > Override and from the dropdown menu select the Modify Raw function.



The output parameter is an Input Action Value, which contains three float values, much like a Vector. The function's input parameters contain the Player Input object, the Current Value from the input hardware or the previous Input Modifier, and a Delta Time value.



The Input Action Value you return from Modify Raw will go to the next Input Modifier, if there is one, or to the first Input Trigger.



Below is an example of an Input Modifier used in the Lyra Game Sample.

A good example of Input Modifier usage is two-dimensional directional input using a single Input Action. With a mouse or a gamepad's analog stick, reading two-dimensional movement is a simple matter of creating an Input Action that supports at least two axes and adding the appropriate input to the Input Mapping Context.

Enhanced Input supports input from one-dimensional sources, such as a keyboard's directional arrows or the popular "WASD" key configuration; you can achieve this control scheme by applying the correct Input Modifiers. Specifically, by using Negate to make some keys register as negative, and using Swizzle Input Axis Values to make some keys register as Y-Axis instead of the default X-Axis:

Letter Key

Arrow Key

Desired Input Interpretation

Required Input Modifiers

W

Up

Positive Y-Axis

Swizzle Input Axis Values (YXZ or ZXY)

A

Left

Negative X-Axis

Negate

S

Down

Negative Y-Axis

Negate Swizzle Input Axis Values (YXZ or ZXY)

D

Right

Positive X-Axis

(none)



This interpretation of the directional arrows or "WASD" keys enables one-dimensional inputs to map to a two-dimensional Input Action.

Since each key reports a positive, one-dimensional value, this value will always occupy the X-axis and will have a value of either 0.0 or 1.0 on any given tick. By negating the value for left and down inputs, and switching the axis order so that the input's X-axis value moves to the Y-axis for up and down inputs, you can use Input Modifiers to interpret a set of one-dimensional inputs as a single two-dimensional input value.

Input Triggers

Input Triggers determine whether user input, after passing through an optional list of Input Modifiers, should activate the corresponding Input Action within its Input Mapping Context. Most Input Triggers analyze the input itself, checking for minimum actuation values and validating patterns like short taps, prolonged holds, or the typical "press" or "release" events. The one exception to this rule is the "Chorded Action" Input Trigger, which is only triggered with another Input Action. By default, any user activity on an input will trigger on every tick.

There are three types of Input Triggers:

Explicit types cause the input to succeed if the Input Trigger succeeds.

Implicit types cause the input to succeed only if the Input Trigger and all other Implicit type Input Triggers succeed.

Blocker types cause the input to fail if the Input Trigger succeeds.

Below is a logical example of how each trigger type interacts in a situation against other trigger types:

After processing user input, Input Triggers can return one of three states:

None indicates that the Input Trigger's conditions have not been met, so the Input Trigger fails.

Ongoing indicates that the Input Trigger's conditions are partially met, and the Input Trigger is processing but is not yet succeeding.

Triggered indicates that all of the Input Trigger's conditions have been met, and the Input Trigger succeeds.

You can create your own Input Trigger by extending the base Input Trigger class, or Input Trigger Timed Base.



Input Trigger Timed Base checks that an input has been held down for a certain length of time before accepting it and returning to the Ongoing state.

The provided Input Trigger Timed Base class does not ever return the Triggered state. Override the functions within your new Input Trigger child class to determine how it responds to user input. The function Get Trigger Type determines the Input Trigger's type. Update State takes the player's input object, current Input Action Value, Delta Time, and returns the None, Ongoing, or Triggered state.

As a C++ example, you can navigate to InputTriggers.h and observe the UInputTriggerHold implementation.

UInputTriggerHold.H

UInputTriggerHold.cpp

Player Mappable Input Config (PMI)

Mappable configs are a collection of Input Mapping Contexts that represent one "Config" or "Preset" of mappings. For example, you can have a "Default" and a "Southpaw" mappable config that holds different input mapping contexts for aiming.

You can use these configs to predefine a set of contexts and their priorities to add them all at once instead of having to manually add an array of input mapping contexts. Mappings provide various selections of metadata options that can make programming UI settings screens easier.

Debug Commands

There are several input related debug commands available to help you debug any input-related behavior you may be working on.

Using the command showdebug enhancedinput displays the available input action and axis mappings used by your project.



Using the command: showdebug devices



Injecting Input

Enhanced Input also brings along the concept of "Injecting Input" to your player. This provides the means for you to call a function in Blueprints, C++, or use a console command to simulate input on your player. You can use the Input.+key console command to start simulating input.

Below is an example of setting the Gamepad_Left2D key:

The key name is whatever the actual FKey name is, which you can find in the InputCoreTypes.cpp file, or in the key picker widget if you remove the spaces in the displayed key name.





injecting input in Blueprints



Platform Settings

You may want different input settings for different platforms, such as rotating the face buttons on the Nintendo Switch or altering the actions available on mobile devices. Enhanced Input provides a per-platform Mapping Context Redirect that allows you to do this easily.

You can make a Blueprint based on the Enhanced Input Platform Data class. This is a base class you can build upon for adding any platform-specific options to your game. By default, it contains a map of Input Mapping Contexts, allowing you to redirect one context to another.

Any time the mapping context is referenced on a specific platform, it will be replaced by the value in the map when the mappings are rebuilt.



To apply this redirect, add it to your Project Settings > Enhanced Input > Platform Settings > Input Data



These project settings add to the platforms DefaultInput.ini, so they are hot fixable and easily changed. Because the platform settings provide the base class of UEnhancedInputPlatformData, you can make custom platform settings by creating your own Blueprint or C++ subclass, which then provides access to the settings from anywhere.

Enabling RawInput

Configuring Devices

Example (Vehicle Templates)

Configuring the Device in RawInput

Mapping our RawInput Axes to Input Bindings

The RawInput plugin provides support for specific, user-defined devices that aren't properly handled by Microsoft's XInput API (Application Programming Interface), usually flight sticks and steering wheels. The buttons and axes of these input devices can be custom-mapped to gameplay inputs, including new inputs created by the plugin itself.

Enabling RawInput

By default, the plugin is not enabled. It can be enabled from the Plugins menu, in the Input Devices section.



After the plugin is enabled, the Raw Input section will appear in the Project Settings menu.



Configuring Devices

Within this section, you can add new devices. Each device is identified by a vendor ID and a product ID, which are hexadecimal values that can be found in the device's driver properties. An array of axes (by default, eight) and buttons (by default, twelve) will be added to the controller's configuration. This provides the ability to map any of the controller's axes or buttons (indicated by the array index) to any Unreal Engine axis or key. The plugin provides eight new axes ("Generic USB Controller Axis 1" through "Generic USB Controller Axis 8") and twenty new buttons ("Generic USB Controller Button 1" through "Generic USB Controller Button 20"). Each axis and button can be enabled or disabled, and axes can also be inverted and offset.



Above, you can see the Hardware ID information in Windows Control Panel (under Device Manager) for the Logitech G920. The Vendor ID is the four-character string following "VID_" test (046D), and the Product ID is the four-character string following "PID_" (C262). This information will be required when configuring the device in RawInput.

Example (Vehicle Templates)

As an example, the Vehicle templates that ship with the Unreal Engine have been configured to work with the Logitech G920, a driving-game controller with a steering wheel and gas/brake pedals.

Configuring the Device in RawInput

The steering wheel is reported by the driver as Axis 1, the brake is reported as Axis 3, and the gas pedal is reported as Axis 4. In the RawInput plugin settings, each input must be entered into the array at the corresponding axis from the device driver. That is, the steering wheel's data must be in array element 1, the brake's data must be in array element 3, and the gas pedal's data must be in array element 4. All other entries may be removed or marked as disabled.



Note that the array index of an input does not need to correspond to the "Generic USB Controller Axis" or "Generic USB Controller Input" value. For example, the brake is bound to "Generic USB Controller Axis 2" even though it is in array position 3. This is necessary to ensure that different controllers can be configured to work the same way, even if they use different input axes.





Because the device's output range doesn't match what we might expect from a standard controller, we will remap the input ranges. The wheel returns values from 0.0 (left) to 1.0 (right), but we want the input range to center on 0.0, so we will give it an offset of -0.5. The brake and gas pedals also return values from 0.0 to 1.0, but the device uses 0.0 to indicate that the pedal is pressed down, and 1.0 to indicate that the pedal is up, where our project expects the reverse. To make this adjustment, we set the axis values to be inverted, and then add a 1.0 offset.

Mapping our RawInput Axes to Input Bindings



We can then map the new axes to our game's input bindings. The wheel (on "Generic USB Controller Axis 1") is mapped to the range [-0.5, 0.5], but we want it to be more sensitive, so we can scale it up by a factor of 3.0. Similarly, the brake (on "Generic USB Controller Axis 2") needs to go in the negative direction, and should be more powerful than the gas pedal, so it will be scaled by -2.0. The gas pedal (on "Generic USB Controller Axis 3") requires no modification, and only needs to be added to the appropriate input binding. By using RawInput and adding these input bindings, we are able to support the Logitech G920 without needing any new input bindings or making any changes to our project's code or Blueprints.



This use of scaling provides a good argument for using the "Generic USB Controller" axes instead of configuring the device to the standard gamepad stick inputs.



Project Setup

Action and Axis Mapping Setup

Creating the Example Character

Creating the SpringArm and Camera Components

Creating the GameMode Blueprint

Result

Choose your implementation method:

Blueprints

C++

In this tutorial, you will create a Character and set it up to receive input, then assign the character to a GameMode so that it is the default pawn during gameplay. After you create your Character, you will define how it reacts to Player Input.

Unreal provides for more complex Input mappings for a variety of project types. Refer to Enhanced Input for additional documentation.

Project Setup

Create a new Games > Blank > Blueprint project named "SettingUpInput".

From the Editor, navigate to Edit > Project Settings > Input > Bindings.



Create a new Games > Blank > C++ project named "SettingUpInput".

In the Editor, navigate to Edit > Project Settings > Input > Bindings.



Action and Axis Mapping Setup

Defining Input is done through user-defined Bindings of Action and Axis Mappings. Both mappings provide a mechanism to conveniently map keys and axes to input behaviors by inserting a layer of indirection between the input behavior and the keys that invoke it.

Action Mappings are for key presses and releases, while Axis Mappings allow for inputs that have a continuous range. Once you have defined your Mappings, you can then bind them to behaviors in Blueprints or C++.

Click Add(+) next to Action Mappings to create a new Action named Jump.



From either the drop down arrow(1) or the Select Key Value button(2), search for and select the Space Bar key value.



Navigate to the Axis mappings and click Add(+) to create the following Axis Mapping names, Key values,and Scale values:

Axis Mapping Name

Key Value

Scale Value

MoveForward

W

1.0

S

-1.0

MoveRight

A

-1.0

D

1.0

Turn

Mouse X

1.0

LookUp

Mouse Y

-1.0



Creating the Example Character

Creating the Example Character

A Character is a special type of Pawn that has the ability to walk around. Characters extend from the Pawn class, and inherit similar properties such as physical representation of a player or AI entity within the world.

Refer to the Pawn and Input pages for additional documentation.

From the Content Drawer, Click Add(+), then from the Pick Parent Class menu choose Character as your parent class.



Name your Blueprint BP_ExampleCharacter, and double-click it to open its class defaults.

A Character is a special type of Pawn that has the ability to walk around. Characters extend from the Pawn class, and inherit similar properties such as physical representation of a player or AI entity within the world.

Refer to the Pawn and Input pages for additional documentation.

From the Content Drawer, navigate to the C++ classes folder, right-click and select New C++ Class, then choose Character as your parent class.



Name your character class "ExampleCharacter", then click Create Class.

Creating the SpringArm and Camera Components

When the Camera and SpringArm Components are used together, they provide functionality for a third-person perspective that can dynamically adjust to your game world. The camera component contains a camera that represents the player's point of view or how the player sees the world. The SpringArm component is used as a "camera boom" to keep the camera for a player from colliding into the world.

In the Components tab, click Add(+), then from the drop down search for and select Spring Arm. Rename your Spring Arm component CameraBoom.



Repeat step 1, but search for and select the Camera. Rename your Camera component FollowCamera.



From the Components tab, drag your FollowCamera onto the CameraBoom to attach it.



Select the CameraBoom in the Components tab, then navigate to the Details > Camera Settings and click the checkbox to enable the Use Pawn Control Rotation variable. When enabled, the Camera parent uses the view / control rotation of the pawn (ExampleCharacter).



For additional Spring arm and Camera settings that you could use for your Character's perspective. Refer to the Using Cameras documentation

Compile and Save.



When the Camera and SpringArm Components are used together, they provide functionality for a third-person perspective that can dynamically adjust to your game world. The camera component contains a camera that represents the player's point of view or how the player sees the world. The SpringArm component is used as a "camera boom" to keep the camera for a player from colliding into the world.

In your code editor, navigate to ExampleCharacter.h. In the Class defaults, declare the following classes.

UProperty Specifiers are used to provide visibility of the component in the Blueprint Editor

Navigate to your ExampleCharacter.cpp file. Add the following libraries to the include line.

Next, implement the following in the AExampleCharacter constructor.

The component calls the FObjectInitializer::CreateDefaultSubobjecttemplate, then uses the SetupAttachment method to attach to a parent Scene Component. When setting the Camera Boom to use the Pawn's control rotation, it uses its parent pawn's rotation instead of its own.

Compile your code.

In the Components panel, select the Mesh Skeletal Mesh Component.



Navigate to Details > Mesh > Skeletal Mesh and expand the drop-down menu. Select Browse Asset Options > Content > Show Engine Content.



Search for and select the TutorialTPP Skeletal Mesh.



Navigate to the Transform category, then set the Location and Rotation vector values to (0.0, 0.0, -90)



Compile and Save.



Creating the Action/Axis Functions to your Input Component

In your ExampleCharacter.h class defaults, declare the following Input functions.

Navigate to your ExampleCharacter.cpp and implement your MoveForward and MoveRight methods.

Navigate to the SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) method, then implement the following code.

Compile your code.

Navigate to My Blueprint > Functions, click Add(+) to add two new functions. MoveForward and MoveRight.



Select the MoveForward function, navigate to the Details > Inputs, then click Add(+) to add a new float value input named AxisValue.



Copy or Implement the logic below for the MoveForward function.



Begin Object Class=/Script/BlueprintGraph.K2Node_FunctionEntry Name="K2Node_FunctionEntry_0" ExtraFlags=201457664 FunctionReference=(MemberName="MoveForward") bIsEditable=True NodePosX=-32 NodePosY=16 NodeGuid=A0FF87524A53EDAA6CBEC48FEE0D9464 CustomProperties Pin (PinId=B427E05D444F66A59DA68E9A5D09AB7B,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_7346 B27FCDDF43B9261BD870CE965B82DF38,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F01767A145595ED17A3E438A7F7BEFA2,PinName="AxisValue",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_7346 D95413A34BE985375A5C2F905CD8109F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="AxisValue",PinType=(PinCategory="real",PinSubCategory="double"),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_7346" FunctionReference=(MemberName="AddMovementInput",bSelfContext=True) NodePosX=384 ErrorType=1 NodeGuid=CE1F697649E08F668E46BFA6FF6FE134 CustomProperties Pin (PinId=B27FC

Select the MoveRight function, and add a new float value as instructed in step 2.



Copy or Implement the logic below for the MoveRight function.



Begin Object Class=/Script/BlueprintGraph.K2Node_FunctionEntry Name="K2Node_FunctionEntry_0" ExtraFlags=201457664 FunctionReference=(MemberName="MoveRight") bIsEditable=True NodePosX=64 NodePosY=-48 NodeGuid=5846746C4FEEF77A895638939B0C845C CustomProperties Pin (PinId=09949021438E59AA6E23A8B112C93B0D,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_7346 B27FCDDF43B9261BD870CE965B82DF38,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0FE0FC0344DE295574151E8BA52B9628,PinName="AxisValue",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_7346 D95413A34BE985375A5C2F905CD8109F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="AxisValue",PinType=(PinCategory="real",PinSubCategory="double"),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_7346" FunctionReference=(MemberName="AddMovementInput",bSelfContext=True) NodePosX=432 NodePosY=-64 ErrorType=1 NodeGuid=0A9F72574C55739F8ABF479B3DA34A3C CustomProperties Pin (

Navigate to the Event Graph. You need to set up your Axis and Action input events to call their respective functions. Copy or implement the logic below.



Finished Code

Creating the Character Blueprint

Navigate to your C++ Classes Folder and right click your ExampleCharacter, from the drop down menu select Create Blueprint class based on ExampleCharacter. Name your Blueprint BP_ExampleCharacter.



In the Components panel, select the Mesh Skeletal Mesh Component.



Navigate to Details > Mesh > Skeletal Mesh and expand the drop-down menu. In the Browser section, click the Settings Icon. Then from the context menu, select Content > Show Engine Content.



Search for and select the TutorialTPP Skeletal Mesh.



Navigate to the Transform category, then set the Location and Rotation vector values to (0.0, 0.0, -90)

Finished Blueprint







Creating the GameMode Blueprint

The GameMode defines the game's set of rules. These rules include what default pawn the player will spawn as when the game is launched. You need to set up these rules to spawn the Player Character you created.

In the Content Drawer, click Add(+) to create a new Blueprint Class, then from the drop down menu choose Game Mode Base as your Parent Class. Name your game mode "BP_InputGameMode".



In the Class defaults, navigate to Classes > Default Pawn Class, and select BP_ExampleCharacter.



Compile and Save.



Navigate to Edit > Project Settings > Maps and Modes. Set the Default GameMode to BP_InputGameMode.



Navigate to the Editor and select Play (Play in Editor)



You can now control your character's movement using the W, A, S, D keys. Moving the mouse moves the camera, and pressing the spacebar causes the character to jump.

The GameMode defines the game's set of rules. These rules include what default pawn the player will spawn when the game is launched. You need to set up these rules to spawn the Player Character you created.

In the Content Drawer, navigate to your C++ Classes folder, right-click the SettingUpInputGameModeBase, then in the drop-down menu select Create Blueprint Based on SettingUpInputGameModeBase. Name your game mode Blueprint "BP_InputGameMode".



In the Class defaults, navigate to Classes > Default Pawn Class, and select the BP_ExampleCharacter.



Compile and Save.



Navigate to Edit > Project Settings > Maps and Modes. Set the Default GameMode to BP_InputGameMode.



Navigate to the Editor and select Play (Play in Editor)



You can now control your character's movement using the W, A, S, D keys. Moving the mouse moves the camera, and pressing the spacebar causes the character to jump.

Result



Hardware Input

PlayerInput

Setting Input Mappings

InputComponent

Input Processing Procedure

Example - Moving Forward

Touch Interface

Enhanced Input Plugin

Getting Started

Core Concepts

Input Actions

Input Mapping Contexts

Input Modifiers

Input Triggers

The PlayerInput Object is responsible for converting input from the player into data that Actors (like PlayerControllers or Pawns) can understand and make use of. It is part of an input processing flow that translates hardware input from players into game events and movement with PlayerInput mappings and InputComponents.

For an example of setting up Input, refer to the Setup Input documentation.

Hardware Input

Hardware input from a player is straightforward. It commonly includes key presses, mouse clicks or mouse movement, and controller button presses or joystick movement. Specialized input devices that don't conform to standard axis or button indices, or that have unusual input ranges, can be configured manually by using the Raw Input Plugin.

PlayerInput

PlayerInput is a UObject within the PlayerController class that manages player input. It is only spawned on the client. Two structs are defined within PlayerInput. The first, FInputActionKeyMapping, defines an ActionMapping. The other, FInputAxisKeyMapping, defines an AxisMapping. The hardware input definitions used in both ActionMappings and AxisMappings are established in InputCoreTypes.

Map a discrete button or key press to a "friendly name" that will later be bound to event-driven behavior. The end effect is that pressing (and/or releasing) a key, mouse button, or keypad button directly triggers some game behavior.

Map keyboard, controller, or mouse inputs to a "friendly name" that will later be bound to continuous game behavior, such as movement. The inputs mapped in AxisMappings are continuously polled, even if they are just reporting that their input value is currently zero. This allows for smooth transitions in movement or other game behavior, rather than the discrete game events triggered by inputs in ActionMappings.

Hardware axes, such as controller joysticks, provide degrees of input, rather than discrete 1 (pressed) or 0 (not pressed) input. That is, they can be moved to a small degree or a large degree, and your character's movement can vary accordingly. While these input methods are ideal for providing scalable amounts of movement input, AxisMappings can also map common movement keys, like WASD or Up, Down, Left, Right, to continuously-polled game behavior.

Setting Input Mappings

Input mappings are stored in configuration files, and can be edited in the Input section of Project Settings.

In the Level Editor, select Edit > Project Settings.



Click Input in the Project Settings tab that appears.

In this window, you can:

Change the properties of (hardware) axis inputs:

Add or edit ActionMappings:

Add or edit AxisMappings:

InputComponent

InputComponents are most commonly present in Pawns and Controllers, although they can be set in other Actors and Level Scripts if desired. The InputComponent links the AxisMappings and ActionMappings in your project to game actions, usually functions, set up either in C++ code or Blueprint graphs.

The priority stack for input handling by InputComponents is as follows (highest priority first):

Actors with "Accepts input" enabled, from most-recently enabled to least-recently enabled.

If you want a particular Actor to always be the first one considered for input handling, you can re-enable its "Accepts input" and it will be moved to the top of the stack.

Controllers.

Level Script.

Pawns.

If one InputComponent takes the input, it is not available further down the stack.

Input Processing Procedure



Example - Moving Forward

This example is taken from the First Person template provided with Unreal Engine.

Hardware Input from Player: The player presses W.

PlayerInput Mapping: The AxisMapping translates W to "MoveForward" with a scale of 1.



InputComponent Priority Stack: Proceeding through the InputComponent priority stack, the first binding of the "MoveForward" input is in the AFirstPersonBaseCodeCharacter class. This class is the current player's Pawn, so its InputComponent is checked last.

This step could also be accomplished in Blueprints by having an InputAxis MoveForward node in the Character's EventGraph. Whatever this node is connected to is what will execute when W is pressed.



Game Logic: AFirstPersonBaseCodeCharacter's MoveForward function executes.

Blueprint Implementation:



Touch Interface

By default, games running on touch devices will have two virtual joysticks (like a console controller). You can change this in your Project Settings, in the Input section, with the Default Touch Interface property. This points to a Touch Interface Setup asset. The default one, DefaultVirtualJoysticks is located in shared engine content (/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks). There is also a Left Stick only version, LeftVirtualJoystickOnly, for games that do not need to turn the camera.



Note that you will need to check the Show Engine Content checkbox in the object picker View Options settings to see these.



If you do not want any virtual joysticks, just clear the Default Touch Interface property. Additionally, you can force the touch interface for your game independent of the platform it is running by checking Always Show Touch Interface (or by running the PC game with -faketouches).

Enhanced Input Plugin

For projects that require more advanced input features, like complex input handling or runtime control remapping, the experimental Enhanced Input Plugin gives developers an easy upgrade path and backward compatibility with the engine's default input system. This plugin implements features like radial dead zones, chorded actions, contextual input and prioritization, and the ability to extend your own filtering and processing of raw input data in an Asset-based environment.

Getting Started

To configure your project to use Enhanced Input, enable the Enhanced Input Plugin. You can do this by opening the Edit dropdown menu in the editor and selecting Plugins. Under the Input section of the Plugin List, find and enable the Enhanced Input Plugin, then restart the editor.



The plugin will become active after you restart the editor.

Once the editor has restarted, you can set your project to use Enhanced Input Plugin classes instead of the default Unreal Engine input handlers. Go to the Edit dropdown menu and choose Project Settings. From there, locate the Input section (under the Engine heading) and find the Default Classes settings. These will initially contain the standard PlayerInput and InputComponent classes.



To use Enhanced Input, change these settings to EnhancedPlayerInput and EnhancedInputComponent, respectively.



Core Concepts

The Enhanced Input system has four main concepts:

Input Actions are the communication link between the Enhanced Input system and your project's code. An Input Action can be anything that an interactive character might do, like jumping or opening a door, but could also be used to indicate user input states, like holding a button that changes walking movement to running. Input Actions are separate from raw input; an Input Action is not concerned with the specific input that triggered it, but does know its current state and can report an input value on up to three independent floating-point axes. As an example, a "pick up item" Action might only need an on/off state, indicating whether or not the user is trying to pick something up, while a "walk" Action might require two axes to describe the direction and speed at which the user is trying to walk.

Input Mapping Contexts map user inputs to Actions and can be dynamically added, removed, or prioritized for each user. You can apply one or more Contexts to a local player through its Enhanced Input Local Player Subsystem, and prioritize them to resolve collisions between multiple actions trying to consume the same input. A common example of this might be a single button that can open doors while the character is walking around in the world, or select an item while looking through the character's backpack. Whenever the character opens the backpack, you could add a "select item" Input Mapping Context that out-prioritizes the "open door" context, and then remove the "select item" context when the character closes the backpack. This would ensure that the user's inputs will be interpreted correctly based on the character's situation, and prevent the need to program code at the input-handling level with awareness of the door and backpack systems. Modifiers adjust the value of raw input coming from the user's devices. An Input Mapping Context can have any number of modifiers associated with each raw input for an Input Action. Common Modifiers including dead zones, input smoothing over multiple frames, conversion of input vectors from local to world space, and several others are included in the plugin; developers can also create their own Modifiers.

Triggers use post-Modifier input values, or the output magnitudes of other Input Actions, to determine whether or not an Input Action should activate. Any Input Action within an Input Mapping Context can have one or more Triggers for each input. For example, taking a photograph might require that the user hold down the Left Mouse Button for a quarter of a second while a separate Input Action for aiming the camera is active.

By combining these concepts, developers can quickly set up input systems ranging from simple to complex, and adjust these systems without having to change project code.

Input Actions

Input Actions are the connection between the system and your project's code. You can create an Input Action by right-clicking in the Context Browser, expanding the Input option, and choosing Input Action. To trigger an Input Action, you must include it in an Input Mapping Context, and add that Input Mapping Context to the local player's Enhanced Input Local Player Subsystem.



To make your Pawn class respond to a triggered Input Action, you must bind it to the appropriate type of Trigger Event in SetupPlayerInputComponent. The following sample code overrides SetupPlayerInputComponent to bind two Input Actions, MyInputAction and MyOtherInputAction, to handler functions:

Binding Input Actions with the Enhanced Input Plugin replaces the built-in input system's Action and Axis bindings; if you are using the Enhanced Input Plugin, you should only bind Input Actions. When binding Input Actions, you can choose between four different handler function signatures, as follows:

Return Type

Parameters

Usage Notes

void

()

Suitable for simple cases where you don't need any extra information from the Enhanced Input system.

void

(const FInputActionValue& ActionValue)

Provides access to the current value of the Input Action.

void

(const FInputActionInstance& ActionInstance)

Provides access to the current value of the Input Action, the type of trigger event, and relevant timers.

void

(FInputActionValue ActionValue, float ElapsedTime, float TriggeredTime)

Signature used when dynamically binding to a UFunction by its name; parameters are optional.

Input Actions have built-in events that expose them to Blueprints Scripting; C++ developers do not have to create pass-through functions to give Blueprint Scripting developers access to Input Action events. A typical handler function might take the following form:

For most use cases, using the void (const FInputActionValue&) signature is recommended. Binding Input Actions to handler functions enables the Pawn to respond to them depending on the specific way that they are triggered. The most common trigger types are likely to be Started for actions that happen once, immediately upon pressing a button, and Triggered for continuous actions that happen every frame while holding an input, but you can view the complete list at the API reference page for Plugins/EnhancedInput/ETriggerEventETriggerEvent.

Input Mapping Contexts

Input Mapping Contexts describe the rules for triggering one or more Input Actions. Its basic structure is a hierarchy with a list of Input Actions at the top level. Under the Input Action level is a list of user inputs that can trigger each Input Action, such as keys, buttons, and movement axes. The bottom level contains a list of Input Triggers and Input Modifiers for each user input, which you can use to determine how an input's raw value is filtered or processed, and what restrictions it must meet in order to drive the Input Action at the top of its hierarchy. Any input can have multiple Input Modifiers and Input Triggers. These will evaluate in order, using the output of each step as the input for the next.

To create an Input Mapping Context, right-click the Context Browser, expand the Input option, and choose Input Mapping Context.



Populate your Input Mapping Context with all of the relevant Input Actions. For a simple project, you may be able to put all of your Input Actions into a single Input Mapping Context. More complex projects may work best with multiple Input Mapping Contexts, since a local player can have more than one active Input Mapping Context at a time. As an example, a character who can swim, walk, and drive vehicles might have an Input Mapping Context for common actions that are always available and always mapped to the same user inputs, and separate Input Mapping Contexts for each mode of travel. Developers could then place the vehicle-related Input Actions into a separate Input Mapping Context, which they can then add to the local player upon entering a vehicle, and remove from the local player upon exiting. Doing this helps to reduce bugs by ensuring that inappropriate Input Actions cannot run (and don't waste CPU cycles), and by avoiding input collisions when a user input is used for different Input Actions by mutually-exclusive Input Mapping Contexts. See the sections on Modifiers and Triggers for more details.



This Input Mapping Context shows an Input Action for running, which can be activated by multiple inputs, including a gamepad's left thumbstick deflection, combining both axes into a single input. That input's raw value will go through a "dead zone" Input Modifier, and the resulting value will be sent to the "hold" Input Trigger to drive the "RunAction" Input Action.



There are a large number of input bindings available in the dropdown list. To select your input binding more quickly, press the small button to the left of the dropdown, and then press the key or button you want to bind.



This simple Input Mapping Context supports Input Actions for running and jumping. Once you have populated an Input Mapping Context, you can add it to the Local Player associated with the Pawn's Player Controller . Do this by overriding the PawnClientRestart function and adding a code block like this:

With your Input Mapping Contexts added, your Pawn is able to respond to any Input Action events you bound in SetupPlayerInputComponent, or that Blueprint Scripting users have set up. If events occur during gameplay that warrant changing the set of available Input Mapping Contexts, you can use ClearAllMappings, AddMappingContext, and RemoveMappingContext to update the set of available commands dynamically. Check the Plugins/EnhancedInput/IEnhancedInputSubsystemInterfaceIEnhancedInputSubsystemInterface API reference page for more information.

Input Modifiers

Input Modifiers are pre-processors that alter the raw input values that Unreal Engine receives before sending them on to Input Triggers. The Enhanced Input Plugin ships with a variety of Input Modifiers to perform tasks like changing the order of axes, implementing "dead zones", converting axial input to world space, and several others. Each input associated with an Input Action within an Input Mapping Context will go through a user-defined series of Input Modifiers before proceeding to the Input Trigger (or Input Triggers) for that input. Input Modifiers are applied in the order they are listed, and the output value from each Input Modifier becomes the input value for the next. To see the complete list of Input Modifiers included with the Enhanced Input Plugin, check the Plugins/EnhancedInput/UInputModifierUInputModifier API reference page. If your project requires an Input Modifier that doesn't already exist, you can create your own UInputModifier class.

Input Triggers

Input Triggers determine whether or not a user input, after passing through an optional list of Input Modifiers, should activate the corresponding Input Action within its Input Mapping Context. Most Input Triggers analyze the input itself, checking for minimum actuation values and validating patterns like short taps, prolonged holds, or the typical "press" or "release" events. The one exception to this rule is the "Chorded Action" Input Trigger, which requires another Input Action to be triggered. By default, any user activity on an input will trigger on every tick. To see the complete list of Input Triggers included with the Enhanced Input Plugin, check the Plugins/EnhancedInput/UInputTriggerUInputTrigger API reference page. If you need an Input Trigger that the Enhanced Input Plugin does not provide, you can create your own UInputTrigger class.

Components Window

Tools and Editors

Timelines

Force Feedback Effect Assets

Creating a Force Feedback Effect Asset

Playing Force Feedback

Sometimes being called "rumble" or controller vibration, Force Feedback refers to the vibration of a device (such as gamepads or controllers), often being used in games to convey a force occurring in the game to the player. A simple example is when an explosion occurs in the game and force feedback is used to simulate the shockwave, which gives an additional dimension to a player's immersion.

Once implemented, Force Feedback will work on all platforms where it is supported. This includes iOS (as of 4.10), Android, and controllers.

Force Feedback Effect Assets

A Force Feedback Effect Asset contains the properties used to define a specific force feedback effect. This enables designers to customize the force feedback to each situation it is used in.



Each Force Feedback Effect can have multiple channels, each of which can play a different effect. For instance, one channel could play a large, long vibration on the right side of the controller, while a second channel could play small, short bursts on the left side. The pattern of the effect for each channel is controlled by a curve. This curve can be edited here with right-click, or the internal curve editor can be opened by double-clicking in the curve's graph.



For information on Curves, Keys, creating external Curve Assets, and using the Curve Editor, check out the Curve Editor and Keys and Curves pages.

The duration of the force feedback effect will be calculated automatically, based on the position of the last key in the curves for all channels. For example, if there are 3 channels and the last key in each is at 1.25, 1.5, and 1.75, then the duration for the overall effect will be 1.75.

Channel Properties

Each channel has the following properties that control how the effect for the channel is played.

Item

Description

Affects Left Large

If true, the left large motor will be used to play the effect.

Affects Left Small

If true, the left small motor will be used to play the effect.

Affects Right Large

If true, the right large motor will be used to play the effect.

Affects Right Small

If true, the right small motor will be used to play the effect.

Curve

A curve that controls the intensity of the effect over time. In other words, this defines the pattern of the vibration. Values above 0.0 will vibrate, while values below 0.0 will not vibrate.

Creating a Force Feedback Effect Asset

Force Feedback Effect assets are created using the Content Browser:

In the Content Browser, click Add New and choose Miscellaneous > Force Feedback Effect, and open the asset you have just created.



By default, the asset will have one channel but you can add more. For each channel, select the combination of the four outputs that the channel will affect.



Hold Shift and click the Left Mouse Button on the curve to add one or more keys.



Manipulate the keys by entering values directly or dragging them in the curve editor.

To adjust the curves between the keys, right-click on the curve segment to change its curve function, then adjust the tangent lines as usual.

Playing Force Feedback

Preview in Editor

You can preview your Force Feedback Effect in the editor by clicking the "play" button that appears in the middle of the Force Feedback Effect's icon when you mouse over it.



Directly to a Player

Force Feedback is implemented in the base PlayerController class. You will need access to the local Player Controller in order to play Force Feedback on the target device or controller.

Get a reference to your Player Controller, either with a Get Player Controller node or a saved reference.



Drag off of the output pin of the reference, then type Play Force Feedback into the context menu and select Client Play Force Feedback.



The force feedback will be replicated to the owning client if called on the server.

Specify the Force Feedback Effect to use directly on the node or with a connected variable.



Check Looping if you want the effect to loop.



Optionally, set a unique name for the effect via the Tag field. This feature allows you to stop the effect; if an effect with the same name is already playing, it will be stopped and the new effect will play instead.



Call ClientPlayForceFeedback on the local Player Controller, passing it the Force Feedback Effect to use as well as whether or not the effect should loop, and an optional name for the effect. If a name is provided, and another Force Feedback Effect with the same name is played before the original effect ends, the original will be stopped immediately and the new effect will play instead.

At a World Location

To play a Force Feedback Effect that changes intensity based on distance from the observing player, place a Force Feedback Component in the world at the intended source of the effect. A Force Feedback component plays a Force Feedback Effect on command, but also has a physical location in the world. Like sound or light, the intensity of the force experienced by the player will change with the player's distance from the source, according to a data-defined attenuation setting.

Force Feedback Components can be attached to any actor via the usual code or Blueprint editor methods, but they can also be added as they are needed during live gameplay. This can be accomplished by calling the utility functions UGameplayStatics::SpawnForceFeedbackAtLocation (to spawn at a given world location), or UGameplayStatics::SpawnForceFeedbackAttached (to attach to a specific pre-existing component). These functions will return the spawned Force Feedback Component, so you can continue to manipulate it if you like. However, if you have no use for the component after it finishes playing the effect, you can use the "Auto Destroy" option to have it remove itself once the effect ends.

Basic Framework Elements

To show how the different pieces of game framework interlock, here is a simple example. Imagine a simple concept for a game, where a rabbit races a snail. The base of the game framework is the GameMode. The GameMode sets the rules for the game, like the rule that whichever player crosses the finish line first is the winner. It also handles spawning the players.

A player is set up in a PlayerController, which can possess a Pawn. The Pawn is the physical representation of a player in the game, while the Controller possesses the Pawn and can set rules for its behavior. In our example, there would be two Pawns, one for the snail and one for the rabbit. The rabbit would actually be a Character, a special subclass of Pawn which has built-in movement functionality including running and jumping. The snail, on the other hand, has a different style of movement, so it could extend directly from the Pawn class.

A Pawn can contain its own rules for movement and other game logic, but that functionality can also be included in a Controller. A Controller can either be a PlayerController taking input from a human player or an AIController with automated control by the computer. In this example, the player would be controlling the snail, so the snail Pawn would be possessed by a PlayerController. The rabbit would be controlled by AI, with rules for when it should stop, sprint, or nap all being set up in an AIController which possesses the rabbit Character. Only human players care about the view provided by a Camera, so only one CameraComponent in the snail Pawn would be used by the PlayerCamera.

During gameplay, input from the player would move the snail around the map, while the HUD was overlaid on the view provided by the Camera, showing information about who was currently in first place, and the race time that had elapsed.

For quick descriptions of the basic framework elements, and a chart of how they fit together, check out the Gameplay Framework Quick Reference. Otherwise, you can use the links below to jump directly to pages with overviews of each class and information about how they can be set up in Blueprints or with C++.

Basic Framework Elements

Creating Actors

Components

Ticking

Lifecycle

Replication

Destroying Actors

An Actor is any object that can be placed into a level, such as a Camera, static mesh, or player start location. Actors support 3D transformations such as translation, rotation, and scaling. They can be created (spawned) and destroyed through gameplay code (C++ or Blueprints).

In C++, AActor is the base class of all Actors.

Note that actors do not directly store Transform (Location, Rotation, and Scale) data; the Transform data of the Actor's Root Component, if one exists, is used instead.

Creating Actors

Creating new instances of AActor classes is called spawning. This can be done using the generic SpawnActor() function or one of its specialized templated versions.

See



Components

Actors can be thought of, in one sense, as containers that hold special types of Objects called Components. Different types of Components can be used to control how Actors move, how they are rendered, etc. The other main function of Actors is the replication of properties and function calls across the network during play.

Components are associated with their containing Actor when they are created.

A few of the key types of Components are:

This is the base Component. It can be included as part of an Actor. It can Tick if you want it to. ActorComponents are associated with a specific Actor, but do not exist at any specific place in the world. They are generally used for conceptual functionality, like AI or interpreting player input.

SceneComponents are ActorComponents that have transforms. A transform is a position in the world, defined by location, rotation, and scale. SceneComponents can be attached to each other in a hierarchical fashion. An Actor's location, rotation, and scale are taken from the SceneComponent that is at the root of the hierarchy.

PrimitiveComponents are SceneComponents that have a graphical representation of some kind (e.g. a mesh or a particle system). Many of the interesting physics and collision settings are here.

Actors support having a hierarchy of SceneComponents. Each Actor also has a RootComponent property that designates which Component acts as the root for the Actor. Actors themselves do not have transforms, and thus do not have locations, rotations, or scales. Instead, they rely on the transforms of their Components; more specifically, their root Component. If this Component is a SceneComponent, it provides the transformation information for the Actor. Otherwise, the Actor will have no transform. Other attached Components have a transform relative to the Component they are attached to.

An example Actor and hierarchy might look something like this:

GoldPickup Actor

Hierarchy



Root - SceneComponent: Basic scene Component to set the Actor's base location in the world.

StaticMeshComponent: Mesh representing gold ore.

ParticleSystemComponent: Sparkling particle emitter attached to the gold ore.

AudioComponent: Looping metallic chiming audio emitter attached to the gold ore.

BoxComponent: Collision box to use as trigger for overlap event for picking up the gold.

Ticking





Actors all have the ability to be ticked by default via the Tick() function.

ActorComponents also have the ability to be updated by default, though they use the TickComponent() function to do so. See the Updating section of the Components page for more information.

Lifecycle

See the



Replication

Replication is used to keep the Actors within the world in sync when dealing with networked multiplayer games. Property values and function calls can both be replicated, allowing for complete control over the state of the game on all clients.

Destroying Actors

Actors are not generally garbage collected, as the World Object holds a list of Actor references. Actors can be explicitly destroyed by calling Destroy(). This removes them from the level and marks them as "pending kill", which means they will hang around until they are cleaned up on the next garbage collection.

Quick Start Guides

Choose your implementation method:

Blueprints

C++

Blueprint scripting and C++ provide several ways to communicate and share information between Actors. This page gives you an overview of the different Actor communication methods available, as well as requirements and common use cases for each.

You will also find links to more detailed Quick Start guides for each Actor communication type.

Direct Communication

Direct Actor communication is the most common method of sharing information between Actors in your Level.

This method requires a reference to the target Actor so you can access its information from your working Actor. This communication type uses a one-to-one relationship between your working Actor and your target Actor.

When to Use It

Use this communication method if you have a reference to the specific Actor in your Level and you need to share information or trigger functionality within that specific Actor.

Examples

Triggering an event on an Actor.

Getting information from an Actor in your Level.

Casting

Casting is a common communication method where you take a reference to an Actor and try to convert it to a different class. If this conversion is successful, then you can use Direct communication to access its information and functionality.

This method requires a reference to the Actor in your Level as you can use the Cast node to try to convert it to a specific class. This communication method uses a one-to-one relationship between your working Actor and your target Actor.

When to Use It

Use this communication method if you have a reference to an Actor and want to check if the Actor is of a certain class to access its information.

Examples

Using a volume to overlap all Pawns and cast the Pawn reference to a particular subclass, such as a Character, to access its information.

Using an Actor's reference to cast to a common parent class and access its information.

Interfaces

Interfaces define a set of common behaviors or capabilities that can be implemented by different Actor classes. This communication method simplifies the process of implementing the same type of functionality on different Actor classes.

This method requires each Actor to implement the interface in order to access its common functions. You also need a reference to the Actor so you can call the interface function using that reference. This communication method uses a one-to-one relationship between your working Actor and your target Actor.

When to Use It

Use this method when you want to create common functionality that applies to different types of Actors.

Examples

Creating an interaction system where each Actor does something different when the player interacts. For example, a door Actor will open when the player interacts with it, while a light Actor will activate when the player performs the same interaction.

Applying damage to different Actors in your Level. Each Actor can react differently to the damage taken. For example, a wall Actor could break when taking damage, while a door Actor could open after taking damage.

Event Dispatchers

Event Dispatchers are a communication method where one Actor triggers an event and other Actors that are listening to that event get notified.

This method requires you to create Event Dispatchers on the working Actor and have your target Actors bind to them. This communication method uses a one-to-many relationship, where a single working Actor triggers the Event Dispatcher for many listening Actors.

When to Use It

Use this communication method when you want a single event to influence several different Actors.

Examples

Creating a BossDied event in your game. Once a boss enemy dies, the event will trigger, causing a door Actor to open, the HUD Actor to display a message, and a chest Actor to open.

Creating a day / night cycle where the DayStarted event tells your NPCs that they must start their daily routines.

Actor Communication Reference Table

Communication Type

When to Use It

Requirements

Example

Direct Communication

When communicating with a specific instance of an Actor in your Level.

Need a reference to the Actor in your Level.

Triggering an event on a specific Actor in your Level.

Casting

When you want to verify an Actor is of a certain class to access its properties.

Need a reference to an Actor in your Level to cast to the desired Actor class.

Accessing specific functionality of child Actors that share the same parent class.

Interfaces

When adding the same functionality to different Actor classes.

Need a reference to the Actor in your Level and the Actor needs to implement the interface.

Adding an interaction behavior to different types of Actors.

Event Dispatchers

When triggering an event from one Actor to many Actors.

Actors need to subscribe to the event to react to it.

Notifying many different types of Actors that an event has triggered.

Blueprint scripting and C++ provide several ways to communicate and share information between Actors. This page gives you an overview of the different Actor communication methods available, as well as requirements and common use cases for each.

You will also find links to more detailed Quick Start guides for each Actor communication type.

Direct Communication

Direct Actor communication is the most common method of sharing information between Blueprint Actors in your Level.

This method requires a reference to the target Actor class Blueprint so you can access its information from your working Actor. This communication type uses a one-to-one relationship between your working Actor and your target Actor.

When to Use It

Use this communication method if you have a reference to the specific Actor class Blueprint in your Level and you need to share information or trigger functionality within that specific Actor class Blueprint.

Examples

Triggering an event on an Actor.

Getting information from an Actor in your Level.

Casting With Blueprint Classes

Casting is a common communication method where you take a reference to an Actor class Blueprint and try to convert it to a different class. If this conversion is successful, then you can use Direct communication to access its information and functionality.

This method requires a reference to the Actor class Blueprint in your Level as you can use casting to try to convert it to a specific class. This communication method uses a one-to-one relationship between your working Actor and your target Actor.

When to Use It

Use this communication method if you have a reference to an Actor class Blueprint and want to check if the Actor class Blueprint is of a certain class to access its information.

Examples

Using an AVolume to overlap all APawns and cast the Pawn reference to a particular subclass, such as an ACharacter, to access its information.

Using an Actor class Blueprint's reference to cast to a common parent class and access its information.

Interfaces

Interfaces (UInterface) define a set of common method behaviors that can be implemented by different classes. This communication type simplifies the process of implementing the same type of functionality on different Actor class Blueprints.

This method requires each Actor to implement the interface in order to access its common methods. You will require a reference to the Actor class Blueprint so you can call the interface function using that reference. This communication method uses a one-to-one relationship between your working Actor and your target Actor.

Note: See Interfaces for additional documentation.

When to Use It

Use this method when you want to create common functionality that applies to different types of Blueprint Actors.

Examples

Creating an interaction system where each Actor class Blueprint does something different when the player interacts. For example, a door Actor will open when the player interacts with it, while a light Actor will activate when the player performs the same interaction.

Applying damage to different Actors in your Level. Each Actor class Blueprint can react differently to the damage taken. For example, a wall Actor could break when taking damage, while a door Actor could open after taking damage.

Delegates

Delegates can call methods in Actor class Blueprints in a type-safe way. A delegate can be bound dynamically to form a relationship where one Actor triggers an event on another Actor "listening" to be notified for that event.

Note: See Delegates for additional documentation.

When to Use It

Use this communication type when you want a single event to influence several different Actor class Blueprints.

Examples

Creating a BossDied event in your game. Once a boss enemy dies, the event will trigger, causing a door Actor to open, the UMG Blueprint to display a message, and a chest Actor to open.

Creating a day / night cycle where the DayStarted event tells your NPCs that they must start their daily routines.

Communicating with Blueprint Classes Reference Table

Communication Type

When to Use It

Requirements

Example

Direct Communication

When communicating with a specific instance of an Actor in your Level.

Need a reference to the Actor in your Level.

Triggering an event on a specific Actor in your Level.

Casting

When you want to verify an Actor is of a certain class to access its properties.

Need a reference to an Actor in your Level to cast to the desired Actor class.

Accessing specific functionality of child Actors that share the same parent class.

Interfaces

When adding the same functionality to different Actor classes.

Need a reference to the Actor in your Level and the Actor needs to implement the interface.

Adding an interaction behavior to different types of Actors.

Event Dispatchers

When triggering an event from one Actor to many Actors.

Actors need to subscribe to the event to react to it.

Notifying many different types of Actors that an event has triggered.

Quick Start Guides



Quick Start for the Event Dispatcher and Delegate communication method.



Quick Start for the Interface communication method.

Choose your implementation method:

Blueprints

C++

Overview

Casting is a common communication method where you take a reference to an Actor and try to convert it to a different class. If the conversion is successful, then you can use Direct Actor communication to access its information and functionality.

This method requires a reference to the Actor in your Level so you can use the Cast node to try to convert it to a specific class. This communication method uses a one-to-one relationship between your working Actor and your target Actor.

Goals

In this Quick Start guide, you will learn how to use Casting to access information from a target Actor.

Objectives

Create an Actor that rotates based on the value of a variable.

Modify the ThirdPersonCharacter Blueprint to cast to the rotating Actor on overlap.

Create several child Actors from the rotating Actor to show how casting works with many Actors that share the same parent.

1 - Required Setup

In the New Project Categories section of the menu, select Games and click Next.



Select the Third Person template and click Next.



Select the Blueprint and With Starter Content options and click Create Project.



Section Results

You have created a new Third Person project and are now ready to learn about casting.

2 - Creating a Rotating Actor

For this example, you will create an Actor that begins rotating a Static Mesh when the player is nearby.

Right-click in the Content Browser and click Blueprint Class under the Create Basic Asset section.



Select Actor as your Parent Class and name the Blueprint BP_RotateObject.





Open the Blueprint by double-clicking it in the Content Browser. Then in the Blueprint editor window, go to the Components panel and click the Add Component button. Search for and select Static Mesh. This will add a Static Mesh component to the Blueprint.



With the Static Mesh component selected, go to the Details panel and click the Static Mesh dropdown. Search for and select Shape_Cube.



Right-click in the Event Graph to open the context sensitive search window and search for and select AddActorLocalRotation to add this node to the graph.



Connect the AddActorLocalRotation node to Event Tick. Set the Z value to 2.0.**



Compile and Save the Blueprint.

Drag the BP_RotateObject Actor into the Level and press Play. You should see the cube rotate continuously.





Now you will add a condition so the object spins only when the player is nearby. Right-click the Event Graph and add a Branch node. Connect the node between the output pin of Event Tick and the input pin of AddActorLocalRotation nodes.



Create a variable of type Boolean called Can Rotate and connect it to the Condition pin of the Branch **node, as shown below.



Compile the Blueprint and set the Default Value of CanRotate to False.



Go to the My Bueprints tab and click the + Function button to create a new function. Name the function OverlappedPlayer.



With the function selected, go to the Details panel and click the + New Parameter button. Name the new boolean parameter Begin Overlap.



Drag the CanRotate variable inside the function and select Set CanRotate. Connect the Overlapped Player node to the Set Can Rotate node. Connect the Begin Overlap pin of the Overlapped Player node to the Can Rotate pin of the Set Can Rotate node, as seen below.



Compile and Save the Blueprint.

Section Results

In this section you created an Actor that rotates a Static Mesh when the CanRotate variable is set to True.

3 - Modifying the Player Blueprint

In this section, you will modify the ThirdPersonCharacter Blueprint to cast to the BP_RotateObject Actor and set its Rotate variable to True when you are nearby.

With your ThirdPersonCharacter Blueprint selected, go to the World Outliner and click Edit ThirdPersonCharacter to open the Blueprint.



In the Blueprint editor window, go to the Components panel and click the Add Component button. Search for and select Sphere Collision. This will add a Sphere Collision component to the Blueprint.



With the Sphere Collision component selected, go to the Details panel and set the Radius to 200.



Right-click the Sphere Collision component and select the OnComponentBeginOverlap and OnComponentEndOverlap events to add them to the Event Graph.





Drag from the On Component Begin Overlap node's Other Actor pin, then search for and select cast to BP Rotate Object.



Drag from the As BP Rotate Object pin and search for and select Overlapped Player. Enable the Begin Overlap pin of the Overlapped Player node.





Repeat steps 5 and 6 to attach the same nodes to the On Component End Overlap node. Disable the Begin Overlap pin of the Overlapped Player node.



Compile and Save the Blueprint.

Press Play and approach the BP_RotateObject Actor to see it rotate only when the player is nearby.



Section Results

In this section you added a sphere overlap component to the ThirdPersonCharacter Blueprint that uses the Cast node on any Actor it overlaps.

The ThirdPersonCharacter Blueprint uses the overlapped Actor reference to Cast to BP_RotateObject and sets the CanRotate variable to True when nearby. If the overlapped Actor is not an instance of the BP_RotateObject class, then the node will fail and no variable will be set.

4 - Adding Different Rotating Shapes

You will now create several child Actors from the BP_RotateObject Actor class to add different shapes that react to the player. This will demonstrate how you can use child Actors to make changes or add additional functionality, while still retaining the ability to cast to the common parent class.

Right-click BP_RotateObject in the Content Browser and select Create Child Blueprint Class. Name the Blueprint BP_RotateObject_Cone.



Repeat the above step two more times and create BP_RotateObject_Pyramid and BP_RotateObject_Torus.



Open BP_RotateObject_Cone and select the Static Mesh component in the Components window. From the Details panel, click the Static Mesh dropdown and search for and select Shape_Cone.



Set the Y Rotation to 90 degrees.



Compile and Save the Blueprint.

Repeat the above steps for BP_RotateObject_Pyramid and select Shape_Quad_Pyramid as the Static Mesh.

Repeat the above steps for BP_RotateObject_Torus and select Shape_Torus as the Static Mesh. Rotate the mesh by 90 degrees in Y.

Drag each shape into your Level and press Play to verify they all rotate when the player is nearby.





Section Results

In this section you created several child Actors from the BP_RotateObject Actor and assigned a different Static Mesh to each.

You also learned that you can cast to an Actor's parent class to access common functionality. In this case, you overlapped each separate child Actor and casted to its parent class to trigger the rotation.

Next Steps

Now that you know how to use casting, take a look at the other types of communication referenced in the Actor Communication documentation page.

Overview

Casting Blueprint classes is a common communication type, in which you use a reference to an Actor class Blueprint and convert it to a different class. If this conversion is successful, then you can use Direct Blueprint communication to access its information and functionality.

This method requires a reference to the Actor class Blueprint in your Level so you can use the Cast node to try to convert it to a specific class. This communication type uses a one-to-one relationship between your working Actor class Blueprint to your target Actor class Blueprint.

Goals

In this Quick Start guide, you will learn how to create an Actor in C++, that has the Blueprint casting functionality used to access information from a target Blueprint.

Objectives

Create a Blueprint that rotates based on the value of a variable.

Modify the ThirdPersonCharacter Blueprint to cast to the rotating Blueprint on overlap.

Create several child Blueprint clases from the rotating Blueprint to show how Blueprint casting works for many Blueprint classes that share the same parent.

1 - Required Setup

In the New Project Categories section of the menu, select Games and click Next.



Select the Third Person template and click Next.



Select the C++ and With Starter Content options and click Create Project.



Section Results

You have created a new Third Person project and are now ready to learn about casting with Actor class Blueprints.

2 - Creating a Rotating Actor

For this example, you will create an Actor class Blueprint that has the functionality to rotate its Static Mesh Component when the player is nearby.

From the C++ Class Wizard, create a new Actor class named RotatingActor.



In the class defaults of your RotatingActor.h implement the following code.

Navigate to your RotatingActor.cpp and declare the following code in the constructor ARotatingActor::ARotatingActor

Implement the following code for your ARotatingActor::RotateActor method.

Navigate to the ARotatingActor::Tick method and implement the following code.

Finished Code

RotatingActor.h

RotatingActor.cpp

Compile your code.

In the editor, navigate to your C++ Classes folder, right-click your RotatingActor and from the C++ class actions dropdown menu, select Create Blueprint class based on RotatingActor named BP_RotatingActor.



In the class defaults for your BP_RotatingActor Blueprint, navigate to the Components tab, select the MeshComp Static Mesh Component, then navigate to the Details panel and from the Static Mesh category,select the arrow next to the Static Mesh variable. Lastly, from the dropdown menu, select the Shape_Cube static mesh.



Compile and save your Blueprint.

From the Content Browser, drag an instance of your Bp_RotatingActor into the Level.



Section Results

In this section, you created a Rotating Actor class Blueprint that includes the functionality to rotate a Static Mesh on tick when the bCanRotate variable is set to True.

3 - Modifying the Third Person Character Class

In this section, you will modify the BPCommunicationCharacter classto cast to the Rotating Actor class and set the bCanRotate variable to True when your player is nearby.

Open your BPCommunicationCharacter.h and implement the following.

In your BPCommunicationCharacter.cpp include the following class libraries

From the constructor ABPCommunicaionCharacter::BPCommunicationCharacter declare the following code.

Next, implement the ABPCommunicationCharacter::NotifyActorBeginOverlap, and ABPCommunicationCharacter::NotifyActorEndOverlap.

Compile your code.

Finished Code

BpCommunicationCharacter.h

BpCommunication.cpp

Press Play and approach the BP_RotateObject Actor to see it rotate only when the player is nearby.



Section Results

In this section you added a Sphere Component to the BPCommunicationCharacter class.

You also created the overlap logic necessary to cast into the RotatingActor class, and call its SetbCanRotate function, which sets the bCanRotate variable to True when the player Character's Sphere Component overlaps it.

4 - Adding Different Rotating Shapes

You can now create several child Blueprint classes from the BP_RotatingActor Blueprint to add different shapes that react to the player Character. This will demonstrate how you can use child Blueprint classes to modify or add additional functionality, while still retaining the ability to cast to the common parent class.

From the Content Browser, right-click BP_Rotating Actor and select Create Child Blueprint Class. Name the Blueprint BP_RotateObject_Cone.



Repeat step 1 two more times to create BP_RotateObject_Pyramid and BP_RotateObject_Torus Blueprint classes.



Open BP_RotateObject_Cone in the Blueprint editor and select the Static Mesh component from the Components tab. From the Details panel, click the Static Mesh dropdown then search for and select Shape_Cone.



Set the Y Rotation to 90 degrees.



Compile and save the Blueprint.

Repeat steps 3 - 5 for BP_RotatingActor_Pyramid and select Shape_Quad_Pyramid as the Static Mesh.

Repeat steps 3 - 5 for BP_RotatingActor_Torus and select Shape_Torus as the Static Mesh. Rotate the mesh by 90 degrees in Y.

Drag each shape into your Level and click Play to verify they all rotate when the player is nearby.





Section Results

In this section, you created several child Blueprint classes from the BP_RotateObject Blueprint and assigned a different Static Mesh to each.

You also learned that you can cast to a Blueprint Actor's parent class to access common functionality. In this case, you overlapped each separate child Blueprint and casted to its parent class to trigger the rotation.

Next Steps

Now that you know how to use Blueprint casting, take a look at the other communication types referenced in the Actor Communication documentation page.

Choose your implementation method:

Blueprints

C++

Overview

Direct Actor communication is a common method of sharing information between Actors in your Level. This method requires a reference to the target Actor so you can access it from your working Actor. This communication method uses a one-to-one relationship between your working Actor and your target Actor. In this Quick Start guide, you will learn how to use direct Actor communication to access information from a target Actor in order to use its functions.

1 - Required Setup

In the New Project Categories section of the menu, select Games and click Next.



Select the Third Person template and click Next.



Select the Blueprint and With Starter Content options and click Create Project.



Section Results

You have created a new Third Person project and are now ready to learn about direct Actor communication.

2 - Adding Direct Actor Communication

Go to Starter Content > Blueprints inside the Content Browser and drag the Blueprint_CeilingLight actor into the Level.



Select your ThirdPersonCharacter Actor in the Level and position it closer to the lamp.



With your ThirdPersonCharacter Actor selected, go to the World Outliner and click Edit ThirdPersonCharacter to open the Blueprint editor.



Go to the Variables section and click the + Variable button to create a new variable.



Name the variable LampReference.

Go to the Details panel and click the Variable Type dropdown. Search for and select the Object Reference for the Blueprint Ceiling Light as shown below.



Finally, enable the Instance Editable checkbox and Compile and Save the Blueprint.



In the Event Graph, right-click and search for and select the F key to create the input node.



Drag from the Pressed pin of the F Key node and search for and select Flip Flop.



Drag the Lamp Reference variable into the Event Graph and select Get LampReference. Drag from the pin and search for and select Get Point Light 1.



Drag from the Point Light 1 pin and search for and select Set Visibility. Connect the A pin from the Flip Flop node to the Set Visibility node as shown below.



Copy the Lamp Reference, Point Lamp 1, and Set Visibility nodes and connect them to the B Pin of the Flip Flop Node. Enable the New Visibility checkbox as shown below.



Compile and Save the Blueprint.

Section Results

In this section you modified your ThirdPersonCharacter Blueprint Actor to use a reference to the lamp Actor and turn the lamp on and off by pressing the F key.

3 - Interacting with the Lamp Actor

Select the ThirdPersonCharacter Actor in your Level and from the Details panel click the Lamp Reference dropdown. Search for and select the Blueprint_CeilingLight Blueprint.



Press Play to go into Play Mode and press the F key to turn the lamp on and off.



Section Results

In this section you added the Ceiling Lamp Actor reference to the ThirdPersonCharacter Blueprint Actor and you turned the light on and off by pressing the F key.

Next Steps

Now that you know how to use direct Actor communication, take a look at the other types of communication referenced in the Actor Communication documentation page.

Overview

Direct Actor communication is a common method of sharing information between Actors in your Level. This method requires a reference to the target Actor so you can access it from your working Actor. This communication method uses a one-to-one relationship between your working Actor and your target Actor. In this Quick Start guide, you will learn how to use direct Actor communication to access information from a target Actor in order to use its functions.

1 - Required Setup

In the New Project Categories section of the menu, select Games and click Next.



Select the Third Person template and click Next.



Select C++ and With Starter Content options and click Create Project.



Section Results

You have created a new Third Person project and are now ready to learn about direct Blueprint communication.

2 - Creating the Ceiling Light Actor

From the C++ Class Wizard, create a new Actor class named CeilingLight.



In the class defaults of CeilingLight.h implement the following code.

Next navigate to CeilingLight.Cpp and declare the following Include library.

From the constructor ACeilingLight::CeilingLight declare the following.

Compile your code.

Finished Code

CeilingLight.h

CeilingLight.cpp

From the C++ Classes folder, right-click your CeilingLight Actor, then from the C++ Class Actions dropdown menu, select Create Blueprint class based on CeilingLight. Name your Blueprint BP_CeilingLight.



From the BP_CeilingLight class defaults, navigate to the Components panel, then select the StaticMeshComp.



From the Details panel, navigate to the Static Mesh category, select the dropdown arrow next to the Static Mesh variable, then search and select for SM_Lamp_Ceiling.



Compile and save your Blueprint.

From the Content Browser, drag an instance of your BP_CeilingLight Actor into your Level.



Modifying the ThirdPersonCharacter Class

Navigate to your C++ Classes folder, and double-click the BPCommunicationCharacter class to open its BPCommunicationCharacter.h, then declare the following code in the class defaults.

Navigate to your BPCommunicationCharacter.cpp, and declare the following include.

Implement your ABPCommunicationCharacter::ToggleCeilingLight method.

Navigate to the ABPCommunicationCharacter::SetupPlayerInputComponent method and declare the following.

In the Editor, navigate to Edit > Project Settings > Input. From the Bindings category, navigate to the Action Mappings then click the Add (+) button to create a new Action mapping named Use, and select the E key for the key value.



Compile your code.

Finished Code

BPCommunicationCharacter.h

BPCommunicationCharacter.cpp

3 - Interacting with the Lamp Blueprint

Select your ThirdPersonCharacter Blueprint in the Level and position it closer to the lamp.



With your ThirdPersonCharacter selected, navigate to the Details panel, then from the BPCommunication Character category, find the Ceiling Light To Toggle variable, and select the arrow adjacent to it. From the dropdown menu, search for and select the BP_CeilingLight Actor.



Press Play to go into PlE (Play-in Editor) mode and press the E key to turn the lamp on and off.



Section Results

In this section you added the Ceiling Light Actor reference to the ThirdPersonCharacter Blueprint and you turned the light on and off by pressing the E key.

Next Steps

Now that you know how to use direct Blueprint communication type, take a look at the other communication types referenced in the Actor Communication documentation page.

Choose your implementation method:

Blueprints

C++

Overview

Event Dispatchers are an Actor communication method where one Actor dispatches an event and other Actors that are listening to that event are notified.

Using this method, the notifying Actor creates an Event Dispatcher to which the listening Actors subscribe. This communication method uses a one to many relationship, where the working Actor triggers the Event Dispatcher and many listening Actors are notified.

Goals

In this Quick Start guide, you will learn how to use Event Dispatchers to create an OnBossDied event that will trigger on two Actors in your Level.

Objectives

Create the BossDied Actor that will create the Event Dispatcher.

Create a door Actor that will bind to the OnBossDied event.

Modify the Blueprint_Effect_Explosion Blueprint to bind to the OnBossDied event.

1 - Required Setup

In the New Project Categories section of the menu, select Games and click Next.



Select the Third Person template and click Next.



Select the Blueprint and With Starter Content options and click Create Project.



Section Results

You have created a new Third Person project and are now ready to learn about Event Dispatchers.

2 - Creating the OnBossDied Event

Right-click the Content Browser and click Blueprint Class under the Create Basic Asset section.



Select Actor class as your Parent Class and name the Blueprint BP_BossDied.





Open BP_BossDied in the Blueprint editor and from the Viewport, click the Add Component button then search for and select Box Collision.



With the Box collision selected, change the scale to X = 4, Y = 4, and Z = 2.



With the Box collision selected, go to the Rendering section of the Details panel and deselect the Hidden in Game checkbox. This will display the collision box during gameplay.



Right-click the Box collision and select Add OnComponentBeginOverlap. You will see the node added to the Event Graph.



From the My Blueprint panel on the left, navigate to the Event Dispatchers section and click + Add New to add a new event. Name this event OnBossDied.



Drag OnBossDied to the Event Graph and select Call to add the node.



Connect the On Component Begin Overlap node to the Call OnBossDied node. Compile and Save the Blueprint.



Drag the BP_BossDied Blueprint into the Level.



Section Results

In this section you created the BP_BossDied Actor to simulate what would happen if a boss character died in your game. In this Actor you created the OnBossDied Event Dispatcher which will be used to signal to other Actors when this event is triggered.

3 - Creating an Interactive Door

Right-click the Content Browser and click Blueprint Class under the Create Basic Asset section.



Select the Actor class as your Parent Class and name the Blueprint BP_BossDoor.



Open BP_BossDoor and from the Viewport click the Add Component dropdown then search for and select Static Mesh. Name the component Frame.



Add another Static Mesh component and name it Door.

Select the Frame component and from the Details panel click the Static Mesh dropdown then search for and select SM_DoorFrame.



Repeat the step above for the Door component and add the SM_Door static mesh.

With the Door component still selected, set the Y location to 45 as seen below. You should see the door aligned with the frame.





Right-click the Event Graph then search for and select Add Custom Event. Name the event OpenDoor.



Drag from the OpenDoor event then search for and select Add Timeline. Name the Timeline TM_Door.



Double-click TM_Door to open it. Click on the Add Float Curve button to add a Float Track and name it Alpha. Set the length to 1.0.



Right-click the graph and select Add key to CurveFloat_1 to add a new point. Set the Time and Value to 0.0.



Repeat the steps above to add another point with Time and Value set to 1.0.

Go back to the Event Graph and drag the Door Static Mesh component into the Event Graph to create a node. Drag from the Door node then search for and select SetRelativeRotation.



Connect the Update pin from TM_Door to the SetRelativeRotation node. Right-click the New Rotation pin and select Split Struct Pin.



Right-click the Event Graph then search for and select Lerp Float. Connect the Return Value to the Yaw pin on the SetRelativeRotation node. Connect the Alpha pin from TM_Door to the Alpha pin on the Lerp node. Lastly, set the value of B to 90.0 as shown below.



Add a new variable by clicking the + button next to the Variable section. Name the variable BossDiedReference.



On the Details panel click the Variable Type dropdown then search for and select the Object Reference of BP_BossDied. Check the Instance Editable checkbox.





Drag BossDiedReference to the Event Graph and select Get BossDiedRerence. From the node, drag then search for and select Bind Event to On Boss Died.



From the red Event pin of Bind Event to On Boss Died, drag then search for and select Add Custom Event. Name the event BossDied.



From the BossDied event node, drag then search for and select Open Door. Connect Event Begin Play to the Bind Event to On Boss Died node as seen below.



Compile and Save the Blueprint.

Section Results

In this section you created an interactive door Actor that binds to the On Boss Died Event Dispatcher found in the BP_BossDied Actor. This binding occurs on Begin Play, but is executed at runtime whenever this event is triggered by BP_BossDied.

4 - Creating an Interactive Explosion

Go to Starter Content > Blueprints and select Blueprint_Effect_Explosion. Drag it into your gameplay folder and select Copy Here.





Open Blueprint_Effect_Explosion in the Blueprint editor. From the Viewport, select the P_Explosion component and on the Details panel go to the Activation section and disable Auto Activate.



Repeat the step above for the Explosion Audio component.

Add a new variable by clicking the + button next to the Variable section. Name the variable BossDiedReference.



From the Details panel click the Variable Type dropdown then search for and select the Object Reference of BP_BossDied. Check the Instance Editable checkbox.





From the Event Graph right-click then search for and select Event Begin Play.

Drag BossDiedReference to the Event Graph and select Get BossDiedReference. From the node, drag then search for and select Assign On Boss Died. Name the custom event BossDied.



Connect Event Begin Play to the Bind Event to Boss Died node.



When you select the Assign option for the Event Dispatcher, a binding will be created as well as a custom event.

Drag the P_Explosion and Explosion Audio components to the Event Graph. Drag from P_Explosion then search for and select Activate. Connect Explosion Sound to the Target pin of the Activate node.

Connect the BossDied event node to the Activate node.



Compile and Save the Blueprint.

Section Results

In this section you modified Blueprint_Effect_Explosion to activate when the OnBossDied event is executed.

5 - Testing the Event Dispatcher

Drag the BP_BossDoor Actor into your Level. Go to the Details panel and click the Boss Reference Died dropdown then search for and select BP_BossDied.





Drag several instances of Blueprint_Effect_Explosion into your Level. Go to the Details panel and click the Boss Reference Died dropdown then search for and select BP_BossDied.





Press Play and walk over the BP_BossDied trigger to simulate your boss dying in the game.



Section Results

In this section you tested the BP_BossDoor and Blueprint_Effect_Explosion Actors in the Level. You confirmed that each Actor responds to the OnBossDied event when the BP_BossDied Actor triggers it.

In this guide you learned how to use Event Dispatchers to communicate between one working Actor to many target Actors. You also learned how to create Event Dispatchers and how to bind Actors to the event in order to trigger specific functionality.

Next Steps

Now that you know how to use Event Dispatchers, take a look at the other types of communication referenced in the Actor Communication documentation page.

Overview

Delegates can call methods in Actor class Blueprints in a type-safe way. A delegate can be bound dynamically to form a communication where one Actor triggers an event on another Actor that is listening to be notified for that event.

See Delegates for additional documentation.

Goals

In this Quick Start guide, you will learn how to use Delegates to create an OnBossDied event that will trigger two Actor class Blueprints in your Level.

Objectives

Create the Boss Actor that will contain an OnBossDied Delegate.

Create an interactive door Actor with a timeline component that will bind to the OnBossDied event.

1 - Required Setup

In the New Project Categories section of the menu, select Games and click Next.



Select the Third Person template and click Next.



Select the C++ and With Starter Content options and click Create Project.



Section Results

You have created a new C++ Third Person project and are now ready to learn about Delegates.

2 - Creating the Boss Actor and OnBossDied Delegate

From the C++ Class Wizard, create a new Actor class named BossActor.



Navigate to your BossActor.h. Underneath your library includes, declare the following Delegate.

In your class defaults, declare the following

Navigate to your BossActor.cpp and add the following class library.

Implement the following class definitions.

Compile your code.

From the C++ Classes folder, right-click your BossActor, then from the C++ Class Actions dropdown menu, select Create Blueprint class based on BossActor. Name your Blueprint class BP_BossActor.



Drag an instance of your BossActor into the Level.



Finished Code

BossActor.h

BossActor.cpp

Section Results

In this section you created the BossActor class, which contains a Box Component, and Delegate for a OnBossDied event, which will be used to signal other Actor classes when the event has been executed.

3 - Creating an Interactive Door

From the C++ Class Wizard, create a new Actor class named DoorActor.

Navigate to your DoorActor.h file and declare the following include:

Then declare the following class definitions.

Inside of DoorActor.cpp declare the following class library.

Implement the following class definitions.

Compile your code.

From the Content Browser, select Add/Import > Miscellaneous > Curve.



Select CurveFloat and name your CurveFloat asset DoorCurveFloat, then double-click your DoorCurveFloat asset. Add two keys to your Float Curve and give one key the time-value (0,0), and the other key the time-value of (4,90).



Shift-click to select both your keys, and set them to Auto Cubic interpolation, then save your Curve.



Save your DoorCurveFloat.

From the Content Browser, navigate to your C++ Classes folder, right-click your DoorActor class, then select Create Blueprint Class based on Door Actor. Name your Blueprint Actor Bp_DoorActor.



Inside BP_DoorActor's class defaults, find the Components tab, and select the DoorFrame Static Mesh component, navigate to the Details panel and change the Static Mesh to SM_DoorFrame.



Next, from the Components tab, select the DoorMesh component. Navigate to the Details panel and change the static mesh to SM_Door.

From the Details panel, select DoorCurveFloat from the Door Timeline Float Curve dropdown menu.



Compile and save your Blueprint.

Finished Code

DoorActor.h

DoorActor.cpp

Section Results

In this section you created an interactive DoorActor that binds to the OnBossDied Event Dispatcher found in the BossActor class. This binding occurs in Begin Play, but is executed at runtime whenever this event is triggered by an overlap in BossActor's Box Component.

5 - Testing the Event Dispatcher

Drag the BP_Door Blueprint into your Level. Go to the Details panel and click the Boss Reference Died dropdown and search for and select BP_BossDied.

With your Bp_DoorActor selected, navigate to the Details panel, click the Boss Actor Reference dropdown arrow, then search for and select BP_BossActpr.

Press Play and walk over the BP_BossActor trigger to simulate your boss dying in the game.



Section Results

In this section you tested the BP_DoorActor in the Level. You confirmed that the Actor responds to the OnBossDied event when the BP_BossActor's Box Component overlaps with another Actor to trigger the Delegate.

In this guide you learned how to use Delegates to communicate between multiple Actor class Blueprints.

Next Steps

Now that you know how to use Delegates, take a look at the other communication types referenced in the Actor Communication documentation page.

Choose your implementation method:

Blueprints

C++

Overview

Interfaces define a set of common behaviors or capabilities that can be implemented by different Actor classes. This method of communication is ideal when implementing the same type of functionality for different Actor classes.

An example of this would be when implementing a common activation behavior for several Actor classes in your project. These Actor classes could include a door, a window, a car, etc. Each Actor class is different and will perform different behavior when an Open Interface function is called.

In this example, an Interface is preferred to casting because you can use the same function call on all Actor classes, instead of casting to each individual one.

There are also performance benefits when Interfaces over casting, as loading an Actor that casts to another Actor will subsequently load that Actor to memory as well. If not treated carefully, this could result in a cascading loading effect where loading a single Actor results in several other Actors being loaded into memory as well.

This method requires each Actor to implement the interface in order to access its common functions. You also need a reference to the Actor so you can call the interface function using that reference. This communication method uses a one-to-one relationship between your working Actor and your target Actor.

Goals

In this Quick Start guide, you will learn how to use Interfaces by creating a simple interaction system to communicate with two different Actors.

Objectives

Create an Interface with an Interact function.

Create interactive lamp and door Actors and implement the interface.

Modify the ThirdPersonCharacter Blueprint to call the Interact interface function on nearby objects.

1 - Required Setup

In the New Project Categories section of the menu, select Games and click Next.



Select the Third Person template and click Next.



Select the Blueprint and With Starter Content options and click Create Project.



Section Results

You have created a new Third Person project and are now ready to learn about Interfaces.

2 - Creating an Interface

Right-click inside the Content Browser and select Blueprints > Blueprint Interface. Name the interface BPI_Interact.

Using the prefix BPI_ is a common naming convention for Blueprint Interfaces.





Open BPI_Interact by double-clicking itin the Content Browser. Name your first function Interact under the Functions list.



Compile and Save the interface.

Section Results

In this section you created an Interface and added the function Interact. Any Actor that implements this interface will now be able to add this function.

3 - Creating an Interactive Lamp

Go to Starter Content > Blueprints in the Content Browser. Right-click Blueprint_CeilingLight and select Duplicate. Name this Blueprint BP_Lamp and move it to your game folder.





Open BP_Lamp by double-clicking it in the Content Browser. Inside the Event Graph right-click then search for and select Add Custom Event. Name the event ToggleLight.



Drag from the ToggleLight node then search for and select Flip Flop.



Drag the Point Light 1 component into the Event Graph to create a reference node. Drag from the Point Light 1 node then search for and select Set Visibility. Connect the A pin of the Flip Flop node to the Set Visibility node as shown below.



Copy the Point Light 1 and Set Visibility nodes and connect them to the B pin of the Flip Flop node. Set New Visibility to True.



Click Class Settings from the Menu Bar and navigate to the Details panel.



Scroll down to the Interfaces section and click the Add dropdown then search for and select BPI_Interact. Compile and Save the Blueprint.



Go to the Interfaces section under the My Blueprint tab. Right-click the Interact interface function and select Implement event. You will see the Event Interact node appear in the Event Graph**.





Drag from the Event Interact node then search for and select ToggleLight.



Compile and Save the Blueprint.

Section Results

In this section you duplicated the Ceiling Lamp Blueprint and added a custom event that toggles the light's visibility. You also implemented the BPI_Interact interface and set up the Interact function to execute the ToggleLight event.

4 - Creating an Interactive Door

Right-click in the Content Browser and click Blueprint Class under the Create Basic Asset section.



Select the Actor class as your Parent Class and name the Blueprint BP_Door.





Open BP_Door by double-clicking it in the Content Browser. Then in the Blueprint editor, go to the Components panel and click the Add Component dropdown. Search for and select Static Mesh and name the component Frame. This will add a Static Mesh component to the Blueprint.



Add another Static Mesh component and name it Door.

Select the Frame component and under the Details panel click the Static Mesh dropdown then search for and select SM_DoorFrame.



Repeat the step above for the Door component and add the SM_Door static mesh.

With the Door component selected, set the Y location to 45.0 as seen below. You should see the door aligned with the frame.





Right-click in the Event Graph then search for and select Add Custom Event. Name the event OpenDoor. Repeat the process and create another event called CloseDoor.



Drag from the OpenDoor event node then search for and select Add Timeline. Name the Timeline TM_Door.



Connect the CloseDoor event to the Reverse execution pin on TM_Door.



Double-click TM_Door to open it. Click the Add Float Curve button to add a Float Track and name it Alpha. Set the length to 1.00.



Right-click on the graph and select Add key to CurveFloat_1 to add a new point. Set the Time and Value to 0.0.



Repeat the steps above to add another point with Time and Value set to 1.0.

Go back to the Event Graph and drag the Door Static Mesh component into the Event Graph to create a node. Drag from the Door node then search for and select SetRelativeRotation.



Connect the Update pin from TM_Door to the SetRelativeRotation node. Right-click the New Rotation pin of the SetRelativeRotation node and select Split Struct Pin.



Right-click the Event Graph then search for and select Lerp Float. Connect the Return Value of the Lerp node to the Yaw pin of the SetRelativeRotation node. Connect the Alpha pin of TM_Door to the Alpha pin of the Lerp node. Lastly, set the value of B to 90.0 as shown below.



Drag from the Finished pin of TM_Door then search for and select Retriggerable Delay. Set the value of the node to 2.0.



Drag from the Retriggerable Delay node then search for and select CloseDoor.



Click Class Settings on the Menu Bar.



In the Interfaces section click the Add dropdown then search for and select BPI_Interact.



Go to the Interfaces section under the My Blueprint tab. Right-click the Interact interface function and select Implement event. You will see the Event Interact node appear in the Event Graph**.



Drag from the Event Interact node then search for and select OpenDoor.



Compile and Save the Blueprint.

Section Results

In this section you created an interactive door Actor that will open its door when the Interact function of the BPI_Interact interface is called.

5 - Modifying the Player Blueprint

Select the ThirdPersonCharacter Blueprint in the Level. Go to the World Outliner and click Edit ThirdPersonCharacter to open the Blueprint editor.



In the Blueprint editor, go to the Components panel and click the Add Component button. Search for and select Sphere Collision. This will add a Sphere Collision component to the Blueprint.



With the Sphere Collision component selected, go to the Details panel and set the Radius to 200.



Right-click the Sphere Collision component and select the event OnComponentBeginOverlap to add it to the Event Graph.



Drag from the On Component Begin Overlap node then search for and select Interact (Message). Make sure you select the function under the BPI Interact category.



Connect the Other Actor node from the On Component Begin Overlap event to the Target pin on the Interact function.



Compile and Save the Blueprint.

Section Results

In this section you added a sphere collision component to the ThirdPersonCharacter Blueprint to detect overlapping Actors. When an Actor overlaps with the sphere, the Blueprint calls the Interact function from the BPI_Interact interface on that Actor. If the Actor does not have the interface implemented the node will fail silently.

6 - Testing the Interaction System

Drag the BP_Door and the BP_Lamp Actors to the Level.



Press Play and approach each Actor to see them interact with the player.



Section Results

In this section you confirmed that the interaction system is working as intended by testing it with the interactive door and lamp Actors.

In this Quick Start guide you learned how each Actor can implement the same interface function, and how they can specify the functionality separately. You also learned why Interfaces are ideal for implementing similar functionality on a wide variety of Actors without the need for casting.

Next Steps

Now that you know how to use Interfaces, take a look at the other types of communication referenced in the Actor Communication documentation page.

Overview

Interfaces define a set of common behaviors or methods that can be implemented by different Actors. This communication type is especially useful when implementing the same type of functionality across different Actor class Blueprint.

As an example, you may choose to use an Interface when implementing a common Open behavior for several Blueprint classes in your project, such as for a door, a window, a car, and so on. In this example, each Actor is a different class and will exhibit a different response when the Open Interface is called.

Additionally, there are performance benefits to using Interfaces over Casting, as loading an Actor class Blueprint that casts to another Actor class Blueprint will subsequently load that Blueprint to memory as well. If not used with caution, this could result in a cascading loading effect where loading a single Blueprint results in several other Blueprints being loaded into memory as well.

This method requires each Actor class Blueprint to implement the interface in order to access those common functions.

Goals

In this Quick Start guide, you will learn how to use Interfaces by creating a simple interaction system to communicate with two Actor class Blueprints.

Objectives

Create an Interface with an Interact function.

Create an interactive lamp and door Actor that implement the interface.

Modify the BpCommunication Character class to call the Interact interface function on nearby objects.

1 - Required Setup

In the New Project Categories section of the menu, select Games and click Next.



Select the Third Person template and click Next.



Select a C++ project with the With Starter Content option enabled, then click Create Project.



Section Results

You have created a new Third Person project and are now ready to learn about Interfaces.

2 - Creating an Interface

From the C++ Class Wizard, create a new Unreal Interface class named InteractInterface.



In the class defaults of your IInteractInterface.h declare the following method.

public:

Compile your code.

Finished Code

InteractionInterface.h

Section Results

In this section you created an Unreal Interface and added the function OnInteract. Any Actor class Blueprint that implements this interface will now be able to use this function.

2 - Creating an Interactive Ceiling Light Actor

From the C++ Class Wizzard, create a new Actor class named CeilingLight.



In the class defaults of CeilingLight.h declare the following class library.

Then, implement the following code.

Next, navigate to CeilingLight.cpp and declare the following Include library.

Then implement the following code.

Compile your code.

From the C++ Classes folder, right-click your CeilingLight Actor, then from the C++ Class Actions dropdown menu, select Create Blueprint class based on CeilingLight. Name your Blueprint BP_CeilingLight.



From the BP_CeilingLight class defaults, navigate to the Components panel, then select the StaticMeshComp.



From the Details panel, navigate to the Static Mesh category, select the dropdown arrow next to the Static Mesh variable, then search and select for SM_Lamp_Ceiling.



Finished Code

CeilingLight.h

CeilingLight.cpp

Section Results

In this section you created a Ceiling Light Actor class and added a custom function that toggles the light's visibility. Additionally, you implemented the Interact interface to trigger the execution of the ToggleLight **event.

4 - Creating an Interactive Door

From the C++ Class Wizard, create a new Actor class named DoorActor.

Navigate to your DoorActor.h file and declare the following include:

In your DoorActor class namespace, you will need to inherit from your Interact Interface.

Then declare the following class definitions.

Inside of DoorActor.cpp implement the following class definitions

Compile your code.

From the Content Browser, select Add/Import > Miscellaneous > Curve.



Select CurveFloat and name your CurveFloat asset DoorCurveFloat

Double-click your DoorCurveFloat asset. Add two keys to your Float Curve and give one key the time-value (0,0), and the other key the time-value of (4,90).



Shift-click to select both your keys, and set them to Auto Cubic interpolation, then save your curve.



Save your DoorCurveFloat.

From the Content Browser, navigate to your C++ Classes folder and right-click your DoorActor class. Select Create Blueprint Class based on Door Actor and name your Blueprint Actor Bp_DoorActor.



Inside BP_DoorActor's class defaults, find the Components tab, and select the DoorFrame Static Mesh component, navigate to the Details panel and change the Static Mesh to SM_DoorFrame.



Next, from the Components tab, select the DoorMesh component. Navigate to the Details panel and change the Static Mesh to SM_Door.



From the Details panel, select DoorCurveFloat from the Door Timeline Float Curve dropdown menu.



Compile and save your Blueprint.

Finished Code

DoorActor.h

DoorActor.cpp

Section Results

In this section you created an interactive Door Actor that opens when the OnInteract method of the Interact interface is called.

5 - Modifying the BPCommunicationCharacter class.

Open your BpCommunicationCharacter.h file and then declare the following in its class definitions.

Navigate to your BpCommunicationCharacter.cpp file and declare the following class libraries.

Then implement the following class methods.

Compile your code.

Finished Code

BpCommunicationCharacter.h

BpCommunicationCharacter.cpp

Section Results

In this section you added a sphere component to the ThirdPersonCharacter class to detect overlapping Actors. When an actor overlaps with the sphere, the Character casts to the interact Interface and triggers the OnInteract function for the overlapped Actor.

6 - Testing the Interaction System

Drag an instance of your BP_DoorActor and the BP_CeilingLamp Blueprints into the Level viewport.



Click Play and approach each Blueprint to see them interact with the player.



Section Results

In this section you confirmed that the interaction system is working as intended by testing it with the interactive door and ceiling lamp Actor Blueprints.

In this Quick Start guide you learned how each Actor class Blueprint can implement the same Interface, and also specify their functionality separately. You also learned why Interfaces are ideal for implementing similar functionality on a wide variety of Blueprint classes without the need for casting.

Next Steps

Now that you know how to use Blueprint Interfaces, take a look at the other communication types referenced in the Actor Communication documentation page.

Lifecycle Break Down

Load from Disk

Play in Editor

Spawning

Deferred Spawn

Coming to the End of Life

During Gameplay

Garbage Collection

Advanced Garbage Collection

This document is a high level overview of the lifecycle of an Actor: how an Actor is instantiated (Spawned) into the level and then how it is removed (Destroyed).

The flow graph below shows the three primary paths for how an Actor is instanced. No matter how an Actor is created, they all follow the same path to their destruction.

Lifecycle Break Down



Load from Disk

This path occurs for any Actor that is already in the level, like when LoadMap occurs, or AddToWorld (from streaming or sub levels) is called.

Actors in a package/level are loaded from disk.

PostLoad - is called by serialized Actor after they have finished loading from disk. Any custom versioning and fixup behavior should go here. PostLoad is mutually exclusive with PostActorCreated.

InitializeActorsForPlay

RouteActorInitialize for any non-initialized Actors (covers seamless travel carry over).

PreInitializeComponents - Called before InitializeComponent is called on the Actor's components.

InitializeComponent - Helper function for the creation of each component defined on the Actor.

PostInitializeComponents - Called after the Actor's components have been initialized.

BeginPlay - Called when the level is started.

Play in Editor

The Play in Editor path is mostly the same as Load from Disk, however the Actors are never loaded from disk, they are copied from the Editor.

Actors in the Editor are duplicated into a new World.

PostDuplicate is called.

InitializeActorsForPlay

RouteActorInitialize for any non-initialized Actors (covers seamless travel carry over).

PreInitializeComponents - Called before InitializeComponent is called on the Actor's components.

InitializeComponent - Helper function for the creation of each component defined on the Actor.

PostInitializeComponents - Called after the Actor's components have been initialized.

BeginPlay - Called when the level is started.

Spawning

When spawning (instancing) an Actor, this is the path that will be followed.

SpawnActor called

PostSpawnInitialize

PostActorCreated - called for spawned Actors after its creation, constructor like behavior should go here. PostActorCreated is mutually exclusive with PostLoad.

ExecuteConstruction:

OnConstruction - The construction of the Actor, this is where Blueprint Actors have their components created and Blueprint variables are initialized.

PostActorConstruction:

PreInitializeComponents - Called before InitializeComponent is called on the Actor's components.

InitializeComponent - Helper function for the creation of each component defined on the Actor.

PostInitializeComponents - Called after the Actor's components have been initialized.

OnActorSpawned broadcast on UWorld.

BeginPlay is called.

Deferred Spawn

An Actor can be Deferred Spawned by having any properties set to "Expose on Spawn."

SpawnActorDeferred - meant to spawn procedural Actors, allows additional setup before Blueprint construction script.

Everything in SpawnActor occurs, but after PostActorCreated the following occurs:

Do setup / call various "initialization functions" with a valid but incomplete Actor instance.

FinishSpawningActor - called to Finalize the Actor, picks up at ExecuteConstruction in the Spawn Actor line.

Coming to the End of Life

Actors can be destroyed in a number of ways, but the way they end their existence is always the same.

During Gameplay

These are completely optional, as many Actors will not actually die during play.

Destroy - is called manually by game any time an Actor is meant to be removed, but gameplay is still occurring. The Actor is marked pending kill and removed from Level's array of Actors.

EndPlay - Called in several places to guarantee the life of the Actor is coming to an end. During play, Destroy will fire this, as well Level Transitions, and if a streaming level containing the Actor is unloaded. All the places EndPlay is called from:

Explicit call to Destroy.

Play in Editor Ended.

Level Transition (seamless travel or load map).

A streaming level containing the Actor is unloaded.

The lifetime of the Actor has expired.

Application shut down (All Actors are Destroyed).

Regardless of how this happens, the Actor will be marked RF_PendingKill so during the next garbage collection cycle it will be deallocated. Also, rather than checking for pending kill manually, consider using an FWeakObjectPtr<AActor> as it is cleaner.

OnDestroy - This is a legacy response to Destroy. You should probably move anything here to EndPlay as it is called by level transition and other game cleanup functions.

Garbage Collection

Some time after an object has been marked for destruction, Garbage Collection will actually remove it from memory, freeing any resources it was using.

The following functions are called on the object during its destruction:

BeginDestroy - This is the object's chance to free up memory and handle other multithreaded resources (ie: graphics thread proxy objects). Most gameplay functionality related to being destroyed should have been handled earlier, in EndPlay.

IsReadyForFinishDestroy - The garbage collection process will call this function to determine whether or not the object is ready to be deallocated permanently. By returning false, this function can defer actual destruction of the object until the next garbage collection pass.

FinishDestroy - Finally, the object is really going to be destroyed, and this is another chance to free up internal data structures. This is the last call before memory is freed.

Advanced Garbage Collection

The garbage collection process in Unreal Engine builds clusters of objects that are all destroyed together. Clustering reduces the total time and overall memory churn associated with garbage collection compared to deleting objects indivudally. As an object loads, it may create subobjects. By combining the object and its subobjects into a single cluster for the garbage collector, the engine can delay freeing the resources used by the cluster until the entire object is ready to be freed, and can then free all of the resources at once.

Garbage collection does not need to be configured or modified at all for most projects, but there are some specific cases in which the "clustering" behavior of the garbage collector can be altered to improve efficiency in the following ways:

Clustering - Turn clustering off. In Project Settings, under the Garbage Collection section, the Create Garbage Collector UObject Clusters option can be set to false. For most projects, this will result in less efficient garbage collection, so it is recommended that this only be done in cases where performance testing reveals that it is definitely beneficial.



Clustering options for Garbage Collection within the Project Settings menu.



Ticking

Tick Groups

Tick Group Order

TG_PrePhysics

TG_DuringPhysics

TG_PostPhysics

TG_PostUpdateWork

Tick Dependency

Examples

Tick Group/Tick Dependency Usage Example

Actor Spawning

Component Ticking

Advanced Ticking Functionality

Ticking

"Ticking" refers to running a piece of code or Blueprint script on an actor or component at regular intervals, usually once per frame. Understanding the order in which your game's actors and components tick relative to each other and other per-frame tasks performed by the engine is essential to avoid off-by-one frame issues, as well as to ensure consistency in the way your game runs. Actors and components can be set up to tick each frame, at set minimum time intervals, or not at all. In addition, they can be grouped together at different phases in the engine's per-frame update loop, and can be individually instructed to wait for specific ticks to complete before beginning.

Tick Groups

Actors and components are ticked once per frame, unless a minimum ticking interval is specified. Ticking happens according to tick groups, which can be assigned in code or Blueprints. An actor or component's tick group is used to determine when in the frame it should tick, relative to other in-engine frame processes, mainly physics simulation. Each tick group will finish ticking every actor and component assigned to it before the next tick group begins. In addition to tick groups, actors or components may set tick dependency, which means that they will not tick until the specified other actor's or component's tick function is finished. Using tick groups and tick dependency can be vital to ensuring that your game works properly with regard to physics-dependent behaviors, or sequential gameplay behaviors that involve multiple actors or components.

The following are the tick groups available for gameplay use, in the order in which they run during the frame, as well as the specific meaning and context of each group:

Tick Group Order

Tick Group

Engine Activity

TG_PrePhysics

Beginning of the frame.

TG_DuringPhysics

Physics simulation has begun by the time this step is reached. Simulation may finish and update the engine's physics data at any time while ticking this group, or after all group members have ticked.

TG_PostPhysics

Physics simulation is complete and the engine is using the current frame's data by the time this step begins.

n/a

Process latent actions, tick the world timer manager, update cameras, update level streaming volumes and streaming operations.

TG_PostUpdateWork

n/a

n/a

Handle deferred spawning of actors created earlier in the frame. Finish the frame and render.

This is the tick group to use if your actor is intended to interact with physics objects, including physics-based attachments. This way, the actor's movement is complete and can be factored into physics simulation.

Physics simulation data during this tick will be one frame old - i.e. the data that was rendered to the screen last frame.

Since this runs at the same time as physics simulation, it is unknown whether physics data during this tick is from the previous frame or the current frame. Physics simulation can finish at any time during this tick group and will not present any information to indicate this fact.

Because physics simulation data could be current or one frame out of date, this tick group is recommended only for logic that doesn't care about physics data or that can afford to be one frame off. Common cases might be updating inventory screens or minimap displays, where physics data is either entirely irrelevant, or displayed coarsely enough that the potential to have a single frame of lag does not matter.

Results from this frame's physics simulation are complete by the time this tick group runs.

A good use of this group might be for weapon or movement traces, so that all physics objects are known to be in their final positions, as they will be when this frame is rendered. This is especially useful for things like laser sights in shooting games, where the laser beam must appear to come from the player's gun at its final position, and even a single frame of lag will be very noticeable.

This runs after TG_PostPhysics. Historically, its primary function has been to feed last-possible-moment information into particle systems.

TG_PostUpdateWork happens after cameras are updated. If you have any effects that rely on knowing exactly where the camera is pointed, this is a good place to put the actors that control those effects.

This can also be used for any game logic that is intended to run after absolutely everything else in the frame, such as resolving two characters trying to grab each other on the same frame in a fighting game.

Tick Dependency

The AddTickPrerequisiteActor and AddTickPrerequisiteComponent functions, which exist on both actors and components, will set the actor or component on which the function is called to wait to tick until the specified other actor or component has finished ticking. This can be particularly useful for things that happen at roughly the same time in a frame, but where one actor or component sets up data that the other will need. The reason to use this over a tick group is that many actors can be updated in parallel if they're in the same group. Making one group of actors move to an entirely new group might not be needed if those actors are only individually dependent on one or two other actors, rather than needing to wait for the whole group to finish before before ticking.

Examples

Tick Group/Tick Dependency Usage Example

As an example of how to use each of the tick groups listed above, imagine a game where the player controls an animated actor who aims a laser, which places a special targeting reticule actor at the point of impact. A special meter fills up as long as the laser stays pointed at a certain type of target object, and a HUD actor displays this meter on the screen.

The player's animated actor would move and animate in TG_PrePhysics. It needs to animate before physics in order for physics-simulated objects to follow and interact with it correctly.

The HUD can update in any tick group, but TG_DuringPhysics is a good selection for two reasons. First, TG_DuringPhysics is acceptable because it doesn't directly interact with, or use data from, the game's physics simulation. Second, it is a good idea because there is no reason to force physics simulation to wait for the HUD to finish updating, nor is there a reason to force the HUD to wait for physics simulation to finish. Note that the HUD will be one frame behind the game, i.e. pointing at a target object this frame will not be reflected in the meter until next frame.

The reticule actor would update in TG_PostPhysics. This way, the reticule knows it is tracing against the scene as it will be rendered at the end of the frame, so it knows that it will appear exactly on the surface of the object as intended. It also knows that it will adjust the meter value based on the correct locations of target objects.

Finally, in TG_PostUpdateWork, the laser particle effect would be updated with the final locations of both the aiming actor and the reticule.

Tick dependency can be used to eliminate the need for TG_PostUpdateWork. The laser particle can be placed in TG_PostPhysics along with the reticule actor, using tick dependency to ensure that the laser is updated with the reticule's location only after the reticule has had a chance to tick. By setting the laser's tick dependency to the reticule, we can ensure that the laser isn't updated too early, but without waiting for other post-physics ticks that aren't relevant. This can be more efficient than moving the laser into a different tick group.

As an example of a case that would not benefit from tick dependency, the reticule itself does not need to be tick-dependent on the aiming actor, even though it needs the aiming actor to have finished ticking before it can do its own tick. The reason that tick dependency is unnecessary is that the reticule is in post-physics while the aiming actor is in pre-physics. Because they're in different tick groups, we can be assured that they will always run in the order of the groups themselves, since each tick group completes ticking all of its actors and components before the next tick group can begin.

Actor Spawning

In BeginPlay, an actor will register its primary tick function and the tick functions of its components with the engine. An actor's tick function can be set to run in a specific tick group, or disabled entirely, via the PrimaryActorTick member. This is generally done in the constructor to ensure that the data is set correctly before BeginPlay is called. Some commonly-used code follows:

Component Ticking

Just as Actors can be segregated into different ticking groups, so can Components. Previously, an Actor ticked all of its Components during the Actor's tick. This still happens, but Components that need to be in different groups are added to a list that manages when they will be ticked. Components should be assigned ticking groups using the same criteria for assigning an Actor to a tick group. The tick structure for Components is named differently from the one that Actors use, but it works the same way:

Remember that PrimaryActorTick uses the Actor's Tick() function, while PrimaryComponentTick uses the ActorComponent's TickComponent() function.

Advanced Ticking Functionality

The default tick function for an actor or component can be enabled or disabled during the game with the AActor::SetActorTickEnabled and UActorComponent::SetComponentTickEnabled functions, respectively. In addition, an actor or component can have multiple tick functions. This is accomplished by creating a struct that inherits from FTickFunction and overriding the ExecuteTick and DiagnosticMessage functions. The default actor and component tick function structures are good examples of how to build your own, and can be found in EngineBaseTypes.h under the names FActorTickFunction and FComponentTickFunction.

Once you have added your own tick function structure to your actor or component, it can be initialized, usually in the constructor of the owning class. To enable and register the tick function, the most common route is overriding AActor::RegisterActorTickFunctions and adding calls to the tick function structure's SetTickFunctionEnable, followed by RegisterTickFunction with the owning actor's level as an argument. The end result of this process is that any actor or component that you create can tick multiple times, including ticking in different groups and with individual dependencies per tick function. To set a tick dependency manually, call AddPrerequisite on the tick function structure you want to make dependent on another and pass in the tick function structure that you wish to use as your dependency.

Choose your implementation method:

Blueprints

C++

Oftentimes in video games, players are kept engaged by attaining new items or weapons for their character, and sometimes new enemies may even appear for them to defeat.

In your game, you may wish to dynamically add items or enemies to your Level during gameplay, this is called spawning.

In this How-To guide, you will create an Actor class that will be spawned from an Actor spawner at the press of a button. Then, you will create the logic to destroy the spawned Actors at the press of a different button.



CameraActor

CameraComponent

Actors and PlayerControllers

PlayerCameraManager

ViewTarget

Camera Responsibility Chain

Camera Topics

The Camera represents the player's point of view, such as how the player sees the world. For this reason, cameras only have relevance to human-controlled players. The PlayerController specifies a camera class and instantiates a Camera Actor (ACameraActor) which is used to calculate the position and orientation the player views the world from.

For basic examples on how to work with Cameras, refer to Using Cameras. For an example of how to layer animations onto cameras, refer to the CameraAnim feature documentation.

CameraActor

All of the camera's behavior and properties are set up in the CameraComponent. The CameraActor class primarily acts as a wrapper for the CameraComponent, so that the camera can be placed directly in the level rather than within another class. When using a CameraComponent in the Editor, You can navigate to Details > Camera Settings to set whether the camera is in Perspective or Orthographic mode.



The vertical field of view (FOV) can be set for perspective mode, and the width in world units can be set for orthographic mode. For both modes, the aspect ratio can be designated and preset aspect ratios for common devices and display types are provided.

You can add Post process effects to the camera, and it is possible to scale the strength of the post process effects.

Two components are added to the CameraComponent to assist with visual placement in the Editor, although they will not be visible during gameplay. A FrustumComponent shows where the camera field of view is located. This does not show by default, but can be turned on by selecting Show > Advanced > Camera Frustums in the Viewport.



CameraComponent

A CameraComponent represents a camera viewpoint and settings, such as Projection Type, Field Of View, and Post-Process Overrides. If the ViewTarget is a CameraActor or an Actor that contains a CameraComponent and has bFindCameraComponentWhenViewTarget set to true. A related property that can be set for any Pawn is bTakeCameraControlWhenPossessed, where the Pawn will automatically become the ViewTarget upon possession by the PlayerController.

Actors and PlayerControllers

PlayerControllers and



PlayerCameraManager

The PlayerCameraManager is responsible for managing the camera for a particular player. It defines the final view properties used by other systems like the Renderer. The PlayerCameraManager can function as a "virtual eyeball" to see the world. It can compute the final camera properties directly, or it can blend between other objects or Actors that influence the camera (blending from one CameraActor to another.)

The PlayerCameraManager's primary external responsibility is to reliably respond to various Get() functions, such as GetCameraViewPoint. By default, a PlayerCameraManager mantains a view target, which is the primary actor the camera is associated with. It can apply various post effects to the final view state, such as camer animations, post-process effects or special effects such as dirt on the camera lens.

If you need to inherit from the PlayerCameraManager, and you are creating a parent class Blueprint instead of C++, then the PlayerCameraManager contains the BlueprintUpdateCamera function to provide your own custom camera implementations.

When using this function, return true to use the returned values, or return false to ignore them.



The UpdateViewTarget function in PlayerCameraManager queries the ViewTarget and returns that ViewTarget's Point Of View. This function is what calls the BlueprintUpdateCamera function if you have subclassed APlayerCameraManager and are not looking through a CameraComponent.

ViewTarget

The ViewTarget struct, defined in PlayerCameraManager, is responsible for providing the PlayerCameraManager with an ideal Point of View (POV). ViewTarget contains information on the target Actor, the Controller of the target Actor (for non-locally controlled Pawns), and the PlayerState, which is used to follow the same player through Pawn transitions and other changes while spectating.

The camera information passed to PlayerCameraManager through the POV property is in the form of a FMinimalViewInfo struct. This struct contains the basic camera information from a CameraComponent, including the Location, Rotation, Projection Mode (Perspective or Orthographic), FOV, Orthographic Width, Aspect Ratio, and Post Process Effects. Providing the PlayerCameraManager with access to these values allows the PlayerCameraManager to blend between two camera modes during its camera management.

Camera Responsibility Chain

Game-specific camera behavior can be provided at any point along the camera "responsibility chain", which flows from top to bottom through the following classes before passing to ALocalPlayer and ending with Rendering, Scene View (FSceneView), and other related systems.

Camera Topics



An overview of camera animation



A How To Guide for Finding Actors in your Scenes in Unreal Engine.

Creating and Editing CameraAnims

Playing a CameraAnim

Play Spaces

Conceptually, a CameraAnim is simply an animation that can be layered onto the in-game camera. You can animate the camera position and rotation, FOV, and post process settings. A CameraAnim's position, rotation, and FOV changes are applied additively to the game camera. These keyframes are treated as "relative to initial", which means that only the delta from time 0.0 in the animation will be applied.

The CameraAnim's postprocess settings are applied in a blended/layered fashion, like other systems that can affect the scene's postprocessing. You can select which settings you would like to override in the temporary camera's properties and animate the settings via appropriate Matinee tracks. What you see in the preview window should closely match what you see when the animation is played. The temporary camera also has a PostProcessBlendWeight you can set or animate to control how strongly your settings affect the scene.

Creating and Editing CameraAnims

There are a few ways to create a CameraAnim. The easiest is to create a blank one as you would any other asset via the Content Browser. You can also convert a camera track in another Matinee to a CameraAnim by choosing "Export to CameraAnim" in the right-click menu on the camera interp group. Since you can import camera keyframes into Matinee from tools like Maya, this provides a pipeline to import CameraAnims from external sources.

To edit a CameraAnim, simply double-click the asset in the Content Browser like you would any other asset. The CameraAnim editor is a slightly customized version of Matinee. When you edit a CameraAnim, a temporary camera is placed in the world that you can manipulate to create keys and use to preview your animation.

Playing a CameraAnim

The PlayerCameraManager contains functions that allow you to control the application of CameraAnims to the game camera from either C++ code or Blueprint script. When you play a CameraAnim, a CameraAnimInst is created which contains the playback information for an active instance of the animation. You can use this object to stop the animation manually or modify its playback parameters.

Multiple CameraAnimInsts (up to 8 currently) can be active at once, all blending and contributing to the final camera settings.

Play Spaces

A CameraAnim has the ability to play in any arbitrary space. The most common usage is for it to play in camera space. For example, if you make an animation that shakes left and right (Y axis) and play it in game, it will still appear to shake the camera left and right no matter which way the camera is pointing.

A less common but still useful case is playing a CameraAnim in world space. This can be useful for simulating something like a ship rocking side to side, where you want the motion of the camera to roll when looking forward, but pitch when looking off the side of the ship.

Finally, you have the ability to specify any arbitrary space. Using the boat example, you might do this if the boat you are walking on can move around and change the world-space axis of the rocking motion. Another use case is for directional camera "hits" based on shots or explosions. Imagine creating a single animation that pitches the camera quickly upward. If an explosion goes off near you, you could then define a transform using the direction vector to the center of the blast and play the CameraAnim in that space, resulting in your camera always rotating away from the blast.

Creating and Placing a Camera Actor

Creating And Placing a Camera Actor

Camera Actor Details Panel Overview

Implementation Guides

Choose your implementation method:

Blueprints

C++

This Tutorial series covers working with and placing Cameras in Unreal Engine. A Camera can be used by itself and placed directly into a level or it can be a part of a Blueprint (for instance, to provide a perspective for the player when flying a plane, driving a car, or controlling a character).

Creating and Placing a Camera Actor

In the Editor, navigate to Window > Place Actors > All Classes, then place a Camera by dragging a Camera Actor into your level.



You can use the Search Bar to find the Camera Actor directly, or You can right-click in the Level Viewport and use the context menu by selecting Place Actor then selecting the Camera Actor.



When you select your Camera in the Level, in the Viewport, a picture-in-picture window appears, representing the viewing angle of the Camera. The upper-middle portion of the picture-in-picture window displays the Camera name. In its lower-left corner, there is a pin icon, which provides the option to "pin" the window (keep it on screen when clicking off the Camera) is represented by a pin icon in the lower left corner of the window.



Select a Camera to populate the Details panel with settings that pertain to the Camera.



This Tutorial series covers working with and placing Cameras (ACameraActor) with C++ in Unreal Engine. A Camera can be used by itself and placed directly into a Level or it can be a part of a Blueprint (for instance, to provide a perspective for the player when flying a plane, driving a car, or controlling a character).

Creating And Placing a Camera Actor

Create a Camera with the C++ Class Wizard. Launch the wizard, enable the box to Show All Classes, and, in the Search bar, type CameraActor to select and create your new Camera Actor class.



In the Sources panel, navigate back to your C++ classes folder and create a Blueprint class of your Camera Actor.



When you select your Camera in the Level, in the Viewport, a picture-in-picture window appears, representing the viewing angle of the Camera. The upper-middle portion of the picture-in-picture window displays the Camera name. In its lower-left corner, there is a pin icon, which provides the option to "pin" the window(keep it on screen when clicking off the Camera) is represented by a pin icon in the lower-left corner of the window.



Select a Camera to populate the Details panel with settings that pertain to the Camera.



Camera Actor Details Panel Overview

The following table is an overview of each section in the Details panel for a Camera Actor.

Property

Description

Transform

This category represents the location of the Camera in the world.

Camera Settings

This category you to modify the type of projection used by the Camera, field of view, aspect ratio, and post process blending.

Auto Player Activation

Specifies which Player Controller, if any, should automatically use this Camera when the controller is active.

Film

In this category, you can apply film effects such as Tint, Saturation, or Contrast. See also Film.

Scene Color

Used to apply effects to the Camera. See also Scene Color.

Bloom

Simulates the effects the eye perceives when viewing bright objects. See also Bloom.

Light Propagation Volume

Used to achieve Global Illumination (GI) in real-time. See also Light Propogation Volumes.

Ambient Cubemap

Lights the scene from a provided image. See also Ambient Cubemap.

Auto Exposure

This simulates the human eye adjusting to bright/dark areas. See also Auto Exposure.

Lens Flares

Simulates the scattering of light when viewing bright objects through imperfections found in camera lenses. See also Lens Flares.

Ambient Occlusion

Approximates the attenuation of light due to occlusion. See also Ambient Occlusion.

Global Illumination

Affects the indirect lighting contribution coming from Lightmass in order to alter a scene's brightness, color, or tint. See also Global Illumination.

Depth Of Field

Applies a blur effect to a scene based on distance in front or behind a focal point. See also Depth Of Field.

Motion Blur

Generates a Motion Blur effect that blurs objects based on its motion. See also Motion Blur.

Misc

Applies Blendables (screen overlays), sets Anti-Aliasing methods or Screen Percentage options for the Camera. See also Blendables, Screen Percentage, or AA Method.

Screen Space Reflections

Alters the appearance of objects on the surface of Materials. Enabled by default. See also Screen Space Reflection.

Activation

Determines whether or not the Camera is automatically enabled.

Tags

Provides you with Tags to place on the Actor.

Actor

Displays information pertaining to the Camera Actor itself.

Blueprint

Allows you to turn the Actor into a Blueprint or add Events to the Level Blueprint for the Actor.

For information on using Cameras for cinematic purposes, refer to Cinematics and Sequencer overview page. Additionally, the In-Camera VFX Production Test provides an excellent resource for a sample cutscene and how it was constructed.

Now that you have an understanding of how to place a Camera Actor in your level, the examples below provide some ways in which you can use the Camera, including how to use a Camera as a viewpoint for a player, how to use a Camera Component as part of an Actor class, how to use a Spring Arm Component with a Camera Component (typically used for creating Third Person perspectives), and how to switch between Cameras during gameplay.

Implementation Guides



How to add a Camera Component to a Character class and use it as a camera for any Actor in a level.

How to add a Camera Component to a Character class and use it as a camera for any Actor in a level.



A how-to guide for using a static camera to blend between player viewpoints.

A how-to guide for using a static camera to blend between player viewpoints.

Using Spring Arm Components

Camera

Blueprints Visual Scripting

End Result

Next Steps

In this tutorial you will be adding a Camera Component to a Character class. Cameras provide a perspective through which to view a level and can be attached to any Actor in the level including playable characters and non-playable Actors.

Choose your implementation method:

Blueprints

C++

Creating a Character Blueprint

Begin by creating a New > Games > Blank > Blueprint project named CameraComponents.



From the Content Browser click the Add/Import button to create a new Blueprint Character class named BP_CameraCharacter.



Double-click the BP_CameraCharacter from the Content Browser to open its Class Defaults.



Select the Mesh Skeletal Mesh Component, then from the Components tab, click Add Component, select Arrow from the dropdown menu, and rename it to CameraRShoulderLocation.



An Arrow Component is a Scene Component that renders a simple arrow with lines to indicate the direction it is facing. For more information, refer to the documentation on



Select the CameraRShoulderLocation Arrow Component, from the Details panel and navigate to the Transform category to set its Location to (-30,0,150) and Rotation to (0,0,90).



Select the Mesh Skeletal Mesh Component, then from the Components tab click Add Component. Select Arrow from the dropdown menu and rename it to CameraOriginLocation.



Select the CameraOriginLocation Arrow Component from the Components tab, then navigate to the Transform category in the Details panel and set its Location to (0, -120, 150) and Rotation to (0,0,90).



CameraOriginLocation and CameraRShoulderLocation are attached to the Skeletal Mesh Component to provide a visual representation of where the Camera Component will switch its viewpoint locations.

In the Components tab, select the Mesh Component and navigate to the Details panel. From the Mesh category, select Skeletal Mesh and from the dropdown menu search and select TutorialTPP.



If you do not see any options listed in the dropdown menu, click View Options, and check the box for Show Engine Content.



From the Details panel, navigate to the Transform category and set the Mesh's Location to (0,0,-90) and the Rotation to (0,0,-90).



Next, in the Components tab, click the Add Component button , select Camera to add a Camera Component, and rename the Component to CameraComp.



Navigate to the Details panel and set the camera's Location values to (0, -120, 150).



Compile and save.

Creating the Character Class

Begin by creating a New > Games > Blank > C++ project named CameraComponents.



From the C++ Class Wizard, create a new Character class named CameraCharacter, then navigate to the CameraCharactor.h file and declare the following class definitions:

Navigate to the CameraCharactor.cpp file and add the following class libraries:

In the ACameraCharactor::ACameraCharacter constructor method declare the following in order to to instantiate and attach the Arrow and Camera Components to the character's skeletal mesh.

[UProperty specifiers provide the capability of editing your class components and properties in Blueprint.

Compile the code.

From the Content Browser, navigate to the C++ Classes folder. Right-click the CameraCharacter class, select Create Blueprint class based on CameraCharacter from the dropdown menu, and name the Blueprint BP_CameraCharacter.



Double click the BP_CameraCharacter to open its Class Defaults.



In the Components tab, select the Mesh Component and navigate to the Details panel. From the Mesh category, select Skeletal Mesh and from the dropdown menu search and select TutorialTPP.



If you do not see any options listed in the dropdown menu, click View Options, and check the box for Show Engine Content.



From the Details panel, navigate to the Transform category and set the Mesh's Location to (0,0,-90) and the Rotation to (0,0,-90).



Select the CameraRShoulderLocation Arrow Component, from the Details panel and navigate to the Transform category to set its Location to (-30,0,150) and Rotation to (0,0,90).



Select the CameraOriginLocation Arrow Component from the Components tab, then navigate to the Transform category in the Details panel and set its Location to (0, -120, 150) and Rotation to (0,0,90).



CameraOriginLocation and CameraRShoulderLocation are attached to the Skeletal Mesh Component to provide a visual representation of where the Camera Component will switch its viewpoint locations.

Select CameraComp from the Components tab, then navigate to the Transform category in the Details panel and set its Location to (0, -120, 150) and Rotation to (0,0,90)



Compile and Save.

The Components should appear as they in the viewport below.



Work-In-Progress Blueprint



In this example, the camera is attached to the character's Skeletal Mesh Component to provide a third person perspective, however a Camera Component can be added to any Blueprint Actor class for any chosen camera perspective.

Work In-Progress Code

Creating and Binding Input Key Events

With the Character Blueprint class created, you need to set up some scripted logic in order to transition the Camera Component's relative location between the two different Arrow Component locations.

From the BP_CameraCharacter's Class Defaults, click the Event Graph tab and right-click in the graph. From the dropdown menu select Right Mouse Button to add an input mouse event.



The Event Graph is where the scripted logic to move the camera will occur.

Navigate to the My Blueprint panel, then from the variables category, Ctrl-click and hold to drag a copy of the CameraComp variable onto the Event Graph.



Creating a copy of the CameraComp variable provides the ability to set properties or affect the Camera Component through its class methods.

Navigate back to the My Blueprint tab, then from the Variables category Ctrl-click and drag the CameraOriginLocation and CameraRShoulderLocation Arrow Components into the Event Graph.



In the Event Graph, click and drag off the CameraComp output pin, then from the dropdown menu search and select SetRelativeLocation.



The SetRelativeLocation function provides the ability to move the Camera Component to a chosen location.

Click and drag off the CameraRShoulderLocation node output pin, then search and select GetRelativeLocation.



Connect the output pin from the Relative Location node into the New Location node, then connect the Pressed execution pin from the Right Mouse Button event node into the input execution pin of the Set Relative Location node.



When the Right Mouse Button is pressed, the relative location of the camera is set to the location of the Arrow Component CameraRShoulderLocation.

Click and drag off the Camera Comp pin and from the dropdown menu select SetRelativeLocation.



Click and drag off the CameraOriginLocation node output pin and from the dropdown menu select Get Relative Location.



Connect the CameraOriginLocation's Relative Location node output pin into the New Location pin, then from the Right Mouse Button event node connect the Released execution pin to the input execution pin of the SetRelativeLocation node.



Compile and Save.

The Event Graph should now look similar to the image below:



Creating and Binding Input Key Event Functions

With the Character Blueprint class created, you need to set up some scripted logic in order to transition the Camera Component's relative location between the two different Arrow Component locations.

From the Level Editor's toolbar, navigate to Edit > Project Settings and open the Input page. Then from the Bindings category, click the + icon next to Action Mappings to create a new input mapping.



Name the action mapping SwitchCamera and select the Right Mouse Button key value from the dropdown menu.



Navigate to the CameraCharacter.h file and declare the following class definitions.

In the CameraCharacter.cpp file, implement the following class methods.

Next navigate to the ACameraCharacter::SetupPlayerInputComponent method, and implement the following code.

For additional documentation on Player Controllers and possessing Pawn Actors refer to Pawn.

Compile the code.

Finished Blueprint



Finished Code

Setting Up the Game Mode

With the character created and set up, you will need to modify the Game Mode in order to spawn the character when Play (PIE) is clicked.

From the Content Browser, click the Add/Import button to create a new Game Mode Base Blueprint class named BP_CameraCompGameMode.



Double-click the BP_CameraCompGameMode to open the Class Defaults. From the Details panel, navigate to the Classes category, and select Bp_CameraCharacter from the Default Pawn Class dropdown menu.



For additional documentation on Player Controllers and possessing Pawn Actors refer to Possessing Pawns.

Compile and save.

From the Unreal Engine toolbar, select Edit > Project Settings and navigate to the Maps & Modes settings. From the Default Modes category select the newly-created BP_CameraCompGameMode class.



From the Level Editor click the Play (PIE) button to start previewing these changes.



Setting Up the Game Mode

With the character created and set up, you will need to modify the Game Mode in order to spawn the character when Play (PIE) is clicked.

Begin by navigating to the C++ classes folder. Right click the CameraComponentsGameModeBase class, select Create Blueprint Class based CameraComponentsGameModeBase from the dropdown menu, and name the Blueprint BP_CameraCompGameMode.



From the Details panel, navigate to the Classes category and select BP_CameraCharacter from the Default Pawn Class dropdown menu.



The Default pawn class can also be set from theGameModeBase DefaultPawnClassDefault Pawn variable in the code.

Compile and save.

From the Unreal Engine toolbar, select Edit > Project Settings and navigate to the Maps & Modes settings. From the Default Modes category select the newly-created BP_CameraCompGameMode class.



From the Level Editor click the Play (PIE) button to start previewing these changes.



End Result



When you select Play (PIE), you can now transition between the two camera perspectives by clicking and releasing the right mouse button.

Next Steps

Now that you have worked with Camera Components you may want to move on to the Spring Arm Component tutorial. This tutorial will demonstrate how to prevent a camera from being obstructed when moving into tight spaces or when an object blocks the camera's view of the player.

Camera

Blueprints Visual Scripting

Creating The Static Camera Actor

Level Setup

Camera Perspective Setup

Creating the Overlap Trigger Actor

End Result

In this How-to tutorial you will create a static (or fixed) camera angle that is used for the player's perspective during gameplay in a third person example map, and then you will create a trigger volume which will transition your viewpoint to the new static camera once your character overlaps the volume. Upon completing this tutorial, you can take the process used here and apply it to your own game to set up a fixed perspective for a player.

Creating The Static Camera Actor

Choose your implementation method:

Blueprints

C++

Begin by creating a New > Games > Third Person > Blueprint project named StaticCameras.

Click Add/Import > Blueprints > Blueprint Class, the Pick Parent Class menu will appear. Click the arrow to expand all classes, then search for and select CameraActor to create a new Blueprint CameraActor class named BP_ExampleCameraActor.



From the Content Browser panel, select and drag the BP_ExampleCameraActor into the Level.



Begin by creating a New > Games > Third Person > C++ project named StaticCameras.

Launch the C++ Class Wizard, enable the checkbox for Show All Classes, then type CameraActor within the search field to select and create your new Camera Actor class named ExampleCameraActor.



From the C++ Class panel, right click on your ExampleCamera and from the dropdown C++ Class actions menu select Create a Blueprint class based on ExampleCameraActor. Then drag an instance of BP_ExampleCameraActor into the level.

[



Click image to expand.



Level Setup

In order to demonstrate the transition of perspectives between the player's camera and the static camera Actor, you will need to set up the scene. You can accomplish this by modifying some of the static mesh geometry from the third person template level.

Begin by navigating to the world outliner panel, and shift select the Floor and the four Wall Static Mesh Actors from the ArenaGeometry > Arena folder.



In the example image above, the four Wall Static Mesh Actors are listed as Wall6, Wall7, Wall8, and Wall9.

Alt-click and drag the Transform gizmo to create a duplicate floor and wall setup.

This will result in the creation of a second Floor, and four additional Wall Static Mesh Actors.



In the example image above, the duplicated floor is labeled Floor2, and the duplicated walls are named Wall10, Wall11, Wall12, and Wall13.

Move the newly duplicated static meshes to resemble the layout below, a new room duplicating the first but without any contents.





Click image to expand.



From the world outliner, select the two walls that connect the two rooms, and set their X Scale values to 14.

In the example image above, these two walls are labeled Wall9 and Wall12.



Select both the connecting walls, then move them using the Transform gizmo so that they form a partition between rooms with a gap as shown in the gif below.

In the example image above, these two walls are labeled Wall9 and Wall10

Your completed level setup should look similar to the image below, with a second room connected to the first by an opening in the wall.





Click image to expand.



Camera Perspective Setup

Now that you have completed the level setup, you can place the BP_ExampleCameraActor in the level to get a better idea of the view the player will have once they overlap the trigger volume. You can take a First Person perspective from the Camera's Point of View by locking the Viewport to the Camera Actor and entering Pilot mode.

With the Camera selected in the level, right-click on it, then from the context menu select Pilot CameraActor.



You can now move around the Viewport using the WASD keys while holding the Left or Right Mouse Button down. While you fly around the level, the Camera's position will move along with your movement allowing you to get an idea of the perspective the camera will take during gameplay.

To unlock the Camera, click the Unlock button.



The camera will remain where it was positioned when you unlocked it. The icon next to the Unlock button allows you to toggle between showing the in-game camera view or the level editor view.

Pilot the Camera into a position looking down on the second room similar to the gif below.

Your completed camera scene setup should look similar to the image below, with a static camera looking down on the new room along with the original camera following the third-person actor.





Click image to expand.



Creating the Overlap Trigger Actor

In this example, the trigger Actor functions as the transition manager between the player's camera view point and the static camera view point, once the player overlaps its box component volume bounds, a transitional blend will occur between the perspectives.

Begin by clicking Add/Import > Blueprints > Blueprint Class, and create a new Blueprint Actor class named BP_BlendTriggerVolume.

Double click the BP_BlendTriggerVolume to open its class defaults. From the Components tab, click the Add Component button and select Box Collision to add a new Box Component named OverlapVolume.



From the My Blueprint tab, navigate to the variables category and click the Add (+) button. Select your new variable and, from the Details panel, change its Variable type to a float and name your variable CameraBlendTime.



Compile and save your Blueprint.



Re-select your CameraBlendTime variable and set its float value to 1.0f.



Creating the On Component Begin Overlap Event

From the Components tab, select the OverlapVolume, navigate to the Details panel, scroll down to the Events category and click the Add (+) button next to the On Component Begin Overlap event.



Click the On Component Begin Overlap(OverlapVolume) node and drag off the execution pin onto the event graph, an Executable actions drop down menu will appear. Search for and select Cast To ThirdPersonCharacter.



From the On Component Begin Overlap node, click and drag off of the Other Actor pin and input it into the Object pin of the Cast To Third PersonCharacter node.



From the Cast To ThirdPersonCharacter node, select and drag off the As Third Person Character reference pin and from the actions drop down menu, search for and select Is Valid.



Select and drag from the Is Valid node's boolean return value. From the actions menu, search for and select a Branch node, then connect the execution pin from the Cast to ThirdPersonCharacter node to the Branch node.



From the Branch node, click and drag off the True pin and, from the actions menu, search and select Cast to PlayerController.



From the Cast To ThirdPerson Character node, click and drag off the As Third Person Character pin and, from the actions menu, search for and select Get Controller.



From the Get Controller Node, click and drag off of the Return Value and connect it to the Object pin of your Cast To PlayerController node.



From the CastToPlayerController node, drag off the As Player Controller pin, and repeat the Is Valid and Branch check described in steps 4 and 5.



Select and drag off the True pin of the Branch node onto the event graph and, from the actions menu, search for and select Get Actor Of Class.



From the Actor Class pin's Select Class drop-down menu, search for and select your BP_ExampleCameraActor class.



Navigate to your Cast To PlayerController node, click and drag off the As Player Controller pin and, from the actions menu, search for and select Set View Target With Blend.



From the Get Actor of Class node, click and drag the return value pin and plug it into the New View Target input pin of the Set View Target node, then connect the execution pin.



Navigate to the My Blueprint tab and, from the Variables categories, click and drag the CameraBlendTime float variable onto the event graph. Then, from the drop-down menu select Get CameraBlendTime to get a reference to your variable.



Connect your Camera Blend Time variable pin into the Blend Time pin from the Set View Target node.



Your VolumeTrigger On Component Begin Overlap logic should look as shown in the image below.





Click image to expand.



Creating the On Component End Overlap Event

The On Component End Overlap event will transition your view back to the Player Character's camera when they exit the OverlapVolume.

Navigate to the Components tab and select the Box component. Then from the Details panel, scroll down to the Events category and click the Add (+) button next to the On Component End Overlap event.



Duplicate the previous logic that you created for your On Component Begin Overlap Event, then delete the Get Actor Of Class node.



From the Cast to ThirdPersonCharacter node, drag off from the As ThirdPersonCharacter output pin.



Connect the pin to the Set View Target with Blend node's New View Target input pin.



This logic will transition the camera back to the Third Person character view.





Click image to expand.



Finished Blueprint

BP_BlendTriggerVolume





Click image to expand.



Setting up the Overlap Trigger Actor

Now that you have created your overlap Actor, you will need to place it into the Level and set up its bounds.

From the Content Browser, drag an instance of your BP_BlendTriggerVolume into the Level.



Move the BP_BlendTriggerVolume into the room with your BP_ExampleCameraActor and, from the Details panel, select the box component. Navigate to the Shape category and modify the Box Extent X, Y, and Z values so the volume will fit your room.

From the Main Editor View, click the Play button to play in the Editor.

Using the C++ Class Wizard, create a new Actor class named BlendTriggerVolume.



Navigate to your BlendTriggerVolume.h file, and declare the following code in your class definition.

Next, navigate to your BlendTriggerVolume.cpp file to set up your constructor and box component overlap methods. Declare the following include class libraries.

In the constructor ABlendTriggerVolume::ABlendTriggerVolume, declare the following code.

Next, implement your NotifyActorBeginOverlap and NotifyActorEndOverlap class methods:

Compile your code.

Finished Code

BlendTriggerVolume.h

BlendTriggerVolume.cpp

Setting up the Overlap Trigger Actor

Now that you have created your overlap Actor, you will need to place it into the level and set up its bounds.

Begin by navigating to your C++ Classes folder, right-click on your BlendTriggerVolume class, select Create Blueprint Class based on BlendTriggerVolume, then name your Blueprint Actor BP_BlendTriggerVolume.



From the class defaults, navigate to Camera To Find in the Details panel, open the drop down menu, then select BP_ExampleCameraActor.



Optionally, you can change the default blend time for this Blueprint without having to go back into the source code, or affecting other Blueprints with the same inherited parent class.



Compile and Save.



From the Content Browser, drag an instance of BP_BlendTriggerVolume into the level.

[ ]



Click image to expand.



Move the BP_BlendTriggerVolume into the room with your BP_ExampleCameraActor, and from the Details panel select the box component. Navigate to the Shape category and modify the Box Extent X, Y, and Z values so the volume will fit your room.

[ ]



Click image to expand.



From the Main Editor View, click the Play button to play in the Editor.

End Result

When the game starts, the player controls their character's movement using WASD. Upon overlapping the BP_BlendTriggerVolume the camera view is assigned to the Camera Actor that you have created and placed in your level, and the view will switch to an overhead shot of the player-controlled character.

You may have noticed that the view is Widescreen; you can disable this by un-checking the Constrain Aspect Ratio option inside the Details panel for the Camera Actor.



Actor Components

Registering Components

Unregistering Components

Updating

Render State

Physics State

Visualization Components

Scene Components

Attachment

Primitive Components

Scene Proxy

Components are a special type of Object that Actors can attach to themselves as sub-objects. Components are useful for sharing common behaviors, such as the ability to display a visual representation, play sounds. They can also represent project-specific concepts, such as the way a vehicle interprets input and changes its own velocity and orientation. For example, a project with user-controllable cars, aircraft, and boats could implement the differences in vehicle control and movement by changing which Component a vehicle Actor uses.

Actor Components

UActorComponent is the base class for all Components. Since Components are the only way to render meshes and images, implement collision, and play audio, everything the player sees or interacts with in the world when playing the game is ultimately the work of some type of Component.

There are a few major classes to understand when creating your own Components: Actor Components, Scene Components, and Primitive Components.

Actor Components (class UActorComponent) are most useful for abstract behaviors such as movement, inventory or attribute management, and other non-physical concepts. Actor Components do not have a transform, meaning they do not have any physical location or rotation in the world.

Scene Components (class USceneComponent, a child of UActorComponent) support location-based behaviors that do not require a geometric representation. This includes spring arms, cameras, physical forces and constraints (but not physical objects), and even audio.

Primitive Components (class UPrimitiveComponent, a child of USceneComponent) are Scene Components with geometric representation, which is generally used to render visual elements or to collide or overlap with physical objects. This includes Static or skeletal meshes, sprites or billboards, and particle systems as well as box, capsule, and sphere collision volumes.

Registering Components

In order for Actor Components to update each frame and affect the scene, the Engine must register them. This happens automatically for Components created as sub-objects of an Actor during that Actor's spawning process. However, manual registration is available for Components created during play. The RegisterComponent function provides this functionality, with the requirement that the Component is associated with an Actor.

Registering a Component during play can impact performance, so you should do so only in cases where it is necessary.

In the process of registering a Component, the Engine associates the Component with the scene, making it available for per-frame updates, as well as running the following UActorComponent functions:

Function

Description

OnRegister

This function can be overridden to add code when registering a Component.

CreateRenderState

Initializes the render state for the Component.

OnCreatePhysicsState

Initializes the physics state for the Component.

Unregistering Components

To remove Actor Components from update, simulation, or rendering processes, you can unregister it with the UnregisterComponent function.

The UActorComponent functions below run when a Component unregisters.

Function

Description

OnUnregister

This function can be overridden to add code when unregistering a Component.

DestroyRenderState

Uninitializes the render state for the Component.

OnDestroyPhysicsState

Uninitializes the physics state of the Component.

Updating

Actor Components have the ability to update each frame in a manner similar to Actors. The TickComponent function enables Components to run code on each frame. For example, USkeletalMeshComponent uses its TickComponent function to update animations and skeletal controllers, while UParticleSystemComponent updates its emitters and handles particle events.

By default, Actor Components do not update. In order to make your Actor Component update each frame, you must enable ticking by setting PrimaryComponentTick.bCanEverTick to true in its constructor. After that, either in the constructor or elsewhere, you must call PrimaryComponentTick.SetTickFunctionEnable(true) to turn updates on. You can later deactivate ticking by calling PrimaryComponentTick.SetTickFunctionEnable(false). If you know your Component will never need updates, or if you intend to call your own update function manually (perhaps from an owning Actor class), you can simply leave PrimaryComponentTick.bCanEverTick with its default false and get a slight performance boost.

Render State

In order to render, an Actor Component must create a render state. This render state also informs the Engine when something has changed about the Component that requires its render data to be updated. When such a change occurs, the render state is marked "dirty". If you build your own Components, you can mark render data as dirty with the MarkRenderStateDirty function. At the end of the frame, all dirty Components have their render data updated in the Engine. Scene Components (including Primitive Components) create render states by default, while Actor Components do not.

Physics State

To interact with the Engine's physics simulation system, an Actor Component needs a physics state. Physics states update immediately when changes occur, preventing issues like "frame-behind" artifacts and removing the need for a "dirty" marker. By default, Actor Components and Scene Components do not have physics states, but Primitive Components do. Override the ShouldCreatePhysicsState function to determine whether or not instances of your Component class need physics states.

If your class uses physics, simply returning true is not advised. See the UPrimitiveComponent version of the function to get an idea of some of the situations in which you should not create a physics state, such as during the Component's destruction. You can also return Super::ShouldCreatePhysicsState in cases where you would normally return true.

Visualization Components

Some Actors and Components have no visual representation, making them difficult to select, or have important properties that are not visible. Developers can add extra Components to display information while working in the Editor, but these extra Components are not needed during Play In Editor, or when running a packaged build. To address this, the Editor supports the concept of Visualization Components, which are ordinary Components that exist only when working in the Editor.

To make a Visualization Component, create any regular Component and call SetIsVisualizationComponent on it. Since the Component does not need to exist outside of the Editor, all references to it should be inside of preprocessor checks against WITH_EDITORONLY_DATA or WITH_EDITOR. This will ensure that packaged builds are unaffected by these Components and are guaranteed not to reference them anywhere in code. As an example, the Camera Component uses several other Components to display helpful information in the Editor, including a Draw Frustum Component to show its view frustum. In the header file, the Draw Frustum Component is defined within the class as follows:

Similarly, all references to this this Component will be inside of preprocessor checks against WITH_EDITORONLY_DATA in the source file. This code, inside of a WITH_EDITORONLY_DATA check within OnRegister, checks to see if the Camera Component is attached to a valid Actor, and then adds the Draw Frustum Component code:

DrawFrustum now exists only in the Editor and is considered a Visualization Component, meaning that it won't appear during in-Editor playtesting.

Scene Components

A Scene Component is an Actor Component that exists at a specific physical position in the world. This position is defined by a transform (class FTransform), containing the location, rotation, and scale of the Component. Scene Components have the ability to form trees by attaching to each other, and Actors can designate a single Scene Component as "root", meaning that the Actor's world location, rotation, and scale are drawn from that Component.

Attachment

Only Scene Components (USceneComponent and its child classes) can attach to one another, due to the requirement for transforms to describe the spatial relationship between the child and parent Components. While a Scene Component can have any number of children, it can have only one parent, or can be placed directly in the world. The Scene Component system does not support attachment cycles. The two primary methods are SetupAttachment, which is useful in constructors and when dealing with Components that haven't been registered yet, and AttachToComponent, which attaches one Scene Component to another immediately and is useful during play. This attachment system also enables attaching Actors to each other by attaching the root Component of one Actor to a Component belonging to another.

Primitive Components

Primitive Components (class UPrimitiveComponent) are Scene Components that contain or generate some sort of geometry, generally for rendering or collision purposes. There are several subclasses for the various types of geometry, but the most common by far are the Box Component, Capsule Component, Static Mesh Component, and Skeletal Mesh Component. Box Component and Capsule Component generate invisible geometry for collision detection, while Static Mesh Component and Skeletal Mesh Component contain pre-built geometry that is rendered, and can also be used for collision detection if desired.

Scene Proxy

The Scene Proxy (class FPrimitiveSceneProxy) of a Primitive Component encapsulates scene data that the Engine uses to render the Component in parallel to the game thread. Each type of primitive has its own Scene Proxy child class to hold the specific render data it needs.

See Rendering System Overview for more details on primitives and rendering geometry.

Characters

Skeletal Mesh Animation System

Character Movement Component

Projectile Movement Component

Rotating Movement Component

Movement Components provide a form a movement to the Actor (or Character) that they are a sub-object of.

Character Movement Component

The CharacterMovementComponent allows avatars not using rigid body physics to move by walking, running, jumping, flying, falling, and swimming. It is specific to Characters and cannot be implemented by any other class. It is automatically added when creating Blueprints based on the Character class and not manually added.

Properties that can be set include values for falling and walking friction, speeds for travel through air and water and across land, buoyancy, gravity scale, and the physics forces the Character can exert on Physics objects. The CharacterMovementComponent also includes root motion parameters that come from the animation and are already transformed in world space, ready for use by physics. See Root Motion for more information.

For information on working with Character Movement, see Setting Up Character Movement.

Projectile Movement Component

A ProjectileMovementComponent updates the position of another Component during its tick. Behavior such as bouncing after impacts and homing toward a target are supported by this type of Component. Normally the root Component of the owing Actor is moved, however another Component may be selected (see SetUpdatedComponent). If the Updated Component is simulating physics, only the initial launch parameters (when initial velocity is non-zero) will affect the projectile, and the physics simulation will take over from there.

An example of a Blueprint using a ProjectileMovementComponent is shown below (click for full sized image).



Rotating Movement Component

The RotatingMovementComponent performs continuous rotation of a Component at a specific rotation rate. Rotation can optionally be offset around a pivot point. Important to note, collision testing is not performed during movement.

An example of using a RotatingMovementComponent might be in the form of an airplane's propellers, or a windmill, or even a series of planets revolving around the sun.

Player Controllers

AI Controllers

Pawn

Characters

Controllers are non-physical Actors that can possess a Pawn (or Pawn-derived class like Character) to control its actions. A PlayerController is used by human players to control Pawns, while an AIController implements the artificial intelligence for the Pawns they control. Controllers take control of a Pawn with the Possess function, and give up control of the Pawn with the Unpossess function.

Controllers receive notifications for many of the events occurring for the Pawn they are controlling. This gives the Controller the opportunity to implement the behavior in response to this event, intercepting the event and superseding the Pawn's default behavior. It is possible to make the Controller tick before a given Pawn, which minimizes latency between input processing and Pawn movement.

By default, there is a one-to-one relationship between Controllers and Pawns; meaning, each Controller controls only one Pawn at any given time. This is acceptable for most types of games, but may need to be adjusted as certain types of games - real-time strategy comes to mind - may require the ability to control multiple entities at once.

Player Controllers

Controllers

Pawn

Characters

While the PlayerController relies on the human player to make decisions on what to do, the AIController is more focused on responding to input from the environment and game world. The job of the AIController is to observe the world around it and make decisions and react accordingly without explicit input from a human player.

AI Controllers

Controllers

Pawn

Characters

A PlayerController is the interface between the Pawn and the human player controlling it. The PlayerController essentially represents the human player's will.

One thing to consider when setting up your PlayerController is what functionality should be in the PlayerController, and what should be in your Pawn. It is possible to handle all input in the Pawn, especially for less complex cases. However, if you have more complex needs, like multiple players on one game client, or the ability to change characters dynamically at runtime, it might be better to handle input in the PlayerController. In this case, the PlayerController decides what to do and then issues commands to the Pawn (e.g. "start crouching", "jump").

Also, in some cases, putting input handling or other functionality into the PlayerController is necessary. The PlayerController persists throughout the game, while the Pawn can be transient. For example, in deathmatch style gameplay, you may die and respawn, so you would get a new Pawn but your PlayerController would be the same. In this example, if you kept your score on your Pawn, the score would reset, but if you kept your score on your PlayerController, it would not.

Initial Setup

Adding Cheats

Adding Components

Adding Data Registries

Adding Data Registry Sources

Choose your implementation method:

Blueprints

C++

The Game Features and Modular Gameplay plugins help developers create standalone features for their projects. Building features with these plugins offers several benefits, including keeping your project's codebase clean and readable, and avoiding accidental interactions or dependencies between unrelated features. This is particularly important when developing live products that change their feature sets over time.

Initial Setup

The following steps will put your project into a state where you can add one or more standalone, plugin-based features:

If this is the first feature you are adding to this project, you will need to begin by activating the Game Features and Modular Gameplay plugins. To do this, go to the Edit dropdown menu in the main Unreal Engine 5 (UE5) editor window, and select Plugins. Once the Plugins window opens, find and enable the Game Features and Modular Gameplay plugins. You can find both plugins in the left-side panel's Gameplay category.



After enabling these plugins, the editor will inform you that it needs to restart. Before doing that, click the Add Button.



When clicking Add the New Plugin window will launch. You will need to create a new plugin that will contain the feature you are building. The plugin does not have to be of any specific type. For this example, we have chosen Content Only as our type, and named the plugin MyStandaloneFeature.



Make sure that your plugin is saved under the /Plugins/GameFeatures/ directory within your project.



Restart the editor by clicking the Restart Now button in the Plugins window, or by closing the editor and then reopening it.



Upon restarting, you may see the following text in the Message Log, within the Load Errors category:

If you see this text, click Add entry to PrimaryAssetTypesToScan? to fix the issue. The editor will make the appropriate changes to the DefaultEngine.ini file, and the message will not reappear in the future.

Alternately, you can set up the Primary Asset Type manually, by using the dropdown Edit menu and selecting Project Settings, then navigating to the Asset Manager category under the Game section. Under Primary Asset Types to Scan, add one called GameFeatureData that uses the GameFeatureData base class, and add the directory /Game/Unused to the Directories array. Finally, expand Rules and set Cook Rule to Always Cook

Use the Content Browser to navigate to your plugin's top-level content folder. In this case, its name is MyStandaloneFeature Content. Create a new Data Asset by right-clicking in the Asset Panel, expanding Miscellaneous within the context menu, and selecting Data Asset. From the list of classes, choose GameFeatureData and name the new Asset whatever you named your plugin; in this case, the Asset's name must be MyStandaloneFeature.

Once you have completed these steps, your standalone feature will be set up to load when the engine (or editor) starts. You can now begin developing the feature itself, and adding the Actions that will implement it. There are four types of Actions available:

Action

Description

Add Cheats

Action extend the Cheat Manager, creating new "cheat codes" or extending existing ones. Cheat codes are helpful for debugging, and are automatically removed from shipping builds. The ~ (tilde) key opens the console where you can enter these codes while running your project.

Add Components

Actions take a list of Actor subclasses and add a set of Components to them on an opt-in basis. This is the most common way to use the Game Features and Modular Gameplay plugins, since Components are well-suited to encapsulating a wide range of behaviors.

Add Data Registry

Actions add one or more Data Registries to the project. Data Registries are efficient places to store and retrieve globally-registered data.

Add Data Registry Source

Actions add one or more Data Tables to existing Data Registries

To add an Action, open the Data Asset you just created. Expand the ACTIONS category to reveal an array called Actions. Add an element to that array and set it to the appropriate Action type. You can find further guidance for each Action type in the sections below.



One of each type of Action. You can have as many Actions as you need for any given plugin.

If, after adding Actions, your Game Feature does not function as expected, you may need to restart the editor once. GameFeatureData Assets load during editor startup, meaning that failure to restart after creating a new GameFeatureData Asset will result in that Asset not functioning. You will only need to do this after initially creating the Asset; updating it during later sessions will not require a restart.

Adding Cheats

An Add Cheats Action registers a Cheat Manager Extension with the game. Using this, developers can create their own debug commands (or "cheat codes") as part of a standalone feature, and make these commands available whenever the feature is in effect. Because Cheat Managers and Cheat Manager Extensions are debugging tools, they do not instantiate in Shipping builds.

Adding Components

An Add Components Action goes through the list of paired Actor and Component classes you provide and attempts to add an instance of each Component to each matching Actor. You can specify whether the Components should be added on clients, servers, or both; by default, Components will be added in both cases.

To keep your feature fully encapsulated within the plugin, the Component or Components that you add will come from the plugin itself, while the Actor class will be a built-in Engine class, like Pawn, or a project-specific child of an Engine class, like a typical MyPawn. Ideally, the Component or Components should handle all program logic and data storage related to your feature.

By keeping the required interaction with the project's Actor subclass to the minimum possible, you make it easier to implement your feature in another project.

Do not use the base Actor class for an Add Components Action; this is unsupported, and the system will ignore that part of the Action. Instead, you should identify the most narrow subset of Actor subclasses that require your Component and specify that class. If there are multiple classes that should receive the Component and they do not have a common parent below Actor, you can set up multiple Add Components Actions to cover all appropriate base classes.

To receive Components from Add Components Actions, your Actor must register itself with the Game Framework Component Manager, generally in its Begin Play event. You can do this by getting the global Game Framework Component Manager and calling its Add Receiver function, passing the Actor in as the Receiver parameter. Actors only need one Add Receiver call, regardless of the number of active Game Features. To remove all Components associated with Game Features from the Actor, use the Game Framework Component Manager's Remove Receiver function.



Registering to receive Components in an Actor's Begin Play event.

To receive Components from Add Components Actions, your Actor must register itself with the UGameFrameworkComponentManager singleton instance, and pass itself into the AddReceiver function. This is generally done in BeginPlay. The code should look like this:

Adding Data Registries

The Add Data Registry Action can add an entire Data Registry to your project. Configure the Action with the path to the Data Registry Asset you want to add. For more information about Data Registries, see the Data Registries page.

Adding Data Registry Sources

To add a data source that streams into a Data Registry, use an Add Data Registry Source Action. You must configure the paths to each data source, the name of the Data Registry that will load them, and the relevant priority and usage flags. If the Game Feature is loaded at startup, the appropriate identifiers will populate dropdown lists. For more information, see the Data Registry Sources section of the Data Registries page.

Extension Handler System

Receivers and Extension Handlers

Lyra Example

Initialization State System

Actor Features

Init States

Reporting and Querying States

Registering For State Changes

Lyra Example

The Game Framework Component Manager is a Game Instance Subsystem in the Modular Gameplay plugin that provides functionality designed to be used with Game Feature Plugins. The functions implemented in this subsystem can be used by Game Feature Actions to support extensibility. Game Feature Actions are used by general gameplay code to coordinate communication between different gameplay objects. The manager implements two basic systems, Extension Handlers, and Initialization States.

Extension Handler System

The Extension Handler system allows the modification of game objects when game features are activated. There are two parts to this system: Actors work as Receivers that register to be extended, and Extension Handlers are delegates that are fired in response to events. These events include handling new receivers, removal of existing receivers, and arbitrary events that are called by gameplay code.

Receivers and Extension Handlers

To correctly register as a Receiver, an Actor should call the AddGameFrameworkComponentReceiver function from the PreInitializeComponents method, and the RemoveGameFrameworkComponentReceiver function from the EndPlay method. This ensures that it registers as a receiver as part of normal component initialization and unregisters when the Actor is removed or disabled.

Receivers can call the SendGameFrameworkComponentExtensionEvent function to send an arbitrary event. Unlike the Initialization State System described below, these extension events are not stateful and will only modify handlers that are currently active. To correctly register an Extension Handler, classes like GameFeatureAction_AddComponents can either call AddExtensionHandler to register a manual delegate, or call AddComponentRequest to call a wrapper function which will automatically add the desired component.

In both cases, the handles returned by the add functions need to be stored like an array because the delegates only stay registered as long as there are live shared pointer references to the returned handle struct.

Lyra Example

For an example of how to use this system, you can look at the implementation in the Lyra Sample Game. The ALyraCharacter class is used for all characters in the game and inherits from the AModularCharacter class that handles registering as a receiver. Additionally, you can observe the LyraHUD Actor which calls this function manually to enable UI extensions. Game feature plugins in Lyra like ShooterCore use the engine-defined UGameFeatureAction_AddComponents action to add components to spawned Actors. Lyra uses some game-specific actions like UGameFeatureAction_AddInputBinding to handle some game-specific cases.

For the game-specific UGameFeatureAction_AddInputBinding action, the HandlePawnExtension function is registered as a manual extension handler and responds to several different extension events. Events like NAME_ExtensionRemoved and NAME_ExtensionAdded are called when the extension handler is first added or removed for all relevant Actors. It responds to a game-specific NAME_BindInputsNow event that is emitted by the LyraHeroComponent, when it is time for binding feature-specific input events.

Initialization State System

The Initialization State system (Init State) provides functions for tracking the initialization and general life cycle of different features (usually implemented by components) attached to Actors in the game world. This system is not meant to be a generic gameplay state machine because the states are globally defined for an entire game, and are arranged linearly from creation to full initialization.

Synchronizing the initialization of components on an Actor is a complex process, especially when network replication is involved. This system provides registration and notification functions that make that coordination simpler. The low-level functions are implemented by the Game Framework Component Manager, and there is an optional native GameFrameworkInitStateInterface that can be inherited by components (or other gameplay objects) that implement a specified feature.

Actor Features

An Actor that has been registered with this system will have multiple Actor Features, which are defined as unique Names. These names are defined by the game and can either correspond to native class names or functional features. The subsystem keeps track of the Init State and Implementer object (often a component) for all features registered for an Actor. For objects that implement the GameFrameworkInitStateInterface, the feature name is returned by the GetFeatureName interface function and used for all other operations.

Init States

Init States are implemented as



Reporting and Querying States

All features registered with this system need to report to the Game Framework Component Manager whenever they change the init state because the manager stores this state for later querying. The manager does not enforce restrictions on changing the state and is designed to be flexible.

GameFrameworkInitStateInterface provides the framework for a simple C++ state machine that can be quickly implemented by overriding a few functions:

Function

Override Description

CanChangeInitState

This function should be overridden to return true if the requested state transition is allowed. This is where you would implement checks to see if the required data is available.

HandleChangeInitState

This function should be overridden to perform any object-specific changes that should occur on a specific state transition.

CheckDefaultInitialization

Can be overridden to attempt to follow the default initialization path for the feature. If the ContinueInitStateChain function is called with an array of init states, it will call CanChangeInitState and HandleChangeInitState to get as far as possible in the state chain. This function should be called from places like OnRep functions that may progress initialization.

Additionally the subsystem and interface provide registration and query functions:

Function

Description

RegisterInitStateFeature

Registers with the system but does not set a state, this is useful to call from component OnRegister.

UnregisterInitStateFeature

This should generally be called from EndPlay to unregister from the system and unbind notification delegates.

HasReachedInitState

This can be called to see if the feature has reached either the specified state or a later state in the initialization order.

HaveAllFeaturesReachedInitState

This is called on the manager to see if all features have reached a certain state. This is useful for coordinating extensions because you can set a central feature to wait for all other features to be ready before transitioning to the next state.

Registering For State Changes

The most useful part of this system is the ability to register for init state changes and call delegates after they reach certain states. The register functions like RegisterAndCallForActorInitState call the specified delegate when a feature reaches a certain state, and immediately call the delegate if it has already reached that state.

RegisterAndCallForClassInitState can be called with a class name to listen for any feature anywhere reaching that state, which is useful for listening to global initialization. These functions can be called from either C++ code or Blueprints, and the versions on the interface fill in the feature name for you. The delegate execution logic was designed to handle multiple state transitions happening in a row and all relevant delegates will be called.

For ease of use, BindOnActorInitStateChanged and OnActorInitStateChanged can be used on the interface to quickly listen for changes made to other features on the same Actor. This can then be used to call functions like CheckDefaultInitialization that may advance the init state of the feature.

Lyra Example

For an example of how to use this system, look at the implementation in the 5.1 or later version of Lyra Sample Game. The 5.0 release of Lyra predates the Initialization State system and has multiple race conditions this system was designed to help address. Here are the states used by the Lyra sample, as registered in ULyraGameInstance::Init

Init State

Description

InitState.Spawned

The feature has finished spawning and initial replication, called from BeginPlay.

InitState.DataAvailable

All data needed by the feature has been replicated or loaded, including dependencies on other actors that may also need to be replicated.

InitState.DataInitialized

After all of the data becomes available, it is used to complete other initialization actions like adding gameplay abilities.

InitState.GameplayReady

The object has finished all initialization and is ready to be interacted with in normal gameplay.

The two main components that use this system are the ULyraPawnExtensionComponent which coordinates the overall initialization and the ULyraHeroComponent that handles initialization of player-controlled systems like camera and input.The initialization of both components depends on replicated data from multiple sources, and they call the RegisterInitStateFeature function from the OnRegister method to let the component manager know they exist. Both components later call the CheckDefaultInitialization function from the BeginPlay method after initial replication is done.

The full initialization state machine is needed for these two components because they also depend on data replicated by other Actors like LyraPlayerState that can be slow to download. The list below displays the overall timeline of initialization for a Lyra character:

When a Character is initially spawned on the Client and Server, it attaches and registers all components, including the two init state components and others like the LyraAbilitySystemComponent.

When BeginPlay is called on the Character, it tries to call BeginPlay on all components. On the server this happens right away, but on the client it will not call BeginPlay until all the replicated properties have sent their initial data. This happens at different times for each component depending on how much data they need to replicate.

When BeginPlay is called on either the Hero Component or Lyra Pawn Component, those components call BindOnActorInitStateChanged to listen for init state changes and then call CheckDefaultInitialization to attempt to follow the 4 state initialization chain. At this point both components will reach InitState.Spawned and will try to continue initializing.

When the Hero Component tries to transition to InitState.DataAvailable, it checks to see if the player state and input component are ready. If that data isn't available, the state machine stalls until something calls CheckDefaultInitialization. If the required data is available, it transitions to DataAvailable but cannot transition to DataInitialized yet.

When the Pawn Extension Component calls CheckDefaultInitialization, if possible, it first tells the other components (like Hero Component) to move their initialization state machine forward. Then when trying to move its own state forward to InitState.DataAvailable it checks to see if the PawnData and Controller are fully available. The Pawn Extension Component calls CheckDefaultInitialization from various OnRep functions to try and move the state machine forward after important cross-actor references finish replicating. Another option is to call the initialization functions from a native tick function.

When the Pawn Extension Component tries to move forward to InitState.DataInitialized, it will not do so until all other features (like the Hero Component) have reached DataAvailable. When it actually transitions, this activates the OnActorInitStateChanged function on the Hero Component and anything else listening.

Once that happens, the extension component moves to InitState.DataInitialized, which then causes the Hero Component to also move to DataInitialized. During this transition, gameplay abilities are created and bound to player input.

Both the Hero Component and Pawn Extension Component then transition to InitState.GameplayReady, which activates Blueprint callbacks in classes like W_Nameplate that registered to wait for this state to be reached.

The Lyra character initialization flow is complex, but many networked games require similarly complicated initialization flows. The init state system is designed to make it easier to set up complex systems and avoid race conditions or random delay loops.

Game Modes

Game State

There are two main classes which handle information about the game being played: Game Mode and Game State.

Even the most open-ended game has an underpinning of rules, and these rules make up a Game Mode. On the most basic level, these rules include:

The number of players and spectators present, as well as the maximum number of players and spectators allowed.

How players enter the game, which can include rules for selecting spawn locations and other spawn/respawn behavior.

Whether or not the game can be paused, and how pausing the game is handled.

Transitions between levels, including whether or not the game should start in cinematic mode.

When rule-related events in the game happen and need to be tracked and shared with all players, that information is stored and synced through the Game State. This information includes:

How long the game has been running (including running time before the local player joined).

When each individual player joined the game, and the current state of that player.

The base class of the current Game Mode.

Whether or not the game has begun.

Game Modes

While certain fundamentals, like the number of players required to play, or the method by which those players join the game, are common to many types of games, limitless rule variations are possible depending on the specific game you are developing. Regardless of what those rules are, Game Modes are designed to define and implement them. There are currently two commonly-used base classes for Game Modes.

Engine version 4.14 introduces AGameModeBase, which is the base class for all Game Modes and is a simplified and streamlined version of the classic AGameMode. AGameMode, the Game Mode base class before version 4.14, still exists and functions as it did before, but is now a child of AGameModeBase. AGameMode is more suited to standard game types like multiplayer shooters due to its implementation of the concept of match state. AGameModeBase is the new default game mode included in new code projects due to its simplicity and efficiency.

AGameModeBase

All Game Modes are subclasses of AGameModeBase, which contains considerable base functionality that can be overridden. Some of the common functions include:

Function/Event

Purpose

InitGame

The InitGame event is called before any other scripts (including PreInitializeComponents), and is used by AGameModeBase to initialize parameters and spawn its helper classes.

This is called before any Actor runs`PreInitializeComponents`, including the Game Mode instance itself.



PreLogin

Accepts or rejects a player who is attempting to join the server. Causes the Login function to fail if it sets ErrorMessage to a non-empty string. PreLogin is called before Login, and a significant amount of time may pass before Login is called, especially if the joining player needs to download game content.

PostLogin

Called after a successful login. This is the first place it is safe to call replicated functions on the PlayerController. OnPostLogin can be implemented in Blueprint to add extra logic.

HandleStartingNewPlayer

Called after PostLogin or after seamless travel, this can be overridden in Blueprint to change what happens to a new player. By default, it will create a pawn for the player.

RestartPlayer

This is called to start spawning a player's Pawn. There are also RestartPlayerAtPlayerStart and RestartPlayerAtTransform functions available if you want to dictate where the Pawn will be spawned. OnRestartPlayer can be implemented in Blueprint to add logic after this function is finished.

SpawnDefaultPawnAtTransform

This is what actually spawns the player's Pawn, and can be overridden in Blueprints.

Logout

Called when a player leaves the game or is destroyed. OnLogout can be implemented to do Blueprint logic.

A subclass of the AGameModeBase class may be created for each match format, mission type, or special zone that the game offers. A game may have any number of Game Modes, and thus subclasses of the AGameModeBase class; however, only one Game Mode may be in use at any given time. A Game Mode Actor is instantiated each time a level is initialized for play via the UGameEngine::LoadMap() function.

The Game Mode is not replicated to any remote clients that join in a multiplayer game; it exists only on the server, so local clients can see the stock Game Mode class (or Blueprint) that was used, but cannot access the actual instance and check its variables to see what has changed as the game progresses. If players do need updated information relating to the current Game Mode, that information is easily kept in sync by being stored on an AGameStateBase Actor, one of which will be created along with the Game Mode and then replicated out to all remote clients.

AGameMode

AGameMode is a subclass of AGameModeBase that has some extra functionality to support multiplayer matches and legacy behavior. All newly created projects use AGameModeBase by default, but you can switch to inheriting from AGameMode if you need this extra behavior. If you inherit from AGameMode, you should also inherit your game state from AGameState, which also supports the match state machine.

AGameMode contains a state machine that tracks the state of the match or the general gameplay flow. To query the current state, you can use GetMatchState, or wrappers like HasMatchStarted, IsMatchInProgress, and HasMatchEnded. Here are the possible match states:

EnteringMap is the initial state. Actors are not yet ticking and the world has not been fully initialized. It will transition to the next state when things are fully loaded.

WaitingToStart is the next state, and HandleMatchIsWaitingToStart is called when entering. Actors are ticking, but players have not yet spawned in. It transitions to the next state if ReadyToStartMatch returns true, or if StartMatch is called.

InProgress is the state where the main part of the game will take place. HandleMatchHasStarted is called when entering it, which then calls BeginPlay on all Actors. At this point, normal gameplay is in progress. The match will transition to the next state when ReadyToEndMatch returns true or EndMatch is called.

WaitingPostMatch is the second-to-last state, and HandleMatchHasEnded is called when entering it. Actors are still ticking, but new players cannot join. It transitions to the next state when a map transfer starts.

LeavingMap is the last state in a normal flow, and calls HandleLeavingMap upon entry. The match stays in this state while transferring to a new map, where it will transition back to EnteringMap.

Aborted is the failure state, and can be started by calling AbortMatch. This is set when there is an unrecoverable error.

The match state will almost always be InProgress since this is the state where BeginPlay is called and actors begin ticking. However, individual games can override the behavior of these states to build a multiplayer game with more complicated rules, such as permitting players to fly around the level freely while waiting for other players to join in a multiplayer shooter.

Game Mode Blueprints

It is possible to create Blueprints derived from Game Mode classes, and use these as the default Game Mode for your project or level.

Blueprints derived from Game Modes can set the following defaults:

Default Pawn Class

HUD Class

Player Controllers Class

Spectator Class

Game State Class

Player State Class

In addition, Blueprints of Game Modes are very useful because they enable adjustment of variables without altering code, and can therefore be used to adapt a single Game Mode to multiple different levels without using hard-coded asset references or requiring engineering support and code changes for every tweak.

Setting the Game Mode

There are several methods to set the Game Mode for a level, ordered here from lowest priority to highest priority:

Setting the GlobalDefaultGameMode entry in the /Script/EngineSettings.GameMapsSettings section of the DefaultEngine.ini file will set the default game mode for all maps in the project.

To override the project settings for an individual map, set the GameMode Override in the World Settings tab in the editor.



URLs can be passed to the executable to force the game to load with specific options. Use the game option to set the game mode. See Command-Line Arguments for more information.

Finally, map prefixes (and aliases for the URL method) can be set in the /Script/Engine.WorldSettings/ section of the DefaultEngine.ini file. These prefixes set the default game mode for all maps that have a given prefix.

For an example of setting up a Game Mode, refer to the Setting Up a Game Mode documentation.

Game State

The Game State is responsible for enabling the clients to monitor the state of the game. Conceptually, the Game State should manage information that is meant to be known to all connected clients and is specific to the Game Mode but is not specific to any individual player. It can keep track of game-wide properties such as the list of connected players, team score in Capture The Flag, missions that have been completed in an open world game, and so on.

Game State is not the best place to keep track of player-specific things like how many points one specific player has scored for the team in a Capture The Flag match because that can be handled more cleanly by Player State. In general, the GameState should track properties that change during gameplay and are relevant and visible to everyone. While the Game mode exists only on the server, the Game State exists on the server and is replicated to all clients, keeping all connected machines up to date as the game progresses.

AGameStateBase is the base implementation, and some of its default functionality includes:

Function or Variable

Use

GetServerWorldTimeSeconds

This is the server's version of the UWorld function GetTimeSeconds and will be synchronized on both the client and server, so it is a reliable time to use for replication.

PlayerArray

This is the array of all APlayerState objects, which is useful when doing something to all players in a game.

HasBegunPlay

Returns true if the BeginPlay function has been called on actors in the game.

AGameStateBase is very commonly extended in C++ or Blueprints to contain additional variables and functions that are needed to keep players informed of what's going on in the game. The specific modifications made are generally based on a paired Game Mode for which the Game State is made. The Game Mode itself can also override its default Game State type to be any C++ class or Blueprint derived from AGameStateBase.

Characters

Controllers

Game Mode and Game State

Default Pawn

DefaultPawnMovementComponent

Spectator Pawn



The Pawn class is the base class of all Actors that can be controlled by players or AI. A Pawn is the physical representation of a player or AI entity within the world. This not only means that the Pawn determines what the player or AI entity looks like visually, but also how it interacts with the world in terms of collisions and other physical interactions. This can be confusing in certain circumstances as some types of games may not have a visible player mesh or avatar within the game. Regardless, the Pawn still represents the physical location, rotation, etc. of a player or entity within the game. A Character is a special type of Pawn that has the ability to walk around.

By default, there is a one-to-one relationship between Controllers and Pawns; meaning, each Controller controls only one Pawn at any given time. Also, Pawns spawned during gameplay are not automatically possessed by a Controller.

In Blueprints, the best way to add movement to your Pawn-derived class is with SetActorLocation. With SetActorLocation, you can decide if you want to teleport to the location, or sweep. When sweeping, your Pawn will move along the direction and stop if it hits something.

Default Pawn

While the Pawn class provides only the essentials for creating a physical representation of a player or AI entity in the world, the DefaultPawn subclass comes with some additional Components and functionality.

The DefaultPawn class contains a native DefaultPawnMovementComponent, a spherical CollisionComponent, and a StaticMeshComponent. To control the DefaultPawnMovementComponent, as well as the camera, a Boolean to add default movement bindings is also present in the DefaultPawn class, and is set to true by default.

DefaultPawnMovementComponent

The movement style set for the DefaultPawnMovementComponent is a no-gravity, flying style. In addition to the usual MovementComponent variables, it includes MaxSpeed, Acceleration, and Deceleration float values. These three variables are also accessible in DefaultPawn-derived Blueprints.

Spectator Pawn

The SpectatorPawn class is a subclass of DefaultPawn. Through a GameMode, different classes can be specified as defaults for Pawn and SpectatorPawn, and this class provides a simple framework ideal for spectating functionality. Like DefaultPawn, it has a spherical CollisionComponent, although the StaticMeshComponent is not created due to the implementation of .DoNotCreateDefaultSubobject(Super::MeshComponentName). The movement for the SpectatorPawn class is handled in the SpectatorPawnMovementComponent; the no-gravity flying behavior is the same as in the DefaultPawnMovementComponent, with added code for handling or ignoring time dilation as necessary.

Pawn

Controllers

Game Mode and Game State

Root Motion

Setting Up a Character

Setting Up Character Movement

SkeletalMeshComponent

CapsuleComponent

CharacterMovementComponent

With the addition of a CharacterMovementComponent, a CapsuleComponent, and a SkeletalMeshComponent, the Pawn class is extended into the highly-featured Character class. A Character is designed for a vertically-oriented player representation that can walk, run, jump, fly, and swim through the world. This class also contains implementations of basic networking and input models.

SkeletalMeshComponent

Unlike Pawns, Characters come with a SkeletalMeshComponent to enable advanced animations that use a skeleton. It is possible for other Skeletal Meshes to be added to Character-derived classes, but this is the main Skeletal Mesh associated with the Character. For more on Skeletal Meshes, refer to Skeletal Mesh Actors and Skeletal Mesh Animation System

CapsuleComponent

The CapsuleComponent is used for movement collision. In order to calculate complicated geometries for the CharacterMovementComponent, there is an assumption that the collision component in the Character class is a vertically-oriented capsule. Refer to Collision and Setting Up Collisions With Static Meshes

CharacterMovementComponent

The CharacterMovementComponent allows avatars not using rigid body physics to move by walking, running, jumping, flying, falling, and swimming. It is specific to Characters, and cannot be implemented by any other class. Properties that can be set in the CharacterMovementComponent include values for falling and walking friction, speeds for travel through air and water and across land, buoyancy, gravity scale, and the physics forces the Character can exert on Physics objects. The CharacterMovementComponent also includes root motion parameters that come from the animation and are already transformed in world space, ready for use by physics.

Representing Players, Friends, and Foes in the World

Controlling Pawns With Player Input or AI Logic

Displaying Information to Players

Setting and Tracking the Rules of the Game

Framework Class Relationships

The basic gameplay classes include functionality for representing players, allies, and enemies, as well as for controlling these avatars with player input or AI logic. There are also classes for creating heads-up displays and cameras for players. Finally, gameplay classes such as GameMode, GameState, and PlayerState set the rules of the game, and track how the game and the players are progressing.

These classes all create types of Actors, which can either be placed into your level or spawned when needed.

Representing Players, Friends, and Foes in the World

Class

Description

Pawn

A Pawn is an Actor that can be an "agent" within the world. Pawns can be possessed by a Controller, they are set up to easily accept input, and they can do various and sundry other player-like things. Note that a Pawn is not assumed to be humanoid.

Character

A Gameplay Framework is a humanoid-style Pawn. It comes with a CapsuleComponent for collision and a CharacterMovementComponent by default. It can do basic human-like movement, it can replicate movement smoothly across the network, and it has some animation-related functionality.

Controlling Pawns With Player Input or AI Logic

Class

Description

Controller

Controllers is an Actor that is responsible for directing a Pawn. They typically come in 2 flavors, AIController and PlayerController. A controller can "possess" a Pawn to take control of it.

PlayerController

A Player Controllers is the interface between the Pawn and the human player controlling it. The PlayerController essentially represents the human player's will.

AIController

An AIController is a simulated "will" that can control a Pawn.

Displaying Information to Players

Class

Description

HUD

A HUD is a "heads-up display", or the 2D on-screen display that is common in many games. Think health, ammo, gun reticle, etc. Each PlayerController typically has one of these.

Camera

The PlayerCameraManager is the "eyeball" for a player and manages how it behaves. Each PlayerController typically has one of these as well. For more, see the camera workflow page.

Setting and Tracking the Rules of the Game

Class

Description

GameMode

The concept of a "game" is split into 2 classes. The Game Mode and Game State is the definition of the game, including things like the game rules and win conditions. It only exists on the server. It typically should not have much data that changes during play, and it definitely should not have transient data that clients need to know about.

GameState

The GameState contains the state of the game, which could include things like the list of connected players, the score, where the pieces are in a chess game, or the list of what missions you have completed in an open world game. The GameState exists on the server and all clients and can replicate freely to keep all machines up to date.

PlayerState

A PlayerState is the state of a participant in the game, such as a human player or a bot that is simulating a player. Non-player AI that exists as part of the game would not have a PlayerState. Example data that would be appropriate in a PlayerState include player name, score, in-match level for something like a MOBA, or whether the player is currently carrying the flag in a CTF game. PlayerStates for all players exist on all machines (unlike PlayerControllers) and can replicate freely to keep things in sync.

Framework Class Relationships

This flowchart illustrates how these core gameplay classes relate to each other. A game is made up of a GameMode and GameState. Human players joining the game are associated with PlayerControllers. These PlayerControllers allow players to possess pawns in the game so they can have physical representations in the level. PlayerControllers also give players input controls, a heads-up display, or HUD, and a PlayerCameraManager for handling camera views.



For more on gameplay framework classes, see Gameplay Framework.

Delegates

Timer Management

Setting and Clearing Timers

Pausing and Resuming Timers

Timer Information

Is Timer Active

Timer Rate

Elapsed and Remaining Time

Known Issues

Timers schedule actions to be performed after a delay, or over a period of time. For example, you may want to make the player invulnerable after obtaining a power-up item, then restore vulnerability after 10 seconds. Or you may want to apply damage once per second while the player moves through a room filled with toxic gas. Such actions can be achieved through the use of timers.

Timer Management

Timers are managed in a global Timer Manager (of type FTimerManager). A global Timer Manager exists on the Game Instance Object, as well as on each World. Two main functions are used to set up timers with a Timer Manager: SetTimer, and SetTimerForNextTick, each with several overloads. Each one can be attached to any type of Object or function delegate, and SetTimer can be made to repeat at regular intervals, if desired. See the Timer Manager API page for more detail on these functions.



Timers will be canceled automatically if the Object that they are going to be called on, such as an Actor, is destroyed before the time is up. In this case, the timer handle will become invalid and the function will not be called.



Accessing the Timer Manager can be done through the AActor function called GetWorldTimerManager, which calls up to the GetTimerManager function in UWorld. To access the global Timer Manager, use the UGameInstance function, `GetTimerManager'. This is also the fallback used if a World doesn't have its own Timer Manager for any reason, and can be used for function calls that aren't relevant to, or should not depend on, the existence of any specific World.

Timers can be used with the standard C++ function pointers TFunction Objects or Delegates.

Setting and Clearing Timers

The SetTimer functions of FTimerManager will set a timer to call a function or delegate after a delay, and can be set to repeat that function call indefinitely. These functions will fill out a timer handle (type FTimerHandle), which can be used to pause (and resume) the countdown, query or change the amount of time remaining, or even cancel the timer altogether. It is safe to set timers within a function called by a timer, even including reuse of the timer handle that was used to call the function. One use for this might be to delay initialization of one Actor if it depends on another Actor that hasn't spawned yet but is expected to spawn soon; the dependent Actor's initialization function could set a timer to call itself again after a fixed length of time, such as one second. Alternately, the initialization function could be called by a looping timer that clears itself upon success.

Timers can also be set to run on the next frame, rather than with a timed interval. This is accomplished by calling SetTimerForNextTick, but note that this function does not fill out a timer handle.

To clear a timer, pass the FTimerHandle that was filled out during the SetTimer call into the FTimerManager function called ClearTimer. The timer handle will become invalid at this point, and can be reused to manage a new timer. Calling SetTimer with an existing timer handle will clear the timer referenced by that timer handle and replace it with a new one.

Finally, all timers associated with a specific Object can be cleared by calling ClearAllTimersForObject.

Example:

Calling SetTimer with a rate less than or equal to zero is identical to calling ClearTimer.

Pausing and Resuming Timers

The FTimerManager function PauseTimer uses a timer handle to pause a running timer. This prevents the timer from executing its function call, but the elapsed and remaining times stay the same while paused. UnPauseTimer causes a paused timer to resume running.

Timer Information

In addition to managing timers, timer managers also provide funtions for obtaining information—such as the rate, elapsed time, and remaining time—for a specific timer.

Is Timer Active

The IsTimerActive function of FTimerManager is used to determine if the specified timer is curently active and not paused.

Example:

Timer Rate

FTimerManager has a function called GetTimerRate that gets the current rate (time between activations) of a timer from its timer handle. A timer's rate cannot be changed directly, but SetTimer can be called with its timer handle to clear it and create a new timer, which could be identical except for the rate. GetTimerRate will return a value of -1 if the timer handle is not valid.

Example:

Elapsed and Remaining Time

FTimermanager provides functionality through GetTimerElapsed and GetTimerRemaining, returning the elapsed and remaining time, respectively, for the timer associated with the provided timer handle. As with GetTimerRate, these functions will return -1 if the timer handle is invalid.

Example:

The sum of the elapsed and remaining time for a timer should be equal to the rate of the timer.

Known Issues

The code is not thread safe at the moment, and will cause an assert if accessed outside of the game thread.

HUD

Canvas

Slate

The way in which the game communicates and interacts with the player is extremely important. User Interfaces (UIs) and Heads-up Displays (HUDs) are the games' way of providing information about the game to the player and in some cases allowing the player to interact with the game.

Unreal Engine 4 provides multiple means of creating UIs and HUDs. The Canvas class can be used to draw directly to the screen at a low level, overlaid onto the world.

The game's Interface is used to convey information to the player and provide a means of prompting the user for directed input. A game interface generally consists of two main elements: the heads-up display (HUD) and menus or user interfaces (UIs).

The HUD refers to the status and information overlaid on the screen during gameplay. The purpose of the HUD is to inform the player of the current state of the game, i.e. the score, their health, the amount of time remaining,

The HUD is usually non-interactive, meaning the player does not click on elements of the HUD, though this becomes a gray area in certain types of games where the HUD and user interfaces are hard to separate.

User Interfaces refer to menus and other interactive elements. These elements are usually drawn overlaid on the screen much like the HUD, but in certain circumstances they could be part of the game world itself rendered onto a surface in the world. The most obvious examples of UIs are the main menu displayed when the game starts up or the pause menu shown when the player has paused the game. However, other UIs may be displayed during play. These could be used to show dialog between characters in the game or in more complex situations, such as in an RTS or RPG, they may be integral to the game play itself allowing the player to choose weapons, armor, units to build, etc.

HUD

The HUD is the base object for displaying elements overlaid on the screen. Every human-controlled player in the game has their own instance of the AHUD class which draws to their individual Viewport. In the case of splitscreen multiplayer games, multiple Viewports share the same screen, but each HUD still draws to its own Viewport. The type, or class, of HUD to use is specified by the gametype being used.

Canvas

The Canvas is an object that can be used during the render loop of the HUD to draw elements - text, texture and material tiles, arbitrary triangles, and simple primitive shapes - to the screen. Unless you are making use of some specialized alternative, drawing with the Canvas is the method used to create HUDs and UIs in games made with Unreal Engine.

Slate

Slate is a custom and platform agnostic user interface framework that is designed to make building the user interfaces for tools and applications such as Unreal Editor, or in-game user interfaces, fun and efficient. It combines a declarative syntax with the ability to easily design, lay out, and style components that provides a method for creating and iterating on UIs.

Refer to Slate UI Framework for additional documentation.

Chaos is Unreal Engine's high-performance physics and destruction system. With Chaos Destruction, users can achieve cinematic-quality visuals in real time in scenes with massive-scale levels of destruction and unprecedented artist control over content creation.

Getting Started:



Overview of Unreal Engine's Destruction system.



Quick Start guide for Unreal Engine's Destruction system.

Key Concepts:



Overview of the authoring process for Geometry Collections.



Overview of the various selection tools included in the Fracture Mode.



Overview of the various methods of fracturing Geometry Collections.



Overview of the Edit Panel included with the Fracture Mode.



Overview of the various methods of clustering Geometry Collections.



Overview of the Physics Fields in Unreal Engine.

Create Geometry Collections

Create Geometry Collection Assets

Create a Geometry Collection from Static Meshes

Create a Geometry Collection from a Blueprint Actor

Create a Geometry Collection from other Geometry Collections

Fracture Geometry Collections

Change the Materials of Geometry Collections

Best practices when creating Geometry Collections

Geometry Collections should be "water tight"

Geometry Collections should not have intersecting geometry

You can find similar information in video format in the Epic Developer Community site by watching the Chaos Destruction - Geometry Collections tutorial.

Destruction within the Chaos system starts with a Geometry Collection Asset. These assets can be built from one or more Static Meshes, Blueprints with Static Mesh components, and even other Geometry Collections.

Once you have a Geometry Collection, you can break it apart using the Fracture Mode and define the settings that determine how it breaks apart.

In this guide you will learn how to create Geometry Collections from different source objects that can be used with the Chaos Destruction system, as well as best practices for ensuring the best simulation results.

Create Geometry Collections

Create Geometry Collection Assets

Follow these steps to create a Geometry Collection asset.

Select a compatible Actor in the scene, click the Mode dropdown and select Fracture.



This will open the Fracture Mode windows that contain all the tools for fracturing your mesh. Alternatively, you can press Shift-6 to switch to the Fracture Mode.



Click for full view.

In the Generate section, click New to create a new Geometry Collection.



This asset type will be saved in the Content Browser and will be used to create your fractured mesh.

(1) Select the directory location where the Geometry Collection will be saved.

(2) Enter the name for the Geometry Collection asset.

(3) Click Create Geometry Collection.



Click Save All in the Content Browser to save the new Geometry Collection asset.



The Actor you selected in the scene is replaced with the Geometry Collection in the level.



These steps can be used to create Geometry Collections from any combination of assets.

Create a Geometry Collection from Static Meshes

You can create Geometry Collections by combining any number of Static Meshes in your Level.

When creating Geometry Collections from a single Static Mesh, select a Static Mesh Actor and follow the steps mentioned above. The selected Static Mesh Actor will be replaced by the new Geometry Collection in the level.



Geometry Collections can be created from any combination of Static Meshes. Select multiple Static Mesh Actors in the Level and follow the steps detailed in Create Geometry Collection Assets.

When selecting multiple Static Meshes, the first selected Actor is used to create the Geometry Collection's pivot point.



Create a Geometry Collection from a Blueprint Actor

You can create Geometry Collections by combining Blueprint Actors that have one or more Static Mesh components. Their Static Mesh components are treated as regular Static Meshes when converted to a Geometry Collection.

The example below is a Blueprint Asset that has two Static Mesh components.



Click for full view.

You can convert a Blueprint Asset to a Geometry Collection by dragging it into the Level and following the steps in Creating Geometry Collections.



Click for full view.

You can also combine Blueprint Actors with Static Meshes or other Blueprint Actors by selecting them and following the steps in Create Geometry Collection Assets.



Create a Geometry Collection from other Geometry Collections

You can create new Geometry Collections from other Geometry Collections following the same process. Drag one or more Geometry Collection Assets into the Level, select them and follow the steps in Creating Geometry Collection Assets.



Click for full view.

Fracture Geometry Collections

Now that you have a Geometry Collection, you can break it apart using the Fracture Mode. This mode contains different types of fracture methods, as well as methods of clustering and editing fractured pieces.

In this guide you will use the standard Uniform Voronoi method. With this method you define a minimum and maximum number of sites to create cell volumes for fracturing. For more details about the various fracturing methods available read the Fracturing Geometry Collections User Guide.

Follow these steps to fracture a Geometry Collection:

Select a Geometry Collection in the Level, click the Mode dropdown and select Fracture.





Click for full view.

Go to the Fracture section and click the Uniform fracture button.



Leave the default settings as they appear and click Fracture.



You can learn more about the fracturing process by referring to the Fracturing Geometry Collections User Guide tutorial.

Select the Geometry Collection and move it above the ground. Click the Play Mode options button and select Simulate or Selected Viewport to see the results.



The Geometry Collection fractures on impact.



Change the Materials of Geometry Collections

Now that you know how to fracture Geometry Collections, you might want to change how the fractured pieces look for the external and internal surfaces.

Follow these steps to show the Geometry Collection with its original Materials:

Select a Geometry Collection and use the Level Details panel.

In the Chaos Physics section, expand the General options.

Deselect the Show Bone Colors checkbox.





In the Materials section, each original Material ID has been duplicated from the source Asset.

In the example below, Element 1 and Element 3 have been duplicated from Element 0, and Element 2 to represent the internal surfaces when you created the Geometry Collection.



Replace the Materials in Element 1 and Element 3 to affect how the internal surfaces look. In the example below, red and green Materials have been added to those slots.



Click the Play Mode options button and select Simulate or Selected Viewport to see the results.



You can see that the internal surfaces now use the newly added Materials.



You can also change the Materials directly inside the Geometry Collection. Double click the Geometry Collection in the Content Browser to open it.



Scroll down to the Materials section and replace the Materials in Index [1] and Index [3].



Save the Geometry Collection and close the window.

Best practices when creating Geometry Collections

Consider the following when creating your Geometry Collections.

Geometry Collections should be "water tight"

Actors used to create the Geometry Collection should be "water tight," meaning they have no open faces or edges. Objects with open faces will perform worse when simulating and return unpredictable results.





Geometry Collections should not have intersecting geometry

Objects that make up a Geometry Collection should not intersect each other. Because each Geometry Collection is an individual object which can be simulated, the Chaos Solver will try to push each object away from the other once simulation starts. This can cause erratic and unpredictable results.



Objects with overlapping geometry will be pushed away from each other.



Objects without overlapping geometry simulate correctly.



Fracture a Geometry Collection

Use the Selection Tools

Select All Nodes

Invert Your Selection

Deselect All Bones

Select the Parent Bones

Select the Child Bones

Select the Sibling Bones

Select All Bones at the Same Hierarchy Level

Contact Selection of Bones

Interactive Selection of Bones

You can find similar information in video format in the Epic Developer Community site by watching the Using the selection tools tutorial.

The Fracture Mode is a Level Editor Mode that contains a variety of tools, including ones used by the Chaos Destruction System for creating, fracturing, and manipulating Geometry Collections, the asset type for simulating real-time fracturing in Unreal Engine.

In this guide you will learn to use the various selection tools available in the Fracture Mode. These tools provide useful ways of selecting specific fractured pieces (also called Bones) in the Geometry Collection that can be further fractured or clustered.

Before learning about the Fracture Mode, you should know how to create Geometry Collections from Actors in the Level. If you are not familiar with the process, refer to the Geometry Collections User Guide.

Fracture a Geometry Collection

In this section, you will create and fracture a Geometry Collection so you can learn about the selection tools included with the Fracture Mode.

Create a Geometry Collection from a Static Mesh Actor in your Level.



With your Geometry Collection selected, go to the Fracture section and select one of the fracturing tools available. Go to the Fracture panel and click Fracture. You can fracture the Geometry Collection multiple times by using the same fracturing tool, or selecting a different one each time you click Fracture.



The example below used the Slice and Uniform Voronoi fracture tools to fracture the Geometry Collection.





Refer to the Fracturing Geometry Collections User Guide to learn more about fracturing Geometry Collections.

Use the Selection Tools

The fracture hierarchy of a Geometry Collection resembles a tree structure. It contains a root bone (Level 0) with one or more child bones (Levels 1). Each child bone can, in turn, contain its own children (Level 2 and 3).



When in Fracture Mode, you can use the selection tools to select the bones of a Geometry Collection directly.

You will find the selection tools in the Select section with the following options:



Name

Description

All

Selects all the bones in the Geometry Collection.

Invert

Inverts the current selection of bones in the Geometry Collection.

None

Deselects all bones in the Geometry Collection.

Parent

Selects the parent bone of the current bone selection.

Children

Selects all the child bones of the current bone selection.

Siblings

Selects all bones that contain the same parent as the currently selected bone.

Level

Selects all bones in the same level of the hierarchy.

Contact

Selects all bones that are adjacent to any currently selected bones.

Interactive

Enables an interactive selection mode where you can use marquee selection and filtering to select a desired number of bones in the Geometry Collection.

You can select multiple bones (fractured pieces) in the Geometry Collection by pressing CTRL and clicking them directly in the viewport.

Select All Nodes

Click the All button to select all the bones in the Geometry Collection. This includes all the bones of each level in the hierarchy.



Invert Your Selection

Use the selection tools, or CTRL+click, to select any individual bones of the fracture mesh. Then, click the Invert button to invert your selection.



Deselect All Bones

Click the None button to deselect all bones in the Geometry Collection.



Select the Parent Bones

Select a bone that is the child of another bone in the Geometry Collection. Click Parent to select the immediate parent bone to the selected child bone in the hierarchy.



In the example below, selecting the child bone 87 and then clicking Parent selects the parent of it, Bone 12.



Select the Child Bones

Select a parent bone and click Children to select all child bones of the selected parent bone.

In the example below, all children of Bone 12 are selected.



Select the Sibling Bones

Select a bone in the Geometry Collection. Click Sibling to select all the bones that share the same parent as the selected bone(s).



In the example below, Bone 87 is selected. When Sibling is clicked, all children of Bone 12 are selected because they share that same parent bone.



Select All Bones at the Same Hierarchy Level

Select a bone in the Geometry Collection. Click Level to select all bones in the same level of the hierarchy.



In the example below, the Geometry Collection contains several bones that are the same hierarchy level in their fracture tree. With Bone 5 selected, when Level is clicked in the selection tools, all other Bones at that same hierarchy level will be selected, like Bones 6, 7 and 8.



Contact Selection of Bones

Click Contact to select all bones that are adjacent to the currently selected bones in the Geometry Collection.



Interactive Selection of Bones

Click Interactive to enter a marquee selection mode. Left-click and drag the mouse in the viewport to select multiple bones. You can hold the CTRL key and drag the mouse to remove bones from the selection.

The interactive selection mode has the following options:



Option

Description

Mouse Selection Method

Determines the bone selection method. Rect Select uses a rectangular marquee for selecting all overlapping bones. Standard Select allows bone selection by left-clicking the mouse on each bone to select them directly.

Volume Selection Method

Determines the method used to calculate the bones selected by the filter operation.

Selection Operation

Determines whether the filter operation will replace, add, or remove from the current selection.

Min Volume Fracture

Determines the minimum bone volume considered for selection.

Max Volume Fracture

Determines the maximum bone volume considered for selection.

You can filter your selection by bone size by using the Filter Settings. Increasing Max Volume Fracture to 1 will include all bone sizes in the filter operation.



Click the image for full size.

Use Min Volume Fracture to filter out the smallest bones. Do this until you reach a desired selection. A common example is excluding the smallest bones from the selection so you can add an additional fracture level to the biggest bones.



Fracture the Geometry Collection

Reset the Geometry Collection

View Settings

Common options included with most fracture methods

Use the Fracture Tools

Uniform Fracture

Cluster Fracture

Radial Fracture

Planar Fracture

Slice Fracture

Brick Fracture

Mesh Fracture

Custom Fracture

You can find similar information in video format in the Epic Developer Community site by watching the Fracture and Clustering tutorials.

The Fracture Mode is an editor mode that contains a wide variety of tools for creating, fracturing, and manipulating Geometry Collections. Geometry Collections are the asset type used by Chaos Destruction for simulating real-time fracturing in Unreal Engine.

The available fracturing tools provide users with a lot of control over how the Geometry Collection is fractured. This includes the number of fractured pieces and how they relate to each other (fracture hierarchy).

Each fracture tool uses a different method, or algorithm, to generate different fracture patterns. Each method comes with a variety of options to further customize the generated pattern, including adding randomization.

In this guide you will learn to use the various fracturing tools available in the Fracture Mode.

Before learning about the Fracture Mode, you should know how to create Geometry Collections from Actors in the Level. If you are not familiar with the process, refer to the Geometry Collections User Guide.

Fracture the Geometry Collection

Before using the fracturing tools, create a Geometry Collection from a Static Mesh Actor in your Level and select it.



You can now access the available fracture tools under the Fracture section of the Fracture Mode panels. Each tool can be applied to the Geometry Collection as a whole, or to selected fractured pieces (individual bones) after fracturing.



Click the image for full size.

When applying a fracture method to the Geometry Collection, a new fracture level is created. This is reflected in the Geometry Collection's Fracture Hierarchy window.



Click the image for full size.

A Geometry Collection's fracture hierarchy resembles a tree structure. It contains a root bone with one or more child bones which make up the fractured pieces. Each child bone can, in turn, contain its own child bones.

The levels in the fracture hierarchy represent the structure of the tree, with four levels representing a tree-like structure with three branching levels of child bones.



You can use different fracturing tools each time you fracture the Geometry Collection, creating different fracture patterns per level in the Fracture Hierarchy.

You can select multiple bones (fractured pieces) in the Geometry Collection by holding CTRL and selecting them directly in the viewport. You can also use the provided selection tools to quickly select a set of bones directly.

Reset the Geometry Collection

After fracturing the Geometry Collection, you can reset it to its original state by clicking the Reset button under the Generate section. This sets the Geometry Collection to its original state when it was created without any applied fracturing. This can be helpful when trying different fracture methods until you find the configuration that provides the desired results.





View Settings

The View Settings help you visualize what the Geometry Collection looks like after applying any fracture operation.



Option

Description

Explode Amount

Displays what the Geometry Collection will look like when it fractures during gameplay. A value of 1 will separate all bones and will show what a completely fractured Geometry Collection looks like.

Hide UnSelected

Hides the bones that are not currently selected in the Geometry Collection. This helps you focus on specific bones while applying a fracture method.

Fracture Level

Defines which fracture level to visualize. Selecting All will display the bones for all fracture levels.



Click the image for full size.



Common options included with most fracture methods

All fracture tools have these Common Fracture options:



Option

Description

Random Seed

This value is used to generate the random fracturing pattern over the Geometry Collection. A -1 means a random seed value will be used every time a new fracture operation is applied. Specifying a value generates a fracture pattern tied to that seed number, which when entered will always generate that same fracture pattern.

Chance to Fracture

Sets the chance that a bone is likely to be fractured during the fracture operation where 1 is equal to 100%, meaning all bones will be fractured. 0 is equal to 0% chance of any bone being fractured.

Group Fracture

Generates a fracture pattern across all selected meshes.

Draw Sites

Draws points in the center of the bones to be cut out by the fracture pattern.

Draw Diagram

Draws the fracture pattern diagram on top of the Geometry Collection.

Grout

Defines the amount of space to leave between cut piece.



Most fracture methods share these Noise options:

Amplitude: Defines the size of the perlin noise displacement in centimeters. A value of 0 indicates that no noise will be used when generating the fracture pattern.





Frequency: Defines the period of the perlin noise. Smaller values produce a smoother noise pattern, and larger ones produce a rougher noise pattern.





Persistence: Defines the persistence of the perlin noise layers. For each layer (octave) after the first, the amplitude of the perlin noise will be scaled by this factor.





Lacunarity: Defines the lacunarity of the perlin noise layers. For each layer (octave) after the first, the frequency of the perlin noise will be scaled by this factor.





Octave Number: Defines the number of fractal layers (octaves) of perlin noise that will be applied to the fracture pattern. Each layer is additive, with Amplitude and Frequency scaled by Persistence and Lacunarity, respectively. Smaller values (1-2) will generate smooth patterns, while larger values will generate more craggy patterns.





Point Spacing: Distance (in centimeters) between vertices on cut surfaces where noise is added. Larger spacing between vertices results in more efficient meshes with fewer triangles. However, this also results in lower overall resolution to see the shape of the added noise.

Use the Fracture Tools

Each Fracture tool has its own settings that provide relevant options to achieve the desired results.

Uniform Fracture

The Uniform tool uses a Voronoi algorithm to generate the fracture pattern. Enter a minimum and maximum number of Voronoi sites (or number of fractured pieces) and the algorithm will choose a random value within the range.



In the fractured Geometry Collections below, the one on the left has the Min and Max Voronoi Sites set to 20. This means that the fractured Geometry Collection will have 20 fractured pieces. The example on the right has the Min and Max Voronoi Sites set to 100.





20 Voronoi Sites

100 Voronoi Sites

Click image for full size.

Click image for full size.

Cluster Fracture

The Cluster fracture tool is an extension of the Uniform fracture method where both use a Voronoi algorithm when generating their fracture pattern. While the Uniform Voronoi method produces a relatively even distribution of sites, the Cluster method gathers its sites together into islands of close proximity, creating a more varied fracture pattern compared to the uniform method.



Option

Description

Min Num Clusters

Defines the minimum number of Voronoi clusters that will be created.

Max Num Clusters

Defines the maximum number of Voronoi clusters that will be created.

Min Sites per Cluster

Defines the minimum number of Voronoi sites per cluster.

Max Sites per Cluster

Defines the maximum number of Voronoi sites per cluster.

Min Dist from Center

Defines the minimum cluster radius. The cluster radius offset will be added to this value.

Max Dist from Center

Defines the maximum cluster radius (in centimeters). The Cluster Radius Offset will be added to this value.

Cluster Radius Offset

Defines the radius offset of the cluster (in centimeters) that is added to the minimum and maximum distance from the center.

The examples below use the following Cluster settings as a starting point:

Setting

Value

Min Num Clusters

2

Max Num Clusters

2

Min Sites per Cluster

5

Max Sites per Cluster

5

Min Dist from Center

0.1

Max Dist from Center

0.1

Cluster Radius Offset

0

The following have also been set under the Common Fracture settings:

Draw Sites: Enabled

Draw Diagram: Disabled

In the example below you can see the difference between setting the Min / Max Number of Clusters from 2 to 5.





In the example below you can see the difference between setting the Min / Max Sites per Cluster from 5 to 10.





In the example below you can see the difference between setting the Min / Max Distance from Center from 0.1 to 0.2.





In the example below you can see the difference between setting the Cluster Radius Offset from 0 to 10.





Radial Fracture

The Radial fracture tool creates a distribution of Voronoi sites that operate from a center point and radiate outwards. The center position is controlled by manipulating the gizmo inside the Viewport.



If you want to place it at a specific location, you can enter the Center and Normal rotation (1) of the center point directly in the Radial Voronoi options. To activate those fields, disable the Use Gizmo checkbox (2) in the Placement Controls section.



The Radial fracture tool comes with the following options:

Center: Defines the center location of the generated fracture pattern. This option is only available if you disable the Use Gizmo checkbox.

Normal: Defines the normal rotation of the plane used to generate the fracture pattern. This option is only available if you disable the Use Gizmo checkbox.

Radius: Defines the radius of the pattern from the center location.





Angular Steps: Defines the number of angular steps used to generate the fracture pattern. These steps subdivide the circumference of the diagram.





Radial Steps: Defines the number of radial steps used to generate the fracture pattern. This affects the number of times the pattern is divided outwards from the center.





Angle Offset: Defines an angular offset (in degrees) used for every radial step.





Variability: Defines the amount to randomly space each generated Voronoi site (in centimeters).





Planar Fracture

The Planar fracture tool is used to create a planar cut in the Geometry Collection. As cuts are created in the Geometry Collection, the gizmo resets to the centroid of your current selection. This is helpful if you are trying to make deliberate cuts as you select different Bones in the Viewport.

You can disable the gizmo resetting to the center of your current selection by disabling Center on Selection under the Placement Controls section.



It's important to note that the plane used for each cut extends to infinity, meaning that even if the gizmo displays the plane at a specific size, the cut will extend in the plane's direction to cut the entire Geometry Collection.

You can also forgo using the gizmo by disabling Use Gizmo under the Placement Controls section.



Disabling the gizmo enables you to set a Number of Cuts under the Plan Cut section. This results in a random number of cuts to the Geometry Collection.



In the example below you can see the difference between setting the Number of Cuts from 1 to 10.





You can change the placement of these cuts by changing the Random Seed value under the Common Fracture section.





Slice Fracture

The Slice fracture tool is an extension of the Planar fracture tool with the added ability to set the number of cuts along each axis. This allows for initial cuts to be aligned into columns and rows. Slices can also have random angles and offset variations applied to them.

Option

Description

Slices X

Defines the number of slices along the X axis.

Slices Y

Defines the number of slices along the Y axis.

Slices Z

Defines the number of slices along the Z axis.

Random Angle Variation

Defines the maximum angle (in degrees) to randomly rotate each slicing plane.

Random Offset Variation

Defines the maximum distance (in centimeters) to randomly shift each slicing plane.

In the example below you can see the difference between setting the Random Angle Variation from 0 to 35.





In the example below you can see the difference between setting the Random Offset Variation from 0 to 50.





Brick Fracture

The Brick fracture tool is considered experimental and may receive significant changes in future versions of the engine.

The Brick fracture tool generates a customizable brick pattern. You can specify how the bricks are arranged and their size for when the pattern is applied to the Geometry Collection.

Option

Description

Bond

Sets the brick bond pattern that determines how the bricks are arranged in the fracture pattern. You can select from: Stretcher, Stack, English, Header, and Flemish.

Brick Length

Defines the brick length in centimeters.

Brick Height

Defines the brick height in centimeters.

Brick Depth

Defines the brick depth in centimeters.

The Example below shows the Stretcher bond method applied to the Geometry Collection.



Mesh Fracture

The Mesh fracture tool uses the shape of a Static Mesh to generate the fracture pattern. This is useful if you want to create very specific pattern shapes.

Drag a Static Mesh into the level and place it so it intersects the Geometry Collection.



Click Mesh and go to the Mesh Cut section in the Fracture panel.



Click the Cutting Actor dropdown. Select the Static Mesh actor you dragged into the level. Alternatively, you can click the Eye-Dropper button and click on the Static Mesh in the viewport.



Click Fracture to cut the Geometry Collection in the shape of the Cutting Actor. To see the results, select the Cutting Actor in the Viewport and move it.



The following Cut Distributions are available with the tool:



Option

Description

Single Cut

Generates a single cut at the current location of the Cutting Actor.

Uniform Random

Scatters the Cutting Actor in a uniform random distribution around the Geometry Collection's bounding box.

Grid

Arranges the Cutting Actor in a regular grid pattern across the Geometry Collection.

The following options are available for the Uniform Random Cut Distribution:



Option

Description

Number to Scatter

Defines the number of Actors to randomly scatter.

Min Scale Factor

Defines the minimum scale factor to apply to the cutting meshes. A random scale will be chosen between Min and Max.

Max Scale Factor

Defines the maximum scale factor to apply to the cutting meshes. A random scale will be chosen between Min and Max.

Random Orientation

Whether to randomly vary the orientation of the cutting actors.

+/- Roll Range

Defines the range that will be used to pick a random roll (rotation in X axis) for the cutting Actors.

+/- Pitch Range

Defines the range that will be used to pick a random pitch (rotation in Y axis) for the cutting Actors.

+/- Yaw Range

Defines the range that will be used to pick a random yaw (rotation in Z axis) for the cutting Actors.

In the example below you can see the difference between setting the Number to Scatter from 5 to 10.





In the example below you can see the difference between enabling and disabling the Random Orientation.





The following options are available for the Grid Cut Distribution:



Option

Description

Grid Width

Defines the number of cutting meshes to add to the X-axis of the grid.

Grid Depth

Defines the number of cutting meshes to add to the Y-axis of the grid.

Grid Height

Defines the number of cutting meshes to add to the Z-axis of the grid.

Variability

Defines the magnitude of the random displacement of the cutting Actors.

Min Scale Factor

Defines the minimum scale factor to apply to the cutting Actors.

Max Scale Factor

Defines the maximum scale factor to apply to the cutting Actors.

Random Orientation

Whether to randomly vary the orientation of the cutting Actors.

In the example below you can see the difference between enabling and disabling the Random Orientation.





Custom Fracture

The Custom fracture tool is the most extensive fracturing tool included with the Fracture Mode.



Option

Description

Pattern

Defines the pattern used to generate the Voronoi sites.

Normal Offset

Defines the offset value used for each vertex's normal direction.

Variability

Defines the amount to randomly offset each Voronoi site in centimeters.

Sites to Add

Defines the number of Voronoi sites to add to the pattern.

Skip Fraction

Defines the fraction of points that will not be fractured (skipped).

Skip Mode

Defines the method used for skipping the points that will not be fractured.

With this tool, the Fracture Diagram is considered its own entity that can be moved relative to the Geometry Collection. This is useful when looking to create more customized fracture patterns.





The gizmo is centered

The gizmo is moved to a corner

Click image for full size.

Click image for full size.

To better visualize the fracture diagram, you can freeze positional data for the fracture sites. Under the Common Fracture section, enable Draw Sites and disable Draw Diagram.



In addition, under the Live Voronoi Sites section. set the Pattern to Centered and set the Variability to 40.



Doing this enables you to move the gizmo to a desired location on the Geometry Collection. In the Fracture Mode panel under the Custom Voronoi section, click the Freeze Live Sites.







The gizmo is placed at the top left corner

The gizmo is moved revealing the frozen sites

Click image for full size.

Click image for full size.

You can continue this process to deliberately place sites on the Geometry Collection. Once you are ready, click Fracture to see the results of all the sites placed on the Geometry Collection.



Since the fracture diagram is separate from the Geometry Collection, you can make changes to the Geometry Collection without affecting the fracture itself.

For example, if you set the Sites to Add to 2000, scale down the Geometry Collection to the shape of a column and click Fracture, you get the fracture pattern applied to the current shape of the Geometry Collection.





Rescale the Geometry Collection to its original size and notice how the fracture pattern is now stretched, resembling splinters of wood.



Because the fracture diagram isn't directly tied to the Geometry Collection, when you rescale the Geometry Collection, the fracture diagram remains the same. This means that you can create unique fracture patterns that fit a stylistic choice for your project, like this one with elongated fractures.

Fracture a Geometry Collection

Use the Edit Tools

The Prune tool

The Visibility tools

You can find similar information in video format in the Epic Developer Community site by watching the Fracture and Clustering tutorials.

The Fracture Mode comes with editing tools that provide the ability to remove unwanted bones (fractured pieces) from the Geometry Collection hierarchy, as well as hide and unhide specific bones. These tools present a workflow improvement when working with complex fracturing of Geometry Collections.

In this guide you will learn how to use the available tools in the Edit panel.

Before learning about the Edit Tools, you should know how to create Geometry Collections and fracture them. If you are not familiar with the process, refer to the Geometry Collections User Guide and the Fracturing User Guide.

Fracture a Geometry Collection

In this section, you will create and fracture a Geometry Collection so you can learn about the Edit tools included with the Fracture Mode.

Create a Geometry Collection from a Static Mesh Actor in your Level.



Fracture the Geometry Collection by using one of the available methods included. In the example below, we used the Slice tool to fracture the Geometry Collection into 8 pieces.



Click the image for full size.

Use the Edit Tools

The Prune tool

The Prune tool is used to remove any selected bones (fractured pieces) from the fracture hierarchy.

Select one or more bones in the viewport or the hierarchy.



Click the image for full size.

Click Prune to remove selected bones.



This tool is commonly used to remove intersecting geometry or unwanted Bones after fracturing the Geometry Collection.



The Visibility tools

The Visibility tools are used to temporarily hide selected bones from the viewport. This can be useful when trying to focus on a specific set of Bones in the hierarchy.

Click Hide in the Edit category to hide all selected Bones.







To show the hidden Bones, select them in the Fracture Hierarchy and click Unhide.





The Cluster Tools

Auto Cluster

Magnet Cluster

Flatten Cluster

Cluster and Uncluster

Merge Cluster

Level Up Cluster

Drag and Drop Clustering

Embedded Geometry Tools

You can find similar information in video format in the Developer Community site by watching the Fracture and Clustering tutorials.

Fracture Mode is a Level Editor Mode that contains a variety of tools, including those used by the Chaos Destruction System for creating, fracturing, and manipulating Geometry Collections, the asset type for simulating real-time fracturing in Unreal Engine.

When you fracture a Geometry Collection, a new fracture level is created. This is reflected in the Geometry Collection's Fracture Hierarchy window.



You can also see a summary of the fracture levels in the Level Statistics panel.



Each fracture level in the hierarchy represents a cluster of bones (fractured pieces) for the Geometry Collection. In other words, all the bones grouped in the same level will be treated as a group when it comes to the fracture simulation.

Clustering helps reduce the performance impact of the simulation as the system has less collisions to calculate at the same time. During the simulation, the higher level clusters will break first, followed by the lower ones. In the example above, Level 1 (20 pieces) will break first, followed by Level 2 (87), and so on.

Clustering can create a more realistic destruction simulation as most objects in the real world fracture into larger pieces when strain is first applied. Clustering can also be used to give your destructible object different artistics looks by applying different fracture patterns to your Geometry Collection.

You can enable or disable Clustering during the simulation by selecting your Geometry Collection and referring to the Details panel. Scroll down to the Clustering section and toggle the Enable Clustering checkbox.







Fracture Mode has a variety of tools to adjust the bone clusters in your Geometry Collection. This gives you more control over the performance and aesthetics of the simulation.

In this guide you will learn how to use the available clustering tools.

Before learning about the clustering tools, you should know how to create Geometry Collections and fracture them. If you are not familiar with the process, refer to the Geometry Collections User Guide and the Fracturing User Guide.

The Cluster Tools

In this section you will learn how to use the available clustering tools in the Fracture Mode.

Auto Cluster



The Auto cluster tool creates bone clusters by using a specified number of Cluster Sites. This gives you precise control of how many clusters are created when the cluster operation is applied to the Geometry Collection. You can also specify whether bones grouped together should connect by enabling the Enforce Cluster Connectivity checkbox.



The tool is branch-based, meaning that it creates a cluster based on the current number of bones selected in the Fracture Hierarchy.

In the example below, the Uniform Voronoi fracture tool was used to create 500 sites.



You can see the hierarchy in the Level Statistics panel or the Fracture Hierarchy window.



Select the Auto cluster tool and enter 200 Cluster Sites.



Click Auto Cluster button to see the results.



Now you can see the result.



Repeat this process and add an additional 100, 50, and 15 Cluster Sites.



As you can see, you can create as many fracture levels (clusters) as you want to achieve a desired effect.

Magnet Cluster



The Magnet Cluster tool creates bone clusters by grouping all connecting bones of the current selection. You can specify the number of Iterations to control how many bones are grouped using the operation.



In the example below, 1 iteration is used to cluster all bones on the outer ring of the selection.





Before clustering

After clustering

Click image for full size.

Click image for full size.

In this example, 2 iterations are used to cluster the outer 2 rings from the selection.





Before clustering

After clustering

Click image for full size.

Click image for full size.

The Magnet Cluster tool can also work with multiple selections at once. In the example below, the tool is used with 3 bones selected for 1 iteration at a time. You can see how each time we apply the operation, the connecting bones of each selection are clustered separately.



Flatten Cluster



The Flatten cluster tool flattens the bone hierarchy, removing the middle levels of the Destruction Hierarchy. This can be useful to remove the intermediate fracturing steps to get to a final fracture pattern.

In the example below, we see a Geometry Collection fractured into beams for its first level (Level 1), then further fractured into blocks (Level 2).





Level 1

Level 2

Click image for full size.

Click image for full size.

We can use the Flatten cluster tool to flatten the hierarchy and remove the beam configuration altogether. Select the root bone in the hierarchy and click Flatten.





Before using Flatten

After using Flatten

Click image for full size.

Click image for full size.

Cluster and Uncluster



The Cluster tool creates a bone cluster from the current bone selection. Conversely, the Uncluster tool removes a bone cluster from the current selection. This gives you complete control over the creation of Clusters in your Geometry Collection.

In the example below, we have a Geometry Collection fractured into blocks with two levels in the hierarchy.



Select a group of bones and click Cluster to create a new cluster for the selected bones.





Before using Cluster

After using Cluster

Click image for full size.

Click image for full size.

Repeat this process and create two more clusters.





You can use the Uncluster tool to remove a cluster by selecting the bone in the hierarchy and clicking UnClstr.





Before using Uncluster

After using Uncluster

Click image for full size.

Click image for full size.

Merge Cluster



The Merge cluster tool combines clusters into a single cluster and keeps the same structure in the hierarchy.

This can be useful to keep a certain number of bones in the hierarchy for your simulation.

In the example below you can see a Geometry Collection that has three clusters in Level 1. If we select two clusters and click Cluster, both clusters combine into one. However, the hierarchy now looks like this:





Before using Cluster

After using Cluster

Click image for full size.

Click image for full size.

As you can see, the hierarchy has been altered after the operation. In contrast, if we use the Merge cluster tool, the hierarchy remains the same:





Before using Merge

After using Merge

Click image for full size.

Click image for full size.

Level Up Cluster



The Level Up cluster tool moves the selected bones to a higher level in the hierarchy. Select the desired nodes in the Fracture Hierarchy window and click Level Up to see the results.

You can also perform this operation on the entire hierarchy by selecting the root bone and clicking Level Up.





Drag and Drop Clustering

You can create bone clusters manually by dragging and dropping bones directly in the Fracture Hierarchy window. You can drag clusters or leaf nodes into other clusters.

In the example below, the Geometry Collection has 2 bones in Level 1 and 25 bones in Level 2 of the hierarchy.





Level 1

Level 2

Click image for full size.

Click image for full size.

You can select any bone in the hierarchy and move it to alter the clusters in the level above.



Embedded Geometry Tools

The Fracture Mode comes with tools to embed additional geometry into the fracture simulation. The primary purpose of embedded geometry is to add a layer of visual complexity to augment the simulation. For this reason, embedded geometry does not have any collision nor is it considered part of the simulation.

A common example is using embedded geometry to create the internal structure of a building. This can be rebar, cabling or grout within the walls.

In the example below, we have a Geometry Collection that has been cut diagonally. Drag a Static Mesh into the Geometry Collection and make sure it intersects with the Geometry Collection.



Duplicate the Static Mesh and move it to the other side of the Geometry Collection.



Select both Static Meshes and the Geometry Collection and go to the Embed section and click Auto.



You can now remove the Static Meshes from the level. You will notice that the Static Meshes still appear to be intersecting the Geometry Collection.

Go to the Content Browser and open the Geometry Collection asset. Scroll down to the Embedded Geometry Exemplar section and expand it. Notice how the Static Mesh has been added to the list along with the Instance Count denoting that we are using 2 instances of the Mesh in the Geometry Collection.



You can continue to add Static Meshes to the Geometry collection by clicking Auto to embed them into the Geometry Collection.



If you want to embed a Static Mesh that does not overlap the Geometry Collection, select a bone in the Geometry Collection and the Static Mesh, then click Embed.





Click Flush to remove all embedded geometry from the Geometry Collection.



Creating a Geometry Collection

The Anchor Field

The Sleep and Disable Fields

The Master Field

Introduction

External Strain

Strain Magnitude

Strain Falloff Type and Min and Max

Number of Strain Hits

Internal Strain

Activate Rigid Bodies

Velocity

Radial Velocity

Angular Velocity

Force vs Velocity

Falloff

Noise

You can find similar information in video format in the Developer Community site by watching the Chaos Destruction - Fields tutorials.

Chaos Fields use a region of space to control properties of a physics simulation. There are three primary types of fields — Anchor Fields, Strain / Force Fields, and Sleep / Disable Fields.

Anchor Fields are construction Blueprints that constrain a portion of a Geometry Collection in place during simulation. You can use them to make sure a certain part of the Geometry Collection stays fixed in place no matter what happens in the simulation.

Sleep / Disable Fields bring a Geometry Collection to rest when the bone (fractured piece) velocities fall below a specified threshold value. Sleeping bones can be reawakened during the simulation if they come in contact with an active object. Disabled bones cannot be reawakened.

Strain / Force Fields apply strain or linear velocity to a Geometry Collection during simulation.

Unreal Engine comes with pre-built Chaos Fields that can be used as-is, or modified by opening them in the Blueprint Editor.

To find them, click Settings > Show Engine Content in the Content Browser.



Go to Engine > Content > EditorResources > FieldNodes to find the available Chaos Fields.



Creating a Geometry Collection

In this section you will create a Geometry Collection so you can learn to use the Chaos Fields during a fracture simulation.

Select a Static Mesh Actor in the scene, click the Mode dropdown and select Fracture.



This opens the Fracture Mode panels that contain all the tools for fracturing your mesh.



In the Generate section, click New to create a new Geometry Collection.



This asset type will be saved in the Content Browser and will be used to create your fractured mesh.



(1) Select the directory location where the Geometry Collection will be saved.

(2) Enter the name for the Geometry Collection asset.

(3) Click Create Geometry Collection.



Click Save All in the Content Browser to save the new Geometry Collection asset.

The Actor you selected in the scene is replaced with the Geometry Collection in the level.



See the Geometry Collections User Guide to learn more about creating Geometry Collections.

Use the Fracturing tools to fracture the Geometry Collection. In the example below, we used the Slice and Uniform Voronoi tools to create 4 Levels in the Fracture Hierarchy.



See the Fracturing Geometry Collections User Guide to learn more about fracturing Geometry Collections.

The Anchor Field

Anchor Fields set any Geometry Collection bone that falls within its volume to Static during the simulation.

Drag FS_AnchorField_Genericto the level and overlap it with a corner of the Geometry Collection.



Select the Geometry Collection and go to the Details panel. Scroll down to the Chaos Physics section and expand the Initialization Fields array. Click the Index [0] dropdown and select FS_AnchorField_Genericfrom the list.



Go to the Clustering section and disable the Enable Clustering checkbox. This is done for demonstration purposes as it will better show the fracturing of the Geometry Collection.



Click the Play Mode menu button and select Selected Viewport or Simulate to see the results.





You can add as many Anchor Fields as you want by following the steps above. In the example below, we added Anchor Field to the top right corner.



You can also use the same Anchor Field on several Geometry Collections at once. In the example below, we used one Anchor Field on two Geometry Collections.



Anchor Fields come with three Falloff Shapes — Box, Sphere, and Plane. These shapes affect how many bones are set to Static and how the effect is implemented.

To change the Falloff Shape, select the Anchor Field and go to the Details panel. Scroll down to the Default section and click the Anchor Falloff Shape dropdown. Select the desired falloff shape.



In the example below, we use a Sphere shape for the Anchor Field.



In the example below, we use a Plane shape for the Anchor Field.



The Sleep and Disable Fields

The Sleep and Disable Fields bring rigid bodies to rest when their velocities go below a given Threshold value. Higher Threshold values will stop objects more aggressively.

These Fields are used to improve simulation performance and prevent excess jittering of the Geometry Collection pieces as they collide with each other. They also give you more control over how many rigid bodies are part of the simulation.

Sleeping bodies can be reawakened when they collide with an active object. Disabled bodies are removed from the simulation completely after they come to a resting state. Disabled bodies cannot be reawakened.

This type of field also has a Kill option, in addition to Sleep and Disable. This option ignores the Threshold value and immediately stops the body from simulating and removes it from the simulation once it overlaps the Field's volume.

Drag FS_SleepDisable_Generic into the Level and place it as seen below.



Go to the Details panel and scroll down to the Default section. Here you can specify the Threshold value the field uses to apply its effect. You can also specify the Field Behavior, Falloff Shape, and whether you want to show the Debug information.



In the example below we enabled the Debug option and used two Geometry Collections to show the effects of a Sleep Field. On the left, the Threshold value is set to 2, and on the right, the value has been set to 50.



As you can see, when the first object passes through the volume it goes to sleep. However, it is awakened when it collides with the second object. The higher the Threshold value, the more aggressively the bodies will be set to sleep.

In the examples below, we switched to Disable Fields. The Field on the left has a Threshold value of 2, and the Field on the right has a value of 200.



Notice how the Geometry Collections on the right do not collide with each other after they have been disabled. The higher Threshold value shows the effect more prominently.

Finally, we can use Kill Fields to immediately stop any rigid body from simulating. Notice that on the right we show a Static Mesh simulating physics while we use Geometry Collections on the left.



The Master Field

Introduction

The FS_MasterFieldis a pre-built Chaos Field included with Unreal Engine. You can find it by going to Engine > Content > EditorResources > FieldNodes.

This Field comes with many options for customization and is used primarily to:

Activate rigid bodies by applying external strain that breaks the connection between bones.

Apply velocity to rigid bodies to make them move and spin in a realistic manner

In the example below, we placed a default FS_MasterField where it overlaps with a Geometry Collection.

In its default configuration, the Field applies a large amount of external strain which causes the Geometry Collection to fracture. Then, the Field adds radial and angular velocities to the broken pieces to make them spin. Finally, the Field applies noise to add randomness to the effect.

This is the result:



You can configure the shape of the Field by clicking the Field Falloff Shape dropdown and choosing an option.



You can also configure the way the Field is applied by clicking the Activation Type dropdown and choosing an option.



Activation Type

Description

Delay

The field activates after the Delay Amount.

OnTick

The field activates on each tick.

OnTickWithDelay

The field activates on each tick after the initial Delay Amount.

Trigger

The field is activated by a Blueprint directly.

You can set the Field's lifespan by going to Advanced Field Settings > Timing and Lifespan section in the Details panel. This is useful when you are creating Fields that need to apply their effects over a short period.

You will learn more about these settings and more in the following sections.

External Strain

External Strain breaks the connections between the bones in a fractured Geometry Collection. You can modify the External Strain options of the Field by going to the Apply External Strain to Break Node Connections section in the Details panel.



Option

Description

Use External Strain

If enabled, the Field applies external strain to the assigned Geometry Collections.

Strain Magnitude

The magnitude of the strain force applied. By default, this value is very high to ensure the applied strain force breaks the bones. If the strain force is lower than the Damage Threshold for the Geometry Collection, the strain will not cause a fracture.

Strain Falloff Type

Applies a falloff to the strain force within the volume. You can select between Linear, Inverse, Square, and Logarithmic falloff types.

Strain Falloff Min Max

Sets the falloff values from the center of the volume (Min) to the edge of the volume (Max). A value of 0 represents no falloff, and a value of 1 represents 100% falloff.

Num Strain Hits

Sets the number of times the Field will be applied. The Field is activated once per hit, so multiple hits allow the user to break multiple cluster levels before any forces are applied.

In the example below, the Field is applying more strain than the Geometry Collection's Damage Threshold, resulting in the bones breaking.



In this example, we have two different Geometry Collections. The blue Geometry Collections have a Damage Threshold of 200,000, while the orange ones have a Damage Threshold of 500,000. The Field is applying internal strain with a magnitude of 400,000. This results in the blue Geometry Collections breaking, while the orange ones remain intact.



You can adjust the Strain Falloff by clicking the Strain Falloff Type dropdown and selecting an option. You can also adjust the Min and Max falloff values to get a desired result.

In this example, the Field has no falloff applied:



In this example, we applied a Linear falloff with a Max value of 2:





For performance reasons, we recommend avoiding using falloff with external strain. However, external strain falloff can be useful when combined with internal strain to achieve specific effects.

The Strain Hits option executes the external strain portion of the Field multiple times, once per hit. The strain is applied before other forces are applied to the fractured pieces.

This setting can be useful if you want to break multiple fracture levels of the Geometry Collection before applying other forces during the simulation.

In this example, you can see the results of applying a Field with a Strain Hit value of 1:



In this example, you can see the results of applying a Field with a Strain Hit value of 2:



Internal Strain

Internal Strain, or decay, changes the internal Damage Threshold values of the Geometry Collection. When active, a decay Field will lower the Damage Threshold of the bones inside the volume by the Decay Amount.

This can be used to weaken a Geometry Collection gradually, until it breaks from external strain.

In the example below, we set the Activation Type to OnTick with a Delay Amount of 1 second. In addition, we enabled the Use Decay checkbox and set a Decay Amount of 100,000, with a Decay Delay of 1 second.

The Geometry Collection has a Damage Threshold of 500,000.

These options will reduce the Damage Threshold of the bones within the volume by 100,000 every second, with a falloff towards the edges. Here are the results:





Activate Rigid Bodies

There are situations where you might want to activate kinematic rigid bodies without using strain.

You can do this by going to the Advanced Field Settings > Force Dynamic Switching section under Field Settings and enabling the Force Dynamic Switch checkbox.



In the example below, the Geometry Collection is set to Kinematic and the field is activating the Geometry Collection without applying any strain or velocity.



You can also activate Static and Skeletal Meshes by enabling the Activate Tagged Static and Skeletal checkbox.



For each Mesh you want to activate, set its Mobility to Movable and add the Actor Tag ‘SM_Rigids.' In addition, make sure the Mesh has collision so it can simulate correctly.







Velocity

Radial velocity pushes objects away from a point in space by a given magnitude. This point is in the center of the volume by default, but can be changed by the user.

In the example below the radial velocity is applied at the center of the sphere volume.



To change the origin of the velocity, go to the Advanced Field Settings > Velocity Controls section and change the Radial Position Offset. In this example, we offset the origin in the Y Axis by 100 units. This results in the velocity being applied from the edge of the sphere volume, as seen below.





You can also apply velocity in a specific direction by going to the Apply Linear and Angular Velocities section and enabling the Use Directional Vector checkbox.



In the example below, we are applying a Directional Magnitude of 800 in the up vector of the Field.



You can change the velocity direction by rotating the field. In this example, we rotated the field to change the direction of the velocity.



You can manually enter the direction vector by going to the Advanced Field Settings > Velocity Controls section and enabling the Override Directional Vector checkbox. Then, enter the Directional Vector Override value.





You can apply angular velocity by going to the Apply Linear and Angular Velocities section and enabling the Use Torque checkbox. You can control the magnitude of the velocity applied by setting the Torque Multiplier value.

In the example below, we set the Torque Multiplier to 64.





Force vs Velocity

The FS_MasterField comes with options to apply force or velocity within its volume. By default, the Field applies velocity, which explicitly sets the velocity of objects to the given value without taking into account their mass or volume.

Applying force is more realistic, as it takes into account each object's mass during the simulation. To adjust a Geometry Collection's mass, open the Geometry Collection asset from the Content Browser and go to the Collision section. Enter the desired amount for Mass.



Keep in mind that for Geometry Collections, the Mass value under the Physics section will not be used by the Field. Instead, only the settings in the Geometry Collection asset itself will be considered.

If you are applying force to a Static Mesh or Skeletal Mesh, set the object's mass by going to the Details panel and scrolling down to the Physics section. Enable Simulate Physics and enter the Mass value.



In the example below, you can see the Field on the left is applying velocity, while the Field on the right is applying force. Inside each field, there are two objects with a mass of 500 and 1000 Kilograms.

As you can see, both objects on the Field that is applying velocity move in the same way even though they have different masses. However, on the Field that is applying force, the objects are affected differently when the same amount of force is applied.



Falloff

The FS_MasterField has a variety of options to control the falloff of velocity applied within its volume. You can change the falloff type by going to the Apply Linear and Angular Velocities section and clicking the Velocity Field Falloff Type dropdown.



Velocity Field Falloff Types

Falloff Type

Description

None

No falloff function is applied to the Field.

Linear

The falloff function will be proportional to X, where X represents the distance between the center of the volume and its edges.

Inverse

The falloff function will be proportional to 1 / X, where X represents the distance between the center of the volume and its edges.

Squared

The falloff function will be proportional to X * X, where X represents the distance between the center of the volume and its edges.

Logarithmic

The falloff function will be proportional to Log(X), where X represents the distance between the center of the volume and its edges.

When using the Linear falloff type, the field will apply the maximum velocity at the center of the Field, and fade to the minimal value when it reaches the edges of the Field.

In the example below, you can see a Field where the Minimum Velocity Falloff is 0, and the Maximum Velocity Falloff is 1.



You can adjust the minimum and maximum Falloff values to create different effects. For example, the Field below is using a Minimum Falloff value of -1, and a Maximum Falloff value of 0. The negative value pulls objects towards the center, instead of repelling them. This creates the following effect:



You can also set the Minimum Falloff and Maximum Falloff values to larger integers to create a ring effect within the volume. In the example below, the Minimum Falloffvalue is set to -1, and the Maximum Falloff value is set to 1.



Noise

The FS_MasterField includes the ability to add noise to the velocities and forces applied within its volume. Noise adds randomness to the otherwise predictable velocities applied to objects inside the Field.

To add noise to the Field, go to the Noise section in the Details panel, and enable the Use Noise checkbox. You can set the minimum and maximum noise values multiplied against the velocities inside the Field. You can also set the Noise Scale Multiplier which scales the perlin noise used to create randomness.



In the example below, the box Field is applying velocity on Tick without any noise.



In the example below, the box Field is applying velocity on Tick with a Minimum Noise value of 0.8 and a Maximum Noise value of 1. The Noise Scale Multiplier is set to 30.





The Chaos Destruction system is a collection of tools that can be used to achieve cinematic-quality levels of destruction in real time. In addition to great-looking visuals, the system is optimized for performance, and grants artists and designers more control over content creation and the fracturing process by using an intuitive nonlinear workflow.

The system allows artists to define exactly how geometry will break during the simulation. Artists construct the simulation assets using pre-fractured geometry and utilize dynamically-generated rigid constraints to model the structural connections during the simulation. The resulting objects within the simulation can separate from connected structures based on interactions with environmental elements, like Physics Field and collisions.

The destruction system relies on an internal clustering model which controls how the rigidly attached geometry is simulated. Clustering allows artists to initialize sets of geometry as a single rigid body, then dynamically break the objects during the simulation. At its core, the clustering system will simply join the mass and inertia of each connected element into one larger single rigid body.

The destruction system uses on a new type of asset called a Geometry Collection as the base container for its geometry and simulation properties. A Geometry Collection can be created from static and skeletal mesh sources, and then fractured and clustered using UE5's Fracture Mode.

At the beginning of the simulation a connection graph is initialized based on each fractured rigid body's nearest neighbors. Each connection between the bodies represents a rigid constraint within the cluster and is given initial strain values. During the simulation, the strains within the connection graph are evaluated. These connections can be broken when collision constraints or field evaluations apply an impulse on the rigid body that exceeds the connections limit. Physics Fields can also be used to decrease the internal strain values of the connections, resulting in a weakening of the internal structure.

For large-scale destruction simulations, Chaos Destruction comes with a new Cache System that allows for smooth replay of complex destruction at runtime with minimal impact on performance.

Chaos Destruction easily integrates with other Unreal Engine systems, such as Niagara and Audio Mixer, to spawn particles or play specific sounds during the simulation.

1 - Required Setup

Section Results

2 - Creating the Geometry Collection

Section Results

3 - Fracturing the Geometry Collection

Section Results

4 - Destroying the Geometry Collection by shooting it

Section Results

5 - On Your Own!

Next Steps

You can find similar information in video format in the Developer Community site by watching the Chaos Destruction Overview tutorial.

1 - Required Setup

Create a new project and select the Games category and the First Person template. Enter your project's name and click Create.



Click for full view.

In the editor, click File > New Level. Select the Basic template and click Create. Save the level.



Section Results

In this section, you created a new project and set it up so you can add a Static Mesh which can be fractured in the next section of this guide.

2 - Creating the Geometry Collection

Destruction within the Chaos system starts with a new kind of asset called a Geometry Collection. These assets can be built from one or more Static Meshes, including those gathered together in Blueprints or even nested Blueprints.

Once you have a Geometry Collection, you can break it apart using the Fracture Mode and define the settings that determine how it breaks apart.

In this section you will create a Geometry Collection from a Static Mesh actor.

Add a Static Mesh to the level which you'll use to create a fractured mesh. In this example, I'm using the Chaos Primitive Box included in the Content Examples project available in the Unreal Engine Marketplace.



Click for full view.

Click the Mode dropdown and select Fracture.



This will open the Fracture Mode windows that contain all the tools for fracturing your mesh. Alternatively, you can press Shift-6 to switch to the Fracture Mode.



Click for full view.

Go to the Generate section and click New to create a new Geometry Collection. This new asset type will be saved in the Content Browser and will be used to create your fractured mesh.



Select the directory location where the Geometry Collection will be saved.

Enter the name for the Geometry Collection asset.

Click Create Geometry Collection.



Click Save All in the Content Browser to save the new Geometry Collection asset.



The Static Mesh will be replaced with the Geometry Collection in the level. In the Fracture Hierarchy window you will see that the Geometry Collection has a single node in the hierarchy.

This means that the Geometry Collection is composed of only one piece (single node). As you fracture your Geometry Collection, you will see each fractured piece represented as a separate leaf (child) node in the hierarchy. This hierarchy represents how the entire object was fractured, from a single solid piece to individual pieces that can break off as strain is applied.





Click for full view.

Section Results

In this section you learned how to create a Geometry Collection from a Static Mesh actor. You also learned how to enable the Fracture Mode in the editor and view a Geometry Collection's Fracture Hierarchy.

In the next section you will learn how to fracture the Geometry Collection.

3 - Fracturing the Geometry Collection

There are several different types of fracture methods available. Combining the different techniques may lead to more interesting-looking destruction. You will have to experiment with the different options and settings to achieve your desired results.

In this guide you will learn about the standard Uniform Voronoi method. With this method you define a minimum and maximum number of sites to create cell volumes for fracturing.

Go to the Fracture section and click the Uniform fracture button.



Leave the default settings as they appear and click Fracture.



The Geometry Collection is now fractured and you can see the newly created nodes (fractured pieces) in the Fracture Hierarchy window. For this example, you created 20 nodes.



Click for full view.

You can see the current fracture hierarchy by going to the Level Statistics window. In this example, Level 0 has 1 piece, and Level 1 has 20 pieces. If you continue to further fracture the Geometry Collection, the new structure will be reflected in this window.



Click for full view.

You can preview how the Geometry Collection will fracture by changing the value of the Explode Amount field inside the Fracture window.



Click for full view.

In the example below, you can see the results of changing the value from 0 to 1 in the field.



Select the Geometry Collection and move it above the ground. Click the Play Mode options button and select Simulate or Selected Viewport to see the results.



Below you can see the result of the performed steps.



Section Results

In this section you learned how to use the Fracture Mode to fracture a Geometry Collection by using the standard Uniform Voronoi method.

In the next section you will learn how you can destroy the Geometry Collection by shooting it.

4 - Destroying the Geometry Collection by shooting it

In this section you will use the First Person Rifle Blueprint that comes with the template to shoot and destroy the Geometry Collection you created.

The fractured pieces of a Geometry Collection break apart when enough strain is applied to its Connection Graph (how the fractured pieces are connected to one another).

The most common way to apply strain to a Geometry Collection is by using a Physics Field. In this example, you will use a pre-built Master Field that comes with Unreal Engine by default. You will spawn this Field at the projectile's impact location, and the Field will cause the Geometry Collection's pieces to break apart.

In the Content Browser go to FirstPerson > Blueprints and drag BP_Rifle to the level. During gameplay you can pick up the rifle and shoot by using the left mouse button.



Click for full view.

In the same folder, double-click BP_FirstPersonProjectile to open it. In the Event Graph, select all the nodes except Event Hit and delete them.



Click for full view.

Drag from the Event Hit node and search for then select Spawn Actor from Class.



Click the Class dropdown of the Spawn Actor node and search for then select FS_MasterField.



Drag from the Spawn Transform pin of the Spawn Actor node and select Make Transform.



Connect the Hit Location pin of the Event Hit node to the Location pin of the Make Transform node.



Drag from the Return Value pin of the Spawn Actor node and search for then select Set Activation Type.



Connect the Spawn Actor node to the Activation Type node.

Click the Activation Type dropdown and select Trigger. This will set the Master Field to activate when triggered.



Drag from the Return Value pin of the Spawn Actor node and search for then select CE Trigger.



Connect the Activation Type node to the CE Trigger node. The CE Trigger node immediately activates the Master Field.



Click for full view.

Drag from the CE Trigger node and search for then select Delay.



Drag from the Delay node and search for then select Destroy Actor. This will destroy the projectile after a brief delay on impact.



Your complited Blueprint Script should look as following:



Click for full view.

Go back to Fracture Mode and select the Geometry Collection. Press Shift-B to toggle the bone colors of the Geometry Collection so you can see the box materials.



Press Play and move to the rifle to pick it up. Use the left mouse button to shoot a projectile at the Geometry Collection and destroy it



Section Results

In this section you learned how to spawn a Physics Field that applies strain to a Geometry Collection, causing it to break apart.

5 - On Your Own!

Now that you know how to create and fracture a Geometry Collection, you can take what you've learned and apply it to more complex examples.

Here are some additional examples you might want to try:

Use several Static Meshes to create a more complex Geometry Collection.

Create more fracture levels and use different fracturing methods to create more interesting destruction patterns.

Build a more complex structure by combining several Geometry Collections and destroy them by shooting them.



Next Steps

You can learn more about the Fracture Mode and the Destruction system by reading the Key Concepts documentation or watching the Chaos Destruction video tutorials in the Developer Community site.

Clothing Tool Properties Reference

Cloth Painting Workflow

Paint Tools

Cloth Properties

Masks

Copy Clothing from Skeletal Mesh

Unreal Engine uses Chaos Cloth solver which is a low-level clothing solver responsible for the particle simulation that runs clothing. This clothing solver allows integrations to be lightweight and very extensible because we now have direct access to the simulation data.



With the Clothing Tools available within the Editor, the workflow enables developers to work directly with Unreal Engine to author their content without the need for external dependencies.



Unreal Engine Cloth Workflow. Click the image for full-size view.

This workflow enables you to create your content once and then do all the creation editing of the clothing directly inside of Unreal. It makes the creation and iteration of testing content that much quicker, and you also avoid any disconnects between where the content was created versus where it's being used by being able to see all of your edits for your clothing simulation happening in real-time and as they will appear in your game.

Cloth Painting Workflow

Using the workflow of creating cloth in-Editor, the Cloth Paint Tool enables you to quickly create clothing for your characters using any existing material element of a Skeletal Mesh.



Click for the full image.

Section Selection - Use this to select the Material IDs that will be used for painting cloth onto.

Cloth Paint Panel - This section includes all the necessary tools and properties you can use when painting clothing.

Follow the steps below to learn the process to create your clothing assets, assign them to your character, and along with the basics of painting on your render mesh.

Create and Assign a Cloth Asset

To start working with clothing, you will first need to create a clothing asset from your Level of Detail (LOD) section and assign it to your render mesh so that you can paint on it.

Follow the steps below to get started:

In the Skeletal Mesh Editor, click the Section Selection button from the main toolbar. It will enable you to select the different parts of your Skeletal Mesh that have their Material Element assigned.



Click for full image.

Use the left-click to select a part of your mesh that you want to use as cloth. Then right-click to open the context menu to create your Cloth Asset.



Click image for full size.

From the context menu, select Create Cloth Asset from Selection and then fill in the following areas of the menu:



Asset Name - Give your asset a name so that you can easily find locate it later.

Remove from Mesh - If you've got a separate mesh piece of geometry you want to be associated as cloth, you can enable this option. If not, you can leave this unchecked.

Physics Asset - If this cloth asset is for a character, use its Physics Asset here to get proper collision for the cloth simulation.

Once you're happy with the settings, click the Create button.



Right-click on the section again to bring up the context menu and hover over the Apply Clothing Asset and select from the available clothing assets to apply. It will associate any clothing assets created with the section you've selected.



Painting On Your Cloth

Once you're ready to paint on your cloth, you can use the following controls to Paint on your selected cloth asset.

Paint - Left Mouse Button

Erase - Shift + Left Mouse Button

Cloth Preview - H

If you've used the NVIDIA's PhysX DCC Plugin to create Clothing for 3DS Max or Maya, or similar painting tools in other programs, the controls should feel familiar for this operation.

In the Skeletal Mesh Editor, go to the File menu and select Window, then select Clothing from the list.



This will open the Clothing panel.



Click the Activate Cloth Paint button from the toolbar to enable properties you can use to paint for your selected Cloth Asset.



In the Clothing panel, select your assigned Cloth Asset from the Clothing Data list.



In the Cloth Painting section, you can select a Paint Tool type to use and then set a Paint Value (by default, the Brush paint tool will be used). Then left-click and drag across the surface of your mesh to start painting.

Hold the H keyboard shortcut to preview your painted cloth.

Paint Tools



The Tool selection enables you to choose from the brushes available to cloth paint.

Brush

Gradient

Smooth

Fill

Brush

The Brush tool enables you to paint a radius and strength value on your cloth as you drag across cloth assets.



Use the Paint Value to control the strength of the brush when you are painting the cloth. This value controls how much the painted area will react like cloth based on this value. A value of 0 would mean that the skinned vertex could not move and a value of 100 would allow the skinned vertex to move one meter from its original position.



For additional information about this tool and its properties, see the Brush Properties reference here.

Gradient

The Gradient tool enables you to paint a gradual blend between a set of cloth values that are selected.



To paint a gradient, perform the following steps:

Use the Left-Mouse Button to paint your Gradient Start Value. This is indicated by a Green dot over the painted vertice.

Hold the Ctrl + Left-Mouse Button to paint your Gradient End Value. This is indicated by a Red dot over the painted vertice.

When you are finished painting, press the Enter key to paint your gradient.



For additional information about this tool and its properties, see the Gradient Properties reference here.

Smooth

The Smooth tool enables you to blur or soften the contrast between painted cloth values.



Use the Strength value to adjust how strong or soft the blurring effect is to create a soft gradient between painted areas.



For additional information about this tool and its properties, see the Smooth Properties reference here.

Fill

The Fill tool enables you to replace areas with similar values with another value.



Use the Fill Value to set a value to fill the vertices in the area with. Use Threshold to set a value that the fill operation should use when sampling the vertices to replace.





For additional information about this tool and its properties, see the Fill Properties reference here.

Cloth Properties

The Cloth Config properties enable you to adjust your cloth to simulate different materials, such as burlap, rubber, or many other types of cloth materials.



For additional information about the configuration properties for clothing, see the Cloth Config Properties reference here.

Masks

A Mask is a parameter set that can be swapped out for your clothing asset.



This parameter set represents the following Targets (or parameter sets):

Max Distance is the maximum distance any point on the cloth can move from its animated position.

Backstop Distance is the offset used from any point on the cloth to limit movement within the Max Distance.

Backstop Radius uses a sphere radius that when intersected with the Max Distance will prevent any painted point on the cloth from moving into that region.

Anim Drive Multiplier is used to drive springs that pull clothing towards its animated position, giving control to animators in cinematics or animation-driven scenes.

This can also be driven at runtime using the interactor object that Blueprints can access on Skeletal Mesh Components.

The value set at runtime is multiplicatively combined with the painted values to get the final spring and damper strengths.

You can have multiples of each of these Targets but only one of each can be assigned at a time. This makes it possible to test different configurations very quickly in a non-destructive way.

To create a Mask and assign it to a Target, perform the following steps:

Click the Plus (+) button to create a new empty Mask.



Right-click on the New Mask and hover the mouse over Set Target to select from the available Targets list.



In the Mask window, you will now see the Target you selected listed as an active target for your cloth asset.



You can also rename the Mask by clicking on the default name in the window and entering a new name.



You can also copy Skeletal Mesh Vertex Colors to the selected Clothing Parameter Mask via the context menu:



For additional information about masks, see the Mask Properties reference here.

Copy Clothing from Skeletal Mesh

If you have multiple Skeletal Meshes of a similar type, for example, the cape on a character, you can use the Copy Clothing from SkeletalMesh option to copy and import the settings you've defined for cloth setup to another, saving you time by not requiring you to set up all parameters from the beginning.



Under Clothing Data, click Copy Clothing from SkeletalMesh and choose the Skeletal Mesh you want to copy clothing data from.

Clothing Asset Creation Menus

Section Selection

Clothing Panel

Clothing Data

Masks

Config

Import

Cloth Painting

The Cloth Paint Tools have many options and properties that you can use to make very specific clothing simulations. Below you'll find the details about the menu options you can use when creating your clothing assets and details about the Cloth Paint panel that you will use when selecting different painting tools to paint cloth values for your render mesh.

Clothing Asset Creation Menus

In this section, you'll find the details about the properties and settings you can use when creating and applying your clothing assets to your render mesh.

Section Selection

The Section Selection menu is available by right-clicking a selected section. It enables you to select the different material elements of your render mesh to create and apply a clothing asset. In this menu, you can identify the LOD and a material section of your mesh that you've selected, create a cloth asset for your render mesh and its LODs, apply the clothing asset to the selected section, and remove it later if needed.



Property

Description

LOD Section Selection

The name of the LOD level used and the Section to create a Cloth Asset for.

Apply Clothing Asset

Select a clothing asset to apply to the selected section.

Remove Clothing Asset

Remove the currently assigned clothing asset.



Create Clothing Asset from Section



Create a new clothing asset using the selected section as a simulation mesh.





Basic



Asset Name

The name entered for the cloth section asset.

Remove from Mesh

Whether or not to leave this section behind (if driving a mesh with itself). Enable this is driving a high-poly mesh with a low-poly mesh.



Collision



Physics Asset

Physics Asset to extract collisions from. Note that this will export Sphere and Sphylls, but does support up to 32 convex faces (or 5 boxes).





Create Clothing Asset from LOD Section



Create a clothing simulation mesh from the selected section and add its LOD to an existing clothing asset.





Target



Remap Parameters

If reimporting, this will map the old LOD parameters to the new LOD mesh. If adding a new LOD, this will map the parameters from the preceding LOD.

Target Asset

This is the target asset when importing LODs.

LOD Index

Replace LOD

Replace the simulation mesh in LOD0 of your selected clothing asset with this section.

Add LOD

Use the selected section to add a new LOD.



Basic



Remove from Mesh

Whether or not to leave this section behind (if driving a mesh with itself). Enable this if driving a high-poly mesh with a low-poly one.



Generate section # up to LOD #

Generated LODs will use section # up to LOD #, and ignore it for lower quality LODs

Clothing Panel

The Clothing panel houses all the clothing data, masks, configuration parameters for how your cloth reacts, and the tools you'll use when painting your cloth values.



Clothing Data

The Clothing Data category displays your currently created clothing assets that are assigned to a render mesh,enables you to copy clothing data from an existing skeletal mesh, and lets you select from the available LODs created for your mesh to adjust parameter values.



Property

Description

Name

The name of the cloth asset created for a LOD section of your physical mesh.

Copy Clothing from SkeletalMesh

Enables you to select a skeletal mesh from which to copy clothing data.

Level of Detail (LOD) Selection

Enables you to select a Level of Detail (LOD) mesh to set parameters, paint values, or copy values to.

Masks

The Masks category displays any created parameter sets for painted cloth values. These can be assigned a Target value for use with your clothing asset.



Property

Description

Name

The name given to the mask along with its target setting for this parameter set.



Context Menu Settings





Set Target



None

The target has not been set for this parameter set.

Max Distance

This is the maximum distance the clothing simulation particle can move from its animated position.

Backstop Distance

This is the distance offset from the Max Distance used to limit the movement of the cloth simulation particles.

Backstop Radius

This is a radius that when intersected with the Max Distance will prevent any cloth simulation particle from moving into that area.



Actions



Move Up

Moves the Mask up one slot in the list.

Move Down

Move the Mask down one slot in the list.

Delete

Deletes the Mask from the list.

Apply

Applies the Mask to the physical mesh.



Plus (+)

Adds a new Mask to the available list of Mask parameters.

Config

The Config properties enable you to adjust how your cloth reacts so that it can simulate different types of material, such as burlap, rubber, leather, and much more.



Property

Description

Physics Asset

The Physics Asset to extract collisions from when building a simulation.

Wind Method

How wind should be processed; Accurate uses drag and lift to make the cloth react differently, Legacy applies similar forces to all clothing without drag and lift (similar to APEX).

Legacy

Use the Legacy wind mode, where accelerations are modified directly by the simulation with no regard to drag or lift.



Vertical Constraint Config

Constraint data for vertical constraints.

Stiffness

How stiff this constraint is between the nodes. This affects how closely it will follow the desired position.

Stiffness Multiplier

This is a multiplier affecting the Stiffness value used.

Stretch Limit

The hard limit on how far this constraint can stretch.

Compression Limit

The hard limit on how far this constraint can compress.



Horizontal Constraint Config

Constraint data for horizontal constraints.

Stiffness

How stiff this constraint is between the nodes. This affects how closely it will follow the desired position.

Stiffness Multiplier

This is a multiplier affecting the Stiffness value used.

Stretch Limit

The hard limit on how far this constraint can stretch.

Compression Limit

The hard limit on how far this constraint can compress.



Bend Constraint Config

Constraint data for bend constraints.

Stiffness

How stiff this constraint is between the nodes. This affects how closely it will follow the desired position.

Stiffness Multiplier

This is a multiplier affecting the Stiffness value used.

Stretch Limit

The hard limit on how far this constraint can stretch.

Compression Limit

The hard limit on how far this constraint can compress.



Shear Constraint Config

Constraint data for shear constraints.

Stiffness

How stiff this constraint is between the nodes. This affects how closely it will follow the desired position.

Stiffness Multiplier

This is a multiplier affecting the Stiffness value used.

Stretch Limit

The hard limit on how far this constraint can stretch.

Compression Limit

The hard limit on how far this constraint can compress.



Self Collision Radius

The size of self-collision spheres centered on each vertice.

Self Collision Stiffness

The stiffness of the spring force that will resolve self-collisions.

Self Collision Cull State

The scale to use for the radius of the culling checks for self-collisions. Any other self-collision body within the radius of this check will be culled. This helps performance with higher resolution meshes by reducing the number of colliding bodies within the cloth. Reducing this will harm performance.

Damping

The damping of particle motion per-axis.

Friction

The friction of the surface when colliding.

Wind Drag Coefficient

The drag coefficient for wind calculations, where higher values mean wind has a more lateral effect on cloth.

Wind Lift Coefficient

The lift coefficient for wind calculations, where higher values make cloth rise easier in the wind.

Linear Drag

The drag applied to linear particle movement per-axis.

Angular Drag

The drag to angular particle movement, where higher values should limit material bending (per-axis).

Linear Inertia Scale

The scale for linear particle inertia, or how much movement should translate to linear motion (per-axis).

Angular Inertia Scale

The scale for angular particle inertia, or how much movement should translate to angular motion (per-axis).

Centrifugal Inertia Scale

The scale for centrifugal particle inertia, or how much movement should translate to angular motion (per-axis).

Solver Frequency

The frequency of the position solver, where lower values will lead to stretchier, bouncier cloth.

Stiffness Frequency

The frequency for stiffness calculations, where lower values will degrade stiffness of constraints.

Gravity Scale

The scale of gravity effect on the cloth particle simulation.

Gravity Override

The direct gravity override value

Tether Stiffness

The scale for stiffness of particle tethers between each other.

Tether Limit

The scale for the limit of particle tethers (how far they can separate).

Collision Thickness

The "thickness" of the simulated cloth, which is used to adjust collisions.

Anim Drive Spring Thickness

Default spring thickness if an anim drive is in use.

Anim Drive Damper Thickness

Default damper thickness if an anim drive is in use.

Import

The Import option displays the file path of any imported APEX files.



Property

Description

Imported File Path

If this asset was imported from a file, this will be the original path.

Cloth Painting

The Cloth Painting section enables you to select between your different tools, such as brush, gradient, smooth, and fill.

Before these properties can be populated, you must first select a clothing asset from your Clothing Data window and then click the Activate Paint Tools button in the toolbar.



The type of tool to use when painting cloth values.

Brush

Gradient

Smooth

Fill

The Brush tool enables you to paint a radius and strength value on your cloth as you drag across cloth asset.



Property

Description



View



View Min

When painting float/1D values, this is considered the zero or black point for painted values.

View Max

When painting float/1D values, this is considered the one or white point for painted values.

Autoview Range

When set, the view min and max values will be calculated from the values present in the currently editable mask.



Advanced Rollout



Flip Normal

Whether to flip normals on the mesh preview.

Cull Backface

Whether to cull back-facing triangles when rendering the mesh preview.

Opacity

The opacity value of the mesh preview enables you to see through the mesh.



Visualization



Vertex Preview Size

Size of vertex points drawn when mesh painting is active.



Tool Settings



Paint Value

The value to paint onto the mesh for this parameter.



Brush



Radius

The radius of the Brush used for painting.

Strength

The strength of the brush (0.0 - 1.0).

Falloff

The amount of fall off to apply (0.0 - 1.0).

Enable Brush Flow

Enables "flow" painting where the paint is continually applied from the brush every tick.

Ignore back-facing

Whether back-facing triangles should be ignored when painting.

The Gradient tool enables you to paint a gradual blend between a set of cloth values that are selected.



Property

Description



View



View Min

When painting float/1D values, this is considered the zero or black point for painted values.

View Max

When painting float/1D values, this is considered the one or white point for painted values.

Autoview Range

When set, the view min and max values will be calculated from the values present in the currently editable mask.



Advanced Rollout



Flip Normal

Whether to flip normals on the mesh preview.

Cull Backface

Whether to cull back-facing triangles when rendering the mesh preview.

Opacity

The opacity value of the mesh preview enables you to see through the mesh.



Visualization



Vertex Preview Size

Size of vertex points drawn when mesh painting is active.



Tool Settings



Gradient Start Value

The value of the gradient at the start points.

Gradient End Value

The value of the gradient at the end points.

Use Regular Brush

Enables the painting of selected points using a brush rather than a point.



Brush



Radius

The radius of the Brush used for painting.

Strength

The strength of the brush (0.0 - 1.0).

Falloff

The amount of falloff to apply (0.0 - 1.0).

Enable Brush Flow

Enables "flow" painting where the paint is continually applied from the brush every tick.

Ignore back-facing

Whether back-facing triangles should be ignored when painting.

The Smooth tool enables you to blur or soften the contrast between painted cloth values.



Property

Description



View



View Min

When painting float/1D values, this is considered the zero or black point for painted values.

View Max

When painting float/1D values, this is considered the one or white point for painted values.

Autoview Range

When set, the view min and max values will be calculated from the values present in the currently editable mask.



Advanced Rollout



Flip Normal

Whether to flip normals on the mesh preview.

Cull Backface

Whether to cull back-facing triangles when rendering the mesh preview.

Opacity

The opacity value of the mesh preview enables you to see through the mesh.



Visualization



Vertex Preview Size

Size of vertex points drawn when mesh painting is active.



Tool Settings



Strength

The strength of the smoothing (blurring) effect when painting.



Brush



Radius

The radius of the Brush used for painting.

Strength

The strength of the brush (0.0 - 1.0).

Falloff

The amount of falloff to apply (0.0 - 1.0).

Enable Brush Flow

Enables "flow" painting where the paint is continually applied from the brush every tick.

Ignore back-facing

Whether back-facing triangles should be ignored when painting.

The Fill tool enables you to replace areas with similar values with another value.



Property

Description



View



View Min

When painting float/1D values, this is considered the zero or black point for painted values.

View Max

When painting float/1D values, this is considered the one or white point for painted values.

Autoview Range

When set, the view min and max values will be calculated from the values present in the currently editable mask.



Advanced Rollout



Flip Normal

Whether to flip normals on the mesh preview.

Cull Backface

Whether to cull back-facing triangles when rendering the mesh preview.

Opacity

The opacity value of the mesh preview enables you to see through the mesh.



Visualization



Vertex Preview Size

Size of vertex points drawn when mesh painting is active.



Tool Settings



Threshold

Threshold for fill operation that will keep filling until sampled vertices aren't within this range of the original vertex.

Fill Value

The value to fill all select vertices to.



Brush



Radius

The radius of the Brush used for painting.

Strength

The strength of the brush (0.0 - 1.0).

Falloff

The amount of falloff to apply (0.0 - 1.0).

Enable Brush Flow

Enables "flow" painting where the paint is continually applied from the brush every tick.

Ignore back-facing

Whether back-facing triangles should be ignored when painting.

Steps

Steps



These options create basic collision shapes:



Once a simple collision shape is created, it can be moved, rotated, and scaled into the desired position. You can create more than one collision shape for more complex Static Meshes.

Control

Action

W, E, R

Switch between Translation, Rotation, and Scale tools.

Delete

Will delete the currently selected Physics Body or Bodies.

F

Will focus on the currently selected Physics Body or Bodies.

Ctrl + Left Click

Adds a Physics Body to the selection.

Alt + Left Drag (On a manipulation widget)

Duplicates a Physics Body.

Steps

End Result

In the following How-To we will take a look at using the Auto Convex Collision tool to automatically create collision for Static Meshes.

The Auto Convex Tool also uses a newer version of V-HACD library that should give more accurate results.

Steps

First open up the Static Mesh you want to add collision to in the Static Meshes Editor. For this example, we will be using the SM_Rock Mesh that comes with the Starter Content.

Next, open up the Auto Convex Collision tool by going to Collision > Auto Convex Collision. This will open up the Auto Convex Collision in the lower right-hand corner of the Static Mesh Editor.

Inside of the Auto Convex Collision tool set the following parameters with the following settings:

Property Name

Value

Hull Count

32

Max Hull Verts

16

Hull Precision

50,000

When all of the above settings have been input, click the Apply button to begin the collision creation process.

Computation of the collision will now run as background task in the Static Mesh Editor. The progress of the collision creation will be shown in the following progress window.

End Result

When completed you can view the new collision, if not already enabled, by clicking on the Collision icon and then selecting the Simple Collision option from the drop-down list.





The following image sequence shows what type of results you get when increasing the values of the Auto Convex Collision from the default settings to the maximum settings allowed.

Auto Convex Collision Settings Results



Presets

There will be times where 6 Object Response Channels and 2 Trace Response Channels simply are not granular enough for what you want to create. This is what the Collision Editor in your Project Settings is for. You can access them from the Edit Menu -> Project Settings -> Collision:





From here you can add new Object Response Channels and Trace Response Channels. Click the New Object Channel... or New Trace Channel... button, provide a name, select a Default Response, and click Accept.



You can have up to 18 Custom Object Response Channels or Custom Trace Response Channels.

Presets

Custom Presets can also be set here by expanding the Preset Category and clicking the New... button.



From here you can name your preset, enable or disable collision, select your preset's Object Type, and finally define the behavior of each Response Channel for the selected Object Type.

Steps

Result

Often you will find a need for more than just the two default Trace Response channels (Visibility and Camera), perhaps you have a special laser that needs to pass through a special opaque object that you can't see through or have the camera clip through. When you encounter a situation like this you can add your own custom Trace Response channels by following the steps below.

Steps

Open your project settings: Edit Menu -> Project Settings.



Under Engine select Collision:



Click the New Trace Channel... button. Name your new Trace Channel and set its Default Response. Click the Accept button.

The Default Response can be Block, Overlap, or Ignore. Depending on your use case you'll want to choose carefully to prevent as much additional work adjusting collision profiles on your Actors.

Any Blueprints open in the Blueprint Editor will have to be closed down and re-opened for the new Trace Channel to appear on any components or nodes.

Result

You'll now have a new Trace Channel to use anywhere in the editor. Any Actors or Components you want to be able to Trace with your new Channel will have to be set to block the new Channel.

Steps

Steps



There are a series of menu options in the Static Mesh Editor under the Collision menu entry, named ##DOP, these are the K-DOP simple collision generators. K-DOP is a type of bounding volume, which stands for K discrete oriented polytope (where K is the number of axis aligned planes). Basically it takes K axis-aligned planes and pushes them as close to the mesh as it can. The resulting shape is used as a collision hull. In the Static Mesh Editor K can be:

10 - Box with 4 edges beveled - you can choose X- Y- or Z-aligned edges.

18 - Box with all edges beveled.

26 - Box with all edges and corners beveled.

See below for an example. This tool is quite handy for packages full of pipes, pillars, and railings:



Here are a couple of console commands you can use while in game to give you information on the collision in your game.

Run your game.

Hit the ` (back tick/tilde key) to bring up the console input box.

Enter one of the following commands:

show COLLISION - This will draw all collision models and blocking volumes in use in the level.



stat game - This shows you various useful stats on how long different types of collision are taking.



Interactions

Common Collision Interaction Examples

Collision

Collision and Simulation Generates Hit Events

Overlap and Ignore

Overlap and Generate Overlap Events

Collision Responses and Trace Responses form the basis for how Unreal Engine 4 handles collision and ray casting during run time. Every object that can collide gets an Object Type and a series of responses that define how it interacts with all other object types. When a collision or overlap event occurs, both (or all) objects involved can be set to affect or be affected by blocking, overlapping, or ignoring each other.

Trace Responses work basically the same way, except the trace (ray cast) itself can be defined as one of the Trace Response types, thusly allowing Actors to either block it or ignore it based on their Trace Responses.

Interactions

There are a few rules to keep in mind with how collisions are handled:

Blocking will naturally occur between two (or more) Actors set to Block. However, Simulation Generates Hit Events needs to be enabled to execute Event Hit, which is used in Blueprints, Destructible Actors, Triggers, etc...

Setting Actors to Overlap will often look like they Ignore each other, and without Generate Overlap Events, they are essentially the same.

For two or more simulating objects to block each other, they both need to be set to block their respective object types.

For two or more simulating objects: if one is set to overlap an object, and the second object is set to block the other, the overlap will occur but not the block.

Overlap events can be generated even if an object Blocks another, especially if traveling at high speeds.

It is not recommended for an object to have both collision and overlap events. Though possible, there is much that needs manual handling.

If one object is set to ignore and the other is set to overlap, no overlap events will be fired.

For purposes of testing levels and looking around your worlds:

The default Play In Editor camera is a pawn. Thusly can be blocked by anything set to block pawns.

The Simulate in Editor camera, before possessing anything, is not a pawn. It can freely clip through everything and will not create any collision or overlap events.

Common Collision Interaction Examples

These interactions assume that all the objects have Collision Enabled set to Collision Enabled so they are set to fully collide with everything. If collision is disabled, it is as if ignore has been set for all Collision Responses.

For the following section, this will be the setup used to explain what is happening:



The sphere is a PhysicsBody and the box is WorldDynamic, and by changing their collision settings we can get a number of behaviors.

Collision

By setting both of their collision settings to block each other, you get a collision, great for having objects interact with each other:



Sphere Collision Setup

Wall Collision Setup





In this case, the sphere is a PhysicsBody and it is set to block WorldDynamic (which is what the wall is).

The wall is a WorldDynamic and is set to block PhysicsBody Actors (which is what the sphere is).

In this case, the sphere and the wall will simply collide; no further notifications of the collision will take place.

Collision and Simulation Generates Hit Events

Just collision is useful and in general, the bare minimum for physics interactions, but if you want something to report it has collided so a Blueprint or section of code can be triggered:



Sphere Collision Setup

Wall Collision Setup





As in the example above, the sphere is a PhysicsBody and it is set to block WorldDynamic (which is what the wall is). However, the sphere has also enabled Simulation Generates Hit Events so it will trigger an event for itself whenever it collides with something.

The wall is a WorldDynamic and is set to block PhysicsBody Actors (which is what the sphere is). Since the wall is not set to Simulation Generates Hit Events, it will not generate an event for itself.

With the sphere set to Simulation Generates Hit Events, the sphere will tell itself that it has had a collision. It will fire off events such as ReceiveHit or OnComponentHit in the sphere's Blueprint. Now if the box had an event for collision, it would not fire because it will never notify itself it has happened.

Further, an object that is reporting rigid collisions will report them all and spam reports when it is just sitting on something, so it is best to be careful to filter what it is colliding within its Blueprint or in code.

Overlap and Ignore

For all intents and purposes, Overlap and Ignore work exactly the same assuming Generate Overlap Events is disabled. In this case, the sphere is set to overlap or ignore the box:



Sphere Collision Setup

Wall Collision Setup





Here the sphere is set to overlap WorldDynamic Actors (like our wall), but it does not have Generate Overlap Events enabled. As far as the sphere is concerned, it has not collided or overlapped anything, effectively it has ignored the wall.

The wall is a WorldDynamic and is set to block PhysicsBody Actors (which is what the sphere is). As stated above, both Actors need to be set to block each other's respective object types. If they do not, they will not collide.

Or:

Sphere Collision Setup

Wall Collision Setup





Here the sphere is set to ignore WorldDynamic Actors (like our wall), and it will pass through the wall.

The wall is a WorldDynamic and is set to block PhysicsBody Actors (which is what the sphere is). As stated above, both Actors need to be set to block each other's respective object types. If they do not, they will not collide.

Overlap and Generate Overlap Events

Unlike collisions that can fire every frame, the overlap events are ReceiveBeginOverlap and ReceiveEndOverlap, which only fire in those specific cases.

For an overlap to occur, both Actors need to enable Generate Overlap Events. This is for performance. In the case where both the Sphere and the Box want overlaps when we move either the Sphere or the Box, we do an overlap query to see if we need to fire any events.

If the Box doesn't want overlaps then when it moves we will not do an overlap query. But now we could be overlapping with the Sphere, and so the Sphere would need to tick and check for overlaps each frame in case someone moved into them.



Sphere Collision Setup

Wall Collision Setup





Here the sphere is set to overlap WorldDynamic Actors (like our wall), and it will generate an event for itself when it does overlap something.

The wall is a WorldDynamic and is set to block PhysicsBody Actors (which is what the sphere is). As stated above, both Actors need to be set to block each other's respective object types. If they do not, they will not collide. But, an Overlap does occur here, and events for the sphere and box are fired.

Properties

Collision Presets

There are a large number of properties and settings in the Collision Presets/Collision Response section of the Collision Properties category, so they've been separated out for clarity.

Properties

Below are the properties for the Collision Presets, a sub-category in the Collision Properties on Physics Bodies (BodyInstances).



Collision Presets

Property

Description

Collision Presets

The default collision profiles and any you have created in Project Settings -> Engine -> Collision -> Preset (see: Add a Custom Object Type to Your Project for information on creating custom collision profiles), will appear here.

Property

Description

Default

Use the settings that were applied to the Static Mesh in the Static Mesh Editor.

Custom...

Set all custom collision settings for this instance.

NoCollision

No Collision.

BlockAll

WorldStatic object that blocks all actors by default. All new custom channels will use its own default response.

OverlapAll

WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response.

BlockAllDynamic

WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response.

OverlapAllDynamic

WorldDynamic object that overlaps all actors by default. All new custom channels will use its own default response.

IngoreOnlyPawn

WorldDynamic object that ignores Pawn and Vehicle. All other channels will be set to default.

OverlapOnlyPawn

WorldDynamic object that overlaps Pawn, Camera, and Vehicle. All other channels will be set to default.

Pawn

Pawn object. Can be used for capsule of any playable character or AI.

Spectator

Pawn object that ignores all other actors except WorldStatic.

CharacterMesh

Pawn object that is used for Character Mesh. All other channels will be set to default.

PhysicsActor

Simulating actors.

Destructible

Destructible actors.

InvisibleWall

WorldStatic object that is invisible.

InvisibleWallDynamic

WorldDynamic object that is invisible.

Trigger

WorldDynamic object that is used for trigger. All other channels will be set to default.

Ragdoll

Simulating Skeletal Mesh Component. All other channels will be set to default.

Vehicle

Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.

UI

WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response.

Collision Enabled

Collision Enabled can have 4 possible states as listed below.

Property

Description

No Collision

This body Will have no representation in the physics engine. It cannot be used for spatial queries (raycasts, sweeps, overlaps) or simulation (rigid body, constraints). This setting gives the best performance possible, especially for moving objects.

Query Only

This body is used only for spatial queries (raycasts, sweeps, and overlaps). It cannot be used for simulation (rigid body, constraints). This setting is useful for character movement and objects that do not need physical simulation. Some performance gains are made by reducing the data in the physics simulation tree.

Physics Only

This body is only for physics simulation (rigid body, constraints). It cannot be used for spatial queries (raycasts, sweeps, overlaps). This setting is useful for simulated secondary motion on characters that do not need per bone detection. Some performance gains are made by reducing the data in the query tree.

Collision Enabled

This body can be used for both spatial queries (raycasts, sweeps, overlaps) and simulation (rigid body, constraints).

Object Type

Property

Description

WorldStatic

This should be used for any Actor that doesn't move. Static Mesh Actors are a good example of an Actor that will probably have a WorldStatic type.

WorldDynamic

WorldDynamic is for Actor types that will be moving under the influence of animation or code; kinematic. Lifts and doors are good examples of WorldDynamic Actors.

Pawn

Any player controlled entity should have the Pawn type. The player's character is a good example of an Actor that should receive the Pawn Object Type.

PhysicsBody

Any Actor that will be moving due to the physics simulation.

Vehicle

Vehicles receive this type by default.

Destructible

Destructible Meshes receive this by default.

Collision Responses

These define how this Physics Body should interact with all of the other types of Trace and Object Types. Remember, it's the interaction between both Physics Bodies that define the resulting action, so the Object Type and Collision Responses of both Physics Bodies matter.



Response

Description

Ignore

Regardless of the Collision Response of the other Physics Body, this Physics Body will ignore the interaction.

Overlap

If the other Physics Body is set to Overlap or Block this Physics Body's Object Type, an Overlap Event can occur.

Block

If the other Physics Body is set to Block this Physics Body's Object Type, a Hit Event can occur.

Trace Responses

Trace responses are used in Traces (ray casts), such as the Blueprint Node Line Trace by Channel.

Property

Description

Visibility

General visibility testing channel.

Camera

Usually used when tracing from the camera to something.

Object Responses

Property

Description

WorldStatic

How this Physics Body should react when interaction with a WorldStatic Physics Body Object Type.

WorldDynamic

How this Physics Body should react when interaction with a WorldDynamic Physics Body Object Type.

Pawn

How this Physics Body should react when interaction with a Pawn Physics Body Object Type.

PhysicsBody

How this Physics Body should react when interaction with a PhysicsBody Physics Body Object Type.

Vehicle

How this Physics Body should react when interaction with a Vehicle Physics Body Object Type.

Destructible

How this Physics Body should react when interaction with a Destructible Physics Body Object Type.

Usage

In Unreal Engine, you have access to simple and complex collision shapes. Simple Collision are primitives like cubes, spheres, capsules, and convex hulls. Complex Collision is the trimesh of a given object. By default, Unreal Engine creates both simple and complex shapes, then, based on what the user wants (complex query versus simple query), the physics solver will use the corresponding shape for scene queries and collision tests.

Usage

In the Static Mesh Editor's Details panel, you can find the settings for Collision Complexity in the Collision category.



Setting

Description

Project Default

Using the project's physics seetings, this will cause simple collision requests to use simple collision, and complex requests to use complex collision; the "default" behavior.

Simple And Complex

This flag enables the creation of simple and complex shapes, using simple shapes for regular scene queries and collision tests, and using complex (per poly) shapes for complex scene queries.

Use Simple Collision As Complex

This means that if a complex query is requested, the engine will still query against simple shapes; basically ignoring the trimesh. This helps save memory since we don't need to bake the trimesh and can improve performance if the collision geometry is simpler.

Use Complex Collision As Simple

This means that if a simple query is requested, the engine will query against complex shapes; basically ignoring the simple collision. This allows us to use the trimesh for the physics simulation collision. Note that if you are using UseComplexAsSimple you cannot simulate the object, but you can use it to collide with other simulated (simple) objects.

For example, in the image below the chair on the left has simple collision, and when the Pawn above it falls onto it, it will slide off the large angled surface that covers the seat. However; the chair on the right is using Use Complex Collision As Simple, and when the Pawn above it falls, it will land on the seat of the chair and stay there.



Getting Started:

Reference Guide

Tutorials

Unreal Engine 5 includes a set of tools for simulating 2D and 3D fluid effects in real time. These systems use physically-based simulation methods to produce realistic effects for things such as fire, smoke, clouds, rivers, splashes, and waves breaking on a beach.

The toolset is designed to be artist-friendly and an open platform for experimentation by utilizing simulation stages, reusable modules, and robust Data Interfaces.

Artists can achieve their desired results in real time by modifying only a few parameters, while advanced users and R&D engineers can dive in and break apart the simulators to try new algorithms.

You can learn more about Niagara and Fluid Simulation by going to the Niagara VFX System documentation.

This page provides a starting point to learn about fluid simulation in Unreal Engine.

Getting Started:



Overview of Fluid Simulation in Unreal Engine.



A quick start guide for using the Niagara Fluids plugin to create real-time fluid simulation.

Reference Guide



Reference guide for the Niagara Fluids plugin.

Tutorials



Starting point to learn about fluid simulation tutorials in Unreal Engine.

Intended Audience

Effects Artist

Effects Developers

R&D Developers

Key Concepts of Fluid Simulation

Overview

Grids

Fluid Motion

Collision Objects

Liquids

Key Niagara Concepts

Grid Data Interfaces

Simulation Stages

Reusable Modules

Fluid Parameters

Simulator Types

2D Gas

3D Gas

2D FLIP

Shallow Water

3D FLIP

Unreal Engine 5 includes a set of tools for simulating fluid effects in real time.

This toolset is designed to be artist-friendly and includes a variety of GPU-based simulators, reusable modules, and robust data structures that are all usable within the Niagara Editor. Advanced users can take advantage of the wide range of exposed parameters to modify the simulation to their needs.

The fluid simulation system is designed to generate complex fluid effects for real-time environments that can be used in games and cinematics. The system can also be used to bake out complex simulations to flipbook textures for a variety of use cases.

Intended Audience

The various fluid (gas and liquid) simulators are designed to be useful to everyone, from graphics researchers to effects artists. Here are some applicable use cases for different types of users:

Effects Artist

Quickly place systems in a map for specific game elements or cinematics shots.

Edit, keyframe, or drive various User Parameters exposed by the actor via Blueprints.

Tweak a few system parameters to achieve the desired look.

Add appropriate forces and collision objects so the fluid responds to the world.

Make simple modifications to how fluid is injected into the fluid solver.

Effects Developers

Build custom systems starting from predefined templates to achieve the desired look.

Incorporate new forces, sourcing methods, or custom boundary conditions.

Add and modify existing modules in fluid and sourcing emitters within a system.

Profile and make changes to improve performance for specific systems.

Build or modify systems and expose user parameters to empower artists on the team.

R&D Developers

Design complex fluid behaviors by writing HLSL shader code to extend the base emitters.

Modify all aspects of the simulation algorithm by modifying or replacing existing modules.

Try new algorithms and quickly test them in the Niagara Editor or maps.

Build new systems and package parameters with User Parameters and Summary View.

Key Concepts of Fluid Simulation

Overview

Fluid simulation is the process of algorithmically generating data that represents the motion of fluids, such as gases or liquids. This simulation data can either be represented as grids or particles, depending on the algorithms used.

The Unreal Engine Fluid Simulation system uses grids to simulate gases, and a mixture of particles and grids for liquids.

Grids

Gas simulations are represented by a grid, in which each cell contains data representing the density, temperature, and velocity of the medium at that location. Smaller grid cells sizes result in a higher quality simulation, however this increased quality comes with an increase in computational cost.

When rendering a smoke simulation, you are generally visualizing the density grid. Areas that have higher density are more opaque compared to areas with lower density. Fire simulations function similarly, where temperature controls the color of the fire in each grid cell. Within fire simulations, higher temperatures cause gas to rise faster due to buoyancy.

Fluid Motion

One of the main components in simulating fluids with realistic movement, is the process of "solving for pressure". This technique involves solving a system of equations that are designed to ensure the fluid correctly flows around objects and results in a realistic swirling motion.

This simulation involves an iterative process, with more iterations resulting in a more accurate simulation. However, more iterations will result in a higher computational cost. It is important to note that sometimes the technique of "pressure solving" can affect forces added to a simulation and dampen their effect.

Collision Objects

In order to have the fluid respond to nearby objects, you must first set up what is known as "boundary conditions".

Setting boundary conditions for the simulation involves masking out areas where objects are located within the simulation area, to ensure that no fluid can occupy the same space. These collision objects can move around in the scene and their velocity is used to displace the fluid around them.

A common example involves an object falling into a pool of liquid, causing splashes and ripples around the object. The system can use many object types as colliders, such as static meshes, Geometry Collections, and depth maps.

Liquids

Niagara Fluids use a hybrid particle and grid algorithm called FLIP (Fluid-Implicit-Particle) to simulate liquids, such as flowing water. In this system, the velocity of the fluid is solved on a grid, and then sampled back to particles that represent the shape of the fluid.

Note that there are several similarities between liquid and gas simulations, so the previous sections on collision objects and fluid motion apply to liquids as well.

Key Niagara Concepts

All the fluid simulators are accessible from the Niagara Editor, and make use of a variety of Niagara features.

To learn more about the Niagara VFX System, visit the documentation.

Grid Data Interfaces

Grid 2D Collection and Grid 3D Collection are data interfaces for storing named attributes in 2D and 3D grids, respectively. These are used for all the required computations when solving fluids.

Simulation Stages

For each step in the gas or liquid simulation algorithm, the Unreal Engine Fluid Simulation system makes sure all grid cells are processed before moving on to the next step. The system uses what are known as Simulation Stages within Niagara to do this. Note that Simulation Stages can be run several times before proceeding to the next stage by modifying the stage's Num Iterations attribute.

Reusable Modules

Much of the fluid behavior is defined in modules, which can be moved around in the Niagara System stack. Some modules are used across 2D, 3D, gas, and liquid simulators, and are generally written to be very generic. Advanced users can modify core fluid solver behavior by modifying or replacing various modules.

Fluid Parameters

All of the template systems exposed in the New Niagara System menu have user parameters that allow for modification on the actor when placed in a map. Values can be edited directly in the Details panel. There are more parameters exposed on the fluid emitter's Summary View, which can be modified in the Niagara editor.

Simulator Types

2D Gas

This is a gas simulation where flow only occurs in a two-dimensional space. These simulations are generally much faster than 3D simulations and are best suited for games and real-time use. However, they generally lack the complex turbulent flow that 3D simulations can exhibit.

It is important to note that 3D objects can interact with 2D simulations. These types of simulations can be set to always be oriented toward the camera and mimic 3D behavior. This is commonly used when creating torches or other flame effects where depth is necessary.

2D gas simulations are rendered on planes that are either camera facing or oriented in the world.

3D Gas

This is the most common type of gas simulation. Compared to its 2D counterpart, 3D Gas simulates depth and a more complex flow at a higher memory and GPU cost.

This type of simulator is best used for hero effects in real-time applications, and for cinematics. The results can also be baked into textures for increased performance in real time.

Gas simulations that use baked lighting accomplish self-shadowing by baking the shadows into a grid. This data is then passed to the material for rendering. Ray marching materials are responsible for generating images of the volume by accumulating visible density and temperature.

2D FLIP

2D FLIP samples 3D particles and generates a 2D simulation domain where pressure is solved and the FLIP algorithm is applied to update the particles. Typically, the domain is camera aligned, which allows for complex 3D-looking flow, despite the use of 2D fluid forces. This can be used for simulating convincing splash effects, but not for pools of water.

2D FLIP simulations are generally rendered as 3D particles.

Shallow Water

Unlike 2D FLIP, Shallow Water is useful for simulating pools of water that don't contain many splash effects. This can be used to simulate boat wakes, or simple interactions with objects moving through the water.

Shallow Water simulations are height fields that are rendered as displacements to a water surface.

3D FLIP

3D FLIP simulations are robust liquid simulations that are capable of simulating a wide range of effects, such as waves on a beach, rivers, and complex object interactions. Note that these complex simulations can be computationally expensive. These are particle simulations where velocities are determined by a grid solver that ensures the fluid doesn't compress.

3D FLIP simulations are rendered by splatting particles into a grid, then rendering the grid as a surface using ray marching.

Simulating hair in a realistic manner

Solving the Constraints

Handling Collisions

Simulating hair in a realistic manner



The Unreal Engine's Hair rendering and simulation system uses a strand-based workflow to render each individual strand of hair with physically accurate motion. It enables artists to simulate and render hundreds of thousands (or more) photoreal hairs in real-time for grooms created in DCC packages. Real hair and fur moves in a specific way when reacting to head and body movement, wind, gravity, and other forces. Achieving realistic hair and fur animation is generally accomplished by using a physics-based simulation. Running such a complex simulation at runtime can be very computationally expensive.

Hairs are challenging to simulate because of their large numbers and the complexity of the motion, both with object collisions and self-collisions.

Hair dynamics rely on complex interdependencies. In the case of animal fur, muscle and flesh simulation is responsible for a large portion of the fur motion and hair simulation itself.

When rendering and simulating realistic hair, the system uses specific "guides" to reduce the computational cost of the simulation. A guide is a subset of the total number of strands that are used for deformation. During the simulation, the guide strands are deformed and this deformation is used to interpolate movement for all the strands.

Unreal Engine uses two types of guides - rendering guides and simulation guides. Rendering guides typically provide structure to the groom, such as clumping, direction changes, and flow. These guides represent a small percentage of the total strands (typically between 5 to 10%). Manually selecting the best guides will significantly improve the quality of the deformation compared to a random sample of strands.

Simulation guides drive the shape and motion of the associated strands during physical simulation. These guides are created by resampling the rendering guides and reducing the number of vertices (points) per strand. You can set the number of points per strand to 4, 8, 16, or 32, depending on your needs.

Guides can be created in an external DCC package or inside the Unreal Engine editor. To automatically generate a guide, select the appropriate option in the Import Options window and select the percentage of strands that will be used for the guide.

Unreal Engine will select a random sample from the total strands when auto-generating the rendering guide. Manually creating the guides can significantly improve the quality of the deformation.



Hair simulation in Unreal Engine is implemented as part of the Niagara Visual Effects system. The simulation is performed on the GPU, and the solver is based on the XPBD (Position-Based Simulation of Compliant Dynamics) method.

Solving the Constraints

To solve for all the different constraints, you need to provide the number of substeps and solver iterations, alongside the strands, collisions, and constitutive model parameters. The solver will target the original mesh under gravity (rest pose) to keep the final style as close to the original style as possible.

Handling Collisions

When a physics asset is added to the Skeletal Mesh, the simulation solver handles body collisions against the primitives of that physics asset.

Self-collisions are computed based on an average velocity field built from the rasterization of the particles' velocity onto a regular voxel grid.

The system uses a mathematical model that best approximates the realistic behavior of hair strands when external forces are applied. The biggest challenge is finding a good model that enables strands to behave realistically, at low solver iteration counts.

These models control how the strands will stretch, bend, and twist during simulation. The Cosserat Rod and Angular Spring methods are available within the groom asset physics properties.

Learn more about hair simulation by going to the Hair Rendering and Simulation documentation page.

Creation

Surface Type

Usage

Material

Material Instance

Physics Asset (Skeletal Mesh)

Static Mesh

Misc

This document will cover the creation and usage of Physical Materials as well as enabling or editing Surface Types for your project.

Creation

From the Content Drawer, click Add > Physics > Physical Material or right-click in the Content Drawer > Physics > Physical Material.



Double click the NewPhysicalMaterial to edit its properties.



Adjust properties.



Click Save



See the Physical Material Reference for information on the properties of the Physical Material.

Surface Type

By default, Unreal Engine 5 supports 62 Surface Types, which can be labeled as anything you desire, stored in your project's DefaultEngine.ini, which can be found in YourProjectRoot\Config\DefaultEngine.ini.

Usage

Material

Open or create a new material.



Select the main material node.



Change the Physical Material.



Material Instance

Open or create a new Material Instance.



Change the Physical Material.



Physics Asset (Skeletal Mesh)

When adjusting the Physical Material for a Physics Asset, it is best to start by assigning the most commonly used Physical Material to all of the Physics Bodies in the Physics Asset.

Double-click a Physics Asset in the Content Drawer to open it in the Physics Asset Editor.



In the Physics Asset Editor, select a Physical Material from the Physical Material dropdown in the toolbar.



If specific Physics Bodies need differing Physical Materials, you can then adjust them individually.

Double-click a Physics Asset in the Content Drawer to open it in the Physics Asset Editor.

Select a Physics Body.

In the Details pane, in the Physics Category, change the Simple Collision Physical Material.



The default behavior for Physics interactions with Skeletal Meshes is to only interact with its associated Physics Asset, so the Skeletal Mesh's material's Physical Material will not be used.

With Physics Assets, though you are setting the Simple Collision Physical Material, when you trace against a Physics Asset, you will need to do a complex trace and the complex trace will return the Physical Material listed in the Simple Collision Physical Material property of the hit Physics Body.

Static Mesh

Static Meshes have both Simple Collision (the Physics Bodies that you create in your 3D art package or the StaticMesh Editor) and Complex Collision (per poly collision) which can be composed of several different materials each with their differing Physical Materials.

Collision

Physical Material Order

Simple

When any collision or trace uses Simple Collision, it will reference the Physical Material on the StaticMesh that is set in the StaticMesh Editor, or if the Phys Material Override on the StaticMesh Actor is set to something other than None, it will use what is listed in that property.

Complex

When any collision or trace uses Complex Collision, it will reference the Physical Material on the Material or Material Instances applied to the StaticMesh Actor, or if the Phys Material Override on the StaticMesh Actor is set to something other than None, it will use what is listed in that property.

To set the Simple Collision Physical Material for a StaticMesh:

Double Click a Static Mesh in the Content Drawer to bring up the Static Mesh Editor.



Change the Simple Collision Physical Material property in the Static Mesh Settings category to the desired Physical Material.



Click Save



Misc



The Phys Material Override property exists on everything with a Collision category. This can be used to completely override Simple Collision Physical Materials on an Actor or Component with the selected Physical Material.

Overriding a StaticMesh's simple collision Physical Material.

Since Skeletal Meshes Physics Assets always return Simple Collision, you can use this to override all Physical Materials on a placed Skeletal Mesh Actor.

This does not affect Complex Collision traces.

Properties

Physical Material

Advanced

Destruction

Physical Properties

Vehicles

Properties

Below are the properties for Physical Materials separated by major category.

Physical Material

This category contains the core properties of the Physics Material: Friction, Restitution, and Density.



Property

Description

Friction

This is the friction value of the surface, which controls how easily things can slide on this surface.

Friction Combine Mode

This property enables you to adjust how Physical Material frictions are combined. This is set to Average by default, but can be overriden using the Override Friction Combine Mode property.

Average

Uses the average value of the touching materials: (a+b)/2

Min

Uses the smaller value of the touching materials: min(a,b)

Multiply

Multiplies the values of the touching materials: a*b

Max

Uses the larger value of the touching materials: max(a,b)

Override Friction Combine Mode

By default, the Friction Combine Mode is set to Average, by enabling this property you can change how Frictions are combined between touching Physical Materials.

Restitution

This is how "bouncy" the surface is, or how much energy it retains when it collides with another surface.

Restitution Combine Mode

This property enables you to adjust how Physical Material restitutions are combined. This is set to Average by default, but can be overriden using the Override Restitution Combine Mode property.

Average

Uses the average value of the touching materials: (a+b)/2

Min

Uses the smaller value of the touching materials: min(a,b)

Multiply

Multiplies the values of the touching materials: a*b

Max

Uses the larger value of the touching materials: max(a,b)

Override Restitution Combine Mode

By default, the Restitution Combine Mode is set to Average, by enabling this property you can change how Restitutions are combined between touching Physical Materials.

Density

Used with the shape of the object to calculate its mass properties. The higher the number, the heavier the object. Measured as g per cubic cm.

Advanced

This category contains a property to change how scale affects the mass of the Actor with the Physical Material applied to it.



Property

Description

Raise Mass To Power

Used to adjust the way that mass increases as objects get larger. This is applied to the mass as calculated based on a "solid" object. In actuality, larger objects do not tend to be solid, and become more like "shells" (e.g. a car is not a solid piece of metal). Values are clamped to 1 or less.

Destruction

Properties that are specific to the Destruction system in Unreal Engine 4.



Property

Description

Destructible Damage Threshold Scale

How much to scale the damage threshold by on any destructible this Physics Material is applied to.

Physical Properties

Gameplay related properties for the Physical Material.



Property

Description

Surface Type

Surface Types are set in the DefaultEngine.ini file for your project. They define an enum to be used in the engine for defining any number of things, from what sound plays as a character walks across a surface, to the type of decal an explosion should leave on different surfaces.

You can use ProjectSetting/Physics/Physical Surfaces

This data can be pulled in code or Blueprint:



By default, without editing the source code, you are limited to 30 Surface Types, labeled SurfaceType1 through SurfaceType30.

Vehicles

These properties are specific to Vehicles in Unreal Engine 4. While they may say they deal with Tires, they only do so when applied to a Vehicle (as Tire Data Types, and Wheel Blueprints, don't directly reference a Physical Material).



Property

Description

Tire Friction Scale

Overall tire friction scalar when this Physical Material is applied to a Vehicle. This value is multiplied against the Vehicle's Wheels' specific Friction Scale values.

Tire Friction Scales

Tire friction scales for specific Wheels when this Physical Material is applied to a Vehicle. These values are multiplied against the Vehicle's Wheels' specific Friction Scale values.

The following steps detail how to add a Physical Surface Type to your project.

In the main menu, click on Edit -> Project Settings... -> Physics -> Physical Surface Category.

Change the None in the Name field next to a SurfaceType# to a name descriptive of what you'd like the Surface Type to represent (concrete, flesh, wood, and so on).



From the Content Drawer, click +Add -> Physics -> Physical Material or right-click in the Content Drawer -> Physics -> Physical Material.



Select the Physical Material Class.



Double-click the new Physical Material to open it.



Adjust the Properties.



Click Save.

See the Physical Material Reference for information on the properties in the Physical Material.

The following steps detail how to edit an already existing Physical Material.

Double-click the Physical Material to edit its properties.



Adjust the Properties.



Click Save.

See the Physical Material for information on the properties in the Physical Material.

Open or create a new Material.



In the Material Blueprint, select the main material node.



In the Details panel, use the Physical Material dropdown to select or create a Physical Material.



Click Save.

Open or create a new Material Instance.



In the Details panel, use the Physical Material dropdown to select or create a Physical Material.



Click Save.

The following steps detail how to set the Physical Material of all Physics Bodies in a Physics Asset at once.

Double-click a Physics Asset in the Content Drawer to open it in the Physics Asset Editor.



In the main menu of the Physics Asset Editor, click Toolbar to expand the Dropdown menu and select the Physical Material to apply.



Click Save.

If specific Physics Bodies need different Physical Materials, you can adjust them individually.

Double-click a Physics Asset in the Content Browser to open it in the Physics Asset Editor.





Select a Physics Body.

In the Details panel, in the Physics category, change the Simple Collision Physical Material.



Click Save



Static Meshes have both Simple Collision (the Physics Bodies that you create in your 3D art package or in the StaticMesh Editor) and Complex Collision (per poly collision) which can be composed of several different materials each with their differing Physical Materials. To set the Complex Collision Physical Material see: Assign a Physical Material to a Material.

To set the Simple Collision Physical Material for a Static Mesh:

Double-click a Static Mesh in the Content Drawer to open it in the Static Mesh Editor.



Use the Simple Collision Physical Material dropdown in the Collision category to select the desired Physical Material.



Click Save.

Physical Materials

Traces with Raycasts

Simple versus Complex Collision

Creating Physics Assets

Opening the Physics Asset Editor

Essentials

Tutorials



The Physics Asset Editor is an integrated editor that is part of the Animation Editors in Unreal Engine. It is specifically designed to manipulate Physics Assets for Skeletal Meshes.



A Physics Asset is used to define the physics and collision used by a Skeletal Mesh. These contain a set of rigid bodies and constraints that make up a single ragdoll, which is not limited to humanoid ragdolls. They can be used for any physical simulation using bodies and constraints. Because only a single Physics Asset is allowed for a Skeletal Mesh, they can be turned on or off for many Skeletal Mesh components.





Character Physics Asset

Vehicle Physics Asset

A Physics Asset can be set up for any Skeletal Mesh for simulation. These are two examples of their usage; a humanoid character and the Buggy from Epic's demo Vehicle Game.

Creating Physics Assets

There are two ways that Physics Assets can be created for your Skeletal Meshes:

On import by having Create Physics Asset enabled.





Click image for full size.



By creating a Physics Asset using the Content Drawer and selecting a Skeletal Mesh to use.





Click image for full size.



The first time the Physics Asset is selected, a window to set how bodies and constraints should be generated will open:



Opening the Physics Asset Editor

The Physics Asset Editor can be opened in several different ways:

By double-clicking the Physics Asset in the Content Drawer.



By using the right-click context menu and selecting Edit....



By selecting the Physics tab in the Animation Editors selection tabs.



The dropdown menu next to the Physics tab can be used to select any Physics Asset located in the Content Drawer that is using the currently opened Skeletal Mesh.



Essentials





Tutorials



Physics Constraint Reference

Physics Bodies

Animation Editors

1. Toolbar

2. Skeleton Tree

3. Constraints Graph

4. Viewport

5. Asset Details / Preview Scene Settings

6. Tools and Profiles

The Physics Asset Editor is a tool used for working Physics Assets inside of Unreal Engine. This editor allows for the visualization and control over the body and constraint hierarchy associated with a Skeletal Mesh. In this editor, you can create Bodies and Constraints that are used for collision and simulation of your Skeletal Mesh ragdoll.



Please refer to each section below for a breakdown of the Physics Asset Editor user interface:

1. Toolbar

The Toolbar inside the Physics Asset Editor provides you with options for saving any changes made to your Physics Asset or locating it in the Content Drawer. You can set a Preview Mesh and/or a Preview Animation for this particular Physics Asset, Create Assets to use with your mesh, Enable / Disable Collision for selected bodies, and use the Simulation settings under the arrow dropdown menu for testing the Physics Assets ragdoll. On the far right of the Toolbar is the Editor Toolbar which enables you to switch between the different Animation Tools in Unreal Engine.

2. Skeleton Tree

The Skeleton Tree shows the skeletal hierarchy of the current Skeleton asset and is where you create bodies and constraints.

3. Constraints Graph

The Constraints Graph enables you to have a visual representation of the skeletal hierarchy bodies that are constrained to another body. From this graph, you can create your constraints by pulling off the main body node (left) and selecting a new body to constrain or even navigate the skeleton tree by double-clicking the end body to jump down the tree to the next set of bodies and constraints. You can also see which Physical Animation and Constraints Profiles are assigned based on the currently selected one in the Profiles panel.

4. Viewport

The Viewport enables you to preview the changes you make, like the position of the physics bodies. You can also preview a simulation of the bodies as a physics ragdoll. From the Viewport, you can change lighting modes, show or hide the bones, bodies, and constraints of your skeleton, and even set your Skeletal Mesh to automatically rotate around on a turntable allowing you to view it from all angles.

5. Asset Details / Preview Scene Settings

The Details panel, which is similar to the Main Editor panel, is primarily used for modifying the properties of added elements like bodies or constraints. For example, when adding a body or constraint to the Skeleton, clicking on it in the Skeleton Tree or Viewport will populate the Details panel with options related to how the body or constraint functions.

The Preview Scene Settings panel enables you to quickly assess what your assets will look like in multiple environments and light scenarios without having to set up these scenes within your level. Several different settings can be defined and applied from Skeletal Meshes and specified animations to play along with lighting and Post Process effects all within each of the Animation Tools inside of the Editor.

6. Tools and Profiles

The Tools panel displays the options available for selected physics bodies when generating them or choosing to regenerate them. These are the same options available when creating a Physics Asset from the Content Drawer. Otherwise, these are the default settings that will be used when a Skeletal Mesh is imported and Create Physics Asset is enabled.

The Profiles panel enables you to create profiles that can be reused for Physical Animations and Constraints. These profiles enable you to set default settings that can be quickly assigned to other bodies or constraints.

Physics Constraint Reference

Physics Asset Editor Interface

Physics Asset Editor - Tools and Profiles

Skeletal Hierarchy Selection Displayed in the Graph

Bodies

Constraints

Profile Assignment



The Constraints Graph shows the linkages for constraints between the selected bodies in the Physics Asset. Within it, you can perform the following actions:

Select and view bodies and constraints in the skeletal hierarchy.

Create and edit bodies and constraints using the right-click context menus.

Create constraint links using pin-dragging selection.

Assign / Unassign profiles for Physical Animation and Constraints.

Skeletal Hierarchy Selection Displayed in the Graph

When bodies or constraints are selected in the Skeleton Tree, the graph will display the currently selected ones and their connections.



The body "spine_03" is selected in the Skeleton Tree, and the Graph displays the constraints and the bodies they connect to.

Bodies

When a Body is selected, the Graph will display the following information:

Bone Name

Number of Primitive Shapes used



In this example, the Bone Name is hand_l and there is a single primitive shape.

You can double-click any Body node on the far right to move through the hierarchy list to that body and its constraints.

The node-based display in the graph enables you to drag from the output pin of the main Body (far left, hand_l) and use the selection menu to select a body to create a constraint. The same workflow can be achieved through the right-click context menus in the Skeleton Tree as well.





Pull off the Body output pin and select a Body from the list.

The resulting Constraint.

If the Graph does not update after creating or deleting a constraint, click away and then back to see the update.

Constraints

When a Constraint is selected, the Graph will display the following information:

Bone Names that are linked



Here, the Bone named lowerarm_l is constrained to hand_l.

Profile Assignment

In the Graph, you'll be able to see the Profiles that the selected bodies and constraints are assigned to.

There are two types of profiles that can be created and assigned: Physical Animation which bodies can be assigned to and Constraint ones which constraints can be assigned to. Profiles contain a set of default values for properties of bodies and constraints. When the Current Profile is set in the Profiles tab, the nodes in the Graph will indicate their assignment status of a profile for the displayed bodies and constraints.

There are two states that a node can be in indicated by its color:

Is assigned to a profile.

Is not assigned to a profile or none is selected

When the Current Profile is assigned to the selected body or constraint, or if none is selected, the node's fill color (green for bodies and beige for constraints) is used. When the selected body or constraint is not assigned to the Current Profile, the node will be shaded.



Here, the bodies for lowerarm_l and middle_01_l have been assigned the profile MyPhysicalAnimation_Profile, and the remaining body nodes have not been assigned this particular profile, as indicated by their shaded color.



For the constraints, since the Current Profile is set to None, the fill color remains unshaded until any selected constraints are assigned a selected profile.

For additional information about using Profiles and assigning them to bodies and constraints, see the Tools and Profiles page.

Physics Asset Editor Interface

Physics Asset Editor

Animation Editors

Physics Asset Editor Tutorials

Interface Breakdown

Search Line

Bone Hierarchy List

Selection Context Menus

Skeleton Show/Hide Options



The Skeleton Tree panel in the Physics Asset Editor shows the skeletal hierarchy of the current Skeleton asset, along with additional assets like the collision bodies, primitives, and constraints. Within it, you can perform the following actions:

Select and view specific bones in the skeletal hierarchy with their attached bodies and constraints.

Create and edit bodies, primitives, and constraints, which can be simulated in the Viewport to see the results of ragdoll animations, constraints, and collision interaction.

Create preview assets, which are temporarily attached assets; these are good for previewing how a weapon will look on a character, for example.

Interface Breakdown



Search Line

Bone Hierarchy List

Skeleton Options

Search Line



The Search line allows for quick filtering of the Skeletal hierarchy by filtering out the hierarchy to only include names based on the entered text.



Above, we have filtered the hierarchy to include any Bone Names, Bodies, or Constraints that include the text Pelvis in them.

Bone Hierarchy List



This window shows all the Bones, Bodies, Constraints, Primitives, and Preview Objects currently used by the selected Physics Asset. Inside this window is where you can add and assign collision Bodies, Primitives, Constraints, and Preview Objects. Most of the adjustments made in the Bone Hierarchy list are handled through right-click context menus where the menu options vary based on the object you right-click on (see the context menu sections below).

Selection Context Menus

Within the Bone Hierarchy list, when you right-click on a Bone, Body, Primitive, or Constraint, you access context menus specific to the selection made.

Below are the available context menus and their relative options.

When right-clicking on a Bone, you will see the following context menu:



Option

Description

Copy Selected Bone Names

Copy the selected bone names to the clipboard.

Reset Selected Bone Transforms

Reset the transforms of the selected bones.

Add Preview Asset

Opens a menu of all eligible assets that can be temporarily attached to a bone for previewing purposes. For instance, if you want to see what a certain piece of armor would look like attached to a bone, this is the option you would use. Note, however, that this is not a permanent attachment and will only be visible while previewing.

Remove All Attached Assets

Removes all attached assets from the Skeleton and the mesh.

Add/Replace Bodies

Adds or replaces bodies for the selected bones using the current generation settings found in the Tools tab.

Add Shape

Adds shapes to the body.

Select All Bodies

Selects all bodies in the Skeleton Tree.

Select Simulated Bodies

Selects all simulated bodies in the Skeleton Tree.

Select Kinematic Bodies

Selects all kinematic bodies in the Skeleton Tree.

Select All Constraints

Selects all constraints in the Skeleton Tree.

When right-clicking on a Body, you will see the following context menu:



Option

Description

Regenerate Bodies

Regenerates the selected bodies using the current generation settings found in the Tools tab.

Add Shape

Adds shapes to this body. A Box, Sphere, or Capsule shape can be selected.

Collision

Adjust collision between bodies.

Weld

Weld the currently selected bodies together.

Enable Collision

Enable collision between the currently selected bodies.

Enable Collision All

Enable collision between the currently selected bodies and all bodies.

Disable Collision

Disable collision between the currently selected bodies.

Disable Collision All

Disable collision between the currently selected bodies and all bodies.



Constraint selected bodies

Create a constraint between all selected bodies as children and the last selected body as parent.

Constraints

Create a constraint between the selected body and one selected from the hierarchy list.

Physics Type

The type of physics to use for this body; kinematic or simulated.

Physical Material

Select a Physical Material to apply to all bodies.

Copy Selected Bodies/Constraints To Clipboard

Copy the bodies/constraints of the currently selected object to clipboard.

Paste Bodies/Constraints From Clipboard

Paste the previously selected bodies/constraints from clipboard.

Copy Properties

Copy the properties of the currently selected object to the next selected object.

Paste Properties

Past the properties of a previously selected object to the currently selected object.

Delete

Delete the currently selected body.

Delete All Bodies Below

Delete all bodies below the currently selected body in the Skeleton Hierarchy Tree.

Mirror

Find the body on the other side and duplicate its constraints and body.

Assign

Assigns the selected bodies to the current physical animation profile.

Unassign

Unassigns the selected bodies from the current physical animation profile.

Copy Collision From Static Mesh

Copy convex collision from a specified Static Mesh.

Select All Bodies

Selects all bodies in the Skeleton Tree.

Select Simulated Bodies

Selects all simulated bodies in the Skeleton Tree.

Select Kinematic Bodies

Selects all kinematic bodies in the Skeleton Tree.

Select All Constraints

Selects all constraints in the Skeleton Tree.

When right-clicking on a Primitive, you will see the following context menu:



Option

Description

Rename

Rename selected primitives.

Duplicate

Duplicate selected primitives.

Delete

Delete selected primitives.

Select All Bodies

Selects all bodies in the Skeleton Tree.

Select Simulated Bodies

Selects all simulated bodies in the Skeleton Tree.

Select Kinematic Bodies

Selects all kinematic bodies in the Skeleton Tree.

Select All Constraints

Selects all constraints in the Skeleton Tree.

When right-clicking on a Constraint, you will see the following context menu:



Option

Description

Snap

Snap the selected constraint to Bone.

Reset

Resets the constraint to the default state.

Axes and Limits

Edit axes and limits of this constraint.

Cycle Constraint Orientation

Cycles constraint orientation between different cardinal axes.

Cycle Active Constraint

Cycles whether each constraint axis is active in isolation.

Lock Swing

Set swings 1 or 2 to be locked or limited.

Lock Twist

Set twist to be locked or limited.



Convert

Convert constraint to various presets.

Ball & Socket

Hinge

Prismatic

Skeletal



Copy Selected Bodies/Constraints To Clipboard

Copy the bodies/constraints of the currently selected object to clipboard.

Paste Bodies/Constraints From Clipboard

Paste the previously selected bodies/constraints from clipboard.

Copy Properties

Copy the properties of the currently selected object to the next selected object.

Paste Properties

Past the properties of a previously selected object to the currently selected object.

Delete

Delete the currently selected constraint.

Assign

Assigns the selected constraints to the current physical animation profile.

Unassign

Unassigns the selected constraints from the current physical animation profile.

Copy Collision From Static Mesh

Copy convex collision from a specified Static Mesh.

Select All Bodies

Selects all bodies in the Skeleton Tree.

Select Simulated Bodies

Selects all simulated bodies in the Skeleton Tree.

Select Kinematic Bodies

Selects all kinematic bodies in the Skeleton Tree.

Select All Constraints

Selects all constraints in the Skeleton Tree.

A Preview Asset is an asset, such as a Static Mesh or Skeletal Mesh, that has been temporarily attached to a bone or socket for previewing purposes.

When right-clicking on a Preview Asset, you will see the following context menu:



Option

Description

Add Preview Asset

Opens a menu of all eligible assets that can be temporarily attached to a bone for previewing purposes. For instance, if you want to see what a certain piece of armor would look like attached to a bone, this is the option you would use. Note, however, that this is not a permanent attachment and will only be visible while previewing.

Remove All Attached Assets

Deletes all Preview Assets currently on the mesh.

Skeleton Show/Hide Options

The Skeleton Options window enables you to show or hide Bones, Bodies, Constraints, and Primitives.



Option

Description

UpperBodyMask

Selects the blend profile for editing.

LowerBodyMask

Selects the blend profile for editing.

FastFeet

Selects the blend profile for editing.

LeftFingersMask

Selects the blend profile for editing.

UpperBodyLowerBodySplitMask

Selects the blend profile for editing.

Clear

Clears the selected blend profile.

Add Time Blend Profile

Adds a new time blend profile for this skeleton.

Add Weight Blend Profile

Adds a new weight profile for the skeleton.

Add Blend Mask

Adds a new blend mask for the skeleton.

Filtering Flattens Hierarchy

Whether to keep the hierarchy or flatten it when searching for tree items.

Hide Parents When Filtering

Whether to show parent items grayed out or hide them entirely when filtering.

Show Bodies

Display bodies in the tree view. Bodies are a collection of primitive shapes used for collision.

Show Simulated Bodies

Show all simulated bodies in the Skeleton Tree.

Show Kinematic Bodies

Show all kinematic bodies in the Skeleton Tree.

Show Constraints

Display constraints in the tree view. Constraints are used to control how bodies can move in to one another.

Show Primitives

Display primitive shapes (spheres, boxes, capsules, etc.) in the tree view.

Show Constraints on Parent Body

Display constraints on both the parent and child body.

Show All Bones

Show every bone in the skeleton.

Show Mesh Bones

Show bones that are used in the mesh.

Show LOD Bones

Show bones that are used in the LOD (level of detail) being displayed.

Show Weighted Bones

Show bones that have vertices weighted to them.

Hide Bones

Hide all bones (sockets and attached assets will still be listed).

Physics Asset Editor Interface

Physics Bodies

Physics Constraint Reference

Animation Editors

Physics Asset Editor - Skeleton Tree

Tools Tab

Body Creation Settings

Constraint Creation Settings

Profiles Tab

Current Profile

Thumbnail

Physics

The Tools and Profiles tabs enable you to choose how Bodies are generated and allow for custom profiles for default properties of assigned bodies and constraints.



Tools Tab

The Tools tab enables you to perform batch edits of your Physics Asset. It includes being able to add, generate or re-generate bodies for the entire skeleton or selected bodies in the Skeleton Tree.



Body Creation Settings

The following options are available when creating or editing primitive shapes, sizes, and more for bodies:



Property

Description

Min Bone Size

Bones that are shorter than this value will be ignored for body creation.

Primitive Type

The geometry type that should be used when creating bodies.

Box

Capsule

Sphere

Tapered Capsule (Cloth Only)

Single Convex Hull

Multi Convex Hull



Vertex Weighting Type

How vertices are mapped to bones when approximating them with bodies.

Any Weight

Dominant Weight



Auto Orient to Bone

Whether to automatically orient the created bodies to their corresponding bones.

Walk Past Small Bones

Whether to skip small bones entirely (rather than merge them with the adjacent bones).

Create Body for All Bones

Forces the creation of a body for each bone.

Disable Collisions by Default

Whether to disable collision of body with other bodies on creation.



Advanced Properties



Min Weld Size

Bones that are smaller than this value will be merged for body creation.

Hull Accuracy

When creating convex hulls, the target accuracy of the created hull.

Max Hull Verts

When creating convex hulls, the maximum verts that should be created.

Constraint Creation Settings

The following options are available when creating or editing the constraints of bodies:



Property

Description

Create Joints

Whether to create constraints between adjacent created bodies.

Angular Constraint Mode

The type of angular constraints to create between bodies.

Free

No constraint against this axis.

Limited

Limited freedom along this axis.

Locked

Fully constraint against this axis.



Once the properties have been set for the Body Creation and Constraint Creation categories, any selected bodies, constraints, or bones will display an action to add, generate, or re-generate bodies.



Button



All physics bodies and constraints will be re-created.



When a constraint is selected, this button will enable all bodies and constraints to be recreated using the new settings.



Selected bodies will be replaced along with their constraints using the new settings.

Profiles Tab

The Physics Asset Profiles tab enables you to view, select, and edit a collection of settings for Physical Animations and Constraints that can be saved to profiles which can then be assigned to the selected bodies or constraints in the Skeleton Tree.



For additional information, see the Using Profiles for Bodies and Constraints page.

Current Profile

The Current Profile drop-down is where you'll find any new or existing profiles that have been created. When the profile is selected, options to remove it from the list of profiles, and assign or unassign it from the selected bodies or constraints will become available.



Option

Description

New

Creates a new profile that has properties set and can be assigned to bodies or constraints.

Delete

Removes the custom profile when it is set as the Current Profile selection.

Assign

Assigns the selected bodies or constraints to the Current Profile selection.

Unassign

Unassigns the selected bodies or constraints from the Current Profile selection.

Some options are available for the Current Profile by clicking the arrow drop-down.



Option

Description

Duplicate

Copies the currently set profile.

Set Current Constraint Profile

Select from the currently created profiles the one to be used as the Current Profile to assign, unassign, or delete.

When bodies or constraints are assigned a profile, there are a couple of places where you can check the status of the assignment:

From the Details panel

From the Graph

In the Details panel, the Current Profile being used for the selected body will be listed. When there isn't a profile assigned, it will be listed as None.







Unassigned Profile

Assigned Profile

In the Graph, the selected bodies and their constraints will be displayed. The shading of the bodies and constraints will be based on which the profile is selected as the Current Profile.



For example, the Graph is showing the selected body and constraints, while the Profiles tab is showing the Current Profile for Physical Animation set to MyPhysicalAnimation_Profile which is assigned to two of the four bodies in the Graph. When the Current Profile selected is assigned to a node, it will have an unshaded fill color, and when the node is not assigned that profile, it will appear shaded. The constraints displayed all appear with their fill color since the Current Profile for Constraints is set to None.

For additional information about the nodes in the Graph, see the Constraints Graph page.

When Bodies are selected and assigned a Physical Animation profile, the following options will become available:



Property

Description

Is Local Simulation

Whether the drive targets are in the world or local space.

Orientation Strength

The strength used to correct orientation error.

Angular Velocity Strength

The strength used to correct angular velocity error.

Position Strength

The strength used to correct linear position error. Only used for non-local simulation.

Velocity Strength

The strength used to correct linear velocity. Only used for non-local simulation.

Max Linear Force

The max force used to correct linear errors.

Max Angular Force

The max force used to correct angular errors.

When Constraints are selected and assigned a Constraints Profile, the following options will become available:





Click the image to view the full size.



For additional information, visit the Constraints Reference page.

Thumbnail

Control how the thumbnail image for the Physics Asset should appear in the Content Drawer. You can control the Pitch, Yaw, and Zoom of the thumbnail.



When the Thumbnail pitch, yaw, and zoom values are adjusted the thumbnail in the Content Drawer will update in real-time.



Physics

The following options are available that will apply to all assigned profiles.



Property

Description

Not for Dedicated Server

If true, skips instancing bodies for the PhysicsAsset on dedicated servers.

Applying a Physical Animation Profile

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Using Profiles for Bodies and Constraints

Steps

Result

Additional Resources

Below, you will find the steps for creating a simple graph to enable a Constraint Profile on a Skeletal Mesh Component in a Pawn.

Steps

Open or create a Blueprint with a Skeletal Mesh Component.

If your Blueprint doesn't contain a Skeletal Mesh Component, add one using the Components Panel.



Adjust the Skeletal Mesh Component Collision settings.

The Collision Preset needs to be changed so that that Skeletal Mesh Component has Collision Enabled and if a Pawn capsule (or other geometry) exists make sure that the collision settings are compatible. For example with a Pawn capsule make sure to ignore the Pawn collision:



You'll notice in our example that the Object Type is set to Pawn and that we're ignoring Pawns in our collision channels. This fixes the issue of the Skeletal Mesh trying to eject itself from the collision capsule. However, if you want the Skeletal Mesh to collide with other Pawns you'll need to adjust what Object Type your Skeletal Mesh is and then change how the Capsule interacts with that Object Type. See: Add a Custom Object Type to Your Project, for more information on creating Custom Collision Channels.

Add a Physical Animation Component to your Blueprint using the Components Panel.



Add a Name variable and call it Bone Name.



Compile so you can set the value of the Bone Name variable.



Change Bone Name Default Value to the desired target Bone, in this case, spine_01.



Switch to the Event Graph.

Locate or create the Event BeginPlay event node.



Add a reference to your Skeletal Mesh Component.



Add a Set Constraint Profile for All node.

Target is your Skeletal Mesh Component.

Profile Name is the name of the Constraint Profile that you created (or will create) in the Physics Asset Editor.

Default if Not Found is optional, if enabled then if a bone doesn't exist in the Profile, it will keep its current settings.



Add a Set All Bodies Below Simulate Physics node connected to the Set Constraint Profile for All node.

Target is your Skeletal Mesh Component.

In Bone Name will accept the Bone Name variable as input.

New Simulate should be enabled.

Since you are using spine_01 as the target bone, Include Self should be enabled.

Final Graph:



Hidden Graph Information

Variable

Value

Description

Bone Name

spine_01

Used by the Set All Bodies Below Simulate Physics node to define what parts of the Skeletal Mesh are simulated.

Component

Description

Skeletal Mesh Component

The component that will have the Constraint Profile applied to it. If working from an existing Blueprint that inherits from Character, it will be named Mesh.

Result

Now when you play your game, the Constraint Profile will take over. Depending on your settings, this could mean that your character falls apart, or has motors engaged to make their arms flail around.



This effect was achieved by setting the Linear Limits on the upper arm constraints to Free.



Additional Resources

Applying a Physics Constraint Profile

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Using Profiles for Bodies and Constraints

Steps

Result

Additional Resources

Below you will find the steps for creating a simple graph to enable a Physical Animation Profile on a Skeletal Mesh Component in a Pawn.

Steps

Open or create a Blueprint with a Skeletal Mesh Component.

Or, if your Blueprint doesn't contain a Skeletal Mesh Component, add one using the Components Panel.



Adjust the Skeletal Mesh Component Collision settings.

The Collision Preset needs to be changed so that Skeletal Mesh Component has Collision Enabled and so that it doesn't interact with Pawns:



You'll notice in our example that the Object Type is set to Pawn and that we're ignoring Pawns in our collision channels. This fixes the issue of the Skeletal Mesh trying to eject itself from the collision capsule. However, if you want the Skeletal Mesh to collide with other Pawns you'll need to adjust what Object Type your Skeletal Mesh is and then change how the Capsule interacts with that Object Type. See: AddCustomCollisionType, for more information on creating Custom Collision Channels.

Add a Physical Animation Component to your Blueprint using the Components Panel.



Add a Name variable and call it Bone Name.



Compile so you can set the value of the Bone Name variable.



Change the Bone Name Default Value to the desired target Bone, in this case, spine_01.



Switch to the Event Graph.

Locate or create the Event BeginPlay event node.



Add a reference to your Skeletal Mesh Component.



Add a Set Skeletal Mesh Component node connecting to Event Begin Play.

The target is the Physical Animation Component you added above.

The Skeletal Mesh Component is either the one in your Blueprint or the one you added above.



Add a Apply Physical Animation Profile Below node connecting to the Set Skeletal Mesh Component node.

Target is the Physical Animation Component.

Body Name will accept the Bone Name variable as input; in Physics Assets, Physics Bodies are named after their Bone.

Profile Name is the name of the Physical Animation Profile you wish to apply to the Skeletal Mesh.

Since you are using spine_01 as the desired bone so that just the upper body animates, Include Self should be checked.

Clear Not Found is optional, but enables it to clear any bones that are not found in the profile.



Connect the Set All Bodies Below Simulate Physics node to the Apply Physical Animation Profile Below node. This will complete our graph.

Target is your Skeletal Mesh Component.

In Bone Name will take the Bone Name variable as input.

New Simulate should be enabled.

Again, since you are using spine_01 as the target bone, Include Self should be enabled.



Hidden Graph Information

Variable

Value

Description

Bone Name

spine_01

The name of the Bone in the Skeletal Mesh to start applying the Physical Animation Profile. Also used in the Set All Bodies Below Simulate Physics node.

Component

Description

Physical Animation Component

This is the component that handles the Physical Animation of your Skeletal Mesh.

Skeletal Mesh Component

The component that will be physically animated using the profile. If working from an existing Blueprint that inherits from Character, it will be named Mesh.

Result

When finished, your Skeletal Mesh Component will be simulating physics using the Physical Animation Component while in runtime.



Additional Resources

Steps

Result

Additional Resources

In this How-To, we will cover the basics of creating a Constraint Profile and adding Physics Constraints to it.

Steps

Find or Create a Physics Asset for your Skeletal Mesh using the Content Drawer.



If opting to create a new Physics Asset, you will need to set it up before continuing.

Double-click the Physics Asset to open the Physics Asset Editor.



Under the Windows menu, select Profiles; the Profiles window should appear as a docked tab.



Add a Profile using the New button on the Constraints Profiles section, and set its name (in the image below we've named it DocsConstraintProfile).



Select the Physics Constraint you want to include in your new Constraint Profile in the Skeleton Tree panel, the Physics Graph panel, or the Viewport.

To see Constraints in the Skeleton Tree panel, select Show Constraints in the Options dropdown menu.

Press the Assign button in the Profiles panel.



1 - Assign a button

2 - Constraints selected in the Skeleton Tree panel

3 - Constraints selected in the Physics Graph panel

4 - Constraints selected in the Viewport

Adjust the properties for the selected Physics Constraints.



Repeat steps 5-7 for all the Physics Constraints you want to add to the Constraint Profile.

You can select, assign, and edit the Properties of multiple Constraints simultaneously. You only need to edit them individually if you want their Properties to be different.

Save your Physics Asset using the Save button in the Physics Asset Editor.



You can edit an existing Constraints Profile by selecting it in the dropdown menu, then using Assign to add new Constraints, or using Unassign to remove existing Constraints.

Result

The Physics Asset now has a profile that can be called upon from Blueprint or C++ to change its Physical Constraint properties.

Additional Resources

Editing the Physics Asset of a Physics Body

Editing Physics Asset Constraints

Adding Physics Bodies to Bones

Adding Shapes to Physics Bodies

Result

The Physics Asset Tool enables you to add or replace the Physics Bodies and their associated Shapes (Boxes, Spheres, Capsules, Tapered Capsules, and so on) attached to the Bones make up your Physics Asset.

By default, the Physics Editor Skeleton Tree panel only shows the Physics Bodies. Adding and replacing Physics Bodies is easier if you use the Options dropdown menu in the Skeleton Tree panel to show the Bones and Primitives as well.

Adding Physics Bodies to Bones



Right-click on a Bone in the Skeleton Tree panel, then click on Add/Replace Body in the Context Menu.

You can also right-click on a Bone in the VIewport to open the Context Menu.

A new Physics Body will be added to the Bone, with the default Capsule Shape attached.

If there was already a Physics Body attached to the Bone, the new Physics Body and Capsule Shape will replace it.

Alternatively, when starting with a Bone with no attached Physics Body, you can directly select one of the shapes under Add Shape in the Context Menu. This will create a new Physics Body with the selected Shape attached.

If you right-click on a Physics Body and select Regenerate Bodies, a new Physics Body with a default Capsule Shape attached will be created to replace every currently-selected Physics Body.

Adding Shapes to Physics Bodies



To add a Shape to an existing Physics Body, right-click the Physics Body, then under Add Shape in the Context Menu, select the Shape you wish to add.

A Physics Body can have more than one attached Shape, so delete the default Capsule if you do not want it to remain attached to the Physics Body.

Result

You should see that a corresponding body and shape have been added (and parented) to the selected bone.

Applying a Physical Animation Profile

Steps

Result

Additional Resources

In this How-To, we will cover the basics of creating a Physical Animation Profile and adding Physics Bodies to it.

Steps

Find or Create a Physics Asset for your Skeletal Mesh using the Content Drawer.



If opting to create a new Physics Asset, you will need to set it up before continuing.

Double-click the Physics Asset to open the Physics Asset Editor.



Under the Windows menu, select Profiles; the Profiles window should appear as a docked tab.



Add a Profile using the New button on the Physical Animation Profiles entry, and set its name (in the image below we've named it DocsProfile).



Select the Physics Body you want to include in your new Physical Animation Profile in the Skeleton Tree panel, the Physics Graph panel, or the Viewport.

To see Constraints in the Skeleton Tree panel, select Show Constraints in the Options dropdown menu.

Press the Assign button in the Profiles panel.



1 - Assign a button

2 - Physics Bodies selected in the Skeleton Tree panel

3 - Physics Bodies selected in the Physics Graph panel

4 - Physics Bodies selected in the Viewport

Adjust the properties for the selected Physics Bodies.



A good set of starting values is 1000, 100, 1000, 100, 0, 0



Repeat steps 5-7 for all the Physics Bodies you want to add to the Physics Animation Profile.

You can select, assign, and edit the Properties of multiple Physics Bodies simultaneously. You only need to edit them individually if you want their properties to be different.

Save your Physics Asset using the Save button in the Physics Asset Editor.



You can edit an existing Physics Animation Profile by selecting it in the dropdown menu, then using Assign to add new Physics Bodies, or using Unassign to remove existing Physics Bodies.

Result

The Physics Asset will have a profile that can be called upon from Blueprint or C++ to change the Physical Animation properties of its Physics Bodies.

Additional Resources

Editing a Physics Asset

Steps

Result

There are two ways to create a new Physics Asset: on import or by using the context menu in the Content Drawer. Below are the steps and interfaces for both methods.

Steps

When a Skeletal Mesh is imported, there is an option to generate a Physics Asset for it as it is imported. Once the imported file is processed, a new Physics Asset will be generated using the default properties, which can be modified using the Physics Asset Editor.



You can choose to use an existing Physical Asset by disabling the Create Physics Asset checkbox, then selecting the appropriate Physics Asset using the dropdown menu.



However, you can follow these steps if you need to create a Physics Asset for a Skeletal Mesh at a later time:

in the Content Drawer, find the Skeletal Mesh asset to which you wish to add a Physics Asset.

Right-click on the Skeletal Mesh to open the Context Menu, the select Create -> Physics Asset -> Create.



Adjust the properties to your liking.



Click Create Asset.

Result

Upon creating a Physics Asset you will find it in the same folder as the Skeletal Mesh it is based on.

Editing the Physics Asset of a Physics Body

Editing Physics Asset Constraints

Steps

Result

Below are the steps for opening a Physics Asset for editing in the Physics Asset Editor.

Steps

Find the Physics Asset in the Content Drawer.



Double-click it to open it in the Physics Asset Editor.



Result

The Physics Asset will be open and ready to edit in the Physics Asset Editor.

Editing Physics Asset Constraints

Welding Physics Bodies in the Physics Asset Editor

Physics Bodies Reference

Editing a Physics Body

Copying Physics Bodies

Deleting Physics Bodies

Physical Materials

Below are several common procedures and steps associated with editing Physics Bodies in the Physics Asset Editor.

If it is difficult to see the Physics Body you want to edit, in the Viewport select Character > Mesh > Wireframe/None to adjust the visibility of the Skeletal Mesh.



Editing a Physics Body

Double-click your Physics Asset to open it in the Physics Asset Editor.

Select a Physics Body in the Viewport or in the Skeleton Tree panel.

Select, move, rotate, and scale the Physics Body using the Selection, Translation, Rotation, and Scale tools so it fits the Skeletal Mesh Bone.



Edit the Physics Body's properties in the Details panel.

Use the Enable Collision and Disable Collision tools in the toolbar to edit Collisions between the current Physics Bodies and others in the Physics Asset. Any Physics Bodies that can collide with the currently selected Physics Body will be blue; if they cannot collide, they will be gray.



If a series of bodies should act as one, such as with the twist joints that form a wrist, use the Weld tool to prevent undesired physics simulation behavior. Welded Physics Bodies will be yellow.

Save often.

See the Physics Bodies Reference for more information on the Physics Bodies properties in the Physics Asset Editor.

Copying Physics Bodies

While in either mode, properties from one Physics Body can be copied to other Physics Bodies:

Select the Physics Body you wish to copy data from.

Press Ctrl + C.

Select the Physics Bodies you wish to apply data to.

Press Ctrl + V.

This will not overwrite the shape of a Physics Body.

Deleting Physics Bodies

Double-click your Physics Asset to open it in the Physics Asset Editor.

Select a Physics Body you wish to delete in the Viewport or in the Skeleton Tree panel.

Press the Delete key.

Physical Materials

Each Physics Body in a Physics Asset can have a Physical Material assigned to it. To apply a Physical Material to a single Physics Body:

Double-click your Physics Asset to open it in the Physics Asset Editor.

Select a Physics Body in the Viewport or in the Skeleton Tree panel.

In the Details panel, locate the Simple Collision Physical Material property and assign a Physical Material.



Editing the Physics Asset of a Physics Body

Physics Constraint Reference

Constraints User Guide

Editing Physics Constraints

Aligning Physics Constraints

Copying Physics Constraints

Deleting Physics Constraints

Recreating a Physics Constraint

Below are several common procedures, and steps, associated with editing Physics Constraints in the Physics Asset Editor.

Editing Physics Constraints

The use of Physics Constraints is covered in the Physics Constraints User Guide and their properties are covered in the Physics Constraint Reference. This section will only cover workflows that are specific to the Physics Asset Tool or ones that have deviated substantially from the norm.

Double-click your Physics Asset to open it in the Physics Asset Editor.

Select a Physics Constraint in the Viewport or in the Skeleton Tree panel.

Move and rotate the Physics Constraint using the Translation and Rotation tools to create the rotational point of the "joint" the Physics Constraint will form.

Edit the Physics Constraint's properties in the Details panel.

You can switch Swing1, Swing2, and Twist from Limited to Locked quickly by using the "1", "2", and "3" keys respectively. The "4" key can be used cycle through them setting one to limited and the other two to locked.

Save often.

See the Physics Constraint Reference for more information on the Physics Constraint properties in the Physics Asset Editor.

Aligning Physics Constraints

If you are using the Physics Constraint's Linear or Angular limits, you will be able to see their alignment:



By then translating and rotating the Physics Constraint, you can align the limits to give the desired results. In the most basic of terms, when a Physics Constraint is limited, you can see a yellow line suspended in a green arc or cone structure. The line will be "constrained" within this arc or cone.

For more information on Physics Constraints and their properties, see the Physics Constraints User Guide.

Copying Physics Constraints

While in either mode, properties from one Constraint can be copied to other Constraints:

Select the Physics Constraint you wish to copy data from.

Press Ctrl + C.

Select Physics Constraints you wish to apply data to.

Press Ctrl + V.

Deleting Physics Constraints

There is no easy way to recreate a Physics Constraint, be mindful of this when deleting them.

Double-click your Physics Asset to open it in the Physics Asset Editor.

Select the Physics Constraint you want to delete in the Viewport or in the Skeleton Tree panel.

Press the Delete key.

Recreating a Physics Constraint

There is no easy way to recreate a Physics Constraint, be mindful of this when deleting them.

Physics Constraints are only created on the generation of a Physics Body and are only generated upstream. So, if you remove a Physics Constraint from the shoulder, you would have to remove the upper arm Physics Body (which will remove the elbow Physics Constraint), then re-create the upper arm Physics Body. This would create the shoulder Physics Constraint, but not the elbow Physics Constraint, so you would have to continue this process down the arm.

Exploding

Jitter

While there are several things that can be out of your control during a physical simulation, there are two issues that are definitely within your power to correct: Exploding (interpenetrating physics bodies that are set to collide with each other) and Jitter (when the Physics Bodies refuse to sleep due to micro-movements). Below are some steps for correcting these issues.

Exploding

This is caused by two Physics Bodies interpenetrating and the physics system attempting to correct it by applying a massive amount of force to expel the Physics Bodies from each other. If a Physics Constraint is keeping the offending Physics Bodies together, the physics system will continually apply force to separate them, causing very erratic and extreme movement.



This is normally fixed by disabling collision between the two offending Physics Bodies, or changing their positions and/or scale to make sure they do not interpenetrate. Additionally, welded Physics Bodies act as one regardless of interpenetration.

Jitter

If your Physics Asset is mostly "collapsed" but still shaking and twitching on the ground, but not violently bouncing around, there are a few values you can tweak to get it to stop and sleep.

Before doing anything, try simulating with No Gravity, this will show you if any of your Physics Constraints are misaligned, and tryi to correct them before the Physics Asset has even hit the ground.



Often a small amount of Linear and Angular Damping on all the Physics Asset's Physics Bodies is more than enough to stop the asset from shaking. However, using large values in Linear Damping will cause a Physics Body to slow its movement through the world, even due to gravity. Damping, as it is implemented here, is like the drag of moving through a viscous substance.

If jitter is still an issue, perhaps you have several really small Physics Bodies, check the Substepping documentation for information on having the physics simulation calculates in-between solutions.

See the Constraints Reference for more details on the properties for Physics Constraints.

Physics Asset Editor

Physics Asset Properties Reference

Steps

End Result

The Physics Asset Editor provides several different ways in which you can simulate physics bodies including the ability to have kinematic physics bodies with simulated parents. This enables you to define child bodies that can be driven by animation data while the parents of those bodies are driven by physics simulation data. This can be useful if you have a character that you want to perform a physics-based reaction while playing a hanging idle or hanging traversal animation.

In this How-to, we use kinematic bodies with simulated parents to generate the effect of a character hanging from a ledge while the rest of the body is simulated with physics.



Steps

For this guide, we are using the Blueprint Third Person Template project with Starter Content enabled.

In your project in the Content/Mannequin/Character/Mesh folder, open the SK_Mannequin_PhysicsAsset.



In the Skeleton Tree panel, hold Ctrl and select both the hand_l and hand_r bodies, then in the Details panel, change the Physics Type to Kinematic.



By setting these bones to Kinematic, they will not simulate physics and will follow any animation data.

Alternatively, you can right-click bones in the hierarchy list and expand Physics Type in the Context Menu, then set their Body Physics Type to Kinematic.



This option enables you to set the Physics Type property for children's bodies below the current bone.

Click on a space within the viewport to deselect all bones, then in the Details panel, change the Physics Update Mode to Component Transform is Kinematic.



This option determines whether the simulation of the root body updates component transform or is kinematic.

From the toolbar, open the dropdown menu under the arrow icon, and select Simulate.



The character in the viewport will slump over and appear to be hanging by their hands.



From the toolbar, open the Animation dropdown menu, then select the ThirdPersonJump_Loop animation.



The hands (because they are set to kinematic) will follow the animation data contained within the ThirdPersonJump_Loop motion.



From the Main Editor window, drag the SK_Mannequin_PhysicsAsset into the level and then, in the Details panel, set Physics Transform Update Mode to Component Transform is Kinematic.



Select the SkeletalMeshComponent, then change Animation Mode to Use Animation Asset and Anim to Play to ThirdPersonJump_Loop.



Click the Play button from the toolbar to play in the editor.

End Result

Below we've placed the character near a ledge when we run and bump into it, it reacts to physics while the hands appear slightly fixed.

While the animation we used above is not ideal, below we apply the same concept to an animation of a character hanging and traversing a ledge.

The arms and head are set to Kinematic (denoted below with Gold Boxes) while the rest is being simulated.



Testing

This page covers the basics of testing a Physics Asset in the Physics Asset Tool.

Testing



Selecting Simulation from the dropdown menu under the toolbar arrow icon will allow you to test your Physics Asset.



When the No Gravity option is enabled, the entire Physics Asset is simulated but gravity is not turned on, enabling you to ctrl+click to poke the Physics Bodies in a zero gravity environment. This is useful for finding any interpenetrating Physics Bodies or Limited Physics Constraints already outside of their limits.

You can also simulate a chain of joints by toggling on Selected Simulation. This option only simulates the Physics Bodies you have selected (you can select more than one) and those down the hierarchy from the selected Physics Bodies. For example, if you select the shoulder, the entire arm will be simulated.

Editing the Physics Asset of a Physics Body

Welding

This how-to guide contains the procedures to Weld two or more Physics Bodies together in the Physics Asset Editor.

Welding

Welding Physics Bodies will make multiple bodies interact as one, as well as lock together the Skeletal Mesh Joints they are associated with. To Weld one Physics Body to another:

Select 2 or more Physics Bodies using Ctrl + Left Mouse click.

Right-click one of the Physics Bodies to open the Context menu, then under Collision select the Weld option.



Any Physics Body welded to the currently selected Physics Body will show in yellow.

Physics Asset Editor Interface

Physics Asset Editor - Tools and Profiles

Physics Constraint Reference

Physics Bodies

Create and Assign a Profile

Unassigning a Profile

Deleting a Profile

Additional Resources

The Physics Asset Editor enables you to create your own Profiles that can be used to assign Physical Animation settings to Bodies and Constraint settings to Constraints.



Use the sections below to learn how to create and assign, unassign, and delete your profiles:

Create and Assign a Profile

To create and assign a profile, follow these steps:

Select a Physics Body or Physics Constraint from the Skeleton Tree.



In the Profiles tab, click the New button next to the type of profile you want to create; Physical Animation or Constraint. Then under the Current Profile in the text box, give your profile a name to reference later.



When profiles are created, they are initialized "empty" meaning they use default settings.

Use the Graph or Skeleton Tree to select the bodies or constraints you want to assign to a profile.



The Graph for the selected body.



Then in the Profiles tab, set the Current Profile to the one you want to use and click Assign. The selected nodes will change from shaded to their fill color.



The color change indicates they are assigned this profile, while the other Body node (shaded) is not.



In the Details panel for the selected body, the assigned profile will be displayed, and you can adjust the properties for the type of profile you're creating.



A Physical Animation profile is assigned to this selected Body.

For a Physical Animation profile, a solid place to start for these values is 1000, 100, 1000, 100, 0, 0



Unassigning a Profile

To Unassign a body or constraint from a profile, follow these steps:

Select a Physics Body or Physics Constraint from the Skeleton Tree that you want to edit.



In the Profiles tab, set the Current Profile to the one you want to edit. Use the dropdown menu to select the assigned profile, if needed.



In the Graph, the nodes assigned to the selected profile will have their fill color and not be shaded.



Select the nodes that you want to disassociate from the profile, then click the Unassign button in the Profiles tab.



After doing so, the selected nodes will show as shaded rather than show the fill color for the currently selected profile.



Deleting a Profile

To Delete a profile, follow these steps:

In the Profiles tab, use the dropdown menu to select as the Current Profile the one you want to delete.



The bottom part of the drop-down lists all created profiles.

Click the Delete button to remove it from the list of available profiles.



Additional Resources

Essentials

Given the ever increasing complexity of 3D meshes, proxy shapes must be used to drive physics simulations in real time 3D rendering applications; Physics Bodies (Body Instances) are the simplified 3D meshes that Unreal Engine uses for physics simulations. They can be formed of boxes, spheres, capsules, or convex hulls.

The following links have information on Physics Bodies.

Essentials



Physics Body, or Body Instance, property reference.

Properties

Physics

Advanced

Collision

Advanced

Body Setup

Primitive Types

This page contains a reference listing of properties in the Physics and Collision categories of properties. If you are looking for reference on Collision Responses or Collision Presets please see: Collision Response Reference.

Properties

Below are the properties for Physics Bodies (Body Instances) separated by major category.

Physics



Property

Description

Double Sided Geometry

If enabled, the physics triangle mesh will use double-sided faces when doing scene queries. This is useful for planes and single-sided meshes that need traces to work on both sides.

Simple Collision Physical Material

Physical material to use for simple collision on this body. Encodes information about density, friction, and so on.

Physics Type

Simulated: Object will use physics simulation.

Kinematic: Object will not be affected by physics, but can interact with physically simulated bodies.

Default: Object will inherit from OwnerComponent's behavior.

Mass in KG

Mass of the body in KG.

Linear Damping

'Drag' force added to reduce linear movement.

Angular Damping

'Drag' force added to reduce angular movement.

Enable Gravity

If the object should have the force of gravity applied.

Advanced



Property

Description

Start Awake

If the object should start awake, or if it should initially be sleeping.

Center Of Mass Offset

User specified offset for the center of mass of this object, from the calculated location.

Mass Scale

Per-instance scaling of mass.

Max Angular Velocity

The maximum angular velocity for this instance.

Sleep Family

The set of values used in considering when to put this body to sleep. Normal, Sensitive, Custom.

Inertia Tensor Scale

Per-instance scaling of inertia (larger values mean more difficulty rotating)

Walkable Slope Override

Custom walkable slope setting for this body.

See the Walkable Slope documentation for usage information.

Walkable Slope Behavior

Behavior of this surface (whether we affect the walkable slope).

Walkable Slope Angle

Override a walkable slope, applying the rules of the Walkable Slope Behavior.

Custom Sleep Threshold Multiplier

If the Sleep Family is set to Custom, multiply the natural sleep threshold by this amount. A higher number will cause the body to sleep sooner.

Stabilization Threshold Multiplier

The stabilization factor for this body if Physics stabilization is enabled. A higher number will cause more aggressive stabilization at the risk of loss of momentum at low speeds. A value of 0 will disable stabilization for this body.

Update Mass when Scale Changes

If true, it will update the mass when the scale changes.

Generate Wake Events

Determines whether 'wake/sleep' events should fire when this object is woken up or put to sleep by the physics simulation.

Collision



Property

Description

Never Needs Cooked Collision Data

To do chaos this is to opt out of CreatePhysicsMeshes for certain meshes. Better a long term mesh is not to call CreatePhysicsMesh until is known there is a mesh instance that needs it.

Collision Complexity

Collision Trace behavior - by default, it will keep simple (convex) and complex (per-poly) separate.

Collision Responses

See the Collision Response Reference documentation for more information.

Simulation Generates Hit Events

Should 'Hit' events fire when this object collides during physics simulation.

Phys Material Override

Allows you to override the PhysicalMaterial to use for simple collision on this body.

Advanced



Property

Description

Use CCD

If true Continuous Collision Detection (CCD) will be used for this component

Ignore Analytic Collisions

If true, ignore analytic collisions and treat objects as a general implicit surface.

Smooth Edge Collisions

Remove unnecessary edge collisions to allow smooth sliding over surfaces composed of multiple actors/components.

Body Setup



Property

Description

Skip Scale from Animation

If true, scale changes from animation are ignored. This is useful for subtle scale animations like breathing where the physics collision should remain unchanged.

Primitives

Simplified collision representation of this object.

Spheres

Sphere Elements

Boxes

Box Elements

Capsules

Sphyl Elements

Convex Elements

Convex Elements

Tapered Capsules

Tapered Capsule Elements

Consider for Bounds

Determines whether this BodySetup should be considered for the bounding box of the PhysicsAsset (and hence SkeletalMeshComponent). There is a speed improvement from having fewer BodySetups processed each frame when updating the bounds.

Bone Name

Used in the PhysicsAsset case. Associates this Body with a Bone in a skeletal mesh.

See below for the Detail properties for each Primitive type.

Primitive Types



Property

Description

Center

Position of the sphere's origin.

Radius

Radius of the sphere.

Rest Offset

The offset used when generating contact points. This allows you to smooth out the Minkowski sum by radius R. Useful for making objects slide smoothly on top of irregularities.

Name

User-defined name for this shape.

Contribute to Mass

Enable if this shape should contribute to the overall mass of the body it belongs to. This lets you create extra collision volumes which do not affect the mass properties of an object.

Collision Enabled

Course per-primitive collision filtering. This allows for individual primitives to be toggled in and out of sim and query collisions without changing filtering details.



Property

Description

Center

Position of the box's origin.

Rotation

Rotation of the box, in degrees around each axis.

X Extent

Extent of the box along the x-axis.

Y Extent

Extent of the box along the y-axis.

Z Extent

Extent of the box along the z-axis.

Rest Offset

The offset used when generating contact points. This allows you to smooth out the Minkowski sum by radius R. Useful for making objects slide smoothly on top of irregularities.

Name

User-defined name for this shape.

Contribute to Mass

Enable if this shape should contribute to the overall mass of the body it belongs to. This lets you create extra collision volumes which do not affect the mass properties of an object.

Collision Enabled

Course per-primitive collision filtering. This allows for individual primitives to be toggled in and out of sim and query collisions without changing filtering details.



Property

Description

Center

Position of the capsule's origin.

Rotation

Rotation of the capsule, in degrees around each axis.

Radius

Radius of the capsule

Length

The length of the line-segment. Add Radius to both ends to find the total length.

Rest Offset

The offset used when generating contact points. This allows you to smooth out the Minkowski sum by radius R. Useful for making objects slide smoothly on top of irregularities.

Name

User-defined name for this shape.

Contribute to Mass

Enable if this shape should contribute to the overall mass of the body it belongs to. This lets you create extra collision volumes which do not affect the mass properties of an object.

Collision Enabled

Course per-primitive collision filtering. This allows for individual primitives to be toggled in and out of sim and query collisions without changing filtering details.



Property

Description

Rest Offset

The offset used when generating contact points. This allows you to smooth out the Minkowski sum by radius R. Useful for making objects slide smoothly on top of irregularities.

Name

User-defined name for this shape.

Contribute to Mass

Enable if this shape should contribute to the overall mass of the body it belongs to. This lets you create extra collision volumes which do not affect the mass properties of an object.

Collision Enabled

Course per-primitive collision filtering. This allows for individual primitives to be toggled in and out of sim and query collisions without changing filtering details.



Property

Description

Center

Position of the capsule's origin.

Rotation

Rotation of the capsule, in degrees around each axis.

Radius 0

Radius of the capsule start point.

Radius 1

Radius of the capsule end point.

Length

Length of the line-segment. Add Radius 0 and Radius 1 to find the total length.

Rest Offset

The offset used when generating contact points. This allows you to smooth out the Minkowski sum by radius R. Useful for making objects slide smoothly on top of irregularities.

Name

User-defined name for this shape.

Contribute to Mass

Enable if this shape should contribute to the overall mass of the body it belongs to. This lets you create extra collision volumes which do not affect the mass properties of an object.

Collision Enabled

Course per-primitive collision filtering. This allows for individual primitives to be toggled in and out of sim and query collisions without changing filtering details.

Physics

Content Examples

Physical Animation Component

Physics Constraint Component

Physics Handle Component

Physics Thruster Component

Radial Force Component

The Physics Components are used to affect any objects that are utilizing physics at your level in varying ways.

Physical Animation Component

The Physical Animation Component applies a physics simulation on top of the animation of a Skeletal Mesh. By using this component you can apply realistic physical simulations to specific groups of bones in the Skeletal Mesh, while still playing an animation.





Physics Constraint Component

A PhysicsConstraintComponent is a joint that allows you to connect two rigid bodies. You can create different types of joints using the various parameters of this Component.

By using a Physics Constraint Component and two Static Mesh Components, you can create dangling type objects such as a tire swing, heavy bag, or sign that reacts to physics in the world allowing players to interact with the Component (see Constraints Blueprints for an example in Blueprints).





Physics Handle Component

The Physics Handle Component is an object for "grabbing" and moving physics objects around while allowing the object you are grabbing to continue to use physics. An example of this could be in the form of a "gravity gun" where you can pick up and drop physics objects (see the Physics Content Examples for more information).





Physics Thruster Component

A Physics Thruster Component is used with objects that have physics to apply a specified force down the negative-X direction (i.e. point X in the direction you want to thrust in). The thruster uses continuous force and can be auto-activated, activated ,or deactivated through the script.

An example of using a thruster is in the form of a rocket (pictured below) which continuously applies force propelling the rocket upward (since the thruster is positioned under the rocket). You can contain the movement of the Component that is influenced by a thruster by using Blocking Volumes.





Radial Force Component

The Radial Force Component is used to emit a radial force or impulse that can affect physics objects and or destructible objects. Unlike a Physics Thruster Component, this type of Component applies a "fire-and-forget" type of force and is not continuous.

You can use this type of Component to push the fractured pieces of a destroyed object, for example, an explosion. Using a Radial Force Component to specify the force and direction, when an object is destroyed you can "push" the pieces outwards in a particular direction as seen in the example image below (see the Destructibles Content Examples for more information).





Simulation and Rendering

Enabling the Plug-in

Using the Cable Component

Using Cable Components from the Place Actors Pannel

Using Cable Component in Blueprints

Attaching Objects to the Cable ends

Collision and Stiffness

Property Breakdown

Cable Forces

Cable Rendering

Additional Reference



Having the ability to cheaply add cables, ropes, or chains that can sway back and forth as if being gently blown by the wind can add a nice bit of life to your Unreal Engine projects. In the following document, we will take a look at how you can use the Cable Component plugin to create, setup and control how the cables look, react and even collide with objects in your levels.

Simulation and Rendering

To perform the actual cable simulation, a technique called Verlet Integration, which is well known in game development. The idea is to represent the cable as a series of particles, with distance constraints between them. The particles at the ends are fixed, moving with whatever they are attached to. The ones in the middle are free, falling with gravity. For each step, you update the velocity and position of each particle, and then move them to satisfy the constraints. The stiffness of the cable is controlled by the number of times we iterate to enforce the constraints (each step).



Click for full image.

Now that there is a nice chain of connected particles bouncing around, they need to be rendered. To render a cable, a class called FCableSceneProxy was created to represent the render of the cable. Each end of the Sim particles' positions (done on the main thread, inside of TickComponent) are then passed to this proxy via the SendRenderDynamicData_Concurrent function. Next, update is locked on the render thread, and then the index and vertex buffers are updated, thereby making a tube mesh. For each vertex on this tube mesh, we need to calculate a position, a Texture UV, and three Tangent Basis vectors. When doing this, X will point along the cable, Z will point straight out from the cable (the normal) and Y is perpendicular to X and Z. These properties have been exposed to the components, giving you the ability to control the number of sides, the radius of the tube, and how many times the UVs can tile along the cable.



Click for full image.

Enabling the Plug-in

By default, the Cable Component plugin should be enabled. However, if it is not, you can enable it by first going to the main toolbar and selecting Edit > Plugins. Then, from the plugins list, go to Rendering and make sure the Cable Component has a checkmark in the box next to Enabled.



Click for full image.

Using the Cable Component

You can add Cable Components to your projects levels in two different ways. In the following section, we will go over the two different ways that you can add cables to your project's levels.

Using Cable Components from the Place Actors Pannel

To use the Cable Component from the Place Actors Panel, you will need to do the following:

First, make sure that the Place Actors panel is visible, and then in the Search Classes box, input the word Cable.



To add the Cable Actor to the world, click on the Cable Actor in the Place Actors panel and then drag it into the level.



Click for full image.

You can now position, rotate, and scale the Cable Actor so that it fits the needs of your level.

Using Cable Component in Blueprints

To use the Cable Component in your Blueprints, you will need to do the following:

First, create a new Blueprint called BP_Cable and make sure that it uses Actor as the parent class.



Next, from the Components section of the BP_Cable Blueprint, click on the Add Component button and then locate the Cable component in the list. When located, click on it to add it to the Components list.



With the Cable Component now added, select the Cable component in the components list, so that you can adjust its properties via the Details panel. For now, leave everything as the default and make sure to Compile and Save your Blueprint.



To make either side of the cable fall, un-check the Attach Start or Attach End option the Details panel of the Cable Component. This can also be toggled while the game is running to go along with effects.

Locate your Cable Blueprint in the Content Browser, and then drag it into the level. Once placed, you can use the move and rotate tools to position it as needed.



Click for full image.

Attaching Objects to the Cable ends

You can also attach objects to either end of the cable so that the objects will swing along with the cable. To accomplish this in your UE4 projects, all you need to do is the following:

You will first need to add a Cable Actor and a Static Mesh to the level.



Click for full image.

Make sure that the Static Mesh that you are attaching to the end has its Mobility set to Moveable.

Locate the Static Mesh you want to attach to the end of the Cable Actor in the World Outliner, and then drag it on top of the Cable Actor. After doing this, the following input window will be displayed.



Click for full image.

Select the Cable End option, and in the viewport, you should see your Static Mesh snap to the end of the Cable Actor.





Now, select the Cable Actor in the level. Then, in the Details panel under the Cable section, uncheck the Attach End box.



Click for full image.

Note that you do not have to only use the Attach Start and Attach End option to attach cables to Actors. You can also specify a Socket that can be used as the attachment point.

After doing this, the cable should now swing freely in the viewport.

Note that you can dynamically toggle the Attach Start and Attach End bools at run time, which can make for some interesting effects.

Collision and Stiffness

Enabling Collision and Stiffness will greatly increase the cost of the Cable Actor. Only enable these features if the cable has to collide with something in the world, or if the cable needs some stiffness to help make the effect look better. If none of that is needed, it is best to keep these options disabled to save performance.

The Cable Component does have the option to have the cable collide with the world, controlling how stiff the cable is. To enable this functionality, you will need to do the following:

First, in the Details of the Cable Component under the Cable section, press the small white triangle to expose the advanced rollout option.



Check both the Enable Stiffness and Enable Collision options to enable these features.



Click for full image.

Now, when you move the Cable Actor around, or if an object collides with, the Cable Actor the cable should collide with the object that it comes in contact with.

Property Breakdown

The following table breaks down each of the properties on the Cable Component:



Property Name

Description

Attach Start

Should we fix the start to something, or leave it free. If false, component transform is just used for initial location of the start of cable.

Attach End

Should we fix the end to something (using AttachEndTo and EndLocation), or leave it free. If false, AttachEndTo and EndLocation are just used for initial location of end of cable.

Attach End To

Actor or Component that defines the end position of the cable.

Component Property

Name of component property to attach the cable to.

Attach End To Socket Name

Socket name on the AttachEndTo component to attach to.

End Location

End location of cable, relative to AttachEndTo (or AttachEndToSocketName) if specified, otherwise relative to cable component.

Cable Length

Rest length of the cable.

Num Segments

How many segments the cable has.

Solver Iterations

The number of solver iterations controls how 'stiff' the cable is.

Substep Time

Controls the simulation substep time for the cable.

Enable Stiffness

Add stiffness constraints to cable.

Enable Collision

Perform sweeps for each cable particle at each substep, to avoid collisions with the world. Uses the Collision Preset on the component to determine what is collided with.This greatly increases the cost of the cable simulation.

This is currently Experimental.



Cable Forces



Property Name

Description

Cable Forces

Force vector (world space) applied to all particles in cable.

Cable Gravity Scale

Scaling applied to world gravity affecting this cable.

Cable Rendering



Property Name

Description

Cable Width

How wide the cable geometry is.

Num Sides

Number of sides of the cable geometry.

Tile Material

How many times to repeat the material along the length of the cable.

Additional Reference

The following section sends you to an external reference, where you can read more about the inspriration behind cable components. To read more about Verlet Integration, check out the following paper from Thomas Jakobsen:

http://graphics.cs.cmu.edu/nsp/course/15-869/2006/papers/jakobsen.htm

Overview

Usage

Overview

Physics Constraint Components operate just like Physics Constraints Actors, except they are used in Blueprints or can be created in C++. Given the flexibility of Blueprints and the power of C++, you can constrain just about any Physics Body in your project using Physics Constraint Components.

This document will cover Physics Constraint Component basic creation in a Blueprint.

This document assumes that the user has some knowledge of Blueprints and the Blueprint Editor.

Usage

Create the Components that will be used to constrain. For this demonstration, two StaticMesh Components referencing the StaticMesh Shape_Cube will be used.



You will need to position the Components that you want to be constrained. For this guide, these two cubes are used.

Enable Simulate Physics for the lower of the two StaticMesh Components.



Click Add Component to find Physics Constraint.



Position the Physics Constraint Component where you wish the joint of the constraint to be.



You must manually type in the names of the StaticMesh Components you wish to constrain in the Details panel of the Physics Constraint Component. Type in the component name you wish to constrain in the Component Name 1 of the Component Name property.



Type in the component name you wish to constrain in the Component Name 2 of the Component Name property.



Select the Physics Constraint component and move its location to the bottom of the StableMesh component. This will place the anchor point at the bottom of the cube.



Want to know what all the properties on a Physics Constraint Component affect? See the Physics Constraint Reference for specific details.

Rotate the Physics Constraint Component as necessary to account for Linear and Angular Limits.



Place the Blueprint Actor in a level and position it where you need it.



Select Blueprint Actor and go to the Details panel. Select the ConstrainedMesh component in the hierarchy and move it as seen in the picture. In this example, the location was set to X = -300 and Z = 100. This will allow the ConstrainedMesh to swing once you press Simulate.



Test by using Simulate in Editor or Play in Editor.



Constraint

Constraint Behavior

Linear Limits

Advanced

Angular Limits

Advanced

Linear Motor

Advanced

Angular Motor

Advanced

This page contains a reference listing of properties for Physics Constraints separated by major categories.

Constraint



Property

Description

Constraint Actor 1

When a Physics Constraint is placed into the level editor you must specify Actors to constrain. This is the first of 2 Actors.

Component Name 1

The first target component that will be constrained. This can be specified when using Actors to constrain only a specific component and not the Actor root.

Constraint Actor 2

When a Physics Constraint is placed into the level editor you must specify Actors to constrain. This is the second of 2 Actors.

Component Name 2

The second target component that will be constrained. This can be specified when using Actors to constrain only a specific component and not the Actor root.

Joint Name

When constraining in the Physics Asset Tool, this is the name of the Bone that is initially constrained.

Constraint Bone 1

When constraining in the Physics Asset Tool, this is the name of the first joint to constrain.

Constraint Bone 2

When constraining in the Physics Asset Tool, this is the name of the second joint to constrain.

Constraint Behavior



Property

Description

Disable Collision

This disables collision between the constrained components.

Enable Lenear Projection

Linear Projection is a post-solve fixup where the child body is translated to resolve remaining errors using a semi-physical correction. Use this to make chains stiffer at lower iteration counts. Projection only works well if the chain is not interacting with other objects.

Enable Angular Projection

Angular Projection is a post-solve fixup where the child body is rotated to resolve remaining errors using a semi-physical correction. Use this to make chains stiffer at lower iteration counts. Projection only works well if the chain is not interacting with other objects.

Enable Shock Propagation

Shock Propagation increases the mass of the parent body for the last iteration of the position and velocity solve phases. It can help stiffen up joint chains, but is prone to introduce energy down the chain. Use this for world constraints and ragdoll physics.

Projection Linear Alpha

The amount of linear projection to apply, with 0 being no projection and 1 being full projection.

Projection Angular Alpha

The amount of angular projection to apply, with 0 being no projection and 1 being full projection.

Shock Propagation Alpha

The amount of shock propagation to apply, with 0 being no propagation and 1 being full propagation.

Parent Dominantes

When set, the parent body in a constraint will not be affected by the motion of the child.

Linear Limits



Property

Description

XMotion

Indicates the linear constraint applied along the X-axis.

Type

Description

Free

No constraint along this axis

Limited

Limited freedom along this axis. The limit is defined for all axes by the Linear Limit Size property.

Locked

Fully constrained along this axis.

YMotion

Indicates the linear constraint applied along the Y-axis.

Type

Description

Free

No constraint along this axis

Limited

Limited freedom along this axis. The limit is defined for all axes by the Linear Limit Size property.

Locked

Fully constrained along this axis.

ZMotion

Indicates the linear constraint applied along the Z-axis.

Type

Description

Free

No constraint along this axis

Limited

Limited freedom along this axis. The limit is defined for all axes by the Linear Limit Size property.

Locked

Fully constrained along this axis.

Limit

The distance allowed between the two joint reference frames.

Scale Linear Limits

If true, linear limits scale using the absolute min of the 3D scale of the owning component.

Advanced



Property

Description

Soft Constraint

Whether we want to use a soft constraint (spring).

Stiffness

Stiffness of the soft constraint. Only used when Soft Constraint is on.

Damping

Damping of the soft constraint.

Restitution

Controls the amount of bounce when the constraint is violated.

Linear Breakable

Whether it is possible to break the joint with linear force.

Linear Break Threshold

Force needed to break the distance constraint.

Linear Plasticity

Whether it is possible to reset spring rest length from the linear deformation.

Linear Plasticity Type

Whether linear placticity has a operation mode.

Linear Plasticity Threshold

Percent threshold from center of mass distance needed to reset the linear drive position target.This value can be greater than 1.

Contact Transfer Scale

Collision transfer on parent from the joints child. The maximum range is 0.0.



Angular Limits



Property

Description

Swing 1Motion

Indicates whether the Swing1 limit is used.

Type

Description

Free

No constraint around the axis

Limited

Limited freedom around this axis. The limit for each Angular Motion is controlled individually by a correspondingly named Limit property: Swing 1Limit Angle, Swing 2Limit Angle, and Twist Limit Angle

Locked

Fully constraint around this axis

Swing 2Motion

Indicates whether the Swing2 limit is used.

Type

Description

Free

No constraint around the axis

Limited

Limited freedom around this axis. The limit for each Angular Motion is controlled individually by a correspondingly named Limit property: Swing 1Limit Angle, Swing 2Limit Angle, and Twist Limit Angle

Locked

Fully constraint around this axis

Twist Motion

Indicates whether the Twist limit is used.

Type

Description

Free

No constraint around the axis

Limited

Limited freedom around this axis. The limit for each Angular Motion is controlled individually by a correspondingly named Limit property: Swing 1Limit Angle, Swing 2Limit Angle, and Twist Limit Angle

Locked

Fully constraint around this axis

Swing 1Limit Angle

Angle of movement along the XY Plane.

Twist Limit Angle

Angle of movement along the XZ Plane.

Swing 2Limit Angle

Symmetric angle of roll along the X-axis.

Advanced



Property

Description

Swing Limits

Soft Constraint

Whether we want to use a soft constraint (spring).

Stiffness

Stiffness of the soft constraint. Only used when Soft Constraint is on.

Damping

Damping of the soft constraint.

Restitution

Controls the amount of bounce when the constraint is violated.

Twist Limits

Soft Constraint

Whether we want to use a soft constraint (spring).

Stiffness

Stiffness of the soft constraint. Only used when Soft Constraint is on.

Damping

Damping of the soft constraint.

Restitution

Controls the amount of bounce when the constraint is violated.

Angular Breakable

Whether it is possible to break the joint with angular force.

Angular Break Threshold

Torque needed to break the joint.

Angular Placticity

Whether it is possible to reset rotations from the angular displacement.

Angular Placticity Threshold

Degree threshold from target angle needed to reset the target angle.



Linear Motor



Property

Description

Position Target

Enables the position linear motor on one or more axes and sets the local position desired.

Strength

How much force to apply to reach the desired position.

Velocity Target

Enables the velocity linear motor on one or more axes and sets the desired velocity.

Strength

How much force to apply to reach the desired velocity.

Advanced



Property

Description

Max Force

The force limit of the drive.

Angular Motor



Property

Description

Angular Drive Mode

Whether this angular motor uses SLERP (Spherical Linear Interpolation) or decomposes into a Swing Motor and a Twist Motor (cone and roll constraints). SLERP will not work if any of the angular constraints are locked.

Property

Description

SLERP

Sets the motor to SLERP (Spherical Linear Interpolation) mode. SLERP mode will not work if any of the axis of the angular constraint is locked.

Twist and Swing

Sets the motor to Twist and Swing (cone and roll constraints) mode.

Target Orientation

Target orientation relative to the body reference frame.

Drives

Depending on the Angular Drive Mode setting, you can enable or disable the different motors for that mode.

Strength

The force applied to reach the target orientation.

Target Velocity

Target angular velocity relative to the body reference frame

Drives

Depending on the Angular Drive Mode setting, you can enable or disable the different motors for that mode.

Strength

The force applied to reach the target velocity.

Advanced



Property

Description

Max Force

The force limit of the drive.

Physics Constraint Actor

Skeletal Mesh Considerations

Components in Actors

If you need to create a swinging chandelier, a water wheel, or just want to keep a Physics Body in a general area, the Physics Constraint Actor is what you need. This document will cover the usage of the Physics Constraint Actor.

A constraint is a type of joint. It allows you to connect two Actors (presumably one physically simulating), and also apply limits or forces. Unreal Engine has a very flexible and data-driven constraint system that allows designers to make many different types of joints simply by changing some options. The engine has a few default joint types (ball-and-socket, hinge, prismatic) but they only differ in their settings. You should feel free to start with any joint type and experiment with making your configurations.

Physics Constraint Actor

The Physics Constraint Actor can be found in the All Classes tab of the Place Actors panel:



From here, it can be brought into the level, like any other Actor, by clicking and dragging it into the viewport.



Once in the level, you can designate what two Actors it will constrain by using the Details pane, and expanding the Constraint category.



You can either use the pull-down to search for the Actor you wish to select or use the Eyedropper icon to select an Actor from the viewport.



Repeat step 4 for Constraint Actor 2.



Position the Physics Constraint Actor and Constrained Actors where you desire them to be.



In this case, all three Actors (2 boxes and the Physics Constraint) were selected at the same time, then rotated 90 degrees so the red constrained box was above the blue constrained box. This also rotates the Physics Constraint so its Angular Swing Motions are on the correct axes.

Enable Physics on at least one of the Constrained Actors.



Set your desired settings for the Physics Constraint Actor.

The only properties changed for this example are:

Angular Swing 1Motion and Angular Swing 2Motion to ACM_Limited.

Swing 1Limit Angle and Swing 2Limit Angle to 25 degrees.

Disable Swing Limit Soft.



Want to know what all the properties on a Physics Constraint affect? See the Constraints Reference for specific details.

Test the Physics Constraint in Play in Editor or Simulate in Editor.

You may need a way to apply force to the constrained Actors depending on how you have them arranged and not all project templates have a way to do that. A RadialForceActor can be used. It is found in the All Classes tab just like the Physics Constraint Actor and is placed in the same way.



For the cubes used in this document, a force of 50000 was found to be enough to push it around. The radius of the RadialForceActor reduced to fit in the image.

Skeletal Mesh Considerations

If you are constraining a Skeletal Mesh, you will need to provide a Constraint Bone name to the appropriate property. A Bone in this case is a Physics Body in the Skeletal Mesh Physics Asset. The reason for specifying this is while the Physics Bodies will be named after the Skinned Bone they are associated with, a Physics Asset does not need a Physics Body for every Skinned Bone.



Components in Actors

If you would like to constrain a specific Component in an Actor, you can provide a Component Name in the appropriate property. If the root of the Actor is of a type that can be constrained, it will be the default Component that is constrained. However, if you provide a valid Component Name for either Constrained Actor 1 or 2, that Component will become the target of the Physics Constraint. If that Component is a Skeletal Mesh, you must also provide a Bone name in the appropriate property.



Functionally these two Actors and Physics Constraints produce the same effect; however, the Blueprint on the right could produce a different effect by making the Point Lights children of the Root. A Character has a Physics Capsule as a root, but also a Skeletal Mesh, both of which can be targets of the Physics Constraint.

Once you have provided a Component name that the Physics Constraint can attach to, a bounding volume will appear around that component. If a bounding volume does not appear, check the name of your Component and make sure it can be constrained by the Physics Constraint.

Physics Bodies

Physics Constraints

To slow down Physics Bodies, simulate atmospheric drag, or add resistance to a hinge, there are two properties available to Physics Bodies and Physics Constraints: Linear Damping and Angular Damping. Linear Damping controls how much the Physics Body or Constraint resists translation, while Angular Damping controls how much they resist rotating.

Physics Bodies

Every Physics Body has properties for Linear Damping and Angular Damping, found under Physics in the Details panel. These are primarily used to simulate drag, and even a value of 1.0 has a substantial effect on the Physics Body.



For reference, in normal gravity (9.8m/s^2), a Linear Damping value of 30 is enough to stop any single body Actor from falling under the initial pull of gravity, at the start of the simulation. Once more than one Physics Body is interacting (through the use of Physics Constraints or if a collision is occurring), the amount of damping required to stop the Physics Body goes up.

The minimum Linear Damping value to stop a Physics Body that has had force applied to it is around 100.

Finally, with no Angular Damping, a Physics Body will continue to rotate until it is acted upon by an outside force. Even small values can reduce rotation rapidly, while a value of 100 will almost immediately stop any angular motion caused by an outside source.

Physics Constraints

The Damping for Physics Constraints work a bit differently than with Physics Bodies: they only work on Limited Motions and when a motion attempts to go beyond its limit. Setting a Physics Constraint's Motion(s) to Limited will display the Soft Limits:



The two Angular Swing Motions share Damping values, the Angular Twist receives its Damping values, and all the Linear axes use the same Damping values. While they may have separate properties, the properties all have the same effect on the Motions they relate to.

Property

Description

Limit Stiffness

When a limit is exceeded, this value affects how harshly the constraint attempts to stop the offending motion. The default of 50 will barely affect the motion, a value of 5000 will appear to bounce back into the limit, and 50000 will completely deflect the motion.

Limit Damping

Like the Damping on Physics Bodies, this defines how much the motion should be slowed. Unlike Damping on Physics Bodies, the damping effect occurs only when the Motion Limit is exceeded, draining momentum until the Physics Body stops.

The two values work together to create different effects. A high Stiffness and low Damping will look like a hard limit, while having them both high will appear to be the move through tar, coming to a stop gently but quickly. A good deal of experimentation is necessary to find the right values for your specific needs.

For more information on Constraints, refer to: Constraints User Guide

For a reference specific to the properties available to Physics Constraints, refer to: Physics Constraint Reference

Enabling Sub-Stepping

Technical Details

Uses

By using physics Sub-stepping you can get physics simulations that are more accurate and stable, however, this comes at the expense of performance. The most noticeable improvement will be with the ragdoll jitter and other complex physical assets.

Enabling Sub-Stepping

Sub-stepping can be turned on in the Edit > Project Setting > Physics tab:



This feature is still a work in progress and is not fully supported by APEX Destruction. It is also currently not supported on mobile devices. However, we are working towards this as it can greatly improve the look and feel.

Property

Description

Substepping

This enables or disables sub-stepping in your current project.

Substepping Async

Whether to substep the async physics simulation.

Max Substep Delta Time

This is the maximum time, in seconds a sub-step is allowed to take. So, if a full step takes .05 seconds, and Max Substep Delta Time is set to .025, the full step will be split into 2 sub-steps. Now, if the full step were to take a substantial amount of time, say 2 full seconds, then the step will be evenly split based on the value in Max Substeps, and not 80 (2.0/0.025=80) sub-steps. It is worth noting that Max Physics Delta Time limits how long a physics step is permitted to take.

Max Substeps

The maximum number of sub-steps a full step is permitted to be broken into.

Technical Details

Unreal Engine 5 uses a variable frame rate. While this is good for hardware scalability, it creates a challenge for the physics engine, which works best with small fixed time steps. Sub-stepping takes the total frame time and divides it into sub-steps. The physics simulation is then ticked multiple times per frame. The number of sub-steps taken will depend on how small your max sub-step delta time is set to. The smaller the max sub-step time the more stable your simulation will be but at a greater CPU cost.

Sub-stepping is completely hidden from the user, which means that some calls to the physics engine have to be interpolated or maintained. For example, if a user applies a force to an Actor for a single frame, and the frame is internally sub-stepped N times, we need to apply the force for N consecutive simulation steps to achieve the same acceleration. Similarly, if the user sets the target location of an Actor, we must interpolate the target location over multiple sub-steps to maintain the desired speed. All of these details are already handled internally by Unreal Engine, but there are some CPU and memory costs associated with the required bookkeeping.

Another technical detail to be aware of is the way collision callbacks behave while sub-stepping. Unreal Engine runs the physics sub-stepping in a separate physics thread, allowing the game thread to continue doing work. To get the best performance, we delay the collision callbacks until the final sub-step is done. This means that you can get several callbacks for the same collision. For example, if A collides with B and bounces off, you may get a callback for A and B overlapping AND a callback for A and B no longer overlapping in the same frame. Internally all callbacks are pushed into a queue and so callbacks from sub-step 1 will be processed before callbacks from sub-step 2.

Uses

Sub-stepping will significantly improve the quality of complex physics assets, such as those used for a rag doll. However, you should always weigh the improvement in quality to the CPU cost, and what is truly important to your game.

Usage

Increase Walkable Slope

Decrease Walkable Slope

Examples

The Walkable Slope Override on Physics Bodies enables you to tweak what surfaces Characters can walk up. Perhaps a staircase is too steep or maybe you want to enforce the "no walking on the grass" signs, these settings will enable you to do so.

Usage

The Character Movement Component has a property called Walkable Floor Angle. It defaults to around 45 degrees. So, when the Character attempts to move across a surface that is angled higher than this, the Character will not be able to climb the incline or will lose their footing and slide down it.

Depending on the editor you are in, or if you are looking at an Actor in the level, you will find a property, or expandable grouping of properties, prefixed with Override Walkable Slope. Here you can set the Walkable Slope Behavior and Walkable Slope Angle.



Increase Walkable Slope

This setting will increase the walkable slope of a Physics Body up to the value listed in the Walkable Slope Angle property. If Walkable Slope Angle is set to 75, and the angle of the surface of the Physics Body is 65, the Character will be able to walk up to it, regardless of the Character's Walkable Floor Angle.

While Walkable Slope Behavior is set to "Increase Walkable Slope":

A value of 0.0 in the Walkable Slope Angle is essentially the same as No Change in the Walkable Slope Behavior property.

A value of 90.0 in the Walkable Slope Angle will allow the character to traverse any angle on the Physics Body up to (but not including) 90 degrees.

Decrease Walkable Slope

This setting will "cap" the walkable slope of a Physics Body to the value listed in the Walkable Slope Angle property. If Walkable Slope Angle is set to 25, and the angle of the surface of the Physics Body is 35 degrees, the Character will be unable to walk up to it regardless of the Character's Walkable Floor Angle.

While Walkable Slope Behavior is set to "Decrease Walkable Slope":

A value of 0.0 in the Walkable Slope Angle will result in the Character being unable to walk across the Physics Body surface. This can result in some odd behavior for mostly flat surfaces, as the character will skate across them but will not be able to change direction.

A value of 90.0 in the Walkable Slope Angle is essentially the same as No Change in the Walkable Slope Behavior property.

Examples





The blue angle is the default Character Movement Component Walkable Floor Angle, while the green represents the new Increased Walkable Slope angle.

The blue angle is the default Character Movement Component Walkable Floor Angle, while the red represents the new Decreased Walkable Slope angle.

Adding a Physics Field

Applying Physics Types

Adding Meta Data

Defining the Field

Visualizing the Field

The Physics Field System enables users to directly affect Chaos Physics simulations at runtime on a specified region of space. These Fields can be configured to influence the physics simulation in a variety of ways, such as exerting force on rigid bodies and cloth, breaking Geometry Collection Clusters, anchoring or disabling fractured rigid bodies, and interacting with rigid body animation nodes.

In addition, the Physics Field System can communicate with other engine systems, such as Niagara and Materials. These systems can sample Physics Fields by using built-in functions that allow the evaluation of a Field at a specific location.

Fields are set up by creating a Field System Component Blueprint and specifying which systems are allowed to query your Field. You can configure a Field as a World Field to allow Materials and Niagara Systems to sample the Field. You can also configure it as a Chaos Field to allow Geometry Collections, physics objects, cloth, and rigid body animation nodes to interact with it.

Internally, Physics Fields directly affect Chaos Particles. Chaos Particles are defined as a point in space with various properties, such as position, velocity, and mass, that can be affected by the Chaos Physics Solver. Common examples of Chaos Particles include fractured rigid bodies from Geometry Collections, rigid bodies attached to characters, and individual vertices in cloth simulation.

Adding a Physics Field

Once the Blueprint is created, you can add one of three types of Physics Fields - Transient, Construction, or Persistent.

Transient Fields are created, executed, and destroyed at runtime and are used to add a temporary effect to the physics simulation. A common example includes applying external strain or linear velocity to rigid bodies that overlap the field volume.

Construction Fields are created in the Construction Script of the Blueprint and store the field after each compilation. The most common example of this type of field is the Anchor Field which is used to hold Geometry Collection fractured pieces in place.

Persistent Fields are created and remain active until they are explicitly removed. Persistent fields are evaluated at every tick of the physics simulation. A common example is the Disable Field, which can be used to disable the fractured pieces of Geometry Collections that overlap its volume.

Applying Physics Types

Each Field type applies to a specific Physics Type, such as Linear Force, External Strain, or Disabled Threshold to overlapping Chaos Particles. Each Physics Type is further categorized by type as Integer, Scalar or Vector. These categories are referenced when using the built-in functions in the Material Editor and Niagara Systems.

Adding Meta Data

Fields can use different types of Meta Data to add additional information on how they should be evaluated. This Meta Data can provide filtering of the Chaos Particles according to their State (Dynamic, Static, Kinematic, Sleeping or Disabled) and the Object Type (cloth, rigid body, destruction, and character). It can also be used to set where the Physics Field will be evaluated within a rigid body, such as the center of mass or pivot point.

Defining the Field

Each Field is defined by a Blueprint graph that connects to the Field Node pin of the Add Transient Field, Add Construction Field, or Add Persistent Field nodes. The graph defines the scope and properties of the Field.

The Blueprint graph is composed of Field Nodes, which are added as child components of the Field System Component. Common examples of these objects include Box and Radial Falloff, Uniform and Radial Vectors, and Field Operators, which combine overlapping Fields.

Visualizing the Field

Persistent Physics Fields can be visualized in the level by running the appropriate console command. Click Show > Visualize > Physics Field inside the viewport to enable the visualization.



Enter the following commands in the console during simulation:

Console Command

CVARS Available

Description

r.PhysicsField.Rendering.TargetType

1: Dynamic State 2: Linear Force 3: External Strain 4: Kill Particles 5: Linear Velocity 6: Angular Velocity 7: Angular Torque 8: Internal Strain 9: Disabled Threshold 10: Sleeping Threshold 15: Collision Group 16: Activate Disabled

Set which Physics Field target type should be displayed.

r.PhysicsField.Rendering.SystemType

0: Chaos Field 1: World Field

Set which type of Physics Field type should be displayed.

r.PhysicsField.Rendering.EvalType

0: Analytical Evaluation (precise, slower) 1: Sample the Clipmap (approximate, faster)

Set which kind of field evaluation to use.

List of Field Types

List of Field Physics Types

List of Meta Data available for Fields

List of Field Nodes

This page contains reference information for the Physics Field System in Unreal Engine 5.

A Chaos Particle refers to a point in space with various properties, such as position, velocity, and mass, that can be affected by the Chaos Physics Solver. These particles can also have additional properties like orientation, angular velocity, inertia, and geometry.

The Physics Field System comes with three main types of Fields.

List of Field Types

Field Type

Description

Transient Field

These fields are created, executed, and destroyed at runtime during a function or event call. Transient Fields are used to add a temporary effect to the physics simulation, such as applying external strain or linear velocity to rigid bodies that overlap the field volume.

Construction Field

These fields are created in the Construction Script of the Blueprint and store the field after each compilation. The most common example of a Construction Field is the Anchor Field, used to hold Geometry Collection fractured pieces in place. You can remove all the Construction Fields of a component with the RemoveConstructionFields node.

Persistent Field

These fields are created and remain active until they are explicitly removed. Persistent fields are evaluated at every tick of the physics simulation. A common example is the Disable Field, which can be used to disable the fractured pieces of Geometry Collections that overlap its volume. You can remove all the Persistent Fields of a component with the RemovePersistentFields node.

Each Field type applies to a specific Physics Type, such as Linear Force, External Strain, or Disabled Threshold, to overlapping Chaos Particles. Each Physics Type is categorized by type as Integer, Scalar, or Vector.

List of Field Physics Types

Type

Physics Type

Description

Integer

Dynamic State

Sets the state of a Chaos Particle to Static, Dynamic, Kinematic, or sleeping.

Activate Disabled

Activates all the disabled Chaos Particles for which the field value will be 0.

Collision Group

Sets the Chaos Particle Collision Group.

Scalar

External Strain

Applies an external strain over the Chaos Particles. If this external strain is bigger than the internal one, the Geometry Collection cluster will break.

Internal Strain

Adds an internal strain field to the Chaos Particles.

Disabled Threshold

Disables the Chaos Particles if the linear or angular velocity is less than the threshold specified.

Sleeping Threshold

Sets the Chaos Particles to sleep mode if the linear or angular velocity is less than the threshold specified.

Kill Particles

Disables the Chaos Particles whose field evaluation results in a value bigger than 0. These particles are disabled immediately.

Vector

Linear Force

Adds a vector field to the Chaos Particle's current linear force.

Linear Velocity

Adds a vector field to the Chaos Particle's current linear velocity.

Angular Velocity

Adds a vector field to the Chaos Particle's current angular velocity.

Angular Torque

Adds a vector field to the Chaos Particle's current angular torque.

Fields can use different types of Meta Data to add additional information on how they should be evaluated.

List of Meta Data available for Fields

Type

Name

Description

State

Dynamic

Filter for Chaos Particles that are moving based on the physics simulation.

Kinematic

Filter for Chaos Particles that are moving, but not driven by the physics simulation. A common example is moving a Chaos Particle via animation.

Static

Filter for Chaos Particles that are currently not moving and cannot receive forces from the physics simulation.

Sleeping

Filter for Chaos Particles that are currently Sleeping and waiting to be reactivated.

Disabled

Filter for Chaos Particles that are currently disabled.

All

Filter for all Chaos Particles in the Chaos Solver, regardless of state.

Object

Rigid

Apply the Field to all physics rigid objects.

Cloth

Apply the Field to all cloth objects.

Destruction

Apply the Field to all Geometry Collections.

Character

Apply the Field to all the Rigid Body Animation Nodes.

All

Apply the Field to all Chaos objects.

Position

Center of Mass

The Field will be evaluated at the center of mass of the rigid object.

Pivot Point

The Field will be evaluated at the pivot point of the rigid object.

Resolution

Minimum

Filter for Chaos Particles that are currently enabled.

Parents

Filter for all the top parents' clustered Chaos Particles.

Maximum

Filter for Chaos Particles that are enabled and disabled.

Each Field is defined by a Blueprint graph that connects to the Field Node pin of the Physics Field node. The graph defines the scope and properties of the Field.

The Blueprint graph is composed of Field Nodes, which are added as child components of the Field system Component.

List of Field Nodes

Field Type

Name

Description

Integer

Uniform Integer

Sets a uniform integer value independently of the sample position. The output is equal to the magnitude.

Radial Int Mask

If the sample distance from the field position is lesser or greater than the radius, set the interior or exterior value to an intermediate result. The final output value will be affected by the intermediate one based on the Mask Condition.

Scalar

Uniform Scalar

Sets a uniform scalar value independently of the sample position. The output is equal to the magnitude.

Wave Scalar

Sets a temporal wave scalar value according to the sample distance from the field position.

Radial Falloff

Sets the Field scalar value to decrease with the distance to the sphere's center position.

Plane Falloff

Sets the Field scalar value to decrease with the distance to the plane defined by the position/normal pair.

Box Falloff

Sets the Field scalar value to decrease with the distance from the box's center position.

Noise Field

Defines a perlin noise scalar value if the sample is within a box.

Vector

Uniform Vector

Sets a uniform vector value independently of the sample position. The output is equal to the magnitude * direction.

Radial Vector

Sets a radial vector value with its direction being the normalized vector from the sample position to the field position. The output is equal to the magnitude * direction.

Random Vector

Sets a random vector value independently of the sample position. The output is equal to the magnitude * random direction.

Operator

Operator Field

Computes a mathematical operation between two specified fields.

To Integer Field

Converts a scalar field to an integer field.

To Float Field

Converts an integer field to a scalar field.

Culling Field

Evaluates the input field according to the result of the culling field.

Topics

There may be instances in your game where you want to determine if the player character is looking at something, and if so, alter the game state in some way (for example, highlight something when a player looks at it). Or maybe you want to determine if an enemy can see the player character, and if so, start shooting or engaging them in some way. You can accomplish both scenarios by using Traces (or Raycasts) to "shoot" out an invisible ray which will detect geometry between two points and if geometry is hit, return what was hit so that you may then do something with it.

There are different options available when running a Trace. You can run a Trace to check for collision with any Objects where hit Objects are returned, or you can run a Trace by Trace Channel where any Objects hit will return hit information if the Object is set to specifically respond to a specified Trace Channel (which can be set via Collision Settings).

In addition to running traces by Objects or by Trace Channel, you can run your Trace to detect Single hits or Multi hits, where a Single Trace returns a singular hit result and a Multi Trace returns multiple hits resulting from the Trace. With Traces, you can also specify the type of ray that is used: a straight line, a box, a capsule, or a sphere.

Topics

To learn more about Raycasts using Blueprints, follow the links below:



Overview of the Unreal Engine 5 tracing system.



Guides covering Tracing (Raycasting) in Unreal Engine.

Using a Single Line Trace (Raycast) by Channel

Using a Multi Line Trace (Raycast) by Object

Steps

Multi LineTrace By Channel will perform a collision trace along a given line and return all hits encountered (up to and including) the first blocking hit, returning only objects that respond to the specified Trace Channel. What this means (practically), is that if there are many Actors or Components with a collision that Overlap the specified Trace Channel between the start and the end of the trace, you will receive them all. But, if the first hit Blocks the specified Trace Channel, you will only receive that one item. If you want to receive all items regardless of overlap, or blocking a trace channel, you should use a Multi Line Trace By Object node. Below, you will find steps for setting up a Multi Line Trace By Channel Blueprint.

Steps

Follow the steps used for the Line Trace By Channel example to set up a trace.

Replace the LineTrace By Channel node with the Multi Line Trace By Channel node.

Drag off the Out Hits pin and add a For Each Loop node.



Since multiple Actors are hit, for each of them, we want to do something (in this example, print the Actors to the screen).

Drag off the Array Element and add a Break Hit Result node. Then, drag off the Hit Actor, add a Get Display Name (Object) node, and connect to a Print String node.



Click image for a full view.

This will now print to the string each of the Actors hit by the array.

Result

Here, we have a Glass Window in front of a Physics Actor.



The Glass Window is a Destructible Mesh, and we have set its Trace Response to Visibility in its collision settings, which is set to Overlap; while the Physics Actor (Cube) has its Visibility setting to Block. You could use this for situations where you may want to shoot through an object (destroying it) while also hitting an enemy.

Using a Single Line Trace (Raycast) by Channel

Using a Multi Line Trace (Raycast) by Channel

Steps

Result

Multi LineTrace For Objects will perform a collision trace along a given line and return all hits encountered, returning only objects that match one of the specified Object Types. Below, you will find steps for setting up a Multi LineTrace For Objects Blueprint.

Steps

Follow the steps used for the Line Trace By Channel example to set up a trace.

Replace the Line Trace By Channel node with the Multi Line Trace For Objects node.

Drag off the Object Types pin and add a Make Array node, then use the drop-down menus to add Objects to the Array.



Here we assign WorldDynamic and PhysicsBody as our Object Types. You can use the Add pin button to add more Object Types to the Array.

Drag off the Out Hits pin of the trace node and add a For Each Loop node.



This will allow us to do something for each of the Actors hit by the trace.

Drag off the Array Element and add a Break Hit Result node. Then, drag off the Hit Actor, add a Get Display Name (Object) node and connect to a Print String node.



Click image for a full view.

This will now print to the screen each of the Actors hit by the array.

Result

Here, we have a hanging ceiling light (World Dynamic Object Type) in front of a Physics Actor (Physics Body Object Type).



Multi LineTrace For Objects, unlike Multi Line Trace by Channel, does not stop at the first object it hits, which is why the trace continues through the light to the cube.

Using a Single Line Trace (Raycast) by Object

Steps

End Result

Line Trace By Channel will perform a collision trace along a given line and return the first Object that the trace hits. Below, you will find steps for setting up a Single Line Trace By Channel Blueprint.

Steps

Create a new project using the Blueprint First Person template with Include Starter Content and open the project.

In the FirstPerson/Blueprints folder, open the BP_FirstPersonCharacter Blueprint.

Right-click in the graph, search for and add an Event Tick node.



This will cause the trace to run every frame.

Drag off the execute pin, then search for the Line Trace By Channel node.



While holding down the Ctrl key, drag in the First Person Camera component.



The camera is where we will start our trace from.

Drag off the First Person Camera node, and add a Get World Location node, then connect it to the Start of the trace.

Drag off the First Person Camera node again and add a Get World Rotation node.



Here, we are starting the trace from the location of the First Person Camera, then we are getting the rotation of the First Person Camera.

Drag off the Get World Rotation node and add a Get Forward Vector, then drag off that and add a Vector * Float node set to 1500.



We are getting the rotation and the forward vector, extending outward from it by 1500 (this value is the length of the trace).

Drag off the Get World Location node and add a Vector + Vector node, connecting (as shown below) to the End of the Line Trace By Channel node.



Here, we are taking the location of the First Person Camera and extending out from it, 1500 units based on its rotation and forward vector.

On the Line Trace By Channel node, set the Draw Debug Type to For One Frame.



This will allow us to see a debug line while playing in-game to see our line trace.

Drag off the execution out pin of the Line Trace By Channel node and add a Print String node.



Drag off the Out Hit pin and search for Break Hit then add a Break Hit Result node.



Drag off the Hit Actor pin (off of the Break Hit Result node), add a To String (Object) node, and connect it to the Print String node.



Click image for a full view.

This will allow us to debug print the object we hit with our trace.

Click the Compile button, then play in the Editor and look at the cubes in the level.



Here, we have ejected from the First Person's perspective so that you can see the view angle of the trace.

You should see that when the trace hits a cube, it prints the cube to the screen.

End Result

The example above returns all Objects that are set to respond to the provided Trace Channel, however, there may be instances when you want to only return certain objects. In the example above, you can use the Actors to Ignore pin, taking an Array of Actors that should be ignored by the trace (this means that you have to specify each Actor to ignore).

You can also perform a Line Trace By Object where only the specified Object Types are returned. This will allow you to target a specific set of Objects (only to be included in the trace).

Using a Single Line Trace (Raycast) by Channel

Steps

Result

Line Trace For Objects will perform a collision trace along a given line and return the first Object the trace hits that matches one of the specified Object Types. To set up a Line Trace For Objects Blueprint, do the following:

Steps

Follow the steps used for the Line Trace By Channel example to set up a trace.

Replace the Line Trace By Channel node with the Line Trace For Objects node.

Drag off the Object Types pin and add the Make Array node.



On the Make Array node, specify the ObjectType you want to trace for (via the drop-down menu).



Here, we are tracing for WorldDyanmic Objects. You can add more by clicking the Add Pin button.

You can set the rest of the trace up the same way a Line Trace By Channel is setup.



Click image for a full view.

Result

We have added a single WorldDynamic Object to our level.



Only the added Actor is now returning as a hit; consequently, the cubes (since they are Physics Actors) do not return a hit.

Traces Tutorials

Trace by Channel or Object Type

Returning Single or Multiple Hits

Using Shape Traces

Getting UV Coordinates from Trace

Other Features

Traces offer a method for reaching out to your levels and getting feedback on what is present along a line segment. You use them by providing two endpoints (start and end locations) and the physics system "traces" a line segment between those points, reporting any Actors (with collision) that it hits. Traces are essentially the same as Raycasts or Raytraces in other software packages.

Whether you want to know if one Actor can "see" another, figure out the normal of a specific polygon, simulate high velocity weaponry, or if you need to know that an Actor has entered a space; Traces offer you a reliable and computationally cheap solution. This document covers the basic feature set of Traces in Unreal Engine 5 (Unreal Engine).

Trace by Channel or Object Type

Since Traces use the physics system, you'll be able to define the category of thing you want to trace against. There are two broad categories to choose from: Channels and Object Types. Channels are used for things like visibility and the camera, and almost exclusively have to do with tracing. Object Types are the physics types of Actors with the collision in your scene, such as Pawns, Vehicles, Destructible Actors, and so on.

You can add more Channels and Object types as you need them. See Add a Custom Object Type to Your Project for more information on how to do this.

Returning Single or Multiple Hits

When tracing, you can choose to return the first thing that matches the criteria hit by the trace, or you can return everything hit by the trace that matches the criteria.

Special consideration is given to Multi Trace by Channel versus Multi Trace For Objects. When using Muli Trace by Channel the trace will return all Overlaps up to and including the first Block. Imagine shooting a bullet through some tall grass that then impacts a wall.

Multi Trace For Objects will return everything that matches an object type the trace is looking for, assuming the component is set to return trace queries. This makes it great for counting the number of objects between the start and end of the trace.



Hit Results

When a Trace hits something, it returns a Hit Result struct. Available in Blueprints (and also in C++), this is what the struct looks like:



Member

Definition

Blocking Hit

Whether or not the hit was a blocking hit. This is used when Multi Tracing by Channel, due to the ability to have traces simply overlap and not stop the trace.

Initial Overlap

Whether this is the first overlap in a series of results.

Time

This is the "Time" of impact along the trace direction ranging from [0.0 to 1.0]. If there was no hit, this will return 1.0.

Distance

The distance from the TraceStart to the Location in world space. If there was an initial overlap, this value is 0.

Location

The world space location of the hit that is modified based on the shape of the trace.

Impact Point

The absolute location of the hit. Does not include the shape of the trace, only the point of the hit.

Normal

The direction of the trace.

Impact Normal

The normal of the hitting surface.

Phys Mat

The Physical Material of the hit surface.

Hit Actor

The hit Actor.

Hit Component

The specific Component hit.

Hit Bone Name

If traced against a Skeletal Mesh, this is the name of the bone that was hit.

Bone Name

Name of the trace bone hit. It is valid only if we hit a skeletal mesh.

Hit Item

Primitive-specific data, recording which item in the primitive was hit.

Element Index

Index of the part that was hit if colliding with a primitive with multiple parts.

Face Index

If colliding with a trimesh or landscape, this is the index of the face that was hit.

Trace Start

The start location of the trace.

Trace End

The end location of the trace.

Using Shape Traces



When a Line Trace is not enough, you may get the results you are after by using a Shape Trace instead. For example, maybe you are creating a "vision cone" for an enemy, and you want to detect players that enter it. A Line Trace may not be enough as players may be able to avoid detection by ducking under the Line Trace.

In this situation, you could use a Box Trace, Capsule Trace, or Sphere Trace.



Shape Traces function like Line Traces, where you are sweeping and checking for collision from a start point to an endpoint; however, Shape Traces have an added layer of checking because you are using a shape as a volume (of sorts) in your Raycast. You can use a Shape Trace as a Single Trace, or as a Multi Trace, and each is set up in the same manner as a Line Trace; however, you will need to provide additional details about the size (or orientation) of the shape you use.

Getting UV Coordinates from Trace

A trace can return the UV Coordinates of the Actor it hit, assuming trace complex is used. As of 4.14 this only works on Static Mesh Components, Procedural Mesh Components, and BSP. It will not work on Skeletal Mesh Components because you trace against the Physics Asset, which doesn't have UV coordinates (even if you choose to trace complex).

Using this feature will increase CPU memory usage because Unreal Engine needs to keep an additional copy of vertex positions and UV coordinates in the main memory.

Enabling UV Coordinates from Trace

To enable this feature, follow these steps:

Access your Project Settings from the Edit Menu.



Enable the Support UV From Hit Results feature in the Physics Section of your Project Settings.



Restart the Editor.

You can inspect the Blueprint Find Collision UV node using this feature before restarting the editor; however, the node will only return [0.0, 0.0] when you inspect it. If you want the node to return the correct UV data, you'll have to restart the editor.

Other Features

Tracing also has some minor features to limit what they return, making them easier to debug. They can trace against Complex Collision (if a Static Mesh or Procedural Mesh has it enabled). If they are called from an Actor, they can be told to ignore all attached components by enabling the Actor to trace through itself. Finally, they have the option to show a representation of the trace as red and green lines (with larger boxes representing hits).

Specialized Blueprint Node Groups

Components Window

Additional Resources





Components are useful for sharing common behaviors across different classes, such as the ability to display a visual effect, play sounds, or handle behavioral logic.

There are three components available when creating your own Components: Actor Components, Scene Components, and Primitive Components.

Actor Components (class UActorComponent) are useful for abstract behaviors such as movement, inventory or attribute management, and other non-physical concepts. Actor Components do not have a Transform property, meaning they do not have any physical location or rotation in the world.

Scene Components (class USceneComponent, a child of UActorComponent) support location-based behaviors that do not require a geometric representation. This includes spring arms, cameras, physical forces and constraints (not physical objects), and audio.

Primitive Components (class UPrimitiveComponent, a child of USceneComponent) are Scene Components with geometric representation, which are generally used to render visual elements, or to collide or overlap with physical objects. This includes Static or Skeletal Meshes, sprites, billboards, and particle systems as well as box, capsule, and sphere collision volumes.

Choose your implementation method:

Blueprints

C++

Project Setup

In this tutorial, you are tasked with creating gameplay logic for an Actor Component named HealthComponent. Once this Component is attached to an Actor, your Actor will contain the functionality to deduct damage from its health.

In this example, we will use the Third Person Character included in the Third Person Template project.

Begin by creating a New > Games > Third Person > Blueprint Project named Health Component.



Click for full view.

Navigate to Edit > Project Settings > Engine > Input > Bindings > Action Mappings, then click Add (+) to create a new Action Mapping named OnDamagePressed, and set the value to 1.



Click for full view.

Input contains Action Mappings, which can be used to map a button or keypress to an event-driven behavior such as inflicting damage on the player character.

Creating The Actor Component: Health Component

In this section you'll be creating a Health Component, which is an Actor Component that can be attached to any Actor.

Follow the steps below to begin creating the logic that will keep contain and deduct the player's health value.

From the Content Browser, click Add/New > Blueprint Class. Then, from the Pick Parent Class menu, select Actor Component to create a new Actor Component named Bp_HealthComponent.



In the Class Defaults, navigate to the MyBlueprint panel. Then, from the Variables category, click Add (+) to create two float variables named Health and MaxHealth.



Select the Max Health variable and navigate to the Details panel to set the default Max Health value to 100.0.



Creating The Event Dispatcher: Handle Damage

Event Dispatchers can call methods in an Actor that bind themselves, or "listen", to the Event Dispatcher. Then, when the Event Dispatcher calls an event, the Actor listening to it will respond to that event.

Follow the steps below to begin creating a Handle Take Damage Event Dispatcher.

From the My Blueprint panel, navigate to the Event Dispatchers category and click Add (+) to create a new Event Dispatcher named HandleTakeDamage.



Navigate to the Details panel and from the Input category click the Add(+) button to create the following variables:

Variable Name

Type

Description

DamageActor

Bp_HealthComponent

The Actor that will be damaged.

Health

Float

The base health of the Actor.

Damage

Float

The base damage to apply.

DamageType

Damage Type

The class that describes the damage dealt.

InstigatedBy

Controller

The controller that is responsible for causing the damage. For example, a player who throws a grenade.

DamageCauser

Actor

The Actor that represents the cause of the damage. For example, the grenade that has exploded.



Click Compile and Save.



Creating The Event Begin Play Script of Health Component

Drag a copy of Max Health float into the Event Graph.



Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_0" VariableReference=(MemberName="MaxHealth",MemberGuid=7862E6784472ADD0BBCA19ADA27B2A2A,bSelfContext=True) NodePosY=80 NodeGuid=0C56D66946363F91C2A851B8FDBC18A9 CustomProperties Pin (PinId=A39515D84F2129BBF8BD6BA66C8D1E46,PinName="MaxHealth",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_VariableSet_0 ACA6FDCE41213805283C6FA650AB2249,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FB7D064D48DA44169CF939A484234E4A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag the Health float onto the Event Graph, and select Set Health to create a Set Health node.



Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_6" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=16 NodePosY=432 NodeGuid=6D38950341D66D823D43669C8B79D803 CustomProperties Pin (PinId=1E04F60D4F5A816330E0E39B6C3CD6B4,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B8D0E1CA4D8FB404CF5981ABD8A1B7CF,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C6C89784F978452E7974A8C29B9B55E,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B9366B0848DF0F949107A58180792AAD,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C30154744807BBDD76FDC8BE19955745,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Connect the output pin from Max Health float into the input pin of Health from the Set Health node, then connect the output execution pin from the Event Begin Play node into the input execution pin of the Set Health node.



Begin Object Class=/Script/BlueprintGraph.K2Node_Event Name="K2Node_Event_1" EventReference=(MemberParent=Class'"/Script/Engine.ActorComponent"',MemberName="ReceiveBeginPlay") bOverrideFunction=True NodePosX=16 bCommentBubblePinned=True NodeGuid=0C36B33F4DAF0F5DCF7D72955F02A350 CustomProperties Pin (PinId=19BC90F74E064DA9C22319A8615A1F45,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=Class'"/Script/Engine.ActorComponent"',MemberName="ReceiveBeginPlay"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=15A4263D47CA68EFD8DAA18AD4466F52,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_0 DDA7F6994D6064BF7FA56FB638BFC2B1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_0" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=192 NodePosY=16 NodeGuid=C14C7AE14AACFFB22D76E7B05BDED389 CustomProperties Pin (PinId=DDA7F6994D6064BF7FA56FB638BFC2B1,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Event_1 15A4263D47CA68EFD8DAA18AD4466F52,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8FD8F6134A7D661B64C4BCAB1F78F694,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_3 3C0A34434849B97C610F37AD1374F4E3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ACA6FDCE41213805283C6FA650AB2249,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_VariableGet_0 A39515D84F2129BBF8BD6BA66C8D1E46,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9A4E105B40F4B1BBEB35F7AD86A87681,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2B7FA4814F229F1D76DB64890F812CCC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_0" VariableReference=(MemberName="MaxHealth",MemberGuid=7862E6784472ADD0BBCA19ADA27B2A2A,bSelfContext=True) NodePosX=16 NodePosY=80 NodeGuid=0C56D66946363F91C2A851B8FDBC18A9 CustomProperties Pin (PinId=A39515D84F2129BBF8BD6BA66C8D1E46,PinName="MaxHealth",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_VariableSet_0 ACA6FDCE41213805283C6FA650AB2249,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FB7D064D48DA44169CF939A484234E4A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Set Health Node drag off of the output execution pin. From the Actions menu uncheck the Context Sensitive box, then search for and select Bind Event to On Take Any Damage.



Begin Object Class=/Script/BlueprintGraph.K2Node_AddDelegate Name="K2Node_AddDelegate_3" DelegateReference=(MemberParent=Class'"/Script/Engine.Actor"',MemberName="OnTakeAnyDamage") NodePosX=480 NodePosY=-144 ErrorType=1 NodeGuid=E489A8E34C2FBDB3A6812BBDD10FA565 CustomProperties Pin (PinId=3C0A34434849B97C610F37AD1374F4E3,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C586331449187C499B84E9D3BA50523,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9AA4F5244ECF2519855679A362743D7F,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "BaseMCDelegateSelfPinName", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B9FDFD534D76416CB37DDFA0F5283F45,PinName="Delegate",PinFriendlyName=NSLOCTEXT("K2Node", "PinFriendlyDelegatetName", "Event"),PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=Package'"/Script/Engine"',MemberName="TakeAnyDamageSignature__DelegateSignature"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Bind Event to On Take Any Damage node drag off of the Target pin and from the Actions menu, search for and select Get Owner from the Components category.



Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_12" bIsPureFunc=True bIsConstFunc=True FunctionReference=(MemberName="GetOwner",bSelfContext=True) NodePosX=-144 NodePosY=-96 NodeGuid=22AFC8A64B27CC09B4730EAE5A8DF92F CustomProperties Pin (PinId=80C65FF24B67AF2C9701708AD48EFB6D,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ActorComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C236BEF9433FE73D208AF599760D310B,PinName="ReturnValue",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Bind Event to On Take Any Damage node drag off the Event pin and from the Actions menu, search for and select Create Event.



Begin Object Class=/Script/BlueprintGraph.K2Node_CreateDelegate Name="K2Node_CreateDelegate_10" NodePosX=-96 NodePosY=-160 NodeGuid=ACF8D26843533DC7572EEDA595D2B57E CustomProperties Pin (PinId=D6EAE57340F7CB085D7F07A34A48F8A8,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "CreateDelegate_ObjectInputName", "Object"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D924E4BE44970FC883C571A98936D02F,PinName="OutputDelegate",PinFriendlyName=NSLOCTEXT("K2Node", "CreateDelegate_DelegateOutName", "Event"),Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Create Event node, click the Select Function dropdown menu and select the Create matching function.



Creating The Function: Take Damage

When you finish Creating The Event Begin Play Script of Health Component, the function, you created in the last step will automatically open.

You will need to create a function script to handle the logic for deducting health from the Player Character when they receive damage.

To do this, follow the steps below:

Rename created function to Take Damage.



From the My Blueprint panel, navigate to the Variables category and drag the Health variable into the Event Graph.



Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_2" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=256 NodePosY=384 NodeGuid=E665B43446C05625CB683C87EE5DB412 CustomProperties Pin (PinId=CB6EF22543E1EB5A3AC6F194AEC6EBE0,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8151D38045C06149060A54A1B1D2E50A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Take Damage node, drag off the Damage variable. Then from the Actions menu, search for and select Subtract.



Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_0" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Subtract_DoubleDouble") NodePosX=496 NodePosY=304 NodeGuid=0A8D0B904C6488DEBA361BA3404CAB3A CustomProperties Pin (PinId=672AF8284C7DC39881C1E08926400350,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B0D9B48040A48C244179549C6B768FE0,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B810C157430956234891B8ACC5ED0A88,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nSubtraction (A - B)",Direction="EGPD_Output",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off from the Health pin and connect it to the A subtraction float of the Subtract node.



Begin Object Class=/Script/BlueprintGraph.K2Node_FunctionEntry Name="K2Node_FunctionEntry_0" ExtraFlags=201457664 FunctionReference=(MemberName="Take Damage") bIsEditable=True NodePosX=160 NodePosY=80 NodeGuid=82704CCC4A1235B20E402F85612FA991 CustomProperties Pin (PinId=E317F5C94FD764E27EC2E1B89648A2B7,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B37388FC41BD8A65A26AD9A2E251431C,PinName="DamagedActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0873E9F143AEA68FA14EECAD698C312E,PinName="Damage",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_0 B0D9B48040A48C244179549C6B768FE0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7EFB3A5F4843FF5B469447ABB9943750,PinName="DamageType",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6783C1AE42ABE3101046E59D7E5E030D,PinName="InstigatedBy",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EF616E0A45F44BAA91D116AB342E6FD0,PinName="DamageCauser",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="DamagedActor",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Damage",PinType=(PinCategory="real",PinSubCategory="float"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageType",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.DamageType"',bIsConst=True),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="InstigatedBy",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Controller"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageCauser",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_0" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=320 NodePosY=112 NodeGuid=855B44AC4B8D3B2DE6CFFFB071BB3BC6 CustomProperties Pin (PinId=403C8A604B3D0244E6FD3AADF4ACCF78,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_0 672AF8284C7DC39881C1E08926400350,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B3E3BC5F47EE6E18941E86986EA48F1A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_0" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Subtract_DoubleDouble") NodePosX=480 NodePosY=128 NodeGuid=0A8D0B904C6488DEBA361BA3404CAB3A CustomProperties Pin (PinId=672AF8284C7DC39881C1E08926400350,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_0 403C8A604B3D0244E6FD3AADF4ACCF78,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B0D9B48040A48C244179549C6B768FE0,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_0 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B810C157430956234891B8ACC5ED0A88,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nSubtraction (A - B)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off the result from the Subtract node, then from the Actions menu, search for and select Clamp (float).



Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_1" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="FClamp") NodePosX=528 NodePosY=352 NodeGuid=8893EE2E46B721C86E00709B6A16835D CustomProperties Pin (PinId=40B2047B424A46B11450F4BCEBE4FAEF,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ED5EE0894B55D7868004EF979102A955,PinName="Value",PinToolTip="Value\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8CEC940B4C418B97208DF0B1DA84BF8C,PinName="Min",PinToolTip="Min\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A611CB04393B3A483327182B051F55F,PinName="Max",PinToolTip="Max\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="1.0",AutogeneratedDefaultValue="1.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C87F9C0495881E6DF361B99AD4C6FD3,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nReturns Value clamped between A and B (inclusive)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the My Blueprint panel, navigate to the Variables category, then drag the Max Health variable onto the Max float variable pin of the Clamp (float) node.



Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_1" VariableReference=(MemberName="MaxHealth",MemberGuid=7862E6784472ADD0BBCA19ADA27B2A2A,bSelfContext=True) NodePosX=992 NodePosY=544 NodeGuid=700795C544B27DBEF61CC2949D73B38C CustomProperties Pin (PinId=FBFB49BE4A0A790266BEBC8FE8AC686F,PinName="MaxHealth",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=524F7422422D062F1C75508ACE583CF8,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off the execution pin from the Take Damage node, then from the Actions menu search for and select the Branch.



Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_1" NodePosX=400 NodePosY=336 NodeGuid=7E502E5A406962C56D4A07A0F7F083A9 CustomProperties Pin (PinId=D659073F4B6479F99D64BE936A772190,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AAAE377D46DA17515818F398C6EF7F79,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=50E7AF964175E8FDF362DFA344BAC79E,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=30D075CC479F5A83C609DAA8D01DBF65,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Take Damage node, drag off of the Damage variable. Then, from the Actions menu, search for and select the <= (Less Equal) operator.



Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_1" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="LessEqual_DoubleDouble") NodePosX=544 NodePosY=384 NodeGuid=E5AE6D824E203CD94301FA92A88E4325 CustomProperties Pin (PinId=F02D2A124183D122B0381B848781B5AF,PinName="A",PinToolTip="A\nWildcard",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D5B28ED54A9FAE36512483A58F5006AC,PinName="B",PinToolTip="B\nWildcard",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A7B0E48E425DAC43C1F986978EDA15E7,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nReturns true if A is Less than or equal to B (A <= B)",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Less Equal operator node, drag off of the boolean return pin, and plug it into the Condition pin of the Branch node.



Begin Object Class=/Script/BlueprintGraph.K2Node_FunctionEntry Name="K2Node_FunctionEntry_1" ExtraFlags=201457664 FunctionReference=(MemberName="Take Damage") bIsEditable=True NodePosX=160 NodePosY=80 NodeGuid=82704CCC4A1235B20E402F85612FA991 CustomProperties Pin (PinId=E317F5C94FD764E27EC2E1B89648A2B7,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 F26422854172633F0CC1FA938027C78A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B37388FC41BD8A65A26AD9A2E251431C,PinName="DamagedActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0873E9F143AEA68FA14EECAD698C312E,PinName="Damage",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_4 B0D9B48040A48C244179549C6B768FE0,K2Node_PromotableOperator_3 F02D2A124183D122B0381B848781B5AF,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7EFB3A5F4843FF5B469447ABB9943750,PinName="DamageType",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6783C1AE42ABE3101046E59D7E5E030D,PinName="InstigatedBy",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EF616E0A45F44BAA91D116AB342E6FD0,PinName="DamageCauser",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="DamagedActor",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Damage",PinType=(PinCategory="real",PinSubCategory="float"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageType",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.DamageType"',bIsConst=True),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="InstigatedBy",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Controller"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageCauser",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_4" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=352 NodePosY=224 NodeGuid=855B44AC4B8D3B2DE6CFFFB071BB3BC6 CustomProperties Pin (PinId=403C8A604B3D0244E6FD3AADF4ACCF78,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_4 672AF8284C7DC39881C1E08926400350,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B3E3BC5F47EE6E18941E86986EA48F1A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_4" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Subtract_DoubleDouble") NodePosX=512 NodePosY=256 NodeGuid=0A8D0B904C6488DEBA361BA3404CAB3A CustomProperties Pin (PinId=672AF8284C7DC39881C1E08926400350,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_4 403C8A604B3D0244E6FD3AADF4ACCF78,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B0D9B48040A48C244179549C6B768FE0,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B810C157430956234891B8ACC5ED0A88,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nSubtraction (A - B)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 ED5EE0894B55D7868004EF979102A955,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=736 NodePosY=80 NodeGuid=6DCBD32B45024D59F08E3C99D53DF686 CustomProperties Pin (PinId=F26422854172633F0CC1FA938027C78A,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 E317F5C94FD764E27EC2E1B89648A2B7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=870F6E8A400196915A05DD9D46E86CA3,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_PromotableOperator_3 A7B0E48E425DAC43C1F986978EDA15E7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=368AAFA84C78642305E734AFFA6EB7E4,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=358F70F5473EFA3CEC131D888026D0C3,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_3" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="LessEqual_DoubleDouble") NodePosX=400 NodePosY=144 NodeGuid=E21FA398400F9204F494B9AAAC8BB93F CustomProperties Pin (PinId=F02D2A124183D122B0381B848781B5AF,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D5B28ED54A9FAE36512483A58F5006AC,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A7B0E48E425DAC43C1F986978EDA15E7,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nReturns true if A is Less than or equal to B (A <= B)",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 870F6E8A400196915A05DD9D46E86CA3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A9258EED42FF4031F42BC591D33A71BB,PinName="ErrorTolerance",PinToolTip="Error Tolerance\n",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="FClamp") NodePosX=688 NodePosY=208 NodeGuid=7EF54EC2475BD2DCA5627E9579FB97A5 CustomProperties Pin (PinId=40B2047B424A46B11450F4BCEBE4FAEF,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ED5EE0894B55D7868004EF979102A955,PinName="Value",PinToolTip="Value\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_4 B810C157430956234891B8ACC5ED0A88,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8CEC940B4C418B97208DF0B1DA84BF8C,PinName="Min",PinToolTip="Min\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A611CB04393B3A483327182B051F55F,PinName="Max",PinToolTip="Max\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="1.0",AutogeneratedDefaultValue="1.0",LinkedTo=(K2Node_VariableGet_3 FBFB49BE4A0A790266BEBC8FE8AC686F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C87F9C0495881E6DF361B99AD4C6FD3,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nReturns Value clamped between A and B (inclusive)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" VariableReference=(MemberName="MaxHealth",MemberGuid=7862E6784472ADD0BBCA19ADA27B2A2A,bSelfContext=True) NodePosX=528 NodePosY=336 NodeGuid=9DF05FCD485C1FD8EEAB4EA51B50F97C CustomProperties Pin (PinId=FBFB49BE4A0A790266BEBC8FE8AC686F,PinName="MaxHealth",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_0 5A611CB04393B3A483327182B051F55F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=524F7422422D062F1C75508ACE583CF8,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Branch node, drag off of the False execution pin. Then, from the Actions menu search for and select Set Health.



Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_0" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=1616 NodePosY=32 NodeGuid=A677C8F6456877CF8520899414928CFB CustomProperties Pin (PinId=298CCDC04D6BEA4E56B7DFBC6AF7F86A,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_2 358F70F5473EFA3CEC131D888026D0C3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AA39A45343CA767342E5A7BE8A166BB6,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 23C64DA54C6D65C127A9E08DA7B72814,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=98A1E549446B741F82D2F3BF997B6318,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_2 1C87F9C0495881E6DF361B99AD4C6FD3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9D0DF6AE464476B04C15CB90829B029F,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallDelegate_0 93A327D54BD86CFEF5CD249FB5639638,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AA46409C4B8E967BB406CC85EA281E69,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Navigate to the Clamp (float) node and drag off of the Return Value. Then connect it to the Health pin of the Set Health node.



Begin Object Class=/Script/BlueprintGraph.K2Node_FunctionEntry Name="K2Node_FunctionEntry_1" ExtraFlags=201457664 FunctionReference=(MemberName="Take Damage") bIsEditable=True NodePosX=160 NodePosY=80 NodeGuid=82704CCC4A1235B20E402F85612FA991 CustomProperties Pin (PinId=E317F5C94FD764E27EC2E1B89648A2B7,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 F26422854172633F0CC1FA938027C78A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B37388FC41BD8A65A26AD9A2E251431C,PinName="DamagedActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0873E9F143AEA68FA14EECAD698C312E,PinName="Damage",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_4 B0D9B48040A48C244179549C6B768FE0,K2Node_PromotableOperator_3 F02D2A124183D122B0381B848781B5AF,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7EFB3A5F4843FF5B469447ABB9943750,PinName="DamageType",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6783C1AE42ABE3101046E59D7E5E030D,PinName="InstigatedBy",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EF616E0A45F44BAA91D116AB342E6FD0,PinName="DamageCauser",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="DamagedActor",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Damage",PinType=(PinCategory="real",PinSubCategory="float"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageType",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.DamageType"',bIsConst=True),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="InstigatedBy",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Controller"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageCauser",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_4" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=352 NodePosY=224 NodeGuid=855B44AC4B8D3B2DE6CFFFB071BB3BC6 CustomProperties Pin (PinId=403C8A604B3D0244E6FD3AADF4ACCF78,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_4 672AF8284C7DC39881C1E08926400350,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B3E3BC5F47EE6E18941E86986EA48F1A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_4" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Subtract_DoubleDouble") NodePosX=512 NodePosY=256 NodeGuid=0A8D0B904C6488DEBA361BA3404CAB3A CustomProperties Pin (PinId=672AF8284C7DC39881C1E08926400350,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_4 403C8A604B3D0244E6FD3AADF4ACCF78,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B0D9B48040A48C244179549C6B768FE0,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B810C157430956234891B8ACC5ED0A88,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nSubtraction (A - B)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 ED5EE0894B55D7868004EF979102A955,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=736 NodePosY=80 NodeGuid=6DCBD32B45024D59F08E3C99D53DF686 CustomProperties Pin (PinId=F26422854172633F0CC1FA938027C78A,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 E317F5C94FD764E27EC2E1B89648A2B7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=870F6E8A400196915A05DD9D46E86CA3,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_PromotableOperator_3 A7B0E48E425DAC43C1F986978EDA15E7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=368AAFA84C78642305E734AFFA6EB7E4,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=358F70F5473EFA3CEC131D888026D0C3,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_1 D1A1BB644731CDF09CA1F2B40C47C958,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_3" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="LessEqual_DoubleDouble") NodePosX=400 NodePosY=144 NodeGuid=E21FA398400F9204F494B9AAAC8BB93F CustomProperties Pin (PinId=F02D2A124183D122B0381B848781B5AF,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D5B28ED54A9FAE36512483A58F5006AC,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A7B0E48E425DAC43C1F986978EDA15E7,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nReturns true if A is Less than or equal to B (A <= B)",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 870F6E8A400196915A05DD9D46E86CA3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A9258EED42FF4031F42BC591D33A71BB,PinName="ErrorTolerance",PinToolTip="Error Tolerance\n",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="FClamp") NodePosX=688 NodePosY=208 NodeGuid=7EF54EC2475BD2DCA5627E9579FB97A5 CustomProperties Pin (PinId=40B2047B424A46B11450F4BCEBE4FAEF,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ED5EE0894B55D7868004EF979102A955,PinName="Value",PinToolTip="Value\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_4 B810C157430956234891B8ACC5ED0A88,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8CEC940B4C418B97208DF0B1DA84BF8C,PinName="Min",PinToolTip="Min\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A611CB04393B3A483327182B051F55F,PinName="Max",PinToolTip="Max\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="1.0",AutogeneratedDefaultValue="1.0",LinkedTo=(K2Node_VariableGet_3 FBFB49BE4A0A790266BEBC8FE8AC686F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C87F9C0495881E6DF361B99AD4C6FD3,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nReturns Value clamped between A and B (inclusive)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_VariableSet_1 86F2F28F4D4860C3CFB5AFBC7076DC98,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" VariableReference=(MemberName="MaxHealth",MemberGuid=7862E6784472ADD0BBCA19ADA27B2A2A,bSelfContext=True) NodePosX=528 NodePosY=336 NodeGuid=9DF05FCD485C1FD8EEAB4EA51B50F97C CustomProperties Pin (PinId=FBFB49BE4A0A790266BEBC8FE8AC686F,PinName="MaxHealth",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_0 5A611CB04393B3A483327182B051F55F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=524F7422422D062F1C75508ACE583CF8,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_1" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=944 NodePosY=96 NodeGuid=34D2F5474061BD9D673E85A64D6F259E CustomProperties Pin (PinId=D1A1BB644731CDF09CA1F2B40C47C958,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 358F70F5473EFA3CEC131D888026D0C3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2658DF5B4FBB3A2B5F63438CE1155C06,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=86F2F28F4D4860C3CFB5AFBC7076DC98,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_0 1C87F9C0495881E6DF361B99AD4C6FD3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B14A4CF0418461215D1F61812AF41C4D,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B38165F94FE4B68B2A13D1ABF51CDFA7,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Set Health node, drag off the output execution pin, then from the Actions menu search for and select Call Handle Take Damage.



Begin Object Class=/Script/BlueprintGraph.K2Node_CallDelegate Name="K2Node_CallDelegate_1" DelegateReference=(MemberParent=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',MemberName="HandleTakeDamage",MemberGuid=9800108D42BDCAAC9CC21B85063DD7D6) NodePosX=1344 NodePosY=368 NodeGuid=6C1B570745BE5517EF26B785AA696539 CustomProperties Pin (PinId=7845807F4F8971CA7749CE87722AAFAE,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=922BC8CF4634FFEAB0348C8566301C5F,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D8120929432002135E9B47940272FA30,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "BaseMCDelegateSelfPinName", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AE3355CF4D94226E35C6AA9191AE3828,PinName="DamageActor",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2E67C60647E5F66B4785B9A2E0B222BD,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7B461D9247626277D69851BE2C2DC10B,PinName="Damage",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6CCE815C4CD2B62AF7D9C6BD74E91D00,PinName="DamageType",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=55F5859043605B189C7673B3D09BDAC9,PinName="InstigatedBy",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7148AC1A475D59971CC1CD9577AA09AD,PinName="DamageCauser",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Set Health node, connect the Health output pin to the Health input pin of the Call Handle Take Damage node.



Begin Object Class=/Script/BlueprintGraph.K2Node_FunctionEntry Name="K2Node_FunctionEntry_1" ExtraFlags=201457664 FunctionReference=(MemberName="Take Damage") bIsEditable=True NodePosX=160 NodePosY=80 NodeGuid=82704CCC4A1235B20E402F85612FA991 CustomProperties Pin (PinId=E317F5C94FD764E27EC2E1B89648A2B7,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 F26422854172633F0CC1FA938027C78A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B37388FC41BD8A65A26AD9A2E251431C,PinName="DamagedActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0873E9F143AEA68FA14EECAD698C312E,PinName="Damage",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_4 B0D9B48040A48C244179549C6B768FE0,K2Node_PromotableOperator_3 F02D2A124183D122B0381B848781B5AF,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7EFB3A5F4843FF5B469447ABB9943750,PinName="DamageType",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6783C1AE42ABE3101046E59D7E5E030D,PinName="InstigatedBy",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EF616E0A45F44BAA91D116AB342E6FD0,PinName="DamageCauser",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="DamagedActor",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Damage",PinType=(PinCategory="real",PinSubCategory="float"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageType",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.DamageType"',bIsConst=True),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="InstigatedBy",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Controller"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageCauser",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_4" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=320 NodePosY=224 NodeGuid=855B44AC4B8D3B2DE6CFFFB071BB3BC6 CustomProperties Pin (PinId=403C8A604B3D0244E6FD3AADF4ACCF78,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_4 672AF8284C7DC39881C1E08926400350,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B3E3BC5F47EE6E18941E86986EA48F1A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_4" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Subtract_DoubleDouble") NodePosX=464 NodePosY=224 NodeGuid=0A8D0B904C6488DEBA361BA3404CAB3A CustomProperties Pin (PinId=672AF8284C7DC39881C1E08926400350,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_4 403C8A604B3D0244E6FD3AADF4ACCF78,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B0D9B48040A48C244179549C6B768FE0,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B810C157430956234891B8ACC5ED0A88,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nSubtraction (A - B)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 ED5EE0894B55D7868004EF979102A955,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallDelegate Name="K2Node_CallDelegate_0" DelegateReference=(MemberParent=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',MemberName="HandleTakeDamage",MemberGuid=9800108D42BDCAAC9CC21B85063DD7D6) NodePosX=1008 NodePosY=80 NodeGuid=FDF55BD748C413034CCA40A0D159FADA CustomProperties Pin (PinId=23C64DA54C6D65C127A9E08DA7B72814,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_1 2658DF5B4FBB3A2B5F63438CE1155C06,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6CD09DA14FCE6D0ABB0C23871A696CA5,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=79F26F37402479BD10F29A9E2845DE2C,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "BaseMCDelegateSelfPinName", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=912F056E41D63C2E399160A5AED876D1,PinName="DamageActor",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=93A327D54BD86CFEF5CD249FB5639638,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_1 B38165F94FE4B68B2A13D1ABF51CDFA7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DF376D7743DD47A0D18C76A42829FEC0,PinName="Damage",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CB5821F8485DA6940DCA39AE15E2572E,PinName="DamageType",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=251C8796493CC3D5D1DEAEB0B0933F8C,PinName="InstigatedBy",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2F8EDEA0440D02F0528303AD2FA7F6B3,PinName="DamageCauser",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=624 NodePosY=80 NodeGuid=6DCBD32B45024D59F08E3C99D53DF686 CustomProperties Pin (PinId=F26422854172633F0CC1FA938027C78A,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 E317F5C94FD764E27EC2E1B89648A2B7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=870F6E8A400196915A05DD9D46E86CA3,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_PromotableOperator_3 A7B0E48E425DAC43C1F986978EDA15E7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=368AAFA84C78642305E734AFFA6EB7E4,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=358F70F5473EFA3CEC131D888026D0C3,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_1 D1A1BB644731CDF09CA1F2B40C47C958,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_3" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="LessEqual_DoubleDouble") NodePosX=416 NodePosY=144 NodeGuid=E21FA398400F9204F494B9AAAC8BB93F CustomProperties Pin (PinId=F02D2A124183D122B0381B848781B5AF,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D5B28ED54A9FAE36512483A58F5006AC,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A7B0E48E425DAC43C1F986978EDA15E7,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nReturns true if A is Less than or equal to B (A <= B)",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 870F6E8A400196915A05DD9D46E86CA3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A9258EED42FF4031F42BC591D33A71BB,PinName="ErrorTolerance",PinToolTip="Error Tolerance\n",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="FClamp") NodePosX=624 NodePosY=192 NodeGuid=7EF54EC2475BD2DCA5627E9579FB97A5 CustomProperties Pin (PinId=40B2047B424A46B11450F4BCEBE4FAEF,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ED5EE0894B55D7868004EF979102A955,PinName="Value",PinToolTip="Value\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_4 B810C157430956234891B8ACC5ED0A88,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8CEC940B4C418B97208DF0B1DA84BF8C,PinName="Min",PinToolTip="Min\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A611CB04393B3A483327182B051F55F,PinName="Max",PinToolTip="Max\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="1.0",AutogeneratedDefaultValue="1.0",LinkedTo=(K2Node_VariableGet_3 FBFB49BE4A0A790266BEBC8FE8AC686F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C87F9C0495881E6DF361B99AD4C6FD3,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nReturns Value clamped between A and B (inclusive)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_VariableSet_1 86F2F28F4D4860C3CFB5AFBC7076DC98,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" VariableReference=(MemberName="MaxHealth",MemberGuid=7862E6784472ADD0BBCA19ADA27B2A2A,bSelfContext=True) NodePosX=464 NodePosY=320 NodeGuid=9DF05FCD485C1FD8EEAB4EA51B50F97C CustomProperties Pin (PinId=FBFB49BE4A0A790266BEBC8FE8AC686F,PinName="MaxHealth",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_0 5A611CB04393B3A483327182B051F55F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=524F7422422D062F1C75508ACE583CF8,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_1" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=848 NodePosY=96 NodeGuid=34D2F5474061BD9D673E85A64D6F259E CustomProperties Pin (PinId=D1A1BB644731CDF09CA1F2B40C47C958,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 358F70F5473EFA3CEC131D888026D0C3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2658DF5B4FBB3A2B5F63438CE1155C06,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 23C64DA54C6D65C127A9E08DA7B72814,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=86F2F28F4D4860C3CFB5AFBC7076DC98,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_0 1C87F9C0495881E6DF361B99AD4C6FD3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B14A4CF0418461215D1F61812AF41C4D,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B38165F94FE4B68B2A13D1ABF51CDFA7,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallDelegate_0 93A327D54BD86CFEF5CD249FB5639638,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Call Handle Take Damage node, drag off the input pin Damage Actor, then from the Actions menu search for and select Get a reference to self.



Begin Object Class=/Script/BlueprintGraph.K2Node_Self Name="K2Node_Self_1" NodePosX=848 NodePosY=464 NodeGuid=C73033EC40860C3D29681683E39D3444 CustomProperties Pin (PinId=8F3FF98C47B497E9854823B90DBAD678,PinName="self",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="self",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Navigate to the Take Damage node, then connect the Damage, Damage Type, Instigated By, and Damage Causer pins into their respective pins from the Call Handle Take Damage node.



Begin Object Class=/Script/BlueprintGraph.K2Node_FunctionEntry Name="K2Node_FunctionEntry_1" ExtraFlags=201457664 FunctionReference=(MemberName="Take Damage") bIsEditable=True NodePosX=112 NodePosY=80 NodeGuid=82704CCC4A1235B20E402F85612FA991 CustomProperties Pin (PinId=E317F5C94FD764E27EC2E1B89648A2B7,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 F26422854172633F0CC1FA938027C78A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B37388FC41BD8A65A26AD9A2E251431C,PinName="DamagedActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0873E9F143AEA68FA14EECAD698C312E,PinName="Damage",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_3 F02D2A124183D122B0381B848781B5AF,K2Node_Knot_19 141156B7476A07026BDE089C300862C1,K2Node_Knot_20 7140CDF14A9B7168E6AAD5BDBF285EE6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7EFB3A5F4843FF5B469447ABB9943750,PinName="DamageType",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_17 0F1DB63E4E4CDBE98D9BAF99FA78B0A7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6783C1AE42ABE3101046E59D7E5E030D,PinName="InstigatedBy",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_15 7E9B0BF44B3BC078B20BF4935388B664,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EF616E0A45F44BAA91D116AB342E6FD0,PinName="DamageCauser",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_13 A35B642D48F9A8B87A35478C21F5D195,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="DamagedActor",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Damage",PinType=(PinCategory="real",PinSubCategory="float"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageType",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.DamageType"',bIsConst=True),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="InstigatedBy",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Controller"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageCauser",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_4" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=320 NodePosY=224 NodeGuid=855B44AC4B8D3B2DE6CFFFB071BB3BC6 CustomProperties Pin (PinId=403C8A604B3D0244E6FD3AADF4ACCF78,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_4 672AF8284C7DC39881C1E08926400350,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B3E3BC5F47EE6E18941E86986EA48F1A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_4" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Subtract_DoubleDouble") NodePosX=464 NodePosY=224 NodeGuid=0A8D0B904C6488DEBA361BA3404CAB3A CustomProperties Pin (PinId=672AF8284C7DC39881C1E08926400350,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_4 403C8A604B3D0244E6FD3AADF4ACCF78,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B0D9B48040A48C244179549C6B768FE0,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_20 405E4121421CE9B061F666834ECD4F5D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B810C157430956234891B8ACC5ED0A88,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nSubtraction (A - B)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 ED5EE0894B55D7868004EF979102A955,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallDelegate Name="K2Node_CallDelegate_0" DelegateReference=(MemberParent=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',MemberName="HandleTakeDamage",MemberGuid=9800108D42BDCAAC9CC21B85063DD7D6) NodePosX=1008 NodePosY=80 NodeGuid=FDF55BD748C413034CCA40A0D159FADA CustomProperties Pin (PinId=23C64DA54C6D65C127A9E08DA7B72814,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_1 2658DF5B4FBB3A2B5F63438CE1155C06,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6CD09DA14FCE6D0ABB0C23871A696CA5,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=79F26F37402479BD10F29A9E2845DE2C,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "BaseMCDelegateSelfPinName", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=912F056E41D63C2E399160A5AED876D1,PinName="DamageActor",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Self_1 8F3FF98C47B497E9854823B90DBAD678,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=93A327D54BD86CFEF5CD249FB5639638,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_1 B38165F94FE4B68B2A13D1ABF51CDFA7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DF376D7743DD47A0D18C76A42829FEC0,PinName="Damage",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_18 7CC571B2481D5BE3215EFAAFC636A85B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CB5821F8485DA6940DCA39AE15E2572E,PinName="DamageType",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_16 98CE6C5D489F2F058DDF85B8284B7D1A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=251C8796493CC3D5D1DEAEB0B0933F8C,PinName="InstigatedBy",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_14 7B1B863F4C2D57C8BF9834950CF8F1FA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2F8EDEA0440D02F0528303AD2FA7F6B3,PinName="DamageCauser",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_10 6BCA86D54CA6DCA7348288A8C5E582EB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=576 NodePosY=80 NodeGuid=6DCBD32B45024D59F08E3C99D53DF686 CustomProperties Pin (PinId=F26422854172633F0CC1FA938027C78A,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 E317F5C94FD764E27EC2E1B89648A2B7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=870F6E8A400196915A05DD9D46E86CA3,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_PromotableOperator_3 A7B0E48E425DAC43C1F986978EDA15E7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=368AAFA84C78642305E734AFFA6EB7E4,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=358F70F5473EFA3CEC131D888026D0C3,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_1 D1A1BB644731CDF09CA1F2B40C47C958,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_3" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="LessEqual_DoubleDouble") NodePosX=336 NodePosY=144 NodeGuid=E21FA398400F9204F494B9AAAC8BB93F CustomProperties Pin (PinId=F02D2A124183D122B0381B848781B5AF,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D5B28ED54A9FAE36512483A58F5006AC,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A7B0E48E425DAC43C1F986978EDA15E7,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nReturns true if A is Less than or equal to B (A <= B)",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 870F6E8A400196915A05DD9D46E86CA3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A9258EED42FF4031F42BC591D33A71BB,PinName="ErrorTolerance",PinToolTip="Error Tolerance\n",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="FClamp") NodePosX=624 NodePosY=192 NodeGuid=7EF54EC2475BD2DCA5627E9579FB97A5 CustomProperties Pin (PinId=40B2047B424A46B11450F4BCEBE4FAEF,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ED5EE0894B55D7868004EF979102A955,PinName="Value",PinToolTip="Value\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_4 B810C157430956234891B8ACC5ED0A88,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8CEC940B4C418B97208DF0B1DA84BF8C,PinName="Min",PinToolTip="Min\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A611CB04393B3A483327182B051F55F,PinName="Max",PinToolTip="Max\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="1.0",AutogeneratedDefaultValue="1.0",LinkedTo=(K2Node_VariableGet_3 FBFB49BE4A0A790266BEBC8FE8AC686F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C87F9C0495881E6DF361B99AD4C6FD3,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nReturns Value clamped between A and B (inclusive)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_VariableSet_1 86F2F28F4D4860C3CFB5AFBC7076DC98,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" VariableReference=(MemberName="MaxHealth",MemberGuid=7862E6784472ADD0BBCA19ADA27B2A2A,bSelfContext=True) NodePosX=464 NodePosY=320 NodeGuid=9DF05FCD485C1FD8EEAB4EA51B50F97C CustomProperties Pin (PinId=FBFB49BE4A0A790266BEBC8FE8AC686F,PinName="MaxHealth",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_0 5A611CB04393B3A483327182B051F55F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=524F7422422D062F1C75508ACE583CF8,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_1" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=848 NodePosY=96 NodeGuid=34D2F5474061BD9D673E85A64D6F259E CustomProperties Pin (PinId=D1A1BB644731CDF09CA1F2B40C47C958,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 358F70F5473EFA3CEC131D888026D0C3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2658DF5B4FBB3A2B5F63438CE1155C06,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 23C64DA54C6D65C127A9E08DA7B72814,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=86F2F28F4D4860C3CFB5AFBC7076DC98,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_0 1C87F9C0495881E6DF361B99AD4C6FD3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B14A4CF0418461215D1F61812AF41C4D,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B38165F94FE4B68B2A13D1ABF51CDFA7,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallDelegate_0 93A327D54BD86CFEF5CD249FB5639638,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Self Name="K2Node_Self_1" NodePosX=848 NodePosY=192 NodeGuid=C73033EC40860C3D29681683E39D3444 CustomProperties Pin (PinId=8F3FF98C47B497E9854823B90DBAD678,PinName="self",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="self",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 912F056E41D63C2E399160A5AED876D1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_10" NodePosX=944 NodePosY=400 NodeGuid=A03F528644149E6032849FA6FF1C513E CustomProperties Pin (PinId=2329358D4505388E2AF57199A1371A95,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_13 63950A26426446B56CF15AAB8C2057B5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6BCA86D54CA6DCA7348288A8C5E582EB,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 2F8EDEA0440D02F0528303AD2FA7F6B3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_13" NodePosX=304 NodePosY=400 NodeGuid=39BA547B46E915F1311BA3BF043F5ECA CustomProperties Pin (PinId=A35B642D48F9A8B87A35478C21F5D195,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 EF616E0A45F44BAA91D116AB342E6FD0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=63950A26426446B56CF15AAB8C2057B5,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_10 2329358D4505388E2AF57199A1371A95,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_14" NodePosX=928 NodePosY=384 NodeGuid=4A6B911547AF062B355E199735F2949A CustomProperties Pin (PinId=0E7997AA43956A99EDAFF8901A84D258,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_15 F53AA008478964DFA66F069AB21D3C80,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7B1B863F4C2D57C8BF9834950CF8F1FA,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 251C8796493CC3D5D1DEAEB0B0933F8C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_15" NodePosX=320 NodePosY=384 NodeGuid=C6E19E93432DE8FB283BFABF8A21514D CustomProperties Pin (PinId=7E9B0BF44B3BC078B20BF4935388B664,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 6783C1AE42ABE3101046E59D7E5E030D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F53AA008478964DFA66F069AB21D3C80,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_14 0E7997AA43956A99EDAFF8901A84D258,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_16" NodePosX=912 NodePosY=368 NodeGuid=C93093884E02E88D9F4983ADA4C4C4CB CustomProperties Pin (PinId=890577A74A5AC8F2E507C78D88A893A3,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_17 16808D124A1EE4C5755372B53C7CEE35,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=98CE6C5D489F2F058DDF85B8284B7D1A,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 CB5821F8485DA6940DCA39AE15E2572E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_17" NodePosX=336 NodePosY=368 NodeGuid=E87F2A444C12B10044B0D680EA38EE6D CustomProperties Pin (PinId=0F1DB63E4E4CDBE98D9BAF99FA78B0A7,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 7EFB3A5F4843FF5B469447ABB9943750,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=16808D124A1EE4C5755372B53C7CEE35,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_16 890577A74A5AC8F2E507C78D88A893A3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_18" NodePosX=896 NodePosY=352 NodeGuid=00B7A0294210FD5F276D98975C7D7F3D CustomProperties Pin (PinId=C98005C048B768EA897DE58C4AAE52AC,PinName="InputPin",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_19 EF2F82B64A6BF7482B5AD9933798D700,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7CC571B2481D5BE3215EFAAFC636A85B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 DF376D7743DD47A0D18C76A42829FEC0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_19" NodePosX=352 NodePosY=352 NodeGuid=C635791F456E7EF960CB9EAE4F2AF3A8 CustomProperties Pin (PinId=141156B7476A07026BDE089C300862C1,PinName="InputPin",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EF2F82B64A6BF7482B5AD9933798D700,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_18 C98005C048B768EA897DE58C4AAE52AC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_20" NodePosX=352 NodePosY=272 NodeGuid=0035A8904BD38A1ACBE8F9B8702ADDA4 CustomProperties Pin (PinId=7140CDF14A9B7168E6AAD5BDBF285EE6,PinName="InputPin",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=405E4121421CE9B061F666834ECD4F5D,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_4 B0D9B48040A48C244179549C6B768FE0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Click Compile and Save.



Finished Blueprint

Take Damage Function



Begin Object Class=/Script/BlueprintGraph.K2Node_FunctionEntry Name="K2Node_FunctionEntry_1" ExtraFlags=201457664 FunctionReference=(MemberName="Take Damage") bIsEditable=True NodePosX=112 NodePosY=80 NodeGuid=82704CCC4A1235B20E402F85612FA991 CustomProperties Pin (PinId=E317F5C94FD764E27EC2E1B89648A2B7,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 F26422854172633F0CC1FA938027C78A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B37388FC41BD8A65A26AD9A2E251431C,PinName="DamagedActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0873E9F143AEA68FA14EECAD698C312E,PinName="Damage",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_3 F02D2A124183D122B0381B848781B5AF,K2Node_Knot_19 141156B7476A07026BDE089C300862C1,K2Node_Knot_20 7140CDF14A9B7168E6AAD5BDBF285EE6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7EFB3A5F4843FF5B469447ABB9943750,PinName="DamageType",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_17 0F1DB63E4E4CDBE98D9BAF99FA78B0A7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6783C1AE42ABE3101046E59D7E5E030D,PinName="InstigatedBy",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_15 7E9B0BF44B3BC078B20BF4935388B664,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EF616E0A45F44BAA91D116AB342E6FD0,PinName="DamageCauser",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_13 A35B642D48F9A8B87A35478C21F5D195,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="DamagedActor",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Damage",PinType=(PinCategory="real",PinSubCategory="float"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageType",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.DamageType"',bIsConst=True),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="InstigatedBy",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Controller"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageCauser",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_4" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=320 NodePosY=224 NodeGuid=855B44AC4B8D3B2DE6CFFFB071BB3BC6 CustomProperties Pin (PinId=403C8A604B3D0244E6FD3AADF4ACCF78,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_4 672AF8284C7DC39881C1E08926400350,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B3E3BC5F47EE6E18941E86986EA48F1A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_4" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="Subtract_DoubleDouble") NodePosX=464 NodePosY=224 NodeGuid=0A8D0B904C6488DEBA361BA3404CAB3A CustomProperties Pin (PinId=672AF8284C7DC39881C1E08926400350,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_4 403C8A604B3D0244E6FD3AADF4ACCF78,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B0D9B48040A48C244179549C6B768FE0,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_20 405E4121421CE9B061F666834ECD4F5D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B810C157430956234891B8ACC5ED0A88,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nSubtraction (A - B)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_0 ED5EE0894B55D7868004EF979102A955,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallDelegate Name="K2Node_CallDelegate_0" DelegateReference=(MemberParent=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',MemberName="HandleTakeDamage",MemberGuid=9800108D42BDCAAC9CC21B85063DD7D6) NodePosX=1008 NodePosY=80 NodeGuid=FDF55BD748C413034CCA40A0D159FADA CustomProperties Pin (PinId=23C64DA54C6D65C127A9E08DA7B72814,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_1 2658DF5B4FBB3A2B5F63438CE1155C06,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6CD09DA14FCE6D0ABB0C23871A696CA5,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=79F26F37402479BD10F29A9E2845DE2C,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "BaseMCDelegateSelfPinName", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=912F056E41D63C2E399160A5AED876D1,PinName="DamageActor",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Self_1 8F3FF98C47B497E9854823B90DBAD678,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=93A327D54BD86CFEF5CD249FB5639638,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_1 B38165F94FE4B68B2A13D1ABF51CDFA7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DF376D7743DD47A0D18C76A42829FEC0,PinName="Damage",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_18 7CC571B2481D5BE3215EFAAFC636A85B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CB5821F8485DA6940DCA39AE15E2572E,PinName="DamageType",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_16 98CE6C5D489F2F058DDF85B8284B7D1A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=251C8796493CC3D5D1DEAEB0B0933F8C,PinName="InstigatedBy",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_14 7B1B863F4C2D57C8BF9834950CF8F1FA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2F8EDEA0440D02F0528303AD2FA7F6B3,PinName="DamageCauser",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_10 6BCA86D54CA6DCA7348288A8C5E582EB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=576 NodePosY=80 NodeGuid=6DCBD32B45024D59F08E3C99D53DF686 CustomProperties Pin (PinId=F26422854172633F0CC1FA938027C78A,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 E317F5C94FD764E27EC2E1B89648A2B7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=870F6E8A400196915A05DD9D46E86CA3,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_PromotableOperator_3 A7B0E48E425DAC43C1F986978EDA15E7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=368AAFA84C78642305E734AFFA6EB7E4,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=358F70F5473EFA3CEC131D888026D0C3,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_1 D1A1BB644731CDF09CA1F2B40C47C958,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_3" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="LessEqual_DoubleDouble") NodePosX=336 NodePosY=144 NodeGuid=E21FA398400F9204F494B9AAAC8BB93F CustomProperties Pin (PinId=F02D2A124183D122B0381B848781B5AF,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D5B28ED54A9FAE36512483A58F5006AC,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A7B0E48E425DAC43C1F986978EDA15E7,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nReturns true if A is Less than or equal to B (A <= B)",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 870F6E8A400196915A05DD9D46E86CA3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A9258EED42FF4031F42BC591D33A71BB,PinName="ErrorTolerance",PinToolTip="Error Tolerance\n",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="FClamp") NodePosX=624 NodePosY=192 NodeGuid=7EF54EC2475BD2DCA5627E9579FB97A5 CustomProperties Pin (PinId=40B2047B424A46B11450F4BCEBE4FAEF,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetMathLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ED5EE0894B55D7868004EF979102A955,PinName="Value",PinToolTip="Value\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_PromotableOperator_4 B810C157430956234891B8ACC5ED0A88,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8CEC940B4C418B97208DF0B1DA84BF8C,PinName="Min",PinToolTip="Min\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A611CB04393B3A483327182B051F55F,PinName="Max",PinToolTip="Max\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="1.0",AutogeneratedDefaultValue="1.0",LinkedTo=(K2Node_VariableGet_3 FBFB49BE4A0A790266BEBC8FE8AC686F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C87F9C0495881E6DF361B99AD4C6FD3,PinName="ReturnValue",PinToolTip="Return Value\nFloat (double-precision)\n\nReturns Value clamped between A and B (inclusive)",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_VariableSet_1 86F2F28F4D4860C3CFB5AFBC7076DC98,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" VariableReference=(MemberName="MaxHealth",MemberGuid=7862E6784472ADD0BBCA19ADA27B2A2A,bSelfContext=True) NodePosX=464 NodePosY=320 NodeGuid=9DF05FCD485C1FD8EEAB4EA51B50F97C CustomProperties Pin (PinId=FBFB49BE4A0A790266BEBC8FE8AC686F,PinName="MaxHealth",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_0 5A611CB04393B3A483327182B051F55F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=524F7422422D062F1C75508ACE583CF8,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_1" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=848 NodePosY=96 NodeGuid=34D2F5474061BD9D673E85A64D6F259E CustomProperties Pin (PinId=D1A1BB644731CDF09CA1F2B40C47C958,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 358F70F5473EFA3CEC131D888026D0C3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2658DF5B4FBB3A2B5F63438CE1155C06,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 23C64DA54C6D65C127A9E08DA7B72814,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=86F2F28F4D4860C3CFB5AFBC7076DC98,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallFunction_0 1C87F9C0495881E6DF361B99AD4C6FD3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B14A4CF0418461215D1F61812AF41C4D,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B38165F94FE4B68B2A13D1ABF51CDFA7,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CallDelegate_0 93A327D54BD86CFEF5CD249FB5639638,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Self Name="K2Node_Self_1" NodePosX=848 NodePosY=192 NodeGuid=C73033EC40860C3D29681683E39D3444 CustomProperties Pin (PinId=8F3FF98C47B497E9854823B90DBAD678,PinName="self",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="self",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 912F056E41D63C2E399160A5AED876D1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_10" NodePosX=944 NodePosY=400 NodeGuid=A03F528644149E6032849FA6FF1C513E CustomProperties Pin (PinId=2329358D4505388E2AF57199A1371A95,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_13 63950A26426446B56CF15AAB8C2057B5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6BCA86D54CA6DCA7348288A8C5E582EB,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 2F8EDEA0440D02F0528303AD2FA7F6B3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_13" NodePosX=304 NodePosY=400 NodeGuid=39BA547B46E915F1311BA3BF043F5ECA CustomProperties Pin (PinId=A35B642D48F9A8B87A35478C21F5D195,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 EF616E0A45F44BAA91D116AB342E6FD0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=63950A26426446B56CF15AAB8C2057B5,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_10 2329358D4505388E2AF57199A1371A95,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_14" NodePosX=928 NodePosY=384 NodeGuid=4A6B911547AF062B355E199735F2949A CustomProperties Pin (PinId=0E7997AA43956A99EDAFF8901A84D258,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_15 F53AA008478964DFA66F069AB21D3C80,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7B1B863F4C2D57C8BF9834950CF8F1FA,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 251C8796493CC3D5D1DEAEB0B0933F8C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_15" NodePosX=320 NodePosY=384 NodeGuid=C6E19E93432DE8FB283BFABF8A21514D CustomProperties Pin (PinId=7E9B0BF44B3BC078B20BF4935388B664,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 6783C1AE42ABE3101046E59D7E5E030D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F53AA008478964DFA66F069AB21D3C80,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_14 0E7997AA43956A99EDAFF8901A84D258,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_16" NodePosX=912 NodePosY=368 NodeGuid=C93093884E02E88D9F4983ADA4C4C4CB CustomProperties Pin (PinId=890577A74A5AC8F2E507C78D88A893A3,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_17 16808D124A1EE4C5755372B53C7CEE35,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=98CE6C5D489F2F058DDF85B8284B7D1A,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 CB5821F8485DA6940DCA39AE15E2572E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_17" NodePosX=336 NodePosY=368 NodeGuid=E87F2A444C12B10044B0D680EA38EE6D CustomProperties Pin (PinId=0F1DB63E4E4CDBE98D9BAF99FA78B0A7,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 7EFB3A5F4843FF5B469447ABB9943750,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=16808D124A1EE4C5755372B53C7CEE35,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_16 890577A74A5AC8F2E507C78D88A893A3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_18" NodePosX=896 NodePosY=352 NodeGuid=00B7A0294210FD5F276D98975C7D7F3D CustomProperties Pin (PinId=C98005C048B768EA897DE58C4AAE52AC,PinName="InputPin",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_19 EF2F82B64A6BF7482B5AD9933798D700,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7CC571B2481D5BE3215EFAAFC636A85B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallDelegate_0 DF376D7743DD47A0D18C76A42829FEC0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_19" NodePosX=352 NodePosY=352 NodeGuid=C635791F456E7EF960CB9EAE4F2AF3A8 CustomProperties Pin (PinId=141156B7476A07026BDE089C300862C1,PinName="InputPin",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EF2F82B64A6BF7482B5AD9933798D700,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_18 C98005C048B768EA897DE58C4AAE52AC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_20" NodePosX=352 NodePosY=272 NodeGuid=0035A8904BD38A1ACBE8F9B8702ADDA4 CustomProperties Pin (PinId=7140CDF14A9B7168E6AAD5BDBF285EE6,PinName="InputPin",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_FunctionEntry_1 0873E9F143AEA68FA14EECAD698C312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=405E4121421CE9B061F666834ECD4F5D,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_4 B0D9B48040A48C244179549C6B768FE0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Begin Play



Begin Object Class=/Script/BlueprintGraph.K2Node_Event Name="K2Node_Event_1" EventReference=(MemberParent=Class'"/Script/Engine.ActorComponent"',MemberName="ReceiveBeginPlay") bOverrideFunction=True bCommentBubblePinned=True NodeGuid=0C36B33F4DAF0F5DCF7D72955F02A350 CustomProperties Pin (PinId=19BC90F74E064DA9C22319A8615A1F45,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=Class'"/Script/Engine.ActorComponent"',MemberName="ReceiveBeginPlay"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=15A4263D47CA68EFD8DAA18AD4466F52,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_0 DDA7F6994D6064BF7FA56FB638BFC2B1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="K2Node_VariableSet_0" VariableReference=(MemberName="Health",MemberGuid=2CFF801B4163BBD797A217A8852F4B33,bSelfContext=True) NodePosX=192 NodePosY=16 NodeGuid=C14C7AE14AACFFB22D76E7B05BDED389 CustomProperties Pin (PinId=DDA7F6994D6064BF7FA56FB638BFC2B1,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Event_1 15A4263D47CA68EFD8DAA18AD4466F52,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8FD8F6134A7D661B64C4BCAB1F78F694,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_3 3C0A34434849B97C610F37AD1374F4E3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ACA6FDCE41213805283C6FA650AB2249,PinName="Health",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_VariableGet_6 A39515D84F2129BBF8BD6BA66C8D1E46,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9A4E105B40F4B1BBEB35F7AD86A87681,PinName="Output_Get",PinToolTip="Retrieves the value of the variable, can use instead of a separate Get node",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2B7FA4814F229F1D76DB64890F812CCC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_6" VariableReference=(MemberName="MaxHealth",MemberGuid=7862E6784472ADD0BBCA19ADA27B2A2A,bSelfContext=True) NodePosY=80 NodeGuid=0C56D66946363F91C2A851B8FDBC18A9 CustomProperties Pin (PinId=A39515D84F2129BBF8BD6BA66C8D1E46,PinName="MaxHealth",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_VariableSet_0 ACA6FDCE41213805283C6FA650AB2249,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=FB7D064D48DA44169CF939A484234E4A,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_AddDelegate Name="K2Node_AddDelegate_3" DelegateReference=(MemberParent=Class'"/Script/Engine.Actor"',MemberName="OnTakeAnyDamage") NodePosX=368 ErrorType=1 NodeGuid=F727F3424A07C603D2BE0099A77FD99E CustomProperties Pin (PinId=3C0A34434849B97C610F37AD1374F4E3,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableSet_0 8FD8F6134A7D661B64C4BCAB1F78F694,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C586331449187C499B84E9D3BA50523,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9AA4F5244ECF2519855679A362743D7F,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "BaseMCDelegateSelfPinName", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_12 C236BEF9433FE73D208AF599760D310B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B9FDFD534D76416CB37DDFA0F5283F45,PinName="Delegate",PinFriendlyName=NSLOCTEXT("K2Node", "PinFriendlyDelegatetName", "Event"),PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=Package'"/Script/Engine"',MemberName="TakeAnyDamageSignature__DelegateSignature"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CreateDelegate_10 D924E4BE44970FC883C571A98936D02F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_12" bIsPureFunc=True bIsConstFunc=True FunctionReference=(MemberName="GetOwner",bSelfContext=True) NodePosX=16 NodePosY=144 NodeGuid=700CBB204AE5D1E658663A8A2A711FCE CustomProperties Pin (PinId=80C65FF24B67AF2C9701708AD48EFB6D,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nActor Component Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ActorComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C236BEF9433FE73D208AF599760D310B,PinName="ReturnValue",PinToolTip="Return Value\nActor Object Reference\n\nFollow the Outer chain to get the AActor that \'Owns\' this component",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_3 9AA4F5244ECF2519855679A362743D7F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CreateDelegate Name="K2Node_CreateDelegate_10" SelectedFunctionName="Take Damage" SelectedFunctionGuid=9AA92EF84A769C5B9147C38F30994580 NodePosX=16 NodePosY=256 NodeGuid=87CDBB334E42FA72A69A1EAED90AB65C CustomProperties Pin (PinId=D6EAE57340F7CB085D7F07A34A48F8A8,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "CreateDelegate_ObjectInputName", "Object"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D924E4BE44970FC883C571A98936D02F,PinName="OutputDelegate",PinFriendlyName=NSLOCTEXT("K2Node", "CreateDelegate_DelegateOutName", "Event"),Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_3 B9FDFD534D76416CB37DDFA0F5283F45,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Adding Health Component to the Third Person Character

Now that you have created your Health Component class, you will need to add its Actor Component to your Third Person Character class and bind the OnDamagePressed Action Mapping to inflict damage to the player.

Navigate to the Content > ThirdPersonBp > Blueprints folder and double-click the ThirdPersonCharacter to open its Class Defaults.



From the Components panel, click the Add Component button then search for and select Bp Health Component.



Right-click the Event Graph, then from the Actions menu, search for and select OnDamagePressed.



Begin Object Class=/Script/BlueprintGraph.K2Node_InputAction Name="K2Node_InputAction_0" InputActionName="OnDamagePressed" NodePosX=1856 NodePosY=-1808 NodeGuid=6580DC464016CA7A6F89BBBD0DBC5B1D CustomProperties Pin (PinId=E11DAD9A4461D92E0C1EAB8AF16AA57C,PinName="Pressed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_5 5CD3F96147C45A5C79136E840E94B96B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=68112E4C47B763D7BF723CA629D82780,PinName="Released",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DB02AF2347FE52F807DC578837C1A300,PinName="Key",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/InputCore.Key"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the InputAction OnDamagePressed node, drag off of the Pressed execution pin, then from the Actions menu, search for and select Apply Damage.



Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_5" FunctionReference=(MemberParent=Class'"/Script/Engine.GameplayStatics"',MemberName="ApplyDamage") NodePosX=2736 NodePosY=-1744 NodeGuid=2E7EBDEA4A952EC0C02BFCA57E3D8CB9 CustomProperties Pin (PinId=5CD3F96147C45A5C79136E840E94B96B,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=768E46CE4883A4157B5FED83357250CE,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F610D2DA42A15C92FE32578D07AE65C9,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nGameplay Statics Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.GameplayStatics"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__GameplayStatics",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EE1C897E4AD38A63F9CDD6BB8988E5C8,PinName="DamagedActor",PinToolTip="Damaged Actor\nActor Object Reference\n\nActor that will be damaged.",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5CE2D66E40D7C5E59A9BA99A8C8E25B5,PinName="BaseDamage",PinToolTip="Base Damage\nFloat (single-precision)\n\nThe base damage to apply.",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.000000",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B072209F48726FC12D78E2B7C9A7E140,PinName="EventInstigator",PinToolTip="Event Instigator\nController Object Reference\n\nController that was responsible for causing this damage (e.g. player who shot the weapon)",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2A789E86459D168252ADB691A107F084,PinName="DamageCauser",PinToolTip="Damage Causer\nActor Object Reference\n\nActor that actually caused the damage (e.g. the grenade that exploded)",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BD6E76FC43BCB8B23F0149A2196F54D0,PinName="DamageTypeClass",PinToolTip="Damage Type Class\nDamage Type Class Reference\n\nClass that describes the damage that was done.",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=True,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=49967BEA4F10E487FACE93877390170C,PinName="ReturnValue",PinToolTip="Return Value\nFloat (single-precision)\n\nActual damage the ended up being applied to the actor.",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Apply Damage node, drag off of the Damaged Actor pin and, from the Actions menu, search for and select Get a reference to self. Set the Base Damage float value to 20.0.



Begin Object Class=/Script/BlueprintGraph.K2Node_InputAction Name="K2Node_InputAction_0" InputActionName="OnDamagePressed" NodePosX=1856 NodePosY=-1808 NodeGuid=6580DC464016CA7A6F89BBBD0DBC5B1D CustomProperties Pin (PinId=E11DAD9A4461D92E0C1EAB8AF16AA57C,PinName="Pressed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_10 5CD3F96147C45A5C79136E840E94B96B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=68112E4C47B763D7BF723CA629D82780,PinName="Released",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DB02AF2347FE52F807DC578837C1A300,PinName="Key",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/InputCore.Key"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_10" FunctionReference=(MemberParent=Class'"/Script/Engine.GameplayStatics"',MemberName="ApplyDamage") NodePosX=2160 NodePosY=-1808 NodeGuid=9293AB16409E9A718AE4519E07DAF296 CustomProperties Pin (PinId=5CD3F96147C45A5C79136E840E94B96B,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_InputAction_0 E11DAD9A4461D92E0C1EAB8AF16AA57C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=768E46CE4883A4157B5FED83357250CE,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F610D2DA42A15C92FE32578D07AE65C9,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nGameplay Statics Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.GameplayStatics"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__GameplayStatics",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EE1C897E4AD38A63F9CDD6BB8988E5C8,PinName="DamagedActor",PinToolTip="Damaged Actor\nActor Object Reference\n\nActor that will be damaged.",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Self_1 6706B7C1460358E9CD7BDDA1F98B6BF3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5CE2D66E40D7C5E59A9BA99A8C8E25B5,PinName="BaseDamage",PinToolTip="Base Damage\nFloat (single-precision)\n\nThe base damage to apply.",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="20.000000",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B072209F48726FC12D78E2B7C9A7E140,PinName="EventInstigator",PinToolTip="Event Instigator\nController Object Reference\n\nController that was responsible for causing this damage (e.g. player who shot the weapon)",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2A789E86459D168252ADB691A107F084,PinName="DamageCauser",PinToolTip="Damage Causer\nActor Object Reference\n\nActor that actually caused the damage (e.g. the grenade that exploded)",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BD6E76FC43BCB8B23F0149A2196F54D0,PinName="DamageTypeClass",PinToolTip="Damage Type Class\nDamage Type Class Reference\n\nClass that describes the damage that was done.",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=True,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=49967BEA4F10E487FACE93877390170C,PinName="ReturnValue",PinToolTip="Return Value\nFloat (single-precision)\n\nActual damage the ended up being applied to the actor.",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Self Name="K2Node_Self_1" NodePosX=1968 NodePosY=-1664 NodeGuid=69EDEFE340ACBD853AE71BBEBAC933FD CustomProperties Pin (PinId=6706B7C1460358E9CD7BDDA1F98B6BF3,PinName="self",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="self",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_10 EE1C897E4AD38A63F9CDD6BB8988E5C8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

The Apply Damage function is a part of the Gameplay Statics Library, which includes useful generic functions for gameplay purposes.

Right-click the Event Graph, then from the Actions menu, search for and select Event Begin Play.



Begin Object Class=/Script/BlueprintGraph.K2Node_Event Name="K2Node_Event_0" EventReference=(MemberParent=Class'"/Script/Engine.Actor"',MemberName="ReceiveBeginPlay") bOverrideFunction=True NodePosX=1872 NodePosY=-1568 NodeGuid=090A12D6473F29195BEBE7BA2E406910 CustomProperties Pin (PinId=BD417B1046DE715B3996D2920D5484B1,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=Class'"/Script/Engine.Actor"',MemberName="ReceiveBeginPlay"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A29E62F496C6F0CE7706D9AF95D9A49,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_0 63C5BB1248FB16668AE39B883B3151FA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the Components panel, drag a copy of your BP_HealthComponent into the Event Graph.



Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_0" VariableReference=(MemberName="Bp_HealthComponent",bSelfContext=True) NodePosX=1872 NodePosY=-1488 NodeGuid=2C2DE3F54C11B302C4663FADC8F61C23 CustomProperties Pin (PinId=9C70A7FC46DA25A7C157B7925408DC7D,PinName="Bp_HealthComponent",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_0 A78183E24EE2920056A9C3BE39B29A2E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=23BF1A7E4EE16EEC0398419CFE3B86D3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.BP_ThirdPersonCharacter_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off the Bp Health Component pin, then from the Actions menu, search for and select Bind Event to Handle Take Damage.



Begin Object Class=/Script/BlueprintGraph.K2Node_AddDelegate Name="K2Node_AddDelegate_0" DelegateReference=(MemberParent=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',MemberName="HandleTakeDamage",MemberGuid=9800108D42BDCAAC9CC21B85063DD7D6) NodePosX=2784 NodePosY=-1136 NodeGuid=DEC9621541D6B05500A2B8AFBC93B4DF CustomProperties Pin (PinId=63C5BB1248FB16668AE39B883B3151FA,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4F452B6F45B0FD8A819EE08B1CF2D95C,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A78183E24EE2920056A9C3BE39B29A2E,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "BaseMCDelegateSelfPinName", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D755A44C41AF4E6EA11C8A94C93079B2,PinName="Delegate",PinFriendlyName=NSLOCTEXT("K2Node", "PinFriendlyDelegatetName", "Event"),PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',MemberName="HandleTakeDamage__DelegateSignature",MemberGuid=BB1865064561AE6B4F1C99B1636A7185),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Connect output execution pin of the Event BeginPlay node with input execution pin of Bind Event to Handle Take Damage.



Begin Object Class=/Script/BlueprintGraph.K2Node_Event Name="K2Node_Event_0" EventReference=(MemberParent=Class'"/Script/Engine.Actor"',MemberName="ReceiveBeginPlay") bOverrideFunction=True NodePosX=1872 NodePosY=-1568 NodeGuid=090A12D6473F29195BEBE7BA2E406910 CustomProperties Pin (PinId=BD417B1046DE715B3996D2920D5484B1,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=Class'"/Script/Engine.Actor"',MemberName="ReceiveBeginPlay"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A29E62F496C6F0CE7706D9AF95D9A49,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_1 63C5BB1248FB16668AE39B883B3151FA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_0"VariableReference=(MemberName="Bp_HealthComponent",bSelfContext=True) NodePosX=1872 NodePosY=-1488 NodeGuid=2C2DE3F54C11B302C4663FADC8F61C23 CustomProperties Pin (PinId=9C70A7FC46DA25A7C157B7925408DC7D,PinName="Bp_HealthComponent",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_1 A78183E24EE2920056A9C3BE39B29A2E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=23BF1A7E4EE16EEC0398419CFE3B86D3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.BP_ThirdPersonCharacter_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_AddDelegate Name="K2Node_AddDelegate_1" DelegateReference=(MemberParent=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',MemberName="HandleTakeDamage",MemberGuid=9800108D42BDCAAC9CC21B85063DD7D6) NodePosX=2080 NodePosY=-1568 NodeGuid=89286F1846EDD8E08FDE73A37799C95D CustomProperties Pin (PinId=63C5BB1248FB16668AE39B883B3151FA,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Event_0 5A29E62F496C6F0CE7706D9AF95D9A49,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4F452B6F45B0FD8A819EE08B1CF2D95C,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A78183E24EE2920056A9C3BE39B29A2E,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "BaseMCDelegateSelfPinName", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_0 9C70A7FC46DA25A7C157B7925408DC7D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D755A44C41AF4E6EA11C8A94C93079B2,PinName="Delegate",PinFriendlyName=NSLOCTEXT("K2Node", "PinFriendlyDelegatetName", "Event"),PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',MemberName="HandleTakeDamage__DelegateSignature",MemberGuid=BB1865064561AE6B4F1C99B1636A7185),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CustomEvent_0 6863CB334BFB297B9D518A8810BEB48B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off of the Event pin from the Bind Event to Handle Take Damage, then from the Actions menu search for and select Add Custom Event to create a custom event named OnHealthChanged.



Begin Object Class=/Script/BlueprintGraph.K2Node_CustomEvent Name="K2Node_CustomEvent_0" CustomFunctionName="OnHealthChanged" NodePosX=1872 NodePosY=-1424 NodeGuid=B32F0EDC40B66ACC3BB7E68D53460F25 CustomProperties Pin (PinId=6863CB334BFB297B9D518A8810BEB48B,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=BlueprintGeneratedClass'"/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.BP_ThirdPersonCharacter_C"',MemberName="OnHealthChanged",MemberGuid=B32F0EDC40B66ACC3BB7E68D53460F25),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=83E8967D40161AD541074D98A8B12D7B,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_2 26886FAE4FF14E78B6E54EB321956411,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CCC666454EE4C003B726529537D7A48F,PinName="DamageActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7750702846DF129948F15BA823EEC17D,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_3 1F103BFD4690FA34ABF5CC882117F3A6,K2Node_CallFunction_0 A5257DEE4B322F2C9B3904BFB91A6730,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=509BE62B4F9FBF0E141600B30921FB71,PinName="Damage",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=564F8AAF4B1EEBB9ADD44F9223FE1ADE,PinName="DamageType",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BA671FCE463DB02B3DF7DA848F38CA9E,PinName="InstigatedBy",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D27409B040C701F1617F00BC289519D7,PinName="DamageCauser",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="DamageActor",PinType=(PinCategory="object",PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Health",PinType=(PinCategory="real",PinSubCategory="double"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Damage",PinType=(PinCategory="real",PinSubCategory="double"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageType",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.DamageType"',bIsConst=True),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="InstigatedBy",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Controller"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageCauser",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) End Object

From the OnHealthChanged node, drag off the Health pin, then from the Actions menu search for and select the <= (Less Equal) operator.



Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_3" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="LessEqual_DoubleDouble") NodePosX=2064 NodePosY=-1296 NodeGuid=E25EBF4847887751EA4E8CBB195D049E CustomProperties Pin (PinId=1F103BFD4690FA34ABF5CC882117F3A6,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CustomEvent_0 7750702846DF129948F15BA823EEC17D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=852E3F69458BC93792F1C5915B7ACB88,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6A1AF64242AF88BBB59E1D84FD59DD9D,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nReturns true if A is Less than or equal to B (A <= B)",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_0 DAF36BEC410B7442BA87018878B0F906,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A4C18548489B875BE757A9A94BB0B789,PinName="ErrorTolerance",PinToolTip="Error Tolerance\n",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the OnHealthChanged node, drag off the Execution pin, then from the Actions menu search for and select Branch.



Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=2368 NodePosY=-1440 NodeGuid=2804D7E441A9F9F52E65C49E79B0383F CustomProperties Pin (PinId=748472B44657954E90A1CC8AC6B9FC42,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 EDB5E51048481EE40EE03EADDE475F0C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=917BB9BF437298373EE7939F12E9A3CE,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_Knot_1 36D9CAD34DD96F423F9902B30453CFD1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E1364E124D0DD05193665E8A88D57809,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_9 B66ECD7544D50B74E8C23B908D877A30,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=81F967C941C0052CF167E59413C3A452,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the <= (Less Equal) operator node, drag off of the boolean return pin, then connect it to the Condition pin of the Branch node.



Begin Object Class=/Script/BlueprintGraph.K2Node_CustomEvent Name="K2Node_CustomEvent_0" CustomFunctionName="OnHealthChanged" NodePosX=1872 NodePosY=-1424 NodeGuid=B32F0EDC40B66ACC3BB7E68D53460F25 CustomProperties Pin (PinId=6863CB334BFB297B9D518A8810BEB48B,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=BlueprintGeneratedClass'"/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.BP_ThirdPersonCharacter_C"',MemberName="OnHealthChanged",MemberGuid=B32F0EDC40B66ACC3BB7E68D53460F25),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_1 D755A44C41AF4E6EA11C8A94C93079B2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=83E8967D40161AD541074D98A8B12D7B,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 748472B44657954E90A1CC8AC6B9FC42,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CCC666454EE4C003B726529537D7A48F,PinName="DamageActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7750702846DF129948F15BA823EEC17D,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_3 1F103BFD4690FA34ABF5CC882117F3A6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=509BE62B4F9FBF0E141600B30921FB71,PinName="Damage",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=564F8AAF4B1EEBB9ADD44F9223FE1ADE,PinName="DamageType",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BA671FCE463DB02B3DF7DA848F38CA9E,PinName="InstigatedBy",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D27409B040C701F1617F00BC289519D7,PinName="DamageCauser",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="DamageActor",PinType=(PinCategory="object",PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Health",PinType=(PinCategory="real",PinSubCategory="double"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Damage",PinType=(PinCategory="real",PinSubCategory="double"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageType",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.DamageType"',bIsConst=True),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="InstigatedBy",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Controller"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageCauser",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_3" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="LessEqual_DoubleDouble") NodePosX=2064 NodePosY=-1296 NodeGuid=E25EBF4847887751EA4E8CBB195D049E CustomProperties Pin (PinId=1F103BFD4690FA34ABF5CC882117F3A6,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CustomEvent_0 7750702846DF129948F15BA823EEC17D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=852E3F69458BC93792F1C5915B7ACB88,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6A1AF64242AF88BBB59E1D84FD59DD9D,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nReturns true if A is Less than or equal to B (A <= B)",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 917BB9BF437298373EE7939F12E9A3CE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A4C18548489B875BE757A9A94BB0B789,PinName="ErrorTolerance",PinToolTip="Error Tolerance\n",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=2272 NodePosY=-1408 NodeGuid=2804D7E441A9F9F52E65C49E79B0383F CustomProperties Pin (PinId=748472B44657954E90A1CC8AC6B9FC42,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CustomEvent_0 83E8967D40161AD541074D98A8B12D7B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=917BB9BF437298373EE7939F12E9A3CE,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_PromotableOperator_3 6A1AF64242AF88BBB59E1D84FD59DD9D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E1364E124D0DD05193665E8A88D57809,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=81F967C941C0052CF167E59413C3A452,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off of the True execution pin from the Branch node, then from the Actions menu search for and select DestroyActor.



Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_9" FunctionReference=(MemberName="K2_DestroyActor",bSelfContext=True) NodePosX=2736 NodePosY=-1216 NodeGuid=41E65A0345A7E3705F83249A76CFD74C CustomProperties Pin (PinId=B66ECD7544D50B74E8C23B908D877A30,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9902A1064639C9732735D0A9504C502B,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6AAFE27146BD064D34E720A3777AFCDC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nActor Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

When the player's health value reaches zero, then they will be removed from the world.

From the OnHealthChanged node, drag off of the Execution pin then from the Actions menu search for and select Print String.



Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_8" FunctionReference=(MemberParent=Class'"/Script/Engine.KismetSystemLibrary"',MemberName="PrintString") NodePosX=2576 NodePosY=-1216 AdvancedPinDisplay=Hidden EnabledState=DevelopmentOnly NodeGuid=8F53931647BC342CDAAB93B6DF29469C CustomProperties Pin (PinId=C61410344F44BC39AB3D328A735838C1,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EDB5E51048481EE40EE03EADDE475F0C,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0A48525E4C37014A9E5ED688B53038C3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetSystemLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2EFF028645657B65C1B73EAFCDAEABF0,PinName="WorldContextObject",PinToolTip="World Context Object\nObject Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7F2F9EB94138727F58B07F9BDB7925B2,PinName="InString",PinToolTip="In String\nString\n\nThe string to log out",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",LinkedTo=(K2Node_CallFunction_0 0CB48E964FBDEB90D196C48FE63B9F42,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C3D881A64AEDCAEB890526836CB462E1,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBoolean\n\nWhether or not to print the output to the screen",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=1836DA144A90D101782771AA7A47155C,PinName="bPrintToLog",PinToolTip="Print to Log\nBoolean\n\nWhether or not to print the output to the log",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=F2DC0457475220EE76EA5689541FA08B,PinName="TextColor",PinToolTip="Text Color\nLinear Color Structure\n\nThe color of the text to display",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.LinearColor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=4A5898FC465E6416855BEA8D9FF95845,PinName="Duration",PinToolTip="Duration\nFloat (single-precision)\n\nThe display duration (if Print to Screen is True). Using negative number will result in loading the duration time from the config.",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=67F701514BD4408E59F722A44B2502F9,PinName="Key",PinToolTip="Key\nName\n\nIf a non-empty key is provided, the message will replace any existing on-screen messages with the same key.",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) End Object

Use Print String to print the current value of health onto the screen whenever the player character receives damage.

Connect the Health pin from the OnHealthChanged node to the In String pin of the Print String node.



Click Compile and Save.



Finished Blueprint



Begin Object Class=/Script/BlueprintGraph.K2Node_InputAction Name="K2Node_InputAction_0" InputActionName="OnDamagePressed" NodePosX=1856 NodePosY=-1808 NodeGuid=6580DC464016CA7A6F89BBBD0DBC5B1D CustomProperties Pin (PinId=E11DAD9A4461D92E0C1EAB8AF16AA57C,PinName="Pressed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_10 5CD3F96147C45A5C79136E840E94B96B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=68112E4C47B763D7BF723CA629D82780,PinName="Released",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DB02AF2347FE52F807DC578837C1A300,PinName="Key",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/InputCore.Key"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_10" FunctionReference=(MemberParent=Class'"/Script/Engine.GameplayStatics"',MemberName="ApplyDamage") NodePosX=2160 NodePosY=-1808 NodeGuid=9293AB16409E9A718AE4519E07DAF296 CustomProperties Pin (PinId=5CD3F96147C45A5C79136E840E94B96B,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_InputAction_0 E11DAD9A4461D92E0C1EAB8AF16AA57C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=768E46CE4883A4157B5FED83357250CE,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F610D2DA42A15C92FE32578D07AE65C9,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nGameplay Statics Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.GameplayStatics"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__GameplayStatics",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EE1C897E4AD38A63F9CDD6BB8988E5C8,PinName="DamagedActor",PinToolTip="Damaged Actor\nActor Object Reference\n\nActor that will be damaged.",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Self_1 6706B7C1460358E9CD7BDDA1F98B6BF3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5CE2D66E40D7C5E59A9BA99A8C8E25B5,PinName="BaseDamage",PinToolTip="Base Damage\nFloat (single-precision)\n\nThe base damage to apply.",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="20.000000",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B072209F48726FC12D78E2B7C9A7E140,PinName="EventInstigator",PinToolTip="Event Instigator\nController Object Reference\n\nController that was responsible for causing this damage (e.g. player who shot the weapon)",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2A789E86459D168252ADB691A107F084,PinName="DamageCauser",PinToolTip="Damage Causer\nActor Object Reference\n\nActor that actually caused the damage (e.g. the grenade that exploded)",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BD6E76FC43BCB8B23F0149A2196F54D0,PinName="DamageTypeClass",PinToolTip="Damage Type Class\nDamage Type Class Reference\n\nClass that describes the damage that was done.",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=True,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=49967BEA4F10E487FACE93877390170C,PinName="ReturnValue",PinToolTip="Return Value\nFloat (single-precision)\n\nActual damage the ended up being applied to the actor.",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Self Name="K2Node_Self_1" NodePosX=1968 NodePosY=-1664 NodeGuid=69EDEFE340ACBD853AE71BBEBAC933FD CustomProperties Pin (PinId=6706B7C1460358E9CD7BDDA1F98B6BF3,PinName="self",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="self",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_10 EE1C897E4AD38A63F9CDD6BB8988E5C8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Event Name="K2Node_Event_0" EventReference=(MemberParent=Class'"/Script/Engine.Actor"',MemberName="ReceiveBeginPlay") bOverrideFunction=True NodePosX=1872 NodePosY=-1568 NodeGuid=090A12D6473F29195BEBE7BA2E406910 CustomProperties Pin (PinId=BD417B1046DE715B3996D2920D5484B1,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=Class'"/Script/Engine.Actor"',MemberName="ReceiveBeginPlay"),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5A29E62F496C6F0CE7706D9AF95D9A49,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_1 63C5BB1248FB16668AE39B883B3151FA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_0" VariableReference=(MemberName="Bp_HealthComponent",bSelfContext=True) NodePosX=1872 odePosY=-1488 NodeGuid=2C2DE3F54C11B302C4663FADC8F61C23 CustomProperties Pin (PinId=9C70A7FC46DA25A7C157B7925408DC7D,PinName="Bp_HealthComponent",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_1 A78183E24EE2920056A9C3BE39B29A2E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=23BF1A7E4EE16EEC0398419CFE3B86D3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.BP_ThirdPersonCharacter_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_AddDelegate Name="K2Node_AddDelegate_1" DelegateReference=(MemberParent=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',MemberName="HandleTakeDamage",MemberGuid=9800108D42BDCAAC9CC21B85063DD7D6) NodePosX=2080 NodePosY=-1568 NodeGuid=89286F1846EDD8E08FDE73A37799C95D CustomProperties Pin (PinId=63C5BB1248FB16668AE39B883B3151FA,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Event_0 5A29E62F496C6F0CE7706D9AF95D9A49,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=4F452B6F45B0FD8A819EE08B1CF2D95C,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A78183E24EE2920056A9C3BE39B29A2E,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "BaseMCDelegateSelfPinName", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_0 9C70A7FC46DA25A7C157B7925408DC7D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D755A44C41AF4E6EA11C8A94C93079B2,PinName="Delegate",PinFriendlyName=NSLOCTEXT("K2Node", "PinFriendlyDelegatetName", "Event"),PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',MemberName="HandleTakeDamage__DelegateSignature",MemberGuid=BB1865064561AE6B4F1C99B1636A7185),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CustomEvent_0 6863CB334BFB297B9D518A8810BEB48B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CustomEvent Name="K2Node_CustomEvent_0" CustomFunctionName="OnHealthChanged" NodePosX=1872 NodePosY=-1424 NodeGuid=B32F0EDC40B66ACC3BB7E68D53460F25 CustomProperties Pin (PinId=6863CB334BFB297B9D518A8810BEB48B,PinName="OutputDelegate",Direction="EGPD_Output",PinType.PinCategory="delegate",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(MemberParent=BlueprintGeneratedClass'"/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.BP_ThirdPersonCharacter_C"',MemberName="OnHealthChanged",MemberGuid=B32F0EDC40B66ACC3BB7E68D53460F25),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_AddDelegate_1 D755A44C41AF4E6EA11C8A94C93079B2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=83E8967D40161AD541074D98A8B12D7B,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 C61410344F44BC39AB3D328A735838C1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CCC666454EE4C003B726529537D7A48F,PinName="DamageActor",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7750702846DF129948F15BA823EEC17D,PinName="Health",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_3 1F103BFD4690FA34ABF5CC882117F3A6,K2Node_CallFunction_0 A5257DEE4B322F2C9B3904BFB91A6730,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=509BE62B4F9FBF0E141600B30921FB71,PinName="Damage",Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=564F8AAF4B1EEBB9ADD44F9223FE1ADE,PinName="DamageType",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.DamageType"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=BA671FCE463DB02B3DF7DA848F38CA9E,PinName="InstigatedBy",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Controller"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D27409B040C701F1617F00BC289519D7,PinName="DamageCauser",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties UserDefinedPin (PinName="DamageActor",PinType=(PinCategory="object",PinSubCategoryObject=BlueprintGeneratedClass'"/Game/Bp_HealthComponent.Bp_HealthComponent_C"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Health",PinType=(PinCategory="real",PinSubCategory="double"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="Damage",PinType=(PinCategory="real",PinSubCategory="double"),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageType",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.DamageType"',bIsConst=True),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="InstigatedBy",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Controller"'),DesiredPinDirection=EGPD_Output) CustomProperties UserDefinedPin (PinName="DamageCauser",PinType=(PinCategory="object",PinSubCategoryObject=Class'"/Script/Engine.Actor"'),DesiredPinDirection=EGPD_Output) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_PromotableOperator Name="K2Node_PromotableOperator_3" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetMathLibrary"',MemberName="LessEqual_DoubleDouble") NodePosX=2080 NodePosY=-1296 NodeGuid=E25EBF4847887751EA4E8CBB195D049E CustomProperties Pin (PinId=1F103BFD4690FA34ABF5CC882117F3A6,PinName="A",PinToolTip="A\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CustomEvent_0 7750702846DF129948F15BA823EEC17D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=852E3F69458BC93792F1C5915B7ACB88,PinName="B",PinToolTip="B\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6A1AF64242AF88BBB59E1D84FD59DD9D,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nReturns true if A is Less than or equal to B (A <= B)",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_3 3D8ACEC04B271A51F280398CFE9195C9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A4C18548489B875BE757A9A94BB0B789,PinName="ErrorTolerance",PinToolTip="Error Tolerance\n",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_0" NodePosX=2432 NodePosY=-1408 NodeGuid=2804D7E441A9F9F52E65C49E79B0383F CustomProperties Pin (PinId=748472B44657954E90A1CC8AC6B9FC42,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 EDB5E51048481EE40EE03EADDE475F0C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=917BB9BF437298373EE7939F12E9A3CE,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_Knot_3 1D4A12A94D60994912A098ABCF08EAD2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=E1364E124D0DD05193665E8A88D57809,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_9 B66ECD7544D50B74E8C23B908D877A30,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=81F967C941C0052CF167E59413C3A452,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_9" FunctionReference=(MemberName="K2_DestroyActor",bSelfContext=True) NodePosX=2624 NodePosY=-1424 NodeGuid=41E65A0345A7E3705F83249A76CFD74C CustomProperties Pin (PinId=B66ECD7544D50B74E8C23B908D877A30,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 E1364E124D0DD05193665E8A88D57809,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=9902A1064639C9732735D0A9504C502B,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=6AAFE27146BD064D34E720A3777AFCDC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nActor Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_8" FunctionReference=(MemberParent=Class'"/Script/Engine.KismetSystemLibrary"',MemberName="PrintString") NodePosX=2272 NodePosY=-1408 AdvancedPinDisplay=Hidden EnabledState=DevelopmentOnly NodeGuid=8F53931647BC342CDAAB93B6DF29469C CustomProperties Pin (PinId=C61410344F44BC39AB3D328A735838C1,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CustomEvent_0 83E8967D40161AD541074D98A8B12D7B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EDB5E51048481EE40EE03EADDE475F0C,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 748472B44657954E90A1CC8AC6B9FC42,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0A48525E4C37014A9E5ED688B53038C3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetSystemLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=2EFF028645657B65C1B73EAFCDAEABF0,PinName="WorldContextObject",PinToolTip="World Context Object\nObject Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=7F2F9EB94138727F58B07F9BDB7925B2,PinName="InString",PinToolTip="In String\nString\n\nThe string to log out",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",LinkedTo=(K2Node_CallFunction_0 0CB48E964FBDEB90D196C48FE63B9F42,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C3D881A64AEDCAEB890526836CB462E1,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBoolean\n\nWhether or not to print the output to the screen",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=1836DA144A90D101782771AA7A47155C,PinName="bPrintToLog",PinToolTip="Print to Log\nBoolean\n\nWhether or not to print the output to the log",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=F2DC0457475220EE76EA5689541FA08B,PinName="TextColor",PinToolTip="Text Color\nLinear Color Structure\n\nThe color of the text to display",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.LinearColor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=4A5898FC465E6416855BEA8D9FF95845,PinName="Duration",PinToolTip="Duration\nFloat (single-precision)\n\nThe display duration (if Print to Screen is True). Using negative number will result in loading the duration time from the config.",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) CustomProperties Pin (PinId=67F701514BD4408E59F722A44B2502F9,PinName="Key",PinToolTip="Key\nName\n\nIf a non-empty key is provided, the message will replace any existing on-screen messages with the same key.",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_0" bIsPureFunc=True FunctionReference=(MemberParent=Class'"/Script/Engine.KismetStringLibrary"',MemberName="Conv_DoubleToString") NodePosX=2096 NodePosY=-1360 NodeGuid=0E3E7A8141130C288D50538D43D1D652 CustomProperties Pin (PinId=600BF9B54CDCFAA18C98CE985F2B346F,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet String Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetStringLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetStringLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A5257DEE4B322F2C9B3904BFB91A6730,PinName="InDouble",PinToolTip="In Double\nFloat (double-precision)",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",LinkedTo=(K2Node_CustomEvent_0 7750702846DF129948F15BA823EEC17D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0CB48E964FBDEB90D196C48FE63B9F42,PinName="ReturnValue",PinToolTip="Return Value\nString\n\nConverts a double value to a string",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 7F2F9EB94138727F58B07F9BDB7925B2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_3" NodePosX=2368 NodePosY=-1280 NodeGuid=ED1A915D4C80AE5F16E2F4AECFC998B7 CustomProperties Pin (PinId=3D8ACEC04B271A51F280398CFE9195C9,PinName="InputPin",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_PromotableOperator_3 6A1AF64242AF88BBB59E1D84FD59DD9D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1D4A12A94D60994912A098ABCF08EAD2,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 917BB9BF437298373EE7939F12E9A3CE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

End Result

You are now ready to test the functionality of your Health Component.

You can move your character using the WASD keys. When pressing the numeric 1 key, your character will receive damage until its health reaches zero, at which point it will be destroyed from the world.

Navigate to the Toolbar, and click Play.



Project Setup

In this tutorial, you are tasked with creating gameplay logic for an Actor Component named HealthComponent. Once this Component is attached to an Actor, your Actor will contain the functionality to deduct damage from its health.

In our example, we will use the Third Person Character included in the Third Person Template project.

Begin by creating a New > Games > Third Person > CPP Project named Health Comp.



Click for full view.

Navigate to Edit > Project Settings > Engine > Input > Bindings > Action Mappings, then click the Add (+) to create a new Action Mapping named OnDamagePressed, and set the value to 1.



Click for full view.

Input contains Action Mappings, which can be used to map a button or keypress to an event-driven behavior such as inflicting damage on the player character.

Creating the Actor Component: Health Component

Delegates can call member functions on C++ objects in a generic, type-safe way. When an Actor binds itself to a delegate, it will respond to that Delegate's member function event.

Follow the steps below to begin creating an On Health Changed Delegate.

Click Tools > New C++ Class to create a C++ Class, then from the Choose Parent Class menu, select Actor Component and click Next.



Click for full view.

Name your Actor Component Class HealthComponent and click Create.



Click for full view.

In the HealthComponent.h file, declare the following Delegate:

Navigate to the Class Defaults and declare the following methods and variables:

Navigate to the HealthComponent.cpp file and inside the HealthComponent Constructor, initialize the following class variable:

Implement the following definition for the BeginPlay class method:

Declare the following code for the HandleTakeDamage method:

Compile your code.

Finished Code

Health Component.h

Health Component.cpp

Adding Health Component to the HealthComp Character

Now that you have created your Health Component class, you will need to add its Actor Component to your Health Comp Character class and bind the OnDamagePressed Action Mapping to inflict damage to the Player.

From the Content Browser, navigate to C++ Classes > HealthComp and double-click the HealthComp Character to open the HealthCompCharacter.h file.

Declare the following code in the Class Defaults:

Navigate to the HealthCompCharacter.cpp file and include the following class libraries:

The Gameplay statics library includes numerous utility helper functions that can serve your gameplay purpose needs. In this instance, we will be using the ApplyDamage method.

In the AHealthCompCharacter Constructor, initialize your Health Component class:

Navigate to the AHealthCompChatacter::BeginPlay method and add the following code:

In the AHealthCompCharacter::OnHealthChanged method, implement the following logic to destroy the Player Character when its health reaches zero:

UE_LOG is a macro that contains varying verbosity types to use along with commands for visualizing your data to the output log.

Implement the AHealthCompCharacter::DamagePlayerCharacter method by adding the following code:

Navigate to AHealthCompCharacter::SetupPlayerInputComponent method to assign your OnDamagePressed binding to the DamagePlayerCharacter function:

Compile your code.

Finished Code

HealthCompCharacter.h

HealthCompCharacter.cpp

End Result

You are now ready to test the functionality of your Health Component.

You can move your character using the WASD keys. When pressing the numeric 1 key, your character will receive damage until its health reaches zero, at which point it will be destroyed from the world.

Navigate to the Toolbar, and press Play.



Additional Resources

There are several concepts that tie into Adding Components to Blueprints and the links below provide additional relevant information:

Blueprint User Guide

Using Components in Blueprints

Creating a New Project

Creating the Player Character

Creating Input Key Mappings and Input Movement Events

Creating Input Key Mappings and Input Action Events

Setting up the Game Mode

Creating the Locomotion Blend Space

Creating the Crouch Locomotion Blend Space

Creating the Animation Blueprint

Creating the Animation State Machines

Result

Character Movement provides a locomotion system for humanoid characters to traverse through your world. The Character Movement Component is an Actor Component that provides modes of movement for Character classes, including walking, falling, swimming, and flying. Additionally, the Character Movement Component features robust network gameplay integration and provides a framework to help developers create custom networked movement.

For additional documentation on Network Replication in Unreal Engine, refer to the Networking Overview.

In this How-To Gameplay Guide, you will create a Character class, script it's movement logic, Input, and create an Animation Blueprint which will help determine which state your Character is in, and then play the corresponding animation.



Choose your implementation method:

Blueprints

C++

Creating a New Project

Begin by signing into the Epic Games Launcher and creating a New > Games > Blank > Project named CharacterMovement.



To animate your Character, you will require the Animation Starter Pack which is available to download for free from the Epic Games Marketplace. Click the Free button to download and add the Animation Starter Pack to your Epic Games Library.



From your Library, search for your Animation Starter Pack and click Add to Project, then from the Select the Project to Add the Asset to menu, search for and select your CharacterMovement project file, then click Add to Project.



Upon adding the Animation Starter Pack to your project, you will notice its presence in the Content Browser.



Begin by creating a New > Games > Blank > C++ project named CharacterMovement.



To animate your Character, You will require an Animation Starter Pack which is available to download for free from the Epic Games Marketplace. Click the Free button to download and add the Animation Starter Pack to your Epic Games Library.



From your Library, search for your Animation Starter Pack and click Add to Project, then from the Select the Project to Add the Asset to menu, search for and select your CharacterMovement project file, then click Add to Project.



Upon adding the animation starter pack to your project, you will notice its presence in the Content Browser.



Creating the Player Character

A Character class is required for your Player to control. A character is a pawn that comes with a Character Movement Component to provide a locomotion system for humanoid characters to traverse through your world. Follow the steps below to set up your character.

Click the Add/Import button to create a new Blueprint Character class named BP_PlayerCharacter.



Double-click your BP_PlayerCharacter to open its class defaults, then in the components tab select the Mesh(CharacterMesh0) Skeletal Mesh Component, and navigate to the Details panel.



Click image to expand.

In the Mesh category, select the drop down arrow adjacent to the Skeletal Mesh variable, and from the drop down menu select SK_Mannequin.



In the Details panel, navigate to the Transform category, and set the Mesh's Location and Rotation to (0,0,-90).



Your Character's Skeletal Mesh will now be oriented in the direction of the forward facing Arrow Component as shown in the image below.



Navigate to the Components tab to select your Mesh component, then click Add Component and in the drop down menu search for and select SpringArm, then name your Spring Arm Component "SpringArmComp".



Navigate to the Details panel, and in the Camera Settings category enable the Use Pawn Control Rotation.



Enabling use Pawn Control rotation will rotate the camera relative to the spring arm.

In the Camera category, set the socket offset to (0,0,30) then navigate to the Transform category and set the SpringArmComp's Location to (0,0,50).



With your SpringArmComp selected, click the Add Component button, then in the drop down menu search for and select Camera to add a Camera Component named CameraComp.



In the Components tab, select the Character Movement Component, then navigate to the Details panel, and in the Character Movement (Rotation Settings) category, enable Use Controller Desired Rotation and Orient Rotation To Movement.



In the Character Movement:Walking category enable the Ignore Base Rotation variable.



Setting Ignore base rotation to true will tell the character to maintain its current world rotation, and ignore any changes in rotation of the base it's standing on.

In the Character Movement Nav Movement category, navigate to the Movement Capabilities and select the drop down arrow to reveal additional variable settings, navigate to the Can Crouch Boolean and click to enable it.



Compile and Save.



A Character class is required for your Player to control. A character is a pawn that comes with a Character Movement Component to provide a locomotion system for humanoid characters to traverse through your world. Follow the steps below to set up your character.

In the C++ Class Wizard, create a new Character class named PlayerCharacter, then navigate to the PlayerCharacter.h file and declare the following class definitions:

Navigate to the PlayerCharactor.cpp file and add the following class libraries:

In the APlayerCharactor::APlayerCharacter constructor method declare the following

Compile your code.

In the Editor, navigate to your C++ Classes folder, then right click on your PlayerCharacter class and in the C++ Class Actions drop down menu select Create Blueprint class based on PlayerCharacter. Name your Blueprint Bp_PlayerCharacter.



Click image to expand.

Double-click your BP_PlayerCharacter to open it's class defaults, then in the Components tab select the Mesh(CharacterMesh0) Skeletal Mesh Component, and navigate to the Details panel.



Click image to expand.

In the Mesh category, select the drop down arrow adjacent to the Skeletal Mesh variable, and from the drop down menu select SK_Mannequin.



Your Character's Skeletal Mesh will appear oriented in the direction of the forward facing Arrow Component as shown in the image below.



Compile and Save.



Creating Input Key Mappings and Input Movement Events

You will need to set up some custom logic that will move your character when an Input key; such as W,A,S, or D is pressed.

Navigate to Edit > Project Settings > Input, then in the Bindings Category click the + sign next to Action Mappings to add the following:

Action Mapping

Key Value

Jump

Space Bar

Crouch

Left Ctrl

Sprint

Left Shift



In the Bindings Category click the + sign next to Axis Mappings to add the following Axis Mappings.

Axis Mapping

Key Value

Scale

MoveForward

W

1.0

S

-1.0

MoveRight

D

1.0

A

-1.0

Turn

Mouse X

1.0

LookUp

Mouse Y

-1.0



In the Content Browser, double click your BP_PlayerCharacter to open it's class defaults, then right click on the Event Graph and in the drop down menu search for and select MoveForward.



Click image to expand.

Drag off from the execution pin of your InputAxis MoveForward node and in the drop down menu search for and select for the Add Movement Input node, then connect the Axis Value pin of the InputAxis MoveForward node to the Scale Value pin of the Add Movement Input node.



Click image to expand.

Right click on the Event Graph and in the context menu search for and select Get Control Rotation, then drag off the Rotator return value pin, and in the drop down menu search for and select Break Rotator.



Click image to expand.

Drag off from the Break Rotator node's Z(Yaw) pin, and in the drop down menu search for and select Make Rotator, then drag off from the Make Rotator node's Rotator Return value pin and in the drop down menu search for and select Get Forward Vector.



Click image to expand.

Drag off from the Get Forward Vector node's Vector Return Value pin and plug it into the Add Movement Input node's World Direction pin.



Click image to expand.

Right-click on the graph again, and search for and select Move Right for your Input Axis Event.



Click image to expand.

Drag off the execution pin of your InputAxis MoveRight node and in the drop down menu search for and select for the Add Movement Input node, then connect the Axis Value pin of the InputAxis MoveRight node to the Scale Value pin of the Add Movement Input node.



Click image to expand.

Drag off from the Make Rotator node's Rotator Return Value pin and in the drop down menu search for and select the Get Right Vector node, then drag off from the Vector Return Value pin and plug it into the Add Movement Input node's World Direction pin.



Click image to expand.

Your completed Movement Input Events Blueprint graph will look as it does below.



Click image to expand.

Right-click on the Event Graph, then search for and select for the InputAxis LookUp event node, then right-click, search for and select for the Add Controller Pitch Input node.



Click image to expand.

Drag off from the Axis Value pin of the Input Axis LookUp node and connect to the Val pin of the Add Controller Pitch Input node. Drag off from the execution output pin of the InputAxis LookUp node and connect to the execution input pin of the Add Controller Pitch Input node.



Click image to expand.

Right-click on the Event Graph, then search for and select for the Input Axis Turn event node, then right-click, search for, and select the Add Controller Yaw Input node.



Click image to expand.

Drag off from the Axis Value pin of the Input Axis Turn node and connect to the Val pin of the Add Controller Yaw Input node. Drag off from the execution output pin of the Input Axis Turn node and connect to the execution input pin of the Add Controller Yaw Input node.



Click image to expand.

Click Compile and Save.



Work-In-Progress Blueprint

At this point in the process, your Blueprint graph should resemble the image shown below.



Click image to expand.

You will need to set up some custom logic that will move your character when an Input key such as W,A,S, or D is pressed.

Navigate to Edit > Project Settings > Input, then from the Bindings Category click the + sign next to Action Mappings to add the following Action mappings.

Action Mapping

Key Value

Jump

Space Bar

Crouch

Left Ctrl

Sprint

Left Shift



In the Bindings Category click the + sign next to Axis Mappings to add the following Axis Mappings.

Axis Mapping

Key Value

Scale

MoveForward

W

1.0

S

-1.0

MoveRight

D

1.0

A

-1.0

Turn

Mouse X

1.0

LookUp

Mouse Y

-1.0



In your PlayerCharacter.h, declare the following class methods

In your PlayerCharacter.Cpp, implement the following logic for your APlayerCharacter::MoveForward, and APlayerCharacter::MoveRight class methods.

Next, navigate to the APlayerCharacter::SetupPlayerInputComponent method, and implement the following code.

Compile your code

Work-In-Progress Code

PlayerCharacter.h

PlayerCharacter.Cpp

Creating Input Key Mappings and Input Action Events

Now that you have completed the Blueprint scripting logic for your Move Forward, Move Right, Look Up, and Turn input events, you will need to finish implementing your Action Mappings for your Jump, Crouch, and Sprint input events.

Right click on the Event Graph, then in the All Actions for this Blueprint drop down menu, search for and select your Jump Action Event.



Click image to expand.

Drag off from your InputAction Jump node's Pressed execution pin, then in the drop down menu, search for and select the Character function Jump.



Connect the execution pin of your InputAction Jump node to the execution pin of your Jump node.



Click image to expand.

Drag off from the InputAction Jump node's Released execution pin, and in the drop down menu, search for and select the Character function Stop Jumping.



Click image to expand.

Right click on the Event Graph and in the drop down menu, search for and select the Input Action Sprint.



Navigate to the Components tab, then click and drag your Character Movement Component on to the Event Graph.



Click image to expand.

Drag off the Character Movement pin and from the drop down menu, search for and select Set Max Walk Speed. Set the Max Walk Speed float value to 1000, then connect the Pressed Execution pin of the InputAction Sprint node to the Input Execution pin of the Set Max Walk Speed.



Click image to expand.

Drag off from the Character Movement pin, then search for and select for another set Max Walk Speed node. Set the Max Walk Speed float value to 600, and then connect the Released execution pin of the InputAction Sprint node to the Set Max Walk Speed execution input pin.



Click image to expand.

Right-click on the Event Graph, and in the drop down menu search for and select your Input Action Crouch.



Drag off from the InputAction Crouch node's Pressed execution pin, then in the drop down menu, search for and select the Character class function Crouch.



Click image to expand.

Drag off from the InputAction Crouch node's Released execution pin, then in the drop down action menu search for and select the Character class function Un Crouch.



Click image to expand.

Compile and Save your Blueprint.



Completed Blueprint

Your completed Blueprint should resemble the image shown below.



Click image to expand.

Now that you have completed the Code scripting logic for your Move Forward, Move Right, Look Up, and Turn input events, you will need to finish implementing your Action Mappings for your Jump, Crouch, and Sprint input events.

Navigate to your PlayerCharacter.h file and declare the following class methods

In your PlayerCharacter.cpp file, implement the following logic for your APlayerCharacter::BeginSprint and APlayerCharacter::EndSprint class methods.

Implement the following logic for your APlayerCharacter::BeginCrouch and APlayerCharacter::EndCrouch methods.

Navigate to your APlayerCharacter:: ::SetupPlayerInputComponent method and declare the following code:

Compile your code.

Finished Code

PlayerCharacter.h

PlayerCharacter.cpp

Setting up the Game Mode

The GameMode defines the game's set of rules. These rules include what default pawn the player will spawn as when the game is launched. You will need to set up these rules in order to spawn the Player Character that you have created.

In the Content Browser, click the Add/Import button and create a new Blueprint class, when the Pick a Parent Class menu appears, select Game Mode Base and name your new Gamemode class Bp_GameMode.



Click image to expand.

Double click Bp_GameMode to open it's class defaults, then navigate to the Details panel Classes category, and for the Default Pawn Class select Bp_PlayerCharacter.



Compile and Save your Blueprint.



Navigate to Edit > Project Settings > Maps & Modes, and in the Default Modes category, select Bp_GameMode.



Click image to expand.

The Game Mode defines the game's set of rules. These rules include what default pawn the player will spawn as when the game is launched. You will need to set up these rules in order to spawn the Player Character that you have created.

In the Editor navigate to your C++ classes folder. Right click your CharacterMovementGameModeBase and from the C++ Class Actions menu, select Create Blueprint class based on your CharacterMovementGameModeBase, then name your new Gamemode class Bp_GameMode.



Click image to expand.

Double click Bp_GameMode to open it's class defaults, then navigate to the Details panel Classes category, and for the Default Pawn Class select Bp_PlayerCharacter.



Compile and Save your Blueprint.



Navigate to Edit > Project Settings > Maps & Modes, and in the Default Modes category, select Bp_GameMode.



Click image to expand.

Creating the Locomotion Blend Space

Now that you have a character that possesses the input functionality to move in your level, you will need to create Blend Spaces for your movement states (sprinting, jogging, and crouch walking).

Blend Spaces are special assets that allow for blending of animations based on the values of two inputs. You will create your own blend spaces that move between forward and backward and left and right movements based on the character's movement speed or direction.

In the Content Browser, click Add/Import > Animation > BlendSpace, when prompted to pick a skeleton, choose the UE4_Mannequin_Skeleton, then name your Blend Space Locomotion_BS.



Double click to open the Locomotion_BS Blend Space. In the Asset Details tab, navigate to the Axis Settings category, then select the arrows adjacent to the Horizontal Axis and the Vertical Axis to see more variable details.



In the Horizontal Axis settings, change the Name variable to Direction, then set the Minimum Axis Value to -180, and the Maximum Axis Value to 180.



In the Vertical Axis Settings, change the Name variable to Speed, then set the Maximum Axis Value to 1000.



Compile and Save.



Navigate to the Asset Browser, then within the filters search bar type Idle_Rifle_Hip, then drag and drop the Idle_Rifle_Hip asset into the Blend Space at Direction 0.0, and Speed 0.0.



Click image to expand.

Repeat the previous step, inserting the Idle_Rifle_Hip asset into:

Direction 180, Speed 0.

Direction 90, Speed 0.

Direction -90, Speed 0.

Direction -180, Speed 0.



Click image to expand.

In the Asset Browser tab Filters search bar type Walk_Fwd_Rifle_Ironsights, then drag and drop the Walk_Fwd_Rifle_Ironsights asset into the Blend Space at Direction 0.0, and Speed 250.



Click image to expand.

Next, in the Asset Browser tab Filters search bar type Walk_Lt_Rifle_Ironsights, then drag and drop the Walk_Lt_Rifle_Ironsights asset into the Blend Space at Direction -90 and Speed 250.



Click image to expand.

In the Asset Browser tab Filters search bar type Walk_Rt_Rifle_Ironsights, then drag and drop the Walk_Rt_Rifle_Ironsights asset into the Blend Space at Direction 90 and Speed 250.



Click image to expand.

In the Asset Browser tab Filters search bar type Walk_Bwd_Rifle_Ironsights, then drag and drop the**Walk_Bwd_Rifle_Ironsights asset into the Blend Space at Direction 180 and Speed 250, then drag and drop it again at Direction -180 and Speed 250**.



Click image to expand.

In the Asset Browser tab Filters search bar type Jog_Fwd_Rifle, then drag and drop the Jog_Fwd_Rifle asset into the Blend Space at Direction 0.0, and Speed 500.



Click image to expand.

Navigate to the Asset Browser, then within the filters search bar type Jog_Lt_Rifle, then drag and drop the Jog_Lt_Rifle asset into the Blend Space at Direction -90, and Speed 500.



Click image to expand.

Navigate to the Asset Browser, then within the filters search bar type Jog_Rt_Rifle, then drag and drop the Jog_Rt_Rifle asset into the Blend Space at Direction 90, and Speed 500.



Click image to expand.

From the asset browser search bar filter type Jog_Bwd_Rifle_Ironsights, then drag and drop an Jog_Bwd_Rifle_Ironsights asset into the Blend Space at Direction 180 and Speed 500, then drag an additional Jog_Bwd_Rifle_Ironsights at Direction -180 and Speed 500.



Click image to expand.

Complete your Blend Space by navigating to the asset browser, search for and select Sprint_Fwd_Rifle_Ironsights, then drag and drop an Sprint_Fwd_Rifle_Ironsights asset into the Blend Space at Direction 0 and Speed 1000,



Click image to expand.

Compile and Save.



Your completed Locomotion_BS will look as shown in the image below!



Creating the Crouch Locomotion Blend Space

With your Locomotion Blend Space complete, you will now need to create your Crouch Locomotion Blend Space.

In the Content Browser, click Add/Import > Animation > BlendSpace, when prompted to pick a skeleton, choose the UE4_Mannequin_Skeleton, then name your Blend Space LocomotionCrouch_BS.

Double click to open the Locomotion_BS Blend Space. In the Asset Details tab, navigate to the Axis Settings category, then select the arrows adjacent to the Horizontal Axis and the Vertical Axis to see more variable details.



In the Horizontal Axis settings, change the Name variable to Direction, then set the Minimum Axis Value to -180, and the Maximum Axis Value to 180.



In the Vertical Axis Settings, change the Name variable to Speed, then set the Maximum Axis Value to 300.



Repeat the previous steps from the Creating The Locomotion Blend Space section, and place your assets into the Blend Space at the values below.

Animation Asset Name

Speed

Direction

Crouch_Idle_Rifle_Hip

0

0, 90, -90, 180, -180

Crouch_Walk_Fwd_Rifle_Hip

300

0

Crouch_Walk_Lt_Rifle_Hip

300

-90

Crouch_Walk_Rt_Rifle_Hip

300

90

Crouch_Walk_Bwd_Rifle_Hip

300

180, -180

Save and Compile your LocomotionCrouch_BS



Your completed LocomotionCrouch_BS Blend Space will look as shown in the image below.



Creating the Animation Blueprint

You will require an Animation Blueprint that will determine what character animations to play based on the current actions by the player. Additionally, you will need to set up a State Machine to create a Walk and Crouch state then set up the transitions between each of them.

In the Content Browser, click Add/Import > Animation > Animation Blueprint, and when prompted to pick a skeleton, choose the UE4_Mannequin_Skeleton, then name your Animation Blueprint PlayerCharacter_AB.



Double-click PlayerCharacter_AB to open the Animation Blueprint. In the My Blueprint tab, navigate to the Variables category and select the adjacent + sign to create two boolean variables named Is Crouched and Is Jumping.



Click the Event Graph tab, then drag off from the Return Value pin of the Try Get Pawn Owner node, then from the drop down menu search for and select Cast to BP_PlayerCharacter.



Click image to expand.

Drag off from the As BP_PlayerCharacter return pin of the Cast to BP_PlayerCharacter node, then search for and select Get Is Crouched.



Navigate to the My Blueprint tab, then from the variables category drag and drop the Is Crouched variable on to the return pin of the Get Is Crouched node.



Click image to expand.

Drag off from the Cast To BP_PlayerCharacter's Output execution pin, and connect it to the Input execution pin of the Set Is Crouched node.



Click image to expand.

Drag off from the As BP_PlayerCharacter return pin of the Cast to BP_PlayerCharacter node, then from the All Actions drop down menu search for and select Get Pressed Jump.



From the MyBlueprint tab, navigate to the variables category, then drag and drop the Is Jumping variable on to the return pin of the Get Pressed Jump node.



Click image to expand.

Drag off from the Set Is Crouched node Output execution pin, and connect it to the Input execution pin of the Set Is Jumping node.



Click image to expand.

Compile and Save your PlayerCharacter_AB Animation Blueprint.



From the Variables category select the adjacent + sign to create two float variables named Speed and Direction.



Drag off from the As BP_PlayerCharacter return pin of the Cast to BP_PlayerCharacter node, then click to enable the context sensitive box, and search for and select Get Velocity.



Drag off from the Get Velocity node's Return Value pin, and from the Actions drop down menu, search for and select Vector Length.



In the My Blueprint tab, drag and drop the Speed variable on to the vector Return Value pin of the Vector Length node.



Click image to expand.

Next, connect the Execution output pin of the Set Is Jumping node to the execution input pin of the Set Speed node.



Click image to expand.

Drag off from the As BP_PlayerCharacter return pin of the Cast to BP_PlayerCharacter node, then search for and select Get Actor Rotation.



Drag off from the GetActorRotation node's rotator return value pin and from the drop down Actions menu, search for and select Calculate Direction.



Next, drag off from the vector Return Value pin of the Get Velocity node, and plug it into the Velocity input pin from the Calculate Direction node.



Click image to expand.

From the My Blueprint tab, click and drag the Direction variable and drop it onto the float Return Value pin of the Calculate Direction node.



Click image to expand.

Next, connect the Execution output pin from the Set Speed node to the execution input pin of the Set Direction node.



Click image to expand.

Drag off from the Event Blueprint Update Animation node's execution output pin and connect it to the Cast To BP_PlayerCharacter node.



Click image to expand.

Compile and Save your PlayerCharacter_AB Animation Blueprint.



Your completed Animation Event Graph will resemble the image below



Click image to expand.

Creating the Animation State Machines

State Machines provide a graphical visualization of organizing the animation of a Skeletal Mesh into a series of States. These states are governed by Transition Rules that control how to blend from one state to another. You will use your boolean variables to transition between the different locomotion Blend Spaces that you created in the earlier sections.

Inside your PlayerCharacter_AB Animation Blueprint, navigate to the Anim Graph.



Click image to expand.

The AnimGraph is used to evaluate a final pose for the skeletal mesh.

Right-click on the AnimGraph and from the Actions drop down menu, search for and select Add New State Machine.



Rename your State Machine node to Locomotion, then double-click the node to open its graph. Drag off from the Entry pin, and from the Actions drop down menu, select Add State.



Click image to expand.

Name the new state Movement, then double-click to open the Movement State Node. Navigate to the Asset browser, and search for Locomotion_BS, then click and drag it into the graph.



Click image to expand.

From the My Blueprint tab, click and drag your Speed float variable into the Blend Space's Speed vertical axis.



Click image to expand.

Navigate back to the My Blueprint tab, then click and drag your Direction float variable into the Blend Space's Direction horizontal axis.



Click image to expand.

Connect the Animation Pose output pin to the Animation Pose Result pin of the Output Animation Pose node.



Click image to expand.

Compile and Save.



Navigate back to the Locomotion state machine, then click and drag the Movement state node to create a new Animation state named Crouch Movement.



Click image to expand.

Double click the Transition rule node to open its Anim Graph.



Click image to expand.

From the My Blueprint Tab, navigate to the variables category and drag your Is Crouched boolean onto the Can Enter Transition input pin from the Result node.



Click image to expand.

Navigate back to the Locomotion state machine graph, and double click on the Crouch Movement state to open its anim graph. From the Asset browser, search for your LocomotionCrouch_BS, then click and drag it into the graph.



Click image to expand.

From the My Blueprint Tab, navigate to the variables category and drag your Speed and Direction float variables into their respective pins on the LocomotionCrouch_BS, then connect your LocomotionCrouch_BS Animation Pose into your Output Animation Pose Result pin.



Click image to expand.

Compile and Save your Animation Blueprint.



Navigate back to the Locomotion AnimGraph then click and drag off the CrouchMovement Animation state and connect it to the Movement Animation State.



Click image to expand.

Double click the Transition rule node to open it's Anim Graph.



Click image to expand.

From the My Blueprints tab, click and drag the Is Crouched boolean variable onto the Anim Graph, select Get Is Crouched, then drag off from its output pin and in the drop down actions menu search for and select NOT Boolean.



Click image to expand.

Next, connect the NOT Boolean's return pin to the Can Enter Transition input pin.



Click image to expand.

Compile and Save.



Navigate back to the Anim Graph, then click and drag off from the Movement Animation state and select Add State.



Click image to expand.

Rename this Animation State to Jump, then double-click to open its animation graph. Navigate to the Asset Browser and search for Jump_From_Jog, then drag it into the graph.



Click image to expand.

Finish your Jump Animation State by connecting your Play Jump_From_Jog Animation Pose to your Output Animation Pose Result pin.



Click image to expand.

Navigate back to the Locomotion Anim Graph, then double-click the Movement to Jump Transition rule node to open its Anim Graph.



Click image to expand.

Inside the Transition Rule Anim Graph, navigate to the My Blueprints tab, and drag your Is Jumping Boolean variable onto the Result node's Can Enter Transition input pin.



Click image to expand.

Navigate back to the Locomotion Anim Graph, then click and drag off the Jump anim node and create a transition to the Movement Anim Graph node.



Click image to expand.

Double-click the Jump to Movement Transition rule node to open it's Anim Graph.



Click image to expand.

From the My Blueprints tab, click and drag the Is Crouched, and Is Jumping Boolean variable onto the Anim Graph, then drag off each of their output pins and from the drop down actions menu search for and select NOT Boolean.



Click image to expand.

Drag off the NOT Boolean output pin and search for and select for the AND Boolean.



Connect both the Is Crouched, and Is Jumping NOT Boolean node output pins into the AND Boolean node's input pins, then connect the AND boolean's output pin into the Result node's Can Enter Transition Input pin.



Click image to expand.

Navigate back to the Locomotion Anim Graph, then click and drag off the Crouch node and create a transition to the Jump node.



Click image to expand.

Double-click the Crouch Movement to Jump Transition rule node to open it's Anim Graph.



Click image to expand.

Inside the CrouchMovement to Jump transition rule Anim Graph, navigate to the My Blueprint tab, then click and drag your Is Jumping bool variable onto the Result node's Can Enter Transition input pin.



Click image to expand.

Navigate back to the Locomotion Anim Graph, then drag off from the Jump node to create a transition to the CrouchMovement node.



Click image to expand.

Double-click the Jump to Crouch Movement Transition rule node to open it's Anim Graph.



Click image to expand.

From the My Blueprints tab, click and drag the Is Crouched and Is Jumping Boolean variables onto the Anim Graph.



Click image to expand.

Drag off from the Is Jumping Boolean output pin and from the actions drop down menu search for and select the NOT Boolean, then drag off from the Is Crouched Boolean output pin and search for and select for the AND Boolean. Connect the Is Jumping NOT Boolean output pin into the AND Boolean input pin, then connect the AND Boolean output pin into the Can Enter Transition Result pin to complete the transition rule.



Click image to expand.

Your completed Locomotion AnimGraph will resemble the image below.



Click image to expand.

Navigate to the AnimGraph and connect the Locomotion Pose Output pin into the Output Pose Result pin.



Click image to expand.

Compile and Save.



From the Content Browser, double-click your Bp_PlayerCharacter to open it's class defaults, then in the Components tab select the Mesh component, then navigate to the Details panel Animation category and in the Anim Class variable drop down menu, search for and select PlayerCharacter_AB.



Click image to expand.

Result

Now is the time to test your logic. From the toolbar select Play (PIE), you will be able to control your character's movement using the W,A,S,D keys. To sprint, click and hold your left shift key, to crouch, hold left ctrl, and to jump press the spacebar.



Project Setup

Creating the FireEffect Actor

Third Person Character: Setting Up the Finding Actor Pressed Event

End Result

Get Specific Actors with Tag

End Result

Once your projects begin to increase in scale, you may find it difficult to locate an individual Actor in your scene. It is common to have hundreds of Actors in your scene ranging from level set pieces and geometry, to NPCs, enemies, interactable objects, and pick-ups. When working in the Unreal Editor, You can use the World Outliner to assist in finding an Actor in your scene.



In the image above, the World Outliner (right) represents all the Actors that are placed inside your level. Clicking on one of the Actors in the World Outliner highlights it inside the level viewport as well. You can sort the World Outliner by Actor Name or by Actor Type by clicking on the Actor or Type headers (you can change the secondary category from Type to other filters by clicking the down arrow in the Type Box).

With an Actor selected in the World Outliner, and while navigating inside the Level Viewport, double-clicking the Actor or pressing the F key will move the camera to the location of the Actor selected to Focus on it.

Refer to the World Outliner documentation for more information on locating an Actor in your scenes.

Choose your implementation method:

Blueprints

C++

Project Setup

In this tutorial, you will find Actors in a Level by using the Get All Actors of Class node. When this node is called it will retrieve all Actors in your Level of the specified Class and place them in an Array. Then, from that Array, you can retrieve an Actor or Actors based on your filter criteria. You can then access the properties of the Actor(s) or modify them in some way based on the functionality you want to achieve.

Begin by creating a New > Games > ThirdPerson > Blueprint Project with Starter Content, named FindingActors.





Click for full view.

Navigate to Edit > Project Settings > Engine > Input > Bindings > Action Mappings, then click Add(+) to create a new action mapping named FindActorPressed, then set the key value to 1.





Click for full view.

In this tutorial, you will find Actors in a Level by using the Gameplay Statics Class Library (Get All Actors of Class node). When this Function (node) is called, it will retrieve all Actors in your Level of the specified Class and place them in an Array. Then, from that Array, you can retrieve all Actors or an Actor based on any filter criteria. You can then access the properties of the Actor(s) or modify them in some way based on the functionality you want to achieve.

Begin by creating a New > Games > ThirdPerson > C++ Project with Starter Content named FindingActors.





Click for full view.

Navigate to the Edit > Project Settings > Engine > Input > Bindings > Action Mappings, then click Add(+) to create a new action mapping named FindActorPressed, then set the key value to 1.





Click for full view.

Creating the FireEffect Actor

The Starter Content folder provides a completed FireEffect Actor that includes a Particle Component to represent the flame effect, and an Audio Component for the sound effects. This Actor will be used as the base Actor class to find from the Get All Actors of Class node.

Navigate to Content > StarterContent > Blueprints, then drag an instance of Blueprint_Effect_Fire into the World.





Click the Add button to create a New C++ Class then from the Choose a Parent Class menu, select Actor, click Next.





Click for full view.

Name your new Actor class FireEffect and click Create Class.





Click for full view.

In FireEffect.h, declare the following:

Navigate to the FireEffect.cpp file, then include the following class libraries:

In the AFireEffect constructor, implement the following code:

Compile your code.

Navigate to Content Browser > C++ Classes > FindingActors and right-click the FireEffect Actor to Create a Blueprint class based on FireEffect named BP_FireEffect.





In the Class Defaults of BP_FireEffect, click Particle Fire in the Components panel, then navigate to the Details panel, then under the Particles category open the Template dropdown menu and choose P_Fire.





Click Fire Audio in the Components panel, then navigate to the Details panel. From the Sound category, open the Sound variable dropdown menu and choose Fire01_Cue.





Click Compile and Save.





Finished Code

FireEffectActor.h

FireEffectActor.cpp

Third Person Character: Setting Up the Finding Actor Pressed Event

Navigate to the Content > ThirdPerson > Blueprints folder and double click the BP_ThirdPersonCharacter to open its Class Defaults.





Right-click on the Event Graph, then from the Actions menu search for the FindActorPressed action key event.





Begin Object Class=/Script/BlueprintGraph.K2Node_InputAction Name="K2Node_InputAction_0" InputActionName="FindActorPressed" NodePosX=1888 NodePosY=-1872 NodeGuid=FBD130CA4B38E7EC109B4F9BBCA33FFB CustomProperties Pin (PinId=9F6A77044C16959D8F56609708D89596,PinName="Pressed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 E58983F14694AB7BCC89A98A65E6BB35,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=87DC23804616D07F09DC8190ADA3FE96,PinName="Released",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B611973E4A523F0F16BEC087FF8D723E,PinName="Key",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/InputCore.Key"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the FindActorPressed node Key Event, drag off from the Pressed pin, then from the Actions menu, search for the Get All Actors Of Class node.





Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_4" FunctionReference=(MemberParent=Class'"/Script/Engine.GameplayStatics"',MemberName="GetAllActorsOfClass") NodePosX=2160 NodePosY=-1872 NodeGuid=61E4EE4740C10058B2B9DFA689C49F9C CustomProperties Pin (PinId=E58983F14694AB7BCC89A98A65E6BB35,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_InputAction_0 9F6A77044C16959D8F56609708D89596,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=119C73644CB61F6C74F409BF547B7FF8,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 16F4B13848C9E3132F384194078D6D5F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B4D3D3A94877B6A8609BC8BE5D8D0699,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.GameplayStatics"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__GameplayStatics",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C3D99D2420710A459B12B81C8E158E2,PinName="WorldContextObject",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3AB4E1F24203C70A4FA12E8ECD70A681,PinName="ActorClass",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=True,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=86BEB46F4082E7E5B82111852DDB356F,PinName="OutActors",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 F99669A64B33AF344D600893B938A007,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Inside the Get All Actors of Class node, click the Actor Class, then from the drop-down select the Blueprint_Effect_Fire class.





Drag off from the Out Actors pin and in the Actions menu, search for For Each Loop.





Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_0" MacroGraphReference=(MacroGraph=EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForEachLoop"',GraphBlueprint=Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=99DBFD5540A796041F72A5A9DA655026) ResolvedWildcardType=(PinCategory="object",PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',ContainerType=Array) NodePosX=2480 NodePosY=-1872 NodeGuid=28A2257841BDB047B1458C88DF019D23 CustomProperties Pin (PinId=16F4B13848C9E3132F384194078D6D5F,PinName="Exec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 119C73644CB61F6C74F409BF547B7FF8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F99669A64B33AF344D600893B938A007,PinName="Array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 86BEB46F4082E7E5B82111852DDB356F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5D8F4FF74F98AD3553017FB055D45FA1,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_1 097B103847E03552E82681AD1D405537,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CAADD35C46C95564750F4F92E7F58527,PinName="Array Element",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_2 ECAD8B5D4D680090E3CCC29D37C5C195,K2Node_VariableGet_3 471F92EF481AEF8ACC53108520ECA2F3,K2Node_Knot_0 5C8BB9C743BFE8143F2B6F8F1A9D75B5,K2Node_VariableGet_6 374C3EF1414A966273A058B3E457E146,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=57931C1344A0AA9732A47995DEF0D73B,PinName="Array Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C75ADED6436FF26968C48EA3F8458746,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off from the Execution pin of the Get All Actors Of Class node and plug it into the Exec pin of the For Each Loop node.





Begin Object Class=/Script/BlueprintGraph.K2Node_InputAction Name="K2Node_InputAction_0" InputActionName="FindActorPressed" NodePosX=1888 NodePosY=-1872 NodeGuid=FBD130CA4B38E7EC109B4F9BBCA33FFB CustomProperties Pin (PinId=9F6A77044C16959D8F56609708D89596,PinName="Pressed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 E58983F14694AB7BCC89A98A65E6BB35,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=87DC23804616D07F09DC8190ADA3FE96,PinName="Released",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B611973E4A523F0F16BEC087FF8D723E,PinName="Key",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/InputCore.Key"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_4" FunctionReference=(MemberParent=Class'"/Script/Engine.GameplayStatics"',MemberName="GetAllActorsOfClass") NodePosX=2160 NodePosY=-1872 NodeGuid=61E4EE4740C10058B2B9DFA689C49F9C CustomProperties Pin (PinId=E58983F14694AB7BCC89A98A65E6BB35,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_InputAction_0 9F6A77044C16959D8F56609708D89596,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=119C73644CB61F6C74F409BF547B7FF8,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 16F4B13848C9E3132F384194078D6D5F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B4D3D3A94877B6A8609BC8BE5D8D0699,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nGameplay Statics Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.GameplayStatics"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__GameplayStatics",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C3D99D2420710A459B12B81C8E158E2,PinName="WorldContextObject",PinToolTip="World Context Object\nObject Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3AB4E1F24203C70A4FA12E8ECD70A681,PinName="ActorClass",PinToolTip="Actor Class\nActor Class Reference\n\nClass of Actor to find. Must be specified or result array will be empty.",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=True,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=86BEB46F4082E7E5B82111852DDB356F,PinName="OutActors",PinToolTip="Out Actors\nArray of Blueprint Effect Fire Object References\n\nOutput array of Actors of the specified class.",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 F99669A64B33AF344D600893B938A007,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_0" MacroGraphReference=(MacroGraph=EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForEachLoop"',GraphBlueprint=Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=99DBFD5540A796041F72A5A9DA655026) ResolvedWildcardType=(PinCategory="object",PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',ContainerType=Array) NodePosX=2480 NodePosY=-1872 NodeGuid=28A2257841BDB047B1458C88DF019D23 CustomProperties Pin (PinId=16F4B13848C9E3132F384194078D6D5F,PinName="Exec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 119C73644CB61F6C74F409BF547B7FF8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F99669A64B33AF344D600893B938A007,PinName="Array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 86BEB46F4082E7E5B82111852DDB356F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5D8F4FF74F98AD3553017FB055D45FA1,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_1 097B103847E03552E82681AD1D405537,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CAADD35C46C95564750F4F92E7F58527,PinName="Array Element",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_2 ECAD8B5D4D680090E3CCC29D37C5C195,K2Node_VariableGet_3 471F92EF481AEF8ACC53108520ECA2F3,K2Node_Knot_0 5C8BB9C743BFE8143F2B6F8F1A9D75B5,K2Node_VariableGet_6 374C3EF1414A966273A058B3E457E146,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=57931C1344A0AA9732A47995DEF0D73B,PinName="Array Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C75ADED6436FF26968C48EA3F8458746,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

From the ForEachLoop node, drag off the Array Element pin, then in the Actions menu, search for Get P Fire.





Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" VariableReference=(MemberParent=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',MemberName="P_Fire") SelfContextInfo=NotSelfContext NodePosX=2752 NodePosY=-1856 NodeGuid=EC0E6A0448508964FD46B5B8C2BED41D CustomProperties Pin (PinId=A11784CE4D38B09FC622309D4408E976,PinName="P_Fire",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ParticleSystemComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_3 38015A0A4A2DF318E70CDDA5F8DDB66B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=471F92EF481AEF8ACC53108520ECA2F3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off from the Array Element pin, then in the Actions menu, search for Get Fire Audio.





Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_6" VariableReference=(MemberParent=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',MemberName="Fire Audio") SelfContextInfo=NotSelfContext NodePosX=2752 NodePosY=-1776 NodeGuid=4BF6103543046FA0CAFA23B081755645 CustomProperties Pin (PinId=A14DD3644E3EBF8808946899CDCE846C,PinName="Fire Audio",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.AudioComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 F9297D5B4219E323C1CE74B36E5EF5CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=374C3EF1414A966273A058B3E457E146,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off from the P Fire pin, then in the Actions menu search for the Deactivate node.





Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_8" FunctionReference=(MemberParent=Class'"/Script/Engine.ActorComponent"',MemberName="Deactivate") NodePosX=3152 NodePosY=-1888 NodeGuid=FF5C3C8E4A4C49B506A620AD75FC9931 CustomProperties Pin (PinId=CF1465F14359C545CA991789CF948299,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_0 479CC221426D34E09D3C34A84FC49952,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=980C2EFD4D2829559411F0BC91A845EE,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F9297D5B4219E323C1CE74B36E5EF5CC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nActor Component Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ActorComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_3 81932E9C4206896379B8B09FB0254656,K2Node_VariableGet_6 A14DD3644E3EBF8808946899CDCE846C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off from the Fire Audio pin and connect it to the Target pin from the Deactivate node.





Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_0" MacroGraphReference=(MacroGraph=EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForEachLoop"',GraphBlueprint=Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=99DBFD5540A796041F72A5A9DA655026) ResolvedWildcardType=(PinCategory="object",PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',ContainerType=Array) NodePosX=2480 NodePosY=-1872 NodeGuid=28A2257841BDB047B1458C88DF019D23 CustomProperties Pin (PinId=16F4B13848C9E3132F384194078D6D5F,PinName="Exec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 119C73644CB61F6C74F409BF547B7FF8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F99669A64B33AF344D600893B938A007,PinName="Array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 86BEB46F4082E7E5B82111852DDB356F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5D8F4FF74F98AD3553017FB055D45FA1,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 CF1465F14359C545CA991789CF948299,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CAADD35C46C95564750F4F92E7F58527,PinName="Array Element",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_3 471F92EF481AEF8ACC53108520ECA2F3,K2Node_VariableGet_6 374C3EF1414A966273A058B3E457E146,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=57931C1344A0AA9732A47995DEF0D73B,PinName="Array Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C75ADED6436FF26968C48EA3F8458746,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" VariableReference=(MemberParent=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',MemberName="P_Fire") SelfContextInfo=NotSelfContext NodePosX=2704 NodePosY=-1808 NodeGuid=EC0E6A0448508964FD46B5B8C2BED41D CustomProperties Pin (PinId=A11784CE4D38B09FC622309D4408E976,PinName="P_Fire",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ParticleSystemComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 F9297D5B4219E323C1CE74B36E5EF5CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=471F92EF481AEF8ACC53108520ECA2F3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_6" VariableReference=(MemberParent=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',MemberName="Fire Audio") SelfContextInfo=NotSelfContext NodePosX=2704 NodePosY=-1744 NodeGuid=4BF6103543046FA0CAFA23B081755645 CustomProperties Pin (PinId=A14DD3644E3EBF8808946899CDCE846C,PinName="Fire Audio",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.AudioComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 F9297D5B4219E323C1CE74B36E5EF5CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=374C3EF1414A966273A058B3E457E146,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_8" FunctionReference=(MemberParent=Class'"/Script/Engine.ActorComponent"',MemberName="Deactivate") NodePosX=2928 NodePosY=-1888 NodeGuid=FF5C3C8E4A4C49B506A620AD75FC9931 CustomProperties Pin (PinId=CF1465F14359C545CA991789CF948299,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 5D8F4FF74F98AD3553017FB055D45FA1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=980C2EFD4D2829559411F0BC91A845EE,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F9297D5B4219E323C1CE74B36E5EF5CC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nActor Component Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ActorComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_6 A14DD3644E3EBF8808946899CDCE846C,K2Node_VariableGet_3 A11784CE4D38B09FC622309D4408E976,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Click Compile and Save.





From the Content Browser, navigate to C++ Classes > FindingActors and double-click FindingActorsCharacter to open the FindingActorsCharacter.h file.





In the FindingActorsCharacter class defaults, declare the following:

Navigate to FindingActorsCharacter.cpp and include the following class libraries:

Unreal Engine uses an Include-What-You-Use (IWYU) dependency model. This means that the Engine's source code only includes the dependencies that it needs to compile. See IWYU for additional documentation.

Implement the logic for your OnFindActorPressed by declaring the following code:

Navigate to the SetupPlayerInputComponent method and declare the following code:

Compile your code.

Finished Blueprint





Begin Object Class=/Script/BlueprintGraph.K2Node_InputAction Name="K2Node_InputAction_0" InputActionName="FindActorPressed" NodePosX=1888 NodePosY=-1872 NodeGuid=FBD130CA4B38E7EC109B4F9BBCA33FFB CustomProperties Pin (PinId=9F6A77044C16959D8F56609708D89596,PinName="Pressed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 E58983F14694AB7BCC89A98A65E6BB35,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=87DC23804616D07F09DC8190ADA3FE96,PinName="Released",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B611973E4A523F0F16BEC087FF8D723E,PinName="Key",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/InputCore.Key"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_4" FunctionReference=(MemberParent=Class'"/Script/Engine.GameplayStatics"',MemberName="GetAllActorsOfClass") NodePosX=2160 NodePosY=-1872 NodeGuid=61E4EE4740C10058B2B9DFA689C49F9C CustomProperties Pin (PinId=E58983F14694AB7BCC89A98A65E6BB35,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_InputAction_0 9F6A77044C16959D8F56609708D89596,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=119C73644CB61F6C74F409BF547B7FF8,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 16F4B13848C9E3132F384194078D6D5F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B4D3D3A94877B6A8609BC8BE5D8D0699,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nGameplay Statics Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.GameplayStatics"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__GameplayStatics",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C3D99D2420710A459B12B81C8E158E2,PinName="WorldContextObject",PinToolTip="World Context Object\nObject Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3AB4E1F24203C70A4FA12E8ECD70A681,PinName="ActorClass",PinToolTip="Actor Class\nActor Class Reference\n\nClass of Actor to find. Must be specified or result array will be empty.",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=True,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=86BEB46F4082E7E5B82111852DDB356F,PinName="OutActors",PinToolTip="Out Actors\nArray of Blueprint Effect Fire Object References\n\nOutput array of Actors of the specified class.",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 F99669A64B33AF344D600893B938A007,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_0" MacroGraphReference=(MacroGraph=EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForEachLoop"',GraphBlueprint=Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=99DBFD5540A796041F72A5A9DA655026) ResolvedWildcardType=(PinCategory="object",PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',ContainerType=Array) NodePosX=2480 NodePosY=-1872 NodeGuid=28A2257841BDB047B1458C88DF019D23 CustomProperties Pin (PinId=16F4B13848C9E3132F384194078D6D5F,PinName="Exec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 119C73644CB61F6C74F409BF547B7FF8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F99669A64B33AF344D600893B938A007,PinName="Array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 86BEB46F4082E7E5B82111852DDB356F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5D8F4FF74F98AD3553017FB055D45FA1,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 CF1465F14359C545CA991789CF948299,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CAADD35C46C95564750F4F92E7F58527,PinName="Array Element",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_3 471F92EF481AEF8ACC53108520ECA2F3,K2Node_VariableGet_6 374C3EF1414A966273A058B3E457E146,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=57931C1344A0AA9732A47995DEF0D73B,PinName="Array Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C75ADED6436FF26968C48EA3F8458746,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" VariableReference=(MemberParent=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',MemberName="P_Fire") SelfContextInfo=NotSelfContext NodePosX=2704 NodePosY=-1808 NodeGuid=EC0E6A0448508964FD46B5B8C2BED41D CustomProperties Pin (PinId=A11784CE4D38B09FC622309D4408E976,PinName="P_Fire",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ParticleSystemComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 F9297D5B4219E323C1CE74B36E5EF5CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=471F92EF481AEF8ACC53108520ECA2F3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_6" VariableReference=(MemberParent=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',MemberName="Fire Audio") SelfContextInfo=NotSelfContext NodePosX=2704 NodePosY=-1744 NodeGuid=4BF6103543046FA0CAFA23B081755645 CustomProperties Pin (PinId=A14DD3644E3EBF8808946899CDCE846C,PinName="Fire Audio",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.AudioComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 F9297D5B4219E323C1CE74B36E5EF5CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=374C3EF1414A966273A058B3E457E146,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_8" FunctionReference=(MemberParent=Class'"/Script/Engine.ActorComponent"',MemberName="Deactivate") NodePosX=2928 NodePosY=-1888 NodeGuid=FF5C3C8E4A4C49B506A620AD75FC9931 CustomProperties Pin (PinId=CF1465F14359C545CA991789CF948299,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 5D8F4FF74F98AD3553017FB055D45FA1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=980C2EFD4D2829559411F0BC91A845EE,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F9297D5B4219E323C1CE74B36E5EF5CC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nActor Component Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ActorComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_6 A14DD3644E3EBF8808946899CDCE846C,K2Node_VariableGet_3 A11784CE4D38B09FC622309D4408E976,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Finished Code

FindingActorsCharacter.h

FindingActorsCharacter.cpp

End Result

Navigate to the Toolbar and click Play (PIE).





When pressing the numeric 1 key, you should notice the Fire effect particles will extinguish and the sound effects emitting from the audio component will no longer be heard.

Navigate to Content Browser, and drag a few instances of your BP_FireEffect into the Level.





Click for full view.

Navigate to the Toolbar and click Play (PIE).





When pressing the numeric 1 key, you should notice the Fire effect particles will extinguish and the sound effects emitting from the audio component will no longer be heard.

Get Specific Actors with Tag

You used the Get All Actors of Class node to get an Array of Actors of a specified Class. However, you can also filter the Array results based on different criteria to get specific Actors or a single Actor from the Array by using Tags on the Actor.

Navigate to the Content > StarterContent > Blueprints and select Blueprint_Effect_Fire.





In the Details panel, navigate to the Tags section and click Add(+) to add a tag to the Actor.





In the 0 element field, enter "FindActorTag" into the text string.





Inside the MyCharacter Blueprint, drag off from the Array Element pin of the For Each Loop and in the Actions menu search for Get Tags.





Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_2" VariableReference=(MemberParent=Class'"/Script/Engine.Actor"',MemberName="Tags") NodePosX=1920 NodePosY=-1360 NodeGuid=0C203A7543F707A440C80293D590709B CustomProperties Pin (PinId=7308599B448C1CD0C091DF96165E4DF3,PinName="Tags",PinFriendlyName=NSLOCTEXT("UObjectDisplayNames", "Actor:Tags", "Tags"),Direction="EGPD_Output",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GetArrayItem_0 E3258A5846572B56A5470CB8B762F84B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ECAD8B5D4D680090E3CCC29D37C5C195,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off from the Tags pin, then in the Actions menu search for the Get(a copy) node.





Begin Object Class=/Script/BlueprintGraph.K2Node_GetArrayItem Name="K2Node_GetArrayItem_0" bReturnByRefDesired=False NodePosX=2144 NodePosY=-1360 NodeGuid=E5DF6CC2421E8DDECB7098867E072B0E CustomProperties Pin (PinId=E3258A5846572B56A5470CB8B762F84B,PinName="Array",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_2 7308599B448C1CD0C091DF96165E4DF3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=68D25C4D4CBA98D3119F3EBAE624B37F,PinName="Dimension 1",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0",AutogeneratedDefaultValue="0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=772A9C434EFD0F4D4B86BA939BBD6347,PinName="Output",Direction="EGPD_Output",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_7 295FB75E40124619DB4B0B92AFE7D90B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Here we are "Getting" the Tag at Index 0 which we set as FindActorTag above.

Your Blueprint Script should look as following:





Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_0" MacroGraphReference=(MacroGraph=EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForEachLoop"',GraphBlueprint=Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=99DBFD5540A796041F72A5A9DA655026) ResolvedWildcardType=(PinCategory="object",PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',ContainerType=Array) NodePosX=2480 NodePosY=-1872 NodeGuid=28A2257841BDB047B1458C88DF019D23 CustomProperties Pin (PinId=16F4B13848C9E3132F384194078D6D5F,PinName="Exec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 119C73644CB61F6C74F409BF547B7FF8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F99669A64B33AF344D600893B938A007,PinName="Array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 86BEB46F4082E7E5B82111852DDB356F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5D8F4FF74F98AD3553017FB055D45FA1,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 CF1465F14359C545CA991789CF948299,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CAADD35C46C95564750F4F92E7F58527,PinName="Array Element",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_3 471F92EF481AEF8ACC53108520ECA2F3,K2Node_VariableGet_6 374C3EF1414A966273A058B3E457E146,K2Node_VariableGet_7 8338CB724A8E5FBFCD980AAFA875ECAA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=57931C1344A0AA9732A47995DEF0D73B,PinName="Array Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C75ADED6436FF26968C48EA3F8458746,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" VariableReference=(MemberParent=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',MemberName="P_Fire") SelfContextInfo=NotSelfContext NodePosX=2704 NodePosY=-1808 NodeGuid=EC0E6A0448508964FD46B5B8C2BED41D CustomProperties Pin (PinId=A11784CE4D38B09FC622309D4408E976,PinName="P_Fire",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ParticleSystemComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 F9297D5B4219E323C1CE74B36E5EF5CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=471F92EF481AEF8ACC53108520ECA2F3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_6" VariableReference=(MemberParent=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',MemberName="Fire Audio") SelfContextInfo=NotSelfContext NodePosX=2704 NodePosY=-1744 NodeGuid=4BF6103543046FA0CAFA23B081755645 CustomProperties Pin (PinId=A14DD3644E3EBF8808946899CDCE846C,PinName="Fire Audio",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.AudioComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 F9297D5B4219E323C1CE74B36E5EF5CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=374C3EF1414A966273A058B3E457E146,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_8" FunctionReference=(MemberParent=Class'"/Script/Engine.ActorComponent"',MemberName="Deactivate") NodePosX=2928 NodePosY=-1888 NodeGuid=FF5C3C8E4A4C49B506A620AD75FC9931 CustomProperties Pin (PinId=CF1465F14359C545CA991789CF948299,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 5D8F4FF74F98AD3553017FB055D45FA1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=980C2EFD4D2829559411F0BC91A845EE,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F9297D5B4219E323C1CE74B36E5EF5CC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nActor Component Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ActorComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_6 A14DD3644E3EBF8808946899CDCE846C,K2Node_VariableGet_3 A11784CE4D38B09FC622309D4408E976,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_7" VariableReference=(MemberParent=Class'"/Script/Engine.Actor"',MemberName="Tags") NodePosX=2704 NodePosY=-1680 NodeGuid=C9A1337446A5FAB270F463B3A5BE48E1 CustomProperties Pin (PinId=EFC5D4414D32E8FA9B94E3BC4D8DA0FD,PinName="Tags",PinFriendlyName=NSLOCTEXT("UObjectDisplayNames", "Actor:Tags", "Tags"),Direction="EGPD_Output",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GetArrayItem_1 B846E80B4B02B43E916652BF8864DC1D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8338CB724A8E5FBFCD980AAFA875ECAA,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_GetArrayItem Name="K2Node_GetArrayItem_1" bReturnByRefDesired=False NodePosX=2928 NodePosY=-1728 NodeGuid=02E22D154D3632EE5A50DCA2A8C00EC5 CustomProperties Pin (PinId=B846E80B4B02B43E916652BF8864DC1D,PinName="Array",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_7 EFC5D4414D32E8FA9B94E3BC4D8DA0FD,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DEFD5C384D9EE0DE1CAA9BA9ECF81990,PinName="Dimension 1",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0",AutogeneratedDefaultValue="0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=AE53DDF64003901AC2B1878E9E4B61AA,PinName="Output",Direction="EGPD_Output",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off from the Execution pin of the For Each Loop node, then in the Actions menu search for the Branch node.





Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_1" NodePosX=3120 NodePosY=-1488 NodeGuid=DFC4ABE64DC0356473DDA2BE738D771D CustomProperties Pin (PinId=61B6E9074113999977E39DAA7B7B352D,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=52EE3DC9454E19C791E1CAAFE1023020,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=361E54BD42BF2F21DC6C4C856E41085F,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=0F1C1F4542A52B92F073A8B341105534,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Drag off from the Condition pin of the Branch node and add an Actor Has Tag node.





Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_5" bIsPureFunc=True bIsConstFunc=True FunctionReference=(MemberName="ActorHasTag",bSelfContext=True) NodePosX=3040 NodePosY=-1360 NodeGuid=02CBA1AF4E96C2869FD090A2395E3330 CustomProperties Pin (PinId=5B9B626F499F8E500E65E3B726DAA426,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=81A1A559439FDD8186421C9CEF04CC5A,PinName="Tag",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=276E52B2477269656B9F3D9D64AEC475,PinName="ReturnValue",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",AutogeneratedDefaultValue="false",LinkedTo=(K2Node_IfThenElse_1 52EE3DC9454E19C791E1CAAFE1023020,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Connect the out pin from the Get node to the Tag pin on the Actor Has Tag node.





Connect the Array Element pin of the For Each Loop node to the Target pin on the Actor Has Tag node. Your Blueprint Script should look as following:





Connect the True pin of the Branch node with Exec Pin of the Deactivate node.





Your Blueprint Script should look as following:





Begin Object Class=/Script/BlueprintGraph.K2Node_InputAction Name="K2Node_InputAction_0" InputActionName="FindActorPressed" NodePosX=1888 NodePosY=-1872 NodeGuid=FBD130CA4B38E7EC109B4F9BBCA33FFB CustomProperties Pin (PinId=9F6A77044C16959D8F56609708D89596,PinName="Pressed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 E58983F14694AB7BCC89A98A65E6BB35,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=87DC23804616D07F09DC8190ADA3FE96,PinName="Released",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B611973E4A523F0F16BEC087FF8D723E,PinName="Key",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/InputCore.Key"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_4" FunctionReference=(MemberParent=Class'"/Script/Engine.GameplayStatics"',MemberName="GetAllActorsOfClass") NodePosX=2160 NodePosY=-1872 NodeGuid=61E4EE4740C10058B2B9DFA689C49F9C CustomProperties Pin (PinId=E58983F14694AB7BCC89A98A65E6BB35,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_InputAction_0 9F6A77044C16959D8F56609708D89596,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=119C73644CB61F6C74F409BF547B7FF8,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 16F4B13848C9E3132F384194078D6D5F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B4D3D3A94877B6A8609BC8BE5D8D0699,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.GameplayStatics"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__GameplayStatics",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=1C3D99D2420710A459B12B81C8E158E2,PinName="WorldContextObject",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=3AB4E1F24203C70A4FA12E8ECD70A681,PinName="ActorClass",PinType.PinCategory="class",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=True,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=86BEB46F4082E7E5B82111852DDB356F,PinName="OutActors",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 F99669A64B33AF344D600893B938A007,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_MacroInstance Name="K2Node_MacroInstance_0" MacroGraphReference=(MacroGraph=EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForEachLoop"',GraphBlueprint=Blueprint'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros"',GraphGuid=99DBFD5540A796041F72A5A9DA655026) ResolvedWildcardType=(PinCategory="object",PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',ContainerType=Array) NodePosX=2480 NodePosY=-1872 NodeGuid=28A2257841BDB047B1458C88DF019D23 CustomProperties Pin (PinId=16F4B13848C9E3132F384194078D6D5F,PinName="Exec",PinType.PinCategory="Exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 119C73644CB61F6C74F409BF547B7FF8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F99669A64B33AF344D600893B938A007,PinName="Array",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_4 86BEB46F4082E7E5B82111852DDB356F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=5D8F4FF74F98AD3553017FB055D45FA1,PinName="LoopBody",Direction="EGPD_Output",PinType.PinCategory="Exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_1 412C6A0F43DED9C26E7C2593C21A82FC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CAADD35C46C95564750F4F92E7F58527,PinName="Array Element",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_2 ECAD8B5D4D680090E3CCC29D37C5C195,K2Node_VariableGet_3 471F92EF481AEF8ACC53108520ECA2F3,K2Node_VariableGet_6 374C3EF1414A966273A058B3E457E146,K2Node_Knot_13 91DAD7694D23A6620A0853B20C039690,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=57931C1344A0AA9732A47995DEF0D73B,PinName="Array Index",Direction="EGPD_Output",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C75ADED6436FF26968C48EA3F8458746,PinName="Completed",Direction="EGPD_Output",PinType.PinCategory="Exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_2" VariableReference=(MemberParent=Class'"/Script/Engine.Actor"',MemberName="Tags") NodePosX=2720 NodePosY=-1600 NodeGuid=0C203A7543F707A440C80293D590709B CustomProperties Pin (PinId=7308599B448C1CD0C091DF96165E4DF3,PinName="Tags",PinFriendlyName=NSLOCTEXT("UObjectDisplayNames", "Actor:Tags", "Tags"),Direction="EGPD_Output",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_GetArrayItem_0 E3258A5846572B56A5470CB8B762F84B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=ECAD8B5D4D680090E3CCC29D37C5C195,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" VariableReference=(MemberParent=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',MemberName="P_Fire") SelfContextInfo=NotSelfContext NodePosX=2720 NodePosY=-1744 NodeGuid=EC0E6A0448508964FD46B5B8C2BED41D CustomProperties Pin (PinId=A11784CE4D38B09FC622309D4408E976,PinName="P_Fire",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ParticleSystemComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 F9297D5B4219E323C1CE74B36E5EF5CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=471F92EF481AEF8ACC53108520ECA2F3,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_6" VariableReference=(MemberParent=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',MemberName="Fire Audio") SelfContextInfo=NotSelfContext NodePosX=2720 NodePosY=-1696 NodeGuid=4BF6103543046FA0CAFA23B081755645 CustomProperties Pin (PinId=A14DD3644E3EBF8808946899CDCE846C,PinName="Fire Audio",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.AudioComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 F9297D5B4219E323C1CE74B36E5EF5CC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=374C3EF1414A966273A058B3E457E146,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_8" FunctionReference=(MemberParent=Class'"/Script/Engine.ActorComponent"',MemberName="Deactivate") NodePosX=3056 NodePosY=-1888 NodeGuid=FF5C3C8E4A4C49B506A620AD75FC9931 CustomProperties Pin (PinId=CF1465F14359C545CA991789CF948299,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_1 EF9A4AB442A08B1818D0858D9C9E00F0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=980C2EFD4D2829559411F0BC91A845EE,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=F9297D5B4219E323C1CE74B36E5EF5CC,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nActor Component Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.ActorComponent"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_6 A14DD3644E3EBF8808946899CDCE846C,K2Node_VariableGet_3 A11784CE4D38B09FC622309D4408E976,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_GetArrayItem Name="K2Node_GetArrayItem_0" bReturnByRefDesired=False NodePosX=2896 NodePosY=-1616 NodeGuid=E5DF6CC2421E8DDECB7098867E072B0E CustomProperties Pin (PinId=E3258A5846572B56A5470CB8B762F84B,PinName="Array",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=Array,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_2 7308599B448C1CD0C091DF96165E4DF3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=68D25C4D4CBA98D3119F3EBAE624B37F,PinName="Dimension 1",PinType.PinCategory="int",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0",AutogeneratedDefaultValue="0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=772A9C434EFD0F4D4B86BA939BBD6347,PinName="Output",Direction="EGPD_Output",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_5 D3406CDE427DF19321BA55B93DA78583,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_IfThenElse Name="K2Node_IfThenElse_1" NodePosX=2736 NodePosY=-1872 NodeGuid=95EAB7DB415B81596D237D987202235A CustomProperties Pin (PinId=412C6A0F43DED9C26E7C2593C21A82FC,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 5D8F4FF74F98AD3553017FB055D45FA1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A7C2490D47CC93C5F677AAB023E5F096,PinName="Condition",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",LinkedTo=(K2Node_Knot_2 CC625E6C4D5221DFCD836497FEEC5EAA,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=EF9A4AB442A08B1818D0858D9C9E00F0,PinName="then",PinFriendlyName=NSLOCTEXT("K2Node", "true", "true"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_8 CF1465F14359C545CA991789CF948299,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=13176FBC4ADA353C1003BE941D9C5CAE,PinName="else",PinFriendlyName=NSLOCTEXT("K2Node", "false", "false"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_5" bIsPureFunc=True bIsConstFunc=True FunctionReference=(MemberName="ActorHasTag",bSelfContext=True) NodePosX=3104 NodePosY=-1744 NodeGuid=E9D631E54CBBCFFECAF4948BCCFA812F CustomProperties Pin (PinId=A32784844BE6740F3FE7F69737FDC850,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nActor Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.Actor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_14 B6B8D69849BB206B2A0F3DB5CA259AAB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=D3406CDE427DF19321BA55B93DA78583,PinName="Tag",PinToolTip="Tag\nName",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",LinkedTo=(K2Node_GetArrayItem_0 772A9C434EFD0F4D4B86BA939BBD6347,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DA1EE5F64AE953E681BE0B98A9C5FCE9,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nSee if this actor\'s Tags array contains the supplied name tag",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",AutogeneratedDefaultValue="false",LinkedTo=(K2Node_Knot_4 A79DD69041122EE234CA108A99C62C8D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_2" NodePosX=2736 NodePosY=-1776 NodeGuid=2B0B3E7F43183DF7FE39E390ED13A190 CustomProperties Pin (PinId=7B13AFCF4578934F13EA3F80EB41FBF0,PinName="InputPin",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_10 A805508D4168A383A2F9E5B8B567E53F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=CC625E6C4D5221DFCD836497FEEC5EAA,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_IfThenElse_1 A7C2490D47CC93C5F677AAB023E5F096,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_4" NodePosX=3264 NodePosY=-1760 NodeGuid=386FB0794F8C8B9851E5A18714E74054 CustomProperties Pin (PinId=A79DD69041122EE234CA108A99C62C8D,PinName="InputPin",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_5 DA1EE5F64AE953E681BE0B98A9C5FCE9,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=C6B0DFFE4F72588B27D027A415368BD8,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_11 A9A0053B45D42013C52EEAB5AAB20AFC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_10" NodePosX=2912 NodePosY=-1776 NodeGuid=9B72586042A289423F23B487FBE67BE9 CustomProperties Pin (PinId=6E42CDF54BC465939BB3A997C0116E8E,PinName="InputPin",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_11 DBE99D1B4C800128556803A29FA8D370,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=A805508D4168A383A2F9E5B8B567E53F,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_2 7B13AFCF4578934F13EA3F80EB41FBF0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_11" NodePosX=3024 NodePosY=-1760 NodeGuid=93BBF083479B6D19363A04A8B83D9636 CustomProperties Pin (PinId=A9A0053B45D42013C52EEAB5AAB20AFC,PinName="InputPin",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_4 C6B0DFFE4F72588B27D027A415368BD8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=DBE99D1B4C800128556803A29FA8D370,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_10 6E42CDF54BC465939BB3A997C0116E8E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_13" NodePosX=2720 NodePosY=-1648 NodeGuid=7CEF1AEB4B7F63D6562E07BAEC9E6804 CustomProperties Pin (PinId=91DAD7694D23A6620A0853B20C039690,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_MacroInstance_0 CAADD35C46C95564750F4F92E7F58527,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=8B4C510641FF5ACAA0D7639A8ECDCDE0,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_14 F64828724F21CBBD0992759FB8D38512,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_14" NodePosX=3040 NodePosY=-1648 NodeGuid=644D5B434166BA7666CA42909F758A5E CustomProperties Pin (PinId=F64828724F21CBBD0992759FB8D38512,PinName="InputPin",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_13 8B4C510641FF5ACAA0D7639A8ECDCDE0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,) CustomProperties Pin (PinId=B6B8D69849BB206B2A0F3DB5CA259AAB,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_Effect_Fire.Blueprint_Effect_Fire_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_5 A32784844BE6740F3FE7F69737FDC850,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,) End Object

Click Compile and Save.





Select one of your Blueprint_FireEffect's from the Outliner, then from the Details panel navigate to the Tags variable, locate the FindActorTag field, open the drop-down menu, then select Delete to delete the tag variable.





We are intentionally leaving one of the fire effects without a tag in order to demonstrate the functionality.

Navigate to the Toolbar and Press Play (PIE).





You used the GetAllActorsofClass function from the Gameplay Statics Library, to get an Array of Actors of a specified Class. However, you can also filter the Array results based on different criteria to get specific Actors or a single Actor from the Array by using Tags on the Actor.

Begin by navigating to your Content Browser > C++ Classes folder, and double click your FireEffect Actor to open it's FireEffect.cpp file.





Inside the FireEffect constructor add the following code

Tags is an array that is a part of the Actor's class defaults, It can be used for grouping and categorizing.

Compile your code.

Open your BP_FireEffect, then in the Details panel, navigate to the Actor category and you will notice your Actor Tag has been created.





Navigate to your Content Browser > C++ Classes Folder, and double-click your FindingActorsCharacter to open its FindingActorsCharacter.cpp file.





In the OnFindActorPressed method implement the following:

Compile your Code.

Select one of your BP_FireEffect instances in the Level Viewport, then in the Details panel navigate to the Tags variable, locate the FindActorTag field and open the dropdown menu next to it to delete the variable.





Navigate to the Toolbar and click Play (PIE).





End Result

When pressing the numeric 1 key, you should notice all Bluprint_Fire_ Effect particles with the ActorsToFindTag are extinguished, while the fire effect without the tag remains.

When pressing the numeric 1 key, you should notice all BP_FireEffect particles with the FindActorsTag are extinguished, while the fire effect without the tag remains.

In your game projects, there may be times when the player character is destroyed through gameplay and you will want to respawn them back into the world.

In this How-To guide, you will learn how to set up a simple respawn system using the Third Person Template, for a single-player, non-replicated game. You will then be tasked with implementing functionality for the Game Mode class, which will respawn a third-person player character back into your Level.



Choose your implementation method:

Blueprints

C++

Project Setup

You will start by creating a new Third Person Template and setting up input mappings from the Project Settings. These input mappings will enable the respawn functionality that you will create for your Player Character.

Begin by creating a new Games > Third Person > Blueprint project named RespawnPlayer.



Navigate to Edit > Project Settings > Engine > Input, then under the Details panel's Bindings category, click Add (+) next to the Action Mappings variable to create a new Action Mapping named Restart.



Set the Restart Action Mapping key value to R.



Implementing the RespawnPlayerGameMode Class

In this example, the GameMode class is responsible for respawning the player character class when it is destroyed during gameplay. You will be tasked with implementing this functionality through the use of Event Dispatchers.

In the Content Browser, navigate to Content > ThirdPersonBP and double-click the ThirdPersonGameMode Blueprint to open its Class Defaults.



In the Class Defaults , click the Open Full Blueprint Editor link.



In the My Blueprint panel, navigate to the Event Dispatchers category and click Add (+) to create a new Event Dispatcher named OnPlayerDied.



Navigate to the Details panel, then under the Inputs category click Add (+) to create a New Input Parameter of Blueprint class type Character, then name it Character.



Right-click the Event Graph to bring up the Actions menu, then search for and select Event BeginPlay.



From the Begin Play Node, drag from of the execution pin, then from the Actions menu, search for and select the Bind Event On Player Died node.



Drag off the Event pin from the Bind Event to On Player Died node, then from the Actions menu, search for and select Add Custom Event, and name this custom event PlayerDied.



You have created and bound an Event to a Custom Event with the intention of calling it from another Blueprint.

This causes the Event in this Blueprint to trigger when the Event occurs within another Blueprint, such as the OnDestroy Event from the ThirdPersonCharacter Blueprint class. This is called an Event Dispatcher.

For additional documentation, refer to Event Dispatchers and Event Dispatchers QuickStart.

From the PlayerDied Custom Event node, drag from the Character pin, and from the Actions dropdown menu search for and select the Get Controller node.



From the PlayerDied node, drag from the execution pin, then from the Actions menu, search for and select the Restart Player function.



Drag from the Return Value output pin from the Get Controller node, and connect it into the New Player input pin of the RestartPlayer node.



RestartPlayer is a method that already exists within the GameModeBase class. It tries to spawn the player's Pawn at the location returned by FindPlayerStart.

Click Compile and Save.



Finished Blueprint



Implementing the RespawnPlayerCharacter Class

You will now be implementing the logic to destroy the RespawnPlayerCharacter and call the GameMode's RestartPlayer method.

From the Content Browser navigate to Content > ThirdPersonBP and double-click the ThirdPersonCharacter to open its Class Defaults.



From the My Blueprint panel, Navigate to the Functions category and click the Override button. Then, from the dropdown menu select the Destroyed Override Function.



When selecting the Override button from the Functions category, each function lists the class from which the Character inherits its override. A Destroyed event is listed because the Character class inherits from the Actor class, which contains its own Destroyed function.

Drag from the Event Destroyed execution pin and from the Actions menu, search for and select Cast to Third Person Game Mode.



From the Cast to Third Person Game Mode node, drag from the Object pin, then search for and select the Get Game Mode node.



From the Third Person Game Mode node, drag from the As Third Person Game mode pin, then search for and select the Call On Player Died event dispatcher.



From the Call On Player Died node, drag from the Character pin and from the Actions menu search for and select Get a reference to self.



From the My Blueprint tab, navigate to the Functions category and click the Add (+) button to create a new function named Call Restart Player.



Double-click Call Restart Player, then navigate to the Local Variables category and click the Add (+) button to create a new local variable of type Controller, named ControllerRef.



Drag the ControllerRef variable onto the Execution pin of the Call Restart Player node.



Drag from the ControllerRef pin, and from the Actions menu, search for and select Get Controller from the Pawn category.



Navigate back to the Set ControllerRef node, then drag from the execution pin and from the Actions menu search for and select DestroyActor.



From the Destroy Actor node, drag from the execution pin, then from the Actions menu, search for and select Cast to Third Person Game Mode.



From the Cast to Third Person Game Mode node, drag from the Object pin, then search for and select the Get Game Mode node.



From the Third Person Game Mode node, drag from the As Third Person Game mode pin, then search for and select for RestartPlayer.



From the My Blueprint panel, navigate to the Local Variables category, then drag a copy of your ControllerRef onto the New Player pin from the Restart Player node.



Click Compile and Save.



Your completed Call Restart Player function will appear as it does below.



Navigate back to the Event Graph, then right-click, search for, and select the Restart Input Action Event.



Drag off of the Pressed key pin, then from the Actions menu, search for and select Call Restart Player.



The Call Restart Player function will destroy your player character and is triggered when the R key is pressed. The Destroy method will usually be triggered when the player loses enough health from a Gameplay event that would despawn your player.

Click Compile and Save



Finished Blueprint



End Result

Navigate back to the editor and click Play in Editor (PIE).

You can control your character's movement around the map by using the W, A, S, D keys.

When you press the R key your player character will disappear momentarily, then respawn at the Player Start Location.



Project Setup

You will start by creating a new Third Person Template and setting up input mappings from the Project Settings. These input mappings will enable the respawn functionality that you will create for your Player Character.

Begin by creating a new Games > Third Person > C++ project named RespawnPlayer.



Navigate to Edit > Project Settings >Engine > Input, then from the Details panel's Bindings category, click the Add (+) button next to the Action Mappings variable to create a new Action Mapping named Restart.



Set the Restart Action Mapping key value to R.



Implementing the RespawnPlayerGameMode Class

In this example, the GameMode class is responsible for respawning the player character class when the player character is destroyed during gameplay. You will be tasked with implementing this functionality through the use of Delegates.

From the Content Browser, navigate to your C++ Classes folder and double-click the RespawnPlayerGameMode to open its RespawnPlayerGameMode.h.



Inside the RespawnPlayerGameMode.h file, declare the following code under your library include declarations

This action creates a Dynamic Multicast delegate FOnPlayerDiedSignature for your Game mode class to bind when your Player Character dies.

Next, declare the following class declarations:

RestartPlayer is a method that already exists within the GameModeBase class. It tries to spawn the player's Pawn at the location returned by FindPlayerStart.

Navigate to your RespawnPlayerGameMode.cpp file and implement the following class methods

Compile your code.

Finished Code

RespawnPlayerGameMode.h

RespawnPlayerGameMode.cpp

Implementing the RespawnPlayerCharacter

You will now be tasked with implementing the logic used to destroy the RespawnPlayerCharacter, and implement respawn through the RespawnPlayerGameMode's class.

From the Content Browser, navigate to your C++ Classes folder and double-click the RespawnPlayerCharacter to open its RespawnPlayerCharacter.h file.



Inside the RespawnPlayerCharacter.h file, declare the following code:

In this declaration, the Destroyed method is marked with virtual because the Character class inherits from the Actor class, which contains its own destroyed method.

Navigate to your RespawnPlayerCharacter.cpp file, then declare the following class library include:

You will include the Gamemode library declaration to later call its class functionality from thePlayer Character class.

Next, add the following RespawnPlayerCharacter class methods.

The `CallRestart`Player function will Destroy the player character and is called when the **R** key is pressed. The **Destroy **method will usually be called when the player loses enough health from a Gameplay event that causes your player character to despawn.

Compile your code.

Finished Code

RespawnPlayerCharacter.h

RespawnPlayer.cpp

End Result

Navigate back to the editor and click Play in Editor (PIE).

You can control your character's movement around the map by using the W, A, S, D keys.

When you press the R key your player character will be destroyed and will disappear momentarily before respawning at the Player Start Location.



Saving A Game

Loading A Game

Choose your implementation method:

Blueprints

C++

The meaning of "saving the game" can vary considerably from one game to the next, but the general idea of enabling players to quit the game and then resume where they left off at a later time is a part of most modern games. Depending on what type of game you're making, you may only need a few basic pieces of information, such as the last checkpoint the player reached and maybe which items the player has found. Or you may need much more detailed information, possibly involving things like a long list of the player's social interactions with other in-game characters, or the current status of a variety of quests, mission objectives, or subplots. Unreal Engine 4 (UE4) features a saving and loading system that revolves around one or more custom SaveGame classes that you create to meet your game's specific needs, including all of the information that you need to preserve across multiple play sessions. The system supports the ability to have multiple saved game files, and to save different SaveGame classes to those files. This is useful for separating globally-unlocked features from playthrough-specific game data.

Saving A Game

Once you have created a SaveGame class, you can populate it with variables to store your game's data. For example, you might create an integer variable to store the player's score, or a string variable for the player's name. When you save the game, you will transfer that information from the current game world into a SaveGame object, and when loading a game, you will copy it from the SaveGame object to game object like Characters, the Player Controller, or the Game Mode.

On development platforms, saved game files use the .sav extension and appear in the project's Saved\SaveGames folder. On other platforms, particularly consoles, this varies to accommodate the specific file system.

Loading A Game

To load a saved game, you must provide the save slot name and user ID that you used when you saved it. If the SaveGame you specified exists, the Engine will populate your SaveGame object with the data it contains and return it as a base SaveGame (class USaveGame) object. You can then cast that object back to your custom SaveGame class and access the data. Depending on what kind of data your SaveGame type contains, you may want to keep a copy of it, or simply use the data and discard the object.

As with saving, you can load synchronously or asynchronously. If you have a large amount of data, or wish to use a loading screen or animation during load time, we recommend the asychronous method. For small amounts of data that load quickly, a synchronous method exists.

Implementation Guide

If you want to switch between multiple Playable Characters in your game or you have a situation where you want a Character to enter and control a Vehicle (car, plane, tank, etc.) or other Pawn that has unique controls (like a mounted machine gun a player can control), you will want to take Possession of the Character or Pawn in order to pass input information to it.

The PlayerController is what is responsible for directing a Pawn and Possession of a Pawn requires a PlayerController to be specified. Pawns themselves do not need to be a humanoid character and can be anything that you want to apply basic movement to and allow a player to control. Characters on the other hand are a form of Pawn that includes Collision and a CharacterMovementComponent by default which allows it to do basic human-like movement.

Implementation Guide

Learn how to use the Possess and UnPossess Blueprint nodes to take control of and provide input to a Pawn or Character in your project.

For the purposes of this guide we are using the Blueprint Side Scroller template, however you can use your own project if you would like. If you do not know how to create projects or use templates, refer to the Project Browser page for more information.

Steps

From the Content Browser, drag-and-drop into your level the additional characters you would like to control.



Here we added two additional SideScrollerCharacter Blueprints from the Content > SideScrollerBP > Blueprints folder to the level giving us a total of three characters in our level. With this particular template project, a character is already placed inside the level by default.

In the World Outliner, select each of the characters you want to control.



From the Main Toolbar, click the Blueprints button and Open Level Blueprint.



Right-click in the graph area, then select Create References to selected Actors option from the context menu.



This will allow us to reference each of the characters that we've selected in the level.

Right-click in the graph area, then search for the 1 Keyboard Event and select it.



This will allow us to fire off an event whenever the 1 key is pressed or released.

Add the 2 and 3 Keyboard Events to the graph.

Right-click in the graph and search for and add the Get Player Controller node.



The Player Controller is used to take the input from a human player and translate that into actions for a Pawn.

Left-click and drag off the Return Value of the Get Player Controller node and search for and add the Possess node.



This will tell the Player Controller which target Pawn to possess and take control of. When the Possess function is called, it will automatically check if a Pawn is currently controlled and UnPossess it first before attempting to Possess a new Pawn.

You can use the UnPossess function if you want to have the player release control of their Pawn and enter, say for example, a spectator type of state where they are not directly controlling a playable character.

Create two more Possess nodes and connect the 1, 2 and 3 Keyboard Events as shown below.



We are now set up to possess a Pawn when 1, 2 or 3 is pressed. Next we need to define which Pawn to possess from our references.

Connect each of the SideScrollerCharacter references to each of the In Pawn pins as shown below.



Our scripted functionality is complete and we are ready to test it.

Click Compile from the toolbar to update your script.



Click Play from the toolbar to play the game in the editor.



End Result

When you press 1, 2 or 3 on your keyboard you will switch between each of the characters in your level.

Implementation Guide

The GameMode defines the game's set of rules. The rules can include how players join the game, game pausing, and level transition, as well as any game-specific behavior such as win conditions. The GameMode is set for each level, and GameModes can be reused in multiple levels.

Implementation Guide

Implementation Guide

This guide covers how to create a GameMode Blueprint and set default values for it, how to assign a Default GameMode for your game, and how to override the Default GameMode through the World Settings and GameMode Override option.

Creating a Game Mode Blueprint

The steps below will guide you in creating and setting up defaults for a Game Mode Blueprint.

For this example, we are using the Blueprint Third Person Template; however you can use any project you wish.

In the Content Browser, click the Add New button.



Select Blueprint Class from the Create Basic Asset section of the dropdown menu.



You can create several different types of Blueprint Assets from the Blueprints option under Create Advanced Asset.

Choose a Parent Class for your Blueprint Asset. See Parent Classes for more information.



In the Pick Parent Class window, select the Game Mode Base Class. This is the parent class for all Game Modes.

Editing the Game Mode Defaults

Double-click on the Blueprint to open it, click the Class Defaults button to open the Blueprint Defaults in the Details panel.

Under the Game Mode are several options that you can set as the game's default settings (default character, HUD, etc.).



Here we are assigning the Character Blueprint called ThirdPersonCharacter as the Default Pawn Class for players to use in the game.

The Game Mode Blueprint points to existing Blueprints of the Character, HUD, PlayerController, Spectator, and Game State Classes. You will need to create these separately then specify them for use in the Game Mode Blueprint in order to actually use them in your game.

Assigning a Default Game Mode

In the previous section, we created a Game Mode Blueprint. Once you have a Game Mode Blueprint, you can assign it as the Default Game Mode to use in your game. The steps below will guide you through assigning the Default Game Mode through the Project Settings option.

From the Main Editor Window, click the Edit button from the Menu Bar, then select Project Settings.



In the Project Settings window, click the Maps & Modes option.



In Maps & Modes under Default Modes, click the Default GameMode drop-down box and assign the GameMode you wish to use.



This will assign the GameMode you select as the Default Game Mode whenever the project is loaded.

If you click the arrow next to Selected GameMode, you will see the current settings used by the assigned GameMode.



Here we can see that ThirdPersonCharacter is being used as the Default Pawn Class.

Overriding the Default Game Mode

When you have a Default Game Mode assigned, you can overwrite it on a per level basis through the World Settings menu under the GameMode Override section. The steps below will show you how to override the default Game Mode.

From the Main Editor Window, click the World Settings button from the Main Toolbar.



This will open the World Settings option which will appear in the bottom right window where the Details tab is located.

Inside the World Settings, under Game Mode, you can click the GameMode Override drop-down box to change the GameMode used.



Implementation Guide

Steps

If you are creating a game that involves any kind of damage to a player, enemy, or object, chances are you will run into the situation where you need to determine if they were hit by something and if so, who hit them, where the impact point was, or other information regarding the hit detected. The OnHit Event will provide this information and much more when the collision occurs in which you can use the data to drive changes in your game be it affecting health, destroying an object, or other gameplay related actions.

Implementation Guide

In this guide we will use the OnComponentHit and Event Hit Events to apply damage to and fracture a Destructible Mesh as well as apply an impulse at the hit location to push the destructible, simulating the effects of being hit by a projectile and applying force at the hit location.

Steps

For this How To, we are using the Blueprint First Person Template project with Starter Content enabled.

In your project in the Content Browser, go to the Content/Geometry/Meshes folder.

Right-click on 1M_Cube Static Mesh and select Create Destructible Mesh.



We are creating a Destructible Mesh out of this Static Mesh so that when it is shot, we can fracture it causing it to break apart.

Inside the Destructible Mesh Editor, click the Fracture Mesh button then Save and close the window.



Right-click on the newly created Destructible Mesh asset, then under Asset Actions, select Create Blueprint Using This...



Be sure to choose a save location and name for the new Blueprint created.

Inside the Blueprint Editor for the new Blueprint, in the Components window select the Destructible component.

In the Details panel, under Physics, check the Simulate Physics checkbox.



This Blueprint will now simulate physics.

Also in the Details panel, at the bottom under Events, click the OnComponentHit Event.



This will add a new node to and open the Event Graph.



Left-click and drag off the Other Actor pin and search for and add the Cast To FirstPersonProjectile node.



Here we are casting to another Blueprint called the FirstPersonProjectile Blueprint and making sure that when we hit the Destructible Mesh, that it is in fact the FirstPersonProjectile Blueprint that hit it. If it is, then we can apply additional script to fracture the mesh, breaking it apart. If it is not, we will not do anything.

Drag off the Hit pin and add a Break Hit Result node.



The Break Hit Result node gives us access to all sorts of information about the resulting hit and its information.

Drag off the Hit Actor pin from the Break Hit Result and add the Apply Point Damage node.

On the Apply Point Damage node, set the Base Damage to 100 and set the Damage Type Class to Damage Type.



The Apply Point Damage node allows us to not only specify the amount of damage to cause, but the location at which the damage was inflicted.

On the Apply Point Damage node, connect the remaining wires as shown below.



With all wires connected, your graph should look similar to above.

Compile and Save then, close the Blueprint.

Drag the Blueprint into the level from the Content Browser.



Click Play to play in the editor and use the Left-mouse button to fire a projectile at the cube.

When you play in the editor, you will see that when you hit the cube with the projectile that is fired it causes the cube to take damage and break apart as well as applies an impulse at the location in which it was hit causing it to fly in that direction. The amount of force that is applied is defined inside the FirstPersonProjectile Blueprint which uses the Event Hit node to determine when the projectile actually hits something.

In the Content/FirstPersonBP/Blueprints folder, open the FirstPersonProjectile Blueprint.



Click the image for a larger view.

The script in this Blueprint, checks to see if the object that is hit is simulating physics (which we set to true on our cube Blueprint). If it is, it then applies an Impulse at the location it hits (the amount is defined inside the green box which we have reduced to 50). You can adjust this value to increase/decrease the amount of impulse applied when a hit occurs.

Upgrading your Project to Unreal Engine 5

Experimenting with Large Worlds

Upgrading your Project to Unreal Engine 5

Blueprints

Source Code Interface

Exposing UFUNCTION Property Specifiers Expecting Float Values

Rendering

Shaders

Niagara

Chaos

Large World Coordinates (LWC) introduces support for double-precision data variant types in Unreal Engine 5(UE5) where extensive changes are being implemented across all engine systems to improve floating-point precision. These systems include Architectural Visualization, Simulation, Rendering (Niagara and HLSL code), and projects with massive world scale.

In Unreal Engine 4(UE4), 32-bit float precision types would restrict the size of the world. LWC vastly improves the size of your projects by providing a 64-bit double to your core data types. These new changes will enable you to build massive worlds and greatly improve Actor placement accuracy and orientation precision. Large World Coordinates are ready for you to use when you begin a new project in UE5.

Upgrading your Project to Unreal Engine 5

When upgrading your UE4 project to an UE5, We generally recommend you refer to the Migration Guide, as you may experience a few edge cases where your code base experiences precision loss. This is not as much of a cause of concern for projects that are not using Large World Coordinates. However, for projects that plan to use the double type to increase the scale of their worlds, we recommend you use the Large World Coordinates Conversion Guidelines.

Experimenting with Large Worlds

As a result of the beta status of Large World Coordinates in UE5, the default WORLD_MAX size has been left at the UE4 WORLD_MAX size of 21km and the engine check on the world bounds remains enabled. There are two options for experimenting with the scale of your large worlds:

You can disable the bounds checks by accessing your WorldSettings class and setting your bEnableLargeWorlds boolean to true:

This will keep the value of WORLD_MAX at approximately 21 km and provides improved stability for experimentation in the initial release of Unreal Engine 5.0.

Alternatively, you can set the global value of UE_USE_UE4_WORLD_MAX to enable larger world bounds:

This will set the WORLD_MAX value to approximately 88 million km.

This value may change before future releases of Unreal Engine and may exhibit stability issues that will continually be optimized throughout the development of Unreal Engine 5.

Upgrading your Project to Unreal Engine 5

When upgrading your UE4 project to a UE5, We generally recommend you refer to the Migration Guide, as you may experience a few edge cases where your code base experiences precision loss. This is not as much of a cause of concern for projects that are not using Large World Coordinates. However, for projects that plan to use the double type to increase the scale of their worlds, we recommend you use the Large World Coordinates Conversion Guidelines.

Blueprints

In Blueprints, floats now display with the appropriate single or double precision subtype. This new type supports feature parity with both float and double. All existing Blueprints and Blueprint types (UMG, Control Rig, Animation Blueprints) have been implicitly converted to use either precision type without any need for you to update your previous work.

Source Code Interface

Source code may now expose both float and double types. The Unreal Header Tool(UHT) will interpret any Blueprint-accessible floating-point type in code as a Blueprint Float with the appropriate single (C++ float) or double (C++ double) precision subtype, enabling automatic conversion of Float values of either precision supplied by any Blueprint node.

Exposing UFUNCTION Property Specifiers Expecting Float Values

Any method marked with a UFUNCTION Property Specifier that contains a float data value risks introducing imprecision, because the Blueprint Float value is cast to the lower precision float. It is important to audit any existing UFUNCTION property. This helps to determine if switching the parameters or return values to double may be necessary to avoid precision issues in the future. Switching between float and double types is safe to do at any time, and in either direction.

This applies to any K2 nodes that you may have constructed or exposed in code.

Rendering

In Unreal Engine you have various coordinate spaces and transformations that describe how an object can exist in the world. World space(coordinates of your level / world) and Local space(relative to a specific object), for additional information refer to the Coordinate Space Terminology documentation.

Each object that can be placed in your project's world has a three coordinate axis, an orientation, and an origin. Refer to Transforming Actors for additional information.

Shaders

New HLSL types have been introduced along with Large World Coordinates and can be found in the LargeWorldCoordinates.ush file. Refer to the LWC Rendering Doc for additional information on how to convert your shader code to UE5.

Niagara

In Niagara, the implementation is different from the main engine. To keep particle effects performant, the data is stored as a set of floats instead of using doubles. A sufficiently large world will be divided into grid cells. The first float then defines the Niagara system in that grid cell, and the second represents which grid cell the system is in.

To accommodate this additional information, there is a new data type called Position for storing the vectors referenced by Particles.Position. Refer to the Large World Coordinates in Niagara document for additional information.

Chaos

Chaos Destruction Physics continues to function unabridged using the double type. The engine implicitly casts in both directions, for example:

With further release versions of Unreal Engine 5, the FVector casts will continue to implicitly upgrade your floats to double. If you want to cast your double to a float, then you will need to explicitly perform a conversion. Refer to the Large World Coordinates Conversion Guidelines for additional information.



This document serves as a guide to convert your UE4 Projects to UE5 with minimal precision loss.



An overview of Rendering Large World Coordinates.

Modified Aliased Types

FMath Support for Doubles

Experimenting with Large Worlds

Forward Declaration of Variant Types

Error: C2027/C2371

Warnings: "Arguments cause function resolution ambiguity"

Converting Between Float and Double Variant Types Requires Explicit Casting

Shader Parameters

Runtime Check Failures

Enable Unsafe Typecast Warnings

By Module

By Single File or Code Block

Ensure No Loss of Precision When Storing A Copy of Type Components.

Bulk Serialization of Variant Types

Reduced Memory Consumption of Core Types

Blueprints

Source Code Interface

Exposing UFUNCTION Property Specifiers Expecting Float Values

Full World Space Plugins

World Space Origin Only Plugins

Supporting both UE4 and UE5

Large World Coordinates (LWC) is designed to slot into your existing project seamlessly. You can import your project into Unreal Engine 5 and follow this guide for conversion, however, it is possible that a limited set of issues may arise. In source code, variant types have a typedef alias that will default to the double type which matches the original Unreal Engine 4(UE4) name. Your existing code will be recompiled to support doubles automatically.

Modified Aliased Types

For compatibility in the future, we recommend you use the FVector alias wherever possible, only falling back to the explicit FVector3f or FVector3d types where you absolutely need to ensure a particular type.

The table below displays the following types that have been converted to variants:

Default (Double Variant Alias)

Float Variant

Double Variant

FVector

FVector3f

FVector3d

FVector2D

FVector2f

FVector2d

FVector4

FVector4f

FVector4d

FMatrix (FScaleMatrix,FQuatRotationTranslationMatrix, and more.)

FMatrix44f

FMatrix44d

FPlane

FPlane4f

FPlane4d

FQuat

FQuat4f

FQuat4d

FRotator

FRotator3f

FRotator3d

FTransform

FTransform3f

FTransform3d

FBox

FBox3f

FBox3d

FBox2D

FBox2f

FBox2d

FSphere

FSphere3f

FSphere3d

FBoxSphereBounds

FBoxSphereBounds3f

FBoxSphereBounds3d

FCapsuleShape

FCapsuleShape3f

FCapsuleShape3d

FDualQuat

FDualQuat4f

FDualQuat4d

FRay

FRay3f

FRay3d

To maintain compatibility in the future we do not recommend using the variant types unless absolutely necessary. Instead, you should use the original versions listed in the alias above, and only use the explicit float and double types in instances where you need to ensure a particular type.

If you want to cast between variants, then you must do this explicitly. For example:

FMath Support for Doubles

FMath functionality has been extended to support doubles. This includes support for standard mathematical operations on the new types.

This includes vectorization support from the VectorRegister located in the UnrealMathSSE.h/UnrealMathNeon.h directory which adds VectorRegister4f and VectorRegister4d types.

Experimenting with Large Worlds

As a result of the beta status of Large Worlds in UE5, the default WORLD_MAX size has been left at the UE4 WORLD_MAX size of 21km and the engine check on the world bounds remains enabled. There are two options for experimenting with the scale of your large worlds:

You can disable the bounds checks by accessing your WorldSettings class and setting your bEnableLargeWorlds boolean to true:

This will keep the value of WORLD_MAX at approximately 21 km and provides improved stability for experimentation in the initial release of Unreal Engine 5.0.

Alternatively, you can set the global value of UE_USE_UE4_WORLD_MAX to enable larger world bounds:

This will set the WORLD_MAX value to approximately 88 million km.

This value may change before future releases of Unreal Engine and may exhibit stability issues that will continually be optimized throughout the development of Unreal Engine 5.

Code Compile Errors

Below you will find several categories of compilation errors and their suggested solutions.

Forward Declaration of Variant Types

When writing forward declaration statements you should use the macro UE_DECLARE_LWC_TYPE.

For example instead of:

FVector should be declared as:

Please refer to Engine/Source/Runtime/Core/Public/CoreFwd.h for examples of proper UE_DECLARE_LWC_TYPE usage per type.



Forward declaration of variant types is unnecessary for any file that includes a generated.h, or CoreMinimal.h.



Error: C2027/C2371

If your project is generating C2027/C2371 errors for an FVector or other variant type, then a forward declaration of that type as a struct within your code is the most likely cause.

Warnings: "Arguments cause function resolution ambiguity"

You may observe warnings similar to the one above if you're calling multi-argument FMath functions that contain a mix of variant type, floating-point, or constant arguments.

It is important that you do not ignore function resolution ambiguity warnings as they may be indicating an underlying loss of precision occurring in your program.

You can correct precision errors by passing explicit template arguments, casting mismatched types, or modifying constants to match the desired type.

For example:

Converting Between Float and Double Variant Types Requires Explicit Casting

Converting between float and double variant types in code requires explicit casting to avoid unintended precision or performance issues.

As an example, you may need to account for this behavior when passing an FVector3f into a function that requires a FVector4. The FVector3f should be cast to the FVector, this enables the implicit cast from an FVector to an FVector4 to complete the conversion.

Explicit casting applies to similar types in internal systems. For example, a Chaos FVec3 to an FVector3f.

Shader Parameters

We do not support double parameters on the GPU. As such, FVector, FVector2D, FVector4, and FMatrix are no longer supported within SHADER_PARAMETER declarations in native code, and will need to be switched to the float variant of the corresponding type.

Runtime Check Failures

You may encounter runtime check failures such as:

Unexpected element array size in TArray::BulkSerialize

These can be a result of bulk serializing a struct that contains a type that was automatically converted to a double variant. This can be fixed by adding a bForcePerElementSerialization parameter based on the archive version:

We recommend you ensure your archive has an up-to-date version.

Precision Issues

The conversion of LWC type components to a double type can introduce precision issues in your converted UE4 projects, particularly if your code is written with the expectation of these components being floats. We recommend you audit your code for these issues after upgrading.

Enable Unsafe Typecast Warnings

Below you will find several methods available to enable your project to receive unsafe typecast warnings.

By Module

You can add the following to your project's build.cs file:

While this may generate a considerable number of warnings in a large codebase, it is invaluable for detecting and fixing situations that may lead to a loss of precision.

Some Engine header files will generate unsafe typecast warnings at present. These will be fixed in a future release.

By Single File or Code Block

The following macros enable toggling of unsafe typecast warnings:

Macro

Description

PRAGMA_FORCE_UNSAFE_TYPECAST_WARNINGS

Unsafe typecasts will generate errors past this point regardless of module settings.

PRAGMA_DISABLE_UNSAFE_TYPECAST_WARNINGS

Unsafe typecasts will be ignored past this point regardless of module settings.

PRAGMA_RESTORE_UNSAFE_TYPECAST_WARNINGS

End marker for FORCE/DISABLE block. Behavior reverts to module settings. The CheckBalancedMacros automation script will fail if blocks are not closed correctly.

Ensure No Loss of Precision When Storing A Copy of Type Components.

Code which accesses Type Components directly may require some refactoring to avoid precision loss. Precision errors can lead to invalid code execution, for example:

For a precise double value of MyVector.X, the difference between the X and the OtherVector.X delta can be significant enough to cause the code to follow this path.

For a project that plans to expand beyond the older UE4 float limitations of a 10.5KM bounds, this becomes increasingly dangerous as you move further out from the origin:

If you are planning to make use of large world coordinates in your converted project, then you need to audit your codebase for these precision errors.

LWC types expose an FReal alias to their underlying component type (float or double). Using an FReal in place of the fundamental types will ensure you avoid precision issues, even if these types should change in the future, for example:

A refined approach would be to update your float types to double across your codebase:

Code that accesses type components directly may require refactoring to avoid precision loss.

A converted UE4 project that intends to stay within the float bounds (~10.5KM from the origin) may experience a precision loss, however it may not negatively affect your project.

Bulk Serialization of Variant Types

By default, bulk serialization of arrays of default core types(FVector) is disabled for converted projects. The engine is required to load each vector component as a float, then convert it to a double. When an affected asset is re-saved, it is written as a double, and bulk serialization will function again. if you are bulk serializing structs containing a variant type, then you will need to convert it to use the float variant, or force a per-instance serialization in the BulkSerialize call / disable TCanBulkSerialize support.

Reduced Memory Consumption of Core Types

Serialized Core types that are marked with Property Specifiers will automatically recognize a switch between the double and float variants, providing you the ability to retroactively reclaim wasted memory by switching to the float variant at any time.

Blueprints

In UE5, all Blueprint Float types are represented by a modified Float type which is capable of working at both single and double precision. This means your Blueprints will automatically support LWC scales. Any float or double types in an imported UE4 blueprint project are promoted to the new type, as a result of removing explicit float / double support in Blueprints.

Source Code Interface

Source code may now expose both float and double types. The Unreal Header Tool(UHT) will interpret any Blueprint-accessible floating-point type in code as a Blueprint Float with the appropriate single (C++ float) or double (C++ double) precision subtype, enabling automatic conversion of Float values of either precision supplied by any Blueprint node. We recommend caution when using floating-point terminology.

A float in Blueprints can refer to either a single-precision or double-precision float. However, In C++ you need to be explicit about what you want. The term "float" specifically refers to a single precision float, whereas a "double" refers to a double precision float. The Unreal Header Tool recognizes both types as valid for Properties or Function Parameters. If the type is a "float" or "double", Blueprint will treat either as a singular "Float" type, but will indicate whether the float is single or double precision.



From the perspective of a Blueprint user, there's no difference between a single or double precision type, these pins can be connected without any explicit cast nodes. Nonetheless, Unreal Engine may need to perform either a narrowing or widening conversion in these instances. The Blueprint compiler will automatically analyze a Blueprint graph for any potential floating-point conversions. If any are detected, the compiler will automatically insert a cast operation into the underlying code. This works for containers as well.

Developers do not have to do any special fixes with their older Blueprint content to take advantage of Large World Coordinates. By default, Unreal Engine automatically converts float pins to use double precision. If any pins were used for single precision floats in native C++ code, then it ensures that those pins continue to represent single precision floats. This includes native C++ properties, function parameters, and the parameters of any Blueprint functions that are bound to native C++ delegates.

Exposing UFUNCTION Property Specifiers Expecting Float Values

Any method marked with a UFUNCTION Property Specifier that contains a float data value risks introducing imprecision, because the Blueprint Float value is cast to the lower precision float. It is important to audit any existing UFUNCTION property. This helps to determine if switching the parameters or return values to double may be necessary to avoid precision issues in the future. Switching between float and double types is safe to do at any time, and in either direction.

This applies to any K2 nodes that you may have constructed or exposed in code.

Plugins - Guidelines for Published Plugin Authors

When converting existing plugins to support Large Worlds, we advise you to be cautious to ensure your plugin avoids precision loss. We recommend using the general guidelines listed in the Precision Issues section to update your plugin core-type components.

Full World Space Plugins

Certain plugins may require conversion to full world space. This can be done by converting your underlying types to use doubles, although the engine will accommodate the majority of this process when you convert your plugin to UE5, you will need to ensure your code is not creating precision errors by storing results as floats.

For example: FVectors used to represent world coordinates in UE4 will already have been upgraded to use double precision types in UE5, however, if your plugin accesses core types at the component level, then some refactoring of your code may be required to ensure precision is maintained.

World Space Origin Only Plugins

Some plugins only need to work within a local float scale space, and can rely on the engine to render the results at a world space origin. In this case you may want to explore converting the core types used internally by your plugin to float variants to reclaim memory lost to doubles.

Supporting both UE4 and UE5

Plugins that target both engine versions need to be distributed as code to be compiled at source, or as separate binary packages. UE4 does not support core type variants, so you either need to ensure your UE5-compatible code uses only the default core types (compiling as floats in UE4, and as doubles in UE5), or provide separate source code for UE4 and UE5 versions of the plugin.

To ensure the correct precision for intermediate calculations using core type components, they can be handled using either the auto c++ declaration, or doubles.

LWC Rendering Overview

New HLSL types were introduced along with Large World Coordinates and can be found in the LargeWorldCoordinates.ush file. Refer to the



Quick Porting Guide

Material Translator

LWC Rendering Overview

New HLSL types have been introduced along with Large World Coordinates and can be found in the LargeWorldCoordinates.ush file.

HLSL Type

Notes

FLWCScalar FLWCVector2/3/4

These types are similar to float1/2/3/4, however, they include an additional Tile coordinate. Therefore, a FLWCVector2 is made from a float2 Tile and a float2 Offset. The value represented is calculated by the formula: Tile * TileSize + Offset, where TileSize represents a constant value that is defined as 256k.

FLWCMatrix FLWCInverseMatrix

These types are similar to float4x4, however, they both include an additional float3 Tile coordinate.

FLWCMatrix

adds the Tile coordinate to the result after multiplying the matrix.

FLWCInverseMatrix

adds the Tile coordinate before multiplying the matrix.

FLWCMatrix

is used for transforms to world space (LocalToWorld).

FLWCInverseMatrix

is used for transforms from world space (WorldToLocal).

Operations such as LWCAdd or LWCRsqrt can be performed on these types. Operations that take LWC input values will return LWC outputs (LWCAdd), while others return regular float outputs (LWCRsqrt). This distinction is driven by your choice of implementation but operations that make coordinates smaller provide you with a return to regular floats.

Within the shader code, many types have been switched to LWC variants. Below is a list of some notable examples:

At a high level, LWC types are not included directly inside uniform buffers. Entities contain several pieces of data that can all use the same tile coordinate (WorldToLocal, LocalToWorld, AbsoluteWorldPosition). Therefore, the typical pattern is to store regular non-LWC values in the uniform buffer (RelativeWorldToLocal, LocalToRelativeWorld, RelativeWorldPosition) along with a single float3 TilePosition value.

Inside the shader, this uniform data is "unpacked" into a new struct type that includes the actual LWC values in which many values are initialized with the single TilePosition.

SceneData.ush, FPrimitiveSceneData, and FInstanceSceneData have various updated matrices and position vectors.

Global camera uniforms have various matrices and offsets changed (such as PreViewTranslation.) Previously, global camera uniforms were either accessed through ResolvedView when rendering meshes (which handles instanced stereo rendering), or View when rendering post-processing and other global passes.

In previous engine versions, View refers directly to the global uniform buffer, as a result we added a new alias PrimaryView which refers to the unpacked global view struct. Therefore, names such as View.PreViewTranslation changed to PrimaryView.PreViewTranslation. ResolvedView.PreViewTranslation continues to function where applicable and is valid to access non-LWC quantities from the regular View alias.

FNaniteView now matches updates to the camera uniforms.

Light positions and reflection capture positions have been switched over to the new LWC HLSL types.

Switching these global types provides a general indication of where your shader code needs to be refactored to support LWC. For example:

The initial LWC pass does not check to ensure that all shaders work correctly with LWC.

To accommodate them, you can use the global function LWCHackToFloat to convert a LWC type to a non-LWC type.

LWCHackToFloat behaves as a wrapper around the LWCToFloat function. The distinction between them is the LWCToFloat function is used when you know a conversion is safe at LWC-scale. LWCHackToFloat is a searchable marker. If you didn't have time to refactor your codebase from switching WorldPosition from float3 to FLWCVector3, you could instead use the following code:

TranslatedWorldSpace is an existing engine concept that is used in UE5 shaders. Previously, it was intended to increase precision by working relative to the Camera Origin. However, this behavior is useful for LWC because it is safe to use floats when working in TranslatedWorldSpace. Rather than convert WorldPosition to an LWC value, you can use a formula such as:

Quick Porting Guide

You can port your existing HLSL codebase into Unreal Engine 5. Below are some suggestions to ensure a successful conversion.

Change View to PrimaryView when accessing values/matrices in the world space (LocalToWorld, PreViewTranslation),

If your code performing in world space doesn't compile (if it is missing function overloads or type conversions), and you do not have the resources to refactor your codebase, you can use the LWCHackToFloat function where needed, for example:

If your code still does not compile:

Consider changing the shader code to operate in TranslatedWorldSpace instead of WorldSpace.

World space values require LWC types (FLWCVector3 instead of float3). You may need to use the LWCAdd and LWCMin function.

Any new code you develop should follow the guidelines listed above to use TranslatedWorldSpace whenever possible, otherwise we recommend you use the LWC types.

Material Translator

The Material Translator has been updated to work with LWC values. Material nodes will output LWC values instead of floats when querying the AbsoluteWorldPosition and transforming it to WorldSpace.

Materials will work at the LWC scale, however, this may come at a performance cost. Materials that you port can become more expensive, due to LWC operations that add more process calls.

1 - Required Project Setup

2 - Displaying Health, Energy & Ammo

3 - Further Reading

This Quick Start Guide shows you how to implement some basic in-game HUD elements using Unreal Motion Graphics UI Designer (UMG). Get familiar with example of the process of creating dynamic elements: health bar, energy bar, and counter of ammo. Also learn how to add them to the Viewport.

All actions are described step by step and in detail. However, if you have never worked with Unreal Engine, then it is recommended that you first familiarize yourself with the Level Designer Quick Start. Here you will find basic knowledge and terminology for working with UE. Also, this course contains links to more detailed information. Check them out if necessary.

1 - Required Project Setup

For this tutorial, use the Blueprint First Person template with Starter Content enabled.

Character appears unarmed at the start of game process. Ammo indication should appear in case Character take a weapon. For this reason, use two Widgets: HUD and HUD_AmmoCount. You should adjust HUD Widget to display health and energy of the Character from the start of game process, and HUD_AmmoCount Widget to display ammo in case taking a weapon.

Create Widget Blueprint. Click the Add New in the Content Browser, then select User Interface > Widget Blueprint. Name this widget HUD.



Use a Widget Blueprint to create and set up UI elements (HUD, Menus, and so on). With the help of this, you can visually layout UI elements and provide scripted functionality for it.

For more information on Widget Blueprints see Widget Blueprints in UMG.

Create three more Widget Blueprints, name it HUD_AmmoCount, MainMenu, PauseMenu.



Create new Level. Right-click in the Content Browser select Level. Name it Main.



You will use this later in the guide for Main Menu setup.

Adjusting BP_FirstPersonCharacter Blueprint

In the Content Browser, open the BP_FirstPersonCharacter Blueprint located under the Content/FirstPerson/Blueprints folder.



This is the Character Blueprint you control in the game. You should adjust it to construct HUD Widget and display it in a viewport.

In the Blueprint Editor window, click the Add Variable Button.



In the Details panel of this variable, select a Float variable type and input the name Health. Set the Default Value to 1.0.



You will use this variable for adjusting Health Bar of the character in the the HUD Widget.

Create another variable with Float type and name it Energy. Set the Default Value to 1.0.



You will use this variable for adjusting Energy Bar of the character in the the HUD Widget.

You should compile Blueprint by clicking the Compile button from the Tool Bar before input a Default Value.

Create another variable with Integer type and name it Ammo. Set the Default Value to 25.



Create one more variable with Integer type and name it MaxAmmo. Set the Default Value to 25.

Right-click inside the Graph window, add the Event Begin Play node, then add a Create Widget node. Set the Class to HUD Widget.



For the Return Value of the Create HUD Widget, select Promote to Variable and name it HUD Reference.



With the help of this, you create HUD Widget, when the game is started, and set it as a variable for later calls. This is usefull in case you need call some functions or set properties of the HUD Widget via Blueprint. For example, if you need hide the HUD, while the game is paused, you can access the HUD through this variable.

Add the Add to Viewport node to the out pin of the Set node.



With the help of this, you've added the HUD Widget to the viewport from start of game process.

Compile and Save the BP_FirstPersonCharacter Blueprint and close it.

Adjusting BP_Rifle Blueprint

The process of adjusting BP_Rifle Blueprint is similar to adjusting BP_FirstPersonCharacter Blueprint. In case you need more detail see section above Adjusting BP_FirstPersonCharacter Blueprint.

In the Content Browser, open the BP_Rifle Blueprint located under the Content/FirstPerson/Blueprints folder.



Find the On Component Begin Overlap (SphereCollision) node. Right-click on the execution pin and select Break All Pin Link(s).



Drag the execution pin of the On Component Begin Overlap (SphereCollision) node and add a Create Widget node. Set the Class to HUD_AmmoCount Widget.

For the Return Value of the Create HUD Widget, select Promote to Variable and name it HUD Ammo Count Ref.

Add the Add to Viewport node to the out pin of the Set node.

Connect the execution pin of the Add to Viewport node with the execution pin of the Cast to BP_FirstPersonCharacter node. Your script should look as following.



With the help of this, you've added the HUD_AmmoCount Widget to the viewport in case Character take a weapon.

Compile and Save the BP_Rifle Blueprint and close it.

Adjusting Character Variables in BP_FirstPersonCharacter Blueprint

In this chapter you can find information about the adjusting declaired variables and adding them to the Blueprint.

In the Blueprint Editor of the BP_FirstPersonCharacter, hold Alt and drag the Energy variable into Graph window and place it next to the Jump script.



Hold Ctrl and drag a copy of the Energy variable into Graph window. Add Substruct operator node, connect and set to 0.25 as shown below.



With the help of this script, every time the Character jumps, the Energy is reduced by 0.25 from current Energy value.

Set up the same script for the Health variable but use an F Key Event (or any other key press event) for testing.



With the help of this script, you will be able to test if Health is reduced by 0.25 from current value, every time you press F.

Compile and Save the BP_FirstPersonCharacter Blueprint and close it.

To add the ability to reload ammo do the following. Add the R Key Event. Hold Alt and drag the Ammo variable. Hold Ctrl and drag the Max Ammo variable. Connect it as shown in the image below.



Adjusting Character Variables in BP_Rifle Blueprint

Open BP_Rifle Blueprint. Find the OnFireProjectile Custom Event. Right-click on the execution pin and select Break All Pin Link(s).



Near this node, Right-click and add a Branch node.

Hold Ctrl and drag a copy of the FirstPersonCharacterReference variable into Graph window. Drag the pin and select Get Ammo.



Add Greater operator node, set to 0 and connect as shown below.



Character you play can fire if their ammo is greater than zero, due to this script.

At the end of the OnFireProjectile Custom Event script following the Montage Play node, hold Ctrl and drag a copy of the FirstPersonCharacterReference variable into Graph window. Drag the pin and select Get Ammo. Drag the pin again and select Set Ammo.



Add Substruct operator and set Ammo to equal Ammo - 1. Your script should look as following.



Every time Character you play fires it decreases ammo by one, due to this script.

Compile and Save the BP_Rifle Blueprint and close it.

2 - Displaying Health, Energy & Ammo

At this step you should set up the visualization of Health, Energy and Ammo variables in the Widgets and adjust connection with game process.

Visual: Health and Energy

To set up the visualization of HUD Widget do the following.

Open HUD Widget Blueprint to access the Widget Blueprint Editor. With the help of this, you can create the visual layout and scripted functionality of HUD Widget.



Click here for full view

For more information on the different facets of the Widget Blueprint Editor, see Widget Blueprints in UMG.

Find the Horizontal Box in the Palette panel under Panel and drag it onto the Canvas Panel in the Hierarchy panel.



Panel Widgets are like containers for other widgets. You can provide additional functionality for the widgets that are inside it.

Also under Panel, drag two Vertical Boxes onto the Horizontal Box.



Under Common, drag two Text widgets onto the first Vertical Box and two Progress Bars onto the second Vertical Box.



Select the Horizontal Box, find it in the Graph, resize the box and place it in the upper left corner of the window.



Select both Progress Bars, then in the Details panel set both to Fill under Size.



Select the Vertical Box containing the Progress Bars, then in the Details panel set both to Fill under Size as well.



Select the Horizontal Box again and resize it so the bars line up with the text.



Select the top-most Text widget in the Hierarchy panel, then in the Details panel under Content enter Health:.



Do the same for the other Text widget, but enter Energy:. It should look as following.



By default, UMG text widgets use a font from Unreal Engine. It allows you get started work in Unreal Engine quickly. However, this built-in font has some limitations. For example, it only supports a small set of languages. In most cases, it is necessary import custom fonts into Assets. For more details about setting up text widgets to use custom fonts see Creating and Assigning Fonts in Unreal Engine User Interface.

Select the Progress Bar next to Health, then in the Details panel set the Fill Color and Opacity to green color.



Progress Bar does not change color when assigning a color. This is because the Percent value to fill the bar is set to 0.0. You can change this to test out different colors. Later you will link this to the Health variable value of the Character.

Also set a Fill Color and Opacity for the Energy bar (For example, an orange color).

Your HUD Widget layout should look as following.



Compile and Save the HUD Widget Blueprint and close it.

Visual: Ammo

To set up the visualization of HUD_AmmoCount Widget do the following.

Open HUD_AmmoCount Widget Blueprint to access the Widget Blueprint Editor.

Use the same way to add widgets to the Hierarchy panel. Your structure of layout should look as following.



Select the Horizontal Box in the Graph, resize the box and place it in the upper right corner of the window.



Select the Horizontal Box, then in the Details panel click Anchors and select the upper-right Anchor.



With the help of this, you place the Anchor Medallion to the upper right corner of your screen.



You fix the Horizontal Box position regardless of screen size, due to the Anchors settings. The Widget stays the same distance from the Anchor Medallion when the screen is resized.

You can test different screen sizes by clicking and changing the Preview Size option inside the graph.

Compile and Save the HUD_AmmoCount Widget Blueprint and close it.

Script: Health and Energy

The next step is provide functionality for the HUD Widget elements.

Open HUD Widget Blueprint to access the Widget Blueprint Editor.

Click the Graph button in the upper right corner of the Widget Blueprint Editor window.



In the Graph under the Event Construct node, Right-click and add Get Player Character node.

Drag the Return Value pin of Get Player Character node and select Cast to BP_FirstPersonCharacter.



Drag the As BP First Person Character pin and select Promote to Variable (name it My Character), then connect as shown below.



With the help of this, you will be able to access the variables from BP_FirstPersonCharacter Blueprint.

Click Compile in the toolbar to compile the script.

Return to the Designer and select the Progress Bar next to Health.

In the Details panel under Progress, click the Bind option next to Percent and click Create Binding.



With the help of this, you can create custom bindings by adjusting function script in opened window.

Hold Ctrl and drag the copy of MyCharacter variable into the Graph.



Drag the pin MyCharacter and select Get Health.



Connect the Health pin to the Return Value of the Return Node. It should look as following.



Do the same procedure to adjust Progress Bar next to Energy. It should look as following.



Compile and Save the HUD Widget Blueprint and close it.

Script: Ammo and AmmoMax

Procedure of setting up Ammo variable is similar to setting Health and Energy variables. For more detailed information see section above Script: Health and Energy.

Open HUD_AmmoCount Widget Blueprint and go to Graph tab.

Create script for connection HUD_AmmoCount Widget Blueprint to BP_FirstPersonCharacter Blueprint as described before. This should look as following.



Click Compile in the toolbar to compile the script.

Return to the Designer and select the 25 text following the Ammo text. In the Details panel for Text, click Bind and Create Binding.



In opened window, hold Ctrl and drag the copy of MyCharacter variable into the Graph. Drag the pin MyCharacter and select Get Ammo. Connect the Ammo pin to the Return Value of the Return Node. It should look as following.



A conversion node To Text will be created automatically after connecting Ammo node to the Returned Node.

Repeat the process above for other 25 text and creating a binding for the "AmmoMax" text.



It is not necessary to do this if your max ammo is constant. However, with the help of this AmmoMax variable setting, you will be able to change it by creating a script in BP_FirstPersonCharacter.

Click Compile and Save, then click the Play button to play in the Editor.

With the help of this quide, you have adjusted displaying Health and Energy Bars via HUD Widget, and displaying Ammo via HUD_AmmoCount Widget. All these Widgets display current values from your Character Blueprint. In game process, the pressing Space cause the jump Character, reducing Energy; pressing F cause the reducing of the Health; the pressing Left Mouse Button cause fire the weapon, reducing Ammo.

In the next section, you will find the information on creating a Main Menu, which you can use to load into game you set up. Also, there is additional information on working with Unreal Motion Graphics and Blueprints.

3 - Further Reading

To continue to build on the HUD you created in this Quick Start guide, see the



As for coverage related to the topics in this guide:

For more information on Unreal Motion Graphics, see: UMG UI Designer.

For more information on Blueprints, see: Blueprints Visual Scripting.



Widget Blueprints

Media Framework

Components Window

Widget Component Property Reference

Widget Components allow you to manifest 3D UI elements created through Unreal Motion Graphics in your game world. The Widget Component itself is a 3D instance of a Widget Blueprint that you can interact with in your game world. Once you place the Actor that contains the WidgetComponent in your level, the Widget Class Blueprint is displayed in the world.



Widget Component Property Reference

Here are the properties that can be adjusted via the Details panel for the Widget Component.

Option

Description

Space

The coordinate space in which to render the widget (World or Screen). With World the widget is rendered in the world as a mesh while and can be occluded while Screen renders the widget on the screen completely outside of the world and is never occluded.

Widget Class

The class of User Widget to create and display an instance of.

Draw Size

The size of the displayed quad.

Manually Redraw

Should the Widget wait to be told to redraw to actually draw or not.

Redraw Time

The time in between draws, if 0 - redraw every frame. If 1, we would redraw every second. This will work with the Manually Redraw as well. So you can say, manually redraw, but only redraw at this maximum rate.

Window Focusable

Is the virtual window created to host the widget focusable? Should this take focus from the user.

Draw at Desired Size

Causes the render target to automatically match the desired size specified by the Widget Class. Expensive if is done every frame.

Pivot

The Alignment/Pivot point that the widget is placed at relative to the position.

Widget Blueprint Editor

At first, you should create a Widget Blueprint, as shown below. With the help of this, you will be able to start working with Unreal Motion Graphics (UMG).

Create Widget Blueprint. Click the Add in the Content Browser, then select User Interface > Widget Blueprint.



You can also Right-click in the Content Browser instead of clicking the Add button.

You can rename or use the default name for the Widget Blueprint you created in the Content Browser.



Double-click the created Widget Blueprint to open it in the Widget Blueprint Editor.



Click image for full view.

Widget Blueprint Editor

The Designer tab is tab by default in the opened Widget Blueprint Editor. With the help of available editor tools, you can customize the appearance of the UI. Also, you can get the visual preview of the in-game screen, due to layout you adjust.



Click for full view.

Number

Window

Description

1

Menu Bar

It contains the common menu options.

2

Tool Bar

It contains a number of commonly used functions for the Blueprint Editor, such as Compile, Save, Browse, Play, and so on.

3

Editor Mode

It switches the Blueprint Editor between Designer and Graph modes.

4

Palette

It contains the list of widgets, that you can drag into the Visual Designer window. Displays any class inheriting from UWidget.

5

Hierarchy

It displays the structure of the User Widget. You can also drag widgets from Palette panel into this panel.

6

Visual Designer

It is the visual representation of the UI layout. Also, you can manipulate widgets you dragged into the Visual Designer.

7

Details

It displays the properties of the selected widget. You can adjust them via this panel.

8

Animations

This is the animation track for UMG which allows you to keyframe animations for your widgets.

The Visual Designer window by default is 1:1 scale. You can change the scale by holding Ctrl and using Mouse-Wheel.

The Graph tab of the Widget Blueprint Editor looks as following.



Click for full view.

The Graph tab has similar functions to the Designer tab of the Blueprint Editor. For more information on the basic functionality of the Graph tab see Blueprint Editor Graph Editor.

Set Input Mode and Show Cursor

Adding Widgets to Widgets

Once you have created and laid out your Widget Blueprint, in order for it to be displayed in-game, you will need call it by using the Create Widget and Add to Viewport nodes inside another Blueprint (Level Blueprint or a Character Blueprint for example).



In the example above, the Create Widget node is calling the Widget Blueprint specified under the Class section and the Return Value is the resulting product (Owning Player is the Player Controller and is applied to blank results in the default Player Controller). The Add to Viewport is what draws the Widget Blueprint onscreen and we are specifying that the Main Menu variable, which holds the created Widget, is the added Target.

Additionally, the Return Value is being assigned to a variable titled Main Menu, which allows us to access the Widget Blueprint later instead of re-creating the Widget and, if needed, to remove the widget.

To remove the Widget from being displayed, use the Remove from Parent node and specify the Target Widget Blueprint.



Set Input Mode and Show Cursor

There may be instances when you want the player to interact with your UI and there may be instances when you want them to completely ignore it. There are some nodes that can be used to determine how the player interacts with the UI, which are of the Set Input Mode type as seen below.



The left node above, Set Input Mode Game and UI, does as the name implies and allows the player to manipulate the game via inputs as well as UI (for example, controlling a character onscreen but also having access to clicking on any buttons or UI elements you may have).

The center node above, Set Input Mode Game Only, enables input only for the game and ignores UI elements (this is perfect for non-interactive UI elements like Health, Points, or Time display).

The right node above, Set Input Mode UIOnly, is an edge case node and is used when you only want to allow for UI navigation only and no game input. This completely disables all game controls and UI consumes all input, so use this node sparingly.

To supplement the nodes above, you may want to Enable/Disable the Mouse Cursor from being displayed. You can do so by using the Set Show Mouse Cursor node. Drag off a Get Player Controller node, then use the Set Show Mouse Cursor node and check it to True or False to display or hide the Mouse Cursor.



Above, I is used to toggle between showing/hiding the Mouse Cursor.

Adding Widgets to Widgets

You can add widgets to other widgets by creating a Parent-Child relationship where the second widget is nested under the first widget. To do this, simply append the child widget to the parent widget. You do not need to use the Add to Viewport function.



The example above shows how a Scroll Box Widget called start_Button is appended to a new Widget called Main Menu using the Add Child function.

The Add Child node is for parenting one widget to another in a panel while the Add to Viewport adds the widget to the root viewport as if it is a new window. In order to remove a child widget, you need to get your Parent and call RemoveChild.

Target Resolution and Scale

Creating Art for UMG

Tips and Tricks

As you start to experiment with and create UI elements with Unreal Motion Graphics (UMG) you might ask yourself if you are doing things the most efficient way possible. While that largely depends on the scope of your project, this page will outline some of the things you may want to consider when setting up your UI.

For example, if you are creating a simplistic UI screen that has a handful of variables that are going to change frequently, you might consider using Property Bindings to drive those changes. However, if you have a more complex UI screen with several properties that are going to change at specific times, it might be better to use Event Based logic to perform those changes rather than checking them every frame to see if they should change.

Keep in mind that there are no "right" or "wrong" answers when it comes to creating content with UMG and you should go with what works best for you in your given situation. With that said, the topics covered on this page are things that you can consider when creating your content and then decide whether or not to implement them.

Target Resolution and Scale

When creating your content in UMG, have in mind the target resolution and build all your Widgets based off that resolution. For example if your target is 1080x1920, author each of your Widget Blueprints using this resolution setting inside UMG. You can set the working screen size from the ScreenSize drop-down menu.



Previewing what it will look like on other screen sizes is fine, but try to avoid building your screens on different screen sizes as that may lead to some things appearing to scale and some not appearing to scale. Speaking of scale, whenever you are creating content inside of UMG, try to create that content at a DPI Scale of 1.0.



You can see your current Screen Size and Scale on the Designer tab in the lower portion of the graph.

Not only will this ensure that everything you create appears at the same scale, it will make scaling to higher/lower screen sizes easier to perform if there is a unified scale applied to all your Widget Blueprints. Similar to working in different screen sizes, if you author one Widget Blueprint in one scale and another in a different scale when you go to scale them for different screen sizes, they might not scale as you expect.

Creating Art for UMG

Establishing a target resolution and scale is important before creating your art assets for UMG. If you create your assets without a resolution or scale in mind, you may have some textures that are bigger or smaller than they need to be. In either case you will need to make those assets conform to your UI and that may stretch or skew your textures leading to undesired effects.

As for your textures, try to minimize the amount of built-in padding in the imported texture.



This texture has quite a bit of padding around it making it difficult to get the true size of the window frame.

When using the texture above in a UI screen, if we were to try to rescale it for different screen sizes, the scale will be based on the size of the texture and not the window frame. If you need to add padding around an object, it�s better to use the padding options inside UMG to provide space around objects so that when you rescale things, they appear the proper scale.

Another issue with this image is the way that the art was created. Rather than one piece of art, this texture could have been split up into pieces (the wood frames separate from the corners and separate from the background).



The corners and wood panel should be their own textures and imperfections make it difficult to tile textures.

Ideally, the corners and wood panel would be their own textures so that you can tile them to make your background image as big/small as you need without stretching the image. Inside UMG you can set the texture Draw As option to different settings, this would have been a good chance to use the Border mode which supports tiling.



Please see the Mobile Rendering Features for more information on creating textures for mobile devices.

Tips and Tricks

This section highlights some tips and tricks you can use when working with UMG or assets for use with UMG.

Formatting Tip

When working with panels like Vertical or Horizontal Boxes, whether to use Fill or Auto for the Size of a Slot comes into play.



Above, a series of buttons across the top of a screen have been set to Auto to only use the amount of space it needs for layout.

When you select Auto for the slot size, you are saying that the Widget needs a specified amount of room to be properly displayed. Auto looks at each child of the Widget set to auto and determines how big each needs to be as well. This is useful in situations where you have several Widgets that need to be scaled inside a Scale Box, if set to auto, the Scale Box can then look at each child and determine how much to scale each by so that they all fit.

Fill on the other hand, does as the name implies and will attempt to take as much space as possible. In the image below, we've set both the top and bottom rows of buttons to Auto and the center Vertical Box containing the Main Menu buttons to Fill. This was done so that the top and bottom rows of buttons are pushed by the Vertical Box to the top and bottom of whatever the screen size is.



Using Render Transforms

Be wary when using Render Transforms to affect the translation, scale or other settings for a particular Widget.



Above, the Scale under Render Transforms is adjusted and driven by an Animation to create a pulsing effect.

Render Transforms are great for temporary transforms (such as animating a widget) but not necessarily good for permanent transforms. For example if you need to scale up the size of a Widget, do so by wrapping the Widget with a Scale Box instead of adjusting Scale through Render Transforms. A Scale Box will perform Layout Scale while Render Transforms (which are not calculated as part of Layout) will not so they will not be scaled properly when scaling for different resolutions and could lead to improper scaling of your Widgets.

Right-click Context Menu

On the Designer tab of a Widget Blueprint, you can right-click on a Widget in the Hierarchy to wrap or replace it with another Widget.



This makes it quick and easy to swap Widgets in or out without having to re-parent things.

You can also right-click on properties in the Details panel and copy/paste them.



This is helpful for copying/pasting things like the style of a Button.

Ctrl-Drag Anchors and Widgets

When working with a Canvas Panel, you can hold Ctrl while dragging your Anchor (or selecting it from the preset Anchors) to drag the Anchor and the Widget at the same time to the desired location.



The Anchor will auto position to the upper-left of the Widget when Ctrl dragging the Anchor/Widget.

Designer Preview Background

Inside any Widget Blueprint on the Designer tab, you can set a preview image to be used in the graph as your background.



Using a preview background can help ensure that you are scaling widgets to the right size.

To do so, select the Root in the Hierarchy, then under Details you can assign a texture to use.

User Widgets / Reusing Content

Whenever you create a Widget Blueprint with some content, it is considered a User Widget. These User Widgets will appear in the Palette window of the Designer tab under the User Created section and can be drag/dropped into the graph like any other Widget.



Above, a confirmation screen User Widget is added to a different menu screen.

Use this to your advantage when constructing your screens and content. If you have some functionality that is going to be used quite a bit throughout your project, make it its own Widget that you can drop into any other Widget to supply that functionality rather than building it into each area each time you need it.

Optimizations

Some optimizations you can consider when authoring your UI Screens include:

Use Textures instead of Materials for your art whenever possible.

Use Events to Drive UI updates whenever possible instead of Bindings or Tick events.

Use the Invalidation Box to cache Widgets that do not change very often.

Use the Widget Reflector (Ctrl+Shift+W) to get information and statistics about your Widgets.

UMG UI Designer

DPI Scaling

Blueprints Visual Scripting

How Anchors Work

Preset Anchors

Manual Anchors

Use Anchors to set location of the UI widgets on a Canvas Panel. The Anchors supports settings with different screen sizes and aspect ratios.

Minimum (X,Y) and Maximum (X,Y) Anchors parameters and offset parameters determine location of each widget.

You are able to select from a number of Anchors presets or set up it manually by the Minimum (X,Y) and Maximum (X,Y) parameters (where Min (0,0) and Max (0,0) determine the upper left corner of the Canvas Panel; Min(1,1) and Max(1,1) determine the bottom right corner of the Canvas Panel). Anchors presets differ in the set of offset parameters.

How Anchors Work

Anchor Medallion shows the Anchor position in the Canvas Panel. It is marked by the yellow box in the image below.



Image below shows you the Image Widget placed on the Canvas Panel. For this you should drag the Image from the Palette panel onto the Canvas Panel. Use default settings of Anchors (top left corner location).

The horizontal yellow line is X-axis Button offset. It determines distance in Slate Units from Anchor Medallion to the Image in the X-direction.

The vertical yellow line is Y-axis Button offset. It determines distance in Slate Units from Anchor Medallion to the Image in the Y-direction.

The offset parameters based on Canvas Panel size and adapt to size changes.



Click the Screen Size Button in the graph to change the currently used size. It is very useful to test the UI widget layout with different screen sizes or aspect ratios and adjust accordingly.

It is important to take into account differences in device screen sizes and aspect ratios, when you set Anchors and offset parameters of the widgets. You should avoid shifting widget out of the viewport. It could happen in case innapropriate Anchors settings for some screen sizes.

Image below shows what it looks like. Yellow box marks the location of Anchor point. Image is shifted off viewport.



Set up the Anchor location to the lower right corner.



These settings allow you to avoid cropped off screen, and the Image is shifted inside viewport. Image below shows what it looks like. Yellow box marks the location of Anchor point.



This example shows the effect of the Anchors on widgets position in viewport, depending on aspect ratios. You can also split the Anchor Medallion into several components. With the help of this, you will be able to set more offset options to customize the display of widgets with different screen sizes and aspect ratios (see the Manual Anchors section for more information).

Preset Anchors

Preset Anchors is the most common method of Anchor point setting for widgets. With the help of this, you will be able to cover most of your needs in setting position of UI widget.

Select preset from Anchors drop-down window at the Details panel. Each preset determines the Anchor point location. The silver box marks this location.



For example, select the Center/Center preset Anchor option for widget you need.



There are also preset stretching methods of the Anchor Medallion, when it is splitted into several components.







Horizontal Stretch

Vertical Stretch

Stretch Both

With the help of this, you will be able set up widget to stretch along with the viewport, based on screen size.

Image below shows the preset, which stretch Anchor of widget along bottom side of the Canvas Panel.



In this case, the stretching of the Anchor Medallion means splitting it into two pieces.

You can split the Anchor Medallion by draging one of the pins.

Progress Bar with Anchors settings, which is described before, in game process looks as following:



In case of using another aspect ratios of viewport, it looks as following:



Manual Anchors

In some cases, it is necessary to set Anchors manually. For example, this is useful, when you need to anchor widgets to each other.

Image below shows the Image Widget next to the Progress Bar Widget. Both of them are inside the Canvas Panel, which is placed on another Canvas Panel.



The Progress Bar Widget and the Image Widget has Anchors to the upper left corner of the Canvas Panel.



The following shows adjustment process of the sizes proportional dependence between the Canvas Panel, widgets, and their positions.

Set the Progress Bar to stretch along longitudinal side of the Canvas Panel and fix distance from right side. You should do it by setting Anchors as following: move the Anchor Medallion of the Progress Bar to the center of the Progress Bar left side, then splitting apart the Anchor Medallion by dragging the left center pin.



With the help of these settings, there is a proportional dependence between the Canvas Panel and the Progress Bar horizontally. Also, there is a fixed distance between right sides.



The next step is to fix the Image Widget position in the Canvas Panel and fix the distance between the Image Widget and the Progress Bar Widget.

Move the Anchor Medallion of the Image to the Progress Bar top left corner.



With the help of these settings, Image moves with resizing of the Canvas Panel. Distance between the Image and the Progress Bar is fixed.



Set fixed distance between the Image and right side of the Canvas Panel. With the help of this, you avoid cropping the Image off with the Canvas Panel resizing.



Move and split the Anchor Medallion of the Image as shown below.



With the help of these settings, the Image location is fixed horizontally. Also, there is a proportional dependence between the Canvas Panel and the Image horizontally.



The next step is to fix the Image Widget position in vertical direction. With the help of this, you avoid displacement of the Image relative to the Progress Bar.



Fix the Image position based on Progress Bar position in X and Y direction, by setting the Anchor Medallion as shown.



As a result, there is a proportional dependence of sizes in any direction between the Canvas Panel, the Progress Bar, and the Image. Also, there is fixed positions of each item.



Adding Animations

Adding Animation Keys

Changing Key Values

Calling Animations

Example: Animated Main Menu

Located along the bottom of the Widget Blueprint Editor are two windows which allow you to implement and control animations for your UI Widgets. The first, the Animations window, allows you to create essentially animation tracks which are used to drive the animation of your Widgets. The second, the Timeline window, is how an animation is applied to a Widget over time which is done by placing Keyframes at specified times then defining how the attached Widget should appear at that Keyframe (this could be size, shape, location, or even coloring options).

Adding Animations

In order to get started with animations in UMG, you will need to first add an animation track. This can be done by clicking the +Animation button in the Animations window. Once you add an animation (yellow box below), you will be prompted to enter a name for the animation track.



After adding an animation track, the Timeline will become active and you can begin adding Animation Keys that are associated with values that shift over time for your Widgets. It should also be noted that you can have multiple animation tracks for each Widget, for example, having a button move across the screen and flash at the same time.

Adding Animation Keys

There are two methods in which you can add Keys to an animation track. The first is by using the Auto Key checkbox located inside the Timeline window (yellow arrow below). This will automatically add Keys to the Timeline when you make adjustments to a value that supports Keyframing.



The currently selected animation track is highlighted at the top of the Timeline (indicated by the yellow box above).

The general workflow for adding Keys via the Auto Key option is to specify a time in which you want to reach your desired value for your Widget, then moving the Timeline Bar to that time and setting the value via the Details panel or by using the Grid (mostly used for location, rotation, or scale). Once you have set your end result, scrub to the beginning of your sequence and set the default state for your Widget. When scrubbing the Timeline bar between the two time periods, you should see your change occur gradually over the time period.

The second method in which you can add Keys is by clicking the Add Key button next to a setting that supports Keyframing.



In the image above, the icon next to each of the settings can be clicked on and doing so will result in a Key for the value being added to the Timeline at its current position. In the image below, Keyframes for Background Color have been added at 0.00 and 2.00 where the Background Color of a Button Widget is changed from White to Yellow over 2 seconds.



Changing Key Values

You can change the value for multiple Keys at a particular time on the Timeline by holding Ctrl and clicking on the Keys.



Above, we have selected each of the Keys associated with the position of a Vertical Box containing Buttons so that we may set them manually via the Details panel. Manually entering values allows for more precise control (for example) over moving Widgets as we only want to move the object along one axis.

Calling Animations

When you create an animation, a variable for it is also created. If you look on the Graph tab under the Animation dropdown menu in the MyBlueprint window, you will see all your animation tracks you have created. By holding Control and dragging the animation into the graph, you will be able to issue commands to it such as Play or Stop.



Here we are telling our Start Animation to Play when the Widget Blueprint is constructed.



And here we are telling our Blinking Button animation to Stop playing when our start_Button is clicked on.



Example: Animated Main Menu

Below are two example animations used to mimic a simple Main Menu screen where Buttons fly in from the bottom of the screen and a Start Button blinks. After following the steps, you should end up with something similar to the example below.

This example is for demonstrating how to set up animation in UMG only as the Buttons do not do anything when clicked on.

Set up your Main Menu however you see fit and include a Vertical Box containing Buttons on your screen.



Click image for full view.

Click the New button in the Animations window and give the Animation a name such as StartAnimation.



Click the Auto Key button in the Timeline Window.



Move the Timeline Bar to 0.00 on the Timeline, then click on the Vertical Box containing your Button.

Holding Control, click in the center of the Medallion Widget (yellow arrow) and drag the Vertical Box off screen (1).



This will add Keyframes for the current location on the Timeline (2).

In the Details panel for the Vertical Box, click Anchors and select the Bottom Center option.



Move the Timeline Bar to 1.00 then holding Ctrl, click and move the Vertical Box up so it is fully visible.

In the Details panel for the Vertical Box, click Anchors and select the Center option.



In the Animations window, click the New button to add another animation called BlinkingButton.



Make sure that Auto Key is not checked.

Move the Timeline Bar to 1.00 and click on your Start Button so it is selected.

Under the Appearance section in the Details panel, click the Add Key button next to Background Color.



Move the Timeline Bar to 2.00 then change the color for Background Color and add another Keyframe.



The Timeline should now look like below for the BlinkingButton animation.



Click the Graph tab, then drag in both animation variables and create the graph below.



Here we are saying when the Widget Blueprint is constructed, play the Start Animation (our Buttons flying in from the bottom of the screen). We are then using the Set Timer node to call a Custom Event called StartBlinking every 2 seconds (the Set Timer node is set to Looping). Our StartBlinking Custom Event then plays the Blinking Button animation every 2 seconds (which is our color shift over time from white to green for our Start Button).

Finally, create the Widget Blueprint from either the Level Blueprint or your playable Character Blueprint.



In our MyCharacter Blueprint, we are creating the Widget containing the animations and UI layout of our Main Menu and adding it to the viewport by using the Add to Viewport node.

Slate Clipping System

Clipping Properties

Additonal Considerations

The clipping system in UMG uses Slate's Clipping System as a framework to control how text, images, or content is shown for Widgets (as well as the rest of the Editor). Clipping works by restricting rendered objects (graphics and text) to a region using a bounding box so that anything outside of it is not shown. The clipping system is now axis-aligned meaning that it can clip any rotation, which was not possible before because of the way transforms were handled.



In this example, each of the buttons is a parent to the displayed text. These examples demonstrate whether the button or the text is responsible for clipping.

Left - No clipping is enabled on the button or the text.

Center - Clipping is enabled on the text

Right - Clipping is enabled on the button.

The Canvas panel (or clipping zone), outlined in blue, represents your game screen and will clip (or not draw) anything outside of this area for your game.





In the UMG Designer Graph, the Canvas panel (blue) represents the clipping zone for your game screen.



In Unreal Engine 4.16 and earlier, clipping for Widgets was handled using layout-space which prevented anything from rendering outside of the Canvas panel. So if part of a Widget's bounding box was outside of the Canvas panel it would no longer rendered, even if the Widget were rotated, its bounding box would not be leaving parts of the graphic or text cut off even if it's inside the Canvas panel.

Take for instance these examples showing a comparison before and after the changes:





The Image Widget (left) has been placed at the edge of the Canvas panel so that part of its bounding box is outside. Now that the clipping system is axis-aligned, instead of using layout-space, clipping which resolves artifacts and issues like the comparison (right).

Clipping Properties

You can change how clipping is handled based on the Widget selected in the UMG Details panel under Clipping.



Property

Description

Inherit

This widget does not clip children and obeys whatever clipping / culling it was passed in from a parent widget.

Clip to Bounds

This widget clips content to the bounds of the widget. It intersects those bounds with any previous clipping area.

Clip to Bounds - Without Intersecting

Clip to Bounds - Always

Clip to Bounds - Always

This widget clips to its bounds. It intersects those bounds with any previous clipping area.

This clipping area cannot be ignored, it will always clip children. This is useful for hard barriers in the UI where you never want animations or other effects to break this region.



On Demand

This widget clips to its bound when it's Desired Size is larger than the allocated geometry the widget is given. If that occurs, it will work like Clip to BoundsText, which is often placed into containers that eventually are resized to not be able to support the length of the text. So rather than needing to tag every container that could contain text with [YES], which would result in almost no batching, this mode was added to dynamically adjust the clipping if needed. The reason not every is not set to On Demand

Additonal Considerations

In most cases, you should not need to adjust the clipping method except in instances where you can't control the length of the text and need to clip it. An example of this would be Scroll Box and Editable Text Widgets, which are set to Clip to Bounds instead of Inherit.

Elements in different clipping spaces cannot be batched together, so there is a performance cost that comes with clipping. For this reason, do not enable clipping unless a panel actually needs to prevent content from showing up outside of its bounds.

Setting and Testing Safe Zone Resolutions

Testing UI in PIE and Standalone Game

Safe Zone widgets are an essential part of developing a game user interface (UI) that can run on a lot of different devices. Safe zones are designed to keep the UI from displaying somewhere that it can technically use but the player can't see, such as the edge of a TV display or under the notch and home bar of the iPhoneX. The UMG Designer enables you to test the resolution (or rotation) of the device with your UI and applied Safe Zone widgets.

When you add a Safe Zone widget to the Designer , the widget will scale any other widgets that are made children of it from the Hierarchy panel. These child widgets will scale and adjust anytime there is an "unsafe" zone.





In this example, a 1080p display has a Uniform Safe Zone area of 0.9 (red) for testing and debugging purposes. When the widgets are parented to a Safe Zone widget, the child widgets will scale to the safe zone area. This prevents widgets from being cut off at the screen edge deemed "unsafe". This can be seen in the example, with the "My Menu" title text.

Setting and Testing Safe Zone Resolutions

In



To test the screen resolution of a device, use the UMG Designer viewport to select the Screen Size dropdown and select from the listed devices.

If the device supports screen orientation, like a phone or tablet, use the Portrait/Landscape button to swap between the two view modes. This option will be grayed out when the device selected doesn't support orientation shifting.



Here is an example of the two view modes:

Left: Landscape, Right: Portrait

When a device is selected, relevant information and marked "unsafe" zones will be displayed in the Designer graph.

Marked "Unsafe" Zones

Device Details for Mobile Content Scale Factor, Device Name or Uniform Safe Zone, and Screen Size

DPI Scale

For non-uniform safe zones, you can use the Flip button to simulate device rotation for Landscape mode.

This option is only available on some devices and only for Landscape view mode.

When previewing TVs and Monitors from the list, if you've set a debug title safe zone that is less than 1, the Uniform Safe Zone will display that size. The debug safe zone area is represented by the red area around the canvas widgets.

The Debug Safe Zone mode is on by default in UMG which enables the red "unsafe" zone area to be represented.

For some devices, there are now custom "unsafe" zones represented within the Designer graph. These are used to represent hardware or software specific areas of the device that take up screen real estate, such as the iPhoneX where these zones represent the notch and home bar sections of the screen.

In this example of the iPhoneX, the Safe Zone widget is parented to the section of the widget hierarchy where the menu and buttons are contained. When areas are "unsafe," the encapsulated widgets scale to avoid these areas (see example above).



Testing UI in PIE and Standalone Game

When testing your UI in the Editor, you can set the screen size based on a common device screen size when using PIE with a New Editor Window or when using Standalone Game without deploying content to a device. Use the Editor Preferences to set the device under Level > Play > Game Viewport Settings to choose a common device resolution.

Use the Landscape/Portrait Orientation button to swap which orientation should be used.

UMG Slots

Widget Type Reference



States

Padding

Sounds

Render Transform

When it comes to creating your UI screens through UMG, arranging the layout of your elements is only the beginning. For each of your Buttons, Bars, Text Boxes, etc. there are several Style options that can be assigned directly within UMG from the Details panel that can affect the way that they appear.

Each of the Widgets below utilize the Style option, however their individual Style options may vary:

Button

Check Box

Editable Text Box

Multi Line Editable Text Box

Progress Bar

Size Box

Slider

Spin Box

Text Block

Combo Box (String)

Editable Text

Multi Line Editable Text

States

There may be instances, particularly with interactive Widgets, that you want to convey a different look for your Widget based on how it is interacted with or the condition it is in. For example, say you have a button on screen that appears normally and when moused over, changes colors or pulsates, then when clicked does something entirely different. Referred to as States, this is the most common form of styling and allows you to specify how the Widget appears based on the current state it is in.



Above, a Button Widget changes based on its Normal, Pressed, Hovered, or Disabled States. Most Widgets will use the Normal, Pressed, Hovered, and Disabled States, however there may be additional options based on the type of Widget you are using.

Setting Image States

For each state, you can set an Image (either a Texture or Material asset) for the Widget to use. Image Size refers to the size of the resource in Slate Units and the Draw As option, which uses a 9 Scale Box, allows you to specify how the image is drawn in the form of a Box, Border, or an Image.

Examples of each are provided below:







Box

Border

Image

The Box draws a 3x3 box where the sides and the middle Stretch (orange arrows) based on the Margins (dotted blue lines).

The green arrows represent constant values based on the Margin x Image Size.

The Border draws a 3x3 border where the sides Tile (orange arrows) based on the Margins (dotted blue lines).

The middle is not drawn when using a Border.

The green arrows represent constant values based on the Margin x Image Size.

The Image will draw the image and will Stretch (orange arrow) and the Margin will be ignored.

You can assign Textures as your Image asset, but there are some flags you will want to set in order for the Texture to show up on every device, and to show up crisp and without compression artifacts. Inside the Texture Edtior under Level Of Detail, set Mip Gen Settings to NoMipmaps and set the LOD Group to UI. Under Compression, set the Compression Setting to TC Editor Icon.



Click for full view.

Materials can also be assigned as the Image asset for your Image States, but you will need to change a few settings. Inside the Material, in the Details panel under Usage, you will need to check the Used with UI checkbox. This enables compiling a different shader specifically for Slate. You also need to only output Emissive Color.



Click for full view.

In order to modify Material Parameters, you need a Dynamic Material Instance. The Image Widget makes this especially easy as long as it has a Slate Brush on it with a Material, you can ask for the dynamic image (only creates it once and then caches it).



Tint / Margin

Also under each State is the option to Tint the image, which allows you apply a tint color to the supplied image associated with the state. There is also a Margin option which allows you to enter a margin size for the Box and Border draw modes (in Image mode, margin is ignored).

Padding

The Padding styling option refers to the border created around aspects of the Widget.



For example, in the image above for a Box Button, Normal Padding accounts for the border in the button's background image. When it is applied, the content of the button will appear flush with the button's border. Pressed Padding is the same as Normal Padding, however it refers to the padding applied when the button is pressed.

Based on the type of Widget you are using, different Padding options may be available.

Sounds

Sounds can be set for your Widgets based on the State the Widget is in.



Most Widgets that allow sounds to be applied make use of the Hovered or Pressed Sound Events, which play the specified sound when hovering over the Widget or clicking on the Widget. In the image above for a Check Box Widget, there is the option to set sound events for Checked and Unchecked as well as Hovered.

Based on the type of Widget you are using, different Sound options may be available.

Render Transform



There are additional styling options that can be used to modify the look of your Widgets found under the Render Transform section of the Details panel for your Widget. With the Render Transform settings, you can Translate, Scale, Shear, or Angle your Widgets as well as adjust its Pivot point.

Samples of Render Transform settings are illustrated below.



Each of the Render Transform settings can be Keyframed allowing you to modify them with Animations and they can also be modified through Blueprints allowing you to make modifications during or based on gameplay actions performed by the user. Render Transforms are relative to Layout Transforms and are not clipped by their parent (for example if you had a Scroll Box full of Buttons, adjusting the Translation in the Render Transform settings could push the Button outside of its box).



Widget Blueprints

Widget Type Reference



A Font is an asset that can be used with Text Actors (especially with the



By default, UMG text widgets use a font that ships with Unreal Engine. This gives you something to work with out of the box so you can get started quickly. However, this built-in font has some limitations; for example, it only supports a small set of languages. For most projects, especially those that require UIs with non-English text, you'll want to import your own custom fonts into Assets and set up your text widgets to use your fonts.



Explains how to enable 3rd party screen reader support for your project.



This how-to will guide you through importing your Font assets for use in Unreal Engine 4.



This how-to will guide you through creating Font assets that can be used with the UMG UI designer tools.



Examples of how you can style your UMG fonts using colors, Materials, and outlines.



This guide provides information on using Fonts with the UMG UI designer tools.

Enabling Screen Reader Support

Using Accessibility in UMG

Custom Widget Support (C++)

UE4 now supports third party screen readers for Windows or VoiceOver on iOS. This makes it possible to ensure your game UI is accessible and helps you comply with CVAA standards. Screen readers, such as NVDA and JAWS, allow a software application's UI to be narrated to the user. This is a critical feature that enables those who are visually impaired to use and navigate software applications.

As of 4.23, there are now APIs included in UE4 to allow the use of 3rd party screen readers to read UI text. This supports a number of common UMG widgets, such as Text Block, Editable Text Box, Slider, Button, and Checkbox. This built-in functionality removes the need to implement custom text-to-speech technology, making screen readers easier to support.

Enabling Screen Reader Support

To enable screen reader support, go into either your project or Engine Console Variable configuration file. Once in the file, add the variable Accessibility.Enable=1.

Using Accessibility in UMG

To make your UMG widgets accessible with screen readers, go to the Details panel for any of your widgets, and you will see a section for Accessibility. By default, the accessibility settings are enabled. If you would like to adjust the default settings, check Use Custom Behavior. This enables you to adjust Can Children Be Accessible, Accessible Behavior, and Accessible Summary Behavior options.

The Can Children Be Accessible checkbox indicates whether or not the child widgets inherit the Accessible Behavior settings.

Accessible Behavior is where you indicate how you want the screen reader API to read the widget text. You can choose from the following options:

Auto: Automatically reads the assigned text for a widget.

Summary: Screen reader concatenates the text of all child widgets.

Custom: Screen reader uses custom text pre-coded by developer.

Tool Tip: Screen reader only reads Tool Tip Text.

Not Accessible: Ignores screen reader API.

If you select Summary in Accessible Behaviors, Accessible Summary Behavior shows you what text will be read when concatenating the text from the parent widget and all subsequent child widgets.



Custom Widget Support (C++)

You can add additional support by creating new C++ classes for their custom Slate widgets. To add specialized support to a new widget, you must override SWidget::CreateAccessibleWidget() and return an instance of a new FSlateAccessibleWidget. You can find an example of this in the file SlateAccessibleWidgets.h under FSlateAccessibleButton. This example shows how screen readers enable users to click the button.

You can compile out the screen reader code from Slate and platform layers when bCompileWithAccessibilitySupport is set to false.

Using Fonts with UMG

Creating and Assigning Fonts

Using Fonts with UMG

Using the Content Browser

Using Drag-and-drop

Using the Font Editor

End Result

In this guide, you'll learn how to import your own Font files into Unreal Engine 4.



When you start to import your Fonts, you can choose between several methods and choose the method that best fits your workflow. The available methods you can use to import are:

Using the Content Browser's Import button

Drag-and-drop method into the Content Browser

Using the Font Editor

You also have the choice between TrueType Font (TTF) and OpenType Font (OTF) files when importing your fonts. Choose the import method and font type that best fits your needs.

For this how-to guide, we are using the Blank Template project, using no Starter Content, with default Target Hardware and Project Settings.

Using the Content Browser

You can use the Content Browser's Import button to select your TTF or OTF font file.

In the Content Browser, click the Import button.



After the Import dialog box appears, navigate to the TFF or OTF font file you want to import and select it. Then, click Open.



After a moment, the Font Face Import Options dialog will appear. Select Yes from the options listed to create your Font Face asset and your Composite Font asset in your Content Browser.



The Font Face asset can now be found in your folder hierarchy.



Using Drag-and-drop

You can Drag-and-drop a TTF or OTF file directly into the Content Browser to create your font assets.

Navigate to the folder where you've stored your TTF or OTF file(s). Select and hold to drag the file over the Content Browser to start the import process.



After a moment, the Font Import Options will appear. Select Yes from the options listed to create your Font Face asset and your Composite Font asset in your Content Browser.



The Font Face asset can now be found in your folder hierarchy.



Using the Font Editor

You can import and create Font Face assets directly from the Default Font Family list in the Font Editor removing the need to import a font asset first then assign it.

Open an existing Font asset or create a new one using the Add New button in the Content Browser.



Click the Add Font button to add a new font selection to the Default Font Family.



Select the folder button next to the selection dropdown.



After the Import dialog box appears, navigate to the TFF or OTF font file you want to import and select it. Then, click Open.



Next, the Save Font Face window will appear. Give your font a name and choose the save location in your game folder's hierarchy. Then, click Save.



The Font Face asset can now be found in your folder hierarchy.



End Result

Now that you've seen how to import using the various methods, you should be able to import your own font files using any one of these options for use in your games and projects.

Using Fonts with UMG

Importing Fonts

Using Fonts with UMG

Steps

Creating a Font Asset

Assign a Font Face Asset

End Result

In this guide, you'll learn how to create an empty Font asset to which you can then assign a Font Face asset or import a new TTF or OTF font file directly using the Font Editor.



Steps

Follow the steps below to create your own Font asset and then learn how to assign one of your Font Face assets using the Font Editor.

For this how-to guide, we are using the Blank Template project, using no Starter Content, with default Target Hardware and Project Settings.

Creating a Font Asset

Click the Add New button inside the Content Browser, then under User Interface, select the Font option.



Click image for full view.

A new Composite Font asset will be created, prompting you to give it a Name.



Once you enter a name, you will notice an asterisk appears on the asset, this indicates that the asset has not be saved. Click the Save All button to save your asset, then confirm the save in the pop-up menu that appears.



Assign a Font Face Asset

Now that you've created your empty Font asset, you will have to assign your Font Face(s) to be used. To do this, double-click to open your Font in the Font Editor.



In the Font Editor, click on the Add Font button to add a new Font slot.



Now, use the dropdown selection under the Font Name to select an existing Font Face asset that was already imported into your project.



If you do not have any Font Face assets, you can use the Folder icon next to the dropdown selection box to navigate and import your own TrueType Font (TTF) or OpenType Font (OTF) font file.

End Result

Now that you've seen how to create your own Font assets and assign an already imported Font Face asset using the Font Editor, you should be able to create your own Font assets that can be used with the UMG UI Designer.



Using Fonts with UMG

UMG Styling

Font Colors

Font Materials

Font Outlines

In addition to being able to set a Color and Opacity for your Font in UMG, you can also use Materials and font outlines for additional Font styling.

Font Colors

You can set the Vertex Color for your Font by setting its Color and Opacity.



Without a Font Material specified, this will apply a solid color to your text.



Font Materials

You can specify a Font Material for your Font in the Details panel.



If your Font Material doesn't have a Vertex Color node, the effect is like a simple multiplication.







Font Material Setup

Font Material Preview

Final Font

However, if you place a Vertex Color node in your Font Material, you can use its outputs to do math within your shader.







Font Material Setup

Font Material Preview

Final Font

Materials used as font materials must be in the User Interface domain.



Font Outlines

You can specify a different Outline Color as well as a different Material to use for a font outline.



The size of the outline is specified in Slate units, but when the font's scale is 1.0, 1 Slate unit is equivalent to 1 pixel.



One interesting note is that you can specify whether or not to use Separate Fill Alpha.



When this is enabled, the outline is translucent where the filled area will be, allowing you to adjust the alphas of the font and the font outline independently. When it is disabled, the font is overlaid on the outline, so the alphas are additive and the outline color and Material is visible through a font with an alpha less than 1.





Font Color Alpha = 0.5, Separate Fill Alpha disabled

Font Color Alpha = 0.5, Separate Fill Alpha enable

Using Fonts with UMG

Importing Fonts

Creating and Assigning Fonts

Widget Blueprints

Steps

End Result

This guide provides information on setting up Fonts Assets of the Text Widget via Widget Blueprints Editor.



Steps

Follow the steps below to see how to adjust custom Fonts and use them via UMG UI Designer of the Widget Blueprints Editor.

For this how-to guide, use Blank Template is used with no Starter Content. Settings of Target Hardware and Project Settings are used by default.

Create a new Widget Blueprint. Click the Add in the Content Browser, then select User Interface > Widget Blueprint.



Double-click the created Widget Blueprint to open it in the Widget Blueprint Editor.

Find Canvas Panel Widget in the Pallete panel and drag it into the Visual Designer window.

Find Text Widget in the Pallete panel and drag it into Canvas Panel of the Visual Designer window.

Click created Text Widget for access the Details panel of this item. In the Details panel, under Appearance, find a Font option. With the help of this, you can adjust family type, facetype (regular, bold, itallic, and so on), size, letter spacing and so on.



By default, the Unreal Engine uses the Roboto font. Click the dropdown menu next to Font Family for selecting any custom Fonts Assets, you have created.



You can also choose option to create a custom Fonts via this menu and specify location of the new asset (it will be blank by default).

Click dropdown menu next to TypeFace for selecting a style for selected Fonts Asset.



You can specify the size of the Fonts Asset in the input box next to Size.



Also, you can specify a space between letter in the input box next to Letter Spacing.



Currently, UMG only supports Runtime cached Fonts Assets. Also, if you have assigned Fonts using the old method, none of your existing file-based font settings will be lost, however going forward, you will need to create a Fonts Asset in order to use custom Fonts with UMG.

End Result

You have get familiar with basics of adjusting Fonts Assets of the Text Widget via Widget Blueprints Editor. Moreover, you can style your Fonts by colors, Materials, outline properties, and so on.



Specialized Blueprint Node Groups

1 - Setting Up the UI Widget Blueprint

2 - Adding the UI Blueprint Widget to your Level

End Result

In most games, you will want to communicate some information to your players through your game's User Interface. This can range from things like Main Menus, in-game Pause Menus, HUD elements like Health or Experience, Inventory Items, or help text to instruct players what to do in a given situation.

With Unreal Motion Graphics (UMG), you can create a Widget Blueprint to handle the display of UI elements in your project. The Widget Blueprint uses Blueprints Visual Scripting to design the layout as well as script functionality for UI elements such as what happens when a button is clicked or if a value changes.

In this how-to, we will create a Widget Blueprint and add some Text to it, then through the Level Blueprint display it when a key is pressed.



1 - Setting Up the UI Widget Blueprint

First, we need to set up our User Interface (UI) Widget Blueprint.

For this how-to, we are using the Blueprint Third Person Template. However, you can use any project you wish.

In the Content Browser click the Add* button, then select User Interface > Widget Blueprint**.



All UMG UI elements are created inside a Widget Blueprint.

Enter the name SampleUI for the name of the Widget Blueprint, and double-click to open it.



When you open the Blueprint, the UMG Editor Interface appears.



Click for full view

The Widget Blueprint opens by default to the Designer tab, which is where you set up the visual layout of your UI elements. To script functionality for the Widget Blueprint, select Graph in the top right corner of the editor.

Inside the Palette window, drag a Text widget into the Visual Designer graph.



The Palette window contains several different types of widgets that you can use to construct your UI elements.

In the Details panel for the Text Widget, click the Anchors dropdown and select to Anchor to the center.



This ensures that as the viewport size changes, the Text widget will stay anchored relative to the center of the screen.

Set the following properties for the Text widget in the Details panel:

Text Widget Name: We suggest you change this so it's easier to quickly differentiate between the different elements you create.

Size to Content: Check this so the widget auto-adjusts to the size of the widget.

Text: This is the text inside the widget that appears in the UI.

Color and Opacity: Select a color for your text.

Font Size: Open the Font group and adjust the size to 56. In this section, you can also change the Font Family and Typeface.



Also, place you Text Widget in the center of the screen. It should look as following.



After making your adjustments, select Compile then Save. Then, close the Widget Blueprint.



2 - Adding the UI Blueprint Widget to your Level

In order to see the text you just created in-game, you need to add the Blueprint Widget to your level. This involves adding some scripting to tell the level that when you press Enter the text should display in-game.

From the Main Toolbar, select the Blueprints dropdown and then Open Level Blueprint.



Right-click in the graph and search for the Create Widget node.



On the node, click the Class drop-down menu and search for the Widget Blueprint we just made, SampleUI.



Right-click on the Return Value pin and select Promote to Variable. Rename the variable to SampleUI.



Whenever you create the Widget Blueprint (your UI), it's a good idea to promote that to a variable so you can access it later through Blueprint script.

Drag off the out pin on the Set node and search for the Add to Viewport node.



This is how we tell the Widget Blueprint to display in-game.

Right-click in the graph and search for the Enter Keyboard Event.



Connect the Pressed pin to the executable pin of the Create Sample UI Widget node.



This tells the viewport when we press Enter to create and store the widget as a variable, and then show the SampleUI widget in-game.

Hold Ctrl and drag the SampleUI variable into the graph from the My Blueprint panel.



Drag off the pin of the new node and search for and add the Remove from Parent node.



The Remove from Parent node tells a Blueprint when an element should be removed from the viewport.

Connect the Release pin of the Enter node to the Remove from Parent executable pin.



Now when we press the Enter key during gameplay, the text will be displayed. When we release Enter, the text will disappear.

Select Compile and Save before closing the Level Blueprint. Then click the Play button from the Main Toolbar. Press and release Enter to see the SampleUI widget in action!



End Result

When you play in the Editor, you will have something similar to below whenever you press and release the Enter key.

Create an Editor Utility Widget

If you want to modify the User Interface (UI) of the Unreal Editor, you can use Editor Utility Widgets to add new UI elements. Editor Utility Widgets are based on Unreal Motion Graphics (UMG), so you can set up Widgets in a Blueprint like you would for any other UMG Widget Blueprint.

These Widgets are specifically for the Editor UI, and you can use them to create custom Editor tabs. You can then select these custom tabs from the Windows menu, like you would select existing Editor tabs.

Create an Editor Utility Widget

Right-click in the Content Browser and select Editor Utilities > Editor Widget.

Name your Editor Utility Widget Asset. In this example, the Asset is named TestEditorUtility. Double-click the Editor Utility Widget Asset to open the Widget Blueprint for editing.

Edit your Widget Blueprint as needed.



Click for full image.

Right-click the Editor Utility Widget Asset and select Run to open an Editor tab with your Editor Utility displayed. The tab is only dockable with Level Editor tabs.

Once you have run the Editor Utility Widget, it appears in the Level Editor's Windows dropdown, under the Editor Utility Widgets category.

Workflow

Required Setup

Viewmodels

Create a Viewmodel

Variables with FieldNotifies

Functions with FieldNotifies

Triggering FieldNotifies with Macros

Example

Add a Viewmodel to a Widget

Initialize Your Viewmodel

Create Instance

Manual

Property Paths

Global Viewmodel Collection

Access Your Viewmodel's Members

Working With Arrays

Best Practices for Creating Viewmodels

View Bindings

Add a View Binding to a Widget

Using the Details Panel

Using the View Binding Menu

Configure Your View Binding

Choose the Target Widget

Create View Binding Entries

Select the Widget Property

Select the Viewmodel Property

Set The Bind Direction

Using Conversion Functions

Typically, UI developers break backend data and visual design into separate systems. This makes the process of building the user interface (UI) less destructive and more efficient, as designers can change the visual presentation without breaking the code behind the UI, and programmers can focus on data and systems without needing a completed frontend. The Viewmodel plugin provides a medium for this workflow by introducing Viewmodel assets and View Bindings.

Workflow

Viewmodels contain variables that you can use in your UI. Designers can bind fields in their UI to these using the View Binding panel, while programmers can build the Viewmodels themselves and tie them in with the application's code as they see fit.

Once you add a Viewmodel to a UMG widget, you can access it and call functions or update variables. The Viewmodel pushes updates to any widgets whose fields are bound to its variables.



This is a more efficient alternative to raw attribute binding, as it only updates widgets when you update the variables. It also provides the benefits of an event-driven UI framework without the implementation time setting one up manually.

Required Setup

To use Viewmodels in your project's UI, enable the UMG Viewmodel plugin in the Plugins **menu.



If you do not enable this plugin, you will not be able to use the UMVVMViewModelBase class, and you will not be able to use View Bindings in UMG.

Viewmodels

Viewmodels have two main purposes:

Maintain a manifest of the variables needed for your UI.

Provide a medium of communication between your UI and the rest of your application.

When you need your UI to be aware of a variable, you can add it to a Viewmodel, then add the Viewmodel to your widget and bind fields to it. When you need to update your variables, you can get a reference to the Viewmodel and set them from there. They then notify the widgets bound to those variables about the changes and update them.

Create a Viewmodel

You can create a Viewmodel in C++ by extending the UMVVMViewModelBase class, or by extending another Viewmodel class. Viewmodels are UObjects that depend on FieldNotify variables and functions to broadcast changes to widgets that are bound to them.

It will be possible to create Viewmodels with Blueprint in a future release of Unreal Engine.

When you define variables in your Viewmodel, each variable should be Private, and must have a UPROPERTY macro with the FieldNotify specifier. The full list of specifiers used for FieldNotify variables is as follows:

UPROPERTY Specifier

Description

FieldNotify

Broadcasts a notification to any widgets bound to this variable.

Setter

States that the variable should allow setting its value. This assumes that the Setter function will have a name with the format Set[Variable Name]

Setter="[FUNCTION_NAME]"

As Setter, but you can provide the name of a custom function to use it as the Setter.

Getter

States that the variable should allow retrieving its value. This assumes that the Getter function will have a name with the format Get[VariableName]

Getter="[FUNCTION_NAME]"

As Getter, but you can provide the name of a custom function to use it as the Getter.

The FieldNotify specifier is required to broadcast value changes to widgets. Any variable with this specifier will appear in the View Binding menu.

You can decide whether to provide the Setter or Getter specifiers. If you decide not to provide one of them, you will not be able to perform that operation outside of this class. Specifying only the Getter and Setter specifiers without a function name is sufficient when you only want to trigger a notification for the variable itself.

Custom Getters and Setters are useful when:

You need to perform an operation before retrieving a variable.

You want to trigger other functions or update other variables when setting a variable.

For example, if you want to create a health bar using a Progress Bar widget, you would need to retrieve a percent value representing how much of the character's maximum health is left, as the Progress Bar uses a percentile value to determine how much it should be filled. In this case, you would define a custom Setter for the character's current health, then have it trigger a separate notify for returning the percentage of the character's maximum health.

If you create custom Getter or Setter functions, do not make them UFUNCTIONS, as it will create redundant listings for Get and Set functions in Blueprint. The UPROPERTY macro for the variable already provides access to these in the form of the variable's Get and Set nodes. You should also make any custom Getters const functions, as their only job should be returning a value.

You can create custom functions that broadcast FieldNotifies, and you can bind widgets' properties to these functions the same way as you can with variables. Functions used in this way must follow these requirements:

They must have the UFUNCTION macro with the FieldNotify and BlueprintPure specifiers.

They must take no arguments.

They must be const functions.

They must return only a single value.

For example, the following function is a FieldNotify for returning the percent value of a character's current health divided by their maximum health:

When changing variables, functions need to call one of the Viewmodel notification macros to broadcast changes to bound widgets. The list of available macros is as follows:

ViewModel Macro

Description

UE_MVVM_BROADCAST_FIELD_VALUE_CHANGED([Member name])

Broadcasts an event after the field value is changed.

UE_MVVM_BROADCAST_FIELD_VALUE_CHANGED_WITH_REP([Member name])

Replicates the field value over a network game, then broadcasts an event after the field value is changed.

UE_MVVM_SET_PROPERTY_VALUE([Member Name], [New Value])

Test if the value of the field has changed, then set the new value of the field and send a notification to bound widgets.

UE_MVVM_SET_PROPERTY_VALUE_WITH_REP)[Member Name], [New Value])

As UE_MVVM_SET_PROPERTY_VALUE, and then replicate it and send a notification to bound widgets.

The SET_PROPERTY_VALUE macros do the same thing as BROADCAST_FIELD_VALUE macros, except that the SET_PROPERTY_VALUE macros check to see if the value changed before broadcasting. This is a very common check when creating Setters for Viewmodels, and it is included for convenience.

The BROADCAST_FIELD_VALUE_CHANGED macros can take either the variable itself, if you want to notify widgets bound directly to that value, or they can take the names of functions. This can be useful if you want a widget bound to values that are derived or converted from other variables, but do not want to create an extra variable to hold that information.

The following code snippet is an example of a Viewmodel class using the above concepts. GetHealthPercent is defined as a separate function from the Getters and Setters, but the Setters call it in addition to notifying when the variables themselves are changed.

Add a Viewmodel to a Widget

You can add Viewmodels to a widget in the Viewmodels window in UMG. You can find this under Window > Viewmodels in the UMG Designer tab.



Click the + Viewmodel button to select one of your project's Viewmodels, then click Select.



Initialize Your Viewmodel

When you click a Viewmodel in the Viewmodels window, you can choose how to initialize it with the Creation Type setting. The following methods are available:

Viewmodel Creation Type

Description

Create Instance

The widget automatically creates its own instance of the Viewmodel.

Manual

The widget initializes with the Viewmodel as null, and you need to manually create an instance and assign it.

Global Viewmodel Collection

Refers to a globally-available Viewmodel that can be used by any widget in your project. Requires a Global Viewmodel Identifier.

Property Path

At initialization, execute a function to find the Viewmodel. The Viewmodel Property Path uses member names separated by periods. For example: GetPlayerController().Vehicle.Wheel[0].ViewModel. Property paths are always relative to the widget.

Viewmodels do not necessarily have a one-to-one relationship with widgets. There are multiple ways to set them up and assign them to widgets, and it is possible for multiple widgets to take information from a single Viewmodel. Each creation type method is detailed below.

The Create Instance creation method automatically creates a new instance of the Viewmodel for each unique instance of the widget. This means, if you have several copies of the same widget in the viewport, and you change the Viewmodel variables for one of them, only that widget will update, while all the other copies will remain the same. Similarly, if you create multiple different widgets that use the same Viewmodel, none of those widgets will be aware of changes to each other's information. The other methods below are useful for when you want multiple widgets to reference the same data.

The Manual creation method requires you to create an instance of the Viewmodel yourself somewhere in your application's code, then assign it to the widget manually. The widget has a Viewmodel object reference, but it will have a null value until you assign a Viewmodel to it. Once you have assigned your Viewmodel, you can update it whenever you want to update your UI without getting any references to widgets.



This provides an opportunity to assign the same Viewmodel to multiple different widgets in your UI.

The Property Path creation method provides an alternative that is potentially cleaner and requires less code support. Instead of other classes reaching inside the widget to set its Viewmodel reference, the widget reaches out with a series of function calls and references to fetch the Viewmodel. The Property Path field in the editor expects a series of member names separated by periods, and it assumes that the starting point for calling these functions is Self. In other words, it always starts at the widget you are editing.

Do not manually specify Self in your Property Paths, as the Property Path field already assumes you are starting with a reference to Self.

As an example, the following field gets the owning player controller of the widget, then gets a Viewmodel attached to the first wheel on the vehicle it is currently controlling:

You can also call functions you define in your Blueprint, which can help condense the logic for your Property Paths and provide extra flexibility. For example, the following function gets the Character Health Viewmodel from the character who owns the widget:



You can then use this function's name as the Property Path:

The Global Viewmodel Collection is a globally accessible list of Viewmodels in the MVVM Subsystem. These are ideal for handling variables that may need to be accessed throughout your UI, such as settings for your game's option's menu. To add a Viewmodel to the Global Viewmodel Collection in Blueprint, follow these steps:

Add a reference to the MVVM Subsystem.

Drag a pin from the MVVM Subsystem node, then call Get Global Viewmodel Collection.

Drag a pin from the Global Viewmodel collection, then call Add Viewmodel Instance.

You can then construct an instance of the Viewmodel and add it to the collection with this node. The Game Instance class is a convenient place to initialize these.



When choosing Global Viewmodel Collection as an initialization mode, provide the Context Name from your Add Viewmodel Instance node in the Global Viewmodel Identifier. This name must match the class name for the Viewmodel. For example, if your Viewmodel is called VM_GraphicsOptions you would provide that as both the Context Name and the Global Viewmodel Identifier.

Access Your Viewmodel's Members

After you have assigned a Viewmodel to a widget, you can access it as a property of the widget in your Blueprint. It will be located under the Variables > Viewmodel category. Once you have a reference to a Viewmodel, you can access its variables and functions.



Depending on what options are configured in the Viewmodel, you may not have access to all internal functions or Setters.

Working With Arrays

Arrays are not normally accessible in Viewmodels. To access an array in your Viewmodel, create your own FieldNotify functions to add, remove, and get members in the array directly from the Viewmodel itself.

Best Practices for Creating Viewmodels

When creating your Viewmodels, you should use small, concise Viewmodels instead of large, monolithic ones. This practice makes debugging your UI easier.

For example, you could create a Viewmodel representing a Character in an RPG, with a complete array of characteristics, an inventory, and hit points. However, to debug any part of the UI that depends on this Viewmodel, you would first need to spawn an entire character to fill the Viewmodel's data. If you split these up into different components, you can more easily fill them with test data when debugging.

You can nest Viewmodels inside other Viewmodels. This can be useful for representing complex sets of data.

View Bindings

After you have created a Viewmodel, you can add it to a widget in the UMG editor and target it with the View Bindings window.

Add a View Binding to a Widget

There are two methods for adding View Bindings to widgets: you can add them with the property binding dropdown in the Details panel, or you can use the View Binding menu to manage all of your widget's bindings.

To use View Bindings in the Details Panel, select the widget you want to add a binding to, then click the Bind dropdown on the property you want to bind. Any Viewmodel variables and functions that are valid for that property will appear at the bottom of the dropdown. Click one to assign the binding.



The View Binding window offers more detailed control over how your View Bindings behave. Open the View Binding window by clicking Window > View Binding in the UMG Designer tab.



Click + Add Widget to add an entry to the View Binding list.



Any Viewmodel you have added in the Viewmodels window is eligible for bindings.

In the current version of Unreal Engine, if you bind a Viewmodel with the View Bindings menu, then reassign it with the Details panel, the binding might become invalid. To fix this, you should delete the binding from the View Bindings menu, then reassign it.

Configure Your View Binding

View Bindings contain the following information:

The target widget and target Viewmodel** for the binding.

The widget property and Viewmodel property that you want to bind to one another.

The direction of the binding, which determines the flow of information between the two target properties.

The update type of the binding.

The enabled / disabled toggle, which turns the binding on and off.

The following sections provide details about each of these fields and how to configure them.

The first dropdown for a View Binding entry chooses the widget you want to add the View Binding to. When you click it, the dropdown shows the hierarchy for your widget, and you can choose either the parent widget itself or any of its child widgets. Click Select to confirm your selection.



Underneath the target widget, there are entries for individual properties you want to set up Viewmodel bindings for. Each binding is indented from the widget that it belongs to. You can add multiple bindings for a single widget by clicking the + button next to the widget's dropdown. Each binding must target a different property.



The first dropdown in a View Binding entry displays a list of the target widget's variables and functions. For example, if you use a select Progress Bar widget, the Percent property will be available.



For a property or function defined in C++ to appear in this list, it must be visible to the Unreal Engine reflection system with the UFUNCTION or UPROPERTY macros. Blueprint-defined variables and functions are automatically available.

The third dropdown selects both the Viewmodel you want to target, as well as which of its properties you want to use for the View Binding. When you click it, it displays a list of the Viewmodels you added to this widget.



Click the Viewmodel you want to use to display a list of variables and functions that are viable for View Bindings. For variables and functions to appear here, they must have the FieldNotify specifier.

The second dropdown selects the Bind Direction for the View Binding. This determines how information flows between the widget and the Viewmodel.



The available bind directions are as follows:

Bind Direction

Description

One Way to Widget

The binding applies only from the Viewmodel to the widget. Any time you update the corresponding variable in the Viewmodel, it notifies the widget that the variable has changed and updates the selected widget property. Alternatively, if you chose a function, calling that function updates the selected widget property.

One Way to Viewmodel

The binding applies only from the widget to the Viewmodel. Any time either the user or your code changes the selected property in the widget, it applies that change to the Viewmodel property. Typical examples include user-edited text fields or graphics options.

Two Way

The binding applies in both directions.

Using Conversion Functions

As an alternative to binding directly to a variable, you can select Conversion Functions. These provide an interface for translating variables from your Viewmodel into different types of data, such as changing integers into text. Conversion Functions appear in the Viewmodel property dropdown underneath the list of Viewmodels.



When you choose a Conversion Function, a list of options for configuring that function's arguments appears beneath the dropdowns for the View Binding.



If you click the link button for one of these properties, you can bind that property to any Viewmodel value.





Specialized Blueprint Node Groups

1 - Setting Up the Button Widget

2 - Adding the Button Widget to the HUD Widget

End Result

Every Widget Blueprint that you create with UMG is considered a User Widget that can be reused and placed within other Widget Blueprints. Both visual and scripted functionality will be carried over into the Blueprint.

With some Blueprint Scripting, you can create variables for how your UI widget functions or looks that can be overwritten on a per-instance basis. In this How-to, we will create and stylize a Button and set it up in such a way that we can override the style when we place it in other Widget Blueprints. Lastly, we will customize what happens when the Button is clicked on a per-instance basis. This is useful if you have a series of Buttons in a menu that you want to look and act the same but produce different results when pressed.

1 - Setting Up the Button Widget

First, we need to create a Button and set up the script for what happens when we click the Button.

For this how-to, we are using the Blueprint Third Person Template with Starter Content enabled.

Click the Add in the Content Browser, then select User Interface > Widget Blueprint.



You can also add a Widget Blueprint by right-clicking into Content Browser, then User Interface > Widget Blueprint.

You should create two Widget Blueprints with names CustomButton and HUD.



The CustomButton is the User Widget that we will add into the HUD Widget Blueprint.

Add a Button by dragging from the Palette panel into Hirerchy panel. Right-click Button you added and select Wrap With > Size Box.



In the Size Box Details panel, change the Width Override to 300 and Height Override to 100. You can also change the graph layout to Desired on Screen to get an idea of the actual size of the button.



In the Event Graph, hold Ctrl and drag the Button from the My Blueprint panel. Then, drag off the pin and add a Set Style node. Make sure to select the Variable Apperance node and not the Button Function node.



Connect the Event Construct node to the Set Widget Style node, and then Right-click on Widget Style and select Promote to Variable.



Name the new variable ButtonStyle and then Compile the Blueprint. Then, set the Normal > Image style to any texture.



Right-click on the Normal section and select Copy. Then, paste the image settings to the Hovered and Pressed values. All three of these values should now have the same image texture.



Expand Hovered and change the Tint color to any color (such as yellow).



In the ButtonStyle, check Instance Editable and Expose on Spawn.



This enables us to modify the values of this variable from other Widget Blueprints when we use this Widget Blueprint elsewhere.

Select the Button variable, and click the + sign to add an OnClicked node to the graph.



In the MyBlueprint panel, select + Event Dispatcher to create a new Event Dispatcher and call it ButtonClicked.



Drag the ButtonClicked event into the graph, select Call, and connect the node to the OnClicked event.



This creates a unique script functionality when we click the button. If we had multiple instances of this button and only used the OnClicked event, each instance would respond and execute the same functionality. However, by creating an Event Dispatcher, we can implement events on a per-instance basis and have only the button that was actually clicked on fire off an additional script.

2 - Adding the Button Widget to the HUD Widget

With our Button widget created and scripted, we can now add the Button to the HUD Widget, add the HUD to the viewport, and see the buttons in-game.

Open the HUD Widget Blueprint, and add a Vertical Box to the Canvas Panel. Resize the box to a smaller size.



From the Palette under User Created, add three Custom Buttons to the Vertical Box.



In the Event Graph, select each CustomButton and click + to add the Button Clicked event to the graph. You should have three events, one for each button.



This is the Event Dispatcher that we created inside our CustomButton Widget Blueprint and will respond whenever this particular button is clicked.

For each ButtonClicked event, drag off the pins and connect Print String nodes up to each event. Add different text to the In String text boxes.



In this example, we are printing different text to the screen depending on which button we click. In a real-world example, you can have each button open up a different menu, change different game settings, or make modifications to a player character.

This how-to simulates clicking a button for example purposes. To learn how to make HUD menu, see



From the Level Editor Main Toolbar, go to Blueprints and select Open Level Blueprint.



Right-click in the Event Graph and add an Event BeginPlay node. Connect the node to a Create Widget node with the Class set to HUD.



Add an Add to Viewport node and connect it to the Create HUD Widget node. Then, add a Get Player Controller function to a Set Show Mouse Cursor node and check the box (set it to True).



Compile, Save, close the Level Blueprint, and click Play in the editor to interact with your button in-game.

End Result

When playing in the editor, each Button is automatically styled based on the defined ButtonStyle variable, and they execute a different portion of the script as the Event Dispatcher is called and the corresponding ButtonClicked Event is called. Since our ButtonStyle variable is exposed and editable on spawn, we can override the style of the button in whatever Widget Blueprint we place it in. This is useful if you have some kind of animation or other complex scripted logic that you don't want to re-create in each Blueprint. By creating your button as a User Widget, you can reuse it in any other Widget Blueprints without additional work.

Bindable Events

Multicast Events

This page details the methods you can use to call and bind Events in UMG.

Bindable Events

Bindable Events are a way for UMG to mimic the behavior currently used by Slate which needs a single handler to tell it if the Event was handled. You can bind a function in your Widget Blueprint to the event from the Details panel under the Events section (shown below indicated by the yellow arrows).



Indicated above by the yellow box, some Widgets supplement Events through the handling of Interaction. For the example above, in addition to the OnClicked Event for a Button Widget, you are able to specify the handling of click events through setting the Click Method or Touch Method. You can also specify through the IsFocusable option if a button should only be mouse-clickable and never keyboard focusable.

Multicast Events

Multicast Events are the standard way Events are handled in Blueprints.

To use a Multicast Event:

click the Widget in the My Blueprint tab (1).

Scroll down to the Events section in the Details panel, then click the + button for the Event you want to use (2).

The Event appears in the Blueprint graph, where you can connect other nodes to it (3).



Function Binding

Property Binding

One of the most useful aspects inside UMG is the ability to bind properties of your Widgets to Functions or Properties inside the Blueprint. By binding a property to a Function or Property Variable in your Blueprint, anytime that Function is called or Property is updated, it will be reflected in the Widget.

Function Binding

Say for instance you had a Progress Bar Widget and you wanted to update it to reflect a player's health at all times. Under Appearance for the Progress Bar you will notice a Percent option with the option to Bind the Percent value to a Function or Property (illustrated below in the yellow box).



After clicking the Bind Button and selecting the Creating Binding option, a new Function will be created and open up.



The Return Value is tied to the Percent's Value, so you can plug in a value to feed your Progress Bar data.



Above, the Function gets a variable called Player Health from inside our Character Blueprint. Anytime the Player Health variable is updated, it is automatically passed to and reflected as the Percent Value on the Progress Bar.

Property Binding

Property Binding consists of specifying a Property Variable that is bound to a Widget's property. When the Property Variable is updated, the setting that is bound to it is automatically updated and reflected in the Widget.

An example of binding a Property Variable for a Button is illustrated below.



In the image above, we have three Buttons for a Main Menu: Continue, Start, and Quit and we want Continue to only be enabled if the player has a Save Game. Under the Behavior section for the Continue Button, you can un-check IsEnabled (so the Button is not enabled by default) and then click the Bind Button.



On the Graph tab for this Widget Blueprint, you could then create a Boolean variable and once it has been created, can assign it via the Bind Button (below we have created a Boolean called DoesSaveExist?).



With this variable bound to the IsEnabled Behavior, you could then set this whenever your game is started by checking if a save file is present and if so, Casting to this Widget Blueprint to access and set the DoesSaveExist variable to True which would then enable the Button.

If you bind a property of a Widget and then directly call the Set function on that Widget, it will break the binding.

Accessing Slots

Slots are the invisible glue that bind Widgets together. In Slate they are a lot more explicit in that you must first create a Slot then choose what control to place inside of it. In UMG, however, you have Panel Widgets that automatically use the right kind of Slot when Child Widgets are added to them.

Moreover, each Slot is different. For example, if you were to place a control on a Grid, you would expect to be able to set things like Row and Column. But these properties have no business being on a Widget that was placed on a Canvas. That is where Slots come in. A Canvas Slot understands how to layout content absolutely and through Anchors, while a Grid Slot only understands Rows and Columns.

Accessing Slots

By convention, all Slot-related properties appear under the Layout category in the Details panel. You will also notice that the type of Slot being used by your Widget is displayed in parentheses.



Setting Layout Properties

At runtime, to modify properties under Layout, you can access the Slot member of the Widget in Blueprint or C++ and then Cast it to the correct Slot Type. Once doing so, you will then be able to modify the properties, an example of which is indicted below.



Above, a Vertical Box entitled GameTitleBox has been placed on a CanvasPanel. By getting the Slot associated with the Vertical Box and Casting to the CanvasPanelSlot type, we are then able to set the position of the box when our "StartButton" is clicked.

Currently in Blueprints, only SETTER nodes are exposed. If you need to GET properties from the Layout, you may want to create a Variable to store your property and upon Event Construct, and SET your Layout property via your Variable so that you have reference to and can access it later.

Specialized Blueprint Node Groups

Blueprints Visual Scripting

Programming and Scripting With UMG

Adding a Widget Interaction Component

Widget Interaction Property Reference

Widget Interaction Blueprint Node Reference



If you are using a Widget Component to display UI that exists in 3D in your game world and you want to allow players to interact with that widget, the Widget Interaction component provides a way for that interaction to occur.

The Widget Interaction component performs a Raycast to see if it hits a Widget Component placed in the world and if it hits one, you can set up rules to determine how to interact with it. The interaction is performed by simulating a defined key press, for example if a Button can be clicked on with the Left Mouse Button, you could tell other forms of input to simulate a Left Mouse Button click (controller button press, motion controller trigger press, etc.).

For step-by-step examples, see Creating 3D Widgets and



Adding a Widget Interaction Component

Typically you will want to add the Widget Interaction component to your player Pawn or Characters class from the Components Window.



Above, we add and attach it to a gun our character is carrying so that where the gun points, the Widget Interaction component points.

Widget Interaction Property Reference

Once you have added a Widget Interaction component, you can adjust several properties from the Details panel to define how it functions. Aside from common component properties like Transform, Rendering, or Sockets, the properties below are specifically used with the Widget Interaction Component.

Option

Description



Interaction



Virtual User Index

Represents the Virtual User Index. Widget Interaction Components operate by using this Virtual User Index which captures and handles focus states separately. Each Virtual User should be represented by a different Index to ensure that they will maintain separate capture and focus states. As each Widget Interaction component comes online, it informs Slate of the Virtual User Index it has been assigned and can send events as if it were a real Slate user.

Pointer Index

Each user's simulated Virtual Controller or Virtual Finger Tips should use a different Pointer Index.

Interaction Distance

The distance in game units the component should be able to interact with a widget component.

Interaction Source

Determines where we should project from and start the trace (World, Mouse, Center Screen or Custom). If you set this to Custom, you'll need to call SetCustomHitResult() and provide the result of a custom hit test from whatever location you wish.

Enable Hit Testing

Should the interaction component perform hit testing (Automatic or Custom) and attempt to simulate hover? If you were going to emulate a keyboard and the virtual keyboard is separate from the virtual pointer device, you should turn this option off and use a second interaction component for the pointer device.



Debugging



Show Debug

Shows debugging lines and a hit sphere to help debug interaction.

Debug Color

Determines the color of the debug lines when Show Debug is enabled.



Events



On Hovered Widget Changed

Called when the hovered Widget Component changes. The interaction component functions at the Slate level - so it's unable to report anything about what Widget is under the hit result.

Widget Interaction Blueprint Node Reference

The Widget Interaction component can simulate different types of input methods (such as press, release or press + release) which you can find under the Interaction section in the Blueprint Context Menu. You can also get information such as the last "hit" position registered by the Widget Interaction component or if a Widget Component in the world is currently being hovered upon.



Node

Description

Get Hovered Widget Component

Gets the currently hovered Widget Component.

Get Last Hit Result

Gets the last hit result generated by the component. Returns the custom hit result if that was set.

Is Over Focusable Widget

Returns true if a widget under the hit result is focusable. Slate widgets that return true for SupportsKeyboardFocus().

Is Over Hit Test Visible Widget

Returns true if a widget under the hit result has a visibility setting that makes it hit test visible. Slate widgets that return true for GetVisibility().IsHitTestVisible().

Is Over Interactable Widget

Returns true if a widget under the hit result is interactive. Slate widgets that return true for IsInteractble().

Press and Release Key

Performs both the press and release of a simulated keyboard key.

Press Key

Performs a press of a simulated keyboard key. Avoid using this for a-z|A-Z, since things like the Editable Textbox in Slate expect OnKeyChar to be called to signal a specific character being sent to the widget. For those cases, use SendKeyChar instead.

Press Pointer Key

Simulates pressing a key on the mouse/pointer. In most cases, the key supplied would be a mouse button, but any key can be used. Advanced use cases, such as sending other keys to signal widgets to take special actions, are supported.

Release Key

Releases a key as if it had been released from the keyboard.

Release Pointer Key

Simulates releasing a key on the mouse/pointer, similar to Press Pointer Key. In most cases, the key supplied would be a mouse button, but any key can be used.

Scroll Wheel

Sends a scroll wheel event to the widget under the last hit result.

Send Key Char

Transmits a list of characters to a widget by simulating an OnKeyChar event for each key listed in the string.

Set Custom Hit Result

Sets a custom hit result. This is only taken into account if the Interaction Source is set to Custom.

The properties for the Widget Interaction component can also be reterived in the form of a getter or set via setter nodes.



Creating and Assigning a Data Table Asset

Rich Image Row Data Type

Rich Text Style Row Data Type

Using Rich Text Block Widgets in UMG UI Designer

Add a Rich Text Block Widget

Assign a Data Table Asset to a Rich Text Block

Apply Style to Text

Decorator Classes

Using Decorators

Adding New Decorators

Setting of the UMG Rich Text Block

Rich Text Block Properties

Properties of the Data Table Asset with Rich Image Row Data Type

Properties of the Data Table Asset with Rich Text Style Row Data Type

The Text Block, provided in Unreal Motion Graphics (UMG), offers a variety of style options and customization. However, you might need a more flexible text block option that supports markup for things like style changes, inline images, hyperlinks, and so on.

The UMG RichTextBlock provides a more flexible text block. It supports markup for things like style changes, inline images, hyperlinks, and so on. UMG RichTextBlock accepts decorator classes, which you can write to define the markup behavior you need in your project. Also, page shows the detailed information about properties, you can set to the RichTextBlock Widget and the Data Table Asset with the Rich Image Row and Rich Text Style Row data types.

The Rich Text Block uses a Data Table Asset to manage added styles and customization. With the help of the Data Table Asset, you will be able to create your own styles. Also, it allows you to write custom decorator classes, that define the markup behavior you need, in your project. The page shows an example of decorator class, RichTextBlockImageDecorator. You can use it as a starting point for experience in writing custom decorator classes.

Get familiar with the content of the page to learn more about the RichTextBlock in UMG, and how you can write custom decorator classes.

Creating and Assigning a Data Table Asset

At first, you should create a Data Table Asset. With the help of the Data Table Asset, you will be able to create different types of data tags and use it with the RichTextBlock Widget in UMG. You can use the Data Table Asset for specifying text styles or images, that you can use inline with rich text via the RichTextBlock.

Create a Data Table Asset like any other asset: click Add New in the Content Browser, then select Miscellaneous > Data Table.



Select either Rich Image Row or Rich Text Style Row in Pick Row Structure window.



The Rich Image Row uses a custom decorator class, which you can find more details about in the Decorator Classes Decorator Classes section.

Rich Image Row Data Type

As an example, the page shows the Rich Image Row data type, which is a custom decorator class. Store images and set up it with different customization options, using the Data Table Asset with the Rich Image Row data type. Due to this, you can use this data as inline images in the text via the RichTextBlock.



Click here for full view

Follow the steps below to create and use the Rich Image Row data type of the Data Table Asset.

Create a Data Table Asset, select the Rich Image Row from the drop-down list of the Pick Row Structure window. Also, you can rename this Data Table Asset. For example, put the name "Image_DataTable".

Double-click the created Data Table Asset in the Content Browser to open it in the Data Table Editor.

Click Add in the Data Table Asset panel to add a new row. Create rows in the Data Table Asset for each inline image, that will be used in your text via the RichTextBlock. There are other instruments for rows at the Data Table Asset panel, like: Copy, Paste, Duplicate, Remove.



You can change the row name via the text field of the Row Name section. It is allowed to use prefixes, camel case, and so on.

Set the properties you need for these images under Appearance.

When you have done adding rows, click Save and close the Data Table Asset.

See Properties of the Data Table Asset with Rich Image Row Data Type for more information about these settings.

Rich Text Style Row Data Type

The Rich Text Style Row data type is the default decorator class. With the help of this, you can set text styles, that can be applied to the text via the RichTextBlock.



Click for full view.

Follow the steps below to create and use the Rich Text Style Row data type of the Data Table Asset.

Create a Data Table Asset, select the Rich Text Style Row from the drop-down list of the Pick Row Structure window. Also, you can rename this Data Table Asset. For example, put the name "TextStyle_DataTable".

Double-click the created Data Table Asset in the Content Browser to open it in the Data Table Editor.

Click Add in the Data Table Asset panel to add a new row. Create rows in the Data Table Asset for each text style, that will be used in your text via the RichTextBlock. There are other Instruments for rows at the Data Table Asset panel, like: Copy, Paste, Duplicate, Remove.



You can change the name of each row in the text field of the Row Name section. It is allowed to use prefixes, camel case, and so on.

It is recommended to rename the first row of the Data Table Asset to "Default". Due to this, you have defined style of this row as the default style for text in the assigned RichTextBlock.

Set the properties you need for these styles under Appearance.

When you have done adding rows, click Save and close the Data Table Asset.

See Properties of the Data Table Asset with Rich Text Style Row Data Type for more information about these settings.

For correct display of the text, it is necessary to set the font in the Data Table Asset for each Rich Text Style Row. Open Data Table Editor. You should select the text row you want to customize, then go on Appearance > Text Style > Font section of the Row Editor. In new window you need click Gear and enable Show Engine Content. With the help of this you will be able to choose Roboto font or another one you want.



Click for full view.

Using Rich Text Block Widgets in UMG UI Designer

You should assign the RichTextBlock widget with the created Data Table Asset. Due to this, you will be able to use configured text styles and inline images from the Data Table Asset via the Designer Viewport.

Add a Rich Text Block Widget

Create a Widget Blueprint: click Add New in the Content Browser, then select User Interface > Widget Blueprint.



You should find a Canvas Panel in the Palette panel on the left side. Drag the Canvas Panel into the Designer Viewport. Find a RichTextBlock in the Palette panel, drag this widget into the Canvas Panel box of the Designer Viewport. You can scale or resize the RichTextBlock box for your needs.



The text box does not scale automatically to fit the text size. If you do not resize the box to fit your text size, some of your text may be clipped and not display properly. Also, you can enable the checkbox of the section Set to Content in the Details panel for automatic resizing text box to content.

Assign a Data Table Asset to a Rich Text Block

Select the added RichTextBlock widget. With the help of the Details panel on the right side, you will be able to assign your Data Table Asset to the RichTextBlock in the Appearance section.

Use the Text Style Set to assign your Data Table Asset with Rich Text Style Rows to the RichTextBlock.



Apply Style to Text

You should assign the Data Table Asset to the RichTextBlock as described before. Follow the steps below to apply the styles from your Data Table Asset to the text.

Select RichTextBlock.

Find the Content section of the Details panel on the right side.

Type your text into the text field of the Text section.

The display text has a style from the row of the Data Table Asset with name "Default". For example, if you typed to the text field "This is some rich text!", it would display with the style you customized in "Default" row of the Data Table Asset.



Click for full view.

You can change default text style for the RichTextBlock you defined in the Data Table Asset. Enable the checkbox of the section Override Default Style in the Details panel. Due to this you will be able to customize new default text style in Default Text Style Override section.

In case you need another style from your Data Table Asset, type the name of the style row in enclosed brackets, using the markup <TextStyleRowName>text</> (where "TextStyleRowName" is the text style Row Name of the Data Table Asset you assigned, "text" – part of text you want to have style from specified row). For example: This is some <RichText.Emphasis>rich</> text! You can apply different styles for different parts of your text.



Click for full view.

T I P: The row name tag in the RichTextBlock is case insensitive to the Data Table Asset rows name.

Decorator Classes

You can include something other than style to your text by using the Decorator Classes. When you create a Decorator Class, you can set up your own markup tags. With the help of this, you will be able to use Slate. It allows you to render other elements seamlessly within your text.

Using Decorators

As an example, the page shows how to include inline images into the text via RichTextBlockImageRowDecorator class. This example helps you to get start using custom decorator classes.

You need to have the created Data Table Asset with Rich Image Row data type (see Creating and Assigning a Data Table Asset section above), and subclass Blueprint Class with RichTextBlockImageRowDecorator Parent Class as a blueprint to configure the instance. Follow the steps below to do this:

Create a new Blueprint class: click Add New in the Content Browser, then select Blueprint Class.



Choose RichTextBlockImageRowDecorator in the Pick Parent Class window and click Select.



Click for full view.

Double-click the created Blueprint Class in the Content Browser to open it in the Blueprint Editor.

Assign this Blueprint Class to the Data Table Asset with Rich Image Row data type via the Image Set with the help of the Details panel on the right side.



Having done everything listed above, you are able to add the Decorator Class to your RichTextBlock Widget. Follow the steps below for using inline images from Data Table Asset in your text.

Open your Widget Blueprint.

Find Decorator Classes section under Appearance in the Details panel on the right side.

Click (+) button for adding array element to the Decorator Classes.

Choose the created Blueprint Class in drop-down list.



For inserting inline images from the Data Table Asset, you should use the markup <img id="ImageRowName"/> (where "ImageNameFromTable" is the Row Name of Data Table Asset you assigned) in the Content section of Details panel. For example, if you typed to the text field With <img id="RichText.Logo"/> inline images! and click Compile, it would display text with inline images you customized in the Data Table Asset at the row with the name "RichText.Logo".



Click for full view.

Adding New Decorators

You can define custom decorator classes, that can leverage Slate to add anything you want inline the text. To do this, you should write two classes: URichTextBlockDecorator and FRichTextDecorator. You should set up these classes. Due to this, you will be able to add your Decorator to any RichTextBlock. Use the Decorator Classes array and your markup to parse text with your Decorator.

URichTextBlockDecorator defines a UObject to implement CreateDecorator, which should return a SharedPtr to the FRichTextDecorator. Due to this, you can implement any properties and utility functions. Also, you can subclass your Decorator as a Blueprint. It allows to add and use any data you need in RichTextBlock.

Remember, the RichTextBlockImageDecorator defines a Data Table property. Anything you want to modify in Blueprints should exist in the UObject.

Setting of the UMG Rich Text Block

This reference section shows the detailed information about properties, you can set to the RichTextBlock Widget and the Data Table Asset with the Rich Image Row and Rich Text Style Row data types.

Rich Text Block Properties

Property

Description



Slot (Canvas Panel Slot)



Anchors

This sets the anchor location for the selected widget.

Minimum - Holds the minimum anchors, left and top.

Maximum - Holds the maximum anchors, right and bottom.

Alignment

Alignment is the pivot point of the widget. Starting in the upper left at (0,0) and ending in the lower right at (1,1). Moving the alignment point enables you to move the origin of the widget.

Size To Content

When AutoSize is true, it uses the widget's desired size.

ZOrder

This indicates the order priority for rendering selected widget. Higher values are rendered last, appearing on top. Lower values rendering first and appearing on the bottom.



Content



Text

This is the text to display in the widget.



Appearance



Text Style Set

This holds the Data Table Asset, which enables rich text decorators to be used for text and image styles.

Decorator Classes

This adds the Decorator can be used for selected widget.

Override Default Style

If sets true, it specifies the default text style for this rich text inline, overriding any default provided in the style set table.

Default Text Style Override

This sets the text style to apply by default.

Min Desired Width

This sets the minimum desired size for the text.

Transform Policy

The text transformation policy to apply to this text block.

None - No transform, just use the given text as-is.

To Lower - Convert the text to lowercase for display.

To Upper - Convert the text to uppercase for display.

Justification

This sets how the text is aligned with the margin.

Margin

This sets the amount of blank space, left around the edges of the text area.

Line Height Percentage

This sets the amount each line height is scaled by.



Clipping



Clipping

Controls how the clipping behavior of this widget works. Normally, content, that overflows the bounds of the widget, continues rendering. Enabling clipping prevents that overflowing content from being seen.

Inherit - Selected widget does not clip children, it and all children inherit the clipping area of the last clipped widget.

Clip to Bounds - Selected widget clips content the bounds of this widget. It intersects those bounds with any previous clipping area.

Elements in different clipping spaces can not be batched together, so there is performance costs when clipping is applied. Do not enable clipping, unless a panel actually needs to prevent content from showing up outside its bounds.

Overflow Policy

Sets what happens to text, that is clipped and does not fit within the clip rect for this widget.

Clip - Overflowing text will be clipped.

Ellipsis - Overflowing text will be replaced with an ellipsis.



Wrapping



Auto Wrap Text

If sets true, it wraps the text automatically, based on the computed horizontal space for this widget.

Wrap Text At

This determines whether text wraps onto a new line when its length exceeds this width. If this value is zero or negative, no wrapping occurs.

Wrapping Policy

The wrapping policy to use:

Default Wrapping - No fallback, just use the given line-break iterator.

Allow Per Character Wrapping - Fallback to per-character wrapping if a word is too long.



Behavior



Tool Tip Text

The tooltip text, that is displayed, when the user hovers the mouse cursor over the widget.

Is Enabled

This sets whether this widget can be modified interactively by the user.

Visibility

Sets the visibility of this widget.

Visible - The widget is visible and can interact with the cursor.

Collapsed - The widget is not visible and takes up no space in the layout. It can never be clicked on, because it takes up no space.

Hidden - The widget is not visible, but occupies layout space. It is not interactive, because it is hidden.

Not Hit Testable (Self & All Children) - The widget and its children are visible, but cannot interact with cursor.

Not Hit Testable (Self Only) - The widget and its children are visible, but cannot interact with cursor. (The same as Not Hit Testable (Self & All Children) but doesn't apply to child widgets.

Render Opacity

This sets the opacity of the widget.

Tool Tip Widget

The tooltip widget, that is displayed, when the user hovers the mouse cursor over the widget.

Cursor

The cursor to show when the mouse is over the widget.

None - Causes no mouse cursor to be visible.

Default - Default arrow cursor.

Text Edit Beam - Indicates text that can be edited.

Resize Left Right - Resize horizontal arrows cursor.

Resize Up Down - Resize vertical arrows cursor.

Resize South East - Bi-directional forward resize arrow cursor.

Resize South West - Bi-directional back resize arrow cursor.

Cardinal Cross - Indicates something is being moved.

Crosshairs - Indicates precision selection, usually by dragging a selection box around something.

Hand - Uses the hand cursor with pointing finger.

Grab Hand - Uses the open hand cursor indicating something can be grabbed.

Grab Hand Closed - Uses the closed hand cursor indicating something is grabbed.

Slashed Circle - Cursor indicates the action cannot be completed.

Eye Dropper - Indicates a color can be selected.



Render Transform



Transform

The render transform of the widget allows for arbitrary 2D transforms to be applied to the widget.

Translation - The amount to translate the widget in X and Y in Slate Units.

Scale - The amount of scale to apply to the widget in X and Y.

Shear - The amount of shear to apply to the widget in X and Y in Slate Units.

Angle - The degree angle to rotate the widget.

Pivot

The render transform pivot controls the location, about which transforms are applied. This value is a normalized coordinate, about which things, like rotations, will occur.



Performance



Is Volatile

If sets true, this prevents the widget, or its child's geometry, or layout information, from being cached. If this widget changes every frame, but you want it to still be in an invalidation panel, you should mark it volatile, instead of invalidating it every frame. It would prevent the invalidation panel from actually ever caching anything.



Navigation



Left

Defines navigation when using Left:

Escape - Navigation is allowed to escape the bounds of this widget.

Stop - Navigation stops at the bounds of this widget.

Wrap - Navigation wraps to the opposite bound of this object.

Explicit - Navigation goes to a specified widget.

Custom - Custom function can determine what widget is navigated to, when itself or its children are navigated away from. Applied when the itself or any children are navigated from.

Custom Boundary - Custom Function can determine what widget is navigated to. Applied when the boundary is hit.

Right

Defines navigation when using Right:

Escape - Navigation is allowed to escape the bounds of this widget.

Stop - Navigation stops at the bounds of this widget.

Wrap - Navigation wraps to the opposite bound of this object.

Explicit - Navigation goes to a specified widget.

Custom - Custom function can determine what widget is navigated to, when itself or its children are navigated away from. Applied when the itself or any children are navigated from.

Custom Boundary - Custom Function can determine what widget is navigated to. Applied when the boundary is hit.

Up

Defines navigation when using Up:

Escape - Navigation is allowed to escape the bounds of this widget.

Stop - Navigation stops at the bounds of this widget.

Wrap - Navigation wraps to the opposite bound of this object.

Explicit - Navigation goes to a specified widget.

Custom - Custom function can determine what widget is navigated to, when itself or its children are navigated away from. Applied when the itself or any children are navigated from.

Custom Boundary - Custom Function can determine what widget is navigated to. Applied when the boundary is hit.

Down

Defines navigation when using Down:

Escape - Navigation is allowed to escape the bounds of this widget.

Stop - Navigation stops at the bounds of this widget.

Wrap - Navigation wraps to the opposite bound of this object.

Explicit - Navigation goes to a specified widget.

Custom - Custom function can determine what widget is navigated to, when itself or its children are navigated away from. Applied when the itself or any children are navigated from.

Custom Boundary - Custom Function can determine what widget is navigated to. Applied when the boundary is hit.

Next

Defines navigation when using Next:

Escape - Navigation is allowed to escape the bounds of this widget.

Stop - Navigation stops at the bounds of this widget.

Wrap - Navigation wraps to the opposite bound of this object.

Explicit - Navigation goes to a specified widget.

Custom - Custom function can determine what widget is navigated to, when itself or its children are navigated away from. Applied when the itself or any children are navigated from.

Custom Boundary - Custom Function can determine what widget is navigated to. Applied when the boundary is hit.

Previous

Defines navigation when using Previous:

Escape - Navigation is allowed to escape the bounds of this widget.

Stop - Navigation stops at the bounds of this widget.

Wrap - Navigation wraps to the opposite bound of this object.

Explicit - Navigation goes to a specified widget.

Custom - Custom function can determine what widget is navigated to, when itself or its children are navigated away from. Applied when the itself or any children are navigated from.

Custom Boundary - Custom Function can determine what widget is navigated to. Applied when the boundary is hit.



Localization



Force Direction Preference

Use it for set up a new flow direction.

Inherit - Inherits the flow direction, that set by the parent widget.

Culture - Begins laying out widgets. It uses the current cultures layout direction preference, flipping the directionality of flows.

Left to Right - Forces a Left to Right layout flow.

Right to Left - Forces a Right to Left layout flow.

Text Shaping Method

It determines text shaping method, that used within selected widget. When unset, the default is used that is set by Get Default Text Shaping Method.

Auto - Automatically picks the fastest possible shaping method (either KerningOnly or FullShaping), based on the reading direction of the text. Left-to-right text uses the KerningOnly method. Right-to-left uses the FullShaping method.

Kerning Only - Provides fake shaping using only kerning data. This can be faster than full shaping, but won't render complex right-to-left or bi-directional glyphs (such as Arabic) correctly. It can be useful as an optimization, when you know your text block will only show simple glyphs (such as numbers).

Full Shaping - Provides full text shaping, allowing accurate rendering of complex right-to-left or bi-directional glyphs (such as Arabic). It will perform ligature replacement for all languages (such as the combined "fi" glyph in English).

Text Flow Direction

It determines flow direction, that used within selected widget. When unset, the default is used that is set by Get Default Text Flow Direction.

Auto - Automatically detect the flow direction for each paragraph from its text.

Left to Right - Force text to be flowed left-to-right.

Right to Left - Force text to be flowed right-to-left.

Properties of the Data Table Asset with Rich Image Row Data Type

Set the following properties in the Data Table Asset to control the style for images, that used with a RichTextBlock widget.

Property

Description

Image

The image to render for this brush. The assigned Asset can be a UTexture, UMaterialInterface, or an object implementing the AtlasedTextureInterface.

Image Size

The size of the resource in Slate Units.

Tint

Tinting applied to the image.

Draw As

How to draw the image.

None- Don't do anything.

Box - Draw a 3x3 box, where the sides and the middle stretch based on the Margin.

Border - Draw a 3x3 border, where the sides tile and the middle is empty.

Image - Draw an image; the margin is ignored.

Rounded Box- Draw a solid rectangle wuth an outline and corner radius.

Tiling

How to tile the image in Image mode.

No Tile - Just stretch.

Horizontal - Tiles the image horizontally.

Vertical - Tiles the image vertically.

Both - Tiles the image in both directions.

Preview

Sets how the image should be displayed in the preview box.

Horizontal Alignment:

Fill - The image will fill the preview box horizontally.

Left - The image will be aligned to the left of the preview box.

Center - The image will be positioned in the center of the preview box.

Right - The image will be aligned to the right of the preview box.

Vertical Alignment:

Fill - The image will fill the preview box vertically.

Top - The image will be aligned to the top of the preview box.

Center - The image will be positioned in the center of the preview box.

Bottom - The image will be aligned to the bottom of the preview box.

Properties of the Data Table Asset with Rich Text Style Row Data Type

Set the following properties in the Data Table Asset to control the style for text, that used with a RichTextBlock widget.

Property

Description



Font



Font Family

The font object (valid when used from UMG or a Slate widget style asset).

Typeface

The name of the font to use from the default typeface. If None is initially selected, the first entry (Bold) will be used.

Size

The font size is a measure in point values. The conversion of points to Slate Units is done at 96 dpi. So, if you are using a tool like Photoshop to prototype layouts and UI mock ups, be sure to change the default dpi measurements from 72 dpi to 96 dpi.

Font Material

The material to use when rendering this font.

Outline Settings

Settings for applying an outline to a font.

Outline Size - Size of the outline in Slate Units (at 1.0 font scale, this unit is a pixel).

Separate Fill Alpha - If sets true, the outline will be completely translucent where the filled area will be. It allows for a separate fill alpha value to be used. The trade off when enabling this is slightly worse quality for completely opaque fills, where the inner outline border meets the fill area.

Apply Outline to Drop Shadows- If sets true, the outline will be applied to any drop shadow, that uses this font.

Outline Material- Sets optional material to apply to the outline.

Outline Color - The color of the outline for any character in this font.

Color

The color and opacity of this text.

Shadow Offset

It sets how much should the shadow be offset. An offset of 0 implies no shadow.

Shadow Color and Opacity

The color and opacity of the shadow.

Shadow Background Color

The background color of selected text.

Highlight Color

The color of highlighted text.

Transform Policy

The Text Transform Policy (defaults to None).

Overflow Policy

Determines what happens to text that is clipped and does not fit within the clip rect of a text widget.



Highlight Shape



Image

The image to render for this brush. The assigned Asset can be a UTexture, UMaterialInterface, or an object implementing the AtlasedTextureInterface.

Image Size

The size of the resource in Slate Units.

Tint

Tinting applied to the image.

Draw As

How to draw the image.

None- Don't do anything.

Box - Draw a 3x3 box, where the sides and the middle stretch based on the Margin.

Border - Draw a 3x3 border, where the sides tile and the middle is empty.

Image - Draw an image; the margin is ignored.

Rounded Box- Draw a solid rectangle wuth an outline and corner radius.

Tiling

How to tile the image in Image mode.

No Tile - Just stretch.

Horizontal - Tiles the image horizontally.

Vertical - Tiles the image vertically.

Both - Tiles the image in both directions.

Preview

Sets how the image should be displayed in the preview box.

Horizontal Alignment:

Fill - The image will fill the preview box horizontally.

Left - The image will be aligned to the left of the preview box.

Center - The image will be positioned in the center of the preview box.

Right - The image will be aligned to the right of the preview box.

Vertical Alignment:

Fill - The image will fill the preview box vertically.

Top - The image will be aligned to the top of the preview box.

Center - The image will be positioned in the center of the preview box.

Bottom - The image will be aligned to the bottom of the preview box.



Strike Brush



Image

The image to render for this brush. The assigned Asset can be a UTexture, UMaterialInterface, or an object implementing the AtlasedTextureInterface.

Image Size

The size of the resource in Slate Units.

Tint

Tinting applied to the image.

Draw As

How to draw the image.

None- Don't do anything.

Box - Draw a 3x3 box, where the sides and the middle stretch based on the Margin.

Border - Draw a 3x3 border, where the sides tile and the middle is empty.

Image - Draw an image; the margin is ignored.

Rounded Box- Draw a solid rectangle wuth an outline and corner radius.

Tiling

How to tile the image in Image mode.

No Tile - Just stretch.

Horizontal - Tiles the image horizontally.

Vertical - Tiles the image vertically.

Both - Tiles the image in both directions.

Preview

Sets how the image should be displayed in the preview box.

Horizontal Alignment:

Fill - The image will fill the preview box horizontally.

Left - The image will be aligned to the left of the preview box.

Center - The image will be positioned in the center of the preview box.

Right - The image will be aligned to the right of the preview box.

Vertical Alignment:

Fill - The image will fill the preview box vertically.

Top - The image will be aligned to the top of the preview box.

Center - The image will be positioned in the center of the preview box.

Bottom - The image will be aligned to the bottom of the preview box.



Underline Brush



Image

The image to render for this brush. The assigned Asset can be a UTexture, UMaterialInterface, or an object implementing the AtlasedTextureInterface.

Image Size

The size of the resource in Slate Units.

Tint

Tinting applied to the image.

Draw As

How to draw the image.

None- Don't do anything.

Box - Draw a 3x3 box, where the sides and the middle stretch based on the Margin.

Border - Draw a 3x3 border, where the sides tile and the middle is empty.

Image - Draw an image; the margin is ignored.

Rounded Box- Draw a solid rectangle wuth an outline and corner radius.

Tiling

How to tile the image in Image mode.

No Tile - Just stretch.

Horizontal - Tiles the image horizontally.

Vertical - Tiles the image vertically.

Both - Tiles the image in both directions.

Preview

Sets how the image should be displayed in the preview box.

Horizontal Alignment:

Fill - The image will fill the preview box horizontally.

Left - The image will be aligned to the left of the preview box.

Center - The image will be positioned in the center of the preview box.

Right - The image will be aligned to the right of the preview box.

Vertical Alignment:

Fill - The image will fill the preview box vertically.

Top - The image will be aligned to the top of the preview box.

Center - The image will be positioned in the center of the preview box.

Bottom - The image will be aligned to the bottom of the preview box.

Specialized Blueprint Node Groups

Details

Usage Example

Background Blur is a widget you can add to the UI layout. Use this widget to provide an opportunity to surround its content with adjustable padding and apply a post-process Gaussian blur to all backgroun behind. Background Blur Widget can contain one child widget.

This page gives basic information about using and adjustment the Background Blur Widget in the UI layout. Also, get familiar with example of using and adjustment the Background Blur Widget below using Unreal Motion Graphics UI Designer (UMG).

Details

In the Details panel for a placed Background Blur widget, there are a couple of specific options that can be set, which pertain to the Widget:



Option

Description

Apply Alpha to Blur

If true, modulates the strength of the blur based on the widget alpha.

Blur Strength

Sets blurry level of the background. Larger numbers increase blur, resulting in a larger runtime cost on the GPU.

Low-Quality Fallback Brush

An image to draw (instead of applying a blur) when Low-Quality Override mode is enabled. You can enable Low-Quality Mode for background blurs by setting the cvar Slate.ForceBackgroundBlurLowQualityOverride to 1. This is usually done in the project's scalability settings.

Blur Radius

This is the number of pixels that will be weighted in each direction from any given pixel when computing the blur. A larger value is more costly but allows for stronger blurs.

Blur Corner

This is the number of pixels that will be weighted in each direction from any given pixel when computing the blur. A larger value is more costly but allows for stronger blurs.

Each of the aforementioned properties can also be set (or changed) at runtime through Blueprint Script.



The ability to set other appearance settings (such as Horizontal and Vertical Alignment), as well as any padding around the Widget, can also be defined.

Usage Example

In the following example, we use the Background Blur Widget to highlight a menu when the game is paused, blurring out the background.

For this, we add the Blur Widget with our simplified menu, using the Blur Strength value to determine the strength of background blur being applied.



Click here for full view

On our Menu Widget Blueprint's Graph, we create a script to handle how our menu reacts to button clicks.



Above, when we construct the widget, we are turning on the Mouse Cursor. When the Resume button is pressed, we hide the cursor, un-pause the game, and remove the menu from being displayed. When the Quit button is pressed, we quit the game. Inside of our player character's Blueprint (see below), we add a script to create and display the menu when a key is pressed. In this case, whenever P is pressed, the game is paused when the menu is displayed.



The result is the ability to pause the game and blur the background, keeping our menu intact for players to interact with.



We could also decrease the Blur Strength from 50 (above) down to 10 (below) to make the background slightly more visible.







In order to understand and use the content on this page, make sure you are familiar with the following topics:

Widget Type Reference

Description

Details

Functions

Debugging

Description

Widgets that are wrapped with an Invalidation Box allows the child widget geometry to be cached to speed up Slate rendering. Any widgets that are cached by an Invalidation Box are not pre-passed, ticked, or painted. In general, if you are looking to optimize your project, wrapping certain widgets with Invalidation Boxes may boost your performance (particularly for mobile projects or complicated UI displays). For widgets that do not change constantly, they can be placed inside an Invalidation Box and cached instead of considered during paint, tick, or prepass.

If the widget changes, however, it will become invalid and you will need to manually invalidate the cache which will throw it away essentially and force it to redraw on the next paint pass. Anything that changes the visual appearance of the widget requires it to be invalidated. The only exception to this is a change to the appearance that is not stored in the vertex buffer for those widgets (for example Materials, as changing a Material Parameter does not require invalidating the widget).

Details

In the Details panel for a placed Invalidation Box, there are a couple of specific options that can be set that pertain to the widget:



Option

Description

Cache Relative Transforms

Caches the locations for child draw elements relative to the invalidation box which adds extra overhead to drawing them every frame. However, in cases where the position of the invalidation boxes changes every frame, this can be a big saving.

Is Volatile

If true, prevents the widget or its child's geometry or layout information from being cached. If this widget changes every frame, but you want it to still be in an invalidation panel, you should make it as volatile instead of invalidating it every frame, which would prevent the invalidation panel from actually ever caching anything.

Regarding the Is Volatile check box, any widget can be set to be volatile. Volatile widgets act like normal Slate widgets pre-invalidation. They're redrawn every frame, including all their children. When combined with the invalidation panel, it allows you to care only about redrawing the most dynamic bits of the UI, as invalidating a whole panel could be far more costly.

Functions

When using an Invalidation Box, it is up to the user to call Invalidate through C++ or the Invalidate Layout And Volatility node (pictured below) on a child widget to force invalidation.



Currently, some core widgets do this automatically when certain properties are changed, however more will do it over time.

Debugging

You can debug your Invalidation Boxes using the Widget Reflector (CTRL+Shift+W) and clicking the Invalidation Debugging toggle.

SlateDebugger.Invalidate.Enable 1 is invoked, use SlateDebugger.Invalidate.ToggleLegend



Click image for full view.

With the Widget Reflector up and Invalidation Debugging on, you will see the following colors:

Color

Description

Yellow

Paint invalidated this frame.

Gray

Volatility invalidated this frame.

Cyan

ChildOrder invalidated this frame.

Black

RenderTransform invalidated this frame.

White

Visibility invalidated this frame.

Pink

Layout invalidated this frame for Invalidation Box.

Blue

Every widget was reordered.

Red

Fully re-updated.

SlateDebugger.InvalidationRoot.Enable



Above we have an image that is marked as volatile inside of a Border which is wrapped with an Invalidation Box. Since the image is marked as volatile, it can be updated dynamically during gameplay while the Border (or any other art assets that we wanted to appear around the image that do not change) is cached.

Specialized Blueprint Node Groups

UMG Styling

UMG Slots

Menu Anchor Properties

Usage Example

Menu Anchor is a widget you can add to the UI layout. With the help of Menu Anchor, you can adjust location of the pop-up menus on the screen.

This page gives basic information about using and adjustment the Anchor Menu Widget in the UI layout. Also, get familiar with example of using and adjustment the Anchor Menu Widget below using Unreal Motion Graphics UI Designer (UMG).

Menu Anchor Properties

Details Panel Options

In the Details panel for a placed Menu Anchor, there are a couple of specific options that can be set that pertain to the Widget:



Option

Description

Menu Class

The Widget Blueprint (pop-up) to spawn when the menu is called. Creates the widget freshly each time.

Placement

Several placement options use to determine the location of the created widget.

Fit in Window

If sets true, the Menu Anchor attempt to fit the menu inside the window.

Should Defer Painting After Window

Sets ability to defer painting after window content.

Use Aplication Menu Stack

If sets false, you can control the menu's lifetime yourself.

OnGetMenuContent

Allows for the customization of the pop-up by binding a function or property to the OnGetMenuContent Event which is called when the pop-up is summoned (see below).

OnGetUserMenuContent

Allows for the customization of the pop-up by binding a function or property to the OnGetUserMenuContent Event which is called when the menu content is requested.

OnMenuOpenChanged

Allows for the customization of the pop-up by binding a function or property to the OnMenuOpenChanged Event which is called when the opened state of the menu changes.

For the OnGetMenuContent Event and OnGetUserMenuContent Event, you can create and bind a function directly from the Details panel which will be called whenever the Menu Anchor is called. This allows you to provide extra functionality to the creation of your pop-up menu. For example, below we've run a check to determine if the player is "In Battle" and if not, we allow them to access the pop-up menu. If they are we do not allow them to access the pop-up menu.



Blueprint Functions

The Menu Anchor widget has some widget specific functions that can be called through script which are described below.



Option

Description

Close

Closes the menu if it is currently open.

Fit in Window

Sets the fitting of the Anchor Menu in window.

Get Menu Position

Returns the menu's position in world space.

Has Open Sub Menus

Returns wether the menu has open sub menus or not.

Is Open

Checks to see if the Target Menu Anchor is currently open and returns a Boolean.

Open

Opens the menu if it is currently closed.

Set Placement

Sets placement options use to determine the location of the created widget.

Should Open Due to Click

Returns wether the menu should be openable by clicking or not.

Toggle Open

This toggles the open state for the menu and can be used instead of opening/closing.

Usage Example

Say you wanted to create an Inventory Menu and have a pop-up appear when the player clicks on a item, as seen in the example below.

The first thing you would want to do is create what your pop-up menu looks like.



Above we created a simple Widget Blueprint called MenuPopUp that is comprised of three Buttons inside a Vertical Box.

Next you would need to create another Widget Blueprint for your Inventory Menu, which we called HUD below.



After you have created your Inventory Menu, you would also add the Menu Anchor Widget (located under Primitive).



You would then position the Menu Anchor where you want it to appear, we positioned and Anchored it to the right/center position.



In the Details panel for the Menu Anchor, you would set the Menu Class (or Widget Blueprint to spawn) as well as its placement options.



On the Graph tab, you would add OnClick Events for each of your Buttons and drag in the Menu Anchor widget.

Dragging off the Menu Anchor, you can call the Open function to open and display your specified Menu Class.



Check the Focus Menu option on the Open node to apply focus to the Menu Anchor Widget. In this case, the Menu Anchor Widget automatically closes when focus leaves the menu (which happens when you click anywhere else). This is a way of making the menu close when the user interacts with other areas of the screen.

After you have created the Inventory Menu, you would need to call that menu in-game somehow.

This could be through the Level Blueprint or (in our case) through the Default Pawn Class (which is set to use the MyCharacter Blueprint).



Above in our MyCharacter Blueprint, when the game is started we create the HUD Widget and store it as a variable called HUDWidget so we can access it later. We then set I to toggle between Add to Viewport and Remove from Parent to Display or Remove the Inventory Menu. We also set Show Mouse Cursor to enabled or disabled based on whether or not the Inventory Menu is open or not.

And finally inside the MenuPopUp Blueprint (your pop-up menu), adding some script to Close the Menu Anchor when the player presses a Button in the pop-up menu. Below when the pop-up is constructed, we get a reference to the MyCharacter Blueprint by Casting to it then promoting it to a variable called MyCharacterReference. With this reference we can then access the HUD



You would probably want to add some functionality for each of the buttons for your pop-up (instead of printing to the screen) that when pressed, does something. For example, perhaps the first button "uses" the item from the Inventory, while the second "drops" the item and the third "cancels" and returns the player to the Inventory Menu.

This is just one example, you could also change what causes the Menu Anchor to open. Instead of a button press, perhaps using the IsHovered function to determine if an object is being hovered over then opening the Menu Anchor and pop-up window to display a tool-tip or some other form of notification. In either case, this should get you started with using the Menu Anchor to display/remove pop-up widgets through script.

Specialized Blueprint Node Groups

UMG Styling

UMG Slots

Details

Usage Example

Wrap Box Widget is a widget you can add to the UI layout to arrange child widgets. Arrangement is from left to right. Widgets that exceed the width, will be placed on the next line.

This page gives basic information about using and adjustment the Wrap Box Widget in the UI layout. Also, get familiar with example of using and adjustment the Wrap Box Widget below using Unreal Motion Graphics UI Designer (UMG).

Details

In the Details panel of a Widget that is placed inside a Wrap Box, there are some settings that can be used to adjust how the Widget functions which are outlined below.



Option

Description

Padding

Sets the padding area between the slot and the content it contains.

Fill Empty Space

Determines if the slot should fill the remaining space on the line.

Fill Span when Less Than

This states that if the total available space in the wrap box drops below the specified threshold, the slot will attempt to fill the entire line. A value of 0 denotes that no filling will occur.

Horizontal Alignment

Sets the alignment of the object horizontally.

Vertical Alignment

Sets the alignment of the object vertically.

Force New Line

Sets current slot start on a new line.

Usage Example

The Wrap Box is useful when you want to arrange items within a container and have those items appear aligned and evenly spaced and automatically format the contents inside it based on the width of the container. Create a widget layout with this hierarchy to work with the example below.



Image below represents layout of created a "shop" screen of sorts where several items are presented to the player.



The white images above could represent different items that the player could buy when clicking on an item, then clicking the purchase button. In our example say we wanted to remove the item from the shop when it has been purchased or add an item to the shop when the "sell" button is pressed (of course you would probably want a pop-up menu to select the item you want to sell but this should convey the idea).

For example, "buying" and removing items would automatically update the window:

As would "selling" and adding items (automatically wrapping when reaching the max width of the window):

It could also be used to keep things inside it arranged when resizing the window:

While the Wrap Box only checks width to determine when to arrange the Widgets within it, you could also use this in combination with a Scroll Box which will add a scroll bar when the amount of Widgets within the window becomes cut off allowing the user to scroll down to see the remaining Widgets.

Behavior

How to Use Named Slot Widgets

1. Create a Template Widget Using Named Slots

2. Fill Named Slots Using Drag-and-Drop

3. Fill Named Slots With the Pre Construct Event

3a. Create the Binary Prompt Buttons

3b. Add the Binary Prompt Buttons Using Pre Construct

Expose on Instance Only

On Your Own

When creating a complex user interface, you might need to re-use heavily templated widgets. As an example, you could display a character's status alongside different sets of information depending on which UI or HUD it is used in. One version could need a large character portrait, another version could need a name-only bar for a more compact display, and another may need to show additional information about the character's statistics.

Named Slot Widgets are specialized for acting as placeholders in templated UI like the above example. When you add a Named Slot to a widget's hierarchy, it appears in the hierarchy of any child classes of that widget. This makes it possible to easily create multiple versions of a widget with different sub-widgets injected into them.



Example of using Named Slots to create multiple derivatives of the same UMG widget.

Alternatively, you can use your Named Slot to easily preview what your widget will look like with different sub-widgets added in, then fill the Named Slot at runtime depending on where it appears in your UI. In either case, Named Slots reduce the need for duplication in your UMG widget classes.

Behavior

Named Slots are containers that support only one child widget. When not holding a child, Named Slots display with their name in the center, surrounded by a dotted outline around their bounds.



This makes it easy to visualize the location and size of the Named Slot, and makes it easier to distinguish between multiple Named Slots.

You can drag and drop any widget as a child of your Named Slot to display it directly in the UMG Designer view. Additionally, unlike other widgets, Named Slots appear in the hierarchy of any widgets extended from their parent widget. This makes it easier to reference them and provides you with consistent visibility in the UMG Designer tab, no matter how deep in your widgets classes' hierarchy you are.



Alternatively, you can use the Pre Construct event to add a child widget through code.



Because Pre Construct runs when the widget displays in the UMG designer, you can also preview child widgets added with this method.

How to Use Named Slot Widgets

The following sections provide instructions on how to add a Named Slot to a widget and how to fill it in derived widgets. This example uses a template for a dialog box, usable for pop-up menus such as warnings or prompts.

1. Create a Template Widget Using Named Slots

First, create a simple dialog box widget using two Named Slots. One will hold interactive elements, while the other will hold content such as messages.

Create a new UMG Widget in the Content Browser. Name it UI_DialogBox_Template.

Open UI_DialogBox_Template, then change the Screen Size setting to Custom. Set the size to a width of 750 and a height of 175.



Add a Border to the hierarchy. Set its Appearance > Brush Color to solid black ( 0.0, 0.0, 0.0 ).



Add a Vertical Box inside your Border.

Add two Named Slot widgets to your Vertical Box. Name the first one Slot_Contentand the second one Slot_Interaction.

In each of your Named Slots, apply the following settings:

Size: Fill

Vertical Alignment: Fill Vertically

Horizontal Alignment: Fill Horizontally.



If you followed the instructions above, your widget should look like this:



The UI_DialogBox_Template widget as handled in the instructions above. Two Named Slots occupy a vertical box inside a border.

This serves as a base for other versions of the widget.

2. Fill Named Slots Using Drag-and-Drop

Next, create a derived widget and fill it with the needed elements for a warning prompt. This prompt needs do the following:

Display a warning about an operation the user is doing.

Provides Confirm and Cancel buttons so the user can choose whether to continue the operation.

As an example, this type of prompt would be used if the user changed their screen resolution, and would ask if they want to keep or discard changes. This section will guide you through building the layout for this type of widget using drag-and-drop operations in your Named Slots.

Create a new Blueprint derived from UI_DialogBox_Template. Call it UI_DialogBox_Warning.

Open the Designer tab for UI_DialogBox_Warning.

Add a Horizontal Box to Slot_Content.

Add an Image widget named Content_Image to Slot_Content's Horizontal Box. Give it the following settings:

Size: Auto

Horizontal Alignment: Left

Vertical Alignment: Top

Image Size: 64 x 64



The images shown use an icon created for this tutorial as an example. This is not included with the engine, and it is not required to follow along with the essential information in this tutorial, but you can make your own and apply it to Content_Image.

Add a Text widget named Content_Text to Slot_Content's Horizontal Box. Give it the following settings:

Size: Fill

Horizontal Alignment: Fill Horizontally

Vertical Alignment: Fill Vertically

Font > Size: 18



Set the Text field of Content_Text to say "Do you want to keep these changes?"

Put a Spacer between Content_Image and Content_Text and give it a width of 10.

Compile and save your widget. It should appear as follows:



The UI_DialogBox_Warning with a warning icon and text. Note that the original vertical box from the template is hidden, but the named slots are all visible.

3. Fill Named Slots With the Pre Construct Event

Finally, to provide the buttons for the warning dialog box, create a sub-widget with two buttons, then add it in the Pre Construct Event for UI_DialogBox_Warning.

The prompt's buttons consist of two buttons with text labels added to them. The following steps will walk you through constructing them in a way that will align them to the center of the prompt.

Create a new User Widget called UI_BinaryPromptButtons, then open it.

Change the Screen type to Custom, then set the Width to 500 and the Height to 75.



Add a Horizontal Box, then add two Size Box widgets inside it. Name them SizeBox_Button_Left and SizeBox_Button_Right.

Add a Spacer between SizeBox_Button_Left and SizeBox_Button_Right. Set its width to 40.

Give SizeBox_Button_Leftand SizeBox_Button_Rightthe following settings:

SizeBox_Button_Left

Size: Fill

Horizontal Alignment: Right

Vertical Alignment: Center

SizeBox_Button_Right

Size: Fill

Horizontal Alignment: Left

Vertical Alignment: Center

Both SizeBox widgets

Width Override: 150

Height Override: 50

This will center both boxes in the middle of the prompt.



Add a Button Widget to both Size Boxes. Name the left button ConfirmButton and the right button CancelButton.

Add a Text Widget to both buttons. Give both of them the following settings:

Font Size: 16

Color: Black ( 0.0, 0.0, 0.0 )

Set the text for ConfirmButton to say "Confirm" and set the text for CancelButton to say "Cancel."

Compile and save your widget. It should appear as follows:



Create an instance of the binary prompt widget on the Pre Construct Event in UI_DialogBox_Warning, then add it as a child of Slot_Interaction.

Open UI_DialogBox_Warning, then open the Graph tab to edit its Blueprint graph.

Add a Create Widget node. Set its Widget Class to UI_BinaryPromptButtonsand connect it to the Pre Construct function.

Add a Get Owning Player node and connect it to the Owning Player pin for the Create Widget node.

Drag from the Output pin and Promote it to a variable. Name it PromptButtonWidget.

Create a Get node for Slot_Interaction. Drag off its pin and create an Add Child node.

Connect PromptButtonWidget to the Add Child node.



The full Blueprint code used in the instructions above.

Compile and save your Widget Blueprint, then switch back to the Designer tab.



The completed UI_DialogBox_Warning widget.

Your button widget appears in place of the Named Slot as if its contents were added to the hierarchy.

Expose on Instance Only



The Expose on Instance Only setting is false by default. When you set it to true, you can access the Named Slot in any instances of your widget through code, but it will not appear in the hierarchy for any derived widgets.

As an example, in the UI_DialogBox_Template widget detailed above, if you set Slot_Interaction's Expose on Instance Only property to true, you can still access the Named Slot in the base Widget Blueprint normally. However, in derived classes such as UI_DialogBox_Warning, Slot_Interaction will not appear in the Hierarchy in the Designer tab.



However, you can still access Slot_Interaction through code. This can be useful if you want to enforce a specific function, event, or callback for populating the Named Slot.

If you set Expose on Instance Only to True on a Named Slot widget that is already being used in derived classes, the widgets you added will remain where you put them, but the Named Slot will not be visible in the hierarchy.

On Your Own

To explore more of the utility of Named Slots, try creating your own widget derived from UI_DialogBox_Template. The following screenshot shows an example of a prompt with a message and a single "Continue" button. This provides a way to tell the user that an operation – such as saving their game – is complete.



Alternatively, you can intentionally leave slots open for child classes to fill later. For example, instead of constructing the warning prompt all at once, you could construct a binary prompt with the Cancel and Confirm buttons in Slot_Interaction, but leave the Slot_Content slot open. You could then create derivatives that fill Slot_Content with different message layouts.





Specialized Blueprint Node Groups

Blueprints Visual Scripting



Example 1. Function Binding

Example 2. Property Binding

Example 3. Event Driven

It is recommended that you have a general understanding of the



When crafting your UI elements, it's best practice to think of ways you can optimize your content to increase performance and minimize inefficiencies. For example, based on the scope of your project, Property Binding may be fine for communicating information to your UI. However, if you have a more complex UI setup, or need to optimize your project, you may want to consider updating your UI on a need-to-know basis.

In this reference guide, we will examine three ways of communicating information to a HUD. While all three approaches accomplish the task, the third example presents the most cost effective way by moving the update process away from tick events, and instead manually updates information through the use of Event Dispatchers.

Example 1. Function Binding

For this example, we will take a look at updating Health/Energy for a player using Function Binding.

Here we have a basic Health/Energy setup.



With display in place, we Create Bindings for our progress bars called GetHealth and GetEnergy. The function bindings cast to the Player Character Blueprint and assign the variables we defined for Health and Energy.

Below is the binding for GetHealth. For debugging purposes, we also added a Print String node to print to the screen the value of our Health variable.



In the image below, you can see the Health and Energy values from the player character that are passed through and reflected in the HUD. However, you can also see that even when we are not updating the Health Value, the blue debug text illustrates that we are still checking the Health Value every frame.



Essentially, this approach is asking "What is the player character blueprint? And when I know what it is, "give me the values for health and energy" each frame. For smaller, less complex systems, this approach works well; however, if you are using a more complex system with multiple properties checking for updates every frame, this setup can lead to poor performance.

Example 2. Property Binding

The second approach is Property Binding, which is a bit more cost effective than Function Binding.

Using the same Health/Energy setup, let's examine how Property Bindings work.



In the Event Graph of our Widget Blueprint, we use the Event Construct to get a reference to the Player Character Blueprint.

By using Event Construct, we are casting to the Character Blueprint once and storing the information as a reference so the script does not have to call that information every frame.



Then, we can bind the values for the progress bars directly to the variables inside the Character Blueprint.



With this approach, we are no longer casting every frame and checking "what is the player character blueprint?" Instead, we are only querying the values for health and energy each frame.

Based on the scope of your project, this is approach can be efficient; however, if your system is more complex, then an Event Driven approach may be better.

Example 3. Event Driven

Here we take a look at using Events to update the HUD only when it changes, and we will continue with the same Health/Energy setup.



Inside the Character Blueprint, add an Event Dispatcher node to the end of the script that decrements our Health. In this example, the Event Dispatcher node is Call Update Health.

For testing purposes, Health is set to decrease whenever the F key is pressed.

We created a similar example in the Adjusting Character Variables section of our





Now, whenever we decrease our Health, we also call this Event Dispatcher. In the Event Graph of the HUD Widget Blueprint, we can use the Event Construct again to get and store a reference to the Player Character Blueprint. We can also Bind a Custom Event to the Event Dispatcher inside that Character Blueprint so that the Custom Event is called when the Event Dispatcher is called.



Click image for full view.

The Custom Event inside the HUD Widget Blueprint now only checks and updates the display of player's Health when it changes, rather than always checking the value regardless of whether or not it changed.

The image below shows how you can incorporate Health and Energy into the same Event Construct script.

The Custom Events UpdateHealth and UpdateEnergy are bound to Event Dispatchers from the Character Blueprint, which are only called when the character's Health/Energy value changes. We can also initialize the display by calling those two Custom Events when the HUD is constructed following the binding process.



Click image for full view.



Specialized Blueprint Node Groups

DPI Scaling

Scaling the UI to 1

Adding New Device Ratios

When working on the UI for a project, you may already have a targeted device in mind for releasing your project. In fact, you may want to release on multiple devices or platforms. In Unreal Engine, the automatic resolution-independent UI scaling using DPI Scaling rules enables you to create a resolution scale for multiple devices.

DPI Scaling enables you to define a DPI Scale Rule and a DPI Curve to automatically scale your UI elements based on varying resolutions. The DPI Scale Rule determines which scale to apply, and the DPI Curve contains different resolutions and respective scale values. Using these options makes it quick and easy to translate your UI screens from devices like a phone to a tablet or a PC, with a range of device resolutions.

In this how-to, we will set up our initial aspect ratio scale, and then add another device ratio to the scale.

For more information on DPI Scale Rules and Curve, see DPI Scaling.

Scaling the UI to 1

To scale the UI correctly, you need to designate an aspect ratio range for the first device and set its scale to 1.

For this how-to, we are using the First Person Template. However, you can use any project you wish.

Navigate to Content Browser > Add New > User Interface, create a Widget Blueprint called DPI_Widget.

Inside DPI_Widget, under the Screen Size drop-down menu, select a device aspect ratio.



For this example, we are going to use an Andriod phone as our first device for this guide.

The Screen Size options automatically update in UE4 based on approved and supported devices at the time of each version release.

Take note of the Resolution aspect ratio in the lower left corner, and the DPI Scale in the lower-right corner.



Click for Full view.

Typically, it is best to work on your UI elements in a scale of 1.0 and use the DPI Scaling Rule to scale up or down your UI elements.

Click the Gear icon in the lower right corner to open up the User Interface Settings window.



You can also access the User Interface Settings from the Project Settings of your project.

Under DPI Scaling, choose the DPI Scale Rule you prefer to use. In this example, we are using the Shortest Side of the viewport.



On the DPI Curve, find the key on the curve which reflects a Scale value of 1.0.



Set the Resolution based on the Scale Rule you designated. This example uses the smallest side, so the resolution is reset from 1080 to 496.



This is the base key, from which all other keys change in relation to. If the resolution value is slightly off, such as 496.000061, this is because we have not set a resolution range yet.

Select another key on the graph and set the Resolution to 1, and the scale to 495.



In order to make sure the UI elements are set correctly between different resolutions, we need this second key to set a designated resolution range for the UI to render correctly.

You can zoom in and out of the graph to get a detailed or high-level view of the range.

Return to your DPI_Widget Blueprint and, if it wasn't before, the DPI Scale for the device is now 1.0.

Adding New Device Ratios

With the initial aspect ratio set, you can now add more aspect ratios for different devices.

Select the Screen Size drop-down and select a different aspect ratio, such as a tablet or different phone brand.



Click for Full view.

In this example, we will use an iPhone.

In the User Interface Settings for the DPI Curve, hold Shift and Left-click and create two new keys.

In the first key, set the Resolution to 1079 and the Scale to 1.66.



In the second key, set the Resolution to 1090 and the Scale to 1.66.



To determine the new scale for these keys, we find the difference between the DPI Scale Rule of the first and new devices. In this example, we divide the new device's smallest side by the first device's smallest side, so we divide 828/496 for a new scale of 1.66.

When adding more devices, keep the same resolution for the new nodes of 1079 and 1090 as these are standard resolutions. The Scale is the variable that should change with each new device.

Your DPI Widget now includes an Andriod phone and an iPhone. Repeat this procedure to add new devices to your widget scaling.

If you are placing widgets and they are shifting off-screen, you may need to anchor your widgets to locations in the viewport. See Anchors for more information about anchoring widgets.

Specialized Blueprint Node Groups



1 - Project Setup

2 - Setting Up the Health Bar Widget

2.1 - Scripting the On Mouse Button Down Function

2.2 - Scripting the On Drag Detect Function

3 - Setting up the On Drop Function

4 - Scripting the Drag Widget

5 - Adding the HUD Widget to the Viewport

End Result

There may be instances in your project where you want your players to be able to interact with UI elements by dragging and dropping them onscreen. This could be to customize interface layouts (positioning health bars or unit frames) or interacting with gameplay systems like inventory screens (adding/removing items around). With UMG you can create these types of interactions with the DragAndDropOperation node and override some of the inherited Blueprint Functions based on your method of interaction.

In this example, we take a look at how a player can drag and reposition a health bar on screen with the Left Mouse Button. At the end of this guide, you will have a UI widget that you can drag around inside the viewport and drop at a new location.

In this tutorial, we will not be creating a functional Health Bar and this is intended for demonstration purposes only. See



1 - Project Setup

Before we get started, there are a couple assets that we need to create as part of our project setup. In this example, the element in our HUD that we want to drag and drop is the HealthBar. To do this, we will create a DragWidget in the same shape as our Health Bar rather than dragging the actual Health Bar around. This separates the Health Bar programming from the drag and drop function.

For this how-to guide, we are using the Blueprint Third Person template project.

In the Content Browser, create three Widget Blueprints called: DragWidget, HealthBar, and HUD.



Right-click in the Content Browser, create a new Blueprint Class for the DragDropOperation class, and call it WidgetDrag.



This specialized Blueprint Class enables us to pass through information as part of our drag and drop action.

Open the WidgetDrag Blueprint, and create a User Widget variable called WidgetReference. Check the boxes for Instance Editable and Expose on Spawn.



This will be used to hold the UMG Widget that we want to drag around on screen.

Create a Vector 2D variable called DragOffset. Check the boxes for Instance Editable and Expose on Spawn.



This offsets the location from where we start dragging and dropping the widget.

Compile and Save the WidgetDrag Blueprint.

Open the Drag Widget Blueprint, and create a User Widget variable called WidgetReference. Check the boxes for Instance Editable and Expose on Spawn.



Compile and Save the DragWidget Blueprint.

With our project setup done, next we will start working on the HealthBar Widget Blueprint which is the piece of UI that we want to be draggable.

2 - Setting Up the Health Bar Widget

In this step, we determine when the Left Mouse Button is pressed and store the location where it was pressed in screen space. We also use the DetectDragIfPressed node to determine if the player is dragging with a specified key.

Open the HealthBar Widget Blueprint, and delete the Canvas Panel in the Hierarchy window.

Add a Size Box and add a Progress Bar to the box. In the Details Panel for the Size Box, set the Width and Height Override to 500x50.



You can also stylize the Progress Bar yourself by setting the preview to Desired on Screen. Then set the Percent to 1.0 so the progress bar is filled and changes color.



2.1 - Scripting the On Mouse Button Down Function

This step enables us to determine if the player is dragging the Left Mouse Button.

In the Event Graph, add the OnMouseButtonDown and OnDragDetected overrides. This creates tabs for each of the overrides in the Event Graph.



There are several functions that you can override to call your own custom script. Here we will perform some checking when the Mouse Button is pressed and what happens when a widget drag is detected.

Select the OnMouseButtonDown tab. From the OnMouseButtonDown node, drag off the My Geometry pin and add the Absolute to Local node.

Drag off the Mouse Event pin and add the Get Screen Space Position node and connect the Return Value to the Absolute Coordinate pin.



This converts the absolute coordinates of the Health Bar widget to local space by getting the screen position where the mouse button registered a button down key press. This stores the location as a variable so we can determine where on the widget the player actually clicked and where it gets dropped.

Right-click the Return Value of the Absolute to Local node, and select Promote to Variable. Name the variable Drag Offset.



Don't worry if you see an error on the On Mouse Button Down node. Once we complete the function it will go away.

Right-click in the graph and add a Detect Drag if Pressed node. Set the Drag Key to Left Mouse Button.

Finish connecting the remaining pins.

Connect Mouse Event to Pointer Event.

Connect the Return Value pins from Detect Drag if Pressed to Return Node

Connect the Exec pins across the four nodes.



This determines if the player is dragging the Left Mouse Button, which will start the On Drag Detected script.

Compile and Save the HealthBar Blueprint.

2.2 - Scripting the On Drag Detect Function

In this step, we determine what happens when the player is, in fact, dragging the HealthBar around on the screen.

Select the OnDragDetected tab. From the OnDragDetected node, Right-click and add a Create Widget node. Set the Class to Drag Widget.



From the Widget Reference pin, connect a Self node. Promote the Return Value to a variable called Dragged Widget and connect the pins.



Now when we create the drag widget, it will have a reference to the existing Health Bar widget. We also promote the dummy drag widget to a variable so that we have access to it later and can remove it from the display when we choose to drop the widget.

Right-click and create a Drag & Drop Operation node. Set the Class to Widget Drag, and set Pivot to Mouse Down.



Pivot determines where the Drag Widget Visual appears while being dragged relative to the pointer performing the drag operation.

Connect the following nodes to the DragAndDropOperation node pins.

Exec line from the Dragged Widget Set through to the Return Node

Self to Widget Reference

Dragged Widget to Default Drag Visual

Drag Offset to Drag Offset



Above we indicated what Widget Blueprint is our reference and what the drag visual should be and provided an offset in which to start dragging. There is an offset pin on the node by default; however, we are using our own calculation to determine the position in which to start dragging when Mouse Button Down is pressed.

Compile and Save the HealthBar Blueprint.

Next, we need to do is to determine what happens when the player releases the Left Mouse Button and performs the OnDrop function.

3 - Setting up the On Drop Function

Here we set up our main HUD Widget Blueprint and override what happens when we perform the OnDrop function.

Open the HUD Widget Blueprint. In the Details panel for the Canvas Panel, set the Visibility to Visible.



We scripted the drag detection inside the Health Bar widget; however, when we release the Left Mouse Button we want to drop the bar in our HUD Widget Blueprint. In order for our HUD to receive the hit detection, we need to make the panel Visible.

From the Palette window, add the Health Bar widget to the Canvas.



In the Event Graph, add an OnDrop function override from the My Blueprint panel.



From the OnDrop node, drag off Operation and add a Cast to WidgetDrag node. Then, add a Get Widget Reference and connect the As Widget Drag pin to a Widget Reference and Drag Offset nodes.



This checks which type of operation is being performed as part of the OnDrop function. If it is Widget Drag we get the WidgetReference (which we passed through as the widget being dragged), as well as the DragOffset (or position in which we started the drag from).

From the My Geometry pin, add an Absolute to Local node. From the Pointer Event pin, add a GetScreenSpacePosition node.



This will tell us the position in 2D space where we released the Left Mouse Button to drop the widget. We will use this minus the DragOffset to determine where we should place the widget when it is dropped.

Add a Vector2D - Vector 2D node and subtract the DragOffset from the the Return Value of Absolute to Local.



Right-click and add Remove from Parent, Add to Viewport, and Set Position in Viewport nodes. Connect the Exec pins across all 3 modes in the order listed above, and connect the Set Position in Viewport node to the Return Node.

Make the following connections and adjustments:

Widget Reference pin to Target pin on all 3 nodes.

Return Value pin from the Vector2D - Vector 2D node to the Position pin.

Uncheck Remove DPIScale

Check Return Value



We uncheck Remove DPIScale and check the Return Value because we do not need to remove the DPI Scaling. We already handled this function, so we return as true. With this script, we first remove the existing Health Bar widget before re-adding it to the screen in the new location relative to our Drag Offset.

Compile and Save the HUD Widget Blueprint.

Our HUD is set up to handle dropping our dragged widget and it displays our Health Bar. Next, we set up our Dragged Widget to mimic the shape of our Health Bar as well as instruct our Character Blueprint to add the HUD to the viewport.

4 - Scripting the Drag Widget

In this step, we configure the DragWidget, which is the visual widget we will be dragging in the viewport.

Open the DragWidget Widget Blueprint and replace the Canvas Panel with a Size Box with a child Border.

Rename the SizeBox to WidgetSize, and set isVariable to true. Check both Width Override and Height Override.



We are going to set the Width and Height of the Size Box to reflect the size of our Health Bar widget.

Select Border, and set the Brush Color to Black with an Alpha of 0.5 for some transparency.



In this example, we will have a silhouette of our Health Bar as the drag visual while keeping the actual Health Bar in the same location.

In the Event Graph, off of Event Construct, add a Cast to HealthBar node. Drag in the Widget Reference and connect it to the Object pin.

From the As Health Bar pin, add a Get Desired Size node. Connect the Return Value pin to a Break Vector 2D node.



This gives us the size of our Health Bar and we can set the Size Box to the same size. We could have manually entered the overrides; however, if we change the size of our Health Bar we would then also have to change it here.

Right-click and add Set Height Override and Set Widget Override nodes and connect them respectively to the Cast to HealthBar node. Then, drag in the Widget Size node.

Connect the following pins:

Widget Size to both Target pins

Break Vector 2D X to In Height Override

Break Vector 2D Y to In Width Override



Compile and Save the DragWidget Blueprint.

5 - Adding the HUD Widget to the Viewport

Lastly, we need to add the HUD Widget Blueprint to the viewpoint in the Character Blueprint and enable the Mouse Cursor so we can see where we are dragging.

In the Content Browser under Content/ThirdPersonBP/Blueprints, open the ThirdPersonCharacter Blueprint.

Off the Event Begin Play node, add a Create Widget node and set the Class to HUD. Create an Add to Viewport node connect it to SET Show Mouse Cursor. Add a Get Player Controller node and connect the Return Value to the SET Target.



Compile, Save, and click the Play button to play with the drag and drop widget.

End Result

When you play in the Editor, you can left-click and drag the health bar on screen then drop it in a new location.

This is just an example of the elements you will need to start the Drag and Drop process. Additional checking may be needed to ensure that players do not drag the widget outside of Safe Zones or potentially on top of other widgets.

Common UI provides a toolbox for creating rich, multi-layered user interfaces with cross-platform support, such as those found in Fortnite. Its tools include:

A new library of Common UI Widgets that provide commonly used game functionality.

New style data assets that separate styling information from UI elements, making it easier to share styling among multiple UIs.

A new Input Routing system that can give UI widgets selective interactivity, making it easier to manage focus in multi-layered UIs.

Support for console-specific UI elements, such as button icons for a specific controller.

Cardinal navigation management for gamepads.

Refer to the pages below for more information about Common UI's intended use cases and how to get started using these tools.



Learn about the problems Common UI is designed to solve and how it solves them.



A first-time walkthrough of Common UI's core features.

Problems Common UI Solves

Navigating Multi-Layered Menus

Returning to the Correct Element

Console-specific UI Elements

Common UI's Features

Key Concepts

Input Routing

Nodes

Activatable Widgets

Further Reading

Content Examples

Common UI supports the development of cross-platform UIs with complex navigation, such as menus with layers, submenus, or popups. Originally developed for UI in Fortnite, this plugin is available to Unreal Engine users through the Plugins menu. This page details the use-cases Common UI was designed to address, and the main concepts that drive its design.

Problems Common UI Solves

Navigating Multi-Layered Menus

The image below shows an example of a complex menu:



This UI shows two blade menus overlaid on top of a tabbed UI in the background. The background UI still exists, but cannot be interacted with if the top layer exists. How is this selective interactivity achieved?

Meanwhile, input methods can vary between different platforms and controllers. On PC, users select the UI elements above by clicking them with a mouse cursor. On consoles, however, the user selects UI elements using cardinal navigation and button presses. How do we create a UI that works across multiple platforms, consoles, and PC?

Returning to the Correct Element



Suppose the user sees a popup like the one in the image above. Then, the user closes the popup. How does the UI return to the correct element for cardinal navigation? If the overlay UI beneath the popup is then closed, then it will again need to find somewhere to return to. The solution to this problem must be applicable in a wide variety of circumstances.

Console-specific UI Elements



In the image above, the UI displays the button to press for each interaction. However, these buttons' icons vary per console. How do we create a UI that is indifferent to console-specific UI elements?

Common UI's Features

Common UI's features are designed to address the problems listed above. With Common UI, you gain:

Selective widget interactivity, providing an easy way of creating rich UIs with layering.

Multiplatform console and PC support.

On consoles:

Cardinal navigation management, including breadcrumbs and history.

Console-specific UI element management.

Key Concepts

This section explains the design and main features of Common UI.

Input Routing

On consoles and PC, interactivity is determined by input. To achieve selective interactivity, CommonUI uses Input Routing, which only permits certain widgets to receive input, whether from a mouse or a gamepad, at a given time.



Input routing can also selectively distribute input across widgets. For instance, in the image above, the bumper buttons are always routed to the tab widget at the top, while the ‘X' action button is routed to the widget currently selected by cardinal navigation.

For a deeper look, refer to CommonGameViewportClient.h and CommonUIActionRouterBase.h in Common UI's source code.

Nodes

Common UI routes inputs to whatever UI widget is visually rendered on top. Common UI converts widgets into nodes, which handle input routing based on visual and logical hierarchies.

Nodes are organized into trees which, with a few exceptions, match the Slate hierarchy. Each tree consists of a root node, usually represented with a widget placed directly in the Viewport, as well as leaf nodes, usually represented with individual UI elements like buttons.

Once per tick, Common UI finds the tree of nodes painted higher than any other tree, then sends input to that tree's root node. That root widget will then forward input to the first leaf widget within the tree ready to handle input, which will then process the input or forward it again if needed.



For a deeper look, see UIActionRouterTypes.h.

Activatable Widgets

Within Common UI, only certain widgets are converted into nodes for the purpose of handling input, and only widgets that are ready to handle input receive input. These widgets are called activatable widgets, and they are considered active if they are ready to receive input.

Activatable Widgets:

Can be toggled between active or inactive states, indicating if they are ready to receive input.

Can forward input to other activatable widgets within the same tree.

Can deactivate automatically when appropriate, such as when handling back actions.

With activatable widgets, if the user dismisses an overlay UI that is currently receiving input, the issue of returning to the correct element is trivial. Since input is only routed to the highest painted tree, we can leave widgets active without concern if they are on a lower UI layer. Once that upper level UI is dismissed, Common UI routes input to the still-active widgets in the next-highest UI layer.

For a deeper look, refer to CommonActivatableWidget.h.

Further Reading

For detailed information about how to set up Common UI for first-time use, refer to the Common UI Quickstart Guide.

Content Examples

For a basic example of Common UI in action, look at the Common UI content sample. For a more advanced example that includes a full frontend menu, download the Lyra sample project.

1. Viewport Input Routing Setup

2. Creating an Input Action Data Table

3. Default Navigation Action Setup

4. Controller Data Binding (Platform-Specific UI Elements)

5. Common UI Widget Library and Widget Styling

This page provides a walkthrough for how to set up Common UI in your project. You will learn the following in this guide:

Setting up your viewport to support Input Routing.

How to create Input Action Data Tables, which map controller buttons to actions within your UI.

How to set up Default Navigation Actions, which support global click and back button functionality.

How to create Controller Data Assets and assign them to specific types of controllers on specific platforms.

1. Viewport Input Routing Setup

The Viewport is the base for all input routing in Common UI. When Common UI captures input, it sends it to the Viewport first, which then sends it to whichever root node is drawn on top. To support this functionality, perform the following setup steps:

Open Edit > Project Settings > Engine > General Settings.

Set your Game Viewport Client Class to CommonGameViewportClient.



If you need your own custom game viewport class, you will need to extend it from CommonGameViewportClient to use Common UI.

2. Creating an Input Action Data Table

Common UI uses Input Action Data Tables to create named actions that can be associated with various platform-specific inputs. For examples, see GenericInputActionDataTable in Common UI's content folder, or NavigationInputActionDataTable in the Content Example project.

Common UI's Input Action Data Tables are not related to the input actions used in Project Settings or the Advanced Input System. They are exclusively used for managing UI input.

Right-click in the Content Browser, then click Miscellaneous > Data Table Asset.

Select CommonInputActionDataBase as your row structure, then click OK to create a new Input Action Data Table.



To add a new Input Action row, click Add in the top bar.



Populate the Input Action with a name and information about which keys activate it.

Input Actions consist of the following parameters:



Parameter

Description

Display Name

Name of input action. Displayed in Nav-bar if present.

Hold Display Name

Name of the input action if it requires the user to hold the button down.

Nav Bar Priority

Priority used when sorting actions in Nav-bar from left to right.

Keyboard Input Type Info

Key used for this action when using Mouse & Keyboard, if any.

Default Gamepad Input Type Info

Key used for this action when using Gamepad, if any.

Gamepad Input Overrides

Key used for this action on a specific gamepad. Useful for platform-specific button overrides, such as swapping the back and forward buttons for the gamepad on the Nintendo Switch.



Touch Input Type Info

Key used for this action when using a touch interface, if any.

Common UI widgets map these abstract actions to actual inputs. For example, you can add a data table and row name reference to the Triggering Input Action in the CommonButtonBase widget. After that, pressing the button associated with that action will activate the Common UI button.



For fewer version control conflicts, group related sets of actions into their own data tables. For example, put all menu navigation actions into one table together, then put actions for more specialized menus into their own tables as well. After that, create a single composite data table that references those data tables.

3. Default Navigation Action Setup

Cardinal navigation is natively supported by Unreal Engine. However, Common UI uses the Common UI Input Data asset to define universal Click and Back input actions that are used across all platforms.

Create a new Blueprint Class in the Content Browser.

Search for CommonUIInputData and click Select to create a new Blueprint.

Assign an appropriate Data Table containing your default Click and Back actions.



Assign this asset to Project Settings > Game > Common Input Settings > Input Data.



The asset specified above will be loaded by Common UI and used for default navigation. The designated Click button substitutes for mouse clicks when highlighting buttons or other interactable elements, and the designated Back button is universally used for navigating backward from your current menu to a previous one.

4. Controller Data Binding (Platform-Specific UI Elements)

Controller Data Assets associate key-actions with UI elements. Each Controller Data Asset is associated with an input type, gamepad, and platform. CommonUI uses this information to automatically use the correct platform-specific UI elements based on the current platform and input type. Optionally, for platforms that support multiple input types or unique gamepads, it can also use the user's input to find the correct gamepad and swap its UI elements at runtime.

Right-click in the Content Browser and create a new Blueprint Class.

Search for CommonInputBaseControllerData and click Select to create a new Controller Data Asset.

Populate the Controller Data Asset with assets and information about one of the controllers you plan to support.



Parameter

Description

Input Type

Set this to Gamepad, Mouse and Keyboard, or Touch.

Gamepad Name

If the controller is a Gamepad, this will be the platform this gamepad corresponds to. The default Gamepad is called Generic.

Input Brush Data Map

Mapping of keys to UI elements and Icons.

Input Brush Key Sets

Mapping of multiple keys to a single UI element. Useful for D-Pads and other inputs that can potentially map to different axes.

Once you have created Controller Data for all inputs you plan to support, these classes must be added to their associated platforms under Project Settings > Game > Common Input Settings > Platform Input.



The Default Gamepad Name must exactly match the Gamepad Name field in one of your Controller Data Assets, otherwise it will not be recognized and its icons will not appear.

Assign each gamepad's data to the Controller Data array for its corresponding platform. You can have multiple gamepads associated with a single platform. For example, PC games would typically support a mouse and keyboard Controller Data as well as a generic gamepad. However, you can also add Controller Data for specific gamepad models.

5. Common UI Widget Library and Widget Styling

Common UI has a library of widgets, listed under the Common UI Plugin section in UMG's Palette. Many of these are pieces of UI functionality that are commonly reproduced in many games and applications, including:

Specialized text blocks for date / time and numeric values.

Navigation and visibility aids like carousels and animated switchers.

Platform aids like a loading guard and a hardware visibility border.

Widgets that provide basic functionality, like buttons and text, but that use style data assets for styling.

None of these widgets have the styling options of their equivalent base UMG widgets. Instead, they reference Common Style Assets, making it possible to apply a consistent style across multiple menus and HUDs. Any changes you make to a style asset will take effect on every Common UI widget that uses it.

To make a common style asset:

Right-click in the Content Browser and create a Blueprint, then select one of the Common Style classes as the base.



Populate its Details with the styling information that you want to apply to Common UI widgets. These are typically the same as the styling options on standard UMG widget.



Assign it to a Common UI widget of the appropriate type. For example, if you create a Common Text Style asset, you would assign it to the Style field in the Common Text Widget.



You can also assign these to the Template Styles in Project Settings > Plugins > Common UI Editor.



Any Common UI widgets that you have not manually assigned a style will use the appropriate Template Style instead. This makes it easy to create a global default style for your application.

The Project Settings > Plugins > Common UI Framework menu features several more global assets, including a Default Throbber Material that is used in loading screens, and a Default Image Resource Object that displays as a placeholder for UI assets that have not been loaded.



Abilities, Tasks, Attributes, and Effects

System Setup

The Gameplay Ability System is a highly flexible framework for building the types of abilities and attributes that you might find in an RPG or MOBA title. You can build actions or passive abilities for the characters in your games to use, and status effects that can build up or wear down various attributes as a result of these actions, additionally you can implement "cooldown" timers or resource costs to regulate the usage of these actions, change the level of the ability and its effects at each level, activate particle, sound effects, and more. The Gameplay Ability System can help you to design, implement, and efficiently network in-game abilities from as simple as jumping to as complex as your favorite character's ability set in any modern RPG or MOBA title.

Abilities, Tasks, Attributes, and Effects

Gameplay Abilities are C++ or Blueprint children of the UGameplayAbility class. They define what the Ability does in C++ code or Blueprint scripting, in addition to establishing how elements of the Ability should be treated, such as replication and instancing behaviors.

The logic within a Gameplay Ability will generally call a series of asynchronous building blocks, known as Ability Tasks during the course of the logic that defines the Ability. These tasks are derived from the abstract UAbilityTask class. Ability Tasks are written in C++, and frequently call one of several delegates(in Cpp) or output execution pins (in Blueprints) when they complete their work. For example, an Ability that requires a target might have an "aim" task with one delegate or output pin for confirming the target, and another for canceling the Ability.

In addition to Gameplay Abilities, the Gameplay Ability System also supports Gameplay Attributes and Gameplay Effects. Gameplay Attributes are float values stored within the FGameplayAttribute structure that influence the game or the Actor in some way; these are typical values like health, strength, jump height, attack speed, and so on. Gameplay Effects provide a way to alter Gameplay Attributes instantaneously or over time (commonly known as "buffs" and "debuffs"), such as subtracting magic points when casting a spell, granting a movement speed boost while a "Sprint" Ability is active, or gradually restoring health points over the lifetime of a dose of healing medicine.

Any Actor that interacts with the Gameplay Ability System must have an Ability System Component. This Component will activate Abilities, store Attributes, update Effects, and handle interactions between Actors. Once you have enabled the Gameplay Ability System and created an Actor that includes an Ability System Component, you can begin creating Abilities and determining how Actors should react to them.

System Setup

The Gameplay Ability System exists as a Plugin, therefore you will need to opt-in to use it. To enable the plugin, follow the two steps below:

Enable the Gameplay Ability System Plugin in the Edit -> Plugins window.

To get the full range of capabilities of this system, add "GameplayAbilities", "GameplayTags", and "GameplayTasks" to PublicDependencyModuleNames in your project's "(ProjectName).Build.cs" file. This is easy to do by finding the list of public modules:

To use the Gameplay Ability System, add the three module names anywhere in the braced list, as follows:

The Ability System Component is the main interface through which your game's characters will access the Gameplay Ability System. This Component manages Gameplay Attributes, runs Gameplay Events, stores Gameplay Abilities, and even handles binding player input to Gameplay Ability activation, confirmation, and cancelation commands. Any Actor that is intended to interact with the Gameplay Ability System will require an Ability System Component.



Using the Ability System Component with Gameplay Attributes and Attribute Sets



Overview of the Gameplay Ability class.



Using Gameplay Attributes and Attribute Sets



Overview of Attributes and Effects within the Gameplay Ability System.



Guides for learning the basics of how the Gameplay Ability System works.



Overview of the Ability Task class.

Basic Requirements

Setup Example

Advanced Usage Scenarios

The Ability System Component (UAbilitySystemComponent) is the bridge between Actors and the Gameplay Ability System. Any Actor that intends to interact with the Gameplay Ability System needs its own Ability System Component, or access to an Ability System Component owned by another Actor. Make sure that your project is set up to use the [Gameplay Ability System Plugin][making-interactive-experiences\GameplayAbilitySystem] before attempting to use the Ability System Component.

Basic Requirements

To set up your AActor subclass to use the Gameplay Ability System, implement the IAbilitySystemInterface interface and override the GetAbilitySystemComponent function. This function must return the Ability System Component associated with your Actor. In most cases, the Actor class will have a variable, tagged with UPROPERTY, that stores a pointer to the Ability System Component, similar to any built-in Component on any Actor type. While it is common for an Actor to have its own Ability System Component, there are cases in which you might want an Actor, such as a player's Pawn or Character, to use an Ability System Component owned by another Actor, like a Player State or Player Controller. Reasons for this may include things like a player's score, or long-lasting ability cooldown timers that do not reset when the player's Pawn or Character is destroyed and respawned, or when the player possesses a new Pawn or Character. The Gameplay Ability System supports this behavior; to implement it, write the Actor's GetAbilitySystemComponent function so that it returns the Ability System Component you want to use.

Setup Example

The following procedure will help you to get started with a simple but common pattern that utilizes the Ability System Component.

Declare your class as a child of AActor or a subclass (APawn and ACharacter are common base classes), and add the IAbilitySystemInterface to its definition in the header file, like this:

class AMyActor : public AActor, public IAbilitySystemInterface

The IAbilitySystemInterface has a single function which you must override, GetAbilitySystemComponent, so declare that function in your class definition.

In some cases, especially those where an Actor can be destroyed and respawned, you may want to keep the Ability System Component elsewhere, such as the Player State. For simplicity, this example will store it on the Actor.

In the source file for your Actor, write the GetAbilitySystemComponent function. Since the Ability System Component is stored on the Actor, the function will be very short, like this:

Advanced Usage Scenarios

You can set up an Actor to use an Ability System Component that belongs to another Actor, such as a Pawn that uses an Ability System Component that its Player State owns. To do this, the Actor's GetAbilitySystemComponent function must retrieve the Ability System Component from the owner, or you must cache it on the Actor in advance. This happens most often in projects where player-controlled Actors can be destroyed and respawned, and the player needs certain Gameplay Ability System information, such as money, points, or long ability cooldowns, to persist. It can also be used in projects where Actors attach other Actors to themselves to represent equipment or modular machine or body parts; in these cases, Gameplay Ability System interactions with the attached Actors can route to the main Actor's Ability System Component. A simple way to accomplish this to have the attached Actor's GetAbilitySystemComponent function pass through to the the main Actor; for better performance, consider maintaining a cached pointer while your Actor is attached to (or possessed by) another Actor.

Although the Gameplay Ability System supports multiple Actors sharing a single Ability System Component, it does not support a single Actor having multiple Ability System Components. Doing this would result in ambiguity when querying, applying changes to an Actor's Ability System Component, or even retrieveing the Component from the Actor.

Granting and Revoking Abilities

Basic Usage

Tags

Replication

Instancing Policy

Triggering with Gameplay Events



A Gameplay Ability, derived from the UGameplayAbility class, defines what an in-game ability does, what (if anything) it costs to use, when or under what conditions it can be used, and so on. Because Gameplay Abilities are capable of existing as instanced objects running asynchronously, you can run specialized, multi-stage tasks involving character animation, particle and sound effects, and even branching based on player input or character interactions that occur during execution. Gameplay Abilities can replicate themselves across the network, run on client or server machines (including client-side prediction support), and even sync variables and make Remote Procedure Calls (RPCs). Gameplay Abilities also provide flexibility in terms of how the Engine implements them during a game session, such as extensible functionality to implement cooldown and usage costs, player input, animation with Anim Montages, and reacting to the Ability itself being granted to an Actor.

Granting and Revoking Abilities

Before an Actor can use an Ability, its Ability System Component must be granted that Ability. The following Ability System Component functions can grant access to an Ability:

GiveAbility: Specifies the Ability to add with an FGameplayAbilitySpec, and returns an FGameplayAbilitySpecHandle.

GiveAbilityAndActivateOnce: Specifies the Ability to add with an FGameplayAbilitySpec, and returns an FGameplayAbilitySpecHandle. The Ability must be instanced and able to run on the server. After attempting to run the Ability on the server, a FGameplayAbilitySpecHandle will be returned. If the Ability did not meet the required criteria, or if it could not execute, the return value will be invalid and the Ability System Component will not be granted the Ability.

The following functions can revoke access to an Ability from an Ability System Component, using the FGameplayAbilitySpecHandle that was returned when the Ability was granted:

ClearAbility: Removes the specified Ability from the Ability System Component.

SetRemoveAbilityOnEnd: Removes the specified Ability from the Ability System Component when that ability is finished executing. If the Ability is not executing, it will be removed immediately. If the Ability is executing, its input will be cleared immediately so that the player cannot reactivate or interact with it any further.

ClearAllAbilities: Removes all Abilities from the Ability System Component. This function is the only one that does not require an FGameplayAbilitySpecHandle.

Basic Usage

A Gameplay Ability's basic execution lifecycle, after being granted to an Actor's Ability System Component, looks like this:

CanActivateAbility lets the caller know whether or not an Ability is available for execution without attempting to execute it. For example, your user interface may need to gray out and deactivate icons that the player can't use, or play a sound or particle effect on the character to show that a certain Ability is available.

CallActivateAbility executes the game code associated with the Ability, but does not check to see if the Ability should be available. This function is usually called in cases where some logic is needed between the CanActivateAbility check and the execution of the Ability.

The main code that users need to override with their Ability's custom functionality is either the C++ function called ActivateAbility, or the Blueprint Event called Activate Ability.

Gameplay Abilities do not carry out their primary work in a "tick" function like Actors and Components do. Instead, they launch Ability Tasks during activation which do most of the work asynchronously, and then handle the output of those Tasks by hooking into Delegates (in C++) or connecting nodes to output execution pins (in Blueprints).

The CommitAbility function, if called from within Activate, will apply the cost of executing the Ability, such as by subtracting resources from Gameplay Attributes (such as "magic points", "stamina", or whatever fits your game's systems) and applying cooldowns.

CancelAbility provides a mechanism to cancel the Ability, although the Ability's CanBeCanceled function can reject the request. Unlike CommitAbility, this function is available for callers outside of the Ability itself. A successful cancelation will broadcast to On Gameplay Ability Cancelled before going through the standard code path for ending the Ability, giving the Ability a chance to run special cleanup code or otherwise behave differently when canceled than it would if it had ended on its own terms.

TryActivateAbility is the typical way to execute Abilities. This function calls CanActivateAbility to determine whether or not the Ability can run immediately, followed by CallActivateAbility if it can.

EndAbility (in C++) or the End Ability node (in Blueprints) shuts the Ability down when it is finished executing. If the Ability was canceled, the UGameplayAbility class will handle this automatically as part of the cancelation process, but in all other cases, the developer must call the C++ function or add the node into the Ability's Blueprint graph. Failing to end the ability properly will result in the Gameplay Ability System believing that the Ability is still running, and can have effects such as preventing future use of the Ability or any Ability that it blocks. For example, if your game has a "Drink Health Potion" Gameplay Ability that doesn't end properly, the character using that Ability will be unable to take any action that drinking a health potion would prevent, such as drinking another potion, sprinting, climbing ladders, and so on. This Ability blockage will continue indefinitely, since the Gameplay Ability System will think that the character is stil busy drinking the potion.

For information about setting this up in a Unreal Engine project, check out Gameplay Abilities in Action RPG.

Tags

Gameplay Tags can help to determine how Gameplay Abilities interact with each other. Each Ability possesses a set of Tags that identify and categorize it in ways that can affect its behavior, as well as Gameplay Tag Containers and Gameplay Tag Queries to support these interactions with other Abilities.

Gameplay Tag Variable(s)

Purpose

Cancel Abilities With Tag

Cancels any already-executing Ability with Tags matching the list provided while this Ability is executing.

Block Abilities With Tag

Prevents execution of any other Ability with a matching Tag while this Ability is executing.

Activation Owned Tags

While this Ability is executing, the owner of the Ability will be granted this set of Tags.

Activation Required Tags

The Ability can only be activated if the activating Actor or Component has all of these Tags.

Activation Blocked Tags

The Ability can only be activated if the activating Actor or Component does not have any of these Tags.

Target Required Tags

The Ability can only be activated if the targeted Actor or Component has all of these Tags.

Target Blocked Tags

The Ability can only be activated if the targeted Actor or Component does not have any of these Tags.

Replication

Gameplay Abilities support replication of internal state and Gameplay Events, or to turn replication off and save network bandwidth and CPU cycles. The Ability's Gameplay Ability Replication Policy can be set to "Yes" or "No", and this will control whether the Ability replicates instances of itself, makes state updates, or sends Gameplay Events across the network. For multiplayer games with Abilities that do replicate, there are a few options for how replication is handled, known as the Gameplay Net Execution Policy:

Local Predicted: This option provides a good balance of responsiveness and accuracy. The Ability will run on the local client immediately upon the client issuing the command, but the server will have the final word, and can override the client in terms of what the Ability's actual impact was. The client is effectively asking permission from the server to execute the Ability, but also proceeding locally as if the server is expected to agree with the client's view of the outcome. Because the client is locally predicting the behavior of the Ability, it will feel perfectly smooth and lag-free as long as the server does not contradict the client's prediction.

Local Only: The client simply runs the Ability locally. There is no replication to the server, although the Ability will run on the server if the client using it is the host (playing on the physical server machine), or if this is a single-player game. This does not apply to dedicated-server games, as there is never a client playing on the server machine. Anything the client affects with this Ability will still follow normal replication protocol, including potentially receiving corrections from the server.

Server Initiated: Abilities that initiate on the server will propagate to clients. These are often more accurate, from the client's perspective, to what is actually happening on the server, but the client using the Ability will observe a delay due to the lack of local prediction. While this delay should be very short, some types of Abilities, especially rapidly-performed actions in pressured situations, will not feel as smooth as they would in Local Predicted mode.

Server Only: "Server Only" Abilities will run on the server, and will not replicate to clients. Any variables these Abilities change will replicate as they normally do, meaning that the Ability can affect server-authoritative data, which will then propagate to the clients. In this way, the Ability can still have effects that clients observe, even though the Ability itself will only run on the server.

Instancing Policy

When a Gameplay Ability executes, a new Object (of the Ability's type) will usually spawn to track the Ability in progress. Since Abilities can execute very frequently in some cases, such as battles between a hundred or more players and AI characters in Battle Royale, MOBA, MMO, or RTS games, there may be cases where rapid creation of Abiltiy Objects can negatively impact performance. To address this, Abilities have a choice of three different instantiantion policies, offering tradeoffs between efficiency and functionality. The three supported instancing types supported are:

Instanced per Execution: A copy of the Ability's Object will spawn each time the Ability runs. The advantage to this is that you can use Blueprint graphs and member variables freely, and everything will be initialized to default values at the beginning of the execution. While this is the simplest instancing policy to implement, it is ideal for Abilities that run infrequently due to the larger overhead involved. For example, an "Ultimate" in a MOBA would be a reasonable use case, as there tends to be a long cooldown (usually 60-90 seconds) between executions, and there are only a few characters (usually about ten) who can use these Abilities at all. A basic attack Ability used by the computer-controlled "minions" would be a poor candidate, as there may be hundreds of them at a time, and each can issue basic attacks fairly frequently, causing rapid creation (and possibly replication) of new Objects.

Instanced per Actor: Each Actor will spawn one instance of this Ability when the Ability is first executed, and future executions will reuse it. This creates the requirement to clean up member variables between executions of the Ability, but also makes it possible to save information across multiple executions. Per-Actor is ideal for replication, as the Ability has a replicated Object that can handle variable changes and RPCs, but does not waste network bandwidth and CPU time spawning a new Object every time it runs. In larger-scale situations, this policy performs well, since large numbers of Actors using the Ability (for example, in a big battle) will only spawn Objects on their first Ability use.

Non-Instanced: This is the most efficient instancing policy in all categories. The Ability will not spawn any Object when it runs, and will instead use the Class Default Object. However, this efficiency introduces several restrictions. First, this policy uniquely requires that the Ability is written entirely in C++, as Blueprint Graphs require an Object instance. You can create Blueprint classes of a non-instanced Ability, but only to change the default values of exposed Properties. Further, the Ability must not change member variables or bind Delegates during its execution of the Ability. The Ability also cannot replicate variables or handle RPCs. This should be used only for Abilities that require no internal variable storage (although setting Attributes on the user of the Ability is possible) and don't need to replicate any data. It is especially well-suited to Abilities that run frequently and are used by many characters, such as the basic attack used by units in a large-scale RTS or MOBA title.

Triggering with Gameplay Events

Gameplay Events are data structures that can be passed around to trigger Gameplay Abilities directly, sending a data payload for context, without going through the normal channels. The usual way to do this is by calling Send Gameplay Event To Actor and providing an Actor that implements the IAbilitySystemInterface interface and the contextual information that Gameplay Events require, but it is also possible to call Handle Gameplay Event directly on an Ability System Component. Because this isn't the normal path to calling Gameplay Abilities, context information that the Ability may need will be passed in through the FGameplayEventData data structure. This structure is generic and will not be extended for any specific Gameplay Event or Ability, but should be sufficient for any use case. The polymorphic ContextHandle field will provide support for additional information as needed.

When a Gameplay Ability is triggered by a Gameplay Event, it will not run through the Activate Ability code path, but will instead use Activate Ability From Event, which provides the additional context data as a parameter. Be sure to handle this code path if you want your Ability to respond to Gameplay Events, but also be aware that, once implemented in your Gameplay Ability's Blueprint, Activate Ability From Event will replace Activate Ability, taking all activation traffic through itself.

Ability System Component And Attributes

Gameplay Attributes

Attribute Sets

Definition and Setup

Initialization

Importing Data Tables

Manually Populating Data Tables

Controlling Gameplay Attribute Access

Interactions with Gameplay Effects

Replication

The Gameplay Ability System uses Gameplay Attributes (FGameplayAttribute) to store, calculate, and modify gameplay-related floating-point values. These values can describe any trait of their owners, such as a character's remaining health points, a vehicle's top speed, or the number of times an item can be used before it breaks. Actors in the Gameplay Ability System store their Gameplay Attributes in an Attribute Set, which helps to manage interactions between Gameplay Attributes and other parts of the system, and registers itself with the Actor's Ability System Component. These interactions include clamping to value ranges, performing calculations that apply temporary value changes, and reacting to events that permanently alter their base values.

Gameplay Attributes

Gameplay Attributes keep a current and base value. The "current" value is commonly used in calculations and logic that use and can be affected by any Gameplay Effects that are currently active, while the "base" value is more likely to remain fixed for a longer period. As an example, a "Jump Height" Gameplay Attribute might have a base value of 100.0, but if the character has an active Gameplay Effect stating that they're tired and can only jump to 70% of their normal height, then the current value would be 70.0. If that character becomes skilled at jumping through a level-up system, then the base value might increase to 110.0, while the current value would be calculated as 77.0 as long as the Gameplay Effect remains.

To create Gameplay Attributes, you must first establish an Attribute Set. You can then add your Gameplay Attributes into the Attribute Set.

In some cases, Gameplay Attributes can exist without an Attribute Set. This generally indicates that a Gameplay Attribute has been stored on an Ability System Component that does not have an Attribute Set containing the appropriate type of Gameplay Attribute. This is not recommended, because the Gameplay Attribute will have no defined behaviors that interact with any part of the Gameplay Ability System other than being storage for a floating-point value.

Attribute Sets

Definition and Setup

To begin, set up an Attribute Set with one or more Gameplay Attributes, and register it with your Ability System Component.

Extend the base Attribute Set class, UAttributeSet, and add your Gameplay Attributes as FGameplayAttributeData UProperties. A simple Attribute Set with one Gameplay Attribute might look like this:

Store the Attribute Set on the Actor, and expose it to the engine. Use the const keyword to ensure that code cannot modify the Attribute Set directly. Add this to your Actor's class definition:

/** Sample Attribute Set. */ UPROPERTY() const UMyAttributeSet* AttributeSet;

Register the Attribute Set with the appropriate Ability System Component. This happens automatically when you instantiate the Attribute Set, which you can do in the Actor's constructor, or during BeginPlay, as long as the Actor's GetAbilitySystemComponent function returns a valid Ability System Component at the moment of instantiation. You can also edit the Actor's Blueprint and add the Attribute Set type to the Ability System Component's Default Starting Data. A third method is to instruct the Ability System Component to instantiate the Attribute Set, which will then register it automatically, as in this example:





Finally, applying a Gameplay Effect that modifies a Gameplay Attribute that the Ability System Component doesn't have will cause the Ability System Component to create a matching Gameplay Attribute for itself. However, this method does not create an Attribute Set or add the Gameplay Attribute to any existing one.

As an optional step, add some basic helper functions to interact with the Gameplay Attribute. It is a good idea to make the Gameplay Attribute itself protected or private, while leaving the functions that interact with it public. The Gameplay Ability System provides a set of macros to set up some default functions:

Macro (with Parameters)

Signature of Generated Function

Behavior/Usage

GAMEPLAYATTRIBUTE_PROPERTY_GETTER(UMyAttributeSet, Health)

static FGameplayAttribute GetHealth()

Static function, returns the FGameplayAttribute struct from the engine's reflection system

GAMEPLAYATTRIBUTE_VALUE_GETTER(Health)

float GetHealth() const

Returns the current value of the "Health" Gameplay Attribute

GAMEPLAYATTRIBUTE_VALUE_SETTER(Health)

void SetHealth(float NewVal)

Sets the "Health" Gameplay Attribute's value to NewVal

GAMEPLAYATTRIBUTE_VALUE_INITTER(Health)

void InitHealth(float NewVal)

Initializes the "Health" Gameplay Attribute's value to NewVal

After adding these, your Attribute Set class definition should look like this:

Although these helper functions are not strictly required, they are considered a best practice.

This establishes a basic Attribute Set with a single Gameplay Attribute. You will also need to implement code that controls the behavior of your Gameplay Attributes based on an understanding of how these values are meant to interact with each other, and what they mean in the context of your project or the specific Actor class you are developing. You can build this functionality by controlling access to the Gameplay Attributes themselves, or by directing the way that Gameplay Effects work at the Ability Set level.

Initialization

If you choose not to initialize your Attribute Set and its Gameplay Attributes by calling an initialization function with hard-coded values, you can do so with a Data Table using the Gameplay Ability System row type called "AttributeMetaData". You can import data from an external file, or manually populate the Data Table in the editor.



When creating the Data Table Asset, choose "AttributeMetaData" as the row type.

Developers usually import their tables from .csv files like the following:



When importing a .csv file as a Data Table Asset, select the "AttributeMetaData" row type.

You can append additional rows to support Attribute Sets with multiple Gameplay Attributes. In the file shown above, the "Health" Gameplay Attribute within UMyAttributeSet (the reflection system drops the "U" prefix) will initialize with a value of 100. It has no derived information and does not stack.

Although there are columns for MinValue (0.0) and MaxValue (150.0), Gameplay Attributes and Attribute Sets do not feature a built-in clamping behavior; the values in these columns have no effect.

If you prefer to edit values in Unreal Editor rather than an external spreadsheet or text-editor program, you can do so by creating your table and opening it like any other Blueprint Asset. Use the Add button at the top of the window to add a row for each Gameplay Attribute. Keep in mind that the naming convention is AttributeSetName.AttributeName, and it is case-sensitive.

The "Min Value" and "Max Value" columns are not implemented in the default Gameplay Ability System Plugin; these values do not have any effect.

Controlling Gameplay Attribute Access

Controlling direct access to the Gameplay Attributes is a good way to ensure that their values are always within the limits that you set for them. This is done through the Ability Set, not by extending FGameplayAttributeData; FGameplayAttributeData only stores and provides access to the Gameplay Attribute's data.

To restrict the value of the "Health" Gameplay Attribute so that it can never go below zero, you can write your own getter and setter functions. Remove the GAMEPLAYATTRIBUTE_VALUE_GETTER and GAMEPLAYATTRIBUTE_VALUE_SETTER macros, replacing them with function headers:

Define these functions in your Attribute Set's source file:

Interactions with Gameplay Effects

A common way to exercise control over the value of a Gameplay Attribute is to handle [Gameplay Effects] as they relate to it.

Begin by overriding the PostGameplayEffectExecute function in your Attribute Set's class definition. This function should be at the public access level.

void PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData& Data) override;

Write the function body in the Attribute Set's source file, making sure to call the parent class' implementation.

Replication

For multiplayer projects, you can replicate your Gameplay Attribute through the Attribute Set similar to how you would replicate any other property.

Begin by adding the ReplicatedUsing Specifier to your property's definition in the Attribute Set header file. This will set up a callback function that helps with prediction on remote systems.

protected: /** Sample "Health" Attribute */ UPROPERTY(EditAnywhere, BlueprintReadOnly, ReplicatedUsing = OnRep_Health) FGameplayAttributeData Health;

Declare your replication callback function:

/** Called when a new Health value arrives over the network */ UFUNCTION() virtual void OnRep_Health(const FGameplayAttributeData& OldHealth);

In the Attribute Set's source file, define your replication callback function. The body of the function can be expressed as a single macro that the Gameplay Ability System defines.

If this is the first replicated property in your Attribute Set, set up an override for the public GetLifetimeReplicatedProps function.

/** Marks the properties we wish to replicate */ virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override;

Add the Gameplay Attribute to the Attribute Set's GetLifetimeReplicatedProps function in its source file, as follows:

Gameplay Attributes

Creating an Attribute Set

Gameplay Effects

Major Properties

Programming Effect and Attribute Interaction

Actors that interact with the Gameplay Ability System will generally need a set of numerical properties that the system can access and modify to affect game logic and keep track of what has happened in the game. These properties are known as Gameplay Attributes (or "Attributes" for short), and they are modified (temporarily or permanently) by Gameplay Effects.

To see how this could be setup in a Unreal Engine project, check out the Samples and Tutorials in the Action RPG documents.

Gameplay Attributes

A Gameplay Attribute contains any numerical measurement of an Actor's current state that can be described by a single floating-point value, such as health points, physical strength, movement speed, resistance to magic, and so on. Attributes are declared as UProperties of FGameplayAttribute type within Attribute Sets, which both contain Attributes and supervise any attempts to modify them.

Attributes and Attribute Sets must be created in native code - they cannot be created in Blueprints.

Creating an Attribute Set

To create an Attribute Set, inherit from UAttributeSet, and add Gameplay Attribute Data members tagged with UPROPERTY. For example, an Attribute Set containing only a "health" Attribute would look like this:

A minimal Attribute Set, containing a single Attribute.

Once you have created an Attribute Set, you must register it with the Ability System Component. To accomplish this, either add the Attribute Set as a subobject of the Ability System Component's owning Actor, or pass it to the Ability System Component's GetOrCreateAttributeSubobject function.

Gameplay Effects

Gameplay Effects are the Gameplay Ability System's way to change Attributes. This includes:

Direct changes to the Attribute's base value, like taking away health points from an Actor that has received damage.

Temporary changes (often called "buffs" or "debuffs"), like granting a boost to movement speed for a few seconds.

Persistent changes that are applied over time, like regenerating a certain amount of magic points per second over a period of several seconds (or indefinitely).

Gameplay Effects are implemented as data-only Blueprints (of base class UGameplayEffect) that interact with the Ability System Component and can be stored there while they are active, if appropriate.

Major Properties

Gameplay Effects, unlike most other parts of the Gameplay Ability System, do not usually override the base class, UGameplayEffect, in either native or Blueprint code. Instead, Gameplay Effects are designed to be configured purely through variables. The following are some of the major properties of Gameplay Effects that you can adjust:

Duration: Gameplay Effects can apply instantly (such as Health decreasing when attacked), over a limited time (such as a movement speed boost that lasts for a few seconds), or indefinitely (such as a character naturally regenerating magic points over time). In addition, Effects that have a non-instant duration can also apply themselves at different intervals. This can be useful not only to change how the Effect works in terms of gameplay, but also for setting up the timing on things like repeating audio or visual effects.

Modifiers and Executions: Modifiers determine how the Gameplay Effect interacts with Attributes. This includes mathematical interactions with Attributes themselves, like "increase armor rating by 5 percent" as well as Gameplay Tag requirements to execute the Effect. When a Gameplay Effect needs to do something beyond what Modifiers support, Executions can help. Executions use the UGameplayEffectExecutionCalculation to define custom behaviors that the Gameplay Effect will have when it executes. These are particularly useful for defining complex equations that aren't adequately covered by Modifiers.

Application Requirements: Application Requirements include sets of Gameplay Tags that are required (or forbidden) to be present in order for a Gameplay Effect to apply, and a random chance for a Gameplay Effect not to apply. If these requirements are not sufficient for your game's needs, you can derive a data object from the UGameplayEffectCustomApplicationRequirement base class, in which you can write native code that defines arbitrarily complex application rules.

Granted Abilities: Gameplay Effects can grant Abilities, not just Gameplay Tags, when they apply. When used in conjunction with Executions, these can be used to set up highly-specific gameplay combinations. For example, an Actor struck with a fire-themed Gameplay Effect while possessing a Gameplay Tag or Attribute indicating that the Actor is soaked in oil could gain the ability "On Fire", which passively damages nearby Actors and has a visual effect with particles and dynamic light, for the next ten seconds.

Stacking: "Stacking" refers to the policy of applying a buff or debuff (or Gameplay Effect, in this case) to a target that already carries it, as well as handling the situation, known as Overflow, where a new Gameplay Effect is applied to a target that is already fully saturated with the original Gameplay Effect (such as a poison meter that builds up, resulting in damage-over-time poison only after it overflows). The system supports a wide variety of Stacking behaviors, such as building up until a threshold is broken, maintaining a "stack count" that increases with each fresh application up to a maximum limit, resetting or appending time on a limited-time Effect, or simply applying multiple instances of the Effect independently with individual timers.

Gameplay Cue Display: Gameplay Cues** are a network-efficent way to manage cosmetic effects, like particles or sounds, that you can control with the Gameplay Ability System. Gameplay Abilities and Gameplay Effects can trigger them, and they act through four main functions that can be overridden in native or Blueprint code: On Active, While Active, Removed, and Executed (used only by Gameplay Effects). All Gameplay Cues must be associated with a Gameplay Tag that start with "GameplayCue", such as "GameplayCue.ElectricalSparks" or "GameplayCue.WaterSplash.Big".

The Gameplay Cue Manager executes Gameplay Cues. Actors can respond to Gameplay Cues by implementing the IGameplayCueInterface and having a function whose name matches the Gameplay Cue's tag. Standalone Gameplay Cue Notify Blueprints can also respond to Gameplay Cues.

Programming Effect and Attribute Interaction

There are several functions that an Attribute Set can override to deal with the way that an Attribute responds when a Gameplay Effect attempts to modify it. As an example, the "Health" Attribute from our sample USimpleAttributeSet can store a floating-point value, and that value can be accessed or changed by the Gameplay Ability System, but nothing actually happens when the Health value drops to zero, and there is nothing to prevent it from dropping below zero. To make the "Health" Attribute behave the way we want it to, the Attribute Set itself can step in by overriding several virtual functions that handle attempted modifications to any of its Attributes. The following functions are commonly overridden by Attribute Sets:

Function Name

Purpose

PreAttributeChange / PreAttributeBaseChange

These functions are called just before modifications to an Attribute. They are intended to enforce rules on the Attribute's value, such as "Health must be between 0 and MaxHealth", and should not trigger in-game reactions to Attribute changes.

PreGameplayEffectExecute

Just before modifying an Attribute's value, this function can reject or alter the proposed modification.

PostGameplayEffectExecute

Immediately after modifying an Attribute's value, this function can react to the change. This often includes clamping the final value of the Attribute, or triggering an in-game reaction to the new value, like dying when the "health" Attribute falls to zero.

Abilities in Lyra

What is a Gameplay Ability?

Tracking an Ability's Owner

Tracking an Ability's State

Coordinating an Ability's Execution

Components of the Gameplay Ability System

Tracking Ownership

Handling Abilities and Their Execution

Controlling Activation

Controlling Execution

Attribute Sets and Attributes

Handling Gameplay Effects

Handling Cosmetic Effects

Supporting Network Multiplayer

Ability System Components and Replication

Replicating Abilities and Using Prediction

Using Abilities to Interact With Server-Owned Objects

Further Reading

The Gameplay Ability System is a framework for building abilities and interactions that Actors can own and trigger. This system is designed mainly for RPGs, action-adventure games, MOBAs, and other types of games where characters have abilities that need to coordinate mechanics, visual effects, animations, sounds, and data-driven elements, although it can be adapted to a wide variety of projects. The Gameplay Ability System also supports replication for multiplayer games, and can save developers a lot of time scaling up their designs to support multiplayer.

With this system, you can create abilities as simple as a single attack, or as complex as a spell that triggers many status effects depending on data from the user and the targets. This page provides an overview of the Ability System and how its components work together.

What is a Gameplay Ability?

A Gameplay Ability is an ingame action that an Actor can own and trigger repeatedly. Common examples include spells, special attacks, or effects triggered by items. This concept is very common in video games, so much so it is often taken for granted, though the processes involved in running an ability are often complex and require specific timing. For example, while coding an attack activation is fairly simple in itself, over the course of a long-term project the complexity of building abilities can explode as you add resource costs, buff or debuff effects to add or remove from players, combo systems, and other details. As such, there are three major considerations involved in how Unreal Engine's Gameplay Ability System is designed.

Tracking an Ability's Owner

Abilities and their effects must maintain a concept of ownership. When an effect runs a calculation, it needs to know who its owner is so that it can use their attributes, and when an ability does something that would score a point for a player, it needs to know what player owned it so that it can give credit correctly.

The "Owner" for a Gameplay Ability is not the same as Ownership in network replication terms.

Tracking an Ability's State

An ability must be able to track a cycle of states:

When the ability is activated.

When the ability's execution is currently in-progress.

When the ability is fully completed and no longer active.

The Lyra sample project also tracks when an ability is granted.

As an example, an Actor in the middle of using an ability typically wouldn't be able to activate the same ability again until it is done. However, abilities could have special rules that make it possible to cancel an ability, ending its execution early, and then start another one.

Coordinating an Ability's Execution

An ability must be able to interact with multiple different systems during its execution, with specific timing. These interactions can include:

Activating animation montages.

Taking temporary control of a character's movement.

Triggering visual effects.

Performing overlap or collision events.

Changing characters' stats, either temporarily or permanently.

Increasing or decreasing ingame resources.

Allowing or blocking the activation of other abilities.

Handling cooldowns to restrict ability usage.

Getting interrupted by ingame events.

Canceling other abilities in-progress.

Making major state changes to a character, such as activating a new movement mode.

Responding to input in the middle of other interactions.

Updating UI elements to show ingame status for abilities.

Depending on how an ability works, it could perform any of these interactions at many different points in time while it is active, including in the middle of animations, and some effects may need to persist after the ability itself completes.

Components of the Gameplay Ability System

The Gameplay Ability System is designed to address all of these use-cases by modeling abilities as self-contained entities responsible for their own execution. This system consists of several components:

An owning Actor with an Ability System Component, which maintains a list of all the abilities the Actor owns and handles activation.

Gameplay Ability Blueprints that represent individual abilities, and coordinate their ingame execution.

Composed of Gameplay Ability Tasks as well as other functions.

An Attribute Set attached to the Ability System Component.

Contains the Gameplay Attributes that drive calculations or represent resources.

Gameplay Effects that handle changes to Actors as a result of using Abilities.

Gameplay Effect Calculations that provide modular, reusable methods for calculating effects.

Gameplay Cues that are associated with Gameplay Effects and provide a data-driven method for handling visual effects.

The sections below summarize these classes in greater detail.

Tracking Ownership

You need to attach an Ability System Component to an Actor for it to use Gameplay Abilities. This component is responsible for adding and removing abilities to an Actor, keeping track of what abilities an Actor owns, and activating them. It is also the main representation of the owning Actor in the context of the ability system, providing a system for tracking attributes, ongoing effects, Gameplay Tags, and Gameplay Events, as well as the interface for accessing the owning Actor directly.

In multiplayer games, the Ability System Component is also responsible for replicating information to clients, communicating player actions to the server, and verifying that clients are authorized to change the Ability System Component's state. The Ability System Component's parent Actor must be owned by a locally controlled player for remote activation to take place.

Handling Abilities and Their Execution

A Gameplay Ability is a Blueprint object that is responsible for executing all of an ability's events, including playing animations, triggering effects, fetching attributes from its owner, and displaying visual effects.

You can Activate Gameplay Abilities through four main methods:

You can activate an Ability explicitly through Blueprint or C++ code using a Gameplay Ability Handle. This is provided by the Ability System Component when an Ability is granted.

Using Gameplay Events. This fires all abilities with a matching Ability Trigger. If you need to abstract your input and decision mechanisms, this method is preferable, as it provides the greatest degree of flexibility.

Using Gameplay Effects with matching tags. This fires all abilities with a matching Ability Trigger. This is the preferred method for triggering abilities off of Gameplay Effects. A typical use case would be a Sleep debuff, which triggers an ability that plays a disabled animation and inhibits other game actions.

Gameplay Abilities can represent a wide array of ingame actions, and are not limited to powers or spells that players explicitly use. Hit reactions, or the above example of a Sleep animation, are good examples.

Using Input Codes. These are added to the Ability System Component, and when called they will trigger all Abilities that match. This functions similarly to Gameplay Events.

When you Activate a Gameplay Ability, the system recognizes that ability as being in-progress. It then fires off any code attached to the Activate event, moving through each function and Gameplay Task until you call the Finish function to signal the ability is finished executing. You can attach further code to the On Finished event if you need to do any extra cleanup. You can also Cancel an ability to stop it mid-execution.

Gameplay Abilities use Gameplay Tags to limit execution. All abilities have a list of tags that they add to their owning Actor when they activate, as well as lists of tags that block activation or automatically cancel that ability. While you can manually cancel, block, or allow abilities' execution with your own code, this provides a method that is systemically consistent.

Gameplay Abilities support a variety of common use-cases, like cooldowns and assigning resource costs, and there is a pre-made library of Gameplay Ability Tasks that handle animations and other common Unreal Engine systems.

Whereas standard Blueprint function nodes finish executing immediately, Gameplay Ability Tasks keep track of whether they're inactive, in-progress, or finished, and they can be programmed to fire off other events during their execution. They can also keep track of whether their parent Gameplay Ability has been canceled and clean up accordingly. It is common for games to implement custom gameplay logic by extending Gameplay Ability Tasks.

Gameplay Abilities can also respond to Gameplay Events, which are generic event listeners that wait to receive a Gameplay Tag and an Event Data struct from the owning Actor.

Attribute Sets and Attributes

The Gameplay Ability System interacts with Actors mainly through Attribute Sets, which contain Gameplay Attributes. These are numeric, floating point values that can be used in calculations or modified by Gameplay Abilities. These can be used for any purpose you want, but common use-cases include tracking a character's health or hit points, as well as values for a character's core statistics (such as Strength and Intelligence). While you can use basic variables to represent these values, Gameplay Attributes provide several advantages:

Attribute Sets provide a consistent, reusable group of attributes that you can build systems around.

Gameplay Abilities can access Gameplay Attributes through reflection, making it possible to create simple calculations and effects directly in the Blueprint editor.

Gameplay Attributes track their default value, current value, and maximum value separately, making it easier to create temporary modifications (buffs and debuffs) and persistent effects. Gameplay Attributes also replicate their value to all clients, and are safe for local UI visualizations such as enemy health bars.

For an Actor to use Gameplay Attributes, you must add an Attribute Set to its Ability System Component. After that, the Ability System Component can automatically access the attributes you assigned to the Attribute Set.

Handling Gameplay Effects

The Gameplay Ability System uses Gameplay Effects to apply changes to Actors targeted by Gameplay Abilities. These can be one-shot effects, such as applying damage, or persistent effects, such as ongoing poison damage, buffs, and debuffs. In the case of persistent effects, the Gameplay Effect attaches itself to the target Actor until it is removed, and they can be pre-set to have a limited lifetime before they expire and clean themselves up, undoing any changes to the target Actor's Gameplay Attributes.

Gameplay Effects use Gameplay Effect Calculations to handle calculations based on Gameplay Attributes. While you can create simple calculations directly in the Blueprint editor, you can also program custom Effect Calculations that have more complex logic and affect multiple attributes at a time. These are able to process information from both the owning Actor of the Gameplay Ability and the target Actor, so you can concentrate common calculations into one reusable piece of code.

Handling Cosmetic Effects

Gameplay Cues are Actors and UObjects responsible for running visual and sound effects, and are the preferred method for replicating cosmetic feedback in a multiplayer game. When you create a Gameplay Cue, you run the logic for the effects you want to play inside its Event Graph. Gameplay Cues can be associated with a series of Gameplay Tags, and any Gameplay Effect matching those tags will automatically apply them.

For example, if you add the tag Ability.Magic.Fire.Weak to a Gameplay Cue, any Gameplay Effect that has Ability.Magic.Fire.Weak will automatically spawn that Gameplay Cue and run it. This makes it quick and easy to create a universal library of visual effects without manually triggering them from code.

Alternatively, you can trigger Cues without a Gameplay Effect association. For an example of this implementation, you can look at the Lyra sample game's weapon firing feedback.

Gameplay Cues do not use reliable replication, so there is a chance that some clients do not receive the Cue or display its feedback. This can cause desyncs if you tie in gameplay code to these. Therefore, Gameplay Cues should be used for cosmetic feedback only. For gameplay-relevant feedback that needs to be replicated to all clients, you should rely on Ability Tasks to handle replication instead. The Play Montage Ability Task is a good example of this.

Supporting Network Multiplayer

Gameplay Abilities provide some built-in functionality for supporting networked multiplayer games, but have some limitations and guidelines you should be aware of. Many of these guidelines reflect general network multiplayer best practices.

Ability System Components and Replication

To save bandwidth and prevent cheating, Ability System Components do not replicate their full state to all clients. Specifically, they do not replicate Abilities and Gameplay Effects to all clients, only Gameplay Attributes and Tags that they affect.

Replicating Abilities and Using Prediction

Most abilities in networked games should run on the server and replicate to clients, so there is normally lag in ability activation. This is not desirable in most fast-paced multiplayer games. To mask this lag, you can activate an ability locally, then tell the server you have activated it so that it can catch up.

There is a chance that the server rejects the ability activation, which means it must undo the changes the ability made locally. You can handle these cases using locally predicted abilities. To help support this, some Gameplay Effects support rollback if the ability that granted them gets rejected by the server. These include most non-instant GEs, but notably excludes things like damage and other instantaneous attribute/tag changes.

Using Abilities to Interact With Server-Owned Objects

Gameplay Abilities can handle interactions with bots, NPCs, and other server-owned Actors and objects. You have to do this through a locally owned Actor – usually the player's Pawn – and a replicated ability or another non-GAS mechanism that calls a server function. This replicates the interaction to the server, which then has authority to perform changes with the NPCs.

Further Reading

For a working model of the Gameplay Ability System in action, examine the Lyra sample game project, which implements several abilities and weapons. To get started working with these building blocks yourself, follow the Gameplay Ability System Quickstart Guide.

Ability Tasks (C++ class UAbilityTask) are a specialized form of the more general Gameplay Task class intended to work with Gameplay Abilities. Games that use the Gameplay Ability System usually include a variety of custom Ability Tasks which implement their unique gameplay features. They perform asynchronous work during a Gameplay Ability's execution, and have the capability to affect execution flow by calling Delegates (in native C++ code) or moving through one or more output execution pins (in Blueprints). This enables Abilities to execute across multiple frames, and to perform several distinct functions in the same frame. Most Ability Tasks have an execution pin that fires immediately, enabling Blueprint execution to continue after starting a Task. In addition, there are often task-specific pins that will fire after a delay, or following a certain event that may or may not happen.

Ability Tasks can self-terminate by calling the EndTask function, or it can wait to be terminated automatically when the Gameplay Ability that ran it ends. This prevents phantom Ability Tasks from running, effectively leaking CPU cycles and memory. For example, one Ability Task might play a spell-casting animation while another places a targeting reticule at the player's aim point. The Gameplay Ability could end if the player either hits the Confirm input to cast the spell, or waits for the animation to finish without confirming the spell. Although they can self-terminate at any time, the Ability Tasks are guaranteed to end, at latest, when the main Ability ends.

Ability Tasks are designed to be used in both networked and non-networked environments, although they do not directly update themselves across the network. They generally stay in sync indirectly, since they are created by Gameplay Abilities (which do replicate), and use replicated information, such as player input or networked variables, to determine their execution flow.



A melee attack Gameplay Ability, implemented in Blueprints. The "Play Montage and Wait for Event" Ability Task at the center is part of the ActionRPG sample.

To see how this could be setup in a UE4 project, check out the Melee Abilities In ARPG documents.

Understeering versus Oversteering

Debugging Center of Mass

Weight distribution of a vehicle is important to its control, as it affects a variety of its characteristics, like handling, acceleration, and traction. Different vehicle types will require different weight distributions depending on their intended use. For the purposes of game development, these characteristics can also define what style of game you are making, whether that is an arcade-style racer, a simulation, or even a hybrid of the two. Altering Center of Mass enables you to change the weight distribution of your vehicle.

In games, the primary use of Center of Mass is for vehicles, but it can also be used for large Physics Bodies encapsulating an irregular shape. In your Physics Asset, you will often use one large Physics Body to define the majority of the Mass for the vehicle (or large object). The Center of Mass will be generated at the center of this Physics Body, which can make the vehicle handle oddly, so you can adjust the Center of Mass to account for where the mass of the vehicle is really located.



Understeering versus Oversteering

Depending on where the Center of Mass is located, you can shift it to be predominantly front-heavy, causing the vehicle to have a tendency toward understeering (not turning enough when going around corners), or to be predominantly rear-heavy, causing it to tend toward oversteering (turning more sharply than intended). In most cases, it is ideal to find a neutral balance for your Center of Mass so that the vehicle is more easily controlled.





Also, when you consider where to place the Center of Mass, it is worth noting that this choice can have an effect on how your vehicle handles in the air. In this example, the Center of Mass has been lowered and moved closer to the rear of the car. Since it's low to the ground and can get to high speed quickly, the lower rear Center of Mass helps to stabilize the car, especially with jumps!

Center of Mass: X: 0, Y: 0, Z: 0

Center of Mass: X: -25, Y: 0, Z: -10

Debugging Center of Mass

To help you debug mass properties and inertia tensors associated with physics objects while in the Level Editor, you can enable the Show flag by going to Show > Advanced > Mass Properties.





The thickness of each axis indicates the moment of inertia magnitude along that axis.

How to Convert PhysX Vehicles to Chaos

Vehicle Debug Commands

Enabling the Chaos Vehicles Plugin

Creating and Editing Chaos Wheel Blueprints

Create a Wheel Blueprint

Edit the Wheel Blueprint

Creating a Curve Asset for the engine torque

Importing a Vehicle Mesh

Vehicle Physics Editor

Creating and Editing a Physics Asset

Creating the Physics Asset

Editing the Physics Asset

Creating an Animation Blueprint with the Wheel Controller node

Wheel Controller Node

Create an Animation Blueprint

Creating a Vehicle Blueprint

Setting up Vehicle Control Inputs

Vehicle Game Mode Setup

The individual assets that make up a vehicle are as follows.

A Skeletal Mesh

A Physics Asset

An Animation Blueprint

A Vehicle Blueprint

One or more Wheel Blueprints

A Float Curve asset that represents the engine's torque curve

These are the same no matter whether you are creating an automobile or a motorcycle. This document will guide you through the process of setting up a Vehicle.

Enabling the Chaos Vehicles Plugin.

Creating and Editing Chaos Wheel Blueprints.

Creating a Curve Asset for the engine torque.

Importing a Vehicle Mesh.

Creating and Editing a Physics Asset.

Creating an Animation Blueprint with the Wheel Controller node.

Creating a Vehicle Blueprint.

Setting up Vehicle Control Inputs.

Setting up the Vehicle Game Mode.

Enabling the Chaos Vehicles Plugin

Before using Chaos Vehicles, the Chaos Plugin needs to be enabled.

Click Settings > Plugins to open the Plugins Menu.



Click the Physics category and enable the ChaosVehiclesPlugin.



Restart Unreal Editor after enabling the plugin.

This plugin will not work with PhysX enabled.

Creating and Editing Chaos Wheel Blueprints

The wheel Blueprint is where the configuration for a Wheel / Suspension / Brakes combination is set up.

In most cases, you will require at least two wheel types per vehicle. A wheel (or axle) that is affected by the steering / engine / handbrake, and one that is not. Also, this may be the case for having differently sized wheels for the front or the back, in which case, you have full control over setting the differing radii, mass, width, handbrake effect, suspension, and many other properties to give your vehicle the handling you desire.

There is no limit on the number of wheels that a vehicle may have. It is possible for multiple vehicles to share the same Wheel Blueprints, but this strategy is only valid if the wheel dimensions and suspension limits are the same.

Create a Wheel Blueprint

In the Content Browser, right-click and select Blueprint Class from the Create Basic Asset section.



In the Pick Parent Class window, under All Classes, search for "wheel" and select ChaosVehicleWheel. Click Select to create the asset.



The new asset will be created in the Content Browser. Give it a recognizable name so that you can easily locate it later (for example, 'BP_ChaosFrontWheel').

(Optional Step) Repeat these steps again so that you have a front and rear wheel type. Think of each as a setup per axle.

Edit the Wheel Blueprint

Double-click the assets in the Content Browser to open them in the Blueprint Editor, where there are options to edit the wheels.

To start, there are five properties that need to change for each wheel, as the rest of the properties depend on how the vehicle performs (and should be tweaked later on) during testing.

Property

Notes

Axel Type

This defines whether the wheel is in the front or the rear of the vehicle.

Wheel Radius

This needs to match the size of the render model in centimeters (cm).

Affected by Handbrake

Enable this in the rear wheels.

Affected by Engine

Enable this in the rear wheels for a rear-wheel drive (RWD) vehicle. Enable this in the front wheels for front-wheel drive (FWD) vehicles. Enable this on all of the wheels for all-wheel drive (AWD) vehicles.

Affected by Steering

Enable this in the front wheels. For vehicles with more wheels in the front (for example, a truck cab might have four-wheel steering), enable it in the second layer with a different steering angle. Alternatively, all-wheel steering is possible by selecting steering on the rear wheels with a negative steering angle.

Max Steer Angle

Normally, this is a positive value (specified in degrees). However, a negative value is allowed for rear-wheel counter-steering for all-wheel drive (AWD) vehicles.



Example Class Defaults for the Chaos Wheel Blueprint.



For the buggy example, set the Wheel Radius to 58 for both front and back wheel Blueprints.

Creating a Curve Asset for the engine torque

The torque curve represents the amount of torque output from the engine at a given RPM. The graph's X axis represents the engine RPM (revolutions per minute) with a range from 0 to the engine max RPM. The Y axis represents the engine Torque output in NM (Newton Meters). A typical torque curve is an inverted U shape with the torque peaking near the middle of the rev range, and trailing off either side.

To create your torque curve, follow these steps:

In the Content Browser, right-click and select Miscellaneous > Curve. Select the Curve Float type and click the Select button to create the asset.





Name the asset TorqueCurve.



In the Content Browser, double-click TorqueCurve to open it in the Curve Editor. Add points to create the curve shape to your liking.



Importing a Vehicle Mesh

This guide uses the Buggy vehicle mesh from the Vehicle Game sample project. In the Epic Games Launcher click the Learn tab to find the project.



Vehicle Physics Editor

After importing a vehicle mesh to your project, follow these steps to view the mesh in the Physics Asset Editor.

In the Content Browser, double-click the vehicle Skeletal Mesh to open it.



Click the Physics tab to open the Physics Asset Editor.





Creating and Editing a Physics Asset

Creating the Physics Asset

If you have a skeletal mesh that does not have an associated physics asset, then you can create a physics asset by following these steps:

In the Content Browser, right-click the skeletal mesh asset and select Create > Physics Asset > Create and Assign.



Click the Primitive Type dropdown and select Single Convex Hull. Click Create Asset to create a new physics asset.



This will generate a physics asset with default collision shapes for each of the bones. The initial collision setup will most likely not be ideal since it will use the same primitive type to represent all of the bones in the physics asset.

In the Content Browser, right-click the physics asset to open it in the Physics Asset Editor.





Inside the Physics Asset Editor you can adjust the collision primitives used on each bone to better suit the vehicle mesh.

Editing the Physics Asset

In the Skeleton Tree window, click the gear icon and select Show Primitives.



Select all the wheel bones inside the Skeleton Tree window.



Go to the Tools window and under the Body Creation section, click the Primitive Type dropdown and select Sphere. Click Re-generate Bodies.





You can now see the Sphere primitives on each of the wheels.





Select the suspension bones inside the Skeleton Tree window. Right-click and select Collision > No Collision to remove collision from the vehicle suspension.





Creating an Animation Blueprint with the Wheel Controller node

Animation Blueprints are used to control Vehicle Skeletal Mesh animations specific to that vehicle, such as spinning tires, suspension, handbrakes, and steering animations. To offload a lot of the work in creating these types of animations, you can use the Wheel Controller Node to drive the animations.

Wheel Controller Node

Where an Animation Blueprint is used to get and control animations for the vehicle, the Wheel Controller node makes controlling all of the animations for the vehicle straightforward with little to no additional setup.



The node gets the necessary information from the wheels (such as "How fast is it spinning?" or "Is it affected by the Handbrake?" or "What are the suspension settings for this wheel?"), and translates the query results to an animation on the bone that the wheel is associated with.

Create an Animation Blueprint

In the Content Browser, right-click and select Animation > Animation Blueprint.



In the Create Animation Blueprint window, select the VehicleAnimationInstance parent class and select the vehicle Skeleton from the list. Click Create to create a new Animation Blueprint asset.



In the Content Browser, double-click the animation Blueprint to open it.

Right-click in the Anim Graph and search for then select Mesh Space Ref Pose.



Right-click in the Anim Graph and search for then select Wheel Controller for WheeledVehicle. Connect the Mesh Space Ref Pose node to the Wheel Controller node.





Right-click in the Anim Graph and search for then select Component To Local. Connect the Wheel Controller node to the Component To Local node. Connect the Component To Local node to the Output Pose node.





(Optional Step) If you have additional struts or other suspension needs (like the sample Buggy from Vehicle Game), you will need additional nodes in the Animation Graph to handle the joints that affect those polygons. For example, in the Buggy, the extra joints are used to control the axle connections to the wheels. These are driven by Look At nodes, which, when given the wheel joints, will be driven by the Wheel Controller node. The Look At nodes will ensure the suspension stays attached to the wheels, as demonstrated in the following example.



The Buggy uses the following Look At node composition:

Bone

Look At

F_L_Suspension

F_L_wheelJNT

F_R_Suspension

F_R_wheelJNT

B_L_Suspension

B_L_wheelJNT

B_R_Suspension

B_R_wheelJNT

B_L_wheelJNT

B_L_Suspension

B_R_wheelJNT

B_R_Suspension

Creating a Vehicle Blueprint

In this section, you will create the Vehicle Blueprint that uses all the assets created in the previous sections.

In the Content Browser, right-click and select Blueprint Class from the Create Basic Asset category.



In the Pick Parent Class window, expand the All Classes section and search for and select WheeledVehiclePawn. Click Select to create the new Blueprint asset.



In the Content Browser, double-click the Vehicle Blueprint to open it.



In the Components window, click the Mesh Skeletal Mesh Component. Go to the Details panel and under the Mesh section click the Skeletal Mesh dropdown. Select your vehicle's Skeletal Mesh asset.





In the Details panel, scroll to the Animation section and click the Anim Class dropdown. Select your vehicle's Animation Blueprint.



In the Details panel, scroll to the Physics section and enable the Simulate Physics checkbox.



From the Components window, click Add Component, and search for then select Spring Arm.



With the Spring Arm component selected, click Add Component, and search for then select Camera.



In the Viewport select the Camera and position it to your liking.



Select the Camera component and go to the Details panel. Scroll to the Camera Settings section and verify that Use Pawn Control Rotation is disabled.



This ensures that the camera is locked to its view direction rather than the Player Controller's view direction.

Select the Vehicle Movement Component in the Components window.



Go to the Details panel and scroll to the Vehicle Setup section. Expand the arrow next to Wheel Setups and set the following for each wheel:

Set the Wheel Class to the Wheel Blueprint(s) you created.

Set the Bone Name to the name of the joint that should be controlled by the wheel.



The order you assign the wheels has no bearing on whether it is a front or a rear wheel, only the Bone Name and Wheel Class have any effect. For organizational purposes, we recommend keeping the wheels in the same order for each new vehicle (for example: FL, FR, BL, BR). Keeping a standard helps when you access wheel data by wheel index (the index in the Wheel Setup array).

If the vehicle requires more than 4 wheels, click the + icon next to the Wheel Setups property to add more, or conversely remove wheels as needed.

Select the Vehicle Movement Component in the Components window and go to the Details panel. Scroll down to the Mechanical Setup section and expand the Engine Setup category. Expand the Torque Curve category and add the torque curve asset to the External Curve dropdown.



Setting up Vehicle Control Inputs

Click Settings > Project Settings to open the Project Settings window.



Go to the Input category and set up control inputs for steering, throttle, brake, and handbrake. The image below shows the inputs for the Buggy in the Vehicle Game.



In the Content Browser, double-click the Vehicle Blueprint to open it.

Drag the Vehicle Movement Component to the Event Graph to create a node.

Drag from the Vehicle Movement Component node and search for then select Set Throttle Input.



Right-click in the Event Graph and search for then select Throttle to add your Throttle input event.



Connect the InputAxis Throttle node to the Set Throttle Input node. Connect the Axis Value pin from the InputAxis Throttle node to the Throttle pin of the Set Throttle Input node.



Follow the steps above and add the nodes for Set Brake Input and Set Steering Input, and connect them with their corresponding input events.



Follow the steps above and add the nodes for Set Pitch Input, Set Roll Input and Set Yaw Input, and connect them with their corresponding input events.



Follow the steps above and add the nodes for Set Change Up Input and Set Change Down Input, and connect them with their corresponding input events.

Enable the New Gear Up checkbox on the Set Change Up Input node.

Enable the New Gear Down checkbox on the Set Change Down Input node.



Follow the steps above and add the node for Set Handbrake Input twice, and connect each node to the Pressed and Released pins of the InputAction Handbrake node. Enable the New Handbrake checkbox on the Set Handbrake Input node connected to the Pressed pin.



Vehicle Game Mode Setup

In the Content Browser, right-click and select Blueprint Class from the Create Basic Asset category.



In the Pick Parent Class window, select Game Mode Base to create the Game Mode Blueprint.



In the Content Browser, double-click the new Game Mode Blueprint to open it.



Go to the Details panel and scroll to the Classes section. Click the Default Pawn Class dropdown and select your Vehicle Blueprint.



Click Compile and Save, then close the window.

In the Main Viewport window, click Window > World Settings to open the World Settings panel.

Go to the World Settings panel and scroll down to the Game Mode section.

Click the GameMode Override dropdown and select your Game Mode Blueprint.





Press Play and test your vehicle.



If you have an existing PhysX vehicle that you want to convert to Chaos, follow the PhysX to Chaos Vehicle Conversion guide.

How to Set up Vehicles

Vehicle Debug Commands

Setup

Asset Configuration

Animation Blueprint

Class Layout

Conversion Steps

Troubleshooting common issues

Your vehicle does not move during gameplay

Your vehicle's wheels are not animating

Your vehicle's reverse is not working as before

As mentioned in the Vehicle Setup guide, the assets that make up a vehicle are a skeletal mesh, a physics asset, an Animation and Vehicle Blueprint, and one or more Wheel Blueprints.

This guide will go through the steps of converting a PhysX (legacy) vehicle to a Chaos vehicle.

Setup

Asset Configuration

At this time, the workflow involved with configuring assets remains the same — setting up physics collision, the camera, and vehicle controls do not change between PhysX and Chaos vehicles.

Animation Blueprint

The Animation Blueprint is the same with the exception of using the WheelController node in place of the WheelHandler node.

Class Layout

In most cases the class layout is similar, with different class names.

PhysX Component

Chaos Component

VehicleWheel

ChaosVehicleWheel

VehicleMovement

ChaosWheeledVehicleComponent

VehicleAnimInstance

VehicleAnimationInstance

WheelHandler

WheelController

WheeledVehicle

WheeledVehiclePawn

Conversion Steps

Create Front and rear wheel Blueprint classes based on the ChaosVehicleWheel class.

Copy the setup details from the PhysX vehicle wheels. The important details to copy are the wheel radius, the suspension max raise/drop values, steering angle, and whether the wheels have an engine, brake, or handbrake.

We recommend converting the front wheel first, setting its values, then creating a duplicate and renaming it the back wheel. By doing this, you will only need to set the values that are different from the front rather than repeating all of the wheel setups again — since in most cases, the wheels and suspension setup will be the same from the front to the rear.

Select your vehicle's Skeletal Mesh and go to the Details panel. Scroll down to the Physics section and enable the Simulate Physics checkbox.



Add a ChaosWheeledVehicleComponent Component to the vehicle pawn.

Add the same number of wheels as in the PhysX Vehicle Component.

Copy the Bone Names from the PhysX Skeletal Mesh.

Set the wheels' classes to the matching wheels that were created earlier.



Example Wheel Class assignments

Set up other properties as needed, including mass and engine torque.

Create a Torque Curve and assign it to the engine torque.

Open the Animation Blueprint. Click File > Reparent Blueprint, and select VehicleAnimationInstance.

This will convert the PhysX VehicleAnimInstance to the Chaos equivalent.

Edit the Vehicle Animation Blueprint by deleting the WheelHandler animation node and replacing it with the WheelController node.



The Animation Graph after replacing WheelHandler with WheelController.



All other setup that exists in the Blueprint can remain exactly as is.



Verify the physics asset looks as expected. For example, the chassis should have a collision model and the wheels may have simple collision; however, the wheels should have collision disabled.

In any Blueprint code that references the PhysX WheeledVehicleMovementComponent4W reference, remove the PhysX movement component references and recreate the Blueprint using the ChaosWheeledVehicleMovement reference.

Add the following setup for your Throttle Input. This setup mimics the previous reverse behavior for PhysX vehicles.



After following these conversion steps, you should have a vehicle that uses the Chaos physics solver.

Troubleshooting common issues

Select your vehicle's Skeletal Mesh and go to the Details panel. Scroll down to the Physics section and enable the Simulate Physics checkbox.



Make sure you are using the Wheel Controller node inside the vehicle's Animation Blueprint.



Make sure you use the following setup for your Throttle Input. This setup mimics the previous reverse behavior for PhysX vehicles.



How to Set up Vehicles

How to Convert PhysX Vehicles to Chaos

Generic Commands

Visualize Forces and Locations

Disable Features and Forces

Wheeled Vehicle Commands

Vehicle Commands Overrides

Vehicle Stat Commands

Using the Center of Mass

Chaos Vehicles come with a variety of debug commands to help you visualize what is happening during the vehicle simulation. All the vehicle-specific commands start with p.vehicle. The commands are enabled by following them with 1, and are disabled by following them with 0. These commands either enable or disable vehicle physics or render debug lines in the scene.

Many of the debug rendering commands are called from the physics thread and need to be enabled with the p.chaos.debugdraw.enabled 1 command before they can be visualized in the scene.



p.Vehicle debug commands display in the editor command console

Generic Commands

Generic commands apply to all vehicle types and include visualizing forces and locations, and disabling features and forces.

Visualize Forces and Locations

Command

Description

p.Vehicle.ShowCOM

Enables or disables the center of mass visualization.

p.Vehicle.ShowModelOrigin

Enables or disables the origin visualization.

p.Vehicle.ShowAerofoilForces

Enables or disables the aerofoil visualization.

p.Vehicle.ShowAerofoilSurface

Enables or disables the surface visualization.

p.Vehicle.ShowAllForces

Enables or disables the force visualization.

p.Vehicle.SetForceDebugScaling

Sets scaling for force visualization. If the forces are large and the lines appear too long, lower the scaling of the rendered lines by using a smaller value.

Disable Features and Forces

These commands will turn off specific forces in isolation to other force. This can help isolate which system is generating a particular behavior in the vehicle movement.

Command

Description

p.Vehicle.DisableSuspensionForces

Disables suspension forces in isolation of other forces.

p.Vehicle.DisableFrictionForces

Disables wheel friction forces in isolation of other forces.

p.Vehicle.DisableRollbarForces

Disables suspension roll bar forces in isolation of other forces.

p.Vehicle.DisableTorqueControl

Disables direct torque control.

p.Vehicle.DisableStabilizeControl

Disables position stabilization control.

p.Vehicle.DisableAerodynamics

Disables aerodynamic force drag / downforce.

p.Vehicle.DisableAerofoils

Disables aerofoil forces.

p.Vehicle.DisableThrusters

Disables thruster forces.

Wheeled Vehicle Commands

Command

Description

p.Vehicle.ShowWheelCollisionNormal

Shows the hit location and normal of the surface that the wheel raycast has hit.

p.Vehicle.ShowSuspensionRaycasts

Shows the suspension raycast length. The color indicates whether the ray hit something (green), or not (red).

p.Vehicle.ShowSuspensionLimits

Enables or disables the suspension limits visualization.

p.Vehicle.ShowWheelForces

Enables or disables the wheel forces visualization.

p.Vehicle.ShowSuspensionForces

Enables or disables the suspension forces visualization.

p.Vehicle.ShowRaycastComponent

Displays the name of the component the wheels are in contact with (from the raycast hit).

p.Vehicle.ShowRaycastMaterial

Displays the name of the physics material that the wheels are in contact with (from the raycast hit).

Vehicle Commands Overrides

Command

Description

p.Vehicle.ControlInputWakeTolerance

Sets the threshold used by the control input to wake up the vehicle if it is sleeping. The default is 0.02.

p.Vehicle.TraceTypeOverride

Global override of the ray trace type. A value of 1 uses Simple collision, while a value of 2 uses Complex collision.

p.Vehicle.SetMaxMPH

Set a top speed override in miles per hour(affects all vehicles). Can help debug an issue or can be used in conjunction with the throttle override.

p.Vehicle.ThrottleOverride

Global override of the throttle control input (range 0 to 1). This is useful for testing the performance of many vehicles driving at once.

p.Vehicle.SteeringOverride

Global override of the steering value (range -1 to 1). This is useful for testing the performance of many vehicles driving at once, as you can set them to dre in circles over the terrain.

p.Vehicle.BatchQueries

Enable or disable batching of suspension raycasts.

p.Vehicle.EnableMultithreading

Enable or disable parallel updates of all vehicles. If a threading crash is suspected, then the vehicle manager can be switched from parallel updates to serial updates. This will simulate vehicles one at a time.

Vehicle Stat Commands

Command

Description

stat ChaosVehicle

Displays timings for the different parts of the vehicle simulation.

stat ChaosVehicleManager

Displays timings for simulating all the vehicles in the scene. It also displays counters showing the number of vehicles, and the portion of vehicles currently awake or sleeping.

Using the Center of Mass

The location of the center of mass has a significant effect on vehicle handling. A high center of mass will cause the vehicle to roll more in corners, or dip more under acceleration and braking.

Pushing the center of mass forward will make steering less reactive since the movement arm will be longer for the rear wheels and shorter for the front wheels. This means that the lateral forces on the rear wheels will have a greater effect on the angular rotation of the vehicle compared to the front wheels.

Visualizing where the center of mass is located is one of the most useful tools for debugging vehicle behavior. A Center Of Mass Offset defined on the skeletal mesh can shift the center of mass position relative to the initially calculated location from the collision model. The center of mass visualization command p.Vehicle.ShowCOM 1 displays the current center of mass position after any offset has been applied.





Simulated Wheels Versus Real Suspension Linkages

What Skeletal Nodes Can Do

Copy Bone

Look At

Implementation Overview

Constructing the Model

The Setup in Unreal Engine 4

PhAT

Antenna Setup

Rolling Your Own

Import Options

This tutorial will walk you through the details of the Advanced Vehicle template. When we are done, you should have a pretty good idea of how it works in theory, and how to build and configure something similar yourself. The main focus is going to be on the suspension.

All the FBX assets used in the vehicle template are available here for download. You should be able to analyze the originals and experiment with your own designs in any modeling package that is capable of reading and writing FBX files. These FBX files should be used with the Advanced Vehicle project template available in Unreal Engine.

Before we get started, you should be aware that a double wishbone suspension is quite a bit more complex to set up than the standard Unreal Engine 4 vehicle, so if you have not successfully set one of those up before, you are strongly encouraged to do that first. Refer to the How to Setup Vehicles documentation for more information.

Once you have read that documentation and have successfully set up a base vehicle, you will be ready to look at the double wishbone design discussed here. We will start with some fundamental theory.

Simulated Wheels Versus Real Suspension Linkages

When we set up the vehicle movement component and assign wheels to it, the vertical movement of the wheels is typically updated by a WheelHandler node inside the vehicle's animation Blueprint. On each frame, the handler will move the wheels up and down along the local Z axis to simulate suspension, making sure that the wheels touch the ground whenever that is possible.

Furthermore, the WheelHandler also applies rotation to make the wheels spin around their Y axis, driven by the rotation speed of the simulated motor and gearbox. In addition to this, it will turn the wheels around their Z axis, driven by the current steering angle.

The default vertical suspension movement is clamped by the Suspension Max Raise and Drop settings in your VehicleWheel-derived classes. This movement is entirely linear, as illustrated below:



The standard vertical movement produced by the WheelHandler.

While not entirely realistic, this type of suspension simulation is in fact perfectly fine for most vehicles, because you cannot usually see the suspension arms or the other components such as the springs and shocks. Any car model with a full body can get typically away with this.

However, in a more open vehicle like a Buggy or a Formula 1 car, where the moving parts are in plain view, this movement can be problematic, because there is no sensible real-world suspension design that would be able produce this kind of movement.

To achieve a more realistic result, we really need a type of motion that can be expressed as a rotation around some fixed pivot point on the vehicle's body:



Ideal vertical and lateral movement.

To solve this little conundrum, we can start by assuming that wheel management falls into two different categories: one being the simulated wheel nodes controlled by the WheelHandler, the other being the wheels that we can actually see being rendered when we drive the car. Then we could feed data supplied to us by the WheelHandler to the rest of our suspension setup to get the desired results.

In short, the visible wheel and the simulated wheel could in fact be two entirely different objects, and the simulated wheel would not even have to be visible at all.

The wheel parameters we define in the VehicleWheel class can specify the collision mesh, radius and width explicitly. Those specifications do not necessarily have to correspond to any real geometry in the vehicle's skeletal mesh, so there is really no need for the simulated wheel nodes in the mesh to have any real geometry attached to them at all. Furthermore, we can specify additional wheel offsets in the wheel setup section of the vehicle Blueprint, so the pivot of our wheels do not have to be aligned with the geometrical center of the visible wheel mesh.

These are the basic insights we need to build a suspension that looks like it could realistically work from a mechanical point of view.

What Skeletal Nodes Can Do

Before we move on, we need to take a look at two animation Blueprint nodes that will be particularly useful for our setup. The WheelHandler node has already been covered, and we will definitely want to use that, but there are other powerful tools that are crucial for this type of rigging: the CopyBone and LookAt nodes. They can both be found in the Skeletal Control category in the animation Blueprint editor, and they perform much the same tasks as standard position, rotation and aim constraints typically do in an application like Maya.

Copy Bone

As its name suggests, the CopyBone node can copy transformation data from one bone (the source) to another bone (the target):



The CopyBone animation Blueprint node and its default settings.

This means that once the WheelHandler has updated the transformation of the simulated wheels, we could, for example, grab only the rotation values it has produced and apply them to our visible wheels. This basic step would take care of spinning and steering the wheels, which we do want, while we avoid getting the translation (position) data, which we do not want.

Look At

The LookAt node can rotate any given bone in such a way that one of its cardinal axes ends up aiming at another bone:



The LookAt animation Blueprint node and its default settings.

This is useful for our setup, because it gives us a way to make sure that all the components of the suspension mechanism are constantly updated to point in the right direction, all driven directly or indirectly by the current position of the simulated wheels. All we have to do is to make sure that there are bones available for the LookAt nodes to aim at. This will be used for several bones in our animation Blueprint.

Implementation Overview

To recap: for each of the four wheels we will use one invisible wheel for the WheelHandler to manage, and one visible wheel that is actually rendered in game. The former is just a single bone/joint, without any part of the mesh weighted to it, while the latter is any wheel-like mesh we build in a modeling package and add to the vehicle model, which is then imported into UE4 for final setup.

For everything to work as intended, key parts of the suspension will then copy the transformation data they need from other bones, or adjust their orientation by looking at targets that we have set up in the model.

Constructing the Model

With the theory out of the way, it is time to look at how this demo vehicle is constructed. If you open Assets/FBX/vehicle_proto_S2.9.fbx in your main modeling application, you can follow along and see how everything fits together.

The vehicle prototype created for this tutorial has a suspension rig designed like this:



Close-up on the front right suspension of the prototype vehicle. The colors have been added to this illustration for clarity - they are not assigned to materials in the FBX file.

The key components here are the upper and lower arms (yellow), the kingpin (red) and the hub (blue). Both arms pivot around their respective hexagonal bolts seen in the far right of the image.

The most central point where everything comes together is close to the green bolt on the lower arm. That is where the simulated wheel joint, PhysWheel_[loc], is initially located. The kingpin, hub, and visible wheel also have their pivots at that exact same location.

Each one of these components has a very strict responsibility and transformation range. The arms rotate only around their forward axis. The kingpin follows the position of the tip of the lower arm, but stays vertical at all times and never rotates relative to the vehicle. The hub rotates around its vertical axis only, in response to steering. The visible wheel copies its rotation from the simulated wheel, but takes its position from the tip of the lower arm. This keeps everything tightly locked together.

In any reasonably complex rig, it is very important to keep the hierarchy and update order in mind. In this particular case: when the lower arm rotates, it must bring with it a child mesh (lower green bolt) that the kingpin subsequently needs in order to position itself correctly using a CopyBone node. The upper arm in turn needs access to the updated position of a child mesh (near the upper green bolt) of the kingpin in order to have something to aim at using a LookAt node, and so on. As you can see, it is essential to make sure that the different components are updated in the correct order, otherwise parts of the suspension may appear to lag behind the movement of other parts.

All these frame-by-frame updates are handled by the animation Blueprint.

When building the model in a DCC (Digital Content Creation) application, we really only have to worry about the hierarchy and the exact position and orientation of the component pivots. A sensible orientation is particularly important for components that will have their rotation updated by LookAt nodes.

As a general note, it can be helpful to use the constraints offered by your modeling package while designing this kind of mechanism. They will not follow the FBX into UE4 on import, but sometimes it is easier to figure out what needs to be done if you can get some basic movement going while building the model, just to ensure that different components will be able to move the way they need to without intersecting each other. However, avoid using any constraints that you will not be able to recreate inside the animation Blueprint.

The Setup in Unreal Engine 4

Now let us see how this demo has been set up inside Unreal Engine. Load up the project file in the editor to follow along, and open the vehicle's animation Blueprint. Note that most of the operations are applied four times, once for each wheel.

While driving the vehicle, the following things happen in the animation Blueprint:

First, the WheelHandler updates the position and rotation of the simulated wheels (PhysWheel bones). The visible wheels (VisWheel bones) then update their rotation by copying the rotation from the PhysWheels:



The WheelHandler followed by Copy Rotation to the visible wheels.

This gives us a visually correct spin and steering, but the wheels will not change their position. That is handled separately in a later step.

Next, the lower arms (ArmLower bones) aim at the position of the PhysWheel. Arms on the right side of the vehicle use Y as the look at axis, while arms on the left side use Negative Y:



The ArmLower bones looking at the PhysWheel position.

The result of a LookAt node can easily be previewed in the 3D window of the animation Blueprint editor: the current target of a selected LookAt node is marked with a red cross. This is easier to see if you set the preview viewport to wireframe mode.

When an ArmLower bone rotates to match its LookAt target, it brings with it a child component called POS_Hub. This is used in the next step to correctly position the Kingpin using a CopyBone node which grabs only the translation of the POS_Hub bone:



Setting the Kingpin position.

The Hub and VisWheel will later be set to the same position using the same method.

The next step adjusts the upper arms (ArmUpper bones) by looking at their respective targets (LAT_ArmUp bones) which have been placed in the correct position by the fact that these targets are children of the Kingpin bones, which were updated in the previous step:



Orienting the upper arms.

After setting the position of the hubs, there is some extra work that needs to be done on the front hubs only, to account for rotation around Z caused by steering. This is handled with LookAt nodes targeting LAT_Hub bones that are children of the frontal PhysWheels:



Setting Hub position and steering angle.

Finally, after setting the VisWheel positions to match the POS_Hub bones, we make sure that the upper part of the shock is aimed at the lower shockmount (ShockMount_Low), and that the lower shock bone follows the position of that very same shockmount, which is a child of the upper arm:



Positioning visible wheels, and adjusting shock components.

PhAT

The prototype's physics asset setup is largely the same as the standard vehicle template, with a few exceptions. The most obvious difference is a lot of small spherical bodies along the antenna, but more importantly, there is a custom collision shape surrounding the main vehicle frame.



Collision bodies in PhAT.

Since the root component of this model is actually a joint, there is no geometry available from which to create a detailed collision volume. The main body volume was created by importing a separate Static Mesh equipped with a UCX mesh (Assets/FBX/vehicle_collision_S2.9.fbx).



Separately imported Static Mesh asset with collision.

We cannot handle this entirely inside PhAT. The first step is to build the collision asset in your 3D modeling package of choice, preferably by starting from the main body mesh itself. This collision model is then imported into UE4 as a standard Static Mesh, along with the UCX collision. Once that is done, we can simply copy this collision data over to the root node of the vehicle inside PhAT. This option is available when you right-click an existing body in PhATs Skeleton Tree panel. If the target bone does not already have a body assigned, you can just add a new body which will have a default capsule shape primitive attached. Then remove the capsule once the custom collision has been added.



Copy collision option, under "Advanced" in the menu.

Antenna Setup

While the antenna is not part of the double wishbone suspension setup, it can still affect the overall handling of the vehicle. The simplest solution is of course a completely rigid antenna, unaffected by physics, but this template shows how to set up an antenna that will move as you drive without negatively impacting your vehicle's movement.

In this template, each antenna bone starting from Antenna1 all the way to the tip at Antenna10 has been set up with a spherical body that has a radius roughly matching that of the antenna mesh itself. The bodies have Enable Gravity turned off to make sure the antenna can remain upright with a minimum of effort from the physics system. The mass of these bodies decays exponentially as we get closer to the tip, starting with a mass scale set to 16 at the bottom. The mass scale of the next body is set to 50% of the previous body, and so on, giving a full sequence from bottom to tip with the values 16, 8, 4, 2, 1, 0.5, 0.25, 0.12, 0.06 and 0.03. This gives us a heavy base, a featherlight tip, and a smooth gradient between the two extremes.



The constraints applied to these bodies are fully locked, both linearly and angularly. Since the bone chain is relatively long, small changes in orientation will still occur in response to acceleration, which combined with the mass scale settings described above gives us a stable simulation with just the right kind of mildly amusing oscillation.

To ensure that the simulation does not explode during extreme acceleration, all the antenna constraints have Enable Projection checked, using an Angular Tolerance of 1.0, and the Position Solver Iteration Count for the bodies has been bumped up to 16.



Finally, all internal collision between the antenna bodies as well as the rest of the vehicle's bodies has been disabled to prevent any unnecessary infighting. To do this easily, just select all the bodies in the Skeleton Tree panel, then click the Disable Collision button in the main PhAT toolbar.



Rolling Your Own

Now that you know how this setup works, you will no doubt want to start building your own model to replace this prototype. Below are some pointers that will help you do that with a minimum of headaches.

The first thing is to keep the names and the Skeleton Tree pretty much identical to the prototype. Doing that ensures that the Animation Blueprint can be reassigned and reused on a different Skeletal Mesh without any changes. That will save you a lot of time. All the meshes can of course be remodeled and moved to different positions. Just make sure that everything is properly aligned. Adding more mesh nodes to the model is not a problem, as long as it does not interfere with the overall hierarchy of the key suspension components.

The vehicle root should be placed at 0,0,0 in global space, and must not be rotated in any way. Making the root a simple joint object ensures that FBX export and import will work with a minimum of problems, particularly when using soft-bound components such as the deforming shock meshes.

If your modeling package allows it, set it up to use Z as the up axis. At any rate, assume that X is the forward axis even if your application of choice thinks that Y is forward.

The wheel meshes should touch the floor/grid in your modeling application. Always make sure that the individual components of your model have their pivots at the intended center of rotation, and that their rotation is zeroed out. The obvious exceptions are the shocks, where it makes more sense to orient the root and tip joints towards each other. Unless you know exactly what you are doing, never use any scaling other than 1,1,1, and avoid freezing transforms or equivalent functions.

Import Options

The following import settings, which were used for the prototype, should be a decent guideline for importing your own custom model:



Import options used for the prototype vehicle.

...and with that, you should have a pretty good idea about how to build your own advanced vehicle. Good luck!

Credit

This project and tutorial are based on work provided by community member Xenome, and are published here with permission.

Thank you, Xenome!

Basics

Joints

Binding

Export

Import

Physics Asset

Physics Body Creation Set-up

Create the Body Collision

Create the Wheel Collision

Taking it Further

The basic, bare minimum, art setup for a vehicle is just a Skeletal Mesh. The type of vehicle will decide how complicated an art setup you will need, and special consideration may need to be given to the suspension. A tank does not need to have a crazy suspension setup, because it will almost always go unseen, but a dune buggy, such as the one in Vehicle Game, will require more joints to make all the exposed components move in a believable way.

Basics

The vehicle mesh should point down Positive X.



You will need to measure the radius of your wheels, in centimeters, for use within Unreal Engine 4.



In the image above, the Distance Measurement tool in Maya is being used to get the diameter of the wheels based on the distance between 2 vertices opposite each other on the wheel. The radius of the wheel is half of this value.

A similar tool exists in the Helpers section of 3D Studio Max.

Joints

The absolute minimum number of joints required for a 4 wheeled vehicle, is 5:1 root, and 4 wheels. The wheel and root joints should be aligned with X forward, Z up:



This will ensure they roll on the Y axis and steer on the Z axis.

All other joints can be arranged as you see fit, but it should be noted that things like Look At nodes for the Animation Blueprint assume X forward.

To prevent visual oddities, the joints for the wheels should be accurately centered. The visual mesh will not be used for collision detection, however, if the wheel mesh is off center, then it will look like the wheel is broken, and will be really noticeable due to motion blur.

Binding

Standard smooth bind for Maya or Skin Modifier for 3DS Max. Wheels should only have weighting to one joint, so they can spin free with no odd deformation. For shocks and struts, you can get away with some fancy skinning, but it will require more thought on the Unreal Editor side.

Export

Vehicles are exported as Skeletal Meshes, with no special considerations.

Import

Vehicles are imported using the standard FBX import for a Skeletal Mesh. You will want to enable the importer's Create Physics Asset option.

Physics Asset



The Physics Asset is incredibly important for vehicles, and cannot be overlooked or skipped. When you first have Unreal Engine 4 create a Physics Asset for you, it will probably end up looking much like this:



That is because the Physics Asset Tool (PhAT) attempts to wrap the vertices skinned to a joint the best it can. However, you are going to delete and recreate them all. Why? The PhAT does not currently have a way to gracefully handle the re-creation of the constraints that hold all the Physics Bodies together. So if you delete an intermediate Physics Body, it does not create a new constraint up the hierarchy. However, if you delete all the Physics Bodies and start building them from the Vehicle root joint out, all your constraints will get created correctly.

In the Skeleton Tree panel with the default display options (Physics Bodies only), select and delete everything. This will remove all Physics Bodies from the asset.



Physics Body Creation Set-up

Open the Skeleton Tree panel Options dropdown menu, and select Show All Bones.



At each creation step, check that the Body Creation settings in the Tools panel are what you need; there are two settings in particular to pay attention to

Min Bone Size defines how large a bone must be for a Physics Body to be created for it, make sure it is set for an appropriate size for your Skeletal Mesh. In this example, we set it to 5.

Primitive Type controls the basic shape of the Physics Body created, you will need to change the type depending on the Physics Body being created.

For the purposes of this example, the other options can be left as is.



Create the Body Collision

Now, starting with your root joint, start creating physics bodies. Keeping in mind, you only need a physics body on a joint that either needs to be physically simulated or affects the bounds of the vehicle.

In the case of our buggy here, a box for the body and spheres for the wheels will be just fine to start, but it will require a number of other Physics Bodies to get the desired behavior.

Change the Body Creation Primitive Type to Box.

Right-click the rootJNT bone in the Skeleton Tree panel to open the context menu.

Select Add/Replace Bodies.



You can then move, rotate, and scale the new Physics Body to better approximate the shape of your vehicle



The Physics Body created will be the root of the hierarchy of Constraints and Physics Bodies created for the rest of the mesh. You can see the relations directly in the Graphs panel, and alongside the bones in the Skeleton Tree panel.

Create the Wheel Collision

To create the spheres for the wheels:

Change the Body Creation Primitive Type to Sphere.



Select the wheel joint bones in the Skeleton Tree panel, then right-click to open the context menu.

Select Add Replace/Bodies.



Select the newly created Physics Bodies for the wheels, then right-click to open the context menu.

Under Physics Type, select Kinematic.



You can also change the Physics Type from the Details panel in the Physics section.



This is necessary for the wheels to affect the bounds of the vehicle so shadows and culling occur correctly, and also, to prevent them from just rolling off the vehicle once your game begins.

The wheel Physics Bodies are never actually used for collision. Currently, the wheels use a ray casting for interacting with the world.

Taking it Further

This is just a simple setup for a basic imported vehicle mesh. If you examine the Physics Asset for the Vehicle in Vehicle Game, it looks like this:



Outside of the wheels, all of those collision bodies exist on the root joint of the vehicle. They prevent the wheels from getting jammed on certain game elements, and also prevents the meshes of the wheels from clipping through walls and railings.

Basics

Managing Sessions

Network Multiplayer Programming

Deploying Multiplayer Games

Debugging and Optimization

Tutorials and Examples

Modern multiplayer experiences require synchronizing vast amounts of data between large numbers of clients spread around the world. What data you send and how you send it is extremely important to providing a compelling experience to users since it can drastically affect how your project performs and feels. In Unreal Engine (UE), Replication is the name for the process of synchronizing data and procedure calls between clients and servers. The Replication system provides a higher-level abstraction along with low-level customization to make it easier to deal with all the various situations you might encounter when creating a project designed for multiple simultaneous users.

Basics



Setting up networked games for multiplayer.



Create a simple multiplayer game in C++.

Managing Sessions



An overview of how travelling works in multiplayer.

Network Multiplayer Programming



An overview of the role of the server in multiplayer.



Information about Actor relevancy and priority



The various aspects of replicating Actor objects.



Designating function replication across the network



Detailed information about how Actor properties are replicated.



Detailed information about how to conditionally replicate Actor properties.



Detailed information about how object reference properties are replicated.



Learn how to replicate any UObject-derived class and the replicated properties they contain.



Overview of the Online Beacon system



Overview of the Replication Graph feature and Replication Graph Nodes.



Overview of the Replay system for recording and playback of gameplay



Overview of the Replay system for recording and playback of gameplay

Deploying Multiplayer Games



How to enable the Steam network protocol layer for Unreal Engine projects.

Debugging and Optimization



An Overview for Using Network Emulation in Unreal.



Testing and Debugging Networked Games in Unreal.



An overview of Logging for Network Games.



Emulate network packet lag and loss in Unreal Engine.



Set up the Unreal Editor for testing multiplayer games.



Analyze network traffic and performance information captured at runtime.



Some tips for optimizing the performance and bandwidth usage of Actor replication.



An overview of using Oodle Network to improve streaming performance for your project.

Tutorials and Examples



Detailed explanation of the Character Movement Component



Set up and run a dedicated server for your project.

Multiplayer Programming Quick Start

Actors and their Owning Connections

Plan for multiplayer early

The Client-Server Model

Client-Server Gameplay Example

Fundamental Networking Concepts

Network Modes and Server Types

Actor Replication

Variable Replication

Remote Procedure Calls (RPCs)

Tips and Further Reading

Basic Replicated Actor Checklist

Networking Tips

Tutorials

In a multiplayer session, game state information is communicated between multiple machines over an internet connection. In case single-player game, all information store on one machine. This makes multiplayer programming inherently more complex, than programming for a single-player game. The process of sharing information between players is delicate and adds several extra steps. Unreal Engine features a robust networking framework, that powers some of the world's most popular online games, helping to streamline this process. This page provides an overview of the concepts, that drive multiplayer programming, and the tools for building network gameplay, that are at your disposal.

Plan for multiplayer early

If there is a possibility, that your project might need multiplayer features at any time, you should build all of your gameplay with multiplayer in mind from the start of the project. If your team consistently implements the extra steps for creating multiplayer, the process of building gameplay will not be much more time-consuming compared with a single-player game. In the long run, your project will be easier for your team as a whole to debug and service. Meanwhile, any gameplay programmed for multiplayer in Unreal Engine will still work in single-player.

However, refactoring a codebase, that you have already built without networking, will require you to comb through your entire project and reprogram nearly every gameplay function. Team members will need to re-learn programming best practices, that they may have taken for granted up to that point. You also will not be prepared for the technical bottlenecks, that will be introduced by network speed and stability.

Introducing networking late in a project is resource-intensive and cumbersome compared with planning for it from the outset. We therefore advise, that you should always program for multiplayer, unless you are completely certain that your project will never need multiplayer features.

The Client-Server Model

In a single-player or local multiplayer game, your game is run locally on a standalone game. Players connect input to a single computer and control everything in the game directly, including the Actors, the world, and the user interface for each player, exists on that local machine.



Single-player and local multiplayer take place on only one machine.

In a network multiplayer game, Unreal Engine uses a client-server model. One computer in the network acts as a server and hosts a session of a multiplayer game, while all of the other players' computers connect to the server as clients. The server shares game state information with each connected client and provides a means for them to communicate with each other.



In network multiplayer, the game takes place between a server (1) and several clients (2) that are connected to it. The server processes gameplay, and the clients show the game to users.

The server, as the host of the game, holds the one true, authoritative game state. In other words, the server is where the multiplayer game is actually happening. The clients each remote-control Pawns that they own on the server, sending procedure calls to them in order to make them perform ingame actions. However, the server does not stream visuals directly to the clients' monitors. Instead, the server replicates information about the game state to each client, telling them what Actors should exist, how those Actors should behave, and what values different variables should have. Each client then uses this information to simulate a very close approximation of what is happening on the server.

Client-Server Gameplay Example

To help illustrate how this changes gameplay programming practices, here is an example of two players in a multiplayer game. System refers to them as Player 1 and Player 2, and break down the process of having them fire projectiles at each other.

Local Gameplay

Network Gameplay





Player 1 presses an input to fire a weapon.

Player 1's Pawn responds to this by firing its current weapon.

Player 1's weapon spawns a projectile and plays any accompanying sound or visual effects.

Player 1 presses an input on their local machine to fire a weapon.

Player 1's local Pawn relaying the command to fire the weapon to its counterpart Pawn on the server.

Player 1's weapon on the server spawns a projectile.

The server tells each connected client to create its own copy of Player 1's projectile.

Player 1's weapon on the server tells each client to play the sound and visual effects associated with firing the weapon.

Player 1's projectile moves forward from the weapon.

Player 1's projectile on the server moves forward from the weapon.

The server tells each client to replicate the movement of Player 1's projectile as it happens, so their version of Player 1's projectile also moves.

Player 1's projectile collides with Player 2's Pawn.

The collision triggers a function that destroys Player 1's projectile, causes damage to Player 2's Pawn, and plays any accompanying sound and visual effects.

Player 2 plays an onscreen effect as a response to being damaged.

Player 1's projectile on the server collides with Player 2's Pawn.

The collision triggers a function that destroys Player 1's projectile on the server.

The server automatically tells each client to destroy their copies of Player 1's projectile.

The collision triggers a function that tells all clients to play the accompanying sound and visual effects for the collision.

Player 2's Pawn on the server takes damage from the projectile's collision.

Player 2's Pawn on the server tells Player 2's Client to play onscreen effects as a response to being damaged.

In the standalone game, all of these interactions take place in the same world on the same machine, so they are easy to both understand and program in literal terms. When you spawn an object, for instance, you can take for granted that all players will be able to see it.

In the network game, these interactions take place in several different worlds: one that exists on the server, one that exists on Player 1's client, one that exists on Player 2's client, and an additional world for each other client that is participating in the session. Each world on each different machine has its own copy of the Pawns, their weapons, and the projectiles that they fire. The server is where the game is actually being played, but we need to make the clients' worlds look like the same events are happening in them. It is therefore necessary to selectively send information to each client to create a visual representation of the world on the server.

This process introduces a division between essential gameplay interactions (collision, movement, damage), cosmetic effects (visual effects and sound), and private player information (HUD updates). Each of these is relevant to a specific machine or set of machines in the network. However, the process of replicating this information is not completely automatic, and you must specify what information is replicated to which machines as you program your gameplay. The main challenges are choosing what information you should replicate and how so as to both provide a consistent experience to all players, but also minimize the amount of information that you are replicating so as to use as little network bandwidth as possible.

Fundamental Networking Concepts

The sections below detail the concepts that drive network gameplay within Unreal Engine. It will give you an overview and quick reference of several of the tools that will help you in building your own multiplayer games.

Network Modes and Server Types

Network mode describes a computer's relationship to a network multiplayer session. An instance of a game can take on any of the following network modes:

Network Mode

Description

Standalone

The game is running as a server, that does not accept connections from remote clients. Any players participating in the game are strictly local players. This mode is used for single-player and local multiplayer games. It will run both server-side logic and client-side logic as appropriate for the local players.

Client

The game is running as a client, that is connected to a server in a network multiplayer session. It will not run any server-side logic.

Listen Server

The game is running as a server hosting a network multiplayer session. It accepts connections from remote clients and has local players directly on the server. This mode is often used for casual cooperative and competitive multiplayer.

Dedicated Server

The game is running as a server hosting a network multiplayer session. It accepts connections from remote clients, but has no local players, so it discards graphics, sound, input, and other player-oriented features in order to run more efficiently. This mode is often used for games requiring more persistent, secure, or large-scale multiplayer.

Listen servers are easy for users to set up spontaneously since any user with a copy of the game can both start a listen server and play on the same computer. Games that support listen servers often feature an ingame UI for starting a server or searching for servers to join. However, because the player, who is hosting a listen server, is playing on the server directly, they have and has an advantage over other players, that must use a network connection to play, which raises concerns about fairness and cheating. There is also an extra processing load associated with running as a server and supporting player-relevant systems like graphics and sound. These factors make listen servers less suitable for games in highly competitive settings or games with very high network loads associated with them, but very convenient for casual cooperative and competitive multiplayer among a small group of players.

Dedicated servers are more expensive and difficult to configure, requiring a separate computer from all of the players, that would participate in a game, complete with its own network connection. However, all players joining a dedicated server experience the game with the same type of connection, which ensures fairness. Since a dedicated server does not render graphics or perform other logic, that would only be relevant to a local player, it is also able to process gameplay and networking more efficiently. This makes dedicated servers preferable for games requiring a large number of players or games requiring a high-performing, trusted server for either security, fairness, or reliability reasons. Such games would include MMOs, competitive MOBAs, or fast-paced online shooters.



Because standalone games serve as both a server and a client, any logic created for a multiplayer game will function in single-player with no additional work.



Actor Replication

Replication is the process of reproducing game state information between different machines in a network session. If replication is set up correctly, the different machines' instances of the game become synchronized. By default, most Actors do not have replication enabled and will perform all of their functions locally. You can enable replication for Actors of a given class by setting the bReplicates variable in a C++ Actor class or the Replicates setting of an Actor Blueprint to true.

The following are the most common replication features that you will use to create networked gameplay:

Replication Feature

Description

Creation and Destruction

When an authoritative version of a replicated Actor is spawned on a server, it automatically generates remote proxies of itself on all connected clients. It will then replicate information to those remote proxies. If you destroy an authoritative Actor, it will automatically destroy its remote proxies on all connected clients.

Movement Replication

If an authoritative Actor has Replicate Movement enabled, or bReplicateMovement is set to true in C++, it will automatically replicate its Location, Rotation, and Velocity.

Variable Replication

Any variables that are designated as being replicated will automatically replicate from the authoritative actor to its remote proxies whenever their values change.

Component Replication

Actor Components replicate as part of the Actor that owns them. Any variables within the Component that are designated as being replicated will replicate, and any RPCs called within the component will behave consistently with RPCs called in the Actor class.

Remote Procedure Calls (RPCs)

RPCs are special functions that are transmitted to specific machines in a network game. No matter what machine an RPC is initially called on, its implementation will run only on the machine it is intended for. These may be designated as Server (only runs on the server), Client (only runs on the Actor's owning client), or NetMulticast (runs on every machine connected to the session, including the server).

While common use cases like creation, destruction, and movement can be handled automatically, all other gameplay features do not automatically replicate by default, even when you enable replication. You must designate exactly which variables and functions you want to replicate as is appropriate to your game. Detailed information on all of the above replication features is available in the Property Replication guide.

Several common features of Actors, Pawns, and Characters do not replicate:

Skeletal Mesh and Static Mesh Components

Materials

Animation Blueprints

Particle Systems

Sound Emitters

Physics Objects

Each of these runs separately on all clients. However, if the variables that drive these visual elements are replicated, it will ensure that all client has the same information and therefore simulates them in approximately the same way.

An Actor's network role determines whose machine has control over the Actor during a network game. An authoritative Actor is considered to have control over that Actor's state, and will replicate information to other machines within the network multiplayer session. A remote proxy is a copy of that Actor on a remote machine, and it receives replicated information from the authoritative Actor. This is tracked by the Local Role and Remote Role variables, which can take the following values:

Network Role

Description

None

The Actor has no role in a network game and does not replicate.

Authority

The Actor is authoritative and replicates its information to remote proxies of it on other machines.

Simulated Proxy

The Actor is a remote proxy, that is controlled entirely by an authoritative Actor on another machine. Most Actors in a network game, like pickups, projectiles, or interactive objects, will appear as Simulated Proxies on remote clients.

Autonomous Proxy

The Actor is a remote proxy, that is capable of performing some functions locally, but receives corrections from an authoritative Actor. Autonomous Proxy is usually reserved for Actors under the direct control of a player, like Pawns.

The default model used by Unreal Engine is server-authoritative, meaning that the server always has authority over the game state, and information will always replicate from the server to clients. You would expect an Actor on the server to have a Local Role of Authority, and you would expect its counterparts on remote clients to have a Local Role of either Simulated or Autonomous Proxy.

For more information regarding Actors' network roles, refer to the Actor Role and Remote Role guide.

Pawns in a network game are owned by a PlayerController on a specific client's machine. Any time, that Pawn calls a client-only function, it will be directed only to the owning player's machine. No matter which machine calls the function. Actors, that have their Owner variable set to a specific Pawn, belong to that Pawn's owning client by association. They also direct client-only functions to their owner's machine. You may use the IsLocallyControlled function in C++, or the Is Locally Controlled node in Blueprint, to determine whether or not an Pawn is on its owning client.

Avoid using IsLocallyControlled in a custom Pawn class's constructor, as it is possible for a Pawn not to have any Controller assigned yet during construction.

For more information about ownership, refer to our guide on Actors and their Owning Connections.

Relevance is used to determine whether or not it is worthwhile to replicate an Actor during a multiplayer game. Actors, that are not considered relevant, are culled during replication. This saves bandwidth, so Actors, that are relevant, can replicate more efficiently. If an Actor is not owned by any players and not physically near any players, then it is not considered relevant and does not replicate. Non-relevant Actors still exist on the server and can affect the authoritative game state, but do not send information to clients until players are nearby. You can manually control relevance by overriding the IsNetRelevantFor function, and you can determine the distance at which an Actor is relevant using the NetCullDistanceSquared property.

Sometimes there is not enough bandwidth available to replicate all relevant Actors during a single frame of gameplay. Actors, therefore, have a Priority value, which determines which Actors get to replicate first. By default, Pawns and PlayerControllers have a NetPriority of 3.0, which makes them the highest-priority Actors in a game, while base Actors have a NetPriority of 1.0. The longer that an Actor goes without being replicated successfully, the higher its priority will get with each successive pass until it is replicated.

For more detailed information about Actors' relevance and priority, refer to our guide on Actor Relevancy and Priority.

Variable Replication

You can add replication to variables and object references either by using the Replicated or ReplicateUsing specifiers in their UPROPERTY macros in C++, or by designating them as Replicated in the Details Panel in Blueprint. Whenever a replicated variable's value changes on an authoritative Actor, its information is automatically sent from the authoriative Actor to the remote proxies connected to the session.

You can designate a RepNotify function, that will be called in response to an Actor successfully receiving replicated information, for specific variables. RepNotifies only trigger locally, when a variable is updated, making them a low-overhead way to trigger gameplay logic in response to variable changes on an authoritative Actor. You can access this functionality by using the ReplicatedUsing specifier in a variable's UPROPERTY macro in C++, or by changing the Replication setting for the variable in Blueprint to use a RepNotify.

RepNotifies are preferable over using RPCs or replicated functions, as they can be added to variables, that you would need to replicate regardless of other gameplay functionality, saving a significant amount of bandwidth over creating additional network calls.

Remote Procedure Calls (RPCs)

Remote Procedure Calls are also referred to as replicated functions. They can be called from any machine, but will direct their implementation to happen on a specific machine that is connected to the network session. There are three types of RPCs available:

RPC Type

Description

Server

Called only on the server, that is hosting the game.

Client

Called only on the client, that owns the Actor that the function belongs to. If the Actor has no owning connection, this logic will not be executed.

NetMulticast

Called on all clients, that are connected to the server, as well as the server itself.

Events and functions in Blueprints can be given the same designations by setting their Replicates dropdown in the Details Panel to one of the three types available.



You can designate a function in C++ as being an RPC by providing either the Server, Client, or NetMulticast specificer in its UFUNCTION macro. Their implementations use the suffix _Implementation in their code implementations.



ExampleClass.h





ExampleClass.cpp



Once you have designated a function as an RPC, you can give it gameplay logic and call it the way, that you would with any other function. For more details regarding RPCs, refer to the Remote Procedure Calls guide.

You must designate RPCs as being reliable or unreliable. In Blueprint, functions and events are assumed to be unreliable by default. By setting the Reliable setting in the Details Panel to true, you can designate the function as being reliable. In C++, you must add either the Reliable or Unreliable specifier to any RPC's UFUNCTION macro alongside its status as a Server, Client, or NetMulticast function.

Unreliable RPCs are not guaranteed to arrive at their intended destination, but they can be sent faster and more frequently, than reliable RPCs. They are most appropriate for functions, that are either not critical to gameplay, or that are called very frequently. As an example, Actor movement is replicated using an unreliable RPC, due to the fact that it can change every frame.

Reliable RPCs are guaranteed to arrive at their intended destination, and will remain in a queue until they are successfully received. They are most appropriate for functions, that are critical to gameplay, but that do not get called very frequently. Examples of this would include collision events, starting or ending the firing of a weapon, or spawning Actors.

Overuse of Reliable functions can result in overflowing the queue for them. This will result in forced disconnections. If you call a replicated function on a frame-by-frame basis, you should make it Unreliable. If you have a Reliable function that is bound to player input, you should limit how often the player can call that function.

The WithValidation specifier indicates, that in addition to an implementation of the function, there will also be a function, that validates the data of the incoming function call. This validation function has the same signature as the function, that it is responsible for, but it returns a boolean instead of its original return value. If it returns true, then it permits the RPC's Implementation to execute. If it returns false, then it prevents execution.



ExampleClass.cpp



Tips and Further Reading

The following are basic guidelines for implementing efficient and consistent multiplayer systems in your games.

Basic Replicated Actor Checklist

To create a replicated Actor, follow these steps:

Set the Actor's Replicated setting to True.

If the replicated Actor needs to move, set Replicates Movement to True.

When you spawn or destroy a replicated Actor, ensure that you do it on the server.

Set any variables that must be shared between machines to replicate. This usually applies to gameplay-essential variables.

Use Unreal Engine's pre-made Movement Components whenever possible, as they are already built for replication.

If you are using a server-authoritative model, make sure any new actions that the player can perform are triggered by Server functions.

Networking Tips

Use as few RPCs or replicated Blueprint functions as possible. If you can use a RepNotify instead, you should.

Use Multicast functions especially sparingly, as they create extra network traffic for each connected client in a session.

Server-only logic does not necessarily have to be contained in a server RPC if you can guarantee that a non-replicated function will only execute on the server.

Be cautious when binding Reliable RPCs to player input. Players can repeatedly press buttons very rapidly, and that will overflow the queue for Reliable RPCs. You should use some way of limiting how often players can activate these.

If your game calls an RPC or replicated function very often, such as on Tick, you should make it Unreliable.

Some functions can be recycled by calling them in response to gameplay logic, then calling them in response to a RepNotify to ensure that clients and servers have parallel execution.

You can check an Actor's network role to see if it is ROLE_Authority or not. This is a useful method for filtering execution in functions that activate on both server and client.

You can check if a Pawn is locally controlled by using the IsLocallyControlled function in C++ or the Is Locally Controlled function in Blueprint. This is useful for filtering execution based on whether it is relevant to the owning client.

Avoid using IsLocallyControlled in constructor scripts, as it is possible for a Pawn not to have a Controller assigned during construction.

Tutorials

For a thorough walkthrough of how to implement a simple multiplayer game using the above principles, refer to the Multiplayer Quick Start Guide.

First Person Shooter Tutorial

Testing Multiplayer

Actors and their Owning Connections

Networked Movement in the Character Movement Component

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Networking Overview

Setting Up Dedicated Servers

1. Essential Setup

2. Replicating the Player's Health with RepNotifies

3. Making the Player Respond to Damage

4. Creating a Projectile with Replication

5. Making the Projectile Cause Damage

6. Shooting the Projectile

7. Test Your Game

Final Result

On Your Own

Code Samples



Developing gameplay for a multiplayer game requires you to implement replication in your game's Actors. You must also design functionality specific to the server, which acts as the host for the game session, or a client, which represents a player connecting to the session. This guide walks you through the process of creating some simple multiplayer gameplay, and you will learn the following:

How to add replication to a base Actor.

How to take advantage of Movement Components in a network game.

How to add replication to variables.

How to use RepNotifies when a variable changes.

How to use Remote Procedure Calls (RPCs) in C++.

How to check an Actor's Network Role in order to filter calls that are performed within a function.

The end result will be a third-person game where players can throw exploding projectiles at one another. The bulk of the work we do will be creating the projectile and adding a damage response to the Character.

Before you begin, it is highly recommend, that you review the essentials in the Dedicated Servers and Networking Overview pages. As a point of comparison for this guide, you can refer to the First Person Shooter Tutorial, which does not introduce replication concepts.

1. Essential Setup

Open the Editor and create a New Project. Ensure that it has the following settings:

Is a C++ Project

Uses the Third-Person Template

Includes Starter Content

Targets Desktop

Once you have applied these settings, name your project ThirdPersonMP and click the Create button to continue. The project's C++ files will be created, and the Unreal Editor will open ThirdPersonExampleMap automatically.

Click the ThirdPersonCharacter standing in this scene and Delete it, then ensure, that there are two Player Starts are present in your map. These will handle spawning your players instead of the manually placed ThirdPersonCharacter, that the scene includes by default.



The Pawns and Characters in most templates have replication enabled by default. In this example, ThirdPersonCharacter already has a Character Movement Component, that will automatically replicate movement.

For more information on how the Character Movement Component handles replication and how to expand on its functionality, you can refer to the Character Movement Component guide.

Cosmetic components like the Character's Skeletal Mesh and its Animation Blueprint are not replicated. However, variables that are relevant to gameplay and movement, like a Character's velocity, are replicated. The Animation Blueprint reads these variables as they are updated. In this way, copies of each client's characters will update their visuals. The process is performed in such a way that they are consistent with accurate updating of gameplay variables Likewise, the



If you start a server with this project and have a client join it, you would already have a functioning multiplayer game. However, players would only be able to move and jump with their avatar. Therefore, you will create some additional multiplayer gameplay.

2. Replicating the Player's Health with RepNotifies

Players need a health value, so that you can cause damage to them during gameplay. That value needs to replicate and all clients have synchronized information about each player's health. You need to provide feedback to a player, when they take damage. This section will demonstrate how it is possible to use a RepNotify to synchronize all essential updates to a variable without relying on RPCs.

Just a quick reminder, that 'Role' has been replaced with 'GetLocalRole()' and 'GetRemoteRole()' respectively. You'll notice some sections below, that might have previously used 'Role' so just be mindful of the change.

Open ThirdPersonMPCharacter.h. Add the following Properties under protected:

Open ThirdPersonMPCharacter.h. Add the following Properties under protected:



ThirdPersonMPCharacter.h



You need strictly control how the player's health is changed, therefore these health values have the following constraints:

Open ThirdPersonMPCharacter.cpp. Add the following #include statements at the top, underneath the line that reads #include "GameFramework/SpringArmComponent.h":



ThirdPersonMPCharacter.cpp



These provide required functionality for variable replication, as well as access to the AddOnscreenDebugMessage function in GEngine. You will use it to output messages to the screen.

In ThirdPersonMPCharacter.cpp, add the following code at the bottom of the AThirdPersonMPCharacter constructor :



ThirdPersonMPCharacter.cpp



These will initialize the player's health. Any time a new copy of this Character is created, its current health will be set to its maximum health value.

In ThirdPersonMPCharacter.h, add the following public function declaration just after the AThirdPersonMPCharacter constructor:



ThirdPersonMPCharacter.h



In ThirdPersonMPCharacter.cpp, add the following implementation for this function:



ThirdPersonMPCharacter.cpp



The GetLifetimeReplicatedProps function is responsible for replicating any properties you designate with the Replicated specifier, and enables you to configure how a property will replicate. Here you are using the most basic implementation for CurrentHealth. If at any time you add more properties that need to be replicated, you must add them to this function as well.

You must call the Super version of GetLifetimeReplicatedProps, or inherited properties from your Actor's parent class will not replicate, even if the parent class designates them as being replicated.

In ThirdPersonMPCharacter.h, add the following function declaration under Protected:



ThirdPersonMPCharacter.h



In ThirdPersonMPCharacter.cpp, add the following implementation:



ThirdPersonMPCharacter.cpp



You will be using this function to perform updates in response to changes to the player's CurrentHealth. Currently its functionality is limited to onscreen debug messages, but additional functionality could be added. For example, an OnDeath function, that is called on all machines in order to trigger a death animation. Note, that OnHealthUpdate is not replicated, and you will need to manually call it on all devices.

In ThirdPersonMPCharacter.cpp, add the following implementation for OnRep_CurrentHealth:



ThirdPersonMPCharacter.cpp



Variables replicate any time their value changes rather than constantly replicating, and RepNotifies run any time the client successfully receives a replicated value for a variable. Therefore, any time you change the player's CurrentHealth on the server, you would expect OnRep_CurrentHealth to run on each connected client. This makes OnRep_CurrentHealth the ideal place to call OnHealthUpdate on clients' machines.

3. Making the Player Respond to Damage

Now, that you have implemented the player's health, you need to provide a means for modifying the player's health from outside of this class.

In ThirdPersonMPCharacter.h, add the following function declarations under Public:



ThirdPersonMPCharacter.h



The GetMaxHealth and GetCurrentHealth functions provide getters, that can access the player's health values from outside of AThirdPersonMPCharacter, both in C++ and in Blueprint. As const functions they provide a safe means of getting these values without allowing them to be modified. You are also declaring functions for setting the player's health and taking damage.

In ThirdPersonMPCharacter.cpp, add the following implementation for SetCurrentHealth:



ThirdPersonMPCharacter.cpp



SetCurrentHealth provides a controlled means of modifying the player's CurrentHealth from outside of AThirdPersonMPCharacter. It is not a replicated function, but by checking that the Network Role of the Actor is ROLE_Authority, you restrict this function to execute only if it is called on the hosted game server. It clamps CurrentHealth to values between 0 and the player's MaxHealth, making it impossible to set CurrentHealth to an invalid value. It also calls OnHealthUpdate to ensure, that the server and clients both have parallel calls to this function. This is necessary, because the server will not receive the RepNotify.

While "setter" functions like this are not necessary for every variable, they are preferable for sensitive gameplay variables, that change frequently during play, especially if they can be modified by many different sources. This is a best-practice for single-player and multiplayer games alike, as it makes live changes to these variables more consistent, easier to debug, and easier to extend with new functionality.

In ThirdPersonMPCharacter.cpp, add the following implementation for TakeDamage:



ThirdPersonMPCharacter.cpp



The built-in functions for applying damage to Actors call the basic TakeDamage function for that Actor. In this case you implement a simple health deduction using SetCurrentHealth.

If you have followed this section so far, the following should now be the flow for applying damage to an Actor:

An external Actor or function calls CauseDamage on your Character, which in turn calls its TakeDamage function.

TakeDamage calls SetCurrentHealth to change the player's Current Health value on the server.

SetCurrentHealth calls OnHealthUpdate on the server, causing any functionality, that happens in response to changes in the player's health, to execute.

CurrentHealth replicates to all connected clients' copies of the Character.

When each client receives a new CurrentHealth value from the server, they call OnRep_CurrentHealth.

OnRep_CurrentHealth calls OnHealthUpdate, ensuring that each client responds the same way to the new CurrentHealth value.

This implementation has two main advantages. First, it condenses the workflow for adding new functionality around two key functions, namely SetCurrentHealth and OnHealthUpdate, which makes maintaining and expanding the code easier for the future. Second, since this implementation does not use any Server, Client, or NetMulticast RPCs, it condenses the amount of information being sent across the network, depending only on the replication of CurrentHealth to trigger all essential changes. Since CurrentHealth would need to replicate regardless of what other functions you implement, this is the most efficient possible model for replicating health changes.

4. Creating a Projectile with Replication

Inside the Unreal Editor, create a new C++ class using either the Tools menu or the Content Browser.



In the Choose Parent Class menu, choose Actor as the Parent Class and click Next.



Click image for full view.

In the Name Your New Actor menu, name your class ThirdPersonMPProjectile and click Create Class.



Click image for full view.

Open ThirdPersonMPProjectile.h and add the following code inside the class definition, under public:



ThirdPersonMPProjectile.h



You need precede each of the types in these declarations with the class keyword. This makes each of them a forward declaration of their own classes in addition to being variable declarations, which ensures that their classes will be recognized within the header file. You will be adding `#include`s for them in the CPP file during the next step.

The properties you are declaring will provide you with the following:

A Static Mesh Component to act as a visual representation of the Projectile.

A Sphere Component to check for collisions.

A Projectile Movement Component to move the Projectile.

A Particle System reference that you are going to use to spawn an explosion effect in a later step.

A Damage Type for use in damage events.

A float value for Damage to denote how much health should be subtracted, when a Character is hit by this Projectile.

However, none of these are defined yet.

Like the Character Movement Component, the Projectile Movement Component automatically handles replication, when it moves the Actor that it belongs to, provided that the Actor has bReplicates set to True.

Open ThirdPersonMPProjectile.cpp, and add the following code to the #include statements at the top of the file, underneath the line #include "ThirdPersonMPProjectile.h":



ThirdPersonMPProjectile.cpp



You will need use each of these throughout this walkthrough. The first four are the components you are using, while GamePlayStatics.h will give you access to basic gameplay functions, and ConstructorHelpers.h will give you access to some useful Constructor functions for setting up our components.

Add the following code inside of the AThirdPersonMPProjectile constructor:



ThirdPersonMPProjectile.cpp



The bReplicates variable tells the game that this Actor should replicate. By default, the Actor would only exist locally on the machine that spawns it. With bReplicates set to True, as long as an authoritative copy of the Actor exists on the server, it will try to replicate the Actor to all connected clients.

Add the following code inside of the AThirdPersonMPProjectile constructor:



ThirdPersonMPProjectile.cpp



This will define the SphereComponent when the object is constructed, giving your Projectile collision.

Add the following code inside of the AThirdPersonMPProjectile constructor:



ThirdPersonMPProjectile.cpp



This will define the StaticMeshComponent that you are using as a visual representation. It will automatically try to find the Shape_Sphere mesh inside of StarterContent and fill it in. The sphere will also be scaled so as to align with your SphereComponent in size.

Add the following code inside of the AThirdPersonMPProjectile constructor:



ThirdPersonMPProjectile.cpp



This will set the asset reference for your ExplosionEffect to be the P_Explosion asset inside of StarterContent.

Add the following code inside of the AThirdPersonMPProjectile constructor:



ThirdPersonMPProjectile.cpp



This will define the Projectile Movement Component for your Projectile. This Component is replicated, and any movement that it performs on the server will be reproduced on clients.

Add the following code inside of the AThirdPersonMPProjectile constructor:



ThirdPersonMPProjectile.cpp



These will initialize both the amount of Damage that the Projectile will deal to an Actor as well as the Damage Type that will be used in the damage event. Here you are initializing with the base UDamageType, as you have not yet defined any new Damage Types.

5. Making the Projectile Cause Damage

If you have been following along thus far, then it is possible for you to spawn the projectile on the server, and it will appear and move on all clients. However, if it hits a wall or a blocking object, it will stop. You need it to apply damage to players, and you need to show an explosion effect to all of the connected Clients in the session.

In ThirdPersonMPProjectile.h, add the following code under Protected:



ThirdPersonMPProjectile.h



In ThirdPersonMPProjectile.cpp, add the following implementation for this function:



ThirdPersonMPProjectile.cpp



The Destroyed function is called any time an Actor is destroyed. Particle emitters themselves do not normally replicate, but since Actor destruction does replicate, you destroy this projectile on the server. This function will be called on each connected client, when they destroy their own copies of it. As a result, all players will see the explosion effect, when the projectile is destroyed.

In ThirdPersonMPProjectile.h, add the following code under Protected:



ThirdPersonMPProjectile.h



In ThirdPersonMPProjectile.cpp, add the following implementations for this function:



ThirdPersonMPProjectile.cpp



This is the function, that you are going to call when the Projectile impacts with an object. If the object it impacts with is a valid Actor, it will call the ApplyPointDamage function to damage it at the point, where the collision takes place. Meanwhile, any collision regardless of the impacted surface will destroy this Actor, causing the explosion effect to appear.

In ThirdPersonMPProjectile.cpp, add the following code to the AThirdPersonMPProjectile constructor, underneath the line that reads RootComponent = SphereComponent:



ThirdPersonMPProjectile.cpp



This will register the OnProjectileImpact function with the OnComponentHit event on the Sphere Component, which acts as the projectile's primary collision component. To make especially sure, that only the server runs this gameplay logic, you check for GetLocalRole() == ROLE_Authority before registering OnProjectileImpact.

6. Shooting the Projectile

Open the Unreal Editor, then click the Edit drop-down menu at the top of the screen, and open your Project Settings.



In the Engine section, click on Input to open up your project's Input Settings. Unfold the Bindings section and add a new entry to it. Name it "Fire", and select the Left Mouse Button as the key this Action is bound to.



Click image for full view.

In ThirdPersonMPCharacter.cpp, add the following #include, underneath the line that reads #include "Engine/Engine.h":



ThirdPersonMPCharacter.cpp



This will enable your Character class to recognize the projectile's type and spawn it.

In ThirdPersonMPCharacter.h, add the following code under protected:



ThirdPersonMPCharacter.h



These are the variables and functions you will be using to fire your projectiles. HandleFire is the only RPC you will implement in this tutorial, and it will be responsible for spawning projectiles on the server. Because it has the Server specifier, any attempt to call it on a client will result in the call being directed over the network to the authoritative Character on the server instead.

Because HandleFire has the Reliable specifier as well, it is placed into a queue for reliable RPCs whenever it gets called, and it is removed from the queue, when the server successfully receives it. This guarnatees that the server will definitely receive this function call. However, the queue for reliable RPCs can overflow if too many RPCs are placed into it at once without removing them, and if it does then it will force the user to disconnect. Therefore, you need to be cautious in how often you allow players to call this function.

In ThirdPersonMPCharacter.cpp, add the following code to the bottom of the AThirdPersonMPCharacter constructor:



ThirdPersonMPCharacter.cpp



These will initialize the variables necessary to handle firing the projectile.

In ThirdPersonMPCharacter.cpp, add the following implementations:



ThirdPersonMPCharacter.cpp



StartFire is the function, that players call on their local machine in order to initiate the firing process, and it restricts how often the user is allowed to call HandleFire based on the following criteria:

The user cannot fire a projectile if they are already in the middle of firing. This is designated with bFiringWeapon, which is set to true when StartFire is called.

bFiringWeapon is only set to false when StopFire is called.

StopFire is called when a timer with a length of FireRate finishes.

This means that when the user fires a projectile, they must wait a number of seconds equal to FireRate before they can fire again. This will function consistently regarldess of what kind of input StartFire is bound to. For example, if the user binds the "Fire" command to a scroll wheel or similarly inappropriate input, or if they mash the button repeatedly, this function will still execute at an acceptable interval of time and not overflow the user's queue for reliable functions with calls to HandleFire.

Because HandleFire is a Server RPC, its implementation in the CPP file must have the suffix _Implementation added to the function name. Our implementation here uses the Character's Control Rotation to get the direction that the camera is facing, then spawn the projectile facing in that direction, enabling the player to aim. The projectile's Projectile Movement Component then handles moving it in that direction.

In ThirdPersonMPCharacter.cpp, add the following at the bottom of the function SetupPlayerInputComponent:



ThirdPersonMPCharacter.cpp



This binds StartFire to the Fire Input Action you created in the first step of this section, enabling the user to activate it.

7. Test Your Game

Open your Project in the Editor. Click the Edit drop-down menu, and open Editor Preferences.



Navigate to the Level Editor section and click the Play menu. Find the Multiplayer Options and change the Play Net Mode to Play As Listen Server. Also, set Play Number Of Clients to 2.



Click image for full view.

Press the Play button. The main Play in Editor (PIE) window will start a Multiplayer Session as the Server, and a second PIE window will open and connect as the Client.

Final Result



Click image for full view.

Both players in your game should be able to see each other moving, and they should also be able to shoot the custom projectile at each other. When one player is hit by the custom projectile, the explosion particle should appear for both players, and the player taking the hit will receive a "hit" message telling them how much damage they took and their current health, while all other players in the session should not see anything. If a player's health is reduced to 0, they should see a message informing them that they have been killed.

Now that you have completed this walkthrough, you should have a grasp on the basics of building multiplayer functionality in C++, including an overview of variable and component replication, how to work with Network Roles, and when it is appropriate to use RPCs. With this information you shlould be able to build your own multiplayer games within Unreal's Server-Client model.

On Your Own

To continue expanding your skills with Network Multiplayer programming, try to do the following:

Expand the Projectile's OnHit functionality to create additional effects, when the Projectile hits a target, like creating a Sphere Trace to simulate an explosion radius.

Extend ThirdPersonMPProjectile and experiment with its ProjectileMovement Component to create new variations with different behaviors.

Expand the TakeDamage function in ThirdPersonMPCharacter to kill the player's pawn and make them respawn.

Add a HUD to the local PlayerController and have it display replicated information or respond to Client functions.

Use DamageTypes to create personalized messages when a player is killed.

Explore the use of Game Mode, Player State, and Game State to create a complete set of rules for moderating a match with player stats and a scoreboard.

Code Samples



ThirdPersonMPProjectile.h





ThirdPersonMPProjectile.cpp





ThirdPersonMPCharacter.h





ThirdPersonMPCharacter.cpp



Network Multiplayer Basics

Gameplay Framework

Seamless and non-seamless travel

`UEngine::Browse`

`UWorld::ServerTravel`

`APlayerController::ClientTravel`

Enabling Seamless Travel

Seamless Travel Flow

Persisting Actors across Seamless Travel

Seamless and non-seamless travel

In Unreal Engine (UE), there are two main ways to travel: seamless and non-seamless. The main difference, is that seamless travel is a non-blocking operation, while non-seamless will be a blocking call.

When a client executes a non-seamless travel, the client will disconnect from the server and then re-connect to the same server, which will have the new map ready to load.

It is recommended that Unreal Engine multiplayer games use seamless travel when possible. It will generally result in a smoother experience, and will avoid any issues that can occur during the reconnection process.

There are three ways in which a non-seamless travel must occur:

When loading a map for the first time

When connecting to a server for the first time as a client

When you want to end a multiplayer game, and start a new one

There are three main function that drive travelling: UEngine::Browse, UWorld::ServerTravel, and APlayerController::ClientTravel. These can be a bit confusing when trying to figure out which one to use, so here are some guidelines that should help:

`UEngine::Browse`

Is like a hard reset when loading a new map.

Will always result in a non-seamless travel.

Will result in the server disconnecting current clients before travelling to the destination map.

Clients will disconnect from current server.

Dedicated server cannot travel to other servers, so the map must be local (cannot be URL).

`UWorld::ServerTravel`

For the server only.

Will jump the server to a new world/level.

All connected clients will follow.

This is the way multiplayer games travel from map to map, and the server is the one in charge to call this function.

The server will call APlayerController::ClientTravel for all client players that are connected.

`APlayerController::ClientTravel`

If called from a client, will travel to a new server

If called from a server, will instruct the particular client to travel to the new map (but stay connected to the current server)

Enabling Seamless Travel

To enable seamless travel, you need to setup a transition map. This is configured through the UGameMapsSettings::TransitionMap property. By default this property is empty, and if your game leaves this property empty, an empty map will be created for the transition map.

The reason the transition map exists, is that there must always be a world loaded (which holds the map), so we can't free the old map before loading the new one. Since maps can be very large, it would be a bad idea to have the old and new map in memory at the same time, so this is where the transition map comes in.

So now we can travel from the current map to the transition map, and then from there we can travel to the final map. Since the transition map is very small, it doesn't add much extra overhead while it overlaps the current and final map.

Once you have the transition map setup, you set AGameModeBase::bUseSeamlessTravel to true, and from there seamless travel should work!

Seamless Travel Flow

Here is the general flow when executing seamless travel:

Mark actors that will persist to the transition level (more below)

Travel to the transition level

Mark actors that will persist to the final level (more below)

Travel to the final level

Persisting Actors across Seamless Travel

When using seamless travel, it's possible to carry over (persist) actors from the current level to the new one. This is useful for certain actors, like inventory items, players, etc.

By default, these actors will persist automatically:

The GameMode actor (server only)

Any actors further added via AGameModeBase::GetSeamlessTravelActorList

All Controllers that have a valid PlayerState (server only)

All PlayerControllers (server only)

All local PlayerControllers (server and client)

Any actors further added via APlayerController::GetSeamlessTravelActorList called on local PlayerControllers



RPCs

Networking Overview

You will hear a lot about the owning connection of an actor. Ultimately, each connection has a PlayerController, created specifically for that connection (read more about this process in the client connection flow details). Each PlayerController that is created for this reason, is owned by that connection. To determine if an actor in general is owned by a connection, you query for the actors most outer owner, and if the owner is a PlayerController, then that actor is also owned by the same connection that owns the PlayerController.

One example of this is when Pawn actors are possessed by a PlayerController. Their owner will be the PlayerController that they are possessed by. During this time, they are owned by the connection of the PlayerController. The Pawn is only owned by this connection during the time it is also owned/possessed by the PlayerController. So as soon as the PlayerController no longer possesses the Pawn, the Pawn is no longer owned by the connection.

Another example is inventory items that are owned by a Pawn. These inventory items are owned by the same connection (if any) that might own that Pawn.

Components are a little special in how they determine their owning connection. In this case, we first determine the components owner by walking the components outer chain until we find the owning actor, and then we continue as above by determining owning connection of this actor.

Connection ownership is important for a few things:

RPCs need to determine which client will execute a run-on-client RPC

Actor replication and connection relevancy

Actor property replication conditions when the owner is involved

Connection ownership is important for things like RPCs, because when you call an RPC function on an actor, unless the RPC is marked as multicast, it needs to know which client to execute that RPC on. It determines the connection to send the RPC to by finding the owning connection.

Connection ownership is used during actor replication, and determining which connections get updates for each actor. For actors that have bOnlyRelevantToOwner set to true, only the connection that owns that actor will receive property updates for that actor. By default, all PlayerControllers have this flag set, and this is why each client only receives updates for PlayerControllers that they own. This is done for various reasons, the main ones being to prevent players from cheating and efficiency.

Connection ownership is important during property replication involving conditions that use the owner. For example. When COND_OnlyOwner is used, only the owners of that actor will receive these property updates.

Lastly, the owning connection is important for actors that are autonomous proxies (Role is ROLE_AutonomousProxy). For these actors, their role is downgraded to ROLE_SimulatedProxy while their properties are replicated to connections that don't own these actors.



Performance and Bandwidth Tips

Relevancy

Prioritization

Relevancy

A level can be huge, and at any time a player can only see a small fraction of the Actors in that level. Most of the other Actors in the level are not visible, are not audible, and have no significant effect on the player. The set of Actors that a server deems are visible to or capable of affecting a client are deemed the relevant set of Actors for that client. A significant bandwidth optimization in Unreal Engine (UE) network code is that the server only tells clients about Actors in that client's relevant set.

Unreal applies the following rules (in order) in determining the relevant set of Actors for a player. These tests are implemented in the virtual function AActor::IsNetRelevantFor().

If the Actor is bAlwaysRelevant, is owned by the Pawn or PlayerController, is the Pawn, or the Pawn is the Instigator of some action like noise or damage, it is relevant.

If the Actor is bNetUseOwnerRelevancy and has an Owner, use the owner's relevancy.

If the Actor is bOnlyRelevantToOwner, and does not pass the first check, it is not relevant.

If the Actor is attached to the skeleton of another Actor, then its relevancy is determined by the relevancy of its base.

If the Actor is hidden (bHidden == true) and the root component does not collide then the Actor is not relevant.

If there is no root component, AActor::IsNetRelevantFor() will log a warning and ask if the Actor should be set to bAlwaysRelevant=true.

If AGameNetworkManager is set to use distance based relevancy, the Actor is relevant if it is closer than the net cull distance.

Pawn and PlayerController override AActor::IsNetRelevantFor() and have different conditions for relevancy as a result.

Note that bStatic Actors (which remain on the client) can also be replicated.

These rules are designed to give a good approximation of the set of Actors which really can affect a player. Of course, it is imperfect: the distance check can sometimes give a false negative with large Actors (though we use some heuristics to help it out), it does not account for sound occlusion of ambient sounds, and so on. However, the approximation is such that its error is overwhelmed by the error inherent in a network environment with such latency and packet loss characteristics as the Internet.

Prioritization

Unreal uses a load-balancing technique that prioritizes all Actors, and gives each one a fair share of the bandwidth based on how important it is to gameplay.

Each Actor has a floating point variable called NetPriority. The higher the number, the more bandwidth that Actor receives relative to others. An Actor with a priority of 2.0 will be updated exactly twice as frequently as an Actor with priority 1.0. The only thing that matters with priorities is their ratio; so obviously you cannot improve Unreal's network performance by increasing all of the

Some of the values of NetPriority we have assigned in our performance-tuning are:

Actor = 1.0

Matinee = 2.7

Pawn = 3.0

PlayerController = 3.0

The current priority of an Actor is calculated using the virtual function AActor::GetNetPriority(). To avoid starvation AActor::GetNetPriority() multiplies NetPriority with the time since the Actor was last replicated. The GetNetPriority functions also consider the relative location of and distance between the Actor and the viewer.

Actors and their Owning Connections

Networking Overview

Role/RemoteRole Reversal

Mode of Replication

`ROLE_SimulatedProxy`

`ROLE_AutonomousProxy`

There are two properties on actor that are important when it comes to replication. Role and RemoteRole.

These two properties tell you:

Who has authority over the actor

Whether the actor is replicated or not

The mode of replication

The first important thing to determine, is who has authority over a particular actor. To determine if the current running instance of the engine has authority, check that the Role property is ROLE_Authority. If it is, then this running instance of Unreal Engine (UE) is in charge of this actor (whether it's replicated or not).

If Role is ROLE_Authority, and RemoteRole is either ROLE_SimulatedProxy or ROLE_AutonomousProxy, then this instance of the engine is in charge replicating this actor to remote connections.

Currently, only the server replicates actors to connected clients (clients will never replicate actors to the server). With this in mind, ONLY the server should see Role == ROLE_Authority and RemoteRole == ROLE_SimulatedProxy or ROLE_AutonomousProxy.

Role/RemoteRole Reversal

Role and RemoteRole could be reversed depending on who is inspecting these values. For example, if on the server you have this configuration:

Role == ROLE_Authority

RemoteRole == ROLE_SimulatedProxy

Then the client would see it as this:

Role == ROLE_SimulatedProxy

RemoteRole == ROLE_Authority

This makes sense, since the server is in charge of the actor, and replicating this actor to clients. The clients are just supposed to receive updates, and simulate the actor between updates.

Mode of Replication

The server doesn't replicate actors every update. This would take way too much bandwidth and CPU resources. Instead, the server will replicate actors at a frequency specified on the AActor::NetUpdateFrequency property.

This means that some time will pass on the client between actor updates. This could result in actors looking sporadic or choppy in their movement. To compensate for this, the client will simulate the actor between updates.

There are currently two types of simulation that occur.

`ROLE_SimulatedProxy`

This is the standard simulation path, and is generally based on extrapolating movement based on the last known velocity. When the server sends an update for a particular actor, the client will adjust its position towards the new location, and then in between updates, the client will continue to move the actor based on the most recent velocity sent from the server.

Simulating using last known velocity is just one example of how general simulation works. There is nothing stopping you from writing custom code to use some other information to extrapolate between server updates.

`ROLE_AutonomousProxy`

This is generally only used on actors that are possessed by PlayerControllers. This just means that this actor is receiving inputs from a human controller, so when we extrapolate, we have a bit more information, and can use actual human inputs to fill in the missing info (rather than extrapolating based on the last known velocity).

Actors and their Owning Connections

Components

Using RPCs

Quick Tips

Requirements and Caveats

RPC invoked from the server

RPC invoked from a client

Reliability

Blueprints

Validation

RPCs (Remote Procedure Calls) are functions that are called locally, but executed remotely on another machine (separate from the calling machine).

RPC functions can be very useful and allow either the client or the server to send messages to each other over a network connection.

The primary use case for these features are to do unreliable gameplay events that are transient or cosmetic in nature. These could include events that do things such as play sounds, spawn particles, or do other temporary effects that are not crucial to the Actor functioning. Previously these types of events would often be replicated via Actor properties.

When using RPCs, it it also important to understand how ownership works, since it determines where most RPCs will run.

Using RPCs

To declare a function as an RPC, you simply need to add Server, Client, or NetMulticast keywords to the UFUNCTION declaration.

For example, to declare a function as an RPC that will be called on the server, but executed on the client, you would do this:

To declare a function as an RPC that will be called on the client, but executed on the server is very similar but uses the Server keyword:

There is another special type of RPC function type called Multicast. Multicast RPCs are designed to be called from the server, and then executed on the server as well as all currently connected clients. To declare a multicast function, you simply use the NetMulticast keyword:

Multicast RPCs can also be called from clients but will only execute locally in this case.

Quick Tips

Notice how we prepended the Client, Server, or Multicast keyword to the beginning of the functions. This is an agreed upon convention that we have made internally to signify to programmers using this function that this will be called on the client, server, or all clients respectively.

This is very useful to determine at a glance what machines this function will be called on during a multiplayer session.

Requirements and Caveats

There are a few requirements that need to be met for RPCs to be completely functional:

They must be called from Actors.

The Actor must be replicated.

If the RPC is being called from server to be executed on a client, only the client who actually owns that Actor will execute the function.

If the RPC is being called from client to be executed on the server, the client must own the Actor that the RPC is being called on.

Multicast RPCs are an exception:

If they are called from the server, the server will execute them locally as well as execute them on all currently connected clients.

If they are called from clients, they will only execute locally, and will not execute on the server.

For now, we have a simple throttling mechanism for multicast events: a multicast function will not replicate more than twice in a given Actor's network update period. Long term, we expect to improve on this and have better support for cross channel traffic management and throttling.

The following tables summarize where a given type of RPC will execute, depending on the ownership of the calling actor (leftmost column).

RPC invoked from the server

Actor ownership

Not replicated

NetMulticast

Server

Client

Client-owned actor

Runs on server

Runs on server and all clients

Runs on server

Runs on actor's owning client

Server-owned actor

Runs on server

Runs on server and all clients

Runs on server

Runs on server

Unowned actor

Runs on server

Runs on server and all clients

Runs on server

Runs on server

RPC invoked from a client

Actor ownership

Not replicated

NetMulticast

Server

Client

Owned by invoking client

Runs on invoking client

Runs on invoking client

Runs on server

Runs on invoking client

Owned by a different client

Runs on invoking client

Runs on invoking client

Dropped

Runs on invoking client

Server-owned actor

Runs on invoking client

Runs on invoking client

Dropped

Runs on invoking client

Unowned actor

Runs on invoking client

Runs on invoking client

Dropped

Runs on invoking client

Reliability

By default, RPCs are unreliable. To ensure that an RPC call is executed on the remote machine, you can specify the Reliable keyword:

Blueprints

Functions that are marked as RPCs will also be replicated if called from Blueprints. In this case, they will follow the same rules as if they are being called from C++. It is not possible at this time to dynamically mark functions as an RPC from Blueprints.

Custom events can however be marked as replicated from within the Blueprint editor.

To use this feature, create a new custom event in your event graph. Click on the custom event and edit the Replication settings in the details view:



Validation

Recently, the ability to add validation functions to RPCs was added to serve as a choke point for detecting bad data/inputs. The idea is if the validation function for an RPC detected that any of the parameters were bad, it could notify the system to disconnect the client/server who initiated the RPC call.

To declare a validation function for an RPC, simply add the WithValidation keyword to the UFUNCTION declaration statement:

Then, somewhere next to the Implementation function, put the Validate function:

A more recent change was added to UHT to require client->server RPC's to have a _Validate function. This is to encourage secure server RPC functions, and to make it as easy as possible for someone to add code to check each and every parameter to be valid against all the known input constraints.

Replicating object references

Conditional Property Replication

RPCs

Setting up properties for replication

Network Update Optimization

Data-Driven Network Update Frequency

Adaptive Network Update Frequency

(Advanced) Update Frequency Decrease Algorithm

(Advanced) Update Frequency Increase Algorithm

Each Actor maintains a list of all properties that include the Replicated Specifier. The server will send an update to each client whenever a replicated property changes its value, which the client will apply to its local version of the Actor. These updates only come from the server; the client will never send property updates to the server or other clients.

Changing a replicated variable's value on the client is not recommended. The value will continue to differ from the server's value until the next time the server detects a change and sends an update. If the server's copy of the property does not change very often, it could be a long time before the client receives a correction.

Actor property replication is reliable. This means that the property of the client version of the Actor will eventually reflect the value on the server, but the client will not necessarily receive notification of every individual change that happens to a property on the server. For example, if an integer property rapidly changes its value from 100 to 200, and then to 300, the client will eventually receive an update with the value of 300, but there is no guarantee that the client will know about the change to 200.

Setting up properties for replication

To replicate a property, you need to do a few things: In the header of the actor class where the property is defined, you need to make sure you have the replicated keyword as one of the parameters to the UPROPERTY declaration:

In the implementation of the actor class, you need to implement the GetLifetimeReplicatedProps function:

In the actor's constructor, make sure you have the bReplicates flag set to true:

The member variable Owner will now be synchronized to all connected clients for every copy of this actor type that is currently instantiated (in this case, the base actor class).

Network Update Optimization

Data-Driven Network Update Frequency

Actors will observe a maximum update frequency set in their NetUpdateFrequency variable. By reducing this variable on less-important or less-frequently-changing Actors, network updates can be made more efficient, potentially leading to smoother play experiences in limited-bandwidth scenarios. Common update frequency values are 10 (updating every 0.1 seconds) for important, unpredictable Actors like player-controlled characters in a shooter, 5 (updating every 0.2 seconds) for slower-moving characters like AI-controlled monsters in cooperative games, or 2 (updating every 0.5 seconds) for background Actors that are not very important to gameplay, but are still synced over the network and/or are controlled by server-side logic and thus need replication.

Adaptive Network Update Frequency

By default, this feature is deactivated. Setting the console variable net.UseAdaptiveNetUpdateFrequency to 1 will activate it.

With Adaptive Network Update Frequency, we can save CPU cycles that would normally be wasted in redundant attempts to replicate an actor when nothing is really changing. When this feature is enabled, the system will dynamically adapt the update frequencies of individual Actors based on whether or not their updates are meaningful. In this context, a "meaningful" update is any update which initializes the Actor, adds or removes a subobject (i.e. an owned Component), or changes the value of a replicated field on the Actor or any of its subobjects. Each Actor's possible range of update rates is determined by two variables on the Actor itself: NetUpdateFrequency and MinNetUpdateFrequency. NetUpdateFrequency indicates the maximum number of times per second that the Actor will attempt to update itself, while MinNetUpdateFrequency indicates the minimum number of update attempts per second. Using this feature can result in massive replication performance improvement.

During update attempts, Actors determine how long it has been since the most recent meaningful update was sent, and record the new time if they send a meaningful update. If an Actor being considered for update has not sent a meaningful update for more than two seconds, it will start decreasing its update frequency, reaching its minimum frequency after seven seconds without a meaningful update. For example, if an Actor with an update delay between 0.1 and 0.6 seconds had no meaningful updates for 3 seconds, it would attempt its next update in 0.2 seconds.

After sending a meaningful update, an Actor will schedule its next update to happen in 30-percent less time than the time between the last two meaningful updates, clamped between the minimum and maximum update frequencies. For example, if an Actor went exactly one second between meaningful updates, it would schedule its next update attempt for 0.7 seconds in the future (or a time near the specified minimum and maximum update frequencies). With each successive meaningful update, this calculation will be repeated, quickly reducing the time between updates if an Actor starts to have frequent data or subobject changes.



Detailed information about how to conditionally replicate Actor properties.



Detailed information about how object reference properties are replicated.

Once a property is registered for replication, you can't unregister it (that's where the lifetime part comes from). The reason for this is because we bake in as much information as possible, so we can take advantage of sharing work across many connections for the same set of properties. This saves a lot of computation time.

So how does one get more fine grain control over how this property replicates? That's where conditional properties come in.

By default, each replicated property has a built-in condition, and that is that they don't replicate if they haven't changed.

To give you more control over how a property replicates, there is a special macro that allows you to add a secondary condition.

This macro is called DOREPLIFETIME_CONDITION. An example of its usage can be seen below:

The COND_SimulatedOnly flag that was passed into the condition macro will cause an extra check to be performed before even considering this property for replication.In this case, it will only replicate to clients that have a simulating copy of this actor.

One of the big benefits of this is that it saves bandwidth; since we've determined that client that has the autonomous proxy version of this actor doesn't need to know about this property (this client is setting this property directly for prediction purposes for example). Another benefit is that for the client not receiving this property, the server won't step on this client's local copy.

Here is a quick glance at the list of conditions currently supported, specified in the ELifetimeCondition enum in Engine\Source\Runtime\CoreUObject\Public\UObject\CoreNet.h:

Condition

Description

COND_InitialOnly

This property will only attempt to send on the initial bunch

COND_OwnerOnly

This property will only send to the actor's owner

COND_SkipOwner

This property send to every connection EXCEPT the owner

COND_SimulatedOnly

This property will only send to simulated actors

COND_AutonomousOnly

This property will only send to autonomous actors

COND_SimulatedOrPhysics

This property will send to simulated OR bRepPhysics actors

COND_InitialOrOwner

This property will send on the initial packet, or to the actors owner

COND_Custom

This property has no particular condition, but wants the ability to toggle on/off via SetCustomIsActiveOverride

So far we've talked about conditions that are based off of state that is already known. This makes it easy for the engine to make the necessary optimizations while still giving you enough control over property replication.

But what if this isn't enough control? There is one more thing to talk about on this subject. There is a macro called DOREPLIFETIME_ACTIVE_OVERRIDE, which gives you full control over when a property does and does not replicate, using any custom condition you want. The one caveat is that this is per actor, not per connection. So in other words, it's not safe to use a state that can change per connection in your custom condition. An example can be seen below.

The property ReplicatedMovement will now only replicate if bReplicateMovement is true.

Why not use this macro all the time? There are two main reasons to avoid this method:

If custom condition value changes a lot, this can slow things down.

You cannot use condition that can change per connection (don't check RemoteRole here).

Property replication conditions give a nice balance of control vs. performance. They give the engine the opportunity to optimize the time it takes to check and send the properties for many connections, while still giving the programmer fine-grained control over how and when properties replicate.

Conditional Property Replication

RPCs

Stably Named Objects

Generally, object references are handled automatically in the Unreal Engine (UE) multiplayer framework. What this means is, if you have a UObject property that is replicated, the reference to that object will be sent over the network as a special ID that is assigned by the server. This special ID is a FNetworkGUID. The server is in charge of assigning this ID, and then notifying all connected clients of this assignment.

To replicate object references, you simply mark a UObject property as replicated, like this:

In this case, the "Owner" property will be a replicated reference to the actor that this property refers to.

For an object to be legally referenced over the network, it must be supported for networking. To check for this, you can call UObject::IsSupportedForNetworking(). This is generally considered a low level function, so it's not common to need to check this in game code.

In general, these are the guidelines to go by to determine if you can reference an object over the network:

Any replicated actor can be replicated as a reference

Any non-replicated actor must be stably named (loaded directly from a package)

Any replicated component can be replicated as a reference

Any non-replicated component must be stably named.

All other UObjects (non actors or components) must come directly from loaded packages

Stably Named Objects

Stably named objects are simply objects that will exist on both the server and the client, and have exactly the same name.

Actors are stably named if they were loaded directly from packages (not spawned during gameplay).

Components are stably named if they were:

Loaded directly from a package

Added via simple construction scripts

Manually marked (via UActorComponent::SetNetAddressable)

This should only be used when you know you are manually naming the component so that it has the same name on the server and client (a good example are components added in an AActor C++ constructor)

Replicate Subobjects Overview

Registered Subobjects List Overview

Replicated Actor Components

Complex Replication Conditions

Client Subobjects List

Replicated Subobjects in Unreal Engine (UE) provide a way to replicate any UObject-derived class and the replicated properties they contain. The previous system for replicating components and subobjects uses the virtual function AActor::ReplicateSubobjects. With the new system, actors now have methods that register subobjects to a list on the owning Actor or Actor Component, with the replication of these registered subobjects handled automatically by the actor channel.

We explain both systems below. First, we walk through two examples that use the ReplicateSubobjects function. Then, we introduce the new Registered Subobjects List and walk through some code samples outlining its usage. Lastly, additional topics are discussed such as Complex Replication Conditions and maintaining Registered Subobjects Lists on clients.

Replicate Subobjects Overview

The previous system for replicating components and subobjects relies on the virtual function AActor::ReplicateSubobjects. For actors with replicated subobjects, this function needs to be overridden, with actors having to manually call ReplicateSubobject and ReplicateSubobjects on each of their replicated components or subobjects. Consider the following example:

Code Sample

In the above code sample, the actor makes the content of MySubObject a subobject in the ReplicateSubobjects function. At this stage, the pointer is net-referenceable. The Counter variable is then replicated to clients whenever the actor is replicated. If we did not make MySubObject a subobject via Channel->ReplicateSubobject(MySubObject), the MySubObject variable would always be null on clients.

Code Sample

Suppose CreateMyDerivedClass() is called after CreateMyClass(). The new pointer becomes a replicated subobject the next time ReplicateSubObjects is called. On the client side, the MySubObject variable changes and is now of type UMyDerivedSubObjectClass and both its Timer and Counter variables are replicated to the client.

Registered Subobjects List Overview

Actors now have new methods that register subobjects to a list on the owning Actor or Actor Component, with the replication of these registered subobjects handled automatically by the actor channel. The Registered Subobjects List allows for a ELifetimeCondition to be specified for subobjects when they are registered. This process offers greater control over when and where subobjects are replicated without requiring the user to implement this logic in ReplicateSubobjects. The need for actors to implement the virtual function AActor::ReplicateSubobjects and manually replicate individual subobjects is also eliminated.

Use the Registered Subobjects List

The following code sample outlines how to enable the Registered Subobject List.

Set the property bReplicateUsingRegisteredSubObjectList = true for your Actor class.

Call AddReplicatedSubObject in ReadyForReplication, BeginPlay, or when creating a new subobject. There are a few things to keep in mind when using Replicated Subobjects in an Actor Component class. Within an Actor Component class, ReadyForReplication is called between InitComponent and BeginPlay. Registering a component here allows it to call Remote Procedure Calls (RPCs) early inside of the component's BeginPlay.

Call RemoveReplicatedSubObject whenever you modify or delete a subobject.

This last step is very important. Unless the reference is removed, the list still contains a raw pointer to the subobject changed or marked for destruction. As a result, this causes a crash after the object is garbage collected.

When converting existing code, the net.SubObjects.CompareWithLegacy Console Variable (CVar) can be set to compare the new list with the old method at runtime. This triggers an ensure statement if any differences are detected.

Replicated Actor Components

Replicated Actor Components using this system are handled the same way as above since they are also replicated subobjects. To set a replication condition for an Actor Component, the owning actor class must implement AllowActorComponentToReplicate and return the ELifetimeCondition desired for the specific component. SetReplicatedComponentNetCondition can be called to directly change a component's condition after BeginPlay.

Make sure that AllowActorComponentToReplicate returns the new condition; otherwise, the condition will be reset if UpdateAllReplicatedComponents is ever called on the actor.

Use Replicated Subobjects with Actor Components

In the above example, the owning actor class is AMyWeaponClass. We want to set a replication condition for the UActorComponent ComponentToReplicate based on whether or not the weapon is currently in an actor's inventory. To accomplish this, the owning actor class AMyWeaponClass implements AllowComponentToReplicate.

While the weapon is on the ground, it is not in an actor's inventory. Therefore, we do not want to replicate components that will cause damage. The ELifetimeCondition returned in this case is COND_Never which specifies that these components will never be replicated. When we want to change the damage component's condition, such as when the weapon is picked up, SetReplicatedComponentCondition is called directly, setting the replication condition to COND_None meaning the component is always replicated.

For more information on the list of conditions supported for ELifetimeCondition, see Conditional Property Replication.

Actor Components Subobjects List

Actor Components can also have their own replicated subobjects list They use the same API as Actors for registering and unregistering their subobjects. Subobjects within an Actor Component can have replication conditions as well.

The owning component must be replicated to a connection before the conditions of its replicated subobjects are checked. For example, if a subobject has the COND_OwnerOnly condition, it will never be replicated if it is registered to a component that uses the COND_SkipOwner condition.

Complex Replication Conditions

The Replicated Subobjects system supports the creation of custom replication conditions for subobjects. This is accomplished through the NetConditionGroupManager and COND_NetGroup. Subobjects and Player Controllers can be part of multiple groups at the same time. In that case, a subject is replicated to a client if it is a part of at least one of the client's groups.

Implement and Use a Replication Group

Register your subobject with the COND_NetGroup condition.

Create an FName that will represent a replication condition.

Add the desired subobject to the replication group.

Add the clients we want to replicate the subobject to in the same group. This is done using the client's PlayerController.

The client of PlayerControllerAlphaOwner now receives this special subobject whenever the owning actor is replicated to that connection.

Client Subobjects List

While the server must maintain a Replicated Subobjects List, actors and components on clients should also maintain their subobject list locally. This is particularly important if a project is recording replays on clients. In this case, actors on a client are temporarily swapped to a local authority role when recording the actor into a replay. As a result, any replay recorded actors should maintain their subobject list on the client regardless of their local NetRole.

If the subobject in question is a replicated property, managing the subobject list on clients can be made easier by using a RepNotify function for the property. Clients can use the RepNotify to identify when the subobject has changed so that the old subobject pointer can be removed and the new one can be added.

While removing a subobject from the list on the server results in none of that object's replicated properties being sent to clients, the subobject's pointer is still net-referenceable until the UObject itself is marked as garbage. Once the server detects that the UObject is invalid, it will notify the clients to delete the subobject locally on the next reflection update.

The Replicated Subobjects List system does not support UActorChannel::KeyNeedsToReplicate(). We recommend using push-model replication for the subobect's replicated properties instead. Using push-model replication with the new system should be at least as efficient as using RepKeys.

RPCs

Property Replication

Online Beacon Base Classes

AOnlineBeacon

AOnlineBeaconHost

AOnlineBeaconClient

AOnlineBeaconHostObject

Online Beacon Example

Online Beacons are a special type of Actor that provide a lightweight way to contact a server and interact with it (via RPCs) without committing to a normal game connection. While the built-in classes can be used as they are in some cases, they are intended to be extended into custom classes that perform project-specific interactions, logic, and information requests.

Online Beacon Base Classes

Common actions performed by beacon classes are to request quality-of-service information, reserve a slot in a game that the client wishes to join, receive a list of the names of players in a game, find out the score and running time of a game in progress, and so on. The following classes are provided with the engine, and lay the foundation for the Online Beacon system:

AOnlineBeacon

This is the base class for AOnlineBeaconClient and AOnlineBeaconHost. It derives from AActor directly.

AOnlineBeaconHost

This class uses its own UNetDriver to listen for incoming Online Beacon connections from remote client machines. When it receives one, it looks through its list of registered AOnlineBeaconHostObject instances to find the one that matches the incoming client and hands the connection off to it. This class will not usually need to be derived, since it only manages the initial connection between the client and the registered AOnlineBeaconHostObject.

AOnlineBeaconClient

Children of this class connect to hosts and make the actual RPCs. One of these will be spawned on the client machine, and one will be spawned on the server by the appropriate AOnlineBeaconHostObject that is registered with the server's AOnlineBeaconHost. By default, the output of the GetBeaconType function (which will be the class name) will be used to match instances of this class to the registered instance of the appropriate host object class. Note that this is different from how Actor spawning usually works, where the server spawns the Actor and then replicates it to the client. However, once the connection between the client's and server's copy of the object has been made, replication of the object behaves as normal, with either side able to make RPCs to the other, and the server's version of the object being authoritative with regard to property replication. The base class implements OnConnected and OnFailure functions that can be overridden by child classes to perform RPCs when connected, or to handle failures to connect. This class is the workhorse of the Online Beacon system, and will do the client-side work that your Beacon requires. Since a second instance, synced with the original, will be spawned on the server in the event of a successful connection, this class can also do server-side work, coordinating and communicating through client and server RPCs, or server-to-client replicated properties.

AOnlineBeaconHostObject

This class should also be overridden so that it can be paired with an overridden AOnlineBeaconClient class. Pairing is accomplished by matching the return value of the client's GetBeaconType with the value stored in the BeaconTypeName member variable. When the server's AOnlineBeaconHost detects a paired AOnlineBeaconHostObject for an incoming AOnlineBeaconClient, it will instruct the AOnlineBeaconHostObject to spawn a local copy of the AOnlineBeaconClient via the virtual SpawnBeaconActor function. By default, this function uses the ClientBeaconActorClass member variable to determine the class of actor to spawn, which should be set to the paired AOnlineBeaconClient class. It also calls SetBeaconOwner on the server's copy of the spawned object, so that the server-side instance of the client object can communicate with the host object. Most of this setup is established in the base class, and does not need to be overridden.

Online Beacon Example

There are a variety of premade Beacon class pairs already in the engine, but the Test Beacon is a good, simple example of how to build your own. ATestBeaconClient is derived from AOnlineBeaconClient, and ATestBeaconHost is derived from AOnlineBeaconHostObject. The Test Beacon simply makes repeated function calls back and forth between the client and server. Here is how the classes work together:

In ATestBeaconHost's constructor, ClientBeaconActorClass is set to the class of ATestBeaconClient, and BeaconTypeName is set to the name (obtained by calling the GetName function) of ClientBeaconActorClass. This ensures that the AOnlineBeaconHost will pair the two Test Beacon classes correctly.

When the client's ATestBeaconClient successfully contacts the server, the server's AOnlineBeaconHost instance will direct the registered ATestBeaconHost to spawn its own ATestBeaconClient and associate it with the ATestBeaconClient on the client. This is important because it allows client and server RPCs to pass between the two ATestBeaconClient instances.

The server's ATestBeaconHost will then call OnClientConnected, a client RPC, on its ATestBeaconClient instance. Since this function is a client RPC, the command to call the function will be passed to the client machine rather than calling the function on the server.

On the client's ATestBeaconClient instance, the RPC will run the virtual OnConnected function, which has been overridden to call ClientPing.

ClientPing will output some text to the debug log and then call ServerPong, a server RPC, which will then be sent across the network connection and executed on the server's ATestBeaconClient instance.

ServerPong will output debug text and then call ClientPing, again triggering a networked RPC call to the client.

This process will continue indefinitely. While this is usually not desirable, especially since these RPCs aren't really doing anything, it could be used to keep track of a server's ping time by recording the time between two subsequent runs of the same RPC. There could also be a delay, so that this ping check is not done as frequently as the computer and network will allow, or the client or server could simply stop pinging back after a certain number of pings. Other use cases might involve only a single RPC call back to the client, rather than a continuing loop, such as asking a question along the lines of "What map is being used for this server's game?" or "Is this a Capture The Flag server?" depending on what information might be relevant to your specific game or project.

Structure

Enabling The System

Configuration (.ini) Files

Binding In Code

High-Level Example

The Replication Graph Plugin is a system for network replication in multiplayer games that is designed to scale well with large numbers of players and replicated Actors. As an example, Epic's own Fortnite Battle Royale starts each game with 100 connected players and about 50,000 replicated Actors. The standard network replication strategy, which is to require each replicated Actor to determine whether or not it should send an update to each connected client, performs poorly in cases like this and will bottleneck the server's CPU. Solutions like dividing Actors into staggered groups, or simply updating less frequently, might mitigate the issue, but will also degrade the client experience by decreasing update frequency. The Replication Graph eliminates the need for Actors to evaluate each connected client individually, solving the CPU performance issue without sacrificing the client experience.

Structure

The Replication Graph contains a series of Replication Graph Nodes, which are responsible for building lists of Actors to replicate to each client on demand. Because this system is built from persistent objects, as opposed to merely being function calls processed by the replicated Actors themselves, data can be stored across multiple frames and shared between client connections. This persistent, shared data is what enables the Replication Graph system to decrease the time it takes to produce replication lists for each client.

Replication Graph Nodes (we'll call them "nodes" for short) do the actual work of establishing which Actors potentially require updates, sorting them into groups, storing precomputed lists to send to clients, and so on. Their ultimate task is to provide "replication lists" of Actors on demand to each client connection as quickly as possible, so that the server spends as few CPU cycles as possible per Actor, per client. Each node can function in a unique way, and developers are encouraged to write custom nodes for their own games as needed. Nodes may be game-agnostic, or may leverage game-specific information. Putting Actors into different nodes based on their roles in your game can give you better control over how and when they replicate. Building new nodes and using the Replication Graph to assign Actors to the best nodes possible based on how they behave in your game will provide the greatest decreases in server CPU time spent on preparing network replication lists.

Enabling The System

You can configure your project to use a custom Replication Driver (the parent class of Replication Graph) in one of two ways:

Specifying a Replication Driver class in the "DefaultEngine.ini" file.

Binding a function that returns an instance of your Replication Driver class to the default Replication Driver's creation Delegate.

The ShooterGame project is a good example of how to set up and implement a Replication Graph. However, note that Replication Graph is disabled on console builds because it does not currently work in splitscreen games.

Configuration (.ini) Files

To configure the Engine's default Replication Driver, open the "DefaultEngine.ini" file for your project. Find (or add) the [/Script/OnlineSubsystemUtils.IpNetDriver] section and set (or add) the "ReplicationDriverClassName" entry so that it indicates the name of the Replication Driver (or Replication Graph) class you wish to use. This should look roughly as follows, substituting "ProjectName" with your actual project's name, and "ClassName" with your custom class name:

Binding In Code

If your project has multiple game modes or maps that have vastly different networking requirements, binding to a Delegate will enable you to create the appropriate Replication Driver for the current game mode or map in code. To use this method, bind a function to the UReplicationDriver function called CreateReplicationDriverDelegate. Your bound function must return a valid instance of your desired Replication Driver class, as this sample lambda function does:

High-Level Example

For a game with a large number of connected clients and an even larger number of synced Actors, a Replication Graph that assigns Actors based on type and status to different nodes can save a tremendous amount of CPU time. This makes it possible to build games that would not be viable with traditional replication methods. At a conceptual level, a game at this scale might build a Replication Graph and Replication Graph Nodes with the following features to handle its huge volume of replicated Actors and connected clients:

Separate Actors into groups based on location. The world can be divided up into grid spaces for games in the battle royale, MOBA, or MMORPG genres, or predefined rooms or zones for dungeon crawlers or corridor-style first- or third-person shooters, or any method that fits your game's play spaces. Adding Actors into each grid cell or room from which that Actor can potentially be seen or heard will make client updates fast, as the node can simply provide the client with the persistent Actor list for whatever grid cell or room the client's camera is in.

Identify "dormant" placed Actors and keep them in a separate list. While some Actors, like those representing players or AI-controlled characters, are likely to need frequent updates, there may be many Actors that are pre-placed in the level and that don't move or change state on their own until a player interacts with them. These Actors may go for a long time (possibly the entire game session) without needing to send a network update. In Fortnite Battle Royale, for example, players and projectiles would be expected to update constantly until being removed from the game. A tree, on the other hand, would be expected to lie dormant for a long time, requiring no updates to any client. When the tree is damaged, any client who can see the tree would need to receive an update about it. Finally, when the tree is destroyed, any client who receives the update describing the tree's destruction never needs to receive any further updates about the tree.

If characters in your game can pick up and carry items, update those items with their carriers. When a player pulls out an item or weapon and carries it around, or wears a piece of clothing or armor, add the Actor representing the item (assuming it is a separate Actor and not merely a Component) to a special group that always gets updated when the owning player updates, and never updates otherwise.

Make a list of special Actors that always known to all clients. Special Actors that are always network-relevant to every player and can be put into a simple node that tracks these Actors, keeping them out of other lists where they might eat up CPU cycles doing unnecessary computation.

Make a list of special Actors that are always (or never) relevant to certain clients. A similar always-relevant list node could be made for individual players, or for teams of players. This is especially useful for things like ensuring that a player's teammates are always updated, or that opponents who have been "revealed" by a special in-game detection power are visible to the entire team of the player who revealed them. If the "reveal" expires, these Actors can be added back into their default nodes.

Building a Replication Graph that intelligently assigns Actors to different nodes based on knowledge of the Actor's role within the game can make the best use of your server's CPU time. The end result is steady server performance for games that otherwise could not run on current hardware. The Replication Graph Plugin includes several Replication Graph Node classes that you can use in large-scale online games. Developers are also encouraged to build custom node classes based on knowledge of the inner workings of their specific game.

Replay System Functionality

DemoNetDriver and Streamers

Backward Compatibility

Unreal Engine (UE) features a Replay system which can record gameplay for later viewing. This feature is available in all games, from live, multiplayer games played on dedicated servers, to single-player games, and even including Play-In-Editor sessions. At a high level, the Replay system works by using a DemoNetDriver to read data drawn from the built-in replication system, similar to how a NetDriver operates in a live, networked gameplay environment. Even if a project doesn't have a multiplayer mode, any project set up to replicate data is compatible with the Replay System without the need for further modification.

The way this works involves the DemoNetDriver passing network data to a Replay Streamer, which handles the process of filtering and storing the data. When viewing a replay, a DemoNetDriver will have access to all of the replicated information that was available during live play (as well as special data fields designated as relevant only to replays) so that it can reconstruct the events of the game from this data.

Replay System Functionality

The basic functions of the replay system are to start or stop recording a demo, or play back a previously-recorded demo. While in playback mode, the Replay system supports commands to pause, change the playback speed, or jump to a specific point in time. More advanced usage of the system can include adding text tags (usually meta tags or the names of players involved in the game) to a replay, or querying existing replays based on text tags or version information present. The Replay system can be used from C++ code, mainly via the UGameInstance and UWorld classes, or with console commands or command-line arguments.

Function Or Variable Name

Equivalent Console Command

Effect

UGameInstance::StartRecordingReplay

"demorec (ReplayName)"

Begins recording a replay. If the (ReplayName) parameter is not supplied, the replay system can generate a name on its own.

UGameInstance::StopRecordingReplay

"demostop"

Stops a replay currently being recorded.

UGameInstance::PlayReplay

"demoplay (ReplayName)"

Plays the named replay.

UDemoNetDriver::GotoTimeInSeconds

"demoscrub (ReplayTime)"

Jumps to the provided time (in seconds) in the replay.

UWorld::Pauser (variable)

"demopause"

The World's DemoNetDriver->ServerConnection has an OwningActor variable. Setting Pauser to that value will pause the replay. Setting it back to null will resume the replay. The "demopause" console command will automatically set or clear that variable.

WorldSettings->DemoPlayTimeDilation (variable)

"demospeed (ReplaySpeed)"

Speeds up or slows down playback by setting the time-scaling factor. A value of 1.0 is normal speed.

AGameMode::bHandleDedicatedServerReplays (variable)

N/A

Setting this variable to true causes dedicated servers to record games automatically.

DemoNetDriver and Streamers

The DemoNetDriver is a specialized network driver that passes replicated data to Streamers, which record the information for later playback. For details on the features of the DemoNetDriver and the Streamers included with the Engine, please see the DemoNetDriver and Streamers page.

Backward Compatibility

Backward compatibility is supported by the Replay system, starting in version 4.13. This means you can make modifications to a build, such as adding or removing replicated properties, and still load and view replays that were recorded with the original build. In most cases, this is handled automatically, as the Replay system will skip over old replicated fields that have been removed, or use defaults for new replicated fields that have been added. Note that structures with NetSerialize overridden will require these differences in data format to be handled manually.

To this end, FArchive now provides the EngineNetVer and GameNetVer functions, which identify the engine and game version, respectively, enabling you to adjust replay data as it comes in so that it fits with your current build. The delegate GetLocalNetworkVersionOverride in FNetworkVersion can be bound to a function that returns a uint32 version number of your choosing. In case exact matches are not required for compatibility, FNetworkVersion has a delegate called IsNetworkCompatibleOverride that can be overridden to perform the comparison between two version numbers and decide if they are compatible.

DemoNetDriver Features

Replay Data Format

Local File Streamer

SaveGame Replay Streamer

The Null Streamer

The Memory Streamer

Memory Streamer Usage Details

The HTTP Streamer

HTTP Streamer Usage Details

The DemoNetDriver uses Streamers to extract and record the information needed to create replays. There are several different Streamers included with the Engine that can be attached to the DemoNetDriver depending on how the replay data is intended to be viewed. The Local File Streamer, which is the default, records events from the host machine directly to disk, making it best suited for single-player games and games that keep replays locally, on the host player's own machine. A variant of the Local File Streamer, the Save Game Streamer, records replays into save game slots, which is especially useful on consoles, and supports supplemental features to play and manage these replays. The Memory Streamer runs on a client machine and stores data in memory, making it ideal for "instant replay" features in sports titles or "kill cams" in shooters. Finally, the HTTP Streamer is used to send replay data to a second machine over LAN or the Internet, which makes it a great choice for dedicated-server games and for games that may need to be streamed live to a large number of viewers while still remaining responsive to players.

DemoNetDriver Features

DemoNetDrivers use the Local File Streamer by default, but can override this by receiving the URL option "ReplayStreamerOverride" set to the name of a different Streamer Factory's module, such as "InMemoryNetworkReplayStreaming" or "HttpNetworkReplayStreaming". The default value, "LocalFileNetworkReplayStreaming", can be changed by setting the "DefaultFactoryName" variable in the "NetworkReplayStreaming" section of your project's DefaultEngine.Ini file. This can also be accomplished by calling InitBase and providing the appropriate URL argument as a parameter.

DemoNetDrivers can amortize the time cost of recording replay data by setting the "demo.CheckpointSaveMaxMSPerFrame" CVar to a positive value. Actors that are not recorded into the replay before the per-frame time limit expires will be queued to record on the next frame. The advantage to this feature is that it caps the amount of time that checkpoint recording can take and helps to keep your game free of hitches. The drawback is that slight visual errors can appear during playback due to checkpoints containing data on Actors taken from different frames. This feature will only be activated in the case that your game is taking longer than your specified time limit to record checkpoints, which means that it will primarily apply to lower-end machines, or to more performance-intensive games.

If bPrioritizeActors is set to true, Actors being saved into a replay will be pre-sorted by priority for recording order, based on the virtual function GetReplayPriority. This is useful when combined with amortized recording via MaxDesiredRecordTimeMS.

Checkpoint recording frequency can be adjusted by changing the CVar demo.CVarCheckpointUploadDelayInSeconds. The default is 30 seconds. Increasing the length of time between checkpoints will make scrubbing backward or skipping around in replays slower, but will decrease the size of replays.

The variable bPauseRecording can be set to true while recording a demo to suspend recording temporarily. Setting it back to false will resume the recording.

The Game Mode will use a different Player Controller class (designated as ReplaySpectatorPlayerControllerClass) when viewing replays.

Using SetViewerOverride, a DemoNetDriver can change how Actors' network relevancy, culling, and prioritization are determined by creating an alternate Player Controller that will be used for recording purposes. This is especially useful for games with large maps, where the player isn't always aware of things happening far away during live play (both for efficiency and cheat-prevention reasons), but will expect to see everything when viewing a replay.

DemoNetDrivers can operate in parallel with Slate. To accomplish this, both "tick.DoAsyncEndOfFrameTasks" and "demo.ClientRecordAsyncEndOfFrame" CVars must be non-zero.

Replay-generated Actors will make function calls just like live-gameplay Actors do. This causes them to behave just like live actors with minimal replay data, but it also means that function calls that affect shared objects such as the GameInstance, GameState, or GameMode, will still be usable by replay Actors, and can affect the state of the game in unintended ways. This is especially true in the case of the Memory Streamer, which can view a replay while live gameplay is still running. To guard against Actors affecting things that they shouldn't, it is recommended that these operations first be checked to see if the Actor is part of a live or replay level, and behave accordingly. This is most likely a game-specific issue and must be handled by each project on a case-by-case basis; for example, a given game may wish to update the player's health bar or full-screen damage overlay during a replay, but not alter the player's score.

Replay Data Format

In terms of data, a replay contains three types of game-state information, as well as some additional text data. At the start is baseline data describing the starting state of the game world. Checkpoints that act as snapshots of the net changes to the world (from the baseline) appear at regular, user-defined intervals. The space between checkpoints is then filled with incremental changes to individual objects in the world. Any moment in the game can be reconstructed by the engine quickly and accurately by initializing the world to the starting state, making the changes described in the checkpoints before the chosen time, and then applying each incremental change after the most recent checkpoint leading up to the desired point in time. The text data contained in a replay consists of a display name, which can be used when making a player-facing list, and user-defined text tags (HTTP Streamer only), which can be used when searching or filtering through lists of games.

Local File Streamer

The Local File Streamer records replay data asynchronously to a single file on local storage (such as a hard drive). This is the default streamer as of its introduction in Engine version 4.20, replacing the Null Streamer. The Local File Streamer's single-file output makes distribution and management of saved replays easier, and its asynchronous recording improves performance on systems with lower hard drive speeds, such as consoles. Replay data files are saved to the "Saved/Demos/" folder in your project, and have the extension ".replay".

The Local File Streamer is not compatible with replays recorded by the Null Streamer. If your project uses the Local File Streamer, but you want to maintain backward compatibility with replays recorded by the Null Streamer, you will need to include the Null Streamer. This does not preclude the project from using the Local File Streamer moving forward.

SaveGame Replay Streamer

The SaveGame Replay Streamer is a specialized version of the Local File Streamer that adds the ability to transfer a replay into a savegame slot. This is particularly useful on consoles, where client-side replays can be saved and then loaded through the platform's normal interface for loading saved games. Although this Streamer retains the ability to store, save, and load replays without the savegame system, its main purpose lies in its supplemental API, which can identify replays that haven't been copied to a savegame slot, perform the copy, and play or delete replays, both from local files and from savegame slots.

The Null Streamer

The Null Streamer writes replay data directly to disk, such as a local hard drive. This is good for making local recordings, especially of single-player games. These recordings can be very helpful for a variety of uses, such as producing gameplay trailers or in-game cutscenes, or enabling your users to view and share speedrun or tutorial videos within your game. Replay data files are saved to the "Saved/Demos/(Replay Name)" folder in your project.

The Null Streamer was the default way to record a replay before Engine version 4.20. It has since been deprecated, but can still support backward compatibility by playing old replays.

The Memory Streamer

The Memory Streamer keeps a user-configurable running length of replay data in memory on the local machine. This type of stream is best suited to instant replays of recent, dramatic moments, such as scores in a sports game, deaths in a shooter, or the final moments of a boss battle in an action game.

Memory Streamer Usage Details

The Memory Streamer is special in that it is meant to record, play back, and resume gameplay during a single session. The live game is able to continue, invisibly and silently, while the player is watching a replay, so that the game can be resumed seamlessly the moment the replay ends. At load time, the engine collects levels into three groups: Static Levels, Dynamic Source Levels, and Dynamic Duplicated Levels. These groups determine how the level will interact with live gameplay and the Replay System, as follows:

Level collection

Levels added to this collection

Behavior

Static Levels

Levels that are not the persistent level and are marked with the IsStatic boolean.

Should be unaffected by gameplay, and will be shown during both live play and replays.

Dynamic Source Levels

The persistent level and any sublevels with the IsStatic boolean variable set to false.

Affected by live gameplay. Hidden during replays, but with gameplay still running as normal.

Dynamic Duplicate Levels

Copies made from Dynamic Source Levels at load time. Do not exist on dedicated servers or in editor mode.

Hidden during live gameplay. Replays take place in these levels, then they are emptied out.

The "Is Static" setting can be found by activating the Levels view from the Window menu, and then clicking the Level Details button with your sublevel highlighted.



From there, the "Is Static" option will be available in the Level Details window. This window will be empty for the persistent level, so make sure to select a sublevel.



These level collections are a part of the level-streaming process and are not specifically related to the Replay system.

With this system in mind, we can create one DemoNetDriver for the Dynamic Source Levels, and another for the Dynamic Duplicate Levels. This enables us to record live gameplay in the Dynamic Source Levels and then play that data back in the Dynamic Duplicate Levels. By hiding the Dynamic Source Levels and showing the Dynamic Duplicated Levels during replay, the game can continue playing and receiving network updates unaffected by the replay. The third group, Static Levels, can be active and visible at any time; they should contain things like static world geometry or ambient background sounds, particles, and animations that are not affected by live gameplay, and therefore do not need to be involved in the replay process. When the replay is finished, the contents of the Dynamic Duplicate Levels will be destroyed and will undergo garbage collection, and the Dynamic Source Levels will become visible/audible again. Since the Dynamic Source Levels were never destroyed or suspended, only hidden, the game will have naturally progressed while the replay was being viewed, and can be shown immediately and without hitches. Additionally, this system enables increased efficiency by giving the developers the ability to mark levels as static in order to exclude them from replay recording and playback, saving both memory and time.

The HTTP Streamer

The HTTP Streamer sends replay data to another server, which could be on a LAN or elsewhere on the Internet. This is useful for live-streaming matches, or for keeping recordings of matches that can be viewed at any time. This streamer is especially useful for dedicated-server games, where only the server knows everything that's happening everywhere in the game at all times, and where offloading the work of processing replay data will increase the number of simultaneous games that can be hosted on a single server. It can also help to serve as a moderation or cheat detection tool, since the data can be captured from computers completely controlled by the party running the game.

HTTP Streamer Usage Details

The HTTP Streamer will communicate with a custom-written replay server through the HTTP Streamer REST API, using GET and POST methods to send data as binary or JSON-formatted strings. In order to set up your own replay server, you must first establish your URL. Your project's DefaultEngine.Ini file contains the replay server's URL under the [HttpNetworkReplayStreaming] section, in the variable ServerURL. Your ServerURL should be in the format "http://replay.yourgame.com/". The final "/" is important, as the HTTP Streamer will not assume that it should modify the format of the URL.

Upload Requests

Start Streaming

Upload Header

Flush Stream

Add/Update Event

Stop Streaming

Download Requests

Request Start Download

Request Header

Request Checkpoint Data

Request Stream Chunk

Enumerate Events for Replay

Refresh Viewer

Search Requests

Search Replays

Search Replays by Event

Request Replay

The following requests will be made by the HTTP Streamer and must be handled by your replay server. In most cases, simply recording the information given in the appropriate location, or providing that information back to a viewer upon request, will be sufficient. It is good to note at this point that replays are not generally stored as a single file. Each individual chunk of a replay generally occupies its own file. Event data, although associated with a replay, is stored separately, since events can be searched without knowing what replay they belong to. Even event groups should be stored as separate files with lists of all events (across all replays) belonging to that group.

The HTTP Streamer's REST API provides functionality for streaming replays from the game server to the replay server (uploading), for streaming live or pre-recorded replays from the replay server to the game, or viewer, server (downloading), or for querying information about the replays available on the server (searching). To implement your own replay server, you will need to respond to the following HTTP requests, as well as any additional requests specific to your game.

Upload Requests

Start Streaming

Sends a request to begin uploading a replay stream.

Item

Value

Request Method

POST

Content Type

application/json

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Session Name Override

(Optional, including the leading "/".) Any name for the replay. Usually includes a GUID.

The replay server is expected to recognize this name when a replay is being requested. It should be returned as the session name, although it can be ignored and the streamer will respect the returned name.

Replay Version AppString

A user-defined string that describes the game being played.

This value is expected to be used for filtering when the HTTP Streamer requests a list of replays.

Replay Network Version

A user-defined string that describes the version of the game being played.

This value is also used for filtering lists of replays, so it should be stored with the replay data.

Replay CL

The changelist of the build being played.

This value is used for filtering lists of replays.

Platform Friendly Name

The platform on which the game is being played.

This value might be displayed to users, and is expected to be returned when lists of replays are requested. However, it will not be sent to the game server with requests for lists of replays and therefore is not expected to be used as a filter.

Expects a response of type FNetworkReplayStartUploadingResponse, which contains JSON data with the string "sessionId" defined. This value will be used as the Session Name in future communication from the HTTP Streamer. If the optional <Session Name Override> was provided, the returned "sessionId", and thus the ultimate <Session Name>, should be the same value. This is the game's way of demanding the session name.

Name

Type

Content

Users

String Array

List of users present in the game. Should be stored as tags on the replay.

Upload Header

Sends a request to upload the binary data constituting the archive header, which should be recorded in a header file associated with Session Name.

Item

Value

Request Method

POST

Content Type

application/octet-stream

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Session Name

Name of the replay being uploaded.

This name will match the value that the replay server provided in response to the initial upload request.

Stream Chunk Index

The index of the current chunk of replay data being sent.

Stream chunks are not uniform in size, but they are strictly ordered by this value.

Total Demo Time In MS

The total running time of the demo up to the end of the current stream chunk.

Tells how much replay data, in milliseconds, has been uploaded so far without having to interpret binary replay data.

Flush Stream

Sends a request to flush the stream. The content is binary replay data, which can be compressed. This data represents the chunk indicated by Stream Chunk Index. Since chunks can vary in data size as well as the length of time they cover, it is recommended that each chunk be stored in a separate file. The HTTP Streamer will attempt to flush its current stream data via this system every ten seconds. The interval between flushes can be adjusted by changing the console variable httpReplay.ChunkUploadDelayInSeconds

To enable compression, three functions must be overridden in a child class of FHttpNetworkReplayStreamer:

SupportsCompression must return true.

CompressBuffer must perform compression and return true, except in the case of an error.

DecompressBuffer must perform decompression and return true, except in the case of an error.

Item

Value

Request Method

POST

Content Type

application/octet-stream

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Session Name

Name of the replay being uploaded.

This name will match the value that the replay server provided in response to the initial upload request.

Stream Chunk Index

The index of the current chunk of replay data being sent.

Stream chunks are not uniform in size, but they are strictly ordered by this value.

Total Chunks

The total number of chunks sent so far.

This is always one greater than Stream Chunk Index.

Total Demo Time In MS

The total running time of the demo up to the end of the current stream chunk.

Tells how much replay data, in seconds, has been uploaded so far without having to interpret binary replay data.

Start Time In MS

The total running time as of the point where this stream chunk begins.

Time is in milliseconds. For streaming replays, can be used to identify which chunk a scrubbing viewer needs.

End Time In MS

The total running time as of the point where this stream chunk ends.

Time is in milliseconds. For streaming replays, can be used to identify which chunk a scrubbing viewer needs.

Total Uploaded Bytes

The total size of the demo up to the end of the current stream chunk.

Tells how much replay data, in bytes, has been uploaded so far.

Add/Update Event

Sends a request to add or update a replay event. Content contains binary event data to be recorded. This data can be sent through DemoNetDriver and is be user-defined. The second version of this HTTP request can be used to modify or update an existing event, whereas the first version is used to create a new event.

Note that events are meant to be stored separately from replays, which is why event names use GUIDs. Each event knows what replay it belongs to, which is why events are not embedded in the replays themselves.

Item

Value

Request Method

POST

Content Type

application/octet-stream

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Session Name

Name of the replay being uploaded.

This name will match the value that the replay server provided in response to the initial upload request.

Group Name

The name of the event group containing this event.

Events can be put into groups for filtering lists, such as grouping all penalty calls in a sports title.

Event Name

The GUID of the event being added or updated.

(Optional.) Information about specific, named events may be requested by viewers. If not specified, the event can still be found by listing the events in its group.

Event Time In MS

The time in the replay when this event takes place.

Time is in milliseconds. Although "time1" and "time2" can be used as a begin time and an end time respectively, they are always the same value in the default HTTP Streamer.

Meta Tag

Meta tag associated with this event.

Replay lists can be filtered by meta tag, if the request specifies any. Meta Tag will be URL-encoded by the HTTP Streamer during transmission.

Stop Streaming

Sends a request to indicate that the replay is done uploading.

Item

Value

Request Method

POST

Content Type

application/octet-stream (no content is sent)

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Session Name

Name of the replay being uploaded.

This name will match the value that the replay server provided in response to the initial upload request.

Total Num Chunks

The number of chunks in the finished replay.

Total Time In MS

The total running time, in milliseconds, of the replay.

Total Bytes Uploaded

The total size, in bytes, of the replay.

Download Requests

Request Start Download

The purpose of this request is to start downloading a replay from the replay server by establishing a connection based on the user name. Immediately after this request goes through successfully, the HTTP Streamer will send a request to download the replay's header, and then another to enumerate all checkpoints in the replay.

Item

Value

Request Method

POST

Content Type

None

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Session Name

Name of the replay being downloaded.

This name will match the value that the server provided when the replay was originally uploaded.

User Name

Unique Net Id (GUID)

The preferred network GUID that is logged into the client machine. This value comes from the engine and is not intended to be user-supplied.

The expected response to this request is of type FNetworkReplayStartDownloadingResponse, which contains JSON data.

Name

Type

Content

State

String

The word "Live", to indicate that the game being viewed is happening live. Otherwise, the replay is assumed to be pre-recorded.

NumChunks

Integer

This is expected to be nonzero, and can be updated as streaming continues (used for live replays).

Time

Integer

The total time (in MS) of the replay. Subject to change if State indicated that this is a live stream.

ViewerId

String

A unique, name assigned by the replay server that the game server will use when requesting further chunks of replay data. Often referred to as Viewer Name in this document.

Request Header

Item

Value

Request Method

GET

Content Type

None

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Session Name

Name of the replay being downloaded.

This name will match the value that the replay server provided when the replay was originally uploaded.

Expects a response with the replay's header in the content portion, as binary data.

Request Checkpoint Data

Item

Value

Request Method

GET

Content Type

None

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Session Name

Name of the replay being downloaded.

This name will match the value that the replay server provided when the replay was originally uploaded.

Expects a response of type FHttpResponsePtr containing checkpoint data as a JSON-formatted string.

Name

Type

Content

events

Array

Contains array entries which consist of all the other fields in this table.

id

String

The name (a GUID) of the checkpoint.

group

String

The group to which the event belongs, if any.

meta

String

Meta Tag string associated with this event, if any.

time1

Integer

Start time (in MS) of the event.

time2

Integer

End time (in MS) of the event. Often the same as the start time.

Note that this is technically a generic request for a group of events. While "checkpoint" is explicitly specified here, the replay server should be able to handle other values for "group" and report all events for any given group.

Request Stream Chunk

This is a request for a specific stream chunk, named by the viewer. This request will not be sent while there is a chunk already being downloaded.

Item

Value

Request Method

GET

Content Type

None

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Session Name

Name of the replay being downloaded.

This name will match the value that the replay server provided when the replay was originally uploaded.

Stream Chunk Index

The index of the current chunk of replay data being requested.

Stream chunks are not uniform in size, but they are strictly ordered by this value.

The expected response has a header with some information about the chunk, and its content is a binary chunk of replay data. The binary data can be compressed, if compression is supported. The following fields are expected in the header:

Header Field Name

Description

NumChunks

The total number of chunks in the stream. This can be useful with streamed games, as it lets the user know about new chunks that have been created while viewing.

Time

The total length of the replay (in MS). As with NumChunks, this value can change during the viewing session if the replay is live.

State

This variable has one recognized value, "Live". If this variable is missing or is a different value, the streamer will switch to non-live streaming mode.

MTime1

The start time of the stream, in MS. Can be non-zero for live replay streams. This variable will only be checked if a chunk of data sent, and either this is the first chunk the streamer has downloaded, or the stream is live.

MTime2

The end time of the stream, in MS. Can change as more chunks come in. This variable will always be checked if a chunk of data is sent, or if the replay is live.

To enable compression, three functions must be overridden in a child class of FHttpNetworkReplayStreamer:

SupportsCompression must return true.

CompressBuffer must perform compression and return true, except in the case of an error.

DecompressBuffer must perform decompression and return true, except in the case of an error.

Enumerate Events for Replay

Can be called directly from DemoNetDriver, meaning your game project can do this at any time. This request asks the replay server to send a list of all events pertaining to a specific replay (identified by Session Name) and filtered by a certain event group. It is recommended that empty group names, as well as a lack of the "group" argument, be supported.

Item

Value

Request Method

GET

Content Type

None

Content received in response to this request is expected to be a JSON-formatted string corresponding to FReplayEventList and FReplayEventListItem.

Name

Type

Content

events

Array

Contains elements which consist of all the other fields in this table.

id

String

The name (a GUID) of the checkpoint.

group

String

The group to which the event belongs, if any.

meta

String

Meta Tag string associated with this event, if any.

time1

Integer

Start time (in MS) of the event.

time2

Integer

End time (in MS) of the event. Often the same as the start time.

Refresh Viewer

This request is a heartbeat, sent every ten seconds. This frequency is currently hard-coded, but will likely be made user-configurable without code changes in the future. If a viewer fails to send this request for a long period of time (perhaps one minute), then the viewer has most likely disconnected unexpectedly and it would be reasonable to disconnect them. If the "final=true" version is sent, the user is indicating that this is the final heartbeat, and the user has stopped watching the replay.

Item

Value

Request Method

POST

Content Type

None

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Final Heartbeat

"true" or "false"

By default, "final" will not be sent unless Final Heartbeat is true. If true, the viewer has stopped watching and no further data should be sent.

Search Requests

Search Replays

Request a list of all replays that the replay server can send. These replays are expected to be pre-filtered by the user's criteria in the URL. The replay server should be able to handle some of the filter fields being empty or missing.

Item

Value

Request Method

GET

Content Type

None

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Replay Version AppString

A user-defined string that describes the game being played.

This value was sent when the user began uploading the replay, and is now being used for filtering the list of replays sent to the potential viewer.

Replay CL

The changelist of the build being played.

This value is used for filtering lists of replays.

Replay Network Version

A user-defined string that describes the version of the game being played.

This value should reflect changes in your game's data formats as they affect replay. It is also used for filtering lists of replays.

Meta

Tags applied to this replay.

User-applied meta tags can be used for filtering games that have certain features. This could be anything from "all Capture The Flag matches" to to "games that went into double-overtime".

User

Unique Net Id (GUID)

This is used to filter games based on their inclusion of a specific player.

Recent

"true" or "false"

If true, only recently-uploaded replays should be shown. What defines "recent" is up to the replay server.

Expects a response with content in the form of a JSON-formatted string.

Name

Type

Content

replays

Array

Contains elements which consist of all the other fields in this table.

AppName

String

The Replay Version AppString that was sent when the replay was uploaded. Should match the parameter you sent with the request.

SessionName

String

The name (GUID) of the replay.

FriendlyName

String

The <Platform Friendly Name> that was provided when the replay was uploaded.

Timestamp

DateTime

The time and date associated with the replay (i.e. when this game happened).

SizeInBytes

Integer

Total size, in bytes, of the replay.

DemoTimeInMs

Integer

Running length, in MS, of the replay.

NumViewers

Integer

Number of users currently watching this replay.

bIsLive

Boolean

True if the game in the replay is still being played.

Changelist

Integer

The changelist (CL) of the engine running the game when this replay was recorded. Corresponds to the Replay CL argument sent when uploading the replay. Should match the parameter you sent with the request.

shouldKeep

Boolean

True if the debug "shouldKeep" request was made.

Search Replays by Event

Sends a request for a list of replays from the server. These replays are expected to be pre-filtered to include only those that contain at least one event in the named Event Group.

Item

Value

Request Method

GET

Content Type

None

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Event Group

The name of the event group containing this event.

Events can be put into groups for filtering lists, such as grouping all penalty calls in a sports title.

Expects a response with content as a JSON-formatted string containing a list of replays from the server.

Name

Type

Content

replays

Array

Contains elements which consist of all the other fields in this table.

AppName

String

The Replay Version AppString that was sent when the replay was uploaded.

SessionName

String

The name (GUID) of the replay.

FriendlyName

String

The <Platform Friendly Name> that was provided when the replay was uploaded.

Timestamp

DateTime

The time and date associated with the replay (i.e. when this game happened).

SizeInBytes

Integer

Total size, in bytes, of the replay.

DemoTimeInMs

Integer

Running length, in MS, of the replay.

NumViewers

Integer

Number of users currently watching this replay.

bIsLive

Boolean

True if the game in the replay is still being played.

Changelist

Integer

The changelist (CL) of the engine running the game when this replay was recorded. Corresponds to the Replay CL argument sent when uploading the replay.

shouldKeep

Boolean

True if the debug "shouldKeep" request was made.

Request Replay

This is called directly from the DemoNetDriver, so it can be done from the game project at any time, but will usually be called while viewing a replay with an Event Name retrieved from a list provided by a previous request.

Item

Value

Request Method

GET

Content Type

None

Element

Value

Intended Use / Notes

Server URL

Replay server URL. Drawn from DefaultEngine.ini, unmodified.

The final "/" in the URL must be included - it will not be added automatically.

Event Name

The GUID of the event requested.

Since events are identified by GUID, the event can be from any replay on file. Make sure that the event you request is from a list of events pertaining to the replay you are currently watching.

Expects a response with Content as a binary stream from the replay server.



How to enable the Steam network protocol layer for Unreal Engine projects.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Plugins

Configuration Files

Enabling the Steam Sockets Plugin

Using Steam Sockets Features

In Unreal Engine 4.27.0, an issue with the FUniqueNetIdSteam structure prevented Steam Sockets from creating successful connections. This issue is fixed in 4.27.2 and later.

Steam Sockets is a networking plugin that takes advantage of the new Steam network protocol layer, which Unreal Engine supports as of Steamworks SDK version 1.46.

Compared with the previous SteamNetworking protocol, this plugin provides improved security and reliability using Steam's communication network, with built-in DDoS protection, end-to-end encryption, and NAT traversal. Steam Sockets also provides ping calculation for listen servers, which can be used by matchmaking systems to match users to servers with better performance. This is a significant improvement over SteamNetworking, which could not provide ping calculation until users were already connected to a server.

Steam Sockets uses its own net driver in place of Unreal Engine's default net driver, and builds created with Steam Sockets enabled can only connect with other builds using Steam Sockets. Additionally, Steam Sockets builds can support cross-platform play between Windows, Mac, and Linux, but not with other devices.

Enabling the Steam Sockets Plugin

Steam Sockets can be enabled for Windows, Mac, and Linux-based builds with the following steps:

Open your project in Unreal Editor and click Edit > Plugins.

In the Plugins Menu, click the Networking plugins group under Built-in Plugins.

Locate the Steam Sockets plugin and click enabled. You will need to restart Unreal Editor for the changes to take effect.



Open the Engine.ini files for each platform that you want to use the Steam Sockets plugin, and change the Net Driver Definitions to use SteamSockets.SteamSocketsNetDriver. As an example, if you are enabling Steam Sockets for a Windows build, you would add the following to WindowsEngine.ini:

WindowsEngine.ini

Any builds targeting devices outside of Windows, Mac, and Linux will strip Steam Sockets before packaging and default to UE4's standard network protocol.

If you are targeting a platform outside of Steam on any of those OSes, such as the Oculus store on Windows, the build will still package with Steam's net driver, which will be incorrectly set for that platform. You will need to account for this by configuring your project appropriately for builds distributed on different PC-based platforms.

Using Steam Sockets Features

Steam Sockets can be customized with config parameters for enabling and disabling large-scale functionality.

OnlineSubsystemSteam.bUseSteamNetworking controls whether SteamSockets SocketSubsystem is the default subsystem or not. This parameter is set to true by default. Most projects will not need to change this setting, and it is mainly available as a backward-compatibility option for developers migrating from the previous SteamNetworking protocol.

OnlineSubsystemSteam.bAllowP2PPacketRelay controls whether or not packets should tunnel through the Steam communication network when using a dedicated server. This parameter is set to true by default. When this setting is disabled, dedicated servers expose their connection addresses directly, enabling custom implementation. When this setting is enabled, dedicated servers function over Steam's relay network, which insulates them from DDoS attacks and provides improved security. P2P listen servers always use Steam's communication network regardless of this setting.

Other functionality, including ping calculation, is provided through existing network interfaces in UE4.

For additional information about the Steamworks SDK, refer to Valve's official documentation.

Index

When creating a multiplayer game or networked project in Unreal Engine (UE), there are several unique challenges in the process of debugging, profiling, and testing your project. These challenges include:

Debugging multiple instances of your project

Accounting for the general unreliability and instability that comes with networked communication

Examining the different functionality that exists on Clients as opposed to Servers.

UE multiplayer is based around the Client-Server model. This means that there will be a single server that will be Authoritative over the GameState, while connected clients will maintain a close approximation. See Client-Server Model for additional documentation.

Unreal Engine features specialized tools and workflows for debugging networked applications. The guides below will show you how to use these tools, as well as tips and best practices for troubleshooting common networking issues.

Index



An Overview for Using Network Emulation in Unreal.



Testing and Debugging Networked Games in Unreal.



An overview of Logging for Network Games.



Emulate network packet lag and loss in Unreal Engine.



Set up the Unreal Editor for testing multiplayer games.



Analyze network traffic and performance information captured at runtime.



Some tips for optimizing the performance and bandwidth usage of Actor replication.

General Commands and Variables

Replication Graph Commands and Variables

Console Commands for Network Debugging

Unreal Engine (UE) includes several console variables and commands that are useful for debugging networked games.

General Commands and Variables

The following are commands and variables that apply to all networked games using the server-client model.

Command

Description

net.DebugDraw

Can be enabled to draw debug information for a replicated Actor's dormancy and relevancy.

net.ListActorChannels

Prints a list of all Actor channels to the log.

net.ListNetGUIDs

Prints a list of all NetGUIDs to the log.

net.Reliable.Debug

Can be enabled to print a log message every time a reliable bunch is sent.

net.PackageMap.DebugAll

Debugs the PackageMap serialization of all Objects.

net.PackageMap.DebugObject <Object Name>

Debugs the PackageMap serialization of a specific Object.

net.Replication.DebugProperty <Property Name>

Debugs replication of the specified property.

net.RPC.Debug

Can be enabled to print all RPCs sent.

net.UseGranularNetworkTracking

Can be enabled to have the Object list print information on network memory usage.

net.RepMovement.DrawDebug

Can be enabled to draw debug information on Replicated Movement.

p.NetShowCorrections

Can be enabled to draw color-coded client position corrections.

Demorec <ReplayName>, Demostop, and Demoplay <ReplayName>

Can be used to record and playback a replay from the console.

Replication Graph Commands and Variables

The list below provides useful commands for issues concerning the Replication Graph. You can find the full list of debugging commands in ReplicationGraphDebugging.cpp.

Command

Description

Net.RepGraph.PrintGraph

prints the full contents of your Replication Graph

Net.RepGraph.PrintAllActorInfo <MatchString>

For information on specific Actors within the Replication Graph can be used to print global connection-specific information about Actors whose path name contains <MatchString>

Net.RepGraph.SetDebugActor <ClassName>

Sets a specific Actor as the Debug Actor providing you with a breakpoint on a specific Actor when debugging the graph.

Testing Networking Options In Unreal Editor

Multiplayer Options

Launching a Dedicated Server

Connecting to Standalone Server instances

Debugging Multiple Client and Server Instances

Profiling Networked Games

Networking Insights

Network Profiler

Gauntlet Automation Framework

Functional Testing

Testing Networking Options In Unreal Editor

The Unreal Editor contains adjustable settings to help with testing multiplayer projects. These options include setting the Number Of Players, running multiple Play windows, and running a Dedicated Server.

To view these settings, launch the Editor and navigate to the Toolbar, then select the Modes drop-down button adjacent to the Play button.



For additional details on adjusting Multiplayer settings in the Editor, see Testing Multiplayer

Multiplayer Options



Launching a Dedicated Server

There are other alternatives to launching a multiplayer game. Follow the steps below to launch a separate Dedicated server instance.

You may select Advanced Settings from the Modes drop-down arrow, or by navigating to Editor Preferences > Level Editor > Play > Multiplayer Options.

From the Multiplayer Options section, navigate to the Launch Separate Server variable and click the box to enable its boolean to true.

Click the drop-down menu adjacent to the Play Net Mode variable and select Play Standalone.

This will create a new server instance, however, other instances won't automatically connect to it.

Connecting to Standalone Server instances

You can connect Standalone instances to the Server by using the command:

You can also use the Session interface. This creates an instance of the game running on a server that other clients can discover and join. This is useful for testing your project's connection flow.

If the Play Net Mode variable is set to Play as Client, you are not required to enable the Launch Separate Server variable, as it is not needed for a dedicated server instance to be launched.

When using Play as Client or Play As Listen Server in the Net Mode options of the editor, these instances are automatically connected directly to each other by IP address. This is the equivalent of running the open 127.0.0.1:17777 command on a Client to connect to the Server.

This connection process does notuse the Session Interface, therefore, the Server will not create an online multiplayer session, and Clients will not search and join this session. For most gameplay testing purposes, this won't make a difference. However, certain online features that rely on the session interface, such as voice chat, will not be available.

If the box adjacent to the Run Under One Process variable is enabled, then all Client and Server instances will share the same tick rate as the editor.

This is different behavior than running these instances separately. As an example, in Standalone mode, you can control the server's tick rate using the NetServerMaxTickRate config value located in the BaseEngine.ini file.

This may affect certain behavior which uses tick rate, such as calculating the bandwidth limit for a single net update.

When using Play-In-Editor (PIE) there are limitations to features such as Server/Client traveling. Your project will need to run in Standalone mode as a separate process outside of the editor to test these features.

If you're running instances under separate processes, one instance will be considered Play-In-Editor and the others will be Standalone. This may lead to varying behaviors when compared to uniformly running all instances as Play-In-Editor. or Standalone. For example, the UEditorEngine::NetworkRemapPath function will need to be called in order to add remove or PIE prefixes on static Actors whose paths are sent across the network.

Debugging Multiple Client and Server Instances

Running multiple Client and Server instances has unique challenges, most especially understanding which instance you're attached to. You can mitigate these challenges by using breakpoints to assist in debugging a PIE instance.

In your code editor, you can add the following variables to your Watch window.

Watch Variable

Use

UnrealEditor-Engine!GPlayInEditorContextString

Determines which instance you're currently stepping through.

NetDriver ServerConnection

On Clients, this will hold a reference to the NetConnection to the server. On the server, this value will be Null, allowing you to quickly check which instance you're in when debugging the replication system.

Additionally, you can check an Actor's Role property by placing a call to the function GetLocalRole() in a watch, or by calling it directly in code. The GetLocalRole function returns how much control the instance has over this Actor. If you're debugging issues within a Replicated Actor, then it will return one of three roles:

Role

Description

ROLE_Authority

An Actor that exists on the server instance.

ROLE_AutonomousProxy

An Actor that is a Character or Pawn possessed by a local PlayerController on this client instance.

ROLE_SimulatedProxy

An Actor that exists on a client instance.

Profiling Networked Games

Networking Insights

You can profile networked games using Networking Insights. This is a component of the Unreal Insights profiling tool that provides detailed information to help analyze, debug, and optimize a project's network traffic.



Overview of Networking Insights, the network performance profiling tool

Network Profiler

Unreal Engine also includes the Network Profiler, a legacy tool that offers a different view of a project's network traffic. While the information provided by the Network Profiler is less detailed than that of Networking Insights, it can still provide a high-level overview of your game's bandwidth usage as well as stats on individual Actors, Properties, or RPCs.



Analyze network traffic and performance information captured at runtime.

Gauntlet Automation Framework

The Gauntlet Automation Framework supports launching multiple sessions, such as a server and clients, and it can be an invaluable tool for testing and validating your multiplayer project.

There is a sample implementation of an automation script using Gauntlet for a multiplayer game in the ShooterGame project. It contains a ShooterGame automation C# that drives the tests, located in the /Build/Scripts folder, as well as the project's native test controller code, which is located in the /Source/ShooterGame/Private and Public/Tests directories.

Functional Testing

UE includes the ability to set up and run Functional Tests through the Runtime:Engine:ALevelScriptActorLevel Blueprint. Your functional tests will initially be required to run on a single instance of your project. Afterward, you may run these tests in a multiplayer project. You can start the level containing the tests in a Client Instance, Dedicated Server, or a Listen Server Instance.

Setting up a functional test that runs across multiple instances, such as both the Client and the Server, is not currently supported. An example scenario where the desired functionality will not work is if the Server sets a Replicated Property to a new value, then the Client checks if this new replicated value was received.

Logging for Networked Games

Client and Server logs are important for identifying and debugging networking issues. While many networking logs fall into the LogNet category, we recommend checking log categories that are more closely related to specific systems to provide greater insight into any issues.

These categories are not enabled by default and have varying amounts of verbosity that you may need to adjust to gain information about the behavior you're experiencing. The list below provides some recommended categories:

Category

Description

LogNetTraffic

Logs all network traffic when this log variable is set to VeryVerbose.

LogNetPackageMap

Logs information related to how NetGUIDs are Sent, Received, and Acknowledged.

LogNetVersion

Logs information related to Property Replication and RepNotify functions that are used by FRepLayout and FObjectReplicator.

LogNetFastTArray

LogNetDormancy

LogRep

LogRepTraffic

LogRepProperties

Logs information related to the sending and receiving of replicated properties.

PacketHandlerLog

Logs information on the packet handler and its components. These components have their own sub-categories. For example, LogDTLSHandler, OodleNetworkHandlerComponentLog, and LogHandshake.

LogDemo

Logs information on recording and playing back replays. Each replay streamer has a related log category: LogLocalFileReplay, LogSaveGameReplay, LogNullReplay, and LogMemoryReplay.

You can enable these categories and adjust their verbosity by either passing in the command line argument:

using the console command Log:

or by setting them in your project's DefaultEngine.ini. For example:

When reading logs, the following list can be useful for determining what kind of error occurred.

UEngine::BroadcastNetworkFailure

Printed when a net driver encounters some major error. The log line will include the failure type, the error string, and the description of the net driver that encountered the error. You can see a list of the possible network failures with brief descriptions in the ENetworkFailure enum in EngineBaseTypes.h.

UNetConnection::Close

A description of the connection being closed.

UActorChannel::Close

A LogNetTraffic category that will include the channel index, the Actor for that channel, and the reason it was closed. Checking the logs around these lines can help provide some indication as to why a connection or Actor channel was closed.

The command-line argument -LogTrace=<partial log line> performs stack traces from partial log message strings. For example: -LogTrace=UNetConnection::Close will produce a stack trace whenever UNetConnection::Close is printed to the logs. The command-line argument -DumpRPCs provides the capability to dump RPCs and their parameters, which can be useful for tracking what RPCs are being sent and their parameters.

LogTrace and DumpRPCs both require NetcodeUnitTest to be enabled.

Enable Network Emulation

Unreal Editor

Command-Line

Console

Configuration Files

Settings Reference

Recommendations for Use

Testing multiplayer on a single machine requires you to run multiple instances of your game, with one acting as a server and the others acting as clients. Normally, this creates an environment with ideal conditions for your replicated data. Your replicated data will be passed through the appropriate systems, similar to a real networked environment, but there will be no lag or packet loss, which means you won't get an accurate idea of how it will behave when deployed to end-users. Similarly, LAN-based tests will not experience these conditions.

Network Emulation simulates lag and packet loss for servers and clients. This is crucial in identifying issues that may arise in networking environments. The Network Emulation settings are configurable in the Unreal Editor, command-line, console, and configuration files.

Enable Network Emulation

Unreal Editor

To use Network Emulation, from the Menu Bar navigate to Edit > Editor Preferences > Level Editor > Play > Multiplayer Options and enable the Enable Network Emulation checkbox. This enables the Network Emulation settings.



The editor includes pre-built Network Emulation Profiles including: Custom, Average, and Bad. These profiles use the provided fields to customize network emulation settings:

Incoming Traffic: cause a delay or loss for receiving a packet

Minimum Latency: minimum amount of time lag in milliseconds (corrsponds to PktIncomingLagMin)

Maximum Latency: maximum amount of time lag in milliseconds (corresponds to PktIncomingLagMax)

Packet Loss Percentage: chance that a packet is lost before being received (corresponds to PktIncomingLoss)

Outgoing Traffic: cause a delay or loss for sending a packet

Minimum Latency: minimum amount of time lag in milliseconds (corresponds to PktLagMin)

Maximum Latency: maximum amount of time lag in milliseconds (corresponds to PktLagMax)

Packet Loss Percentage: chance that a packet is lost before being sent (corresponds to PktLoss)

Command-Line

You can specify settings with a command-line argument using the syntax:

Console

You can specify settings from the console at runtime using the syntax:

Configuration Files

To set these values from your engine configuration files such as DefaultEngine.ini, add the [PacketSimulationSettings] section to your your configuration file, followed by the <SETTING_NAME>=<VALUE> pairs you wish to specify:

Settings Reference

These settings provide you with a multitude of combinations to customize your network emulation:

Setting

Description

Value

Off

Turn off network emulation

Toggle command, no value required.

PktLoss

Specifies a percentage chance of an outbound packet being discarded to simulate packet loss.

Clamped value between 0 (no packets dropped) and 100 (all packets dropped).

PktOrder

Changes the order of packets at random. This works by randomly selecting packets to be delayed until a subsequent call to FlushNet.

0 = False, Anything else = True

PktDup

Specifies a percentage chance of a sent outbound packet being duplicated.

Clamped value between 0 (no packets duplicated) and 100 (all packets duplicated).

PktLag

Delays the sending of a packet by the amount of time specified in milliseconds. Note: Cannot be used with PktOrder.

Value in milliseconds.

PktLagVariance

Causes packet lag to be a random variable instead of constant time in milliseconds. If set, lag becomes a random variable from [PktLag - PktLagVariance, PktLag + PktLagVariance] Note: Can only be enabled when PktLag is enabled.

Value is chosen at random from the range [-Variance, Variance].

PktLagMin

Causes packets to have a minimum amount of lag.

Value in milliseconds.

PktLagMax

Causes packets to have a maximum amount of lag.

Value in milliseconds.

PktIncomingLagMin

Causes packets to have a minimum amount of lag for the receiving end.

Value in milliseconds.

PktIncomingLagMax

Causes packets to have a maximum amount of lag for the receiving end.

Value in milliseconds.

PktIncomingLoss

Specifies a percentage chance of an inbound packet being discarded to simulate packet loss.

Clamped value between 0 (no packets dropped) and 100 (all packets dropped).

PktJitter

Causes sent packets to have a variable fluctuating latency by adding the value of PktJitter to range of possible packet lag times.

Value in milliseconds.

PktEmulationProfile

Set a predefined emulation profile.

Name of profile.

Recommendations for Use

Multiplayer games running with perfect connectivity will not experience many bugs that only occur during poor connectivity. To ensure that you catch these bugs, you should perform local and LAN-based tests with extremely harsh conditions. For example:

500 round trip ping.

10% packet loss or higher.

Epic Games uses conditions like these to test cooperative and competitive gameplay. This makes it possible to catch numerous bugs and exploits that would otherwise go overlooked, and strongly incentivizes optimizing network performance.

Multiplayer Play Options

Advanced Settings

Listen Server vs. Dedicated Server

This page shows you how you can change some of the settings for the editor for testing different multiplayer scenarios.

Multiplayer Play Options

Set Number of Players

Click the more options button next to the Play button and enter a value for Number of Players.



By default, the server uses the Selected Viewport as the play window and new windows will be created for each client that is added:



Adjusting Play Windows

While it is perfectly okay to use the Editor's Viewport as a play window, for clarity you may want to use windows for each player. To adjust the play window for the server, click the more options button next to the Play button then select New Editor Window (PIE). While simulated clients have their own windows, this setting will also create a separate window for the simulated server.

Advanced Settings

If you have set up the Play method to use new editor windows, you may want to adjust the size of the editor windows. Click the more options button next to the Play button then select Advanced Settings. Set the desired window sizes under the Multiplayer Viewport Size (in pixels) section. The Multiplayer Viewport Size (in pixels) size option allows you to set the size of windows that are created. You can choose from a number of preset window sizes or manually enter a window size (we specified 640x480 in our example). Once you have entered a window size, when you play in the editor, each new window will be of the same size.



When playing in the editor using new windows for each play session, you will notice at the top of each window it will display if the player is a server or client. Also while in Play mode, when you move windows around, their locations will be remembered for your next Play in editor session (so you will not have to keep moving them around which makes testing easier).

Multiplayer Options



Also inside Advanced Settings, there is a section for setting up additional multiplayer options:

Option

Description

Number of Players

This option defines the number of players to spawn in the game when launched. The editor and listen server count as players, a dedicated server will not. Clients make up the remainder of players.

Server Game Options

Here you can specify additional options that will be passed to the server as URL parameters.

Run Dedicated Server

If checked, a separate dedicated server will be launched. Otherwise the first player will act as a listen server that all other players can connect to.

Route 1st Gamepad to 2nd Client

When running multiple player windows in a single process, this option determines how the game pad input get routed. If unchecked (default) the 1st game pad is attached to the 1st window, 2nd to the 2nd window, and so on. If it is checked, the 1st game pad goes to the 2nd window. The 1st window can then be controlled by keyboard/mouse, which is convenient if two people are testing on the same computer.

Use Single Process

This spawns multiple player windows in a single instance of Unreal Engine. This will load much faster, but has potential to have more issues. When this is unchecked, additional options become available.

Create Audio Device for Every Player

Enabling this will allow rendering accurate audio from every player's perspective but will use more CPU.

Play In Editor Description

This is a description of what will occur when playing based on the currently applied multiplayer settings.

When Use Single Process is checked, multiple windows are spawned in a single instance of Unreal Engine. When this option is unchecked, multiple instances of UE will be launched for each player that is assigned and additional options become available:

Option

Description

Editor Multiplayer Mode

This is the NetMode to use for Play In Editor (Play Offline, Play As Listen Server or Play As Client).

Command Line Arguments

Here you can assign additional command line options that will be passed to standalone game instances.

Multiplayer Window Size (in pixels)

Define the width/height to use when spawning additional standalone game instances.

Listen Server vs. Dedicated Server

When launching a multiplayer game, there are two methods in which the game can be hosted. The first, is by using a Listen Server (default setting) which means that the machine that has the authority is also running a client and can play the game normally while hosting for other players.

The second method is by using a Dedicated Server, which as the name implies, is dedicated to only hosting the game and no local players play on the machine as everyone connected is a client. Usually running as a Dedicated Server is more optimized than running as a Listen Server as there are no visuals or input being registered.

By default, the server type is set to a Listen Server when playing in the editor or standalone game.

Run a Dedicated Server

Click the more options button next to the Play button then check the Run Dedicated Server checkbox. For more information about setting up a dedicated server for your project, see our Setting Up Dedicated Servers documentation.

Record a Profiling Session

With a Command-Line Argument

With a Console Command

File Save Location

Server and client considerations

View a Profiling Session

User Interface

The Network Profiler is a standalone tool used to display network traffic and performance information recorded by Unreal Engine (UE) as a game runs. This is a good way to identify areas of a multiplayer game that use unusually high bandwidth, since you can see how much bandwidth individual actors, remote procedure calls (RPCs), and properties contribute to the total.

Record a Profiling Session

Before you can use the network profiler, you must record some data for it to analyze. To do this, you need to use a version of the engine with stat tracking enabled. Typically, this means you need to use either a debug build, or for non-debug configurations, an editor build. More specifically, the engine should have been compiled with the STATS macro defined to a nonzero value.

For more information on stat tracking, see our Stat Commands documentation.

With a Command-Line Argument

You can pass the networkprofiler=true command-line argument to record as soon as the engine starts up.

With a Console Command

You can also use the following console commands at runtime to control the recording of network profiler data:

netprofile: toggles recording on and off

netprofile enable: start recording if not already recording

netprofile disable: stop recording if currently recording

File Save Location

The data file recorded during a profiling session is saved as <PROJECT_DIRECTORY>/Saved/Profiling/<PROJECT_NAME>-<TIMESTAMP>.nprof. If you see a file named NetworkProfiling.tmp in the same directory, this is just the temporary file the engine uses while collecting data. When the current profiling session is stopped, this file will be renamed according to the scheme above and is then ready to be opened in the standalone network profiler tool.

Server and client considerations

You can record profiling data from both clients and servers. However, be aware that since only servers replicate actors and their properties, when viewing a profile recorded on a client, you will only see detailed data for RPCs that were sent from that client.

View a Profiling Session

The network profiler is a standalone application located at <UNREAL_ENGINE_ROOT>/Engine/Binaries/DotNET/NetworkProfiler.exe. At the top of the window, click the Open File button to select a *.nprof file and view the data contained within.

User Interface

By default, the Chart, Filters, Details tab is selected. This section provides an overview of the network profiler user interface.



View Tabs

Chart, Filters, Details

All Actors

All Properties

All RPCs

All Objects

Chart

Stats List

Details

Summary

Actors

Token Details

Apply Filters

The View Tabs are where you select the information that you would like to view.

This view is the most detailed. In this view mode, you can:

View the Chart

Refine analysis with the Stats List

Get an in-depth look at Details

Apply Filters

The All Actors view mode displays information about all of the actors that were profiled in this session. This tab has similar functionality and display information as the All Properties, All RPCs, and All Objects tabs. Each of these tabs show a summary of the respective replication data for the entire profiling session. Note that the data displayed in these tabs is not affected by the current frame or time span selected in the chart on the Chart, Filters, Details tab.

The tabs show a list of actors, properties, RPCs, or objects respectively. The Total Size and Average Size columns show how much bandwidth was needed for a particular item, and the Count column represents how many times a particular item was replicated during the profiling session. This information includes:

Header Name

Description

Actor Class

Name of the actor class for this row.

Average Time

Average time to send replicated information in ms.

Time

Total time spent sending replicated information in ms.

Average Size

Average size of replicated information in Bits.

Average Size

Average size of replicated information in Bytes.

Count

Number of times this actor's information was replicated.

Total Size

Total size of replicated information in KBytes.

You can toggle between sorting by a column in ascending or descending order by clicking on the column heading.

The All Properties view mode displays information about all of the properties that were profiled in this session. This table has the same headers as the All Actors section except the Actor Class header is replaced with the Property header representing the name of the property for the specified row.

The All RPCs view mode displays information about all of the RPCs that were profiled in this session. This table has the same headers as the All Actors section except the Actor Class header is replaced with the RPC header representing the name of the RPC for the specified row.

The All Objects view mode displays information about all of the objects that were profiled in this session. This information includes:

Header Name

Description

Object Class

Name of the object class for this row.

# Comparisons

Number of comparisons made.

# Replications

Number of replications performed.

Comparison Time

Amount of time spent making comparisons in ms.

Average Time Per Compare

Average amount of time spent making comparisons in ms.

This view mode also includes a seperate table for properties. This information includes:

Header Name

Description

Property

Name of the property for this row.

# Comparisons

Number of comparisons made.

# Times Changed

Number of times the property value changed.

# Replications

Number of replications performed.

This is the main chart view. Similar to charts in other profiling applications, it shows a graph of the enabled stats over time. You can click on a particular frame to populate the other views with the data associated with that frame, or click and drag across the graph to zoom in to that area and view a summary for that time span.

Chart view and all of the following options are only available in the Chart, Filters, Details view mode.

This is a list of all the stats tracked by the network profiler. Toggling the checkboxes will show or hide that particular stat in the graph. For most stats, you can choose to show the raw count, the count per second, the number of bytes, or the number of bytes per second.

The details tabs display more in-depth network profiling information.

This is a summary of the data for the time span that has been selected in the chart. It shows raw totals as well as per-second information. Note that the "Outgoing bandwidth" will be greater than the "Game socket send size" because "Outgoing bandwidth" includes an approximation of the IP and UDP header sizes as well.

While a single frame is selected in the graph, this view will show a list of actor types that were replicated during that frame, sorted by the CPU time it took to replicate them. If an actor has associated replicated properties, expanding the tree view for the actor will show each property. For actors, the first column of numbers is the CPU replication time for that actor, in milliseconds. The second column is the number of bytes used to represent the actor in the bunch, and the third column is the number of actors of the given type that were replicated during the current frame. For property rows, the first column is the number of bytes used for the property, and the second column shows how many properties with the given name were replicated for the actor.

This view breaks down the data that was sent on the currently selected frame. You can see which actors, properties, and remote functions were sent, as well as how many bytes each one contributed. Note that replicated actors and RPCs are both included in bunches, so the value in the SendBunchSize sections includes the bytes from sending RPCs and replicating actors. Ultimately, the SocketSend entries will tell you exactly how many bytes the engine sent to the outgoing socket. Also note that the standard UDP packet overhead is not included here.

You can enter a filter for actors, properties, and RPCs, and after clicking the Apply Filters button, the graph will update to only show data that is relevant for actors, properties, and RPCs that contain the text entered in the filter fields. Selecting a frame or range of frames in the graph after a filter has been applied will also filter the data in the summary and frame details views accordingly.

Actors and their Owning Connections

Actor Relevancy and Priority

Replication Graph

Replicating Actors can take time. Unreal Engine (UE) does its best to make this as efficient as possible, but there are a few things you can do to make this job easier.

When gathering actors for replication, the server will check a few things like relevancy, update frequency, dormancy, etc. You can tweak any of these checks to affect performance. When thinking about making this process as efficient as possible, it is best to prioritize in this order:

Turning off replication (AActor::SetReplicates(false))

When an actor is not replicating, it is not on the list in the first place, so this is the biggest win, to make sure actors that do not need to replicate are marked as such.

Lower NetUpdateFrequency value

The less an actor updates, the less time it takes to update. It is best to make this number as low as possible. This number represents how often per second this actor will replicate to clients.

Dormancy

Relevancy

NetClientTicksPerSecond

Do not mark properties to replicate if they are not absolutely necessary. It is best to try and derive state from existing replicated properties when possible.

Try to take advantage of the quantization functionality that already exists. e.g. FVector_NetQuantize. These will greatly reduce the size needed to replicate this state over to clients, and if used properly, should not cause any noticeable artifacts.

FName variables are not generally compressed, so when you are using them as parameters to RPCs, keep in mind that they will generally send the string each call. This can be a lot of overhead.

Networking Overview

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Networking Overview

Basics of Character Movement

Movement Replication Summary

Replicated Character Movement In-Depth

Special Movement Cases

Customizing Networked Character Movement

The Character Movement Component is an Actor Component that provides an encapsulated movement system with common modes of movement for humanoid characters, including walking, falling, swimming, and flying. The character movement component also features robust network gameplay integration. Its default movement modes are all built to replicate by default, and it provides a framework to help developers create custom networked movement.

Basics of Character Movement

UCharacterMovementComponent comes preattached to the ACharacter Actor class and any Blueprints derived from it.

During its TickComponent function, UCharacterMovementComponent will call PerformMovement to calculate desired acceleration within the world based on what movement mode it is currently using as well as the player's input variables, commonly represented with the control input variables in APlayerController . Once movement calculations are finalized, UCharacterMovementComponent applies the final movement to the owning character.

While ACharacter is derived from APawn, Characters are not simply Pawns that have a character movement component added to them. UCharacterMovementComponent and ACharacter are designed to be used together, as ACharacter overrides several replicated variables and functions specifically to facilitate replication in UCharacterMovementComponent.

PerformMovement and Movement Physics

The PerformMovement function is responsible for physically moving the character in the game's world. In a non-networked game, UCharacterMovementComponent calls PerformMovement directly each tick. In a network game, PerformMovement is called by specialized functions for servers and clients to either perform the initial movement on a player's local machine or reproduce that movement on remote machines.

PerformMovement handles the following:

Applies external physics, like impulses, forces, and gravity.

Calculates movement from animation root motion and root motion sources.

Calls StartNewPhysics, which selects a Phys* function based on what movement mode the character is using.

Each movement mode has its own Phys* function that is responsible for calculating velocity and acceleration. For example, PhysWalking determines the character's movement physics when moving on the ground, while PhysFalling determines how it behaves in the air. If you wanted to debug the specifics of these behaviors, you would look inside each of these functions.

If a movement mode changes during a tick, such as when a character starts falling or collides with an object, the Phys* functions call StartNewPhysics again to continue the character's motion in the new movement mode. StartNewPhysics and the Phys* functions each pass through the number of iterations of StartNewPhysics that have occurred. The parameter MaxSimulationIterations is the maximum number of times this recursion is allowed.

Movement Replication Summary

UCharacterMovementComponent uses its owner's network role to determine how to replicate movement. The three network roles are as follows:

Network Role

Description

Autonomous Proxy

The character is on its owning client's machine, being controlled locally by a player.

Authority

The character exists on the server hosting the game.

Simulated Proxy

The character exists on any other client that can see the remotely-controlled character, whether it's being controlled by an AI on the server or by an autonomous proxy on a different client.

The replication process follows a cycle within the TickComponent function, which repeats itself on every tick. As the character performs movement, copies of it on all the different machines in the network game make Remote Procedure Calls (RPCs) to each other to synchronize movement information, with different network roles using different execution paths as appropriate.

The table below provides a step-by-step overview of what UCharacterMovementComponent does on each machine during this process:

Step

Description



Autonomous Proxy (Owning Player's Client)



1

The owning client controls the autonomous proxy locally. PerformMovement runs the physical movement logic of the movement component.

2

The proxy builds an FSavedMove_Character containing data about how it just moved, then queues it in SavedMoves.

3

Similar FSavedMove entries are combined together. The autonomous proxy sends a condensed version of their data to the server with a ServerMove RPC.



Authoritative Actor (Server)



4

The server receives the ServerMove and reproduces the client's movement using PerformMovement.

5

The server checks to see if its position after the ServerMove matches the client's reported end location.

6

If the server and client's final positions match, it sends a signal back to the client saying the move was valid. Otherwise, it sends a correction with a ClientAdjustPosition RPC.

7

The server sends its location, rotation, and current state to the simulated proxies on the other connected clients by replicating the ReplicatedMovement structure.



Autonomous Proxy (Owning Player's Client)



8

If the client receives a ClientAdjustPosition, it reproduces the server's movement and uses its SavedMoves queue to re-trace its steps to get a new final position. When the move is successfully resolved, it removes the saved move from the queue.



Simulated Proxy (All Other Clients)



9

The simulated proxies directly apply replicated movement information. Network smoothing provides visual cleanup for the final motion.

This process synchronizes movement between all three types of machines within a network game. The user controlling a given character should experience minimal interference from the server and maintain the illusion that they are controlling their character locally, and they should see other users' characters performing an approximation of the movement that they are all performing on their own machines.

Most of this process's complexity focuses on mediating predictions and corrections between the autonomous proxy and its counterpart on the server to make sure that players have the smoothest experience possible in controlling their own characters. Simulated proxies, by comparison, only need to stay up to date where the server says they should be.

Replicated Character Movement In-Depth

The following sections provide a detailed step-by-step walkthrough of the process briefly outlined above. Although a majority of projects are not expected to override UCharacterMovementComponent's behavior, this will serve as a reference in case you need to develop similar functionality or need to find where to make modifications.

This section focuses on replicating a character's normal movement modes. However, there are alternate execution paths for root motion and moving while based on another Actor, which follow similar steps to those listed in this section.

Local Movement on the Owning Client

Autonomous proxies process movement locally in TickComponent, record it, then send it to the server to be reproduced and applied authoritatively. This section will break down the process that an autonomous proxy goes through on each tick.

Autonomous proxies build an FNetworkPredictionData_Client_Character object called ClientPredictionData as part of their process for both recording moves and processing corrections from the server. Its parameters include:

Timestamps from when the client communicates with the server

Lists of saved or pending moves

Saved information from server corrections

Flags denoting how to apply corrections

Parameters determining smoothing behavior

ClientPredictionData also includes utility functions that interact with these parameters. You can find a full list of this object's information and functions in the API reference for FNetworkPredictionData_Client_Character. Its parameters are referenced and changed frequently as the client performs local movement, prepares moves to send to the server, and processes corrections.

Before the player's input or forces within the world are processed, the autonomous proxy calls ClientUpdatePositionAfterServerUpdate. This checks to see if the server has sent any corrections to the owning player. If it has, the variable bUpdatePosition inside ClientPredictionData will be true, and the character reproduces any moves sent from the server through the client correction process. For more information about server corrections, refer to the section below on Handling Client Error and Corrections.

Autonomous proxy characters call ReplicateMoveToServer during TickComponent instead of calling PerformMovement directly. This function surrounds PerformMovement with the necessary logic to record movement as the character performs it, then submits the move to the server. The FSavedMove_Character structure is a record of how the autonomous proxy started and ended its move during each tick, after which a minimum subset of its data is sent to the server through a ServerMove RPC. Its parameters include:

Information about the character's final position and rotation

What movement inputs were captured

What velocity and acceleration the character held

Root motion information captured from AnimMontages

You can review a full list of this structure's parameters in the API reference for FSavedMove_Character. This information enables the server to reproduce the movement that the player performed, then check against the final position of the client.

After processing PerformMovement, the ReplicateMoveToServer function records the results of a character's movement in the client prediction data with an FSavedMove_Character structure called NewMove, which is then added to a buffer called SavedMoves. This buffer is ordered from the oldest saved move to the newest and acts as a queue until a saved move can be submitted to the server. Any similar moves in the buffer are combined together into a single FSavedMove_Character before being submitted to ease the strain on bandwidth. The parameter PendingMove acts as storage for moves that are waiting to be combined with an upcoming movement.

These will be removed from the buffer when they are acknowledged, or ACKed. The server can ACK a move directly by confirming that the client's position is valid, or the client can ACK a move when it processes a correction from the server. The last move to be ACKed is saved in LastAckedMove for use in processing future corrections.

ReplicateMoveToServer finishes by running the function CallServerMove, which takes in the newest move and the oldest move in the queue that has not yet been ACKed by the server. This runs the final preparations for submitting a move to the server, attempts to submit the old move first (if applicable), then calls an appropriate ServerMove function to submit the finalized movement for the new move. The final ServerMove is submitted directly to the owning character of the UCharacterMovementComponent as an unreliable server RPC.

There are two reasons that ServerMove functions are unreliable:

During normal gameplay, ServerMove functions are called often enough that if they were designated as reliable, they could overflow the buffer for reliable functions, forcing the owning player to disconnect.

The system for buffering saved moves already ensures that movement information lost in transit will be resubmitted and evaluated. This provides a similar safety net to a reliable function, but without the risk of overflowing the reliable RPC buffer, and with added provisions to make sure movement data that is too old gets discarded.

Evaluating Movement on the Server

The server does not regularly tick movement in sync with the game's tick cycle. Instead, it waits to receive ServerMove calls from autonomous proxies, and ServerMove_Implementation handles movement on the server-side, reconstructing the client's movement and checking for discrepancies. This section will provide a walkthrough of the process that a ServerMove performs in detail.

This document broadly refers to ServerMove and ServerMove_Implementation, but there are multiple types of ServerMove calls depending on what kind of information is queued.

The authority version of a character movement component creates an FNetworkPredictionData_Server_Character object called ServerPredictionData, which exists for the lifetime of the character. During ServerMove_Implementation this object will store information to be used by later processes to reproduce the owning client's movement. This object is continually modified in the background as the server receives data, and its parameters include:

Timestamps used to calculate the server's delta time

Pending client adjustments

Flags related to resolving time discrepancies

Flags denoting whether the server ACKs or corrects a move

You can read its full list of parameters and functions in the API reference guide for FNetworkPredictionData_Server_Character.

The information sent with a ServerMove RPC includes a timestamp for when the move occurred. If the server's timestamp and the client's timestamp have too large of a discrepancy, the client's timestamp is considered expired and the move is discarded. Otherwise, the discrepancy is flagged to be resolved, and UCharacterMovementComponent uses ProcessClientTimeStampForTimeDiscrepancy to create an override for the delta time in the next step.

While delta time is usually obtained by keeping track of the time that has passed between the current tick and the previous tick, characters on the server do not use TickComponent to calculate movement. Instead, ServerMove_Implementation calls GetServerMoveDeltaTime and calculates movement as ServerMoves are received. If the server prediction data is flagged as trying to resolve a timestamp discrepancy, it will use TimeDiscrepancyResolutionMoveDeltaOverride. If there is no time discrepancy, it uses the server prediction data to create a delta time using the difference between the current ServerMove RPC's timestamp and the last ServerMove RPC's timestamp. To provide an extra layer of security, the majority of these calculations are performed with the server's timestamps instead of the client's, preventing clients from hacking their speed by speeding up their local game clock.

The server next uses the data from the ServerMove RPC to reconstruct the owning player controller's control rotation, then calls the function MoveAutonomous to process the character's acceleration, rotation, and jump inputs.

MoveAutonomous uses the PerformMovement function to simulate the character's movement physics using this reconstructed data and the delta time supplied in the previous step. Instead of simulating movement from where the client started, the server simulates from the location where its own copy of the character was when it got the ServerMove call.

If the character is performing root motion from an animation, MoveAutonomous also ticks the character's animation pose using the supplied delta time. Any animation events will trigger appropriately. Otherwise, animation ticks normally.

Handling Client Error and Corrections

Server movement works from the assumption that the server and owning client are both starting their movement in the same locations, and that if the server performs the same moves that the client reports, the locations that they end their moves in will also be the same. If the client's moves get dropped due to connection problems or if the client submits bad data, however, the two will end in different locations, necessitating a correction. The function ServerMoveHandleClientError is responsible for these operations.

Issuing corrections frequently would strain bandwidth and cause the client to re-simulate a large number of saved moves too often, so we first check against the value returned from WithinUpdateDelayBounds to see if a minimum amount of time has passed between moves. If it returns false, then no corrections will be issued. If it returns true, then the rest of the process is permitted to run.

Next, we use ServerCheckClientError to see if the error between server and client is large enough to be worth correcting. If it returns true, or if something sets bForceClientUpdate to true to force a correction, then ServerMoveHandleClientError continues with the rest of the process.

The parameters for adjusting both these operations can be found in BaseGame.ini, and you can provide project-specific overrides in the DefaultGame.ini for your project. The value ClientErrorUpdateRateLimit determines the minimum delay in seconds for the server sending error corrections to a client. The value MAXPOSITIONERRORSQUARED is the square of the max position error that is accepted in network play without being corrected. Both of these can be found under the [/Script/Engine.GameNetworkManager] section of the config file.

If an adjustment is necessary, the server prediction data fills an FClientAdjustment structure called PendingAdjustment with current movement variables sampled from the server's copy of the character, including location, rotation, velocity, and any objects that might be acting as a base for the character's movement. Otherwise, we set PendingAdjustment's bAckGoodMove value to true to flag the client's movement as being valid.

The final call for acknowledging movement to the client is made with SendClientAdjustment. This function does not occur as part of ServerMove_Implementation. Rather, this is part of UNetDriver::ServerReplicateActors, which is called at the end of a tick on the server and is similarly responsible for calling other client adjustment RPCs. When SendClientAdjustment is called, it will act depending on how the prediction data we built in the previous steps is flagged.

If the server prediction data's PendingAdjustment is flagged with bAckGoodMove as true, it will call the ClientAckGoodMove RPC to ACK the move, telling the autonomous proxy on the owning client's machine that the move was valid. This will remove the original move from the SavedMoves buffer on the owning client's side and record it as the LastAckedMove for use in building future prediction data.

If the PendingAdjustment has bAckGoodMove flagged as false, it will call client adjustment functions to send the final corrections to the client.

The client adjustment RPCs include ClientAdjustPosition, ClientAdjustRotation, shortened versions of them that occur when velocity is zero, and versions of them specially used for root motion-based movement. The server may call more than one of these as part of SendClientAdjustment, depending on the nature and severity of what needs to be corrected. Each of these is capable of telling ClientPredictionData to ACK moves once the necessary corrections are applied, and each of them will flag bUpdatePosition to true.

The final corrections are then applied at the beginning of the client's next TickComponent using ClientUpdatePosition.

Replicating Movement to Simulated Proxies

Characters on client machines other than their owners are simulated proxies instead of autonomous proxies. The process for replicating movement from the server to simulated proxies is highly simplified, as simulated proxies' only job is responding to the server. Instead of simulating movement physics, when they receive movement updates from the server, they set their location, rotation, and velocity to whatever the server says they should be, with a few additional processes to make their movement smoother and more believable.

When Actors replicate movement, they do not replicate their transforms directly. Instead, all Actors maintain a replicated variable called ReplicatedMovement, which uses the structure FRepMovement.

The boolean bReplicateMovement, represented by the Replicate Movement variable in Blueprint, flags Actors to store movement information in this structure and replicate it to clients. When a client receives updates to ReplicatedMovement, the RepNotify function OnRep_ReplicatedMovement unpacks the stored movement data and performs updates to the Actor's location and velocity accordingly.

Neither ReplicatedMovement or its OnRep are accessible inside of Blueprint, but OnRep_ReplicatedMovement can be overridden in C++, and ReplicatedMovement's replication conditions can also be overridden in GetLifetimeReplicatedProps. This enables you to customize how movement replication behaves in C++ based Actor classes.

In ACharacter, the ReplicatedMovement structure is only replicated for simulated proxies. It will be ignored on autonomous proxies, who otherwise use the server move and client adjustment RPCs to process movement.

If a character is using another Actor as a base, it will use ReplicatedBasedMovement instead, which applies additional logic to make sure the client is based correctly according to the server. If the character uses the root motion system, all of these processes are ignored in favor of using RepRootMotion.

When UCharacterMovementComponent runs TickComponent on a simulated proxy, it calls SimulatedTick to handle the logic for simulating movement. This does not perform the replicated movement outlined above. Instead, SimulatedTick continues moving in accordance with the most recently provided replicated movement data. When performing standard movement physics, it calls the SimulateMovement function, then performs final validations and network smoothing with SmoothClientPosition.

The SimulateMovement function is responsible for moving simulated proxy characters. In addition to being called by SimulatedTick, it is also called by OnRep_ReplicateMovement. This function performs the following processes:

Calls the owning character's GetReplicatedMovement function to obtain a reference to ReplicatedMovement.

Performs safety checks to ensure that replicated movement data is valid and that the client's base is resolved.

Checks to see if any network updates have been received.

Applies the character movement mode from the server, obtained with GetReplicatedMovementMode.

Resets all flags regarding network updates.

Performs the logic for simulated moves based on the current MovementMode and information about the character's current state.

The logic for simulated moves is highly simplified compared with standard movement physics, such that it is mostly contained in the SimulateMovement function itself rather than broken into smaller functions. However, this function is still responsible for updating the character's local movement state, including what movement mode it should transition into, whether or not the character has landed on the ground, and what velocity it should have. This information ensures that the character can update its animation correctly and that its movements appear reasonably accurate.

If we replicated movement by simply replicating the Location and Rotation of a character, then the character would seem to teleport every few moments. This is due to the rendering rate for a local machine being faster than the rate that we would want to send data over a network. A client may be rendering to a monitor with a 240 Hz refresh rate, for instance, but the replicated movement may be sent at only 30 Hz.

Network smoothing is a process that smooths out this motion, interpolating the character gradually from the source location towards a target location instead of snapping it to the target instantly. The source location is given by the character's current position, while the target is given by the client prediction data. The interpolation itself is handled in SmoothClientPosition, which uses NetworkSmoothingMode to determine what kind of interpolation it should use.

Special Movement Cases

The following sections contain information on common special movement cases, including teleportation, custom movement, and code-driven movement as you might see in special abilities.

Teleporting a Character in Multiplayer

You can teleport a character in a network game by calling any of the SetLocation functions or the Teleport Blueprint node, provided you:

Make sure they are called on the server.

If using the SetLocation functions, set the bTeleport variable to true so it recognizes the move as a teleport.



If these conditions are satisfied, the movement is recorded in the server's prediction data and in replicated movement as a teleport, and all clients respond accordingly by snapping the character to the desired location instead of applying smoothing.

Using Custom Movement Modes

The movement mode MOVE_Custom suspends all other movement physics, enabling you to implement custom movement logic without interference from UCharacterMovementComponent's normal processes.

UCharacterMovementComponent is not normally Blueprintable, so custom movement in Blueprint is usually implemented directly inside Character using the UpdateCustomMovement event. You can use the Custom Movement Mode byte variable to provide sub-modes, either with a switch on integer or with a conversion to a custom enum.



UpdateCustomMovement is called by the PhysCustom function in UCharacterMovementComponent. The functions StartNewPhysics, PhysCustom, and all the other movement physics functions are virtual functions, so if you create a custom UCharacterMovementComponent in C++, you can override them directly.

Replicating Special Case Movement with Root Motion

You may need to take direct control of a character's movement for brief periods, such as during abilities created with the Gameplay Ability System or during animation-driven actions. While this is simple to do in a local-only game, replicated special case movement requires the use of root motion, which generally refers to the application of movement from an animation. The root motion system has also been adapted to permit code-driven special case movement.

Root motion always takes precedence over standard movement physics, regardless of what movement mode the UCharacterMovementComponent is using. When your root motion is finished, normal movement will resume.

Most applications of root motion are expected to come from AnimMontages, which are used for code-triggered one-shot animations. This use of root motion suspends any other movement that your character is performing until the end of the animation. The character instead consumes movement from its skeleton's root bone and translates it into world-space movement, enabling the animation to control how the character moves. When this completes, the use of normal physics for the character is restored.

If your character is in the falling movement mode, gravity is still applied to the character's Z movement even when the character is performing root motion.

Within the replication process outlined above, root motion information is captured by the FSavedMove_Character structure, including the AnimMontage it comes from, the character's track position within the montage, and parameters for the character's movement itself.

The server and the autonomous proxy on the owning client do not check to see that they are playing the same animation, as this is normally considered a cosmetic feature. Therefore, you must program your gameplay logic to ensure that any AnimMontages are triggered correctly on all machines connected to a game. However, simulated proxies have parallel processes to the ones outlined above for synching root motion-based movement.

The Gameplay Ability System plugin synchronizes AnimMontages and root motion by replicating the ability that triggers them.

Sometimes you may need to control a character's location manually for special cases. For example, you might need to create a special ability where a character leaps a specific height into the air, then lands on a moving target.

Manually controlling the character with SetLocation and SetRotation is possible on standalone games, but in network games, this motion is not captured by the above replication process, so the server will see the client's final location as an error and issue a correction. Root motion from AnimMontages, meanwhile, follows only pre-computed motion from animations. This means that root motion can not normally take in real-time information from the game's world, such as the position of other characters, and it also can not be easily fine-tuned using gameplay variables.

Root motion sources provide a means for programmers to manually take control of a character's root motion. This enables you to control a character's movement programmatically while also taking advantage of the above system for handling root motion during networking.

Root motion sources should be applied to autonomous proxies on the owning client.

To use this system, you must create a new FRootMotionSource structure. Different FRootMotionSource variants exist for different kinds of movement. For instance, FRootMotionSource_MoveToForce is used for a straightforward move from a starting location to a target location, while FRootMotionSource_JumpForce follows a jump-like arc. Once you have created an appropriate root motion source, you can initialize its properties with the desired source location, target location, and parameters for how its movement should behave.

The function UCharacterMovementComponent::ApplyRootMotionSource will apply the root motion source to the character and return a handle that can be used to reference it later. The root motion sources themselves do not process movement. Instead, the character movement component performs movement consistent with the parameters in the provided FRootMotionSource in place of an animation. This is eventually added to SavedRootMotion within the FSavedMove_Character structure, capturing it in the replication cycle provided that the FRootMotionSource is applied to an autonomous proxy.

When the movement is completed, you must call UCharacterMovementComponent::RemoveRootMotionSource to remove it using the handle returned from ApplyRootMotionSource.

The Gameplay Ability System plugin contains several ability tasks that utilize root motion sources, enabling abilities to perform complex sequences of programmatic movement. You can refer to AbilityTask_ApplyRootMotionMoveToForce for a basic example.

Customizing Networked Character Movement

Unreal Engine enables replicated Character movement support of custom function parameters. Developers who do not require this functionality and want to maintain the legacy API can define SUPPORT_DEPRECATED_CHARACTER_MOVEMENT_RPCS to a non-zero value in the project build files, and set the Console Variable "p.NetUsePackedMovementRPCs" to zero.

The Character Movement Component sends data across the network using an FSavedMove_Character struct. The system consolidates move data from one or more updates into a single variable-length bit stream for transmission across the network. By packaging old and new data together, this method avoids potential ordering issues involving ServerMoveOld RPCs being called after ServerMove, which could cause old (but still important) data to be incorrectly disregarded as obsolete. Internally, the Character Movement Component uses the new CallServerMovePacked function to serialize multiple FSavedMove_Character instances into an FCharacterNetworkMoveDataContainer, replacing the old usage of CallServerMove.

Extending Saved Move Data

To add new data, first extend FSavedMove_Character to include whatever information your Character Movement Component needs. Next, extend FCharacterNetworkMoveData and add the custom data you want to send across the network; in most cases, this mirrors the data added to FSavedMove_Character. You will also need to extend FCharacterNetworkMoveDataContainer so that it can serialize your FCharacterNetworkMoveData for network transmission, and deserialize it upon receipt. When this setup is finised, configure the system as follows:

Modify your Character Movement Component to use the FCharacterNetworkMoveDataContainer subclass you created with the SetNetworkMoveDataContainer function. The simplest way to accomplish this is to add an instance of your FCharacterNetworkMoveDataContainer to your Character Movement Component child class, and call SetNetworkMoveDataContainer from the constructor.

Since your FCharacterNetworkMoveDataContainer needs its own instances of FCharacterNetworkMoveData, point it (typically in the constructor) to instances of your FCharacterNetworkMoveData subclass. See the base constructor for more details and an example.

In your extended version of FCharacterNetworkMoveData, override the ClientFillNetworkMoveData function to copy or compute data from the saved move. Override the Serialize function to read and write your data using an FArchive; this is the bit stream that RPCs require.

To extend the server response to clients, which can acknowledges a good move or send correction data, extend FCharacterMoveResponseData, FCharacterMoveResponseDataContainer, and override your Character Movement Component's version of the SetMoveResponseDataContainer.

Accessing Extended Move Data

To maintain backwards compatibility, there have been no changes to the function stack for working with client moves on the server and replaying them on the client after receiving a correction. While this provides a stable API for the legacy functions, it also means that those function signatures do not accomodate the new movement data. You can access this data on the server while processing a move, or on a client while replaying one, by calling GetCurrentMoveData and casting the returned FCharacterNetworkMoveData to your subclass.

Networking Overview

Multiplayer Programming Quick Start

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Installing Unreal Engine

Setting Up Visual Studio

Downloading Unreal Engine Source Code

Building Unreal Engine from Source

Lyra Sample Game

Overview

Dedicated Server

Tutorial

Configure Lyra

Build

Cook

Test

Extend the Multiplayer Experience

Lyra Sample

Expand Gameplay

Overview

Unreal Engine (UE) uses the client-server model for network multiplayer games. One server acts as the host for the game while players connect to the host as clients. The true game state is moderated by the server, this is referred to as the server being the authoritative host. Players control their pawns with an autonomous proxy. The server replicates changes from each connected client to simulate the true game state for each connected client. Clients see a close approximation of the game, which is actually being played on the server.

Dedicated Server

A listen server consists of a client hosting the game on their machine and acting as the server. Other clients connect to the hosting client and play the game on the hosting client's instance. In this model, the hosting client is the authoritative host. This gives them an advantage over the connected clients as they are actively playing in the true game state.

A dedicated server consists of a server that runs headlessly. This means that there are no clients playing directly in the dedicated server game instance. Every player comes from a connected, remote client. A headless server does not render any visuals and nobody is playing locally on the headless server.

This has several advantages over a listen server:

Smaller size

No unfair advantage for the host client

Focus on gameplay logic and moderating information from clients

A listen server is often acceptable for casual multiplayer and cooperative gaming, but dedicated servers are ideal for large-scale or competitive games.

This tutorial shows you how to build, cook, and test a dedicated server.

Tutorial

This tutorial uses the Lyra Starter Game as a base for setting up the dedicated server and clients. Lyra provides multiplayer functionality out-of-the-box, which makes it an ideal choice as a sample game for this tutorial.

To follow the steps in this tutorial, your project needs to satisfy the following requirements:

You must use a source build of Unreal Engine. See our Download Unreal Engine Source Code page for more information.

You must use a C++ project that supports client-server multiplayer gameplay.

Configure Lyra

Ensure that you have Generated Visual Studio project files for Lyra. Furthermore, make sure that you have switched the Unreal Engine version to your source build. Instructions for doing this can be found on the Download Lyra for Engine Source Builds documentation page. Once you have done this, open Lyra in the Unreal Editor by navigating to your project source directory and opening LyraStarterGame.uproject.

There are a couple things that you need to change before building the dedicated server and client builds of the Lyra sample:

Set the Server Default Map to L_Expanse so clients are taken directly to the map instead of the Lyra Main Menu.

Change the number of bots that spawn to 0 so bots do not immediately start attacking clients as soon as they connect to the server.



In the menu bar, navigate to Edit > Project Settings.... This opens a new Project Settings window.

Use the table of contents on the left to find Project > Maps & Modes.

Change Default Maps > Advanced > Server Default Map to L_Expanse.

Close the Project Settings window.

For more information about the maps available with Lyra, see the Lyra Sample Game documentation.



Changing the number of bots requires you to edit one of Lyra's assets. To edit an asset, open the Content Drawer.

Switch the directory to Plugins.

Search for the B_ShooterBotSpawner blueprint. This is the blueprint you need to edit to change the number of bots that spawn.

Open the B_ShooterBotSpawner blueprint. This opens a new window for this blueprint's settings.

Under the Teams section, find the field Num Bots to Create.

By default, this number is set to 3 so that when a game is started within the Unreal Editor, it starts a 2v2 elimination style game. Set Num Bots to Create to 0. This way you can see the clients connecting to the same dedicated server without the distraction of bot activity.

In the top left corner of the window, there is a Compile button. Click Compile for the changes that you made to the blueprint to take effect.

Close the blueprint window.

The initial project settings are now configured. Close the Unreal Editor.

If you are following this guide using Lyra, the PROJECT_NAME variable in file paths is LyraStarterGame for the Lyra Sample.

Build



You are ready to build the Development Server configuration for the Lyra Starter Game project.

Navigate to your project's root directory in File Explorer.

Right-click on your project's *.uproject file and select Generate Visual Studio project files...

Open the generated *.sln Visual Studio solution file in Visual Studio (VS).

If your project does not already have one, create a <PROJECT_NAME>Server.Target.cs in the <PROJECT_DIRECTORY>/Source directory.

See LyraServer.Target.cs for an example.

Change the Solution Configuration to Development Server.

From the menu bar, select Build > Build Solution. This builds the dedicated server for your project.

After the build process successfully finishes, you can find the newly built files in <PROJECT_DIRECTORY>/Binaries/Win64, in particular, the executable <PROJECT_NAME>Server.exe.

For Lyra, these are located in LyraStarterGame/Binaries/Win64, in particular, the executable LyraServer.exe.



You have built the server and can now build the Development Client configuration for the Lyra Starter Game.

With Visual Studio still open from the Build Server step, change the Solution Configuration to Development Client.

If your project does not already have one, create a <PROJECT_NAME>Client.Target.cs in the <PROJECT_DIRECTORY>/Source directory.

See LyraClient.Target.cs for an example.

From the menu bar, select Build > Build Solution. This builds the client game for your project.

After the build process successfully finishes, you can find the newly built files in <PROJECT_DIRECTORY>/Binaries/Win64, in particular, the executable <PROJECT_NAME>Client.exe.

For Lyra, these are located in LyraStarterGame/Binaries/Win64, in particular, the executable LyraClient.exe.

Cook



You have now built both the dedicated server and the clients that connect to the server. If you try to run the server from VS, you get an error message stating that there are missing shaders. This is because you have not yet cooked the content. To cook the server content:

Start the Development Editor either from VS or by navigating to UnrealEditor.exe in your project's directory.

From the Main Toolbar, set Platforms > Windows > Build Target to Server and Platforms > Windows > Binary Configuration to Development.

Run Cook from Platforms > Windows > Content Management.

A dialogue box appears in the lower right corner indicating that the content is cooking. Click Show Output Log in this dialogue box to monitor the cooking process.

If the process exits successfully, the output log shows BUILD SUCCESSFUL.

To see the files that were created during the cooking process, navigate to <PROJECT_DIRECTORY>/Saved/Cooked/WindowsServer.

Test that the server runs successfully by navigating to your project directory in the command prompt and execute ./Binaries/Win64/<PROJECT_NAME>Server.exe -log

Close the Logging window to shut down the dedicated server.

To cook the client content:

If the Unreal Editor is not already running, start the Development Editor either from VS or by navigating to UnrealEditor.exe in your project's directory.

From the Main Toolbar, set Platforms > Windows > Build Target to Client and Platforms > Windows > Binary Configuration to Development.

Run Cook from Platforms > Windows > Content Management.

A dialogue box appears in the lower right corner indicating that the content is cooking. Click Show Output Log in this dialogue box to monitor the cooking process.

If the process exits successfully, the output log shows BUILD SUCCESSFUL.

To see the files that were created during the cooking process, navigate to <PROJECT_DIRECTORY>/Saved/Cooked/WindowsClient.

Run the client by navigating to VS, changing the Solution Configuration to Development Client, and selecting Run without Debugging.

A splash screen appears saying Experience Still Loading... The client is running successfully, but it is expecting to connect to a dedicated server, which is not running. Close the Lyra client window.

Test



In a terminal window, run the following command from your project's root directory:

This starts the dedicated server and a logging window pops up.

By default, a dedicated server listens on the localhost IP address (127.0.0.1) at port 7777. You can change the port for your dedicated server by adding the command line argument -port=<PORT_NUMBER>. If you change the port that your server is using, you will also need to change the port when connecting the client to the server.

In a terminal window, run the following command from your project's root directory:



This starts an instance of the client game. To illustrate two clients connected to the same dedicated server, start another client instance by repeating the same command:



You should now see two players in the game. You can also check the server log for confirmation that both players are connected to the server.

The -WINDOWED, -ResX=<HORIZONTAL_RESOLUTION>, and -ResY=<VERTICAL_RESOLUTION> command-line arguments set here are for convenience. This enables you to see both client windows easily on the same screen for testing purposes. For more information on the command-line arguments used here, see our Command-Line Arguments page.

Extend the Multiplayer Experience

This tutorial teaches you how to build, cook, and test a dedicated server on your local machine. The next steps include: providing a functioning frontend, expanding your game's gameplay, and providing a means for players to connect to your dedicated server over the internet.

Lyra Sample

See the Lyra Sample for an example of a working game sample in Unreal Engine.



Explore how to develop projects in UE5 using techniques from the Lyra Sample Game.

Expand Gameplay

See the Network Multiplayer Quick Start Guide for more information about expanding your game's multiplayer gameplay.



Create a simple multiplayer game in C++.

Unreal Engine provides a wide variety of powerful tools for managing characters, creating cinematic content, and animating directly in the engine.

With the Skeletal Mesh Animation System, you can manage your imported characters, skeletons, and animations. This content can then be expanding to create interactive gameplay animation using various features such as Blend Spaces, Animation Blueprints, and State Machines. Cinematic sequences can be created using the Sequencer tool, where you can animate Cameras, characters, and effects. Animating characters can be accomplished using Control Rig, which is Unreal Engine's built-in control rigging tool. Using Control Rig, you can build animator-friendly rigs which can be animated in Sequencer.

Explore the following pages to learn about the various animation tools and features within Unreal Engine.



Unreal Engine's system for animation and controlling characters.



Sequencer is Unreal Engine's multi-track editor used for creating and previewing cinematic sequences in real time.



Rig and Animate characters in real-time using Control Rig.



Paper 2D is a sprite-based system for creating 2D and 2D/3D hybrid games entirely within Unreal Engine.

Animation Editors

Animation Blueprints

Animation Assets and Features

Live Link

Debugging and Optimization

Workflow Guides and Examples

Animation Shortcuts and Tips

Character animations in Unreal Engine are built on the foundation of a Skeletal Mesh, a rigged mesh that can be manipulated to create animations. In addition, Animation Blueprints can be augmented to Skeletal Meshes to apply logic that governs animation behavior and interactions within levels.

Unreal Engine provides a variety of animation tools to work with Skeletal Meshes to further enhance your animations. This page provides an overview of these primary systems.



Animation Editors

Here you will find information about the Animation Editors in Unreal Engine, such as the Skeleton Editor, the Animation Sequence Editor, and the Skeletal Mesh Editor.



An overview of the Animation Editor modes in Unreal Engine.



An in depth look at the Skeleton Editor mode in Unreal Engine.

An in depth look at the Skeleton Editor mode in Unreal Engine.



An in depth look at the Skeletal Mesh Editor mode in Unreal Engine.

An in depth look at the Skeletal Mesh Editor mode in Unreal Engine.



An in depth look at the Animation Sequence Editor in Unreal Engine.

An in depth look at the Animation Sequence Editor in Unreal Engine.

Animation Blueprints

In Unreal Engine, Animation Blueprints are a powerful and versatile system that provides you with the ability to visually script your animation behavior. With Animation Blueprints, you can control animation blending, script interactions, and create other procedural behaviors.



Animation Blueprints are visual scripts that are used for the creation and control of complex animation behaviors.



An overview of the Animation Blueprint Editor and its user interface.

An overview of the Animation Blueprint Editor and its user interface.



Edit, blend, and manipulate poses on Skeletal Meshes using various graphs in Animation Blueprints.

Edit, blend, and manipulate poses on Skeletal Meshes using various graphs in Animation Blueprints.



Create logic-based branching animation by using State Machines.

Create logic-based branching animation by using State Machines.



Descriptions of the various animation nodes available for use in Animation Blueprints.

Descriptions of the various animation nodes available for use in Animation Blueprints.



Insert entry-points within your Anim Graph to play animation from using Slots.

Insert entry-points within your Anim Graph to play animation from using Slots.



Synchronize the cycles of animations with different lengths using Sync Groups.

Synchronize the cycles of animations with different lengths using Sync Groups.



Modularize your Animation Blueprint logic by using Animation Blueprint Linking and Templates.

Modularize your Animation Blueprint logic by using Animation Blueprint Linking and Templates.

Animation Assets and Features

These pages contain information about the various Animation Assets and their associated features available to you.



Here you can find pages related to Animation Assets and Features in Unreal Engine.



Animation assets that contains animations for skeletal meshes.

Animation assets that contains animations for skeletal meshes.



Learn about Skeletons, Bones, and animation data management in Unreal Engine.

Learn about Skeletons, Bones, and animation data management in Unreal Engine.



Blend Spaces are graphs where you can plot any number of animations to be blended between based on the values of multiple inputs.

Blend Spaces are graphs where you can plot any number of animations to be blended between based on the values of multiple inputs.



Animation Montages are animation assets that enable you to combine animations in a single asset and control playback using Blueprints.

Animation Montages are animation assets that enable you to combine animations in a single asset and control playback using Blueprints.



Retarget and procedurally adjust animations using IK Rig and Retargeting tools.

Retarget and procedurally adjust animations using IK Rig and Retargeting tools.



An overview of Character Locomotion features in Unreal Engine.

An overview of Character Locomotion features in Unreal Engine.



Animation Composites serve as a way to combine multiple animations together and treat them as a single unit.

Animation Composites serve as a way to combine multiple animations together and treat them as a single unit.



Describes the Animation Pose Asset which can be used to drive animation through weighted curve data.

Describes the Animation Pose Asset which can be used to drive animation through weighted curve data.



Use Deformer Graphs to create and edit custom mesh deformations for skinned characters and objects.

Use Deformer Graphs to create and edit custom mesh deformations for skinned characters and objects.



Animation Modifiers enable users to define a sequence of actions for a given animation sequence or skeleton.

Animation Modifiers enable users to define a sequence of actions for a given animation sequence or skeleton.



Mirror animation in Unreal Engine using the Mirror Data Table.

Mirror animation in Unreal Engine using the Mirror Data Table.



Describes how you can use Skin Weight Profiles to improve visual fidelity on lower end platforms.

Describes how you can use Skin Weight Profiles to improve visual fidelity on lower end platforms.



Create shared animation systems that reduce the overall amount of animation work needed for a crowd of Actors.

Create shared animation systems that reduce the overall amount of animation work needed for a crowd of Actors.



User guide for the 3ds Max Vertex Animation tool set.

User guide for the 3ds Max Vertex Animation tool set.



User guide for the editing modes available in the Animation Editor.

User guide for the editing modes available in the Animation Editor.

Live Link

The pages below will help you set up and operate Live Link, a tool for real-time streaming of animation data from external DCC environments.



Describes how to enable and use the Live Link Plugin and features within the animation system in Unreal Engine.



Guide on how to use the LiveLink MasterLockit Plugin with a virtual camera

Guide on how to use the LiveLink MasterLockit Plugin with a virtual camera



A guide to how to use the LiveLink Preston MDR Plugin with a virtual camera.

A guide to how to use the LiveLink Preston MDR Plugin with a virtual camera.



Add tracking and camera data through Live Link with the FreeD protocol, commonly used for camera tracking and Pan, Tilt, Zoom (PTZ) cameras.

Add tracking and camera data through Live Link with the FreeD protocol, commonly used for camera tracking and Pan, Tilt, Zoom (PTZ) cameras.



Add tracking and input data from VR peripherals with the Live Link VRPN plugin.

Add tracking and input data from VR peripherals with the Live Link VRPN plugin.



Use LiveLink with XR devices through the LiveLinkXR plugin

Use LiveLink with XR devices through the LiveLinkXR plugin



Connect Unreal Engine to Audodesk Maya with the Live Link Plugin.

Connect Unreal Engine to Audodesk Maya with the Live Link Plugin.



Provides an overview of the features available for using Live Link to stream data to Actors.

Provides an overview of the features available for using Live Link to stream data to Actors.



An overview of plugin development and integration with Live Link.

An overview of plugin development and integration with Live Link.



Using the Live Link Curve Debugger, you can quickly see what the output is of various Live Link curves are in an easy to debug manner.

Using the Live Link Curve Debugger, you can quickly see what the output is of various Live Link curves are in an easy to debug manner.



Connect Unreal Engine to Audodesk Motionbuilder with the Live Link Plugin.

Connect Unreal Engine to Audodesk Motionbuilder with the Live Link Plugin.

Debugging and Optimization

For performance and debugging concerns, the following pages contain information about animation debugging and optimization.



With the Rewind Debugger you can record real-time segments of projects and preserve the data for debugging workflows.

With the Rewind Debugger you can record real-time segments of projects and preserve the data for debugging workflows.



Describes methods to achieve more performant Animation Blueprints through optimization techniques.

Describes methods to achieve more performant Animation Blueprints through optimization techniques.



Overview of Animation Insights, the gameplay and animation performance profiling tool available as an editor plugin

Overview of Animation Insights, the gameplay and animation performance profiling tool available as an editor plugin



System for constraining the time taken for animation data by dynamically throttling Skeletal Mesh Component ticking.

System for constraining the time taken for animation data by dynamically throttling Skeletal Mesh Component ticking.

Workflow Guides and Examples

Contained below are guides and content examples created using Unreal Engine's animation tool kit.

Animation Shortcuts and Tips

Here you can find workflow shortcuts, tips, and console commands to foster more efficient and productive techniques when utilizing the many animation tools Unreal Engine has to offer.



Workflow shortcuts and tips for animators and animation programmers in Unreal Engine.

Overview

Toolbar

Viewport

Editor Modes

Skeleton Editor

Skeletal Mesh Editor

Animation Sequence Editor

Preview Scene Settings

The Skeletal Mesh Animation System in Unreal Engine is comprised of specialized animation asset editors that feature robust animation tools that you can use when working with Skeletal Meshes and other Animation Assets. With these animation editors, you can create character animations, interactions within the levels, and other procedural behaviors.

This document provides an overview of the specialized animation editors in Unreal.

Overview

A character's skeletal mesh has many associated assets that can be opened through the Content Browser. These assets include a Skeleton, Skeletal Mesh, Animation Sequences, and Animation Blueprints. Depending on which asset is opened, the corresponding Editor Mode will open.

Here you will find an overview of an Animation Editor window with highlighted features, common across all of the Animation Editor Modes.



Toolbar

Viewport

Editor Modes

Preview Scene Settings

Toolbar

The Toolbar, which is found in all of the Animation Editor modes, is similar to the Toolbar found across Unreal Engine's many editors and windows. For general Toolbar functions refer to the Main Toolbar, and for specific animation editor toolbar features, reference their respective pages for more information.



The following unique features are common across all of the Animation Editors:

Name

Icon

Description

Preview Mesh



Set a new preview Skeletal Mesh for the current asset (Stored per-animation or per-skeleton).

Preview Animation



Select a preview animation for playback with the current asset.

Create Asset



From this drop down menu, the following Animation Assets can be created:

Create Animation creates a new Animation Sequence from either the current default Reference Pose, or from the displayed meshes Current Pose.

Create Pose Asset creates a new Pose Asset from either the Current Pose displayed on the mesh, the Current Animation description, or the Insert Pose Description.

Anim Blueprint creates a new Animation Blueprint for the current Skeletal Mesh.

Anim Composite created a new AnimComposite using the selected Skeleton.

Anim Montage creates a new AnimMontage using the selected skeleton.

Blend Space creates a new Blend Space used for smoothly blending transitions between animations.

Blend Space 1D creates a new 1D Blend Space using the selected Skeleton.

Aim Offset creates a new Aim Offset Blend Space using the selected skeleton.

Aim Offset 1D creates a new Aim Offset 1D Blend Space using the selected skeleton.

Viewport

The Viewport window allows you to preview playback of animation assets on your selected Skeletal Mesh and provides information about your assets. Below you will find highlighted features relevant to the Animation Editors.



Viewport Property Settings

Listed below are the viewport properties relevant to the Animation Sequence Editor Viewport.

Name

Description

Preview Animation

Lists the current selected animation sequence.

LOD (Level of Detail)

The current displayed LOD or Level of Detail assigned value of the character.

Current Screen Size

This is a value that represents how much of the viewport is occupied by the character's bounding box (By default, the bounding box is derived from the Physics Asset, if one is present, and Skeleton Asset if not.). Factors that affect this number are how large the animation's bounding box is (or the displacement in 3D space), how close the character is to the camera, and the amount of zoom applied to the camera. Based on this value you can assign when your LOD should switch between levels.

Triangles

Lists the number of triangles rendered that comprise the previewed mesh.

Vertices

Lists the number of vertices, or individual coordinate points, that comprise the previewed mesh.

UV Channels

Lists the current mesh's UV Channel.

Approximate Size

Dimensions of a bounding box containing the current animations displaced space, calculated by one of the animations assets. By default the physics asset will be used, and if no physics asset is present then the Skeleton asset will be referenced. Listed in Unreal Units (Centimeters).

Frame Rate

Lists the preview animations frame rate of playback.



Debug Text

Here you the Animation Editor Debug Text can also be seen in the top right of the Viewport. Here you can find important reference information about the animation asset currently being used such as the name of the animation asset, the LOD mode, Current screen Size and display output of mesh properties such as displayed triangles and vertices.



Editor Modes

Each Animation Editor Mode, can be opened with their respective buttons in the top right of your project window:



Skeleton Editor: This editor is used for working with Skeleton Rigs and provides visual control of bone and joint hierarchy associated with a Skeletal Mesh.

Skeletal Mesh Editor: The Skeletal Mesh Editor is where you can make edits to meshes, assign Materials, adjust Level of Detail (LOD), and test Morph Target functionality.

Animation Sequence Editor: If the Skeletal Mesh has associated Animation Sequences, you can edit and preview them, including augmentation tools such as, Blendspaces, Morph Targets and Animation Notifies here.

Animation Blueprint Editor: Similar to Unreal's Blueprint Editor, The Animation Blueprint editor is a visual scripting environment for directing animation functionality and behaviors within the level. You can access this Mode after an Animation Blueprint asset has been created for your mesh.

Physics Asset Editor: The Physics Asset Editor is a dedicated animation editor you can use to manipulate the Physics Asset assigned to your Skeletal Mesh.

After opening a Skeletal Mesh asset for the first time, the Skeletal Mesh Editor will be the default Editor Mode open. By clicking any of the other Editor Modes, a new window tab will open in your current editor window.

Skeleton Editor

In the Skeleton Editor Mode you will find a hierarchy outline and visual preview of the Bone data found within your Skeleton Mesh. Here you can adjust bone placement, create Skeleton Sockets, and preview Animation Curves.



An in depth look at the Skeleton Editor mode in Unreal Engine.

Skeletal Mesh Editor

The Skeletal Mesh Editor Mode is where you can edit visual attributes of Skeletal Meshes. For instance, manipulating the polygonal structures of meshes, editing the associated Materials, and even assigning LODs.



An in depth look at the Skeletal Mesh Editor mode in Unreal Engine.

Animation Sequence Editor

With the Animation Sequencer Editor mode, you can perform animation focused editing, specific to any of your project's animation asset types. Examples include creating and managing Animation Sequences, Animation Notifies, Animation Montages, and more.



An in depth look at the Animation Sequence Editor in Unreal Engine.

Preview Scene Settings

The Preview Scene is the visual preview found in all of Unreal Engine's many project windows. With this window you can quickly see what your asset and animations will look like in different lighting environments and playback scenarios.



Below are a few features of the Preview Scene Settings window that are unique to the animation editors modes:

Name

Description

Preview Controller

Here you have control over which animation is previewed in the viewport.

Default will use the Animation tool's default settings. In most cases, this will cause the character to use the reference pose, except when an animation sequence is being viewed.

Reference Pose will use the Skeletal Mesh's Reference Pose.

Use Specific Animation will open an option to select a specific Animation Sequence associated with your skeletal mesh to preview.

Live Link Preview Controller will use preview using Live Link settings.

The selected mode will also be displayed on the first line of the Debug Text in the viewport.



Preview Mesh (Skeleton)

This property enables you to change the Skeletal Mesh used for previewing purposes. Only found in Skeleton Editor and Animation Editor.

Allow Different Skeletons

When this property is enabled you can select an additional mesh, even ones not associated with the current skeleton, to preview in the viewport. Only found in Skeleton Editor and Animation Editor.

Allow Custom AnimBP Override

If using a Preview Collection, you can enable this property to allow an override of custom Animation Blueprints. Only found in Skeleton Editor and Animation Editor

Additional Meshes

For use in instances of Mesh Collection implementation. View other meshes included in the current Mesh Collection for previewing purposes. Only found in Skeleton Editor and Animation Editor.

Skeletal Meshes

The Skeletal Mesh assets that are included in the specified Preview Mesh Collection. Only found in Skeleton Editor and Animation Editor.

Settings

General scene lighting and rendering settings.

Toolbar

Skeleton Tree / Retarget Sources

Skeleton Tree

Bone Manipulation

Retarget Sources

Viewport

Preview Scene Settings / Details

Preview Scene Settings

Details

Anim Curves / Animation Notifies

Anim Curves

Animation Notifies

In Unreal Engine, Skeleton Assets are the foundation for all animation work with Skeletal Meshes. The Skeleton Editor Mode is the visual editor where you can find the tools and properties to make changes to Skeleton Assets.

In this editor you can manipulate individual bones and bone structures, attach Skeletal Mesh Sockets, and preview any Animation Curves and Animation Notifies associated with your skeleton. The Skeleton Editor is also where you can find the Retargeting Manager, a tool for managing meshes associated with the current Skeleton Asset.

Below is the Skeleton Editor window with the following tools and Panels:



Toolbar

Skeleton Tree / Retarget Sources

Viewport

Preview Scene Settings / Details

Anim Curves / Animation Notifies

Toolbar

The Toolbar found in the Skeletal Mesh Editor is similar to the Toolbar found across Unreal Engine's many editors and windows. For general Animation Editor functions refer to the Animation Editors Overview's Toolbar Section for more information. The following are features unique to the Skeletal Mesh Editor Mode.



Name

Icon

Description

Anim Notifies



Opens the Animation Notifies panel where you can manage the animation notifies associated with the skeleton.

Retarget Sources



Will open the Retarget Sources panel where you can manage retarget sources and setups with the current skeleton asset.

Import Mesh



Imports a new mesh for this skeleton.

Make Static Mesh



Makes a new static mesh out of the preview's current pose.

Skeleton Tree / Retarget Sources

This panel features the Skeleton Tree tab by default. After clicking Retarget Sources in the Toolbar, the Retarget Sources tab will also appear here.

Skeleton Tree

Skeleton Tree tab displays the Skeletal Hierarchy of the current Skeleton Asset, which allows you to create and edit Skeleton Sockets and define settings related to Animation Retargeting.



Using the green Plus (+) button, assets and profiles can be added to your skeleton. Below you will find a list of the assets the Plus (+) button can create.

Name

Description

Socket

Sockets are offsets from bones that allow you to attach game objects to skeletons.

Virtual Bone

Virtual Bones are auxiliary bones that are children of a bone but constrained to another.

Add Time Blend Profile

A Time Blend Profile is a set of per-bone scales that can be used in transitions to tweak the weights of specific bones, relative to the transitions' blend time.

Add Weight Blend Profile

A Weight Blend Profile is a set of per-bone scales that can be used in transitions to tweak the weights of specific bones, relative to the transitions' blend weight.

Add Blend Mask

A Blend Mask is used to specify the alpha of individual bones when layering poses. (It is used by the Layered Blend Per Bone node and the Pose Watch.)

The Gear icon to the right of the Search Bar will open a menu providing settings and toggle filters you can use to alter Skeleton preview and skeleton tree behavior. Below you will find a description of each property and a description of its function.

Setting

Description

Blend Profiles

Select the Blend Profile you want to preview and edit with the current Skeleton Asset. The profile from the base Skeleton Asset will appear as a column in the Skeleton Tree tab displaying each bone's weight in the form of a slider. The Clear option at the bottom of the Blend Profiles header will clear the currently selected Blend Profile.



Add Time Blend Profiles

Add a new Time Blend Profile for this skeleton.

Add Weight Blend Profiles

Add a new Weight Blend Profile for this skeleton.

Add Blend Mask

Add a new Blend Mask to this skeleton.

Show Retargeting Options

Opens a new column in the Skeleton Tree showing each bone's Bone Translation Retargeting mode. The selectable options are:

Animation: Displays translation data from the associated animation.

Skeleton: Shows translations from the associated Skeleton.

Animation Scaled: Shows translations from the associated animation, but scales the length by the current skeleton's proportions.

Animation Relative: Uses relative translations from the associated animation similar to an additive animation.

Orient and Scale: Orients and scales a uniform translation.

Filtering Flattens Hierarchy

A visual filter that determines whether to display the above hierarchy or flatten it when searching for tree items.

Hide Parents When Filtering

A visual filter that determines whether to show the parent items as grayed out, or hide them entirely.

Show all Bones

Shows all bones in the current skeleton.

Show Mesh Bones

Shows all bones used in the current mesh.

Show LOD Bones

Shows all bones that are used in the current LOD.

Show Weighted Bones

Shows all bones that have vertices weighted to them.

Hide Bones

Hides all bones, but will still list any sockets and attached assets.

Show Active Sockets

Shows mesh and skeleton sockets, hiding the skeleton sockets that have a customized mesh socket.

Show Mesh Sockets

Shows any sockets that are in the mesh only.

Show Skeleton Sockets

Show any sockets that are in the skeleton only.

Show All Sockets

Shows all sockets that are in the mesh and skeleton.

Hide Sockets

Hides all sockets.

Bone Manipulation

The Bone Manipulation tool is useful for previewing animations with altered bone positions. Using Bone Manipulation, you can preview how skeletons interact with other assets and even create new animations by assigning altered bone positions using the Timeline Record.

To use the Bone Manipulation Mode, select the desired Bone in the Skeletal Tree Window. You can now see the highlighted bone has a Manipulator in the Viewport and you can now manipulate the Bone through Transform (W), Rotation (E) and Scale (R).



After you have manipulated a bone, the manipulation persists when you select different animation assets, so you can preview the change with different animations. Any modified bones will return to their default translation, rotation, or scale when you close and re-open the Animation Editor.

Retarget Sources

The Retarget Sources tool in the toolbar will open a panel which stores and manages a list of your retarget sources. Retarget sources are used to import animations on authored characters with different proportions, a method called Animation Retargeting.



Viewport

The Viewport window allows you to preview your selected Skeletal Mesh and provides information about your assets.



For more information about the unique animation centric features of the viewport, refer to the Animation Editors Overview page.

Preview Scene Settings / Details

This panel has two tabs, Preview Scene Settings and Details.

Preview Scene Settings

Located in this section is a tab for Preview Scene Settings which you can use to control the preview settings such as the selected animation, applied Skeletal Meshes, Viewport lighting, and Post Process settings.



Details

Similar to the main editor, the Details panel is primarily used for modifying the properties of elements like bones.



Clicking a Socket in the Skeleton Tree will populate the Details panel with options related to how the Socket functions.



Below you will find a list of unique properties of Skeleton Sockets.

Name

Description

Force Always Animate

When enabled, the current socket and the associated hierarchy of bones will always be evaluated for animation, even in instances where the structure has been optimized for the current LOD.

Socket Name

Lists the selected Socket's name.

Bone Name

Displays the bone to which the current Socket is attached.

Anim Curves / Animation Notifies

In this section, you find the Anim Curves tab by default. Additionally, this is also where the Animation Notifies tab will open after selecting Anim Notifies in the Toolbar.

Anim Curves

Using the Anim Curves panel, you can create and manage curve values for Morph Targets, as well as Attribute and Material curves for the selected skeleton.



You can filter the visible curves to show only active curves by clicking All Curves to deselect it, then you can toggle filters by checking the boxes next to Morph Target, Attribute, and Material curves.

For more information about Animation Curves and the Curve Editor, refer to the Animation Curves page.

Animation Notifies

Animation Notifications (AnimNotifies or just Notifies) provide a way for animation programmers to set up events to occur at specific points during an Animation Sequence. Notifies are commonly used to add effects to animation like footstep sounds during a walk.



Here you can create and manage the Notifies associated with the current skeleton asset.

For more information about Animation Notifies and workflow examples, refer to the Animation Notifies page.

Toolbar

Reimport Base Mesh

Cloth Paint

Make Static Mesh

Asset Details / Skeleton Tree

Asset Details

Skeletal Tree

Viewport

Preview Scene Settings / Morph Target Previewer

Preview Scene Settings

Morph Target Previewer

The Skeletal Mesh Editor Mode is where you can find the tools to manipulate and preview Skeletal Mesh assets. It is similar to the Static Mesh Editor. In the Skeletal Mesh Editor you can make changes to the polygonal mesh by assigning Materials, adding clothing elements, setting up LODs (Level of Detail), and previewing any Morph Targets applied to the mesh.

Here is the Skeletal Mesh Editor, with the following tools and panels:



Toolbar

Asset Details / Skeleton Tree

Viewport

Preview Scene Settings / Morph Target Previewer

Toolbar

The Toolbar found in the Skeletal Mesh Editor is similar to the Toolbar found across Unreal's many editors and windows. For general Animation Editor functions refer to the Animation Editors Overview's Toolbar Section for more information. The following are features unique to the Skeletal Mesh Editor Mode.



Reimport Base Mesh

With Reimport Base Mesh, you can begin the re-import process for the Base Mesh of the current Skeletal Mesh. This can be helpful if the mesh was not imported correctly and adjustments need to be made, or if you need a fresh start with the current mesh.



Option

Description

Reimport Base Mesh

Opens the current skeletal meshes original source FBX file, with a new import options window.

Reimport Base Mesh With New File

A file browser opens where a new source FBX file can be selected and imported. Unreal will work to assign any of the existing Materials, Bones, and other Assets to the new mesh, and will ask for permission in some instances where an exact match is not available. Any assets unable to be assigned will be marked as failed.

Reimport Base Mesh + LODs

Re-imports the Mesh's original source file, including the base LOD and any custom LODs associated with the source file.

Reimport Base Mesh + LODs With New File

Imports the base mesh, the base LOD, and any custom LODs from new source files. LODs can be imported directly with FBX files, but can also be found in separate source files. See the Source Import Filename property in the Asset Details panel to see how your mesh's source files are organized.

Reimport Content

Only re-imports specific content elements of the Mesh for it's base LOD. Elements can be either Geometry or the Skinning and weights exclusively.

By clicking any of these options associated with the original source file, Unreal will automatically open the mesh from its original known location. If the file cannot be located, or the option involves selecting a new source file, a browser window will open where one can be assigned.

Cloth Paint

Unreal provides an efficient and lightweight clothing solver, with integrated editing and preview tools, accessible from the Skeletal Mesh Editor Toolbar.



Clicking the button will open the Clothing panel that will dock next to the Asset Details and Skeleton Tree panels. Here you will have access to properties and settings that will assist in assigning your mesh's clothing materials and controlling their behaviors.

For more information and workflow examples regarding clothing in Unreal, refer to the Clothing Tool page.

Make Static Mesh

The Make Static Mesh button will create a new Static Mesh Asset from the current Skeletal Mesh's pose.



After manipulating the Skeletal Mesh to a desired pose and clicking Make Static Mesh, you are prompted to choose a location to save the new Static Mesh. This asset can now be placed in a level or edited similar to any other static mesh object.

Asset Details / Skeleton Tree

By default this window contains two panels, the Asset Details panel and the Skeleton Tree panel, that, while accessible in other editors, contains unique features for the Skeletal Mesh Editor.

Asset Details

The Skeletal Mesh Asset Details panel is a context-sensitive property editor that you can use to edit and modify settings pertaining to the selected Skeletal Mesh and its elements such as its Materials, LODs, and the Reduction Tool. Many of the properties found under this tab are general to all Meshes and will be described in detail on the Static Mesh page.



Here you will find a description and function of all of the unique and relevant properties of the Asset Details panel.

Property

Description

Sections

Many of the same properties for assigning and previewing Static Mesh Materials are present here. However, a unique property to Skeletal Mesh LOD generation is the Generate Up To property, where you choose up to which LOD the current material is generated. This can be helpful when you want to swap materials at different LODs.



LOD Info



LOD Hysteresis

This value is used to avoid ‘flickering' when crossing a LOD threshold. Only taken into account when transitioning from a complex to a simple LOD. Higher values will increase the hysteresis, or lag, of the perceived model, which can smooth transitions between radically different LODs.

Bones to Prioritize

While the Skeletal Mesh Reduction tool is effective at reducing the triangle count of Skeletal Meshes, there can be instances where the reduction is too aggressive. To provide more control over what is optimized and what is not, the Bones to Prioritize array makes sure that any geometry skinned to the bones in the list will not be optimized. Listed here is an array of Bones which should be prioritized to retain quality. Use the Weight of Prioritization property to control the value at which these are prioritized.

Sections to Prioritize

Similar to the Bones to Prioritize property above, this property is an array of Sections, or Material Slots, which should be prioritized to retain quality. Use the Weight of Prioritization property to control the value at which these are prioritized.

Weight of Prioritization

Listed here is the value that determines how much consideration to give the Bones to Prioritize and Sections to Prioritize properties. The weight is an additional vertex simplification penalty where 0 means nothing. Higher values increase the weight of prioritization for listed Bones and Sections, while lower values reduce the weight of prioritization.

Source Import Filename

Listed is the source file directory, for the base mesh FBX file, and any separated associated custom LOD source files.

Skin Cashe Usage

This drop down menu will set the LODs behavior in using the skin cache feature. Options are as follows:

Auto defers to the default project global option established in the project settings.

Disabled means the Mesh will not use the skin cache.

Enabled means the mesh to use the Skin Cache.

If the Support Ray Tracing property is enabled on the mesh, it implies Enabled by default.

Morph Target Position Error Tolerance

The property value is displayed in microns. Larger values result in better compression and lower memory footprint, but also lower quality.

Bake Bose

Select a single frame of animation to bake into a pose. This is useful when automatic LOD generation is removing bones for lower detail LODs but you want to retain a finer detail that has been removed. For more information, refer to the Pose Asset page.

Bake Pose Override

Overrides the Bake Pose property. The source Bake Pose can be disabled if some LOD settings are in use. For more information, refer to the Pose Asset page.

Bones to Remove

An array of Bones to be removed from the skeleton for this LOD level.



Skeletal Mesh Reduction Tool



Termination Criterion

The Termination Criterion option in the Skeletal Mesh Reduction tool gives you the ability to change the way the simplifier reduces the Skeletal Mesh asset in LOD generation. For example, you can specify the number (or percentage) of vertices, instead of triangles, to provide more control to better fit memory or performance targets.

The available options for reduction technique are as follows:

Triangles: Relying on the Percent of Triangles property, the Reduction Tool targets a percentage of triangles of the base mesh to generate a LOD.

Vertices: Relying on the Percent of Vertices property, the Reduction Tool targets a percentage of vertices of the base mesh to generate a LOD.

First Percent Simplified: This option will generate a simplified LOD by factoring both Percent of Triangles and Percent of Vertices, completing the LOD with whichever factor is achieved first.

Max Triangles: This option will generate a LOD using an established maximum number of triangles, in the Max Triangle Count property.

Max Vertices: This option will generate a LOD using an established maximum number of vertices, in the Max Vertex Count property.

First Max Satisfied: This option will generate a simplified LOD by factoring both Max Triangles and Max Vertices, completing the LOD with whichever factor is achieved first.

Depending on which Termination Criterion is selected the following options will dynamically change to the relevant properties.

Percent of Triangles

This property is a target percentage value of triangles to generate a simplification of the source mesh for a new LOD.

Percent of Vertices

This property is a target percentage value of vertices to generate a simplification of the source mesh for a new LOD.

Max Triangles Count

The maximum number of triangles to retain when using the percentage criterion. A maximum value to limit the automatic generation.

Max Vertices Count

The maximum number of vertices to retain when using the percentage criterion. A maximum value to limit the automatic generation.

Max Triangles Count

The maximum triangles to retain when using the Max Triangle criterion.

Max Vertex Count

The maximum vertices to retain when using the Max Vertices criterion.

Remap Morph Targets

Remaps the existing morph targets from the base LOD to the reduced LOD selected.

Max Bone Influence

The maximum number of bones that are assigned to each vertex.

Enforce Bone Boundaries

If enabled, Unreal will penalize edge collapses between vertices that have different major bones attached. This helps articulated segments like tongues, but can lead to undesirable results under extreme simplification.

Merge Coincident Vertices Bones

If enabled, the same location, for example UV boundaries, always has the same bone weights. This can fix bone merge errors when the characters are animated.

Volumetric Correction

A slider to determine the Volumetric Correction implemented at this LOD level. The default value of 1 attempts to preserve volume. Smaller values will lose volume by flattening curved surfaces, and larger values will accentuate curved surfaces.

Lock Mesh Edges

If enabled, cuts in the mesh's surface are preserved by locking vertices in one place. This increases the quality of the simplified mesh at edges, at the cost of more triangles.

Lock Vertex Color Boundaries

If enabled, edges that connect two vertex colors are locked. This increases the quality of the simplified mesh at edges at the cost of more triangles.

Regenerate

If pressed, Unreal will regenerate the current LOD with the applied Reduction Tool properties above.



LOD Settings



LODSettings

Choose the data asset with which to save the current LOD info. This data can be saved to an existing data asset or, if none is selected, a new one can be generated by clicking Generate Asset.

Disable Below Min LOD Stripping

If enabled, below minimum LOD stripping is disabled. With the plus(+) button, you can add an override for a specific platform or group.

Override LodStreaming Settings

If enabled, overrides the LOD streaming settings. With the plus(+) button, you can add an override for a specific platform or group.

Stream LODs

If enabled, supports LOD streaming. With the plus button, you can add an override for a specific platform or group.

Max Num Streamed LODs

The maximum number of Streamed LODs allowed. With the plus(+) button, you can add an override for a specific platform or group.

Max Num Optional LODs

The maximum number of Optional LODs allowed. With the plus(+) button, you can add an override for a specific platform or group.



Clothing



Mesh Clothing Assets

An array listing the Mesh Clothing Assets associated with the current mesh.



Mesh



Skeleton (Mesh)

The current Skeletal Mesh's Skeleton asset. Double clicking the Skeleton will open the skeleton in the Skeleton Editor.



Animation Rig



Default Animation Rig

The Control Rig Asset associated with the current Skeletal Mesh.



Physics



Enable Per Poly Collision

If enabled, Per Poly Collision is allowed, or the inhibition of the mesh's individual polygons to overlap.

Physics Asset

The Physics asset associated with the Skeletal Mesh. Double clicking the Physics asset will open the Physics Editor.



Lighting



Shadow Physics Asset

The Shadow Physics asset associated with the Skeletal Mesh.



Skeletal Mesh



Post Process Anim Blueprint

Assign or access a Post Process Animation Blueprint which runs after any Animation Blueprint assigned to the Main Anim Instance for a Skeletal Mesh Component. By assigning a Post Process Anim Blueprint to a Skeletal Mesh, you can create AnimDynamics, Skeletal Controls, or other Anim Blueprint logic without having to copy that logic to other Animation Blueprints.

Advanced User Data

An array of stored user data, used for implementing uniform functions or accessing stored information.



Animation



Node Mapping Data

An array of stored node mapping data, used for implementing uniform functions or accessing stored information.



Import Settings



Import Content Type (Import/Mesh)

Select what content from the source file you wish to import. Options are as follows:

Geometry and Skinning Weight imports all source file content.

Geometry Only imports the respective content exclusively.

Skinning and Weights Only import the respective content exclusively.

Update Skeleton Reference Pose

If enabled, the mesh's skeleton's reference pose will be updated when importing.

Use T0 As Ref Pose

If enabled, frame 0 will be used as the reference pose when importing.

Preserve Smoothing Groups

If enabled, triangles with non-matching smoothing groups will be physically split when importing.

Import Meshes In Bone Hierarchy

If enabled, meshes in bone hierarchies will be imported instead of being converted to bones.

Import Morph Targets

If enabled, creates Unreal morph objects for the imported meshes.

Threshold Position

Edit the threshold to compare vertex position equality.

Threshold Tangent Normal

Edit the threshold to compare normal, tangent of bi-normal equality.

Threshold UV

Edit the threshold to compare UV equality.

Morph Threshold Position

The threshold to compare vertex position equality when computing morph target deltas.

Normal Input Method

Select the normal input method for normals and tangents associated with the mesh. Options in the dropdown are as follows:

Compute Normals in Unreal.

Import Normals from the source file.

Import Normals and Tangents from the source file.



File Path



Source File (Geometry and Skinning Weights)

The file directory of the source file.



Skin Weights



Skin Weight Profiles

An array of stored skin weight profiles, used for implementing uniform functions or accessing stored information.



Ray Tracing



Ray Tracing Min LOD

Decide which LOD of the current mesh is the minimum LOD for which Ray Traced reflections are enabled.

Cloth LOD Bias Mode

Decide the LOD bias towards Cloth simulation. Options are as follows:

Mapping to Same LOD only stores the strict minimum amount of cloth deformer mappings to save on memory usage. Ray Tracing of cloth elements must never be of a different LOD to the one rendered when using this mode.

Mapping to a Min LOD stores additional cloth data deformer mappings to allow Ray Tracing of the cloth elements at the Ray Tracing minimum LOD. When using this mode, Ray Tracing of cloth elements must never be of a different LOD to the one rendered, or to the one set for the Ray Tracing minimum LOD.

Mappings to Any LOD stores all cloth deformer mappings at the expense of memory usage to allow the Ray Tracing of the cloth elements at any higher LOD. Use this mode when the Ray Tracing LOD Bias console variable is in use.



Sampling



Regions

An array of stored regions sampling data, used for implementing uniform functions or accessing stored information.

Skeletal Tree

The Skeleton Tree tab displays the Skeletal Hierarchy of the current Skeleton Asset that you can use to create and edit Sockets and define settings related to Animation Retargeting.



Although the skeleton tree is most relevant to the Skeleton Editor Mode, the Skeletal Mesh Sockets feature is also important when working with the Skeletal Mesh Editor.

Viewport

With the Viewport window you can preview your selected Skeletal Mesh and see provided information about your assets.



For more information about the unique animation centric features of the viewport, refer to the Animation Editors Overview Page.

Preview Scene Settings / Morph Target Previewer

This panel has two tabs, Preview Scene Settings and Morph Target Previewer.

Preview Scene Settings

Preview Scene Settings enable control of the preview settings such as the selected animation and applied Skeletal Meshes, as well as Viewport lighting and Post Process settings.



Morph Target Previewer

With the Morph Target Previewer you can preview edits and modifications made to the Morph Targets associated with your Skeletal Mesh.



Toolbar

Asset Details / Skeleton Tree

Animation Asset Details

Skeletal Tree

Viewport

Details / Preview Scene Settings

Asset Editor

Asset Browser

The Animation Sequence Editor provides access to the various animation-centric assets available for Skeletal Meshes in Unreal Engine. In the Animation Sequence Editor, you can edit and preview animation Sequences, Montages, Curves, and more.

Here is an highlighted overview of the Animation Sequence Editor, showing the following tools and windows:



Toolbar

Asset Details / Skeleton Tree

Viewport

Details / Preview Scene Settings

Asset Editor

Asset Browser

Toolbar



Here is a list of unique buttons found in the Animation Sequence Editor Toolbar and a description of their functionalities.

Name

Icon

Description

Reimport Animation



With this button you can reimport Animations from their original file's location on your computer. If the location is not known or cannot be located, Unreal will prompt you to browse for the file you wish to Reimport.

Apply Compression



You can use this button to apply Animation Compression to your animation to reduce the animations resource demand.

Export Asset



With this button you can export the current animation asset for the current Skeleton either as Animation Data or a Preview Mesh. For more information see, Exporting and Importing FBX Files.

Key



Add a Keyframe of the current pose to the Asset Editor as an additive layer.

Make Static Mesh



Create a new Static Mesh Asset from the current pose displayed by the Mesh.

Edit In Sequencer



Open the current animation in Sequencer. From this drop down you can also toggle the button to open the Animation in Control Rig or Bake the animation to Control Rig.

Asset Details / Skeleton Tree

This window contains two panels by default, the Asset Details panel and the Skeleton Tree panel.

Animation Asset Details



The Animation Asset Details panel is a context-sensitive property editor where you can edit and modify settings pertaining to the selected Animation Sequence and its assets such as, Blend Spaces, Animation Montages and Animation Notifies.

Name

Description

Animation Track Names

Displays the currently selected Animation Track's name.

Interpolation

This property controls the interpolation between key frames of animation.

Linear interpolation will implement linear easing between keyframes, causing abrupt starts and stops when reaching each keyframe.



Step interpolation will implement non-interpolating keyframes, which maintain their value until the next keyframe is reached.



Target Frame Rate

Listed here is the read only target frame rate the animation had been imported or created at.

Number of Sampled Keys

Here you will find a numerical read out of the number of sampled keys the current animation has been imported or created with.

Number of Sampled Frames

Listed is the number of sampled frames the animation has been imported or created with.

Resampled Animation Track Data

A list of bones being manipulated in your animation. Depending on how you export your animation, not all bones will always be animated.

Rate Scale

The speed of the animation playback. 1 is default, lower values are slower, higher values are faster.

Skeleton

Reference to the in use Skeleton Asset. This can be double-clicked to open the Skeleton Editor.

Parent Asset

Lists associated Parent Asset, only when working with Animation Montages and the currently selected AnimMontage is a Child. However, modifications to the current montage will be disabled, apart from assigning unique child behaviors through the Asset Mapping Table. This data will be used to bake out to a normal asset during cooking. Useful for mapping animations to exact timing and displacement of other animations.

Asset Mapping Table

Displays Asset Mapping Table, for use when working with Parent and Child Animation Montages. When a Mapping Table is present double-click to reference the associated Source Asset and Target Asset.

Retargeting Source

Base pose to use when Retargeting an Animation.

Retarget Source Asset

If the Retarget Source property is set to Default (None), then the selected skeletal mesh here, will serve as the base pose for use when retargeting. Transform data will be saved in RetargetSouceAssetReferencePose.

Preview Pose Asset

The default Skeletal Mesh Pose Asset to use when previewing this Skeletal Mesh - this only applies when you open one of the Animation Editor modes using the associated asset.

Asset User Data

Asset User Data is a general array of applied functions that can be attached to animations in order to derive data or perform uniform behaviors. In addition to Animation Sequences this data is shared across multiple asset types such as, Skeletal Meshes and Skeleton Assets, and attach arbitrary user data to these targets.

Allow Frame Stripping

If enabled, this will allow low priority frames of animation to be removed if the export platform requests it. Can be disabled if animation has high frequency movements that are being lost.

Compression Error Threshold Scale

Set a scale for error threshold on compression. This is useful if the animation will be played back at a different applied scale. For example, if the animation will be played on an actor or component that is scaled up by a factor of 10, then set this value to 10.

Bone Compression Settings

The bone compression settings used to compress animation data on bones in this sequence.

Curve Compression Settings

The curve compression settings used to compress Anim Curve data in this sequence.

Do Not Override Compression

For use to prevent an override of the compression scheme when running a CompressAnimations commandlet. Some high frequency animations are too sensitive and shouldn't be changed.

Additive Anim Type

Overview

Animations can be used as absolute or additive. When absolute animations are set to control the same bones, each will compete and influence one another. Additive animations can circumvent this issue by having priority of their respective region so as not to conflict with other animations. Additive Animation

The Additive Animation calculates the delta, or the displacement value, from their starting position of the base animation and the current animation. You can then apply the difference of delta to any base animation with an Additive Animation. With Additive Animations you can create different permutations of animations by applying this delta to different base animations.

Two necessary components are needed to create an additive animation.

The Current Animation is the animation you wish to add to a base animation.

The Base Animation is the foundation animation form which delta can be calculated. Which base animation is selected can change how the delta is extracted.

Additive Animation Type

This decides what kind of additive animation you want to use.

No additive: This animation is not additive and will compete with any other animation data present.

Local Space: This animation is additive and delta is calculated using the local space. This is the most common option for additive animation. Using the local space as reference the additive animation can implement delta, to smoothly incorporate the additive animation data onto the existing location of the properties.

Mesh Space: This animation is additive and delta will be applied in component space. This is required for Aim Offset because aim offset should be applied in component space.

There are many different ways to obtain the base animation pose to which the additive animation can be derived. After selecting which additive animation type, the options are as follows:

Skeleton Reference Pose: will use the current skeleton's reference pose as the base pose.

Selected Animation Scaled: will use a whole animation sequence as a base pose. BasePoseSeq must be set.

Selected Animation Frame: Use one frame of an animation sequence as a base pose. BasePoseSeq and RefFrameIndex must be set (RefFrameIndex will be clamped).

Frame from this Animation: Will use one specified frame of this animation as the base pose.

EnableRootMotion

If enabled, this will allow for extraction of root motion data and transfer it to in-place animation. For more information, see Root Motion.

Root Motion Root Lock

Root Bone will be locked to the following selected position when extracting root motion.

Ref Pose: Use the Reference Pose's Root Bone position.

Anim First Frame: Use the Root Bone position of the animation's first frame.

Zero: Use the Root Bone position on the first frame of the Animation.

Force Root Lock

Enable to force Root Bone Lock even if Root Motion is not Enabled.

Use Normalized Root Motion Scale

If enabled, a normalized scale value for the root motion extracted: FVector(1.0, 1.0, 1.0) will be used.

Animation length

Select the desired animation range, or length to import.

Exported Time: This option imports animation frames based on what is defined at the time of export.

Animated Time: Will import the range of frames that have animation data assigned. Can be useful if the exported range is longer than the actual animation in the FBX file.

Set Range: This will enable manual control to define the Start Frame and End Frame of the imported animation.

Import Meshes in Bone Hierarchy

If checked, meshes nested in bone hierarchies will be imported instead of being converted to bones.

Frame Import Range

If under the Animation Length property above, Set Range is selected, then you can manually set the frame range used during an importation or reimportation of the current animation.

Use Default Sampler Rate

If enabled, samples all animation curves to 30 FPS.

Custom Sample Rate

Sample FBX animation data at the specified sample rate. If set to 0, Unreal will automatically find the best sample rate.

Import Custom Attribute

If one is present, Unreal will import a custom attribute as a curve within the animation.

Delete Existing Custom Attribute Curves

If enabled, all previous custom attribute curves will be deleted when doing a re-import.

Delete Existing Non Curve Custom Attributes

If enabled, all previous non-curve custom attributes will be deleted when doing a re-import.

Import Bone Tracks

By default, Unreal is set to Import bone transform tracks. If disabled, this will discard any bon transform tracks. Useful for curves only animation.

Set Material Curve Type

Set Material Curve Type for all custom attributes that exist.

Material Curve Suffixes

Set Material Curve Type for a custom attribute with the following suffixes. This property is disregarded if Set Material Curve Type is true.

Remove Redundant Keys

If enabled, this will remove redundant keys when importing custom attributes as curves.

Delete Existing Morph Target Curves

If enabled, this will delete existing Morph Targets from the FBX.

Do not import curves with only 0 values

When enabled, Unreal will disregard any curves with a value of zero during Importation. Useful when importing custom attributes or Morph Targets as curves, to avoid adding extra curves to evaluate.

Preserves Local Transform

If enabled, this will import a curve within the animation.

Import Transform

Controllable offset for importation Transform placement. More relevant when working with Skeleton and Skeletal Mesh assets.

Import Rotation

Controllable offset for importation Rotation placement. More relevant when working with Skeleton and Skeletal Mesh assets.

Import Uniform Scale

Controllable Uniform Scale for importation. More relevant when working with Skeleton and Skeletal Mesh assets.

Convert Scene

Convert the scene from FBX coordinate system to UE coordinate system.

Force Front XAxis

Convert the scene from FBX coordinate system to UE coordinate system with front X axis instead of -Y.

Convert Scene Unit

Convert the scene from FBX unit to UE unit (centimeters),

Source File

Viewable file path for currently selected asset.

Per Bone Custom Attribute Data

Custom Attribute Data array for each bone in current Skeleton Asset.

Data Model

Here you can locate a viewable Data Asset containing important animation data for the current animation such as, Bone Animation Tracks and Curve Data, in addition to foundational values like the animations frame rate, sampled frames and keys.

Controller

Here you can locate an instance of the current animation's Data Controller. This asset handles the operation of the Data Model asset found above.

Meta Data

Meta data that can be saved with the asset. You can query available data with the ‘GetMetaData' debug command.

You can also double-click an animation from the Asset Browser panel to open its Asset Details.

Skeletal Tree

Skeleton Tree panel displays the Skeletal Hierarchy of the current Skeleton Asset where you can create and edit skeleton Sockets and define settings related to Animation Retargeting.



Although the Skeleton Tree is accessible in the Animation Sequence Editor, the panel and its contents are more relevant to the Skeleton Editor which you can find by following the link below.

Skeleton Editor

Viewport

The Viewport window is where you can preview playback of animation assets on your selected Skeletal Mesh and provides information about your assets.



To see more information about the Viewport features unique to the Animation Editors, please see the Animation Viewport window.

Details / Preview Scene Settings

The Editor Details panel, similar other Details Panels found in Unreal Engine, is primarily used for modifying options that have been added while working in the Asset Editor. For example, when you select a bone from the Skeleton Tree window, the Details panel will populate with options related to the selected bone.



For more information about The Editor Details Panel, see the Skeleton Editor documentation.

Also located in this section is a tab for the Preview Scene Settings panel which enable the ability to control the preview settings such as selected animation, applied Skeletal Meshes, as well as viewport lighting and Post Process settings.

Asset Editor

The Asset Editor is a contextual window that will change its interface and features based on the type of animation asset opened. You can playback and modify Blend Spaces, Animation Montages, and more.



Here you will find links to the various animation assets in Unreal Engine. Each page contain descriptions of the asset type as well as an explanation of the unique Asset Editor layout and its properties.

Animation Sequence

Pose Asset

Anim Blueprint

Anim Composite

Anim Montage

Blend Space

Blend Space 1D

Aim Offset

Aim Offset 1D

Asset Browser

Similar to Content Browser the Asset Browser is where you can view and filter animation assets associated with the current Skeleton Asset.



With the forward and backward buttons, you can navigate between previously selected animations.

Here you can toggle the Other Developers filter to view assets located in other developers folders. For use on shared server team based projects.

With the settings button you can access the Asset Browser's many settings, such as to toggle View Options such as the Advanced Details column, to view more advanced information about the listed assets.

Consistent color coding between the Asset Browser and the Content Browser is applied to each type of animation asset for easier distinction between asset types.

Animation assets can be opened in the Animation Sequence Editor, or the Content Browser from the Asset Browser by double-clicking the desired asset. Depending on the asset opened, the Asset Editor will populate with tools and properties relevant to the asset type automatically.

Before opening an asset you can hover your cursor over the asset to view advanced details.



Right-clicking an asset will open a context menu, with options to Save the asset, Open the asset in a new window, or Browse for the File Path in a File Explorer window on your computer.

Animation Blueprint Creation

Assigning to Characters

Working with Animation Blueprints

Animation Blueprints are specialized Blueprints that control the animation of a Skeletal Mesh during simulation or gameplay. Graphs are edited inside of the Animation Blueprint Editor, where you can blend animation, control the bones of a Skeleton, or create logic that will define the final animation pose for a Skeletal Mesh to use per frame.

This document provides an overview of how to create an Animation Blueprint, its editor, and its primary features.

Your project contains a Skeletal Mesh.

Animation Blueprint Creation

You can create Animation Blueprints in the following ways:

In the Content Browser, click Add (+), then select Animation > Animation Blueprint. You will then be prompted to specify which Skeleton to target for the Animation Blueprint. Select one and click Create.



For this creation method, you can optionally specify a Template Animation Blueprint, and Parent Class, if you are wanting to create a child Blueprint. For more information about templates, visit the Animation Blueprint Linking page.

Animation Blueprints can also be created by right-clicking on a Skeletal Mesh Asset in the Content Browser and selecting Create > Anim Blueprint.



Once created, double-click your new Animation Blueprint to open it in the Animation Blueprint Editor. To learn more about the interface, toolbar, and sections of this editor, refer to the Animation Blueprint Editor page.



An overview of the Animation Blueprint Editor and its user interface.

An overview of the Animation Blueprint Editor and its user interface.

Assigning to Characters

Animation Blueprints on their own will not affect your characters until you assign them. Typically this is done on the Skeletal Mesh of your character, regardless if it is referenced in a level or as a component in Blueprints.

To assign your Animation Blueprint, select your Skeletal Mesh and set the following properties:

Set Animation Mode to Use Animation Blueprint.

Set Anim Class to your Animation Blueprint asset.



Working with Animation Blueprints

There are several features and workflows available to you when using Animation Blueprints. From creating animation logic using the AnimGraph, to using Linked Anim Instances, Animation Blueprints provide a powerful suite of tools for you.

Reference the following pages to learn how to create robust Animation Blueprint logic for your characters.



An overview of the Animation Blueprint Editor and its user interface.

An overview of the Animation Blueprint Editor and its user interface.



Edit, blend, and manipulate poses on Skeletal Meshes using various graphs in Animation Blueprints.

Edit, blend, and manipulate poses on Skeletal Meshes using various graphs in Animation Blueprints.



Create logic-based branching animation by using State Machines.

Create logic-based branching animation by using State Machines.



Descriptions of the various animation nodes available for use in Animation Blueprints.

Descriptions of the various animation nodes available for use in Animation Blueprints.



Insert entry-points within your Anim Graph to play animation from using Slots.

Insert entry-points within your Anim Graph to play animation from using Slots.



Synchronize the cycles of animations with different lengths using Sync Groups.

Synchronize the cycles of animations with different lengths using Sync Groups.



Modularize your Animation Blueprint logic by using Animation Blueprint Linking and Templates.

Modularize your Animation Blueprint logic by using Animation Blueprint Linking and Templates.

Toolbar

Graph

Anim Preview Editor

The Animation Blueprint Editor shares similar functionality to the Blueprint Editor, but contains different features, tools, and windows to aid in character animation scripting.

This document provides an overview of the Animation Blueprint Editor interface.

You have created an Animation Blueprint and opened it.

You have a basic understanding of Blueprint Visual Scripting, from which the Animation Blueprint Editor derives much of its interface and behavior.

Upon opening an Animation Blueprint, the following interface will be displayed:



Toolbar, which contains buttons for Animation Blueprint management and editor type switching.

Viewport, where you can preview the behavior of your Animation Blueprint logic on your character. For more information, refer to the Viewport section of the Animation Editors page.

My Blueprint, similarly found in the Blueprint Editor, contains a list of your graphs, functions, variables and other related properties within the Animation Blueprint. Also contained here is the Pose Watch Manager panel, refer to the Animation Shortcuts and Tips page for more information.

Graph, which displays the different graphs for visual scripting in your Animation Blueprint.

Details, which displays properties for the selected item.

Anim Preview Editor, where you can make changes to your variables and class defaults. Docked on a separate tab is the Asset Browser where you can view and open the animation assets that are associated with this Skeleton. Visit the Asset Editor section of the Animation Sequence Editor page for more information.

Toolbar

The Toolbar is where you compile your Blueprints, Save, locate the Animation Blueprint asset in the Content Browser, and define Class Settings and Class Defaults settings. Several buttons and tools here are common for most Animation Editors, such as Preview Mesh. You can learn more about these common menus from the Animation Editors Toolbar Section.



The Animation Blueprint Editor Toolbar provides the following buttons and menus:

Name

Icon

Description

Compile



Compiles this Animation Blueprint. This icon will change depending on the compilation state of the Blueprint. In most cases, making changes to any Graph will require you to recompile.

Clicking the Options menu will reveal additional behaviors when compiling. Save On Compile can be used to automatically save the Animation Blueprint upon compiling. Jump to Error Node can also be enabled to automatically frame the graph node preventing a successful compile.



Diff



If you are using a Source Control Package in Unreal Engine, then this dropdown menu can be used to compare your current Animation Blueprint against previous revisions.

Find



Opens a search panel where you can search for references to functions, events, variables, nodes, and pins within all graphs. You can also press Ctrl + F. Additionally, pressing Ctrl + Shift + F will open a search window where you can search through all Blueprints in your project, Animation or otherwise.

Hide Unrelated



Enabling this will fade out any nodes not currently selected or directly linked to your selected node in the Graph. You can also enable Lock Node State from the options menu, which will maintain the current hidden state of all nodes, regardless of your selection afterwards.



Class Settings



Clicking this exposes several Blueprint class settings in the Details panel. Most of these properties are general Blueprint class settings. However the following settings are specific to Animation Blueprints.

Target Skeleton: Specifies the Skeleton Asset to use for this Animation Blueprint.

Use Multi Threaded Animation Update: Enables the Animation Blueprint to update its native update, blend tree, montages, and asset players on a worker thread. The compiler will attempt to pick up any issues that may occur with the threaded update.

Warn About Blueprint Usage: Enabling this causes warnings to occur whenever a call into the Blueprint is made from the AnimGraph. This can help locate optimizations that need to be made.

Class Defaults



Clicking this exposes your Blueprint's variables in the Details panel, including default variables from the Blueprint class.

Root Motion Mode: Controls how root motion is applied within this Animation Blueprint. You can select the following options:

No Root Motion Extraction, which causes no root motion to be extracted or applied.

Ignore Root Motion, which extracts root motion, but does not apply it.

Root Motion from Everything, which enables root motion from all animation sources. Typically you should not enable this in multiplayer or network setups.

Root Motion from Montages Only, which causes root motion to only apply from Animation Montages. This is a more suitable option for multiplayer or network setups.

Receive Notifies from Linked Instances: Whether to process notifies from any linked anim instances.

Propagate Notifies to Linked Instances: Whether to propagate notifies to any linked anim instances.

Use Main Instance Montage Evaluation Data: Enabling this causes linked instances to use the main instances' montage data, synchronizing all instances when the main instance plays a montage.

Play / Simulate



These buttons can be used as a way to start playing or simulating the Animation Blueprint, using the In-Editor Testing framework.

Debug Object



This drop-down menu links the Animation Blueprint viewport to an active animation instance in a simulating or playing session. This previews the current animation from that session in the Control Rig viewport. Additionally, your graph nodes will also respond to any inputs and changes that occur in session, so that you can debug your graph and character state.

Animation Editors / Blueprint



When creating an Animation Blueprint for a Skeleton, this button will appear as a selectable editor type within the Animation Editor Modes region. Clicking here opens the Animation Blueprint. You can also click the Options dropdown menu next to this button to select a specific Blueprint if more than one Animation Blueprint uses this Skeleton.

Graph

The Graph panel is where you create the logic that controls your character during gameplay. There are three main types of graphs, each with different interfaces:

The Event Graph, where you construct Blueprint-based logic to define node properties and variables which inform your other graph areas.



The Anim Graph, where you construct pose-based logic which evaluates the final pose of the Skeletal Mesh for the current frame.



State Machines, where you construct state-based logic, typically used for locomotion.



Visit the Graphing in Animation Blueprints and State Machines pages for more information about the different graph types and graphing within Animation Blueprints.



Edit, blend, and manipulate poses on Skeletal Meshes using various graphs in Animation Blueprints.

Edit, blend, and manipulate poses on Skeletal Meshes using various graphs in Animation Blueprints.



Create logic-based branching animation by using State Machines.

Create logic-based branching animation by using State Machines.

Anim Preview Editor

The Anim Preview Editor is where you can make changes to your variables (including Class Defaults), which will update the Skeletal Mesh in the viewport.



Clicking Edit Preview changes the behavior of this panel so that you are only making temporary edits to your variables. This can be useful if you only want to preview different variable states, without making destructive edits. When you make changes, a prompt will appear where you can choose to apply these changes to the default.



Anim Graph

Creating and Connecting Nodes

Execution Flow and Information

Node Functions

Property Access

CPU Thread Usage and Performance

Event Graph

Animation Events

Thread Safe Update Animation

The primary method of using Animation Blueprints is by creating logic in the Anim Graph and Event Graph. This logic then defines the pose behavior, variables, and other properties of the Blueprint. These graphs work together to provide the final output pose of the character at any given frame.

This document provides an overview of the Anim Graph, Event Graph, and the graphing experience in Animation Blueprints.

You have created an Animation Blueprint and opened it.

You have a basic understanding of Blueprint Visual Scripting, from which the Animation Blueprints derives its interface and behavior.

Anim Graph

The AnimGraph is where you create animation-specific logic for your character. Typically, this includes creating nodes which control blending, transforming bones, locomotion, and other similar animation effects. Inside the AnimGraph, you can use values calculated from the EventGraph, or Functions, and then connect those variables as inputs for your AnimGraph nodes, such as Blend Spaces. The combined effects of your nodes and their values are connected to the Output Pose, which is where the final pose of the character is defined for every frame.



For a basic example, you can create a Sequence Player node in the AnimGraph, which references an Animation Sequence. Connect this node to the Output Pose node, then click Compile in the Toolbar. You should now see your animation play indefinitely, as the Sequence Player continuously plays the animation.



Creating and Connecting Nodes

Similar to Blueprints, nodes are created by right-clicking in the graph and selecting a node.



If you create a node that outputs Pose information, then this node can be connected to other pose pins, such as on the Output Pose node. Typically, creating and connecting nodes will require you to recompile the Blueprint.



There are several node types you can create in the AnimGraph. To learn more about them, refer to the Animation Node Reference page.



Descriptions of the various animation nodes available for use in Animation Blueprints.

Descriptions of the various animation nodes available for use in Animation Blueprints.

Execution Flow and Information

Pose connections, which are denoted with the Pose icon, have their execution shown as pulsing links along their connection lines. For regular graphs, such as the EventGraph of a Blueprint, this flow is visualized during play as it is dependent on the firing of events. The AnimGraph is different in that it displays the flow of execution at all times since it is not event-based and is evaluated each frame.



In the AnimGraph, the flow of execution represents poses being passed from one node to another. Some nodes, such as Blends, have multiple inputs and make a decision internally on which input is currently part of the flow of execution. This determination is usually dependent on some external input, like the value passed to a data pin. In this example, the Alpha value on a Blend node is being set to either 0 or 1, which enables or disables the evaluation of each incoming pose.



Poses and nodes can also contain several internal attributes, which are represented by parallel execution lines between the connected pins and icons on the node. This information conveys additional attributes that are being sent along with the animation pose.



The list of attributes are as follows:

Attribute

Icon

Description

Curves



Passes Anim Curve data.

Attributes



Passes Animation Attribute data.

Sync



Passes Sync Group data.

Root Motion



Passes Root Motion data.

Inertial Blending



Passes Inertialization data. This indicator only appears when the Inertialization node is requested, typically when a blend occurs.

Node Functions

Alongside the normal node execution in the AnimGraph, you can also specify functions to call during a node's execution steps. This makes it possible to create more manageable logic that is organized within its relevant node and function. Additionally, this saves on CPU resources so that these events are only called when a node is active

These function properties can be accessed by selecting any animation node in the AnimGraph and locating the Functions property category in the Details panel.



The following Function properties are available:

Function Type

Description

On Initial Update

This Function will execute only once during gameplay or simulation. It executes the first time the node becomes relevant, and before On Become Relevant. It does not re-execute if the node becomes relevant repeatedly.

On Become Relevant

This Function executes the first time the node becomes relevant, but after On Initial Update. It will also re-execute if the node becomes relevant repeatedly, such as if it were to be blended on, then off, then on again.

On Update

This Function executes continuously every tick as long as the node is relevant. It starts executing after On Become Relevant executes.

The concept of relevance in the AnimGraph refers to if a node is being evaluated or not. In cases when nodes are not being evaluated, such as when using blend nodes or state machines, some nodes may be completely inactive. When this occurs, the node is not relevant. Only nodes currently contributing to the Output Pose are considered relevant.

In this example, the Aim Offset node is not relevant because the Blend node is blended completely to input A.



To add a new Function, click the dropdown menu for your chosen property and select Create Binding. This will create a new function for your Animation Blueprint and bind it to the Function property.



When you create a function this way, it will automatically create input pins which are used to link the function to the node it's associated with. These pins are optional in some cases, but are required if you are using the function to read the current state of the node.

Context: Allows the node to pass data through that is relevant to the node, such as Delta Time, or Inertialization requests.

Node: Allows the node to pass itself through this pin. Typically you will want to convert this pin to a specific node type using a Convert function.



When a function is assigned to a node, this is indicated by the function name being visible on the node. In this example, the Aim Offset logic, for getting a character's rotation and setting the pitch and yaw values, is all contained within the function. This logic executes only while this node is being updated, rather than permanently as it would if it was in the Event Graph, reducing performance costs.



Property Access

In order to expedite getting and setting properties, you can use the property access feature, which contains a variety of automated functions. Property access is useful for reducing the instances of getting properties, redundant connections, and overall graph complexity. It also provides a way to automatically provide gameplay data to your animation graphs in a thread-safe way.

There are two main ways to use this feature:

To create a property access node, right-click in the AnimGraph and select Property Access from the Variables category.



Once added, you will need to bind it to a Get function. Click the drop-down menu on the node and select the Get function you want. You can also navigate beyond a single Get, and locate a more specific property. In this example, a Get property path is created from TryGetPawnOwner, to GetActorLocation, to a specific axis.



Once bound, you can use the property access node to provide property logic in your graph.



For simpler logic, you can also embed property access directly onto a property pin. Select the node, locate the pin property in the Details panel, and click the dropdown menu for that property. From here you can select a similar Get function chain to map to this node's property.



Custom functions can also be created to output values that require more complex logic. In order for the property value to output correctly, the following must be done on the function:

The function must contain a Return Node with the final resulting property connected to a ReturnValue output pin.

Pure must be enabled from the function's Details panel.



Once created and properly set up, these functions can be added from the Property Access menu.



The property access menu contains the following selections and properties:



Name

Description

Call Site

The Call Site controls which CPU thread to execute the property access on. You can select the following options:

Automatic, which will automatically determine the call site for this property access based on context and thread safety. You should leave this as the selection in most cases.

Thread Safe, which will execute this property access on the Worker Thread.

Game Thread (Pre-Event Graph), which will execute this property access on the Game Thread, before the Event Graph executes.

Game Thread (Post-Event Graph), which will execute this property access on the Game Thread, after the Event Graph executes.

Worker Thread (Pre-Event Graph), which will execute this property access on the Worker Thread, before the Event Graph executes.

Worker Thread (Post-Event Graph), which will execute this property access on the Worker Thread, after the Event Graph executes.

Functions

The list of functions you can bind to the property access.

Properties

The list of variables in your Animation Blueprint, as you can also bind property access to variables.

CPU Thread Usage and Performance

When creating complex AnimGraph logic, it may become necessary to consider performance and costs of the graph logic. By default, the AnimGraph executes on a separate CPU thread from the EventGraph, which is referred to as the "Worker Thread". The "Game Thread" is the CPU thread where the Event Graph of the Animation Blueprint and all other Blueprints execute instead.

This behavior significantly improves the performance of games on multi-core machines by allowing animation work to complete in parallel with other updates.

The compiler will also warn if unsafe operations are performed in the AnimGraph. Safe operations generally are:

Using most AnimGraph nodes.

Directly accessing member variables of your Animation Blueprint (including members of structures).

Calling Blueprint pure functions that don't modify state (such as most math functions).

Although we do not recommend it, you can disable this behavior so that the AnimGraph executes on the game thread by disabling Use Multi Threaded Animation Update from the Class Settings Details panel.



In addition to the AnimGraph, Functions can also optionally execute on the Worker Thread. Then, when using Functions in conjunction with Node Functions, you can offload your entire Animation Blueprint graph to run exclusively on the Worker Thread, further improving performance.

Although we do not recommend it, you can disable this behavior so that Functions execute on the game thread by disabling Thread Safe from your selected Function's Details panel.



Event Graph

Every Animation Blueprint has a single EventGraph, which is a standard Graph that uses a collection of special animation-related events to initiate sequences of nodes. The most common use of the EventGraph is to update values or properties used by AnimGraph nodes.

Animation Events

The EventGraph is used by adding one or more events to act as entry points and then connecting Functions, Flow Control nodes, and Variables to perform the desired actions.

With the CPU Threading and Node Function features offered in the AnimGraph, it is recommended to use the EventGraph as little as possible. This is because the EventGraph executes on the primary game thread, along with most other Blueprint logic in your project. Therefore, having a complex EventGraph in your Animation Blueprint will reduce overall performance. Most of these events have thread-safe counterparts, and should be used instead if possible.

Event Name

Node image

Description

Begin Play



Similar to Event Begin Play in Blueprint Visual Scripting, this event is executed at the start of the game or simulation, but before the Begin Play event of an actor.

As a thread-safe alternative, you can instead use the On Initial Update Node Function for the relevant node.

Initialize Animation



This event is executed once when the Animation Blueprint instance is created to perform initialization operations. It executes as soon as the Animation Blueprint is created, before the execution of an actor's Construction Script and Begin Play.

Linked Animation Layers Initialized



This event executes once, after Initialize Animation, and after any linked animation layers are initialized.

As a thread-safe alternative, you can instead use the On Initial Update Node Function for the relevant linked animation layer node.

Post Evaluate Animation



Executes every frame, but after the animation finishes evaluating and has applied the pose for the current frame. This is useful to reset values, or to get the accurate transform of a bone.

Update Animation



Executes every frame, allowing the Animation Blueprint to perform calculations and updates to any values it needs. This event is the entry point into the update loop of the EventGraph. The time elapsed since the last update is available from the Delta Time X pin so time-dependent interpolations or incremental updates can be performed.

As a thread-safe alternative, you can instead use the Blueprint Thread Safe Update Animation Function.

AnimNotify



Executes when a Skeleton Notify is triggered.

Thread Safe Update Animation

To improve the performance of your Animation Blueprint, you can use a thread-safe alternative to the Update Animation Event, called Blueprint Thread Safe Update Animation. This alternative is a Function that you must override in order to add it to the Blueprint. It is useful because the Event Graph Update Animation event always runs on the game thread, so it cannot take advantage of multithreading to improve overall framerate

To do this, click the Override dropdown menu in the Functions category of the My Blueprint panel, then select Blueprint Thread Safe Update Animation.



It is now added to your list of Functions. Opening it will reveal the function entry point, as well as a Delta Time pin, similar to the Delta Time X pin on the EventGraph Update Animation node. You can now create the same Update Animation logic in this Function as you would in the EventGraph, with this function executing on the Worker Thread instead of the Game Thread.



Animation Blueprints

Programming and Scripting

Blueprints Visual Scripting

Anatomy of an Animation Node

Node Hierarchies

Runtime Node Component

Pose Inputs

Properties and Data Inputs

Optional Pins

Editor Node Component

Title

Tooltip

Context Menu

Derived Native Getters

Animation nodes are used inside of Anim Blueprints to perform operations, such as working with Animation Assets, blending Animation Poses, and manipulating a Skeletal Mesh's bones. A suite of animation nodes are included in Unreal Engine, but you can also create custom nodes to fit the needs of your project.



To open an Animation Blueprint in your project's source code editing IDE, open the AnimBP in the AnimBP Eitor, and click the Parent Class link in the top-left of the editor window.



Anatomy of an Animation Node

The two essential components of any Animation nodes are:

A runtime struct that performs the actual operations to generate an output pose.

An editor-time container class that handles visual aspects and functionality of the node within the graph, such as node titles and the context menu.

In order to add a new animation node, both of these must be created.

Node Hierarchies

It is possible to create a hierarchy of nodes, but any non-abstract editor-time classes should contain exactly one runtime node.

Do not add additional nodes when deriving unless the parent was abstract and did not contain one.

See the UAnimGraphNode_BlendListBase node family for examples.



Runtime Node Component

The runtime struct is derived from FAnimNode_Base and is responsible for initialization, updating, and performing operations on one or more input poses to generate the desired output pose. It also declares any input pose links and any properties needed by the node to perform the desired operation.

Pose Inputs

In the runtime node, pose inputs are exposed by creating properties of the type FPoseLink or FComponentSpacePoseLink. FPoseLink is used when working with poses in local space, such as blending animations. FComponentSpacePoseLink is used when working with poses in component space, such as applying skeletal controllers.

An Anim BP node can have a single pose input. The following are examples of animation nodes using a single pose input.

Node Classification

Code Example

Image

Local Space

Local Space pose input code implementation:



Component Space

Component Space pose input code implementation:



Component Space pose input pins are blue.

An Anim BP node can also have more than one pose input pin for nodes that blend between multiple animations:

Node Classification

Code Example

Image

Blending Node

Base pose and Additive pose input pin code implementation:



Once implemented into your custom Anim BP node, each of these properties will display a pose link input pin.

Properties of this type are always exposed as input pins. They cannot be optionally hidden or used only as editable properties in the Details panel.

Properties and Data Inputs

You can assign any number of properties to an AnimBP that are used to perform the operations of the node. Similar to other properties, you can declare custom properties using the UPROPERTY macro.

Node Clasifcation

Code Example

Image

Alpha Property Implementation

Alpha property pin code implementation:



Using special metadata keys, animation node properties can be exposed as data inputs pins to allow values to be passed to the node. The following are metadata keys you can use when create custom AnimBP nodes for your project.

Metadata Key

Description

NeverAsPin

This key will hide property as a data pin in the AnimGraph and will only be editable in the node's Details panel.

PinHiddenByDefault

You can use this key to hide the property as a pin, by default. The property can then be exposed as a data pin in the AnimGraph. See the Optional Pins section for more information about exposing hidden pins in the AnimGraph.

PinShownByDefault

With this key you can expose a property as a data pin in the AnimGraph by default.

AlwaysAsPin

This key will always expose the property as a data point in the AnimGraph.

Optional Pins

For properties that are hidden, but exposable in the AnimGraph, using keys like PinHiddenByDefault or PinShownByDefault, you can expose properties in the node's Details panel, by navigating to the property and toggling Expose As Pin from the dropdown menu.



You can also hide property pins from the AnimGraph by right-clicking the pin you want to hide, navigating to the Binding option and toggling Expose As Pin from the dropdown menu.



Editor Node Component

The editor class is derived from UAnimGraphNode_Base and is responsible for visual elements like the node's title or adding context menu actions.

The editor-time class should contain an instance of your runtime node exposed as editable.

Title



You can override the appearance of an Animation node's title elements in the AnimGraph, such as the text and background color, using the GetNodeTitle and GetNodeTitleColor functions.

For example, the UAnimGraphNode_ApplyAdditive node uses a gray background and displays "Apply Additive":

Tooltip



When creating custom animation nodes you can create custom tooltips that are viewable in the AnimGraph by overriding the GetTooltip function:

Context Menu

When creating your own custom animation nodes, you can add node-specific options to the node's context menu, which is accessible by right-clicking the node in the AnimGraph. You can add context menu options to your custom animation nodes using the GetContextMenuActions function, which also is a function of all Blueprint nodes in Unreal Engine.



For example, the UAnimGraphNode_LayeredBoneBlend node adds context-menu options for adding a Add Blend Pin or Remove Blend Pin:

Derived Native Getters

You can create your own UAnimInstance derived class to achieve performance improvements . You can add new getters if there is a need for improved performance. You can set up a new getter following the steps below:

The getter functions must be tagged as UFUNCTIONS.

They must be BlueprintPure.

They must include the metadata AnimGetter="True".

They must also define some specifically named parameters (this is also explained above the base anim getter functions in AnimInstance.h). That list of parameters includes :

Parameter

Description

int32 AssetPlayerIndex

The getter acts on an asset player and an entry will be added to the editor per asset player available.

int32 MachineIndex

The getter acts on a state machine, an entry will be added per state machine.

int32 StateIndex

This also requires MachineIndex. The getter acts on a state, an entry will be added per state.

int32 TransitionIndex

This also requires MachineIndex. The getter acts on a transition, an entry will be added per transition.

You can also use helper functions to get the actual nodes in your getters. These exist on the UAnimInstance:

Function

Description

GetStateMachineInstance(int32 MachineIndex)

Gets the baked state machine instance.

GetCheckedNodeFromIndex(int32 NodeIdx)

Gets a node from an index, asserts if invalid.

GetNodeFromIndex(int32 NodeIdx)

As above, can return nullptr.

GetRelevantAssetPlayerFromState(int32 MachineIndex, int32 StateIndex)

Gets the highest weighted asset player in a state.

Creation and Setup

Entry Point

States

Creating States

Editing States

State Properties

Transitions

Conduits

State Alias

Alias Example

State Machine Properties

State Machines are modular systems you can build in Animation Blueprints in order to define certain animations that can play, and when they are allowed to play. Primarily, this type of system is used to correlate animations to movement states on your characters, such as idling, walking, running, and jumping. With State Machines, you will be able to create states, define animations to play in those states, and create various types of transitions to control when to switch to other states. This makes it easier to create complex animation blending without having to use an overly complicated Anim Graph.

This document provides an overview of how to create and use State Machines, states, and transitions in Animation Blueprints.

State Machines are created within Animation Blueprints, therefore you should have an understanding of how to use Animation Blueprints and their interface.

Your project contains a character with a movement component so that you can build states that react to input. The Third Person Template can be used if you do not have one.

Creation and Setup

State Machines are created within the Anim Graph. To create one, right-click in the Anim Graph and select State Machines > Add New State Machine. Connect it to the Output Pose.



State Machines are subgraphs within the Anim Graph, therefore you can see the State Machine graph within the My Blueprint panel. Double-click it to open the State Machine.



You can also double-click the State Machine node in the Anim Graph to open it.

Entry Point

All State Machines begin with an entry point, which is typically used to define the default state. In most common locomotion setups, this would be the character idle state.

To create the default state, click and drag the entry output pin and release the mouse, which will expose the context menu. Select Add State. This will create the new state and connect it to the entry output, making this state active by default.



States

States are organized sub-sections within a State Machine that can transition to and from each other regularly. States themselves contain their own Anim Graph layer, and can contain any kind of animation logic. For example, an idle state may just contain a character's idle animation, whereas a weapon state may contain additional logic for shooting and aiming. Whatever logic is used, the purpose of a state is to produce a final animation or pose unique to that state.

Creating States

States can be created in the following ways:

Right-click in the State Machine graph and select Add State.



Click and drag off of the border of a state (or entry output), then release the mouse and select Add State. This will also connect it to the previous state with a transition.



Drag an Animation Asset into the State Machine graph from the Content Browser or Asset Browser. This also adds the animation to the state and connects it to its Output Pose.



State Machines can have as many states as needed, and they also display as subgraphs under the State Machine.



Editing States

To view the internal operation of a state, you can either double-click it in the My Blueprint panel, or double-click the node itself in the State Machine graph. This will open the state.



Like Anim Graphs, states contain a final Output Pose node to connect your animation logic to. When the state is active, this logic will execute. When a different state is active, this logic will no longer execute. In this idle state example, an idle animation is connected to the Output Pose. When this state is active, this resulting animation will play.



State Properties

When a state is selected, you can view and edit the following properties in the Details panel.



Name

Description

Name

The name of the selected state.

Entered State Event (Custom Blueprint Event)

Creates a Skeleton Notify with the name used in the Custom Blueprint Event field. This notify will execute when the state becomes active and starts to transition. As with normal Skeleton Notifies, you can access the event by creating it in the Animation Blueprint's Event Graph.



Left State Event (Custom Blueprint Event)

Creates a Skeleton Notify with the name used in the Custom Blueprint Event field. This notify will execute when starting to blend to another state.

Fully Blended State Event (Custom Blueprint Event)

Creates a Skeleton Notify with the name used in the Custom Blueprint Event field. This notify will execute when this state is fully blended to.

Always Reset on Entry

Enabling this will cause all animations within this state to re-initialize to their default values. In most cases, this means the following:

Sequence players will restart at the animation start time.

Properties will initialize at their default values.

If disabled, then all animations and their properties will maintain their previous playback state and other properties upon leaving and then returning to this state. In other words, the animations will "pick up where they left off".

Transitions

To control which states can blend to another, you can create transitions, which are links between states that define the structure of your State Machine.



To create a transition, drag from a state border to another state. In this example the Idle state is connected bi-directionally to the Run state, which is a common setup for basic locomotion State Machines. Transitions are single-direction, so if two states are intended to transition back and forth, you need to create a transition for each direction.



To learn more about transitions and transition rules, refer to the Transitions page.



Blend between states in your State Machine using Transitions.

Blend between states in your State Machine using Transitions.

Conduits

While ordinary transitions can be used for 1-to-1 transitions between states, conduits can be used to create 1-to-many, many-to-1, or many-to-many transitions. Because of this, conduits serve as a more advanced and shareable transition resource.

To create a conduit, right-click in the State Machine graph and select Add Conduit.



There are several ways you can use conduits. One example might be to use them to diverge your State Machine's entry point. You can then use transitions from the conduit to select which state should start as the default. This example can be useful when re-initializing a State Machine if you were overwriting it with another animation, such as an Animation Montage.



The above example requires Allow Conduit Entry States to be enabled in the State Machine Details panel.

Conduits contain their own transition rules, which can be located by double-clicking on the conduit node, or by opening the conduit graph from the My Blueprint panel. By default, conduit transitions rules will return false. In most cases you may just want to enable Can Enter Transition, and create transition rule logic on the individual transitions in and out of the conduit.



Refer to the Transition Rules page for more information on transitions and transition rules.

State Alias

As you build more complicated State Machines with many states and ways to transition between them, you may want to use state aliases to improve your graph. State aliases are shortcut-type nodes you can add to your State Machine to reduce line clutter, consolidate transitions, and improve the readability of your graph.





State Machine with no alias usage

State Machine using aliases

To create a state alias, right-click in the State Machine graph and select Add State Alias.



State aliases work by defining which states can transition into it, then connecting the alias to other states using the normal transition method. Click the state alias node, and in the Details panel you can observe the following:

Each state within your State Machine is listed as a property. If you enable that state, it causes that state to adopt the transitions and rules that you make from the alias to other states. In other words, this is where you define which states are "coming into" the alias.

Enabling Global Alias makes all states come into the alias. Although you can enable all listed states which causes the same behavior, enabling Global Alias will also include any new states created later.

Global Alias is best used in a limited way with single-frame input and finite-duration states, such as interaction, attacks, or other similar animations. Using Global Alias for states with indefinite lengths may require additional complicated logic between all other state transitions to ensure your other states are not always transitioning to it.



Alias Example

In this example, a somewhat simple State Machine requires the land and locomotion states to transition to both the jump and fall loop states. Four transitions in total are being used, each with their own transition rules.



State aliases can be used to clean up this graph. To achieve the same effect, you can do the following:

Create a state alias and transition it to both the fall loop and jump states.

Select the state alias and enable locomotion and land.



Because state aliases consolidate transitions from all enabled states, using state aliases means that these states share the same transition rules and properties. If you want certain transitions to have different rules, blend durations, or other properties, then you should create unique transitions for those states instead.

State Machine Properties

State Machines contain the following properties in the Details panel.



Name

Description

Name

The name of the selected State Machine.

Max Transitions Per Frame

This number defines how many transitions or decisions can occur in a single frame or tick. If your state machine has many states and transitions where more than one transition can be true at a given time, you may want to set this number to 1. This makes it so that only one decision can be made at a time, preventing competing decisions and transitions.

Skip First Update Transition

When a State Machine becomes relevant, it initializes into the default state connected to the Entry point. At that point, normal State Machine processes begin and any valid transitions are taken.

If this property is enabled, then any non-default states that are valid transition targets upon initialization will be immediately transitioned to.

If disabled, then any valid transition targets will blend normally.

This is to allow for any non-default states to behave as if they were the default state, if that is desired behavior. For example, if you have a simple idle and run State Machine, where idle is the default state and can transition to run. If Skip First Update Transition is enabled, and if the run transition rule is true at the time of the State Machine's initialization, then run will be initialized and blended to 100% immediately.

Reinitialize on Becoming Relevant

Enabling this reinitializes the first entered state when the State Machine becomes relevant. This setting operates similarly to the per-state property Always Reset on Entry, but only resets the first initialized state entered.

Create Notify Meta Data

When using Animation Notify Functions in your transition rules, enabling this allows for all relevant data to be sent to these notify functions. If this is disabled, then none of the notify functions will work.

Allow Conduit Entry States

Enabling this allows conduits to be used as entry states, allowing for variable default states depending on the conduit's transition rules.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

State Machines

Transition Setup

Transition Rules

Transition Functions

Animation Notify Functions

Transition Interrupt

Transition Blend Types

Standard Blend

Inertialization

Custom

Transition Properties

Transition Setup

To control which states can blend to another, you can create transitions, which are links between states that define the structure of your State Machine.



To create a transition, drag from a state border to another state. In this example the Idle state is connected bi-directionally to the Run state, which is a common setup for basic locomotion State Machines. Transitions are single-direction, so if two states are intended to transition back and forth, you need to create a transition for each direction.



Transition Rules

While transitions control the structure of inter-state blending, transition rules control when a state can transition. In other words, it is not enough to simply define a transition, you must also define how and when the transition happens.

Transition rules are automatically created when you create a transition. Like states, you can see and access them from either the My Blueprint panel, or by double clicking the transition icon in the State Machine graph.



Within transition rules, you can create any variety of blueprint logic for checking and comparing, all with the purpose of outputting a boolean (true or false) value. A true value is used to determine whether the state can transition to the next state.

For example, when transitioning from idle to run, and then back to idle, the logic might look like this. In this example, a bool variable is being used to provide the transition rule. When returning to the default state, the inverse of the bool is used.



Transition rules are typically informed by the movement component and other character variables. To learn more about how to get common properties for a controllable character, refer to the How to Get Animation Variables page.

Once your variables are correctly set up with the intended logic, meeting the conditions of those variables during gameplay causes the transition to occur.



Transition Functions

Within the transition rule graph, you can use the following specialized transition-only functions to augment your logic:

Name

Image

Description

Current State Time



Gets the current elapsed time (in seconds) of any currently active state within this State Machine. This output provides information similar to the activity indicator in State Machines.



Get Current State Name



Gets the name of the currently active state within this State Machine.

Get Relevant Anim Time



Gets the current elapsed time (in seconds) of the most relevant animation within the state this transition is going to.

Because states can potentially have multiple animations with equal relevance, you can disable those animations from being checked and used in relevant-related functions. To do this, open the state graph, select the animation nodes you want to exclude (sequence players, blend spaces, aim offsets, or similar), and enable Ignore for Relevancy Test from the Details panel.



Current Time



Gets the current elapsed time (in seconds) of an animation from the preceding state. This function is useful if you want to reference a specific animation directly, rather than by relevance.

Get Relevant Anim Time Remaining



Gets the current time remaining (in seconds) of the most relevant animation within the state this transition is going to.

Time Remaining



Gets the current time remaining (in seconds) of an animation within the state this transition is going to. This function is useful if you want to reference a specific animation directly, rather than by relevance.

Animation Notify Functions

There are also several Animation Notify functions that you can use within the transition graph. You can add these functions by right-clicking in the transition graph and locating Was Anim Notify… functions.



Name

Description

Was Anim Notify Name Triggered…

Returns true if a Skeleton Notify, specified by name, was triggered in the previous tick.

Was Anim Notify State Active…

Returns true if a Notify State, specified by class, was active in the previous tick.

Was Anim Notify Triggered…

Returns true if a Notify, specified by class, was active in the previous tick.

The main differentiators between the notify function checks are if they are searching:

In any state, which searches for the notify in all active State Machines.

In the source state, which searches for the notify in the previously active state (the state being transitioned from).

In the State Machine, which searches for the notify in a specific State Machine.

Transition Interrupt

While transitioning, if another state becomes active, then the transition will "interrupt" and transition to that new state instead. When this interruption occurs, you can link certain Animation Notifies to the interruption. This makes those notifies execute when the interruption occurs.

To set up transition interruption notify behavior, select the transition and locate the Transition Interrupt properties in the Details panel.



You can specify either a Notify or Notify State Class to link to the interruption. If a Notify State is used, then the interruption executes both the start and end notify events in sequence on subsequent frames.

The other properties can be referenced in the Montage Notify page.

Transition Blend Types

There are three main types of state transition blending you can use when deciding how you want states to transition: Standard Blend, Inertialization, or Custom. You can choose any of these types by selecting the transition and locating the Blend Logic property in the Details panel.



Standard Blend

Standard Blend is the default transition option and contains settings for duration, curve, and other basic controls. You can locate and adjust these settings by selecting the transition and locating the Blend Settings category in the Details panel.



Name

Description

Transition Crossfade Sharing

You can use this dropdown menu to share Blend Settings properties between different transitions. To create a new shared setting, click Promote to Shared, type in the name of the setting, and press Enter. You can now access this setting on other transitions. The settings are completely shared, so editing settings for one transition affects all others.

Duration

The length of time, in seconds, that the transition takes.

Mode

The curve type to use when blending with this transition. Holding Ctrl + Alt on each of the options will display a preview of the curve shape.

Custom Blend Curve

If Mode is set to Custom, then this is where you specify a custom created Curve Asset to use as the curve shape, when blending with this transition.

Blend Profile

You can optionally specify a Blend Profile here, if you want certain bones to blend faster than others during this transition.

Inertialization

Rather than simply blending from one state to another, Inertialization can be used where the animation velocity and acceleration occurring at the time of the switch to the new animation are used to carry forward the motion. Refer to the Inertialization document for more information.

If you are using inertialization as a blend type, you must also ensure that the Inertialization node is used in the Anim Graph. It must be placed after your State Machine evaluates.



Inertialization does not produce good results on all transitions, depending on the animations used in the states bordering them. Some general rules to keep in mind when using interialization blending are:

Keeping your blend duration short, less than 0.4 seconds is best.

When the poses are extremely different, do not use inertialization.

Custom

Custom blends are blends you can graph and customize in their own Anim Graph layer, with its duration and curve shape determined by the standard blend settings.

When Blend Logic is set to Custom, you can either click Edit Blend Graph next to the dropdown menu, or double click the custom blend graph in My Blueprint to open the graph.



Within a custom blend graph, you can use the following special functions to read transition time and state weight information to inform your graph:

Name

Image

Description

State Weight



Gets the blend weight of the preceding state. This number gradually decreases from 1 to 0 over the transition duration.

Get Transition Time Elapsed



Gets the elapsed time in seconds of a specified transition.

Get Transition Time Elapsed (ratio)



Gets the elapsed time as a ratio of the crossfade duration for a specified transition. In other words, this number gradually increases from 0 to 1 over the transition duration.

Get Transition Crossfade Duration



Gets the crossfade duration of a specified transition. This is the number used in the Blend Settings > Duration property.

With custom blends, you can create a wide variety of blending logic. As a simple example, you can replicate a standard blend by using a normal Blend node with the Get Transition Time Elapsed (ratio) function.



Transition Properties

Transitions contain the following properties:



Name

Description

Automatic Rule Based on Sequence Player in State

Enabling this causes this transition to automatically occur when the most relevant animation ends in the preceding state. The blend duration also factors into the transition time, so if your animation is 2.0 seconds long, with a transition duration of 0.5 seconds, then the transition occurs after 1.5 seconds have elapsed.

Sync Group Name to Require Valid Markers Rule

If you specify a Sync Group name here, then this transition is only used if the current state contains animations with valid Sync Markers. Normal transition rules still apply.

Priority Order

The priority order of this transition. If multiple transitions are true at the same time, the one with the smallest priority is chosen.

Bidirectional

This setting is unsupported and currently does not function.

Blend Logic

What transition blend type to use.

Transition Rule Sharing

You can use this dropdown menu to share the Transition graph between different transitions. To create a new shared setting, click Promote to Shared, type in the name of the setting, and press Enter. You can now access this setting on other transitions. Graphs are completely shared, so editing the graph for one transition affects all others.

Transition Crossfade Sharing

You can use this dropdown menu to share Blend Settings properties between different transitions. To create a new shared setting, click Promote to Shared, type in the name of the setting, and press Enter. You can now access this setting on other transitions. The settings are completely shared, so editing settings for one transition will affect all others.

Duration

The length of time, in seconds, that the transition takes.

Mode

The curve type to use when blending with this transition. Holding Ctrl + Alt on each of the options will display a preview of the curve shape.

Custom Blend Curve

If Mode is set to Custom, then this is where you specify a custom created Curve Asset to use as the curve shape, when blending with this transition.

Blend Profile

You can optionally specify a Blend Profile here, if you want certain bones to blend faster than others during this transition.

Transition Interrupt

Contains settings for transition interrupts.

Start Transition Event (Custom Blueprint Event)

Creates a Skeleton Notify with the name used in the Custom Blueprint Event field. This notify executes when this transition starts. As with normal Skeleton Notifies, you can access the event by creating it in the Animation Blueprint's Event Graph.

End Transition Event (Custom Blueprint Event)

Creates a Skeleton Notify with the name used in the Custom Blueprint Event field. This notify executes when the transition ends.

Interrupt Transition Event (Custom Blueprint Event)

Creates a Skeleton Notify with the name used in the Custom Blueprint Event field. This notify will execute when the transition interrupts.

Programming and Scripting

Animation Blueprints

Programming and Scripting

Blueprints Visual Scripting

Animation Node Technical Guide

Animation Node Structure

EventGraph Nodes

AnimGraph Nodes

Animation Node Pose Watching

An Animation Blueprint (AnimBP) is a special class of Blueprint that specifically controls an object's animations behaviors. AnimBPs are divided into two graphs, the EventGraph, for controlling the animation logic and interaction behaviors, and the AnimGraph, which controls the animation pose output for the object. Each graph within an AnimBP uses nodes to perform operations. These nodes can be classified into a few distinct types based on their function in an AnimBP.

Animation Node Structure

AnimBP nodes on the AnimGraph and EventGraph can have input and output pins in which information can be passed.



AnimBP nodes can also have property pins, such as data values or variables that can be modified with linked functions in the AnimBP AnimGraph and EventGraph.



AnimBP node properties can also be accessed in the node's Details panel after selecting the node in the AnimBP.



EventGraph Nodes

Event graph nodes are used to process incoming data that in turn is used to drive the pose data in the Anim Graph, such as triggering playback, activating or disabling animations functions, and updating animation data.



With the Animation Events documentation, you can reference the function and properties of EventGraph AnimBP nodes.



A reference to the Animation Blueprint Event Nodes, used to initialize and update animations and animation logic from the AnimBP EventGraph.

AnimGraph Nodes

Using data from the EventGraph, AnimGraph nodes determine the actual frame-by-frame pose to use for the animating object.



Here you can access a reference doc for each of the main types of Anim Graph Nodes.



Animation nodes that blend multiple animations together based on a set of criteria.



Animation nodes that enable direct manipulation and applying solvers to the bones of the target Skeleton.



Animation nodes that convert poses between local and component space.



Animation node for Forward And Backward Reaching Inverse Kinematics.

Animation Node Pose Watching

When working in an AnimBP, you can toggle Pose Watching on specific AnimBP nodes to see a color coded debug drawing of the pose that it is generating in the Viewport.



To toggle an AnimBP node to pose watch, right-click on a node that contains pose data and select Toggle Pose Watch from the context menu.



You can also have multiple nodes toggled to Pose Watch at once, allowing you to compare poses at different points in the AnimBP to find the exact point in which any errors in your current pose are introduced.



By clicking the icon in the upper left corner of the node You can hide the node's watched pose. To change a node's watched pose color, open the Pose Watch Manager by navigating in the Menu Bar to Window > Pose Watch Manager and select the color option next to the desired pose.



You can disable a Pose Watch from the color picker window or by reselecting Toggle Pose Watch on the Animation Node.

Animation Blueprints

Blueprints Visual Scripting

Animation Blueprint Editor

Animation Event Node Types

Advanced Animation Event Node Types

Within an Animation Blueprints EventGraph, event nodes are Animation Blueprint (AninBP) nodes that you can use to create starting or activation points for animation blueprint logic. This document will provide a reference for the AnimBP event node types that you can use when creating animation logic in Unreal Engine.



In the EventGraph, event nodes are red, and are indicated by the arrow icon in the top right corner of the node.



You can add event nodes in the EventGraph by right-clicking in the graph and selecting a node from the Add Event section of the context menu.



An AnimBP's EventGraph can only contain one of each type of event node. However multiple functions can be connected to a single event node simultaneously.

EventGraph event nodes do not contain input pins as they begin a string of animation logic. Event nodes have an Output Execute pin that will initialize the sequentially connected nodes when the event node is activated. Each event node type is activated by a set of parameters.



You can begin a string of logic in the EventGraph by selecting one of the following Animation Event Node Types.

Animation Event Node Types

You can use the following Event Nodes in your AnimBP's EventGraph to begin animation logic with specific parameters.

Node Type

Image

Description

Blueprint Begin Play



The Event Blueprint Begin Play event node will activate any connected logic when the owning component is activated by the Play function. With this node you can connect logic that will be run when the owning object is first activated, even before animation functions are initialized. When hovering over the node, you can reference the node's owning component, or Target.

Blueprint Initialize Animation



The Blueprint Initialize Animation event node will activate seqeunctail nodes when the current Animation Blueprint is first built during runtime to perform initialization operations. With this node, you can build logic that will activate once at the beginning of the Animation Blueprint.

Blueprint Linked Animation Layers Initialized



The Blueprint Linked Animation Layers Initialized event node will activate connected nodes when the all linked animation layers are initialized. You can use this node to run logic once, that will be activated as soon as all linked animation layers are initialized for the first time.

Blueprint Post Evaluate Animation



The Blueprint Post Evaluate Animation event node will activate sequential nodes after the AnimBP has been evaluated. With this node, you can activate logic that will run after the AnimBP has been evaluated.

Blueprint Update Animation



The Blueprint Update Animation event node is executed every frame allowing the Animation Blueprint to perform calculations and updates to any values it needs. This event node is the entry point into the update loop of the EventGraph. The amount of time elapsed since the last update is available from the DeltaTimeX output pin so time-dependent interpolations or incremental updates can be performed.

Advanced Animation Event Node Types

You can use the following Event Nodes in your AnimBP's EventGraph to begin animation logic using project specific parameters, player input, and custom parameters.

Node Type

Image

Description

Input



Input event nodes will activate connected logic when the specified player input is received or released, depending on the output pin the logic is connected to. You can use this node to create animation logic that is dependent on user inputs, with specific input functions, such as keys, mouse movements, or touch controls.

Input Action



With Input Action event nodes, sequential logic will be activated when the player initiates a defined input action during run time. You can use this node to create animation logic that is dependent on user interactions with specified mechanics and systems in your project. These systems are definable in the project settings.

Anim Notify



You can use specific Anim Notify event nodes to activate animation logic when the connected Anim Notify is activated in an animation. These nodes are dependent on the Anim Noties present in your project and will activate any connected logic when the notify is triggered in your animation sequence, composite or montage. You can use these event nodes to build animation logic that is connected to animation playback.

Custom Event



With the Custom Event node you can build and define the custom parameters in which you want to activate animation logic in your project. See the Programming and Scripting documentation for more info on blueprints and blueprint nodes.

Programming and Scripting

Animation Blueprints

Skeletons

Blueprints Visual Scripting

Overview

Properties and Settings

Forward And Backward Reaching Inverse Kinematics (FABRIK) is an IK solver that operates on a chain of bones of arbitrary length as long as there are at least of 2 bones links in the chain.



Overview

You can add the FABRIK blueprint node to the AnimGraph of your Animation Blueprint. Once added, you can integrate the FABRIK node into your AnimBP using your objects Component Pose.

You can use the FABRIK node's Effector Transform input pin to connect a transform variable to implement a relative or absolute bone transform to the chain. You can use a relative transform to reference a different bone from the same skeleton for the transform, or transform the chain without a reference using an absolute transform.



In order to determine the strength of the applied Skeletal Control, you can set an alpha value on the Alpha input pin, either manually on the Alpha input pin or with a dynamic variable in the AnimGraph. Larger alpha values apply more Skeletal Control, while lesser values apply less.



Properties and Settings

Inside the Details panel for the FABRIK node you will find additional settings which you can be use to adjust how the solver functions:



In the End Effector section, you determine the target location and rotation.

The End Effector properties, found in the FABRIK node's details panel are very similar to the TwoBone_IK node properties.

Property

Description

Location, Rotation, Scale

Coordinates for target location of tip bone. If the EffectorLocationSpace property is set to bone, this is the offset from Target Bone to use as target location (can also be set as a Pin on the node).

Effector Transform Space

Set the position of the bone in SkeletalMeshComponent's reference frame.

Effector Transform Bone

If the Effector Transform Space property is set to bone, this properties defined bone will be used.

Effector Rotation Source

Control the Rotation (maintain component space, local space or match end effector target rotation).

In the Solver section, you define the chain of bones to use, from the Root to the Tip. The Tip will try to reach the end effector location.

Property

Description

Tip Bone

Define a bone as the Tip Bone from the Skeleton Tree.

Root Bone

Set a reference to the skeleton's Root Bone from the Skeleton Tree.

Precision

Here you can set a value that will operate as the Tolerance for final tip bone location delta from Effector Location input pin. The lower the tolerance, the more precise the tip bone's location will be in relation to the End Effector target, but will result in higher performance cost for the evaluation.

Max Iterations

Here you can set the maximum number of iterations allowed. You can tune this value in order to control performance cost of the evaluation to ensure high volume usage will not reduce your project's frame rate.

Enable Debug Draw

Here you can toggle drawing of axes to debug joint rotation.

In the Settings section, you set the strength applied.

Property

Description

Alpha

Current strength of the Skeletal Control (can also be set as a Pin on the node).

Alpha Scale Bias

Set the Minimal and Maximal input scale values.

Node

Can be used to reset the Effector Rotation Source if it is set to something other than Local Rotation Relative to Parent.

Programming and Scripting

Animation Blueprints

Skeletons

Blueprints Visual Scripting

Animation Blueprint nodes on the AnimGraph calculate and generate new poses that drive animations in either the Local Space or a Component Space. Animation poses generated in Local space calculate bone transforms relative to the bones parent bone. Animation poses generated in Component Space calculate bone transforms relative to the Skeletal Mesh Component of your character.



The Convert Spaces nodes available in the AnimGraph of Animation Blueprints provides the ability to convert poses between local and component space.

When working with poses in an Animation Blueprint, most nodes will operate within Local Space, indicated with white pose input and output pins. However, certain blend nodes and all skeletal controls nodes, operate in Component Space, indicated with blue pose input and output.

To use nodes that operate within Component Space, poses must first be converted to Component Space using the Local to Component conversion node.



After an animation pose has undergone component space operations, it must be converted back to local space in order to be usable by additional nodes, or provide a final pose for the output node.



Because there is a cost associated with each conversion to or from Component Space, it is best to group any nodes that operate in Component Space, to reduce the number of conversions needed.

Programming and Scripting

Animation Blueprints

Skeletons

Blueprints Visual Scripting

Blend Nodes

Apply Additive

Blend

Blend Bone by Channel

Blend Multi

Function Blend Nodes

Blend Poses by bool

Blend Poses by int

Blend Poses by Enumeration (Enum)

Layered blend per bone

Inertialization

Request from Blend Nodes

Request from State Machine Transitions

Request from Linked and Layered AnimGraphs

In the AnimGraph of a character's Animation Blueprint you can use blend nodes to blend multiple source animation poses together to create new animation poses.



With each blend node you can input multiple animation poses using the node's pose input pins, to generate a blended pose that will be accessible from the node's output pose pin.



Some Blend Nodes can accept and blend more than two animation poses, with these nodes you can right-click the node in the AnimGraph and select Add Blend Pin to add another pose input pin.



You can also remove additional pose input pins by right-clicking the specific input pin you want to remove and selecting Remove Blend Pin from the context menu.

While using blend nodes, you can control the degree of blending with an Alpha value. You can manually assign a blend node's alpha value, by selecting the variable input node, or the alpha property in the node's details panel, and entering a value. You can also assign a blend node's alpha by connecting an alpha variable node to the alpha input pin in the AnimGraph. An alpha value of zero will typically favor the primary pose, while a value of 1 will favor the secondary pose.



Using more advanced blend nodes that can incorporate additional animation data, you can create unique animation blending results in your project. Here you will find a reference to the available blend nodes you can use to blend animation poses in Unreal Engine.

Blend Nodes

Categorized with a gray title color, standard blend nodes perform simple blends of animation poses based on node specific parameters. Here you can reference a list of the standard blend nodes that you can use in your project to blend animation poses in the AnimGraph

Apply Additive

Both the Apply Additive and the Apply Mesh Space Additive nodes add an additive pose to a base-normal animation pose, based on an alpha value.



Using the nodes input pins, you can connect a base pose and an additive pose with which to apply.

Apply Additive nodes are also affected by the LOD Threshold system. You can adjust the LOD level threshold that the blend occurs in the Apply Additive and Apply Mesh Space Additive's Details panel.

In addition, you can use a Make Dynamic Additive node, to negatively blend additive animation poses. With this node, you can subtract the additive pose from the base pose to create an output pose.



In the Make Dynamic Additive node's details panel you can also enable the node to operate in the Mesh Space.

Blend

The standard Blend node is a simple combination of the two input poses that scales the weight of which input is prioritized based on an alpha value from the Alpha input pin.



You can connect animation poses to the A and B input pins, and control the degree of blending between the poses with the Alpha pin.

Blend Bone by Channel

With a Blend Bone by Channel blend node you can specify individual bones, in which to apply specific blending transforms.



In the Blend Bone by Channel's Details panel you can add a Bone Definitions section with (+) Add. After creating a definition, you can define a source bone to pull transform data from, and a Target bone to apply the blend. You can also define what aspects of the transform you want to incorporate in the blend, such as Translation, Rotation and Scale by toggling the available properties. In addition you can define in what Transform Space the transform data is being calculated, such as World Space, Component Space, Parent Bone Space and Bone Space.

The present alpha value will facilitate the weight of the blend.

Blend Multi

With a Blend Multi node, you can blend more than two blend poses, between a range of alpha values.



In the Blend Multi's Details panel you can also toggle the node to behave as additive with the Additive Node property.

Function Blend Nodes

Categorized with a green title color, function blend nodes perform more advanced calculation-based blends of animation poses based on node specific parameters. Here you can reference a list of the function based blend nodes that you can use in your project to blend animation poses in the AnimGraph.

Blend Poses by bool

The Blend Poses by bool node performs a time-based blend between two poses using a Boolean value as the trigger. When the Boolean reads true, the pose connected to the True Pose input pin is used; when the Boolean is false, the False Pose is used. Each pose has a float value Blend Time that is used to control how long it will take to blend into the pose.



In the Details panel, you can toggle the Blend Time pins to be visible in the AnimGraph as well as set the Transition Type.

Blend Poses by int

The Blend Poses by int node performs a time-based blend between any number of poses using an integer value as the key. For each input integer value, the pose associated with that value's input pin is used. For instance, when the integer is set to 0, the pose connected to Blend Pose 0 is used. Each pose has a float value Blend Time that is used to control how long it will take to blend into the pose.



In the Details panel, you can toggle the Blend Time pins to be visible in the AnimGraph as well as set the Transition Type.

Blend Poses by Enumeration (Enum)

The Blend Poses by Enum node performs a time-based blend between poses using an Enumeration (Enum) value as the key. A default pose can be used, and additional poses can be added for the values identified within the enum connected through the Active Enum Value pin. Additionally, each pose has a float value Blend Time that is used to control how long it will take to blend into the pose.



In the Details panel, you can toggle the Blend Time pins to be visible in the AnimGraph as well as set the Transition Type.

Layered blend per bone

With the Layered blend per bone node you can blend between any number of dynamic blend poses based on a defined set of bones.



In the Details panel of the Layered blend per bone node, you can define the blend mode as either a Branch Filter or a Blend Mask.



You can enable the Mesh Space Rotation Blend and Mesh Space Scale Blend properties to control whether the Rotation and Scale blending occurs in the Mesh Space or Local Space.

With the Curve Blend Options property you can set the curve blend behaviors from a set list to control how the animation layers blend together. Here you can reference a list of the available Curve Blend Options.



Blend Option

Description

Override

Overrides the pose to the last pose that contains a valid curve value.

Do Not Override

Does not override the pose. Best used when the desired previous pose doesn't have a curve value.

Normalize by Weight

Normalizes the pose blend by the sum of all blend weights.

Blend by Weight

Blends the poses by blend weight without normalizing.

Use Base Pose

Uses the Base Pose for all curve values.

Use Min Value

Selects the highest curve value from all connected poses and uses it to blend.

Use Max Value

Selects the lowest curve value from all connected poses and uses it to blend.

You can also enable the Blend Root Motion Based on Root Bone property to incorporate the per-bond blend weight of the root bone when lending Root Motion.

With the Branch Filter option, you can define an Index of bones the blend will affect.



After adding an element to the Branch Filters property, you can input a bone as the Bone Name to use as a reference point to control localized animation blending. Using the Blend Depth property, you can control the wight the blend has on the children bones of the Bone Name.

Value

Example

Description

Positive



Positive Blend Depth values will offset the weight by the same number of bones and taper the weight through the chain to the Bone Name. For example, a Blend Depth of 2 will apply a blend weight of 1 to the next child bone and a blend weight of .5 to the Bone Name.

Zero



A Blend Depth of 0 will apply a blend weight of 1 to the Bone Name and all connected child bones.

Negative



Negative Blend Depth values will disable any Blend Poses and favor the Base Pose. Lesser values than -1 will offset the weight by the same number of bones and taper the disabled blend weight through the chain to the Bone Name. For example, a Blend Depth of -2 will apply a blend weight of -1 to the next child bone and a blend weight of -.5 to the Bone Name.

With the Blend Mask option, you can define the character's Blend Masks as reference points to control the blending between the Base Pose and the Blend Poses.



Inertialization

Inertial blending is a high-performance alternative to traditional animation crossfading that produces natural transitions as a post-process. Once an inertial blend is activated, the source pose is no longer evaluated at all. By contrast, traditional blending evaluates both source and target poses for the duration of the transition to combine them into a blended pose.



To use inertial blending, you can add an Inertialization node to the AnimGraph after the source animation blend you want inertially blended.



The Inertialization node keeps track of pose motion and curve changes so that it can continue moving toward the target animation when an inertial blend is activated. The node is activated by any inertial blend requests connected to its input pose pin. State Machine Transitions, Blend Nodes, Linked Anim Graphs and Linked Anim Layers, can all trigger inertial blends.

The Inertialization node must be connected after the source of the inertial blend request, but does not have to be immediately adjacent. Deferring an Inertialization node closer to the Output Pose node can help reduce or eliminate standard blends from your graph and improve performance. If your AnimGraph contains a Inertialization request but is missing an Inertialization node, a runtime error will be logged in the Message Log panel.



A single Inertialization node can handle many inertial blend requests. The minimum requested blend duration will be used.

When authoring animations and graphs with inertial blending in mind, it's best to begin transitions while the outgoing animation is still in motion. There is no need to return to a neutral pose, as inertial blending will handle smoothly and naturally easing to a rest position. Short blends work best since inertial blending is a post-process for easing motion toward a target animation. Inertial blends can be interrupted with other inertial blends, but try to avoid scenarios that cause continuous interruptions because subsequent blend durations may be trimmed to keep the pose stable.

You can place multiple Inertialization nodes in your graph as needed, and each will handle inertial blend requests from their source pose. This means you can perform inertial blending in different spaces. For example, you may want separate Inertialization nodes for your character's upper and lower body, followed by a Layered Blend per bone node to splice them together into a final pose. You can use inertial blending with additive poses by inserting an Inertialization node before applying to the base pose. For final pose fixups, you will generally run Inertialization before IK, which effectively does inertial blending in IK space.

A Source pose stops being evaluated once inertial blending begins. As a result, Animation Notifies from the source animation Sequence will no longer trigger after inertial blending begins. You may need to refactor existing game logic and Anim Notifies to be compatible with Inertialization.

Request from Blend Nodes

In the Details panel of Inertialization compatible nodes, you can set a Transition Type property to Inertialization. To use inertial blending, the Inertialization node must be placed in the animation graph anywhere after the blending node.



Request from State Machine Transitions

A Inertial Blend request can be made by a State Machine. In the Details panel of a Transition Rule, you can set the Blend Logic property to Inertialization.



Request from Linked and Layered AnimGraphs

Inertialization properties can also be defined in an Animation Layers or from a Linked Anim Graph. After selecting a Graph from the My Blueprints panel you can find the Graph Blending section of properties in the Details panel. An Animation Layer can blend in or out, but only via inertial blending. An Inertialization node must be placed anywhere after the Linked Anim Layer node that links this Animation Blueprint. A negative value means the blend time will be determined by the other incoming or outgoing Animation Layer.



Animation Blueprints

Animation Node Reference

Skeletons

Skeletal Mesh LODs

Skeletal Control Nodes

With Skeletal Control Animation Blueprint nodes you can take direct control of a character's Skeleton asset. Skeletal Control nodes can be used within a character's Animation Blueprint, on the AnimGraph, to control an individual bone, create IK chains, and other procedural, dynamic bone-driven animations.



Skeletal Control nodes are structured similarly to other AnimBP nodes. The node can receive an animation pose through the input pin and generates a modified pose through the output pin. Most Skeletal Control nodes operate and compute transforms in the Component Space. Animation poses generated in Component Space calculate bone transforms relative to the Skeletal Mesh Component of your character as opposed to the bone's Parent Bone. Component space pose pins appear as blue in the Anim Graph.



You can convert poses from Local Space to Component space with space conversion nodes.



Space Conversion nodes have an associated cost to your project's performance. It is recommended that space conversions occur as infrequently as possible by grouping specific space reliant functions together, near the final pose node when possible.

An alpha value is also common among Skeletal Control nodes. Similar to Blend nodes the alpha value controls the degree of applied modification to the source pose, when generating the new pose.



In the case of Skeletal Control nodes, a float value between 0.0 and 1.0 is used as the alpha value to determine the weight of the applied Skeletal Transform. A value of 0.0 gives full weighting to the input pose, while a value of 1.0 gives full weighting to the control's computed Transform.

Within the Details panel of each Skeletal Control node, you can also set the LOD Threshold in which the node is considered. The value defined as the LOD Threshold will be the highest LOD level the Skeletal Control node will be used. Any higher LOD levels, (lower quality models), will ignore the Skeletal Control node.



By restricting the LOD level Skeletal Control nodes to compute bone transforms, you can reduce the performance cost of your animation system.

Skeletal Control Nodes

Here you can reference additional documentation about each of the Skeletal Control Nodes you can use in your projects.



Describes how the AnimDynamics AnimBP node can be used as a light-weight physics simulation solution that you can use to apply physics-based secondary animation to characters.



Describes how Apply a Percentage of Rotation drives the Rotation of a target bone with a specified percentage of the Rotation of another bone within the Skeleton.



Describes the Bone Driven Controller node which allows a 'Driver' bone to dynamically affect the motion of a target object.



Describes how to access and use the CCDIK Skeletal Control node to set up and control IK chains.



Describes the Copy Bone node which copies the Transform data or any component of it from one bone to another.



Describes the Hand IK Retargeting control which can be used to handle retargeting of IK bones.



Describes how the Look At control can be used to specify a bone to trace or follow another bone.



Describes the Modify Curve node which can be used to modify animation curves with arbitrary logic inside Animation Graphs.



Describes how you can debug a specified Bone with the Observe Bone node.



Describes the RigidBody node and how it can be used as a lightweight physics simulation inside Animation Blueprints.



Describes how the Spline IK Solver node can be used for controlling character spines or bone chains within Animation Blueprints.



Describes the Spring Controller which is used to limit how far a bone can stretch from its reference pose before force is applied in the opposite direction.



Describes how the Trail Controller node can be used affect a chain of bones.



Describes the Transform (Modify) Bone skeletal control node which can be used to modify the transform of a specified bone.



Describes how the Twist Corrective control can be used to drive curve values based on the twist of one bone relative to another.



Describes how the Two Bone IK control can be used to apply IK to a 3-joint chain.

Animation Blueprints

Graphing in Animation Blueprints

Skeletal Controls

RigidBody

Overview

Single-Body Simulation

External Force

Chains

Collision Simulation

Planer Limits

Spherical Limits

Property Reference

The AnimDynamics Animation Blueprint node is a light-weight physics simulation solution, that you can use to apply physics-based, secondary animation to parts of a character's Skeletal Mesh at runtime. Unlike the RigidBody node that uses the character's Physics asset, the AnimDynamics node simulates its own physics bodies, to increase your projects performance.



With the AnimDynamics node, you can apply simulated-physics motion to parts of your character's skeletal mesh, such as, necklaces, bracelets, wires, or other items, in conjunction with character motion.

Here, the AnimDynamics node is used to dynamically drive the motion of the character's antenna, to react to the motion of the character's head during animation playback.





AnimDynamics Disabled

AnimDynamics Enabled

Overview

The AnimDynamics node is a low-performance cost physics-solver that is processed on the AnimGraph at runtime. In order to achieve a low performance cost, the AnimDynamics node makes a few approximations that are important to consider:

Simulated boxes are used instead of the character's bones or physics bodies, to calculate inertia for each segment.

Collision is not calculated; instead, constraints can be used to restrict movement.

The AnimDynamics node supports Linear, Angular and Planar constraints to simulate physically-influenced motion. Linear and Angular constraints can be driven by springs to provide a more bouncy feel, while Planar constraints can be used to create a plane that the object will not cross. You can toggle each of these constraints, and adjust their associated properties in the AnimDynamics node's Details panel.



Single-Body Simulation

Using the AnimDynamics node you can apply simulated-physics motion to any object on your character using a bone as a reference point. Here is an example of the AnimDyamics node being used to add dynamic motion to a drum that is reacting to the motion of the character's running animation.





AnimDynamics Disabled

AnimDynamics Enabled

By selecting the drum's bone as the Bound Bone, you can control the physics-driven motion by defining a bounding box with the Box Constraints property. The Local Joint Offset is an offset from the Bound Bone's joint, that you can use to determine the reference point of the constraints.

By leaving the Box Constraints and the Local Joint Offset properties as their default values, you may not see any movement. This is because the constraints are preventing any motion on the object. By reducing the bounding box's dimensions, you will see motion.

Here, the AnimDynamics's Debug properties are enabled. You can use these debug drawings to visually see the Bounding Box and Local Joint Offset properties as they influence the mesh.



In this example, Rotation Constraints are also set, so the drum can only move along a set axis, within a specified range. The applied Rotation Constraint along the Y axis is represented by the green angle overlay, and is useful to prevent the mesh from overlapping on itself.



For more information about creating single-body physics simulations using the AnimDynamics node, see the Creating Dynamic Animations workflow guide.

External Force

You can also set an External Force to the physics-simulate motion, to weight the object being simulated, or apply more inertia for more reactive motion. By default, an External Force vector can be applied using the pin in the AnimGraph.



For more information about using an External Force to create physics simulations using the AnimDynamics node, see the Creating Dynamic Animations workflow guide.

Chains

By enabling the Chain property in the Details panel, you can use the AnimDynamics node is to simulate the motion and collision of a chain of objects.



Chain simulation is a much more resource intensive simulation, than a single-body simulation. With chain simulation, linked constraints now need to be solved, which requires many more iterations to correctly converge. Iteration counts are also configurable per-node using the Num Solver Iterations Pre Update and the Num Solver Iterations Post Update properties in the Details panel.

By enabling the Chain property and selecting a Bound Bone and Chain End, the AnimDynamics will generate a chain using any bones in between. Each bone within the chain, excluding the Bound Bone, will have a constraint box generated around it, to simulate motion and collision with the other bones in the chain. These constraint boxes will need to be tweaked manually to achieve good results.



Overlapping constraints can cause undesirable results, like flailing bones and uncontrolled motion. If you are experiencing these kinds of results, ensure the chain constraints are not overlapping.

Collision Simulation

Using Planer and Spherical limits, you can enable simple collision simulation with the AnimDyanmic node's simulated physics structures.

Planer Limits

With planar limits, you can set flat boundaries the physically-simulated structures are unable to cross. You can use these planer constraints to prevent the simulated structures from overlapping with other parts of the character's Skeletal Mesh or the ground.



In the AnimDynamics Details panel, you can enable planer limits with the Use Planer Limits property. Then, using Add (+) to create an Index, you can set individual planer limits to control the simulated structure's behavior. With each index, you can set a Driving Bone as a reference point for the location of the planer limit. Then, using the Plane Transform properties, you can set the planer limit's Location, Rotation, and Scale properties to establish planer boundaries that the simulated structure is unable to cross.

For example, adding a planer limit to the character's root bone, can create a boundary that represents the ground, that simulated objects are not able to cross.



Spherical Limits

With spherical limits, you can create sphere boundaries, that surround points on the AnimDynamics physics-simulated structures, to act as a simple collision prevention.



After enabling the Use Spherical Limits property in the AnimDynamics Details panel, you can use Add (+) to create an Index where you can set up sphere limits. Within each Index you can set a Driving Bone to act as a reference point for the location of the sphere and the offset its location on the X, Y, and Z axes, with the Sphere Local Offset property. You can also set the sphere's Limit Radius to determine how large the sphere is, and set the Limit Type to decide how the sphere interacts with the Skeletal Mesh.



By setting the Limit Type on a sphere limit to Outer, you can use sphere limits to prevent structures from colliding, by not allowing objects to pass through the sphere. You can also use sphere limits to contain structures, by setting the Limit Type to Inner.

Property Reference



Here, you can reference a list of the AnimDynamics properties and a description of their functions:

Property

Description

Preview Live

When enabled a preview of the live physics object will be drawn on the mesh in the viewport.

Show Linear Limits

When enabled a preview of the Linear Limits (prismatic) will be drawn on the mesh in the viewport.

Show Angular Limits

When enabled a preview of the Angular Limit ranges will be drawn on the mesh in the viewport.

Show Planer Limit

When enabled a preview of the Planer Limit information (actual plane, plane normal) will be drawn on the mesh in the viewport.

Show Spherical Limit

When enabled a preview of the Spherical Limits will be drawn on the mesh in the viewport.

Show Collision Spheres

If Planer Limits are enabled and the Collision Mode is set to Custom Sphere, Inner Sphere or Outer Sphere a preview sphere, representing the collson sphere, will be drawn on the mesh in the viewport.

Reset Simulation

Reset the simulation for this node.

Simulation Space

The space used to run the simulation. The options available for selection are as follows:

Component: Simulation origin will be calculated using the location and orientation of the Skeletal Mesh component.

Actor: Simulation origin will be calculated using the location and orientation of the actor containing the Skeletal Mesh component.

World: Simulation origin will be calculated using the world origin.

It is not recommended to use the World simulation mode with Teleporting characters.

Root Relative: Simulation origin will be calculated using the location and orientation of the skeleton's root bone.

Bone Relative: Simulation origin will be calculated using the location and orientation of the bone specified in the Relative Space Bone property.

Relative Space Bone

When the Simulation Space is set to Bone Relative, the simulation will use the selected bone from the character's skeleton as the origin reference.

Chain

When enabled, the node will use the solver to simulate a connected chain.

Bound Bone

Select a bone from the character's skeleton to attach the physics body to. If the Chain property is enabled, the selected bone will become the top, or first, bone of the defined chain.

Chain End

When the Chain property is enabled, the selected bone from the character's skeleton will become bottom, or end, of the defined chain. When the Chain property is disabled, this property is ignored.

Box Extents

Set the extents of the box on the X, Y, and Z, to use for physics simulation. The coordinates within the context of the Simulation Space and are in reference to the Local Joint Offset location.

Local Joint Offset

Set the position offset of the Box Extent, from the nearest joint to the Bounding Bone.

Angular Spring Constraints

Set a Spring constant to use when the Angular Spring property is enabled. Higher values mean a stronger spring.

To see results, ensure the Angular Target Axis and Angular Target properties have been defined.

Use Gravity Override

When enabled the Gravity Override property values will be used instead of the Gravity Scale for simulation.

Gravity Override

Set the vector value to override the Gravity Scale when Use Gravity Override is enabled.

Gravity Override in Sim Space

When enabled, the Gravity Override is defined in simulation space. When disabled, the Gravity Override is defined in world space.

Gravity Scale

Set the scale for gravity use in the simulation. A value of 1 is a full gravity weight while values higher than 1 increase forces due to gravity.

Linear Spring

When enabled the body will attempt to spring back to its initial position using the Linear Spring Constraint property value as a scale.

Angular Spring

When enabled the body will attempt to align itself with the specified angular target using the Angular Spring Constraint property value as a scale.

Linear Spring Constraint

Set the spring constant to use when calculating linear springs. Higher values mean a stronger spring.

Num Solver Iterations Post Update

Set the number of updates passed on the Linear and Angular limits, found in the Constraint property section of the Details panel. Post Update indicates the set number of update passes occurs after the solver has the position of the bodies.

It is recommended that the set value should be around a quarter of the set Number Solver Iterations Pre Update property.

Do Eval

When enabled, the node will perform bone transform evaluations. You can disabled this property to see a visualization of the default animation state, to quickly compare the physics simulation to the default animation state.

Num Solver Iterations Pre Update

Set the number of updates passed on the Linear and Angular limits, found in the Constraint property section of the Details panel. Pre Update indicates the set number of update passes occurs after the solver has the position of the bodies.

It is recommended that the set value should be about four times the value of the set NumSolverIterationsPostUpdate property.

Linear Damping Override

Set a value to be used when the Override Linear Damping property is enabled.

The default is 0.7. Values below 0.7 won't have an effect.

Angular Damping Override

Set the value to be used when the Override Angular Damping property is enabled.

The default is 0.7. Values below 0.7 won't have an effect.

Angular Bias Override

Set the value to be used when the Override Angular Bias property is enabled.

Angular bias performs a twist reduction for chain forces and defaults to a value to keep chain stability in check. When simulating, a single-body angular force can appear delayed from the position of the mesh. If you encounter this issue you can tweak the value of the Angular Bias Override towards 1.0f until it settles correctly.

Do Update

When enabled the node will perform physics simulation updates. When disabled will show the base animation pose. This property can be helpful to toggle the node's effects.

Override Linear Damping

When enabled, the Linear Damping Override value will be used to apply linear damping.

Override Angular Bias

When enabled, the Angular Bias Override value will be used to apply an angular bias for bodies in this node.

Angular bias is a twist reduction for chain forces and defaults to a value to keep chain stability in check. When using single-body systems sometimes angular forces will look like they are delayed from the mesh's motion, if that's the case enable Override Angular Bias and tweak the Angular Bias Override value towards 1.0f until it settles correctly.

Override Angular Damping

When enabled the Angular Damping Override value will be used to apply angular damping.

Component Linear Acc Scale

When using non-world space simulation, this property controls how much of the component's world-space acceleration is passed on to the local-space simulation. Vector values can be used on the X, Y, and Z axes.

Component Linear Vel Scale

When using non-world space simulation, this applies a drag to the bodies in the local space simulation, based on the component's world space velocity. Vector values can be used on the X, Y, and Z axes.

Component Applied Linear Acc Clamp

When using non-world space simulation, this is an overall clamp on acceleration derived from the Component Linear Acc Scale and Component Linear Vel Scale properties.

Linear XLimit Type

Limit the linear X-Axis motion by selecting Limit. Select Free to disable any limits.

Linear YLimit Type

Limit the linear Y-Axis motion by selecting Limit. Select Free to disable any limits.

Linear ZLimit Type

Limit the linear Z-Axis motion by selecting Limit. Select Free to disable any limits.

Linear Axes Min

Set the minimum values to allow linear movement per-axis, X, Y, and Z.

To lock linear motion on a specific axis, set the value to 0 on the desired axis in the Linear Axes Min and Linear Axis Max properties.

Linear Axes Max

Set the maximum values to allow linear movement per-axis, X, Y, and Z.

To lock linear motion on a specific axis, set the value to 0 on the desired axis in the Linear Axes Min and Linear Axis Max properties.

Angular Constraint Types

Select the method to use when constraining angular motion. Angular will limit the motion, based on the parameters set in the Angular Limits Min, Angular Limits Max, Angular Target Axis, and Angular Target properties. Cone will limit the motion within a cone, whose origin point is vectored from the Bound Bone's joint, and angle is set in the Cone Angle property.

Twist Axis

Select which axis, X, Y, and Z, the twist will be occurring along when constraining angular motion.

Cone Angle

Set the cone angle to use when Angular Constraint Types is set to Cone.

Angular Limits Min

Set the minimum angle limits on each axis, X Y, and Z, to use when Angular Constraint Types is set to angle.

Angular Limits Max

Set the maximum angle limits on each axis, X Y, and Z, to use when Angular Constraint Types is set to angle.

Angular Target Axis

Set the axis, X Y, and Z, the angle will be used to align to the Angular Target. Typically, this is the axis pointing along the Bound Bone.

This is affected by the Angular Spring Constraints.

Angular Target

Set the axis to align the Angular Spring Constraint to. A value of 0 will disable the axis while a value of 1 will enable the axis when factoring the alignment.

The properties values are typically set to point down the bone. For example, the property might be set to (1.0, 0.0, 0.0), but you can pick other values to align the spring to a different direction.

External Forces

When set, an external force can be applied to all bodies in the simulation, specified in world space. By default this property appears as a Pin on the node in the AnimGraph. Also see the External Force Section of this page.

Collision Type

Set the resolution method to use when Planer Limits are enabled. Options include: CoM (Center of Mass): Only limits the center of mass from crossing planes. Custom Sphere: Use the specified sphere radius to collide with planes. Inner Sphere: Use the largest sphere that fits entirely within the body extents to collide with planes. Outer Sphere: Use the smallest sphere that fully contains the body extents to collide with planes.

Sphere Collision Radius

Set the radius to calculate a sphere when Collision Type is set to Custom Sphere.

Use Spherical Limits

When enabled, spherical limits will be evaluated.

Spherical Limits

When Use Spherical Limits is enabled, you can add spherical limits to the array. After adding an element, it's properties include:

Driving Bone: Bone to attach the sphere to. Sphere Local Offset: Local offset for the sphere, if no driving bone is set the is in node space, otherwise bone space. Limit Radius: Set the radius of the sphere. Limit Type: Whether to lock bodies inside (Inner) or outside (Outer) the sphere.

Use Planer Limits

When enabled, planer limits will be evaluated.

Planer Limits

When Use Planer Limits is enabled, you can add planer limits to the array. After adding an element, it's properties include:

Driving Bone: When using a driving bone, the plane transform will be relative to the bone transform. Planer Transform: Set the transform of the plane. This is either in component space if no Driving Bone is specified, or in bone space if a driving bone is present. Set the X, Y, and Z values for the planes location, rotation, and scale properties.

Enable Wind

When enabled wind is factored for the bodies in this simulation.

Wind Scale

Set the scale to apply calculated wind velocities in the solver.

Animation Blueprints

Graphing in Animation Blueprints

Skeletal Controls

Skeletons

Overview

Stacking Nodes

Property Reference

With the Apply a Percentage of Rotation Animation Blueprint node, you can apply a Source Bone's rotation motion to a Target Bone.

Here, the robot's antena are matching the X-axis rotation its head.





Disabled Apply a Percentage of Rotation

Enabled Apply a Percentage of Rotation

Overview

The Apply a Percentage of Rotation node operates within Component Space, so a space conversion will need to occur to implement the node within your character's Animation Blueprint.



With the Alpha property or pin, you can control the degree of the applied rotation on the generated output pose. A value of 1 will fully use the generated output pose, while a value of 0 will output the source pose.

The Multiplier property or pin allows you to multiply the degree of the rotation beyond the Source Bones rotation.

A Multiplyer value of 0 will not apply any rotation to the Target Bone.

In the Apply a Percentage of Rotation node's Details panel you can select a Source Bone, to copy the rotational movement from, as well as a Target Bone in which to apply the copied rotation motion.



See the Property Reference table for more information about the Apply a Percentage of Rotation node's properties.

Stacking Nodes

Multiple Axis rotation can be used by stacking addition Apply a Percentage of Rotation nodes together, and assigning unique axis of rotation to each.



When stacking Apply a Percentage of Rotation nodes, ensure the Is Additive property is enabled in the Details panel for any additive or stacked nodes applying rotation to the same bone. This property is also important to enable when using the Apply a Percentage of Rotation node in conjunction with any other animation or node making adjustments to the same bone.

Property Reference



Here you can reference a list of the Apply a Percentage of Rotation node's properties.

Property

Description

Target Bone

Select a bone from the character's Skeleton in which to apply the rotation from the Source Bone. Any child bones of the Target Bone will also be moved relevant to the parent bone motion.

Source Bone

Select a bone in which to copy the rotational motion from, on the axis defined in the Rotation Axis to Refer property. This rotation motion will then be applied to the Target Bone.

Multiplyer

Set a multiplier to apply to the rotation motion from the Source Bone as it is applied to the Target Bone. A value of 1 will copy the rotation motion exactly.

By default this property is accessible in the AnimGraph on the selected node.

Rotation Axis To Refer

Here you can select which axis of rotation motion will be copied from the Source Bone, and applied to the Target Bone.

Is Additive

Enable this property to enable the rotation motion to be applied to the bone as additive. Disabling this property will overwrite any previous motion on the Target Bone.

Animation Blueprints

Graphing in Animation Blueprints

Skeletal Controls

Skeletons

Overview

Set Up

Debug

Property Reference

With the Bone Driven Controller Animation Blueprint node, you can dynamically affect the motion of a Target Object, such as another Bone, Morph Target or Material Parameter.

Overview

With this node, you can apply motion data from the Source Bone to dynamically adjust another object on the Skeletal Mesh, such as a character's accessory object, to avoid geometry intersections during an animation.



Here the character's arm bone has been selected as the Source Bone, and the shoulder pad bone has been selected as the destination Target Bone. As the arm rotates, the Bone Driven Controller node uses the arm bone motion to drive a similar rotation of the shoulder pad bone, to avoid the geometry intersection when no motion occurs on the shoulder pad bone.





Disabled Bone Driven Controller

Enabled Bone Driven Controller

Set Up

The Bone Driven Controller node operates within Component Space, so a space conversion will need to occur to implement the node within your character's Animation Blueprint.

With the Alpha property or pin, you can control the degree of the applied driven motion on the generated output pose. A value of 1 will fully use the generated output pose, while a value of 0 will output the source pose.

In the Detail panel of the Bone Driven Controller node, you first declare the Source Bone. Then in the Source Component Property, you can select the kind of motion (Translation, Rotation or Scale), and on what axis (X, Y or Z) you want to use from the Source Bone as the motion to drive the target object's motion.



With the Multiplier property you can declare a set value with which to multiply the Source Bone motion as it drives the target object.



If the Multiplier property is a value of 0, no motion will occur. The Multiplier property is ignored when a Driving Curve is selected.

You can assign a curve to modify the Source Bone motion within the Driving Curve property. Curves can provide more precise control over how the Source Bone's motion data is used to drive the target object.



If the Destination Mode property is set to Bone, an applied motion type must be defined. You can define how the Source Bone motion drives the Target Bone, by toggling the different axis of motion in the Translation, Rotation and Scale properties. You can enable any combination of these properties, and the source bone motion data will be applied to each additively.



If there are no applied motion types selected, no motion will occur.

Debug

When a Bone Driven Controller node is selected in the AnimGraph, a debug object will be drawn in the Viewport window to indicate the associated objects. A blue line will be drawn connecting the Source Bone to the target object, and a green cone will be drawn on the blue line pointed in the direction of the target object.



Property Reference



Here you can reference a list of the Bone Driven Controller node's properties.

Property

Description

Source Bone

Select the bone that will be used as the controller to drive the target object.

Source Component

Select which motion component from the Source Bone will be used to drive the target object.

You can select any axis (X, Y, Z) from the source object's Transform, Rotation and Scale components.

Driving Curve

Here you can select a curve to map the Source Bone attribute to the target object attributes. If no curve is selected, the Bone Driven Controller node will default to using the Multiplier property to determine the degree of effect the Source Bone attribute has on the target object attributes.

Remap Source

If enabled, the Bone Drive Controller node will clamp the Source Bone attribute and remap them to the curve before scaling the values.

Multiplier

Applies the assigned value as a multiplier to the Source Bone attribute to drive the target object.

Destination Mode

Select the type of object the Source Bone motion will drive. You can choose another another Bone, Morph Target or Material Parameter.

Target Bone

When Bone is selected in the Destination Mode property, you can select a bone to drive with the Source Bone.

Target Component Space

Here you can reference the Target Bone's component space.

Modification Mode

Toggle any of the Translation axes (X, Y, Z) you want driven by the Source Bone.

Translation

Toggle any of the Translation axes (X, Y, Z) you want driven by the Source Bone.

Rotation

Toggle any of the Rotation axes (X, Y, Z) you want driven by the Source Bone.

Scale

Toggle any of the Scale axes (X, Y, Z) you want driven by the Source Bone.

Modification Mode

Here you can select the method in which the Bone Driven Controller node will drive the Target Bone.

Add to Input: Will add the driven attribute values to the existing input attribute values.

Replace Component: Replaces the input attribute values with the driven attribute values.

Add to Reference Pose: Adds the driven attribute values to the character's reference pose.

Parameter Name

When the Destination Mode property is set to Morph Target or a Material Parameter, you can specify which object you want to drive with the Source Bone, by typing the name of the object in the property's field.

Animation Blueprints

Graphing in Animation Blueprints

Skeletal Controls

Skeletons

Set up

Property Reference

Button Blueprint Reference

The CCDIK (Cyclic Coordinate Descent Inverse Kinematics) Animation Blueprint node is a light-weight IK solver, that you can use to drive a chain of bones to an Effector Location. The CCDIK node is similar to the FABRIK node, but the CCDIK provides the ability to define angular constraints which can be useful if you want to limit rotations of any affected bones.



Here the CCDIK node is selected in the AnimGraph and the Effector Location is being manipulated with the debug movement tool in the viewport window.



As the Effector Location is changed the selected bone chain, highlighted with the red debug line, moves to match the Tip Bone to the Effector Location. By using a dynamic vector variable for the Effector Location, and applying rotation constraints, this node can be used to make dynamic adjustments to the Skeletal Mesh to ground the character's interactions with objects in the game world.

With the Alpha value or pin, you can control the degree of the solved motion on the generated output pose. A value of 1 will fully use the generated output pose, while a value of 0 will output the source pose.

Set up

In this example workflow, the CCDIK node will be used to dynamically adjust the characters finger to press a button in the game world.

The CCDIK node operates within Component Space, so a space conversion will need to occur to implement the node within your character's Animation Blueprint.

After adding the CCDIK node to your Animation Blueprint, select the node in the AnimGraph to open the Details panel.

In the Details panel you can select the Tip Bone, which will be the bone at the end of your chain, and the Root Bone, which will ground the adjustments to a local root bone. In this example, the Tip Bone is set to the character's left index finger (index_03_l), and the Root Bone is set to the character's left clavicle (clavical_l).



Set the Effector Location Space to World Space, to calculate the Effector Location vector variable in the level.



You can enable rotation limits by toggling the Enable Rotation Limit property and make adjustments in the Rotation Limit Per Joints property section. An Index will populate for each joint present in the skeleton between the local Root Bone and the Tip Bone. You can make adjustments to these rotations to prevent unwanted geometry overlapping and over-extension of your characters joints.



The CCDIK node will now adjust the Tip Bone, under the constraints of the Root Bone and rotation constraints, to match the location of the Effector Location, resulting in the character being able to dynamically interact with the button from any angle or height.



Property Reference



Here you can reference the CCDIK node's properties.

Property

Description

Effector Location

By default this property appears as a pin on the node in the AnimGraph. This property's value is the target point to adjust the selected Tip Bone to when solving.

Effector Location Space

Space frame of reference used by the Effector Location.

Effector Target

When the Effector Location Space is set to Bone, you can define the bone to target in this property.

Tip Bone

Select the bone from the Skeletal Mesh to adjust to meet the Effector Location.

Root Bone

Select the bone from the Skeletal Mesh to end the chain, locking the chain's motion to the local root point.

Precision

Here you can set the tolerance level for the Tip Bone adjustment to match the Effector Location. A value of 1 is the default value and is most commonly the best for your project. You can increase this value for more precise adjustment or reduce it to decrease the precision.

Max Iterations

Here you can set the maximum number of solving iterations the node can perform. A higher value will decrease performance but allow for more precise values to be calculated, a lower value will increase your project's performance but not allow for as much precision. A default value of 10 is suitable for more projects.

Start from Tail

When enabled the debug drawing of the chain will begin from the Tip Bone and end at the Root Bone.

Enable Rotation Limit

When enabled, the node will limit the rotation of each joint in the chain based on the Index values, in the Rotation Limit Per Joints property.

Rotation Limit Per Joints

Here you can define the rotation limits for each joint between the Tip Bone and the Root Bone in the chain. The starting Index will apply to the joint directly connected to the Tip Bone and sequentially work up the chain until the joint that is adjacent to the Root Bone.

Button Blueprint Reference

Here you can reference the button blueprint, the character blueprint and the character's animation blueprint used to create the button demonstration.

Button Actor Blueprint | Character Blueprint | Character Animation Blueprint



Animation Blueprints

Graphing in Animation Blueprints

Skeletal Controls

Skeletons

Property Reference

With the Copy Bone Animation Blueprint node, you can copy transform data such as Translation, Rotation, and Scale, from a Source Bone to a Target Bone.



Using a simple implementation, you can use the Copy Bone node to copy the position and motion of the Source Bone to the Target Bone. Here the character's right-hand auxiliary weapon bone (weapon_r), is selected as the Target Bone, copying the Source Bone's, the character's left hand (hand_l), position and motion. Here the effect of the Copy Bone node can be seen as it moves the weapon bone at runtime from the character's right hand to their left hand.





Copy Bone Disabled

Copy Bone Enabled

You can use this implementation of the Copy Bone node to pass an object from one of the Skeletal Mesh's hands to the other during animation playback.

In the AnimGraph, you can toggle the different components of motion, including Translation, Rotation, and Scale, to apply the Source Bone motion to the Target Bone.

With the Alpha value or pin, you can control the degree of the blend on the generated output pose. A value of 1 will fully use the generated output pose, while a value of 0 will output the source pose.

Property Reference



Here you can reference the Copy Bone node's properties.

Property

Description

Source Bone

Select a bone from the character's skeleton as the source of the motion data applied to the Target Bone.

Target Bone

Select a bone from the character's skeleton as the destination for the motion data.

Copy Translation

Applies the Translation motion from the Source Bone to the Target Bone. By default this property appears as a Boolean on the node in the AnimGraph.

Copy Rotation

Applies the Rotation motion from the Source Bone to the Target Bone. By default this property appears as a Boolean on the node in the AnimGraph.

Copy Scale

Applies the Scale motion from the Source Bone to the Target Bone. By default this property appears as a Boolean on the node in the AnimGraph.

Control Space

Select in which space the Source Bone motion is calculated and applied to the Target Bone.

World Space: copies the absolute position of the Source Bone in world space.

Component Space: copies the position and motion data of the Source Bone within the Skeletal Mesh's reference frame.

Parent Bone Space: copies the position and motion data of the Source Bone relative to the parent bone.

Bone Space: copies the position and motion data of the Source Bone within its own reference frame.

Animation Blueprints

Graphing in Animation Blueprints

Blend Nodes

Skeletal Controls

Two Bone IK

Property Reference

With the Hand IK Retargeting Animation Blueprint node, you can retarget IK bone chains, to correct fk hand locations when using animations with characters of different proportions.



Here, the same animation is playing across both Masculine and Feminine characters, as the Feminine character twists, their right arm is overextending in order to keep their hands connected to the weapon.





Masculine Character with Hand IK Retargeting Node Disabled

Feminine Character with Hand IK Retargeting Node Disabled

You can use the Hand IK Retargeting node's Hand FKWeight property to shift the prioritization weight of the set FK bone, to correct any over-extension.



Feminine Character with Hand IK Retargeting Node Enabled

In the example, the characters arms are being attached to the weapon, using a combination of the Two Bone IK nodes. The Hand IK Retargeting node is then being used to correct for the over extension of the character's left arm. The Hand FKWeight is set to a value of 0 to achieve this result.



Property Reference



Here you can reference a list of the Hand IK Retargeting node's properties.

Property

Description

Right Hand FK

Select the characters right hand bone from the characters skeleton to set as the Right Hand FK.

Left Hand FK

Select the characters left hand bone from the characters skeleton to set as the Left Hand FK.

Right Hand IK

Select the right hand IK bone from the characters skeleton to set as the Right Hand IK.

Left Hand IK

Select the left hand IK bone from the characters skeleton to set as the Left Hand IK.

IKBones to Move

Here you can select other bones to be moved. You can add bones with Add (+) and select a bone from the character's skeleton in the drop down.

Additional bones to move could be weapon bones, or other bones used for object interactions.

Hand FKWeight

Here you can set the weight to favor the right or the left hand to correct for joint popping and stretching. For example, 0 would favor the left hand, 1 would favor the right hand and 0.5 would be equal weight. By default this property appears as a pin on the Hand IK Retargeting node in the AnimGraph.

Skeletal Controls

Graphing in Animation Blueprints

State Machines

Animation Blueprints

Property Reference

With the Loot At Animation Blueprint node, you can drive a bone's rotation to follow a point of reference.



You can use the Loot At node to drive motion like head rotation to follow a reference point, and even set the reference point to follow the motion of another bone of the character's skeleton.

Here, the Look At node is set to drive the character's head to follow the character's hand. Then, the Look At Location is offset from the hand, and shown driving the motion form the offset location.



Property Reference



Here you can reference a list of the Look At node's properties.

Property

Description

Bone to Modify

Select the bone from the character's skeleton to be driven with the Look at Target and Look at Location properties.

Look at Axis

Set the axis of the Bone to Modify to point towards the Look at Target. A value of 1 will enable the axis to be factored, a value of 0 will disable the axis to be factored. A value set of (0, 0, 0) will allow a default axis to be used. You can also enable the axis to be factored in local space by enabling the Local Space property. When the Local Space property is disabled, the axis will be factored in world space.

Use Look Up Axis

When enabled, the Bound Bone will be pointed towards the Look Up Axis.

Interpolation Type

Select the interpolation type when factoring the modified motion. Options include:

Linear: Blends along a linear trajectory. Cubic: Blends along a cubic trajectory. Sinusoidal: Blends along a sine wave trajectory. Ease in Out Exponent 2: Blends in and then out, along a squared trajectory. Ease in Out Exponent 3: Blends in and then out, along a cubed trajectory. Ease in Out Exponent 4: Blends in and then out, along a quartic trajectory. Ease in Out Exponent 5: Blends in and then out, along a quintic trajectory.

Look Up Axis

When Use Look Up Axis is enabled, set the axis to align the Bone to Modify with the Look at Target. You can also enable In Local Space, to factor the axis in local space. When In Local Space is disabled, the axis will be factored in world space.

Look at Clamp

Set a clamp to limit the angles the Bound Bone can rotate on the X, Y, and Z axes.

Since the axis used as the Look at Axis is occupied, only the other axis will be used when clamping. For example, if the Look at Axis is Z, only X, Y degree of clamp will be used.

Interpolation Time

Set the duration of time, in seconds, to perform the interpolation using the Interpolation Type.

Interpolation Trigger Threshold

Set the threshold to trigger the interpolation in seconds.

Look at Target

Set a bone from the character's skeleton to use as the target socket to look at.

Look at Location

Set a reference point in world space to angle the Bone to Modify towards. When a bone is set as the Look Target, this property's value is factored in local space and used as an offset from the selected bone.

Animation Curves

Skeletal Controls

Animation Blueprints

Graphing in Animation Blueprints

State Machines

Property Reference

With the Modify Curve Animation Blueprint node, you can blend, scale and remap Animation Curves at runtime.



By right-clicking the Modify Curve node in the AnimGraph, you can select one of the character's Animation Curves from the Add Curve Pin option in the context menu to add a pin that corresponds to the selected Animation Curve.



Here, a Hue Shift curve has been added to the Modify Curve node to alter the hue of the characters material.

Description

Graph

Restults

Here the Hue Shift curve has been set to a static value of 1.0 on the Modify Curve Node in the AnimGraph. This returns a static value from the curve, resulting in the character displaying a single color material.





Here a sine wave is set to drive the Hue Shift curve value on the Modify Curve node in the AnimGraph. This returns a dynamic value, resulting in the character displaying a rotating color material.





Property Reference



Here you can reference a list of the Modify Curve node's properties.

Property

Description

Curve Map

Here you can set any curve maps. Curve maps are associative, unordered containers that associate a set of keys with a set of values. Each key in a map must be unique, but values can be duplicated.

Curve Values

Curve values are the values used to drive curve modifications. You can add a new curve by right-clicking the Modify Curve node in the AnimGraph and selecting one of the character's Animation Cures from the Add Curve Pin option in the context menu. These added curve pins can then drive their respective curves with a value.

Alpha

Set the alpha value to control the blend of the modified curve pose and the source animation pose. By default this property appears as a pin on the node in the AnimGraph.

Apply Mode

Set the method to apply the modification to the Animation Curve. The application modification options include:

Add: Add new value to input curve value. Scale: Scale input value by new value. Blend: Blend input with new curve value, using alpha setting on the node. Weighted Moving Average: Bend the new curve value with the last curve value using Alpha to determine eht weighting. For example, .5 is a moving average, higher values react to new values faster lower slower. Remap Curve: Rempas the new curve values between the Curve Values entry and 1.0. For example, .5 in Curve Values makes 0.51 map to 0.02.

Animation Blueprints

Graphing in Animation Blueprints

Skeletal Controls

Skeletons

Property Reference

With the Observe Bone Animation Blueprint node, you can watch a selected bone's translation rotation and scale motion for debug purposes.



Here a character's upperarm_l is being observed during an animation.



The node will display debug data in the AnimGraph with the coordinates of the Bone to Observe's motion. Each line of the debug data displays an element of motion data on each axis.

For example:

TX represents Translation on the X axis.

RY represents Rotation on the Y axis.

SZ represents Scale on the Z axis.

Property Reference

Here you can reference the Observe Bone properties accessible in the node's Details panel.

Property

Description

Bone to Observe

Here you can define a bone from the character's skeleton to track position and motion data.

Display Space

Here you can select what space the Bone to Observe motion is calculated.

World Space: observes the absolute position of the Bone to Observe in world space.

Component Space: observes the position of the Bone to Observe within the Skeletal Mesh's reference frame.

Parent Bone Space: observes the position of the Bone to Observe relative to the parent bone.

Bone Space: observes the position of the Bone to Observe within its own reference frame.

Relative to Ref Pose

When enabled this property will track the position and motion data of the Bone to Observe relevant to the Skeletal Mesh's reference pose, based on the space defined in the Display Space property.

Animation Blueprints

Graphing in Animation Blueprints

Skeletal Controls

AnimDynamics

Overview

Set-Up

Creating a Physics Asset

Editing the Physics Asset

Animation Blueprint

Adjustments and Tweaks

Results

Base Bone Simulation Reference

Resetting Dynamics

Property Reference

Sim Space Settings

With the RigidBody Animation Blueprint node, you can use a character's physics asset, to perform light-weight simulated physics motion of a character's auxiliary objects. This document will provide an overview of the RigidBody node and explain how you can get started using the RigidBody node, with an example workflow.



Your project contains a Skeletal Mesh character, with an Animation Sequence or Montage.

Overview

The RigidBody node performs a similar function to the Anim Dynamics node, but offers a more feature-rich physics simulation solution by enabling you to integrate a character's physics asset to have better control over the simulation. By using the RigidBody node, in conjunction with a physics asset, you can also simulate collisions with the rest of the character and any other objects in the level.

A typical use case for the RigidBody node is to simulate motion for secondary structures on the character's Skeletal Mesh, such as ponytails, chains, or other bones that are hanging or extended from the character's main body that require collision interaction with the rest of the Skeletal Mesh and the level. The RigidBody node can be used to simulate dynamic and reactive motion to these structures in real time, in a more efficient process than more performance demanding techniques, such as true physics simulation.





RigidBody Disabled

RigidBody Enabled

Set-Up

The example workflow will demonstrate how you can set-up and implement a RigidBody node in the character's animation blueprint using a physics asset to simulate dynamic and reactive motion for secondary structures on your character's Skeletal Mesh.

Creating a Physics Asset

To begin using the RigidBody node, you must first set up a physics asset for your character. A full set up guide can be found in the Creating a New Physics Asset documentation.

If your character already has an associated physics asset, you can optionally choose to make a specialized physics asset to isolate the secondary structures you are simulating motion and collision with the RigidBody node. Using a specialized physics asset with the RigidBody node can be a more optimal method to better control the behaviors of the structures during the simulation.



If your character does not have a physics asset, or you are choosing to create a specialized physics asset for use with the RigidBody node, you can create a new physics asset for your character by right-clicking the character's Skeletal Mesh asset in the Content Browser and selecting Create > Physics Asset > Create.



From the New Physics Asset window, select Create Asset to create a new physics asset for your character.

For more information about creating a physics asset please see the Creating a New Physics Asset guide.

Editing the Physics Asset

Open your character's physics asset in the Physics Asset Editor and ensure your character's physics Asset has physics bodies for the structure or structures you wish to use with the RigidBody node. In the example, physics bodies have been generated for the character's head hoses, as well as the objects the head hoses will interact with, such as the characters head, back, arms and weapon.



With default settings, collision will be disabled on all physics bodies. Enable collision on the bodies that comprise the parts of the Skeletal Mesh you wish to simulate physics motion in the Skeleton Tree by right-clicking and selecting Collision > Enable Collision All.



With all of the bodies that comprise the parts of the Skeletal Mesh you wish to simulate physics and collision selected, set their Physics Mode to Simulated in the Details panel.



Select the remaining physics bodies, and set their Physics Mode to Kinematic.



You can test the basic functionality of the physics asset with the Simulate button in the Physics Asset Editor's Toolbar.



Jittering or shaking of the simulated objects will be common at this stage, you can fix this issue by enabling and tapering the Mass (kg) property on each of the physics bodies. Start by setting the closest body to the parent structure, as the heaviest physics body, and halving the mass for each subsequent body in the chain.

In the example, the first head hose physics body was set to a mass of 2kg, and the second head hose physics body was set to a mass of 1kg.

Mass (kg) properties for Physics Bodies



Finally, on all of the bodies you are simulating motion and collision with, set a value for the Linear Damping and Angular Damping properties. Higher values will reduce motion, controlling flailing and shaking of the simulated bodies. In the example, a value of 5.0 was set for each property, but fine tuning this value, for each unique implementation, is essential to achieving ideal results.



Animation Blueprint

With a physics asset, you can now add the RigidBody node to the character's Animation Blueprint in the AnimGraph.

The RigidBody node operates within Component Space, so a space conversion will need to occur to implement the node within your character's Animation Blueprint.

By default the RigidBody node will utilize the physics asset associated with the character. If a secondary physics asset is being used, you can define the specific asset in the Rigidbody node's Override Physics Asset property in the Details panel.



Adjustments and Tweaks

More adjustments can be made using the constraints in the RigidBody node's properties (Component Liner Acc Scale, Component Linear Vel Scale, Component Applies Linear Acc Clamp and the Sim Space Settings properties), or by adjusting the location of the physics bodies in the physics asset to more closely align with the skeleton's joints.



You can also adjust the Center of Mass property on each physics body in the physics asset to align closer to the nearest skeletal joint, to further reduce shaking and excessive motion.



Results

Here you can see the final results of the simple implementation of the RigidBody node demonstrated in the example workflow.



Base Bone Simulation Reference

By setting the Simulation Space to Base Bone Space and defining a Base Bone in the RigidBody node's details panel, any joint can be used as a reference point for simulation.

Moving the entire Skeletal Mesh and individually modifying the Base Bone will have no effect on velocities. So when using a Base Bone Space as the Simulation Space, character motion will not influence the simulation.

Resetting Dynamics

The RigidBody node also supports the Reset Dynamics Blueprint node which you can use in the Animation Blueprint's EventGraph. To use the function node, get the Animation Instance from the Skeletal Mesh in Blueprint and use the function call, Reset Dynamics node to reset the simulation.



This function node can be especially useful to reset the simulation, to avoid visual and behavioral issue that could occur, for example, when teleporting a character.

Property Reference



Here you can reference a list of the RigidBody node's Settings properties.

Property

Description

Override Physics Asset

Select the physics asset to use. If empty, use the Skeletal Mesh's default physics asset.

Override World Gravity

When enabled, overrides the world gravity, to the set values on the X, Y, and Z axes.

External Forces

Applies a uniform external force in world-space. This allows for easy simulation of inertia of movement while still simulating in component-space. By default, this property appears as a pin on the node in the AnimGraph.

Component Linear Acc Scale

When using a non-world-space simulation, this property controls how much of the component's world-space acceleration is passed on to the local-space simulation.

Component Linear Vel Scale

When using a non-world-space simulation, this property applies a drag to the physics bodies in the local-space simulation, based on the component's world-space velocity.

Component Applied Linear Acc Clamp

When using non-world-space simulation, this is an overall clamp of acceleration derived from teh Component Linear Acc Scale property, to ensure it is not too large.

Cashed Bounds Scale

Scale of cached bounds (vs. actual bounds). Increasing this may improve performance, but overlaps may not work as well. (A value of 1.0 effectively disables cached bonds).

Base Bone Ref

When Simulation Space is set to Base Bone, select a bone from the character's skeleton to act as a reference point for the simulation.

Overlap Channel

The channel used to find static geometry to collide with. Options include:

World Static World Dynamic Pawn Visibility Camera Physics Body Vehicle Destructible

Simulation Space

What space to simulate the physics bodies in. This affects how velocities are generated. Options include:

Component Space: Simulate in component-space. Moving the entire Skeletal Mesh will have no effect on velocities. World Space: Simulate in world-space. Moving the Skeletal Mesh will generate velocity changes. Base Bone Space: Simulate in the selected Base Bone's bone-space . Moving the entire Skeletal Mesh and individually modifying the Base Bone will have no effect on velocities.

Force Disable Collision Between Constrained Bodies

Whether to allow collisions between two physics bodies joined by a constraint.

Transfer Bone Velocities

When simulation starts, transfer previous bone velocities from the input pose to make transition into simulation seamless.

Freeze Incoming Pose on Start

When simulating starts, freeze the incoming pose. This is useful for ragdolls, when we want the simulation to take over. It prevents nin simulated bones from animating.

Clamp Linear Translation Limit to Ref Pose

Correct for lineratearing on bodes with all axes locked. This only works if all axes linear translation are locked.

World Space Minimum Scale

For world-space simulations, if the magnitude of the component's 3D scale is less than world-space minimum scale do not update this mode.

Evaluation Rest Time

If the node is not evaluated for this amount of time(seconds), either because a lower LOD was in use for a whole or the component was not visible, rest the simulation to the default pose on the next evaluation. Set to 0 to disable time-based rest.

Sim Space Settings

The RigidBody node's Sim Space Settings Settings control the motion passed from the simulation's space into the simulation. This allows the simulation to pass a fraction of the world-space motion onto the physics bodies which allows Bone-Space and Component-Space simulations to react to world-space movement in a controllable way.

This system is a superset of the functionality provided by the Component Liner Acc Scale, Component Linear Vel Scale and Component Applied Linear Acc Clamp. For most cases you should not have both systems enabled.



Here you can reference a list of the RigidBody node's Sim Space settings properties.

Property

Description

Master Alpha

Global multiplier on the effects of simulation space movement. But be in range [0, 1]. If the Master Alpha is set to 0, the system is disabled and the simulation will be fully local, for example, world-space actor movement and rotation does not affect the simulation. When Master Alpha is set to 1, the simulation effectively acts as a world-space simulation, but with the ability to apply limits to other parameters.

Velocity Scale Z

Multiplier on the Z-Component of velocity and acceleration that is passed to the simulation. Usually from 0.0 to 1.0 to reduce the effects of jumping and crouching on the simulation, but it can be higher than 1.0 if you need to exaggerate this motion.

Max Linear Velocity

A clamp on the effective world-space velocity that is passed to the simulation. Units are cm/s. The default value effectively means "unlimited". It is not usually required to change this but you would reduce this to limit the effects of drag on the physics bodies in the simulation (if you have bodies that have linear drag set to non-zero in the physics asset). Expected values in this case would be somewhat less than the usual velocities of your object which is commonly a few hundred for a character.

Max Angular Velocity

A clamp on the effective world-space angular velocity that is passed to the simulation. Units are radian/s, so a value of about 6.0 is one rotation per second. The default value effectively means "unlimited". You would reduce this (and Max Angular Acceleration) to limit how much bodies fly out when the actor spins on the spot. This is especially useful if you have characters that can rotate very quickly and you would probably want values around or less than 10 in this case.

Max Linear Acceleration

A clamp on the effective world-space acceleration that is passed to the simulation. Units are cm/s/s. The default value effectively means "unlimited". This property is used to stop the physics bodies of the simulation flying out when suddenly changing linear speed. It is useful when you have characters that can change from stationary to running very quickly such as in an FPS. A common value for a character might be in the few hundreds.

Max Angular Acceleration

A clamp on the effective world-space angular acceleration that is passed to the simulation. Units are radian/s/s. The default value effectively means "unlimited". This has a similar effect to Max angular velocity, except that it is related to the flying out of bodies when the rotation speed suddenly changes. Typical limits for a character might be around 100.

External Linear Drag V

Additional linear drag applies to every body in addition to linear drag specified on them in the physics asset. When combined with external linear velocity, this can be used to add a temporary wind-blown effect without having to tune linear drag on all the bodies in the physics asset. The result is that each body has a force equal to (- External linear drag v * external linear velocity) applied to it, in addition to all other forces. This vector is in simulation local-space.

External Linear Velocity

Additional velocity is added to the component velocity so the simulation acts as if the actor is moving at speed, even when stationary. Vector is in world-space. Units are cm/s. Could be used for wind effects ext. Typical values are similar to the velocity of the object or effect, and usually around or less than 1000 for characters / wind.

External Angular Velocity

Additional angular velocity that is added to the component angular velocity. This can be used to make the simulation act as if the actor is rotating even when it is not. For example, to apply physics to a character on a podium as the camera rotates around it, to emulate the podium itself rotating. Vector is in world-space. Units are radian/s.

Animation Blueprints

Animation Node Reference

Skeletons

Skeletal Controls

Graphing in Animation Blueprints

Blueprint Splines

Landscape Splines

Property Reference

With the Spline IK Animation Blueprint node, you can define a chain of bones within a character's skeleton, as a spline.



After selecting the chain of bones as a spline the Spline IK node will create Control Points along the spline based on the parameters you set in the nodes Details panel.



You can manually manipulate these Control Points to set locations for the spline to react to during animation playback. You can also drive these control points with dynamic values with internal functions or as pins in the AnimGraph. In addition, you can drive several Spline IK node properties, such as twist, roll, and stretch, using dynamic values in the same manner.

You can use the Spline IK node to create more realisting motion for tails or other malleable character structures that can be influenced by dynamic variables like velocity and movement direction.



Property Reference



Here you can reference a list of the Spline IK node's properties.

Property

Description

Start Bone

Select a bone from the character's skeleton to begin the chain of bones that will comprise the spline.

End Bone

Select a bone from the character's skeleton to end the chain of bones that will comprise the spline.

Bone Axis

Select the Axis of motion (X, Y, or Z) the control points along the spline will move along.

Auto Calculate Spline

Enable this property to automatically calculate the number of Control Points based on the number of bones between the Start Bone and the End Bone.

Point Count

When Auto Calculate Spline is disabled you can specify how many Control Points will be added along the spline between the Start Bone and the End Bone.

Control Points

Here you can apply transforms to each of the Control Points along the spline. By default, these transforms can be applied manually in the viewport or with the transform properties under each array element for each control point. These properties can also be adjusted dynamically by exposing the Control Points as pins in the AnimGraph, or by using internal functions.

Roll

Set a degree of rotation of the Control Points between the Start Bone and the End Bone applied on top of the other motion along the direction of the spline. A value of 0 will disable an additional roll, positive values will roll the middle Control Points positively along the Bone Axis and negative values will roll the middle Control Points negatively along the Bone Axis.

Twist Start

Set a degree of twist the first Control Point (Control Point 0) applied on top of the other motion along the direction of the spline. A value of 0 will disable twist, positive values will twist the start Control Point positively along the Bone Axis and negative values will twist the start Control Point negatively along the Bone Axis.

Twist End

Set a value of the twist on the last Control Point (highest numerical Control Point X) applied on top of the other motion along the direction of the spline. A value of 0 will disable twist, positive values will twist the end Control Point positively along the Bone Axis and negative values will twist the end Control Point negatively along the Bone Axis.

Twist Blend

Select the properties of twist applied to the Twist Start and Twist End.

Blend Time: Set the time, in seconds, to blend between twist poses.

Blend Option: Select the type of blending used to blend between twist poses.

Custom Curve: Here you can set a curve to drive the blending between twist poses.

Stretch

Set the maximum stretch allowed when fitting bones to the spline. A value of 0.0 will disable stretch of the structure along the length of the spine. A value of 1.0 will enable the structure to fully stretch to the length of the spline.

Offset

Set the distance offset along the spline from the Start Bone from which bones are constrained. A value of 0 will not offset the structure, higher values will offset the structure twords the End Bone.

Animation Blueprints

Animation Node Reference

Skeletons

Skeletal Controls

Graphing in Animation Blueprints

Property Reference

With the Spring Controller Animation Blueprint node, you can apply a controlled stretch to bone from a character's skeleton.



Here is an example of the Spring Controller node being used to simulate movement of non-animated bones by applying a force in the opposite direction for the character's motion.





Spring Controller Disabled

Spring Controller Enabled

Property Reference



Here you can reference a list of the Spring Controller node's properties.

Property

Description

Spring Bone

Select the bone from the character's skeleton to apply the Spring Controller node to.

Max Displacement

Set the maximum distance the bone can stretch from the reference pose location, in Unreal Engine units, when Limit Displacement is enabled.

Spring Stiffness

Set a multiplier value used to calculate the stiffness of the spring. Larger values require more bone velocity to displace the bone and result in a larger applied force with quicker reactive movements.

Spring Damping

Set a multiplier to reduce the Spring Bones's velocity, to create smoother and more controlled results.

Error Reset Thresh

Set a threshold to reset the Spring Bones in Unreal Engine units. If the Spring Bone stretches more than this amount, it resets in order to avoid errors introduced by sudden, large displacements such as those caused by teleporting Actors.

Limit Displacement

When enabled the Max Displacement property will be considered.

Animation Blueprints

Graphing in Animation Blueprints

Skeletal Controls

Property Reference

Limit Properties

Debug Properties

Using the Trail Controller Animation Blueprint node, you can define a chain of bones to animate based on a delayed replication parent bone motion.



You can use the Trail Controller node to create more realistic trailing motion on your character's auxiliary boned objects, such as tails, capes or accessories.



By defining a bone as the Trail Bone, you can select how many bones up the chain from the Trail Bone that will be influenced by the Trail Controller node. You can then set constraints on Stretch, Rotation and even Planer Limits on transforms.

Property Reference



Here you can reference a list of the Trail Controller node's Trail properties.

Property

Description

Trail Bone

Set the bone at the end of a chain structure to trail the parent bone motion.

Chain Length

Set the number of bones to influence up the chain from the Trail Bone.

Chain Bone Axis

Set the axis (X, Y, or Z) to orient the chain points to one another.

Invert Chain Bone Axis

Set a scale alpha to apply the Relation Speed Scale Input Processor properties. A value of 0 will disable the effect, while a value of 1 will fully enable the effect. Values greater than 1 will act as a multiplier.

Trail Relaxation Speed

Here you can use the Trail relaxation speed graph to set a curve to define the behavior at which the transform returns to the animated pose.



Using the graph editor in the property's settings, you can edit the beginning and ending point of the graph to control how the behavior of the chains return to the animated pose. Or right click the graph to add a new point on the graph to manipulate the curves position.

The graph's X-axis is ranged from 0 to 1, and it is mapped to the chain of joints. 0 represents the last joint in the chain and 1 represents the closest joint to the Trail Bone.

The graph's Y-axis controls the rate at which the delayed motion is passed to the next joint in the chain. Values less than or equal to 0 will prevent joints from continuing to pass the delayed motion. Higher values will pass the delayed motion on quickier. The Y-axis operates as an absolute value to prevent frame dependency. The default range is from 5 to 10 resulting in a faster return from the root joint to the bottom joint.

Limit Properties



Here you can reference a list of the Trail Controller node's Limit, Velocity and Rotation properties

Property

Description

Limit Stretch

Enable a constraint on the structures stretching. This constraint can be set in the Stretch Limits property.

Limit Rotation

Enable rotation constraints and offsets on each chain point. Rotation constraints can be set on each chain point using the Indexes within the Rotation Limits property.

Use Planer limit

Enable planer constraints to eliminate motion past set planes. These planes can be added and set in within the Planer Limits property.

Max Delta Time

To avoid hitches caused by stretching the chain, you can use this property to clamp the length of the delta time. For example, if you want a 30 fps trail animation playback, set this property to 0.03333f (or 1/30).

Rotation Limits

Set the rotation limits at each joint along the chain points. The highest Index number represents the Trail Bone and Index 0 represents the furthest bone from the Trail Bone in the chain.

Limit Min: Set the minimum range of rotation on the X, Y and Z axis. Limit Max: Set the maximum range of rotation on the X, Y and Z axis.

Rotation Offsets

Set a rotational offset, in degrees, for each joint's X, Y, and Z axes, along the chain. The highest Index number represents the Trail Bone and Index 0 represents the furthest bone from the Trail Bone in the chain.

Planer Limits

Add and set planer limits to constrain the chain's motion from crossing a plane. After adding a planer limit with Add (+), you can adjust the following properties to set up a plane limit:

Driving Bone: Select a bone from the character's skeleton that will become the reference point to set the Plane Transform properties. Plane Transform: Set the planer properties, Location, Rotation, and Scale, to limit the chain's motion, in context to the Driving Bone.

Stretch Limits

Select how far the chain structure can stretch from the reference pose. A value of 0 will disable stretching, while values greater than 0 will increase the amount of stretching that is possible.

Actor Space Fake Vel

When enabled, simulated velocity will be applied in actor-space. When disabled, simulated velocity will be applied in world-space.

Fake Velocity

Here you can set the the simulated velocity vector that will be applied to the Base Joint.

Base Joint

Here you can select a bone from the character's skeleton to serve as the base joint that can receive a simulated velocity vector to apply motion to the chain.

Reorient Parent to Child

When enabled, child bones are free to rotate to preserve the structure integrity.

Last Bone Rotation Anim Alpha Blend

This property controls the blend between the parent joint of the structure and animated pose. With a value of 0, the last joint will copy the previous joints alpha. A value of 1 will use the animated pose.

Debug Properties



Here you can reference a list of the Trail Controller nodes Debug properties.

Property

Description

Enable Debug

Enables debug drawing in the preview viewport.

Show Base Motion

Draws red lines that follow the basic transform path, (X, Y and Z axes) of the structure. A dot will be drawn on the line to indicate the location of the joint before the application of any motion.

Show Trail Location

Draws color coded sections of lines, to delineate different segments of the chain, between each joint in the chain.

Show Limit

Draws any planer limits.

Debug Life Time

This value determines the duration of time any debug feature remains drawn in the viewport, in seconds.

Animation Blueprints

Graphing in Animation Blueprints

Skeletal Controls

Skeletons

Property Reference

You can use the Transform (Modify) Bone Animation Blueprint node to transform (Translation, Rotation, and Scale) a specified bone.



After selecting a bone to control with the Bone to Modify property, you can select the kind of transform mode within the Translation, Rotation, and Scale property sections. Here the character's upperarm_l has been selected and additive transforms are being made using the controller in the viewport.



The Transform Bone node operates within Component Space, so a space conversion will need to occur to implement the node within your character's Animation Blueprint.

Property Reference



Here you can reference a list of the Transform Bone node's properties.

Property

Description

Bone To Modify

Select a bone from the character's skeleton to control with the Transform Bone node.

Translation

Control the translation of the selected bone. By default the translation coordinates are controllable in the AnimGraph.

With the Translation Mode property you can set the node to Ignore the modifications made by the node, retaining any existing translation on the bone, Replace Existing to replace any translation on the bone with the translation the node is performing, and Add to Existing which will add the Transform Bone's translation to any existing Translation on the bone.

You can also set the Translation Space of the node to control the space the translation is applied. You can set the following options:

World Space: Applies the translation based on the absolute position in world space.

Component Space: Applies the translation based on the bones position in relation to the Skeletal Mesh's reference frame.

Parent Bone Space: Applies the translation based on the bones position in relation to its parent bone.

Bone Space: Applies the translation based on the bone's own reference frame.

Rotation

Control the rotation of the selected bone. By default the rotation coordinates are controllable in the AnimGraph.

With the Rotation Mode property you can set the node to Ignore the modifications made by the node, retaining any existing rotation on the bone, Replace Existing to replace any rotation on the bone with the rotation the node is performing, and Add to Existing which will add the Transform Bone's rotation to any existing rotation on the bone.

You can also set the Rotation Space of the node to control the space the rotation is applied. You can set the following options:

World Space: Applies the rotation based on the absolute position in world space.

Component Space: Applies the rotation based on the bones position in relation to the Skeletal Mesh's reference frame.

Parent Bone Space: Applies the rotation based on the bones position in relation to its parent bone.

Bone Space: Applies the rotation based on the bone's own reference frame.

Scale

Control the scale of the selected bone. By default the scale coordinates are controllable in the AnimGraph.

With the Scale Mode property you can set the node to Ignore the modifications made by the node, retaining any existing scale on the bone, Replace Existing to replace any scale on the bone with the scale the node is performing, and Add to Existing which will add the Transform Bone's scale to any existing scale on the bone.

You can also set the Scale Space of the node to control the space the scale is applied. You can set the following options:

World Space: Applies the scale based on the absolute position in world space.

Component Space: Applies the scale based on the bones position in relation to the Skeletal Mesh's reference frame.

Parent Bone Space: Applies the scale based on the bones position in relation to its parent bone.

Bone Space: Applies the scale based on the bone's own reference frame.

Animation Blueprints

Graphing in Animation Blueprints

Skeletal Controls

Skeletons

Overview

Example Workflow

Property Reference

With the Twist Corrective Animation Blueprint node, you can drive Animation Curves, like Morph Targets, using the transform of a delta angle calculated using a Base Frame and Twist Frame against the direction of a Twist Planer.



Overview

Using the Twist Corrective node, you can drive Animation Curves values, such as Morph Targets, based on the twist of one bone relative to another.

Here is an example of a character's scarph morph targets adjusting as the head bone is twisted, to create a more natural look.





Disabled Twist Corrective

Enabled Twist Corrective

Example Workflow

The Twist Corrective node operates within Component Space, so a space conversion will need to occur to implement the node within your character's Animation Blueprint.

First, you must select a bone to act as the Base Frame, to calculate the twisting bone's alpha from. It is also important to define on what axis the motion the twist alpha will be in reference to. In the Axis property define which axis the motion will occur by setting the value to 1. In the provided example the neck_02 bone was used and the Z-axis was given a value of 1.



Next select the bone that is undergoing the twist motion as the Twist Frame Bone, in the example the head bone is used. You must also define the axis of motion, in this case the property will replicate the Base Frame Axis with only a value of 1 on the Z-Axis.



You must also set the twist plane as a reference point, to calculate the alpha motion. In the example, the Y-Axis was enabled by setting a value of 1 in the Y-Axis field.



Finally, you must input the name of the Animation Curves. In the workflow example, the morph target C_BipedHeadNeck_A_NeckMid_Jnt_n11_44_n1 is used.



After compiling the Animation Blueprint the effects should be visible as the head bone rotates on the Z-Axis in the viewport.

Property Reference



Here you can reference a list of the Twist Corrective node's properties.

Property

Description

Base Frame

The Base Frame series of properties defines the reference point to calculate the motion alpha of the Twist Frame.

In the Bone property, you can select the bone to use as the Base Frame from the characters skeleton.

In the Axis property, you can select what axes of motion to calculate motion. A value of 0 will not calculate motion, a value of 1 will calculate positive motion, and a value of -1 will calculate negative motion.

You can also enable the In Local Space property to calculate motion in local space, or disable In Local Space to calculate motion in world space.

Twist Frame

The Twist Frame series of properties defines the twisting bone to calculate the motion alpha from in relation to the Base Frame and Twist Planer Normal Axis.

In the Bone property, you can select the bone to use as the Twist Frame from the characters skeleton.

In the Axis property, you can select what axes of motion to calculate motion. A value of 0 will not calculate motion, a value of 1 will calculate positive motion, and a value of -1 will calculate negative motion.

You can also enable the In Local Space property to calculate motion in local space, or disable In Local Space to calculate motion in world space.

Twist Planer Normal Axis

Here you can set the normal of the plane to calculate the angle alpha of the Twist Frame from the Base Frame.

In the Axis property, you can select what axes of motion to calculate motion. A value of 0 will not calculate motion, a value of 1 will calculate positive motion, and a value of -1 will calculate negative motion.

You can also enable the In Local Space property to calculate motion in local space, or disable In Local Space to calculate motion in world space.

Max Angle in Degree

Set the maximum limit of the twist that will output a value to the Curve. For example, the degree at which the twist should result in the maximum curve value being outputted. Values cannot exceed 180.

Mapped Range Min

Minimum value to apply to the curve. A value of 0 being the beginning of the curve and a value of 1 being the end of the curve.

Mapped Range Max

Maximum value to apply to the curve. A value of 0 being the beginning of the curve and a value of 1 being the end of the curve.

Curve

Input the name of the Curve or Morph Targets you wish to apply the Mapped Range Min and Mapped Range Max based on the calculated twist alpha from the Twist Frame Bone.

Graphing in Animation Blueprints

Blend Nodes

Skeletal Controls

Animation Blueprints

Property Reference

With the Two Bone IK Animation Blueprint node, you can control two-bone chains, such as a Skeletal Mesh, character's limbs, to make contact with the Effector Location or an end point, using the Joint Target Location reference point to control the bone chain's middle point.



With the Two Bone IK node's Effector Location, you can drive the position of the bone at the end of the two-bone chain. This property can be set in the AnimGraph to follow the location of a socket on an interactable object, or make a grounded contact point with a point in the level.



With the Two Bone IK node's Joint Target Location, you can set the location of the bone chain's middle joint, to control the rotation behavior of the bone chain.



You can also set other properties such as Stretching and Twisting to control the behavior of the two-bone chain.

Property Reference



Here you can reference the Two Bone IK node's properties.

Property

Description

Enable Debug Draw

When enabled, debug tools will be drawn in the preview viewport. The Effector Location will be represented with a red object, and the Joint Target Location will be drawn as a green object. Lines will also be draw from each bone position, including the chain's root bone, to the Joint Target Location to show their position.

IK Bone

Set a bone from the character's skeleton as the bone to control.From this bone, the node will consider two bones up the chain, to build the two-bone chain. The first parent bone will act as the joint, and the second parent bone will become the root for the chain.

Start Stretch Ratio

When the Allow Stretching property is enabled, you can set the threshold to control when the two-bone chain is able to begin stretching. This value determines when to start stretching. For example, 0.9 means once it reaches 90% of the whole length of the limb, it will start to apply a stretch to the structure.

Max Stretch Scale

When the Allow Stretching property is enabled, you can set the limit to control the maximus scale of the stretch allowed for the structure. This value determines what is the max stretch scale. For example, 1.5 means it will stretch until 150% of the whole length of the limb.

Twist Axis

When the Allow Twist property is disabled, you can specify which axis (X, Y, and Z) the bone is aligned to. This property is most helpful when isolating twists for a structure. When the Allow Twist property is disabled, You can also enable the twist to be calculated in local-space.

Allow Stretching

When enabled, stretching of the set two-bone chain will be allowed. You can set the limits of the stretching in the Start Stretch Ratio and the Max Stretch Scale properties.

Maintain Effector Rel Rot

Keep local rotation of the end bone.

Allow Twist

When enabled, the bone chain will perform under normal structure constraints. When disabled, you can manually set the axes of twist that the structure will be allowed to twist on, in the Twist Axis property.

Effect Location Space

Here you can set the frame of reference to calculate the position of the Effector Location. You can set the reference frame from the following options:

World Space: The Effector Location's absolute position will be calculated using world space. Component Space: The Effector Location's set position will be calculated in the Skeletal Mesh component's reference frame. Parent Bone Space: The Effector Location's set position will be calculated in the parent bone space of the bone set as the Effector Target. Bone Space: The Effector Location's set position will be calculated in the reference frame of the bone set as the Effector Target.

Take Rotation from Effector Space

When the Effector Location Space property is set to Parent Bone Space or Bone Space you can enable this property to take the rotation of the effector location and apply it to the IKBone. When disabled, rotation will be ignored.

Effector Target

When the Effector Location Space property is set to Parent Bone Space or Bone Space you can select a bone from the character's skeleton to use as the Effector Location.

Effector Location

By default this property appears as a pin on the Two Bone IK node in the AnimGraph. The Effector Location drives the two-bone chain end point's location. When the Enabled Debug Draw property is enabled this property will appear as a red object in the preview viewport.

Joint Target Location Space

Here you can set the frame of reference to calculate the position of the Joint Target Location. You can set the reference frame from the following options:

World Space: The Joint Target Location's absolute position will be calculated using world-space. Component Space: The Joint Target Location's position will be calculated using the Skeletal Mesh Component's reference frame. Parent Bone Space: The Joint Target Location's position will be calculated using the parent bone space of the bone set as the Joint Target. Bone Space: The Joint Target Location's position will be calculated in the reference frame of the bone set as the Joint Target.

Joint Target

When the Joint Target Location Space property is set to Parent Bone Space or Bone Space, you can select a bone from the characters skeleton to use as a reference space to calculate the set position of the Joint Target Location.

Joint Target Location

By default this property appears as a pin on the Two Bone IK node in the AnimGraph. With the Joint Target Location you can control the motion and behavior of the two-bone chain's middle joint. The Joint Target acts as a reference point to bend the joint. When the Enabled Debug Draw property is enabled this property will appear as a green object in the preview viewport.

Overview

Creating and Managing Slots

Using Slots

In Animation Montages

In Sequencer

Slot Groups

As you create more complex Animation behavior for your characters, it may be necessary to create proxy areas in your Animation Blueprint where you can insert one-off animations. This can be accomplished by using Slots, which are nodes that you can add to your Animation Blueprint at various points to layer and play animations into. Slots are mainly used together with Animation Montages, however they can also be used with Sequencer.

This document provides an overview of how to create and use Animation Slots in your Animation Blueprint, Montages, and Sequencer.

You are familiar with how to graph within Animation Blueprints.

Overview

The main purpose of Slots is to provide a place in the Anim Graph to insert animations into your Animation Blueprint. This can be useful when using Animation Montages as a way to insert one-off animations, such as shooting or interacting with objects. Slots can also be used together with blending nodes to separate playback to only occur on certain Bones on your character, such as upper body or arms.

For example, in this setup, Slots are used in the following two ways:



A Full Body Slot is used after the main locomotion State Machine, which can insert animations in an overriding manner. This Slot can be used for full-body object interaction or emote gestures.

An Upper Body Slot is used together with a Layered blend per bone node to remove animation on the lower body so that only the upper body is affected. This Slot can be used for weapon reloading, shooting, or other similar animations which can work correctly regardless of your character's locomotion state.

Creating and Managing Slots

Slots are created and managed from the Anim Slot Manager, which is a panel that can be opened from the Animation Blueprint, Skeleton, or Animation Sequence Editors. To open the panel, in any one of those editors, go to Window > Anim Slot Manager from the main menu.



By default, all Skeletons come with a starting Slot named DefaultSlot. To add a new Slot, click Add Slot (+), type in a name for the Slot, then press Enter.



Regardless of the animation editor you are in, Slots are stored on the Skeleton Asset, therefore, when you are creating or changing Slots, you are also editing the Skeleton. Clicking Save in the Anim Slot Manager will save the Skeleton when you make any Slot changes.

Right-clicking in the Anim Slot Manager or on Slot entries will show the following context menu commands:



Name

Description

Set Slot Group to

Moves the selected Slot to a different Slot Group, if one is available.

Rename Slot

Renames the selected Slot.

Delete Slot

Deletes the selected Slot.

Add Slot

Creates a new Slot.

Add Group

Creates a new Slot Group.

Using Slots

Before you start using Slots, you must first ensure they are added to your Animation Blueprint.

In the Anim Graph, right-click and add the Slot ‘DefaultSlot' node.



By default, newly created Slot nodes will use DefaultSlot. To change this, select the node and set the Slot Name property in the Details panel to your desired Slot.



Slots are designed to support incoming source pose links so that the Slot passes through the incoming pose if animations are not being inserted into it. The Slot only begins to override the incoming animation with its own once animation starts playing on the Slot.

Once an incoming source pose is overridden, it will no longer evaluate. You can change this to ensure the incoming animation keeps evaluating by enabling Always Update Source Pose in the Slot's Details panel.



In Animation Montages

Animation Montages require Slots in your Anim Graph to function, as they exclusively play animation using Slots. In this example, an Animation Montage will apply this animation to the Upper Body Slot.



To change or add Slots to the Montage, click the Slot dropdown menu on the Slot track to view the following commands:



Name

Description

Slot name

Exposes a menu where you can change the current Slot. If this is the topmost Slot track, then selecting a Slot that is part of a different Slot Group will change the Montage's Slot Group.

New Slot

Adds a new Slot Track using a pre-existing Slot.

Delete Slot

Deletes the Slot.

Duplicate Slot

Duplicates the Slot track and its contents into a new Slot track.

Preview Slot

If you have more than one Slot track, enabling this will cause the contents of this Slot to preview in the Viewport.

Slot Manager

Opens the Slot Manager panel.

A single Montage can play animations on multiple Slots at the same time, but they must be within the same Slot Group.

Refer to the Animation Montage page for more information on using Animation Montages.



Animation Montages are animation assets that enable you to combine animations in a single asset and control playback using Blueprints.

Animation Montages are animation assets that enable you to combine animations in a single asset and control playback using Blueprints.

In Sequencer

Slots can also be used in Sequencer, which is Unreal Engine's cinematic and movie-making tool. Using Slots in Sequencer enables inserting cinematic animation within an Animation Blueprint, so that your characters can benefit from its additional logic.

Slots are used for animations in the Animation Track. To set an animation to play from a Slot, right-click an animation section and navigate to Properties > Slot Name. Enter the name of the Slot you want to insert this animation into.



A common use-case for using Slots in Sequencer is to blend cinematic and gameplay animation together. Refer to the Blending Gameplay and Sequencer Animation page to learn more.



Illustrates how you can blend animation smoothly from gameplay into a Level Sequence based animation.

Slot Groups

In addition to Slots, you can also create Slot groups to organize and control Slot playback within Animation Montages.

A DefaultGroup Slot group will already exist on your Skeleton. To create another Slot group, click Add Group (+) in the Anim Slot Manager, type in a name for the Slot group, then press Enter.



An existing Slot can be moved to a different Slot group by right-clicking it and selecting Set Slot Group to.



Slot groups are not just organizational. When you play a montage that uses a Slot in the same group as one that's already running, it stops the active one. This automatic behavior allows for montages to be interrupted. For example, a weapon reloading montage could be interrupted to play an ability or melee attack montage. If both montages are playing animations on Slots within the same group, then the most recent montage will interrupt the previous.

To learn more about using Slot groups in Animation Montages, refer to the Animation Montage page.

Overview

Sync Settings

Sync Group Types

Group-Based Syncing

Marker-Based Syncing

Graph-Based Syncing

To improve blending behavior in Animation Blueprints, Sync Groups can be used to automatically synchronize the related animation's lengths and playback during the blend. This can be useful when blending between walking and running cycles of different lengths. In such a case, directly blending from one to the other without Sync Groups could cause unnatural results as the feet placement may not be synchronized.

This document provides an overview of the Sync Group system in Animation Blueprints.

Sync Groups are created and managed in Animation Blueprints, therefore you should have a basic knowledge working in this editor.

Overview

Sync Groups work with the concept of roles, in which one animation is the leader while all other animations are followers. Leaders provide the master animation length that is used by all followers and have priority for triggering Animation Notifies. Followers match their animation lengths to leaders and have their notifies suppressed.

By default during the blend, leader and follower assignment can change based on the weight distribution. The animation with the highest blend influence is considered the leader.

Image

Description



As an example, you can compare a walk and run cycle animation. Typically these animations may not match in length. Without Sync Groups, the general body movement cycles of these animations will not align.



When using Sync Groups, and with the run cycle as leader, this will cause the walk cycle to adjust its playback speed to match the leader. In this case, the walk cycle is being shortened to play faster to match the run cycle.



When using Sync Groups, and with the walk cycle as leader, this will cause the run cycle to adjust its playback speed to match the leader. In this case, the run cycle is being lengthened to play slower to match the walk cycle.

Due to the nature of synchronizing animations with Sync Groups, there are certain animation restrictions that you should consider when using animations in this way:

Ensure that all animations being synchronized have the same general body movement from the start to the end. For walk and run animations, this might mean ensuring that the same feet are being planted at the start and ending frames.



Also ensure that there are no drastic length differences between the animations that are blending. This may result in some animations playing noticeably faster than others, as well as causing noticeable playrate "pops" when leader and follower animations switch.

Sync Settings

When syncing animations in a variety of ways, you can edit the behavior with the following settings found in the Details panel.

Name

Description

Group Name

Defines the name of the Sync Group. Generally, you will want all related animations that are meant to blend together (such as body motions for sneak, walk, run, sprint) to have the same name, causing them to be in the same Sync Group.

Group Role

Specifies certain leader and follower rules for this animation. You can select from the following:

Can be Leader, which is the default behavior, and when selected causes this animation to be the leader as long as it has the highest blend weight.

Always Follower, which causes this animation to always follow the Sync Group leader. If all animations are set to this, then the first animation evaluated will be set to the leader.

Always Leader, which causes this animation to always be the leader. If more than one animation in the group is set to this option, then the last one evaluated will be set to the leader.

Transition Leader, which causes this animation to be excluded from syncing while blending in. Once blended in it will become the Sync Group leader until blended out.

Transition Follower, which causes this animation to be excluded from syncing while blending in. Once blended in it will become a follower until blended out.

Method

Defines how syncing is determined. You can select from the following:

Do Not Sync, which is the default setting and causes no animation syncing to occur.

Sync Group, which will enable Group-Based Syncing.

Graph, which will enable Graph-Based Syncing.

Sync Group Types

There are several ways to set up Sync Groups, you can choose from the following types.

Group-Based Syncing

Group-Based Syncing groups animations together by name. To create a group-based Sync Group, select the animation nodes to sync in the AnimGraph and locate the Sync category in the Details panel. Set the following properties:

Set Method to Sync Group.

Type a name in Group Name. The Group Name must match for all animations you want to sync.



Your animations now sync when blending. You can preview this behavior by connecting them to a Blend node and setting the Alpha to 0.5.





Group Sync Off

Group Sync On

When using Sync Groups with Animation Nodes, the node will display a text watermark for the sync method, and the group name.



Marker-Based Syncing

In addition to Sync Groups, animations can be synchronized using Sync Markers within Animation Sequences. This causes the playback of animations to synchronize based on the relative position of playback between markers placed along the timeline of animations.

This can be useful for a variety of blending conditions:

When general body movement does not have a matching number of steps. For example, when blending a run cycle that has the right foot touching the ground four times, and the walk cycle's foot only touches the ground two times.

When the stride lengths are not the same. For example, when blending a time-rigid marching walk animation to a time-loose scramble running animation.

When blending with non-looping animations, such as run and walk starts and stops. Additionally with this case, the start and stop animations should be set to Always Leader.



To add a Sync Marker, right-click within an Animation Notify timeline and select Add Sync Marker... > New Sync Marker…. Next, type in the name of the Sync Markers and press Enter.



Once a Sync Marker has been added, it will be saved to the Skeleton. Once added, you can easily reuse Sync Marker names on different animations, ensuring that the same names are being used and standardized. Saved Sync Markers can be added by right-clicking in the notify timeline and selecting Add Sync Marker... > Existing Sync Markers, then selecting a Sync Marker from the list.



Sync Markers will only synchronize with other markers if the animations are in the same Sync Group. This means you must ensure that both Sync Marker and Sync Group names match.

Animation Montages also support marker-based syncing while blending out, so you can transition back to other animations seamlessly. In the Animation Montage Editor, navigate to the Sync Group properties in the Asset Details Panel to edit the relevant sync properties.



Other elements to consider when using Sync Markers are:

Only markers common to all animations within a group are synced. For example, if one animation is missing "Right Foot Down" markers, then those markers will be ignored for all animations when determining that frame's position.

Marker-based syncing is used automatically when animations in a Sync Group have matching markers. Otherwise, the system will fall back to normal length syncing behavior.

Graph-Based Syncing

When building complex Animation Blueprints, it can become tedious to manage name-based sync groups. You can instead use Graph-Based Syncing to propagate a single Sync Group to various sub-graphs and child nodes. Graph-Based Syncing requires children nodes and graphs that have their Method property set to Graph.



The first method of using Graph-Based Syncing is by creating the Sync node. This node propagates sync behavior to all incoming pose nodes that have their Method property set to Graph. To add a Sync node to your graph, right-click and select Sync from the Misc. category.



Typically, you may want to place this node after your pose logic, so that it can synchronize all incoming animation data.



In addition to the Sync node, Blend Space Graphs also provide graph syncing functionality. This will cause the sync behavior to propagate to all children samples within the graph.

Similar to the Sync node, Blend Space Graphs require a Group Name in order for the sync behavior to propagate.



By default, Sequence Players generated in Blend Space Graph samples will default to using the Graph sync method, to accept synchronization from the Blend Space Graph node.



Linked Anim Graph

Creation and Overview

Input Pose

Input Variables

Linked Anim Layer

Animation Layer Interface

Base Blueprint Setup

Specific Blueprint Setup

Linking Anim Layers

Additional Use Case Example

Animation Blueprint Templates

Template Usage

As you start to create more and more complex Animation Blueprints for your characters, there may be times when you want to reuse portions of an Animation Blueprint within another Animation Blueprint. There are a variety of ways you can do this, from linking specific Animation Blueprints, linking Animation Layers, or using Templates.

This document provides an overview of modularizing your Animation Blueprints in various ways.

You have created and have an understanding of Animation Blueprints.

Linked Anim Graph

Within an Animation Blueprint, you can reference another one by using the Linked Anim Graph node.

Creation and Overview

To create this node, right-click in the Anim Graph and select Linked Anim Graph from the Linked Anim Blueprints category. You can also select a specific Animation Blueprint reference from this list to add the node and reference it.



The node contains the following properties in the Details panel. These settings also apply for Linked Anim Layer nodes:



Name

Description

Instance Class

The Animation Blueprint class to use for this Linked Anim graph.

Receive Notifies from Linked Instances

Whether Skeleton Animation Notifies will be received by this linked instance from other Linked Anims. This can be useful in situations where you want to encapsulate Animation Notify handling in one Linked Anim instance, while playback can happen in another.

Propagate Notifies to Linked Instances

Whether Skeleton Animation Notifies will be sent from this linked instance to other linked instances. Propagate Notifies to Linked Instances must also be enabled on the target Linked Anim instance for notifies to successfully propagate.

Double-clicking a Linked Anim Graph node will open the linked Animation Blueprint asset, if one is assigned,

Input Pose

One of the ways you can use your Linked Anim Graph is by exposing animation inputs using the Input Pose node. Create this node by right-clicking in the Anim Graph of your linked Blueprint and select Input Pose from the Misc. category. You can then connect this node to an animation node.



You can optionally rename the Input Node by selecting it and changing the Name in the Details panel.



You can create as many Input Poses as needed, and all of them will display on the Linked Anim Graph Node as input pins.



Input Variables

Variables can also be exposed to the Linked Anim Graph, in a process similar to the Blueprint process of making a variable public. Select your variable and enable Instance Editable. This will expose the variable on the Linked Anim Graph.



Linked Anim Layer

With Linked Anim Graphs, you link to a specific Animation Blueprint. With Linked Anim Layers, you use linking in a more standardized form. Linked Anim Layers require you to create an Animation Layer Interface, which defines the preset Animation Layers of your graph. You can then create a primary Animation Blueprint which contains the main logic structure for these different layers, and then different Animation Blueprints for each gameplay differentiator.



You will typically want to use Linked Anim Layers when you are creating an animation project of high complexity, for example a live-service project where new animations are added and updated. This is due to the workflow centering around creating new, or removing, Animation Blueprints for specific gameplay logic.

Rather than continuously update and manage a single Animation Blueprint, you can separate your logic into these layers. This enables multi-user collaboration and memory savings, as the system will only load the relevant Animation Blueprints if they are being linked and used.

You can control animation memory with Linked Anim Layers by breaking your Animation Blueprints into multiple asset files. An Animation Blueprint that contains linked layers can be loaded and unloaded when necessary using Unreal Engine's memory management systems. Therefore, you must set up additional streaming logic if you want to remove Animation Blueprints from memory when they are unlinked.

Animation Layer Interface

To create a Linked Anim Layer system, you must create an Animation Layer Interface Asset, where you will define the animation layers to use in your Animation Blueprints. In the Content Browser, click Add (+), then select Animation > Animation Interface.



Open the Asset to view the Animation Layer Interface editor. The primary way you will interact with this asset is by adding Animation Layers, which can be done by clicking Add (+) in the My Blueprint panel.



Layers under the same non-default Group name will share the same Animation Instance. It is recommended to use a new/non-default shared name for the layers in your Layer Interface.

For some layers you may want to also expose pose and property inputs, as this may be necessary for the Linked Anim structure, such as if this layer is to modify an incoming pose. To do this, click Add (+) on the Inputs section of the selected layer's Details panel. You can also add property inputs under the Inputs property.



For an example Animation Layer setup, you may want to create a general system of Full Body, Upper Body, and IK layers. These layers provide the following functionality for your character:

Full Body: The overall base locomotion and animation of your character.

Upper Body: If your character holds items or weapons, you could have a layer that contains this logic.

IK: Final arm or leg adjustments on your character. Typically this would be leg IK to adjust foot placement, or arm IK to ensure the hands are holding weapons correctly.

In this case, your Animation Layer Interface may look like this:



The Animation Layer Interface graph is read-only and is only used to pre-define a list of shared Animation Layers and inputs for your Animation Blueprints.

Base Blueprint Setup

When using Linked Anim Layers, you construct a "Base" Animation Blueprint, which you assign to your character. This base may contain the general structure of your linked animation layers, but not necessarily the logic or data within them.

First, you need to bind the Animation Layer Interface to your Animation Blueprint by selecting Class Settings, then clicking the Add dropdown menu in the Interfaces section. Select your Animation Layer Interface.



You will now see your predefined layers appear in the Animation Layers section of your Blueprint. Drag these layers into your AnimGraph to build the base logic. In this example the overall structure order is Full Body > Upper Body > IK. Both the Upper Body and IK layers have pose inputs added to them to allow for animation to be passed through and modified.



Depending on how complex and modular you want your setup, you can choose to not create any specific logic within your base Animation Blueprint. Your layers can be left empty and default, with the true logic coming from various linked Animation Blueprints.



Specific Blueprint Setup

Next, you need to create your specific logic for one of the Animation Blueprint states on your character. This requires you to create a second Animation Blueprint and also bind the Animation Layer Interface to it.

Once you have created, opened, and bound the interface to the Blueprint, you can now create the logic within each of the linked layers. To continue the example from before, this Animation Blueprint handles the overall animation and behavior for a weapon-equipped character. The layers contain the following logic:

Upper Body contains an Aim Offset node that controls the character's weapon aiming behavior, specific to that weapon.

IK contains an IK Rig node that controls the final hand placement for the character, specific to that weapon.

Full Body contains a State Machine that controls the general locomotion of the character, specific to that weapon or movement-set.



In this way, you partition the entirety of a weapon's Animation Blueprint logic into this Blueprint exclusively, enabling different users to work on these Blueprints. You can create as many different Animation Blueprints as required, with different logic in them depending on the context.

For these logic-specific Animation Blueprints, you do not need to recreate the same Anim Graph logic that exists in the base Blueprint. Instead you can consider the base Blueprint to be a "parent" Blueprint in terms of maintaining that overall logic structure in the Anim Graph. You only use these specific Blueprints for creating logic within each linked layer.

Linking Anim Layers

The final step in using the Linked Anim Layers is adding the Link Anim Class Layers Blueprint node. You use this node to bind the layers of one of your specific Animation Blueprint classes to the Animation Layer system, causing its internal layer logic to overwrite the current logic.



Target is where you connect your Skeletal Mesh component.

In Class is where you specify your Animation Blueprint class.

Continuing the previous example, create a Link Anim Class Layers node, with the character mesh connected and the In Class input set to the specific weapon Animation Blueprint. In some cases, you may also want to play a Montage after the layers change, to help transition the change with an animation, such as a "weapon equip" animation.



To summarize this example:

The weapon Actor Blueprint stores a reference to the Weapon Animation Blueprint Layer. This means that the animations related to that specific weapon are only loaded when the weapon is activated in the game.

You can then create similar logic and assets for other weapons, such as a rifle, bow, or rocket launcher. Each weapon stores a reference to its associated Animation Blueprint Layer and therefore only those specific animations load when those weapons are loaded.

Additional Use Case Example

Below, a use case for Linked Anim Layers used on Fortnite is shown.



In this example, there are two interfaces—one for weapons, and another for vehicles. You can have both active at the same time. It is also possible for a single Animation Blueprint that implements one of these interfaces to override multiple points of the graph, such as a weapon overriding WeaponUpperBody and WeaponAdditive.

Here are some possibilities with the above setup:

When driving a car, the vehicle layer overrides the entire pose of the character.

When riding as a passenger, the vehicle overrides a seated animation on the lower body of the character while the weapon controls the upper body. If the character changes weapons, a new weapon Animation Blueprint will control the upper body while the lower body continues to play from the vehicle.

A weapon can override the upper body pose, which will then be combined with the lower body pose from the main graph, then a custom additive animation, such as idle noise, will be played on top of the full body pose from the weapon.

In this way, weapons can override several different points in the main graph. For example, a locomotion State Machine with states like Jump, Fall, Land, and Zipline, is used. Rather than duplicating this State Machine for each weapon, the State Machine lives in the main graph, and weapon Animation Blueprints have a Layer they can override for each state.

If a weapon doesn't need to override some states, then you don't need to connect anything to the output pose in the corresponding Layer. Additionally, Animation Blueprints containing Layers have their own Event Graphs. So, if you need to process data for a specific vehicle, you can keep it contained in that vehicle Animation Blueprint's Event Graph.

Animation Blueprint Templates

Animation Blueprints can also be created as Templates, which are Blueprints that do not reference a specific Skeleton asset or animations. This means you can reuse Animation Blueprint logic in a more modular way.

To create a Template Animation Blueprint, follow the normal Animation Blueprint creation process, but instead of specifying a Skeleton, click Template, then click Create.



Template Usage

Animation Blueprint Templates contain the same interface and editor found in normal Animation Blueprints. However, because templates do not correspond to any Skeleton, you cannot directly reference animations or assets related to a specific Skeleton. Instead, you can parameterize your template logic and expose Variables that are set in another Blueprint.

For example, you can create a Sequence Player node in the AnimGraph. Typically, this node is used to play Animation Sequences directly, but instead you can expose the Sequence property as a Variable. To do this, click the Bind dropdown menu in the Sequence Player's Details panel, and select Expose As Pin.



Next, right-click the newly exposed pin on the Sequence Player and select Promote to Variable, to create a Variable for the Animation Sequence to play. Similar to exposing Linked Anim Graph variables, you must also make this Variable public.



Animation Blueprint templates are referenced in the Anim Graph by right-clicking in the graph and selecting your template from the Linked Anim Blueprints section of the context menu.



You can then set any exposed variables on this template to correspond to your Blueprint requirements.



Here you can find pages related to Animation Assets and Features in Unreal Engine.



Animation assets that contains animations for skeletal meshes.



Learn about Skeletons, Bones, and animation data management in Unreal Engine.



Blend Spaces are graphs where you can plot any number of animations to be blended between based on the values of multiple inputs.



Animation Montages are animation assets that enable you to combine animations in a single asset and control playback using Blueprints.



Retarget and procedurally adjust animations using IK Rig and Retargeting tools.



An overview of Character Locomotion features in Unreal Engine.



Animation Composites serve as a way to combine multiple animations together and treat them as a single unit.



Describes the Animation Pose Asset which can be used to drive animation through weighted curve data.



Use Deformer Graphs to create and edit custom mesh deformations for skinned characters and objects.



Animation Modifiers enable users to define a sequence of actions for a given animation sequence or skeleton.



Mirror animation in Unreal Engine using the Mirror Data Table.



Describes how you can use Skin Weight Profiles to improve visual fidelity on lower end platforms.



Create shared animation systems that reduce the overall amount of animation work needed for a crowd of Actors.



User guide for the 3ds Max Vertex Animation tool set.



User guide for the editing modes available in the Animation Editor.

Skeletal Meshes

Skeletons

Animation Curves

Animation Notifies

Animation Montage

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Overview

Creating Animations

Importing Animations

Sequencer

Editing Animation Sequences

Additive Animation Tracks

Record Feature

Sharing Animations

Animation Compression

Bone Compression Settings

Curve Compression Settings

Animation Sequence Features

Overview

An Animation Sequence is an animation asset that contains animation data that can be played on a Skeletal Mesh to animate a character. An Animation Sequence contains keyframes that specify the position, rotation, and scale of the Skeletal Mesh's Skeleton at specific points in time. By blending between keyframes during sequential playback, the Skeleton's motion animates the Mesh.



Animation Sequences are tied to specific Skeletons, which enables animations to be shared across Skeletal Meshes that use the same Skeleton.



Creating Animations

Animation Sequences are most often created in external animation and modeling software and are contained within an FBX file. You can import Animation Sequences into Unreal Engine during the FBX import process for use in your project.

Importing Animations

To import an animation, select Import in the Content Browser.



Navigate in your computer's File Explorer window and select the FBX file containing an animation you want to import.

You will be prompted with the FBX Import Options window. Here you can fine-tune the import process for animations.



The FBX Import Options window contains the following configurable properties:

Property

Description

Import Animation

When importing an FBX file that contains animations, enable this property to import the animations as Animation Sequence Assets.

Animation Length

Exported Time: Imports animations at their exported lengths, based on time. Advanced Time: Imports animations at the length for which there is animation data present. Set Range: Imports animations at a set range of frames as defined in the Frame Import Range property.

Override Animation Name

If used, this property will override the name of the animation being imported with the given name. By default, animations will be imported with the name of the FBX file.

Import Meshes in Bone Hierarchy

If enabled, meshes nested within bone hierarchies will be imported separately instead of being converted to bones.

Frame Import Range

Defines the frame range that will be used when importing animations. Only used when Animation Length is set to Set Range.

Default Sample Rate

If enabled, all present animation curves will be sampled at 30fps.

Custom Sample Rate

Defines a custom sample rate to import animation data. If this is set to 0, Unreal Engine will automatically find the best sample rate.

Import Custom Attribute

If enabled, imports any FBX attribute as a Curve, or as an Animation Attribute.

Delete Existing Custom Attribute Curves

If enabled when re-importing, any present custom-attribute curves will be deleted.

Delete Existing Non Curve Custom Attributes

If enabled when re-importing, all previous non-curve attributes will be deleted.

Import Bone Tracks

If enabled, bone transform tracks will be imported. If disabled, all bone transform tracks will be discarded. It can be useful to discard bone transform tracks when working with curves-only animations.

Set Material Curve Type

When enabled, this property sets Material Curve Types for all custom attributes.

Material Curve Suffixes

Here you can manually set Material Curve Types for the custom attributes. This property has no effect if Set Material Curve Type is enabled.

Remove Redundant Keys

When enabled and importing custom attributes as curves, this property will remove unnecessary keys.

Delete Existing Morph Target Curves

If enabled, this property will delete any existing Morph Target curves.

Do not Import Curve with Zero

When enabled, any present curves with a value of 0 will be removed in order to avoid adding extra curves to evaluate.

Preserve Local Transform

If enabled, this property will import all present curves within the animation.

Using the Skeleton property in the Import Settings window, you can choose a Skeleton which drives your imported animations. Leaving this property blank will import any skeletal structure found in the FBX file as a new Skeleton.



In order to drive any imported animations using an existing Skeleton, the animation must be using a similar skeleton. Unreal Engine will automatically match bones from the animation to match the existing Skeleton's bones using the bone names and hierarchy in the Skeleton Tree.

Ensure the Import Animation option is enabled and select Import.



When importing multiple FBX files at once, you can use Import All to import all selected FBX files with the same FBX Import Options.

After the import process is complete, your animation will now appear as an Animation Sequence Asset in the Content Browser.

Animations with non-whole end frame values will not import into Unreal Engine correctly.



You can correct this issue by importing the animation Sequenece into an external DCC and editing the end frame to a whole frame value or by setting the Animation Length property in the FBX Import Options to Frame Range and manually setting the Frame Import Range property in the Advanced section.

For more information on importing animations into Unreal Engine, see FBX Animation Pipeline and Importing Animations Using FBX.

Sequencer

Using Sequencer, you can create animations in Unreal Engine with just a Skeletal Mesh. This can be useful if you want to save animations as a new Animation Sequence, when using the Animation Track, or when animating using Control Rig.

To create a new Animation Sequence from an animation created using Sequencer, right-click the Skeletal Mesh Actor track and select Bake Animation Sequence from the context menu.



You can also create unique variants and modified versions of Sequences by editing existing animations with FK Control Rig.

For more information on Control Rig and how you can use Control Rig to animate characters in Unreal Engine, see the Control Rig documentation.

Editing Animation Sequences

When working with Animation Sequences, you can make additive edits and adjustments to existing animations using the Animation Sequence Editor. Within the Animation Sequence Editor, you can preview playback, tweak animations with additive layers, and add notfies and curves.



The following are a few methods that you can use to edit and modify existing animations within your project.

Additive Animation Tracks

You can tweak the position of your Character's bones in an Animation Sequence with the Bone Manipulation tool. Select a bone in the Viewport or the Skeleton Tree panel and, using the movement tools, manipulate a bones position and rotation.



After manipulating a bone, add a key with Add Key in the Toolbar to save the movement data in an additive animation track that will appear in the sequence timeline.



The additive track will blend the bones' positions to match their manipulated positions at the added keyframes.

For more information about Bone Manipulation, see the Bone Manipulation section of the Skeleton Editor documentation.

Record Feature

When editing an Animation Sequence, you can record directed movement in real time and save the animation as a new Sequence using the Record Button.



The resulting animation will then be usable as a unique Animation Sequence asset.



You can also use the record feature to create Assets from blended animations.



Sharing Animations

If your project is using a combination of different Skeletons and Skeletal Meshes, you can share Animation Sequences across these different Assets. There are a few methods of sharing animations or retargeting Skeletons that you can choose from depending on your project's needs.



For Skeletal Meshes that do not share the same Skeleton but have identical skeletal structures, you can define their Skeletons as Compatible to share Animation Sequences. See the Compatible Skeletons section of the Skeleton documentation for more information.



Learn about Skeletons, Bones, and animation data management in Unreal Engine.

To share Animation Sequences between Skeletal Meshes that share the same Skeleton but possess different mesh proportions, you can use Animation Retargeting. See the Animation Retargeting documentation for more information.



Describes how retargeted animations can be used with multiple Skeletal Meshes, allowing you to share animations.

You can use Animation Sequences from one Skeletal Mesh to create new Animation Sequences for another Skeletal Mesh using a different Skeleton with IK Rig Retargeting. See the IK Rig Retargeting documentation for more information.



Share and transfer animation between characters of any size using IK Rigs and IK Retargeting.

Animation Compression

Compression Settings are data Assets that you can define. They apply compression to animation Assets. Compression removes animation data, lowering your animation's memory cost to improve your project's performance. Animations with minimal movement are affected less by compression, while compression effects on animations with intricate movement will be far more noticeable.

To create a Compression Settings asset, click the Add (+) in the Content Browser; and, from the context menu, select Animation > Bone Compression Settings or Curve Compression Settings.



After creating a compression Asset, you can open its Details panel by double-clicking it in the Content Browser.

Bone Compression Settings

The Bone Compression Settings Asset is used to define and apply a compression method to an Animation Sequence's bone data. Bone compression removes unnecessary or arbitrary bone motion data based on the codec method you define in the Bone Compression Settings' properties.



The Bone Compression Settings Asset has the following configurable properties:

Property

Description

Codecs

Here you can define a list of animation bone compression codecs to try when compressing bone data in an Animation Sequence. The available Codes are as follows:

Anim Compress Bitwise Compress Only: Focuses on Bitwise compression and retains all keys. Anim Compress Least Destructive: Restores any present animation compression to raw data. Anim Compress Per Track Compression: Focuses compression to a per- track basis, and compresses each track individually. Anim Compress Removes Every Second Key: Removes every second key present in the animation. Anim Compress Revolve Linear Keys: Removes any keys that are unchanged from surrounding keys. Anim Compress Removes Trivial Keys: Removes any keys where position and orientation of Assets are unchanged from surrounding keys.

Empty entries in the list are ignored when running bone compression on the Animation Sequence. However, the list must contain at least one codec in order to compress the bone data.

Error Threshold

When enabled and triggered during compression, this property will use the best codec below this error threshold. The default error threshold value is 0.1.

Force Below Threshold

If enabled, any codec with a lower error threshold will be used until it falls below the threshold.

You can apply a Bone Compression Settings Asset in the Animation Sequence's Asset Details panel, under the Bone Compression Settings property.



Curve Compression Settings

When using curves to drive animation sequence properties, curve compression can provide a useful resource to maintain your project's performance.



The Curve Compression Settings Asset has the following configurable properties:

Property

Description

Codec

Define the animation curve compression Codec. The available codec types you can choose are as follows:

Compressed Rich Curves: Only targets and compresses Rich Curves. Uniform Indexable: Compresses curves so that their points are indexable for other features to access. Uniformly Sampled: After compression, any curves will be sampled at a uniform rate.

Max Curve Error

Maximum error threshold allowed when compressing Rich Curves. By default, this value is 0.

Use Anim Sequence Sample Rate

Enable this property to use an explicit value for the Animation Sequence sample rate.

Error sample rate

When Use Anim Sequence Sample Rate is enabled, the Animation Sequence will use the defined value as the sample rate to use when measuring the curve error. By default, this value is 60.

You can apply a Curve Compression Settings Asset in the Animation Sequence's Asset Details panel, under the Curve Compression Settings property.



Animation Sequence Features

Here, you can find related Animation Sequence features you can use when working with Animation Sequences in your project.



Import and use custom animated FBX attributes in your Animation Sequences.

Import and use custom animated FBX attributes in your Animation Sequences.



Animate Material Parameters, Morph Targets, and other properties synchronized to your animations using Animation Curves.

Animate Material Parameters, Morph Targets, and other properties synchronized to your animations using Animation Curves.



Breaks down the Retarget Manager options within the Skeleton Editor.

Breaks down the Retarget Manager options within the Skeleton Editor.



Send and receive events synchronized to Animation Sequences using Animation Notifies.

Send and receive events synchronized to Animation Sequences using Animation Notifies.

Importing Attributes

Project Settings Setup

Animation Sequence

Transform Attributes

FBX Setup

Settings and Import

Referencing Attributes

Get Attribute Ref

Custom node attributes can be imported in your FBX Animation Sequences for creating varied animation data-driven setups. Unlike other animation data, such as Curves, attributes are stored per-sequence and support various property types.

This document provides an overview of how to import and reference animation attributes in Unreal Engine.

You are familiar with creating custom attributes on nodes in Autodesk Maya.

Your project contains a Skeletal Mesh.

You are familiar with importing Animation Sequences.

Importing Attributes

To start importing animation attributes in your Animation Sequence, you must ensure that a Bone contains an attribute with animation. Typically, this is done in DCC software, such as Autodesk Maya. In this example, the root Bone has a custom float attribute.



The currently supported attribute data types for importing are Floats, Integers, Strings, and Transforms.

Project Settings Setup

In order for attributes to import correctly, you will need to ensure they are defined in your Project Settings. From the main menu in Unreal Engine, go to Edit > Project Settings, navigate to the Engine > Animation section, and locate the Custom Attributes settings. The following settings are available:



Name

Description

Bone Timecode Custom Attribute Name Settings

A list of timecode-related properties and their default mappings to custom attributes. You can change these settings to map to different timecode attributes if your project is using different attribute names.

Hour Attribute Name is an Integer attribute and is set by default to TCHour.

Minute Attribute Name is an Integer attribute and is set by default to TCMinute.

Second Attribute Name is an Integer attribute and is set by default to TCSecond.

Frame Attribute Name is an Integer attribute and is set by default to TCFrame

Subframe Attribute Name is a Float attribute and is set by default to TCSubframe

Rate Attribute Name is an Integer attribute and is set by default to TCRate.

Takename Attribute Name is a String attribute and is set by default to Takename.



These will be included in the list of attribute names to import and will act as if they were added to the Bone Custom Attributes Names array.

Bone Custom Attributes Names

An array where you define your custom attribute names to search for when importing animation. Defining an attribute name on this list will search all Bones in your skeleton for the attribute.

Click Add (+) to add an attribute to the list, then fill in the following properties:

Name, which is the name matching your custom animation attribute.

Meaning, which is an optional field where you can define additional context for this attribute.



Bone Names with Custom Attributes

An array where you can define a list of Bones to filter for custom attributes when importing animation. Defining a Bone on this list will cause all custom attributes to import from that Bone when importing animation.

Click Add (+) to add an item to the list, then define a Bone name.



Attribute Blend Modes

An array where you define how certain attributes behave during blends. This overwrites the global Default Attribute Blend Mode per attribute.

Click Add (+) to add an item to the list, define an attribute name, then set the blend mode:

Override will overwrite the custom attribute value based on the highest weight during the blend.

Blend will set the average value of the custom attribute between the animations according to their weight.



Default Attribute Blend Mode

The default blend mode to use for all custom attributes. Similar to Attribute Blend Modes, you can select from Override or Blend.

Transform Attribute Names

The transform node name to search for when importing transform attributes.

Depending on how you want to import custom attributes, you may want to set values on either Bone Custom Attribute Names or Bone Names with Custom Attributes. For example, if you wanted to import two custom attributes created on the root Bone, you could either:

Create two array entries under Bone Custom Attributes Names, and match the names to your attributes.



Create an entry under Bone Names with Custom Attributes, and name it root.



After you set up your custom attribute project settings, you can import your Animation Sequence containing the custom attributes. When importing the FBX, ensure that Import Custom Attribute is enabled.



Animation Sequence

After you import your Animation Sequence containing the custom attributes, you can view the attributes in the Animation Sequence Editor. Attributes are located as tracks within the timeline under the convention Attributes > Bone > Attribute Name.



Hovering your cursor over an attribute will provide you with details about the attribute, including its type and number of keyframes.



Transform Attributes

You can also import custom transform attributes, which require a different workflow for importing. Transform attributes are useful for providing auxiliary transform information within an Animation Sequence without adding extra Sockets or Bones.



FBX Setup

Since Bones already contain base transform attributes, you must instead create a child node of the Bone that you want to apply a custom attribute to. This can be a locator or an empty node.

In this example, a locator named "MyTransformAttribute" is parented to a hand Bone. Like any other node or attribute, this can be keyframed in any arbitrary way.



Settings and Import

Next, you need to define the name of the transform attribute in the Custom Attributes Project Settings. Locate Transform Attribute Names, click Add (+) to create an item, and then add the name of the transform attribute node.



You can now import your Animation Sequence containing the custom transform attributes. Once imported, the transform attribute will be visible as a track within the timeline under the convention Attributes > Bone > Attribute Name.



You can visualize custom transform attributes in the Animation Sequence Viewport by clicking Character > Bones, then enabling Attributes in the Viewport menu.



Referencing Attributes

Attributes can be referenced and read in Blueprints by using Get Attribute functions targeting a Skeletal Mesh Component. You can use the following functions:

Get Float Attribute

Get String Attribute

Get Integer Attribute

Get Transform Attribute



These functions contain the following common pin information:

Name

Description

Target

The Skeletal Mesh Component to target.

Bone Name

The name of the Bone containing the custom attribute.

Attribute Name

The name of the custom attribute to look for.

Default Value

If the attribute cannot be found, then this value will be sent to Out Value.

Lookup Type

Determines how the attribute is to be found on the Skeleton. You can select from the following:

Bone Only, which will only search for the attribute on the provided Bone Name.

Immediate Parent, which will search for the attribute on the provided Bone Name and its first parent Bone.

Parent Hierarchy, which will search for the attribute on the provided Bone Name and directly upward in the hierarchy until the root Bone.

Out Value

Passes the value of the attribute, or Default Value if the attribute is not found.

Return Value

Outputs true if the attribute is found when executing this function, otherwise will output false.

Get Attribute Ref

You can also use Get Attribute Ref functions. These functions require a Variable connected to Out Value, where it will write the value to the Variable you linked to the pin. Unlike the Get Attribute functions, Get Attribute Ref will maintain the last value of the attribute if it fails to find it.



Creating Animation Curves

Importing Animation Curves

Creating Curve Animation

Anim Curves Panel

Curve Management

Curve Filtering

Curve Details

Using Animation Curves

Materials

Morph Targets

Animation Blueprints

Metadata Curves

As you play Animation Sequences on your Skeletal Mesh, you may find it necessary to animate additional properties and values synchronized to that animation. You can accomplish this using Animation Curves (also called anim curves, or curves), which are float-type values you can add and keyframe within an Animation Sequence. Curves can be useful for augmenting your animations with additional animatable properties, such as animating Material Parameters, Morph Targets, and other attributes.

This document provides an overview of Animation Curves, and the various ways you can use them.

Your project contains a Skeletal Mesh and Animation Sequences.

If you are using anim curves to affect Material Parameters, you need a basic understanding of Material Instancing.

If you are using anim curves to affect Morph Targets, you need a basic understanding of setting up Morph Targets on your Skeletal Mesh.

Creating Animation Curves

Animation Curves can be created in the following ways:

When viewing an Animation Sequence in the Animation Sequence Editor, click the Curves track dropdown menu and select Add Curve… > Create Curve. Type in the name of the new curve and press Enter to create it.



In the Anim Curves panel, right-click in the curve list area and select Add Curve. Type in the name of the new curve and press Enter to create it.



If your skeleton already has curves, you can select them from the Curves > Add Curve… dropdown menu.



Animation Curves are stored on the Skeleton Asset. Therefore, when you are creating curves, you are also editing the Skeleton, which will require you to save it.

Importing Animation Curves

Custom attributes can also be created externally in animation software like Autodesk Maya, and then imported as curves along with your Animation Sequence.

To do this, first create a custom attribute on any bone in your skeleton and keyframe it. You must ensure that it is a float-type attribute, as that is the only compatible data type with curves. Once finished, export your animation.



Your custom attribute must be keyframed in order for curve data to correctly import.

Next, import your Animation Sequence containing the custom attributes. When importing the FBX, ensure that Import Custom Attribute is enabled.



Once imported, your curves should appear in your Animation Sequence. In this example, two attributes were created on different bones and then imported.



Creating Curve Animation

Once you have created an Animation Curve and added it to your Animation Sequence, you can animate its value. Select the Curve dropdown menu on the Animation Curve track and click Edit Curve. This will open the Curve Editor.



You can also open the Curve Editor by double-clicking the timeline region for the specific curve track.



Once the Curve Editor is open, you can create keyframes by pressing Enter. This creates a keyframe at the Playhead location, which can be moved by dragging it to set keyframes at different times along the sequence. You can click and drag keyframes to change their time and value.



Refer to the Curve Editor page for more information on navigation, keyframes, and tangent editing using the Curve Editor.



Tweak your keyframes and curves by using the Curve Editor and tools within it.

Tweak your keyframes and curves by using the Curve Editor and tools within it.

Anim Curves Panel

Your created and stored curves can be viewed and managed from the Anim Curves panel. To view this panel, navigate to the main editor menu and enable Window > Anim Curves. The Anim Curve panel can only be viewed from the Skeleton Editor, Animation Sequence Editor, or Animation Blueprints Editor.



Curve Management

Several settings and features can be adjusted on your curve entries within the Anim Curve panel.



Name

Description

Curve Name

The name of the curve. You can rename curves by right-clicking one in the Anim Curve panel and selecting Rename Curve.



Type

Enables this curve to either be used for Morph Targets or Materials.

Weight

The current value of the curve.

Auto

Enabling this causes the Weight value to change automatically according to its keyframed values if the curve is being animated in this sequence. If disabled, it ignores its animated values. Disabling this can be useful for testing how the curve value affects the character without keyframing it.



Bones

The number of bones connected to this curve.

Curve Filtering

You can filter the list of curves in the Anim Curves panel to display only the actively-used curves, or only certain types of curves.

Disabling All Curves causes only the currently-used curves for this Animation Sequence to be displayed.

Disabling Morph Target, Attribute, and Material curves disables those curve types from being displayed.



Curve Details

Selecting a curve reveals the following properties in the Details panel.



Name

Description

Curve Name

The name of the curve.

Connected Bones

An array of bones that you can connect to this curve. This is useful if you want certain curves to be active depending on if a bone is being used or not. Bones can be active or inactive depending on if different skeletons are merged, or bones are being reduced for different LODs.

Max LOD

The maximum LOD to use before this curve no longer evaluates. For example, setting this value to 1 will cause this curve to evaluate for LODs 0 and 1, but not for 2 and beyond.

Using Animation Curves

Once you have created and animated your curve, there are a variety of ways you can use it to affect your character.

Materials

You can use Animation Curves to automatically affect Scalar Material Parameters. This requires you to do the following:

Match the curve name to the name of the Material Parameter in the Material.



Enable the Material curve type in the Anim Curves panel.



Once this is done, the curve value starts to affect the Material Parameter.



Material Animation Curves affect all Materials (and their parameters) assigned to a Skeletal Mesh. Therefore, you may need to adjust your content appropriately if you want your anim curve to only affect a parameter from a single Material. This can happen if your Skeletal Mesh has multiple assigned Materials deriving from a single parent, which will cause parameter names to share between all assigned Materials.



Morph Targets

Similarly to Materials, you can use Animation Curves to automatically affect Morph Targets on your Skeletal Mesh. This requires you to do the following:

Match the curve name to the name of the Morph Target found in the Morph Target Previewer



Enable the Morph Target curve type in the Anim Curves panel.



Once this is done, the curve value starts to affect the Morph Target.



Animation Blueprints

You can use Animation Curves to affect arbitrary values in Animation Blueprints. In most cases, you can use them to affect the alpha values of certain Anim Graph nodes, such as IK, in order to change IK states during animation playback.



The following curve-related functions are available in both the Animation Blueprint Anim Graph, and Event Graph:

Name

Image

Description

Get Active Curve Names



This targets an Anim Instance and returns the last up-to-date list of active curve names for the specified curve type.

Get All Curve Names



This targets an Anim Instance and returns all Curve Names into a string array.

Get Curve Value



This targets an Anim Instance and returns the value of a specified Curve Name.

Metadata Curves

Metadata Curves are Animation Curves that output a static curve value of 1.0 when added to an Animation Sequence. They can work conversely with normal Animation Curves, which by default (with no keyframes) output a static curve value of 0.0. If no curve is added to a sequence, the anim curve value also falls back to a value of 0.0.

This behavior can be useful in larger projects that contain many Animation Sequences. In these projects, many of those animations may require constant 1.0 curve values throughout them. Therefore, you can use Metadata Curves to expedite this process, rather than manually adding normal curves and keyframing them to 1.0. In other words, large projects that are using anim curves can structure their usage in Animation Sequences in the following way:

A small number of Animation Sequences may require explicit curve animation on them. Therefore, add Animation Curves to those animations and keyframe them accordingly.

A larger number of Animation Sequences may require curve values set constantly to 1.0, in order to maintain a property value. Therefore, add Metadata Curves to those animations.

The remainder of all Animation Sequences may not require curve value considerations, or require curve values set constantly to 0.0. No action is required.

To create a Metadata Curve, click the Curves track dropdown menu and select Add Curve… > Create Curve. You can either select a currently-existing curve, or click Create New to create a new curve.



Alternatively, a currently-existing anim curve can be converted to a Metadata Curve by clicking the Curve drop down menu on a curve track and selecting Convert To Metadata.



Once created, Metadata Curves are read-only and output a constant curve value of 1.0.



Using Retargeted Animations

Skeletons

Skeleton Editor

Animation Pose Assets

Animation Sequences

Manage Retarget Source

Set up Rig

Manage Retarget Base Pose

The Retarget Manager within the Skeleton Editor can be used to manage your retarget sources, set up rigs and define retargeted base poses for use with Animation Retargeting.

Manage Retarget Source

Since retargeting uses a Skeleton asset and the Skeleton has its original proportions defined by the Skeletal Mesh for which it was initially created, it follows that one-directional retargeting will work smoothly in most cases. However, there will often come times when you will have special animations that are built just for the variant versions. For example, suppose you have multiple characters that share the same Skeleton asset (a base character, a short character, and a tall character) and you have a special animation that was created just for the tall version of the character.

If you imported this new tall-only animation in, you would still need to use the same Skeleton asset as before, which was created from the base version of the character. This will cause the new animation's proportions to be distorted. The solution is to use the Manage Retarget Source option within the Retarget Manager which allows you to associate an Animation Sequence with the actual Skeletal Mesh for which it was designed. In this way, any problems of retargeting for special animations will be fixed.

Adding Retarget Sources

Inside the Skeleton Editor, from the Toolbar click the Retarget Source Manager button.



Click the Add New Retarget Source button.



Choose the Skeletal Mesh for which the special animation was created.



You will now see that Skeletal Mesh listed in the Retarget Manager.



Open the special case Animation Sequence intended for your specific Skeletal Mesh.

In the Asset Details panel, locate the Animation category and locate the Retarget Source property and choose your Skeletal Mesh from the drop-down menu.



By choosing this mesh, you are specifying that you want to use the proportions of that mesh to drive this animation.

Set up Rig

The middle section of the Retarget Manager allows you assign a Rig to the Skeleton which can be used to pass animation data to a different Skeleton that uses the same Rig.



This process is needed in order to perform any animation retargeting for characters that use different Skeleton assets.

You can select the Rig to use from the Select Rig drop-down option where a Humanoid option is available which you will want to select for most characters.



Once you assign the Humanoid Rig, you will need to assign Bones from the Skeleton that correspond to the same (or similar) location as the Node on the Rig. You can use the drop-down menu for Node and manually assign the corresponding Bone from your Skeleton, or you can use the Auto Mapping feature located at the top of the menu. This will look through your Skeleton and attempt to find the best matching Bone for each Node on the Rig.

If you are working with non-biped characters, or have a hierarchy that is not compatible with the Humanoid Rig asset then you can create your own Rig asset by right-clicking on your Skeleton in the Content Browser and selecting Create > Create Rig.

The Clear Mapping button will wipe all the currently assigned Bones from their corresponding Node assignment. You can also use the Save and Load buttons to save the current mapping assignment or load a previously saved mapping assignment from a Node Mapping Container asset (shown below).

The Show Advanced button will allow you to assign additional Node/Bone correlations for things like finger digits, IK Bones or Twist Bones. Once you set up the Rig for your source Skeleton (or the Skeleton asset that drives the animation that you want to retarget to another character), you will need to go into the Skeleton of the target Skeleton and assign the same Rig and define the Bones in the new Skeleton that best match up with the Nodes on the Rig.

Please see Using Retargeted Animations for a step-by-step guide on how to retarget animations between characters that use different Skeletons.

Manage Retarget Base Pose

There may be instances where you want to retarget animations to a Skeleton that is not quite using the same base pose as your Source Skeleton.

Take for example the Skeleton in the image below on the right when attempting to retarget an animation:



Our Source Skeleton (left) is in a A-Pose while our Target Skeleton is using an T-Pose. If we were to retarget animations as is now, we may encounter issues:



Above we have our target animation on the left of a character holding a shotgun, however, when we retarget the animation to our new character on the right (because they are using different base poses) the arm positioning is not correct. We can fix this by Retargeting the Base Pose inside the Retarget Manager which allows us to define a Retargeted Base Pose to use for animation retargeting purposes rather than using the characters normal Base Pose.

We can select bones in our character and rotate them (in this case the left and right shoulders) so that our character is in an A-Pose, then we click Modify Pose:



In context menu, select Use Current Pose:



This will set the pose you define as the Retargeted Base Pose to use when performing any animation retargeting.

Now when we go to retarget an animation, we will see the updated Retargeted Base Pose:



When we retarget animations for Skeletons that have more similar Base Poses, we get better-looking results:



Importing Retarget Base Pose from Pose Asset

From the Modify context menu, you can also choose to import a pose from an animation Pose Asset to use as the Retargeted Base Pose.



In the image above, after selecting which Pose Asset to use (1) the available poses will be displayed in the selection drop-down menu (2). After selecting a pose from the Pose Asset to use, clicking the Import button (3) will update the mesh in the viewport to use the pose selected as the Retargeted Base Pose. Below (left) our default pose is shown and (right) our Retargeted Base Pose selected from a pose within our Pose Asset is shown.



Getting Started

Animation Notify Types

Notify

Skeleton Notify

Notify State

Sync Marker

Montage Notifies

Montage Notify

Montage Notify Window

Disable Root Motion

Managing Your Notifies

Keyframe Editing

Common Notify Properties

Animation Notify Panel

Custom Notify Classes

Animation Notifications (Animation Notifies or just Notifies) provide a way for you to create repeatable events synchronized to Animation Sequences. These events can be sounds (such as footsteps for walk or run animations), spawning particles, and other types. Animation Notifies have any number of different uses, and the system can be extended with custom types.

This document provides an overview of the different types of Animation Notifies, how to create them, and how to use them in a variety of ways.

Animation Notifies are created within Animation Sequences, therefore your project needs a Skeletal Mesh and an Animation Sequence.

Getting Started

Animation Notifies are commonly accessed and created within Animation Sequences. To get started, open an Animation Sequence Asset, and locate the Notifies track in the timeline.



The Notifies track itself is a parent group for individual child tracks below, which contain the actual notify keyframes. By default, a single child track should exist (named 1). If no child tracks exist, or if you want to add extra notify tracks, click Add Track (+) > Add Notify Track on the Notifies track.



You can also insert or remove notify tracks by clicking the Add Track (+) dropdown menu on the child track itself and selecting either Insert Notify Track or Remove Notify Track.



To rename a Notify track, triple-click on the track text to enable text editing.



Animation Notify Types

There are several types of Animation Notifies you can create, which are viewed when creating Notifies by right-clicking in the Notify track's timeline region.



Notify

The most basic kind of Animation Notify you can create is simply called a Notify, which causes different pre-made events to be triggered at a specified time. The following Notifies can be found when viewing the Add Notify… menu. Selecting one will create the Notify keyframe at your cursor position.



Notify keyframes can be edited by dragging them in the timeline. You can also hold Shift, which will move the Playhead in sync with the Notify, making it easier to align the Notify with a specific time in the animation.



Particle Effect Notifies are used to spawn and play non-looping particle systems. You can select either:

Play Niagara Particle Effect, which spawns Niagara particles.

Play Particle Effect, which spawns legacy Cascade particles.

This Notify is useful for creating repeatable particle effects, such as an effect when a character lands from jumping, shooting effects for a Skeletal Mesh weapon, or other similar effects.



When selecting the Particle Notify keyframe, the following relevant properties are located in the Details panel:



Name

Description

Particle System / Niagara System

The Cascade or Niagara system to spawn for this Notify.

Location / Rotation / Scale Offset

An array of location, rotation, and scale transform properties to offset the system from its spawn point.

Attached

When spawned on a Socket, enabling this causes the particle system to follow the Socket for its full duration. Disabling this still spawns the particle system at the Socket location, but the system does not continue to follow the Socket.

Socket Name

You can specify a bone or Socket here, which spawns the particle system at its location. If nothing is specified here, then the system spawns at the root of the object.

Sound Notifies are used to play sound effects from imported Sound Waves, Sound Cues, and MetaSounds. These Notifies are useful for synchronizing foley-type sounds to animations, such as footsteps, cloth movements, and similar repeatable sounds.

When selecting the Sound Notify keyframe, the following relevant properties are located in the Details panel:



Name

Description

Sound

The sound asset to play for this Notify. You can select the following assets:

Sound Wave

Sound Cue

MetaSound

Sound Bus

Volume Multiplier

A multiplier to increase or decrease the volume of the playing sound.

Pitch Multiplier

A multiplier to increase or decrease the pitch of the playing sound.

Follow

If enabled, the sound effect source follows the animated mesh as it moves. If disabled, the sound remains behind at the location it spawned.

Preview Ignore Attenuation

If enabled, sound attenuation is disabled when playing the sound. This setting is editor-only and does not impact normal sound attenuation operation when playing or simulating the game.

Attach Name

If Follow is enabled, you can specify a bone or Socket to attach to. If nothing is specified here, then the sound spawns at the root of the object.

Clothing Simulation Notifies are used to pause, resume, and reset cloth simulations on a character. These Notifies are useful if you are teleporting the character during the animation and need to pause or reset cloth evaluation. They can also be useful if your animations are causing the cloth simulation to overreact.



You can select the following Notifies:

Pause Clothing Simulation, which pauses the simulation.

Resume Clothing Simulation, which restores the simulation after having been paused.

Reset Clothing Simulation, which initializes the simulation back to its default reference pose.

The Reset Dynamics Notify can be used to restore any AnimDynamics used on this Skeletal Mesh back to their original state. This Notify is useful if your animations are causing the AnimDynamic simulation to overreact or enter broken-looking states.

Skeleton Notify

Skeleton Notifies are custom Notifies saved on the Skeleton Asset, and then used as events within your Animation Blueprint. These Notifies are useful for creating any arbitrary Blueprint logic you want a Notify to execute.

To create a Skeleton Notify, right-click on a Notify track, then select Add Notify > New Notify…



You will be prompted to enter a name for the newly created Notify. Name it and press Enter to create the Skeleton Notify.



Skeleton Notifies are stored on the Skeleton Asset. Therefore, when creating them, you are also editing the Skeleton, which requires you to save it.

You can also add currently-existing Skeleton Notifies to the timeline by right-clicking a Notify track, then selecting one from the Add Notify > Skeleton Notifies menu.



Skeleton Notifies are used as Notify Events within Animation Blueprints, either in the Event Graph or Transition Graph. To add a Skeleton Notify Event, right-click in the Event or Transition Graph of your Animation Blueprint and select the Notify from the Add Anim Notify Event menu. This adds the event node to the Graph which is executed when the Notify is called from the animation it resides in.



Notify State

Notify States work similar to standard Notifies, however they operate over a duration, rather than a single event. Because of this, they provide three distinct events: a start, an update, and an end. These events can be accessed when creating Notify State child classes.

Also like standard Notifies, they provide several different pre-made classes to choose from. You can find the following notifies when viewing the Add Notify State… menu. Selecting one creates the Notify keyframes at your cursor position.



Notify State keyframes are edited similar to normal Notifies by dragging them in the timeline. You can either drag the start or end to edit the range, or drag the whole Notify.



Similar to Particle Effect Notifies, Timed Particle / Niagara Effects Notifies are used to play particles during an animation. The main difference is that you can also define the duration of the particle, if the particle is set to loop. You can select the following types of Particle Notifies:

Timed Particle Effect, which spawns legacy Cascade particles.

Timed Niagara Effect, which spawns Niagara particles.

Advanced Timed Niagara Effect, which spawns Niagara particles with extra options for driving parameters within them.

Timed Particle Notifies share the same details with normal Particle Effect Notifies, however Advanced Timed Niagara Notifies contain the following additional properties:



Name

Description

Enable Normalized Notify Progress

When enabled, causes the Notify state to output a normalized (0-1) value over the duration of the Notify to the Niagara User Parameter specified in User Parameter. The parameter starts at 0 and interpolates to 1 upon the notify finishing. This property is useful if you want to link certain particle parameters to the lifetime of the notify.

User Parameter

The name of the Niagara User Parameter to drive if Enable Normalized Notify Progress is enabled.

Anim Curve Parameters

An array where you can link Animation Curve values to Niagara User Parameters. You can add items to the array by clicking Add (+), then specify the following properties:

Anim Curve Name, which is the Animation Curve that drives the Niagara parameter.

Niagara User Float, which is the Niagara User Parameter controlled by the Animation Curve.

Trail Notifies are similar to Timed Particle Effects in that they spawn a particle system over the duration of the Notify. It differs because it is primarily used for AnimTrail Cascade Particles, and contains additional properties for controlling trail attachment and properties.



Selecting the Trail Notify reveals the following properties in the Details panel.



Name

Description

PSTemplate

The AnimTrail Cascade Particle system to use.

First / Second Socket Name

You can specify a separate bone or Socket here for each property, which are used to define the attach points for the AnimTrail. This also defines the trail's default width, based on the distance between these two attach points.

Width Scale Mode

If Width Scale Curve is used, this defines the relative scale point of the trail's width. You can select the following options:

From Centre, which scales the trail relative to the center point between the two sockets.



From First Socket, which scales the trail relative to the location of the first Socket.



From Second Socket, which scales the trail relative to the location of the second Socket.



Width Scale Curve

You can optionally specify an Animation Curve here, which can be used to animate the scale width of the trail during the animation. A value of 1.0 maintains the default width, higher numbers increase the width, and lower numbers decrease the width.

Render Geometry

Enables rendering of the main trail geometry, leave this enabled.

Render Spawn Points

Enables debug rendering of the primary spawn points for the trail.

Render Tangents

Enables debug rendering of the curve tangents.

Render Tessellation

Enables debug rendering of all vertices on the curve, showing how the curve is tessellated between the spawn points.

Sync Marker

Sync Markers are Notifies used to inform marker-based animation syncing, which is useful for blending animations together and keeping overall motion synchronized. Similar to Skeleton Notifies, Sync Markers save to the Skeleton Asset, which requires you to save the Skeleton when adding them. You can then use the same Sync Markers repeatedly in any animation you want to synchronize while blending.



To learn more about using Sync Markers, refer to the Sync Groups page.

Montage Notifies

When creating Animation Montages, additional Animation Notify types are available to you to support montage-specific workflows. The following Notifies can be added in montages:

Montage Notify, which can be added by right-clicking on the Notify timeline and selecting Add Notify > Montage Notify.

Montage Notify Window, which can be added by right-clicking on the Notify timeline and selecting Add Notify State > Montage Notify Window.

Disable Root Motion, which can be added by right-clicking on the Notify timeline and selecting Add Notify State > Disable Root Motion.

Montage Notify

A Montage Notify operates similarly to standard Notifies in that it executes an event upon reaching the Notify keyframe. When reached, the On Notify Begin event is executed on the Play Montage Blueprint function. This requires playing the montage using the Play Montage node, instead of the Play Anim Montage node.



Montage Notify Window

A Montage Notify Window operates similarly to Notify States, in that the Notify operates over a duration you define. This causes both On Notify Begin and On Notify End to execute when the start and end of the Notify are reached. This requires playing the montage using the Play Montage node, instead of the Play Anim Montage node.



Disable Root Motion

A Disable Root Motion Notify operates similarly to Notify States, in that the Notify operates over a duration you define. This Notify suppresses root motion, allowing for user-input to control a character for its duration. This can be useful if you want to allow input control during parts of a montage, which locks out input by default.



Managing Your Notifies

As you create and use Animation Notifies, there are several features and properties that you can use to customize your workflow and Notify behavior.

Keyframe Editing

You can view information and commands for your Notify keyframes by right-clicking on them. The context menu shows the following:



Name

Description

Notify Begin Time

The time (in seconds) that this Notify is placed in the animation.

Notify Frame

The time (in frames) that this Notify is placed in the animation.

Min Trigger Weight

Determines how much weight (between 0 and 1) the animation needs to have to trigger the Notify. This is only relevant if the animation is being blended with another. The default value of 0.00001 means that even if this animation is barely blended in, the Notify will still execute. Setting it to higher numbers means that the animation must be blended in more fully in order for the Notify to successfully execute.

Anim Notify State Duration

The time (in seconds) of this Notify State's duration.

Anim Notify State Frames

The time (in frames) of this Notify State's duration.

Copy

Copies this Notify.

Delete

Deletes this Notify

Replace with Notify…

Replaces this Notify with another of the same type.

To assist with keyframe alignment, you can enable snapping options by right-clicking the top of the timeline and enabling either Frames or Notifies.



Common Notify Properties

In addition to the properties that can be modified for each type of Notify, Notifies also contain the following common properties:

Name

Description

Notify Color

Sets the color of the Notify keyframe.

Should Fire in Editor

Enables the Notify executing when previewing it in the Editor. This does not impact normal gameplay or simulation.

Notify Trigger Chance

Defines the chance of the Notify executing successfully. A value of 0 means the Notify never executes, and 1 means the Notify always executes.

Trigger on Dedicated Server

Enabling this causes the Notify to execute on dedicated servers.

Trigger on Follower

If enabled, this Notify also triggers when the animation is a follower, when using Sync Groups. By default, only Sync Group leader animations execute their Notifies.

Notify Filter Type

Defines a method for filtering Notifies to control if they should execute or not. You can filter by LOD and specify the maximum LOD to filter the Notify from.

Trigger Weight Threshold

Determines how much weight (between 0 and 1) the animation needs to trigger the Notify. This is only relevant if the animation is blended with another. The default value of 0.00001 means that even if this animation is barely blended in, the Notify still executes. Setting it to higher values means the animation must be blended in more fully for the Notify to successfully execute.

Montage Tick Type

When using Montage Notifies, this property determines how the Notify is ticked and executed in regards to its accuracy and sequential ordering. You can select either:

Queued, which is a less precise, asynchronous, but more performant ticking method. Select this if you are okay with minor frame inaccuracy when your Notify executes.

Branching Point, is a more precise, synchronous, and higher-cost ticking method. Select this if you want to ensure your Notify executes with maximum frame accuracy, which can be useful if you are using the Notify to execute other events in a controlled sequence. For example, Branching Point is useful when making gameplay-altering decisions, such as branching a decision based on this Notify.

Slot

When using Montage Notifies, this property links the Notify to an animation within a specific Slot, as some montages can have more than one Slot.

Link Method

When using Montage Notifies, this property defines the method to link a Notify to an animation. Linking will cause the Notify keyframes to follow the montage animation section if they are adjusted. You can select from:

Absolute, which disables any automatic adjustment.

Relative, which will move the notify with the segment, but not adjust if the scale changes.

Proportional, which will both move and adjust with the segment location and scale.

Linked Sequence

A read-only property that displays the currently-linked Animation Sequence. This changes if you align the Notify with a different sequence in a multiple-sequence montage.

Animation Notify Panel

The Animation Notifies panel can be used to manage your currently existing Skeleton Notifies. You can access it by right-clicking in the Notify timeline area and selecting Manage Notifies.



You can right-click on a Notify and perform the following actions:



Name

Description

New…

Creates a new Skeleton Notify.

Rename

Renames the currently-selected Skeleton Notify.

Delete

Deletes the currently-selected Skeleton Notify.

Find References

Opens the Animation Asset Browser Panel and filters the list to only show animation assets that use this Notify.

Custom Notify Classes

If your project requires different Notify classes from those provided, you can create custom Notifies and Notify States with their own pre-defined Blueprint logic. This is a way for you to extend and create different Notify templates.

To create new Notify classes, navigate to the Content Browser and click Add (+) > Blueprint Class. Navigate in the All Classes section and select either AnimNotify, to create a child class of a Notify, or AnimNotifyState, to create a child class of a Notify State.



To start building unique functions for AnimNotify classes, click the Override function drop down menu in My Blueprint and select Received Notify. This opens the function graph where you can now script custom logic from the Received Notify entry node.



You can override and implement the following functions in either AnimNotify or AnimNotifyState classes:

Function

Description

Get Default Trigger Weight Threshold

This function sets the default value of Trigger Weight Threshold for this Notify, however it can be overridden in the Notify keyframe details.

Get Notify Name

This function sets the name of the Notify or State keyframe in the timeline.

Received Notify

Used in standard Notifies, this function executes once when the Notify keyframe is reached.

Received Notify Begin

Used in Notify States, this function executes once when the Notify region begins.

Received Notify End

Used in Notify States, this function executes once when the Notify region ends.

Received Notify Tick

Used in Notify States, this function executes continuously throughout the duration of the Notify State.

Once you have created your custom Notify class, you can add it to the Notify timeline from either the Add Notify or Add Notify State menu.



Skeletal Mesh Animation System

Skeleton Editor

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Creating Skeletons

Skeleton Tree Information

Animation Data Storage

Sharing Skeletons

Merging during Import

Compatible Skeletons

Skeleton Features

A Skeleton is a hierarchy that is used to define Bones (sometimes called joints) in a Skeletal Mesh. In some ways, these Bones mimic a real biological skeleton due to their position and control over how characters deform.

In Unreal Engine, Skeletons are used to store and associate animation data, the overall skeletal hierarchy, and Animation Sequences. Skeleton Assets can also be shared through a variety of methods, enabling for additional animations and data to be shared between different Skeletons.

This document provides an overview of how to create and use Skeletons.

Your project contains a Skeletal Mesh Actor, or you have a skinned FBX character to import into Unreal Engine.

Creating Skeletons

The primary way to create a Skeleton is to import a skinned character FBX, which then converts to a Skeletal Mesh in Unreal Engine. When importing a Skeletal Mesh, in the FBX Import Options window, leaving the Skeleton field empty will automatically create a Skeleton Asset based on the skinned character being imported.



After importing your character, the Skeleton Asset will be created along with other Skeletal Mesh Assets.



You can also create a copy of a Skeleton from any Skeletal Mesh by right-clicking on it in the Content Browser and selecting Skeleton > Create Skeleton. This creates a new Skeleton associated with an existing mesh. If that mesh had another Skeleton associated with it, it will re-link to the new Skeleton and any animations will then link to the new Skeleton.



Double-click the Skeleton Asset to open the Skeleton Editor.



Skeleton Tree Information

Bones and other items displayed in the Skeleton Tree can appear different depending on several factors.

Icon

Description



A normal Bone that influences vertices on the Skeletal Mesh.



A Bone in the current Skeleton that doesn't influence vertices on the Skeletal Mesh. These Bones are typically used in an auxiliary manner, such as for attaching weapons or props, while still being animatable as a Bone.



A Socket, which is a static point that acts as an offset attachment point for Bones.



A Virtual Bone, which is a Bone that follows the transforms of another Bone, but in a different Bone space. These are useful for locking down unwanted joint movements, and are used in conjunction with IK.



A Bone that exists in the Skeleton, but is not used by the current Skeletal Mesh. This can happen if you have merged Skeletons, or are previewing different LODs on this Skeleton that are not using certain Bones.

Animation Data Storage

In addition to controlling animation, Skeletons in Unreal Engine also store animation-specific data. When data is created from those sources, such as creating an Animation Notify in an Animation Sequence, it gets added to the Skeleton as shared data.

Skeletons store the following types of animation data:

Animation Notifies.

Animation Curves.

Slots.

Retarget Sources.

Blend Profiles and Blend Masks.

This data can be viewed in dedicated tool panels by clicking Window in the Skeleton Editor menu, then enabling one or more of these panels.



Sharing Skeletons

An important feature of Skeleton Assets is that a single Skeleton Asset can be used by multiple Skeletal Meshes, so long as the Skeletal Meshes use the same general rig hierarchy. This means that the names and hierarchical order of your Bones must be consistent in order for sharing to work correctly.

For example, consider a limb with three Bones in a Skeletal Mesh. The bones are named 1, 2, and 3:



If you want to share this Skeleton with another Skeletal Mesh, you will need to keep these Bones in the same order and with the same names. The second Skeletal Mesh, however, can contain Bones that are additions or peripheral to the hierarchy. Any time animation data is received for a Bone that is not included in the Skeletal Mesh, that animation data will be ignored.

In that case, your new hierarchy could look like the image below. Here, the second Skeletal Mesh has extra Bones, while still retaining and not interfering with the original hierarchy from the first Skeletal Mesh.



However, in order for both Skeletal Meshes to use the same Skeleton Asset, you cannot change the hierarchy order or rename the Bones. If a second Skeletal Mesh uses a different Bone hierarchy and naming structure, you will need to create a new Skeleton Asset.



If you insert a bone into the hierarchy without changing the order, you will be able to share successfully. However in most cases the extra bone may cause unintended transform offsets in your skeleton. It is recommended that you avoid this if possible.



Taking these sharing rules into account, there are several ways you can share Skeletons between Skeletal Meshes in Unreal Engine. These are detailed below.

Merging during Import

The first method for sharing Skeletons is done during the FBX import process. When importing your new Skeletal Mesh (with additional and peripheral Bones compliant with the rules above), you can select a Skeleton from a Skeletal Mesh that already exists in your project. Unreal Engine will then merge the Skeletons, appending any new Bones into the hierarchy. Additionally, your Skeleton's proportions will be defined by the original Skeletal Mesh from which it was created.



If you are importing a Skeleton that is vastly different from the Skeleton you are attempting to merge to and breaks any sharing rules, you will see an error message:



In this case, you may need to create a new Skeleton Asset for the Skeletal Mesh you are importing, rather than merge into an existing one.

When viewing your merged Skeleton, you will see these additional Bones listed in your hierarchy, but they will only be visible and active for the Skeletal Mesh they are intended for.





Skeletal Mesh Variant 1

Skeletal Mesh Variant 2

Compatible Skeletons

Additionally, skeletons can non-destructively share animation assets by defining other skeletons as compatible. Compatible skeletons can share Animation Sequences, Montages, Animation Blueprints, and more.

To define another skeleton as compatible for a character, open the character's skeleton asset in the Skeleton Editor, and then open the Retarget Manager by clicking the button in the Toolbar.



In the Retarget Manager, locate the Manage Compatible Skeletons section of the Retarget Sources panel and click Add Skeleton to select another skeleton asset in your project using the context menu.



Now, animations can be shared from the Skeleton that was added to the Manage Compatible Sources list.



Skeleton compatibility is bi-directional. If you set Skeleton 1 to be compatible with Skeleton 2, that also means that Skeleton 2 is now compatible with Skeleton 1.

Creating and managing a system of compatible skeletons can be an effective way to optimize the number of animation assets your project requires to animate multiple characters. However, in order to utilize the Compatible Skeletons system, all characters must have nearly identical skeleton hierarchy structures and naming conventions. Additionally, all characters must have similar mesh proportions to achieve ideal results.

To share animations across characters with the same skeleton structure but with different proportions see the Animation Retargeting documentation.

To rebuild animation sequences to work across characters with radically different skeleton structures, see the IK Rig Retargeting documentation.

Skeleton Features

Skeletons in Unreal Engine support a variety of features for attaching, blending, and other settings. Refer to the following pages to learn more about these features:



Describes how retargeted animations can be used with multiple Skeletal Meshes, allowing you to share animations.

Describes how retargeted animations can be used with multiple Skeletal Meshes, allowing you to share animations.



Exclude Bones or change their individual blend speed by using Blend Masks and Blend Profiles.

Exclude Bones or change their individual blend speed by using Blend Masks and Blend Profiles.



Generate and modify LODs for Skeletal Meshes using the Skeletal Mesh Reduction Tool

Generate and modify LODs for Skeletal Meshes using the Skeletal Mesh Reduction Tool



Create attachment points within your Skeletal Mesh using Sockets.

Create attachment points within your Skeletal Mesh using Sockets.



Resolve layered animation problems by using Virtual Bones with IK.

Resolve layered animation problems by using Virtual Bones with IK.

Skeletons

Skeleton Editor

Animation Sequences





Animation Retargeting is a feature that allows animations to be reused between characters that use the same Skeleton asset but may have vastly different proportions. Through retargeting, you can prevent your animated skeletons from losing their proportions or becoming unnecessarily deformed when using animations from differently shaped characters. With Animation Retargeting it is also possible to share animations between characters that use different Skeleton assets as long as they share a similar Bone Hierarchy and use a shared asset called a Rig to pass animation data from one Skeleton to the other.

Why Use Retargeting?

How Does Retargeting Work?

How Are End Effectors Handled With Retargeting?

Setting Up Retargeting

Using the Retarget Manager

Why Use Retargeting?

Suppose you have multiple characters that you would like to share animations between A base character, a short stocky character, and a tall skinny character.







Base Character

Short Stocky Character

Tall Skinny Character

Results Before Retargeting

Before retargeting is applied, you can already use animations between any Skeletal Meshes that share the same Skeleton asset. However, when you have differing proportions, as shown above, you can get some unsightly results. Notice how the short character gets unnecessarily stretched and the tall character gets compacted, both so that they can fit onto the Base Character's skeletal proportions.







Base Character

Short Stocky Character

Tall Skinny Character

Results After Retargeting

Once retargeting is applied to the characters, the differences in their proportions are taken out of the equation and the animation plays properly on each character. You can also go to Show > Non-Retargeted Animation from the Viewport options and see the difference in the original skeleton (shown in beige) and the current skeleton (white). Notice how on the Base Character, the beige non-retargeted bones perfectly match the skeleton.







Base Character

Short Stocky Character

Tall Skinny Character

How Does Retargeting Work?

Animations are bound to a Skeleton asset. The Skeleton asset is really just a list of bone names and hierarchy data, but it also stores the initial proportions from the original Skeletal Mesh used to define the Skeleton asset. This data is stored as bone translation data. It is important to note that the retargeting system only retargets the bone's translation component. The bone's rotation always comes from the animation data.

Because the original Skeletal Mesh is used to define the proportions of the Skeleton asset, any other Skeletal Meshes using that Skeleton asset that have different proportions (such as a mesh that is much shorter than the original one) will require retargeting to work properly. Without it, the Skeletal Meshes of varied proportions would try to use the translation data of the original mesh, leading to the types of errors seen at the beginning of this document.

To solve this problem, the Skeleton Tree within the Skeleton Editor offers a few settings to change how translation retargeting between bones is handled. There are 3 different settings for Bone Translation Retargeting:



Animation - Bone Translation comes from the animation data, unchanged.

Skeleton - Bone Translation comes from the Target Skeleton's bind pose.

AnimationScaled - Bone translation comes from the animation data, but is scaled by the Skeleton's proportions. This is the ratio between the bone length of the Target Skeleton (the skeleton the animation is being played on), and the Source Skeleton (the skeleton the animation was authored for).

Also with Animation Retargeting, there is no significant difference in performance between using retargeted and non-retargeted animations. The benefit of using animation retargeting is increasing the number of unique characters without having to create an entirely new set of matching animations which could seriously cut down on your animation memory budget.

Retargeting Animations for Different Skeletons

The process in which Animation Retargeting is handled for characters that do not share the same Skeleton asset involves assigning a special asset called a Rig that processes animation data from one Skeleton to another. The Skeleton assets associated with each character communicate with the shared Rig asset to properly pass transform data from a source to its intended target.

The Rig can be assigned inside the Skeleton Editor under the Retarget Manager and the same Rig will need to be assigned to both Skeleton assets.

Please see Using Retargeted Animations for a step-by-step guide.

How Are End Effectors Handled With Retargeting?

Do tall characters run faster, can they still hold the same props - these are questions that may arise when working with retargeting. In short, there is no automatic work happening and it is up to the user to decide what they want it to do.

One method that can be taken regarding the holding of props is to create a separate chain of bones that follow the hands in the original animation, called "Hand IK Bones". Then retarget the body and arms, but not the "Hand IK Bones", so they remain identical after retargeting. This will allow you to have characters of different proportions manipulating the same props (for example, reloading a rifle).

Having a separate chain of bones allows you to switch smoothly between FK and IK easily when you want to (for example, you would want the Hand IK ON when reloading the weapon, and OFF when reaching for a magazine in a pocket).

The system is very flexible and can be customized to fit your needs. Perhaps you only want the left hand to be IK and the right hand to use its FK position, but IK rotation. Feet are sometimes handled this way, sometimes not. When stepping on a very precise prop, you would want to turn on IK; when you are just running around, you would want to use the FK, so you do not end up with a bow-legged character (or the opposite).

Setting Up Retargeting

As mentioned above under How Retargeting Works, the first thing you will want to do is set up the Bone Translation Retargeting mode for the Bones within the Skeleton.

Typically, you will want to use these settings for bipeds:

Root Bone, IK Bones, weapon bones, and any kind of markers will use the Animation mode.

The pelvis will use AnimationScaled so it sits at the right height and is still animated.

Any other bone you want translation to be animated and retargeted should also use AnimationScaled.

All other bones will use Skeleton. They will use the static translation from the target skeleton.

This means that a fast workflow would be:



Right-click on your root bone and Recursively Set Translation Retargeting Skeleton so all bones are set to Skeleton.

Find the Pelvis or equivalent bone and set that to AnimationScaled.

Find the Root bone, any IK bones, any weapon bones, or other marker-style bones and set them to use Animation.

If you are retargeting animations for characters that share the same Skeleton asset, those animations will now be affected by animation retargeting. If you want to retarget animations for characters that do not share the same Skeleton asset, there a couple extra steps you will need to take to ensure the animations are properly retargeted. Please see Using Retargeted Animations for more information.

Using the Retarget Manager



Another tool you can use as part of your Animation Retargeting efforts is the Retarget Manager which allows you to:

Manage Retarget Source assets - useful for when you have different proportional meshes per skeleton, you can use this setting to indicate if a particular animation is from a different source.

Set up Rig - which allows you to retarget animations to different skeletons that use the same rig.

Manage Retarget Base Pose - which is used when retargeting assets to a different skeleton and allows you to alter the base pose of the target so it lines up with the source's base pose and provides a more accurate retargeted animation.

Please see the Retarget Manager page for more information.

Blend Masks

Creating Blend Masks

Editing Blend Mask Values

Using Blend Masks

Blend Profiles

Time Blend Profile

Weight Blend Profile

Using Blend Profiles

As you create complex animation logic, it may be necessary to have more refined control over the way your animation blends, instead of just blending all bones at once. Blend Masks can be used to exclude bones from a blend, and Blend Profiles provide control over the rate at which different bones blend. These additional blending controls can improve the fidelity and compatibility of your gameplay animation.

This page provides an overview of how to create and use Blend Masks and Blend Profiles.

Your project contains a Skeletal Mesh Actor, along with Animation Sequences.

You have a basic knowledge of how to create and use Animation Blueprints.

Blend Masks

Blend Masks are definitions you can add to your skeleton where you can define weight influences, disabling animation from playing partially or fully on specific bones. You can then use this pre-set definition on the Layered Blend Per Bone to play animation on certain bones.

A common use-case for using Blend Masks is to exclude lower-body bones so that animation plays only on the upper-body, regardless of the full-body state. This is useful for weapon-based animations that require the upper-body bones to ignore the rest of the body, such as reloading, equipping, or shooting.





Using Blend Masks

No Blend Masks

Creating Blend Masks

You create Blend Masks within the Skeleton Tree of your Skeletal Mesh. Click the Options dropdown menu in the Skeleton Tree and select Add Blend Mask. Give it a name and press Enter.



Once created, a Blend column appears within the Skeleton Tree listing your Blend Mask. If you have multiple Blend Masks, you can switch between them by clicking them in the Options menu.



To delete the currently-viewed Blend Mask, click the Options dropdown menu in the Skeleton Tree and select Remove.



Both Blend Masks and Blend Profiles are stored in the Skeleton asset. Therefore, when creating or editing Blend Masks, you are editing the Skeleton asset.

Editing Blend Mask Values

The Blend column shows the current values of each bone within your Blend Mask. Each bone can have an assigned value between 0 - 1. A value of 0 will cause no animation to play on that bone, and a value of 1 will cause animation to play at 100% value.

You can edit these values by either dragging on the value to enable the slider control, or by selecting and typing in a value directly.



You can also set the same value to all children by right-clicking on a bone and selecting Recursively Set Blend Scales, which applies this blend value across several bones at once.



If you do not see the column for editing Blend Mask values, you may need to right-click on the property header and enable Blend Profile.



Using Blend Masks

Once you have created and set appropriate values for your Blend Mask, you can use it in your Animation Blueprint. This is done by setting your Blend Mask on the Layered Blend Per Bone node within the Anim Graph.

In your Animation Blueprint Anim Graph, right click and create a Layered blend per bone node, then set the following properties in the Details panel:

Set Blend Mode to Blend Mask.

Set Blend Masks to your Blend Mask.



Connect your incoming source base and blend poses and you can now observe that the Blend Mask is working. In this example, we used an upper-body Blend Mask.



Although this behavior is possible by using the default Branch Filter Blend Mode on the Layered Blend per bone node, Blend Masks let you reuse these blend amounts on your bones more easily.

Blend Profiles

Blend Profiles are definitions you can add to your skeleton where you can define per-bone blend speeds, causing some bones to blend faster than others. Blend Profiles can be used when blending using the following methods:

Blend Poses by bool.

Blend Poses by int.

Blend Poses by enum.

State Machine Transitions.

Animation Montages.

A use case for using Blend Profiles might be to blend the lower-body faster than the upper-body, which can be useful when transitioning between idle and locomotion states. This can make the feet appear to plant firmly on the ground when stopping, and start more naturally before the upper body when starting to move.





Using Blend Profile (Legs are blending faster)

No Blend Profile

Similar to Blend Masks, Blend Profiles are created, managed, and edited in the Skeleton Tree. Click the Options dropdown menu in the Skeleton Tree and select either Add Time Blend Profile or Add Weight Blend Profile.



Because the list of Blend Masks and Blend Profiles occupy the same column and option menu region, you should ensure that they are clearly named to avoid confusion.



Time Blend Profile

Time Blend Profiles are Blend Profiles that blend using a normalized (0 - 1) multiplier against the base blend value. A value of 1.0 blends at normal speed, and lower numbers blend faster. A value of 0.0 causes the blend to be instantaneous.

For example, if you set the following:

Pelvis and all upper-body bones set to 1.0.

Legs and all lower-body bones set to 0.5.

This causes the legs to blend twice as fast, according to the base blend time wherever you use this Blend Profile. If it is used on a Blend Poses by bool node, with the base blend time set to 2.0 seconds, then the legs blend over only 1.0 seconds. All other bones set to 1.0 still blend over the base 2.0 seconds.



Weight Blend Profile

Weight Blend Profiles are Blend Profiles that blend using a weight factor against the base blend value. A value of 1.0 will blend at normal speed, and higher numbers will blend faster.

For example, if you set the following:

Pelvis and all upper-body bones set to 1.0.

Legs and all lower-body bones set to 2.0.

This causes the legs to blend twice as fast, according to the base blend time wherever you use this Blend Profile. A value of 2.0 means the blend will be 2x faster, 3.0 will mean 3x faster, and so on.



Using Blend Profiles

Once you have created and set appropriate values for your Blend Profile, you can apply it in the following ways:

On Blend Pose nodes in the Animation Blueprint Anim Graph, select the node and locate the Blend Profile property in the Details panel.



On State Machine transition rules, select the transition rule and locate the Blend Profile property in the Details panel.



In the Animation Montages editor, you can set a different Blend Profile for blending in and out of the Montage using the Blend Profile In and Blend Profile Out properties in the Asset Details panel.



Skeletal Meshes

Skeletons

Creating LODs

Generate LODs

Skeletal Mesh Reduction Tool

Bones to Prioritize

Lock Mesh Edges

Termination Criterion

Volumetric Correction

Reducing Bones

Properties Reference

LOD Picker

LOD Info

Skeletal Mesh Reduction Tool

Console Commands

In Unreal Engine, you can generate Skeletal Mesh LOD (Level of Detail) model variants to optimize gameplay. In the following document you can read about using the LOD generation tool and the Skeletal Mesh Reduction Tool features to tweak the LOD generation to retain details and more precisely optimize Skeletal Meshes.

Your project contains a Skeletal Mesh.

Your project has the Skeletal Mesh Reduction Plugin enabled.

First open in the Project Settings window by clicking Edit > Project Settings in the Menu Bar. In the Project Settings window, navigate to the Skeletal Mesh Reduction Simplification category and ensure the Skeletal Mesh Reduction Plugin property is set to SkeletalMeshReduction.



Creating LODs

With your Skeletal Mesh, you can use the LOD Generation tool to create LOD variants of the model for use in your project.

In some cases, LODs for a Skeletal Mesh are created in an external DCC (digital content creation) software. The Skeletal Mesh Reduction Tool can be used in cases where externally created LODs are present, but any regenerated LOD will overwrite any existing LOD, even LODs imported from an external source.

Generate LODs

First, open the Skeletal Mesh you wish to generate LODs for. In the Asset Details panel of the Skeletal Mesh Editor, navigate to the LOD Settings section.

With the Number of LODs property you can define how many LODs you wish to generate.

Generating 4 LODs, would result in a total of 4 LODs for the Character. LOD 0 being the highest quality Mesh imported into Unreal Engine. Beginning with LOD 1, each increasing LOD is a step down in quality for the Skeletal Mesh, with LOD 3 being the lowest quality mesh.

Click Apply Changes to generate the new LODs for your Skeletal Mesh.



You will be prompted to select a location to save a LODSettings file, this can be saved in the same location as your Skeletal Mesh and any related files.

The generated LODs will now be visible in the LOD menu option within the Viewport.

Skeletal Mesh LODs



Depending on the complexity of your Skeletal Mesh and the power of your hardware, the LOD generation process may take some time to complete.

LODs can be individually modified and regenerated at any time by selecting Regenerate LOD from within an Individual LODs Reduction Settings, or the entire set can be modified and regenerated with Apply Changes from the base LOD's (LOD 0) LOD Settings.

LODs that have been generated using Unreal Engine, will have a note next to their property section in the Asset Details panel, indicating that it has been [generated].



Skeletal Mesh Reduction Tool

When generating LODs in Unreal Engine, there may be some cases where the Mesh reduction can eliminate key or important details of the Mesh. Using the Skeletal Mesh Reduction Tool, you can more precisely define how LODs are generated, and control the reduction effect.

Bones to Prioritize

Within an individual LOD's set of properties in the Asset Details panel, you can use the Bones to Prioritize property to preserve the associated skinned geometry quality.





First, in the Asset Details panel locate the LOD Picker section and enable the Custom property. This will allow you to see each LOD's set of properties in the Asset Details panel.



Next, in an Individual LODs properties, Navigate to LOD Info > Bones to Prioritize and click (+) to add a new element to the array.



To preserve a structure in the Skeletal Mesh, select each bone within the structure from the drop down menu. Defining an individual bone in each array element.



Once you have defined all the bones of a structure you wish to preserve, set a high value for the Weight Of Prioritization property under LOD Info, for example 5,000, and then select Regenerate LOD.



Here is an example of a mesh with defined bones to prioritize when generating a LOD.





Lock Mesh Edges

Another method of controlling the LOD generation process to reduce any visual errors using the Lock Mesh Edges feature. Lock Mesh Edges will lock mesh Vertices in place which will attempt to maintain the structure of the simplified mesh at mesh edges at the cost of more triangles. This property can be helpful when vertices are disconnected from the mesh, causing visual errors along the mesh edges.

To enable the Lock Mesh Edges property, expand a LOD's properties in the Asset Details panel. Under the Reduction Settings, enable Lock Mesh Edges and then select Regenerate LOD.



Termination Criterion

With the Termination Criterion properties you can control the amount and the method used to calculate what mesh geometry is retained at each individual LOD level during the LOD generation process. When generating or regenerating LOD meshes for your project's Skeletal Meshes you can choose to specify the number, or percentage, of triangles or vertices thresholds that must be met when optimizing a set of LODs or an individual LOD level.

Generally speaking, the memory cost of a Skeletal Mesh is related to the number of vertices in the mesh geometry, while certain rendering costs are more closely tied to the number of triangles.

Select the highest quality LOD (LOD 0) of your Skeletal Mesh and then expand its Reduction Settings.



In the Termination Criterion property you can select what method by which to optimize the Mesh during the LOD generation process. From the drop down you can select your desired optimization method.

Depending on the optimization method chosen, additional properties will be accessible that you can use to fine tune the LOD generation method to fit your project's needs. For a full list of the Termination Criterion properties, with accompanying descriptions, please see the Skeletal Mesh Reduction Tool section of the Properties Reference.

After these properties are defined, select Apply Changes to generate or regenerate the Skeletal Mesh's set of LODs or Regenerate LOD if modifying the Termination Criterion for an individual LOD level.

Volumetric Correction

Volumetric Correction controls space occupied by the optimized Skeletal Mesh when compared to its source. When disabled (with a value of zero), the simplification process will flatten and deflate rounded surfaces. You can slightly increase (with values greater than 1) or decrease (with values less than 1) the volume of the Skeletal Mesh LOD by adjusting the Volumetric Correction property.

Typically the default setting (a value of 1.0) will give the best results.

You can apply volumetric correction to an entire set of LODs with the Volumetric Correction property that can be accessed in the LOD 0 Reduction Settings, and then selecting Apply Changes.



Volumetric Correction can be applied to each individual LOD's Reduction Settings and selecting Regenerate LOD.

Reducing Bones

When working with Skeletal Mesh LODs there may be situations where you want to reduce the amount of Bones in a Skeletal Mesh's Skeleton Asset alongside the reduction in the Mesh. Unlike the LOD generation workflow, this process requires the manual definition of the bones you wish to remove.

Within the desired LOD's LOD Info properties, navigate to the Bones to Remove property. Using the (+), add an array element and select a bone you wish to remove in the drop down menu.



Add a new array element and define a bone for each individual bone you wish to remove at the selected LOD level.



After defining each bone you wish to remove, select Regenerate LOD.

When a Skeletal Mesh's LOD has had bones removed from its skeleton, the Bones will still be visible in the Skeleton Tree of the LOD, however they will be indicated with a dot icon rather than the usual bone icon.



Properties Reference

Here you can reference properties relevant to Skeletal Mesh LODs while working in the Skeletal Mesh Editor's Asset Details panel.



LOD Picker

In the LOD Picker property section you can choose which LOD's properties will be accessible in the Asset Deteails panel.

Property

Description

LOD

From the drop down you can toggle which LODs properties are visible in the Asset Details panel. By default only one LODs properties are visible at a time.

Custom

When toggled you can use the Advanced property drop down menu to toggle which LODs properties will be visible, enabling multiple LOD property sets to be visible at once.

Advanced

Toggle each individual LOD's property set to be visible in the Asset Details panel.

LOD Info

For each LOD variant associated with a Skeletal Mesh, a set of the following properties will be accessible, after switching to the individual LOD in the Viewport, or by selecting the LODs you wish to view in the LOD Picker property section.

Property

Description

LOD Hysteresis

This value is used to avoid ‘flickering' when crossing a LOD threshold. Only taken into account when transitioning from a complex to a simple LOD. Higher values will increase the hysteresis, or lag, of the perceived model, which can smooth transitions between radically different LODs.

Bones to Prioritize

While the Skeletal Mesh Reduction tool is effective at reducing the triangle count of Skeletal Meshes, there can be instances where the reduction is too aggressive. To provide more control over what is optimized and what is not, the Bones to Prioritize array makes sure that any geometry skinned to the bones in the list will not be optimized. Listed here is an array of Bones which should be prioritized to retain quality. Use the Weight of Prioritization property below to control the value at which these are prioritized.

Sections to Prioritize

Similar to the Bones to Prioritize property above, this property is an array of Sections, or Material Slots, which should be prioritized to retain quality. Use the Weight of Prioritization property below to control the value at which these are prioritized.

Weight of Prioritization

Listed here is the value that determines how much consideration to give the Bones to Prioritize and Sections to Prioritize properties. The weight is an additional vertex simplification penalty where 0 means nothing. Higher values increase the weight of prioritization for listed Bones and Sections, while lower values reduce the weight of prioritization.

Source Import Filename

Listed is the source file directory, for the base mesh FBX file, and any separated associated custom LOD source files.

Skin Cashe Usage

This drop down menu will set the LODs behavior in using the skin cache feature. Options are as follows:

Auto defers to the default project global option established in the project settings.

Disabled means the Mesh will not use the skin cache.

Enabled means the mesh to use the Skin Cache.

If the Support Ray Tracing property is enabled on the mesh, it implies Enabled by default.

Morph Target Position Error Tolerance

The property value is displayed in microns. Larger values result in better compression and lower memory footprint, but also lower quality.

Bake Bose

Select a single frame of animation to bake into a pose. This is useful when automatic LOD generation is removing bones for lower detail LODs but you want to retain a finer detail that has been removed. For more information, refer to the Pose Asset page.

Bake Pose Override

Overrides the Bake Pose property. The source Bake Pose can be disabled if some LOD settings are in use. For more information, refer to the Pose Asset page.

Bones to Remove

An array of Bones to be removed from the skeleton for this LOD level.

Skeletal Mesh Reduction Tool

Here you can reference a list and description of the Skeletal Mesh Reduction Tool properties you can use to tailor the LOD generation process for your Skeletal Mesh.

Property

Description

Termination Criterion

The Termination Criterion option in the Skeletal Mesh Reduction tool gives you the ability to change the way the simplifier reduces the Skeletal Mesh asset in LOD generation. For example, you can specify the number (or percentage) of vertices, instead of triangles, to provide more control to better fit memory or performance targets.

The available options for reduction technique are as follows:

Triangles: Relying on the Percent of Triangles property, the Reduction Tool targets a percentage of triangles of the base mesh to generate a LOD.

Vertices: Relying on the Percent of Vertices property, the Reduction Tool targets a percentage of vertices of the base mesh to generate a LOD.

First Percent Simplified: This option will generate a simplified LOD by factoring both Percent of Triangles and Percent of Vertices, completing the LOD with whichever factor is achieved first.

Max Triangles: This option will generate a LOD using an established maximum number of triangles, in the Max Triangle Count property.

Max Vertices: This option will generate a LOD using an established maximum number of vertices, in the Max Vertex Count property.

First Max Satisfied: This option will generate a simplified LOD by factoring both Max Triangles and Max Vertices, completing the LOD with whichever factor is achieved first.

Depending on which Termination Criterion is selected the following options will dynamically change to the relevant properties.

Percent of Triangles

This property is a target percentage value of triangles to generate a simplification of the source mesh for a new LOD.

Percent of Vertices

This property is a target percentage value of vertices to generate a simplification of the source mesh for a new LOD.

Max Triangles Count

The maximum number of triangles to retain when using the percentage criterion. A maximum value to limit the automatic generation.

Max Vertices Count

The maximum number of vertices to retain when using the percentage criterion. A maximum value to limit the automatic generation.

Max Triangles Count

The maximum triangles to retain when using the Max Triangle criterion.

Max Vertex Count

The maximum vertices to retain when using the Max Vertices criterion.

Remap Morph Targets

Remaps the existing morph targets from the base LOD to the reduced LOD selected.

Max Bone Influence

The maximum number of bones that are assigned to each vertex.

Enforce Bone Boundaries

If enabled, Unreal will penalize edge collapses between vertices that have different major bones attached. This helps articulated segments like tongues, but can lead to undesirable results under extreme simplification.

Merge Coincident Vertices Bones

If enabled, the same location, for example UV boundaries, always has the same bone weights. This can fix bone merge errors when the characters are animated.

Volumetric Correction

A slider to determine the Volumetric Correction implemented at this LOD level. The default value of 1 attempts to preserve volume. Smaller values will lose volume by flattening curved surfaces, and larger values will accentuate curved surfaces.

Lock Mesh Edges

If enabled, cuts in the mesh's surface are preserved by locking vertices in one place. This increases the quality of the simplified mesh at edges, at the cost of more triangles.

Lock Vertex Color Boundaries

If enabled, edges that connect two vertex colors are locked. This increases the quality of the simplified mesh at edges at the cost of more triangles.

Regenerate

If pressed, Unreal will regenerate the current LOD with the applied Reduction Tool properties above.

Console Commands

Here is a reference to helpful console commands you can use while working with Skeletal Mesh LODs.

Command

Description

FORCESKELLOD LOD=X

Forces a Skeletal Mesh to render at the assigned LOD level, where X is any available LOD number for the Skeletal Mesh.

a.VizualizeLODs

To draw LODs during runtime.

Creating Sockets

Managing and Editing Sockets

Socket Visibility

Selection and Movement

Copy and Paste

Mesh Sockets

Socket Details

Attaching with Sockets

Basic Level Attachment

Basic Blueprint Attachment

Dynamic Attachment

When attaching objects to Bones on your Skeletal Mesh, it may be necessary to offset this attachment. Instead of using math operations to estimate the offset transform, you can create Sockets. Sockets are dedicated attach points within the hierarchy of your Skeleton, which can be transformed relative to the Bone it is parented to. Once set up, you can attach your objects, weapons, and other actors to the Socket.

This document provides an overview of how to create and use Sockets.

Your project has a Skeletal Mesh.

Creating Sockets

Sockets are created from the Skeleton Tree, which can be accessed from any of the main Animation Editors. Right-click on a Bone in the Skeleton Tree and select Add Socket.



Your new Socket will now be displayed in the Skeleton Tree, parented to the Bone that you selected previously.



Sockets can be deleted by right-clicking on them and selecting Delete or by pressing Delete on your keyboard.



By default, when creating and manipulating Sockets, this will edit the Skeleton Asset of your Skeletal Mesh. Therefore, you must save it when making Socket changes.

Managing and Editing Sockets

Once you have created a Socket, you can interact with them in the following ways.

Socket Visibility

By default, Sockets are not visible in the Animation Editor Viewport, you can make them visible by navigating in the Viewport menu to Character > Bones, and enabling Sockets.



Selection and Movement

Sockets can be selected by either clicking them in the Skeleton Tree, or if made visible in the viewport, by clicking them in the Viewport. You can then move them by dragging on the transform manipulator in the Viewport. Sockets can be translated, rotated, and scaled.



Copy and Paste

Sockets can be copied and pasted in different ways depending on your requirements.

To copy a Socket, right-click on it in the Skeleton Tree and select Copy Selected Sockets, or press Ctrl+C.



Next, you can choose to either:

Paste the Socket to the same bone, which is done by right-clicking on any Bone in the Skeleton Tree and selecting Paste Sockets. This will essentially duplicate the Socket.



Paste the Socket to a different Bone, which is done by right-clicking a different Bone in the Skeleton Tree and selecting Paste Sockets To Selected Bone. This will paste a copy of that Socket with the same offset information, but parented to the new Bone.



Mesh Sockets

When sharing Skeletons between different Skeletal Meshes, it may be necessary to create Sockets that are exclusive for one of the Skeletal Meshes. This can be done by using Mesh Sockets, which will make a Socket exist on the Skeletal Mesh, instead of the Skeleton.



To make a Mesh Socket, right-click an existing Socket and select Create Mesh Socket. This will convert the Socket into a Mesh Socket. Ensure that you are currently using the Skeletal Mesh Editor for the Skeletal Mesh you want to create this for.



As with Sockets existing on the Skeleton Asset, Mesh Sockets will instead exist on the Skeletal Mesh, requiring you to save that asset if you create or modify Mesh Sockets.

Socket Details

Sockets contain the following properties in the Details panel when selected.



Name

Description

Relative Location / Rotation / Scale

The current transform coordinates of the Socket in relative coordinates to its parent Bone in either location, rotation, or scale.

Force Always Animated

Enabling this will cause all parent bones of this Socket to always evaluate, regardless of if they are being removed due to the current LOD setting.

Socket Name

The name of this Socket.

Bone Name

The name of the Bone this Socket is attached to. Changing this value to a different Bone will re-parent the Socket.

Attaching with Sockets

Once you have created and positioned your Socket, you can attach objects, effects, and other actors to it. The following kinds of attachments can be performed.

Basic Level Attachment

You can set up a basic attachment within a Level, where an object will be attached to a Socket by default. There are a few ways you can do this.



In the Level Outliner, drag the object onto your Skeletal Mesh Actor. A window will appear after where you can select any Bone or Socket to attach to. Select your Socket and the attachment process will complete.



When attaching in the Level, the object will retain its world transform from before, which can be useful if you are creating unique offsets for different objects. If you want the object to match the Socket's transform, then set the transform values of the object to default.



Right-click your object and select Attach To, then click on your Skeletal Mesh Actor. A window will appear after where you can select any Bone or Socket to attach to. Select your Socket and the attachment process will complete.



Click the Settings dropdown menu in the Level editor and select Enable Socket Snapping. This will make all Sockets visible in the viewport.



Next, you can quickly attach an object to any visible Socket by selecting the object first, then selecting a Socket.



Basic Blueprint Attachment

You can also set up a basic default attachment to a Skeletal Mesh Component in Blueprints.

First, parent the object to the Skeletal Mesh Component by dragging the object on the Skeletal Mesh in the Components panel.



Next, select the child object, and in the Details panel locate the Parent Socket property. Click the search button and select the Socket to attach to.



Dynamic Attachment

In cases where you want to control when your object attaches and detaches to Sockets, you can use various Attach and Detach Blueprint functions.

For attaching, you can use the following functions:

Attach Actor To Actor.

Attach Actor To Component.

Attach Component To Component.



Attaching functions contain the following properties:

Name

Description

Target

The child actor or component that is being attached.

Parent

The parent actor or component that the Target is being attached to.

Socket

The Socket to use when attaching

Location / Rotation / Scale Rule

Transform rules that control where the Target should end up after being attached. You can select from the following options:

Keep Relative, which maintains the current transform numerical values. This will likely cause the Target to pop into a new position and is useful to maintain the same offset coordinates when attaching.

Keep World, which will maintain the current visual transform of the Target. This will not cause a pop when attaching as a calculation will occur to maintain the same visual transform before and after the attachment.

Snap to Target, which will teleport the Target to the coordinates of the Parent or Socket.

Weld Simulated Bodies

Whether or not to weld the Target to the Parent.

For detaching, you can use the following functions:

Detach From Actor

Detach From Component



Virtual Bone Overview

Differences from Traditional IK

Creating Virtual Bones

Animation Blueprint Setup

Slot Setup

Exclude Virtual Bones

IK Setup

View Results

When building complex blending, layered, or compressed animation systems, there may be cases where this causes extra and undesired movement (known as "swimming") on character limbs, typically on hands and feet. Virtual Bones, used in combination with IK nodes, can be used to correct this unwanted behavior.

This document provides an overview of how to create Virtual Bones in your Skeleton, and use them within your Animation Blueprint.

Your project contains a Skeletal Mesh Actor.

You have a basic understanding of working in Animation Blueprints.

Virtual Bone Overview

Virtual Bones are Bones that follow the transforms of another Bone, but in a different Bone space. In most cases this means that a Virtual Bone would be parented to the root Bone, but following an end Bone, like a hand or foot. In other words, Virtual Bones can directly follow a target Bone, without receiving the additional effects of the forward kinematic (FK) hierarchy of all joints leading to that target. Using this feature, you can set up inverse kinematic (IK) systems which make the character limbs follow the Virtual Bone, resolving "swimming" and other limb wobbling problems from complex animation systems.

In this example, Virtual Bones with IK are being used to maintain the rifle and hand positions while an additive head-look animation is playing. Without it, the hands and weapon will "swim" causing unintended movement.





Using Virtual Bones

No Virtual Bones

Differences from Traditional IK

One of the main aspects of Virtual Bones is that they follow the target bone. This makes it so that you can still play an animation in which the target bone can move, changing the position of the Virtual Bone. Such a setup can be superior to traditional IK-only systems where IK can interfere with animation. For example, if you were to set up a system where the hands were IK-attached to a weapon, you would have to perform extra steps to disable IK in certain situations, such as reloading.

In this example, Virtual Bones with IK are still able to allow for base hand movement relative to another object, even with the additive animation playing. Although a traditional IK setup might resolve the "swimming" issue, the result will pin the hands in place at all times, forcing you to create extra logic to turn off IK during cases like this.





Virtual Bones allowing for base hand movement

IK-only setup which pins the hands in place

Creating Virtual Bones

You can create Virtual Bones in the Animation Editor's Skeleton Tree. Right-click on a Bone, which will be the parent, and then select Add Virtual Bone. Select a Bone from this list to specify the target. In this example, a Virtual Bone is being created parented to the root Bone, then targeting the hand_l Bone.



Once created, you should now see the Virtual Bone as a child of the parent Bone, but matching the transform of the target Bone. By default, Virtual Bones are automatically named as VB <Parent>_<Target> for their naming convention.



You can also preview an Animation Sequence and observe the Virtual Bone following the target Bone for the duration of the animation.



Animation Blueprint Setup

Once you have created your Virtual Bones, you can set up logic for them in Animation Blueprints. Due to the arbitrary nature of Virtual Bones, there are many different ways you can use them. This section will demonstrate how to create a basic weapon override and additive animation setup for Virtual Bones.

Slot Setup

First, in your Animation Blueprint Anim Graph, create two Slot nodes. Slots are proxy areas in your Animation Blueprint where you can insert one-off animations, and will be used to differentiate between your base and additive animation layers.

Right-click in the Anim Graph and select Montage > Slot ‘DefaultSlot' to create a Slot.



For the second Slot, select it and set the Slot Name property in the Details panel to a different value other than DefaultSlot, so that the animations diverge correctly.



Connect your Slots to an Apply Additive node, connecting the default Slot to the Base pin, and the additive Slot to the Additive pin.



Exclude Virtual Bones

Next, you will need to create a Blend Mask in order to exclude the Virtual Bones from being evaluated from your additive Slot.

In the Animation Editor's Skeleton Tree, click the Options dropdown menu and select Add Blend Mask. Give it a name and press Enter.



Next, navigate to your Virtual Bones and set their blend values to 0.0.



Returning to the Anim Graph, create a Layered Blend per Bone node and set the following properties on it:

Set Blend Mode to Blend Mask.

Set Blend Masks to your Virtual bone-excluding Blend Mask.



Connect this node so that it is in between your additive Slot and Apply to Additive node, connecting the Slot only to the Blend Poses pin. Now, as animation plays from this additive Slot, the Blend Mask will cause the additive animation to not affect the Virtual Bones.



IK Setup

Lastly, you will need to create an IK setup that causes the limb to follow the Virtual Bone, while the additive layer will exclude any extra Virtual Bone movement.

Create a Two Bone IK node and set the following properties on it in the Details panel:

Set IKBone to your ending target Bone for this limb.

Set Effector Location Space to Bone Space.

Enable Take Rotation from Effector Space, which will add rotation to the IK Bone.

Set Effector Target to your Virtual Bone for this limb.

Set Joint Target Location Space to Parent Bone Space.

Set Joint Target to the same value of IKBone.



Joint Target Location is used to define the IK Pole Vector, which should be set to a position behind the elbow. Depending on your character's joints, this value may be different. For the default Unreal Engine mannequin, this value is set to:

X: -25.0

Y: -50.0

Z: 0.0



Create additional Two Bone IK nodes for each limb you want to match to a Virtual Bone.

View Results

Once fully complete, your Anim Graph should look something like this, where you have:

Slot nodes for your base and additive animation layers

The Slots are connected to an Apply Additive node, and a Layered Blend per Bone node is being used to exclude the Virtual Bones from the Additive layer using a Blend Mask.

IK nodes are being used on the limbs to attach to the final Virtual Bone location, which will use the base animation layer.



Now when playing your animations within this framework, you should see your character's limbs following the Virtual Bone position, while not being affected whenever additive animations are playing.



Blend Space Overview

Blend Space Creation and Types

Blend Space

Aim Offset

1D

Blend Space Setup

Defining Axis Names and Ranges

Adding Animations to the Graph

Referencing in Animation Blueprints

Editor Overview

Asset Details

Blend Graph

Blend Spaces are assets that allow multiple animations or poses to be blended by plotting them onto either a one or two-dimensional graph. This graph can then be referenced within Animation Blueprints where the blending can be controlled by gameplay input or other variables. By using Blend Spaces, virtually any type of blending arrangement can be used for your animations.

This document provides an overview of Blend Spaces, their different types, and their setup.

Your project has a Skeletal Mesh with various directional or similar Animation Sequences imported.

Blend Space Overview

Blend Spaces are assets where you specify animations along a graph at various points, called samples. The overall animation is calculated by blending between the points on the graph based on input values for each axis. For example, a locomotion system that blends between directional movement and idle animations can be created.



Blend Space Creation and Types

There are different types of Blend Spaces, which provide different functionality in either the asset editor, or how they are used within Animation Blueprints.

The following Blend Space types can be created by clicking on the Add (+) button in the Content Browser, then selecting from the Animation menu:

Aim Offset

Aim Offset 1D

Blend Space

Blend Space 1D



Blend Space

Regular Blend Spaces are the base variety of Blend Space, which provides all the main functionality of blending animations along the graph. They are intended to be referenced within Animation Blueprints as a base layer, with secondary animations proceeding from it.



Aim Offset

Aim Offsets are Blend Spaces meant to contain mesh-space additive animations as their samples. Typically, these are used to create weapon or other look-at aiming blend spaces. Aim Offset Animation Blueprint nodes are intended to receive an input pose along with the normal axis inputs



Refer to the Aim Offsets page for more information on how to use them.



An Aim Offset is a type of Blend Space that uses additive poses, typically for creating aim-spaces.

An Aim Offset is a type of Blend Space that uses additive poses, typically for creating aim-spaces.

1D

Both Blend Spaces and Aim Offsets also support single-axis (1D) variants. Typically these Blend Spaces are used when you only need a single axis of blending. In the case of Blend Space 1D or Aim Offset 1D, the graph only provides a horizontal axis.



Although 1D Blend Spaces are available, normal 2D graphs can also be used in a one-dimensional way by only using a single axis for your sample placement. This way, you can expand the Blend Space from 1D to 2D if needed.

Blend Space Setup

After creating and opening your Blend Space type, proceed with the following setup.

Defining Axis Names and Ranges

In most cases, you will want to define the names and value ranges of the axes used in your Blend Space. To do this, navigate to the Asset Details panel and change the following properties located in the Axis Settings category:

Name

Minimum Axis Value

Maximum Axis Value



Depending on the type of Blend Space, you may want to use different value scales, such as -90 to 90, or -180 to 180 if you are creating an Aim Offset and want your grid to match rotation values.

Adding Animations to the Graph

You can populate the graph with animations by dragging them from the Asset Browser or Content Browser onto the graph. Holding Shift will cause the animations to snap to the grid points which can be useful for alignment. Depending on what kind of Blend Space you want to create, these can either be looping animations or static poses.



Because 1D Blend Spaces only have a single axis for input, you can only apply animations along that single axis.



In this example, the vertical and horizontal axes are mapped to the direction and speed, respectively. Several cycle-based animations are then set up to blend appropriately based on the values of these inputs resulting in the final pose you see in-game.



Referencing in Animation Blueprints

Once you have a completed graph, you can reference and manipulate the Blend Space in Animation Blueprints. To add your Blend Space, right-click in the AnimGraph and locate your Blend Space. You can also drag it from the Content Browser into the graph. Doing this creates a Blend Space player, which references the asset



Refer to the Blend Spaces in Animation Blueprints page to learn more about using Blend Spaces in Animation Blueprints.



Start using Blend Spaces in Unreal Engine by referencing or creating them in Animation Blueprints.

Start using Blend Spaces in Unreal Engine by referencing or creating them in Animation Blueprints.

Editor Overview

Regardless of the Blend Space type being used, the following editor is displayed when opening one of these assets:



Asset Details, where you can set properties and other settings for this Blend Space.

Viewport, which displays the Skeletal Mesh and current playing animation according to the graph.

Asset Browser, which can be used as a convenient location to drag animations into the graph.

Blend Graph, where you plot your animations along either a one or two-dimensional graph and preview the blending functionality.

Asset Details

The Asset Details panel contains properties and other settings for this Blend Space asset.



Name

Description

Use Grid

Enabling this will use the legacy grid mode for blending, as opposed to the default triangulation method. Typically, you would only use the grid if you are performing specific blending arrangements, such as using Wrap Input. Otherwise, in most cases you should leave this disabled and instead use triangulation for more accurate blend results.

Preferred Triangulation Direction

Controls the triangular blend angle between samples. This will only affect samples that are placed in a uniform manner and only if Use Grid is disabled.

None will cause the triangles to have the same angle along the entire graph. Typically, you should not pick this option if you are creating a symmetrical Blend Space as the blending result will be different on each side.



Tangential will cause the triangles to face outward from the graph origin.



Radial will cause the triangles to face inward to the graph origin.



Axis to Scale Animation

If Smoothing Time is being used, then this specifies the axis on which to scale the animation playback speed. In most cases this would be used for locomotion animations where you would specify the axis for speed.

Name

The name of the axis to display in the Blend Graph and on the Blend Space Animation Blueprint node.

Minimum Axis Value

The minimum displayed value for this axis.

Maximum Axis Value

The maximum displayed value for this axis.

Grid Divisions

The number of divisions on this axis. Higher values here will result in more precise blending results. Odd numbers will also provide different blending results from even numbers. If Use Grid is disabled, then this will only cause cosmetic changes for the grid.

Snap to Grid

Enables snapping to the Grid Divisions when moving animation points along this axis. Holding Shift will also temporarily enable snapping for all axes.

Wrap Input

When enabled, the input value for this axis can exceed the Minimum and Maximum Axis Values. When this occurs, the Blend Space will treat the axis as circular and convert the input to the inverse value on the other side. If you enable this property, ensure the animations on either end of the axis are similar to prevent popping.

Smoothing Time

The time in seconds for this axis to blend between different inputs. A value of 0 will cause no time blending to occur. You can preview the blend within the graph by observing the secondary crosshair moving independently of your preview point.



Smoothing Type

Determines which easing function is used if Smoothing Time is used. You can select from the following:

Averaged

Linear

Cubic

Ease In/Out

Exponential

Spring Damper

Damping Ratio

When using Spring Damper for the Smoothing Type, this determines how much damping there is. Values less than 1 will result in overshoot, which can make some motions look more natural.



Max Speed

The maximum rate of change of this axis value when smoothing. Only used when the Smoothing Type is set to Spring Damper or Exponential. If set to 0, then blending speeds can be limitless.

Analysis

You can specify a function to be used per axis to analyze and automatically place the samples in the Blend Space. Refer to the Blend Space Analysis page for more information.



Accurately calculate and place your Blend Space samples using Blend Space Analysis.

Accurately calculate and place your Blend Space samples using Blend Space Analysis.

Blend Samples

This section lists all the samples involved in the Blend Space, allowing their details to be modified or deleted. You can also preview these same properties by right-clicking on the sample in the Blend Graph.

Weight Speed

This controls the speed at which the individual sample weights can change. A value of 2.0 means that a sample can have its weight change from zero to one in half a second. A value of 0.0 disables this feature, unless you are using Per Bone Overrides. In general, do not use this in conjunction with Smoothing Time or Smoothing Type.

Smoothing

Enables easing in and out of the Weight Speed. In general, do not use this in conjunction with Smoothing Time or Smoothing Type.

Per Bone Overrides

An array where you can specify different Weight Speeds for Bones to blend at a different rate. Bones specified here will also include all descendants.

Preview Base Pose

If you are using additive animations in a Blend Space or Aim Offset, then you can specify a base animation here to preview the additive animations from.

Notify Trigger Mode

The current mode used by this Blend Space to control how Animation Notifies trigger when blending between multiple samples. You can select from the following:

All Animations, which will trigger all notifies.

Highest Weighted Animation, which will only trigger the notifies from the sample with the highest weight.

None, which will cause no notifies to trigger.

Blend Graph

The Blend Graph is the primary interaction panel within a Blend Space. Here you will place and manipulate animation samples, preview the blending behavior, and debug blending problems.



Clicking Show Triangulation enables or disables the triangulation view. This button only appears if Use Grid is disabled from the Asset Details panel, which enables triangulation as the blend method.



Clicking Show Samples enables each sample to display its name.



You can stretch the graph to fit the panel by clicking Stretch Grid to Fit. Disabling this will cause the graph to maintain relative scale based on each axis range.



If a sample is selected, it will display its axis coordinates in the toolbar, which can be manipulated.



These toolbar settings are also accessible in the context menu when right-clicking in the graph.



Samples can be moved by dragging them within the graph. Holding Shift will snap them to the grid increments defined in the Grid Divisions property for that axis.



Right-clicking a sample will show a context menu where you can edit its Blend Sample properties.



Holding CTRL and moving your cursor within the graph will preview the blend at that position, which is marked by a green crosshair. If you are using Smoothing Time properties, then a secondary green crosshair will also appear, allowing for the preview of both the target position and smoothing.



Holding CTRL + ALT will also enable an influence display, where you can see the different sample weights update relative to the preview point.



If samples are placed in such a way that it will cause very thin triangulation between points, then that triangle will display in red to denote that it should be adjusted. Typically this can happen when performing a Blend Space Analysis.



If Use Grid is enabled, then samples that are awkwardly placed will indicate this error with a red highlight around the sample point. This also indicates that the highlighted sample will not contribute to the Blend Space properly.



Enabling Analysis

Analysis Properties

Analysis Examples

Aim Offset

Locomotion

Managing your Analysis

Post-Analysis Cleanup

Placing samples accurately in the Blend Graph can be slow and tedious, especially if you are not sure exactly what characteristics the animations have. Blend Space Analysis can be used to calculate a range of relevant properties, and to then automatically place your samples in the Blend Space.

This document provides an overview of the Blend Space Analysis system in Blend Spaces.

You have an understanding of Blend Spaces.

Your project has a Skeletal Mesh character with the necessary imported animations to use as samples in the Blend Space graph.

Blend Space Analysis cannot be used for Blend Space nodes created in Animation Blueprints.

Enabling Analysis

Blend Space Analysis can be enabled for all Blend Space types by setting the analysis axis function properties located in the Asset Details panel. Setting the Axis Function to a value other than None will enable Blend Space Analysis, and the value to select depends on the kind of Blend Space you are creating. For example, if you are creating an Aim Offset, then typically you may want to select Orientation.



The following Axis Functions are available for use:

Axis Function

Description

None

Disables analysis for this axis.

Position

Calculates the position of a Bone or Socket averaged over the duration of the sample.

Velocity

Calculates the velocity of a Bone or Socket averaged over the duration of the sample.

Delta Position

Calculates the change in position of a Bone or Socket over the duration of the sample.

Orientation

Calculates the orientation (roll, pitch and yaw) of a Bone or Socket averaged over the duration of the sample.

Orientation Rate

Calculates the rate of change of roll/pitch/yaw of a Bone or Socket averaged over the duration of the sample.

Delta Orientation

Calculates the change in roll/pitch/yaw of a Bone or Socket over the duration of the sample.

Angular Velocity

Calculates the angular velocity as a rotation vector (in degrees per second) averaged over the duration of the sample.

Locomotion

Estimates the locomotion velocity of a biped character based on the foot movements.

Root Motion

Estimates the locomotion velocity of a character based on the motion of the root (requires root motion data in the animation sequences).

Analysis Properties

Selecting any of the Axis Function types will reveal additional properties, which are used to configure the analysis. Most of these properties are common for all types, however there are some that are exclusive to certain types.



Name

Description

Axis

The axis of the Bone or Socket to analyze. Depending on the chosen Axis Function, there will be a different Axis to select:

Position, Velocity, Delta Position, and Angular Velocity provides X, Y, or Z for the analysis axis.

Orientation, Orientation Rate, and Delta Orientation provides Pitch, Roll, or Yaw for the analysis axis.

Locomotion and Root Motion provides Speed, Direction, Forward Speed, Rightward Speed, Upward Speed, Forward Slope, and Rightward Slope for the analysis axis.

Bone/Socket

This specifies the Bone or Socket to analyze. If Axis is set to Locomotion, then two Bone/Socket properties are required, one for each foot. Some analysis functions will also use the orientation of the Bone for calculating Pitch, Roll, or Yaw values. In these cases, you need to ensure that the facing and right axes are set correctly, depending on how the character's skeleton is set up.

Bone Facing Axis

The forward-facing axis of the selected Bone or Socket if Orientation, OrientationRate, or DeltaOrientation is selected as the Axis Function.

Bone Right Axis

The right-facing axis of the selected Bone or Socket if Orientation, OrientationRate, or DeltaOrientation is selected as the Axis Function.

Space

The spatial coordinates in which to perform the analysis, so you can calculate the position and orientation of one Bone with respect to another. You can select the following spatial coordinates:

World space represents the space the character is in at the start of each animation sequence, and can be determined from the viewport axis display.

Fixed space uses the space of a particular bone or socket, without updating it during the animation sequence. Using it, you can specify your own "world space" coordinate frame using the Bone or Socket from the first frame of the animation sequence.

Changing, which is similar to Fixed, but the space is updated for each frame that is analyzed in the animation sequence.

Moving space, which is similar to Changing, except that the velocities are also calculated relative to the Bone space.

Analysis Space Bone/Socket

If Space is set to either Fixed, Changing, or Moving, then this is where you specify the Bone or Socket to use for the spatial analysis.

Character Facing Axis

The facing direction of your character, which can be determined from the viewport axis display. Typically this should be set to +Y.



Character Up Axis

The upward direction of your character, which can be discerned from the viewport axis display. Typically this should be set to +Z.

Start Time Fraction

The normalized start time of the animation sample to analyze. You may want to adjust this if you only want a certain section of an animation to be analyzed.

End Time Fraction

The normalized end time of the animation sample to analyze. You may want to adjust this if you only want a certain section of an animation to be analyzed.

Analysis Examples

The following are some examples of how you can use Blend Space Analysis to populate your Blend Space graph.

Aim Offset

If you want to automatically place your Aim Offset samples, you can use Blend Space Analysis in the following way. This example will assume you have already created an Aim Offset Asset.

In the Aim Offset Asset Details panel, locate both the Horizontal Axis Function and Vertical Axis Function properties and set them to Orientation.



Additional analysis properties will appear under each Axis Function. Under Horizontal Axis, set the following properties:

Set Axis to Yaw, which will analyze the selected Bone or Socket along its yaw (sideways) axis.

Set Bone/Socket to your character's weapon or prop Bone that the weapon attaches to. In most cases this will be the weapon bone on the right hand.

Set Bone Facing Axis to match the direction the weapon will be aimed when attached to the Bone. In most cases this will be +X.

Set Bone Right Axis to match the right-facing direction of the weapon when attached to the Bone. In most cases this will be +Y.



Under Vertical Axis Function, set the following properties:

Set Axis to Pitch, which will analyze the selected Bone or Socket along its pitch (up and down) axis.

Set Bone/Socket to your character's weapon or prop Bone that the weapon attaches to. In most cases this will be the weapon bone on the right hand.

Set Bone Facing Axis to match the direction the weapon will be aimed when attached to the Bone. In most cases this will be +X.

Set Bone Right Axis to match the right-facing direction of the weapon when attached to the Bone. In most cases this will be +Y.



You can now drag in your samples from the Asset Browser. Doing this will analyze and automatically position them within the blend graph. The graph will also automatically adjust its ranges and grid divisions based on the analysis.



Press Ctrl and move your cursor in the graph to preview the results.



After analyzing your samples, you may need to adjust the axis ranges for your Blend Space so that they encompass your samples more accurately.

Locomotion

This example will create a Blend Space that controls forward movement on the vertical axis, and sideways / strafing movement on the horizontal axis. We will assume you have already created a Blend Space Asset.

In the Blend Space Asset Details panel, locate both the Horizontal Axis Function and Vertical Axis Function properties and set them to Locomotion.



Additional analysis properties will appear under each Axis Function. Under Horizontal Axis, set the following properties:

Set Axis to Rightward Speed.

Set Bone/Socket 1 to one of your character's feet bones.

Set Bone/Socket 2 to the other foot bone.



Under Vertical Axis Function, set the following properties:

Set Axis to Forward Speed.

Set Bone/Socket 1 to one of your character's feet bones.

Set Bone/Socket 2 to the other foot bone.



You can now drag in your samples from the Asset Browser. Doing this will analyze and automatically position them within the blend graph. The graph will also automatically adjust its ranges and grid divisions based on the analysis.



You can also drag in additional samples, which will add them to the analysis array.



Managing your Analysis

When tweaking your sample positions in the graph, you can click Analyze all Samples in the Asset Details panel to revert all samples back to their analyzed positions.



Post-Analysis Cleanup

Depending on your Blend Space complexity, you may see some resulting triangulation problems, indicated by red lines in the graph.



These can cause blending discontinuities when interpolating the Blend Space, and need adjustment. You can perform any of the following operations to resolve this:

Moving existing samples, which can fix the triangulation problems, but may result in slightly inaccurate sample positions.

Duplicating existing samples and placing them outside the current area so the perimeter is more convex (circular) shaped.

Creating new samples that you can place in locations to remove the bad triangles.

In this example, two samples were placed almost on top of each other on the left of the graph, causing blending problems. The extra sample can be selected and moved to its desired position at the right side of the graph, since aiming distinguishes between +180 and -180 degrees.



In this example, a few perimeter samples will cause problems when using the Blend Space outside or near the edge of the region containing samples. You can move these samples to the outer edges of the graph where they will no longer generate long / thin triangles, then duplicate them by right-clicking on them and selecting Duplicate. This will place the duplicate at the analyzed position, while retaining the sample you just moved.



Blend Space Player

Blend Space Graph

Blend Space Evaluator

Blend Spaces are used in Unreal Engine by placing nodes in the AnimGraph of Animation Blueprints which take input data to drive the blending of the samples used in the Blend Graph. They can also be created directly in the AnimGraph without needing a pre-existing Blend Space.

This page provides an overview of the different types of Blend Space nodes in Animation Blueprints, and how to use them.

You have created and have an understanding of Animation Blueprints.

You have created a Blend Space or Aim Offset.

Blend Space Player

Blendspace Players are nodes which reference a currently existing Blend Space Asset. They contain data pin inputs for both axes, or one axis if using a 1D Blend Space. The node outputs the resulting pose based on those inputs.



Aim Offsets can also be used as players.

Creation and Usage

Blendspace Players can be created in any of the following ways:

By right-clicking in the AnimGraph and selecting your Blend Space from the Blend Spaces category. Ensure it contains the Blendspace Player prefix.



By dragging the Blend Space Asset from the Asset Browser or Content Browser into the AnimGraph.



Double-clicking a Blendspace Player will open that Asset in a separate window, if the Blend Space is assigned.



Properties

Selecting the Blendspace Player will reveal the following properties relevant to the Blend Space in the Details panel.



Name

Description

Coordinates

The Axes or Axis (if 1D) of the Blend Space.

Play Rate

The speed of the playing samples in the Blend Space. Setting this to negative values will cause the samples to play in reverse.

Loop

Enabling this will cause the samples to repeat playing indefinitely. When disabled, this will cause the final frame of the sample to be held.

Reset Play Time when Blend Space Changes

Resets the normalized time of the playing samples if the Blend Space property changes.

Start Position

The start time for all the samples in the Blend Space. This is in normalized time, so it must be a value between 0 and 1.

Blend Space

The Blend Space Asset to use.

LOD Threshold

Controls the maximum Level of Detail (LOD) that this node is permitted to run on. For example, if you set this to 2, it will enable until LOD2, but disables once the component's LOD becomes 3. A value of -1 will cause the node to always execute, regardless of LOD. This property only appears for Aim Offset and Aim Offset Players.

Blend Space Graph

While Blendspace Players are nodes that reference currently existing Blend Spaces, Blend Space Graphs are nodes that contain Blend Spaces within the Animation Blueprint. Using them, you can create bespoke Blend Spaces for your Animation Blueprint, diverge them from other assets, and edit sample logic.



Aim Offsets can also be used in this manner.

Creation

To create this Blend Space type, right-click in the AnimGraph and select Blend Space from the Blend Spaces category. You can also select a pre-existing Blend Space Asset by selecting it, ensuring the prefix says Blendspace. Doing this will import (instead of referencing) the Blend Space, in which you can diverge it from the original.



Usage

As Blend Space Graphs are meant to be created and managed within your Animation Blueprint, you can open the Blend Space interface by double-clicking on the Blend Space entry in the My Blueprint panel. From here, you can add samples, define your axis values, and edit other properties just like a Blend Space asset.



Each sample in the blend space contains its own sub-graph, which can be viewed by double-clicking it. In this way, you can assign more features to a sample by creating additional logic.



Blend Space Evaluator

Blendspace Evaluators are Blend Space nodes that have the times of all their samples' times controlled externally, rather than play automatically. This time control is a normalized (0 - 1) float value that determines the point at which the pose is sampled.



To create this Blend Space type, right-click in the AnimGraph and select Blendspace Evaluator from the Blend Spaces category. You can also select a pre-existing Blend Space Asset by selecting it, ensuring the prefix says Blendspace Evaluator**.



By default, the Blendspace Evaluator teleports to the provided time and does not advance time, which causes root motion or Animation Notifies to not evaluate. Disabling Teleport to Normalized Time will restore this functionality.



Overview

Creation and Setup

Base Pose Setup

Referencing Aim Poses

Mesh Space Additive

Animation Blueprint Setup

An Aim Offset is a type of Blend Space in which the animation samples are additive. Typically Aim Offsets are used to create a multi-directional weapon aiming blend structure, which then apply additively to a default aiming pose.

Your project has a Skeletal Mesh character with the necessary imported animations and poses to use as samples in the Aim Offset graph.

You have an understanding of Blend Spaces; Aim Offsets are a type of Blend Space.

Overview

The main concept with Aim Offsets is that they are designed to be additively applied to an existing base animation. In weapon aiming examples, this base animation would typically be an "aiming forward" neutral animation.



From this base, you can then implement the full range of additive poses within your Aim Offset graph. The number of poses you will need is dependent on the motions your character will need to do. A typical aim-space sample system might look like this:











Up Right Behind

Up Right

Up

Up Left

Up Left Behind











Right Behind

Right

Base

Left

Left Behind











Down Right Behind

Down Right

Down

Down Left

Down Left Behind

Creation and Setup

To create an Aim Offset in the Content Browser, click Add (+) and select Animation > Aim Offset or Aim Offset 1D from the context menu. When creating a new Aim Offset, you have to designate a Skeleton asset. Be sure to choose the same one used by the Skeletal Mesh you want to use with the Aim Offset.



Open the newly created Aim Offset to continue setup.

Base Pose Setup

Because Aim Offsets are meant to be used with additive animation samples, you should set a base animation to play in order to preview the additive behavior correctly. To do this, navigate to the Preview Base Pose property in the Asset Details panel and specify an animation asset to play.



Referencing Aim Poses

Like Blend Spaces, Aim Offsets are created by referencing animation samples within a blending graph. The easiest way to do this is by dragging the animations from the Asset Browser panel into the graph.



When creating your Aim Offset system, you should be mindful about how you allow the yaw (side-to-side) motion to animate. For example, the example poses you see above will look fine when the character is standing still. However it may produce issues if you allow it to play during other animation states, such as running or walking.

To alleviate this, you can use Animation Blueprints to limit the incoming data for the Aim Offset so that the side-to-side extremes are only in use when the character is stationary. Alternatively, you can change your Aim Offset to just aim the character up and down, allowing the rotation of the actual character to deal with side-to-side motion.

Mesh Space Additive

For your animation samples to work with an Aim Offset, ensure your animations are additive, and that the Additive Anim Type is set to Mesh Space. This is required because Aim Offsets only accept animations that are additive.

To do this, open all of the Animation Sequences being used in your Aim Offset. In their Asset Details panels, locate and set the following properties:

Set Additive Anim Type to Mesh Space.

Set Base Pose Type to Selected animation frame.

Set Base Pose Animation to use the same base animation as the Base Pose Setup.

Set Ref Frame Index to 0.



The reason Mesh Space must be selected instead of Local Space is because Mesh Space applies its additive effect in the space of the Skeletal Mesh Component. This causes rotations to move in the same direction, regardless of the orientation of the preceding Bone in the Skeletal Mesh. This is important for Aim Offsets because in some cases, you may want the rotations coming from the Blend Space to be applied consistently, regardless of the current base pose of the character.

For example, if your character has the ability to lean sideways while aiming, this can cause the Bones' overall local space to shift towards the lean direction. If your additive type is set to Local Space, then it can cause the upward-aiming pose to be skewed, and not correctly face up. Using Mesh Space as your additive type corrects this by applying the rotation offsets from the Blend Space in the expected way.



Base pose with leaning.

Leaning and aiming up when using Local Space additive.

Leaning and aiming up when using Mesh Space additive.

Animation Blueprint Setup

Once your Aim Offset is created, you can reference it within your Animation Blueprint. Similar to Blend Spaces, you can reference it as a player, which references the Aim Offset asset directly, or as a graph, where you can diverge the logic within your Anim Graph.

To reference an Aim Offset Player in the Anim Graph, right-click in the graph and select your Aim Offset Player Asset from the Blend Spaces category. Connect the output to the Output Pose node.



You must also connect a Base Pose to the Aim Offset node, typically this would be the same animation defined in the Base Pose step earlier, or a State Machine that uses a similar base pose.



Finally, you must create logic to drive the Yaw and Pitch values on the Aim Offset. Depending on your player controls, this logic can be created in several different ways. For this example, you can use property access to output data from the pawn's base aim rotation.



Animation Sequences

Animation Sequences

Animation Slots

Creating a Montage

Timeline

Sections

Montage Track

Slots and Slot Groups

Timing

Details Panel

Montage Sections Panel

Child Montages

Network Games

You can use Animation Montages (Montages) to combine several Animation Sequences into a single asset and control playback with Blueprints. You can also use Animation Montages to replicate Root Motion animation in network games.



In addition to building animations with multiple sequences, you can divide montages into Montage Sections, which can be dynamically played back in any order through logic at runtime. You can control the transitions between Montage Sections in the Montage Sections Panel or you can set up more dynamic transition behaviors between Sections by using Blueprints.



For more information about using Animation Montages in Blueprints, see Editing and Using Animation Montages in Blueprints.

Within animation Montages, Sequences are organized into Slot Groups and Slots. Several sequences can be stored in a single Slot to produce animations and additional tracks can be created using different Slots.

By default Sequences that occupy the same Slot and reside in the same Slot Group will override playback of any other sequence when triggered.

See the Slots and Slots Groups section below for more information on Slots.

Creating a Montage

To create a montage, right-click within the content browser then navigate to Animation > Animation Montage. Next, select which Skeleton you want to animate using a montage.



You can also create a Montage from an existing Animation Sequence by Right-Clicking the Sequence in the Content Browser and selecting Create > Create AnimMontage.



After creating an Animation Montage and opening the asset, the Animation Sequence Editor opens and populates the Timeline with an Animation Montage workspace.

Timeline

The Timeline, like other editor timelines in Unreal Engine, is organized into tracks. These tracks contain information that dictates the behavior of the animation playback and are organized into playback frames.



Sections

Within the Montage track you can access any Montage Sections present in your Animation Montage.



Indicated by their assigned name and a purple header, you can add, delete and move these sections to match the corresponding sequences or sections of sequences for gameplay purposes.

To create a Montage Section Right-Click within the top track, select Create New Section, and enter a name for this Montage Section. You can move and place the Montage Section header by clicking and dragging the header or the line in the timeline.



After creating a Montage Section it appears in the Montage Sections Panel.

To remove a Section, Right-Click the Section header and select Delete Montage Section.

Montage Track

Under the Montage Track header, you can add and manage Animation Sequence tracks, organize tracks by Slot Groups or Slots, and see Timing indicators for Notifies.



You can switch the Sequence Track you are previewing in the Editor by opening the drop-down menu on the desired track. Then, toggle Preview Slot under the Other Options heading.

Slots and Slot Groups

Within Animation Montages, Animation sequences are organized and played in Slots. A Slot occupies a mesh or part of a mesh, and when an animation is placed into the Slot from the animation Montage it can then be played on the Animation Blueprint in that Slot. A Slot track is a succession of sequences that can hold any number of Animation Sequences. By using Montage Sections these sequences can be used in any order dictated by gameplay logic or player input.

You should not overlap animations as Sequences will interfere with one another if they are played at the same time on the same Slot.

To play Sequences on different parts of your Character, animations can be divided into Slot Groups. These Slot Groups can be set up to play on separate parts of your character using the Anim Graph. For example you can use an upper body Slot and a lower body slot, to play separate animations on the upper body and lower body at the same time.

To change or add Slots to the Montage, click the Slot dropdown menu on the Slot track to view the following commands:



Name

Description

Slot name

Exposes a menu where you can change the current Slot. If this is the topmost Slot track, then selecting a Slot that is part of a different Slot Group will change the Montage's Slot Group.

New Slot

Adds a new Slot Track using a pre-existing Slot.

Delete Slot

Deletes the Slot.

Duplicate Slot

Duplicates the Slot track and its contents into a new Slot track.

Preview Slot

If you have more than one Slot track, enabling this will cause the contents of this Slot to preview in the Viewport.

Slot Manager

Opens the Slot Manager panel.

For the best results when using multiple slots, you should ensure that the timing of animations involved from end-to-end is the same length.

For more information on Slots and Slot Groups, see the Slots documentation.

Timing

The Timing track displays indicators from the Montage and Notifies sections to help with the timing of elements.



Each node in the track is given a number denoting the trigger order of that object within the montage, and is color coded by reference type, purple for sections, red for Notifies.

Clicking the dropdown arrow on the Timing track presents you with options for showing and hiding the present reference types.

Details Panel

Within the details panel, you can edit and manage properties of the assets contained in your Animation Montage such as Sequences, Notifies, and Montage Sections.



For more information about using the details panel with specific Montage elements see Editing and Using Animation Montages

Montage Sections Panel

In the montage sections panel you can establish the default playback order of your Montage Sections.



To establish a playback order, first select the Clear option, which unlinks any currently selected section behavior, leaving any present sections unlinked.

Then, click the white box to the right of the section you want to edit to select the next Section to be played when triggered. To preview a Sections playback order: begin the animation playback, then click the preview button next to the Section Sequence you wish to preview.



Preview All plays preview of all sections in the order they appear within the Timeline.

Child Montages

You can use Child Montages to create variants of Montages that inherit all the Parent Montage properties. You can then edit the Child Montage to fit specific needs without altering an established gameplay system or behavior.

To create a Child Animation Montage, right-click on a Montage in the Content Browser and select Create Child Montage.



The new Child Montage is created with the same name as the original asset, with "_Child" added to the end.



When opening a Child Montage, all elements within the montage are set to read only.

You can right-click the Child Montage Segment in the Slot Track and override it with a new animation.



In the Slot Track, you can substitute any animation for any other, even if they are of different lengths. Unreal Engine automatically adjusts the play rate, start time, and end time of the replacement animation so that it uses the same portion and runs at the same time as the original. Animations that have not been changed from the parent are shown in green, and animations that have been overridden are shown in yellow.



Child montages cannot be used as parents for other child montages.

Network Games

When working on a project intended to be played over a network connection you can use Animation Montages to replicate Root Motion in network games. The replication process occurs by default but you first need to replicate the PlayMontage Node manually with a RPC (Remote Procedure Call).

Only the replication and correction of the root motion are carried over when using a Play Montage node in a RPC.

For more information on Network Projects, see the Network Multiplayer documentation.

Animation Sequences

Animation Montage

Animation Slots

Editing Animation Montages

Adding Animations

Creating Montage Sections

Defining Track Slots

Using Multiple Slots

Playing Animation Montages

Montage Properties Reference

Asset Details

Sections

Animations

Editing Animation Montages

If you are new to Animation Montages, you should read the Animation Montage Overview document before proceeding.

This document shows you how to set up an Animation Montage and the properties within the Animation Sequence Editor relevant to working with Animation Montages.

Adding Animations

To add an Animation to your Montage, drag the desired Sequence from the Asset Browser and drop it in the Animation Sequence Editor Timeline in a Montage Slot track.



You can add additional Animations to the Montage by dragging a Sequence into the same Slot track. Additional animations are added sequentially and are visually staggered to indicate the breaks between Animations.



You can click and drag the Animations on the Slot track to re-order them.

Right-clicking on an Animation in a Montage track provides the following context menu:

Property

Description

Delete Segment

Deletes the selected Animation from the Montage.

Open Asset

Opens the selected Animation Asset in the relevant editor window.

When working within more than one Animation Asset at once, it can be helpful to have more than one Asset open at the same time. You can open more than one Animation Asset at once in a new editor tab by holding Shift when clicking on an asset from the Content Browser or an asset linking instance.

New Montage Section

Creates a new Montage Section. See Creating Montage Sections for more information.

New Slot

Creates a New Slot track after defining which slot to occupy. See Defining Track Slots for more information.

Delete Slot

Deletes the selected Slot, including all contained instances of assets.

Duplicate Slot

Duplicates the selected Slot, including all contained assets.

Two or more tracks cannot occupy the same Slot on the same Skeleton. One of the duplicated tracks must be redefined with a new Slot.

Set Elements To…

This property defines the nature of the associated Notifies and Sections tied to the selected Sequence.

The options include:

Absolute: The Notify location is tied to the location it occupies in the Montage timeline as a whole, regardless of sequence length or order.

Relative: The Notify is tied to the location relative to the ordered Sequence when this option is enabled. For example, a Notify that occurs one second after the beginning of the first Sequence in a Montage, will be tied to the location of one second after the beginning of the first Sequence regardless of which Sequence is the first Sequence, even after the property has been enabled.

Proportional: The Notify will be attached to the associated sequence even when reordering Sequences.

Creating Montage Sections

To create a Section, right-click on the Slot track or the Montage track and select New Montage Section from the context menu. When prompted, define the Section's Name.



The new Section appears in the Montage track and is indicated by a purple header and timing tag.

By default, all Animation Montages include a Default Section that, when used by itself, will sequentially play the entire Montage.



You can edit the location of Sections by dragging the Section header to the desired location.



A section must be present at the beginning of an Animation Montage. If an edit is made moving or modifying the Section at the beginning of the timeline, the editor corrects the position of either the edited section or the next closest section to the beginning of the montage.



Defining Track Slots

Slots are a management system for animation playback on Skeletal Meshes that are assigned to areas or parts of a mesh. In the Anim Graph within a character's Animation Blueprint, Slots can be used to organize which region on a character an animation is played back on. You can organize which Slot an animation will play on, by declaring what Slot the Montage track uses when creating a New Track or with the dropdown menu.

All sequence tracks must use Slots from the same Slot Group.

For more information about slots and Slot Management see the Slots documentation.

Using Multiple Slots

Montages can contain many animation tracks using multiple slots in order to play animations on different regions of the mesh at the same time, or in instance of different states. Using Montages you can consolidate a group of related animations, and assign them to different Slots to playback in their respective circumstance using the same Asset. A single reload Montage can be used for any state a character occupies. For example, using Blueprints, a single reload Montage can be commanded to play animations from one Slot if the character is standing, and play animations from a different Slot if the character is lying prone.

For best results when using multiple Slots in an Animation Montage, ensure that the length of each of your animation tracks are the same.

Playing Animation Montages

After having created and modified your Animation Montage in the Animation Sequence Editor, you can now play the Montage from a Blueprint as long as your character actor is able to be referenced. You can use the Play Anim Montage node to playback an Animation Montage.



With the Play Anim Montage Node, you can activate the playback of an Animation Montage from a Blueprint. You need to specify the target to play the Montage. When using the Play Anim Montage Node the target is the Self object by default.

Other options include changing the In Play Rate of the montage by a factor of the value assigned. For example, a value of 2 will play the montage back at double speed, while a value of 0.5 will playback at half speed.

With this node you can also define which section to begin playback if you want to use a section other than Default as the starting section. The sections play based on the behavior you define in the Montage Sections panel in the Animation Sequence Editor.

For a more powerful and feature rich node, you can use the Play Montage node. With the Play Montage node you need to connect the Mesh you want to animate and assign the Montage to Play.



You can also set a Play Rate factor, or set a custom Starting Position, in seconds, or Starting Section, by name, for playback.

From the node's output, there are several events that you can use to activate connected nodes and functions based on the state of the Montage:

Output Pin

Description

On Completed

Functions can be connected from this pin to be activated when the Montage finishes playing and is fully blended out.

On Blend Out

Here, functions can be activated when the Montage is starting to Blend Out, using Blend Out Trigger Time or if the Montage ends.

On Interrupted

From this pin, functions can be activated when Montage playback is Interrupted.

On Notify Begin

Functions can be activated from this pin when a Play Montage Notify is activated or a Play Montage Notify Window begins. For more information about the different types of Notifies and how to implement them into Animation Sequences or Montages, see the Notifies documentation.

On Notify End

When a Play Montage Notify Window ends, this pin will activate any connected functions.

Notify Name

This pin outputs the active Notify's name.

In order for the Montage to play, in the Character Blueprint of the Skeletal Mesh you should set the Animation Mode to Use Animation Blueprint and connect the Animation Blueprint being used in the Anim Class property.



Inside your Animation Blueprint, on the AnimGraph, you can use a Slot node referencing the corresponding Slot used in your Montage to integrate the Montage playback with the rest of your characters animation system.



Also see Using Layered Animations for an example of how Montages can be used with other animation systems.

Montage Properties Reference

Animation Montages are an assembly of many assets working together. Here you will find a reference guide to each asset type and the accessible properties you can use when working within animation montages.

Asset Details

Here you can reference a list of properties that you can use to define the behaviors of the Animation Montage currently open in the Animation Sequence Editor.



Property

Description

Blend Mode In

Select the Mode used when blending into the Montage. You can select either Standard and Initialization.

Blend Mode Out

Select the Mode used when blending out of the Montage. You can select either Standard and Initialization.

Blend In

When assigning blend behaviors, into an Animation Montage, you can set the following options in this property:

Blend Time: Set the blend time in sections, to dictate the duration of the blend to occur.

Blend Option: Select the method to which the blending will be performed.

Custom Curve: Assign a custom curve asset to be referenced when performing a blend.

Blend Out

When assigning blend behaviors, out of an Animation Montage, you can set the following options in this property:

Blend Time: Set the blend time in sections, to dictate the duration of the blend to occur.

Blend Option: Select the method to which the blending will be performed.

Custom Curve: Assign a custom curve asset to be referenced when performing a blend.

Blend Out Trigger Time

Set the threshold for a blend out process to begin. The assignable value is the time (in seconds) from the end of the Montage.

Using a value of less than 0 results in using BlendOutTime, so BlendOut finishes as the Montage ends. Using a value greater than or equal to 0 results in using the Montage End subtracting the BlendOutTriggerTime to trigger blend out.

Enable Auto Blend Out

When toggled, the montage automatically blends out when the montage reaches its end. When disabled, no blending will occur and the final pose will last until stopped explicitly by another function.

Blend Profile In

Select the Blend Profile to use when Blending In to the Montage. For more information on Blend Profiles, refer to the Blend Profiles documentation.

Blend Profile Out

Select the Blend Profile to use when Blending Out of the Montage. For more information on Blend Profiles, refer to the Blend Profiles documentation.

Sync Group

Define the name of the Sync Group the Montage is a part of. For more information about Sync Groups and using them in conjunction with Animation Montages, see the Sync Groups documentation.

Sync Slot Index

Define the Sync Group Slot Index. For more information about Sync Groups and using them in conjunction with Animation Montages, see the Sync Groups documentation.

Time Stretch Curve

With Time Stretch Curves you can specify play-rate adjustments using an Animation Curve during animation playback. A Time Stretch Curves will only be referenced during playback when the montage has a non-default play rate. In this property you can define the following properties.

Sampling Rate: Desired Sampling rate of the above curve. This will be rounded off so we sample the whole curve with a fixed time step.

Curve Value Min Precision: Minimum delta allowed between consecutive sampled segments. Below this value, segments will be combined to optimize the number of markers.

Markers: Lists an optimized array of markers.

Time Stretch Curve Name

Define the name of the Time Stretch Curve you want to use to affect the Animation Montage playback.

Sections

While working with an Animation Montage in the Animation Sequence Editor you will find properties in the Details Panel related to each asset type. Here you will find a reference of the available properties you can use to edit Sections while working within Animation Montages. To access these properties, select the desired Section and the relevant properties will populate within the Details Panel.



Property

Description

Section Name

Reference or rename the selected section.

Next Section Name

Reference the next section from the selected section as defined in the Montage Section panel.

Slot Index

Definable Slot Index value that can be referenced when using a Linked Montage.

Link Method

When using Linked Montages, you can define the Link Method in this property as well as in the Right-Click context menu on the relevant Animation Sequence. Refer to the Set Elements To… property in the Adding Animations section.

Linked Sequence

Reference of the Animation Sequence the Notify is linked to.

Animations

Here you will find a reference for the available properties you can use to edit Animations while working within Animation Montages. To access these properties, select the desired Animation and the relevant properties will populate within the Details Panel.



Property

Description

Animation Reference

Lists the Animation Sequence to play when the selected segment is activated.

Start Time

Indicates the Start Time in seconds of the selected Animation in relation to the Sequence.

End Time

Lists the End Time of the selected Animation in seconds in relation to the Sequence.

Play Rate

Factor of Play Rate. Where a value of 2 makes the montage playback at double speed, while a value of 0.5 plays back at half speed.

Loop Count

Define the number of Loops the Animation performs by default.

Changing this value alters the Animation in the Montage, resulting in any loops to be innate to the Animation. To have a dynamic looping Animation, you should set any Animation to only perform one loop, and use game logic to decide how many loops should be performed based on context.

Preview Window

With the Preview Window you can see a preview of the animation playback on the mesh. You can pause or play this animation preview with the Play/Pause button. You can also scrub through the animation using the simplified timeline under the preview window.

Start Position

Lists the Start Position, in seconds, in relation to the entire Montage.

The first animation in an Animation Montage must have a Start Time of 0.

For Notify properties, see the Animation Notifies documentation.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

IK Rig

Retargeting

Animation Blueprint Authoring

The IK Rig system provides a method of interactively creating Solvers that perform pose editing for your skeletal meshes. The resulting IK Rig Asset can then be embedded into any animation systems, such as Animation Blueprints to dynamically modify the pose-based solver parameters.

Additionally, the IK Retargeting system can be used to transfer animations between characters of varying proportions, either at runtime or for offline creation of new animation sequences.

This page contains links to documentation covering Unreal Engine's IK Rig and Retargeting tools, and real-world examples of their workflows.

IK Rig

IK Rigs are the primary Assets you will be using when using the IK Rig system. These pages describe its usage and primary features.



Create your custom IK Rig using goals, solvers, and settings.



Use Solvers to create different kinds of IK Rig setups.

Use Solvers to create different kinds of IK Rig setups.

Retargeting

IK Rigs can also be used as a platform to quickly retarget animations between different skeletons. This page describe this retargeting process using IK Rigs and the IK Retargeter.



Share and transfer animation between characters of any size using IK Rigs and IK Retargeting.

Animation Blueprint Authoring

IK Rigs can be utilized in Animation Blueprints to procedurally adjust animations for better alignment. This page describes the features of using IK Rig in Animation Blueprints.



Use IK Rig in Animation Blueprints to create procedural IK adjustment of your character in gameplay.

Create IK Rig

Editor and Feature Overview

IK Goals

Solvers

Viewport Settings

IK Rig Example Setup

Create Solvers

Create Goals

Connect Goals to Solvers

Set Solver Root

Final Result

The IK Rig editor is where you set up IK Rigs and retargeting for characters. With it, you can create different Solvers, adjust Bone settings, and preview your results.

This page provides an overview of this editor and how to create IK Rig Assets.

IK Rigs require a Skeletal Mesh in your project.

Create IK Rig

To start creating IK Rigs, you must create an IK Rig Asset. To do this, click Add (+) in the Content Browser, then select Animation > IK Rig. A dialog window will open where you select the Skeletal Mesh you want to create the IK Rig for.



After selecting the Skeletal Mesh, the IK Rig Asset will be created. Double-click it in the Content Browser to open it.

Editor and Feature Overview

The IK Rig editor contains the following tools and options:



The Reset button, which resets IK Goals to their default position.

Hierarchy, which displays your Bones, IK Goals, and settings.

Solver Stack, which displays the IK Solvers being used on this Skeletal Mesh.

Viewport, where you can select your Bones and manipulate IK Goals to preview the IK behavior.

IK Rig Output Log, which displays debug information about your IK Rig. It displays warnings and errors indicating the current status of the rig.

The Details panel displays properties for your selected item. Preview Scene Settings is where you can change the ambient viewport environment, such as lighting and background.

The Asset Browser displays a list of Animation Sequences that you can preview along with your IK behavior to test its effects. IK Retargeting is where you specify Bone chains for use with an IK Retargeter asset if you are retargeting this character using IK Rig.

IK Goals

IK Goals are the manipulation and effector points for your IK chains, which you create in the IK Rig Editor. IK Goals are used in conjunction with Solvers to modify an incoming pose to reach the goal locations.

To create IK Goals, first select the ending Bones in the IK chain you want to create. Typically, these would be the hand or foot Bones if you are creating IK along the arms or legs.



Next, click Add (+) in the Hierarchy panel and select New IK Goal. If your IK Rig does not already have a Solver, then a dialog window will appear where you can select a Solver to associate with the new goal. For common IK setups, you can select Limb IK, then click OK.



You can also right-click Bones in the Hierarchy panel to access the Add (+) menu.



The goal and Solver-specific settings will now be created and be visible in the Viewport and Hierarchy.



When you select an IK Goal, you will see the following properties in the Details panel:



Name

Description

Goal Name

The name of the IK Goal object.

Bone Name

The name of the end Bone that the IK Goal is acting as the effector for.

Position Alpha

Blends the final location of the IK Goal from the position of the Goal bone in the input pose (0) to the Goal's own position (1).



Rotation Alpha

Blends the final rotation of the IK Goal from the rotation of the Goal bone in the input pose (0) to the Goal's own rotation (1).



Preview Mode

Previews (in editor only) the goal in either Additive or Absolute modes. Additive is used when you want to ensure the IK behavior is relative to any incoming animation, whereas Absolute overwrites any incoming animation along the chain. Additive goal behavior can be achieved at runtime by setting your goals to Manual Input and Additive on the IK Rig Anim Graph node.



Transforms

Contains the current transform information for the selected IK Goal.

Size Multiplier

Multiplies the size of the IK Goal relative to its base size from the viewport settings. Increase this if you have larger, non-human characters.



Thickness Multiplier

Multiplies the line thickness of the IK Goal relative to its base thickness from the viewport settings You may want to increase this if you have increased the Size Multiplier.



Expose Position

Exposes position pins on the IK Rig Animation Blueprint Node in order to affect the position of the IK Goal in Animation Blueprints.

Expose Rotation

Exposes rotation pins on the IK Rig Animation Blueprint Node in order to affect the rotation of the IK Goal in Animation Blueprints.

Solvers

Different IK behaviors can be added to your IK Rig, which are called Solvers. Using Solvers, you can create a wide variety of IK effects, from simple three-bone chains to full-body multi-limb IK systems.

Visit the Solvers page to learn more about the different Solvers you can add, and how to use them in your IK Rigs.



Use Solvers to create different kinds of IK Rig setups.

Use Solvers to create different kinds of IK Rig setups.

Viewport Settings

When nothing is selected in the IK Rig editor, the Details panel will display the following Viewport settings:



Name

Description

Preview Skeletal Mesh

The Skeletal Mesh to run the IK solve on. You can change the assigned Skeletal Mesh here and the IK Rig system will attempt to run on the replacement. If the new Skeletal Mesh contains incompatible bone names or hierarchies, then the IK Rig will not function. You can reference the IK Rig Output Log for more information on any incompatibilities.

Draw Goals

Shows or hides IK Goals in the viewport.

Goal Size

The base size of IK Goals.

Goal Thickness

The base thickness of IK Goals.

IK Rig Example Setup

A common use-case for IK in Unreal Engine is to control foot alignment to uneven terrain, which requires manipulating the feet and hips of a character. The example below will walk you through setting up this IK Rig system for a humanoid character.

Create Solvers

Start by creating a new Solver. To do this, click Add New Solver in the Solver Stack panel, then add the following Solvers:

Set Transform.

Limb IK.

Limb IK again.



The order in which you add the Solvers matters, because Solvers execute in sequence according to the number displayed next to their name. For this IK system, Limb IK should evaluate last.

You can drag Solvers within the Solver stack to change their order if needed.



Create Goals

Due to the Solver types being used for this IK system, you will need to create IK Goals for each Solver. To do this, select the pelvis and feet bones, right-click them, and select New IK Goal. Goals will be created at the location of each of these bones.



You can optionally adjust the goals so they appear more prominently in the viewport by selecting them and editing their Size and Thickness Multiplier properties.



Connect Goals to Solvers

Each IK Goal must be connected to a Solver for it to correctly act as the effector for that Solver.

To do this, select both the Solver and the IK Goal, right-click the goal, and select Connect Goal to Selected Solver.



Repeat this action for each goal and Solver so that all your goals are connected to their respective Solvers.



Set Solver Root

For some Solvers, like Limb IK, you must specify both a goal and a root. The root is typically the starting Bone of the IK chain. In this example, the thigh will be the root.

To set the root for a Solver, select both the Solver and the Bone, right-click the Bone, and select Set Root Bone on Selected Solver.



Repeat this action for both Limb IK Solvers so that both of them have their respective thigh Bones set as the root.



Final Result

You can now preview your IK system in the viewport by selecting IK Goals and manipulating them. Clicking Reset restores your Goals to their initial state.



Creating Solvers

Solver Usage

Connecting to Bones and Goals

Multiple Solvers

Excluding Bones

Solver Types

Body Mover

Limb IK

Full Body IK

Pole Solver

Set Transform

IK Rig supports a variety of IK Solvers to affect a wide range of Bone hierarchies. They are used to create the Inverse Kinematic solution to rotating and positioning Bones in a chain. Multiple Solvers can also be used at the same time to further customize the IK effect.

This page provides an overview of the different Solvers you can add within the IK Rig editor, and their properties.

You have created and opened an IK Rig Asset. See the IK Rig Editor page for how to do this.

You are familiar with how to create IK Goals.

Creating Solvers

The primary way to create Solvers is by clicking Add New Solver in the Solver Stack panel, then selecting a Solver.



If a Solver does not already exist in your IK Rig, then creating an IK Goal will also prompt you to create a Solver, which automatically binds to that goal. Click the Solver Type dropdown menu to select a Solver.



Solver Usage

All IK Solvers require either a root Bone, IK Goal, or both to be specified. These two starting and ending Bones will complete the IK chain for that Solver.



The root Bone at the start of the hierarchy chain.

The goal, or effector Bone at the end of the hierarchy chain. This is driven by an IK Goal.

Connecting to Bones and Goals

To set the root Bone to a Solver, select the Bone in the Hierarchy and the Solver from the Solver Stack, then right-click on the Bone and select Set Root bone on Selected Solver.



If your Solver requires an IK Goal, connect it by selecting the goal from the Hierarchy and the Solver from the Solver Stack, then right-click on the goal and select Connect Goal to Selected Solver.



Once Bones and goals are connected to a Solver, selecting the Solver will highlight those objects within the Hierarchy, as well as in the Viewport.



Multiple Solvers

Multiple Solvers can also be added to the Solver Stack, which provides extra functionality for your IK Rigs. The order of multiple Solvers will matter, as they evaluate in sequence, denoted by the number next to their name.



For example, in most leg IK setups, you may want to ensure that the Set Transform Solver on the hips evaluates first, before the Limb IK leg chains. This is so the legs can properly compensate for the movement of the hips beforehand.



Solvers can be rearranged by dragging them up and down in the Solver Stack.



Excluding Bones

Bones within an IK chain can be excluded from the hierarchy, causing them to be ignored by all Solvers. This can be useful to correct bad poses, or to simplify a complex chain.

To exclude Bones, select all the Bones to be excluded, then right-click on them and select Exclude Selected Bone From Solve. Excluded Bones are denoted with a different icon.



You can re-include excluded Bones by right-clicking them and selecting Include Selected Bone In Solve.

Solver Types

The following is a list of the different Solvers you can use in IK Rig.

Body Mover

The Body Mover Solver will translate and rotate the root Bone based on the location of other connected IK Goals, which are typically the feet. Using Body Mover allows IK Rig to generate large-scale, gross movement of the body resulting in a more natural final pose

Body Mover requires a root Bone and at least two IK Goals to be connected. However, it can support several goals if the character is quadrupedal or multi-legged.

Body Mover is mainly intended for ground alignment, and should be used as the first Solver paired with other Solvers, such as Limb IK or Full Body IK.

For example, on its own, Body Mover does not produce correct looking results as an IK Solver.



However, once other IK Solvers are set up to evaluate after it, and with appropriate settings applied, then Body Mover will function more naturally.



Selecting the Body Mover Solver will reveal additional settings in the Details panel.



These settings are used to control the degree of movement exerted on both position and rotation axes, including their channels. In certain cases it may be necessary to adjust these properties to provide a more natural looking pose.

For example, on humanoid characters, setting Rotation Alpha to 0 will resolve the character leaning unnaturally towards the offset goal.



However, on quadrupedal or multi-legged creatures, it may be more natural to keep this root rotation and not change any settings.



Selecting a Goal Setting located underneath a goal assigned to the Body mover solver will reveal additional properties in the Details panel.



Influence Multiplier is used to increase or decrease the amount of influence this goal exerts on the Body Mover solver, and can be useful if you want a goal to have more influence compared to others.

Limb IK

Limb IK provides a cheaper-performance single-chain IK Solver. Typically you will want to use this for individual limbs, such as arms and legs.

Limb IK requires a root Bone and a single IK Goal to function. It follows typical IK rules in that you specify the starting bone (root), and an ending bone (goal). This Solver requires at least three Bones in the chain, in order to work correctly.

In most cases, you should specify the shoulder or arm as the root, and the hand as the goal. For legs, you should specify the upper leg or thigh as the root, and the foot as the goal.



Selecting Limb IK from the Solver Stack panel will reveal additional properties in the Details panel. These properties are only valid if your Limb IK chain is made up of more than 3 Bones. So if you are using Limb IK for a normal humanoid Thigh > Leg > Foot solve, then these properties will not affect its behavior.



Name

Description

Root Bone

The root Bone assigned to this Limb IK solver.

Reach Precision

This value controls the accuracy threshold of the effector reaching the goal's position. Lower numbers are more accurate and higher numbers are less accurate.

Hinge Rotation Axis

The normal plane for the solver chain.

Max Iterations

Increasing this value will cause the joint chain to better converge on the goal location, but increases the CPU cost of the Limb IK chain.

Enable Limit

Enables rotational limits on the joint chain between the root and effector.

Min Rotation Angle

If Enable Limit is enabled, this forces at least this input angle between the parent and child bone.

Average Pull

Enables an average pull distribution along the joint chain.

Pull Distribution

Manual control of the weight of the pull distribution along the chain if Average Pull is disabled. Lower numbers favor the effector, and higher numbers favor the root.

Reach Step Alpha

Moves the end effector towards the target and limits displacement.

Enable Twist Correction

Enables twist correction along the solver chain by comparing the orientations of bones along the chain.

End Bone Forward Axis

Which axis to favor if Enable Twist Correction is enabled.

Full Body IK

Full Body IK (FBIK) is a fully-featured multi-goal IK solver that supports Bone limits, stiffness, and preferred angles. This Solver is useful if you want to create a large-scale IK system for multiple goals, with each of them exerting natural influence upon the whole body.

A root Bone and at least one IK Goal must be connected for Full Body IK to function. However, unlike Limb IK, multiple goals may be added to allow the skeleton to reach for multiple locations simultaneously.



FBIK differs from other solvers in that you can create settings for any of the Bones affected by the Solver. This is so you can further refine the movement of a specific Bone within the FBIK chain.

To create a Bone setting, select the Full Body IK Solver, then right-click a Bone you want to create settings for and select Add Settings to Selected Bone.



Selecting the Bone setting in the Hierarchy will reveal the following Bone settings in the Details panel:



Bone Setting

Description

Stiffness

Rotation and Position Stiffness properties are used to control how much a bone in the IK chain can be affected by goals and effectors. Use these properties to change the degree to which the pelvis bone will be affected by the movement of the controls. A value of 0 results in completely free movement, whereas a value of 1 completely locks the bone from movement.

In this humanoid example, the pelvis bone is specified as the root Bone for the FBIK chain, however in its base state it is rotating too aggressively. Increasing the Stiffness properties resolves this.



Limits

Limits can be used to limit the range of, or completely lock, the rotation of bone axes along the IK chain. Each axis can be set to the following:

Free, which allows for the bone to move freely.

Limited, which only allows movement within a specified range. If this is chosen, then the Min/Max properties are used to define the range of movement.

Locked, which disables movement along that axis.

Using limits can help with correcting unnatural joint movement. For example, these limits can be used to correct the unnatural ankle rotation issue. A value of -50 is set for Min Z and 40 for Max Z, and the Z axis is set to Limited.



Preferred Angles

Preferred Angles can be used to prioritize joints rotating along a specific axis to reach the effector. In some cases they can be used to resolve rigid issues in joint rotation. Enabling Use Preferred Angles will cause the rotation to reference the Preferred Angles.

The Preferred Angle properties you specify depend on the type of character, and its joint structure. For this example, the mannequin's knee should be bending more along the Z axis, therefore the Z property is increased.



Selecting the Full Body IK Solver reveals the following properties in the Details panel:



Name

Description

Iterations

Increasing this value will cause the effectors to converge on their goal locations, but increases the CPU cost of the FBIK chain. The addition of Stiffness, a high Mass Multiplier, and Rotation Limits can all affect the convergence rate and may require more adjustments to this value.

Mass Multiplier

This is a global value that affects how much the bones resist rotations and translations. Typical values range between 0.0 and 10.0, with 0.0 being completely loose and 10.0 being very stiff. Increasing this value also requires you to increase Iterations in order to achieve convergence.

Increasing Mass Multiplier can resolve severe convergence problems within FBIK, which occur most commonly with larger characters. In general, the larger your character is, the higher this number should be.



Min Mass Multiplier

Keep this value as low as possible as long as the Solver provides stable results. Lower values improve the convergence of the chain.

Allow Stretch

Enabling this will cause bones along the IK chain to translate to reach their effector. Position Stiffness values affect this result, where higher stiffness will cause less stretching.

Root Behavior

Controls the translation behavior of the root Bone. You can select the following options:

Pre Pull limits the translation of the root by the average motion of the goals. This helps achieve better convergence so that all goals are reached.

Pin to Input locks the translation and rotation of the root. This also cancels any Bone settings applied to the root Bone.

Free allows the Bone to move freely or according to any bone setting. This setting requires more iterations to be set to achieve convergence when compared to Pre Pull.

Start Solve from Input Pose

When enabled, the Solver is reset each tick to start from the current input pose. If disabled, then the incoming animated poses are ignored and the solver starts from the results of the previous solve.

Selecting a Goal Setting located underneath a goal assigned to the Full Body IK Solver will reveal additional properties for that goal in the Details panel.



Name

Description

Strength Alpha

This property affects the strength of this effector's influence on the IK chain. Lower numbers will cause this IK Goal to not pull the chain towards it as strongly, causing other goals to take priority.

Pull Chain Alpha

When enabled by setting the value greater than 0.0, the FBIK solver will partition the skeleton into "chains" which extend from the effector to the nearest skeleton hierarchy divergence. Using this can improve results for sparse bone chains, but cause undesirable results for more complex constrained bone chains.

Pin Rotation

Blends the effector bone rotation between the rotation of the effector transform (1.0), and the rotation of the input bone (0.0).

Pole Solver

The Pole Solver provides Pole Vector controls for a single Bone chain, which is used to orient middle joints to face an IK Goal, like elbows or knees. Typically this Solver should be used in conjunction with other Solvers, such as Limb IK.

Pole Solvers differ from other solvers in that you must specify both a root and end Bone. This is done by right-clicking on the root and end bones and selecting Set Root / End Bone on Selected Solver. In this example, the upper arm is set as the root, and the hand is set as the end.



An IK Goal must also be used which will act as the Pole Vector. In most cases you must create it for the first child bone of the root.

For example, in a simple three-bone chain, the IK Goal must be created on the first child Bone of the root. This would place it on the middle joint.



In longer chains, the first child will not be the middle joint, making the IK Goal located closer to the root.



Once the root, end, and goal is specified, you can manipulate the IK Goal to preview the Pole Solver.



In most cases you should pair the Pole Solver with another Solver, with the Pole Solver executing last. In this example it is being paired with an IK Limb Solver.



Set Transform

Set Transform will translate and rotate a bone to match a goal. No IK system is involved as this Solver simply translates and rotates a single Bone and any children. In most cases this Solver should be paired with others to achieve a more complex IK effect.

This Solver only requires a single IK Goal to be connected, which is used as the transform point.



Typically you may want to pair this Solver with other solvers, with Set Transform executing first. In this example, Set Transform on the hips is being paired with Limb IK on the legs.



Creation and Overview

Retarget Chains

Chain Creation

Chain Properties and Names

Chain Display and Mapping

Retarget Root

Retarget Pose

Create and Edit Pose

Importing and Exporting Poses

Miscellaneous Workflows

Hierarchy Display

Preview Animation and Export

Batch Retargeting

Retargeter Properties and Settings

Editor Settings

Global Settings

Root Settings

Chain Settings

You can use IK Rigs to create animation retargeting between different Skeletal Meshes. This differs from Unreal Engine's traditional Animation Retargeting feature in that you can transfer animation between skeletons with varying numbers of bones, bone names, and orientations, while optionally maintaining precise hand or foot contact points using IK.

Retargeting animations provides a way to share animation data between multiple different skeletons, without needing to create and manage new animations outside of Unreal Engine.

This page provides an overview of the IK Retargeter.

Your project has two different Skeletal Meshes to evaluate the retargeting process.

IK Rig Assets have already been created and retargeting chains defined within them. Refer to the Retargeting Bipeds with IK Rig page for how to do this.

Creation and Overview

To create an IK Retargeter, click Add (+) in the Content Browser, then select Animation > IK Rig > IK Retargeter. A dialog window appears where you must select the IK Rig that you want to retarget animation from. Once selected, name and open the IK Retargeter Asset.



The IK Retargeter contains the following tools and options:



Retarget Pose, where you can edit, save, and import the base retarget poses on either the source or target character.

Viewport, where you preview and debug the source and target characters being retargeted.

The Details panel, which displays properties for your selected item or when other modes are active.

Hierarchy, which displays a filterable list of bones and their assigned chains on either character.

Retarget Output Log, which displays debug information, warnings, and errors indicating the current status of your IK Retargeter.

Chain Mapping, which is used to map target chains to source chains. The Asset Browser is used to preview and export retargeted animations.

Retarget Chains

Limbs and other appendages you want to transfer in the retarget process must be defined on both the source and target IK Rigs. This is a process similar to "characterizing" your rig as seen in other applications like Autodesk MotionBuilder or Maya. The main difference is you define it by joint chains, rather than by individual Bones. This provides flexibility in retargeting characters with vastly different bone structures.

For example, if your target character contains more arm joints than your source, the retargeting behavior will still work correctly because you are defining the entire arm chain, no matter the number of bones.



Source arm chain.

Target arm chain.

Chain Creation

Retargeting chains are created in the IK Rig Editor. To create a chain, open the IK Rig Asset for both characters, navigate to the IK Retargeting panel, then do the following:

Click Add New Chain (+).



In the Add New Retarget Chain dialog window, ensure Chain Name is set correctly, then click OK. In most cases, IK Rig automatically assigns this value from its list of common chain names.



In the Add Goal to New Chain dialog window, select No Goal. Typically you do not need to add IK Goals unless your retargeting requires additional IK adjustments, such as Speed Planting, Stride Warping, or Blend to Source.



You can also create chains by selecting every bone in the intended chain, right-clicking on them in the Hierarchy panel, and selecting New Retarget Chain from Selected Bones.



Chain Properties and Names

Chains require the following parameters to be set:

Name

Description

Chain Name

The name of this chain. This name can be arbitrary, but it should match with the intended retarget chain in the other IK Rig.

The matching chain name process is determined by a Fuzzy string match. Therefore, while your Chain Names in each IK Rig do not have to match perfectly, you should still try to match them. For example, a Chain Name of ArmLeft can match to left_arm as long as there isn't a name that might be more accurate.

Start Bone

The starting Bone of the retarget chain. If you are retargeting an arm, then typically you would select the upper arm bone here.

End Bone

The ending Bone of the retarget chain. If you are retargeting an arm, then typically you would select the hand bone here.

IK Goal

You can optionally select an IK Goal here in order to stabilize limbs or chains which may not be retargeting with good accuracy. This means you will also need to create Solvers for those goals, which will execute their solve after the retargeting process.

The Chain Name property automatically fills in itself depending on the name of the selected bones used when creating the chain. The system looks for common bone names used, and then picks a name that best matches the selected bones. This mapping list is as follows:

Chain Name Mapping

Bone Names to Search For

Head

head

Neck

neck

Leg

leg hip thigh calf knee foot ankle toe

Arm

arm clavicle shoulder elbow wrist hand

Spine

spine

Jaw

jaw

Tail

tail tentacle

Thumb

thumb

Index

index

Middle

middle

Ring

ring

Pinky

pinky

Root

root

For symmetrical chains, such as arms and legs, the auto-naming feature is determined by comparing the average location of the bones in the chain, and then assigning a prefix of Left or Right. If the selected bones are mostly located on the negative X side, they are "Left", positive X is "Right", and if they are relatively centered on the X axis, then they are considered "Center" and no prefix is applied.

If multiple chains are created for bones with similar names, a numerical suffix will apply for each subsequent chain. For example, if you were retargeting a creature with multiple heads, then the resulting chains would read as Head_1, Head_2, and Head_3. You can manually name your chains however you like, but this convention is helpful to establish standard naming conventions and retarget quickly using other IK Rigs.

Chain Display and Mapping

The Chain Mapping panel displays the source and target chains, and their mapping relationships. Using the dropdown menus under Source Chain, you can specify different chain mappings or correct mismatches.



Chains are drawn by default in the viewport and can be selected, which highlights the chain in the Chain Mapping panel. You can edit chain debug visualization in the Details panel.



Retarget Root

In addition to defining chains, you must also define the Retarget Root, which is typically the pelvis or hip bone. This is done so the character's root motion can be defined and transferred in a proportional way.

Like chains, the Retarget Root is defined in the IK Rig Editor. To do this, open the IK Rig Asset for both characters, navigate to the Hierarchy panel, right-click the bone and select Set Retarget Root.



Once done, the Retarget Root indicates with the selected bone in the Hierarchy and the IK Retargeting panels.



Retarget Pose

Depending on the reference poses of the characters being retargeted, it may be necessary to edit this pose in the form of a base Retarget Pose. Typically you need to do this if your target character's reference pose is different from the source, such as being in a T-pose, rather than an A-pose. Matching these retarget poses will increase the accuracy of the retargeting.



Source character's reference pose is an A-Pose.

Target character's reference pose is a T-Pose.

You can resolve reference pose discrepancies by editing, importing, or exporting different poses using the Retarget Pose tools in the Hierarchy panel.



Clicking Source or Target will change the focus of the Retarget Pose tools and Hierarchy panel to either the source or target character. If bone drawing is enabled in the viewport, then the skeletons will indicate which rig is currently focussed by highlighting in color.



Create and Edit Pose

Although you can edit the Default Pose for any of your retargeted characters, we recommend creating new Retarget Poses if you need to make adjustments. To do this, click Create (+) > Create New, name the new Retarget Pose, then click Ok.



Next, ensure Current Retarget Pose is set to your new pose, then enable Edit Mode. You can now select and modify bones in the viewport and match the poses. When finished, disable Edit Mode.



For extra precision, you can numerically modify retarget poses in the Details panel where a rotation value of 0, 0, 0 returns the bone to its reference pose.

Importing and Exporting Poses

Rather than manually creating new Retarget Poses, you can also import them from Animation Sequences or Pose Assets.

To import from an Animation Sequence, click Create (+) > Import from Animation Sequence. In the dialog window, select the sequence to import from and set the following parameters:

Sequence Frame defines a specific frame of the Animation Sequence to base the imported pose on. By default this will be set to 0, which will use the first frame of the animation.

Pose Name defines the name of the Retarget Pose upon importing.



To import from a Pose Asset, click Create (+) > Import from Pose Asset. In the dialog window, select the pose to import from, click the dropdown menu to set the specific pose name to use, then select Import Retarget Pose.



You can also export Retarget Poses as a Pose Asset to share with other IK Retargeting assets in your project. To do this, click Create (+) > Export Pose Asset, give your asset a name, then click Save.



Miscellaneous Workflows

The Retarget Pose area also contains the following miscellaneous tools to assist with creating and editing your Retarget Pose:

Name

Description

Current Retarget Pose

Displays the current Retarget Pose used by either the Source or Target character. Initially this will only list Default Pose, and populates when you create new poses. You can click the dropdown menu to select different poses.



Run Retargeter / Show Retarget Pose

When enabled, this engages the retargeter so you can preview the results of the current Retarget Pose using Animation Sequences. Disabling this switches back to Retarget Pose mode, where you can continue to make further refinements if necessary.



The viewport will highlight in a blue outline to indicate that the Retarget Pose mode is enabled.

Retarget Pose Blend

When making several edits to a Retarget Pose, it may be helpful to preview what changes have occurred on which bones. To help this, you can edit the Retarget Pose Blend slider. Setting it to 0 changes the pose back to the Skeletal Meshes default reference pose. Setting it to 1 changes the pose to the current Retarget Pose.



Reset

You can use the Reset menu to reset the Retarget Pose back to the Skeletal Meshes default reference pose. You can select the following options:

Reset Selected Bones, which resets only the bones you have selected in the viewport or Hierarchy.

Reset Selected and Children Bones, which resets only the bones you have selected and their children in the viewport or Hierarchy.

Reset All, which resets all bones.



Duplicate

You can duplicate the current Retarget Pose by clicking Create (+) > Duplicate Current, then naming the new pose.



Rename

Rename the current Retarget Pose by clicking Rename, entering a new name, then clicking Ok.



Hierarchy Display

The Hierarchy panel displays the skeletal hierarchy of either the Source or Target character, depending on which is enabled. Bone names indicate if they are used in Retarget Chains by highlighting in addition to the Retarget Chain column displaying the name of the chain being used.



You can search to locate and filter specific Bone Names or Retarget Chains.



You can also click the filter dropdown menu to set the following filters:

Hide Bones Not in a Chain, which hides bones not used within a chain, regardless if the IK Retargeter is using the chain.

Hide Bones Not Retargeted, which hides all bones not used by the IK Retargeter.

Hide Retargeted Bones, which hides bones used by the IK Retargeter



Preview Animation and Export

The Asset Browser panel is used to preview and export the retargeting effect on different assets. Double-click an asset to play it.



Once you are satisfied with your retargeting results on the target character, you can export the animations to compatible Animation Sequences for that character's Skeleton. To do this, select the animations you want to export in the Asset Browser panel, then click Export Selected Animations.



In the export dialog window, choose the export folder, then optionally specify the following rename properties:

Add Prefix, which adds text before the new asset name.

Add Suffix, which adds text after the new asset name.

Search for and Replace with, which searches for existing names in the file name and replaces it with the name specified. Search and replace is not case sensitive.

Click Export to save your retargeted Animation Sequences.



Batch Retargeting

Most animation assets, such as Animation Sequences, Blend Spaces, or Animation Blueprints can be retargeted quickly from the Content Browser using batch retargeting.

In the Content Browser, select the animation assets you want to retarget, then right-click them and select Retarget Animation Assets > Duplicate and Retarget Animation Assets.



A batch retargeter window appears where you can customize the retargeting behavior and results before starting the batch process.



Source and Target Skeletal Mesh preview. These panels will not be active until you specify an IK Retargeter. Once active, you can change the Target Skeletal Mesh if you want to change the character being retargeted to.

Changing the Target to a completely different skeleton from the one defined in the IK Retargter may produce incorrect results.

The IK Retargeter Asset to inform the Source and Target Skeletal Meshes and retargeting batch process.

Text fields where you can specify new Prefix and Suffix modifiers to the output asset names, as well as search and replacing text. Old Name and New Name will display a preview of your text entries.

The output folder where the retargeted assets will be saved.

Remap References Assets will enable any assets that have references to other retargeted assets (such as a Blend Space referencing an Animation Sequence) to remap to the newly created retargeted results.

Disabling this will maintain the original references and may cause issues with assets referencing animations that are no longer compatible with the new Skeleton.

Enabling this may cause reference issues if you are not retargeting all assets referenced.

Click Retarget to start the batch retargeting process.



Retargeter Properties and Settings

Editor Settings

The IK Retargeter Details panel contains the following properties when nothing is selected.



Name

Description

Source IKRig Asset

The source IK Rig to copy animation from.

Source Preview Mesh

The source Skeletal Mesh. You can change this, and the IK Retargeting system will use name matching to attempt to make the IK Rig compatible with a different mesh and skeleton.

Target IKRig Asset

The target IK Rig to copy animation to.

Target Preview Mesh

The target Skeletal Mesh. You can change this, and the IK Retargeting system will use name matching to attempt to adapt the IK Rig to the provided skeleton and proportions. Incompatibilities are printed as warnings or errors in the Retarget Output Log.

Target Mesh Offset

A positional offset that can be applied to the target Skeletal Mesh to offset it from the source. This is useful to help with previewing both characters, or if the target character is very large, requiring a larger offset.



Target Mesh Scale

A preview scale modifier which you can use to increase or decrease the target character's scale. This is useful if your target is very small or large relative to the source, where changing this value can align their sizes more closely for convenience.



Source Mesh Offset

Similar to Target Mesh Offset, this is a positional offset you can apply to the source Skeletal Mesh to offset it from the target.

Debug Draw

Enables drawing chain and root debug visuals in the viewport for the target character.



Draw Final Goals

Enables drawing IK Goals used by chains for the target character.



Draw Source Locations

Enables drawing IK Goals used by the source character.

Chain Draw Size

Controls the size of chains and IK Goals drawn in the viewport.

Chain Draw Thickness

Controls the line thickness of chains and IK Goals drawn in the viewport.

Global Settings

Clicking Global Settings in the Chain Mapping panel reveals additional settings for the IK Retargeter, including Stride Warping features.



Name

Description

Enable Root

Enables the translation movement of the root bone defined in the target IK Rig. Do not disable this unless you are debugging root retargeting behavior.

Enable FK

Enables the retargeting of all bone chains. Do not disable this unless you are debugging bone chain retargeting behavior.

Enable IK

Enables the IK retargeting pass if you are using IK Goals in the retarget chains. Do not disable this unless you are debugging IK retargeting behavior.

Stride Warping

Enables Stride Warping functionality, which allows manipulation of the stride length, width, and splay of the retargeted animations. Stride Warping requires your character to be set up using IK Goals for retargeting.

Forward Direction

The world space facing direction of your character. In most cases this is Y.

Direction Source

The source to use to determine a "best fit" global rotation that approximates the facing direction of the character over time. You can select from the following:

Goals: Uses the positions of IK Goals to approximate the facing direction. This option is best used on characters with a vertical spine, like bipeds.

Chain: Uses the positions of the bones in Retarget Chains to approximate the facing direction. This is best used for characters with a horizontal spine, like quadrupeds.

Direction Chain

If you set Direction Source to Chain, this property is used to specify which chain to use to help define the forward direction of the character.

Warp Forwards

Warps the IK goals along the forward direction. Values lower than 1 creates smaller strides, which values higher than 1 increase the stride length.



Warp Splay

Warps the overall stance of the character. Values below 1 pulls the IK Goals together to an average location, and higher than 1 pushes them apart.



Sideways Offset

Warps the sideways stance of the character. Values below 0 pulls the IK Goals together perpendicularly to the forward direction, and higher than 0 pushes them apart.



Root Settings

Clicking Root Settings in the Chain Mapping panel, or selecting the root in the viewport reveals Retarget Root settings for the IK Retargeter.



Name

Description

Rotation / Translation Alpha

Blends the animation on the retarget root between the Retarget Pose (0) and the incoming retarget source (1).

Translation Offset

Applies a component-space translation offset to the retarget root.

Rotation Offset

Applies a local-space rotation offset to the retarget root.

Scale Horizontal / Vertical

Scales the motion of the retarget root in either the horizontal or vertical directions. You can use this in conjunction with IK Goals and Translation Offset to create embellished or diminished movements on your retargeted characters.



Blend to Source

Blends the retarget root's translation between its retargeted location (0) and the exact source location (1). This property is similar to "reach" as seen in other retargeting tools.

Blend to Source Weights

Per-axis blending control multipliers for Blend to Source.

Affect IK Horizontal / Vertical

If you are using IK Goals, these sliders control whether all IK Goals should move along with the root if the root is modified along the horizontal or vertical axes. At 0 the IK Goals remain at their retargeted position, and at 1 they move relative to the modified root transform.

Chain Settings

Selecting IK Goals or Chains reveals chain-specific properties in the Details panel:



Name

Description

Source Chain

The source chain assigned to this IK Goal. Changing this is the same as changing Source Chain in the Chain Mapping panel.

FK

Enables copying the shape of the chain from the source character using rotation and translation.

Rotation Mode

Determines how rotation is copied from the source chain to the target chain. You can select from the following:

Interpolated: The source and target chains are normalized by their length, then each target bone rotation is generated by finding the rotation at the same normalized distance on the source chain and then applying that normalized rotation to the target. This typically provides the best result for targets with a different amount of bones in the chain, or different proportions.

One to One: Each bone in the source chain is copied to the equivalent bone in the target chain, based on the bone order starting from the root chain bone. If the target chain has more bones than the source, the extra bones will remain at their reference pose. This option is best chosen when the amount of bones in a chain match between the target and source, and typically is the best choice for finger chains.

One to One Reversed: This operates similarly to One to One, but the copying order is started from the end bone in the chain instead of the root.

None: No rotation copying occurs, causing bone rotations to remain at their reference pose.

Rotation Alpha

Blends the amount of FK rotation copying.

Translation Mode

Determines how translation is copied from the source chain to all bones in the target chain. You can select from the following:

None: No translation copying occurs, causing bone translations to remain at their reference pose. In most cases this is the best option to choose.

Globally Scaled: The target bone translations are set to the source bone, multiplied by the relative global scale of the target skeleton.

Absolute: The target bone translations are set to the absolute positions of the source bones.

Translation Alpha

Blends the amount of FK translation copying.

Pole Vector Matching

Blends the rotation angle of the target chain to the source chain by twisting the chain along its length. This does not alter the location of the end bone.

Pole Vector Offset

When Pole Vector Offset is set to 1, you can use this property to apply an angular offset (in degrees) to the rotation angle of the chain, essentially controlling the twist of the chain.

IK

Enables using an IK Goal to modify this chain. To enable this, you must associate an IK Goal with the chain in the IK Rig asset.

Blend to Source

Blends the IK Goal's translation between its retargeted location (0) and the exact source location (1). This property is similar to "reach" as seen in other retargeting tools.

Blend to Source Weights

Per-axis blending multipliers for Blend to Source.

Static Offset

Applies a world-space translation offset to the IK Goal.

Static Local Offset

Applies a local-space translation offset to the IK Goal.

Static Rotation Offset

Applies a local-space rotation offset to the IK Goal.

Extension

Moves the IK Goal along the direction of the chain. Higher values increase the distance, and lower values move it closer to the root bone in the chain.

Affected by IK Warping

Enables this IK Goal to be affected by Stride Warping properties. Typically this should be enabled for IK Goals used for leg chains, and disabled for all others.

Speed Planting

Enables this IK Goal to use Speed Planting properties.

Speed Curve Name

The name of the Animation Curve that contains the speed curve data.

Speed Threshold

The maximum speed a source bone is allowed to move for the Speed Planting system to determine it is not moving. This causes the target IK Goal to not move whenever the source bone speed drops below this threshold.

Unplant Stiffness

How stiff the spring model is that smoothly pulls the IK position after unplanting. Increasing this means increasing the speed that the IK Goal reaches the target value.

Unplant Critical Damping

How much damping to apply to the spring. A value of 0 means no damping, and a value of 1 means critically damped, causing no oscillation.

Chains with adjusted settings will indicate in the Chain Mapping panel.



Setup

Usage

Properties

Once your IK Rig is created, you can reference it within Animation Blueprints to use its IK behavior in gameplay.

This document provides an overview of this process, and the various features available to you.

You have created an IK Rig for a Skeletal Mesh. Refer to the IK Rig Editor page for example setup instructions.

Your Skeletal Mesh has an Animation Blueprint, which the Third Person Template project provides if you do not have one.

You have a basic understanding of using Animation Blueprints.

Setup

IK Rigs are referenced in Animation Blueprints from the AnimGraph panel. Right-click in the graph and select IK Rig from the Misc category to create an IK Rig node.



Once added, you will need to assign your IK Rig to the Rig Definition Asset property in the Details panel.



In common setups the IK Rig node is placed after most of your locomotion and other AnimBP logic. This is so that IK adjustments can occur correctly in sequence after other effects.



Usage

By default the IK Rig will not cause any change in your animation pose. In order to affect IK changes from the node you need to expose an IK Goal's position, rotation, or both.

To do this, select an IK Goal in the IK Rig editor and enable Expose Position and Expose Rotation in the Details panel. This will add pins for that goal's position or rotation on the IK Rig node, and expose the goal for manipulation.



From here you can create Variables for these properties and build logic that manipulates your IK Rig.

You can test the behavior of the IK Rig in the Animation Blueprint by adjusting either the Goal Position or Rotation pin values.



Editing the Position / Rotation Alpha will blend the IK effect on/off for that goal on the respective axis.



Properties

Selecting the IK Rig node reveals the following IK Rig-specific properties in the Details panel:



Name

Description

Goals

The property section will populate for each IK Goal that is exposed, and provide you with additional settings to control its behavior. You can specify a goal to be one of the following types:

Manual Input, which exposes the Position and Rotation pins on the node for manual control of the goal's transform. You can also choose the position or rotation space that is applied to the goal:

Additive, which treats the goal transform as a world-space additive offset relative to the to the Bone at the effector.

Component, which treats the goal transform as being in the space of the Skeletal Mesh Actor Component.

World, which treats the goal transform as being in world space.

Bone, where you can specify a Bone within this skeleton for the goal to snap to. This can be useful when using auxiliary Bones, like weapon or prop Bones, which may procedurally adjust.



Rig Definition Asset

The IK Rig Asset to modify the incoming pose.

Start from Ref Pose

Enabling this ignores the incoming pose and instead starts the solve using the Skeletal Mesh reference pose.

Enable Debug Draw

This enables the visibility of all IK Goals within the Viewport for debugging and preview.



Debug Scale

Increases or decreases the scale of the IK Rig debug draw, if Enable Debug Draw is enabled.

Root Motion

Pose Warping

Motion Warping

Distance Matching

In Unreal Engine character Locomotion is built on the foundation of character object, movement, and animation playback. This foundation is supported with Locomotion tools that you can use to synchronize character movement behavior with reactive and dynamic animations.

This document provides an overview of the character Locomotion tool in Unreal Engine.

Root Motion

By enabling Root Motion, a character's movement can be driven by an animation sequence using motion data from the Root Bone. Animations with their Root Motionenabled, create more realistic and grounded movement behaviors and interactions within levels.



Read about how you can drive a Character's movement with animation playback using Root Motion in the following documentation.



An overview Root Motion Animations in Unreal Engine.

Pose Warping

You can enable Pose Warping to dynamically adjustment a character's animated poses to align with character movement, using Root Motion. With Pose Warping, you need fewer individual animations to reach the same level of animated-movement coverage as before. This reduces the dependency on animation-dictated gameplay, and allows animation and gameplay tuning to evolve side by side during development.



Read about Pose Warping and an example implementation in the following documentation.



Pose Warping dynamically warps a character's animated pose to align with capsule movement.

Motion Warping

With Motion Warping, you can dynamically warp windows of a character's animation to align with Root Motion or to align with assigned Warp Targets. With this feature, you can rely less on the manual creation and fine tuning of animations to fit specific object interactions, and apply logic to bend base animations to fit pre-established conditions.



In the following documentation you can read more about Motion Warping and follow along with an example workflow.



An in depth look at Motion Warping for animations in Unreal Engine.

Distance Matching

With Distance Matching you can use a calculated distance value, to or from, a target to drive Animation Sequences. Distance Matching can align animation playback with character speed, reducing the need for manual animation tuning when altering character behaviors.



Read about Distance Matching and see an example workflow in the documentation below.



An in depth look at Distance Matching in Unreal Engine with an example workflow implementation.

Overview

Root Bone

Root Motion

Enabling Root Motion

Animation Sequence

Animation Blueprint

Results

Debugging Root Motion

Animation Sequence Editor

Console Command

With Root Motion animations, you can drive character movement with animation data to create more grounded movement within levels.

This document provides an overview of Root Motion, and a quick explanation of how to enable Root Motion in compatible animations.

Your project contains a character with a Skeleton that has a Root Bone.

Your project contains an Animation Sequence or a Montage with motion data assigned to the Skeleton's Root Bone.

Overview

Within a level, a character is composed of many Components. A character's movement is often driven by the character's Movement Component, with animation playback layered on top to communicate the visual feedback of motion.

Below is an example of a character rendered with a Skeletal Mesh Component and a Capsule Component in the Blueprint Viewport Editor.



Root Bone

Animations are driven by the Skeletal Mesh's Skeleton, which is composed of bones. The Root Bone is the Skeleton's foundational bone; unlike other bones, the Root Bone is not built to represent an element of the Skeletal Mesh, like a leg or arm, but rather, is a reference point for the entire skeletal structure. Some animations do not have any animation data on the Root Bone, it remains stationary and grounds the skeleton and the animation to a single point, while others animate the Root Bone to follow the animation's displacement in 3D space.

Below is an example of a Skeletal Mesh with its Root Bone highlighted.



Root Motion

In the absence of any character movement, animations with a stationary Root Bone will play in place with no actual movement or displacement.



While some animations, like the animation above, have a stationary Root Bone, others have movement assigned to the Root Bone.

Below is a demonstration of an animation with movement data on the Root Bone. The red line represents the tracked displacement of the Root Bone, from its starting position to its current location.



However, an animation containing animation data on the Root Bone does not affect the character movement by default, it must first be enabled with the Root Motion property.





No Root Motion

Using Root Motion

Without Root Motion enabled, the animation is animating the Skeletal Mesh off the Root Bone and away from the character (represented with the wireframe capsule). The Skeletal Mesh disconnects from the character, before snapping back to the starting position at the end of the animation cycle. By enabling an animation's Root Motion, the Root Bone motion data can drive the character's movement, which drags the character along with the Root Bone's movement.

By driving character movement with Root Motion, animations are able to recursively loop, beginning from the character's last position from the previous animation loop. Below is an example of recursive animation cycles.



Enabling Root Motion

In order to enable and use Root Motion features, you must first have a Skeleton that has a root bone, and an animation with an animated root bone.

Animation Sequence

Each individual Animation Sequence or Montage must be toggled to Enable Root Motion. This property is found and modified within the Asset Details panel in the Animation Sequence Editor.



Below is a listing and explanation of the properties relating to Root Motion found when editing an Animation Sequence Asset.

Property

Description

Enable Root Motion

When enabled, Root Motion data is extracted. Uses the Animation Blueprint's Class Defaults property Root Motion Mode to define how Root Motion is extracted.

Root Motion Root Lock

Locks the Root Bone to the defined position when extracting the Root Motion.

The options for the position with which to lock the Root Bone are as follows: Ref Pose: Locks the Root Bone to the location it presides in the Reference Pose for the Skeletal Mesh. Anim First Frame: Locks the Root Bone to its location in the first frame of the selected animation. Zero: Locks the Root Bone position to a 0,0,0 coordinate point, relative to the mesh.

Force Root Lock

When enabled, forces the Root Bone to Lock, even if Root Motion is not enabled.

Use Normalized Root motion Scale

When enabled, applies a normalized scale to the extracted Root Motion. FVector(1.0, 1.0, 1.0).

Animation Blueprint

After enabling Root Motion within an individual Animation Sequence's parameters, you need to determine how that sequence is handled inside of the Animation Blueprint driving your object's animations. There are several different ways you can handle Root Motion within Animation Blueprints. To access these options, click Class Defaults in the Animation Blueprint Editor's Toolbar. This opens a Details panel that contains a Root Motion Mode property with a drop down menu.



The options are as follows:

Name

Description

No Root Motion Extraction

Root Motion remains unchanged (applied to the root bone).

Ignore Root Motion

Root Motion is extracted (and removed from the root bone), but not applied to the character.

Root Motion from everything

Each Root Motion enabled animation asset that contributes to the final character pose has its Root Motion extracted. The extracted Root Motion is blended based on the weight of the source assets contributing to the pose.

Root Motion from Montages Only

Root Motion is only extracted from Root Motion enabled Animation Montages.

There is a performance cost to enabling Root Motion.

When either Root Motion from everything or Root Motion from Montages is enabled, the Animation Graph is updated on the Game Thread instead of a Worker Thread. More work on the Game Thread can cause performance issues.

Results

Once Root Motion is enabled in your animation and the application method of Root Motion extraction is defined in the Animation Blueprint, the animation drives the Movement Component during playback.

The physics state of the character is taken into account during Root Motion. For example, if a character is Walking or Falling, along an X and Y axis, then the Z-axis of Root Motion is ignored, and gravity is applied. This character will fall, go down slopes, or up stairs. If the character is Flying, in an unbound state, then the full Root Motion is applied and gravity is ignored.

This is defined and adjusted within the character Blueprint with a Movement Mode Node.

Debugging Root Motion

Below are relevant debugging properties for working with Root Motion animations.

Animation Sequence Editor

While working with animation sequences in the editor's Viewport, there are many helpful features at your disposal for debugging purposes.

To render the character's Skeleton as an overlay over the Skeletal Mesh, navigate to the Character tab and open the Bones breakout menu. Within the Bone Drawing header, select All Hierarchy. This option renders the entire Skeleton, including the Root Bone rendered in red. Since the Root Bone is undergoing a transform, a red line is rendered between the Root Bone origin point and the current location.

Below is a demonstration of enabling the All Hierarchy Bone Drawing Mode.



The Red Line represents the Root Bone displacement due to enabling Root Motion. You can see the amount of displacement, and track the movement of the Root Bone during animations with Root Motion enabled.

To alter the playback settings of the Root Motion animation, navigate to the Character tab and open the Animation breakout menu. Under the Root Motion header you can toggle the preview playback options as shown and described below.

Option

Image

Description

Ignore



Ignores any present Root Motion and plays back the animation in a static setting.

Loop



Enables the Root Motion playback, and continually loops the animation beginning from the endpoint of the previous loop.

Loop and Reset



Enables the Root Motion playback, and continually loops the animation beginning from the Root Bone origin point for every loop.

Console Command

You can enable a character's Capsule Component to display during run time with a Console Command.

Although the Collision Component is not the character object, the Collision Component can be a quick and easy way to visualize the character object separately from the Mesh.

While a game is running in the editor, press the Backtick (`) key, to enable the console command window.

Enter the console command: show collision, and press the Enter key.

Pose Warping Overview

General Details

Pose Warping Nodes

Orientation Warping

Stride Warping

Slope Warping

Pose Warping Workflow

Adding Necessary AnimBP Nodes

Defining Necessary Parameters

Results

Debugging

Orientation Warping

Stride Warping

Pose Warping lets you dynamically adjust a character's animated pose to align with Capsule Movement. This document will describe the Pose Warping features as well as demonstrate an implementation of Pose Warping in your Character's Animation Blueprint.

Enable the Animation Warping plugin. For more information regarding Plugins and how to Install them, refer to Working With Plugins.



Pose Warping uses Animation Blueprint workflows, so you need to understand this feature.

In addition, a Root Motion enabled animation, an Implemented IK Rig, and a Direction Variable driven by Root Motion, must be accessible in the project where you want to create gameplay examples.

Pose Warping Overview

The Pose Warping set of Animation Blueprint nodes perform dynamic adjustments to Animation Sequence Poses through warping, to create more cohesive animation interactions within the game world.

Pose Warping can be broken down into three nodes. Each of these nodes performs a specific-use warping implementation to adjust animations to match Root Motion in unique ways.



Orientation Warping

Stride Warping

Slope Warping

Within the properties of each node, many parameters can be defined through a Manual Evaluation mode of control over the generation of these warps. A Graph Evaluation mode is also present and can define these parameters automatically.

General Details

Below you will find an explanation of the Pose Warping node properties and their functions.



Name

Description

Mode

Select a mode in which the Pose Warping node will derive the value with which to Warp the Poses of animation.

Manual: Animation Warping evaluations are derived from the user-defined parameters. Due to a lack of transitional smoothness when relying on updating variables, this is best used in static or scripted instances. Graph: Animation Warping evaluations are derived from dynamically-defined, graph-driven parameters. Some node properties will change and now require Root Motion enabled Animation Sequences.

IK Foot Root Bone

Define the IK Foot Root Bone of the skeleton.

Pose Warping Nodes

Below you will find a description of the unique properties for each of the Pose Warping nodes, and explanations of their functions.

Orientation Warping

The Orientation Warping node applies directional compensation warps to animations in motion. With this node, you can isolate and warp the leg IK bones of an animation pose to align with the dynamically updating locomotion direction of the root motion. The pose will also maintain the facing angle by twisting the spine bones along a designated axis.

This feature can be used to fill coverage gaps in animation sequences, reducing the need to manually create interstitial animations or the creation of excess blend space transitions.



Below you will find a description of the Orientation Warping properties and their functions.

Property

Description

Orientation Angle

Only available when the Evaluation Mode property is set to Manual. Defines the degree of orientation you want to warp the locomotion component's pose. This value is relative to the Axis specified under the Rotation Axis property.

Locomotion Angle

Only available when the Evaluation Mode is set to Graph. Defines the degree of orientation you want to warp the locomotion component's pose. Built to use graph-driven values, the Locomotion Angle excels with dynamically changing values.

This will be used in the following equation for computing the orientation angle: [Orientation = RotationBetween(RootMotionDirection, LocomotionDirection)].

Location Angle Delta Threshold

Specifies an angle threshold to prevent erroneous over-rotation of the character. By default, this property is set to 90 degrees, and it can be disabled by setting a value of 0.

Spine Bones

Defines the spine bones which taper the warp throughout, to provide a more seamless-looking rotation.

Use the Add (+) button to add more definitions. Index 0 is the highest hierarchically-ranked and the least-rotated bone, with each additional Index being the next nested spine bone and more progressively influenced by the rotation.

IK Foot Bones

Add and define the Index instances of the IK Foot Bones present in the skeleton.

Rotation Axis

Define the axis by which the orientation warp should occur. For most cases, orientation warping should occur on the Z axis, resulting in a twisting of the body.

Distributed Bone Orientation Alpha

Specifies how much of the rotation is distributed across the character body through the spine bones. This value is biased towards the upper body, with a value of 1 indicating that the total rotation occurs at the Index 0 spine bone and a value of 0 indicating rotation occurs at the highest indexed spine bone.

Rotation Interp Speed

Specifies the interpolation or blending speed (in alpha per second) in order to reach the final warped rotation angle. Lower values indicate low interpolation speed and thus slow transitions between locomotion changes and animation warping. Greater values will have quicker transitions with less smoothing. A value of 0 will cause instantaneous rotation.

Stride Warping

Stride Warping is a Pose Warping node that dynamically adjusts the animated stride of a character to match the capsule movement speed. By defining the speed of motion, and the relevant bones, the Stride Warping node is able to modify the spacing between foot positions, to create a dynamically adjusting stride length to match motion speed. This reduces the need to manually tune movement speeds to match animation playback, and reduces the dependency on blend spaces to transition between different animation sequences for different speeds of movement.



Below will find the Stride Warping properties and their applications.

Property

Description

Stride Direction

Only available if the Evaluation Mode is set to Manual. Defines the direction of motion towards which the stride will be.

Stride Scale

When the Evaluation Mode is set to Manual, scales the amount of warping applied to the foot definitions in order to fine tune the stride adjustment. A value of 1 will provide a default scale of warping, 0.5 will decrease the effective leg stride by half, and a value of 2 will double the effective leg stride.

The following equation will be used for computing the Stride Scale: [StrideScale = (LocomotionSpeed / RootMotionSpeed)].

Locomotion Speed

When the Evaluation Mode is set to Graph, specifies the current speed of motion applied to the character. Relying on the Graph Driven Evaluation mode, this parameter is designed to work cohesively with dynamically updating data, such as Root Motion or Capsule speed. For best results, the declared speed should be relative to the delta time of the animation graph.

Min Locomotion Speed Threshold

The defined threshold for the minimum locomotion speed value required to apply the effects of the Stride Warping feature.

Pelvis Bone

Define the skeleton's Pelvis Bone.

Foot Definitions

Within this parameter, Indexes can be created and used to define the necessary IK and FK feet and thigh bones to perform warps. One index with its necessary definitions is needed per locomotion leg present in the skeleton.

Stride Scale Modifier

With this parameter, you can add clamps and interpolation guidelines that will modify the final Stride Scale Result. These limits can be activated by toggling the Clamp Result or the Interp Result sub-properties.

Clamps can be modified by specifying the minimum and maximum values to allow scaling to take place. A value of 1 is the base scale, 0.5 is half scale, and 2 is double scale.

Interpolation speeds can be defined to control the range at what motion speeds the interpolation is applied. Interp Speed Increasing defines the threshold at which interpolation is applied with increasing motion speed values. Inversely, Interp Speed Decreasing defines the threshold at which interpolation is applied as motion speed is decreasing.

Below you will find the Advanced properties found in the parameters of the Stride Warping node used for fine tuning stride warping applications.

Name

Description

Floor Normal Direction

This value internally converts into a corresponding Component-space representation prior to warping.

Mode: Space of the corresponding Vector Value. Component Space Vector Actor Space Vector World Space Vector IKFoot Root Local Space Vector

Value: Specifies a vector relative to the space defined by Mode.

Gravity Direction

This value internally converts into the corresponding Component-space representation prior to warping.

Declares the space to which this property will convert the corresponding Vector Value that will apply the simulated directional pull of gravity. The different modes of declared space are as follows: Component Space Vector Actor Space Vector World Space Vector IKFoot Root Local Space Vector

Pelvis IK Foot Solver

Solver for controlling how much the pelvis is "pulled-down: towards the IK/FK foot definitions during leg limb extensions.

Pelvis Adjustment Interp: Specifies the spring interpolation parameters applied during pelvis adjustment. Defined by a Stiffness Constraint property and Dampening Ratio Property. Pelvis Adjustment Interp Alpha: Specifies an alpha between the original and final adjusted pelvis locations. This is used to retain some degree of the original pelvis motion. Pelvis Adjustment Max Distance: Specifies the maximum displacement the pelvis can be adjusted relative to its original location. Pelvis Adjustment Error Tolerance: Specifies that if the pelvis adjustment distance is incrementing at a value lower or equal to this value for each iteration, the solve will halt. Lower values will marginally increase visual quality at the cost of performance, but may require a higher PelvisAdjustmentMaxIter to be specified. Pelvis Adjustment Max Iter: Specifies the maximum number of iterations to run for the pelvis adjustment solver. Higher Iterations will guarantee closer PelvisAdjustmentErrorTolerance convergence at the cost of performance.

Orient Stride Direction Using Floor Normal

Orients the specified (Manual) or computed (Graph) stride direction by the floor normal.

Compensate IK Using FK Thigh Rotation

Include warping adjustments to the FK thigh bones alongside the IK/FK foot definitions. This is used to help preserve the original overall leg shape.

Clamp IK Using FK Limits

Clamps the IK foot warping to prevent over-extension relative to the overall FK leg.

Slope Warping

Slope Warping assists in warping feet locations to match the floor normals, to create smoother transitions of locomotion animations on inclines and stairs.



This node is still in development, don't trust a project to its functionality, but implementation is encouraged in testing environments.

Below is a list of properties associated with the Slope Warping node.

Name

Description

Pelvis Bone

Define the skeleton's Pelvis Bone.

Feet Definitions

Within this parameter, Indexes can be created and used to define the necessary IK and FK feet bones, the Number of Bones associated to the defined feet, and the Foot Size value, in Unreal units. These definitions define the bones the node will use to perform the slope warps. You need one index with its necessary definitions per locomotion leg present in the skeleton.

Pelvis Offset Interpolator

Specifies the pelvis bone offset interpolation parameters applied during pelvis adjustment. Defined by a Stiffness Constraint property and Dampening Ratio property.

Gravity Dir

Define the Direction of gravitational pull in the skeletal elements affected by the warp.

Custom Floor Offset

Define which axis to use to perform the custom floor offset in relation to the skeleton.

Floor Normal Interpolator

Specifies the floor normal interpolation parameters applied during pelvis adjustment. Defined by a Stiffness Constraint property and Dampening Ratio property.

Floor Offset Interpolator

Specifies the floor offset interpolation parameters applied during pelvis adjustment. Defined by a Stiffness Constraint property and Dampening Ratio property.

Max Step Height

Defines the maximum value of height adjustment possible between steps of slope warping in Unreal units.

Keep Mesh Inside Of Capsule

When enabled, prevents warping from pushing the Mesh outside of the Capsule.

Pull Pelvis Down

Enables pulling the pelvis down to accommodate new foot placements.

Use Custom Floor Offset

Toggles the use of a custom floor offset.

Pose Warping Workflow

The workflow below demonstrates a basic implementation of the Orientation Warp node in a Character's Animation Blueprint to add warping to locomotion animations.

To begin, call a reference to a Root Motion Enabled Animation Sequence, within the AnimGraph of a character's Animation Blueprint. For this demonstration, the animation can be as simple as a single directional movement animation, and as complex as a full array of cardinal direction movements with transitions. The Locomotion State Machine used in this demonstration, only contains a forward jog animation.

With this single animation, and the Orientation Warping node, a full 180 degrees of lower body animation will be possible, adapting to analog input controls while retaining the upper body facing angles.

Adding Necessary AnimBP Nodes

This demonstration uses a simple state machine with a transition between an idle and single forward jog animation that is Root Motion Enabled.



By dragging off of the Output Pin of the State Machine, create a Local To Component space conversion node. This node is required to convert the animation poses that make up the animation sequence to the component space.



From this Local To Component space conversion node, drag off of the Output Pin to create the Orientation Warping node.



After the Orientation Warping node, you need a downstream Leg IK node to communicate the warps being made to the IK bones of the skeleton to the FK bones.



By connecting the Leg IK node to the Result node, the Local to Component conversion will close automatically by creating a Component To Local space conversion node.



With all of the necessary nodes in place, compiling will return errors related to the Orientation Warping node. Within the compiler results panel, the Orientation errors listed request spine and IK bone definitions. These bones can be defined in the Orientation Wrapping properties found in the details panel, and are explained in the next section.



Defining Necessary Parameters

Clicking the Orientation Warping node in the AnimGraph viewport will open the Details panel. Under the Settings header, you can assign the instances of the IK foot root and the individual IK feet for the skeleton. Additionally you will need to Add (+) and specify at least one spine bone for the node to displace the twist in order to retain the facing angle of the character. One bone will operate like a pivot point for the entire lower body. Adding more spine variables will taper the warp across the spine bones to appear more natural.



It is a good idea to populate as many spine bones as are present in the skeleton of your model.

Now the Orientation Warping angle must be defined. This angle can be defined manually with extensive parameterization, or a dynamic value, such as a directional variable driven by the angle of Root Motion, can provide this angle automatically.

In the Details panel of the Orientation Warping node, change the Evaluation Mode to Graph. The Graph Evaluation mode will change the Orientation Angle pin, a manual and static value, to the Locomotion Angle pin which can be connected with a graph-driven value. For this example we will use a Direction variable driven by the Capsule movement direction.



Call the Direction variable and connect the Output Pin of the variable node to the Locomotion Angle Input Pin.



Lastly, you need definitions for the IK bones with their FK bone counterparts within the IK Rig properties to blend the occurring warps.

In the IK Rig Details panel, create a Leg Definition array for each leg present in the model using Add (+). Define the IKFoot Bone and the FKFoot Bone in the array.



The Num Bones In Limb property, found in the Leg Definition array, describes the number of bones found in the leg structure that are associated with each foot. This value, not including the foot bones themselves, must account for every bone that makes up the remaining structure that should be warped. In the case of this example, from the foot we have a calf and a thigh bone before reaching the pelvis bone. Since the pelvis is not a part of the leg structure, we declare 2 bones to associate with the already defined foot bone. This is a typical structure but your skeletal mesh may differ.

Results

Compiling, saving, and playing the level demonstrates effects of the Orientation Warping node. With only a single animation sequence, a forward jogging animation, a full 180 degrees of locomotion coverage is generated. In addition, by defining the spine bones, a facing angle is retained so the character remains facing the direction of movement.

Before Pose Warping

After Pose Warping





In the above demonstration, the input being applied to the character does enact locational and direction movement to the mesh, through the capsule. Due to the limitations of the present animation coverage, the input has no effect on the animation playback. The animation simply loops in a single direction.

After the above workflow is completed, warping is being performed in real-time, driven by the character's input. Notice the twisting occurring in the spine, in order to focus the direction of the leg animation to follow the input-driven locomotion direction (Red arrow), while also retaining the Root Motion driven facing direction (Blue Arrow).

Below is a full image of the Animation Blueprint logic used for this page's implementation of the Orientation Warping node.



Debugging

Below you will find a description of debugging properties to assist in correcting any encountered issues when implementing the Orientation or Stride Warping nodes.

Orientation Warping

Below you will find a description of the Orientation Warping node's Debugging properties and a description of their function.

Name

Description

Debug Draw Scale

Uniformly scales the visually drawn debugging guides.

Enable Debug Draw

If enabled, a set of colored arrows will be drawn to represent vectors of interest, originating from the character in the viewport during run. Red arrow: Input Direction. Blue arrow: Root Motion. Green arrow: Simulated Direction, a blended vector, determined by input and displayed action. The speed of this blending can be adjusted using the Rotation Interp Speed property in the Details panel.

Stride Warping

Below is a list of Debugging properties to assist in the successful implementation of the Stride Warping node.

Name

Description

Debug Draw Scale

Uniformly scales the visually drawn debugging guides.

Enable Debug Draw

Displays a red arrow, representing a movement speed vector, originating from the center of the Character's Capsule, in the viewport during run. With a higher input force, a longer arrow will be drawn, and with smaller input force, the arrow will shorten.

Debug Draw IKFoot Origin

When enabled, the defined IK Feet are made visible with a red sphere.

Debug Draw IKFoot Adjustment

If enabled, blue vector arrows will be drawn, originating from the IK Feet center, to visibly show the adjustments being made.

Debug Draw Pelvis Adjustment

When enabled, a vector will be drawn in the viewport, indicating the Pelvis Bone adjustments being made.

Debug Draw Thigh Adjustment

Toggle drawn vectors to visually see adjustments being made to the defined Thigh Bones.

Debug Draw IKFoot Final

This property will enable drawing a visual representation of the final location of IK Feet bones after a full warp has occurred.

Motion Warping Overview

Animation Montage

Creation

Details

Blueprint

Motion Warping Component

Nodes

Motion Warping Example

Set up Target Location

Set up the Animation Montage

Get Target Location

Warp Target

Play Montage

Results

Motion Warping is a feature where you can dynamically adjust a character's root motion to align to targets. This document will show you how to create the Motion Warping logic in your character blueprint, assign Motion Warping windows within animation montages, and link them to named positions.

You must enable the Motion Warping plugin. For more information regarding Plugins and how to Install them, see: Working With Plugins.



Motion Warping utilizes Blueprint and Animation Montage workflows. Therefore you should have an understanding of these features.

You have a Character Blueprint, Input Controls, and Animations in your project that you can create gameplay examples with.

Motion Warping Overview

The overall feature for Motion Warping can be broken down into two main areas:

Animation Montage, where you create motion warping windows with Anim Notify States.



Blueprint Logic, where you set up the logic to assign the warp target and play the Montage.



Animation Montage

Animation Montages are where you specify the Motion Warping areas, customize their behavior, and name them.

Creation

To create a new Motion Warping region, right-click on one of the Notifies tracks and select Add Notify State... > Motion Warping.



These are customizable areas with start and end times that you can align to areas of the animation where warping is best applied.

For example, in this mantling montage, you likely need to ensure your starting warp region covers the area when the character places their hand on the obstacle.



Details

The Anim Notify's Details panel contains properties and settings necessary for your Motion Warping to function. Select your motion warping section to reveal these details.



Detail Name

Description

Root Motion Modifier

The Motion Warping type to specify.

Scale: A Motion Warp that alters an animation's scale in a uniform manner. Skew Warp: Warps the game object's root motion so that it matches the animation's location and rotation in the level at the end of the warping window.

Warp Target Name

The name used to find this warp target. Correlates to the Add or Update Warp Target Blueprint node.

Warp Point Anim Provider

Select which provider is desired for the Warp Point.

None: No Warp Point Provider is declared here. Static: Warp Point defined by a user-defined parameter transform, which can be declared through the warping notify itself. Bone: Warp Point is defined by a Bone.

Warp Point Anim Transform

Transform the Animation Warp Point. Only relevant when the Warp Point Anim Provider is set to Static.

Warp Point Anim Bone Name

Declare the Bone Name with which to target as a Warp Point. Only relevant when the Warp Point Anim Provider is set to Bone.

Warp Translation

Whether to warp the translation component of the root motion.

Ignore ZAxis

Whether to warp the Z component of the translation.

Warp Rotation

Whether to warp the rotation component of the root motion.

Rotation Type

Whether the rotation should warp to match the warp target's rotation or face the warp target.

Default: Character rotates to match the rotation of the warp target. Facing: Character rotates to face the warp target.

Warp Rotation Time Multiplier

Modifies how fast the rotation is warped. For example, if the Motion Warping window lasts for two seconds, and this property is 0.5, then the final rotation will be reached in one second.

Notify Color

Sets the color of the Motion Warping Notify keyframe.

Blueprint

Blueprints are used to add your Motion Warping component, trigger the warp to occur, and specify warp targets.

Motion Warping Component

You must add a Motion Warping Component to your blueprint to enable Motion Warping behavior. To do this, click (+) Add in the Components panel and locate Motion Warping under the Movement category. Click it to add.



The Component can now be referenced in your blueprint graph by dragging and dropping it from the Components panel to the Event Graph.



Nodes

Dragging a link from the Motion Warping reference allows you to browse for functions and events related to it. These are located within the Motion Warping category.



You can use the following Motion Warping nodes in your Blueprint:

Node Name

Node Image

Description

Add or Update WarpTarget



This node is used to link the Warp Target Name, which was defined in the Montage Asset, to a location. The Warp Target pin can be split into separate Translation and Rotation pins by right-clicking it and selecting Split Struct Pin.

Conversely, you can use the Remove Warp Target node to unlink the Warp Target Name.

Add Root Motion Modifier Skew Warp



You can use this node to generate new Motion Warping Windows with Blueprints instead of adding Skew Warp Anim Notifies in the Montage Asset.

Settings for this Motion Warping Window can also be assigned here, such as Start Time and End Time and Warp Target Name.

Also available is an Add Root Motion Modifier for Scale node, as well as a node for disabling all Root Motion Modifiers.

Motion Warping Example

This section describes how you can set up a simple Motion Warping example of a character warping to a target to punch.



Before starting, ensure the animation you intend to use has Root Motion enabled. Do this by opening the Animation Asset and enabling EnableRootMotion.



Set up Target Location

The first step is to create and position a target for you to warp to. In this example, a Cylinder is used.

In the Place Actors panel, click All Classes and locate Target Point. Drag and drop it into your level to add a Target Point. Ensure it is aligned and rotated to your desired warp point.



Set up the Animation Montage

Next, create an Animation Montage Asset. An easy way to create one that derives from an existing animation is to right-click on your Animation Asset and select Create > Create AnimMontage. After you have created the montage, open the asset.



With your Montage now open, you can scrub through the sequence to preview your animation. The next step is to add a Motion Warping window under the Notifies track. Do this by right-clicking in the track area and selecting Add Notify State… > Motion Warping.



A Motion Warping window is now created, with handles where you can set the start and end ranges.

Set the range of this Motion Warping Window so that it begins near the start of the animation, and ends at the moment the character strikes. You can also hold down the Shift key as you move your Notify keyframes to preview the current animation at that time.



Next, select the Motion Warping keyframe and navigate to the Details panel. Here you will set some properties for this keyframe.

Set Root Motion Modifier Config to Skew Warp**. This is done to specify the type of warp.

Set a name for Warp Target Name. This is done to identify this warp with a name.



Get Target Location

Now open your Character Blueprint Asset. In the Event Graph, create an Input Action node mapped to your desired input action. Do this by right-clicking in the graph and select your input event from Input > Action Events.

In this example there is an Input Action Event for Punch.



Next you will want to get the location of the Target Point you placed earlier in this example. There are a few ways you could choose to do this, but for this example create a Get All Actors Of Class node. Set the Actor Class to Target Point. Finally, hook the Pressed output pin from the Input Action node into the input execution pin for the Get All Actors of Class function.



Finally, add a Get (a copy) node to connect to the Out Actors array data pin. Also add a Get Actor Location function and connect its input Target data pin to the Get node's output data pin.



Warp Target

Now you create logic for getting your Target Point's location.

To start, add a Motion Warping Component to your Character Blueprint. Do this by clicking (+) Add in the Components panel and locate Motion Warping under the Movement category. Click it to add the component.



Next, drag and drop the Motion Warping component from the Components panel to the Event Graph.



Drag off from the Motion Warping reference pin to add an Add or Update Warp Target from Transform node. Once created, connect its input event pin with the Get All Actors Of Class node. Also, ensure you assign a Warp Target Name to the Name pin. This name must match the Warp Target Name you defined earlier in the Montage.



You also need to link the Add or Update Warp Target from Transform node to the Target location. Right-click on the Warp Target pin and select Split Struct Pin to convert this into a dual Location/Rotation pin structure. Then connect the Get Actor Location's Return Value pin to the Get Actor Location's Return Value pin.

When connecting the Return Value of the Get Actor Location node, (a vector value, indicated by a yellow pin) and the Add or Update Warp Target from Transform node's Target Transform pin, (a transform value, indicated by an orange pin) a conversion node is created. In instances where different value types are present, but are compatible through a conversion, Unreal Engine automatically creates a conversion node when connecting the pins.



Play Montage

Now you can reference your Skeletal Mesh Component in the Event Graph, and play the Montage on it. Drag and drop the Skeletal Mesh Component into your event graph.

Right-click in the graph and select Animation > Montage > Play Montage to add a Play Montage node. Then assign your Montage Asset to the Montage to Play pin.



Results

When you play your level now, you should be able to see your character warp to the appropriate point as they play their punch animation.



Below you can see a full image of the Character Blueprint logic used for this page's implementation of Motion Warping to a simple warp target location.



Overview

Distance Matching Workflow

Curve Generation

Compression

Animation Blueprint

Results

Distance Matching Node Reference

Distance Match to Target

Advance Time By Distance Matching

Set Playrate to Match Speed

With Distance Matching, Animation Sequences can be driven by a calculated distance variable rather than time-based linear playback. This document provides an overview of Distance Matching, and a workflow example demonstrating the implementation process.

Enable the Animation Locomotion Library Plugin. Navigate in the Menu Bar to Edit > Plugins and locate the Animation Locomon Library in the Animation section, or use the Search Bar. Enable the Plugin and restart the editor.



Have an Animation Sequence.

Have a float variable solving for the distance to or from a point.

Distance Matching relies on Animation Blueprint and Animation Node Function, so a foundational knowledge in both is required.

Overview

With Distance Matching, you can drive Animation Sequences with the character's distance to or from a target. An Animation Sequence Curve is used within the Animation Blueprint logic, to graph and select animation keyframes based on the desired pose at specific distance values rather than time displacement.

Below is an example of an Animation Sequence Editor with a curve highlighted in the Timeline.



Double-click the curve to open it in the Curve Editor. In the Curve Editor, you have access to detailed information about the curve and editing tools to tweak or adjust the curve.

The example below shows a Ground Distance curve graphing the animation sequence's poses on the x-axis, and the units of vertical displacement on the y-axis, where y = 0 is the level's ground. In the example curve, triangles representing keyframes are consistently displaced along the curve trajectory (the green line). However, a pose can be selected at any point on a trajectory, not only at the keyframe intersections. Using Distance Matching, the Animation Blueprint searches the Animation Curve to find the indexed value, denoted by the distance variable, and outputs the corresponding Animation Pose.



Below is a manual demonstration of this process. Given a distance value of -100 units from the ground, a pose is located around the 6th keyframe on the curve and selected for playback.



A Distance Matching Node will use an Animation Distance Curve to select an animation pose to adjust the animation sequence playback. With Distance Matching, animation playback speed can be driven to match character movement speed, which reduces the need to fine tune animations and allows for the character's speed to be altered without disrupting animation playback.

Below is a practical implementation of Distance Matching in action, within the Lyra sample project.



Distance Matching Workflow

This workflow example demonstrates a basic implementation of Distance Matching. Using the Sequence Evaluator node to evaluate a landing animation, the Distance Matching logic selects an animation pose based on the remaining distance to the ground from the character's location using an Animation Distance Curve.

Curve Generation

Distance Matching requires an Animation Curve graphing animation poses with the distance to or from a target. This curve can be referenced to adjust the animation playback pose according to a dynamic distance variable.

For example, instead of the 9th keyframe transitioning to the 10th keyframe based on a unit-of-time threshold, the transition occurs based on a unit-of-distance threshold.

This curve can be generated form an Animation Sequence with Root Motion enabled.

To generate a curve, open an Animation Sequence in the Animation Sequence Editor. Navigate to Menu Bar > Windows, and in the Asset Editor section, select Animation Data Modifiers to open the window.



Select Add Modifier and choose the Distance Curve Modifier option from the drop down menu.



In the Distance Curve Modifier Settings, set the parameters for generating the curve.

Below is a list of the Distance Curve Modifier Properties and their functions.

Property

Description

Sample Rate

Determines how many curve samples to generate for the sequence. Higher values increase the samples and the distance curve precision. A value of 30 covers most use cases.

Curve Name

Defines the name of the generated curve.

Stop Speed Threshold

Defines the threshold when the character has stopped moving or reached the animation end point. A value of 0 is the default, but a character doesn't always reach 0 before the animation is finished. This property can be used to tweak the end threshold for smoother transitions.

For example, in a pivot animation, the character changes direction but may never fully stop. Tweak this threshold to specify how slow the character must be to be "stopped".

Axis

Determines what axis / axes of motion to consider. "Z" is useful for land animations. "XY" is useful for locomotion transitions (stop, start, pivot).

Stop at End

If enabled, the curve only declares the character stopped on the last frame of the Animation Sequence. Enable this property if the character is or can be stopped before the last frame of Animation Sequence.

For the demonstration, change the Axis property to the Z axis, since the animation is Distance Matched according to a change in height.

Enable the Stop at End setting.

Name your curve using the Curve Name property, for later reference.



Leave other settings as the default option.

Click Apply All Modifiers at the top of the window to generate the new curve.

Now that you have the Animation Distance Curve, you can move back and forth along the curve using the playhead in the Curve Editor window, to view the Animation Pose output at different distance values from your target. For this demonstration, the character extends their legs to meet the approaching ground.



Compression

Distance Matching an animation sequence requires a Uniform Indexable Animation Compression Setting asset in place of default compression methods, to read the distance curve at runtime.

To apply this compression, create a new Animation Compression Settings Asset. Right-click in the Content Browser and navigate to the Animation dropdown menu under Create Advanced Asset, then select Curve Compression Settings.

Double-click the new Compression Asset to open the Details panel. Under Compression, select Uniform Indexable for the Codec option.



Within the Animation Sequence you are Distance Matching, assign the new Curve Compression Settings asset in the Details panel under Compression.



Animation Blueprint

In the character's Animation Blueprint AnimGraph, create a Sequence Evaluator node and connect it to the Output Pose node.



Open the Sequence Evaluator node's Details panel to define the Animation for Distance Matching.

Next, in the Explicit Time property, open the pin's drop down menu, and toggle the Dynamic Value option in the Pin category. Toggling the Dynamic Value option allows you to set the value using the Anim Node Function. It is safe to hide this pin in the Blueprint.

Disable Should Loop and Teleport to Explicit Time.

Set the Start Position to 0 and Reinitialization Behavior to rely on Explicit Time.



After you define the properties of the Sequence Evaluator node, create an Animation Node Function on the Sequence Evaluator node to drive the logic. To create this internal function, navigate to the Functions section in the Sequence Evaluator node's Details panel. In the On Update property, open the dropdown menu and select +Create Binding.



You can rename the function in the Details panel. In this example, the function is named "Distance Matching".

The function opens in a new tab in the Blueprint Editor Viewport window.

Between the In and Out nodes of the function, create a Distance Match to Target node.



Next, drag off of the Distance Match to Target node's Node output pin and create a Convert to Sequence Evaluator float function (green) node.



Connect the Convert to Sequence Evaluator node's Sequence Evaluator output pin to the Distance Match To Target's Sequence Evaluator input pin.

Call an instance of the Float Variable that calculates the distance from the target. In this example, the variable measures the distance from the character to the ground, and is called Distance to Ground.

On the Distance Match to Target node, define your Distance Curve Name.

Save and Compile the Blueprint and you can now see the results of Distance Matching in the Animation Preview Viewport.

Results

While running the animation, in the Scene Setup section of the Viewport Settings, you can adjust the Floor Height Offset property to show Distance Matching in action. With Distance Matching enabled and implemented the Sequence Evaluator node selects the animation poses from the curve as you alter the distance between the character and the ground. This creates a more natural landing animation, where the character dynamically reacts to the approaching ground. With distance matching, the animation sequences can also adjust to changes in the character's falling speed, without the need to reanimate the sequence to match an adjusted fall rate.



Below is the full Anim Node function Blueprint used in the example workflow to implement Distance Matching within the Sequence Evaluator node.



Distance Matching Node Reference

Below is a list of the Distance Matching nodes that operate in Anim Node Functions.

Distance Match to Target

The Distance Match To Target node uses an Animation Curve and a distance variable to select animation poses, to scale the animation playback speed to match character speed.



Under the Animation Blueprint section of the workflow demonstration, there is an implementation of the Distance Match To Target node in an Anim Node Function.

Advance Time By Distance Matching

The Advance Time By Distance Matching node advances a connected Sequence Evaluator node forward by the distance the character travels each frame.



This node requires an Animation Distance Curve graphing the distance traveled by the Root Bone to select animation poses from, and a variable measuring the distance traveled.

Set Playrate to Match Speed

The Set Playrate to Match Speed node sets the play rate of an Animation Sequence Player node so that the speed of the animation matches the character's movement speed, assuming the character has consistent movement speed.



Animation Sequences

Animation Montage

Creating a Composite

Editing a Composite

Using Composites

Anim Asset Details

With Animation Composites (Composites) you can combine several Animation Sequences into a single asset that can be played back as one sequence. However, be aware that a Composite only stitches animation sequences for combining playback and does not provide any additional ability, such as blending. For a more advanced asset type that can be used to combine sequences and add additional functionality, please refer to Animation Montages for more information.



Like Animation Sequences, Animation Composites can also have Notifies and Curves.

Creating a Composite

You can create a new Composite inside the Content Browser by Right-Clicking (or selecting the Add New Button) and choosing Animation > Animation Composite from the context menu.



After creating the new Composite, you will need to specify the Skeleton asset with which to associate your new Animation Composite.

You can also create a Composite from an existing Animation Sequence by Right-Clicking the Sequence in the Content Browser and selecting Create > Create AnimComposite.

When creating a Composite from an Animation Sequence any present Notifies or Curves will not be copied by default. You can manually copy these assets by selecting them and using the hotkey CTRL + C and selecting the Notifies track in the new Composite asset and using the hotkey CTRL + V.



The Composite will now be accessible and indicated by a lighter shade of green to distinguish it from Animation Sequences.

Editing a Composite

Double-clicking a Composite will open Animation Sequence Editor and populate the editor with relevant properties and features.

In the Timeline, you can add Sequences from the Asset Browser, to the Composite track.



You can edit the order of the Sequences in the Composite by dragging them to the desired order. Sequences will snap into place either before or after another Sequence.

You can remove a Sequence by selecting one, Right-Clicking and choosing Delete Segment. You can also open the asset in its respective asset editor by selecting Open Asset.

Using Composites

Once assembled, an Animation Composite is used in the same way as an Animation Sequence in the AnimGraph of an Animation Blueprint.



You can also add an Animation Composite to another Animation Composite or to an Animation Montage in the same fashion as a singular Animation Sequence using the Asset Browser.

Anim Asset Details

When opening your Animation Composite in the Animation Sequence Editor, there are a few unique properties that can be accessed from the Asset Details panel. Here you can see a reference of these properties for Animation Composites in the Animation Sequence Editor.



Property

Description

Preview Base Pose

Here you can assign and reference the base pose for an Additive BlendSpace. For more information about Blend Spaces please see Blend Spaces.

Sequence Length

Length (in seconds) of the selected AnimSequence playback, assuming a playback speed factor of 1.0.

Creating a Pose Asset

Animation Blueprints

Animation Curves

Curve Driven Animation

Creating Pose Asset

Additive Pose Assets

Using Pose Assets

Pose Blender

In Unreal Engine, animation Pose assets are stored skeletal mesh poses that you can use in your project, as an animation target or reference point.



Pose assets save the position of the mesh geometry as well as the skeleton data. Pose assets can contain a single static pose, or many poses, saved as animation curves within the asset.

Creating Pose Asset

There are many ways to create an animation Pose asset.

While working in the Skeleton Editor, skeletal mesh editor, or the animation sequence editor, you can create a pose asset, using the create asset button in the animation editor Toolbar to save the current skeletal mesh position as an animation Pose asset.



You can also create an animation Pose asset from an entire animation sequence by right-clicking the asset in the Content Browser and selecting Create > Create PoseAsset from the context menu.



After selecting Create PoseAsset, the Create Pose Asset window will open, where you can select which animation sequence you wish to create an animation pose asset from.



When generating a Pose asset from an entire animation sequence, Unreal Engine will create a pose for each frame of animation. The generated poses will then be accessible using animation curves present in the Pose Asset.

You can sequentially input any desired names for the generated pose curves by typing a name on a new line for each curve or frame of animation, in the [OPTIONAL] Pose Names field.



Additive Pose Assets

After creating and opening a Pose Asset, you can modify a pose asset, to behave as additive by toggling the Additive property and selecting the Convert to Additive Pose button in the pose asset's Asset Details Panel.



Additive pose assets are able to play in an additive capacity, in conjunction with other animation data, such as animation sequences, without overriding the entire pose.

Using Pose Assets

Pose assets can be used in many ways to animate characters.

Pose Blender

You can use the Pose Blender and Pose Driver animation blueprint nodes, to control the playback and blending of animation Pose assets to animate characters at runtime.



How to playback Pose Asset curves using the Pose Blender and Pose by Name Animation Blueprint nodes.

How to playback Pose Asset curves using the Pose Blender and Pose by Name Animation Blueprint nodes.



Describes how to use the Pose Driver to drive Pose Asset or Curve values based on a bone's movement.

Describes how to use the Pose Driver to drive Pose Asset or Curve values based on a bone's movement.

Animation Pose Assets

Creating a Pose Asset



Animation Curves

Animation Blueprints

Skeletal Controls

Pose Blender

Pose by Name

After creating an Animation Pose Asset, you can use the Pose Blender and Pose by Name animation blueprint nodes to animate characters with pose assets.

Pose Blender

Pose Blender nodes are Animation Blueprint nodes that are automatically created by dragging a pose asset into the AnimGraph.



Pose Blender nodes are used to play the associated pose asset on the skeletal mesh at runtime.

Pose Blender nodes will not display an output pose without any method of driving the contained animation curves. You will need to use an Animation Blueprint node to drive the curve data of the pose node to generate an output pose.



Here is an example of an animation sequence, that contains authored animation curves, driving the pose assets curves, to animate the face.





Animation Sequence Curves

Pose Asset playback using animation sequence curves and Pose Blender node

While nodes like the animation sequence players, can be used to drive animation curves found within the pose asset, you can also drive these curves with an curve asset. You can set a custom curve, to drive the pose asset, in the Custom Curve property, in the Pose Blender node's Details panel.



Pose by Name

When working with a pose asset that contains multiple skeletal mesh poses, stored as unique animation curves, you can use the Pose by Name Animation Blueprint node to selectively playback poses by using their name.



To create a Pose by Name node, you must right click a Pose Blender node in the AnimGraph and select, Create Pose by Name Node from the context menu.



Here a Pose by Name node is outputting a single pose from within a pose asset that was generated using a run animation, with each frame of animation having its own animation curve assigned, Frame 25 being the desired pose's name.



When using the Pose by Name node, you can control the weight of the specified pose using the Alpha Property. Here a simple wave value is adjusting the alpha value to drive the weight of the pose.





Animation Blueprint

Result

If you are using a Pose Asset that has been enabled as Additive, you will need to use the Apply Additive node to correctly display your desired pose.



Creating a Pose Asset

Animation Curves

Animation Blueprints

Skeletal Controls

Pose Targets

You can use the Pose Driver Animation Blueprint node to drive Pose Assets using animation curve values to animate characters.



While the Pose Blender and Pose by Name Animation Blueprint nodes are used to blend Pose Assets with existing animation poses, the Pose Driver node is used to drive the contained poses within a Pose Assets to animate characters.

With the Pose Driver node, you can use bone motion to drive the Pose Asset playback at runtime.





Viewport

Graph

By selecting a Pose Asset, setting Pose Targets and a Source Bone, you can control the behavior of how the Pose Asset is driven using the source bone motion data.

When reselecting a Pose Driver node's pose asset, and importing a new set of poses using the Tool property, you must create a new Pose Driver node.

Pose Targets

By assigning targets in the Pose Targets property, you can specify skeletal mesh poses from a Pose Asset or Animation Curves you want to target using the Pose Driver node. Pose targets can be manually entered or automatically assigned using the poses contained within a Pose Asset.

To import a Pose Asset's contained poses as Pose Targets, first, in the Pose Driver's Details panel, assign select a Pose Asset in the Pose Asset property.



Once a Pose Asset has been assigned, select the Copy Poses from Pose Asset option form the Tool property's context menu.



The imported Pose Targets are now controllable using the Pose Driver node.

Pose Target Property Reference



The following properties control the behaviors of all of the Pose Driver node's Post Targets. Here you can reference a list of the Pose Target properties.

Property

Description

Solo Driven Pose / Curve Only

Here you can toggle if the Pose Target is representative of an entire pose or just an Animation Curve. When enabled the property will only interpet curve data and leave the source joint(s) in place. When Disabled, all pose data will be used.

Tools

When the Pose Driver node has a pose asset set in the Pose Asset property, you can select the following options to dictate the behavior of the poses or curves driven by the Pose Driver. From the drop down menu you can select from the following options:

Copy All from PoseAsset: Create and set all Pose Targets from the associated animation poses from the set Pose Asset. When selected, this option will overwrite any existing pose targets. Auto Scale: Automatically set all Scale factors, based on distance to the nearest neighbor pose target.

Add Target

You can add a pose target with the (+) Add Target button.



The following properties can be adjusted for each individual Pose Target registered within the Pose Driver node. Here you can reference a list of the pose target properties.

Property

Description

Solo

Clicking and holding the solo button will preview the pose target in the viewport. You can also Double-click the solo pose to lock the Pose Target pose preview. You can double-click on a locked pose's solo button to unlock its preview.

Remove Target

You can remove a target by selecting the Remove Target button, adjacent to the specific Pose Target you wish to remove.

Scale

Here you can set the Pose Target's curve or pose scale. A value of 1 will result in the full curve or pose value being used as the Pose Target.

Drive

Here you can select which pose from the set Pose Asset to drive using the Pose Target.

Hidden

When enable this property will hide this Pose Target from debug drawing.

Override

Here you can set an override the pose targets blending method and function. In the first field you can set the Blending Method form the following options:

Euclidian

Quaternion

Swing Angle

Twist Angle

Default Method

In second field you can select an override blending function from the following options:

Gaussin

Exponential

Linear

Cubic

Quintic

Default Function

Curve

Enable this property when the Pose Target is an Animation Curve rather than an animation pose. When using animation poses as pose targets, disable this property.

X, Y and Z

Here you can reference and adjust the X, Y, and Z values of the Pose Target location. Which, by default, can be seen in the Viewport as a green object. If all values are set to Zero, the motion of the pose target will be isolated to the Source Bone and its Children.

Curve-Based Pose Targets

Pose Targets can also be driven by Animation Curves instead of using a Pose Asset. In the Details panel of a Pose Driver node, set the Drive Output property to Drive Curves.



In the Pose Target section, enable the Solo Driven Pose / Curve Only and for each curve Pose Target, enable the **Curve*. After enabling the Curve property you can now edit the curve graph within the property window.



Property Reference



Here you can reference a list of the Pose Driver node's properties.

Property

Description

Source Bones

Select a bone from the character's skeleton to use as a Source Bone to apply the driven animation pose parameters based on orientation. Many source bones can be added, but at least one is required. Add (+) Indexes, to define source bones to drive the pose orientation from.

Eval Space Bone

Here, you can select optional bones from the character's skeleton to evaluate the Source Bone's transform. If not specified, the local space of Source Bone is used.

Eval from Ref Pose

When enabled, the Source Bone orientation and transform will be evaluated relative to its Reference Pose position. This is recommended when using Swing and Twist Angle as Distance Method, since the twist will be computed from the character's Reference Pose. When disabled, the local space of Source Bone will be used.

When Eval Space Bone is set, Eval from Ref Pose will be ignored.

Only Drive Selected Bones

When enabled, all bones that are not set in the Only Drive Bones property will be filtered out.

Only Drive Bones

Here you can add and select bones from the character's skeleton, to be exclusively used when the Only Drive Selected Bones property is enabled.

Solver Type

Here you can specify which type of blending solver to use. Typically, the Additive solver requires normalization, and the Interpolation solver does not. The Interpolative solver also has smoother blending, whereas the Additive solver requires more targets but has a more precise control over the influence of each target.

Additive: The additive solver sums up contributions from each target. It's faster but may require more targets for a good coverage, and requires the normalization step to be performed for smooth results.

Interpolative: The interpolative solver interpolates the values from each target based on distance. As long as the input values are within the area bounded by the targets, the interpolation is well-behaved and return weight values within the 0% - 100% limit with no normalization required. Interpolation also gives smoother results, with fewer targets, than additive but at a higher computational cost.

Radius

Here you can set the default radius for each target.

Automatic Radius

When enabled, the node will automatically pick the radius based on the average distance between targets.

Function

Here you can set the blending function to use. The options available are:

Gaussin

Exponential

Linear

Cubic

Quintic

Default Function

Distance Method

Here you can set the blending method to use. The options available are:

Euclidian

Quaternion

Swing Angle

Twist Angle

Default Method

Twist Axis

Axis to use when the Distance Method is set to Swing Angle. You can set the values of the axis limits on the X, Y, or Z axes.

Weight Threshold

Here you can set the weight, below which should be ignored, in the contribution from the target.

Normalize Method

Here you can set the method to use for normalizing the weight. The options include:

Only Normalize Above One: When values exceed 1, values will be normalized.

Always Normalize: Zero distribution weights stay zero.

Normalize Within Median: Normalize only within the Median Reference property values. The median is a cone with a minimum and maximum angle within which the value will be interpolated between non-normalized and normalized. This helps to define the volume in which normalization is always required.

No Normalization: Don't normalize at all. This should only be used with the interpolation method, if it is known that all input values will be within the area bounded by the targets.

Median Reference

When enabled, you can set the rotation or position of median limits used for normalization, when the Normalize Method is set to Normalize Within Median.

Median Min

Here you can set the minimum distance used for the median normalization method.

Median Max

Here you can set the maximum distance used for the median normalization method.

Drive Source

Here you can select which part of the transform is read, the Rotation or Translation, to apply the alpha to drive Pose Targets.

Drive Output

Here you can select if the Pose Targets are animation poses from a Pose Asset or animation curves to drive. You can select:

Drive Poses: Use target DriveName to drive poses from the assigned PoseAsset.

Drive Curves: Use the target's DriveName to drive curves.

Pose Asset

Here you can select a *Pose Asset** from your project to drive.

Debug Settings



Here you can reference a list of the Pose Driver node's debug settings.

Property

Description

Axis Length

Length of axis in world unity used for debug drawing.

Cone Subdivision

Number of subdivisions / lines used when debug drawing a cone.

Draw Debug Cones

When enabled, the cones will be drawn in 3d for debugging.

Skeletal Meshes

Static Meshes

Morph Target Previewer

Cloth Simulation

How to use the Machine Learning Deformer

How to Create a Custom Deformer Graph

How to Use the Deformer Graph

Creating a Deformer Graph Asset

Opening The Deformer Graph

Palette Component Reference

Using Unreal Engine's Deformer Graph plugin, you can create and edit Deformer Graph assets to perform and customize mesh deformations for any skinned mesh in Unreal Engine. Using Deformation Graphs, you can create and modify logic that adjusts the geometry of the mesh to fine tune mesh deformation behaviors, or create entirely new deformations within Unreal Engine. Most often Deformer Graphs are used to fine-tune realistic skin and fabric behaviors in motion for characters, or for one-off animations that are easier to create using deformation logic than hand-authored animations.



Mesh Deformers come in many forms, such as Morph Targets, Cloth simulation, and even generated models created in external DCC (Digital Content Creation) software such as the Machine Learning (ML) Deformer.

This document provides an overview of the Deformer Graph system in Unreal Engine.

How to Use the Deformer Graph

Here you can read about how to set up and begin using the Deformer Graph in Unreal Engine.

Enable the Deformer Graph plugin. Navigate in the Menu Bar to Edit > Plugins and locate the Deformer Graph in the Animation section, or using the Search Bar. Enable the plugin and restart the editor.



Your project contains a skinned mesh, which could be a Skeletal Mesh character, or a Static Mesh object.

Creating a Deformer Graph Asset

Create a Deformer Graph asset by right-clicking in the Content Browser and navigating to Animation > Deformers > Deformer Graph.



With a Mesh selected in the Viewport, you can also navigate in the Details panel to the Mesh Deformer property, and after enabling the Mesh Deformer property, you can create a new Deformer Graph by selecting the Deformer Graph option from the selection menu.



The following default Deformer Graph Assets are packaged alongside the Deformer Graph Plugin and are available for you to use or customize when creating custom mesh deformer logic for your characters and objects. These Deformer Graphs can be accessed in the Content Browser by navigating to Engine > PlugIns > Deformer Graph Content > Deformers.



Asset

Description

DG_LinearBlendSkin

This graph applies the standard linear blend skinning pipeline. All skinning features are supported using this graph.

DG_LinearBlendSkin_Morph

This graph applies the standard linear blend skinning and Morph Target pipelines. All features of those pipelines are supported using this graph.

DG_LinearBlendSkin_Morph_Cloth

This graph applies the standard linear blend skinning, Morph Target and Cloth simulation pipelines. All features of those pipelines are supported using this graph. This is a superset of the DG_LinearBlendSkin and DG_LinearBlendSkin_Morph Deformer Graph, and can be used instead of those without any performance penalty. The simpler Deformer Graph assets, DG_LinearBlendSkin and DG_LinearBlendSkin_Morph, exist individually as reference for those who want to build their own implementations.

DG_LinearBlendSkin_Morph_Cloth_RecomputeNormals

This graph applies the standard linear blend skinning, Morph Target, and Cloth simulation pipelines. It also applies additional passes to recompute vertex normals. This emulates the existing behavior of the GPU Skin Cache with Recompute Tangents settings.

If you do not see the Engine folder, or the default Deformer Graphs as available options when selecting a Deformer Graph in a mesh's Details panel, ensure you have Plugin Content enabled in the View Settings of the Content Browser.



For more information about creating and using Deformer Graph assets, refer to the How to create a custom Deformer Graph guide.

Opening The Deformer Graph

After enabling the Deformer Graph Plugin, you can open the Deformer Graph Editor by double-clicking any Deformer Graph Asset in the Content Browser or in a game objects Details panel, in the Mesh Deformer property.



Deformer Graph Interface

Here is a reference for the Deformer Graph interface you can use when creating and editing custom Deformer Graph assets, to deform meshes in Unreal Engine.



Interface

Description

Compile

Compiles the Deformer Graph.

Viewport

See the effect of the Deformer Graph logic on the mesh.

Palette

A toolbox of unique Deformer Graph Blueprint nodes.

Explorer

Add and manage Deformer Graph Subgraphs, Component Bindings, Variables, and resources.

Graph Editor

Similar to other Blueprint Editors, manage and edit Deformer Graph logic using a series of unique Deformer Graph nodes.

Compile Output

Review compiler logs and information, after successful and unsuccessful compiles of the Deformer Graph.

Details

Access component and node specific information and properties.

Shader Text Editor

A text editor used to modify Custom Compute Kernel node programming using HLSL (High-Level Shader Language).

Palette Panel

Using the Deformer Graph Palette, you can drag and drop custom Deformer Graph nodes and Kernels to reference or use when creating mesh deformation logic.



For a comprehensive list and description of the available components in the Palette panel, refer to the Palette Component Reference list at the bottom of this document.

Deformer Graph Subgraphs

There are 3 types of Subgraphs you can use within a Deformer Graph.



By default, a Deformer Graph only contains an Update Graph which is executed once per frame.

You can optionally add a SetUp Graph that executes when the owning object is initialized.

Additionally, you can create and use Trigger Graphs, which can be executed by request from a Blueprint or C++ code. When Trigger Graphs are requested, they are queued and executed after an initial Setup Graph, if one is present, and before the Update Graph every frame.

You can add a Subgraph to the Deformer Graph by clicking Add (+), adjacent to the Graphs section of the Explorer panel, or by clicking the green (+) Add New button at the top of the Explorer panel. After clicking either, you can then choose to create either a Setup Graph or a Trigger Graph from the drop down menu.



No additional Update Graphs, and only one Setup Graph, can be added to a Deformer Graph. You can add as many Trigger Graphs as your project needs. Trigger Graphs can then be renamed, by double-clicking the name of the desired Trigger Graph in the Explorer panel or by selecting the Trigger Graph and pressing the F2 key.

Component Bindings

Component Bindings are references to available components contained in the owning object.



You can create additional component bindings to the Deformer Graph by clicking Add (+), adjacent to the Component Bindings section of the Explorer panel, or by clicking the green (+) Add New button at the top of the Explorer panel.



The following are some examples of Component Bindings that you can use when creating Deformer Graph logic:

Component Binding

Descriptions

Skeletal Mesh Component

Add a reference to the owning object's Skeletal Mesh component. Using the Skeletal Mesh, many properties and components can be referenced, such as the Mesh Vertices and Triangles, and Scene Time.

Scene Component

A Scene component draws data and information from the scene the character or subject the Deformer Graph is occupying. Game time and other useful information can be drawn from scene components.

Scene information can also be gathered from a Skeletal Mesh or Skinned Mesh component binding, but there may be a context where using a separate Scene component binding is useful for control or organizational purposes.

Skinned Mesh Component

A Skinned Mesh component can be representative of any kind of skinned mesh. This can be an auxiliary object attached to the character, or this can represent a character or object without bones.

Variables

In the Variables section of the Explorer Tab you can create and manage externally visible variables you can reference to adjust and control logic in the Deformer Graph.



You can create a variable by clicking Add (+), adjacent to the Variables section of the Explorer panel, or by clicking the green (+) Add New button at the top of the Explorer panel.



After creating a new variable, you can open its properties in the Details panel, by selecting the variable in the Explorer panel.



In the Details panel, you can name the variable using the Variable Name property, and define its Data Type. Variables can be assigned any data type, or component, for use with the other Deformer Graph nodes.

Resources

Similar to Variables, you can create and manage Shader Resources in the Resources section of the Explorer panel. Resources are internal references to values and components that other nodes in the Deformer Graph can reference to perform mesh deformation functions.



You can create a resource by clicking Add (+), adjacent to the Resources section of the Explorer panel, or by clicking the green (+) Add New button at the top of the Explorer panel.



After creating a resource, you can select it in the Explorer tab to open its properties in the Details panel.



You can adjust the following resource parameters:

Property

Description

Resource Name

Name the resource in the provided field.

Data Type

Set the type of data the resource can store.

Component Binding

Set the component binding the resource is bound to.

Data Domain

Set the data domain for the resource.

In the first drop down menu you can select the dimension. You can select from the following dimensions:

Triangle: Select all triangles.

Vertex: Select all vertices.

Vertex > Bone: Select groups of vertices by bone.

Vertex > Index0: Select groups of vertices within Index 0.

Vertex > UVChannel: Select groups of Vertices by UVChannel.

Expression…: Input a custom data type using the provided field.

When the dimension is set to Triangle or Vertex, you can additionally specify how many data values should be stored per entry. Beginning at x1, for one data point per entry, you can also select from x3, x4, or x8.

Data points must match, not only in their dimension but also in the amount of data values present for each entry. If you are experiencing input/output pin incompatibility, or unresponsive resources in the Defromer Graph logic, ensure your Data Domain properties are set to compatible values.

Unlike variables, you can set, as well reference resource values and components within the Deformer Graph. After creating a resource, you can drag-and-drop the resource into the Deformer Graph Editor, and choose from a Get instance, used for referencing the existing value contained in the resource, a Set instance, used for setting or defining the resource for use later, or a Get/Set instance, that can be used to both set and reference the stored value.



After creating a Get/Set Resource, Get Resource, or Set Resource node, you can modify how the instance of the resource interacts with the resource buffer. You can define this behavior by selecting the node in the Graph and setting the Write Type property in the node's Details panel.



You can choose from the following write type property options:

Option

Description

Write

Writes the value to the resource buffer.

Write Atomic Add

Overwrites the graph value to the value in the resource buffer.

Write Atomic Min

Overwrites the graph Min value to the value in the resource buffer.

Write Atomic Max

Overwrites the graph Max value to the value in the resource buffer.

Details Panel

The Deformer Graph Details panel shows information and settings regarding each Deformer Graph node. To see a node's properties, select the node in the Graph Editor, and the Details Panel shows its properties.



When selecting Kernel Nodes, Input and Output bindings can be added and modified.

To achieve functional results, Input and Output bindings must match the exact data type they are connected to. Please ensure any Kernel Input or Output binding is set to match the desired connected or extracted value.

Shader Text Editor

Using the Shader Text Editor, you can program Custom Compute Kernel nodesto control specific mesh deformation behaviors.



The Shader Text Editor operates in HLSL (High-Level Shader Language) to program kernels.

For each Custom Compute Kernel added to a Deformer Graph, a new tab opens within the Shader Text Editor panel.



Within each Custom Compute Kernel tab, you can access the node's Declarations, which are read-only, and represent the Graph Editor modification made to the node, such as added Input and Output bindings.



You can also access the node's Shader Text where you can write custom HLSL code to create mesh deformations.



For more information about the HLSL coding standard, refer to the Microsoft High Level Shader Language reference documentation and programming guide.

For an example workflow of using the Shader Text Editor, refer to the How to Create a Deformer Graph guide.

Palette Component Reference

Here you can reference a list of the available components found in the Deformer Graph Palette and a description of their function.



Palette Component

Node

Description

Animation Attributes



Add references to Animation Attributes that you can use to trigger or activate Deformer logic.

Cloth



Add and attach references to Cloth simulation models associated with the skeletal mesh. Refer to Cloth Simulation Models for more information.

Connectivity



Connect Skinned Mesh components to an existing vertex or vertice data set.

Debug Draw



Uses a connected Skinned Mesh component binding to draw a debug view of the mesh in the Viewport. Debug data is extracted as a string and is accessible using the nodes output pin in the Graph.

Options in the Details panel include:

Force Enable: Forces the debug draw to occur in the Viewport.

Max Line count: Set the maximum amount of lines between vertices the debug drawing can display.

Max triangle Count: Set the maximum amount of geometry triangles the debug drawing can display.

Max Character Count: Set the maximum number of characters the debug drawing can display.

Font Size: Set the font size for the debug drawing overlay.

Morph Target



Using a Skinned Mesh component, the Morph Target node can isolate the Delta Position and Delta Normal as Vector 3** values.

Scene Data



Extract scene data you can use to control or trigger Deformer Graph logic. A Scene component binding can be created, but you can also use a Skeletal Mesh component binding to reference the current scene the skeletal mesh occupies at runtime.

Skeleton



Extract Skeleton data from a Skeletal Mesh component binding. The available outputs include:

Num Bones: Output value is a UInt and represents the number of bones in the skinned mesh's skeleton.

Bone Matrix: Output value is a 3x4 matrix of bone positions.

Bone Weight: Output value is the alpha weight of bones, in the form of a float.

Weighted Bone Matrix: Output value is a 3x4 matrix of weighted bone positions.

Skinned Mesh



Extract mesh data from any Skinned Mesh component binding. The available outputs include:

Num Vertices: Output the number of vertices contained in the mesh as an integer.

Position: Output the position of the Vertices in a Vector 3.

Tangent X: Output the tangent on the X axis as a Vector 2.

Tangent Z: Output the tangent on the Z axis as a Vector 2.

Num UV Channels: Output the number of UVChannels the mesh possesses as an integer.

UV: Output the mesh vertices by a set UVChannel as a Vector 2 value.

Color: Output the R, G, B, and W values of the meshes color as a Vector 4.

Num Triangles: Output the number of triangles that comprise the mesh's geometry as an integer.

Index Buffer: Output and isolate the mesh's index buffer coordinates from its mesh vertice coordinates, as an array.

Custom Compute Kernel



Create a Custom Compute Kernel that can be programmed using HLSL (High-Level Shader Language), to perform custom mesh deformations. For more information on creating and using Custom Compute Kernels, refer to the How to Create a Custom Deformer Graph documentation.

Execute Skinned Mesh



Using a Skinned Mesh component as an input, you can execute mesh data threads for use in a Kernel. In the Details panel you can set the Domain of the function to either run the Kernel with one thread per vertex, or one thread per triangle.

The Execute Skinned Mesh node outputs an IntVector 3 value that can be connected and used with a Custom Compute Kernel. To isolate the output data on only the X, Y, or Z axis, expand the output pin using the triangle next to the output pin. Each axis has a separate Integer output pin.

Write Skinned Mesh



The Write Skinned Mesh output node is the final operation of a Deformer Graph, writing any modifications performed to the mesh's vertices or triangles**.

The Skinned Mesh input pin connects to the initial mesh component binding. Then, using the Vector 3 Position input pin, and the Vector 4 Tangent X, Tangent Z, and Color input pins, the new mesh properties can be written to the mesh.

Bool Constant



Set a constant boolean value. The node can accept a bool variable value, or you can manually toggle the boolean in the graph or in the node's Details panel using the Value property.

Component Constant



Set a component constant, using a component binding. A component constant can be set in the graph, or manually defined using the Value property in the node's Details panel.

Float Constant



Set a constant float value. The node can accept a float value from another component, or you can manually set a value in the graph or in the node's Details panel.

Int Constant



Set a constant signed integer value. The node can accept zero and positive integer values from another component, or you can manually set a value in the graph or in the node's Details panel.

UInt Constant



Set a constant unsigned integer value. The node can accept any integer value from another component, or you can manually set a value in the graph or in the node's Details panel.

Double Constant



Set a constant double value. The node can accept any double value from another component, or you can manually set a value in the graph or in the node's Details panel.

Int Vector 2 Constant



Set a constant Vector 2 value on the X and Y axes. The node can accept any vector 2 value from another component, or you can manually set X and Y integer values in the graph by expanding the input pin using the triangle or in the node's Details panel. Using the triangle near the output pin you can also split the vector 2 value into Integer values for the X and Y.

Int Vector 3 Constant



Set a constant Vector 3 value on the X, Y, and Z axes. The node can accept any Vector 3 value from another component, or you can manually set X, Y, and Z integer values in the graph by expanding the input pin using the triangle or in the node's Details panel. Using the triangle near the output pin you can also split the Vector 3 value into Integer values for the X, Y, and Z** values.

Int Vector 4 Constant



Set a constant Vector 4 value on the X, Y, Z, and W axes. The node can accept any Vector 4 value from another component, or you can manually set X, Y, Z, and W integer values in the graph by expanding the input pin using the triangle or in the node's Details panel. Using the triangle near the output pin you can also split the Vector 4 value into Integer values for the X, Y, Z, and W values.

Linear Color Constant



Set a constant Color value for the R, G, B, and A values stored as a float 4 value. The node can accept any float 4 or Color value from another component, or you can manually set R, G, B, and A float values in the graph by expanding the input pin using the triangle or in the node's Details panel. Using the triangle near the output pin you can also split the Color value into float values for the individual R, G, B, and A values.

Quat Constant



Set a constant Quat or float 4 value on the X, Y, Z, and W axes. The node can accept any Quat or float 4 value from another component, or you can manually set X, Y, Z, and W float values in the graph by expanding the input pin using the triangle or in the node's Details panel. Using the triangle near the output pin you can also split the Quat value into separate float values for the individual X, Y, Z, and W values..

Rotator Constant



Set a constant Rotator or float 3 value on the X (Pitch), Y (Yaw), and Z (Roll) axes. The node can accept any Rotator or float 3 value from another component, or you can manually set Pitch, Yaw, and Roll values in the graph by expanding the input pin using the triangle or in the node's Details panel. Using the triangle near the output pin you can also split the Rotator value into float values for the Pitch, Yaw, and Roll.

Transform Constant



Set a constant Transform value. The node can accept any transform value from another component, or you can manually set the Location, Rotation, and Scale values on the X, Y, and Z axes in the node's Details panel.

Vector 2 Constant



Set a constant Vector 2 value on the X, Y, and Z axes. The node can accept any Vector 2 value from another component, or you can manually set X, Y, and Z float values in the graph by expanding the input pin using the triangle or in the node's Details panel. Using the triangle near the output pin you can also split the Vector 2 value into float values for the X, Y, and Z axes.

Vector 3 Constant



Set a constant Vector 3 value on the X, Y, and Z axes. The node can accept any Vector 3 value from another component, or you can manually set X, Y, and Z float values in the graph by expanding the input pin using the triangle or in the node's Details panel. Using the triangle near the output pin you can also split the Vector 3 value into float values for the X, Y, and Z axes.

Vector 4 Constant



Set a constant Vector 4 value on the X, Y, Z, and W axes. The node can accept any Vector 4 value from another component, or you can manually set X, Y, Z, and W float values in the graph by expanding the input pin using the triangle or in the node's Details panel. Using the triangle near the output pin you can also split the Vector 4 value into float values for the X, Y, Z, and W axes.

Creating an Anim Modifier

Implementing an Anim Modifier

Animation Blueprint Library Reference

Animation Modifiers (Anim Modifier) are a type of native or Blueprint Class that enable users to apply a sequence of actions to an Animation Sequence or Skeleton asset. An example of this includes (but is not limited to) creating automatic foot sync markers by pin-pointing on which frames the right or left foot is place on the ground. Using this information, Animation Sync Markers can be added to frames where a foot bone is at its lowest point (or touching the floor).

Above an Anim Modifier is used to generate auto foot sync markers.

Accessing and applying Anim Modifiers is performed in either the Animation Editor or Skeleton Editor under the Animation Data tab. When applying an Anim Modifier to a Skeleton, the modifier is applied to all Animation Sequences that are based on the Skeleton. When applying the modifier to an Animation Sequence, it is only applied to the sequence itself and no other sequences.

Creating an Anim Modifier

To get started, you will need to create an Anim Modifier Blueprint class:

In your project's Content Browser, click the Add New button and select Blueprint Class.



In the Pick Parent Class window, expand All Classes and search for and select Animation Modifier, click Select then give it a name.



Double-click the new Animation Modifier Blueprint to open it up in the Blueprint Editor.



With your Anim Modifier created, you can now use Blueprint Script and functions contained with the Animation Blueprint Library to access and manipulate animation data.

Animation Blueprint Library

Right-click in the graph of the Anim Modifier Blueprint to see the context menu and list of functions available, particularly under the Animation Blueprint Library.



In the image above, functions related to Marker Syncing are expanded which enable you to synchronize animations using marker data.

Before working with the various functions available for accessing data, you will want to implement the OnApply and OnRevert events. The OnApply Event enables the user to change, add or remove data from the animation while the OnRevert enables the user to remove previously applied user changes (or return the sequence to its original state). Each event returns the Animation Sequence in which to feed the Animation Blueprint Library operations.



In the image above, when the Anim Modifier is applied, a new Notify track is created with the defined name while reverting the Anim Modifier, the track is removed.

Implementing an Anim Modifier

Implementing an Anim Modifier can be done inside a Skeleton asset (to add to the Anim Modifier to all animations associated with the Skeleton) or in a single Animation Sequence.

Inside the Skeleton Editor or Animation Editor, go to Window menu option and select Animation Data Modifiers.



In the Animation Data Modifiers tab, select Add Modifier and select your desired Anim Modifier Blueprint.



Right-click on your Anim Modifier Blueprint then click Apply Modifier to apply the Anim Modifier and any changes (or Revert Modifier to remove changes).



Your Anim Modifier will be listed as Out of Date until you apply it.

Below is an example of an Anim Modifier that has been applied to a Skeleton asset, indicated by the Skeleton icon.



Any properties that you have set as Instance Editable will be available to edit in the Animation Data Modifiers tab.



In the image above, we define properties that can be used to drive automatic foot syncing.

Exposing Properties

Inside your Anim Modifier Blueprint, you will want to expose parameters using Instance Editable that you can manipulate within the Animation Tab in the Animation Tools



In the image above, we use a structure variable containing information that we can set for the name of a bone as well as provide an offset.

Inside our Animation Sequence when we implement our Anim Modifier and apply it, we can see our exposed parameters.



In the image above, we enter the names of the bones that we want to include in our Anim Modifier in which to gather animation data (such as Bone Transform) from.

Animation Blueprint Library Reference

While there are several different nodes available within the Animation Blueprint Library, this section lists some of the more commonly used types within Anim Modifiers.

Add/Remove Notify and Curve Tracks



These nodes enable you to dynamically add Notify or Curve Tracks to the specified Animation Sequence. Once Notify or Curve Tracks have been added, you can add various types of keys or events to those tracks. For example, you may want to Add Float Curve Keys to a Curve Track, Add Animation Notify Events or Add Animation Sync Markers to a Notify Track.



Get Bone Pose



To get Bone Transform data you can use the Get Bone Pose for Frame or Get Bone Pose for Time nodes which will return the Bone Transform for the provided Animation Sequence with the specified Bone Name. Alternatively, you can use the Get Bone Poses for Frame or Get Bone Poses for Time to collect Bone Transforms for a specified array of Bone Names.

When getting Bone Transforms the transform data will be in local space. If you need it to be in component space, you will need to manually convert the transforms.

Helper Nodes



The Animation Blueprint Library nodes include several helper nodes including nodes for converting frame and time information (Get Time at Frame or Get Frame at Time). Another node that is useful for getting information is the Find Bone Path to Root which will take an Animation Sequence and a Bone Name (typically the Root Bone) and output a list of Bone Names in a chain.

Mirror Data Table

Adding and Editing Entries

Data Table Details

Find and Replace Expressions

Mirroring Animation

Detecting Mirrored Animation in Blueprint Notifies

Animation mirroring copies animation from one side of a character to another so you can reuse the same animation in different situations. Using the Mirror Data Table, and other mirroring workflows, you can mirror not only your Animation Sequences, but also curves, sync markers, and Notifies. Additionally, mirroring within Unreal Engine provides a way to create mirrored animations without needing to manage a second copy.

This document provides an overview of how to mirror animation using the Mirror Data Table and Animation Blueprints.

Your project already contains a Skeletal Mesh and animations to mirror.

You have an understanding of how to create and use Animation Blueprints.

Mirror Data Table

To start mirroring animations, you must first create a Mirror Data Table Asset. Mirror Data Tables provide mirroring assignments and instructions for all the elements of a Skeleton you want to mirror.

To create it, click Add (+) in the Content Browser and select Animation > Mirror Data Table. A dialog window will appear where you must select the Skeleton you want to mirror. Select one and click Accept.



Open the Mirror Data Table to view the editor with the following primary areas:



Data Table, which contains the list of elements to mirror. This list auto-populates depending on the bone, notify, and other element names, which you can configure in the Data Table Details.

Data Table Details, which contains configuration settings for the mirroring behavior.

Row Editor, which provides settings for the selected entry where you can edit the element name, the mirrored name, and the element type.

Adding and Editing Entries

To add a new table entry, click the Add (+) toolbar button and fill the four properties in the Row Editor panel.

Row Name, which is the name of the entry.

Name, which is the name of the first bone to mirror.

Mirrored Name, which is the name of the second bone to mirror. Left or right bones can go in either of these properties, but these properties must contain the symmetrical bones.

Mirror Entry Type, which is the element type to mirror. You can select the following types:

Bone

Animation Notify

Curve

Sync Marker

Custom, which provides a code foundation for extending the Mirror Data Table in C++ by adding additional types.



In order to have a fully mirrored character, it is necessary that the table contains most skinned bones, including central bones like pelvis, spine, neck, and head. This is so that the mirroring operation can appropriately flip the rotations of those bones along the mirror axis. For these entries, both the Name and Mirrored Name should match.



Data Table Details

The Data Table Details panel contains configurations and other settings for the mirror behavior:



Name

Descriptions

Mirror Find Replace Expressions

An array of expressions that are used to automatically populate the table with common mirror entries. Refer to the Find and Replace Expressions section for more information.

Mirror Axis

The axis of mirroring, which is across the front of the character. In most cases this should be X.



Skeleton

The Skeleton Asset to use for the mirror operation.

Row Struct

The structure to use for each row of the table. You must inherit from FTableRowBase if you want to extend this.

Strip from Client Builds

Enabling this will not cook this Data Table into client builds. Useful if you are making confidential tables that only servers should know about.

Find and Replace Expressions

Find and Replace Expressions are array entries you can add to the Data Table Details that automatically search and replace certain string text of elements in the skeleton. These expressions are then used to inform which elements are automatically populated when creating or reimporting the skeleton.



Each array requires the following expressions:

Name

Description

Find Expression

The text to search for. In most cases this will likely be the symmetry modifiers for your element names, such as _l, left_, or _left_.

Replace Expression

The text to replace. In most cases this will likely be the symmetry modifiers for your element names, such as _r, right_, or _right_.

Find Replace Method

The search method to use when replacing text. You can select from the following options:

Prefix, which will search for text only at the beginning of the name.

Suffix, which will search for text only at the end of the name.

Regular Expression, where you can write a custom expression for finding and replacing names.

When using Regular Expression as your method, you can write custom Regular Expressions for Find Expression and Replace Expression.

For example, Index 12 of the default array contains the following expression, searching for common central bone names and assigning to the Name and Mirrored Name properties:

Find Expression: ((?:^[sS]pine|^[rR]oot|^[pP]elvis|^[nN]eck|^[hH]ead|^ik_hand_gun).*)

Replace Expression: $1

In cases where your symmetry text modifiers are in the middle of an element name, such as finger_left_index1, you can write the following expression to correctly search and replace:

Find Expression: (\S*)_left_(\S*)

Replace Expression: $1_right_$2

The array comes pre-populated with common expressions, such as searching and replacing several permutations of symmetry modifiers as pre or postfixes. You can change this default array from the Project Settings. In the main Unreal Engine menu bar, select Edit > Project Settings, then navigate to the Engine > Animation section and locate the Mirroring property section.



Mirroring Animation

Once you have created and populated your Mirror Data Table, you can now mirror your animations in Animation Blueprints. This is done using the Mirror AnimGraph node.

To create it, right-click in the AnimGraph and select your table from the Mirroring category.



You can preview the mirroring effect by providing an input pose and bool variable, enabling or disabling the mirroring.



The Mirror node contains the following properties:



Name

Description

Mirror

Enables or disables the mirror effect. This is exposed as a pin by default.

Mirror Data Table

The Mirror Data Table to use for mirroring.

Blend Time on Mirror State Change

The length of time to blend between mirror states when Mirror is enabled or disabled. Using this also requires you to use an Intertialization node after the Mirror node.



Reset Child on Mirror State Change

Enabling this will reinitialize the source pose when the mirror state changes.

Bone

Whether or not to include bone data in the mirroring.

Curve

Whether or not to include curve data in the mirroring.

Attributes

Whether or not to include notify and sync marker data in the mirroring.

Detecting Mirrored Animation in Blueprint Notifies

If you are using Custom Notify States, then you may want to change it to have a different behavior based on the mirrored state. You can differentiate between mirrored states in the Notify Blueprint using the Is Triggered By Mirrored Animation node.

In this example, it is being used in the Received Notify Function to branch the logic, checking if the notify was received from a mirrored animation or not.



Setup

Importing a Profile

Importing Specific LOD Data

Importing a Profile for a Specific LOD

Reimporting a Profile

Removing a Profile

Previewing a Profile

Runtime Blueprint Exposed API

Scalability

Static Path

Dynamic Path

Default Profiles

Console Commands at Runtime

The Skin Weight Profile (SWP) system enables you the ability to replace, a subset of, the original Skin Weights (SW) stored as part of a Skeletal Mesh. While the use-cases for this system may vary, one possible use-case is to improve visual fidelity in situations or on certain platforms that disable any dynamic character parts.

For example in the video below, a character with a coat may have its dynamic parts disabled in order to improve performance on lower-end platforms. When the foot is raised, this leads to undesirable clipping. Using Skin Weight Profiles, you can achieve a suitable alternative to using more expensive dynamics and mitigate the amount of clipping.

Below you can also see the difference between using dynamic cloth, copy pose without Skin Weight Profiles, and running with Skin Weight Profiles.







Cloth

Copy Pose

Profile

Setup

When working with Skin Weight Profiles, they have to be imported and set up in the Editor in order to be able to use them at runtime.

Importing a Profile

You can import a profile inside the Skeletal Mesh Editor and you will need to provide an FBX file containing the different Skin Weights, a name for the profile, and optionally an LOD index.

Inside the Asset Details panel for a Skeletal Mesh, click the Add (+) button under Skin Weights and select Import Skin Weight Profile.



Select an FBX file containing Skin Weight data to import and click Open.



Enter a Profile Name (and optionally an LOD index) and click Import.



Your new Skin Weight Profile will be added as an array element inside the Asset Details panel.



Importing Specific LOD Data

If you have Skeletal Mesh LODs that use custom LODs, meaning they were imported separately and not generated in-Engine, you will need to import a matching file containing the different Skin Weights. These files can also be imported as part of a pre-existing SWP as illustrated below.

For your existing SWP, select which LOD you want to import weights for.



After you select an FBX file containing Skin Weight data, it will show up under the Source Files section of the profile.



Importing a Profile for a Specific LOD

If you want (or need) to override the original Skin Weight at a specific LOD level, you can do so during the import process by specifying which LOD index the imported file contains data for.



Reimporting a Profile

If you update any of the source data for the Skin Weight Profile, you can reimport the files. If the stored file path does not exist any more, you will be prompted for a new file location.

To do so, click the Reimport icon for the SWP you wish to reimport.



If you have multiple LODs, you can select which LOD you wish to reimport a SWP for from the reimport menu.

Inside the Skeletal Mesh Editor, you can reimport Skin Weights from a different file by clicking the ellipse (...) icon and choosing a new file.



Removing a Profile

You can remove a Profile, or a LOD within a Profile, inside the Skeletal Mesh Editor by clicking the Remove Profile button.



You can remove an entire SWP or LOD within a profile from the remove option.

Previewing a Profile

You can preview what the different Skin Weights for a specific SWP look like inside the Animation Editors in the Viewport, or during a Play in Editor session.

You can set a specific SWP for a Skinned Mesh component (or child class), by selecting it in the Viewport and selecting the desired profile to preview.

Click the Character button, then under Animation, select your desired SWP under the Skin Weight Profile section.



Debug information will be displayed in the Viewport when selecting a SWP to preview.



You can also preview Skin Weights inside the Main Level Editor Viewport through the Details panel and the Skin Weights Profile setting.



Runtime Blueprint Exposed API

At runtime, you can set up a SWP for a Skinned Mesh component (or any child-class) using the provided (Blueprint exposed) API.

Name

Blueprint Node

Description

Set Skin Weight Profile



This will set the specific SWP according to the provided name (if it exists).

Clear Skin Weight Profile



This will clear any previously set SWP.

Unload Skin Weight Profile



This forcefully unloads deletes the Skin Weight Buffer for the provided name.

Get Current Skin Weight Profile



Returns the name of the currently set SWP, ‘None' otherwise.

Is Using Skin Weight Profile



Returns whether or not a profile is set.

Scalability

The system has the ability to load the default-set SWP at runtime, this can be performed using two paths: Static or Dynamic Paths.

Static Path

Using the Static path, during serialization of the Skeletal Mesh data, the system will check whether or not a default profile has been set, and if so it will be loaded. It will take the original Skin Weight buffer and overwrite its data with that of the default profile. This means that whenever a default SWP is loaded using the Static path, no more changes can be applied afterward, and the original data will be lost until the Skeletal Mesh is reloaded.

If the user tries to change to the Dynamic path or try and set a SWP manually the system will cause an error.

Dynamic Path

The Dynamic path, just like with the Static path, during serialization the default profile will be loaded. However, instead of overriding the original Skin Weight buffer, it will create a new one. Whenever any subsystem requests the buffer, it will return the override rather than the original. The benefit of this system is that it can be toggled at runtime, which is what sets it apart from the Static path.

Default Profiles

You can assign a default SWP profile inside the Details panel of the Skeletal Mesh Editor as well as override the original Skin Weights on a per-platform or LODIndex basis.



In the image above, one SWP is assigned as the override for Desktop and another SWP is set for Mobile.

When assigning a SWP as the default profile, any additional profiles will be unable to be assigned as the default.



When a default profile is assigned, any LOD below the LOD index set under Default Profile from LODIndex will override the Skin Weights of the Skeletal Mesh with Skin Weights from the profile.



Console Commands at Runtime

The following console commands can be used at runtime while previewing the SWP system:

Name

Description

a.SkinWeightProfile.LoadByDefaultMode

Enables/disables run-time optimization to override the original skin weights with a profile designated as the default to replace it. Can be used to optimize memory for specific platforms or devices.

Value

Description

0

Static disabled.

1

Static enabled.

2

Dynamic disabled.

3

Dynamic enabled.



a.SkinWeightProfile.DefaultLODOverride

Override LOD index from which on the default Skin Weight Profile should override the Skeletal Mesh's default Skin Weights.

Value

Description

-1

Disabled.

0

LOD index 0.

N

LOD index N (where N is the LOD to load).



a.SkinWeightProfile.AllowedFromLOD

Override LOD index from which on the Skin Weight Profile can be applied.

Value

Description

-1

Disabled.

0

LOD index 0.

N

LOD index N (where N is the LOD to load).



Animation Blueprints

Graphing in Animation Blueprints

Animation Blueprints

Enabling the Animation Sharing Plugin

Animation Sharing Setup Asset

Skeleton Setups

Animation States

Scalability Settings

Animation Sharing State Processor

Animation Blueprint Setup

Anim Sharing Additive Instance

Anim Sharing State Instance

Animation Sharing Manager

The Animation Sharing Plugin provides a way to create shared animation systems that reduce the overall amount of animation work needed for a crowd of Actors. Based on the Master Pose Component system, Animation Sharing utilizes a set of animation state buckets for which animation instances are evaluated. The resulting poses are then transferred to all child components that are part of the bucket.

The diagram below provides a high-level breakdown of how the system works:



Click image for full view.

Individual Crowd Actors (AActor)

UAnimationStateProcessor instance that is part of the Animation Sharing Setup

Runtime manager that is initialized using the Animation Sharing Setup

States (enum named), which the user has set up

Runtime representation of the state that takes the form of a Skeletal Mesh Component

Master Pose Component system used to share the animation with the child Skeletal Mesh Components

In the example video below, a Blueprint with a Skeletal Mesh Component cycles through several Animation States. A group of individual Actors is also shown where the Animation State of each Actor is determined based on the Animation State of the Skeletal Mesh Component in the Blueprint.

Enabling the Animation Sharing Plugin

In order to use Animation Sharing, you will need to enable the Animation Sharing Plugin from the Edit > Plugins menu under the Programming section:



Click image for full view.

You will need to restart the Editor after enabling the plugin.

Animation Sharing Setup Asset

The Animation Sharing Setup asset contains all the information that will be shared across the specified Actors. You can create an Animation Sharing Setup asset inside the Content Browser under the Animation category.



Inside the Animation Sharing Setup asset, you can define the following properties:



Skeleton Setups

The ability to add multiple Skeletons along with their corresponding settings is available by clicking the + (plus sign). This is useful when you have multiple Skeletons and Skeletal Meshes that will be driven by animations during animation sharing.

Property

Description

Skeleton

The Skeleton asset to be replicated.

The Animation Sharing Setup is specific to the specified Skeleton.

Skeletal Mesh

The Skeletal Mesh to be replicated.

This is used for debugging poses only.

Animation Blueprint for Blending

The Animation Blueprint that is a child of AnimSharingTransitionInstance.

You must create and set up one of these to handle blending between states. Additionally, every time a blend is required, one of these is generated and ran to handle the transition which adds a cost.

Animation Blueprint for Additive Animation

The Animation Blueprint that is a child of AnimSharingAdditiveInstance used for additive animations.

Inside your Animation Sharing Setup asset, you will also need to set Animation State to On Demand and enable the Additive option.

State Processor Class

Interface class used when determining which state an Actor is in.

This needs to be set in order to add the Animation States.

Animation States

This is an array that holds all the states the Actor can be in. Each state is its own bucket.

Animation States



Once you define a State Processor Class inside your Skeleton Setup, based on the states within it, you will be able to define the following properties for each of your Animation States.

Property

Description

State

Define which state you want that index of the array to contain information for.

This is inherited from the State Processor Class and the assigned Animation State Enum.

Animation Setups

This enables you to define the per state Animation information such as which Animation Sequence to play, what Animation Blueprint to use for playing back the Anim Sequence, number of randomized instances (if desired), and whether or not the setup is enabled for specific platforms.

On Demand

Whether or not this state is classified as on-demand, which means you can kick off a unique animation when needed. This spins up a unique instance per on-demand animation.

When reaching the maximum value, it will snap to the nearest animation.

Additive

Whether or not the state is an additive state.

On-demand must be enabled and you will need an Additive Animation Blueprint to handle blending.

Blend Time

Duration of blending when blending to the state.

Maximum Number Of Concurrent Instances

The number of instances that will be created for the state (platform-specific).

Requires Curves

Whether or not this animation requires curves or morph targets to function correctly for follower components.

Scalability Settings



The following properties are available under the Scalability Settings section:

Property

Description

Use Blend Transitions

If the animation should play a blend to transition from one state to another.

Blend Significance Value

Significance value tied to whether or not a transition should be blended.

Maximum Number Concurrent Blends

The number of blends that can be running at the same time.

Each animation that is over this limit will snap to the nearest one.

Tick Significance Value

Used with the Significance Manager Anything over the specified value will not be ticked.

Animation Sharing State Processor

The AnimationSharingStateProcessor class is a specialized Blueprint class (or you can use the native C++ class) that is used to determine what state you are currently in. To create this class of Blueprint, create a new Blueprint of the AnimationSharingStateProcessor class and enter a desired name for the Blueprint.

The Animation Sharing State Processor Blueprint should only be used for prototyping. Runtime performance will be greatly improved by using the native implementation as opposed to the Blueprint implementation.



In your Blueprint, in the Details panel, set the Animation State Enum to an enumeration containing your Animation States.



The Animation Sharing State Processor Blueprint is also the Blueprint Class that you will define as the State Processor Class inside your Animation Sharing Setup asset (pictured below). After defining the State Processor Class, you can add Animation States by clicking the + (plus sign) to represent each state in your enumeration.



The Animation Sharing State Processor Blueprint can override two functions. The first, the Process Actor State function (pictured below), can be used to find out what Actor you are editing the state for. The second overridable function, Get Animation State Enum, should be used to return the Enum class from a native Animation Sharing State Processor and can be used for interacting with the native implementation.



Click image for full view.

In the image above, we override the Process Actor State function and cast to a Blueprint called Husk_BP to retrieve its Animation State (stored in a variable we have created). The Animation Sharing State Processor Blueprint is also assigned inside your Animation Sharing Setup as the State Processor Class.

Animation Blueprint Setup

You will need to set up an Animation Blueprint to handle the blending between the Animation States. This requires a special class of Animation Blueprint called an Anim Sharing Transition Instance. Create an Animation Blueprint from the Content Browser, then in the Pick Parent Class menu, select your desired Skeleton asset and the AnimSharingTransitionInstance as the class.



On the AnimGraph of the AnimSharingTransitionInstance Animation Blueprint, copy or use the setup depicted below.

Copy Node Graph



Anim Sharing Additive Instance

When using additive animation, you will need to use an Animation Blueprint of the AnimSharingAdditiveInstance class.



Animation State will need to be marked as On Demand and Additive enabled inside your Animation Sharing Setup asset.



On the AnimGraph of the AnimSharingAdditiveInstance Animation Blueprint, copy or recreate the setup depicted below.

Copy Node Graph



Anim Sharing State Instance

This Animation Blueprint (AnimBP) class enables the ability to add AnimBP behavior if the user would like to do so as it exposes two properties by default: Animation to Play and Permutation Time Offset. On a basic level, this is what should drive the pose.

As for the native implementation, it exposes GetInstancedActors which returns all AActor(s) that are currently being driven by this state. That way , in case there are Notifies, they can be handled correctly and propagated to the unique instances.

This is achieved by overriding HandleNotify and handling it accordingly.

Copy Node Graph



Animation Sharing Manager

In order for Animation Sharing to be executed at runtime, you will need to create an Animation Sharing Manager that points to your Animation Sharing Setup asset. This can be called through Blueprint inside any Actor (or from the Level Blueprint) with the Create Animation Sharing Manager function.



You can also call the following functions targeting an Animation Sharing Manager:

Function

Description

Animation Sharing Enabled

Returns whether or not Animation Sharing is enabled.

Get Animation Sharing Manager

Returns the Animation Sharing Manager (or null if none has been set up).

Register Actor

Registers an Actor with the Animation Sharing Manager, according to the specified Sharing Skeleton.

In the image below, we use Get Animation Sharing Manager and Register Actor to register our Husk Actor with the Animation Sharing Manager (we also enable input in the Blueprint so that we may change the Animation State with a key press).



Click image for full view.

Vertex Key Framed Meshes

Vertex Animation Tool - Timeline Meshes

Prerequisites

Script Location

Tool Caveats

Vertex Animation Tools Break Down

3Ds Max Version & Script Installation

3Ds Max Unit Setup

Tool Choices

Tips & Tricks

Speeding Up the Animation Play Rate

Multiple Animated Meshes

Frame Skip

Technical Information

Limitations

Memory Usage

Storing complex animation data into 2D Textures or a meshes UV's is a great way to reduce animation overhead while still maintaining the required look and feel of the animation. In the past you might have used Morph Targets to do the exact same thing, however this new method has a few advantages that Morph Targets do not. One of those advantages is allowing you to use complex animation data inside systems that would not otherwise be capable of utilizing Morph Targets like the Cascade Particle Editor. In the following documents we will cover how you can use this script to generate content for your projects.

Prerequisites

Before we can begin using the script there are few things to be aware of so you can get the best results possible when using this technique.

Script Location

The Vertex Animation Script will be in the following location and is called VertexAnimationTools.ms.

The newest version of the Verext Animation Script has been updated to correct for the way 3Ds Max 2014 and later handle image gamma.

Tool Caveats

While this tool is very good at reducing animation overhead by storing complex animation data into a texture, there are a few drawbacks to using the tool. First of all the tool can only affect a maximum of 8192 vertices in a single 2D Texture. This is because the maximum Texture size a Texture can be for DirectX 11 is 8192 pixels in either the X or Y direction. The tool generates the data in the Texture using the following formula.

Due to this limitation this tool is best suited for Visual Effects or ambient Static Meshes that require animations but might not justify using a complex animation rig to do so. This tool will also not work with Skeletal Mesh Animations as the bone transforms are not available to the Material Editor. This means that if you want to affect the vertices of a Skeletal Mesh in a similar manner you will need to use Morph Targets instead.

Vertex Animation Tools Break Down

Inside of the Vertex Animation Tools you will find two entirely different methods for affecting the vertices of Static Meshes. In the following section we will go over what these two methods are and how they differ from one another.

Vertex Animation Tools: The top section of the Vertex Animation Tools, called Vertex Animation Tools, is for generating a 2D Texture that will store the morph target vertex positions and normals.



Property Name

Description

Animation Options:

Animation Options allows you to pick between using animation that was created using the Timeline in 3Ds Max or use individual Key Frame Meshes that were created in 3Ds Max or another 3D package like Maya or Blender and then exported out of that package frame by frame so the animation could then be re-constructed inside 3Ds Max.

Process Animated Meshes:

This button will process the animated meshes that are in the 3Ds Max scene, creating and then exporting the required Textures.

Anim Start:

This option defines the frame that the animation should start from.

Anim End:

This option defines the frame that the animation should end on.

Frame Skip:

This option allows you skip frames to try and save on Texture space.

Process Selected Meshes:

This option, only available if Key Frame Meshes is enabled, will process the selected Key Frame Meshes in the order that they were selected.

Sequence Painter: The Sequence Painter does something similar to the Vertex Animation Tool's but with one key difference, the information for the vertices positions is stored in the meshes UV's instead of a 2D Texture.



Property Name

Description

Paint Selection Sequence:

This stores the information about the meshes Vertices inside of the meshes UVs instead of storing that data in a 2D Texture.

3Ds Max Version & Script Installation

This tool has only be tested using 3Ds Max 2015. While it might be able to work with other 3Ds Max versions, none of them have been tested so use other version of 3Ds Max at your own risk. To install the script just drag it from its location in 4.8\Engine\Extras\3dsMaxScripts right into the 3Ds Max viewport and the script will launch itself.

If you find that you are using this script a lot you can always add the script to one of the tool bars or quad menus. If you are unfamiliar how to do this the Autodesk site has a very detailed walk through that will explain how you go about doing this.

3Ds Max Unit Setup

Before we can begin to use the tool we need to first ensure that the units of measurement 3Ds Max uses is setup to correctly match the units of measurement UE4 uses. This way we can ensure that the data the tool exports from 3Ds Max will work in the same manner inside UE4. Since UE4 uses Centimeters for its default unit of measurement we will need to ensure that 3Ds Max uses this as well and to change this we must do the following.

First open up 3Ds Max 2015 and once loaded from the Main Toolbar select Customize > Unit Setup.

Next click on System Unit Setup and change the System Unit Setup from Inches to Centimeters and then press the OK button.

Finally change the Display Unit Scale to Generic Units and then press the OK button.

It is extremely important that you DO NOT skip this step. Skipping this step could result in rendering errors when the content is imported into UE4 because UE4 and 3Ds Max's units are not the same.

Tool Choices

The Vertex Animation 3Ds Max script offers two different ways to store the vertex animation data. One method will store the vertices positions in a 2D Texture while the other method will store the vertex position data in the UV's of the mesh. Below you will find links that show you how to setup and use both methods.

Key framed Method - This method uses individual key frames that can be exported from other 3D packages and imported into 3Ds Max. That information is saved to the meshes UVs.

Animation Timeline Method - This method uses the 3Ds Max animation timeline and the results are encoded into a 2D Texture.

Tips & Tricks

To get the most out this technique, there are a few tips and tricks that you can follow which are outlined below.

Speeding Up the Animation Play Rate

If you feel that the rate at which the animations are playing is to slow, you can use the TimeWithSpeedVariable Material Function to speed up the play rate. To do this just plugging the output of the TimeWithSpeedVariable into the 0-1 Animation input if you are using the MS_SequencePainter_SequenceFlibook Material Function. If you are using the MS_VertexAnimationTools_MorphTargets Material Function plug the output of the TimeWithSpeedVariable into the Morph Animations input.



Multiple Animated Meshes

You can select multiple animated meshes at a time and the script will bake all of that data down to one mesh and one set of Textures. This is very useful when working with characters that are made up of different parts. Just select the parts that you want to use and the run the script like normal. The script will then combine the pieces you selected and generate a new mesh from them along with the required 2D Textures.

Frame Skip

Using the Frame Skip option that is under the Vertex Animation Tools section of the script will allow you to skip certain frames. This is a very useful option as it allows you to reduce the final Texture size while still maintaining the look and feel of the original animation.



If we take a look at the example video below, we can see the Frame Skip feature in action. The first Teapot you see in front of the word, Original, shows how the Teapot will animate using the full frame range. The next Teapot, with the number 2 in front of it, shows how the teapot animates skipping every 2nd frame and so on. As you can see the last example, the effect will still maintain its look and feel even if you skip 10 frames.

Mesh Name /Number

Texture Size

Memory Savings

Original

175 KB

N/A

2

59 KB

116 KB

5

30 KB

145 KB

10

21 KB

154 KB

Technical Information

The following section is for technical information about how the Vertex Animation script works. Please note that this is here purely for reference or for people who would like to know more about how the script works in case they want to modify it.

Limitations

Vertex positional morph target information is stored in a 16 bit signed floating point file format. A 32 bit image would be more precise but 16 should suffice for most FX work. With that said, the offset vertex positions will be less precise as they move further away from their resting positions.

Also note that the scripts Textures should be sampled using the nearest neighbor method.

Memory Usage

The memory usage for each frame per vert is as follows :

Vertex Offset Texture: 8 bytes per vertex per frame (each pixel)

Normal Texture: 4 bytes per vertex per frame (each pixel)

3Ds Max Content Creation

Unreal Engine Setup

You can also use the Vertex Animation tool with meshes that do not make use of the Animation Timeline in 3Ds Max. Generally speaking mesh animations that use this method have been exported frame by frame from another 3D package like Maya or Blender. In this section we will go over how to use this method as well as any differences in setup that you need to be aware of.

3Ds Max Content Creation

Please note that while we are using 3Ds Max for this example, the method in which the content is created and setup inside 3Ds Max is no different than how content could be set up inside other 3D Packages such as Maya or Blender.

First inside 3Ds Max create a new scene and then create a Teapot with the following settings and place it at 0,0,0 in the world.

Radius: 70.0

Segments: 5

Next from the Modifier List add a Melt Modifier to the Teapot mesh.



Now make a copy of the mesh by holding down the Shift key and moving the Teapot along the X axis with the mouse. Position the Teapot copy so that the orange bounding box of the Melt modifier does not intersect the original mesh. Once the Teapot copy is in position release the mouse and the shift key and the Clone Options will be displayed. Make sure the Object is set to Copy and then set the Number of Copies to Four and press the Ok button to create the copies.

Then select the 2nd Teapot mesh and set the Melt Amount in the Melt modifier to 25. Then select the next Teapot in line and set the Melt Amount of the Melt modifier to 50 and the next one to 75, and finally set the last Teapot Melt Amount to 100.

With all the Teapots now having some type of deformation on them, select all the Teapots and then with the mouse Right-Click in the 3Ds Max viewport and select Convert To: > Convert to Editable Poly.

You have to convert any mesh that you want to use with this tool to Editable Poly. The tool WILL NOT work with any other mesh type.

Now that the Teapot meshes have all been converted to Editable Poly, select all the meshes and move them to 0,0,0 in the world. Once the meshes are in the center of the world, deselect the Teapot meshes and then select them in the order that the animation is supposed to play. For this example we want to select Teapot001 first then select Teapot002 and so on till all five are selected.

The Sequence Painter Tool requires that you select the meshes in the order that they should be played in the animation. Failing to do this will result in the animation that gets played in Unreal Engine not syncing up to the bone driven animation that it is supposed to replace.

With the Teapots now in the center of the world and selected in the order that the animation is supposed to be played, it is now time to run the Sequence Painter script. To do this all you need to do is press the Paint Selection Sequence button that is in the Sequence Painter section of the tool.



Depending on the amount of vertices your mesh has the time that it takes for the Paint Selection Sequence to finish is quite fast.

Now that position data has been saved to the UVs of the Teapot, it is time to export the Teapot mesh for use in the Unreal Engine. When exporting the Teapot mesh use the same setting as you would for any other Static Meshes and make sure that Smoothing Groups are enabled. For this example the Teapot mesh was given the name SM_Teapot_PSS.FBX.

Unreal Engine Setup

Once the Teapot mesh has been exported from 3Ds Max, it is now time for the Teapot mesh to be imported and setup so that it will work the same inside Unreal Engine.

First import the Teapot mesh, SM_Teapot_PSS.FBX by dragging it from the location it was exported to into the Content Browser, making sure that the following options are enabled / disabled.

Disable the Auto Generate Collision option.

Disable the Remove Degenerates option.

Disable the Generate Lightmap UV's option.

Enable the Combine Meshes option.

Disable both Import Materials & Import Textures option.



After the Teapot mesh has been imported, open the mesh up by Double-Clicking on it with the Left Mouse button in Content Browser. Once the mesh has been opened enable the Use Full Precision UVs option and set the Distance Field Resolution Scale to 0.0 then press the Apply Changes button.



With the Teapot mesh now set up correctly, create a new Material in the Content Browser and name it MAT_Sequance_Painter and then open up the Material.



Once the Material is opened up, add two Constant Parameter nodes to the Material Graph by holding down the 1 key on the keyboard and Left-Clicking with the mouse in the Material Graph to place the Constant Parameter nodes. Set the value of one of the Constant Parameter node and plug that into the Base Color input on the Main Material Node. Then set the value of the other Constant Parameter node to 5.



Next use the mouse and Right-Click in the Material Graph to expose the search menu and then search for MS_SequencePainter_SequenceFlipbook Material Function using MS as the search term. When you find the MS_SequencePainter_SequenceFlipbook Material Function, click on it with the Left Mouse button to add it to the Material Graph.

With the correct Material Function now in place, connect the output of the MS_SequencePainter_SequenceFlipbook, into the World Position Offset input on the Main Material node and then connect the remaining Scalar parameter to the Number Of Frames input on the MS_SequencePainter_SequenceFlipbook Material Function node.

Now that everything has been hooked up press the Apply button to compile the Material and then press the Save button. After that is completed you can then close down the Material Graph Editor.



With the Material created, compiled, and saved drag the Teapot mesh from the Content Browser into the level and then drag the Material that was just created for it from the Content Browser on to the mesh that was placed in the level. Once this has been completed you will now see the mesh "playing" the animation.

3Ds Max Content Creation

Unreal Engine Content Setup

Texture Import & Setup

Static Mesh Import & Setup

Unreal Engine Material Setup and Uses

In the following section we will cover how you can use the 3Ds Max Animation Timeline in conjunction with the Vertex Animation tools to create a 2D Texture that stores the position of vertices in any given 3D mesh.

3Ds Max Content Creation

First from the Standard Primitives create a Teapot at 0,0,0 in the world with the following options.

Radius: 70.0

Segments: 5



Next from the Modifier List, apply a Bend Modifier to the Teapot and then set the Direction to 90.



Now enable Auto Key and then move the Time Slider to 10 and set the Angle on the Bend Modifier to -50 and then move the Time Slider to 25 and set the Bend Angle to 50. Finally move the Time Slider to 35 and then set the Bend Angle to 0. Once all of that has been completed make sure to turn off Auto Key to ensure that you do not place any extra keys by accident.

With the Teapot now bending, open up the Vertex Animation Tools, if not already open, and set the Animation Options to Animated Meshes and the Anim End to 35.



Now that the correct tool options have been set, press the Process Animated Meshes button to begin the Texture creation process. About half way through the process a Windows Dialogue box will be displayed asking for a location to store the Textures that are generated. For this example a folder was placed on the Desktop called Vertex_Anims and the Textures where saved to that folder. When completed the folder that was placed on the Desktop should now have two Texture files inside of it, a .EXR Texture which contains the vertices position data and a .BMP Texture that contains the Teapots Normal information.



With the Textures now created go back to 3Ds Max and select the Teapot mesh with "_MorphExport" added to the name and export it as a .FBX file to the same folder that the Textures where exported to. Name the mesh "SM_Teapot_Bend_00" and in the FBX options make sure that Smoothing Groups are enabled and leave all other setting with the default values.

Unreal Engine Content Setup

Once all of the content has been exported from 3Ds Max it is now time to import and set that content up so that it will work correctly inside Unreal Engine. Please keep in mind that each and every step listed below MUST BE completed exactly how it is described below or you run the risk of things not working correctly inside Unreal Engine.

Texture Import & Setup

If you are unfamiliar with the Unreal Engine Texture Import process please read the Textures documentation for more information.

The first thing that needs to be completed is that both Textures that were exported from 3Ds Max need to be imported into Unreal Engine. To do select each Texture from its export location in Windows Explorer and drag them into the Content Browser, releasing the left mouse button to trigger the import process. When you do this, you will be prompted with a warning message about the Textures not being a power of 2 resulting in the Texture not working with Streaming or Mip Mapping. Press the Yes button to dismiss the prompt and continue with the import process.

Once each Texture has been imported, they then need to be setup in a very specific manner to ensure that they work correctly. The first Texture to setup is the .EXR Texture that contains the vertices position data. Open up this Texture by Double-Clicking on it in the Content Browser with the Left Mouse Button and make sure the following options are set / enabled.

Make sure the Mip Gen Settings is set to No Mip Maps.

Change the Texture Group to UI.

Make sure that SRGB has been disabled.

Set the Compression Settings to TC_HDR.

Set the Filter to Nearest.



Next open up the Normal Map Texture and make sure that the following options are set / enabled.

Make sure the Mip Gen Settings is set to No Mip Maps.

Change the Texture Group to UI.

Make sure that SRGB has been disabled.

Set the Compression Settings to TC_Vector Displacement Map.

Set the Filter to Nearest.



With the Textures now set up correctly, make sure to press the Save All button in the Content Browser to save all changes that have been made.



Static Mesh Import & Setup

Now that the Textures have been imported and setup, it is now time to import and setup the Teapot Static Mesh. Import the Teapot Static Mesh in the same way the Texture were imported by first selecting the Teapot Static Mesh in Windows Explorer and then dragging it into the Content Browser and releasing the Left Mouse Button to trigger the import process. When you do this the following dialogue box will be displayed. From this dialogue make sure that the following options are set / disabled.

If you are unfamiliar with how to import Static Meshes into Unreal Engine please check out the Importing Assets Directly document for more information about this.

Disable the Auto Generate Collision option.

Disable the Remove Degenerates option.

Disable the Generate Lightmap UV's option.

Enable the Combine Meshes option.

Disable both Import Materials & Import Textures option.



Once all those options have been set, press the Import button to begin the import process. After the Static Mesh has been imported, open the Static Mesh up and make sure the following options are enabled / disabled.

Enable the Use Full Precision UVs option.

Set Distance Field Resolution Scale to 0.0.



With the Static Mesh now set up correctly, make sure to press the Apply Changes button in the Static Mesh editor and then press the Save All button in the Content Browser to save all changes that have been made so far.

Unreal Engine Material Setup and Uses

Now that all of the required content has been imported and properly setup, it is now time to create a that can Material use the content.

If you are unfamiliar with how Materials work inside Unreal Engine please refer to the Materials documentation for more information.

First create a new Materia**l by Right-Clicking with the Mouse and then choosing the Material option that is under the Create Basic Asset section. Name the Material MAT_Vertex_Animation**.

Next open up the MAT_Vertex_Animation Material and locate the two Textures that were imported into the Content Browser in the previous step. Select both Texture**s and then Drag** them from the Content Browser and Drop them into the Material Graph.

Then select the Main Material Node and in Details Panel search for Num Customized UVs. When you located the Num Customized UVs input, input a value of 4. You should now see four new inputs on the Main Material Node with Customized UV and then a number starting at 0 going to 3.



Next while still in the Main Material Node Details Panel, Un-Check the Tangent Space Normal option.



Then hold down the 1 key on the Keyboard and then click inside the Material Graph with the Left Mouse Button to place down a Constant Parameter node. Set the value of the Constant to 0.5 and then plug the output into the BaseColor input in the Main Material Node.



Now it is time to add the Material Function that powers the effect. To do this Right-Click with the Mouse inside the Material Graph and then from the menu that is displayed, type MS to show the Maxscript Material Functions. Then click on the MS_VertexAnimationTools_MorphTargets Material Function with the mouse to add it to the Material Graph.

With all the required Textures and Material Function now added to the Material Graph, we can now begin to connect everything together but first, select both Texture Samplers and convert them to Texture Objects by Right-Clicking on one of the Textures and selecting the Convert To Texture Object option.

Next connect the output from the Normal Texture Object to the Morph Normal(T2d) input. Then connect the .EXR Texture Object to the Morph Texture (T2d) input. Finally connect the outputs of the MS_VertexAnimationTools_MorphTargets Material Function to the related inputs on the Main Material node.



Now add another Constant Parameter to the Material Graph by holding down the 1 key on the Keyboard and then clicking in the Material Graph with the Left Mouse Button to place the node in the Material Graph. Once the Constant Node has been added set its value to 51 and connect it to the Number of Morph Targets input on the MS_VertexAnimationTools_MorphTargets Material Function.



The number that is used for the Number of Morph Targets input comes from the Y value of the .EXR and Normal Textures. Make sure to always use the number that comes from the Texture as using any other number could result in your effect not working the same in Unreal Engine as it did in 3Ds Max.

Once everything has been connected press the Apply button to compile the Material and then press the Save button to save your work and once that is completed closed down the Material Graph Editor.

From the Content Browser select the Teapot mesh that was imported and drag it from the Content Browser into the level. Then once the Teapot mesh is in the level, select the Material that was created, MAT_Vertex_Animation, and apply it to the Teapot mesh by dragging it from the Content Browser on to the Teapot mesh that is placed in the level.



Skeletal Meshes







Interface

Creating Morph Targets

Using Morph Targets

Morph Target Debug View Mode

Optimization

The Morph Target Previewer previews any Morph Targets (sometimes called "morphs" or "blend shapes") that are applied to a Skeletal Mesh. Each Morph Target is additively blended into the existing Skeletal Mesh geometry. Multiple morph targets can be combined to create a complex vertex-driven animation, which is often ideal for such things as facial expressions.

The Morph Target Previewer window is visible by default whenever any Animation Editor is open.

Interface

The Morph Target Previewer panel has two main sections:



Search Bar

Morph Target List

The Search Bar filters the list of Morph Targets to quickly find the one you need. Type the first few letters of the desired target and the list will begin filtering. You can also right-click on a Morph Target, which will pop-up a dialog box with additional actions, such as Delete or Copy Morph Target Names.



Creating Morph Targets

You can import Morph Targets as a part of a Skeletal Mesh, as well as independently (from a given mesh). This is supported via the FBX file format.

For more information on the setup procedure, as well as how to import Morph Targets into Unreal, please see FBX Morph Target Pipeline.

Using Morph Targets

Once your Morph Targets are in place, you will need to set up your Animation Blueprint to utilize them. This is done within your Event Graph via the Set Morph Target node.



Pin

Description



Input Pins



Execution

An execution wire to trigger the effect of the node.

Target

The target Skeletal Mesh. For most circumstances, this will point to "self".

Morph Target Name

The name of the Morph Target being edited.

Value

A float value (between 0.0 and 1.0) used to set the value of the Morph Target being edited.



Output Pins



Execution

Passes execution on to the next node.

Morph Target Debug View Mode

You can enable this view mode to easily see what vertices are affected by each Morph Target.

In the viewport window, click on Show > Mesh Overlay >, and then Selected MorphTarget Vertices.

Now select any Morph Target from the Morph Target Preview panel to see the debug view.

Optimization

For target platforms that support Shader Model 5, you can enable the GPU calculation of morph targets. This means that the CPU does not have to perform the calculations if your game is CPU bound, and you have GPU processing to spare. This feature can be activated in the Project Settings, as follows:

On the file menu, go to Edit > Project Settings.

Open the Rendering section of Project Settings.

In the Optimizations category, find the Use GPU for computing morph targets checkbox and enable it.



Click for full image.

Live Link Client

Enabling Live Link

Live Link Connection Window

Editor Integration

Live Link Retargeting

Animation Blueprints

Motion Controllers

Plugin Development

Maya Live Link Plugin

Motionbuilder Live Link Plugin

ART Tracking Live Link Plugin

The purpose of Live Link is to provide a common interface for streaming and consuming animation data from external sources (for example, DDC tools or Mocap Servers) into Unreal Engine. It is designed to be extensible through Unreal Plugins, allowing third parties to develop new features—hopefully with no need to make, then maintain Engine changes.

With DDC tools like Maya or Motionbuilder, Live Link provides a way for you to edit animations externally while seeing a preview of your work inside Unreal Engine in real-time. Motion Capture Systems can also use Live Link to stream data into the Engine that can be previewed in real-time.

Live Link Client

The hub of Live Link is the Live Link Client that is created when the Live Link plugin is enabled inside a project. It has two main responsibilities:

Manage Sources: These are the sources of data and mostly represent connections to other applications, either on the same machine or across the network, that provide data to Live Link.

Manage Subjects: Subjects are individual streams of data within the client. One animating character would be a subject for instance.

A subject is made up of the following data:

A name.

Static data that doesn't change (like the Skeleton for an animation role.).

One or more "frames" of data (like the bone transforms for the animation role).

The client is also responsible for building up the next frame of data to be used by the Engine. This can either be a straight copy of the latest received data or an interpolated frame created by buffering the incoming data and playing it back with a user-definable delay.

Roles

Live Link also utilizes a concept of Roles that define how incoming data should be used. This allows for the data to be more easily mapped to a target Actor within the Engine. Supported Roles include Cameras, Lights, Characters, Transforms, and a Basic role (for generic data).

Sources

Sources are how data gets into the Live Link client. Sources can be defined within plugins so that third parties can build their own without having to change Engine code. Sources are responsible for managing how they receive the animation data (over a network protocol for example, or reading from an API for a device connected to the machine itself). Each source is handed a reference to the client to allow it to pass data to it. Within the Live Link plugin, we have defined our own source (called the Message Bus Source) that reads data from an Unreal Message Bus connection. We have used this to build Live Link plugins for Maya and Motionbuilder.

UDP Messaging

When using the Live Link Message Bus Source, it uses UDP Messaging under the hood and (by default) will use the first Network Adapter it finds. If you have more than one Network Adapter in your machine, this may cause issues if you expect to receive data from a particular adapter. If you want to receive UDP data on a specific Network Adapter, you will need to modify your Project Settings by going to Edit > Project Settings > UDP Messaging and changing the Unicast Endpoint.



For example, if you have two adapters:

Adapter A: XX.X.XXX.123

Adapter B: XXX.XXX.X.53

If you want to receive data from the Live Link Message Bus Source on Network Adapter B, you would need to set your Unicast Endpoint to: XXX.XXX.X.53:0

The ":0" specifies that all ports should be listed to.

UDP Messaging is not enabled by default in -game. You can enable it by adding -messaging in a packaged game (shipping target is not supported).

Enabling Live Link

The Live Link plugin can be enabled by opening the Plugins window (Edit > Plugins), selecting the Animation category and selecting Enabled on the Live Link Plugin.



Live Link Connection Window

Once enabled. the Live Link client can be accessed from the Window menu.



Upon selecting the Live Link option, the Live Link Connection window opens, where you can add Source Types and Subjects.



Above we can see the Live Link client with an open connection to an instance of Maya running our plugin (top left section). That instance is sending three subjects to the Editor: two Camera subjects (one named "EditorActiveCamera" and another named "camera1"), as well as a subject containing Transform data called "TestCube" (bottom left section).

Adding a Source

You can add sources through the + Source button and select the type of source you want to connect with Live Link.



Your external application will need to be set up to push data to Unreal Engine through Live Link for it to be displayed as a source to connect to. See the Live Link Plugin Development page for more information.

In addition to receiving data through a Message Bus Source, Live Link supports Hand Tracking sources for devices like Magic Leap, as well as the ability to create Virtual Subjects that allow you to combine multiple Subjects into one "Virtual Subject". For example, you could take the lower body from Character A and the upper body from Character B, then combine them into a new Subject. Or you could use the camera tracking data from one source and combine just the translation from another tracked object and drive it manually.

In the Sources panel, you can manage all your connected Sources. You can also delete a Source by clicking the Trashcan icon next to a Source.

You can also click the Presets button to save or load any previously saved presets.



Presets are saved as assets inside the Content Browser and enable you to quickly load up any previous configurations.

Subject Panel

The Subjects panel of the Live Link Connection window indicates a connected source and the subjects that are being streamed in.



This panel indicates the name of each subject, their associated role, and a status indicator where a green light is displayed if you are receiving data. A yellow light is displayed if you are connected to the Source but you didn't recieve data in the specified amount of time (configurable in the Project Settings, the default is 0.5ms).

Connection Settings

Once you establish an active connection, the following settings can be used to define the parameters of the connection:

Property

Description

Evaluation Mode

Determines how to create the frame snapshot.

Evaluation Mode

Description

Engine Time

The source will use the Engine's time to evaluate its subjects. This mode is most useful when smooth animation is desired.

Latest

The source will use the latest frame available to evaluate its subjects. This mode will not attempt any type of interpolation or time synchronization.

Timecode

The source will use the Engine's timecode to evaluate its subjects. This mode is most useful when sources need to be synchronized with multiple other external inputs (such as video or other time synchronizes sources).

Should not be used when the Engine is not set up with a Timecode provider.





Valid Engine Time

If the frame is older than ValidTIme, remove it from the buffer list (in seconds).

Engine Time Offset

When evaluating with time, how far back from current time should the buffer be read (in seconds).

Timecode Frame Rate

When evaluating with timecode, what is the expected frame rate of the timecode.

Valid Timecode Frame

If the frame timecode is older than ValidTimecodeFrame, remove it from the buffer list (in TimecodeFrameRate).

Timecode Frame Offset

When evaluating with timecode, how far back from the current timecode should the buffer be read (in TimecodeFramerRate).

Max Number of Frame to Buffered

Defines the maximum number of frames to keep in memory.

Source Debug Infos

A collection of debugging information passed through from the source.

Interpolation Settings

After a Subject has been added, you can assign any Pre Processors, Interpolation methods, or Translators to the selected Subject.



Property

Description

Pre Processors

These are good for processing the incoming data before it is pushed to the Subjects for a given frame. One possible use case is the Axis Switch, that will switch any axis of an incoming transform with another axis.

Interpolation

Defines the type of interpolation method used for blending frames.

Translators

These enable you to transform data from one role to another. For example, if you wanted to translate data from a Skeleton to a Transform. This could be useful if you wanted to just get the location of the hips of a character. This will transform the data into the correct role.

Editor Integration

Currently, the Animation Editors have a built-in integration with Live Link. This is accessed in the Preview Scene Settings tab under the Preview Controller property.



When the Live Link plugin is enabled, the Preview Controller option can be changed to Live Link Preview Controller. Once selected, you can set the following options:

Subject Name: The name of the subject in Live Link you would like to apply to the Preview Mesh.

Enable Camera Sync: Enables syncing of the Unreal Editor camera with an external editor. Internally this looks at Live Link for a subject called EditorActiveCamera. Both our internally developed Maya and Motionbuilder plugins support this.

Retarget Asset: This specifies the Retarget Asset to apply to the Live Link data that will be applied to the Preview Mesh.

Below we have an established connection between Unreal Engine and Maya, using the Maya Live Link Plugin.

Live Link Components

The Live Link Controller and Live Link Skeletal Animation components can be added to an Actor in order to drive its parameters with Live Link from a connected external source.

To use these components, click the Add Component button and use the Live Link Controller (or Live Link Skeletal Animation) component.



For the Live Link Controller, in the Details panel, you can use the Subject Representation property and select from your connected Subjects. Based on the Subject, a role will automatically be assigned (you can change if needed). The Component to Control is what will actually be driven through Live Link. In the example below, we have a Cine Camera Actor with a Live Link Controller component that allows us to move the camera and change the Focal Length from Maya. We also use the Live Link Skeletal Animation component on a Skeletal Mesh and stream in animation data. To achieve this, the Live Link Pose node has been added to our Animation Blueprint and our Subject has been selected.

The Live Link Controller can control Animation, however, it is recommended that the Live Link Skeletal Animation component be used for Animation for best results.

Live Link in Blueprint

You can also use Blueprint function calls to access Live Link data. Below, the Evaluate Live Link Frame function attempts to get a Live Link Frame from a specified subject using a given role (in the case below, the Subject "camera1" and the role of Camera is accessed).



We can then get frame data from the data result, and in this case, the transform information from our Subject. That information is then used to update the relative transform of a Cine Camera within our Blueprint.

If you are using the Maya Live Link Plugin prior to Unreal Engine version 4.23, when driving a camera through Blueprint, it may not have the correct transform. You can fix this by adding an Add Relative Rotation node set to 0, 180, 90 as indicated below.



Live Link Retargeting

Live Link retargeting is currently performed by retargeting assets (Base class ULiveLinkRetargetAsset). The Live Link pose node has a pin for specifying the retarget asset to use. We provide a very simple remap asset (ULiveLinkRemapAsset) to allow mapping of transforms from Live Link on to a USkeleton. Below is an example of how to implement a retargeting asset.

A Live Link Retarget Asset has one function it needs to override:

This function takes:

A LiveLinkSubjectFrame: the transform/skeleton as Live Link sees it, optionally buffered and interpolated.

A FLiveLinkRetargetContext: Allows for retargeting instance data, as the ULiveLinkRetargetAsset will not be instanced for each use (can be customized by overriding CreateRetargetContext).

An FCompactPose: This is the output pose from the retargeting FCompactPose is the format we use during animation evaluation.

An FBlendedCurve: This is the output curve data. ULiveLinkRetargetAsset has a helper function BuildCurveData t will populate this from the supplied Live Link data.

Retarget Assets can be Blueprintable as well, allowing users to specify logic in Editor (where appropriate). This functionality is used by the Remap Asset to allow bone names to be transformed in the Editor.

Live Link Remap Asset

An example of what is required to create a new retarget asset can be found in the editor by looking at the following classes in /Engine/Plugins/Animation/LiveLink/Source/LiveLink:

ULiveLinkRetargetAsset

ULiveLinkRemapAsset

In Editor, Remap Assets can be created by using the LiveLinkRemapAsset class type.



Inside the remap asset, you can override the function Get Remapped Bone Name.



This will enable you to transform the Bone Name in Editor.



In the example above, we are taking in Bone Name information from a Skeletal Mesh in Maya. That data is then being modified and mapped to the Bone Name naming convention in Unreal Engine.

For example in Maya, the naming convention used refers to our Bone Names as CharacterName:BoneName. In Unreal Engine, the Skeleton Asset uses just the BoneName portion. In order for Maya to stream data to the Unreal Engine Skeleton, we use the Remap Asset and override the function Get Remapped Bone Name by splitting the string at the colon and only taking the string information following the colon, so just BoneName instead of CharacterName:BoneName.

In the Preview Scene Settings window, we then specify to use the Retarget Asset.



Animation Blueprints

Data from Live Link can be applied directly inside Animation Blueprints:



This is achieved by creating a Live Link Pose node inside the AnimGraph of an Animation Blueprint. The node has 2 properties:

Subject Name: The name of the subject in live link to stream data from

Retarget Asset: The Retarget Asset to use to apply the data from Live Link to the Skeleton that the animation Blueprint uses.

The output of the Live Link Pose node is a normal pose like any other pose node in an Anim Blueprint, and therefore can be manipulated like other poses (fed into Modifier or Blend nodes for instance).

While you can drive animation without the Live Link Pose node in the Editor, if you want to drive animation at runtime, you will need the Live Link Pose node set up in your Animation Blueprint.

Motion Controllers

Live Link can be used with Motion Controllers. The motion source property of a Motion Controller can be set to a subject within Live Link.



When set in this way, the position of the Motion Controller component is governed by the first transform of the subject.

The Motion Controller integration can also access custom parameters on the Live Link subject. These are passed by the curve support built into Live Link subjects. To access the values, it is necessary to derive a new Blueprint from MotionControllerComponent and override the OnMotionControllerUpdated function. During OnMotionControllerUpdated it is valid to call GetParameterValue on the Motion Controller.

Plugin Development

There are two paths for integrating with Live Link:

Building an Unreal Engine plugin that exposes a new Source to Live Link.

This is the recommended approach for anyone that already has there own streaming protocol.

Integrating a Message Bus endpoint in third-party software to allow it to act as a data transmitter for the built-in Message Bus Source.

This is the approach we have taken for our Maya and Motionbuilder plugins.

For more information, please see the Live Link Plugin Development page.

Maya Live Link Plugin

Prebuilt binaries of the Maya Live Link plugin are available from the Maya Live Link Plugin Unreal Engine 4 GitHub repository. Once you download and extract the zip files, you will see binaries for Maya 2016-2019 for Windows.

The Maya plugin is supplied in the Maya Module format. To install the plugin, copy the contents of the correct versioned folder within the zip file to your Maya Module folder. Once the Live Link plugin is installed in Maya and enabled, it will automatically show as a connection in the Unreal Editor. A window can be opened within Maya to access the streaming settings. This is spawned by the MEL command MayaLiveLinkUI and can be bound to a toolbar button.



At the top right is a display that shows whether this instance of Maya is connected to an Unreal client. Below Unreal Engine Live Link, is a list of all the Subjects currently being streamed. You can click the minus (-) button to remove a Subject, or add any currently selected item (or items) from your scene with the Add Selection button. You can also assign the type of data being streamed with the Stream Type option.

For a step-by-step guide on how to set up the Maya Live Link plugin, please see the Connecting Unreal Engine to Maya with Live Link How-to guide.

Motionbuilder Live Link Plugin

The Motionbuilder Plugin offers the same functionality as the Maya plugin and shows up in Editor as a connection in a similar way. It also has a custom UI for managing streaming:



Objects can be selected from the current scene and added to the streamed list (as shown above). From there, their names can be set in the Subject Name column and their Stream Type (Camera, Skeleton, for example) can be set. Streaming on the subject can also be enabled and disabled from here.

You can download the Motionbuilder Live Link Plugin binares from the Unreal Engine 4 GitHub repository.

For a step-by-step guide on how to set up the Motionbuilder Live Link plugin, please see the Connecting Unreal Engine to Motionbuilder with Live Link How-to guide.

ART Tracking Live Link Plugin

ART Tracking (Advanced Real-time Tracking) is supported through Live Link for the following use-cases:

Body trackers

Flystick trackers

Hand trackers

Human model

ART Tracking through Live Link provides the ability to leverage ART technology for various tracking purposes in applications such as VR, Augmented Reality and Motion Capture.

ART will be distributing a LiveLink plugin on the Marketplace and also hosting the latest development on Github.

Live Link

Getting Started

Configuring Camera Data

Live Link Settings

Encoder Data Settings

Physical Camera Settings

Live Link supports the FreeD data protocol, which is a commonly used protocol for camera tracking with 8 axes of data from the transform position, rotation, and lens. The FreeD protocol is supported by some specific Pan, Tilt, Zoom (PTZ) cameras, such as the Panasonic AW-UE150 and the Sony BRC-X1000, and can be a cost-effective way to add tracking data to your projects.



FreeD is an older protocol and doesn't support many of the new features that some cameras now include. Some features provided by this plugin may not be available depending on your camera model and what data it provides:

All cameras that support FreeD should support at least pan, tilt, and rotation.

Some may support focus, iris, and zoom (FIZ).

Some may support 3D tracked positions in the world.

We recommend referring to your camera manual for details on how it supports FreeD.

Getting Started

Follow these steps to set up camera tracking with Live Link FreeD.

Enable both the Live Link plugin and the Live Link FreeD plugins.



Go to Window > Live Link to open the Live Link window.

Select Source > LiveLinkFreeD Source and enter the IP Address and Port Number for the camera you're connecting. The default Port Number is 40000.



Not all cameras are set up the same. Refer to your camera's manual for how to connect to it and configure network parameters.

For some cameras, you will need to enable camera data over UDP, which sometimes is referred to as FreeD data. If the camera is set up to send camera data over UDP to the PC, the IP Address must be set to 0.0.0.0 and the appropriate port number.

Once the source is added and the camera is connected, the camera will appear as a Subject.



If a Subject doesn't appear, then the camera wasn't set up properly. Check the IP Address, the Port Number, and the settings on the camera for troubleshooting.

The FreeD protocol associates an ID with the camera which can't be modified in UE. Some cameras do have an interface to set their ID, however. Since Live Link requires Subjects to have unique names, it's important to make sure you have unique IDs when you're using multiple cameras with Live Link.

Verify the engine is receiving camera data by selecting View Options > Show Frame Data.



Add a Cine Camera (or other Camera Actor) to the Level.



Select your Camera Actor in the World Outliner to open its Details panel.



In the Details panel, choose Add Component. Search for and select Live Link Controller.



Select the LiveLinkComponentController that you added to your Camera and set its Subject Representation to your Live Link FreeD Subject. In this example, the Subject name is Camera 0.



Move the connected physical camera and verify the Camera Actor updates in the Level.

Configuring Camera Data

Most broadcast and cinematic cameras support the FreeD protocol but don't support all of its features. Because each camera provides different data, when you set up your camera with Live Link FreeD, you'll need to customize the settings for your device. You can set the parameters once, however, and save them as a Live Link Preset for future use.

The following sections describe how you can modify your incoming camera data correctly for your device.

Live Link Settings

The incoming data is in binary format so the Plugin handles how to interpret the data into the appropriate focus, iris, and zoom parameters depending on the camera model. You can modify how the Plugin interprets the data.

In the Live Link window, under the Subject section, select FreeD and modify the Source settings. The following table provides further details on the settings.



Setting

Description

Send Extra Meta Data

When enabled, the camera sends additional information per frame. This option can affect performance slightly.

Default Config

Customized configurations are provided for some camera brands. The following are the available options:

Generic

Panasonic

Sony

stYpe

Mosys

Ncam

The Generic option doesn't change any of the settings so you will need to modify them for your camera.

Focus Distance Encoder Data

Focus distance data from the camera. See Encoder Data Settings for details on the settings in this section.

Focal Length Encoder Data

Focal length data from the camera. See Encoder Data Settings for details on the settings in this section.

User Defined Encoder Data

Other data from the camera, typically aperture data. The FreeD spec refers to this as User Defined. See Encoder Data Settings for details on the settings in this section.

The following settings apply to the Encoder Data section they're located in. The available Encoder Data include: Focus Distance, Focal Length, and User Defined (typically Aperture data depending on the camera model).

Setting

Description

Is Valid

When enabled, the engine will use this encoder data.

Invert Encoder

When enabled, the incoming axis direction is flipped.

Use Manual Range

By default, the expected range of values is determined based on dynamic auto-ranging. When using the dynamic auto-ranging, you must calibrate the encoder by forcing the camera to reach its min and max values a few times. You must perform this calibration every time, even if you're using a Live Link Preset, since camera encoders aren't consistent.

Enable Use Manual Range to set your own range. If you switch to auto-ranging after setting the range values manually, the auto-ranging will reset those values.

Min

The minimum value for the expected range of values, when Use Manual Range is enabled.

Max

The maximum value for the expected range, when Use Manual Range is enabled.

Mask Bits

Applies a binary mask to the incoming data. The text box expects the mask in decimal format. Some camera manufacturers will encode multiple types of data, so set this field if there are specific bits you want the engine to ignore.

Physical Camera Settings

In addition to the settings in Live Link, you must modify the settings on the Camera Actor to match your physical camera parameters.

With your Camera Actor selected, go to its Details panel, and under the Current Camera Settings modify the following fields.



Set Lens Settings > Min Focal Length and Lens Settings > Max Focal Length to match the focal length range on your physical camera lens.

Set Lens Settings > Min FStop and Lens Settings > Max FStop to match the aperture range on your physical camera lens.

There's no way to set the max focus distance on the Camera. You can set the Focus Settings > Manual Focus Distance on the Camera Actor. This focus distance is a constant in the engine.

Steps

Results

Steps

In this section you will connect a Smart lens using an Ambient Master Lockit Plus device using Live Link.

The Smart lens on the production camera will be connected to the Master Lockit Plus and the Master Lockit Plus will connect to the Unreal Engine workstation network by Ethernet.

Click Settings > Plugins to open the Plugins Menu. Click the Virtual Production category and search for the LiveLinkMasterLockit plugin.



Enable the plugin and click Yes on the message window. Click Restart Now to restart the editor.





Once the editor finishes loading, go to the Live Link window and click + Source > MasterLockit. Enter the Master Lockit's IP Address and click OK.



Select the Master Lockit Device in the window and click View Options, then select Show Frame Data. Confirm the values are updating correctly in the Live Link section.



Select the CineCamera Actor in the World Outliner window and go to the Details panel. Select the Live Link Controller component and scroll down to the Live Link section. Click the Subject Representation dropdown and select your Master Lockit Device.



Select the Camera Component and scroll down to the Focus Settings. Verify that changing the focus and aperture on the physical camera updates those same settings in the CineCamera Actor.

Change the Focus Method setting from Manual to Disabled. This stops the focus changing on the CG Cinema Camera as focus is being controlled by the physical camera



In this guide you connected your Master Lockit Device by using Live Link and streamed Focus Iris and Zoom from a Smart Lens on the Production camera.

Steps

Results

Steps

Follow these steps if you are using a Preston system with your production camera.

In this example, the Preston MDR unit needs to convert the serial output to Ethernet. This is done by using a Tibo serial-to-Ethernet converter. This Ethernet connection needs to be on the same network as Unreal Engine. There are other hardware devices for streaming Preston data. Refer to the vendor for the relevant plugin or setup if sending Preston data using a different device.

Click Settings > Plugins to open the Plugins Menu. Click the Virtual Production category and search for the LiveLinkPrestonMDR plugin.



Enable the plugin and click Yes on the message window. Click Restart Now to restart the editor.





Once the editor finishes loading, go to the Live Link window and click + Source > PrestonMDR. Enter the Tibo's IP Address and Port Number 1001 and click OK.



Select your Preston subject from the list and set the Incoming Data Mode dropdown to Calibrated Data.



Select the Preston MDR device with the green circle. Open the View Options dropdown and change the setting to Show Frame Data. This will display live link data.



Change the focus and iris on the Preston hand unit to see the values for Aperture and Focus distance change and verify that these values match the values on the camera.

Select your CineCamera Actor in the World Outliner window and go to the Details panel. Select your Live Link Controller component and scroll down to the Live Link section. Click the Subject Representation dropdown and select your Preston subject.



Scroll down to the Camera Calibration section and click the Lens File dropdown. Select the Lens File for your camera.



Change the Focus Method setting from Manual to Disabled. This stops the focus changing on the CG Cinema camera as focus is being controlled by the physical camera by the value manually input using the Live Link Virtual Subject.



In this guide you set up and connected a Preston MDR using Live Link to stream Focus Iris and Zoom to the Lens File connected to the Cine camera in UE.

Getting Started

Reorienting Axis Mapping

Troubleshooting

Live Link supports devices exposed through a VRPN server that has OpenVR support. VRPN provides an abstraction layer for VR peripherals so that they all appear to have the same data reports. Because of the nature of VRPN, you can have multiple Live Link Subjects that map to the same device.

Getting Started

Follow these steps to set up your devices with Live Link VRPN.

Start your VRPN server.

The VRPN server must support OpenVR.

Launch Unreal Engine and open your project.

Enable the following plugins:

Live Link

Live Link VRPN

Restart Unreal Engine.

In Unreal Editor's main menu, choose Window > Live Link to open the Live Link window.

Click Add Source and choose Live Link VRPN Source.



A user-selected Live Link VRPN Source which shows the Connection Settings panel. These are the default settings.

In the Connection Settings window:

Set IPAddress to the IP address and port number of the VRPN server. In this example, the VRPN server is running on the local computer using port 3884, so the text value is 127.0.0.1:3884.

Set Local Update Rate in Hz for the frequency to poll the VRPN server. The default is 120, and the max is 1000.

Set Device Name to the identifier used by the VRPN server for your device. It is better to use the serial number than the generic device identifier because the serial number won't change.

In this example, the VRPN server uses the identifier openvr/controller/1GNGH850VE0304_Controller_Left for the left VR controller.

Set Subject Name to a friendly name. This will be the Live Link Subject Name. In this example, the subject name is LeftController_VRPNTracker.

Set Type to one of the following:

Tracker: Returns the position and orientation of the device as an Unreal Transform.

Analog: Returns one or more analog axes in the 0 - 1 range, such as joystick or sliders from the device.

Dial: Returns a float to represent the rotation, such as a dial from the device.

Button: Returns an array of floats with 0 or 1 values.

Click Add.



A Live Link Subject with the given name appears under a VRPN section when the first data is received. In this example, the subject name is LeftController_VRPNTracker.



If your Live Link VRPN Subject doesn't appear, refer to the Troubleshooting section below for tips on how to make sure you're receiving data.

For Tracker type: Select an Actor in the level and add a LiveLinkComponentController to it. Set Subject Representation to the Live Link VRPN Subject. In this example, the subject is LeftController_VRPNTracker.



For the other types: Since the other types are floats, use them in Blueprints to modify the scene.

Reorienting Axis Mapping

Since VRPN doesn't enforce a standard axis mapping, Live Link provides controls for reorienting the axis mappings using Live Link preprocessors.

Follow these steps to change the axis mappings in Unreal Engine for your device.

In the Live Link window, click on the Live Link VRPN Subject.

Click View Options > Show Subject Properties.

Next to Pre Processors, click the Add (+) button to add a Live Link preprocessor.



Set the Pre Processors element to Transform Axis Switch and expand the section.



Change the Front, Right, and Up Axes to match the coordinate system of the device. Each VRPN server may have a different default axis mapping, and each device may have its own axis mapping. Refer to the documentation or configuration file for your VRPN server for details. In this example, the device uses -Z forward, +X right, and +Y up.



Once the axes are moving as expected, enable and set Offset Position or Offset Rotation to achieve the right orientation or position in the world, if necessary.



Troubleshooting

If your Live Link VRPN Subject doesn't appear when you add a Live Link Source, try the following tips to troubleshoot.

Make sure the IP address and port specified in Live Link match the VRPN server.

You can use the LiveLinkXR plugin on the same server to troubleshoot if the stream of data is correctly sent from VRPN.

In Live Link, select the Live Link VRPN Subject and click View Options > Show Frame Data to see what data Unreal Engine is receiving.



Developing for SteamVR

Live Link

Enabling LiveLinkXR

Source Settings

Adding a LiveLinkXR Source

Associating VR Sources with Blueprints and Meshes

Calibration

Using Vive Trackers without an HMD

Troubleshooting

SteamVR Issues

The purpose of Live Link is to provide a common interface for streaming and processing animation data from external sources into Unreal Engine (UE). It is designed to be extensible through Unreal Plugins, allowing third parties to develop new features—hopefully with no need to make and maintain Engine changes.

LiveLinkXR extends this functionality to be used with XR devices. By using the LiveLinkXR plugin, you can add XR sources such as Vive Trackers and HMDs for use with the Live Link tool.

LiveLinkXR currently only supports SteamVR. If you are using LiveLinkXR and SteamVR you will not be able to use the Virtual Scouting tools because these tools now require only the OpenXR plugin to be active.

This article aims to walk you through setting up and configuring the LiveLinkXR plugin, adjusting the tools various settings, and to provide potential troubleshooting and workaround steps.

Enabling LiveLinkXR

Click the Edit tab to expand., Under the Configuration heading, click Plugins.



Use the search box to find the LiveLinkXR plugin, then click Enabled.



You may also need to enable the SteamVR plugin.

Click Yes in the box that appears.



Click Restart Now to restart UE with the plugin enabled.



Launch the Live Link tool by expanding the Window tab and clicking Live Link.



Once opened, if you expand the Source window, you will see LiveLinkXR listed as a new source.



Expand the LiveLinkXR Source option to view the various settings associated with it.



Source Settings

The LiveLinkXR Source settings allow you to adjust data sources and adjust the local update rate.

Setting Name

Purpose

Track Trackers

Track all Vive Trackers within SteamVR.

Track Controllers

Track all controllers.

Track HMDs

Track all HMDs.

Local Update Rate in Hz

Update rate (in Hz) at which to read the tracking data for each device.

Adding a LiveLinkXR Source

Although the process below was drafted using a Vive HMD with trackers, you should be able to use Live Link XR with any VR device that is supported by SteamVR.

SteamVR must be running to add a new LiveLinkXR source. Consult the SteamVR Troubleshooting page for help setting up SteamVR.

Once the LiveLinkXR plugin is enabled and you have adjusted the settings to match your needs, you will be able to add a XR source.

Launch the Live Link tool, expand the Source window, and under LiveLinkXR Source click Add.



If you have configured everything correctly, after clicking Add you should see items added to the tables in the Live Link tool. These items should correspond to the Data Sources you have selected under the Data Source settings.



The IDs found under Subject Name are a combination of the device type and the internal hardware serial number for the device. The internal hardware serial number is different from the serial number printed on the device itself. Some devices may not have internal serial numbers.

Associating VR Sources with Blueprints and Meshes

After you enable the LiveLinkXR plugin, your project will gain access to LiveLinkXR Blueprints and Meshes. These valuable premade items can help you get started. This section will walk you through locating and using those items.

Navigate to the Content Browser, expand the View Options menu, and select Show Engine Content and Show Plugin Content.



You should immediately see new items appear within the Content Browser navigation window.



Within the Content Browser, locate the LiveLinkXR Content folder and open the Blueprints folder under it.



Drag the BP_LiveLinkXR_DataHandler into your scene.

You can verify the tracking data you're receiving with the Toggle Debug Vis option. Do this by using the Toggle Debug Vis debugging tool.

After you have set up sources in Live Link and have dragged the BP_LiveLinkXR_DataHandler into your scene, select the handler from the World Outlier and navigate to the Details panel.

Expand the Default category and click the Toggle Debug Vis button.



A BP_LiveLinkXR_DebugVis debug visualization should appear in your level for each Live Link Source that you have set up.

These items should then move around based on their real-world movements.

Select BP_LiveLinkXR_DataHandler from the World Outliner and navigate to the Details panel.



To add a new entry, expand the Default section under Details, and click the Add (+) button next to Subject Name to Attached Actor .



In the textbox next to the new element, enter the Subject Name from the Live Link window.



Repeat this process as needed for all sources that you want to track.

Use the dropdown menu next to your element to map the tracking data to the Object or Actor in the scene.



Calibration

You can use the Calibrate button next to Toggle Debug Vis to set a new tracking origin relative to an arbitrary actor in the world. When you click it, the transform from the LiveLink Subject Calibration Subject Name is used to calculate a new world origin transform relative to the transform of the Calibration Target Actor.

To take advantage of the Calibrate feature, first select BP_LiveLinkXR_DataHandler from the World Outliner. In the Details panel, select an actor in your level from the dropdown next to Calibration Target Actor.



After selecting the target actor, enter the Calibration Subject Name in the box provided. This should match one of the LiveLink Subject names being tracked.



After adjusting the settings, click the Calibrate button next to Toggle Debug Vis.

Notice that the relative tracking origin of the devices is now relative to your new calibration.





On the left is the location information for the BP_LiveLinkXR_DataHandler actor when initially dragged into the level. On the right is the location information after calibration relative to another actor in the level.

Using Vive Trackers without an HMD

By default, you cannot use the Vive Trackers without an HMD. This section outlines a potential workaround that should allow you to use Trackers without an HMD within UE.

This process is a potential workaround that is unsupported by Valve, HTC, or Epic. It has the potential to stop working unexpectedly or cause unexpected issues with SteamVR. We recommend that you only attempt this workaround if you are an expert with SteamVR troubleshooting.

First, fully shut down Steam and SteamVR.

Ensure this by checking the Task Manager for any lingering Steam processes after closing the main program.

Locate the following file on your computer: <Steam Install Directory> /steamapps/common/SteamVR/drivers/null/resources/settings/default.vrsettings.



Copy the file and add "_BACKUP" to the end of the file extension.



There are a few ways to back up the files outlined in this process. Copying the original and changing the file extension is the method shown below.

Open the original default.vrsettings file in a text editor.

In the driver_null object, change the enable property value from false to true.



If using nDisplay, set windowWidth, windowHeight, renderWidth, and renderHeight to 0 (zero). This will help you to avoid the un-minimizable VR Composer window in the middle of the screen.

Save and close.

Locate the following file: <Steam Install Directory>/steamapps/common/SteamVR/resources/settings/default.vrsettings.



The file names are similar, but they are located in different folders.

Create a backup of the default.vrsettings file.



Under the steamvr heading, change the requireHmd setting to false.

Under the steamvr heading, change the forcedDriver setting to "null".

Under the steamvr heading, change the activateMultipleDrivers setting to true.

Once you have updated the correct settings, the file should look something like this:

Save and close the default.vrsettings file.

Launch Steam and SteamVR.

Because you have altered the SteamVR settings, you may need to run the Room Calibration setup again.

After completing Room Calibration, relaunch SteamVR and you should be able to track devices without the need for an HMD.



When you are ready to use the HMD again, close SteamVR, restore the edited files from the backups, and relaunch SteamVR.

Troubleshooting

SteamVR Issues

If your HMD, Controllers, or Trackers are not appearing in SteamVR, then they will not appear in UE. If you are having issues setting up your VR devices, it is recommended that you review the Steam VR Troubleshooting guide for assistance.

1 - Enabling the Live Link Plugin

2 - Enabling Maya Live Link

3 - Establishing a Connection to Unreal Engine

4 - Live Link Preview Controller

5 - End Result

In this How-to, we use the Live Link Plugin to connect Unreal Engine to Maya, which enables us to control our Skeletal Mesh and animations inside Maya while live previewing them on a rendered Skeletal Mesh in Unreal Engine in real-time.

Using the Live Link Plugin can speed up your animation workflow as you no longer need to export your content and import it into Unreal Engine to see how it looks. You can now work directly inside Maya, and through Live Link, preview what it will look like inside the Engine in real-time. In this How-to, we go through the process of getting Live Link set up for Maya, and control a Skeletal Mesh animation in Maya while previewing it in Unreal Engine.

For this guide we are using the Blueprint Third Person Template Project and Maya 2017.

Live Link works with other versions of Maya and other DDC tools. For more information, please refer to the Live Link Plugin documentation pages.

1 - Enabling the Live Link Plugin

Inside your project, from the Menu Bar under Edit, select Plugins.



Under the Animation section, click Enabled for Live Link, and Yes on the confirmation window, then restart the Editor.



This will enable the Live Link plugin, which can be used to connect to external DDC tools. In order for your DDC tool to connect to Unreal Engine, you will need to enable the corresponding plugin. For this How-to, we are focusing on Maya, and need to enable the plugin inside Maya.

Download the MayaLiveLink Code Plugin files from the Unreal Engine Marketplace.



Unless you've tweaked your install locations, these files will likely be installed to: C:\Program Files\Epic Games\UE_4.25\Engine\Plugins\Marketplace\MayaLiveLink.

Copy the folder for your version of Maya, then navigation to your Maya installation folder, and paste it in the plug-ins folder.



There are pre-built binaries for Maya versions 2016-2019, for this guide we are using Maya 2017.

In the next step, we will enable the Live Link plugin inside of Maya, and open the Maya Live Link UI window. This enables you to see the connection status to a running version of the Unreal Engine Editor.

2 - Enabling Maya Live Link

Open Maya, then under Windows and Settings/Preferences, select Plug-in Manager.



Click the Browse button, and then navigate to the copied MayaLiveLink folder, then add the .mll file.



Repeat the previous step and add the .py file from the Plug-in Manager.



Once added, you will see the plugins inside the Plug-in Manager as Loaded.

In the MEL console in the lower-left of Maya, enter MayaLiveLinkUI then press Enter.



The MEL console command is case-sensitive, so you will need to enter it as specified in the step above.

This will open the Maya Live Link UI Connection Status window.



In the upper-right of the window, the connection status is displayed to indicate if you are connected to a running version of the Unreal Engine Editor. You can use the lower window to name and add/remove Subjects that you wish to stream to Unreal Engine, which we will do later in this guide.

For now, we are not connected, however in the next step we will establish a connection to Unreal Engine. We will also export an animation asset and Skeletal Mesh that we can use to work with in Maya, then add it as a Subject to stream back to Unreal Engine for live previewing.

3 - Establishing a Connection to Unreal Engine

In Maya, select an object (i.e. a cube, sphere, etc.) and select "Add Selection in Maya Live Link UI." This will help UE recognize the newly enabled plug in.

Inside the Unreal Engine Editor, from the Menu Bar under Window, select Live Link.



In the Live Link window, click the Source button, then under Message Bus Source, select your Maya Live Link source and click Ok.



If you return to Maya, the Maya Live Link Connection Status window will update to reflect the new connection status.



Now that we are connected, we need a Subject to preview and test the connection.

Inside Unreal Engine, in the Content/Mannequin/Animations folder, open the ThirdPersonRun asset.

From the Toolbar, click Export Asset and select Preview Mesh.



Select Yes to export the Skeletal Mesh, enable Export Preview Mesh, choose an export location, then select Export at the FBX Export Options window.



Inside Maya, under File select Import, and import the FBX asset from the previous step.



Switch to Animation mode, and then select the Root bone for the character.



In the Maya Live Link UI window, click the Add Selecton button.



This will add the selection (or selections) as the Subject to stream to Unreal Engine.



The plugin knows that this is a joint hierarchy and labels the Subject as a Character. The name Root is the name of the Subject which you can change in the text entry box. This name will be the Subject name reflected inside Unreal Engine. By default, the Stream Type will be set based on the type data being streamed. You can change this to stream over the information you want inside the Stream Type setting.

If you have more than one Network Adapater in your machine and want to specify which one to recieve data from, you will need to specify the Unicast Endpoint in your Project Settings.

Maya is now set up to stream our Subject to the Unreal Engine Editor. In the next step, we will set up Unreal Engine to receive the streamed Subject so that we can start to live preview the content from Maya inside Unreal Engine.

4 - Live Link Preview Controller

Inside Unreal Engine, under the Content/Mannequin/Character/Mesh folder, open the SK_Mannequin asset.

Click the Preview Scene Settings tab, and then under Preview Controller, select Live Link Preview Controller.



Under Live Link Subject Name, click the drop-down menu, and select root.



The viewport will update and the character will enter the pose that the character is using inside Maya.

Enable the Enable Camera Sync option.



This will sync Unreal Engine's camera to the last viewport camera used inside Maya. Anytime you move the camera in Maya, Unreal Engine's camera will update to match.

Go to your Editor Preferences, and under Performance, disable the Use Less CPU when in Background option.



This option throttles background performance on the Editor and stops the Editor from rendering while Maya has focus, which will prevent us from seeing the updates in real time.

If you want the Editor to continue evaluating while you are idle, you can also adjust the Valid Engine Time in the Live Link Connection window to give you more time before the Editor stops evaluating.

Return to Maya and scrub the animation, or move the camera in the viewport.

For this example, we are using the Live Link Preview Controller, however you can also stream data through the Live Link Component attached to an Actor.

5 - End Result

As you scrub the animation in Maya or move the camera, the character and camera movement in Unreal Engine will update to match what you see in Maya. A typical workflow would be to author your content in Maya, export the Skeletal Mesh and import it into Unreal Engine, follow the connection setup steps outlined in this guide to establish a connection, then preview animations authored in Maya on the Live Link Subject in Unreal Engine.

You can also make changes to your animations and those will be reflected in real-time inside Unreal Engine on the Live Link Subject.

Above, we re-key the position of the head so the character is looking around while running, and see what it would look like inside Unreal Engine. While this is a simplistic example of how to use the Live Link Plugin, there are many more advantages to this feature which you can find on the Live Link Plugin documentation page.

If you are using the Maya Live Link Plugin prior to 4.23, when driving a camera through Blueprint, it may not have the correct transform. You can fix this by adding an Add Relative Rotation node set to 0, 180, 90 as indicated below.



Live Link Presets

Live Link Components

Live Link Skeletal Animation Component

Live Link Controller Component

Using a Live Link Controller

Transform

Camera

Light

Applying a Controller to an Actor

Common Blueprint Nodes

Get Live Link Subjects

Evaluate Live Link Frame

Using Data from Evaluate Live Link Frame

Get Basic Data

Get Curves

Get Metadata

Get Root Transform

Get Transform By Index

Get Transform by Name

Number of Transforms

Get Transform Names

Applying a Live Link Preset with Blueprints

Live Link provides users with the ability to stream various types of data from a variety of sources and apply that data directly to Actors within their level. To improve these workflows, Unreal Engine uses several features designed to streamline the process of applying Live Link data to the Actors in your level.

Live Link Presets save your source settings for later use.

The LiveLink Controller Component enables using LiveLink controllers. These simplify applying Live Link information to your Actors and several Blueprint nodes have been added to facilitate gathering this data.

The LiveLink Skeletal Animation Component exposes the OnLiveLinkUpdated event node which retrieves information on Subjects and Sources every time Live Link updates, and can perform a number of other functions through Blueprint.

For more information on enabling Live Link and setting up your connections, please see the Live Link Plugin documentation.

Prior to Unreal Engine version 4.23, the LiveLink Skeletal Animation Component was called the Live Link Component.

Live Link Presets

Unreal Engine obtains Live Link data from a variety of sources created in the Live Link Connection window. Once created, these sources can be saved as Presets and accessed via Blueprints using the Apply to Client node.



Using this node, a Live Link preset can load when your application launches.

Live Link presets can also be activated via the Presets button in the Live Link panel or in the Project Settings by setting the Default Live Link Preset in the Plugins - Live Link section of the menu. A preset may also be applied via command line using ‘LiveLink.Preset.Apply Preset=/Game/Folder/MyLiveLinkPreset.MyLiveLinkPreset'.

Live Link Components

Live Link Skeletal Animation Component

When you add a Live Link Skeletal Animation Component to an Actor Blueprint from the Components panel, it doesn't get parented to other Components. It sits inside your Blueprint and gives you access to the On Live Link Updated Event.



The On Live Link Updated event is triggered any time the Component is updated, including inside the Editor.



The On Live Link Updated node effectively takes the place of your Tick Event, but it runs inside the Editor as well. For example, if you want to drive some data live inside the Editor, this node will support that.

Live Link Controller Component

The Live Link Controller Component is a component that sits inside of your character Blueprint and provides the ability to use Live Link Controllers. These controllers automatically fetch data from your Live Link subject and apply it to a corresponding component in your Actor via a Live Link Controller.



Using a Live Link Controller

Live Link controllers provide a quick method of taking Live Link data and pushing it to an Actor in your scene. Each controller consumes data from a Live Link subject and applies it automatically to the actor of your choice. Controllers come in three different varieties defined by the role:

Transform

Camera

Light See below for details on the different Live Link controllers.

Transform

The Transform controller quickly captures and applies transform data from a Live Link subject to an Actor in your level.



This controller provides the following options:

Setting

Description

World Transform

Sets the transform of the component to world space. Uncheck for local space.

Use Scale

Uses scale data from Live Link.

Sweep

Sweeps the root component and checks for blocking collision, triggering overlaps along the way and stopping short of the target if blocked.

Teleport

Teleports the physics state (if physics collision is enabled).

If checked, physics velocity remains unchanged.

If unchecked, physics velocity is updated based on the change in position.

Camera

The Camera controller applies camera settings and movement data directly from a Live Link subject with the camera role to a Camera Actor in your level.



Camera settings that can be animated include:

Field of View (in degrees)

Aspect Ratio (width / height)

Focal Length

Aperture of the camera in terms of f-stop

Focus distance of the camera in cm (works only with manual focus)

Projection mode of the camera (perspective, orthographic, etc)

Light

The Light controller applies Light settings directly from a Live Link subject with the Light role to a Light Actor in your level.



Light settings that can be animated include:

Color temperature (in kelvin).

Total energy (in lux).

Filter color.

Inner cone angle (in degrees for a spotlight).

Outer cone angle (in degrees for a spotlight).

Light visible influence (for pointlight and spotlight).

Soft radius for light source shape (for pointlight and spotlight).

Length of light source shape (for pointlight and spotlight).

Additional controllers may be added or created using external plugins. For more information on external Plugins, please see our Plugin documentation.

Applying a Controller to an Actor

Applying a Live Link Controller begins with adding the Live Link Controller component to your Actor:



This section requires that you have connected to a Live Link source. For more information on connecting to your source, please see our Live Link Plugin documentation.

Use the following steps to add the component through the Details panel:

Select the Actor in your level.

In the Details panel click the + Add Component button and search for the Live Link Controller component.

Once added, select the component from the component list and open the Subject Representation drop down menu. Select the subject from the list that you want to use as the source of data for this Actor. Unreal will select the Component to Control for you based on your selection. This can be adjusted if needed.

With the controller set up, your Actor will begin receiving data from the selected Live Link subject automatically.

Common Blueprint Nodes

Live Link data can be accessed via a variety of Blueprint nodes.

Get Live Link Subjects

There are times when you will need to get a list of Subjects to use with the Evaluate Live Link Frame node. When this happens, you can use Get Live Link Subjects:



This returns an array of Subjects that the Evaluate Live Link Frame function will find valid.

Evaluate Live Link Frame

Calling the Evaluate Live Link Frame function enables you to get the Live Link data associated with the provided Subject Name. This function gives you execute pins for whether the current frame is valid or not, as well as static and frame data that can be accessed from the Data Result output. This data is determined by the type of Role chosen to evaluate the subject.

The example below shows data being accessed directly from the data structure pin.



Using Data from Evaluate Live Link Frame

Evaluate Live Link Frame opens the way to using several Blueprint functions to evaluate the data that it provides. The resulting data depends on the Role being evaluated. When the Animation Role is evaluated, you see the following:

Get Basic Data

Get Curves

Get Metadata

Get Root Transform

Get Transform by Index

Get Transform by Name

Number of Transforms

Transform Names

Get Basic Data

The Get Basic Data node returns the base structure of the Subject that is stored in the current Subject frame.



Get Curves

The Get Curves function enables you to get all the Blend Shapes or Animated Curves and returns a Map of the Name to Value for each entry.



You could use a Find and enter a Name to retrieve the value of a curve (or use the boolean to determine if it was found or not).



Get Metadata

The Get Metadata function returns the Subject Metadata structure stored in the Subject Frame which you can break apart to retrieve information:



String Metadata is a Map to named strings on the subject, for example you may want to pass through the type of an object being streamed as a named string. Also included with the metadata is the Scene Timecode and Scene Framerate, whose structures you can break to obtain the information you need.

Output

Description

String Metadata

A map of named strings used to provide additional information about a frame or subject, for example "Type": "Camera".

Scene Timecode

Timecode value associated with the current frame.

This is not guaranteed to be unique, for example editing a single frame in MotionBuilder will result in that frame's timecode being sent for multiple frames.

Scene Framerate

Corresponding Framerate to the Scene Timecode.

Get Root Transform

The Get Root Transform function will return the Root Transform for the Subject Frame as a Live Link Transform (or the identity if there are no transforms).



This returns a Live Link Transform instead of a standard Transform as you can call additional functions on it (outlined below):

Function

Description

Child Count

Returns the number of Children for a given Live Link Transform.

Component Space Transform

Returns the Transform value in Root Space for a given Live Link Transform (relative to the root of your model).

Get Children

Returns an array of Child Live Link Transforms for a given Live Link Transform.

Get Parent

Returns the Parent Live Link Transform if one exists or an Identity Transform if no Parent exists.

Has Parent

Returns whether a given Live Link Transform has a Parent Transform.

Parent Bone Space Transform

Returns the Transform value in Parent Space for a given Live Link Transform (how it's stored internally and relative to whatever the Parent bone is).

Transform Name

Returns the Name of a given Live Link Transform.

Get Transform By Index

The Get Transform By Index function returns the Live Link Transform stored in a Subject Frame at a specified index (the function returns an Identity Transform if the Transform Index is invalid).



Get Transform by Name

The Get Transform by Name function is similar to Get Transform by Index but takes in Transform Name data.



Number of Transforms

The Number of Transforms function returns the number of Transforms within the Subject Frame.



One use case for this would be to use it in conjunction with the Get Transform By Index to loop through and retrieve each of your Live Link Transforms (similar to the example below):



Click image for full view.

Get Transform Names

The Get Transform Names function returns an array of names for all the transforms in a frame.



Applying a Live Link Preset with Blueprints

A common use of Blueprints with Live Link is to use the Apply to Client node to assign a Live Link preset to a Skeletal Mesh at runtime:



Start by creating your Live Link preset in the Live Link Panel. For more information on presets, please see our Live Link Plugin documentation.

In your character blueprint, create a reference to your preset by making a new variable and setting the Variable Type to Live Link Preset in the Details panel.

Compile your Blueprint and set the default value of your new variable to your saved Live Link Preset.

Drag your variable into your Blueprint and choose Get from the menu.

Drag off from the variable and search for the Apply to Client node.

Connect the Event Begin Play node to Apply to Client.

Live Link Source

Message Bus source

Using the Live Link Message Bus Framework

There are two paths for integrating in Live Link:

Building an Unreal Engine plugin that exposes a new Source to Live Link.

This is the recommended approach for anyone that already has there own streaming protocol.

Integrating a Message Bus endpoint in third-party software to allow it to act as a data transmitter for the built in Message Bus Source.

This is the approach we have taken for our Maya and Motionbuilder plugins.

If you have more than one Network Adapater in your machine and want to specify which one to recieve data from, you will need to specify the Unicast Endpoint in your Project Settings.

Live Link Source

A Live Link source provides animation data to the Live Link client. A source plugin needs to provide the following:

A Source Factory Base Class ULiveLinkSourceFactory

This is how Live Link knows about the sources it can use. The source factory must be a UObject and derive from ULiveLinkSourceFactory. The factory provides functions to create sources and create custom editor UI for source creation. Source factories are automatically picked up by the client (there is no manual registration process).

Your source factory must override the following functions:

GetSourceDisplayName - Returns a localized string for the source name

GetSourceTooltip - Returns a localized string for the source UI tooltip

CreateSourceCreationPanel - Returns a reference to a slate widget to be used to create the source.

OnSourceCreationPanelClosed - Is called when the client is done with the source creation widget. The bCreateSource parameter tells the source factory whether it should use the contents of the UI to create a source or not.

A Source object (Base Class ILiveLinkSource)

This is the object that manages data transfer into the client from the outside world. A source must derive from ILiveLinkSource. It is created by the source factory and is responsible for passing animation data to the client and managing its data connection lifetime.

Your source must override the following functions:

ReceiveClient - Is called when a source is created

IsSourceStillValid

RequestSourceShutdown - Called to ask the source to close. Usually connection cleanup will happen here. Can return false if more time is needed to clean close the connection

The following are used by the client UI:

GetSourceType - Return localized string representing the source type

GetSourceMachineName - Return string representing source ident (MachineName, IP Address, etc.)

GetSourceStatus - Return a localized string for source status.

Message Bus source

An example of what is required to create a new source can be found in the editor by looking at the following classes in /Engine/Plugins/Animation/LiveLink/Source/LiveLink:

FLiveLinkMessageBusSource

ULiveLinkMessageBusSourceFactory

SLiveLinkMessageBusSourceEditor

These classes make up the Message Bus Live Link source that is built into the Live Link plugin. The message bus source uses a custom message bus protocol to allow third party apps to transfer animation data to the engine.

Using the Live Link Message Bus Framework

To make use of the Live Link Message Bus framework (like the Maya and MotionBuilder plugins, the software needs to include the core libraries of Unreal Engine and create a LiveLinkProvider).

This automatically handles communication with one or more Unreal Engine instances. All the software then needs to do is use the following two functions to tell the provider about the streamed data:

UpdateSubject - Gives a description of the subject to Live Link (name and joint hierarchy).

UpdateSubjectFrame - Gives a frame of data about the subject to Live Link (current transform, any named float parameters we want to associate and a time/frame number).

An example of this approach can be found in Engine\Source\Programs\MayaLiveLinkPlugin\.

Enabling Live Link Curve Debugger

Using Live Link Curve Debugger

When streaming content into Unreal Engine using the Live Link Plugin, you may want to view the various curves and values that are active. The Live Link Curve Debugger is a tool that enables you to quickly see what the output is of various Live Link curves are in an easy to debug manner.

Enabling Live Link Curve Debugger

In order to use the Live Link Curve Debugger, you will first need to enable it from the Plugins menu:

From the Edit menu, select Plugins.



In the Plugins menu under Animation, enable both Live Link and Live Link Curve Debug UI options, and restart the Editor.



From the Window option, under Developer Tools, select Live Link Curve Debugger.



The Live Link Curve Debugger window will open.



Using Live Link Curve Debugger

Once connected to Maya with Live Link or Motion Builder with Live Link, the content you have in your application will be accessible within Unreal Engine, include any animation curves. With the Live Link Curve Debugger, you can see a list of all the curves and curve values for the currently selected Subject Name which you can define by clicking the Live Link Subject Name drop-down menu and selecting your Subject.



Once you select a Subject, any curves will be displayed in the window along with their values.



Click image for full view.

If you haven't specified a Subject Name, as soon as one connects with some curves, the debugger will switch to that one. You can change this selection by clicking the Live Link Subject Name drop-down (in Editor or a Desktop build) or by typing LiveLinkDebugger Next in the command-line to cycle through different subject names (on other client builds)

Inside a client you can also use the command-line to show the Live Link Debugger with the command: LiveLinkDebugger Show

Optionally you may specify a Live Link Subject Name to start with in the command-line by using the command LiveLinkDebugger Show SubjectName (the name of your Subject).

MotionBuilder Setup

Install Plugin

Broadcast Live Link

Unreal Engine Setup

Setup Connection

Preview Live Link

MotionBuilder Settings

Linking to Other Machines

Broadcast Satellites

Multicast

Using Live Link, you can stream content from MotionBuilder into Unreal Engine in real time, in order to preview your content in Unreal without needing to export and import. There are also a variety of settings for controlling the session's IP address and casting.



This document provides an overview of how to set up a Live Link session between MotionBuilder and Unreal Engine, as well as the settings available to you.

You have read Live Link and have enabled the Live Link plugin.



You have a Skeletal Mesh Actor for use in Unreal Engine and MotionBuilder. If you do not have one, then you can create a project using the Third Person Template, and Export the SK_Mannequin Skeletal Mesh to FBX in order to Import to MotionBuilder

You can optionally Characterize your character in MotionBuilder in order to use the Control Rig.

MotionBuilder Setup

Follow these steps to set up Unreal Live Link in MotionBuilder and begin broadcasting a Live Link signal.

Install Plugin

You will need to download and install the MotionBuilder Live Link plugin. To do this, first navigate to the MotionBuilder Live Link Marketplace page and download the plugin.



When the plugin is installed, it will be located in the Plugins folder of your Unreal Engine install directory. By default, it is located under the following path:

Within that folder, you can navigate to the Binaries folder and view the plugins available for each MotionBuilder version.



Now you will assign the plugin path to MotionBuilder. In MotionBuilder click Settings > Preferences in the main menu bar to open the Preferences window, and navigate to the SDK category. Click Add and browse for the version folder that matches your MotionBuilder version. Restart MotionBuilder afterward.



After restarting MotionBuilder, you should now see the UE - LiveLink entry in the Devices category of the Asset Browser tab.



Broadcast Live Link

Ensure your MotionBuilder scene contains the characters you want to use, then drag the UE - LiveLink plugin into the viewport.



This will open up the Live Link Connection window, which you can find under the Devices section of the Navigator.



Click the Subject Selector (...) button, expand and select your character's Root Bone, then click Add. You must ensure the selected root bone also matches the root (top-most) bone from the imported Skeleton in your project.



This will add your character as a Subject to stream over to Unreal Engine. You can optionally enable Stream Viewport Camera. This will make MotionBuilder's camera streamed as a Live Link subject to Unreal Engine, from which you can select it as a source to drive the editor camera.



You can optionally rename your Subject by editing the Subject Name field. This will help distinguish it in the Live Link broadcast.



Click the button next to Online to enable content streaming. The Online status button will change from red (Offline) to green (Online). At this point, MotionBuilder is now broadcasting a Live Link signal.



When MotionBuilder loses focus and becomes a background application, its performance will be throttled, which could lead to stuttering during the streaming process. To prevent this from occurring, enable the Always refresh viewer option, located in the Navigator's System menu.



Unreal Engine Setup

Follow these steps to connect Unreal Engine to your MotionBuilder Live Link broadcast, in order to preview the connection on a character.

Setup Connection

With MotionBuilder running in the background, open Unreal Engine and select Window > Live Link from the main menu bar. This will open the Live Link Connection Window, which will enable you to connect to the running instance of MotionBuilder.



Click the + Source button, then select your MotionBuilder broadcast signal from Message Bus Source.



The Connection Window will update to show the connected Source Type, Subjects, and Status.



Refer to the Live Link Overview page for more information on Live Link Options, Roles and Status Indicators.

Preview Live Link

You can now preview the Live Link connection on your character. Open your character's Skeletal Mesh asset from the Content Browser.



In the Preview Scene Settings tab, set the following properties:

Preview Controller: Live Link Preview Controller

Subject Name: Subject name from MotionBuilder

Enable Camera Sync: Enabled



Your MotionBuilder Subject is now connected to this window and will stream data. The MotionBuilder viewport will also stream to this view if Enable Camera Sync and Stream Viewport Camera are enabled from MotionBuilder.



You can alternatively use Blueprint functions to establish a connection instead of manually connecting through the Live Link window. Instead of using a Preview Controller, you can also use a Live Link Component attached to an Actor, or the Live Link Pose node in an Animation Blueprint.

MotionBuilder Settings

The MotionBuilder Live Link Plugin contains various advanced settings for controlling your Live Link casting behavior. To access these settings, click the Settings tab in the Live Link Connection window.



Linking to Other Machines

By default, using Live Link to connect MotionBuilder to Unreal Engine works as long as the session is running on the same device. If you are on a local area network where multiple devices are being used, and you want to broadcast to a different device, then you will need to use Unicast and Static Endpoints with explicit Local IPv4 Addresses set on them.

The Unicast Endpoint can be considered as one end of the Live Link bridge, whereas Static Endpoints are the other end of the bridge. Together they form an active Live Link connection.

To set up a Unicast Endpoint, copy your IPv4 Address into the Unicast Endpoint property. To get your IPv4 Address, you can type "ipconfig" into a Windows Command Prompt window to view and copy it. You must also specify a port number at the end of the address.



Port 6666 is reserved and cannot be used for Endpoints.

In Unreal Engine, on the other receiving PC, open the Project Settings window by clicking Edit > Project Settings and navigate to the UDP Messaging panel. In the Transport category, expand the advanced details and input the same address and port from the host machine's Unicast Endpoint in the Static Endpoints property.



You should now be able to receive the remote Live Link source when adding sources to the Live Link Connection Window.



The inverse of this process will work as well. You can instead set a Unicast Endpoint in the UDP Messaging Project Setting and set the Static Endpoint in MotionBuilder.



Broadcast Satellites

Rather than a single MotionBuilder live link instance broadcasting to multiple Unreal Engine destinations at the same time, you can set up a single Unreal Engine receiver to re-broadcast the live link source to other machines. This can be useful if the live link source is located far away from all receivers, or has limited bandwidth.



To enable this behavior, first select your live link source and subject in the Live Link Connection Window and enable Rebroadcast Subject.



Next, you will need to set a Unicast Endpoint in the UDP Messaging Project Setting on the machine that is performing the rebroadcast.



Now when selecting Live Link sources from other machines, you can choose the re-broadcasted source from an Unreal Engine instance.



Multicast

Multicast is an internet specification through which clients can participate in network communication. Multicast is represented using Class D addresses which are different from the standard class address space that you usually see in endpoint to endpoint communication. Multicast addresses range from 224.0.0.0 and to 239.255.255.255.

Clients can subscribe to the multicast group that tells the router, switch, or operating system that it is interested in multicast messages on that given IP. Unreal Engine uses multicast group 230.0.0.1 at port 6666. On startup, Unreal Engine will transmit a signal to the network that it would like to join the 230.0.0.1:6666 multicast group. Any multicast message received with that specified IP and port will then be assigned to that Unreal Engine instance inbound socket for processing by the engine.

The purpose of the multicast address is to notify other Unreal Engine instances about the presence of other Unreal Engine instances on the network. This is done using a discovery message that is sent on the multicast socket. The discovery message will be received by the other instances and contained within that message is the specific IP or port that can be used to directly communicate with the Unreal Engine instance. Direct communication will then occur using this known endpoint (IP and port) and no further communication will occur over the multicast group. This is equivalent to manually adding the static endpoint. The multicast mechanism enables this automatically.

Typically most routers will not propagate multicast messages beyond the local area network (LAN) unless they are configured to do so. In most cases, you can only discover Unreal Engine instances on the same local area network.

Live Link is generally not aware of multicast communication when it is happening. All of this network communication occurs through the message bus and using UDP messaging. Live Link is made aware of the available endpoints through its interaction with message bus and when sending its own discovery message via the message fus framework. All of the endpoints that have been discovered will be made available to Live Link as receivers and Live Link will send its discovery message to those receivers.

If you want to change the multicast range group, it will need to be changed in both the UDP Messaging Project Settings and the Live Link plugin Engine.ini file.

You can locate Multicast Endpoint** in the UDP Messaging Project Setting.



You can locate the MotionBuilder live link plugin Engine.ini file in your Unreal Engine installation directory, by navigating to: ...\Engine\Plugins\Marketplace\Engine\Programs\MobuLiveLinkPlugin\Saved\Config\Windows\Engine.ini

Once the Engine.ini file is opened in a text editor, you must change the MulticastEndpoint line to be the same value as the setting in Unreal Engine.

The multicast group should not be modified unless you fully understand multicast networking.

Overview

Rewind Debugger Interface

Using the Rewind Debugger

Animation Blueprints

Pose Watch

Rewind Debugger Settings

Extensibility

Using the Rewind Debugger, you can record a gameplay segment of a project during runtime, and rewind the simulation to observe information about animation behaviors and interactions. Building off of the Animation Insights foundation, the Rewind Debugger provides a refreshed visual interface to debug animation content in Unreal Engine.

Enable the Animation Insights plugin. Navigate in the Menu Bar to Edit > Plugins and locate Animation Insights in the Animation section, or use the Search Bar. Enable the plugin and restart the editor.



Overview

When working with character animation systems in Unreal Engine, it can be difficult to isolate the source of a bug. Using the Rewind Debugger, you can record a segment of gameplay, and then scrub through the recording to debug animation content in a more functional and stable work environment.



Animation data is represented visually, on tracks that populate the Rewind Debugger Timeline after selecting a target object. The Rewind Debugger tracks can contain information about Animation Blueprints, Sequence playback, animation variables, notifies and more.



To open the Rewind Debugger window, navigate in the Menu Bar to Tools > Debug > Rewind Debugger.



You can view more precise animation data in the Rewind Debugger Details panel, after selecting a track from the Rewind Debugger Timeline. To open the Rewind Debugger Details panel, navigate in the Menu Bar to Tools > Debug > Rewind Debugger Details.



Rewind Debugger Interface

The Rewind Debugger panel is populated with a unique interface you can use to observe animation data while navigating recorded gameplay segments.



Feature

Image

Description

1. Project Simulation Controls



Controls the project's simulation with features such as Play, Pause, and Stop. For more information, refer to the Unreal Editor Interface documentation.

2. Rewind Debugger Camera Menu



Select the camera behavior for the gameplay recording playback. The Camera Modes are as follows:

Disabled: Disables camera movement, leaving the camera unattached and untethered to any game object.

Follow Target Actor: Locks the camera to the selected object from a pre-positioned location. You can position the camera anywhere in the level, and the camera moves along the same track as the selected object.

This option does not track the selected object, it moves the camera based on the same movement data as the character.

Replay Recorded Camera: locks the camera to the position it occupied in the simulation, following the same movements if there were any.

Eject the player control in the Project Simulation Controls before attempting to change the Camera Control Mode.

3. Object Outliner



After recording a gameplay segment, you can choose a game object from the Object Outliner dropdown menu to populate the Rewind Debugger panel.

After selecting a game object, the Object Outliner lists the selected object, and all child objects and components, including any that are created or destroyed during runtime as well as any attached controllers.

The Object Outline has the following tools you can use to assist in selecting game objects to debug, and in filtering their connected components.

Dropper Tool: You can use the Dropper tool to manually select a game object to debug in the Viewport.

Filter Menu: You can use the Filter Menu to filter the Object Outliner's list of components and child objects of the selected game object.

Some game objects are composed of many components, such as a Movement Component, Animation Blueprints, and more. Each of these components is listed as a child object in the Object Outliner with an associated track in the Rewind Debugger Timeline, and must be selected individually to see their respective data within the Rewind Debugger Details panel.

4. Playback Controls



Lets you control the playback of the recorded gameplay segment. You can Start and Stop the recording with the Record Button, as well as Play, Pause, and Scrub through the Rewind Debugger Timeline.

5. Rewind Debugger Timeline



After selecting a game object to debug, the Rewind Debugger Timeline populates with the selected game object's components and child objects. Each component or child object is given a track where you can visually see changes in its data, variables, and curve values during the recorded gameplay segment.

You can select a track in the Rewind Debugger Timeline to observe more precise animation data values in the Rewind Debugger Details panel.

By clicking and dragging the red playhead, you can scrub through the Timeline manually to observe the animation data changes in the Rewind Debugger Details Panel and Viewport simultaneously.

**6. Rewind Debugger Details Panel



The Rewind Debugger Details panel displays all available data depending on the selected track in the Rewind Debugger Timeline and the position on the Timeline. Displayed information can include variable values, boolean states, and more.

Depending on the track you have selected in the Rewind Debugger Timeline, contextual data populates the panel.

You can open the Rewind Debugger Details panel by navigating in the Menu Bar to Tools > Debug > Rewind Debugger Details.

Using the Rewind Debugger

To use the Rewind Debugger, first start the game simulation by clicking the Green Play Button in the Project Simulation Controls.

Click Record in the Rewind Debugger Playback controls to begin recording the project simulation.

To disconnect your cursor from the simulation, without stopping or pausing the simulation, use the hot key Shift + F1.



When you have recorded a gameplay segment, pause the simulation and eject the camera using the Project Simulation Controls.





The recording stops automatically when the simulation is paused.

The recorded section of gameplay is now prepared for use. You can begin debugging game objects by selecting a game object from the Object Outliner or by selecting your game object in the Viewport using the Dropper tool.

After selecting a game object, the Rewind Debugger Timeline contextually populates with tracks of animation data relevant to the game object's components and child objects. You can scrub through the Rewind Debugger Timeline with the Playhead or the Playback Controls, to see how the recorded animation data updates the game object in the Viewport.

For a quick readout of animation data values in the Timeline, hover over a timeline track to see a readout of the current value of the animation track at the position in time of the recorded segment.



Within the Rewind Debugger Menu you can also select a different Camera Mode to obtain a different view of the subject while debugging. For example, with the Disabled option, you can detach the camera and position it freely and observe your game object from any angle to assist in your workflow.



After making edits to your game object or animation system, you can simply reattach the game controller using the controller icon in the Project Simulation Controls, and resume the game to continue debugging. The Rewind Debugger continues recording gameplay when the game simulation is resumed, unless manually stopped.

Animation Blueprints

After obtaining a recorded gameplay segment you can double-click an Animation Blueprint component in the Object Outliner to open and attach the Animation Blueprint Editor in a new window. While scrubbing through the recorded segment, the Animation Blueprint Editor displays the recorded state of the selected Animation Blueprint corresponding to the recorded moment of the game object.



With this functionality, you can observe how the animation blueprint produces the Output pose at any moment of the recorded gameplay segment. You can observe Animation Blueprint nodes, variables, state machine positions and more.

Pose Watch

While within an Animation Blueprint, you can enable pose watching on Animation Blueprint Nodes to see each node's effect on the Output Animation Pose during the recorded gameplay. This can be extremely useful for understanding what influence each node has on the object's animation during the gameplay recording.



Animation Blueprint Nodes must be enabled to Pose Watch, before the Rewind Debugger records a segment of gameplay. Pose Watching can then be toggled while using the recorded gameplay segment.

Rewind Debugger Settings

Here you can reference the Rewind Debugger Settings, accessed in Unreal Engine's Project Settings. Open the Project Settings by selecting Edit > Project Settings in the menu. The Rewind Debugger Settings section is listed under the Plugins category.



Setting

Description

Camera Mode

Here you can view the current, saved Camera Mode. You can set the saved Camera Mode option within the settings, or within the Rewind Debugger Camera Menu. You can select from the following camera options:

Disabled: disables camera movement, leaving the camera unattached and untethered to any game object.

Follow Target Actor: locks the camera to the selected object from a pre-positioned location. You can position the camera anywhere in the level, and the camera will move along the same track as the selected object.

This option does not track the selected object, it moves the camera based on the same movement data as the character.

Replay Recorded Camera: locks the camera to the position it occupied in the simulation, following the same movements if there were any.

Should Auto Record on PIE (Play In Editor)

When enabled, the Rewind Debugger will automatically record gameplay when the game simulation has begun, as long as the Rewind Debugger is open. When disabled, gameplay recording will need to be manually activated.

Show Empty Object Tracks

When enabled, empty animation data tracks will still be visible in the Rewind Debugger Timeline. When disabled, all empty tracks will be hidden.

Extensibility

The Rewind Debugger's uses extend beyond the version packaged with the Animation Insights plugin. Teams can build and add their own custom tracks to Rewind Debugger to display their project specific components or gameplay elements.

An example of how the Rewind Debugger can be modified to fit a project's specific needs can be seen in the Pose Search plugin with unique debug tools designed for working with Pose Searching animations.



With both plugins installed, a custom Pose Search track is added to the Rewind Debugger when the selected character uses the Pose Searching node, which contains expanded Pose Search animation data to assist with debugging.



You can try out the Pose Searching feature, but it is Experimental, and we do not recommend shipping projects with it.

Testing and Optimizing Your Content

Multi Threaded Animation Update

Animation Fast Path

General Tips

As you construct your Animation Blueprints, there are some practices you should keep in mind to ensure the animation in your project runs as smoothly as possible. Some of these are enabled by default while others will require that you consider the approach you take in setting up your Animation Blueprints. Other efforts can be performed through C++ that will also grant you some control over how and when animations are updated, which can lead to improved performance.

Multi Threaded Animation Update

This allows more animation work to run in worker threads and is enabled by default which you can find in your Project Settings:

Inside the Project Settings under General Settings > Anim Blueprints, make sure Allow Multi Threaded Animation Update is enabled.



This controls whether by default we allow Animation Blueprint Graph updates to be performed on non-game threads. This also enables some extra checks in the Animation Blueprint compiler that will warn when unsafe operations are being attempted. Inside your Animation Blueprints, you will also want to make sure that it is set to Use Multi Threaded Animation Update.

Inside your Animation Blueprint under the Class Settings, make sure that Use Multi Threaded Animation Update is enabled.



The main driver behind this was to control data access more tightly across threads. To this end, much anim-graph-accessed data has been moved from UAnimInstance to a new struct called FAnimInstanceProxy. This proxy structure is where the bulk of the data on UAnimInstance is found.

In general, the UAnimInstance should not be accessed or mutated from within AnimGraph nodes (Update/Evaluate calls) as these can be run on other threads. There are locking wrappers (GetProxyOnAnyThread and GetProxyOnGameThread) that prevent access to the FAnimInstanceProxy while tasks are in-flight. The idea is that in the worst case, tasks wait for completion before data is allowed to be read from or written to in the proxy.

From the Anim Graph point of view, only the FAnimInstanceProxy can be accessed from animation nodes, not the UAnimInstance. Data must be exchanged with the proxy for each tick (either through buffering, copying or some other strategy) in FAnimInstanceProxy::PreUpdate or FAnimInstaceProxy::PreEvaluateAnimation. Any data that then needs to be accessed by external objects should then be exchanged/copied from the proxy in FAnimInstanceProxy::PostUpdate.

This is in conflict with the general use case of UAnimInstance where member variables can be accessed from other classes while tasks are in-flight. As a recommendation, try to not directly access the Anim Instance at all from other classes. Instead, the Anim Instance should pull data from elsewhere.

Example Custom Native AnimInstance

In the code block below is an example of how one would build a custom native AnimInstance class using the new FAnimInstanceProxy, granting access to the internal workings and avoiding copies of shared data between the proxy and the instance:

Animation Fast Path

Animation Fast Path provides a way to optimize variable access inside the AnimGraph update. This enables the engine to copy parameters internally rather than executing Blueprint code (which involves making calls into the Blueprint Virtual Machine). The compiler can currently optimize the following constructs: member variables negated boolean member variables and members of a nested structure.

The Animation Fast Path option is enabled by default inside the Project Settings:

Inside the Project Settings under General Settings and Anim Blueprints, make sure Optimize Anim Blueprint Member Variable Access is enabled.



To make use of Animation Fath Path, inside the AnimGraph of your Animation Blueprints, ensure that no Blueprint logic is being executed. In the image below, we are reading several float values which are being used to drive multiple Blend Space assets and a Blend resulting in our Final Animation Pose. Each node denoted with the lightning icon in the upper right corner are utilizing Fast Path as no logic is being executed.



If we were to change this network to include any form of calculation such as the example depicted below, the associated node would no longer be using Fast Path.



Above, since we are now executing Blueprint logic to generate the values feeding the TEST_Blend2D node, it is no longer using Fast Path (and the lighting icon will be removed).

Fast Path Methods

In order for your Animation Blueprints to use Fast Path, ensure that they either:

Access Member Variables Directly

Below we are using Fast Path by directly accessing and reading the value of our boolean variable to determine our pose.



In the next example, we are not using Fast Path as we are performing logic to determine if the boolean variable is equal to true.



Access Negated Boolean Member Variables

Below we are using Fast Path by reading the value of the negated boolean to determine our pose.



In the next example, we are not using Fast Path as we are performing logic to determine if the boolean variable is not equal to true.



Access Members of a Nested Struct

Below we break our rotator variable to directly access our Pitch and Yaw variables to feed our Aim Offset.



Access Members Using "Break Struct" Nodes

Below we use a Break Struct node to break our rotator variable into XYZ values to feed our Aim Offset.



Some Break Struct nodes like Break Transform will not currently use Fast Path as they perform conversions internally rather than simply copying data.

Warn About Blueprint Usage

To ensure that your Animation Blueprints are using Fast Path, you can enable the Warn About Blueprint Usage option which will cause the compiler to emit warnings to the Compiler Results log whenever a call into the Blueprint Virtual Machine is made from the AnimGraph.

To enable Warn About Blueprint Usage, enable the option inside the Class Settings of your Animation Blueprint under Optimization.



When the compiler identifies any nodes that are not using Fast Path, they will be displayed in the Compiler Results log.



Above, since we are executing Blueprint logic in our AnimGraph and have the warning option enabled, we get a warning message in the compiler results and can click on it to take us to the offending node. This can help track down optimizations that need to be made and will enable you to identify the node(s) that may be the source of the problem.

General Tips

As you start to consider the performance of your animation usage, here are some guidelines that you may want to follow when performing optimizations.

Based on the size and scope of your project, more invasive changes may be needed however this is generally a good place to start.

Make sure that the conditions for Parallel Updates are met

In UAnimInstance::NeedsImmediateUpdate you can see all the conditions that must be met to avoid the update phase of animation running on the game thread. If root motion is required for character movement, the parallel update cannot be performed as character movement is not multi threaded.

Avoid calls into the Blueprint Virtual Machine

Consider Nativizing Blueprints into C++ code.

Keep your Event Graph in your Animation Blueprints empty. Use a custom UAnimInstance and FAnimInstanceProxy derived class and do all of your work in the proxy during FAnimInstanceProxy::Update or FAnimInstanceProxy::Evaluate as these are executed on worker threads.

Ensure that the nodes within your Anim Graph of your Animation Blueprint are structured in a way that they are using Fast Path.

Ensure that Optimize Anim Blueprint Member Variable Access is enabled in the Project Settings as this controls whether Animation Blueprint nodes that access member variables of their class directly should use the optimized path that avoids a thunk to the Blueprint VM.

Generally the most costly part of an AnimGraph's execution, avoiding calls to the virtual machine is the key to getting maximum performance out of Animation Blueprints.

Use Update Rate Optimizations (URO)

This will prevent your animations from ticking too often. Control over how this is applied is up to your game, but we recommend moving toward ~15Hz and under Update Rates at appropriate distances for many characters, as well as disabling interpolation.

To enable, set your Skeletal Mesh Component to Enable Update Rate Optimizations and refer to AnimUpdateRateTick().

Optionally, you can also enable Display Debug Update Rate Optimizations to enable onscreen debugging of URO being applied.

Enable Component Use Fixed Skel Bounds

In your Skeletal Mesh Component, enable the Component Use Skel Bounds option.

This will skip using a physics asset and will instead always use the fixed bounds defined in the Skeletal Mesh.

This will also skip recalculating bounding volumes for culling for every frame, increasing performance.

Other Considerations

When profiling your project, you may see that FParallelAnimationCompletionTask is being run for Skeletal Meshes on the main thread after worker threads are done. This will be the bulk of the main thread work that you will see in your profile once the conditions for parallel updates are satisfied and usually consist of a few things, depending on your setup:

Moving your components around, updating physics objects for bones for example.

Try avoiding updating physics for things that don't actually need it as this will be key to reducing this.

Firing off Animation Notifies.

These should be non-Blueprint, again to avoid calls to the Blueprint VM for efficiency.

These also need to be performed on the game thread as they can affect the animated object's lifetime.

Interpolation of animation if URO is enabled.

Blending of curves if Material or Morph Target curves are in use.





Setup

Trace Data Filtering

Trace Source Filtering

User Interface

Animation Insights

Control Reference

User Interface

Track Inspection

Track Types

Notifies

Curves

Pose

Graph

Montage

Blend Weights

Track Visibility

The editor features the Animation Insights plugin to visualize gameplay state and live animation behavior. Animation Insights enables users to record trace information to visualize animation behavior with the following features:

Channel filtering to select the trace data written out to the recorded data set

Source filtering to select the gameplay objects that output trace data

Pose, Curve, Blend Weight, Anim Graph, Montage, and Anim Notify tracks

Schematic Anim Graph view with a live update that replaces the showdebug animation system.



Setup

To begin using Animation Insights in the editor, enable these plugins:

Animation Insights

Insights Data Source Filters

Trace Data Filtering

If you choose to enable these plugins from inside the editor, locate them in the Plugins tab under Editor > Plugins > Built-In. Otherwise, enable these plugins in the project's *.uproject file:

After enabling the required plugins, restart the editor.

If you built the editor from source, you will need to compile and run the editor for your project after enabling the required plugins.

When the editor restarts, navigate Window > Developer Tools > Profiling to open Animation Insights and Trace Data Filtering.

After setting up filters with Trace Data or Trace Source filtering, live trace data will record and visualize in Animation Insights. Traces automatically write to the following project directory: <YourProject>/Saved/TraceSessions. Because trace sessions can grow in size over time, make sure to actively monitor and manage the *.utrace files.

Trace Data Filtering

The Trace Data Filtering minor tab initially opens next to the Content Browser. In Trace Data Filtering, users can set Trace Channel states to enable trace data by while the engine runs. After making filter selections, users may choose Filter Presets > Save User Preset. Currently, the editor provides a default Animation preset that currently enables Frame, Object, and Animation channels.

To learn more general information about channels, read Unreal Insights.



Channel filtering

With enabled channels, data will trace to the timeline in the Animation Insights minor tab.

Selective channel filtering limits performance overhead and disk space.



Play-in-Editor (PIE) to view animation data trace out for skeletal mesh components in the scene

Trace Source Filtering

With Trace Source filtering, users determine the gameplay objects that can output trace data. If users are working on a large-scale game, there are a large number of Actors and Components in a given world. Trace Source filtering enables users to reduce the amount of recorded trace data, limit overhead, and reduce the amount of used disk space (for example, users may only have interest in the PlayerPawn or certain Actors within range of the Player).

To open the Trace Source Filter tab, select Menu > (Filtering) Trace Source Filtering in Animation Insights.



Number

Description

1

The Add Filter dropdown enables users to add and combine user-created filters with AND, OR, and NOT logical operators. Use Options to visualize each Actor it's individual filtering state, reset the current filters, and to save or load filter presets.

2

Context sensitive region to set filter variable values.

3

The Options dropdown allows users to enable world filtering by World Type (Editor, PIE or Game) or by World Net Mode (Client, Server or Standalone).

The following animation shows the Trace Source Filtering in action:



To read more, learn How to Implement Trace Source Filtering.

Animation Insights

Animation Insights expands on the preexisting showdebug animation feature, which displays animation runtime internal data. The ability to visualize and analyze the information enables users to identify the cause(s) of animation glitches or bugs.

Over time, showdebug animation limited users' ability to track down animation problems because the showdebug animation system only outputs text to the screen. With Animation Insights, users can record the frame ranges containing the animation bugs while also having the ability to scrub (or play back) those frames while reviewing the data breakdowns.



Animation Insights schematic view with a live update—this replaces showdebug animation

Control Reference

Input Shortcut

Function

Ctrl + Left Mouse Button Drag over Time Ruler

Drags Time Ruler (above tracks view) to control the current time, allowing values to be scrubbed in schematic views, poses to animate in the viewport, and more

G

Toggle Graph visibility

V

Auto-hide tracks that have no timing events in the current Viewport

I

Toggle I/O (File Input) Overview and Activity Track visibility

L

Toggle Asset Loading track visibility

Y

Toggle GPU track visibility

U

Toggle CPU Thread (and all CPU thread group) track visibility

R

Toggle Frame track visibility

User Interface

Number

Description

1

Animation Insights menu that enables users to display Timing Insights tracks (such as Counters or Frames). Additionally, users can open the Trace Source Filtering Panel from this menu.

2

Frames panel

3

Timing panel with Track grouping and filtering options. See below to view the available track types.

4

Context menu enabling users to view specific properties, visualization styles (like polygons or points), series data, track layouts, and track sizes.

5

Transport controls enable users to play back a recorded session and step frames.

6

Schematic views that display properties of each track. These change over time while scrubbing the ruler.

To learn more about Timing Insights, the Frames panel, the Timing panel, Tracks (and more), read Unreal Insights.

Track Inspection

To inspect a track for debugging or performance analysis, right-click the track and follow its context menu to learn more about the track.



Right-clicking Graph - AnimSingleNodeInstance_1 opens the Graph Track context menu.

Animators typically need to identify problem spots in their animations, and Animation Insights helps the debugging process by enabling animators to visualize Notifies, Curves, Pose, Graph, Montage, and Blend Weights.

Each track type features its own context menu, which is the main entry point for per-track operations (for example, the Pose Track menu allows poses to be enabled or disabled for viewport rendering). Some tracks have common context menu options. For instance, tracks that display graphs allow graphs to be scaled, series to be toggled, stacked/overlay views and more.

Notifies tracks display animation about notifies and sync markers. The topmost lane of the track displays the per-frame events, such as ticks, notify events (example, for audio and effects) and sync markers. Other lanes display the active notify states. Right-click the track and select View Properties to display the notifies that are active on the current frame.



Curves tracks display all curves that were active in a frame. Right-click and select View Properties to see the curve values that were active on a given frame.



Pose tracks enable users to show or hide Actor poses while scrubbing the timeline.



Right-click and select Debug this graph to open the Animation Blueprint debugger and connect it to the track. With the Animation Blueprint debugger open, scrub the timeline to view the graph in action, including pose link weights, state machine states, asset player positions and blendspace samples. Select View this graph to see a schematic 'tree' view of the animation graph.



Montage tracks enable users to inspect Montage information over time, including blend weights and current/next sections.



Blend Weights tracks show all the assets that were active in a frame and their effective blend weights. Right click on a graph to go to the node in the Animation Blueprint that the graph corresponds to. You can also view other graphs such as playback time or blendspace coordinates.



Use the Tracks dropdown filter to toggle timing track visibility.



Enabling Anim Budgeter

Using the Anim Budgeter

Anim Budgeter C++ API

Additional Console Commands

The Animation Budget Allocator (or Anim Budgeter) system constrains the time taken for animation data that is run by dynamically throttling Skeletal Mesh Component ticking. The intent is to use a fixed CPU budget (not to exceed it) while maximizing perceived animation quality with minimal system overhead.

The system determines a fixed budget per platform (milliseconds (ms) of work to perform on the game thread), and it works out if it can do it all of the work needed, or if it needs to cut down on the work to be done. If it needs to be cut down, it does so based on Significance and targets several areas with the goal of dynamically adjusting the load to fit within the fixed (game thread) budget. Areas of which include:

Stop ticking and use Master Pose Component.

Perform updates at a lower rate.

Interpolate (or not) between updates.

Enabling Anim Budgeter

To use the Animation Budget Allocator, you will need to first enable it from the Plugins menu.

Open the Plugins menu from the Edit > Plugins option.

Under Programming, enable the Animation Budget Allocator plugin and restart the Editor.



Click image for full view.

Using the Anim Budgeter

To use the Anim Budgeter, enter the following console command by pressing the ` (backtick key):

To enable - "a.Budget.Enabled 1"

To disable - "a.Budget.Enabled 0"

When enabling the plugin, Anim Budgeter is automatically enabled.

You can also enable/disable the Anim Budgeter through Blueprint using the Enable ANimation Budget Blueprint node.



Currently, this is the only aspect of the system that is exposed to Blueprint, the rest of the system is based around CVars and C++ API calls.

To enable the debug display:

The ability to enable the display of debug information is available in the Master Branch in GitHUb currently only. This feature will become more widely available in 4.23.

To enable debug display - "a.Budget.Debug.Enabled 1"

To disable debug display - "a.Budget.Debug.Enabled 0"

Once enabled, a graph will be displayed inside the Viewport at runtime.



The graph is comprised of the following:

Time in ms smoothed over a kernel of about 20 frames (makes it easier to read trends and is the time taken per-tick).

Total Time

Anim Budget (dotted line)

Performance (solid line)

The performance will vary based on the amount of work that needs to be done. Below, the dotted line is our Anim Budget and the solid line is our performance. We are currently under budget as only a single character (the player) is ticking.



Below, we increase the number of characters to 10 and the hit on performance is seen by the spike in performance (noisy lines). There are two lines for performance, the gray line is the actual system performance and is a bit noisy and fluctuates depending on the load of the system. The smooth white line gives you a better idea of what the actual system performance is.



In the final example below, we increase the number of characters to just over 100 and you can see that the performance hovers around the allocated budget (dotted line).



Click image for full view.

This is only for animation and represents how often animation is being ticked.

Anim Budgeter tries to keep the overall amount of work that the system is doing within the budget and tries to maximize the quality that the system can produce. It will try and run the closest, most significant meshes at the highest framerate it can and push the framerate of lesser significant things or things that are further away lower. It does this all whilst filling out the budget with the total amount of work that needs to be done.

On each of the Skeletal Meshes, you'll see debug data:



The numbers show the rate at which the mesh is being updated. A value of one would mean that it is being updated and ticking every frame. A value of five would mean, that every five frames, it would perform an update and tick.

As an example, in Fortnite, characters are comprised of several Skeletal Meshes (heads, bodies, backpacks, etc.) all of which can be ticking at a given time. As we run the Anim Budgeter, you'll notice that in addition to how often the mesh updates which is represented by the numerical value, the text Lo, Hi, or I are used. This represents how the mesh is ticked.

Hi (or high detail) - means that Skeletal Mesh components and running more expensive logic.

Lo (or low detail) - means that expensive logic (such as extra character parts or more expensive work that can be skipped at a distance) is not running.

I (or interpolating) - means that the Skeletal Mesh is interpolating between frames.

The example below illustrates how the Anim Budgeter updates and priorities are shifted based on the amount of animation work needed.

Anim Budgeter C++ API

You can access the C++ files for Anim Budgeter inside your Engine installation folder under:

Engine\Plugins\Runtime\AnimationBudgetAllocator\Source\AnimationBudgetAllocator\Public\

Below is the IAnimationBudgetAllocator.h:

Additional Console Commands

The following console commands can also be used for debugging the Anim Budgeter:

Property

Description

a.Budget.AlwaysTickFalloffAggression

Range [0.1, 0.9], Default = 0.8

Controls the rate at which 'always ticked' components falloff under load.

Higher values mean that we reduce the number of always ticking components by a larger amount when the allocated time budget is exceeded.

a.Budget.BudgetFactorBeforeAggressiveReducedWork

Range > 1, Default = 2.0

Reduced work will be applied more rapidly when budget pressure goes over this amount.

a.Budget.BudgetFactorBeforeReduceWork

Range > 1, Default = 1.5

Reduced work will be delayed until budget pressure goes over this amount.

a.Budget.BudgetFactorBeforeReducedWorkEpsilon

Range > 0.0, Default = 0.25

Increased work will be delayed until budget pressure goes under a.Budget.BudgetFactorBeforeReducedWork minus this amount.

a.Budget.BudgetMs

Values > 0.1, Default = 1.0

The time in milliseconds that we allocate for Skeletal Mesh work to be performed.

When overbudget various other console variables come into play, such as a.Budget.AlwaysTickFalloffAggression and a.Budget.InterpolationFalloffAggression.

a.Budget.BudgetPressureSmoothingSpeed

Range > 0.0, Default = 3.0

How much to smooth the budget pressure value used to throttle reduced work.

a.Budget.Debug.Enabled

Values: 0/1

Controls whether debug rendering (in builds that support it) is enabled for the Animation Budget Allocator.

a.Budget.Debug.ShowAddresses

Values: 0/1

Controls whether debug rendering shows addresses of component data for debugging.

a.Budget.Enabled

Values: 0/1

Controls whether the Skeletal Mesh batching system is enabled. Should be set when there are no running Skeletal Meshes.

a.Budget.GBudgetPressureBeforeEmergencyReducedWork

Range > 0.0, Default = 2.5

Controls the budget pressure where emergency reduced work (applied to all components except those that are bAlwaysTick).

a.Budget.InitialEstimatedWorkUnitTime

Values > 0.0, Default = 0.08

Controls the time in milliseconds we expect, on average, for a Skeletal Mesh component to execute.

The value only applies for the first tick of a component, after which we use the real time the tick takes.

a.Budget.InterpolationFalloffAggression

Range [0.1, 0.9], Default = 0.4

Controls the rate at which interpolated components falloff under load.

Higher values mean that we reduce the number of interpolated components by a larger amount when the allocated time budget is exceeded.

Components are only interpolated when the time budget is exceeded.

a.Budget.InterpolationMaxRate

Values > 1, Default = 6

Controls the rate at which ticks happen when interpolating.

a.Budget.InterpolationTickMultiplier

Range [0.1, 0.9], Default = 0.75

Controls the expected value an amortized interpolated tick will take compared to a 'normal' tick.

a.Budget.MaxInterpolatedComponents

Range >= 0, Default = 16

Max number of components to interpolate before we start throttling.

a.Budget.MaxTickedOffsreen

Values >= 1, Default = 4

The maximum number of off screen components we tick (most significant first).

a.Budget.MaxTickRate

Values >= 1, Default = 10

The maximum tick rate we allow. If this is set then we can potentially go over budget but keep quality of individual meshes to a reasonable level.

a.Budget.MinQuality

Values [0.0, 1.0], Default = 0.0

The minimum quality metric allowed. Quality is determined simply by NumComponentsTickingThisFrame / NumComponentsThatWeNeedToTick.

If this is anything other than 0.0 then we can potentially go over our time budget.

a.Budget.ReducedWorkThrottleMaxInFrames

Range [1, 255], Default = 20

Prevents reduced work from changing too often due to system and load noise. Max value used when under budget pressure.

a.Budget.ReducedWorkThrottleMaxPerFrame

Range [1, 255], Default = 4

Controls the max number of components that are switched to/from reduced work per tick.

a.Budget.ReducedWorkThrottleMinInFrames

Range [1, 255], Default = 2

Prevents reduced work from changing too often due to system and load noise. Min value used when over budget pressure (for example: aggressive reduction).

a.Budget.StateChangeThrottleInFrames

Range [1, 128], Default = 30

Prevents throttle values from changing too often due to system and load noise.

a.Budget.WorkUnitSmoothingSpeed

Values > 0.1, Default = 5.0

The speed at which the average work unit converges on the measured amount.

Deformer Graph

Skeletal Meshes

Morph Target Previewer

Cloth Simulation

How to use the Machine Learning Deformer

Create a Custom Deformer Graph

Graph Reference

You can use Deformer Graphs to create custom mesh deformations within Unreal Engine. After creating a custom Deformer Graph asset, you can use the Deformer Graph Editor, with its unique set of Blueprint nodes to edit existing mesh deformation systems, such as Morph Targets and Cloth simulations, or you can create new mesh deformation systems for any Linear Skinned Mesh.

This document provides an example workflow of how to create a custom Deformer Graph to apply a twisting mesh deformation to a Skeletal Mesh character at runtime.

Enable the Deformer Graph plugin. Navigate in the Menu Bar to Edit > Plugins and locate the Deformer Graph in the Animation section, or using the Search Bar. Enable the plugin and restart the Editor.



Your project contains a Skeletal Mesh Character. We used the Unreal Engine mannequin in the example workflow, and you can access it in the Third Person Template.

Create a Custom Deformer Graph

In the Details panel of your Skeletal Mesh Character, enable the Mesh Deformer property and then select the Deformer Graph option from the drop down menu to create a new Deformer Graph asset.



After creating the asset, open the Deformer Graph Editor by double-clicking the asset in the Mesh Deformer property. In the Deformer Graph's Details panel, use the drop down menu in the Mesh property to select the mesh you are modifying.



From the Pallet panel, drag-and-drop the Skeletal Mesh Component Binding into the Deformer Graph's Update Graph to read the mesh's data.



Next, to rewrite the mesh's position data, add the Write Skinned Mesh node to the Update Graph and connect the Skeletal Mesh component binding.



Add and connect the Execute Skinned Mesh to the Skeletal Mesh component binding to set the domain of the mesh deformation. Select the node and change the Domain property to the Vertex option.



Next, add and connect the Scene Data node to the Skeletal Mesh component binding, to extract information about the scene the mesh occupies. This workflow uses the Time data to drive the mesh deformation at runtime.



To read the position of the vertices of the skeletal mesh, add the Skinned Mesh node and connect it to the Skeletal Mesh component binding. This node provides the Position, Tangent X, and Tangent Y coordinates for the characters mesh vertices.



Now, add a Custom Compute Kernel to the Update Graph. The Custom Compute Kernel performs the actual mesh deformation calculations using HLSL (High-Level Shader Language) programming.



Before writing the driving HLSL programming, or connecting the node to any other nodes in the graph, you must create the input and output pins, which are used by the HLSL program to perform the mesh deformation. In the Details panel of the Custom Compute Kernel, add the following input pins to make use of the information extracted from the Skeletal Mesh Component Binding using the various Read nodes.



Pin

Data Type

Domain

Description

Num Threads

Int Vector 3

Parameter

The Num Threads pin can accept the Domain of the mesh deformation from the Execute Skinned Mesh node's output pin.

Twist

Float

Parameter

Using a Constant or Variable value, this input pin determines the degree of the maximum amount of twist the mesh deforms.

Start

Float

Parameter

Using a Constant or Variable value, this input pin determines the start position of the twist on the Mesh's Z axis, in Unreal Engine Units (cm).

End

Float

Parameter

Using a Constant or Variable value, this input pin determines the end position of the twist on the mesh's Z axis, in Unreal Engine Units (cm).

Time

Float

Parameter

This variable input pin draws the game time from the mesh at runtime.

Position

Vector 3

Vertex x1

This input pin reads the position of each mesh axis at runtime.

Tangent X

Vector 4

Vertex x1

This input pin reads the tangent value of the X axis.

Tangent Y

Vector 4

Vertex x1

This input pin reads the tangent value of the Z axis.

Connect the Execute Skinned Mesh node's Num Threads output pin to the Custom Compute Kernel node's Num Threads input pin. Then set the Execution Domain property to the Vertex setting in the Custom Compute Kernel's Details panel.



Next, add the following Output pins in the Custom Compute Kernel's Details panel, to output the deformed mesh data for the Write Skinned Mesh node to write back to the Skeletal Mesh.



Pin

Data Type

Domain

Description

Out Position

Vector 3

Vertex x1

Outputs the newly deformed axis positions of the mesh vertices.

OutTangentX

Vector 4

Vertex x1

Outputs the modified tangent value on the X axis.

OutTangentZ

Vector 4

Vertex x1

Outputs the modified tangent value on the Z axis.

Save and Compile the asset.



Then ensure your Custom Compute Kernel's Declarations (Read-Only) tab in the Shader Text Editor panel registers all of the input and output pins as HLSL declarations.



The Decelerations (Read Only) tab should contain the following text:

Decelerations (Read Only)

Next, in the Shader Text section of the Shader Text Editor panel, input the following HLSL program to perform the vertex deformation on the Skeletal Mesh.

Shader Text Editor

After adding the custom HLSL program to calculate the mesh deformation, connect the read and write nodes to the associated input and output pins on the Custom Compute Kernel node.



Finally, drag-and-drop three Float Constant nodes from the Pallet panel to the Update Graph to set the Twist, Start, and End values for the custom function. Connect one Float Constant node to each of the three available input pins on the Custom Compute Kernel node. Set the Float Constant node connected to the Twist input pin to a value of 180.0, the Float Constant node connected to the Start input pin to a value of 0, and the Float Constant node connected to the End input pin to a value of 100.0.



Alter these values to see how the function's inputs are modified, to dynamically change the deformation. Instead of constant values, the function is driven using Deformer Graph variables, Resources or animation curves.

Save and Compile the asset to see the mesh now twisting in the Preview Viewport panel as well as in the level in real time.



You can add the custom Deformer Graph to any character in a level, by selecting the mesh, and navigating to the Deformers section of its Details panel. You can assign the custom Deformer Graph to the character by enabling the Deformer Graph property, and selecting the custom graph from the drop down menu.

For more information about Deformer Graphs or the Deformer Graph Editor and Blueprint nodes, refer to the Deformer Graph documentation.

This and other application examples of mesh deformations controlled by custom Deformer Graph logic are present in the Content Examples.

For more information about HLSL (High-Level Shader Language)programming used to drive the Deformer Graph's Custom Compute Kernels, refer to the Microsoft High-Level Shader Language reference documentation and programming guide

Graph Reference

Here you can use the image slider to reference the full Deformer Graph, Custom Compute Kernel Details panel, and Shader Text Editor panel, used in the workflow example.

Reference Images



Source Animation Setup

Animation Data Modifier

Generate Speed Curve

IK Rig Setup

Create FBIK

FBIK Settings

Speed Planting in IK Retargeter

Final Result

When using the IK Retargeter to retarget animation between different characters, the target character may exhibit noticeable feet sliding. This can occur if leg lengths and stances between the source and target characters are very different, causing leg retargeting to be imperfect. To resolve this, you can use Speed Planting workflows which pin IK Goals in place when they should not be moving.





Original retargeting results

Modified retargeted results using Speed Planting

This document provides instructions on how to use Speed Planting to resolve foot sliding in your retargeted animations.

You have retargeted animations from one character to another using the IK Retargeter. Refer to the Retargeting Bipeds with IK Rig page for how to do this.

You are familiar with creating Full Body IK solvers in IK Rig.

Source Animation Setup

The first step for setting up Speed Planting is to create Animation Curves in the source animation that will define the speed of each foot bone throughout the animation. You can do this using Animation Data Modifiers to generate the curve so that it produces accurate motion data quickly. The intent of this step is to use Animation Curve data to determine at what point during the animation the feet should be planted.

Animation Data Modifier

In your source Animation Sequence, from the main menu, go to Window > Animation Data Modifiers.



Next, add a Motion Extractor Modifier by clicking Add Modifier > MotionExtractorModifier. Do this for each foot bone within the source animation. In this example, two Motion Extractor Modifiers are added.



Within both Motion Extractor Modifiers, set the following properties:

Bone Name: The name of the foot bone to watch for its speed. This example uses the ball_r and ball_l bones.

Motion Type: Translation Speed.

Axis: XYZ.



Generate Speed Curve

Once your Animation Data Modifiers are set up, click Apply All Modifiers to generate speed curves for the specified bones.



Double-click the curve track to open the Curve Editor where you can see more detailed information about it. Select or hover your cursor over the keyframes to see the values. This information can be used to determine the threshold of speed at which the foot should be planted. In most cases, this means that the lower flat parts of the curve are where the foot is stationary, whereas the peaks are where it is in motion.



Because you modified this Animation Sequence and the Skeleton (due to creating a new curve), make sure you save both Assets now.

IK Rig Setup

Continuing the setup process, you must now create IK Goals and Solvers for the leg chains on the target character. This example uses a Full Body IK (FBIK) solver, however depending on your character, you could choose other kinds of IK Rig Solvers. This step is required in order to pin the legs using IK when they become stationary during the animation.

Create FBIK

Open the target character's IK Rig Asset used for retargeting, navigate to the Hierarchy panel, right-click the end bone in one of the leg retarget chains, and select New IK Goal.



In the following prompts, ensure Full Body IK is set as the solver and click Add Solver, then click Assign Goal.



Next, ensure that the newly created Full Body IK solver is selected in the Solver Stack panel, right-click the other foot bone, select New IK Goal, then click Assign Goal.



Finally, select the Full Body IK solver, then right-click the root bone in the hierarchy and select Set Root Bone on Selected Solver. Typically, the root bone for an FBIK solver is the pelvis or hips.



FBIK Settings

Depending on the bone structure of your character's legs, you may also need to create additional bone settings for bones that are controlled by the FBIK solver. This resolves stiffness or incorrect joint rotation that can result from the FBIK solve. To create a Bone setting, select the Full Body IK Solver, then right-click a bone you want to create settings for and select Add Settings to Selected Bone.



In this example, to resolve rotational stiffness for some leg bones, bone settings were created for these bones with the following properties:

thigh_l

Use Preferred Angles: Enabled

Preferred Angles: 0, 0, -45

calf_l

Use Preferred Angles: Enabled

Preferred Angles: 0, 0, 45

thigh_r

Use Preferred Angles: Enabled

Preferred Angles: 0, 0, -45

calf_r

Use Preferred Angles: Enabled

Preferred Angles: 0, 0, 45



Depending on your character's needs, there may be other bone settings required to ensure your FBIK solver functions correctly, such as Stiffness, Limits, and Mass Multiplier. Refer to the Full Body IK section of the Solvers page for more information.

Speed Planting in IK Retargeter

Next, open the IK Retargeter Asset for your characters. In the viewport select either the IK Goal or the chain, and in the Details panel enable Speed Planting.



Set the following properties in the Speed Planting section:

Set Speed Curve Name to the name of the corresponding leg curve that was generated earlier on the source character. In this example it is set to ball_l_translation_speed_XYZ.

Depending on the generated curve values, you may need to adjust Speed Threshold to a number that is slightly higher than where the curve stays flat. If you notice that your character's feet are still unplanting inappropriately, then increase this number. In this example, it is set to 30.

Do this for all necessary leg chains on your target character.



Final Result

Now when you play animations in the retargeter, you should see better feet planting for your target character. You can now export the retargeted animation to a new Animation Sequence.



Deformer Graph

Morph Target Previewer

Cloth Simulation

Autodesk Maya Plugin Setup

Training Data Generation in Maya

Adding Bone Parameters

Configure Bone Parameters

Configure Mesh

Start Pose Generation

Deformer Training in Unreal Engine

Import Alembic File

Import Trained FBX

Create ML Deformer Asset

Deformer Blueprint Setup

Creating accurate, non-linear deformer systems for skinned static and skeletal mesh objects is a complex and computationally-intensive process, especially when calculating these deformation simulations in real-time. Using Unreal Engine's Machine Learning (ML) Deformer Framework, you can approximate complex mesh deformations at runtime, using externally pre-generated mesh deformation simulation data to train a ML Deformer Model in order to mimic high-quality mesh deformations, greatly improving the quality of in-game mesh deformations without the computational cost of real-time deformation generation.

The ML Deformer Framework internally leverages the Neural Network Inference (NNI) system, driven by a deformer model, to process approximate mesh deformation calculations on the GPU, alleviating some processing bandwidth on the CPU.

Also available, in the Unreal Engine Marketplace, is a plugin for AutoDesk Maya that you can use to generate the necessary mesh deformation data. After generating mesh deformation data in AutoDesk Maya, the data is then exported as FBX (.fbx) and Alembic (.ab) files that you can import to Unreal Engine and use to train a deformer model.

This document provides an example workflow of generating mesh deformation simulation data in Autodesk Maya, and then using that data in Unreal Engine to train a deformer Model to approximate a character's mesh deformations at runtime.

The ML Deformer Framework is a Plugin and must be enabled prior to use. Navigate in the Unreal Engine menu to Edit > Plugins, locate ML Deformer Framework in the Animation section, and enable it. After enabling the plugin, you will need to restart the editor.



The ML Deformer workflow requires you to use Autodesk Maya for a portion of the workflow.

You have a skinned character in both Unreal Engine and Autodesk Maya.

The ML Deformer Framework relies on trained ML Deformer Models to drive skinned mesh deformations.

You can choose to install premade models in the form of Plugins. For this example, a portion of the workflow optionally uses the ML Deformer Neural Morph Model, which you can install, from the Plugins window.

The ML Deformer Neural Morph Model is a Plugin and must be enabled prior to use. Navigate in the Unreal Engine menu to Edit > Plugins, locate ML Deformer Neural Morph Model in the Animation section, and enable it. After enabling the plugin, you will need to restart the editor.



There are several other prefabricated Models that you can install and use in your project. You can even create your own ML Deformer models within the C++ package of the plugin or customize an existing model.

Autodesk Maya Plugin Setup

You will need to download and install the ML Deformer Data Generation Maya Plugin. To do this, first navigate to the www.unrealengine.com/marketplace/en-US/product/ml-deformer Marketplace page and download the plugin.



When the plugin is installed, it will be located in the Plugins folder of your Unreal Engine install directory. By default, it is located under the following path:

Unzip the contents of MayaMLDeformer.zip to C:\Users\username\Documents\maya\modules. If the modules folder does not exist, you can create it.



For Mac users, the plugin is installed to /Users/Shared/Autodesk/modules/maya.

Now when you open Autodesk Maya, you should see UE MLDeformer in the main menu bar.



Training Data Generation in Maya

The ML Deformer plugin creates training data for characters by setting procedural keyframes on bones that produce a useful data set for machine learning algorithms. To start the training data generation process, you must first open the tool.

In Maya's main menu bar, click UE ML Deformer > Data Generator, which will open the Training Data Generation Setup window.



Also import or open your skinned character in the Maya scene. For this example workflow, a MetaHuman is used.



Adding Bone Parameters

In order to train your joints, you must add a list of nodes and attributes to modify, along with the range of values that these attributes can adopt.

Select the joints in Maya you want to add, and then click Add (+) in the Parameters section of the Training Data Generation Setup window.



This will open the Add Parameters window, where you can further refine which joint attributes you want to use in the training. You can also click Refresh to refresh the parameter list with your current selection.



Select the joint attributes you want to add as parameters, then click Add Selected Parameters to add them to the Training Data Generation Setup. In most cases, only the rotation attributes are necessary from joints.



You can use the Attributes Filter section to automatically refine and exclude attributes. Click Add (+) to add a new entry and name it according to the attributes you want to exclude. In this example, all the translation and other minor attributes are being excluded so that the resulting attributes only show rotation.



Configure Bone Parameters

With the attributes added, you will now need to configure the range of motion for each axis. This is done by selecting each attribute and specifying the Minimum and Maximum range of movement for that axis in the Parameter Properties. These values should be as realistic as possible, depending on the complexity and type of character. Defining this data is necessary for the accuracy and quality of the ML Deformer training process. The plugin will automatically initialize the values to the joint limits that are configured in Maya, if they are set up for that joint. You can also provide defaults for given parameter types.



Correctly configuring these parameters can be time consuming, so we recommend you save your progress as a .json file by clicking File > Save Config.



You can restore a saved configuration by selecting File > Load Config. Configuration files are based on node and attribute names, and can be used in any Maya scene with matching names.

Configure Mesh

To finalize the training data, you must specify a Base Mesh, and optionally a Target Mesh.

The Base Mesh is the mesh bound to the skeleton, and is the same mesh used in Unreal Engine.

The Target Mesh is a separate mesh that contains the same vertices and topology as the Base Mesh, but is used for deformation. For example, the Target Mesh might use volume preservation techniques and muscle simulation to create realistic deformation. The target mesh can exist inside Maya, or it can be created in an external program such as Houdini. The Target Mesh is exported as an alembic cache .abc.

To specify your Base and Target Meshes, click Add (+) in the Mesh Settings area. A window will appear where you can click the Select button and specify each mesh, with the Target Mesh being optional unless you have it in your scene.



Select your meshes and click OK to add them to the Mesh Settings list.



If your Skeletal Mesh is composed of multiple meshes, you should add each individual mesh to the Mesh Settings list. Typically you would only need to do this if you are using modular characters.

Start Pose Generation

Lastly, you must specify Generator Settings to determine the training length and configuration. A keyframe will be created for every attribute in the parameter list, for each Num Poses.



Name

Description

Num Poses

The number of random poses to create, which creates animation for those frames. The recommended range is 5,000 - 50,000, however in typical cases you can set this to 25,000.

Training requires a large amount of data to give good results. Approximately 25,000 frames of animation data is expected to correspond with the default training settings in Unreal. Although it is possible to train with smaller data sets, the results are likely to be worse. The higher the Num Poses value, the slower the training will be.

Start Frame

The frame number where the randomly generated poses will start. You can combine existing animation data with the generated frames by setting a value greater than 0.

Active Parameters

The amount of randomness of the pose between each frame. In most cases, you should set this to around 75%, with higher values resulting in better quality. Setting this to 100% can cause simulation issues, however.

Click Generate to start the training data generation process in Maya. If you are using a Target Mesh and Target Alembic File, then this process can take a very long time. Depending on the complexity of your mesh it can take anywhere from a few minutes to several hours. Make sure you also have enough free disk space, as the Alembic file can become very large (around 50 to 100 gigabytes), depending on the vertex count and Num Poses setting.



Once the training data is finished generating, you should now have an exported .fbx and .abc file if you specified a Target Alembic File.



Your FBX and Alembic files must contain the same number of frames, and each frame must correspond to the same skeletal pose.

Deformer Training in Unreal Engine

You can now bring your completed training files into Unreal Engine.

Import Alembic File

Start by importing the .abc file that you either created in the training process, or in a different external deformer tool. In the Content Browser, click Import, then select your .abc file and click Open.



In the import settings dialog window, set the following parameters for the import:

Set Import Type to Geometry Cache.

Disable Flatten Tracks. This is required in order to match FBX meshes with the Alembic Geometry Cache tracks. If you have just a single mesh, you can keep Flatten Tracks enabled, but are not required to do so. It is important that your Alembic Track names start with the same name as the name you see in the outliner in Maya.

Set Compressed Position Precision to 0.001 to ensure greater accuracy. If you keep the default, the ML Deformer may learn errors introduced by compression.

Enable Store Imported Vertex Numbers. This is required in order to match vertices between the Skeletal Mesh and the Geometry Cache. If you forget to do this the ML Deformer editor will show you a warning, and you will have to re-import the Geometry Cache again.



Once these parameters are set, click Import to import the geometry cache. This process can take a very long time due to the size of the alembic file. Depending on the complexity and size it can take anywhere from a few minutes to several hours.

Import Trained FBX

Next, you will need to import the FBX file that was created from the Maya training data. In the FBX Import Options dialog window, set the following parameters for the import:

If you have already imported your character into Unreal Engine, set the Skeleton field to use the skeleton of the character.

Enable Import Animations.

Set Animation Length to Exported Time.



Once these parameters are set, click Import to import the FBX. This process can take a very long time due to the size of the FBX file.

Create ML Deformer Asset

Next, you must create the ML Deformer Asset in order to contain and correlate both the Alembic and FBX sequences. In the Content Browser, click Add (+), then select Animation > ML Deformer. Open the asset after you create it.



In the Details panel of the ML Deformer Editor, assign both the Skeletal Mesh of your character and the imported trained FBX Animation Sequence to their respective properties. This will cause the mesh to appear under the Training Base viewport label.



Also assign the imported Alembic file to the Geometry Cache property. This will cause the Alembic mesh to also appear in the viewport under the Training Target label.

You should see green lines appear, being rendered on top of the Training Base model. These represent the deltas, or differences, between the base and target mesh. Make sure they look correct, as the deformer model will learn these during training. If your target mesh is somehow rotated differently compared to your training base, you can use the Alignment Transform to align them. They do not need to overlap, only the rotation needs to match.



Dragging on the timeline playhead will scrub both sequences together, so that you can verify their animations are matching. Make sure the green lines (deltas) look correct every frame.

If the deltas look incorrect on some frames, you can try reimporting the Geometry Cache with the option Constant Topology Optimization enabled.



Click Train Model in the ML Deformer Editor toolbar to start training. This process can take a long time.



After the training process is complete you can view the results in the ML Deformer Testing mode.



You can adjust the Weight property in the Visualization panel to observe the effect of the ML Deformer mesh (right) compared to the linear skinned mesh (left).



Enable the Show Heat Map property and adjust the Heat Map options in the Visualization panel to see a visual representation of the areas of the mesh being deformed by the ML Deformer.



Deformer Blueprint Setup

In order to start using the ML Deformer on a character in a level, you will need to set up the character using the ML Deformer Component in Blueprints.

Start by creating an Actor Blueprint. In the Content Browser, click Add (+) > Blueprint Class, then select Actor. Open the Blueprint after it is created.



Add your Skeletal Mesh to the Blueprint by dragging it from the Content Browser into the Components panel.



Next, add the MLDeformer Component by clicking Add (+) in the Components panel and selecting MLDeformer.



Select the MLDeformer Component and specify your ML Deformer Asset in the Details panel.



Lastly, select the Skeletal Mesh Component and specify a Deformer Graph in the Mesh Deformer property.



If you do not have a Deformer Graph, you can use the example DefaultMLDeformerGraph located in the Engine > Plugins > MLDeformer Content > Deformers content folder. To access this folder, click on Settings in the Content Browser and enable both Show Engine Content and Show Plugin Content.



Source and Target IK Rig Setup

Retarget Root

Retarget Chains

IK Retargeting

Create and Set Up IK Retargeter

Checklist Before Retargeting

Preview Retargeting

Export Retargeting Results

Embellishing Motion

Create IK Goals

IK Retargeter Root Settings

Unreal Engine provides flexible tools for retargeting animation from one character to another. One of the ways you can do this is by using IK Rigs in conjunction with the IK Retargeter, which make it possible to retarget characters with vastly different skeleton hierarchies and proportions. Retargeting animations is a way to share animation data between multiple different skeletons without needing to create and manage new animations outside of Unreal Engine.

This document provides an overview of how to use these tools to retarget animation between two different bipedal characters.

Your project contains at least two different bipedal characters. This example uses the Unreal Engine Mannequin available from the Third Person Template and the Stack O Bot.

Both characters should have different Skeleton Assets and bone hierarchies so you can maximize the rationale for retargeting this way. Otherwise, it may be better to use Compatible Skeletons if your characters have similar proportions and hierarchies.

Source and Target IK Rig Setup

Retargeting with IK Rig requires a source and target Skeletal Mesh, which are defined by an IK Rig Asset for each of those meshes. Therefore, you must first create an IK Rig for each of the characters being used in the retargeting process.

Open the Content Browser and click Add (+) > Animation > IK Rig > IK Rig.

Select the Skeletal Mesh you wish to add the rig to.

Do this for both characters, then open each IK Rig Asset.



Retarget Root

Within both IK Rig Assets, you must define the root for each character, which is typically the pelvis or hip bone. This is done in order for the character's root motion to be defined and transferred in a proportional way.

In the Hierarchy panel, right-click the bone and select Set Retarget Root. Do this in both IK Rig Assets.



Once done, the chosen bone shows an indication that it is the Retarget Root in the Hierarchy and the IK Retargeting panels.



Retarget Chains

You must also define limbs and other appendages that you want to transfer in the retarget process on both the source and target IK Rigs. This is a process similar to characterizing your rig in other applications like Autodesk MotionBuilder or Maya. The main difference is that you define it by joint chains, rather than by individual bones. This provides flexibility in retargeting characters with vastly different bone structures.

You must create chains for all major limbs that you want to retarget. You can optionally create chains for minor limbs such as fingers, too. In this example, you will create the following chains in both IK Rigs:

Spine

Left Arm

Right Arm

Neck

Head

Left Leg

Right Leg



To create a chain, follow these steps:

Select the first bone of the chain in the Hierarchy panel, then select all bones down the hierarchy until you reach the last bone of the chain.

Right-click these bones and select New Retarget Chain from Selected Bones.

In the Add New Retarget Chain dialog window, make sure the Chain Name is set correctly, then click OK. In most cases, IK Rig will automatically assign this value from its list of common chain names.

In the Add Goal to New Chain dialog window, select No Goal. Typically, you do not need to add IK Goals unless your retargeting requires additional IK adjustments, such as Speed Planting, Stride Warping, or Blend to Source.



Repeat this step for all major chains in both IK Rig Assets. Once completed, the IK Retargeting panel should be populated with several chains.



It is valid for a chain to consist of a single bone. This can happen in some cases, such as for shoulders, neck, or head bones. In those cases, you can still right-click a single bone in the Hierarchy panel and select New Retarget Chain from Selected Bones. The chain entry will have the same bone defined in the Start Bone and End Bone fields.

IK Retargeting

After you create the necessary bone chains, you can begin the retargeting process in the IK Retargeter. The IK Retargeter is an Asset that references both source and target IK Rigs. In the IK Retargeter Editor, you can customize how to transfer animation between the source and the target.

Create and Set Up IK Retargeter

To create an IK Retargeter, do the following steps:

Click Add (+) in the Content Browser, then select Animation > IK Retargeter.

In the dialog window that appears, select the IK Rig that you want to retarget animation from.

After you select a rig, name the new IK Retargeter Asset, then double-click it to open it in the IK Retargeter Editor.



The IK Retargeter Editor only shows the source Skeletal Mesh in the viewport and in the Source IKRig Asset property. To add the target character, click the Target IKRig Asset dropdown menu and select the target IK Rig.



Checklist Before Retargeting

Before continuing, there are a few things you should check to ensure the retargeting process is correct and accurate.

In the Chain Mapping panel, make sure the Target and Source Chains are matching. In most cases, the names should correctly auto-match. If not, then you can click the Source Chain dropdown menu and change the chain assignment to match with the Target Chain.



Make sure both characters have matching reference poses. If these reference poses differ, such as if one character is T-posed and another is A-posed, then you will need to adjust one of their retarget poses so they match.



You can optionally adjust offset and scale settings in the Details panel to more easily see both source and target skeletons.



Preview Retargeting

In the Asset Browser panel, double-click different animations to preview the retargeting effect on different Animation Sequences.



Export Retargeting Results

Once you are satisfied with your retargeting results on the target character, you can export the animations to Animation Sequences that are compatible with that character's Skeleton. To do this, select the animations you want to export in the Asset Browser panel, then click Export Selected Animations.



Specify your export path in the dialog window and click OK to export the animations. The retargeted animations will now be available in the output folder with the postfix _Retargeted.



Embellishing Motion

If you are retargeting realistic motion-capture animation to a non-realistic character, the resulting animation may appear incorrect or strange looking. This can be somewhat subjective, but in these cases it may be helpful to perform extra steps to embellish or diminish certain character motions to achieve a more fitting appearance.

For example, when previewing a run animation on the retargeted robot character, you might want the character to have more bounce. The following steps detail how you can achieve this.





Original retargeting results

Retargeting with adjusted settings

Create IK Goals

The first step is to create IK Goals to ensure the feet stay planted on the ground when adding the extra bouncing.

Assuming no IK Goals are already created, open the IK Rig Asset for the target character. In the Hierarchy panel, right-click one of the feet bones and select New IK Goal.



In the following prompts, ensure Limb IK is set as the solver and click Add Solver, then click Assign Goal.



Next, ensure that the newly created Limb IK solver is selected in the Solver Stack panel, then right-click the thigh bone and select Set Root Bone on Selected Solver.



Perform the same steps above for the other leg until you have two IK Goals and Limb IK solvers.



IK Retargeter Root Settings

Next, return to the IK Retargeter Asset and open the root settings by either selecting the root debug visualizer in the viewport or clicking Root Settings in the Chain Mapping panel.



The two properties you need to edit are Scale Horizontal and Translate Offset Z.

Scale Horizontal increases the overall scale of the animation curve on the retarget root, which in most cases is the pelvis or hip bone. This increases the overall vertical motion of the character, but also causes the character to rise higher away from the floor.

Translation Offset Z compensates for this. When decreasing it, it lowers the retarget root, but does not affect its overall scale.

Using both these properties together makes it so that you can increase the up and down bounce of a retargeted character. The amount to increase or decrease the properties depends on your character and the animation.



In this example, to achieve a desirable bounce, Translation Offset Z is set to -173, and Scale Vertical is set to 6.



Accessing Retarget Profiles

Static Override

Dynamic Override

IK Rig Setup

Retarget Profile Variable Setup

Create Event Graph Logic

Animate Retarget Setting

In addition to IK Retargeting your characters during runtime, you can modify Global, Root, and Chain settings dynamically using Retarget Profiles. Retarget Profiles are an additional feature of the Retarget Pose From Mesh Animation Blueprint Node which you can use to change or animate these settings. This can be useful in cases where you need to change or apply different retarget settings at different points throughout an animation.

This document provides instructions on how to set up Retarget Profiles and various ways to modify them.

You have set up characters to dynamically retarget at runtime using Retarget Pose From Mesh. Refer to the Runtime IK Retargeting page for instructions on how to do this.

You are familiar with using Animation Blueprints.

You are familiar with creating and using Sequencer.

Accessing Retarget Profiles

You can access Retarget Profiles from the Retarget Pose From Mesh node in the target character's Animation Blueprint you created in the Runtime IK Retargeting prerequisite step. Select Retarget Pose From Mesh and locate the Custom Retarget Profile properties in the Details panel.



Static Override

By default, the settings you set up in the assigned IK Retargeter Asset are used by the Retarget Pose From Mesh node. You can statically override those settings by modifying the Custom Retarget Profile properties on the node:

Name

Description

Apply Target Retarget Pose

Enabling this overrides the Retarget Pose used for the target character.

Target Retarget Pose Name

If Apply Target Retarget Pose is enabled, this setting specifies the new Retarget Pose name to use instead.

Apply Source Retarget Pose

Enabling this overrides the Retarget Pose used for the source character.

Source Retarget Pose Name

If Apply Source Retarget Pose is enabled, this setting specifies the new Retarget Pose name to use instead.

Apply Chain Settings

Enabling this overrides the Chain Settings used in the IK Retargeter Asset with new ones specified below in Chain Settings.

Chain Settings

An array to add chains to override with new Chain Settings. Click Add (+) to add a new chain and set the name to match one of the retarget chains in the IK Retargeter Asset. Expand FK, IK or Speed Planting categories to modify the settings within.



Apply Root Settings

Enabling this overrides the Root Settings used in the IK Retargeter Asset with new ones specified below in Root Settings.

Root Settings

If Apply Root Settings is enabled, these settings override the Root Settings used in the IK Retargeter Asset.

Apply Global Settings

Enabling this overrides the Global Settings used in the IK Retargeter Asset with new ones specified below in Global Settings.

Global Settings

If Apply Global Settings is enabled, these settings override the Global Settings used in the IK Retargeter Asset.

Dynamic Override

If you need to control when retarget settings change, then you must create additional blueprint logic. Due to the arbitrary nature of Blueprints and Animation situations, there are many ways you can create logic to edit a variety of retarget situations.

In this example, Retarget Profiles will be used to adjust the larger character's arm to correctly reach for the ground, matching the Mannequin.



IK Rig Setup

Because of this specific retarget situation, you need to modify the target character's IK Rig to use IK Goals and Solvers. This example uses a Full Body IK (FBIK) solver, however depending on your character, you could choose other kinds of IK Rig Solvers. This step is required to provide IK arm Chain Settings for the Retarget Profile to modify.

Open the target character's IK Rig Asset used for retargeting and do the following:

Right-click one of the hand bones in the Hierarchy panel and select New IK Goal.

In the next prompt, ensure Full Body IK is set as the solver and click Add Solver.

Select the Full Body IK solver in the Solver Stack panel, then right-click the other hand bone and select New IK Goal.

Lastly, select the Full Body IK solver, right-click the root bone (typically the pelvis or hips) in the hierarchy and select Set Root Bone on Selected Solver.



Select Full Body IK in the Solver Stack and set Root Behavior to Pin to Input in the Details panel. This is required to prevent the lower body from moving when the IK goals move.



You may also need to create additional bone settings for bones that are controlled by the FBIK solver. This resolves stiffness or incorrect joint rotation that can result from the FBIK solve. To create a bone setting, select the Full Body IK Solver, then right-click a bone you want to create settings for and select Add Settings to Selected Bone.

In this example, to resolve rotational stiffness for the spine, shoulder, and arm bones, bone settings were created for these bones (including any symmetrical bones) with the following properties:

Spine_01

Rotation and Position Stiffness: 0.75

Spine_02

Rotation and Position Stiffness: 0.75

Spine_03

Rotation and Position Stiffness: 0.75

Clavicle_l

Rotation and Position Stiffness: 0.8

Lowerarm_l

Use Preferred Angles: Enabled

Preferred Angles: 0, 0, 45



Retarget Profile Variable Setup

Returning to the target Animation Blueprint, select the Retarget Pose From Mesh node. In the Details panel click the Custom Retarget Profile dropdown menu and enable Expose As Pin, which adds a Custom Retarget Profile pin on the node.



Right-click the newly created pin and select Promote to Variable. This creates a new Struct Variable of type Retarget Profile and connects to the pin. The variable is also visible in the My Blueprint panel.



Create Event Graph Logic

Open the Animation Blueprint Event Graph and reference the Retarget Profile variable here, then do the following:

Drag off it and create a Get Chain Settings from Retarget Profile node.

Set Target Chain Name to the retarget chain that you want to animate. In this example it is LeftArm.

Right-click Return Value and select Split Struct Pin.



Next, drag off Return Value IK and create a Set members in TargetChainIKSettings node. Select it, and enable Static Offset in the Details panel, which exposes the Static Offset chain property as a pin on the node.



Drag off Struct Out and create a Set Chain IKSettings in Retarget Profile node, then do the following:

Set Target Chain Name to the same chain name used earlier: LeftArm,

Connect the Retarget Profile variable to the Retarget Profile input.



Connect Event Blueprint Update Animation to this execution chain, and expose Static Offset as a variable by right-clicking the pin and selecting Promote to Variable.



Finally, in the Details panel for the Static Offset variable, enable Expose to Cinematics and Instance Editable, which makes the variable editable externally.



Animate Retarget Setting

Because you created logic in the Target's Animation Blueprint Event Graph and linked it to Event Blueprint Update Animation, you can animate the exposed variable in Sequencer the same way you would animate Anim Instances.

Assuming you have already created and opened a Level Sequence, add the retargeted character blueprint to it and the source Skeletal Mesh Component, then play an animation on the source component to observe the retargeting effects on the target.



Next, add the Chain Setting variable you exposed earlier by doing the following:

Add the target Skeletal Mesh Component by clicking Add Track (+) on the Blueprint Track and select the Target component.

Click Add Track (+) on the target Component Track and select Anim Instance.

Select Add Track (+) on the Anim Instance Track and select the variable.



You can now keyframe this track to adjust the chain property in real-time.



Animating Retarget Profiles in conjunction with Runtime Retargeting provides you with a way to make fine-tuning adjustments to your runtime retargeting results without creating new animations or additional assets.







Original Animation

Animating Retarget Profiles on Large Character

Animating Retarget Profiles on Small Character

Animation Blueprint Setup

Blueprint Setup

Character Blueprint Example

One of the options available to you when retargeting characters using IK Retargeting is to retarget during runtime sessions. Doing this means you can retarget to other characters without generating new Animation Sequences, or during Live Link sessions.

This document provides instructions on how to set up a character to retarget to another during runtime sessions using IK Retargeting and Retarget Pose From Mesh.

You have created an IK Retargeter Asset retargeting from one character to another. Refer to the Retargeting Bipeds with IK Rig page for how to do this.

Although not absolutely required, your source character should be gameplay controllable to better preview the retargeting effects at runtime. You can use the Third Person Template, which contains a controllable Mannequin.

Animation Blueprint Setup

The first main step is to create an Animation Blueprint for the target character. In this example, the Mannequin is retargeting to the Stack-O-Bot, therefore, create a new Animation Blueprint for the Stack-O-Bot and a Retarget Pose From Mesh Node.

In the Content Browser, click Add (+), then select Animation > Animation Blueprint. In the next window, select the target Skeletal Mesh and click Create. Name your Animation Blueprint Asset and double-click it to open it.



Next, right-click in the Anim Graph and select Misc. > Retarget Pose From Mesh to create this node, then connect it to Output Pose.



Select the Retarget Pose From Mesh node and ensure the following properties are set:

Enable Use Attached Parent. Doing this simplifies content set-up, without needing you to find and assign the Source Mesh Component manually.

Set IKRetargeter Asset to your IK Retargeter Asset created as a prerequisite for this tutorial.



Blueprint Setup

In this next step, you will need to set up both source and target characters in a single Blueprint and assign the Animation Blueprint created in the previous step to the Target character.

First, create a new Actor Blueprint by clicking Add (+) in the Content Browser, then select Blueprint Class and click Actor. Name your Blueprint Asset and double-click it to open it.



In the Components panel of the Blueprint, click Add (+) and add two Skeletal Mesh Components, one for the source, and the other for the target. Assign the Skeletal Mesh Asset property in the Details panel to the appropriate Skeletal Mesh Asset for each Component.



If Use Attached Parent is enabled in your target Animation Blueprint, then the target Skeletal Mesh must be parented to the source Component so that the retargeting will work correctly. As this setting is based on using the parent Component as the source.



Select your source character and set Animation Mode to Use Animation Asset, then assign an animation to Anim to Play. Next, select your target character and assign the Animation Blueprint created earlier to Anim Class.



You should now see the target character retargeting to the source character in the Blueprint Viewport.



Character Blueprint Example

Depending on your project's needs, runtime retargeting can be useful for prototyping gameplay animation on different characters. In this example, the Third Person Template Character Blueprint has been modified with the Stack-O-Bot added to the Blueprint.



You can then create logic to switch Visibility between the different characters to preview the retargeting results in a gameplay scenario.



In situations where you are hiding the source character, you must set Visibility Based Anim Tick Option to Always Tick Pose and Refresh Bones under the Optimizations category.



1 - Setting up the Animation to Blend

2 - Updating the Character Blueprint

3 - Setting up the Anim Graph

4 - Finalizing the Blend Settings

Animation blending, as a concept, simply means making a smooth transition between two or more animations on a single character or Skeletal Mesh. In Unreal Engine, there are various ways in which such blending can be applied either through Blend Spaces, through additive methods by literally combining two animations based on a weighted bias or alpha value, or even applying direct overrides of the existing pose.

You can also send animation directly to specific bones within the Skeleton and all of its children. For instance, you can start with an animation in which the character is running, but then selectively apply a shooting animation to the upper body of the character. The final result would be a character that can run around and shoot at the same time, similar to the video below.

1 - Setting up the Animation to Blend

In this step, we change our default player character and create an AnimMontage for the animation we want to layer in on top of our movement animations.

For this guide we are using the Blueprint Third Person Template project and have added the Animation Starter Pack to the project:



You can download the Animation Starter Pack for free through the Marketplace from the Epic Launcher.

With your project open, inside the Content Browser under the Content/ThirdPersonBP/Blueprints folder, open the ThirdPersonGameMode Blueprint.

Under Default Pawn Class, click the drop-down menu and select the Ue4ASP_Character.



Compile and Save then close the Blueprint.

In the Content Browser, open the Content/AnimStarterPack folder.

Right-click on the Fire_Shotgun_Ironsights animation, select Create then Create AnimMontage.



You can filter the window by typing "Fire" inside the search window as shown above.

Open the new AnimMontage and click the magnifying glass icon.



This will open the Anim Slot Manager which we will use to create a Slot that we can use to blend to when calling the Slot by name.

Click the Add Slot button, then name the slot UpperBody then click Save.



Although we chose the name "UpperBody" here, we are not targeting the upperbody just yet but have assigned the name so we know where we are targeting.

Click the drop-down menu inside the Montage Group section and change it to DefaultGroup.UpperBody, then close the window.



We have now associated this Montage with the DefaultGroup.UpperBody, allowing it to play when the Slot is called.

In the next section, we will change our default player character and make some adjustments to determine when we are firing a weapon.

2 - Updating the Character Blueprint

In this step, we create some script inside our Character Blueprint to allow us to signal our Animation Blueprint that we are firing a weapon.

Inside the Content Browser under Content/AnimStarterPack, open the Ue4ASP_Character Blueprint.

Locate the Crouching section, and delete the InputAction Crouch Event (with the Warning!) sign.



There is a warning on this node because our project is not set up to use the InputAction event "Crouch".

Right-click in the graph and add a C Key Event and connect as shown below.



We have just associated crouch now with the C key press, you can change this input to whatever you would like.

In the MyBlueprint window, click the Add Variable button to create a Boolean variable and call it Fire Button Down.



Right-click in the graph and add the Left Mouse Button Key Event.

Holding Alt, drag the Fire Button Down variable in the graph to create a Set node.

Repeat the previous step (or copy the Set node) and connect as shown below.



Make sure that Fire Button Down is True when Left Mouse Button is Pressed and False when Released.

Select CapsuleComponent in the Components window, then in the Details panel check the Hidden in Game option.



This will turn off the debug display of capsule's collision.

Compile and Save then close the Blueprint.

Our character is now set up to send signals to our Animation Blueprint when we are crouching or firing a weapon. In the next step, we will set up our Animation Graph inside our Animation Blueprint to handle the blending of our Anim Montage with our normal movement animations so that we can blend between the two.

3 - Setting up the Anim Graph

In this step, we set up our AnimGraph to handle the blending of our AnimMontage and the movement pose from our State Machine.

In the Content/AnimStarterPack, open the UE4ASP_HeroTPP_AnimBlueprint Animation Blueprint.

Inside the MyBlueprint window, open the AnimGraph.



Drag off the Locomotion State Machine and search for and add New Save cached pose.



Here we are getting the resulting pose from our Locomotion State Machine and storing it in a cached pose that we can use elsewhere.

Give the cached pose a name by pressing F2 on the node such as LocomotionCache.



Right-click in the graph and add the Use cached pose 'LocomotionCache' (or whatever you named the cached pose).



Drag off the Use cached pose node and search for and add the Layered blend per bone node.



The Layered Blend Per Bone node will allow us to blend animations together from a specified bone on the Skeleton.

Copy/Paste the Use cached pose 'LocomotionCache' node, then drag off it and add the Slot 'DefaultSlot' node.



In the Settings for the Slot node, click the dropdown menu and select DefaultGroup.UpperBody.



When an Animation Montage that uses this slot is called to play, it will now be called inside our AnimGraph.

Connect the Slot to the Blend Poses 0 pin on the Layered blend per bone node, then connect the out to the Result and Compile.



Our AnimGraph is complete, but we still need to modify some settings on the Layered blend per bone node to finish up which we will do next.

4 - Finalizing the Blend Settings

In this final step, we define the method in which to layer our blended animation and which bone to start the blend from.

Inside the AnimGraph of UE4ASP_HeroTPP_AnimBlueprint, click on the Layered blend per bone node, then expand the Layer Setup section and click the + sign.



Under Bone Name enter spine_01, then set Blend Depth to 1 and check Mesh Space Rotation Blend.



With these settings, we can blend the shooting AnimMontage onto our Skeleton starting from the spine_01 bone.

Inside the MyBlueprint window, open the EventGraph.



Drag off the As Ue4ASP Character pin of the Cast To Ue4ASP_Character node and add the Get Fire Button Down node.



This will tell us if the player is pressing the fire button or not.

Hold B and Left-click in the graph to create a Branch node and connect it following Set Crouching.



For the Condition, plug in the FireButtonDown pin.

Right-click in the graph and add the Montage Is Playing node and assign Fire_Shotgun_Ironsights_Montage.



Off the Return Value of the Montage Is Playing node, add a Branch.

Connect the Branch from Step 5 to the new Branch as shown below and add a Montage Play node with Montage to Play set to your Montage.



This will check now if the Montage is currently playing and if it is, do not play it (and if it is not, play the Montage).

Compile and Save, close the Blueprint and delete the existing ThirdPersonCharacter in the level.



This will allow us to use our selected character defined in our Game Mode and not the one placed in the level.

Play in the editor.

End Result

You will see that when you hold the Left Mouse Button down, the character will play the shooting AnimMontage. You can walk around while shooting, you can even crouch (by holding C) and shoot as well. You could use this same guide to play a melee attack, reload animation or any other animation that you want to be able to do while moving around.

The UpperBody slot that we created and assigned in our Animation Montage can be assigned in other Animation Montages as well. Since our AnimGraph has the Slot node assigned, whenever we call to play an Animation Montage that has that slot assigned, it will get played with our defined settings.

1 - Creating Aim Poses

2 - Creating the Aim Offset

3 - Implementing the Aim Offset

4 - Finishing Up

In this guide, we will create an Aim Offset, which is an asset that stores a blendable series of poses to help a character aim a weapon. We will take an animation sequence and chop it up into usable poses for an Aim Offset, get the player's pitch/yaw location of the mouse and use that to determine which blended pose to use so that the character moves and aims in the location of the mouse (with some restrictions) as seen in the example below.

Completing the following steps will result in a similar character as depicted above:

1 - Creating Aim Poses

In this step, we update our default playable character and create all the poses that will be needed for the Aim Offset.

For this guide we are using the Blueprint Third Person Template project and have added the Animation Starter Pack to the project:



You can download the Animation Starter Pack for free through the Marketplace from the Epic Launcher.

Steps

In the Content Browser under the Content/ThirdPersonBP/Blueprints folder, open the ThirdPersonGameMode.

Under Default Pawn Class, click the drop-down menu and select the Ue4ASP_Character then Save and close the Blueprint.



We are changing the default playable character to use the one provided with the Animation Starter Pack.

In the Content Browser open the Content/AnimStarterPack folder, then click Add New and create a folder called AimPoses.



Drag the Aim_Space_Hip asset onto the AimPoses folder and select Copy.



This is the animation sequence that contains a range of motions for aiming a weapon that we will chop up into poses.

Inside the AimPoses folder, with Aim_Space_Hip selected, press Ctrl+W to duplicate it and name it Aim_Center.



Open the Aim_Center asset, click the Pause button from the playback controls, then click the ToFront button.



Right-click on the scrub bar in the timeline, then choose the Remove from frame 1 to frame 87 option.



With this, we now have a single frame containing a pose we can use in our Aim Offset.

In the AimPoses folder with Aim_Space_Hip selected, press Ctrl+W to duplicate it and name it Aim_Center_Down.

Open Aim_Center_Down, make sure it is on frame 0, then click the ToNext button and go to frame 20.



The character will now be aiming downward in the viewport, which is the pose we want to use for aiming down.

Right-click on the scrub bar in the timeline, then choose the Remove frame 0 to frame 20 option.



Depending on where you Right-click on the scrub bar, the frame range may be off by a frame or two, just make sure the character is aiming down.

Right-click on the scrub bar in the timeline again, then choose the Remove from frame 1 to frame 68 option.



In the AimPoses folder with Aim_Space_Hip selected, press Ctrl+W to duplicate it and name it Aim_Center_Up.

Open Aim_Center_Up, make sure it is on frame 0, then click the ToNext button and go to frame 10.

Right-click on the scrub bar in the timeline, then choose the Remove frame 0 to frame 10 option.



Right-click on the scrub bar in the timeline again, then choose the Remove from frame 1 to frame 78 option.



Duplicate the Aim_Space_Hip asset each time and create each of the remaining poses based on the table below.

Anim Name

Start At Keyframe

Remove Frames 1

Remove Frames 2

Aim_Left_Center

30

0 - 30

1 - 57

Aim_Left_Up

40

0 - 40

1 - 48

Aim_Left_Down

50

0 - 50

1 - 37

Aim_Right_Center

60

0 - 60

1 - 27

Aim_Right_Up

70

0 - 70

1 - 17

Aim_Right_Down

80

0 - 80

1 - 8

For each animation, be sure to start at the suggested Start At Keyframe frame, then Right-click on the scrub bar and Remove Frames 1, Right-click on the scrub bar again and Remove Frames 2. Each of your animations should be a single frame with the character aiming in the direction of its corresponding name. When you have created each, your AimPoses folder should have several poses in it for each aiming direction.



In the Content Browser, Shift and select each of the aim poses.



Right-click and under Asset Actions, select the Bulk Edit via Property Matrix option.



In the Property Matrix, under Additive Settings, change the Additive Anim Type to Mesh Space.



For an animation to be compatible with an Aim Offset, it must be set to use an Additive Anim Type of Mesh Space.

Change the Base Pose Type to Selected animation frame, then under Base Pose Animation, click the pick asset icon and choose Idle_Rifle_Hip.



This Base Pose Type will define how the additive delta is to be calculated.

Once you have done so, return to the Content Browser and click the Save All button.



With each of our pose assets created, in the next step, we will the poses to create our Aim Offset.

2 - Creating the Aim Offset

In this step, we take each of our aim poses and create our Aim Offset which will blend between each of the poses.

Steps

In the Content/AnimStarterPack/UE4_Mannequin/Mesh folder, Right-click on the UE4_Mannequin and select Create Aim Offset.



This will create the Aim Offset asset based on this Skeleton.

In the Aim Offset window (center window), under Parameters, enter the parameters shown below.



Set the X Axis Label to Yaw and Y Axis Label to Pitch, then set both Axis Ranges to -90 to 90 and click Apply Parameter Changes.

Aim Offsets work very similar to Blend Spaces and will allow us to blend between our poses based on our parameters.

In the Asset Browser, search for Aim, then drag the Aim_Center animation onto the graph in the center position as shown below.



Drag the Aim_Center_Up to position 1 and Aim_Center_Down to position 2 as shown below.



Optionally, you can turn off the tooltip in the grid by unchecking the Enable Tooltip Display option.

Drag the Aim_Left_Center to position 1 and Aim_Right_Center to position 2 as shown below.



Add the Aim_Left_Up (1), Aim_Right_Up (2), Aim_Left_Down (3) and Aim_Right_Down (4) poses to finish the Aim Offset.



In the Asset Details panel, set the Preview Base Pose option under Additive Settings to Idle_Rifle_Hip.



You can preview the blending of poses by moving your mouse within the grid, the viewport mesh will update its pose based on your mouse position.

The Aim Offset is now setup, in the next step we will hook it up for use within our Animation Blueprint so that gameplay can drive the blending.

3 - Implementing the Aim Offset

In this step, we add the Aim Offset to our Animation Blueprint and hook it up to our existing Anim Graph.

Steps

In the Content/AnimStarterPack folder, open the UE4ASP_HeroTPP_AnimBlueprint and Double-click the AnimGraph in the MyBlueprint panel.



From the Asset Browser tab, drag in your Aim Offset asset.



Connect the Aim Offset as shown below, then Right-click on the Yaw and Pitch pins and Promote to Variable and name them Aim Yaw and Aim Pitch.



These two variables will be populated by where the player is aiming using their mouse and will drive the pose in our Aim Offset.

In the MyBlueprint panel, jump over to the EventGraph.



In the EventGraph, locate the Sequence node within the Movement portion of the script.



Click the Add pin button on the Sequence node.



From the MyBlueprint panel, hold down Alt and drag in both the Aim Yaw and Aim Pitch and connect to Sequence node.



Drag off the Cast To Ue4ASP_Character node and add the Get Control Rotation and Get Actor Rotation nodes.



Drag off the Get Control Rotation node and add a Delta(Rotator) node.



Connect the Get Actor Rotation to the Delta(Rotator) B Pin, then off the Return Value add an RInterp To node (and swap the connection from Current to Target).



You can hold Ctrl and Left-click on the Current pin to drag its connection to the Target pin.

Drag off the Current pin of the RInterp To node and select Make Rotator.



From the MyBlueprint panel, hold Ctrl and drag in the Aim Pitch and Aim Yaw variables and connect them to the Make Rotator node's Pitch and Yaw.



At the start of the Movement script, find the Event Blueprint Update Animation node and promote Delta Time X to a variable called Time and connect as shown.



Back on the RInterp To node, connect the new Time variable and set the Interp Speed to 15.



We are going to use the rotation of the character and the rotation of the player's input to create a new rotator that will limit how much the character can turn in a direction.

Off the RInterp To node, add a Break Rotator and Clamp Angle of Pitch and Yaw with min/max angles set to -90 and 90 respectively.



Connect the Clamp Angle from the Pitch to Aim Pitch and the Yaw to Aim Yaw.



The Aim Yaw and Aim Pitch values that drive our Aim Offset now take into account the character's rotation, the player's current controller rotation and are clamped to prevent the character from turning too far in one direction. Without clamping the angle degrees, the character's legs could be pointed forwards while the character turns all the way around and points in the opposite direction which is probably something we want to avoid.

We are just about done with our setup, in the next step, we will tie everything together and test out our character's ability to aim.

4 - Finishing Up

In this final section, we will update our Character Blueprint to change how controller rotation is handled as well as fix some minor issues before testing.

Steps

In the Content/AnimStarterPack folder, open the Ue4ASP_Character Blueprint.

Cick on Ue4ASP_Character in the Components window, then in the Details uncheck Use Controller Rotation Yaw.



This will prevent the character from automatically turning to the location of the Controller's yaw.

Cick on CapsuleComponent in the Components window, then in the Details check the Hidden in Game option.



This will hide the debug collision display during gameplay.

Click the EventGraph in MyBlueprint, then find the Crouching section and replace the InputAction Crouch node with a C Key Event.



This will remove the yellow warning sign on the compile button in the upper left corner of the window since the project does not have an Action Mapping for Crouch by default, we are going to use the C button to crouch (you can use any Key Event you wish for this).

Compile and Save, then close the Blueprint.

Remove the ThirdPersonCharacter from the level.



This will make sure that we use the character assigned to Game Mode and not the one placed in the level.

Click the Play button to play in the editor.

End Result

When you play in the editor, the character will now aim while stationary and will react to mouse movement, pointing in the direction of your mouse. There are some restrictions in place that prevent the character from turning and facing backward while the mouse is behind them as well and while the character is jogging, moving the mouse also turns the character's torso in the direction you are pointing.

You can take this a few steps further by allowing the character to aim in a direction and play a shooting animation in that direction and (or) allow the character to play a shooting animation while moving in a direction or crouching by layering animations over the existing animations. Or, you can take a look at Skeletal Mesh Sockets for examples on how to attach a weapon to the character's hands now that they can aim.

Blend Spaces

Blending with Blueprints

Animation blending, as a concept, simply means making a smooth transition between two or more animations on a single character or Skeletal Mesh. In Unreal Engine, there are various ways in which such blending can be applied. In this document, we will overview each one and how they can be applied to your characters.

Blend Spaces

One of the most common ways to blend together animations is with Blend Spaces.

For more information on Blend Spaces, please see the Blend Spaces documentation.

Blending with Blueprints



Animation blending can also be handled directly by way of the AnimGraph within an Animation Blueprint. The AnimGraph charts the flow of animation pose data through a series of different nodes, each node contributing in some way to the final look of the pose or motion. There are a variety of nodes specially designed to aid in blending multiple poses together in some way. These can be additive, literally combining two animations based on a weighted bias or alpha value, or can be direct overrides of the existing pose. You can also send animation directly to a specific bone in the Skeleton and all of its children. For instance, you can start with an animation in which the character is running, but then selectively apply a waving animation just to the right arm. The final result will be the character running and waving.

For an understanding of how animation blending can be handled with Blueprints, please see Animation Blueprints and Blend Nodes.

Animation Blueprints

Graphing in Animation Blueprints



Character Object Reference

Movement Component Reference

Velocity

Thread Safe

Character Speed

Thread Safe

Movement Threshold

Thread Safe

Jumping and Falling

Thread Safe

EventGraph Reference

When developing Animation Blueprints for characters in Unreal Engine, it can be helpful to implement dynamic movement and locomotion variables to control animation behaviors.

This document will explain how to set up the EventGraph Animation Blueprint logic to calculate these variables in your own project. In addition, this document will also provide an explanation of how to calculate these variables in a thread safe blueprint function, using property access nodes to increase your projects performance and stability.

A controllable Third Person Character with a movement component.

You can supplement this requirement with the Third-Person template project if needed.

Character Object Reference

Most animation variables can be calculated using the character's movement component in the EventGraph. In order to use the character's movement component to calculate other animation variables, a reference variable must be created.

First, in the EventGraph of the character's Animation Blueprint, create an Event Blueprint Initialization Animation node.



From the Event Initialization node, create a Cast node that casts the animation blueprint to the character's blueprint.

In the workflow example, the character's blueprint is the BP_ThirdPersonCharacter found in the Third Person template project.

Then create a Get Owning Actor node and connect the Return Value output pin of a to the Cast node's Object input pin.



Next, right-click the cast node's As Character output pin and select the Promote to Variable option from the context menu, to create a character object reference variable.

After connecting the logic, a character object reference variable is accessible in your blueprint's EventGraph and AnimGraph.



Movement Component Reference

In order to isolate the character's Movement Component from the Character Object, a Get Character Movement node is needed. From the Set Character variable node's Character output pin, create a Get Character Movement node.



Next, right-click the Character Movement output pin to a variable, and select promote to variable from the context menu, to create a movement component reference variable.



After connecting the logic, a character movement component reference variable is accessible in your blueprint's EventGraph and AnimGraph.



Velocity

A character's velocity can be a helpful value to use when calculating animations that require direction or speed.

To create a velocity variable in the EventGraph, first create an Event Blueprint Update Animation node.

Next, add the Movement Component reference variable to the EventGraph. Then, you can use a Get Velocity node, to calculate the vector value that represents the movement component's direction and magnitude of movement.



Next, right-click the Velocity output of the Get Velocity node and select the Promote to Variable option from the context menu to create the velocity variable.

After connecting the logic, a Velocity variable is accessible in your blueprint's EventGraph and AnimGraph.



Here, a Print String node is sending a debug message every frame with the updated X, Y and Z values of the character's velocity.



Thread Safe

First create a new thread safe function in your character's animation blueprint.

Then, right-click in the graph to create a property access node.

From the property access node's drop down menu select the function, Try Get Pawn Owner > Get Movement Component > Velocity. Then right-click the vector output pin and select promote to variable, to create a velocity variable.



After connecting the logic, a Velocity variable is accessible in your blueprint's EventGraph and AnimGraph.



In order to update this function during your project's runtime, add the thread safe Velocity function to the Blueprint Thread Safe Update Animation graph.



Your character's Animation Blueprint now calculates the character's velocity in a thread safe manner.

Character Speed

Character movement speed can be a helpful variable to use when selecting animations based on a character's speed, such as running or walking states.

You can create a Vector Length XY node from the velocity variable to isolate the character's speed from the movement component velocity.

Next, right-click the Vector Length XY node's Return Value output pin to select Promote to Variable from the context menu.



After connecting the logic, a Speed variable is accessible in your blueprint's EventGraph and AnimGraph.

Here, a Print String node is sending a debug message every frame with the updated value of the character's speed.



Thread Safe

First create a new thread safe function in your character's Animation Blueprint.

Next, create a property access node and select the Try Get Pawn Owner > Movement Component > Velocity function from the drop-down menu.

From the property access node's output, create a Vector Length XY node to extract the forward and lateral motion (X and Y axis).



In order to update this function during your project's runtime, add the thread safe Speed function to the Blueprint Thread Safe Update Animation graph.



Your character's Animation Blueprint now calculates the character's velocity in a thread safe manner.

Movement Threshold

To control when your character's movement should trigger animation playback, you can create a Movement Threshold variable that will allow movement when the character's speed reaches a set magnitude.

From the character's speed variable in the EventGraph, create a Greater Than or Equal To (>=) node and set the value to a low number.

This number can be a very small value like 0.1.

Right-click the boolean output pin of the Greater Than or Equal To (>=) node, and select Promote to Variable from the context menu.



After connecting the logic, a Movement Threshold variable is accessible in the Animation Blueprint's EventGraph and AnimGraph.

Here, a Print String node is sending a debug message every frame with the updated state of the character's movement threshold variable.



Thread Safe

First, create a new thread safe function in your character's Animation Blueprint.

Create a property access node in the thread safe graph, and set the node to Try Get Pawn Owner > Movement Component > Velocity. Extract the forward and lateral movement with the Vector Length XY function node.

Then with a Greater Than or Equal To (>=) node, set the speed threshold at which movement animation should not occur.

This number can be a very small value like 0.1.

Right-click the boolean output pin of the Greater Than or Equal To (>=) node, and select Promote to Variable from the context menu.



In order to update this function during your project's runtime, add the thread safe Should Move function to the Blueprint Thread Safe Update Animation graph.



Your character's Animation Blueprint now calculates the character's movement threshold variable in a thread safe function.

Jumping and Falling

You can use a Jumping and Falling variable to determine when to play jumping and landing animations in the character's AnimGraph.

First create a Movement Component variable into your Animation Blueprint's EventGraph.

You can now create a IsFalling function node from the movement component reference variable node.

Right-click the Is Falling node's Return Value output pin, and select the Promote to Variable Option from the context menu.



After connecting the logic, a Jumping and Falling variable is accessible in the Animation Blueprint's EventGraph and AnimGraph.

Here, a Print String node is sending a debug message every frame with the updated state of the character's Jumping and Falling variable.



Thread Safe

First create a new thread safe function in your character's Animation Blueprint.

Create a property access node and set the node to Try Get Pawn Owner > Get Movement Component > IsFalling.

Right-click the property access node's output pin and select the Promote to Variable option from the context menu.



In order to update this function during your project's runtime, add the thread safe Is Falling function to the Blueprint Thread Safe Update Animation graph.



Your character's Animation Blueprint now calculates the character's jumping and falling state variable in a thread safe function.

EventGraph Reference

Here you can reference the full Event Blueprint Update Animation logic in the EventGraph used in the example workflow.



Animation Sequences

Animation Blueprints

Skeletons

Skeletal Mesh Animation System

Overview

Steps

End Result

Overview

When setting up characters and animation for those characters, there may be instances where you want to have one character perform an animation for an action and have another character perform a different animation for the same action. By using the Asset Override Editor inside of a child Animation Blueprint, you can override any previously set animation asset used in a Sequence Player Node allowing you to quickly create variations of Animation Blueprints that each of your characters can use.

Be aware that the only functionality that should be changed via a Child Anim Blueprint is the animation sequences. Changing other properties such as the Skeleton or introducing Animation Layers is not supported.

For this guide, we are using the Blueprint Third Person template and included the Infinity Blade: Warriors and Animation Starter Pack assets which are available for free via the Marketplace.

We also performed some Animation Retargeting and retargeted the Animation Blueprint and Animations that came with the Animation Starter Pack for use with the Infinity Blade characters.

Steps

Right-click on the Animation Blueprint you would like to override animations for and select Create Child Blueprint Class.



Open the child Animation Blueprint, then click Window from the File Menu and select Asset Override Editor.



The Asset Override Editor will open showing the available animations which can be overridden.



You can expand/collapse the display of assets by clicking the arrow next to each asset.

In the Asset column, click the drop-down window and specify the new asset to use (which will override the existing when called).



Clicking the eyeball icon will allow you to see a preview of the node context in the parent graph as read only in the main graph panel.



You can view your changes after you click Compile.

End Result

Below is an example where a character's default movement (assigned as Jog) in the parent Animation Blueprint is overridden so that the character performs a Walk instead.

A prime usage case for this is if you have a character that performs a certain attack when a button is pressed but you want a different character to have the same general movement but perform a different motion when the attack button is pressed.

1 - Required Setup

2 - Applying AnimDynamics

One way you can improve the realism in your character's movement is to provide dynamic animations for items that they may be carrying or wearing. With AnimDynamics those pieces that you would expect to move around as you move in real life (hair, necklaces, bracelets, swords, pouches, etc.) will bounce around and move while your character moves.

In this How-to we will apply AnimDynamics to a character to achieve the effect seen below:

Above, the character has AnimDynamics applied to the harness and furnace that is being carried around the character's neck. As the character moves, the harness shifts slightly while the furnace has a bit more movement forwards/backwards. The amount of movement can be adjusted via the Details panel of the AnimDynamics node to achieve the effect you are looking for. Additional constraints can be added as well to manipulate just how the bones move.

If you already have a character with an AnimBlueprint and bones ready to drive with AnimDynamics, you can proceed to step 2.

1 - Required Setup

Before we get started with applying dynamic animations to our character we need to set up the character we wish to use. The template characters do not have any dynamic bones we can use so we will retarget animations from the template character over to an Infinity Blade character who has bones that we can influence with AnimDynamics.

For this guide, we created a New Project using the Blueprint Third Person template.

We then added the Infinity Blade: Adversaries pack which is available for free on the Marketplace to the project.



With your Blueprint Third Person based template project open and the Infinity Blade assets added:

In the Content Browser under Content/Mannequin/Character/Mesh, open the UE4_Mannequin_Skeleton asset.



Click the Retarget Manager button, then under Select Rig assign the Humanoid rig.



We are going to retarget this character's AnimBlueprint and Animations to an Infinity Blade character.

In the Content Browser navigate to and open the SK_Master_Grunt_Skeleton in the Infinity Blade Adversaries folder.



Click the Retarget Manager button, then select Humanoid under the Select Rig option.

For each node on the Rig, assign a Bone from the Skeleton.



The full assignment is shown in the table below.

Node (Rig)

Bone (Skeleton)

Root

b_MF_Root

Pelvis

b_MF_Pelvis

spine_01

b_MF_Spine_01

spine_02

b_MF_Spine_02

spine_03

b_MF_Spine_03

clavicle_l

b_MF_Clavicle_L

upperarm_l

b_MF_UpperArm_L

lowerarm_l

b_MF_Forearm_L

hand_l

b_MF_Hand_L

clavicle_r

b_MF_Clavicle_R

upperarm_r

b_MF_UpperArm_R

lowerarm_r

b_MF_Forearm_R

hand_r

b_MF_Hand_R

neck_01

b_MF_Neck

head

b_MF_Head

thigh_l

b_MF_Thigh_L

calf_l

b_MF_Calf_L

foot_l

b_MF_Foot_L

thigh_r

b_MF_Thigh_R

calf_r

b_MF_Calf_R

foot_r

b_MF_Foot_R

Before we proceed with retargeting, we will adjust the Translation Retargeting to ensure that our animations play correctly.

In the Skeleton Tree, click the Show Advanced Options button.

Right-click on the b_MF_Root bone and select Recursively Set Translation Retargeting Skeleton.



Under Translation Retargeting, set b_MF_Root to Animation and b_MF_Pelvis to Animation Scaled.



Our Skeleton is set up and we can now retarget the AnimBluperint and Aniamtions from the template character.

Navigate to the ThirdPersonAnimBP and Right-click on it and select Duplicate Anim Blueprints and Retarget.



In the Select Skeleton window, select the SK_Master_Grunt_Skeleton asset then choose Retarget.



You can click the Change... button to assign where the retargeted assets are copied to if you like.

Navigate to the duplicated assets and rename the new AnimBlueprint to GruntAnimBP.



Navigate to and open the ThirdPersonCharacter Blueprint.



Click the Mesh in the Components window, then assign the SK_Master_Grunt and GruntAnimBP_C in the Details panel.



Compile and Save, then close the Blueprint.

At this point if you play in the Editor, you should be controlling the Grunt Character who can run and jump with WASD and Spacebar.

Notice the limited movement of the harness and furnace around the characters neck. It appears relatively static and our character would look more natural if these objects moved along with the character's movement.

In the next step we will use the AnimDynamics node to animate the harness and furnace so it reacts to character movement.

2 - Applying AnimDynamics

Now that our character is set up with an Animation Blueprint and has bones that we want to dynamically animate, we can do so from the AnimGraph of our Animation Blueprint with the AnimDynamics node.

In our example, the character is carrying a large furnace around their neck that we want to be animated based on character movement. If you are using your own character, you can follow the steps below and assign the bone(s) you want to drive with AnimDynamics and adjust the settings as desired.

Steps

In the Content Browser, open the character's Animation Blueprint (GruntAnimBP).



Click MyBlueprint, then AnimGraph to open the Animation Graph.



Right-click in the graph and search for and add the AnimDynamics node.



The AnimDynamics node takes in an External Force value which is additional force to apply to all bodies in the simulation (this is optional, but may be something to consider). It also takes in the Component Pose which is the reference pose data as well as an Alpha value (the strength with which to apply the skeletal control, where 0 is no strength and 1 is full strength).

Copy and Paste the node, then connect the nodes as shown below.



The Local to Component and Component to Local will be automatically created when connecting pose pins.

In our example we are using two AnimDynamics nodes (one to affect the Harness and another to affect the Furnace).

Select the first AnimDynamics node in the sequence, then in the Details panel assign the settings shown below.



The Preview section is all about visualization, which helps to indicate the current limits applied to the movement in the viewport. You can also see Collision Spheres if you are using Planar Limits and CoM (Center of Mass) is not enabled. This is outside the scope of this example but you can experiement with this setting.

The last thing we set is the Bound Bone or bone we are affecting which we set to the furnace bone on our character (this bone affects the Harness).

With the node still selected, set the Setup and Constraint sections as shown below.



The Setup and Constraint sections are where you define the movement and range of movement for the bone driven by AnimDynamics. The Box Extent provides the inertia, the Local Joint Offset defines the pivot point, and Angular Limits provide the rotational range of movement (which is indicated by the preview visualization options when enabled).

Please see AnimDynamics section of Skeletal Controls for more information on Setup and Constraint settings.

Click Compile and notice how the harness object tilts to the side.



The Angular Limits for the Y axis is quite large right now indicated by the green cone in the picture above. Let's reduce this range.

With the node still selected, in the Constraints section, adjust the Angular Limits for Min/Max as shown below.



When you Compile this time, the harness should not shift as much to either side (even if you adjust the Speed or IsInAir? settings).



Select the second AnimDynamics node in the sequence and use the following settings.



Click for full view.

With the settings above, we changed the Bound Bone to now target the Furnace_Pivot bone in our character which affects the furnace object. We also adjusted the Twist Axis so that it twists on the Y axis providing back-and-forth movement instead of side-to-side. The Angular Limits are set to -50 and 50 as the range in which to move.

Compile and Save then play in the editor.

End Result

You should now see that the furnace for our example character bounces around as the character moves based on our constraint settings.

Feel free to experiment with the Box Extent and Local Joint Offset values in the Setup section as well as the Linear and Angular Limits in the Constraints section to see how it alters the movement of our bones affected by AnimDynamics.

Blend Spaces

Creating an Aim Offset

State Machines

Skeletons

Steps

End Result

Blend Spaces are special assets which can be sampled in AnimGraphs that allow for blending of animations based on the values of two inputs. Simple blending between two animations based on a single input can be performed using one of the standard Blend Nodes available in Animation Blueprints. Blend Spaces provide a means of doing more complex blending between multiple animations based on multiple values (currently limited to two).

In this How-to, we use a Blend Space to blend between walking and jogging animations based on the character's movement speed and movement direction.



Steps

For this guide, we are using the Blueprint Third Person Template project and have added the Animation Starter Pack to the project.



You can download the Animation Starter pack for free through the Marketplace from the Epic Launcher.

In your project in the Content/ThirdPersonBP/Blueprints folder, open the ThirdPersonGameMode and set the Default Pawn Class to Ue4ASP_Character.



This will allow us to use the playable character that was created along with the Animation Starter Pack project.

In the Level, select the ThirdPersonCharacter and delete it from the level.



We need to delete this character from the level in order to spawn in as the character from the previous step.

In the Content/AnimStarterPack/UE4_Mannequin/Mesh folder, right-click on the UE4_Mannequin and under Create, select Blend Space and give it a name.



Blend Space assets need a Skeleton asset to reference, here we are using a shortcut to create a Blend Space from this Skeleton asset which we called MyBlendSpace.

Inside the Blend Space, in the Asset Details panel under Axis Settings, add the following values:



The Horizontal Axis will determine the Direction we are moving in degrees:

Horizontal Axis Settings

Value

Name

Direction

Minimum Axis Value

-180

Maximum Axis Value

180

Number of Grid Divisions

4

Interpolation Time

0

Interpolation Type

Averaged Interpolation

The Vertical Axis will determine the Speed in which our character is moving:

Vertical Axis Settings

Value

Name

Speed

Minimum Axis Value

0

Maximum Axis Value

250

Number of Grid Divisions

4

Interpolation Time

0

Interpolation Type

Averaged Interpolation

In the Asset Browser, drag the Walk_Fwd_Rifle_Ironsights animation to the center-bottom position on the grid.



This will be are starting position when we enter this Blend Space.

Drag the Walk_Lt_Rifle_Ironsights animation to location 1 and Walk_Rt_Rifle_Ironsights animation to location 2 below.



Here we place the animations to use when moving left or right.

Drag the Walk_Bwd_Rifle_Ironsights animation to locations 1 and 2 below.



Here we place the animation to use when moving backward.

From the Asset Browser, drag the Jog_Fwd_Rifle animation to the top-center position on the grid.



This allows us to use a different animation when our speed is at max 250 and we are not moving left or right, we are jogging forward.

Drag the Jog_Lt_Rifle animation to location 1 and Jog_Rt_Rifle animation to location 2 below.



Drag the Jog_Bwd_Rifle animation to locations 1 and 2 below.



In the Content/AnimStarterPack folder, open the UE4ASP_HeroTPP_AnimBlueprint then in the My Blueprint panel, Double-click the Locomotion graph.



Double-click the Jog State to open its graph.



This State Machine already has a Jog State and in it, a Blend Space for different Jogging motions.

From the Asset Browser, drag the MyBlendSpace asset into the graph and replace the BS_Jog Blend Space as shown below.



The default Blend Space does not include Walking states which our Blend Space does, so let's replace it with ours!

In the Content/AnimStarterPack folder, open the Ue4ASP_Character.

Locate the section marked Crouch in the graph and delete it to remove the warning error.



By default, the Animation Starter Pack has bindings created for crouch which our project does not. For this example, we will remove the ability to crouch walk.

Right-click in the graph and add a Left Shift Key Event, then drag the CharacterMovement into the graph from the Components tab.



When we press and hold the Left Shift button, that will toggle us from walking into a jog.

Drag off the CharacterMovement node and Set Max Walk Speed for Pressed and Released with the values 250 and 100 respectively.



We are changing our movement speed based on if Left Shift is held and will alter our character's movement speed in-game.

Click the CharacterMovement component, then in the Details panel set the Max Walk Speed to 100.



We need to update our character's default movement speed so they start out walking.

Click the CapsuleComponent in the Components tab and in the Details panel, check the Hidden in Game option.



This will turn off the collision capsule debug display in-game.

Click Compile then click the Play in editor button from the Toolbar.

End Result

When playing in the Editor, using WASD to move around, the character will now walk by default and blend between walking animations when changing directions. While standing, pressing and holding Left Shift while using WASD will cause the character to blend from the walk/aim animation to a lowered/aim jog animation, essentially creating a sprint for the character.

Skeletal Meshes

Physics-Based Animation

Animation Blueprints

State Machines

Artificial Intelligence



Workflow at a Glance

Creating Art Assets

Importing Skeletal Meshes

Creating a Player Controller

Creating a Pawn or Character Blueprint

Animation Blueprint

GameMode Setup

Summary

Included Examples

No matter your game project or genre, it is likely that at some point you are going to need some kind of animated character to move around in your environment. This may be a character that the player controls or may be some AI-driven entity that interacts with the world in some way. Regardless, you are going to need to know how to set such characters up so that they can properly animate in your world. The purpose of this document is to give you a very high-level overview of how this is done while guiding you to dedicated documents and examples for specific details. For our purposes, we will assume that you want to create a character that is controllable by the player in some way.

Throughout this document, we will make references to various scripting operations that can be done with Blueprints. Anything that can be done in Blueprints can also be done in C++, so you should not feel restricted solely to Blueprint visual scripting. The final section of this document contains references to example content showing the setup in both C++ and in Blueprints.

You can also find an example of the Playable Owen Character on the Animation Content Examples page under section 1.10.

Workflow at a Glance

The primary workflow for character setup in Unreal Engine is as follows:

Create your art assets (Skeletal Meshes) and animations, using a 3rd party digital content creation (DCC) package such as 3ds Max or Maya.

Import your Skeletal Meshes and animations into Unreal Engine by creating a new Skeleton asset for new Skeletal Meshes or by reusing an existing Skeleton asset for identical or similar Skeletal Meshes.

Create a PlayerController script or Blueprint to handle inputs from the player.

Create a Blueprint or script for a Character or Pawn to parse inputs and control the actual movement (not skeletal animation) of the character.

Construct the Animation Blueprint for the character.

Create a GameMode script or Blueprint that utilizes your custom PlayerController and any other custom script assets.

Play your game!

Each of these steps will generally require a wide variety of further sub-steps to be completely successful. This list just gives a general idea of the flow. In the following sections, we will go into further detail on exactly what each one of these steps means and how you can apply them.

Creating Art Assets



In many ways, the creation of your art assets may be the most challenging part of the character development process. Generally, there is significant design, modeling, surfacing, rigging, and animation time that must take place long before you even touch the Unreal Engine. While we cannot teach you the nuances of character design and animation, we do have certain tools to help the process along.

Importing Skeletal Meshes



For more information, please see the FBX Importing and Skeletal Meshes documentation.

Properly importing your Skeletal Meshes into Unreal Engine is a vital step in the process of creating your animated characters. Unreal contains a robust importing system with a variety of options to speed up your import process.

Creating a Player Controller



The PlayerController is a special type of script or Blueprint whose primary purpose is to parse inputs from the player into events that can drive a character. For instance, it can control how moving the analog stick on a controller upward can cause an event that will eventually be used to push the character forward on the screen.

A PlayerController is already an existing Class within Unreal. In the editor, you can create a new Blueprint with a parent class of PlayerController, and then use this to set up your events that will take place upon inputs from the player.

For an example of a custom Blueprint PlayerController, you can start a new project within the editor (File > New Project) and check out the Blueprint Top Down template. All of the Blueprint-based templates will contain a PlayerController of some sort (either the default Player Controller or a Player Controller Blueprint), though if you want to see a custom application using a Player Controller, the Blueprint Top Down template is the most straight forward.

Once within the new project, you can search within the Class Viewer for PlayerController, turning off the filters in the Class Viewer. Double-clicking on this asset will open it up and you can see the setup for yourself.

You can also see a PlayerController in C++ script by creating a new project (File > New Project) and choosing the C++ Top Down template.

Creating a Pawn or Character Blueprint



Once you have set up your PlayerController, your system is now prepared to handle inputs from the player. Now, however, you have to translate those inputs into something that can in turn drive a character around on the screen. That means those inputs need to be translated (or parsed) into actions. This is where the Pawn or Character classes come into play.

Choosing Pawn or Character

You will notice that we mention two potential classes here: Pawn and Character. Both are used for entities in the game that are either controlled by the player or by in-game AI. The key difference is that the Character class is an extension of the Pawn class, adding in player physics, support for a specific mesh, and the general types of handling needed when creating a playable in-game character. For our purposes, we will be using the Character class. For simpler elements that would just need to be driven around the scene by AI, for example, you can generally get away with using a Pawn.

Character Class Setup



Your Character Class is going to start with events that are triggered from the PlayerController, and use scripting (including Blueprint visual scripting) to control what to do with those inputs and how they can be used to control the character. For instance, where the PlayerController simply creates a basic event for moving the analog stick on a controller in an upward direction, the Character class is responsible for receiving that event and using it to drive the character forward.

The Character Class also holds a reference to a Skeletal Mesh, which will be the basis for what the player sees while playing the game. In the case of a first-person game, this is often just a pair of floating arms, though there may be a full body if you need that body to shadow the environment properly. For third-person games, the mesh will be the Skeletal Mesh that represents the character.

Motion on a character is generally handled by applying some motion to the physics shape (typically a capsule). This motion also coincides with a MovementMode. This is an enumeration used to keep track of what a character is doing (i.e. walking, running, falling, swimming, etc.). This information will later be used to drive what animations are being played on the Skeletal Mesh.

For an example of a custom Blueprint Character class, you should start a new project within the editor (File > New Project) and choose either of the Blueprint templates for First Person or Third Person. All of the Blueprint-based templates will contain a Character of some sort, though we recommend the First or Third Person templates due to their overall simplicity and the common use of those genres.

Once within the new project, you can search within the Class Viewer for Character, filtering by Blueprints in the Game folder. Double-clicking on this asset will open it up and you can see the setup for yourself.

You can also see a Character in C++ script by creating a new project (File > New Project) and choosing either the First or Third Person Code templates.

Animation Blueprint



You do most of the heavy lifting of hooking up animation to Characters in the Animation Blueprint.

After you have defined how a Skeletal Mesh Actor moves around in the world in the Character Blueprint, you can start assigning specific animations based on those movements (such as velocity) in the Animation Blueprint.

Animation Blueprints are by far the most sophisticated aspect of character setup. This is where all of your data comes together to cause your Skeletal Meshes to perform the appropriate animations. To fully understand Animation Blueprints and their power, there are many different animation assets that you should know about, including:

State Machines

Blend Spaces

Sequences

These are just the tip of the iceberg. You would do well to look at the Animation Blueprint documentation, and to also look at some of the Animation Blueprints included in some of our examples content, such as the First and Third Person Templates and those found within the Content Examples project.

Once you have created the Animation Blueprint that defines the motion of your character, you will need to make sure you assign it to the Anim Blueprint Generated Class property, found under the Mesh Component of the Character Blueprint. This is necessary because you may have multiple Animation Blueprints for each Skeletal Mesh, and the Character Blueprint needs to know the one into which it will be sending the necessary animation and variable data.

GameMode Setup



A GameMode is a special type of class that is used to define your game. Generally speaking, is it going to be just a collection of properties used to define what the essential classes for your game are going to be. The primary properties you will set up include:

Game Session Class - This class of Game Session handles loging approval and online game interface.

Game State Class - This class controls any special rules or setup for how your game will be played, but is not covered in this document.

Player Controller Class - This will hold the custom PlayerController you set up for your in-game character.

Player State Class - This class defines any special rules for replicating relevant player information to all clients.

HUD Class - This contains any special heads-up display (HUD) classes created, which are not covered in this document.

Default Pawn Class - This will hold the Character class you set up for your in-game character.

Spectator Class - This holds any special classes used to control spectators or passive players that just watch the action. These are not covered in this document.

Replay Spectator Class - This holds any special classes used to control spectators when in a replay. These are not covered in this document.

Server Stat Replicator Class - Class used to replicate server "stat net" data over.

For testing out your character, you need to at the very least set up the Default Pawn Class and the PlayerController Class properties.

World Settings



Once you have set up your GameMode, the last step to being able to play with your custom Character is to make sure that the current Level is using your GameMode. This is done using the World Settings tab, accessible from the Settings button located on the main toolbar.

Within the World Settings, you will want to make sure you have set the GameMode Override to the name of your GameMode class. Once you have done that, you are ready to save and test out your new character!



Summary

So, to summarize the flow of setup back up the chain:

Your Level's World Settings are used to set which GameMode you are using.

The GameMode specifies which Pawn (Character) Class and which PlayerController Class you will need to play the game.

The Character Class:

Contains the Skeletal Mesh that you imported via FBX.

Takes in data from the PlayerController Class and converts it to the movement (not animation).

Stores which Animation Blueprint will be used to drive skeletal animation within its Mesh Component.

The Animation Blueprint:

Takes data from the Character Class into its Event Graph.

Uses that data to drive State Machines, Blend Spaces, and other assets.

Those assets use Animation Sequences (skeletal animation data from an FBX file) to animate the character.

The final result of the Animation Blueprint is applied to your Skeletal Mesh so that you can see the in-game character animate.

Included Examples

There are several examples you can check out in the engine to see how these setups are done and try them for yourself. We include both Templates, which are basic project genres you can use to make your games, and Content Examples, which are pre-constructed examples of content created by artists and technicians here at Epic.

Templates



When you create a new project in Unreal Engine (File > New Project), you are given the option to choose a Template. Virtually all of these will use their GameModes, Character Blueprints, Animation Blueprints, and every asset mentioned in this document. For purposes of simplicity and clarity, we strongly recommend you check out the First Person or Third Person Templates.

Each of these Templates is available in a coded form or a Blueprint form so that you can choose to develop it in the way that you are most comfortable. If you are a coder, you will probably want to use a Code Template. If you are a more artistic developer, you will likely be more comfortable exploring a Blueprint Template. Be aware that the two are not mutually exclusive; you can add code classes to a Blueprint Template project, just as you can add new Blueprint classes to a Code Template project!

Content Examples



Content Examples are specialized versions of content designed by artists and technicians here at Epic. They are found within a project named ContentExamples, which can be downloaded by users via the Marketplace. Of particular importance would be the assets found within the Animation map inside the Maps folder, which shows a variety of uses for Skeletal Mesh animation on a character.

Steps

End Result

When working with animated characters, there may be times when you want to apply the same animation data to an entirely different character. Using the Copy Pose From Mesh Animation Blueprint node and a little bit of Blueprint Visual Scripting, you can reference a Skeletal Mesh Component and copy whatever pose is being used to another Animation Blueprint for a different Skeletal Mesh.

In this how-to, we use the Copy Pose From Mesh node to copy the player's animations onto another Skeletal Mesh.



Steps

In the Content/ThirdPersonBP/Blueprints folder, duplicate the ThirdPersonCharacter Blueprint using the default name.



In the Content/Mannequin/Character/Mesh folder, right-click the SK_Mannequin and under Create, select Anim Blueprint and use the default naming convention.



Open the ThirdPersonCharacter1 Blueprint from Step 1 and delete all the nodes in the Event Graph.

Select the Mesh in the Components window, and then in the Details panel, set the Anim Class to UE4_Mannequin_Skeleton_AnimBlueprint.



Open the UE4_Mannequin_Skeleton_AnimBlueprint, and in the Anim Graph, add the Copy Pose From Mesh node and connect it to the Final Animation Pose, then promote the Source Mesh Component to a variable called Character Reference.



The Character Reference variable will refer to the Skeletal Mesh Component of the character we specify.

Inside ThirdPersonCharacter1 Blueprint, create a variable called Character Reference and set the Variable Type to Third Person Character, then enable Instance Editable.



Drag the ThirdPersonCharacter1 Blueprint into the level, then in its Details panel, assign the ThirdPersonCharacter from the level as the Character Reference variable.



By assigning the value here, we will have a reference to the character whose Skeletal Mesh Component we want to copy (in this case, the Player).

Open the UE4_Mannequin_Skeleton_AnimBlueprint and on the Event Graph use a Try Get Pawn Owner node to Cast to ThirdPersonCharacter1, then off the As Third Person Character 1 pin, get the Character Reference variable.



Off the Character Reference node, add the Get Mesh node and set the Character Reference variable inside the Animation Blueprint.



The Skeletal Mesh from the Player will now be copied and assigned to the Character Reference inside this Animation Blueprint, driving the character's pose.

From the Main Toolbar, Play in the Editor.

End Result

When you play in the Editor, the non-playable character will play the same animations as your player character.

As you move around, the other character in the level will copy your animation pose even though that character has no logic or State Machine driving the different poses. While this example copies the player, it is possible to set up a non-playable character (NPC) with AI and a State Machine driving animations, then have another NPC that has no logic copy the pose through the Copy Pose From Mesh node to mimic the same behavior and logic.

When using the Copy Pose From Mesh node, in the Details panel, you can enable Use Attached Parent which will look for an attached parent and use it as the source if the Source Mesh Component is not valid.



Also, you can Copy Curves in addition to Bone Transforms, which will copy the curves that exist in the current Skeleton. If the curve list has changed, it will require the animation system to be reinitialized.

Steps

Result

While you've been able to extract single frames of animation from an Animation Sequence for some time, you've been left to set up blends on your own. This changes with the use of Pose Assets which were implemented to support facial animation where either FACS (Facial Action Coding System) or viseme curves can drive poses. However, you could use this system to drive and create new animation by blending multiple poses. Pose Assets also support bone transform as well as blendshapes which makes them an extremely flexible asset.

This How-To will walk you through the creation of a Pose Asset.

Steps

To create a series of Pose Assets from a single animation, from the Content Browser, you can right-click an Animation Sequence and create an Pose Asset from it:



Once you create pose asset, the names will be auto generated by default. You can rename each pose or you can paste from clipboard.



You can then see the effect of each pose by changing their weights in the FacePose Panel.



Result

You now have a new Pose Asset to use in your animations.

To preview it make sure Preview Post Asset is set to your Pose Asset, and then add a Variable Curve to your animation that needs the Pose Asset data.



You can then add keyframes to the variable curve to drive the value of the pose weights, affecting the animation.

For these to work at run time, you'll also need to include a PoseAsset node in your Anim Blueprint.



It's also worth noting you can create a Pose Asset in the Animation Editor. You can use the Create Asset > Create PoseAsset > From Current Pose or Animation options:



Creating a Pose Asset



Animation Pose Assets

End Result

In this How-to we create a new walking animation that relies purely on curve data to drive the animation. By using a Pose Asset based on an existing Animation Sequence, we take two of the poses from the animation and blend between them to create our new walking motion. While this is a Full Body example used to create locomotion, you can take these same concepts and apply them to a facial animation to create Additive facial animation that is driven by curve data.

For this How-to, we are using the Blueprint Thirdperson Template project.

Inside the Content Browser under the Content/Mannequin/Animations folder, Right-click on the ThirdPersonWalk and select Create PoseAsset.



Use the default name for the new Pose Asset, then Double-click to open it.



Click for full view.

When creating a Pose Asset, the Pose Names will be automatically generated by default (as long as the curves exist in the animation). A pose will be created for each frame of the animation in which the Pose Asset was created from. You can adjust the curve weights for each pose to see the resulting pose when weight influence is applied. For example, above we adjusted the weight of Pose_6 and our character moves their right foot forward.

By default, all Pose Assets are set to Full Body and are not Additive which means the weight values are either 0 (no influence) or 1 (full influence). Setting a weight value in this case to 0.2 for example is the same as setting it to 1. For more granularity, you can set the Pose Asset to Additive however doing so to an animation that is applied to the full body of a character (such as a walk or run) may cause your character to become compacted or scaled undesirably.

Right-click on Pose_6 and Rename it to r_foot_fwd.



Right-click on Pose_24 and Rename it to l_foot_fwd.



From the Main Toolbar, click Create Asset and select Create Animation / From Reference Pose.



Choose a save locaiton and save name (we called ours CurveWalk).

Inside the new animation, Right-click in the timeline and select Append at the End and add 30 frames.



Under Curves, click the Add button, then under Add Variable Curve.. select l_foot_fwd to add it then add r_foot_fwd.



We now have the two poses that we want to drive with curve data.

Click the Expand Window checkboxes for both the l_foot_fwd and r_foot_fwd curves.



Move the timeline to 0, then in the l_foot_fwd curve, hold Shift + Left Click to create a key and set Time and Value to 0.



Shift + Left Click and add keys for Time 0.5 and Value 1.0, then Time 1.0 and Value 0.0 resepectively.



This will pose our character's left foot foward midway through the animation.

In the r_foot_fwd curve, Shift + Left Click and add keys for: (Time 0, Value 1), (Time 0.5, Value 0), and (Time 1, Value 1).



At the start of our animation our character's right foot will be forward and midway through we switch to the left foot forward. As the animation nears the end, we use the curve data to drive the right foot forward pose again and when looped we generate our walk cycle.

To preview the animation with the Pose Asset, in the Asset Details panel, set the current Preview Pose Asset to use the ThirdPersonWalk_PoseAsset.



End Result

We can now play the animation to see the two poses being blended together with our curve data.

To play this animation at runtime, you will need to use one of the Pose Blend Nodes within an Animation Blueprint.

Create and Use a Master Skeleton

Create a Pose Asset

Establish Parent/Child Animation Blueprints

Bringing In Animations



If you have multiple characters in your project that are similar and share the same Skeleton Asset, you may want to consider using curve driven animations for facial expressions. When doing so, you can share thoseanimation curves and drive them with Pose Assets to produce your desired facial expressions and even share them across multiple Skeletal Meshes.

One important caveat however is that your animation must not have any bone transform data within it. Any bone transform data, even with one mesh's reference pose, won't work for other meshes so it is important to remove bone transforms (keeping only curves) and start with each mesh's own reference pose if you want to share the curve between different meshes. This enables you to share the facial curves between different faces.

The following is an example workflow, your workflow may differ based on your assets and desired results.

Create and Use a Master Skeleton

The first thing you will want to do is to import a base Skeletal Mesh and create a Skeleton Asset that will be considered as your Master Skeleton (which every other Skeletal Mesh that you want to share facial animations with will use). Any additional meshes that you import should have the same bone hierarchy and naming convention in order to share the Skeleton asset.



Please see the Skeleton Assets documentation pages for more information on Skeletons.

Create a Pose Asset

The next thing you will want to do is inside your DCC, bake out your poses to an FBX sequence and import the FBX into Unreal Engine. This will give you an Animation Sequence containing each of the curves at their min/max blend values.



Click image for full view.

Above, our imported animation sequence contains all curves and their max values at a given frame.

Once you have imported your sequence containing all your curve data, you can create a Pose Asset from that animation sequence which can be used to translate the animation curve data into actual facial animation on the character.



You can right-click on an Animation Sequence and create a Pose Asset from it from the context menu.

Inside your Pose Asset, you will need to define the Pose Names by entering in each name manually or by copying and pasting data stored from your clipboard.

Here we have a list of all the poses identified in our 58 frame animation sequence containing our poses that we imported:



We can then apply these as the names of our poses in our Pose Asset:



You will then see these curves in the Anim Curves window which is stored along with the Skeleton Asset.



Click image for full view.

Every character that uses the Master Skeleton would then have access to these curves and can drive their own facial animation by the different values represented in each curve while the Pose Asset translates all of the curve data to the actual animation pose the character takes.



Above, we changed the default value of the jaw_open_pose from 0 to 1 resulting in the character opening its mouth.

When entering your Pose Names inside the Pose Asset, it is generally a good idea to delete unused curves from the Anim Curves window to minimize the amount of unused curves from being displayed.

Below in our Pose Asset we can see all of our Pose Names which are also displayed in the Anim Curves window:



When we change Pose_0 to l_eye, Pose_0 remains as a curve in the Anim Curves which we can delete by right-clicking on it and selecting Delete Curve.



Establish Parent/Child Animation Blueprints

Once you have a Pose Asset, you'll want to create an Animation Blueprint for your character that utilizes a curve driven animation, and finally, a Pose Asset node (assigning your Pose Asset) to correctly translate the curve data into poses the character can use.



Click image for full view.

If you plug the curve driven animation directly into the Final Animation Pose, the Animation Pose will not now how to translate the curves into pose data. This is where the Pose Asset node comes in and intercepts the animation, properly translating the curves into actual pose data that the character can use.

When you have additional characters, if you create and assign them Child Animation Blueprints from this Master Animation Blueprint, you can override the Pose Asset with unique Pose Asset data for each character. This allows for the character specific deltas to be achieved, ensuring that a scream for example looks correct on varying proportions.



Click image for full view.

Above we have an additional character that is using a Child Animation Blueprint based on our Master.

Inside our Child AnimBP, we have overridden the Pose Asset to use one that is specific to this character, enabling us to use the deltas to drive facial poses specific to this character and the animation that is played comes from our parent.

Bringing In Animations

When you start to bring in facial animations for your characters, typically you'll want some body animation that is driven by bones in the character in addition to the curve driven facial animation. In order to share body animations but drive facial animations through curves, you will need to remove any Bone Tracks from the facial animation leaving only curves or use an Animation Modifier to remove specified Bone Tracks and drive curves for the face.

How would this work? For example, take the Animation Sequence below:



Our Animation Sequence contains all the curves and keyed values for those curves representing varying facial poses. The problem however is that the curves would also be playing on top of any bone driven animations which would result in double transforms and incorrect results. In this case you would want to remove those Bone Transforms, leaving only the curves.

You can Remove All Bone Tracks from the Asset menu under animation:



You can also use Animation Modifiers to remove certain bones only if you want to share body animations but drive curves for the face. Typically you'll want to have a bone driven body animation, but curve driven facial animations in which case we opted to use an Animation Modifier.



Here the Animation Sequence and specified Bone Track to remove (include its children) are finalized when the modifier is applied.

You can create an Animation Modifier by creating a Blueprint with the Parent Class set to Animation Modifier.

On any animation that your import, you can go into the Animation Modifiers section and then apply the Animation Modifier that you have created to remove Bone Transforms.



After adding the Animation Modifier, you can then click to Apply the modifier.

With only the curves remaining, you can run the animation through a Pose Asset inside your Animation Blueprint to give you the curve driven pose that can be shared. Below, we connect our curve driven animation directly up to the Final Animation Pose, however the pose is not used as it does not know how to handle the curves. We then connect it to the Pose Asset to drive those curves which results in the character performing our facial expressions.

Each of our characters since they are using a Child Animation Blueprint and their own assigned Pose Asset can now share the facial animation using their relative deltas. Since we do not have bone transforms and the animation is purely driven by curves, we are not seeing double transforms and can blend this with any additional bone driven animation data (such as full body animation).

Getting Started

Setting Up Head Rotation

Head Rotation Blueprint - Event Graph

Head Rotation Blueprint - Anim Graph

Live Link Face App Controls

Live Link Face App Settings

Raw Facial Recordings

Extracting .CSV Facial Recordings from an iOS Device

Using .CSV Facial Recordings in Unreal Engine

Calibration

Recording Modes and Results

Working with Multiple Users

Timecode Sources

Controlling Live Link Face through OSC

Recent models of the Apple iPhone and iPad offer sophisticated facial recognition and motion tracking capabilities that distinguish the position, topology, and movements of over 50 specific muscles in a user's face. If your iOS device contains a depth camera and ARKit capabilities, you can use the free Live Link Face app from Epic Games to drive complex facial animations on 3D characters inside Unreal Engine, recording them live on your phone and in the engine.

This page explains how to use the Live Link Face app to apply live performances on to the face of a 3D character, and how to make the resulting facial capture system work in the context of a full-scale production shoot.

Live Link Face relies on the same ARKit features used by the Face AR Sample that you'll find on the Learn tab of the Epic Games Launcher. However, the Face AR Sample needs to be compiled for iOS, which requires a Mac and an Apple developer account. With the Live Link Face app, you can immediately get started applying facial animation to any properly set up character in any Unreal Engine Project.

Prerequisites:

The material on this page refers to several different tools and functional areas of Unreal Engine. You'll have best results if you're already familiar with the following material:

Live Link Plugin

Animation Blueprints

Sequencer and Take Recorder

You'll need to have an iOS device that supports ARKit and depth API.

Getting Started

Follow the instructions in this section to set up your Unreal Engine Project, connect the Live Link Face app, and apply the data being recorded by the app to a 3D character.

Enable the following Plugins for your Project:

Live Link

ARKit

ARKit Face Support

You need to have a character set up with a set of blend shapes that match the facial blend shapes produced by ARKit's facial recognition. You'll typically need to do this in a third-party rigging and animation tool, such as Autodesk Maya, then import the character into Unreal Engine.

For a list of the blend shapes your character will need to support, see the Apple ARKit documentation.

If you don't have a character of your own ready, you can use the boy that you'll find in the Face AR Sample on the Learn tab of the Epic Games Launcher.

Your character's blend shapes don't have to use exactly the same names as the ARKit blend shapes. You can create a custom Blueprint function in a LiveLinkRemap Asset to translate the ARKit blend shape names into the ones used by your character. For instructions, see the Face AR Sample documentation. However, for best results, you should make sure that your character's facial blend shapes cover the same facial areas as the ARKit blend shapes.

Set up your character in Unreal Engine with an animation Blueprint that includes a Live Link Pose node. For example, in the animation Blueprint for the boy in the Face AR Sample:



Later, you'll use this node to apply the animation data being sent from the phone to your character.

Get the IP address of your computer. You'll need this to connect your Live Link Face app.

You can typically find the IP address in your computer's control panel or settings. Alternatively, on most Windows platforms you can use the ipconfig command-line utility.

If your computer is connected to the Internet, you may have both a local IP address that is visible only within your network and a public IP address that identifies you on the open Internet. If so, choose the local IP address. Local IP addresses typically start with either 10. or 192.168..

Your computer may also have multiple IP addresses configured for different adapters. For example, you may have a wired Ethernet adapter and a wireless adapter, each with its own address. Make sure you choose the IP address of whichever adapter your computer is using to connect to the same network as your device.

Find the free Live Link Face app from Epic Games on the Apple App Store, and install it on your phone.



Connect your phone to the same wireless network as your computer, or use an Ethernet cable to connect the phone directly to the computer using a Lightning Ethernet adapter.

Live Link requires a network data source, so it's not enough to connect the phone to your computer by USB.

Run the Live Link Face app on the device. You'll start on the home screen, where you can initiate new recordings.



Click for full image.

When you first get started, you'll see the camera picture overlaid by the triangular mesh generated by the ARKit facial recognition system. You can disable the overlay to see just your face, as shown in the image above, by turning off the Preview Mesh setting. See the Live Link Face App Controls section below.

Tap the icon at the top left to open the app settings. At a minimum, you'll need to go into the LiveLink settings to be able to connect to your computer.



Click for full image.

On the LiveLink settings page, tap Add Target and enter your computer's IP address.

If you need to broadcast your animations to multiple Unreal Editor instances, you can enter multiple IP addresses here. See also the Working with Multiple Users section below.

For details on all the other settings available for the Live Link Face app, see the sections below.

In the Unreal Editor, open the Live Link panel by selecting Window > Live Link from the main menu. You should now see your device listed as a subject.



In your character's animation graph, find the Live Link Pose node and set its subject to the one that represents your device.



Compile and Save the animation Blueprint.

Select your character. In the Details panel, ensure that the Update Animation in Editor setting in the Skeletal Mesh category is enabled.



Back in Live Link Face, point your phone's camera at your face until the app recognizes your face and begins tracking your facial movements.

At this point, you should see the character in the Unreal Editor begin to move its face to match yours in real time.

When you're ready to record a performance, tap the red Record button in the Live Link Face app. This begins recording the performance on the device, and also launches Take Recorder in the Unreal Editor to begin recording the animation data on the character in the engine.

Tap the Record button again to stop the take.

Setting Up Head Rotation

To apply head rotation to the Actor using data from the Live Link Face App, you first need to set up Blueprints in the Event Graph and Anim Graph to drive the joints in the head.

Head Rotation Blueprint - Event Graph

This Blueprint is placed in the Event Graph of your character's Anim Blueprint. It takes in yaw, roll, and pitch data from your Live Link performance and applies it to the appropriate bones in your character's rig.



Click for full image.

Right click in the Blueprint and add an Event Blueprint Update Animation node. This ensures the head position updates each frame there is movement.

Next, in the My Blueprint panel create 3 float variables named HeadRoll, HeadYaw, and HeadPitch. Drag each into the Blueprint and choose the Set option from the menu.

Drag off from the Event Blueprint Update Animation node and create an Evaluate Live Link Frame node. This will provide the data from the Live Link source that will be stored in your float variables.

Using the Subject dropdown menu, choose the subject that represents your device.

Open the Role dropdown menu and choose the LiveLinkBasicRole.

Right click near Evaluate Live Link Frame and create three Get Property Value nodes. These will be used to get the yaw, roll, and pitch from the Live Link app. Using the Property Name box on each node, set one to headYaw, another to headRoll, and the last to headPitch.

Connect the Valid Frame output of Evaluate Live Link Frame to the Set variables as seen in the image above.

Finally, connect the Value outputs of each of the Get Property Value nodes to the float input on its corresponding Set variable node.

Head Rotation Blueprint - Anim Graph

With the head and neck rotation data coming in from the app, it can now be applied to the character's rig in the Anim Graph:



Click for full image.

The section shown above is added to the end of the Anim Graph, right before the Output Pose node.

Starting from Output Pose, drag off from the Result and create a Component To Local node.

Next, you will need a Transform (Modify) Bone node for each head and neck bone in your character's skeleton that will be influenced by the rotation data. If you are using the Kite Boy from the Face AR Sample project, you will need two.

For each node, click on it in the Blueprint and set the Bone to Modify setting in the Details panel to the correct bone name. For the Kite Boy, this is the neckRoot and head.

Connect the output of the first node to the Component Pose input of the next, similar to what you see in the image above.

In each of the Transform (Modify) Bone nodes, click on the dropdown for the Translation Space option and change it to Bone Space.

In the Details panel for the Transform (Modify) Bone nodes, find the Rotation section and change the Rotation Mode to Add to Existing, and change the Rotation Space option to Bone Space.

Now take the yaw, pitch, and roll data that you are gathering in the Event Graph and create a Rotator to update the rotation of the head and neck bones. Drag in a copy of each of your float variables created earlier and choose Get from the menu.

For each variable, drag from the output and create a Float x Float node. Multiply the Pitch by 15 and the Yaw and the Roll by -15. The yaw, pitch, and roll multiplier may need to be adjusted to achieve the desired result. You may need to try positive and negative values to get the correct rotation.

With the multipliers set up, it is time to create the rotator. Right click in the Blueprint panel and create a Make Rotator node.

Connect the output from the yaw multiplier into the X (Roll) input on the Make Rotator.

Connect the pitch multiplier to the Z (Yaw).

Finally, connect the roll multiplier to the Y (Pitch).

Connect the output of Make Rotator to the Rotation input on each of the Transform (Modify) Bone nodes.

Finish the sequence by creating a Live Link Pose node and setting Live Link Subject Name to your device. Drag off from the output and create a Local to Component node.

Connect its output to the Component Pose input on the first of the Transform (Modify) Bone nodes.

The yaw, pitch, and roll connections may need to be adjusted to achieve the correct rotation. The best way to check your rotations is with a live test once the sequence is complete. Your character should move with you. If you tilt your head to the left, your character should do the same to their left.

Press Play in Editor and test your head rotation setup. Your character's head should now rotate to match what is being recorded by the Live Link app.

Live Link Face App Controls

The home screen of the Live Link Face app offers the following controls.



Click for full image.

1

Opens the Settings dialog.

2

Toggles sending facial animation data to all LiveLink targets. When highlighted in green, the app is sending the animation data.

When live, also lists the current timecode value being read from the timecode source configured in the app settings.

3

Toggles video display and facial tracking on and off.

4

Starts and stops recording a new take.

5

Opens the list of takes previously recorded by the app.

6

Shows the current slate and take, and the LiveLink subject name. Tap to rename the current slate or change the take number.

7

When highlighted in green, indicates that the ARKit facial capture system is able to successfully detect a face in the current camera view.

Live Link Face App Settings

Tap the icon at the top left of the home screen to enter the Settings page, where you can configure the behavior of the app.

Setting

Description

LiveLink

Configures the app to connect to computers running Unreal Engine, so that it can send animation data and control recordings through Live Link.

Timecode

Configures the timecode source for the Live Link Face app. For details, see Timecode Sources below.

OSC

Configures connections between the Live Link Face app and external OSC controllers and devices. For details, see Controlling Live Link Face through OSC below.

Calibration

Opens the Calibration menu.

Stream Head Rotation

Determines whether the app sends head rotation (yaw/pitch/roll) data from ARKit through the Live Link connection.

This option can be useful if you set up your phone on a static tripod stand, and you want to use the Live Link Face app to drive the movements of a virtual head as you move your head up and down and side to side relative to the phone.

If you use the Live Link Face app in conjunction with a body motion capture setup, you probably will not need this setting. Instead, you would typically mount your device to your head using a custom helmet so that it is always directly in front of your face, and let the body motion capture system record the up and down and side-to-side movements of your head.

Preview mesh

Determines whether the home screen overlays the camera picture with the triangular mesh generated by the ARKit facial recognition system.

Record button

Determines whether the red Record button is visible on the home screen.

You may want to disable this option if you are toggling recordings from an external OSC device, to avoid the possibility of actors accidentally hitting the button on the phone.



Blendshape data

Determines whether the home screen shows the data values being produced by the ARKit facial recognition system for all facial blend shapes. This information is typically useful only for debugging purposes.

Take Recorder

Determines whether the home screen should show the current slate name and take number, or the filename that will be used for the current recording.

Overlay

Determines whether the main screen of the Live Link Face app remains visible at all times, or whether it fades out until you interact with the touchscreen.

Fading out the overlay may prevent actors being distracted by seeing the captured video during their performances.



Video Quality

Determines the quality of the JPEG compression used to encode the reference video. Higher quality produces sharper images, but takes correspondingly more storage space on your device.

Storage

Shows the amount of free space on your device, and the amount of space being used by Live Link Face. You can also use this screen to delete takes that you've recorded previously.

Reset

Allows you to reset the Live Link Face app to its factory settings, undoing any changes you made to the settings above since you installed the app.

About

Displays legal information about the app.

Raw Facial Recordings

Whenever you initiate a new recording from the Live Link Face app, the capture is recorded to the device in two files:

A .mov file that contains a reference video recorded by the camera.

The video frames are compressed using the JPEG codec, but it is frame-accurate with no temporal compression. The file contains audio and timecode, and is intended to act as a reference for animators who may need to work with the animation performance after the recording.

A .csv file that contains the raw animation data captured by ARKit during the recording.

You can export this .csv file from the iOS device and import it into Unreal Engine as if you had recorded it in Take Recorder. Read the sections below about how to extract a .csv recording from Live Link and use it to drive facial animation in Unreal Engine. The raw data in this file may also be useful for developers who want to build additional tools around the facial capture.

Extracting .CSV Facial Recordings from an iOS Device

There are two methods for extracting raw Live Link facial recordings from an iOS device in the .csv format. The easiest method is to share the Takes from within the Live Link App itself, but you can also browse to the .csv files in the iOS Files App and transfer or share them manually.

Tap the Take Browser icon in the bottom-left corner of the main screen.



Tap Select and then choose the Takes you want to extract from the device.



Hit the Share icon and use one of the built-in iOS share functions such as AirDrop or Mail.



AirDrop is the most reliable option to share Live Link takes from the device. Extracting a large number of takes, or long takes, may cause issues with third party services like Google Drive. The iOS share functionality is frequently buggy with integrated non-Apple services.

The iOS Files App provides several alternative ways to extract files from an iOS device. Read Apple's documentation on transferring files between an iOS device and computer.

The Live Link App stores raw facial recordings in a folder called Live Link Face in the Files > Browse folder on your iOS device.



Open Live Link Face > takes, then tap the folder of the take you want to share. The raw .csv file is found inside that folder.



Click for full image.

You can share the .csv file by tapping it and selecting one of the Share options in the context menu.

Using .CSV Facial Recordings in Unreal Engine

This process requires all three Plugins listed in the Getting Started section at the top of this document, plus the LiveLinkFaceImporter Beta Plugin.

Go to Edit > Plugins to open the Plugins Browser. Search for LiveLinkFaceImporter and enable the plugin. Restart the Editor before you proceed.



Click Import in the Content Browser and import the Live Link .csv file you want to use.



A new Level Sequence Asset is created in the Content Browser with the same name as the .csv file.



Double-click this asset to open the Level Sequence in Sequencer. If you click the dropdown caret next to the name of the Track you will see keyframe data from all the different facial blendshapes.



Click for full image.

To use the Level Sequence with a character, open it in Sequencer and then set it as a Subject wherever your Live Link source is configured. The Level Sequence should appear as an option. To play the animation on a MetaHuman, you can select the MetaHuman Blueprint and then configure the following settings in the Live Link section of the Details Panel.



Check the box to enable Use ARKit Face.

In the ARKit Face Subj dropdown menu, select the subject that matches the .csv you imported.

These settings are also accessible from the Event Graph of the MetaHuman Blueprint.



Click for full image.

Now when you play the Level Sequence in Sequencer, the facial animation is bound to your MetaHuman character.

Calibration

In order to improve facial tracking quality, you can calibrate the Live Link Face app to better respond to changes in your face by capturing an image of your neutral "rest" face pose.

To enable calibration, open the Settings icon in the top left when Live Link Face app is open, then tap on Calibration. You should now see the calibration menu where you can enable the feature by tapping the Enable button.



You can optionally enable the Countdown property too, which enables a three-second timer when initiating the calibration image.

Now when you return to the main Live Link Face screen, a new Calibrate (+) button will appear at the bottom right of the screen. Tapping this will enable a special "calibration mode", which converts the Record button function into the calibration capture.



To calibrate your face, tap the Calibrate button. Next, face towards your device camera, ensure your face is neutral and expressionless, and press the Record button. The calibration image will either be taken immediately, or a three-second countdown will occur before the image is captured, if Countdown was enabled from the calibration settings.

After the calibration image is captured, you can choose to either Save or Discard it to try again. If you save it, then tapping on the Calibration button again will display options to Recalibrate and capture a new image, or Remove the calibration.

Recording Modes and Results

Anytime you initiate recording from the Live Link Face app on your device, or through the OSC interface of the Live Link Face app, your performance will be recorded to the phone as described in the previous section. You don't have to be connected to any instances of Unreal Engine to record in this way.

If you are connected through Live Link to any instances of Unreal Engine at the time you start recording from the Live Link Face app or through the OSC interface, you will also launch the Take Recorder on all connected instances of Unreal Engine. Your animation performances will be recorded both on your device and in the Take Recorder on your computer.

If you are connected through Live Link to one or more instances of Unreal Engine, and you initiate recording from the Take Recorder in the Unreal Editor interface instead of initiating the recording from your device or the OSC interface, your performance will not be saved to the device. It will only be recorded in the Take Recorder on your computer.

Working with Multiple Users

In the context of more complex, real-world productions, you may have multiple operators working in Unreal Engine at the same time, using Multi-User Editing to collaborate live in the same virtual world. In this case, we recommend that you configure the Live Link Face app to connect to all Unreal Engine instances run by all operators. The app will multicast the performance capture to all engine instances. This ensures that all operators see the incoming animation data in context with a minimum of latency.

Timecode Sources

It's likely that in a real production Live Link Face will only be part of a much larger performance capture setup. You will likely need to record other things at the same time: audio, live video, other body capture data, camera tracking data, and so on. In order to be able to synchronize these separate recordings with perfect accuracy, you need to ensure that all recordings embed consistent timecode values.

Live Link Face offers three options for timecode sources, which you can configure in the Settings panel.

System Timer

By default, Live Link Face bases its timecode values on the device's System Timer. This timer is based on the elapsed time since the last system reboot. This provides a base option that is accurate in itself, but it can be hard to link this timecode up with recordings made on other devices.

NTP Server

One way to get consistent timecode based on the time of day is to rely on a server that provides time values through Network Time Protocol (NTP). If you choose this option, the default server is time.apple.com, which is the same server that Apple uses to synchronize the device's time of day. However, if you use a custom NTP server, as many productions do to synchronize timecode for devices on stage, you can enter the server name and IP address.

Tentacle Sync

The Tentacle Sync is a third-party hardware device that allows devices to synchronize via Bluetooth to a master clock on stage. This is likely the most professional timecode option; high-end productions typically rely on a master clock for timecode synchronization during a shoot. For details, see Tentacle Sync.

Controlling Live Link Face through OSC

The Live Link Face app supports two-way communication through the Open Sound Control (OSC) protocol.

You can use OSC devices to control Live Link Face remotely. For example, you could use an external device to start the app recording remotely.

You can also configure Live Link Face to send notifications of its activity to other OSC devices. For example, you could trigger actions on other devices whenever the app begins a new recording.

To set up OSC, open the app settings:

In the Listener section, you'll see the current IP address of your device, and the port that the Live Link Face app is listening to for incoming OSC messages. You'll need to make your OSC remote control device send commands to this IP address and port.

If you want Live Link Face to send OSC commands to control another device, enter the IP address and port of that device in the Target section.

The Live Link Face app supports the following OSC commands:

Command

Description

/OSCSetSendTarget <IP:string> <port:int32>

Sets the OSC send target to the given IP address and port. The app replies to the new OSC send target with the command /OSCSetSendTargetConfirm.

/AddLiveLinkAddress <IP:string> <port:int32>

Adds a new Live Link target for the app to broadcast blend shape data.

/ClearAllLiveLinkAddresses

Removes all Live Link targets.

/LiveLinkSubject <name:string>

Sets the Live Link subject name.

/LiveLinkStreamStart

Starts streaming data to all Live Link targets.

/LiveLinkStreamStop

Stops streaming data to Live Link targets.

/BatteryQuery

Requests the battery level of the device. The app replies to the OSC send target with /Battery <level:float32>.

/ThermalsQuery

Requests the thermal state of the device. The app replies to the OSC send target with /Thermals <state:int32>.

/Slate <name:string>

Sets the slate to the given name.

/Take <number:int32>

Sets the take number to the given value.

/ARSessionStart

Turns on video and AR tracking. The app replies to the OSC send target with /ARSessionStartConfirm.

/ARSessionStop

Turns off video and AR tracking. The app replies to the OSC send target with /ARSessionStopConfirm.

/RecordStart <slate:string> <take:int32>

Starts recording with the given slate and take number. The app replies to the OSC send target with /RecordStartConfirm <timecode:string>. Note that at this time the timecode is always 00:00:00.000.

/RecordStop

Stops recording. The app replies to the OSC send target with /RecordStopConfirm <timecode:string> <blendshapesCSV:string> <referenceMOV:string>. You can use the two strings in the /Transport command below to copy data from the device.

/Transport <IP:port:string> <path:string>

Using a path returned by the /RecordStopConfirm command (above), requests the app to transport the contents of the file to the specified IP address and port. The app will open a TCP connection to that address and port. It first sends an int32 that contains the total size of the file, in big-endian format. It then sends the contents of the file.

/VideoDisplayOn

Turns the display of the video on.

/VideoDisplayOff

Turns the display of the video off. Tracking and recording can and will still occur.

/AppActivated

The app sends this to the OSC send target when the it becomes active on the phone. That is, when it is first started, brought to foreground, and so on.

/AppDeactivated

The app sends this to the OSC send target when the it becomes inactive on the phone. That is, when it is killed, sent to background, and so on.

Animation Sequences

Animation Blueprints

Animation Montage

Skeletons



Steps

End Result

FAQ

Animation Layer Editing allows you to modify any existing Animation Sequences inside Unreal Engine as part of Additive Layer Tracks. With Animation Layer Editing you can take an existing animation and adjust it to produce a different take on that animation, or you can create a separate, new animation with its own motion you provide based off the original.

This page will show you how to use the Animation Layer Editing tools to take an Idle animation and repurpose it into a Reload animation.

For this guide, we created a New Project using the Blueprint First Person template with Starter Content enabled.

Steps

Inside the Content/FirstPerson/Animation folder, duplicate the FirstPerson_Idle animation and name it FirstPerson_Reload.



Inside FirstPerson_Reload, pause the animation at frame 0, click the upperarm_l bone in the Skeleton Tree, then click the Key button.



This will add Transform, Rotation and Scale keys for the current position of the upperarm_l to the Additive Layer Tracks section.



Move the timeline ahead to frame 15.



Rotate the upperarm_l bone -70 degrees, then press the Key button.



This will add a key for the bone's rotation when the animation is at frame 15.

Move the timeline ahead to frame 20, rotate the upperarm_l bone 70 degrees to its default position and press the Key button.



Over the course of 20 frames, the arm will move down then back up to its default position.

Right-click on the timeline marker and Remove from frame 20 to frame 92.



This will remove the rest of the frames from the animation, keeping only our reloading motion.

In the Content Browser, Right-click on the FirstPerson_Reload animation and select Create AnimMontage.



We are going to use this to play our new reload animation when the player presses the designated key during gameplay.

Open the new AnimMontage, then change the slot to use the DefaultGroup.Arms slot.



Below, the Animation Blueprint assigned to the template character is set up to use a Slot Node to play any Anim Montages assigned to the "Arms" slot.



This is currently being used to handle the playing of the firing weapon animation which we will also use for our reload motion.

Inside the Content/FirstPersonBP/Blueprints folder, open the FirstPersonCharacter Blueprint.



This is the Character Blueprint assigned to the template and is our playable character.

Locate the Spawn Projectile script and Ctrl select the Mesh2P, Get Anim Instance and Montage Play nodes shown below.



These nodes get the animation instance assigned to the Skeletal Mesh and signals the playing of an Animation Montage, in this case, the fire weapon montage. We are going to use this same script but instead call our reload Animation Montage when the key we specify is pressed.

Right-click and copy the selected nodes, then paste them in an empty space in the graph.

Right-click and add a R Key Event and connect them as shown to the pasted nodes, setting Montage to Play to your reload montage.



Compile and Play in the Editor.

End Result

When playing in the editor, pressing the R key will drop the character's hand off screen before bringing it back up to the gun, simulating a reload motion.

You can continue to modify this animation by moving to a frame on the timeline and selecting the Bone you want to modify and keying it, then moving the timeline forward some and moving the Bone to a new location and keying it again. The Bone will move from your first key to your second key along the curve created as the timeline progresses. You can modify as many Bones as you wish for more precision than our example, but the process of keying is the same.

FAQ

What happens if you export the animation?

When you export, it will be whichever baked version of the animation is available. If you apply all the curves, it will export with curves.

What happens if you re-import the animation?

Reimporting the animation, it will overwrite the source data and apply the curves. If you do not want the curves, you can remove them.

Can I temporarily disable or remove tracks?

Yes, you can do both from the Track Options menu located in the upper right corner of the track window.



Is there a way to see the difference of my edited animation versus its source?

Inside the Show menu options, you can enable the Source Animation and (or) Baked Animation for display in the viewport. The Source Animation can be seen as a white skeleton, while the Baked Animation can be seen as a blue skeleton as shown in the image below.



Just make sure that you have enabled the display of Bones from the Show -> Bone Hiearchy menu.

Can Animation Layer Editing be used to create root motion?

Select your Root Bone and key it, then scrub the timeline forward and move the Root Bone and re-key it.



Above we have enabled the Source and Baked Animation preview where the white skeleton is the source animation.

Animation Blueprints

Skeletons



Steps

End Result

Additional Use Case

The Animation Blueprint Linking system is an extension of Sub Anim Instances. It enables dynamic switching of sub-sections on an Animation Graph, making possible both multi-user-collaboration and memory savings, as the Animation Blueprint will no longer load animation assets that are not in use.

In this how-to, we create an Animation Blueprint that retrieves an animation pose contained in a Linked Animation Blueprint by way of an Animation Layer Interface.

The Content Examples project on the Learn Tab of the Epic Games Launcher also contains an example of Animation Blueprint Linking inside the Animation map.

Steps

For this guide, we are using the Blueprint Third Person template with Starter Content enabled. We also added the Animation Starter Pack, which is available for free in the Marketplace on the Epic Games Launcher for the project.

Inside your project, under Content > AnimStarterPack, add the Ue4ASP_Character to the Level. In the Details panel, set Auto Possess Player to Player 0.



This will let you control this character when you play in the Editor.

Right-click in the Content Browser. Under Animation, create an Animation Layer Interface asset called MyLayerInterface.



These assets are analogous to Blueprint Interfaces, and you can use them to define the number of Layers, their names, and which groups they belong to, as well as any inputs.

Inside the MyLayerInterface asset, name the Layer ExampleLayer. In Details panel, click the + (plus) sign to add an Input, then click Compile.



Animation Layers can expose multiple input poses from sub-graphs along with input parameters that can be used for blending or other logic-based implementation purposes.

Create an Animation Blueprint using the UE4_Mannequin_Skeleton (from the Animation Starter Pack folder), and name it HitReact_AnimBP.



This is the Animation Blueprint that we will be linking to the existing Animation Blueprint used for the character we placed in the Level earlier in this guide.

Inside the HitReact_AnimBP on the toolbar, click the Class Settings button, then in the Details panel, under Interfaces, add the MyLayerInterface.



In the Example Layer, add the Hit_React_1 animation from the Asset Browser to the graph and connect to the Output Pose.



The Input Pose from the Layer Interface can bring in pose data, and can be used to blend with any logic or other pose data defined within this layer.

In the Content > AnimStarterPack folder, open the UE4ASP_HeroTPP_AnimBlueprint and add the MyLayerInterface from the Class Settings.



In the Example Layer, connect the Input Pose to the Output Pose as shown below.



The Input Pose, in this case, comes from the Linked Anim BP (where we placed our Hit React animation). For this example, we are going to take the pose from the Linked Animation Blueprint directly and switch to it.

On the Anim Graph, add a Linked Anim Layer node (set to Example Layer) and connect as shown.



The Default state machine will pass a pose through the Linked Animation Layer and out to the Output Pose. When Link Anim Class Layers is called, the underlying Animation Blueprint will be executed.

The Linked Anim Layer node has an Instance Class property that you can use to specify a default Layer override. This is especially useful when you want to break up your logic into multiple Animation Blueprints. For example, if you have some IK logic that gets changed frequently, you can move it out to a separate Animation Blueprint and set it to run by default in your main Animation Blueprint.

In the Content > AnimStarterPack folder, open the Ue4ASP_Character Character Blueprint.

Add an H keyboard event (or any other keyboard event), then drag in the Mesh component and add both the Link Anim Class Layers and Unlink Anim Class Layers nodes set to HitReact_AnimBP.



When H is pressed and held, the Linked Anim BP specified as the In Class will be set up as a linked instance and executed. When releasing H, any Layer nodes running the specified class will be unlinked and reset back to its default value.

Optionally, we also added a C keyboard event for the crouch to resolve the warning message.

Compile and Play in the editor.

End Result

Below, our Animation Blueprint executes normally until we press the H key to activate the Layer Node and the underlying Animation Blueprint setup (which plays a Hit React animation).

Animation Layers and Linked Animation Blueprints may provide a way to maintain scalability and organization within complex characters. With Layers and Linked Animation Blueprints, logic can be sectioned off within an Animation Blueprint through a layer, or split off entirely in another Animation Blueprint and linked from within a Master Animation Blueprint.

Additional Use Case

Below, a simplified use case for Linked Anim Layers utilized on Fortnite is shown.



In the image above, we have two interfaces—one for weapons, and andother for vehicles. It is possible to have both active at the same time. It is also possible for a single Animation Blueprint that implements one of these interfaces to override multiple points of the graph (for example, a weapon overriding WeaponUpperBody and WeaponAdditive).

Here are some possibilities with the above setup:

When driving a car, the vehicle takes over the entire pose.

When riding shotgun, the vehicle plays a seated animation on the lower body while the weapon controls the upper body. If the user changes weapons, a new weapon Animation Blueprint will control the upper body while the lower body continues to play from the vehicle.

A weapon can override the upper body pose, which will then be combined with the lower body pose from the main graph, then a custom additive animation (for example, idle noise) will be played on top of the full body pose from the weapon.

In Fortnite, weapons can override a bunch of different points in the main graph. For example, a State Machine for locomotion with states like Jump, Fall, Land, and Zipline, is used.

Rather than duplicating this State Machine for each weapon, the State Machine lives in the main graph, and weapon Animation Blueprints have a Layer they can override for each state.

If a weapon doesn't need to override some states, it simply doesn't connect anything to the output pose in the corresponding Layer.

Additionally, Animation Blueprints containing Layers have their own Event Graphs. So if we need to process data for a specific vehicle, we can keep it contained in that vehicle Animation Blueprint's Event Graph.



Skeletal Meshes

State Machines

Artificial Intelligence



Setup

Set All Bodies Below Simulate Physics

Set All Bodies Below Physics Blend Weight

Hit-Based Reaction Overview



This document covers how to apply physics-driven animation to your characters and Skeletal Meshes. The concept is that you can blend in the result of a simulation along with your keyframed animation to have a naturally simulated feel for characters that need to exhibit a "ragdoll" effect.

An example of this concept in action can be seen in the Content Examples project, within the map named PhysicalAnimation.umap. In this map, we have a series of Skeletal Meshes to which animation has been applied. In each one, we can also interact in some way and see physics animation take over the existing motion.

Be aware that the use of physics on a Skeletal Mesh in any form requires that the mesh have a Physics Asset set up and applied to it. Please see the associated documentation for the Physics Asset Tool (PhAT).

Skeletal Meshes are used in this example for overall simplicity. The same techniques can be applied to a Character or Pawn, simply by utilizing the Set All Bodies Simulate Physics and Set All Bodies Below Physics Blend Weight nodes within the Animation Blueprint's Event Graph, rather than on a simple Blueprint Actor's Event Graph, as we do in this example.

Setup

There are many ways to apply physics to a character and our example shows only a few possibilities. In our approach, the two primary tools you will need are the Set All Bodies Simulate Physics and Set All Bodies Below Physics Blend Weight nodes, which will generally be placed within your character's Animation Blueprint Event Graph.



Set All Bodies Below Simulate Physics

The purpose of the Set All Bodies Below Simulate Physics node is to recursively activate Physics Asset bodies on a Skeletal Mesh to begin simulating physics starting at a given bone and moving recursively down the bone chain. For example, if you tell the left clavicle to start simulating, then all of the bones descending from that in the skeletal hierarchy will simulate as well, resulting in a limp or ragdolling arm. Simply put, you can think of this node as an on/off switch to begin or stop simulating physics from a given bone.

Set All Bodies Below Physics Blend Weight

This node simply controls how much influence the Physics Asset will have over the animated Skeletal Mesh. At a value of 1.0, the given bone and all those below it are completely driven by physics. At a value of 0.0, the Skeletal Mesh has returned to its original keyframe animation. Often, you will want to drive this node at each tick so that you can smoothly animate the Physics Blend Weight value.

Hit-Based Reaction Overview

Hit-based physics reactions are a common use case for simulation on characters, such as when a character is struck by a projectile. At a high-level, this requires that you:

Get the name of the bone that was hit. This can be done via a trace for instant-effect weapons, or within a projectile class where applicable.

Transfer that bone name into the Character's Animation Blueprint for the Event Graph to use, generally through a Set All Bodies Below Simulate Physics node. This activates the simulation system.

Control the Physics Blend Weight property via a Set All Below Physics Blend Weight node. Generally, you want to quickly animate this going up to 1.0 and then back down to 0.0 so that the physics reaction blends in and then back out. This would generally be done within the Animation Blueprint's Event Graph.

Once the reaction is complete and the Physics Blend Weight returns to 0, you should use the Set All Bodies Below Simulate Physics node once more to deactivate the simulation.

You can see an example of this technique in Example 1.2 of the PhysicalAnimation.umap level, found within the Content Examples project.

Animation Blueprints

Blueprints Visual Scripting

Animation Blueprint Editor

Animation Montage

Physics Asset Editor

Save Pose Snapshot

Retrieve Pose Snapshot

Snapshot Pose Function

Additional Resource

When animating Skeletal Meshes, there may be instances when you want to let physics take control of the mesh (such as a character entering a rag-doll state). After physics has been applied, using the Animation Pose Snapshot feature, you can capture a Skeletal Mesh pose (storing all the Bone Transform data) within a Blueprint. You can then retrieve that informaiton inside an Animation Blueprint and use the saved pose as a source to blend from (as seen in the example video below).

Above, our character enters a rag-doll state when we press the R key and we use the Pose Snapshot node in our Character Blueprint to save off the pose of our Skeletal Mesh. When we press the R key again, our character blends from that snapshot into and plays a "get up" Animation Montage before resuming the normal locomotion state. This grants us the ability to take whatever pose the character ends up in as a result of physics and generate a smooth blend from that pose into an animation of the character getting back to their feet.

Save Pose Snapshot

In order to save your Skeletal Mesh's pose at runtime, inside your Character Blueprint, you will need access to the Skeletal Mesh Component and its Anim Instance. After getting the Skeletal Mesh and Anim Instance, you can call the Save Pose Snapshot node and enter the desired Snapshot Name. You can manually enter a name into the Snapshot Name field or create a variable to store the name.



The name you provide as the Snapshot Name must also be used when attempting to retrieve the Pose Snapshot inside your Animation Blueprint. Additionally, when calling Save Pose Snapshot, the snapshot is taken at the current LOD. For example, if you took the snapshot at LOD1 and then used it at LOD0, any bones not in LOD1 will use the mesh's reference pose.

Retrieve Pose Snapshot

To retrieve a Pose Snapshot, inside the AnimGraph of your Animation Blueprint, right-click and add the Pose Snapshot node and enter your Snapshot Name.



Below is the graph used for the example of a character getting up from a rag-doll pose.



Above, we have a State Machine called Default that drives our character's locomotion and uses a Slot node called MySlot that plays an Animation Montage of our character getting up. We use the Blend Poses by bool node to determine if our character has stopped moving, where if True we switch over to our Pose Snapshot. If False, we blend from the Pose Snapshot into our slotted Animation Montage before continuing on with our normal Default State Machine.

Snapshot Pose Function

An alternative way of using the Pose Snapshot feature is by calling the Snapshot Pose function within Blueprint to save a snapshot to a Pose Snapshot variable.



When using Snapshot Pose, you will need to provide a variable to save the snapshot to as shown above.

Inside your AnimGraph after adding the Pose Snapshot node, set the Mode to Snapshot Pin and check the (As pin) Snapshot option inside the Details panel.



This will expose a Pose Snapshot input pin on the node where you can pass in your desired snapshot variable.



Additional Resource

Additional information about this feature can be seen in the following Live Training Stream.



Skeletons



Animation Retargeting is the process of repurposing existing animations for use between multiple characters, eliminating the need to create entirely new animations as you can instead share your animation assets between characters.

There are two forms of Animation Retargeting, one in which the Skeleton of the character you wish to share animations with is using the Same Skeleton as the character that the animations were originally created for. The other involves an intermediary object called a Rig which allows you to retarget animations from one character's Skeleton and pass that Skeleton's Bone information to a Different Skeleton using the Rig which both Skeleton's share.

Refer to the two links below for the type of Animation Retargeting you are looking to achieve:

Retargeting Using the Same Skeleton

Retargeting Using Different Skeletons

Retargeting Using the Same Skeleton

This section will show you how to set up a Skeleton to use retargeted animations for all biped characters that use the Skeleton.

Steps

Inside the Content Browser, open the Skeleton asset that is being used for each of your characters.

In the Skeleton Tree window of the Skeleton Editor, check the Show Retargeting Options checkbox.



Right-click on your Root bone in the Skeleton Tree and select Recursively Set Translation Retargeting Skeleton.



This will ensure that all bones use the skeleton's static translation (we will modify certain bones for retargeting in a moment).

Locate the Pelvis bone (or its equivalent bone) and click the drop-down box and select AnimationScaled.



This will make sure that the bone sits at the right height and is still animated. Any other bone you want translation to be animated and retargeted should also use this setting.

Find the Root bone, any IK bones, any Weapon bones you may be using or other marker-style bones and set them to Animation.



By using Animation as the Bone Translation Retargeting Mode, the bone's translation comes from the animation data itself and is unchanged.

You may have to experiment with the different methods for different bones to produce your desired results.

Click the Scene Setup button in the Viewport and select a different Preview Mesh.



Try out different animations on different Skeletal Meshes to ensure that your Skeleton is set up properly for each of your animations.

Inside the Viewport, click Show and check NonRetarget Animation and under Bone, choose All Hierarchy to display all Bones.



End Result

You should now see something similar to below on your Skeleton.







Base Character

Short Stocky Character

Tall Skinny Character

Shown in beige above is the original Skeleton along with the current, retargeted Skeleton in white. When retargeting is applied to the characters, the differences in their proportions are taken out of the equation and animations applied play properly on each of the different characters and the original Skeleton (beige Skeleton) is depicted in the same position in both the Short and Tall Characters.

Retargeting Using Different Skeletons

In this section, we will go through the process of retargeting animations from one character to another who both use different Skeleton assets. We are also going to use two asset packs that are available for free via the Marketplace that have additional skeletons and animations in it that we can use to retarget. If you have two Skeleton assets ready to use, you can skip the note below and use your assets. If you do not, you can follow along with the steps by adding the two packs outlined in the note below.

In this example, we are using the following assets which are available for download for free from the Marketplace.

The Source Skeleton we are using is the UE4_Mannequin_Skeleton that is included in the Animation Starter Pack.

The Target Skeleton we are using is the SK_Mannequin_Skeleton that is included in the Infinity Blade: Warriors pack.

Once you have installed the packs above, you can add them to a project via the Add to project button in the Unreal Launcher.



Steps

Inside the Content Browser under the Content/AnimStarterPack/UE4_Mannequin/Mesh folder, open the UE4_Mannequin_Skeleton asset.



Click the Retarget Manager button, then under Set up Rig, click the Select Rig dropdown and select Select Humanoid Rig.



In the Content Browser under the Content/InfinityBladeWarriors/Character/CompleteCharacters folder, open the SK_Mannequin_Skeleton asset.



Click the Retarget Manager button, then under Set up Rig, click the Select Rig dropdown and select Select Humanoid Rig.



With the Rig assigned, next you will need to match up the Bones from the Target to the Nodes on the Rig.



Since the Skeleton in the Infinity Blade: Warriors pack uses the same naming convention and Bone hierarchy, they are automatically detected and applied to the Rig.

If your Bone naming convention differs from the Epic Skeleton, you may see "none" applied to each of the Bones in the Rig:



In this case, you will need to use the Auto Mapping feature or manually assign each Bone from the Skeleton that best matches the Node on the Rig.

When using the Auto Mapping feature, it is a good idea to double check which Bones were assigned to which Nodes on the Rig. Auto Mapping will try to get the best match based on Bone position and (or) Bone Naming Conventions and assign those to ones on the Rig, but they may not the ideal Bone to use in each case.

Click the Show Advanced button to toggle between Advanced/Base configuration.



In this section, you can assign Bones from the Skeleton that corresponds to Nodes on the Rig for digits of fingers, IK Bones or Twist/Roll Bones.

Similar to the Base configuration, the Bones within Advanced may be set to "none" depending on your Skeleton which you will have to set.

In the Content Browser, under Content/AnimStarterPack, select an animation that you want to retarget to the new Skeleton.

Right-click on the animation and choose Retarget Anim Assets -> Duplicate Anim Assets and Retarget.



In the Select Skeleton window, you should see your Skeleton in the upper portion of the window, select it and click Retarget.



This will copy the animation to the specified folder location. You can assign a New Asset Name in this window as well.

The Target Skeleton should have a similar Base pose as the Source to generate the best possible retargeted animation. Above, both Skeletons are in an A-Pose, however, you may have a character that is an A-Pose and one that is in a T-Pose. You can use a Retargted Base Pose to fix this prior to retargeting animations.

End Result

The new retargeted animation will be available to any Skeletal Meshes that use the Skeleton asset the animation was retargeted for.

While this example illustrates how to retarget an animation, the same Right-click method can be used on any animation asset and retargeting can be applied.

Animation Blueprints

Skeletons



Steps

End Result

As you start to create more and more complex Animation Blueprints for your characters, there may be times when you want to re-use portions of an Animation Blueprint within another Animation Blueprint. Rather than re-creating the node network, you can split that network off into its own Animation Blueprint and use a Sub Anim Instance to access the Animation Blueprint when it is needed.

In this how-to we create an Animation Blueprint with logic to affect our playable character, then use a Sub Anim Instance inside the template's Animation Blueprint to call that logic.

For this guide, we are using the Blueprint Third Person template with Starter Content enabled.

Steps

In the Content/Mannequin/Animations folder, Right-click on and Duplicate the ThirdPerson_AnimBP and call it AltAnimBP.



This AltAnimBP will be used as our Sub Anim Instance that will be called from the ThirdPerson_AnimBP.

When creating an Animation Blueprint to use as a Sub Anim Instance, you must use the same Skeleton Asset as the one in the Animation Blueprint you plan to incorporate it in. In our example, we duplicated the template's Animation Blueprint, however, when creating Animation Blueprints from scratch you will need to select a Skeleton.

In the AnimGraph of AltAnimBP, Right-click and add a Sub-Graph Input node.



This will create an In Pose on the Sub Anim Instance, allowing us to pass through external pose data to this Animation Blueprint.

Right-click again and add a FABRIK skeletal control node.



For this example, we will use IK to push the character's arms up into the air as they run around during gameplay.

Assign the following settings to the FABRIK node from the Details panel.

Uncheck the (As Pin) Effector Transform

Set Location to 100, 0, 200.

Set Tip Bone to index_01_l.

Set Root Bone to clavicale_l.



Copy the FABRIK node in the graph and make the following changes to it from the Details panel.

Set Location to -100, 0, 200.

Set Tip Bone to index_01_r.

Set Root Bone to clavicale_r.



This will ensure that both the Left and Right arms are affected.

Right-click on the Alpha pin of a FABRIK node and Promote to Variable called Effect Alpha.



Recreate the node network shown below (the Local to Component and Component to Local nodes will be automatically created).



If you Compile the Animation Blueprint, the character in the preview window will put their arms up.



Inside the Content Browser under Content/Mannequin/Animations, open the ThirdPerson_AnimBP.

Inside the AnimGraph, Right-click and add the Sub Anim Instance node.



This is the node that we use to gain access to our Animation Blueprint we created.

In the Details panel for the Sub Anim Instance node, set the Instance Class to AltAnimBP.



Click the Expose checkbox next to EffectAlpha to expose the property.



By exposing properties, you can update those properties with data from the parent Animation Blueprint.

From the MyBlueprint panel, drag in the Speed variable and divide it by 600 then plug that into the Effect Alpha.



Here we divide the character's movement speed by a value to produce a blend between the amount of Skeletal Control applied.

Compile then Play in the Editor.

End Result

Below, as our character's speed increases it is divided by the specified amount before being used to drive the amount of Skeletal Control applied inside our Sub Anim Instance network. In this example we used the Sub-Graph input node to determine the resulting pose data, however, you can create an Animation Blueprint with its own State Machine and logic to generate the resulting pose data as well.

Animation Editors



Skeletal Meshes

Master Pose Component

Copy Pose From Mesh

Skeletal Mesh Merge

Mesh Merge Example

Comparison Chart



When creating systems that enable players to customize their characters and swap out different parts, for example different heads or body types, clothing or other options, you'll want to consider constructing your characters in a modular way. Rather than importing a Skeletal Mesh for the full character, breaking out your Skeletal Mesh into sections, such as the torso, legs, and head, and importing them into the Engine; you can then use some of the methods described on this page for assembling those pieces and animating them. Not only will this give you increased flexibility in generating different characters, it will also be more performant.

Master Pose Component

The Master Pose Component is a Blueprint callable function that enables you to set a Skinned Mesh Component Object (or Skinned Mesh Component Objects) as children to another Skinned Mesh Component Object considered to be the master. For example, you can define the Torso as the Master Pose Component, assign an animation to the Torso, then add Feet, Legs, Hands and a Head as children which will follow the animation assigned to the Torso.

Behind the scenes, the children do not use any Bone Transform Buffer and won't run any animations even if you set them on the child, it only uses the Torso's Bone Transform Buffer when rendered which makes it a very lightweight attachment system. The only Component that has to run animation is the Torso, and all attached Components will use the Torso's Bone Transform. Below is an example setup where we have assigned an animation to the Torso. We use the Construction Script inside a Blueprint to set the Torso Skeletal Mesh as the Master Bone Component and the other aspects of our modular character as children.



Above, we use the Construction Script inside a Blueprint to set the Torso Skeletal Mesh as the Master Bone Component and the other aspects of our modular character as children.

The Set Master Pose Component function has a second parameter of the boolean type called Force Update. If Force Update is disabled, it will skip updating all runtime info if that info is the same as the Master Component. If Force Update is enabled, it will force the updating of the runtime info. This only applies to the registration process as that can be serialized, at which point it will need to refresh all runtime data.

Each aspect of our character is a Skeletal Mesh that we can change out with another Skeletal Mesh Component. Below, we have toggled the display of the Torso and the Feet (we could change these out with different Skeletal Meshes that follow the same Skeletal hierarchy).



One issue to consider however, is that when using Master Pose Component, although it does reduce the game thread cost, it does not reduce the render cost. You will still render the same number of Components separately, keeping in mind that additional sections per Component will incur more draw calls.

There is also the limitation that any children of the Master Bone has to be a subset with the exact matching structure, you cannot have any other extra joints or skip any joints. Since there are no Bone Buffer data for extra joints, it will render using the reference pose. Also, you cannot run any other animations or physics on any children.

Copy Pose From Mesh

Copy Pose From Mesh is an AnimGraph node you can use on the Animation Blueprint of the child that enables you to copy the animation pose from any Skeletal Mesh Component. Copy Pose From Mesh will only copy matching bones, and everything else will use the reference pose. However, you can play the animation on top of the copied transforms as illustrated below.



Click image for full view.

When using Copy Pose From Mesh, you will want to make sure that the Skeletal Mesh Component you copy from had already ticked, otherwise you will copy the last frame's animation (for example, if you are copying from the Body and the Head is the Child). To ensure the Body has ticked, you can attach the Head to the Body, which will ensure the parent ticks first before the child.

You could also set the relationship in code. If you set it as a prerequisite, it will ensure ticking them prior to the current component. See the



Some elements to consider when using Copy Pose From Mesh is that it is more expensive than Master Pose Component because this runs the animation on each child. Additionally, if you want to use physics on the child, you may want to use the Rigid Body or AnimDynamics skeletal control nodes instead.

When previewing an animation in the Animation Editor, you can assign additional meshes that will automatically use Copy Pose From Mesh. You can also create a custom Preview Mesh Collection that you can use to build collections of related Skeletal Meshes that are animated together (such as the components of a character). Below we illustrate how to change and assign different Skeletal Meshes to our preview enabling us to swap out different heads on our character.

Skeletal Mesh Merge

At runtime you can merge multiple Skeletal Meshes into a single Skeletal Mesh through code with FSkeletalMeshMerge. While this has a high initial cost of creating the Skeletal Mesh, the rendering cost is cheaper since you are rendering a single Skeletal Mesh instead of multiple meshes. For example, if you have a character comprised of three Components (head, body and legs) and you have 50 characters on screen, this would result in 50 draw calls. Without Skeletal Mesh Merge, each Component has its own draw call resulting in three calls per character or a total of 150 draw calls.

When using FSkeletalMeshMerge, your main "body" has to contain all the animations because the merged mesh will only use the Skeleton that's set and it has to contain all the joints you'd need to animate. If you have extra joints for certain body parts, you still have to have all the animations on the body. Other things to consider, you can only run one animation on the merged mesh and transferring Morph Targets to the merged mesh is not supported. If however, you look at FSkeletalMeshMerge::GenerateLODModel, once you have your Skeletal Mesh you can create your Morph Targets by calculating the FMorphTargetDelta between your base mesh and any morphs.

Additionally when using FSkeletalMeshMerge you will likely need to build your content in a specific way from the start. You'll want to use one common Material and decide on an atlas for your Textures (for example, boots go in this region while gloves go in this region and so on) so you can cut up and put together your textures to make new ones and render your whole character as one section.

Mesh Merge Example

In the example below, we use the Mesh Merge code to assemble several Skeletal Meshes at runtime.



Above, we have several Skeletal Meshes that we want to join together into a single Skeletal Mesh at runtime. For this example, we create a Blueprint callable function through code called Mesh Merge that will enable us to define the meshes that we want to merge together. The first thing we would need to do is to create our C++ class based on a





Below we have provided the sample code blocks you can use inside your header and source files:

.h code sample

Inside the header, you need to change out all the PROJECTNAME_API references to the name of your actual project. For example, if your project is called "MyProject", you will need to instead use MYPROJECT_API in all those instances for the code to work.

.cpp code sample

Once you compile the code inside the Editor, you can create an ActorBlueprint with a Skeletal Mesh Component and an exposed variable of the Skeletal Mesh Parameters type. This variable will provide you with several properties to define not only the Skeletal Meshes to merge, but how those meshes are merged and additional options.



Below are the options you can use to define how your Skeletal Meshes are merged:

Property

Description

Mesh Section Mappings

This is an optional array to map sections from the source meshes to merged section entries.

UVTransforms Per Mesh

This is an optional array used to transform the UVs in each mesh.

Meshes to Merge

These are the Skeletal Meshes that will be merged together.

Strip Top LODs

The number of top LODs to remove from input meshes.

Needs Cpu Access

Whether or not the resulting mesh needs to be accessed by the CPU for any reason (For example, spawning particle effects).

Skeleton Before

Whether to update the Skeleton before the merge or after (Skeleton must also be provided).

Skeleton

This is the Skeleton that will be used for the merged mesh. You can leave this empty if the generated Skeleton is okay.

Inside your Event Graph, upon Event Begin Play, use the node network below.



Click image for full view.

You can use your new Blueprint Function Merge Meshes to return a Skeletal Mesh object reference while passing in the Mesh Merge Parameters. The Skeletal Mesh Component that is added to the Blueprint can then be used as the target for setting a new Skeletal Mesh to use, which you can point to the return value of the Merge Meshes function call. In the above example, we are also assigning an Idleanimation for the Skeletal Mesh to play once all of the individual meshes have been merged.

After you add the Mesh Merge Blueprint to the Level, inside the Details panel, you can define the Mesh Merge Parameters including the Meshes to Use and Skeleton asset to use.



At runtime, the Mesh Merge function will execute and assemble the Skeletal Mesh based on the defined meshes.

Comparison Chart

Whether you are using Master Pose Component, Copy Pose from Mesh, or Skeletal Mesh Merge there are advantages and disadvantages with each method. The table below outlines the setup and performance cost associated with each, as well as additional features that are (or are not) supported.

Master

Copy Pose

Mesh Merge

Setup Cost

Min

Medium

High

Game Thread Cost

Min

High

Medium

Render Thread Cost

High

High

Low

Physics

No

AnimDynamics or RigidBody

Yes

Morph Target

Yes

Yes

No

Navigating Assets

Opening in Separate Tabs

Revert Unsaved Changes

Content Browser Filtering

Animation Asset Filtering

Reference Viewer

Content Browser Advanced Search Syntax

Animation Blueprints

Compile Settings

Blueprint Editor Cheat Sheet

Pose Watch

Animation Sequence and Montage Editor

Visualizing Additive Animations

Editor Preferences

AutoSave

Level Loading

Play In Editor (PIE)

Animation Debug Text

Miscellaneous Commands

Debugging LODs

Debugging Properties

Memory Tracking

Cheat Scripts

Editor Utility Widgets

Unreal Engine animation workflow shortcuts and tips for animators and animation programmers.

Navigating Assets

Here you will find workflow shortcuts and tips to assist in navigating and working with Animations Assets.

Opening in Separate Tabs

In Unreal Engine, opening a second animation asset of the same type overrides the open asset. To open multiple animations assets of the same type, hold Shift while clicking on another asset to open it in a new adjacent tab.



Revert Unsaved Changes

Unsaved assets will be indicated with an asterisk (*), in the Content Browser. You can revert these unsaved changes by right-clicking the asset and selecting Asset Actions > Reload from the context menu.



Content Browser Filtering

The Content Browser has various filters for all file types, including animation content. The Other Filters category also contains helpful filter options, such as Checked Out files when working within a server-based development environment.

Animation Asset Filtering

With an Animation Asset open, you can filter for content in the Asset Browser tab. Especially useful filters include Anim Filters > Uses Curve for finding animations that rely on an Animation Curve and Anim Filters > Uses Skeleton Notify for animations containing Animation Notifies.

Reference Viewer

The Reference Viewer is a tool you can use to visually see where assets are being used in your project. This is especially useful with animation assets to reference which Animations Sequences or Montages are being referenced in an Animation Blueprint.

First select the asset you wish to see in the Reference Viewer. Then, use the hotkey combination Alt + Shift + R to open the Reference Viewer window.



Content Browser Advanced Search Syntax

Refer to the Advanced Search Syntax documentation for information on how to use the Content Browser's advanced search features.

Animation Blueprints

In the following section you will find helpful Tips and Tricks to aid in the navigation and editing of Animation Blueprints.

Compile Settings

When working with Animation Blueprints, compiling and saving are frequent actions that are preformed in tandem. To enable these functions to occur simultaneously, first open the breakout menu next to Compile in the Toolbar, indicated by the three horizontal dots.

Within this menu, navigate to the Save On Compile option and choose On Success Only.



For debugging purposes, the Jump To Error Node option in the Compile setting breakout menu, will locate and show the point of error or warning in the Animation Blueprint, when a compile has been unsuccessful or produces a warning.

Blueprint Editor Cheat Sheet

Refer to the Blueprint Cheat Sheet for useful general tips on working with the Blueprint Editor.

Pose Watch

Right-click any Animation Blueprint Node in the Animation Graph and select Toggle Pose Watch to see a debug drawing of the pose during animation preview playback.



Toggle multiple animation nodes to see all animations in effect. You can manage the pose watch toggled animations and adjust their properties, such as color, in the Pose Watch Manager window. To open this window, navigate to the Window option in the Menu Bar, and select Pose Watch Manager in the Animation Blueprint Editor section.

Animation Sequence and Montage Editor

In this section you will learn helpful tips and tricks about working within the Animation Sequence Editor.

Visualizing Additive Animations

When previewing Additive Animations in the viewport, click the Character tab and open the Animation breakout menu. Under the Animation header select the Additive Base option to overlay the base pose skeleton over the Additive Animation.



Editor Preferences

Below is a list of helpful properties you can adjust in the Editor Preferences window. You can open the Editor Preferences window in the Menu Bar by selecting Edit > Editor Preferences.

AutoSave

You can enable or disable the Unreal Engine's AutoSave feature with the Enable AutoSave setting. In the Editor Preferences window, navigate in the sidebar to General > Loading & Saving, you will find the AutoSave section, which contains the Enable AutoSave property.

Level Loading

In the Editor Preferences, set the Load Level at Startup property to Last Opened, to reopen the last level open in the editor when relaunching Unreal Engine.

Play In Editor (PIE)

In the section below you will find a reference guide of helpful commands to enter into the Console while running or simulating a project in the Editor. While simulating a project, press the Backtick (`) key to bring up the Console command line. Type a command then press Enter to execute it within the Console.

While debugging, you may find yourself frequently running the same commands. You can send recently used commands to the Console by pressing the Up Arrow key after initializing the command line to bring up a list of recently used commands, navigate to the desired command using the Arrow keys and press Enter to reactivate it.

Animation Debug Text

Command

Description

NextDebugTarget (PGUP)

Cycles to the next debug target.

PreviousDebugTarget (PGDOWN)

Cycles to the previous debug target.

ShowDebug

Toggles the display state of all applicable debug features.

ShowDebug ANIMATION

Toggles display the state of animation debug data.

ShowDebugToggleSubCategory

Toggles display of a specific category. Categories will appear as autocomplete results.

Miscellaneous Commands

Command

Description

a.animnode."NODE_NAME"

Provides debug options for various animation nodes.

Log <Category> <Verbosity>

Changes log verbosity.

Example: Log LogAnimMontage Verbose

p.VisualizeMovement 0

Hides the movement component debug.

p.VisualizeMovement 1

Shows the movement component debug.

show bones

Toggles the rendering of the project's objects' bones.

show collision

Toggles the rendering of the project's objects' collision.

Slomo 0.5

Slows the speed at which the game is displayed. The numerical value is the factor to which the game is slowed. Example: 0.5 = Half Speed.

Stat FPS

Toggles the display of the project framerate in frames per second.

t.MaxFPS 0

Sets the project's framerate limit. A value of 0 will remove the framerate limit.

Framerate adjustments affect the Editor and can have detrimental effects in the functionality of the editor on weaker hardware.

Debugging LODs

Command

Description

a.VisualizeLODs 0

Hides displayed LOD info.

a.VisualizeLODs 1

Displays LOD info.

FORCESKELLOD LOD=0

Forces all Skeletal Meshes to render at specified LOD level. For example: FORCESKELLOD LOD=0 will render LOD 0, LOD=1 will render LOD 1, ext.

FORCESKELLOD LOD=-1

Disables any forced LOD rendering.

Debugging Properties

Command

Description

DisplayAll <ClassName> <PropertyName>

Displays the value of a property on all objects of a specific class.

Example: DisplayAll CharacterMovementComponent Velocity, displays the value of the velocity of all character movement components in the level.

Example: DisplayAll MyAnimBP_C AimYaw, displays the value of AimYaw for all Animation Blueprints in the class.

DisplayClear

Clears the displayed results of a DisplayAll command.

GetAll <ClassName> <PropertyName>

Possesses the same functionality as the DisplayAll command, but prints the values in the Output Log rather than displaying debug text in the editor.

Display <ObjectName> <PropertyName>

Displays the value of a property for a single defined instance.

When using the Display commands to display property values, the GetAll command can be useful for identifying which actors to define in the comand's <ObjectName> field.

Identify the desired Actor's instance in the World Outliner. For example: BP_MyPawn_C_3

Run: GetAll MyAnimBP AimYaw

Find the path to the object's name in the Output Log. For example: /Temp/UEDPIE_0_Untitled_1.Untitled_1:PersistentLevel.BP_MyPawn_C_3.CharacterMesh0.MyAnimBP_C_0

Run: Display /Temp/UEDPIE_0_Untitled_1.Untitled_1:PersistentLevel.BP_MyPawn_C_3.CharacterMesh0.MyAnimBP_C_0 AimYaw

Memory Tracking

Command

Description

obj list class="AnimSequence"

Lists all animation sequence assets that are loaded. Executing this command is a recommended procedure in a cooked build to ensure all assets are present.

obj refs name="ASSET_NAME"

Prints the reference chain of the specified asset.

Example: obj refs name= /Game/Characters/Animations/ThirdPersonJump_End.ThirdPersonJump_End

Cheat Scripts

Use Cheat Scripts to combine multiple Console commands into a single command. You can define and set up Cheat Scripts by adding them to your project's DefaultGame.ini file, found in the projects Config folder.

Example:

The new executable command ShowAnimVars, will now perform the function of DisplayClear, DisplayAll CharacterMovementComponent Velocity, and DisplayAll MyAnimBP_C AimYaw in succession.

Editor Utility Widgets

Editor Utility Widgets allow custom editor widgets to be created entirely in Blueprints. A common use case is to create a set of buttons that trigger common Console commands.

Starting Out

Sequencer Editor

Cameras

Rendering

Workflow Guides and Examples

Cheat Sheet and Workflow shortcuts

Cinematic Samples

Unreal Engine contains robust Cinematic tools enabling you to create animated and cinematic sequences. You can pilot cameras to create level fly-throughs, animate lights, move objects, animate characters, render output sequences, and more. At the core of these workflows is Sequencer, a powerful non-linear editing suite. Sequencer is the primary tool you will be using to create Cinematic content in Unreal Engine.

This page contains links to documentation covering Unreal Engine's Cinematic tools and real-world examples of their associated workflows.



Starting Out

If you're just starting to learn about Cinematics and Unreal Engine, the following pages cover the basics of the Sequencer Editor. Simple guides are provided to assist you in learning common actions you might perform when creating Cinematics.



Get started making cinematics and animations with Sequencer in Unreal Engine.

Sequencer Editor

These pages describe tools, features, and workflows of the Sequencer Editor and tools related to Sequencer.



Learn about Level Sequences and the primary features of the Sequencer Editor.



UI, tools, and options reference page for Sequencer.

UI, tools, and options reference page for Sequencer.



Tweak your keyframes and curves by using the Curve Editor and tools within it.

Tweak your keyframes and curves by using the Curve Editor and tools within it.



Create tracks that affect your actors in Sequencer.

Create tracks that affect your actors in Sequencer.



Edit your cinematic in a non-linear form by using Master Sequences, Shots, and Takes.

Edit your cinematic in a non-linear form by using Master Sequences, Shots, and Takes.



Describes how you can embed Sequences within Actor Blueprints using an Actor Sequence Component.

Describes how you can embed Sequences within Actor Blueprints using an Actor Sequence Component.



Record Editor, Gameplay, and Live Link actors with Take Recorder.

Record Editor, Gameplay, and Live Link actors with Take Recorder.



Animate objects, actors, and properties in Sequencer by keyframing them and utilizing sections.

Animate objects, actors, and properties in Sequencer by keyframing them and utilizing sections.



Tweak Sequencer's behavior using Editor and Project Settings.

Tweak Sequencer's behavior using Editor and Project Settings.



Describes the options available to you when rendering out your cinematic sequences.

Describes the options available to you when rendering out your cinematic sequences.



Describes how you can export FBX files from Sequencer and import FBX files to Sequencer.

Describes how you can export FBX files from Sequencer and import FBX files to Sequencer.



Reuse animation data created in sequencer with Template Sequences.

Reuse animation data created in sequencer with Template Sequences.



Reference your Sequencer Actors using Tags for Blueprint scripting, and organize your tracks with Groups.

Reference your Sequencer Actors using Tags for Blueprint scripting, and organize your tracks with Groups.



Spawn temporary Actors, lights, and other objects in your scene by utilizing Spawnables.

Spawn temporary Actors, lights, and other objects in your scene by utilizing Spawnables.



Prepare and trigger Sequences during your virtual production session.

Prepare and trigger Sequences during your virtual production session.



Learn common Python scripting commands and features used with Sequencer.

Learn common Python scripting commands and features used with Sequencer.

Cameras

The following pages contain information on setting up and using Cameras in your Cinematics.



Learn about using cameras and its features for your cinematics.



The Cine Camera Actor is used as the primary camera type for filming cinematic content in Unreal Engine.

The Cine Camera Actor is used as the primary camera type for filming cinematic content in Unreal Engine.



Control Cameras inside Unreal Engine by using a modular component system to manipulate and output Camera data.

Control Cameras inside Unreal Engine by using a modular component system to manipulate and output Camera data.



Film with real-world techniques in Unreal Engine by using Camera Rigs.

Film with real-world techniques in Unreal Engine by using Camera Rigs.



Create camera shake effects in Unreal Engine.

Create camera shake effects in Unreal Engine.



Use the Cinematic Viewport to add filmmaking controls in the viewport.

Use the Cinematic Viewport to add filmmaking controls in the viewport.



Play full screen videos and image sequences on your cameras using Image Plates.

Play full screen videos and image sequences on your cameras using Image Plates.

Rendering

Unreal Engine's Movie Render Queue allows you to output your Cinematic scenes to an image sequence. These pages describe how to use this tool.



Render and batch render your cinematics with the versatile Movie Render Queue tool.



Customize your render output and visuals with Movie Render Queue's Render Settings

Customize your render output and visuals with Movie Render Queue's Render Settings



Quickly render multiple camera angles to individual images in MRQ using the Still Image Render tool.

Quickly render multiple camera angles to individual images in MRQ using the Still Image Render tool.



How to use Movie Render Queue in a distributed build to create movies on end-users' devices

How to use Movie Render Queue in a distributed build to create movies on end-users' devices

Workflow Guides and Examples

These how-to guides will walk you through how to create certain Cinematic content examples.

Cheat Sheet and Workflow shortcuts

These pages contain small workflow tips, hotkeys, and other time-saving shortcuts.



Tips, tricks, and shortcuts for your cinematic workflow.



A list and description of Sequencer's main hotkeys.

Cinematic Samples

You can also browse and download pre-made projects to learn how these content examples were made with Sequencer.



How to setup the Car Configurator sample project, render a commercial with Movie Render Queue, and edit with the Variant Manager.



How to set up the Meerkat demo, render it with Movie Render Queue, and explore its animation and optimization features



Fully realize your virtual production workflows in Unreal Engine by learning about Slay and its cinematic techniques.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

What is Sequencer?

How to Create and Open Sequencer

How to Create Content with Sequencer

This page provides a beginner's overview of the Sequencer tool for anyone who is starting to learn about Cinematics and Unreal Engine.

What is Sequencer?

Sequencer is Unreal Engine's cinematic toolset where you can directly animate characters, cameras, properties, and other Actors over time. This workflow is achieved by providing a non-linear editing environment in which tracks and keyframes are created and modified along a timeline.



Sequencer requires the creation of Level Sequence assets. These are created and saved in the Content Browser, and then referenced in your Level.



How to Create and Open Sequencer

The easiest way to start using Sequencer is to click the Cinematics dropdown menu in the main toolbar and select Add Level Sequence. This will prompt you to create a new Level Sequence asset. Give it a name and click Save.



Once the Level Sequence is created, the Sequencer Editor will open at the bottom of the Unreal Editor window.



How to Create Content with Sequencer

The following beginner's guides will assist you in learning common actions performed while using Sequencer.

Cameras in Sequencer

Cine Camera Actor

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Creating a Camera

Creating Transform Keyframes

Previewing your Results

This page provides a beginner's overview of creating camera animations in Sequencer and is intended for those who are new to Cinematics and Unreal Engine.

You have read through the Sequencer Basics page and have already created and opened a Level Sequence in your level.

You have a basic understanding of Viewport navigation and controls.

Creating a Camera

Start by creating a Cine Camera Actor in your sequence. The quickest way to do this is by clicking Create New Camera in the Sequencer toolbar. This will create a Cine Camera Actor as a spawnable for this sequence and automatically update your viewport's perspective to the Camera Actor's (this is referred to as Piloting).



To ensure that you are correctly piloting the camera, make sure Lock Cine Camera is enabled on the camera you want to control.



Creating Transform Keyframes

Next, you can start setting up your camera animation. From the viewport, align your camera to the initial position and framing you want to use. Then, navigate to the camera's Transform Track, select it, and press Enter. This will set an initial transform keyframe for the camera.



Next, move the playhead marker to a later point in the sequence by dragging it along the timeline.



Lastly, move the camera in the viewport to a new position. Once done, return to the Transform track, select it, and press the Enter key to place another transform keyframe.



Previewing your Results

To preview your camera animation, click Play in the Sequencer playback controls. You may now also continue to further refine your camera animation by adding more keyframes to your sequence.



This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Adding a Character to Sequencer

Applying Animation to a Character

This page provides a beginner's overview of how to animate Skeletal Meshes in Sequencer, and is intended for those who are new to Sequencer and Unreal Engine.

You have read through the Sequencer Basics page and have already created and opened a Level Sequence in your Level.

Your project contains a Skeletal Mesh and Animation Sequence. If not, you can create a project using the Third Person template, which provides sample Skeletal Meshes and animations.

Adding a Character to Sequencer

Start by adding a character to your Level. Do this from the Content Browser by navigating to your asset and dragging it into your Level.



Next, with your sequence open and the character selected, click Add Track (+) and select Actor to Sequencer > Add ‘SKM_Manny2'. This will add a track referencing the character into your sequence.



When the Skeletal Mesh track is added to the sequence, it automatically adds commonly used tracks for this Actor. In this example, Animation and Transform tracks are automatically created.

Applying Animation to a Character

Click Add Animation (+) on the Animation track. This will list all available animations that are compatible with your character's skeleton. Select one of these animations to add it to your sequence.



Once the animation is added, click Play to preview the sequence. If the animation is intended to continue past the current endpoint, you can drag the edge of the clip to extend it.



Lighting the Environment

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Adding a Light to Sequencer

Animating Intensity

Animating Color

This page provides a beginner's overview of how to animate lights in Sequencer and is intended for those who are new to Cinematics and Unreal Engine.

You have read through the Sequencer Basics page and have already created and opened a Level Sequence in your level.

Lights are in your level.

Adding a Light to Sequencer

Start by adding a light to your sequence. To do this, click Add Track (+) and select Actor to Sequencer > Add ‘Light'. Any type of light Actor can be added as a track in Sequencer.



Whenever a light is added to Sequencer, it will automatically add some of its commonly used tracks to the sequence. In this example, Intensity and Light Color tracks were automatically added.

Animating Intensity

To animate a light's intensity, select the Intensity track and press Enter. This will set a keyframe with the current intensity value.



Next, move the playhead to a later point in the sequence by dragging it.



Finally, set a new intensity value by manipulating the value of the Intensity track. You can do this by either dragging it to change the value, or by selecting the textbox and typing the value directly. Either method will result in a new keyframe being created at the playhead. At this point you can drag the playhead along the sequence, or play the sequence to preview your animation.



Animating Color

To change a light's color, select the Light Color track and press Enter. This will set a keyframe at the current color value. Double-click the keyframe to open the color picker tool, then select a color value and click OK to confirm the change.



Next, move the playhead to a later point in the sequence by dragging it.



Set a new color keyframe by selecting the Light Color track and pressing Enter to create another keyframe. Double-click that keyframe and select a color from the color picker tool. At this point, you can play or scrub the sequence to preview your color animation.



Creating Visual Effects

Creating Visual Effects

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Adding an Effect to Sequencer

Activating the Effect

Continuous Effects

Trigger Effect

Animating Parameters

This page provides a beginner's overview of triggering effects in Sequencer and is intended for those who are new to Cinematics and Unreal.

You have read through the Sequencer Basics page and have created and opened a Level Sequence in your level.

Your project contains Niagara Systems. The example below uses effects from the Stack O Bot project.

Adding an Effect to Sequencer

Start by adding an effect to your Level. Do this by opening the Content Browser, locate a Niagara System asset, and drag it into your Level.



You may want to disable the Auto Activate property in the Particle's Details Panel, to prevent interference with how you want to control it in Sequencer.



Next, with your sequence open and the Niagara System selected, click Add Track (+) and select Actor to Sequencer > Add ‘Niagara System'. This adds a track referencing the effect into your sequence.



Once the track is added, do the following:

On the Niagara track, click Add Track (+) and select NiagaraComponent0.

On the NiagaraComponent0 track, click Add Track (+) and select FX System Toggle Track.



Activating the Effect

Now that your effect is added to Sequencer, there are two main ways to trigger it depending on if the effect is meant to be continuous or singularly triggered.

Continuous Effects

For effects that loop indefinitely, you need to create Activate and Deactivate keyframes.

First, select the FX System track, ensure the dropdown menu is set to Activate, then press Enter. This sets an Activate keyframe on the particle system track which enables the effect at this time.



Next, move the playhead to a later point in the sequence by dragging it. Then click the dropdown menu on the FX System track and select Deactivate. This sets a Deactivate keyframe, which disables the effect at this time.



Now when you play your sequence, you should see the particle activate and deactivate at their corresponding keyframes.



Trigger Effect

For effects that are meant to only play once, and not loop indefinitely, you can use the Trigger keyframe.

To start, click the dropdown menu on the FX System track and select Trigger. This changes the type of keyframe to Trigger, which has no enable/disable states.



Next, select the FX System track and press Enter to place a keyframe. You should now see your effect play.



You can set as many Trigger keyframes as you want for the particle system. They will all trigger with their corresponding keyframes when the sequence is played.



Animating Parameters

If your Niagara System contains User Exposed Parameters, you can animate them in Sequencer as well.

To access a parameter, click Add Track (+) on NiagaraComponent0 and select the Parameter Track. This adds a compatible Property Track for the parameter.



Next, select the Parameter Track and press enter to create a keyframe, then move the playhead to a different location and change the property value on the track to set a new keyframe for that value. You can now play the sequence to see the parameter animate.



Sequencer Asset and Actor

Sequencer Creation

Sequencer Editor

Sequencer Features

Sequencer gives users the ability to create in-game cinematics through its specialized multi-track editor. By creating Level Sequences, adding tracks, and creating keyframes you can manipulate objects, characters, and cameras.

This page provides an overview of Sequencer Actors, Level Sequence Assets, and the primary features of Sequencer.

Sequencer Asset and Actor

Sequencer in Unreal Engine consists of 2 main parts: a Level Sequence Asset and a Level Sequence Actor.

The Level Sequence Asset is located in the Content Browser and contains Sequencer's data. This includes tracks, cameras, keyframes, and animations. This is assigned to a Level Sequence Actor in order to bind its data to a Level.



The Level Sequence Actor is located in the Level and is the container for the Level Sequence Asset. You can select it to view its details in the Details panel.



Name

Description

Open Level Sequence

Opens the Sequence Editor for the currently bound level sequence asset.

Level Sequence

The currently bound level sequence asset.



Playback



Auto Play

The sequence will automatically play when the actor is created.

Loop

Loop options for the sequence. Don't Loop will cause the sequence to play once and finish. Loop Indefinitely will cause the sequence to loop forever. Loop Exactly... will expose a numerical time entry where you can specify the amount of times the sequence will loop, then finish.

Play Rate

The speed of the sequence to play. Does not affect Time Dilation.

Start Offset

The amount of time in seconds the sequence should start relative to the start time.

Random Start Time

Starts playing the sequence at a random point between the start and end time. Enabling this will disable Start Offset.

Restore State

Restores all actors to their previous state before the sequence started.

Pause at End

The sequence will pause upon reaching the end, keeping all actors in their final positions in the sequence.



Cinematic



Disable Movement Input

Disables translation input from the player pawn for the duration of the sequence.

Disable Look At Input

Disables rotation input from the player pawn for the duration of the sequence.

Hide Player

Disables the player pawn's visibility for the duration of the sequence.

Hide Hud

Hides all Heads Up Display (HUD) elements for the duration of the sequence.

Disable Camera Cuts

Disables the Camera Cuts track, causing the sequence to not take control of the camera.

Sequencer Creation

There are several ways you can create and assign your Level Sequences.

One of the quickest ways is to click the Cinematics dropdown in the Level Editor's main toolbar and select Add Level Sequence. This will prompt you to create a new Level Sequence Asset in the Content Browser. Give it a name and click Save. Once created, your Level will now contain a Level Sequence Actor with a reference to the newly created Level Sequence Asset.



An alternate way of creating and assigning your sequence is to click Add/Import > Animation > Level Sequence in the Content Browser. This will also prompt you to create a new Level Sequence Asset.



Once the sequence Asset has been created, navigate to the Place Actors panel and drag in a Level Sequence Actor from the Cinematic category.



Then bind your Level Sequence Asset to the Level Sequence Actor by dragging and dropping the Asset onto the Level Sequence property.



Sequencer Editor

The Sequencer tab contains the Sequencer Editor, which provides a user interface for creating cinematic content.



There are various ways you can open this window.

One way is to click the Cinematics dropdown in the Level Editor's main toolbar and select your sequence from the list. Your sequence must be assigned to a Level Sequence Actor within your Level for it to appear here.



Another way is by clicking the Level Sequence Actor's Open Level Sequence button in the Details panel.



Or by double-clicking the Level Sequence property icon in the Details panel.



You can also open it by double-clicking the Level Sequence Asset in the Content Browser.



When opening a sequence from the Content Browser, you must currently have a Level opened in which this sequence is being referenced. Otherwise the contents will be unbound.

Finally, you can open it by navigating to the main menu bar and clicking Window > Cinematics > Sequencer.



Visit the Sequencer Editor Reference page for more information on the Sequencer editor.



UI, tools, and options reference page for Sequencer.

UI, tools, and options reference page for Sequencer.

Sequencer Features

The following pages detail the primary animation and movie-making features of Sequencer.



UI, tools, and options reference page for Sequencer.

UI, tools, and options reference page for Sequencer.



Tweak your keyframes and curves by using the Curve Editor and tools within it.

Tweak your keyframes and curves by using the Curve Editor and tools within it.



Create tracks that affect your actors in Sequencer.

Create tracks that affect your actors in Sequencer.



Edit your cinematic in a non-linear form by using Master Sequences, Shots, and Takes.

Edit your cinematic in a non-linear form by using Master Sequences, Shots, and Takes.



Describes how you can embed Sequences within Actor Blueprints using an Actor Sequence Component.

Describes how you can embed Sequences within Actor Blueprints using an Actor Sequence Component.



Record Editor, Gameplay, and Live Link actors with Take Recorder.

Record Editor, Gameplay, and Live Link actors with Take Recorder.



Animate objects, actors, and properties in Sequencer by keyframing them and utilizing sections.

Animate objects, actors, and properties in Sequencer by keyframing them and utilizing sections.



Tweak Sequencer's behavior using Editor and Project Settings.

Tweak Sequencer's behavior using Editor and Project Settings.



Describes the options available to you when rendering out your cinematic sequences.

Describes the options available to you when rendering out your cinematic sequences.



Describes how you can export FBX files from Sequencer and import FBX files to Sequencer.

Describes how you can export FBX files from Sequencer and import FBX files to Sequencer.



Reuse animation data created in sequencer with Template Sequences.

Reuse animation data created in sequencer with Template Sequences.



Reference your Sequencer Actors using Tags for Blueprint scripting, and organize your tracks with Groups.

Reference your Sequencer Actors using Tags for Blueprint scripting, and organize your tracks with Groups.



Spawn temporary Actors, lights, and other objects in your scene by utilizing Spawnables.

Spawn temporary Actors, lights, and other objects in your scene by utilizing Spawnables.



Prepare and trigger Sequences during your virtual production session.

Prepare and trigger Sequences during your virtual production session.



Learn common Python scripting commands and features used with Sequencer.

Learn common Python scripting commands and features used with Sequencer.

Sequencer Overview

Cinematic Workflow Guides and Examples

Toolbar

Outliner

Timeline

Timeline Navigation

Panning

Zooming

Playhead

Selection Ranges

Custom Marks

Playback Controls

This page outlines the user interface, tools, and options contained within Sequencer.



Toolbar

Outliner

Timeline

Playback Controls

Toolbar

The Sequencer Toolbar contains various commands, tools, and options.



Name

Icon

Description

World



Lists information on the current world context, Level Sequence Actor, and playback realm. It contains options for specifying whether you want your sequence to autobind to Play In Editor (PIE), Simulation, or other runtime sessions.

Save



Saves the current sequence and any subscenes or shots.

Find in Content Browser



Locates the current sequence's Level Sequence asset in the Content Browser.

Create Camera



Creates a new Cine Camera Actor. A new Camera Cut Track will also be created and will reference this camera if one had not already been created.

Render



Opens the Render Movie Settings dialog, or the Movie Render Queue if its plugin is enabled.

Director Blueprint



Opens the Director Blueprint for this sequence, from which Event Track logic can be accessed.

Actions



Lists various sequence editor actions such as saving, import/export, baking, and selection editing.

View Options



Lists various sequence view options.

Playback Options



Lists various playback options such as playrate, start/end times, and playhead behavior.

Keyframe Options



Lists settings for Auto Key transform keyframing behavior, and what default tangents are created.

Auto Key



Enables Autokey mode, where keyframes are automatically created whenever a property or transform changes.

Edit Options



Lists settings for how edits from the Details panel are interpreted by Sequencer when using Auto Key.

Snapping



Enables snapping. The dropdown menu next to this lists options for setting snapping rules for keyframes, sections, and the timeline.

Frames Per Second



Lists settings for various Frames Per Second (FPS) targets at runtime. Also contains options to enable the runtime to lock to the chosen frame rate.

Curve Editor



Opens the Curve Editor which is used for fine tuning of animation keyframes and tangents.

Breadcrumbs



Displays the current sequence name, and is used to navigate master sequences and shots.

Lock



Locks the entire sequence to prevent editing.

A comprehensive reference for the Sequencer Toolbar can be found on the Sequencer Toolbar Reference page.



Learn about the tools and options within Sequencer's Toolbar.

Learn about the tools and options within Sequencer's Toolbar.

Outliner

The outliner contains header information for all tracks added to your sequence, as well as tools to add, filter, and search for tracks.



Visit the Tracks page for more information.

Timeline

The timeline area contains the entire playable region of your sequence including animations, keyframes, and timeline controls.

The playback range of your sequence is contained within Start (Green) and End (Red) markers.



Timeline Navigation

Panning and zooming are used to navigate within the timeline.

You can pan your view vertically by dragging the right-side scrollbar up and down.



You can also pan and zoom horizontally using the Range Slider at the bottom of the timeline.

Dragging the middle area of the slider pans, while dragging the left/right margins will zoom your view.



The Range Slider is enabled by default and can be disabled from the View Options dropdown in the Sequencer toolbar.

Holding RMB and dragging along the timeline enables panning horizontally and vertically.



Scrolling will pan the timeline up and down, while holding Shift and scrolling will pan the timeline left and right.



You can zoom in the timeline by holding CTRL and scrolling.



By holding ALT + Shift and click-drag RMB left and right you can free-form zoom.



By holding CTRL and dragging along the time bar to the right, you can define a zoom region. Holding CTRL and dragging the time bar to the left resets the zoom back to full.



The zoom pivot is relative to the playhead by default and can be changed by locating the Zoom Position preference in the Editor Preferences and Project Settings.

If your zoom and timeline framing have overextended, you can reset your zoom and timeline framing by pressing the Home key, which also resets the bounds of the range slider.



Playhead

The playhead displays the current time in the sequence and is one of the main controls for timeline interactions. During playback it will move across the timeline at the specified playrate and can be stopped in place by pausing.



You can LMB drag the playhead to change the current time in the sequence, and preview changes in the viewport. This is commonly referred to as "scrubbing".



MMB dragging causes the playhead to change to the selected position without causing the sequence to evaluate. This technique is used to change time, without changing property values and can be used to create same-value keyframes quickly. When manipulating the playhead in this way, it will change its color to yellow, to indicate the sequence is not evaluating.



You can fast forward the playhead to other areas of the timeline by holding Shift and double-clicking a region of the timebar.



The current time of the playhead is displayed and can be manipulated from the sequence outliner. You can press CTRL + T to focus selection to this field and type in a new time value.



You can also right-click the playhead or anywhere on the time bar to reveal additional options.



Name

Description

Hotkey

Set Start Time

Changes the start time of the sequence to the current position of your cursor. If using the hotkey it will set to the playhead instead.

[

Set End Time

Changes the end time of the sequence to your cursor. If using the hotkey it will set to the playhead instead.

]

Set Selection Start

Sets the start point of a custom timeline selection range to your cursor.

i

Set Selection End

Sets the end point of a custom timeline selection range to your cursor.

o

Clear Selection Range

Removes the selection range.

Add Mark

Creates a Custom Timeline Mark at the current playhead time.

m

Delete All Marks

Removes all custom marks from the sequence.

Selection Ranges

Selection ranges are custom regions you can define in a sequence to assist with timeline selection and playback.

To create a selection range, right- click a point in the timeline bar and set a Start and End Selection Range.



The selection range handles can be adjusted similarly to the start and end times of the sequence.



You can also set the playback of the sequence to loop within the section range.



Selection ranges can also be used to select keyframes and sections within them by clicking the Actions toolbar button and selecting Select Keys in Selection Range or Select Sections in Selection Range.



To remove a selection range, right-click the timeline bar and select Clear Selection Range.

Custom Marks

Custom marks are points you can add to call attention to areas or provide annotation for your sequence.



To create a mark, right-click a point in the timeline bar and select Add Mark.

To edit a mark, right-click it to view its details. Here you can customize its properties such as Label, Color and Frame Number.



Marks within Subscenes, Shots, or Template Sequences can be viewed from the parent sequence if you enable Show Marked Frames Globally from the View Options menu.



Marks can also function as Determinism Fences. Determinism Fences force the engine to evaluate on the same frame as the mark, even if normal engine ticking would have skipped over it during playback. They are useful for resolving issues related to events or keyframes being skipped when a sequence or sub sequence is being played.



Playback Controls

The playback controls can be found in the bottom-left corner of Sequencer and function similarly to standard media playback applications.

Buttons for toggling playing, pausing, and other playback-related functions are found here.



Icon

Description



Sets the start time of the sequence to the current location of the playhead.



Jumps to the start of the sequence.



Jumps to the previous keyframe in the selected track.



Jumps to the previous frame.



Plays or pauses the sequence in reverse from the current position of the playhead.



Plays or pauses the sequence from the position of the playhead.



Jumps to the next frame.



Jumps to the next keyframe in the selected track.



Jumps to the end of the sequence.



Sets the end time of the sequence to the current location of the playhead.



Toggles between looping and no looping. Selection range looping is added if selection ranges are being used in the timeline.

Sequencer Editor Reference

World

Create Camera

Render

Director Blueprint

Actions

View Options

Playback Options

Keyframe Options

Auto Key

Edit Options

Snapping

Frames Per Second

Curve Editor

Breadcrumbs

This page provides a reference for Sequencer's Toolbar.



Name

Icon

Description

World



Lists information on the current world context, Level Sequence Actor, and playback realm. It contains options for specifying whether you want your sequence to autobind to Play In Editor (PIE), Simulation, or other runtime sessions.

Save



Saves the current sequence and any subscenes or shots.

Find in Content Browser



Locates the current sequence's Level Sequence asset in the Content Browser.

Create Camera



Creates a new Cine Camera Actor. A new Camera Cut Track will also be created and will reference this camera if one had not already been created.

Render



Opens the Render Movie Settings dialog, or the Movie Render Queue if its plugin is enabled.

Director Blueprint



Opens the Director Blueprint for this sequence, from which Event Track logic can be accessed.

Actions



Lists various sequence editor actions such as saving, import/export, baking, and selection editing.

View Options



Lists various sequence view options.

Playback Options



Lists various playback options such as playrate, start/end times, and playhead behavior.

Keyframe Options



Lists settings for Auto Key transform keyframing behavior, and what default tangents are created.

Auto Key



Enables Autokey mode, where keyframes are automatically created whenever a property or transform changes.

Edit Options



Lists settings for how edits from the Details panel are interpreted by Sequencer when using Auto Key.

Snapping



Enables snapping. The dropdown menu next to this lists options for setting snapping rules for keyframes, sections, and the timeline.

Frames Per Second



Lists settings for various Frames Per Second (FPS) targets at runtime. Also contains options to enable the runtime to lock to the chosen frame rate.

Curve Editor



Opens the Curve Editor which is used for fine tuning of animation keyframes and tangents.

Breadcrumbs



Displays the current sequence name, and is used to navigate master sequences and shots.

Lock



Locks the entire sequence to prevent editing.

World

Sequencer's World menu contains options relating to the current Level, session, and the level sequence name.



The Actors options category lists the running sessions that Sequencer can bind to, and provides you the option to switch your binding between them.

In this example you can see there are now two sessions being run: Editor and Simulate. You have the option to switch between them which causes Sequencer to bind to that realm instead.



Auto Bind to PIE and Simulate enable the automatic binding of Sequencer to their respective realms when they begin to run.

Create Camera

Clicking the Create Camera button will automatically create a Cine Camera Actor and a Camera Cut Track with a binding to the new camera. Your viewport will also begin piloting the camera, which will prepare you to start framing your shot.



You can specify if this camera is spawnable or posessable by toggling Create Spawnable Camera in the Editor Preferences and Project Settings window.

Render

Clicking the Render button will open the Render Movie Settings dialog box, from which you can render your sequence as a series of images.



If you have enabled the Movie Render Queue (MRQ) plugin, then the button will have a dropdown menu from which you can choose between launching the new MRQ tool or the legacy rendering tool.



Director Blueprint

Clicking the Director Blueprint button opens the Sequence Director window, from which you can see your sequence's Event Track events.



Actions

The Actions button displays a dropdown menu with the following tools, commands, and options:



Name

Description

Save As...

Saves the current sequence and provides the option to select a different name.

Import...

Imports an FBX animation file to the selected Actor. If no Actor is selected then the importer will attempt to apply the animation to the entire sequence. Visit the Importing and Exporting FBX files page for more information.

Export...

Exports a selected Actor to an FBX file. If no Actor is selected then the entire sequence will be exported. Visit the Importing and Exporting FBX files page for more information.

Open Director Blueprint

Opens the Director Blueprint for this sequence, from which Event Track logic can be accessed.

Open Binding Tag Manager

Opens a tool from which you can create Tags. These tags are applied to Actors which allows them to be identified in a Blueprint to perform special functions. Visit the Sequencer Tags and Groups page for more information.

Open Sequencer Group Manager

Opens a tool that displays custom groups and the tracks applied to them. Visit the Sequencer Tags and Groups page for more information.

Restore Pre-Animated State

Snaps all Actors back to their default editor positions. Playing or scrubbing the sequence will snap them back to their Sequencer-determined positions.



Transform



Transform Selection

Opens a tool you can use to modify keyframes and sections relative to the playhead time. You can move keys in a positive and negative numerical direction, or multiply and divide their relative distance from the playhead.



Stretch/Shrink

Opens a tool used for adding and removing time in your sequence relative to the playhead time.



Translate Left

Moves a selected keyframe 1 frame to the left relative to the sequence's frame rate.

Translate Right

Moves a selected keyframe 1 frame to the right relative to the sequence's frame rate.

Trim or Extend Section Left

Trims or extends a selected track's section from its left/start point to the playhead location. If no track is selected, then all sections will be trimmed or extended.

Trim or Extend Section Right

Trims or extends a selected track's section from its right/ending margin to the playhead location. If no track is selected, then all sections will be trimmed or extended.

Bake Transform

Selecting this will bake a selected Actor's transform in world space. Any existing attachment or transform tracks will be disabled. This behavior can be changed by locating the Disable Sections After Baking preference in the Editor Preferences and Project Settings window. If you disable it, any existing tracks overwritten during the bake will be deleted.

Sync Sections using Source Timecode

Synchronizes sections with the first selected section using its source timecode.



Selection Range



Set Selection Start

Sets the start point of a custom timeline selection range to the playhead time.

Set Selection End

Sets the end point of a custom timeline selection range to the playhead time.

Clear Selection Range

Removes the selection range.

Select Keys in Selection Range

Selects all keyframes within the selection range. Does not select sections.

Select Sections in Selection Range

Selects all sections within the selection range. Does not select keyframes.

Select All in Selection Range

Selects all keyframes and sections within the selection range.



Advanced



Fix Actor References

Attempts to automatically fix broken Actor bindings by matching the object binding name with an Actor in the Level with the same name.

Rebind Possesable References

Rebinds all posessable Actors in the current sequence to ensure they're using the most robust referencing mechanism.

Networking

Lists options for emulating the current sequence in a Client or Server context.

Volatile

Signifies that this sequence can change dynamically at runtime or during the game. This property must be set if any procedural changes will be made to the source sequence data in game.

Blocking Evaluation

Enables the sequence to fully evaluate and apply its state every time it is updated.

View Options

The View Options button displays a dropdown menu with the following tools, commands, and options:



Name

Description

Pilot Camera

Toggles the piloted camera between the viewport camera and the camera cut track camera.

Auto Scroll

Enables automatic panning in Timeline view to keep the playhead in view when playing.



Range Slider

Toggles the display of the bottom timeline region between a Maya-style range slider and a second timeline bar.



Selected Nodes Only

Automatically filters tracks when enabled to list only tracks or sub-tracks matching the selected Actor.

Combined Keyframes

Shows or hides a preview of a track's keyframes when collapsed.

Channel Colors

Enables the visualization of common colors for transform axes in the Timeline view. Red = X, Green = Y, and Blue = Z.



Pre/Post Roll

Toggles the display of the pre-roll and post-roll visualization for sections.

Zero Pad Frame Numbers

Applies the selected amount of digit padding to the displayed time. Only applies when you are displaying time as frames.



Organize and Sort



Expand/Collapse Nodes

Expands or collapses a selected track.

Expand/Collapse Nodes and Descendants

Expands or collapses a selected track, including all sub-tracks.

Expand All Nodes

Expands all tracks and sub-tracks in the sequence.

Collapse All Nodes

Collapses all tracks in the sequence.

Sort All Nodes

Sorts all tracks by type, then alphabetically within the types.

Show Marked Frames Globally

Makes marked frames in a sub-sequence visible to its parent or sibling sequence.

Clear Global Marked Frames

Sets all marked frames in all sub-sequences to not display.

Playback Options

The Playback Options button displays a dropdown menu with the following tools, commands, and options:



Name

Description

Start

Sets the start time of the sequence.

End

Sets the end time of the sequence.

Playback Speed

Displays options for previewing the current sequence's playback at different speeds.

Playback Range Locked

Locks the start and end times of the sequence and prevents editing.

Game View (Clean Playback Mode)

Automatically enables Game View whenever the sequencer is being played.

Rerun Construction Scripts

Enables the construction script from Blueprint Actors to run every tick. This also requires you to enable the Run Construction Script in Sequencer property in the Blueprint's Class Settings.

Async Evaluation

Enables a single asynchronous evaluation once per frame. When disabled, this forces a full blocking evaluation every time the sequence is evaluated. This should be enabled for sequences that run in real time.

Evaluate Sub Sequences in Isolation

Isolates a sub-sequence or a shot from the master sequence when viewing it. This will disable any tracks or content that may be propagating from the master sequence, as well as disable the shot range preview.

Keep Cursor in Playback Range While Scrubbing

Clamps the playhead within the start and end regions of the sequence when scrubbing.



Link Curve Editor Time Range

Synchronizes the Curve Editor's view with Sequencer's timeline.



Jump Frame Increment

Sets the number of frames to jump when pressing Shift + Left / Right Arrows to jump forward and backward in the timeline.

Keyframe Options

The Keyframe Options button displays a dropdown menu with the following options:



Name

Description

Key All

All transform channels will be keyframed when a value is changed and if auto key is enabled.

Key Group

All axes within a channel will be keyframed when a value is changed and if auto key is enabled.

Key Changed

Only the axis that changes will be keyed if auto key is enabled. This is the default behavior.

Cubic (Auto)

When a new keyframe is created, the tangents will be automatically managed and smoothed during changes. This is the default behavior.

Cubic (User)

When a new keyframe is created, the tangents will be user controlled and will not change if the keyframe is adjusted.

Cubic (Break)

When a new keyframe is created, the tangents will use cubic interpolation and broken to allow for individual edits to in/out angles.

Linear

When a new keyframe is created, the tangents will use linear interpolation.

Constant

When a new keyframe is created, the tangents will use stepped interpolation meaning they retain the previous keyframe's value until the next keyframe.

Auto Key

The Auto Key button enables Auto Key mode which automatically creates keyframes when channels or properties are changed.



Auto Key will only add keyframes if the track already contains at least one keyframe.

Edit Options

The Edit Options button displays options for automatic behavior when manipulating Sequencer-bound and Level-bound actors.



Name

Description

Allow All Edits

Enables interaction with both Sequencer-bound and Level-bound Actors. Both edit operations occur in their respective realms (Sequencer or Level).

Allow Sequencer Edits Only

Manipulating any Level-bound Actor will automatically add the Actor to the current sequence under a folder named: Autotracked Changes.



Allow Level Edits Only

Disables all interaction with Sequencer. You cannot set any keyframes and any edits can only occur in the Level.

Snapping

The Snapping button enables the ability to have your keyframes or playhead marker snap to increments or other keyframes within the timeline.

The Snapping dropdown menu contains options for customizing the snapping behavior.



Name

Description



Key Snapping



Snap to the Interval

Snaps keyframes to time intervals when moving along the timeline.



Snap to Keys and Sections

Snaps keyframes to other keys, or the start and end of sections when moving along the timeline.





Section Snapping



Snap to the Interval

Snaps sections to time intervals when scaling or moving sections in the timeline.



Snap to Keys and Sections

Snaps sections to other keys, or the start and end of sections when moving along the timeline.





Keys and Sections Snapping



Snap Keys and Sections to the Playback Range

Clamps key and section placement to within the playback range.





Play Time Snapping



Snap to the Interval While Scrubbing

Snaps the playhead marker to time intervals while scrubbing.



Snap to Keys While Scrubbing

Snaps the playhead marker to other keys, or the start and end of sections while scrubbing.



Snap to the Pressed Key

Pops the playhead marker to a keyframe when clicked. This can also be done when holding Shift and clicking the keyframe if this option is disabled.



Snap to the Dragged Key

Keeps the playhead maker at the same time as the keyframe when dragging the keyframe along the timeline.





Curve Snapping



Snap Curve Key Values

Toggles value snapping in the Curve Editor.



Frames Per Second

The Frames Per Second (FPS) menu displays options for specifying the frame rate of a sequence, the unit of time to be used, and other timing-related options.



Name

Description

Show Time As

Specifies the unit of time to display in your sequence to Frames, Seconds, or Timecode. This affects all time displays in your sequence.



Clock Source

Directs Sequencer to advance time in one of the following ways:

Tick uses the default mechanism for how the engine advances time.

Platform uses system time.

Audio uses the audio clock and is useful for keeping audio and visuals in sync.

Timecode uses the absolute timecode if one is being used.

Relative Timecode advances relative to the timecode when you press play.

Lock to Display Rate at Runtime

Locks the playback of this sequence to the chosen FPS display rate.

Advanced Options

Opens a window in which you can specify different tick intervals for your sequence.



Curve Editor

The Curve Editor button displays the Curve Editor tab, which can be used to fine-tune your keyframes and tangents.

Visit the Curve Editor page to learn more about it.



Breadcrumbs

The breadcrumbs area of the toolbar displays the name of the current sequence. When using master sequences and shots, it can be used to navigate between your shots and the master sequence.

Use the forward and backward buttons to navigate through your view history, or use the folder button to navigate through all shots in a tree view.



Curve Editor Overview

Toolbar

Outliner

Graph

Graph Navigation

Panning

Zooming

View Modes

Curve Editing

Editing Keyframes

Creating New keyframes

Copy and Paste

Editing Tangents

Weighted Tangents

Buffer Curves

Pre and Post Infinity

Custom Curve Colors

Curve Tools

Transform Tool

Retime Tool

Multi Select Tool

Filter Tool

When you want more control over the way your objects are animated, the Curve Editor can be used to modify and fine-tune your keyframes. Using the Curve Editor's graph, you can create new keyframes, edit tangents, and use various built-in tools to adjust your animation curves.

The Curve Editor is used in other tools across the Unreal Editor, such as Niagara, Curve Assets, and Animation Curves. This guide provides an overview of how to use the Curve Editor within Sequencer, however, many of the features and functions shown will still be compatible within other areas of the editor as well.

You have an understanding of Sequencer and its Interface.

You have an understanding of Keyframing in Sequencer.

Curve Editor Overview

The Curve Editor can be opened from Sequencer by clicking the Curve Editor button in the Sequencer Toolbar.



Once the Curve Editor is opened, you will see the following view:



Toolbar

Outliner

Graph

Toolbar

The Curve Editor Toolbar contains various commands, tools, and options. These can be found listed in the table below.



Name

Icon

Description

Save



Saves the current sequence and any subscenes or shots.

View Modes



Opens a dropdown menu for the Curve Editor View Modes.

Zoom to Fit



Frames and zooms in on the selected keyframes. If no keyframes are selected, then all viewable keyframes within the Graph view will be framed. You can also use the F hotkey for this command.

Focus Playhead



Focuses the graph view on the Playhead without changing zoom level. You can also use the A hotkey for this command.

Zoom to Playback Range



Focuses the graph view so that all keyframes are visible, including the start and end frames of the sequence.

Curve Options



Opens a menu where you can set the following commands:

Tangent Visibility, which controls how Tangents are drawn in the graph. You can choose from:

All Tangents, which causes all keyframes to display their tangents, regardless of whether they are selected or not.

Selected Keys, which only displays tangents on selected keyframes.

No Tangents, which disables all drawing of tangents.

Auto Frame Curves, which causes automatic framing and zooming of all visible keyframes on a curve when it is selected from the Outliner.

Snap Time to Selection, which moves the Playhead to the selected keyframe's time. If multiple keyframes are selected, the Playhead moves to the left-most keyframe.

Buffered Curves, which enables or disables drawing buffered curves in the graph.

Curve Tooltips, which shows a tooltip for a curve's name, time, and value when hovering your cursor over it in the graph.



Time and Value Fields



These property fields display the Time and Value of the selected keyframe. You can edit these properties directly by typing in new values.

Selection Mode



Enables normal keyframe and tangent selection and editing. You can also use the Q hotkey for this command.

Transform Mode



Enables the Transform Tool for editing keyframes. You can also use the Ctrl + T hotkey for this command.

Retime Mode



Enables the Retime Tool, which activates a lattice manipulation mode for adjusting keyframe times. You can also use the Ctrl + E hotkey to enable this command.

Multi Select Mode



Enables the Multi Select Tool, which activates a scaling mode for selected groups of keyframes based on an adjustable pivot. You can also use the Ctrl + M hotkey to enable this command.

Time Snapping



Enables keyframe snapping on horizontal (time) increments in the graph.

The snap increments are based on Sequencer's Frames Per Second if you are using the Curve Editor from Sequencer. Otherwise, you can click the nearby dropdown menu to select a custom time-based snapping increment.



Value Snapping



Enables keyframe snapping on vertical (value) increments in the graph. You can select the nearby dropdown menu to select a custom value-based snapping increment, as well as adjust the display of the graph lines.



Lock Axis



Opens a dropdown menu for selecting which axis to lock keyframe movements to.

Both is the default value and allows keyframe movement in all directions in the graph.

X Only restricts keyframe movement along the horizontal (time) axis only.

Y Only restricts keyframe movement along the vertical (value) axis only.

Cubic (Auto) Tangent



Sets the selected keyframes to interpolate automatically, causing the curve's tangents to adjust based on the location of neighboring keyframes in the graph.



Cubic (User) Tangent



Sets the selected keyframes to use user-defined tangent angles. Whenever you adjust a tangent angle, the keyframe will automatically switch to this mode.



Cubic (Break) Tangent



Sets the selected keyframes tangents to use broken tangent angles, allowing for keyframes that have different incoming and outgoing tangent angles.



Linear Tangent



Sets the selected keyframes to use linear tangent angles. This causes the incoming and outgoing tangents to always face their respective neighbors, resulting in abrupt changes when reaching each keyframe.



Constant Tangent



Sets the selected keyframe to use stepped tangent angles, causing keyframes to maintain their value until reaching the next keyframe.



Weighted Tangents



Sets the selected keyframe to use weighted tangent angles, causing tangents to use user-defined lengths which determines the influence that tangent angle exerts over its neighboring keyframe tangents.



Pre Infinity Settings



Opens a dropdown menu for selecting the Pre-Infinity behavior of the selected keyframe or curve.

Post Infinity Settings



Opens a dropdown menu for selecting the Post-Infinity behavior of the selected keyframe or curve.

Flatten Tangent



Flattens the tangents of the selected keyframes horizontally.



Straighten Tangent



When using Broken Tangents on a keyframe, selecting this will straighten the tangent angles, but not unbreak them. The angles will straighten along an average angle between the two broken tangents.

Filter Tool



Opens the Filter Tool window, where you can bake, simplify, and perform other curve functions.

Outliner

The Curve Editor Outliner contains header information for all animatable tracks added to your sequence, as well as a track filter and playback controls.



Selecting entries from the list automatically filters and frames the Graph View to only display curves from that selection and any children. You can disable the auto-framing behavior by disabling Auto Frame Curves from the Curve Options toolbar menu.



You can also use the search bar to search for entries to narrow down the list. Any returned results will also include children tracks.



Contents displayed in the outliner are determined by what tracks you have selected from Sequencer. Selecting tracks in the Sequencer window will cause only the selected tracks to appear in the Curve Editor Outliner. Deselecting all tracks in Sequencer will cause all contents to appear in the Curve Editor.



You can disable this selection matching and filtering behavior by disabling Synchronize Curve Editor Selection and Isolate Curve Editor to Selection in the Sequencer Editor Preferences window.

Graph

The Curve Editor Graph contains a two-dimensional display of your keyframes, and the interpolated curves generated. The graph plots both Time and Value on the Horizontal and Vertical axes, respectively, and keyframes are positioned in the graph according to those properties.



Graph Navigation

There are several ways to navigate within the graph, as well as different View Modes you can use for representing curve data.

Panning

Use RMB to pan the graph view freely.



Holding Shift + RMB will pan along either the horizontal or vertical axis, depending on the initial direction of your cursor.



Holding Alt + MMB will pan only along the horizontal axis.



Zooming

Scrolling the mouse wheel will zoom the graph relative to the Playhead.



Holding Alt + RMB will smoothly zoom the graph according to your cursor movement. The zoom pivot is relative to your cursor position upon pressing RMB.



Holding Alt + Shift + RMB will freely zoom the graph according to your cursor movement, which enables scaling time and value axes separately. Moving your cursor up and down will scale the value axis, and moving it left and right will scale the time axis.



View Modes

The View Modes menu contains different options to visualize your curves.



Absolute View Mode is the default view mode, in which all curves and keyframes are displayed at their exact values in the graph. This mode functions similarly to most animation curve editors.



Stacked View Mode will separate each curve into its own group, and stack them in the graph. Each group's value range is normalized between -1 and 1.



Normalized View Mode will display all curve and keyframe values overlapping along a normalized value range of -1 and 1. This view can be useful if you are wanting to universally scale curve amounts proportionally.



Curve Editing

The Curve Editor is primarily used for editing your keyframes and tangents. You can add, remove, or change keyframe locations which affect the curve. You can also edit a keyframe's tangent, and control the incoming and outgoing curve vectors of a keyframe, which also affects the curve. There are also a variety of features and behaviors to help with your editing.

Editing Keyframes

Keyframes can be moved by using LMB and dragging them around the graph. Depending on your Snap settings, it should be possible to move a keyframe anywhere along the time and value axes. You can also use MMB to move selected keyframes relative to your cursor position. This provides an easier way for manipulating keyframes without needing selection accuracy.



Holding Shift and dragging a keyframe will cause it to lock on either the horizontal or vertical axes as it moves, depending on the initial direction of your cursor.



Clicking a curve segment will select all keyframes for that curve. With these selected, you can move entire curves by dragging a keyframe or by using MMB to move the curve relative to your cursor.



Creating New keyframes

Keyframes can be added along a curve by clicking MMB when your cursor is hovered over a curve segment.



You can also create keyframes without disturbing the curve structure by holding Ctrl and clicking MMB on any curve segment.



Copy and Paste

Keyframes can be cut (Ctrl + X), copied (Ctrl + C), and pasted (Ctrl + V) on the same curve and across different curves. There are also certain rules and contexts that determine the paste behavior.

When copying and pasting keys, they will paste at their original value and relative to the Playhead. Pasting multiple keys will cause the starting (left-most) keyframe to be placed at the playhead, and all other keys relative to that point.



Depending on which curve you have selected and filtered in the Outliner, the paste operation will occur on all curves within the current view.



If multiple curves are within the current view and you want to paste on only one of them, you can click the curve segment, which will select all keyframes for that curve, and press Ctrl + V.



Editing Tangents

When selecting your keyframes, they will display their tangent information. Tangents are lines that control the incoming and outgoing direction of the curve as it reaches the keyframe. You can select either side of the tangent handle and edit them to control the curve trajectory from that keyframe.



Depending on your Tangent Visibility settings in the Curve Options menu, your tangents may be displayed differently. Ensure this is set to Selected Keys for the default behavior.



To edit a Tangent, first select a keyframe, then select the tangent handle and drag it around in the graph. Similar to moving keyframes, you can also use the MMB to move the tangent relative to your cursor position.



Multiple tangents can be adjusted at the same time by multi-selecting them and using MMB to edit them.



If multiple keyframes are selected, clicking a single tangent will select all tangent handles of the same side.



Holding the Shift key while moving your tangents will snap them to the nearest 45 degree increment.



Various tangent modes are located in the toolbar, and can be used to change the tangent angle of the selected keyframe. Reference the Toolbar section in this document to view their behaviors.



Weighted Tangents

With a keyframe selected, clicking the Weighted Tangents toolbar button will enable weighted tangent angles. This causes tangents to have user-defined lengths which determines the influence that tangent angle exerts over its neighboring keyframe tangents.

Once Weighted Tangents is enabled, you can stretch the tangent to increase its influence on the curve, or shrink it to decrease its influence.



Buffer Curves

Curves can be temporarily saved and stored (known as buffering), which is useful when making experimental changes to your curves as these curves can be reverted to their stored state. While a curve is buffered, it will display an after-image on the graph for your reference.

To store a curve, right-click a part of the curve segment and select Buffer Curves.



After a curve is stored, you can make any edits you want to the curve. Keyframes and tangents can be added, edited, or removed. To revert your curve back to the original stored version, right-click the curve segment and select Apply 1 Buffered Curves. Buffered curve data is locked to the curve it is stored on, so you cannot buffer for one curve and then apply that buffered data to a different curve.



You can also Swap your curves, which restores the curve but also stores the changes you just made. To do this, right-click the curve and select Swap Buffered Curves onto Selected Curves.



Stored curves are lost whenever you close the Sequencer window.

Pre and Post Infinity

Curves also contain rules for how they should behave in the timeframes before and after their keyframe segments. This is known as Pre and Post Infinity, and can be useful in order to extend the animation on a curve without needing to create additional keyframes. Pre-Infinity affects the curve region before the first keyframe, and Post-Infinity affects the curve region after the last keyframe.



You can access the Pre and Post Infinity settings for your curves by clicking the Pre or Post Infinity buttons in the Toolbar, or by right-clicking a curve segment and selecting Pre-Infinity and Post-Infinity. Both methods require you have a keyframe selected from the curve you want to adjust .



You can choose from the following infinity types:

Name

Description

Constant

This is the default value for all new curves, and will cause the curve to retain its value leading up to the first key, and after the final key.



Cycle

The curve will repeat, using the absolute values of the keyframes for each loop segment.



Cycle with Offset

Similar to Cycle, the curve will repeat, however each loop segment's value will be set relative to the previous, causing the curve to compound for each loop.



Linear

The curve will project the first and last keyframe's tangent angle outward.



Oscillate (Ping Pong)

Similar to Cycle, the curve will repeat, however each loop segment will mirror the previous, going backward and forward for each loop.



For looping-based infinity modes, such as Cycle and Oscillate, the loop length is defined by the number of keyframes used. Therefore, it will adjust as you add or adjust the length of your keyframe segments.



Custom Curve Colors

If you want to alter the displayed color of a curve, which can be useful when you want to visually differentiate property curves, you can use the following commands from the Curve Options toolbar menu:

Set Random Curve Colors, which applies a random color to all visible curves.



Set Curve Color For Selected, which opens a Color Picker where you can apply a specific color to a curve. Select a color and click OK to apply the color to the curve.



Custom curve colors are saved on the specific property or channel curve, enabling them to be re-used throughout your project. To view or change curve color data, open Editor Preferences by clicking Edit > Preferences in the main Unreal Engine menu. Navigate to the Content Editors > Curve Editor section and locate the Custom Colors property array. Here you can add, edit, or remove custom color data. Deleting entries will restore the default color for that curve.



Curve Tools

When editing curves, Selection Mode is the default behavior for interacting with keyframes. There are also a variety of other tools you can enable to assist in scaling, transforming, and warping your keyframes.



Transform Tool

The Transform Tool enables a lattice interface when you select your keyframes. You can use the various controls on this lattice to adjust your keyframes' times and values.

To activate the Transform Tool, click the Transform Tool button in the toolbar, then select multiple keyframes.



Various points on the lattice can be manipulated, which scales the entire selection relative to the center point. You can drag the Corners, Edges, and Central areas to adjust the curve.



The pivot point of the transform can also be dragged and changed. It will snap to the edges, corners, and center of the lattice, when moving close to those points.



When the Transform Tool is active, you can also use the Tool Options properties to set explicit values for the lattice. These properties affect specific areas of the lattice and display in absolute Seconds.

Name

Description

Upper / Lower Bound

These properties control the locations of the upper and lower bounds of the lattice.



Left / Right Bound

These properties control the locations of the left and right bounds of the lattice.



Scale Center X / Y

These properties control the location of the scale pivot point.



Retime Tool

The Retime Tool enables a one-dimensional lattice tool, with which you can specify arbitrary anchor points along the time graph in order to retime your keyframes relative to those points.

To enable the Retime Tool, click the Retime Tool button in the toolbar. This will cause two vertical green lines to appear, which are Retime Anchors.



Drag either of the Retime Anchors to retime your keys. When you select one, it will show its influence between its adjacent anchors, which is a linear falloff.



Double-click in the graph to add new anchor points, and click the Delete (X) button below the anchor lines to remove anchors.



Multi Select Tool

The Multi Select Tool enables a pivot-based scaling tool, with which you can scale your curve along either the value or time axes relative to a set pivot point.

To enable the Multi Select Tool, click the Multi Select Tool button in the toolbar, then select multiple keyframes.



Dragging either the vertical or horizontal handles will stretch the selected keyframes along the time or value axes. The horizontal handle corresponds to the XScale property, and the vertical handle corresponds to YScale.



The Pivot Type property controls the placement of the scale pivot point, which is denoted with a crosshair overlay on the graph. You can select the following options from it:

Average, which will place the pivot at the average location between all selected keyframe points and values.

Bound Center, which will place the pivot at the center point of the bounding box of all selected keyframes.

First Key, which will place the pivot at the location of the left-most selected keyframe.

Last Key, which will place the pivot at the location of the right-most selected keyframe.



Filter Tool

The Filter Tool contains various filters and commands with which you can Bake, Smooth, and perform other operations to your curves. To open the Filter Tool window, click the Filter Tool button in the toolbar.



When performing filter commands, the commands will only apply to the keyframes and curves you have selected in the graph.

Baking causes new linear keyframes to be created along your curve selection at a specified interval when clicking Apply.



When baking a curve section, only the section between your keyframe selections will be baked. In the above example you can see curve sections outside of the selection are not being baked.

Bake has the following properties:

Name

Description

Use Frame Bake

If this is enabled, then keyframes will be baked according to the Frames Per Second value of the sequence.

Bake Interval in Frames

The interval to bake keyframes relative to the framerate of the sequence. A value of 1 will bake every frame, and higher number values will skip that number of frames.

Bake Interval in Seconds

If Use Frame Bake is disabled, then this will be the seconds-based interval to bake keyframes.

The Euler filter is used to correct rotational frame jumps. Typically these can occur when working with imported raw motion capture data.



The Fourier Transform filter is used to smooth keyframes with a lot of divergences or noise between them. The smoothing effect is achieved without deleting keyframes, and is based on intelligent low or high pass smoothing with frequency parameters. Typically you would use this if you are cleaning up raw imported motion capture animation, or smoothing a noisy curve with many keyframes.



Select Fourier Transform (FFT) in the filters window to view its properties.



Name

Description

Cutoff Frequency

This property controls the strength of the filtering effect. If Type is set to Lowpass, then you will need to set this value lower in order to produce a smoother result. If Type is set to Highpass, then you will need to set this value higher.

Type

Which types of frequencies are to be allowed through. If Lowpass is specified, then low frequency noise will be ignored and filtering will only occur on high frequency noise.

Response

The type of Fourier filter to use.

Butterworth filter removes noise from data without affecting the curve's minimum or maximum values.

Chebyshev filter removes noise from the data and can affect the curve's minimum or maximum values, but it will have a sharper cutoff at the specified frequency, and will improve accuracy in some cases.

Order

The number of samples to use when filtering in the time domain, which affects how steep the roll-off is for the filter.

In this example, a Butterworth filter type is being used to remove high frequency noise along a curve when clicking Apply.



The Simplify filter removes redundant keyframes based on a tolerance amount, while still maintaining the overall curve. You can also set the following properties to customize the Simplify operation:

Name

Description

Tolerance

The higher the Tolerance value, the more the filtered curve is allowed to deviate from the original, which causes more keyframes to be removed.

Try Remove User Set Tangent Keys

Enables using Sample Rate as the method to sample between evaluated keyframes, which includes keyframes with user tangents to be possibly removed during simplification.

Sample Rate

The frame rate at which the curve should be sampled to compare against Tolerance.

Click Apply to execute the Simplify command on all selected keyframes.



Sequencer Overview

Track List

Adding Tracks

Adding Actors

Adding Components

Organization

Renaming

Lock

Pin

Mute

Solo

Reordering

Search and Filter

In Sequencer, Actor properties and other elements are accessed by the adding of tracks to your timeline. Depending on the track's type, they can be used to organize your tracks, create keyframes, or enable other auxiliary functions.

You have an understanding of Sequencer and its Interface.

Track List

Below is a list of the main tracks you can add in Sequencer.



The Object Binding Track is a track that binds Actors and Objects to Sequencer and provides controls to manipulate their specialized properties or components.

The Object Binding Track is a track that binds Actors and Objects to Sequencer and provides controls to manipulate their specialized properties or components.



The Animation Track enables the adding of Animation Sequences to your Skeletal Mesh track.

The Animation Track enables the adding of Animation Sequences to your Skeletal Mesh track.



Event Tracks support the creation of custom events that are scripted in a dedicated Sequencer Blueprint layer.

Event Tracks support the creation of custom events that are scripted in a dedicated Sequencer Blueprint layer.



The Geometry Cache Track enables the scrubbing and playback of cloth and other Alembic mesh simulations on Static Meshes.

The Geometry Cache Track enables the scrubbing and playback of cloth and other Alembic mesh simulations on Static Meshes.



Sequencer's Audio Track supports the playback of Sound Waves and Sound Cues. You can also adjust the volume and pitch of the sound during playback.

Sequencer's Audio Track supports the playback of Sound Waves and Sound Cues. You can also adjust the volume and pitch of the sound during playback.



The Fade Track in Sequencer is used to fade the entire screen to a solid color. With it, you can fade to black, white, or any other color.

The Fade Track in Sequencer is used to fade the entire screen to a solid color. With it, you can fade to black, white, or any other color.



Set the contents of Levels to be visible or hidden with the Level Visibility track.

Set the contents of Levels to be visible or hidden with the Level Visibility track.



Animate Materials in Sequencer in various ways using Material Tracks with different features.

Animate Materials in Sequencer in various ways using Material Tracks with different features.



Speed up or slow down your Cinematics with the Time Dilation Track.

Speed up or slow down your Cinematics with the Time Dilation Track.



Organize and enable multiple artists to work in the same sequence by using the Subsequences Track.

Organize and enable multiple artists to work in the same sequence by using the Subsequences Track.



The Media Track provides controls for the playback of movies and images from Sequencer using Unreal Engine's Media Framework features.

The Media Track provides controls for the playback of movies and images from Sequencer using Unreal Engine's Media Framework features.



The Camera Cut Track controls which Cine Camera Actor is currently active during playback in Sequencer.

The Camera Cut Track controls which Cine Camera Actor is currently active during playback in Sequencer.



Folder Tracks allow for the organization of your tracks within Sequencer's Outliner.

Folder Tracks allow for the organization of your tracks within Sequencer's Outliner.



Sequencer's Property Tracks are used to animate an Actor's common variables or properties such as transform, floats, or color.

Sequencer's Property Tracks are used to animate an Actor's common variables or properties such as transform, floats, or color.



Adjust render settings and other console variables in your real-time cinematic using the Console Variable Track

Adjust render settings and other console variables in your real-time cinematic using the Console Variable Track



Create your own tracks for use in Sequencer using Blueprints and the Customizable Sequencer Track feature.

Create your own tracks for use in Sequencer using Blueprints and the Customizable Sequencer Track feature.

Adding Tracks

Sequencer provides a variety of ways to add tracks to your timeline.

Clicking Add Track (+) in Sequencer's Outliner reveals the list of tracks to add to your sequence. Select any track here to add it to Sequencer.



Right-clicking in the empty region of the outliner will also bring up the track list.



Adding Actors

One of the most common track Sequencer uses is the Object Binding Track. These are tracks that bind to Skeletal Meshes, Static Meshes, Effects, Blueprints, Components and other objects in a Level.

You can add Actors to your sequence by navigating in the Add Track (+) menu to the Actor To Sequencer submenu. Here you can choose any Actor currently in your Level to add to your sequence, or you can also search for a specific Actor using the search bar.



If an Actor is already selected in your Level, then it will be listed at the top of the Actor To Sequencer list for convenience.

You can also drag Actors from other windows, like the Outliner and add them into Sequencer.



Actors can also be added as Spawnables by dragging them from the Content Browser or Place Actors panels.



Adding Components

Some tracks allow for components and other track types to be added under their main header track. This is done to access specific track functionality, such as transform, components, properties, and other similar features.

To add a component track, hover over the track and click Add Track (+) to view a list of tracks available for the selected track. Typically, this list will be filtered based on the types of tracks and components that track or Actor can support.



As you can with most menus in Unreal Engine, you can type to filter the results in the Add Track (+) menu, making it easier to locate a specific property, component, or other track to add.



Organization

Most tracks have properties that allow for them to be edited and displayed in different ways. These properties are saved in Sequencer and can be shared with others working on your project.

Renaming

To assist in organization, all top-level tracks and components can be renamed in Sequencer. You can rename a track by triple-clicking on the track text, or right-clicking and selecting Rename, or by pressing F2.



When renaming a track bound to an Actor in the Level, the Actor in the level also renames.



Most, but not all tracks can be renamed. Typically, you cannot rename a track if it is a property. However, some property tracks can be renamed, such as Transform.





Tracks in Green can be renamed, tracks in Red cannot.



Lock

Tracks can be locked to prevent keyframes on them and their subtracks from being edited. Right-click a track and select Locked to lock that track. When a track is locked, all keyable tracks under it will display with a red border denoting the lock state.



Pin

You can Pin tracks so that they will appear in a separate outliner section at the top of your Sequencer outliner. Right-click a track and select Pinned to pin that track.



Only one track can be pinned within each sequence.

Mute

Muting tracks causes them to become inactive and to not display any of their properties or keyframe results from Sequencer. Right-click a track and select Mute to mute that track.



If the Object Binding Track is muted, it will also hide the Actor in the viewport.

Solo

When you Solo a track, all other tracks will be muted, allowing for the soloed track to be viewed in isolation. Right-click a track and select Solo to solo that track.



Soloing and muting are editor-only operations and do not impact the Level at runtime, unless you are previewing through Play In Editor.

Reordering

Tracks can be reordered in the outliner by dragging them above or below each other. Visual cues appear when dragging to indicate where the track will be placed.



Search and Filter

You can search and filter for specific track names using Sequencer's search field. Typing the full or partial name of a track will filter out tracks that do not match that name and will include child tracks as part of its search.



Clicking the Filters button will also reveal a list of common track types that you can filter for.



When a filter is applied, the Filter button will indicate with a red dot.



Creation

Binding

Multi Binding

Accessing Components

Automatic Track Creation

In Sequencer, you can add Static Mesh Actors, Skeletal Mesh Actors, and other kinds of Actors in order to animate them. All Actors in Sequencer are referenced by using the Object Binding Track, which enables access to their properties, components, and variables.

This guide provides an overview of the Object Binding Track, how bindings work with it, how to access Actor components within Sequencer, and how to work with automatic track creation.

You have an understanding of Sequencer and its Interface.

You have an understanding of Blueprint Visual Scripting.

Creation

Object Binding tracks are created whenever you add an Actor to Sequencer through a variety of methods.

You can add Actors to your sequence by navigating within the Track (+) menu to the Actor To Sequencer submenu. From here you can choose any Actor currently in your Level to add to your sequence, or you can search for a specific Actor using the search bar.



If an Actor is already selected in your Level, then it will be listed at the top of the Actor To Sequencer list for convenience.

You can also drag Actors from other windows, like the Outliner and add them into Sequencer.



Binding

When Actors are added to Sequencer, the Object Binding Track is created and is bound to the chosen Actor. The binding enables certain property tracks and components to become available that are dependent on the Actor's class.

For example, when the track binds to a Skeletal Mesh Actor, it enables the creation of the Animation Track, which is a track specific to the Skeletal Mesh Component.



Actor bindings can be changed or removed by right-clicking the track and navigating to the Assign Actor menu.



To change an Object Binding Track's binding, you can either choose the new Actor directly from the Actor list in the Assign Actor menu, or select the new Actor and click Replace with Selected.



When rebinding between different classes of Actors, any class-specific tracks will remain, but will no longer function unless the new binding contains a compatible component for the track.

To remove a binding, right-click the Object Binding Track, navigate to the Assign Actor menu, and select Remove All. You may also select Remove Selected if the same Actor is selected in the viewport.



Bindings can also be changed with Blueprint Functions. You can locate binding functions when calling Blueprint functions from a Level Sequence reference object by navigating to Sequencer > Player > Bindings. From here you can choose to use explicit binding functions, such as Set Binding, or changing bindings By Tag.



Multi Binding

Multiple Actors can also be bound to the track, enabling a single track to control several Actors at once. When more than one Actor is bound, the track is denoted with a yellow chevron, and the number of bound Actors is displayed in brackets next to the track name.



Binding multiple Actors can be useful in situations where you want to change the properties of multiple Actors at once, such as when adjusting all lights in an area.



You can also share data between multiple characters in your cinematic, then control their visibility during runtime, enabling conditional characters or objects to be visible when the scene plays.



To bind multiple Actors to the same track, select your required Actors from the viewport, then right-click a currently existing Object Binding Track, and select Assign Actor > Add Selected.



You can bind Actors of different classes together, however you will only be able to access the components of the first bound Actor. Shared properties, such as Transform, will still function correctly though.

Accessing Components

Typically, Actors only have a single component, and the most often used properties for that component are filtered down when adding tracks to the Actor. You can access the full range of an Actor's properties by adding a component track, and adding properties from that component.

This is done by clicking the Track (+) dropdown on the Object Binding Track, and selecting the component from the Components category. Then click the Track (+) dropdown on the component track to view all available component properties.



Actor Blueprints, or Blueprints with multiple components can also have their components accessed in the same way. In this example, an Actor Blueprint contains a Skeletal Mesh Component, Point Light Component, and a Camera Component. These components and their subcomponents are accessible in the Components category when clicking the Track (+) dropdown.



Automatic Track Creation

When adding certain Actors to Sequencer, you may notice that tracks are automatically created with them. For example:

Static Mesh Actors will automatically create a Transform Track.



Skeletal Mesh Actors will automatically create a Transform Track and an Animation Track.



Cine Camera Actors will automatically create a Transform Track and a Camera Component with Aperture, Focal Length, and Focus Distance property tracks.



Light Actors will automatically create a Light Component with Intensity and Light Color property tracks.



This occurs because of the Tracks Settings located in the Sequencer Plugins Project Settings. You can locate these settings by opening the Project Settings window, and locating Level Sequencer in the Plugins category.



The Track Settings array is populated by default with settings for the previously mentioned tracks. You can click the Add (+) button to add a new array item, and each array has the following categories:



Name

Description

Matching Actor Class

This is where you specify the Actor class to automatically create tracks for when adding it to Sequencer.



Default Tracks

This array is where you specify the tracks that are added when the Matching Actor Class is added to Sequencer. Click the Add (+) button and click the dropdown menu to browse Sequencer's track types.



Exclude Default Tracks

This array is where you specify tracks you don't want added for this Actor class. You may want to use this if you are specifying different tracks to add, such as when your class is inheriting from a parent class which also has its default tracks specified here.

Default Property Tracks

This array is where you specify the property tracks that are added when the Actor is added to Sequencer. Click the Add (+) button to add a new property item to the array.



Component Path is where you specify the Actor's component you want to add the property from.

Property Path is where you specify the property name you want to automatically add.

Exclude Default Property Tracks

This array is where you specify property tracks you don't want added for this Actor class. You may want to use this if you are specifying different tracks to add, such as when your class is inheriting from a parent class which also has its default property tracks specified here.

Tracks

Animation Sequences

Skeletal Meshes

Creation

Usage

Animation Mode

Adding Animations

Layers and Blending

Trim, Loop, and Play Rate

Properties

Blending Tools

The Animation track applies animation to your Skeletal Mesh Actors using Animation Sequence assets in Sequencer. This guide provides an overview of the usage of this track and its properties.

You have an understanding of Sequencer and its Interface.

Your project has a Skeletal Mesh actor and can play Animation Sequences in it.

Creation

By default, the Animation track is automatically created under your Actor's track when a Skeletal Mesh Actor class is added to Sequencer. If you have added a different Actor class that supports animation, or have deleted the track, then you can add the track manually by clicking + Track > Animation on the Actor's track, and selecting an Animation Sequence.



Doing this will create the Animation track with an Animation Sequence section at your current playhead time.



Usage

Animation Mode

When a Skeletal Mesh is being animated in Sequencer, its Animation Mode property will switch to Use Custom Mode. This is done to ensure Sequencer drives the Actor's animation using a special Animation Blueprint. This Blueprint enables certain Sequencer behavior on the Animation track, such as animation blending.



Adding Animations

Once an Animation track is created, you can add additional animations to it. There are two ways to do this.

Click the + Animation button on the Animation track and select an Animation Sequence. The animations listed here are filtered to only display compatible animations for the Skeletal Mesh.



You can also drag Animation Sequences from the Content Browser into the timeline area of Sequencer. This operation will preview the clip's length and drop points as you drag along the Animation track.



Dragging onto another clip will create a separate track layer for the animation.

Layers and Blending

The Animation track supports multiple track layers, animations, and allows animations to be blended together in various ways.



You can add a second animation by clicking on the + Animation button and selecting another Animation Sequence asset. This will add the new sequence to your current playhead time. If your playhead is placed over an animation, then it will create a new track layer for the animation.



You can expand the Animation track to reveal the Weight attribute for the layer, which has a value range of 0-1. Weights can be keyframed to allow for dynamic weighting of animation layers.



Animations can be moved between layers by dragging them up and down the layer stack.



Intersecting two animation sections will create an automatic blend curve between them, and will blend the animations over the duration of the intersection.



You can adjust the Start and End blend curves by selecting and moving the blend curve handle located on the upper portion of the animation section's edge. A curve symbol will appear above the cursor to aid your selection accuracy.



Right-clicking a blend curve will reveal the additional context menu commands.



Name

Description

Easing Length

The length of the blend curve. Enabling Auto will cause the blend curve to return to the default behavior and support automatic length calculation when sections are intersecting.



Method

Method controls the type of curves to apply to the blend, and enables custom external blends based on functions.

Options

The Options menu will display a list of curve shapes that you can apply to your blend curve. Selecting one of these will replace your current curve shape with the selected curve.



Trim, Loop, and Play Rate

There are various ways you can edit your clips by looping, trimming, and time-scaling them.

Selecting either edge of the section and dragging inward will trim the section.



You can also split a selected animation section at the current playhead time by pressing Ctrl + /.



Trim and split commands are located in the Edit menu when right-clicking a section.



Sections can be looped by dragging the right-side edge outward. Loop segments are indicated by notches in the section.



Holding Ctrl when hovering on a section edge will engage the Play Rate modifier.



Once the Play Rate modifier is engaged, dragging the clip edge will scale the clip's playback rate instead of looping or trimming.



If you have trimmed or looped a sequence and want to restore it to its original length, you can right-click it and select Edit > Auto Size.



Properties

Animation tracks display the following properties when right-clicking them and navigating to the Properties menu.



Name

Description

Section Range Start

The start time of the animation section.

Section Range End

The end time of the animation section.

When Finished

Determines what the Actor should do when the animation section finishes.

Keep State will keep the Actor in Sequencer's animation mode. This will not cause the Actor to snap back to its previous state and will instead hold on its last animation frame.

Restore State will return the Actor back to its state before Sequencer animated them.

Project Default is the default behaviour, and will use the settings defined in your DefaultEngine.ini project file. Adding the following lines to the .ini file will set the project default.

[/Script/LevelSequence.LevelSequence]

DefaultCompletionMode=KeepState

or

DefaultCompletionMode=RestoreState

Timecode Source

The timecode information for the clip, if timecode is being used. You can also specify delta frames here to control offset information.

Is Active

Activates the selected section. This is similar to Muting Tracks, but is used for sections instead of tracks.



Is Locked

Locks the selected section. This is similar to Locking Tracks, but for sections instead of tracks.



Pre/Post Roll Frames

Specifies the extra padding to apply to the start and end regions of your animation track. This padding causes the first and last frame of the animation to be held for the specified duration. The roll visual can be enabled or disabled in Sequencer's Editor Preferences to preview this padding in the timeline.



Animation

The Animation Sequence asset being referenced.

First Loop Start Frame Offset

When the sequence is being looped, this property controls the amount of start trim to apply to the first loop of the sequence. Subsequent loops will be full length.

When holding the Shift key, you can also change this value directly by dragging your mouse left and right.



Start/End Frame Offsets

The frame offset properties control the amount of offset to apply to the start and end of a section. The result is an effect similar to trimming, but looping will now respect these trimmed regions as the new loop segments.

Play Rate

The playback speed of the section. A value of 1.0 will result in normal-speed playback, lower values will playback more slowly, and higher numbers will playback more quickly.

Reverse

Enabling this will cause the sequence to play backwards, reversing the animation.

Slot Name

Specifies the Anim Slot to play animation from. Anim Slots are containers that can be used in Animation Blueprints to allow for Sequencer to utilize Animation Blueprint logic in addition to the playback of Animation Sequences. In order to use Slot Name you must also set the Animation Mode of your Skeletal Mesh to use the appropriate Animation Blueprint.



Skip Anim Notifiers

When enabled, any Animation Notifies for this animation will be ignored, and will not be triggered.

Force Custom Mode

When enabled, the Skeletal Mesh's Animation Mode will be forced into using Custom Mode for the duration of this animation.

Start Location Offset

Specifies the location offset to apply to the Actor at the beginning of its animation when using root motion.

Start Rotation Offset

Specifies the rotation offset to apply to the Actor at the beginning of its animation when using root motion.

Show Skeleton

Draws a skeleton in the viewport for this animation sequence. Multiple animation sequence skeletons can also be enabled at once, allowing for the display of multiple skeletons per animation on the same character. This is useful when using Sequencer's Blending Tools.



Blending Tools

The Animation Track also supports aligning bones in order to better support dynamic blending. Visit the Blending Tools page to learn more about this feature.



An overview of the animation blending tools for non-linear animation.

An overview of the animation blending tools for non-linear animation.

Overview

Blending Root Motion of Skeletal Animation

Setting Up Skeletal Animation Blending

Blending Non-Root Motion or Static Root Skeletal Animations

Control Rig Integration

Overview

With the new Motion Blending tools, existing animation sequences can be aligned and blended to have characters seamlessly perform a series of animations. The engine automatically calculates offset transformations to align clips and stores that data within the animation sections.

Each animation sequence can overlap an existing animation sequence. The overlapping zone creates a blended region. Traditionally, this blended region would do a simple blending between two animations. This is problematic if you have two animations where the root motion is not located in the same space, then you will see the character transition to the second animation's root location. This is common when blending animations that might have come from different sources. To solve this, you can now blend animations based on a per-bone matching basis. This is particularly useful when blending based on a commonly known point such as when an actor runs, and their foot hits the ground.

Blending Root Motion of Skeletal Animation

You can now blend Skeletal Animation sequences based on their root motion. This means that it is now possible to blend several takes of gameplay animation cycles or keyframe animation to create new animation sequences. This opens new possibilities for using Unreal Engine as a content creation tool for new animations.

Setting Up Skeletal Animation Blending



To set up a blending of skeletal animations, follow these steps:

Open Sequencer.

Create a new Animation Track.

Add at least two skeletal animations to the animation track.

Trim animation Sequences so that similar poses are at the ends of the sequences to be matched. Push Sequences together to ensure there are no spaces between Sequences.

Right-click on the animation and you will see a new section called Motion Blending Options. Commonly used bones for matching include pelvis, right foot, and left foot.



These options include:

Match With This Bone In Previous Clip - Matches the selected bone with the previous clips matching the selected bone.

Match With This Bone In Next Clip - Matches the selected bone with the previous clips matching the selected bone.

Match X and Y Translation - Matches the translation of the root bone in X and Y axes.

Match Z Height - Matches the translation of the root bone in the Z axis only.

Match Yaw and Roll Rotations - Matches the Yaw and Roll rotation for the root bone.

Match Pitch Rotation - Matches the Pitch Rotation on the root bone.

Smoothly blend clips by dragging the skeletal animations so that there is an overlapping region between both animations.

You can now preview the skeleton of the animation on both clips that you are trying to match. Toggle this option on by selecting Show Skeleton. Enabling this shows a colored overlay of the current skeleton. You can manually move the skeleton for better alignment by using the transform tools to adjust it manually.

Along with the visualization of skeletons, you have the option to show a Root Motion Trail. This visualizes the motion and trajectory of the root motion. This can be turned on by right-clicking and under Display and enabling Show Root Motion Trail.



Blending Non-Root Motion or Static Root Skeletal Animations

The default alignment works by moving the root bone of the skeleton, since gameplay root motion animations usually contain the dominant motion for the root. However, some animations, in particular those acquired by motion capture, may have a fixed root. In this case, you can still match the animation to a bone in the previous clip, but if you try to blend them, it may lead to errors since this is attempting to blend both of the offset roots and the distance between the roots and the first child. In this case, you want to blend the first child of the root, which ignores the root offset between the matched animation sequences and ensures a proper blend. Enable this by right-clicking on the Animation track and selecting Blend First Child of Root.



Blending root motion and non-root motion-based animations may not lead to smooth blending.

Control Rig Integration

Sometimes a minor tweak is needed to fix some flaw with the mocap or to change the behavior of an animation slightly to meet the requirements of the shot. Control Rig can be used for such fixes with an Additive FK Control Rig.

Creation

Trigger Events

Repeater Events

Director Blueprint

Event Endpoint

Parameters and Event Payloads

Object Binding

Event Properties

In Sequencer, you can define frames in your sequence where you want to execute Blueprint Scripting functionality. This is accomplished using the Event Track.

This guide provides an overview of the Event Track, including how to create it, access the Director Blueprint, and the types of events you can create.

You have an understanding of Sequencer, and its Interface.

You have an understanding of Blueprints Visual Scripting.

Creation

To create an Event Track, click Add Track (+) in Sequencer, navigate to Event Track, and select either the Trigger or Repeater event type.



Event Tracks can also be created under an Object Binding Track, which will bind the event to that object.



Once an Event Track is created, you can create additional event Sections by clicking Add Section (+) on the Event Track and selecting an event type.



When adding events, you can choose to add either Trigger or Repeater type events. Trigger Events cause an event to evaluate on the same frame as the keyframe, whereas Repeater Events will evaluate for each frame for the duration of the event section.

Trigger Events

Trigger events are events that evaluate once per keyframe. When this track is created, you can then Keyframe it to create event keyframes.



Repeater Events

Repeater events are events that will fire or evaluate for each frame of the sequence continuously for the duration of the event section. Adjusting the Frames Per Second of the sequence will also adjust the evaluation rate of the repeater to match. When this track is created, it will contain a finite Section range, controlling its evaluation time.



You can edit, move, and trim this event section just like any other section in Sequencer.

Director Blueprint

The Director Blueprint is the logic center for the Event Track from which you will perform Blueprint Visual Scripting from your event endpoints. Parameters and Object Bindings can also be specified in the Blueprint in order to pass variable and object information throughout the script. Each Level Sequence has its own Director Blueprint, containing all the logic for the events in that sequence.

There are several ways you can open the Director Blueprint:

Double clicking an event keyframe or section. This method will also bind the event to a new endpoint if it is currently unbound.



Clicking the Director Blueprint Toolbar button.



Clicking the Actions Toolbar button and then selecting Open Director Blueprint.



Event Endpoint

Regardless of whether a Trigger or Repeater event is created, you must bind it to an Event Endpoint in order to add logic to it. To do this, right-click the keyframe (if using trigger) or section (if using repeater) and select Properties > Unbound > Create New Endpoint. Doing this will bind the event keyframe or section to a new endpoint node and open the Director Blueprint.



The Event Endpoint can be renamed in the Blueprint's Details panel from the Name property.



You can create as many event keyframes or sections as you need. Event nodes can also be shared between multiple event sources by using the Quick Bind or Rebind To menus.



Parameters and Event Payloads

Similar to Blueprint Custom Events, the Event Track can have input parameters associated with it. Using event parameters and payloads, you can send property values to targets when the event fires.

To add a parameter to your event, select the event endpoint and click Add Parameter (+) in the Details panel. Doing this will create a new parameter in the details and on the node for scripting



When you right-click the event keyframe or section, additional properties for your parameters will be displayed under the Payload category. Here you can define the values on the parameters, which will be sent when the event executes.



Object Binding

When creating an Event Track under a bound object in Sequencer, it will create an Object Binding for the Event Track where the target object of the event node becomes bound to the object the Event Track has been added to. This makes it easier to script functions on specific Actors in your sequence, as functions can now be called on the object directly.



An additional property will also be exposed on the keyframe or section properties context menu. Pass Bound Object To controls which object parameter this event should be bound to. If you have added additional Object or Blueprint Interface parameters to your endpoint node, then they will be selectable here.



If an endpoint node is not yet designated for your object bound event, you can use the Quick Bind command to add script functions directly related to the bound object, similar to calling functions from an object reference in Blueprints.



Event Properties

When right-clicking either a Trigger keyframe or Repeater section, you can view the following properties in the Properties context menu.



Name

Description

Event

The Event Endpoint this keyframe or section is bound to in the Director Blueprint.

By default this is unbound and can be bound by clicking the dropdown menu and selecting Create New Endpoint or any other existing endpoint node.



Quick Bind contains a list of compatible functions for this event, including the object binding if the Event Track is bound to an object.



Call In Editor

Enabling this will cause the event logic to evaluate in the editor session without requiring you to Play or Simulate in Editor. This property appears once the event is bound to an endpoint node.

You can also right-click the Event Track to view the following properties in the Properties context menu.



Name

Description

Fire Event when Forwards

Enabling this will cause the Event to fire when the sequence is playing forward normally.

Fire Event when Backwards

Enabling this will cause the Event to fire when the sequence is playing in reverse.

Using the Forwards and Backwards properties can be useful if you need to reset an event chain back to normal when previewing your sequence multiple times. You can set one Event Track to fire forward only and another to fire backward only. Afterward, you can hook up the forward event to the normal event chain, and the backward event to the reset chain.

Event Position

Defines where in the evaluation the event should trigger.

At Start Of Evaluation will cause the event to fire first, before anything else is evaluated in the sequence.

At End Of Evaluation will cause the event to fire last, after everything else has been evaluated in the sequence.

After Spawn will cause the event to fire after Spawnables have spawned and evaluated.



Steps

End Result

The Geometry Cache Track enables you to scrub through a Geometry Cache and render it out with frame accuracy. Once you have imported your Alembic file into Unreal Engine and added it to a Level, you can add it to a Level Sequence and add the Geometry Cache Track to play your content.

Steps

For this How-to guide, we are using the Blueprint Third Person template project. You will also need an Alembic file to import into the Engine. If you do not have your own asset, download this Sample File.

Import your Alembic file(s) into Unreal Engine as a Geometry Cache and define your desired settings.



Place your Geometry Cache in the Level, then create a Level Sequence and add it to Sequencer with the + Track button.



Click the + Track button for the newly created Track and select Geometry Cache from the Tracks menu.



Scrub the Timeline to view a playback.



You can also set the Level Sequence to Auto Play before selecting Play in the Level.

End Result

With the Geometry Cache Track set, you can scrub through your content or it will play back automatically when your Level Sequence plays.

You can access the properties of the Geometry Cache by right-clicking on the Track in the Tracks Window. From the properties menu, you can change which Geometry Cache asset is being used, add a Start or End Offset, or adjust the Play Rate. There are also options for the Section itself and whether to play the animation in Reverse.



The following properties are available for Geometry Cache tracks from the right-click context menu, under Properties:

Property

Description

Geometry Cache

Specifies the Geometry Cache asset to play.

Start Offset

Number of frames to offset into the beginning of the animation clip.

End Offset

Number of frames to offset into the end of the animation clip.

Play Rate

Defines the playback rate of the animation clip (lower to slow down, increase to speed up).

Sequencer Overview

Sequencer Editor Reference

Creation

Usage

Editing

Blending

Sound Attaching

Track and Audio Properties

Sound Sources can be played in Sequencer using the Audio Track. Similar to other film editing software, the audio track provides controls for adjusting the volume, pitch, and crossfading sounds together.

This guide provides an overview of the creation and usage of the audio track.

You have an understanding of Sequencer and its Interface.

You have a basic understanding of How to Import Audio Files or your project already contains audio files.

Creation

There are several ways to create an Audio Track and add a sound.

The first way is to click the Track (+) dropdown and select Audio Track. This will create the track in Sequencer.



Then you can add an audio section to the track by clicking the Audio (+) dropdown on the track and selecting a Sound Wave or Sound Cue asset. Doing this will create the audio section at the Playhead.



You can also drag Sound Waves and Sound Cues from the Content Browser into your sequence, which will automatically create the Audio Track and the sound.



You can continue to add as many sounds to the Audio Track as needed by either clicking the Audio (+) button or dragging sources from the Content Browser.



Although both Sound Waves and Sound Cues are playable in the Audio Track, Sound Cues are not fully supported at this time and their usage in Sequencer can lead to unintended results depending on the logic set up within the Sound Cue.

Usage

Similar to most Sections, Audio Sections can be trimmed, looped, and moved within the timeline region. You can also attach audio to Actors, skeletal meshes, and their bones, in order to create sound sources and spatial sounds.

Editing

Dragging the left and right edges of an audio section will trim the Start and End times. Dragging the end time past the duration of the clip will cause the sound to Loop for the trimmed duration.



For more information on all the editing techniques you can use on audio sections, please refer to the Section Interaction area of the Keyframing document.

Blending

Dragging the upper corner edges of an audio section will cause the volume to blend up and down for the duration of the blend.



Intersecting two or more sound sections will cause them to crossfade for the duration of the overlap.



For more information on all the blending techniques and properties you can use on audio sections, please refer to the Blending area of the Keyframing document.

Sound Attaching

Spatial audio can also be played from an Audio Track or section, allowing for sounds to have a 3D source and distance falloff. To do this, you must attach the Audio Track or section to an Actor, and then specify an Attenuation for it.

To attach an audio section to an Actor, expand the Audio Track and locate the Attach Track. Click the dropdown to select an Actor for this section to attach to. Only Actors that are currently referenced in Sequencer can be attached to this track.



If you are attaching to an Actor with a Skeletal Mesh Component, you can select that component after specifying the Actor and then select a bone for the sound to attach to instead.



The attach track can be keyframed as well, so you can change the audio source attachment at any point during playback. When you attach to multiple sources, selecting the Attach track will display a sound icon on all the attached sources. It will highlight in green when the current source is active.



You can also create an Audio Track under any Actor added to Sequencer by clicking the Actor's Track (+) dropdown and selecting an audio asset from the Audio menu. This automatically attaches the sound source to that Actor, but it does not allow the attachment to change to any other Actor, which is denoted by the lack of an Attach track.



Lastly, you will need to specify a Sound Attenuation which is an audio asset that specifies how sound behaves based on the listener's distance from the audio source.

If your Sound Wave already has a Sound Attenuation specified, then this step can be skipped.

Right-click the sound section and navigate to the Properties menu. Enable Override Attenuation and specify a Sound Attenuation asset in the Attenuation Settings property.



Now your sound should play as spatial audio in Sequencer with appropriate falloff denoted by the Sound Attenuation.

Track and Audio Properties

Once a sound asset is added to the Audio Track, it can be expanded to reveal the following keyframable tracks.



Name

Description

Attach

Attaches this sound to an Actor in Sequencer for the purposes of spatial audio.

Pitch

Increases or decreases the pitch frequency of this sound.

Volume

Increases or decreases the overall volume of this sound.

Right-clicking an audio section and navigating to the Properties menu will reveal the following properties.



Name

Description

Sound

The Sound Wave or Sound Cue asset being used.

Start Frame Offset

The number of frames to offset the start time of this audio section by. This value provides a similar effect to Slip Editing, as it is used to adjust the playable region of a sound without affecting the duration. Holding the Shift key and dragging on the clip provides a shortcut to changing this property using your mouse.

Looping

Enables the audio section to loop or not.

Suppress Subtitles

Disables the display of subtitles if subtitles are being used on the Sound Wave asset.

Override Attenuation

Overrides the Sound Wave attenuation asset with the attenuation specified in Attenuation Settings.

Attenuation Settings

Specifies a Sound Attenuation asset to apply to this audio section.

Tracks

Fade Track Overview

Creation and Usage

Fade Color and Settings

Fading Between Gameplay and Cinematics

Gameplay to Cinematic

Cinematic to Gameplay

There may be times when you want to fade in or out of your Level Sequence. You can accomplish this using the Fade Track. This page provides an overview of the Fade Track, as well as additional considerations when fading your cinematics.

You have an understanding of Sequencer.

If you are fading between gameplay and cinematics, then you should have an understanding of Blueprints.

Fade Track Overview

Creation and Usage

To create a Fade Track, click Add track (+) and select Fade Track.



The Fade Track is a Float Property Track that you animate between values of 0 (no fade) and 1 (fully faded).

Set keyframes on the track by selecting the Fade Track and pressing Enter, which keys the default value of 0. Next, move the playhead to a new time and change the track value to 1, which sets a new key with that value at the playhead time.



Now, when playing your sequence, you should see the fade happen gradually.



Fade Color and Settings

You can change the color of the fade and adjust other fade settings by right-clicking the fade section and navigating to the Properties menu.



The following properties have special interaction with the Fade Track:

Name

Description

When Finished

Determines what the property should do when the section finishes. You can select either:

Keep State, which can be used to persist your fade after the sequence ends for the length of the fade section.

Restore State, which restores the fade back to its state before it was animated.

Project Default, which uses the settings defined in your DefaultEngine.ini project file. By default, it is set to Restore State.

Fade Color

You can change the color of the fade effect to be any color you want. In some cases, you may want to fade to white instead of fading to black. The track section inherits the color specified here to indicate the color the Fade Track is fading to.



Fade Audio

Enabling this causes the fade effect to also reduce the audio of all sounds playing, including sounds from the Audio Track, during runtime.

Because Fade Color is set on the section, you need to create two different fade sections if you want to have fades with different colors in a single sequence.



Fading Between Gameplay and Cinematics

The Fade Track is essentially a track version of the Set Manual Camera Fade Blueprint function. Because of this, you can use both the Fade Track and camera fade functions to script fading behavior. This can be useful if your project requires you to create fade transitions between gameplay and cinematics.



Fading using these Blueprint functions requires targeting the Player Camera Manager. You can get a reference to this Object by right-clicking in the graph and selecting Get Player Camera Manager.



In your Sequence, you must also set your fade section property When Finished to Keep State. By default, when the Sequence ends, the fade state reverts back to its previous state before Sequencer begins to play. Keep State overwrites this with the final value from the Fade Track. This may be required in cases to ensure that the Fade Track propagates after the Sequence ends.



Gameplay to Cinematic

If you need to cover a transition from gameplay to cinematic with a fade, do the following:



Create a Start Camera Fade node and set the following parameters on it:

Connect Get Player Camera Manager to Target.

Set To Alpha to 1.

Set Duration to any number greater than 0, which is the length (in seconds) of the blend. The fade will not work if Duration is 0.

Enable Hold when Finished, which holds the fade until Sequencer fades in with the Fade Track.

Add a Delay node that executes after Start Camera Fade and set Duration to the same number as Start Camera Fade's Duration. Start Camera Fade's out execution does not occur on fade complete, so you need a delay to wait for the fade to complete before continuing.

Play your Sequence, which contains a Fade Track fading in, and When Finished is set to Keep State, to ensure the fade does not revert after the Sequence ends.

Cinematic to Gameplay

If you need to cover a transition from cinematic to gameplay with a fade, do the following:



Create an On Finished event bound to your Sequence, which contains a Fade Track fading out, and When Finished is set to Keep State.

Create a Start Camera Fade node and set the following parameters on it:

Connect Get Player Camera Manager to Target.

Set From Alpha to 1.

Set Duration to any number greater than 0, which is the length (in seconds) of the blend. The fade will not work if Duration is 0.

Enable Hold when Finished, which holds the fade in and does not revert back to faded out, due to Sequencer keeping the Fade Track state.

Tracks

Levels

Steps

End Result

There may be times when you want to toggle the visibility of entire Levels during your sequences. You can do so with the Level Visibility Track by setting Levels to either Visible or Hidden within Sequencer. This does not stream in/out the level but sets all the content within the level to either Visible or Hidden.

In this example we create two very small levels with unique content and toggle the visibility of those levels during our cinematic.

Steps

For this how-to, we are using the Blueprint Third Person Template with Starter Content enabled.

Inside your project in the Content Browser, Right-click and create two Levels named Level01 and Level02.



Open Level01, then in the viewport click the ViewMode drop-down and select Unlit



This will make it easier to see the items that we place in the level since there are no lights.

From the Content Browser under Content/StarterContent/Architecture drag the SM_AssetPlatform into the level.



From the Content Browser under Content/StarterContent/Props drag the SM_Chair into the level.



Save the level, then open the Level02 level and drag a Wall_Door_400x300 into the level.



Drag the Floor_400x400 (or any other assets) into the level as shown below.



The content we are added are for example purposes to distinguish Level 01 from Level 02. Feel free to add your own content!

In the Content Browser under Content/ThirdPersonBP/Maps open the ThirdPersonExampleMap and set the viewport to Lit.



From the Menu Bar, select Window then select Levels.



Click the Levels drop-down menu then select Add Exisiting....



We need to add which levels we want to affect with the Level Visibility Track.

In the Open Level window point to your Level01 then repeat the process and add Level02.



Hold Shift and click on each level, then Right-click and change the Streaming Method to Always Loaded.



This will allow us to selectively turn on/off each level with Sequencer's Visibility Track.

Right-click on the Persistent Level and select Make Current.



Our Levels are now set and we can jump into Sequencer and use our Level Visibility Track to affect them.

Please see the Level Streaming for more information on Level Streaming.

From the Toolbar, click Cinematics and Add Level Sequence.



In Sequencer, click the Add button and add the Level Visibility Track.



On the Level Visibility Track, click the Visibility Trigger button and add two Visible and two Hidden tracks.



Right-click on the top-most Visible track, then under Properties click the + for Level Names and enter Level01.



The Level Names field is where we define what level we want to affect, which we set to Level01 for this track.

Repeat the previous step for the second Visible track, but use Level02 instead.

For the two Hidden tracks, set one of the Level Names to Level01 and the other to Level 02 then arrange as shown below.



Above, the top-most tracks are pertaining to Level01 where we move from Visible to Hidden. The bottom two tracks pertain to Level02 where we start out Hidden then move to Visible.

You may not see your items in the level, used the WASD keys and check under the level.



The location where they appear when streamed in is based on the location they are placed in their corresponding levels. You can select the level streamed in Actors like you can any other Actor and manipulate them with the Transform Tools.

Use the preview Play button for the Sequencer Editor to play the Level Sequence.

End Result

The items placed in Level 01 will appear in the Persistent Level before disappearing at which point the items placed in Level 02 appear.

We also dragged the Level Sequence asset into the Level and enabled the Auto Play option so that we could use the Play in Editor option.

One thing to keep in mind with using the Level Visibility Track is that while you can toggle whether or not a level and its assets are hidden or visible, it does not unload or load levels as each level still sits in memory and is either rendered or not rendered based on the setting you choose.

Switch Materials

Animate Material Parameters

Animate Material Parameter Collections

In Sequencer, you can change and animate Materials on your Actors in a variety of ways. Change which Material is currently applied to an Actor using the Material Switcher Track, animate Material Parameters using the Material Parameter Track, or animate several Materials at once using the Material Parameter Collection Track.

This page provides information about the variety of ways you can animate Materials on your Actors in Sequencer.

You have an understanding of Sequencer and its Interface.

You have a basic understanding of creating Materials, Material Parameters, and Material Parameter Collections.

Switch Materials

To switch an Actor's Material with a different one during playback of your sequence, use the Material Switch Track. This track can be useful if you have already created preset Material Instances and want to immediately switch between them.

To switch Materials on your Actor, first add the Mesh Component Track of the Actor in Sequencer. Click Add Track (+) and select the Mesh Component.



Next, add the Material Switcher Track for this Component by clicking Add Track (+) on the Component Track and adding a Material Element Switcher. The element numbers correspond to the Material Elements currently assigned to the mesh. To change more than one material, add switchers for all necessary elements.



Once the tracks are added, you can keyframe them to set materials you want to apply at a specific time. To change the assigned material, click the dropdown menu on the Material Switcher Track and select a different material.



You can now scrub or play your sequence and observe the material switching.



Animate Material Parameters

To animate specific Material Parameters over time within a material, use the Material Parameter Track.

Similar to switching Materials, you must first add the Mesh Component Track of the Actor in Sequencer. Click Add Track (+) on the Actor Track and select the Mesh Component.



Next, add the Material Parameter Track for this Component by clicking Add Track (+) on the Component Track and adding a Material Parameter Element. The element numbers correspond to the Material Elements currently assigned to the mesh. To animate parameters on more than one material, add Material Parameter Tracks for all necessary elements.



Once the element track is added, add a specific Material Parameter to animate. Click Add Parameter (+) on the Material Element Track then select a parameter. Add as many parameter tracks as needed for your element.



Depending on the type of parameter added, Sequencer will interface with it using compatible Property Tracks. For example, adding a Vector Parameter will create a Color Track

Once the parameter tracks are added, you can keyframe them normally to animate the parameters. Afterward, scrub or play your sequence to observe the effects of the parameter changing.



As you can with usual section usage, Material Parameter Sections can be blended with one another by overlapping their sections. This can be useful to blend between different preset material states, rather than directly animating them.



Animate Material Parameter Collections

Sequencer also contains the Material Parameter Collection Track for animating Material Parameter Collections. Use it to directly animate any material where the collection is referenced, so Sequencer can affect multiple materials at the same time.

To create a Material Parameter Collection track, click Add Track (+) in Sequencer and select your Material Parameter Collection Asset from the Material Parameter Collection Track menu.



You can then add individual parameters from this collection by clicking Add Parameter (+) on the track and selecting a parameter. The parameters listed here are based on the parameters created in the collection asset. Once a parameter is selected, its corresponding track is created with a keyframe set at your current time along the timeline.



Due to the arbitrary nature of Material Parameter Collections and how they are set up within each Material's graph, there are a variety of ways the Material Parameter Collection Track can affect your scene. In this example, a vector parameter is used to control additional color tinting on the character. Changing this parameter affects all child instances of this material.



Once the parameter tracks are added, you can keyframe them as usual to animate the parameters. Afterward, scrub or play your sequence to observe the effects of your animated parameter collection.



Creation

Usage

Time Dilation Effects

The Time Dilation Track allows you to speed up or slow down a Cinematic Sequence. Keyframes can also be added in order to add a time warp effect to the sequence.

This document explains how to create, use, and understand the Time Dilation Track.

You have already created and opened a Level Sequence asset.

You have an animated Actor in Sequencer to preview the Time Dilation effect.

Creation

To create a Time Dilation Track, click Add Track (+) and select Time Dilation Track.



The Time Dilation Track creates with a value of 1.0, which is the default speed of the game simulation.



Usage

You can preview different play rates by changing the track's value while playing the sequence.



You can also set keyframes on the Time Dilation Track in order to create a time warp effect for your sequence.

Select the track and press Enter to add a starting keyframe, then move the Time Marker along the timeline and change the Time Dilation value. This should automatically create a new keyframe with this value set.



Time Dilation Effects

The Time Dilation Track affects more than just the Tracks contained within your Cinematic. It also slows down the global time scale of all simulations in your Level. This means that any materials, particles, or other dynamic objects in your Level will have their simulation speed affected by the Time Dilation regardless of whether they are referenced by Tracks in your sequence or not.

The example below shows the Time Dilation Track affecting the speed of a particle simulation, as well as the panning texture of the background clouds. These assets are not being directly referenced by any Tracks in Sequencer.



Tracks

Creation

Working in the Subsequence

Collaboration

Hierarchical Bias

Section Editing

Looping

Properties

In large-scale cinematic productions, it may be necessary to have multiple artists working on the same sequence or even shot at the same time. The Subsequences Track enables this type of workflow by allowing additional sequence assets to be contained within the same sequence. Subsequences can also be used to organize your scene so that repetitive tracks and content are partitioned away into their respective disciplines' subsequence.

This document provides an overview of how to create and use the Subsequences Track.

You have an understanding of Sequencer and its Interface.

Creation

To create a Subsequences Track, click the Add (+) Track button in Sequencer and select Subsequences Track.



From there you can add sequences by either clicking Add (+) Sequence and selecting a sequence from the menu, or by dragging a Level Sequence from the Content Browser onto the Subsequences Track.



Once added, a subsequence section will display the name of its corresponding Level Sequence and the number of tracks contained within it.



Working in the Subsequence

Once a subsequence is added to a sequence, it can be opened by double-clicking its section. When you open a subsequence in this way, it will be displayed within the context of the parent sequence. This means it continues to evaluate tracks from the parent in order to provide the full scene context, even though the current Sequencer view only shows the subsequence.



When viewing subsequences from the parent sequence context, start and end times will be displayed for both the base subsequence, and the trimmed subsequence. In this example, you can see a subsequence with both the Start and End times being trimmed in the parent sequence, and how that information is displayed in the subsequence.



The trimmed area. This is the region that will be played from the parent sequence.

The full playable sequence area. This area has been trimmed, and will not play in its entirety.

Conversely, you can also trim the Start and End times within a subsequence and observe the trimmed region from the parent sequence.



This context view can be enabled or disabled by toggling Evaluate Sub Sequences In Isolation from Sequencer's Playback Menu.

When working within subsequences, you can add tracks, keyframes and other content as with any other sequence, and can preview the results alongside the contents in the parent sequence. As such, subsequences are not only useful for limiting file conflicts, but also for compartmentalizing Sequencer content within different subsequences.



Unlike Shots, multiple subsequences that are stacked in Sequencer will not overwrite the bottom ones. All subsequences will evaluate when played at the same time.

Collaboration

As subsequences affect a different Level Sequence from the main sequence, multiple artists can work on a single cinematic at the same time without any file conflicts occurring. In this example, you can see two different subsequences being used to contain content from both the Visual Effects and Lighting disciplines.



Hierarchical Bias

Due to the nature of the Master Sequence, Shot, and Subsequence systems, there may be cases where the same Actor is being referenced by both the shot and the master, which can cause conflicts. Hierarchical Bias can be used to arbitrate which reference of that Actor should be prioritized to evaluate over other sources. This property is found when right-clicking Shots or Subsequences, navigating to the Properties menu, and locating Hierarchical Bias.



Increasing the bias number on a source will cause that source to "win", decreasing the number will cause it to "lose", and having equal bias between sources will cause all sources to evaluate together and blend (if possible).

The default value for Hierarchical Bias on the top-level (master) sequence is 0, while for subsequences it is 100. This causes shot sources to take precedence over master sources. Bias also compounds for each subseqeunce layer added, so if a shot sequence contained a child subsequence, then it would have a total bias of 200 (100 + 100), causing the deepest level of influence to "win'' by default.

This effect is demonstrated in the image below, where:



The root sequence, which has a default bias of 0, and cumulative bias of 0.

The first child sequence, which has a default bias of 100, and cumulative bias of 100.

The second child sequence, which has a default bias of 100, and cumulative bias of 200.

The following example demonstrates how to utilize Hierarchical Bias values in your sequences.

A Light Actor is placed in a Level, and is referenced by three different sequences:

The Master Sequence references this light, and its color is keyframed to red.



Within the Master Sequence is a Shot, and its color is keyframed to green.



Within the Shot, is a Subsequence, and its color is keyframed to blue.



By default, the Subsequence, and blue light take priority, because it has the largest cumulative bias. For reference, each sequence's bias value is listed below:

Master Sequence = 0

First child sequence = 100

Second child sequence = 200 (100 + 100)



If you right-click the Subsequence section and lower its hierarchical bias to -50, then that will cause the Shot, and green light to take priority. This is because the Subsequence's cumulative bias is now smaller than its parent, causing the green light to have the largest bias.

At this point, each sequence's bias value would be:

Root Sequence = 0

First child sequence = 100

Second child sequence = 50 (100 - 50)



Setting all the bias values to 0 will cause all sequences to evaluate together and the results will be blended. In this example, the red, green, and blue light color values are combined, becoming white.

At this point, each sequence's bias value would be:

Root Sequence = 0

First child sequence = 0

Second child sequence = 0 (0 + 0)



Section Editing

Each subsequence section functions similar to most Sections, meaning they can be moved, trimmed or edited.



To differentiate your subsequences from one another, you can change the color that is displayed on all sections in a track by clicking the color bar on the track header. This will open the Color Picker from which you can select a new color for this track.



Looping

When extending the section beyond its default time, it expands the sequence's playback range in a linear fashion. If you want to loop the sequence instead, right-click on the section and enable Properties > Can Loop.



Properties

Right-clicking a subsequence section and navigating to the Properties menu will reveal the following properties:



Name

Description

Time Scale

Controls the playback rate of the subsequence. A value of 1 will result in a normal playback speed, larger numbers will play faster, and smaller numbers will play slower.

Hierarchical Bias

Controls the Hierarchical Bias of the subsequence. Larger numbers will cause this subsequence to take priority over other sources when referencing the same Actors.

Sub Sequence

The sequence asset that is played by this subsequence.

Network Mask

The network realm that this subsequence is hosted on. This can be set to Client, Server, or Both. It is important to set this appropriately depending on your sequence's content. For example, if a subsequence contains only audio, then it should usually be set to Client only as audio is not played over the server.

Media Framework

Steps

End Result

Additional Information

Sequencer can control the playback of any Media Source by using a Media Track and assigned Media Source and Media Texture assets. Sequencer will also create internal Media Players when playing back your media source so you do not need to create a Media Player asset.

In this How-to, we create a new Level Sequence, assign a Media Track and point it to our EXR image sequence which plays back when we play in our Level.



Steps

For this How-to, we are using a new Blank Blueprint Project. You will also need a series of EXR or PNG images to use for your Media Source. If you do not have a set of images to use, you can download this UE4 Logo set of images for use in this guide.

Inside your project, right-click in the Content Browser and under Media, select Img Media Source and give it any name.

Open the Img Media Source asset, then point the Sequence Path to the sample EXR images and open the first image.

In the Content Browser, right-click then under Media, create a Media Texture asset.

Typically you would create a Media Player asset and an associated Media Texture. When we use the Media Track in Sequencer, each Media Track will automatically create an internal Media Player to handle playback on-demand.

From the Main Toolbar, click Cinematics then select Add Level Sequence and choose any name and save location.

Open the Level Sequence, then click the Track button and select the Media Track option. Alternatively, you can drag a Media Source asset from the Content Browser into Sequencer to create a Media Track.

On the Media Track, click the + Media button and select your Img Media Source asset.

Stretch the Media to frame 520 and move the end marker to the end of the sequence.

Currently, the Media section does not automatically size itself to the length of the Media which is why we are stretching it to fill the section. In a future release, we hope to have it automatically resize itself.

Right-click on the Media, then under Properties, set the Media Texture to your Media Player asset. Whenever you add a Media Track, you will need to go into the Properties and define the Media Texture to associate the Media Track with. This Media Texture will receive the video output of the video that is being played.

You can reuse the same Media Texture from multiple sections, but you will need to make sure that no two sections write to the same Media Texture at the same time.

Select your Level Sequence in the Level, then in the Details panel, enable Auto Play.

From the Modes panel under Basic, drag a Plane into the Level and resize and rotate as desired.

Drag your Media Texture asset from the Content Browser onto the Plane in the Level.



This will automatically create and assign a new Material that uses the Media Texture.

Click the Play button to play in the Editor.

End Result

When you play in the Editor, the video will start playing back as indicated by the Level Sequence which is set to auto play. You can also scrub through the Media inside the Sequencer Editor which will scrub the video playback.

Additional Information

The Media Track currently works best with Img Media Source objects for images sequences, particularly EXR sequences.

MP4 movies and other movie formats are supported but are experimental, as is rendering out Media Tracks.

When optimizing playback of Media Tracks, there are a few things to configure.

First, there is a global setting in the Project Settings > Plugins > IMG Media. The Cache Size GB is the number of gigabytes that each active Media Player will cache. You need to set this to a reasonable number, depending on how many Media Players you have active at a time, and what the memory footprint of video frames is. As a recommendation, 0.5 or 1.0 is usually a good number, but your requirements may differ.



The Cache Behind Percentage is the percentage of the cache that will be used to cache frames behind the current play position. For real-time playback you want to set this to 0 as you are only interested in caching frames forward.

Second, each Media Track Section needs to have its Pre-roll time configured for the frames to be preloaded in time. Again, the correct amount depends on a number of factors, such as how many videos you're playing, how big the frames are or how fast your machine is.

In general, you want to make sure that video frames are pre-rolled early enough so they are available by the time they are needed, but you also don't want to pre-roll too soon as that may interfere with the performance of other sections that are still playing and loading video frames. You should adjust the Cache Size and Pre-roll settings in such a way that the least number of video frames are pre-rolled at any given point in time while still guaranteeing that all frames are ready when needed.

Sequencer Overview

Steps

End Result

Once you have content in your cinematic, you may want to shoot that content from different camera perspectives. In Sequencer, you can do this with the Camera Cuts Track and selecting which cameras to use at a given time in your scene.

In this example we will use the Camera Cuts Track to cycle between cameras as if two characters were talking to one another.

Steps

For this how-to, we are using the Blueprint Third Person Template project with Starter Content Enabled.

In the viewport, select the ThirdPersonCharacter and Delete it from the level. This is the playable character if we were playing the game which we will not need for this example.

In the Content Browser under Content > Mannequin > Character > Mesh, drag the SK_Mannequin into the level.

Add a second SK_Mannequin to the Level and rotate it to face the first Mannequin. We will shoot an example scene between these two mannequins and alternate camera perspectives from each mannequin.

From the Main Tool Bar, click the Cinematics drop-down menu and select Add Level Sequence.

Hold Ctrl and select both mannequins, then in Sequencer click + Track button and select Add Current Selection.

This will add both Skeletal Mesh Actors to Sequencer which we can then animate.

Add the ThirdPersonIdle for each by clicking the + Animation button on each Animation Track. Optionally, you can stretch out the idle animations to the length of the scene so they continue to idle.

From the Place Actors panel in the Cinematic tab, drag a Cine Camera Actor into the level.

Press Ctrl+Shift+P to Pilot the camera and position it over the shoulder of one mannequin. With the Right Mouse Button held and WASD you can fly around the level and view the perspective the camera will take. This makes it easier to frame up your shots exactly as you wish as you get a better indication of what it will look like.

You can exit Pilot mode by click the Eject button.

Add a second Cine Camera Actor and position it over the other Mannequin's shoulder.

Hold Ctrl and select both cameras, then add them to Sequencer. When adding a camera to Sequencer, it will automatically add a Camera Cuts track and assign the first camera added as the default camera to use. You can also add a Camera Cuts track manually from the + Track option menu. Above the Camera Cuts track is grayed out as you can only have one Camera Cuts track assigned per Sequence.

Move the Timeline Marker to frame 50, then click the + Camera button and add the other camera.

Move the Timeline Marker to frame 100, then click the + Camera button and add the first camera. You should now have a sequence that starts with the first camera, switches to the second, then back to the first.

Click the Lock Viewport to Camera Cuts button on the Camera Cuts Track. This will tell the cinematic to use this track and its cameras to view the scene.

Click the Preview Play button in the viewport to preview the scene.

End Result

During playback, you should see the camera perspective change to the two cameras used in the Camera Cuts Track.

In the video above, we also entered Game View (G key in the viewport) to hide the cameras from being displayed during playback.

You can also use the Add Camera shortcut to add and assign a camera in a Camera Cuts Track in one click.



Also, you will automatically enter Pilot Mode for the camera you added!

Creation

Usage

Renaming

Add to Folder

Remove from Folder

Setting Folder Color

Folder tracks in Sequencer are used to organize your content and other tracks within custom folders. This page provides an overview of how to create and use Folder tracks.

You have an understanding of Sequencer and its Interface.

Creation

The most common way to create a Folder track is by clicking Add Track (+) in Sequencer and selecting Add Folder.



Folders can also be created by right-clicking a single or group of tracks and selecting Move to Folder > New Folder. Doing this will create a new Folder track and move the selected tracks under it.



You can also select one or several tracks and press Ctrl + G on your keyboard. This will create a new folder and move the selected tracks under it.



Right-clicking a folder and selecting Add Folder will also create a subfolder on that Folder track.



Usage

Folder Tracks support a wide range of intuitive movement and organization operations.

Renaming

Like most top-level tracks, folders can be renamed by triple-clicking the track text, by right-clicking and selecting Rename, or by pressing F2.



Add to Folder

Tracks can be added to folders by dragging them onto a folder in the Sequencer Outliner.



They can also be added to any currently existing folders by right-clicking them and selecting the folder from the Move to Folder menu.



Remove from Folder

Tracks can be removed from folders by right-clicking them and selecting Remove from Folder.



Setting Folder Color

You can apply colors to each Folder track's icon to distinguish them from one another.

To do this, right-click the folder and select Set Color. A Color Picker window will appear from which you can select your color. Once a color is selected, click the OK button and your folder icon will be updated with the selected color .



Transform Track

Creation

Usage

Properties

Property Tracks

Boolean

Integer

Float

Vectors

Color

String

Enum

Object

UMG Properties

Overridable Channels

Sequencer contains various Property Tracks you can use to animate Actors' common property types. Using these tracks, you can animate properties such as Transform, Color, or Booleans. This guide provides an overview of the various Property Track types that exist in Sequencer.

You have an understanding of Sequencer and its Interface.

Transform Track

One of the most commonly-used tracks in Sequencer is the Transform track. You can use this track to animate the movement of objects, cameras, and characters in your scene.



Creation

By default, whenever a Static Mesh, Skeletal Mesh, or Camera is added to Sequencer, a Transform track will automatically be added under them.

To manually add a Transform track, click Add Track (+) on your Actor Track, and select Transform.



The automatic adding of the Transform track under certain tracks is enabled from the Project Settings, and can be customized to occur for other Actor class types under the Track Setting Project Setting.

Usage

Transform tracks can be expanded to view individual channels or axes. Selecting these channel or axis tracks and pressing Enter will allow you to place keyframes on those specific tracks.



Channels and axes can also be disabled and removed from view if you don't need them. To do this, right-click the transform section and enable or disable channels under the Active Channels category. Removing any channel or axis will cause those tracks to not be evaluated by Sequencer and to not respond to Auto Keying.



Properties

The Transform track section contains properties to assist with improving control on your Transforms. Right-click a Transform track section and select Properties to view them.



The Use Quaternion Interpolation option enables quaternion linear interpolation between transform keyframes. Quaternion interpolation helps reduce Gimbal lock and other Euler-based problems with rotations.





Use Quaternion Interpolation Disabled

Use Quaternion Interpolation Enabled

Show 3D Trajectory contains options for drawing trajectory paths for the Transform track.



These options include:

Only When Selected, which will only draw the trajectory when the object or track is selected.

Always, which will always draw the trajectory regardless of selection.

Never, which will never draw the trajectory.

Regardless of the chosen trajectory setting, the trajectory will always hide when Game View is enabled.

Property Tracks

Sequencer supports the animating of various properties. Properties can be added to your Actor Track in Sequencer by clicking Add Track (+) on your Actor and choosing one from the Properties category.



Boolean

Boolean tracks are used to animate boolean properties. Boolean tracks can only be set to enabled or disabled, and do not interpolate. The timeline will be colored red when set to disabled, and green when enabled.



Booleans are also represented in the curve editor by values of 0 (disabled) and 1 (enabled).

Integer

Integer tracks are used to animate integer properties and do not interpolate.



Float

Float tracks are used to animate scalar float properties. Float keyframes interpolate and can use custom tangents and curves.



To assist with visualizing float value changes, you can enable float curves to be displayed in-line within a float track section.



To enable the float track curve display, right-click on a float track section and select Display > Show Curve.



Vectors

Sequencer supports animating Vector 2, 3, and 4 properties using their respective tracks. All Vector tracks interpolate and can have custom tangents and curves.



Color

The Color track is used to animate color-specific properties in Sequencer, such as on lights or materials. The Color track supports interpolation and will also display the color set at each keyframe along the timeline so you can preview your colors at a glance.



To help with color selection, you can double-click a Color track keyframe to bring up the Color Picker. Once a color is selected, click the OK button and the keyframe will now be set to that color.



The Color track supports animating both Color and Linear Color spaces.

String

The String track is used to animate different String values. String values do not interpolate between keyframes.



Enum

The Enum Track is used to animate different enumerated values. Enum values do not interpolate between keyframes.



Object

The Object Track is used to animate different Object and Asset values. Object values do not interpolate between keyframes.



UMG Properties

Sequencer supports animating properties from UI Elements in the UMG UI Designer. The two main tracks used for UMG are the Margin and Widget Transform Tracks.



Overridable Channels

Some properties can be overridden to output animation data other than normal keyframes or curves. For example, you can override float channels or individual X/Y/Z channels on transform axes to output random perlin noise. This can be useful to create procedural noise-based animation, rather than manually animating noise.



Currently only float/double and transform tracks support overridable channels.

To override a channel navigate either to a Float Track or an individual axis channel of a Transform Track, right-click the track and select Override with Double Perlin Noise.



You can modify noise parameters by right-clicking the track and navigating to Double Perlin Noise Parameters, where both the Frequency and Amplitude can be edited.



Noise channels animate relative to a value of 0. If you want your noise to animate between certain value ranges, such as between 100 - 200, then you can create extra additive Sections, and convert those channels to noise. This way, you can have the base section at a specific value, and then noise will apply additively to that base.



If you have overridden multiple channels within a section, you can right-click on the section and edit all noise parameters at the same time under the Perlin Noise Channels menu.



Creation

Usage

In some cinematic sequences, you may find it necessary to adjust render settings (or other settings) through console variables. You can do this using the Console Variable Track. Editing console variables in track form can be helpful for projects that are real-time, or require changes mid-way through a sequence. For cases where you are rendering your sequence, you may want to instead use Movie Render Queue's global or per-shot console variable render settings.

You have an understanding of Sequencer, and its Interface.

Creation

To add a Console Variable Track to your sequence, click the Track (+) dropdown and select Console Variable Track.



The Console Variable Track works by applying console variables over a range of time using Sections. To create a console variable section, click Section (+) located on the track. Similar to most Sections, console variable Sections can be trimmed, edited, and moved within the timeline region.



Usage

To make console variables execute during the section's duration, right-click on the section and locate the Properties > Console Variables property.



You can add console variables to the Console Variables property by typing in the field next to it. To add multiple variables to a single section, separate each variable with a comma (,) in the text field.



Once your variables are added to the section, you can scrub or play the sequence to preview the effects. As with normal default section behavior, the previous console variable values are restored when the section ends.



Create New Track

Creating Track Logic

Section Events

Section Functions

Overview of Classes

SequencerSectionBP

SequencerTrackBP

SequencerTrackInstanceBP

Using Blueprints and child classes, you can create your own customizable Sequencer tracks. This feature can be used to extend Sequencer track functionality without using C++. It can be useful for prototyping or implementing new tracks you may need on your project.

This document provides an overview of the Custom Sequencer Track feature, how to create new track types, and the various functions used to communicate with common Sequencer objects.

The Customizable Sequencer Track feature is a Plugin that must be enabled prior to use. From Unreal Engine's main menu, go to Edit > Plugins, locate Customizable Sequencer Tracks in the Runtime section, and click the checkbox to enable it. Then, restart Unreal Engine.



You should be familiar with creating and using Blueprints.

Create New Track

New custom Sequencer tracks require creating three different Blueprint classes that are inherited from:

SequencerSectionBP

SequencerTrackBP

SequencerTrackInstanceBP

To do this, in the Content Browser, click Add (+) > Blueprint Class, then navigate in the All Classes section to these three classes. Create a new child Blueprint class for each one.



Next, you must associate the different classes so they communicate. To do this, open the new Blueprint that inherits from SequencerTrackBP and set the following properties in the Class Defaults section of the Details panel:

Set Default Section Type to the new Blueprint that inherits from SequencerSectionBP.

Set Track Instance Type to the new Blueprint that inherits from SequencerTrackInstanceBP.



After you compile and save the Blueprint, you can now add the track as a master track from Sequencer's main Add Track (+) menu.



Creating Track Logic

Although you can now create your new track in Sequencer, its sections have no logic, so nothing will happen when you create the track. To start making logic for your track, open the new Blueprint that inherits from SequencerTrackInstanceBP. In the Functions section, you can override Events to add them to the Event Graph, where you can create Blueprint logic.



Section Events

The following section events can be overridden in the SequencerTrackInstanceBP Event Graph.

Name

Image

Description

OnBeginUpdateInputs



This event executes when a section is about to begin or end. It executes first, but after OnInitialize.

OnEndUpdateInputs



This event executes when a section has finished beginning or ending. It executes after OnBeginUpdateInputs and OnInputAdded/Removed.

OnDestroyed



This event executes when a section is ending and there are no other sections playing. It executes last.

OnInitialize



This event executes when a section is starting and there are no other sections playing. It executes first.

OnInputAdded



This event executes when a section is starting. It executes after OnBeginUpdateInputs.

OnInputRemoved



This event executes when a section is ending. It executes after OnBeginUpdateInputs.

OnUpdate



This event executes continuously every frame as long as any section is active. When first initializing a section, it starts executing after OnEndUpdateInputs.

As an example, this image shows the total execution order of all singular events in a multi-section scenario:



Custom Sequencer Tracks only use sections, and not keyframes.

Section Functions

When building logic in the SequencerTrackInstanceBP child Blueprint, you can use the following functions to get section or owning object information:

Name

Image

Description

Get Animated Object



Gets the object or Actor that this track is a child of, if Track Type is set to Object Track. This function should be paired with a Cast function to get a usable Blueprint reference of the returned object.



Get Input



Gets the currently playing section according to the index (if more than one section is playing). The default return pin is a struct that must be broken to access the actual section object. You can break it either with Break SequencerTrackInstanceInput, or by right-clicking the pin and selecting Split Struct Pin.



Get Inputs



Returns an array of currently playing sections.

Get Num Inputs



Gets the number of currently playing sections.

Overview of Classes

This section contains information about the three main Blueprint classes that make up the custom track as well as their properties.

SequencerSectionBP

SequencerSectionBP is a transient class that is constructed at runtime. You can also use it to set default section properties, which can be overwritten on the section properties in Sequencer. To access and change these properties, navigate to the Class Defaults section in the Details panel.



Name

Description

Timecode Source

The default timecode information for the section, if timecode is being used. You can also specify delta frames here to control offset information.

Is Active

Sets whether or not the section is active by default

Is Locked

Sets whether or not the section is locked by default.

Pre / Post Roll Frames

Specifies extra padding to apply to the start and end regions of the section by default, which causes the first and last frame of the section to be held for the specified duration

SequencerTrackBP

This class is used to set general properties and rules for the track, such as name, type, and supported sections. To access and change these properties, navigate to the Class Defaults section of the Details panel.



Name

Description

Supports Multiple Rows

If enabled, this allows for the track to encompass multiple sub-tracks (rows). This can be useful if you intend to layer data using this track.



Supports Blending

Enabling this will allow the sections to blend between each other.

Track Type

Sets in what context this track can be added and exist in Sequencer. You can select either:

Master Track, which adds the track to the main Add Track (+) menu in Sequencer. This makes the track a top-level Sequencer track.



Object Track, which adds the track to another track's Add (+) menu. The parent track is dependent on the object class defined in Supported Object Type.



Supported Object Type

If Track Type is set to Object Track, this property is used to specify which object type this track can be added under.

Default Section Type

Specifies the inherited base SequencerSectionBP class created as part of the required track setup.

Supported Sections

An array where you can add additional SequencerSectionBP classes to add from the track's Add Section (+) menu. You can use the various Get Input functions when creating your logic to differentiate these sections.



Track Instance Type

Specifies the inherited SequencerTrackInstanceBP class created as part of the required track setup.

Icon

Displays a preview of the track's icon. Expanding this property reveals the following icon properties:

Image: The texture or material to use as the icon image.

Image Size: The size and X/Y dimensions of the image.

Tint: The color of the image. Enabling Inherit will disable any color tinting and instead use the parent widget color.

Draw As: You can select different methods to draw the icon: Box, Border, Image, or Rounded Box.

Tiling: Enables tiling the image in horizontal, vertical, or both directions.

Preview: An area to preview the final look and size of your icon.



Display Name

The default name for the track. This can be overwritten in Sequencer through normal track renaming operations.



Track Row Display Names

An array where you can specify row names if Supports Multiple Rows is enabled. If more than one array element is added, then adding section rows will add all named rows at once.



Color

Sets the default color for the track and its sections. You must ensure that the color's alpha value is not 0, otherwise the transparency will fall through to the default gray color.



Show Vertical Frames

If enabled, this will cause section start and end bounds to display vertical lines in the timeline.



SequencerTrackInstanceBP

This class is used to create the primary logic and behavior of the track within the Event Graph by overriding events and creating functions.



Sequencer Overview

Sequencer Editor Reference

Master Sequence

Creation

User Interface

Shots

Creation

Details and Interaction

Thumbnails

Master Sequence Context

Hierarchical Bias

Takes

In Sequencer, you can organize your cinematic content to be shot-based by utilizing Master Sequences and Shots. A Master Sequence is a sequence which contains multiple other sequences. These sequences are laid out as shot clips, similar to what you might see in other non-linear editors such as Adobe Premiere or Final Cut Pro.

Content can be added to shots, such as cameras, Characters, and other Actors. Shots can be trimmed and moved anywhere in the Master Sequence, enabling a full non-linear editing experience. You can also differentiate shots from one another using the Take system, and can be used to experiment with different shot contents without modifying the original shot.

This guide gives an overview of the Master Sequence, Shot, and Takes systems.

You have an understanding of Sequencer and its Interface.

To see Master Sequences and Shots used in content examples, you can refer to the Samples and Tutorials or Meerkat Demo samples.

Master Sequence

Fundamentally, there is no difference between a Master Sequence and a Level Sequence. A Level Sequence is referred to as a Master Sequence when it contains a Shot Track and Shots. When shots exist in a sequence, additional behaviors and features become enabled to support shot-based workflows

Creation

To create a Master Sequence, you can simply create a Shot Track. Click the Track (+) dropdown and select Shot Track.



You can also click the Cinematics menu in Unreal Editor's main toolbar and select Add Master Sequence. A dialog window will appear afterward, where you can set properties for the creation and management of the master sequence and its shots. Clicking Create Master Sequence will create both the Master Sequence, its shots, and automatically arrange them in the timeline.



Name

Description

Name

The name assigned to the Master Sequence asset being created and its folder.

Suffix

Additional text to apply after the main sequence name for the master sequence asset.

Base Path

The base file directory in which to create the Master Sequence and shots. The Master Sequence will be stored in a subfolder relative to this, and its shots will be stored in shot-named folders relative to the Master Sequence folder.

Number of Shots

The number of shot sequences to create alongside the Master Sequence. Each shot will be automatically added to the master sequence, and will be automatically named, lengthened, and incremented based on the Shots settings you are using.

Sequence to Duplicate

If you already have a Level Sequence with cinematic content, you can assign it here and its contents will be copied and duplicated over the number of shots you have specified. If no sequence is specified, then all shots will be created with only a Camera and Camera Cut Track. This is useful if you want to automatically populate your shots with Actors and cameras.

Sub Sequence Names

An array in which you can add Subscenes to be created within each shot.

Instance Sub Sequences

Enabling this will only create a single Subsequence asset for the first shot. The rest of the shots will reference that sub sequence, instead of creating a unique Subsequence per shot.

An overview of the other properties in the dialog box can be referenced in the Editor Project Settings Page.

User Interface

When viewing a Master Sequence, there are two main areas for navigation and interaction.



Breadcrumbs

Shot Sections

The breadcrumbs area of the toolbar expands when using Master Sequences and Shots, it can be used to navigate between your shots and the master sequence. Clicking the folder dropdown will display a tree view list containing the Master Sequence and Shots contained within. Selecting any of these items will open that sequence.



When viewing a shot or subsequence, the sequence name area will also display the Master Sequence. This is done to provide the ability to navigate back to the Master Sequence by selecting it. It also displays the viewing context, meaning that content from the Master Sequence is influencing the content you are also seeing in the Shot view.



The Forward and Backward buttons can be used to step through your sequence view history, similar to an internet browser.



Your Shots are displayed in Sequencer's timeline area. Each shot section operates similar to most Sections, and can be moved, trimmed or edited. Double-clicking a shot will open it.



When multiple shot tracks are being used, shots placed in the top tracks will be prioritized. This means that if their sections overlap with other sections below, the section range on the top-most tracks will evaluate instead of the bottom tracks.



Shots

Shots are individual sequences used by the Master Sequence to create the complete cinematic sequence. Each shot typically corresponds to its own sequence asset. In typical content setups, you would be placing your Actors, cameras, and other cinematic contents within shots, so that you can perform top-level edits to the whole sequence in the Master Sequence.



Creation

You can create shots a few different ways.

When clicking the Shot (+) dropdown, you can choose to Insert Shot, Insert Filler, or add a currently existing sequence as a shot.



When selecting Insert Shot, an asset creation dialog window will appear, asking you to save the shot sequence asset to a location. By default, the directory will be relative to the Master Sequence, and placed in a shot subdirectory if one is defined in your Editor Project Settings.



When selecting Insert Filler, a shot section is created without binding to a sequence asset. A typical use case for filler is when creating a proxy shot or timing that will later have a sequence assigned to it.



Shots can also be added by dragging Sequencer assets from the Content Browser to the Shots timeline.



Details and Interaction

Right-click a shot section and navigate to the Properties menu to see its details.



Name

Description

Start Frame Offset

The number of frames to offset the start time of this clip. This value provides a similar effect to Slip Editing, as it adjusts the playable region of a clip without affecting the duration.

Holding the Shift key and dragging along the clip provides a shortcut to changing this property using your mouse.



Can Loop

Enables the shot to be looped when extending its section beyond its default playable region.



End Frame Offset

When Can Loop is enabled, this property can be used to offset the loop region end time.

First Loop Start Frame

When Can Loop is enabled, this property can be used to offset the first loop start time.

Time Scale

Controls the playback rate of the shot. A value of 1 is normal speed, larger numbers are faster, and smaller numbers are slower.

Hierarchical Bias

Controls the Hierarchical Bias of the shot. Larger numbers will cause this shot to take priority over other sources when referencing the same Actors.

Sub Sequence

The sequence asset this shot is playing.

Right-clicking a shot and navigating to the bottom of the context menu will reveal shot-specific actions.



Name

Description

Thumbnails

Opens the Thumbnails menu for controlling the image preview on the shot section.

Takes

Opens the Takes list for switching your current take for the shot.

New Take

Creates a new Take based on this current shot.

Insert Shot

Creates a new shot at the playhead's location.

Duplicate Shot

Creates a new sequence asset from the shot's data.

Render Shot

Opens the Render Movie dialog window. If Movie Render Queue is enabled, then a Movie Render Queue window will open instead and will assign that shot to be rendered.

Rename Shot

Renames the shot.

Thumbnails

Thumbnails are images that are displayed on the shot sections to provide a preview image of the shot. Thumbnail images update when zooming in on the timeline in order to show an accurate preview of any specific area of a shot.



You can customize the thumbnail display by right-clicking any shot and navigating to the Thumbnails menu.



Name

Description

Refresh

Regenerates the thumbnails for this shot. This is useful if the thumbnail images are out of date or are displaying incorrectly.

Set Thumbnail Time to...

If Draw Single Thumbnail is enabled, then selecting this will pick a specific frame of the current shot to use as the single thumbnail image.

Refresh All

Regenerates the thumbnails for all shots. This is useful if the thumbnail images are out of date or are showing incorrectly.

Draw Thumbnails

Controls the display of thumbnails for all shots. If disabled, then no thumbnails will display, and the track size will reduce.



Draw Single Thumbnail

Enabling this will cause only a single thumbnail image to display, which is anchored to the start region of the shot. This mimics the thumbnail display found in other editors like Adobe Premiere.



Thumbnail Size

Controls the width and height of thumbnails. Adjusting the height of your thumbnail will increase or decrease the shot track size.

Quality

The quality used to render the thumbnail images.

Master Sequence Context

When a shot is opened from a Master Sequence, it will be displayed within the context of the Master Sequence. This means the shot is including elements from the Master Sequence and other neighboring shot sequences in order to provide the full scene context.

When viewing shots from the Master Sequence context, start and end times will be displayed for both the base shot sequence, and the actual trimmed shot. In this example, you can see a shot with both the Start and End times being trimmed in the Master Sequence, and how that information is displayed in the shot view.



The trimmed area. This is the region that will be played from the Master Sequence.

The full sequence playable area. This area is being edited out, and will not play.

Conversely, you can also trim the Start and End times within a shot and observe the trimmed region on your shot from the Master Sequence.



If Keep Cursor in Playback Range While Scrubbing is disabled from the Playback Menu, then you can further utilize the Master Sequence context by scrubbing outside of the bounds of the trimmed area and see the previous or next shots. This is useful when aligning your current shot with the edits of your adjacent shots.



You can disable this context view by enabling Evaluate Sub Sequences In Isolation from Sequencer's Playback Menu. This option is useful if you want to isolate a specific shot sequence from its master sequence, as any tracks not in this sequence will no longer evaluate alongside the sequence you are currently viewing.



Hierarchical Bias

Due to the nature of the Master Sequence, Shot, and Subsequence systems, there may be cases where the same Actor is being referenced by both the shot and the master, which can cause conflicts. Hierarchical Bias can be used to arbitrate which reference of that Actor should be prioritized to evaluate over other sources. This property is found when right-clicking Shots or Subsequences, navigating to the Properties menu, and locating Hierarchical Bias.



Increasing the bias number on a source will cause that source to "win", decreasing the number will cause it to "lose", and having equal bias between sources will cause all sources to evaluate together and blend (if possible).

The default value for Hierarchical Bias on the top-level (master) sequence is 0, while for subsequences it is 100. This causes shot sources to take precedence over master sources. Bias also compounds for each subseqeunce layer added, so if a shot sequence contained a child subsequence, then it would have a total bias of 200 (100 + 100), causing the deepest level of influence to "win'' by default.

This effect is demonstrated in the image below, where:



The root sequence, which has a default bias of 0, and cumulative bias of 0.

The first child sequence, which has a default bias of 100, and cumulative bias of 100.

The second child sequence, which has a default bias of 100, and cumulative bias of 200.

The following example demonstrates how to utilize Hierarchical Bias values in your sequences.

A Light Actor is placed in a Level, and is referenced by three different sequences:

The Master Sequence references this light, and its color is keyframed to red.



Within the Master Sequence is a Shot, and its color is keyframed to green.



Within the Shot, is a Subsequence, and its color is keyframed to blue.



By default, the Subsequence, and blue light take priority, because it has the largest cumulative bias. For reference, each sequence's bias value is listed below:

Master Sequence = 0

First child sequence = 100

Second child sequence = 200 (100 + 100)



If you right-click the Subsequence section and lower its hierarchical bias to -50, then that will cause the Shot, and green light to take priority. This is because the Subsequence's cumulative bias is now smaller than its parent, causing the green light to have the largest bias.

At this point, each sequence's bias value would be:

Root Sequence = 0

First child sequence = 100

Second child sequence = 50 (100 - 50)



Setting all the bias values to 0 will cause all sequences to evaluate together and the results will be blended. In this example, the red, green, and blue light color values are combined, becoming white.

At this point, each sequence's bias value would be:

Root Sequence = 0

First child sequence = 0

Second child sequence = 0 (0 + 0)



Takes

When creating cinematic content, there may be cases where you want to experiment with your shots without modifying the original shot. Takes can be used to create separate copies of shots, allowing you to edit those copies without disturbing the original.

To create a Take, right-click a shot and select New Take. A new asset window will appear, with the directory pointing to the same folder as the original shot. Click Save to save the new Take.



By default, new takes will be named after a shot, with a numerical postfix. You can customize this postfix in the Editor Project Settings.

When a new take is created, the shot will switch to using it instead of the original shot. You can change between the original (Take 1), and other takes by right-clicking and navigating to the Takes menu. The active take is denoted by a star icon next to the entry.



Sequencer Overview

Sequencer Editor Reference

Blueprints Visual Scripting

Steps

End Result

This is an experimental feature that is currently undergoing development. Some aspects may not work as expected or may change in future revisions.

When working with and creating Sequences, there may be situations where you want to reuse the functionality of a Sequence in other places or instances. With the Actor Sequence Plugin and Actor Sequence Component, it is possible to embed Sequences directly into an Actor Blueprint. This enables reuse of Sequences by binding the animations to the Blueprint instance and triggering them automatically or through the Event Graph of the Blueprint. Additionally, you can add an Actor Sequence Component to any Actor in the world to add animations to a single instance of an Actor.

In this how-to guide, you'll create a Blueprint with an embedded Sequence that animates and changes the color of a Spot Light over time.



The Blueprint can then be placed in any level or duplicated and the embedded Sequence will play automatically when called.

Steps

For this how-to guide, we are using the Blueprint Third Person Template with Starter Content enabled.

With your project open, from the Edit menu select Plugins.

From the Plugins menu, under Built-in, enable the Actor Sequence Editor option and restart the editor when prompted.



You may see the Experimental confirmation dialog window when enabling the Actor Sequence Editor, click Yes to proceed.

Create a new Blueprint of the Actor type can call it Light_BP.



Inside the Light_BP, click Add Component and add a Spot Light.



In the Details panel for the Spot Light, change the Rotation value for Y to -60.



This will rotate and angle the light slightly downward in the viewport.

Add another Component of the Static Mesh type, then in the Details panel set the mesh to Floor_400x400 with its Location set to -180 (X), -180 (Y), -100 (Z).



We will use this Floor Mesh to shine our Lights on and to see the effects of Sequencer driving the parameter changes.

Add another Component of the Actor Sequence type.



In the Details panel for the Actor Sequence, set Loop Indefinitely, Random Start Time and Auto Play, then click Open in Tab.



After clicking Open in Tab, the Sequencer Editor will open within the Blueprint.



For this example we will automatically trigger and play the Sequence, however, you can also call this to play from the Event Graph.

In the Sequencer tab, click Add then under Component select SpotLight.



On the SpotLight track, click the Track button and select Transform.



Click the Track button again for the SpotLight track and add the Light Color track.



For the Transform track under Rotation, click the + icon for the Z value to add a key of 0 at frame 0.



Select the key that was added, then press the 4 key to change the interpolation type to Linear.



You can change the type of interpolation with the number keys or by right-clicking on the keyframe and selecting your interpolation method.

Add a key at 2.00 for the Z value of Rotation set to -180.0 and change the interpolation to Linear by pressing 4 on the key.



Add a key at 4.00 for the Z value of Rotation set to -360.0 and change the interpolation to Linear by pressing 4 on the key.



You can also move the red End Marker back to 4.00 so the Sequence ends where it began.

For the Light Color track, click the Add (+) button to add a key at frame 0.



Add a key at 1.00 for Red with a value of 0.0.



Add a key at 2.00 for Green with a value of 0.0.



Add keys at 3.00 for Blue with a value of 0.0, and both Red and Green at 1.0.



Add a key at 4.00 for Blue with a value of 1.0.



This will cause the light to go from white to various colors before returning back to white at the end of the Sequence.

In the Components window, select and Delete the StaticMesh floor.



Now that our light is set up, we no longer need this mesh as a way to preview the light in the viewport.

In the Main Level Editor Viewport, select the floor, then while holding Alt drag up a copy of the floor to create a roof encapsulating the level.



From the Content Browser, drag and place instances of the Light_BP in the level (you can also press E and rotate them if desired).



From the Build drop-down menu, select Build Lighting Only to rebuild the lighting in the level.



Click the Play button to play in the editor.

End Result

When you play in the level, you will see that the lights you placed start rotating and changing colors playing the embedded Sequence.

Since the Sequence is embedded within the Actor Blueprint, it has no dependencies and can play in any level or can be duplicated without any issues.

In our example we've set the Sequence to Auto Play, however, you can also use the Event Graph to script when the Sequence should Play.



Above, upon Event BeginPlay we have allowed the Actor to receive input from a Player Controller. When the P key is pressed, we take the Actor Sequence Component and get the Sequence Player which allows us to make a call to the function Play to start playing the Sequence. You can use any method you desire to make the call to the Play function if you prefer not to have the Sequence Auto Play upon level load.

Opening Take Recorder

Interface Overview

Toolbar

Slate

Sources

Details

Recording Example

Editor

Gameplay

Reviewing Subscenes and Assets

Record Timecode

Skeletal Mesh Timecode

Take Recorder enables the recording of gameplay animation, live performances, and other sources directly into Unreal Engine. By recording and managing takes into Sequencer, you can achieve a highly iterative workflow in your virtual production. This guide gives an overview of the Take Recorder feature, and demonstrates it's workflow.

Take Recorder is a Plugin that must be enabled prior to use. From Unreal Engine's main menu, go to Edit > Plugins, locate Take Recorder in the Virtual Production section, and click the checkbox to enable it. Then, restart Unreal Engine.



In order to record animation from motion capture and other live performances, you can optionally enable Live Link. From Unreal Engine's main menu, go to Edit > Plugins, locate Live Link in the Animation section, and click the checkbox to enable it. Then, restart Unreal Engine.



You should also have created a project with a playable character and Actors to record. Alternatively, you can use a project created using the Third Person Template template.

Opening Take Recorder

To start using Take Recorder, click Window > Cinematics > Take Recorder. This will open the Take Recorder window and open a new sequence, if one is not open already.



The new sequence will have its time display set to a timecode matching the Take Recorder's time display.

Interface Overview

There are four main sections of the Take Recorder user interface:



Toolbar: The Take Recorder toolbar contains several buttons and toggles which control Sequencer integration, takes browsing, and option displays.

Slate: The Slate section contains information on the pending take and timecode. You can specify the take name, take number, frames per second (fps), recording speed, and write a description. The Start Recording button is also located here and initiates the recording of the take.

Sources: The Sources section contains options to specify the sources to record into your sequence. Sources can be captured from any Actor in the Level as well as Live Link sessions, other sequences, a microphone, or World states.

Details: The Details section contains user and project settings for Take Recorder, as well as settings for your sources.

Toolbar

The Take Recorder toolbar contains buttons and toggles for controlling Sequencer integration, takes browsing, and option displays.

Name

Icon

Description

Clear Pending Take



Reverts the currently opened sequence to an empty pending sequence. Removes any sequences specified in the Record to Sequence button.

Review Last Recording



Opens the most recent sequence that was recorded. Does not become clickable until after a recording has been created.

Record to Sequence



Contains a dropdown menu from which you can specify another sequence to record your take into. Can be cleared by clicking the Clear Pending Take button.

Take Browser



Opens a Content Browser window for navigating to your saved takes. When using the columns view mode, take-related metadata information will be displayed.



Show / Hide Sequence



Shows or hides the Level Sequence that is used for setting up this take.

Settings



Shows or hides project and user settings in the Take Recorder's details area.

Return



Returns to the pending take sequence, when reviewing a previous take.

Slate Info Lock



Locks or unlocks the modifying of a slate, when reviewing a previous take.

Slate

The Slate area displays information on the current pending take, the current time, and recording functions. You can set custom names and numerical entries for your slate and take number by clicking the Slate or Take text fields and modifying the text. The same can be done by clicking the field in the slate body.

You can also start a new recording by clicking the red Record button. When the Take Recorder plugin is enabled, the record button will also be available in Sequencer's playback controls. Sequencer's record button allows you to start recording any selected Actor into the current sequence, and does not require the Take Recorder window to be open. Clicking the button again or pressing Esc will stop the recording and save the current take.



During a recording session, you can click the Add Marked Frame button to add custom marks to the current time of the recording.



Click the Frames Per Second (fps) menu for a dropdown list of different frame rates to select for your pending take.



You can also change the recording speed and overall time dilation of the engine by editing the Record Speed. This can be useful when recording to a populated sequence by making the animation play at a slower speed, ensuring you can observe and match the animation at a more comfortable pace.



Sources

The sources area is where you specify various recording sources. Sources are displayed in a list here and can be enabled or disabled from the recording.



To add a source, click Add Source (+) and choose from a list of sources. You can choose from any Actor in the Level, other sequences, a microphone, camera cuts, or World / Level information.



Source

Description

Any Actor

Selecting Any Actor as a source will create an Actor source with the following details.

Source Actor: The Actor being referenced in the Level.

Record Type: You can specify here to record the Actor as a Spawnable or Possessable.

Record Parent Hierarchy: Whether or not to also include the parent hierarchy if this Actor is attached to a parent. If this is disabled and you are recording to a posessable, then the resulting transforms will be in local space, since this Actor is still attached to the parent. If this is disabled and you are recording to a spawnable, then the resulting transforms will be in world space since the Actor will be a spawned copy and not attached to anything.

Reduce Keys: If enabled, this will execute a Simplify operation on all keyframes after recording finishes.

Recorded Properties: A list of default properties for this Actor and Components that can be enabled or disabled. Disabling a property will not include it as a track when recording finishes.

Include Animation Names: An array where you can specify Bone or Curve names to only include in the recording. For example, if you specify "root", then only the root bone will be recorded.

Exclude Animation Names: An array where you can specify Bone or Curve names to exclude from recording.



Camera Cuts

If Camera Cuts is added as a source, Take Recorder will record all active cameras during the session. Any time the active camera is changed, a new camera Actor and camera cut section will be created.

Level Sequence

Selecting a Level Sequence as a source will allow for other sequences to be played during your recording session. You can specify any number of sequences to play from the details area of this source. Playback of sequences only is supported during recording within gameplay or simulation sessions.

Level Visibility

The Level visibility source will record the visibility states of all Levels at the start of the recording. It does not record any changes during the recording session.

Live Link

Live Link will connect to any currently active Live Link sessions. The Live Link session must be specified in the Subject Name details field. You can shortcut to selecting a session directly by navigating to + Source > From Live Link.



Microphone Audio

Selecting Microphone Audio will allow your device's microphone to be recorded during the recording session. A sound file will be created upon completion containing your recorded audio. The details area contains settings for audio recording, track name, and the recording directory.



Nearby Spawned Actors

The Nearby Spawned Actors source will record all spawned Actors located within a specified radius from the player's location to the take. The details panel includes options for defining the range and specifying filters. If you are using filters, then only the filtered Actors will be added to the take. Only Actors that spawn during a gameplay session are added. Actors that have already spawned are not affected by this.



Player

Selecting the Player source records the Player Actor. Using this source might be useful if your player is dynamically spawned and does not exist as an Actor in the Level until gameplay starts.

World

If World is added as a source, everything in the Level will be recorded. Particles that are created using Spawn Emitter functions can only be captured when using this source.

Your source list can also be saved as a preset and can be reused later. To do this, click the Presets button and select Save As Preset. Any saved presets will be listed in the Presets menu.



You can remove all sources from the list or revert to your preset's selection by clicking the Revert button.



Details

The details area of Take Recorder contains project properties and settings for your sources as well as the Take Recorder. It can be enabled by clicking the Settings button in the toolbar. You can specify default settings for sources here which will propagate to the source. However, individual sources can still be customized from the project.



Other project related settings are:

Name

Description



Take Recorder



Root Take Save Dir

The root directory in which to save recorded takes. Supports any of the following format tokens that will be substituted when a take is recorded:

{year}: The year of the timestamp at the start of the recording.

{month}: The month of the timestamp at the start of the recording.

{day}: The day of the timestamp at the start of the recording.

{hour}: The hour of the timestamp at the start of the recording.

{minute}: The minute of the timestamp at the start of the recording.

{second}: The second of the timestamp at the start of the recording.

{take}: The Take number from the Slate section.

{slate}: The Slate name from the Slate section.

Take Save Dir

A sub-directory relative to the root to further organize saved takes.

Default Slate

The project's default name for slates when opening Take Recorder.

Recording Clock Source

The clock source to use when recording. You can select from the following options:

Tick, which uses the default world tick delta for timing. This mode responds to world and Actor pause states, but can be susceptible to accumulation errors.

Platform, which uses the platforms clock for timing. This mode does not respond to world and Actor pause states.

Audio, which uses the audio clock for timing. This mode does not respond to world and Actor pause states.

Relative Timecode, which uses the time relative to the Timecode provider for timing. This mode does not respond to world and Actor pause states.

Timecode, which uses the current Timecode provider for timing. This mode does not respond to world and Actor pause states.

Play Every Frame, which is a debugging mode where each frame is held for Sequencer.SecondsPerFrame many wall-clock seconds before advancing to the next frame. This mode does not respond to world and Actor pause states and time dilation. Audio will also not be synchronized.

Custom, which is a custom clock source created and defined externally.

Start at Current Timecode

If enabled, recording will begin at the current date's timecode depicted in your slate. Otherwise, the recording will begin at time 0.

Record Timecode

If enabled, this will write timecode metadata into every track section for every Actor. This information can be viewed by right-clicking a track section and navigating to Properties > Section > Section Range Start/End.

Record Sources Into Sub Sequences

If enabled, records each actor into their own subscene track, allowing for swapping of different takes per actor. If this property is disabled, all actors will record into a single sequence.

Record to Possessable

If enabled, records all Actors to possessable type tracks instead of spawnables. This can be overwritten per actor source.

Default Tracks

Specify Actor classes and their components so that those components will always be captured during a recording session.

Show Notifications

Shows or hides Take Recorder notifications while recording.





Movie Scene Take Settings



Movie Scene Take Settings

Specify your project's names for Hours, Minutes, Seconds, Frames, Sub Frames, and Slates. This will also affect the names of tracks created in the Takes Track for your Actors.



Animation Recorder



Animation Track Name

The name of the recorded animation track.

Animation Asset Name

The name of the saved Animation Sequence.

Animation Sub Directory

The name of the subdirectory that Animation Sequences will be saved to. If this is empty, then sequences will be saved in the Root Take Save Dir.

Remove Root Animation

If enabled, Skeletal Meshes will move based on a Transform track. If disabled, motion will occur on the root bone in the Animation Sequence.

Timecode Bone Method

Controls for recording Timecode on Skeletal Meshes.



World Recorder



Record World Settings

Whether to record the World Settings Actor in the Sequence (some projects use this to attach world sound effects).

Autotrack Actors

Adds bindings and tracks for all Actors that are not explicitly being recorded.



User Settings



Maximize Viewport

Enables Immersive Mode during a recording.

Countdown

The time in seconds the take recorder will count down to before starting the recording session after the Record button is pressed.

Engine Time Dilation

The amount of time dilation to apply to the recording session.

Stop at Playback End

The recording will stop upon reaching the end time of the sequence. On new sequences the end time defaults to 5 seconds.

Remove Redundant Tracks

By default, Take Recorder records all possible tracks from sources. When this option is enabled, only tracks with changes will be kept by the recording.

Reduce Keys Tolerance

Tolerance to use when reducing keyframes created during a recording. Higher numbers will cause more keyframes to be removed if they contain values differences within the tolerance.

Save Recorded Assets

Automatically saves recorded sequences and subscenes upon completing a recording. These assets will be lost if they are not saved.

Auto Lock

Locks the take to prevent editing after the recording session ends. The take can be unlocked by toggling the lock button in the Sequencer Toolbar

Auto Serialize

Stores capture data as it's recorded, as opposed to all at once at the end of the recording. This is an experimental feature and should be used at your own risk, as it has not been tested fully.

Preset Save Location

The directory in which to save source preset files to.

Recording Example

Take Recorder can be used to record from various sources in both editor and gameplay contexts. The examples below illustrate how you can record your actions in Take Recorder.

Editor

Take Recorder can be used to record your manipulation of Actors in the editor viewport.

First, you will need to add the object you want to record to the Sources list. Select the Actor in the viewport and click + Source > From Actor > Add ‘Sphere'.



Next, click Record. A countdown and notification will appear. When it reaches 0, the sequence will start to record. Select your Actor in the viewport and move it around to capture its editor motion. When finished, click Stop .



Click the Review Last Recording button to view the recording.



Click Play in Sequencer to observe your recorded editor movements on the Actor.



You may see a duplicate Actor performing the actions instead of the editor object. This is because the record type for the Actor was set to record as a Spawnable. You can change this on the source object or globally on the project by changing the Record to Possessable property in the Take Recorder details. If you record to a possessable, then you will only see the original Actor animate.

Gameplay

Take Recorder can also be used to record Gameplay actions such as the player's movement and animation in a Level.

From the Take Recorder, select Add Source (+) > Player to add the Player to the Sources list.



Next, click Play in the Unreal Engine toolbar to start a Play in Editor session.



Once the session has started, click Record. When the countdown reaches 0, the sequence will start to record. Move the character around your Level to capture its animation. When finished, click Stop or press Esc.



Click the Review Last Recording button to view the recording.



Click Play in Sequencer to preview your recorded player's animation.



Reviewing Subscenes and Assets

You can double-click the subscene section to open an Actor's sequence and view its recorded keyframes, such as transform and animation.



Clicking Take Browser will open a Content Browser from which you can navigate to your saved takes and subscenes.



Record Timecode

Take Recorder can also be used to record Timecode metadata. It provides controls for recording Timecode relative to the Scene, individual Actors, and Skeletal Mesh bones. Such a way of recording Timecode can be useful to allow for performances to be changed relative to other performances within the same take, while maintaining other Timecode values.

To record Timecode with Take Recorder, ensure that Record Timecode is enabled



For Cameras and non-Skeletal Mesh Actors, recorded Timecode information will be displayed under a Take Track in the Subsequence.



Skeletal Mesh Timecode

With Skeletal Meshes, Take Recorder provides a few options for where to record and save Timecode. The Bone Mode property, located under Animation Recorder > Timecode Bone Method, provides the following options:



Bone Mode

Description

All

Records Timecode metadata on every bone in the Skeleton as an Animation Attribute.

Root

Records Timecode metadata on the top-most bone in the Skeleton hierarchy. In most cases this will be the "root" bone.

User Defined

Records Timecode metadata on the bone specified in the Bone Name property.

After recording, you can view Skeletal Mesh Timecode data within the Animation Sequence timeline under the Attributes track.



Keyframes

Creation

Selection and Movement

Layer Bars

Key Bars

Interpolation

Properties

Sections

Creation

Interaction and Display

Show Curves

Data and Evaluation Range

Blending

Blend Types

Properties

Tracks and content in Sequencer are animated by creating Keyframes (also referred to as Keys) with defined properties at specific points along the timeline. When the playhead reaches a key in the timeline, the properties are updated to the values defined at those points. Properties can either gradually change (interpolate) between keyframes, or change immediately to the specified value upon reaching the keyframe (no interpolation).

Keyframes and track states reside within grouped containers, called Sections. Sections are time ranges in which the track is being evaluated by Sequencer. They can either have an infinite or finite length, and also can be moved, trimmed, or blended.

This guide provides an overview of animation keyframing in Sequencer, and how sections enhance the animation feature set.

You have an understanding of Sequencer and its Interface.

Keyframes

Similar to most animation software, objects are animated in Sequencer by creating keyframes within the timeline. Keyframes enable the animation of an object's position, color and other attributes. Most Actor properties can be animated in Sequencer, and therefore also be keyframed.



Creation

There are a variety of ways to create keyframes in Sequencer. In most cases when a keyframe is created, it will be created at the location of the Playhead. If the playhead is at the same location as an existing keyframe when placing a new keyframe, it will be overwritten with the new keyframe.

Keyframe Creation Method

Image

Clicking the Add Key button on a track.



Clicking the Add Key button next to a property in the selected Actor's Details panel.

The Actor or track does not need to be added to Sequencer for this to work. If it isn't added, it will automatically be added to Sequencer and keyframed.



Pressing Enter on your keyboard will place keys on the selected tracks.

If you have an Actor track selected, pressing Enter will create keyframes on all keyable child tracks.



Adjusting the property value displayed along the property track will add a new keyframe if the track already contains keyframes. You can either drag the property left and right to scrub its value, or click it and manually type a new value.



Clicking the middle mouse button along the track's timeline will create a keyframe at the playhead's position. The keyframe value will match the value at the playhead's position.



Pressing S with an Actor selected creates a Transform Track (if one does not already exist) and creates a keyframe with its current Location, Rotation and Scale properties.

This command also works if your window focus is on the viewport, mirroring Maya's keyframing hotkeys. It also will automatically add any Actor to Sequencer, if they currently are not being referenced inside your sequence.



Pressing Shift + W with an Actor selected creates a Transform track (if one does not already exist) and keyframes the Location property only.



Pressing Shift + E with an Actor selected creates a Transform track (if one does not already exist) and keyframes the Rotation property only.



Pressing Shift + R with an Actor selected creates a Transform track (if one does not already exist) and keyframes the Scale property only.



Keyframes can also be set up to create automatically whenever you change an Actor's properties, which is known as Auto Keying. To use Auto Key, you must enable the Auto Key button in the Sequencer Toolbar.

Once enabled, modifying Actor properties will cause new keyframes to be created.



The track you are auto keying must already have keyframes present in order to automatically create new keyframes. An empty track will not be auto keyed.

You can also open the Keyframe Options Menu to change the number of keyframes that are automatically created when channel keyframes are being auto keyed. Channel keyframes are property types made up of several properties, such as Vectors or Transform.



Auto Key Option

Description

Key All

All channels and groups will be keyframed when a value is changed. For example, in transform, if you only edit the X-Location property of an Actor, then keyframes will be set on the full XYZ Location channels as well as all channels in Scale and Rotation.

Key Group

All axes within a channel will be keyframed when a value is changed. For example, in transform, if you only edit just the X-Location property of an Actor, then keyframes will be set on the full XYZ Location channels.

Key Changed

Only the axis that changes will be keyed. For example, in transform, if you only edit the X-Location property of an Actor, then only the X-Location channel will be keyframed.

Keyframes can be created by duplication and copy / paste methods. You can duplicate a keyframe by right-clicking it and selecting Duplicate or by pressing Ctrl+D. Doing this will create a duplicate keyframe at the same location as the original.

You can also duplicate a keyframe by holding Alt and dragging a key, or group of selected keys along the timeline.



Keyframes can be copied and pasted using standard Cut / Copy / Paste commands. You can either right-click a keyframe and select one of these commands, or use the Ctrl + X, Ctrl + C, Ctrl + V hotkeys on a selected keyframe or group of keyframes. When keyframes are pasted, the left-most keyframe will paste at the same location as the playhead, and the keyframe group (if multiple keys were copied) will be placed relative to that location.



Selection and Movement

Keyframes are selected by clicking them individually or by dragging a marquee selection around a group of keyframes. Keyframes from other tracks can be included in your selection when using marquee selection, and are highlighted when included within the marquee selection box.



You can change the time of a keyframe by dragging it left and right. Multiple selected keys can also be moved relative to each other.



By default, the timeline Playhead will automatically snap to a selected keyframe, and will continuously snap to the keyframe while dragging it along the timeline. You can change this behavior by disabling both the Snap to the Pressed Key and Snap to the Dragged Key settings in the Snapping toolbar menu.

Use Ctrl + ] and Ctrl + [ to select all keyframes to the left or right of the playhead's location.



Layer Bars

To assist with movement and scaling of multiple keyframes at the same time, you can utilize Layer Bars to manipulate your keyframes. When multiple keyframes or sections exist on your Actor or Component, this bar will appear along the header track of the object which you can move and trim.



Dragging the center portion of the bar moves all child keyframes and sections in a grouped manner. Dragging the edges will scale the keyframes and sections relative to that edge.



Layer Bars are hierarchical and will appear on lower Component Tracks, and also Folder Tracks. Manipulating them at any of these points will appropriately manipulate keys, sections, and other Layer Bars of all Actors within. This makes it easier to manipulate keyframes on your Actors without needing to expand to the tracks to do so.



You can enable or disable this feature by navigating to the View Options menu in Sequencer and selecting Layer Bars.



Key Bars

If you want to retime neighboring pairs of keyframes, you can select and drag the line drawn between two keyframes. This will move both keyframes relative to each other. This method of manipulating keyframes can be useful to save time from multi-selecting each key individually, and preserving custom curves between these keys.



You can enable or disable this feature by navigating to the View Options menu in Sequencer and selecting Key Bars.



Interpolation

Keyframes can either Interpolate or not Interpolate. Keys that interpolate will gradually change the values of the property they are animating over time, while keyframes that don't interpolate will retain their value until the next keyframe is reached. An example of non-interpolating keyframes would be when keyframes created on an Event Track, Boolean Track, or Enum Track



Non-Interpolating Keyframes: These keyframes are displayed using a white diamond shape.

Interpolating Keyframes: These keyframes are displayed using a red circle, or other colored shape if using different tangents.

Keyframes that interpolate can have their tangents adjusted. Tangents are properties on the keyframe that control the speed and easing angle of the interpolation between keyframes. Depending on the tangent type chosen, the keyframe icon will display differently to denote its tangent property



There are five main types of tangents you can select:

Tangent Name

Keyframe Icon

Description

Cubic (Auto)



The Cubic (Auto) tangent type is the default tangent type. It attempts to maintain a smooth curve between keyframes and eases both the start and end keyframes. It will automatically adjust whenever keyframes are added or moved.

Cubic (User)



Cubic (User) is similar to Cubic (Auto), but it will lock the tangent from any further automatic edits when keyframes are added or moved. Cubic (Auto) keyframes will convert to Cubic (User) when manual tangent edits occur within the Curve Editor.

Cubic (Break)



Cubic (User) is similar to Cubic (Auto), but its tangents are broken, allowing for different incoming and outgoing angles to be specified from the Curve Editor.

Linear



Linear tangents cause keyframes to have no smoothing or easing between them, causing abrupt starts and stops when reaching each keyframe.

Constant



Constant tangents function similarly to non-interpolating keyframes by maintaining their current value until the next keyframe is reached.

You can convert an existing keyframe's tangent type by right-clicking it and selecting a tangent type from the Key Interpolation menu category.



Hotkeys can also be used to change a selected keyframe's tangent. Pressing 1, 2, 3, 4, or 5 on your keyboard will change the tangent to Cubic (Auto), Cubic (User), Cubic (Break), Linear, or Constant, respectively.

The default tangent for newly created keyframes can be changed by clicking the Keyframe Options button in the Sequencer toolbar and selecting a tangent type from the Default Key Interpolation menu category.



Properties

Right-clicking a keyframe and navigating to the Properties menu will display the keyframe's current Property Values and Time. Depending on the Property Track being animated, the Properties menu display will vary according to the property.



There are also keyframe-specific commands you can use to edit your keyframe time.

Name

Description

Set Key Time

Selecting this will cause a new window to appear from which you can specify a new time for the keyframe.



Rekey

Snaps the keyframe to the Playhead.



Snap to Frame

Snaps all selected keyframes to their nearest frame, as defined in the Frames Per Second toolbar menu.



Delete

Deletes the selected keyframe.

Sections

In the context of keyframes and keyframing actor properties, Sections are the groups that contain keyframes. They function similar to animation layers found in other animation tools, but with some differences. While layers usually do not consider time ranges for their keyframes, Sections do, which enable features such as offsetting whole chunks of keyframe data easily, without needing to select and move every keyframe individually. All keyframes reside within sections, either infinite or finite in length.



Additionally, while keyframes occupy only single frames within the timeline, sections occupy a range of time. As such, any animatable track that produces its content from ranges of time is using Sections. This includes tracks such as the Animation Track, Subsequence Track, or Audio Track.



Creation

A section with infinite length is created automatically whenever a keyframable track is created. You can more clearly see this section by right-clicking an empty space of the section, navigating to the Properties menu and unlocking the Section Range Start and Section Range End properties. This will convert the section to a finite length, in order to view and manipulate it.



Additional sections can be added by clicking the Section (+) button on the track. You can choose which Blend Type to use for this new section. Additional sections created after the initial one will be created with finite range.



Interaction and Display

Finite sections can be moved and resized by dragging them or their edges. You can move them between tracks as well by dragging them up and down in the timeline.



Use Alt + ] and Alt +[ to trim or loop sections to the current playhead time. If you select the main header track beforehand, then all child sections will trim or loop to the playhead.



You can also time scale sections, which will scale the keyframes proportionally to the scale amount. Hold Ctrl and drag the edge of a section to timescale a section. Time scaling is denoted by a clock icon beside your cursor when holding Ctrl and hovering over the left or right edge of a section.



When multiple sections exist on a property, only one of them can receive keyframes (when keyframing by pressing S or Enter). This section is displayed with a green outline around its border to denote that it is the section designated to receive new keyframes. Typically, the most recently created section will be the one receiving keyframes.



You can change which section will receive keyframes by right-clicking a section and selecting Key This Section.



Custom colors can be applied to sections if you want to differentiate them from their default color scheme. To change the color of a section, select the vertical color bar on the track header edge. This will open the Color Picker where you can select a different color. Click OK to apply the new color to the section.



Show Curves

To assist with visualizing your animation data, you can also enable your curves to be displayed in-line on the section. To do this, right-click on a section and select Curve Channels > Display, then enable Show Curve.



You can modify the curve display using the following options in the Display menu:

Name

Description

Show Curve

Enables or disables showing curves in this section.

Key Area Curve Normalized

If enabled, this adjusts the curves range to display normalized, relative to the height of the track defined by Key Area Height. If disabled, curves will show in absolute terms.

Key Area Curve Range

The range of the curve if Key Area Curve Normalized is disabled.

Key Area Height

The height of the track if Show Curve is enabled. You must restart Sequencer for this to update.

Data and Evaluation Range

Even without keyframes, Sequencer sections provide a static evaluation of an Actor's properties. This can be useful if you want to set properties on Actors and have Sequencer store them, without needing to set keyframes. This can be done by ensuring your playhead is on the section range for that property (if it is finite), then change the property. You should see the property change between its default level value and the sequencer section when playing or scrubbing over the section boundaries.



You can also blend sections by dragging the top corner edge of a section, which enables the ability to blend any property from its current value to that section's value.



Blending

You can adjust the start and end blend curves of a section by selecting and moving the blend curve handle located on the upper portion of a section's edge. A curve symbol will appear above the cursor to aid your selection accuracy.



Right-clicking a blend curve will reveal the additional context menu commands.



Name

Description

Easing Length

The length of the blend curve. Enabling Auto will cause the blend curve to return to the default behavior and support automatic length calculation when sections are intersecting.



Method

Method controls the type of curves to apply to the blend, and enables custom external blends based on functions.

Options

The Options menu will display a list of curve shapes that you can apply to your blend curve. Selecting one of these will replace your current curve shape with the selected curve.



Sections can also blend between other sections by dragging them on top of each other. Doing this will blend the resulting keyframe values for the duration of the overlapping region.



Sections that overlap show keyframes from only a single section. You can adjust which section's keys are showing by using the Order context menu commands to re-order section displays forward or backward.



Blend Types

When creating sections or viewing the Blend Type menu, there are different blending modes to apply to your sections. These modes affect how your sections interact with each other, or the value that results from animating a property.



The following blend types can be chosen:

Name

Description

Absolute

Sets the property to the absolute value defined by the section or keyframe. If multiple absolute sections are set up to animate the same value, then the value will blend equally between them.

Additive

Adds the amount defined by the section or keyframe to the current properties. These values stack additively with other sections.

Relative

Applies this value as a sum total of all other additives and the initial value before animation.

Additive from Base

The first keyframe of this section will be equal to the current value of the property it is animating at that time. Subsequent keyframes will animate the property relative to that initial point.

When hovering your cursor over a section with a blend type other than Absolute, it will display the blend type name on the section bar.



Properties

Right-clicking a section and navigating to the Properties menu will show the section properties.



Name

Description

Section Range Start

The start time of the section. If this region is Locked, then the start time is infinite, and no value is shown.

Section Range End

The end time of the section. If this region is Locked, then the end time is infinite, and no value is shown.

When Finished

Determines what the property should do when the section finishes.

Keep State will keep the property in the last animated value, and it will not snap back to its previous value.

Restore State will return the property back to its state before the section animated it.

Project Default is the default behavior, and will use the settings defined in your DefaultEngine.ini project file. Adding the following lines to the .ini file will set the project default. By default, it is set to Restore State.

[/Script/LevelSequence.LevelSequence]

DefaultCompletionMode=KeepState

Timecode Source

The timecode information for the section, if timecode is being used. You can also specify delta frames here to control offset information.

Is Active

Activates the selected section. This is similar to Muting Tracks, but is used for sections instead of tracks.

Is Locked

Locks the selected section. This is similar to Locking Tracks, but for sections instead of tracks.

Right-clicking a section and navigating to the Sections category reveals section-specific properties and commands.



Name

Description

Pre/Post-Infinity

If the section contains keyframes, this menu will display options for selecting what the animation should be doing before the first keyframe (Pre-Infinity), or after the last keyframe (Post-Infinity). These settings affect the animation for the entirety of the section.

Cycle will repeat the keyframe animation.

Cycle with Offset will repeat the keyframe animation, but will make each repeating starting keyframe be relative to the starting or ending keyframe value.

Oscillate will repeat the keyframe animation by mirroring the animation backward and forward with each loop.

Linear will cause the initial or final keyframe to determine a continuous motion. This may require setting the keyframe tangent type to Linear, or setting a custom tangent angle in the Curve Editor.

Constant is the default behavior and causes the section to maintain the initial or final keyframe value.

Order

When sections with keyframes overlap, keyframes from only one section will display on the timeline. The Order menu contains the following controls for sorting which sections are in front or behind.

Blend Type

Sets the Blend Type for the selected section.

Active

Activates the selected section. This is similar to Muting Tracks, but is used for sections instead of tracks.

Locked

Locks the selected section. This is similar to Locking Tracks, but for sections instead of tracks.

Group

Links two or more sections together so that when one of the sections moves, they all move together.



Ungroup

Ungroups the selected section.

Delete

Deletes the selected section.

Key This Section

Specifies this section to receive keyframes when keyframing.

Trim Section Left/Right

Trims the selected section's start or end time to the playhead position. You can also use the Ctrl + , and Ctrl + . hotkeys. This command only trims sections and does not add section time like the Alt + ] and [ commands.

Split Section

Divides the selected section into two parts at the playhead position. If the section contains keyframes, then bracketing keyframes will be created at the split point in order to maintain continuous animation up to the split. You can also use the Ctrl + / hotkey.



Delete Keys

Deletes keyframes when they fall outside the section range when using the Trim Section Left/Right commands.

Auto Size

Sets the section's start and end times to match to the starting and ending keyframes. This command is not clickable if the section range is infinite, or if there are no keyframes in the section.

Synchronize using Source Timecode

Synchronizes multiple selected sections using the source timecode. The first selected section will be used as the source timecode, and subsequent selected sections will be adjusted according to their source timecode as relative to the first section.

Key Interpolation

Sets all keyframes in this section to use a specific Tangent Type.

Reduce Keys

Automatically reduces keyframes in the selected section based on the Tolerance value.

Tolerance

Sets how aggressive the automatic removal of keyframes should be when reducing keyframes. Higher values will cause more keyframes to be removed.

Sequencer Overview

Editor Preferences

Project Settings

Engine

Editor

Plugins

Saving and Resetting

Sequencer's Editor Preferences and Project Settings control Sequencer's project-wide default behaviors and local user preferences during editor usage and runtime. This document provides an overview of the options available to you for modifying Sequencer behavior at the local and project level.

Editor Preferences

Editor Preferences are used to configure Sequencer's tool and feature behavior at the local level. Changes here only apply to your machine only and not with others.

To view Sequencer's Editor Preferences, navigate to Edit > Editor Preferences… in Unreal Engine's top menu bar. Next, select Level Sequence Editor in the sidebar in the Content Editors category.



In addition to the Level Sequence Editor, you can also customize your preferences for other sequence editors. Under Content Editors, you can locate and modify preferences for:

Embedded Actor Sequence Editor, when using the Actor Sequence Component.

Niagara Sequence Editor, when using Sequencer in Niagara.

Take Recorder Sequence Editor, when using Sequencer from Take Recorder.

Template Sequence Editor, when using Template Sequences.

UMG Sequence Editor, when using Sequencer with the UMG UI Designer.



Name

Description



Keyframing



Auto Change Mode

Auto Change Mode describes the behavior when creating tracks or when keyframed changes occur to your Actor.

Auto Key will enable Auto Key mode.

Auto Track will add tracks and Actors whenever an Actor or its properties are changed.

All will combine the effects of Auto Key and Auto Track modes.

None will use the default behavior and no automatic changes or keying will occur.

Allow Edits Mode

Allow Edits Mode contains options for automatic behavior when manipulating Sequencer-bound and Level-bound Actors. These options are described in the Sequencer Toolbar page.

Key Group Mode

Key Group Mode controls the scope of keys set when using Auto Key. These options are described in the Sequencer Toolbar page.

Key Interpolation

The interpolation type for newly-created keyframes.

Auto Set Track Defaults

When enabled, this will allow Transform and Property Tracks to have custom default values without needing to set keyframes. When disabled, then setting any value will cause a keyframe to be created for that track at the chosen value.



General



Spawn Position

The default location to create a Spawnable when it is added to Sequencer.

Origin is the default behavior and will place the Spawnable at the world origin (0, 0, 0).

Place in Front of Camera will place the Spawnable in front of the currently active perspective viewport's camera.

Create Spawnable Cameras

When enabled, clicking Sequencer's Toolbar Camera Button will create the camera as a Spawnable.

Show Selected Nodes Only

Automatically filters tracks when enabled to list only tracks or sub-tracks that match the selected Actor.

Rewind on Record

When enabled, the sequence will jump back to the start when a recording has started. Only used with Sequence Recorder.

Left Mouse Drag Does Marquee

Enabling this changes the Left Mouse dragging behavior in the level viewport so that it performs a box (marquee) selection, instead of moving the viewport camera laterally.

Clean Playback Mode

Automatically enables Game View whenever Sequencer is being played.

Activate Realtime Viewports

Automatically enables Realtime from the Viewport Options menu whenever Sequencer is open.

Show Debug Visualization

If enabled, a debug display will appear at the bottom of Sequencer. The debug sections are grouped by keyframes. These sections are assigned a color based on evaluation complexity. Blue is low complexity, whereas Red is high complexity.



Visualize Pre and Post Roll

Enables the drawing of pre and post-roll frame visualizers on your tracks if you are using them.



Compile Director on Evaluate

When enabled, the Sequencer Director blueprint will automatically compile when playing or scrubbing if it is dirty from changes.

Trajectory Path Cap

Specifies the maximum number of keyframe segments to draw when rendering transform trajectories in the viewport.

Frame Number Display Format

Specifies the unit of time to display in your sequence to Frames, Seconds, or Timecode. This affects all time displays in your sequence.



Movie Renderer Name

Describes which renderer to use. By default, this is set to "MovieSceneCapture", which uses the legacy rendering tool. If Movie Render Queue is enabled, then this field will be set to "Movie Render Queue".

Auto Expand Nodes on Selection

Enabling this automatically expands the Sequencer Outliner to the selected track.

Tree View Width

The default width of the Sequencer Outliner in normalized percent relative to the full width of the Sequencer Editor.





Timeline



Show Range Slider

Toggles the display of the bottom timeline region between a Maya-style range slider and a second timeline bar.



Snap Keys and Sections to Play Range

Clamps key and section placement to within the playback range.



Zoom Position

What the focal point is when Zooming in the Sequencer UI. You can choose to either zoom relative to the Current Time playhead or to your Mouse Position.

Auto Scroll Enabled

Enables automatic panning in Timeline view to keep the playhead in view when playing.



Keep Playhead in Play Range While Scrubbing

Clamps the playhead within the start and end regions of the sequence when scrubbing.



Keep Play Range in Section Bounds

Enabling this will cause the playback range of your sequence to clamp its start and end times to the first and last keyframe or section.



Zero Pad Frames

Applies the selected amount of digit padding to the displayed time. Only applies when you are displaying time as frames.

Jump Frame Increment

Sets the number of frames to jump when pressing Shift + Left / Right Arrows to jump forward and backward in the timeline.

Show Layer Bars

Enables Layer Bars.

Show Key Bars

Enables Key Bars.

Infinite Key Areas

If enabled, the first transform track created will include an infinite length section. If disabled, a non-infinite section will be created instead with a length of 0.

Show Channel Colors

If Show Key Bars is enabled, this draws red, green, and blue lines on transform Key Bars.



Show Status Bar

Shows the status indicator in the Sequencer Outliner.



Show Tick Lines

Enables or disables vertical lines in the Timeline.



Show Sequencer Toolbar

Shows or hides the Sequencer Toolbar.

Key Area Curve Extents

The key area curve extents, stored by channel name.

Key Area Height with Curves

The height of the track when Show Curve is enabled. You must restart Sequencer for this to update.

Reduce Keys Tolerance

Tolerance to use when reducing keyframes from the Edit > Reduce Keys menu. Higher numbers will cause more keyframes to be removed if they contain a value difference larger than the tolerance's value.

Delete Keys when Trimming

Deletes keyframes that fall outside a section when trimming from the Edit > Trim Left/Right menu.

Disable Sections After Baking

Enabling this will deactivate the previous transform sections when selecting Bake Transform from Sequencer's Actions Menu. Disabling it will instead delete any previous sections.



Snapping



Is Snap Enabled

Enables Snapping.

Snap Key Times to Interval

Snaps keyframes to time intervals when moving along the timeline.



Snap Key Times to Keys

Snaps keyframes to other keys, or the start and end of sections when moving along the timeline.



Snap Section Times to Interval

Snaps sections to time intervals when scaling or moving sections in the timeline.



Snap Section Times to Sections

Snaps sections to other keys, or the start and end of sections when moving along the timeline.



Snap Playhead to Keys

Snaps the playhead marker to other keys, or the start and end of sections while scrubbing.



Snap Playhead to Interval

Snaps the playhead marker to time intervals while scrubbing.



Snap Playhead to Pressed Key

Pops the playhead marker to a keyframe when clicked. This can also be done when holding Shift and clicking the keyframe if this option is disabled.



Snap Playhead to Dragged Key

Keeps the playhead maker at the same time as the keyframe when dragging the keyframe along the timeline.



Snap Curve Value to Interval

Toggles value snapping in the Curve Editor.





Curve Editor



Link Curve Editor Time Range

Synchronizes the Curve Editor's view with Sequencer's timeline.



Synchronize Curve Editor Selection

Enabling this synchronizes the Curve Editor selection with the selected track in Sequencer.

Isolate Curve Editor to Selection

Enabling this will remove all other tracks from the Curve Editor outliner and will only show the currently selected track and its hierarchy from Sequencer.



Playback



Evaluate Sub Sequences in Isolation

Isolates a sub-sequence or a shot from the master sequence when viewing it. This will disable any tracks or content that have been propagated from the master sequence, and will also disable the shot range preview.

Rerun Construction Scripts

Enables the construction script from Blueprint Actors to run on every tick. The Run Construction Script in Sequencer property must also be enabled in the Blueprint's Class Settings in order to use this option.

Project Settings

Sequencer also has various Project Settings that affect Sequencer across the entire project. Changes here will affect all users and will require certain files be changed.

To view Sequencer's Project Settings, navigate to Edit > Project Settings… in Unreal Engine's top menu bar.



There are three main categories that contain Sequencer project settings: Engine, Editor, and Plugins.

Engine

In the sidebar, navigate to the Engine category and select Level Sequence. This will reveal Sequencer project settings for the DefaultEngine.ini file, which is located in the Config folder in your project's root directory.



Name

Description

Default Lock Engine to Display Rate

Locks the playback of all newly-created sequences to the specified Default Display Rate.

Default Display Rate

The default playback rate for newly-created sequences. This can also be used to define the frame locked frame rate. Some of the valid formats include:

30fps.

120/1, which will result in 120 fps.

30000/1001, which will result in 29.97 fps.

0.01s, which will result in 10 ms.

Default Tick Resolution

Specifies the tick resolution for newly-created sequences.

Default Clock Source

The default Clock Source to use for newly-created sequences.

Editor

Navigate to the Engine category, and select Level Sequences. This will reveal Sequencer's engine project settings. Changes here will create a new file for your project named DefaultEditorPerProjectUserSettings.ini. It will be located in the Config folder in your project's root directory.



Name

Description

Default Start Time

The default start time value for newly-created sequences.

Default Duration

The default duration for newly-created sequences.

Shot Directory

The default folder name when creating shots from the Shot Track. The folder will be relative to the master sequence asset's location.

Shot Prefix

The filename prefix when creating shots.

First Shot Number

The shot number to add to the filename after the Shot Prefix.

Shot Increment

The amount by which to increment the shot number when creating new shots.

Shot Num Digits

The amount of digit padding to use in the shot number field.

Take Num Digits

The amount of digit padding to use in the take number field.

First Take Number

The shot number to add to the end of the filename when creating takes.

Take Separator

The single-character separator between the shot number and the take number.

Sub Sequence Separator

The single-character separator between the take number and the subsequence name.

Fbx Settings

This array lists FBX property readers used to map properties and their keyframes to relevant tracks when Importing FBX's in Sequencer. By default this array includes property mappings for common FBX camera properties such as FieldOfView, FocalLength, and FocusDistance.



Plugins

Navigate to the Plugins category, and select Level Sequencer. This will reveal Sequencer's plugin project settings. Changes here will create a new file for your project called DefaultEditorPerProjectUserSettings.ini and it will be located in the Config folder in your project's root directory.



Name

Description

Track Settings

Track Settings is an array used to specify property or component tracks to be automatically created when binding certain Actor Classes to Sequencer. Refer to the Object Binding Track page for more information.

Auto Bind to PIE

Specifies whether or not newly-created sequences automatically bind to Play In Editor sessions.

Auto Bind to Simulate

Specifies whether or not newly-created sequences automatically bind to Simulate sessions.

Saving and Resetting

With all Editor Preferences and some Project Settings, you can Save, Export, Import, or Reset them by using the menu beneath the top header.

Set as Default saves your current settings as your new default settings. Afterwards, when clicking Reset to Defaults, your settings will be reset to these values.

Export saves the current settings as a .ini file. You can then use this file to share your settings with others.

Import imports settings from a specified .ini file.

Reset to Defaults will set all settings and preferences to the default defined by the project or your Set as Default settings.



Render Movie Option

Capture Settings

Audio Output Format

Video Settings

Composition Graph Options

Including Render Passes

Image Settings

General Settings

Filename Format Tokens

Sequence Settings

Cinematic Settings

Animation Settings

Sequencer gives you the option to render out your cinematic in either video or image format. You can render out your scene to an AVI video format to share with others, or render out images in BMP, EXR, JPG, or PNG file formats. You can also perform Custom Render Passes to render out things like Base Color, Scene Depth, Subsurface Color and more.

When rendering out your cinematic, there are several Render Movie Settings that you can use to define how your content is rendered. This page covers how to access the Render Movie Settings and the options that are available to you during the process.

Render Movie Option

To access the Render Movie Settings and render out your cinematic, first click the Render Movie option within a Sequence.



This will open the Render Movie Settings window where you can define how your cinematic is rendered.



Clicking the Capture Movie button will start the render process with your desired Image Output Format.



You will see the Capturing status message in the lower-right corner of the Editor, and a Movie Render - Preview that will scrub through your content as it renders. When the render is complete, you will see the Capture Finished status message in the lower-right corner of the Editor. Click the Open Capture Folder option in the status message to open the file location that you define as the save location for your renders.

For a step-by-step example of rendering out a movie, see Rendering Out Cinematic Movies.

Capture Settings

The Capture Settings section is where you define the Image and Audio Output Formats, Frame Rate, Resolution, and whether to apply Burn Ins.



Property

Description

Image Output Format

The type of capture protocol to use for the image data.

Audio Output Format

The type of capture protocol to use for audio data.

Frame Rate

The frame rate to perform the capture at.

Resolution

The resolution to perform the capture at.

Use Burn In

Whether to apply Burn In content to the capture (for example, scene data, time code, and take number).

Enable Texture Streaming

Whether Texture Streaming should be enabled while capturing.

Turning off Texture Streaming may cause much more memory to be used, but also reduces the chance of blurry textures in your captured video.

Audio Output Format

Exporting audio as part of the render process is currently experimental as it relies on the experimental Audio Mixer feature.

The Audio Output Format uses an experimental audio capture implementation which captures the final output from the Master Submix. This requires the new Audio Mixer (launched with the command line argument -audiomixer) and requires that your Sequence can be played back in real-time (when rendering is disabled). If the Sequence evaluation hitches, the audio will become desynchronized due to more time passing in real-time (platform time) than in the Sequence itself.

When electing to render out a cinematic with the experimental audio bake down feature, a separate pass will be performed to specifically capture the audio. No video will appear in the preview window while the audio is being captured.

Video Settings

The following Video Settings are available when choosing to render out a Video Sequence.



Property

Description

Use Compression

Whether to render out an uncompressed video or apply compression to reduce file size.

Compression Quality

Level of Compression to apply between 1 (worst quality, best compression) and 100 (best quality, worst compression).

Video Codec

Enables you to specify a specific video codec to use when rendering out your cinematic.

Composition Graph Options

The following options are available when performing Custom Render Passes as the Image Output Format.



Property

Description

Include Render Passes

A list of render passes to include in the capture. Leave this field empty to export all available passes.

Capture Frames in HDR

Whether to capture the frames as HDR textures (*.exr format).

HDRCompression Quality

Compression Quality for HDR Frames (0 for no compression, 1 for default compression which can be slow) when Capture Frames in HDR is enabled.

Capture Gamut

The color gamut to use when storing HDR captured data and Capture Frames in HDR is enabled.

The gamut depends on whether HDRCompression Quality is enabled.

Post Processing Material

Whether to use a custom Post Processing Material for rendering.

Disable Screen Percentage

Whether to disable Screen Percentage during rendering.

Including Render Passes

When rendering out Custom Render Passes, you can render out all available passes or choose which passes you want to render.



You can add multiple passes as part of the render, each of which will be displayed in the menu.



Click the minus sign to remove any Passes you previously added.

Image Settings

When rendering out an Image Sequence as the Image Output Format, Image Settings may be available.

Image Sequence (EXR)



Property

Description

Compressed

Whether to write out compressed or uncompressed EXRs.

Capture Gamut

The color gamut to use when storing HDR captured data.

Image Sequence (JPG or PNG)



Property

Description

Compression Quality

Level of Compression to apply to the image, between 1 (worst quality, best compression) and 100 (best quality, worst compression).

General Settings

The following options are available under the General section regardless of the type of rendered output.



Property

Description

Output Directory

The directory to output the captured file(s) in.

Filename Format

The format to use for the resulting filename. Extensions will be added automatically. Any tokens of the form {token} will be replaced with the corresponding value.

Game Mode Override

Optional Game Mode to override the map's default game mode with. This is useful if the game's normal mode displays UI elements or loading screens that you don't want captured.

Overwrite Existing

Whether to overwrite existing files.

Use Relative Frame Numbers

If frame numbers in the output files should be relative to zero, rather than the actual frame numbers in the originating animation content.

Zero Pad Frame Numbers

How much to zero-pad frame numbers on filenames (4 results in 0000 followed by the file name).

Use Separate Process

Whether to capture the movie in a separate process where a standalone version of the Editor will open to process capturing.

Close Editor when Capture Starts

When enabled, the Editor will shutdown when the capture starts.

Use Separate Process must be enabled for this option.

Additional Command Line Arguments

Additional command line arguments to pass to the external process when capturing.

Use Separate Process must be enabled for this option.

Inherited Command Line Arguments

The command line arguments that are inherited from this process.

Use Separate Process must be enabled for this option.

Filename Format Tokens

The following Tokens can be added to the Filename Format option to process your file's naming convention:

Token

Description

{fps}

The captured frame rate.

{frame}

The current frame number (only relevant for image sequences).

{width}

The width of the captured frames.

{height}

The height of the captured frames.

{world}

The name of the current world.

{quality}

The image compression quality setting.

{material}

The material/render pass.

{shot}

The name of the Level Sequence Asset Shot being played.

{camera}

The name of the current Camera.

Sequence Settings

The Sequence section provides the following options as part of the render process.



Property

Description

Write Edit Decision List

Whether to write Edit Decision Lists (EDLs) if the Sequence contains Shots.

See the Importing & Exporting Edit Decision Lists page for more information.

Write Final Cut Pro XML

Whether to write Final Cut Pro XML files (XMLs) if the Sequence contains Shots.

Handle Frames

The number of Frame Handles to include for each Shot. These extra frames pad each Shot and are cut into and out of by the EDL (or XML) files, which can be used in your external video editing package to adjust the cuts between Shots.

Cinematic Settings

The following settings can be used to define how your cinematic plays during capture.



Property

Description

Cinematic Engine Scalability

Whether to enable the Cinematic Engine Scalability Settings.

Cinematic Mode

Whether to enable Cinematic Mode while capturing.

Allow Movement

Whether to allow Player movement while capturing.

Requires Cinematic Mode to be enabled.

Allow Turning

Whether to allow Player rotation while capturing.

Requires Cinematic Mode to be enabled.

Show Player

Whether to show the local Player while capturing.

Requires Cinematic Mode to be enabled.

Show HUD

Whether to show the in-game HUD while capturing. This setting does not apply to UMG based HUD elements and refers to the HUD class based Blueprints.

Requires Cinematic Mode to be enabled.

Animation Settings

The following options define the Animation settings used during capture:



Property

Description

Use Custom Start Frame

When enabled, the Start Frame setting will override the default starting Frame Number.

Start Frame

Time field which takes timecode, frame and seconds formats.

This value is used when Use Custom Start Frame is enabled.

Use Custom End Frame

When enabled, the End Frame setting will override the default ending Frame Number.

End Frame

Time field which takes timecode, frame and seconds formats.

This value is used when Use Custom End Frame is enabled.

Warm Up Frame Count

The number of extra frames to play before the Sequence's Start Frame, to "warm up" the animation. This is useful if your animation contains particles or other run-time effects that are spawned into the scene earlier than your capture Start Frame.

Delay Before Warm Up

The number of seconds to wait (in real-time) before we start playing back the warm up frames.

This is useful for enabling Post Processing effects to settle down before capturing the animation.

Delay Before Shot Warm Up

The number of seconds to wait (in real-time) at Shot boundaries.

This is useful for enabling Post Processing effects to settle down before capturing the animation.

Sequencer Overview

Example Workflow

Exporting from Sequencer

External Editing

Importing to Sequencer

This page describes how you can export a scene from Sequencer as an FBX file and make alterations to that file inside a third-party application like 3ds Max or Maya. Once satisfied with your changes, you can then import the FBX file back into your Sequencer scene in Unreal Engine 4 (UE4) along with your updated changes.

There are some caveats to this process that you should keep in mind:

When exporting, you can export all the objects with animations in your scene to your FBX file.

Importing FBX files will only import animation. It will not create new objects.

Export/Import does not work with Master Sequences, Shots within a Master, or Subscenes.

Make sure that the time settings in your third-party application matches the time frame used for your scene in Unreal Engine.

As long as you export from a source Level Sequence and not a shot that sits inside a Master, and are only altering the animation of existing assets, you will be able to import your changes directly back into your scene inside UE4. Also, using the same time frames in both UE4 and your third-party application will ensure that they line up, and that the imported scene is not resampled at a different time rate.

Example Workflow

Below, we export a scene from the Sequencer Subway Project (pictured below) available for free from the Learn tab of the Launcher. We then take it into Maya and alter the camera movement in the scene, then import that FBX along with our changes back into UE4 where our existing scene is automatically updated with our changes.



Exporting from Sequencer

First, determine which Level Sequence to export.

In the clip below, we pick the shot we want to alter and open it up. We then go into the General Options and choose Export. We have a Master Track that includes shot0040_001 so we open that particular Level Sequence to export it.

Upon performing the FBX Export process, you will be shown the FBX Export Options window where you can define how to export your content.



Use these options to choose the FBX Export Compatibility version as well as the option to export the Skeletal Mesh's Vertex Color, Level of Detail or Collision settings.

There is also the option to Map Skeletal Motion to Root which will (if enabled) map the Skeletal Actor motion to the root bone of the Skeleton. For this example, we use the default settings and choose Export to export our content.

When exporting an object in a Shot or Subsequence, you can determine if you want to export the Shot by Master Sequence time or Local Sequence time. Master Sequence time is useful when you are looking at the animation holistically and in comparison to other shots. Local Sequence time is useful when you are working shot by shot. Exporting to either time maps to the shot keys in Maya, and in Sequencer you can move from Local to Master time easily.

The default setting is to Export Local Time (checked). To export by Master Time, uncheck the box.



External Editing

Once we have an exported FBX from Sequencer, we open our third-party application to import it so we can start editing.

Before we import our FBX into Maya, we set our working units for Time to match our Time Rate used in Unreal Engine.

We then import our FBX into Maya and set up our scene so that we can begin making edits. After importing:

Set the Perspective under Panel to use the camera shotCamA in our scene.

Hide any elements obstructing the view (such as the god ray mesh) by pressing Ctrl + H with it selected.

Then, under View we Select Camera to display the properties and keyframes for shotCamA, which we can then begin to edit.

Next, we make edits to the movement of our camera. Below, we select the Translation and Rotation properties of our shotCamA. Then, right-click and select Break Connections. We then pick a new starting point for the camera to be in, to start our scene, pressing the S key to keyframe the new position. We scrub ahead slightly and move the camera to the ending position. Press the S key again to keyframe the end position so that our camera moves along a new path.

With our changes in place, we then export our scene using Export Selection from the File menu. During the export process from Maya, we first change the export type to FBX export. Then, under Advanced Options and Axis Conversion, we change the Up Axis to follow the Z-axis to allow for a compatible import into Unreal Engine. Future versions of the engine may address this so that you do not have to convert the axis, but you will need to do this for now to avoid any importing problems.

Importing to Sequencer

Now that we have an edited version in FBX format we can import it and the changes into Unreal Engine, updating our scene.

Inside our shot0040_001 that we wanted to edit, we right-click on our shotCamA and select Import. This will take the transform data inside the FBX and apply it to the selected object in Unreal Engine. This can be useful if you want to apply the same transform data to multiple objects inside your scene.1.

Upon importing our FBX we are presented with the Import FBX window.



This (if enabled) allows you to Force Front XAxis which will convert the scene from the FBX coordinate system to UE4 coordinate system with front X axis instead of -Y. If cameras do not already exist in the Level, go ahead and enable the Create Cameras option.

You can also import the FBX from the General Options window instead of using the right-click method.



When choosing this method, Unreal Engine will try to match the names of your objects. For example, we have shotCamA in both our FBX file and our Sequence so it will apply the data from the FBX file to that object inside Unreal Engine.

In our example, we only applied Transform changes to our camera. However, we could have keyframed new values for our Focal Length to produce a different looking shot as well.

Template Sequence Asset

Interface

Camera Animation Sequence

Usage

Binding Actors

Content Setup

Apply Template Sequence Animation

Property Multipliers

Blueprint Usage

Content Setup

Template Sequences enable the reuse of animation data created in Sequencer for Actors of a compatible class (same or inherited). Similar to how animation sequences can be played on any compatible Skeletal Mesh, Template Sequence animation can be played on any compatible Actor.

You have an understanding of Sequencer and its Interface.

You have an understanding of Blueprints Visual Scripting.

Template Sequence Asset

To start using Template Sequences, you must first create a Template Sequence asset. Do this by right-clicking the Content Browser and selecting Animation > Template Sequence.



Next, select the root object class binding for the sequence.



Once created, double-click the asset to open the Template Sequence window. You should see your root object class added to the sequence as a Spawnable.



Interface

The Template Sequence interface looks similar to Sequencer's interface, with the exception of certain unneeded items omitted from the toolbar.

A new Bind Actor Class button is added to the toolbar, which allows for rebinding the root Actor class.



Camera Animation Sequence

Template Sequences are commonly used for creating template camera animation. You can easily create a Template Sequence with a default binding to a camera by right-clicking the Content Browser and selecting Animation > Camera Animation Sequence.

Upon opening this Template Sequence, you will see a Cine Camera Actor added to the sequence. The Bind Actor Class button's behaviour has also changed to swap between the Cine Camera Actor and the Legacy Camera Actor



Usage

This section describes how to bind and rebind Actors to Template Sequences and assign your animations to other Actors of the same class.

Binding Actors

Template Sequences require you bind your Actors as Spawnables in order to animate. Therefore, you can bind or rebind Actors to your Template Sequence by dragging them from either the Content Browser or the Place Actors panel.



Only a single Actor can be added to a Template Sequence, as adding another Actor from a different class will change the current binding.

Content Setup

If the content of your Template Sequence is meant to be additive, you will need to ensure your animation sections are set to Additive, Relative, or Additive from Base.

Do this by right-clicking the section keyframe area and selecting one of the Additive options from the Blend Type submenu.



You can then create your additive animation in the Template Sequence view. In this example the animation is of a simple bouncing ball, in which the ball hits the ground at the (0, 0, 0) coordinates.



Apply Template Sequence Animation

Template Sequences are meant to be used on an Actor within a Level Sequence. The Actor's class must match the class that the Template Sequence was bound to.

In your Level Sequence, click the + Track button, navigate to Template Sequence, and select your Template Sequence Asset.



You can apply your Template Sequence animation to any Actor of the same class. If your template is additive, the animation will apply additively to the Actor's current position.



Property Multipliers

Property Multipliers can be used on the Template Sequence instance as a way to modify the intensity of properties and transforms for each template instance. The multipliers available to add to a Template Sequence is based on the Property Tracks that you have added to the Actor class in the Template Sequence.

To add a Property Multiplier, right-click the Template Sequence section and select your property from the Property Multipliers menu.



Once added, you can expand the Template Animation track and view the multipliers, which typically have a default value of 1. You can change the value of a multiplier and set keyframes for it.



Using Property Multipliers, you can vary the intensities of each instance of your Template Sequence.



Blueprint Usage

Template Sequences can also be applied to Actors at runtime using the Create Template Sequence Player Blueprint node.



Content Setup

In your Blueprint, add the Create Template Sequence Player node. Once added, select your Template Sequence asset from the dropdown menu on the node.



Call Set Binding from the Template Sequence Player node and connect the Out Actor pin from the Template Sequence Player node to the Target pin.

Add a reference to the Actor you want to apply the template sequence animation to and connect it to the Set Binding node's Actor pin.



Lastly, add a Play node and connect from the Create Template Sequence Player node's Return Value pin.



Tags

Binding Tag Manager

Referencing in Blueprints

Groups

Group Manager

Sequencer provides the ability to tag tracks with metadata in order to support additional functions and behavior. Actors can have Tags assigned to them, and those tags can be referenced in Blueprints, which enables referencing Actors and tracks more generically. Tracks can also be placed into Groups, in order to manage their display and selection.

This page provides an overview of the Tags and Groups features in Sequencer.

You have an understanding of Sequencer, its Interface, and how to add Tracks.

You have an understanding of Blueprints Visual Scripting.

Tags

Tags are metadata markers that you can assign to the Object Binding Track in Sequencer, and can be referenced by tag-based Blueprint nodes.



The quickest way to add a tag to a track is by right-clicking it, navigating to the Tags menu, and typing a name in the Add Tag field. Once done you can either press Enter or the Add (+) button to create the tag.



You can have more than one tag assigned to an Actor.

Once a tag is assigned, the Tags context menu will now show the list of tags added to the track. They can be toggled on and off by clicking them.



Binding Tag Manager

To view and manage your tags in Sequencer, you can open the Binding Tag Manager by clicking Open Binding Tag Manager in the Tags context menu. You can also open it from the toolbar's Actions menu.



The Binding Tag Manager has two main areas:



The first area contains a list of all object bindings in the sequence, including any subsequences. Tags assigned to Actors are displayed next to them, and can be unassigned by clicking Delete (X) on the tag. New tags can be added by right-clicking a binding, typing in a name, and pressing Enter.



The second area lists all existing tags for this sequence. Clicking Delete (X) will unassign it from all bindings.

Referencing in Blueprints

Binding Tags can be accessed in Blueprints by calling one of the "by Tag" Binding functions from Level Sequence Actors. You can use these functions to get the current binding or bindings of Actors with tags, rebinding those Actors, or resetting bindings.

"By Tag" binding functions can be found by right-clicking in the Blueprints graph or by dragging off from a Level Sequence Actor reference and locating them within Sequencer > Player > Bindings.



Most of the "by Tag" Blueprint functions have the following input pins:



Target: The reference to the Level Sequence Actor.

Binding Tag: The Tag name to look for.

Actor: The Actor to bind, rebind, or add binding to.

Allow Bindings from Asset: Disabling this will lock the sequence from further binding actions.

Groups

Tracks in Sequencer can be added into groups, which aid in quick selection and display filtering.

To create new groups and add tracks to them, right-click a single track or multiple tracks, and select Add to Group > New Group. This will open the Sequencer Group Manager and create the new group and add the tracks to it.



With a new group created, new tracks can also be added to that group from the Add to Group context menu.



You can also drag tracks from Sequencer's outliner into the Sequencer Group Manager to add tracks to groups.



Group Manager

The Sequencer Group Manager is where you manage your groups and tracks that are assigned to them. If you are not creating a new group, you can open it by clicking Open Sequencer Group Manager in the toolbar's Actions menu.



Right-clicking in the Group Manager window will show the context menu, where you can create new groups, rename your group, delete groups, or Filter Groups.



You can quickly select the contents of a group by clicking the group header, or by clicking each group item individually.



Clicking the Filter icon will filter all tracks out in the Sequencer outliner except for the tracks (and their children).



Clicking the Filters menu in Sequencer's outliner will also display controls for enabling Group Filters.



Sequencer Overview

Possessable

Spawnable

Creating a Spawnable Actor

Properties

Workflows

Lighting Scenes

Sequencer in Different Levels

In Sequencer, you can choose to either reference an Actor that currently exists in the scene - referred to as a Possessable - or spawn a new Actor - referred to as a Spawnable. This document provides an overview of these concepts and how you can utilize them in your scenes.

You have an understanding of Sequencer and its Interface.

You know how to create and use Tracks.

Possessable

Possessing Actors is done by adding or binding Actors that exist in the Level to your sequence.



Once an Actor is possessed, the sequence will be linked to the instance of that Actor in the current Level. In most cases this might be an acceptable or even preferable workflow. If your scene requires a high degree of interaction with currently existing Actors in a Level, then possessing is likely the best choice for referencing Actors.

Spawnable

In cases where your scene requires Actors that might be temporary for the duration of a scene, you can use Sequencer's Spawnable feature for creating temporary Actors. By default, when a sequence with a Spawnable Actor starts, the Actor will be spawned. When the sequence ends, the Actor will be destroyed and removed.

A Spawnable Actor in Sequencer is denoted by a lightning bolt overlay on the Actor's icon.



A Spawned property track that has been enabled is also required and will be created automatically when using Spawnable Actors. If this track is deleted or disabled, then the Actor will not appear. This track can be keyframed if you want to more accurately control when the Spawnable Actor will appear.



Creating a Spawnable Actor

Spawnable Actors can be added to your sequence in a few ways.

You can right-click a Possessable Actor and select Convert to Spawnable. This will copy and delete the current Actor in your Level and create a Spawnable Actor based on the copy in Sequencer instead.



A Spawnable Actor can be converted back to Possessable by doing the same steps. When that occurs, the Actor is re-created in your Level and the track binds to it, removing the Spawnable Actor.

Dragging an Actor from the Content Browser or Place Actors panels into the Sequencer Outliner will also add them as Spawnable Actors.



Properties

Spawnable Actors have various properties that control their behavior and interactions with Sequencer. These properties can be accessed by right-clicking the Spawnable bound track and locating the Spawnable category.



Property Name

Description

Spawned Object Owner

Specifies which Level Sequence owns the Actor, which also determines the automatic spawn behavior.

This Sequence is the default setting which causes the Actor to be spawned and destroyed for the duration of the current sequence only.

Master Sequence causes the Actor to spawn and unspawn for the duration of the master sequence, if one is being used. This causes the Actor to be spawned and destroyed outside the bounds of the current sequence.

External causes the Actor to spawn at the start of the sequence, but it will not be destroyed at the end. You can instead destroy the Actor through Blueprints by using Sequencer Tags and Groups.

Spawned Level

Specifies which Level the Actor will spawn into. This list is determined by what Levels exist in your Levels window.

Change Class

Specifies the class that will rebind the spawned Actor to the chosen class from your project.

Continuously Respawn

When enabled, the Actor will continuously spawn every tick, ignoring any external destroy events.

Evaluate Tracks When Not Spawned

When enabled, all tracks from this Actor will still be evaluated even if the Actor is not spawned. This is useful if the Actor requires any preprocessing before being spawned.

Net Addressable

When enabled, this Spawnable Actor will be spawned using a unique name that allows it to be referenced by the server and client.

Save Default State

Saves the current state of this Spawnable Actor. Typically you do not need to click this as Unreal Engine will attempt to automatically save any changes to the Spawnable Actor.

Convert to Possessable

Converts the Actor to a Possessable Actor. When this occurs, the Actor is re-created in your Level and the track binds to it, removing the Spawnable Actor.

Workflows

Spawnable Actors can help you create more organized scenes in terms of content organization and management. Examples of when or how you can use Spawnable Actors effectively are listed below.

Lighting Scenes

Instead of placing several lights in your Level that have to be manually enabled and disabled per shot, you can simply just add the required lights to your shot as Spawnable Actors. They will exist only for that shot, and not clutter your Level with unnecessary lights.



This workflow can also be used for any temporary Actor, such as particles.

Sequencer in Different Levels

If every Actor within your sequence is a Spawnable Actor, then it is possible to reference that sequence in multiple different Levels and have all the Actors appear. This will allow cutscenes to play in multiple Levels using the same spawned Actors.



Overview

Workflow Example

Create and Populate Playlist

Trigger Playlist Playback

Saving and Managing Playlists

For broadcasts, live events, or timing-critical playback, you may find it necessary to trigger different sequences to play at arbitrary times. You can do this using Sequencer Playlists, where you can prepare sequences and trigger them to play during a virtual production session.

This document provides an overview of how to use Sequencer Playlists.

Sequencer Playlists is a Plugin that must be enabled prior to use. Navigate in the Unreal Engine menu to Edit > Plugins, locate Playlists in the Virtual Production section, and enable it. You will need to restart the editor afterward.



Your project already contains some Level Sequences that you can reference in your playlist.

Overview

To start using Sequencer Playlists, navigate to the main Unreal Engine menu and click Window > Virtual Production > Playlists. This will open the Playlists panel.



The Playlists panel contains the following interface:



The Toolbar, where you can Save, Load, and create new playlists.

The name of the current playlist and a short description. You can name a playlist by Saving it, and you can edit the description by clicking on the playlist description field.

Adds a Sequencer item to the playlist. When one is added, you need to specify the Sequence you want to play in the main dropdown menu of the item.

The Playlist, which displays the list of Sequences added to the playlist. The following properties can also be set on each item:

Offset, which controls the start and end trim of the Sequence, when played.

Hold, which holds the first frame of the Sequence until it is played. This is done by creating a second instance of the Sequence with its Time Scale property set to 0.

Loop, which enables the Sequence to loop when triggered. If looping is enabled, then you must also set the number of times to loop before stopping.

Play Mode, which enables a more streamlined overlay for your items, making it easier to select Play and Stop for each Sequence.

Playback Controls, which contains the following buttons:

Play All: Starts playing all playlist items at the same time.

Stop All: Stops all playlist items.

Reset All: Stops all playlist items and re-holds the first frame for any Sequences that have Hold enabled.

Hovering your cursor over a Sequence item also reveals additional buttons and properties.



Playback Controls, where you can Play, Stop, and Reset this Sequence.

Settings for this Sequence, which contains the following:

Playback Controls.

Playback Speed, which controls the playback rate of the Sequence when triggered.

Mute, which disables this Sequence from being triggered when clicking Play All. This Sequence can still be triggered directly by clicking Play.

Remove from Playlist, which deletes this Sequence from the playlist.

Workflow Example

The main purpose of Sequencer Playlists is to add pre-created Sequences to a "playlist" so that you can trigger them to play as Subsequences during the playback or recording of another Sequence. In most cases, this is during recording with Take Recorder.

Create and Populate Playlist

Click the Add (+) Item button to start adding Sequences to your playlist.



Next, assign a Sequence to the item by clicking the dropdown menu and selecting a Sequence.



Continue to add and assign Sequences to your Playlist until you are satisfied with your list.



Trigger Playlist Playback

To trigger the playback of your entire playlist, click Play All. This will open a new pending Sequence, if one was not open already, and play all Sequences indefinitely until you stop the playback. Playlist Subsequences will be stored in a folder called Playlist - (Your Playlist Name).



The most typical use-case for Playlists will be triggering them during a Take Recorder session. During recording, you can trigger your sequences to play at different times by clicking on each Sequence's playback controls. Sequences can be started, stopped, and reset multiple times during the recording and playback process.



You can also enable Play Mode, which will enable a more streamlined overlay for your items, making it easier to select Play and Stop for each Sequence.



Saving and Managing Playlists

You can save Sequence Playlists by either clicking Save, or by opening the Save dropdown menu to clicking Save Playlist As. Saved playlists are stored in the Content Browser as SequencerPlaylist Assets.



Clicking Load will display a list of all playlists in your project. Selecting one will load it as the current playlist.



You can clear your current playlist and start over by clicking Create New Playlist.



Sequencer Python Terms

Accessing a Level Sequence

Simple Access

Access Current Level Sequence

Create and Open Level Sequence

Get and Set the Currently Viewed Level Sequences

Querying and Editing a Level Sequence

Change Frame Rate

Change Start and End Times

Adding Actors

Creating Tracks and Sections

Copy and Paste Commands

Track Filtering

Additional Sequencer Scripting Resources

Python scripting can be used to automate and control various parts of Sequencer. This document provides an overview of the main ways to use Python with Sequencer, and examples of general Sequencer scripting.

You have some experience with Python scripting in Unreal Engine.

You have an understanding of how to use Sequencer.

Sequencer Python Terms

Sequencer uses the following terminology:

Sequencer Python Terms

Description

World

An object that represents a map in which actors and components can exist and be rendered (also referred to as a Level).

LevelSequence

An asset that is a container for cinematics scenes (also referred to as a Sequence). Level Sequences contain data and tracks that can be bound to different objects to animate them.

MovieSceneBindingProxy

A struct defining the actor or component that is bound by a Level Sequence (also referred to as a Binding).

Possessable

A type of binding describing an actor or component that exists in a Level, in which the Level Sequence can own any animatable properties.

Spawnable

A type of binding describing an actor or component that exists only while the Sequence is playing.

MovieSceneTrack

An object located under a Binding (MovieSceneBindingProxy), which contains all sections of edits for a specific typed property. For example, MovieScene3DTransformTrack > Actor / Component Transform.

MovieSceneSection

An object located under a Track (MovieSceneTrack), which contains all channels, length, and parameters for a specific typed property. For example, MovieScene3DTransformSection > Pre / Post Roll, When Finished State, Active/Muted, Additive.

MovieSceneScriptingChannel

An object located under a Section (MovieSceneSection) which contains all keyframes that animate a specific typed property or sub-property. For example, MovieSceneScriptingFloatChannel > Location.X.

MovieSceneScriptingKey

An object that represents a keyframe in the specifically typed channel. For example, MovieSceneScriptingFloatKey.

FrameNumber

A struct that represents a frame.

FrameRate

A struct that represents a fraction of 2 integers defining frames and seconds. For example, 30 frames per second is written as: 30/1.

Accessing a Level Sequence

The first step when Python scripting in Sequencer is to access the LevelSequence, which is the main object you'll be interacting with. There are several ways to do that depending on your situation.

Simple Access

To access a Level Sequence that exists in the Content Browser, you can use the following example script. The sequence does not have to be currently opened or exist in your current Level. This script assumes the Level Sequence Asset is located in the root content folder.

Access Current Level Sequence

You can also access a currently-opened Level Sequence using the following script:

Create and Open Level Sequence

You can use the following script to create a new Level Sequence Asset and open it:

Get and Set the Currently Viewed Level Sequences

You can use the following scripts to get or set the level sequence of focus in Sequencer:

You can also focus on a specific sub sequence by providing the sub sequence section to focus on:

To focus back on a parent sequence, all you would need to do is run this command:

Querying and Editing a Level Sequence

Once you have access to a Level Sequence in Python, you can perform changes to it. There are a variety of ways to affect your sequence, and some examples will be provided below.

Change Frame Rate

By default, Level Sequences play at a rate of 30 frames per second (fps). To change this playback rate, you can use the following commands:

Change Start and End Times

By default, A sequence's playback range is set to start at frame 0 and end at frame 150 (Assuming the frame rate is 30fps). You can adjust both the start and end frames with the following commands:

Adding Actors

To add an actor from your current Level for Sequencer to possess, use the following commands:

To add a Camera object through python scripting, mimicking the process through the Sequencer UI, use the following command :

Instead of possessing an actor present in your Level, you can spawn actors using python you can use for the duration of the sequence. Using the previously mentioned add_actors in the LevelSequenceEditorSubsystem, you can first use a command to make the actor possessables and then convert it to a spawnable object. Use the following commands to add a spawnable to your sequence:

For binding in bindings:

If necessary, you can additionally convert spawnables back to possesables with the following command using the LevelSequenceEditorSubsystem:

For binding in selected_bindings:

Creating Tracks and Sections

You can also add Tracks and Sections through Python scripting, with each track type informing the section type. For example:

Transform Tracks are defined as unreal.MovieScene3DTransformTrack and their sections use unreal.MovieScene3DTransformSection.

Skeletal Mesh Animation Tracks are defined as unreal.MovieSceneSkeletalAnimationTrack and their sections use unreal.MovieSceneSkeletalAnimationSection.

To add Tracks and Sections, use the following commands:

Some sections may require properties to be defined in order to be used. In the case of an Animation Track section, an animation asset must be defined. To do this, use the following commands:

Copy and Paste Commands

Additionally, Objects, Tracks, sections and folders can all be organized and managed using python scripting, using the following copy and paste functions:

Track Filtering

Track filtering commands can also be used:

Additional Sequencer Scripting Resources

For more resources on general Sequencer Python scripting, refer to the Sequencer scripting examples located in your local engine path:

…\Engine\Plugins\MovieScene\SequencerScripting\Content\Python

Overview

Overview

Sequencer includes powerful camera tools, enabling you to achieve your filmmaking goals in Unreal Engine. The following pages provide an overview of the different ways you can use cameras and enhance their behavior.



The Cine Camera Actor is used as the primary camera type for filming cinematic content in Unreal Engine.

The Cine Camera Actor is used as the primary camera type for filming cinematic content in Unreal Engine.



Control Cameras inside Unreal Engine by using a modular component system to manipulate and output Camera data.

Control Cameras inside Unreal Engine by using a modular component system to manipulate and output Camera data.



Film with real-world techniques in Unreal Engine by using Camera Rigs.

Film with real-world techniques in Unreal Engine by using Camera Rigs.



Create camera shake effects in Unreal Engine.

Create camera shake effects in Unreal Engine.



Use the Cinematic Viewport to add filmmaking controls in the viewport.

Use the Cinematic Viewport to add filmmaking controls in the viewport.



Play full screen videos and image sequences on your cameras using Image Plates.

Play full screen videos and image sequences on your cameras using Image Plates.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Creation

Usage

Piloting

Picture-in-Picture Display

Look at Tracking

Post Processing

Properties

The Cine Camera Actor is a specialized Camera Actor with additional settings that replicate real-world film camera behavior. The ability to adjust Filmback, Lens, and Focus settings will provide you with the tools necessary for creating realistic scenes, while adhering to industry standards.

Creation

In the Place Actors panel, navigate to the Cinematic tab and locate Cine Camera Actor. Drag it from the panel into your viewport to add a Cine Camera Actor to your scene.



If you are using Sequencer, you can also create a Cine Camera Actor by clicking the Camera button in Sequencer's toolbar. Doing this will create a temporary Spawnable Cine Camera Actor track for your current sequence.



You can specify whether or not to create the camera as a spawnable in Sequencer's Editor Preferences, using the Create Spawnable Cameras preference.

Usage

The Cine Camera Actor has a few primary functions to aid your viewport filming experience.

Piloting

Similar to most other Actors, the Cine Camera Actor can be Piloted to preview your camera's look and behavior from the viewport.



To pilot the Cine Camera Actor, right-click it from the viewport and select Pilot ‘CineCameraActor' or press Ctrl + Shift + P to toggle piloting mode.



Picture-in-Picture Display

When a Cine Camera Actor is selected, a Picture-in-Picture window will appear in the bottom right corner of the viewport. This window displays a preview of the camera's view and lists information about the camera's name, filmback and other properties.



Selecting multiple Cine Camera Actors will display multiple picture-in-picture windows with their respective views in the viewport.

This window can be pinned so that it remains visible even when the camera is not selected. Click the Pin button in the bottom-left corner of the picture-in-picture window to pin it.



The window can also be customized or disabled in Unreal Engine's Editor Preferences. In Unreal Engine's top menu, select Edit > Editor Preferences, then click on the Viewports menu in the Level Editor category and locate the following properties:



Name

Description

Preview Selected Cameras

Enables picture-in-picture display.

Camera Preview Size

Controls the size of the picture-in-picture display.

Look at Tracking

You can use the Cine Camera Actor to track other Actors using its Look at Tracking settings. Enabling this feature will override the camera's rotation and modify it to aim towards a specified object.



To enable camera tracking, locate the Look at Tracking settings in the camera details under the Current Camera Settings category. Then, select Enable Look at Tracking, and set the Actor to Track property to the Actor you want the camera to look at.



The Look at Tracking feature also contains the following properties for further customization:

Name

Description

Enable Look at Tracking

Enables the Look at Tracking feature on this camera.

Draw Debug Look at Tracking Position

Enables a debug locator cube to show what the camera is tracking. This is useful if you are using it in conjunction with Relative Offset.



Look at Tracking Interp Speed

The speed at which the camera updates its tracking of the object. The default value of 0 will make the camera track instantly, and numbers greater than 0 will add an increasingly large delay to the camera's tracking.



Actor to Track

Specifies the Actor that the camera is tracking. This property can be keyframed in Sequencer, allowing the camera to change its tracked target over time. If no Actor is specified, the camera will instead track the world origin (0, 0, 0).

Relative Offset

Specifies a positional offset to apply to the tracked Actor relative to its local space. This is useful for controlling specific framing of a tracked Actor.



Allow Roll

Enabling this will allow the camera to be rolled on its X-axis. If disabled, the camera tracking will override any data on the X-axis.

Post Processing

All Cine Camera Actors have their own Post Processing layer that is enabled when piloting them. Post processing allows for additional camera effects to be displayed and adjusted, such as Bloom, Exposure, Vignetting, Color Grading, and more.



Visit the Post Processing page for more information on the post-processing effects available in Unreal Engine.



Effects applied to the whole rendered scene prior to being rendered.

Properties

Selecting the Cine Camera Actor will reveal the following details:



Name

Description



Filmback



Filmback

The Filmback property contains a list of real-world preset Camera Bodies to choose from. These presets affect the Sensor Width and Height properties in order to emulate the selected camera body. The camera's base field of view and aspect ratio are also affected by these settings.



Sensor Width/Height

The Sensor Width and Height properties emulate the dimensions of your film or Digital Sensor in millimeters. These values automatically change whenever a new Filmback preset is selected.

Sensor Aspect Ratio

This property displays your current aspect ratio computed from the selected sensor's dimensions. This value cannot be changed manually as it is intended for read-only reference.



Lens Settings



Lens Settings

The Lens Settings property contains a list of real-world preset Camera Lenses to choose from. These presets affect the Focal Length, FStop, and Diaphragm properties to emulate the selected lens.



Min/Max Focal Length

The minimum and maximum Focal Length range for the camera. Setting these will affect the value range of the camera's Current Focal Range property, which is used to emulate Zoom Lenses. Setting both of these properties to the same value will emulate Prime Lenses, which are not designed to be zoomable.

Min/Max FStop

The minimum and maximum Aperture range for this camera.

Diaphragm Blade Count

This controls the Diaphragm (blade) count on the camera lens. The number of diaphragms on a lens correlates to the shape of the Bokeh effect. Lower numbers cause bokeh to appear more square, and higher numbers cause it to appear more rounded.





Focus Settings



Focus Method

Focus Method controls the depth of field and focus settings. It contains the following options:

Do Not Override, which disables the camera-influencing depth of field.This still allows depth of field from other sources, such as from a post-process volume.

Manual, which enables depth of field and controls the focus, relative to the camera position, using the Manual Focus Distance property.

Tracking, which enables depth of field and controls the focus by tracking Actors using the Tracking Focus Settings properties.

Disable, which disables depth of field entirely and does not allow any depth-of-field influence from other sources.

Manual Focus Distance

Controls the focus distance relative to the camera's position in centimeters. This is a type-aware field, so you can input 5m and it will convert the value to 500cm. There is also an eye dropper to enable selecting an object directly from your viewport and snapping your camera's focus to it. To use it, click the button, and then left-click the object in your viewport. This property only appears if Focus Method is set to Manual.

Actor to Track

The Actor used as the focus point for the camera's depth of field. This is enabled only if Focus Method is set to Tracking.

Relative Offset

A positional offset to apply to the tracked Actor relative to its local space. This is enabled only if Focus Method is set to Tracking and is useful for fine-tuning the focus point on tracked Actors.

Draw Debug Tracking Focus

Enables a debug locator cube to show where the depth of field is focused if Focus Method is set to Tracking. This is useful if you are using it in conjunction with Relative Offset.



Draw Debug Focus Plane

Enables a camera-oriented transparent plane for previewing your focus point.



Debug Focus Plane Color

Specifies the color of the Debug Focus Plane.

Smooth Focus Changes

Enables focus distance changes to be automatically interpolated over time, instead of instantaneously.

Focus Smoothing Interp Speed

The speed of focus-change interpolation if Smooth Focus Changes is enabled. Lower numbers are slower, and higher numbers are faster.

Focus Offset

Offsets the focus point relative to the position of the tracked Actor, if Tracking focus is being used. The focus point will instead use the Manual Focus Distance, if Manual focus is being enabled. Positive numbers increase the distance from the camera, and negative numbers decrease the distance.

Current Focal Length

The focal length property of the camera, which is limited based on the focal length range defined by the Min/Max Focal Length properties in Lens Settings.

Current Aperture

The aperture or FStop property of the camera, which is limited based on the FStop range defined by the Min/Max FStop properties in Lens Settings.

Current Focus Distance

A read-only property that displays the final focus distance output based on either the Manual or Tracking focus, including any additional offsets applied to them.

Current Horizontal FOV

A read-only property that displays the final horizontal field of view based on a combination of the camera's Focal Length and Sensor Dimensions.



Camera Options



Constrain Aspect Ratio

Enables the drawing of black bars which preview the Sensor Dimension and its base aspect ratio.



Use Pawn Control Rotation

If the camera is being used as a component on a Pawn, then enabling this will cause the Pawn's rotation to influence the camera component.

Post Process Blend Weight

Blends the influence of the camera's Post Process layer between fully on and off. A weight of 1 will cause it to be fully enabled, and 0 will cause it to fall through to other layers.

Lock to Hmd

Locks the camera's position and orientation to a connected head-mounted display, when a VR headset is connected for XR Development.

Use Field Of View for LOD

When enabled, the camera's field of view will influence what level of detail the object should display, instead of relying on camera distance only. This fixes issues caused by low-quality objects that are rendered from far away cameras , and that are zoomed in on the subject.

A Virtual Camera drives a Cine Camera in Unreal Engine by using a modular component system to manipulate camera data and output the final results to a variety of external output devices. In addition, the Virtual Camera system provides its functionality while in the editor.

The Virtual Camera Component (VCamComponent) is the base component for building custom virtual cameras in Unreal Engine.

With the VCamComponent, you can drive a Cine Camera in Unreal Engine by adding custom Modifiers and Output Providers.

TModifiers manipulate the camera data with custom effects such as filtering, tracking, and lens control.

Output Providers route the output of the virtual camera to Composure, Media Framework, editor viewports, or over Pixel Streaming to devices running the Live Link VCam app or capable of viewing a WebRTC stream.

In addition, this virtual camera architecture includes the following:

Multi-User editing support for all features.

The ability to overlay custom UMG controls over the output and interact with them in the editor or on a device.

Built-in support for input hardware such as controllers and touchscreens.

Functionality to switch to any custom tracking system with Live Link.

An updated Live Link VCam app with a new UI and improved streaming performance using Pixel Streaming.

To learn more about the virtual camera system, see the pages below.



The Virtual Camera Actor is a sample Virtual Camera that can be used as a starting point for your project.



The Virtual Camera Component is the base architecture that provides the foundation for building custom virtual cameras in Unreal Engine.



Use Switchboard to connect multiple users to simultaneously operate Virtual Cameras.

Overview

Goals

1 - Required Setup

Editor Setup

iOS Device Setup

Section Results

2 - Adding a Virtual Camera Actor

Placing the Camera in your Scene

Connecting your Device

3 - Record a Video Clip

4 - Exploring the Virtual Camera Controls

The Interface at a Glance

Adjusting the F-Stop

Adjusting Focus Distance

Adjusting the Lens

Adjusting Filmback

Adjusting Exposure

Adjusting exposure

Adjusting Exposure Compensation

Adjusting Near Clipping Plane

Adjusting The Custom Mask

Adjusting Axis Scaling

Repositioning your Camera

Taking Bookmarks

Using the Virtual Joysticks

Changing Joystick Sensitivity

Viewing the Recording Information

Overview

Unreal Engine includes a sample VCam Actor that you can use as a starting point for your project. This actor is built using the Virtual Camera Component referenced in the Virtual Camera Component Quick Start.

Goals

In this guide, you will learn how you can use the VCam Actor in your scene.

By the end of the guide, you will be able to:

Place the VCam Actor in the scene

Connect your iOS device via Live Link

Use the Virtual Camera Actor's built-in interface to change the camera's parameters

1 - Required Setup

Editor Setup

Before you start, you must enable the appropriate plugins inside your project.

To open the Plugins menu, click on Settings > Plugins.

Search for the VirtualCamera, Take Recorder, and Live Link plugins, and enable them.

Restart the editor.

Download the Live Link VCAM app from the App Store to your ARKit enabled iOS device, and launch the app.



Section Results

You are now ready to start using the virtual camera actor.

2 - Adding a Virtual Camera Actor

To place a virtual camera in your scene:

On the Place Actors panel, select the Virtual Production category and click and drag the VCam Actor to your scene.



To connect your device:

In the World Outliner panel, select your VCamActor object, go to the Details panel, and select the VCam component.



In the VCam component's properties, enable the object by toggling the checkbox in the Enable property.



Section Results

Your iOS device can now operate the Virtual Camera in your scene. As you move the iOS device in 3D space, the Editor's view changes to reflect your movements.

Additionally, you can now use the VCam interface, on your iOS device, which contains many controls for managing the look and behavior of your Virtual Camera in the scene.



3 - Record a Video Clip

After connecting your iOS device to Unreal Engine via Live Link, you can record sequences, or shots of your project's animated scenes and characters using Take Recorder.

When you start a recording via Take Recorder, Unreal Engine automatically plays the current Level Sequence.

After recording a shot, you can play back a take for review from the Take Recorder panel. While you're reviewing the previous take, VCam's HUD hides. When you exit review mode, The HUD returns and the camera repilots.

To open the Take Recorder panel:

In the Menu Bar, go to Windows > Cinematics > Take Recorder.



To record a video clip:

Tap on the Recording icon to start the recording, and tap it again to end the recording.



Unreal Engine saves recorded animations as a Sequencer Clip. When a video clip is saved, it replaces any VCam Actors with a clean CineCameraActor named VCamProxyActor.

4 - Exploring the Virtual Camera Controls

The following is an overview of the features that come with the Virtual Camera Actor interface using a Live Link connected device.

The Interface at a Glance



The Virtual Camera's Controller Interface features a range of controls and settings you can use to modify the look and behavior of a Virtual Camera, using an external device.

Using your iOS device's ARKit features, the physical position and rotation of your device control the Virtual Camera's position and rotation within your project in real time while you're editing a project.

If you use a Gamepad, the camera's position and rotation will be controlled directly via the joysticks, layered on top of the device's movement.

Adjusting the F-Stop

By default, when you adjust the F-Stop in Unreal Engine's Virtual Camera setup, this only affects the camera's depth of field; it does not affect the exposure of the image.

To adjust the F-Stop:

To bring up the F-stop dials, tap on the Lens button in the left ear menu.



To adjust the F-Stop in real time, slide your finger along the Iris dial to rotate it.



Adjusting Focus Distance

To bring up the Lens dial, tap on the Lens button in the left ear menu.

To adjust the Focus Distance in real-time, drag your finger along the Focus Distance dial to rotate it.



Adjusting the Lens

You can change the virtual camera's lens using the Lens dial and observe the updated camera view in real time.

To adjust the lens:

To bring up the Lens dials, tap on the Lens button in the left ear menu.

To adjust the lens, slide your finger along the Lens dial. Unreal Engine renders your changes in real time.



You can configure the options available for the in Lens under your Project Settings > Cinematic Camera > Lens Presets.

If your Lens Preset supports a range of Focal Lengths, you can further adjust Focal Length via the Focal Length dial.

Adjusting Filmback

The Filmback settings control the dimensions of the image area.

To adjust the filmback:

To bring up the filmback dial, tap the Filmback button in the left ear menu.

To select the desired filmback for your camera, drag your finger along the dial. Unreal Engine renders any changes to the image area in real time.



You can configure the filmback options under Project Settings > Cinematic Camera > Filmback Presets.

Adjusting Exposure

To bring up the ISO dial, tap the ISO button in the left ear menu

To select the desired ISO for your camera, drag your finger along the dial to rotate it.



Lower numbers give lower light sensitivity, higher numbers give higher light sensitivity.

When you've set the exposure via the ISO dial, the Iris dial appears. The Iris impacts both exposure and depth of field.

You can adjust the Exposure Compensation Dial to change the camera's exposure compensation. Compensation is measured in stops. Lower numbers give higher exposure, and higher numbers give lower exposure.



Adjusting Near Clipping Plane

The near clipping plane determines the distance from a camera at which an object "clips" and doesn't render.

To adjust the near clipping plane:

Tap the Clipping Plane button in the left ear menu to bring up the Near Clip Plane dial.

To select the desired Near Clipping Plane distance, drag your finger along the dial to rotate it. Unreal Engine renders any changes in real time.



Adjusting The Custom Mask

If you have a custom mask present in your render, you can adjust its values.

To adjust the custom mask:

To bring up the Custom Mask dial, tap the Viewfinder button in the left ear menu.

To select the Custom Mask Aspect Ratio for your inner mask, drag your finger along the dial to rotate it. Unreal Engine applies the changes within the mask already defined by your camera's Filmback.



Adjusting Axis Scaling

To adjust the scale of an axis:

To bring up the Axis dials, tap the Scale button in the right ear menu.



Drag your finger along the Inner Axis dial to rotate it and select between scaling All Axes, Planar Movement (X,Y), or Vertical Movement (Z).



To select a motion scale for the axis selected on the inner dial, drag your finger along the Outer Scale to rotate it.



If you want to lock the axis, you can set a Scale's value to 0.

Repositioning your Camera

You can tap Hold in the right ear menu of the HUD to freeze the camera's location and rotation in place. You can then move the controlling device to a new position without losing the camera's current transformation. You can unfreeze the camera by tapping Hold again. Your camera remains in the original held position, even if you have physically moved your controlling device.



Taking Bookmarks

You can use bookmarks to save a Virtual Camera's position, rotation, and settings in the scene.

To save a bookmark location in the scene:

Tap on the Bookmark. The camera's position and settings have now been saved as a bookmark.



(Optional) To reload a bookmark, tap the forward or backwards buttons in the Bookmark panel to cycle between your saved bookmarks. To re-inherit the camera controls from a bookmark, tap the camera icon to the right of the bookmark button.



3, (Optional) To delete the current bookmark, tap the Minus icon in the Bookmarks panel.

Bookmarks also exist as actors in the scene. You can add or delete bookmarks manually from the editor using the World Outliner panel.

Using the Virtual Joysticks

You can control the VCam Actors movement and rotation with a set of virtual joysticks on your Live Link-connected device. To use the virtual joysticks, tap and drag anywhere in your device's viewport.



The left joystick appears as soon as you press down on the left side of the frame and moves the camera along the X and Y axis within the level.

The right joystick is direction sensitive and only appears after dragging in an initial direction, giving you contextual controls. Dragging the right joystick up moves the camera along the Z axis or booms the camera. Dragging the right joystick side to side pans the camera left and right. You cannot operate both modes simultaneously. To switch the right joystick's operations, lift your finger from the screen and then re-apply your gesture.

To change the sensitivity of your on-screen joysticks select the Axis Scaling button in the right ear menu, and drag your finger to rotate the Joystick Gain dials.

Viewing the Recording Information

When the virtual camera is active, it can display the current Timecode, Slate, and Sequence Frame in the HUD. This data is derived from the Unreal Engine Take Recorder panel, and displays the same information simultaneously.



Controlling Sequencer When a sequence is open in Sequencer, you can view and control the timeline and playback of the sequence using the transport controls on your Live Link-connected device.



You can use these controls to preview the animation, use the Seqeuncer's Play, Pause and Scrub controls, and observe the current sequence's current frame data.

Overview

Goals

Objectives

1 - Required Setup

Section Results

2- Creating a Virtual Camera

Section Results

3 - Adding Modifiers

Creating your First Modifier

Adding the Modifier to the Stack

4 - Using the Virtual Camera Input System

Goals

Creating an Input Event

Section Results

5 - Adding Output Providers

Viewport Output Provider

Overview

The Virtual Camera Component (VCamComponent) is the base component that enables building custom virtual cameras in Unreal Engine.

With the VCamComponent, a user can drive a Cine Camera inside Unreal Engine by adding custom Modifiers and Output Providers.

Goals

This Quick Start guide is designed to take you through the basic steps of creating a virtual camera using the Virtual Camera Component.

Objectives

After going through this guide, you will learn the following:

How to place a camera in the scene and add the VCamComponent.

How to add Modifiers to the camera to customize its behaviors.

How to add basic key inputs to enable and disable Modifiers.

How to use different Output Providers.

1 - Required Setup

Before you start, you need to enable the appropriate plugins inside your project.

Click on Settings > Plugins to open the Plugins menu.



Search for the Virtual Camera plugin and enable it.



Restart the editor.

Section Results

You are now ready to start creating your virtual camera.

2- Creating a Virtual Camera

The Virtual Camera Component works with any Actor that contains a Cine Camera Component. In this example, we will be using the Cine Camera Actor for convenience.

On the Place Actors panel, select the Cinematic category and click and drag the Cine Camera Actor to your scene.



With the Cine Camera Actor selected, go to the Details panel and select the CameraComponent.



Click the +Add button and search for and add the VCam component.



Make sure the VCam component is a child of the CameraComponent.

Select and click VCam to add the component.

Feel free to move the Cine Camera Actor in your scene and adjust the Current Camera Settings to your liking. In the example below, we moved the camera to frame the meerkat in the scene and adjusted the camera to always keep the subject in focus.



You can learn more about adjusting the camera settings by going to the Cine Camera Actor documentation page.

Select the Camera Actor, then select the VCam component in the component hierarchy.



You can now see the properties available under the Virtual Camera section.



The properties are as follows:

Property

Description

Enabled

This toggle enables and disables the entire Virtual Camera Component.

Role

The role of the virtual camera. If this value is set and the corresponding tag set on the editor matches this value, then this camera is the sender and the authority in the case when connected to a multi-user session.

Live Link Subject

This is the subject used via the Live Link plugin. The component uses the subject's camera information to drive the camera into the scene.

Lock Viewport to Camera

The viewport will be rendered from the point of view of the virtual camera.

Disable Component when Spawned by Sequencer

Disables the Virtual Camera Component when spawned by a Sequence. This prevents a situation where two VCam components might become active simultaneously when you play a Sequence that contains a VCam component set as spawnable.

Target Viewport

This is the editor viewport that will be used by the component to render its view.

Output Providers

Contains a list of all output device destinations.

Modifier Context

An optional object that contains arbitrary data that is shared between all Modifiers.

Modifier Stack

Contains a list of all Modifiers added to the component.

Section Results

You placed a Cine Camera Actor in your scene and added the Virtual Camera Component. You are now ready to customize your camera by adding Modifiers.

3 - Adding Modifiers

Modifiers can manipulate the camera by adding custom effects and behaviors to simulate real-life camera behaviors. You can create custom modifiers with Blueprints or C++ and add them to the stack to layer different effects.

The Modifiers in the stack will be executed from top to bottom and the effects will be applied in that order.

Right-click inside the Content Drawer and select the VCam Modifier under the Virtual Camera category.



Name your Blueprint VCM_LookAt, then double-click it to open it.



Go to the My Blueprint tab and click on the plus sign next to Variables to add a new variable. Name the new variable TargetActor.



With TargetActor selected, go to the Details panel and click on the Variable Type dropdown. Search for Actor and select the Object Reference.



Select the Instance Editable checkbox and Compile and Save the Blueprint.



Drag TargetActor into the Event Graph and select Get TargetActor. Then drag from the node and search for and select Is Valid, as shown below.



Connect the Event on Apply node to the Is Valid node.



Drag from the Camera Component pin of the Event On Apply node and search for and select Get World Location.



Drag from TargetActor and search for and select Get Actor Location.



Drag from the Return Value of the GetWorldLocation node and search for and select Find Look At Rotation.



Connect the Return Value pin of the Get Actor Location node to the Target pin of the Find Look at Rotation node.



Drag from the Camera Component pin of the Event On Apply node and search for and select Set World Rotation.



Connect the Is Valid pin from the Is Valid node to the Set World Rotation node. Connect the Return Value pin of the Find Look at Rotation node to the New Rotation pin of the Set World Rotation node.



Compile and Save the Blueprint.

Now you are ready to add your custom Modifier to the Modifier Stack.

Go to the Place Actors tab and under the Basic category, click and drag a Sphere into the level.



Select your Camera Actor and inside the component hierarchy, select the VCam component.

Click the plus sign on the Modifier Stack to add an entry to the list.



Enter a name for your Modifier, such as Look At. Adding a name allows you to reference this Modifier in your Blueprints later on.



Click on the dropdown arrow for Generated Modifier and select VCM_LookAt from the list.



Expand the Default section of the Modifier and click on the Target Actor dropdown. Select the Sphere Actor you added to the level.



Select the Sphere Actor in your level and move it. You will see the camera rotate toward the Sphere.



Section Results

In this section, you learned how to create a custom camera modifier by using Blueprints.

You also learned how to add your custom modifier to the Modifier Stack to manipulate your virtual camera inside the editor.

4 - Using the Virtual Camera Input System

The current Virtual Camera input system is a placeholder and will be replaced by a more advanced version in the future.

The Virtual Camera Component can use Editor Input Events directly inside Modifiers to provide additional control to the user.

Here is how you can use this system to add additional functionality to your Modifier.

Goals

Our goal for this section will be to add a key input to our Modifier that will allow us to enable and disable the effect by pressing a single key.

Creating an Input Event

Open the VCM_LookAt Blueprint by double-clicking it in the Content Drawer.

Right click on the Event Graph then search for and select the function Get VCamInputSubsystem.



Drag from the VCam Input Subsystem node then search for and select the Bind Key Up Event. Connect the Event On Initialize node with the Bind Key Up Event node.



Drag from the red Delegate pin and search for and select Add Custom Event. Name the new custom event ToggleActivation.





On the Bind Key Up Event node, click on the keyboard icon and press the S key to bind it to the event. Alternatively, you can press the dropdown arrow and select the desired key from the list.



Right click on the Event Graph and search for and select Set Enabled under the Virtual Camera category. Connect the ToggleActivation node to the Set Enabled node.



Right click on the Event Graph and search for and select Is Enabled under the Virtual Camera category.



Drag from the Is Enabled node and search for and select Not.



Connect the Not node to the New Enabled pin of the Set Enabled node.



Return to your scene and while moving the Sphere Actor in the level, press S to toggle the effect on and off.

The virtual camera input system executes every time the user presses a key, even when the viewport is not in focus. This can cause conflicts when the user presses the key for other purposes. For example, if the user renames an asset in the Content Drawer and uses the letter S, it will execute your event.

To prevent accidental activation of the Modifier, you can add safeguard to your code such as adding the Shift key as part of the input.

Go back to VCM_LookAt and add a Branch node between the ToggleActivation event and the Set Enabled node, as shown below.



Drag from the Key Event pin of the Toggle Activation node, then search for and select the Get Input from Key Event function.



Drag from the node, then search for and select the Is Shift Down function.



Finally, connect the Is Shift Down node to the Condition pin of the Branch node, as seen below.



Your Modifier will now execute only when the Shift key is down and you press the S key.

Section Results

In this section, you added an input event that executes when the S key is pressed. This event enables and disables the effect of your Modifier. In addition, you added the Shift key as a safeguard to prevent conflicts when the user presses the S key for another purpose.

5 - Adding Output Providers

The Output Provider system is used to route the output of the virtual camera onto various providers including viewports, devices using the remote session protocol, the Composure plugin, and various supported video capture cards.

The Output Providers list is always executed in order, starting from the top.

Let's take a look at the available Output Providers that come with the Virtual Camera Component.

This Provider will output the virtual camera's view directly to the main viewport in the editor.

Select the VCam component and click on the + sign next to the Output Providers to add a new Provider to the list.



Select the Viewport Output Provider option from the list.



You can now see the shared properties among the different Providers:

Property

Description

Is Active

Enables and disables the Provider.

UMG Overlay

UMG widget that is overlaid on top of the image output.

Use Override Resolution

Sets a custom resolution to the output image. This is especially useful when using external devices with fixed resolutions.

Override Resolution

This is the fixed resolution used for the output image.

As an example, click on the UMG Overlay dropdown and search for and select TestUMG to add a test widget to the viewport.



Finally, set the Output Provider as Active by clicking on the checkbox.



You should now see an overlay on the main viewport in your scene. This is an example of how you can customize your camera output to fit your specific needs.



Unreal Remote Output Provider

This Provider outputs the main editor viewport to a remote device connected via the Remote Session protocol, such as the Unreal Remote 2 app. Any compatible device connected with this method can be used for this purpose.

Next, you will configure your project to connect an external device using Remote Session.

Open Settings > Project Settings.



Go to the UDP Messaging section and set your Unicast Endpoint to your computer's IP address with :0 at the end of the IP to indicate your port number.



Go to the Rendering section and under Default Settings click on the arrow to expand the advanced settings. Set your Frame Buffer Pixel Format to 8bit RGBA.



Restart the editor.

Download the VCAM App from the App Store to your ARKit enabled iOS device and launch the app.



Select the VCam component on your virtual camera actor, and select the Unreal Remote Output Provider from the Output Provider dropdown list.



Open the Unreal Remote 2 app on your device. Enter the IP address of your computer and tap the Connect button to try and establish a connection.

You should now see the main editor viewport mirrored on your device's screen.



The Media Output Provider sends the virtual camera's output to any device supported by the Unreal Media Framework, such as video capture cards from Black Magic and AJA.

Once chosen, you can select the Output Config, which is used to specify the output parameters.



For more information on how to use the Unreal Media Framework, visit the Media Framework documentation page.

The Composure Output Provider sends the virtual camera's output to a render target that can be used directly by the Composure Plugin. In addition, you can specify the Composure Layer Targets that the camera's view will be rendered on.



For more information on how to use the Composure Plugin, please visit the Composure Plugin documentation page.

Section Results

In this section, you learned how to add different Output Providers to your Virtual Camera component. You can now use your virtual camera to output directly to the editor viewport, or an external device via the Remote Session protocol.

You also learned how to send your output to be processed by the Unreal Media Framework and the Composure Plugin.

Next Steps

Now that you know how to build your virtual camera, look at the pre-built Virtual Camera Actor that comes included in the Unreal Engine by going to the Virtual Camera Actor Quick Start.

Virtual Cameras

Multi-User Editing in Unreal Engine

Switchboard

nDisplay Overview

nDisplay Quick Start

nDisplay Configuration File Reference

Declare Virtual Production Roles

Connect Your Devices

Multi-User Virtual Camera Operation

You can create a Multi-User Virtual Camera (VCam) workspace, where users from multiple workstations can control and render VCams in the same scene simultaneously, using the Switchboard application.

This document provides an example workflow, you can use to set up a connected work environment for multiple users to operate VCams in the same scene simultaneously.

Enable the Switchboard Plugin. In the Menu Bar, navigate to Edit > Plugins and locate the Switchboard plugin under the Virtual Production section. Alternatively, you can use the Search Bar. After enabling the Plugin, restart the editor.



You can access the Switchboard application using the Icon in the Unreal Engine Toolbar, after the plugin has been successfully installed.



You must have a functional Virtual Production project. If you do not have one, you can use the Template project.

You must have a Multi-User Editor Server. For more information, refer to the Multi-User Quick Start Guide.

Your project must have a Virtual Camera (VCam) Actor.

Declare Virtual Production Roles

The Switchboard application requires each user to occupy a VP Role, such as an Editor or Render, to differentiate and identify which user is associated with which VCam Actor.

On your primary workstation in the Unreal Editor, select the VP Roles button in the Toolbar and Select the (+) Add Role option from the drop down menu. Define the new role with a name. In this workflow example the primary workstation is named Editor.





Add a second Role using the VP Roles Toolbar button, for your secondary device to occupy. In this workflow example the secondary workstation is named Render.



In the Menu Bar, navigate to Edit > Project Settings, and under the Multi-User Editing section, and set the Validation Mode property to Soft, using the dropdown menu.



If your project contains any dirty packages, you will be prompted with an error when joining a multi-user session. You then have the opportunity to cancel the connection, to fix any present issues. If you choose to proceed any dirty packages will be deleted.

Your project is now ready to connect other devices using Switchboard for multiple users to operate VCams simultaneously in the same scene.

For more information about connecting multiple users using the Switchboard plugin, refer to the Switchboard and the Switchboard Quick-Start Guide documentation.

Connect Your Devices

After creating your VP Roles in the Unreal Editor, use the Switchboard application to connect your devices to the Multi-User session.

Launch the SwitchboardListener, using the options menu adjacent to the Switchboard button in the Toolbar.



Launch the Switchboard application by clicking the button in the Toolbar.



Create a new Switchboard Device, representing the primary workstation, by selecting Unreal from the Add Device dropdown menu.



Set a Name in the provided field, and the primary workstation's IP Address. Set the same name as the primary workstation role set in Unreal Engine. In this workflow example, Editor was used.



Create a second Switchboard Device, representing the second workstation, using the same method. For the second device, use the same name as the second workstation's role. In this workflow example, Render was used. Both devices are now listed in the Switchboard application, in the Unreal Devices list.



To automatically open a network connection and to connect a device to the Multi-User Editor session, select the Auto-Join and Network Connection icons for each device in the Unreal Devices list. The Connection Indicator appears blue after a device makes a successful connection to the network.



You can open a Network Connection and enable Auto-Join for every listed device using the Auto-Join and Network Connection icons in the Unreal Device's list header.



Assign a VP Role to each connected device. In the Switchboard's Menu Bar, navigate to Settings > Settings and scroll down to each connected device's section. In the Roles property, select one of the Unreal Engine VP Roles, for each device, using the dropdown menu.



With your workstations connected, and their roles assigned, you are now ready to launch each device and start operating VCams in a Multi-User environment.

Multi-User Virtual Camera Operation

Connect your primary workstation to the multi-user session by selecting the Launch icon next to the primary Editor device in the Unreal Devices list, in the Switchboard application.



Once your project has launched, you can verify that the editor is connected to the multi-user session in the Multi-User Browser window. You can open the Multi-User Browser in the Menu bar, navigating to Window > Multi-User Browser.



In the World Outliner, select the VCamActor.

Select the VCam component in the VCam actor's Details panel.

Set the Role property to Edit in the Virtual Camera properties section and select the Editor VP Role from the drop down menu.



Enable the Virtual Camera by toggling the Enabled property.

In the Switchboard application, launch the Render device by clicking the Launch icon. Following the steps above, verify that the secondary Render device is also connected to the multi-user session, using the Multi-User Browser window.

Now that both editor instances are open, move the Virtual Camera on the primary Editor device and see the changes replicated in the secondary Render device in real time. In the example below the Editor device (Left) is operating a VCam Actor and the Render device (Right) is receiving the changes and rendering the scene.



For more information on about Multi-User connection set behaviors, refer to the Virtual Camera Multi-User Technical Reference.

Virtual Cameras

Virtual Camera Multi-User Quick-Start Guide

Multi-User Editing in Unreal Engine

Switchboard

nDisplay Overview

nDisplay Quick Start

nDisplay Configuration File Reference

Multi-User Set Up Example

You can use a multi-user server to connect many users to synchronous editing sessions, in order to operate multiple Virtual Cameras in an Unreal Engine project.

You can use the following document to reference an example project that features a multi-user connection between three workstations each operating a virtual camera (VCam).

Multi-User Set Up Example

Here you can read about an example of a more complex Multi-User VCam setup that you can use to build a better understanding of working with VCams with multiple users.

This example scene setup contains three separate virtual cameras:

VCam1 - Is assigned the Editorial role.

VCam2 - Is assigned the Main role.

VCam3 - Is assigned the Render role.

Using the Switchboard application, each virtual camera is connected to the multi-user server. Based on each camera's assigned VP Role, information can be sent and received between devices.

Each device launched using the Switchboard application also has an assigned VP Role. If this VP Role matches a virtual camera actor's role in the scene, the device will connect and operate the camera freely. Using the VP Role system, you can pair each device to a corresponding virtual camera in the scene without conflict.

In this example, the device with the Editorial role owns VCam1 and is sending the camera's information to the other two devices. Since the Editorial role does not own VCam2 or VCam3, it can only receive their information.

You can see this relationship illustrated in the chart below:

Since the Editorial role does not own VCam2 or VCam3, it simply receives the information from those devices.

You can see this relationship illustrated in the chart below:



Using the VP Role system, many Virtual Camera operators, designated with unique VP Roles, are able to operate virtual cameras independently and make changes within the scene simultaneously.

For more information about how to set up a project where multiple users are able to pilot multiple Virtual Cameras at the same time, refer to the VCam Multi-User Quick Start Guide.

Cine Camera Actor

Camera Rig Rail

Creation

Track Length and Shape

Rail Controls

Camera Rig Crane

Creation

Crane Controls

Camera Rigs In Sequencer

Rail

Crane

Combining Crane and Rail

One of the methods real-world filmmakers use to produce smooth, sweeping shots, is by utilizing Camera Rigs, which are apparatuses that the camera attaches to. In Unreal Engine, you can use Rail and Crane rigs to create realistic camera movements.

You have an understanding of the Cine Camera Actor, and have already added one into your Level.

You know how to Create Camera Animation within Sequencer.

Camera Rig Rail

The Camera Rig Rail is used to emulate a Camera Dolly system, which is used to create Tracking Shots. The rail's track length and curvature can be modified to suit the needs of your shot.



Creation

To add a rail rig to your Level, navigate to the Cinematic tab in the Place Actors panel and locate Camera Rig Rail. Drag it from the panel and into your viewport.



Next, move the camera to your chosen position, relative to the dolly, and attach it to the rail by dragging the camera Actor onto the rig rail in the World Outliner.



After a camera is attached to the dolly, it can still be moved to fine-tune its final position.

Track Length and Shape

The Camera Rig Rail uses Unreal Engine's Blueprint Splines for determining its track's length and shape. By default, the rail uses linear spline points at the start and end of the track. These points can be selected and moved to adjust the length and direction of the track.



Selecting and moving the spline tangent points will add curvature to the track based on the tangent angle.



Additional points can be added to the track's spline to fine-tune the track's shape. Select the rig rail, right-click the spline, and select Add Spline Point Here to add a new point at your cursor's position.



Rail Controls

When selecting the Camera Rig Rail Actor, it displays the following properties for controlling its behavior and movement.



Name

Description

Current Position on Rail

This property controls the dolly movement along the track. The value range is clamped between 0 and 1, where 0 is the start point of the track, and 1 is the end point.



Lock Orientation to Rail

By default, the camera's orientation is set independently from the orientation of the dolly. Enabling Lock Orientation to Rail will cause the camera's rotation to be set relative to the dolly's rotation.



Show Rail Visualization

Disabling Show Rail Visualization will hide the dolly and track mesh, leaving only the spline visible.



Preview Mesh Scale

This property changes the size of the track and dolly preview geometry.



Camera Rig Crane

The Camera Rig Crane Actor is used to emulate a boom arm or Camera Jib system, which is used to create Crane Shots. The crane can be pivoted along horizontal and vertical axes, and can be extended as needed.



Creation

To add a crane rig to your Level, navigate to the Cinematic tab in the Place Actors panel and locate Camera Rig Crane. Drag it from the panel and into your viewport.



Next, move the camera to your chosen position, relative to the crane anchor, and attach it by dragging the camera onto the rig crane in the World Outliner.



Crane Controls

When selecting the Camera Rig Crane Actor, it displays the following properties for controlling its behavior and movement.



Name

Description

Crane Pitch

Controls the pitch movement of the crane mechanism.



Crane Yaw

Controls the yaw movement of the crane mechanism.



Crane Arm Length

Controls the crane arm length in centimeters. This is a type-aware field, meaning that if you were to type in other units such as 2m will automatically convert to 200cm.



Lock Mount Pitch / Yaw

By default, the camera's orientation is independent from the crane's pitch and yaw movement. Enabling either Lock Mount Pitch or Lock Mount Yaw will cause the camera's rotation to be set relative to the pitch or yaw rotation of the crane.



Camera Rigs In Sequencer

The primary way you will be manipulating Camera Rigs will be by animating them in Sequencer. Both the Camera Rig Rail and Camera Rig Crane Actor tracks can be added to your sequence



You will also need to add the attached camera Actors as tracks in Sequencer in order to animate them in conjunction with the movement of your rigs.



Rail

Camera Rail Rig property tracks can be added to Sequencer by clicking the + Track button on the track and selecting from the Properties category.



Once the tracks have been added, you can set keyframes on the rail and camera property tracks to create your tracking shot.



Crane

Camera Crane Rig property tracks can be added by clicking the + Track button on the track and selecting from the Properties category.



Once the tracks have been added, you can set keyframes on the crane and camera property tracks to create your crane shot.



Combining Crane and Rail

You can also attach a rail to a crane, using the same camera attachment steps detailed above, to create a camera dolly and crane system. Crane and rail properties can be animated together to allow for more freedom and realism in your shot creation.



Camera Shake Creation

Details

Root Shake Pattern Types

Perlin Noise

Sinusoidal Wave

Sequence Shake

Composite

Playing Your Shake

Playing from Sequencer

Playing from Blueprints

Camera Shake Source

Looping Shake Example

Camera Shake Previewer

You can add a camera shake effect to your cameras using Unreal Engine's Camera Shake Blueprints. This guide provides an overview of how to create a CameraShakeBase Blueprint, the type of shakes that are available, and how to play them in Sequencer, Blueprints, and Camera Shake Sources.

You have an understanding of Sequencer and know how to Create Camera Animation.

You have an understanding of Blueprints Visual Scripting.

If you are using custom sequence-based shakes, then you must have an understanding of Template Sequences.

If you want to test camera shakes in gameplay, you can create a project using the Third Person Template.

Camera Shake Creation

To create a shake asset, click Add/Import in the Content Browser and select Blueprint Class. In the next window, locate or search for the CameraShakeBase class and click Select.



Once the asset is created, name and open it to view the camera shake details.



Details

Camera shake assets have the following base details:

Name

Description

Single Instance

Enabling this will allow only a single instance of this shake to play at a time. Subsequent attempts to play this shake will restart it, instead of layering it additively.

Root Shake Pattern

The Shake Type to use.

Root Shake Pattern Types

Shake patterns control the shape and behavior of the camera shake. You are able to select from the following patterns to create a camera shake.

Perlin Noise

Perlin generates noise over time by sampling random points based on a specified amplitude and frequency. These points are blended to by using the Smootherstep easing function. Typically, Perlin noise is useful for high-intensity camera shakes such as rumbles or nearby explosions.





When you select Perlin Noise Camera Shake Pattern for your Root Shake Pattern, additional details will appear which you can use to control the Perlin noise shake behavior. It is possible to create a shake effect for the location, rotation, and Field of View (FOV) properties of a camera.



Both Location and Rotation property categories have their individual axes displayed, and you can expand them to reveal the Amplitude and Frequency properties.

Amplitude controls the size of the shake pattern. Increasing this will cause the shake on that axis to move a larger distance from the center.

Frequency controls the speed of the shake. Increasing this will cause the shake's movement to appear more rapid.



Additionally, you can multiply the combined Amplitude and Frequency results on your Location and Rotation axes by using their Amplitude and Frequency Multiplier properties. These properties are useful if you want to make global changes to your shake instead of needing to change each individual axis.



The timing of a shake can be controlled by expanding the Timing category.

Duration controls the length of the shake. If it is 0 or less than 0, then the shake will play infinitely.

Blend In/Out Time controls the length of a linear blend at the start and end of the shake. A value of 0 means no blending will occur.



Sinusoidal Wave

Sinusoidal Wave generates noise over time using a continuous wave with smooth periodic oscillation. Typically, wave noise is useful for lower-intensity shakes such as a rocking boat, or a dream-like drifting effect.





When you select Wave Oscillator Camera Shake Pattern for your Root Shake Pattern, additional details will appear which you can use to control the wave shake behavior. Similar to Perlin noise, it is possible to create a wave shake effect on the location, rotation, and Field of View (FOV) properties of a camera.



The properties of Location, Rotation, FOV, and Timing for Sinusoidal Wave noise are the same as Perlin Noise. However, when an axis is expanded, there is an additional property called Initial Offset Type from which you can specify if you want your waveform to begin at Zero or at a Random point along the curve.



Sequence Shake

Sequence shakes generates shakes using camera animation contained within Camera Animation Sequences. Sequence noise is useful in cases where you want full control over the camera's shake style and behavior.



When you select Sequence Camera Shake Pattern for your Root Shake Pattern, additional details will appear which you can use to select the Camera Animation Sequence asset, and control its behavior. The duration of the shake is based on the length of the camera animation sequence.



Name

Description

Sequence

Specifies your Camera Animation Sequence Asset.

Play Rate

The speed of the shake effect. A value of 1 is normal speed, values less than 1 will play the shake slower, and values higher than 1 will play faster.

Scale

A multiplier applied to the shake intensity. A value of 1 is normal intensity, values less than 1 will be less intense and values higher than 1 will be more intense.

Blend In/Out Time

Blend In/Out Time controls the length of a linear blend at the start and end of the shake. A value of 0 means no blending will occur.

Random Segment Duration

The duration of the random segment used if Random Segment is enabled.

Random Segment

Enabling this will start playing the shake at a random point in the camera animation sequence. You must also set a value in the Random Segment Duration property to define a new length for the shake. This is useful if you have a very long camera shake animation and want to play random smaller segments from it.

Unlike in typical Template Sequence workflows, when creating a Camera Animation Sequence for use as a camera shake pattern, you do not need to set the section to additive.

Composite

Composite shakes enable the combining of Perlin, Wave, and Sequence shakes in a layer system. Using Composite shakes, you can create more varied shakes that include elements from each shake type.



When you select Composite Camera Shake Pattern for your Root Shake Pattern, additional details will appear which you can use to add child patterns and layer different shake types together.



Clicking the + button next to Child Patterns will add a new shake pattern to the array. You can add as many shake patterns as you want. Each element contains details relevant to that pattern.



Playing Your Shake

Once you have created your camera shake, there are a couple of ways to play it.

Playing from Sequencer

You can add your shake to a camera in Sequencer by clicking the + Track button on the Cine Camera Actor track, and selecting your camera shake asset in the Camera Shake menu.



You can also add the shake to the CameraComponent track, which produces the same result.



Once added, you can play your sequence to see your shake in action.



The camera shake section contains visualizations for its duration and blend in / out times determined by the Blueprint details. Changing these properties will update the section display.



Right-clicking the shake section and navigating to the Properties menu will reveal the shake properties in Sequencer.



Name

Description

Shake Class

Specifies the shake Blueprint class to use. You can change this shake to a different asset if another is available.

Play Scale

A global multiplier for the shake intensity. A value of 1 is normal intensity, values less than 1 will be less intense and values higher than 1 will be more intense.

Play Space

Specifies the coordinate space the shake should play in.

Camera Local will cause the shake to be relative to the camera's position, making it an additive shake.

World will cause the shake coordinates to be relative to the Level's coordinates.

User Defined will cause the shake rotational coordinates to be relative to the coordinates specified in User Defined Play Space.

User Defined Play Space

When Play Space is set to User Defined, you can input rotation coordinates here, which are relative to the World Rotation coordinates, but with a specified offset.

Playing from Blueprints

You can also play shakes from Blueprints using the Start Camera Shake node. The node contains parameters for specifying the Shake, Scale, and Play Space.



The Start Camera Shake function requires a Player Controller or a Camera Shake Source Component as the target.

Camera Shake Source

The Camera Shake Source triggers camera shakes based on the camera's proximity to a location. It also contains controls for the size and radius of the shake influence. You can add it as an Actor in your Level, or as a Component in Blueprints.

To add a Camera Shake Source Actor to your Level, drag it from the Place Actors panel into your Level.



Selecting the Actor or Component will reveal the following details:



Name

Description

Attenuation

The falloff curve type as the camera gets closer or further away from the source. This can either be Quadratic, which provides an ease in and out blend, or Linear, which provides a linear blend.

Inner Attenuation Radius

The radius from the source in which the shake will play at its full intensity.

Outer Attenuation Radius

The radius from the source in which the shake will no longer be visible. The shake will blend its intensity between the outer and inner radius as the camera moves between them.

Camera Shake

The shake Blueprint class to use.

Auto Start

Enabling this will cause the shake to automatically start when playing the game.

Looping Shake Example

You can quickly create a source shake effect by doing the following:

In the Camera Shake Blueprint, set all Timing properties to 0. This will make the shake loop indefinitely with no blending. Also ensure you have set an appropriate amplitude and frequency on your axes so that the shake is visible.

Assign the Blueprint to the camera shake source Camera Shake property, and enable Auto Start.



Now when you play the game and approach the source point, you should see the shake blend on and off as the camera enters the influence of the camera shake source.



Camera Shake Previewer

The Camera Shake Previewer can be used to preview Camera Shake Sources in the editor without needing to start the game or simulation.

To open the previewer, navigate to Unreal Editor's main menu and select Window > Camera Shake Previewer.



In order for camera shakes to play in the editor, you will need to enable Allow Camera Shakes in the viewport options menu.



Next, select the shake source entry you want to preview and click Play/Stop Selected to enable the shake preview. You can also click Play/Stop All if you want to preview multiple sources at once. Once it is playing, you can move the editor's camera towards the source and see the shake effect.



Enabling the Cinematic Viewport

Overview

Film Overlays

Playback Preview and Controls

Allow Cinematic Control

In the Unreal Editor, you can change any Level Viewport to a specialized Cinematic Viewport. The Cinematic Viewport enables additional functionality, behavior, and display modes that can assist you with cinematic content creation. This guide gives an overview of how to enable the Cinematic Viewport and its features.

You have a project that is using Sequencer. You can use one of the provided Cinematic Samples if you don't already have one.

Sequencer is currently open in your Level.

Enabling the Cinematic Viewport

To enable the Cinematic Viewport mode, select the Viewport Perspective menu and enable Cinematic Viewport.



Overview

Once the Cinematic Viewport is enabled and Sequencer is opened, your viewport should now be displaying new cinematic elements.



Film Overlays

Playback Preview and Controls

Film Overlays

The Film Overlays menu contains visual guides for the viewport that you can enable to assist with your framing and composition. There are two main categories of overlays, Composition and Frame overlays.



Name

Description

Disabled

The default view mode, which does not display any overlay.

Grid (3x3)

Displays a 3x3 grid on the viewport, allowing for framing based on Rule of Thirds.



Grid (2x2)

Displays a 2x2 grid on the viewport.



Crosshair

Displays a central reticle, useful for emulating photography reticles.



Rabatment

Displays a rabatment overlay on the viewport, allowing for framing based on Rabatment of the Rectangle.



Composition overlay lines can also be tinted to any color or alpha value you want. Clicking the color bar next to Tint will open the Color Picker where you can select the color and transparency of the lines.



Frame Overlays are guidelines used to emulate Safe Areas or Letterboxing when framing your image.

Name

Description

Action Safe

Displays the "Action" safe guidelines. By default it appears to appear at 95% of the screen space margins and is colored red.



Title Safe

Displays the "Title" safe guidelines. By default it appears at 90% of the screen space margins and is colored yellow.



Custom Safe

Displays a custom safe guideline. By default it appears at 85% of the screen space margins and is colored green.



Letterbox Mask

Displays a letterbox overlay, showing what the target aspect ratio will crop out of the original image. By default the letterbox aspect ratio is 2.35:1.



You will need to ensure that the Constrain Aspect Ratio property is enabled on your Camera's Properties in order for the letterboxing to be accurate for your camera's sensor size.

Each safe region entry has a percentage field next to it, which corresponds to the screen size of the guideline. A value of 100% will make the guidelines reach the outer edges of the screen, and 0% will cause the guidelines to reach the centerpoint of the screen. The guideline ranges are clamped between 1% and 99% in order to remain fully visible.



You can input different letterbox aspect ratios next to the Letterbox Mask entry. Doing this will change the shape of the letterbox to conform to the input aspect ratio.



Both the safe and letterbox guidelines can be tinted to any color by clicking the color bar under their properties. Doing this will open the Color Picker where you can select the color and transparency of the guidelines.



Playback Preview and Controls

When the Cinematic Viewport is enabled, new controls and displays will appear at the bottom of the viewport.



The upper region of this area displays information about the current shot, camera, and timing.



The name of the current Sequence and current Camera.

The current camera's Filmback Properties.

The current Time of the sequence or Master Sequence.

A time bar is also displayed and can be interacted with by utilizing similar Playhead interactions from Sequencer. The displayed time bar synchronizes with the time bar in Sequencer.



The bottom region displays time and playback controls.



The start times of the Working Range and Playback Range.

The current time of the active sequence.

Playback Controls. These can be clicked to play, pause, and perform other playback functions.

The end time of the Playback Range and Working Range.

In the bottom region, the time displays can be interacted with by clicking them and typing in different values, or by clicking and dragging left and right to scrub their values.



Allow Cinematic Control

When working on cinematic content in Unreal Engine, you may want to use Multiple Viewports in order to preview your scene from different perspectives in conjunction with the main cinematic view. You can use the Allow Cinematic Control option to choose which viewport should display the cinematic when Sequencer has camera control.



Allow Cinematic Control can only be enabled or disabled on viewports using the Perspective view mode.

By default, Unreal Engine's primary viewport has Allow Cinematic Control enabled.



In situations where you have more than one viewport set to the Perspective viewport, you can choose which viewports will have the full cinematic control by enabling or disabling Allow Cinematic Control in the viewport options menu. In most cases, you will want to enable Allow Cinematic Control for at least one viewport, and leave it disabled for all others.



Cine Camera Actor

Creation

Behavior

Properties

Material

Material Setup

Media Texture and Player

Material Graph

Playback

Media Track Setup

Examples

The Image Plate Actor supports the playback of movies and image sequences from a plate attached to the frustum of a Cine Camera Actor. Using these image plates, you can playback full-screen videos and image sequences, as well as including foreground elements within the camera's perspective.

The Image Plate plugin must be enabled prior to use. Navigate in the Unreal Engine menu to Edit > Plugins, locate Image Plate in the Rendering section, and enable it. You may need to restart the editor for this change to come into effect.



You are familiar with how to set up a video asset for playback, or how to set up image sequences for playback.

You are familiar with the usage of the Media Track.

You are familiar with the basics of Materials.

You have an understanding of Sequencer and its Interface.

Creation

To fully set up the Image Plate Actor, you will need to add both a Cine Camera Actor and an Image Plate Actor to a Level, then attach the plate to the Cine Camera Actor.

First, add a Cine Camera Actor to your Level by navigating to the Cinematic tab in the Place Actors panel, and locate Cine Camera Actor. Drag it from the panel and into your viewport.



Next, add an Image Plate to your Level by dragging it from the Place Actors panel.



After both Actors have been added to your Level, attach the plate to the camera by dragging it onto the camera in the World Outliner panel. Once that is done, the Image Plate will snap to the front of the camera and resize to fit its view frustum.



Behavior

By default, the Image Plate will automatically adjust its size to fit the Cine Camera Actor's Sensor Dimensions, ensuring it will always be fully in the camera's view.



You can also move the plate toward and away from the camera to control the spacing between the plate and the camera. This spacing will allow more foreground elements to be included in the camera's view. The plate will also dynamically adjust its scale to ensure it will remain fully in view.



When Piloting the camera, the image plate will fill the screen and will stretch to conform to the camera's aspect ratio. You may also need to adjust your camera's focus distance to match the plate distance to ensure it remains in focus.



Properties

Selecting the Image Plate Actor will reveal its details in the Details panel.



The Fill Screen property enables automatic plate sizing to fit the camera's full view. When this is disabled, you can instead use the Fixed Size property to manually set the plate's size.



If Fill Screen is enabled, then you can use the Fill Screen Amount property to offset the plate's size as a percentage of the screen. X controls the percentage of the width of the screen, and Y controls the height.



Material

Expanding the advanced section of the Image Plate Details will reveal its Material properties. You can adjust the default material or texture here.



Material Setup

Regardless of if you are displaying an image sequence or a video on your plate, you will need to create a new Material that references a Media Texture. The Media Texture must also reference a Media Player.

Media Texture and Player

First, create the Media Player by clicking Add/Import in the Content Browser, navigating to the Media category, and selecting the Media Player asset. Once selected, a dialog window will appear. Ensure that Video output MediaTexture asset is enabled, and click OK.



Doing this will ensure that both a Media Texture and Media Player are created and linked.



Material Graph

Create a new Material asset by clicking Add/Import in the Content Browser, and selecting Material. Once it is created and opened, set the Shading Model to Unlit, and enable the Two Sided property in its details. This is done so that the image plate is not affected by any lighting in the Level.



Drag the Media Texture asset into the material graph and connect its RGB pin to the material's Emissive Color input pin.



Lastly, you will need to assign the media material to the Material property of the Image Plate Actor.



Playback

Videos and image sequences can be played on the image plate through Sequencer's Media Track.

Media Track Setup

Start by creating a new Level Sequence, then click + Track and select Media Track.



Next select a File Media Source (for videos) or Image Media Source (for image sequences) asset to play by clicking + Media and selecting a source. If you do not have one of these assets, refer to their setup instructions in either the Video or Image playback documents.



Right-click the media section, navigate to its properties category, and assign your media texture to the Media Texture property.



Examples

Once finished, you will be able to play your sequence and preview the video or image sequence displayed on your image plate.





Video Example







Image Sequence Example



Render Settings

Image Settings

Export Formats

Render Passes

Opening Movie Render Queue

Interface Overview

Toolbar

Jobs

Job Details

Start Render

Render Preview

Creating a Basic Render

Job Setup

Output Settings

Render

Usage in Blueprints

Movie Render Queue is Unreal Engine's image sequence and movie rendering solution. It is built for high-quality rendered images, simplified integration into production pipelines, and user extensibility.

Movie Render Queue supports several features for producing high-quality renders, such as its temporal subsampling feature which allows you to produce high-quality radial motion blurs. You can also export images containing translucent pixel values (using appropriate project / scene settings), generate 16-bit HDR images with linear data, and save render configurations into assets that you can reuse and share. Multiple jobs and their settings can be managed at once using the render queue, which supports the running of batch rendering jobs.

Movie Render Queue is a plugin that must be enabled prior to use. Navigate in the Unreal Engine menu to Edit > Plugins, locate Movie Render Queue in the Rendering section, and enable it. You will need to restart the editor afterward.



You have created a project with a Level Sequence for you to render. If you have not yet created a project, Samples and Tutorials and Meerkat Demo are also pre-made content examples that are available for use.

Opening Movie Render Queue

You can open the Movie Render Queue window two different ways

The first way is from Unreal Engine's main menu bar, from which you can click Window > Cinematics > Movie Render Queue.



Alternatively, from within Sequencer, click the Render Movie button in the toolbar. Make sure your default render tool is set to Movie Render Queue by clicking the dropdown menu. If not, Sequencer's legacy renderer tool will open instead.



After following one of the two options above, the Movie Render Queue window will now be open.



Interface Overview

The Movie Render Queue interface is comprised of four main areas:



Toolbar: Contains a menu for adding or removing render jobs and loading or saving the current job list.

Jobs: Displays the sequences to render in the order in which they are queued. Each top-level item in the list is considered a job. These items also contain the configuration settings for each job.

Job Details: Details for the selected job. Lists the name, the level sequence asset, the level to run during the job, and the author of this job.

Start Render: Starts the render either locally on your machine, or in a separate process on your machine.

Toolbar

The toolbar contains the menu for adding and removing jobs. To add a new sequence to the render queue, click the + Render button and select a Level Sequence Asset. Sequences can also be added to your job list by dragging them from the Content Browser to the job region.



To remove a sequence from the job list, select the job and click the - button or press the delete key on your keyboard



You can also save your current job list as a Queue Preset asset from the Toolbar. Click the Load/Save Queue button and then select Save As Asset. You will then be prompted to name and save the Movie Pipeline Queue asset somewhere in your project.



The preset will now be listed under the Load/Save Queue button. Selecting it will set your job list to match the saved preset.

This will import a copy of the queue into the jobs area, and changes made to the job list will not affect the asset unless you select Save as Asset and save over the existing preset.



Jobs

The jobs area contains a list of the Level sequences that will be rendered, along with their render settings and output directory.

You can expand a sequence to view its cameras. The list is generated from any Camera Cut Track sections in the sequence. You can also enable or disable any camera to prevent that section from being rendered.



Clicking the Settings entry for a job will open the settings window, where you can specify your output directory, rendering settings, and export format.



You can apply saved presets to your job by clicking the dropdown arrow and selecting a preset.



The Output area displays the folder directory where your images or videos will be rendered to, as set in the output setting. Clicking here will open a File Explorer window with this folder targeted.



Visit the Render Settings page for more information on customizing your renders.



Customize your render output and visuals with Movie Render Queue's Render Settings



Output your render using a variety of formats in Movie Render Queue.

Output your render using a variety of formats in Movie Render Queue.



Adjust the picture quality of your render with Movie Render Queue's Image Settings

Adjust the picture quality of your render with Movie Render Queue's Image Settings



Learn about the different render pass layers in Movie Render Queue.

Learn about the different render pass layers in Movie Render Queue.

Job Details

When a job is selected, you can view its details in the job details area.



This area lists the following fields for the selected job:

Name

Description

Job Name

The name of the job. This is set to the name of the level sequence asset by default but can be modified. The Job Name field is also displayed in the default Burn In overlay.

Sequence

The sequence asset reference. You can change which sequence is referenced here if you want to specify a different sequence for the job.

Map

The level to run when rendering. If your sequence uses Spawnables, you can render the same scene in different Levels.

Author

The author of the job. This field is automatically populated with your operating system user name.

Start Render



Render (Local) renders in the same process as Unreal Engine and launches a Play in Editor session to render from. You do not need to save your changes when performing a local render.

Render (Remote) launches a separate process that renders your jobs. You must save your changes in the project so the external process can read the saved files from disk.

The Remote option can be used to implement a remote render farm. The default behavior of the render options are determined by the Project Settings and can be adjusted to run your own code, which is helpful when using third party render farm management software. Additionally, the command used to launch the remote render process is written to the Output Log, which can be used as reference when building your own automated render farms.

Because you specify the Level asset to render in the Job Details, you do not need to have that same Level open when rendering. Movie Render Queue will automatically open the specified Levels when running the render job.

Render Preview

When a render job is running, Movie Render Queue will display a render preview window showing you the current visual state of the render with relevant information. The preview window will automatically close when the render is complete.



Render Preview: This view shows the current visual status of the render. As each frame is displayed here, they are also being saved to your output directory. The preview here is based on the latest sample data from your GPU and may appear at a lower quality than the final render. If you have enabled Tiling for your render, then the preview will only display the bottom-right corner tile.

Overall Render Progress: These details show the current sequence that is being rendered, as well as the overall progress, elapsed time, and estimated time remaining.

Current Camera Cut Progress: These details show the current camera being rendered, as well as the progress for the current camera cut.

Creating a Basic Render

You can create a basic render of your cinematic sequence by following these steps.

Job Setup

First, open the Movie Render Queue tool by clicking Window > Cinematics > Movie Render Queue.



Then add your sequence asset to the job list by clicking the + Render button and selecting your sequence.



Also ensure that the correct Level is set in the Map property.



Output Settings

Once your sequence is added, you may want to adjust some of the output settings such as the destination folder, resolution, and file type.

Click the Unsaved Config text to open the Render Settings window for that job.



By default, Movie Render Queue will render out to a sequence of .jpg images. If you want to change this, you can delete the .jpg Sequence [8bit] entry and click the + Setting button to pick a different output format.

Select the .jpg Sequence [8bit] entry and press Delete, then click the + Setting button and select .png Sequence [8bit].



The Deferred Rendering entry will cause the output to render the exact image you see in your viewport. For basic renders like this, you can leave this setting as-is, but it must exist here in order for your image to render.



Clicking Output will reveal typical output-related settings such as file name, directory, and resolution.

If you want to change the Output Directory field, click the … button next to the entry, navigate to a new folder, and press Select Folder. Your image sequence will now output here.



Close the Render Settings window once you are done making changes.

Render

You can now render your sequence.

Click Render (Local) to start the render job for your sequence. A Render Preview window will appear showing your current render progress.



Once the render has completed, the preview window will close. You can now navigate to the output folder by clicking the linked output text for your job and view your output image sequence.



Usage in Blueprints

You can use Movie Render Queue to render movies in runtime builds and output files to a user's computer using Blueprints. Visit the Movie Render Queue in Runtime Builds to learn more.



How to use Movie Render Queue in a distributed build to create movies on end-users' devices

How to use Movie Render Queue in a distributed build to create movies on end-users' devices

Movie Render Queue

Image Settings

Export Formats

Render Passes

Opening Render Settings

Interface Overview

Settings List

Settings

Exports

Rendering

Presets

Master

Shot

Editing Presets

The Render Settings in Movie Render Queue are used to customize how your sequences are rendered. These include additional rendering processes such as anti-aliasing, custom console commands, output format, rendering mode, and more.

This guide covers the settings interface, the list of settings that can be added, and the ability to save your settings as presets.

You have completed the prerequisite steps from the Movie Render Queue page.

Opening Render Settings

You can open the Render Settings window by clicking the Settings entry for your job.



Interface Overview

There are three main areas of the Render Settings window:



Toolbar: The toolbar contains a menu for adding additional settings and loading or saving the current setting list to a preset.

Settings List: The Settings List shows the current settings to apply to the job, and includes toggles to enable or disable them. Each setting is categorized into either Exports, Rendering, or Settings.

Settings Details: Shows the properties for the selected setting from the Settings List.

Settings List

Clicking the + Setting button will reveal the list of different settings you can add to your job. They are categorized into three groups; Settings, Exports, and Rendering.



Settings

The Settings category contains options for render quality options, console variables, and miscellaneous render options.

Name

Description

Output

The Output setting controls your output file's directory, file name, frame rate, and output resolution. Your file name and directory path can be customized using {token} format strings. Output is a required setting and cannot be deleted from the settings window.

Anti-Aliasing

Anti-aliasing controls the number of samples used to produce the final render. There are two types of sampling that produce the render: Spatial and Temporal.

Burn In

Burn In enables adding custom watermarks to your render, which contain information about the render and shot. You can choose whether the Burn In is added to the final image, or is rendered to a separate layer.

Camera

The Camera setting contains settings for the shutter timing and you can specify an overscan percentage to render extra pixels around the edges of your images.

Color Output

The Color Output setting overrides Unreal's default color space settings with a custom OpenColorIO (OCIO) configuration. You can also use it to disable the Tone Curve portion of post-processing even if not using an OCIO-based workflow.

Console Variables

Console Variables enables console commands to be designated when the render begins. This is useful when trying to apply quality settings that are too computationally expensive for real-time preview in the Editor. The variables will be reverted upon the render completing.

Debug Options

Debug Options contain options for debugging certain render behaviors. Typically you do not need to use these options unless you're troubleshooting issues within your renders.

Game Overrides

Game Overrides change several common game-related settings, such as Game Mode and Cinematic Quality settings. This is useful if the game's normal mode displays UI elements or loading screens that you do not want to capture.

High Resolution

The High Resolution settings enable the use of tiled renders to produce larger images without being constrained by maximum texture sizes or memory limits on GPUs.

Visit Image Settings for a more comprehensive look at these options.



Adjust the picture quality of your render with Movie Render Queue's Image Settings

Adjust the picture quality of your render with Movie Render Queue's Image Settings

Exports

The Exports category controls what image, audio, and video format you want to output your sequence to.

Name

Description

Command Line Encoder

The Command Line Encoder can be used to create your own output format from third party software, such as FFmpeg. This setting requires an encoder executable and settings to be enabled in your Project Settings.

Final Cut Pro XML

The Final Cut Pro XML format will output an XML file that can be read by Final Cut Pro and other video editing software that support this format. This is not supported in shipping builds.

.bmp Sequence [8bit]

Outputs the movie as a sequence of .bmp images. Pixel values are clamped in the [0-1] range, meaning that no HDR values are preserved. This applies sRGB encoding curve.

EXR Sequence

Outputs the movie as a sequence of .exr images. HDR values are preserved but if the Tone Curve is enabled, linear values are scaled to approximately the [0-1] range with only the brightest highlights going above one. Disabling the Tone Curve writes linear values in the [0-100] range or more depending on the intensity of lights and other bright objects. No sRGB encoding curve is applied to .exr targets.

.jpg Sequence [8bit]

Outputs the movie as a sequence of .jpg images. Applies sRGB encoding curve.

.png Sequence [8bit]

Outputs the movie as a sequence of .png images. Applies sRGB encoding curve. Transparency is supported by enabling Enable Alpha Channel Support in Post Processing project setting.

WAV Audio

Outputs a .wav audio file alongside any other output formats you have selected.

Apple ProRes Video Codecs

Outputs a .mov file using Apple ProRes, which is Apple's high-quality, lossy video compression codec. This requires the Apple ProRes Media plugin to be enabled.

Avid DNx Video Codecs

Outputs a movie file using Avid DNx, which is a high-definition lossy video codec. This requires the Avid DNxHR/DNxMXF Media plugin to be enabled.

Prestreaming Recorder

The Prestreaming Recorder is used to create render caches for cinematics using Virtual Textures or Nanite.

More than one export item can be specified for any given sequence. For example, you may choose to export your sequence as both a .jpg image sequence and .wav audio file to combine in your video editing software.

Visit the Export Formats page for a more comprehensive look at these options.



Output your render using a variety of formats in Movie Render Queue.

Output your render using a variety of formats in Movie Render Queue.

Rendering

The Rendering category contains options for outputting different view-mode images and render passes.

Name

Description

Deferred Rendering

Outputs the final image for the sequence, matching what you see in the viewport.

Deferred Rendering (Detail Lighting)

Outputs using a special shader variation which only displays lighting combined with normal maps. Can be useful to show off the geometry of a Level.

Deferred Rendering (Lighting Only)

Similar to Detail Lighting but without normal maps affecting the lighting.

Path Tracer

Displays path-tracing data as it is calculated for each frame. Not all rendering features are supported by the Path Tracer at this time.

Deferred Rendering (Reflections Only)

Outputs using a special shader variation which makes everything in the world reflective.

Deferred Rendering (Unlit)

Outputs using a special shader variation which displays only base color, with no lighting information.

UI Renderer

Includes any UMG widgets that have been added to the viewport in the output render. This is an experimental feature.

Object Ids (Limited)

The Object Ids render pass outputs an image where components in the scene are assigned an ID. IDs can be grouped individually, or based on other factors such as material, folder, or Actor name. This requires the Movie Render Queue Additional Passes plugin to be enabled. Object Ids are not supported in shipping builds.

Visit the Render Passes Page for a more comprehensive look at these options.



Learn about the different render pass layers in Movie Render Queue.

Learn about the different render pass layers in Movie Render Queue.

Presets

By default, render settings are temporarily set for your editor session and will be lost once the session is closed. You can save your settings as Presets to allow for project-wide sharing or for different settings to be used for different sequences.

There are two types of presets that can be saved and reused: Master and Shot.

Master

Master presets are meant to be applied to the top-level job in order to propagate their settings to the camera cuts beneath them.

To save your current settings as a master config, click Load/Save Preset and select Save As Preset. You will then be prompted to save a Movie Pipeline Master Config Asset.



You can then apply this preset to a job in your queue by clicking the dropdown menu in the settings field and selecting the saved Movie Pipeline Master Config Asset.



Shot

Shot presets allow for overriding render settings per camera in your render. These may be useful if certain shots in your cinematic sequence require different settings from those that are being applied from the Master.

To save and use Shot presets, expand a job in your render queue to view its child cameras. Each camera has its own settings field that can be overwritten. Click one of the Edit fields to open the settings window for that camera.



You can add settings by clicking the + Setting button and selecting a setting from the list.

You cannot add Export category settings or change the output directory for shot settings, as settings at this level cannot conflict with required settings from the Master.

To save your current settings as a shot preset, click Load/Save Preset and select Save As Preset. You will then be prompted to save a Movie Pipeline Shot Config Asset.



Similar to applying a Master preset, you can apply this preset to a specific shot in your queue by clicking the dropdown menu in the settings field and selecting the saved Movie Pipeline Shot Config Asset.



Master and Shot Config Assets are different asset types and cannot be used interchangeably.

Editing Presets

When you have assigned a preset in the Settings column, it will change to match that preset's name. If you click a preset you will be taken to the configuration editor where you can edit the configuration. These edits do not change the preset asset, they are only modifying a temporary copy of that preset.

If you would like to modify the presets directly, you have two options:

You can open the editor through the Movie Render Queue UI and choose Save as Preset and overwrite the preset that already exists.

You can open and edit them directly by double-clicking them in the Content Browser. This will bring up an editor from which you can add settings, edit their values and save the changes using the asset's Save buttons.

Render Settings

Movie Render Queue

Command Line Encoder

Export Details

Project Settings

Example Setup

EXR Sequence

Apple ProRes Video Codecs

Avid DNx Video Codecs

Final Cut Pro XML

WAV Audio

Custom Output Formats

Prestreaming Recorder

Movie Render Queue supports a variety of output formats for rendering to images or movies, and is capable of outputting different formats at the same time.

You have completed the prerequisite steps from the Movie Render Queue page.

You can choose which formats you want to render in Movie Render Queue's Settings window by clicking the + Setting dropdown menu and selecting a format from the Export category.

You can enable and disable output formats as you would with any other setting by clicking on the enable button next to their text. You can also select them to edit their properties, if available.

The following output formats are available:

Name

Description

Command Line Encoder

The Command Line Encoder can be used to create your own output format from third party software, such as FFmpeg. This setting requires an encoder executable and settings to be enabled in your Project Settings.

Final Cut Pro XML

The Final Cut Pro XML format will output an XML file that can be read by Final Cut Pro and other video editing software that support this format. This is not supported in shipping builds.

.bmp Sequence [8bit]

Outputs the movie as a sequence of .bmp images. Pixel values are clamped in the [0-1] range, meaning that no HDR values are preserved. This applies sRGB encoding curve.

EXR Sequence

Outputs the movie as a sequence of .exr images. HDR values are preserved but if the Tone Curve is enabled, linear values are scaled to approximately the [0-1] range with only the brightest highlights going above one. Disabling the Tone Curve writes linear values in the [0-100] range or more depending on the intensity of lights and other bright objects. No sRGB encoding curve is applied to .exr targets.

.jpg Sequence [8bit]

Outputs the movie as a sequence of .jpg images. Applies sRGB encoding curve.

.png Sequence [8bit]

Outputs the movie as a sequence of .png images. Applies sRGB encoding curve. Transparency is supported by enabling Enable Alpha Channel Support in Post Processing project setting.

WAV Audio

Outputs a .wav audio file alongside any other output formats you have selected.

Apple ProRes Video Codecs

Outputs a .mov file using Apple ProRes, which is Apple's high-quality, lossy video compression codec. This requires the Apple ProRes Media plugin to be enabled.

Avid DNx Video Codecs

Outputs a movie file using Avid DNx, which is a high-definition lossy video codec. This requires the Avid DNxHR/DNxMXF Media plugin to be enabled.

Prestreaming Recorder

The Prestreaming Recorder is used to create render caches for cinematics using Virtual Textures or Nanite.

Command Line Encoder

The Command Line Encoder can be used to create your own output format from 3rd party software, such as FFmpeg. To use Command Line Encoder, you must navigate to the Movie Pipeline CLI Encoder project setting to set up certain properties and settings.

If you use the Command Line Encoder, you must accompany it with an image sequence export format too, in order for it to create movie frames from those images. If you want to include audio, you must also include a .wav Audio export.



Export Details

Selecting Command Line Encoder will reveal the following details:



Detail Name

Description

File Name Format Override

Overrides the File Name Format from the Output setting for the movie that the Command Line Encoder outputs. You can use this to generate a single master movie file, instead of individual shot movie files if you are rendering your image sequences to separate shot folders.

Quality

What encoding quality settings to use. These can be defined in the Movie Pipeline CLI Encoder project setting.

Additional Command Line Args

Any additional command line arguments to pass to the encoder for this job.

Delete Source Files

If enabled, deletes the source image sequence files after the movie encoding is completed. This will result in only the movie being exported, without the source images.

Skip Encode on Render Canceled

If enabled, the encoder will not attempt to encode whatever frames were rendered if the render was cancelled prematurely.

Write Each Frame Duration

Writes the duration for each frame into the generated texture file. This is needed for some input types on some CLI encoding software.

Project Settings

You will be required to set up certain project settings in order to use Command Line Encoder.

Click on Edit > Project Settings to open the project settings window and navigate to Movie Pipeline CLI Encoder in the Plugins category.



Detail Name

Description

Executable Path

The path, including executable name, to the encoder executable file.

Can either be a direct path, such as ‪D:\ffmpeg\bin\ffmpeg.exe.

Or, if you have designated your encoder's path in Windows Environment Variables, you can just specify your encoder executable.

Codec Help Text

Text for your project to paste into Unreal's console window to generate a list of valid audio and video codecs for your encoder. Requires the Executable Path to be set first as the command queries the executable.

Video Codec

Specify the video codec here. If using FFmpeg, you can see the list of codecs by executing MovieRenderPipeline.DumpCLIEncoderCodecs in Unreal's Output Log window.

Audio Codec

Specify the audio codec here. If using FFmpeg, you can see the list of codecs by executing MovieRenderPipeline.DumpCLIEncoderCodecs in Unreal's Output Log window. An audio codec must be specified if -acodec {AudioCodec} is being specified in the command line.

Output File Extension

Extension for the output file and should not include the period, such as mp4, mkv, or webm. Certain codecs support different containers and you should ensure you are using the correct container for your codec.

Command Line Format

The format string to use when building the final command line argument to launch. Uses {tokens} to insert arguments from your project setting or Command Line Encoder details.

{AdditionalLocalArgs}: Inserts arguments here from the Additional Command Line Args property in the Command Line Encoder details.

{VideoInputs}: Inserts argument here from the Video Input String Format project setting.

{AudioInputs}: Inserts argument here from the Audio Input String Format project setting.

{AudioCodec}: Inserts argument here from the Audio Codec project setting.

{VideoCodec}: Inserts argument here from the Video Codec project setting.

{Quality}: Inserts arguments here from the Quality property in the Command Line Encoder details, then defined by the Encode Settings project setting.

{OutputPath}: Inserts arguments here from the Output Directory property in the Movie Render Queue's output details.

Video Input String Format

The format string to use when building the video input argument. Uses {tokens} to insert arguments from your image sequence.

{InputFile}: When your render is occurring, a temporary text file is created which itemizes every frame being rendered in sequence. This token references that file in order to find the frames to produce the video. By default this text file is automatically deleted after encoding finishes. You can keep this text file by enabling the Write All Samples property from the Debug Options setting.

{FrameRate}: The frame rate from either the Level Sequence, or the Output Frame Rate if Use Custom Frame Rate is enabled from the job's Output.

Audio Input String Format

The format string to use when building the audio input argument. Uses {tokens} to insert arguments from your .wav file output.

{InputFile}: When your render is occurring, a temporary text file is created which itemizes the audio being created. This token references that file in order to find the audio to add to the video. This text file can be saved by enabling the Write All Samples property from the Debug Options setting.

Encode Settings Low

The encoding argument to use when Low is specified from the Quality property in the Command Line Encoder details.

Encode Settings Med

The encoding argument to use when Med is specified from the Quality property in the Command Line Encoder details.

Encode Settings High

The encoding argument to use when High is specified from the Quality property in the Command Line Encoder details.

Encode Settings Epic

The encoding argument to use when Epic is specified from the Quality property in the Command Line Encoder details.

Your Encode Settings may need to be different depending on the codecs being used. The default values are considered a typical setting for the most common codecs you may use with FFmpeg. Only single pass encoding is supported with Command Line Encoder. You can reference FFmpeg Codec Documentation for more information on codecs and their encoding settings.

Example Setup

The following shows an example of what details and project settings you can use if you want to set up your encoder to use ffmpeg with the open format VP9 codec.

Here you can see that the Command Line Encoder is being exported along with .jpg Sequence and .wav Audio.



In the Project Settings, the highlighted properties are the only ones that have been altered from their default values in order to support the codec. If you are not exporting a .wav audio pass, then it is not necessary to specify an Audio Codec.



Video Codec: libvpx-vp9

Audio Codec: libvorbis

Output File Extension: mkv

Encode Settings Low: -crf 28 -b:v 0

Encode Settings Med: -crf 23 -b:v 0

Encode Settings High: -crf 20 -b:v 0

Encode Settings Epic: -crf 16 -b:v 0

EXR Sequence

Unreal supports .exr image sequences as an output format for Movie Render Queue. These are compatible with a variety of visual effects packages, including Nuke, Tweak RV, IfranView, and Adobe Premiere with the ProEXR plugin.



Currently, EXR output supports the following compression settings:

EXR

Description

None

Applies no compression to the render output for the .exr sequence.

PIZ

A lossless compression format that provides good quality for grainy images.

ZIP

A lossless compression format that provides good quality for images with low amounts of noise.

Unreal also supports the use of Multilayer .exr output. If you enable multiple different Render Passes, each of them will be embedded into your .exr sequence, and they will all be separately accessible in your external visual effects editing program.

Not all software supports multi-layered .exr files. In these cases, they will only show the default RGBA channels when you load the .exr. If you are using a program that does not support multi-layered .exrs, you can uncheck the Multilayer setting to write out each layer as an individual .exr file.

Apple ProRes Video Codecs

Apple ProRes is Apple's high-quality, lossy video compression format for post-production and visual effects, which supports up to 8k video.

To use it, you must enable it's plugin. Navigate in the Unreal Engine menu to Edit > Plugins, locate Apple ProRes Media in the Media Players section, and enable it. You will need to restart the editor afterward.

Apple ProRes [10-12bit] will now be available in the Settings menu. When you select this output format, your render will output a video file using one of several codecs, each providing a different level of compression and quality. The video container will be .mov.



Click the Codec dropdown to select your desired codec for the output video file. The following codecs are available:

Codec

Pixel depth

Estimated Bitrate at 1080p and 30 fps

Description

Apple ProRes 422 Proxy

10 bit

45 mbps

Highest compression. Intended for use in offline workflows that require low data rates but full-resolution video.

Apple ProRes 422 LT

10 bit

100 mbps

A more compressed version of Apple ProRes 422, estimated at roughly 30% smaller file size. Intended for environments with limited storage and data rate.

Apple ProRes 422

10 bit

150 mbps

High quality compression for full-width 4:2:2 video sources. Intended for multistream, real-time editing.

Apple ProRes 422 HQ

10 bit

220 mbps

A higher bit-rate version of Apple ProRes 422. Offers the same level of quality as ProRes 4444, but for 4:2:2 video sources.

Apple ProRes 4444

12 bit

330 mbps

High-quality compression format for 4:4:4:4 image sources. Provides an extremely high-quality image and supports alpha channels. Output files are very large.

Apple ProRes 4444 XQ

12 bit

500 mbps

Highest-quality storage with support for alpha channels. 12 bits of precision for RGB channels and 16 bits for alpha. Output files are extremely large.

For more information about each of these codecs, see Apple's documentation on Apple ProRes.

The Drop Frame Timecode setting will set the timecode track to use the drop-frame format. This is only applicable if your sequence has a framerate of 29.97.

If you enable Override Maximum Encoding Threads, you can set the Max Number of Encoding Threads to a manual number. This sets the maximum number of CPU threads that you want to allow the codec to use in the encoding process for the video file. Using more threads will make encoding faster, but will result in a higher CPU usage.

Apple ProRes does not export any audio. Add a .wav Audio export setting to output a separate .wav file alongside your video so that you can combine them in post-production.

Avid DNx Video Codecs

Avid DNxHR and DNxMXF are Avid's high-definition lossy video codecs for post-production, which support up to 8k video.

To use them, you must enable their plugin. Navigate in the Unreal Engine menu to Edit > Plugins, locate Avid DNxHR/DNxMXF Media Plugin in the Media Players section, and enable it. You will need to restart the editor afterward.



Avid DNx [8bit] will now be available as an output setting. When you select this setting, it will output your movie as a video file using Avid's DNx codec. The video container will be .mxf.



Enabling Use Compression will output a lossy, compressed file, while disabling it will output a lossless, uncompressed file. You can change the Number of Encoding Threads to control how many CPU threads you want the codec to use for encoding. Using a higher number of threads will decrease the amount of time required to encode the file, but will result in a higher CPU usage.

Refer to Avid's documentation on the DNx video codecs for more information regarding this codec and its specifications.

Avid DNx does not export any audio. Add a .wav Audio export setting to output a separate .wav file alongside your video so that you can combine them in post-production. At this time, Avid DNx only supports 8-bit precision regardless of codec.

Final Cut Pro XML

The Final Cut Pro XML format will output an XML file that can be read by Final Cut Pro and other video editors that support this format. Similar to Command Line Encoder, you are also required to specify an accompanying image sequence or video file output along side this export format.



Use the File Name Format Override field to specify a {token} for the name of your output files. These tokens are based on the ones from your Output settings.

The Data Source dropdown menu specifies the method for building the Final Cut Pro XML file, which in turn decides what data is embedded in the file and how it will be formatted.

Data Source

Description

Output Metadata

Builds the XML file based on the files that were actually written to disk, instead of based on the original Level Sequence data. This will support time dilation tracks (which will cause shots to have more/less frames than the actual Shot section in Sequencer) and does not support being reimported back into Sequencer later.

Sequence Data

Builds the XML file directly from sequence data. Intended for use in re-importing.

Final Cut XML is only supported as an output format for Unreal Editor. It is not available for use in shipping builds, as it depends on editor-only functionality.

WAV Audio

You can export .wav audio of your sequences without needing an additional rendering pass. This enables you to output a movie's audio and combine it with your image sequences in post-production.



Use the File Name Format Override field to override the File Name Format from the Output setting for the exported .wav file.

The WAV Audio output format is experimental and may not be production ready. Because the movie renderer runs the engine between shots for warmup frames, audio that is not controlled by Sequencer will have gaps between shots. Additionally, there may be minor audio distortion on audio clips in Sequencer between shots.

Custom Output Formats

You can create your own format by implementing the UMoviePipelineOutputBase class, which gives you a callback for each output frame containing all render passes rendered in that frame (such as burn-ins, UI widgets, and the final image). By implementing the class in your project's code, it will automatically show up in the Settings menu for use. You will need to link against the MovieRenderPipelineCore module.

If you want to ensure this output format is added to every new job created with the UI, you can adjust the Default Job Setting Classes specified in the Movie Render Pipeline Project settings.

Prestreaming Recorder

The Prestreaming Recorder option is only available if you have enabled the Cinematic Prestreaming Plugin and is used to create render caches for cinematics using Virtual Textures and Nanite.



Due to how Virtual Textures and Nanite stream their data, you must first render using the Prestreaming Recorder to build a cache for the Cinematic Prestreaming system to interpret. This cache automatically saves and gets referenced within the sequence being rendered. With it, Sequencer uses this data to inform the Virtual Texture and Nanite systems which content is required for a frame before it is needed, allowing the required data to already be on the GPU when the frame is rendered. Without it, Nanite and Virtual Textures will have a delay between being shown and reaching their target quality, potentially causing lower resolution or quality on textures and geometry during a cinematic.



Building a prestreaming cache isn't only for MRQ renders. The Cinematic Presteaming track and its data cache can also inform streaming of Virtual Textures in real-time sequences. This requires your real-time cinematics to be mostly deterministic, as the cache only contains data for what was rendered at that time. When the cache has no data available, it reverts back to the regular runtime latency seen in these systems.

The Prestreaming Recorder contains the following properties:

Data Source

Description

Package Directory

The directory, relative to your project root folder, to save the Cinematic Prestreaming data cache. This must start with /Game/, and it can also use normal format strings.



Virtual Textures

Enables capture of Virtual Texture page requests. Disabling this prevents any Virtual Textures information from being gathered to build the Cinematic Prestreaming cache.

Nanite

Enables capture of Nanite requests. Disabling this prevents any Nanite information from being gathered to build the Cinematic Prestreaming cache.

Modify Target Sequence

Enables the Cinematic Prestreaming Recorder to automatically add the cache playback data to the Level Sequence after the render completes.

Disable Advance Render Features

If enabled, this disables several rendering features, such as lighting, post processing, reflections. Disabling these can speed up your render, but causes the actual output render images to be very basic and unusable.

It can be useful to enable this, since the primary purpose of the Prestreaming Recorder is to build the Cinematic Prestreaming cache, not render.

Nanite and Virtual Textures are screen resolution dependent, which means you must render your cinematic with the Prestreaming Recorder at your target resolution to generate accurate cache data. It will also need to be re-rendered if your content changes drastically, such as the transforms of objects, edits to materials, or other changes.

You can also add the VT Pending Mips (Debug) render pass, which exports additional frames to your output directory. These frames can be used to debug Virtual Texture mip information.

Render Settings

Movie Render Queue

Output

Format String Information

Anti-Aliasing

Burn In

Camera

Color Output

Console Variables

Debug Options

Game Overrides

High Resolution

You can add a variety of settings to jobs in the Movie Render Queue. These include additional rendering settings like anti-aliasing, color output adjustments, console commands, and more.

You have completed the prerequisite steps from the Movie Render Queue page.

You can choose which settings you want to add by clicking the + Setting dropdown menu in the Movie Render Queue's window and selecting an item under the Settings category.



Once added, you can enable and disable them using the toggle switch, and you can select them to customize their properties.

Name

Description

Output

The Output setting controls your output file's directory, file name, frame rate, and output resolution. Your file name and directory path can be customized using {token} format strings. Output is a required setting and cannot be deleted from the settings window.

Anti-Aliasing

Anti-aliasing controls the number of samples used to produce the final render. There are two types of sampling that produce the render: Spatial and Temporal.

Burn In

Burn In enables adding custom watermarks to your render, which contain information about the render and shot. You can choose whether the Burn In is added to the final image, or is rendered to a separate layer.

Camera

The Camera setting contains settings for the shutter timing and you can specify an overscan percentage to render extra pixels around the edges of your images.

Color Output

The Color Output setting overrides Unreal's default color space settings with a custom OpenColorIO (OCIO) configuration. You can also use it to disable the Tone Curve portion of post-processing even if not using an OCIO-based workflow.

Console Variables

Console Variables enables console commands to be designated when the render begins. This is useful when trying to apply quality settings that are too computationally expensive for real-time preview in the Editor. The variables will be reverted upon the render completing.

Debug Options

Debug Options contain options for debugging certain render behaviors. Typically you do not need to use these options unless you're troubleshooting issues within your renders.

Game Overrides

Game Overrides change several common game-related settings, such as Game Mode and Cinematic Quality settings. This is useful if the game's normal mode displays UI elements or loading screens that you do not want to capture.

High Resolution

The High Resolution settings enable the use of tiled renders to produce larger images without being constrained by maximum texture sizes or memory limits on GPUs.

Output

Output contains settings related to the sequence's resolution and file formatting. Output is a required setting and cannot be deleted from the settings window.



Property

Description

Output Directory

Designates the file directory where the export saves.

File Name Format

Determines the file name format given to the export. You can use format string tokens to allow for custom naming. Slashes (/) can also be used here to designate subfolders relative to the Output Directory.

Output Resolution

Determines the export resolution.

Use Custom Frame Rate

Enables you to use a custom frame rate different from the one in the Level Sequence.

Output Frame Rate

Determines the new framerate if you enabled Use Custom Frame Rate.

Override Existing Output

Enables you to automatically overwrite any files with the same file name. If disabled, an integer, such as 1, will be appended to the file name.

Zero Pad Frame Numbers

Determines how many numbers to pad the output frame numbers. For example a value of 2 will output _01, and a value of 4 will output _0001 for your file name suffix.

Frame Number Offset

Adds a specified number to the frame numbers when writing to the disk during rendering. This allows you to offset issues regarding negative numbers for labeling frames, which confuses most software. So, instead of writing -2, -1, 0, 1 to the disk, you can write out 98, 99, 100, 101 by setting the Frame Number Offset to 100.

Handle Frame Count

Determines the number of frame handles to include for each shot. This will expand each shot section by the given number of frames on both sides and render them.

Output Frame Step

The amount of frames to skip for every frame. For example, setting the value to 2 sets the rendering to every other frame. For the frames that are skipped, the game will still tick to make the results between rendering every frame and every stepped frame more consistent. Some image quality differences will be visible (due to a different temporal history). This feature is experimental.

Use Custom Playback Range

Enables you to designate a custom playback range different from the sequence.

Custom Start Frame

Determines the frame start if you enabled Custom Playback Range. Start frame is Inclusive.

Custom End Frame

Determines the frame end if you enabled Custom Playback Range. End frame is Exclusive, so a Start Time of 0 and an End Time of 1 will render only one frame (frame 0).

Auto Version

If enabled, Movie Render Queue will check the most recent version number from the last render in the output directory, increment it by 1, then use that value for the next render's version number.

Version Number

If Auto Version is disabled, the value in this field will be used as the version number for the render output if using the {version} token.

Format String Information

The File Name Format property allows for using custom tokens, known as Format Strings to allow for customizing a file name format. When a token is specified in the file name format, it will be replaced with the intended name when the files are being rendered and saved.



The following tokens are available for you to use:

Token Name

Description

{level_name}

The name of the level the render is occurring in.

{sequence_name}

The Level Sequence Asset name.

{frame_rate}

The frame rate of the sequence, or the overridden frame rate if Use Custom Frame Rate is enabled.

{date}

Today's date, formatted by {year}.{month}.{day}.

{year}

The current year when the render begins.

{month}

The current month when the render begins.

{day}

The current day when the render begins.

{time}

The current time when the render begins, formatted by {hours}.{minutes}.{seconds}. Uses a 24 hour clock scale.

{frame_number}

The frame number of the sequence being rendered. This token will be stripped for any video output, as it is meant only for image sequence files.

{frame_number_shot}

The frame number of the shot being rendered. This token will be stripped for any video output, as it is meant only for image sequence files.

{frame_number_rel}

The frame number of the sequence being rendered, relative to 0 regardless of the frame start number. Useful if you have sequences that begin in negative regions. This token will be stripped for any video output, as it is meant only for image sequence files. If using time dilation, this value will be used for {frame_number} as well.

{frame_number_shot_rel}

The frame number of the shot being rendered, relative to 0 regardless of the frame start number. Useful if you have sequences that begin in negative regions. This token will be stripped for any video output, as it is meant only for image sequence files. If using time dilation, this value will be used for {frame_number_shot} as well.

{camera_name}

The currently active camera actor name in Sequencer.

{shot_name}

The name of the Shot Section in the Level Sequence, otherwise falls back to sequence asset names.

{render_pass}

Will be replaced with the name of the Render Pass the image is for during rendering. Automatically inserted if rendering multiple render passes to ensure final images have unique names.

{output_resolution}

The full output resolution, formatted by {width}_{height}.

{output_width}

The output resolution's width.

{output_height}

The output resolution's height.

{version}

The version number defined by either Auto Version or Version Number.



These tokens become available to use as you add settings to your list.



{ts_count}

The Temporal Sample count of your Anti-aliasing setting, if Anti-Aliasing is being used.

{ss_count}

The Spatial Sample count of your Anti-aliasing setting, if Anti-Aliasing is being used.

{shutter_timing}

The Shutter Timing property of your Camera setting, if Camera is being used.

{overscan_percentage}

The Overscan Percentage property of your Camera setting, if Camera is being used.

{tile_count}

The Tile Count property of your High Resolution setting, if High Resolution is being used.

{overlap_percent}

The Overlap Ratio property of your High Resolution setting, if High Resolution is being used.

Anti-Aliasing

Anti-Aliasing controls the number of samples used to produce a final frame. The Movie Render Queue adds the ability to combine multiple renders together to produce a final frame. This significantly increases the quality of anti-aliasing, motion blur, and can decrease noise from ray tracing. There are two types of sampling that produce the final frame: Temporal and Spatial.



Temporal sampling takes the time the camera shutter is open (based on the camera/post-processing Motion Blur Amount setting) and slices the frame into corresponding time slices. The engine then evaluates at the center of each time slice while using the standard engine motion blur to interpolate between each time slice. This enables rotational motion blur by representing the motion blur as many small directional motion blurs.

Because the engine is ticked (and by extension time passes in the world) these are called temporal samples. For each temporal sample, there are as many renders accumulated according to the Spatial Sample Count variable. Using too many temporal samples will create too small of a delta time for the engine to handle and will result in warnings after a render.

Spatial sampling takes each sample that is going to be rendered and renders it multiple times, each time jittering the camera a little bit. This is useful for renders where you have a very short motion blur duration and still need more samples to increase anti-aliasing or reduce noise.

Any combination of spatial and temporal sampling produces the same pattern of offsets used for anti-aliasing. This means that it is generally more efficient to put your samples into temporal sampling instead of spatial, since non-moving objects will receive the same anti-aliasing, and moving objects will be blurred, hiding the aliasing.

Increasing the Temporal Sample count will result in smoother, radial motion blur.



You can use Spatial and Temporal sampling with TAA to experiment with anti-aliasing results, though it is not recommended in most cases. If TAA is enabled then there is a limit on how many unique positions are chosen for anti-aliasing. This limit is defined by r.TemporalAASamples, which defaults to 8. If TAA is enabled and you have more than 8 samples, you should enable Override Anti-Aliasing and set it to None to disable TAA, or increase r.TemporalAASamples to match the sample count resulting from Spatial Count x Temporal Count.

If you use a Temporal Sample Count higher than 1, the sequence will be evaluated on either side of the frame. This means that you will need to extend your tracks in Sequencer to cover the time one frame before the start of your sequence, otherwise there will be no data to sample. Sections will be auto-expanded to cover the timespan evaluated by the first temporal sample. Some track types, like animation or audio, cannot automatically be expanded and will be skipped. You will be notified post render which sections need to be expanded by hand.

Name

Description

Spatial Sample Count

Determines how many accumulated renders are in each Temporal Sample.

Temporal Sample Count

Determines how many time intervals each frame is divided into.

Override Anti-Aliasing

Enables you to choose a different anti-aliasing method using the Anti-Aliasing Method property.

Anti Aliasing Method

When Override Anti-Aliasing is enabled, this field will select the desired anti-aliasing method.

None: Disables anti-aliasing. Recommended if you are using 8 or more spatial/temporal samples.

FXAA: Smooths jagged pixels in screen-space rather than using data from the 3D meshes in the world, which is faster than TAA or MSAA, but less precise for fine details.

TemporalAA: Uses Temporal Anti-Aliasing. This is the default algorithm for motion blur used in Unreal Engine which uses the information from previous frames to anti-alias the current frame. May cause ghosting, especially if a moving object is in front of a noisy background.

MSAA: Not supported.

Use Camera Cut for Warm Up

When enabled, the system will determine the amount of warmup frames based on the Camera Cut section before the start time. This feature will cause these frames to be evaluated during warmup which enables you to have characters animate from their reference pose with cloth, or have particles/cloth appear to continue motion from the previous shot.



Render Warm Up Frames

If enabled, Movie Render Queue will submit each Engine Warm Up frame to the GPU to be rendered. This can be useful if your content must be rendered to properly warm up, such as GPU particles or virtual texturing. If disabled Engine Warm Up frames will tick the game thread but not submit renders to the GPU.

Render Warm Up Count

Controls the number of samples used to build the temporal history before rendering begins. When a camera cut or shot occurs, the temporal history used by TAA is cleared to prevent "ghosts" from the previous camera angle appearing. To allow anti-aliasing on the first frame, this history must be rebuilt. All samples are taken at the same time without ticking the engine between them. This happens immediately before rendering starts regardless of the number of Engine Warm Up Count frames or whether or not Render Warm Up Frames is enabled.

Engine Warm Up Count

Indicates the number of frames to run the engine for before rendering begins. These frames are not submitted to the GPU unless Render Warm Up Frames is enabled. Typically the warmup is useful when you need time for cloth physics, particles, or other dynamics to settle into the right position before rendering starts.

Burn In

Burn In allows for adding custom watermarks to your render, typically these would be timecode related. You can choose whether the burn in is applied to the final image, or rendered to a separate layer



The Burn In image has the following display format:



Job name.

Date and Time when render begins.

The Level name.

The author of the render, defined by the Job Details.

The source control changelist and branch the current render was made on.

The current frame and time of the Master sequence.

Focal Length, f-stop, and focal distance in milimeters of the current camera.

The current frame and time of the shot sequence.

Camera

The Camera setting changes how motion blur is presented and allows for overscanning.



Name

Description

Shutter Timing

Shutter Timing controls the bias of the motion blur angle to either be before, during, or after a frame.

Frame Open represents the shutter opening, so the motion blur represented is what comes after a frame in Sequencer.

Frame Center has an equal bias between Frame Open and Close, causing motion blur to be centered between before and after frames.

Frame Close represents the shutter closing, so the motion blur represented is what comes before a frame in Sequencer.

Overscan Percentage

Increasing this value will enable rendering additional pixels beyond the output resolution based on a percentage multiplied against the Output Resolution. The camera Field of view is also inflated proportionally to this percentage so that the original image within the non-overscanned region is maintained. This property is meant to be used primarily with the EXR output format, as it encodes the region information into a format unique to EXR. It will work with other formats but the final output resolution will be larger than expected and the framing of the shot will have changed.

Render All Cameras

Enabling this causes all Cameras to be rendered separately, allowing this sequence or shot to be rendered from multiple angles.

Color Output

The Color Output setting overrides the default color space settings with a custom Open Color IO (OCIO) configuration.



Set the Is Enabled field to true to enable OCIO color conversion and disable the Tone Curve automatically. You can then set the Configuration Source to an OCIO configuration created in the content browser, and you can use the Source Color Space and Destination Color Space settings to convert from one color space to another. If you are doing post production work (stencil layers, object ids, etc.) you will want to use an OCIO based workflow as most post production workflows require you to be in Linear space. Checking Disable Tone Curve will have the engine output in Linear space when combined with .exr image sequences.

The Disable Tone Curve setting enables you to manually disable the use of filmic tone curve even if you have not enabled OCIO. This option will be greyed out if Is Enabled is set to true. Disabling the tone curve makes it possible to output .exr files that store the linear data that comes from the Post Processing pipeline that will not be rescaled down to the [0-~1] range as is normally done for display.

For more information about OCIO configurations, visit the Color Management with OpenColorIO page.

Console Variables

The Console Variables setting will change any console variables that you designate when the render begins. This is useful when trying to increase ray tracing sample counts or apply other quality settings that are too expensive for real-time preview in the Editor.



Any console variables in the Console Variables list will be set to your designated value when your movie render starts. The original value before the render starts is saved, and when the render finishes, the console variable will be restored to the original value. Each entry in the list is a key-value pair consisting of the name of the console variable and the value you want to set it to.

The Start Console Command and End Console Commands list will execute the provided console command before the render starts, and after the render ends. This can be used for running console commands that are not variables, such as executing Custom Events.

Debug Options

Contains options for debugging certain render behaviors.



Name

Description

Write All Samples

Enabling this will write every single render sample produced by the GPU to disk alongside the output so you can inspect the results of individual temporal or spatial sub-sample renders without accumulation.

Capture Frames with Render Doc

Enable this to specify a frame number on the Capture Frame property. Requires Using RenderDoc with Unreal Engine.

Capture Frame

Specify a sequence frame number to capture and it will automatically trigger RenderDoc on that frame and write the capture to disk where you can inspect visual issues.

Game Overrides

This overrides several common game-related settings, such as Game Mode and Cinematic Quality settings. This is useful if the game's normal mode displays UI elements or loading screens that you do not want captured.



Property

Description

Game Mode Override

Overrides the map's default game mode with another game mode. This is useful if the game's normal mode displays a UI or loading screen you do not want captured. By default the empty MoviePipelineGameMode is used which hides the player.

Cinematic Quality Settings

Automatically applies the Cinematic quality setting in the Engine Scalability Settings.

Texture Streaming

Determines what methods should be used to load textures in each frame.

Use LODZero

Enables the highest quality settings for meshes and particle systems, regardless of distance.

When this is enabled, it will also run the console command foliage.ForceLOD 0. The foliage system however has a cap on the number of triangles it will draw, which other systems do not. Since there can be lots of foliage meshes, it can impact performance, which the cap safeguards. When the cap is reached no foliage will be rendered.

You can work around this by doing either:

Increasing the cap with foliage.MaxTrianglesToRender (this defaults to 100000000). Be warned that this can significantly slow down render times.

Increasing foliage.LODDistanceScale and not running foliage.ForceLOD 0 (in this case you would not enable Use LODZero). You can specify these commands instead in the Console Variables settings of Movie Render Queue.

Since Use LODZero also changes other system's LODs the you may need to also run the following console commands for force LOD0 on non-foliage sources:

Disable HLODs

Disables Hierarchal LODS to use real meshes, regardless of distance.

Use High Quality Shadows

Enables some common shadow related settings to increase quality in renders.

Shadow Distance Scale

Multiplies the distance at which a shadow is visible on an object. Higher values mean shadows are visible for more distant objects.

Shadow Radius Threshold

Overrides the minimum on-screen size required for an object to cast shadows. Smaller values mean smaller objects will cast shadows.

Override View Distance Scale

Overrides the View Distance Scale for objects. Useful when the Max Draw Distance is already set to a certain value to improve in-game performance.

View Distance Scale

Sets the value for the scale if you override the default View Distance Scale.

High Resolution

The High Resolution settings enable you to use tiled renders to produce larger images than would be normally possible due to maximum texture sizes or memory limits on GPUs. Under High Resolution, you can adjust the Tile Count, Overlap Ratio, and Texture Sharpness Bias.



Property

Description

Tile Count

Sets the number of tiles the image breaks into while rendering. Uses square formatting, so a 7680x4320 Output Resolution with Tile Count set to 2 will render four total 2x2 tiles at 1920x1080 each.

Texture Sharpness Bias

Biases the texture mip mapping to pick a higher resolution texture when it might normally not. A more negative number means the bias is more likely to select a higher detailed mipmap than it normally would, but, if the value is too high, it can cause a grainy image. The bias has no effect on textures that are already displaying their highest quality mipmap.

Overlap Ratio

Controls how much each tile overlaps each other. A value of 0.1 will cause a 10% overlap between the images that are blended together. This is particularly useful for Depth of Field, which normally produces a different result near the edges of images. Using this property makes rendering more time consuming, but can reduce seams between tiles.

Override Sub Surface Scattering

Some sub-surface scattering methods rely on Temporal Anti Aliasing for image history. Because TAA is not supported in high resolution tiling this option allows you to increase the number of samples to overcome the lack of image history.

Burley Sample Count

Number of samples to use for Burley sub-surface scattering.

This example image shows how tiles are combined to create a final image, when the Tile Count is set to 2 and Overlap Ratio is set to .25 (25%). The Overlap Ratio area is being visualized on the tiled image in yellow.





Currently, High Resolution does not support temporal anti-aliasing and some rendering features which rely on-screen space effects. This includes screen space reflections, convolution bloom, lens flares and motion blur on very fast moving objects.

Render Settings

Movie Render Queue

Path Tracer

Post Process Materials

Overview

Deferred Rendering

Post Process Render Pass

Stencil Layers

Path Tracer

Object ID's

Setup

Object ID Grouping

Combining Object Id, Depth and Velocity in Post

UI Renderer

VT Pending Mips

Movie Render Queue supports rendering different types of output images in separate passes, such as the final image, object ids, and other rendering related passes. Each render pass setting will output your movie in a separate rendering mode. You can then use them in an external post-production or compositing program of choice.

You have completed the prerequisite steps from the Movie Render Queue page.

If you are using Object ID's, you must enable a plugin to use it. Navigate in the Unreal Engine menu to Edit > Plugins, locate Movie Render Queue Additional Render Passes in the Rendering section, and enable it. You will need to restart the editor afterward.



Although Movie Render Queue has the capability to output some render passes, the limitations of Deferred Rendering does not make it possible to output all passes to assemble the final image from. This means that common passes available in other rendering packages (AOV's), such as Ambient Occlusion or Sub-surface Scattering, are unavailable in Unreal Engine. This page lists the only supported passes.

Overview

You can add Render Passes to your output by clicking on the + Setting button and selecting any of the entries in the Rendering category.



You can enable and disable render passes as you would with any other setting, and you can select them to edit their properties, if any are available.

By default, all of your selected render passes will be output alongside each other in the final output folder. You can utilize the format string token {render_pass} to help organize your passes. For example, setting the following in File Name Format will cause your passes to separate into pass-relevant subfolders relative to the Output Directory:

Examples of some render passes that Movie Render Queue can produce.



Deferred Rendering

The main output from Unreal is handled by the default Deferred Rendering setting, which produces the final image that you see in the viewport. Some variations are provided, including Detail Lighting, Lighting Only, Reflections, and Unlit. These variations are not used in creating the final image, and are provided here for parity with the Level Editor viewport.

The Deferred Rendering options include the following:

Render Pass

Description

Deferred Rendering

Displays the final image for the scene, matching what you see in the viewport.



Detail Lighting

A special shader variation which only displays lighting combined with normal maps. Can be useful to show off the geometry of a scene.



Lighting Only

Similar to Detail Lighting but without the normal maps affecting the lighting.



Reflections Only

A special shader variation which makes everything in the world reflective.



Unlit

A special shader variation which displays only base color, with no lighting information.



All Deferred Rendering passes contain the same properties, but each render pass can be configured individually.



Name

Description

Accumulator Includes Alpha

If enabled, multiple temporal/spatial samples will accumulate for the alpha channel. This requires r.PostProcessing.PropagateAlpha to be set to 1 or 2, which you can enable by going to Project Settings > Rendering and using the Enable Alpha Channel Support in Post Processing setting.

It also adds roughly 30% to the cost of accumulation, so you should avoid using it unless necessary. This applies to renders that use multiple temporal or spatial samples.

Disable Multisample Effects

Disables post-processing effects that blend multiple pixels together, like depth of field, temporal anti-aliasing, motion blur, and chromatic aberration, which are undesirable when using the Object Ids render pass. This setting enables you to exclude these post-processes for a rendering job without having to manually disable them within your scene.

Use 32Bit Post Process Materials

Enabling this will cause the post process materials to write to 32 bit quality, instead of 16 bit.

Additional Post Process Materials

An array of additional post-process render passes to include. Includes MovieRenderQueue_WorldDepth and MovieRenderQueue_MotionVectors by default. The material must be Enabled in order for the pass to render.

Add Default Layer

Creates an extra stencil layer that contains all objects not already contained in the Stencil Layers array. This default layer will render separately, enabling you to create renders that exclude small groups of objects for later re-compositing.

Stencil Layers

A list of stencil layers, which contain groups of objects in the scene. The scene will be re-rendered with all objects and then pixels that don't contain objects on the specified layer will be clipped and turned black. Post Processing is then applied which preserves the ability to use DoF, Motion Blur and TAA.

Post Process Render Pass

Post Process Render Passes are additional render passes you can specify from the Deferred Renderer. You must output them in the .exr format as they contain color and metadata information beyond what can be displayed and interpreted from the other formats.

The World Depth is the depth written in world units stored in the red channel. This can be used to re-create the Depth of Field in post production. The camera focal length and shutter size can be read from the EXR metadata to automatically match the in-game depth of field.



An example of the Nuke ZDefocus2 node can be found below. This will read the metadata from the EXR file and produce a similar blur to what is found in realtime. You must re-adjust the focal_point property after pasting, so that it samples the WorldDepth texture correctly.

World Depth with ZDefocus Nuke node

Motion Vectors are stored in the 0,1 coordinate space for X and Y, where 0.5, 0.5 is no motion.



In Nuke, the VectorBlur node can be used to apply motion vectors to your image. Unreal stores motion vectors normalized to the entire screen which may be unlike other rendering packages. As a result, in the Nuke VectorBlur node the uv_offset is set to -0.5 (to rescale to /[-.5, .5/] instead of /[0, 1/]) and then the motion blur scale is driven by the width of your image.

Motion Vector with VectorBlur Nuke node

Depending on your software of choice, you may need to rescale the X and Y channels of the motion vectors independently, as other software may expect them to be in pixel values and not normalized to the screen. By normalizing them to the screen the X and Y channels have different strengths.

Stencil Layers

Stencil Layers allow for layered rendering of your sequence based on objects within Layers.

The entire scene is rendered for each layer, and actors that belong to a layer are rendered into the Stencil Buffer. The stencil buffer is then used to clip pixels that fall outside of the actors in their layer. This allows for shadow casting objects to cast shadows onto other actors and layers.

Once rendered to the stencil buffer, a post-processing effect is applied that takes each pixel and writes black with translucency into the pixel. This happens after translucency but before Post Processing, and then post processing is applied to this layer. The alpha channel can be preserved, which will allow you to know in post production which pixels were actually affected, and by how much.

Below is an example of three Stencil Layers alongside the default layer. You can see that post processing effects, such as depth of field, have been correctly applied, and that objects in the foreground have been clipped out of background images as well. These images can be added back together to create a similar result to the final render, though it may require un-premultiplying the data.



Below is an example from Nuke which applies a simple hue shift to one of the layers specified in the original image. The original image was rendered with alpha channel accumulation enabled and the Tone Curve disabled in the Color Output setting.



To properly recombine multiple images like this they should be exported in linear space (disabling the Tone Curve in the Color Output setting). You should use an OCIO-based workflow for this kind of post production work.

The Stencil Layers are not a true layer system, as translucent objects will show opaque objects from other layers behind them, and background layers will show black holes where foreground objects occlude them. Stencil layers do not support per-layer post processing materials, As they will match the additional post-process materials of the base layer, and are only compatible with materials that support Custom Depth/Stencil.

Path Tracer

The Path Tracer outputs an image based on the Path Tracer rendering method. It has similar details to the Deferred Rendering passes.



The Path Tracer rendering mode accumulates path data each frame that renders. This results in a noisy image as the pixels of the image are filled in, especially if the contents of the camera frame changes significantly.

To reduce this noise, you can increase the number of Spatial Samples in your Anti-Aliasing settings.



This will render the image multiple times, and the additional samples will enable the path tracer to more effectively fill in the gaps. A large number of Spatial Samples is required to effectively denoise a Path Tracer render, and this will greatly increase the amount of time required to output the images.

Increasing the Spatial Samples Anti-Aliasing property will reduce the noise in a Path Tracer render.



The Path Tracer render mode is currently experimental, and not all material shading modes are supported at this time.

Object ID's

The Object Ids render pass outputs an image where each actor in the scene is assigned an ID. These ID's can be completely unique per actor, or grouped based on certain properties.



You can use this image in a post production suite to select individual objects in a scene and create a mask for them, enabling you to selectively apply adjustments to specific objects.





Setup

The Object Ids pass has specific requirements in order to render correctly:

Enable Disable Multisample Effects for any render passes that you intend to composite together with the Object Id pass. This will exclude motion blur, depth of field, anti-aliasing, and other post-processes that would blend multiple layers of pixels, ensuring that all objects maintain crisp edges. This is required for the object ID pass to line up with the final image correctly.



Under the Deferred Renderer setting, expand the Additional Post Process Materials and enable both the MovieRenderQueue_WorldDepth and MovieRenderQueue_MotionVectors materials.



Add the Anti-aliasing setting to your job and set the Spatial Sample Count to at least 8. Also enable Override Anti Aliasing and set Anti Aliasing Method to None.



This will allow you to overcome the limitation where TAA is not supported. Using Temporal Sample Count is unlikely to produce the desired results due to the lack of motion blur covering the gap between each sample; you will simply end up with multiple copies of the object faintly superimposed over each other.

Add the .exr Sequence output mode to your settings and deactivate or remove any other export formats. Ensure that the Multilayer property is enabled.



When you start the Movie Render Queue with these settings in place, it will output a multi-layered EXR that includes the Final Image, Object Ids, World Depth, and Motion Vectors.

The Object Ids are stored in the EXR file using the Cryptomatte specification, and plugins to read this data are available for third party software.

The Object Ids render pass is experimental in Unreal Engine. It is only available in the Unreal Editor, and can not be used in shipping builds.

Object ID Grouping

By default, unique colors or ID's are assigned to every actor or component in the level. You can change this on the Object Ids Id Type property.



ID Type

Description

Full

The default behavior. A unique ID is created for every material applied to each primitive on all actors in the level.

Material

ID's will be grouped based on their material or material instance. Material instances will group with their parent material.

Actor

ID's will be grouped by the same actor instance.

Actor With Hierarchy

ID's will be grouped by the same actor instances. Actors in different World Outliner folders will be separately grouped relative to those folders.

Folder

ID's will be grouped by actors within World Outliner folders. All actors within these folders will be merged into one ID.

Layer

ID's will be grouped by actors assigned in Layers. Actors that belong to multiple layers may cause unreliable outcomes.

Combining Object Id, Depth and Velocity in Post

By combining multiple spatial samples, depth, and velocity you can produce a similar result to Unreal's post processing pipeline; Depth of Field via the depth map and Motion Blur via the velocity texture. You can use Object Id's to pick objects and color correct them before applying these post process passes.

To preserve the correct bright highlights through depth of field and motion blur, the scene should be rendered with the tone curve disabled. Do this by adding a Color Output item and enable the Disable Tone Curve property. This will output HDR Linear values in the sRGB colorspace. After applying depth of field and motion blur you can now convert it to your desired colorspace (from Linear sRGB).



You must also set Velocity Path to Write during base pass. Do this by navigating in the main Unreal Engine menu to Edit > Project Settings > Engine > Rendering and set Velocity Path to Write during base pass. The editor must be restarted after changing this project setting.



Additionally, the r.BasePassForceOutputsVelocity variable must be set to 1. You can do this engine-wide by editing /Engine/Config/ConsoleVariables.ini, or you can apply it as a Console Variable during your render.



Below is an example Nuke graph which uses the ZDefocus and VectorBlur nodes. For the velocity texture to be used in Nuke, the Red and Green channels of it need to be swapped (RG_TO_GR in the graph below, using a ShuffleCopy node).

This Nuke graph takes an exr rendered with 8 spatial samples, object id pass, motion vectors and world depth. Depth of Field information is automatically pulled from the exr metadata. The cryptomatte nodes are used to create masks of the Newton's Cradle device, and then are used as masks for a simple hue shift. After the hue shifting is applied the previously mentioned ZDefocus node is applied, and then the VectorBlur.



ObjectID, ZDefocus, and VectorBlur Nuke nodes

Additionally, because Unreal stores motion vectors normalized [0-1] in both X and Y you will need to rescale the Red channel to ImageHeight and ImageWidth (1080, 1920 in this example), or 0.5625. To do this rescaling, subtract 0.5 from the velocity channel, multiply it by 0.5625, and then add 0.5 back to the velocity channel before plugging it into the VectorBlur node. Failing to rescale the red channel will result in an incorrect angle for the motion blur.

Like Stencil Layers this feature is intended to be used in combination with an OCIO-based workflow. Depth of field must be applied to images in linear space in order to determine which highlights are bright enough to create bokeh. By disabling the tone curve the look of your image changes. By using an OCIO based workflow you can both visualize the final look in viewport and re-apply the look to your images in post production to recreate the look.

If you would like to experiment with Nuke node creation, you can download the frames and nuke file from the above example.

UI Renderer

The UI Renderer will render Slate or UMG Widgets added to the Viewport as a separate output with alpha. You can combine this with your final images in a compositing program to add any UI elements you want to render.

VT Pending Mips

VT (Virtual Textures Pending Mips is a render pass designed to be used in conjunction with the Prestreaming Recorder. This pass exports Virtual Texture mip debugging frames to your output directory, which can be used to debug your pre-streaming cache.



This debug render pass will not show Virtual Texture information on Nanite geometry. If you are using lots of Nanite geometry, use the r.nanite 0 console command, which causes all meshes to revert to their non-Nanite versions, and debug information to be better visible.

Open Still Image Setup Tool

Tool Usage

Still Settings

Movie Render Queue can be used to render still images from multiple cameras as a batch process, without the need for complicated setups in Sequencer. This simplifies the process of creating large series of stills from different viewpoints, as you work through variations or iterations. This is ideal for architectural, automotive, or product design deliverables.

This document provides an overview of the Still Image Setup tool and how it can be used with Movie Render Queue.

You have completed the prerequisite steps from the Movie Render Queue page.

You have placed multiple cinematic cameras in your Level, capturing your chosen angles.

Open Still Image Setup Tool

The Still Image Setup Tool is located within Movie Render Queue's Plugin Content folder. In order to access this folder in the Content Browser, select View Options and enable both Show Engine Content and Show Plugin Content.



You should now see multiple folders in your Content Browser sidebar. Locate MovieRenderPipelione Content and navigate to its Editor > Stills subfolder. You should see StillRenderSetupAutomation contained within it, which is an Editor Utility Widget.



Right-click StillRenderSetupAutomation and select Run Editor Utility Widget to open the tool.



Tool Usage

To create a sequence of still images using the cameras placed in your Level, click Create Sequence For All Cameras. This will create a Level Sequence Asset for each Cine Camera Actor that is placed in this Level.

The sequences are created within the folder path determined by the Sequence Creation Path property, and are named according to their assigned camera.



You can also click Create Sequence For Selected, which will only create sequences for selected cameras.

If Automatically Add Jobs to Movie Queue is enabled, then when you open the MRQ window, you should see your sequences already added to the queue.



Click Render (Local) to create a single image render from your different cameras.



When rendering, it is recommended that you add some amount of warm up time in order to allow your assets and textures to fully load at their maximum quality. You can do this by setting the Engine Warm Up property to a value of at least 60. This property is located in the Anti-Aliasing image setting.

Still Settings

The following buttons and properties are available in the Sequencer Still Setup window.

Name

Description

Create Sequence For Selected

Creates a single-frame Level sequence for all selected cameras in the Level, and stores it within the folder path specified by the Sequence Creation Path property.

Create Sequence For All Cameras

Creates a single-frame Level sequence for all cameras in the Level, and stores it within the folder path specified by the Sequence Creation Path property.

Automatically Add Jobs to Movie Queue

Enabling this causes newly created sequences to be automatically added to the Movie Render Queue.

Sequence Creation Path

The path for creating new sequences when clicking Create Sequence For Selected or Create Sequence For All Cameras.

Job Settings Preset

The Render Settings to apply for all sequences.

Override Output Folder

Enabling this will override the Output Directory of the Job Settings Preset with the directory specified in the Output Folder property.

Output Folder

The output directory to override for newly created sequences added to the queue, if Override Output Folder is enabled.

Override Movie Resolution

Enabling this will override the Output Resolution of the Job Settings Preset with the resolution specified in the Movie Resolution property.

Movie Resolution

The output resolution to override for newly created sequences added to the queue, if Override Movie Resolution is enabled.

Override Tile Count

Enabling this will override the Tile Count amount of the Job Settings Preset with the new amount specified in the Tile Count property.

Tile Count

The number of image tiles to override for newly created sequences added to the queue, if Override Tile Count is enabled.

Override Spatial Sample Count

Enabling this will override the Spatial Sample Count of the Job Settings Preset with the amount specified in the Spatial Sample Count property.

Spatial Sample Count

The spatial samples count to override for newly created sequences added to the queue, if Override Spatial Sample Count is enabled.

Override Temporal Sample Count

Enabling this will override the Temporal Sample Count of the Job Settings Preset with the new amount specified in the Temporal Sample Count property.

Temporal Sample Count

The spatial samples count to override for newly created sequences added to the queue, if Override Temporal Sample Count is enabled.

Use Map as Output Prefix

Enabling this will add the Level name as a prefix to the output image files.

Movie Pipeline Subsystem

Creating a Basic Render

Allocate Job

Set Configuration

Render Job

Additional Functions and Settings

Customize Render Configurations

Canceling Jobs

Render Finish Event

Change Render UI

Limitations

In addition to rendering using the Movie Render Queue user interface, you can also execute renders using Blueprints on runtime distributed builds. This makes it so that renders can be created on end-user devices.

This document provides an overview of how to create renders using Blueprints, and the functions available to you to configure various settings.

You have completed the prerequisite steps from the Movie Render Queue page.

You have an understanding of using Blueprints in Unreal Engine.

Movie Pipeline Subsystem

Movie Render Queue in Blueprints is accessed using the Movie Pipeline Runtime Subsystem node. This subsystem features a Queue which contains a list of rendering jobs. Each job can contain one or more shots, and each job also has its own configuration, which contains the render settings used to render its shots. To render a video, you need to build a list of jobs, allocate them to the queue, then call the Movie Render Queue subsystem's Executor to process the queue.

To add this, right-click in the Event Graph and select Engine Subsystems > Get MoviePipelineQueueEngineSubsystem.



Creating a Basic Render

From the Movie Pipeline Runtime Subsystem node, there are three main functions and steps required for successfully rendering using Blueprints.

Allocate Job, which is a function used to assign a Level Sequence to the render job.

Set Configuration, which is used to assign a render configuration.

Render Job, which renders the job using the provided sequence and configuration.

Allocate Job

First, drag off the Movie Pipeline Runtime Subsystem node and select Movie Render Pipeline > Rendering > Allocate Job.



Connect the Subsystem node to the Target pin, and then assign the Level Sequence you want to render to the In Sequence pin.



Set Configuration

Next, drag off the Allocate Job node's Return Value pin and create a Set Configuration node.



Assuming you already saved a custom render configuration as a Preset, assign it in the In Preset pin.



Render Job

Lastly, drag off the Movie Pipeline Runtime Subsystem node and create a Render Job Function. It should execute after Set Configuration, and In Job should connect to Allocate Job.



Executing these functions performs a render on the local machine using the sequence assigned in Allocate Job, and the render settings assigned in Set Configuration.

Additional Functions and Settings

For more advanced render controls, you can use the following functions and workflows.

Customize Render Configurations

If you want to edit or create new render settings for a job, you can connect Get Configuration and Find or Add Setting by Class nodes after Allocate Job.



Next, set the specific export format, image setting, or render pass in the In Class pin.



After you choose a setting, you can now drag from the Return Value pin to get or set property variables related to that setting class.



If you are building custom render configurations without setting a base configuration, you are required to add a base render pass and output format. Typically this means adding Deferred Pass and an output such as PNG or JPG. Unlike the editor, these settings will not be added by default.

Canceling Jobs

You can also cancel active render jobs using functions. This can be important as a protection for cases when the simulation ends while a render is ongoing. Without this protection, it could cause the editor to enter into a softlock state.

To cancel all render jobs, connect the Movie Pipeline Runtime Subsystem node to Get Active Executor, then Cancel All Jobs.



To implement the cancellation as a protection when the simulation ends, create an End Play Event, connect it to an Is Valid check, then connect Is Valid it to Cancel All Jobs.



Render Finish Event

Render finish events can be created by binding to a custom event from the Movie Pipeline Runtime Subsystem. To do this, drag off the subsystem and select either Assign On Render Finished (to create both a Bind and Custom Event node), or Bind Event to On Render Finished (to create only a Bind node to connect to an already existing custom event).



Once connected to a custom event, right-click on the Results pin and select Split Struct Pin. A Render Finish event outputs the following information related to the render that occurred when this event fires:



Name

Description

Results Pipeline

The internal UMoviePipeline object that generated this event. This is an advanced option and is only meant for tracking.

Results Job

The UMoviePipelineExecutorJob that generated the event. This is the same result as Allocate Job earlier, and can be used for tracking.

Results Success

Outputs true or false depending on if the render was successful.

Results Shot Data

This contains lists of the render passes and the file paths for the files that were generated on disk. This can be used in the event you want to load these images for further processing.

Change Render UI

The Debug Widget is the UI Widget that displays the preview frames of your movie while it renders. You can set the Executor to use a different Debug Widget by using Set Configuration from the Movie Pipeline Runtime Subsystem.



Select the In Progress Widget Class dropdown menu to select which widget to use. You can select from the following:

MovieRenderDebugWidget, which is the base class and shows a blank screen.

UI_MovieRenderPipelineScreenOverlay, which shows the default rendering progress UI seen above.

UI_MovieRenderPipelineScreenOverlayBlank, which shows a blank screen.



You can create your own custom debug widget by creating a Widget Blueprint, then setting its Parent Class to MovieRenderDebugWidget. You can then select this custom widget as your Debug Widget Class for your Executor.



Limitations

Some settings are unavailable in runtime builds, as they depend on editor-specific functionality. These include:

The FinalCut Pro XML output format

Object ID render passes

Wav Output (unless your application is launched with -deterministicaudio and -audiomixer).

The Sequencer - How To... pages provide step-by-step examples on how to work with the Sequencer Editor in various capacties inside Unreal Engine. Whether you would like to learn how to animate a character, setup up multi-camera sequences or learn about working with cameras in general, these pages will guide you each step of the way. Reference links are also included to provide more detailed documentation of the systems and content being outlined in each guide.

Refer to the table below for more information and click each link to view its contents.

Level Sequencer Setup

Content Setup

Results

Animated Transform Origin

If your project requires cinematics or other Level Sequence content that takes place in more than one location, it may be beneficial to use Sequencer's Transform Origin features to dynamically change the location of the animation at runtime. By default, all Sequencer transforms are relative to the world origin (0, 0, 0). However, by using Transform Origin, you can make transforms relative to any transform, or even to an Actor's transform.

This document provides instructions on how to bind Transform Origin to an Actor to change the location of Sequencer content.

You are familiar with creating content with Sequencer. Refer to these pages for more information:

Create Camera Animation

Apply Animation to a Character

Level Sequencer Setup

To start, create a Level Sequence Actor in your Level. Select it, and in the Details panel do the following:

Enable Override Instance Data.

Assign the Level Sequence Actor to Transform Origin Actor.



Which Actor to assign to Transform Origin Actor is arbitrary and depends on the context of your scene. For example, if you have a scene where characters are interacting with an object, like a table, then it may be better to assign the table as the Transform Origin Actor.

Depending on your use-case, you may want to assign the Transform Origin Actor first, before creating any Sequencer content in Unreal Engine. If you create content first and then assign a Transform Origin Actor with a non-zero location, your content will move relative to that Actor. In other words, your current Sequencer transforms do not compensate when assigning the Transform Origin Actor.

Content Setup

Next, create content in your sequence, aligning your Sequencer content to the Transform Origin Actor. In this example, the Mannequin character walks to the same location as the Level Sequence Actor.



You can now move the Transform Origin Actor and see your animation change location when playing.



Results

Changing the location of the Transform Origin Actor affects all transforms and animations within the sequence. This makes it possible to dynamically change where a scene takes place.



All objects within a Root Sequence also receive Transform Origin offsets.

Animated Transform Origin

Transform Origins also correctly adjust Sequencer content if the origin Actor is animated. In this example, the boat Actor is set as the Transform Origin Actor, causing the character and any other transformed actors in the sequence to follow the animation of the boat during runtime.



Sequencer Overview

1 - Sequence Setup

2 - Animation and Character Blueprint Setup

3 - Using Cinematic Exposed Variables

4 - Triggering the Sequence Playback and Blend

When creating your cinematic sequences, you may want to blend existing gameplay animation with animation contained inside your Level Sequence. For example, a playable character walks up to a door during gameplay and you want Sequencer to animate the character and open the door. Or a player is controlling their character in a third person shooter and comes around a blind corner and you want to blend in a cinematic death sequence. By using a combination of Sequencer, Blueprint, and an Animation Blueprint you can blend whatever gameplay pose your character is in with a Slot animation defined by Sequencer.

In this example, we take whatever gameplay pose the character is in when entering a trigger volume and blend it with a death animation inside Sequencer.

1 - Sequence Setup

In this step we set up our Level Sequence and add our playable character and animation we want to blend to.

For this how-to guide, we are using the Blueprint Third Person Template with Animation Starter Pack available for free from the Epic Marketplace.



Inside your project, delete the ThirdPersonCharacter from the level and add the Ue4ASP_Character, setting Auto Possess Player to Player 0.



Optionally, you can disable the capsule component from being displayed by selecting the capsule component then checking the Hidden in Game option.



From the main toolbar, click the Cinematics button then select Add Level Sequence and save it with any name.



In your Level Sequence, add the Ue4ASP_Character and an Animation Track with Death_3 assigned as the animation.



Right-click on the animation in the keyframe window then under properties, change When Finished to Keep State.



This will enable us to preserve the animation state when the Level Sequence is over. Also, take note of the Slot Name property highlighted below.



When an Animation Blueprint is controlling a Skeletal Mesh, Sequencer plays back animations on slots within that Blueprint and is controllable through the Slot Name property. An Animation Blueprint can then Blend between a slot Animation and whatever game logic driven animation your character may happen to be in.

In the next step, we set up our Animation Blueprint and Character Blueprint so that we can blend from our gameplay animation into our death animation we created in this step.

2 - Animation and Character Blueprint Setup

In this step we will set up our Animation Blueprint so that we can take our gameplay pose and blend to a Slot animation defined by our Level Sequence.

In the Content Browser, locate and open the UE4ASP_HeroTPP_AnimBlueprint then double-click on the AnimGraph in the My Blueprint window.



In the AnimGraph off the existing Locomotion State Machine, create a New Save Cached Pose and call it lococache.



Use the lococache twice and connect one to the A pin of a Blend node which feeds the Final Animation Pose.



Off the other lococache, use a Slot node and connect it to the B pin of the Blend, then right-click on Alpha and Promote to Variable and call it Blend Interp.



In the Content Browser open the Ue4ASP_Character Blueprint and replace the Crouching section with the graph below.



Above we are replacing the InputAction Crouch node with the C keyboard event and a Flip Flop node to toggle our crouching states.

This Blueprint was originally created for another project which included an input binding for crouch which our template project does not have. By replacing the InputAction Crouch with a standard C keyboard event, we will eliminate the Blueprint warning messages as well as enable us to press the C key to toggle between crouching and non-crouching states.

Create a new Float variable called DefaultSlotInterp and set Instance Editable and Expose to Cinematics to True.



We will use this variable inside Sequencer to blend and pass the value over to the Animation Blueprint variable Blend Interp which handles the actual blend.

Create a new function called SetDefaultSlotInterp and add an Input called Interp of the Float type in the Details panel.



By creating a function called Set (Property Value Name) we have created a Proxy function that will be called by Sequencer whenever the associated property value changes. This function is only called when the propery value changes and is more efficent than using Event Tick or a Custom Event and Timeline to reflect changes in the DefaultSlotInterp property value.

From the Components window, drag in the Mesh and use Get Anim Instance and Cast to UE4ASP_HeroTPP_AnimBlueprint.



Off As UE4ASP Hero TPP Anim Blueprint, use Set Blend Interp and pass in the Interp value to the Blend Interp in.



Whenever our DefaultSlotInterp value is changed through Sequencer, the SetDefaultSlotInterp proxy function is called and the float value is passed through to the Animation Blueprint's Blend Interp value which affects the blending of our poses.

In the next step we will add the Default Slot Interp property to our Level Sequence so that we can control the Blend Interp in our Animation Blueprint. We'll also add a Trigger Box to the level so that we can activite our Level Sequence and play it when the player enters the Trigger Box volume.

3 - Using Cinematic Exposed Variables

Here we add the float variable Default Slot Interp which is feeding the interp in our Animation Blueprint, determining when we blend from a gameplay pose to our Slot animation. We also add a Trigger Box to the level that we will use in the next step to allow the player to trigger the playback of our Level Sequence when they enter its volume.

Inside your Level Sequence for the Ue4ASP_Character, click the Track button and assign the new Default Slot Interp property.



Scub the timeline ahead to frame 25 (or whichever frame you prefer) and add a key for Default Slot Interp with a value of 1.0.



From the Place Actors panel in the main level editor, drag a Triggerbox into the level and resize and place where desired.



You can optionally set Actor Hidden In Game to false if you want to be able to see the trigger volume during playback.

In the next and final step of this guide, we set up the Level Blueprint to playback our Level Sequence when we enter the Trigger Box's volume.

4 - Triggering the Sequence Playback and Blend

In the final step before we can test out our setup, we use the Level Blueprint to activate our Level Sequence when the player enters the Trigger Box. When our Sequence starts, the property DefaultSlotInterp that is exposed to cinematics is changed which starts the process of updating our interp values. This tells our Animation Blueprint to start blending from gameplay animation to our Slot Animation.

With the Triggerbox selected, from the main toolbar, click the Blueprints button then Open Level Blueprint.



Right-click in the graph then under Collision for the Trigger Box select Add On Actor Begin Overlap.



Return to the level viewport and select your Level Sequence, then in the Level Blueprint right-click and add a reference to your Level Sequence.



Off your Level Sequence, use Get Sequence Player then off it use the Play node and connect as shown.



Compile and Save, then click Play to play in the editor.

End Result

When our character enters the trigger volume, regardless of their current animation state, we start to blend from our gameplay pose into our death pose defined by Sequencer.

We could take this a step further by adding a camera to our Sequence and improve the blending by shifting the point in which the death animation starts in our Sequence.

In the example above, the player can walk, run, crouch walk, or jump into the trigger and each case they will blend into the death animation when entering the trigger volume.

End Result

The Material Element Switcher track is a Sequencer track that you can use to animate Materials on an Actor. This enables you to change materials on an Actor by adding keys for specific materials on the track.

For this how to, we can use the Paragon Phase and Fey materials from the Epic Marketplace. You can see that we already have a Material Element Switcher for Phase's Skirt. This is so we can easily see the change in materials in contrast with the jacket.

Navigate to Cinematics > Add Level Sequence. Name and save the sequence, such as "MaterialAnim", and then open it from the Content Browser.

Add the Skeletal Mesh for your actor to the Viewport. Then add the mesh as a track to your sequence.

Under Skeletal Mesh Component, add a new Track and select a Material Element Switcher. You can find which material number corresponds to the element you want to change on the actor in the Skeletal Mesh animation Blueprint.



In this example, I want to change the jacket material, which is Material Element 10.

In the dropdown labeled None, select the first material for the sequence. Then, add a key for this material in the Sequence.





In this example, we will start with MIC_Phase_jacket, which is Phase's jacket material.

Move the slider along the Timeline to where you want to change materials. Using the dropdown, select a new material and add a new key to the sequence.



In this example, we changed the material to the M_Fey_Armours material.

Repeat the previous step to add a third material.



In this example, we change the material to the M_Fey_Plantseed material.

The last material change is back to Phase's original jacket material, MIC_Phase_jacket. Move the slider and add a key to change the material again. In this example, I change the jacket material before the skirt material changes at the end of the sequence.



You can now playback the sequence and watch the materials change.

End Result

Applying Burn Ins

Importing & Exporting Edit Decision Lists (EDLs)

Render Passes

Sequencer Overview

Steps

End Result

As of Unreal Engine 5.0, Renderer Movie is deprecated. Instead, please use Movie Render Queue.

Once you have created your cinematic (or even during your production process as part of daily reviews), you may want to render it out as a movie file that you can share with others. The Render Movie option in Sequencer enables you to share your movie with others as an AVI file that will play with most media players.

In addition to rendering as a movie file, you can render your cinematic as an Image Sequence or render out Custom Render Passes that you can use in an external application to finalize your scene. Selecting the Render Movie button will display the Render Movie Settings window, which you can use to define how your scene will be rendered.

In the following example, we render out a sample scene and present some of the options available as part of the rendering process.



Steps

For this guide, we are using the Blueprint Third Person Template with Starter Content enabled.

Inside your project, from the Main Toolbar, click the Cinematics button then select Add Level Sequence.

In the Save Asset As window, enter a name for your Sequence, then click Save.

Inside the Sequencer Editor, click the Add Camera button.

In the Viewport, position the camera anywhere in the Level facing the Character, then press the S key to add a keyframe. We will shoot a sample scene where the camera pushes in on our the Character in the Level for a close-up shot.

In Sequencer move to frame 150, then move the Camera in the Level to a new location and press the S key to add a key. The camera will now move from our first keyframe to our second keyframe, pushing in on the Character.

In Sequencer, click the Render Movie button. The Render Movie Settings window will open. Under the Capture Settings, click the Output Format option to view the options, then select Video Sequence. In addition to rendering out a movie, you can render out an Image Sequence or use Custom Render Passes.

Under General, choose an Output Directory to save your cinematic to, then click Capture Movie. A preview window will appear while the rendering process occurs.



If prompted to Save, click Save or Don't Save to continue as selecting Cancel will abort the rendering process.

End Result

After the capture process, you will have a video file of your cinematic sequence (below is our rendered-out cinematic).

There are additional options available when rendering out video sequences. One that may be useful during production is the ability to add Burn Ins to your video. Burn ins are overlays that are embedded with your video, generally to provide internal information about the frame being shown.

You can add the default burn ins to your video, or custom burn ins that you create, by enabling the Use Burn In option.



This can be useful if you are doing reviews of a cinematic, as it will display timecode information as well as shot names and any other custom information you want to provide.



First Camera Setup

Additional Camera Setup

Open Movie Render Queue

Render Settings

Render and Results

When rendering using Movie Render Queue, there may be a requirement to render from multiple Cinematic cameras within a single sequence or Shot. For example, you could be rendering a product demonstration video or training material, which may require multiple angles. Rendering from multiple angles within a single shot can be more ideal than using Takes, as Takes cause new Level Sequence assets to be created, diverging your content.

This document provides an overview of how to render multiple camera angles from a single shot using Movie Render Queue.

You have a basic knowledge of how to create and open a Level Sequence

Movie Render Queue is a Plugin you must enable prior to use. From Unreal Engine's main menu, go to Edit > Plugins, locate Movie Render Queue in the Rendering section, and click the checkbox to enable it. Then, restart Unreal Engine.



First Camera Setup

Assuming Sequencer is already open within the Level you want to render, the first step is to start creating your Cinematic Cameras.

Click Camera in the Sequencer Toolbar. This creates a spawnable Cine Camera Actor, Camera Cuts Track, and then binds the Cine Camera Actor to the Camera Cuts section.



Next, move and keyframe the camera to your desired framing and animation for this shot.

Enable the Camera icon on the Cine Camera Actor track, which pilots the camera.

You can also adjust camera-specific properties, such as Aperture, Focal Length, and Focus Distance to help with your shot composition.



Additional Camera Setup

You can now start to add new cameras to the sequence. Do this the same way you added the first camera, by clicking Camera in the Sequencer Toolbar. Each click will add a new camera, so add as many as you require. Although the Camera Cuts Track still is bound to the first camera (making it appear as if this shot only has one camera), these other cameras will be correctly rendered with Movie Render Queue in the final steps of this guide.



Similar to the steps taken for the first camera, enable the Camera icon on each new camera track to pilot it and set up your composition.



Although not required, we recommend you rename your camera tracks to better reflect their content or usage. Right-click on a track and select Rename, or press F2. If two cameras share the same name, Movie Render Queue automatically renames them to avoid a filename conflict.



Open Movie Render Queue

Once all your cameras are composed and animated within the sequence, you can now render using Movie Render Queue (MRQ). To open MRQ, click Render in the Sequencer Toolbar.



If MRQ is not correctly opening from this button, check the dropdown menu next to Render and ensure it is set to Movie Render Queue.



Render Settings

With the MRQ window open, click the Settings entry to open the Render Settings window.



Click Add Setting (+) and select Camera, then select the newly added Camera entry and enable Render All Cameras.



Although optional, you may want to edit Output Directory or File Name Format in Output settings with the {camera_name} Format String. Using this provides you extra control over how your output renders are named or categorized. For example, setting Output Directory to {project_dir}/Saved/MovieRenders/{camera_name}/ outputs each camera angle to a different folder.



If you don't use {camera_name}, then MRQ automatically adds the camera name as a suffix to the file name when Render All Cameras is enabled, to prevent file name conflicts.

Render and Results

Once your render settings are set up, click Render (Local) to start the MRQ render process.



When the render completes, click the Output entry to open a file explorer window to the output directory. You should see your multiple angles rendered here. In this example, the different angles were separated by folder using the steps detailed above.



Setting up the Character

Adding Event Tracks

End Result

When playing a cinematic through Sequencer, there may be instances when you want to trigger an Event that initiates some scripted functionality. Perhaps at a certain point in your cinematic you want a door to open, or have a particle effect to spawn and effect the Player in some way. With the Event Track you can key the exact frame in the cinematic where you want to call the Event.

You can add Events through a Sequencer track without needing to access the Blueprint. You can add multiple Events to an object, or add multiple object bindings to a single Event. If you open the Blueprint, you can also add multiple Parameters to one Event. For more detailed information, refer to Event Track Overview.

In this guide, we use several Event Tracks to print text to the screen indicating our character is dead. At the same time, we disable player movement and simulate physics on the character.

For this guide we are using the Blueprint Third Person Template project.

Setting up the Character

First, we need to set up the Third Person Character.

From the Main Toolbar, click the Cinematics button and select Add Level Sequence with any name and save location.

In the Details panel for the Level Sequence, enable the Auto Play option.

Select the ThirdPersonCharacter in the Level, then add it to Sequencer from the + Track button.

Right-click on the ThirdPersonCharacter in the Level, then select Edit ThirdPersonCharacter.

Right-click in the Event Graph and search for then add a Custom Event.

Call the Custom Event KillPlayerText and connect a Print String node with custom text as the String.



Select the KillPlayerText node, and on the Details panel, go to Inputs. Select +Add Parameter to add a new parameter to the node.



Choose the String parameter from the dropdown and update the parameter name to In String. Then, connect the In String input from the Custom Event to the Print String.



Adding Event Tracks

With the character set up, we can add Events so the character becomes disabled and prints the text from the Character Blueprint.

In Sequencer, click the + Track button on the ThirdPersonCharacter track and select Event.

Move the Timeline to frame 149, then add a key to the Events track.

Right-click on the new keyframe, and under Properties, select the Unbound dropdown to add Create a Quick Binding.

In the Quick Bind, search for Set All Bodies to Simulate Physics. Make sure to check New Simulate under Payload.





Add a second Event Track and add a Quick Bind for Disable Movement.

Add a third Event Track and add a Quick Bind to call the Kill Player Text we set up earlier. Under Payload, enter GAME OVER! in the In String textbox.



ALT+Drag the string key to three other locations on the timeline. Update the first key's string text with 3, the second key with 2, and the third key with 1.



Essentially, we are counting down to the GAME OVER! string text.

From any key's Event Properties, double-click the magnifying glass icon to open the Sequence Director Blueprint.



You can also open the Blueprint by double-clicking the event key or by navigating to General Options > Open Director Blueprint.

Add a SetCollisionEnabled node to Set All Bodies Simulate Physics, and set the type to Collision Enabled. Connect the Target pin to the Mesh pin.



This setting causes the character to collide into objects rather than fall through them. Even though we don't need to access the Blueprint to create Events, we do need the Blueprint to add onto Events, such as in this case.

When you press Play you can run around in the viewport until the 150 second mark where the character dies and the text prints to the upper left corner of the viewport.

If the Mouse Control label appears in the upper left corner, you will not be able to see the text easily. To toggle this off, go to Editor Preferences > Level Editor > Play, and uncheck Show Mouse Control Label.

End Result

When you play in the Editor, after a few moments, text will appear in the upper-left corner of the window and the character will fall to the ground with your ability to move disabled.

Adding an Event Track to an Object within Sequencer creates an Object Binding where you can call Events, Functions or access properties of the Object that you are bound to. Event Tracks can also be used to execute script within the Level Blueprint, UI Widget Blueprints, or communicate with multiple Blueprints through a Blueprint Interface.

Create Blueprint Interface

Implement the Interface in your Level

Set Up Event Track

Implement Interface

Create Logic

Bind Keyframe to Target

Results

Event Tracks are mainly used to trigger Blueprint Scripts within Sequencer's Director Blueprint. In your project, there may be cases where you instead want events from Sequencer to trigger in other Blueprints, such as the Level Blueprint. You can do this using Blueprint Interfaces and additional set-up steps in the Director Blueprint.

This document provides instructions on how to trigger Level Blueprint events from Sequencer's Event Track.

You have a basic understanding of how to create and open a Level Sequence.

You have an understanding of how to create and use the Event Track.

You have a basic understanding of Blueprints.

Create Blueprint Interface

First, create a Blueprint Interface. In the Content Browser, click Add (+) and select Blueprints > Blueprint Interface. Name your asset and open it.



In the Blueprint Interface Editor, give a unique name to the default Function, to help you locate it later in this guide.



The purpose of the Blueprint Interface is to provide communication between the Sequencer Director Blueprint and the Level Blueprint.

Implement the Interface in your Level

Next, open your Level Blueprint by clicking Level Blueprint in the Level Toolbar and selecting Open Level Blueprint.



Enable Class Settings, and in the Details panel click the Add dropdown menu for Inherited Interfaces. Locate and select your Blueprint Interface to add it to the Level Blueprint.



Right-click in the Event Graph and add the Event from your Blueprint Interface. The event name matches the name of the Function you named earlier in this guide. Add the Event and connect it to the Level Blueprint logic you want to trigger. Due to the arbitrary nature of Blueprints, this guide will assume your Level Blueprint logic is already created. In this example, the logic is activating a Niagara System.



Set Up Event Track

Now that the Level Blueprint side of the logic is set up, you can implement the rest of the logic in Sequencer's Event Track.

Open your Level Sequence, then create an Event Track by clicking Add Track (+) > Event Track > Trigger.



Select the Event Track and press Enter to create an Event keyframe at the Playhead. Double-click this keyframe to open the Director Blueprint and bind the keyframe to a new Event.



Implement Interface

Like you did in the Level Blueprint earlier, enable Class Settings in the Director Blueprint, and in the Details panel click the Add dropdown menu for Inherited Interfaces. Locate and select your Blueprint Interface to add it to the Level Blueprint.



Create Logic

Right-click in the Director Blueprint Graph and add the Function from your Blueprint Interface under the Call Function category. The Function name matches the name of the Function you named earlier in this guide.



Make sure you are using the Blueprint Interface Function that targets your Sequence Director BP. Other function targets will not work.



Connect the execution and target pins to the Event.



Bind Keyframe to Target

Lastly, return to the Event Track and right-click the keyframe. Under the Properties menu, set Pass Bound Object To to Target.



Connecting and binding the Target is a necessary step, despite there being no actual target. This is because when no target is specified, the Blueprint Interface system will fallback to the Level Blueprint, and then correctly link to the interface there.

Results

Once the preceding steps are finished, you can now play or simulate your level. Upon playing your sequence, the level event should trigger.



Using Take Recorder

Organizing and Reviewing Your Takes

Using Layered Take Recording

Take Recorder enables the fast iteration of recording performances and quickly reviewing previous takes for virtual production workflows. You can easily record animations from motion capture linked to characters in the level, as well as actual Live Link data for future playback. By recording takes and adding them to Sequencer, productions of all sizes and any number of takes can easily be accommodated.



The most common usage of Take Recorder will be with projects using Live Link. Because Take Recorder enables you to quickly record performances, using Live Link is an easy way to update and iterate on previous takes.

For this how-to, we use Live Link with the Face AR Sample. If you would like to follow along, see the Face AR Sample documentation for how-to set up Editor and Live Link.

Using Take Recorder

With the connection established, we can now use Take Recorder to capture a sequence.

Make sure you enable the Take Recorder plugin. You can do this by navigating to Edit > Plugins and searching for Take Recorder.

In Unreal Engine, navigate to Window > Take Recorder.

Select your Actor from the World Outliner. In Take Recorder, select + Source > From Actor > Add 'Actor Name' .



Select the Actor from the list. Under the Actor settings, make sure to change Record Type to the appropriate setting.

Select Play and then select the red record button in Take Recorder. The recording displays data in real-time in Sequencer, and you can see the motion capture live in the viewport.



When you are finished recording, click the Stop button in Take Recorder.

You can record as many takes as you need by repeating this process.

Organizing and Reviewing Your Takes

After you finished recording, there are two ways to view your takes in Sequencer. First, you can view the take you just recorded by selecting the Review the Last Recording icon (floppy disk with an eye). This allows you to review recorded tracks in Sequencer. If you decide you do not like the take and want to record again, you can switch back to record mode by selecting the Return Back to the Pending Take arrow icon.



To view your takes, select the Take Browser icon in Take Recorder. A separate window tab will appear with the folders of all your takes in the Content Browser. The Take Browser uses the location saved in the Take Recorder User Settings.





The default save location is under Cinematics > Takes To change the default save location in Content Browser, select the Take Recorder Settings icon. Under User Settings, change the Preset Save Location to the new location.





To review the sequence, double-click the file from the Content Browser. You can playback the sequence the same way as any other sequence.



There is also assigned metadata for each sequence that you can see by hovering over a sequence in the Content Browser. You can also see the metadata by using the Column View Type.



Using Layered Take Recording

Layered Take Recording allows you to add additional recorded tracks to an existing sequence. This is particularly helpful when using motion capture for multiple actors in a sequence.

Record your first take with "Actor A" as many times as you need. Then, choose the last or best take, and select Review the Last Recording to switch into review mode.

In review mode, select the clapboard icon Start a new recording using this Take as base.



The mode switches back to record, and you can see the take from Actor A in Sequencer.

Add a new Source for the second actor, "Actor B". Click the toggle button to disable "Actor A".



Record the take with Actor B. Once you are finished recording, select Review the Last Recording to playback the recordings simultaneously and preview the takes together. In this example, we hid Actor A from the viewport to record Actor B. You may or may not want to do this depending on what you are recording.

You can record and stack as many takes into a single sequence as you want. When you are finished, your entire sequence is saved as a single file, and each individual take is saved into a subfolder.

Sequencer Overview

Sequencer Editor Reference

Steps

End Result

When creating cinematics for gameplay purposes, there may be times when you want to animate an object in Sequencer that is dynamically spawned at runtime. For example, you can create and animate an object that moves along a path within Sequencer but that object is something which can be defined by the player that is spawned during gameplay. With the help of Blueprints Visual Scripting, you can expose binding identifiers from a Level Sequence using the Get Sequence Bindings node and override any of those bindings with your own settings.

In this example, we animate and move an Empty Actor along a path, allowing the player to change the object to different effects with the press of a button.



For this how-to guide, we are using the Blueprint Third Person Template project with Starter Content enabled.

Steps

From the Place Actors panel in the Basic tab, drag an Empty Actor into the Level.



We will animate this Empty Actor inside Sequencer and override the Sequence Bindings to change the Actor to different particle effects.

From the Main Toolbar, click the Cinematics button, then select Add Level Sequence and give the Sequence any name.



Select the Empty Actor in the Level, then add the Empty Actor to Sequencer.



Click the Track button on the Empty Actor and select Transform.



Add a keyframe for the Transform track to initialize the Empty Actors current location in the Level.



Scrub the Timeline ahead to frame 75, then move the Empty Actor up in the Level and add a keyframe for the new position.



Right-click and copy the first keyframe in Sequencer, then move to frame 150 and right-click and Paste the Transform key.



Copying the first key and pasting it at the end will give us a smooth sequence that we can loop.

In the Details panel for the Level Sequence, enable Auto Play and set Loop to Loop Indefinitely.



From the Main Toolbar, click the Blueprints button then select Open Level Blueprint.



In the Level Blueprint, right-click and add an F keyboard event connected to a Flip Flop node.



Add two Spawn Actor from Class nodes (one using Blueprint Effect Fire and the other using Blueprint Effect Sparks) and connect to a Make Transform node as shown.



Right-click on the SpawnActor Blueprint Effect Fire node's Return Value and select Promote to Variable and call it Fire BP.



Promote the Return Value for the SpawnActor Blueprint Effect Sparks to Sparks BP.

Add a reference to your Level Sequence, then off it, use the Add Binding node.



Create another Add Binding node and connect each as shown below, feeding the Fire BP and Sparks BP as the Actor.



Right-click and use the Get Sequence Binding node (setting the options highlighted below) and connect to both Add Binding nodes.



On the Get Sequence Binding node, you can specify the Level Sequence you want to target and the Binding you want to override. In our example, we only have one track listed in our Level Sequence (our Empty Actor) that we can override. Objects that are added to your Level Sequence that can be overridden will be displayed in the drop-down menu.

Bring in the Sparks BP and Fire BP variables and use an IsValid node and Destroy Actor if the object is valid.





Click image for full view.



Our script is complete and will spawn either the fire or sparks effect, override the Empty Actor in our Level Sequence then destroy the other particle effect (if it is valid).

Play in the Editor, then press the F key to cycle between our spawned Actors.

End Result

When we play in the Editor and press the F key, our Empty Actor is replaced by our spawned fire or spark effect and continues to use the animation we applied to the Empty Actor.

Not only can you add bindings, you can:

Remove Binding to remove the specified Actor from the specified binding.

Reset Binding to reset the specified binding back to its default settings.

Reset Bindings to reset all overridden bindings back to the default settings.

Set Binding to override the specified binding with the specified Actors.



Sequencer Overview

Sequencer Editor Reference

Steps

End Result

When creating and rendering out cinematic movies, you may want to include overlays with information about the scene you are viewing such as the name of the shot, the date, time or frame information. These overlays are referred to as Burn Ins as they are burned into the movie when it is rendered out. Often times you will see this process as part of real world movie making to provide directors, editors or anyone viewing the scene with contextual information about the scene (some will even be watermarked with copyright information).

Sequencer allows you to apply burn ins to your rendered out movies and provides a default burn in with general information about the shot. In this guide we take a look at how to enable the default burn in options when rendering out your cinematics.

For this how-to we are using the Blueprint Third Person Template project and have created a small sample cinematic.

Steps

Once you are ready to render out your Level Sequence, inside a Level Sequence click the Render Movie button.



In the Render Movie Settings window, click the Show Advanced expand button.



Under Burn in Options, click the Burn in Class dropdown and select DefaultBurnIn.



This will enable the ability to define the burn in settings.



Leave the options as default, then click Capture Movie.

End Result

When the capturing of your movie is complete, upon playing back your movie you will notice similar overlays applied to the cinematic. The Default Burn in applies the name of your Level Sequence across the Top Center followed by the current date. In the Bottom Left, the current Shot Name is applied (or Level Sequence name if no shots are used). The Bottom Center displays the time and frame count for the Master Sequence while the Bottom Right shows the current Shot Frame.

Each of these options can be changed to display your own text inside the Settings section of the Burn in Options. Additionally, you can apply Watermarks or make Font changes within the Default Burn In options.

You may want to view the video above in full screen or on YouTube to see the overlays more clearly.

Steps

End Result

Within Sequencer, it is possible to animate variables on Anim Instances through Possessables, enabling you direct control of Anim Blueprint variables, functions and other content. By adding a Skeletal Mesh Component Track, you can gain access to the Anim Instance Track where any variables that are exposed to cinematics will be shown and available to keyframe.

In this how-to, we blend between multiple animation poses that are defined within an Animation Blueprint by keyframing those changes inside Sequencer.

Steps

For this guide we are using a new Blueprint Third Person template project.

In the Content/Mannequin/Character/Mesh folder, right-click the SK_Mannequin then select Anim Blueprint under Create and give it any name.



Right-click in the Content Browser and under Blueprints, select Enumeration and call it MoveType.



Create three enumerators called, Idle, Walk and Run by clicking the New button.



Open the Animation Blueprint created in step 1 and create a variable of the MoveType type called MoveType and enable Expose to Cinematics.



On the Anim Graph, add the ThirdPersonIdle, ThirdPersonWalk and ThirdPersonRun animations and a Blend Poses by Move Type node.



Right-click on the Blend Poses node then add a pin for Idle, Walk and Run.



Add the Move Type variable to the graph and connect each of the nodes to the Final Animation Pose as shown below.



Drag the Animation Blueprint into the Level, then create a new Level Sequence (give it any name) and add the Anim Blueprint to the Sequence.



Click the + Track button on the Anim Blueprint and add an SkeletalMeshComponent0 track.



Click the + Track button on the SkeletalMeshComponent and add the Anim Instance track.



Click the + Track button on the Anim Instance and add the Move Type property.



Scrub the Timeline to frame 45 and change the Move Type drop-down to Walk, adding a key.



Scrub the Timeline to frame 90 and change the Move Type drop-down to Run, adding another key.



Add a key for Move Type at frame 120 set to Walk and another key at frame 150 set to Idle.



Set the Level Sequence to Auto Play in the Details panel, then click the Play or Simulate button to play/simulate in the Editor.

End Result

When you Play or Simulate, the Level Sequence will play back and change the character's state based on the key framed property Move Type defined in the Sequence. Animating variable properties is useful in the event that you have characters that have Animation Blueprints that drive their animation logic, however you want to control what animation the character enters through a Sequence.

Sequencer Overview

Sequencer Editor Reference

Steps

End Result

Sequencer in Unreal Engine not only allows you to render and export your entire cinematic, but you can also export your cinematic split up into each of your shots along with an Edit Decision List (EDL), which is a file that can be used with most video editing applications like Premiere, Avid or Final Cut.

The EDL contains an ordered list of reel and timecode data representing where each video clip can be obtained in order to produce the final cut. In this how-to, we export a cinematic and EDL file, take it into an external program (like Premiere), make edits to it, and re-import the edited cinematic back into UE4 along with those changes.

Steps

For this how-to, we are using the Blueprint Third Person Template project, having created a sample cinematic; however, you can use your own project and cinematic sequence. We are also using Adobe Premiere Pro CS6 as our external editing software; however, you can use any software that supports EDL importing.

Make sure the cinematic you want to export includes a Shot Track containing your shots, then click the Render Movie button.

Set the Output Format to Video Sequence, choose an Output Directory and Filename Format using the {shot} token, then enable Write Edit Decision List.

Here, we show the sample cinematic that we want to export (along with an EDL), and click the Render Movie button to bring up the settings dialog window. Inside the settings window, we create a new folder to export the cinematic to, and prefix our {shot} token with the name of our cinematic. By using the {shot} token, each of our shots will be exported as individual video files along with the full cinematic.

You must set the Output Format to Video Sequence in order for this to work, it does not work with individual frames.

Import the EDL file exported from the previous step into your external video editing software.

In Premiere Pro, you can right-click in the lower left of the window, choose Import, then point to the EDL file.

Link the data from the EDL to the exported media files in your external video editing software.

In Premiere Pro, you can right-click the media folder, select Link Media, then point each file to its corresponding media file.

Modify the shots in your external video editing software as desired, then Export as an EDL.

For our sample scene, we adjust the length of the shots as well as re-arrange their position in the sequence.

Returning to your Sequence in Unreal Engine, right-click your Shot Track and Import EDL.

The changes we made externally are now reflected inside our Sequence in UE4.

End Result

The import/export EDL option within Sequencer gives you the flexibility to determine where you want to do your editing. You can do most of your setup inside of Sequencer, then pass your sequence off to an editor that works inside an external application (like Premiere) to perform the final touches, who can then pass it back to you to tweak in Sequencer. By exporting your sequence as an EDL and working externally, you have the ability to add post production effects (or after effects) to your scene before rendering out the final cinematic.

Optionally, when rendering out your sequence and exporting an EDL, you can add Frame Handles automatically to each shot, and define the number of frames to include.



These extra frames pad each shot and are cut into and out of by the EDL, which can be used in your external video editing package to adjust the cuts between shots.

Sequencer Overview

Blueprints Visual Scripting

Steps

End Result

Once you have created your cinematic sequence, you may want to have it called and played during gameplay as part of a cutscene. For example, maybe the player walks into a room and you want to have the camera zoom in on an object. Or perhaps you want to trigger an ending cinematic after the player kills an enemy. By getting a reference to your Level Sequence, you can use Blueprint or C++ code to tell your sequence to start playing.

In this How-to, we create a sample cinematic that turns on a light when the player enters a Trigger Box. When the cinematic finishes playing, we'll instruct Sequencer to apply the changes to the light in the Level so it persists after the cinematic has finished playing. We also allow the player to skip the cinematic while it is playing but still instruct Sequencer to turn and leave the light on after skipping the scene.



Steps

For this How-to, we are using the Blueprint Third Person Template project.

From the Place Actors panel in the Basic tab, drag a Box Trigger into the Level and resize and position as desired.



When the player enters our trigger, we will instruct our cinematic to start playing through Blueprint.

From the Main Toolbar, click the Cinematics button then select Add Level Sequence and give your cinematic a name.



From the Place Actors panel in the Basic tab, drag a Point Light into the Level and place the light in the position shown below.



With the Point Light selected, in the Details panel, change the Intensity value to 0.0 and click the Keyframe button.



This will add the Point Light to Sequencer and keyframe its initial value at the start of the sequence.

In Sequencer, move the timeline to frame 150 and set the Intensity value of your light to 5000 and keyframe it.



Click image for full view.

Your Point Light will now start in the off position and get brighter as the Sequence plays out.

Click the Add Camera Button, then move the Camera in the Level to a position near the Character and keyframe it.



Click image for full view.

Move the Timeline to frame 75, then in the Level, move the Camera to a new position overlooking the Character and the light and keyframe it.



Click image for full view.

Move the Timeline to frame 150, then in the Level, move the Camera to a position focused on the light and keyframe it.



Click image for full view.

Our cinematic now has a camera fly-through animation that will show the player where the light is in the Level.

Select the Trigger Box in the Level, then from the Main Toolbar, click the Blueprints button and select Open Level Blueprint.



Right-click inside the graph, then select the Add On Actor Begin Overlap for the Trigger Box.



Return to the Level and select your Level Sequence, then back inside the Level Blueprint, right-click and Create a Reference to your Level Sequence.



Drag off the Level Sequence reference and select Play (SequencePlayer).



Connect the OnActorBeginOverlap node to the Play node.



When entering the Trigger Box, the Play node will be executed and will play your Level Sequence.

You will notice if you play in the Editor that the sequence plays when entering the Trigger Box, however, it will only play once. If you want to play the sequence again, you will need to start the sequence over using the Set Playback Position node with the Playback Position set to 0 (or the start of the sequence) before telling the sequence to play.

In the Level Blueprint, drag off the Sequence Player node and use the Set Playback Position node.



Connect the Set Playback Position node between the OnActorBeginOverlap and Play nodes.



This will set the Level Sequence back to the beginning prior to playing it.

Inside Sequencer, right-click on the Intensity track, then under Properties set When Finished to Keep State.



Using the Keep State option enables our light Intensity setting to remain after the sequence has ended. This is useful for situations where you want effects or settings you make in Sequencer to remain after the Sequence has ended. For example, your cinematic opens a door and you want the door to remain open once the cinematic ends.

In the Level Blueprint, add an F keyboard event connected to a Branch (with condition Is Playing) that is connected to the Go to End and Stop node.



When pressing the F key, if the Level Sequence is currently playing, it will immediately jump to the end and stop playing. The Go to End and Stop node is useful for situations when you want to allow your player to skip your cinematic but continue with any changes that Sequencer would have applied if the Sequence continued playing.

For example, in our cinematic, Sequencer turns on a light in the Level. If the player skips the cutscene of the light being turned on, we still want the light to be on after the cutscene is skipped. If we were to simply use the Stop node to stop playing our cinematic, it would not complete the cinematic and would stop at whatever point in the cinematic we chose to stop (meaning the light would not be fully on or not on at all depending on where we stopped).

Return to the Main Editor, then from the Main Toolbar, click the Play button to play in the Editor.

End Result

When you play in the Editor, you will notice that the light is not on by default. When entering the Trigger Box, the cinematic will start playing and the light will turn on and stay on when the cinematic completes. You can re-trigger the cinematic by entering the Trigger Box again, which will play the sequence from the beginning. You can also enter the Trigger Box and press the F key to skip the cinematic, which will result in the light automatically turning on.

Steps

End Result

When working in Sequencer, you may make changes to the properties of your Actors that you want to persist after the cinematic finishes. For example, you might create a cinematic where a player unlocks and opens a door, and the door remains in the open state afterward. In a film production environment, however, you may want animated values in a shot to return to their pre-animated state so they don't bleed into the next shot. With the When Finished property, you can determine on a per-track basis whether tracks should return to their pre-animated state or keep changes when the sequence finishes.

In this how-to guide, you will use the When Finished property to restore the color change of a light but keep the changes made to the movement of a door.



Steps

For this how-to guide, we are using the Blueprint Third Person Template with Starter Content enabled.

From the Content/StarterContent/Props folder, drag an SM_Door and SM_DoorFrame into the Level Viewport and position the door inside the frame.



Press the W key to enter translation mode and, if needed, disable grid snapping (pictured below) to fine tune the position of the door in the frame.



From the Place Actors panel in the Lights tab, drag a Point Light into the Level Viewport and position it in front of the door.



Position the ThirdPersonCharacter in the Level Viewport in front of the door.



From the Main Toolbar, click the Cinematics button and select Add Level Sequence.



In the Save Asset As window, select a Name and save location, then click Save.



In the Sequencer window, click the Add button and select Shot Track.



This will create a Shot Track which enables you to section off parts of your cinematic into self-contained "shots" that you can arrange and re-arrange.

On the Shot Track, click the + Shot button and Insert Shot and use the default naming convention when prompted.



Grab the end of the shot and pull it back to Frame 75 so the shot is half the length of the entire sequence.



We are going to use the shot to affect the light in our scene, but restore those changes once the shot is over.

With the Timeline at Frame 0 and the SM_Door selected in the level, add the Actor To Sequencer from the + Add button.



We will affect the door on the master level and keep the state of the changes we are going to apply.

Click the Add (+) button on the Transform track of SM_Door.



Move the Timeline marker to Frame 150, then rotate the door (E key) in the level so it is open and press the S key to add its transform while open.



This will cause the door to go from closed to open once we reach the end of the cinematic.

Double-click on the shot in the Shot Track to open it, then in the level select the Point Light and add it to the shot.



On the Light Color track, click the + sign to assign the default color to use at Frame 0 of the shot.



Move the Timeline marker to Frame 75 and change the Light Color to Green (or any color you desire) adding keys for the new values.



Right-click on the Light Color track in the tracks window and select Properties to view the When Finished state.



By default, When Finished states that this track will Restore State (return to its original state) when the section is completed.

Exit the Shot and return to the Master Sequence level by clicking the breadcrumb buttons in the upper-right of the Sequencer window.



Right-click on the Transform track of the SM_Door and select Properties, then change the When Finished property to Keep State.



We are now stating that we want to Keep State, meaning we want to keep the changes that we apply through Sequencer when the cinematic is complete.

Select the Level Sequence Actor in the level, then, in the Details panel, set the Auto Play option to True.



From the Main Toolbar, click the Build button and select Build Lighting Only, then (after lighting has built) click the Play button.



End Result

When you play in the level, the light will change colors before returning to white. Our door, however, will remain in the opened state.

For the light inside our shot, we used the default When Finished property value of Restore State, which will restore it back to its original state when the shot is finished. For the door, however, we changed the When Finished property to Keep State preserving our changes and keeping the door in the open state when the cinematic completes.

One thing to consider is that, while Keep State has a local effect, there is a global Restore State option contained within the Level Sequence actor:



The Restore State option in the Details panel of a Level Sequence actor will restore all states when the Level Sequence stops. If you want to keep the state of a track after the sequence has completely finished, you will need to make sure both that your section is set to Keep State, and the Level Sequence actor is not set to Restore State, otherwise the global value will override your local settings.

Steps

End Result

If you want to blend an animation assigned within Sequencer with an animation defined from a Character's Animation Blueprint, you can do so using a Slot node and the Weight property of an Animation Track in Sequencer.

In this example, we take the idle pose from our Animation Blueprint and blend in a running animation defined from Sequencer.

Steps

For this how-to guide, we are using the Blueprint Third Person Template project.

In the Content/Mannequin/Character/Mesh folder, right-click the SK_Mannequin then under Create, select Anim Blueprint.



Give the Animation Blueprint any name and save location.

Inside the Anim Blueprint, drag in the ThirdPersonIdle and connect to a Slot node, then connect to the Final Animation Pose node.



Notice the Slot node is given the name DefaultSlot by default and is the name we will refer to inside our Level Sequence later in this guide.

Drag the Anim Blueprint into the Level, then from the Main Toolbar, select Cinematics and select Add Level Sequence.



Give the Level Sequence any name and save location.

Add the Anim Blueprint character to the Sequence, then add/loop the ThirdPersonRun animation to fill the Sequence.



Expand the Animation track, then change the Weight value to 0.0 and add a key to the Sequence.



By setting the Weight to 0.0, we are stating that we want to use no part of this Animation until we increase the Weight value.

Add a key for Weight with the value 1.0 at frame 75, and another key with a value of 0.0 at frame 150.



This will blend from 0.0 to to 1.0 (full effect of the animation) back down to 0.0.

Right-click on the ThirdPersonRun track, then under Properties, notice the Slot Name, and the three Keys we added.



Slot Name is the name referring to the Slot Node added inside the Animation Blueprint. These names must match in order for Sequencer to know which Slot you are referring to and to pass through the Weight values.

Select the Level Sequence, then in the Details panel, enable Auto Play and set Loop to Loop Indefinitely.



From the Main Toolbar, select to Play in the Editor.

End Result

When you play in the Editor, the character will starting idle (which is the state inside our Animation Blueprint) and will blend to the animation we assigned (running) inside our Level Sequence, then back to idle.

While our example uses an idle animation as our Final Animation Pose, using this method you can generate an entire State Machine to produce the Final Animation Pose inside your Animation Blueprint based on any number of factors, then blend to an animation defined inside a Level Sequence.

As an example, an NPC could have some logic defined that governs what pose they are in and the player could approach that NPC triggering a cutscene where you override the animation logic with an animation defined within Sequencer.

Playback

Spacebar Playback Toggle

Inclusive and Exclusive Frames

Workflow Shortcuts

Middle-Mouse Scrubbing

Adding Actors to Sequencer

Default Tracks

Auto Size Shots

Shift Snapping and Alignment

Warm-Up Rendering

Particles

Cloth and Physics

Temporal Artifacts

To improve your cinematic animation productivity, several shortcuts have been built into the Sequencer Editor. This document provides tips for common workflows, overcoming problems, and other helpful features of Sequencer.

Playback

Spacebar Playback Toggle

By default, using the Space Bar as a hotkey to toggle playback of your sequence only works if your window focus is on Sequencer. If your focus is on the Viewport, then pressing the Space Bar will instead cycle between transform manipulation modes.

You can make the Space Bar toggle playback of Sequencer regardless of window focus by following these steps:

Open the Editor Preferences window and locate Cycle Between Translate, Rotate, and Scale under General > Keyboard Shortcuts. Unbind this shortcut by clicking Remove this binding (X).



You will still be able to use hotkeys to switch between these transform modes by pressing Q, W, E, and R to enable Select, Translate, Rotate, and Scale, respectively.

From the Viewport's Perspective menu, enable Cinematic Viewport.



Now you can press the Space Bar while your focus is on either the Sequencer or the Cinematic Viewport, and the playback will toggle correctly.



Inclusive and Exclusive Frames

Animation within Unreal Engine uses the concepts of "inclusive" and "exclusive" frames, which determine if a full frame is being included or evaluated fully. Typically this matters when defining start and end frames in your sequence, such as for animations, shots, or overall Sequencer playback times.

For Sequencer, the start frame is inclusive and the end frame is exclusive, which causes all frame data up to the end frame to be evaluated. In this example, where the start time is set to 0, and the end time is set to 10, this means that the actual elapsed time is 9.999 (repeating) frames. In other words, it evaluates up to, but not completely to, the end time. This mimics behavior seen in most non-linear editing software such as Adobe Premiere.



Because of this functionality, you can expect the following behavior:

If Keep Cursor in Playback Range While Scrubbing is enabled, then it should be impossible to scrub or view the exact end frame in a sequence. While data can exist on that frame, Sequencer will never reach it. In this example, the end time is 0346 frames, but playback only reaches 0345* .



If the Playhead is at the same point where two sections touch, such as shots, then the data from the next shot will be shown instead of the previous shot.



When rendering image sequences with Movie Render Queue, the end frame will be excluded. This means that if your sequence contains frames 0 - 50, the image sequence will output frames 0 - 49.



Sequencer's treatment of inclusive and exclusive frames differs from Animation Sequences, which includes both start and end frames. When an animation FBX is imported, Unreal Engine will include a small amount of data beyond the final frame, which causes the final frame to be fully included. This can be observed in Sequencer if you zoom in far enough on the end of an unedited Animation Section.



However, trimming, and other section editing operations on the animation will restore Sequencer's end frame exclusive behavior.

Workflow Shortcuts

Middle-Mouse Scrubbing

Similar to Autodesk Maya, you can change your current time without causing updates or evaluations to occur by clicking and dragging the middle mouse button in the timeline. This can be useful when you want to set additional bracketing keyframes at the same value but at different times. When manipulating the playhead in this way, it will change its color to yellow to indicate the sequence is not evaluating.



Adding Actors to Sequencer

When dragging new Actors into your Level from the Content Browser or by placing Actors, pressing certain keys will also add them to Sequencer. Depending on the pressed key, it will add the Actor as either a spawnable or possessable.

Holding Ctrl will add the new actor to Sequencer as a possessable.

Holding Shift will add the new actor to Sequencer as a spawnable.



Default Tracks

When adding certain Actors to Sequencer, you may notice that tracks are automatically created with them. For example:

Static Mesh Actors will automatically create a Transform Track.



Skeletal Mesh Actors will automatically create a Transform Track and an Animation Track.



Cine Camera Actors will automatically create a Transform Track and a Camera Component with Aperture, Focal Length, and Focus Distance property tracks.



Light Actors will automatically create a Light Component with Intensity and Light Color property tracks.



This occurs because of the Tracks Settings located in the Sequencer Plugins Project Settings. You can locate these settings by opening the Project Settings window, and locating Level Sequencer in the Plugins category.



The Track Settings array is populated by default with settings for the previously mentioned tracks. You can click the Add (+) button to add a new array item, and each array has the following categories:



Name

Description

Matching Actor Class

This is where you specify the Actor class to automatically create tracks for when adding it to Sequencer.



Default Tracks

This array is where you specify the tracks that are added when the Matching Actor Class is added to Sequencer. Click the Add (+) button and click the dropdown menu to browse Sequencer's track types.



Exclude Default Tracks

This array is where you specify tracks you don't want added for this Actor class. You may want to use this if you are specifying different tracks to add, such as when your class is inheriting from a parent class which also has its default tracks specified here.

Default Property Tracks

This array is where you specify the property tracks that are added when the Actor is added to Sequencer. Click the Add (+) button to add a new property item to the array.



Component Path is where you specify the Actor's component you want to add the property from.

Property Path is where you specify the property name you want to automatically add.

Exclude Default Property Tracks

This array is where you specify property tracks you don't want added for this Actor class. You may want to use this if you are specifying different tracks to add, such as when your class is inheriting from a parent class which also has its default property tracks specified here.

Auto Size Shots

When adjusting start and end times of shots internally, you can automatically match the parent shot section to these edits using the Auto Size command. To do this, right-click the shot and select Edit > Auto Size. This can be useful if you are retiming your shot and want the shot section to match, without needing to re-trim manually.



Shift Snapping and Alignment

When dragging section assets onto Sequencer tracks, such as audio, subsequence, or animation tracks, holding Shift will snap the dropped section to the Playhead location.



If Snap to the Pressed Key is disabled, you can still align the Playhead to keyframes by holding Shift and clicking the keyframe. This makes it easy to perform subsequent actions, such as changing the value of this keyframe, or aligning other keys to it.



Warm-Up Rendering

When creating pre-rendered sequences with Movie Render Queue (MRQ), it may be necessary to "warm up" each shot in order for various aspects of your scene to render correctly. For example, some common problems can be:

Particles and other effects activating at the start of the shot, instead of already being active.

Cloth and other physics-driven entities exhibit a noticeable "settle" at the start of the shot.

The first rendered frame of a shot can exhibit noticeable aliasing or other temporal artifacts (sparkles).

You can use various warm-up properties within Movie Render Queue's Anti-Aliasing Render Settings to resolve these scenarios. Depending on the scenario, there may also be different considerations to take into account that will determine which settings are best to use.

Particles

In some cases, you may want particles and other effects to be active for a certain duration of time before a shot begins. While real-time previewing might show the correct behavior, rendering with MRQ may cause your particle system to activate at the start of the shot, which is undesirable.





Particle with no warm-up

Particle with warm-up

For this particle scenario, you can resolve it in either of the following ways:

Create the particle's Activate keyframe at the start time of your shot, then set a frame value on Engine Warm Up Count. This value can be arbitrary depending on how many frames are needed for your particle to warm up.



Or, you can create or move the particle's Activate keyframe to the pre-start region of the sequence, along with the Camera Cut section. Then, enable Use Camera Cut for Warm Up. This will cause the warm-up time to be defined by the pre-start area that the Camera Cut track section occupies.



If your particle is GPU-based, then you will also need to enable Render Warm Up Frames.



Cloth and Physics

For cloth and other physics objects, a common problem when rendering is that they can exhibit a noticeable settle at the start of a shot. This is due to the game simulation not starting until the rendering begins, therefore physics needs time to settle to its true simulated state.





Cloth settles at start (no warm-up)

No cloth settling (with warm-up)

For shots where the character or physics object is not initially moving, such as being in an idle pose, you can fix this by setting a frame value on Engine Warm Up Count. This value can be arbitrary depending on how many frames are needed for your physics to settle. Typically, a value greater than 30 should be used.



In scenarios where shots start with the physics object in motion, such as running or jumping, then Engine Warm Up Count will not produce an accurate result. This is because it only "warms up" the starting frame and does not take into account motion that may be occurring beforehand. Here you can observe the cloth in the left example starting at an unnatural rest position, then correcting as the simulation reacts to the motion.





Cloth starts at rest (incorrect warm-up settings)

Cloth starts correctly behind (using correct warm-up settings)

In order to resolve this, you must do the following:

Make sure that your physics character or object contains animation data in the pre-start region of Sequencer, including the Camera Cuts section. This may require you to alter your animation and transform track keyframes in order to extend it into the pre-start region.



If you are previewing your shot in context, then you may want to enable Evaluate Sub Sequences In Isolation from Sequencer's Playback Options menu. Otherwise, scrubbing into the negative timeline region will preview the previous shot and not the pre-start region of your current shot.

In the Anti-Aliasing image settings, enable Use Camera Cut for Warm Up. This will cause the warm-up time to be defined by the pre-start area that the Camera Cut track section occupies. This will result in the sequence accumulating the pre-start motion so that the physics state at the start of the shot is accurate. Unlike Engine Warm Up Count, which evaluates and holds on the first frame, Use Camera Cut for Warm Up will evaluate the sequence leading up to the starting frame.



This technique can be used to also build a movement history for other things, such as trail particles.

Temporal Artifacts

Aliasing and other artifacts caused by rendering features that have a temporal component, such as Temporal Anti Aliasing (TAA), Temporal Super Resolution (TSR), or raytracing denoisers, can also occur on the first few frames of your shots. Typically, this issue appears as noticeable hard edges or grainy sparkling on reflective surfaces. This is due to the lack of temporal history being accumulated at the start of a render.





Sparkling and jagged edges (no warm-up)

Smooth edges and highlights (with warm-up)

To resolve this issue, you can do either of the following:

Set a frame value for Render Warm Up Count. This value will be the number of frames to render beforehand to build a temporal history for the first frame.



If increasing Render Warm Up Count does not resolve the issue, then you can instead increase the Engine Warm Up Count value and enable Render Warm Up Frames. This will evaluate the first frame of the sequence and then continually tick the engine and renderer until the Engine Warm Up Count frames have passed.



Playback and Timing

Timeline and Track Navigation

Keyframing

Keyframe Interpolation

Section Editing

Transform Track

The following is a list of Sequencer's main hotkeys and their functions.

Playback and Timing

Command

Description

Spacebar

Toggles playback of the sequence between play and pause.

Down Arrow

Plays the sequence.

K

Pauses the sequence.

Up Arrow

Jumps to the start of the sequence.

Ctrl + Up Arrow

Jumps to the end of the sequence.

Left Arrow

Steps backward in the sequence by a single frame.

Right Arrow

Steps forward in the sequence by a single frame.

L

Shuttles forward. Shuttle is an editing concept that describes playing the sequencer at incremental speeds. Pressing this key will start playing the sequence and repeatedly pressing it will increase the speed.

J

Shuttles backward. If the sequence is already playing or shuttling forward, then this will decrease the speed with each press and eventually start playing backwards.

Shift + Left Arrow

Steps backward in the sequence by the amount defined by Jump Frame Increment in the Playback Options menu.

Shift + Right Arrow

Steps forward in the sequence by the amount defined by Jump Frame Increment in the Playback Options menu.

Ctrl + Left Arrow

Moves a selected keyframe or section backward by a single frame.

Ctrl + Right Arrow

Moves a selected keyframe or section forward by a single frame.

[

Sets the start time of the sequence to the playhead.

]

Sets the end time of the sequence to the playhead.

End

Sets both the start and end times of a master sequence to match the duration of all shots.

.

Steps forward in the sequence by each keyframe and section bounds.

,

Steps backward in the sequence by each keyframe and section bounds.

I

Sets the start point of a custom timeline selection range to the playhead.

O

Sets the end point of a custom timeline selection range to the playhead.

Page Up

Creates a custom timeline selection range which encompasses the previous shot from the playhead.

Page Down

Creates a custom timeline selection range which encompasses the next shot from the playhead.

M

Toggles the creation or deletion of a custom timeline mark at the current playhead time.

Ctrl + Shift + .

Fast-forwards Sequencer playback to the previous custom timeline mark.

Ctrl + Shift + ,

Fast-forwards Sequencer playback to the next custom timeline mark.

Ctrl + Shift + T

Cycles time display between Timecode, Seconds, and Frames.

Ctrl + A

Adds the currently-selected Actor to Sequencer.

Shift + S

Toggles auto-scroll. When enabled, this automatically scrolls the timeline to keep the playhead visible as the sequence plays.

Ctrl + T

Go to a specific time in the timeline by typing in a numeric value and then pressing Enter.

Ctrl + R

Restores all objects animated by Sequencer back to their original editor-default state.

Timeline and Track Navigation

Command

Description

Right-Click Drag

Pans the timeline view according to your cursor movement.

Scroll Mouse Wheel

Pans the timeline up and down.

Shift + Scroll Mouse Wheel

Pans the timeline left and right.

Ctrl + Scroll Mouse Wheel

Zooms the timeline.

Alt + Shift + Right-click Drag

Zooms the timeline according to your cursor movement.

Home

Restores the timeline zoom level to frame the start and end times.

-

Zooms in the timeline by 10%.

=

Zooms out the timeline by 10%.

V

Toggles expanding and collapsing selected tracks by a single level.

Shift + V

Toggles expanding and collapsing selected tracks and their descendants.

Ctrl + G

Groups the selected tracks into a new folder.

Shift + G

Removes the selected tracks from a folder.

Alt + Left

Goes back and opens the previously-viewed shot or sequence.

Alt + Right

Goes forward and opens the previously-viewed shot or sequence.

Ctrl + F

Focuses on the search bar so you can search for track names in the Sequencer.

Ctrl + [

Selects all keyframes and sections backward from the playhead.

Ctrl + ]

Selects all keyframes and sections forward from the playhead.

Keyframing

You can use the following commands for primary keyframe operations.

Command

Description

Enter

Creates a keyframe for each selected track at the playhead.

Middle-Click

Creates a keyframe for the selected track at your cursor location.

Ctrl + Shift + V

Pastes copied keyframes from Sequencer's clipboard history. Each time you copy keyframes, they are added to a special Sequencer clipboard history. You can then choose to paste any specific set of copied keys anytime from this history.



Ctrl + Left

Moves selected keyframes and sections left by a single frame.

Ctrl + Right

Moves selected keyframes and sections right by a single frame.

Ctrl + M

Moves selected keyframes and sections by a specified amount.

Keyframe Interpolation

You can use the following hotkeys to set keyframe interpolation modes.

Command

Description

1

Sets the selected keyframes to Cubic (Auto). It attempts to maintain a smooth curve between keyframes and eases both the start and end keyframes. It automatically adjusts whenever you add or move keyframes.

2

Sets the selected keyframes to Cubic (User). Cubic (User) is similar to Cubic (Auto), but it locks the tangent from any further automatic edits when you add or move keyframes.

3

Sets the selected keyframes to Cubic (Break). Cubic (Break) is similar to Cubic (Auto), but its tangents are broken, allowing you to specify different incoming and outgoing angles from the Curve Editor.

4

Sets the selected keyframes to Linear. Linear tangents cause keyframes to have no smoothing or easing between them, causing abrupt starts and stops when reaching each keyframe.

5

Sets the selected keyframes to Constant. Constant tangents function similarly to non-interpolating keyframes by maintaining their current value until the next keyframe is reached.

Section Editing

You can edit Sections with the following commands.

Command

Description

Ctrl + /

Splits the selected section at the playhead location.

Ctrl + ,

Trims the selected section's left side to the playhead location. This command only removes section data.

Ctrl + .

Trims the selected section's right side to the playhead location. This command only removes section data.

Alt + [

Trims all sections' left sides on the selected track to the playhead location. This command can add or remove section data.

Alt + ]

Trims all sections' right sides on the selected track to the playhead location. This command can add or remove section data.

Transform Track

You can use the following commands to keyframe an Actor's transform.

Command

Description

S

Creates a Transform track (if it does not exist) and keyframes the Location, Rotation, and Scale properties.

Shift + W

Creates a Transform track (if it does not exist) and keyframes the Location property only.

Shift + E

Creates a Transform track (if it does not exist) and keyframes the Rotation property only.

Shift + R

Creates a Transform track (if it does not exist) and keyframes the Scale property only.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Starting Out

Creating Rigs

Creating Animation

Unreal Engine provides a suite of animation tools for you to rig and animate characters directly in-engine, called Control Rig. Using Control Rig, you can bypass the need to rig and animate in external tools, and instead animate in Unreal Editor directly. With this system, you can create and rig custom controls on a character, animate in Sequencer, and use a variety of other animation tools to aid your animating process.

This page contains links to documentation covering Unreal Engine's Control Rig tools and real-world examples of their workflows.

Starting Out

If you're just starting to learn about animating within Unreal Engine, this page gives a quick overview of how to create and animate a basic Control Rig.



Learn the basic fundamentals of Control Rig in Unreal Engine.

Creating Rigs

Control Rigs are the primary assets you will be using to create your rigs. These pages describe its usage and primary features.



Start rigging by creating a Control Rig Asset and learning about its various features.



Learn about the various tools and areas in the Control Rig Editor.

Learn about the various tools and areas in the Control Rig Editor.



Learn about the primary Rig Elements you can use for constructing Control Rigs.

Learn about the primary Rig Elements you can use for constructing Control Rigs.



Learn about the different solve directions in Control Rig and the features they enable.

Learn about the different solve directions in Control Rig and the features they enable.



Build Full Body IK systems for your character.

Build Full Body IK systems for your character.



Utilize Splines in your Control Rig to achieve easier procedural animation on long joint chains.

Utilize Splines in your Control Rig to achieve easier procedural animation on long joint chains.



Save bone poses and states to reference in your Control Rig graph.

Save bone poses and states to reference in your Control Rig graph.



Customize your controls using different control shapes from the Control Shape Library.

Customize your controls using different control shapes from the Control Shape Library.



Use Control Rig in Blueprints using the Control Rig Component.

Use Control Rig in Blueprints using the Control Rig Component.



Construct and reference public Control Rig functions to speed up your rigging workflows.

Construct and reference public Control Rig functions to speed up your rigging workflows.



Extend and customize the Control Rig Rigging process using Python scripting.

Extend and customize the Control Rig Rigging process using Python scripting.



Find and fix issues inside the Control Rig graph using Control Rig Debugging tools.

Find and fix issues inside the Control Rig graph using Control Rig Debugging tools.

Creating Animation

Once you have created your Control Rig, you can animate it in Sequencer and other areas of Unreal Engine. These pages provide an overview of this process.



Start animating your Control rig using various tools and workflows.



Enable Animation Mode to provide an animator-friendly workspace and tools in Unreal Engine.

Enable Animation Mode to provide an animator-friendly workspace and tools in Unreal Engine.



Procedurally affect your Control Rig by using it in Animation Blueprints.

Procedurally affect your Control Rig by using it in Animation Blueprints.



Quickly edit animation without needing Control Rig Assets using FK Control Rig.

Quickly edit animation without needing Control Rig Assets using FK Control Rig.



Attach the position, orientation, or scale of an object to other objects using a variety of constraints.

Attach the position, orientation, or scale of an object to other objects using a variety of constraints.



Dynamically re-parent your Controls when animating with Control Rig.

Dynamically re-parent your Controls when animating with Control Rig.



Drive and extend your Control Rig animation workflow using Python scripting.

Drive and extend your Control Rig animation workflow using Python scripting.

What is a Control Rig?

How do I Create and Open a Control Rig?

How do I Rig and Animate with Control Rig?

Create Control

Edit Control Shape

Drive Bone with Control

Animate Control in Sequencer

This page provides an overview of Control Rig, and shows how to create and animate rigs in Unreal Engine.

What is a Control Rig?

Control Rig is Unreal Engine's solution to animating characters directly in the engine.

The Control Rig Editor is where you can create custom controls, channels, and other manipulators for your characters. After a rig is created, you can animate these controls within other areas of Unreal Engine, such as Sequencer.



Control Rigs require the creation of Control Rig Assets, which are created and stored in the Content Browser.



How do I Create and Open a Control Rig?

The main way to create a new Control Rig asset is to right-click on a Skeletal Mesh in the Content Browser and select Create > Control Rig. This creates a Control Rig asset in the same directory with the postfix "_CtrlRig".



Next, double-click on the Control Rig asset to open the Control Rig Editor.



How do I Rig and Animate with Control Rig?

One of the simplest control types you can create is an FK Control. This guide gives an overview of how to create this control and animate it in Sequencer.

Create Control

In the Control Rig Editor, select the Rig Hierarchy tab to view the skeleton hierarchy for your character. Navigate to the bone you want to animate, right-click it, and select New > New Control.



This creates a control at the same location and orientation of the bone. The control is also named the same as the bone with the postfix "_ctrl".



Although you can keep the control nested within the skeleton hierarchy, it is best practice to remove it from the hierarchy and build your own control rig hierarchy adjacent to the skeleton. Select the control and press Shift+P to unparent the control from the skeleton.



Edit Control Shape

In order to better see and select the control in the viewport, you can change the Control Shape. To do this, navigate to the Details panel and locate the Control Shape property category. Here you can set a new shape using the Shape property, as well as customize the scale and offset of it using the Transform properties.

For this example, the shape is set to Circle_Thick, Rotation Y is set to 90, and all Scale axes are set to 3.0.



Drive Bone with Control

Next, reference your control and bone in the Rig Graph. Do this by dragging the control from the Rig Hierarchy panel into the graph, then select Get Control.



Do the same for the bone you want this control to affect. Drag the bone from the Rig Hierarchy panel into the graph, then select Set Bone.



Connect the Transform output data pin from the Get Transform - Control node to the Transform input data pin of the Set Transform - Bone node, then connect the Execute output pin from the Forwards Solve node to the input execution pin of the Set Transform - Bone node.



You can now manipulate the control in the viewport and see the control driving the bone.



Clicking Compile resets the control position back to default.

Animate Control in Sequencer

Now that your control is appropriately manipulating a character's bone, you can start to animate it in Sequencer.

Drag the Control Rig Asset from the Content Browser into the Level viewport. Once this is done, Sequencer opens with the character added to it as a Track.



Expand the Control Rig track to locate the controls you created. You can either select them here, or in the viewport.



With the control selected in the Viewport, press the S key to create a transform Keyframe for the selected control at the Playhead. Afterward, drag the Playhead to a different location in the sequence, manipulate your control, then press S again to set a second Keyframe.



Now when playing or scrubbing the sequence, you should see your control and character animate between the two keyframes.



Create Control Rig Asset

Rigging Features

In order to animate characters in Unreal Engine, you must first create controls for it. Control Rig contains various features and tools to create unique rigs for characters of all shapes and sizes.

This page provides an overview of creating Control Rigs, and the primary features of rigging.

Create Control Rig Asset

You can view the Control Rig Editor when you open a Control Rig Asset from the Content Browser. This Asset can be created in the following ways.

In the first method you can right-click on your Skeletal Mesh Asset and select Create > Control Rig. This creates a Control Rig Asset in the same directory with the postfix _CtrlRig. Double click the Asset to open it.



The second method is to create a Control Rig manually. You can do this by clicking in the Content Browser and selecting Animation > Control Rig. Next, in the pop-up window, select ControlRig and click Create. Double click the Asset to open it.



If you create a Control Rig this way, you will need to manually assign the Skeletal Mesh to your Control Rig Asset after opening. This is done by clicking Import Hierarchy in the Rig Hierarchy tab, then specifying your Skeletal Mesh.



Refer to the Control Rig Editor page to learn more about the Control Rig Editor's interface and features.

Rigging Features

The following features are available to help you rig your Control Rig in Unreal Engine.



Learn about the various tools and areas in the Control Rig Editor.

Learn about the various tools and areas in the Control Rig Editor.



Learn about the primary Rig Elements you can use for constructing Control Rigs.

Learn about the primary Rig Elements you can use for constructing Control Rigs.



Learn about the different solve directions in Control Rig and the features they enable.

Learn about the different solve directions in Control Rig and the features they enable.



Build Full Body IK systems for your character.

Build Full Body IK systems for your character.



Utilize Splines in your Control Rig to achieve easier procedural animation on long joint chains.

Utilize Splines in your Control Rig to achieve easier procedural animation on long joint chains.



Save bone poses and states to reference in your Control Rig graph.

Save bone poses and states to reference in your Control Rig graph.



Customize your controls using different control shapes from the Control Shape Library.

Customize your controls using different control shapes from the Control Shape Library.



Use Control Rig in Blueprints using the Control Rig Component.

Use Control Rig in Blueprints using the Control Rig Component.



Construct and reference public Control Rig functions to speed up your rigging workflows.

Construct and reference public Control Rig functions to speed up your rigging workflows.



Extend and customize the Control Rig Rigging process using Python scripting.

Extend and customize the Control Rig Rigging process using Python scripting.



Find and fix issues inside the Control Rig graph using Control Rig Debugging tools.

Find and fix issues inside the Control Rig graph using Control Rig Debugging tools.

Toolbar

Viewport

Rig Hierarchy

My Blueprint

Execution Stack

Curve Container

Rig Graph

Details

Preview Scene Settings

This page outlines the user interface, tools, and features contained within the Control Rig Editor.



Toolbar

Viewport

Rig Hierarchy

Rig Graph

Details

Toolbar



The Control Rig toolbar contains buttons and settings for previewing behavior and Control Rig construction. The buttons with specific Control Rig functionality are as follows:

Name

Image

Description

Compile



Similar to Blueprints, Control Rigs must be compiled in order to fully save and begin executing their logic. Clicking this button will compile your rig, as well as visually provide feedback on whether or not your rig needs to be compiled.

You are required to compile whenever changes are made within the Rig Hierarchy. This can include adding, removing, reparenting, or renaming Controls, Bones or spaces. Recompiling is also required when creating variables.

The Compile button also resets your controls after you manipulate them in the viewport.

Solve Direction



The Solve Direction button switches between different Solver event chains. Use this to preview different Solve Directions. Each option is associated with a Rig Graph solve direction event node. Selecting an option will begin previewing that solve chain.



Clicking the main button will swap the mode between the current mode and the previously selected mode.

Auto Compile



Enable Auto Compile to set compiling to automatically occur when you make changes in the Rig Graph. This includes actions like creating and linking nodes. All other changes mentioned above will still require you to manually compile.

Debug Object



This drop-down menu links the Control Rig viewport to an active Control Rig in a simulating or playing session. This previews the current Control Rig animation from that session in the Control Rig viewport.

Class Settings



The Class Settings button toggles Blueprint class settings to be visible in the Details panel. The Shape Libraries property is located here, which can be used to change the control shapes available to you when rigging. Visit the Control Shapes and Control Shape Library page to learn more about this feature.



You can also access Control Rig Python commands such as Python Context and Copy Python Script.

Viewport

From the Viewport, you can:

Preview interaction with your Control Rig nodes.

Set different display modes and debug displays.

Select and manipulate controls.

Change the preview mode using the top toolbar.



The View Options menu has the following Control Rig settings:



Name

Description

Display Nulls

Displays a selectable axis of Nulls in the viewport.



Display Axes On Selection

Displays a local axis when you select any rig element.



Axes Scale

The size of the axis display when drawing axes from either the Display Nulls or Display Axes On Selection options.



Bone Radius

The size of the Bones when Bones are visible by either selecting them or by showing Bones from the Character > Bones menu.



Pin Control Space

When controlling a pin value, you can select an element from this to offset the manipulator to be relative to a different element.

Rig Hierarchy

The Rig Hierarchy panel is used to view and select your control hierarchy in an outliner-type view. This is also the primary area to create new Controls, Bones, and Nulls.



Create these elements by right-clicking in the panel and selecting New > Control, Bone, or Null. Your selection determines the location where these elements are created. If nothing is selected, then new elements will be created at the origin (0,0,0).



The context menu contains the following commands:



Name

Description

New

Creation menu for creating new Controls, Bones, or Nulls.

Delete

Deletes the current selection.

Duplicate

Duplicates the current selection.

Rename

Renames the current selection.

Mirror

Copies your currently selected elements and mirrors the copy along an axis. When clicked, a dialog window will appear where you can specify how you want the mirror action to function.



Mirror Axis is the axis to mirror against. For characters that face Y-Forward in Unreal, you can keep this at the default value of X.

Axis to Flip is the axis to rotate 180 degrees in order for rotations to be properly mirrored. For characters that face Y-Forward in Unreal, you can keep this at the default value of Z.

Search is where you specify a keyword or letter to search for to be replaced. If you are mirroring a control with the postfix "_left", then you will want to write "left" here.

Replace is where you specify a keyword or letter to replace the text used in Search. If you are mirroring a control with the postfix "_left", then you will want to write "right" here.

Test Space Switching

Opens a dialog window for previewing Space Switching behavior for your controls.



Parent is the default behavior, where the control will follow any space changes by the parent.

World will detach the control from any parent influence and attach it to the world.

Click the Add (+) button to add any other control to parent to.

Copy

Copies the current selection, including the local and global transform, which can be used in conjunction with Paste Local / Global Transform.

Paste

Pastes the current selection.

Paste Local Transform

Pastes the currently copied control's local transform.

Paste Global Transform

Pastes the currently copied control's world transform

Reset Transform

Resets the currently selected control back to its initial transform.

Reset All Transforms

Resets all controls back to their initial transform.

Set Initial Transform from Current

After moving a transform in the viewport, clicking this will set the new location as the new initial transform.

Set Initial Transform from Closest Bone

Using this command will snap your selected Control to the nearest Bone and set that location as the Initial Transform. This is useful for aligning your controls to Bones.

Set Shape Transform From Current

If you are transforming your control, performing this command will reset the control's pivot point back to its initial transform, but maintain the current visual position of the control shape. This is useful if you want to customize your control's visual position while keeping the pivot the same.

Unparent

Moves the currently selected element to the top of the hierarchy.

Import

Imports a skeleton hierarchy to the current rig.

Refresh

Refreshes the existing initial transform from the selected mesh. This only updates if the node is found.

My Blueprint

The My Blueprint panel, similar to that found in Blueprints, contains your various Control Rig Functions and Variables. Variables in Control Rig are meant to be used within your Rig Graph as a way to drive logic, rather than being exposed directly to an instance in a Level.



Execution Stack

The Execution Stack panel previews the order of operations within your graph. Use this to debug your nodes and evaluate the sequence of events.



Right-clicking on an execution node and selecting Focus on Selection will frame that current node in the Rig Graph. You can also double-click a node to focus it.

Curve Container

The Curve Container panel displays the list of Anim Curves from your Skeleton, and provides functionality to control them in the Rig Graph.



Curves can be referenced in the Rig Graph by using the Get Curve Value and Set Curve Value nodes.



Rig Graph

The Rig Graph is where you script the Control Rig's behavior.

Hierarchy nodes can be referenced into the graph by dragging and dropping them from the Rig Hierarchy panel into the graph and selecting your desired reference type.



You can also create nodes by right-clicking. Search or navigate the context menu for your desired node.



Similar to Blueprints, multiple nodes can be collapsed into groups or Functions by right clicking on your selected nodes and selecting either Collapse Nodes or Collapse to Function.



Your functions are accessible from the My Blueprint panel in the Functions category. With functions, you can better organize large graphs, repeat logic, and easily share functionality across Control Rigs.



Details

The Details panel contains information for your selected elements within the Control Rig Editor. These can include elements such as Controls, Bones, and rig graph nodes. Selecting Controls will reveal the following properties:



Name

Description

Name

The name of the selected rig element.

Display Name

The name of the Control as it will appear in Sequencer and the Anim Outliner. If not used, then the name will fallback to what is specified in Name.

Control Type

The type of Control to use. This is used to limit or change the Control's data if you intend the Control to only affect certain values, such as a Control that only rotates, translates, or provides a single property.

Animatable

Determines whether or not the Control will be animatable in Sequencer. This is useful if your rig has Controls that are visual-only.

Available Spaces

An array where you can add predefined custom spaces for your Controls, which are used for space switching.

Draw Limits

Draws a debug line if transform limits are being used on the selected Control.



Transform

Displays the different transform types for the selected rig element. Bones and Nulls will only display Initial and Current, while Controls will display Initial, Current, Offset, and Min/Max limits.

Shape

The Shape category contains properties for customizing the shape of the selected Control.

Preview Scene Settings

The Preview Scene Settings panel contains properties that control your Skeletal Mesh, animation, and viewport environment settings.



The following properties can be used to affect the Control Rig viewport:

Name

Description

Preview Controller

Use the Preview Controller to play back animations in the viewport. This can be useful when testing how your Controls behave when animation is playing on your character, or for testing Backwards Solve behavior.



Preview Mesh

The Skeletal Mesh to use for your character in the viewport. You can change this to any other meshe with a compatible skeleton.

Clothing Simulation Factory

The cloth simulation to use in the viewport.

Allow Different Skeletons

If enabled, you can select Skeletal Meshes with incompatible skeletons in the Preview Mesh or Skeletal Meshes properties.

Allow Custom AnimBP Override

When using Preview Collections, enable Animation Blueprints to override from those collections.

Additional Meshes

Specify a Preview Collection here.

Skeletal Meshes

Additional meshes to add to the viewport. This can be useful if you are using Modular Characters.

Elements Overview

Organization

Controls

Creation Context

Control and Value Types

Transform Limits

Bones

Workflow Example

Nulls

Workflow Example

Transform Types

Initial

Current

Offset Transform

The primary rig elements used when creating robust rigs in Control Rig are Controls, Bones, and Nulls. Each of these elements have wide-ranging applications and can be used together to create complete rigs.

This document provides an overview of Controls, Bones, and Nulls, and provides simple workflow examples for using them.

You have created and opened a Control Rig for a skeletal mesh.

Elements Overview

Controls, Bones, and Nulls are created by right-clicking in the Rig Hierarchy panel and selecting one of the options from the New menu.



By default, creating one of these elements will locate it at the origin (0,0,0) of the viewport. If you have an element selected in the Rig Hierarchy panel, it will instead create it at the location of, and parented to, that selected element. This makes it easy to align your elements with each other, using this selection context.



Organization

Elements can be renamed by right-clicking them in the Rig Hierarchy and selecting Rename or by pressing F2.



Elements can be re-organized by dragging them in the Rig Hierarchy.

Dragging an element onto another element parents it to that element.

Dragging an element to an empty region unparents it.

Pressing Shift+P also unparents selected elements.



Controls

Controls are the main elements used for your Control Rig interaction. They are used to drive your Bone chains, animate in Sequencer, and provide additional custom attributes. You can also customize your Controls to have different shapes and colors, property types, and transform limits.

Creation Context

When creating Controls relative to a Bone, the Control will automatically inherit the same name as that Bone and apply _ctrl as a suffix.



In addition to the normal creation method, you can also create Controls when multiple Bones are selected using a provided Python script. In the Rig Hierarchy, select multiple Bones, then right-click on them and select New > Add Controls For Selected. This will create Controls for all selected Bones, matching their names with the suffix _ctrl, and matching the hierarchy structure.



You can customize this creation method by holding Alt and clicking New > Add Controls For Selected. This will open a dialog window where you can customize the following settings:



Name

Description

Output Format

How to organize the controls once created. You can select the following options:

Hierarchy: Copies the same hierarchy as the selected Bones, with the top-most control unparented from the Bone hierarchy.

List: Unparents all created Controls so they appear at the root of the Rig Hierarchy as a flat list.

Child: Parents all created Controls underneath the associated Bone.

Suffix

The text to apply after the Control name, which is copied from the Bone name.

Prefix

The text to apply before the Control name, which is copied from the Bone name.

Control and Value Types

There are a variety of Control types that you can specify for Controls which provide alternative or more limited properties for it. This can be useful if you are wanting to create attribute-based Controls, Proxy Controls, or feedback Controls.

You can specify the type of the Control by clicking the Animation Type drop-down menu for a selected Control in the Details panel. The following Control types can be chosen:



Control Type

Description

Animation Control

The default Control type, which provides a normal visible animatable Control.



Animation Channel

A type of Control that is used to provide an animation channel or custom attribute. If Group Channels is enabled, this attribute will be accessible on the parent Control, where it can be animated together with other attributes.



Proxy Control

Proxy Controls are a type of Control which can be linked to other Controls in a Driver / Driven relationship. This is done by adding the Controls you want to drive in the Driven Controls array. Proxy Controls cannot be animated directly, however you can use them to drive other Controls in a consolidated manner using Get Driven and Set Driven nodes.



Visual Cue

In addition to the Animation Type, you can also adjust the Value Type, which sets the output data of a Control. From the Value Type dropdown menu, you can set the following types:

Name

Description

Bool

Makes the Control become a bool-type, where you can set True / False states in animation. Bool-type Controls are not visible in the Viewport.



Float

Makes the Control become a float-type, where you can animate the Control along a single position axis. If Animation Type is set to Animation Control, then you can specify which axis by selecting an axis from the Primary Axis property. The range you can move the Control when using this type is limited by default between 0 - 100. Floats can be useful if you are wanting to create a slider Control.



Integer

Makes the Control become an integer-type, where you can animate the Control along a single position axis, incrementing by one. If Animation Type is set to Animation Control, then you can specify which axis by selecting an axis from the Primary Axis property. The range you can move the Control when using this type is limited by default between 0 - 100. You can also convert this Control Type to an Enum by referencing an Enumeration in the Control Enum property.



Vector 2D

Makes the Control become a vector 2d-type, where you can animate the Control along two position axes. If Animation Type is set to Animation Control, then the axis specified in Primary Axis will not be used, with the remaining axes being the ones providing the 2D plane. The range you can move the Control on both axes when using this type are limited by default to between 0 - 100.



Position

Makes the Control become a position-type, where you can only animate the Control's location.



Scale

Makes the Control become a scale-type, where you can only animate the Control's scale.



Rotator

Makes the Control become a rotator-type, where you can only animate the Control's rotation.



Euler Transform

Makes the Control become a transform-type, where you can freely manipulate the Control on all translation, rotation, and scale axes. This is the default type.



For spatial Controls, such as Euler Transform, Rotator, Scale, and Position, there are additional transform-related features available to you in the details panel when viewing the Transform properties:



The Rotation drop-down menu is where you can select different rotation interpolation modes, such as Euler, Quaternion, or Axis and Angle.

Local /World Space buttons will swap the axis information displayed between local and world space. Shift-clicking will change all three axes.

Locks Scale, which will cause scaling to occur uniformly in each direction when changing scale.

Transform Limits

Spatial Controls can have limits placed on them so that they only can animate within a certain range. This can be useful if you are wanting to create slider or 2D-based controls and limit their movement range.

Limits are set on Controls by defining their minimum and maximum property ranges. You can locate these properties for a selected Control by clicking Min or Max under the Transform category in the Details panel.



Enable any axis channel to enable limits for that value, and define the number within the region next to it. In this example a Minimum limit of -50 and Maximum limit of 50 is set. Manipulating your Control will now keep its movement restricted to those limits.



Enable Draw Limits to visualize the limits of all Controls in the Viewport.



Bones

Separate from normal Bones that are included in your skeleton, new Bones can also be created in Control Rig. These Bones can be used in an auxiliary manner to provide extra Bones for specific rigging behavior, such as making ending effectors in an IK-chain, or making "dummy" Bones in order to control "real" Bones in a consolidated manner.

Bones created in the Control Rig editor have their hierarchy icons displayed hollow to differentiate them from normal Skeletal Mesh Bones.

After creating a new Bone, you can move it in the viewport by entering into the Setup Event mode, which enables the ability to edit the Initial Pose of an element in the viewport. In the toolbar, click the Solve Direction drop-down menu and select Setup Event.



Once Setup Event is enabled, you can move your Bone in the viewport.



By default, only selected Bones are displayed in the viewport. You can change this view mode by clicking Character > Bones in the viewport toolbar, then select your desired Bone drawing setting.



Workflow Example

In this example, a Bone created in Control Rig is being used as an end effector for a finger IK chain.



Nulls

Nulls are container elements used to collect, group, and transform other rig elements together in arbitrary ways. In a typical humanoid control rig setup, they can be used as a way to group your symmetrical controls, such as legs and arms, in order to mirror these controls. In this way, Nulls are a similar concept to Groups from Autodesk Maya, and are meant to be used for rigging organization.



By default, Nulls are not visible in the viewport. To view nulls, you can enable Display Nulls from the Viewport toolbar.



Similar to Bones, Nulls can be edited by enabling Setup Event from the Solve Direction dropdown menu. Once Setup Event is enabled, you can move your Null in the viewport.



Enabling Setup Event will also enable visibility on all Nulls in the Viewport.

Workflow Example

In this example, Nulls are being used to group several controls together along symmetrical and limb lines. This grouping can now facilitate easier organization, mirroring, and other rigging operations.



Transform Types

The position, rotation, and scale of rig elements are determined from multiple transform sources, which are named Initial, Current, and Offset. These transform types each perform transformations on rig elements at different phases of the Control Rig execution. You can view these different types from any selected rig element's details.



When a different Control type is specified for a Control, you can only specify Initial and Current Values.



Holding Shift and clicking the different types will display them alongside each other in the Details panel.



Initial

Initial is the starting value of the element before control rig logic from the rig graph executes. It also specifies the default value of a rig element within its range of operation, and will affect the default value of Current.

You can edit the Initial value by either editing it from the Details panel, or by enabling Setup Event and manipulating the element in the Viewport, if it has a Transform.



Current

Current is the value of the element when operating in the Forwards Solve mode. It is meant to be the real-time actual transform of your Control, and manipulating Controls in the viewport will edit the Current pose. Within the Control rig editor, the Current pose is temporary and can be reset by recompiling or reopening the asset.



When animating a Control Rig within Sequencer, you are animating the Current value.

Offset Transform

Offset only appears for Controls with Control Type set to Euler Transform. It is used to spatially offset controls without changing the Initial or Current values, and provides the ability to change a Control's "zero position". In other rigging tools such as Autodesk Maya, Offset is analogous to Freeze Transformations, or Transform Offset Parent Matrix.



If you are outputting Transform values from a Control with an offset specified, the resulting transform will combine both Offset and Current for its final calculated transform. You can change this by setting the Space property to Local Space, which will then only output Current.



Forwards Solve

Previewing Forwards Solve

Backwards Solve

Previewing Backwards Solve

Bake Animation to Control Rig

Construction Event

Spawn Rig Elements

Previewing Construction Event

Backwards and Forwards

Control Rigs are evaluated in several ways, called solve directions, which are created in the Control Rig Rig Graph. By using these tools to split the rig logic into multiple solve directions, or solvers, you can expand on the incoming data for a rig, which enables workflows such as rig sharing, baking animation back to your controls, and debugging this behavior.

This page provides an overview of the different solve directions available in Control Rig, how to use them, and the workflows these features enable.

You have an understanding of the Control Rig Editor.

You have an understanding of Sequencer, and know how to add Control Rig characters to Sequencer.

Forwards Solve



Forwards Solve is the solve direction used for driving your skeleton with controls, variables, and other rig elements. It is the primary solve direction for Control Rig, as it is used when animating your Control Rig within Sequencer and Animation Blueprints.

By default, all Control Rig assets will include the Forwards Solve node in the Rig Graph. From this node, the logic you will be creating will be based on affecting the skeleton's bones through controls, variables, and other rig elements. In this way, your controls are behaving in a "forward" manner, where controls affect bones.



Previewing Forwards Solve

Forwards Solve is the default preview mode within the Viewport. This can be verified by ensuring the solve direction Toolbar button is set to Forwards Solve. Similar to AnimBP's, Forwards Solve will continuously execute regardless of your editor state within a level.



Depending on which solve direction is active, then this will affect which execution lines are highlighted in the rig graph. For example, if Forwards Solve is active, then the execution lines from Backwards Solve will appear more transparent.



Backwards Solve



Backwards Solve is the solve direction used for driving your controls from your skeleton. It is the inverse of Forwards Solve, and is used to bake animation from animation sequences onto a Control Rig in Sequencer.

In order to create Backwards Solve logic in your Rig Graph, you must create a Backwards Solve node. Right-click in the Control Rig Graph and select Events > Backwards Solve.



From this node, the logic you will be creating will be based on affecting your controls from the bones in the skeleton. In this way, your controls are behaving in a "backward" manner, where bones affect controls.



Previewing Backwards Solve

You can preview Backwards Solve behavior in the the Viewport by opening the solve direction dropdown menu in the Toolbar, then clicking Backwards Solve. This will cause the viewport to execute Backwards Solve logic from the Rig Graph, rather than Forwards Solve.



To better preview this inverse Control Rig behavior, you can navigate to the Preview Scene Settings panel in Control Rig and specify an animation to play on your character. Set Preview Controller to Use Specified Animation, then select an animation from the Animation property. You should now see your controls match the playing animation.



When previewing Backwards Solve, the viewport will be outlined in a yellow border. This color and other colors can be changed in the Control Rig Editor Preferences.



Bake Animation to Control Rig

The main use of Backwards Solve is to bake animation sequences to your Control Rig, in order to make further changes to an animation in Unreal Engine.

To do this, assuming you have an animated character in Sequencer, right-click on the character track, select Bake To Control Rig, then select your Control Rig Asset you want to bake to.



If your Control Rig asset does not use the Backwards Solve node in the Rig Graph, then the Control Rig will not be selectable in the Bake To Control Rig menu.

A dialog window will appear where you can specify options related to the bake operation:



Name

Description

Export Transforms

Bakes transform data to controls.

Export Curves

Bakes AnimCurve data to controls. This includes AnimCurves when evaluating the Backwards Solve logic.

Record in World Space

Bakes in absolute world space coordinates.

Evaluate All Skeletal Mesh Components

Evaluates all skeletal mesh components when baking. Typically you may want to enable this if you are using a Blueprint with other Skeletal Mesh Components.

Warm Up Frames

The number of frames to evaluate before the baking process occurs. This is useful if there are post process Animation Blueprint effects that require additional time to settle before evaluation.

Delay Before Start

The number of Display Rate frames to delay before the baking process occurs. This is useful if there are post process Animation Blueprint effects you need to run repeatedly before evaluation.

Reduce Keys

Enable this to run a Simplify process after the baking process occurs, which removes redundant keyframes based on a tolerance amount.

Tolerance

The higher the Tolerance value, the more the filtered curve is allowed to deviate from the original, which causes more keyframes to be removed if Reduce Keys is enabled.

Click Create to bake the animation sequence to Control Rig. Once completed, you should now see a Control Rig track with keyframes along the timeline. These keyframes should correspond to the overall animation that you have baked from.



You can also import an animation sequence directly as Control Rig keyframes by right-clicking on the Control Rig Section, then selecting an animation from Import Anim Sequence Into This Sequence. The animation will import relative to the Sequencer Playhead.



Construction Event



Similar to Blueprints, you can also create a Construction Event, which is used to execute preparation logic, such as initializing variables and setting initial positions on controls. It is executed once, at the post-initialization stage of the Control Rig.

In order to create Construction Event logic in your Rig Graph, you must create a Construction Event node. Right-click in the Control Rig Graph and select Events > Construction Event.



From this node, the logic you will be creating will be based on affecting the initial state of your rig elements. This can include things like defining the initial offset of your controls to their respective bones, which enables Rig Sharing. Additionally, you can define initial values for variables, or change the initial positions of bones.



Spawn Rig Elements

One of the other main purposes of the Construction Event is to spawn rig elements during this initialization phase. This makes it possible to create procedural Control Rigs by spawning new Controls, Bones, and Nulls, and initialize them using Rig Graph logic.

To create a spawn node, right-click in the Rig Graph and click one of the Spawn nodes from the Dynamic Hierarchy category. The following nodes can be added:



Name

Description

Spawn Bone

Creates a new Bone in the hierarchy.

Spawn Null

Creates a new Null in the hierarchy.

Spawn Animation Channel

Creates a new Animation Channel in the hierarchy. Animation Channels are a type of Control that is used to provide an animation channel or custom attribute.

Spawn Control

Creates a new Control in the hierarchy.

When spawning Animation Channels or Controls, you will need to specify their property type. Do this by right-clicking the Initial Value pin and selecting a type from the Wildcard dropdown menu.



When connecting the Spawn node to the Construction Event, you should see the new element appear in the Hierarchy Panel, as well as in the Viewport as if it were created normally. All spawned element names are colored yellow to distinguish them from non-spawned elements.



Spawn nodes currently only function with the Construction Event.

You can also right-click any spawned element and click Select Spawner Node, which frames the node used to spawn this element. This makes it easy to locate spawn nodes in a complex graph.



Unlike non-spawned elements, initial values and settings for spawned elements are read-only, and must be defined on the node, instead of in the Details panel. You can do this by expanding the Initial Value and Settings pins and editing the properties. You can also connect properties and variables to these to drive them from other logic sources.



There is a limit to the number of spawned elements you can create in a Control Rig, which can be reached if you are creating large rigs or using For Loop logic. By default this limit is set to 128, and can be changed by enabling Class Settings and changing the Procedural Element Limit property.



Previewing Construction Event

You can preview Construction Event behavior in the Viewport by selecting the Solve Direction dropdown menu in the Toolbar, then clicking Construction Event. This causes the viewport to execute Construction Event logic from the Rig Graph, rather than Forwards Solve. Entering into this mode is useful for debugging your construction logic.



When Construction Event is enabled, you can also edit the initial locations of bones and nulls from the viewport.



When previewing Construction Event, the viewport will be outlined in a red border.

Backwards and Forwards



The Backwards and Forwards preview mode executes the Backwards Solve, then the Forwards Solve rig logic. This results in behavior that mimics the Bake Animation to Control Rig process within the viewport. Typically you will enable this mode if you want to debug the baking process to ensure your bones and controls are operating correctly.

You can preview Backwards and Forwards behavior in the Viewport by selecting the Solve Direction dropdown menu in the Toolbar, then clicking Backwards and Forwards. This will cause the viewport to execute both the Backwards and Forwards Solve logic sequentially from the Rig Graph.



When previewing Backwards and Forwards, the viewport will be outlined in a blue border.

Creation and Setup

Rig Graph Setup

Effector Setup

Setup Result

Bone Settings

Rotation and Position Stiffness

Preferred Angles

Limits

Excluding Bones

Node Reference

Use Control Rig's Full Body Inverse Kinematic (FBIK) feature to construct rigs in Control Rig with a high degree of control and flexibility. The overall solver method is built on a Position Based IK framework, which enables faster rig performance, per-bone settings, preferred angles, squash and stretch, and more. FBIK is designed to act as a procedural adjustment tool within Control Rig, such as for ground alignment, or arm reaching behavior.

This document provides an overview of how to create the FBIK node, and its various features.

FBIK is a node within the Control Rig Graph, therefore you should have an understanding of the Control Rig Editor.

You must enable the FullBodyIK plugin. To do this, navigate in the Unreal Editor menu bar to Edit > Plugins and locate FullBodyIK. Ensure the plugin is enabled and restart the editor.



You must have created a Control Rig asset for a character and know how to create controls. See the Control Rig Quick Start page for information on how to do this.

Creation and Setup

FBIK is achieved within Control Rig by creating the FBIK node, then assigning bones and effectors to the appropriate pins.

To start, right-click in the Control Rig graph, and in the context menu select Hierarchy > Full Body IK. This will create the Full Body IK node. Connect the node to the Forwards Solve node.



Rig Graph Setup

Next, set the Root bone property on the Full Body IK node. In typical full-body setups, this will likely be the hips or pelvis bone.



Create and add your chosen controls for the FBIK system. Typically these controls correspond to the limbs you want to affect, and are based on the primary ending bone of the chain. In this example, controls are created for the head, hands, and feet.



Effector Setup

You will need to add an effector pin for each control added to the graph. To do this, click the Add (+) button next to the Effectors property. Effectors will need to be created for each control.



Expanding one of the Effectors entries will reveal its properties. Within each Effector you will set the corresponding Bone value for the control, then connect the Transform pins from the corresponding Get Transform node.



Connect each effector to their corresponding Get Transform nodes in the same way until all effectors and controls are connected.



Setup Result

You should now have a basic FBIK setup for your character. You can manipulate the controls within the Control Rig viewport to see the results.



Bone Settings

Depending on your setup, the base FBIK behavior may not behave as intended. This might be because certain bone settings are not enabled. Bone Settings are properties within the Full Body IK node, and are used to control the behavior of each bone that FBIK is affecting.

Bone Settings are added to the Full Body IK node by clicking the Add (+) button next to Bone Settings, then specifying the bone you wish to affect in the Bone property. Each bone setting only affects a single bone, so you may want to add multiple bone settings depending the specific problem you are experiencing with your rig.



In a humanoid example, the following issues are visible:

The hips are rotating and translating too aggressively.



The legs are not bending enough, having a stiff appearance.



The ankle is rotating too far upward, causing an unnatural pose.



Bone Settings can be used to resolve issues like these, in order to support your preferred IK setup.

Rotation and Position Stiffness

Rotation and Position Stiffness properties are used to control how much a bone in the IK Chain can be affected by controls and effectors. Use these properties to change the degree to which the pelvis bone will be affected by the movement of the controls. A value of 0 results in completely free movement, whereas a value of 1 completely locks the bone from movement.



In the humanoid example, the pelvis bone is specified as the bone setting, and a value of 0.8 is set for both Rotation and Position Stiffness. In this case, some movement is still preferable.



Preferred Angles

Preferred Angles can be used to prioritize joints rotating along a specific axis to reach the effector. In the humanoid example, they can be used to resolve stiffness issues in the legs and knees.

Near the bottom of the Bone Settings are properties for Preferred Angles. You must also ensure Use Preferred Angles is enabled in order to use these Preferred Angles.



The Preferred Angle properties you specify depend on the type of character, and its joint structure. For this example, the mannequin's knee should bend along the Z axis in a positive direction, therefore a value of 45 should be set on the Z property.



Limits

Limits can be used to limit the range of, or completely lock, the rotation of bone axes along the IK chain. These settings are located between the Stiffness and Preferred Angles properties.



Each axis has settings that allow for the following limits:

Free, which allows for the bone to move freely.

Limited, which only allows movement within a specified range. If this is chosen, then the Min/Max properties are used to define the range of movement.

Locked, which disables movement along that axis.

In the humanoid example, these limits can be used to correct the unnatural ankle rotation issue. A value of -70 is set for Min Z and 70 for Max Z, and the Z axis is set to Limited.



Excluding Bones

Depending on the needs of your rig, there may be cases where you want to exclude bones from the FBIK solve. This can be useful when correcting unnatural-looking poses, or when simplifying FBIK behavior.



Excluding bones is recommended rather than exclusively using Bone Settings to set bones to be fully stiff or locked.

To exclude a bone, click the Add (+) button next to Excluded Bones, and select a bone from the dropdown menu to exclude.



Node Reference

The following is a list of all the pins and settings on the Full Body IK node.

Name

Description

Root

The root bone for the FBIK chain.



Effectors



Bone

An endpoint bone for the IK chain, which corresponds to a control.

Transform

The transform to use to control the end-point bone. Typically this is provided by a Get Transform node linked to a control that shares the same transform information as the end-point bone.

Position Alpha

This property weighs the ability for the effector or bone to reach the target's position. When set to 1, the effector does its best to reach the target transform. When set to 0, the effector remains at the input pose.

Rotation Alpha

This property weighs the ability for the effector or bone to reach the target's rotation. When set to 1, the effector does its best to reach the target transform. When set to 0, the effector remains at the input pose.

Strength Alpha

This property affects the strength of this effector's influence on the IK chain. When set to 0, the effector will not pull the chain towards it and other effectors will take priority.

Pull Chain Alpha

When enabled by setting the value greater than 0.0, the FBIK solver will partition the skeleton into "chains" which extend from the effector to the nearest skeleton hierarchy divergence. Using this can improve results for sparse bone chains, but cause undesirable results for more complex constrained bone chains.

Pin Rotation

Blends the effector bone rotation between the rotation of the effector transform (1.0), and the rotation of the input bone (0.0).



Bone Settings



Bone

The specified bone these settings are applied to. This can be any bone in the hierarchy between the Effectors and the Root.

Rotation/Position Stiffness

The amount of stiffness to apply to a bone's rotation or translation property. A value of 0 allows for free movement, whereas a value of 1 will completely lock down the bone.

XYZ Limit Setting

The type of allowed movement on the selected bone's axis.

Free allows for the bone to move freely.

Limited allows movement within a specified range. If this is chosen, then the Min/Max properties are used to define the range of movement.

Locked disables movement along that axis.

Min/Max XYZ

If Limited is set as a Limit Setting, the Min/Max XYZ properties are used to specify the range of movement allowed.

Use Preferred Angles

Enables the use of Preferred Angles.

Preferred Angles

Specifies how much the Bone should rotate, in each axis, as the chain is compressed.



Settings



Iterations

Increase this value until the effectors converge on their desired goal locations. Increasing this value also increases the CPU cost of the FBIK chain. The addition of Stiffness, a high Mass Multiplier and Rotation Limits can all affect the convergence rate and may require more adjustments to this value.

Mass Multiplier

This is a global value that affects how much the bones resist rotations and translations. Typical values range between 0.0 and 5.0, with 0.0 being completely loose and 5.0 being very stiff. Higher Mass Multiplier values require more iterations to achieve convergence.

Allow Stretch

Enabling this will cause bones along the IK chain to translate to reach their effector. Position Stiffness values affect this result, where higher stiffness will cause less stretching.

Root Behavior

Sets the behavior of the solver root. You can select from the following options:

Pre Pull, which translates the root and all children by the average motion of the stretched effectors to help achieve better convergence when reaching far distances.

Pin to Input, which locks the translation and rotation of the root bone to the input pose and overrides any bone settings applied to the root. This can be useful for low-distance, partial-body setups.

Free, which makes the root bone behave like other bones in the chain, allowing it move freely or according to any bone settings applied to it.

Start Solve from Input Pose

When enabled, the solver is reset each tick to start from the current input pose. If disabled, incoming animated poses are ignored and the solver starts from the results of the previous solve.



Debug



Draw Scale

Multiplier that controls size of debug lines.

Draw Debug

Enable this to show all affected bones along the IK chain for this FBIK node.

Create Spline

Apply Spline to Bones

Spline Properties

Spline Nodes

Splines can be built and used in Control Rig in order to create dynamic and procedural motion regardless of skeletal hierarchy. With splines, you can create more complex poses with fewer necessary controls on limbs such as tentacles, spines, and snakes.

This document provides an overview of how to create and use splines in your rig.

You have created a Control Rig Asset for a Skeletal Mesh that has a suitable joint structure for splines, such as a tail. See the Control Rig Quick Start page for information on how to do this.

You are familiar with how to create and position Controls.

Create Spline

Spline creation in Control Rig is done by specifying arbitrary translation points, which are used to construct the spline. In typical setups, these points are based on the transform information from Controls.

To start, create a Spline From Points node by right-clicking in the rig graph and selecting Spline From Points.



Next, create rig elements which are used to define the points in the spline. In this example, four controls are created and evenly distributed along the length of the tentacle. The number of controls does not need to correspond to the number of bones in the chain.



Next, reference your root rig element into the rig graph, and click the Add (+) button on the Spline From Points node to add the first spline point in the array. Expand the Transform pin on your element reference and connect the Translation pin to the input on the Points pin.



Continue to add additional spline points for all the rig elements you want to use to form the spline. You must ensure that the order in which you connect them to the Spline From Points node corresponds to the direction of the spline.



Splines in Control Rig require a minimum of four points in order to create the spline successfully.

You can now preview your spline by using the Draw Spline node, which provides a visual display for the spline. Create this node by right-clicking in the graph and selecting Draw Spline, then connect the Spline pin from Spline From Points, and the Execute event from Forwards Solve. Manipulating your controls in the viewport will preview the spline behavior.



Apply Spline to Bones

Once the spline has been created, you can apply it to your joint chain.

First, create a Fit Chain on Spline Curve node by right-clicking in the graph and selecting Fit Chain on Spline Curve.



Next, multi-select the bones you want to include in the spline from the Rig Hierarchy panel, drag them into the Rig Graph, and select Create Item Array. For this operation, selection order is important to ensure the resulting bone array matches the same order as the spline points.



Lastly, connect the Rig Element array to the Items pin, the Spline pin from Spline From Points, and ensure the Execute event is connected to your Control Rig logic chain.



Your spline should now affect the bone chain.



Spline Properties

The following properties are available on the Spline From Points node.



Name

Description

Points

The position information that will be used to construct the spline. Can be either an array or built using individual translation pins by clicking the Add (+) button.

Spline Mode

The type of spline to use. You can choose from either:

Hermite, which will ensure the Spline passes through all defined Points.



BSpline, which is a smoother spline and will only pass through the start and end points. This is based on the TinySpline library.



Samples Per Segment

This property controls the approximation accuracy of the spline. Higher numbers will cause the spline to be more accurate and smooth. Lower numbers will cause the spline to appear more jagged and incorrect. Performance costs increase with the sample count, so it is a good idea to ensure this number is not set too high.

Compression

The amount the spline should compress when reducing its length.

Stretch

The amount the spline should stretch when increasing its length.

Spline (Output)

The resulting spline from this node.

The following properties are available on the Fit Chain on Spline Curve node.



Name

Description

Items

An array of rig elements to align to the provided Spline.

Spline

The Spline curve to align to.

Alignment

Whether or not to stretch the aligned elements to the full spline length.

Stretched will cause the full amount of stretching to occur.



Front will disable stretching.



Minimum

The Minimum U value to use on the curve. U is the normalized (0 - 1) percentage between all combined control points.

Maximum

The Maximum U value to use on the curve. U is the normalized (0 - 1) percentage between all combined control points.

Sampling Precision

This property controls the approximation accuracy of the spline. Higher numbers will cause the spline to be more accurate and smooth. Lower numbers will cause the spline to appear more jagged and incorrect. This overwrites the Samples Per Segment property from Spline From Points. Performance costs increase with the sample count, so it is a good idea to ensure this number is not set too high.

Primary Axis

The major axis being aligned in the chain. In simple setups this property can be ignored, but typically you will want to set this to be the direction your item chain is progressing in.



Secondary Axis

The minor or "up" axis being aligned in the chain. In simple setups this property can be ignored, but typically you will want to set this to be in the direction of a pole vector if it is being used.



Pole Vector Position

The position of an optional pole vector control. This only has an effect if the Secondary Axis is set.

Rotations

An array of rotations to apply additively to the overall spline.

Rotation Ease Type

The easing type to use between each rotation element.

Weight

The factor to apply the elements to the curve.

Propagate to Children

Whether or not the changes in the rig elements should apply recursively to all children.

Spline Nodes

The following Spline nodes are available for use in your Control Rig Graph:

Name

Image

Description

Closest Parameter From Spline



Retrieves the closest U value from a given spline and position.

Draw Spline



Displays the spline curve in the viewport for preview purposes. Includes properties for controlling the Color, Thickness, and sample Detail.

Fit Chain on Spline Curve



Fits a given spline along an array of items. This node typically is used when performing backwards solves that include splines.

Fit Spline Curve on Chain



Applies a chain of rig elements to a spline.

Get Length Of Spline



Gets the length of a spline.

Parameter At Length Percentage



Returns the U value of a spline given a length percentage.

Position From Spline



Returns the position along a spline given the U value.

Set Spline Points



Sets the currently existing points of a spline to new values, then outputs the resulting new spline.

Spline From Points



Builds a spline from an array of translation points.

Tangent From Spline



Returns the tangent angle of a point along the spline defined by U.

Transform From Spline



Returns a transform from a given Spline and U value based on the given Up and Roll.

Quickstart

Storing Poses

Applying Poses

Pose Cache Nodes

Workflow Examples

The Pose Caching feature in Control Rig is used to save and apply animation poses at different times in the control rig graph. Any Rig Element can be cached into a pose and different properties can be accessed within the rig graph, such as curve values or transforms.

This document provides an overview of the Pose Caching feature, and how to store and apply poses.

You have created a Control Rig Asset for a character. See the Control Rig Quick Start page for information on how to do this.

Quickstart

The following is a quick guide showing how to store and retrieve a pose.

Storing Poses

Poses are stored as variables within Control Rig's My Blueprint panel. To create a new pose variable, click the Add (+) button on the Variables category and set the variable type to Rig Pose.



Next, reference the variable within the Rig Graph as a Set operation by dragging the variable into the graph and selecting Set.



Then, create a Get Pose Cache node by right-clicking in the graph and selecting Get Pose Cache. Connect the Pose and Value pins.



Lastly, connect the Set node to an event. In this example, you can connect it to the Setup Event, which will store the character's initial A-Pose.



Applying Poses

Poses are applied by using the Apply Pose Cache node, which reads from your Rig Pose variable.

To start, reference the Rig Pose variable in the graph as a Get operation by dragging the variable into the graph and selecting Get.



Then, create an Apply Pose Cache node by right-clicking in the graph and selecting Apply Pose Cache. Connect the Pose and Value pins. Also connect it to an event so you can preview its evaluation, like the Forwards Solve event.



Since you are applying the entire pose, you can preview the pose effect by editing the Weight value. For this example, you can also use a Preview Controller from the Preview Scene Settings in order to better see the pose application.



Pose Cache Nodes

The following pose cache nodes are available for use in your Control Rig Graph:

Name

Image

Description

Apply Pose Cache



Applies a saved pose. Includes properties for setting rig elements, the transform space, items to set, and weight.

For Each Pose Cache Element



This node executes iteratively across all items from a given pose.

Get Pose Cache



Saves a pose based on the input of Items to Get and rig element types. If no items are specified, then all items will be used.

Get Pose Cache Curve



Gets a single Animation Curve from a saved pose.

Get Pose Cache Delta



Compares two poses and outputs a comparison check boolean.

Get Pose Cache Items



Returns rig elements in an item array.

Get Pose Cache Transform



Gets the transform or Animation Curve value from a single rig element in a pose.

Get Pose Cache Transform Array



Gets the transforms of all items in a pose and returns them as a transform array.

Is Pose Cache Empty



Checks if a pose is empty or not.

Draw Pose Cache



Draws axis debug information on the saved pose in the viewport. It will only draw the elements saved in a pose.



Most nodes related to pose caching contain the following common properties:



Name

Description

Element Type

The Rig Elements to filter for when saving poses. You can choose from the following elements:

Bones

Nulls

Controls

Curves

All

Space

The transform space that the pose information should be stored and applied in. Can either be Local or Global space.

Items to Set

An array of rig elements to include when saving the pose. If nothing is set here, then all elements will be included according to the Element Type specified.

Workflow Examples

By using array building nodes, like Get Children, you can get just a subsection of rig elements to save into a pose. This is useful if you want to only save and apply the pose to certain elements.



Execution nodes like Branch can be used to save poses at specific times or states.



Control Shapes

Change Shape

Control Shape Library

Library Properties

Adding New Shapes

When creating controls for your Control Rigs, you may need to differentiate them visually from each other, or use a better-suited shape for a control. Using the Control Shape properties, you can affect a control's transform, color, and shape. You can also create and edit Control Shape Libraries to add or change the control shapes available to you.

This document provides an overview of these tools and features.

You have an understanding of the Control Rig Editor.

Controls are added to your Control Rig.

Control Shapes

To view a control's properties, select it in the Control Rig Editor and locate the Control Shape properties in the Details panel.



Change Shape

To change your control's shape, select one of the options from the Shape drop-down menu.



You can also change the color of a shape by clicking the Color property, which opens the Color Picker. Select a color and click OK to change the color of the control shape.



Control Shape Library

If you want to add to or change the list of shapes available, you can do so using the Control Shape Library. Each Control Rig asset contains a reference to the library, and you can view it by clicking Class Settings in the Control Rig Editor, then locating the Gizmo Library property in the Details tab.



You can choose to use the existing library, or assign a different ControlRigGizmoLibrary to the control rig class.

You can open the library by either double-clicking the asset from the Details tab, or by navigating manually to it in the Content Browser. It is located in the Engine > Plugins > Control Rig Content > Controls folder. Because it is located within the Engine > Plugins folder, you must enable Show Engine Content and Show Plugin Content from the Content Browser Settings.



Library Properties

Once opened, the library is populated with the following properties:



Name

Description

Gizmo Name

The name of the initial Control Shape when adding a new control.

Static Mesh

The mesh to use for the initial Control Shape when adding a new control.

Transform

The location, rotation, and scale to use for the initial Control Shape when adding a new control.

Default Material

The Material to use for all controls.

Material Color Parameter

The Vector 3 Material Parameter from the Default Material to affect when you change the Color property on the Control Shape.

Gizmos

The array that populates the Shape drop-down menu of the control. Here you can specify each shape's Name, Static Mesh, and Transform. New shapes can be added using the Add Element button. Shapes can be removed by clicking the drop-down button and selecting Delete.

Adding New Shapes

Control Shapes are represented using Static Meshes, which you can view in the same folder as the Control Rig Library asset.



You can import your own .fbx static meshes to expand your library with custom shapes. To do this, assuming you have a .fbx model file already exported, import it into Unreal Engine by clicking Import in the Content Browser, selecting your .fbx file, and clicking Import.



When importing new meshes for use as a control shape, it is not necessary to import any textures or create materials for them. Therefore, ensure that Import Textures is Disabled and Material Import Method is set to Do Not Create Material in the FBX Import Options menu.



After your static mesh is imported, add a new shape entry into the array by clicking the Add Element button on the Gizmos property. Expand the array list and navigate to the newly created entry at the bottom, where you can fill in the Gizmo Name, Static Mesh, and Transform properties.



Now when you return to the Control Rig, your new control should be selectable from the Shape property.



Component Setup

Mapping Setup

Overview

Details

Events

Mapping

Manual Details Mapping

Dynamic Graph Mapping

Control Rig can be called in Blueprints using the Control Rig Component. Using this component, you can drive Control Rigs with gameplay logic in Blueprints, reinitialize Control Rigs to fit differently proportioned characters, and attach non-skeletal mesh objects to the Control Rig hierarchy.

This document provides an overview of the Control Rig Component, how to add it to your Blueprint, and the features it enables.

You have created a Control Rig asset for a character and know how to create controls. See the Control Rig Quick Start page for information on how to do this.

You have created an Actor Blueprint that contains a skeletal mesh component, and have an understanding of Blueprints Visual Scripting.

Component Setup

The Control Rig Component is created by clicking the Add (+) button in the Blueprint Components panel and selecting Control Rig in the Animation category.



Next, select the Control Rig Component and assign your default Control Rig Class in the Details panel. Click the dropdown menu next to Control Rig Class and assign your class.



After assigning the Control Rig Class, bones from the Control Rig will be visible in the viewport. You can hide these by disabling Draw Bones in the Control Rig Component Details panel.



Mapping Setup

Lastly, you will need to map the Control Rig to the Skeletal Mesh, which must be done on the Pre Initialize Event from the Control Rig Component. This is done to form the connection between the Skeletal Mesh Component and the Control Rig Component.

With the Control Rig Component selected, click the Add (+) button next to On Pre Initialize in the Details panel. This will create the corresponding event in the Event Graph.



Next, drag from the Component pin and select Add Mapped Skeletal Mesh from the context menu. Add a reference to your Skeletal Mesh Component, and connect it to the Skeletal Mesh Component pin.



Overview

Once you have completed the Component Setup, you can start using the Control Rig Component in your blueprints. With it, you can use basic functions, such as getting or setting Rig Elements, editing details, and creating new mapping connections.



Details

The following is the list of relevant details of the Control Rig Component:

Name

Description

Control Rig Class

The Control Rig Class to instantiate. A Control Rig asset must be specified here.

Mapped Elements

This array is used to manually define default mappings for the Control Rig

Reset Transform Before Tick

Enabling this will cause Control Rig transforms to update before each tick.

Reset Initials Before Setup

Enabling this will cause the initial transforms on Bones, Nulls, and Controls to reset prior to the Setup Event.

Update Rig on Tick

Enabling this ensures the rig will update when the component ticks.

Update in Editor

Allows for Control Rig behavior to be visible in the viewport without needing to play or simulate.

Enable Lazy Evaluation

Enabling this will make the Control Rig only evaluate if any of the mapped inputs have changed.

Position Threshold

The position or translation threshold to use when Lazy Evaluation is enabled.

Rotation Threshold

The rotation threshold in degrees to use when Lazy Evaluation is enabled.

Scale Threshold

The scale threshold to use when Lazy Evaluation is enabled.

Draw Bones

Enables drawing bones imported from the Control Rig Class.



Events

Control Rig can call the following events from the Control Rig Component. These events can be added to the Event Graph by either selecting the Control Rig Component and navigating to the Events category in the Details panel, or by right-clicking in the Event Graph and selecting Add Event for Control Rig > Control Rig.



Name

Image

Description

On Pre Initialize



This event gets called before the Component's Control Rig is initialized. It can be used for setting transforms or additional variables in Control Rig before the Control Rig Component is initialized. In typical Control Rig setups, this event fires once, similar to Event Begin Play.

On Post Initialize



This event gets called after the Component's Control Rig is initialized. It can be used to set transforms or additional variables in Control Rig after the Control Rig Component is initialized. In typical Control Rig setups, this event fires once, similar to Event Begin Play.

On Pre Setup



This event gets called before the Setup Event of the Component's Control Rig. It can be used for setting transforms or additional variables in Control Rig before Control Rig's Setup Event. In typical Control Rig setups, this event fires once, similar to Event Begin Play.

On Post Setup



This event gets called after the Setup Event of the Component's Control Rig. It can be used for setting transforms or additional variables in Control Rig after Control Rig Setup Event. In typical Control Rig setups, this event fires once, similar to Event Begin Play.

On Pre Forwards Solve



This event gets called before the Forward Solve of the Component's Control Rig. It can be used for setting transforms or additional variables in Control Rig before its Forwards Solve. In typical Control Rig setups, this event continuously fires, similar to Event Tick.

On Post Forwards Solve



This event gets called after the Forward Solve of the Component's Control Rig. It can be used for setting transforms or additional variables in Control Rig after its Forwards Solve. In typical Control Rig setups, this event continuously fires, similar to Event Tick.

Mapping

During the Setup phase, you are required to map the entire Skeletal Mesh Component to the Control Rig Component. However, you can also map specific elements within your Control Rig to other Components. Mapping is bi-directional, meaning that Control Rig elements can either affect Components, or be affected by them. In this way, mapping is somewhat similar to attaching.

By default, mapping is generally achieved by matching the bone names from the Control Rig Class to the Skeletal Mesh Component. In this way, you can imagine that when both components are in use, that there are two different skeletons operating within your Blueprint. Mapping allows for both of these skeletons — and other components — to affect one another.

Mapping elements can be done in the following ways:

Manual Details Mapping

In the Details panel, under the Animation section, the Control Rig Component has a Mapped Elements array. By clicking the Add (+) button, you can manually add information to map and connect elements to the Control Rig.



For example, if you want to map a Camera Component in your blueprint so that a Control affects its position, then input the following properties:

Set Component Name to Camera, so it matches the Camera Component.

Set Element Type to Control, as that is the Control Rig element you are mapping to.

Set Element Name to Camera_ctrl, which is the name of the Control Rig Element you are mapping to.

Set Direction to Output, in order to define the direction of the mapping. In this case, Output is causing the Control element to dictate the transform of the Camera. If Input was specified, then the Camera Component would dictate the Control element instead.



The following properties can be used to create your mapping settings.

Name

Description

Component Reference

The Blueprint Component to define by name. If the Control Rig Component is in an Actor-based Blueprint, it defaults to Self as the Referenced Actor if no name is specified.

Transform Index

An optional index value for Components with multiple transforms.

Transform Name

An optional name value for Components with multiple individualized transform names, such as sockets in skeletal meshes.

Element Type

The Rig Element type in Control Rig that the Component is an input or output of. You can choose from Bones, Controls, Nulls, Curves, Rigid Bodies, and References.

Element Name

The Rig Element name in Control Rig that the Component is an input or output of.

Direction

Determines the direction of control between the mapped Blueprint Component and Control Rig Element.

Output will cause the Control Rig Element to affect a Blueprint Component.

Input will cause a Blueprint Component to affect the Control Rig Element.

Offset

A transform offset to apply to the mapping.

Weight

The factor of the mapping.

Space

The transform space that the mapping should be defined on.

Dynamic Graph Mapping

You can also dynamically add, or change mappings in the Event Graph. This is done using several different Functions and Structs, which achieve different levels of mapping.

This node takes a Skeletal Mesh Component and maps the bones of the Skeletal Mesh to the Preview Mesh in the Control Rig used in the Control Rig Component. This is a Control Rig to Skeletal Mesh mapping link. Typically this node is used when performing initialization of the Control Rig in Blueprints.



This node maps either an array of Bones or Curves between a Skeletal Mesh Component and Control Rig Component. Additionally, you can specify Source and Target names if the Control Rig Skeleton and Skeletal Mesh Skeleton contain different bone or curve names from one another. This provides a similar workflow to "Find and Replace" names, however it operates only for individual bones or curves.



Only the bones or curves from either array will be mapped. If you want to map the entire skeleton as well, then you can follow this node with Add Mapped Skeletal Mesh.

This node maps an array of Blueprint Components to the Control Rig Component. These components are defined by the Make ComponentReference and Make ControlRigComponentMappedElement structs. The properties and format of these structs are the same as when mapping from the Details panel.



This node maps an array of Blueprint Components to the Control Rig Component. These components are defined by directly referencing the component and the Make ControlRigComponentMappedComponent struct. The properties of this struct is a streamlined variant of the Make ControlRigComponentMappedElement, providing only the most common mapping properties.



New Function Library

Create Control Rig Container

Create Public Function

Setup Data in Function

Referencing the Function

Localizing Functions

Standard Function Library

Similar to Blueprints, you can share user-created functions between asset graphs by making the function "public". Unlike Blueprints, which only share functions to child classes, Control Rig functions can be shared project-wide. You can create custom function libraries, and share them with all Control Rig graphs in your project.

This document provides a guide for the best practices for creating function libraries in Control Rig, and shows how you can access the default engine-provided function library.

New Function Library

The following steps will show you how to create and use a new Control Rig function library.

Create Control Rig Container

As custom functions can only exist inside Control Rig Assets, the first step will be to create a Control Rig Asset. This Control Rig should not be linked to any particular Skeletal Mesh, as it will be used primarily to contain your functions.

In the Content Browser, click Add (+), then select Animation > Control Rig. In the Create Control Rig Blueprint dialog window, select ControlRig and click Create. Open the Control Rig after it is created.



For the purposes of this asset, your function libraries are Control Rig Assets, and do not include dependencies on any particular skeleton. As a container of functions, this allows for the asset to be as lightweight as possible.

Create Public Function

In the Control Rig Editor, create a new function by clicking Add (+) on the Functions section of My Blueprint.



Next, select the function, and in the Details panel set Access Specifier to Public. This makes the function publicly accessible in all Control Rigs.



Setup Data in Function

From within your function, you can create any arbitrary contained logic you want, including metadata on the function such as tooltip descriptions and context menu categories.

In this example, For Each and Set Control Visibility nodes were created and connected to the function's Entry and Return nodes.



To create variable inputs on the Entry node, select Entry and click Add (+) on the Inputs category in the Details panel. In this example, the following variables were created:

Rig Element Key, as an Array type.

Boolean, as a Single type.



Next, connect the variable inputs to their corresponding nodes.



Optionally, you can also edit the Node Settings properties in the Details panel to add categorization, tooltip, or other helpful properties to the function.



Name

Description

Category

Filling this property puts the node within the named context menu category. This category is visible when adding the node in the Control Rig graph.



Keywords

Adds search terms you can use to find this function when searching for it using the context menu.



Description

Adds a tooltip description for this function. You can view the tooltip when hovering your cursor either on the context menu item, or on the node after it is added to the graph.



Color

Sets the color of the function node header. You can preview the look of your node by expanding the Node Defaults category.



Referencing the Function

To add your shared function in another Control Rig, right-click in the Rig Graph and add your function from the context menu. Shared functions also display their folder path in the node header for reference.



Double-clicking on a shared function node opens the Control Rig Asset containing the function, and the function logic.

Localizing Functions

In cases where you want to diverge the logic of the function from the shared version, you can localize the function, which creates a local copy of the function logic within your current Rig Graph.

To do this, right-click on the function node and select Localize Function. In the dialog window, ensure the function is enabled and click OK.



The function now converts to a local function, where you can diverge the logic locally.



Standard Function Library

By default, Unreal Engine contains a Control Rig Standard Function Library, which can be referenced to understand how to construct your own function libraries. Additionally, it contains a variety of functions that can be used to assist your own rigging workflows.

The Standard Function Library is located within the Control Rig Plugin folder. To access it, open the Content Browser and ensure the plugin folder is enabled by clicking Settings and enabling Show Engine Content and Show Plugin Content.



Next, navigate to and open StandardFunctionLibrary located in Engine > Plugins > Control Rig Content > StandardFunctionLibrary.



Once open, you can view the various functions in the My Blueprint panel.



Because the Standard Function Library is provided by Engine Content, any changes that you make in this asset will be overridden if you reinstall or update Unreal Engine. We reccomend instead to create your own Function Library and not modify the Engine Content one.

Scripting Overview

Accessing Control Rig

Python Log

Python Context

Copy Python Script

Python Script Examples

Adding Nodes

Editing the Hierarchy

Variable and Asset Manipulation

Editor Startup

Use Python scripting in Control Rig to automate workflows and create tools for the rigging process. You can also use the Control Rig Python Log to reverse-engineer commands and copy scripts to share to other projects.

This document provides an overview of Python scripting in Control Rig, the Control Rig Python Log, and a few scripting examples.

You have a Control Rig Asset open.

You have some experience with Python scripting in Unreal Engine.

Scripting Overview

Python is primarily used in Control Rig to interact with the Rig Graph, which consists of multiple modules:

Module Name

Description

ControlRig

Contains the runtime for the rigs.

ControlRigDeveloper

Contains all of the functionality to make changes to rigs.

ControlRigEditor

Contains front-end and user-interface logic.

The Control Rig Graph has been implemented using the Model - View - Controller design pattern. The model is the graph itself using the following terminology:

Control Rig Python Terms

Description

RigUnit

A C++ struct defining a function for a rig (Example: FRigUnit_GetBoneTransform).

Pin

A single input or output of a function.

Link

A connection between two pins.

Node

A visual representation of a RigUnit.

Graph

A directed graph containing all nodes and links within a rig.

PinPath

A string describing the address of a pin within the graph (Example: NodeA.Translation.X).

Controller

An object used to make changes in the graph.

RigElementKey

Chosen from Bone, Control, Null, or Curve.

Bone

An element of the rig in the skeleton used for deformation.

Control

An element of the rig used for interaction.

Null

An element of the rig used for intermediate transforms.

Curve

An element of the rig used to store a float channel.

Shape

A visual representation of a Control in the Viewport.

Hierarchy

A container storing all Bones, Controls, Nulls, and Curves within the rig.

HierarchyController

Similar to the Controller, the HierarchyController is used to make changes to the hierarchy.

Compiler

An object to turn a Control Rig graph into a high performance runtime.

VM

The virtual machine runtime used to execute the rig.

Constant

A value that does not change at runtime.

Parameter

A value that can be used as an input to or output from the rig

Variable

A value that can be changed and runtime and is retained following executions of the rig.

ControlRigBlueprint

The asset containing the Graph, the Controller, Compiler and VM.

Factory

An object responsible for creating and importing new objects. This is used throughout the Unreal Editor to create assets.

Python is enabled from the Python Editor Script Plugin, which itself is enabled by default in Unreal Engine. The plugin also automatically enables when the Control Rig Plugin is enabled, as it is a dependency.

Accessing Control Rig

The first step when scripting is to access the main object you will be interacting with, in this case the ControlRigBlueprint object. There are several ways to access it, however your first command will usually be to load the ControlRigDeveloper module in order to make changes to Control Rig.

To access an existing rig, load the asset with the following example command:

You can also load any currently open Control Rig Asset using:

Creating a new Control Rig Asset is done using:

Lastly, you can create a Control Rig Asset based on a Skeleton or Skeletal Mesh with the following example code:

Python Log

The Python Log provides a text log of all the actions that you performed within the Control Rig Editor. This includes actions within the viewport, the hierarchy, and the graph. Use this to reference commands to use in your Python scripts.

To access the log, click Window > Message Log from the main Control Rig menu, then select Control Rig Python Log from the Message Log sidebar.



You can now perform actions in the Rig Graph and see them recorded in the log.



If you want to save a command to share or use elsewhere, you can select any line from the log and press Ctrl + C to copy it, then you can paste in any text editor. You can also select multiple lines by holding Shift.



You can test commands by pasting them into the Output Log and executing them, ensuring the log type is set to Python. In this example, a new control is created.



Python Context

Python context is used to contextualize which Control Rig asset should be affected when running Python commands. By default, no context is set when viewing a Control Rig. You can set the context for the current Control Rig by clicking Run Python Context within the Class Settings Details panel.



This will execute a series of commands that bind the current Control Rig Asset to the Python context. This allows for commands copied from the Python Log to be pasted and executed within this Control Rig Asset.



Copy Python Script

You can also copy the entirety of a Control Rig's nodes, rig elements, and properties to your clipboard. This can then be pasted into an external script editor, or back to the Output Log to execute on another Control Rig. Copy Python Script is useful for sharing, debugging and comparing the logic between different rigs. Similar to copying individual commands, copying whole rigs can also be useful for reverse-engineering Python commands from Control Rigs.

To copy a Control Rig, click Copy Python Script within the Class Settings Details panel.



Python Script Examples

Adding Nodes

Since nodes are visual representations of RigUnit structs, you will need access to the unit in order to add a node to the graph.

Next, you will need to access the Controller. The Controller is the central object used to make changes to the graph.

To add a node to the graph you can use the add_struct_node, add_comment_node, add_parameter_node or add_variable_node functions. The example below focuses on the struct node, which is the most common type. A struct node is a visual representation of a RigUnit, therefore most of the nodes in a graph are struct nodes.

Editing the Hierarchy

In addition to editing the graph, you can also edit the hierarchy using Python code. Each rig element in the Control Rig hierarchy is identified using RigElementKey, which contains the name and the type of the element. When you create or interact with elements in the hierarchy you will need to use this key.

Control Rig elements are structs, which means they are copied using their total values. As a result, if you change an element you may have to set it again in the hierarchy.

Hierarchy can be used to query elements, get or set global / local transforms, and reset elements back to their initial values.

HierarchyController can be used to add, remove and edit elements. You can also use it to rename and re-parent elements if needed.

To perform an inspection of the current hierarchy, you can use the following Python code:

To create a rig element, such as a bone, you can use the following code:

Variable and Asset Manipulation

To create a Control Rig variable with getter and setter nodes, you can use the following code:

The preview mesh can also be changed using the following code:

The Control Rig can be compiled using any of the following code, depending on your context:

Editor Startup

Python scripts can be loaded upon editor startup, which is useful for loading custom tools and built-in Python functions. You can locate this script and sample scripting functions from your project directory, under the following folder path:

Engine\Plugins\Animation\ControlRig\Content\Python

Within this folder is the init_unreal.py script, which contains the following code:



This code loads example scripts which enable extra functionality.

For example, add_controls_for_selected enables functionality for creating controls on selected bones with additional rules. These rules are determined by the custom Python script located in Engine\Plugins\Animation\ControlRig\Content\Python\RigHierarchy\add_controls_for_selected.py.



Debug Mode

Breakpoints

Property Watching

Class Settings Debug and Profiling

VM Profiling

Execution Stack

Use Control Rig's debug tools to evaluate your rig behavior, and address issues in the Rig Graph. This document provides an overview of these tools.

You have created a Control Rig Asset. See the Control Rig Quick Start page for information on how to do this.

Debug Mode

Similar to Blueprint Debugging, Control Rig Graphs can be debugged using Debug Mode. Using this mode, you can add breakpoints to nodes, step through graph logic, and inspect the live value of properties at any point in the graph.

Debug Mode can be enabled by clicking ReleaseMode in the Control Rig Toolbar. This button toggles between Debug and Release modes.



Debug mode supports your Solve Direction context, and will apply depending on if you are evaluating Forwards Solve, Backwards Solve, or Setup Event.

Breakpoints

When debugging your node graph, use breakpoints to stop the evaluation of your graph at specified nodes and step through subsequent nodes.. With this, you can temporarily preview parts of your graph that were evaluated before the breakpoint within the viewport. When using breakpoints, time doesn't advance until the evaluation reaches the end of the graph, which causes accumulated time nodes to not change their results.

You can add breakpoints to pause graph evaluation at the chosen node by right-clicking a rig graph node and selecting Add Breakpoint. Adding breakpoints will also automatically enable Debug Mode if it is not already enabled.



Once a breakpoint is specified, use the Step toolbar buttons to step through your graph evaluation, node by node. The Control Rig will only evaluate to the breakpoint or the currently evaluated node.



The step buttons perform the following functions:

Name

Icon

Description

Resume



Resumes execution after being halted at a breakpoint. This will stop if another breakpoint is encountered.

Focus



Focuses the graph view on the node currently being debugged.

Step Next



When stopped at a breakpoint, this will jump the debug focus to the next node in the evaluation.

Step Into Function



When stopped at a breakpoint, this will jump the debug focus to the next node in the evaluation. If the next node is contained within a function or collapsed group, the view will enter into the function to focus on the first node of that group.

Step out of Function



When stopped at a breakpoint, this will jump the debug focus to the next node in the evaluation. If the current node is contained within a function or collapsed group, and the next node is located outside the function or group, then the graph view will change to focus on the next node outside of the group.

Property Watching

When debugging, the property values for each graph node can be configured to display their updated values in real-time. To enable this, right-click the node pin you want to update in realtime and select Watch this value.



Once a property is being watched, it will display value information on top of the node, and an icon next to the property to denote that it is being watched.



To stop debugging a property, right-click the pin and select Stop watching this value.



Class Settings Debug and Profiling

The Class Settings Details panel contains tools and properties for debugging your graph's performance. Click Class Settings to reveal this panel.



Enabling Show Node Run Counts will display the number of times a node has run in its execution. This can be useful when determining if looping or collection nodes are running correctly.



VM Profiling

Virtual Machine Profiling, or VM Profiling, can also be used to debug real-time graph performance and the speed of node execution.

Click Enable Profiling under the VMRuntime Settings category to start profiling the rig graph. The Min and Max Duration Color properties are used to show which nodes are taking the shortest or longest amount of time, in microseconds, to execute. The total microsecond (μs) count is also displayed next to the node.



Execution Stack

The Execution Stack panel provides a reference for the order of node operations within your graph. This can be used to debug your nodes and evaluate the sequence of events.

The Execution Stack panel can be opened by navigating to the Control Rig menu bar and selecting Window > Execution Stack.



Once opened, the Execution Stack displays the following information:



Node Column, which displays the order of evaluation for all nodes from the given solve direction. Double-clicking any node here will frame the rig graph view to that node. Selecting a node in the Rig Graph will also highlight the instructions associated with it.

Node Run Count, which displays the number of times the node has been executed. This will only display if Show Node Run Counts is enabled from Class Settings.

Microsecond Count, which displays the total time in microseconds (μs) it takes for the node to execute, if Profiling is enabled.

This page describes functionality that appears in both Unreal Engine and Unreal Editor for Fortnite (UEFN).

The page was originally prepared for Unreal Engine, so some descriptions and screenshots may appear different than what you see in UEFN.

Click here to go back to the main UEFN documentation.

Animating in Sequencer

Multiple Control Rigs

Animation Features

Once you have finished rigging your Control Rig, you can animate it in various ways, such as directly in Sequencer, or more procedurally with Animation Blueprints.

This document provides an overview of these animation methods, their tools, and features.

You have created a Control Rig Asset. See the Control Rig Quick Start page for information on how to do this.

Animating in Sequencer

A Control Rig can be interacted with and animated in Sequencer. You can either add a new Control Rig capable character to your sequence, or add the Control Rig to a currently existing character.

Begin animating a Control Rig by dragging the Control Rig Asset from the Content Browser into your level. This will open a new Sequencer, and add the Skeletal Mesh with Control Rig tracks to it.



If your Sequencer already contains a Skeletal Mesh Actor and you want to add a Control Rig to it, then click the Add (+) Track button on the Skeletal Mesh Track, and select Control Rig > Asset-Based Control Rig > Your Control Rig.



Expanding the Control Rig Track will reveal the list of controls that can be animated. Selecting a control here will also select it in the Viewport, and conversely selecting the control in the Viewport will select the Track.



Controls can be Keyframed similar to most objects in Sequencer. Additionally, pressing the S Key with a Control selected will create a Transform keyframe on the selected control at the current playhead time.



Multiple Control Rigs

Sequencer supports the display and animation of multiple Control Rigs at the same time. All Control Rigs and their Controls will display in the viewport and the Anim Outliner. You can also change their visibility by clicking the eyeball icon to show or hide the Control Rig.



Animation Features

The following features are available to help you animate your Control Rig in Unreal Engine.



Enable Animation Mode to provide an animator-friendly workspace and tools in Unreal Engine.

Enable Animation Mode to provide an animator-friendly workspace and tools in Unreal Engine.



Procedurally affect your Control Rig by using it in Animation Blueprints.

Procedurally affect your Control Rig by using it in Animation Blueprints.



Quickly edit animation without needing Control Rig Assets using FK Control Rig.

Quickly edit animation without needing Control Rig Assets using FK Control Rig.



Attach the position, orientation, or scale of an object to other objects using a variety of constraints.

Attach the position, orientation, or scale of an object to other objects using a variety of constraints.



Dynamically re-parent your Controls when animating with Control Rig.

Dynamically re-parent your Controls when animating with Control Rig.



Drive and extend your Control Rig animation workflow using Python scripting.

Drive and extend your Control Rig animation workflow using Python scripting.

Enabling Animation Mode

Animation Mode Overview

Anim Outliner

Anim Details

Animation Mode Tools

Poses Tool

Tweens Tool

Snapper Tool

Motion Trail Tool

Pivot Tool

Animation Mode Settings

Animation Mode is a Mode in Unreal Engine that exposes new tools, panels, and editor behaviors that assist your animation workflows. Using this Mode when animating with Control Rig offers a more animation-focused editor experience, with tabs to aid in selecting Controls, transform displays, and launching tools.

This document provides an overview of Animation Mode, including its user interface, tools, and settings.

You have created a Control Rig Asset. See the Control Rig Quick Start page for information on how to do this.

Animation Mode is mainly dependent on using Control Rig within Sequencer, therefore a basic knowledge of Sequencer is required.

Enabling Animation Mode

Animation Mode can be enabled in the following ways:

Dragging a Control Rig Asset from the Content Browser into a Level. This will create a new Level Sequence, add the character with a Control Rig Track, and enable Animation Mode.



Selecting a Control Rig Track in Sequencer.



Manually enabling Animation Mode by clicking the Mode dropdown menu and selecting Animation. Alternatively, you can also press Shift + 7.



Animation Mode can be disabled and normal level editing mode restored either by selecting the Mode dropdown menu and clicking Select, or by pressing Shift + 1.



Animation Mode Overview

Animation Mode is a level editor Mode which contains specialized editing interfaces and workflows. Activating it will add the following panels to the Unreal Editor interface:



The Animation panel, which contains Animation Mode Tools, Settings, Space Switching Controls, and Constraints.

The Anim Outliner, which is an Outliner modified to only show Controls on the selected Control Rig.

Anim Details, which is a Details panel modified to only show relevant animatable properties of selected Controls.

Anim Outliner

The Anim Outliner panel displays all animatable Controls and organizes them according to their hierarchy, as defined in the Control Rig.



Selecting Controls here will also select them in the Viewport and Sequencer. Inversely, selecting Controls in either the Viewport or Sequencer selects them here, too.

Control icons inherit the control shape color of their control, which makes it easier to read the control and match it to the Viewport color.

Anim Details

The Anim Details panel displays relevant animatable properties for the selected Control, including properties of children channel Controls.



Transform values are relative to the Initial Local / Global values defined on the Control in the Control Rig Asset, therefore, the "zero-point" of these Controls is equal to those values.

Boolean, Float, Integer, and Enum Controls that are children of a selected Control will automatically be selected when selecting the parent, and will display within the Anim Details panel as Channels. This way, you can manipulate these Controls at the same time as the parent, and also create custom attributes and channels on a single Control.

Animation Mode Tools

The Animation panel contains the following tools to aid your animation workflows:

Name

Icon

Description

Select



Enabling this will only make Control Rig controls be selectable in the Viewport. All other objects, including the character, will not be selectable. This can also be enabled from the Animation Settings by enabling Only Select Rig Controls.

Poses



Opens the Control Rig Pose Tool.

Tweens



Opens the Tween Controller.

Snapper



Opens the Control Rig Snapper Tool.

Trails



Opens the Motion Trail Window.

Pivot



Creates a temporary pivot for alternative Control manipulation.

Poses Tool

The Control Rig Pose Tool is a tool that stores and retrieves data on your Controls. You can save the relative pose on selected Controls, adjust the thumbnail icon, and configure your saved pose to apply to symmetrical Controls.



To save a new pose, first select the Controls you want to include in the pose, then click Create Pose in the toolbar. You will then be prompted to name the pose Asset. Enter a name, then click Create Asset to create the pose. The new pose will be created within the selected folder.



You can also adjust the Thumbnail by selecting the pose in the browser, changing your Viewport camera, and clicking Capture Thumbnail.



Before applying poses, you must ensure you have the appropriate Controls selected. You can do this either by manually selecting the Controls or by selecting the pose and clicking Select Controls, which selects all Controls from that pose.



There are several ways you can apply saved poses to your Controls. You can either:

Double-click the pose from the browser, which will apply the selected pose.



Click Paste Pose.



Manipulate the Blend Pose Slider, which will apply the pose partially based on a delta between the current pose of the Controls and the selected Pose. A value of 0 will maintain the current pose, whereas a value of 1 will fully apply the selected pose.



Enabling the Key option will create Keyframes when a pose is applied to the selected Controls.



For humanoid and other symmetrical rigs, you can also apply your poses on either side of the line of symmetry. This is done with a combination of namespace searching and axis mirroring and flipping. Enabling the Mirror option will apply your saved poses to the other side, ensuring you select the Controls first.



By default, the naming convention system assumes Left and Right are designated as _l_ and _r_ respectively. You can change this by editing the Right Side and Left Side property fields to match your Control Rig's symmetry designation. For example, you may want to change these properties to read as _left and _right if your symmetry designation is a postfix.



Mirror Axis is where you designate the axis of symmetry along your character. In most cases this will remain as X if you use a standard Y - Facing character in Unreal Engine.



Axis to Flip is the rotation axis to maintain while inverting the others in order to calculate the mirrored pose. In most cases this should be set to X, which is meant to keep rotational X values the same, while inverting Y and Z.

Because of the arbitrary nature of some Control Rigs, you should ensure your Control Rig symmetry is constructed in such a way that it can appropriately comply with axis mirroring and flipping.

Right-clicking on a pose will expose a context menu with the following commands:



Name

Description

Rename Asset

Renames the pose.

Save Asset

Saves the pose.

Delete Asset

Deletes the pose.

Paste Pose

Applies the pose to the selected Controls.

Paste Mirror Pose

Applies the pose to the selected mirrored Controls.

Select Controls

Selects the Controls defined by the pose.

Update Pose

Updates the pose based on the currently selected Controls and their pose.

Rename Controls

Opens a property matrix for changing the names of the saved Controls within a pose. This is useful if you want a pose to apply to a different Control Rig with differently named Controls.

Holding Alt and double-clicking a pose will select the Controls from that pose.



By default, the folder structure for saving and using poses is Content/ControlRig/Pose. In cases where you want to save to a different directory, or have imported poses that are not within this default directory, you can add other folders to your pose tool directory.

To do this, right-click in the directory area and select Add Existing Folder To View. Select the folder you want to add and click OK.



The folder, and any poses within, should now display in the pose tool directory.



Tweens Tool

The Tweens Tool can be used to adjust the interpolation between selected keyframes or their neighbors in a variety of ways.



With the Tween Controller open, select your keyframed Controls and ensure your playhead is between two keyframes. Manipulate the Tween Controller value by either dragging the slider or typing in a value between -1 and 1. A value of -1 will cause the new in-between keyframe to match the value of the preceding keyframe, whereas a value of 1 will match the next keyframe's value.



The Tween Controller has several modes for adjusting the in-between keyframe available in the Tween tool dropdown menu.

Tween Mode

Description

Blend to Neighbor (BN)

Moves the key to the previous (-1) or next (1) neighboring keyframes from its relative current position.



Push Pull (PP)

Softens (-1) or intensifies (1) the selected keyframes' overall values between the first and last key.



Tween (TW)

Moves the key to the previous (-1) or next (1) neighboring keyframes in absolute values. This means that 0 will always move the key's value half-way between neighboring values.



Snapper Tool

The Snapper Tool can be used to pin your Controls to other sources for a duration of time. Rather than attaching the Control, it bakes keyframes instead, so you can easily modify the resulting animation after snapping. You can snap to other Controls, objects in Sequencer, or the world.



To use the Snapper Tool, you must first define the Child and Parent actors. Clicking on the Children or Parent buttons will assign your current selection to that category. In this example, the Hand Control is selected to be the Child, and the Ball is selected to be the Parent.



Next, if needed, you can define the range of time for the snapping effect to be active and where Keyframes will be baked. In this example the range of time is specified between frames 6 - 24.



Lastly, there are a few settings available that control the snapping behavior:

Name

Description

Keep Offset

Whether to maintain the offset between the parent and child at the initial snap time. If disabled, then the child will attach to the same transform as the parent for the duration of the snap.

Snap Position

Whether or not to snap the child's position to the parent.

Snap Rotation

Whether or not to snap the child's rotation to the parent.

Snap Scale

Whether or not to snap the child's scale to the parent.

Clicking Snap Animation will perform the snap operation. In this example, Keep Offset is enabled in order to maintain the hand at the top of the ball.



Motion Trail Tool

The Motion Trail Tool previews your overall Control motion by drawing the motion as an interactable curve in the Viewport. You can then edit the motion by manipulating the keyframes along the curve.



After opening the Motion Trail window, enable the Show Trails option to make the motion curve visible for your selected Controls.



Selecting other Controls or multi-selecting Controls while Show Trails is enabled will draw motion trails for those Controls, too.



Enable the Show Keys option to draw the position information of Keyframes along the curve. Select these keys in the Viewport to reveal a manipulator you can use to edit the position data of your motion from the Viewport.



The following properties and features are available in the Motion Trail tool:

Name

Description

Show Trails

Draws a Motion Trail for the selected Controls.

Trail Color

Sets the color of the Motion Trail.

Show Full Trail

Enabling this draws the full Motion Trail based on all keyframes within Sequencer. Disabling this will only draw a section of the trail relative to the Playhead.



Trail Thickness

Controls the thickness of the Motion Trail. A value of 0 will make the trail be 1 pixel thin.

Frames Before

The amount of the trail, in Frames, to display before the current Playhead time when Show Full Trail is disabled.

Frames After

The amount of the trail, in Frames, to display after the current Playhead time when Show Full Trail is disabled.

Evals Per Frame

This controls the smoothness of the Motion Trail curve. Increasing this will result in a smoother-looking curve, but at a performance cost.

Show Keys

Enables the display of keyframes along the Motion Trail. Requires Show Trails to also be enabled. Keyframes can be selected and manipulated to change their position information.

Show Frame Number

Enables a frame counter display next to each keyframe. The number is based on the keyframe time in Frames, and adheres to Sequencer's Frames Per Second setting.

Key Color

Sets the color of the keyframe display, including the keyframe number.

Key Size

Controls the size of the keyframe points.

Show Marks

Enables the display of visual timing marks along the Motion Trail. These marks are useful for visualizing the speed of a motion along the curve. Marks that are spread apart denote high-speed regions, whereas marks that are close together denote lower-speed regions.



Mark Color

Sets the color of the timing marks.

Mark Size

Controls the size of the timing marks.

Lock Marks to Frames

Sets the distribution of the timing marks to match Sequencer's Frames Per Second setting.

Seconds Per Mark

If Lock Marks to Frames is disabled, you can set an arbitrary time here (in seconds) for marks to be distributed along the curve.

Motion Trails can be enabled for non-Control Rig objects and actors in Sequencer by using the console command: Sequencer.UseOldSequencerTrails 0. This will disable the legacy transform trajectory display, enabling the new Motion Trails tool to be used instead.

Pivot Tool

The Pivot Tool creates a temporary pivot point for a selected Control, which can then be moved to any arbitrary point. This tool is useful if you need to temporarily manipulate a Control relative to other points. After enabling the Pivot Tool, clicking Edit enables the pivot to be moved to different points. Clicking Pose will lock the pivot to its current position, where manipulating it will move the selected Control relative to the pivot.



There are several hotkeys and behaviors to aid you using the Pivot Tool in different ways.

Hotkey

Description

Ctrl + Shift + Alt + G

Resets the pivot position back to the Control.



Shift + LMB Pivot Tool

When multiple Controls are selected, holding Shift and clicking the Pivot Tool will snap all pivots to the last selected Control.



Ctrl + LMB Pivot Tool

When multiple Controls are selected, holding Ctrl and clicking the Pivot Tool will snap all pivots to the middle point of all selected Controls.



Ctrl + LMB in Viewport

Holding Ctrl and clicking in the Viewport will snap the pivot point to the selected point.



Shift + Pivot

Holding Shift while pivoting will disable rotation on the Control when pivoting, causing it to only translate.



Animation Mode Settings

In the Animation Mode Panel, you can expand the Animation Settings section to reveal the following additional settings:



Name

Description

Display Hierarchy

Enabling this will draw Bones on the character.



Display Nulls

Enabling this will draw all Nulls from the Control Rig in the Viewport.

Hide Control Shapes

Hides all Controls in the Viewport. This will also hide Bones and Nulls if Display Hierarchy or Display Nulls are enabled.

Show All Proxy Controls

Hides or shows all Proxy Controls in the viewport. Proxy Controls are invisible until you select one of the Controls they are driving. Enabling this can be a useful way to discover all Proxy Controls in a rig.

Show Controls as Overlay

Enabling this makes occluded Controls visible (similar to X-ray modes in other software), allowing them to be selected if they are behind other Controls or geometry.



Driven Control Color

When a Proxy Control is selected, this is the color that all driven Controls will exhibit, which can be useful to aid in selection feedback for your Proxy Control relationships.



Display Axes on Selection

Shows a preview axis on the selected element.

Axis Scale

The scale of the preview axis when Display Axes on Selection is enabled.

Coord System Per Widget Mode

Restores the coordinate space when changing Gizmo modes in the Viewport.

Only Select Rig Controls

Enabling this will only make Control Rig controls be selectable in the Viewport. All other objects, including the character, will not be selectable. This can also be enabled from the toolbar by clicking the Select button in the Animation panel toolbar.

Local Transforms in Each Local Space

Enabling this will transform each selected control relative to their local transform space, if your transformation gizmo is set to local coordinates.



Gizmo Scale

Increases or decreases the gizmo scale.



Control Rig Blueprint Node

Properties

Accessing Variables and Controls

Control Rigs can be referenced within Animation Blueprints in order to build animation blueprint logic that interacts with controls and variables. Typically you may want to use Control Rigs in this way to achieve procedural gameplay control of certain Control Rig features, such as ground alignment or other arbitrary contact points.

You have created a Control Rig Asset for a Skeletal Mesh. See the Control Rig Quick Start page for information on how to do this.

You have created an Animation Blueprint Asset for the same Skeletal Mesh. See the Animation Blueprints page for information on how to do this.

Control Rig Blueprint Node

Control Rig content is accessed within Animation Blueprints by using the Control Rig node. You can add this node by right-clicking in the Anim Graph and selecting Misc > Control Rig. Ensure the source output is connected to the result pose by connecting the pins.



Next, you need to assign the appropriate Control Rig Class. To do this, select the node, navigate to the Details panel, and select the Control Rig from the Control Rig Class property dropdown menu.



Properties

The Control Rig Animation Blueprint node has the following specific properties:

Name

Description

Set Initial Transform From Mesh

Overrides the initial transforms from the Control Rig with the initial transform from the Skeletal Mesh.

Reset Input Pose to Initial

Enabling this causes the pose to reset to the initial pose prior to evaluation.

Transfer Input Pose

Enables bone transform information to be read by the Control Rig node when data is connected to its Source pin.

Transfer Input Curves

Enables Animation Curve information to be read by the Control Rig node when data is connected to its Source pin.

Transfer Pose in Global Space

Enables the incoming pose to be evaluated in Global space, as opposed to Local space if this is disabled.

Transferring a pose in global space guarantees a global pose match, while local space ensures a match of the local transforms. In general, transforms only differ if the skeleton hierarchy differs between the Control Rig skeleton and the Animation Blueprint skeleton. Disabling this can also improve performance.

Input Bones to Transfer

A list of bones to transfer when data is connected to its Source pin. When bones are added to this list, only those bones are transferred. If no bones are listed, then all bones are transferred.

Input

If the Control Rig contains Variables, they can be exposed as pins on the node by enabling Use Pin, or controlled by Animation Curves by selecting a curve from the Use Curve dropdown menu if the variable is a Float.

Transform input data for all Controls can also be exposed here by enabling Use Pin on the control entry.

Control Rig Class

The Control Rig class to use for this node.

Accessing Variables and Controls

The primary interaction with the Control Rig node is by manipulating Controls or Variables exposed on the node. You can then connect them to logic that drives their values or transforms.

Variables can be exposed by ensuring they are instance-editable by clicking the Eye next to it in the Control Rig My Blueprint panel. Next, in the Animation Blueprint, select the Control Rig node and enable Use Pin on the Variable entry. You should now see the Variable exposed as a pin on the node.



For Float type variables, you can instead specify for those to be driven with Animation Curves by clicking the dropdown menu next to Use Curve and selecting an AnimCurve.



By default, all controls from the Control Rig Class are listed in the Control Rig node's Input property and can be exposed by enabling Use Pin. This exposes transform data for that control.



Creation and Overview

Usage

Additive FK

Bake to FK Control Rig

Filter Bone List

FK Control Rigs are procedurally-generated Control Rigs that can be added to any Skeletal Mesh in Sequencer, regardless of whether that actor has a Control Rig asset or not. These rigs can be used to make additive adjustments to bones without requiring you to create an entire Control Rig asset. Additionally, you can bake any Animation Sequence to an FK Control Rig to perform overriding adjustments.

This document provides an overview of how to create and use FK Control Rigs in Sequencer.

You have added a Skeletal Mesh character to Sequencer. See the Apply Animation to a Character page for information on how to do this.

You are familiar with Keyframing in Sequencer.

Creation and Overview

To create a FK Control Rig, assuming you have already added a Skeletal Mesh to Sequencer, click Add (+) Track on the character's track and select Control Rig > FK Control Rig.



The FK Control Rig track is now visible, and bones are shown on the Skeletal Mesh in the level viewport.



Expanding the FK Control Rig track reveals the list of bones. You can select bones here, which also selects them in the viewport, or select bones directly in the viewport, which also selects the track. Once a bone is selected, it can be manipulated and keyframed just like any other object in Sequencer.



Usage

Once an FK Control Rig is created in Sequencer, you can animate the bones individually to create animation on the Skeletal Mesh. Depending on the complexity of your character or the scope of animation, it may be preferable to use FK Control Rig rather than creating a unique animation outside of Unreal Engine.

For example, Skeletal Meshes with few bones can be easily animated with FK Control Rig. Select the bone you want to animate and keyframe it by either pressing S (if your focus is in the viewport), or Enter (if your focus is in Sequencer).



Additive FK

FK Control Rig can also apply additively to Animation Sequences playing in Sequencer. This is useful if you want to perform additive edits to an animation instead of overriding it.

To make FK Control Rig additive, right-click on the FK Control Rig track and select Additive.



Now you can edit and keyframe bones and have those changes apply cumulatively to the base animation.



Bake to FK Control Rig

You can also bake animation from Sequencer to FK Control Rig. This is useful if you need to perform overriding adjustments, such as fixing animation pops or bad curves, without needing to perform the same fixes outside Unreal Engine and re-importing.

To do this, right-click on the Skeletal Mesh track in Sequencer and select Edit With FK Control Rig. This opens a baking dialog window where you can specify the following options:



Name

Description

Export Transforms

Bakes transform data to FK controls.

Export Curves

Bakes AnimCurve data to FK controls.

Record in World Space

Bakes in absolute world space coordinates.

Evaluate All Skeletal Mesh Components

Evaluates all skeletal mesh components when baking. Typically you may want to enable this if you are using a Blueprint with other Skeletal Mesh Components.

Warm Up Frames

The amount of frames to evaluate before the baking process occurs. This is useful if there are post-process Animation Blueprint effects that require additional time to settle before evaluation.

Delay Before Start

The amount of Display Rate frames to delay before the baking process occurs. This is useful if there are post-process Animation Blueprint effects you need to run repeatedly before evaluation.

Reduce Keys

Enable this to run a Simplify process after the baking process occurs, which removes redundant keyframes based on a tolerance amount.

Tolerance

The higher the Tolerance value, the more the filtered curve is allowed to deviate from the original, which causes more keyframes to be removed if Reduce Keys is enabled.

Pressing Create completes the bake operation, which creates a FK Control Rig track with keyframes according to the baked animation.



Once you have edited your animation using FK Control Rig, you can also bake back to an Animation Sequence by right-clicking on the Skeletal Mesh track and selecting either Bake Animation Sequence or Create Linked Animation Sequence.



Filter Bone List

Depending on the Skeletal Mesh, the list of bones displayed by FK Control Rig can sometimes be very large and contain unnecessary bones for your animation. To resolve this, you can filter the list of displayed bones to only include the bones that are relevant for your workflow.

To filter bones, right-click on the FK Control Rig track and click Select Bones Or Curves To Animate. This opens a window where you can manually enable or disable individual bones from showing.



Filtering out bones removes them from FK Control Track as well as hides them in the viewport, making it easier to work with just the bones you want. Once you have specified which bones to filter, click OK to apply the filter.



Create a Constraint

Constraint Usage

Bake Constraint

Compensate Keyframes

Dynamic Offset

Constraints Manager

Constraint Types

Translation Constraint

Rotation Constraint

Scale Constraint

Parent Constraint

LookAt Constraint

When animating, there may be cases where you need to attach elements together without causing a change in the Outliner or Control hierarchy. This kind of attachment is known as constraining. Constraints in Unreal Engine are broken up into different methods: Position, Rotation, Scale, Parent, and LookAt. With these methods, you can set options to control how these constraints operate, such as controlling the attachment offset and baking the constraint back to normal keyframes.

This document provides an overview of constraining in Sequencer, and the different workflows for each constraint method.

You have created a Control Rig Asset. Refer to the Control Rig Quick Start page for information on how to do this.

Constraints when animating are accessed through the Animation Mode panel, therefore you need to enable Animation Mode.

Constraining is mainly dependent on using Control Rig within Sequencer, therefore you need a basic knowledge of Sequencer.

Create a Constraint

Constraint information, as well as the workflow for adding constraints, is located in the Animation panel when Animation Mode is enabled.



Constraints are established by creating a Parent - Child relationship between two or more objects. To create a new constraint, first select your Controls you want to constrain (child), then click Add Constraint (+) and select a constraint type. Your cursor changes to an eyedropper tool you can use to select the object to constrain to (parent) in the Viewport.



Constraining is not limited to Control Rig elements, you can constrain any object or Actor. Additionally, Actors can be constrained without needing Sequencer to be open.

After creating your constraint, you can view its keyframe information in Sequencer for the constrained Control. Most constraints will also create compensating keyframes, which maintains the current visual position of the child when the constraint activates. These compensating keyframes are linked to the constraint keyframe, and follow it if you change the timing.



Constraint Usage

Your constraints can also be viewed in the Animation Panel's Constraints section, when selecting the constrained Control. Here you can create new constraint keyframes, edit the properties of the constraint, and bake the constraint back to normal keyframes.



If you have more than one constraint applied to an object, they also appear here too. When you play or scrub the sequence, each constraint indicates its status by highlighting when it becomes active or inactive.



The buttons for a constraint entry provide the following functionality:

Button

Description



Creates an active keyframe for the constraint at your current time in Sequencer. If the constraint is already active, then a deactivate keyframe is created instead. Compensating keyframes are also created to maintain the same world position on the constrained object





If you have multiple constraints on the same object, these buttons move the constraint up or down on the list. Constraints in Unreal Engine are hierarchical and override other constraints higher on the list (only if the constraints animate the same channels). New constraints always take priority over older ones and are placed lower on the list.



Because constraints can be overridden, it is not always necessary to deactivate other constraints. For example, since Parent Constraints animate all transform channels of a control, simply activating one is enough to essentially deactivate all others, so long as the one activated is higher priority. In this example, although both constraints are active, only the root constraint is providing the constraint effect due to it being lower in the list and higher priority





Removes this constraint.

Right-clicking on a constraint entry reveals a context menu where you can edit properties specific to that constraint type, bake the constraint, and set compensating keyframes.



Bake Constraint

Once you have finalized animating with constraints, you can bake the final result to keyframes. This can be useful if you want to revert to normal keyframe animation to make further edits without constraint considerations.

To bake your selected Controls, right-click a constraint entry and select Bake.



Compensate Keyframes

When animating, there may be cases where the constraint exhibits a noticeable pop when it activates or deactivates. This commonly happens if you adjust the pose of the parent after the constraint has been created, which breaks the visual matching that the original compensating keyframes were providing.



To resolve this, select the offending Controls, right-click the constraint, and select Compensate Key. You must also ensure that the Sequencer Playhead is on the same time as the constraint keyframe that you want to fix. This will re-create new compensating keyframes for the new location of the parent object.



While Compensate Keys can be used to resolve errors with single constraints, Compensate All Keys can also be used to re-create all compensating keyframes for every constrained Control in the sequence, regardless of selection or Playhead position.

Dynamic Offset

By default, you can keyframe the constrained object in addition to the constraint affecting it. If you want to disable this option and not allow the child object to animate, right-click the constraint and disable Dynamic Offset. This locks the position of the constrained object at its current transform, and it will now only move if the parent object moves.



Constraints Manager

As you constrain many objects in your Level Sequence, it may become more difficult to manage and view your constraints. You can use the Constraints Manager Actor as a way to view and manage all constraints within a Level.

When you create any constraint for the first time, the Constraints Manager Actor automatically creates within your level, and selecting it consolidates all used constraints into a single list. This makes it easier to view and manage large numbers of constraints on several objects at the same time.



Constraint Types

The following constraint types can be created when clicking Add Constraint (+):



Translation Constraint

Rotation Constraint

Scale Constraint

Parent Constraint

LookAt Constraint

Translation Constraint

Translation Constraints constrain an object along translation axes only. It follows the parent position but not its rotation or scale.



If Maintain Offset is disabled from the constraint context menu, then the constrained object follows the parent object position in absolute coordinates, instead of relative to when the constraint was made.



Rotation Constraint

Rotation Constraints constrain an object along rotation axes only. It follows the parent rotation but not its translation or scale.



If Maintain Offset is disabled from the constraint context menu, then the constrained object follows the parent object rotation in absolute coordinates, instead of relative to when the constraint was made.



Scale Constraint

Scale Constraints constrain an object along scale axes only. It follows the parent scale but not its translation or rotation.



If Maintain Offset is disabled from the constraint context menu, then the constrained object follows the parent object scale in absolute coordinates, instead of relative to when the constraint was made.



Parent Constraint

Parent Constraints constrain an object along all axes and channels to a parent as if it were attached hierarchically.



By default, scale is not included in a Parent Constraint. To include it, right-click on the constraint entry and enable Scaling.



Similar to the other constraint types, disabling Maintain Offset causes the constrained object to follow the parent transform in absolute coordinates, instead of relative to when the constraint was made.

LookAt Constraint

LookAt Constraints constrain an object along rotation axes only by aiming at the parent location.



You can set the aim direction for the child object by right-clicking the constraint entry and editing the Axis properties.



Unlike other aim-type attachments, the LookAt Constraint does not use up vectors. Instead, you can animate the roll axis to manually control how you want the roll to behave. This can also be useful to eliminate rotation flipping problems, which are common in other aim-type attachments.



Space Switching in Sequencer

Parent and World Space

Custom Spaces

Keyframing Space Switching

Baking

Settings and Preferences

Space Switching in Control Rig Assets

Pre-defining Custom Spaces

Dynamic Hierarchy Nodes

Preview Space Switching

When animating, there may be cases where you want to change the transform space on Controls to suit different circumstances, such as hands contacting and moving with parts of the body or other objects. Depending on your rig complexity, this can be a difficult problem to solve as it requires you to create preset constraint systems within your Controls.

With Control Rig Space Switching, you can easily and dynamically re-parent your Controls to other rig elements in order to suit your animation needs. Spaces can be pre-defined within the Control Rig Asset, or created within Sequencer, providing you flexibility.

This document provides an overview of Space Switching within Sequencer and Control Rig.

You have created a Control Rig Asset. Refer to the Control Rig Quick Start page for information on how to do this.

Space Switching when animating is accessed through the Animation Mode panel, therefore you need to enable Animation Mode.

Space Switching is mainly dependent on using Control Rig within Sequencer, therefore you need a basic knowledge of Sequencer.

Space Switching in Sequencer

Space Switching when animating a Control Rig is accessed through the Animation panel when Animation Mode is enabled. Click Spaces within the panel to reveal the Space Switching interface.



You can also press Tab when your cursor is on the Viewport to open a temporary Spaces menu.



Parent and World Space

By default there are two main spaces that can be applied to Controls: Parent and World.

For typical Controls, the default space will be set to Parent, which places the Control within the parent-space defined in the Control Rig outliner. For example, selecting the Neck Control will highlight the Parent space, denoting that it is the current transform space, which you can correlate to the hierarchy in the Anim Outliner.



Clicking World will change the transform space of the selected control to be relative to absolute world coordinates. In effect, this dynamically un-parents any selected control from its hierarchy position in the Control Rig.



Custom Spaces

Any Control, Bone, or Null can also be used as a transform space, which makes space switching more versatile as you can dynamically re-parent Controls to other Controls.



To add a custom space for your selected Controls, click Add (+) in the Spaces header menu, then select your rig element. This will add it to the spaces list as a selectable space.



Although you can select either Bones, Controls, or Nulls as a custom space, we recommend that you typically select Controls in order to avoid cyclical rig errors in the re-parenting.

Keyframing Space Switching

One of the main benefits of spaces is being able to change spaces in your animation. This can be useful if characters are placing their hands on points of contact and then animating those points.

When you select different spaces, it will automatically create a space Keyframe for that control, as well as create compensating Transform Keyframes that maintain the visual position of that Control. Each space keyframe will also use a unique color on the track for the duration of that space.



When Controls switch spaces, they occupy the local space of that new parent. Because of this, their local spatial coordinates become different from what they were before. In this way, space switching occurs over a single frame. This can be visualized by viewing the keyframes in the Curve Editor.



You can preview the space switching functionality by moving the Playhead over the different space Keyframes and manipulating the parent Control. In this example when the head Control is the parent, then it will affect the hand IK Control, without needing to keyframe the hand.



Baking

Once you have finalized your animation with space switching, you can bake the final result of your keyframes. This is useful if you are wanting to stabilize the final animation back to the default parent space.

To bake your selected Controls, click Bake… in the Spaces menu, which will open the bake dialog menu with the following interface:



The transform space to bake to. Typically you will want to select Parent in order to restore the original space of the control, but you can also select or add any other space if you want to maintain a non-parent transform space.

Bake settings, which include the following properties:

Name

Description

Start Frame

The start frame in Sequencer to define the range of baking.

End Frame

The end frame in Sequencer to define the range of baking.

Reduce Keys

Enable this to run a Simplify process after the baking process occurs, which removes redundant keyframes based on a tolerance amount.

Tolerance

The higher the Tolerance value, the more the filtered curve is allowed to deviate from the original, which causes more keyframes to be removed if Reduce Keys is enabled.

Settings and Preferences

You can change the space Keyframe colors that are used in Sequencer from the Editor Preferences window. To access these settings, select Edit > Editor Preferences from the Unreal Engine menu, then navigate to the Curve Editor section, and locate the following properties:



Setting

Description

Parent Space Custom Color

The keyframe track color to use when the current space is set to Parent.

World Space Custom Color

The keyframe track color to use when the current space is set to World.

Control Space Custom Colors

A customizable array you can add custom Control names to and set explicit keyframe track colors to use for those Controls.

Space Switching in Control Rig Assets

Space Switching can also be pre-built within your Control Rig asset. This is useful if you are wanting to define common spaces on controls beforehand, alleviating the need to add them continuously in Sequencer. You can also create logic to control space switching through Control attributes.

Pre-defining Custom Spaces

In your Control Rig asset, select a Control, navigate to the Details panel, and locate the Available Spaces property. With this array, you can pre-define other rig elements to use as a transform space.



Click the Add (+) button to add a new entry and specify the Type and the Element to use in the drop-down menu. As mentioned previously, although you can select either Bones, Controls, or Nulls as a custom space, we recommend that you typically select Controls in order to avoid cyclical rig errors in the re-parenting.



Once an item is specified in the Available Spaces property, you can now see this custom space automatically listed as a switchable space for that Control.



Dynamic Hierarchy Nodes

Space switching functionality can also be graphed within the Control Rig graph using the Dynamic Hierarchy nodes. Right-click within the Control Rig graph and locate the following nodes under Dynamic Hierarchy:



Name

Image

Description

Add Parent



Adds a second parent to a rig element. The weight of the new parent is initially 0, and you can use Set Parent Weights to set the weight. This node contains the following options:

Child, where you define the item to receive the additional parent.

Parent, where you define the new parent.

Get Parent Weights



Returns the current weight array of all parents of a given rig element.

Set Parent Weights



Sets the parent weight array of a given rig element. The number of weights must equal the number of parents of a rig element.

Switch Parent



Switches a Rig Element to a new parent. This node contains the following options:

Mode, where you can specify the Child to either switch to a new Parent, World Space, or back to its Default Space.

Child, where you define the item to space switch.

Parent, where you define the new parent element to switch to if Mode is set to Parent Item. Otherwise you can leave this pin unlinked.

Maintain Global, which is used to define if local or world space should be maintained upon switching.

Preview Space Switching

Space switching is built upon a Dynamic Hierarchy system, which you can preview and debug from within a Control Rig asset. In this example, the Rig Hierarchy panel automatically updates as it accounts for a Control space switching to World Space.



You can also temporarily test different spaces by either right-clicking on a selected Control in the viewport and selecting Space Switching, or by pressing Tab.



Create Control Rig Track

Animating Controls

Control Selection

Get and Set Control Values

Animation Mode

Tween Tool

Snapper Tool

Space Switching

Animation Mode Settings

Baking and Merging

Bake to Control Rig

Bake to Animation Sequence

Merging Animation Layers

Python scripting can be used to automate and control various parts of animating your Control Rig in Sequencer. This document provides an overview of the main ways to use Python with animating your Control Rig, Animation Mode, and other various animation workflows.

You have some experience with Python scripting in Unreal Engine, as well as scripting in Sequencer.

You have an understanding of creating and using Control Rigs.

Create Control Rig Track

Creating a Control Rig track is slightly different from normally creating Tracks in Sequencer. A Control Rig track needs to have a Control Rig class defined to be created. To create a Control Rig Track, use the following commands:

Animating Controls

The following examples explain a variety of ways you can edit and animate controls.

Control Selection

These commands can be used to select controls and query control selection:

Get and Set Control Values

You can get specific values from any of the controls at any given frame number with the following commands:

You can also set specific values on any of the controls at any given frame number using these commands:

Animation Mode

Animation Mode Tools can also be affected with Python scripting. The following examples are provided.

Tween Tool

The following commands can be used for the Tween Tool:

Snapper Tool

The following commands can be used for the Snapper Tool. If the driver object is animated, then the driver object has to be added to the active sequence.

Space Switching

The following commands and examples can be used for Space Switching.

To start space switching, you will need to create space keyframes. You can set a control's space to its default parent, world space, or to another control at any given frame number.

Once space keyframes are created, you can move them to any frame number by using these commands:

Space keyframes can be deleted by using these commands:

You can bake the final animation to a specific space by using the following commands:

Animation Mode Settings

Animation Mode Settings can be edited using Python scripting. Each property uses the following terminology:

Name

Description

bDisplayHierarchy

Draws Bones on the character.

bDisplayNulls

Draws Nulls on the character.

bHideManipulators

Hides all Controls in the Viewport. This will also hide Bones and Nulls if Display Hierarchy or Display Nulls are enabled.

bCoordSystemPerWidgetMode

Restores the coordinate space when changing Gizmo modes in the Viewport.

bOnlySelectRigControls

Enabling this will only make Control Rig controls be selectable in the Viewport. All other objects, including the character, will not be selectable.

bLocalTransformsInEachLocalSpace

Enabling this will transform each selected control relative to their local transform space, if your transformation gizmo is set to local coordinates.

GizmoScale

Increases or decreases the gizmo scale.

The following commands can be used:

Baking and Merging

Bake to Control Rig

If you already have an animation sequence on your Actor in Sequencer, you can create a Control Rig Track by baking the current animation to a Control Rig. To do this, use the following commands:

Bake to Animation Sequence

Once a Control Rig animation is completed, you can export the animation as an Animation Sequence to be used in other areas of Unreal Engine by using the following commands:

Merging Animation Layers

Starting Out

Guides

Paper 2D in Unreal Engine is a sprite-based system for creating 2D and 2D/3D hybrid games entirely within the editor. At the core of Paper 2D are Sprites (which are a Texture Mapped Planar Mesh and associated Material). You can edit Sprites inside Unreal Engine with the Sprite Editor and create sprite-based animations with Flipbooks (which animate a series of Sprites sequentially by using key frames and specifying a duration in frames to display them).

Refer to each section below for more information and the Paper 2D map inside the Content Examples project for additional examples:

Starting Out



Description of Paper 2D Flipbooks and how to create them.



Importing assets from third party applications for use with Paper 2D.



Description of Sprites in Unreal Engine and how to create them.



Overview of how to create Tile Sets and Tile Maps for use within Paper 2D.

Guides

Flipbook Components

Paper 2D Sprites

Materials

Textures



Creating a Flipbook

Blank Flipbooks

Auto-Generated Flipbooks

The best way to think of Paper 2D Flipbooks (or Flipbooks for short) is in the form of hand-drawn animation, where a series of images that are slightly different are "flipped" through to produce what appears to be motion. In Unreal Engine, Flipbooks consist of a series of keyframes, each of which contains a Sprite to be displayed and a duration (in frames) to display it. A Frames Per Second option determines how fast the frames will be displayed, indicating how many animation "beats" will occur in a second and the keyframes themselves can be edited in the Details panel or by using a Timeline which can be found at the bottom of the Flipbook Editor.

Creating a Flipbook

There are a couple of ways you can go about creating a Flipbook. You can either create a blank Flipbook that you populate with sprites yourself or you can auto-generate a Flipbook based off a series of selected sprites.

You can import a JSON-formatted sprite sheet description, which will import associated textures and create sprites and a Flipbook for the described frames as well. See Paper 2D Import Options for more information.

Blank Flipbooks

Creating a blank Flipbook can be achieved by following the steps below.

From the Content Drawer:

Click the +Add button, then in the context menu under Animation, select the Paper Flipbook option.



You can also Right-click inside the Content Drawer to open the context menu instead of clicking Add New.

You will then be prompted to enter a name for your new Flipbook.



After you select a name, your Flipbook asset has been created.



The asterisk symbol in the lower-left corner indicates that the asset has not been saved yet and will go away when you save it.

Auto-Generated Flipbooks

To create an automatically generated Flipbook, follow the steps below.

From the Content Drawer:

Locate and select each of the sprites you would like to include in the Flipbook in the Content Drawer.



Right-click on any of the sprites, then select the Create Flipbook option from the context menu.



You will then be prompted to enter a name for your new Flipbook.



After you select a name, your Flipbook asset has been created.



When you mouse over the Flipbook in the Content Drawer, you will also be able to preview the Flipbook animation.

When auto-generating a Flipbook, the naming convention you use for the sprites included is very important as the sprites will be added to the Flipbook in alphabetical order. In the example above, we've named each of our sprites for creating an Idle to Idle_x where X is the order in which we want the sequence to appear.

Setup

Flipbook Components are regular primitive components, and can be posed arbitrarily in 3D, attached to other components, or have other components attached to them. Each Flipbook Component instance can specify a custom color that will be passed down to the Flipbook Material as a Vertex Color. They can also have a custom Material specified that will override the default Material defined in the Flipbook.

You can change the current Flipbook asset by calling SetFlipbook, but note that this will only work if the Mobility property is set to Moveable (or if it is called during the construction of the Actor). You can also control play rate, play direction, looping, etc. with various other methods on the component.

While C++ documentation for working with Flipbook Components is still in development, you can refer to UPaperFlipbookComponentUPaperFlipbookComponent for more information on using them in your code until more detailed documentation comes online.

Setup

To learn more about Flipbook Components using Blueprints, follow the link below:

Paper 2D Flipbooks

Paper 2D Sprites

Paper 2D Flipbooks

The Paper 2D - How-to pages provide short step-by-step examples of ways to accomplish certain tasks within Paper 2D in Unreal Engine. While there may be other ways to accomplish these tasks, these samples should get you started and give you ideas on how you may want to approach your objectives.

Refer to the table below for more information and click each link to view its contents.

How To...

Description

Applying 2D Physics

Examples of implementing physics for 2D games.

Using Sprite Sockets

How to attach objects to sockets defined in a Paper 2D Sprite.

Top Down 2D Game Setup

How to quickly set up a top down 2D game with a playable character.

Setting up an Animation State Machine

How to set up and play different animations for a 2D character based on different states.

Top Down 2D Game Setup

Paper 2D Sprites

Paper 2D Flipbooks

State Machines

State Machines

Variable Setup

Update Animation Setup

Animation State Machine Function

Finishing Update Animation Event

On this page you will learn how to set up an Animation State machine for a 2D character which will allow the character to cycle between different Flipbook animations based on your defined criteria.

This tutorial assumes you have a Paper 2D character that is already set up for movement and have some Flipbook animations that you want the character to switch between. If you do not have a character or Flipbook animations, see the Paper 2D Top Down Tutorial for information on setting up a Paper 2D character and applying movement as well as a link to the sample assets used in this tutorial.

With your project open and Paper 2D character ready to go, follow the steps below.

Variable Setup

Inside your project, open your Paper 2D Character Blueprint (TopDownCharacter in our example).

In the My Blueprint window, click the Add Variable button to create a Bool variable and name it IsMoving?.



Create and name another variable based on one of your Flipbook animations (such as Idle) and set it to a Paper Flipbook type.



Depending upon the type of game you are making, you may have different animations. Most character based games, have a state where the character is idle (or resting and not moving).

Click Compile then set the default value of the variable to its corresponding Flipbook asset.



Above we have assigned our Idle Flipbook animation to our IdleFlipbook variable.

(Optional) For the sake of clarity, you may also want to put the variable in a Category called Animations.



You can type in the name of the category you would like and will keep things organized for you.

Repeat the previous two steps for each of the animations that you want your character to be able to play.



Above we have created another Paper Flipbook variable called RunFlipbook, clicked Compile then set the Default Value for that variable to our corresponding Run Flipbook animation. While our example only has the two animations, you could have one for a death animation, another for reloading a gun (if they have one) or a melee attack, another for picking up or using items, etc.

Once you have added variables for each of our Flipbook animation states, proceed to the next section.

Update Animation Setup

Next we will create some script to handle the updating of our Animation state.

Right-click inside the Event Graph and search for and add a Custom Event.



Call the Custom Event something to the effect of UpdateAnimation.

Right-click in the graph again and add a Get Velocity node, then drag off the return value and add the Vector Length node.



We can use the Vector Length of Velocity to determine if our character is moving or not.

Off the return value of the Vector Length, add a > node then drag-and-drop the IsMoving? variable onto the Bool return to set it.



Animation State Machine Function

Here we will create a function that will handle the checking of which state we are in and output a corresponding Flipbook animation to use.

In the My Blueprint window, create a new Function called Anim State Machine.



In the Details panel of the function, add an Input Boolean called IsMoving? and an Output Paper Flipbook called Output Flipbook.



Our function will take in the value of our variable also called IsMoving? to check if we are moving and use that as a test case to determine what state we are in (moving or not). Our function will then output an Output Flipbook which we will set our sprite to use in a moment.

Connect a Branch node off the input executable pin of the function.



The first thing that occurs when this function is called is run a True/False check against our IsMoving? variable.

Back inside the Content Browser, Right-click and under Blueprints create an Enumeration and call it Animation State.



We are using an Enumeration to create a list of all our animation states that our character can be in which we can then select from.

Open the Enumeration, then add a state for each of the animations that your character will enter.



For example, we only have Idle and Run however you may have many more depending upon the animations you plan to use.

Return to your Paper 2D Character Blueprint and create a new variable called AnimationState set to the Enum Animation State.



Inside the Anim State Machine function, hold Alt and drag in the AnimationState variable to set it.

Drag in another AnimationState variable and connect each to the True and False pins of the Branch node.



For the Enum connected to True, set the state to Run and set the other Enum to Idle. We are saying if IsMoving? is true set our Enum state to Run and if we are not moving set it to Idle. While our example only checks whether we are moving or not, you could add different Branch nodes to check different criteria based on your needs.

One thing to note is that the order in which you process your checking is important and you'll want to prioritize certain states over others. For example, if we had a death Flipbook animation for our character would probably want to process that first and check if the character is dead and if so, we would want to play the death animation and kill the character. If they are not dead, then we can proceed on to the next series of checks (if the character is moving, attacking, using an item, etc. with the final check being if the character is not doing anything at all resulting in the Idle pose.

See the Animation State Machine section of the Paper 2D video tutorial series for more information.

Hold Ctrl and drag in the IdleFlipbook, RunFlipbook and Animation State variables, then Right-click and add a Select node.



For this section, you will need to drag in each of your animation variables into the graph.

Connect each of the nodes so the function is complete and looks similar to below.



Our function now checks if we are moving and if so, sets our Enum state to Run (Idle if we are not moving). We then use a Select node to get our Animation State from our Enum and based on the state assigns the corresponding Flipbook as the Output Flipbook to use.

Finishing Update Animation Event

Now that our function is complete, we will call it as part of our Update Animation Event and finish off the remaining script.

On the Event Graph in the My Blueprint window, choose to Show Inherited Variables then hold Ctrl and drag in your Sprite.



Drag in the Anim State Machine function and connect it to the Set Is Moving? node, then off your Sprite add a Set Flipbook node.



Connect all of your nodes together for the UpdateAnimation custom event as shown below.



Following the Add Movement Input node from your MoveForward Event, call the Update Animation custom event.



Compile and Save then play in the editor.

You will now have a character that cycles between the two states based on your condition of whether or not the character is moving.

As mentioned, in order to add additional animation states to this setup you would need to:

Have Flipbook Animations for each of the animation states you want your character to enter.

Add and set them as Flipbook variables inside your Paper 2D Character Blueprint.

Add each of the states to the Animation State Enumeration we created.

Create conditions that determine when the character can enter each state and add it to the Anim State Machine function.

Connect each of your Flipbook variables to the Select node inside the Anim State Machine function.

Paper 2D Sprites

Paper 2D Flipbooks

This page provides an example of applying physics to sprites in 2D games.

For this example we are using a 2D Side Scroller Game, however you can apply the same concepts to any 2D game.

When using physics in any 2D style game, typically you'll want to apply some constraints to your sprite when physics are applied to prevent the sprite from moving or rotating in such a way that the card becomes visible to the player, or even worse, falls out of your game world as seen in the example below.

Above, we have applied physics to a sprite but have not applied any constraints to those physics so our object that falls and applies physics actually tumbles outside of our game world and off screen which is not what we want. We want our physics object to react to the world and player interaction, however we want to keep it inside our level and prevent it from rotating on certain axis so that the sprite is always fully visible.

For our sprite, we can apply constraints from the Details panel in addition to applying physics.

Select the Sprite in your level that you want to apply physics to.

In the Details panel, click the Simulate Physics option under Physics.

Expand Constraints and choose the Lock Position (typically to the Y axis for side scrolling games).



While this will apply physics and lock it to only the Y axis, there are additional issues that may occur with just this setting.

Our sprite is now locked to the Y axis, however you can see that it can still rotate freely which may not be what we want.

Also in the Constraints section, choose a Lock Rotation (typically to the X axis for side scrolling games).



Now when physics is applied to the sprite its position is locked to the Y and its rotation is locked at the X.

You can also use the Mode option to constrain movement along a specified axis (in this case XZPlane to achieve the same effect).

Depending upon the type of 2D game you are making, varying settings can be used to restrict how physics are applied to your object.

Paper 2D Sprites

Paper 2D Flipbooks

On this page you will learn how to add sockets to sprites then access those sockets from within a Blueprint which you can attach an object to. You can spawn particle effects from sprite sockets (such as a character on fire), attach a weapon to a character's hand (like a gun or sword) or any number of different items that you want to spawn and attach to a sprite's socket.

For this example we will attach a hat to our character's head.

To add a socket to a sprite:

Locate the sprite you wish to add a socket to and open it.

In the Details panel, click the + next to Sockets to add a new socket.

Enter in a Socket Name and move the socket where you would like using the Local Transform or widget inside the viewport.



To move the socket in the viewport, you may need to zoom in and click on the socket first.

It is important to note the name you give your socket. Above we have created a new socket called HatSocket to which we want to spawn in a 2D hat for our character to wear. The steps above have only covered one sprite, in our idle animation we are using 8 different sprites so we need to add sockets to each of those sprites as well.

A quick way to do this would be to use the Property Matrix.

Add Sockets to Several Sprites:

In the Content Browser, select each of the sprites in your Flipbook animation that you want to apply sockets to.

Right-click on a sprite, then under Asset Actions select Property Matrix...



By opening the Property Matrix we can modify each of these sprites at the same time which will save time.

We also selected the sprite which we already added a socket to for reference so all 8 frames are selected.

Inside the Property Matrix, select each of your sprites (which do not have sockets) then click the + to add sockets to them.



Expand element 0, then under Socket Name name them the same as your first sprite (in our example HatSocket).



Expand Local Transform then Translation and set the XYZ values to the same as your first sprite.



Open up each of the sprites in your animation to ensure that a socket has been added to each.



You may need to adjustment the socket location per sprite to ensure it is at the desired location for that frame.

Now that we have a socket attached to each frame of our Flipbook, we can tell our Blueprint to spawn an Actor at the socket location.

Accessing Sprite Sockets via Blueprint:

Inside our Character Blueprint, in the My Blueprint window click the eye icon and Show Inherited Variables.

Left-click and drag in the Sprite component for your character.



Off an Event Begin Play node, add a Spawn Actor from Class node set to the Actor Class you want.

Use a Make Transform node for the Spawn Transform and off the Return Value use an Attach To node.

Connect your Sprite component as the In Parent and for the In Socket Name enter the Socket you created.



Your setup should look similar to above. For example we are just spawning a Blueprint called Hat_BP which is a Blueprint containing a Sprite Component of a hat that we are attaching to our character at the HatSocket location we've created. The same process we took above for our idle frames, we've done for our run frames so that we end up with a character that wears a hat in our game (as seen below).

Once you Compile and play in the editor, the Actor Class spawned will spawn at the socket location and become attached.

You could add a socket to a sprite and attach any number of different things in that socket, whether or not the sprite is part of a Flipbook and is animated as well as what goes in the socket is entirely up to you.

Setting up an Animation State Machine

Paper 2D Tile Sets / Tile Maps

Camera

Paper 2D Sprites

Paper 2D Flipbooks

Setup Project

Character Setup

Finishing Up

On this page you will learn how to modify the existing Third Person Template project to create a Top Down 2D style game.

You can use your own 2D character with this tutorial or you can download a sample character from the link below:

Sample Assets

Setup Project

Here we will set up our project for this tutorial, you can import your own assets during this section or use the Sample Assets provided.

Create a new Third Person Blueprint template project.

Inside the project, Right-click on the Content folder in the Content Browser and create a New Folder.



Give the folder a name such as TopDown or whatever you would like.

Locate the downloaded Sample Assets and drag the SoldierSprites.paper2dsprites asset into Content Browser.



This will automatically create a SolderSprites Sprite Sheet asset and folders containing Frames and Textures.



For more information on how to set up assets for importing, see the Paper 2D Import Options documentation.

Right-click on the SoldierSprites asset and select create Flipbooks.



This will automatically create two Flipbooks based on the sprite sheet for us.



(Optional) Open the Idle Flipbook and in the details panel set Frames Per Second to 3.0.



Also set the Run Flipbook Frames Per Second to 8.0.



This will slow down the playback speed of both Flipbook Animations.

Our project is now set up and we can begin setting up the Top Down Character.

Character Setup

Here we will create a new Paper 2D Character Blueprint and set up the character.

Right-click in the Content Browser and select to create a new Blueprint Class.



In the Pick Parent Class window, click the All Classes drop down and search for and add the PaperCharacter.



Give the new Blueprint a name such as TopDownCharacter.

Inside the TopDownCharacter Blueprint, in the Components window click the Sprite component.



In the Details panel under Sprite click the Source Flipbook drop down and select the Idle Flipbook.



The character will then be added to the Viewport inside the Capsule Component.



Back inside the Details panel under Transform, set the Rotation to -90,0,90 and Scale to 0.75 for XYZ.



This will rotate the Flipbook into position and scale it down so it fits inside the Collision Capsule.

In the Components window, click the CapsuleComponent then in the Details panel adjust the Shape settings.



This will vary based on the character you are using, we have set both Half Height and Radius to 45.0.

In the Components window, click TopDownCharacter(self) then in the Details panel, un-check Use Controller Rotation Yaw.



For this example we are going to automatically orientate our character to the direction they are moving and not use the controller rotation.

In the Components window, click the CharacterMovement component.

In the Details panel for CharacterMovement, update the Max Walk Speed to 400 and check Orient Rotation to Movement.



This will reduce the characters movement speed and automatically rotate the character based on our movement.

In the Components window, click Add Component and search for and add a Spring Arm component.



Click Add Component again and add a Camera component, then drag the Camera onto the Spring Arm to attach it.



Select the Camera component, then in the Details panel, zero out the Location setting.



Select the Spring Arm then make the following updates in the Details panel.



Here we are adjusting the Rotation of the Spring Arm (and by extension, Camera) to 180, -90, 180 to position the camera directly above the character. We are also adjusting the camera distance away from the character by changing the Target Arm Length to 600. Finally we've unchecked the Inherit options for Pitch, Yaw and Roll as we do not want to inherit settings from the camera.

Click Compile and Save then minimize the Blueprint (we will come back to it in a moment).

The character is setup, however there is no movement script applied to it which we will grab from the Third Person Character Blueprint.

Finishing Up

There is no need to reinvent the wheel here, since this template comes with a character with scripted functionality for movement, we can copy that into our Paper Character to provide movement for it.

For more detailed information on setting up character movement and setting up character movement from a blank project, see the Setting Up Character Movement in Blueprints documentation.

Inside the ThirdPersonBP folder in the Content Browser, open the Blueprints folder then the ThirdPersonCharacter Blueprint.

Inside the Event Graph, copy the Movement Input section by Left Mouse dragging a selection box then pressing Ctrl+C to copy.



There is other script in here for 3D gameplay such as manipulating the camera, controller input and jumping. For the purposes of this tutorial we are only concerned with general movement.

Return to your Paper Character Blueprint and press Ctrl+V in the Event Graph to paste it in.

Also inside the ThirdPersonBP and Blueprints folder, open the ThirdPersonGameMode Blueprint.

Under Classes, change the Default Pawn Class to your Paper Character (TopDownCharacter).



This will set our Paper Character as the default character to use during gameplay.

Inside the level delete the Blue Character so you will not take control of it when launching the game.



From the Main Tool bar, click the Play button to play in the editor.

Although the 2D character is idle, you can now move around the default map using the WASD keys.

This tutorial illustrates how to set up the foundation of a top down game by creating a playable 2D character, there are other tutorials you can take a look at to continue to develop this sample such as the Setting up an Animation State Machine (to set up different Flipbook Animation states for the character to use) as well as the section on Paper 2D Tile Maps to create a 2D map. Want a fixed camera position instead of a follow camera for your top down game? The How to Use Cameras in Blueprints page will show you how to set that up and more.

Paper 2D Sprites

Paper 2D Flipbooks

Paper 2D Tile Sets / Tile Maps

Importing from Texture Packer

Importing from Tiled / Adobe Flash CS6

Paper 2D in Unreal Engine supports a number of different import options for your externally created content. Below are some examples of importing assets from some of the more commonly used content creation applications.

Importing from Texture Packer

If you are using the third party sprite sheet generation tool Texture Packer for content creation, it has a plug-in built into it which will allow you to easily import your content into Unreal Engine by creating a .paper2dsprites file. This file when imported into UE will automatically import your sprite sheet as a texture, extract and create sprites from it as well as create a Sprite Asset which can be used to auto-generate Flipbooks out of your sprites.

Example Workflow

Inside Texture Packer, select the UnrealEngine - Paper2d framework option.



Add your assets that will be included in the sprite sheet.



Under Layout set Size Constraints to POT (Power of 2).

Under Sprites, show advanced and set Border and Shape Padding to 0.



This will eliminate the spaces between your sprites, making it easier to tile them together or create Flipbook animations.

Click the Publish sprite option (this will create a .paper2dsprites file along with a .png sprite sheet)

Drag the .paper2dsprites file into the Content Browser of your project to import it.



The .png file is already included with the .paper2dsprites file so there is no need to import that as well.

This will create a Sprite Sheet asset and two folders Frames (extracted sprites) and Textures (your sprite sheet).



From here you can Right-click on...

Your Sprite Sheet asset to automatically generate Flipbooks based on your sprites.

Your imported texture to adjust its settings, configure it for retro sprites or create a Tile Set based on it.

Your individual frames to manually add them to a Flipbook.

Importing from Tiled / Adobe Flash CS6

If you are building your content in external content generation tools such as Tiled or Adobe Flash CS6, you can import your work into Unreal Engine in the .json file format. This will automatically import the sprite sheet(s) used to create your map and create Tile Sets and a Tile Map based off those assets for you.

Example Workflow for Tiled

Inside Tiled, choose the File/Save As option, then Save as type .json.



Click for full view.

Drag-and-drop the .json asset into the Content Browser of your project.



This will import your sprite sheet textures, create Tile Sets and a Tile Map from those textures.



Opening the Tile Map created, you will see the map constructed externally which can be modified inside Unreal Engine.

Sprite Collision

Paper 2D Sprites

Paper 2D Flipbooks

Materials

Textures



Creating Sprites

Blank Sprite Asset

Single Sprite from Texture

Series of Sprites from Sprite Sheet Texture

Importing from a JSON file

Creating Sprite Materials

Creating Custom Sprite Materials

A Sprite in Paper 2D is a Texture Mapped Planar Mesh and associated Material that can be rendered in the world, created entirely within Unreal Engine. In simpler terms, it's a quick and easy way to draw 2D images in Unreal Engine.

Sprites can also be edited inside Unreal Engine in the Sprite Editor which offers four modes: View for previewing the sprite and general statistics, Edit Source Region which displays the full source texture and allows you to set the area within the source texture that composes the individual sprite, Edit Collision displays and allows editing of the sprite collision shapes, and Edit RenderGeom which displays and allows editing of the sprite render geometry.

Once you have a collection of Sprite assets, you can then begin animating them by creating a Flipbook which sequentially will play through the Sprites added to the Flipbook. See the Flipbook documentation for more information.

Creating Sprites

Sprites are created in the Content Drawer, like other assets. They can be created from scratch as blank assets, generated from other existing assets, or created using imported data.

Blank Sprite Asset

To create a new blank Sprite asset:

Click the +Add button in the Content Drawer, then under Paper2D, select Sprite.



You can also Right-click in the Content Drawer to bring up the same context menu.

Name the new Sprite asset.



The Sprite has been created but has not been saved yet (indicated by the asterisk in the lower-left corner).



Click the Save All button to save the Sprite.

Double-click the new Sprite asset to open it in the Sprite Editor.

In the Details panel, you can assign a Texture to the Sprite asset using the Source Texture property.



See the Sprite Editor Reference documentation for information on working with Sprites in the Sprite Editor.

Single Sprite from Texture

To create a sprite from an existing Texture asset:

In the Content Drawer, Right-click on the Texture asset, then under Sprite Actions choose Create Sprite.



Name the new Sprite asset.



Series of Sprites from Sprite Sheet Texture

To create a series of Sprites from a Sprite Sheet Texture:

In the Content Drawer, Right-click on the Sprite Sheet Texture, then under Sprite Actions choose Extract Sprites.



Individual Sprites will be automatically extracted and added to the Content Drawer.



Importing from a JSON file

Paper 2D includes an importer for JSON formatted sprite sheet descriptions, which can be exported from tools like Adobe Flash CS6 or Texture Packer. It will import any referenced textures and create sprite assets for each sprite. The importer also assumes that all of the sprites are frames of an animation, so it will always create a Flipbook in addition to the individual sprites. You can delete the generated flipbook if it is not needed.

See Paper 2D Import Options for more information on Importing Options.

Creating Sprite Materials

The Paper 2D plugin includes a set of basic Materials that sample a Texture and multiply it by the Vertex Color, with Lit and Unlit variations for Opaque, Masked, and Translucent textures. The default Material on Sprites and Flipbooks is Unlit Masked.



Creating Custom Sprite Materials

A custom Sprite Material can be created by duplicating one of the existing ones, or creating a new Material in the Content Drawer. When a Sprite is rendered, the texture defined in a Sprite asset will be piped into any texture parameters named SpriteTexture in the material. The SpriteTextureSampler node in the Material Editor can be placed to do this automatically. Sprite instances will pass in their color as a Vertex Color, but it can be used for anything in the material, not just tinting.

Paper 2D Sprites

Paper 2D Flipbooks

Materials

Textures

Collision Domain

Collision Geometry

2D Collision

Just like other types of geometry, such as Static Meshes, Skeletal Meshes, etc., Sprites can define shapes that are used to calculate collisions with other geometry in the world.



Collision Domain

The method used for calculating collision is defined using the Sprite Collision Domain property. There are three different settings:

Collision Type

Description

None

No collision geometry is generated; use this for purely decorative sprites.

Use 2D Physics

This is an experimental option to generate collision geometry for use with Box2D. See 2D Collision for more information on the current limitations.

Use 3D Physics

Collision geometry will be generated for use with PhysX. The 2D collision geometry defined in the sprite will be extruded using the Collision Thickness units deep in the perpendicular axis to make 3D collision geometry.

Collision Geometry

The Geometry Type setting on collision geometry specifies the type of calculation to use for generating the collision

The following settings are available:

Type

Description

Source Bounding Box

Uses the bounding box of the Source Region

Tight Bounding Box



Shrink Wwrapped

(Experimental

Fully Custom



Diced

Split up into smaller squares, including only no-empty ones in the final geometry.

The Edit Collision mode displays the collision geometry and lets you adjust it in the viewport, automatically setting the mode to fully custom.

The toolbar buttons can be used to add additional polygons or snap vertices to the pixel grid. New vertices can be added by selecting an edge and Shift+clicking and selected vertices can be deleted by pressing Delete.

2D Collision

There is an initial experimental integration of Box2D 2.3.1 and various associated changes to enable 2D physics in the

This is a totally unsupported and undocumented prototype, exercise great caution and do not use in production. The current build only includes precompiled libraries of Box2D for Win32 and Win64, so 2D collision will not work on other platforms. Collision detection and response is automatic when the 2D domain is selected in a sprite, but queries like point traces must be separately enabled in the Physics project settings (bEnable2DPhysics option).

The integration supports collision detection and response (including Unreal collision channels/filtering), rigid body simulation, and ray casts. Non-zero extent queries, sweep tests, and overlap tests are not implemented yet. Things like CharacterMovementComponent and MoveComponent with bSweep=true rely on these sorts of queries and do not work correctly yet.

The long term integration strategy is to make it a first class citizen, where the same techniques and knowledge used in 3D scenes will directly apply to 2D scenes; for example, there'll only be one Overlap event, not a separate 2D and 3D

3D raycasts are already implemented for Box2D and you can both trace 'in-plane' (gameplay traces within the 2D 'world') or 'perpendicular to plane' (things like the Touch input trace to determine the object under your finger / mouse cursor), providing a proper hit result location and normal as well.

Sprite Collision

Paper 2D Flipbooks

Materials

Textures

The features on this page are currently in the experimental stage and as such, some aspects may not yet be fully supported.

Creating Tile Sets

Tile Set Editor

Creating Tile Maps

Tile Map Editor

Example Tile Map Workflow

Tile Sets and Tile Maps within Paper 2D, provide a quick and easy way to layout the framework or "general layout" of your 2D levels. By creating and using a Tile Set (a collection of tiles pulled from a texture) with a Tile map (a 2D grid with a defined width and height in tiles), you can select various tiles to "paint" onto the Tile Map which can be used for your level layout. You can also paint tiles on multiple layers, each of which can specify which tile should appear in each cell of the map for that particular layer.

Creating Tile Sets

You can create Tile Sets inside the Content Browser, similar to other assets. They can be created from scratch as blank assets or generated from other existing assets.

Blank Tile Set

To create a new blank Tile Set asset:

Click the button in the Content Browser, then under Miscellaneous, select Tile Set.



Enter in a name for the new Tile Set asset.



Double-click on the asset to open it up in the Tile Set Editor window.



Specify a Tile Sheet texture asset to use inside the Details panel.



Tile Set from Texture

To create a Tile Set from an existing Texture:

In the Content Browser, Right-click on a Texture asset, then under Sprite Actions choose Create Tile Set.



The Tile Set will automatically be created/named based on the Texture you supplied.



You can rename the asset by selecting it and pressing F2 or Right-clicking on it and choosing Rename.

Double-click on the asset to open it up in the Tile Set Editor window.



Tile Set Editor

Once you have created a new Tile Set asset, Double-clicking on the asset will open it in the Tile Set Editor.



Above in the Viewport window (1), you will see the Tile Sheet you've specified to use with your Tile Set. In the Tile Editor window (2), the currently selected tile will be displayed. In the Details panel (3), you can set various settings that will affect the Tile Set or the individual Sprites that make up the set (see Configuring Your Tile Set below).

Configuring Your Tile Set

You will more than likely need to configure your Tile Set to ensure that you are accurately selecting each tile within your sheet.

Inside the Viewport, Left-clicking on your Tile Sheet will display a white tile selection box indicating the currently selected tile.



Right Mouse Button drag inside the Viewport to pan and use the Mouse Wheel to zoom in/out on your Tile Sheet.

Above, the default Tile Width and Tile Height (in pixels) of 32 is being used represented by the white selection box. Unfortunately our tiles are larger than the default values and we want our Tile Width and Height to encompass our entire tile (represented by the yellow box outline).

Inside the Tile Editor preview window the currently selected Tile and its associated Tile Number (see below) are displayed. Just below it, inside the Details panel, you can adjust the Tile Width and Tile Height so that it properly encompasses your entire tile.



In our example, we've increased the Tile Width and Tile Height to 64 to match our tile size.



Click for full view.

In the Viewport, the white tile selection box now fully highlights an individual tile on the Tile Sheet (you may need to experiment with different values depending on how your Tile Sheet is set up). The Tile Editor window also updates to show a single tile from our Tile Sheet that is selected.

In addition to setting Tile Width and Tile Height, you can use the following settings to further adjust your Tile Set from the Details panel.

Setting

Description

Tile Width

The width of a single tile (in pixels).

Tile Height

The height of a single tile (in pixels).

Margin

The amount of padding around the perimeter of the tile sheet (in pixels).

Spacing

The amount of padding between tiles in the tile sheet (in pixels).

Drawing Offset

The drawing offset for tiles from this set (in pixels).

Background Color

The background color displayed in the tile set viewer.

Per Tile Settings / Applying Tile Collision

Also inside the Details panel, you can specify per tile settings (such as applying collision to a particular tile).

To apply collision to a tile:

Select the tile in the viewport (1) then click the type of shape you want to use for collision (2).



The shape will be applied and can be further edited inside the Tile Editor window.



Note the tile number you are editing (green box above), you will need this to apply settings to this particular tile.

In the Details panel under the Sprite section, find the selected tile and change to the desired Geometry Type.



For information on sprite collision types, see the Sprite Collision documentation.

This will set this tile up for collision based on the specified geometry type and shape used. For the collision to actually take effect in-game, when creating your Tile Map you will need to set the Sprite Collision Domain (see below for information on creating/using Tile Maps).

Creating Tile Maps

Tile Maps are created inside the Content Browser and edited inside the Tile Map Editor.

New Tile Map

To create a new Tile Map asset:

Click the button in the Content Browser, then under Miscellaneous, select Tile Map.



Enter in a name for the new Tile Map asset.



Double-click on the asset to open it up in the Tile Map Editor window.



Tile Map Editor

After opening a new Tile Map asset, before you can work within the Tile Map editor you will need to assign an Active Tile Set to work with.

You can specify the Active Tile Set to use inside the Toolbox window by clicking the Selection box.



Then selecting the Tile Set you wish to currently work with.



Any Tile Sets that you have created will be displayed in the window above, allowing you to switch between the "Active Tile Set".

Once you have selected a Tile Set, the viewer will become updated with your selection.



The three windows that comprise the Tile Map Editor are outlined below.



Above in the Toolbox window (1), you can switch between different Tile Sets to use for the creation of your Tile Map. The Tools used to Paint, Erase or Fill tiles on the map are also presented (in addition to options for flipping or rotating the currently selected tile). The bottom section of this window contains the Viewer, which uses the same controls for navigation as the Tile Set viewer (Right Mouse Button drag to pan and Mouse Wheel to zoom in/out).

The center window, the Viewport (2), is used for filling out the Tile Map layout. Using the tools from the Toolbox, you can fill in tiles on the map to create the desired effect by painting, erasing or filling the tiles that comprise your Tile Map. This is where you can "paint" how you want your map to appear in-game.

In the Details panel (3), you can configure how many layers your Tile Map consists of as well as adjust various settings such as the width/height of the Tile Map itself, the width/height of the Tiles that comprise the map, the scaling factor between pixels and Unreal Units, the type of collision to use, etc.

Enabling Collision for your Tile Map

As noted in the Tile Set section, once you've specified which tiles use collision and which do not, you will also need to set your Tile Map to use a collision type. You can do so from the Details panel under the Collision section.



You can set the collision thickness (which is the extrusion thickness of collision geometry when using a 3D collision domain) as well as the Collision Domain itself (which determines if the Tile Map should have collision geometry and participate in the physical world).

The Use 2D Physics option is currently experimental and may not work properly, it is suggested that the Use 3D Physics option be used instead.

When you play in your level, you can check which tiles have collision and which do not with the Show Collision console command.



Above, the upper most ground tiles that the player walks on have collision applied to them while the lower ground and water tiles do not.

Example Tile Map Workflow

Below is an example of a typical workflow for creating a Tile Map.

Open your Tile Map asset.

In the Details panel, set the Map Width and Map Height for your Tile Map.



This is essentially the size you want your map or level to be.

Also set the Tile Width and Tile Height of the individual tiles in your map.



These are usually going to be the same size you defined in your Tile Set.

Assign an Active Tile Set to work with for the construction of your Tile Map.

Also add some additional layers to work with (one for background, one for foreground and one for the playable level geometry).



This is optional, but usually good to have a layer that has your background elements and another for any foreground elements and having your level geometry (the ground, boxes, platforms, etc.) that the player will walk around on placed on a separate layer.

Select a tile in the viewer, then in the map Left-click to paint it onto the map.



You can also select multiple tiles at once and paint multiple tiles in the map by Left-click and dragging over tiles in the viewer.



In the map, you can then paint with the selected tiles.



Continue Painting, Filling or Erasing Tiles on our map to reach your desired layout.



Be sure to enable collision from the Collision section of the Details panel.



You must have specified in your Tile Set which tiles have collision and which do not for collision to take effect.

Drag the Tile Map asset into your level and scale or move based on your needs.



Sound is vital to creating believable and immersive environments. From ambient sounds to interactive sounds of vehicles or weapons, from music cues to spoken dialog, audio in a game can make or break the user experience.

The Audio Engine system in Unreal Engine provides tools and features that offer ways for audio designers and engineers to mold audio to match their visions. This means that a clean version of the sound can be produced once in an external application, imported, then crafted within the engine to create the desired result.

Topics



A collection of topics related to audio analysis and visualization in Unreal Engine.



A collection of topics related to audio debugging in Unreal Engine.



A collection of topics related to Audio Gameplay Volumes in Unreal Engine.



A collection of topics related to audio in Unreal Engine.



A collection of topics related to audio memory management in Unreal Engine.



A collection of topics related to audio mixing in Unreal Engine.



A collection of topics related to external audio control in Unreal Engine.



A collection of topics related to music systems in Unreal Engine.



A collection of topics related to sound sources in Unreal Engine.



A collection of topics related to Soundscape in Unreal Engine.



A collection of topics related to spatialization and sound attenuation in Unreal Engine.



A collection of topics related to submixes in Unreal Engine.



A collection of topics related to Audio Volume Actors in Unreal Engine.



A collection of topics related to reverb in Unreal Engine.

Getting Started

Basic Concepts

Non-Real-Time (NRT) Analyzers

The Audio Synesthesia plugin exposes automatically extracted audio metadata for use in gameplay scripting with Blueprint. This feature helps designers drive animations, effects and other elements that are tightly coupled to sounds.

Getting Started

The Audio Synesthesia plugin must be activated to use this feature. Go to Edit > Plugins > Audio, then check Audio Synesthesia to enable. Restart the engine when prompted.

If you add a new Audio Synesthesia asset, Unreal Engine will automatically create an Audio Analyzer for it. You can add three types of asset:

Audio Synesthesia NRT: An analyzer that supports non-real-time (NRT) analysis of a USoundWave.

Audio Synesthesia NRT Settings: The settings for the Audio Synesthesia NRT that you can use to change settings from the default values.

Synesthesia Settings: The settings for the Audio Synesthesia that you can use to change settings from the default values.



When you create a new asset, a dropdown menu will appear. Select the type of analysis you want to perform.



Basic Concepts

What an AudioSynesthesiaNRT Object does:

Links the analysis algorithm settings to the sound wave being analyzed.

Maintains the results of analysis as a uasset.

Provides Blueprint function access to the results.

All analysis of audio using an AudioSynesthesiaNRT Object is performed in the editor. During gameplay, the results of the analysis are read from a file. This limits AudioSynesthesiaNRT Objects from analyzing audio that is generated in game, but avoids performing costly audio analysis during runtime.

Analysis is performed whenever a setting is updated, or when the sound property is updated in the analyzer.

Example of How the Analyzer Can Be Used

Add an AudioSynesthesiaNRT asset. The AudioSynesthesiaNRT assets are found in Sound > AudioSynesthesiaNRT.

From the dropdown menu of possible AudioSynesthesiaNRT analyzers, choose LoudnessNRT.

Optional: Add an AudioSynesthesiaNRTSettings Object from Sound > AudioSynesthesiaNRTSettings by selecting LoudnessNRTSettings from the dropdown.

Update the LoudnessNRT Sound property with an imported sound.



A LoudnessNRT Settings property updated with previously created LoudnessNRTSettings.

There are many ways to use LoudnessNRT within a Blueprint. Here is an example where two spheres change their sizes in relation to the loudness of the audio that is playing.

Create a new Actor Blueprint and add it to your scene.

Open the Blueprint, then add an AudioComponent and two spheres. In the example shown, the spheres are named LeftSphere and RightSphere.



Add two variables: LoudnessAnalyzer and Duration. Duration should be a float, and LoudnessAnalyzer should be a LoudnessNRT.



In the construction script:

Set the sound of the audio component to be the sound used in the Loudness Analyzer.

Store the overall duration of the sound.



Click for full image.

In the event script:

Set up the AudioPlaybackPercent event to trigger an event every time the audio playback percentage is updated.

Start audio playback.

Get the playback in seconds by multiplying the sound duration by the playback percent.

Retrieve the normalized loudness values from the analyzer at the current playback time in seconds.

Set the scale of the sphere based upon the loudness value.



Click for full image.

Non-Real-Time (NRT) Analyzers

LoudnessNRT

The LoudnessNRT analyzer measures the perceptual loudness of audio. It is similar to an envelope follower or even a decibel meter in that it is related to the amplitude of the audio and provides a number that changes over time. It differs from a straight amplitude measurement by taking into consideration how humans perceive sound and are more or less sensitive to specific frequencies. For example, a whistle can have a fairly low amplitude but still be perceived as relatively loud. Compare that to the lowest of the lowest bass notes, which can have very high amplitude but be deemed only moderately loud by many listeners. The LoudnessNRT takes all this into account, representing the whistle as loud and the bass note as moderate.

LoudnessNRTSettings is used to configure the LoudnessNRT analyzer. The most commonly tuned parameters in the LoudnessNRTSettings are:

AnalysisPeriod controls how often the measurement is taken.

MinimumFrequency and MaximumFrequency control the frequencies of interest. This is useful if you want to completely ignore some content in the upper or lower registers, or if you want to contrast the loudness activity of multiple frequency ranges.

CurveType controls specifically which perceptual curve should be utilized. This is generally an advanced setting.

NoiseFloorDb denotes what amplitude should be considered silence.

ConstantQNRT

The ConstantQNRT analyzer measures the strength of individual bands in audio. It is similar to a spectrogram in that it represents the loudness of a frequency band at a given time, but differs by arranging the bands in a perceptually meaningful way. When using the ConstantQNRT analyzer, the bands are arranged the way notes on a piano or bands in a multi-band equalizer are spaced.

ConstantQNRTSettings is used to configure the ConstantQNRT analyzer. The most commonly tuned parameters in the ConstantQNRTSettings are:

AnalysisPeriod controls how often the measurement is taken.

StartingFrequency, NumBands, and NumBandsPerOctave control the frequency band spacing, width, location and count.

DownMixToMono signifies whether audio channels should be processed separately or mixed down to a single audio channel before processing.

OnsetNRT

The OnsetNRT analyzer detects audio onset events originating from a multitude of sources, including note onsets, percussive hits, speaker plosives, and explosions. The OnsetNRT analyzer provides onsets with both their timestamps and strength.

OnsetNRTSettings is used to configure the OnsetNRT analyzer. The most commonly tuned parameters in the OnsetNRTSettings are:

GranulartiyInSeconds determines the minimum spacing between onsets.

Sensitivity sets the threshold for how loud an onset must be before it is detected.

MinimumFrequency and MaximumFrequency control the frequency range to look for onsets. This is useful if you want to completely ignore some content in the upper or lower registers, or if you want to contrast the onset activity of multiple frequency ranges.

DownMixToMono signifies whether audio channels should be processed separately, or mixed down to a single audio channel before processing.

How to Use the Console

Common Commands and Uses

Audio Console Commands

When debugging games or other projects in Unreal Engine, it can be helpful to send commands to your game or the editor directly while it is running. This is especially true for audio. If you are trying to trace a bug that only occurs in narrow or unknown circumstances, console commands can help by enabling or disabling specific functionalities, or by altering a significant parameter in real time.

How to Use the Console

By default, the Command Console is included in the Bottom Toolbar. It is located at the bottom of the Unreal Editor window. You can jump directly to the Command Console entry field by pressing the tilde key ( ~ ) on the keyboard. Note that on British English keyboards, the key used is the grave key ( ` ).



If the tilde key does not open the console, or if you want to use a different key, you can change your keyboard bindings by going to Project Settings > Engine > Input > Console Keys.

When using the console commands, you may also want to open the Output Log. Click the shortcut located to the left of the Command Console. Pressing the tilde key ( ~ ) twice will open the output log drawer as well. This can be also set at Window > Output Log.

Most audio console commands involve setting a given console variable (CVar) to a desired value, through the syntax <CVar> <Value>.

For example, to debug a sound mix, you would set the CVar au.Debug.SoundMixes to true using the command au.Debug.SoundMixes 1 in the console, where 1 = true.

You can also find more information about the usage of a given CVar by entering the command <CVar> ? or by using the help command.

Commands that you type into the console will affect your editor in real time. Console commands can be executed from within the game, from within the editor, or, if the game has been started, by using the server switch from the server's console.

Common Commands and Uses

With the exception of a handful of older functions, console commands and variables that are audio specific have the au. prefix. Because the console supports autosuggestion, you can get a list of available commands by typing au. in the console and scrolling through the listed commands.

au.Debug.SoundMixes — This variable, when set to 1, provides information on the currently active sound class mixes. As sound mixes are objects that can impact many sounds in the level at once, glitches with them can be hard to trace. By displaying information on sound mixes, it is easy to tell if any unexpected sound mixes are getting triggered, a sound mix is failing to be pushed and popped off the sound mix modifiers list as expected, or multiple instances of the same mix being active simultaneously. This is often a good first step if attempting to debug a situation such as a single class of sounds suddenly becoming inaudible.

au.DumpActiveSounds — When set to 1, this variable provides a list of all sounds currently playing. You can use this to narrow down possible sources of errors for issues that sound identical to the human ear, but have different causes. For example, if a sound can no longer be heard, dumping active sounds can clarify whether it is an issue of a sound not being played or if the sound is playing at an inaudibly low level. Similarly, it can help distinguish between loud sounds that are the result of volume modifiers set to unreasonable volumes, and loud sounds that are the result of multiple instances of the same sound playing simultaneously which you might perceive as one very loud sound.

au.Debug.AudioMemReport — Use this command without additional arguments to generate a detailed document on the memory usage of active sound objects. This is useful for tracking down unexpectedly large amounts of memory usage in the audio system. It is also useful for general audio optimization.

Audio Console Commands

Command

Description

Arguments

au.3dVisualize.ActiveSounds

Sets the visualization mode for active sounds.

0: Disable, 1: Volume (Linear), 2: Volume (dB), 3: Distance, 4: Random Color, 5: Occlusion Volume and Filter Amount

au.3dVisualize.ActiveSounds.Type

Sets the type of sound to visualize.

0: All, 1: Components Only, 2: Non-Components Only

au.3dVisualize.Attenuation

If enabled, visualizes attenuation spheres.

0: Disable, 1: Enable

au.3dVisualize.Enabled

If enabled, activates audio visualization.

0: Disable, 1: Enable

au.3dVisualize.Listeners

If enabled, visualizes listeners.

0: Disable, 1: Enable

au.3dVisualize.SpatialSources

If enabled, visualizes spatialized audio sources.

0: Disable, 1: Enable

au.3dVisualize.VirtualLoops

If enabled, visualizes virtualized loops.

0: Disable, 1: Enable

au.adpcm.ADPCMReadFailureTimeout

Sets the number of ADPCM decode attempts before stopping the Sound Wave altogether.

<Value>: Number of Attempts

au.adpcm.ChanceForIntentionalChunkMiss

If enabled, intentionally drops chunks.

0: Disable, 1: Enable

au.adpcm.DisableSeekForwardOnReadMisses

If enabled, disables forward file scanning when seeks are pending.

0: Disable, 1: Enable

au.adpcm.DisableSeeking

If enabled, disables ADPCM seeking.

0: Disable, 1: Enable

au.adpcm.OnlySeekForwardOneChunk

If enabled, forward seeks stop after failing to load two chunks in a row.

0: Disable, 1: Enable

au.AllowAudioSpatialization

If enabled, spatializes audio. If disabled, sounds will still attenuate.

0: Disable, 1: Enable (Default)

au.AllowReverbForMultichannelSources

If enabled, allows reverb processing for sources with more than 2 channels.

0: Disable, 1: Enable

au.AllowUnsafeAudioMixerToggling

If enabled, allows au.IsUsingAudioMixer to swap out the audio engine (even if in use).

0: Disable, 1: Enable

au.Ambisonics.VirtualIntermediateChannels

If enabled, decodes to a virtual 7.1 speaker configuration before mixdown instead of decoding directly to the output device configuration.

0: Disable, 1: Enable

au.AnalysisTimeShift

Sets a timeline shift (in seconds) for baked analysis playback.

<Value>: Timeline Shift

au.AudioThreadCommand.ExecutionTimeWarningThresholdInMs

Sets a threshold (in milliseconds) to log warnings on commands which took longer to execute.

<Value>: Threshold

au.AudioThreadCommand.LogEveryExecution

If enabled, logs each audio thread command caller and execution time.

0: Disable, 1: Enable

au.BakedAnalysisEnabled

If enabled, queries baked analysis from audio components.

0: Disable, 1: Enable

au.BypassAllSubmixEffects

If enabled, bypasses all submix effects.

0: Disable, 1: Enable

au.BypassAudioPlugins

If enabled, bypasses audio plugin processing.

0: Disable, 1: Enable

au.BypassPlayWhenSilent

If enabled, ignores the Play When Silent flag for non-procedural sources.

0: Disable, 1: Enable

au.ClearMutesAndSolos

Clears any soloed or muted sounds.

N/A

au.CommandBufferFlushWaitTimeMs

Sets the command buffer flush wait time (in milliseconds).

<Value>: Wait Time

au.CommandBufferMaxSizeInMb

Sets the maximum command buffer size (in megabytes) to allow before ignoring additional commands.

<Value>: Buffer Size

au.compression.AsyncCompression

If enabled, compresses Sound Waves (when supported by the codec).

0: Disable, 1: Enable

au.Concurrency.MinVolumeScale

Sets the silent volume threshold for volume scaling (linear).

<Value>: Volume Threshold

au.Debug.Display.X

Sets the X coordinate of the debug text on the viewport.

<Value>: X (Default = 100)

au.Debug.Display.Y

Sets the Y coordinate of the debug text on the viewport.

<Value>: Y (Default = -1)

au.Debug.Generator

If enabled, activates debug sound generation.

0: Disable, 1: Sine Tone, 2: White Noise

au.Debug.Generator.Channel

Sets the channel output index of debug audio. If input is beyond supported channel range, defaults to 0.

<Value>: Channel Index (Left = 0, Right = 1, and so on)

au.Debug.Generator.Freq

Sets the debug sound generation frequency.

0: Disable, 1: Sine Tone, 2: White Noise

au.Debug.PlaySoundCue

Plays a Sound Cue.

-Name: Plays the sound with the specified name (if it is in audio settings).

-Path: Plays the sound at the specified path.

-Radius: (Optional): Radial distance between listener and source.

-Azimuth: (Optional) Azimuth angle between listener and source (in degrees, where 0 is straight ahead, negative to left, positive to right).

-Elevation: (Optional) The elevation between listener and source.

-AllViews: (Optional) Plays through all viewports.

-LogSubtitles: (Optional) Logs the sound's subtitle.

au.Debug.PlaySoundWave

Plays a Sound Wave.

-Name: Plays the sound with the specified name (if it is in audio settings).

-Path: Plays the sound at the specified path.

-Radius: (Optional): Radial distance between listener and source.

-Azimuth: (Optional) Azimuth angle between listener and source (in degrees, where 0 is straight ahead, negative to left, positive to right).

-Elevation: (Optional) The elevation between listener and source.

-AllViews: (Optional) Plays through all viewports.

-LogSubtitles: (Optional) Logs the sound's subtitle.

au.Debug.SoundCues

If enabled, displays Sound Cue information on viewports.

0: Disable

1: Enable

-AllViews: (Optional) Apply changes to all viewports.

au.Debug.SoundCues.Minimal

If enabled, uses the Sound Cue debug compact view.

0: Disable, 1: Enable

au.Debug.Soundcues.ShowDistance

If enabled, displays Sound Cue distances.

0: Disable, 1: Enable

au.Debug.Soundcues.ShowPath

If enabled, displays full Sound Cue paths.

0: Disable, 1: Enable

au.Debug.SoundCues.Spacing.Char

Sets the compact view character size (in pixels).

<Value>: Character Size (Default = 7)

au.Debug.SoundCues.Spacing.Tab

Sets the compact view tab size (in characters).

<Value>: Tab Size (Default = 5)

au.Debug.SoundMixes

If enabled, displays sound mix information on viewports.

0: Disable

1: Enable

-AllViews: (Optional) Apply changes to all viewports.

au.Debug.SoundModulators

If enabled, displays modulation information on viewports.

0: Disable

1: Enable

-AllViews: (Optional) Apply changes to all viewports.

au.Debug.SoundReverb

If enabled, displays reverb information on viewports.

0: Disable

1: Enable

-AllViews: (Optional) Apply changes to all viewports.

au.Debug.Sounds

If enabled, displays sound information on viewports.

0: Disable

1: Enable

-AllViews: (Optional) Apply changes to all viewports.

au.Debug.Sounds.Max

Sets the maximum number of sounds to display in the full sound debugger view.

<Value>: Maximum Number (Default = 32)

au.Debug.Sounds.ShowPath

If enabled, displays full paths of sounds in the debugger list.

0: Disable, 1: Enable

au.Debug.Sounds.Sort

Sets the sound stat sorting attribute.

Class, Distance, Name (Default), Time, Waves, Volume, Priority (Highest of Wave Instances per Sound)

au.Debug.Sounds.TextColor

Sets the body text color in audio debug views.

White, Red, Orange, Yellow, Blue, Magenta, Purple, Black

au.Debug.SoundWaves

If enabled, displays Sound Wave information on viewports.

0: Disable

1: Enable

-AllViews: (Optional) Apply changes to all viewports.

au.Debug.StopSound

Stops debug sound.

-AllViews: (Optional) Stops sound in all viewports.

au.Debug.Streaming

If enabled, displays stream caching information on viewports.

0: Disable

1: Enable

-AllViews: (Optional) Apply changes to all viewports.

au.DecompressionThreshold

If set, overrides the maximum decompression duration (in seconds) in either the sound group or the platform's runtime settings.

<Value>: Maximum Duration

au.DefaultModulationPlugin

Sets the default modulation plugin to load and use (overridden by platform-specific implementation name in config).

<Value>: Plugin Name

au.DisableAppVolume

If enabled, disables external volume changes.

0: Disable, 1: Enable

au.DisableAutomaticPrecache

If enabled, disables precaching on load or startup and will only precache synchronously when playing.

0: Disable (Default), 1: Enable

au.DisableBinauralSpatialization

If enabled, disables binaural spatialization.

0: Disable, 1: Enable

au.DisableDeviceSwap

If enabled, disables device swap handling code for Audio Mixer on Windows.

0: Disable, 1: Enable

au.DisableDistanceAttenuation

If enabled, disables distance attenuation.

0: Disable, 1: Enable

au.DisableEnvelopeFollowing

If enabled, disables envelope follower use for source envelope tracking.

0: Disable, 1: Enable

au.DisableFiltering

If enabled, disables per-source lowpass and highpass filter use.

0: Disable, 1: Enable

au.DisableHPFiltering

If enabled, disables per-source high pass filter use.

0: Disable, 1: Enable

au.DisableLegacyReverb

If enabled, disables reverb on legacy audio backends.

0: Disable, 1: Enable

au.DisableOcclusion

If enabled, disables audio occlusion.

0: Disable, 1: Enable

au.DisableParallelSourceProcessing

If enabled, disables async task use for processing sources.

0: Disable, 1: Enable

au.DisableQuadReverb

If enabled, disables quad reverb in surround.

0: Disable, 1: Enable

au.DisableReverbSubmix

If enabled, disables the reverb submix.

0: Disable, 1: Enable

au.DisableSourceEffects

if enabled, disables source effect use.

0: Disable, 1: Enable

au.DisableStereoSpread

If enabled, ignores the 3D Stereo Spread property in attenuation settings and insteads renders audio from a singular point.

0: Disable, 1: Enable

au.DisableStoppingVoices

If enabled, disables the Stopping Voices feature.

0: Disable, 1: Enable

au.DisableSubmixEffectEQ

If enabled, disables the EQ submix.

0: Disable, 1: Enable (Default)

au.DisableSubmixMutationLock

If enabled, disables the submix mutation lock.

0: Disable (Default), 1: Enable

au.dsp.FFTMethod

Sets the fourier transform method.

0: Iterative Fast Fourier Transform, 1: Discrete Fourier Transform

au.DumpActiveSounds

Outputs data about all currently active sounds to the log.

N/A

au.DumpBakedAnalysisData

Outputs the baked Sound Wave analysis data to a .csv file.

N/A

au.editor.CookOverrideCachingInterval

Sets the maximum latency (in seconds between caching intervals) between a cook override change in the project settings and its application to new audio sources.

<Value>: Maximum Latency

au.editor.ForceAudioNonStreaming

If enabled, forces audio to play non-streaming. This may cause a DDC miss.

0: Disable, 1: Enable

au.EnableBinauralAudioForAllSpatialSounds

If enabled, binaurally renders all spatial sounds (if binaural rendering is available).

0: Disable, 1: Enable

au.EnableDetailedWindowsDeviceLogging

If enabled, logs Windows device details.

0: Disable, 1: Enable

au.EnableOcclusionFilterScale

If enabled, scales occlusion by 0.25f to compensate for change in filter cutoff frequencies in audio mixers.

0: Disable, 1: Enable

au.EnableReverbStereoFlipForQuad

If enabled, flips the stereo for quad reverb when in surround.

0: Disable, 1: Enable

au.ExtraAudioMixerDeviceLogging

If enabled, logs audio mixer devices every 500 callbacks.

0: Disable, 1: Enable

au.ExtraResonanceLogging

If enabled, logs extra information about the Resonance HRTF processing state.

0: Disable, 1: Enable

au.FadeOutTimeoutMSec

Sets the wait time (in milliseconds) for the FadeOut Event to fire.

<Value>: Wait Time

au.FloatArrayMath.ISPC

If enabled, uses ISPC optimizations in audio float array math operations.

0: Disable, 1: Enable

au.FlushAudioRenderCommandsOnSuspend

If enabled, ensures that all pending commands to the audio thread and audio render thread are pumped through on app suspension.

0: Disable, 1: Enable

au.FlushAudioRenderThreadOnGC

If enabled, flushes all pending audio render thread commands every time the garbage collector runs.

0: Disable, 1: Enable

au.FlushCommandBufferOnTimeout

If enabled, flushes the audio render thread synchronously when the fence has timed out.

0: Disable, 1: Enable

au.FocusData.InitializeFocusFactorOnFirstUpdate

If enabled, initializes focus factor on the first update to the proper value, instead of interpolating from 0 to the proper value.

0: Disable, 1: Enable

au.ForceRealtimeDecompression

If enabled, deliberately ensures that all audio assets are decompressed when played, rather than decompressed fully on load.

0: Disable, 1: Enable

au.ForceSyncAudioDecodes

If enabled, disables asynchronous task use for processing sources.

0: Disable, 1: Enable

au.ForceSynchronizedAudioTaskKick

If enabled, forces all audio tasks created in one audio render frame to be queued until they can all be kicked simultaneously at the end of the frame.

0: Disable, 1: Enable

au.IgnoreUserResonanceSubmix

If enabled, bypasses the Resonance Submix Effects project setting.

0: Disable, 1: Enable

au.InteriorData.UseAudioVolumes

If enabled, allows gathering of interior data from Audio Volumes (legacy).

0: Disable, 1: Enable

au.InteriorData.UseIActiveSoundUpdate

If enabled, allows gathering of interior data from subsystems that implement the IActiveSoundUpdate interface.

0: Disable, 1: Enable (Default)

au.IsUsingAudioMixer

If enabled, uses the Audio Mixer. This will only take effect if an audio device is currently not in use, unless au.AllowUnsafeAudioMixerToggling is set to 1. Sounds will stop, and looping sounds will not automatically resume.

0: Disable, 1: Enable

au.LinearGainScalarForFinalOutut

Sets the linear gain scalar to apply to the final float buffer to allow for hotfixable mitigation of clipping.

<Value>: Gain Scalar (Default = 1.0)

au.LogRenderTimes

If enabled, logs audio render times.

0: Disable, 1: Enable

au.LogSubmixAutoDisable

If enabled, logs submix enable and disable states.

0: Disable, 1: Enable

au.MaxConcurrentStreams

If set, overrides the maximum concurrent streams.

<Value > 0>: Maximum Streams

au.MaxRandomBranches

Sets the maximum number of branches to play from for any random node. The other branches will be released from memory.

<Value>: Maximum Branches

au.MaxWorldDistance

Sets the maximum world distance used in audio-related calculations, such as attenuation.

<Value>: Maximum Distance

au.MetaSound.AutoUpdate.NativeClassesOfEqualVersion

If enabled, attempts to auto-update node references to native classes that share a version number if the interface is different. This results in slower graph load times.

0: Disable, 1: Enable (Default)

au.MetaSound.BlockRate

Sets the block rate (blocks per second) for MetaSounds.

<Value>: Block Rate (Default = 100, Minimum = 1, Maximum = 1000)

au.MetaSound.DisableWaveCachePriming

If enabled, disables MetaSound Wave Cache Priming.

0: Disable, 1: Enable (Default)

au.MetaSound.Editor.AsyncRegistrationEnabled

If enabled, registers all MetaSound asset classes asynchronously on Editor load.

0: Disable, 1: Enable (Default)

au.MetaSound.EnableAllVersionsNodeClassCreation

If enabled, creates nodes for major versions of deprecated MetaSound classes in the Editor.

0: Disable (Default), 1: Enable

au.MetaSound.EnableAsyncGeneratorBuilder

If enabled, asynchronously builds FMetaSoundGenerators.

0: Disable, 1: Enable (Default)

au.MetaSound.Frontend.DiscardStreamedRegistryTransactions

If enabled, discards MetaSound registry transactions after streaming.

0: Disable, 1: Enable (Default)

au.MetaSound.Parameter.EnableWarningOnIgnoredParameter

If enabled, logs warnings when parameters sent to a MetaSound are ignored.

0: Disable (Default), 1: Enable

au.MetaSound.WavePlayer.SimulateSeek

If enabled, simulates seek calls by reading and discarding samples for Sound Waves which are not in a seekable format.

0: Disable, 1: Enable

au.MinLogTimeBetweenUnderrunWarnings

Sets the minimum time (in milliseconds) between underrun warnings.

<Value>: Minimum Time (Default = 10000)

au.Modulation.SetPitchRange

Sets the maximum pitch modulation range (in semitones).

<Value>: Range (Default = 96)

au.MultithreadedPatching.PushCallsPerOutputCleanupCheck

Sets the number of push calls (usually corresponding to audio block updates) before checking if an output is ready to be destroyed.

<Value>: Number of Push Calls (Default = 256)

au.NeverMuteNonRealtimeAudioDevices

If enabled, non-realtime audio devices will be exempt from normal audio device muting, such as when a window loses focus.

0: Disable, 1: Enable

au.NumPrecacheFrames

If set, overrides the default value of precache frames for audio buffers.

0: Default, <Value > 0>: Frames to Precache

au.OverrunTimeoutMSec

Sets the wait time (in milliseconds) for the render thread to time out before swapping to the null device.

<Value>: Wait Time

au.Quartz.bAlwaysTakeVoiceSlot

If enabled, takes voice slots immediately without trying to cache the request on the component.

0: Disable, 1: Enable

au.Quartz.HeadlessClockSampleRate

Sets the sample rate for Quartz clocks when no mixer device is present.

<Value>: Sample Rate

au.Quartz.MaxSubscribersToUpdatePerTick

Sets a number of Quartz subscribers to update per tick.

0: No Limit,<Value > 0>: Limit

au.Quartz.SimulateNoAudioDevice

If enabled, QuartzSubsystem assumes no audio devices and runs new clocks in headless mode.

0: Disable, 1: Enable

au.RealtimeDecompressZeroDurationSounds

If enabled, realtime decompresses sounds with a duration of 0.

0: Disable, 1: Enable

au.RecoverRecordingOnShutdown

If enabled, attempts to record to a .wav file if the game is shut down while a recording is in flight.

0: Disable, 1: Enable

au.RecycleThreads

If enabled, reuses threads instead of recreating them.

0: Disable, 1: Enable

au.RenderThreadAffinity

If enabled, overrides audio render thread affinity.

0: Disable, <Value > 0>: Thread Affinity

au.RenderThreadPriority

Sets the audio render thread priority.

0: Normal, 1: Above Normal, 2: Below Normal, 3: Highest (Default), 4: Lowest, 5: Slightly Below Normal, 6: Time Critical

au.ReportAudioDevices

Outputs any active audio devices (instances of the audio engine) currently alive.

N/A

au.resonance.quality

If set, overrides the quality of Resonance sound sources. This will not increase quality levels. The quality used will be the minimum between the Resonance Source Settings and this override.

0: No Quality Override, 1: Stereo Panning, 2: Low, 3: Medium, 4: High

au.Resonance.UsingReverb

If enabled, allows Resonance to query Audio Volumes for reverb effects.

0: Disable, 1: Enable (Default)

au.SetAudioChannelCount

Sets the audio channel count. Maximum value is clamped to the MaxChannelCount.

<Value>: Channel Count

au.SetAudioChannelScaleCount

Sets the audio channel scale count (percentage). Maximum produced value is clamped to the MaxChannelCount.

<Value>: Channel Scale Count

au.SoundDistanceOptimizationLength

Sets the maximum sound duration (in seconds) in order to be a candidate to be culled due to one-shot distance optimization.

<Value>: Maximum Duration (Default = 1.0)

au.SourceFadeMin

Sets the minimum fade length (in samples) to use when a sound source is stopped. The value must be divisible by 4. This is ignored for some procedural source types.

<Value>: Fade Length (Default = 512, Minimum = 4)

au.spatialization.ListAvailableSpatialPlugins

Outputs the list of available spatialization plugins.

N/A

au.spatialization.SetCurrentSpatialPlugin

Sets the current spatialization plugin.

<Value>: Spatialization Plugin

au.SpoofFailedStreamChunkLoad

If enabled, treats incoming streaming chunks as if they had failed to load.

0: Disable, 1: Enable

au.streamcache.BlockOnChunkLoadCompletion

If enabled, attempts to synchronously load chunks after a Sound Wave request has finished.

0: Disable, 1: Enable

au.streamcache.DisableRetaining

If enabled, disables retaining chunks of Sound Waves own audio.

0: Disable, 1: Enable

au.streamcache.DispatchToGameThreadOnChunkRequest

If enabled, dispatches a callback to the game thread whenever a Sound Wave request has finished, instead of capturing the audio chunk once it is loaded. This may cause audio chunks to be evicted before they are needed.

0: Disable, 1: Enable

au.streamcache.priming.BypassRetainFromSoundCues

If enabled, ignores loading behavior of Sound Classes set on Sound Cues directly.

0: Disable, 1: Enable

au.streamcache.priming.PrimeDelayNodes

If enabled, loads sounds into cache when a delay node is hit.

0: Disable, 1: Enable

au.streamcache.priming.PrimeRandomNodes

If enabled, loads sounds into cache when a random node is hit.

0: Disable, 1: Enable

au.streamcache.SoundWaveDefaultLoadingBehavior

Sets the default Sound Wave loading behavior.

0: Load on Demand (Default), 1: Retain Audio on Load, 2: Prime Audio on Load

au.streamcaching.AlwaysLogCacheMisses

If enabled, all cache misses will be added to the au.Debug.AudioMemReport. If disabled, cache misses will not be logged until au.streamcaching.StartProfiling is called.

0: Disable, 1: Enable

au.streamcaching.BlockForPendingLoadOnCacheOverflow

Sets the default request priority for audio chunks that are about to play but aren't in the cache on cache overflow.

0: Clear Sound Wave Retainers, 1: Cancel In-Flight Loads

au.streamcaching.ChunkSlotNumScalar

Sets the number (scalar) of chunk slots to pre-allocate.

<Value>: Chunk Slot Scalar (Minimum = 1.0)

au.streamcaching.DebugView

If enabled, compares FObjectKeys when comparing Stream Cache Chunk Keys. This avoids FName collisions if Sound Waves have the same name.

0: Disable (Legacy), 1: Enable (Default), 2: Averaged View, 3: Detailed View

au.streamcaching.EnableExhaustiveCacheSearches

If enabled, linearly searches cache in FindElementForKey. If disabled, relies on chunk offset.

0: Disable, 1: Enable

au.streamcaching.EnableTrimmingRetainedAudio

If enabled, trims retained audio when the stream cache goes over the memory limit.

0: Disable, 1: Enable

au.streamcaching.FlushAudioCache

If enabled, flushes any non-retained audio from the cache.

0: Disable, 1: Enable

au.streamcaching.ForceBlockForLoad

If enabled, blocks getting loaded chunks until the disk read is complete.

0: Disable, 1: Enable

au.streamcaching.KeepCacheMissBufferOnFlush

If enabled, maintains a buffer of recorded cache misses after calling au.Debug.AudioMemReport.

0: Disable, 1: Enable

au.streamcaching.MaxCachesToDisplay

Sets the maximum amount of stream chunks to display on screen.

<Value>: Number of Stream Chunks

au.streamcaching.MemoryLimitTrimPercentage

Sets the memory cache trim percentage of each trim call when the stream cache goes over the memory limit.

<Value>: Trim Percentage

au.streamcaching.MinimumCacheUsage

Sets the minimum cache usage percentage to limit chunk eviction. This is helpful to avoid disk I/O when playing lots of small sounds.

0: Limit Chunk Number to Cache Size / Maximum Chunk Size, 0.01 - 0.99: Usage Percentage

au.streamcaching.NumSoundWavesToClearOnCacheOverflow

Sets the number of Sound Waves to release on cache overflow.

0: Retain Sounds on Cache Overflow, <Value > 0>: Number of Sounds to Release

au.streamcaching.PlaybackRequestPriority

Sets the default request priority for audio chunks that are about to play but are not in the cache.

0: High, 1: Normal, 2: Below Normal, 3: Low, 4: Minimum

au.streamcaching.PrimeSoundOnAudioComponents

If enabled, automatically primes a Sound Base when an Audio Component is spawned with that sound, or when an Audio Component's sound is set.

0: Disable, 1: Enable

au.streamcaching.ReadRequestPriority

Sets the default read request priority for audio chunks.

0: High, 1: Normal, 2: Below Normal, 3: Low, 4: Minimum

au.streamcaching.ResizeAudioCacheTo

Sets the audio stream cache size (in megabytes). Audio chunks will be culled if necessary to shrink to or maintain the new size.

<Value>: Cache Size

au.streamcaching.SaveAudiomemReportOnCacheOverflow

If enabled, an audio memory report prints if the cache overflows.

0: Disable, 1: Enable

au.streamcaching.SearchUsingChunkArray

If enabled, uses Chunk Pool (TArray) for exhaustive cache searches instead of LRU (Linked List).

0: Disable, 1: Enable

au.streamcaching.StartProfiling

Starts a performance-intensive profiling mode for this streaming manager. Output profile stats with au.Debug.AudioMemReport.

N/A

au.streamcaching.StopProfiling

Stops the au.streamcaching.StartProfiling command.

N/A

au.streamcaching.StreamCacheSizeOverrideMB

Sets a cache size override (in megabytes) instead of using the project settings.

<Value>: Cache Size

au.streamcaching.TrimCacheWhenOverBudget

If set, calls TrimMemory to stay in budget.

0: Disable, 1: Enable

au.submix.clearbrokensubmixassets

If set, verifies submix children are still children and clears previous parent listings from former children.

0: Disable, 1: Enable

au.Submix.Effects.DynamicsProcessor.Bypass

If enabled, bypasses all active submix dynamics processors.

0: Disable, 1: Enable

au.ThreadedSwapDebugExtraTime

If enabled, simulates a slow device swap by adding additional time to the swap task.

0: Disable, 1: Enable

au.UnderrunTimeoutMSec

Sets the render thread wait time to generate the next buffer before submitting an underrun buffer.

<Value>: Wait Time (ms)

au.UseCachedDeviceInfoCache

If enabled, uses the DeviceCache instead of the OS cache.

0: Disable, 1: Enable

au.UseListenerOverrideForSpread

If enabled, zero overrides attenuation distance for stereo panning instead of using actual distance.

0: Disable, 1: Enable

au.VirtualLoops.Enabled

If enabled, supports virtualization for audio loops.

0: Disable, 1: Enable

au.VirtualLoops.ForceUpdateListenerMoveDistance

Sets the distance threshold required to force an update on virtualized sounds to check for listener movement in a single frame over the given distance, measured in Unreal Units (UU).

<Value>: Distance (Default = 2500)

au.VirtualLoops.PerfDistance

Sets the virtual loop distance to scale update rate between minimum and beyond maximum audible distance of sound.

<Value>: Distance (Default = 15000.0)

au.VirtualLoops.UpdateRate.Max

Sets the maximum rate to check if sound becomes audible again (at beyond sound's maximum audible distance + performance scaling distance).

<Value>: Rate (Default = 3.0)

au.VirtualLoops.UpdateRate.Min

Sets the minimum rate to check if sound becomes audible again (at sound's maximum audible distance).

<Value>: Rate (Default = 0.1)

au.voip.AlwaysPlayVoiceComponent

If enabled, guarantees VOIP components won't get deprioritized and killed by setting their priority higher than all other audio sources.

0: Disable, 1: Enable

au.vorbis.ReadFailiureTimeout

If enabled, bails on decoding Ogg Vorbis audio after several unsuccessful decoding attempts.

0: Disable, 1: Enable

au.WaitForSoundWaveToLoad

If enabled, refuses to play any sound unless the Sound Wave has been loaded.

0: Disable, 1: Enable

au.WorldlessGetAudioTimeBehavior

Sets the return value of GetAudioTime when an audio component doesn't belong to a World.

0: 0.0 (Default), 1: Application's Current Time

Audio Gameplay Volumes

Extensible

Component-Based Architecture

Improved Integration

Improved Workflow

Improved Performance

Proxy Functionality



Audio Gameplay Volumes

The Audio Gameplay Volumes system is the next-generation approach to area-based sound processing, which allows sound designers to define physical regions that apply effects to sounds, relative to the listener's position.

For example, you can add reverb while the listener is inside a specific room to simulate sound waves bouncing within the space, or apply a low pass filter to sounds outside of a room to simulate the wall's muffling effect.

The legacy Audio Volume system can present challenges to audio designers, as each Audio Volume's functionality is fixed at runtime and cannot be extended without modifying engine code. Furthermore, all of the possible settings are provided on each Audio Volume and that can be cumbersome when often only a subset of the options available are needed. This system can also present a workflow challenge as each Audio Volume requires a separate Actor in the Level, which makes the system harder to integrate.

Designed as a replacement for the legacy system, this new approach leverages a plugin and component-based architecture to address many of the challenges of the legacy approach, while providing more flexibility to developers.

Extensible



You can enable or disable the Audio Gameplay Volume plugin based on your project needs. Additionally, you can use the provided C++ API or the Blueprint Interaction Interface to extend functionality with new effects, positional player interactions, and more.

Component-Based Architecture



Audio Gameplay Volumes are designed using a modular component approach. Each component contains a configurable behavior you can add to a Volume individually, or in combination with others, so you can create custom functionality for when a listener enters or exits the volume.

These components provide parity to the functionality found in the legacy Audio Volumes system, but with greater control as each feature set is its own component.

The behavior component types are:

Attenuation: Interpolates the audio's current volume (loudness) to a target volume (loudness). You can configure the effect to apply to sounds inside of the volume while the listener is outside, or the other way around.

Filter: Applies a low pass filter to the audio. You can configure the effect to apply to sounds inside of the volume while the listener is outside, or the other way around.

Reverb: Adds a reverb effect to the audio. When the listener enters the volume, this effect applies to all sounds regardless of whether they are inside or outside of the volume.

Submix Override: Adds a Submix Effect Chain to a Sound Submix. When the listener enters the volume, this effect applies to all sounds regardless of whether they are inside or outside of the volume.

Submix Send: Sends the audio to a Sound Submix. This effect applies to sounds inside of the volume, and can be configured to apply while the listener is either outside or inside.

Each component comes with a Priority value which determines which component is used in cases where the listener is inside multiple volumes that have a valid component of the same type.

Improved Integration



Audio Gameplay Volumes offer deep integration with Blueprints to give audio designers flexibility in how they want to implement the system. You can place volumes directly in a Level as stand-alone Actors, or add them as components to any Actor Blueprint.

You can implement custom collision checks within Blueprint Actors to simulate when a listener enters or exits the volume. In this way, manual location or transformation adjustments within the Level are unnecessary.

Improved Workflow

In many projects, audio implementation tends to happen toward the end of the production cycle. This can make it challenging to implement a robust audio system that works seamlessly with other gameplay features. The Audio Gameplay Volume system takes this into consideration by providing the ability to attach Volume components to any Actor in a Level.

Furthermore, the user interface was streamlined to make it more intuitive for audio designers.

Improved Performance

Volume processing and collision tests were moved out of the game thread and into the audio thread. This results in significant improvements to performance and allows you to extend the system without worrying about thread safety.

Proxy Functionality



In addition to replacing and enhancing the legacy features, the Audio Gameplay Volume system offers new Proxy functionality. With Proxies, system functionality can be leveraged without a traditional Audio Gameplay Volume object.

There are two types of Proxies:

Primitive: Allows any static mesh to be used as a Volume with its own Enter and Exit events.

Condition: Allows functionality use when a particular condition is met without the need for a physical Volume.

Prerequisites

1 - Set Up the Sound Class

2 - Place the Audio Gameplay Volume

3 - Add the Reverb Component

4 - Set Up the Reverb Effect

5 - Play

6 - On Your Own!

Using Audio Gameplay Volumes you can define physical regions that apply effects to sounds, relative to the listener's position.

In this guide, you'll learn how to set up a basic Audio Gameplay Volume with a Reverb component to simulate sound waves bouncing within the space.

Prerequisites

A brand new project created using the First Person Template.



The Audio Gameplay Volumes plugin is disabled by default. To enable it, open the Plugin panel by selecting Edit > Plugins, use the search bar to find the plugin, and then click the corresponding checkbox.



1 - Set Up the Sound Class

Audio Gameplay Volumes require Sound Wave assets as part of a properly set up Sound Class in order to function.

For more information on Sound Classes, see Sound Classes.

The First Person Template has a single Sound Wave asset which plays when you fire the weapon. Using the Content Browser, go to Content/FPWeapon/Audio.

Double-click the FirstPersonTemplateWeaponFire02 Sound Wave to open the Sound Wave Details panel.



Click the dropdown for Sound > Class.



Select Sound Class in the context menu to create a new asset.



Enter a name for the new Sound Class and save it to your Content folder.

Double-click on your new Sound Class to open the Sound Class Details panel.



Enable Routing > Apply Ambient Volumes to allow sounds associated with this Sound Class to be used with Audio Gameplay Volumes.

Input 1.0 for the Submix > Default 2DReverb Send Amount to send 100% of the sound in the Sound Class to the Master Reverb Submix.



Save the Sound Class and Sound Wave assets.

2 - Place the Audio Gameplay Volume

Place an AudioGameplayVolume in your level by using the Place Actors panel or by clicking Quick Add in the Level Editor Toolbar and selecting Volumes > AudioGameplayVolume.



Position the volume in the level so that your character can move into and out of it, such as directly over the BP_Pickup_Rifle.



3 - Add the Reverb Component

Audio Gameplay Volume functionality is driven by components. Each volume may have any number of these components which affect the sounds that happen inside or outside of the volume, relative to the listener. For this example, add a Reverb component to your volume to make the weapon fire sound reverberate while the player is inside it.

With the Audio Gameplay Volume selected, click the Add Component button in the Details panel.



Select the Reverb component under the Audio Gameplay Volume section of the context menu.



Input 1.0 for Reverb > Volume to increase the loudness of the effect.

Input 0.0 for Reverb > Fade Time to apply the effect immediately when entering the volume.



4 - Set Up the Reverb Effect

The Reverb component applies its effect using a Reverb Effect asset, so you'll need to create one.

With the new Reverb component selected, click the dropdown for Reverb > Reverb Effect.



Select Reverb Effect in the context menu to create a new asset.



Enter a name for the new Reverb Effect and save it to your Content folder.

Double-click on your new Reverb Effect to open the Reverb Effect Details panel.



Input 1.0 for Late Reflections > Gain to amplify the signal and make the effect easier to hear.



Save the Reverb Effect asset.

5 - Play

Click the Play Level button in the Level Editor Toolbar.

Move your character into the BP_Pickup_Rifle to pick up the weapon.

Left-click to fire while inside or outside of the volume and listen to the difference in the sound.

6 - On Your Own!

Now that you've finished creating a basic Audio Gameplay Volume, consider taking it even further.

Try adding these other Audio Gameplay Volume component types to a new or existing volume:

Submix Override: Adds a Submix Effect Chain to a Sound Submix. When the listener enters the volume, this effect applies to all sounds regardless of whether they are inside or outside of the volume.

Submix Send: Sends the audio to a Sound Submix. This effect applies to sounds inside of the volume, and can be configured to apply while the listener is either outside or inside.

Attenuation: Interpolates the audio's current volume (loudness) to a target volume (loudness). You can configure the effect to apply to sounds inside of the volume while the listener is outside, or the other way around.

Filter: Applies a low pass filter to the audio. You can configure the effect to apply to sounds inside of the volume while the listener is outside, or the other way around.

You will need at least one sound positioned away from the player to hear the effects of some of the component types, such as Attenuation and Filter. The First Person Template doesn't come with any sounds set up this way by default, so some additional work is required.

There are a lot of ways to do this, but for a simple option, try importing an ambient sound file as a Sound Wave asset and then place it either inside or outside of the volume within the level. See Importing Audio Files for information on how to import audio files.

Legacy Features

Sound Cues

Sound Classes and Sound Mixes

Sound Rendering in UE5

MetaSounds

Audio Modulation

Quartz

Audio Analysis

The Audio Mixer is Unreal Engine's fully-featured, multi-platform audio renderer. This powerful audio engine was first launched in Fortnite and was later added to Unreal Engine 4.24.

Since its initial release, the Audio Mixer has continued to evolve its legacy feature set, and has added next-generation audio rendering features that provide unprecedented control and flexibility to audio designers working on real-time experiences.

This overview covers the current legacy feature set, as well as the next-generation features added to Unreal Engine 5 (UE5).

Legacy Features

The core of the Unreal Engine legacy audio features are Sound Cues, Sound Classes, and Sound Mixes. These features are supported in the new Audio Mixer to facilitate the migration of projects to the new audio engine.

Sound Cues are Unreal Engine's legacy audio objects. Sound Cues are audio parameter graphs from which audio designers can play sound sources and manipulate various parameters, such as volume and pitch.

Sound Cues are not capable of sample-accurate control and do not support the creation of arbitrary digital signal processing algorithms. The workflow is mostly manual, forcing audio designers to create separate Sound Cues for every sound.

Lastly, the inability to handle sample-accurate timing and scheduling of audio causes the creation of procedural sound to become more challenging.

Sound Classes represent a set of static parameters corresponding to specific sounds.

These are used to categorize sounds and apply a consistent set of parameters to the project. Due to their static nature, audio designers will often end up creating many similar Sound Classes to cover all the different use cases needed for a large project. Debugging Sound Classes can also become complex due to inheritance inconsistencies between parameters within Sound Classes, where some take precedence over others.

Sound Mixes provide audio designers the ability to modulate a set of audio parameters dynamically at runtime. This is useful in creating dynamic sounds that react to gameplay events and other conditions. Sound Mixes can also become challenging to debug as audio designers can add complexity by creating multiple instances of the same Sound Mix and combining them with Sound Classes.

Sound Rendering in UE5

Many of the features developed for Audio Mixer expand on the legacy features found in Unreal Engine and address the challenges mentioned above. Other features were newly developed to give Unreal Engine capabilities similar to other professional audio authoring tools.

Unreal Engine 5 introduces MetaSounds, a new high-performance audio system that provides audio designers with complete control over Digital Signal Processing (DSP) graph generation for sound sources. MetaSounds have feature parity with Sound Cues and include next-generation features that empower designers to create immersive audio experiences.

MetaSounds address the issues present in Sound Cues and serve as a replacement for Unreal Engine's default audio objects. Unlike Sound Cues, MetaSounds are fundamentally a Digital Signal Processing (DSP) rendering graph. They provide audio designers the ability to construct arbitrarily-complex procedural audio systems that offer sample-accurate timing and control at the audio-buffer level.

In addition to runtime audio rendering capabilities, MetaSounds support improved workflows for audio designers, including: building MetaSounds through composition (MetaSounds within MetaSounds), templatization support, and dynamic and static asset instancing.

MetaSounds also provide significant performance improvements over Sound Cues and offer a fully extensible API that can be used by third-party plugins.

In Unreal Engine's legacy audio feature set, the Sound Class defines static global parameters and applies them to sounds in groups, and Sound Mixes adjust those parameters dynamically at runtime. These parameters are hardcoded and static which limit their use during gameplay.

Audio Modulation is the evolution of these legacy classes and it liberates the concept of parameter control and modulation to a generic "parameter bus". Anything can be a modulation source and anything can be a modulation destination.

The parameter buses can have any number of modulation sources, including Blueprint classes, modulation mixes, and gameplay code. Modulation destinations are parameters that are being modulated and can be locally mapped from the parameter bus in multiple ways.

Audio Modulation Parameter Buses provide audio designers the ability to define their own parameter groups (Sound Classes) and control them however they want (Sound Mixes).

Quartz is a feature set that brings sample accurate timing of audio events to Blueprints. Quartz handles the complexity of scheduling audio to play at precise times and is designed to support custom interactive and procedural music systems. Quartz also sends precise timing events back to Blueprints to support synchronized gameplay logic and visuals with audio.

Audio Analysis is a set of technologies that offers non-real-time and real-time audio analysis. These tools work with Niagara and Blueprint scripting and will provide integration into Unreal Engine 5's editor for the creation of UX and debug analyzers, as well as runtime audio analysis to drive gameplay and graphics.

Each platform supported by Unreal Engine has an Audio category in its Project Settings menu. This category contains platform-specific options for how your application manages audio, including Audio Mixer settings and compression settings. These values override your global audio settings. Although the Audio settings are written to different config files for each platform, all platforms have the same possible settings.

For most audio settings, if you use a value of 0 or lower, that setting will be ignored in favor of the global audio settings.

These settings are written to each platform's (PlatformName)Engine.ini file alongside all other platform-specific project settings.

Configuring Platform Audio Settings

Click Settings > Project Settings to open the Project Settings window. Go to the Platforms section and click on the name of your target platform. Scroll to the Audio category and expand it to reveal all the platform-specific audio settings.





The following table is a summary of each of these settings.

Setting Name

Description

Audio Mixer Sample Rate

The sample rate at which to run the audio mixer.

Callback Buffer Size

The amount of audio to compute in each audio callback block. Lower values decrease audio latency, but may increase CPU cost.

Number of Buffers to Enqueue

The number of audio buffers to keep enqueued. More buffers increase audio latency, but can compensate for varying availability of threads in the job pool on some platforms.

Max Channels

The maximum number of audio voices for this platform. The value used in your application will be the smaller of the two when comparing this setting and the global setting.

Number of Source Workers

The number of workers available to compute source audio. Sources are evenly divided between workers.

Compression Overrides

A list of audio compression settings that will be overridden for the selected platform. Refer to the Compression Overrides table below for more information.

Cook Overrides

A list of cooking settings overridden for the selected platform. Refer to the Cook Overrides table below for more information.

Spatialization Plugin

Which of the currently-enabled spatialization plugins to use on this platform.

Reverb Plugin

Which of the currently-enabled reverb plugins to use on this platform.

Occlusion Plugin

Which of the currently-enabled occlusion plugins to use on this platform.

Sound Cue Cook Quality

Quality level to cook SoundCues at. If set, all other levels will be stripped by the cooker in favor of this setting.

Compression Overrides

Setting Name

Description

Override Compression Times

If set to true, this will override Sound Groups and use the Duration Threshold to determine whether a sound should be fully decompressed during initial loading.

Duration Threshold

A value measured in seconds. If Override Compression Times is enabled, any sound shorter than the Duration Value will be fully decompressed on load. Otherwise, a segment of the sound is cached at load time, and the rest is decompressed in real time.

Maximum Branches on Random SoundCue nodes

On this platform, SoundCues that use the Random node will preload this number of branches and dispose of any others. This can dramatically cut down on memory usage.

Quality Index for SoundCues

Use the specified quality level at this index to override the quality setting used for SoundCues on this platform.

Cook Overrides

Setting Name

Description

Max Size Per Streaming Chunk (KB)

Determines how compressed audio files are split into chunks when cooking for this platform. The smaller this value is, the more chunks a file will be split into.

Use Stream Caching (Experimental)

Enables use of Audio Stream Caching when cooking projects, which changes how audio is managed in memory. Stream Caching separates compressed audio data from USoundWave files and instead places them at the end of a .pak file, which makes loading audio into memory and releasing it when not in use significantly easier. This can result in audio not immediately playable when a USoundWave is loaded, but it enables use of a large variety of sounds without the risk of overstepping memory boundaries. It also provides a way for audio engineers to load chunks of audio without depending on the state of the audio engine, and provides benefits for mitigating audio latency. For more information about Stream Caching, refer to the Audio Steam Caching documentation.

Resample for Device

When True, resamples Sound Waves according to their Sample Rate Quality. The exact Sample Rates to be used for each member of the Sample Rate Quality Enum can be set in Resampling Quality.

Compression Quality Modifier

Scales all quality settings for this platform. For example, a value of 0.5 will halve the quality settings on all SoundCues.

Stream All Soundwaves Longer Than:

If this is set to any value larger than 0, any SoundWaves longer than this value in seconds will stream directly off the disk.

Stream Caching

Contains the Max Cache Size and Max Chunk Size Override. Refer to the Stream Caching table below for more information.

Resampling Quality

Mapping of which sample rates are used at which sample rate quality levels on this platform. Includes values for Min, Low, Medium, High, and Max.

Stream Caching

Setting Name

Description

Max Cache Size (KB)

Sets the maximum amount of memory in KB used for the cache at any given time. If this is a small value (lower than 8 MB), this will lower the size of individual audio chunks during cooking.

Max Chunk Size override (KB)

Overrides the default max chunk size used when chunking audio for stream caching. This value is ignored if it is 0 or less.

Source Asset Management

Asset Management Tools

Sound Cues

Spatialization and Attenuation

Gameplay Audio API

Game Volume Mixing

Concurrency Management

DSP Effects and Synthesis

Asset Cooking

Debugging and Profiling

The Unreal Audio Engine is a robust audio engine that supports a wide variety of features across all platforms supported by Unreal Engine.

Combined with the power of Blueprints and a new multi-platform audio mixer that enables audio digital signal processing (DSP), procedural synthesis, a customizable submix graph, and a flexible C++ API, the audio engine is fully capable of shipping high-quality audio on any project, and at any scale.

This overview presents a snapshot of various subsystems and features that are utilized to solve high-level audio issues.

Source Asset Management

Overall asset management is straightforward. The guiding principle in asset management is to do things as directly as possible, and handle things automatically whenever possible.

Importing Assets

Unreal Engine supports direct import of audio assets into the Content Browser from the desktop by use of the file import dialog, or by dragging audio assets directly into the browser.

You can import a wide variety of asset types and channel formats (see Importing Audio Files).

Internally, Unreal Engine stores the imported audio file in a 16-bit, uncompressed .wav format.

The UAsset that contains the imported data is called a USoundWave, and it can be played directly from all Unreal Engine audio gameplay APIs. The imported asset can also be previewed in the Content Browser by clicking the Play button on the asset or pressing the spacebar while the asset is selected.



When an audio asset is imported into the Content Browser, the engine stores it in a 16-bit, uncompressed .wav format.

Asset Management Tools

Apart from a well-organized Content Browser folder structure, well-designed bookmarks, and useful general Content Browser tools, audio assets in particular benefit greatly from the Property Matrix tool. To make mass edits to audio assets in Unreal Engine, select the assets you want to edit, then open the Property Matrix tool, where you can make sweeping adjustments on up to hundreds of assets simultaneously.



The Property Matrix tool can be used to make broad changes to assets at the same time.

Sound Cues

In the Unreal Audio Engine, the asset that is the conceptual aggregation of multiple sound assets into an abstract Sound Object is the Sound Cue. It is not literally the sound itself, but the abstract concept of that sound.

A Sound Cue is runtime-evaluated, that is, a bundle of potential—not actual—sound. Each time a Sound Cue plays, it may sound different, depending on the context in which it is used.

Sound Cues are one of the oldest tools in Unreal Engine. The Sound Cue Editor gives sound designers a way to create their own sound-design topologies that translate a simple play-sound event into an arbitrarily complex, nuanced, sound-designed event.

At a high level, Sound Cues support asset randomization, gameplay-driven parameter mapping, custom logic and branching for distance attenuation, volume attenuation, pitch shifting, and a large number of other features.



The Sound Cue Editor provides a way of translating a simple play-sound event into a complex, nuanced, sound-designed event.

Sound Cues can also be built using the Sound Cue Templates plugin, which is a simple C++ interface that sound designers can use to name specific sound cues, graph topologies, and logic to be automatically constructed and used from the Matrix Property Editor and the Content Browser. In this way, a common Sound Cue graph can be defined, and the sound designer can use this to optimize the workflow.

See the Sound Cue Editor for more information.

Spatialization and Attenuation

Spatialization and attenuation in games is important. In the Unreal Audio Engine, you can define custom spatialization and attenuation behavior.



Custom spatialization and attenuation can be done in various ways.

In general, sound and attenuation settings are defined using a Sound Attenuation Settings asset, and hooked up to sounds by sound designers. There are a number of places where sound attenuation can be hooked up:

Directly on sound assets

Within Sound Cues

Overridden in Blueprint

For more information, see Sound Attenuation.

Non-Spatialized Sounds

Non-spatialized sounds are usually referred to as 2D sounds in the context of audio engines. Unreal Audio supports playback of 2D assets by disabling spatialization in the sound's attenuation setting asset, or by not providing a sound attenuation asset. Such 2D sounds are useful for music, UI feedback sounds, and any other number of cases where the position of the listener is static.

Even though a sound asset might be played without a special spatialization method, the asset can contain spatial information that is baked into it.

Multichannel sound sources (such as quad, 5.1, and 7.1 sound sources) are only supported for 2D playback. These are typically used for musical or ambient beds.

Stereo sound sources can be played back in 2D but can also be spatialized.

Spatialized Sounds

By default, when spatialization is enabled by attenuation settings, sounds are spatialized using panning.

Panning is the process of changing the amplitude of a sound in physical output speaker channels based on the angle of that sound relative to the orientation of the listener.

Unreal Audio supports panning for multiple output configurations: stereo, 5.1, and 7.1, and for both mono and stereo source assets.

For stereo assets, there is a stereo-spread parameter that defines the virtual distance between left and right input channels for the source. In this way, the stereo source left and right channels are panned analogously to a mono source, and relative to the listener.

There are two global panning modes that sound designers can configure to use in projects: linear panning and equal-power panning.

Linear panning performs a simple linear crossfade between output channels.

Equal-power panning maintains the power (amplitude squared) between output channels.

Since perception of volume is based on the power of the sound, maintaining equal power for panning results in a more perceptually constant volume pan. Linear panning results in sound appearing louder as it gets closer to the physical speaker location, and quieter when it is between speaker locations.

Unreal Audio also supports spatialization using third-party plugins with a robust and flexible C++ API. Third-party plugins can spatialize sounds however they want, including binaural/HRTF spatialization or ambisonics (soundfield) encoding and decoding. Plugins can provide their own asset settings that can be hooked up to the attenuation setting asset.

Distance Attenuation

Distance-based sound attenuation is also defined in the Sound Attenuation Settings asset. In addition to providing a number of pre-designed functions and shapes for distance-based sound attenuation, sound designers can design their own custom distance-attenuation curves.



Spatialization/Attenuation Orthogonality

One subtle aspect of the Unreal Audio spatialization and attenuation features is that they are treated as orthogonal properties. This means sound designers can choose to attenuate a sound by distance (or source-listener orientation) independent of spatialization, and vice versa.

Spatialization and attenuation settings are defined on the Sound Attenuation Settings asset.



In this image, when the listener is within the non-spatialized radius (represented by the green sphere), the sound bleeds to all channels of the speaker configuration. Outside of the radius, the sound is spatialized as normal.

Distance Filtering

Sound Attenuation settings also have an option for filtering sounds as a function of distance. Separate curves for low-pass and high-pass filters allow sound designers to emulate the effect of air absorption (low-pass filter), or to model frequency-dependent distance attenuation (high-pass filter).

Occlusion

Unreal Audio has an extremely inexpensive default async trace that performs occlusion checks for sounds. The sound attenuation setting has options that allow sound designers to enable occlusion, and to set a variety of parameters for filtering sounds based on whether they are occluded. More advanced occlusion solutions are implemented in third-party plugins utilizing Unreal Audio's Occlusion C++ API.

Listener-Based Attenuation

Sound Attenuation settings also have an option that allows sound designers to write volume attenuation, prioritization scaling, and other effects based on the orientation of the sound relative to the listener. In this way, sounds can become more "in-focus" or "out-of-focus" when they come within view of the listener.

For more information, see Attenuation and Listener Focus.

Distance-Based Reverb Sends

Unreal Audio also supports changing how much audio is sent to the master reverb submix as a function of distance. This mapping is defined similarly to the other distance-based parameter curves.

For more information, see Attenuation Reverb Send.

Gameplay Audio API

Unreal Audio has a simple and flexible gameplay API that allows Blueprint and C++ code to customize the behavior of the audio engine.

PlaySound and SpawnSound Blueprint APIs

There are a number of Blueprint functions that you can use to play sounds from Blueprints and gameplay C++ code, in two general categories:

PlaySound functions: This includes PlaySoundAtLocation, PlaySound2D, PlayDialogue2D, and so on.

SpawnSound functions: This includes SpawnSoundAtLocation, SpawnSound2D, and SpawnSoundAttached.

PlaySound APIs: These play the indicated sound in a fire-and-forget mode. Once the sound is playing, you can't modify its playback from Blueprint, or attach it to objects. This type of playback is useful for simple one-shot types of sounds where you don't need dynamic control.

SpawnSound functions: You can create an audio component to dynamically control parameters on a sound, attach the sound to other actors, and control looping sounds. Audio components are a useful object in Unreal Engine for sounds, and can be used for complex interactive Blueprint systems for audio.

Most Unreal Engine audio systems have associated Blueprint APIs that allow for customization and control from Blueprint. For example, every source and submix DSP effect can be modified and controlled from Blueprint, as can sound mixes and sound classes.

Game Volume Mixing

Game mixing is one of the more challenging aspects of game audio. Unreal Audio provides a number of features for sound designers to use to define and control game mix. There is a wide variety of factors that contribute to the overall volume mix.

Direct Volume Adjustments

Individual assets, such as Sound Cues and Sound Waves, have parameters that provide volume control. Audio components also allow sound volume to be modified from Blueprint. The PlaySound and SpawnSound audio gameplay API makes it possible to select volumes at playback. Sound Cues can modify sound volumes according to dynamic gameplay parameters, or with other Sound Cues graph logic. Asset volume can also be set via a variety of distance attenuation options, including attenuation via listener orientation.

Sound Classes

A Sound Class is an asset that provides a bucket of common settings for assets that share some semantic meaning. One primary motivation for grouping sounds together into a common classification is to control volumes of sounds as a group. Sound Classes are created and modified in a separate Sound Class graph editor. In addition to volume, SoundSound Classes can be used to control other parameters on sounds in a class group.

Sound Mixes

A Sound Mix is an asset type that applies dynamic Sound Class volume and pitch adjusters to Sound Classes. Sound Mixes are the traditional method with games to perform Class-based volume control, including ducking.

Volume ducking is achieved using a Passive Mix Modifier—a mechanism that indirectly applies a mix when a sound plays on a given Sound Class. In this way, a game can, for example, cause ducking on background ambience when a player talks or when a gun shoots.

Sound Parameter Modulation

A newer mixing method to control a game mix is with the audio Parameter Modulation plugin. This plugin generalizes the concept of changing audio parameters through a mix. Sounds can now associate their parameters as modulation destinations of a parameter bus. A parameter bus is an object that allows arbitrary parameter modulation sources to write into the bus. For example, a modulation source could be from a Blueprint, derived from a parameter mix, from some interactive system, or from a parameter modulation oscillator such as an LFO.

Instead of controlling only the volume parameter of a sound, the Parameter Modulation plugin also generalizes the concept of parameter modulation, and allows the same paradigm to control any number of output parameters (such as filter frequency cutoff and pitch modulation).

For more information, see Audio Modulation Overview.

Concurrency Management

An often overlooked aspect of game mixing is the issue of managing sound concurrency—essentially, how many sounds of a given type can play at the same time. Without careful management, it is easy for games to generate a flood of sounds of one type, such as guns and other enemy weapons.

The Unreal Audio Engine provides tools for sound designers to control their concurrency groups via the Sound Concurrency Asset. This asset defines the limit of how many sounds to allow in the group, and what to do once that limit is reached.



Sound concurrency is a way to manage how many sounds of a specific type can play simultaneously.

For example, a sound designer could choose to stop the oldest sound when a new sound comes in, or alternatively, to reject new sounds and continue the ones that are already playing.

Sound Concurrency also allows groups to happen in a chain, where a hierarchy of Concurrency Resolution needs to pass for a sound to play.

For example, footsteps might exist in a concurrency, limiting the total number of footsteps. But that, in turn, could exist in a concurrency group of Foley sounds, and again in turn, might be in a concurrency group of SFX sounds, and so on.

For more information, see Make SoundConcurrencySetting.

Global Polyphony Management and Prioritization

Managing the number of sounds that can play at once in a game is called polyphony management or voice management. The primary cost for an audio engine is decoding and rendering sound sources, so one of the primary tools for reducing CPU cost is limiting the number of sounds that can play at the same time.

In Unreal Engine, this number is set in a project setting that you can change based on the target platform. The number can also be changed dynamically while the game is running, so in situations where performance is bottlenecked or tight, the audio engine can dynamically reduce the number of sound sources to be rendered.

Once the audio engine reaches the number of sounds it can render, it needs to decide which ones to play and which ones to reject or stop. This is done through a combination of the sound's volume total (the final volume of the sound after all stages are accounted for) and the sound's priority. For more information, see Priority.

DSP Effects and Synthesis

The Unreal Audio Engine also features a robust digital signal processing (DSP) effects processing pipeline.

Individual sound sources can specify a DSP effect chain to be applied to individual source instances. Settings for those effects can be changed at runtime in Blueprint, and will support live previewing changes while the Play in Editor (PIE) session runs.

Unreal Audio also has a Submix Graph Editor that allows sound designers to apply DSP effects and perform analysis on mixes of sound sources. You can construct submix effects in submix effect chains. Sound sources can be specified to play on any given submix and to send their audio as send effects to any other submix graph. Any sound source can dynamically route their audio to any submix from a Blueprint. Further, Sound Attenuation Settings support sending audio to submix effects as a function of distance. There is a huge variety of possibilities.

The Unreal Audio Engine is flexible enough to allow canonical master-effect setups like Master EQ, Master Compression, and Master Reverb, while also supporting experimentation and exploration of more custom DSP graphs and routing schemes.

A variety of source and submix effects have been implemented in the Synthesis and DSP Effects plugin, and new effects are always being added. With our growing DSP C++ library in our Signal Processing Module, it is easy to add new effects via the Unreal Audio Engine's DSP and Synthesis C++ API.

With other robust tools and technology in Unreal Engine via automatic property reflection and hot-loading DLLs, Unreal Audio Engine is an ideal place to learn about writing DSP effects, or to serve as a platform for cutting-edge experimentation and research in game audio technology.

Asset Cooking

When cooking for a target platform, assets are compressed using a codec specific to both the platform being targeted and the feature the sound is using. For example, Unreal Engine will automatically encode to hardware-accelerated codecs on platforms where that is supported.

The USoundWave that wraps the imported asset has a quality slider to help cook-time compression schemes in relation to the quality the sound designer is targeting for the given asset. This quality value is interpreted differently, based on the specific codec used for a target platform.

Asset Compression Overrides: Automatic Quality Reduction

Unreal Engine has a wide variety of tools that sound designers and engineers can use to control automatic cook-time down-sampling and quality scale reductions for any given target platform. This allows a project to ship on as wide a variety of platforms as possible, and with as little platform-specific content redesign as possible.

For example, a project that ships on PC could automatically have the asset memory footprint reduced when targeting a mobile platform.

Debugging and Profiling

The Unreal Audio Engine is fully integrated with the rest of Unreal Engine, and so benefits from all other existing profiling tools used to analyze CPU usage and memory. Hooks into LLM (low level memory) tracking are added throughout the Unreal Audio Engine, as well as CSV CPU profiling. Furthermore, the Unreal Insights tool has access to all audio CPU usage.

In addition to comprehensive CPU and memory profiling available to all Unreal Engine developers, there are a variety of debugging tools that can be used to view and analyze audio events as they happen in-game. For example:

To view all playing Sound Wave instances (the objects that are actively generating sound), type stat soundwave in the dev console window.

To view playing Sound Cues, type stat soundcues in the console window.

To visualize playing 3D sounds in your game, type Audio3DVisualize in the console window.

There are also a variety of console variables that can be toggled to enable and disable various components of the audio engine, enable muting and soloing of sounds, and so on. See FAudioDevice for more information on debugging.

Background and Motivation

Audio Rendering

Platform-Level Features: Audio-Rendering APIs

Game-Level Features: Gameplay APIs

The Problems with Platform-Specific Audio Rendering APIs

The Audio Mixer Is the Solution

Why It's Called the Audio Mixer

The Audio Mixer Architecture

The Platform Layer

Buffer Generation

The Audio Mixer Threading Model

Generating Sound Sources

The Submix Graph

The Audio Mixer is a multi-platform audio renderer that lives in its own module. It enables feature parity across all platforms, provides backward compatibility for most legacy audio engine features, and extends Unreal Engine functionality into new domains. This document describes the structure of the Audio Mixer as a whole, and provides a point of reference for deeper discussions.

Background and Motivation

Audio Rendering

Audio rendering is the process by which sound sources are decoded and mixed together, fed to an audio hardware endpoint (called a digital-to-analog converter, or DAC), and ultimately played on one or more speakers. Audio renderers widely vary in their architecture and feature set, but for games, where interactivity and real-time performance characteristics are key, they must support real-time decoding, dynamic consuming and processing of sound parameters, real-time sample-rate conversion, and a wide variety of other audio rendering features, like per-source digital signal processing (DSP) effects, spatialization, submixing, and post-mix DSP effects such as reverb.

Platform-Level Features: Audio-Rendering APIs

Typically, each hardware platform provides at least one full-featured, high-level, audio-rendering, C++ API. Some platforms provide several options. These APIs often provide platform-specific codecs and platform-specific encoder and decoder APIs. Many platforms provide hardware decoders to improve runtime performance. In addition to codecs, platform audio APIs provide all the other features that an audio engine might need, including volume control, pitch control (real-time sample-rate conversion), spatialization, and DSP processing.

Game-Level Features: Gameplay APIs

Game engines write additional functionality on top of these platform-level features. For example, features might hook into a scripting engine (such as Blueprint) or game-specific components and systems (such as audio components, ambient Actors, and audio volumes), or do a lot of work to determine which sounds to actually play (such as Sound Concurrency) and with what parameters (such as Sound Classes, Sound Mixes, and Sound Cues).

The Problems with Platform-Specific Audio Rendering APIs

This paradigm works well when there is a small number of target platforms to support, and when there is a long lead time to ramp up new platforms. However, in the case of Unreal Engine where we support a large number of platforms, juggling differences between each platform-specific API, hunting platform-specific bugs, and striving for platform feature parity can easily dominate the audio engine development time. This is at the cost of writing new runtime features or development tools.

Since feature parity in this paradigm is not possible, feature support matrices need to be authored and maintained to communicate with quality assurance teams and sound designers regarding which features work on which platforms. Related to this, documentation and support is difficult, as not every feature will work on every platform. Mixing a game which is intended to ship on multiple platforms is difficult when not all features work on all platforms, and existing features sound different on different platforms.

Writing new audio rendering-level features needs to be implemented uniquely for every platform—or increase the platform disparity problem. Similarly, any optimization or bug fix either requires duplication, or is isolated to specific platforms.

In most cases, new lower-level features, optimizations, and bug fixes are simply not possible. If a performance issue or known bug exists with a platform API, there is often no recourse to fix it without working with the owner of the platform. Bug fixes often consist of hacks or workarounds. If new features are even possible, they're often relegated to a narrow-platform plugin API, and won't work across platforms.

Implementing the platform-specific audio API on new platforms takes a significant amount of work, and requires a larger development lead time. In some cases, a brand new platform may not even have a full-featured audio API available. In those cases, establishing audio rendering on that platform would be impossible until the platform invested resources into writing their own audio rendering API.

One exciting avenue for any game engine is the ability for third parties to add new features and extensions to Unreal Engine. With a complex constellation of platform APIs and all the various ways they themselves might support plugin extensions,creating a common API that wraps everything is all but impossible.

The Audio Mixer Is the Solution

The solution to all of these issues is a single multi-platform, audio-rendering API—what we call the Audio Mixer. With the Audio Mixer, since there is one common code base for all platforms, feature parity is much more easily achieved. Development time is optimized as programmers are able to implement a new feature once and can expect it to work on all platforms. Testing, documentation, and sound designer implementation and mixing is also simplified. Apart from a subset of unavoidable and specific cases, things will sound the same and behave the same across platforms.

Supporting new platforms is fast—it often takes just a few days and a couple of hundred lines of code. Writing an interface for audio engine plugins becomes not only very doable but a primary avenue for innovation. In addition, fixing bugs and optimizing code benefit all platforms.

There will still remain platform-specific challenges—each platform has different CPU and memory capabilities, or different hardware support options. However, in cases of CPU or memory deficiencies, the Audio Mixer can employ features that automatically reduce CPU load (via feature disablement, quality reductions, and so on) or memory load (memory pruning at cook, automatic downsampling and down-quality encoding). Sound designers and audio programmers can tune the Audio Mixer to hit a given performance and memory target for a given platform.

Why It's Called the Audio Mixer

Another word for audio rendering is audio mixing. Since the word rendering is used almost exclusively in Unreal Engine to refer to graphics, we decided to call the new audio renderer the Audio Mixer. However, this decision has sometimes caused confusion within the audio community and others due to the ambiguity of the word mixing. It can be confused with the operation of volume (loudness) mixing.

The Audio Mixer is essentially doing the same thing that a hardware mixing console does—it adds together sound sources after processing them through a variety of parameters and effects processors, including through submixing and master-effects processors.

The Audio Mixer Architecture

The Platform Layer

The Audio Mixer has a minimal platform-specific API layer. The platform API wraps all the necessary details of accessing audio hardware for our various platforms, and this layer deals with querying hardware capabilities and, where needed, hardware state changes, and sets up the multi-platform Audio Mixer to feed audio to the hardware.

Some platforms require additional code to handle a variety of platform-specific nuances like state interruptions, app suspension, device swapping, and so on; while in other cases, support was added to leverage platform-specific enhancements like hardware-accelerated decoding. In these cases, there can still be a good deal of platform-specific code required. Note that this platform-specific layer is also dealing with some of our remaining platform-specific features in Unreal Engine, like creating runtime decoders for our various codecs.

Buffer Generation

Different platforms have different methods of feeding audio to its hardware. Some platform APIs are designed to push audio to the hardware into a queue, and the client app is responsible for keeping audio queued up. Other APIs are callback-based, and will call into client code when the hardware needs more audio. In both cases, the Audio Mixer employs a multi-buffer scheme that generates future audio buffers while hardware is rendering the current buffer (such as the buffer you are listening to).

If the Audio Mixer takes too long to render the next buffer of audio, and the buffer queue starves (for push APIs), or if there is no audio available when the API calls back (for callback APIs), there will be an audible gap in the playback. This is called an underrun (sometimes called starvation), and should be avoided at all costs as it always sounds very bad. An underrun will cause a sudden discontinuity in the audio stream, and is perceived as a noise-burst—either as a pop for a short underrun, a stutter for short and persistent underruns, or a major drop-out of audio for long-running underruns. The sudden amplitude change can even cause damage to audio receivers or speakers. In most cases, underruns are due to CPU saturation—the Audio Mixer is doing too much work in the time it has. In other cases, it might indicate a blockage in the task graph (for async decoding or synthesis), or some other problem. It's also sometimes difficult to distinguish a click or pop in the audio from an underrun or vice versa.

On the other end of things, it's possible to generate too much audio up front. In these cases, game events will lag further and further from real time, and this is perceived as latency. In extreme cases, this is called an overrun, and is also something to avoid. Real-time audio engines need to find the balance between underrunning and overrunning. Underrunning is avoided at all costs, while overrunning, which is required to some degree to prevent underrunning, needs to be below the threshold of perception.

Finding the right balance can be tricky, and is often platform dependent. To that end, the Audio Mixer is architected to allow sound designers (or audio programmers) to choose, per platform, the size of the audio buffers to render per audio buffer render, and how many buffers to render ahead of the currently audible buffer.

The Audio Mixer Threading Model

The Audio Mixer creates its own thread to do the actual audio rendering. We call this the audio render thread. This thread is distinct from the audio thread, and is the thread that does all the work for DSP source generation and mixing.

The audio thread is the thread that does the work to determine what sounds to play and what their parameters are (processing sound cues, sound classes, sound mixes, attenuation,and so on). The audio thread is largely identical between the Audio Mixer and the legacy platform-specific audio engines. The audio thread currently has some complexities to how it deals with UObject and garbage collection. Since the audio thread has UObjects, it is fenced and halted during garbage collection. During runtime, these UObjects are read-only. However, in the editor, since these UObjects are writable, we don't use the audio thread.

In callback-based platform APIs, there is also a hardware thread that the actual platform hardware callback is made from. This hardware-owned thread callback nearly always pops off the rendered buffer that was queued up from the audio render thread, and does very little actual work.

Finally, the audio engine utilizes async tasks from the task graph for decoding and procedural audio (for example, synthesis) generation.

Generating Sound Sources

The first stage of the audio mixer render itself is source generation. To generate sources, the Audio Mixer receives parameters sent from the game, and from the audio thread, that define what sound sources to play, along with their parameters (such as volume, pitch, and position).

Here we use the word source because the audio generated for that source can be derived either from a compressed audio asset (such as a sound file), procedurally generated (by synthesis, decoded media, VOIP, or microphone capture), or source-derived from other sources mixed together (for example, a source bus). A different method is used to generate the source data for each case.

In the case of encoded sound sources (ogg-vorbis, opus, atrac9, xma2, adpcm, and so on), an asynchronous task is used to decode the audio into uncompressed 32-bit float buffers. This 32-bit float buffer is then sample-rate converted (SRC) from the source's sample rate to the sample rate of the Audio Mixer. This SRC process takes into account any pitch scale that might have also been applied to the sound source, and does the SRC only once.

For example, if a sound source is encoded at 32 kHz and has a pitch scale of 1.2 because the sound designer wants to pitch up the sound source, and if the Audio Mixer is rendering audio at 48 kHz, the SRC will use the following sample-rate ratios:

This means that it will pitch up the sound source by 1.8 after the audio has been decoded.

In the case of procedural sound sources, the audio is generated through an abstract interface that calls back into client code to generate the next 32-bit float buffer. Client code can feed any audio into this callback, and the audio could theoretically be from any source. In UE4, we use this to do real-time synthesis, render audio from media sources (such as play audio from video in 3D, including attenuation, occlusion, or with real-time effects), or play audio from VOIP.

This is also one of the many ways that third-party plugins can extend the audio engine. Procedural sound sources can be defined in a plugin, and source audio can be fed into the Audio Mixer from any other source, including entirely independent sound engines.

The Audio Mixer also has support for mixing sound sources together to create other sources. These mixed sources are called source buses. Source buses are treated like any other source, and support most of the features that other sources have, such as spatialization, distance attenuation, volume mixing, and source-effects processing. There are a number of useful applications for this feature: dynamic routing of sound sources to new spatial locations (such as radio broadcasting), spatialized effects processing (such as location-based reverb processing), and delay-type spatial effects (such as bouncing audio off specific objects in a scene).

Once a sound source has generated its audio, it's output is fed through a chain of audio DSP effects. There are some built-in effects that all sound sources automatically have access to. These DSP effects are a high-pass filter and a low-pass filter, and are used for a variety of higher-level features.

Through the sound-attenuation settings, sound designers can map filter frequency cutoffs of high-pass and low-pass features to apply to individual sound sources as a function of distance from the listener.

Another feature that utilizes this per-source filter is the built-in occlusion system. If occlusion is enabled, when a sound is obstructed behind occluding geometry (determined via async ray traces), it will automatically apply a sound designer-defined low-pass filter. Finally, sound mixes and sound classes can apply per-source, low-pass filtering to sounds.

Beyond the automatic built-in filter effects, sounds can also feed themselves through what is called a source effect chain. This is an asset that defines a sequence of per-source DSP effects that are authored via a source-effect plugin API and can be anything: chorus effects, flangers, delays, advanced filters, ring modulation, bit crushing, and so on.

The Submix Graph

After source generation, the Audio Mixer then processes the submix graph. The output of the submix graph is the audio that is heard on audio hardware.

A master submix is created in the audio engine when the audio engine is initialized. By default, all sound sources are automatically registered to this submix as its base submix if no other submix is specified as the base submix.

A source's base submix is the submix that mixes the source output at full volume (post-attenuation, post-spatialization. Any number of send submixes can also be specified, which allows mixing sources together before sending through auxiliary DSP effects. These send submixes are analogous to auxiliary channels for DSP effects like reverb in a digital audio workstation or mixing console.

As discussed earlier, there is default routing that happens to a sound source that does not specify any submix routing. However, there are two primary means of controlling where the sound source sends its audio to submixes. The first is to specify the base submix. This submix mixes the sound at full-volume. If left blank, it will route the audio to either the EQ submix or the master submix, depending on the legacy features.

In addition to the master submix, two master-effect submixes are created and added as children to this master submix. These are the master reverb submix and the master equalizer (EQ) submix. These master submixes were created primarily for backward compatibility with legacy features in Unreal Engine, and to aid in swapping existing projects to the Audio Mixer. However, they are the underlying mechanisms that support the various higher-level features in Sound Classes, Sound Mixes, Audio Volumes, and Sound Attenuations that interact with reverb and EQ.

The master submix is the root node of the submix graph. The final output is generated by retrieving the audio generated from this master submix.

The output of each submix object is generated by first generating the output of the submix's child submixes, then mixing this output with any sources that have been registered (or sent) to it. The send amount of the registered sound sources are a gain/attenuation on the sources mixed together in the submix.

This mixed buffer is mixed to the output channel configuration for the hardware. For example, for stereo output, this would be a 2-channel audio buffer. For 7.1 audio, it would be an 8-channel audio buffer.

This mixed, interleaved audio is then fed through the submix's DSP effect chain to generate a final output.

Submixes are the ideal object for performing audio analysis. Currently, there is a mechanism to register Blueprint delegates, which retrieves amplitude envelope values from the submix, per channel. This could be useful for a number of visualizations or gameplay systems that want to interact with audio. There is also a real-time FFT delegate to retrieve spectral data from submixes in Blueprint.

Submixes also have a feature to enable recording their output to either a USoundWave object or to a raw PCM (.wav) file to disk.

Finally, there is a C++ delegate that can be registered by other code systems to retrieve the mixed audio from any submix dynamically. This functionality can be used for a number of useful features, like internet broadcasting (for server-based streaming of a game) or third-party plugin extensions.

Working with Audio

Importing Single Audio Files

Multi-Channel Audio Extension Table

Importing Multi-Channel Audio

Verifying Imported Assets



Importing Single Audio Files

Unreal Engine currently imports uncompressed, little endian, 16-bit Wave (WAV) files at any sample rate (although, we recommend sample rates of 44.1 kHz or 22.05 kHz).

In the Content Browser, click the Import button.



Locate and select your .wav file.



Click Open to begin importing the audio file to your project.

After the import progress bar fills up, a sound asset appears inside of the Content Browser, indicating that Unreal Engine has successfully imported the audio file to your project.



The unsaved sound asset is marked with an asterisk, prompting you to click the Save All button.



Once the Save Content dialog box appears, go ahead and click Save Selected to save your imported asset.



After clicking on the Save Selected button, Unreal Engine removes the asterisk, indicating that the audio file has been successfully saved.



Hover over the saved asset inside the Content Browser to view a summary of the sound asset's properties.



Multi-Channel Audio Extension Table

Prior to importing multi-channel audio, it's a good practice to reference the following table when naming your .WAV files.

Extension

4.0

5.1

6.1

7.1

FrontLeft

_fl

✓

✓

✓

✓

FrontRight

_fr

✓

✓

✓

✓

FrontCenter

_fc

✓

✓

✓

LowFrequency

_lf

✓

✓

✓

SideLeft

_sl

✓

✓

✓

✓

SideRight

_sr

✓

✓

✓

✓

BackLeft

_bl

✓

✓

BackRight

_br

✓

The following steps demonstrate a specific use-case for importing a 4.0 surround sound asset into the editor. Refer to our Audio documentation for information on sample rates, audio specifications, and best practices when importing audio into Unreal Engine.

After exporting your multi-channel sound asset, verify that your audio files are named according to the Multi-Channel Audio Extension Table (4.0 example pictured below).



Extension requirements for 5.1, 6.1, and 7.1 channel surround sound are found in the Multi-Channel Audio Extension Table.

Importing Multi-Channel Audio

Exporting a multi-channel sound asset will create a mono .wav file for each channel, following the Multi-Channel Audio Extension naming convention.

In the Content Browser, click the Import button.



Locate and select your .wav files.



Click Open to begin importing the audio files to your project.

After the import progress bar fills up, a four channel sound asset (named "Surround") appears inside of the Content Browser, indicating that Unreal Engine has successfully imported the audio file to your project.



The unsaved sound asset is marked with an asterisk, prompting you to click the Save All button.



Once the Save Content dialog box appears, go ahead and click Save Selected to save your imported asset.



After clicking on the Save Selected button, Unreal Engine removes the asterisk, indicating that the assets have been successfully saved.



Hover over the saved asset inside the Content Browser to view a summary of the sound asset's properties.



Verifying Imported Assets

It's good practice to verify that .uassetfiles were imported properly onto the hard disk.

Inside the editor, right-click the folder with imported files. Under Folder Options, click 'Show In Explorer'.



With Explorer open, verify that Unreal Engine created the corresponding .uasset files for your project.



Determining the Right Cache Size

Configuring the Cache Size

Avoiding Latency by Caching Sounds In Time

Keeping Sounds In Memory

Trimming Memory

Blowing the Cache

Increasing Worst-Case Cache Utilization

Prioritizing Audio Reads

Audio stream caching significantly changes the way audio is loaded and released from memory.

When this feature is enabled at cook time, almost all compressed audio data is separated from the USoundWave asset and placed at the end of the .pak file. This makes it possible for audio to be loaded into memory at any point, and released again when it has not been recently used.

This method of memory management is popular for open world games, where the actual audio needed for a specific use case is difficult to determine ahead of time. The primary disadvantage of this method is that just because USoundWave is loaded, this does not guarantee that the audio will be immediately playable. However, the benefit is a system that lets designers reference as many audio assets as they want without overstepping memory boundaries. The system also provides a way for engineers to load and reference chunks of compressed audio without relying on the state managed by the audio engine. Also, mitigating latency when playing back audio with the stream cache is easier than mitigating memory issues without the stream cache.

Determining the Right Cache Size

The Max Cache Size is a hard limit for memory used by the compressed audio data, with the exception of headers and sounds explicitly marked to stay in memory. When a cache is too small, sounds will be unloaded too quickly, causing latency when loading sounds.

An Extreme Example

If your cache limit is set to 8 MB, chunks are a maximum of 256 KB each, so you could have 32 chunks in your cache at any time. This means that if you are playing 32 sounds at once, no more chunks can be loaded.

A Less Extreme Example

Now assume your cache limit is set to 16 MB. This would allow for 64 256-KB chunks in the cache. If you are playing 32 sounds at once, you have room to prime 32 more sounds. However, if all 32 sounds you are playing are long enough to be in multiple chunks, The next chunk in sequence will stay loaded into the cache automatically. This means that any sounds you try to prime during this time will be stomped by the 32 chunks that are loaded in advance for your 32 playing sounds.

A Normal Example

If your cache limit is set to 32 MB, it can contain 128 elements, each at a max of 256 KB. If you are playing 32 sounds at the same time, you still have 96 additional chunks of audio you can keep in the cache to avoid latency. If your limit is 48 MB, you have room for 192 elements, so even if you play 32 sounds concurrently, you can keep 160 chunks primed.

Configuring the Cache Size

With the project open, from the main menu, select Edit > Project Settings.

From the Project menu, go to Platforms > Windows > Audio > Compression Overrides > CookOverrides > Stream Caching.

Set Max Cache Size (KB) to determine how many elements are in the cache.

When the value is set to 0, the value defaults to 32 KB. The max cache size is 2,147,483,647 MB, but you should be cautious of using a cache size so large that it would cause the machine you are running on to run out of memory.



Avoiding Latency by Caching Sounds In Time

Ideally, sounds are always in memory by the time they play. This can be achieved the following ways.

Priming a Sound for Playback

If you anticipate that a sound is going to play in the near future, you can call Prime Sound For Playback in Blueprints (or UAudioMixerBlueprintLibrary::PrimeSoundForPlayback from C++):



For example, in an open world game, vehicle sounds and radio stations are loaded into the cache when the player comes within a few feet of a car. If the player does not enter the car, the sounds remain in the cache until they are eventually released.

Sound Cues can also be primed, but no delegate fires when loading is complete. (A delegate is a Class that wraps a pointer or reference to an object instance—a member method of that object's Class to be called on that object instance, and that provides a method to trigger that call.)



Setting the Default Loading Behavior for a Sound

If you expect sounds to play shortly after they are loaded, you can set the Loading Behavior of a Sound Wave to Prime on Load:



You can also set the Sound Class Loading Behavior for a Sound Wave to Prime on Load:



Additionally, you can set all Sound Waves to prime on load by setting au.streamcache.DefaultSoundWaveLoadingBehavior to 2.

Keeping Sounds In Memory

If a sound must play with zero latency under any circumstance, it can be useful to keep it in memory for the full duration of the USoundWave life span.

Forcing a Sound Wave to Stay in Memory

When you set the Loading Behavior for a Sound Wave to Retain on Load, you set that sound's first chunk of audio to live in the cache forever.



You can set all Sound Waves to retain their first chunk by default by setting au.streamcache.DefaultSoundWaveLoadingBehavior to 2.

Trimming Memory

If the application requires more memory, you can release unused chunks of audio from the cache using the Trim Audio Cache function (UAudioMixerBlueprintLibrary::TrimAudioCache).



The Trim Audio Cache function iterates through the cache and frees chunks that are not in use until you reach the amount specified by the In Megabytes To Free argument. The function returns memory that was freed successfully.

When called from C++, this function is thread safe. However, keep in mind that it locks the cache, and is potentially expensive. This means that streaming audio may underrun while the function is running.

Blowing the Cache

If you try to load or play a chunk of audio while every element of the cache is in use (either because chunks are playing or are in the process of loading in from disk), you will blow the cache. In this case, this ensures hits in AudioStreamingCache.cpp:



If you are consistently blowing the cache, you have five options:

Increase the size of your cache.

Decrease the amount of Sound Waves you are retaining.

Decrease your voice limit.

Decrease the amount of sounds you are attempting to load when the cache is blown.

Ignore it and drop chunk requests.

Increasing Worst-Case Cache Utilization

For cases where you have many short sounds, the cache will be filled with tiny chunks, and you will only use a small part of your cache size.

For example, if your cache is 128 chunks long and the max chunk size is 256 KB, and you load in a large number of 64-KB sounds, you will only use 8 MB of your cache when the limit is 32 MB.

To compensate for this, you can set your maximum number of chunks to be larger than the MaxCacheSize/MaxChunkSize, keep a running counter of the number of bytes currently allocated in the pool, and evict the least recent chunk, either when that memory counter hits your cache size or when you hit your maximum number of chunks. You determine your maximum number of chunks using the cvar au.streamcaching.MinimumCacheUsage.

Setting au.streamcaching.MinimumCacheUsage

The au.streamcaching.MinimumCacheUsage can be set between 0.0–1.00. This can only be set before the IAudioStreamingManager is initialized. Setting this during gameplay will not affect anything.

Increasing this value increases the maximum number of chunks that can be in the cache. For example, if au.streamcaching.MinimumCacheUsage is 0.75 and your cache size is 32 MB, your maximum number of chunks would be 512. If you loaded in a large number of 64-KB audio assets, you would still be able to use 32 MB. This means that the closer au.streamcaching.MinimumCacheUsage gets to 1, the lower the average size of a chunk is needed to fully utilize the cache.

au.streamcaching.MinimumCacheUsage

Cache Size (Megabytes)

Maximum Number of Chunks

Minimum Average Size of a Chunk in KB for 100% Utilization

0.0

32

128

256

0.0

16

64

256

0.5

32

256

128

0.5

16

128

128

0.75

32

512

64

0.75

16

256

64

0.825

32

1024

32

0.825

16

512

32

We can never guarantee 100% cache utilization for any size of an individual audio asset, because that would require the Maximum Number of Chunks to be infinite.

Increasing au.streamcaching.MinimumCacheUsage has the following implications:

Average case disk IO reads decrease, because you keep more audio cached in the worst case.

Average case memory usage increases, since you can handle more chunks when they are smaller.

Average case CPU cost for finding a chunk in the cache increases.

Costs for insertion/eviction of chunks remain the same.

Using au.streamcaching.TrimCacheWhenOverBudget

The au.streamcaching.TrimCacheWhenOverBudget value defaults to 1. This solves a potential vector for leaked memory in the streaming cache when au.streamcaching.MinimumCacheUsage is set to any value greater than zero. The leak occurs when you evict a small asset for a large asset in the LRU cache. Since this can happen many times in sequence, it results in cache usage that is much larger than your targeted max cache size.

The solution that au.streamcaching.TrimCacheWhenOverBudget uses is to trim your least recently-used chunks until you get back under budget. The trade-off is that calls to prime or play a sound may result in less-recently used sounds being evicted.

Prioritizing Audio Reads

Chunks of audio are read from the disk using instances of IAsyncReadRequest, similarly to your texture streaming and geometry streaming systems. Because of this, you can prioritize audio chunk loading above or below other streaming systems in the engine using the cvar au.streamcaching.ReadRequestPriority. This value can be set from 0 to 4, where 0 is the highest priority and 4 is the lowest. The default value for cached audio streaming requests is 2.

au.streamcaching.ReadRequestPriority

AsyncIOPriority

Other Streaming Managers that use this priority

0

AIOP_High

Animations, Textures, Shader Code

1

AIOP_Normal

Async Pak Reads

2

AIOP_BelowNormal

Geometry Streaming

3

AIOP_Low

4

AIOP_MIN



Import

Single File Import

Multichannel Import

Related

Unreal Engine's audio system provides tools and features to mold the sounds in the game to give them the desired feel. This all starts with your audio source files. Either as mono or stereo files, they can be quickly imported into Unreal Editor and begin breathing more life into your creations. Below are the basic requirements for your audio content and a quick import guide.

Import

The engine currently supports importing uncompressed little endian 16 bit .wav files at any sample rate (although sample rates of 44100 Hz or 22050 Hz are recommended).

Specifications

PCM, ADPCM, DVI ADPCM

Format

.wav

Bit Rate

16

Speaker Channels

Mono, Stereo, 2.1, 4.1, 5.1 6.1, 7.1

Importing with the normal sound factory yields a simple sound node .wav that can be referenced by a sound cue for playback. These sounds can be mono or stereo. Importing with a special naming convention gives the potential of multichannel (e.g. 5.1) sounds. Up to 8 channel sounds can be compressed on all platforms, although not all platforms can play them back efficiently. The package saving process does all the necessary work to convert to the platform's native format. There is no strict speaker mapping, so the number of channels infers which channels are played on which speakers (see table below).

Extension

4.0

5.1

6.1

7.1

FrontLeft

_fl

✓

✓

✓

✓

FrontRight

_fr

✓

✓

✓

✓

FrontCenter

_fc

✓

✓

✓

LowFrequency

_lf

✓

✓

✓

SideLeft

_sl

✓

✓

✓

✓

SideRight

_sr

✓

✓

✓

✓

BackLeft

_bl

✓

✓

BackRight

_br

✓

Compression settings are tweaked to maintain similar quality across platforms. After testing many sounds, our musician determined an XMA quality of 40 was equivalent to an ogg vorbis quality of 0.15.

Single File Import

In the Content Browser:

From the Content Browser, click the Import button (pictured below).



Select the .wav file you wish to import.

Or

Select your sound file in a Windows File Explorer window.

Drag it into the Content Browser in the Unreal Editor.

Multichannel Import

In the Content Browser:

From the Content Browser, click the Import button (pictured below).



Select the files that have the appropriate naming convention that will form your sound asset, such as: Surround_fl.wav, Surround_fr.wav, Surround_sl.wav, Surround_sr.wav.

This will create a four channel asset called "Surround."

Or

Select all your sound files in a Windows File Explorer window.

Drag them into the Content Browser in the Unreal Editor.

Exporting a multi channel sound asset will create a mono .wav file for each channel with the above speaker extension naming convention.

Related





Creating Sound Concurrency Assets

Editing Sound Concurrency Assets

Setting Sound Concurrency Assets

Playing too many sounds at the same time can result in high resource consumption and poor performance. Sound Concurrency assets are one of the primary tools you can use to handle that problem. With a Sound Concurrency asset, you can limit how many sounds play simultaneously and what to do when that limit is reached. You can assign these rules to individual sounds, groups of sounds, or all sounds within a project.

Creating Sound Concurrency Assets



You can create a Sound Concurrency by clicking the Add button in the Content Browser and selecting Sounds > Sound Concurrency.

Editing Sound Concurrency Assets



You can edit the properties of the Sound Concurrency by double-clicking it in the Content Browser, or by right-clicking it and selecting Edit… from the context menu. A Details panel for the asset will appear.

Property

Description

Max Count

The maximum number of concurrently active sounds allowed in this group before the Resolution Rule takes effect.

Limit to Owner

If enabled, limits these concurrency rules to each actor that plays the sound.

Resolution Rule

Sets the behavior to follow when Max Count has been reached:

Prevent New: Prevent any new sounds from starting.

Stop Oldest: Stop the oldest playing sound.

Stop Farthest Then Prevent New: Stop the farthest sound. If all sounds are the same distance, prevent new sounds from starting.

Stop Farthest Then Oldest: Stop the farthest sound. If all sounds are the same distance, stop the oldest sound instead.

Stop Lowest Priority: Stop the lowest priority sound. If all sounds have the same priority, stop the oldest sound instead.

Stop Quietest: Stop the quietest sound.

Stop Lowest Priority Then Prevent New: Stop the lowest priority sound. If all sounds have the same priority, prevent new sounds from starting.

Retrigger Time

The wait time (in seconds) between playing sounds. The sounds rejected by this setting ignore virtualization settings.

All active components count towards Max Count, not just actively playing sounds. This can affect systems that can remain active without playing any audio, such as synthesizers. It can also affect Source Buses as they take up two spots within your Max Count: one for the original source and one for the bus. This is true even if the source is set to Output to Bus Only because it is still an active component.

Property

Description

Can Recover

If enabled, allows volume scaling to recover to its default value after all sounds in the group have stopped playing.

Volume Scale

The scaling factor (ducking) applied to older sounds, which compounds based on the Volume Scale Mode.

Volume Scale Mode

Sets the volume scaling behavior to use based on the attributes of the active sounds in the group:

Default: Scale older sounds more than newer sounds.

Distance: Scale distant sounds more than closer sounds.

Priority: Scale lower priority sounds more than closer sounds.

Duck Time

The time (in seconds) to duck using the Volume Scale.

Recover Time

The time (in seconds) to recover from volume scaling.

To avoid thrashing sounds, Volume Scale is applied after Stop Quietest rules are evaluated.

Property

Description

Voice Steal Release Time

The fade-out time (in seconds) used if a sound is stopped due to another sound in the group starting.

Setting Sound Concurrency Assets



You can set a Sound Concurrency as the default for all sound sources in the Project Settings.

To assign a project default Sound Concurrency:

Go to Edit > Project Settings… to open the Project Settings panel.

On the left side of the panel, click Audio under the Engine heading.

Click the Default Sound Concurrency dropdown and select the Sound Concurrency to use.



You can also set Sound Concurrency assets directly on sound source assets, such as MetaSounds, Sound Cues, and Sound Waves.

To assign a Sound Concurrency to a sound source:

Open the sound source's Details panel.

Find Voice Management > Concurrency > Concurrency Set in the Details panel

Click the Add button to add an index to the Concurrency Set.

Click the dropdown for the new index and select the Sound Concurrency to use.

You can use the same Sound Concurrency across multiple sound source assets. If you do so, the properties and state of the Sound Concurrency are shared between the sources.

You can specify multiple Sound Concurrency assets within a Concurrency Set. The source must fulfill all of the rules in the set before it can play.

If a Concurrency Set has multiple Sound Concurrency assets with fulfilled rules that stop active sounds, one sound per group will be stopped to make room for the new sound.



You can also enable the Override Concurrency option and use the properties under Concurrency Overrides to specify behavior for an individual sound asset without creating a Sound Concurrency asset.

Enabling Audio Modulation

Modulation Values

Modulation Parameters

Modulation Destinations

Modulator Sources and Mix Stages

Creating Custom Generators

Modulation Patches (USoundModulationPatch)

Control Bus Mix (USoundControlBusMix)

Modulator Activation

Blueprint API

The Audio Modulation system provides control over common floating-point audio parameters from the Blueprint and Component systems. The system includes a better, more intuitive and dynamic subset of features for mixing audio sources, and for dynamically controlling and parameterizing audio properties than Unreal Engine has had in prior versions.

The system:

Exposes a generic, flexible, decoupled, generic parameter modulation and mix system.

Establishes a more robust set of tools for auditioning and debugging a game's mix.

Provides an API that can be easily extended and used for further modulation of sources, effects, submixes, and various other audio types via plugins.

Audio Modulation is a powerful way to modulate virtually any float- or buffer-based parameter within the Unreal Audio Engine. In the most basic form of modulation, a user can connect a Modulation Source to a Modulation Destination. If no source is referenced, a default value, as provided by a Modulation Parameter, is mixed together with the value supplied as the default Modulation Destination value (see Modulation Sources and Mix Stages). This scenario can be thought of as plugging a traditional hardware patch cable into a modulation input, with the output end connected to a known quantity, such as a ground or voltage source.

Enabling Audio Modulation

All modulation features are encapsulated in the Audio Modulation plugin, and implement a lightweight, engine-side API.



To enable the Audio Modulation plugin, go to Edit > Plugin, click Audio in the left panel, then check Enabled for Audio Modulation.

Enabling the plugin, then restarting the editor or rebuilding in Visual Studio enables Unreal's native implementation of the Audio Modulation system.

Modulation Values

All modulation values can be transformed between two value spaces, the unit value space and the normalized value space. The unit space is displayed and provided as a means of convenience in the editor, while the normalized space provides a uniform way of passing and mixing bus values. All modulation values map to a normalized [0.0f, 1.0f] range. In a similar way to how a hardware synthesizer might use a control voltage (CV) as a standard for passing a value from a source to a destination, the Modulation System uses Control Buses that always contain values within the normalized float range.

Taking the case of Volume, the unit space may be the range between -60 dB (threshold of silence — which is configurable via the Modulation Parameter) and 0 dB (full volume), where the normalized values map logarithmically to the normalized space of 0.0f and 1.0f. Semitones is another example where a minimum and maximum value of +/- 12 in unit space can be configured in its respective Modulation Parameter settings. The normalized space always maps between 0.0f and 1.0f. In the most basic case, the unit and value space are identical — namely, all unit values correspond to the same normalized value between 0.0f and 1.0f.

Modulation Parameters

Modulation parameters provide context for how a value associated with a bus, bus mix, destination, and patch is displayed, mixed, and transformed to and from unit and normalized (unitless) [0.0, 1.0] values. They include a Unit Display Name property that dictates how to display units to all modulators referencing them, and a default parameter value. This value should be set to a value that results in no change to an input when a modulator referencing this parameter is mixed with another. (Mathematically, the value should be selected so that the mix function is effectively reduced to an Identity Function when set as an input).

For example, the Volume Default Modulation Parameter has a default value of 1.0f in normalized space (0 dB in unit space) and when mixed multiplicatively, this leads to no change at the output (meaning that mixing the input with this value results in the same value on the output).



The Volume Default Parameter Value results in no change at output when mixed multiplicatively.

Similarly, pitch has a default value of 0.5f in normalized space (0.0 semitones in unit space) as adding 0 semitones results in the same value as the value it is mixed with.

A Parameter Note for Developers: In code, the base class USoundModulationParameter can be inherited from, and can provide overloaded functions used to mix values (GetMixFunction) as well as transform values to and from unit and normalized space (GetUnitConversionFunction and GetNormalizedConversionFunction respectively). GetMixFunction returns a FModulationMixFunction, which is passed with a set of two float buffers — an InValueBuffer to mix into an OutValueBuffer, where the InValueBuffer contains values in normalized space.

Modulation Destinations

A Modulation Destination (FModulationDestination, found in the engine module) is any endpoint that provides a float value to an audio source or effect, and can be modulated by a referenced modulating source.



1) The base value that can be modulated; 2) Check to enable or disable modulation; 3) The source object to be modulated.

Modulation Destinations can be found on properties in a Submix Effect Preset, Source Effect Preset, or sound type (such as SoundWaves, SoundCues, and anything that generally inherits from the SoundBase Class). Standard Modulation Destinations for modulation on sound types include Volume, Pitch, Highpass, and Lowpass.

A Modulation Destination includes three basic properties:

A base value (in units) that can be modulated.

A boolean indicating whether or not modulation is enabled.

A modulation source object, which can be a Control Bus, Modulation Generator, or Modulation Patch.

Modulator Sources and Mix Stages

A variety of Modulation Source asset types are provided by the Audio Modulation plugin (all inheriting types of USoundModulatorBase, the base class found in the engine module). Each can be referenced by a Modulation Destination, and can even reference each other in select cases. These types include Control Buses, Modulation Generators, and Modulation Patches. Note that Control Bus Mixes, while not modulation sources, can drive values utilized by Control Buses.

In the flowchart below, each arrow represents a mix stage, where an array of one type can be mixed together, and will modify the resulting value using the input Modulation Parameter mix function (see USoundModulationParameter::GetMixFunction) specified in code. The default mix function is a simple multiplication of all resulting values. In other words, a Bus Mix (or an array of Bus Mixes) and/or a Modulation Generator (or array of generators) can be used to drive a Bus, and a Bus (or array of Buses) can be used to drive a Patch. A Modulation Generator, Bus, or Patch can then drive a Modulation Destination as shown below (multiple arrows denote where an array of modulators can affect another type):



1) Bus Mix; 2) Generator; 3) Bus; 4) Patch; 5) Destination

Control Bus (USoundControlBus)

Buses take on the value as set by the referenced parameter property by default. If Bypass is set, the bus will be ignored and not mixed into any input being driven by it.



Enabling Bypass will cause the bus to be ignored and not mixed into any input driven by it.

When driving the bus via a Bus Mix (or array of Bus Mixes), a client can use OSC-style addressing to adjust the mix value (see Set Control Bus Mix By Filter).

An array of Modulation Generators can also be supplied to drive the bus algorithmically.

Modulation Generator (USoundModulationGenerator)

Modulation Generators are a subclass of modulators that can procedurally generate values over time. Generators can be referenced by, and thus drive, Control Buses or Modulation Destinations directly. An LFO and Envelope Follower are implemented within the Audio Modulation plugin.

LFO (USoundModulationGeneratorLFO)

The LFO Modulator is the simplest example of a Modulation Generator available in the Audio Modulation plugin.

Each LFO shape observes the Amplitude, Frequency, and Offset supplied. The LFO bus modulator can be any of the following basic shapes as selected from the Shape dropdown:

Sine

Saw (Up)

Saw (Down)

Square

Triangle

Exponential

Random

Periodic functions will or will not loop, depending on whether Looping has been enabled. Setting the modulator to Bypass will compute the generated value, but will not drive or mix to buses or destinations referencing it.

EnvelopeFollower (USoundModulationGeneratorEnvelopeFollower)



The Envelope Follower generates a continuously updating envelope value based on the amplitude of the referenced Audio Bus input. The Gain property provides a way to dampen the incoming envelope by a provided scalar. Attack Time and Release Time provide the ability to effectively smooth out the resulting envelope. Setting the modulator to Bypass will compute the generated value, but will not drive or mix to buses or destinations listening to it.

Creating Custom Generators

Code generation templates are provided for the USoundModulationGenerator class, allowing developers to create their own Modulation Generators quickly and easily. Code generation creates all the boilerplate necessary for a generator to be created and registered. You can find this by going to Tools > New C++ Class and selecting All Classes from the Choose Parent Class modal dialog.



Go to Tools > New C++ Class. The Choose Parent Class dialog will open. Check All Classes to enable.

Developers are only required to implement the GetValue and Update functions. GetValue will return a cached, normalized, unitless value between 0.0f and 1.0f.

The Update function is where any computation of the next frame's cached value should go. The value is generated once per frame through the Update call, and is provided to any listening Modulation Destinations via the GetValue call.

Optionally, IsBypassed, GetDebugValues, and GetDebugCategories can be implemented as well. IsBypassed returns whether the generator value should or should not be included in Destination computations. By default, it forwards the value provided by the generated USoundModulationGenerator Bypass property to the Unreal Audio Engine. GetDebugValues provides an array of strings per generator instance to be displayed at runtime using the au.Debug.SoundModulators family of debug commands in non-shipped builds. GetDebugCategories should supply a static array of field names corresponding to the values provided by these instance values.

Modulation Patches (USoundModulationPatch)

The Modulation Patch is the Unreal analogy to a patch bay in hardware modulation, but more powerful in that it provides the ability to functionally remap input bus values.

It reroutes and mixes Parameter bus values to destinations in potentially abstract and interesting ways, but unlike Control Bus Mixes, which apply a stage to an array of buses in parallel, patches are intended to combine bus values, then mix them to a destination (or multiple destinations) serially.



Patches combine bus values and mix them to one or more destinations serially.

A patch consists of an array of bus Input slots, each containing a bus reference and transform information. If no buses are subscribed to, the Default Input Value of the patch referenced parameter will be sent to the patch output.

Each input provides a Sample-And-Hold property, which results in the patch capturing the bus value as soon as the patch is initialized, and holds it for the duration of the patch's lifetime. The output of each of these subscribed bus-transformed values is mixed using the patch Modulation Parameter mix function. Each input can be mapped using a shared curve asset, a custom curve (stored in the patch asset), or an expression (listed below with examples):



(red) Log; 2. (green) Exponential (inverse); 3. (blue) Sin; 4. (orange) S-Curve; 5. (purple) Exponential

Control Bus Mix (USoundControlBusMix)

A Control Bus Mix is a way to drive and group control bus values dynamically at runtime. Multiple mixes can drive a single bus, and multiple buses can be driven simultaneously by a single mix.



With the Control Bus Mix feature, multiple mixes can drive a single bus, and multiple buses can be driven simultaneously by a single mix.

Each control bus mix has an array of Mix Stages. A Mix Stage can be thought of as similar to a channel strip found on a traditional hardware mixer. However, Control Bus Mixes are dynamic — meaning they can have any number of entries, unlike a traditional mixer — and can control virtually any parameter type, not just those canonical values found on a mixer such as volume, pitch, HPF cutoff, LPF cutoff, and trim.

Mix Stages are always associated with a single Modulation Value, and have no direct relation to the traditional definition of a channel in audio (that is, the number of channels in an audio file set, such as mono, stereo, or surround). The name Mix Stage is more related to a traditional gain stage in a volume mix chain, but not limited to volume.

Each Mix Stage provides a Value (displayed in both unit and normalized space), Attack Time, and Release Time. Attack Time is the time it takes for the Mix Stage Value to go from the default value (as defined in the Modulation Parameter for that bus) to the value supplied when the mix is activated. Release Time is the time it takes for the Mix Stage Value to go from its current value back to the default value.

A myriad of functions are exposed as tools in the Details panel when editing Control Bus Mix assets. Activation and deactivation can be auditioned using the functions provided. In addition, a mix can be soloed, or you can deactivate all mixes being auditioned.

Mix profiling is a way to test out different settings saved as loose config files. For a developer, this can be extremely useful for testing out mixes in a non-shipped build, allowing for fast iteration on perfecting, or testing out new mixes during development. It can even be used to load user-created mixes in a shipped build. Mix profiles are loaded and saved to .ini files at <ProjectDirectory>Saved\Config\AudioModulation\< RelativeContentPathToObject> using the Load Mix from Profile and Save Mix to Profile functions. Mix profiles are indexed using the Profile Index property.

Modulator Activation

All Modulation Sources are activated upon any object being instantiated where they contain a destination that references them. For example, if a Sound Wave with a reference to a Control Bus is played by an Audio Component and that Control Bus is not currently active, it will become active, a process which effectively instantiates a proxy to that Control Bus on the Audio Render Thread. When all references to that Control Bus are destroyed, the Control Bus deactivates, sending a message to the Audio Render Thread to destroy the respective proxy.

Modulation Sources can also be activated by another source referencing them. For example, a Control Bus may become activated if a patch is referenced by a Modulation Destination, and that patch references the given Control Bus.

Optionally, from Blueprint, a client system can hold a handle to a modulator, forcing activation of a bus irrespective of Modulation Destination references being instantiated. This style of explicit management has the benefit of allowing users to feed values to a modulator regardless of whether it is subscribed to. However, utilizing explicit management may require more diligence on the part of the client system to keep tabs on modulator lifetime. An example of when this might be useful includes having a character's ability power be bussed to the audio engine, regardless of whether destinations are actively registered to the modulator.

Blueprint API

(De)ActivateBus/BusMix/Modulator

These calls provide the ability to manually activate and deactivate Control Buses, Bus Mixes, and Modulators (See Modulator Activation). They respectively no-op (do nothing) if already in the requested state (activated or deactivated).

UpdateModulator

To preserve thread safety, changes to inheriting types of USoundModulatorBase (such as USoundControlBus, USoundControlBusMix, and USoundBusModulatorLFO) must be committed via UpdateModulator. When provided with a type, all applicable changes to the USoundModulatorBase instance will be reflected in the respective runtime instance. For example, if a volume control bus is referenced by a USoundBase type and active (with no mixes applied), updating the default value will instantly update the gain stage supplied by that bus to that USoundBase instance.

CreateLPFBus/HPFBus/PitchBus/VolumeBus/BusMix/LFO

These are convenience functions for creating respective types, setting a default value, and providing the option to activate immediately.

Save Control Bus Mix to Profile

Saves a control bus mix to a profile, serialized to an .ini file. If the mix is loaded, it uses the state of the current proxy. If not, it uses the default UObject representation.

Load Control Bus Mix From Profile

Loads control bus mix from a profile into UObject mix definition, deserialized from an .ini file.

Set Control Bus Mix

Sets a mix with the provided stage data if stages provided in active instance proxy of mix. Does not update UObject definition of mix.

Set Control Bus Mix By Filter

Sets filtered stages of a given class to a provided target value for active instance of mix. Does not update UObject definition of mix unless specified.

Update Control Bus Mix

Commits updates from a UObject definition of a bus mix to active proxy in audio render thread. Ignored if the mix is inactive.

Update Modulator

Commits updates from a UObject definition of a modulator ( such as Bus, Bus Mix, LFO) to an active proxy in an audio render thread.

Overview

Goals

Objectives

1 - Required Setup

Section Results

2 - Create the Control Buses

Section Results

3 - Assign the Control Buses to Sound Assets

Section Results

4 - Create a Sample MetaSound

Section Results

5 - Apply a Mix

Section Results

6 - Debug a Mix

Section Results

7 - Adjust Control Buses from Blueprints

Section Results

Overview

The Audio Modulation system provides control over common floating-point audio parameters from the Blueprint and Component systems. The system includes a better, more intuitive and dynamic subset of features for mixing audio sources, and for dynamically controlling and parameterizing audio properties than Unreal Engine had in prior versions.

In this guide, you will learn how to build a basic volume-based Control Bus structure for your game audio.

Goals

Use the Audio Modulation Plugin to build a basic volume-based Control Bus structure for your game audio.

Objectives

Create a collection of Control Buses and Control Bus Mix objects to apply volume mixing to sound assets .

Assign Control Buses to MetaSound Sources and Sound Classes.

Use the Mix Matrix Debugger to see the current values of the Control Bus.

Adjust a Control Bus from Blueprints.

1 - Required Setup

Create a new project and select the Games category and the Third Person template. Enter your project's location and name. Click Create.



Click Settings > Plugins to open the Plugins window.



Search for and enable the Audio Modulation and MetaSound plugins. Restart Unreal Engine.



Section Results

In this section, you created a new project and enabled the Audio Modulation and MetaSound plugins. You are now ready to create the Control Buses.

2 - Create the Control Buses

In the Content Browser, right click and select Sounds > Modulation > Control Bus. Name the asset CB_Main.





Open CB_Main and click the Parameter dropdown. Click the Gear icon and enable the Show Plugin Content checkbox. You may have to select Show Engine Content, as the Modulation plugin is an Engine plugin.



Search for and select the Volume parameter.



You can create a custom parameter by right clicking in the Content Browser and selecting Sounds > Modulation > Modulation Parameter. Then, select the SoundModulationParameterVolume class from the list.

Create two folders in the Content Browser that will contain several Control Buses meant for designers and users. In the example below, the folders are named Buses_Designerand Buses_User.



Right-click on CB_Mainand select Duplicate. Name the new asset CB_Ambience.



Repeat this process two more times and create CB_Foleyand CB_Footsteps. Select all three assets and move them to the Buses_Designerfolder.



Repeat the previous step and create CB_Dialogue, CB_Music, and CB_SFX. Move them to the Buses_Userfolder.



Section Results

In this section, you created the main Control Bus that will modulate the volume for all assigned audio in your project. In addition, you created several Control Buses meant for the user and designer. You are now ready to assign the main Control Bus to the Master sound class in your project.

3 - Assign the Control Buses to Sound Assets

Click Settings > Project Settings to open the Project Settings.



Scroll down to the Engine section and select the Audio category. Go to the Audio section and double click the Master Default Sound Class to open it.





In the Details panel, go to the Modulation section and enable the Modulate checkbox next to Volume.

Click + next to Volume Modulators and add CB_Mainto Index[0].





Add the CB_Main Control Bus to any additional sound classes in your project, so all sounds are mixed using the same Control Bus. The Sound Class reference hierarchy is not observed by modulation and the mix structure. Each Sound Class must list all Control Buses that are to be applied to Sound Assets referencing said Sound Class.

Section Results

In this section, you assigned the CB_Main Control Bus to the Master sound class. You are now ready to create a sample MetaSound to test the mix during gameplay.

4 - Create a Sample MetaSound

In the Content Browser, right-click and select Sounds > MetaSound Source. Name the asset MS_Sample.





Open MS_Sampleby double-clicking it in the Content Browser.

Go to the Interfaces panel on the left and click the remove icon next to UE.Source.OneShot to remove it.

Right-click in the Event Graph and search for then select Wave Player (Mono).

Connect the Input node to the Play pin of the Wave Player node.

Connect the Out Mono pin of the Wave Player node to the Output node.







Click the Wave Asset dropdown and select a sound asset. In this example, EndPlayInEditor was selected.

Enable the Loop checkbox.



Click Source on the toolbar and scroll down to the Details panel.

Expand the Modulation category.

Click the Volume Routing dropdown and select Union.

Enable the Modulate checkbox next to Volume.

Click + next to Volume Modulators and add CB_SFXto Index[0].







Drag MS_Sampleto your level.



Section Results

In this section, you create a simple MetaSound that will play a sound asset continuously. You are now ready to apply the Control Bus Mix to the Control Buses.

5 - Apply a Mix

In this section, you will create a Control Bus Mix and apply it to all Control Buses in the Buses_Userfolder. You can follow these steps to create a Control Bus Mix for all Control Buses in the Buses_Designer folder as well. In addition, there is no strict rule as to what can be included in a mix.

Multiple mixes can be activated and applied to a single or group of Control Buses. However, only a single instance of a given mix can be active at a time.

In the Content Browser, right-click and select Sounds > Modulation > Control Bus Mix. Name the asset CM_User.





Open CM_User and go to the Mix Stages section.

Click + next to Mix Stages to add a new mix.

Click the Bus dropdown and select CB_Dialogue.



Repeat the previous step and add CB_Musicand CB_SFXto the Mix Stages.



Press Play to enter runtime.

Press Shift-F1 to regain control of your mouse.

Go to CM_Userand click Activate Mix.

Change the value of CB_SFXto see the changes applied in real time.





Section Results

In this section, you created and applied the CM_User Control Mix to the Control Buses in your project. You also activated the mix during gameplay and changed the volume of sounds using the CB_SFXControl Bus.

6 - Debug a Mix

During gameplay, press ~ to open the console window.

Enter the following command: au.Debug.SoundModulators.Enable.Matrix 1 to enable Sound Modulation debugging.



You can filter the list of Control Buses and Control Mixes displayed by entering the commands: au.Debug.SoundModulators.Filter.Buses [substring] and au.Debug.SoundModulators.Filter.Mixes [substring].





Section Results

In this section, you activated the Sound Modulation debugger and filtered the matrix to only show the CB_SFX Control Bus.

7 - Adjust Control Buses from Blueprints

In this section, you will activate a Control Mix from Blueprints at runtime.

Click the Blueprint button in the Level Editor toolbar and select Open Level Blueprint.



In the Event Graph, right-click and search for then select Event Begin Play.



Drag from the Event Begin Play node and search for then select Activate Control Bus Mix.

Click the Mix dropdown and select CM_User.



Drag from the Activate Control Bus Mix node and search for then select Delay.

Set the Duration to 3.0.



Drag from the Delay node and search for then select Set Control Bus Mix By Filter.

Click the Mix dropdown and select CM_User.

Add CB_SFXto the Address Filter.

Enter a Value of 0.25.



Press Play and verify that the CM_User Control Bus is activated and the volume of MS_Sample is lowered after 3 seconds.

Section Results

In this section, you activated the CM_User Control Bus and changed the volume of audio using the CB_SFX Control Bus.

Creating Audio Buses

Sending Audio to Audio Buses

Audio-Rate Modulation with Audio Buses

Outputting Audio from Audio Buses

Audio Buses vs. Submixes

In Unreal Engine, Audio Buses combine sound sources into a single signal path.

You can use the combined audio signal in two primary ways:

Use the signal to perform audio-rate modulation on parameters or other signals. For example, use it to dynamically control digital signal process (DSP) effect parameters (known as sidechaining).

Output the mixed audio signal from a point in space. In particular, using the rendered output, create speakers or other audio-producing objects within your Level.

Creating Audio Buses

To create an Audio Bus:

In the Content Browser, click the Add button.

Select Sounds > Mix > Audio Bus.



To edit an Audio Bus, you can double-click it in the Content Browser or right-click it and select Edit from the context menu. Then, in the Details panel that appears, set the number of Audio Bus Channels you want to use.

If you send audio to an Audio Bus with a different channel configuration, it will be mixed accordingly. For example, sending a mono source to a stereo Audio Bus will upmix to stereo.

Sending Audio to Audio Buses



You have to start an Audio Bus before it can receive audio. Set the Default Audio Buses in the Project Settings to have the specified Audio Buses start automatically.

You can also start an Audio Bus manually by using the Start Audio Bus Blueprint node. Similarly, you can stop an Audio Bus by using the Stop Audio Bus Blueprint node.



You can set an Audio Bus to send audio to in the Details panel for your source asset (such as a Sound Wave, Sound Cue, or MetaSound Source). Under Effects > Source, click the Add (+) button for Post-Effect Bus Sends or Pre-Effect Bus Sends to add a bus send that will occur before or after an optionally provided Source Effect Chain.



Expand the new bus send index to set the Audio Bus and the Send Level.

You can change the Source Bus Send Level Control Method (in combination with the other related properties) to send based on distance or a custom curve.



If you want the original source audio to be inaudible (by only sending it to the Audio Bus), you can disable Enable Base Submix and Enable Submix Sends under Source > Submix in the Details panel.

Audio-Rate Modulation with Audio Buses



Modulation is the process of using a signal to alter other audio signals or parameters of a sound. You can modulate at an audio rate using Audio Buses.

By default, two Source Effect Preset classes allow for audio-rate modulation with an Audio Bus:

Filter: The Audio Bus signal controls the filter frequency cutoff.

Ring Modulation: The Audio Bus signal is multiplied by the input signal.

To create a Source Effect Preset:

In the Content Browser, click the Add button.

Select Sounds > Effects > Source Effect Preset.

Choose from the list of classes available in the Pick Source Effect Class window.



You can set the Audio Bus you want to modulate with in the Details panel for the Source Effect Preset.

After you create a Source Effect Preset, you must add it to a Source Effect Preset Chain.

To create a Source Effect Preset Chain:

In the Content Browser, click the Add button.

Select Sounds > Effects > Source Effect Preset Chain.



You can set the Source Effect Presets you want to use in the Source Effect Preset Chain's Details panel.



After you configure a Source Effect Preset Chain, you can set it in the Source > Source Effects Chain property in a source's Details panel. The Source Effects Preset Chain specified will take effect after any bus sends in the Pre-Effect Bus Sends and before any bus sends in the Post-Effect Bus Sends.

Outputting Audio from Audio Buses

By default, Audio Buses are not audible. To output Audio Bus audio, you must use a Source Bus or MetaSound Source.

A Source Bus renders the output of an Audio Bus. Source Buses can use sound source features, such as spatialization, attenuation, and concurrency resolution. They can even output audio to other Audio Buses and Source Buses.

Source Buses only support Mono or Stereo. Use a MetaSound Source to support additional channel configurations.

To create a Source Bus:

In the Content Browser, click the Add button.

Select Sounds > Source > Source Bus.



Set the Audio Bus you want to render in the Source Bus Details panel. Additionally, you can select the number of Source Bus Channels and the Source Bus Duration.

If the Source Bus Duration is set to 0, the Source Bus will play indefinitely. Use any positive value to create a one-shot sound source that will stop after the duration.

You can also render Audio Bus audio by using a MetaSound Source. On the MetaSound graph, use an Audio Bus Reader node to read in Audio Bus data, then attach it to the corresponding outputs.

In addition to mono and stereo, you can produce quad, 5.1, and 7.1 audio with a MetaSound Source by setting the Output Format accordingly.

For more information on MetaSounds, see the MetaSounds documentation.

Audio Buses vs. Submixes

Audio Buses are comparable to Submixes but differ in several important ways:

They don't have graphs.

Their audio is not audible by default.

They provide a way to define spatialization behavior.

They can't have DSP effects applied to them directly.

They only use CPU resources when receiving source audio.

See Submixes Overview for more information on Submixes.

General Properties

Child Classes

Passive Sound Mix Modifiers

Routing

Legacy

Submix

Modulation

Loading

A Sound Class is an asset type for the audio engine within Unreal Engine that a user can use to group multiple sounds together, then alter the parameters of all relevant Sound Waves at once.

By using Sound Class Mixes, many Sound Class parameters can be adjusted during gameplay.

To set up a new Sound Class, right-click from the Content Browser, then select Sounds > Classes > Sound Class.

To open the Details panel for a Sound Class, double-click the Sound Class in the Content Browser.



General Properties

The first set of parameters in a Sound Class are the General Properties.



Volume: A multiplier on the loudness of each sound within the Class. This acts on top of Volume settings in the Sound Wave object itself.

Pitch: A multiplier on the pitch of each sound within the Class that acts on top of pitch settings in the SoundWave object.

Low Pass Filter Frequency: The cutoff frequency for the low-pass filter that impacts all sounds within the Class; a value of 20,000 or above has no effect on a Sound Wave.

Attenuation Distance Scale: Scales the attenuation distance of each sound within the Class, allowing for attenuation settings to be adjusted dynamically.

Always Play: When enabled, it prevents sounds within the Sound Class from being ejected from the voice pool by sounds with a priority lower than Always.

Child Classes

A Sound Class can have other classes set as its Child Classes.



To add a Child Class, either click the plus (+) icon in line with Child Classes and select it from the dropdown, or drag the Sound Class onto the graph and connect the Children output pin from the Parent Class node to the input pin of the Child Class node.

When a Sound Class is set as a child, if set to Inherited (see Loading), it will inherit features like Pitch, Volume, and Loading behavior from the Parent Class. In this way, the user can alter the settings of both the parent and any of its child classes at the same time.

Passive Sound Mix Modifiers

A Sound Class can have an array of Sound Class Mixes attached that are triggered automatically when any sound within that Sound Class is played. These are called passive because they do not need to be manually activated.

For example, they are triggered automatically when a member of the Sound Class is played, without the need for an explicit Push Sound Mix Modifier command. You can still call the Sound Mix Modifier through a Push command if you want, and multiple Sound Classes or Blueprints can refer to the same Sound Mix Modifier.



Each Passive Sound Mix Modifier can be given a minimum and maximum volume threshold for parametric volume to control when it should activate. As an example, this gives the user a way to prevent a far-away sound that has attenuated to an inaudibly quiet volume from triggering a Sound Mix Modifier.

With this feature, a sound designer can create complex behavior in EQ and relative volumes of Sound Classes without adding a lot of Blueprint triggers.

Routing

These settings control how the Sound Class audio is routed through directional channels, with surround-sound setups in mind.



LFE Bleed: The proportion of the signal that should be sent to the Low Frequency Effects (LFE) Channel. The default is .5, or 50 percent.

Voice Center Channel Volume: The proportion of the signal to be sent to the Center Channel. This is not a multiplier, and the value is not inherited by children.

Center Channel Only: When enabled, the sound will be sent only to the Center Channel.

Apply Ambient Volume: When enabled, the sounds within the Sound Class will be affected by Ambient Zone settings within Audio Volumes, such as Interior/Exterior Volume and Low Pass Filter settings.

Legacy

This tab contains settings that were created before the Audio Mixer feature was added to the Unreal Audio Engine.



Output Target: Changes whether sounds within the Sound Class are sent to the main speaker, an external controller, or a controller (with playback to speaker if no controller present).

Radio Filter Volume: The volume of the radio filter effect that applies to the sounds within the Sound Class. Available on Windows and Xbox with the XAudio2 backend.

Radio Filter Volume Threshold: The volume at which the radio filter kicks in. Available on Windows and Xbox with the XAudio2 backend.

Output to Master EQ Submix: If enabled, sends the sounds within the output for this Sound Class to the reverb system that was used before the Audio Mixer reverb system replaced it. This setting is still respected by the Audio Mixer.

Is UISound: If enabled, the sounds within the Sound Class are audible within UI menus and during regular gameplay. This setting is still respected by the Audio Mixer.

Is Music: If enabled, the sound is marked as music.

Submix

Sounds within a Sound Class can be sent to a Submix, which allows multiple sound types to be processed with submix effects at once.



Send to Master Reverb Send Amount: When enabled, primary reverb settings are applied to sounds within the Sound Class.

Default 2D Reverb: The default amount of reverb effect to be placed on non-spatialized sounds.

Default Submix: The submix that the output of sounds within the Sound Class are sent to by default. When set to None, the output will be sent to the Sound Class Default Submix specified in Project Settings.

Modulation

If the Audio Modulation plugin is installed, it is possible to add an array of Modulations Settings to all sounds within a Sound Class.



Loading

This setting controls how the compressed audio data is loaded.



Inherited: When set to this option, the Sound Class inherits its loading behavior from its parent Sound Class.

Retain on Load: The first chunk of audio for sounds within the Sound Class remains in the cache until explicitly deleted.

Prime on Load: After being loaded, sounds within the Sound Class remain in the cache, but risk being removed to make space for other audio if unused for long periods of time.

Load on Demand: No chunks of the audio are stored until the asset is played or primed.

Force Inline: Forces the sounds within the Sound Class to only use non-streaming decode paths, and no portion of audio is stored in the cache. Requires each Sound Wave asset's Loading Behavior Override to also be set to Force Inline.

MIDI Device Support

What Is MIDI?

Workflows

MIDI Output

MIDI Input

MIDI Device Support



The MIDI Device Support plugin adds the ability to send and receive MIDI (Musical Instrument Digital Interface) protocol messages. This is most frequently used to communicate between Unreal Engine and external hardware such as MIDI keyboards. However, because MIDI is a data protocol, a user can use data parsed from messages to drive non-audio related parameters, as well.

Currently, Unreal Engine only supports streamed MIDI data. Reading MIDI files is not supported.

What Is MIDI?

MIDI is a data protocol designed for communicating between different audio hardware devices, using MIDI messages. A MIDI message starts with a byte containing the type of message it is (a "status" byte), followed by data bytes.

For example, one of the most common MIDI messages is a Note On message, which consists of a status byte that both signifies it as a Note On message and communicates the channel it is intended for (a value from 0 - 15), followed by a byte of pitch data, and then a byte of velocity data. Because the most significant bit of each data byte is used to signify that it is a data byte, both the pitch and velocity data can only contain a value between 0 and 127.

The MIDI protocol also specifies how to interpret bytes of data, such as how to translate a pitch value of 0 to 127 into a unit such as Hz. While Unreal does not directly translate MIDI data this way, which potentially allows users to use MIDI messages to drive behavior other than audio, our Sound Utilities plugin includes several functions that can be used to perform MIDI data conversions.



Workflows

MIDI Output

To get MIDI Output functioning in Unreal Engine, follow the workflow described below:

Find the ID of the device you want to send the MIDI signal to. You can do this by:

Selecting the default MIDI device.

Iterating through all available MIDI devices

Searching for a specific MIDI device by name.

The relevant Blueprint functions are Get Default MIDI Output Device ID, Find MIDI Devices, and Get MIDI Output Device ID by Name.

Create your MIDI Output UObject using the Blueprint function, Create MIDIDevice Output Controller. This function takes an ID as input, and returns either a reference to the MIDI Output, or a null reference if it was unsuccessful in connecting to the MIDI Device.

It's important to make sure you cache your MIDI Device Output Controller into a variable. Otherwise, your MIDI Controller is at risk of being unexpectedly garbage collected.

Send over your MIDI commands! These are going to be the functions under MIDI Device Manager that act on a MIDIDevice Output Controller. Generally, the functions used most often are Send MIDINote On, Send MIDINote Off, and Send MIDIPitch Bend.

If you're more experienced with MIDI protocols, you also have the option of constructing raw MIDI Event data using Send MIDIEvent.

A basic Blueprint implementation for MIDI Output will resemble the image below, though likely with more elaborate instructions for what MIDI data to send:



MIDI Input

To set up MIDI Input, follow the workflow described below:

Get your MIDI Input Device set up and cached in a variable; this will look almost identical to the first two steps in setting up MIDI Output listed above, with the exception that the function names will contain Input instead of Output.

Register to delegates for the MIDI Events you care about, through actions such as Assign To On MIDI Note On on your MIDI Input Device

Use the resulting data from these MIDI Events to drive parameters in your project, such as the pitch or velocity of a playing sound. Some of the functions in the Sound Utilities Plugin can translate MIDI's (0 - 127) integral data points into units more readily interpreted by the Audio engine, such as frequency and volume scalars.

For more advanced users, you may want to experiment with interpreting MIDI data such as Control Change messages, or with creating a polyphonic music system by using multiple Audio Components and keeping track of which notes are active.

A basic MIDI Input system Blueprint implementation might look like this, although likely with more complex uses for the incoming MIDI data:



Root Types

Asset Classes

Blueprint API

Resources/Examples

Blueprint API

Console Variables

Open Sound Control (OSC) is an open protocol commonly used in many areas of the audio industry. It is primarily used to network generic audio data between clients, although it can also be used for non-audio data.

The OSC plugin provides an intuitive, type-safe Blueprint library that a developer can use to quickly iterate networked audio (and potentially other domain) data in Unreal Engine. When this plugin is enabled, you can send and receive OSC events through a simple API in either C++ or Blueprint. It supports sending and receiving messages and bundles, or combinations of bundles and messages.

The OSC plugin must be enabled to use this feature. Go to Edit > Plugins > Input Devices, then check the OSC (Open Sound Control) option to enable.

Root Types

OSC Server

The OSC Server (UOSCServer) acts as a listening endpoint for messages sent to the local instance of Unreal Engine. It supports multicast loopback, and parsing of both OSC messages and bundles. It also lets the server specifically state which IP addresses it will listen to (whitelisting).

A user can bind an event to receive messages from all OSC addresses using a provided address pattern (see Binding An Event to Address Patterns below), listen for all messages (see Binding An Event to All Messages below), or listen for all bundles (similar to Binding An Event to All Messages below but requiring unpacking a received bundle).

OSC Client

The OSC Client (UOSCClient) provides a way of sending OSC messages and bundles.

FOSCAddress

An OSC Address (FOSCAddress) is a typed path that may or may not also be a valid pattern. As a valid path, it can be created, sent, and received as part of a message packet.

It contains an array of containers and a method in the form of /Container1/Container2/Method, and can be queried for validity as either a path or a pattern, converted to or from a string, and manipulated with Blueprint calls. It can also be filtered against another OSC Address that is a pattern when binding to the event BindEventToOnOSCAddressPatternMatchesPath.

OSC Bundle/Message

Both OSC Message (FOSCMessage) and OSC Bundle (FOSCBundle) are packet types that are received from the OSC Client, or sent with the OSC Server.

An OSC Message contains an address that is also a valid path, and that has a payload of supported OSC protocol types.

An OSC Bundle contains an array of packets of either other OSC Bundles or OSC Messages, or both.

Asset Classes

The OSC plugin does not require any asset classes. All of its required types are transient and expected to be created, managed, and destroyed with Blueprint.

Blueprint API

OSC Server

OnOsc(Bundle/Message)Received

An event that gets called when an OSC bundle/message is received.

SetWhitelistClientsEnabled

When set to true, the server will only process received messages from whitelisted clients.

(UnbindEvent/UnbindAllEvents/BindEventTo/Get)OnOSCAddressPattern(s)

Unbinds, binds, removes or gets event(s) to dispatch when an OSCAddressPattern is matched.

(Add/Remove/Clear/Get)WhitelistedClient(s)

Adds, removes, clears, or gets a set of client IP Addresses as strings (IPv4) that are whitelisted.

OSC Client

(Get/Set)SendIPAddress

Gets the OSC Client IP address and port.

SendOSC(Bundle/Message)

Sends an OSC bundle/message to a specific address.

OSC Bundle/Message

Add(Bundle/Message)ToBundle

Adds provided bundle/message to bundle.

Get(Bundles/Messages)FromBundle

Returns the bundles/messages found in the bundle.

(Add/Get) OSC Message (Strings/String at Index, Integer/Integer at Index, and so on)

Adds/gets POD type to or from OSCMessage. (List of types supported can be found here.

Clear OSC (Message/Bundle)

Clears the message/bundle's payload.

Resources/Examples

OSC implementation is based on the OSC 1.0 protocol found on the OpenSoundControl website.

Click the Copy Node Graph button on each image below and paste the text into your Blueprint Graph to see the examples in action.

Sending an OSC Message



Binding an Event to All Messages



Binding an Event to Address Patterns



Blueprint API

Get OSC Message From Bundle At Index

Returns the message found in a bundle at ordered index.

Add OSC Address (As String) to OSC Message

Adds an address (packed as a string) value to the end of OSCMessage

Get OSC Message Address At Index

Sets the Value to the address at the provided Index in OSCMessage if in bounds, and if OSC type matches String. (It does not return the address of the message; instead, the string is packed in the message and casts to the OSC address.) Returns if the string is found at Index, and if it is a valid OSC address path.

Get OSC Message Addresses

Returns all strings that are valid address paths, in the order received from OSCMessage. (It does not include the address of the message, just the strings packed in the message that are valid address paths.)

Find Object at OSC Address

Finds an object with the given OSC Address in path form, where containers correspond to path folders and the address method corresponds to the object's name. Only supports parent objects.

Convert Object Path to OSC Address

Converts an object path to the OSC Address, converting folders to address containers, and the object's name to the address method. Only supports parent objects. See UObjectBaseUtility::GetPathName and UObjectBaseUtility::GetFullName.

Convert Object Path (String) to OSC Address

Converts the object path string to an OSC Address, converting folders to address containers and the object's name to the address method. Only supports parent objects. See UObjectBaseUtility::GetPathName and UObjectBaseUtility::GetFullName.

Convert OSC Address to Object Path

Converts an OSC Address to an object path.

Remove Containers from OSC Address

Removes containers from an ordered array of containers at index, up to the count of containers.

In addition to new Blueprint API calls listed above, all index getters now return a Succeeded Boolean value indicating whether or not the typed value at the provided index was of the given type and the value parsed as expected by the client.

Console Variables

osc.clients

Prints diagnostic information for the currently initialized OSC client objects to the output log.

osc.client.connect

Connects (or reconnects) the OSC mix client with the provided object name. See osc.clients for a list of available clients and their respective names.

Id — Object ID of client to (re)connect to

Address — IP Address to (re)connect to (default: LocalHost)

Port — Port to (re)connect to (default: 8094)

osc.client.connectById

Connects (or reconnects) the OSC mix client with the provided Object ID. See osc.clients for a list of available clients and their respective IDs.

Id — The Object ID of client to (re)connect to.

Address — IP Address to (re)connect to (default: LocalHost)

Port — Port to (re)connect to (default: 8094)

osc.servers

Prints diagnostic information for the currently initialized OSC server Objects to the output log.

osc.server.connect

Connects (or reconnects) the OSC mix client with the provided Object name. See osc.clients for a list of available clients and their respective names.

Name — Object name of server to (re)connect to

Address — IP Address to (re)connect to (default: LocalHost)

Port — Port to (re)connect to (default: 8095)

osc.server.connectById

Connects (or reconnects) the OSC mix client with the provided Object ID. See osc.clients for a list of available clients and their respective IDs.

Id — Object ID of client to (re)connect to

Address — IP Address to (re)connect to (default: LocalHost)

Port — Port to (re)connect to (default: 8095)

Issues with Accurate Timing and Latency in Audio Rendering

Quartz and Sample Accuracy

How Quartz Works

Main Components in Quartz

Create and Initialize Quartz Clocks

Play Sounds on a Quantization Boundary

Subscribe to Command Events

Subscribe to Metronome Events

Time Signatures and Pulse Overrides

Issues with Accurate Timing and Latency in Audio Rendering

In an audio engine, for CPU performance reasons, audio samples are rendered in buffers, and submitted individually to output hardware — a digital audio converter (DAC). A number of reasons make this the only feasible way to render audio in real time on a CPU — CPU cache coherency, hardware API overhead, and so on.

These buffers typically contain hundreds or even thousands of samples at a time. It is important to understand that audio engine rendering commands are typically consumed at the beginning of an audio buffer render. A command, for example, might be to play a new sound, stop an old one, or change the parameter of a sound like volume or pitch.

Because of this, the size of the rendered audio buffer directly controls the rate at which new commands are consumed. This rate also describes the perceived audible latency of any issued commands. For example, if you were to trigger an explosion VFX and an explosion sound on the same game-thread tick, the latency between seeing the VFX explosion and hearing the sound is determined by this buffer size.

This means that for a buffer that contains 2048 samples rendered at 48k samples per second (kHz), the buffer would result in an audible latency of up to 43 milliseconds (ms).

In addition to this inherent latency with an audio renderer due to the render buffer size, audio commands issued from the game thread take time to get to the audio engine due to game-thread and audio-thread ticks, and general thread communication overhead. If a threading or gameplay latency is 13 ms (a feasible number), and we use the same buffer size of 2048 samples at 48 kHz, and if the command just missed the start of the current buffer being rendered, there will be a worst-case accumulated latency of 56 ms.



If an audio request comes in after a buffer has started to render (1), then the request will carry forward without playing (2) until the beginning of the next buffer (3).

To complicate matters, game-thread ticks are highly variable (at least from the perspective of an audio renderer), and are often susceptible to arbitrary hitches — during garbage collection, loading assets, and so on.

Game-thread ticks are also timed for gameplay and graphical rendering, not for audio rendering and audio timing. If you need to play a sound at a precise moment in time (exactly when a different sound is finishing or starting), calling that command from the game thread will not work because the game-thread and audio render-thread event timings are decoupled.

These issues of variable latency and game-thread-dependent timing of audio events are not significant for the majority of audio applications. Depending on the CPU load of a game or the constraints of a particular platform, it is usually possible to tweak the buffer sizes and number of buffers rendered ahead of time to a size where most timing issues are below the threshold of perception.

However, for some audio applications, such as interactive music, precisely timed repeating weapon fire, or other rhythmically-dependent audio, these issues are a significant problem.

Quartz and Sample Accuracy

Sample accuracy is the ability for a sound to start at an arbitrary sample in the audio renderer (such as the middle of a buffer) instead of on a buffer boundary.

Quartz is a system that works around the issues of variable latency and game-thread timing incompatibility by providing a way to accurately play any sound sample. Sample accuracy refers to the ability for a sound to render audio at an arbitrary sample (point in time) within an audio buffer rather than at the beginning of the buffer.



Quartz provides a way of scheduling an audio call mid-buffer instead of having to delay the audio render until the beginning of the next buffer.

Instead of rendering a sound at the beginning of an audio buffer, Quartz cues the sound to play on the desired musical value (bars or beats) or time value (seconds), independent of the buffer size, game-thread timing, or other sources of variable latency.

This has many applications — from creating dynamic music systems, to controlling the playback of rhythmic and timing-dependent sounds such as sub-machine gunfire.

How Quartz Works

With Quartz, you can give the audio engine advance warning by scheduling a sound with PlayQuantized(), which executes the play command at a specific sample in the audio render. By scheduling ahead of time, you account for the delay so that sounds can render on exactly computed samples to make the queued-up sounds play as though there were no delay.

The buffer size is also referred to as the audio buffer callback size, or callback size for short.



A represents the game thread, with X-axis demarcations indicating game frame ticks, while B represents the audio render thread with X-axis demarcations indicating rendered audio buffers. Their respective X-axes vertically line up in real-world time. (1) When the game thread calls PlayQuantized(), it requests that the sound be played on a given quantization boundary (such as the next quarter note), as calculated to the nearest audio output sample on the audio render thread. (2) Quartz issues this request in the form of a generic Quantized Command, and queues the sound for audio rendering at a future point in time. The request is held through multiple audio buffers on the audio render thread (3) by the computed amount. When it is time to render the sound in the computed buffer, Quartz feeds the audio through an integer delay that prevents it from rendering at the beginning of the buffer (4) and instead renders partway into the output buffer on the sample needed to play exactly on the quarter note (5).

Quartz also works with Blueprints. Blueprints provide a way to apply these quantized commands and timing events, which in turn trigger gameplay logic in sync with the quantized actions occurring in the Audio Mixer.

Main Components in Quartz

Quartz Clock

A clock is the object in charge of scheduling and firing off events on the audio rendering thread. A clock is created with the Quartz Subsystem, and modified via a Blueprint using Clock Handles. Each clock has a Quartz Metronome.

Quartz Metronome

The metronome is the audio render thread object that tracks the passage of time, and decides when upcoming commands need to be executed (from user-provided information such as BPM (beats per minute) and a time signature.

Gameplay logic can subscribe to events on the metronome to be notified when musical durations occur.

Quartz Clock Handle

The Clock Handle is the gameplay-side proxy of an active clock. This is acquired via the Quartz subsystem, and used to control the clock running in the Audio Mixer.

Quartz Subsystem

While the Clock Handle provides access to functionality on a specific clock, the Quartz subsystem provides access to functionality that does not relate to a specific clock. This includes creating and getting clocks, seeing if a clock exists, and querying latency information.

AudioComponent: PlayQuantized()

This is a new function added to Audio Components that provides a way to play a sound on a specific clock, with a specified Quantization Boundary.

Create and Initialize Quartz Clocks

Below is a sample workflow:

To create a clock, call Create New Clock on the Quartz Subsystem.

Provide a Clock Name and a Time Signature.

Store the return value as a Blueprint variable. (If a clock by the same name already exists, this will return a handle to the existing clock.)

Set the Tick Rate for the clock by calling one of these functions on the Clock Handle:

Beats per Minute (shown below)

Milliseconds per Tick

Ticks per Second

Thirty-second Notes per Minute



The calls in Step 4 are technically interchangeable; the variations are for convenience, but it is worth noting that each has its own corresponding getter.

Play Sounds on a Quantization Boundary

To play a sound on a Quantization Boundary, call Play Quantized on an Audio Component, and provide a Clock Handle and Quantization Boundary.



The Quartz Quantization Boundary is how you tell the Audio Mixer exactly when you want the sound to begin. This is used in a few other scheduling-related Quartz functions. There are several options in this struct.

Quantization is the time value to be used for scheduling. Possible durations include:

Duration

Description

Bar

Automatically determined by time signature.

Beat

Defaults to the denominator of time signature, but can be overridden.

1/32

Thirty-second notes are the smallest duration available.

1/16, (dotted) 1/16, 1/16 (triplet)

Sixteenth note, dotted sixteenth note, and sixteenth note triplet.

1/8, (dotted) 1/8, 1/8 (triplet)

Eighth note, dotted eighth note, and eighth note triplet.

1/4, (dotted) 1/4, 1/4 (triplet)

Quarter note, dotted quarter note, and quarter note triplet.

Half, (dotted) Half, Half (triplet)

Half note, dotted half note, and half note triplet.

Whole, (dotted) Whole, Whole (triplet)

Whole note, dotted whole note, and whole note triplet. Whole notes are the largest duration available.

Tick

On Tick is the smallest value — the same as a thirty-second note.

Multiplier is the number of Quantization time values until the sound should play. This is a multiplier of the Quantization time value selected.

Counting Reference Point is the reference point used for scheduling the event. Different use cases will want to use different reference points.

Bar Relative — From the start of the current bar. For example, with a drum machine:

Setting Quantization to Beat and Multiplier to 2.0 will schedule the event for the next Beat 2 (second beat in the measure) that occurs.

If the clock is set on Beat 1 of 4 beats to the bar, then the event will trigger on the next beat.

If the clock is set on Beat 3 of 4, then the event will trigger on Beat 2 of the next bar.

Transport Relative — From the time the clock was started, or the transport was last reset. For example, when triggering a musical stem on a 4-bar boundary:

This is used to trigger clips/stems relative to the Transport (song counter).

If the clock is on Bar 6, then the event will trigger on Bar 9 (Transport counting starts from Bar 1).

Current Time Relative — From the current time. For example, for triggering stingers as soon as makes musical sense:

Quantization set to Beat and Multiplier to 2.0 will schedule the event for the downbeat after next.

If the clock is on Beat 1 of 4, then the event will trigger on Beat 3.

If the clock is on Beat 3 of 4, then the event will trigger on beat 1 of the next bar.

With Quartz, a bar is not always a whole note, and a beat is not always a quarter note. See Time Signatures and Pulse Overrides below for more information.

Subscribe to Command Events

When you want to synchronize gameplay logic with a quantized event (such as the onset of a sound you have scheduled to play), you can get notified at different stages of that particular command's life cycle.

To do this, drag a pin off the In Delegate argument for these kinds of functions and create a custom event:



The custom event may be called multiple times for different reasons. In the pictured example, you can break on the Event Type EQuantizationCommandDelegateSubType Enum to respond to the following events:

Event Type

Description

Failed To Queue

The command did not make it to the audio render thread (Play Quantized likely failed concurrency).

Queued

The command has been received by the audio render thread, and is awaiting execution (concurrency passed)

Canceled

The command was canceled on the audio render thread before it was executed (Stop was likely called on the Audio Component before it started playing).

About to Start

The command is about to be executed (this is currently called on the same gameplay frame as Started, but in the future this should be called early enough to compensate for inter-thread latency).

Started

The command has been executed on the audio render thread.

Subscribe to Metronome Events

In addition to subscribing to various stages of a Quantized Command life cycle to synchronize gameplay with audio rendering, you can also get notified each time a Quantization Duration occurs.

In the example below, we subscribe to a bar notification. Each time our event fires, we schedule a sound to play on the following bar:



If you want access to all Quantization Durations in a single event, you can subscribe to all the Quantization Events at once and switch on your Quantization Type Enum:



Time Signatures and Pulse Overrides

Quartz allows for finer control over time signature and meter. As seen in Create and Initialize Quartz Clocks above, when creating a clock, you will need to provide a Time Signature.



A Time Signature has three fields. The first two represent an ordinary time signature:

Num Beats: The number of beats (of the type specified under Beat Types) per measure, or the numerator of the time signature.

Beat Type: Enum representing the duration that gets the beat, or the denominator of the time signature. Possible values are:

Enum

Value

/2

Half note

/4

Quarter note

/8

Eighth note

/16

Sixteenth note

/32

Thirty-second note

Optional Pulse Override, which is the third field, provides a way to specify which durations get the beat throughout the bar. If no Optional Pulse Override is provided, it defaults to Beat Type from the Time Signature.

The Bar Quantization Boundary is intuitively governed by the Time Signature. In 4/4 time, a bar lasts 4 quarter notes, while in 12/8 time, a bar would last 12 eighth notes.

The Pulse Override argument is actually an array of pulse overrides. Each entry lets you specify the Number of Pulses desired at the specified Duration before moving on to the next entry in the array. See the example below:



The Time Signature is 7/8. Without providing an Optional Pulse Override, the Beat Quantization Boundary would be the same as the /8 (eighth note) Quantization Boundary.

But with Quartz, you can specify exactly how long your beats (or pulses) are. In this example, there are two entries in the array, shown under Default Value on the Details panel:



For the 0 value:

Number Of Pulses: 2

Pulse Duration: 1/32

This means our first 2 beats will be a thirty-second note in duration.

For the 1 value:

Number Of Pulses: 1

Pulse Duration: (dotted) 1/4

This means the last beat will be a dotted quarter note in duration.

This enforces a count of (1, 2) (1, 2) (1, 2, 3), where each bold 1 is the eighth note that gets the beat. If your Blueprint subscribes to the Beat Quantization Boundary, this is when that event will be fired.

If you switch the entries around, the count becomes (1, 2, 3) (1, 2) (1, 2).

If the values provide a duration shorter than a bar, the last entry is duplicated to reach the correct length.

If the values provided represent a duration longer than a bar, the list will be truncated, and counting will restart from the beginning of the list on the downbeat of the next bar.

Prerequisites

1 - Create the Soundscape States Data Table

2 - Add the Data Table to the Project Settings

3 - Create a Soundscape Palette and Color

4 - Add the Palette to the Project Settings

5 - Set Up the Palette

6 - Set Up the Color

7 - Place the Trigger Volume

8 - Set Up the Blueprint

9 - Listen to the Results

10 - On Your Own!

Soundscape procedurally generates ambient sounds which are streamed as the player moves around the world. Once set up, the plugin manages and composes these sound systems autonomously and removes the need to manually create them.

In this guide, you'll learn how to set up a basic Soundscape of your own.

Prerequisites



The Soundscape plugin is disabled by default. To enable it, open the Plugin panel by selecting Edit > Plugins, use the search bar to find the plugin, and then click the corresponding checkbox.

A project with a Player Character that supports movement, such as the Third Person Template.

This guide also requires you to have a Sound Wave asset in your project. See Importing Audio Files for information on how to create Sound Waves.

(Optional) Because Soundscape composes sounds in 3D space, using the Attenuation Settings on your Sound Wave produces better spatialized results. For more information on spatialization, see Spatialization and Sound Attenuation.

1 - Create the Soundscape States Data Table

Soundscape uses Gameplay Tags as states. You can control these states using a Blueprint or C++ and Soundscape will respond automatically with the conditions you set.

Create a Data Table asset by clicking Add Content or right-clicking an empty space in the Content Browser and selecting Miscellaneous > Data Table. A Pick Row Structure window appears.



Select GameplayTagTableRow from the dropdown.



Click Ok.

Input "SoundscapeStates" as the name for the Data Table.

Right-click the new Data Table asset and select Edit… from the context menu. A new Data Table Editor window appears.



Click Add to create a new Gameplay Tag.

Change the Tag in the Row Editor panel to "Soundscape.Active".

Save the Data Table.

2 - Add the Data Table to the Project Settings

You must add Gameplay Tags to the central tag dictionary in Project Settings for the engine to be aware of them. For more information about Gameplay Tags, see Gameplay Tags.

Go to Edit > Project Settings… to open the Project Settings panel.

On the left side of the panel, click GameplayTags under the Project heading.

Click Add Element for the Gameplay Tag Table List.

Click the Index [0] dropdown and select the previously created SoundscapeStates Data Table. The Soundscape.Active state now displays in the Gameplay Tag List.



3 - Create a Soundscape Palette and Color

The Soundscape system is driven by two different asset types: Palettes and Colors. A Soundscape Color contains a sound asset reference and behavior properties which control how the sound plays. A Soundscape Palette contains references to Colors and playback conditions which control when the Palette is active.

Create a Soundscape Palette asset by clicking Add Content or right-clicking an empty space in the Content Browser and selecting Sounds > Soundscape > Soundscape Palette.



Input any desired name for the Palette. In general, this name should reflect the condition which activates the Palette.

Create a Soundscape Color asset by clicking Add Content or right-clicking an empty space in the Content Browser and selecting Sounds > Soundscape > Soundscape Color.

Input any desired name for the Color. In general, this name should reflect the content of the sound that the Color will play.

4 - Add the Palette to the Project Settings

You must add Soundscape Palettes to the Soundscape Palette Collection in Project Settings for the engine to be aware of them.

Go to Edit > Project Settings… to open the Project Settings panel.

On the left side of the panel, click Soundscape under the Game heading.

Click Add Element for the Soundscape Palette Collection.

Click the dropdown to select the previously created Soundscape Palette.



5 - Set Up the Palette

Your Palette is in the Collection, but you still need to configure it.

Double-click the Soundscape Palette in the Content Browser to open its Details panel.

Click Edit… located beside Soundscape Palette Playback Conditions. A new Tag Editor window appears.

Click the Root Expression dropdown and select All Tags Match. A new Tags entry appears.

Click the Tags dropdown and select Soundscape.Active.

Click Save and Close at the top-left of the Tag Editor window.



Click Add Element for the Colors.

Click the arrow at the left of Index [0] to expand that section.

Click the Soundscape Color dropdown and select the previously created Soundscape Palette for Index [0].

Save the Soundscape Palette.



6 - Set Up the Color

Now that your Color is in the Palette, add a sound and some behavior to your Color.

Double-click the Soundscape Color in the Content Browser to open its Details panel.

Select the dropdown for Soundscape > Color > Sound and select the Sound Wave asset that you want to play.



Enable the checkbox for Modulation Behavior > Randomize Pitch. This randomizes the pitch of the sound each time it plays.

Enable the checkbox for Spawn Behavior > Continuously Respawn. This spawns the sound continuously.

Enter 50.0 for Spawn Behavior > Max Spawn Distance. This spawns the sound closer to the listener.

Save the Soundscape Color.



7 - Place the Trigger Volume

The sound within your Color will play when your Palette's condition is met. That condition will be met when the GameplayTag Soundscape.Active is set. By using a Blueprint or C++, you can set the state however you want, but for this guide, use the Level Blueprint and a Trigger Volume to define a region of your level in which to play your Soundscape.

Place a Trigger Volume in your level by using the Place Actors panel or by clicking Quick Add in the Level Editor Toolbar and selecting Volumes > Trigger Volume.



Adjust the position, size, and shape of the Trigger Volume within the level so that your character can move into and out of it.



8 - Set Up the Blueprint

Select the Trigger Volume.

Click the Blueprint button in the Level Editor Toolbar and select Open Level Blueprint.



Right-click an empty space on the graph and add an On Actor Begin Overlap node for the Trigger Volume.

Right-click an empty space on the graph and add an On Actor End Overlap node for the Trigger Volume.

Right-click an empty space on the graph and add a Get SoundscapeSubsystem node.

Drag a pin connection from the Soundscape Subsystem to an empty space on the graph and add a connected Set State node.

Drag a pin connection from the Soundscape Subsystem to an empty space on the graph and add a connected Clear State node.

Connect the execution pin for the On Actor Begin Overlap node to the Set State node.

Connect the execution pin for the On Actor End Overlap node to the Clear State node.

Save the Level Blueprint.



9 - Listen to the Results

Click the Play Level button in the Level Editor Toolbar.

Move your character into your Trigger Volume and stop.

Listen to your new Soundscape!

The following console commands may be useful as you continue to develop your Soundscape:

au.debug.sounds 1: Displays a list of all of the active sounds in your level and related information in your viewport.

au.3dVisualize.Enabled 1: Displays the location of active sounds in 3D space.

For more information on Audio Console Commands, see Audio Console Commands.



10 - On Your Own!

Now that you've finished creating a basic Soundscape, consider building it out even further.

Below are some suggestions you can explore on your own:

Create more SoundscapeStates to support additional conditions within your level.

Use Blueprints or C++ to script additional logic for other ambient situations, such as time of day.

Play with the details of your Colors and Palettes to change their behaviors.

Add more Colors to your Palette to layer additional sounds.

Add more Palettes to your Soundscape to use on their own or to layer with your existing Palettes.

Instead of a Sound Wave, use a MetaSound Source for your Color. See MetaSounds for more information.

Audio Engine Overview

Required Knowledge and Setup

Creating Dialogue Voices

Building Dialogue Waves

Setting the Context

Enabling Subtitles

This tutorial will show you how to create a basic dialogue setup in Unreal Engine by using MetaHumans as in-game characters. You will also learn how to use Dialogue Voices and Dialogue Waves to adjust a character's tone depending on who they are speaking to.

For longer conversations, you will likely want to create a conversation manager system.

Required Knowledge and Setup

This page requires basic knowledge of Animation Blueprints in Unreal Engine.

Before you can follow the steps outlined on this page, create a new Unreal Engine project based on the Third Person Template.

Downloading and Exporting the MetaHumans

Open Quixel Bridge and download three MetaHumans. This tutorial uses the Ada, Cooper and Hana Presets. You can download multiple MetaHumans at the same time.

After downloading them to your local machine, import the MetaHumans to your project.



You will find your downloaded MetaHuman files in the MetaHumans > [MetaHumanName] folder inside the Content Browser. For example, the location for Ada will be MetaHumans > Ada.



If you need help completing this step, refer to the MetaHumans Getting Started page.

Animating the MetaHumans

After successfully importing your MetaHumans, you can set them up to be used as in-game characters. Follow the Runtime Animation Retargeting guide to learn how to retarget the animations from the UE5 Mannequin to a MetaHuman at runtime.

After completing the guide, you will have controllable Blueprints for each MetaHuman that you can use as playable characters in your level.



Click image for full size.

Refer to the Animating MetaHumans section of the documentation to learn more about animating MetaHumans. This section includes guides on creating Animation Blueprints and Assets, animation retargeting, using Control Rig and using facial rigs.

Creating Dialogue Voices

In this tutorial, Ada will be a quest NPC and Cooper and Hana will be playable characters.

Here is a snippet of an example design document:

Cooper is a mercenary who prefers stealth over direct confrontation.

Hana is an ex-soldier who joined Cooper's team after the last major Galactic Skirmish.

Ada is a soldier who wants to hire someone from Cooper's team as backup on a supply escort mission.







Ada (Quest NPC)

Cooper

Hana

First you need to add a Dialogue Voice variable to each of your MetaHuman characters. In the Content Browser, double-click Ada's Blueprint you created in the previous section. In this example, the Blueprint is called BP_AdaCharacter.



Add a new variable by clicking the Add (+) button.



Name the new variable DialogueVoice, then set its type to a DialogueVoice Object Reference. Compile and save the Blueprint. Repeat the process for the other character's Blueprints.



Now, you will create Dialogue Voice Assets to use for each of the characters. In the Content Browser, right-click and select Sounds > Dialogue > Dialogue Voice.



Name the new Asset Ada, then open it by double-clicking.



Referring to the design document, Ada's voice is Feminine and Singular. Click the dropdown and set the Gender and Plurality accordingly.



Repeat the process two more times to create a Dialogue Voice Asset for Cooper that is Masculine and Singular, and a Dialogue Voice Asset for Hana that is Feminine and Singular.



Save and close all your Dialogue Voice Assets.

You will now associate the Dialogue Voice Assets with their respective MetaHumans.

Switch to the BP_AdaCharacter Blueprint. Select the DialogueVoice variable and go to the Details panel. Set the Dialogue Voice property to Ada.



Repeat the process and set the Dialogue Voice properties for Cooper and Hana.



(Optional) Add a custom thumbnail to each Dialogue Voice Asset.

Place your character in the world and frame them in the viewport. Right-click the Dialogue Voice Asset in the Content Browser. Select Asset Actions > Capture Thumbnail. This will add the MetaHuman to the thumbnail for each of the Dialogue Voice Assets.



Building Dialogue Waves

This example implements a greeting from Ada to Cooper and Hana. Each line of dialogue needs a Dialogue Wave Asset associated with it.

In the Content Browser, right-click and select Sounds > Dialogue > Dialogue Wave to create a new Dialogue Wave Asset.



Name the new Asset QuestGreeting, then open it by double-clicking.

For the Spoken Text, enter "Hey! Could you come over here? I need your help with something important." Although the same text is spoken when Ada is talking to Cooper and Hana, the game design document gives us some hints that the way the text is spoken may be different for each listener. That means you need to set up two different Dialogue Contexts.



One context is already created by default. Fill in the Speaker entry with Ada. Click the Add (+) icon to add a listener. Set the Directed At property to Cooper.



Click Add Dialogue Context to add a new Dialogue Context.



Set this context's Speaker to Ada, and Directed At to Hana.



You can also make some notes about how the voice actor should sound friendlier toward Hana, as they have a shared military background, and be more abrupt with Cooper, who she doesn't trust because of his mercenary past. Enter these notes in the Voice Actor Direction field.



Finally, after the voice actor recordings come back, you can import those as Sound Waves and set them in the Sound Wave field for each context. You can create new Sound Waves or use Sound Waves from the Starter Content for testing purposes.



The Dialogue Wave is also where you can set a Subtitle Override. This is useful for effort sounds, as well as some other cases, such as characters speaking in a foreign language not known to the player.

Setting the Context

Now that you have your Dialogue Voices and Dialogue Wave set up, you can add logic to the Ada Blueprint to create the right context for her greeting.

A Dialogue Context involves at least two Dialogue Voices, a Speaker and at least one Dialogue Voice that the dialogue is Directed At.

Add a Box component to the BP_AdaCharacter Blueprint.



In the Viewport, scale the Box component so it is about the height of the character, and extends some distance in front of her. Make sure it doesn't overlap her, or she will trigger the conversation logic herself.



Add a new Dialogue Wave variable named Greeting.



Compile your Blueprint and set the Default Value of Greeting to the QuestGreeting Dialogue Wave you made previously.



Set up the following Blueprint graph.



Click image for full size.

This graph:

Executes after something overlaps the Box component.

Casts the Overlapping Actor to the BP_HanaCharacter and BP_CooperCharacter Blueprints, where you added the Dialogue Voice variable.

Gets the voice from the Overlapping Actor and uses it as the Target for your Dialogue Context.

Uses Ada's voice as the Speaker for your Dialogue Context.

Plays the Dialogue Wave named Greeting at Ada's location, using the correct Dialogue Context.

The Blueprint graph above is used for illustration purposes only and does not demonstrate best practices. We recommend using Blueprint Interfaces or another method of Actor communication to accomplish that functionality.

Open the World Settings and expand the Selected GameMode option under the Game Mode section. Set the Default Pawn Class to BP_CooperCharacter or BP_HanaCharacter.



Now, if your quest NPC is placed in the level, you can run up to them with either Cooper or Hana and trigger the dialogue.

Enabling Subtitles

Subtitles are enabled by default, but if you need to verify this, follow these steps:

Click Settings > Project Settings to open Project Settings.



Under General Settings, locate the Subtitles section and make sure the Subtitles Enabled checkbox is enabled.



Now, when you trigger a quest NPC's dialogue, the accompanying subtitle text appears at the bottom of the screen.



Subtitles will not display unless there is a Sound Wave set in your Dialogue Wave for the context that is currently happening.

Prerequisites

1 - Open the Waveform Editor

2 - Get Familiar with the UI

3 - Trim Fade

4 - Normalize

5 - Export the Edits

Result

Using the Waveform Editor, you can edit Sound Waves with basic transformations, such as trim fade and normalization.

The Waveform Editor is not intended to replace a traditional digital audio workstation (DAW).

Prerequisites



The Waveform Editor plugin is disabled by default. To enable it, open the Plugin panel by selecting Edit > Plugins, use the search bar to find the plugin, and then select the corresponding checkbox.

This guide also requires you to have a Sound Wave asset in your project. See Importing Audio Files for information on how to create Sound Waves.

1 - Open the Waveform Editor



To edit your Sound Wave asset, you need to open the Waveform Editor.

Right-click the Sound Wave file you want to edit in the Content Browser.

Select Edit Waveform from the context menu. This opens the Waveform Editor in a new window.

2 - Get Familiar with the UI



Now that you have the Waveform Editor open, take a moment to get familiar with the user interface.

File Controls: Save the current Sound Wave or locate it in the Content Browser.

Transport Controls: Play, pause, and stop the active Sound Wave.

Zoom Controls: Zoom the waveform in or out.

Export Options: Export the current edits to another Sound Wave asset or change the channel format (mono or stereo).

Processing Panel: View or apply waveform transformations.

Details Panel: View or modify the Sound Wave asset details.

Time Ruler: Display the timing of the current Sound Wave or track and change playback by moving the playhead.

You can change colors, line thickness, and other display settings for the Waveform Editor in Editor Preferences > Waveform Editor Display.

3 - Trim Fade



You can use the Trim Fade transformation to edit timing and add fades to the beginning and end of a sound.

Find the Transformations array in the Processing panel.

Click Add Element to add a transformation to the array.



The Add Element button

Select Waveform Transformation Trim Fade from the new index's dropdown.

Expand the transformation properties by clicking the arrows on the left of the index, the Trim group, and the Fade group.

Change the Trim properties to your liking.

Start Time: The time (in seconds) to start the trimmed sound.

End Time: The time (in seconds) to stop the trimmed sound.

Change the Fade properties to your liking.

Fade-In Duration: The duration (in seconds) of the fade-in.

Fade-In Curve: The shape of the fade-in.

Fade-Out Duration: The duration (in seconds) of the fade-out.

Fade-Out Curve: The shape of the fade-out.

You can use your mouse to control the properties of the Trim Fade transformation.

Drag the trim boundary to change the Start Time and End Time.

Drag from the top-left corner to change the Fade-In Duration.

Drag from the top-right corner to change the Fade-Out Duration.

Scroll the mouse-wheel over a fade line to change the Fade Curve.

4 - Normalize



You can use the Normalize transformation to apply a constant amount of gain to target a maximum volume level. By doing this after the Trim Fade transformation, the normalization will apply only to the trimmed section of the waveform.

Find the Transformations array in the Processing panel.

Click Add Element to add another transformation to the array.

Select Waveform Transformation Normalize from the new index's dropdown.

Expand the Transformation properties by clicking the arrows on the left of the index and the Normalization group.

Change the Normalization properties to your liking.

Target: The target maximum volume (in decibels).

Max Gain: The maximum gain to apply.

Mode: The type of analysis used to find the peak value.

5 - Export the Edits



Once you've made your edits, you can export the edited waveform to a new Sound Wave asset.

Click Export Options and select your desired channel format.



The Export Options button

Click the Export button. A Save Content window appears.



The Export button

Click Save Selected in the Save Content window.

Using the Content Browser, you can now find the new edited Sound Wave asset in the same directory as the original with _Edited appended to its original name.

If you want to rename the asset, right click and select Rename from the context menu.

Result

Your edited Sound Wave asset is now ready for use in your project.

You can set default transformations to be applied every time the Waveform Editor is opened within Editor Preferences > Waveform Editor Transformations.

Supported Audio Files

How to Import an Audio File

Compression

Unreal Engine provides several features for you to create the desired audio for your project. Sound Wave assets are representations of audio files and are one of the basic building blocks required to work with many of those features. You can create Sound Waves by importing audio files into the Unreal Editor.

Supported Audio Files

Format

.wav, .ogg, .flac, .aif

Bit Depth

16, 24 (Windows)

Sample Rate

Any

Speaker Channels

Mono, Stereo, 4.0, 5.1, 7.1

All imported audio files are converted to 16-bit .wav files internally. As such, exporting (by right-clicking a Sound Wave and selecting Asset Actions > Export...) will produce the converted file and not the originally imported file. Additionally, 24-bit files are not dithered during conversion so importing 16-bit files is recommended.

How to Import an Audio File

In the Content Browser, click the Import button.



Select the file you wish to import using the File Explorer.

Find the newly created Sound Wave asset.



To preview the Sound Wave, hover over it until a Play/Stop toggle button appears and click it.



Double-click the Sound Wave to open the Details panel. You can view and edit the properties of your asset here.



You can also import audio files by dragging them from Windows Explorer directly into the Content Browser.

Unreal Engine also supports importing first-order ambisonic files. See Native Soundfield Ambisonics Rendering for information on importing and using ambisonic assets.

Compression

All audio assets are compressed with the Default Audio Compression Type specified in the Project Settings. You can change this to suit your project's needs.

Bink Audio: A perceptual-based codec which supports all features across all platforms. This is the default option.

ADPCM: A time-domain codec that has fixed-sized quality and a compression ratio around 4x, but is relatively cheap to decode.

PCM: Uses uncompressed audio which results in higher memory usage as streamed chunks contain less audio per chunk, but provides extremely cheap decoding and support for all features.

Platform Specific: Encodes the asset in a platform-specific format. Seeking is not supported.

Introducing MetaSounds

A Fully Procedural Audio Engine

More Control for Audio Designers

Sample-Accurate Control of Audio

Improved Workflow

Increased Performance

Growing Node Library

Portable and Extensible

Rich Gameplay Interactions

Introducing MetaSounds

Unreal Engine 5 introduces MetaSounds, a high-performance audio system that provides audio designers with complete control over a Digital Signal Processing (DSP) graph for the generation of sound sources.

MetaSounds offer user customization, third-party extensibility, graph re-use, and a powerful tool for in-editor sound design.

A Fully Procedural Audio Engine

Unlike Sound Cues, MetaSounds are fundamentally a Digital Signal Processing (DSP) rendering graph. They provide audio designers with the ability to construct powerful procedural audio systems that offer sample-accurate timing and control at the audio-buffer level.

Using MetaSounds, audio designers can generate audio synthetically at runtime and freely mix and match procedurally generated sound with other audio sources.

MetaSounds are also designed to easily integrate with game data and player interactions to create immersive experiences triggered by gameplay events.

More Control for Audio Designers

Each MetaSound is its own audio rendering engine. They render in parallel with each other and have potentially independent rendering formats (e.g. sample rate, buffer size, channel count).

MetaSounds are created in a new MetaSound Editor where audio designers with no programming experience can create procedural sounds using a node-based interface. The editor enables the live previewing of all audio input parameters, and contains several ready-made nodes that provide detailed control options for the entire audio rendering pipeline.

The MetaSound editor features a real-time meter on the output, in-graph widgets to control and visualize parameters (knobs and sliders), and buttons to interact with events in real time.

Sample-Accurate Control of Audio

MetaSounds offer sample-accurate control of audio sources. Sample accuracy refers to the ability for timing to be on the order of a single sample of audio. In other words, if the sample rate is 48,000 samples per second, a sample-accurate event would have a timing resolution of 1/48,000 seconds, or 0.02 milliseconds.

MetaSounds support sample-accurate control in several ways. MetaSound triggers execute sample-accurate events within the graph. Triggers can originate from gameplay events, MetaSound nodes, or the graph itself.

The MetaSound Wave Player node features sample-accurate concatenation.This means that, when the playing sound wave finishes playing, it will seamlessly play the next queued-up sound wave without audible hitches or interruptions.

Many MetaSound node parameters can be modulated by audio buffers, allowing for "audio-rate" parametric modulation. This enables powerful synthesis and sound design techniques.

Improved Workflow

With MetaSounds, you can re-use and reference their graphs through presets. Presets reference an existing MetaSound graph, and you can override the graph's inputs.

This can result in a significant boost in productivity as you now have a single graph with different presets which reference a base graph. The presets will contain the unique differences for the same base graph. Without presets, you would have to manage hundreds of potentially similar graphs to account for different variations.

Another benefit of using presets is the ability to update the base graph and have the changes automatically propagate to any preset that references that graph. This can also result in significant productivity gains throughout the development process.

In addition to presets, MetaSounds also features graph composition, which is the ability to use MetaSounds directly inside other MetaSound graphs. Custom MetaSound nodes can also be created and used inside any other MetaSound graph. These custom nodes can define their inputs and outputs, and provide tooltip and versioning information.

This way, you can build up a library of common functionality nodes and re-use them across multiple graphs. Similar to presets, custom MetaSound nodes will automatically propagate their changes across any MetaSound that references them, further increasing productivity in a complex and changing project.

Increased Performance

MetaSounds are rendered asynchronously to the main Audio Mixer using the same architecture and tasks used for asynchronously decoding sound sources.

Each MetaSound DSP graph is automatically converted to an optimized static, non-virtual C++ object, with data between nodes passed by reference and not copied. This avoids common disadvantages to this type of system, such as interpreted bytecode runtime, expensive virtual function overhead, and data copying.

Growing Node Library

MetaSounds ship with a growing library of MetaSound nodes, which provide a wide variety of powerful options for procedural sound design and music.

The library features a rich Wave Player node, which supports seeking, loop points, sample-accurate concatenation, pitch-scale modulation, and reading from cue-points in an audio file.

Other nodes include a diverse library of Trigger utilities, DSP math operations, DSP filters, dynamics processing, spatialization, real-time synthesis generators, and so on.

Portable and Extensible

MetaSounds can be extended by third-party plugins using its C++ Node API.

Creating a new node for the MetaSound Editor involves creating a C++ class where the programmer defines the node's inputs and outputs, and an execution callback. This class also contains the actual audio rendering code and logic. A new node can be written in a single ‘.cpp' file in only a few hundred lines of code.

Rich Gameplay Interactions

MetaSounds accept custom user input parameters, similar to the input parameters used in Materials and Niagara VFX systems. These parameters can be connected to gameplay systems through the Audio Component parameter interface, either directly in Blueprint, or in gameplay C++ code.

MetaSounds have also been integrated with the Parameter Modulation Plugin, which is an optional plugin that provides a system to write into a modulation bus asset from any modulation source (including from Blueprint). MetaSounds can now read from the parameter buses, which means you can use them to modulate any MetaSound system.

Asset Types

Presets

Adding Nodes

Pin Types

Connections

Input and Output Nodes

Constructor Pins

Variable Nodes

Interfaces

Graph Nodes

Conversion Nodes

Comments

Function Nodes

General

Array

Debug

Delays

Dynamics

Envelopes

External IO

Filters

Generators

Math

Mix

Music

Random

Spatialization

Triggers

Value

The MetaSound Editor is where MetaSounds are created, modified, and previewed. The MetaSound Graph, contained within the MetaSound Editor, is composed of a variety of pins and nodes which make up the design of every MetaSound.

The MetaSound Graph functions a bit differently than the graph found in Blueprints. In Blueprints, the graph functions as an execution graph, while in MetaSounds, the graph functions as a flow graph.

The pin and node types listed in this document are built-in types, but you can add your own types by using the C++ API.

Asset Types



MetaSounds have two main asset types: MetaSound Source and MetaSound Patch. These two types are identical in terms of graph manipulation; however, only MetaSound Sources can generate audio on their own. MetaSound Patches are intended to be referenced by other MetaSounds to encapsulate and reuse functionality.

You can create a MetaSound asset by clicking the Add button in the Content Browser and selecting Sounds > MetaSound Source or Sounds > MetaSounds > MetaSound Patch. You can edit a MetaSound asset in the MetaSound Editor by double-clicking it in the Content Browser or by right-clicking it and selecting Edit… from the context menu.

Presets

MetaSound Presets are a special type of asset that inherits a read-only graph from a parent MetaSound and provides the ability to override default Input values. This allows you to create multiple versions of the same MetaSound with different sets of Inputs, which can be helpful to decrease graph duplication.

Any changes to the parent MetaSound asset will be reflected in the child Presets. This ensures consistency among the affected assets and reduces the workload associated with applying changes in multiple MetaSounds.

You can create a MetaSound Preset in the Content Browser by right-clicking on the MetaSound Source or Patch you wish to be the parent, and then selecting Create MetaSound Preset from the context menu. In the MetaSound Editor, you can modify a Preset's Input values by selecting an Input in the Members panel, enabling Default Value > Override Inherited Default in the Details panel, and then changing the Default Value > Default.

If you want to convert a MetaSound Preset into a standard MetaSound asset, you can click the Convert From Preset button on the toolbar at the top of the MetaSound Editor.

Adding Nodes



You can add nodes to your graph by right-clicking empty space in the graph and selecting the desired node type from the context menu. You can also drag a pin connection into empty space to create a connected node.

The context menu is equipped with a search box you can use to find node types by name and tag. For example, searching for "synth" will find nodes with names containing "synth" but also nodes relevant to synthesis.

Pin Types

MetaSound nodes interact with a variety of data types through pin connections, both individual (circle connector) and array (block connector).

Pin Type

Description

Trigger

Comparable to modular synthesis triggers and are used to execute other nodes, similar to execution pins in Blueprints. They can be connected to multiple (or even zero) other nodes at once.

Audio

Represent an actual audio buffer that can be manipulated by MetaSound nodes. In some instances, these pins may be parameters intended to be consumed at audio-rate, such as for frequency modulation synthesis.

Time

Represent a time value (in seconds).

String

Provide labeling and debugging functionality. These pins are not directly used during playback, but are useful for relaying information to the audio designer, such as outputting node information to the console log.

UObject

Represent a supported UObject type, such as USoundWave which is commonly used to provide the Wave Player node with a reference to the asset to be played.

Bool

Represent a boolean variable.

Float

Represent a floating-point number variable.

Int32

Represent an integer (4 bytes) variable.

Enum

Represent an enumerated variable.

When Trigger nodes are triggered through timing nodes or through gameplay events, they are sample-accurate and will execute on a precise sample index in the audio rendering block. However, since other node types do not operate at audio rate, a Trigger input may generate a block rate output if it is connected to another node type.

Connections



The connections between nodes are visualized on play to make understanding their behavior easier. Trigger connections pulse when they activate, Audio connections change in thickness with signal strength, and Float connections color shift based on value.



Float connection visualization is disabled by default. While the MetaSound is playing, you can enable it by hovering your mouse cursor over the connection until a context menu appears. The context menu provides a toggle to enable or disable visualization, two numeric inputs to define the expected value range, and two color inputs to blend between.

Additional visualization settings are available in Editor Preferences > MetaSound Editor > Graph Animation.



You can use Reroute nodes to keep your connections organized. MetaSound Reroute nodes function similarly to those found in Blueprints. You can create one by double-clicking a connection. Afterwards, you can move it by dragging the border that appears while it is selected. You can make additional connections from the node by dragging from the node itself.



You can also organize your graph with Alignment and Distribution operations by selecting all relevant nodes, right-clicking a selected node, and then selecting the desired operation from the context menu.

Input and Output Nodes



Input and Output nodes provide access to pins that typically begin or end a data flow through a MetaSound. For example, every MetaSound Source asset starts with an On Play Input node and an On Finished Output node. The On Play Input node has a Trigger pin output used to signal other nodes to begin when the MetaSound plays, and the On Finished Output node has a Trigger pin input used to receive a signal when the MetaSound finishes playing.

The On Finished Output node is added to the graph by the UE.Source.OneShot Interface, which is enabled on new MetaSound Sources by default. If the On Finished node is not triggered, the MetaSound will play indefinitely. To create a sound with an indefinite duration, such as for music or ambience, remove the UE.Source.OneShot Interface in the Interfaces panel.



Some of the Output nodes, such as Out Left, correspond to an audio channel output. Each MetaSound has an Output Format setting to support different audio channel configurations, including Mono, Stereo, Quad (4.0), 5.1, and 7.1. You can find the setting by clicking the MetaSound button located next to the Play button, and then checking the Details panel.

You can create additional Inputs and Outputs in the Members panel of the MetaSound Editor. Afterwards, you can set the desired properties, such as Display Name and Type, in the Details panel. Next, you can create a new node instance by right-clicking an empty space in the graph and selecting the corresponding Get Input or Set Output node option from the context menu. You can also drag the Input or Output from the Members panel into the graph to create the new Input node instance.



You can use a Slider or Knob widget on Float and Time Input nodes to easily change values while the MetaSound is playing for a much smoother workflow. This is set in the Details panel (with the Input selected), under Editor Options > Widget. You can also change the Range, Orientation (for Sliders), and Value Type in the panel.

Constructor Pins



Constructor pins are indicated by diamond-shaped icons. They have read-only values which can improve the performance of a MetaSound by not dynamically updating at runtime. In this way, they are similar to the const declaration in C++.

You can make pins on Input and Output nodes into constructor pins by checking the Is Constructor Pin checkbox in the Details panel. All data types (including array types) that support copy assignment and construction can support constructor pins. However, Trigger and Audio types cannot be constructor pins.

You can only set Constructor pin values before playing the MetaSound. You can do so in the Details panel or by using the SetParameter node in Blueprint.

Connection constraints apply when working with constructor pins. You can connect an output constructor pin to both constructor and non-constructor input pins, but an input constructor pin can only be connected to constructor output pins.

You cannot override Constructor pin status on MetaSound Presets.

Variable Nodes



You can use Variable nodes to access and manipulate variables that support Function nodes in your MetaSound. Three node types exist for each individual variable in your asset: Get Variable, Get Delayed Variable, and Set Variable. Get Variable and Set Variable provide immediate read or write access to the associated variable, whereas Get Delayed Variable delays the read by a block and can be used to mitigate cycles.

Changes to Variables are not registered while a MetaSound is playing. Use Inputs instead to allow for value changes during playback.

Like Inputs and Outputs, Variables can be created in the Members panel of the MetaSound Editor and their properties set in the Details panel. You can create Variable node instances using the right-click context menu in the graph, but only the Get Variable node can be created by dragging from the Members panel.

MetaSound Variables cannot be accessed by Blueprints.

Interfaces

Interfaces allow MetaSounds to work with other systems within the Unreal Audio Engine by providing access to specialized Inputs and Outputs. You can add or remove an Interface from your MetaSound from the Interfaces panel of the MetaSound Editor.

The following Interfaces are available:

UE.Source.OneShot - Allows you to create one-shot sounds by providing an On Finished Output which stops the MetaSound when triggered. This Interface is added by default and should be removed on MetaSounds with indefinite durations.

UE.Attenuation - Provides a Distance Input with a value based on the distance between the MetaSound and the listener.

UE.Spatialization - Provides Azimuth and Elevation Inputs with values based on the MetaSound's position in relation to the listener.

Graph Nodes



Graph nodes allow for composition capability as they provide an access point to the graphs of other MetaSounds in your project. These nodes have connection pins based on the Inputs and Outputs of another MetaSound, so you can use them to influence the design of the MetaSound containing it.

Graph nodes can provide many workflow improvements. You can use them to:

Reduce the complexity and size of MetaSounds by separating the functionality into several smaller MetaSounds.

Reuse functionality from existing MetaSounds and eliminate the need for duplication.

Simultaneously alter MetaSounds containing the same Graph node by changing the referenced graph.

When using Graph nodes representing a MetaSound Patch, you must use a MetaSound Source in the composition to be audible.

Conversion Nodes



Conversion nodes change one pin type into another supported pin type, similar to Blueprint conversion nodes.

From

To

Audio

Float

Bool

Float or Int32

Float

Audio, Bool, Int32, or Time

Frequency Multiplier

Semitone

Int32

Bool, Float, Time, or Enum

Semitone

Frequency Multiplier

String

Transmission:Address

Time

Float or Int32

Enum

Int32

Comments



Putting comments in your graph is a great way to organize and document your design. You can add a comment box to your graph by right-clicking empty space and selecting Add Comment from the context menu, or by selecting multiple nodes, right-clicking, and then selecting Create Comment from Selection from the context menu. Afterwards, you can change the comment by double-clicking the text to select it and typing your desired comment.

The comment box's size can be adjusted by dragging the handle displayed on the lower-right corner. You can also change the color of a comment box by selecting it and modifying the Comment Color property in the Details panel.

By default, moving comment boxes in the graph moves all of the contained nodes as well. If desired, you can remove this behavior by changing the comment box's Move Mode to Comment in the Details panel.



You can also put Comment bubbles on individual nodes by hovering your pointer over the node and selecting the comment bubble button that appears at the top-left corner, or by right-clicking the node and inputting the desired comment into the Node Comment text box.

Function Nodes

Function nodes come in a large variety of types and provide the functionality required to play audio files, mix sounds, apply filters and effects, and more.

General



The BPM To Seconds node calculates a beat time in seconds from the given beats per minute (BPM), beat multiplier, and divisions of a whole note.

Input

Description

BPM

The input target BPM.

Beat Multiplier

The multiplier value to apply to the BPM.

Division of Whole Note

The divisions of a whole note.

Output

Description

Seconds

The output beat time in seconds.



The Envelope Follower node outputs an envelope from an input audio signal.

Input

Description

In

The input audio signal.

Attack Time

The attack time (in seconds).

Release Time

The release time (in seconds).

Peak Mode

The following-method of the envelope follower:

MS: Envelope follows a running Mean Squared of the audio signal.

RMS: Envelope follows a running Root Meat Squared of the audio signal.

Peak: Envelope follows the peaks in the audio signal.

Output

Description

Envelope

The output envelope value (block rate).

Audio Envelope

The output envelope value (audio rate).



The Flanger node applies a flanger effect to the input audio.

Input

Description

In Audio

The input audio signal to apply the flanger effect to.

Modulation Rate

The Low-Frequency Oscillator (LFO) rate that varies the delay time (in Hz). This value is clamped at block rate.

Modulation Depth

The LFO amplitude (strength) that scales the delay time.

Center Delay

The center delay amount (in milliseconds).

Mix Level

The balance between original and delayed signal. The value should be between 0 and 1.0. For example, a value of 0.5 uses equal amounts of each signal and a value greater than 0.5 uses more delayed signal than non-delayed signal.

Output

Description

Out Audio

The output audio signal with the flanger effect applied.



The Get Wave Duration node returns the duration of an input Sound Wave asset (in seconds).

Input

Description

Wave

The Sound Wave asset to get the duration of (in seconds).

Output

Description

Duration

The duration of the Sound Wave asset (in seconds).



The Get WaveTable From Bank node retrieves (or generates an interpolated) WaveTable from a given WaveTable Bank asset.

Input

Description

WaveTableBank

The WaveTable Bank asset to retrieve or generate an interpolated WaveTable from.

TableIndex

The index of the WaveTable to retrieve. If set between two whole values, the WaveTables located at the two closest indices are mixed together. The value will be adjusted to loop if it is set beyond the range of the WaveTable Bank. For example, if the WaveTable Bank has 3 indices, a value of 3.0 will retrieve the WaveTable at index 0.

Output

Description

Out

The retrieved WaveTable.



The InterpTo node interpolates between the current value and a target value over a specified time.

Input

Description

Interp Time

The time to interpolate from the current value to the target value.

Target

The value to interpolate to.

Output

Description

Value

The current value.



The RingMod node performs ring modulation with a carrier signal and a modulator signal.

Input

Description

In Carrier

The carrier audio signal.

In Modulator

The modulator audio signal.

Output

Description

Out Audio

The modulated audio signal.



The Wave Player node is used to play a Sound Wave asset. There are multiple versions of this node in order to support several different channel configurations, such as Mono, Stereo, Quad (4.0), 5.1, and 7.1.

Input

Description

Play / Stop

The Play and Stop triggers start and stop the Wave Player playback at a sample-accurate moment in time.

Wave Asset

The Sound Wave asset played by the Wave Player during playback. This asset uses the same real-time decoders as all other sound sources in Unreal Engine.

Start Time

The time within the Sound Wave asset to begin playing the audio file. This is also referred to as seek time.

Pitch Shift

The Pitch Shift to use for the Wave Player. This is defined in units of semitones to account for the non-linear nature of frequency scaling.

Loop

Whether the Wave Player will loop the audio file or stop when it's finished. This can be toggled at any time during playback from the graph.

Loop Start

The Loop Start indicates at which point in time the Wave Player will loop the audio file.

Loop Duration

The Loop Duration represents the total time the loop will play. Any value other than -1 sets the end point of the loop to the sum of the Loop Start and Loop Duration values, while a value of -1 loops the entire audio file.

Output

Description

On Play

Triggers when the Wave Player's Input Play pin is triggered.

On Finished

Triggers when the Wave Player finishes playing the audio file. This pin will trigger on the same sample point where the audio file finishes playing.

On Nearly Finished

Triggers on the audio rendering block before the audio file is expected to finish playback. This is commonly used to loop back and pick a new audio file variation for the Wave Player.

On Looped

Triggers on the sample where a sound looped based on the looping settings.

On Cue Point

Triggers when a cue point has been parsed in the Wave Player. Cue points are metadata embedded in audio wave files on import.

Cue points are often used by sound designers to trigger events or loop points in their audio at exact points in time. With this feature, sound designers can procedurally trigger MetaSound behavior based on embedded data in the imported audio wave file.

This pin is executed with sample accuracy, but the integer and label associated with the cue point is read at the block rate. Cue points in the audio wave file that are closer together than the block rate of the MetaSound will only trigger on the last cue point in that block.

Cue Point ID

The ID of the cue point as parsed from the imported audio wave file.

Cue Point Label

The label of the cue point as parsed from the imported audio wave file.

Loop Percent

The current location in the audio wave file within the given loop region.

Playback Location

The current location in the audio wave file as a fraction of the total length of the audio wave file.

Out X

The X channel output of the input Sound Wave asset.

In the case of mono file playback, the audio in the right and left channels are up-mixed using mono-channel duplication.



The WaveShaper node applies a non-linear shaping to the input audio signal.

Input

Description

In

The input audio signal to apply the non-linear shaping to.

Amount

The amount of the non-linear wave shaping to apply.

Bias

The DC offset to apply before wave shaping.

OutputGain

The amount of gain to apply after processing.

Type

The type of algorithm to use to process the audio: Sine, Inverse Tangent, Hyperbolic Tangent, Cubic Polynomial, or Hard Clip

Output

Description

Out

The output audio signal with the non-linear shaping applied.

Array

Array functions provide options to manipulate arrays within a MetaSound. Each of these functions have different versions which allows them to support arrays of several common data types, including: Bool, Float, Int32, String, Time, Transmission:Address, AudioBusAsset, WaveTableBankAsset, and WaveAsset.



The Concatenate node concatenates two arrays on a given trigger.

Input

Description

Trigger

The trigger on which to concatenate the input arrays.

Left / Right Array

The input arrays.

Output

Description

Array

The concatenated array.



The Get node retrieves an element from an array at the given index.

Input

Description

Trigger

The trigger on which to retrieve the specified array element.

Array

The array from which to retrieve an element.

Index

The index of the element to retrieve.

Output

Description

Element

The value of the retrieved element.



The Num node returns the number of elements in the given array.

Input

Description

Array

The array whose elements will be counted.

Output

Description

Num

The number of elements in the given array.



The Random Get node randomly retrieves elements from an input array. Optionally, an array of weights can be supplied to adjust the randomness.

Input

Description

Next

The trigger on which to get the next random value in the array.

Reset

The trigger on which to reset the randomization seed for the array.

In Array

The input array from which to randomly retrieve elements.

Weights

(Optional) An input array of weights used to define the probability of each entry retrieved. If not provided, an even probability for all elements is assumed. If this array is shorter than the input array, it is repeated to match the size.

Seed

The seed used for the random shuffle. The default value of -1 will use the current time.

No Repeats

The number of elements to track to avoid repeating in a row. For example, a value of 2 prevents this node from repeating the last two selected elements.

Enabled Shared State

If enabled, this node's state is shared across instances of this MetaSound to avoid playing the same exact variations at the same time.

Output

Description

On Next

Triggers when the Next input is triggered.

On Reset

Triggers when the Shuffle input is triggered or if the array is auto-shuffled.

Value

The randomly-selected value from the input array.



The Set node sets the value of a specified index in a given array.

Input

Description

Trigger

The trigger on which to set value in the array.

Array

The array in which a value will be set.

Index

The index to set in the target array.

Value

The value to which the selected index is set.

Output

Description

Array

The array after the setting operation is completed.



The Shuffle node outputs elements from a shuffled array.

Input

Description

Next

The trigger on which to get the next value in the shuffled array.

Shuffle

The trigger on which to shuffle the array manually.

Reset Seed

The trigger on which to reset the random seed stream.

In Array

The array from which to shuffle and output elements.

Seed

The seed used for the random shuffle. The default value of -1 uses the current time.

Auto Shuffle

If enabled, automatically shuffles when the array has been read completely.

Enabled Shared State

If enabled, the state is shared across instances of this MetaSound.

Output

Description

On Next

Triggers when the Next input is triggered.

On Shuffle

Triggers when the Shuffle input is triggered or if the array is auto-shuffled.

On Reset Seed

Triggers when the Reset Seed input is triggered.

Value

The value of the currently-selected element.



The Subset node returns a subset of an input array.

Input

Description

Trigger

The trigger on which to generate a subset.

Array

The input array from which to get a subset.

Start / End Index

The first and last indices to include in the subset.

Output

Description

Array

The subset of the input array.

Debug



The Print Log node is used to record values to the Output Log on a given trigger for debugging purposes. There are multiple versions of this node in order to support several common data types, including: Bool, Float, Int32, and String.

Input

Description

Trigger

The trigger on which to write the set value to the log.

Label

The label to attach to the value logged.

Value To Log

The value to record to the log when triggered.

Delays



The Delay node provides a mono buffer delay that supports dry level, wet level, and feedback. For multi-channel buffer delay, use the Stereo Delay node.

Input

Description

In

The audio signal to apply delay to.

Delay Time

The amount of time to delay the audio (in seconds).

Dry Level

The level for the unprocessed (dry) signal

Wet Level

The level for the processed (wet) signal.

Feedback

The amount of feedback to use.

Max Delay Time

The amount of feedback to use.

Output

Description

Out

The delayed audio signal.



The Delay Pitch Shift node pitch shifts the audio buffer using a delay-based doppler-shift method. This allows for pitch shifting without changing the length of the audio file by using an internal delay buffer. The pitch will shift but the sound will not speed up or slow down.

Input

Description

In

The audio buffer to process.

Pitch Shift

The amount of pitch shift (in semitones) to apply.

Delay Length

The amount of delay (between 10 and 100 milliseconds) to apply. Changing this value can reduce artifacts in certain pitch shift regions.

Output

Description

Out

The processed audio buffer.



The Diffuser node applies diffusion to the incoming audio.

Input

Description

Input Audio

The audio to apply diffusion to.

Depth

The number of filters to use to diffuse the audio (between 1 and 5). This will not update while running.

Feedback

The amount of feedback to use on each diffuser (between 0 and 1).

Output

Description

Output Audio

The diffused audio.



The Grain Delay node performs delayed audio granulation on a given audio buffer by sampling it into "grains" and playing them after a set delay.

Input

Description

In Audio

The audio buffer to be grain delayed.

Grain Spawn

The trigger on which to spawn a new grain of audio.

Grain Delay

The delay (in milliseconds, between 0 and 2000) of the next spawned grain.

Grain Delay Range

The range delta (in milliseconds) used to randomize the delay in relation to the central Grain Delay value.

Grain Duration

The duration (in milliseconds) of the next spawned grain.

Grain Duration Range

The range delta (in milliseconds) used to randomize the duration in relation to the central Grain Duration value.

Pitch Shift

The pitch value (in semitones) to change the grain pitch of all rendering grains.

Pitch Shift Range

The pitch shift delta (in semitones) used to randomize the pitch shift in relation to the central Pitch Shift value.

Grain Envelope

The type of envelope to use for the grains: Gaussian, Triangle, Downward Triangle, Upward Triangle, Exponential Decay, or Exponential Attack

Max Grain Count

The maximum number of grains to render at a time (between 1 and 100).

Feedback Amount

The amount of feedback of each grain. If feedback is applied, the grain delay will feed its audio output back into itself.

The Max Grain Count input is CPU intensive, so setting it to high values can reduce performance and introduce clipping.

Output

Description

Out Audio

The grain-delayed audio buffer.



The Stereo Delay node provides multi-channel buffer delay. Like the Delay node, which provides mono buffer delay, this node supports dry level, wet level, and feedback, but also supports additional delay modes.

Input

Description

In Left / Right

The input audio signals (left / right channels) to apply delay to.

Delay Mode

The delay method to use:

Normal: The left input mixes with the left delay output and feeds to the left output.

Cross: The left input mixes with the right delay output and feeds to the right output.

Ping Pong: The left input mixes with the left delay output and feeds to the right output.

Delay Time

The amount of time to delay the audio (in seconds).

Delay Ratio

The ratio of delay to apply to the left and right channels. This means channels can have different delay amounts. For example, a value of -1 applies no delay to the left channel while fully delaying the right channel, which can be useful for stereo channel decorrelation.

Dry Level

The level for the unprocessed (dry) signal

Wet Level

The level for the processed (wet) signal.

Feedback

The amount of feedback to use.

Output

Description

Out Left / Right

The output audio signal (left / right channels).

Dynamics



The Compressor node lowers the dynamic range of an input audio signal.

Input

Description

Audio

The audio signal to compress.

Ratio

The ratio of gain reduction to apply. For example, a value of 1 produces no gain reduction and a value greater than 1 produces gain reduction.

Threshold dB

The amplitude threshold (in decibels) above which gain will be reduced.

Attack Time

The amount of time it takes for audio above the Threshold (dB) to reach its compressed volume level.

Release Time

The amount of time it takes for audio below the Threshold (dB) to return to its original volume level.

Lookahead Time

The amount of time it takes to delay the compressed signal behind the analyzed input signal.

Knee

A decibel value that determines how hard or soft the gain reduction blends. A value of 0 dB provides no blending.

Sidechain

(Optional) An external audio signal to control the compressor with. If unset, the input audio signal is used.

Envelope Mode

The envelope-following method the compressor will use for gain detection:

MS: Envelope follows a running Mean Squared of the audio signal.

RMS: Envelope follows a running Root Meat Squared of the audio signal.

Peak: Envelope follows the peaks in the audio signal.

Analog Mode

If enabled, use Analog Mode for the compressor's envelope follower.

Upwards Mode

If enabled, an upwards compressor is used instead of the standard downwards compressor.

Wet/Dry

The ratio between the processed (wet) and the unprocessed (dry) signal. For example, a value of 0 is fully dry and a value of 1 is fully wet.

Output

Description

Audio

The output audio signal with the compressor effect applied.

Gain Envelope

The amount of gain applied to the signal.



The Decibels to Linear Gain node converts a logarithmic (dB) gain value to a linear gain value.

Input

Description

Decibels

The input logarithmic (dB) gain value.

Output

Description

Linear Gain

The output linear gain value.



The Limiter node prevents a signal from going above a given threshold.

Input

Description

Audio

The input audio signal to be limited.

Input Gain dB

The amount of gain (in decibels) to apply to the input before limiting.

Threshold dB

The amplitude threshold (in decibels) above which gain will be reduced.

Release Time

The time it takes for audio below the threshold to return to its original volume level.

Knee

The knee mode determines if the gain reduction blends are Hard or Soft.

Output

Description

Audio

The limited audio signal.



The Linear Gain to Decibels node converts a linear gain value to a logarithmic (dB) gain value.

Input

Description

Linear Gain

The input linear gain value.

Output

Description

Decibels

The output logarithmic (dB) gain value.

Envelopes

MetaSounds provide Envelope nodes so audio designers can change aspects of their sounds over time. With the exception of the WaveTable Envelope node, each type of Envelope node has two different versions to support Audio (audio-rate) and Float (block-rate) data types.

Audio designers can customize their curve values using the various curve values contained within the nodes. For attack-time values, a curve value of less than 1.0 is a logarithmic curve (which rises quickly at first and slower near the end), and a value greater than 1.0 is an exponential curve (rises slower at first and more quickly near the end). Decay and release curves have the opposite behavior. Values of 1.0 for these curves are linear curves.



The AD Envelope node generates an attack-decay envelope value output when triggered.

This node provides an additional option for looping the Attack-Decay curve similarly to a Low Frequency Oscillator (LFO) or Wave Generator. When paired with a Map Range node, this can be used to great effect in a variety of applications.

Input

Description

Trigger

The trigger on which to start the attack phase of the envelope generator.

Attack Time

The amount of time (in seconds) to reach the maximum envelope value (1.0).

Delay Time

The amount of time (in seconds) to reach the minimum envelope value (0.0).

Attack Curve

The exponential curve factor of the attack phase. For example, a value of 1.0 produces linear growth, a value less than 1.0 produces logarithmic growth, and a value greater than 1.0 produces exponential growth.

Decay Curve

The exponential curve factor of the decay phase. For example, a value of 1.0 produces linear decay, a value greater than 1.0 produces logarithmic decay, and a value less than 1.0 produces exponential decay.

Looping

If enabled, the envelope will loop.

Output

Description

On Trigger

Triggers when the envelope is triggered.

On Done

Triggers when the envelope finishes or loops back if looping is enabled.

Out Envelope

The output value of the envelope.



The ADSR Envelope node generates an attack-decay-sustain-release envelope value output when triggered. This node is similar to the AD Envelope node, but it requires a separate release trigger for the release phase of the envelope to begin.

Input

Description

Trigger Attack

The trigger on which to start the attack phase of the envelope generator.

Trigger Release

The trigger on which to start the release phase of the envelope generator.

Attack Time

The amount of time (in seconds) to reach the maximum envelope value (1.0).

Delay Time

The amount of time (in seconds) to reach the minimum envelope value (0.0).

Sustain Level

The sustain level of the envelope.

Release Time

The release time of the envelope.

Attack Curve

The exponential curve factor of the attack phase. For example, a value of 1.0 produces linear growth, a value less than 1.0 produces logarithmic growth, and a value greater than 1.0 produces exponential growth.

Decay Curve

The exponential curve factor of the decay phase. For example, a value of 1.0 produces linear decay, a value greater than 1.0 produces logarithmic decay, and a value less than 1.0 produces exponential decay.

Release Curve

The exponential curve factor of the release phase. For example, a value of 1.0 produces linear release, a value greater than 1.0 produces logarithmic release, and a value less than 1.0 produces exponential release.

Output

Description

On Attack Triggered

Triggers when the envelope attack phase is triggered.

On Decay Triggered

Triggers when the envelope decay phase is triggered.

On Sustain Triggered

Triggers when the envelope sustain phase is triggered.

On Release Triggered

Triggers when the envelope release phase is triggered.

On Done

Triggers when the envelope is finished.

Out Envelope

The output value of the envelope.



The Crossfade node blends between inputs linearly using a provided block-rate float parameter. There are multiple versions of this node to support different input counts (between 2 and 8).

Input

Description

Crossfade Value

The value which represents the current blend between the provided inputs. For example, a value of 0.5 for input values of 2 and 4 will result in an output of 3.

In X

The input corresponding with position X.

Output

Description

Out

The value produced from the crossfade.



The WaveTable Envelope node reads through the given WaveTable over the given duration.

Input

Description

WaveTable

The WaveTable to read.

Play

The trigger on which to play the envelope.

Stop

The trigger on which to stop the envelope.

Pause

The trigger on which to pause the envelope.

Duration

The duration (in seconds).

Mode

Determines what value the envelope completes on and if it loops:

Loop: Interpolates the last and first values in the WaveTable and restarts interpolation of the envelope on completion.

Hold: Holds the last value in the table if playback elapses beyond the WaveTable's length.

Unit: Interpolates the last value in the table with 1.0 if playback elapses beyond the WaveTable's length.

Zero: Interpolates the last value in the table with 0.0 if playback elapses beyond the WaveTable's length.

Interpolation

Determines how the envelope interpolates between WaveTable values:

None (Step): No interpolation between values. The lowest value is used.

Linear: Linearly interpolates between values.

Cubic: Cubically interpolates between values.

Output

Description

OnFinished

Triggers when the envelope is finished.

Out

The output value.

External IO



The Audio Bus Reader node outputs audio data from an Audio Bus asset. There are two versions of this node to support different channel amounts (either 1 or 2).

Input

Description

Audio Bus

The Audio Bus asset to read data from.

Output

Description

Out X

The audio output for channel X.



The Wave Writer node writes audio signals to disk. There are multiple versions of this node to support different channel amounts (between 1 and 8).

The file is rendered at 48,000 Hz and is saved to the Saved > AudioCaptures folder.

Input

Description

Filename Prefix

The filename prefix used for the output file.

Enabled

If enabled, this node will write audio signals to disk.

In X

The audio input corresponding with channel X.

Filters



The Biquad Filter node provides a simple two-pole biquad filter that supports a variety of configurations.

Input

Description

In

The audio to be biquad filtered.

Cutoff Frequency

The value of the cutoff frequency.

Bandwidth

When applicable, controls the bandwidth value of the current filter type.

Gain (dB)

The gain (in decibels) applied to the band when in Parametric mode.

Type

The type of biquad filter to use.

Output

Description

Out

The biquad-filtered audio.



The Bitcrusher node downsamples and lowers the bit-depth of an incoming audio signal.

Input

Description

Audio

The audio signal to bitcrush.

Sample Rate

The sampling frequency to downsample the audio to.

Bit Depth

The bit resolution to reduce the audio to.

Output

Description

Audio

The bitcrushed audio signal.



The Dynamic Filter node filters a band of audio based on the strength of the input signal.

Input

Description

Audio

The audio signal to filter.

Sidechain

(Optional) An external audio signal to control the filter with. If not set, the input audio signal is used.

FilterType

The filter shape to use: Bell, Low Shelf, or High Shelf

Frequency

The center frequency of the filter.

Q

The filter's Q, or resonance, which controls the steepness of the filter.

Threshold dB

The amplitude threshold (dB) above which gain is reduced.

Ratio

The amount of gain reduction to apply. A value of 1 applies no reduction and a higher value provides more reduction.

Knee

A decibel value that determines how hard or soft the gain reduction blends. A value of 0 dB provides no blending.

Range

The maximum gain reduction allowed (in decibels). A negative value applies compression and a positive value flips it into an expander.

Gain (dB)

The amount of make-up gain (in decibels) to apply.

AttackTime

The amount of time (in seconds) it takes the audio above the threshold to reach its compressed volume level.

ReleaseTime

The amount of time (in seconds) it takes for the audio below the threshold to return to its original volume level.

EnvelopeMode

The envelope-following method the compressor uses for gain detection.

AnalogMode

If enabled, analog mode is used for the compressor's envelope follower.

Output

Description

Audio

The filtered audio signal.



The Ladder Filter node provides a virtual analog filter that has a pleasing and classic rolloff and resonance.

Input

Description

In

The audio to be processed by the ladder filter.

Cutoff Frequency

The value of the cutoff frequency.

Resonance

The value of the filter resonance.

Output

Description

Out

The ladder filtered audio.



The Mono Band Splitter node splits incoming audio into separate frequency bands. There are multiple versions of this node to support different input and output counts (between 2 and 5).

Input

Description

In

The base audio input channel.

Filter Order

The steepness of the crossover filters: Two Pole, Four Pole, Six Pole, or Eight Pole

Phase Compensate

If enabled, each band is phase-compensated so they can be summed back together correctly.

Crossover X

The frequency of the crossover filters from Band X to the next.

Output

Description

Band X Out

The audio output corresponding to channel X.



The One-Pole High Pass Filter node is a computationally cheap filter useful for a number of simple applications, such as simulating occlusion.

Input

Description

In

The audio signal to be filtered.

Cutoff Frequency

The value of the cutoff frequency.

Output

Description

Out

The filtered audio signal.



The One-Pole Low Pass Filter node is a computationally cheap filter useful for a number of simple applications, such as simulating air absorption

Input

Description

In

The audio signal to be filtered.

Cutoff Frequency

The value of the cutoff frequency.

Output

Description

Out

The filtered audio signal.



The Sample And Hold node outputs a single value of the input audio signal when triggered.

Input

Description

Sample And Hold

The trigger on which to sample and hold the input audio.

In

The audio signal to sample.

Output

Description

On Sample And Hold

Triggers when the Sample and Hold input is triggered.

Out

The sampled audio signal.



The State Variable Filter node provides a virtual analog filter used in many synthesis applications.

Input

Description

In

The audio to be processed by the filter.

Cutoff Frequency

The value of the cutoff frequency.

Resonance

The value of the filter resonance.

Band Stop Control

The control value applied to the band stop output.

Output

Description

Low Pass Filter

The low pass filter output.

High Pass Filter

The high pass filter output.

Band Pass

The band pass filter output.

Band Stop

The band stop filter output.



The Stereo Band Splitter node splits incoming audio into separate frequency bands. There are multiple versions of this node to support different input and output counts (between 2 and 5).

Input

Description

In L / R

The base audio input channels.

Filter Order

The steepness of the crossover filters: Two Pole, Four Pole, Six Pole, Eight Pole

Phase Compensate

If enabled, each band is phase-compensated so that they can be summed back together correctly.

Crossover X

The frequency of the crossover filters from Band X to the next.

Output

Description

Band X L / R

The audio output corresponding to channel X (in the left / right channel).

Generators

MetaSounds have several audio-rate generators which provide options for frequency modulation.

With the exception of the Noise node, all of these nodes support sync triggering which resets their phase. When combined with an audio-rate trigger repeat or a threshold trigger, this can create many unique synthesis effects.



The Additive Synth node synthesizes audio by adding given sinusoids together.

Input

Description

Base Frequency

The sinusoid frequency the harmonics are based on. The value is clamped from 0.0 to the Nyquist frequency.

HarmonicMultipliers

An array of harmonic multipliers applied to the base frequency. The number of sinusoids used depends on the size of this array. The values are clamped from 0.0 to a maximum so the resulting frequency won't go above the Nyquist frequency.

Amplitudes

The array of sinusoid amplitudes. The values are clamped to a range of 0.0 to 1.0

Phases

The array of sinusoid phases (in degrees). The values are clamped to a range of 0.0 to 360.

Pan Amounts

The array of pan amounts (using equal power law). For example, a value of -1.0 is fully left and a value of 1.0 is fully right.

Output

Description

Out Left / Right Audio

The synthesized audio output (left / right channels).



The LFO node provides a low-frequency oscillator which you can use to create a variety of audio effects, such as phasing, vibrato, and tremolo.

Input

Description

Frequency

The frequency (Hz) of the LFO (clamped at block rate).

Shape

The wave shape of the LFO: Sine, Saw, Triangle, or Square

Min / Max Value

The minimum / maximum output values.

Sync

Resets the phase of the generator. You can use this in conjunction with other nodes to get audio-rate phase synced generators.

Phase Offset

The phase offset (in degrees, between 0 and 360).

Pulse Width

The pulse width (between 0 and 1).

Output

Description

Out

The output value of the LFO (clamped at block rate).



The Noise node generates either pink or white noise.

Input

Description

Seed

The seed for the random number generator. The default value of -1 uses the current time.

Type

The type of noise to generate: Pink Noise or White Noise

Output

Description

Audio

The generated noise output.



The Saw node emits an audio signal of a saw wave with the given properties.

Input

Description

Enabled

If enabled, the oscillator produces a signal.

Bi Polar

If enabled, the output is bi-polar (-1, 1). Otherwise, the output is uni-polar (0, 1).

Frequency

The base frequency of the oscillator (in Hz).

Modulation

An audio-rate input to modulate the base frequency.

Sync

Resets the phase of the generator. You can use this in conjunction with other nodes to get audio-rate phase synced generators.

Phase Offset

The phase offset (in degrees, between 0 and 360).

Glide

The amount of glide (smooth interpolation over time) used when changing frequencies. For example, a value of 0.0 will produce no glide and a value of 1.0 produces lots of glide.

Type

The generator type used to make the saw wave:

Poly Smooth: Generates a smooth version of the saw wave.

Trivial: Uses a basic implementation to generate a saw wave.

Output

Description

Audio

The saw wave audio signal.



The Sine node emits an audio signal of a sinusoid with the given properties.

Input

Description

Enabled

If enabled, the oscillator produces a signal.

Bi Polar

If enabled, the output is bi-polar (-1, 1). Otherwise, the output is uni-polar (0, 1).

Frequency

The base frequency of the oscillator (in Hz).

Modulation

An audio-rate input to modulate the base frequency.

Sync

Resets the phase of the generator. You can use this in conjunction with other nodes to get audio-rate phase synced generators.

Phase Offset

The phase offset (in degrees, between 0 and 360).

Glide

The amount of glide (smooth interpolation over time) used when changing frequencies. For example, a value of 0.0 will produce no glide and a value of 1.0 produces lots of glide.

Type

The generator type used to make the sinusoid:

2D Rotation: Rotates around the unit circle to generate the sine wave.

Pure Math: Uses the standard math library to generate the sine wave (most expensive method).

Bhaskara: Uses the Bhaskara technique to approximate the sine wave.

Wave Table: Uses a wave table to generate the sine wave.

Output

Description

Audio

The sinusoid audio signal.



The Square node emits an audio signal of a square wave with the given properties.

Input

Description

Enabled

If enabled, the oscillator produces a signal.

Bi Polar

If enabled, the output is bi-polar (-1, 1). Otherwise, the output is uni-polar (0, 1).

Frequency

The base frequency of the oscillator (in Hz).

Modulation

An audio-rate input to modulate the base frequency.

Sync

Resets the phase of the generator. You can use this in conjunction with other nodes to get audio-rate phase synced generators.

Phase Offset

The phase offset (in degrees, between 0 and 360).

Glide

The amount of glide (smooth interpolation over time) used when changing frequencies. For example, a value of 0.0 will produce no glide and a value of 1.0 produces lots of glide.

Type

The generator type used to make the square wave:

Poly Smooth: Generates a smooth version of the Square wave.

Trivial: Uses a basic implementation to generate a Square wave.

Pulse Width

The relative pulse width of the square wave.

Output

Description

Audio

The square wave audio signal.



The Triangle node emits an audio signal of a triangle wave with the given properties.

Input

Description

Enabled

If enabled, the oscillator produces a signal.

Bi Polar

If enabled, the output will be bi-polar (-1, 1). Otherwise, the output will be uni-polar (0, 1).

Frequency

The base frequency of the oscillator (in Hz).

Modulation

An audio-rate input to modulate the base frequency.

Sync

Resets the phase of the generator. You can use this in conjunction with other nodes to get audio-rate phase synced generators.

Phase Offset

The phase offset (in degrees, between 0 and 360).

Glide

The amount of glide (smooth interpolation over time) used when changing frequencies. For example, a value of 0.0 will produce no glide and a value of 1.0 produces lots of glide.

Type

The generator type used to make the triangle wave:

Poly Smooth: Generates a smooth version of the Triangle wave.

Trivial: Uses a basic implementation to generate a Triangle wave.

Output

Description

Audio

The triangle wave audio signal.



The WaveTable Oscillator node reads through the given WaveTable at the provided frequency.

Input

Description

Play

The trigger on which to play the oscillator (block rate).

Stop

The trigger on which to stop the oscillator (block rate).

WaveTable

The WaveTable to read.

Freq

The number of times to sample one period of the WaveTable per second. This frequency should be set between -20000 Hz and 20000 Hz.

Sync

The trigger on which to restart playback of the WaveTable on the trigger boundary (sample rate).

Phase Modulator

The audio source to be used for the modulating oscillation phase of the provided WaveTable. A value of 0 produces no phase modulation and a value of 1 produces a full table length (360 degrees) of phase shift.

Output

Description

Out

The output audio buffer.

Math

MetaSounds come with a variety of nodes that perform basic math operations on the given inputs.

Operations on Audio data types are executed at a per-sample level.



The Abs node returns the absolute value of a given input. For example, an input value of -2.0 will output 2.0. This node has different versions which support several common data types, including: Audio, Float, Int32, and Time.



The Add node performs addition operations on provided inputs. This node has different versions which support several common data types, including: Audio, Float to Audio, Float, Int32, and Time.



The Clamp node returns the clamped value of the input within the given value range. This node has different versions which support several common data types, including: Audio, Float, and Int32.

Input

Description

In

The input value to clamp.

Min / Max

The min / max value to clamp the input value to.

Output

Description

Value

The clamped value.



The Divide node performs division operations on provided inputs. This node has different versions which support several common data types, including: Float, Int32, and Time by Float.



The Filter Q To Bandwidth node converts a given Q (quality-factor) parameter for filter control to a bandwidth value.



The Linear To Log Frequency node converts a linear space input value to a log-frequency output.

Input

Description

Value

The linear input value to map to a log frequency output.

Min / Max Domain

The min / max domain for the input value. The input and output values are clamped to this domain.

Min / Max Range

The min / max positive range for the output frequency (Hz) value. The input and output values are clamped to this range.

Output

Description

Frequency

The output frequency (Hz) that is the log frequency of the input value.



The Log node calculates the float-base logarithm of another float.



The Map Range node maps an input value in a given input range to a given output range. The results can also be clamped. This node has different versions which support several common data types, including: Audio, Float, and Int32. These nodes are analogous to the Blueprint Map Range nodes.

The Audio version of this node does a per-sample mapping. This is useful when mapping audio-rate signals to audio-rate modulation parameters, such as Frequency Modulator in FM synthesis.

Input

Description

In

The input value to map.

In Range A / B

The minimum and maximum input value range.

Out Range A / B

The minimum and maximum output value range.

Clamped

If enabled, the input will be clamped to the specified input range.

Output

Description

Out Value

The mapped output value.



The Max node returns the higher value (max) of A and B. This node has different versions to support several common data types, including: Audio, Float, and Int32.

Input

Description

A / B

The input values to compare.

Output

Description

Value

The higher value (max) of A and B.



The Min node returns the lower value (min) of A and B. This node has different versions which support several common data types, including: Audio, Float, and Int32.

Input

Description

A / B

The input values to compare.

Output

Description

Value

The lower value (min) of A and B.



The Modulo node returns the remainder of a division operation of two given Int32 values.



The Multiply node performs multiplication operations on provided inputs. This node has different versions which support several common data types, including: Audio by Float, Audio, Float, Int32, and Time by Float.

This node can be used to provide ring-modulation type effects and audio-rate amplitude modulation.



The Power node raises a given Float to the power of another Float.



The Subtract node performs subtraction operations on provided inputs. This node has different versions which support several common data types, including: Audio, Float, Int32, and Time.

Mix

MetaSounds provide two node types to create audio mixes, the Mono Mixer node and the Stereo Mixer node. These nodes have different versions which support between 2 and 8 input audio buffers, which are combined into a single buffer by using the input channel's corresponding gain values and summing them together.

The gain values are not clamped so they can be used for attenuating and inverting the audio signal.

These nodes are useful for mapping audio-rate buffers to different ranges for modulating various audio-rate-capable parameters.





Music



The Frequency To MIDI node converts a frequency value (in Hz) to a standard MIDI scale note value (where middle C is 60).

Input

Description

Frequency In

The input frequency value (in Hz).

Output

Description

Out MIDI

The output MIDI note value.



The MIDI Note Quantizer node quantizes a MIDI note to the nearest note that matches the provided criteria.

Input

Description

Note In

The MIDI note to quantize.

Root Note

The MIDI note to treat as the root. For example, a value of 0 equals C, a value of 1 equals D, and so on. The octave does not matter. Additionally, all values less than 0 clamp to 0.

Scale Degrees

An array containing a set of notes (in ascending order) representing half steps. The array must start with 0.0 to represent the root note and the highest value in the array must represent the root note in a higher octave, such as 12.0 for a single octave range or 24.0 for a two octave range.

Output

Description

Note Out

The quantized note.



The Frequency to MIDI node converts a standard MIDI scale note value (where middle C is 60) to a frequency value (in Hz). This node has two different versions which support Float and Int32 data types respectively.

You can use this node to musically control generators that take frequencies (in Hz) as an input. Additionally, the Float version can take fractional MIDI note values, which can be useful for microtonality and custom tuning.

Input

Description

MIDI In

The input value which represents a MIDI note value.

Output

Description

Out Frequency

The output frequency value (in Hz).



The Scale to Note Array node returns an array of floating-point numbers representing notes of the selected scale.

This node can be useful when creating procedural music by using the Chord Tones Only toggle to switch between full scale and chord tones.

Input

Description

Scale Degrees

The preset scale to get the notes for.

Chord Tones Only

If enabled, a subset of the scale representing chord tones is returned. For example, scale degrees of 1, 3, 5, and 7.

Output

Description

Scale Array Out

The array representation of the scale as half-steps above the root. The set is inclusive at both ends (starting at 0.0f and ending at 12.0f).

Random



MetaSounds provide several Random nodes categorized by their output value type, including Bool, Float, Int, and Time. These nodes output a random value from their input type and a seed.

Using the Reset trigger with an identical seed will produce the same results. This is useful to get randomized repetition.

Input

Description

Next

The trigger on which to generate the next random value.

Reset

The trigger on which to reset the random sequence with the supplied seed.

Seed

The seed value to use for the randomization. The default value of -1 uses a random seed.

Min / Max

The inclusive range of the random value.

Output

Description

On Next

Triggers when the Next input is triggered.

On Reset

Triggers when the Reset input is triggered.

Value

The randomly generated value.

Spatialization



The ITD Panner node pans an input audio signal using an interaural time delay method.

Input

Description

In

The input audio to spatialize.

Angle

The sound source angle (in degrees). A value of 90 degrees is front, 0 degrees is right, 270 degrees is behind, and 180 degrees is left.

Distance Factor

The normalized distance factor (0.0 to 1.0) to use for Interaural Level Difference (ILD) calculations. A value of 0.0 is near and a value of 1.0 is far. The further away the input audio is, the less difference in levels (gain) between the ears.

Head Width

The width (in centimeters) of the listener's head.

Output

Description

Out Left / Right

The audio output (left / right channel).



The Mid-Side Decode node converts a stereo signal with mid and side channels to left and right channels.

Input

Description

In Mid / Side

The audio channels to convert.

Spread Amount

The amount of stereo spread. A value of 0.0 produces no spread, a value of 0.5 is the original signal, and a value of 1.0 is fully wide.

Equal Power

If enabled, an equal power relationship between the input audio channels will be maintained.

Output

Description

Out Left / Right

The output audio channels.



The Mid-Side Encode node converts a stereo signal with left and right channels to mid and side channels.

Input

Description

In Left / Right

The audio channels to convert.

Spread Amount

The amount of stereo spread. A value of 0.0 produces no spread, a value of 0.5 is the original signal, and a value of 1.0 is fully wide.

Equal Power

If enabled, an equal power relationship between the input audio channels is maintained.

Output

Description

Out Mid / Side

The output audio channels.



The Stereo Panner node pans an input audio signal to left and right outputs.

Input

Description

In

The input audio signal to pan.

Pan Amount

The amount to pan the audio signal (-1.0 is fully left, 1.0 is fully right).

Panning Law

The panning law to use:

Equal Power: The power of the audio signal is constant while panning.

Linear: The amplitude of the audio signal is constant while panning.

Output

Description

Out Left / Right

The output audio signal (left / right channels).

Triggers



The Trigger Accumulate node triggers once all connected input triggers have been triggered at least once. There are multiple versions of this node in order to support different input counts (between 1 and 8).

This node is can be useful to detect when multiple Wave Player nodes to finish before triggering the On Finished Output trigger.

Input

Description

In X

The trigger input(s).

Auto Reset

The trigger on which the accumulation on this node is reset.

Output

Description

Out

Triggers when all input triggers have been accumulated.



The Trigger Any node triggers once any of the connected input triggers activate. This node has different versions which support different input counts (between 2 and 8).

This is a useful node when you want to have many different trigger sources execute another node's input.

Input

Description

In X

The trigger input(s).

Output

Description

Out

Triggers when any input trigger is triggered.



The Trigger Compare node triggers either true or false based on comparing connected inputs. This node has different versions which support several common data types, including: Bool, Float, and Int32.

Input

Description

Compare

The trigger on which to compare A and B.

A / B

The values to compare.

Type

The type of comparison to make: Equals, Not Equals, Less Than, Greater Than, Less Than Or Equals, or Greater Than Or Equals

Output

Description

True / False

Triggers with the resulting trigger after making the comparison.



The Trigger Control node provides controls to allow or block trigger signals from passing through to the output.

Input

Description

Trigger In

The input trigger to control.

Open

The trigger on which to allow the input trigger to pass through.

Close

The trigger on which to block the input trigger to pass through.

Toggle

The trigger on which to toggle the open/closed state of this node.

Start Closed

If enabled, the node will start in a closed state.

Output

Description

Trigger Out

The output trigger that passes through if the node is open.



The Trigger Counter node counts the connected input trigger activations.

This node is useful for sequencing array inputs and a large number of other procedural use cases.

Input

Description

In

The input trigger for which to count activations.

Reset

The trigger on which to reset the counter to zero and the value back to the start value.

Start Value

The value to start with on initialization and when reset.

Step Size

The value to add to the current value for each input trigger. This can be negative.

Reset Count

The number of input triggers to count before automatically resetting. If the value is set to 0, the node won't automatically reset.

Output

Description

On Trigger

Triggers when the input trigger is triggered and the count is updated.

On Reset

Triggers when the input reset is triggered or if the counter automatically resets.

Count

The current trigger count.

Value

The current value.



The Trigger Delay node executes a trigger after a given delay time from the most recent execution of the input trigger.

This node is similar to the Trigger Pipe node, but differs by only considering the most recent trigger execution. This means that additional triggers that happen within the delay time will reset the timer and cause the output trigger to be delayed again.

Input

Description

In

The input trigger to delay.

Reset

The trigger on which to reset the delay and clear the execution task, if it is pending.

Delay Time

The amount of time to delay the trigger (in seconds).

Output

Description

Out

The delayed output trigger.



The Trigger Filter node responds to a trigger by randomly activating one of the two output triggers.

Input

Description

Trigger

The trigger on which to randomly activate an output trigger.

Reset

The trigger on which to reset the random sequence with the provided seed.

Seed

The seed value to use for the randomization. A value of -1 will use a random seed.

Probability

The probability that a particular output trigger will get activated. For example, a value of 0.0 is always heads, a value of 1.0 is always tails, and 0.5 is equal odds.

Output

Description

Heads / Tails

The possible output triggers.



The Trigger On Threshold node operates as an edge detector and triggers when the input audio crosses a given threshold value while moving in the specified direction. This node has different versions which support several common data types, including: Audio, Float, and Int32.

If set to Rising Edge, a trigger is output when the signal crosses the threshold with a positive slope. This is useful when paired with a generator node and connected to another generator's sync trigger input.

Input

Description

In

The input audio signal.

Threshold

The threshold at which to trigger output.

Type

The type of trigger threshold: Rising Edge, Falling Edge, or Abs Threshold

Output

Description

Out

The output threshold trigger.



The Trigger On Value Change node triggers when a given value changes. This node has different versions which support several common data types, including: Bool, Float, and Int32.

Input

Description

Value

The input value to watch.

Output

Description

Trigger

The output trigger.



The Trigger Once node triggers the first time an input trigger is activated and ignores all other occurrences, unless reset.

Input

Description

Trigger In

The input trigger.

Reset

The trigger on which to open the node and allow another trigger through.

Start Closed

If enabled, the node is closed when playback begins.

Output

Description

Trigger Out

The output trigger.



The Trigger Pipe node delays execution of all input trigger signals by the given delay.

This node is similar to the Trigger Delay node, but does not reset the timer upon receiving additional triggers.

Input

Description

In

The input trigger to delay.

Reset

The trigger on which to reset the trigger delay and clear any pending execution tasks.

Delay Time

The time to delay the input trigger (in seconds).

Output

Description

Out

The delayed output trigger.



The Trigger Repeat node emits a trigger periodically at a given sample-accurate and arbitrarily-precise rate.

Input

Description

Start / Stop

The triggers on which to start or stop executing periodic output triggers.

Period

The period to trigger (in seconds).

Output

Description

RepeatOut

The periodically generated output trigger.



The Trigger Route node routes different input values to a single output value. This node has multiple versions for different input counts (between 2 and 8) and for each supported data type, including: Audio, Bool, Float, Int32, and Time.

Input

Description

Set X

The input triggers which initialize the routing. The default option is 0.

Value X

The input value to route to the output when triggered by its corresponding trigger.

Output

Description

On Set

Triggers when any of the input triggers are set.

Value

The output value set by an activated input trigger.



The Trigger Select node passes triggers through to the currently selected output trigger. This node has multiple versions for different input counts (between 2 and 8).

Input

Description

In

The trigger to pass through.

Index

The output index to trigger. If the provided value is out of range, it will be ignored.

Output

Description

Out X

The output trigger at index X.



The Trigger Sequence node responds to input triggers by sending the next output trigger in a sequence. This node has multiple versions which provide different numbers of output triggers (between 2 and 8).

Input

Description

In

The input trigger.

Reset

The trigger on which to reset the sequence back to 0.

Loop

If enabled, the sequence automatically loops back to 0 once all triggers have been activated.

Output

Description

Out X

The trigger outputs in sequence.



The Trigger Toggle node toggles a Bool value on or off.

Input

Description

On / Off

The trigger on which to toggle the Bool output on or off.

Init

The initial states of the Bool.

Output

Description

Out

Triggers when the Bool is toggled.

Value

The current Bool value.

Value



The Value node sets a variable value on a trigger. This node has different versions for each of the supported data types, including: Bool, Float, Int32, and String.

Input

Description

Set

The trigger on which to write the set value to the output.

Reset

The trigger on which to reset the value to the initial value.

Init Value

The value to initialize the output value to.

Target Value

The value to set the output to when triggered.

Output

Description

On Set

Triggers when the value is set.

On Reset

Triggers when the value is reset.

Output Value

The current output value.

Menu Bar

Toolbar

Details Panel

Viewport Panel

Palette Panel

The Sound Cue Editor is divided into the following regions:



Menu Bar

Toolbar

Details Panel

Viewport Panel

Palette Panel

You can close any panel by clicking the small "X" in the upper-right corner of the tab. To reopen a panel that you have closed, click that panel's name on the Window menu.

You can also hide any tab by right-clicking on the tab, and then clicking Hide Tab on the context menu that appears. Likewise, you can show any hidden tab by clicking the little blue arrow in the top left order of the panel.

Menu Bar

File

Open Asset… - Displays the Open Asset panel to quickly find an asset and open the appropriate editor.

Save All - Saves all unsaved levels and assets for your project.

Choose Files to Save… - Brings up a dialog box that allows you to choose which levels and assets you want to save for your project.

Save - Saves the current asset.

Save As… - Saves the current asset under a different name or location.

Edit

Undo - Undoes the most recent action.

Redo - Redoes the most recent Undo, if it was the last action taken.

Undo History - Displays the Undo History panel.

Editor Preferences… - Displays the Editor Preferences panel, where you can modify your Unreal Editor preferences.

Project Settings… - Displays the Project Settings panel, where you can modify various settings for your Unreal Engine project.

Plugins - Displays the Plugins panel, where you can control the active plugins for your Unreal Engine installation.

Asset

Find in Content Browser… - Locates and selects the current asset in the Content Browser.

Reference Viewer… - Displays the Reference Viewer panel, where you can see reference information for the current asset.

Size Map… - Displays the Size Map panel, where you can see size information for the current asset.

Audit Assets… - Displays the Asset Audit panel.

Shader Cook Statistics… - Displays the Statistics panel with the Shader Cook Stats filter applied.

Window

Viewport - Displays the Viewport panel.

Details - Displays the Details panel.

Palette - Displays the Palette panel.

Content Browser - Brings up the Content Browser in a separate window.

Device Output Log - Displays the Device Output Log panel.

Interchange Results Browser - Displays the Interchange Results Browser panel.

Message Log - Displays the Message Log panel

Output Log - Displays the Output Log panel.

Open Marketplace - Opens the Unreal Engine Marketplace.

Load Layout - Loads the selected panel layout.

Save Layout - Saves the current layout of the panels as the new default layout.

Remove Layout - Removes the selected layout from the Unreal Editor.

Enable Fullscreen - Enables fullscreen mode for the application, expanding across the entire monitor.

Tools

New C++ Class… - Opens a dialog where you can create a new C++ class for your project.

Refresh Visual Studio Project - Refreshes your Visual Studio C++ project.

Open Visual Studio - Opens your C++ code in Visual Studio.

Find in Blueprints - Displays the Find in Blueprints panel.

Cache Statistics - Displays the Cache Statistics panel.

Class Viewer - Displays the Class Viewer panel.

CSV to SVG - Displays the CSV to SVG panel.

Localization Dashboard - Displays the Localization Dashboard panel.

Merge Actors - Displays the Merge Actors panel.

Project Launcher - Displays the Project Launcher panel.

Resource Usage - Displays the Resource Usage panel.

Session Frontend - Displays the Session Frontend panel.

Struct Viewer - Displays the Struct Viewer panel.

Virtual Assets - Displays the Virtual Assets panel.

Debug - Acts as a container folder for the below options.

Blueprint Debugger - Displays the Blueprint Debugger panel.

Collision Analyzer - Displays the Collision Analyzer panel.

Debug Tools - Displays the Debug Tools panel.

Modules - Displays the Modules panel.

Niagara Debugger - Displays the Niagara Debugger panel.

Pixel Inspector - Displays the Pixel Inspector panel.

Stylus Input Debug - Displays the Stylus Input Debug panel.

Visual Logger - Displays the Visual Logger panel.

Widget Reflector - Displays the Widget Reflector panel.

Profile - Acts as a container folder for the below options.

Profile Data Visualizer - Displays the Profile Data Visualizer panel.

Trace Data Filtering - Displays the Trace Data Filtering panel.

Audit - Acts as a container folder for the below options.

Asset Audit - Displays the Asset Audit panel.

Material Analyzer - Displays the Material Analyzer panel.

Platforms - Acts as a container folder for the below options.

Device Manager - Displays the Device Manager panel.

Device Profiles - Displays the Device Profiles panel.

View Changelists - Opens a dialog which displays the current changelists.

Submit Content - Opens a dialog with check in options for content and levels.

Connect to Source Control… - Brings up a dialog box that allows you to choose or interact with a source-control system that the Unreal Editor can integrate with.

Run Unreal Insights - Runs the Unreal Insights standalone application.

Help

SoundCue Editor Documentation - Opens the SoundCue Editor documentation page.

Documentation Home - Opens the Unreal Engine documentation home page.

C++ API Reference - Opens the C++ API Reference documentation page.

Console Variables - Opens the Console Variables and Commands documentation page.

Online Learning - Opens the Epic Developer Community site, which provides video tutorials and guided learning paths.

Forums - Opens the Unreal Engine Forums site.

Q&A - Opens the Q&A section of the Unreal Engine Forums site.

Support - Opens the Unreal Engine Support site.

Report a Bug - Opens the Unreal Engine Bug Submission Form page.

Issue Tracker - Opens the Unreal Engine Issues page.

About Unreal Editor - Opens a dialog with information about the installed Unreal Editor.

Credits - Opens a dialog which displays the credits for the installed Unreal Engine version.

Visit UnrealEngine.com - Opens UnrealEngine.com in a browser window.

Toolbar

Button

Description



Saves the current Sound Cue.



Finds and selects the current Sound Cue in the Content Browser.



Mutes all other sound sources except for the current Sound Cue.



Mutes the current Sound Cue.



Plays the entire Sound Cue.



Plays only the currently selected node in the Viewport panel. Only available while a single node is selected.



Stops playing the Sound Cue or node.

Details Panel



The Details panel displays the properties of the currently selected node. If multiple nodes are selected, the Details panel displays only the properties that the nodes have in common.

Viewport Panel



The Viewport panel contains the Sound Node Graph, which displays the audio signal path with wire-connected Sound Nodes which manipulate the signal as data flows through the Sound Cue.

For general information about the Sound Cue Editor and working with the Sound Node Graph, see the Sound Cue Editor documentation.

Palette Panel



The Palette panel lists all of the available Sound Node types available for Sound Cues. You can add a node to a Sound Node Graph by dragging one of the types from the list in Palette panel into the Viewport panel.

For information about Sound Node types and their properties, see the Sound Cue Reference documentation.

Sound Wave

Sound Cue

Creating Sound Cues

Opening the Sound Cue Editor

Sound Node Graph



The Sound Cue Editor is a node-based editor that is used to design Sound Cue assets. Sound Cues contain a Sound Node Graph which can store references to imported audio assets, known as Sound Waves, or contain instructions on how to manipulate audio as it flows through the graph.

Sound Wave

A Sound Wave asset is created by importing an audio file and wrapping it with additional properties and control options. These properties can be found by double-clicking on a Sound Wave asset, or by right-clicking and selecting Edit from the context menu.

In Sound Cues, Sound Wave references are built into the Sound Node Graph by using a Wave Player Sound Node or a Wave Param Sound Node.

See Importing Audio Files for information on how to create Sound Waves.

A Sound Wave's properties work as a base and can influence any Sound Cues which contain it. For example, increasing the pitch or volume will increase it everywhere it is referenced.

Sound Cue

A Sound Cue is an asset which acts as a container for audio behavior information. Sound Cues are made up of Sound Nodes, which are individual modules that each affect a sound's design. The Sound Nodes are arranged in a graph which displays the relationships between the Sound Nodes and the flow of data between them.

Creating Sound Cues

To create a Sound Cue, do the following:

In the Content Browser, click the button or right-click in an empty space in the Content Browser to bring up a context menu.

Under the Create Advanced Assets section, click Sounds, and then click Sound Cue.

Enter a name for your new Sound Cue.

Opening the Sound Cue Editor

You can open the Sound Cue Editor by double-clicking a Sound Cue asset in the Content Browser or by right-clicking a Sound Cue asset in the Content Browser and then clicking Edit on the context menu.

For more information about the Sound Cue Editor's User Interface, see the Sound Cue Editor UI documentation.

Sound Node Graph

The Viewport panel contains the Sound Node Graph, which displays the audio signal path with wire-connected Sound Nodes which manipulate the signal as data flows through the Sound Cue.



You can add a new Sound Node by right-clicking on an empty space in the Viewport panel or by dragging off an existing node's connection pin into an empty space. In both cases, you will be prompted with a search-enabled context menu where you can select the Sound Node type of the new node.



You can also add a new Sound Node by dragging a Sound Node type from the Palette panel to either an empty space or to an existing node's connection pin.





To preview playback, use the play buttons located in the toolbar at the top of the Sound Cue Editor window. The Play Cue button plays the entire Sound Cue, and the Play Node button plays the sound from the selected node. (If multiple nodes are selected, the Play Node button is grayed out and unavailable.)



While a Sound Cue is playing, to aid in debugging, the wires of currently active nodes turn red. This makes it easy to follow the Sound Cue's construction in real time.



Due to the connection pin locations on Sound Nodes, it's highly recommended to build a Sound Node Graph from left to right. Start with Sound Wave playing nodes (such as Wave Player or Wave Param), then all relevant control nodes (such as Delay or Modulator), and end with the Output node.

For explanations of the nodes available for use within the Sound Cue Editor, see the Sound Cue Reference documentation.

Named Parameters

Output Node

Attenuation Node

Branch Node

Concatenator Node

Continuous Modulator Node

Crossfade by Distance Node

Crossfade by Param Node

Delay Node

Dialogue Player Node

Doppler Node

Enveloper Node

Group Control Node

Looping Node

Mature Node

Mixer Node

Modulator Node

Oscillator Node

Quality Level Node

Random Node

SoundClass Node

Switch Node

Wave Param Node

Wave Player Node

Add Comment

Examples

In Unreal Engine, a Sound Cue is an audio asset that encapsulates complex sound design tasks within a node graph. Sound Cues provide audio designers freedom to dynamically change parts of a sound effect's design by arranging and modifying Sound Nodes to create complex and interesting audio output.

In the Sound Cue Editor, a list of Sound Node types is provided within the Palette panel. Selecting a node in the Viewport panel will display the node's properties in the Details panel.



For more about working with Sound Cues, see the Sound Cue Editor and Sound Cue Editor UI documentation.

Named Parameters

In some Sound Nodes, you can declare a parameter by entering a new parameter name. When you enter a parameter name in a node, it will create a parameter with that name.



You can name the parameter whatever you want. However, when you use an Audio Component Function to set the parameter's value, its In Name field must exactly match the Parameter Name you gave it.

You cannot set the values for a named parameter from within a Sound Cue. A recommended workflow would be:

Add a Sound Node.

Enter a name in the node Parameter Name field.

Call the relevant audio component function from within a Blueprint, or in code, using the appropriate Set [Name] Parameter function.

Add the same name to the In Name parameter. This will get the Sound Cue to respond as expected.



The table below shows the nodes that can use named parameters, and the corresponding parameter setting functions.

Node Type

Corresponding Function

Branch

Set Boolean Parameter

Continuous Modulator

Set Float Parameter

Crossfade by Param

Set Float Parameter

SoundClass

Set Wave Parameter

Switch

Set Integer Parameter

Wave Param

Set Wave Parameter

Output Node

An Output node is required in every Sound Cue and works as an end point for the audio signal path in the node graph. The Output node's properties are relative and affect all of the audio output contained within the Sound Cue.



Property

Description

Memory

Prime on Load

If enabled, all connected Sound Waves will load into cache when this Sound Cue is loaded.

Disable Random Branch Culling

If enabled, all per-platform random node culling will be ignored.

Sound

Volume Multiplier

The base volume multiplier.

Pitch Multiplier

The base pitch multiplier.

Class

The Sound Class asset that this Sound Cue belongs to.

Attenuation

Override Attenuation

If enabled, the existing attenuation settings will be overridden with the provided values. See the Attenuation Node section of this page for more information.

Attenuation Settings

This can be set to an existing Sound Attenuation asset to utilize that asset's settings.

Effects

🞂 Source

Enable Bus Sends

If enabled, audio output will be sent to buses.

Source Effect Chain

The Source Effect Preset Chain asset to use for this Sound Cue.

Post-Effect Bus Sends

An array of buses to send audio output to if there are bus instances playing after the source effects are processed.

Pre-Effect Bus Sends

An array of buses to send audio output to if there are bus instances playing before source effects are processed.

🞂 Submix

Enable Base Submix

If enabled, sound will route to the Master Submix by default or to the Base Submix if defined. If disabled, sound will route ONLY to the Submix Sends and/or Bus Sends.

Base Submix

The Submix asset to use for this Sound Cue.

Enable Submix Sends

Enables sending audio output to additional submixes.

Submix Sends

An array of submixes which receive a prescribed amount (see Send Level) of this Sound Cue's audio output.

Voice Management

Virtualization Mode

Sets virtualization behavior to determine if a sound may revive and how it continues playing when culled or evicted due to looping sound limitations.

🞂 Priority

Subtitle Priority

The priority of the subtitle. Higher values will play instead of lower values.

Bypass Volume Scale for Priority

If enabled, bypasses volume weighting priority upon evaluating whether sound should remain active when max channel count is met.

Priority

This is used to determine whether sound can play or remain active if the channel limit is met. Higher values will play instead of lower values. Unless bypassed, value is weighted with the final volume of the sound to produce final runtime priority value.

🞂 Concurrency

Override Concurrency

If enabled, the existing concurrency settings will be overridden with the provided values. This allows the Concurrency Overrides values to be modified.

Concurrency Set

An array of concurrency settings to observe (if override is set to false). Sound must pass all concurrency settings to play.

🞂 Concurrency 🞂 Concurrency Overrides

Max Count

The maximum number of concurrent sounds allowed in this concurrency group.

Limit to Owner

If enabled, the concurrency settings are applied to the actor which played the sound. If the sound doesn't have an owning actor, it falls back to the global concurrency settings.

Resolution Rate

The concurrency resolution policy to use if max voice count is reached.

Retrigger Time

The amount of time (in seconds) to wait between different sounds. The sounds rejected from this will ignore virtualization settings.

Volume Scale

A ducking factor to apply per older voice instance, which compounds based on scaling mode, and optionally revives them as they stop according to provided attack/release times.

Volume Scale Mode

Designates how to scale voice volume based on the number of member sounds active in the group.

Duck Time

The amount of time (in seconds) to apply the ducking factor using the volume scalar.

Can Recover

If enabled, volume scaling can recover from the volume ducking behavior when concurrency group sounds stop. This is only available when Volume Scale Mode is set to Default.

Recover Time

The amount of time (in seconds) to recover from the volume scalar duck. This is only available when Can Recover is enabled.

Voice Steal Release Time

The amount of time (in seconds) to fade out if a sound is culled due to another sound in the group starting.

Advanced

Asset User Data

An array of user data stored with this asset.

Developer

Debug

If enabled, the attenuation shape is drawn when the sound is audible. For debugging purposes only.

Duration

The duration of the sound in seconds.

Max Distance

The maximum distance as determined by the attenuation settings.

Total Samples

The total number of samples (in the thousands). This is useful to analyze the relative size of a given asset. This value can also be viewed in the context menu that displays while hovering over a Sound Cue in the Content Drawer.

Attenuation Node

The Attenuation node controls volume for a sound based on the distance of the sound source from the listener.

The Attenuation Settings can be set to an existing Sound Attenuation asset or manually specified in the node's properties by enabling the Override Attenuation setting.

For an overview on attenuation and how it works, see the Sound Attenuation documentation.



Property

Description

Attenuation

Attenuation Settings

This can be set to an existing Sound Attenuation asset to utilize that asset's settings.

Override Attenuation

If enabled, the existing attenuation settings will be overridden with the provided values.

Attenuation (Volume)

Enable Volume Attenuation

Enables or disables distance-based volume attenuation.

Attenuation Function

The type of attenuation function to use: Linear, Logarithmic, Inverse, Log Reverse, Natural Sound, or Custom

Attenuation At Max (dB)

(For Attenuation Function: Natural Sound) The attenuation volume at the falloff distance in decibels.

Falloff Mode

(For Attenuation Function: Natural Sound) Controls whether to continue attenuating, go silent, or hold the last volume value when beyond falloff bounds. Only editable if Attenuation At Max (dB) is set to a value of greater than -60dB.

Attenuation Shape

The shape for a non-custom attenuation function: Sphere, Capsule, Box, or Cone

Inner Radius

(For Attenuation Shape: Sphere) The radius that defines where sound attenuation begins (or where a custom attenuation curve begins). Sounds played at a distance less than this radius will not attenuate.

Capsule Half Height

(For Attenuation Shape: Capsule) The attenuation capsule's half height.

Capsule Radius

(For Attenuation Shape: Capsule) The attenuation capsule's radius.

Extents

(For Attenuation Shape: Box) The attenuation box's extents.

Cone Radius

(For Attenuation Shape: Cone) The attenuation cone's radius.

Cone Angle

(For Attenuation Shape: Cone) The attenuation cone's angle.

Cone Falloff Angle

(For Attenuation Shape: Cone) The attenuation cone's falloff angle.

Cone Offset

(For Attenuation Shape: Cone) The attenuation cone's offset.

Falloff Distance

The distance over which the volume attenuates.

Attenuation (Spatialization)

Enable Spatialization

When enabled, allow the input sound to be positioned in 3D space.

Spatialization Method

The method used to spatialize the sound:

Panning: The standard panning method for spatialization (linear or equal power method, as defined in project settings).

Binaural: If available, use the binaural spatialization method (requires headphones and is enabled by plugins).

Binaural Radius

The minimum radius to swap to non-binaural audio when a sound starts playing.

Non-Spatialized Radius

The distance from the origin where a sound is non-spatialized (2D). This prevents near-field audio from flipping as audio crosses the listener's position.

3D Stereo Spread

The world-space distance between left and right stereo channels when stereo assets are 3D spatialized.

Normalize 3D Stereo Sounds

When enabled, applies a -6 dB attenuation to stereo Assets that are 3D spatialized. This avoids clipping when Assets have a spread of 0.0 due to channel summing.

Spatialization Plugin Settings

An array of settings assets for spatialization plugins. As this is an array, multiple settings can be applied.

Attenuation (Occlusion)

Enable Occlusion

Enables real-time occlusion tracing.

Occlusion Trace Channel

The type of trace channel to use for audio occlusion checks.

Occlusion Low Pass Filter Frequency

The low-pass filter frequency (in Hz) that applies if the sound playing in this audio component is occluded. This will override the LowPassFilterFrequency specified in code or Blueprints. A frequency of 0.0 is the device sample rate and will bypass the filter.

Occlusion Volume Attenuation

The amount of volume attenuation to apply to occluded sounds.

Occlusion Interpolation Time

The amount of time in seconds to interpolate to the target Occlusion Low Pass Filter Frequency when a sound is occluded.

Use Complex Collision for Occlusion

Enables tracing against complex collisions when doing occlusion traces.

Occlusion Plugin Settings

An array of settings assets for occlusion plugins. As this is an array, multiple settings can be applied.

Attenuation (Submix)

Enables Submix Send

Enables submix sends based on distance.

Submix Send Settings

When this feature is enabled, the Submix Send Settings expand into a full set of parameters.

Attenuation (Reverb)

Enable Reverb Send

Enables adjusting reverb sends based on distance.

Reverb Send Method

The method used to control master reverb sends:

Linear: Reverb send based on linear interpolation between distance and send-level ranges.

Custom Curve: Reverb sending based on a supplied curve. This can be set directly in the Details Panel or to an external curve by clicking on the triangle beside the parameter name and using the expanded External Curve parameter options.

Manual: Reverb send level that uses the manual setting specified below. Useful for 2D sounds.

Reverb Min Send Level

The amount to send to master reverb when sound is located at a distance equal to the value specified.

Reverb Max Send Level

The amount to send to master reverb when sound is located at a distance equal to the value specified.

Reverb Min Send Distance

The minimum distance to send to the master reverb.

Reverb Max Send Distance

The maximum distance to send to the master reverb.

Reverb Plugin Settings

An array of settings assets for reverb plugins. As this is an array, multiple settings can be applied.

Attenuation (Focus)

Enable Listener Focus

This enables listener focus-based adjustments.

Focus Azimuth

The azimuth angle (in degrees) relative to the forward vector of the listener which defines the focus region of sounds. The sounds playing at an angle less than this will be in-focus.

Non Focus Azimuth

The azimuth angle (in degrees) relative to the forward vector of the listener which defines the non-focus region of sounds. The sounds playing at an angle greater than this will be out-of-focus.

Focus Distance Scale

The amount to scale the distance calculation for in-focus sounds. This can be used to make in-focus sounds seem closer or further away than they actually are.

Non Focus Distance Scale

The amount to scale the distance calculation for out-of-focus sounds. This can be used to make out-of-focus sounds seem closer or further away than they actually are.

Focus Priority Scale

The amount to scale the priority of sounds that are in-focus.

Non Focus Priority Scale

The amount to scale the priority of sounds that are not in-focus.

Focus Volume Attenuation

The amount to attenuate sounds that are in-focus. This can be overridden at the sound level.

Non Focus Volume Attenuation

The amount to attenuate sounds that are not in-focus. This can be overridden at the sound level.

Enable Focus Interpolation

This enables focus interpolation to smooth focus transition in and out.

Focus Attack Interp Speed

The scalar value used to increase interpolation speed upward to the target focus value. This option requires Enable Focus Interpolation to be enabled.

Focus Release Interp Speed

The scalar value used to increase interpolation speed downward to the target focus value. This option requires Enable Focus Interpolation to be enabled.

Attenuation (Priority)

Enable Priority Attenuation

Enables attenuation of sound priority based on distance.

Priority Attenuation Method

The method used to control priority attenuation:

Linear: Priority attenuation based on linear interpolation between distance and priority-attenuation ranges.

Custom Curve: Priority attenuation based on a supplied curve. This can be set directly in the Details Panel or to an external curve by clicking on the triangle beside the parameter name and using the expanded External Curve parameter options.

Manual: Priority attenuation based on the given Attenuation Priority value. This is useful for 2D sounds.

Priority Attenuation At Min Distance

The interpolated value to scale priority against when the sound is at the minimum priority attenuation distance from the closest listener.

Priority Attenuation At Max Distance

The interpolated value to scale priority against when the sound is at the maximum priority attenuation distance from the closest listener.

Priority Attenuation Min Distance

The minimum distance to attenuate priority.

Priority Attenuation Max Distance

The maximum distance to attenuate priority.

Attenuation Priority

(For Priority Attenuation Method: Manual) The priority level entered is static and does not change with distance.

Attenuation (Air Absorption)

Enable Air Absorption

Enables air absorption simulation by applying a filter with a cutoff frequency as a function of distance.

Min Distance Range

The minimum distance to apply an absorption low pass filter. Absorption frequency cutoff interpolates filter frequency ranges between Min Distance Range and Max Distance Range.

Max Distance Range

The maximum distance to apply an absorption low pass filter. Absorption frequency cutoff interpolates filter frequency ranges between Min Distance Range and Max Distance Range.

Low Pass Cutoff Frequency Min

The minimum range of the cutoff frequency (in Hz) for the low pass absorption filter.

Low Pass Cutoff Frequency Max

The maximum range of the cutoff frequency (in Hz) for the low pass absorption filter.

High Pass Cutoff Frequency Min

The minimum range of the cutoff frequency (in Hz) for the high pass absorption filter.

High Pass Cutoff Frequency Max

The maximum range of the cutoff frequency (in Hz) for the high pass absorption filter.

Enable Log Frequency Scaling

This enables perceptually linear frequency sweeping by applying a log scale to frequency values.

Absorption Method

The method used to map distance values to frequency absorption values:

Linear: The air absorption conforms to a linear distance function.

Custom Curve: The air absorption conforms to a custom distance curve. This can be set directly in the Details Panel or to an external curve by clicking on the triangle beside the parameter name and using the expanded External Curve parameter options.

Attenuation (Source Data Override)

Enable Source Data Override

Enables overriding WaveInstance data using source data override plugins.

Source Data Override Plugin Settings

An array of settings assets for source data override plugins. As this is an array, multiple settings can be applied.

Stereo files play evenly on the left and right channels, and attenuate to allow volume fades between the Radius Min and Radius Max values, but they are not spatialized.

Sound Cues that do not contain an Attenuation node are not localized, and play consistently at the Sound Cue volume setting.

Branch Node

The Branch node selects an input node based on the value of a named Boolean parameter of True, False or Parameter Unset.

Parameter Unset is the output that plays when the value of a named parameter has not been set. For example, if the parameter is saved as Name in the Branch node, but the user hasn't called SetBooleanParam(Name, [true or false]), the Sound Cue will use the Parameter Unset input pin, not the True or False pin.

For more information about named parameters, see the Named Parameters section of this page.



Property

Description

Bool Parameter Name

The name of the Boolean parameter that determines which input node is used.

Concatenator Node

The Concatenator node is used to play sounds sequentially (for example, creating a simple BGM playlist that plays through a series of specified tracks). While this node handles sequential playback, it will also add a small delay between each asset.

Initially, this node has two input pins. You may add more pins by clicking the Add input button on the node or remove pins by right-clicking them and selecting "Delete Input" from the context menu.



Property

Description

Input Volume

An array which stores the volume multiplier for each attached input sound.

Continuous Modulator Node

The Continuous Modulator node provides a way to control named parameters for volume and pitch modulation in real time. A typical example would be using the velocity of a vehicle to correspond to the pitch of an engine sound. This modulator needs to be hooked up in code or Blueprint to work, and does not function on its own within the Sound Cue Editor. However, you can change pitch and volume from within the Sound Cue Editor.

By setting maximum and minimum values, you can determine the range of randomization.

The pitch and volume of the input sound will default to a uniform distribution, but you can change them in the Sound Cue Editor to any other type.

For more information about named parameters, see the Named Parameters section of this page.



Property

Description

Pitch Modulation Params

Parameter Name

The name of the sound instance parameter being used to manipulate pitch.

Default

The default pitch value used if no parameter is found.

Min Input

The minimum input pitch value. Values will be clamped to the [MinInput, MaxInput] range.

Max Input

The maximum input pitch value. Values will be clamped to the [MinInput, MaxInput] range.

Min Output

The minimum output pitch value. This value is scaled from the [MinInput, MaxInput] range to the [MinOutput, MaxOutput] range.

Max Output

The maximum output pitch value. This value is scaled from the [MinInput, MaxInput] range to the [MinOutput, MaxOutput] range.

Param Mode

The mode with which the parameter is applied:

Normal: Clamps input value to the range (MinInput, MaxInput), then maps to the range (MinOutput, MaxOutput).

Absolute: Same as Normal, except that the input value is treated as an absolute value.

Direct: Uses the input value directly, without scaling or reference to Min or Max input or output values.

Volume Modulation Params

Parameter Name

The name of the sound instance parameter being used to manipulate volume.

Default

The default volume value used if no parameter is found.

Min Input

The minimum input volume value. Values will be clamped to the [MinInput, MaxInput] range.

Max Input

The maximum input volume value. Values will be clamped to the [MinInput, MaxInput] range.

Min Output

The minimum output volume value. This value is scaled from the [MinInput, MaxInput] range to the [MinOutput, MaxOutput] range.

Max Output

The maximum output volume value. This value is scaled from the [MinInput, MaxInput] range to the [MinOutput, MaxOutput] range.

Param Mode

The mode with which the parameter is applied:

Normal: Clamps input value to the range (MinInput, MaxInput), then maps to the range (MinOutput, MaxOutput).

Absolute: Same as Normal, except that the input value is treated as an absolute value.

Direct: Uses the input value directly, without scaling or reference to Min or Max input or output values.

Crossfade by Distance Node

The Crossfade by Distance node provides the ability to fade between two or more input sounds based on the distance from the Sound Cue's origin to the listener.

For example, a gunshot heard at a distance will sound different from a gunshot up close. This node can calculate the distance the listener is from the shot and play the sound based on a short or long distance, or a mix of the two.

This node differs from the Attenuation node in that the sound will only play if it is within the minimum and maximum distance settings.

Sound Nodes can be connected directly to the Crossfade by Distance node inputs, but you can also add nodes between them for independent control per layer.

Initially, this node has two input pins. Add more pins by clicking Add input.



Property

Description

Cross Fade Input

Fade in Distance Start

The distance from the listener's position at which the sound begins to be audible.

Fade in Distance End

The distance from the listener's position at which the sound reaches full volume.

Fade Out Distance Start

The distance from the listener's position at which the sound begins to fade out.

Fade Out Distance End

The distance from the listener's position at which the sound is no longer audible.

Volume

The maximum volume of the input sound.

If you want to hear the sound up close, then setting Fade in Distance Start to 0 might be a good option.

These values can be set independently for each attached sound.

Crossfade by Param Node

The Crossfade by Param node works similarly to the Crossfade by Distance node, except that the Crossfade by Param node provides a way for you to manipulate the value of a named parameter that controls the crossfade programmatically (with code or Blueprints).

Initially, this node has two input pins. You may add more pins by clicking the Add input button on the node or remove pins by right-clicking them and selecting "Delete Input" from the context menu.

For more information about named parameters, see the Named Parameters section of this page.



Property

Description

Param Name

The name of the parameter used to control the crossfade.

Cross Fade Input

Fade in Param Value Start

The parameter value at which the sound begins to be audible.

Fade in Param Value End

The parameter value at which the sound reaches full volume.

Fade Out Param Value Start

The parameter value at which the sound begins to fade out.

Fade Out Param Value End

The parameter value at which the sound is no longer audible.

Volume

The maximum volume of the input sound.

If you want to hear the sound up close, then setting Fade in Param Value Start to 0 might be a good option.

Delay Node

The Delay node inserts a delay into the Sound Node chain to cause a pause before the input sound is passed to the output. The amount of the delay is a random value between the Delay Min and Delay Max values specified in the Details panel.



Property

Description

Delay Min

Sets the lower bound of time in seconds for the pause.

Delay Max

Sets the upper bound in seconds.

Dialogue Player Node

The Dialogue Player node is a way to set up a Dialogue Wave asset to be played under specific conditions.

Since Dialogue Waves are expected to be used purely for spoken dialogue, the Dialogue Player node requires that you specify both the speaker and the targets of the dialogue being played. This allows the Dialogue Wave to play the correct audio Asset depending on the specific context, such as plurality, gendered language, or for localization purposes.



Property

Description

Dialogue Wave

The Dialogue Wave that the node will play. Click the dropdown to browse for the Asset you want to use.

Context

Who is speaking, and to whom. Note that this can only be used once a valid Dialogue Wave is entered.

Looping

When enabled, the dialogue will play on a loop.

Doppler Node

The Doppler node simulates a Doppler effect, in which a sound's pitch changes based on the source's movement in relation to the listener. The pitch will increase as the source approaches the listener and will decrease as the source moves away.

A common real world example of this is the sound of a passing ambulance's siren.



Property

Description

Doppler Intensity

A multiplier value for how strongly the Doppler effect is heard. Increase the value to make the effect more pronounced.

Use Smoothing

When enabled, the node performs a smooth interpolation on the Doppler effect.

Smoothing Interp Speed

The speed at which the pitch scale is interpolated.

Enveloper Node

The Enveloper node creates an envelope where a sound's volume and pitch are manipulated over a specified time period via distribution curves. These curves can be edited using the embedded Curve Editors, or can be based on curves defined in an existing Float Curve Asset already in the Content Browser.

Optionally, the envelope can be set to loop a set number of times or even indefinitely.

You can use the properties in the Modulation category to randomize predefined values across set points on the envelope.



Property

Description

Looping

Loop Start

The time in seconds where the envelope's loop begins.

Loop End

The time in seconds where the envelope's loop ends.

Duration After Loop

The time in seconds it takes the envelope to fade out after the last loop is completed.

Loop Count

The number of times the envelope will loop if looping is enabled and the envelope is not set to loop indefinitely.

Loop Indefinitely

If enabled, the envelope will continue to loop indefinitely regardless of Loop Count value.

Loop

If enabled, the envelope will loop using the specified loop settings.

Envelope

Volume Curve

The distribution curve that defines the volume envelope. This can be set directly in the Details Panel or to an external curve by clicking on the triangle beside the parameter name and using the expanded External Curve parameter options.

Pitch Curve

The distribution curve that defines the pitch envelope. This can be set directly in the Details Panel or to an external curve by clicking on the triangle beside the parameter name and using the expanded External Curve parameter options.

Modulation

Pitch Min

The minimum pitch for the input sound.

Pitch Max

The maximum pitch for the input sound.

Volume Min

The minimum volume for the input sound.

Volume Max

The maximum volume for the input sound.

Group Control Node

The Group Control node controls which sounds are played based on the number of active sounds, while giving priority to the first available group.

Initially, this node has two input pins. You may add more pins by clicking the Add input button on the node or remove pins by right-clicking them and selecting "Delete Input" from the context menu.



Property

Description

Group Sizes

The maximum number of Sound Wave sources allowed for each group, minus 1 (the first Sound Wave Node is node 0).

Looping Node

The Looping node is used to loop sound indefinitely or a set number of times.

You can loop multiple audio files independently when used in conjunction with the Mixer node.



Property

Description

Loop Count

The number of times to loop the input sound. This can only be edited if the Loop Indefinitely option is disabled.

Loop Indefinitely

When enabled, loop indefinitely regardless of the Loop Count value.

A Looping node should only be used for logical or procedural looping such as introducing a delay because these sounds will not play seamlessly. If you want a sound to loop seamlessly and indefinitely, use the Looping flag on the Wave Player node (see below) for the sound.

Mature Node

With the Mature node, you can flag input nodes as intended for mature audiences. This node uses the value of UEngine:bAllowMatureLanguage to determine whether input nodes should be played.

Initially, this node has two input pins. You may add more pins by clicking the Add input button on the node or remove pins by right-clicking them and selecting "Delete Input" from the context menu.



Mixer Node

The Mixer node defines how concurrent sounds in a Sound Cue are mixed together by providing volume control for each individual input.

Initially, this node has two input pins. Add more pins by clicking Add input.



Property

Description

Input Volume

The list of volumes to use for each of the input sounds, allowing normalization with different source volumes. The topmost input is represented by index 0 and each additional input is incremented in order.

Modulator Node

The Modulator node is used to randomize volume and pitch modulation. You can set maximum and minimum values to determine the range of randomization. When the Sound Cue is triggered, it randomly selects a value within that range.

To set a consistent level for volume or pitch, set the same values for both the minimum and maximum values. This node can also be used to adjust relative volumes of multiple Sound Wave nodes contained within a Sound Cue.

If the Modulator node is used in combination with the Looping node, it will randomize on the each Sound Cue trigger and not on each individual loop.



Property

Description

Pitch Min

Sets the minimum pitch for the input sound.

Pitch Max

Sets the maximum pitch for the input sound.

Volume Min

Sets the minimum volume for the input sound.

Volume Max

Sets the maximum volume for the input sound.

Oscillator Node

The Oscillator node is used to introduce continuous pitch and volume oscillation. This is useful when looping sounds to create a greater degree of ongoing movement.

By setting maximum and minimum values, you can determine the range of randomization.



Property

Description

Modulate Volume

Enables volume modulation.

Modulate Pitch

Enables pitch modulation.

Amplitude Min

The minimum amplitude of the sine wave's modulation, centered around the value set by Center Min and Center Max. For example, an amplitude of 0.25 would oscillate between 0.75 and 1.25.

Amplitude Max

The maximum amplitude of the sine wave's modulation, centered around the value set by Center Min and Center Max. For example, an amplitude of 0.25 would oscillate between 0.75 and 1.25.

Frequency Min

The minimum frequency of the sine wave's modulation, with the value divided by two to equal to the hertz rate. For example, a frequency of 20 would oscillate at 10Hz.

Frequency Max

The maximum frequency of the sine wave's modulation, with the value divided by two to equal to the hertz rate. For example, a frequency of 20 would oscillate at 10Hz.

Offset Min

The minimum offset value into the sine wave, commonly called phase. The value entered here will be multiplied by 2π.

Offset Max

The maximum offset value into the sine wave, commonly called phase. The value entered here will be multiplied by 2π.

Center Min

Both Center Min and Center Max default to 0. Because the default is 0 (not 1), if the amplitude is .2, the sample will be multiplied between -.2 and .2 (instead of .8 and 1.2).

Center Max

See Center Min.

Quality Level Node

By default, there are no quality levels; the designer must add them to the Project Settings for the node inputs to populate. Once populated, node branching can be used to switch between various levels of SoundCue graph complexity. This provides a way for designers to use simpler SoundCue graphs for lower-powered platforms.



The Quality Level node uses GameUserSettings AudioQualityLevel (or the editor override) to choose which branch to play.

At runtime, this node will only load into memory the Sound Waves connected to the branch that is selected.

Random Node

The Random node is used to randomly trigger a node from the list of connected input nodes. Weight values control the probability of a node being triggered relative to the other nodes connected to the Random node.

When an input node is selected randomly, the Sound Cue will play the entire data flow of that selected input.

Initially, this node has two input pins. You may add more pins by clicking the Add input button on the node or remove pins by right-clicking them and selecting "Delete Input" from the context menu.



Property

Description

Weights

The list of weights for each input sound that determines the odds that a particular sound will be chosen. Each item in the Array can be assigned its own weight value.

Preselect at Level Load

If greater than 0, then upon each level load the specified number of inputs will be randomly selected and the rest will be removed. This can be used to cut down the memory usage of large randomizing cues. This setting does not apply during Play In Editor or Simulate; it applies only in game builds outside of Unreal Editor.

Should Exclude from Branch Culling

If set to true, this node will not be culled on load for platforms with a maximum amount of preloaded random branches set in the project settings.

Randomize Without Replacement

When enabled, the entire list of Sound Nodes will be exhausted before repeating a sound.

SoundClass Node

The SoundClass node provides a way to remap which Sound Class asset used with the input node.

For more information about named parameters, see the Named Parameters section of this page.



Property

Description

Sound Class Override

The Sound Class Asset that will override the current Sound Class for the input node.

Switch Node

The Switch node selects an input node based on the value of a runtime integer parameter. The specified parameter must be declared in either code or Blueprints.

Initially, this node has four input pins. You may add more pins by clicking the Add input button on the node or remove pins by right-clicking them and selecting "Delete Input" from the context menu.

For more information about named parameters, see the Named Parameters section of this page.



Property

Description

Switch

Int Parameter Name

The name of the integer parameter that determines which input is used.

Wave Param Node

The Wave Param node uses a named parameter to determine whether to play a different Sound Wave than the one feeding into the input pin. If the specified parameter is set to the name of a valid Sound Wave asset, that asset is played.

If an optional input node is connected and the named parameter is valid, the Wave Param will override the input node when the Sound Cue is played.

For more information about named parameters, see the Named Parameters section of this page.

A potential use for this node would be to play dynamic dialogue lines in between static blip sounds in order to simulate dialogue over a radio. In this way, the same Sound Cue can be reused to great effect.



Property

Description

Wave Parameter Name

The name of the Sound Wave asset to play. If the Sound Wave asset specified does not exist, then the input node is evaluated to determine which sound to play instead.

Wave Player Node

The Wave Player node contains a reference to a Sound Wave asset to be played with the Sound Cue.



Property

Description

Sound Wave

The Sound Wave Asset to use in this node.

Looping

When enabled, the Sound Wave will play on a loop. Additionally, the node type displayed in the Sound Node Graph will be changed to "Looping Wave Player."

Add Comment

Comments can be added anywhere on the Sound Cue. They do not affect the output, but instead are used to call attention to or explain details in the node arrangements or uses.

The comment appears at the top of the frame. There is no limit to the length of the comment.



The comment frame's size can be changed by dragging the lines in the lower right corner and the position can be changed by dragging from anywhere else on the frame. Wherever positioned, it will appear behind the nodes.

If you move a comment box, it will bring any fully contained Sound Nodes along with it.

You can also add a comment by selecting multiple nodes, right-clicking a selected node, and then selecting Create Comment from Selection from the context menu.

Examples

Below are examples of more complex Sound Cue arrangements. You can click on each image to expand it.



This Sound Cue plays one sound if a parameter is set to true, and another if it is set to false.



This Sound Cue changes the Sound Classes of the Sound Waves.



This Sound Cue mixes together Sound Waves with a variety of properties, including attenuation, randomization, looping, and delays.

Introduction

Panning

Determining the Panning Value: The Listener and Speaker Geometry

Listener Geometry

Speaker Geometry

The Center Channel

Computing Pan Values For Mono Sources

Computing Pan Values for Multi-Channel Sources

Performing Audio Panning

Linear Panning

Equal Power Panning

The Problem of Vector Flipping

Soundfield Spatialization

Binaural Audio Spatialization

Interaural Level Difference

Interaural Time Delay

Spectral Shadowing

The Head-Related Transfer Function (HRTF)

Using HRTFs

Hybrid Approaches

Third-Party Plugins

Introduction

In audio, the simulation of sound spatialization, also known as sound localization, is achieved using a wide variety of audio technologies working together. These technologies mimic natural sound phenomena such as orientation, attenuation, propagation, occlusion and obstruction, and reverb.

These phenomena are explained below:

Phenomena

Description

Orientation

The relative orientation between the listener and the sound source.

Attenuation

The distance between the listener and sound source.

Propagation

The paths a sound travels from its source to the listener.

Obstruction and Occlusion

A sound may collide with other objects while it travels towards the listener. These objects act as obstructions to the sound.

Reverb

A sound may take different alternative paths to reach the listener, creating a perceived echo effect.

In the Unreal Audio Engine, and in game audio, the term "spatialization" usually refers to only one aspect of the overall generalized spatialization problem: the techniques and technologies used to orient the sound relative to a listener. Other considerations, such as attenuation, reverb, and occlusion, are usually discussed in that same context. This overview will use the term "spatialization" to exclusively refer to methods of orienting a sound relative to a listener.

The three main methods of spatialization are panning, soundfield spatialization, and binaural audio spatialization.

Panning

Panning is the oldest and simplest way to simulate spatialization. In its most basic form, panning can be achieved by adjusting the relative gain between different audio channels (speakers). Gain is a generic term used to describe the operation of either attenuating (gain < 1.0) or boosting (gain > 1.0) a sound.

For a given sound, making its gain higher in the left channel compared to the right channel will create the illusion that the sound is coming from the left. This is called stereo panning, where "stereo" means that the audio has two channels. It may seem obvious that this would produce the feeling of spatialization, but it's important to note that this illusion is created because the brain has been trained to understand that a sound to your left will sound louder in your left ear compared to your right ear. Technically speaking, this psycho-acoustic experience is referred to as the interaural level difference, where "level" is another term often used for volume.

For speaker setups that have more than two channels, such as quad, 5.1, and 7.1 surround sound, the technique for panning is the same as it is for stereo panning, but it's applied to pairs of speakers instead. When describing panning with more than two speakers, this is known as pairwise panning.

For speaker setups that use more than two channels and have speakers above and below the listening plane, the technique for panning is similar to pairwise panning. However, instead of adjusting the relative gain between two paired speakers, gain is adjusted between speaker triplets (i.e. triangulation). This type of panning is known as vector-based amplitude panning or VBAP.

Determining the Panning Value: The Listener and Speaker Geometry

Before discussing different panning techniques, is it useful to understand how the panning value is calculated based on game geometry. There are two main geometries to consider when computing the pan values: the geometry of the listener, and the geometry of the physical speaker locations.

Listener Geometry

All spatialization techniques depend on the concept of having a listener. The listener is the location and orientation where a virtual listener is maintained. It can be stationary or manually controlled in a 3D environment.

Typically, the listener is attached to the player camera where it's assumed that the "eyes" and "ears" of a game viewport ought to be in the same location. Although this is a reasonable assumption for most situations, there can be more unusual setups depending on the game type or gameplay requirements. For example, a character might have an ability that allows them to hear things from different locations. Another example can be seen in third person games, where designers often split their listener geometry: the location of the listener is set on the character for purposes of distance attenuation, and the camera is used for purposes of panning.

Speaker Geometry

Speaker geometry involves the actual physical arrangement of speakers in the player's environment as they experience the game. For headphones, the arrangement is simple and fixed: speakers are immediately to the left and right of the listener. If the green triangle is the listener's position and orientation, the geometry of headphone speakers is the following:



For surround sound speakers, however, the arrangement is more complicated and depends on the number of speakers and the standard used to position them. The following is a typical arrangement of speakers in a 5.1 surround sound setup (the subwoofer is not pictured):



There are many standard speaker layouts and channel configurations. Typically, games make an assumption about speaker locations based on the standard configuration selected. There are methods of automatically determining speaker locations using noise bursts, sound tones, and microphone analysis, but this is almost never done for video games.

The Center Channel

The center channel is often ignored during pan calculations because it is usually reserved for non-spatialized audio, such as dialogue or interface audio.

This is typically done in cinematic mixing where important dialogue uses the center channel to ensure it is heard clearly. Since dialogue has a narrow spectral band and low power requirements, this has caused many sound systems to underpower their center channels.

Games usually opt to disable panning through the center channel for this reason, and mostly use it for dialogue or other important audio, such as interface audio.

Computing Pan Values For Mono Sources

Given the listener and speaker geometries, a sound's relative location in the world can now be calculated.

Simplifying the speaker arrangement to ignore the center channel in a 5.1 speaker arrangement, we can conceptualize the speaker arrangement as virtual locations within a game world. These locations are relative to the listener's location in the world.

The pan calculation can then be described by the following diagram, where X represents the angle between the line that connects the listener's location to the right speaker, and the line between the listener location and a sound in the world.



If the angles of the speakers relative to the listener are known (or chosen according to a standard), this derived angle X can be used to compute a pan parameter that can be used in the linear pan algorithm or the equal power pan algorithm (see the Performing Audio Panning section below).

PanLeft = X / TotalArcLength PanRight = 1.0 - PanLeft

For example, if the angle X is determined to be 15 degrees, and the total arc length between the left and right speakers is 60 degrees (30 degrees to the right and 30 degrees to the left from center), the pan parameter will be determined to be 0.25 for left and 0.75 for right.

To continue this as the sound pans around the listener, the algorithm only changes by determining which pairs of speakers need to be used to calculate the pan value. The azimuthal arrangement of each of the speakers would be used in the same way to determine the left and right pan parameters.

For non-azimuthal speakers (height speakers), the algorithm is similar but requires three pan parameters instead of two.

Computing Pan Values for Multi-Channel Sources

Panning is computed for multi-channel sources in a similar way to mono source panning. The difference is that, for each of the channels in the source file, a unique panning matrix (how much gain to apply to what output channel) is computed.

For stereo sources, each left and right channel is treated as a mono source. A spread parameter is used to determine the geometry to use for each of the source channels position. This parameter is defined as the actual spatial distance (or half-distance) between each left and right channel.

Note that the orientation of the left and right channels relative to the listener needs to be decided. Typically, for stereo spatialization, the left and right channels are oriented such that they are always orthogonal to the vector pointing from the listener to the source's position.



For channel sources higher than stereo, which are typically even-value counts (4, 6, or 8), a similar algorithm can be employed. Instead of the spread parameter being defined as the distance (or half-distance) from the left and right channels, they are defined as the radius of a circle centered on the source's position. In this case, the source channel virtual points are typically points on the edge of the circle, spread equally.



For higher channel spatialization, since there is no clear source orientation preference (like there was with stereo sources, where we can just prefer they maintain orthogonal orientation), we need to also supply a separate vector from which to orient the channel positions. Usually, the source's own orientation vector is used to orient the source channel positions.

Performing Audio Panning

There are two main methods of performing audio panning: linear panning and equal power panning.

Linear panning is the simplest panning technique where the relative gain of the sound between paired channels is linearly interpolated and the total gain is held constant.

When using two channels (left and right), the following gain computation equations are used:

GainLeft + GainRight = 1 GainLeft = X GainRight = 1 - X

Linear panning, visualized, looks like like this:



Linear panning is straightforward to compute but it has a fundamental drawback: loudness (volume), which is the term used to describe the perceptual experience of sound amplitude, is not determined by the actual amplitude of an audio signal but by the power of the audio signal. Power is equal to the square of the signal's amplitude. If the amplitude, or gain, of a sound is X, the power for panning calculations is computed by the following equations:

PowerLeft = GainLeft2 = X2 PowerRight = GainRight2 = (1 - X)2

And the total power is computed by adding up the computed power in the left and right channels:

PowerTotal = GainLeft2 + GainRight2 PowerTotal = X2 + (1 - X)2

Using the gain values with this equation demonstrates that the power is not constant. The power, and thus the loudness, will drop when the sound is panned in the middle (X = 0.5) vs. the sides (X = 0.0 or X = 1.0).

The following is the power, or perceived loudness, in the center of a pan between left and right channels:

PowerTotal = (0.5)2 + (1 - 0.5)2 PowerTotal = 0.25 + 0.25 PowerTotal = 0.5

While the following is when the sound is either to the right or the left:

PowerTotal = (1)2 + (1 - 1)2 PowerTotal = 1 + 0 PowerTotal = 1

This change in power during panning will affect the game's overall audio experience, as the sound will appear to move through the speaker field non-linearly.

For stereo (headphones or speakers), the sound will appear to "stick" to the edges. For surround sound panning, as a sound crosses over a speaker location, it will get loud and then dip in loudness between speakers. This creates uneven loudness as a sound rotates or moves around the listener.

Since gain reduction is a primary method for the simulation of distance attenuation, this gain reduction can also cause sounds to be interpreted by the brain as moving closer and further away from the listener, even though the audio engine's intention is that the sound is merely moving around the listener.

The equal power panning method counters the loudness dips present in linear panning by boosting the loudness perfectly to maintain constant power. This technique retains constant loudness by holding the power constraint during the pan, instead of holding the amplitude constant.

Returning to the total power equation, we solve for X where the result is that the total power is constant for every value of gain, X (i.e. 1.0).

PowerTotal = GainLeft2 + GainRight2 = 1.0

There are several possible solutions to this equation. In audio, a square root solution (called the square-root panning law) or a sine / cosine equation (called the cosine panning law) can be used.

If X is a panning parameter number between 0.0 and 1.0 (where 0.0 is fully left and 1.0 is fully right), the following gain computation equations are used to maintain equal power.

For the square-root panning law, the left and right channel gains are computed as:

GainLeft = √X GainRight = √(1 - X)

Where it can be seen that the total power is always maintained constant:

PowerTotal = (√X)2 + (√(1-X))2 PowerTotal = X + (1-X) PowerTotal = 1

For the cosine panning law, the left and right channel gains are computed as:

GainLeft = Sin2 (X) GainRight = Cos2 (X)

To see that this also satisfies the requirement to maintain constant power, recall the trigonometric identity that defines a unit circle (a circle of radius 1):

Sin2(θ) + Cos2(θ) = 1

Graphing what this panning law outputs, it can be seen that the actual gain values are not linear:



For panning calculations involving a third dimension, such as height speakers, the equal power constraint would be calculated using the following equation:

PowerTotal = GainA2 + GainB2 + GainC2 = 1.0

Note that most game audio engines forgo this calculation when panning to height channels and instead use object-based rendering methods, such as Dolby Atmos and DTS:X, which are rendered outside of audio engines. Audio rendering for game engines becomes significantly more complex and computationally costly the larger the number of channels used.

One issue with the panning algorithm is the case where a moving sound source traverses across the listener, such that the vector pointing from the listener to the position of the source instantly changes direction.



Since this vector is primarily used to determine gain values in a speaker array, it will result in a sudden change in gain from one moment to the next, as the sound moves from one side of the listener to the other. In the above diagram, between cases 2 and 3, the blue source moves across the listener origin and the vector which is used to compute gain values jumps from pointing forward to pointing behind. This "vector flip" will cause a discontinuity in the audio signal, which is perceived as a click or pop and is a classic edge case many engines which utilize 3D panning will fail to account for.

The primary method of avoiding this discontinuity is to utilize an omni-directional blend to all speakers or a portion of speakers to "smooth out" any discontinuities that might happen due to this vector-flip. Typically, there will be a user-defined radius below which the sound source will blend to an omni-directional pan. This removes the ability to localize the sound during this transition.

When panning sound sources that are within the virtual radius of the speaker configuration, there is no way to spatially differentiate (via gain values in speaker channels) a sound source between cases 1 and 2 and between cases 3 and 4. Thus "near-field" panning is traditionally problematic.

Soundfield Spatialization

Another spatialization technique ideal for speaker-based spatialization is to use a spherical harmonic representation of a sound field. The preferred term used to describe this method is "sound fields", but they are also widely known as "ambisonics".

Spherical harmonics are a wave-based way to represent vibrations of a field in three dimensions (spherically). They are used in many domains where an arbitrarily high resolution of spatial information is necessary.

Conceptually, spherical harmonics are a spatial equivalent to the Fourier theorem, where any periodic function can be represented as a series of sinusoids of various frequencies and amplitudes. In this way, spherical harmonics can be thought of as a series of functions which can precisely define a three-dimensional field.

Practically speaking, the order of a spherical harmonic (or soundfield / ambisonics) representation describes how well-resolved the spatial representation is. The higher the harmonic order, the more terms in the spherical harmonic expansion are included, and the more well-resolved (sharper) the spatial representation is. However, the more orders used, the more expensive they are to compute and the more memory is required to represent them.

The benefits of using sound fields over panning is that they tend to have a significantly better result in localizing sound sources between speaker positions. Where the quality of panning methods increases linearly with the number of speakers used, sound fields can achieve very high quality results with very few speakers.

Another significant benefit of sound fields is that they encode and preserve their spatial information independent of speaker or channel configuration. They retain their spatial information in a channel-agnostic way under rotational transformations, mixing, and so on.

3D sound sources can be encoded to a sound field representation, mixed with other sound field formats, and then, at the last step in the rendering pipeline, decoded to match a precise output channel format. This means that audio content can be pre-baked in a sound field format and decoded locally to a particular local player's hardware configuration that is ideal for their listening environment. Without this ability, multi-channel sound sources need to be downmixed (e.g. 7.1 content downmixed to stereo) to fit a local hardware configuration. This downmixing process inevitably loses important spatial information. Sound fields, on the other hand, would merely decode to whatever channel configuration exists.

It's important to note that sound fields on their own can't be directly listened to in a way that would be identified as spatial. They require a decoding step to a traditional speaker / channel format, where the sound field is essentially resolved to a set of channel gains that are applied to channels similar to the way panning works. Interestingly, sound fields will usually result in non-zero gain values that are spread around a surround-sound channel configuration even though they will audibly sound like they are spatialized in any given direction.

Finally, it's possible to capture a real-world sound field using particular microphone configurations which capture audio in a way that is directly encoded into a sound field format. Usually, sound field microphone arrays record sound fields of lower order due to hardware and microphone cost, but expensive, higher-order sound field microphone arrays do exist. This technique makes sound field recordings of environmental audio particularly powerful as a technique to gather complex and spatial source material.

Binaural Audio Spatialization

If the audio is designed for headphones, then a variety of psycho-acoustic phenomena can be taken advantage of to increase the quality of spatialization. In audio technology, it's more common to hear this type of spatialization referred to as binaural spatialization (as opposed to headphone spatialization). The term "binaural" comes from the fact that humans (and most animals) have two ears. It is the acoustical equivalent to the term binocular.

There are three main components to the way your ears physically localize sound binaurally: interaural level difference, interaural time delay, and spectral shadowing.

Interaural Level Difference

Interaural Level Difference (ILD) is the component of spatialization perception derived from the fact that ears are spread apart in space physically, and the volume (power) of sounds drops off as a function of distance. This means that a sound to the left of your head will sound slightly louder to your left ear than the right ear.

ILD is the primary perceptual reason why panning audio works and is a significant component to binaural spatialization. The primary factor that influences the ILD effect is the size of a person's head (or, more specifically, the distance between their ears).

Interaural Time Delay

Interaural Time Delay (ITD) is the component of spatialization perception derived from the fact that ears are spread apart in space physically, and it takes time for sound to travel through the air. This means that a sound to the left of your head will arrive at your left ear slightly faster than it will arrive at your right ear.

This effect is extremely small but detectable by the brain, and is a significant component to sound localization. Similar to ILD, the primary factor that influences the ILT effect is the size of a person's head.

Spectral Shadowing

Sound is a wave that diffracts when it comes in contact with a medium or obstruction. This diffraction can be quite complex and result in tiny variations and fluctuations in sound. This variation can occur in terms of loudness and frequency filtering.

If the spectral shadowing of a sound is consistent and predictable as a function of angle to your ears, the brain can interpret that information and derive valuable location information. This is one of the reasons why ears are oddly shaped and have little rivulets. These complex shapes are unique to each person but have evolved to help the brain with disambiguating and fine-tuning spatial information due to this spectral shadowing.

This effect is extremely individualized, and therefore very difficult to simulate in audio engines.

The Head-Related Transfer Function (HRTF)

The Head-Related Transfer Function, or HRTF, is used to combine all the psycho-acoustic factors that go into binaural spatialization together.

HRTFs are data-derived filters that are built by recording impulses as a function of angle, relative to a representative listener geometry.

A dummy head is used that is precisely the average head size (for a human) and average ear shape. Microphones are inserted into the ears of the dummy head, and impulses (tiny noise bursts) are recorded as a function of angle. Below is an example of a dummy head with a modeled ear with microphones placed inside the ear canal.

The derived filter is called Impulse Response (IR). As long as the system is time-invariant (doesn't change over time) and linear (doesn't have a non-linear mapping of inputs to outputs), IRs are filters that can represent all the complex details of that system without actually knowing all the internal details.

Since a person's ear shape and arrangement of parts is unique, a common IR set from a standard dummy will not result in the most accurate experience for many people. For this reason, many different IR data sets are produced to compensate for this.

By recording how a system modifies a single audio sample, subsequent samples can be processed by the recorded data set (by a process called convolution) and it will be as if those samples were processed by the original system.

HRTF data sets store IRs as a function of angle relative to the head. This is why a game audio engine uses the angle of the sound relative to the listener to look up the closest data set match at that angle. Some HRTF rendering techniques snap to the nearest IR and others perform interpolation between IR sets to get a more continuous IR.

The selected IR data set is then convolved with the input audio, and the output takes into account ILD, ITD, and the spectral characteristics of the actual shape of the ears and head. The result is usually significantly more localizable for sounds than any one technique implemented on its own.

The downside of HRTF rendering (and binaural methods in general) is that it only works well with headphones. The filters and the delays break down when heard on stereo speakers, and the actual feeling of spatialization can be much worse than if traditional panning was used.

Hybrid Approaches

There are spatialization techniques that combine different elements of the above spatialization methods.

A common hybrid approach does the following:

Encodes spatial information of individual sound sources into a channel-agnostic sound field.

Mixes those sound field sources together.

Decodes the sound field into an arbitrary virtual speaker / channel configuration.

Instead of outputting the decoded audio out to actual surround sound hardware, it outputs the virtual speaker audio into a binaural rendering process. This is a method widely used by "3D Audio" headphones that take surround sound output from a game and make it sound more three-dimensional for headphones. Some software techniques also use this method because it can result in overall lower CPU costs to get the benefits of HRTF spatialization.

Third-Party Plugins

Unreal Engine provides several third-party spatialization plugins. For additional information, refer to the third-party's official documentation.

Plugins handle channel management which may produce undesired results with multi-channel sources, as Unreal Engine only supports spatialization for mono and stereo sources.

Attenuation (Volume)

Attenuation (Spatialization)

Attenuation (Air Absorption)

Attenuation (Focus)

Attenuation (Reverb)

Attenuation (Occlusion)

Attenuation (Priority)

Attenuation (Submix)

Attenuation (Source Data Override)

Attenuation Plugin Settings

Reference for the Sound Attenuation settings asset, which controls various aspects of how sound behaves over distance relative to the listener. Usually, the player is the listener, but not always, and so for the purposes of this document, we will use the term ‘listener'.

Attenuation (Volume)



This section defines how the sound's volume will reduce (attenuate) as the listener moves away from it. The volume of the sound will be at its maximum within the inner area of the attenuation shape. As the listener moves away from this inner area the sound will decrease in volume, reaching its minimum volume at the boundary of the outer area. The rate of attenuation relative to distance is determined by the attenuation function.

Attenuation Function

This property defines the function that determines the rate of attenuation over distance. There are a number of different functions to choose from:



This is the default function. When using this function the volume will attenuate linearly and so the changes in volume are constant as the listener moves towards and away from the source. This function is good for crossfading between large background-type sounds that don't need tightly focussed 3D spatial falloff settings.



When using this function the volume attenuates such that the changes in volume are greater at close distances, and lesser at far distances. This function is good for spot sounds that need good 3D positioning, while still being audible at reasonable distances.



When using this function, the changes in volume are similar to that of the logarithmic curve, but are more exaggerated. This function is good for sounds that only need to be just audible at far distances, but that gets significantly louder as the listener gets quite close to the source.



When using this function, the changes in volume are lesser at close distances, with more dramatic differences at far distances. This function is good for sounds that need to be loud across larger distances.



This function attempts to model a more ‘naturalistic' falloff behavior to produce behaviors that closer match reality. This function is a kind of ‘middle ground' between the Logarithmic and Inverse functions.



Click for full image.

This allows you to define your own custom function when none of the provided ones give you the required behavior. You can either draw one directly into the curve editor window, or assign a pre-existing Float Curve asset.

Attenuation Shape

This property defines the shape that is used to define the minimum and maximum attenuation points of the sound.



This is the default and produces a spherical attenuation shape, which is useful for most spot sounds as it models how sound propagates in the real world.





This produces a capsule attenuation shape (a cylinder with rounded ends), this is useful for things like water pipes, where the sound doesn't want to appear to come from a single, specific point in space — the sound of gurgling water would follow the length of the pipe





This produces a box attenuation shape, this is useful for things like room tones/ambiance as you can define the shape of the box to match that of the room.





This produces a cone attenuation shape, this is useful in situations when you want a directional attenuation pattern — for example, public address speakers.



Inner Shape Areas

These properties define the inner area of the attenuation shape — the area where the sound will be at maximum volume (in other words, completely unattenuated). They are measurements of distance from the origin of the source sound in Unreal Units.

The exact property you see depends on which attenuation shape you have chosen.

This property defines the inner area of the sphere attenuation shape.



This property defines the height of the inner area of the capsule attenuation shape (termed ‘half height' as it's measured from the sound's origin which is at the midpoint of the capsule).



This property defines the radius of the inner area of the capsule attenuation shape.



This property defines the dimensions of the box attenuation shape (as measured from the sound's origin). There are 3 values to this property: x, y, z.



This property defines the length of the inner area of the cone attenuation shape (as measured from the sound's origin).



This property defines the width (in degrees) of the inner area of the cone attenuation shape (as measured from the center of the cone).



This property defines the width (in degrees) of the outer area of the cone attenuation shape (as measured from outside of the cone angle).



This property defines the distance directly behind the sound's origin from where you want the cone to start (this is independent from the other properties, so will extend the cone backward rather than shift it backward).



Falloff Distance

This property defines the size of the outer area of the attenuation shape. This is the same property regardless of shape and is measured from the edge of the inner area.









Enable Volume Attenuation

This property is used to enable or disable the distance-based volume attenuation.

When true, the sound will attenuate over distance according to the settings defined above.

When false, the sound will play at full volume irrespective of the distance between the sound and the listener.

Attenuation (Spatialization)



This section defines how the sound will spatialize in the game world. You can choose the method of spatialization that best suits your project, as well as experiment with different settings for how your sounds will behave as the listener moves around them.

Enable Spatialization

This property enables or disables spatialization of the sound.

When true, the sound will be spatialized from a specific location within the game world and will pan accordingly as the listener moves around. Use this if you want the sound to appear to come from a particular location in the game world (eg. a spot source sound).

When false, the sound will be non-spatialized, and will effectively become a 2D ‘flat' sound and so no panning will be applied, regardless of the sound's source position relative to the listener. The exact nature of this process will depend on the configuration of your speakers and the format of your sounds. For example, if you're using stereo playback, then a mono sound will be upmixed to stereo, while quad, 5.1, and 7.1 sounds will be downmixed to stereo. You can set the method used when upmixing mono sounds within Project Settings > Engine > Audio > Quality > Mono Channel Upmix Method. Use this if you don't want the sound to come from a particular location in the game world (such as an area loop or room tone).

Spatialization Method

This property allows you to define which panning method you want to use when spatializing the sound. Currently, there are 2 options:

This is the default and uses Unreal Engine's standard panning method to calculate spatial positioning. When using this method you can define as a global project setting whether to use linear or equal power panning. This can be found within Project Settings > Engine > Audio > Quality > Panning Method. This method is the best one to use if playing back over loudspeakers.

This uses whatever binaural plugin you have enabled to handle the spatial positioning of your sound. The plugin can be set within Project Settings > Platforms > [YourPlatform] > Audio > Spatialization Plugin. You can use the built-in spatialization plugin, or enable a third-party one via the Plugins window. This method requires playback over headphones as binaural panning does not translate well over loudspeakers.

Non-Spatialized Radius

The property defines the distance threshold below which the sound will start to transition from being spatialized to non-spatialized (becoming a 2D sound). This is useful for preventing sudden, and jarring jumps in the spatial position of a sound when close to the source. It is also useful for helping ‘large' sounds to fill the spatial field when up close (such as large machines, waterfalls, etc).

In the image below, the sound of a large machine has been set to have a non-spatialized radius of 450 (depicted by the green sphere). When the listener is beyond this, the sound will be spatialized as normal, but as the listener crosses the threshold all channels of the sound will start to bleed to all channels of the speaker configuration. This process is interpolated, starting at the defined threshold and ending with a 100% bleed at the sound's origin. As an example, a stereo sound being played back on a 5.1 system would have its left channel bleed to all 5 channels, and its right channel bleed to all 5 channels. The result of this is a sound that starts to fill the spatial field (in whatever speaker configuration you're using, the sound will start to come from all the speakers) giving a much more convincing sense of scale.



3D Stereo Spread

This property defines the distance between the left and right channels of a stereo sound when spatialized in the game world. This is useful for creating a greater sense of width and size when using stereo sounds. It can also help mitigate sudden jumps in the spatial position of the source. In the image below, the green and red spheres depict the left and right channels of the stereo sound which have been positioned either side of the machine through the use of this parameter.



Normalize 3D Stereo Sounds

This property is used to enable or disable a 6dB gain reduction applied to stereo sounds which are being spatialized in the world. This is useful if you find the sound clipping due to channel summing when the stereo spread reduces to 0.0, either as a result of the 3D Stereo Spread property above, or through distance-related panning.

Attenuation (Air Absorption)



This section defines how the algorithm that attempts to model the effect air absorption has on the sound behaves, namely that higher frequencies decay quicker than lower frequencies relative to distance.

You can define a distance range within which the filter will be applied and then use the low pass cutoff frequency settings to determine how much filtering you want — the filter will interpolate between the min and max cutoff frequency as you move between the min and max distances. As well as a low pass filter for modeling air absorption, you also have a high pass filter that could be used to reduce the perceived size of the sound relative to distance.

In the image below, the green circle represents the min distance, and the red circle the max distance — any filter settings will be applied and interpolated between these two distances.



Enable Air Absorption

This property enables or disables the air absorption model.

If true, then the sound will be processed using a low pass filter whose cutoff point varies relative to the listener's distance from the sound's source (as configured by the settings below).

If false, then the sound will go unprocessed.

Min Distance Range

This property defines the minimum distance from the sound's source at which the filter should be applied. You should experiment with different settings to find the point that best suits the sound you are using (but a good starting point would be based on the inner range of your attenuation distance settings).

Max Distance Range

This property defines the maximum distance from the sound's source at which the filter should be applied. You should experiment with different settings to find the point that best suits the sound you are using (but a good starting point would be based on the falloff range of your attenuation distance settings).

Low Pass Cutoff Frequency Min

This property defines the cutoff frequency of the low pass filter when at the Min Distance Range (as defined above). You should experiment with different settings to find the value that best suits the sound you are using, but given that in reality there is little air absorption effect when in close proximity to a sound, higher values here work well.

Low Pass Cutoff Frequency Max

This property defines the cutoff frequency of the low pass filter when at the Max Distance Range (as defined above). You should experiment with different settings to find the value that best suits the sound you are using, but given that, in reality, there is more air absorption effect when further away from a sound, lower values here work well.

High Pass Cutoff Frequency Min

This property defines the cutoff frequency of the high pass filter when at the Min Distance Range (as defined above). You should experiment with different settings to find the value that best suits the sound you are using, but subtle values work best here (for the most part). Given that you will likely want the sound to feel large when up close, lower values here work well.

High Pass Cutoff Frequency Max

This property defines the cutoff frequency of the high pass filter when at the Max Distance Range (as defined above). You should experiment with different settings to find the value that best suits the sound you are using, but subtle values work best here (for the most part). To make your sound feel smaller in size, and less dominant, when at a distance higher values here work well.

Enable Log Frequency Scaling

This property is used to enable or disable the application of a logarithmic scale to the filter cutoff frequency values as they are interpolated relative to the listener position. Depending on your settings, you may find the default linear scale produces some extreme and unnatural sounding results. If so, you can enable the log scale which should smooth out the changes as it will produce a perceptually linear frequency sweep.

Absorption Method

This property is used to determine whether you want to use either the inbuilt scaling function (log or linear from above) or whether you want to create your own custom curve for how the interpolation is scaled over the filtering distance.

You have two choices:

This uses the inbuilt scaling function (either linear or logarithmic depending on the property above).

This enables you to create custom scaling curves for the low pass and high pass filters independently.



Click for full image.

Attenuation (Focus)



This section controls some additional processing that you can use to the ‘focus behavior' of sounds. There may be times when you want a sound to be more prominent depending on its position relative to the listener's rotation. For example, you may have certain sounds that belong to a special pickup item that is usually (intentionally) masked slightly by the rest of the mix, but if the player is looking directly at (or nearly directly at) the pickup item, you may want to bring the sound up in the mix slightly to accentuate it. Alternatively, you may want to set this listener focus behavior up across all your sounds in order to try and emulate the perceptual differences that arise from the fact that we tend to focus our attention on sounds that are directly in front of us.

With these settings you can control the angles that determine whether a sound is classed as being in or out of focus, the amount of scaling to apply to a sound's distance calculations and priority settings based on whether it is in or out of focus, the amount of attenuation to apply to in and out of focus sounds, and the interpolation speed for these settings as sounds move in and out of focus.

In the image below, the green cone depicts the angular area in which objects are classed as being in focus, the red cone depicts the transition area — anything beyond this is classed as being out of focus.



Enable Listener Focus

This property enables or disables the listener focus system.

If true, then the sound will check to see whether it is in or out of focus and apply the various scaling factors accordingly.

If false, then the sound will simply behave according to its usual attenuation, distance, and priority settings.

Focus Azimuth

This property determines the azimuth (horizontal rotation) angle that a sound needs to be within in order to be classed as in focus, and is expressed in degrees. An angle of 0 degrees would be directly in front of the listener's forward vector.

Non-Focus Azimuth

This property determines the azimuth (horizontal rotation) angle that a sound needs to be beyond in order to be classed as out of focus, and is expressed in degrees. An angle of 0 degrees would be directly in front of the listener's forward vector.

Focus Distance Scale

This property defines the scaling value that will be applied to the sound's calculated distance from the listener, and therefore the attenuated volume of the sound. A value of less than 1.0 here will result in the sound appearing to be closer to the listener than it actually is when it is in focus.

Non-Focus Distance Scale

This property defines the scaling value that will be applied to the sound's calculated distance from the listener, and therefore the attenuated volume of the sound. A value greater than 1.0 here will result in the sound appearing to be further away from the listener than it actually is when it is out of focus.

Focus Priority Scale

This property defines the scaling value that will be applied to the sound's priority setting (which is defined within the sound itself). A value greater than 1.0 here will result in the sound's priority setting increasing when it is in focus.

Non-Focus Priority Scale

This property defines the scaling value that will be applied to the sound's priority setting (which is defined within the sound itself). A value of less than 1.0 here will result in the sound's priority setting decreasing when it is out of focus.

Focus Volume Attenuation

This property defines the scaling value that will be applied to the sound's volume when it is classed as being in focus. This occurs after the sound's initial volume has been scaled relative to its distance from the listener according to the Attenuation Distance settings above. A value greater than 1.0 here will result in sounds being boosted in volume when in focus.

Non-Focus Volume Attenuation

This property defines the scaling value that will be applied to the sound's volume when it is classed as being out of focus. This occurs after the sound's initial volume has been scaled relative to its distance from the listener according to the Attenuation Distance settings above. A value less of than 1.0 here will result in sounds being reduced in volume when out of focus.

Enable Focus Interpolation

This property allows you to enable or disable the focus interpolation system — this can be used to smoothly transition between settings when sounds move between being in or out of focus.

If true, interpolation will be applied to the various settings above when moving between being in or out of focus.

If false, the system will simply switch between the settings defined above when the sound between being in and out of focus.

Focus Attack Interp Speed

This property defines the interpolation speed used when moving from being out of focus to in focus. Smaller values here result in quicker transition times.

Focus Release Interp Speed

This property defines the interpolation speed used when moving from being in focus to out of focus. Smaller values here result in quicker transition times.

Attenuation (Reverb)



This section defines the relationship between the sound's distance from the listener and the amount of reverb that is applied to the sound. This assumes you have either defined a default reverb setting within the World Settings or the sound is within an audio volume with a reverb effect applied, and the sound's sound class settings allow for reverb to be applied.

You can control the method used to determine the reverb send level, the amount of the sound to send to the reverb effect (Reverb Min/Max Send Level) and how this might vary with the sound's distance from the listener (Reverb Min/Max Send Distance).

Enable Reverb Send

This property enables or disables the reverb send system.

If true, the sound will be processed by the assigned reverb effect according to the settings defined below.

If false, the sound will not be processed by reverb and will be completely dry.

Reverb Send Method

This property defines the method used to determine how much of the sound is sent to the reverb effect.

The amount of the sound sent to the reverb effect will be determined by interpolating between the values defined in the Min/Max Send Levels, over the distances defined in the Min/Max Distance values.



Click for full image.

The amount of the sound sent to the reverb will be determined by the curve you have defined, over the distances defined in the Min/Max Distance values.

The amount of the sound sent to the reverb will be defined by a single constant value — this doesn't change relative to distance, and so is probably most useful for non-spatialized ‘ambiance-style' sounds rather than point-source 3D sounds.

Reverb Min Send Level

This property is only available when using the Linear Send Method, and determines the amount of reverb to apply to the sound when at the distance defined in the Min Distance property. Typically you would use lower values here so that there appears to be more direct than reverberant sound when close to the sound's source.

Reverb Max Send Level

This property is only available when using the Linear Send Method, and determines the amount of reverb to apply to the sound when at the distance defined in the Max Distance property. Typically you would use higher values here so that there appears to be more reverberant than direct sound when far away from the sound's source.

Reverb Min Distance

This property defines the distance from the sound's source that will correspond with the Min Send Level (when using the Linear Send Method), or the lowest value of your Custom curve.

Reverb Max Distance

This property defines the distance from the sound's source that will correspond with the Max Send Level (when using the Linear Send Method), or the highest value of your Custom curve.

Attenuation (Occlusion)



This section defines how the in-built occlusion system will behave in order to simulate the effect of sound being reduced in high-frequency content and/or amplitude as a result of an object being between the source and the listener.

You can control how the engine will check for obstructions, as well the severity of low pass filtering and volume reduction should an obstruction be found. You can also change the speed that, as a result, any changes to the sound will occur.

Enable Occlusion

This property enables or disables the in-built occlusion system.

If true, the in-built system will check for obstructions and apply the settings defined below.

If false, the in-built system will be turned off, and unless you're using a 3rd party plugin (defined in the Plugin Settings below), your sounds will not emulate occlusion.

Occlusion Trace Channel

This property determines which trace channel will be used to determine whether there is an obstruction between the source and the listener. The default here is Visibility, which would probably work fine for most purposes — essentially, if the object has collision set up in its properties then it will work with this setting. If you want to exclude any specific objects from the occlusion system, so that they didn't form obstructions to your sounds, you can do this by setting their Collision Response property for the channel you're using (for example Visibility) to ‘Ignore' (you may have to change the Collision Preset property to ‘Custom' to access this — this may have implications on the correct functioning of other systems, so do this with care. It may be better to set up a custom Audio Trace channel).

Occlusion Low Pass Filter Frequency

This property defines the cutoff frequency of the low pass filter that will be applied if the system detects an obstruction between the sound source and the listener. The lower the values used here, the more extreme and noticeable the filtering effect will be.

Occlusion Volume Attenuation

This property defines how the scaling value applies to the sound's volume if the system detects an obstruction between the sound source and the listener. The lower the values used here, the more extreme and noticeable the volume reduction will be.

Occlusion Interpolation Time

This property defines the transition time for the occlusion effect as a sound alternates between being obstructed and not obstructed. The lower the values here, the more responsive the system is able to be, but depending on your settings this can produce some fairly extreme behavior. It's a good idea to experiment with different time values to find what works best for different situations.

Use Complex Collision for Occlusion

This property allows you to enable and disable the use of complex collision models for the obstruction system. By default, the system will use an object's simple collision to check for obstructions as this is significantly cheaper in terms of resources. However, if the objects in your level have complex shapes, then you may find that this produces unconvincing results — for example, sounds may be flagged as obstructed even though they are not. In the screenshots below, you can see the difference between an object's simple and complex collision models, and how if the listener was towards the bottom of the object then it could produce the problem highlighted above.





Attenuation (Priority)



This section determines whether sound can play or remain active if the channel limit is met. You can choose the method of priority attenuation, and define the minimum and maximum distance to attenuate priority.

Enable Priority Attenuation

This setting enables or disables the attenuation of sound priority based on distance.

Priority Attenuation Method

This property defines the method used to control priority attenuation.

A priority attenuation is based on linear interpolation between a distance range and a priority attenuation range.

A priority attenuation based on a supplied curve.

A manual priority attenuation based on a static priority scalar. This setting can be useful for 2D sounds.

Priority Attenuation At Min Distance

Interpolated value to scale priority against when the sound is at the minimum priority attenuation distance from the closest listener.

Priority Attenuation At Max Distance

Interpolated value to scale priority against when the sound is at the maximum priority attenuation distance from the closest listener

Priority Attenuation Min Distance

This property defines the minimum distance to attenuate priority.

Priority Attenuation Max Distance

This property defines the maximum distance to attenuate priority.

Attenuation (Submix)



Click for full image.

This section allows sending sound sources to a submix in a convenient way. You can set up submix sends on large numbers of assets from one place. These settings can be useful when volume attenuation is also defined.

Enable Submix Send

This property enables or disables submix sends based on distance.

Submix Send Settings

This property defines a set of Submix Send Settings to use when sending audio to submixes as a function of distance.

Submix to send audio to based on distance.

This property defines the method used for submix sends.

The amount of the sound sent to the Submix when the sound is located at a distance equal to the value specified in the Submix Min Send Distance.

The amount of the sound sent to the Submix when the sound is located at a distance equal to the value specified in the Submix Max Send Distance.

This property defines the minimum distance to send to the Submix.

This property defines the maximum distance to send to the Submix.

This property defines the manual Submix send level. Doesn't change as a function of distance.

This property allows you to define a custom curve to use for distance-based send level.

Attenuation (Source Data Override)



This section contains settings to use with the Source data override plugin.

Enable Source Data Override

This property enables or disables overriding WaveInstance data using the Source data override plugin.

Source Data Override Plugin Settings

This is an array of settings to use with the Source data override plugin. Not all audio plugins utilize this feature.

Attenuation Plugin Settings

This section allows you to define any settings made available to you by the developers of any third-party plugins you choose to use for either Spatialization, Occlusion, Reverb, or Source Data Override. If you are using the native built-in systems, then this section will be empty.

Spatialization Plugin Settings

This is where any spatialization plugin settings will appear.

Occlusion Plugin Settings

This is where any occlusion plugin settings will appear.

Reverb Plugin Settings

This is where any reverb plugin settings will appear.

Source Data Override Plugin Settings

This is where any source data override plugin settings will appear.

The Challenge of Capturing and Representing Soundfields

Ambisonics in Unreal Engine

Importing and Playing an Ambisonic Audio Asset

Soundfield Submixes

Soundfield Encoding Compatibility

Conclusion

A soundfield is an audio representation of a spatial area, real or virtual. One of the most challenging problems in both real-world and virtual audio is how to best capture and represent a soundfield.

The Challenge of Capturing and Representing Soundfields

If you have ever taken microphones to a beach, a forest, or any other locale that you wanted to capture as a soundscape, you already have hands-on experience with the difficulties you might encounter. For example, say that you bring a single cardioid microphone into the forest and you are able to get a great audio recording of a bird cawing as it flies from your right side to your left. Assume that your microphone is equally sensitive in all directions, and that the bird is continually cawing at the same volume. You can play back that recording at equal volume in the left and right channels of your home speaker setup:



The caw of the bird flying past the microphone will natively have the same volume in both speakers.

Because of the limitations of this recording setup, you did not record the bird in a way that would give the listener an idea of where the bird is in relation to that listener, or in which direction the bird is flying. The recording will sound louder in both speakers as the bird gets closer to the microphone, and quieter in both as the bird flies away.

If you were able to record this bird with two microphones spaced some distance apart, one for each speaker you play the sound back on, you would have vastly more information:



With two microphones, the caw of the bird will be louder in the first mic and softer in the second, then louder in the second as the sound grows softer in the first.

As the bird moves from right to left, it becomes louder in the left microphone and quieter in the right microphone.

By using two microphones to record a stereo audio asset, we've already captured important spatial information from the soundfield into our audio stream: how far to the left or right of the microphones the bird currently is. If we added more microphones, we could capture more spatial information about the bird's location and motion in space, including if the bird flies behind our microphone array instead of in front of it, and even how high the bird is above our array of microphones.

Downmixing is the process of taking an audio source and rendering it as a number of speaker outputs. If you're familiar with the way that downmixing occurs in games, you might notice that it is analogous to the microphone array described in the previous diagram.

Typically, an audio source is played in each speaker, and the loudness is directly proportional to how close the source is to where that speaker would be in the game world relative to the other speakers.

A typical panning system is analogous to placing an omnidirectional microphone where a speaker might be in the game world. When we downmix our game to stereo, we are preserving information about how far to the left or right of the player an audio source is.

Downmixing audio to 5.1 or 7.1 gives additional information about whether the source is in front of or behind the player, based on how loud the source is in the surround-left and surround-right channels compared to the front-left and front-right channels.

For many applications, this may be enough information for the player to be able to localize an audio source. However, for many use cases, it would be ideal to also have elevational information. There are many ways of retaining the 3D position of an audio source when encoding (capturing) a representation of a soundfield that allow easy decoding (playback) on any speaker configuration needed. These methods provide a rich spatial audio experience.

One of the most popular soundfield representations for retaining both elevational and azimuthal information about audio when downmixing sources is called ambisonics.

Ambisonics in Unreal Engine

Ambisonics is a specific soundfield representation that projects positional audio onto a sphere using spherical harmonics. You may recognize spherical harmonics from their use in lighting for video games — ambisonics is the equivalent for sound. The higher the order of ambisonics we use, the higher the spatial resolution of our ambisonic audio stream will be, resulting in easier-to-localize audio when we decode the ambisonic audio stream to speaker positions.

There are various microphone arrays available that even allow you to record directly to an ambisonic audio file. Because you can rotate ambisonic-encoded audio as you see fit, ambisonics is a great choice for ambient audio beds (background sounds). As Unreal Engine plays back ambisonic audio sources, we can dynamically rotate the ambisonic audio bed as the player looks around, giving the impression that the ambient audio is truly coming from fixed directions in the game world.

Importing and Playing an Ambisonic Audio Asset

Unreal Engine only supports first-order ambisonic assets.

A first order ambisonics asset has four channels — the omni component, or W channel, and the vector components, or X, Y, and Z channels.

Unreal Engine supports two channel orders: FuMa (Furse-Malham), and ACN (Ambisonics Channel Number).

FuMa channel ordering sequences the ambisonics audio channel components as W,Y,Z,X.

ACN channel ordering uses W,X,Y,Z.

Since first-order ambisonic audio uses four channels, any imported file that does not have four channels will be treated as a normal, non-ambisonic audio asset.

To import an ambisonic .wav file into the Content Browser, you should end the name of the asset with either:

_fuma.wav If your ambisonics file uses FuMa channel ordering.

_ambix.wav If your ambisonics file uses ACN channel ordering.

This will tell the engine what the channel order of the original ambisonic asset is. After dragging your file into the Content Browser, when you open the Sound Wave asset, you should see that the Is Ambisonics checkbox is already checked in the Sound Wave inspector panel:



If you forget to end the name of your file with _ambix or _fuma before you import the .wav file, you can still check this box yourself. The engine will assume that the original file you imported used ACN channel ordering if you do this.

After your ambisonic file is imported, you can treat it like any other Sound Wave in the engine, with the important exception that rotation matters. When you play back an ambisonic Sound Wave via an audio component in the world, the engine will rotate the ambisonic bed based on the rotation between the current rotation of the audio component that is playing and the current rotation of the player in the game world.

Soundfield Submixes

In addition to playing back ambisonic Sound Waves like you would any other Sound Wave, you can use ambisonics directly in the submix graph. To do this, you will need to create a Soundfield Submix:



Soundfield Submixes can be used and connected to other submixes in the submix graph, but are able to use any soundfield representation currently implemented in the engine or implemented by a currently enabled plugin.

If you open your newly created Soundfield Submix and look at the inspector panel, you will see a dropdown menu for Soundfield Encoding Format that includes Unreal Ambisonics as one option:



After you select Unreal Ambisonics, you can send any audio source to this submix — whether or not it is an ambisonic source — and it will be encoded or mixed down to a single ambisonic stream. If you are sending an ambisonic source that has some rotation on it to an ambisonic stream, don't worry — the engine will rotate the ambisonic source audio based on the source rotation before it is mixed down.

If you have the Google Resonance or Oculus Audio plugins enabled, you may see some other entries in the Soundfield Encoding Format menu. These allow you to send both non-ambisonic and ambisonic sources, as well as other submixes, directly to Resonance or Oculus in the submix graph.

Let's say that you want to take the output of your ambisonic submix and render it to binaural audio with Google Resonance. To do this, create another soundfield submix and drop it onto the submix graph, then select Resonance Binaural Spatialization as its Soundfield Encoding Format:



Now all you need to do is connect the output of your Ambisonics Submix to your Resonance Submix.



You can also send both ambisonic and non-ambisonic audio sources to your Resonance Submix and they will be rendered to a binaural stereo output. You can even send the output of non-soundfield submixes to soundfield submixes, and they will automatically be encoded to whatever the format of that submix is. In the following graph, we take the output of a normal, downmixed submix and mix it in with our Oculus Audio binaural audio stream before sending the output of that to a different, non-soundfield submix:



It is important to remember that once sources are sent to a submix, they are downmixed to the format of that submix.

For example, any spatial information that would have been received from sending an audio source to MyOculusSubmix will be lost if its output is sent solely to the StandardSoundSubmix instead.

Soundfield Encoding Compatibility

Not all soundfield encoding formats are compatible. For example, you cannot connect a submix that uses the Oculus Audio soundfield format to a Google Resonance soundfield submix, or vice versa:



Click image for full size.

However, you can have sources send their output to either of these soundfield submixes in your project as needed.

Conclusion

Both native ambisonic rendering and soundfield submixes are a major step forward for developers to control and extend every aspect of the spatial audio pipeline in Unreal Engine. In the future, more soundfield formats will be added to this system. Meanwhile, if you are curious about writing your own soundfield format, check out ISoundfieldFormat.h in the Audio Extensions module.

Creating a Submix

The Submix Graph Editor

Sending Audio to a Submix

Submix Properties

Submix Effects

Blueprint APIs and Submixes

Recording Submix Audio in a Blueprint

Real Time Analysis in Blueprints

Volume Control in Blueprints

Submix Effect Control in Blueprints

A submix is a DSP (digital signal processing) graph that is always running, even when no audio is being sent.

A fundamental component of the audio renderer in Unreal Engine, submixes have a dual purpose:

To mix audio generated from individual sources into a single output buffer, and

To optimize the application of digital signal processing (DSP) effects to multiple sound sources simultaneously.

Think of your submixes as flowing rivers — when a sound plays, it pours into the submix. When one submix connects to another, it cascades into the next. All of the sounds pouring together mix into one stream of sound and flow down. And like a river, the flow is in one direction only.

Each submix endpoint (hardware output) is fed from a single graph. For example, the master submix — a single, default submix endpoint — defines a single submix graph.

A Sound Cue can send to a submix the same as any other USoundBase.

You can use a Blueprint to modify properties on a submix, changing the way that submix processes audio.

Creating a Submix

A submix can be created directly in the Content Browser, much like other sound-related assets: right-click in the Content Browser asset area, then select Sounds > Mix > Sound Submix. This will create a new Sound Submix asset in the Content Browser:



The Submix Graph Editor

Double-click a submix asset to open the Submix Graph Editor.



Click image for full size.

You can connect submixes into a graph structure and set the output of one submix as the input to another submix.



To create a new submix from within the graph editor, drag an output or input pin into the graph, then name the new submix (names cannot contain spaces.) The new submix will be added to the Content Browser.



A submix can have multiple inputs but only one output.

The Master Submix

The Master Submix parameters are set from Project Settings (Edit > Project Settings > Engine > Audio > Mix):



Click image for full size.

Double-click the submix icon to access the Master Submix properties.



Click image for full size.

The Master Submix is directly connected to an output endpoint (such as hardware speakers). This is the final rendering stage for the Audio Mixer, after which audio is passed on to the platform audio backend, then to the audio device that platform uses.

If a submix output pin is not connected to anything else, it will send the output to the Master Submix.

Master Reverb Submix

Master Reverb Submix settings are in the Sound Class.



Send to Master Reverb Submix: Sends sounds to the Master Reverb.

Default 2DReverb Send Amount: Sets the send level for 2D sounds when sent to the Master Reverb.

Master EQ Submix

Settings for the Master EQ Submix are in Sound Class, under Legacy, Advanced.



The Output to Master EQ Submix setting must be enabled for the EQ Settings on Sound Class Mixes to work.

Sending Audio to a Submix

There are several ways to send sound sources to a submix:

Set up the send manually in a sound source asset.

Use Attenuation settings.

Set dynamically in a Blueprint.

Set it through Audio Volumes.

Manually Set Up a Submix Send

To play a sound source on a submix, or to send its generated audio to a submix, assign the new submix asset to the Submix property on the sound source. The Submix property on sound assets is considered the base submix of the sound, and 100% of the audio is sent to that submix.



Click image for full size.

Properties:

Submix Sends: The Submix Sends array on a sound asset is an array of further submixes to which sound sources can send a portion of their audio. Sends can be done either manually or via distance; for example, the farther away a sound is, the less audio it might send to a submix.

Send Level Control Method: How the source should send its audio to the indicated submix:

Manual: The sound sends its audio directly using the Send Level value.

Linear: The sound sends its audio to the submix using a linear mapping between the Min and Max Send Level, and the Min and Max Send Distance.

Custom Curve: Uses the Custom Send Level Curve to send its audio to the submix, instead of using linear mapping.

Send Stage: Determines whether the source send should be done before or after distance attenuation is applied.

Sound Submix: Which submix the sound source is sending its audio to using this submix send entry.

Send Level: The send level to use if the Send Level Control Method is set to Manual.

Disable Manual Send Clamp: Enables or disables the 0–1 clamp when using the manual Send Level Control Method.

Min Send Level: The minimum send level to use when using the non-manual Send Level Control Method.

Max Send Level: The maximum send level to use when applying a Linear control method.

Min Send Distance: The minimum distance to use when applying a Linear control method.

Max Send Distance: The maximum distance to use when applying a Linear control method.

Custom Send Level Curve: The curve to use for mapping the minimum and maximum Send Level and Distance.

Send to Submixes Using Sound Attenuation

Submix sends can also be set using Attenuation settings. This is a convenient way to set up submix sends on large numbers of assets from one place. Since submix sends can send their audio based on distance to the listener, it makes sense to use this where distance attenuation is also defined.



Click image for full size.

For more on this method, see Sound Attenuation.

Send Dynamically to Submixes in Blueprint

This Blueprint function provides a way for audio components to dynamically route their audio to arbitrary submixes using whatever method you choose.



To set a Submix Send you will need:

Target: The audio component to use for sending audio to the submix.

Submix: The submix where audio will be sent.

Send Level: The amount of audio to send, as a % of total volume.

Also see Blueprint APIs and Submixes later in this document.

Send to Submixes using Audio Volume

Audio Volume supports sending audio to submixes in a similar way to how sends are set up directly on sound sources. The primary difference is that the submix send is based on its location relative to the audio volume geometry.



Click image for full size.

The properties in the Submix Send Array are identical to the properties that are directly set on the sound sources themselves.



Sound sources will send their audio to a given Submix Send Array based on whether the Listener Location State shows the listener inside or outside the Volume.

Audio Volume also supports Submix Override, depending on the Listener Location State. The submix is overridden by a specified effect chain, depending on whether the listener is inside or outside of the Volume.

Submix Properties

While in the Graph Editor, the Property Details panel displays for the selected submix in the submix graph.



Click image for full size.

Properties:

Mute when Backgrounded: Allows a submix to automatically mute itself by applying a volume scaler of 0.0 on its output when the application is backgrounded. This feature allows a game to continue playing audio in the background by default for some audio but not all.

Submix Effect Chain: This is an array of submix effects through which the mixed submix audio will be fed. These effects are implemented with the Synthesis and DSP Effects plugin. Other Unreal Engine plugins can also extend the list of submix effects available.

Ambisonics Plugin Settings: This property allows plugins to optionally allow a submix to encode audio sources sent to it as an ambisonic soundfield. These settings define the soundfield encoding properties.

The only settings type this property will accept is for Oculus Ambisonics Settings (when the Oculus Plugin is enabled). For more information on soundfields, see Native Soundfield Ambisonics Rendering.

Parent Submix: The parent to the selected submix. The parent submix receives the rendered output as input.

Child Submixes: An array of child submixes that feed their audio as input into the selected submix.

Envelope Follower: A DSP algorithm that outputs the amplitude of an audio signal that has been smoothed over time. Attack Time values define how quickly the algorithm reacts to increasing amplitude (attack) and decreasing amplitudes (release).

Deriving the amplitude of an audio signal using an envelope follower is significantly more effective than using the raw audio data because audio signals can be significantly faster (for example, 48,000 samples per second) than game frames (for example, 60 frames per second).

Submixes also have a Blueprint API that allows a Blueprint to receive an amplitude envelope for audio rendered in a submix. These properties define how the envelope follower behaves.

Submix Level: Controls the overall volume levels for the submix. The values in this category can be optionally set to display linear volume gain (such as 0.0 to 1.0), or decibels (-120 dB to 0 dB). The decibel is a common volume measurement that accounts for the fact that volume is perceived logarithmically.

Output Volume: Controls the overall output volume for the whole submix in both dry and wet channels. It is not recommended that you mix game volume using this property, but it can be useful for tweaking the volume in a submix.

Wet Level: The output volume of the audio that was fed through the submix effect chain. By default, this is set to 1.0 as it is assumed that most uses of a submix are intended to be fully wet, with all audio sent through the effects.

Dry Level: This is the output volume of the audio that was not fed through the submix effect chain. By default, this is set to 0.0 as it's assumed that most uses of a submix are intended to be fully wet (all audio sent through the effects).

Audio Link Settings: An optional audio link settings object.

Auto Disable: This will automatically enable or disable a submix whether it is silent or audible. This is useful for CPU optimization.

Auto Disable Time: This is the minimum amount of time to wait before disabling a submix.

Submix Effects

A number of submix effects are available using the Synthesis and DSP Effects plugin. This plugin is made by Epic, and new synthesis, source effects and submix effects are often added to this plugin. Third-party plugin makers can also easily add to the list of available submix effects.

The general requirement for non-soundfield submix effects is that they are able to handle multiple audio channels (up to 8 channels).

Making Submix Effect Presets

A Submix Effect Preset is an asset that exists in the Content Browser and is hooked up to a Submix Effect Chain. To create a Submix Effect Preset, right-click in the Content Browser, then select Sounds > Effects > Submix Effect Preset.



This will give you a class picker where you can select the effect you want to create a preset asset for.



Plugins will automatically extend the options available in the Pick Submix Effect Class list.

Blueprint APIs and Submixes

Submixes can be very useful in Blueprints. For example, you can reference a submix in a Blueprint by creating a Sound Submix Variable reference.



Click image for full size.

Recording Submix Audio in a Blueprint

Submixes support recording the audio output of a submix to either a PCM (pulse code modulation) .wav file that is output to disk, or to a Sound Wave asset. Only one recording per submix can be active at a time.

The default path for saved .wav files is Saved\BouncedWavFiles.

Sound Waves are saved to the root directory of the Content Browser.

You can change either of these paths when setting up Finish Recording Output (see below).



Start Recording Output properties:

Expected Duration: An optional advanced parameter to preallocate an internal audio buffer (in seconds) for the anticipated duration.

Submix to Record: The submix you want to record.

Pause Recording Output pauses the recording.



Resume Recording Output resumes the recording.



Finish Recording Output ends the recording and saves it.



Properties:

Export Type: Whether to export (or save) the submix recording as a .wav file or a Sound Wave (UAsset).

Name: The name of the asset.

Path: The path of the exported asset. If nothing is entered it will save to the default path for the export type.

Submix to Record: The submix that was recorded.

Existing Sound Wave to Overwrite: If saving as a Sound Wave, you have the option of overwriting a previous asset.

Real Time Analysis in Blueprints

Submixes support the retrieval of real-time analysis in a Blueprint either through envelope following or through spectral analysis, such as a fast Fourier transform (FFT).

Envelope Following Analysis

Add Envelope Follower Delegate is called when new envelope data is available on the submix.



Click image for full size.

It is called with the envelope value of the submix per channel (left, right, center, left-surround, right-surround, and so on).

Start Envelope Following starts the submix envelope follower on the given submix. If a delegate is hooked up, it will begin to fire.



Stop Envelope Following stops the follower on the given submix.



Spectral Analysis

Add Spectral Analysis Delegate provides spectral analysis.



Properties:

In Band Settings: A struct that defines the settings for the spectral analyzer.

In Num Bands: How many spectral bands to analyze.

In Minimum Frequency: The minimum frequency range (in Hz) to consider in the spectrum analyzer.

In Maximum Frequency: The maximum frequency range.

The delegate is called with the spectral data for each spectral band defined in the setting.

Start Spectral Analysis starts the spectrum analyzer.



Stop Spectral Analysis stops the spectrum analyzer.



Volume Control in Blueprints

Volume controls can also be set for submixes from a Blueprint.

Set Submix Output Volume directly sets the output volume of the submix.



Submix Effect Control in Blueprints

Add Submix Effect dynamically adds a submix effect preset to the end of a submix effect chain.



Remove Submix Effect Preset removes the submix effect preset in the submix effect chain of the submix.



Remove Submix Effect Preset At Index is similar to Remove Submix Effect Preset, but removes the submix effect preset at the given index in the submix effect chain if an effect exists at that index.



Replace Submix Effect replaces the submix effect preset at the given index with a new effect preset.



Clear Submix Effects clears the submix effects chain on the given submix.



Set Submix Effect Chain Override provides a way to override the entire submix effect chain at once.



Properties:

Sound Submix: The submix to override with the submix effect preset chain.

Submix Effect Preset Chain: An array of submix effect presets.

Fade Time Sec: The cross-fade time of the submix effect chain. This will fade from the current effect chain to the new effect chain override.

Setting a Submix Effect Chain Override can also be done via Audio Volumes.



Click image for full size.

Clear Submix Effect Chain Override clears any submix effect chain overrides that are set.



Properties:

Sound Submix: The submix to be cleared.

Fade Time Sec: The cross-fade time from the current submix effect chain override to the default submix effect chain.

Ambient Zone Settings

Creating An Ambient Zone

Ambient Zones are an inexpensive interior/exterior ambient audio solution. Benefits of Ambient Zones include:

Makes the transition from interior to exterior areas sound good.

Reduces labor for audio designers, as less Sound Actors will need to be placed and iterated on inside/outside spaces.

Reduces game systems overhead, due to a reduction of required Sound Actors to define interiors and exteriors.

Ambient Zone Settings

The settings for an Ambient Zone define how Sound Actors located inside and outside of its associated Audio Volume are altered by the player's location.

A simple example of how this works is shown below:



In the image above, the gold box around the section marked as "Inside" is an Ambient Zone volume; the two speaker icons are Sound Actors. As you can see, one Sound Actor is located inside the Ambient Zone and the other is located outside the Ambient Zone.

Here is the behavior of the Ambient Zone volume when playing in the level:

When the player is outside of the Ambient Zone, the Sound Actor located inside the Ambient Zone will have a volume multiplier and LPF effect applied to it.

When the player enters the Ambient Zone, the Sound Actor located inside the Ambient Zone will return to a 1.0 multiplier for volume and LPF over a specified fade time. At the same time, the Sound Actor located outside of the Ambient Zone will have a volume and LPF multiplier applied to it over a specified fade time.

When the player exits the Ambient Zone, the Sound Actor outside the Ambient Zone will return to its previous default volume and LPF values using the previous fade time, and the Sound Actor located inside the Ambient Zone will have its volume multiplier and LPF values changed via the Ambient Zone Settings for the Ambient Zone.

You can access the Ambient Zone Settings from the Details panel of an Audio Volume by expanding it as seen below.



Property

Description

Exterior Volume

The final volume of exterior sounds when the player is inside this Ambient Zone.

Exterior Time

Time to fade to the new exterior volume in seconds.

Exterior LPF

Low pass filter multiplier applied to exterior sounds when inside (0.1 to apply the maximum LPF).

Exterior LPFTime

Time to fade to the new low pass filter level in seconds.

Interior Volume

The final volume of interior sounds when outside this Ambient Zone.

Interior Time

Time to fade to the new interior volume in seconds.

Interior LPF

Low pass filter multiplier applied to interior sounds when outside (0.1 to apply the maximum LPF).

Interior LPFTime

Time to fade to the new low pass filter level in seconds.

Creating An Ambient Zone

Create an Audio Volume and place two Ambient Sound Actors in the level: one inside the volume and the other outside the volume.

Assign a large radius looping sound to both Ambient Sound Actors.

In the Details panel of the Audio Volume, expand the Audio Volume properties.

Expand the Ambient Zone Settings to reveal its properties:



In the Ambient Zone properties, set the Exterior Volume to .5

This is the final volume of Ambient Sounds that are outside the Ambient Zone when the player is inside the Ambient Zone.

Set the Exterior LPF to .5

This is the final low pass filter on Ambient Sounds that are outside the Ambient Zone when the player is inside the Ambient Zone.

Set the Interior Volume to .2

This is the final volume of Ambient Sounds that are inside the Ambient Zone when the player is outside the Ambient Zone.

Set the Interior LPF to .2

This is the final low pass filter on Ambient Sounds that are inside the Ambient Zone when the player is outside the Ambient Zone.

Create a new Sound Class and in its properties, check Apply Ambient Volumes:



Assign the Sound Class to both the interior and exterior sounds from the Details panel of each sound:



Rebuild geometry, and enter the Audio Volume with the Ambient Zone you just set up.

The Ambient Sound that is outside the Ambient Zone will have its volume and low pass filter multiplied by .5

Exit the Audio Volume.

Now the Ambient Sound that was outside the Audio Volume is restored to its previous volume and LPF settings.

The Ambient Sound inside the Audio Volume now has a volume multiplier and LPF multiplier of .2 applied, making it very quiet.

When placing a Sound Actor inside of an Ambient Zone volume, you must rebuild the level's geometry, as this is when the check is performed on the Sound Actor to determine its location. After geometry has been rebuilt, all Ambient Zone parameters can be freely changed in the editor.

Transform

Audio Volume

Reverb

Brush Settings

Brush Shapes

Box (CubeBuilder)

Cone (ConeBuilder)

Curved Stair (CurvedStairBuilder)

Cylinder (CylinderBuilder)

Linear Stair (LinearStairBuilder)

Sphere (TetrahedronBuilder)

With the Audio Volume Actor, you can define areas within a Blueprint map that can be used to process sounds, then use these settings to apply reverb effects, set volumes, define the zones affected, emulate occlusion on a sound, and define the shape of the sound volume.

Transform

The Transform settings change the location, rotation and scale. Use these settings to ensure that the audio volume encompasses the area in which you want sound to be processed.



Location: Determines the location of the origin of the audio volume.

Rotation: Determines the rotation of the audio volume.

Scale: Determines the scale (size) of the audio volume.

Audio Volume

The Audio Volume settings define which volume's settings are used when there are overlapping volumes.



Priority: Determines the priority of the audio volume, which is used to ensure that in the case of overlapping or nested volumes, the correct volume is applied. The higher the number used, the higher the priority. When two overlapping volumes have the same priority, no priority is used.

Enabled: Toggles audio volume on or off.

In the image below, a small area is nested inside a larger one. Each space has its own audio volume (note the yellow volume outlines around the two spaces) for defining the different reverbs and ambient zone settings.



If the listener is within the smaller space, they are inside both of the audio volumes, so it's necessary to define how the audio engine chooses which audio volume to use. When audio volumes overlap, the one with the higher priority is used by the audio engine.

In this case, it would make sense to set the larger audio volume to 1, and the smaller to 2. This way, when inside of the smaller space, the appropriate reverb and ambient zone settings are used.

Reverb

You can use the Reverb settings to turn audio volume on or off, select a reverb preset for use when activated, and define the volume of the reverb signal and the fade time between reverb settings.



Apply Reverb: Enables or disables the reverb effect assigned below.

Reverb Effect: Determines the Reverb Effect asset that will be used. There are a number of reverb presets included within the engine content, or you can create your own reverb effect assets within the Content Browser.

Reverb Plugin Effect: Determines the Reverb Plugin Effect that will be used. If you're using a third-party audio plugin (such as Google Resonance), select the reverb effect that the plugin will use from the dropdown menu options.

Volume: Set the volume level for the reverb effect. The default setting is 0.5.

Fade Time: The time (in seconds) it takes to interpolate from the current reverb settings to the new ones as you enter and leave audio volumes. Determines the transition times between areas within a Level — there is a balance to be struck between how responsive the system is and how much movement the settings have to make to reach the new values. For example, if you were moving from a space with very little reverb to one with very long reverb times, then you might want to use longer transition times to avoid abrupt changes when moving between spaces. A move between spaces with similar reverb settings could transition more quickly.

Brush Settings

Brush settings define the overall shape of the audio volume, and set the initial size of the volume (before the scaling values from above are applied).



Select the Brush Shape for the audio volume that would provide best coverage for the area. The remaining settings below Brush Shape change based on the shape chosen.

You can use Geometry Editing mode to alter any of the shapes provided to create bespoke (customized) shapes that better fit specific areas within your Level. Some brush shapes can be set to hollow, and while this can work (for instance, when the audio volume only has an effect between the interior and exterior walls), it is not recommended for general audio use. The Brush Editor was primarily designed to build geometry for level designers, so some of the available shapes may be impractical for audio use.

Brush Shapes

Click the Brush Shape dropdown menu to display and select from a list of built-in shapes:



Box (CubeBuilder)

The default shape, this shows up as CubeBuilder in the dropdown menu. This shape produces a cube-shaped audio volume.



For the Box Brush shape, the following options are available:

X, Y, Z: Determines the initial size of the box-shaped audio volume when it is first created. These values are then scaled according to the values of the Scale property above.

Wall Thickness: Only active when the Hollow option is enabled, and determines the thickness of the walls if the audio volume is set to be hollow.

Hollow: Determines whether the audio volume is hollow. This is an inherited feature from the parent volume class and is not recommended for general audio use.

Tessellated: Determines whether extra internal faces are generated for each cube face.

Display Shaded Volume: Displays the brush with a shaded volume when checked.

Shaded Volume Opacity Value: A value between 0–1 to set opacity for the shaded volume.

Cone (ConeBuilder)

Select ConeBuilder in the dropdown menu to produce a cone-shaped audio volume.



The following options are available for this shape:

Z: Determines the initial height of the cone, from base to tip. It is then scaled according to the Z value within the Scale property under Transform settings.

Cap Z: Only active when the Hollow option is enabled. It determines the height of the inner cone.

Outer Radius: The initial radius of the cone-shaped audio volume, which is then scaled according to the X and Y values of the Scale property under Transform settings. This allows you to produce non-symmetrical cones.

Inner Radius: Only active when the Hollow option is enabled. It determines the radius of the inner cone.

Sides: Determines the number of sides of the cone, which in turn affects how closely the base approximates a circle.

Hollow: Determines whether the audio volume is hollow. This is an inherited feature from the parent volume class and is not recommended for general audio use.

Align to Side: Enables or disables aligning the brush to a face.

Display Shaded Volume: Displays the brush with a shaded volume when checked.

Shaded Volume Opacity Value: A value between 0–1 to set opacity for the shaded volume.

Curved Stair (CurvedStairBuilder)

Select CurvedStairBuilder in the dropdown menu to produce a curved-stair-shaped audio volume. This shape is inherited from the parent volume Class. While it can be used for audio, it may not be practical.



The following options are available for this shape:

Inner Radius: Determines the initial inner radius of the curved-stair audio volume. This value is scaled according to the X and Y values of the Scale property above.

Step Height: Sets the initial height of the steps within the curved-stair audio volume. This value is scaled according to the Z value of the Scale property above.

Step Width: Determines the width of the steps within the curved stair audio volume.

Angle of Curve: The angle of the total curve of the curved stair audio volume.

Num Steps: The number of steps within the curved stair audio volume.

Add to First Step: The amount the volume should drop below the level of the first step.

Counter Clockwise: Determines whether the stair curves clockwise or counter-clockwise.

Display Shaded Volume: Displays the brush with a shaded volume when checked.

Shaded Volume Opacity Value: A value between 0–1 to set opacity for the shaded volume.

Cylinder (CylinderBuilder)

Select CylinderBuilder in the dropdown menu to produce a cylinder-shaped audio volume.



The following options are available for this shape:

Z: Determines the initial height of the cylinder. It is then scaled according to the Z value within the Scale property under Transform settings.

Outer Radius: The initial radius of the cylinder-shaped audio volume, which is then scaled according to the X and Y values of the Scale property under Transform settings. This allows you to produce non-symmetrical cylinders.

Inner Radius: Only active when the Hollow option is enabled. It determines the radius of the inner cylinder.

Sides: Determines the number of sides the cone has, which in turn affects how closely the base approximates a circle.

Hollow: Determines whether the audio volume is hollow. This is an inherited feature from the parent volume class and is not recommended for general use.

Align to Side: Enables or disables aligning the brush to a face.

Display Shaded Volume: Displays the brush with a shaded volume when checked.

Shaded Volume Opacity Value: A value between 0–1 to set opacity for the shaded volume.

Linear Stair (LinearStairBuilder)

Select LinearStairBuilder in the dropdown menu to produce a linear-stair-shaped audio volume.

This shape is inherited from the parent volume Class. While it can be used for audio, it may not be practical.



The following options are available for this shape:

Step Length: Determines the initial length (depth) of the steps within the linear-stair audio volume. This value is scaled according to the X value of the Scale property above.

Step Height: Determines the initial height of the steps within the linear-stair audio volume. This value is scaled according to the Z value of the Scale property above.

Step Width: The width of the steps within the curved stair audio volume. This value is scaled according to the Y value of the Scale property above.

Num Steps: The number of steps within the curved stair audio volume.

Add to First Step: The amount the volume should drop below the level of the first step.

Display Shaded Volume: Displays the brush with a shaded volume when checked.

Shaded Volume Opacity Value: A value between 0–1 to set opacity for the shaded volume.

Sphere (TetrahedronBuilder)

Select TetrahedronBuilder in the dropdown menu to produce a spherical audio volume.



The following options are available for this shape:

Radius: Determines the initial radius of the sphere. It is then scaled according to the X, Y, and Z values within the Scale property under Transform settings. This allows you to produce non-symmetrical spheres.

Tessellation: Sets the number of iterations the audio volume will use to calculate the sphere shape, which influences how closely the base approximates a sphere.

Display Shaded Volume: Displays the brush with a shaded volume when checked.

Shaded Volume Opacity Value: A value between 0–1 to set opacity for the shaded volume.

Ambient Sound Actor

Sound Properties

Attenuation Properties

Modulation Properties

Adding Audio Components To Blueprints

Audio Volumes

Unreal Engine streamlines the process by which you can produce or modify ambient sounds through the use of the Ambient Sound Actor. When a Sound Wave or Sound Cue asset is placed in a level, an Ambient Sound Actor with that sound asset is created. The Ambient Sound Actor has several properties which are covered on this page that will allow you to modify how players receive the sound.

For more information on importing files as Sound Waves or modifying files through Sound Cues, refer to their respective pages for additional documentation.

Ambient Sound Actor



The Ambient Sound Actor can be used for many purposes such as ambient looping sounds as well as non-looping sounds. Generally, the Ambient Sound Actor conforms to the real world where the closer you are to a sound, the louder it will appear. By comparison, a sound that is normally loud, may appear soft if it is further away.

If the Ambient Sound Actor is set to Auto Activate, it will immediately begin to play once it is created (at the beginning of play or on spawn), even if the player is not in a position to hear it.

The sound asset the Ambient Sound Actor points to will only play once per trigger unless specified as Looping in the Sound Wave or defined as part of a Sound Cue asset.

You can add an Ambient Sound Actor to your level in several ways:

Select the Ambient Sound Actor from the Place Actors panel in the All Classes tab and drag it into your level as seen below.



Right-click in your level and select Place Actor from the context menu.



Open the Actor menu in the Menu bar and select Place Actor.



Drag a Sound Wave or Sound Cue from the Content Browser into your level.



Sound Properties

An Ambient Sound Actor has no function without an associated sound asset. You can assign a sound asset from the Details panel by selecting an asset from the Sound setting's drop-down menu or by highlighting a sound asset in the Content Browser and clicking the button.



Click image for full size.

Once a Sound Cue asset has been assigned as the associated sound, the Edit option will become available so that you can open the Sound Cue asset up for editing inside the Sound Cue Editor. Optionally, instead of assigning a sound asset, you can select the New option which will create a new Sound Cue asset and will open it in the Sound Cue Editor for editing.

The Play and Stop options allow you to preview the assigned sound inside the editor and will play and stop playing the sound respectively.



Click image for full size.

Additional options inside the Sound section of the Details panel are defined below.

Property

Description

Sound

Points to a Sound Wave or Sound Cue asset.

Volume Multiplier

Modifier applied to set the overall Volume of the sound.

Pitch Multiplier

Modifier applied to set the overall Pitch of the sound.

Is UI Sound

Whether or not the sound asset plays when the game is paused.

Low Pass Filter Frequency

Enable to set the frequency (in Hz) of the low pass Filter. A frequency of 0.0 is the device sample rate and will bypass the filter.

Priority

Enable to override the priority of selected sound with the value provided.

Play Multiple Instances

If true, the Audio Component plays multiple sound instances at once.

Source Effect Chain

Determines a chain of source effects to apply to the sounds playing on the Audio Component.

Attenuation Properties

Attenuation is the ability of a sound to decrease in volume as the player moves away from it. It works using two radii: MinRadius and MaxRadius. As you move from the sound's origin through the MinRadius, the volume of the sound is at 100%. As you move within the space between the MinRadius and the MaxRadius, the volume level is adjusted based on the Distance Algorithm. Outside of the MaxRadius, the volume of the sound is at 0%.

It is advisable to use Sound Attenuation objects whenever possible, if for no other reason than to give broad control over the settings for many Actors.

For additional information on Attenuation, please refer to the Attenuation Overview page.



The options under the Attenuation section that can be modified inside the Details panel are defined below:

Property

Description

Allow Spatialization

Enables or disables spatialization of the audio component.

Override Attenuation

Uses the asset's Attenuation settings or the Attenuation Override's settings.

Attenuation Settings

Points to and uses the settings assigned inside a SoundAttenuation asset.

When Override Attenuation is checked, the ability to modify settings on the following sections becomes available:

Section

Description

Attenuation (Volume)

Properties in this section define how the sound's volume will attenuate as the listener moves away from it.

Attenuation (Spatialization)

Properties in this section define how the sound will spatialize in the game world.

Attenuation (Occlusion)

Properties in this section control real-time occlusion tracing.

Attenuation (Submix)

Properties in this section control sending sound sources to a submix.

Attenuation (Reverb)

Properties in this section define the relationship between the sound's distance from the listener and the amount of reverb that is applied to the sound.

Attenuation (Focus)

Properties in this section control some additional processing that you can use to the ‘focus behavior' of sounds.

Attenuation (Priority)

Properties in this section control attenuation of sound priority based on distance.

Attenuation (Air Absorption)

Properties in this section define the behavior of the algorithm that attempts to model the effect air absorption has on the sound.

Modulation Properties



The Modulation settings define what settings to use for Volume, Pitch, Highpass and Lowpass modulation. There are three options available:

Disable: Disables modulation routing.

Inherit: The Audio Component inherits modulation settings from its parent Sound.

Override: Ignores inherited settings and allows you to set the base value, enable or disable modulation and set the modulation source for each parameter.

For additional information on Modulation, please refer to the Overview of Audio Modulation in Unreal Engine page.

Adding Audio Components To Blueprints

Inside a Blueprint, in the Component panel, select the Add Component button and select the Audio component.



The Audio component can be referenced through Blueprints and many of its settings can be altered by using different types of functions.



The Audio component does have a unique event which can be used. This OnAudioFinished event allows you to fire off events when the audio is finished playing or is stopped prematurely with a Stop function.

Audio Volumes

For an added level of control, you can include Audio Volumes in conjunction with Ambient Sound Actors. For more information on how to use an Audio Volume, refer to the Audio Volumes page.

Making changes to an Audio Volume will not work in real time inside the editor. You will need to rebuild the geometry of the level that contains the edited volume in order for your changes to take effect.

Conceptual Background

The Convolution Operation

Convolution in Audio

Computational Considerations

How to Use the Convolution Reverb

Convolution reverb is an exciting technology that sound designers can use to capture the impulse responses (IRs) of any physical location (such as caves, churches, offices, or hallways) and process audio in real time as though it were being played at that location. In effect, the IRs are capturing the reverberations of real locations, thereby allowing a new level of realism and immersion in environmental audio processing.

In addition to capturing real-life reverberations, IRs can be derived from any other sound source: algorithmic reverb output, foley, VO (such as huffs or breaths), contact mics, and so on. IRs can be edited and processed like any other sound — they can be filtered, attenuated, reversed, chopped-up, edited, and more. In this way, the Convolution Reverb feature introduces a whole new dimension of experimentation.

Convolution reverb provides a data-driven alternative to more traditional algorithmic reverb techniques that simulate reverberation using a combination of delay buffers, filters, and various other DSP topologies.

Conceptual Background

The Convolution Operation

Convolution is a mathematical operation like any other mathematical operation — addition, subtraction, integration, dot products, or cross products, to name a few. In the same way that dot products and cross products can be thought of as different ways to multiply vectors (or signals), convolution is a third way to think of vector transformation. As with cross products, convolving two signals results in a third signal.

Without getting overly involved in complex mathematics, the simplest way to conceptualize convolution is to consider every sample of the output signal, y(t), as the sum of weights, g(t), of the time-shifted input signal, x(t). In this way, you can think of convolution as a kind of blurring operator.

Convolution in Audio

Convolution has a wide variety of applications in a large number of fields, including statistics, machine learning, and graphics rendering. In audio, convolution is a way to process audio signals through IRs, which represent real-world systems that would otherwise be impossible to model due to their complexity.

If the input audio signal is f(t) and our weight, g(t), is the IR that represents the complex system to be modeled, then the output, x(t), is what the audio signal would be if it were fed through that system.

Computational Considerations

Convolution is fundamentally an expensive mathematical operation. Every element in the input signal, f(t), is multiplied by every element in the convolving signal, g(t), and added together to produce every element in the output signal, x(t). For large IRs, which represent large reverberant spaces, this gets very expensive. Performing the convolution operation directly is usually too costly for a real-time scenario.

Luckily, there is a symmetry that can be taken advantage of that speeds up convolution significantly: convolving two signals in the time domain is identical to multiplying signals in the frequency domain. The frequency domain of a signal can be produced by using the Fast Fourier Transform (FFT). The FFT, as the name would suggest, is fast. By doing this step for the input signal and the IR, convolution reverb can be computed on the CPU in real time. Take care, however, as it is still usually more expensive than traditional algorithmic reverbs.

With new CPU capabilities and hardware acceleration of convolution operations, convolution reverb is becoming a more viable option in game audio. In this way, convolution reverb has been traditionally a next-gen audio technology.

How to Use the Convolution Reverb

Enable the Synthesis and DSP Effects plugin (Edit > Plugins > Audio > Synthesis and DSP Effects). This plugin contains a variety of optional synthesis and DSP capabilities.



With the plugin enabled, right-click any imported sound wave in the Content Browser and select Create Impulse Response.



Click image for full size.

This creates an impulse response from the selected sound wave. In this way, any sound wave could become the IR for the convolution reverb algorithm (you can convolve with any sound). This will create a new asset with a name appended by _IR.



Import an IR with the same process you would use to import any sound wave.

This asset contains some data that will be used by the convolution reverb effect, as well as a normalization value that can be set for each impulse response. To set the volume normalization value for an individual Audio Impulse Response asset, open the Details panel.



The Normalization Volume Db is a decibel attenuation that is applied to any convolution effect that is actively using this impulse response. This provides an easy way to achieve equal loudness between various impulse responses.

The True Stereo is a checkbox that defines whether impulse response channels are interpreted as true stereo or independent channel impulses.

To use the convolution reverb effect, create a Submix Effect Preset by right-clicking in the Content Browser and selecting Sounds > Effects > Submix Effect Preset.



Click image for full size.

When you create a new asset, the Pick Submix Class dialog will appear. Select the SubmixEffectConvolutionReverbPreset.

[

To open the Details panel for a Convolution Reverb Effect, double-click it in the Content Browser and set up the impulse response asset as the one to use.



Click image for full size.

Other parameters include:

Bypass: If true, the input audio is directly routed to the output audio with applying any effect.

Mix Input Channel Format to Impulse Response Format: If true, the submix input audio is downmixed to match audio channel format of the impulse response asset. If false, the input audio channels are matched to the impulse response audio channels.

Mix Reverb Output to Output Channel Format: If true, the reverberated audio is upmixed or downmixed to match the submix output audio format. If false, the reverberated audio channels are matched to the submix output audio channels.

Surround Rear Channel Bleed Db: How many decibels of the output of the convolution effect to send to rear channels in a surround sound environment. Values of -60.0 or less will be considered silent.

Invert Rear Channel Bleed Phase: Whether or not to invert the phase of the audio sent to the rear channels in surround sound environments.

Surround Rear Channel Flip: Whether or not to flip the left and right channels of the effect before sending to the rear channels.

The advanced parameters include:

Block Size: Sets the internal processing block size, which may have an effect on runtime performance.

Enable Hardware Acceleration: Enables hardware acceleration if it exists on the target platform.

To use this on a submix effect, add it to any submix as a submix effect in a submix effect chain.



Click image for full size.

You can automatically send reverb audio to the submix if you set this submix as the master reverb submix to be used. Alternatively, you can manually send audio to this submix as a submix-send effect.

Integrating Media

Communicating with Media Components

Managing Color

Capturing Media

With Unreal Engine, you can integrate your pre-recorded media into your project seamlessly and share your rendered frames live or recorded. Use Unreal Engine's real-time rendering for shooting real-time visual effects, broadcasting on air or to tape, and rendering on complex arrangements of physical displays for live performances. With end-to-end color management and the ability to synchronize multiple media sources, Unreal can fit into the technical pipeline for any virtual production or live event.

The following sections contain information on the tools and workflows to make the most of media and rendered frames for your projects and audience.

Integrating Media



A short overview of using Bink Video to show movies.



Using the Media Plate Actor in Unreal Engine



Working with Media Playback functionality in Unreal Engine.



Contains information about getting professional quality video into and out of the Unreal Engine.



The Camera Calibration plugin provides users with simplified tools and workflows to calibrate a camera and lens in the editor.



With in-camera VFX you can shoot real-time visual effects during a live action film shoot with an immersive LED volume.



nDisplay renders your Unreal Engine scene on multiple synchronized display devices.



In Composure, a graphics utility plugin available with Unreal Engine, we've added a new set of tools to make compositing a lot easier.



Share GPU data and bypass the CPU across Unreal Engine instances, nDisplay devices, and other graphics applications.



Composite footage of users into a virtual space with Mixed Reality Capture

Communicating with Media Components



The DMX Plugin enables Unreal Engine use for live events and permanent digital installations.



Control multiple remote machines from one application with Switchboard.



Stage Monitor reports events from multiple instances of Unreal Engine



Monitor, calibrate, and view incoming timed data from multiple sources through Live Link or SDI.

Managing Color



Ensure color consistency across projects with OpenColorIO.



Details on applying color grading using volumes on your level's environment with Color Correct Regions.

Capturing Media



Guide to taking in-game screenshots of environments and gameplay.



A look at how to use the Stereo Panoramic plugin to capture VR images.

Installation

Bink for Unreal Engine Movie Types

Fullscreen Startup Movie Setup

Other Bink for Unreal Notes

Multithreaded Decoding

Seeking

Video Depth (Sorting During Drawing)

Subtitles

Stereo Video

Bink Plugin API

The Bink Media plugin is built into Unreal Engine 5. All Unreal platforms (including NDA platforms) are supported.

Installation

Select Edit > Plugins in the Editor, search for Bink, and enable the plugin. Restart Unreal Engine as required.





Click image to expand.



Copy your Bink video files into the Contents/Movies directory in your Unreal Engine Project directory.

You create Bink files using Bink 2 Encoder for Unreal found in the Engine/Binaries/ThirdParty/Bink directory (Bink2ForUnreal.exe). Double-click the executable, then select your video file to convert and click Bink it! then Bink. For most use cases, the automatic settings work fine.



Double-click on the .uproject file for your project, and a warning dialog appears and asks if you want to rebuild the project due to missing plugins. Confirm executing the rebuild, and Unreal Engine restarts with the project loaded up.

You can now play the Bink files in your Content/Movies directory.

Bink for Unreal Engine Movie Types

Unreal Engine has two distinct types of movies: fullscreen startup movies, and in-game non-startup movies. You use each type a little differently, as described below.

Fullscreen Startup Movie Setup

First, you need to disable all other movie player plugins. Otherwise, any enabled MPEG-4 player tries to play the Bink movie files and silently fails.

To do this, go into Edit > Plugins:





Click image to expand.



Disable all Movie Player plugins other than the Bink Media plugin.

Second, you need to configure some movies to play on startup.

Go into Edit > Project Settings:





Click image to expand.



Click the + button next to Startup Movies, and then expand the list to show the movies. You can play multiple movies in sequence. Then, click the … button to select a file to play.

Go into Edit > Project Settings > Bink Movies to see Bink-specific options.





Click image to expand.



There are some Bink-specific options:

Bink Buffer Mode: This controls whether or not you want to stream a portion of the movie from disk, preload the whole movie before playing, or don't start streaming until the whole movie is resident.

Bink Sound Track: This determines how you want to play the sound. There are several options:

SndNone: don't play any sound in this Bink.

Snd Simple: Default. This option tries to figure out what you want based on the filename of the Bink file.

If the filename ends in _51, it uses the Snd 51 option.

If the filename ends in _51L, it uses the Snd 51 Language Override option.

If the filename ends in _71, it uses the Snd 71 option.

If the filename ends in _71L, it uses the Snd 71 Language Override option.

Otherwise, it plays the Bink track specified by the Sound Track Start value (by default, track 0).

Snd Language Override: This option plays two tracks.

The audio in track 0, usually the background music / effects.

The track specified by the Sound Track Start value, which is usually the language track.

Snd 51: This option plays the six mono tracks starting at the track specified by the Sound Track Offset value (by default, 0) into the systems. So, if you have fully localized 5.1 tracks for four languages, you would mix in twenty-four Bink tracks, and use the Sound Track Offset setting to specify the right range of audio tracks to play.

Snd 51 Language Override: This option plays the six mono background / effect tracks starting at offset 0, and then the one mono track specified by the Sound Track Start value as the language track into the center channel. So, for four languages here, you would have ten audio tracks, the 5.1 background music / effects tracks and then four different center language tracks.

Snd 71: This option plays the eight mono tracks starting at the track specified by the Sound Track Offset value (by default, 0) into the systems. So, if you have fully localized 7.1 tracks for four languages, you would mix in twenty-eight Bink tracks, and use the Sound Track Offset setting to specify the right range of audio tracks to play.

Snd 71 Language Override: This option plays the eight mono background / effect tracks starting at offset 0, and then the one mono track specified by the Sound Track Start value as the language track into the center channel. So, for four languages here, you would have twelve audio tracks, the 7.1 background music/effects tracks and then four different center language tracks.

Bink Sound Track Start: A Bink movie can contain multiple different sound tracks. With this option you can specify which sound track you want to play.

Bink Destination Upper Left / Lower Right This specifies the rectangle you want the movie to render to. You can use this to force a letter box, for example.

In-Game (Non-Startup) Movie Setup

You can also render movies during the game level itself. You can either render directly to a texture and then use that texture in game, or you can render directly to the screen. Bink renders after all the graphics but before the UI, so you can draw subtitles on top of the movie.

To do this, right click in the Content Browser and under the Miscellaneous section add a new Bink Media Player.







Click image to expand.



The Bink specific configuration options are:

Bink Buffer Mode This controls whether or not you want to stream a portion of the movie from disk, preload the whole movie before playing, or don't stop streaming until the whole movie is resident.

Bink Sound Track This determines how you want to play the sound. There are various options from simple stereo to 7.1 surround sound.

Bink Sound Track Start A Bink movie can contain multiple different sound tracks. With this option you can specify which sound track you want to play.

Bink Draw Style With this you can override the default UE5 functionality of rendering to a texture and instead render directly to the screen bypassing UE4 rendering.

Bink Destination Upper Left / Lower Right This specifies the rectangle you want the movie to render to. You can use this to force a letter box, for example.

Bink Layer Depth Allows you to render multiple videos at the same time and set the depth to control the order that they are drawn.

Bink movie files (*.bk2) should be placed in the (ProjectName)/Content/Movies folder, where (ProjectName) is the name of your project. This ensures that they are copied through to the final build properly in all configurations.

Right-click on the BinkMediaPlayer in the Content Browser and select Create Media Texture to generate a texture from the player. You can then create a default material using this texture by right-clicking the BinkMediaPlayer_Tex texture in the Content Browser and selecting Create Material. You can use this material and texture like you would use any other material or texture in Unreal Engine.

Other Bink for Unreal Notes

Multithreaded Decoding

The Bink Media plugin for Unreal Engine natively supports multithreaded decoding. It uses up to four threads during decompression, depending on the runtime CPU count.

By default, Bink 2 Encoder for Unreal Engine uses four video slices for best multithreaded performance.

Seeking

You can set a new playback position by calling the Bink plugin function, BinkPluginGoto, directly. Usually, you want to jump to a key frame, or all the intervening frames have to be decompressed along the way (the Bink plugin does this in the background for you). You control how much CPU Bink spends each frame seeking to the new frame with the ms_per_process parameter. Usually using 30 ms or so per frame seeks relatively quickly.

Video Depth (Sorting During Drawing)

If you are drawing lots of video overlays with the non-startup movie option, you can control the order in which they are drawn with the Depth option. This lets your videos stack correctly regardless of the order that Unreal Engine processes your videos.

For render targets, the Depth controls the order that the videos are drawn into the render target, but the render target is drawn into the scene normally by Unreal Engine.

Subtitles

Subtitles are supported via the Subrip .srt file format.

To use an srt file, include it in the same directory as the Bink 2 Video bk2 file. Name the file using the following format: "<name of Bink2 video file>_<language<.srt." This file should contain the subtitles for the specified language.

For example, if you have a "Movies/example.bk2" file, you would then have an additional "Movies/example_en.srt" file alongside it containing the subtitles for the English language.

Stereo Video

Bink is fast enough to use for 3D video. To do this, use the render target path, and then draw to a screen aligned quad. For each eye, adjust the quad to fill the screen with either the top half of the quad or the bottom half of the video.

Bink Plugin API

There are a number of other controls to the Bink plugin API as well. You can call any of the functions in binkplugin.h when you need custom controls, such as seeking, pausing, and so on.

Creating a Media Plate Actor

Importing Media Sources

Import Video Files

Import Media Sequences

Media Plate Settings

Mesh

Playlist

General Settings

Advanced Settings

Transform Settings

Materials

Sequencer integration

Considerations and Limitations

Useful Console Variables

Debugging

The Media Plate Actor is a pre-built Actor that you can add to your scene to play video, image sequences, and any URL towards a Media framework supported asset.



The Media Plate Actor supports:

A simplified process for importing video

Optimized streaming for tiled EXR image sequences with the built-in Sphere and Plane meshes. Requires DX12 or higher.

Media Playlists

Drag and drop assets and Actors

Sequencer integration

View frustum culling

Creating a Media Plate Actor

There are multiple ways to create a Media Plate Actor.

You can either:

Drag a media file (video file or an image from a sequence) directly into the Viewport.

Drag a media source asset from your Content Browser into the Viewport.

Use the Place Actors menu

Importing Media Sources

Media Plate supports both video files and image sequences. Depending on which media type you use, there are different ways to import them and denote the reference path of the related assets in Unreal Editor.

Common to both of these ways is that they immediately create the Media Plate Actor, which you can then configure using the Media Plate Controls.

Import Video Files

To import a video file:

Open the Content Browser.

Drag your video file into the Content Browser and drop it there.

Drag the file from the Content Browser into the Viewport. This creates the Media Plate Actor.



Import Media Sequences

To import a media sequence:

In the Content Browser, create an Img Media Source.

Under Sequence > Sequence Path, assign the path to the folder containing your images.

Optional: Under Advanced > Frame Rate Override, set the image sequence frame rate. If you don't specify anything here, the Media Plate Actor uses the default frame rate under your global settings.

Drag the Img Media Source from the Content Browser into the Viewport. This creates the Media Plate Actor.

Media Plate Settings

In the Media Plate Actor settings, you can adjust the look and playback of your video or image sequence. You do not need to create a Media Texture or Media Player.

The Media Plate has the following settings

Mesh

Here, you can select whether to use a Plane, Sphere, or a Custom mesh. When you select one, the referenced mesh automatically appears and the relevant settings for that mesh type become available for you to configure.

If you are using a tiled EXR image sequence and have DX12, or above, graphics capability, we recommend you select a Plane or Sphere mesh. Both these pre-built meshes use the Media Plate Actor's optimized streaming, so only the tiles visible to the camera are streamed. Custom meshes stream all tiles, regardless of their visibility to the camera. If you want to convert your media to the EXR format, you can use the Process EXR tool.

Playlist

When you add a video or image sequence, Unreal Editor automatically creates a Media Playlist to hold the video asset reference, visible in the Media Playlist section. This section also displays the references to the initial Media Source as well as the Media Path.

This section also contains clickable icons you can use to Restart, Rewind, Play, Pause, Fast Forward, Open, and Close the playlist.

The pen Media Plate button lets you open a media plate window with a flat-facing mesh that shows you more in-depth information about the media. In this window, you can also use the Previous and Next icons to access other media in your playlist.

General Settings

Property

Description

Media Details

Expand this to see the details about your media's resolution, frame rate, size, method, format, combined level of detail bias, and its number of mips and tiles.

Play on Open

Makes the video or image automatically start playing when opened.

Auto Play

Automatically opens the video or image sequence when you enter game mode.

Enable Audio

If an audio track exists, this setting enables audio for the active video decode engine.

Start time

You can use this to set a custom start time. This allows different Media Plate Actors that use the same source video to start at different times. You can then use the same loopable clip in multiple instances in your level, appearing different each time.

Play Only when Visible

Applies frustum culling to the Media Plate Actor so the whole video decode and streaming stops when the Actor is outside of the frustum.

This is typically useful for large installations with clustered rendering like nDisplay. Especially if you're using several large and resource heavy Media Plates.

Loop

Automatically loops the video when it reaches the last frame.

Advanced Settings

Property

Description

Sound Component

Contains details of any sound components used.

Static Mesh Component

Contains advanced details and properties of the mesh component used.

Letterboxes

Contains details of any letterboxes used.

Cache Settings

Override makes the Media Plate cache settings override global cache settings. Enabled by default. The Time to Look Ahead is expressed in seconds. For adequate caching, we suggest 2-4 frames. At 24fps, 2 frames should take 0.084 seconds. The default value is 0.2s.

Caching with tiles is a balancing act. The more frames you cache, the more frames need to be invalidated and reloaded when the camera moves.

Visible Mips Tiles Calculations

By default, this setting matches the static mesh you've chosen. If you want to use a Plane or Sphere, but do not want the Media Plate to only stream pixels visible to the camera, you can set this to None.

This can be useful for debugging, but we recommend that you do not use this for production.

Mip Map Bias

Sometimes, a PC is unable to playback a certain EXR sequence because of bandwidth, even though the sequence is split in tiles and mips. This setting lets you hint the Media Plate Actor in one direction or the other in order to load higher mips (lower resolution), which saves on input / output bandwidth. The estimated mip level matches the renderer by default, which makes it FOV / resolution dependent.

Transform Settings

In the Transform section, you can adjust the position, scale, and orientation of the Media Plate Actor. To read more about these settings, refer to Transforming Actors in Unreal Engine.

Materials

The Materials section allows you to pick another Material to override the existing default Media Plate Material. The default is a translucent and non-lit Material that renders pixels in the emissive channel. This Material is bundled within the Media Plate Plugin content directory.

You can drag the default or custom Materials within the Materials section of the Media Plate actor.

The Media Plate Actor looks for a special Texture parameter called MediaTexture. This parameter must exist within the chosen Material so that it can bind and access the pixels received from the video decoder MediaTexture.

Media Plate comes with the following default materials:

For 2D plates:

Material name

Description

M_MediaPlate

Is translucent. This is the default selection.

If you move away from a translucent material, you might experience TSR ghosting artifacts.

M_MediaPlateCC

Color correction material.

For Skies:

Material name

Description

M_Sky

Opaque, with the IsSky boolean enabled.

M_SkyCC

Color correction material for skies.

Sequencer integration

Sequencer integration is important to precisely control when video or image sequence clips start, end, or loop. You can also use it to make sure all clips are framelocked to the exact Sequencer time, providing you the means to finely control sequences with the overall level animation and logic.

To add your Media Plate Actor to Sequencer:

Drag the Actor from within the World Outliner and drop it in your Sequencer Track.



For proper sync in Sequencer, you must disable audio in the Media Plate Controls (general settings > uncheck Enable Audio) or any manually-created Blueprint using Electra Media Player.

Considerations and Limitations

When you use the Media Plate Actor, be aware of the following considerations and limitations:

Media Players: Only Electra and IMGMedia Players support synchronization. By default, the engine picks the first player it finds. To guarantee sync playback, you can manually force Electra as your player by selecting it inside FileMediaSource > Player Overrides > Windows > Electra player (ElectraPlayer).

Genlock: If you are using a clustered setup and want to optimize image playback frame accuracy, you must either use an unlocked custom timestep or select Genlock > Custom Time Step > Genlocked Fixed Rate. If you want to always increment time by the fixed rate delta time, select Force Single Frame Delta Time.

Real-time skylights and reflections: If you want to use the mips and tiles outside of your viewport to contribute to real-time skylights and reflections, you must use the [anchor link upscalehigherlevelmip]console variable.

Useful Console Variables

ImgMedia.FieldOfViewMultiplier: (ImgMedia.FieldOfViewMultiplier=1)

Since Media Plate only loads tiles visible by the current views, in some cases a fast-panning shot can cause temporary missing tiles around the edges. This console variable lets you increase the number of tiles loaded around the edges of the view.

ImgMedia.MipMapLevelPadding: (ImgMedia.MipMapLevelPadding=0)

If the mipmap estimation doesn't match the renderer with sufficient precision, this value is padded onto the calculated minimum and maximum mipmap levels.This increases the number of loaded tiles but can help eliminate artifacts under exceptional conditions.

Concert.EnableLoopingOnPlayer: (Concert.EnableLoopingOnPlayer=1) (Default)

By default, the Multi-User Sequence Manager ensures media playback is looped when looping is enabled on the Sequencer player. Prior to 5.1 Multi-user would not enable looping on the nDisplay sequence player and the looping would be handled by the reset of the play head with sequencer. This allows the playhead to remain in sync with the content on an ICVFX wall. If you prefer the playhead to be synchronized between the editor and nDisplay cluster then set this value to 0.

r.EXRReaderGPU.UpscaleHigherLevelMip: (r.EXRReaderGPU.UpscaleHigherLevelMip=-1)

Normally, Media Plate only loads the required quality mips and tiles in the viewport. However in some cases, such as reflections and skylights, you might want to load lower-quality tiles outside of the viewport for the areas of the EXR texture that are not filled with any data, in order for them to contribute to lighting and reflection.

For example, if you set this console variable to a mip level of 3, then mip level 3 will be fully read, loaded and upscaled into mip 0, 1, 2. Mip levels including and above 3 (4, 5, 6 etc) will be fully read into the texture. When recording, the area visible by the camera contains the proper quality mips, while everything not directly visible by the active views contains lower quality mips.

Debugging

You can use the following Stat commands for debugging the Media Plate Actor:

Stat Media: Displays information about the current Media being played.

ImgMedia.MipMapDebug 1: Prints visible tile and mip debug information to the screen in game mode. Only usable for files in the .exr media format.

Log LogImgMedia Verbose: Enables verbose log data specific to ImgMedia.

VP specifics

The Media Plate Actor is especially useful in clustered rendering setups with large LED displays, where the Actor maximizes the 2D plate or 360 latlong EXR playback performance and quality. The Media Plate Actor can use EXR tiling and mipmaps to balance load on render nodes and improve per-PC bandwidth limitations.

VP specifics

To make use of this maximization, we recommend you use an EXR media format, and select a Sphere or Plane mesh under the Mesh settings. These two meshes use optimized streaming, so the media plate only streams the tiles visible to the camera frustum.

If you have the Virtual Production Utilities plugin enabled, an extra property becomes available in the Settings for the Media Plate:

Materials > Create Dynamic Material You can create a dynamic material, which has any available parameter within the root Material exposed, so you can configure individual parameters.

If you want your skylight and tiles outside of the viewport to contribute to lighting and reflections, use the Upscale Higher Level Mip console variant.

In a clustered rendering setup using nDisplay, we recommend you try to use multiple PCs to help with bandwidth requirements. The more PCs you have, the fewer visible EXR tiles you will get per render node. Leveraging the support for tiles and mips, this should cut the per-PC input/output (IO) requirements. For high resolution EXR playback, for example simultaneous 8K+ latlongs, we also recommend that you have an SSD / NVMe raid configuration that throughputs at least 7-10 GB/sec on all nDisplay PCs.

The Process EXR Window

Sequence

Tiles

Processing

Debug



Unreal Engine supports EXR tiles and mips for EXR videos and sequences. When you use the Media Plate Actor to play your EXR sequences, the Actor's sphere and plane meshes automatically optimize performance by only streaming the tiles visible to the camera at any given time and picking the appropriate mip level for those tiles. This technique is compatible with clustered rendering, so the more PCs you have for a given display volume, the better the per-PC performance improvements are.

You can convert existing latlong 360 videos and 2D plates into the EXR format, by using the Process EXR tool. The tool divides EXR images into sub-divisions of tiles with mips in them.

To convert media source to the Unreal Engine EXR format:

Go to Content Browser > ImgMedia > Process EXR. This opens the Process EXR window, where you configure your .exr files.

If you want to convert your media outside of Unreal Engine, you can use the offline tool oiiotool. If you want to use the tool, you must disable compression. The following command line is an example for converting your media: oiiotool source.exr --ch R,G,B --compression none --tile 256 256 -otex result.exr

The Process EXR Window

The Process EXR window has the following options for you to configure:

Sequence

Property

Description

Input Path

Source folder for the files you want to convert into the EXR format.

Output Path

Destination folder you want to store the converted .exr files in.

Enable Mip Mapping

Enable the computation and processing of the EXR tile mipmap chain. Enabled by default.

Tiles

Property

Description

Enable Tiling

Enables tile splitting where you can determine the grid subdivision. Enabled by default.

When you are setting the numbers of tiles and mips, there's a potential trade off: if you have too many tiny tiles, your calculation cost increases. If your tiles are too large, your streaming cost increases. The default value is 256.



Tile Size X

The size of each tile along the X-axis.

Tile Size Y

The size of each tile along the Y-axis.

Num Tiles X

The amount of tiles on the X-axis.

Num Tiles Y

The amount of tiles on the Y-axis.

Processing

Property

Description

Num Threads

Specify the number of concurrent process threads to be used in your system.

Use Player

Use the Player for decoding. This is capped to 1 image per frame.

This is a faster option for large images. For smaller images, the cap makes it a slower option.

Debug

Property

Description

Enable Mip Level Tint

Bake mipmap coloring into the .exr file, to use for debugging purposes.

Mip Level Tints

Select the tints you want to bake into your mips.

Essentials



While there is currently a Startup Movie Player system in UE, it can only be used for playing startup movies while the Engine loads up. It cannot be used to play movies in-game, say for instance as part of a UI element or perhaps on a Static Mesh in your level like a movie playing on a TV. This is where the Media Framework comes in, as not only will it allow you to do both of the examples presented above, it will also provide much more general media playback capabilities (outlined below) and is also scheduled to replace the deprecated Startup Movie Player framework in a future engine release.

The Media Framework in Unreal Engine is:

Both Engine & Slate Agnostic

Able to support Localized Audio & Video Tracks

Accessible in the Content Browser, Material Editor, & Sound System

Available for use with Blueprint & the UMG UI Designer

Able to support Streaming Media

Able to Fast Forward, Reverse, Play, Pause, & Scrub Media

Able to support Pluggable Players

As stated above, the Media Framework itself is both Engine and Slate agnostic, which means it can be used in pretty much any application not just the game engine or the Editor. There are layers on top of the framework that provide media playback capabilities to other sub-systems as well, such as Engine, Blueprints, Slate, and the UMG UI Designer. This will cover most expected use cases, such as in-game textures & UI, in-Editor video tutorials, and Marketplace videos.

This page contains several links to additional documentation regarding Media Framework. It is recommended that you check out the Overview page for more of a breakdown of the features of Media Framework as well as the How-To and Quick Start pages for step-by-step instructions to working with Media Framework.

Essentials

Electra Media Player

Media Editor Reference

Media Framework Overview

Media Framework Quick Start

Media Framework Tutorials

Media Framework Technical Reference

Play a Video File

Play a Video Stream

Supported Media Formats

Supported Codecs

HTTP Live Streaming

Variant Streams Restrictions

Unsupported HLS Tags



Electra Media Player is a media player plugin for Unreal Engine, designed for both live streams and video on demand (VOD) streams using the HTTP Live Streaming (HLS) format. With this plugin, you can stream live performances and media into your Unreal project by providing the link to the source. In addition to streaming, Electra also supports .mp4 progressive download and local playback of .mp4 files.

Electra is supported on the following platforms:

Windows 7 or later

macOS

iOS 13.0 or later

Android Lollipop (5.1) or later

Playstation 4

Playstation 5

Xbox One/S/X

Xbox Series X

Nintendo Switch

The maximum playable video resolution and frame rate depends on the platform. See the respective platform documentation for their specifications.

To learn how to use the Electra Media Player to stream videos in your projects, see Play a Video Stream.

Supported Media Formats

Electra Media Player is a streaming media player within Unreal Engine that supports HLS formatted media streams. See HTTP Live Streaming for more details.

Electra Media Player also supports playback of a single, multiplexed .mp4 (ISO/IEC 14496-12) file if it meets the following specifications:

Contains at most one video track.

Contains only video and audio tracks.

Formatted as faststart, which stores the metadata of the file—the moov atom—before the frames—the mdat.

Accessed through the file:// URI scheme only.

Common Media Application Format (CMAF) is also supported since it is a specialization of .mp4.

See the Media Framework Technical Reference for a full list of supported file formats.

Supported Codecs

Electra Media Player only supports media files and streams encoded with the following codecs:

Media Type

Codec

Video Codec

H.264 / AVC (ISO/IEC 14496-10)

Audio Codec

AAC (ISO/IEC 14496-3)

HTTP Live Streaming

Electra Media Player provides streaming functionality in Unreal projects by supporting HLS (RFC-8216). With HLS, the server fragments the media files into segments and creates an index file. This index file contains the list of the media segments and their location that the client reads and uses to format its requests for media playback.

HLS also supports variant streams for the media files with different bitrates so the client can minimize stalling in playback. The variant streams are defined in another index file, called the master playlist. For more details on the HLS architecture, see Apple's HLS documentation.

Variant Streams Restrictions

HLS permits variant streams to use different segment durations as well as different number of segments without a way to identify matching segments. To reduce client overhead, the Electra Media Player requires all video variants to be segmented identically. For VOD presentations, the Electra Media Player then switches variants based on the absolute index of the segment in the variant playlists.

Live streaming presentations are handled differently since the playlists are constantly changing and contain a rolling window of a few media segments. Use the EXT-X-PROGRAM-DATE-TIME tag to identify matching segments in addition to segmenting media identically.

For optimal performance, Electra Media Player has the following restrictions for playlists and media segments:

Variant streams must be formatted as ISO/IEC-14496-12 or CMAF segments: MPEG2 transport stream segments as per ISO/IEC-13818-1 are not supported.

Corresponding segments in variant streams must have the same duration at each segment index: The video does not have to be segmented equally. For every variant stream A and B, the segment duration dur for segment n is the same:

dur(segment A(n)) == dur(segment B(n))

Different stream types do not need to have identical durations when segmented. Audio can use different segment durations than video segments.

Audio streams do not switch: There must be only one audio stream specified in the master playlist.

Segment duration cannot be rounded to the nearest integer in the variant playlists: Audio and video will segment differently because individual video images and audio sample blocks are not equal. The Electra Media Player synchronizes audio to video by locating the audio segment whose start time best matches the start time of the video segment and discarding any audio samples that are before the video start time. If the segment durations are not specified precisely in the variant playlist, the small error will accumulate and eventually result in selecting the wrong audio segment to start with, which would cause the audio to be out of sync with the video.

Audio groups are required in a master playlist: Because the container format requires a single elementary stream, you must specify an audio group in the master playlist. The following is an example of an audio group media tag in the master playlist.

#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_audio",NAME="audio_0",DEFAULT=YES,URI="manifest_0.m3u8"

#EXT-X-STREAM-INF:BANDWIDTH=8905600,RESOLUTION=1920x1080,CODECS="avc1.42c028,mp4a.40.2",AUDIO="group_audio"

CODECS and RESOLUTION properties are required in EXT-X-STREAM-INF tags: These properties are optional in RFC-8216 but required for Electra Media Player.

Use the FRAME-RATE property in EXT-X-STREAM-INF tags: The FRAME-RATE property is highly recommended for media playback with Electra Media Player since it helps identify and filter streams that cannot be played back on platforms that have issues with decoding more than 30 frames per second.

Rendition groups other than the required audio group are not supported: Rendition groups are used for alternate content, such as different viewing angles. Electra Media Player only supports one rendition group, the audio group referenced by the video variant playlists.

Video segments must have an Instantaneous Decoder Refresh (IDR) frame as the first frame: Playback will start on times only where an IDR frame exists in the video stream. This is equivalent to implicitly requiring the use of the EXT-X-INDEPENDENT-SEGMENTS tag, which itself is not required to be set but it is strongly recommended.

Frame accurate seeking is not supported: The IDR frame nearest to the specified time where playback should begin will be located and playback starts from there.

Only AES-128 encryption is supported for streams with the HLS format: SAMPLE-AES is not supported.

Media streams can contain an audio track without a video presentation. It is also possible to only stream a video with no audio.

Unsupported HLS Tags

Electra ignores the following tags in a master and variant playlist. These tags will not cause an error if they are present in the file unless they are required for correct playback.

EXT-X-DISCONTINUITY

EXT-X-DISCONTINUITY-SEQUENCE

EXT-X-DATERANGE

EXT-X-I-FRAMES-ONLY

EXT-X-I-FRAME-STREAM-INF

EXT-X-SESSION-DATA

EXT-X-SESSION-KEY

Media Framework Overview

Media Framework Tutorials

Toolbar

Player Window

Media Library

Playlist

Details / Info

When opening a Media Player asset, the Media Editor window will open presenting you with options for playing back and controlling different aspects of your Media Source assets. In the Media Editor, you can define the player Plug-in used for a Media Source, select between different audio/video tracks (if applicable) as well as define settings for the Media Player itself. The Info tab inside this editor will also display information about the type of media you are accessing which can be used to debug any potential playback problems. Please refer to each of the sections below for more information and a breakdown of the available options.

Toolbar



The Toolbar section of the Media Editor enables you to control the playback of media.

You must first select a valid Media Source from the Media Library window that you want to play for the playback options to become available.

Option

Description



Saves this Media Player asset (Ctrl+S).



Browse to the Media Player asset in the Content Browser (Ctrl+B).



Jump to previous item in the Playlist.



Rewind the media source to the beginning.



Reverse playback of the selected media (clicking multiple times increases the seek speed).



Start/Resume media playback.



Pause media playback.



Fast forward media playback (clicking multiple times increases the seek speed).



Jump to the next item in the Playlist.



Close the currently opened media.

Player Window



The Player Window enables you to view the playback of your media as well as define Playback Options. When you open a Media Source and mouse over this window, you will see text overlays that display the name of the file (upper-left), the current player Plug-in being used (upper-right), the state of the media (lower-left), and the current horizontal, vertical fields of view and view rotation (lower-right), which is used for 360 videos.

At the top of the Player Window, there is a text field that displays the URL path (which you can use to Open directly in Blueprint with the Open URL Blueprint node). To the right of the URL field, a reload button can be used to reload the current media (similar to pressing the reload button on most web browsers and can be used to reload external URLs that link to the Internet). To the left of the URL field, via the drop-down menu, are the Capture Devices options.

Capture Devices



The Capture Devices menu and options are available when you have a connected and supported device attached to your computer. These options enable you to test different audio and capture devices where the URL will update with the selected device. Capture Devices are slightly different the other Media Sources in that you can have multiple devices connected. You can use Blueprint (or C++) code to enumerate and filter for specific devices.



Above, in a Blueprint, you can search for enumerate or capture devices to see the list of optional enumerators.

In the example below, a sample setup using the Enumerate Video Capture Devices node is shown to filter for specified devices that we can use to obtain the URL to open.



Please see the Playing Live Video Captures page for more information.

Playback Options



Also part of the Player Window is the Playback Options menu that contains several different options used to define how your media is played.

Player

Option

Description

Decoder

This section enables you to define the player Plug-in used for media. Automatic is the default setting which will auto-select the appropriate player Plug-in based on the type of media.

Tracks

Option

Description

Audio

Enables you to set the default audio track associated with a media source (if multiple audio tracks are embedded with the media) or disable the audio track.

Captions

Enables you to define the default caption track for a selected media source (if tracks are embedded with the media).

Subtitles

Enables you to define the default subtitles track for a selected media source (if tracks are embedded with the media).

Text

Enables you to define the default text track for a selected media source (if tracks are embedded with the media).

Video

Enables you to set the default video track associated with a media source (if multiple video tracks are embedded with the media) or disable the video track.

Formats

Option

Description

Audio

Displays the available audio format tracks which you can select from (if applicable).

Captions

Displays the available caption format tracks which you can select from (if applicable).

Subtitles

Displays the available subtitle format tracks which you can select from (if applicable).

Text

Displays the available text format tracks which you can select from (if applicable).

Video

Displays the available video format tracks which you can select from (if applicable).

View

Option

Description

Scale

Change the video size to Fit (fit video in the Player Window), Fill (fill video in the Player Window) or Original Size (to use the original dimensions of the video).

Show Text Overlays

Toggles the display of any associated overlay assets with the selected media.

Media Library



The Media Library displays all of the Media Source assets within your project that you can open in the Media Editor. You can right-click on a source in this window to open up a context menu that you can use to edit the asset, open in the Media Editor, browse to the asset in the Content Browser or show the location of the Media File on your computer. This window also displays the type of each Media Source as well as their associated URL string.

Playlist



The Playlist section of the Media Editor not only displays all of the files contained within a Media Playlist but also enables you to create/save new Media Playlists assets inside your project. The arrows in the upper-right corner of the Playlist window function similar to the Toolbar's Prev and Next buttons and enable you to cycle through Media Sources in your playlist.



Above, an active Media Playlist displays each of the Media Sources contained within it with the arrow marker pointing to the currently playing source.

Each Media Source (when active) has a local Media Playlist created inside the Media Editor. You can save the local Media Playlist as a new Media Playlist by clicking the Save icon.



Details / Info



The Details panel provides options for controlling playback of the Media Player itself.

Playback

Option

Description

Play on Open

When enabled will automatically start to play a Media Source when opening the source through Blueprint or C++.

Shuffle

When a Playlist is opened, if this option is enabled, the player will randomly select a source within the playlist rather than playback sequentially.

Loop

When enabled will loop a single Media Source or entire Media Playlist (looping Video Capture devices is not supported).

View Settings

Option

Description

Horizontal Field of View

Enables you to manually set the Horizontal FOV value for 360 videos.

Vertical Field of View

Enables you to manually set the Vertical FOV value for 360 videos.

View Rotation

Enables you to manually set the View Rotation for 360 videos.

Editor

Option

Description

Affected by PIEHandling

Enables you to set whether this player should stop when entering or exiting PIE.

Info Panel



The Info panel provides information about the selected Media Source that you can use for debugging purposes. This window displays the player Plug-in associated with the file, the number of video and audio streams and information about video and audio tracks such as the codec being used, sample rate and dimensions.

Any errors when trying to playback video will be displayed here, for example, if you attempt to load an unsupported format, it will list it in this window as Not supported. Additionally, you can use the Copy to Clipboard button to copy this information out which you can use to post to our official forums or Answer Hub pages to get help with and troubleshoot any playback issues.

Media Framework Technical Reference

Media Framework Tutorials

Media Source Types

File Media Source

Image (Img) Media Source

Stream Media Source

Platform Media Source

Media Playlists

Media Sound Component

Media Textures

Media Player Assets

Media Assets & Scripting

Sequencer Integration

Media Framework uses several assets to enable the playback of videos inside Unreal Engine 5 (UE5). Videos can be scrubbed, paused, or rewound inside a Media Player asset, as well as controlled through C++ or Blueprints Visual Scripting. Whether you want a surface in your Level playing a video, or you want to create a UI element with



Media Source Types

There are several different Media Source assets that you can use to define where the media is coming from. Whether you have a file that is included as part of your project, streaming media from a website or using platform specific media, you will need to define a source before you can play the video. You can add a Media Source inside the Content Drawer by clicking the Add New button, then under Media, specifying which source type you want to use.



File Media Source





Click image to expand.



The File Media Source asset is used for media files stored on your device or in a shared local network file. The File Path section is where you specify where the media file resides.

While a media file can exist anywhere, it's typically a good practice to move your media files to the Content/Movies folder of your project and then point to the media file. This will ensure that your media is packaged correctly with your project. You will also see a yellow exclamation mark (as shown above) when pointing to a file outside of this location as a warning.

This type of source asset can load the entire media file into memory before playing by enabling the Precache File option (under the Advanced Options section). Based on the size of your file, caching time may vary, so take that into consideration when choosing this option. Each File Media Source asset can have its native Media Player Plugin (Plugin used to playback media) overridden on a per-platform basis (depicted below) or the player Plugin can be selected automatically.

Precaching may not be supported by all players and is currently only supported with MfMedia, PS4Media, and WmfMedia player Plugins.

Please see the Play a Video File how-to for working with File Media Source assets.

Image (Img) Media Source





Click image to expand.



The Img Media Source asset can be used for playback of image sequences stored on your device or from a shared local network where the Sequence Path field is used to point to the first image in your sequence. Images must be in a supported format and named sequentially (for example: MyImage01.png or MyImage_01.png) in order for the Engine to discover and populate the remaining images in the sequence.

You can define a Frames Per Second Override and any Proxy Overrides for the images in your sequence as part of the advanced options. As with other source assets, you can define the player plugin to use based on the type of platform the media is playing on using the Player Overrides section.

Please see the Play an Image Sequence how-to for working with Img Media Source assets.

Stream Media Source





Click image to expand.



This Stream Media Source asset takes a URL as the source of your media and pulls it from the internet. Currently, linking to a YouTube or Dailymotion style URL is not supported, and you will need to link directly to a hosted file. Like the File Media Source asset, Stream Media Source assets can have their player Plugin overridden on a per-platform basis or the player Plugin can be selected automatically.

Please see the Play a Video Stream how-to for working with Stream Media Source assets.

Platform Media Source





Click image to expand.



The Platform Media Source asset supports overriding a Media Source on a per-platform basis. For example, suppose you want a particular video to play only on Android Devices or only on PS4. Inside the Media Sources section, you can designate which videos play on which platforms. When using a Platform Media Source, a Media Source must be selected for every platform.

Please see the Playing Platform Specific Media how-to for working with Platform Media Source assets.

Media Playlists

While you can play Media Source assets individually, the Media Playlist asset can play multiple Media Sources in order. After creating a few Media Source assets, you can add them to a Media Playlist, which will automatically cycle through and play each asset in the order you define. You can create Media Playlists inside the Content Drawer from the Add New button under the Media section.



After creating and opening a Media Playlist, the Media Playlist Editor will open:





Click image to expand.



In the Media Playlist Editor, you can define the source assets to include and specify the playback order. Any Media Source assets you have created will be displayed in the lower Media Library window which you can double-click on to add to the end of the playlist (or add by using the + button under the Items section.) Media Playlists can use a mixture of each Media Source type and play in order unless specified through Blueprint Script.

Please see the Using Media Playlists how-to for working with Media Playlist assets.

Media Sound Component

In order to hear audio associated with a video, you will need to create a Media Sound component and add it to your Blueprint or Actor playing back the media in your Level.

Below we have a Static Mesh Actor in our Level, and in the Details panel have added a Media Sound component.





Click image to expand.



Once you have a Media Sound component added to your Actor or Blueprint, you will need to point the Media Sound component to a Media Player asset.





Click image to expand.



The Media Sound component provides Channels, Attenuation, Concurrency and other audio related settings inside the Details panel that you can use to define how your sound is perceived. When linked to a Media Player asset, audio attached to a video source will automatically playback along with the video. Typically, you can leave the default settings for the Media Sound component. However, if you need more control over the sound, you can adjust the Concurrency, Attenuation, and other settings.

Media Textures

Media Texture assets are used for rendering video tracks from Media Player assets.



While the Media Sound component provides the audio, Media Textures provide the visuals from your Media Source assets. Media Texture assets can be included within Materials that can then be applied to meshes in your levels such as a billboard, TV or monitor to make it appear as if the video is playing on that object within the game world. When you create a Media Texture asset, you will need to define which Media Player it is to reference inside the Details panel under Media Player.





Click image to expand.



Below, a Material including a Media Texture asset has been created and applied to a static mesh in the Level. Inside the Texture Editor, the Media Texture displays the same playback position as it appears in the Material in the Level. In addition to the standard Properties available, Media Textures accept X and Y Axis Addressing values of Clamped, Mirror or World values.





Click image to expand.



Materials use a Texture Sample node which references the Media Texture asset. On the Texture Sample node, the Sampler Type property should be set to External unless you are using the Electra Media Player, then you must set the Sampler Type property to Color.





Click image to expand.

Default Sampler Type property setting







Click image to expand.



Sampler Type property setting for the Electra Media Player

Media Player Assets

Once you have a Media Source or Media Playlist, you can play the asset using a Media Player asset. The Media Player asset requires the use of a Media Texture to produce the video playback and a Media Sound component to produce the audio associated with the video. You can create Media Player assets inside the Content Drawer from the Add New Button under the Media section.



When creating Media Player assets, the Create Media Player window (pictured below) will appear asking if you would also like to create and link assets to the Media Player. This allows you to automatically create and assign a Media Texture associated with the Media Player asset you are creating.



Double-clicking on a Media Player asset will open the Media Player Editor:





Click image to expand.



In the Media Player Editor, you can preview all the Media Source assets in your project, you can play, pause, rewind, or fast-forward (if supported) through media. You can also define playback settings for the Media Player asset including: where the media should automatically start playing when opened, whether the media should loop playback (if supported), or (if a playlist is being used) whether to shuffle and randomly select a source to play from the playlist.

For a more detailed breakdown of the Media Editor and options, please see the Media Editor Reference documentation page.

Media Assets & Scripting

Once your Media Player asset is set up and linked with a Media Texture and (if the video has audio) a Media Sound component, it can be played during a game session. In order to play media in-game, you will first need to create a reference to the Media Player asset through Blueprint or C++. To do this, create a Variable of the Media Player variable type inside any Blueprint and set the Default Value of the variable to reference your desired Media Player.





Click image to expand.



With a reference to your Media Player defined, you can then call an Open function based on the type of media source.





Click image to expand.



Option

Description

Open File

Opens a media file at the specified file location on your computer.

Open Playlist

Opens the first media source in the specified playlist.

Open Playlist Index

Opens a specific media source within a specified playlist.

Open Source

Opens the specified media source (File Media, Stream Media or Platform Media).

Open Source Latent

Opens the specified media source with options using a latent action.

Open Source with Options

Opens the specified media source with supplied options applied.

Open URL

Opens the specified media URL.

Reopen

Reopens the currently opened media or playlist.

Newly created Media Player assets have the Play on Open option enabled by default which means when you open a Media Source it will start playing the video automatically. You can uncheck this option inside your Media Player asset to have the source avoid playing when open and only start playing when explicitly called through Blueprint or C++.



If you do not want to automatically play the media once it has been opened successfully, you can also hook into the Play Blueprint event.





Click image to expand.



Above on Event BeginPlay, we open a Media Playlist and play the Media Player when the Right Mouse Button is Pressed only if it is ready to be played.

If you are not automatically playing a Media Source on open and are using the Play function to start playback, it is advised that you do not chain the Play call directly after an Open Source or Open Playlist call. This is because it may take some time for the Media Source to open and the Play command will just return false and the movie will not play as expected. In these instances, you may want to use a binding event that is bound to the On Media Opened call.





Click image to expand.



Above, we open a Stream Media source and bind the Media Player to On Media Opened which will fire an event when fully opened that will play the media.

You can bind other functions with a Media Player reference to various states of playback (for example: if the video is paused or if the video ends). You can also call several different functions off a Media Player reference like checking if a video can be paused, checking if a video is playing, if a video set to loop, and accessing play rate information (among other use cases). To see these options, drag off a Media Player reference then look under the Media Player section of the Blueprint Context Menu.





Click image to expand.



Sequencer Integration

Playback of videos with Media Framework will be frame-accurately synced to the timeline in Sequencer independently of the media player's real-time behavior. Sequencer internally handles communication and setup for this synchronization with the media player.

Currently, only ImageMediaPlayer supports this new synchronization. If you use a media player that doesn't support this feature, playback will start or stop close to what is indicated by the Sequencer timeline; however, frame-by-frame alignment could be random.

Introduction

Mipmaps

Limitations

File Directory Structure

Editor Setup

Mip Level Selection

Using Nuke and Python Scripts to Create EXR Mipmaps

Introduction

This document provides an overview of using mipmapping for image sequences.

As of 5.1, you can use the Process EXR tool to generate .exr files with the correct settings to use with the Media Plate Actor

Mipmaps

Mipmaps are used in image sequences to reduce the amount of data loaded in.

Mipmaps are not imported into the Engine as a normal texture, therefore there will not be a UAsset created for the EXR mipmaps. Due to this behavior, the mip levels need to be generated manually before using them in the Engine. See Using Nuke and Python Scripts to Create EXR Mipmaps for how to generate your own mipmaps.

Limitations

Only EXR files are supported at this time.

Anisotropic mips are not supported.

Reduction of data loaded in is achieved by only loading the required mip levels.

For GPU optimized streaming into Unreal, all EXR Image Sequences should be uncompressed.

You will only get GPU acceleration for loading EXRs if they are uncompressed.

All mip levels need to be either compressed or un-compressed. Having one level compressed and another uncompressed will break the chain.

File Directory Structure

The mipmap file directory structure should look like this, which follows the Cineon naming convention and is the industry standard.

File and folder names must follow these rules:

All folder names need to be a power of two, for example 1024x512.

Mip level images should be named exactly the same as the source image.

Editor Setup

To use the mipmap functionality, the ImgMediaPlayback component must be added to all objects that display the images. If the component is not present on an object, then the object will not be used in determining what mip levels should be used.

You can enable debugging with the following console command:

ImgMedia.MipMapDebug 1

This will display which mip level each image sequence is currently using.

Mip Level Selection

Mip levels are selected based on an estimated pixel to texel density for each object displaying the image.

The camera position is used for these calculations, so fast moving cameras can introduce more errors in the estimation. Further work could improve the estimation and take camera movement into account.

The mip level selected can be manually adjusted with the LODBias setting on the ImgMediaPlayback component.

Using Nuke and Python Scripts to Create EXR Mipmaps

Nuke and Python scripts are available to aid you in the auto-generation of your mip levels. Each script is available for both downloading and viewing on this page.

nukeMipMap.py is a Python script you can run in Nuke that will set up the proper LOD generating tree.

To use the script, select your EXR sequence, then set the number of mip levels desired.

At the top of the script, select the read nodes you want to create mip maps for, and execute.

All the necessary reformats and write nodes will be created for you in Nuke.

All the necessary resolution folders for each mip render will be created for you.

The paths of the mip renders will be based on the selected read node on execution.

nukeMipMap.py

Unreal_ExrMipMap_GenerationExample.nk is an example Nuke script with a tree already created for you. It demonstrates what folder structure is required for the mipmapping to generate the proper LOD scaling and displays the write node configuration without compression.

Unreal_ExrMipMap_GenerationExample.nk

The generated image below displays an example screenshot of the Unreal_ExrMipMap_GenerationExample.nk script.



autoGenEXR_mipmap.py is a script for users who do not have Nuke. This Python script will automatically create the necessary folders in addition to scaling and writing out the mip levels to the disk.

In order for this script to work, you will need to install the following free python modules numpy,opencv, and shutil.

autoGenEXR_mipmap.py

Blueprints Visual Scripting

Materials

1 - Project and Material Setup

1 - Project and Material Setup

2 - TV Blueprint - Component Setup

3 - TV Blueprint - Scripted Setup

4 - On Your Own!



At the end of this guide, you will have a TV playing content in your level that you can turn on or off when standing next to them and pressing a key.

Goals

In the Media Framework Quick Start guide, we walk through setting up a television (TV) that can play videos inside your level. We also set the TV up with Blueprints so the content on the TV can be turned on with the press of a button. We also expose the Media Framework variables so that we can quicly change the content that is played on the TV through the Details panel. If you are new to the Media Framework tools, or want to know how to play videos on Static Meshes inside your levels, this guide is for you.

This guide includes some setup using Materials and Blueprints to achieve the effect of a video playing on a TV. Some prior knowledge of these topics is recommended but not required.

Objectives

After going through this tutorial, developers will know the following:

How to import Media and use different Media Sources.

How to create a Material incorporating a Media Texture used to play media files.

How to start and stop playback of media using Blueprint.

How to create a TV Blueprint where you can specify what Media Source to use.

1 - Project and Material Setup

1 - Project and Material Setup

Create a New Project using from the Games category using the ThirdPerson Blueprint template and give it any name.

Extract this Sample Content to your machine, then import all content into the Engine.



Optionally, you can create a new folder to hold all the sample content. A Material will automatically be created based on the Texture asset.

In the M_TV_Inst Material, delete the Vector Parameter node, and add a Texture Sample with the Sample Type set to External.



Add a Texture Object Parameter and name it TV_Texture, then connect to the Texture Sample through the Tex pin.

For the TV_Texture Param Tex Object, change the Texture to a new Media Texture and call it MediaPlayer_01_Video.



Click image to expand.

Click the magnifying glass icon to browse to and open the MediaPlayer_01_Video asset.



If you are using a Texture Sample or Texture Object with the Electra Media Player, set the Sampler Type to Color.



Click the Media Player drop-down menu and create a Media Player asset called MyMediaPlayer.



Click image to expand.

When the Create Media Player pop-up menu appears, just click Ok as you do not need to create another Media Texture as you did this in Step 5 above.



Open your MyMediaPlayer asset, then double-click the Sample Video file and the video will start playing.



Click image to expand.

In the M_TV_Inst Material, add a TexCoord with VTiling set to 2.0 and connected to the UVs pin of the Texture Sample.



Click image to expand.

Add another TextureSample with the Texture set to the T_TV_M2 asset.



Click image to expand.

Add a LinearInterpolate node with the Texture from the previous step connect to the Alpha through the Green channel.



Connect the remaining pins as shown below.



Click image to expand.

Section Result

We've set up the Material that will play back our Media using a Media Player and associated Media Texture asset. If we open the TV mesh in the Content Browser, you may notice that the screen appears black (or white in some instances).



To preivew, you can open the Media Player asset and double-click the Media Source, at which point, the media will play on the Static Mesh TV in the Viewport.



Click image to expand.

2 - TV Blueprint - Component Setup

In this step, we create a Blueprint that uses the TV Static Mesh and the remaining components needed make our TV work in the Level.

In the Content Browser click the Add New button and select Blueprint Class.



In the Pick Parent Class menu, select Actor and name the Blueprint TV_BP.



In the TV_BP asset, click the Add Component button and select Static Mesh.



In the Details panel for the Static Mesh, assign the SM_TV as the Static Mesh to use.



Click image to expand.

Add a Box Collision component, then resize and move the box infront of the TV as shown below.



Click image to expand.

We are going to use the Box Collision to indicate when the player is infront of the TV and can turn it on (we don't want to be able to turn on the TV while standing behind it).

Add a MediaSound component and assign the MyMediaPlayer asset in the Details panel for the Media Player property.



Click image to expand.

This will be used to play back the audio associated with the defined Media Source inside the Media Player.

In the Details panel for the Box Collision, add both the On Component Begin Overlap and On Component End Overlap events.



Section Result

Our TV Blueprint is set up, next we will add the scripted functionality to be able to turn the TV on when standing next to it by pressing a key.

3 - TV Blueprint - Scripted Setup

In this final step, we add the scripted functionality that enables the player to press a button to turn the TV on or off.

On the Event Graph of the TV Blueprint, use a Get Player Controller, Enable Input and Disable Input connected as shown below.



Click image to expand.

Right-click in the graph and add a P Keyboard Event (or your desired key press) and connect Pressed to a FlipFlop node.



Right-click in the graph and disable Context Sensitive, then add an Open Source node.



On the Open Source node, right-click the Target pin and select Promote to Variable and call it MediaPlayerforVideo.



By default, Media Players are set to Play on Open which will play the media whenever it is opened.

For Media Players that have Play on Open disabled, you can use a Play node followed by an Open Source call.

Promote Media Source to a variable and call it SourceToOpen.

In the Variables list, click the eye icon on both variables to make them Instance Editable and connect as shown below.



Add a Close node connected to the B pin of the FlipFlop and Target set to MediaPlayerforVideo.



Drag the TV_BP into the Level, then in the Details panel, assign the MyMediaPlayer and Opening Demo assets.



Click image to expand.

You are going to use the Box Collision to indicate when the player is infront of the TV and can turn it on (we don't want to be able to turn on the TV while standing behind it).

Inside the MyMediaPlayer asset, enable the Loop option.



This will automatically loop the video once it starts playing unless instructed to close.

Click the Play button to play in the Level.

End Result

When playing in the Level and approaching the TV, pressing the P button will start playing the assigned media. Pressing P again will stop playback.

4 - On Your Own!

Here are some additional things to try with your project using the Media Framework tools:

Enable the player to control playback of the TV.

Use a Media Playlist as a Media Source and allow the player to "change the channels" for the TV.

Add a second TV Blueprint to the level with its own Media Player, Media Sound, and Media Source Assets.

Media Framework Overview

Media Framework Technical Reference

Level 1 Tutorials - Beginner

Level 2 Tutorials - Intermediate

Level 3 Tutorials - Advanced

This page provides links to step-by-step guides to creating and using the Media Framework tools within Unreal Engine 5. If you are looking to quickly get a video asset up and running inside your levels, check out the Beginner tutorials which illustrate how to use files located on disk as well as URL based media sources.

Refer to the table below for more information and click each link to view its contents.

Level 1 Tutorials - Beginner



Illustrates how you can play a video file inside a level on a Static Mesh with the File Media Source asset.



Example of how you can use playback an Image Sequence with the Image Media Source asset.



Shows how you can stream video from the internet and play it inside a UI element.

Level 2 Tutorials - Intermediate



Example of how you can pause, rewind, fast-forward, and resume playback of your videos in Blueprint.



Shows how to create and work with Media Playlists using the Media Framework tools.



Shows how the Platform Media Source asset can be used to play platform specific media.

Level 3 Tutorials - Advanced



Illustrates how you can pull live video captures and play it inside UE with the Media Framework tools.

Media Framework

Initial Setup

Blueprint Setup

Play/Pause - Up

Rewind/Fast-Forward - Left/Right

Close/Resume - Down

End Result

Along with playing videos inside your Unreal Engine 5 based projects, you can enable players to control the playback of your videos with a series of Blueprint nodes.

In this how-to, we provide a way for the Player to control playback of a video by creating the ability to pause, rewind, fast-forward, and resume playback of a video in progress.



Not all player Plug-ins may support fast forward and/or reverse playback. Please refer to the Media Framework Technical Reference page for more information.

Initial Setup

First, we'll locate our media and set up a folder in the Content Browser. This will lay a foundation we can later build upon in Blueprints.

For this how-to we are using the Blueprint Third Person Template project with Starter Content enabled. You will also need a video for playback, you can use your own or right-click and download this Sample Video.

In the Content Browser expand the Sources panel and create a folder called Movies. Then, right-click on the new folder and select Show in Explorer.



Drag the Sample Video (or your supported video) into the Content>Movies folder of your project on your computer.



To ensure that your video content is packaged and deployed with your project, your content must reside in the Content>Movies folder of your project.

Inside your project, create a Media Player and associated Media Texture asset called MediaPlayer and MediaPlayer_Video respectively.



Click image to expand.



Create a File Media Source asset called Video and inside it, point the File Path to the video added in Step 2.



Open your Media Player asset and disable the Play on Open option.



In this example, we are going to give playback control to the Player, rather than automatically start playback once we open our Media Source.

In the Place Actors panel under Shapes, drag a Plane into the level and resize as desired (Place Actors can be found under the Window tab if it's not already enabled).



Click image to expand.



Drag the MediaPlayer_Video texture onto the Plane, then in the Details panel for the Plane, add a Media Sound Component set to use your Media Player asset.





Click image to expand.



Blueprint Setup

Next, we want to set up our initial Blueprint, so later we can add functions to it.

From the Main Toolbar, click the Blueprints button then select Open Level Blueprint.



In the Level Blueprint, create a variable called MediaPlayer (of the Media Player Object Reference type) and set it to point to your MediaPlayer asset.

Hold Ctrl and drag the MediaPlayer variable into the graph and use Open Source and Event Begin Play to open your Video File Media Source asset.





Click image to expand.



Alternatively, you can use the Open Source Latent node (instead of the Open Source node) to open the specified media source with options and will delay the execution of the Completed output pin until after the source file has been opened.



This can be useful when you'd like to do something like set the play rate of the source.

Play/Pause - Up

Add an Up keyboard event connected to a Flip Flop and off your Media Player variable, use Play and Pause as shown below.



When the Player presses the Up arrow keyboard key, the Media Source will start playing while pressing a second time will pause the video.

Pausing corresponds to setting the Play Rate to 0.0, however not all Media Sources support pausing (for example, Web Cam and other video capture hardware sources. You can use the Can Pause Blueprint node to determine if a Media Source supports pausing.

Rewind/Fast-Forward - Left/Right

Add Left and Right keyboard events, then off your Media Player variable use Set Rate with the left key at -2 and the right key at 2.



This will enable the Player to press the left arrow keyboard key to set the Play Rate of the video to -2 (playing the video in reverse at double speed as a value of 1.0 is normal forward playback).

When pressing the right arrow keyboard key, the video will fast forward at double the normal playback speed.

You could add additional Blueprint logic to determine the number of times the Player presses the rewind or fast-forward keys and increase or decrease the Play Rate from 2x to 4x or 6x speeds or higher.

Even if the Player Plug-in supports Play Rates other than 1.0, the actual playback rates that can be selected will depend on the Media Source in use. You can check supported rates with the Get Supported Rates function.



Keep in mind there is a distinction between Thinned and Unthinned rates. Thinned means that some frames will be skipped at this rate, while Unthinned means that all frames will be decoded at this rate.

Close/Resume - Down

Add a Down keyboard event connected to a Flip Flop, then off a Media Player reference, use the Get Time function call.





Click image to expand.



The Get Time function call will return the current playback time which we will store and use when we want to reopen and resume playback of our video.

Right-click on the Return Value of the Get Time node and promote it to a variable called Stop Time, then connect all nodes to a Close function call as shown.





Click image to expand.



This will close the Media Player when pressing the down arrow keyboard key, but store the current time in which the Media Player was stopped to a variable.

Off the B pin of the Flip Flop use the Open Source node and set the Media Source to your Video Media Source.





Click image to expand.



This will re-open your video but will open it from the beginning of the video which we will address in the next few steps.

Drag off the Media Player reference and use the Assign On Media Opened Event Dispatcher and connect as shown.





Click image to expand.



This will create an Event Dispatcher that will call the connected Event only when the Media Source has been fully opened. When issuing commands to a Media Player, it's a good practice to do so in this manner as it ensures that the Media Source has been opened before attempting to tell it to do something. If we were to issue a command to the Media Player directly after opening it, there is no guarantee that the Media Source has been opened fully and can receive commands which may cause the command to fail.

Off your Media Player reference, call the Seek function followed by the Play function.

Create a Stop Time variable and connect it to the Time pin on the Seek node. Then connect the Seek and Play nodes to the OnMediaOpened event as shown.





Click image to expand.



Now when the Player presses the down arrow key, the current time is stored before closing the Media Player. When pressing down again, the Video Media Source is opened and when it becomes fully opened, the video moves to the specified Stop Time before playing the video (resuming playback).

Close the Level Blueprint and click the Play button from the Main Toolbar to play in the Editor.

End Result

You will now be able to use the Up, Down, Left, and Right arrow keys to control the playback of the video.

Pressing Up will play/pause the video, pressing Down will close/resume the video, pressing Left will rewind, and pressing Right will fast forward.

Media Framework

Steps

End Result

If you are looking for a way to play a video inside your level, whether it is playing on a TV inside the level, playing in the background as part of your UI or even playing fullscreen you will need to use the Media Framework tools and Media Source asset. While there are different Media Source asset types, the File Media Source asset is used when you have a video file stored on a device (for example on your computer, phone or console) that you want to play inside Unreal Engine 5 (UE5).

In this how-to, we use the File Media Source asset to play a video on a Static Mesh inside our level.

This tutorial covers manual workflows for playing video files. As of 5.1, you can also use the Media Plate Actor, which offers drag'n'drop addition of media sources and optimized streaming for pre-built meshes.



Steps

For this how-to we are using the Blueprint Third Person Template project with Starter Content enabled. You will also need a Supported Video File saved on our computer that you want to play. You can use your own or if you do not have a video, you can right-click and download this Sample Video for this tutorial.

In the Content Browser expand the Sources Panel, then under Content create a folder called Movies.



Placing your media files inside the Content/Movies folder of your project will ensure that your media is packaged with your project correctly.

Right-click on the Movies folder and select Show in Explorer.



Drag your desired video file into the Content/Movies folder of your project.



In order to package and deploy your content with your project, your media must reside in the Content/Movies folder of your project.

Inside your project, right-click in the Movies folder and under Media select File Media Source and call the asset SampleVideo.



Inside the File Media Source asset, under File Path click the ... button and point to your sample video on your computer.





Click image to expand.



Right-click inside the Movies folder again and under Media select Media Player.



In the Create Media Player window, enable the Video out Media Texture asset option then click OK.



This will create a Media Texture asset and automatically assign it to the Media Player we are creating. The Media Texture is responsible for playing back the media content and we can use this to create a Material that will be applied to a Static Mesh in our level a little later in this guide.

Name the Media Player and Media Texture asset, MyPlayer and MyPlayer_Video then open the MyPlayer Media Player asset.





Click image to expand.



Double-click on the SampleVideo in the Media Library section.





Click image to expand.



When double-clicking on the File Media Source asset inside the Media Library section, the video will start playing back. This is because the Play on Open option is enabled in the Playback section of the Details panel. When this option is checked, whenever a Media Source asset is opened, it will automatically start playing back and does not need to explicitly be told to start playing.

While our video plays back inside the Media Editor, a little later in this guide we will need to tell our Media Player through Blueprint Visual Scripting to open our File Media Source asset during gameplay so that the file will start playing while we are playing our game.

From the Place Actors panel in the Basic tab, drag a Plane into the level and use the Transform tools to move/scale the mesh as desired.





Click image to expand.



With the Plane selected in the level, use the Transform tools and Translate (W), Rotate (E) and Scale (R) the mesh to your desired appearance.

Drag the MyPlayer_Video Media Texture asset onto the Plane inside the level to auto create and assign a new Material.





Click image to expand.



When dragging the Media Texture onto the Static Mesh in the level, it will automatically create a new Material in the Content Browser and apply it to the mesh in the level.

With the Plane selected in the level, in the Details panel click the Add Component button and search for and add a Media Sound.



The Media Sound component is used to define the audio that will playback alongside the video.

In the Details panel, select the new Media Sound component then under the Media section, set the Media Player to use MyPlayer.





Click image to expand.



Here we are associating the Media Sound component with our Media Player asset so it knows where to draw audio from.

From the main toolbar, click the Blueprints button and select Open Level Blueprint.



We will use the Level Blueprint and tell our Media Player to open our File Media Source asset at the start of gameplay so it will start playing in the level.

Add a Variable of the Media Player Reference type called MediaPlayer and set the Default Value to MyPlayer.





Click image to expand.



You may need to create the variable, then click the Compile button in order to define a Default Value.

Hold the Ctrl key and drag the MediaPlayer into the graph, then right-click in the graph and search for and add an Event Begin Play node.





Click image to expand.



We now have a node to signify the start of gameplay and a reference to our Media Player asset. The last thing we need to do is tell our player to open a Media Source.

Left-click and drag off the Media Player node and use the Open Source function with Media Source set to SampleVideo and connect to the Event Begin Play.





Click image to expand.



Close the Level Blueprint, then click the Play in Editor button.

End Result

When you play in the Editor, the video will start playing on the Static Mesh.

Media Player assets by default are set to Play on Open which is why the video automatically starts playing when calling the Open Source function. There are additional commands you can issue to the Media Player asset such as pausing, rewinding or stopping the video once it has begun playing which can be found under the Media Player section when dragging off the Media Player Reference.

In this example we elected to put our media content inside our project's Content/Movies folder. While this is not a requirement it is recommended in the event that you want to package your project, as this is the only folder that will automatically include the content as part of the packaging/deployment process. You could point your File Media Source asset to folders outside of this location and the media will play, however if you were to deploy this to a mobile device for example, the content would not be included as part of deployment.

Media Framework

Media Framework Technical Reference

Media Editor Reference

Steps

End Result

The Image Media Source asset provides a way for you play back Image Sequences inside Unreal Engine 5 (UE5) as part of the Media Framework tools. Image Media Source assets are similar to the File Media Source in that you specify a path to your Image Sequence files so it can play them back instead of linking to a video. Naming conventions are important and it's recommended that you follow a sequentially based system for your images; for example, Image_01, Image_02, Image_03, ensuring that they play back correctly in order.

In this how-to, we apply and use the Image Media Source to play an Image Sequence on a Static Mesh inside the Level.



The Electra Media Player does not currently support Image Sequence playback.

This tutorial covers manual workflows for image sequences. As of 5.1, you can also use the Media Plate Actor, which offers drag'n'drop addition of media sources and optimized streaming for pre-built meshes.

Steps

For this how-to we are using the Blueprint Third Person Template project with Starter Content enabled. You will also need an Image Sequence or if you do not have one, you can right-click and download the Sample Image Sequence used with this tutorial.

In the Content Browser expand the Sources Panel, then under Content, create a new folder called Movies.



Right-click on the Movies folder, then select Show in Explorer.



While not required, in order to package and deploy your media with your project correctly it is recommended you place it inside Content/Movies folder.

Place the images from your Image Sequence inside the Content/Movies folder.



In the image above, we have created a new folder within Content/Movies called UE5_Images and within it, placed our JPG images. We also created another folder called lowres that contains lower resolution versions of the images in our sequence. The Media Framework tools provide a way for you to work with (typically) lower resolution versions of your images through media source proxies during development. This is more efficient and will help minimize any performance issues when working with larger image sequences and file sizes.

Return to the Editor and click the Don't Import button on the Auto-Import dialog window inside your Unreal Engine 5 project.



There is no need to import the images into the project as we can point to where they are located within our project's directory.

Right-click in your Content/Movies folder and under Media, select Img Media Source and call it MyImageSequence.



Inside the new MyImageSequence asset, click the ... button next to Sequence Path and point it to the first image in your image sequence.



Click the Advanced Options rollout button to expand the Sequence options and under Proxy Override, enter lowres.



Here we are pointing to a folder called lowres containing our lower resolution images that we will use for development. Working with the lower resolution image files will reduce the memory requirements and provide a more optimized experience than working with the full resolution files.

The Proxy Override path must point to a folder of the same name, in the same directory structure as your full resolution images in order to locate it.

Right-click in the Content/Movies folder and under Media, select Media Player.



The Media Player asset is what we will use to play back our image sequence we have created.

In the Create Media Player window, enable the Video output Media Texture asset option, then click the OK button.



This will create and automatically assign a Media Texture asset that is associated with this Media Player that will be used for playing our image sequence.

Name the Media Player asset MyPlayer (which will automatically name the Media Texture) and double-click to open it.



Inside the Media Editor, in the Details panel, enable the Loop option.



Enabling this option will cause the Media Player to continually loop (playback) our image sequence.

Double-click on the MyImageSequence asset to start playing the image sequence.



Your image sequence will start to play inside the Media Editor and if you click on the Info tab, you will see information about the image sequence that is playing. In our example, we can see that the Dimension for our image sequence is 640 x 360 as we are currently set to use our lowres images.

In the Content Browser, open the MyImageSequence asset and clear out the Proxy Override section.



This enables us to switch to our full resolution images, where if we open the Media Player asset and play our image sequence again, the Dimension values are different.



The Image Cache progress bar at the bottom of the Player window reflects the amount of content cached in memory (green means fully ready and loaded, yellow is currently being loaded, gray means it's being scheduled for loading). Based on your system hardware, the amount of caching and colors displayed may vary. See the Image Media section of the Media Framework Overview for more information.

From the Main Editor, in the Place Actors panel in the Shapes tab, drag a Plane into the Level and resize and position as desired.



You can use the Transform Tools to move, rotate or scale the plane as you would like.

From the Content Browser, drag the MyPlayer_Video Media Texture asset on top of the Plane in the Level.



This will automatically create and apply a Material using the Media Texture to the Plane in the Level, which our image sequence will play back on.

From the Main Toolbar, click the Blueprints button then select Open Level Blueprint.



Before we can start testing, we will use Blueprint to tell our Media Player to open our Image Media Source asset at the start of gameplay so it can start playing.

In the MyBlueprint panel, create a variable called MediaPlayer of the Media Player Reference type and assign MyPlayer as the Media Player.



You may need to click Compile after creating your variable in order to assign the Default Value for the Media Player.

Hold Ctrl and drag the MediaPlayer variable into the graph, then right-click and create an Event Begin Play node.



Drag off the Media Player variable and use the Open Source node and set Media Source to MyImageSequence and connect as shown.



Compile and Save, then from the Main Editor click the Play button to play inside the editor.

End Result

After playing in the editor, the image sequence will start to play on the Static Mesh in the Level and loop thereafter.

This example used JPG files, however, you can use any image files that are of the supported file type within an Image Media Source.

Media Framework

Steps

End Result

When working with media assets in Unreal Engine 5 (UE5), there may be times where you have a series of videos that you want to play in a specific order or you want to allow players to access videos within a specific series of videos. This can be accomplished by using a Media Playlist asset which points to Media Source assets assigned in a predefined order.

In this how-to, we create a Media Playlist and allow the player to play each asset sequentially or access a specific video inside the playlist through a key press.



Steps

For this how-to we are using the Blueprint Third Person Template project with Starter Content enabled. We are also using three sample videos in our playlist which you can download by right-clicking this Sample Videos link and extracting the contents on your computer.

In the Content Browser expand the Sources Panel, and create a folder called Movies then right-click on it and Show in Explorer.



In order to successfully package and deploy your video files along with your project, your videos must be placed inside the Content/Movies folder of your project.

Drag the Sample Video files provided into the Content/Movies folder of your project.



In your project, right-click in the Content/Movies folder then under Media select File Media Source.



Create three File Media Source assets called Video_01, Video_02 and Video_03 respectively.



Inside Video_01, point the File Path to the Gideon_720x480 file (or your desired video file) then click the Open button.



Repeat the previous step and assign videos for the Video_02 and Video_03 assets.

Create a MediaPlayer asset called MediaPlayer with an associated Media Texture, then open the MediaPlayer asset.



Double-clicking on a video inside the Media Library window will play the selected file.



You can also set the player to Shuffle the playback order of videos in a playlist by enabling the option in the Details panel. The Loop option will loop the playback of entire playlist (or a single source if there is only one source in the Media Playlist). Our Media Player is also set to Play on Open which means, when we open this Media Source associated with this Media Player, it will automatically start playing.

In the Playlist window, you can save out new playlist assets.

Inside the Content/Movies folder of the Content Browser, right-click and under Media select Media Playlist and call it MyPlaylist.



Open the MyPlaylist asset, then in the Media Library window, double-click on a video and add each to the playlist.



You can also use the + button to add new items to the playlist and the drop-down menu to select the type of Media Source to add. Inside the Playlist window you can insert, duplicate or delete items from the playlist or left-click and drag rows to reorder the playback order by clicking the tab along the left side of each row. At the top of the Media Playlist window, the Loop option is available if you want to loop the entire playlist.

From the Place Actors panel of the Main Editor window in the Shapes tab, drag a Plane into the Level and use the Transform Tools to resize it.



Using the Transform Tools you can move (W key), rotate (E key), or scale (R key) the plane as desired as we will play our videos on this Static Mesh.

From the Content Browser, drag the MediaPlayer_Video Media Texture asset onto the plane in the Level to create and apply a new Material.



When dragging the Media Texture onto the Static Mesh in the Level, a Material will automatically be created and applied to the mesh, enabling us to play our videos.

With the Plane selected in the Level, in the Details panel click the Add Component button and add a Media Sound component.



The Media Sound component enables us to associate audio with a Media Player and provides a way for the audio to be played along with our video.

Select the Media Sound component, then under the Media section assign your MediaPlayer asset.



From the Main Toolbar, click the Blueprints button and select Open Level Blueprint.



While our video plays inside the Media Editor, in order to play during gameplay we will need to open our playlist so it can start playing.

In the MyBlueprint window, create a variable called MediaPlayer of the Media Player Object Reference type and set the Default Value to your Media Player asset.



You may need to Compile your Blueprint in order to set the Default Value.

In the graph, right-click and add a 1 Keyboard Event, then hold Ctrl and drag the MediaPlayer variable into the graph.



Drag off the MediaPlayer variable and use Open Playlist Index (with In Playlist set to MyPlaylist) and connect to the Pressed of the 1 keyboard event.



Here, when the Player presses the 1 key on the keyboard, the playlist will open (and start playing) with the first video in the list. The index refers to the playlist index order specified inside your Media Playlist asset (pictured below) and is zero-based with zero being the first video in your playlist. With the Open Playlist Index node, you can specify which file you want to open within a playlist by entering its index value.



Right-click and add 2 and 3 keyboard events to Open Playlist Index for Index 1 and Index 2 respectively.



With this setup, when you press 1 you will open the first file in the playlist, 2 the second and 3 the third.

Right-click and add a Left and Right keyboard event to call Previous and Next nodes and 0 to Open Playlist.



The Previous and Next nodes will jump to the previous video and next video in a playlist respectively while the Open Playlist node executes the same functionality as opening a playlist at index 0 (or the start of the playlist). With these nodes, we will be able to cycle through our playlist by using the Left and Right arrow keyboard keys and pressing the 0 key will open the playlist at the start of our playlist.

Close the Level Blueprint then click the Play button to play in the Editor.

End Result

When you play in the Editor pressing the 1, 2, 3 or 0 keys will start playback at the specified index (if applicable).

When a video ends, it will automatically jump to the next video in the playlist. If you enabled Loop, once the final video in the playlist plays, it will jump back to the start of the playlist. While the video is playing, you can press the Left or Right arrow keys to jump to the previous or next video in the playlist or the 1, 2, or 3 keys to jump directly to a video in the playlist.

Media Framework

Steps

End Result

If you are working on a multi-platform project, there may be instances where you want to play platform specific media. For example, you may want a specific movie to play when playing on PlayStation 4 (PS4) and a different movie to play when playing on the Xbox One. Or you may be using the same type of media, but it is encoded differently for performance reasons and want those different formats to play on different platforms.

With the Platform Media Source asset, you can determine which Media Source assets should play based on the platform it is running on. When you open/play the Platform Media Source, it will look at which platform you are currently on and play the assigned Media Source automatically.

In this how-to, we create a Platform Media Source and assign two different Media Sources for Android and Windows platforms.



Steps

For this how-to we are using the Blueprint Third Person Template project with Starter Content enabled. We are also using two sample videos which you can download by right-clicking this Platform Videos link and extract the contents on your computer.

In the Content Browser expand the Sources Panel and add a new folder called Movies then right-click on it and Show in Explorer.



Drag the sample videos or your desired media files into the Content/Movies folder of your project.



If you want to package and deploy your project along with any media files, you will need to place them inside the Content/Movies folder of your project.

In your project under the Content/Movies folder of the Content Browser, right-click and under Media select File Media Source and name it Android_Movie.



Here we are creating a Media Source asset that the Platform Media Source asset can point to and use if it is running on an Android device.

Create another File Media Source asset and call it Windows_Movie.



Open the Android_Movie Media Source, then for the File Path use the Gideon_720x480 (or your desired video) and select Open.



For our Android movie, we are using a .3GP video file which is better suited for playback on Android devices while our Windows movie is an .MP4 file.

Open the Windows_Movie Media Source, then point the File Path to the Infiltrator Demo (or your desired video) and select Open.

Right-click in the Content/Movies folder then under Media, select Platform Media Source and call it Platform_Source.



Now that we have multiple Media Source assets, we can define which Media Source is to be played on which Platform with the Platform Media Source asset.

Open the Platform_Source, then under Android select the Android_Movie and under Windows select the Windows_Movie.



In our example we are using two different videos. However, you can use the same video that is encoded differently or in a different format for use with different devices. You may also use different Media Source types, for example, on Windows you may elect to use a Media Stream to pull content from a website instead of using a file on disk.

Right-click in the Content/Movies folder then under Media, select Media Player.



We still need to use a Media Player to open and play our Platform Media Source asset.

In the Create Media Player window, enable the Video output Media Texture asset option then click OK and call the asset Media Player.



This will automatically create a Media Texture associated with this Media Player that we can use inside a Material. We can then take that Material and apply it to a mesh in our Level to play our content on.

Inside the Media Player asset, double-click on the Platform_Media asset in the Media Library window.



Double-clicking on the Platform_Source asset will start playback of only the Windows assigned Platform Media Source (since we are running on the Windows platform). Through Blueprint or C++, we could open the Android_Movie Media Source for playback however when we open the Platform_Source, only the Media Source assigned to Windows will play. Also, the Play on Open option is enabled by default which will allow the Media Player to start playback of whatever Media Source is opened.

In the Main Editor window, from the Modes panel under Basic, drag a Plane into the Level and resize as desired then drag the MediaPlayer_Video texture onto it.



By dragging the Media Texture asset onto the Static Mesh in the Level, a Material is created and applied and will playback our media.

If you are using a Texture Sample or Texture Object with the Electra Media Player, set the Sampler Type to Color.



With the Plane selected, in the Details panel add a Media Sound component with the Media Player option set to use your MediaPlayer asset.



From the Main Toolbar, click the Blueprints option then select Open Level Blueprint.



In the MyBlueprint panel create a variable called MediaPlayer of the Media Player Object Reference type then assign your MediaPlayer as the Media Player to use.



This creates a reference to your Media Player asset which you can then use within Blueprint and call actions on.

In order to set the Default Value for the variable, you may need to first click Compile to compile the Blueprint.

Hold Ctrl and drag the MediaPlayer variable into the graph, right-click and add a 1 keyboard event and connect to an Open Source node pointing to the Platform_Source.



Here we are telling our Media Player to open the Platform Media Source asset which is set to open other Media Source assets based on which platform it is being run on.

Close the Level Blueprint then click the Play button to play in the Editor.

End Result

When you play in the Editor, pressing the 1 key will open the Windows-defined Media Source inside the Platform Media Source.

If you were to deploy this project to an Android Device, the Android assigned Media Source asset would play.

Media Framework



Recommended Setup

1. Creating the Streaming Media Source and Texture

2. Associating the Media Source With a Material

3. Adding the Media Source to a User Interface Widget

4. Playing the Media Source

End Result

A Stream Media Source is an asset that enables you to stream a video in the supported URL format inside Unreal Engine 5 (UE5). With the stream defined, you can load it up and play it inside UE5 with a Media Player asset and (with an associated Media Texture) can assign it to various aspects of your level.

The stream can be loaded and played as part of a UI element, played fullscreen or even applied to a Static Mesh (such as a TV) and played inside your level.

For this how-to, we use



You don't need to use C++ for this how-to.



Recommended Setup

For this how-to we are using the Blueprint Third Person Template project with Starter Content enabled.

1. Creating the Streaming Media Source and Texture

In the Content Browser expand the Sources Panel and create a new folder called Media inside the Content folder.



Right-click inside the empty Media folder, then under Media, select Stream Media Source and name the asset MediaStream.



Open MediaStream then enter your desired Stream URL.



If you do not have a URL file to link to, right-click this Sample Video and copy the link address and paste it in the Stream URL field.

Your Stream URL must link directly to a supported format in order to play the video. For example, PS4Media (PS4) only supports MP4 through HLS in the latest engine version, while WmfMedia (Windows) can support a number of other stream sources. For further information on supported formats per platform/player plug-in, see the Media Framework Technical Reference page.

Right-click inside the Media folder, then under Media, select the Media Player asset.



In the Create Media Player window, enable Video output Media Texture asset then click Ok.



This will automatically create and associate a Media Texture asset linked to this Media Player asset which is needed for playback.

Name the new Media Player Asset MyPlayer which will automatically be applied to the created Media Texture asset.



If you are using the Electra Media Player, open the newly created Media Texture asset in the Editor. In the Details panel:

Enable Enable new style output.

Set Output format (new style) to Default (sRGB).



2. Associating the Media Source With a Material

In the Media folder, create a new Material and call it MyPlayer_Material.



Open MyPlayer_Material and change its Material Domain to User Interface. This will change the Result node so that it has user interface outputs.



Click and drag MyPlayer_Video from the Content Browser into the graph for MyPlayer_Material. This will create a Texture Sample node with MyPlayer_Video as the source.

Connect the RGB pin to the Final Color input for your material.



If you are using a Texture Sample or Texture Object with the Electra Media Player, you will need to set the Sampler Type to Color.



3. Adding the Media Source to a User Interface Widget

Right-click in the Media folder, then under User Interface select Widget Blueprint and call it HUD.



A Widget Blueprint is an asset that is used with



Inside the HUD Widget Blueprint, from the Palette window drag an Canvas Panel into the graph and stretch it to fill the grid's aspect ratio.



From the Palette window drag an Image into the graph inside Canvas Panel and stretch it to fit.



We are going to apply our Media Texture to this image, and the image will fill the player's viewport when playing the game (creating a video that will play fullscreen).

In the Details panel for the Image under Appearance expand Brush then set the Image to MyPlayer_Material.



In the Details panel for the Image under Slot, click the Anchors dropdown and select the anchor middle option.



This will ensure that the image stays fixed in the center of the viewport regardless of viewport size.

4. Playing the Media Source

Close the HUD Widget Blueprint, then from the Level Editor Toolbar, select Blueprints and Open Level Blueprint.



Create a new variable called MediaPlayer of the Media Player Reference type and set the Default Value to your MyPlayer Media Player asset.



You may need to click Compile in order to see the Default Value of your MediaPlayer variable.

Hold Ctrl and drag the MediaPlayer variable into the graph to create a Get node for this variable, then right-click and add an Event Begin Play node.



When our game starts, we will go through the process of creating and displaying our HUD, set up sound for our stream, then open our stream so that it plays.

Right-click and add a Create Widget node and set Class to HUD, then off the Return Value use Add to Viewport and connect as shown.



Following the Add to Viewport node, right-click and use Add Media Sound Component and set the Media Player to MyPlayer in the Details panel.



In order to hear audio along with your video, you will need to use a Media Sound Component which points to your Media Player asset. Here we are dynamically creating and adding one at runtime. However, you can also add this component to an Actor that exists in the level or as part of a Blueprint from the Components panel.

Following the Add Media Sound Component node off the Media Player reference node, use Open Source and set Media Source to your MediaStream asset.



Click image for full view.

With our node network complete, when the game starts our HUD will be created and displayed, and sound will play along with our Media Stream we open it for play.

Close out the Level Blueprint, then click the Play button to play in the Level.

End Result

After playing in the Editor, the video will start playing back in full screen as part of our HUD Widget Blueprint.

Similar to using a File Media Source which plays a video file from disk, Stream Media Sources will automatically play when calling Open Source if their associated Media Player asset are set to Play on Open which by default is enabled. There are additional commands you can issue to the Media Player asset such as pausing, rewinding or stopping the video once it has begun playing which can be found under the Media Player section when dragging off the Media Player Reference.

Media Framework

Steps

End Result

Media Framework in Unreal Engine (UE) supports video and audio capture devices as a form of media that can be played inside the Engine. For example, you can take a live video feed from your webcam and play it directly inside UE on a Static Mesh or as part of a HUD. Or, you can deploy your project to a mobile device and retrieve the front or rear camera video feed and play that back inside your application.

In this example, you take the video capture feed from a webcam and display it as part of a HUD during gameplay.



The Electra Media Player does not currently support Live Video Capture playback.

Steps

This tutorial is using the Blueprint Third Person Template project with Starter Content enabled. You must also have a webcam attached to your computer.

Expand the Sources panel and create a folder called Movies, then inside it, create a Media Player and linked Media Texture asset called MediaPlayer.



Open the MediaPlayer asset, then next to the Media URL field, click and expand the Capture Devices and find your camera under Video.



The number of capture devices and names displayed may differ from the screenshot based on your computer setup.

When selecting your video capture device, video from the camera will be displayed inside the Media Editor Player.

Highlight and right-click copy the Media URL string displayed in the Media URL field.





Click image to expand.



The URL string displayed may differ from the screenshot based on your computer setup.

Inside the Content Browser, right-click and under User Interface select Widget Blueprint and call it HUD.



You are going to use your Media Texture inside your User Interface to display a picture-in-picture style HUD taking in and using your webcam video.

Open the HUD Widget Blueprint, then from the Content Drawer, drag-and-drop the MediaPlayer_Video texture into the HUD graph. You will see the video populate the Image field under Appearance.



Close the HUD Widget Blueprint, then from the Main Editor Toolbar, click Blueprints then select Open Level Blueprint.



While you are not directly opening a Media Source and instead have copied the Media URL, you still need to open it in order for it to play at runtime.

In the My Blueprint panel, create a variable called Media Player of the Media Player Object Reference type and assign your Media Player.





Click image to expand.



You may need to click Compile to compile the Blueprint before assigning the Default Value of the Media Player variable.

Hold Ctrl and drag the MediaPlayer variable into the graph, then right-click and add an Event BeginPlay node.



You have created a reference to your Media Player that you want to perform actions on, and an Event to signify the start of gameplay.

Right-click and add a Create Widget node (with HUD as the Class), then off the Return Value use Add to Viewport and connect as shown.



Here you are saying when the game begins, create the HUD Widget Blueprint and add it to the player's viewport.

Off the Media Player node in the graph, use Open URL and paste the URL copied from Step 3 and connect as shown.





Click image to expand.



If you play in the Editor now, video from your webcam will appear on the HUD image you placed in your desired location.



In this example the Media URL is specified to open, however, knowing what this is may not always be the case. You may package and distribute your project to others with this functionality and want to get what capture devices the end users have connected and use one of those. Or you may want to deploy your project to a mobile device and want to get the front or rear camera video feed and use that as the media source. You can use the Enumerate Capture Devices function to return all of the attached capture devices and get information about those devices.

Right-click in the graph and search for and add the Enumerate Video Capture Devices function.



There are enumerators for Audio, Video and webcam capture devices (where webcam is used for Mobile devices as you can get the Front or Rear cameras).

Drag off the Filter pin and use the Make Bitmask node.



Using the Make Bitmask node will enable you to filter for a specific subset of devices.

With the Make Bitmask node selected, in the Details panel, change the Bitmask Enum to EMediaVideoCaptureDeviceFilter then enable each in the filter.



Here you are filtering for each of the enabled options to return the capture devices (you could exclude the ones you want to omit to narrow the list of returned devices).

From the Out Devices use the Get Copy node and off its out pin, use the Break MediaCpatureDevice node and connect to an Open URL as shown below.



Click image to expand.

This process will find the first available capture device and return its URL that is then used with Open URL to open the source for playback.

Compile and close the Level Blueprint then click the Play button from the Main Toolbar to play in the Editor.

End Result

When you play in the Editor, the video feed from your camera will get pushed through to the Engine and appear on your HUD.

To get the Front or Rear camera on a mobile device:

Use the Enumerate Video Capture Devices node and set the Bitmask Enum to EMediaWebcamCaptureDeviceFilter option.

On the Make Bitmask node, flag which camera you want to get.



Supported Files, URLs & Capture Devices

Capture Devices

WMF Media Configuration

Custom Codecs

Playback Optimization

HAP Codec Playback Support

Benchmarking Test Case

Test System Description

Troubleshooting

Windows

Known Issues & Limitations

This page outlines the currently supported file extensions, URLs, and capture devices, as well as pointing out some troubleshooting tips on how to enable Media Framework with different platforms. There are some known platform-specific issues and limitations which we are currently investigating and trying to resolve, each of which has been identified in the Troubleshooting and Known Issues sections.

Supported Files, URLs & Capture Devices

The table below indicates the supported file extensions based on each media player platform.

Click the image below to download a .xlsx version of the Supported Files & URLs spreadsheets.



The table below shows the supported URLs based on media player platform.



The list of supported file formats above is ongoing, and support for additional file extensions will come online in future engine updates. These have been updated for the Electra Media Player.

For the best compatibility and performance, it is recommended to use H.264 encoded MP4 (.mp4) container files.

Capture Devices

Media Framework supports audio/video capture hardware on Windows (WmfMedia) and Android (AndroidCamera) as of 4.18 (consoles however, are not yet supported).

Please see the Playing Live Video Captures page for an example guide on working with capture devices.

WMF Media Configuration

The following sections describe the configuration options that you can set for the WMF Media Plugin in your Project Settings.

Custom Codecs

Windows Media Foundation (WMF) handles standard audio/video playback and recording on the Windows Platform; however, WMF is also extensible. By default, WMF supports a number of different formats, encoding, and file containers, but it can also be extended with the use of optional codec packs that can be downloaded and installed from the Internet. What this means, however, is that certain users may not have a particular codec needed to decode and playback a media file.

In the past, Unreal Engine only supported default codecs that were supplied with WMF to ensure that everyone could handle and process media the same way. There may be times when you want to use a different method of encoding your media or your own proprietary media encoder that you want to ship your game with (for example, you ship your game with an installer that provides the needed encoder).

You can now enable and allow non-standard codecs for WMF Media from the Plugins section of Project Settings.



Click image for full size.

By default, the player plugin will attempt to detect audio and video codecs that are not supported by the operating system (OS), requiring the user to install additional codec packs. If the player plugin detects an unsupported format when accessing the media, a warning message is provided in the Output Log.

Additionally, you can see media asset information inside a Media Player asset in the Info panel.

When enabling Allow non-supported codecs, the Plugin player will skip the check and allow the usage of non-standard codecs.

Playback Optimization

The WMF Media Plugin offers some options that you can use to customize the way it decodes and plays back your media. If the Plugin doesn't play your media with the responsiveness, smoothness, or performance that you need, you can try enabling these options.



Click image for full size.

Setting

Description

Low Latency

This setting minimizes delays, or latency, in media playback. If your video playback tends to lag, this setting may help you achieve a faster response from the WMF Media Plugin. However, enabling this setting may adversely affect the quality of the video and/or audio.Only works on Windows 8 or later.

Hardware Accelerated Video Decoding (Experimental)

Uses the GPU instead of the CPU to decode video streams. If your CPU is a bottleneck on your video performance, this setting may improve the smoothness of your video playback. It may also enable you to use more media at the same time, with larger resolutions.Only works on Windows platforms, rendering with DirectX 11.

This option is considered Experimental. We do not recommend shipping projects with Experimental features.

HAP Codec Playback Support

HAP Codec Playback allows you to produce high quality media with low CPU/GPU processing requirements.

In UE5, you can play 1x 4K 60 FPS movie or 2x 4K 30 FPS movie, which can be stretched to 2x 4K 60 FPS movies.

Specification

Supported Setting

Format

HAP, HAP Alpha, HAP Q, HAP Q Alpha

Frame Rates

10, 15, 23.976, 24, 25, 29.97, 30, 50, 59.94, 60

Resolutions

Up to 4K 3840x2160

Bit Depth

8bit (4:4:4:)

Pixel Aspect Ratio

Aspect Ratio Independent

As of 4.23, HAP playback does not support embedded audio or timecodes.

Benchmarking Test Case

Below is the benchmark test case the UE5 team used to determine these settings. You can use this test case as a comparison for your own project.

The current benchmarking process is meant to give a rough idea of system performance. We tested playback of the same movie file in 3 different softwares: Unreal Engine, Ventuz, and VLC. For each test, we monitored and logged CPU, GPU, and Disk usage with Windows Task Manager.

The movie file was an 11 second 4K 60 FPS movie from an 8K 60 FPS source that we recompressed in 4K, 8K, and 16K using HAP. We discovered issues with WMF that cause anything above 4K 60 FPS to fail on all three softwares. We also found that using two SSDs is significantly faster than using one SSD.

Here are some additional notes:

We were unable to properly assess disk usage for Unreal and Ventuz applications.

Note that a 60 FPS video clip is the equivalent of two 30 FPS video clips to decode.

At this point, this is not a PRO Video Playback solution so there is no guarantee on synchronous playback in between files or machines.

Xeon 3.39 Ghz

96 GB

Samsung MZVKW512HMJP-000L7 (C:)

ATA Samsung SSD 860 SCSI Disk (D:)



Troubleshooting

As of engine 4.18, most player Plugins have had extensive logging added, and will provide detailed logging of potential problems.

To enable logging, add the following to your project's Engine.ini file:

If a media source fails to open or play, check the Output Log for additional details.

You can also check information about a Media Source inside the Media Player asset and Info tab.



This will show what options are available for the media source, as well as the different Audio and Video streams and information about each stream.

Windows

The Windows Media Foundation (WMF) player Plugin WmfMedia has a number of limitations for MP4 containers.

See Microsoft's MPEG-4 File Source page for more information.

Known Issues & Limitations

Media Framework is still in development, and there are some known issues and limitations, as outlined below:

Android

Audio currently plays via the OS and cannot be piped through UE5's Sound System.

Editor

The Playlist UI inside the Media Player always has a playlist created internally.

Playlists can be saved from the Media Player; however, there is no way currently to edit the playlist in the Media Player.

Workaround: Save a Playlist from the Media Player then open and edit the Media Playlist asset.

Sequencer

Media Playback will not render out properly when recording cinematics from Sequencer.

We have this scheduled to release in the near future as we know this is important.

The ImgMedia Plugin will be synced with Sequencer.

Windows

QuickTime movie (.mov) support on Windows 7 and later is currently unreliable.

Workaround: This format is currently not recommended for use.

Linux

Currently, the WebM Media Player is the only available media player on Linux.

Getting Started

Guides

Reference

Sample Projects



Augmented reality experiences — mixing traditional 2D video with real-time 3D environments — are becoming increasingly in demand for film and broadcast media applications. The pages in this section describe how you can make the Unreal Engine work as a seamless part of your video production pipeline:

Play professional-level video and audio live in the Unreal Engine, composited into the virtual 3D world on the fly.

Apply effects to the imported video directly in the Unreal Engine, like chroma-keying, lens undistortion, color correction, and more.

Synchronize the Unreal Engine with the timecode and frame rate of your input video, to eliminate timing issues.

Render video feeds from the Unreal Editor or from your running game project back out to your studio's video pipeline.

Getting Started



A step-by-step guide to getting video from a supported AJA media card into the Unreal Engine, and sending captured video output from the Unreal Engine out to a port on the AJA card.



A step-by-step guide to getting video from a supported Blackmagic media card into the Unreal Engine, and sending captured video output from the Unreal Engine out to a port on the Blackmagic card.

Guides



Describes how to make the Unreal Engine adopt timecode from an AJA video input, and how to lock the Engine's frame rate to match the source video.



The Media Profile gathers input, output, timecode and genlock settings into one place for easy configuration. Proxies help route input and output.

Reference



Describes the options and settings exposed by the AJA Media Framework components.



Describes the options and settings exposed by the Blackmagic Design Media Framework components.

Sample Projects



The Virtual Studio showcases Unreal Engine's ability to exchange video feeds with professional grade SDI cards and devices.

1 - Set Up the Project

Steps

End Result

2 - Rendering Video Input in the Unreal Engine

Steps

End Result

3 - Output Captures from the Unreal Editor

Steps

End Result

4 - Output Captures at Runtime

Steps

End Result

On Your Own

In this Quick Start guide, we walk through the process of setting up an Unreal Engine Project to work with a professional video card from AJA Video Systems. At the end of this guide:

you'll have video input from your AJA card playing inside your Unreal Engine Project.

you'll be able to capture camera viewpoints both from the Editor and from your runtime application, and send them out to an SDI port on your AJA card.

you'll know where to go when you want to set up more advanced adjustments to your video inputs, such as correcting lens deformation and applying chroma-keying effects.

For a working example that shows many of the elements described below put into practice, see the Virtual Studio showcase, available on the Samples tab of the Epic Games Launcher.

Prerequisites:

Make sure that you have a supported card from AJA Video Systems, and that you've installed the necessary drivers and software. For details, see the AJA Media Reference page.

Make sure that your card is working correctly, and that you have some video input feeding in to at least one of the card's SDI ports.

Open an Unreal Engine Project that you want to integrate with your video feeds. This page shows the steps in the Third Person Blueprint template, but the same steps will work equally well in any Project.

The AJA Media components used in this guide are built on top of the Media Framework, and we'll use Blueprints to script the video capturing process at runtime. Some prior knowledge of these topics is recommended but not required.

1 - Set Up the Project

Before you can get video input from your AJA card into your Unreal Engine Level, and send output from the Unreal Engine through one of your AJA card's SDI ports, you'll need to do some basic setup to enable the AJA Media Player Plugin in your Project.

If you started your Unreal Engine Project from one of the Templates in the Film, Television, and Live Events category, the necessary plugins may already be enabled for you. If not, follow the instructions below to enable them.

Steps

Open the Project that you want to use with AJA video I/O in the Unreal Editor.

From the main menu, select Edit > Plugins.

In the Plugins window, find the AJA Media Player plugin under the Media Players category. Check its Enabled checkbox.





Click image to expand.



Find the Media Framework Utilities Plugin under the Media Players category. Check its Enabled checkbox, if it's not already checked.





Click image to expand.



Click Restart Now to restart the Unreal Editor and reopen your Project.





Click image to expand.



End Result

Your Project is now ready to accept video from the AJA card, and to send rendered output to the card. In the next sections, we'll hook it up and start playing video in and out.

2 - Rendering Video Input in the Unreal Engine

In this process, we'll make video input from the AJA card visible in the current Level in the Unreal Editor. This process uses a Media Bundle: a kind of Asset that packages together several different types of Assets involved in the Media Framework, and that offers you control over some advanced features like lens deformation, chroma-keying, color correction, and more.

Steps

In your Content Browser, expand the Sources panel. Right-click, and choose New Folder from the context menu. Rename your new folder AJA.

Open your new folder, right-click in the Content Browser and choose Media > Media Bundle.



Your new Asset's name is automatically selected in the Content Browser, so you can give it a descriptive name:



Type a new name, like AjaMediaBundle, and press Enter. A new folder of Media Framework Assets is automatically created next to your Media Bundle, named with the suffix _InnerAssets.

Save your new Assets by clicking the Save All button in the Content Browser.



Double-click your new Media Bundle to edit its properties. The Media Bundle is capable of playing video from any kind of media source the Engine supports, so you'll need to tell it that you want to get the video from your AJA card. In the Media Source property, select Aja Media Source from the drop-down list:





Click image to expand.



Once you've identified the type of Media Source you want the Media Bundle to handle, you can then set up any configuration properties offered by that type of source. You can make Unreal Engine automatically match the format and framerate of the incoming video signal. To enable automatic format detection, click the Configuration dropdown, enable Auto, and then click Apply. The engine now seamlessly handles changes and restarts automatically if the signal is temporarily lost.





Click image to expand.



The options you see may vary depending on the devices you have installed. For details on all of the properties you can set for an AJA Media Source, see the AJA Media Reference page.

If you want to apply any compensation to the incoming video to account for lens distortion, you can set up the physical properties of the lens in the Lens Parameters section.





Click image to expand.



These Lens Parameters just set up the physical properties of the lens. You'll actually activate the lens compensation later, when you edit the Material Instance used by the Media Bundle. Save your Media Bundle when you're done setting up its properties, and return to the AJA folder in the Content Browser.

Drag your AjaMediaBundle Asset from the Content Browser into the Level Viewport.





Click image to expand.





Now, we'll see how to apply keying and compositing effects to the video stream. Back in the Media Bundle Editor, click the Open Material Editor button in the Toolbar to edit the Material Instance that this Media Bundle uses to draw its incoming video feed on to an object in the Level.



This Material Instance is saved inside the AjaMediaBundle_InnerAssets folder that was created automatically with your Media Bundle.





Click image to expand.



In the Material Instance Editor, you'll see a number of properties exposed for you to configure keying, cropping, and color correction, and to activate the correction for the lens distortion that you set up in the Media Bundle.





Click image to expand.



You may find it more convenient to see the effects of the changes you make in the preview panel of the Material Instance Editor instead. To do this, temporarily enable the IsValid setting, and set its value to 1.0.

Click the arrow at the top left of the viewport toolbar, and enable the Realtime option in the menu.



You'll be able to judge the effect of your changes more easily by changing the preview mesh to a plane or a cube. Use the controls at the bottom of the viewport: When you're done, return the IsValid setting to its previous value.

When you're done changing the Material Instance properties, click the Save button in the Toolbar.

End Result

At this point, you should have video playing over an SDI port showing up inside your Unreal Engine Level, and you should understand where to set up more advanced features like lens deformation and chroma-keying.

If you're already familiar with the Media Framework, another way you could get video into your Level is to create a new AjaMediaSource Asset in your Project, and set it up with the same source properties you set up inside the Media Bundle in the procedure above. Then, create your own MediaPlayer and MediaTexture Assets to handle the playback of that source in your Level. For details, see the Media Framework documentation. However, we recommend using the Media Bundle, as shown above, to get the best balance between ease of use and professional quality video features.

3 - Output Captures from the Unreal Editor

In this process, you'll set up an AJA Media Output object, and use the Media Captures panel in the Unreal Editor to output the view from selected cameras in the Level to your AJA card.

Steps

Right-click in the Content Browser, and select Media > Aja Media Output.





Click image to expand.



Double-click your new Asset to open it up for editing. Just like when you created your Aja Media Source, you have to set up the Configuration property to control the properties of the video feed that the Unreal Engine sends to your AJA card. Click the arrow to open the submenu, select the options that match your video setup, then click Apply in the submenu.





Click image to expand.



Now we'll place two cameras in the Level, to give us viewpoints for the output we'll send to the AJA card. In the Place Actors panel, open the Cinematic tab, and drag two instances of the Cine Camera Actor into the viewport.

Place the cameras where you want them in the Level, so that they're showing different viewpoints on the scene.

Piloting the camera is a fast and easy way to set its viewpoint exactly the way you want it. See Pilot Actors in the Viewport.

From the main menu, choose Window > Virtual Production > Media Capture. You'll use the Media Capture window to control when the Editor sends output to your AJA port, and what camera it should use in the Level.



Under the Media Viewport Capture area, find the Viewport Captures control. Click the Add (+) button to add a new capture to this list.



Expand the new entry. First, we'll add the cameras that we want to capture from. In the Locked Camera Actors control, click the Add (+) button to add a new entry.

Then, use the drop-down list to choose one of the cameras you placed in the Level.

Repeat the same steps to add the other camera to the list.

Now, set up the output that you want to capture these cameras to. Set the Media Output control to point to the new AJA Media Output Asset that you created above. You can do this by selecting it in the drop-down list, or drag your AJA Media Output Asset from the Content Browser and drop it into this slot.



At the top of the window, click the Capture button.

You'll see a new frame at the bottom of the window that shows a preview of the output being sent to the AJA card. If you have this port hooked up to another downstream device, you should start to see the output coming through.



Each camera that you added to the Locked Camera Actors list for this viewport capture is represented by a corresponding button above the video preview. Click the buttons to switch the capture back and forth between the two views.





Click image to expand.



End Result

Now you've set up the Unreal Editor to stream output from cameras in your Level to a port on your AJA card. Next, we'll see how to use Blueprint scripting to do the same thing in a running Unreal Engine Project.

4 - Output Captures at Runtime

The Media Capture window that you used in the last section is a practical and easy way to send captures to the AJA card. However, it only works inside the Unreal Editor. To do the same thing when you're running your Project as a standalone application, you'll need to use the Blueprint API provided by the Media Output. In this procedure, we'll set up a simple toggle switch in the Level Blueprint that starts and stops capturing when the player presses a key on the keyboard.

The Virtual Studio showcase, available on the Samples tab of the Epic Games Launcher, contains a UMG interface widget that demonstrates how you could control capturing from an on-screen user interface.

Steps

From the main toolbar in the Unreal Editor, choose Blueprints > Open Level Blueprint.

We'll need to start from the AJA Media Output Asset that you've created, where you identify the port you want to output to. In the Variables list in the My Blueprint panel, click the Add (+) button to add a new variable.

In the Details panel, set the Variable Name to AjaMediaOutput, and use the Variable Type drop-down list to make it an Aja Media Output Object Reference.

Enable the Instance Editable setting (1), and compile the Blueprint. Then, in the Default Value section, set the variable to point to the AJA Media Output Asset that you created in your Content Browser (2).

Press Ctrl, and drag the AjaMediaOutput from the Variables list in the My Blueprint panel into the Event Graph.

Click and drag from the output port of the AjaMediaOutput variable node, and choose Media > Output > Create Media Capture. Hook up your nodes to the Event BeginPlay node as shown below: This creates a new Media Capture object from your Aja Media Output. The Media Capture offers two main Blueprint functions that we'll use to control the capturing: Capture Active Scene Viewport and Stop Capture.

First, we'll save the new Media Capture object into its own variable, so we can get access to it again elsewhere. Click and drag from the output port of the Create Media Capture node, and choose Promote to Variable. Rename the new variable MediaCapture in the Variables list in the My Blueprint panel.

It's important to save the Media Capture to a variable here. If you don't, the Unreal Engine's garbage collector may destroy it automatically before you're done with it.

Press Ctrl and drag the MediaCapture variable into the Event Graph.

Click and drag from the output port of the MediaCapture variable node, and choose Media > Output > Capture Active Scene Viewport. Do it again, and choose Media > Output > Stop Capture.

Right-click in the Event Graph and choose Input > Keyboard Events > P. Click and drag from the Pressed output of the P node and choose Flow Control > FlipFlop.

Connect the A output of the FlipFlop node to the input event of the Capture Active Scene Viewport node, and connect the B output of the FlipFlop node to the input event of the Stop Capture node, as shown below:

Compile and save the Blueprint, and try playing your Project. Click the arrow next to the Play button in the main Toolbar, and choose either the New Editor Window (PIE) or Standalone Game option.

Video capture from the Editor will only work when you play your Project in a New Editor Window (PIE) or a Standalone Game. It won't work in the default Selected Viewport mode, or in Simulate mode. In addition, the viewport resolution of your Project (that is, the size of the rendered image the Unreal Engine generates each frame) must match the output resolution set in the active Media Profile, so that it will be the right size for the output video feed.

After your project starts up, you should be able to press the P button on your keyboard to toggle sending the output from the Engine to the AJA card.

End Result

At this point, you should have a basic idea of how to work with Aja Media Sources, Media Bundles, and the Media Capture system, and you should understand how all of these elements work together to get professional video in and out of the Unreal Engine.

On Your Own

Now that you've seen the basics of how to get a new Project exchanging video input and output with an AJA card, you can continue learning on your own:

Explore the in-engine keying solution in the Material Instance created by your Media Bundle. Try passing some green-screen video into your card's input port, and use the keying controls in the Material Instance to remove the background.

Explore the Virtual Studio showcase to see what it adds to this basic setup, like its on-screen UI that switches cameras and controls video capture at runtime.

1 - Set Up the Project

Steps

End Result

2 - Rendering Video Input in the Unreal Engine

Steps

End Result

3 - Output Captures from the Unreal Editor

Steps

End Result

4 - Output Captures at Runtime

Steps

End Result

On Your Own

In this Quick Start guide, we walk through the process of setting up an Unreal Engine Project to work with a professional video card from Blackmagic Design. At the end of this guide:

you'll have video input from your Blackmagic card playing inside your Unreal Engine Project.

you'll be able to capture camera viewpoints both from the Editor and from your runtime application, and send them out to an SDI port on your Blackmagic card.

you'll know where to go when you want to set up more advanced adjustments to your video inputs, such as correcting lens deformation and applying chroma-keying effects.

For a working example that shows many of the elements described below put into practice, see the Virtual Studio showcase, available on the Samples tab of the Epic Games Launcher.

Prerequisites:

Make sure that you have a supported card from Blackmagic Design, and that you've installed the necessary drivers and software. For details, see the Blackmagic Media Reference page.

Make sure that your card is working correctly, and that you have some video input feeding in to at least one of the card's SDI ports.

Open an Unreal Engine Project that you want to integrate with your video feeds. This page shows the steps in the Third Person Blueprint template, but the same steps will work equally well in any Project.

The Blackmagic Design components used in this guide are built on top of the Media Framework, and we'll use Blueprints to script the video capturing process at runtime. Some prior knowledge of these topics is recommended but not required.

1 - Set Up the Project

Before you can get video input from your Blackmagic card into your Unreal Engine Level, and send output from the Unreal Engine through one of your Blackmagic card's SDI ports, you'll need to do some basic setup to enable the Blackmagic Media Player Plugin in your Project.

If you started your Unreal Engine Project from one of the Templates in the Film, Television, and Live Events category, the necessary plugins may already be enabled for you. If not, follow the instructions below to enable them.

Steps

Open the Project that you want to use with Blackmagic video I/O in the Unreal Editor.

From the main menu, select Edit > Plugins.

In the Plugins window, find the Blackmagic Media Player plugin under the Media Players category. Check its Enabled checkbox.





Click image to expand.



Find the Media Framework Utilities Plugin under the Media category. Check its Enabled checkbox, if it's not already checked.





Click image to expand.



Click Restart Now to restart the Unreal Editor and reopen your Project.





Click image to expand.



End Result

Your Project is now ready to accept video from the Blackmagic card, and to send rendered output to the card. In the next sections, we'll hook it up and start playing video in and out.

2 - Rendering Video Input in the Unreal Engine

In this process, we'll make video input from the Blackmagic card visible in the current Level in the Unreal Editor. This process uses a Media Bundle: a kind of Asset that packages together several different types of Assets involved in the Media Framework, and that offers you control over some advanced features like lens deformation, chroma-keying, color correction, and more.

Steps

In your Content Browser, expand the Sources panel. Right-click, and choose New Folder from the context menu. Rename your new folder Blackmagic.

Open your new folder, right-click in the Content Browser and choose Media > Media Bundle.

Your new Asset's name is automatically selected in the Content Browser, so you can give it a descriptive name: Type a new name, like BlackmagicMediaBundle, and press Enter. A new folder of Media Framework Assets is automatically created next to your Media Bundle, named with the suffix _InnerAssets. We'll take a look at these Assets later.

Save your new Assets by clicking the Save All button in the Content Browser.

Double-click your new Media Bundle to edit its properties. The Media Bundle is capable of playing video from any kind of media source the Engine supports, so you'll need to tell it that you want to get the video from your Blackmagic card. In the Media Source property, select Blackmagic Media Source from the drop-down list:





Click image to expand.



Once you've identified the type of Media Source you want the Media Bundle to handle, you can then set up any configuration properties offered by that type of source. You can make Unreal Engine automatically match the format and framerate of the incoming video signal. To enable automatic format detection, click the Configuration dropdown, enable Auto, and then click Apply. The engine now seamlessly handles changes and restarts automatically if the signal is temporarily lost.





Click image to expand.



The options you see may vary depending on the devices you have installed. For details on all of the properties you can set for a Blackmagic Media Source, see the Blackmagic Media Reference page.

If you want to apply any compensation to the incoming video to account for lens distortion, you can set up the physical properties of the lens in the Lens Parameters section.





Click image to expand.



These Lens Parameters just set up the physical properties of the lens. You'll actually activate the lens compensation later, when you edit the Material Instance used by the Media Bundle. Save and close your Media Bundle when you're done setting up its properties.

Drag your BlackmagicMediaBundle Asset from the Content Browser into the Level Viewport.





Click image to expand.



You'll see a new plane appear, showing the video currently being played over the port configured for your Media Bundle. Use the transform tools in the Viewport toolbar to move, rotate, and resize it. If your Media Bundle doesn't start playing automatically, select it, then click the Media Bundle > Request Play Media button in the Details panel.

Now, we'll see how to apply keying and compositing effects to the video stream. Back in the Media Bundle Editor, click the Open Material Editor button in the Toolbar to edit the Material Instance that this Media Bundle uses to draw its incoming video feed on to an object in the Level.

This Material Instance is saved inside the BlackmagicMediaBundle_InnerAssets folder that was created automatically with your Media Bundle.





Click image to expand.



In the Material Instance Editor, you'll see a number of properties exposed for you to configure keying, cropping, and color correction, and to activate correcting for the lens distortion that you set up in the Media Bundle.





Click image to expand.



While you adjust the settings in the Material Instance Editor, you can see the effect of your changes on the video feed playing back in the main Level Viewport.

You may find it more convenient to see the effects of the changes you make in the preview panel of the Material Instance Editor instead. To do this, temporarily enable the IsValid setting, and set its value to 1.0. Click the arrow at the top left of the viewport toolbar, and enable the Realtime option in the menu. You'll be able to judge the effect of your changes more easily by changing the preview mesh to a plane or a cube. Use the controls at the bottom of the viewport: When you're done, return the IsValid setting to its previous value.

When you're done changing the Material Instance properties, click the Save button in the Toolbar.

End Result

At this point, you should have video playing over an SDI port showing up inside your Unreal Engine Level, and you should understand where to set up more advanced features like lens deformation and chroma-keying.

If you're already familiar with the Media Framework, another way you could get video into your Level is to create a new BlackmagicMediaSource Asset in your Project, and set it up with the same source properties you set up inside the Media Bundle in the procedure above. Then, create your own MediaPlayer and MediaTexture Assets to handle the playback of that source in your Level. For details, see the Media Framework documentation. However, we recommend using the Media Bundle, as shown above, to get the best balance between ease of use and professional quality video features.

3 - Output Captures from the Unreal Editor

In this process, you'll set up an Blackmagic Media Output object, and use the Media Captures panel in the Unreal Editor to output the view from selected cameras in the Level to your Blackmagic card.

Steps

Right-click in the Content Browser, and select Media > Blackmagic Media Output.





Click image to expand.



Name your new Asset BlackmagicMediaOutput.

Double-click your new Asset to open it up for editing. Just like when you created your Blackmagic Media Source, you have to set up the Configuration property to control the properties of the video feed that the Unreal Engine sends to your Blackmagic card. Click the arrow to open the submenu, select the options that match your video setup, then click Apply in the submenu.





Click image to expand.



The options you see may vary depending on the devices you have installed. For details on all of the properties you can set in the Blackmagic Media Output, see the Blackmagic Media Reference page. Save and close your Media Output when you're done.

Now we'll place two cameras in the Level, to give us viewpoints for the output we'll send to the Blackmagic card. In the Place Actors panel, open the Cinematic tab, and drag two instances of the Cine Camera Actor into the viewport. Place the cameras where you want them in the Level, so that they're showing different viewpoints on the scene.

Piloting the camera is a fast and easy way to set its viewpoint exactly the way you want it. See Pilot Actors in the Viewport.

From the main menu, choose Window > Virtual Production > Media Capture. You'll use the Media Capture window to control when the Editor sends output to your Blackmagic device, and what camera it should use in the Level.

Under the Media Viewport Capture area, find the Viewport Captures control. Click the Add (+) button to add a new capture to this list.

Expand the new entry. First, we'll add the cameras that we want to capture from. In the Locked Camera Actors control, click the Add (+) button to add a new entry. Then, use the drop-down list to choose one of the cameras you placed in the Level. Repeat the same steps to add the other camera to the list.

Now, set up the output that you want to capture these cameras to. Set the Media Output control to point to the new Blackmagic Media Output Asset that you created above. You can do this by selecting it in the drop-down list, or drag your Blackmagic Media Output Asset from the Content Browser and drop it into this slot.

At the top of the window, click the Capture button. You'll see a new frame at the bottom of the window that shows a preview of the output being sent to the Blackmagic card. If you have this port hooked up to another downstream device, you should start to see the output coming through.

Each camera that you added to the Locked Camera Actors list for this viewport capture is represented by a corresponding button above the video preview. Click the buttons to switch the capture back and forth between the two views.





Click image to expand.



End Result

Now you've set up the Unreal Editor to stream output from cameras in your Level to a port on your Blackmagic card. Next, we'll see how to use Blueprint scripting to do the same thing in a running Unreal Engine Project.

4 - Output Captures at Runtime

The Media Capture window that you used in the last section is a practical and easy way to send captures to the Blackmagic card. However, it only works inside the Unreal Editor. To do the same thing when you're running your Project as a standalone application, you'll need to use the Blueprint API provided by the Media Output. In this procedure, we'll set up a simple toggle switch in the Level Blueprint that starts and stops capturing when the player presses a key on the keyboard.

The Virtual Studio showcase, available on the Samples tab of the Epic Games Launcher, contains a UMG interface widget that demonstrates how you could control capturing from an on-screen user interface.

Steps

From the main toolbar in the Unreal Editor, choose Blueprints > Open Level Blueprint.

We'll need to start from the Blackmagic Media Output Asset that you've created, where you identify the port you want to output to. In the Variables list in the My Blueprint panel, click the Add (+) button to add a new variable.

In the Details panel, set the Variable Name to BlackmagicMediaOutput, and use the Variable Type drop-down list to make it a Blackmagic Media Output Object Reference.

Enable the Instance Editable setting (1), and compile the Blueprint. Then, in the Default Value section, set the variable to point to the Blackmagic Media Output Asset that you created in your Content Browser (2).

Press Ctrl, and drag the BlackmagicMediaOutput from the Variables list in the My Blueprint panel into the Event Graph.

Click and drag from the output port of the BlackmagicMediaOutput variable node, and choose Media > Output > Create Media Capture. Hook up your nodes to the Event BeginPlay node as shown below: This creates a new Media Capture object from your Blackmagic Media Output. The Media Capture offers two main Blueprint functions that we'll use to control the capturing: Capture Active Scene Viewport and Stop Capture.

First, we'll save the new Media Capture object into its own variable, so we can get access to it again elsewhere. Click and drag from the output port of the Create Media Capture node, and choose Promote to Variable. Rename the new variable MediaCapture in the Variables list in the My Blueprint panel.

It's important to save the Media Capture to a variable here. If you don't, the Unreal Engine's garbage collector may destroy it automatically before you're done with it.

Press Ctrl and drag the MediaCapture variable into the Event Graph.

Click and drag from the output port of the MediaCapture variable node, and choose Media > Output > Capture Active Scene Viewport. Do it again, and choose Media > Output > Stop Capture.

Right-click in the Event Graph and choose Input > Keyboard Events > P. Click and drag from the Pressed output of the P node and choose Flow Control > FlipFlop.

Connect the A output of the FlipFlop node to the input event of the Capture Active Scene Viewport node, and connect the B output of the FlipFlop node to the input event of the Stop Capture node, as shown below:

Compile and save the Blueprint, and try playing your Project. Click the arrow next to the Play button in the main Toolbar, and choose either the New Editor Window (PIE) or Standalone Game option.

Video capture from the Editor will only work when you play your Project in a New Editor Window (PIE) or a Standalone Game. It won't work in the default Selected Viewport mode, or in Simulate mode. In addition, the viewport resolution of your Project (that is, the size of the rendered image the Unreal Engine generates each frame) must match the output resolution set in the active Media Profile, so that it will be the right size for the output video feed.

After your project starts up, you should be able to press the P button on your keyboard to toggle sending the output from the Engine to the Blackmagic card.

End Result

At this point, you should have a basic idea of how to work with Blackmagic Media Sources, Media Bundles, and the Media Capture system, and you should understand how all of these elements work together to get professional video in and out of the Unreal Engine.

On Your Own

Now that you've seen the basics of how to get a new Project exchanging video input and output with a Blackmagic card, you can continue learning on your own:

Explore the in-engine keying solution in the Material Instance created by your Media Bundle. Try passing some green-screen video into your card's input port, and use the keying controls in the Material Instance to remove the background.

Explore the Virtual Studio showcase to see what it adds to this basic setup, like its on-screen UI that switches cameras and controls video capture at runtime.

Visualizing Timecode in the Unreal Editor

Setting up Timecode and Genlock

End Result

Timecode Texel Encoding

By default, the Unreal Editor generates its own timecode, based on the current system time on your computer. This timecode is set by default to run at 30 frames per second, but the engine typically renders many more frames than 30 in any given second. So, typically multiple consecutive frames in the output will get assigned the same timecode value.

When you're working with professional video, you often have to keep timecode in sync between multiple different video feeds and signal processing devices. To do this, you may need to make the Unreal Engine's timecode match the timecode of the video feed you're working with. In some cases, you may want to go even further, and lock the engine so that it only produces one single frame for each frame of video that comes in through a reference input — we refer to this as genlock.

This page describes how to make the Unreal Engine adopt the timecode values from a port that you specify on your AJA card instead of generating its own, and how to genlock the Unreal Engine to that timecode signal.

Timecode and genlock management is under active development, and is likely to change in future versions.

Visualizing Timecode in the Unreal Editor

To see the actual timecode values being used by the Unreal Engine while you're working in the Unreal Editor, use the Timecode Provider panel. You can find this panel in the main menu under Window > Virtual Production > Timecode Provider.



It displays the current timecode, the timecode provider (the source of the timecode values), and the number of timecode frames that are being generated within each second. You can dock this panel anywhere in the UI of the main Level Editor.

Alternatively, you can use the following console command:

You'll see the values printed in the Unreal Editor viewport, in HH:MM:SS:FF format:



If you have the Unreal Engine set up to adopt timecode from an input signal, or to genlock to a video signal, you'll also see the source of the timecode and genlock. For example:



You can use this command to confirm that the Unreal Engine is generating frames at the rate you're expecting, and that it's using the same timecode values as your input video.

Setting up Timecode and Genlock

The following steps show how to make the Unreal Engine adopt its timecode values from an input SDI video feed coming in from an AJA or Blackmagic device, and how to make the Unreal Engine lock its frame rate to that feed so that it generates only one frame of output for each frame of input.

Right-click in the Content Browser, and choose Create Basic Asset > Blueprint Class.

In the Pick Parent Class window, expand the All Classes section (1). Search for and select the AjaTimecodeProvider class (pictured) or BlackmagicTimecodeProvider class (2), then click Select (3). Back in the Content Browser, give your new Asset a descriptive name, such as AJA_Timecode_Port or Blackmagic_Timecode_Port.

Double-click your new Asset to open it up in the Blueprint Editor, and set up the properties in the Details panel.

To read the timecode from an incoming video stream, set the Video Configuration or Media Configuration to point to the port on your AJA or Blackmagic card, and (if applicable) the type of timecode to read from the feed (LTC or VITC).

If you are using an AJA card, and you want to read the timecode from a reference port on the card rather than from a video stream, enable Use Reference In and set the Reference Configuration instead of the Video Configuration.

Compile and Save your Blueprint class, and close the Blueprint Editor.

If you want to genlock the Unreal Engine to your video source, repeat the previous instructions to create and set up another Blueprint class, but this time use AjaCustomTimeStep or BlackmagicCustomTimeStep as the parent class.

This class requires similar settings to the AjaTimecodeProvider or BlackmagicTimecodeProvider: AJA cards also offer additional settings; see the tooltips for details.

From the main menu, choose Edit > Project Settings.In the Project Settings window, open the Engine > General Settings category (1), and find the Timecode section (2). From the TimecodeProvider drop-down list, select the timecode port Asset that you created.

If you want to genlock the Unreal Engine to your video source, find the Framerate section above, and expand the advanced properties at the bottom of the section. From the Custom TimeStep drop-down list, select the genlock port Asset that you created.

Close the Unreal Editor and restart your Project.

If you use Media Profiles to set up multiple different media configurations for your Project, you can also override these default Project-level settings for Timecode and Timestep Providers in each Media Profile. For more information, see Supporting Multiple Media Configurations.

End Result

As long as you have video input coming in to the port you set up for the timecode provider and custom timestep classes, and that video has the resolution, frame rate and timecode format that you specified, the Unreal Engine should adopt your video's timecode and lock its frame update frequency so that it generates one output frame for each input frame.

To verify that this is working, use one of the options described under Visualizing Timecode in the Unreal Editor.

Timecode Texel Encoding

For debugging purposes, the Media Source and Media Output Assets for AJA and Blackmagic devices can encode the timecode of each frame into the video image by illuminating pixels in white. This can be useful if you need a visual way to verify that a given frame of video actually matches the timecode signal that accompanies it.

Timecode is usually expressed in the format HH:MM:SS:FF, for a total of eight digits. Each of these digits is assigned a row in the texture output, starting from the top of the image. Within each of those rows, count from the left of the image to value of that timecode digit to find the pixel that represents the timecode value. The leftmost pixel is pixel number 0.

So, for example, given the timecode value 12:08:44:12:

On the first row, the second pixel from the left is lit (pixel number 1).

On the second row, the third pixel from the left is lit (pixel number 2).

On the third row, the leftmost pixel from the left is lit (pixel number 0).

On the fourth row, the ninth pixel from the left is lit (pixel number 8).

and so on.

How Media Profiles and Proxies Work

Selecting and Saving the Active Media Profile

Getting Started with Media Profiles and Proxies

Using Proxy Media Outputs

End Result

If you've followed the Quick Start guide for working with AJA Media or Blackmagic Design hardware, you've seen one possible way to set up Media Input and Media Capture Assets to get SDI video feeds in and out of your Project.

However, you often need a single Project to work with multiple different media configurations. For example:

You may need to work with the Project on different computers, each of which has different hardware or a different wiring setup. For example, one computer might have an AJA card while another has a Blackmagic card; or the video feed that is connected to port 1 on one computer might be wired to port 2 on the other computer.

You may need to be able to switch your Project on one computer between different kinds of sources and outputs. For example, you may want to work with live feeds coming in over the SDI connections, but switch to using pre-recorded files on disk as inputs when the feed is offline.

You may also need to change the way the Unreal Engine reads timecode and genlocks its frame rate, especially when you change to different sources or inputs. For example, you may want to lock the Unreal Engine's frame rate only when using input feeds coming in over SDI connections.

In cases like these, you don't want to have to make deep changes in your media setup and Project content every time you switch setups. Instead, you can set up multiple Media Profiles, each of which gathers together all configuration settings related to media inputs, outputs, timecode providers, and genlock providers. By simply switching to a different Media Profile, you can immediately change your entire media I/O setup.

How Media Profiles and Proxies Work

Media Profiles rely on proxy Assets to make the connection between two different points:

On one hand, the input and output configurations that you set up in the Media Profile.

On the other hand, the places that those inputs and outputs are consumed or generated in your Project content.



Click image to expand.

The following list illustrates the numbered sections in the image above:

You set up multiple Media Profiles in your Project: one for each usage scenario that your Project needs to support. Each profile contains a list of media sources and a list of media outputs. You set up these lists to determine where your Project will get video input from, and where it will send captures to. For example, you could set up one Profile to get inputs from an AJA Media card, another to get inputs from a Blackmagic Design card, and a third to get inputs from files on disk. You can also mix and match within a single Media Profile. For example, a single Media Profile could get inputs from both files and SDI feeds.

When you have the Media Framework Utilities Plugin installed, the Project Settings panel for your Project contains similar lists of inputs and outputs. Each numbered entry in the input list of the Media Profile matches up with the same number in the input list of the Project Settings, and the same goes for the output lists. You set up each of these list entries in the Project Settings to point to a Proxy Media Source or Proxy Media Asset that you create in your Project.

You then refer to these same Proxy Media Assets anytime you need to set up a Media Source or a Media Output in your Project content. For example:

When you set up a Media Bundle or Media Player, you point it to one of those Media Proxy Assets instead of pointing it to a Media Source that directly represents a file, stream, or SDI input.

Similarly, when you set up a Media Capture, you send the output to a Proxy Media Output instead of directly to an AJA or Blackmagic Media Output. You can do this in the Media Capture panel in the Unreal Editor as shown above, or when you invoke the Create Media Capture Blueprint node at runtime. If you've set up the output list in your Project Settings to contain a reference to the same Proxy Media Output, the capture is then forwarded on to the output with the matching index that you have configured in the Media Profile.

The Proxy Media Source and Proxy Media Output Assets don't contain any important configuration properties themselves. They only act as a channel — a way to connect the input and output configurations set in the Media Profile with the places that those inputs and outputs are actually used or generated by other Assets elsewhere in the Project.

Selecting and Saving the Active Media Profile

Whenever your Project is loaded in the Unreal Engine or the Unreal Editor, it can have only one Media Profile active (or none at all).

When you have your Project open in the Unreal Editor, you select the active Media Profile using the Media Profile menu in the Toolbar of the main Level Editor:



Media Profiles are Assets that are always saved in the Unreal Engine Project. However, the choice of which Media Profile is active is saved on each computer, not within the Project. That means that once you've set a Media Profile for a given Project on a given computer, you never have to change it again (unless your media hardware or configuration changes).

On the other hand, when you run a packaged version of your Project, the choice of which Media Profile is active is always determined by the Startup Media Profile setting, which you'll find in the Project Settings window under Plugins > Media Profile.



Click image to expand.

Getting Started with Media Profiles and Proxies

In this procedure, we'll set up two Media Profiles: one that plays input from local movie files, and one that plays live video feeds from an SDI card. We'll set up two separate Media Bundles to play the videos in the Level. Finally, we'll use Proxy Media Sources to redirect the inputs from the sources configured in the Media Profiles on to the Media Bundles.

Prerequisites:

Media Profiles and Proxy Assets are provided by the Media Framework Utilities Plugin. You'll need to have this Plugin installed.

You'll also need to have followed the Quick Start Guide for either AJA Media or Blackmagic Design hardware.

To see a working example of a setup very similar to the one described below, see the Virtual Studio showcase, available in the Samples tab of the Epic Games Launcher.

Start by creating a Proxy Media Source Asset. Right-click in the Content Browser and select Media > Proxy Media Source from the context menu.





Click image to expand.



Repeat the previous step to create another Proxy Media Source, but name it VideoProxyInB.

Create a new Media Bundle Asset. Right-click in the Content Browser and select Media > Media Bundle.





Click image to expand.



Double-click the new Media Bundle Asset to edit it.

In the Details panel, find the Media Source setting and select Proxy Media Source from the drop-down list.





Click image to expand.



Expand the Source category, and set the Proxy to refer to the VideoProxyInA Asset that you created earlier.





Click image to expand.



Repeat the previous steps to create another Media Bundle. This time, name it MediaBundleB, and set its source proxy to refer to VideoProxyInB.

The Asset names recommended here, like VideoProxyInA and MediaProfileA, are intended to help make the relationships between the various Assets clear. However, in your own Project, we recommend using names that are more descriptive of the kind of content that the Media Proxy and Media Bundle need to handle. These Asset names are visible in your configurations, and in places like the Media Capture window, so ideally they should be meaningful to the whole team working on your Project.

From the main menu, select Edit > Project Settings. Find the Plugins > Media Profile section, and expand the advanced options.





Click image to expand.



Add two entries to the Media Source Proxy list. Set one to refer to VideoProxyInA, and one to refer to VideoProxyInB.





Click image to expand.



Now, we'll create a new Media Profile named FileProfile that plays videos from files on disk. You can do this in either of two ways:

Right-click in the Content Browser and select Media > Media Profile from the context menu, then rename the Asset.





Click image to expand.



From the profile selection button in the Toolbar, select New Empty Media Profile and set the path and name for the new Asset.

Double-click the new Media Profile to edit it, if it doesn't open for editing automatically. Find the Media Sources setting, and add two new elements to the list. Set each entry in the list to be a File Media Source, and set a different File Path for each.





Click image to expand.



If you need some sample videos to test with, you can use these: Video1 | Video2

Repeat the previous steps to create a second Media Profile, named LiveFeedProfile, that brings video in from the AJA or Blackmagic device connected your computer. For example:





Click image to expand.



Use the profile selection button in the Toolbar to select the FileMediaProfile that you created above.

Drag and drop your two Media Bundles into your Level Viewport. You should see them begin showing the videos loaded from the files or incoming over the SDI connections.

]



Click image to expand.



Now you can use the Media Profile selection tool in the Toolbar to switch between your two Media Profiles easily, changing your Media Sources (and, optionally, your timecode and genlock settings) in one click.

Using Proxy Media Outputs

In this procedure, we'll extend the Media Profile setup we created in the previous section. We'll capture a video feed in the Unreal Editor (or the Unreal Engine at runtime), and route that feed through a Proxy Media Output to an output configuration that we define in the Media Profile. The overall process is very similar to setting up media sources: you create a Proxy Asset, update the Project Settings to refer to the Proxy, and configure the actual output device in the Media Profile.

Start by creating a Proxy Media Output Asset. Right-click in the Content Browser and select Media > Proxy Media Output from the context menu.





Click image to expand.



From the main menu, select Edit > Project Settings. Find the Plugins > Media Profile section, and expand the advanced options.

Add an entry to the Media Output Proxy list, and set its output proxy to point to VideoProxyOut.

Double-click the LiveFeedProfile you created in the previous section, and add a new entry to the Media Outputs list. Set it up to send the video feed to a port on the AJA or Blackmagic device connected to your computer.

]



Click image to expand.



From the main menu, choose Window > Media Capture.

Add a new entry to the Viewport Captures list if needed, and set its Media Output setting to point to your VideoProxyOut Asset. ![Set the Proxy in the Media Capture22-new-entry-viewport-captures_ue5.png "Set the Proxy in the Media Capture")

Click Capture to start capturing the feed and sending it through the proxy to your AJA or Blackmagic device. If you switch the current Media Profile at this point to the FileVideoProfile, the capture stops, because the FileVideoProfile does not have an output configured for entry 0 in its Media Outputs list.

To capture the video feed at runtime and send it through the Proxy, you do it exactly as instructed in the Quick Start Guide for AJA Media or Blackmagic Design hardware. The only difference is that instead of using a variable that is an Object Reference to an AjaMediaOutput or BlackmagicMediaOutput, you use an Object Reference to the ProxyMediaOutput that you want to send the captures to. You then use this ProxyMediaOutput variable as the input to the Create Media Capture node. For example:

[ ]24-blueprint-setting_ue5.png)



Click image to expand.



End Result

You now have two different Media Profiles set up, each with its own configuration of input and output feeds. Each uses Media Proxy Assets to map those input and output configurations to the other Media Framework Assets that consume or produce those video feeds. This example configuration might not match your exact usage scenario. However, having walked through the steps to set it up, you should have a good idea of how to extend the same basic functionality to meet your own needs.

Supported AJA Cards and Software

AJA Media Source Settings

Configuration Options

Other AJA Options

AJA Media Output Settings

This page describes the options and settings exposed on AJA Media Framework objects.

Supported AJA Cards and Software

The AJA Media Source and AJA Media Output have been tested with the following cards, using Version 15.2 or later of the AJA Desktop Software:

Corvid 88

Corvid 44 12G

Corvid 44 12G BNC

Corvid 44

Corvid 44 BNC

KONA 4 (4K bitfile is supported, UFC bitfile is not supported)

KONA 5 (Both KONA 5 (4K) and KONA 5 (8K) bitfiles are supported)

KONA HDMI

Io 4K Plus

Other devices and SDK versions may or may not work as expected.

AJA Media Source Settings

Each AJA Media Source object that you create exposes the following configuration settings.



Configuration Options

Property

Description

Device

Sets the AJA device that this Media Source will use to bring video into the Unreal Engine. If you have multiple cards or devices attached to your computer, you can choose which one to use here.

Source

Sets the port or SDI connection on the specified device that this Media Source will use to bring video into the Unreal Engine. Note that only single-link connections are supported.

Resolution

Sets the resolution of the incoming video feed. Note that this must match the actual video feed exactly.

Standard

Sets whether the incoming video feed is progressive or interlaced. Note that this must match the actual video feed exactly.

Frame Rate

Sets the number of video frames per second in the incoming feed. Note that this must match the actual video feed exactly.

Other AJA Options

Property

Description

Timecode Format

Specifies the type of timecode that accompanies the video signal.

Capture with Auto Circulating

Captures video, audio, and ancillary data at the same time. This may decrease your transfer performance, but it guarantees that all data for each frame will be synchronized together. If you experience problems with latency, you can try disabling this option.

Capture Ancillary

Determines whether the Unreal Engine captures ancillary metadata that accompanies the video signal.

Max Num Ancillary Frame Buffer

Sets the maximum number of frames of ancillary data the Unreal Engine will store in memory at any given time. If the input video jumps or hitches, you can try raising this value.

Capture Audio

Determines whether the Unreal Engine captures audio from the Media Port.

Audio Channel

Specifies the audio channel that contains the signal you want the Unreal Engine to capture.

Max Num Audio Frame Buffer

Sets the maximum number of frames of audio data the Unreal Engine will store in memory at any given time. If the input video jumps or hitches, you can try raising this value.

Capture Video

Determines whether the Unreal Engine captures video from the Media Port.

Color Format

Determines the order of the color channels that make up each pixel in the input video, and the number of bits in each channel.

Max Num Video Frame Buffer

Sets the maximum number of frames of video data the Unreal Engine will store in memory at any given time. If the input video jumps or hitches, you can try raising this value.

Log Drop Frame

When enabled, the Unreal Engine prints a message to its output log every time it detects a dropped frame in the input feed.

Encode Timecode in Texel

When enabled, the engine embeds the timecode of each frame into the captured video. You can use this to check that the timecode for each frame of input matches the values you're expecting. See Timecode Texel Encoding.

Synchronize with Engine's Timecode

By default, the Unreal Engine attempts to play the video frames as they come in. Enable this setting to buffer incoming frames, and try to align them with the Unreal Engine's internal timecode. If the timecode of any buffered frame matches the Unreal Engine's internal timecode for any frame, the video input will be synchronized with from that frame forward.

Player Overrides

Leave these options at their default values for AJA Media Sources.

AJA Media Output Settings

Each AJA Media Output object that you create exposes the following configuration settings.



Property

Description

Output Type

Determines whether the Unreal Engine outputs only the fill image, or both the fill and key images. When you set this to Fill Only, only the fill image is output to the Source set below. When you set this to Fill and Key, the fill image is output to the Source, and the key is output to the Key Source.

Device

Sets the AJA device that this Media Source will send its video feed to. If you have multiple cards or devices attached to your computer, you can choose which one to use here

Destination

Sets the port or SDI connection on the specified Device that this Media Source will send video to. Note that only single-link connections are supported.

Resolution

Sets the resolution of the video feed produced by this Media Output.

Standard

Sets whether the output feed produced by this Media Output is progressive or interlaced.

Frame Rate

Sets the number of frames per second in the video feed produced by this Media Output.

Key Source

Sets the port that will receive the key images from the Unreal Engine, when the Output Type is set to Fill and Key.

Reference

Configures the source of the timing for the internal clock on the AJA card. The card uses this to determine when it should send each frame of video output.

Free Run - Uses the card's internal clock.

External - Synchronizes the card's internal clock with the genlock signal that arrives on its reference pin from an external source.

Input - Synchronizes with the video signal from the input port that you specify in the Sync Source setting below.

Sync Source

When the Output Reference is set to Input, this setting specifies which input port the AJA card should use as its output reference. The sync port must be on the same device as the fill port.

Output with Auto Circulating

When enabled, the Unreal Engine buffers its output frames before sending them to the AJA card. This may improve the smoothness of the video signal, at the cost of some latency. Leave this option disabled to minimize latency, at the risk of seeing interruptions in the output signal.

Timecode Format

Determines whether the Unreal Engine should embed timecode in the output feed, and which timecode format it should use.

Pixel Format

Determines the order of the color channels that make up each pixel, and the number of bits in each channel.

If you want to output the alpha, set the Output Type setting to Fill and Key, and use the Key Source to send the alpha to an output port on your AJA card.

Number of AJA Buffers

Sets the number of buffers used to transfer each frame image from the main thread memory to the AJA card. Lower values are more likely to cause missed frames as it waits for each transfer to complete; larger numbers are more likely to increase latency.

Interlaced Fields Timecode Need to Match

When producing an interlaced video feed, this setting determines whether the timecode values for both fields in a single interlaced frame need to match.

Number of Texture Buffers

Sets the number of buffers used to transfer each frame image from the GPU to main thread memory. Lower values are more likely to cause a bottleneck on the GPU side as it waits for each transfer to complete; larger numbers are more likely to increase latency.

Wait for Sync Event

When this option is disabled, and you don't already have the Unreal Engine genlocked to an input signal, the engine runs at the fastest frame rate it can manage and provides all the frames it generates to the AJA card. Each time the card is ready to output a new frame, it selects one of the frames generated by the Engine.

When this option is enabled, the Unreal Engine does not generate any new frames of output until the AJA card is ready to accept the new frame. The effect is similar to genlock, but instead of locking the Unreal Engine's frame rate to an input signal, it locks the Engine's frame rate to the output timing of the AJA card.

This option is most useful when you don't already have an input signal that you can lock the Unreal Engine's frame rate to, but you want to ensure that the Engine is producing only one output frame for every frame in the output video feed.

Do not enable this option if you already have the Unreal Engine genlocked to an input feed using a custom time step.

Encode Timecode in Pixel

When enabled, the engine embeds the timecode of each frame in the output signal. See Timecode Texel Encoding.

Supported Blackmagic Cards

Blackmagic Media Source Settings

Configuration Options

Other Blackmagic Options

Blackmagic Media Output Settings

This page describes the options and settings exposed on Blackmagic Media Framework objects.

Supported Blackmagic Cards

The Blackmagic Media Source and Blackmagic Media Output have been tested with the following cards:

DeckLink 4K Extreme 12G

DeckLink Duo 2

DeckLink 8K Pro

Other devices may or may not work as expected.

Blackmagic Media Source Settings

Each Blackmagic Media Source object that you create exposes the following configuration settings.



Configuration Options

Property

Description

Device

Sets the Blackmagic device and SDI connection that this Media Source will use to bring video into the Unreal Engine. If you have multiple cards or devices attached to your computer, you can choose which one to use here.

Resolution

Sets the resolution of the incoming video feed. Note that this must match the actual video feed exactly.

Standard

Sets whether the incoming video feed is progressive or interlaced. Note that this must match the actual video feed exactly.

Frame Rate

Sets the number of video frames per second in the incoming feed. Note that this must match the actual video feed exactly.

Other Blackmagic Options

Property

Description

Timecode Format

Specifies the type of timecode that accompanies the video signal.

Capture Audio

Determines whether the Unreal Engine captures audio from the Media Port.

Audio Channels

Specifies the audio channel that contains the signal you want the Unreal Engine to capture.

Max Num Audio Frame Buffer

Sets the maximum number of frames of audio data the Unreal Engine will store in memory at any given time. If the input video jumps or hitches, you can try raising this value.

Capture Video

Determines whether the Unreal Engine captures video from the Media Port.

Color Format

Determines the order of the color channels that make up each pixel in the input video, and the number of bits in each channel.

Max Num Video Frame Buffer

Sets the maximum number of frames of video data the Unreal Engine will store in memory at any given time. If the input video jumps or hitches, you can try raising this value.

Log Drop Frame

When enabled, the Unreal Engine prints a message to its output log every time it detects a dropped frame in the input feed.

Encode Timecode in Texel

When enabled, the engine embeds the timecode of each frame into the captured video. You can use this to check that the timecode for each frame of input matches the values you're expecting. See Timecode Texel Encoding.

Synchronize with Engine's Timecode

By default, the Unreal Engine attempts to play the video frames as they come in. Enable this setting to buffer incoming frames, and try to align them with the Unreal Engine's internal timecode. If the timecode of any buffered frame matches the Unreal Engine's internal timecode for any frame, the video input will be synchronized with from that frame forward.

Player Overrides

Leave these options at their default values for Blackmagic Media Sources.

Blackmagic Media Output Settings

Each Blackmagic Media Output object that you create exposes the following configuration settings.



Property

Description

Output Type

Determines whether the Unreal Engine outputs only the fill image, or both the fill and key images. When you set this to Fill Only, only the fill image is output to the Source set below. When you set this to Fill and Key, the fill image is output to the Source, and the key is output to the Key Source.

Device

Sets the Blackmagic device and SDI connection that this Media Source will send its video feed to. If you have multiple cards or devices attached to your computer, you can choose which one to use here.

Resolution

Sets the resolution of the video feed produced by this Media Output.

Standard

Sets whether the output feed produced by this Media Output is progressive or interlaced.

Frame Rate

Sets the number of frames per second in the video feed produced by this Media Output.

Key Source

Sets the port that will receive the key images from the Unreal Engine, when the Output Type is set to Fill and Key.

Timecode Format

Determines whether the Unreal Engine should embed timecode in the output feed, and which timecode format it should use.

Pixel Format

Determines the order of the color channels that make up each pixel, and the number of bits in each channel.

If you want to output the alpha, set the Output Type setting to Fill and Key, and use the Key Source to send the alpha to an output port on your Blackmagic card.

Number of Blackmagic Buffers

Sets the number of buffers used to transfer each frame image from the main thread memory to the Blackmagic card. Lower values are more likely to cause missed frames as it waits for each transfer to complete; larger numbers are more likely to increase latency.

Interlaced Fields Timecode Need to Match

When producing an interlaced video feed, this setting determines whether the timecode values for both fields in a single interlaced frame need to match.

Number of Texture Buffers

Sets the number of buffers used to transfer each frame image from the GPU to main thread memory. Lower values are more likely to cause a bottleneck on the GPU side as it waits for each transfer to complete; larger numbers are more likely to increase latency.

Wait for Sync Event

When this option is disabled, and you don't already have the Unreal Engine genlocked to an input signal, the engine runs at the fastest frame rate it can manage and provides all the frames it generates to the Blackmagic card. Each time the card is ready to output a new frame, it selects one of the frames generated by the Engine.

When this option is enabled, the Unreal Engine does not generate any new frames of output until the Blackmagic card is ready to accept the new frame. The effect is similar to genlock, but instead of locking the Unreal Engine's frame rate to an input signal, it locks the Engine's frame rate to the output timing of the Blackmagic card.

This option is most useful when you don't already have an input signal that you can lock the Unreal Engine's frame rate to, but you want to ensure that the Engine is producing only one output frame for every frame in the output video feed.

Do not enable this option if you already have the Unreal Engine genlocked to an input feed using a custom time step.

Encode Timecode in Pixel

When enabled, the engine embeds the timecode of each frame in the output signal. See Timecode Texel Encoding.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Camera Lens Calibration Quick Start Guide

Section Results

Go to Window > Virtual Production > Composure Compositing to open the Composure window.



Right-click inside the Composure window and select Create New Comp from the menu. Click the Empty Comp Shot button to create a new empty composition.





Right-click the composure and select Add Layer Element. Click the Media Plate button. This media plate will use the live video feed from your camera.





Navigate to Content Browser > Your project folder for MediaIO > and drag MediaBundle-01 into your Level.





Click image to expand.



Select the media plate in the Composure window and go to the Details panel. Scroll down to the Composure section and expand the Input category. Click the Media Source dropdown and select T_MediaBundle-01_BC from the list. You should now see the live video feed streamed on the media plate.







Click image to expand.



Right-click the composure and select Add Layer Element. Click the CG Layer button.



Go to Window > Layers to open the Layers window.



Select the BP_UE_Tracker3 and the CameraCalibrationCheckerboard Blueprints from the Outliner. Go to the Layers window then right-click and select Add Selected Actors to New Layer from the menu. Name the layer cglayer.





Click image to expand.



You can also find BP_UE_Tracker3 in the Content Browser under Engine content folder.





Click image to expand.



Select the cg element layer in the Composure window and go to the Details panel. Scroll down to the Composure section and click the + button to expand the Capture Actors options. Click the ActorSet dropdown and select cglayer from the list.





Click image to expand.



With the cg element layer selected, scroll down to the LensDistortion section and select the Distortion Source as the LumixLens file.



Right-click in the Content Browser and select Material from the Create Basic Asset section. Name the Material M_SimpleComp.



Double-click M_SimpleComp to open it. Select the Material node and go to the Details panel. Set the Shading Model to Unlit.



Right-click in the graph then search for and select TextureSample. Right-click the Texture Sample node and select Convert to Parameter. Name it CGLayer. Go to the Details panel and add a texture to the CG Layer dropdown.







Repeat the previous step and add another Texture Sample. Name the parameter MediaPlate.





Click image to expand.



Right-click in the graph then search for and select Over. Connect the RGBA pins of both nodes to the A and B pins of the Over node. Finally, connect the RGBA pin of the Over node to the Emissive Color pin of the Material node.







Click image to expand.



Select your composition from the Composure window and go to the Details panel. Scroll down to the Transform / Compositing Passes section and expand Transform Passes. Add the M_SimpleComp Material to the Material slot.





Click image to expand.



Expand Input Elements and add Media Plate and CG Element layers to their corresponding slots. You should now have the video feed streamed to the Media Plate and your selected Actors displayed in the CG Elements layer.





Click image to expand.



Section Results

In this guide you learned how to use Composure with the Camera Calibration plugin.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Camera Lens Calibration Quick Start Guide

Section Results

Select your CineCamera Actor in the Outliner and go to the Details panel.



Select the LiveLink Component Controller component and scroll down to the Camera Role category. Verify that the correct Lens File is assigned to the Lens File slot. In this example the LumixLens file is used from the Quick Start Guide.



Click the Add Component button, then search for and select Lens Distortion to add the component.



Scroll down to the Default section and click the dropdown next to Distortion Source. Select the LumixLens file and enable the Apply Distortion checkbox.



You should now see the lens distortion applied to the CineCamera Actor in the viewport.

Section Results

In this guide you learned how to apply the lens distortion effect from the Camera Calibration plugin to the CineCamera Actor.

Camera Lens Calibration

Focus and Iris Mapping

Calibrated Data

Distortion Parameters

Camera Intrinsics

Nodal Point Offset

ST Maps

Lens File Asset Editor

Calibration Steps

Lens Information

Lens Distortion

Image Center

Nodal Offset

Viewport Settings

Distortion Pipeline

Producers of Distortion Data

LiveLink streaming per-frame distortion parameters and camera intrinsics

LiveLink streaming camera FIZ to Evaluate a Lens File asset

Static Camera FIZ and LensFile asset

Blueprints

Consumers of Distortion Data

CineCamera with Lens Distortion Component

Composure CG Layers

Overscan

Undistortion

OpenCV

Creating accurate compositions from CG renders and live video requires a virtual camera in Unreal Engine that accurately simulates the physical camera used to capture the real-world video footage. The virtual camera's position and orientation must closely match that of the physical camera, and its tracking information must match the video feed's exact timing to ensure each video frame is accurately synced to the position of the camera for each moment in time.

The Camera Calibration plugin provides simplified tools and workflows to calibrate a camera and lens in the Editor. This calibration process generates the data necessary to accurately align the virtual camera with the physical camera's position in space, and to model the lens distortion of the physical camera. The plugin introduces the Lens File asset type which encapsulates all of the calibration data for the camera and lens.

The Camera Calibration plugin also includes a robust lens-distortion pipeline that takes the calibrated distortion data and applies an accurate post-process effect to the CG render. The distortion post-process effect can be applied directly to a CineCamera Actor, which can be used in Movie Render Queue, or to the CG layers of Composure.

The plugin's tools and framework are extensible and flexible to support a wide range of lenses and workflows.

Camera Lens Calibration

Focus and Iris Mapping

The Camera Calibration plugin uses a Lens File asset to convert the raw focus and iris values to physical units used by the CineCamera component. For example, the raw input values could include encoder positions (absolute or normalized) streamed from an external device through Live Link. These values could also be converted to the appropriate units, but this would require fine tuning to achieve better accuracy.

Calibrated Data

Calibrated lens data can vary depending on the camera's focus and zoom. Therefore, to achieve a high-quality calibration, you often need to calibrate using multiple focus and zoom points. Distortion parameters, camera intrinsics, and nodal point offsets are all stored in the Lens File along with their associated focus and zoom value. It is possible to evaluate a calibrated Lens File for any focus and zoom position by interpolating between the stored focus and zoom points.

Distortion Parameters

The Camera Calibration plugin adds support for an accurate lens distortion post-process effect defined for a physical lens model. This lens model defines a set of distortion parameters that are used to compute the distortion for various positions around the lens.

The plugin supports a spherical-distortion model, based on the Brown-Conrady model, that uses five distortion parameters (K1, K2, P1, P2, K3). These parameters are unitless and are computed as part of the calibration process. The plugin is extensible and provides the ability to add support for additional models with different parameters.

Camera Intrinsics

Camera intrinsics include focal length and image center, and define how 3D points in the camera's coordinate system are projected to a 2D image. These intrinsics must also be calibrated to accurately model the camera and lens.

Depending on the calibration method, focal length may be calculated using physical units (millimeters) or pixel count. Focal Length is often represented as a 2D vector (Fx, Fy), which should be roughly equal in length. To generalize the representation, the Lens File stores calibrated focal length as normalized values dividing either by the image sensor width and height (in millimeters), or by the image resolution (in pixels).

After normalization, Fx and Fy will no longer be roughly equal to one another, but (Fy / Fx) should be roughly equal to your aspect ratio.

A calibrated image center takes into account the physical misalignment between the lens and the image sensor of the camera, but it should generally be close to the ideal center. Image center is also typically calculated in physical units (millimeters) or in pixels and is represented by a 2D vector (Cx, Cy). Like focal length, image center is normalized by dividing by the sensor width and height (in millimeters) or by the image resolution (in pixels). After normalization, the image center should be close to (0.5, 0.5).

Nodal Point Offset

The nodal point of a lens is the point at which light rays converge. In Unreal Engine, the virtual camera should be placed in the virtual world at this nodal point to ensure that real objects and CG objects are well-aligned.

Nodal Point Offset calibration is a separate calibration step that finds the pose of your tracked physical camera and computes the offset between that pose and your tracking data. This ensures that as the camera moves, the virtual camera's transform will continue to be set to the nodal point of the physical lens.

ST Maps

An ST Map is an image in which the value of each pixel corresponds to a distorted image coordinate in UV space. ST Maps can be generated using calibration tools outside of Unreal Engine and can be used in post-processing to alter the UVs used when sampling scene textures.

To support users who already generated calibrated data from external tools, the Camera Calibration plugin supports direct input of ST Maps into a Lens File.

Lens File Asset Editor

The Lens File Asset Editor provides multiple calibration tools for automatically populating the Lens File with calibrated data. The editor also provides a curve editor from which you can adjust the computed results.

Calibration Steps

The calibration steps featured in Unreal Engine include a step for entering static lens information, lens distortion calibration, adjusting the image center, and nodal point offset calibration. The list of calibration steps is extensible, meaning programmers can implement additional calibration tools and add them into the editor.



You can input static lens data, such as the lens model name and serial number, as well as camera data, such as the dimensions of the image sensor. Using accurate lens information ensures an accurate calibration of lens distortion and camera intrinsics.

You can select the calibration algorithm that is used to compute distortion parameters and camera intrinsics. The plugin includes the following algorithms, which rely on OpenCV to calibrate the lens using a set of 3D-2D point correspondences:

Checkerboard: Uses a rigid checkerboard grid whose corners can be automatically detected.

Points Method: Uses any calibrator object with an identifiable calibration pattern, whose features must be manually clicked by the user

This step is extensible to let programmers implement additional algorithms by inheriting from the UCameraLensDistortionAlgo class.

You can manually adjust the location of the image center after you calibrate the lens. This can be useful when the interpolated image center between two calibrated focus or zoom points is not accurate, or when external factors, such as temperature, affect your camera lens slightly.

You can select the calibration algorithm and calibrator object that will be used to compute the nodal point offset. The plugin features the following algorithms:

Points Method: Using a tracked calibrator object with one or more identifiable features (such as an LED marker), you can position the calibrator at varying locations in view of their camera and click in the simulcam viewport to capture the current 3D and 2D location of the calibrator. After gathering a sufficient number of points, the nodal offset is estimated by minimizing the reprojection error of the captured points.

Aruco Markers: A specialization of the points method that uses image processing to capture the 2D positions of a tracked calibrator with a printed ArUco pattern on it.

Checkerboard: A specialization of the points method that uses image processing to capture the 2D positions of a tracked calibrator with a printed checkerboard pattern on it.

Optical Axis: Using a calibrator object, you can capture a small number of points at varying distances from the camera that all project to the exact center of the lens. The line between those points represents the optical axis, and the nodal point is found by manually moving the virtual camera along that axis until the entrance pupil position is found.

This step is extensible to let programmers implement additional algorithms by inheriting from the UCameraNodalOffsetAlgo class.

Viewport Settings

You can change what displays in the Lens File Asset Editor's viewport by modifying the Viewport Settings. Viewport Settings contains the following parameters:

Transparency: Slider to adjust the composite of the media and CG layers. 0.0 represents 100% media. 1.0 represents 100% CG.

Camera: The Virtual Camera Actor that is used to render the CG layer. To do any calibration steps, this camera must also have a Live Link Camera Subject driving its focus, iris, and zoom values, and have this Lens File Asset assigned to it.

Media Source: The Media Profile that is used to render the media layer.

Overlay: Options to apply an overlay on the viewport. You can choose None or Crosshair. You can also add your own custom overlay materials in the plugin's settings.



Distortion Pipeline

The Lens Distortion pipeline uses camera and lens data to create an accurate distortion effect that is applied to the final render.

There are three primary types of input data that can be used to model the distortion of a real-world lens:

A Live Link Lens source streaming per-frame distortion parameters and camera intrinsics.

A Live Link Camera source streaming camera FIZ to evaluate a Lens File asset.

The evaluation of a Lens File Asset using the current focus and zoom of the Camera Actor.

The underlying object that receives input data and produces the distortion state is called the lens distortion handler. Objects that feed the input data into a handler are referred to as producers of distortion data. Objects that receive the output displacement maps from the handler and apply them to an image are referred to as consumers of distortion data.

The lens distortion handler receives distortion parameters and camera intrinsics as input, and generates a distortion UV displacement map and a post-process material that references that displacement map. The displacement map resolution can be specified in the project settings, and can be relatively small compared to the final render resolution (e.g. 128 x 128).

Producers of Distortion Data

There are third party camera tracking vendors that provide calibrated lens distortion information in addition to basic camera position and orientation using their own protocols. This lens data, including distortion parameters and camera intrinsics, is streamed for each frame and can be used to compute distortion without the need of a Lens File asset. In order to stream this data into Unreal Engine, we provide a LiveLink Lens Role and Lens Controller.

The Lens Controller will instantiate a new lens distortion handler and stream the data it receives from the LiveLink source. The type of handler that is instantiated is dependent on the lens model, which must also be specified by the LiveLink source as static data.

For users who perform camera calibration within Unreal Engine, we have added a Lens File asset to the LiveLink Camera Controller. When a Lens File is present, the camera controller will evaluate that Lens File at the focus and zoom positions streamed through LiveLink. This evaluation interpolates between the closest calibrated points in the Lens File to generate distortion parameters, camera intrinsics, and nodal point offset for the current frame.

Alternatively, if the Lens File contains ST Maps, those will also be interpolated based on incoming focus and zoom streamed through LiveLink.

Some users may not stream live-camera data through LiveLink, so the pipeline also supports evaluating a Lens File using the virtual camera's current focus and zoom settings.

The Camera Calibration plugin introduces a Lens Distortion component that can be added to a CineCamera Actor. This component can evaluate a Lens File directly based on the current camera settings.

You can create a lens distortion handler object using Blueprints and drive its distortion state without the need to specify a Lens File. This workflow is not designed for compositing CG elements with live video, but could be used for CG-only projects in which a distortion look is preferred.

Consumers of Distortion Data

A Lens Distortion component can be added to a CineCamera Actor to receive distortion data from any producer in the scene.

You can select a distortion source from the component settings. When a distortion source is selected, a post-process material will automatically be added to the target camera component, which receives the distortion displacement map generated by the chosen distortion source.

Applying a distortion effect to a camera will not affect any Composure CG layers that may be targeting that camera.

You can specify a distortion source within the Composure CG layer settings. The list of available sources is populated based on the producers in the Level that are currently producing distortion data for the camera that the CG layer is targeting.

When a distortion source is selected, a post-process material will automatically be added to the CG layer's scene capture component. This material receives the distortion displacement map generated by the chosen distortion source. Note that the target camera must be a CineCamera Actor.

Applying a distortion effect to a CG layer will not affect the rendered output of the target camera.

Overscan

In order to properly distort a CG image, it is often the case that more input pixels are required than are available in the original undistorted render. In order to ensure that the distorted image has valid data at every pixel, we must overscan the undistorted render to produce a small amount of additional render from the scene.

The percentage of extra pixels needed in the overscan is computed by the lens distortion handler based on the current distortion state. The Oversan Factor is then used by the distortion consumers to augment the field of view (FOV) of the undistorted render before applying the post-process distortion material. This produces an undistorted image with a wider view of the scene, albeit at the same target image resolution as the original undistorted image.

An overscan multiplier can also be specified from any of the distortion producer settings, from which you can specify how much of the computed overscan should be applied (anywhere from 0x to 2x).

Undistortion

The lens distortion handlers compute an undistortion displacement map, which is accessible from Blueprints. This gives the ability to create custom post-process materials and apply them to reverse distortion from incoming media sources.

OpenCV

The Camera Lens Calibration tools use OpenCV for its algorithms. You can use OpenCV directly through the OpenCV plugin, which contains OpenCV version 4.5.4 and adds new Blueprint nodes, such as for ArUco marker tracking and chessboard tracking. Refer to the Blueprint API Reference for more details on the Blueprint nodes:

Blueprint API Reference for OpenCV Chessboard Functions

Blueprint API Reference for OpenCV ArUco Functions

Prerequisites

Step 1 - Creating a Lens File Asset

Step 2 - Calculating Lens Distortion with a Checkerboard

Step 3 - Confirming Lens Distortion

Step 4 - Creating a Tracked Object for Nodal Offset Calibration

Step 5 - Calculating Nodal Offset

In this Quick Start guide, you will go through the steps to calibrate lens distortion and the nodal point offset, using the Camera Calibration plugin.

This guide uses a production camera, an optical camera tracking system, and an AJA Kona 5 for source video input in the examples.

Prerequisites

You must set up the following in your project to complete the sections below:

Camera Calibration plugin enabled.

Camera tracking and focus, iris, zoom (FIZ) data streaming through Live Link. Specifically, your project must have a CineCamera Actor with a Live Link Component Controller that has a Live Link Virtual Subject with a Camera Role.

Source video input, such as AJA or Blackmagic.

A Media Profile added to your project and Media Sources configured.

(Optional) Timecode and genlock setup in the Media Profile if you're using a sync generator. Refer to Media Profile for how to set this up.

(Optional) Timed Data Monitor to evaluate sync and timecode.

Step 1 - Creating a Lens File Asset

The Lens File provides the calculation and storage of distortion and nodal offset data, specific to each lens-to-camera combination. We recommend you create a new Lens File if the lens, tracking object location, or the camera body changes. A new Lens File needs to be created for each lens-to-camera body combination.

Follow these steps to create a Lens File Asset in your project:

In the Content Browser, right-click to open the context menu and choose Miscellaneous > Lens File to create a new Lens File Asset.

Double-click your Lens File Asset to open the Lens File Asset Editor.

Under Viewport Settings:

Set Camera to the connected camera.

Set Media Source to your Media Profile.



Under Lens Information:

Add a Lens Model Name. A recommended naming convention combines the camera body name and the focal length.

Add the Lens Serial Number if available.

Add the Lens Model. Only spherical lens models are supported at this time.

Set Sensor Dimensions to match your camera.



Select your CineCamera Actor in the Outliner to open its Details panel.

In the Details panel, select the Live Link Controller Component to view its details.

Under Role Controllers > CAMERA ROLE > Camera Calibration > Lens File Picker, set Lens File to the Lens File Asset created in the previous section.

At the bottom of the Lens File Asset Editor you will find a summary of the current properties applied to the Lens File. Most of the properties show as blank or N/A at this stage. These properties will update as you continue with the calibration process.



Step 2 - Calculating Lens Distortion with a Checkerboard

This step shows how to calculate lens distortion with the common method of using a checkerboard. You can use a printed checkerboard mounted on a rigid surface and held in view of the production camera, or a checkerboard image displayed on a tablet. You'll create a CG checkerboard in UE to match the properties of the physical checkerboard.

Follow these steps to calculate lens distortion:

In the Toolbar, select Add Content and choose Virtual Production > Checkerboard to add a CameraCalibrationCheckerboard Actor to the level.



Select the CameraCalibrationCheckerboard Actor in the Outliner to open its Details panel. In the Details panel under Calibration:

Set Number of Corner Rows to the number of corners in one of your checkerboard's columns. In this example, the number of row corners is 7.

Set Number of Corner Columns** to the number of corners in one of your checkerboard's rows. In this example, the number of column corners is 11.

Set Square Side Length to the length of a square in your checkerboard in centimeters (cm). In this example, each square side is 4.5 cm.

Initially there aren't any materials assigned to the checkerboard. Set Odd Cube Material to a Material with the color of the top left square, and Even Cube Material to the color of the square next to it. In this example, the color of the first square is black, and the next square is white.



In the Lens File Asset Editor, switch to the Lens Distortion tab.

Set Lens Distortion Algo to Lens Distortion Checkerboard.

Set Checkerboard to the CameraCalibrationCheckerboard Actor you created.

Enable Show Detection. This will create a preview image each time an image is created for use in calculating lens distortion.

Place the checkerboard in front of the camera as shown below.



Click on the viewport to start the calibration process and create the first image to be used.



Move the checkerboard around the camera field of view and continue to click the image to capture more calibration pictures. Make sure to move the checkerboard's location enough times to cover the field of view with overlapping images, at different orientations, and different depths to increase the accuracy of the calibration.



After collecting enough overlapping images to at least cover the complete field of view, click Add To Lens Distortion Calibration.

The Distortion Parameters at the bottom of the window are updated.



Most lenses will have different distortion values at different focus distances. To make the most accurate Lens File for lens distortion, the process above should be repeated at different focus distances.

Step 3 - Confirming Lens Distortion

To check the lens distortion, you can use the Nodal Offset tab. In this case, the untracked CG checkerboard in your scene overlays the video feed so you can visually confirm whether the physical checkerboard and CG checkerboard line up.

Follow these steps to confirm your lens distortion:

Place the physical checkerboard in the field of view of the camera.

In the Lens File Asset Editor, switch to the Nodal Offset tab.

Set Nodal Offset Algo to Nodal Offset Checkerboard.

Set Checkerboard to your Checkerboard Actor.



Click the image to populate all the corner data from the calibration.

Click Apply To Calibrator. This moves the Checkerboard Actor to the camera to match the physical checkerboard.



Under Viewport Settings, set Transparency to 1 to verify the Checkerboard Actor matches the physical checkerboard in the camera viewport.



Step 4 - Creating a Tracked Object for Nodal Offset Calibration

The nodal offset accounts for the difference between the axis of the tracked camera and the axis of the actual nodal point of the lens / camera combination being calibrated. If the lens is changed or the tracking device on the camera is moved, a new nodal point offset will need to be calculated.

In order to calculate the nodal offset applied to the CineCamera Actor, you will need to create a physically tracked object and a CG model to match the tracked object.

In this example, the physical checkerboard that was used previously had tracking markers added to it. A CG model was created to match the tracked checkerboard and set up for optical tracking. The CG checkerboard is imported into UE for use in the next steps.

While using a checkerboard is common, you can create any tracked object and CG model to suit your needs. The process will include adding calibration points to your CG model. Your tracked object and CG model must match each other.

Follow the steps below to create a tracked object for nodal offset calibration:

In the Content Browser, right-click to open the context menu.

Under Create Basic Asset, choose Blueprint Class.

In the Pick Parent Class panel, select Actor.

Double-click the new Blueprint Class in the Content Browser to open it in the Blueprint Editor.

In the Components panel, click (+) Add Component and choose Static Mesh.

In the Details panel under Static Mesh, set Static Mesh to the CG model of your tracked object. In this example, the CG model is Checkerboard_mesh.

In the Components panel, click (+) Add Component and choose Calibration Point. In this example, the component is named Top_Left.

In the Viewport, place the Top_Left component on the top left point of the checkerboard, as seen below.



Duplicate the Top_Left component four times and name the new copies Bottom_Left, Bottom_Right, Top_Right, and Center.

Place those components in their corresponding locations on the checkerboard mesh.



Compile and Save the Blueprint.

Drag the Blueprint Class into your level.

In Live Link, add your tracker source for the checkerboard. In this example, Optitrack is used and the Subject is named Checkerboard. Refer to Live Link for steps on how to add tracker sources.

Select your Blueprint Class Actor in the Outliner to open its Details panel. In the Details panel:

Click (+) Add Component and choose Live Link Controller.

Select the Live Link Controller Component to view its details.

Under Live Link, set Subject Representation to your Live Link Subject for your Checkerboard tracker. In this example, the Live Link Subject is Checkerboard.



Step 5 - Calculating Nodal Offset

The nodal offset applies an offset to the CineCamera Actor to account for the actual nodal point of the lens being used on the physical camera.

The Camera Calibration plugin calculates the nodal offset by having the tracked object move to different positions in front of the physical production camera. In this example, the Checkerboard Actor has calibration points which are collected and used to calculate the nodal offset.

Follow these steps to calculate the nodal offset:

In the Lens File Asset Editor, switch to the Nodal Offset tab. Under Nodal Offset:

Set Nodal Offset Algo to Nodal Offset Points Method.

Set Calibrator to the Blueprint Class Actor created in the previous section.



Click on the checkerboard image in the viewport to match the location of each Calibration Point. For example, click the bottom right corner of the checkerboard to match the Bottom_Right Calibration Point. The Calibration Points update automatically as you click on the image.



Move the tracked checkerboard five to eight different positions in front of the camera and acquire a set of calibration points at each position.

Click Add To Nodal Offset Calibration.



Check that the nodal offset has been applied correctly by checking the Nodal Point Offset properties at the bottom of the editor.



Change the transparency from 0 to 0.5. The CG element of the tracked checkerboard should line up with the checkerboard in the live video.



Pan the tracked camera and move the tracked checkerboard. The CG version should stay correctly superimposed over the physical checkerboard in the live video feed.

If you did not set up a timecode and genlock, and adjusted synchronization using the Timed Data Monitor, there may be lag in the CG element as you move. When you stop moving the camera, the CG element will line up again.

Rendering to Multiple Displays with nDisplay

Getting Started

In-Camera VFX is an exciting new methodology for shooting real-time visual effects during a live action film shoot. This technique relies on a mixture of LED lighting, live camera tracking, and real-time rendering with off-axis projection to create a seamless integration between foreground actors and virtual backgrounds. Its primary goal is to remove the need for green screen compositing to produce final pixel results in camera.

Getting Started



A guide to aligning an optical tracking system to an LED wall using ArUco markers displayed on the LED wall.



Ways to improve your In-Camera VFX project for best results



How to calibrate the display of content on the LED wall for capture with a given camera.



Describes the in-camera VFX methodology for shooting real-time visual effects during a live action film shoot with an immersive LED volume



A guide to your first steps working with in-camera VFX in an LED Volume



Details on the hardware recommendations for an in-camera VFX setup with Unreal Engine



A reference guide for organizing your In-Camera VFX project's file structure in the Content Browser.



An overview of the In-Camera VFX Template



An overview of the In-Camera VFX Template



How to set up the In-Camera VFX Production Test sample, and explore the features, project structure, and settings used during production.

Goals

Objectives

1 - Required Setup

2 - Generating the ArUco markers

Section Results

3 - Calibrating your LED wall with the ArUco markers

Section Results

Goals

In this Quick Start guide, you will go through the steps to align an LED wall to your camera tracking with ArUco markers.

Objectives

Generate ArUco markers for your LED wall.

Preview the ArUco markers in the editor Viewport and the stage LED screens.

Use the ArUco markers to calibrate your LED wall.

1 - Required Setup

For this guide, you will use a production camera, an optical camera tracking system, and an AJA Kona 5 for source video input. In addition, you will need an existing LED wall configuration and a nDisplay Blueprint that matches your stage LED wall configuration. Follow the Rendering to Multiple Displays with nDisplay documentation to learn how to create your nDisplay Blueprint.

Before proceeding, follow the Camera Calibration for Production guide to make sure the lens distortion and nodal point offset of your camera are calibrated. This will create a Lens File Asset that will be used as part of the LED wall alignment with camera tracking.

The example in this guide is based on the Epic LA RnD stage LED wall setup.



Click image to expand.

2 - Generating the ArUco markers

Click Settings > Plugins to open the Plugins Menu.



Search for the LED Wall Calibration and the Live Link Over nDisplay plugins and enable them. Restart the editor.





In the Content Browser, search for your nDisplay stage actor Blueprint and double-click it to open it.





Click image to expand.

Select your first wall mesh from the Components panel and double-click the corresponding cluster from the Cluster panel. This will give you the selected display's resolution.



With the wall mesh selected, click + Add Component and search for and select Calibration Point. This will add a Calibration Point component as a child of your wall mesh.



Rename the Calibration point to ArUcoW1.



With the Calibration Point selected, go to the Details panel and scroll down to the Calibration section. Click Create ArUcos.



The ArUco Generation Options window will open.

Enter the Texture Width and Texture Height values that correspond to the wall viewport that ArUcos are being applied to.

Select the appropriate ArUco Dictionary from the list. In this example, the DICT_6x6_1000 dictionary is selected, which has 1000 unique ArUco symbols.

Enter the Marker ID that will be used as the starting ID for the ArUco markers that will be generated.

Enter the Place Modulus value. This value represents the number of LED panels that will be skipped when placing the ArUco markers. This is useful for working on a large LED wall, where you would use over 1000 unique ArUco symbols if they were to be placed on every LED panel. The default value is 2. Change this to 1 for smaller LED walls where one ArUco can be displayed on every panel. Using the default value of 2 will place an ArUco symbol on every second LED panel.

Click OK to generate the ArUco markers.



Select a location to save the texture and click OK. A confirmation window will appear that tells you which marker Id to start from for the next viewport. This will be remembered by UE, but can be adjusted in case you need to change the order. Click OK to confirm.





Select the Viewport to which the calibration point was applied in the Cluster tab.



Go to the Details panel on the right. Scroll down to the Texture Replacement section and select the generated texture as the Source Texture. Enable the Enable Viewport Texture Replacement checkbox.



Repeat steps 5 to 10 to add the ArUco markers to the remaining LED viewports.

In the Content Browser, double-click the nDisplay Blueprint to open it.



Click + Variable to create a new boolean variable and name it Replace_Viewport_Textures. Go to the Details panel and enable the Instance Editable checkbox.





Drag Replace_Viewport_Textures to the Event Graph and select Get Replace_Viewport_Textures to create a node.

Right-click in the Event Graph and search for and select Set Replace Texture Flag for All Viewports.

Connect the Event Tick node to the Set Replace Texture Flag for All Viewports node. Connect the Replace Viewport Textures node to the Replace pin of the Set Replace Texture Flag for All Viewports node.



Compile and Save the Blueprint.

To see the changes in the Preview Pane of the nDisplay Blueprint, select the nDisplay Blueprint and go to the Details panel. Scroll down to the Editor Preview section and enable the Replace Viewport Textures and Enable Editor Preview checkboxes. This will show the ArUco markers.







Click image to expand.

If you are using multiple render nodes, sync the project to the other computers now.

In the Outliner, select the nDisplay Blueprint and go to the Details panel. Scroll down to the Default tab and enable the Replace Viewport Textures checkbox. The ArUco markers will now appear on the LED wall.





Click image to expand.

To see the ArUco markers in the Editor Viewport, scroll down to the Editor Preview section and enable the Enable Editor Preview checkbox.





Click image to expand.

To check the alignment of the LED wall, it is helpful to see the points at the corners of the ArUco markers.

Select a Calibration Point that was created when the ArUcos were added.

Go to the Details panel and scroll down to the Calibration section. Enable the Visualize Points in Editor checkbox.

The Point Visualization Scale adjusts the scale of the markers on the mesh. The Visualization Shape dropdown changes the marker shapes between Cubes and Pyramids. Adjust these values to suit your needs.



Compile and Save the Blueprint.



In the Outliner window, select the nDisplay Blueprint and go to the Details panel. Scroll down to the Editor Preview section and enable the Enable Editor Preview checkbox.

This will allow the CG ArUcos to be displayed on the viewport mesh in the Lens file. Once the LED calibration is applied, the CG ArUcos will be overlaid on the live video feed from the camera that shows the ArUcos on the LED wall.



Place the tracked production camera and any other tracked objects under a Tracking Node. Parent the Tracking Node to the nDisplay Blueprint.

Section Results

You generated the ArUco markers and are now ready to use them as part of your Lens file to calibrate your LED wall.

3 - Calibrating your LED wall with the ArUco markers

In the Content Browser, double-click the Lens File that was created in the Camera Calibration for Production guide to open it. The Lens File should be attached to the camera under the LiveLinkController streaming the FIZ data.

Click the Nodal Offset tab.



Click image to expand.

Go to the Viewport Settings and set the Transparency to 0. This will turn off the CG overlay of the ArUco markers that are displayed in the Editor.



Go to the Nodal Offset section and set the Nodal Offset Algo to Nodal Offset ArUco markers

Set the Calibrator to the nDisplay Blueprint.

Enable the Show Detection checkbox. This will capture an image each time the Viewport is clicked and will be used to gather calibration points of the ArUco Markers.



Point the production camera at the LED wall that is displaying the ArUcos markers. You will now collect images of the ArUco markers across the LED wall. Click the mouse inside the viewport to capture an image. A preview of the captured image will be displayed. Click the OK button.



Click image to expand.

Repeat the previous step multiple times to capture several images across the LED wall. You will see the captured images displayed under the Nodal Offset section.

Once you have captured enough samples across the LED wall, click on Apply to Camera Parent button. This will offset the Tracking Origin previously created and the tracked production camera below it.

To check the alignment of the LED wall, set the Transparency to 0.5. This will show the CG ArUcos applied to the LED wall mesh overlaying the ArUcos on the physical LED wall. Both sets of ArUco markers should now be right on top of each other. If not, the virtual LED mesh does not match the physical LED mesh.

Section Results

You calibrated your stage LED wall using the ArUco markers.

Project Set Up

Performance Targets & Profiling

Asset Creation and LODs

Lighting and Rendering

On Stage

There are a number of challenges associated with building an environment that will be used for an in-camera VFX shoot. The two main concerns are:

Building assets that appear realistic on an LED wall.

Optimizing the environment for performance so it runs in real time.

Mitigating these issues requires close collaboration between the Art team and the Stage team. Many effects that may appear to be performant and practical when running Unreal Engine in a workstation environment will not be effective for an LED wall, and proper communication between teams can avert many issues that result from that difference.

Use this page as a reference for these topics as you develop your projects for In-Camera VFX. This page is not exhaustive, nor is it intended to act as a strict set of rules. You should always carefully consider the requirements and limitations of your project when trying to determine how to best improve performance.

Project Set Up

Ensure your project is set up properly for efficient workflows. Refer to the In-Camera VFX Production Test documentation for an example of our recommended project set up, then customize it as necessary for your project's requirements.

We recommend disabling the Virtual Reality and Mixed Reality plugins. This will reduce the resources required to run Unreal Engine, and, other than for Virtual Scouting and Live Link XR, they are of limited use for virtual production.

Ensure you define your Project Structure in the Content Browser. When producing multiple levels and environments it is strongly recommended you define a structure for Artists to use from the outset.

One suggested structure as used in the ICVFX Production Test is documented here:

In-Camera VFX Production Test

Performance Targets & Profiling

For real time applications of Unreal Engine, it's often the case that the in-editor performance is worse than in the shipping environment. However, for ICVFX purposes, your in-editor performance should be considerably better than your target framerate on stage.

nDisplay comes with additional performance costs due to the multiple views rendered in an ICVFX environment, and the additional steps taken during rendering to ensure sync. Likewise, hardware can vary from one stage to the next and on individual workstations building content, therefore these differences should be considered along with your performance target when authoring content.

For the ICVFX Production Test, assets were created on a Dual NVIDIA RTX 8000 and 128GB DDR5 RAM machine for an intended stage render node using Dual NVIDIA A6000s and 128GB DDR5 RAM.

To ensure sufficient performance, we targeted a frame rate between 48-72 frames-per-second (FPS) on Artist workstations when viewed in 4K full screen with the resolution scale in Windows set to 100%. This was used as a benchmark guideline. However, further testing was required on a target device off-stage. This device was running scenes in nDisplay with a viewport configuration that simulated the heaviest load anticipated for any on-stage device. Additionally, closer to production, the scenes were regularly tested on-stage using the anticipated hardware.

While the content of this page is focused on performance and profiling specifically for In-Camera VFX workflows, we recommend that you review the documentation for Testing and Optimization and specifically Unreal Insights for additional resources on improving performance in your project.

When preparing your scenes for the stage, consider the following:

While a 2-3x target frame rate approach can provide a rough guideline for Artists, do not assume it will be sufficient in all cases, as not all scenes scale the same. We strongly recommend you run performance tests on a regular basis and document the results. Performance is everyone's responsibility, and testing early and often means you're not surprised by bad performance when you're on set.

Always work towards a target FPS on content workstations that are comparable to the ICVFX stage render nodes.

It may not always be possible for all Artist workstations to be comparable, however it is essential to have access to at least one workstation that is readily available for profiling.

Scalability settings can be used to closely emulate the performance of the target hardware, however this is less accurate and should only be used as a rough guideline.

Conduct regular performance profiling on machines with the same specifications as those found on-stage, by running the scene in the same configuration as the most heavily tasked render node. This means a proper inner and outer frustum setup for a single node with the maximum resolution used on-stage.

When possible, work with the stage team to run performance tests on the stage itself. Don't leave testing until the last minute on a production or assume the stage team will optimize for performance.

Windows scaling can affect Engine performance:



Use Unreal Insights to generate nDisplay traces. Refer to this live stream for a full explanation of how to do so. GPU Profiling and CPU Profiling will also be helpful.

Asset Creation and LODs

Level of Detail: Use different levels of polygon counts for when a Mesh is rendered larger or smaller on the screen. LODs are based on the screen size.

Representations:

Use Hero representation for when an asset is extremely close to the camera.

Use Proxy representation for when an asset is further from the screen and the texture and poly detail isn't needed. One method is to build the hero geometry with complex shading and high-resolution textures, and then use a DCC app or the Proxy Mesh tool to create lower-resolution geometry and bake down the textures using a simplified shader.

If an asset needs to be both near and far from the camera at different points during the shoot, then use Levels of Detail (LODs) for flexibility.

Proxy meshes can be generated in-Editor for individual or clusters of background assets. Refer to the Proxy Geometry Overview documentation for more information.

Local clusters of the same Actor that share materials can be merged together with Merge Actors.

If a local cluster of Actors use different meshes and materials, you can use Merge Actors to merge the materials into a shared material asset that atlases the various textures to reduce draw calls. This is most useful for optimizing medium-distance assets as the atlasing can reduce the quality resulting in potentially smaller texture sizes. They can be used closer to the camera on a case-by-case basis when the drop in quality is not too noticeable.

You can use LODs and other performance-improving techniques with merged Actors.

Object culling can be an issue for performance. Large objects won't cull as easily, resulting in an impact on performance. This is less notable for static scenes, but if the LED volume moves throughout the environment then the culling of Large objects will be more important to consider. Due to this behavior, when merging meshes, don't merge too many Actors together, as creating large meshes will impact the ability to cull the merged mesh.

Automatic LODs can produce assets with a softer, indistinct look. We recommend you budget resources for some hand-crafted LODs.

You only need hand-authored LODs for level 1 and possibly level 2, as anything beyond that will be rendered too small on the screen for the details to be noticeable.

When possible, aim to get optimized versions approved by the Art Director, the Production Designer, or whoever else is signing off on the look, otherwise optimization may introduce noticeable visual differences and increase the budget and schedule of your project.

Optimize as you work, don't leave this process until the end, it will help receive and maintain Art Director approval if the project is always optimized, and will free additional system resources that can be used elsewhere for higher-quality or dynamic effects, such as volumetric fog or dynamic lighting.

Additionally, we recommend to always turn on all the high-quality and dynamic features you intend to use from the beginning, so you will have a consistent idea of what the performance costs are, how much remaining capacity you have to work with, and if you will need to adjust their quality using cvars.

Quad Overdraw can greatly increase performance cost. To minimize this impact, consider the following issues and optimizations:

Avoid using too much translucency, especially large translucent areas. Instead, we recommend using a Masked Material, due to the lower performance cost.

Avoid dense meshes. Models should be built for their appropriate screen size. Solid meshes in wire frame mode, or nearing a solid color might result in poor performance.

Normal maps should only be used for details. Do not use Normal maps for geometry.

Use the Quad Overdraw viewport mode to profile the scene. Any meshes rendered Green or worse should be avoided to keep Quad Overdraw costs down. The majority of the screen should be rendered a shade of blue.

It's important to understand how much of your mesh will render visible on the screen. In our experience, many teams don't properly consider how geometry will be used. For example, If a mountain only fills 100px x 100px on an LED wall, then that mountain doesn't need to consist of 2 million triangles.

The same optimization practices apply for textures. The GPU might not load an 8k texture until it's in the camera's direct view.

Reuse assets so the engine can instance them. Avoid using too many unique meshes, as this is less performant. Use the Statistics window to identify how many unique or rarely reused assets are in the scene. If you see a lot of 1's or 2's in the HWInstance column, then this should be addressed. There are some exceptions to this, as merging Actors or creating a proxy mesh will create a new unique Actor.

Reduce the number of Material IDs on a mesh as much as possible. Try to keep it at 1 material per asset. You can use the Merge Actors tool for this purpose. Each material ID adds draw calls, so to lower the cost of performance you want to keep draw calls to a minimum. Ideally, assets are prepped with the correct number of Material IDs on import.

Use Material Functions to group common features together to have maintainable materials without bloating.

Use Material Parameter Collections to simplify setting up materials.

Use master Materials when possible for easier mass changes. However, remember that master Materials with many switches will increase shader permutations, which will increase shader compile times. There's a balance between maintainability and compile times. Be mindful of any last-minute master material changes while on set, as a lot of materials may need to be recompiled.

Use more complex shading for assets closer to the camera. Use simpler shading for assets further away from the camera. Use static switches to avoid multiple master materials for different quality levels, and implement them using LODs. Then, instead of using a lot of complex nodes to compute an effect in a material when it is far away (being rendered small on the screen), we recommend you bake the output down to a texture to reduce the shader complexity, that is, the instruction count. You can refer to this live stream video on Baking Materials to Textures for more information.

High-resolution assets of 4k or 8k are almost always going to be a poor choice for both visuals and performance. When working with assets in real-time production, more is not always better. In most scenarios it will not be needed, and it consumes memory that can be used by other scene elements. Refer to the documentation on Level of Detail Texture Properties and how to use mipmapping with image sequences for more information.

For mipmapping and streaming reasons, textures need to be a power of 2 in both dimensions, however, they don't have to be perfect squares. They can be rectangular as long as both vertical and horizontal resolutions are a power of 2 respectively. For example, textures of 128x256 and 256x256 will function as intended, 8080x8080 will not.

Are you using decals? If not, disable Deferred Decals in the Project Settings.

Don't use video elements, use Flipbooks instead.

With ICVFX, you want to ensure that all the nodes rendering on the wall are synced. Due to how video elements are encoded, there is no method to properly synchronize them, to ensure that each machine is pointing to the same 'frame' of the video.

Using a texture Flipbook animated through a material parameter, or an EXR sequence being driven by a level sequence that is being played at the same time, are both good methods to have a synchronized animated sequence.

Lighting and Rendering

Efficient lighting: Avoid ray tracing or over-use of dynamic lights, as these forms of Lighting are expensive. Use more efficient alternatives such as light baking and other lower-performance-cost tools. When used with caution, dynamic lighting is a useful tool, but it should be applied sparingly.

If dynamic lighting is needed, consider disabling Cast Shadows to reduce performance impact.

Try to avoid relying on Light Functions and Rect Lights, both of which are expensive compared to cheaper techniques such as IES profiles and Spot Lights.

Consider setting up Precomputed Lighting Scenarios to allow for quick switching between different settings while on-set.

nDisplay costs: When setting up a complex scene, always keep in mind that using nDisplay adds an additional performance cost that exceeds the baseline costs for the scene itself. This can be a source of performance differences between a scene rendered in Unreal Engine on a workstation and a scene rendered on the LED walls for in-camera VFX shoots.

Ray Tracing is not Path Tracing. We sometimes encounter confusion about what ray tracing means in the context of real-time rendering in Unreal Engine. Because ray tracing is expensive in terms of performance, you can achieve better-looking and more stable image quality using baked lighting with volumetric light maps and reflection probes.

While ray tracing is required for GPU Lightmass to work, it does not require the additional ray tracing features that are enabled by default, such as ray-traced shadows, ambient occlusion, global illumination, and reflections. Instead, it's best to disable all of these features using the following console command:

Refer to the main GPU Lightmass Global Illumination documentation for more information.

It is possible to use other ray-tracing effects carefully, if your set up is powerful enough to handle them. For example, the In-Camera VFX Production Test made use of ray-traced shadows and ray-traced reflections.

When ray tracing is a requirement for your project, we recommend going through all master materials and optimizing them for the ray-traced scene using the RayTracingQualitySwitch. Additionally, we recommend reviewing all the ray tracing settings, such as samples, ray distance, bounces, and so on. Refer to the general Ray Tracing documentation for more information.

The Cinematic Engine Scalability quality setting is usually not needed, instead we recommend lowering all the quality settings so they are almost visually identical to cinematic, as this can save a significant amount of performance in your scenes.

Cinematic Engine Scalability automatically determines the values of a number of other settings, so you will have to set some of those manually when you use a lower setting.

At the start of a new project, go through all the Rendering settings in the Project Settings and enable or disable anything you require for the project. This will recompile all shaders, however, after setting up the Derived Data Cache you will not experience many issues with recompiling shaders.

Sometimes customers have raised concerns about baked lighting because they want to be able to change things quickly, so it is important to highlight the value of how to properly use both baked and dynamic lighting.

When using baked lighting, we recommend you keep your lightmap resolutions sensible. They don't need to be set to a 4096p resolution.

If you're not using baked lighting, then disable Allow Static Lighting in the Project Settings.

Volumetric Clouds and lighting effects are expensive. Be careful when relying on them. Consider baking volumetric clouds after the desired look is achieved.

Volumetric Fog is expensive for performance, therefore, we recommend you consider regular fog or shader tricks instead. If Volumetric Fog is needed, we recommend adjusting the quality. To optimize Volumetric Fog use the following CVars:

CVar Command

Description

r.VolumetricFog.GridPixelSize 8

8 is the default value, increase this for better performance, for example to 16. Be careful changing these values, as it can cause artifacts.

r.VolumetricFog.GridSizeZ 128

128 is the default value, decrease this for better performance, for example to 64. Be careful changing these values, as it can cause artifacts.

Lightmaps (CPU & GPU): Set up proper lightmaps. Refer to the Unwrapping UVs for Lightmaps documentation for more information.

Use caution when using lightmaps with large meshes, as the lightmap density will be diluted.

Complex meshes are difficult for the lightmap auto-generation algorithm to evaluate efficiently. Your resulting lightmap might have tiny UV triangles that don't receive any baked lighting info. Consider using manually generated lightmaps in such instances.

Overlapping Dynamic Lights: Be mindful of your light's radius and fall off, tweak these settings to reduce overlap and consider disabling Cast Shadows for small meshes. Overlaps can be previewed with the Light Complexity viewmode.

Dynamic Shadows: If dynamic shadows are required for your project, then ensure a balance between performance and visual quality. There are several methods to improve performance with only a minimal visual impact on quality.

Simplify shadows for complex meshes using Proxy Geometry Shadows.

When using Cascade Shadow Maps (CSM), you can reduce the Dynamic Shadow Distance and Num Dynamic Cascade Shadows settings for better performance.

Consider switching to Distance Field (DF) shadows or Far Shadow Cascade shadows. Because DF shadows are static, and Far Cascade shadows are only used for specific Actors, both are more performant than dynamic shadows.

You can tweak the settings of several additional console commands to improve performance.

r.ShadowQuality

r.Shadow.MaxResolution

r.Shadow.RadiusThreshold

r.Shadow.DistanceScale

r.Shadow.CSM.TransitionScale Refer to the Scalability Reference documentation for more information on how to use these commands.

On Stage

Have a 3D representation of the stage in the level, and ensure it is an empty flat ground plane. The stage area needs to be void of any CG assets, this includes grass or foliage, and be mindful of moving assets through the scene or particle emitters entering the volume. Having the stage is useful for development and level design so you can accurately build around the stage area. .

In theory, the LED wall volume shouldn't have any 3D assets for the shoot. In practice, you can have 3D assets inside the LED wall volume when shooting, but if that is the case then the practical floor or ceiling can't be in the frame as this will reveal that elements are at different depths. Carefully consider if you can make 3D assets on the stage work for your shoot.

Build dynamic controls using the Web Remote Control feature or into a Blueprint that can be controlled using a device such as an iPad or Tablet while on set.

Direct sun lighting is difficult to emulate on a stage, therefore we recommend you consider placing the stage in some kind of shaded space if outdoors.

Take into account the camera location and distance on stage. You don't need to render everything at cinematic quality, just what the camera view can see.

Consider whether the scene is a static set extension, or if you plan to include dynamic content for movement or animation in the background. A dynamic background is more expensive to render in high quality in real time.

Overview

Color Pipeline for In-Camera VFX

Details of OCIO conversion

Scene Exposure

Camera Calibration Matrix

Display a Scene Linear Chart

Linearize Footage for the Vendor

Matrix Creation Math

Place Calibration Matrix in OCIO Conversion

Calibration Verification

Overview

This document covers the steps to calibrate the display of content on the LED wall for capture with a given camera. The steps that are covered in more detail below are:

Display a chart with known RGB values in UE using emissive unlit texture in the scene.

Turn off all camera-related parameters, and ensure OpenColorIO (OCIO) only has PQ encoding.

Set Brompton to receive PQ encoded RGB signal and interpret it as PQ Achievable, and also set wall reproduction to Achievable.

Capture footage of the wall with the camera.

During the calibration step, set the white balance of the camera to 6500, and set the exposure to a value that comfortably captures the bright white patch on the wall.

Linearize camera footage using standard methods, then converted from camera encoding color space to UE camera verification color space (used below).

Find a matrix from known RGB to linearized verification space RGB. Invert that matrix to produce a camera calibration matrix.

Display the chart again in UE. Note that it is now presumed to be in working color space.

Set the OCIO source to a working color space, and set the destination to a space that contains three steps:

Matrix conversion from reference to camera verification space.

Calculated camera calibration matrix application.

Linear to PQ encoding.

Capture the chart again, and linearize footage to working color space. Compare the chart to the linearized footage. Preferably, this should be done analytically by means of the linear content, but could also be done by eye with the same look lut applied to both.

Color Pipeline for In-Camera VFX

The outline above sketches the steps used to calibrate for a camera/LED wall combination. This brief preface is provided to describe the proper setup for a color pipeline from UE to LED processor.

The Working Color Space of Unreal Engine is not explicit. It is implicitly Linear Rec709 (also called Linear sRGB). This means the encoding is linear, and the color space is Rec709 primaries and white point. It is possible to provide textures and materials in another color space, which implies to the engine that the Working Color Space is something other than Rec709. A common alternative space is ACEScg, which is used by many VFX studios.

The important point is that the virtual scene is linear, and that the goal is for those linear values to be represented on the LED wall. To do this, portions of the post-processing chain should be disabled (or set to 0) to ensure that none of the normal UE "camera effects" are applied to the virtual content.

The Bloom Intensity and Vignette Intensity should be set to 0.0, as these effects are typically not desirable on the output to the LED wall. Additionally, you should set the Expand Gamut amount to 0.0 as well as the Tone Curve amount. It should be noted that the Tone Curve amount will automatically be set to zero when OCIO is active, but Expand Gamut is under user control.

The OCIO conversion requires an OCIO Configuration Asset which refers to your local OCIO config file. Additionally, this Asset has an allowlist of colorspaces from the OCIO config that are then available for use by UE. See this page for more info on how to associate a particular Source and Destination colorspace with a nDisplay output viewport.

OCIO conversion from linear to signal value.

Source color space: Linear Working Color Space

This converts from the Source space to OCIO Reference space.

Destination color space: PQ encoded Signal Color Space

This converts from the OCIO Reference space to the Destination space.

Convert from OCIO Reference to Linear Camera Calibration Color Space.

Camera calibration matrix

Linear to PQ conversion

While it is possible to use Post Process Materials (PPMs) After Tonemapping when OCIO is active, they will be operating on encoded data. This can give unexpected results, because all values that are available to the PPM are in the output signal color space and color encoding.

If you need to alter the scene using a PPM, it is preferable to use it Before Tonemapping. This will ensure that the material is operating on linear values. If, for example, you wanted to provide your own color correction controls, this would be a suitable place for those operations.

Details of OCIO conversion

The purpose of the OCIO conversion is to convert from the Working Color Space of UE to the Output Signal for the LED processor.

The camera calibration steps below presume a particular color space to determine that the calibration matches the target. We will call this Camera Calibration Color Space. It is possible that it is the same as the Working Color Space, but for flexibility it is called out separately here.

In the config.ocio file, the target space of PQ Encoded Signal Color Space involves three specific steps:

First, there is conversion from the OCIO Reference space to the Linear Camera Calibration Color Space.

Second, the camera calibration matrix is applied, which converts from the Linear Camera Calibration Color Space to Linear Signal Color Space. It should be noted that the Signal Color Space is not defined using primaries, but rather through the calibration process.

The third step is the encoding from Linear to PQ.

To set up the sequence of steps, a few individual OCIO color spaces need to be defined. One is the Linear Camera Calibration Color Space, which in the example below is Linear sRGB (also called Linear Rec709) and is simply named "Gamut sRGB". Another required conversion is the simple straightforward conversion from Linear to PQ. This conversion assumes that a linear value of 1.0 has a nit value of 100, which is then followed by the standard 0-10000 conversion to a 0-1 encoded value.

The OCIO Linear Reference space is the same as the Linear Camera Calibration space in this example, so there is no color conversion needed in the Gamut sRGB space.

The actual target color space is the conversion to the Encoded Signal Color Space, as shown here. The conversion includes a Color Matrix followed by an encoding from Linear to PQ. The derivation of this Color Matrix is described later. The values in the Matrix Transform below are only shown as an example; these values must be replaced by the calibration done for your particular LEDs and camera.

Scene Exposure

Because the linear values are encoded as PQ and the values are interpreted in a canonical 0-10000 nit range, the exposure of the scene must be adjusted before the OCIO conversion. This can be done by means of the Exposure control in the CineCamera or PostProcess Volumes. The important note here is to make a correspondence between the virtual scene luminances and the eventual brightness on the LED wall.

Typically, a linear scene contains HDR values. While the majority of scene values will hover around a 100 nits luminance value, portions can be much brighter, with some pixels attempting to be 2000 or 3000 nits. For most LED walls, these brightnesses are beyond the capability of the LED panels. The result on the wall will be the same bright value for pixels that may be different in the scene, because the peak presentable value on the LEDs is likely to be 1500-1800 nits. For example, if the peak brightness of LEDs is 1600 nits, that would correspond to a scene linear value of 16.0 after the exposure compensation.

Camera Calibration Matrix

The purpose of the camera calibration matrix is to ensure that there is a match between virtual scene linear colors and the colors produced from linearization of the camera footage.

For background, it should be noted that a camera has a unique set of spectral responses, and those differ by brand of camera, and also are different from the human eye. Because LEDs have a rather narrow spectral distribution, the subtle differences in camera responses can cause photographed LEDs to appear different in the resulting footage of different cameras. To reduce this issue, we desire to change the pixels on the LED wall slightly so that the linearized footage from any particular camera will match the values that were represented in the scene.

To create the matrix, a minimum of four color values must be displayed by UE. Those four values are red, green, blue, and white patches, where the resulting pixels on the wall are captured by the camera. For this to work properly, the LED processor should be set up to produce native color on the wall. In the case of Brompton processors, this is called Achievable. Other vendors may call this Native. The goal of using this color space is that the calibration attempts to use the full capability of the wall, without clipping the color values. Additionally, the color encoding should be set to be the same color encoding that will be used for eventual shooting. For our Brompton setup, we used the PQ encoding.

In actual practice, we used more patches to confirm that the overall behavior is as expected. But the calibration calculation only requires four patches.

The following is the basic method to create a camera calibration matrix. Note that there are concerns and possible issues that are discussed later.

Display a Scene Linear Chart

Display a scene linear chart in UE using a geometric plane object, and a shader that displays the patch values in Unlit mode. The values can be pulled from a known texture file or from math within the plane's shader Material.

The chart should contain a red, green, blue, and white patch that have known scene brightness values. The simplest example would be (1.0, 0.0, 0.0) for red, and similar values for the other patches. By adjusting UE Exposure, the chart should be displayed to have a particular target brightness on the LED wall. The brightness should approach the peak value of the wall, but should be slightly below peak to avoid any color shift that occurs due to clipping.

The chart should be large enough to comfortably allow sampling of each patch in the resulting footage, but should also be centered and small enough to avoid regions of falloff that occur due to lens vignette.

The OCIO conversion should be enabled when the charts are displayed. The conversion used should be similar to the eventual goal conversion, but would only be the conversion from Linear to PQ (without a calibration matrix, since we are creating that with this step).

Linearize Footage for the Vendor

The footage should be linearized using standard methods for the particular vendor. For example, for a Sony Venice, the footage should be linearized using the Sony XOCN F55 ST codec. The data is SLog3 encoded in the SGamut3-Cine color space. For our simple example, we linearized to Rec709 Gamut using the Read node in Nuke12.

It is important to note which method is used to linearize the footage, and to verify that the result is truly linear. In our example, we linearized to Rec709. This term can be misleading, however, because many users speak about a Rec709 camera output which normally has a look lut applied to the content. For this calibration purpose, our goal is to capture in native camera format with no look applied, and to convert that to linear using standard methods.

The white patch should be mostly neutral, assuming the camera was set to 6500K white balance. If the white patch is heavily tinted there may be issues that need to be resolved before proceeding.

Matrix Creation Math

The next segment is the math for how the matrix is created from the sample data for R,G,B,W.

First, a 3x3 matrix is made from the red, green, and blue patch samples:













RR

GR

BR

F

=

RG

GG

BG

RB

GB

BB



I = F-1



Using the inverse of that matrix, multiply it by the white sample, where the highest value has been normalized to 1.0:



S = I × W/max(WRGB)



Use the calculated scale factors to scale the F matrix, then calculate its inverse.













SR

0

0

F

=

0

SG

0

x

F

0

0

SB



CalibrationMX = F-1



Place Calibration Matrix in OCIO Conversion

The resulting calibration matrix should be placed in the OCIO conversion for the wall/camera combination as was shown earlier. It should be noted that the matrix is presented as nine numbers in order such that the first row of the matrix is given, then the second, then the third row.

In the example above, the OCIO Reference Color Space was Rec709. This matched the color space used for linearization during calibration. If you choose to use a different OCIO Reference Color Space, the Calibration Matrix must include a conversion from the Reference Color Space to the Rec709 space used for linearization of the camera footage. This was noted in the outline above as "Matrix conversion from reference to camera verification space".

Calibration Verification

It is useful to confirm that the camera calibration matrix is active and behaving properly. To do this, display known patches using the same method as was used for the initial capture, except the color space target should include the newly created calibration matrix.

The goal is that the known patch values in scene linear space match the values found in the footage after linearization back to the same working space.

Earlier, the required patches were simply R, G, B, and W. For verification, it is helpful to include values that are at known locations between 0 and 1. This image shows a 5x5x5 collection of patches that are separated by 0.25, resulting in an even spacing of samples in linear space.



The reason to include more samples than just RGBW is that the linearized footage of this image will help confirm whether you have clipping due to brightness (or other such concerns).

In-Camera VFX Quick Start

In-Camera VFX Recommended Hardware

Rendering to Multiple Displays with nDisplay

Multi-User Editing in Unreal Engine

Level Snapshot

Live Link

Real-Time Compositing with Composure

Professional Video I/O

In-Camera VFX Template

In-Camera VFX Production Test

LED Panels

Hardware

Camera Tracking

Live Link

Camera Calibration

Timecode and Genlock for In-Camera VFX

Multi-User Editing for In-Camera VFX

Live Compositing

Remote Control for In-Camera VFX

Color Considerations

OpenColorIO

Stage Monitor

Timed Data Monitor

Level Snapshots

In-Camera VFX Example Project and Template

In-Camera VFX Production Test

In-Camera VFX is an exciting new methodology for shooting real-time visual effects during a live action film shoot. This technique relies on a mixture of LED lighting, live camera tracking, and real-time rendering with off-axis projection to create a seamless integration between foreground actors and virtual backgrounds. Its primary goal is to remove the need for green screen compositing to produce final pixel results in camera. One of the challenges of producing high- quality, real-time visual effects is synchronizing the technology to execute everything simultaneously.

Unreal Engine supports this technique through multiple systems such as nDisplay, Live Link, Multi-User Editing, and Remote Control. This documentation covers the features needed for this workflow, and what to consider when creating your set for an in-camera VFX shoot.



A set employing in-camera VFX within a LED volume. The arrows mark the camera's inner frustum, which is rendered from the camera's perspective.

The image above shows a set employing in-camera VFX within an immersive LED volume. The picture-in-picture indicated on the main LED wall shows the camera view, called the inner frustum render of the camera. This inner frustum represents the field of view (FOV) from the camera's perspective based on the current lens focal length. The image shown in the inner frustum tracks with the physical camera as the camera moves within the scene, always displaying what the virtual equivalent of the camera should be seeing in the Unreal Engine environment. When viewed through the real world camera, the system creates a parallax effect that gives the impression of shooting at a real world location, utilizing the full virtual 3D world as opposed to using a flat background plate.

Content displayed on the LED volume outside of the camera's FOV is called the outer frustum. This outer frustum turns the LED panels into a dynamic light and reflection source for the physical set because they surround the set with the virtual world and illuminate it as if it were a real world location. The outer frustum remains static when the camera moves. This mimics how lights and reflections do not move with the camera in the real world. Each shot setup can be placed at the desired location within the Unreal Engine environment and dictate what the outer frustum renders to light the scene on stage.

LED Panels

The LED stage design and its intended use is integral to the in-camera VFX setup. The number of panels in an LED volume that are needed and how they are laid out drives the rest of the hardware setup. LED panels can be placed in an arc pattern around the actor to provide better ambient lighting and reflections. It is also useful for providing an LED ceiling to contribute to the ambient lighting and reflections on the overall scene. Productions that intend to create a fully virtual environment may require at least a 270-degree enclosed volume to achieve accurate set lighting and reflections. If a substantial part of the set is a physical build, and the virtual world is only needed for a portion of the set, such as for set windows, then a one-sided or curved wall can be considered. Other factors, including production budget, physical space constraints, and, in some cases, the availability of panels from the manufacturer, may also impact the LED stage design.



An LED Volume is made up of an array of cabinets that can be arranged in any configuration. This image shows the back of an LED volume.

An LED volume is made up of a cluster of cabinets. Each cabinet has a fixed resolution that can range from a very low resolution, such as 92x92 pixels that can be used for outdoor signs, to 400x450 pixels for ultra-high-resolution indoor displays. The physical size of each cabinet can vary from manufacturer to manufacturer.

The LED processor is the hardware and software that combines multiple cabinets into an array that displays a single image. You can arrange the cabinets in any configuration inside the canvas that the LED processor drives. On a large LED stage, there could be ten or more LED processors driving a seamless LED wall.

Pixel pitch describes the density of the pixels in a cabinet and correlates with its overall resolution. The pixel pitch is typically described in millimeters and represents the distance between each LED light. The closer the LEDs are together—the lower the pitch—the higher the pixel density. A higher pixel density means a noticeable increase in resolution and quality—and higher cost for each cabinet.

A cabinet with a lower pixel pitch does not ensure it will be the correct product for your production, as other factors, such as viewing angle, color shift, color consistency, and heat dissipation, must also be considered. You can consult a professional LED systems integrator to determine the best product for your production.



You can see the optical artifact, the moiré pattern, appearing on the LED wall in the left side of this image.

The combination of the distance from the screen, pixel pitch, and camera sensor size will help you determine how far away you should shoot your subject from the LED wall without seeing any visible artifacts. One visual artifact that is present when shooting on LEDs is the moiré pattern. A moiré pattern is a common optical artifact that appears when the display system and camera sensor pixels are slightly offset. Moiré patterns can appear when the camera's focus plane aligns with the LED panels in 3D space. It is recommended to have the camera's focus placed either in front or behind the LED surface so that the image is slightly out of focus. Moiré patterns can also appear more commonly at severe angles to the LED surface. Try to maintain a perpendicular angle of the camera to the LED's surface where possible.

Hardware



An example hardware layout with three render nodes. Click image for full size.

In-Camera VFX can require a complex network of connected devices with various functions on a film set. The diagram shows an example hardware layout for a set with three LED panels. The table below explains the roles of the various machines in the setup. For details on specific hardware to consider for your in-camera VFX production, see In-Camera VFX Recommended Hardware.

Device

Description

Master Clock

The Master Clock is the heartbeat of the system. It ensures that all devices that receive or record data are in sync throughout the shoot.

Network

It is highly recommended to have a protected LAN with high throughput for all the machines.

nDisplay Render Nodes

Each render node drives a part of the LED volume. This means each node requires an NVIDIA GPU along with an NVIDIA Quadro II Sync card.

UE Primary

This station is the primary operator workstation where stage setup is typically configured. It also runs additional applications for launching the nDisplay cluster, the Remote Control Web Application, and the Multi-User server.

UE Editor—(Tech Art)

This workstation is in the Multi-User session for an artist to make creative real-time scene adjustments while a more stage-oriented operator keeps things running on the primary machine.

UE Record

This workstation records the camera, lights, and prop changes during the shoot using Take Recorder.

UE Composite

This workstation renders live composites in Composure. It is optional for the setup.

UE VR Scouting

This workstation has a VR headset and scouts the environment during a shoot. This can be useful on set both during the film shoot and separately.

Perforce Proxy

The Perforce Proxy is an on-site fast connection to the outside Perforce server.

Remote Control Web App

This is a web app written with HTML, CSS, and JavaScript frameworks that can remotely control the scene from a tablet or device with a web browser.

Camera Tracking

Camera tracking can involve optical, feature, or mechanical tracking to derive the camera's 3D position. This setup can include a small PC or server provided by the tracking company.

Camera

This is the Digital Cinema Camera on set and can be paired with the camera-tracking system.

Video Village

This is the center for video playback and review.

Camera Tracking



Camera tracking is needed to relay the position and movement of the camera from the real world to the virtual world. With this technology, the correct perspective of the production camera is rendered relative to the virtual environment. There are several different methods available for camera tracking with in-camera VFX.

Some of the most common methods for camera tracking include:

Optical Tracking: Optical tracking systems leverage specialized IR-sensitive cameras to track either reflective or active IR markers, in order to determine the location of the production camera.

Feature Tracking: Instead of tracking the custom markers that optical tracking systems use, feature tracking involves identifying specific image patterns of real-world objects as the tracking source.

Inertial Tracking: Inertial Measurement Units (IMUs) contain a gyroscope and accelerometer to determine the position and orientation of the camera. IMUs are frequently used with both optical and feature-tracking systems.

Using multiple sources for measuring the camera position and orientation, such as optical tracking combined with inertial tracking, is recommended for in-camera VFX. Multiple sources can enhance the overall camera-tracking data compared to using any single technique.

Live Link

Live Link is a framework in the Unreal Engine for ingesting live data, including cameras, lights, transforms, and basic properties. For in-camera VFX, Live Link plays a critical role in distributing the tracked camera information and can be enabled to work with nDisplay to carry the tracking information to each cluster node. Unreal Engine supports many camera-tracking partners through Live Link, such as Vicon, Stype, Mo-Sys, and Ncam, as well as several other professional tracking solutions. For more information, see Live Link Plugin.

Camera Calibration

Creating accurate compositions from CG renders and live video requires a virtual camera in Unreal Engine that accurately simulates the physical camera used to capture the real-world video footage. The virtual camera's position and orientation must closely match that of the physical camera, and its tracking information must match the video feed's exact timing to ensure each video frame is accurately synced to the position of the camera for each moment in time.

The Camera Calibration plugin provides users with simplified tools and workflows to calibrate a camera and lens in the Editor. This calibration process generates the data necessary to accurately align the virtual camera with the physical camera's position in space, and to model the lens distortion of the physical camera. The plugin introduces the Lens File asset type which encapsulates all of the calibration data for the camera and lens.

The Camera Calibration plugin also includes a robust lens-distortion pipeline that takes the calibrated distortion data and applies an accurate post-process effect to the CG render. The distortion post-process effect can be applied directly to a Cinecamera Actor, which can be used in Movie Render Queue, or to the CG layers of Composure.

The plugin's tools and framework are extensible and flexible to support a wide range of lenses and workflows.

For more information, refer to Camera Calibration.

Timecode and Genlock for In-Camera VFX

On an in-camera VFX film set, it is very important to have highly accurate synchronization between all devices. Each device, such as the camera, computers, and tracking systems, has an internal clock. Even though two devices may be exactly the same, their internal clocks will not be in sync with each other. This can cause problems in the resulting display, such as tearing, if they are not unified. Genlocking with nDisplay prevents these issues. For more information on synchronization and genlock in nDisplay, see Synchronization in nDisplay.

In addition to synchronizing the displays, the engines' timecode and frame generation need to match the input from the camera. See Timecode and Genlock for steps on how to sync the timecode and genlock the engine between all the devices.

When constructing an environment for in-camera VFX, it is important to note that nDisplay has certain limitations that need to be taken into consideration. Screen spaced effects such as SSGI, SSAO, SSR, vignetting, eye-adaptation, and bloom should be avoided. Since the nature of these effects are screen spaced, there can be issues with borders between two clustered nodes in the nDisplay system.

Multi-User Editing for In-Camera VFX



The left image is the view from a machine dedicated to VR Scouting in a Multi-User session. The right image shows the LED wall displaying the camera's perspective and the representation of the user VR Scouting.

The Multi-User Editing system enables robust collaboration to support any type of change. The primary operator machine is in charge of scene modifications and updates the nDisplay render machines live. You can have multiple operator machines in the same Multi-User session that can perform different tasks and modify the scene in real-time. Examples of machines are ones dedicated to VR Scouting and live compositing with Composure. One machine runs the Multi-User server, and all others machines connect to the server. Any scene changes from these machines are then sent as transactions from the server to all the other machines. Conceptually, any action that can be undone in the engine is transacted and sent through the Multi-User server.

For information on adding Multi-User Editing to your project, follow the instructions in Getting Started with Multi-User Editing. When automatic server discovery is not possible in your network, follow the steps in Advanced Multi-User Networking.

Live Compositing



A set with the green screen visible only in the camera's view. The outer frustum still displays the renders from the Unreal Engine environment for lighting and reflections.

For shots that can't quite be achieved as in-camera finals, the system provides a fallback option. The inner frustum can be easily changed to a green screen with adjustable tracking markers. The outer frustum can continue to display renders from the Unreal Engine environment.



Since this set used the LED walls in the outer frustum for ambient lighting and reflections, you can see the real world reflections visible in both the motorcycle and the actor's glasses even though the background in the final shot is composited.

Using a green screen only in the camera's FOV minimizes the amount of green screen required for a given shot. Less green screen means less green spilling onto the actors and set. Continuing to display renders from the Unreal Engine environment on the outer frustum allows the production to still take advantage of the real world lighting and reflection capabilities of in-camera VFX. Both contribute to improved green-screen elements for compositing.

Green-screen shots also benefit from live compositing, which allows filmmakers and performers to get a fuller sense for what the final shot is going to be as opposed to the classic sea of green. These comps can also be very valuable as preview shots for editorial.

Composure is Unreal Engine's framework for real-time compositing. With this suite of features, you can include live video feeds, AR compositing, green-screen keying, garbage mattes, color correction, and lens distortion in your shots. Composure is a flexible system where you can extend and create your own material effects. For more, see Composure.

Remote Control for In-Camera VFX

Since there can be so many machines involved in an in-camera VFX shoot, controlling the scene in real time from a web app can be useful on set. For example, you can change the color correction, lighting, and virtual actor positions from the web app. Included in the In-Camera VFX Example Project is a sample Remote Control Preset and Web Application to show how you can incorporate this technology into your production workflow. In addition to using the Remote Control Presets, you can also use the UI builder to customize the controls to suit your project's requirements. For more information about Remote Control in Unreal Engine, refer to Remote Control.



A remote control can be helpful on set to adjust the scene for the shot. In this set, a web app was used to change the sky during the shoot.

Color Considerations

Ensuring color consistency between shots is important during an in-camera VFX shoot. It is good practice to verify the final image by looking through the live action camera, and to test with the LED panels displaying the outer frustum as a light source.

Follow these best practices to ensure consistency between shots:

All cameras do not produce the same outputs. Using different cameras between shots can cause the color in the resulting captures to be different. Avoid this by using the same cameras throughout a film shoot with a LED volume.

Test live action assets on stage with the visuals on the LED volume as a light source. Light from the LED panels can have a different effect on stage elements from other lights.

Ensure that the tonemapper is disabled so content from the engine does not have a tone curve and is in linear sRGB color space as input to the LED panels. The tonemapper can be disabled using the console command ShowFlag.Tonemapper 0.

OpenColorIO

OpenColorIO, or OCIO, is a color management system used primarily in film and virtual production. OCIO guarantees that the colors of captured video remain consistent through the entire film pipeline. This pipeline includes from initial camera capture, through all the compositing applications that need to work with the captured media, all the way to the final render.

OCIO is available as a plugin in Unreal Engine. When the plugin is enabled, you can apply OCIO profiles to the Editor, or to individual displays with nDisplay. Refer to Color Management in nDisplay for more information.

Stage Monitor

When operating a stage in a live environment, multiple machines running instances of Unreal Engine 4 work in tandem and rely on each other. Operators may use some instances to render on a LED wall, some could be used to modify the scene in the Editor, and others may be used for compositing. With Stage Monitor, you can receive reports of different events from all these instances of UE4 and be able to troubleshoot any issues in the setup.

For more information, refer to Stage Monitor.

Timed Data Monitor

Unreal Engine can ingest a variety of data types from multiple sources at the same time. For example, in Virtual Production, the engine can receive captured frames from the camera on SDI as well as the position and orientation of the camera from the tracking system through Live Link. The Timed Data Monitor is a solution to configure and visualize how all this incoming timed data relates to each other and the engine's time.

For more information, refer to Timed Data Monitor.

Level Snapshots

Level Snapshots enable you to save a particular configuration of the Actors in the World Outliner of your Level and instantly restore your scene to that state. This can dramatically streamline complex setups and avoid duplication and management of multiple variations of the same Level for different scenarios. Level Snapshots are especially useful for Virtual Production, as they enable users to reset virtual environments to their starting position between takes as well as track per-shot changes that may occur during a shoot while preserving the base starting point of the Level.

You'll want to use a combination of Source Control and Level Snapshots to version both the Assets and Actors in your project. For more details on how to use Level Snapshots, see Level Snapshots.

In-Camera VFX Example Project and Template

This page provided an overview of the technologies and hardware needed for in-camera VFX. To become more familiar with the workflow, the In-Camera VFX Example project is available with a sample scene and a base level to start your in-camera VFX project with. See the In-Camera VFX Quick Start for steps on how to modify the example project for a different LED volume and run the necessary programs on all the machines. If you are aleady familiar with using In-Camera VFX, the In-Camera VFX Template provides a basic set-up with all the tools and assets to create a project from the beginning.

In-Camera VFX Production Test

The In-Camera VFX Production Test is a Virtual Production sample available in the Unreal marketplace that uses Unreal Engine and an LED Volume to feature traveling vehicle shots, multi-camera setups, and multi-user setup for making quick changes between takes. This sample was created in collaboration with filmmakers' collective Bullitt. The team produced final pixels in-camera over four days on NantStudios' LED stage in Los Angeles.

For more information on the production and the technologie used, refer to In-Camera VFX Production Test.

In-Camera VFX Overview

In-Camera VFX Recommended Hardware

Rendering to Multiple Displays with nDisplay

Multi-User Editing in Unreal Engine

In-Camera VFX Production Test

Live Link

Level Snapshot

Real-Time Compositing with Composure

Professional Video I/O

Step 1 - Set up Your Project for In-Camera VFX

Step 2 - Create LED Panel Geometry

Step 3 - Define the LED Screens in Your Project

Step 4 - Launch Your Project with Switchboard

Step 5 - Join Multi-User Session

Step 6 - Use Live Link for Camera Tracking

Step 7 - Enable Green Screen and Chroma Key

Step 8 - Add Light Cards

Step 9 - Shoot with Multi-Frustum

Step 10 - Apply OpenColorIO Configuration

Step 11 - Control the Scene Remotely

Step 12 - On Your Own

This Quick Start page shows the process of setting up a project in Unreal Engine to work with in-camera VFX. At the end of this guide, you will:

Have a synchronized cluster of nDisplay nodes.

Have an inner and outer frustum for in-camera VFX.

Have a real-time camera tracking system integrated via Live Link XR.

Have a green screen inner frustum with chroma key markers that can be toggled on.

Be able to launch all clustered nodes and test on set.

Step 1 - Set up Your Project for In-Camera VFX

The easiest way to set up an in-camera VFX project is to use the In-Camera VFX Example project.

Open the Epic Games Launcher.

In the Learn tab, find the In-Camera VFX Example project.

On the project page, click Free.

Click Create Project.

Specify the location on your machine to save the project and select Create.

Launch Unreal Engine and open the In-Camera VFX Example project.

In the example project, under Content > Maps, there are two levels, Main and EmptyStage. For learning about in-camera VFX with Unreal Engine, open the Main level. For starting with a clean setup, use EmptyStage as the base for your project. The example project and levels automatically enable the necessary plugins, provide helpful blueprints, configure additional settings, and include sample configuration files.

Plugins

Aja or Blackmagic Media Player: Provides support for SDI capture cards.

Camera Calibration A tool for creating lens distortion profiles and nodal offsets.

Color Correct Regions: Color correction and shading constrained to a volume.

ICVFX: A plugin that enables a base suite of in-camera VFX plugins.

Level Snapshots: Store alternative layouts for convenient, non-destructive variations of the current level with filtering abilities.

Live Link: Unreal Engine's API for ingesting live data, such as motion capture and camera tracking.

Live Link Over nDisplay: The primary node receives Live Link data and redistributes the tracking data in an efficient and synchronized manner.

Live Link XR: Unreal Engine's API for ingesting live data from XR devices, such as Vive Trackers.

Multi-User Editing: Multiple editors can be in a shared session.

Media Framework Utilities: Utility plugins related to live video, timecode, and genlock on SDI capture cards.

nDisplay: Unreal Engine's technology for rendering on multiple displays.

nDisplay Support for Level Snapshots: Enables support for saving and restoring nDisplay Root Actor properties with Level Snapshots.

OpenColorIO (OCIO): Provides support for OpenColorIO.

OSC: Provides functionality to send and receive OSC messages between remote clients or applications.

Remote Control API: A suite of tools to control the Engine remotely through a REST API, WebSockets, and C++.

Remote Control Web Interface: Provides a remote web interface and UI builder for remotely controlling the Editor.

Switchboard: Application for launching instances of Unreal, nDisplay nodes, and other Virtual Production devices in a multi-user session.

Timed Data Monitor: Utilities to monitor inputs that can be time synchronized.

Virtual Production Utilities: Utility plugins useful for Virtual Production.

nDisplay Root Actor

The nDisplay Config Asset defines the relationship between the computers in the nDisplay cluster and the topology of the LED volume. The nDisplay Root Actor is an instance of the nDisplay Config Asset in the level, and is created by dragging the nDisplay Config Asset into the level.

Sample nDisplay Config Assets are included in the example project. You can find them in the Content Browser under nDisplayConfigs. For more information on the settings exposed in the nDisplay Root Actor, refer to nDisplay Root Actor Reference.

Step 2 - Create LED Panel Geometry

This section provides an example of how to create a representation of a curved LED wall. Each LED Volume can be different, so modify these steps to match the dimensions and layout of your display.

These steps show how to create the geometry to represent the real-world LED panels.

In this example, a curved wall is created with two meshes. Each mesh is mapped to an nDisplay viewport. There are a few factors which define how an LED stage should be separated into meshes:

Angle: The maximum ideal angle of curvature should be 90 degrees per mesh. A curve greater than 90 degrees per mesh can cause visual degradation. In addition, no single viewport (and therefore mesh) can cover more than 179 degrees.

Resolution: UHD (3840 x 2160) is a sensible upper limit to render on a single GPU nDisplay viewport. For machines with multiple GPUs, you can have multiple viewports that span across a larger display resolution. Either way, separate your stage mesh based on the resolution of the LED panels in increments of the maximum resolution at which you want each machine and viewport to render. Refer to your LED manufacturer for details on your per-panel resolution.

Control: You might want to separate control between the ceiling and side walls, if you only use ceiling panels for lighting and reflections and they never appear in-camera. This is especially true if the LED panels are different models and require different color management. Color management is controlled per viewport, so you must break out these different panels into their own meshes.

These are considerations for how to separate the topology into meshes (and therefore viewports). It is common for a single machine to render multiple viewports, such as a ceiling and a wall. The important thing is that they are separate viewports on the single node.

Each mesh should have two UV sets in a particular order. The first UV set is used for calculating the projection for the PICP_Mesh projection policy for nDisplay. The second UV set is used to ensure that the chroma key tracking markers move appropriately across seams between two viewports.

Each square on this example mesh represents an LED panel that is 500mm x 500mm with 2.6mm pixel pitch.



Mesh representation of a curved LED wall. Click image to enlarge.

The meshes should be modeled in a position and orientation to match the real-world LED panels. In this example, they are modeled upright. The geometry should be modeled to scale in cm.

Create the UV sets with the following specifications:

The first UV set should be scaled to cover the entire UV space in the range 0-1. This UV set should be unfolded as evenly as possible to avoid stretching. The scaling can be non-uniform. Ensure there is no padding around the edges of the UVs, and that the UVs do not go beyond the range 0–1.



The second UV set should have the UVs aligned so that they match at the same seams as the actual hardware configuration. They should also have the same aspect ratio as the meshes.



When the meshes are created, export the geometry from the 3D modeling software and import them into the Unreal project. Download this example mesh and drag the file to the Content Browser into the Content/nDisplayConfigs/Meshes folder to follow the steps in the next section.

Once the meshes are imported into your Unreal Project, enable Use Full Precision UVs on each mesh to prevent UV artifacts appearing. Follow these steps for each imported mesh:

Double-click the imported mesh to open it in the Static Mesh Editor.

In the Details panel under LOD 0, expand Build Settings and enable Use Full Precision UVs.



Click the Apply Changes button.



Click Save.

Close the Static Mesh Editor.

Step 3 - Define the LED Screens in Your Project

You will need to customize the layout and geometry of the screens in the project to reflect what you have on set. These meshes should be in the same physical position and dimensions as your LED wall in the real world in relation to your tracking system. The tracking system used on set will have a zero point. These meshes should be placed in the same world coordinates as they relate to the tracking system. Work with your tracking provider to find out where the zero point is and measure relative to this zero point to find the offsets.

These examples do not use the loopback address 127.0.0.1, because its use cannot be combined with other non-loopback addresses, such as those belonging to other machines, in the same Switchboard configuration. Loopback may be used, but only in a simple configuration where it is the only address used, and every device is local to the machine running Switchboard. Mixing loopback and non-loopback addresses in a multi-machine setup leads to connectivity errors.

Follow these steps to modify and customize the layout and geometry of the screens in the engine:

In the Content Browser, navigate to the nDisplayConfigs folder.

Right-click in the folder to open the Create Asset menu and choose nDisplay > nDisplay Config.



In the Pick a starting point for your nDisplay Config window that appeared, choose Create New Config and click Finish.



Name the new nDisplay Config Asset NDC_ICVFXQuickStart.



Double-click the NDC_ICVFXQuickStart Asset to open it in the nDisplay 3D Config Editor.



In the Components panel, right-click the nDisplayScreen Component and select Delete to remove the component from the list.



Click Add Component and add two Static Mesh Components to the Components panel.



Name one of the Static Meshes CurvedWall_Left, and in its Details panel assign ExampleCurvedWallMesh_nDisplay_WallLeft to its Static Mesh parameter. Name the other CurvedWall_Right, and assign ExampleCurvedWallMesh_nDisplay_WallRight to its Static Mesh parameter.



Select both Static Mesh Components and rotate them so they're curving towards the View Origin Component. You will not see a preview of the projections on the meshes until Projection Policies have been set in a later step.



In the Cluster panel, click the Add New button and choose Add New Cluster Node.



If you are using the NVIDIA Quadro Sync II with NVIDIA Quadro GPUs, select the Cluster item in the Cluster panel and set Type to Nvidia (2).



A Cluster Node represents a host computer. In the Add New Cluster Node window that appears:

Set Host IP Address to your computer's external IP address. You must use your computer's external IP address instead of the default localhost IP address 127.0.0.1, if you want to add more computers to your nDisplay cluster later, because you cannot use both loopback and non-loopback addresses in a multi-machine setup. These steps use the IP address 192.0.2.0 as an example.

Enable Fullscreen to achieve synchronization and genlock.

Click Add.



A Cluster Node is created and a new viewport is assigned to the node. Select the viewport in the Cluster panel to open its Details panel.



In the Details panel, set View Origin to DefaultViewPoint. This allows the associated component to control the point of projection for the outer frustum.



Under the Projection Policy section of the Details panel for the viewport, set Type to Mesh and select your CurvedWall_Left mesh from the list. Only Static Mesh Components added to the Components panel will show in the mesh list.



See the test scene appear on the mesh in the viewport and in the Output Mapping panel.



Create a viewport for the other wall mesh. Right-click the Cluster Node and choose Add New Viewport.



In the Add New Viewport window that appears:

Set View Origin to DefaultViewPoint.

Under Projection Policy, set Type to Mesh.

Under Projection Policy, set Mesh to CurvedWall_Right.

Click Add.



A second viewport is created and the test scene appears on the wall mesh in the viewport and in the Output Mapping panel.



In the Components panel, add an ICVFXCamera Component. This component will give you inner-frustum controls and capabilities.



Select the created ICVFXCamera Component and manipulate it within the Preview Viewport. You will see an inner-frustum projection preview on your projection meshes.



Compile and Save the asset.

Drag the NDC_ICVFXQuickStart Asset into the level to create an nDisplay Root Actor and preview the level in the cluster.



Save the project.

This section showed how to create your own nDisplay Config Asset and set it up with the previously created meshes. An example nDisplay Config Asset is already included in the project with a quad mesh layout. You can find this asset in the Content Browser at nDisplayConfigs/nDisplayBasicExample.

Step 4 - Launch Your Project with Switchboard



Diagram shows how nDisplay works with a network and display devices for in-camera VFX. Click image to enlarge.

In an nDisplay setup, there is a primary computer and a cluster of additional computers. The primary computer is the centralized location for managing and dispatching input information. The primary computer also ensures all PCs in the cluster are synchronized and receive input and data at the same time. For more information on an nDisplay setup, see nDisplay Overview.

Switchboard is an external application that allows a single operator to control nDisplay clusters. Switchboard has additional features such as advanced logging, system monitoring, and integration with external software to simultaneously trigger third-party motion capture software take recording with Take Recorder.

Follow the steps below to launch the nDisplay cluster with Switchboard:

In the toolbar, click the Switchboard button. If this is your first time launching Switchboard, a command prompt appears and installs required dependencies.



In the toolbar, click the arrow next to the Switchboard button and in the dropdown menu choose Launch SwitchboardListener. This companion application must be run on every machine in the cluster to be able to connect to Switchboard.



Create a new Switchboard Configuration for the project.

If this is your first time running Switchboard, the Add New Switchboard Configuration window appears when Switchboard launches.

If you have run Switchboard before, click Configs > New Config in the top left corner of the window to open the Add New Switchboard Configuration window.

In the Add New Switchboard Configuration window:

Set Config Path to ICVFXQuickStart.

Set uProject to the location of the In-Camera VFX Example Project on your computer.

Set Engine Dir to the location of Unreal Engine 4.

Click OK.



In Switchboard, set Level to Main.



Click Add Device > nDisplay to open the Add nDisplay Device window.



In the Add nDisplay Device window, click the Populate button to see a list of available nDisplay Config Assets from the project. Select the nDisplay Asset created in the previous section, NDC_InCameraVFXQuickStart, and click OK.



The cluster node appears under nDisplay Devices.

Click its Connect to listener button to connect to the Switchboard Listener.



Click its Start Unreal button to launch Unreal with the nDisplay renderer.



When nDisplay launches, all windows are minimized on the computer and the nDisplay view appears.



Step 5 - Join Multi-User Session

The Multi-User Editing system enables robust collaboration to support any type of change. Multiple operator machines in the same Multi-User session can perform different tasks and modify the scene in real-time. In an nDisplay setup, Multi-User is responsible for synchronizing changes across the various instances of Unreal Engine on the cluster nodes to ensure that creative updates to the scene appear immediately and simultaneously on the LED wall during a shoot.

Follow the steps below to connect your Unreal Editor to the nDisplay renderer through Multi-User.

In Switchboard, click the Stop Unreal button on the nDisplay node.



Click the Settings button to open the Switchboard Settings window.

Under the Multi User Server section:

Set Server Name to ICVFXQuickStart_MU_Server.

Enable Auto Join so any Unreal instances or nDisplay nodes automatically attempt to connect.

Enable Auto Launch. The Multi User Server Executable will not start without it enabled.



Close the Settings window.

Set Multiuser Session to ICFVXQuickStart_Session_001.



Click the Start Unreal button next to the nDisplay node to relaunch it.



Wait for the nDisplay node to finish launching before going to the next step.

In the Editor's Toolbar, click the Browse button to open the Multi-User Browser.



In the Multi-User Browser, double-click ICVFXQuickStart_Session_001 to connect your Unreal Editor to the multi-user session started with nDisplay.



If the Unreal Editor displays a message about in-memory changes and prevents you from joining your multi-user session, it means that something in your editor may have an unsaved change and your project doesn't match the current state of the project running with nDisplay. All projects joining a multi-user session should be in the exact same state. To fix this, make sure to save the project before launching nDisplay.

The Multi-User Browser will now change to show you the session you are currently connected to and the Level each user has active. The Clients category will show you which nodes and Editor instances are connected. History will list transactions that have been made over a Multi-User session. Details will show more information about the currently selected transaction in the History category.



Changes you make in the Editor are now transmitted to the nDisplay node. Move the Default View Point Component for NDC_ICVFXQuickStart to see the nDisplay view update with the changes in the Editor.



Step 6 - Use Live Link for Camera Tracking

Live Link is a framework in the Unreal Engine for ingesting live data, including cameras, lights, transforms, and basic properties. For in-camera VFX, Live Link plays a critical role in distributing the tracked camera information and can be enabled to work with nDisplay to carry the tracking information to each cluster node. Unreal Engine supports many camera-tracking partners through Live Link, such as Vicon, Stype, Mo-Sys, and Ncam, as well as several other professional tracking solutions. Live Link also supports XR devices such as Vive Trackers and Controllers as a Live Link source.

It's important for this step that you have a Live Link source available. This guide will show how to set up Live Link XR in your project so you can use a VR headset and controllers for tracking. You can use similar steps to enable other Live Link sources. Refer to Live Link XR for more details.

To track the inner camera frustum via Live Link XR with nDisplay:

In Unreal Editor's main menu, choose Window > Live Link to open the Live Link panel.



In the Live Link panel, click the Add Source button. In the dropdown, choose Live Link XR Source.

In the Connection Settings panel that appears, enable Track Controllers and Track HMDs and click Add.



When the Live Link XR Source is added, connected XR devices appear under the XR section of the Subject panel.



In the Subject panel, select the XR device you're using for tracking to open its Details panel. In the Details panel, enable Rebroadcast Subject to share the tracking data with other computers in the Multi-User Session.



Click Presets and select Save as Preset.

In the main menu, select Edit > Project Settings.

In Project Settings, under Plugins, select Live Link.

Add the Live Link preset to Default Live Link Preset to make the preset automatically apply when the project runs.



In the World Outliner, select DemoDisplay3_innerFrustum to open its Details panel.

Click Add Component and choose Live Link Controller to add a Live Link Component Controller to the Cine Camera Actor.

In DemoDisplay3_innerFrustum's Component section, select LiveLinkComponentController to view its settings.

Under Live Link, set the Subject Representation parameter to your Live Link Subject. In this example, the Live Link Subject is a SteamVR Controller.



Select the ICVFX Camera Component of the NDC_ICVFXQuickStart Actor to open its Details panel. Set Cine Camera Actor to DemoDisplay3_innerFrustum.



When you move the XR device, the camera in the editor mimics the movement. The inner frustum also appears in the nDisplay preview when the camera faces the meshes.



Save the project.

Restart the nDisplay cluster to see the changes in the nDisplay renderer.

Step 7 - Enable Green Screen and Chroma Key

You can change what displays in the inner frustum on the LED panels from the virtual world to a green screen with chroma key markers.



Follow these steps to make the green screen visible and to modify the chroma key markers:

In the World Outliner, select NDC_ICVFXQuickStart.

In the Details panel, select the ICVFXCamera Component to view its settings.

In the Details panel under Chromakey, enable Enable Inner Frustum Chromakey.



The inner frustum turns green and tracking markers are rendered on top.



Change the parameters in the Chromakey section to modify the color, marker placement, and custom marker alpha textures. For more details on the settings, refer to nDisplay Root Actor Reference.



This section showed how to enable chroma key for the inner frustum. An example nDisplay Config Asset with chroma key enabled is already included in the project with a quad mesh layout. You can find this asset in the Content Browser at nDisplayConfigs/nDisplayExample_Chromakey.

Step 8 - Add Light Cards

Light Cards can be found in the nDisplay plugin content. Light Card Actors should be spawned to a separate layer to take advantage of nDisplay's Light Card control features and parented to the Config Actor's outer frustum viewpoint for optimum effect.

Follow the steps below to add Light Cards to your project.

In the Content Browser, click View Options and enable both Show Engine Content and Show Plugin Content.



In the Sources panel, open the nDisplay Content/LightCard folder.



Drag the Blueprint LightCard into your level. In the World Outliner, parent the LightCard actor to NDC_ICVFXQuickStart.



The splines visualise the position of the lat/long location of the Light Card. For a better projection to the outer frustum, place the Light Card Actor in the same location as the View Origin Component in the nDisplay Root Actor.

In the main menu, choose Window > Layers to open the Layers panel.



In the Layers panel, right-click and choose Create Empty Layer from the dropdown. Name the Layer ICVFXQuickStart_LightCards.



In the World Outliner, select the Light Card. Right-click the ICVFXQuickStart_LightCards layer and choose Add Selected Actors to Selected Layers.



In the World Outliner, select NDC_ICVFXQuickStart to open its Details panel.

In the Details panel under Light Cards, add an Array element to the Layers parameter.



Set the Layer Array element to ICVFXQuickStart_LightCards.



For more details on the Light Card settings, refer to nDisplay Root Actor Reference.

Step 9 - Shoot with Multi-Frustum

Multiple inner frustums can appear in the nDisplay Config Asset. In this step we'll add a second ICVFXCamera component to the NDC_ICVFXQuickStart nDisplay Config Asset and set it up for multi-frustum shooting.

Follow the steps below to add another ICVFX Camera Component to the nDisplay Config Asset.

Stop all nDisplay nodes before the next step.

In the Content Browser, double-click the NDC_ICVFXQuickStart Asset. Currently, there will already be an ICVFXCamera Component present in the Components panel.



Click Add Component and add another ICVFXCamera Component. Ensure both are parented to the Root Component in the Component hierarchy. Name the two ICVFXCamera Components as follows:

ICVFXCamera_ACam

ICVFXCamera_BCam



Select the new ICVFXCamera component and manipulate it in the viewport to see the multiple frustum projections.



Compile and Save the nDisplay Config Asset.

The nDisplay Root Actor created from this Asset automatically is updated with the second camera in the level.

In the World Outliner, select NDC_ICVFXQuickStart to open its Details panel. In the Details panel under In-Camera VFX, expand Inner Frustum Priority and change the order of the cameras. The camera listed first is rendered on top of the other when they overlap.



Add a new CineCamera Actor to your level to reference it from the ICVFXCamera component. Add a LiveLinkComponentController to the new CineCamera Actor and connect a Live Link Subject to the Component.

This section showed how to add another camera with its own inner frustum to the nDisplay Config Asset. An example nDisplay Config Asset with two cameras is already included in the project with a quad mesh layout. You can find this asset in the Content Browser at nDisplayConfigs/nDisplayExample_multiFrustum.

Step 10 - Apply OpenColorIO Configuration

This section shows how to create an OCIO Configuration Asset from a plugin content OCIO config file and assign it to the nDisplay Root Actor viewports.

Follow these steps to use an OCIO configuration in the project:

In the World Outliner, select NDC_ICVFXQuickStart to open its Details panel.

In the Details panel under OCIO, check Enable Viewport OCIO.

Expand All Viewports Color Configuration.

Set Configuration Source to ExampleOCIO.

Set Source Color Space to Utility - Raw.

Set Destination Color Space to Output -sRGB Monitor.



These steps showed how to add an OCIO configuration to the project. You can also set OCIO configurations per viewport and separately on the inner frustum. For more on how to do this, refer to Color Management in nDisplay.

Step 11 - Control the Scene Remotely

The Remote Control Web Interface is a customisable web application that utilises the Remote Control API. This section shows how to create a Remote Control Preset and make changes to your level from a web browser interface.

Follow the steps below to create your own Remote Control Preset and Remote Control Web Application.

In the Content Browser, right-click and choose Miscellaneous > Remote Control Preset to create a new Remote Control Preset Asset.



Double-click the Remote Control Preset Asset to open the Remote Control Panel.



In the Remote Control Panel, enable Edit Mode to show Closed and Open Eye buttons next to properties in the Details panel.

In the World Outliner, select the actor WebControlMannequinStatic to open its Details panel.

In the Details panel under the Transform section, click the Expose button to expose the Location and Rotation properties to the Remote Control API.



In the Remote Control Panel, click the Edit button next to Default Group in the Control Panel window and name the group of properties Mannequin Transforms.



In the Remote Control Panel, click the Launch Web App button to launch a web browser that will connect to the Remote Control Web Application. On your local computer, the web app is accessible at 127.0.0.1:7000.



In the Remote Control Web Application, switch the Control toggle to Design mode.



Select the Properties tab.

Click and drag Relative Location to the empty canvas. A blue circle in the Properties tab appears next to the property when a property has been added to the interface.



Click and drag Relative Rotation to the same canvas.

Select the Relative Location Widget in the canvas to open its settings.

In the widget settings for Relative Location, set Widget to Joystick to change the look of the widget.



Select the Relative Rotation Widget to open its settings.

In the widget settings for Relative Rotation, set Widget to Sliders.

Toggle from Design mode to Control mode to lock the interface.

With your Editor viewport visible, interact with the UI controls to see how it affects your level.



Step 12 - On Your Own

This guide covered setting up displays on LED screens, launching your project on multiple computers, and incorporating camera tracking into the project. Additional example nDisplay Config Assets are included in the project in the nDisplayConfigs folder that show how to set up your cluster in other configurations including with multi-node and mGPU.

Multi-display setups require syncing capabilities at both software and hardware levels. Not only should the generated content be ready at the same time on all PCs, using the same timing information for simulation, but the display swap (the changing out of the current image for the next image in the video card buffer) needs to also happen at the correct time to prevent tearing artifacts in the display. See synchronization in nDisplay for information on setting up display sync and genlock on the machines to create a seamless view across the multiple displays.

In addition to synchronizing the displays, the engine's timecode and frame generation needs to match the input from the camera. See Timecode and Genlock for steps on how to sync the timecode and genlock the engine between all the devices.

To be able to control the scene and displays during a film shoot, you can try several of the How-Tos for in-camera VFX:

On-stage scene modification in real-time with Multi-User Editing.

Live compositing using Composure.

Match the lighting and shadows between the real-world set and the environment displayed on the LED walls with Color Correct Regions.

Save and restore Actor states for each take with Level Snapshots.

Calibrate the display of content on your LED wall for your camera with the In-Camera VFX Camera Calibration guide.

Receive and monitor events from every machine in your network with Stage Monitor.

Monitor, calibrate, and view incoming timed data with the Timed Data Monitor.

Use motion blur effectively in your process shots with Camera Motion Blur in nDisplay.

Color correct for only the displays and inner frustum with Color Management in nDisplay.

This guide walked through the basics of in-camera VFX projects. For an example of a real production project, refer to the In-Camera VFX Production Test.

In-Camera VFX Overview

In-Camera VFX Quick Start

Recommended Machine Hardware

Additional Recommended Hardware

An in-camera VFX setup using Unreal Engine requires multiple machines to communicate with each other and drive the LED volume display. This page covers the hardware to consider for your in-camera VFX setup.



An example hardware layout with three render nodes. Click image for full size.

Most LED processors have the option to receive sync either from an external genlock source or from the incoming video signal from the graphics cards. Check what options are available with the LED processors you're using. In the hardware diagram, an external genlock source is providing the sync for the LED processors.

Recommended Machine Hardware

Workstation

When you select a workstation, it is important that you have adequate space and power for your memory, storage, and graphics hardware. Make sure your workstation has enough space and can support NVLink if you want to utilize multi-GPU, available starting in Unreal Engine 4.26.

CPU

In general, you should favor faster clock speeds over more cores. Beyond eight cores, the benefits of additional cores will be more noticeable in the compile time for code and shaders than other use cases. It is recommended that you have at least a three gigahertz (Ghz) clock speed as a starting point. Common examples of CPUs used for the in-camera VFX scenario include the Intel Xeon and Intel Core i9 processors, as well as the AMD Ryzen 9 3950X, AMD Threadrippers, and AMD Threadripper Pro.

RAM

64GB of DDR-4 memory is the recommended minimum for most in-camera VFX scenarios. Additional RAM may be required if your production uses large files.

GPU

Artist workstations: For artists using ray tracing and other advanced rendering features in Unreal Engine, we recommend the professional-level NVIDIA RTX cards:

NVIDIA RTX A6000

NVIDIA RTX A5000

NVIDIA Quadro RTX 8000

NVIDIA Quadro RTX 6000

Artists with lighter rendering needs may be able to use the consumer-level NVIDIA RTX cards:

NVIDIA GeForce RTX 3080Ti

NVIDIA GeForce RTX 3090

Render nodes: NVIDIA Quadro Sync is required to synchronize displays across an LED volume. Each render node machine must have this card in addition to its graphics card. You can find more details in NVIDIA's Quadro Sync II User Guide.

For render nodes with either single or dual GPU, we recommend the following NVIDIA RTX cards:

NVIDIA RTX A6000

NVIDIA Quadro RTX 8000

NVIDIA Quadro RTX 6000

For a complete list of compatible graphics cards with NVIDIA Quadro Sync, refer to the NVIDIA page for Quadro Sync.

If you plan to make use of nDisplay's support for rendering to multiple GPUs on a single computer, all graphics cards must also support NVLINK.

We generally recommend using the latest drivers from NVIDIA. In particular, when using multiple GPUs on a single workstation, make sure to use version R512.59 or later.

You can find the recommended driver for Virtual Production on NVIDIA"s Download Drivers page. Select your card type and OS and set Download Type to Production Branch / Studio to find the recommended driver.

Video Card

If you plan to use live green-screen compositing, you will need a SDI video card to handle camera input, compositing output, and timecode synchronization. SDI video cards such as the AJA Kona 5 and the Blackmagic DeckLink are recommended for live compositing.

Storage

Because your project data is localized to each computer, fast local storage is necessary for optimal performance. It is recommended that you use M.2 Solid State Drives (SSDs), such as the Samsung 970 Pro, as the secondary data drives from the machine's boot drive.

Storage Network Card

A 10-Gigabit Ethernet (GbE) Network Interface Controller (NIC) is recommended to maintain high-speed data transfer between operator systems and render machines.

Additional Recommended Hardware

Network Switch

Most 10 GbE Layer 2 or Layer 3 type network switches, such as the Netgear Smart Switch, should be sufficient for this scenario.

Sync Generators

There are wired and wireless options available for sync generators, and it is common to use both for an in-camera VFX set. For example, you can use a wired box to send signals to a wireless one. In the hardware diagram above, the orange line represents the wireless connection from a sync generator to the camera. The following is a list of recommended sync generators:

Wired options:

Blackmagic Design Mini Converter Sync Generator

AJA GEN10 HD/SD/AES Sync Generator

ESE HD-488E/SD HD/SD-SDI Timecode Reader/Generator/Inserter

Evertz 5601MSC Master Sync and Clock Generator

Courtyard CY460 Master Synce Generator

Wireless options:

Ambient Master Lockit for Master Sync

Ambient Lockit for Remote Sync

Display Adapters

See the NVIDIA list of standard display adapters recommended for the NVIDIA GeForce and Quadro cards.

See Club-3D CAC 1080 for connecting Display Port 1.4 to HDMI 2.0 on LED processors.

See the Lightware MX2 Series for connecting Display Port 1.2 to HDMI 2.0 on LED processors.

Use fiber extenders for longer, uncompressed HDMI connections, such as connecting graphics cards to display ports. The Lightware fiber extender is recommended for uncompressed HDMI 2.0 4K signals.

Video Distribution Amplifier (VDA)

For an in-camera VFX setup, VDAs are typically used to distribute the genlock signal into multiple channels to the render nodes, camera tracking system, the live compositing machine, and sometimes the camera itself. In the diagram above, you can see the lines from the genlock sync are distributed through the distribution amplifier to various other devices in the setup.

The following is a list of recommended VDAs:

Shinybow Composite DAs

Kramer

VAC

Content Browser Folders

The In-Camera VFX Production Structure Example is intended to provide a clean sample organizational structure for a Virtual Production project. You can duplicate this structure and modify it as necessary to meet the requirements of your own project. The structure described is based on the structure of the In-Camera VFX Production Test, expanded to cover additional common use cases.

Content Browser Folders

Inside the Content folder of the Content Browser, create a folder named based on your Project Name, to hold any content specifically for your project. If required, create a folder named Common, which will contain any content that is shared with other projects.

Don't confuse the Project folder created by UE when the project was created (the root folder of the entire project) with the folder with your Project Name you create inside the Content Browser. We recommend varying the names so as not to confuse them.



Content/(Project Name)/Assets

All assets for creating Characters, Environments, and visual effects. Level Assets are not included here.

Content/(Project Name)/Envs

Contains all levels, snapshots, and sublevels. Does not contain any Stage actors.

Content/(Project Name)/Media

Any media framework content such as EXRs and Movie Render Queue Outputs and Profiles.

Content/(Project Name)/Sequences

All level sequences, edits, animations, and related snapshots.

Content/(Project Name)/Stages

Stage-specific files like mocap layouts, green screen stages, and LED stages such as nDisplay Configurations which describe the topology of the LED volumes.

Content/(Project Name)/StageLevels

All the Level Assets that have both environment and stage Actors.

Content/(Project Name)/Tools

Custom Blueprints including utilities and widgets, controls, Level Snapshot Filters and Presets, and Remote Control Presets. Also includes any related Blueprint Actors — structures, enums, and so on.

We recommend using an organized naming convention for your Assets to help make it easy to find them in the Content Browser. Refer to the Recommended Asset Naming Convention for a best-practices example.

Refer to the individual pages for the details of the recommended project structure inside each folder.



A diagram showing the recommended top-level folder structure for your project in the Content Browser.



The Assets folder typically contains all Assets for creating Characters, Environments, and FX - Meshes, like Materials, Textures, Blueprints, and other source files. Level Assets are not included here.

Each subfolder contains the appropriate source files for that Asset. For example, the Chr folder contains Character Asset subfolders, one per Character used. Each contains that Character's source Assets, that is, Blueprints, Skeletal Meshes, Skeletons, Animations, Materials, and so on.

The following list is how the Assets were categorized for the In-Camera VFX Production Test project, expanded to include a few Asset types that were not used in that project. It's unlikely for any given project to use all possible Asset types.

Vegetation

Tree_A

SM_Tree_A

MI_Tree_A

T_Tree_A_BaseColor

Rocks

Rock_A

BP_Rock_A

SM_Rock_A

MI_Rock_A

T_Rock_A_BaseColor

Rock_B

Pebble_A

Chr

Backpacker_A

BP_Backpacker_A

SK_Backpacker_A

SKEL_Backpacker_A

MI_Backpacker_A

T_Backpacker_A_BaseColor

ABP_Backpacker_A_Livelink

ABP_Backpacker_A_Game

Animations

A_Backpacker_A_Run

A_Backpacker_A_Idle



A diagram showing the first part of the recommended Asset folder structure for your project in the Content Browser.

FX

Birds_A

BP_Birds_A

FXS_Birds_A_(DescA)_A

FXS_Birds_A_(DescB)_A

Emitters

FXE_Birds_A_(DescA)_A

Decals

MI_Caustic_A_Decal

T_Caustic_A_M

HDRs

HDR_NightSky_A

HDR_CitySky_D

IES

TLP_Arri750Plus_A

TLP_Arri750Plus_B

OCIO

(Stage Name)

OCIO_(Stage)_A

OCIO_(Stage)_B

LUTS

(Description).spi1d (file explorer only)

OpenColorIO .spi1d files do not show in the Content Browser, only in the File Explorer. Refer to the OpenColorIO documentation for more information.

MasterMaterials

Ground_A

M_Ground_A

T_Ground_A_BaseColor

MI_WetGround_A

Textures

Props*

Landscapes*

Vehicles*

Other*

* Not used for the In-Camera VFX Production Test.



A diagram showing the rest of the recommended Asset folder structure for your project in the Content Browser. It links back to the first part at the top.



The Envs folder contains all the assets specifically for your environments (envs).

Since source control only lets you exclusively check out binary assets, such as .umap files, each artist working on an environment at the same time must work on their own level. The solution to this is to divide an environment up into multiple sublevels based on the type of Actors in each.

For example, a lighting artist would work in the lighting sublevel, and an FX artist in the FX sublevel. It is also common to have multiple GEO levels that divide the environment up into regions, each being worked on by a different artist. The number and types of sublevels used should be dependent on the needs of the production.

The files in this section are linked to the Stages folder files, as they will all be combined for the final In-Camera VFX persistent levels.

The following are the types of folders used for each environment in the sample project:

Level Asset: Level Assets follow a (LevelName)_(Descriptor) structure. The _P suffix is given to the Persistent Level, which acts as a container for the sublevels. Open this Level Asset to view the full environment composed of all the sublevels.

SubLevels: In this project, each Level was separated into the Caustics, FX, Geo, and Lighting sublevels.

Snapshots: Level Snapshot Assets associated with the Level.

For example:

CaveEntrance

CaveEntrance_P — Main persistent level

SubLevels

CaveEntrance_Geo_A

CaveEntrance_Lighting_A

CaveEntrance_FX_A

CaveEntrance_Anim_A

CaveEntrance_Vis_A

Snapshots

SNAP_CaveEntrance_(Description)

CavePath

SpaceJunkyard



A diagram showing the recommended Envs folder structure for your project in the Content Browser.



The Media folder includes all the files associated with using media in your production. Some of the files in this section will be automatically populated at the Root level of the Content Browser by the Media Framework plugin. The folders here are used in the background by the Media Profiles, but you should almost never have reason to work with them directly.

Bundles - Auto populated at the Content Root level by the Media Framework plugin.

Proxies - Auto populated at the Content Root level by the Media Framework plugin.

MediaOutputs

MediaProfiles

MPR_(Description1)

MPR_(Description2)

MediaSources - All Actors related to media content, with separate folders for each Media Source.



A diagram showing the recommended Media folder structure for your project in the Content Browser.



The Sequences folder contains all Level Sequences and Animations, grouped by sequence abbreviation (CE, CP, and SJ in the example shown).

The Edits subfolder contains edits that apply to the entire project's sequences taken together. Each individual sequence folder also has an Edits subfolder, which applies specifically to that sequence only.

This sample uses the format (Sequence Code)_(Setup)_(Camera or Anim Pass)_(Take). However, this is only an example take-naming convention. Use whatever naming system for your takes that makes sense for your project. The important point is for the naming system to be consistent.

Edits

EDIT_Origin_00_01

EDIT_Origin_0A_07

CE (Sequence Abbreviation)

Takes - Sorted by shot name and take number

CE_00_0A_01

LS_CE_00_0A_01

SNAP_CE_00_0A_01

CE_00_0A_01_Subscenes

LS_Actor01_CE_00_0A_01

LS_Actor02_CE_00_0A_01

Animations

A_CE_00_0A-01_Actor02

Shots

Previs

Techvis

Edits

EDIT_CE_00_01

EDIT_CE_0G_99

Sublevels

CE_Lighting

CE_Chr



A diagram showing the recommended Sequences folder structure for your project in the Content Browser.



The Stage Levels folder contains all the Level Assets that have both environment and stage Actors. Open these assets when you want to render with nDisplay. The stage levels are categorized by the stage used in the Level Asset.

EpicLA

CaveEntrance_Epic_LA - Persistent level with all sublevels + stage topology

SpaceJunkyard_Epic_LA

CavePath_EpicLA



A diagram showing the recommended Stage Levels folder structure for your project in the Content Browser.



The Stages folder contains the nDisplay Configurations which describe the topology of the LED volume or volumes used and all related files.

The files in this section are linked to the Envs folder files, as they will all be combined for the final In-Camera VFX persistent levels.

EpicLA

EpicLAStage_P - Main Stage persistent level

WarpMeshes - Meshes that make up the volume

EpicLA_C1

SM_EpicLA_C1

MI_EpicLA_C1_(Description)_A

T_EpicLA_C1_(Description)_A

Configs

NPC_EpicLA_(Description)

EpicLA_(Description).cfg - .cfg files are not visible in the content browser



A diagram showing the recommended Stages folder structure for your project in the Content Browser.



The Tools folder contains custom Blueprints and widgets, Level Snapshot Filters and Presets, and Remote Control Presets. The following list describes each tool.

Blueprint Tool A: Separate folder per-Stage blueprint used, containing it's source:

BP_Tool or WBP_WidgetTool — The principle Blueprint.

Enums - Related enumerations used in the Blueprint.

E_(Description)

Structs - Related structures used in the Blueprint.

F_(Description)

SubBlueprints - Only present if any sub-blueprints are used.

BP_(Description)

SubWidgets - Only present if any sub-widget blueprints are used.

WBP_(Description)

Remote Control: Remote control presets used

RCP_(Description)

Common



A diagram showing the recommended tools folder structure for your project in the Content Browser.

In-Camera VFX

Creating a Project from the Template

Template Features

Maps

LED Curved Stage

The In-Camera VFX Template is the starting point for creating the complex configuration that goes into a live-action LED stage. It provides a basic map and a variety of features to help you get started with your in-camera VFX project.

Creating a Project from the Template

Launch Unreal Engine.

Select the Film, Television, and Live Events template category.



Click image for full size.

Click InCamera VFX.



Click image for full size.

Choose whether to include starter content and whether to enable retracing, and select the path and name for your project.

Click Create.

Template Features

An nDisplay configuration and Blueprint set up for In-Camera VFX

Configurable inner frustum and outer frustum

Live Link

A chroma key and tracking markers

Color Correction Regions

Web remote control

OSC

Refer to the In-Camera VFX Overview and In-Camera VFX Quick Start for information on how to use these features.

In order to access the Blueprints and other assets described in the template, make sure to enable Show Engine Content and Show Plugin Content in the View Options menu in the Content Browser.



Maps



Click image for full size.

LED_CurvedStage is the main map. It is provided for typical in-camera VFX set-ups and configurations.

LED Curved Stage



This map provides an alternative set up with a curved mesh used for the LED wall. The LED wall is composed of four sub-sections, two on the left and two on the right, hence why there are four screens within nDisplay_InCamVFX_Config under the root component. You can customize these sub-sections to use this as a starting point to describe any type of curved LED displays, so that it matches your hardware configuration.



In the Details for nDisplay_InCamVFX_Config in the Curved Stage map, there is a control setting to enable the chroma key, allowing control over the visibility of that layer.



Click image for full size.

Getting Started

Guides

Reference

Interactive content isn't limited to being displayed on a single screen, or even a single dual-screen device like a VR headset. An increasing number of visualization systems aim to immerse the viewer more effectively in the game environment by rendering real-time content through multiple simultaneous displays. These systems may be made up of multiple adjacent physical screens, such as a Powerwall display; or they may use multiple projectors to project the 3D environment onto physical surfaces like domes, tilted walls, or curved screens, such as in a Cave virtual environment.

The Unreal Engine supports these usage scenarios through a system called nDisplay. This system addresses some of the most important challenges in rendering 3D content simultaneously to multiple displays:

It eases the process of deploying and launching multiple instances of your Project across different computers in the network, each rendering to one or more display devices.

It manages all the calculations involved in computing the viewing frustum for each screen at every frame, based on the spatial layout of your display hardware.

It ensures that the content being shown on the various screens remains exactly in sync, with deterministic content across all instances of the Engine.

It offers passive and active stereoscopic rendering.

It can be driven by input from VR tracking systems, so that the viewpoint in the displays accurately follows the point of view of a moving viewer in real life.

It is flexible enough to support any number of screens in any relative orientation, and can be easily reused across any number of Projects.

For additional background information about nDisplay, a more in-depth look at the real-life applications and display systems it was designed to support, and the future vision for the technology, download the white paper here.

nDisplay was an integral part of the visuals for Childish Gambino's award-winning 2018 Pharos show. See the project spotlight video below!

Getting Started



Describes how multiple computers work together in an nDisplay rendering network.



A guide to your first steps getting up and running with nDisplay.



A reference companion for all the settings available in the nDisplay configuration file.



How to set up and use the nDisplay Launch plugin for local nDisplay project rendering.

Guides



Describes how to set up any existing Project to be ready for nDisplay.



How to make nDisplay show test patterns that you can use to validate your setup.



An overview of how to control Actor replication across your nDisplay cluster.



Describes how to send events to your nDisplay cluster, and how to respond to those events in Blueprints.

Reference



Describes the different communication ports nDisplay uses on each computer to communicate with other computers in the cluster.

nDisplay Components

Workflow

Failover

Enable Failover

Multi-GPU Support

Runtime Camera Control

Blueprint API

Extending nDisplay

Supported Operating Systems

Windows

Linux

Every nDisplay setup has a single primary computer, and any number of additional computers, called secondary nodes.

Each computer in the network runs one or more instances of your Unreal project either in -game or in packaged format.

Each Unreal Engine instance handles rendering to one or more display devices, such as screens, LED displays, or projectors.

For each display device an instance of Unreal Engine handles, it renders a viewport that shares the same view origin or viewpoint. By setting up these viewports so that their location in the 3D world matches the physical locations of the screens or projected surfaces in the real world, you give viewers the illusion of being present and immersed in the virtual world.

The primary node is also responsible for accepting input from spatial trackers and controllers through connections to Virtual-Reality Peripheral Networks (VRPNs) through Live Link, and replicating that input to all other connected computers.



The image above shows a possible nDisplay network. Like all nDisplay networks, one of its PCs acts as the primary node. This primary node accepts input into the system from a VRPN server, which relays signals that come from spatial tracking devices and other controller devices. The network also contains several other PCs that run other instances of the Unreal Engine Project. Each of these secondary nodes drives one or more display projectors.



One application instance and host computer per display device.This is the most straightforward way to set up a host for nDisplay. For each projector or physical display device you need, you set up one computer to handle rendering to that device. On that computer, you run one instance of Unreal Engine running your project. Typically, in this scenario, you'll set up that application instance to render a single view of the 3D scene into a single viewport.



One application instance and host computer per multiple display devices.With this option, you run a single instance of Unreal Engine per computer, but you set it up to render multiple views of the scene's 3D space. Using the Output Mapping tool, these separate viewports are then mapped into different areas of a large 2D canvas, referred to as the application window.

We recommend leveraging multi-display technologies from graphics card vendors such as NVIDIA Mosaic or AMD Eyefinity to treat multiple connected displays as one display. This ensures that Unreal can render fullscreen on these aggregated screens for better display sync and performance. In this scenario, you can map all your viewports in this extended display canvas using the nDisplay Output Mapping tool.

For improved performance, you can also leverage a second GPU for viewport rendering. Once all pixels are copied and available on the display-facing GPU, they are composited in the application window and sent to the GPU outputs. For more details on using multiple graphics cards, refer to Multi-GPU Support.

nDisplay Components

nDisplay adds several components to the usual Unreal system architecture:

A Plugin that works inside the Unreal Engine. It communicates and synchronizes information between all the application instances that make up the cluster, ensures all instances render the same frame at the same time, ensures each display device renders the correct frustum of the game world, and more.

A shared configuration asset that contains all the settings nDisplay needs to start up the correct number of instances on the correct computers, each rendering the right points of view on the game's 3D world to produce the illusion of a seamless rendering across all display screens or projectors. See the nDisplay 3D Config Editor for more information.

Workflow

You need to tell nDisplay about the different computers you want to use in your network, the size and resolution of the screens or projectors those computers will render to, the spatial relationships between those screens in 3D space, and more. To do this, you create a configuration asset that expresses all of this information in a series of settings.

Typically, once your configuration asset is set up, you only have to modify it when the topology of your network changes: for example, when you need to change the computers you are rendering to, or if you change the physical arrangement of your screens and displays in the real world.

The general workflow for setting up your nDisplay cluster:

Create a new nDisplay Config Asset in the Unreal Editor.

Configure your nDisplay Config Asset in the nDisplay 3D Config Editor:

Components: Add your displays, cameras, and transforms to the root component.

Cluster: Create a representation of your cluster PC configuration, assign Viewports and GPU ID. Essentially adding PC's and Viewports.

Output Mapping: Effectively map Viewports to UE Application Windows. Assign Projection Policies and bind Viewports to Display, Screen, or Mesh Components.

Drag the nDisplay Config Asset into the level viewport to create an nDisplay Root Actor and preview your project's content from the cluster's perspective.

Launch your project onto your physical nDisplay setup with Switchboard.

To get started with a sample nDisplay configuration on your computer, follow the steps in the nDisplay Quick Start.

The nDisplay Root Actor is not required to be in the level to launch the nDisplay cluster. If the nDisplay plugin is enabled for the project, you can specify the location of the nDisplay Configuration Asset (.uasset or .ndisplay file) in Switchboard or the nDisplay Configuration File (.cfg or .ndisplay) as a command-line argument. This method works in -game and Packaged modes.

If a config asset is already present as an Actor in your project, it will be ignored when you specify one externally using Switchboard or command line arguments.

Failover

Every installed clustered system, either permanent or temporary, is exposed to some risk of failure. Failure can be because of hardware, software, or network issues. Failover refers to how systems can mitigate the risk of failure and recover from nodes failing without terminating the entire cluster.

The current implementation of failover in nDisplay addresses the network discoverable failures of the render nodes only. In other words, when a render node becomes unresponsive, whether because of a crash or because it loses its network connection, it is dropped from the cluster after a configurable timeout value.

Enable Failover

To enable nDisplay Failover support, open the Cluster Details panel in the nDisplay 3D Config Editor and set Failover Policy to Drop S-node on fail.



When activated, this option causes render nodes to drop from the cluster should they exceed the timeout value. The timeout values used for failover can be found in the Network settings for the Cluster. Refer to Changing nDisplay Communication Ports for details on the Network settings.



If any of the nodes don't respond in time and a barrier is timed out, those nodes are considered as failed and will be dropped from the cluster when the failover policy is active.

Multi-GPU Support

nDisplay supports multi-GPU (mGPU) for viewport rendering, so you can specify one GPU device to render a specific viewport and copy the frame to another GPU to display. For example, in virtual production and in-camera VFX scenarios, the inner frustum can be entirely rendered on a second GPU thereby improving performance and hardware usage.

On NVIDIA GPUs with NVLink, you can bypass the CPU and transfer memory directly from GPU to GPU. Without NVLink, any memory transfer will still be peer-to-peer (P2P) but might be slower as it has to go through the CPU over PCIe.

To enable mGPU in your nDisplay setup:

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Components panel, select the Config Asset to open the Details panel and set Configuration > Render Frame Settings > Multi GPU Mode to Enabled.

For viewport renders: In the nDisplay 3D Config Editor, select the viewport and in its Details panel set the GPUIndex field to the index of your GPU.



For inner frustum renders: In the nDisplay 3D Config Editor, select the ICVFX camera and in its Details panel set the GPUIndex field to the index of your GPU.



Typically, the first GPU installed and enabled in your computer is referenced as 0, while the others are incrementally assigned 1, 2, ... , n. You can find the GPU device number provided by your OS in your computer's settings. For example on Windows, you can find your GPU device numbers in Task Manager:

Open Task Manager.

Switch to the Performance tab.

The left side of the window shows every GPU you have in your machine and their device number.



In the Switchboard settings under your nDisplay node, set Number of GPUs to match the number of GPUs in the nDisplay node.



Runtime Camera Control

Internally, nDisplay maintains a hierarchy of scene objects in virtual 3D space that you set up in the configuration file. For example, this scene hierarchy typically defines the position of a camera, and the positions of a set of screens—rectangles of 3D space that represent the real-world display screens or projection surfaces in the virtual world. The positions of these nDisplay scene objects are defined relative to a single root position that is always located at the origin (0,0,0) in virtual space.

When you run a Project with nDisplay enabled, the root of this virtual space is based on the position and rotation of a DisplayClusterRoot Component that is attached to a camera in your Level. Every frame, nDisplay uses the position and rotation of this root component as the starting point for the hierarchy of scene nodes that you set up in your configuration file.

By default, nDisplay creates a DisplayClusterRoot Component at startup and attach it to the default camera. The effect is that all devices and projectors in the whole nDisplay cluster automatically render the scene from the point of view of the active camera.

Blueprint API

You can control the behavior of the nDisplay system in your game's runtime logic using its Blueprint APIs.

To get to the functions exposed in these APIs:

For most nDisplay Blueprint functions related to cluster management, querying input devices, nDisplay rendering, and more, create a new N Display > DisplayCluster Module API node in your Blueprint.

Drag from the Out API pin of your node, and look under the Display Cluster category:



Extending nDisplay

nDisplay offers many features out of the box for controlling real-time, synchronized rendering across multiple computers and output devices. However, there are a wide variety of projection systems and display surfaces, and you may need to extend the nDisplay rendering system to support your own choice of technologies. If you are comfortable programming in C++, and you understand how nDisplay works in typical use cases, you can extend nDisplay to support additional display and calibration technologies by building on top of its extendable rendering API.

The nDisplay API breaks the rendering pipeline into a few major concepts:

The DisplayClusterRenderingDevice, which is essentially an extension of the native IStereoRendering Interface.

The DisplayClusterPostProcess is a group of six callbacks that you can use to apply post-processing to specific viewports.

The DisplayClusterProjectionPolicy is responsible for custom projection methods, such as supporting Scalable Display, VIOSO, DomeProjection, or MPCDI to render to curved and arbitrary surfaces, or doing a simple planar projection.

The DisplayClusterRenderSyncPolicy is used for a variety of synchronization methods, like nvSwapLock, vSync, or custom skip-frame sync for 24hz displays.

By creating your own specializations of the elements described above, you can customize the images produced by the nDisplay system to suit whatever projection or display technologies you work with, while still getting all the key benefits of the nDisplay clustering system, all without needing to modify the shipped Unreal Engine source code.

For a working model of how to set up implementations of these elements, see the source code for the PicpProjection and PicpMPCDI modules. You'll find these modules in the Unreal Engine source code, under Engine/Plugins/Runtime/nDisplay/Source.

You can provide your own custom key-value pairs to your nDisplay cluster. You can include as many parameters and values as you need in the Custom Parameters field located in the Config Asset's Details panel. You can then retrieve these configuration values at runtime from the nDisplay Blueprint or C++ APIs.

To add Custom Parameters:

In the 3D Config Editor, select self in the Components panel to open its Details panel.

In the Details panel, expand the Configuration section and add elements to the Custom Parameters field.



Supported Operating Systems

Windows

All nDisplay tools and features are fully functional on Windows 10, 8.1, 8, and 7.

Linux

nDisplay and its tools ecosystem now includes preliminary Linux support. This will benefit users running UE under various flavors of Linux distros, especially those in training and simulation, in a clustered setup environment.

Custom Sync policies will exhibit some limitations due to existing graphics card drivers support.

Some Projection policies relying on other vendors will have to be validated.

Some rendering features, for example ray tracing, are not supported at the moment.

Step 1 - Set Up Your Project for nDisplay

Step 2 - Set up the Configuration File

Step 3 - Package and Deploy

Step 4 - On Your Own

This page describes how to get up and running with nDisplay for the first time.

Prerequisites:

Make sure you have your physical equipment — screens, projectors, and so on — set up and working correctly.

Make sure that the Windows account you intend to use on the primary computer has administrative rights on all computers you intend to use in the nDisplay network.

Make sure that all computers you want to use in the nDisplay network can receive TCP/IP communications over ports 41000, 41001, 41002, and 41003. (You can use different ports instead; see Changing nDisplay Communication Ports.)

Step 1 - Set Up Your Project for nDisplay

The easiest way to get a Project setup to use nDisplay is to create it from the nDisplay Template Project. You'll find this Template in the Film, Television, and Live Events category in the New Project window.



Click image for full view.

This Template automatically enables the nDisplay and Switchboard plugins, configures some helpful additional settings, and includes some sample configuration assets.

This guide uses the NDC_Basic nDisplay Config Asset to show how to launch nDisplay with one Cluster Node and one Viewport.

If you have an existing Project that you want to use with nDisplay, you can do the same configuration by hand. See Adding nDisplay to an Existing Project.

Step 2 - Set up the Configuration File

The template project already includes an nDisplay Root Actor for the NDC_Basic configuration. Select the actor and move it around the scene to preview it in the nDisplay cluster configuration. This real-time config preview is meant to be a replica of your nDisplay setup that you can preview in any level or project.

To preview other nDisplay Configurations, you can drag the nDisplay Config asset from the Content Browser into the Viewport.

Step 3 - Package and Deploy

A core concept with nDisplay is that it does not run in the Editor. Instead nDisplay runs as a separate instance of Unreal Engine launched with Switchboard. Switchboard and its companion application SwitchboardListener also run outside of Unreal Engine.

These examples do not use the loopback address 127.0.0.1, because its use cannot be combined with other non-loopback addresses, such as those belonging to other machines, in the same Switchboard configuration. Loopback may be used, but only in a simple configuration where it is the only address used, and every device is local to the machine running Switchboard. Mixing loopback and non-loopback addresses in a multi-machine setup leads to connectivity errors.

Follow these steps to launch your nDisplay cluster.

In the Toolbar, click the dropdown arrow next to Switchboard and choose Launch SwitchboardListener. SwitchboardListener launches and immediately minimizes itself. SwitchboardListener needs to be launched on every computer that will be in the nDisplay cluster.



If you don't see the Switchboard options in the Toolbar, click the double right arrow to see more options.



In the Toolbar, click the Switchboard button to launch the Switchboard application on your computer.



When launching Switchboard for the first time, a command prompt window may appear, installing required dependencies before the Switchboard window opens.

When Switchboard opens, the Add new Switchboard Configuration window appears. In the window, ensure the Config Path, uProject, and Engine Dir fields are correct, and click OK to open a blank configuration.



Switchboard Configurations are a collection of settings for Switchboard and are saved to disk. They can be reloaded and switched out at any time. Typically, you will want to create a Switchboard Configuration per project.

In Switchboard, click Add Device in the top left and choose nDisplay to open the Add nDisplay Device window.



Browse and select the NDC_Basic.uasset configuration file in your project, and click OK to add all the nDisplay devices described in the configuration asset to Switchboard.



Since only one nDisplay Cluster Node is specified in the configuration asset, only one nDisplay device appears in Switchboard under nDisplay Devices. Set the IP address to your computer's external IP address. You must use your computer's external IP address instead of the default localhost IP address 127.0.0.1, if you want to add more computers to your nDisplay cluster later, because you cannot use both loopback and non-loopback addresses in a multi-machine setup. These steps use the IP address 192.0.2.0 as an example.



Click the Connect to listener button to connect to the SwitchboardListener on the computer.



Click the Start Unreal button launch Unreal with the nDisplay renderer on the computer.



When the nDisplay instance launches, all other windows on the computer minimize and the nDisplay viewport appears on the desktop.

The default Switchboard launch mechanism described above uses -game mode. You can also work with cooked builds. This will require you to specify the file path of the cooked executable instead of the uproject file.

When working with cooked builds, you must update Switchboard settings to include the path of the .exe file and empty the UProject path. This tells Switchboard to ignore project location and use the cooked .exe file instead.



Step 4 - On Your Own

This guide covered setting up and launching one nDisplay cluster node on one computer with Switchboard.

Use the other nDisplay configurations available in the nDisplay Template to see how to set up nDisplay on multiple machines. Ensure you have SwitchboardListener running on every machine, to connect to them from Switchboard.

To create a seamless view across multiple displays, see Synchronization in nDisplay for information on setting up display sync and genlock on the machines.

To use a tracking system with your nDisplay cluster, you must add a LiveLinkComponent to your Cluster configuration. See Live Link for more.

Cluster Node Configurations

Window Configurations

Viewport Configurations

Projection Configurations

Screen Configurations

PostProcess Configurations

Camera Configurations

Scene Node Configurations

Input Configurations

Input Setup Configurations

General Configuration

NVIDIA Configuration

Network Configuration

Info Configuration

Custom Configuration Parameters

Configuration File Scene Structure Example

As of Unreal Engine 4.27, you can continue to import both .cfg and .ndisplay configuration files into your project's Content Browser and they will be converted to the new .uasset format.

You can export and use .ndisplay configuration files to launch a cluster. The .ndisplay files won't have tracking and other features that can only be configured in the nDisplay Config Asset.

We recommend using the nDisplay 3D Config Editor for configuring your nDisplay cluster.

You define most aspects of the nDisplay system in a single configuration file. This file includes the computers that make up your network, the characteristics of the windows and viewports you want the Unreal Engine to render on each computer, the parts of the virtual world each viewport should render, the types of input devices you want to accept, and more.

This page describes all the settings available in the nDisplay configuration file.

The best way to get started understanding the nDisplay configuration file, and creating your own, is to start from the example configurations provided by the nDisplay plugin. If you've created your Project from the nDisplay template, you'll find these files in your Project folder, under Content/ExampleConfigs. If not, you can find these files in the Unreal Engine installation folder, under Templates/TP_nDisplayBP/Content/ExampleConfigs.

The structure of the nDisplay configuration file is directly tied to the different types of components it uses to render the visualization.

Each different type of component that you configure has its own line in the file, and is identified by a string ID that you assign. You use these string IDs when one configuration section needs to refer to another.

Many of the components that you configure in this file have defined positions (and often rotations) in virtual 3D space. Each object's position and rotation is relative to that object's parent. By default, the parent of all objects is the VR space origin: an arbitrary point in 3D world space where VR space is considered to start. You can also configure specific named transforms in 3D space, called scene_nodes, which can act as parents for one or more components. This can help simplify the spatial layout of your screens, cameras and other components. To see how you can use scene_nodes to build a hierarchy of 3D transforms that all start from the same point in virtual space, see the Configuration File Scene Structure Example section below.

All parameters that refer to measurements in virtual 3D space or real-world physical space expect values in meters and degrees, unless otherwise indicated. This includes screens, scene nodes, cameras, and so on.

All parameters that refer to measurements in screen space expect values in pixels. This includes windows and viewports.

Cluster Node Configurations

For each different instance of your Unreal Engine application that you'll use in your nDisplay network, you need to define a cluster_node configuration. Each cluster_node configuration must contain a reference to a window configuration section that defines the properties of the main application window.

The cluster_node configuration also defines the hostname or IP address of the computer that will run that application instance. You may set up a different physical computer for each cluster_node configuration, or you may have multiple cluster_node configurations that run on the same host.

Example configuration:

This example configures a primary node (one per network):

This example shows a non-primary cluster node:

Parameters:

Parameter

Required?

Default

Description

id

Required

A unique name for this cluster node configuration.

addr

Required

The IP address of the computer that will run this instance of Unreal Engine. This must be an IPv4 address. IPv6 is not supported.

window

Required

The name of the window configuration that defines the size and position of the main window for this instance of your Unreal Engine application.

sound

Optional

false

Determines whether this instance of Unreal Engine plays sound. Optional; default value is false.

port_cs

Optional

14001

The port that the primary node uses to communicate with other nodes in the cluster for cluster synchronization. port_ss is for swap synchronization; port_ce is for cluster events. Optional; default values are 14001, 14002, and 14003.

port_ss

Optional

14002

The port that the primary node uses to communicate with other nodes in the cluster for swap synchronization.

port_ce

Optional

14003

The port that the primary node uses to communicate with other nodes in the cluster for cluster events.

master

Optional

false

Determines whether this instance of Unreal Engine is the primary node of the cluster. Only one cluster_node section can have this parameter set to true.

gpu

Optional

Determines the index of the GPU that this instance of Unreal should use for rendering.

Setting the GPU instance in this way is equivalent to using the r.GraphicsAdapter console variable.

Window Configurations

Each window configuration defines a set of properties for the main window of an instance of your Unreal Engine application. You use it to configure things like the starting size and placement of the window when nDisplay launches your application, and whether or not the window should take up the full screen.

You also provide one or more viewport configurations, which identify specific areas within the main application window that nDisplay will fill with renderings of your scene.

Example configuration:

This example configures an application window that contains a single viewport:

This example configures an application window that contains four separate viewports:

Parameters:

Parameter

Required?

Default

Description

id

Required

A unique name for this window configuration.

fullscreen

Optional

false

Determines whether this window should run in fullscreen mode or not. If you set this value to false, you must provide the WinX, WinY, ResX, and RexY settings described below.

WinX

Optional

0

Specifies the X position of the top left corner of the application window on the desktop, in pixels of screen space from the left edge of the screen.

WinY

Optional

0

Specifies the Y position of the top left corner of the application window on the desktop, in pixels of screen space from the top edge of the screen.

ResX

Required

0

Specifies the horizontal size of the application window in pixels of screen space. When fullscreen is set to false, this value is required. When fullscreen is set to true, this value is ignored.

ResY

Required

0

Specifies the vertical size of the application window in pixels of screen space. When fullscreen is set to false. When fullscreen is set to true, this value is ignored.

viewports

Required

Refers to one or more viewport configuration sections that define the areas of the main application window that nDisplay should fill with rendered views of the scene. If you specify more than one viewport, you must use a comma-separated list of viewport configuration section names, enclosed in quotes. See the wnd_four example under the Example configuration section above. The order of this list does not affect the visual order or placement of the viewports. The placement of the viewports within the parent window are defined in the named viewport configurations.

Make sure that the viewport definitions you use do not exceed the size of the window.

postprocess

Optional

Specifies the ID of one or more postprocess configuration sections that define post-processing operations you want to apply to the final generated output image before nDisplay renders it to the window. Optional; use this parameter only if you need to transform the final image before rendering it out. If you provide multiple postprocess configurations, nDisplay will apply their transformations in order.

Viewport Configurations

Each window configuration described above refers to one or more viewport configurations, each of which defines a rectangular area of the game window that nDisplay should fill with a rendered view of the scene.

Usually, a viewport starts at the upper left corner of the application window, and its width and height are set so that they fill the parent window. However, in some cases you may need to offset the viewport within its parent application window. For example, you might want to do this if you need to set up two projectors that partially overlap, or if you need one application window to host multiple separate viewports at different positions.

nDisplay supports multi-GPU (mGPU) for viewport rendering, so you can specify one GPU device to render a specific viewport and copy the frame to another GPU to display. For example in virtual production and in-camera VFX scenarios, the inner frustum can be entirely rendered on a second GPU thereby improving performance and hardware usage. On NVIDIA GPUs with NVLink, you can bypass the CPU and transfer memory directly from GPU to GPU. Without NVLink, any memory transfer will still be peer-to-peer (P2P) but might be slower as it has to go through the CPU over PCIe.

Add MaxGPUCount=2 to the custom command line arguments when you launch nDisplay either through the nDisplay Launcher or Switchboard to utilize mGPU.

Example configuration:

Parameters:

Parameter

Required?

Default

Description

id

Required

A unique name for this viewport configuration.

X

Optional

0

The coordinates of the top left corner of the viewport, in screen space pixels, from the left edge of the main application window. Note that this value is relative to the top left corner of the application window, not relative to the top left corner of the screen itself.

Y

Optional

0

The coordinates of the top left corner of the viewport, in screen space pixels, from the top edge of the main application window. Note that this value is relative to the top left corner of the application window, not relative to the top left corner of the screen itself.

width

Required

0

The width of the rendered frame, in pixels. This should not be larger than the size of the game window that is set by the size parameter of any window configuration using this viewport.

height

Required

0

The height of the rendered frame, in pixels. This should not be larger than the size of the game window that is set by the size parameter of any window configuration using this viewport.

projection

Required

The name of the projection configuration that defines the rendered view of the virtual world that should be drawn to this viewport.

camera

Optional

The ID of a camera configuration section that you want to force this viewport to display. By default, viewports render the scene from the location of the camera section currently in use by nDisplay. However, you can use this parameter to override the default nDisplay camera and force this viewport to render the scene from the point of view configured in a different camera section.

buffer_ratio

Optional

1.0

A value between 0 and 1 that scales the dimensions of the render target texture that nDisplay uses to render this viewport. Lowering this value effectively lowers the resolution of the image generated by nDisplay. This decreases the quality of the final image, but may make it faster to render.

rtt

Optional

false

Determines whether this viewport renders to a texture.

gpu_node

Optional

0

The GPU device assigned to render the viewport and to copy the frames to the display-facing GPU. The default GPU is the first one installed in the computer.

allow_gpu_transfer

Optional

1

With this option enabled, every viewport will be transferred to every GPU. Disabling this option prevents the copy to the other GPU.

share

Optional

With this option enabled, nDisplay uses Texture Sharing for the viewport, sending and receiving textures from other applications. See Texture Share for more details.

Typically, the first GPU installed and enabled in your computer is referenced as 0, while the others are incrementally assigned 1, 2, ... , n. You can find the GPU device number provided by your OS in your computer's settings. For example on Windows, you can find your GPU device numbers in Task Manager:

Open Task Manager.

Switch to the Performance tab.

The left side of the window shows every GPU you have in your machine and their device number.



A computer with one GPU has its GPU labelled GPU 0 in Task Manager.

Projection Configurations

Each viewport configuration described above refers to a projection configuration, which is responsible for defining the rendered image that needs to be drawn in the viewport.

In most common situations, you will use the simple projection type, which renders the virtual world from the current camera's position using a frustum that is defined by a screen configuration section elsewhere in this nDisplay configuration file.

Other projection types, such as mpcdi, easyblend, vioso, and domeprojection, use other methods to define the rendered content for the viewport, and may introduce additional corrections or apply additional rendering techniques before rendering the image to the rectangular viewport. For example, the projection may squash, stretch, or distort the image so that it will look natural when displayed on a curved surface.

Example configuration:

The following example shows the simplest possible use case, which routes the frustum defined by the screen configuration named scr_LT directly to the viewport without distorting or modifying the rendered image.

The following example shows how to use the easyblend projection type to render to a surface defined in a Scalable Display configuration file.

The following example shows how to use the mpcdi projection type to render to a surface defined in an MPCDI configuration file.

The following example shows how to use the mpcdi projection type to render to a curved surface defined by a specified .pfm geometry file, using an alpha blending map defined by a specified .png file.

The following example shows how to use the vioso projection type to render to a surface defined in a native VIOSO file.

The following example shows how to use the domeprojection type to render to a surface defined by DomeProjection in a .xml calibration file.

Parameters:

Parameter

Required?

Default

Description

id

Required

A unique name for this projection configuration.

type

Required

The type of projection that defines how nDisplay generates the rendered image it draws in the viewport. This accepts the following values:

simple: Renders to the viewport a frustum on the virtual world defined by a screen configuration section.

easyblend: Renders to the viewport a view of the virtual world that you have calibrated using tools from Scalable Display Technologies.

mpcdi: Renders to the viewport a view of the virtual world that you have calibrated using MPCDI.

vioso: Renders to the viewport a view of the virtual world that you have calibrated using tools from VIOSO.

domeprojection: Renders to the viewport a view of the virtual world that you have calibrated using tools from DomeProjection.

Projections where type=simple also accept the following additional parameters:

Parameter

Required?

Default

Description

screen

Required

The name of the screen configuration that defines the frustum of 3D space that the Unreal Engine application should render into this viewport.

Projections where type=easyblend also accept the following additional parameters:

Parameter

Required?

Default

Description

file

Required

The path and file name of the Scalable Display calibration file (.ol or .pol extension) that defines the surface that this viewport will be projected on.

origin

Optional

The ID of a scene_node configuration section that defines the starting point for the projection. This maps the frame of reference defined in the Scalable Display calibration file to the virtual space in your Unreal Engine Level.

scale

Optional

1.0

The scaling factor to use for the projection. This value depends on the units you used to calibrate EasyBlend. If you used meters, leave this value at 1.0. For decimeters, use 0.1. For centimeters, use 0.01. For inches, use 0.0254.

Projections where type=mpcdi or type=picp_mpcdi also accept the following additional parameters:

Parameter

Required?

Default

Description

origin

Optional

The ID of a scene_node configuration section that defines the starting point for the projection. This maps the frame of reference defined in the MPCDI calibration file (or the .pfm geometry file) to the virtual space in your Unreal Engine Level.



Option 1: Using an MPCDI file



file

Required

The path and file name of the .mpcdi file that defines the geometry of the surface that this viewport will be projected on.

buffer

Required

The ID of the buffer in the .mpcdi file that defines the projection area for this viewport.

region

Required

The ID of the region within the buffer set above that you want to render to.



Option 2: Using explicit data



pfm

Required

Specifies a pfm file that contains the geometry for the projection.

scale

Optional

1.0

Provides a scaling factor to use for the geometry.

ue4space

Optional

false

Indicates whether the geometry in your .pfm file is already expressed in the Unreal Engine coordinate system.

alpha

Optional

The path and file name of a .png file to use as an alpha blend map, which defines the intensity of the projection. Optional.

alpha_gamma

Optional

If you use the alpha setting, you can use the alpha_gamma setting to provide a multiplier for the alpha gamma. Optional.

beta

Optional

If you use the alpha setting, you can also use the beta setting to provide the path and file name of the .png file to use as a beta blend map. This defines the black level adjustment. Optional.

nDisplay currently supports only MPCDI version 1.0, and only the 2D and A3D (or Advanced 3D) profile types.

Projections where type=vioso also accept the following additional parameters:

Parameter

Required?

Default

Description

file

Required

The path and file name of the VIOSO calibration file (.vwf extension) that defines the surface that this viewport will be projected on.

origin

Optional

The ID of a scene_node configuration section that defines the starting point for the projection. This maps the frame of reference defined in the VIOSO calibration file to the virtual space in your Unreal Engine level.

base

Optional

The custom base matrix to convert the calibration space into UE coordinate system.

Projections where type=domeprojection also accept the following additional parameters:

Parameter

Required?

Default

Description

file

Required

The path and file name of the DomeProjection calibration file (.xml extension) that defines the surface that this viewport will be projected on.

channel

Required

0

The output mapped in the calibration file. One channel per display.

origin

Optional

The ID of a scene_node configuration section that defines the starting point for the projection. This maps the frame of reference defined in the DomeProjection calibration file to the virtual space in your Unreal Engine level.

Projections where type=manual also accept the following additional parameters to define the view rotation and frustum that nDisplay should render. You can configure the frustum using either matrices or angles.

Parameter

Required?

Default

Description

rot

Optional

0,0,0

The view rotation. Expressed as pitch, yaw, and roll values. For example, rot="P=0,Y=0,R=0".



Option 1: Using matrices (monoscopic)



matrix

Required

If using monoscopic rendering, use this 4x4 matrix to define the view frustum.



Option 2: Using matrices (stereoscopic)



matrix_left and matrix_right

Required

If using stereoscopic rendering, use this pair of 4x4 matrices to define the view frustum of both the left eye and the right eye. For example, matrix_left="[0.5 0 0 0] [0 0.999999 0 0] [1 0 0 1] [0 0 1 0]" matrix_right="[0.500001 0 0 0] [0 1 0 0] [-1 0 0 1] [0 0 1 0]".



Using angles





Option 3: Using a frustum (monoscopic)



frustum

Required

If using monoscopic rendering, use this property to define the angle to the left, right, top, and bottom of the frustum. For example, frustum="l=0 r=15 t=10 b=-10". Values are set in degrees relative to the view vector.



Option 3: Using a frustum (stereoscopic)



matrix_left and matrix_right

Required

If using stereoscopic rendering, use these properties to define the angle to the left, right, top, and bottom of the frusta for both the left eye and the right eye. For example, frustum_left="l=-15 r=0 t=10 b=-10" frustum_right="left=0 right=15 top=10 bottom=-10". Values are set in degrees relative to the view vector.

Projections where type=camera do not accept any other additional parameters. You set up the camera for the projection policy at runtime using either the Blueprint or C++ API.

Projections where type=mesh and type=picp_mesh do not accept any other additional parameters. You set up the Static Mesh Component for the projection policy at runtime using either the Blueprint or C++ API.

Screen Configurations

Each different output display that uses the simple projection type renders the scene from the current camera's position using a frustum that is defined by a rectangle with a defined size and placement in the 3D VR space. Each of these rectangles is defined by a screen configuration. Usually, each of these projection screens has the same dimensions in VR space as the physical screen that you'll use to render it.

The pivot point of a screen is always in its exact midpoint.

Example configuration:

This definition describes a screen that is 3 meters by 3 meters screen, directly in front of its parent. Because the pivot point of the screen is at the center of the rectangle defined by the size parameter, we add a 1.5 meter offset on the Z axis to move the screen upward by half its height.

To define a screen on the left side of the viewer, we move it to the left (negative values on the Y axis), and rotate it around its local Y axis (yaw),

Parameters:

Parameter

Required?

Default

Description

id

Required

A unique name for this screen configuration.

loc

Optional

0,0,0

The location of the center of this screen in VR space, relative to its parent.

rot

Optional

0,0,0

The pitch (P), yaw (Y) and roll (R) angles of the screen's facing direction, in degrees, relative to its parent.

size

Required

0,0

The total size of the screen rectangle along its local X and Y axes, in meters.

parent

Optional

The name of a scene_node configuration that you want to act as the parent for this object. This parameter is optional. If you specify a parent, the values you set in the loc and rot parameters will be relative to the position of that parent. If you omit the parent, the values you set in the loc and rot parameters will be relative to the VR root.

tracker_id

Optional

The name of a input configuration that defines a VR device you want to drive the position of the screen over time. Optional. If you omit this parameter, the screen's position will be static in VR space.

tracker_ch

Optional

When you provide a tracker_id, this parameter specifies the channel of that device that nDisplay will read tracking data from.

PostProcess Configurations

A postprocess configuration defines how the image generated for a window by an instance of the Unreal Engine should be post-processed before being rendered. nDisplay currently supports two types of post-process operations: OutputRemap and TextureShare.

With OutputRemap, you can control the way the 2D image, generated by nDisplay, maps to the 2D area of the application window. For example, you can translate, rotate, and scale parts of the output image so that they appear in different regions of the application window. To do this, you need to provide an .obj file that contains a planar geometry with a UV mapping set up. nDisplay will use the UV mapping that was set for your plane to determine how the output image is mapped to each part of the application window.

With TextureShare, you can receive a texture from another application and display it in the specified viewport. To do this, you need to define a postprocess with the name of the Texture Share item and the viewport that will display the texture.

Example configuration:

The following example shows how to use the OutputRemap postprocess type with two .obj files:

The following example shows how to use TextureShare to share the rendered frame for the vp_1 viewport to an external application, receive a texture from a third party source, and display it in the vp_ext viewport.

Parameters:

Parameter

Required?

Default

Description

id

Required

A unique name for this postprocess configuration.

type

Required

The type of post-processing you want to carry out. Currently supports the following types:

OutputRemap

TextureShare



OutputRemap configuration



file

Required

The path and file name of the .obj file that contains the UV mapping you want to use to remap the rendered image before drawing it to the application window.



TextureShare configuration



destination

Required

The name of the viewport that applies the texture share item received from the source application.

source

Required

The share name of the application sending the texture to nDisplay.

Camera Configurations

All instances in the nDisplay cluster render the scene from the same position in the virtual world. Each of these potential viewpoints is defined by a camera configuration line.

You can switch between these viewpoints at runtime. Each camera viewpoint can also be driven by a tracking device.

Example configuration:

Parameters:

Parameter

Required?

Default

Description

id

Required

A unique name for this camera configuration.

loc

Optional

0,0,0

The location of this camera in VR space, relative to its parent.

rot

Optional

0,0,0

The rotation of this camera in VR space, relative to its parent.

parent

Optional

The name of a scene_node configuration that you want to act as the parent for this object. This parameter is optional. If you specify a parent, the values you set in the loc parameter will be relative to the position of that parent. If you omit the parent, the values you set in the loc parameter will be relative to the VR root.

eye_swap

Optional

false

When rendering in stereoscopic mode, this property determines whether or not the images generated for the left and right eye are swapped.

eye_dist

Optional

0.064

When rendering in stereoscopic mode, this property determines the inter-ocular distance to use for offsetting the images generated for the left and right eyes, in meters.

force_offset

Optional

0

When rendering in monoscopic mode, this property allows you to simulate stereoscopic rendering by offsetting the camera to the position of the left or right eye (as defined by the eye_dist property above). Use -1 to force the camera to render from the left eye position, 0 to render from the camera's default position (no effect), or 1 to force the camera to render from the right eye position.

tracker_id

Optional

The name of a input configuration that defines a VR device you want to drive the position of the camera over time. Optional. If you omit this parameter, the camera's position will be static in VR space.

tracker_ch

Optional

-1

When you provide a tracker_id, this parameter specifies the channel of that device that nDisplay will read tracking data from.

Scene Node Configurations

In your configuration file, you can define a hierarchy of scene nodes, each of which represents a transform in 3D space. Anything that you set up in the configuration file that requires a position and rotation in 3D space, such as a camera or a projection screen, can use one of these scene_node configurations as its parent. This can help you to define the spatial relationships between all of the different components of the visualization system.

Like cameras, scene nodes can also be driven by VR tracking devices.

Example configuration:

The following lines define a hierarchy of two nodes, where the child node has an offset of 2 meters in front of its parent.

The following line shows a scene node that is configured to be driven by a VR tracking device:

Parameters:

Parameter

Required?

Default

Description

id

Required

A unique name for this scene node configuration.

loc

Optional

0,0,0

The location of this scene node in VR space, relative to its parent.

rot

Optional

The pitch (P), yaw (Y) and roll (R) angles of the scene node's facing direction relative to its parent, in degrees.

parent

Optional

The name of another scene_node configuration that you want to act as the parent for this scene node. This parameter is optional. If you specify a parent, the values you set in the loc and rot parameters will be relative to the position of that parent. If you omit the parent, the values you set in the loc and rot parameters will be relative to the VR root.

tracker_id

Optional

The name of a input configuration that defines a VR device you want to drive the position of the scene node over time. Optional. If you omit this parameter, the scene node's position and rotation will be static in VR space with respect to its parent.

tracker_ch

Optional

-1

When you provide a tracker_id, this parameter specifies the channel of that device that nDisplay will read tracking data from.

Input Configurations

You define an input section for each device that you need to provide input to the nDisplay system. For example, each camera and each scene_node may optionally be driven by a VR tracking device that you set up in an input section and refer to in the camera or scene_node configuration. Alternatively, you may want to set up trackers, controllers, and keyboards to send generic input events to the Unreal Engine input system, or bind their events and input values to generic nDisplay Blueprint nodes that you can respond to in your Project's gameplay scripts.

You can also use input_setup sections to control the way specific channels, buttons, or keys from these input devices are bound to specific types of input events and values within Unreal Engine.

For an overview of what you can do with nDisplay inputs, see Live Link VRPN.

Example configuration:

This configuration sets up nDisplay to get input from a VRPN location tracking device. Typically this kind of device is mounted to a camera or a viewer's head, or is held by a viewer. You can automatically drive the position of a camera or scene node from the trackerby referring to this input configuration in a camera or scene_node configuration. Or, you can retrieve the value of this tracker in your Project's Blueprint code.

Parameters:

Parameter

Required?

Default

Description

id

Required

A unique name for this input device configuration.

type

Required

The type of this VRPN input device:

tracker for a tracking device.

analog for a device that produces axis data.

button for a device that produces Boolean button data.

keyboard for a standard computer keyboard.

addr

Required

The address of the VRPN server that handles this particular device. The value must match the following format: DEVICENAME@SERVER_ADDRESS:SERVER_PORT where:

DEVICENAME is the VRPN name for this device.

SERVER_ADDRESS is the IPv4 address of the VRPN server.

:SERVER_PORT is the port the VRPN server listens on for incoming connections. This is optional. If you don't provide it, nDisplay uses port 3883 by default.

Devices where type=tracker also accept the following additional parameters:

Parameter

Required?

Default

Description

loc rot

Optional

0,0,0 0,0,0

Similar to other configuration sections, the loc and rot parameters specify position and rotation offsets in local space for this input device. However, for an input device, you typically use these offsets to adjust the root position of a tracking device in VR space to match the location you expect it to be in your scene node hierarchy.

front right up

Required

These parameters match each local axis of the tracker in Unreal (front, right, and up) with the corresponding axis in the tracker's coordinate system. Unreal uses a right-handed, Z-up coordinate system. If your tracker uses a different coordinate system, you can use these parameters to map the tracker's coordinate system to Unreal's. For example, the following line maps the Y axis of the tracker to the front (X) axis in Unreal; the X axis of the tracker to the right (Y) axis in Unreal, and the negative Z axis of the tracker to the up (Z) axis in Unreal: front=Y right=X up=-Z

Devices where type=analog and type=button do not accept any additional parameters.

Input Setup Configurations

Each input_setup configuration section provides additional configuration parameters for a specified input device, typically to bind a channel or key from that device to a generic nDisplay Blueprint input node.

Example configuration:

This configuration sets up the input device with ID controller so that when a button is pressed that generates an event on channel 0, an event is generated from the Input > N Display Events > nDisplay Button 0 node in Blueprint.

This configuration is similar to the above, except that it binds an analog value (typically an axis from a controller) to an nDisplay analog value. You can use the Input > N Display Events > nDisplay Analog 0 node in Blueprint to detect when that controller axis is used, or Input > N Display Values > nDisplay Analog 0 to retrieve the value for the current frame.

Parameters:

Parameter

Required?

Default

Description

id

Required

Refers to the ID of the input configuration that this input_setup section configures. Note that unlike most other sections in the nDisplay configuration file, this id value does not provide an ID for the input_setup section that contains it. Instead, it refers to the ID of an input section defined elsewhere in the file.

ch

Required

Determines the channel of the specified input device that will be bound to the event that you set in the bind setting.

key

Optional

Similar to ch, but used only for input devices where type=keyboard.

bind

Required

Determines the event in Unreal Engine that the channel or key specified above is bound to. This value can be the name of any Blueprint node that you see in the Input category, such as F1, nDisplay F1, nDisplay Button 0, Gamepad Left Thumbstick X-Axis, Gamepad Face Button Top, and so on. If the name contains a space, you must enclose it in double-quotes.

General Configuration

The general configuration line contains parameters that control the overall operation of the nDisplay cluster.

Example configuration:

Parameters:

Parameter

Required?

Default

Description

swap_sync_policy

Optional

0

Determines how output is synchronized over the network.

0: no synchronization (VSync=0).

1: Software swap synchronization (VSync=1).

2: NVIDIA swap lock (only for NVIDIA cards rendering with DirectX11 and DirectX12).

ue4_input_sync_policy

Optional

1

Determines how native input into UE4 is replicated through the nDisplay network.

0: Native UE4 input is processed only by the primary node. No replication is done to other cluster nodes.

1: All native input that the primary node receives is replicated to all other cluster nodes as well.

NVIDIA Configuration

If you use a swap_sync_policy value of 2 in your general configuration section, you can use the parameters in the NVIDIA section to tweak some specific hardware settings relating to frame lock.

Parameter

Required?

Default

Description

sync_group

Optional

1

The sync group to use for frame locking.

sync_barrier

Optional

1

The sync barrier to use for frame locking.

Network Configuration

The network configuration section provides settings that you can use to control timeouts and other settings related to network communication between nDisplay cluster nodes.

You can only have zero or one network section in your nDisplay configuration file.

Example configuration:

Parameters:

Parameter

Required?

Default

Description

cln_conn_tries_amount

Optional

10

When a non-primary cluster node starts up, this setting determines the number of times the node will attempt to connect to the primary PC before it shuts down.

cln_conn_retry_delay

Optional

1000

When a non-primary cluster node starts up, this setting determines the time interval between each successive attempt by the node to connect to its primary PC, in milliseconds.

game_start_timeout

Optional

30000

Sets a time interval that the Unreal Engine application on the primary node wait for all cluster nodes to be ready before it starts the first frame of the game loop and begins rendering to the main window, in milliseconds. This gives all your cluster nodes a chance to connect to the primary PC before rendering begins. During this time, the main window will be black. If, at the end of this time interval, any cluster node has not yet successfully connected to the primary PC, all instances in the cluster will shut down. You may need to raise this value if your cluster takes an unusually long time to initialize.

barrier_wait_timeout

Optional

5000

Sets the barrier timeout for the game and render threads, in milliseconds. This is a barrier timeout to synchronize both game and render threads among cluster nodes. It's used several times within each frame. In other words, this is used at runtime to detect situations where any node becomes unreachable. If this occurs, the state of the cluster state is determined to be invalid, and all nodes shut themselves down.

The cln_conn_tries_amount and cln_conn_retry_delay settings work together to determine the maximum length of time your cluster nodes will try to connect to the primary node at startup. For example, suppose you have cln_conn_tries_amount set to 10, and cln_conn_retry_delay set to 1000 milliseconds. On startup, each node tries to connect to the primary PC. If that connection fails, it waits 1000 milliseconds to try again. If that attempt also fails, it waits another 1000 milliseconds. After ten successive failures, the cluster node quits automatically. As soon as a cluster node makes the connection to its primary PC, the count stops.

Info Configuration

The info configuration line contains optional information about this configuration file: specifically, the latest version of nDisplay and Unreal Engine that this configuration file is known to be compatible with.

Example configuration:

Parameters:

Parameter

Required?

Default

Description

version

Required

The oldest version of Unreal Engine that is compatible with this configuration file.

The number should be understood as the point version that follows 4.. For example, a value of 22 means that the file is compatible with version 4.22 of nDisplay and Unreal Engine.

Do not set this value by hand. The nDisplay Launcher sets it automatically. If you use a configuration file without a version, or where the version in the file is not supported by the current version Unreal Engine you are using, the nDisplay Launcher automatically attempts to update your configuration file to work with the latest version. If it succeeds, it saves the updated configuration to a new file and updates this value to the latest version.

Custom Configuration Parameters

You can include a custom configuration section to provide your own custom key-value pairs to your nDisplay cluster nodes. You can include as many parameters and values as you need on a [cluster] line. You can then retrieve these configuration values at runtime from the nDisplay Blueprint or C++ APIs.

Example configuration:

Configuration File Scene Structure Example

To take a specific example, open the wall_flat_3x2.cfg sample file, which you'll find in your Unreal Engine installation folder under Templates/TP_nDisplayBP/Content/ExampleConfigs. This file defines six projection screens, each of which is to be rendered by a separate physical computer.

It also defines several scene_nodes, which taken together create the following hierarchy:



The relative positions and rotations of the nodes in this hierarchy lay out the arrangement of the camera and the six screens in VR space so that the six projection screens are side-by-side, at a distance of 1 meter from the camera.

Click for full image.

Note that the configuration implies a small space in between each adjacent pair of projection screens, to account for the edges of the monitors rendering the scene.

Toolbar

Components

Screen

Static Mesh

Xform

View Origin

ICVFX Camera

Cluster

Cluster Configurations

Output Mapping

Window Configurations

Viewport Configurations

3D Viewport

You define most aspects of the nDisplay system through a single configuration asset, the nDisplay Config Asset, through the nDisplay 3D Config Editor. This asset defines the computers that make up your cluster network, the characteristics of the windows and viewports you want the Unreal Engine to render on each computer, the display device's topology and configuration, the parts of the virtual world each viewport should render, the types of input devices you want to accept, and more.

This page describes all the settings available in the nDisplay 3D Config Editor.



Click image to enlarge

Toolbar, located in the top left of the Editor.

Components, located on the left below the Toolbar.

Preview, located in the middle of the Editor to the right of the Components panel.

Details, located on the right of the Editor next to the Preview panel.

Cluster, located on the left of the Editor below the Components panel.

Output Mapping, located in the middle of the Editor below the Preview panel.

Compiler Results, located in the bottom right of the Editor below the Details panel.

Toolbar



The Toolbar in the 3D Config Editor shares most of the buttons with the Toolbar in the Blueprint Editor. The following are the two buttons unique to the nDisplay 3D Config Editor:

Import: Imports an nDisplay configuration file (.ndisplay, .cfg) from the local computer.

Export: Exports the nDisplay settings to a configuration file (.ndisplay) on the local computer.

Refer to Toolbar for more details on the other options.

Components



The Components panel defines the physical display, tracking, and in-camera setup for the nDisplay cluster. Adding components to the inherited Root Component is the first step in designing an nDisplay network. You can pick from a predefined list of Displays, Transforms, and default Camera Actors, or add any available UE components.

To use nDisplay with real-world tracking systems, add a Live Link Component to the Components panel. Refer to Live Link for more on how to configure this for your setup.

The following sections describe the nDisplay-specific components that can be added to your setup.

Screen

nDisplay Screen Components are meant to conveniently define flat 2D displays of any size, shape, and resolution. With the referenced view point, the View Origin Component, they define a volume, called the view frustum, that renders a portion of your 3D scene from the camera's or the view point's perspective. The rendered pixels are stored in the Viewport structure, which binds a display, a view point, and a projection policy together. Each of these projection screens need to have the same or similar dimensions in space as the physical screen that you'll use to render it. This setup is compatible with most projection policies.

The pivot point of a screen is always in its exact midpoint.



Static Mesh

When dealing with non-flat displays such as curved LED walls or displays, you can use the Static Mesh Component instead of the Screen Component. This allows you to fully define the shape of your screen using a Static Mesh. This setup is compatible with most projection policies.



Xform

By default, the parent of all objects is the Root Component origin: an arbitrary point in 3D world space where the X, Y, and Z axes have their zero point. You can also configure specific named transforms in 3D space, called Xforms, which can act as parents for one or more components. This can help simplify the spatial layout of your screens, cameras, and other components. Xforms include a visualization mesh and the ability to scale the component in the Details panel.



You can use UE's standard Scene Components instead of Xforms to act as a parent for one or more components, but they will not have the visualization mesh or the ability to control their size in the Details panel.

View Origin

The component for the nDisplay setup that defines the origin for what's rendered in the viewports. Alongside screens or static mesh components defining your displays, they define a view frustum used for rendering 3D content properly. You can have multiple View Origins in your configuration file and bind them to different viewports and displays. The View Origin also contains the settings for Stereo Rendering with nDisplay.



ICVFX Camera

This is a Cine Camera Component where you can reference or link to an external camera placed within your level or project. This component creates the inner frustum necessary for in-camera VFX projects.



Cluster



For each different instance of your Unreal Engine application that you'll use in your nDisplay network, you need to define a Cluster Node. Each Cluster Node is a representation of an application instance, and defines the hostname or IP address of the computer that will run that application instance. You may set up a different physical computer for each Cluster Node, or you may have multiple Cluster Nodes that run on the same host.

Each Cluster Node contains one or more Viewports. Alongside their associated display or static mesh components, they define the window in the 3D world. This window is then used to render your scene from the perspective of any View Origin. The following table describes the elements that can be added to the Cluster.

Nodes

Description

Cluster

Hosts a group of PCs forming one nDisplay cluster. Only one can be created per nDisplay Config Asset.

Host

Representation of a PC with a unique IP address. Customize the color signature to differentiate one PC from another. The color is also used in the Output Mapping panel.

Node (Application Instance)

An instance of UE. Typically there is one application instance per PC but more is allowed for specific use cases. The application instance window is configured in the Details panel for this node.

Viewports

Defines a window in the 3D world. Container for the Projection Policies, Cameras, and target Displays.

Cluster Configurations

To access the Cluster settings:

Select Cluster in the Cluster panel to open its Details panel.



In the Details panel, expand the Configuration section.



In the Cluster settings, you can set the ports, network, and sync policies for the cluster. For more details on changing the Port, Network, and Synchronization settings, see Changing nDisplay Communication Ports and Synchronization in nDisplay.

Output Mapping



The Output Mapping panel effectively maps Viewports defined in the Cluster panel to the 2D UE application windows. In the Output Mapping panel, you can:

View the relationship between the host computer, the Cluster Node (UE application instance), and the viewport.

Visualize, edit, and map 2D viewports inside an application instance window.

Translate and rotate viewports.

Use the following tools, located in the top left corner of the Output Mapping panel in left to right order, to modify the windows and viewports for your nDisplay cluster:



Button

Shortcut

Description

Hamburger Menu

You can enable or disable the following options:

Tint Selected Viewports

Overlap and Bounds

Host Arrangement

Info Bar

W

Enabling this option shows window information, such as the resolution and IP address.

Show Viewports Outside Window

R

Enabling this option shows any viewports that are outside the application window.

Zoom to Fit

Z

Automatically zoom to fit the panel view.

View Scale

Set the scale for the windows and viewports.

Transform Operations

Options to apply transformations to a viewport::

Rotate 90 degrees counterclockwise.

Rotate 90 degrees clockwise.

Rotate 180 degrees.

Flip horizontal.

Flip vertical.

Reset transform.

Positioning Settings

Settings for how nodes are positioned. You can enable or disable the following options:

Allow Cluster Item Overlap

Keep Cluster Nodes inside Hosts

Lock Cluster Nodes in place

Lock Viewports in place

Node Snapping

Options for how nodes snap together. You can enable or disable the following options:

Toggle Adjacent Edge Snapping

Adjacent Edge Padding

Toggle Same Edge Snapping

Snap Proximity

Window Configurations

Each window configuration defines a set of properties for the main window of an instance of your Unreal Engine application. You use it to configure details like the starting size and placement of the window when nDisplay launches your application, and whether or not the window should take up the full screen.

You also provide one or more viewport configurations, which identify specific areas within the main application window that nDisplay will fill with renderings of your scene.

In the nDisplay 3D Config Editor, you can configure the window by selecting the Cluster Node in the Output Mapping panel and modifying its size, or changing the settings in the Window section of the Cluster Node's Details panel.

With Output Remapping, you can specify how Viewports are rendered in terms of position and scale within the Application Window. Output Remapping extends this functionality by allowing custom transforms such as rotation that are defined in the provided mesh's UV channel.

For example, you can translate, rotate, and scale parts of the output image so that they appear in different regions of the application window.



Click image to enlarge

There are three ways to enable this feature:

Assigning a Static Mesh which contains a planar geometry with a custom UV mapping.

Assigning an external .obj file that contains a planar geometry with a custom UV mapping.

Select a viewport in the Output Mapping panel and choose a Transform Operation.

To apply output remapping, you can provide either a Static Mesh or an external .obj file that contains a planar geometry with a custom UV mapping set up. nDisplay will use the UV channel set for your plane to determine how the output image is mapped to each part of the application window.

The input mesh can be of unit size and will be applied to the whole application window. This is because nDisplay uses the final render buffer as an input GPU Texture Sampler to a final post process shader applied to the mesh with an arbitrary UV space.



Click image to enlarge

When you apply rotation to the nDisplay render with an external file, you must manually resize the Application Window resolution to accommodate for the rotation, otherwise the render will appear stretched.

To enable Output Remap in your Project:

In the Cluster panel, select a Node to open its Details panel.

In the Details panel, expand the Output Remapping section.



Enable Output Remapping.



Choose which Data Source you want to use: Static Mesh or External File.

For Static Meshes: Browse to a Static Mesh in your project.



For External Files: Enter the path on disk to an .obj file.



In order to use a Static Mesh with Output Remapping, Allow CPUAccess must be enabled for the Static Mesh. To do this:

Double-click the Static Mesh in the Content Browser to open it in the Static Mesh Editor.

In the Details panel, expand General Settings > Advanced.

Enable Allow CPUAccess.

Save the Static Mesh Asset to keep your changes.



You can transform viewports within the Output Mapping panel to modify how they'll be rendered within the application window.



The left two viewports were rotated 90 degrees clockwise and scaled down to fit the space.

To quickly apply either a rotation or flip transform to a viewport in your project:

Select the viewport either in the Cluster panel or in the Output Mapping panel.

In the Output Mapping panel, select Transform and choose the operation you want to apply.

Alternatively, right-click on a viewport to open the contextual menu and select the desired Transform.



Viewport Configurations

Each window configuration refers to one or more viewport configurations, each of which defines a rectangular area of the window that nDisplay should fill with a rendered view of the scene. Usually, a viewport starts at the upper left corner of the application window, and its width and height are set so that they fill the parent window.

In some cases you may need to offset, scale, or rotate the viewport within its parent application window. For example, LED processors sometimes have custom 2D mapping programmed within a larger canvas. With the nDisplay Output Mapping panel you can place or rotate your viewports so they fit within the region expected by the display devices or processors. You can load a custom background image per application window to help with viewport placements.

If you rotate or translate your displays with the OS configuration, you can use the Output Mapping tools to match that arbitrary rotation and location as well.

Each viewport configuration described above refers to a projection policy, which is responsible for defining how the image is rendered within the viewport. Unreal automatically attaches the whole cluster to the current camera's position so that baked or interactive camera animations are made possible. You can disable the camera for your needs.

In most common 2D situations, you will use the Simple projection type, which renders the virtual world with a view frustum defined by the display configuration and the View Origin. Those rendered pixels are effectively stored and defined by the attached viewport.

More complex setups, such as for in-camera VFX or when the displays are curved or an arbitrary shaped surface, you can use the Mesh or MPCDI projection policies.

Other industry-specific projection types, such as EasyBlend, VIOSO, and DomeProjection, are targeting display surfaces lit by projectors and use other methods to define or adapt the rendered content for the viewport. They may introduce additional corrections or apply custom rendering techniques before rendering the image to the rectangular viewport. For example, the projection may squash, stretch, or distort the image so that it will look natural when displayed on a curved or an arbitrary shaped surface. They can also apply required color or gamma curve corrections for a continuous rendered image.

For more details on projection types and their configurations, see Projection Policies in nDisplay.

With TextureShare, you can share the viewport texture with another application, or receive a texture from another application and display it in the specified viewport.

To enable texture sharing for a viewport:

In the 3D Config Editor, select the viewport to view its Details panel.

In the Details panel, enable Share Viewport.



You can now use the viewport in your external application to send or receive a texture.

Refer toTexture Share for more details on the sync settings and how to set up your external application.

3D Viewport



With the 3D Viewport, you can visualize the display, camera, and tracking setup of your nDisplay cluster. This panel is a 3D editing tool that provides the means for you to visualize and edit the following:

Display topology and projection policies.

The tracked camera location.

The tracked user location.

Use this view to ensure:

Your displays are properly set up.

The preview render looks correct from the camera vantage point.

Viewports are properly mapped to the screens.

nDisplay Overview

nDisplay Quick Start

nDisplay Configuration File Reference

Multi-User Editing in Unreal Engine

Unreal Insights

Set the nDisplay Launch Assets

Settings and Options

Quick Launch Options Menu

Project Settings

When you're creating virtual production projects in Unreal Engine, it can be helpful to test the project's appearance and functionality on your local hardware, before launching the project on a virtual production stage. The nDisplay Quick Launch Local Tool is designed to quickly and efficiently launch your virtual production project without requiring a full virtual production stage environment. This gives you a safe, manageable environment for testing and debugging.

This document provides an example workflow of how you can use the Quick Start Local Tool to launch virtual production projects in Unreal Engine.

Enable, both the nDisplay and nDisplay Launch Plugins. In the Menu Bar, navigate to Edit > Plugins > Virtual Production, and locate the nDisplay and nDisplay Launch plugins. Alternatively, you can use the Search Bar.





Enable both plugins and restart the editor.

You must have a functional virtual production project containing at least a Config File with a working Cluster Display node. If you do not have one, you can use the nDisplay Template project.

Set the nDisplay Launch Assets

After installing the nDisplay and nDisplay Quick Launch plugins, you can now select the nDisplay Config assets, and cluster nodes you will use to launch and render the virtual production project.

To set the nDisplay Launch Assets:

In the Quick Launch Options Menu, ensure your Config File is toggled under Configuration, and that the correct Cluster Node is selected under Nodes > Select nDisplay Nodes.For this workflow example, the Config File and Cluster Node are using the default asset names, and are nDisplayConfig and Node_0 respectively.



In multi-display instances, using multiple Cluster Nodes, you can toggle each node independently in the Select nDisplay Nodes menu.



Any selected display Nodes are rendered at their native resolution across your desktop's display. If the combination of nodes' resolution is greater than the extent of your monitors' resolution, some nodes may be rendered beyond your monitors' field of view.

After ensuring the correct Config File and Nodes are selected, Save your project. You can now launch nDisplay using the nDisplay Launch button in the toolbar.



To improve your project's render performance, you can enable the Close Editor on Launch option for the Quick Launch Options Menu.



Running a single nDisplay node saves computational resources when you are testing a project.

When working with multi-user projects, the Multi-User server launches automatically when you launch a project with the nDisplay launch tool. You can also track your projects data and performance, for debugging purposes by toggling Enable Unreal Insights in the nDisplay Quick Launch Options Menu.For more information about setting up a Multi-User project, refer to the Virtual Camera Multi-User Quick-Start Guide documentation. For a technical reference guide on how multi-user server sessions are created, reference to the nDisplay Multi-User Technical Reference.

Settings and Options

These are the settings for the nDisplay Launch plugin.

Quick Launch Options Menu

Using the drop down menu of the nDisplay Launch button, you can manage and set the Config File, Cluster Nodes, and nDisplay Quick Launch behaviors.



Setting

Description

Configuration

Select which Config File to use when launching the nDisplay render.

Connect to Multi-User

When enabled, the nDisplay Quick Launch Tool attempts to connect to a Multi-User editing environment. If a Multi-User session is not set in the nDisplay Launch Project Settings, or Unreal Engine cannot connect to the server, the nDisplay Quick Launch tool will start the Multi-User server.

To manually set a session name, see the Multi-User property section in the Advanced Settings.

Enable Unreal Insights

When enabled, Unreal Insights debugging tools reads and reports on the nDisplay render.

The Unreal Insight plugin must be installed to use this feature.

To set the file directory and the behaviors of the Unreal Insights report, use the Unreal Insights property section in the Advanced Settings.

Close Editor on Launch

When enabled, the Unreal Editor closes when launching the nDisplay render. Closing the editor can reduce your computer's computational workload and increase the render's performance.

We recommend that you launch nDisplay with the fewest possible render nodes to reduce the computational load for a single machine.

Advanced Settings

You can access the nDisplay Launch tools Advanced Settings. You can also access these settings by navigating in the Menu Bar to Edit > Project Settings and selecting the nDisplay Settings under the Plugins section.

Project Settings

These are the nDisplay Launch plugins settings. You can access these settings using the Advanced Settings menu option from the Quick Launch Options Menu. Alternatively you can access the nDisplay Launch settings in the Menu Bar by navigating to Edit > Project Settings and selecting the nDisplay Launch settings under the Plugins section.



Setting

Description

Close Editor on Launch

When enabled, the Unreal Engine Editor will close when launching the nDisplay render. Closing the editor can reduce your computer's computational workload, and increase the render's performance.

Connect to Multi User

When enabled, the nDisplay Quick Launch Tool will attempt to connect to a multi-user editing environment.

To set a specific Multi-User session name to connect to, see the Explicit Session Name property.

Explicit Session Name

Give your session a name to be used when connecting to a Multi-User editing environment.

If this field is left empty, the Editor automatically generates a name.

Enable Unreal Insights

When enabled, Unreal Insights debugging tools reads and reports on the nDisplay render.

The Unreal Insight plugin must be installed to use this feature.

Use the Unreal Insights property section in the Advanced Settings to set the file directory and the behaviors of the Unreal Insights report.

Enable Stat Named Events

Enables the Unreal Insight Stat Named Events feature.

Explicit Trace File Save Directory

Set a directory path to store the Unreal Insights Trace Files. If empty, Unreal Insights automatically stores the files locally.

If you want to store the Trace Files locally, the Unreal Insights plugin must be installed and launched.

In order to specify a socket to connect to, use Command Line Arguments.

Console Variables Preset

Set a Console Variables Asset to apply by default during an nDisplay launch.

All available commands and variables contained within the set Console Variables Asset will be executed before any variables and commands under the Additional Console Variables and Additional Console Commands properties.

For more information on managing and editing Console Variables, refer to the Console Variable Editor documentation.

Additional Console Variables

Specify and set additional console variables. These variables are defined and set after any present in the Console Variable Asset property.

Setting additional console variables is useful for overriding variables in your defined Console Variables Asset.

Additional Console Commands

Specify and set additional console commands. These commands are executed after any present in the Console Variable Asset property.

Setting additional console commands is useful for overriding variables in your defined Console Variables Asset.

Command Line Arguments

Set a list of Switchboard command line arguments, that the nDisplay Launch tool will execute, mimicking the Switchboard application's functionality, on a single workstation.

Do not include an en-dash ("-") in any commands.The editor automatically adds a dash when calling the command.

If your workstation possesses more than 1 GPU, you can use the following command to run the nDisplay Launch tool using multiple GPUs to render your project.

MaxGPUCount=2

If you do not specify this manually, nDisplay will not recognize the second GPU, and operate as a 1 GPU workstation.

Log File Name

Set the name of the log file Unreal Insights writes logs about the launched node in.

If you do not specify a name, the resulting log file will be called the same name as the node.

Logging

Set which logs should be recorded in the generated log file and the style of verbosity for recording logs.

You can add a new log using (+) Add.

Select the log Category by typing the log's type in the provided field.

Select the verbosity from the associated Verbosity Level drop down menu.

Multi-User Editing in Unreal Engine

nDisplay Quick Launch Local Tool

nDisplay Overview

nDisplay Quick Start

nDisplay Configuration File Reference

Multi-User Connection Logic

When launching multi-user editing sessions using nDisplay, Unreal Engine automatically creates a local server to host multiple editor users simultaneously.

In the following document you can read about the multi-user server connection logic for launching virtual production projects using nDisplay in Unreal Engine.

Multi-User Connection Logic

When launching a virtual production project using nDisplay for the first time, you can use the Quick Launch tool to automatically launch a local server multiple users can connect to.

When launching your project using nDisplay for a second time, Unreal Engine automatically reconnects to the existing local server and reuses the existing multi-user editing session if the editor is already operating in a session. If the editor is not operating in an nDisplay multi-user editing session, Unreal Engine creates a new multi-user editing session on the local server.

You can also build your own custom multi-user server to host an nDisplay multi-user editing session, that multiple users can connect to locally or using a network connection.

When attempting to join a network-based multi-user server, Unreal Engine checks if the editor is already in a multi-user editing session. If the editor is operating in an editing session, Unreal Engine joins the generated multi-user server and session. If the editor is not already operating within an nDisplay multi-user editing session, Unreal Engine closes the local multi-user server, ignores the network-based multi-user server, and launches a new server locally.

You can use the following diagram to better understand the Unreal Engine Multi-User (MU) connection behavior:



For more information about getting started using multi-user editing sessions, refer to the Multi-User documentation.

For more information about launching virtual projects using nDisplay, see the nDisplay documentation.

nDisplay Root Actor Settings

Viewports

Viewport Overscan Settings Per Viewport

In-Camera VFX

Color Grading

Per-Viewport Color Grading

OCIO

Per-Viewport OCIO Overrides Array Elements

Light Cards

Editor Preview

In-Camera VFX Camera Component Settings

In-Camera VFX

Inner Frustum Overscan

Camera Motion Blur

Inner Frustum Color Grading

OCIO

Per-Node OCIO Overrides

Chromakey

Texture Replacement

With the nDisplay Root Actor, you can modify its settings while the nDisplay cluster is launched and rendering on all the nodes. This allows you to quickly make changes to the nDisplay renders without needing to modify the nDisplay configuration through the nDisplay 3D Config Editor.

Typically, once you create your nDisplay topology, you won't need to modify it. Since the nDisplay Root Actor is an instance of the nDisplay Configuration Asset, the nDisplay Root Actor settings cover the cases where you'll want to change how the nDisplay renders look on specific nodes without changing the configuration asset itself.

To create the nDisplay Root Actor, drag the nDisplay Config Asset into the level. This creates a preview of the nDisplay Cluster in the project so you can see how your content looks in your clustered rendering setup.

This page covers all the settings you'll want to use on the nDisplay Root Actor while you're either previewing in the Editor, or in the live environment with your physical nDisplay cluster.

nDisplay Root Actor Settings

To access the nDisplay Root Actor's settings, select your nDisplay Root Actor in the World Outliner to open its Details panel.

The following sections describe the settings for the nDisplay Root Actor.

Viewports

Parameter

Description

Viewport Screen Percentage Multiplier

This parameter defines the resolution for the viewport. 1.0 means full resolution.

In complex and large clustered rendering setups, we recommend lowering this value to improve the Editor's frame rate during preview. Lowering the value lowers the resolution of what's displayed.

Viewport Screen Percentage

Dropdown section that shows all viewports in the nDisplay cluster. Set the Viewport screen percentage per viewport. The Viewport Screen Percentage Multiplier is combined with the per-viewport screen percentage setting to determine the resolution.

This is especially useful for viewports that are used only for lighting during in-camera VFX shoots. You will typically want to lower the resolution for the ceiling displays, unless you need high quality reflections from them in your scene.

Viewport Overscan

With Viewport Overscan enabled, the Engine will render a larger frame than specified for the viewport, to achieve continuity across displays when using post-processing effects. See Overscan Support for more details on what is supported with overscan in nDisplay.

Expand the dropdown to show all viewports in the nDisplay cluster, and change overscan settings per viewport. See Viewport Overscan Settings Per Viewport below for the per-viewport options.

Freeze Viewports

Freezes rendering for viewports displaying the outer frustum. Disabling this option can help to improve performance.

Content Hidden from Entire Cluster

Content added to the arrays here will not show up on any display in the cluster, and will not appear in the inner frustum if it's enabled. Content can be added by specifying Layers, or Actors individually.

This is useful for cases when you need an Actor in your project but don't want it displayed through nDisplay. For example, if you're using an Actor for tracking during an in-camera VFX shoot and don't want it displayed but need it for compositing with Composure.

Content Hidden from Viewports

Content added to the arrays here will not show up on the outer frustum, but will appear in the inner frustum if it's enabled. Content can be added by specifying Layers, or Actors individually.

Parameter

Description

Enable

Enable or disable overscan for the viewport.

Mode

Specify the units for overscan. Options include:

Percentage

Pixels

Adapt Resolution

When enabled, the resolution of the rendering output increases based on the settings below.

When disabled, the rendering output is scaled from the original resolution of the viewport to reach the size in the settings below.

This option is enabled by default.

Left

If overscan is enabled, increases the resolution for the left side of the render by this amount. Units are in pixels or percent, depending on which Mode is selected.

Right

If overscan is enabled, increases the resolution for the right side of the render by this amount. Units are in pixels or percent, depending on which Mode is selected.

Top

If overscan is enabled, increases the resolution for the top of the render by this amount. Units are in pixels or percent, depending on which Mode is selected.

Bottom

If overscan is enabled, increases the resolution for the bottom of the render by this amount. Units are in pixels or percent, depending on which Mode is selected.

In-Camera VFX

Parameter

Description

Enable Inner Frustum

Enable this option if you want to use the inner frustum with your nDisplay setup. Disabling this option overrides the inner frustum settings on the individual ICVFX cameras.

When you have multiple cameras, disabling this option disables the inner frustum for all of them.

Inner Frustum Priority

This list determines which camera's inner frustum is rendered on top, when you have multiple ICVFX cameras and their inner frustums overlap on the display. The priority is determined by the order of the list, with the first camera as the highest priority.

Color Grading

This section describes the specific settings available for color grading in nDisplay. See Color Management in nDisplay for more information on how to use color grading in your project.

Parameter

Description

Enable Entire Cluster Color Grading

When enabled, applies the color grading settings from the Entire Cluster section to all the nDisplay viewports and inner frustums.

The color grading is only applied to nDisplay renders. It will not change the color of the project in the Editor, or the renders from Movie Render Queue.

Entire Cluster

Expand the section to view the color grading options. See Color Correction for details on the color grading options exposed.

Per-Viewport Color Grading

Refer Per-Viewport Color Grading for details.

You can apply color grading settings to an individual viewport or to groups of viewports. Add an Array element and modify the settings described in the following table to apply color grading to specific viewports.

Parameter

Description

Enable Viewport Color Grading

When enabled, applies the color grading settings from the Color Grading section to all viewports defined in Apply Color Grading to Viewports.

The color grading is not applied to inner frustums that appear on the nodes, if they're enabled. To apply color grading only to an inner frustum, see the Color Grading section of the ICVFX Camera settings.

Include Entire Cluster Color Grading

When enabled, applies the color grading settings defined in Entire Cluster before applying the settings defined in the Color Grading section to the specific viewport.

When disabled, the color grading settings defined in Entire Cluster will not be applied to the viewport. The settings defined in Color Grading will still be applied to the viewport if Enable Viewport Color Grading is enabled.

Color Grading

Expand the section to view the color grading options. See Color Correction for details on the color grading options exposed.

Apply Color Grading to Viewports

The color grading settings can be applied to multiple viewports. Add an Array element for each viewport to which you want to apply these color grading settings.

The list of viewports shown in the dropdown is the same as the list defined in the nDisplay Config Asset.

OCIO

This section describes the specific settings available for color management with OpenColorIO (OCIO) in nDisplay. See Color Management in nDisplay for more information on how to use OpenColorIO in your project.

Parameter

Description

Enable Viewport OCIO

When enabled, applies the OCIO configuration to all nDisplay viewports.

The configuration is not applied to inner frustums that appear on the nodes, if they're enabled. To apply an OCIO configuration only to an inner frustum, see the OCIO section of the ICVFX Camera Component settings.

The OpenColorIO configuration set here is only applied to nDisplay renders. It will not change the color of the project in the Editor, or the renders from Movie Render Queue.

If you already have an OCIO configuration applied to your project, this will override those settings on the nDisplay viewports.

All Viewports Color Configuration

Expand this section to set the Configuration Source, Source Color Space, and Destination Color Space. See Color Management with OpenColorIO for more details on using OpenColorIO in your project.

Per-Viewport OCIO Overrides

You can apply OCIO settings to an individual viewport or groups of viewports. Add an Array element and modify the settings described in Per-Viewport Array Elements to apply color grading to specific viewports.

Parameter

Description

Enable Per-Viewport OCIO

When enabled, applies the OCIO configuration from the Viewport OCIO section to all viewports defined in Apply OCIO to Viewports.

If you already have an OCIO configuration applied to your project or all your nDisplay viewports, this will override those settings on the nDisplay viewports defined in Apply OCIO to Viewports.

The configuration is not applied to inner frustums that appear on the nodes, if they're enabled. To apply OCIO configurations only to an inner frustum, see the OCIO section of the ICVFX Camera Component settings.

Viewport OCIO

Expand this section to set the Configuration Source, Source Color Space, and Destination Color Space. See Color Management with OpenColorIO for more details on using OpenColorIO in your project.

Apply OCIO to Viewports

The OCIO settings can be applied to multiple viewports. Add an Array element for each viewport to which you want to apply these OCIO settings.

The list of viewports shown in the dropdown is the same as the list defined in the nDisplay Config Asset.

Light Cards

Parameter

Description

Enable Light Cards

When enabled, all Light Cards defined in Light Cards Content will be displayed in the nDisplay viewports.

Blending Mode

There are two modes for how Light Cards are rendered when the inner frustum overlaps them:

Lightcard Over Frustum: The Light Card renders on top of the inner frustum when they overlap.

Lightcard Under Frustum: The Light Card is hidden by the inner frustum when they overlap.

Light Cards Content

Light Cards can be added by specifying Layers, or Actors individually.

Editor Preview

Parameter

Description

Enable Editor Preview

When enabled, a preview of the Unreal Project appears on the nDisplay Root Actor's meshes in the Level Viewport. The Color Management options and other settings defined in the nDispay Root Actor will appear in the preview.

This option is enabled by default. We recommend disabling this option when you're not previewing in the Level Viewport and need to improve performance.

Preview Screen Percentage

This parameter defines the value by which the preview texture's resolution is scaled.

Enable Post Process

When enabled, post process settings are applied to the nDisplay preview in the Level Viewport.

Freeze Editor Preview

When enabled, the viewport renders for the nDisplay preview freezein the Level Viewport.

Enable Camera Frustums

When enabled, visualizations for the inner frustum appear with the ICVFXCamera as the origin.

Camera Frustum Distance

This parameter defines the maximum distance where the inner frustum can be rendered.

Preview Node

This parameter defines which nodes you want to preview in the Level Viewport. Options are None, All, or specific Cluster Nodes in your nDisplay cluster.

Render Mode

This parameter defines the Render Mode for the nDisplay cluster preview. Options include:

Mono

Stereo: Side By Side

Stereo: Top Bottom

See Stereoscoping Rendering in nDisplay for more details on the options.



Advanced



Tick Per Frame

This parameter defines the time interval between updates for the preview in the Editor.

Viewports Per Frame

This parameter defines how many viewports are rendered per frame for the preview in the Editor. If this parameter is set to less than the number of viewports in the cluster, then the number of preview viewports specified in this parameter are updated each frame.

For example, if Viewports Per Frame is 1 and your cluster has 2 viewports (VP0, VP1), then the preview viewports are updated over multiple frames: VP0 on frame 0, VP1 on frame 1, VP0 on frame 2, and so on.

If Viewports Per Frame is set to a number greater than the number of viewports in the cluster, then all the preview viewports are updated once per frame. For larger clusters, updating every viewport in the preview can be expensive, so you can adjust this parameter to improve performance in the Editor.

Preview Texture Max Size

This parameter defines the maximum dimension of textures for preview. By default, the value is 2048. When you have large preview viewports, you can use less memory by changing this value.

In-Camera VFX Camera Component Settings

To access the nDisplay Root Actor's ICVFX Camera Component settings:

Select your nDisplay Root Actor in the World Outliner to open its Details panel.

In the nDisplay Root Actor's Details panel, select the ICVFX Camera Component in the Components section to open its Details panel.

The following sections describe the settings for the ICVFX Camera Component of the nDisplay Root Actor.

In-Camera VFX

Parameter

Description

Enable Inner Frustum

When enabled, shows the inner frustum from this ICVFX camera in the nDisplay cluster.

Cine Camera Actor

When you assign a Cine Camera Actor to this parameter, that camera is used to render the inner frustum instead of the default nDisplay camera.

Inner Frustum Screen Percentage

This parameter defines the percent multiplier for the resolution of the inner frustum. 1.0 is the same as full resolution.

Inner Frustum Overscan

Refer to Inner Frustum Overscan for more details.

Soft Edge

These parameters define how much of the edges are feathered. You can set the Top and Bottom, and the Sides of the edges separately.

It can be useful to feather the inner frustum's edges so its hard line doesn't appear in a reflection during an in-camera VFX shot.

Inner Frustum Border

These parameters create a border around the inner frustum. You can set Border Width and Border Color to customize the border's appearance.

Inner Frustum Rotation

This rotation offset is applied to the inner frustum.

Inner Frustum Offset

This translation offset is applied to the inner frustum.

Mipmapping

When the inner frustum is smaller, in terms of LED wall pixels, than the resolution you configure nDisplay to render, mipmaps can be generated to create a nicer small inner frustum. Generating mipmaps for the inner frustum might affect performance slightly.

To use mipmapping on your inner frustum, enable Auto Generate Mips. You can choose which mips sampler filter to use:

Nearest

Bi-linear

Tri-linear

Default (from Texture Group)

Auto Generate Mips and the Tri-linear sampler filter are selected by default for the ICVFX camera.

Camera Motion Blur

See Camera Motion Blur for more.

Content Hidden from Inner Frustum

Any Actors added here will not display in the inner frustum. Content can be added by specifying Layers, or Actors individually.

You can specify inner frustum overscan per direction. For in-camera-VFX scenarios, this feature can be useful for extending the inner frustum in specific directions to accommodate the latency of moving cameras or reducing the rendered size of the frustum if it's partially obscured by the set. Its resolution can optionally auto-adapt to maintain the same visual quality. Refer to Overscan Support for details on which features work with overscan.

Parameter

Description

Estimated Overscan Resolution

This parameter displays the resolution that is being sent to the output, which may or may not be scaled. When you change the overscan settings below, this resolution reflects the changes.

For example, if the render target resolution is 3840 x 2160, and Overscan Multiplier is set to 2, then Estimated Overscan Resolution will be 7680 x 4320.

Inner Frustum Resolution

This parameter displays the resolution of the render target, which is defined in the nDisplay Config Asset. When Adapt Resolution is enabled, this resolution reflects the aspect ratio changes made by the overscan settings below.

Enable Inner Frustum Overscan

When enabled, overscan is applied to the inner frustum.

Adapt Resolution

When enabled, the resolution of the render target changes based on the overscan settings below.

When disabled, the rendering output is scaled from the original resolution of the viewport to reach the size in the settings below.

This option is disabled by default.

Overscan Multiplier

Multiplies the field of view for the ICVFX camera by this value. This can increase the overall size of the inner frustum to help provide a buffer against latency when moving the camera.

Overscan Units

Specify the units for overscan. Options include:

Percentage

Pixels

Left

If overscan is enabled, increases the resolution for the left side of the render by this amount. Units are in pixels or percent, depending on which Overscan Units is selected.

Right

If overscan is enabled, increases the resolution for the right side of the render by this amount. Units are in pixels or percent, depending on which Overscan Units is selected.

Top

If overscan is enabled, increases the resolution for the top of the render by this amount. Units are in pixels or percent, depending on which Overscan Units is selected.

Bottom

If overscan is enabled, increases the resolution for the bottom of the render by this amount. Units are in pixels or percent, depending on which Overscan Units is selected.

The settings for specifying motion blur in the nDisplay render. Refer to Camera Motion Blur for how to set up your projects to work with motion blur.

Parameter

Description

Motion Blur Mode

Specify the motion blur mode for the inner frustum and how it corrects for the motion of the camera. Blur due to camera motion will be incorrectly doubled in the physically exposed image if there is already camera blur applied to the inner frustum.

There are three modes:

ICVFX Camera Blur Off: Subtracts blur due to motion of the ICVFX camera relative to the nDisplay root, but preserves blur from both object motion and movement of the nDisplay root, which can be animated to represent vehicular motion through an environment.

ICVFX Camera Blur On: Allows blur from camera motion. This option should not normally be used for camera shooting, but may be useful for diagnostic purposes.

All Camera Blur Off: Subtracts blur due to all global motion of the ICVFX camera, but preserves blur from object motion.

ICVFX Camera Blur Off is selected by default.

Translation Scale

This parameter defines how much translation should be scaled for generating motion blur.

Motion Blur Settings Override

Enable Settings Override

If enabled, override the overall motion blur settings that would otherwise come from the current post-process volume or CineCamera.

Amount

This parameter defines the strength of the motion blur.

Max

This parameter defines the max distortion caused by motion blur, specified by screen width percentage.

Per Object Size

This parameter defines the minimum projected screen radius for a primitive to be drawn in the velocity pass. This parameter is specified in terms of screen width percentage. The smaller the number, the more draw calls there are.

The default value is 4%.

Inner Frustum Color Grading

Parameter

Description



All Nodes



Enable All Nodes Color Grading

When enabled, applies the color grading settings from the Color Grading section to the inner frustum.

The color grading is only applied to nDisplay renders.

Include Entire Cluster Color Grading

When enabled, applies the color grading settings from the Entire Cluster section of the nDisplay Root Actor to the inner frustum.

Color Grading

Expand the section to view the color grading options. See Color Correction for details on the color grading options exposed.



Per-Node Color Grading



Enable Per-Node Color Grading

When enabled, applies the color grading settings from the Color Grading section to the inner frustum when it appears on the cluster nodes defined in Apply Color Grading to Nodes.

The finest granularity of control for the inner frustum in the nDisplay cluster is per-node. This is because the inner frustum can be shared across multiple viewports when mGPU is enabled.

The color grading is only applied to nDisplay renders.

Include Entire Cluster Color Grading

When enabled, applies the color grading settings from the Entire Cluster section of the nDisplay Root Actor to the inner frustum when it appears on the cluster nodes defined in Apply Color Grading to Nodes.

Include All Nodes Color Grading

When enabled, applies the color grading settings from the All Nodes section of the ICVFX Camera Component to the inner frustum when it appears on the cluster nodes defined in Apply Color Grading to Nodes.

Color Grading

Expand the section to view the color grading options. See Color Correction for details on the color grading options exposed.

Apply Color Grading to Nodes

The color grading settings can be applied to multiple cluster nodes. Add an Array element for each cluster node to which you want to apply these color grading settings.

The list of cluster nodes shown in the dropdown is the same as the list defined in the nDisplay Config Asset.

OCIO

Parameter

Description

Enable Inner Frustum OCIO

When enabled, applies the OCIO configuration from the All Nodes Color Configuration section to the inner frustum.

If you already have an OCIO configuration applied to your project, this will override those settings for the inner frustum.

The OCIO configuration is only applied to nDisplay renders.

All Nodes Color Configuration

Expand this section to set the Configuration Source, Source Color Space, and Destination Color Space. See Color Management with OpenColorIO for more details on using OpenColorIO in your project.

Per-Node OCIO Overrides

The OCIO settings can be applied to multiple cluster nodes. Add an Array element for each cluster node to which you want to apply these OCIO settings.

The list of cluster nodes shown in the dropdown is the same as the list defined in the nDisplay Config Asset.

The finest granularity of control for the inner frustum in the nDisplay cluster is per-node. This is because the inner frustum can be shared across multiple viewports when mGPU is enabled.

Parameter

Description

Enable Per-Node OCIO

When enabled, applies the OCIO configuration from the Inner Frustum OCIO section to the inner frustum when it appears on the cluster nodes defined in Apply OCIO to Nodes.

If you already have an OCIO configuration applied to your project or to the inner frustum for all cluster cluster nodes, this will override those settings for the inner frustum when it appears on the cluster nodes defined in Apply OCIO to Nodes.

The OCIO configuration is only applied to nDisplay renders.

Inner Frustum OCIO

Expand this section to set the Configuration Source, Source Color Space, and Destination Color Space. See Color Management with OpenColorIO for more details on using OpenColorIO in your project.

Apply OCIO to Nodes

The OCIO configuration can be applied to multiple cluster nodes. Add an Array element for each cluster node to which you want to apply these settings.

The list of cluster nodes shown in the dropdown is the same as the list defined in the nDisplay Config Asset.

Chromakey

Parameter

Description

Enable Inner Frustum Chromakey

When enabled, turns the entire inner frustum the solid color set in Chromakey Color and applies Chromakey Markers if they're enabled.

This setting is typically used to apply a green screen and tracking markers to the display during an in-camera VFX shoot. Since only the inner frustum changes, the outer frustum can continue to be used for reflections while filming.

Chromakey Color

This parameter defines the color used for chroma keying.

Chromakey Markers

Enable Chromakey Markers

When enabled, tracking markers are generated and applied to the inner frustum's chroma key content.

Marker Color

This parameter defines the color of the tracking marker.

Marker Tile RGBA

This parameter defines the texture used for the tracking marker. A texture with a plus icon is assigned by default.

Marker Scale

This parameter defines the size of the tracking marker.

Marker Tile Distance

This parameter defines the distance between tracking markers.

Marker Tile Offset

This parameter defines an offset applied to the tracking markers' default location.

Custom Chromakey

Use Custom Chromakey

When enabled, only turns the content defined in Custom Chromakey to the Chromakey Color and applies Chromakey Markers when the content appears in the inner frustum. The content is hidden in the outer frustum and will only appear in the inner frustum.

This setting is for green screen halo.

Custom Chromakey Content

Content can be added by specifying Layers, or Actors individually.

Post Process Blur

You can choose to apply a blur to the content defined in Custom Chromakey Content.

There are three modes you can set Post Process Blur to:

None

Gaussian

Dilate

For Gaussian and Dilate, you can set the Kernel Radius and Scale to change the look of the effect.

Texture Replacement

Parameter

Description

Enable Viewport Texture Replacement

When enabled, replaces the inner frustum view with the texture defined in Source Texture. The texture moves with the camera.

The replacement won't be visible if the entire inner frustum is used for chroma keying.

Source Texture

The texture applied to the inner frustum when Enable Viewport Texture Replacement is checked.

Use Texture Crop

When enabled, only uses the rectangle defined in Texture Crop of the Source Texture.

Texture Crop

Texture Crop Origin

Defines the upper left corner of the rectangle using the X and Y parameters.

Texture Crop Size

Defines the width and height of the rectangle from the starting point using the W and H parameters.

You don't have to use the nDisplay Template Project in order to render through nDisplay. If you already have a different Project set up with your content, you can adjust that Project so that it can take advantage of nDisplay.

To set up an existing Project to use nDisplay:

Enable the nDisplay plugin.In the Unreal Editor, choose Edit > Plugins from the main menu. Search for "nDisplay", and check the Enabled checkbox.

Click for full image

Enable nDisplay for your Project.Choose Edit > Project Settings from the main menu, and find the Plugins > nDisplay section. Check the Enabled checkbox.

Click for full image

Restart the Unreal Editor and reopen your Project.

Drag and drop the previously-generated config file (.cfg or .ndisplay) into your Content Browser. It will be automatically converted to a UAsset. Alternatively, add a new nDisplay Config UAsset, found in the nDisplay media category in the Content Browser

Continue on with the rest of the setup instructions in the Quick Start Guide.

Rendering to Multiple Displays with nDisplay

Creating a Project from the Template

Template Features

The nDisplay template is the starting point for creating complex arrangements of physical displays for live performances. The template provides a variety of common nDisplay configurations to get you started.

Creating a Project from the Template

Launch Unreal Engine.

Select the Film, Television, and Live Events template category.



Click image to expand

Click nDisplay, choose whether to include starter content and whether to enable ray tracing, and select the path and name for your project. click Next.



Click image to expand

Click Create.



Click image to expand

Template Features

The following example configurations are available in the template in the ExampleConfigs folder:

NDC_Basic



Click image to expand

NDC_Cave



Click image to expand

NDC_CaveUnwrap



Click image to expand

NDC_DualMonitor



Click image to expand

NDC_MultiViewports



Click image to expand

NDC_WallCurved3x2



Click image to expand

NDC_DualAppWindows



Click image to expand

NDC_XRStage



Click image to expand

Projection Policies in nDisplay

Simple

Camera

Manual

Mesh

MPCDI

Using the .mpcdi File

Explicit Specification

EasyBlend (Scalable Display)

VIOSO

DomeProjection

Projection Policies in nDisplay

As part of the development strategy for new features, Epic Games is constantly evaluating existing tools that could add functionality to Unreal Engine. After much research, we found the following technologies to help us achieve our goals for scaled displays.

Simple

Simple refers to the standard policy used to render on regular 2D flat displays. This policy requires a rectangle in 3D space to be used to build camera frustum. The rectangle (screen) must be defined in the Components panel, then referenced in the simple projection policy section on the viewport's Details panel.

Follow the steps below to use the Simple policy in your project.

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Components panel, select Add Component and choose NDisplay Screen.



In the Cluster panel, select Add New Viewport.

In the Add New Viewport window under Configuration > Projection Policy, modify the following fields:

Set Type to simple.

Set Screen to the screen component that you created in Step 2. In this example, the screen was named nDisplayScreen.



Verify the screen is rendering the Viewport correctly. You may need to set the View Origin in the Viewport's Details panel to see the test scene.



Click image to expand

Camera

Since it is impossible to get a view from a regular Unreal Engine camera or cine camera with nDisplay, the camera policy was introduced. This policy allows you to map a view of any UE4 camera to the nDisplay viewport.

Follow the steps below to use the Camera policy in your project.

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Components panel, select Add Component and choose one of the Camera components: ICVFX Camera, Camera, or Cine Camera.



In the Cluster panel, select Add New Viewport.

In the Add New Viewport window under Configuration > Projection Policy, modify the following fields:

Set Type to camera.

Set Camera to the camera that you created in Step 2. In this example, the camera was named ICVFXCamera.

Choose the setting for Use nDisplay Renderer. By default, this enables the nDisplay render path for clustered rendering. When disabled, the nDisplay renderer is bypassed and displays native UE pixels for this specific camera. Disable this for debugging purposes or to compare native camera rendering vs nDisplay cluster rendering.



Verify the camera is rendering the viewport correctly.



Manual

As a generic solution for those systems that are not yet supported by nDisplay, a new manual projection policy was introduced. The key idea is that the user explicitly sets a view frustum for a particular viewport. For stereo rendering, two frustums are required. This can be done either via projection matrix or frustum angles. For more details on the difference between Mono and Stereo Rendering in nDisplay, see Stereoscoping Rendering in nDisplay.

Follow the steps below to use the Manual policy in your project.

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Cluster panel, select Add New Viewport.

In the Add New Viewport window under Configuration > Projection Policy, modify the following fields:

Set Type to Manual.

Set Rendering to Mono, Stereo, or Mono&Stereo.

Set Frustum to Matrix or Angles

For Frustum Matrix: Set the Rotation and Matrix fields (or MatrixLeft and MatrixRight if you picked Stereo instead of Mono).



For Frustum Angles: Set the Rotation and Frustum fields (or FrustumLeft and FrustumRight if you picked Stereo instead of Mono).



Verify the viewport is rendering correctly.

Mesh

This projection policy simplifies warp-rendering workflows. Instead of a PFM (portable float map) workflow, it is now possible to simply assign a mesh to effectively warp the rendered output. You can use either an NDisplayScreen, which creates a 2D display regardless of ratio and pixel density, or a StaticMesh Component, which can be a screen of an arbitrary shape and form, to specify the shape of the rendered output. The UV channel 0 is used for warp mapping.

Follow the steps below to use the Mesh policy in your project.

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Components panel, select Add Component and choose either NDisplayScreen or StaticMesh.

In the Cluster panel, select Add New Viewport.

In the Add New Viewport window under Configuration > Projection Policy, modify the following fields:

Set Type to Mesh

Set Mesh to the Component you created in Step 2. In this example, it's assigned to a StaticMesh with the name SM_Screen_0.



Verify the viewport is rendering correctly on the mesh. You may need to set the View Origin in the Viewport's Details panel to see the test scene.



Click image to expand

MPCDI

An integration of the MPCDI standard is used for complex projects that rely on this industry protocol.

The MPCDI (Multiple Projection Common Data Interchange) standard was developed by the VESA Multi-Projector Automatic Calibration (MPAC) Task Group. This is a standard data format for projection calibration systems to communicate with devices in a multi-display configuration.

The standard provides a way for multi-projector systems to generate the data needed to combine individual display components into a single, seamless image by a variety of devices. Any new hardware introduced into a system can be easily integrated with the standard.

MPCDI is used throughout the industry by content producers and vendors such as:

Scalable Display Technologies

VIOSO

Dataton Watchout

7thSense Design

Support for the MPCDI standard enables nDisplay to read and store data describing a complex projector system in a standardized and formalized fashion, so that we can easily communicate and interface with various other tools from within the industry. MPDCI is supported in the Editor Preview and Overscan.

There are two ways to use mpcdi projection policy. The first is a native approach where the user has to specify the .mpcdi file, buffer, and region to use. The second is where the user explicitly specifies files stored in .mpcdi (which is basically a file archive).

Using the .mpcdi File

Follow the steps below to use a native approach for the MPCDI policy in your project.

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Cluster panel, select Add New Viewport.

In the Add New Viewport window under Configuration > Projection Policy, modify the following fields:

Set Type to MPCDI.

Set MPCDI Type to MPCDI.

Next to File, browse to the .mpcdi file on your computer.

Set Buffer to the name of the buffer in the .mpcdi file.

Set Region to the name of a region within the .mpcdi file's buffer.



Verify the viewport is rendering correctly.

Explicit Specification

Follow the steps below to explicitly specify how to use the MPCDI policy in your project.

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Cluster panel, select Add New Viewport.

In the Add New Viewport window under Configuration > Projection Policy, modify the following fields:

Set Type to MPCDI.

Set MPCDI Type to Explicit PFM.

Next to File, browse to the .pfm file that represents warp geometry on your computer.

Next to Alpha Mask, browse to the .png file that represents the alpha mask on your computer.

Set the Alpha Gamma field to the associated alpha masks's gamma value. Alpha masks with no gamma can use a value of 1.0, which would be equivalent to linear.

Next to Beta Mask, browse to the .png file that represents the beta mask on your computer.

Set the Scale field to the geometry scale used in the .pfm file.

Enable Use Unreal Axis if you want to use Unreal's axis.



Verify the viewport is rendering correctly.

EasyBlend (Scalable Display)

Integration of EasyBlend calibration data is done with a Scalable SDK that enables warp, blend, and keystoning features. This meets the requirement to display on non-planar and complex display surfaces, such as curved or dome-shaped surfaces, using multi-projectors.

Scalable Display Technologies is a company that focuses on software and SDKs for complex projection systems. Their SDK is designed to provide a solution for large displays of a single image through warping and blending. Since Scalable Display Technologies already had the EasyBlend solution in place to handle warping and blending of large images, we chose to integrate it with Unreal Engine.

The Unreal Engine nDisplay supports warp and blend through the integration of the industry-standard middlewares Scalable SDK and EasyBlend for all supported modes, native warp and blend with MPCDI, and custom implementations.

We implemented the integration of EasyBlend to provide a seamless experience in configuring a complex projective system. Once calibration is completed using the third-party tool or software, the user only needs to specify a few parameters in the nDisplay configuration file to get it running.

Follow the steps below to use the EasyBlend policy in your project.

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Cluster panel, select Add New Viewport.

In the Add New Viewport window under Configuration > Projection Policy, modify the following fields:

Set Type to EasyBlend.

Next to File, browse to the .pol file on your computer.

Set the Origin and Scale fields.



Verify that the viewport rendering is properly deformed in regards to the provided EasyBlend calibration files. The render result should match the reference images from the vendor.

VIOSO

Native SDK integration of VIOSO calibration data is available for projector warping and soft edge blending on complex surfaces.

Once calibration is completed using VIOSO's tools and software, follow the steps below to use the VIOSO policy in your project.

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Cluster panel, select Add New Viewport.

In the Add New Viewport window under Configuration > Projection Policy, modify the following fields:

Set Type to VIOSO.

Next to File, browse to the .vwf file on your computer.

Set the Origin and Matrix fields.



Verify that the viewport rendering is properly deformed in regards to the provided VIOSO calibration files. The render result should match the reference images from the vendor.

DomeProjection

Native SDK integration of DomeProjection calibration data is available for projector warping and soft edge blending on massive dome surfaces. Once calibration is completed using DomeProjection's tools and software, add a couple parameters to the nDisplay configuration file to use it in your project.

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Cluster panel, select Add New Viewport.

In the Add New Viewport window under Configuration > Projection Policy, modify the following fields:

Set Type to DomeProjection.

Next to File, browse to the .xml file exported from DomeProjection's software on your computer.

Set the Origin and Channel fields.



Verify that the viewport rendering is properly deformed in regards to the provided DomeProjection calibration files. The render result should match the reference images from the vendor.

Determinism

Hardware Sync and Genlock

Display Synchronisation Demystified

Daisy Chain vs. Direct Genlock

NVIDIA Mosaic and AMD EyeFinity

Other Aspects of Display Sync

Render Sync Policies

Getting Sync to Work

Workflow

Additional Comments

Synchronization Testing

Links to Additional Information

Synchronization is a vital part of displaying multiple sections of real-time content over a large display. All systems within the render/display ecosystem must adhere to strict timing, measured in milliseconds, to produce the illusion of a seamless display.

Multi-display setups often require syncing capabilities at both software and hardware levels. Not only should the generated content be ready at the same time on all PCs, using the same timing information for simulation, but the display swap (the changing out of the current image for the next image in the video card buffer) needs to also happen at the correct time to prevent tearing artifacts in the display.

For VR and other types of stereoscopic displays, the issue of synchronization applies doubly since the two different frames—one for each eye—must coordinate perfectly.

Determinism

There are two types of approach for managing synchronization:

Deterministic: Each server (PC, rendering node) is set up in such a way that the output is always predictable given a particular set of inputs, which means the only information the server needs to synchronize with other machines in the system is an accurate time, and input/output information for each individual machine.

Non-deterministic: To ensure synchronization, the system forces replication of the transform matrices and other relevant characteristics of all actors or objects in a scene, and reproduces them throughout the system.

Each approach has pros and cons. The main advantage of a deterministic system is project simplicity, and the data bandwidth saved by not sharing transform data for each object at every frame. The downside is that if one system diverges, the divergence will have unknown issues over time. Rendering uniformity could be severely compromised, leading to visual discontinuity and artifacts.

Hardware Sync and Genlock

While the nDisplay primary PC ensures that all cluster (node) PCs are informed of timing information from a gameplay perspective (for example, which frame to render), specialized hardware sync cards and compatible professional graphics cards are necessary to synchronize the display of those rendered frames at exactly the same time on the physical display devices.

For example, in broadcast applications, it is common to synchronize many devices such as cameras, monitors, and other displays so they all switch and capture the next frame at precisely the same time. In this industry, the use of generator-locked signals (genlock) is widely adopted and used.

Typically, the setup is composed of a hardware generator that sends the clock to the hardware that requires synchronization. In the case of PCs used for real-time rendering, professional graphics cards such as those in the NVIDIA Quadro line support this technology alongside the NVIDIA Quadro Sync II card, which will lock to the received timing signal or pulse.



System Topology



Primary Node (house clock generator)



Cluster Nodes (receiving clock from primary node GPU)

Display Synchronisation Demystified

Framelock only: Using daisy-chaining techniques across GPUs, this method is what NVIDIA commonly calls FrameLock/SwapSync. No genlock is used here. A GPU on the primary nDisplay PC gets a master clock from an output display or processor connected to it, then propagates it to the render-node PC GPUs. All PCs are connected within tree topology, where primary PC is the root. This approach allows the use of NVIDIA swap groups/barriers via the NVIDIA API.

This approach is not well suited for virtual production since it works in isolation from other devices used within the space, with all of them being synced with an external master clock.

Genlock only: With this scheme, all cluster PC GPUs get their own master clock signal (genlock) from the same source. In other words, each PC gets its own BNC cable, and all cables are connected to the same master clock generator.

This approach allows synchronization of VSync; however, NVIDIA barriers are not available via NVIDIA API. Technically, all cluster PCs are framelocked to the received clock. However, this approach has not proven to be 100% reliable because there is no accurate control over frame presentation on the application level.

This is the method used before, and why we had to implement an "advanced" sync policy that would reduce the probability of unsync/glitches.

Genlock + framelock: This approach is the most desirable for virtual production. All stage devices are connected to a master clock, including the primary nDisplay PC GPU. In-cluster synchronization is accomplished using daisy-chain connections between the primary PC and the render node PCs.

This approach provides for the use of the NVIDIA API, and therefore utilizes NVIDIA barriers, which gives UE control over frame presentation on the application level. This provides the most reliable method of synchronizing displays, together with a provided external clock (genlock).

Daisy Chain vs. Direct Genlock

Daisy-chaining is a signal-locking technique that is used alongside direct genlock, where the master clock is sent to a single PC or device—in this case, the primary PC. Separate cables then propagate the signal to all other PCs. Although previous experience with nDisplay suggests that direct genlock (where each PC receives the clock directly from the primary source) is simpler and more effective than daisy-chaining, the new hardware approach based on daisy-chaining gives hope to a more reliable and cost-effective solution to signal locking. This solution is called NVIDIA Swap Sync/Lock.

NVIDIA Mosaic and AMD EyeFinity

Mosaic mode from NVIDIA and EyeFinity from AMD are similar GPU technologies that combine and synchronize multiple outputs within one graphics card so that they appear as a unique display from the OS or software perspective. This virtual display is essentially an aggregation of multiple physical displays acting as one synchronous display that can also be synced to other displays from different systems using underlying framelock or genlock techniques.

The process of locking multiple displays using a house clock is called framelocking. Genlocking is when an external clock is used instead. In the context of genlock, the external clock is used throughout all devices, including display devices, cameras and tracking sensors.

Assuming GPUs are properly connected using Quadro Sync II cards or Firepro S400 cards, both Mosaic and Eyefinity technologies allow multiple outputs to have the exact same clock, and to be treated as one big display canvas from an operating system perspective. You can create one or as many Mosaic or Eyefinity groups per PC but not across PCs—each PC must have it's own Mosaic or Eyefinity group.

To synchronize displays that are driven by multiple PCs or GPUs using daisy-chaining techniques, one GPU must act as the master clock generator and share its clock to the other GPUs—either on the same PC or different PC—using sync cards like the Nvidia Quadro Sync II or AMD Firepro S400.

For more information, see Mosaic Technology for Multiple Displays | NVIDIA and Multi-Display Eyefinity Technology.

Although it is possible to have a MOSAIC virtual display spawn across multiple GPUs within one PC, currently, it would be slow to have an application window over that canvas. (Future work may possibly enable this.) Today, this approach would not be recommended for virtual production or in-camera VFX.

Other Aspects of Display Sync

The game and render threads are always synchronized by what are called thread barriers. This is the core feature for both of the two items below. It is not possible to disable barriers. Consider them as points on a timescale that help the primary node deal with the cluster nodes synchronously to provide a uniform content experience across multiple UE PCs.

Feature

Description

Software/Simulation (what you should see)

The process of synchronizing all software-related matters. It is about making Unreal Engine and its content properly sync: feature determinism, delta-time synchronization, input replication, custom transforms, thread barriers, cluster events, game logic, and so on.

Hardware/OS (how you should see content)

The process of synchronizing hardware devices such as GPUs, display devices, and the DWM (Desktop Window Manager) using one shared clock—a house sync or genlock signal. It is how to make an operating system and hardware show what you want synchronously, without tearing. This requires NVIDIA Quadro graphics cards, plus Sync II cards, plus a genlock generator. Expect at least a one-frame hardware delay if this is not enabled.

Render Sync Policies

Render Sync Policies define how to synchronize the rendering output. This parameter can be set in the Cluster's Details panel in the nDisplay 3D Config Editor.

The following table describes the available options for Render Sync Policy.

Option

Description

None (Sync Policy 0)

This means VSync=0. All nodes show their frames after RenderThreadBarrier WITHOUT synchronization to VBlank. This gives maximum FPS at the cost of potential tearing artifacts.

Ethernet (Sync Policy 1)

All nodes show their frames after RenderThreadBarrier WITH synchronization to VBlank. Output displays won't have tearing. Note that tearing can still be possible among the displays because of Windows DWM and runtime or driver settings.

NVIDIA (Sync Policy 2)

NVIDIA hardware framelock (NVIDIA SwapLock API) based on daisy-chain connection. You can use the parameters in the NVIDIA section to tweak some specific hardware settings relating to frame lock.

Sync Group: The sync group to use for frame locking. The default value is 1.

Sync Barrier: The sync barrier to use for frame locking. The default value is 1.

Custom

Configures any custom sync policy that nDisplay is not aware of. A policy ID and any amount of key-value parameters are required.

Previously, we developed a sync mechanism called Advanced Sync for specific circumstances where the rendering of a frame on a given nDisplay PC would happen after VBlank, creating tearing on screen. This software mechanism tries to predict those events, and forces all PCs to skip and render on the next VBlank. This mechanism is not 100% perfect and can have a non-desirable performance impact when enabled.

More recently, we implemented the NVIDIA API for synchronization (Sync Policy 2), which is a hardware-supported approach to the problem.



Framelock connections on a timing server: 1) Timing server 2) Clients.



1) Sync source 2) Server 3) Clients

Getting Sync to Work

For reliable sync in the context of virtual production, you have to use a technique that combines both genlock and framelock. To summarize, you feed the genlock signal to the primary nDisplay PC, then use the daisy-chaining hardware method to dispatch the incoming sync signal to all remaining cluster PCs so that they are properly framelocked. This implies an NVIDIA Render Sync Policy that needs to be properly defined within the configuration asset.

Workflow

Set up daisy-chain connection among cluster GPU sync boards using regular ethernet cable with regular RJ45 connectors.

Enable MOSAIC, and configure synchronization via NVIDIA control panel (set a primary PC, then set sync cluster nodes).

In the nDisplay 3D Config Editor, set the Cluster's Render Sync Policy to NVIDIA.

Optional: For complex systems, it's possible to customize the NVIDIA swap group and sync barriers in the Cluster settings.

By default, sync group 1 and sync barrier 1 are used.

The NVIDIA Render Sync Policy cluster setting enables an NVIDIA swap group over cluster nodes.

Additional Comments

A 0 value is not allowed. A 0 value is used internally to detach/leave a group/barrier. Only natural numbers are allowed. On a simple system with one GPU and one sync board, you have single sync group #1 and single sync barrier #1. Those are used by default.

Synchronization Testing

Testing synchronization for a scaled display can be tricky because desynchronization can result from any number of issues, including:

The wrong frame is simulated due to incorrect timestamp (software issue).

The display device timing is off (display or hardware issue).

To test sync, we use a simple test project displaying a single object that moves quickly across the entire display surface. When systems are properly in sync, the object retains its form as it passes across boundaries. Otherwise, the display will show artifacts at shared edges.



When systems are properly in sync, the object retains its form as it passes from Screen 1 to Screen 2.

Links to Additional Information

NVIDIA QUADRO G-SYNC II

Chapter 30, Configuring Frame Lock and Genlock

QUADRO SYNC II

NVIDIA Recommended Display Adapters

Prerequisites

Step 1 - NVIDIA Drivers

Step 2 - Machine Configuration

Step 3 - NVIDIA Mosaic

Step 4 - NVIDIA Driver Utility

Step 5 - nDisplay Configured for NVIDIA Synchronization

Windows Resolution Example

Step 6 - EDID

Step 7 - Validating Sync and Troubleshooting

Synchronization across multiple nDisplay cluster nodes (PCs) is essential to avoid tearing between LED seams and to ensure the camera does not capture different rendered frames presented on the LED wall. This page describes how to set up synchronization in nDisplay with NVIDIA GPUs. Refer to Synchronization in nDisplay for more details on how synchronization works in nDisplay.

At present, obtaining correct synchronization across nDisplay nodes can require some troubleshooting. We recommend that you spend time preparing your nDisplay cluster nodes with synchronization before a Virtual Production shoot.

Prerequisites

You must have the following set up to complete the steps below.

An NVIDIA Quadro Sync II card per nDisplay node.

(mGPU setup only) NVIDIA SLI or NVLINK.

Compatible Quadro GPUs. Cards must have the same specification for each nDisplay node.

Cat-5 or Cat-6 RJ45 cables.

Tri-level or Bi-level sync generator.

BNC cables.

PCs running Windows with identical specifications for each nDisplay node.

If your Quadro card only has a DisplayPort output but the LED processor only accepts HDMI input, then you must convert the signal. One way you can convert the signal is with an adapter.

Refer to In-Camera VFX Recommended Hardware for recommendations on hardware to use for your setup.

Step 1 - NVIDIA Drivers

Install the latest drivers from NVIDIA, version R512.59, or later.

You can find the recommended driver for Virtual Production on NVIDIA's Download Drivers page. Select your card type and OS and set Download Type to Production Branch / Studio to find the recommended driver.

Step 2 - Machine Configuration

Configure the system with daisy-chain connections that uses both genlock and framelock:

An external sync source comes into the master sync card via a BNC cable for genlock

RJ45 cables daisy chain the remaining sync cards in the remaining nDisplay nodes for framelock.

Configure the NVIDIA Control Panel for sync. Specifically, ensure the vertical sync (vsync) global setting is set to Use the 3D application setting. Refer to NVIDIA's Quadro Sync II User Guide for more details on these steps

Once configured, NVIDIA sync should remain in place unless a machine crashes or locks out to the Windows login screen. We recommend monitoring the sync LED indicators on the Quadro Sync II card and with the NVIDIA Control Panel settings to ensure that synchronization is maintained throughout production.

Connect the cables for this setup in such a way that you can easily restart the nDisplay nodes in the reverse order of the NVIDIA sync daisy chain. Refer to NVIDIA's Quadro Sync II User Guide for more details on these steps.

Step 3 - NVIDIA Mosaic

nDisplay should only output to the primary display, and if more than one video output is necessary configure them as one large desktop with NVIDIA Mosaic.

Every display must be connected and share a common resolution, refresh rate, and color management:

Open NVIDIA Control Panel.

Navigate to Manage 3D settings:

Set Global Presets to Workstation App - Dynamic Streaming.

Under Settings, set Power management mode to Prefer maximum performance.

(mGPU using SLI only) Navigate to SLI and PhysX Configuration, and select Maximize 3D performance.

Navigate to View system topology, and click EDID to export and load an EDID on any used output ports to ensure the display information is locked and not queried again.

Alternatively, you can manage EDIDs through an external hardware device such as a matrix or switcher. For more on EDIDs and what they are, refer to the EDIDs section.

Navigate to Set up Mosaic, and choose Create new Configuration to open the NVIDIA Mosaic set up window.

In the NVIDIA Mosaic setup window on the Select topology tab, select Maximum GPU Topology.

On the Select displays tab, match the resolution for each display you have and set the overall refresh rate for the Mosaic.

On the Arrange Displays tab, match the position of the displays to what you have and click Apply.

Refer to the NVIDIA Mosaic Technology User Guide for more details on these steps.

Step 4 - NVIDIA Driver Utility

Download NVIDIA's Configure Driver Utility and run the application as an administrator through the Windows command prompt to set a specific configuration on the NVIDIA drivers.

After you launch the executable, type 11 and press Enter on your keyboard to enable the prePresentWait setting and improve performance without compromising sync.

You can verify it is running in the correct mode by enabling option 8, Enable the SwapGroupPresentIndicator for Direct x. This will enable a HUD in the lower left area that will appear when running nDisplay with NVIDIA sync policy, will indicate that prePresentWait is enabled, and also if the swap group has been joined and is not pending.

Step 5 - nDisplay Configured for NVIDIA Synchronization

For nDisplay to lock to the synchronization from NVIDIA sync it must run as a fullscreen foreground windows application (windowed should also work if the resolution exactly matches the desktop) because presentation mode needs to be an independent flip. This means that no other application window can be in front of the nDisplay instance while it is running.

Follow these steps to set up the nDisplay nodes for NVIDIA synchronization:

Open your nDisplay Configuration Asset in the nDisplay Config Editor.

In the Cluster panel, select Cluster to open its Details panel.

In the Details panel under Render Sync Policy, set Type to Nvidia (2).



For each node in your cluster, either enable Fullscreen or set the Window dimensions to be the full desktop resolution. Refer to the Windows Resolution Example for how to set your dimensions.

Close the NVIDIA Control Panel if it is open.

Close any virtual desktops. Applications like TeamViewer and Zoom use these.

Disable desktop notifications and pop-ups, such as desktop notifications from the Epic Games Launcher.

Set Windows desktop resolution scaling to 100%.

Disable the fullscreen optimization for Unreal Engine on each node by using Fix ExeFlags from Switchboard. You can also do this by right-clicking the Unreal Engine executable > Properties > Compatibility > Disable Fullscreen Optimizations.

If launching nDisplay on the same PC as Switchboard, enable Minimize Before Launch in the nDisplay section of the Switchboard settings.

Windows Resolution Example

The node's window should cover the entire desktop resolution, but the viewport need only cover the resolution required by the LEDs. This example shows how to set the node's window resolution and your viewport's resolution.

A square 2k section of LED wall is being rendered to from an Ultra HD desktop resolution, where the unused space will remain black:

Windows resolution is set to 3840 x 2160

Viewport resolution is set to 2048 x 2048

In the nDisplay Configuration Editor, this would be set as:

The node's Window parameter: X is 0px, Y is 0px, W is 3840px, and H is 2160px.

The viewport's Region parameter: X is 0px, Y is 0px, W is 2048 px, and H is 2048px.





Step 6 - EDID

Extended Display Identification Data (EDID) is a standard format for display devices defined by the Video Electronics Standards Association (VESA). EDIDs contain metadata about the display device for video sources.

Once you have everything set up in the NVIDIA Control Panel, it is useful to export the current EDID and then load it from a file to ensure display information is locked and not queried again if a display signal is lost. You may also prefer to manage the EDID through an external hardware device such as a matrix or switcher. Refer to NVIDIA's Managing a Display EDID on windows for more details on these steps.

Incorrectly configured EDIDs can halve the performance of nDisplay when using render sync policy 2. To avoid this, there are two options:

Ensure you have an EDID that allows you to select a PC resolution at the frequency you wish to shoot at and is marked as (native).

Create a custom resolution based on the standard 3840 x 2160 60hz PC resolution and then set it to the appropriate frequency.



Step 7 - Validating Sync and Troubleshooting

Refer to Synchronization Testing for how to verify whether you have obtained a successful sync in nDisplay.

Pay attention to the Switchboard as this shows the NVIDIA driver and sync status of the nDisplay nodes. For successful sync, the PresentMode column in Switchboard should indicate that each node is in Hardware Composed: Independent Flip. If a node reports Composed: Flip, then check that nothing is in front of nDisplay on the node (including Windows Taskbar or Switchboard Listener).

If you are still not able to obtain successful sync, you may want to swap the GPU and Quadro Sync cards in the nDisplay cluster nodes or consider whether there is a hardware fault.

Limitations

Supported Rendering Features

Achieve pixel perfect render continuity across multiple render nodes when cluster rendering with nDisplay and with post effects enabled. By overscanning in configurable direction(s), and then cropping out the extra rendered pixels with an exposed amount, users can decide on a (visual accuracy vs performance) ratio that works best for their project.

Visually impactful effects such as bloom, ambient occlusion or motion blur can now be enabled in most nDisplay projects - at some configurable performance cost.

Limitations

Auto-exposure should remain disabled as overscan cannot fix this.

This technique works well when the range of the post effect doesn't exceed the set overscan percentage. It is designed to help reduce or minimise visual discrepancy since the percentage is arbitrary.

This implementation works with Simple screens and projection policies. More advanced ones such as Mesh aren't supported at the moment.

Supported Rendering Features

Feature

nDisplay Compatibility

Solution

Notes*

Visual Impact

Accumulation Buffer

In-Camera VFX Compatible



Rendering / Post Effects



Bloom

Yes*

Overscan

Keep radius small

High

No

Yes

Lens Flare

No

Avoid

High

No

Yes

Auto Exposure (Eye Adaptation)

No

Avoid

Will separate type of logic.

High

Yes

Yes

Motion Blur

Yes*

Overscan

Medium

No

Yes but not working well for cinematography.

Depth of Field (DoF)

No

Avoid

Screen Space Ambient Occlusion (SSAO)

Yes*

Overscan

Keep radius small

Medium

No

Yes

Temporal Anti Aliasing (TAA)

Yes*

Overscan

Low

Yes

Yes

Screen Space Reflections (SSR)

No

Avoid

High

Yes

Yes

Screen Space Global Illumination (SSGI)

No

Avoid

High

Yes

Yes

Vignetting

Yes*

N/A

Medium

No

Yes

Scene Fringe (Chromatic Aberrations)

Yes*

Avoid

Keep radius small

Low

No

Yes

Raytracing (Denoiser)

No

Low

No

Should work but noise is non-deterministic.



Rendering / Other



Planar Reflections

Yes*

N/A

Users can customize the FOV setting.

High

No

Yes

Sky Atmosphere

Yes

N/A

Fixed

High

No

Yes

Material (shader) time based animations

Yes

Sometimes

Shadows

Yes

No

Culling

Yes

No





No

No



Gameplay



Sequencer

Yes

N/A

N/A

High

No

Yes

Blueprints

Yes/No

Avoid randoms

Works if using seeded randoms. There is also the BeginPlay issue not running when BP is reconstructed.

High

Sometimes

Yes

Physics (Chaos solver) IKRigid bodiesCloth

Yes

Yes

High

No

Yes

Particle System Cascade / Niagara

Yes

N/A

Deterministic setting must be set to ON for emitters.

High

Sometimes

Yes



Media / Playback



Video / Image sequence

N/A

N/A

Video engine currently not frame accurate.

High

No

Video I/O, BM, Aja

N/A

N/A

N/A

High

No

NDI/SMPTE 2110

N/A

N/A

Need to test for frame accuracy.

High

No

* The feature functions within limits. For example, Bloom functions for small/medium bloom radiuses as opposed to large blooms which would not make sense or function well in terms of the performance - visual ratio. Refer to the Notes for further details for individual features.

Activating Test Patterns

Console Command Syntax

Cluster Event Syntax

Test Patterns and Parameters

TPSCircles

TPSColoredBars

TPSGrayBars

TPSGridCircles

TPAChevron

TPAGrid

TPAMirroredChevron

TPARadar

TPAStrips

When you set up a new installation that uses nDisplay, partucularly with multiple viewports spread across multiple LED screens, you may sometimes have subtle display problems that are challenging to detect and diagnose when rendering a 3D virtual world. For example, you may experience tearing between adjacent viewports, display synchronization issues, seams between adjacent viewports, or slight color variations between adjacent display devices.

To make detecting these problems easier, nDisplay offers several different 2D test patterns that tile across your display devices. The regularity of these test patterns helps draw your eye to any problems. If you ensure that your nDisplay installation renders test patterns cleanly without any visible tearing or sync issues, you can be more confident that your devices will also be locked in sync when you use them to display your 3D virtual worlds.

Activating Test Patterns

The nDisplay Plugin includes a Display Cluster Test Patterns Actor. Find this Actor in the Place Actors panel and drag it into your Level Viewport.



Activate your choice of test patterns by issuing the nDisplay.Calibration.Pattern console command, or by sending a cluster event to the network. See the Console Command Syntax and Cluster Event Syntax sections below for details.

In both cases, you need to specify the name of the pattern you want to activate, the viewports that you want to show the test pattern. Each pattern also offers additional optional parameters to control aspects like the scale of the pattern and rate of motion across the viewports.

Console Command Syntax

The nDisplay.Calibration.Pattern console command has the following syntax:

with the following parameters:

Parameter

Description

pattern ID

Specifies the test pattern you want to activate. This name should match the name assigned to one of the test patterns registered with the Display Cluster Test Patterns Actor. If it does not match one of those test patterns, the current test pattern will be removed.

viewport IDs

Specifies the nDisplay viewports that should show the test pattern. This must be one of the following values:

The ID of a viewport section in your nDisplay calibration flle.

A comma-separated list of viewport IDs that match viewport sections in your nDisplay configuration file.

The special value *, which applies the test pattern to all viewports.

material parameter

A list of parameters and values that override default settings for the chosen pattern. Each parameter should be in the form <name>:<type>:<value>, where <name> is the name of the parameter you want to set, <type> is the type of data managed by that parameter, and <value> is the actual value you want to set. Use the table in the Test Patterns and Parameters section below as a reference to the names and types.

Parameters with type scalar require values that are a single floating-point number.

Parameters with type color require values that are made up of four floating-point numbers separated by commas. These numbers are interpreted in RGBA order: red, green, blue, alpha.

For example, this console command sets all viewports to show the TPSCircles pattern:

This console command shows the TPSCircles pattern only on three viewports, named vp1, vp2, and vp3:

This console command is the same as above, but also overrides the default values for the width and color of the lines in the pattern:

Cluster Event Syntax

To activate a test pattern by sending a cluster event to your nDisplay network, set up your cluster event as follows:

Description

Event category

nDisplay

Event type

Calibration

Event name

Pattern

Parameter 1

PatternId = <pattern ID>

Where <pattern ID> specifies the test pattern you want to activate. This name should match the name assigned to one of the test patterns registered with the Display Cluster Test Patterns Actor. If it does not match one of those test patterns, the current test pattern will be removed.

Parameter 2

ViewportId = <viewport IDs>

Specifies the nDisplay viewports that should show the test pattern. <viewport IDs> must be one of the following values:

The ID of a viewport section in your nDisplay calibration flle.

A comma-separated list of viewport IDs that match viewport sections in your nDisplay configuration file.

The special value *, which applies the test pattern to all viewports.

Additional parameters

You can pass additional parameters to the cluster event to override default settings exposed by the chosen pattern. Each parameter you pass should be in the form <name> = <type>:<value>, where <name> is the name of the parameter you want to set, <type> is the type of data managed by that parameter, and <value> is the actual value you want to set. Use the table in the Test Patterns and Parameters section below as a reference to the names and types.

Parameters with type scalar require values that are a single floating-point number.

Parameters with type color require values that are made up of four floating-point numbers separated by commas. These numbers are interpreted in RGBA order: red, green, blue, alpha.

Test Patterns and Parameters

This section describes the test patterns that come pre-installed with nDisplay, along with the parameters you can specify for each.

If you select your Display Cluster Test Patterns Actor in the Level Viewport or the World Outliner, you'll see the list of all available calibration patterns in the Details panel under the Display Cluster > Calibration Patterns property.

TPSCircles



Name

Type

Repeats

scalar

LineWidth

scalar

LineColor

color

TPSColoredBars



Name

Type

Notes

Shades

scalar

Direction

scalar

Sets the direction of the bars. Accepts the following values:

0: vertical

1: horizontal

TPSGrayBars



Name

Type

Notes

Shades

scalar

Direction

scalar

Sets the direction of the bars. Accepts the following values:

0: vertical

1: horizontal

TPSGridCircles



Name

Type

Repeats

scalar

LineWidth

scalar

LineColor

scalar

TPAChevron



Name

Type

Repeats

scalar

LineWidth

scalar

LineColor

scalar

Speed

scalar

TPAGrid



Name

Type

Repeats

scalar

LineWidth

scalar

LineColor

scalar

Speed

scalar

TPAMirroredChevron



Name

Type

Repeats

scalar

Color1

color

Color2

color

Speed

scalar

TPARadar



Name

Type

Speed

scalar

Power

color

TPAStrips



Name

Type

Notes

Repeats

scalar

LineWidth

scalar

LineColor

scalar

Speed

scalar

Direction

scalar

Accepts the following values:

0: vertical

1: horizontal

You can also use your own custom test pattern. Create a new Post-Process Material in your Project, and add it to the Calibration Patterns property of your Display Cluster Test Patterns Actor. Once you do this, you'll be able to trigger your own test pattern across your nDisplay cluster using either the console command or the cluster event methods shown above.

Network Configuration

Parameters

nDisplay Communication Ports

Network Configuration

The Network configuration section provides settings that you can use to control timeouts and other settings related to network communication between nDisplay cluster nodes.

To access the Network settings:

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Cluster panel, select Cluster to open its Details panel.

In the Details panel, edit the Network configuration settings.





Click image to expand.



Parameters

Parameter

Default

Description

Connect Retries Amount

300

When a non-primary cluster node starts up, this setting determines the number of times the node will attempt to connect to the primary PC before it shuts down.

Connect Retry Delay

1000

When a non-primary cluster node starts up, this setting determines the time interval after each unsuccessful attempt by the node to connect to its primary PC, in milliseconds.

Game Start Barrier Timeout

18000000

Sets a time interval that the Unreal Engine application on the primary node waits for all cluster nodes to be ready before it starts the first frame of the game loop and begins rendering to the main window, in milliseconds.

This gives all your cluster nodes a chance to connect to the primary PC before rendering begins. During this time, the main window will be black. If, at the end of this time interval, any cluster node has not yet successfully connected to the primary PC, all instances in the cluster will shut down.

You may need to raise this value if your cluster takes an unusually long time to initialize.

Frame Start Barrier Timeout

30000

The waiting time for all nodes to be ready to start frame processing on the game thread.

Frame End Barrier Timeout

1800000

The waiting time for when all nodes finish frame processing on the game thread.

Render Sync Barrier Timeout

1800000

Sets the barrier timeout for the render thread, in milliseconds. This is a barrier timeout to synchronize render threads among cluster nodes. It's used several times within each frame.

In other words, this is used at runtime to detect situations where any node becomes unreachable. If this occurs, the state of the cluster state is determined to be invalid, and all nodes shut themselves down.

The Connect Retries Amount and Connect Retry Delay settings work together to determine the maximum length of time your cluster nodes will try to connect to the primary node at startup. For example, suppose you have Connect Retries Amount set to 10, and Connect Retry Delay set to 1000 milliseconds. On startup, each node tries to connect to the primary PC. If that connection fails, it waits 1000 milliseconds to try again. If that attempt also fails, it waits another 1000 milliseconds. After ten successive failures, the cluster node quits automatically. As soon as a cluster node makes the connection to its primary PC, the count stops.

nDisplay Communication Ports

The nDisplay system communicates between hosts over four TCP/IP ports:

41001 for the Cluster Sync

41002 for the Render Sync

41003 for the JSON Cluster Events

41004 for the Binary Cluster Events

You need to make sure you have these ports open on all computers.

If you want to change the port numbers yourself, you can do so in the following locations.

Runtime synchronization ports: The primary node uses two ports to synchronize data with the other nodes in the cluster. To set these two ports, go to the Cluster's settings.

Cluster event ports: The primary node always uses the same port to exchange cluster events with connected clients. This includes both other nodes in the nDisplay cluster, and any external applications that you write to send and retrieve cluster events. To set this port, go to the Cluster's settings.

Switchboard and SwitchboardListener ports: Switchboard and SwitchboardListener both need to be configured to use the same communication port. You can specify this in the Switchboard settings. In addition, you'll have to start the SwitchboardListener application on each host yourself, with the port argument. For example: SwitchboardListener.exe -port=2980

Replicating Custom Data

All inputs to the nDisplay system are handled only by the primary node. Without any replication, only the primary node would see changes in the scene. Therefore, the primary node needs to be able to replicate changes to all other parts of the nDisplay network.

To accomplish this, nDisplay offers two different kinds of Components that you can attach to your Actors:

The DisplayClusterSceneComponentSyncParent Component tracks changes in the 3D transforms of its parent Component, and pushes those changes to the other cluster nodes in the network.The default DisplayClusterPawn used by the nDisplay system uses this Component.

The DisplayClusterSceneComponentSyncParent Component tracks changes to the 3D transforms of its child components, and pushes those changes to the other cluster nodes in the network.

For example, in the Actor shown below, the DisplayClusterSceneComponentSyncParent_Scene Component tracks and replicates changes to the 3D transforms of its parent Actor as the Actor moves around the Level. The DisplayClusterSceneComponentSyncThis Component tracks and synchronizes movements of its child Static Mesh component as it moves relative to the scene graph root.



If you have other Actors in your scene that can be affected during gameplay, you must use one of these two Components to replicate those changes to all nodes. To do this:

Select the Actor you need to replicate in the Level viewport or the World Outliner panel.

In the Details panel, click + Add Component. Search for either DisplayClusterSceneComponentSyncParent or DisplayClusterSceneComponentSyncThis, and select it from the list.

These components do not carry out a full replication. Only the transforms of the parent Actor or of child Components are sent to the cluster.

Replicating Custom Data

If you need to replicate other custom data between your primary node and the rest of your cluster, you can write your own C++ class that implements the IDisplayClusterClusterSyncObject interface. nDisplay will automatically invoke the methods in this interface to check whether each instance of this class needs to be synchronized from the primary node to the other cluster nodes.

Tuning Stereoscopic Rendering

Stereoscopic Rendering Formats

Monoscopic Rendering with Stereo Offset

In stereoscopic rendering, each nDisplay cluster node generates the images for both the left and right eyes, and encodes the output images using your choice of standard formats for stereoscopic images. In this case, you are responsible for setting up your graphics card, display driver, or hardware to interpret the stereo images produced by nDisplay and route them appropriately.

Tuning Stereoscopic Rendering

To tune stereoscopic rendering:

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Components panel, select the View Origin Component to open its Details panel.

In the Details panel, you'll need to define the interpupillary distance between the left and right eye. Set the Interpupillary Distance field to the distance you want between the left and right eyes, in centimeters. If you need to flip the left and right eyes for the images to show up correctly on your display hardware, you can also enable Swap Eyes.



Click image to enlarge

Open Switchboard and go to its Settings.

In the Switchboard Settings window, go to the nDisplay Settings section, and set Render Mode to one of the stereo options: Side-by-Side or Top-bottom.



Click image to enlarge

For details on the available settings, see the Stereoscopic Rendering Formats section below.

Stereoscopic Rendering Formats

nDisplay can render stereoscopic images in any of the following standard formats.

Render mode

Description

Frame sequential

This mode produces sequential stereo pairs for each frame of the engine's main loop. For example, it first renders the left eye for frame 1, then the right eye for frame 1, then the left eye for frame 2, then the right eye for frame 2, then the left eye for frame 3, and so on. In most cases, this option requires a GPU with specialized support for stereoscopic rendering.

This format is known in OpenGL as a quad buffer.

Side by side

In this mode, the image produced for each frame of the engine's main loop is divided in two. The left half of the image contains the view from the position of the left eye, and the right half of the image contains the view from the position of the right eye. This mode has two advantages. First, it may produce higher frame rates because the rendering time is shorter for each image. Second, you can use it with any GPU. On the other hand, the disadvantage is that the images are of lower quality.

Top-bottom

This mode is almost the same as the Side by side option described above. The only difference is that the image for each frame is divided in half horizontally instead of vertically. The top half of the image shows the view from the left eye, and the bottom half of the image shows the view from the right eye.

Monoscopic Rendering with Stereo Offset

In this approach, you have one viewport render a monoscopic view of the scene from the point of view of the left eye, and another viewport render a different monoscopic view of the scene from the point of view of the right eye. These viewports can be on the same computer, or on different computers entirely. This approach can also improve rendering speed in the same way as a multi-GPU hardware setup.

For this to work, you need to have two different View Origin components attached to your root component, one for the left eye, and one for the right eye.

Open your nDisplay Config Asset in the nDisplay 3D Config Editor.

In the Components panel, click Add Component and add a second View Origin component. This should be placed in the same location as the default View Origin.



In the Details panel, set the Stereo Offset of one of the View Origins to Left Eye, and the Stereo Offset of the other to Right Eye.

Bind one viewport to the first View Origin, and the other viewport to the second View Origin.

Each View Origin will have an offset equal to half the Interpupillary Distance to the left or right, depending on the Stereo Offset setting for that View Origin. As a result, you will have a stereopair generated by different rendering sources.

Color Grading

Viewports

Inner Frustum

OpenColorIO (OCIO)

nDisplay includes color management tools so you can apply color grading and OpenColorIO (OCIO) configurations to your displays without modifying the overall look of the Unreal project itself. These color settings can be applied to the entire nDisplay cluster, or to individual viewports and cluster nodes.

Typically, you'll want to use these nDisplay-specific color management tools after you've achieved the desired look for the project. These tools are useful for tuning the look of the content as it appears on specific displays.

The settings are exposed in the nDisplay 3D Config Editor, and also in the nDisplay Root Actor for rapid iterations. Changes made to the nDisplay Root Actor can be tracked by Level Snapshots.

Changes made to the nDisplay Config Asset are saved in the UAsset. Changes made to the nDisplay Root Actor are only on the instance of the config asset, and won't be saved in the UAsset.

The following sections describe how you can use color grading and OpenColorIO with your nDisplay setup.

Color Grading

The overall behavior of the color grading settings is identical to Post Process Volume, with additional options provided for more specific control between nDisplay viewports and cluster nodes. For more information on the settings exposed in nDisplay, see nDisplay Root Actor Reference.

Color grading is additive: when multiple color grading settings are enabled, they are applied in order like a stack. For example, if one color grading setting applies red, and another applies blue, the resulting color will be purple, a mix of the two.

The following sections describe the behavior of color grading when it's applied to different parts of the nDisplay cluster.

Viewports

Color grading is applied to a viewport in the following order if they're enabled:

Post Process Volume

nDisplay Root Actor's Entire Cluster Color Grading

nDisplay Root Actor's Per-Viewport Color Grading

When color grading is enabled for the entire cluster on the nDisplay Root Actor, the settings will be applied consistently to every viewport and inner frustum. The example below shows a before and after: the nDisplay cluster with color grading disabled, and the nDisplay cluster with a blue color applied.







You can also apply color grading to specific viewports in the nDisplay cluster. This is useful for when content appears to have different colors across different models and brands of displays.

In the example below, a separate color grading is only applied to the viewport rendered on the ceiling panel. The resulting color is purple because color grading is additive. The red color applied to the viewport is mixed with the blue color applied to the entire cluster.





You can choose to not include the color grading settings from the entire cluster on a per-viewport scope as well. In the example below, the Include Entire Cluster Color Grading is unchecked for the ceiling viewport. The color of the ceiling panel turns red, because it still applies the Per-Viewport Color Grading even when the Entire Cluster Color Grading is not included.





Inner Frustum

Color grading is applied to the inner frustum in the following order if they're enabled:

Post Process Volume

nDisplay Root Actor's Entire Cluster Color Grading

ICVFX Camera Component's All Nodes Color Grading

ICVFX Camera Component's Per-Node Color Grading

The nDisplay Root Actor's Per-Viewport Color Grading settings will only be applied to the outer frustum. It will not affect the inner frustum.

When color grading is enabled for All Nodes on the ICVFX Camera Component, the settings will be applied to the inner frustum consistently across all cluster nodes and viewports.





You can also apply color grading to specific cluster nodes in the nDisplay cluster. This is useful for when content appears to have different colors across different models and brands of displays.

The finest granularity of control for the inner frustum in the nDisplay cluster is per-node. This is because the inner frustum can be shared across multiple viewports when mGPU is enabled.

In the example below, a separate color grading is applied to the cluster node containing the ceiling panels. When the inner frustum moves from the back panel to the ceiling, you can see the change in color on the inner frustum.





OpenColorIO (OCIO)

The overall behavior of the OCIO settings for nDisplay is identical to OCIO for the Editor, with additional options provided for more specific control between nDisplay viewports and cluster nodes. For more information on the settings exposed in nDisplay, see [nDisplay Root Actor Reference]().

Unlike color grading, OCIO settings are not additive. Typically, you will set a base OCIO profile for all viewports and the inner frustum, but can override these settings per-viewport or per-node. The OCIO profile you set for nDisplay renders will also override the OCIO profile set for the Editor.

A general OpenColorIO config is provided in the OpenColorIO Plugin's content as a starting point for using OCIO in your project. This config should be useful for most combinations of cameras and panels, but you may need to modify it for your project's needs. For in-camera VFX scenarios, you'll typically want a different Destination Color Space value for each combination of camera and panel that you use in your set up.

The example below shows an nDisplay cluster before applying an OCIO config to the entire cluster and the nDisplay cluster after applying the config.





Similar to the functionality for Color Grading, you can apply an OCIO configuration per viewport on the nDisplay Root Actor, in addition to the entire cluster. You can also apply an OCIO configuration on the inner frustum for all, or a subset of all, cluster nodes on the ICVFX Camera Component.

Ensure that the same viewport or node is not included in multiple OCIO overrides, since only one OCIO profile can be applied. If you do have multiple overrides connected to a viewport or node, the OCIO profile from the last override listed will be the one that is applied.

Process Shots: Move the Stage vs Move the World

Move the Stage

Move the World

Limitations

Previously, motion blur was disabed because it interfered with the common case of filming a static environment. The exposed sensor of the physical camera naturally blurs the inner frustum as the camera moves. If motion blur were naively enabled in nDisplay, it would be incorrectly amplified in the final footage: the inner frustum would be rendered with blur due to the tracked camera motion, and the physical camera would capture a blurred exposure of the inner frustum.

However there are cases in which rendered motion blur on the LED wall is desired. For example:

When content displayed on the wall has animation, such as animated vehicles or characters in the virtual environment.

When shooting a process shot, where the virtual environment itself has motion relative to the actors and props on the set. A common example of a process shot is where actors are sitting in a car and the background appears to be moving. In this case, the blur must be rendered to the LED wall because the physical camera and prop vehicle do not have any gross translational movement.

nDisplay now provides a solution to render the inner frustum with motion blur by subtracting out any blur due to the tracked camera motion. For example, if there's a camera pan in a process shot, it should not create additional blur in the inner frustum even while the background appears to move quickly by.





A car process shot on the Unreal Engine 4.27 In-Camera VFX Test shoot.

Process Shots: Move the Stage vs Move the World

There are two approaches you can take to prepare a scene for a process shot:

Move the Stage: Where the nDisplay Root Actor moves through the environment.

Move the World: Where the entire environment moves around the nDisplay Root Actor.

There are use cases for each approach. The best choice depends on your project's needs.

The nDisplay motion blur calculation was designed to handle both cases. Further testing of real-world scenes is needed to validate the accuracy of motion blur for the Move the Stage approach. We believe that the Move the World approach works reliably in all cases.

Move the Stage

For this approach, the nDisplay Root Actor should be animated with a path representing the gross motion of the vehicle. This is easier to set up than the other approach since the environment can be used without any modifications to make it moveable.

There can be some drawbacks to this approach:

Each take must be carefully choreographed with the timing of the animation playback.

Unless it is possible for the motion path to be a closed loop animation, the playback will have a noticeable reset between the last and first frames.

The longer the take, the more environment content you'll need to create.

Due to the limits of the single-precision floating-point format, Unreal's rendering can become unstable if the gross translation of the camera is too far from the origin.

Move the World

For this approach, you keep the virtual stage fixed in Unreal's world space and animate the environment to move around it. This might be the more flexible approach when you just need a generic visual motion outside of the vehicle.

Many tricks can be employed in this case, especially if the motion path of the vehicle is simple. For example, you can reuse blocks of the environment by moving them like a conveyor belt around the virtual stage, allowing for infinite playback and uninterrupted camera shoots.

If the vehicle path is more directed and the environment has been designed to be moveable, the animation of the vehicle could be created separately and then inverted onto a root transform that is the parent of the environment.

The drawbacks to this approach are that it requires custom scene setups and fully moveable dynamic content and lights.

Limitations

There are fundamental limitations to capturing motion-blurred LED wall content in a physical camera.

For example, if the camera on a real moving vehicle was panning to track a fixed spot in the world, like a sign moving past the vehicle, in reality there would be no blur in the captured image. This is not possible to do on an LED stage since the exposure of a panning camera will blur the wall no matter what.

Cluster Event Format

JSON Cluster Event Structure

Binary Cluster Event Structure

Emitting Cluster Events from Blueprints

Emitting Cluster Events from External Applications

Responding to Cluster Events in Blueprints

Cluster Events are a way for you to make all the nodes in your nDisplay cluster respond to events simultaneously.

You generate a Cluster Event either from a node in the cluster or by sending it to the primary node from an external application. See Emitting Cluster Events from Blueprints or Emitting Cluster Events from External Applications.

When the primary node of your cluster receives a Cluster Event, it propagates that event to each node in the cluster so that the event happens on each node in exactly the same frame.

Within the Blueprint or C++ logic of your Unreal Engine application, you set up listeners to detect these Cluster Events and respond to them with whatever gameplay logic you need for your Project. See Responding to Cluster Events in Blueprints.

Cluster Event Format

There are two types of formats supported by nDisplay for Cluster Events: JSON and binary. The JSON format is human-readable; it uses ASCII, with some characters forbidden by the JSON standard, and requires a specific schema for structuring data. With the binary format, you can use any kind of binary data, and serialization and deserialization is up to you. Using the binary format for Cluster Events has better performance than the JSON format for data throughput and latency.

JSON Cluster Event Structure

Each JSON nDisplay Cluster Event can contain several properties:

Setting

Type

Name

string

Type

string

Category

string

SystemEvent

Boolean to specify whether this is a system or user event. You do not need to set this flag yourself.

ShouldDiscardOnRepeat

Boolean to specify whether events with the same Name, Type, and Category that have already been received within the current frame should be discarded.

Parameters

An optional map of key-value pairs, where the keys and values are both strings.

It's up to you to decide in your Project what data you want to send in each of these properties, and how you want your listeners to interpret that data.

When you interact with a JSON Cluster Event in Blueprint, you'll use the Make DisplayClusterClusterEventJson and Break DisplayClusterClusterEventJson nodes to construct and deconstruct JSON Cluster Events. For example:



In C++, or when emitting JSON Cluster Events from your own applications, you'll use the FDisplayClusterClusterEventJson struct to express the same structure.

Binary Cluster Event Structure

Each Binary Cluster Event can contain several properties.

Setting

Type

Event Id

32-bit integer

System Event

Boolean to specify whether this is a system or user event. You do not need to set this flag yourself.

ShouldDiscardOnRepeat

Boolean to specify whether events with the same Event Id that have already been received within the current frame should be discarded.

Event Data

Array of bytes

It's up to you to decide in your Project what data you want to send in each of these properties, and how you want your listeners to interpret that data.

When you interact with a Binary Cluster Event in Blueprint, you'll use the Make DisplayClusterClusterEventBinary and Break DisplayClusterClusterEventBinary nodes to construct and deconstruct Binary Cluster Events. For example:



In C++, or when emitting Binary Cluster Events from your own applications, you'll use the FDisplayClusterClusterEventBinary struct to express the same structure.

Emitting Cluster Events from Blueprints

The following example shows how to emit JSON Cluster Events from a Blueprint class. You can use these same steps, with some modification, for emitting Binary Cluster Events from a Blueprint class.

To emit a JSON Cluster Event from a Blueprint class in your Project:

Get the DisplayCluster Module API (see Blueprint API), and call its Cluster > Emit JSON cluster event function. This node fires the Cluster Event out to the primary node, labeled the master node in the API, which propagates it back to all the nodes in the cluster.



Click image to expand.



By default, every instance of your Unreal Engine application that evaluates this Blueprint node in its gameplay logic will fire this Cluster Event. If this Blueprint graph gets evaluated on many different nodes in your cluster, this can cause multiple copies of the event to happen.To avoid triggering multiple copies of the Cluster Event, you can set the Primary Only Boolean value on the Emit JSON cluster event node. If you check this box, only the primary node will emit this Cluster Event. If any other non-primary cluster node evaluates the same Blueprint graph, those nodes will not emit the event.



Drag left from the Event port on the Emit JSON cluster event node, and choose Make DisplayClusterClusterEventJson.



Click image to expand.



Use the settings in the Make DisplayClusterClusterEventJson node to set set up your Cluster Event with string values for its Name, Type, and Category. If you need to pass arbitrary key-value data along with your cluster event, you can also pass a map of those keys and values to the Parameters input.



Click image to expand.



Compile and Save your Blueprint.

The next time you repackage your Project and relaunch your nDisplay cluster, this Blueprint code will fire the JSON Cluster Event you've set up. To respond to this event elsewhere in your Blueprint code, see Responding to Cluster Events in Blueprints.

Emitting Cluster Events from External Applications

When you start up your nDisplay cluster, the primary node begins listening for incoming Cluster Events on a specific local port. You can emit new Cluster Events to your nDisplay system from another application running on any other computer in your network by connecting to that port and sending messages. Both JSON and Binary port listeners use TCP, so you can keep the connection open until the cluster session has ended.

For each Cluster Node you want to emit, your message must follow this convention:

The first four bytes must give the total length of the rest of the message.

The rest of the message should be the content of your Cluster Event, expressed as either a JSON object or binary data.

For JSON event messages:

JSON object with the mandatory fields Name, Type, Category, SystemEvent, and ShouldDiscardOnRepeat, and the optional field Parameters.

For binary event messages:

4 bytes for the event ID.

1 byte for the System Event boolean.

1 byte for the Should Discard on Repeat boolean.

N bytes for the binary data, where there is no limit for N.

For example, to emit a JSON Cluster Event with the name "quit" and the type "command", you would need to:

Construct a JSON string that contains the values for your Cluster Node. In this case:

The Name, Type, and Category fields are mandatory, but you may omit the Parameters field. Although some of the fields are mandatory, you can assign empty values to any of the fields because the events with empty fields will be grouped together. It's recommended to provide names and IDs for readability.

Get the length of the JSON string — in this case, 62 characters — and send that length to the nDisplay primary node in binary format with 4 bytes. In this example, it would be 0x00111110.

Send the JSON string itself to the nDisplay primary node.

By default, the primary node listens for Cluster Events on port 41003 and Binary Cluster Events on port 41004. You can change this default in your nDisplay configuration file. See Changing nDisplay Communication Ports.

To respond to these Cluster Events in your Project's Blueprint code, see Responding to Cluster Events in Blueprints.

Responding to Cluster Events in Blueprints

Once you've set up one of the methods described above to emit Cluster Events into your nDisplay network, you'll want to set up your Blueprint (or C++) gameplay logic to detect those Cluster Events and respond to them in some way. To do this, you need to create and register a listener: a class that implements the DisplayClusterClusterEventListener interface. You register the listener by calling the Add Cluster Event Listener function from the nDisplay API, then use the Event On Cluster Event node to detect Cluster Events and respond to them.

For example, to create a new Blueprint class and register it as a listener:

In the Content Browser, right-click and choose Create Basic Asset > Blueprint Class.





Click image to expand.



Choose Actor as the parent class.

Type a name for your new listener class in the Content Browser.

Drag your class into the Level Viewport and drop it into your Level.





Click image to expand.



Double-click your new Blueprint class to edit it.

In the Toolbar, click Class Settings.

In the Details panel, find the Interfaces > Implemented Interfaces setting and click Add.

Find and select the DisplayClusterClusterEventListener interface in the list.

Click Compile in the Toolbar to compile your class.

On the Event Graph tab, set up the following graph to register your listener:





Click image to expand.



To set this up:

Drag right from the output of the Begin Play Event node and choose N Display > DisplayCluster Module API.

Drag right from the Out API port of that node and choose Display Cluster > Cluster > Add cluster event listener.

Finally, drag left from the Listener port of the Add cluster event listener node, and choose Variables > Get a reference to self.

It's a good idea to also destroy each listener you create when you know you won't need it anymore. For example, you can do it when your Blueprint Actor is destroyed:





Click image to expand.



To set this up:

Right-click in the Event Graph and choose the Add Event > Event Destroyed node.

Drag right from the output of the Event Destroyed node and choose N Display > DisplayCluster Module API.

Drag right from the Out API port of that node and choose Display Cluster > Cluster > Remove cluster event listener (Interface Call).

Finally, drag left from the Listener port of the Remove cluster event listener node, and choose Variables > Get a reference to self.

In another area of the Event Graph, add the Add Event > N Display > Event On Cluster Event Json node. Every time a JSON Cluster Event happens in your nDisplay cluster, this event will trigger.You will probably want to read the settings and parameters assigned to this event, so that you can use them to determine what action your Blueprint needs to take. To do this, drag right from the Event port of the Event On Cluster Event Json node, and choose Break DisplayClusterClusterEventJson.For example, this graph simply prints out the Name value of each JSON Cluster Event to the screen:





Click image to expand.



Compile and Save your Blueprint class.

The next time any JSON Cluster Event is emitted in the cluster, from any source, the name of that JSON Cluster Event gets printed to the screen.

Getting Started

Reference



In Composure, a graphics utility plugin available with Unreal Engine, we've added a new set of tools to make compositing a lot easier.

Compositing is the act of combining visual elements from different sources into a single image. In the visual effects industry, compositing a single frame is usually an offline process and can take some time. With compositing built into the engine, users can easily visualize green-screened scenes combined with CG in real-time. This is especially helpful for previsualization, which enables directors to get a sense of what the final scene will look like, or for offline compositors to use as a guide. Compositing will run both in-editor and in-game.

Getting Started



Product documentation including reference and guides for Unreal Engine



Product documentation including reference and guides for Unreal Engine



Product documentation including reference and guides for Unreal Engine

Reference



Product documentation including reference and guides for Unreal Engine



Product documentation including reference and guides for Unreal Engine



Product documentation including reference and guides for Unreal Engine

Prerequisites

Converting a Media Element in Composure

Converting Media Output in Composure

This page explains how to apply OpenColorIO (OCIO) color conversions to input and output media in Composure.

Prerequisites

You must set up the following in your project to complete the sections below:

An OpenColorIO Configuration Asset. Refer to the OpenColorIO Quick Start for steps on creating this Asset.

A Composure Element set up with a valid Media Source and an Output. Refer to the Real-Time Compositing Quick Start for steps on setting these up.

Converting a Media Element in Composure

This procedure shows how to create a new Transform Pass for a Composure Element, and set up that Transform Pass to convert the color space of the Element's media source from one color profile to another.

In the Outliner, select your Composure Element to open its Details panel.

In the Details panel under the Composure > Transform/Compositing Passes section, click Add (+) to add a new Transform Pass entry.



In the settings for your new Transform Pass, open the dropdown menu and select OpenColorIO Pass from the list.



Expand the settings for your Transform Pass, then expand its Color Conversion Settings.



Under Color Conversion Settings:

Set the Configuration Source parameter to point to your OpenColorIO Configuration Asset.

Set the Source Color Space parameter to the color profile you want to convert from. This is typically the color space that the media source was originally captured in.

Set the Destination Color Space parameter to the color profile you want to convert to. Typically you will want to use the linear color space so your media matches the linear color space used in Unreal Engine.

Toggle the Enabled setting on.



As soon as you set up the source and destination color spaces for your Transform Pass, the colors in your Media Source change in the Composure Element's Preview and in the Level Viewport.

Converting Media Output in Composure

This procedure shows how to set up an output from Composure with a new Color Correction pass that converts the colors of the composited media from one OCIO color profile to another.

In the Outliner,select your Composure Element to open its Details panel.

In the Details panel under Composure > Output, expand your Output Pass.



In the settings for your new Output Pass, open the dropdown menu and select OpenColorIO Pass from the list.



Expand the Color Conversion Settings for the Output Pass. Under Color Conversion Settings:

Set the Configuration Source parameter to point to your OpenColorIO Configuration Asset.

Set the Source Color Space parameter to the color profile you want to convert from. Typically you will want to use the linear color space so your media matches the linear color space used in Unreal Engine.

Set the Destination Color Space parameter to the color profile you want to convert to. Typically you will want to match the color space used by the monitor to display the result, or another destination color space that you want.

Toggle the Enabled setting on.



When you display your composited media, the colors are changed.

Enabling the Composure Plugin

Compositing Tree Panel

Anatomy of the Composure Compositing Panel

Compositing Elements

Compositing Material

Outputting Your Composite

The process of compositing imagery together in Unreal Engine (UE) is handled by using our real-time compositing plugin Composure. It enables you to combine visual elements from different sources, such as computer generated (CG) or real-world sources to layer together into a single, seamlessly blended image while working in-Editor or in-game. For Film and Television, the visual effects (VFX) industry, compositing a single frame has primarily been an offline process, up to this point, with each frame taking some time to render.

When you start compositing with previsualization in mind, it's especially helpful in enabling directors—or other creatives working on set—get a sense of what the final render will look like, even helping alter performances or how a shot it set up. For compositors, previsualization can be used as a guide for completing their work in other third-party industry standard software, like Nuke or Fusion.

Enabling the Composure Plugin

To access the Composure compositing tools, go to the Edit menu and open the Plugins browser. Under the Compositing category, enable Composure and restart the Editor for the changes to take effect.



Compositing Tree Panel

Once the Composure plugin is enabled, access the Composure Compositing panel from the Window menu.



Use the panel to build a hierarchy of compositing Elements. These elements are objects responsible for rendering a piece of your composite scene. For example, the hierarchy above is made up of a Composition named "My_Composite." It has three Elements named "FG_Element," "BG_Element," and "Media_Plate." Each element contains a different part of the scene that is composited together. FG_Element and BG_Element are CG Layer elements that contain both foreground and background objects from the scene. Media_Plate is a Media Plate layer that is used for video input into the compositing pipeline.

When right-clicking in the Composure Compositing panel, add your own composite by selecting "New Comp Shot.mp Shot.



When right-clicking on the Composition Shot, new elements are added by selecting Add Layer Element and selecting the type of element you want to add from the Pick an Element Type selection window.



Elements can be nested under one another in a hierarchical structure to determine which Elements are available for cross-Element use in ones found higher in the hierarchy tree. Keep in mind that Elements are just Actors within the Level and can be added like any other Actor. The panel provides a way to nest these Elements for organization and exposes some controls to make them easier to use.

For portability and ease of use within the scene, be sure that your Elements are added to their own sub-Level. Since they are Level Actors, it lets you load your compositing tree in other Levels that you would potentially open.

Anatomy of the Composure Compositing Panel



The Element Row is made up of a Composition Shot composed of Elements composited within the scene. It has a row representing each layer in the currently loaded map.

The Element Name is a unique name given to each added Layer Element and is used to reference the specific Element found in the Compositing Material Graphs.

Each Composition Shot or Layer Element can be toggled on or off using the Eye button.

The Alpha box controls how opaque the selected Composition Shot or Layer Element is. Enter a value in the text box or click the drop-down and use the slider to control its visibility.

The Lock toggles freeze framing the Element. For animations or video streaming in, it lets you pause the Element's rendering, freezing its position.

The Media Output toggle lets you turn on/off the selected Composition Shot or Layer Element render result. Toggling this on for the first time prompts you to pick (or create) a Media Output Definition Asset. Provide the Asset details of your Target Output (such as a card or port).

When selecting a Composition Shot or Layer Element, the properties and attributes of the Element will be available from the Level Details panel. Compositing specific settings are found under the Composure category.

When selecting a Composition Shot or Layer Element, the Element Preview Pane appears in the Level Viewport, like a Camera Actors preview pane would. It displays the render for the selected Element and also shows error messages when the Element is in a bad state. For example, it displays "Empty" if there is no information to display.

Elements are processed in linear color space. By default, the preview is displayed with a linear to sRGB conversion and displays the images without tonemapping, which consequently makes them appear blown out. However, you have the option to change how Elements are previewed, such as adding your own tonemapping through a custom Material.

Compositing Elements

Elements are the individual building blocks used to construct a composited image which can be the Composition Shot or the individual Layer Elements. Each one makes up the composited image made up of layers or Level Actors that are individually responsible for rendering a piece of the composite scene. Layer Actors are individually responsible for rendering a piece of the composited scene.

Internal Passes

Each Element has a set of internal passes it performs. These are a sequential set of steps unique to that Element type. Each pass is a distinct step in rendering the Element in the composite. An Element without any passes does nothing. There are many different kinds of passes available and there are certain Element archetypes that come with their own predefined passes. For example, the Media Plate Element comes with Chroma Key and Despill passes already built in.

Anatomy of an Element

When selecting an Element in the Composure Compositing Tree window, the Details panel in the Level will display information and properties for this selected Element.



The Inputs attribute enables some elements to access a resource outside of the compositing system, such as using a Media texture for video input. They provide a way to route dependencies to the Element and act as a special kind of pass that can be referenced by other subsequent passes and some Element types that come with predefined inputs.

The Target Camera Actor enables some Element types that need a point of view for reference to use a Camera Actor in the Level. If left undefined, the Element searches the Level for the first Camera Actor it can find and assigns it. This can be overridden for individual elements, or let it inherit from the root Element.

Transforms are passes that take an input of some kind and alters it or uses it to generate something new. For example, color transforms take an image from one color space and puts it in another. The last transform in this list produces the Elements final render result.

There are many types of Passes, such as chroma key, despill, or even custom ones that can be added. They all share some properties but may also contain ones unique to that pass.

The Enabled flag toggles a pass on and off. When disabled, the pass behaves as though the pass were not there.

The Pass Name feeds in name that can be referenced by subsequent passes.

A pass must be uniquely named if it's to be referenced in a Material.



The Intermediate flag controls whether subsequent passes use it. By default, it is assumed that you only need it for the next pass. After that, its render target is released so that it can be used by another pass. If you need the pass result to be accessible longer, disable this flag.

Rendering for Elements and passes uses a shared render target pool. Each frame all targets are returned to the pool and redistributed. Unused targets in the pool get flushed.



Outputs are another form of pass, they don't contribute to the Element's render result. Instead, they route the result of the pass somewhere else, such as a video capture card or to the player viewport.

The Render Resolution defines the resolution output of the Element. It can be overridden or inherited from a parent and some passes have the option to override or scale this setting.

In the Preview Transforms, elements are processed in their linear color space. By default, they are previewed without any kind of tonemapping, which can cause their color to appear blown out. The optional transform on the Element enables you to adjust how the image is previewed in the Editor.

The Auto Run flag toggles the Element, preventing it from running (or rendering). The flag state is reflected by the eye icon in the Composure Compositing panel's tree view as well.

Compositing Material

The following sections detail how parts of the compositing pipeline work and come together in UE.

For a step-by-step guide to creating a basic composition with composure, see the Composure Quick Start.

Nesting Elements

Elements can be nested under one another and while any kind of Element can be placed in the hierarchy, you should put the final composition at the top with its layer elements listed below it. To add a new nested Element, right click on the desired parent element and select Add Layer Element from the context menu. Then, choose the type of Element you want to add from the window.

Nesting elements determines the render order of the Elements used in the composition. The parent element is rendered last and everything under is rendered beforehand. Parent elements can use the render result from their children in their own render passes.

Custom Material Pass

The Custom Material Pass is a transform pass that lets you add a user authored Material to the compositing pipeline. In the Material you can reference sub-elements by name.



Referencing Elements in Your Material

In your Material, create a Texture Parameter and have it auto-filled with a child Element's render result. Name the parameter the same as the sub-Element found in the compositing tree.



Since only a single color is needed for output, Post Process Materials are used for compositing these materials. Enable the Output Alpha for Post Process Materials, if needed.

Use the Details panel to plug this Material into the Material slot. If everything is set up correctly, it should start working in the viewport preview.



If you're not seeing the preview show the child Element, double-check that the name match exactly. Typos or extra spaces can cause this to fail.

If the sub-Element is disabled and not rendering, the Texture Parameter is filled with a transparent black texture. If the named Element cannot be found, the texture will use the default texture from the Material.

Referencing your Element by name in the Material is easy enough, but it makes your Material very specialized; it will only work with Element having specific names. Alternatively, give your Material Texture Parameter a generic name and set it to reference a sub-Element in the Pass's properties.



Once a Material is set on the pass, it will have a property section called Input Elements. It lists all of the Texture Parameters in the Material and let's you set them to reference a specific child Element.

Referencing Other Passes in Your Material

Like Elements, Materials can reference other passes that have already run and is how you would do progressive transforms within a single Element. For example, with the Media Plate, we do a chroma keying pass and a despill pass that used the keyed result.



If you need to reference a pass other than the one that comes right before the current pass, the other pass needs to have its Intermediate flad unchecked.

PrePass is a special parameter name that can be interpreted as reference whichever pass was run right before this. Using it in your Material makes it more portable without requiring you to set the parameter mapping in the Details panel.



Compositing Two Elements Together

By default, projects are setup to send alpha data through the post process pipeline. For CG Layers to work properly, the Project Setting Enable alpha channel support in post processing needs to be set to Linear color space only. This setting can be found under the Rendering > PostProcessing category.

To make compositing Elements together simpler in your Material, the following functions are available:

The Over node takes the input A and overlays its with input B using A's opacity to blend the two together. The node takes a flaot4 RGBA vector and expects the RGB channels to be pre-multiplied with their alpha value.



In this example below, the Over material expression is blending the the FG_Element with the BG_Element. The alpha of FG_Element is used to blend the foreground objects with the background plate.



Exposing Material Parameters

Scalar and Vector material parameters are automatically exposed to the pass Details panel under the Material Parameters category. It makes adjusting, tweaking, and experimenting with your composition simpler to do.



In this example material, the Blend scalar parameter is automatically exposed to the Element's Details panel. Adjusting it's value can be used here to make quick edits or experiment with settings while working in the Editor.





Outputting Your Composite

An Output pass is responsible for routing the different Elements' final result to some external consumer. Each Element has a place for you to add Output passes.

Clicking the add (+) button next to Outputs gives you the following selectable options:



Media Capture

Image Sequence (exr)

Player Viewport

Render Target Asset

The most common (or primary) output is to a capture card using the Media Capture pass. To quickly, or conveniently, add a Media Capture pass to your Element, use the tree panel button:



Exporting Composition with Sequencer

An alternative workflow is to render out composites and other layers or passes through Sequencer.



For further reading, see Real-Time Compositing with Sequencer.

1 - Load Composure

2 - Add a Root Comp Element

3 - Add a Media/Video Element

4 - Add CG Elements

5 - Setup a Compositing Material

6 - Output Your Comp

The most basic of composites is the three piece comp: a CG background, a middle media (video) plate, and a CG foreground. In this topic, we'll demonstrate how to use composure to build a basic three piece comp.

1 - Load Composure

Steps

Enable the Composure Plugin.



Open the compositing tree panel (listed as Composure Compositing in the Window menu under Virtual Production section).



2 - Add a Root Comp Element

Next, add a root Element to the compositing tree.

Steps

Right-click in the compositing tree panel, and select Create New Comp from the menu. Then, select Empty Comp Shot from the Pick a Comp Class dialog.



This Element will not render anything immediately as it represents your final composite. This Element will be responsible for combining all of the other Elements.

For portability, make sure your Elements are added to their own sub-level. Since Elements are level actors, this lets you load your compositing tree in other maps.

3 - Add a Media/Video Element

Once you have a top-level comp Element, you need to add child Elements. Child Elements feed into their parent (for compositing).

Steps

Add a Media Plate to the comp tree.Right-click on the comp Element in the compositing tree panel, and then select Add Layer Element from the menu. When prompted to pick a Element type, select Media Plate.



Without a media source, the Media Plate Element will be blank. You can set up a default still image (like we have in the GIF above), in your game config file:[/Script/Composure.ComposureGameSettings] StaticVideoPlateDebugImage="/Game/Path/To/My/TextureAsset"

Set your Media Source. By default, your media Element will not be connected to a media source (such as a streaming video). You can apply a media texture to act as an input In the Element's details. Select the new media Element. Then, in the details panel, find the Media Source section (under Composure→Inputs). The MediaSource texture property will be empty.



Feeding a live video feed into the engine via capture card produces a Media Texture. So you hook that into the compositing system in the exact same way. For more details on how to set that up, look into using capture cards with Media Bundles in Unreal Engine.

Configure the Chroma Key Color.The Media Plate Element has a set of predefined transform Passes on it. Those Passes are for adjusting the media image before it gets composited. The first of those passes is for Chroma Keying. To pick a Chroma Key Color, under Transform Passes navigate to the keying Pass, then find the one named Chroma Keying. After expanding Chroma Keying, you'll find a Key Colors property. Add a new Key Color using the picker button next to the color box.



Clicking the picker button will open up a large picker window to enable you to select a color. To pick a color, click the mouse anywhere on the image to sample that pixel. Click and dragging will average the sampled pixels together, so you can get a more homogenous chroma color. Once you're happy with the result, click Accept.

You can add as many key colors as you wish. This helps when you have multiple shades of green across the backdrop, and keying one color isn't enough. However, for each Key Color you add, the Element performs a full Pass, running the keying material once for each color in the list. This may be a performance concern for some.

Along with the key color, there are many other settings that can be adjusted to perfect the keying. Review the Material Parameters section inside the Pass.



The built-in keyer expects the image to be in linear color space. If your image is coming in in a different color format (such as logC), then you will have to add a colorspace transform before the keying is done. Alternatively, you can replace the keyer with a material of your own.

In addition to the Chroma Keying Pass, there is a separate Despill Pass for removing green bounce on your subject. For more details on chroma keying and despill, see the blog post here.

Preview the Results.Sometimes it's hard to get a sense of how good of a job your keyer is doing. For every Element, you can open up a larger preview window, and look at individual color channels for that image.



The Key Picker window and the Level Editor preview pane also both have this functionality.

At this point in the process, don't worry if it's not perfect. You can always adjust it later when you preview the whole composited scene.

4 - Add CG Elements

Similar to adding the media Element, we want to add Elements for foreground and background layers.

Steps

Add a CG Layer.Right-click on the top-level comp Element in the tree panel, and then select Add Layer Element from the menu and pick CG Layer.



Add two CG Elements – one for foreground objects, another for background objects, and name them appropriately: fg_element, and bg_element.

Link to a Scene Camera.CG Elements requires a camera in the world to cue off of – the camera tells them the viewpoint to render from. Without a camera in your scene, CG Elements will display a "Missing Camera" warning message. To resolve this, simply add a camera actor to your scene.



If there are multiple cameras in your scene, you can specify which one to reference in the Element's details (under Input, look for Camera Source).

Setup Actor Layers.Now that you have two CG Elements (one for foreground, and one for background), you need to specify what scene actors should be rendered to each.For this, we will leverage the level editor's layer system. In our test scene, we've added some basic primitives – a cube, a cone, a sphere, and a cylinder. In this case, the cone and cylinder are in the foreground, and everything else in the background. To start, create an editor layer for just the cone and cylinder.



Now, in the foreground Element (fg_element), find the Capture Actors property (under Composure→Inputs), and add an entry to it. The Capture Actors list specifies what the CG Element should render.



In the new Capture Actors entry, set the ActorSet property to the ConeAndCylinder layer that we created earlier. Because the entry's InclusionType is set to Include, it will render only those actors.

Property

Description

Include

Render only the actors in the specified layer.

Exclude

Render everything except the actors in the specified layer.

You can add as many Capture Actor layers to the Element as you wish. You can mix/match includes and excludes.For the background Element, we want everything except the ConeAndCylinder layer. So we use the same layer, but switch the InclusionType to Exclude.

For your CG renders to have the proper opacity for compositing, you will need to set Enable alpha channel support in post processing to Linear color space only enable in project settings:



Click image to expand

5 - Setup a Compositing Material

Now that you have four Elements (the top-level comp, a Media Plate, and two CG Elements), you can layer them all to produce your comp. The top-level comp Element is responsible for merging all of the other Elements. We're going to add a transform Pass to the comp Element and set it up to composite the other three layers.



Steps

Add a Comp Transform Pass.Select the comp Element, and then in details find the Transform Passes property. Add an entry to the Transform Passes list. The default entry is Custom Material Pass, which is what we want.



Create a Comp Material.

The new Pass expects a material for rendering. Expand the Pass's details and create a new material for its Material property.



Set the new material to be a Post Process material – this ensures that you're outputting the result to the correct channel.



In the new material, we need texture samplers for each of the three sub-Elements. To do this, create three texture sampler parameters and name them to match the child Elements. These texture params will get automatically filled out with the results from the three child Elements. To combine the three Elements all you need are a couple Over nodes. The Over node takes input A and layers it over input B, using input A's alpha. We want to sandwich the media plate between our two CG layers.



Set one Over node so the media plate (A) renders over the bg Element (B).

Next, use the result from that Over node and plug it into B on another Over node.

Lastly, put the fg Element on top by plugging it into A on that second Over node.

The second Over node's output should be plugged into the material's Emissive Color channel.

Save and apply the material.

Review your results back in the compositing window. You should have a single image with all three Elements composited together.

The Over node expects a float4 input, so use the texture sampler's RGBA output pin, not its top RGB pin.

The Over node uses input A's alpha for Blending. By default, projects are not set up to pipe alpha data through the post process pipeline. So for the CG layers to work, you have to enable this project setting.





Click image to expand



6 - Output Your Comp

If you're happy previewing your comp in the editor, then ignore this last step. However, if you want to route the result of your comp to disk or run it out through a capture card, then you will want to use an Output Pass.

In this example, we want our comp to be broadcast via a capture card.

Steps

In the top-level comp Element's details, find the Outputs property and add an entry to that list. The default is Media Capture, which is what we want.



In the new output Pass, you will need to specify the target in the Pass's Capture Output property, and create a new asset for it.



Configure this asset for your capture target, and you should be all set. The comp Element should start broadcasting.

Using Sequencer

Alternatively, you can render out comps and AOVs with Sequencer, our in-engine cinematic editor. For more information, see Real-Time Compositing with Sequencer.



Rendering Out Elements and AOVs

Sequencer, our in-engine cinematic editor, can be used in conjunction with the Composure compositing system.



Primarily, Sequencer can be used to:

Control the scene camera (referenced by the compositing system).

Render out composites and their contributing pieces, including Arbitrary Output Values (AOVs). This can be useful for compositing outside of the engine.

Rendering Out Elements and AOVs

Any Composure element can be added to a sequence to indicate that its output should be exported when rendering out the sequence using the Render Movie Settings dialog with the ComposureExport output format.





Click image to expand.



When such elements are rendered as part of this process, their final output will be written out to disk as an EXR image using the filename format specified in the dialog. Additional format specifiers can be included in the directory and filename options for the {element} and {pass}.

When multiple elements are included for Export Output in Sequencer, they will write over the same image file if {element} is not included in the name.





Click image to expand.



Additional AOVs to be exported with each element can be specified on each element by configuring the Buffers to Export on any CG Capture.



Custom AOVs may be implemented by adding new Buffer Visualization materials, and adding them to the [Engine.BufferVisualizationMaterials] config section with the following format:

CustomAOV=(Material="/Game/AOVs/CustomAOV.CustomAOV", Name=LOCTEXT("CustomAOV", "CustomAOV"))

Basic Compositing Elements

Empty Comp Shot

Media Plate Element

CG Layer Element

CG Matte Element

Advanced Element Types

Texture Element

Depth Element

Radial Element

Ramp Element

Roto Paint Element

Elements are the individual building blocks used to construct a composite. Each Element represents either a layer of a comp, or the comp itself. They are level actors individually responsible for rendering a piece of the composited scene.



There are many different Element types. All of which, you can configure and change. Elements are Blueprintable, and you can create your own custom Elements inheriting from by ACompositingElement (or its sub-classes).

Basic Compositing Elements

Empty Comp Shot

This acts as the starting point for most comps. It doesn't contain any Passes, and requires the user to fill it out.



Media Plate Element

This preset Element comes with all the Passes needed to pipe a video into the compositing system, and apply Chroma Keying on top of it.





CG Layer Element

This preset Element is responsible for rendering actor objects from the virtual scene. Use the Capture Actors property to specify which actors you want to include/exclude.





CG Matte Element

This Element is like a plain CG Layer Element, but it renders the CG objects into a black/white mask texture. This is helpful for garbage matting, or setting up a holdout mask to be used with a keyer.





Change the Element's Matte Type property to invert the mask.

Advanced Element Types

The Advanced Elements are available via the All Classes toggle in the New Element dialog. These additional Elements were created via Blueprints, and can be modified to suit specific use cases.

For the Advanced Elements to be listed, your first have to load their respective Blueprints. You can find the Advanced Element Blueprints in the content browser under the Composure Plugin's Blueprints/CompositingElements folder (make sure your content browser is set to view Engine and Plugin content).

Texture Element

This Element is a utility Element for introducing an external texture into the compositing system.



Depth Element

The Depth Element is similar to the CG Layer element, but produces an image which expresses the depth of the included actors.





Radial Element





Ramp Element





Roto Paint Element





Over

In

Out

PreMult

UnPreMult

KeyMix

To make compositing easier, UE5 has a series of nodes to serve some of the most common compositing operations. Here, each one is briefly highlighted and has an explanation of its purpose.





Click image to expand.



The compositing material nodes expect a float4 input, so make sure you're passing in RGBA and not just RGB.

Over

This node layers one image (A) over another (B), using the alpha from input A.



This node expects that the input color channels are pre-multiplied with the image's alpha.

In

This node returns the portion of A that is inside the shape of B.



Out

This node returns the portion of A that is outside the shape of B.



PreMult

This node multiplies the input's RGBA channel by its alpha.



UnPreMult

This node divides the input's RGBA channel by its alpha.



KeyMix

This node layers two images together using a specified mask.



Blueprintable

Shared Settings

Inputs

Media Texture Compositing Input

Texture Input

Transforms

Compositing Element Material Pass

Compositing Post Process Pass

Compositing Tonemap Pass

Multi Pass Chroma Keyer

Multi Pass Despill

OpenColorIO Pass

Outputs

Compositing Media Capture Output

EXRFile Compositing Output

Player Viewport Compositing Output

Render Target Compositing Output

A Compositing Pass is an object belonging to a compositing Element. Passes are individual steps that are executed when rendering the Element, and are run in sequential order.

There are three compositing pass types:

Inputs

Transforms

Outputs



Most Passes are responsible for rendering an image. For Inputs and Transforms, those images are available to subsequent passes and can be referenced in rendering materials.

Blueprintable

Passes are Blueprintable, so you can easily create your own Pass and use it with the compositing system. Just create a Blueprint and inherit from CompositingElementInput, CompositingElementTransform, or CompositingElementOutput.

Shared Settings

Each Pass has its own set of properties, but every Pass shares the below properties:

Property

Description

Enabled

Like Elements, individual Passes can be disabled. When turned off, the Element behaves as if the Pass is not there.

Pass Name

Passes have names so that they can be referenced by other subsequent Passes. A Pass must be uniquely named if you want to reference it in a render material.

Intermediate

For each render Pass, a render target is allocated. By default, it assumes that you only need that result through the next Pass. After that, to save on render resources, it releases its render target so it can be used by another pass. If you need the Pass's result to be accessible longer, uncheck this box.

Inputs

Media Texture Compositing Input

This Pass is responsible for routing video into the compositing system. It requires a media texture to reference. Its Media Source is processed through the Pass's Material.



Without a Media Source, the media Pass will be blank. However, you can set up a default still image in your game config file: [/Script/Composure.ComposureGameSettings] StaticVideoPlateDebugImage="/Game/Path/To/My/TextureAsset"

Texture Input

This Pass provides you with an easy way to source static textures into the compositing system.



Transforms

Transforms are responsible for taking input image(s) and spitting out a processed image. Traditionally, this is where compositing is done – a Material Pass that references sub-Elements, combining them.

Compositing Element Material Pass

This Pass lets the user author a custom material, in which they can reference other Elements/Passes. This is the bread-and-butter of the compositing system.



Compositing Post Process Pass

This Pass applies a set of post processing effects on the previous Pass (inoperable if it's the first pass).



Only certain effects are available (Bloom and Tonemapping). Users can create more effects by creating a sub-class of ComposurePostProcessPassPolicy.

Compositing Tonemap Pass

This Pass applies finishing post-process tonemapping on the previous Pass.



This is helpful for converting images back from linear color space. It is useful as a preview transform, or on an output Pass (intermediate material operations expect linear colors).

Multi Pass Chroma Keyer

This Pass is used by the Media Plate Element to key an image. The Key Colors property specifies the color(s) to turn transparent.



If needed, you can switch out the material for your own chroma keyer using the parameters listed in the Required Material Parameters field.

This Pass runs multiple times, once for each key color.

Multi Pass Despill

This Pass removes chroma bounce from the image ("spill" from the green screen).



Much like the Chroma Keyer Pass, you specify Key Colors that you want removed. Also like the Chroma Keyer Pass, this Pass runs multiple times – once for each key. You can switch out the material for your own despill process (it just requires the parameters listed in the "Required Material Parameters" field).

You can find information on chroma keying and despill in UE4 in this blog post.

OpenColorIO Pass

This Pass is used to apply a color conversion (color space transform) onto the input image pixel colors.



Outputs

Output passes define a destination for the Element's fully processed image to be broadcast to. Some outputs perform a transform of their own before routing the image.

Compositing Media Capture Output

This Pass routes the Element's result to a media capture target. The Capture Output field expects a media output asset, which is a configuration file detailing where to route the image to (capture card, port ID, pixel format etc.).



This Pass has a Color Conversion transform associated with it, that runs prior to outputting the image.

EXRFile Compositing Output

This Pass will save a .EXR image file to your hard drive for each frame the Element renders.



This Pass will start writing out images (one for each frame) as soon as it has an Output Directory. For more control, disable the Pass first.

Player Viewport Compositing Output

Use this Pass to take over the player's viewport in game, and replace the display with the Element's result.



This Pass has a Color Conversion transform associated with it that it runs before displaying the image. Play in Editor to see it in action.

Render Target Compositing Output

This Pass will write the Element's result to a render target.



Use the Render Target field to specify which asset.

Rendering to Multiple Displays with nDisplay

Texture Share Quick Start

Sample Projects

Sync Policies

Connection Sync Mode

Frame Sync Mode

Texture Sync Mode

Using Texture Share with nDisplay

Known Limitations

Texture Share efficiently sends and receives GPU data between processes by bypassing the CPU and its expensive memory-copy operation by keeping the data stored in GPU memory.

Examples of shared data include GPU textures, projection and camera matrices, and depth buffers. Texture Share supports synchronization mechanisms and thread barriers to ensure coherency between applications.

Texture Share can be integrated into your project through the following methods:

C++ SDK integrated with DirectX11 and DirectX12

Blueprints

Support for nDisplay



Example of Unreal Engine sharing the viewport with an external application. The application is using the viewport as a texture on a rotating cube.

Sample Projects

Sample C++ projects are included with the engine source code in the folder Engine/Source/Programs/TextureShare/Samples/ThirdParty. There are examples for how to use both DirectX11 and DirectX12 with Texture Share. See the Quick Start for details on how to get started with Texture Share.

Sync Policies

There must be a sender and receiver for each interaction in Texture Share to share the GPU data. When the applications exchange data, the sender and receiver should use mirrored priorities for the send and receive operations.

For example, let Unreal Engine be the sender and a third party DirectX application be the receiver:

Unreal Engine would execute Send and then Receive.

The third party application would execute Receive and then Send.

Texture Share provides multiple options to synchronize at various stages of the exchange to control blocking behavior. The three stages are described in the following sections.

Connection Sync Mode

Connection Sync Mode defines the synchronization policy when the client and server connect. The following table describes these policies.

Option

Description

Default

This mode uses the module's global settings. Default connection sync policies are:

Client: SyncSession

Server: None

None

This mode does not block when the remote process connects to the texture shared mechanism.

SyncSession

This mode blocks until the remote process successfully connects and is ready to exchange data.

Frame Sync Mode

Frame Sync Mode defines the synchronization policy for generated frames. The following table describes these policies.

Option

Description

Default

This mode uses the module's global settings. Default frame sync policies are:

Client: FrameSync

Server: FrameSync

None

This mode does not sync frames with the remote process and can skip frames.

FrameSync

This mode ensures both applications exchange frames without skipping. This mode guarantees frame indices are consistent between processes.

Texture Sync Mode

Texture Sync Mode defines the order of operations for reading and writing data when the texture sharing connection mechanism is established. The following table describes these policies.

Option

Description

Default

This mode uses module global settings. Default texture sync policies are:

Client: SyncRead

Server: SyncRead

None

This mode skips pairing textures and does not block on the write operation from the remote process before reading.

SyncRead

This mode skips pairing textures but blocks waiting for the write operation to end in the remote process before reading.

SyncPairingRead

This mode blocks during texture pairing and blocks waiting for the write operation to end in the remote process before reading.

Using Texture Share with nDisplay

nDisplay supports Texture Share for sharing a viewport and displaying received textures on it. You can access the shared viewport texture from the viewport's id.

To display textures received from another application on an nDisplay viewport, use nDisplay's post processing to define the texture share item and assign it to an nDisplay window.

See the nDisplay Configuration File Reference for further details on sharing and receiving textures in nDisplay.

Known Limitations

Texture Share is currently in beta. The following are known limitations of the feature.

Texture Share SDK currently only supports DirectX11 and DirectX12.

Maximum length of the Texture Share item name is 128 characters.

Maximum Texture Share items allowed per process is 100.

Maximum textures per Texture Share item is 10.

A Texture Share item is a container that has a pointer to the DirectX texture and auxiliary buffers such as projection, camera, and rotation matrices.

Texture Share

Rendering to Multiple Displays with nDisplay

Step 1 - Getting Started with the SDK

C++ SDK Integration

Include Files

Initialize

Render Thread

Clean Up

Step 2 - Getting Started in Unreal

Step 3 - Send Unreal Scene as a Texture to a DirectX Application

Step 4 - Send Textures to External DirectX Application

Step 5 - Receive Textures from a DirectX Application and Display Them in Unreal

By the end of this guide, you will be familiar with:

Building the Texture Share SDK from source.

Integrating the C++ SDK with DirectX11 and DirectX12 applications.

Using the Unreal Engine plugin and Blueprints.

Sending the project's rendered viewport in Unreal to an external application.

Sending and receiving textures from an external application during your Unreal session.

Step 1 - Getting Started with the SDK

In order to use the Texture Share SDK, you must download and build the engine from source. See Downloading Unreal Engine Source Code for details on where to find the engine source code.

Building the engine in Visual Studio won't build the TextureShareSDK project by default.

Follow these steps to build the Texture Share SDK:

Open the UE4.sln file in Visual Studio.

In the Solution Explorer panel, navigate to Programs > TextureShare. Right-click the TextureShareSDK project and build it.



When the project finishes building, it generates .lib and .dll files in the folder Engine\Binaries\Win64\TextureShareSDK.

C++ SDK Integration

The Texture Share API provides granular control over the texture sharing process.

To use Texture Share, you must establish a session between exchanging parties before you can perform any read or write operations. Each step of the process provides control over a variety of synchronization states that you can customize for your project.

C++ applications using the Texture Share API adhere to the following structure:

Client application creates texture share object by specifying its name.

Textures are registered with the texture share object, which can hold multiple textures, and the texture session is started.

On each frame, data can be written and sent to the other application or read. The data buffers must be locked before read or write operations and unlocked afterwards.

Step 3 is repeated for every frame until the session ends.

The following section shows how the Texture Share API is used in the DirectX12 sample project TextureShareD3D12Client.vcxproj located in Engine/Source/Programs/TextureShare/Samples/ThirdParty/TextureShare_ClientD3D12.

This example uses DirectX12 but the process is the same for DirectX11. You can follow along with the DirectX11 sample project in the ThirdParty folder with some modifications.

Include the header files TextureShareD3D12Client.h and TextureShareDLL.h.

Link the static library file using a pragma comment. Use TextureShareSDK.lib if you're building with the Release configuration in Visual Studio and TextureShareSDK-Win64-Debug.lib if you're building with the Debug configuration.

The following steps describe what to intialize and how to start a Texture Share session in C++.

Load the render pipeline and assets with the DirectX APIs:

Create a DirectX device.

Create a GraphicsCommandList.

See D3D12HelloTexture::LoadPipeline() and D3D12HelloTexture::LoadAssets() for examples.

Create the Texture Share item:

Set the share name. Maximum length is 128 characters.

Set the application as the client with ETextureShareProcess::Client.

Define the sync policies for the Texture Share session. See Sync Policies for more details. In this example, all the sync policies are set to None so the synchronization events will be non-blocking.

Specify which graphics API is being used. Currently only DirectX11 and DirectX12 are supported.

Register the texture with the Texture Share item:

Set the share name of the session.

Set the texture name.

Set the texture resolution.

Define the texture format and value.

Set whether the texture is readable or writable.

Define the start of the scope of the Texture Share session:

The following steps describe how to access the shared memory in the render thread. The steps show how to use both the read and write operations.

Define the start of the scope for the frame in the Texture Share session:

Read the texture in the render thread:

Put a lock on the texture.

Access the texture memory.

Release the lock on the texture.

Write to the texture in the render thread:

Check if the session is valid.

Put a lock on the texture.

Access the memory.

Release the lock on the texture.

Get frame data to access the information in the auxiliary buffers, such as the projection and camera matrices:

Define the end of the scope for the frame in the Texture Share session:

Present the frame to display.

The following steps describe how to end the Texture Share session when the application exits.

Define the end of the scope for the Texture Share session:

Delete the Texture Share item and release the memory:

Step 2 - Getting Started in Unreal

Follow these steps to use the Texture Share plugin and to access the Texture Share Blueprints in Unreal Engine.

In the Editor's main menu, choose Edit > Plugins to open the Plugins Editor.

In the Plugins Editor, find the Texture Share plugin in the Misc section.



Check the Enabled checkbox and restart the Editor.

In the Content Browser, expand the View Options dropdown at the bottom right of the panel. Check Show Engine Content and Show Plugin Content.



Click the folder icon at the top of the Content Browser to choose a content path. Find TextureShare Content in the list and select it.



In the Blueprints folder, there are two Blueprint objects you can add directly to your scene:

BP_TextureShare_Scene: This Blueprint shares the rendered frame of the whole Unreal scene.

BP_TextureShare_Postprocess: This Blueprint sends and receives specific Texture objects.



In the Materials folder are textures and materials you can use with the BP_TextureShare_Postprocess Blueprint:

RTT_TextureShare_Backbuffer: A Texture Render Target 2D asset.

M_TextureShare_RTTBackbuffer: A material that samples the RTT_TextureShare_Backbuffer texture and uses it as an Emissive Color.



The remaining steps in this quick start describe how to use each Blueprint and connect them to other DirectX applications.

Step 3 - Send Unreal Scene as a Texture to a DirectX Application

Follow these steps to stream an Unreal scene to an external DirectX application.

Navigate to the folder Engine/Source/Programs/TextureShare/Samples/ThirdParty/TextureShare_ClientD3D11 and open the sample project `TextureShareD3D11Client.vcxproj`in Visual Studio.

Set the Solution Configuration to Release in Visual Studio.

Build the project in Visual Studio.

Navigate to the folder Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D11\Binaries\TextureShareD3D11Client-Win64-Release and launch the TextureShareD3D11Client.exe application.

Open your Unreal project in Unreal Engine and add the Blueprint BP_TextureShare_Scene object to your scene.

Select the BP_TextureShare_Scene object to open its Details panel.

Ensure the Share Name parameter is set to the same name as the ShareName variable in the sample project: vp_1.

Press Play in Unreal. The rendered frames from your Unreal scene are streamed as a texture to the client application and applied to the rotating cube.



Step 4 - Send Textures to External DirectX Application

The previous step described how to share the Unreal scene as a texture in a separate process. Any texture object in the project can also be sent to an external application.

Follow these steps to share any texture object in your Unreal project to the sample DirectX application.

Navigate to the folder Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12 and open the sample project TextureShareD3D12Client.vcxproj in Visual Studio.

Set the Solution Configuration to Release.

Build the project.

Navigate to the folder Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12\Binaries\TextureShareD3D12Client-Win64-Release and launch the executable built by the project: TextureShareD3D12Client.exe.

Open your Unreal project in Unreal Engine and add the Blueprint BP_TextureShare_Postprocess object to your scene.

Select the BP_TextureShare_Postprocess object you added to the scene to open its Details panel.



Expand the Postprocess section.

Expand the Send section under Postprocess. There are two Send array elements. The Ids must correspond to the texture names defined in the file D3D12HelloTexture.cpp in the sample project:

Set the first Send element's Id to SceneDepth.

Set the second Send element's Id to BackBuffer.



Press Play in the Unreal Editor.

Update the Texture parameters for both Send elements with texture objects. The engine streams the textures to the client application and applies them to the rendered triangles.



Step 5 - Receive Textures from a DirectX Application and Display Them in Unreal

The previous step described how to send textures to an external DirectX application. This section describes how to receive textures from another application.

Follow these steps to receive textures from the sample DirectX application.

Navigate to the folder Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12 and open the sample project TextureShareD3D12Client.vcxproj in Visual Studio.

Set the Solution Configuration to Release.

Build the project.

Navigate to the folder Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12\Binaries\TextureShareD3D12Client-Win64-Release and launch the executable the project built: TextureShareD3D12Client.exe.

Open your Unreal project in Unreal Engine and add the Blueprint BP_TextureShare_Postprocess object to your scene.

Select the BP_TextureShare_Postprocess object you added to the scene to open its Details panel.

In the Details panel under Default, expand the Postprocess section.

Expand the Receive section under Postprocess. There is one Receive array element. The Id for this element must correspond to the texture name defined in the file D3D12HelloTexture.cpp in the sample project:



Set the Receive element's RTT parameter to the texture RTT_TextureShare_Backbuffer provided in the TextureShare plugin.



Now your Unreal project is set up to receive textures from another application using TextureShare.

In the example below, the Unreal Engine session is started. Unreal is sending a texture to the TextureShareD3D12Client application and receiving the backbuffer from that application. The pictures on the wall in the scene are using a material that's sampling the RTT_TextureShare_Backbuffer texture to display what's received in real-time.



Pre-Calibration Setup

Green Screen and Camera

Calibration Specific Equipment

Steps

Shared Controls

Calibration Process

1. Device/Camera/Tracker Selection

Device Selection Controls

Tracker Selection

2. Lens Calibration

Reprojection Error

Angle of View

3. Alignment Calibration

Phase 1 - Align w/ Model

Phase 2 - Adjust Sample

Phase 3 - Repeat

Adjustment Controls

Preview the Result

4. Alignment Adjustment

Making Adjustments

Adjustment Controls

5. Compositing Calibration

Chroma Key Settings

Other Compositing Settings

6. Garbage Matting

Garbage Matting Controls

End Result

The goal of calibration is to have the virtual and physical cameras match up in the virtual world.

At runtime, the game needs to know a few things, like:

The type of camera and lens that you're using.

Where your camera is in relation to your virtual scene.

And to composite your scene, the game needs to know things like:

The color of your chroma backdrop (usually green).

How aggressively to cut out the chroma color.

Areas you want fully cut out from the camera frame.

The game needs to know these things so the virtual camera can emulate the physical one. This is where the calibration tool comes into play. The calibration tool lets you configure all of these settings at once, and produces a calibration settings file with that information. The settings file can then be reused across different games.

Pre-Calibration Setup

Before you can start a Mixed Reality capture, you will need the right equipment. Here is quick overview of the equipment you will need, and some tips on how set it up. This include the basic green screen and camera setup for the capture process, as well as the equipment and software needed for calibration.



Video Camera UE4 only supports a very specific set of video capture devices; see Supported Video Devices for the current list of the supported devices. Using a device from the list, connect it to your PC for streaming.

Chroma backdrop For chroma keying, we generally use a green screen. When setting up the green screen you will want to make sure it's taut, minimizing any wrinkles, especially behind your subject. If you are setting up lighting, you will want to make sure not to cast shadows directly behind the subject. You want a smooth, flat color. The more shades of green that there are across the backdrop, the harder it is to chroma key. It helps if the subject is far away from the backdrop as possible. If you plan on filming the subject's feet, consider a green screen for the floor as well.

Camera Mount For initial setup (calibration), your camera needs to be static. If you are using a webcam this may be as simple as attaching it to your desk/monitor. Another option is mount the camera to a tripod.

Multi-Mount + Tracker (Optional) If you plan on moving the camera around while filming, you will want attach a tracking device to the camera, such as an HTC Vive Tracker. In addition, connect the camera and tracker together with a multi mount, so that they stay firmly locked in place.

There are a few additional items required specifically for the calibration process (as opposed to the capture process).



HTC Vive or Oculus Rift The calibration tool requires one of these two VR systems to work. The tool uses the controllers' tracking to evaluate the location of the camera. If this is the first time you've set up an HTC Vive or Oculus system, you will need to complete their setup process first for calibration to work properly.

Printed Checkerboard Pattern Print and attach a printed checkerboard pattern to a flat rigid surface (like a piece of cardboard). You can find an example of this checkerboard pattern included with the calibration tool download.

When taping down the checkerboard printout, make sure not to cover the checkerboard pattern itself with tape (even clear tape can cause specular reflections that make it hard for the camera to read).

Steps

Once the equipment is set up, you can download the calibration tool from here. Once you've downloaded the file, unzip it and launch MRCalibration.exe.

The calibration process is divided into distinct steps. The individual steps are discussed further below.

Device/Camera/Tracker Selection

Lens Calibration

Alignment Calibration

Alignment Adjustment

Compositing Calibration

Garbage Matting

During calibration, at the end of each step your progress is saved. So you can exit and return to the tool if needed. Once the calibration process is complete, the tool generates a settings file that you will then use to start a MRC session in other projects.

Your calibration progress is recorded in the setting file. If you want to restart the calibration process, you will need to delete the settings file. The settings file is named MrcCalibration.sav, and can be found under the tool's /Saved/SaveGames/ directory.

While each step has its own distinct controls, there are some controls that are used consistently through the tool:

Enter : Next/Confirm/Accept/Submit

End : Skip (only applicable when step requirements have been met - some steps can't be skipped)

P/Thumbstick : Preview

M : Mirror the video feed

R : Reset altered settings

Esc : Exit

The tool is rough around the edges, and usability can be improved in places. The tool is functional, but we plan on improving the usability of it in later releases. We welcome your feedback!

Calibration Process

1. Device/Camera/Tracker Selection

If you have multiple video capture devices connected to your PC, you have to specify which one you want to use. Use the Up/Down keys to cycle through them.



Additionally, each camera may have multiple formats and resolutions available to it. We try to auto-select the best format and resolution, but you can use Left/Right to change the selection.

The resolution of the camera feed does not affect the output resolution of the Mixed Reality capture. The output resolution of the capture is controlled by the game project you will be capturing from. The resolution of the camera feed only controls how clear the feed is within the scene.

Up/Down : Select video capture source

Left/Right : Select video capture format

Tab : Select camera tracker

If you're planning on moving your camera while filming, you will need to attach it to a tracking device.

Before continuing to the next step, you can use the Tab key to cycle through the available tracking attachments. For the HTC Vive, the first tracker will be named "Special_1" in the attachments list.

After you have made the appropriate selections, press Enter and continue to the next step.

2. Lens Calibration

Different camera lenses bend and distort the picture in different ways (think of a fisheye lens). You don't want that distortion to be carried over into the captured scene, so use this lens calibration step to figure out how to undistort the image.

During this step, you will need a printout of the checkerboard image that you downloaded along with the calibration tool. In this step, the calibration tool continuously takes screenshots using the checkerboard pattern as a baseline.

Hold the printout at different locations in front of the camera. Use different angles and depths, especially around the edges of your frame, so that the calibration tool gets a wide collection of samples. The text at the top of the screen will change to let you know when the calibration tool has collected enough samples.

If your camera is set to auto-focus, you might find it helpful to disable auto-focus during this step.

After the calibration tool has collected enough samples, the tool will show you a preview of the undistorted feed. If the feed looks acceptable, press Enter to continue. If needed, you can add more samples, or press R to reset and start over.

A good way to tell if the undistortion process is working is to find elements in frame that should be straight (wall corners, doorways, etc.). Lens distortion will often warp straight edges (especially towards the edge of the frame).



The reported "reprojection error" lets you know how accurate the process thinks it is. The lower the reprojection error value, the better. You're in great shape if the value is under one!

Probably the most important use of this step is to approximate the camera's angle-of-view (or FOV, ‘field-of-view').

The FOV determines how much of the world the camera can see, and it is important that the FOV of our virtual camera matches this as closely as possible.

If you already know the FOV of your camera (in degrees), you can use the mrc.FovOverride console variable to set it.

Most USB camera manufacturers list the diagonal-FOV (DFOV) for their devices. However, we are interested in the horizontal-FOV (in degrees). You can compute the horizontal-FOV from the diagonal-FOV with the below formula, using the height (h) & width (w) of the resolution you selected in the previous step.



There are also ways to calculate the horizontal-FOV for DSLR lenses.

If you do not know your camera's specific FOV offhand, don't worry, this step will approximate it for you.

If you have a camera with an adjustable lens, you will want to be very careful not to adjust the zoom after you've completed calibration. Adjusting the zoom will change the physical camera's field-of-view (FOV), but not the virtual one. The virtual camera will use the FOV that was used during calibration. If you adjust the camera's zoom after calibration, you will need to repeat the calibration process.

3. Alignment Calibration



This step requires you to rerun the Align and Adjust phases until complete.

Align the controller with an on-screen model.

Adjust the sampled alignment.

Repeat.

It is important to cover your headset's sensor, so that we can get accurate tracking data from your controllers.

For the HTC Vive, make sure that the controllers are on before you launch the tool. Otherwise, the calibration tool may not display models to align with (the tool needs to recognize the type of controllers that you are using).

On screen, there will be a pink/fuschia model to align your controller with. Hold the controller up to the screen and pull the trigger when the controller and the model are lined up.

Once you've pulled the trigger, the screen will freeze frame, and switch into the next phase.

Don't expect to be wholly accurate when you first pull the trigger (shaky hands, etc.). In this phase, you adjust the last sample so it is more exactly aligned in the frame.

In total, there are 11 points for you to align with. You don't have to go through all of them, if at any point you think the alignment is satisfactory.



Up/Down : Move the model vertically

Left/Right : Move the model horizontally

Num +/- : Zoom the model in/out

Alt + Up/Down : Rotate the model vertically (pitch)

Alt + Left/Right : Rotate the model horizontally (yaw)

Alt + Num +/- : Rotate the model left & right (roll)

H : Hide the model & its outline

Alt + H : Hide the model only (leaving its outline)

P : Preview alignment

Enter : Accept alignment

As you take samples, the screen will show a series of color coded icons (a cross and target). How close each pair is gives you an idea how close the alignment is. You want all pairs to be as close as possible, though don't worry if one is wildly off (it may have been an inaccurate sample).

You can preview how the alignment is coming together by holding P (or the thumbstick). If you're happy with the results and wish to skip the rest of the alignment points, press the End key.



Video Lag:There will likely be some lag between the video feed and controller tracking. It can make it hard to tell if the two are properly aligned. To combat this, you can use the console variable, mrc.TrackingLatencyOverride to introduce delay so that they're more in sync.

4. Alignment Adjustment

Up to this point, you've only adjusted the alignment one sample at a time. This single sample gives the calibration tool a good approximation of the camera's position, but the calibration is likely better in some corners of the frame than others.



In this step, there are five white boxes on-screen. Move one of your controllers to each of the boxes and pull the trigger in each.

You want to perform this process at the same depth (distance away from the camera) that you plan on filming from.

Each box will disappear when it's taken a sample for that region. The model tracking with your hands needs to be fully inside the box for it to take a sample.

Once you've hit all 5 boxes, the screen will change to a split-screen like view.



Like in the previous alignment process, move, rotate, and scale the models to match the image.

Up/Down : Move the models vertically

Left/Right : Move the models horizontally

Num +/- : Zoom the models in/out

Alt + Up/Down : Rotate the models vertically (pitch)

Alt + Left/Right : Rotate the models horizontally (yaw)

Alt + Num +/- : Rotate the models left & right (roll)

```` : Adjust FOV up & down (careful)

R : Reset adjustments

P : Preview alignment

Enter : Accept adjusted alignment

You can see how adjusting/optimizing for one sample can throw off the others.

Rotating in this step is a little hard to wrap your head around, as you are moving all the models all at once in unison. Think of them together as a single model that you are rotating about their collective center. Try to keep the middle sample screen center, and align it first, using it as an anchor point.

5. Compositing Calibration

In this step, you tweak specific compositing settings. This is the first step where you get to see the composited scene as you would in a Mixed Reality capture. You could exit now, and everything would work properly.



Use the arrow keys to select and set specific values.

Most of the settings in this step pertain to the chroma keying process which is discussed in detail in this UE blog post.

Setting

Description

ChromaColor

The color of your chroma backdrop (generally green).

Luminance Power

Used to help separate the backdrop color from shadows that may tint the visible color.

Chroma Clip Threshold

Colors matching the chroma color up to this tolerance level will be completely cut out. The higher the value the more that is cut out. A value of zero means that the chroma color has to be an exact match for the pixel to be completely transparent.

Chroma Opacity Strength

Scales the opacity of the remaining pixels. The higher the number, the less translucency there will be. The closer a color is to the ChromaColor, the higher you have to turn this up to keep it from going transparent.

Despill Strength

Scales the despill intensity. A value of zero means no despill correction will be performed.

Despill Cutoff Cap

Colors that differ from the chroma color beyond this tolerance level will be unaffected by despill correction. The higher the value, the more that will be color corrected.

Despill Sharpness

Used to smooth out the despill gradient - defines the despill falloff curve. Scales the despill strength exponentially. The lower the value, the more subtle/smooth it will be.

Faux Bounce Intensity

Used to scale the strength of the color used to replace the color removed as part of the despill process. A value of zero means that the faux bounce color won't be applied.

Faux Bounce Color

A color to replace the chroma color bleed that was removed as part of the despill process with.

Setting

Description

Tracking Latency

Depending on your video capture device, the video feed may be laggy compared to your controllers. With this setting, you can introduce a delay to the controllers, in order to better sync the two.

Depth Offset

By default, the video aligns to the depth of the headset. This is used to determine what renders in front of and behind the subject. This lets you offset that forward or backward in the scene.

Pressing Enter cycles from one setting to the next. Once you're satisfied with the configuration, hit End to save. You can always start the tool again to tweak these values later.

6. Garbage Matting

Garbage matting is the process of blocking out areas that should always be cut out of the video feed.

If your green screen doesn't cover your entire frame, you will need to complete this additional process to cut out those excess regions from the capture.

This is the last step of the calibration process. If you don't have this problem or a need for it, you can skip this step and exit.



This is the only step in the tool that requires you to work in VR. Put your headset on, and the controls should be listed in front of you.

End/Esc : Save & exit the tool

Left Controller

Right Controller

Grip : Alt (hold to change controls)

Trigger (Hold & Drag) : Move gizmo

Thumbstick : Undo

w/ LGrip held

Trigger : Reset gizmo position

Thumbstick : Redo

Grip : Create matte model

Trigger : Select/Deselect matte model

Thumbstick : Next gizmo mode (rotate, translate, scale, etc.)

w/ LGrip held

Trigger : Deselect all

Thumbstick : Prev. gizmo mode



Similar to how our



There's a preview window in VR, so you can see the results as you modify the mattes. You may want to to move the camera around at this point (if it's attached to a tracker), to see how it looks from different angles.

Getting the mattes aligned perfectly can be a difficult process. If you are having trouble, try standing where you want the mat to be, and bring it to yourself. Use the picture-in-picture to help guide your progress.

Once you've matted out the areas you want, you can exit the app (End or Esc) - all of your settings will be saved. If necessary, you can start the tool back up again to tweak the settings.

End Result

Once you've finished the calibration process, you can exit the tool. In the tool's Saved/SaveGames/ directory you should find a MrcCalibration.sav file.



Once you have a MrcCalibration.sav file, copy it into your game's /Saved/SaveGames/ folder. If your game doesn't have a SaveGames directory yet, you will need to create it manually.

If you've gone through this process once, you don't need to do it again (as long as your setup doesn't change). You can reuse the same calibration settings file across different UE titles (titles that have enabled the MRC framework plugin).

Supported Video Devices for Mixed Reality Capture

How To Use the Mixed Reality Capture Calibration Tool

Troubleshooting Mixed Reality Capture

1 - Setting up Green Screen and Camera

2 - Calibrating Physical and Virtual Cameras

3 - Adding the Calibration File to Your Game Project

4 - Enabling the Mixed Reality Capture Framework Plugin

5 - Recording the Mixed Reality Capture

6 - On your own!



At the end of this tutorial, you will have setup and calibrated your system for Mixed Reality Capture (MRC).

1 - Setting up Green Screen and Camera

Before you can take a capture, you will need the right equipment for the job. Here is a quick overview of the equipment you will need, and some tips on how to set it up.



Video CameraUE5 only supports a very specific set of video capture devices; see Supported Video Devices for the current list of the supported devices. Using a device from the list, connect it to your PC for streaming.

Chroma backdropFor chroma keying, we generally use a green screen. When setting up the green screen, you will want to make sure it's taut, minimizing any wrinkles, especially behind your subject. If you are setting up lighting, you will want to make sure not to cast shadows directly behind the subject. You want a smooth, flat color. The more shades of green that there are across the backdrop, the harder it is to chroma key. It helps if the subject is far away from the backdrop as possible. If you plan on filming the subject's feet, consider a green screen for the floor as well.

Camera MountFor the initial setup (calibration), your camera needs to be static. If you are using a webcam, this may be as simple as attaching it to your desk/monitor. Another option is to mount the camera to a tripod.

Multi-Mount + Tracker (Optional)If you plan on moving the camera around while filming, you will want to attach a tracking device to the camera, such as an HTC Vive Tracker. In addition, connect the camera and tracker together with a multi mount, so that they stay firmly locked in place.

2 - Calibrating Physical and Virtual Cameras

Once you have your physical space and equipment set up, you are ready to run through calibration. At runtime, the game needs to know where your camera is in relation to your virtual scene. The configuration is different for each setup, which is why you need to run through a calibration process. To simplify calibration, we've created a standalone calibration tool (MRCalibration.exe), which can be downloaded here.

The calibration process is complicated, so we've created a separate How To Use The Mixed Reality Capture Calibration Tool topic that contains detailed instructions on using the calibration tool.



When the calibration process is complete, the calibration tool will generate a calibration settings file (MrcCalibration.sav). The calibration settings file (MrcCalibration.sav) file can be found in the calibration tool's /Saved/SaveGames/ folder. This settings file will be used by the game when starting a Mixed Reality Capture. As long as your physical setup stays the same, you don't need to rerun the calibration process. You can use the same calibration settings file across multiple games.

If you have a camera with an adjustable lens, be careful not to adjust the zoom after you've completed calibration. Adjusting the zoom will change the physical camera's field-of-view (FOV), but not the virtual one. The virtual camera will use the FOV that was used during calibration. If you adjust the camera's zoom after calibration, you will need to repeat the calibration process.

3 - Adding the Calibration File to Your Game Project

In the last step, we covered how to use the MRC Calibration Tool to produce a MrcCalibration.sav file. Once you have a MrcCalibration.sav file, copy it into your game's /Saved/SaveGames/ folder. If your game doesn't have a SaveGames directory yet, you will need to create it manually.



If you have the Mixed Reality Capture Framework plugin enabled in your game, it checks for a calibration settings file on startup.

4 - Enabling the Mixed Reality Capture Framework Plugin

Integrating the Mixed Reality Capture (MRC) framework into your project is as easy as enabling the Mixed Reality Capture framework plugin. With the MRC plugin enabled and the calibration settings file in place, the game should start in MRC mode and display the composited scene to the spectator window.By default, MRC broadcasting uses the VR Spectator Screen to display the composited scene. If the game isn't in VR mode, then the Mixed Reality capture will not be displayed. The MRC plugin is capturing; it's just not displaying.

Mixed Reality captures are supported both in the editor (VR PIE) and in packaged projects, as long as the MRC plugin is enabled.

Under the Edit menu, select Plugins.





Click image to expand.



Use the Search bar to find the Mixed Reality Capture Framework plugin.

Click the Enabled checkbox, then click Yes on the warning pop-up.





Click image to expand.



Unreal Editor must be restarted to compelte the process of enabling the plugin.





Click image to expand.



When the MRC plugin starts up, it checks for a calibration settings file (MrcCalibration.sav) in the game's /Saved/SaveGames/ folder. If the MRC plugin does not find a calibration settings file, it will not start in MRC mode. Below is a diagram showing how the game determines whether to start in MRC mode or not.



5 - Recording the Mixed Reality Capture

The MRC framework does not record a video of the capture. The MRC framework handles compositing the scene and outputting that to the display window. You must use 3rd party software, like OBS or Nvidia ShadowPlay to record the capture.



6 - On your own!

The hardest part of creating a Mixed Reality Capture is properly calibrating. Once you've done that, you can keep reusing the calibration file. It's as simple as copying a file and running!

If your equipment setup changes, you will need to recalibrate using the Mixed Reality Capture Calibration Tool again.

The Mixed Reality Capture (MRC) framework makes it easy for users to composite real players into a virtual play space so that observing XR experiences is more compelling.



Mixed Reality Capture support has three components: video input, calibration, and in-game compositing. We have a list of supported webcams and HDMI capture devices that enable you to pull real world green screened video into the Unreal Engine from a variety of sources. If you have a separate tracking device, Mixed Reality Capture can match your camera location to the in-game camera to make shots more dynamic and interesting. Setup and calibration is done through a standalone calibration tool. Once you set up and calibrate your filming location, you can reuse those calibration settings across Unreal applications.

While feature support is in Beta, we're looking forward to getting feedback as we continue to improve the framework.

Get started using Mixed Reality Capture by following the Mixed Reality Quick Start.

We have tested a limited number of video capture devices with the Mixed Reality Capture Framework (MRC). This is not to say that other video capture devices won't work, but below is a list of the devices that we've tested here at Epic Games.

Webcams

Logitech C920

Logitech C930e

USB Capture Dongles

Magewell USB Capture HDMI Gen 2¹

¹ While untested, it is likely that other Magewell USB capture products are just as compatible with MRC, such as their Plus model (for 4K), and their SDI capture dongles (for broadcast hardware).

It is possible for advanced users to write a Media Framework plugin to support their own video capture device.

Flickering During Captures

Capture Not Displaying on Spectator Screen

Controller/Trigger Not Responding During Calibration

This page provides troubleshooting information for Mixed Reality Capture (MRC).

Flickering During Captures

Depending on the resolution of the MR capture target (the default is 1080p), your app may be constrained by its render target pool size. By default, render targets are set to reallocate as needed, which can lead to ping-ponging and flickering as the MR capture targets fight with the stereo render targets. (shown in the video below)

If you see this kind of behavior, you can change the render target resize rule to ‘Grow' (in your engine.ini file, set r.SceneRenderTargetResizeMethod=2). Making this change should resolve the issue.



Capture Not Displaying on Spectator Screen

The MRC framework uses the Virtual Reality Spectator Screen to display the composited scene. This means the Mixed Reality capture will only be displayed when running in Virtual Reality. If your project also uses the spectator screen, then you need to conditionally guard where you use them. There are MRC methods to help with this:

Get Mixed Reality Capture TextureReturns the Capture Texture, or a nullptr if there isn't one.



Is Mixed Reality Capture BroadcastingReturns true, if the system is sending the capture texture to the spectator screen.



Set Mixed Reality Capture BroadcastingToggles whether the capture system is sending the capture texture to the spectator screen or not.



An Example of Using the MRC Methods





Click image to expand.



Controller/Trigger Not Responding During Calibration

If your controller input does not appear to respond during calibration, below are several possible causes.

The headset sensor in not covered. If theheadset's sensor is not covered, the controllers may not be active.

The application window needs to have focus. If theMRCalibration window is not the current active window, the controller actions may not be captured by the calibration program.

The Oculus system may not be configured to run from Unknown Sources. As a part of Beta access, the calibration program is still in active development and has not been reviewed by Oculus.



Quality Level

Custom

Exposed Material Instances

MI_Beam

MI_Lens

MI_Light

DMX fixtures are the devices actually responsible for receiving and executing commands based on the data received live or using pre-recorded DMX Tracks. This can mean turning a light on or off or rotating the device 90 degrees. There are many sorts of DMX fixtures you can use, from standard stage lights that simply turn on and off to intelligent lights that have multi-directional rotation and complex lighting functions and filters.

This page describes fixture features included in the DMX plugin.



Quality Level

A revised version of the adaptive quality level feature used in the DMX Previs sample is natively available in the DMX Plugin. You can pick from four predefined quality levels in the Details panel of light fixture Actors and specify their own quality settings. The following options are the available quality levels:



Click image to expand.

Low: 4 distance units between samples

Medium: 2 distance units between samples

High: 1 distance units between samples

Ultra: 0.33 distance units between samples

Custom: A user-defined distance units between samples





The smaller the distance value, the closer the volumetric beam samples are, which will increase the visual accuracy of the beams. Larger values mean there will be larger steps, which will improve performance but may create a blocky visual effect.

Custom

With the custom option you can specify two step-distance values manually. The Min Quality parameter specifies the smaller zoom angles and the Max Quality parameter specifies the larger zoom angles. This means more samples for thinner beams to increase visual quality, and less samples for wider beams to increase speed since the light covers a larger volume quantity in 3D space.



Click image to expand.

Exposed Material Instances

Various Material Instances are also exposed in the Details panel, so you can change the material instances per fixture or per group of fixtures in the Outliner.



Click image to expand.

Some predefined Material Instances are provided with the DMX plugin. You can find them in the Content Drawer at DMXFixtures Content > LightFixtures > DMX_Materials. The sections below describe some unique features of these material instances.

MI_Beam

Refers to the M_Beam_Master material responsible for defining how the volumetric beam looks and performs in the 3D environment.

The following Beam Parameters are included in the volumetric beam material instance MI_Beam:

Jitter Scale: Defines how much jitter is applied to the samples, helping with step artifacts when having lower sample count.

Soft Clip Size: Controls the beam clipping when reaching its maximum length

Atmospheric Density: Simulates particles within the air. With this parameter, you can customize how opaque or translucent the beam is in regards to air density.

MI_Lens

Refers to M_Lens_Master material responsible for defining the look of the actual lens. This is purely cosmetic and does not affect fixture lighting effects in the 3D world.

The following Lens Parameters are included in the lens material instance MI_Lens:

Use Gobo: When enabled, the gobo texture appears in the lens.

Use Lamp: When enabled, the lamp source appears to be behind the lens.

Lens Mask: Shapes the lens.

Lens Base Color: Color of the lens.

Lens Normal: Normal map applied to the lens.

MI_Light

Refers to the M_Light_Master material responsible for defining the light function used when the beam intersects 3D geometry. This is where gobos are applied and visible on arbitrary meshes the light hits such as floor or walls.

The following Light Parameters are included in the light material instance MI_Light:

Use Gobo: When enabled, the gobo texture appears in the light.

DMX Quickstart

Motivation

Use Cases

Show Previs

Device Control

Content Trigger

What is DMX?

DMX Data

Technical Details About DMX

DMX Controllers

DMX Fixtures

Universe

Signal Communication

Fixture Patching

Attribute Resolution

DMX Communication Over Network

Art-Net

sACN

DMX User Types

Design Firms

Creative Agencies and Production Companies

AV Technology Specialists

Protocol Integration

DMX Modulators

Input Modulators

Output Modulators

Feature Guide

Send DMX Data from Unreal Engine (ArtNet + sACN protocols)

Receive Incoming DMX Signals

Register DMX Fixtures with Attribute Names and Channel Mappings

Register DMX Controllers with Universe and Protocol Assignments

Send DMX from Blueprint Attributes

Control DMX From the Editor Using the Virtual Output Console

GDTF Integration

Attribute Naming System

DMX Display Cluster Plugin

DMX Sequencer Feature

DMX Recording

DMX Remote Control Feature

Pixel Mapping

Unicast/Multicast Output

Improved DMX Library UI

Fixture Type Panel

Fixture Patch Panel

Improved DMX Output Console and Input Monitoring

Output Console

Input Monitoring

Matrix Fixture Support

Modular DMX Fixture Blueprint Templates

DMX Stats

DMX Input and Output Refresh Rate



DMX Blueprint Template

Motivation

Lately, there has been increasing interest and demand for Unreal in the context of live events and permanent digital installations throughout the world. We have seen numerous executions that have been either partially or totally powered by Unreal. When Unreal was new to this market, it was missing some fundamental and usability features. Despite that, it has been adopted by talented groups willing to build the necessary and missing tools/plugins to push the boundaries of the possible further and achieve their desired creative goals.

The existing solutions in the live entertainment industry are a mix of hardware and software platforms that are scattered, proprietary, and expensive. The tools and production pipelines are convoluted, difficult to use, and often impair the overall creation and production processes.

Epic has decided to tackle this problem by adding support for DMX (Digital Multiplex) data communication through both Artnet and sACN variants. DMX is used throughout the industry to control various devices in the live events industry such as lighting fixtures, lasers, smoke machines, mechanical devices, among others.

Artnet and sACN are network protocols allowing to aggregate and send DMX data over ethernet (IP). Artnet allows sending 32,768 universes down a single network cable. Although it is an older protocol, it is supported by more gear and devices. sACN (streaming architecture for control networks), currently appears more popular and allows you to run 63,999 universes of DMX data down a single network cable.

Use Cases

Here are typical use cases that we have identified around the DMX feature.

The DMX protocol can be used in the input provided to Blueprint nodes and fixtures-type actors, for rapid live show stage previsualization. Live DMX input is used to drive and control enabled fixtures within a 3D UE level. Proper lighting attributes are used for realistic effects so that show designers can iterate in their creative process.

The DMX protocol output and Blueprint nodes can be used to talk to DMX-enabled fixtures and devices, which enables controlling lighting consoles or devices from UE.

DMX protocol input can be used to trigger live effects or animation sequences within UE that are meant to be displayed on a live show alongside lighting fixtures control.

What is DMX?

DMX is a standard for digital communication networks that are commonly used to control stage lighting and effects. It was originally intended as a standardized method for controlling light dimmers, which, prior to DMX512, had employed various incompatible proprietary protocols. It soon became the primary method for linking controllers (such as a lighting console) to dimmers and special effects devices such as fog machines and intelligent lights.

DMX has also expanded to uses in non-theatrical interior and architectural lighting, at scales ranging from strings of Christmas lights to electronic billboards. DMX can now be used to control almost anything, reflecting its popularity in theaters and venues.

While DMX is primarily used to control lighting devices, there are many other forms of hardware that can be driven using the DMX protocol, including the following.

Special effects hardware

Foggers

Fireworks

Lasers

CO2 Cannons

Flame Cannons

Confetti Launchers

And so on.

Motors

Power Switches

Microcontrollers

And more.

DMX Data

DMX can be thought of as a package of digital information that is being sent from one location (our source) to a different location (or destination). Each package is created at some source with specific information that should be received and read by some recipients. Each packet is structured in a very intentional way and if you would like to know more about how this works on the hardware level, please read the ESTA standards. For our purposes, we are only concerned with the contained data. Each package contains an array of 512 bytes or values that range from 0-255.



In the next section, you will go over how these packets are sent and received.

Technical Details About DMX

By creating an Unreal Engine plugin for DMX which will enable:

Native DMX communication in both directions for both protocols (ArtNet and sACN).

A complete library of Blueprint nodes.

A preliminary UI for describing and building a library of controllers, fixture types, and actual devices.

DMX requires two primary components in order to work:

A DMX controller or DMX source.

At least one DMX fixture (typically a lighting fixture but it can be any kind of device controlled by DMX protocols).

We do not support USB interfaces.

DMX Controllers

DMX controllers (also referred to as "nodes") act as the signal source or the location at which the DMX signal is created. Additionally, controllers act as the distributor of the data to a set of daisy-chained fixtures. There are two forms a DMX controller can take, a USB/Network interface device or a standard DMX console.

A USB/Network interface converts USB signal or IP packets to DMX which is then transmitted out to a set of daisy-chained DMX fixtures.



To view the image source, click here.

A DMX console allows the user to manually trigger outgoing DMX and, depending on the capability of the Console, may also be able to receive and broadcast DMX from network packets.



To view the image source, click here.

DMX Fixtures

DMX fixtures are the devices actually responsible for receiving and executing commands based on the data received. This could mean turning a light on or off or rotating the device 90 degrees. There are many sorts of DMX fixtures from standard stage lights that simply turn on and off to intelligent lights that have multi-directional rotation and lighting filters.

Each fixture has a set of attributes/commands that are predefined on the hardware level. These attributes are organized into groups called modes. Many fixtures contain multiple modes which predefine the available attributes the fixture will respond to.

Fixture makers give the user different mode options so that they can cater to a large range of use cases, including as many features as possible while allowing the user to pick and choose which are the most important to them. This results in the simplest, smallest channel count mode; a complex, huge channel mode; and some in-between modes. A lot of the time in professional lighting practice, the intermediate modes are chosen for their balance between features and ease of control, along with more frugal use of the DMX channel count.

Each mode contains a set of attributes. Attributes are responsible for telling the hardware how to respond to the received DMX data. In most cases, you can find all attributes for a particular fixture outlined in the fixture manual provided with the device.



Refer to the DMX Fixtures documentation for more information.

A universe consists of a set of fixtures all strung together reading the same data. A universe contains 512 bytes of information, so the number of fixtures in a universe will depend on how many bytes of data are needed to address each fixture.

Signal Communication

Let us next consider how controllers and fixtures talk to each other. Each controller is responsible for one or many universes each of which has multiple fixtures daisy-chained in a long string. A universe can be thought of as a form of identification for a group of addressed fixtures. In order to send data to the proper fixture, you need to also send it to the correct universe.

Once a controller has received the command to distribute a DMX packet, it locates the proper universe and sends a packet of data down the string for each connected fixture to receive and interpret. Each fixture receives the same packet of data and executes an internal command if the packet contains any data that is meant for that fixture. Once the data has been read, it is then passed down the chain onto the next fixture to repeat the process. In order to make sure the fixture is receiving the proper information it must be listening for the right data. This introduces the concept of fixture addressing or "patching", covered more in the next section.

Below you can see an overview of the signal hierarchy and data usage.

Controllers can be responsible for one or more universes

Universes can contain many fixtures daisy-chained together (represented by the full 512-byte array)

Fixtures can occupy one or more addresses inside of a universe

Starting Address, each fixture has a starting address which determines how the fixture should interpret the received DMX data packet (a single index in the byte array)

Attributes, each fixture contains a set of attributes defined by its current mode which each take on an address that is determined by their attribute number (channel) plus the starting address (see the diagram below for an example).

The concept of fixture patching comes from the idea that we need to be able to virtually position our fixtures along a communication chain in order to receive the proper data. Since we send full packets of data to be read by multiple fixtures, it is important to have a way of identifying exactly which bytes in the packet should be read and interpreted and which ones should be ignored. This is done by assigning each fixture at a specific starting address in a universe. A starting address can be anywhere between 1 and 512 (the max number of values in our DMX packet). By assigning a fixture to a specific starting address, it then occupies a range of addresses from the assigned starting address through the starting address plus the number of attributes the fixture contains in its current mode.

See the example below:



Fixture 2 current mode = 8ChannelMode (contains 8 attributes)

Red (address 8)

Green (address 9)

Blue (address 10)

Strobe (address 11)

Pan (address 12)

Tilt (address 13)

Dimmer (address 14)

Macro (address 15)

Starting Address = 8 Address Range = 8 - 15

Using the example above, in order to pan, the fixture will be listening on address 12 for a byte value between 0-255 which will ultimately control the amount the fixture will pan within its defined rotation range.

Most commonly an attribute will operate with an input range of a single byte (for example, 0-255). Occasionally, higher resolution is needed to achieve more precision in movements or lighting control. If this is the case, attributes take on larger input ranges constructed of multiple bytes instead of just one. The combination of multiple bytes results in higher possible values for controlling a particular attribute. Below you can see the possible attribute signal types.

8 Bit Attribute - Min: 0, Max: 255 - Occupies 1 address

16 Bit Attribute - Min: 0, Max: 65,536 - Occupies 2 addresses

24 Bit Attribute - Min: 0, Max: 16,777,215 - Occupies 3 addresses

32 Bit Attribute - Min: 0, Max: 4,294,967,296 - Occupies 4 addresses

When an attribute over 8 bit is needed, that attribute occupies more than one address in the universe. Depending on the resolution, it can occupy multiple consecutive addresses. You can see the number of addresses an attribute will occupy in the list above.

DMX Communication Over Network

As mentioned above in the "Controllers" section, DMX data can be sent in a variety of ways including through USB, IP packets, and directly from a console. Over the past few years, network communication methods have become increasingly more popular and important. As shows get larger and the number of fixtures increases there becomes a greater need for addressing more fixtures in a fast, efficient, and reliable way.

To overcome the channel restriction of DMX while still utilizing its structure, ethernet protocols were developed. These protocols allow multiple DMX universes to be transported over a single Cat5 cable using ethernet technology. There are two primary ethernet protocols that are the most widely used and that UE supports in the DMX plugin, Art-Net, and sACN.

Art-Net is a royalty-free communications protocol for transmitting the DMX512-A lighting control protocol and Remote Device Management (RDM) protocol over UDP. It is used to communicate between "nodes" (for example, intelligent lighting instruments) and a "server" (a lighting desk or general-purpose computer running lighting control software).

More detailed information about the Art-Net protocol can be found on the art-net site.

Streaming Architecture for Control Networks(sACN) is a standard protocol developed by ESTA to efficiently transport DMX universes over the network. It is comparable to ArtNET in many aspects. One nice thing is the multicast option allowing very easy configuration. sACN is a popular protocol to control a large number of RGB LEDs.

DMX User Types

Design Firms

Alongside architectural firms, AV specialists, and creative agencies, design firms are often mandated in designing overarching creative projects within the Live Events and Permanent Install verticals where real-time sources are used to generate content to be displayed within the physical space.

A design firm's mandate is to produce precise design documents for all parties involved, ensuring that all aspects of the project are delivered following a detailed and well-thought-out plan - minimizing ambiguities as much as possible. They need to know and understand on a high-level basis why Unreal Engine is the best tool for their projects, what its capabilities and limitations are, and how it integrates into the design master plan.

Creative Agencies and Production Companies

Creative agencies and production companies are essentially responsible for designing and executing the creative plan from a production perspective. Making things happen. They are the ones coding and using the Unreal Engine within the scope of the given project. They are your first front-line customers that are leveraging the existing features and possibly enhancing or modifying them for the needs and requirements of their project. They will need to understand inside-out the technical capabilities of such features and be able to use them to achieve a given creative or design objective within time and budget constraints. Sufficiently large creative agencies and production companies are often also the design firms.

AV Technology Specialists

Technicians and technical specialists from the AV industry responsible for speccing, engineering, and commissioning AV systems need to understand in detail how Unreal Engine can be used within those systems alongside other tools and devices. How does it integrate within the suggested AV infrastructure, how can it communicate with that infrastructure, how does it deal with failures, redundancy, or backup systems? These systems need to be addressed as a whole, often in 24/7 mostly automated environments with minimal human interaction.

Protocol Integration

ArtNet and sACN protocols are both integrated from the original source so that all code is internal to Epic. By building from the source we have greater control over how we can use and access library attributes and most importantly, building from a library source allows support for multi-platform usage.

In the Unreal Engine DMX Plugin, cross-platform support for both receiving and sending of DMX data through sACN and Art-Net protocol variants is included. Since both Art-Net and sACN are UDP network protocols, Unreal Engine's pre-existing network messaging features now natively implement each protocol built on top of the Unreal Engine architecture.

For this plugin, the most recent version of the Art-Net protocol, Art-Net 4, is integrated. Art-Net 4 has a theoretical limit of 32,768 universes or Port-Addresses (that is, 32 kiloverses) as opposed to Art-Net 3's universe limit of 256.

For the full Art-Net 4 protocol specification, you can find the official documentation here.

In comparison to Art-Net, sACN is a newer protocol that allows for as many as 63,999 universes.

For published documentation on the sACN protocol visit this link.

DMX Modulators

DMX Modulators are available data manipulation and conversion functions that can be used and applied to either inbound or outbound DMX data.

Input Modulators

Input Modulators are specified under Fixture Settings in the Details panel. You can add as many Modulators as needed. The following is a list of the input modulator options:

None: No data manipulation or conversion applied.

CMY to RGB: CMY to RGB color conversion.

Constant Frame Delay: Delay outgoing DMX data by a specified number of frames.

Extra Attributes: Set extra attributes on Pixel Mapping cells.

RGB to CMY: RGB to CMY color conversion.



Click image to expand.



Click image to expand.

Output Modulators

Output Modulators are specified in the Pixel Mapping panel. The following is a list of the output modulator options:

None: No data manipulation or conversion applied.

CMY to RGB: CMY to RGB color conversion applied to the live input texture RGB pixels.

Extra Attributes: Set extra attributes that aren't driven by the live input texture.

Extra Cell Attributes: Set extra attributes per cell that aren't driven by the live input texture.

Pixel Mapping Frame Delay: Delay outgoing DMX data by a specified number of frames.

RGB to CMY: RGB to CMY color conversion applied to the live input texture RGB pixels.



Click image to expand.



Click image to expand.



Click image to expand.

Feature Guide

This is a high-level list of all features that are part of the DMX plugin.

Send DMX Data from Unreal Engine (ArtNet + sACN protocols)

The two primary DMX communication protocols (ArtNet and sACN) have been implemented to send DMX over ethernet to 60,000+ universes.

DMX can be sent directly from Unreal Engine at both runtime and from the editor.

Receive Incoming DMX Signals

Users can create getter Blueprints to allow receiving DMX data from any channel in any universe. A range of delegate events and a DMX component that will return current fixture value data are available to use incoming DMX data. These events can be applied to any actor such as a fixture, and control rotation, color, and so on using the incoming data.

Register DMX Fixtures with Attribute Names and Channel Mappings

Users can add any DMX fixture to their projects with any number of channels. If a fixture preset isn't in the fixture database, users will be able to register their own. Users can also set up channel mappings and register their own attributes to ultimately be used in their own custom Blueprints or the provided default fixture Blueprint actors.

Register DMX Controllers with Universe and Protocol Assignments

Users will be able to add different DMX controllers that are responsible for any range of DMX universes.

Send DMX from Blueprint Attributes

Dynamic Blueprint nodes allow users to execute pre-registered fixture attributes for a specific DMX fixture.

Control DMX From the Editor Using the Virtual Output Console

A custom DMX Console window enables users to test any channel or any range of channels in any Universe directly from the editor.

GDTF Integration

Support for the GDTF file format standard from VectorWorks enables importing numerous fixture types with their attributes. Currently, only importing attributes is supported. Spotlight is their software for Live Show previsualization that is extensively used in the industry.

Attribute Naming System

The attribute naming system provides a way of standardizing imported function naming while also providing global access to easily accessible and understandable fixture properties. The attribute system allows users to simply select from a dropdown list of properties without the need to create a DMX library.

DMX Display Cluster Plugin

nDisplay supports replication for DMX. Enable the DMX DisplayCluster plugin in your project to use DMX with nDisplay clustered rendering.



Click image to expand.

When the DMX DisplayCluster plugin is enabled, DMX that is received on the primary node in the nDisplay cluster is replicated to all the cluster nodes. You can specify a primary node for receiving DMX that can be different from nDisplay's primary node. To assign a computer to be the DMX primary node, add the following command-line parameter when launching the instance of Unreal Engine 4 on the computer:

You can also explicitly assign a node to be a cluster node for DMX, which won't receive DMX information from external software or hardware. To assign a computer to be the DMX cluster node, add the following command-line parameter when launching the instance of Unreal Engine on the computer:

DMX Sequencer Feature

DMX can be controlled from Sequencer. With this feature, you can add a range of patches from a DMX library into a Sequencer Track, from which you can program keyframes to output DMX to virtual or physical fixtures.

For more details on the Sequencer integration, refer to DMX Tracks.

DMX Recording

IIncoming DMX can be recorded so that users can use both a physical DMX console and Unreal Engine to build out their show.

DMX Remote Control Feature

You can control properties remotely in the engine with DMX through Remote Control. Refer to Remote Control Protocols for more details.

Pixel Mapping

This feature lets users sample the pixels of a user-specified texture and output the color sample as DMX to a variety of DMX types.

Unicast/Multicast Output

This feature provides additional DMX communication methods for specifying send destinations.

Improved DMX Library UI

The Feature Type panel separates fixture details, modes, and functions/attributes into separate columns for improved organization and visualization.

The Fixture Patch panel is an interactive visualizer for addressing fixture patches to an IP address and universe.

Improved DMX Output Console and Input Monitoring

The Output Console and DMX Monitor tools have been moved outside the DMX Library.

Offers quick fader addition tools and enables using macros for quickly testing and controlling faders.

The multi-universe DMX monitor tool enables listening to any incoming DMX on any universe.

Matrix Fixture Support

DMX can be sent to and received from multi-cell fixtures through blueprints, sequencer, and the take recorder.

Modular DMX Fixture Blueprint Templates

DMX Stats

DMX send and receive statistics can be displayed to the screen.

DMX Input and Output Refresh Rate

In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

Enabling the DMX Plugin

Steps



DMX Blueprint Template



This Quick Start guide will describe the basics of how to use the DMX features in order to help you get started creating your own visual installation or live event using Unreal Engine. This includes the following.

Exposed parameters (what they do, why they are there, what they impact).

Underlying concepts (so that you understand what is going on).

A step-by-step typical workflow with use-cases.

Enabling the DMX Plugin

To enable the DMX plugin in a project, navigate to Edit > Plugins and enable the following plugins.

DMX Runtime

DMX Protocol



Restart the editor before continuing the following steps.



Steps

Create a new DMX Library by going to Add New > DMX > DMX Library.

Open your newly created DMX Library and navigate to the Controllers panel.

Add a controller by clicking the green New Controller button in the top left.



Select your desired protocol and Communication Mode.

Protocol: Art-Net or sACN

Communication Mode: Broadcast or Unicast

Create an array with multiple Unicast IPs for Multicast.



Set the desired Universe Range on your physical controller.



Navigate to the Fixture Types panel and add a new fixture type by clicking the green New Fixture Type button.



Import a GDTF asset to automatically configure your fixture type or configure manually as described below.



Modes

Add modes using the + Add Mode button.



Set the Mode Properties.



Attributes

Add all needed functions for this mode using the + Add Function button.



Set the associated attribute for each function.



Set the desired properties.



Navigate to the Fixture Patch panel and add a new patch by clicking the green Add Fixture button and select the fixture type from which to create a new patch.



Make sure to set your Universe ID, Starting Channel, and Active Mode to match what is set on your physical controller and physical fixture respectively.



The patch visualizer on the right side will indicate where patches are currently assigned in a specified universe.



In order to test that the output of DMX is working properly:

Open the Output Console.



Create a new fader.



Drag the slider up and down to test the output.



Next, to view the outgoing and incoming DMX signals of a particular universe, open the Channel Monitor or Activity Monitor.



Set your protocol and the universe you want to monitor and then broadcast some DMX either in Unreal Engine or from an external program. You will see a real-time update reflected here.



If using an external program, make sure you are connected to the same network and are broadcasting to the network card's IP subnet. See the "Receive DMX" section for more information.





To create a custom fixture and place it in the scene:

Navigate to the DMX Fixtures plugin folder, find a fixture template, and create a child or duplicate actor class.



Add the new actor class to the scene by dragging and dropping it in the viewport.

Set the DMX Library and Fixture Patch.



In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

DMX Quickstart

DMX Components

Initialize Fixture

DMX Input

Attribute Animation/Interpolation

DMX Fixture Proxy Blueprints

BP_MovingHead

BP_MovingMirror

BP_StaticHead

BP_StaticStrobe

BP_StaticMatrix

BP_WashLED

BP_MovingMatrix

BP_LaserModule

BP_PyroModule

BP_WaterSource

BP_FireWorksLauncher

DMX Template Guide



DMX Blueprint Template

Unreal Engine 5 provides additional DMX-enabled fixtures and VFX Blueprints that you can use within your projects or use as a foundation to create your own. These are showcased in the DMX Template, including the following.

An updated and improved C++-based modular DMX fixture system that enables you to toggle available sub-features such as pan, tilt, gobos, strobe, and more.

A volumetric beam shader with adjustable quality levels.

A set of base DMX-enabled VFX Blueprint Actors so that you can use as examples:

Fireworks

Pyro

Water fountain

Lasers

The following are popular categories of DMX fixtures used throughout Live Venues.

Static

Matrix/Pixel Bar

Moving Head

Moving Mirror

Strobe

The DMX UE plugin will ship with an asset pack composed of BP actors for each of the previously-mentioned fixture categories.

These actors can be placed in a level and will have the most features and attributes of typical fixtures of that category.

They have exposed Components that will allow the selection of the DMX Library and fixtures.

They contain DMX BP logic that will bind with received values to fixture attributes.

All default fixtures inherit from a base DMX fixture C++ class ADMXFixture.

DMX Components



Click image to expand.

Provided with the plugin are a set of DMX components to be used to design and configure custom DMX fixture functionality. Any actor inheriting from the ADMXFixture class can utilize the provided DMX components. These components are responsible for responding to incoming DMX packets and updating the parent actor accordingly. Each template fixture has a range of components added by default as seen below.



Click image to expand.

Each component has a set of editable properties that can be changed via the details panel on the right.



Click image to expand.

Initialize Fixture

Every fixture needs to be initialized to ensure the components and meshes respond properly to the received DMX. To do this, use the Initialize Fixture node and input the Lens mesh component and the Beam mesh component, if applicable.



Click image to expand.

DMX Input

DMX input for all fixtures happens through the OnFixturePatchReceived event provided by the added "DMX" component. Upon DMX received, normalized DMX data is pushed to all attribute components added to the BP. Each then updates and applies the change to the actor.



Click image to expand.

Attribute Animation/Interpolation

For each component, the user has the option to have the fixture characteristics be interpolated (animated) for a smoother more realistic look. Interpolation mimics real fixtures in which elements such as pan and tilt take time to move from one location due to motor speeds and hardware limitations. In the DMX Fixtures, interpolation can be changed and modified to fit the users desired looks via properties in the attribute components. Each component has two properties for controlling interpolation characteristics.



Click image to expand.

Property

Description

Use Interpolation

Enables interpolation.

Interpolation Scale

Sets interpolation speed.

All interpolation updates are handled on tick through the "Interpolate DMX Components" node.



Click image to expand.

DMX Fixture Proxy Blueprints



Click image to expand.



Click image to expand.

Here is a complete breakdown of all the included BP with the DMX plugin.

BP_MovingHead

This node has the following default attributes.

Pan

Tilt

Dimmer

Shutter

ColorWheel

Gobo

Zoom

Frost

BP_MovingMirror

This node has the following default attributes.

Pan

Tilt

Dimmer

Shutter

ColorWheel

Gobo

Zoom

Frost

BP_StaticHead

This node has the following default attributes.

Dimmer

Strobe

Zoom

Color

BP_StaticStrobe

This node has the following default attributes.

Dimmer

Strobe

BP_StaticMatrix

This node has the following default attributes.

MatrixPan

MatrixTilt

MatrixColor

BP_WashLED

This node has the following default attributes.

Pan

Tilt

Dimmer

Strobe

Zoom

Color

BP_MovingMatrix

This node has the following default attributes.

Pan

Tilt

MatrixPan

MatrixTilt

MatrixColor

BP_LaserModule

This node has the following default attributes.

StartStop

Angle

NumBeams

BP_PyroModule

This node has the following default attributes.

StartStop

Burst

BP_WaterSource

This node has the following default attributes.

StartStop

Velocity

BP_FireWorksLauncher

This node has the following default attributes.

Launch

DMX Template Guide

This node has the following default attribute.



Click image to expand.

This template is dedicated to live events previsualization and virtual production workflows requiring DMX protocol. It includes examples for addressing, patching, and controlling proxy lighting fixtures as well as recording and playback of live DMX data streams in and out of UE.

Use as a starting point to start pre-visualizing your live show using professional lighting consoles, for controlling external physical DMX enabled devices from within Unreal, or simply for triggering custom events inside your project using DMX. Experimental pixel mapping features and additional controllable effects such as pyrotechnics, fireworks, and water fountains are also showcased.

Three levels are included within this Template:



Click image to expand.

The first default map is Fixtures and contains all lighting fixtures demonstrated alongside a short pre-recorded DMX input sequence that is automatically played when starting the level.

The other two levels are small technical demonstrations of how to use the experimental PixelMapping feature as well as the provided WaterFountain fixtures.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

DMX Quickstart

Monitoring and Output Tools

DMX Output Console

DMX Channel Monitor

DMX Activity Monitor

Pause Receive DMX

Pause Send DMX

Monitoring and Output Tools

You can find the DMX monitoring and output tools in the DMX Toolbar Button.



DMX Output Console

The DMX output console is an editor tool for testing DMX output before running the project. You can use the output console to create custom faders that will output DMX to any number of universes and channels on a specified protocol.

You can also use this tool to verify that you are sending DMX and that your fixtures and controllers are receiving output from Unreal Engine. It is also a valuable debugging tool in the case that anything is responding unpredictably.

If you would like to update your fader, you can click on it, change its properties, then press the Update Selected Fader button.

To start sending DMX, make sure the checkbox is checked and click and drag to move the fader to change the value. Check your fixture manual if you are unsure which channels control what.



Property

Description

Add Faders

Adds a set of faders defined by the number of faders and input Universe/Address.

Remote Universe

The universe you would like all added faders to send to.

Starting Address

Address for the first fader added when Add Faders is pressed.

Number of Faders

The number of faders to add incrementing addresses, beginning with the Starting Address.

Master Fader

Send set value out to all faders.

Sort Faders

Organize faders incrementally by output address.

Name

Custom Name for your Fader.

Max

Set max output value. 255 by default.

Min

Set min output value. 0 by default.

Uni.

Global Universe Offset

Adr.

Address the fader should send to for the assigned Universe.

Protocol

Which protocol you would like this fader to use for sending data.

Macros

Preset macros for testing output.

Affected Faders

Which faders the macros should affect. You can choose Selected or All.

Sine Wave

Apply wave animation to fader(s).

Max

Set fader(s) to relative max value.

Min

Set fader(s) to the relative min value.

Fill in the properties you would like for your fader, and then press the Add Fader button to create a new fader.

DMX Channel Monitor

The DMX Channel Monitor is a debugging tool for visualizing DMX input and output. The monitor will display information when the Unreal Engine receives data for the specified universe and protocol. When DMX is sent out of Unreal Engine, it will also be displayed. When lighter colors are displayed, this indicates higher values that have been received.

Currently, you can only visualize for a single universe but we will extend this in the future to visualize the received of DMX on more than one universe.

Property

Description

Protocol

Select the protocol you would like to listen to.

Remote Universe

Specify the Remote Universe to listen to for the selected protocol.

Clear Values

Clear all channel UI to 0.



DMX Activity Monitor

The DMX Activity Monitor is a debugging tool for visualizing DMX input and output without the need to filter for a specific universe. The activity monitor will show the user which universes are currently receiving DMX and the values that are being changed within each universe.

Property

Description

Protocol

Select the protocol you would like to listen to.

Universe Range

Specify the range of universes to listen for the selected protocol.

Clear Values

Reset all UI elements back to 0.



Pause Receive DMX

Quickly and temporarily disable inbound DMX packets in the editor.

This is particularly useful after having recorded a DMX sequence track from a lighting board and making sure that no extra DMX packets are competing when desiring to playback that same recorded track.

Pause Send DMX

Quickly and temporarily disable outbound DMX packets in the editor.

This is particularly useful when you are trying to edit your scene or DMX project without having your hardware fixtures animate at the same time.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

DMX Quickstart

Sequencer Integration

Steps

DMX Take Recorder/Playback

Steps

We are adding support for DMX recording, playback, and editing in Sequencer through custom DMX tracks in order to help users better design and preview lighting experiences in virtual or physical shows and live events.

Sequencer Integration

Sequencer is a powerful feature that enables easy animation and event triggering. In this release, we are creating a custom DMX Sequencer track, enabling users to utilize its features such as curves and sub-sequencing to program and control DMX without the need for Blueprints or programming.

The custom DMX Sequencer track will represent a DMX Library. From that, you can add Fixture Patch tracks and then key their function values.

The DMX plugin enables the control of fixture patches using level sequences. Users can add any patched fixture contained within a DMX Library to a level sequence and expose desired attributes for sending out DMX. Keyframes can be added for each attribute at a given time to animate and control the DMX output. Curve editing is also supported for defining value animation characteristics.

Steps

To add a fixture patch to a level sequence, perform the following steps.

Press the + Track button and select DMX Library Track from the list. Select the DMX Library you want to add to the sequence.



On the new DMX Library Track click the + Patch button and select a fixture patch to create a new track for the desired patch, or click Add All Patches in the dropdown menu to create a new track for every fixture patch in the library.



Expand a fixture patch track and add a new keyframe by pressing the Add (+) button or by modifying the value next to the attribute name. The value ranges are defined by the DMX signal format selected in the DMX Library for each Attribute.



By default, DMX will output on scrub and "Play" on the sequence.

DMX Take Recorder/Playback

The DMX plugin Take Recorder tool has functionality that allows recording of received DMX data for editing and playback. This feature enables users to listen for incoming DMX streams and record the data as new keyframes in the level sequencer. This level sequence can then be replayed, edited, and shared. Users can listen for incoming DMX for a specified fixture patch assigned in a DMX library, and record changes to keyframes in the level sequence.



DMX recording only works at runtime.



Steps

To record DMX to a level sequence, perform the following steps.

Click the Add button and select DMX Library from the list.



Set the DMX Library parameter to the Library containing the patch you would like to record.



Click the Fixture Patch parameter and select a patch from the list to add it to the patch record list or click Add all Fixture Patches to add all patches in the library to the patch record list.



Reduce Keys

Play the game, and press the Record button. All incoming DMX that matches the patch record list will be saved into a new level sequence as a new keyframe.

When you are done recording, navigate to the created sequence to review and play back the recorded DMX. The new sequence should be saved to Cinematics/Takes/[RecordDate]/

By default, the recorded sequence will be locked from editing. To unlock the sequence for editing, click the lock icon next to the sequence name in the sequence editor.



Double click the recorded subsequence in the editor to view the recorded data.



In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

DMX Quickstart

The DMX Component provides the user a way to assign a specific DMX Fixture Patch to a Blueprint Actor instance in the scene. This gives the user the ability to have multiple instances of a Blueprint Actor in the scene and have it send and receive data to and from a single registered fixture patch. This is intended primarily for 3D previsualization for lighting fixtures.

To set the fixture patch for your DMX Component first select your actor in the scene. Then in the details panel, select the DMX Component and set a DMX Library Asset and a Fixture Patch. See the image below for an example.



Below you can see an example Blueprint showing how to receive data from the fixture patch set for the component.



In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

DMX Quickstart



GDTF (Generic Device Type Format)



The GDTF Group have jointly developed the GDTF protocol for the purposes of creating a unified definition for the exchange of data for the operation of intelligent luminaires. This unified standard provides a consistent and dependable way to adapt new fixtures and devices in the lighting industry. GDTF is a benefit for manufacturers, customers, and users of lighting control systems, CAD systems, and pre-visualizers. With GDTF, the tools they use to perform their jobs will work without the need for advanced IT knowledge.

The DMX Plugin contains support for GDTF file importing for data parsing and asset usage. GDTF files contain information about a particular fixture type such as mode names, attribute names, default values, and more. The GDTF files can be used to auto-configure your DMX fixture types making project setup quicker and easier.

To import a GDTF file, you can drag and drop the file from a containing folder into the Content Browser in Unreal Engine.



The drag and drop operation will pop-up in the window. If you would like to import the asset into a new folder you can check the Use Sub Directory option. After selecting Import or Import All, a DMXGDTFImport asset containing the description data and attributes of a given DMX fixture will be created.



Only XML data import is supported at the moment.





In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

DMX Quickstart

Components

Fixture Group

Matrix

DMX Screen

The feature allows the user to sample the pixels of a specified texture and output the color sample as DMX. The pixel mapping feature integrates with the other DMX plugins utilizing the DMX Library assets and DMX Protocol functionality. To create a new Pixel Mapping asset right-click the content browser, navigate to the DMX category, and select DMX Pixel Mapping.



The Pixel Mapping editor is organized similarly to the UMG interface.



Panel

Description

Palette

Default components that represent different types of fixtures. Drag a component into the Designer to add them.

Hierarchy

This is a representation of all the components added for this Pixel Mapping asset and their associated parents and children in the hierarchy.

Designer

Move around various components to sample portions of the texture. This is where you configure what part of the texture will actually be sampled for DMX output.

Preview

Provides a preview of the visible output after the downsampling is applied to the texture from the component layout in the Designer.

Details

Set relevant properties for the selected component in the hierarchy.

Components

Fixture Group

The Fixture Group component is used to output DMX to multiple fixtures defined in a DMX Library. Fixtures can be added to this group via drag and drop from the Details panel into the Designer. Each fixture in the group can be configured so the RGB values output to any attributes assigned for the fixture.



Property

Description

Color Mode

The method for sampling the texture, RGB (Red Green Blue) or Monochrome (Black and White).

Color Sample

The colors to sample for DMX output (includes an invert option).

R/G/B Attribute

The attribute to which the fixture patch is assigned to output the color sample data.

Output Modulator

DMX Modulators are available data manipulation and conversion functions that can be used and applied to either inbound or outbound DMX data. Refer to Output Modulators for more information.

Editor Color

The color set for the box visualization.

Lock in Designer

Lock position in the Designer.

Visible in Designer

Show / Hide in the Designer.

Cell Blending Quality

The quality at which to sample the image section.

Position X

The X position relative to the parent position.

Position Y

The Y position relative to the parent position.

Size X

The size X in pixels.

Size Y

The size Y in pixels.

Matrix

The Matrix component is used to output DMX to a matrix fixture set in a DMX Library. A matrix fixture can be assigned by setting the DMX Library and Fixture Patch properties to a patched matrix fixture. All cells will automatically show in the pixel mapper with a number assignment representing the position relative to the matrix order defined in the DMX library.



Property

Description

Color Mode

The method for sampling the texture, RGB (Red Green Blue) or Monochrome (Black and White).

Color Sample

The colors to sample for the DMX output (includes an invert option).

R/G/B Attribute

Attribute to which the fixture patch cells are assigned to output the color sample data.

Extra Attributes

Additional attributes to statically output to while the pixel mapper renders.

Output Modulator

DMX Modulators are available data manipulation and conversion functions that can be used and applied to either inbound or outbound DMX data. Refer to Output Modulators for more information.

Fixture Patch Matrix Ref

DMX Library and Fixture Patch assignment to output the DMX.

Editor Color

The color set for the box visualization.

Lock in Designer

Lock position in the Designer.

Visible in Designer

Show / Hide in the Designer.

Cell Blending Quality

The quality at which to sample the image section.

Position X

The X position relative to the parent position.

Position Y

The Y position relative to the parent position.

Size X

Size X in pixels.

Size Y

Size Y in pixels.

DMX Screen

The DMX Screen component is used to output raw DMX to a matrix of cells manually set in the details panel.



Property

Description

Local Universe

The output universe.

Start Address

The starting address for the first cell.

Color Space

The desired sample type.

Distribution

The order in which to address consecutive cells.

Ignore Alpha Channel

Controls whether or not to use the Alpha channel when the color space includes Alpha.

Pixel Intensity

Controls the pixel intensity multiplier for the DMX output.

Alpha Intensity

Controls the intensity of the Alpha channel when the color space includes Alpha.

Show Addresses

Hide/Show the assigned address of the cell.

Show Universe

Hide/Show the assigned universe of the cell.

Send to All Output Ports

When enabled, outputs to all Output Ports specified in the Plugin Settings.

DMX Output Ports

Add Array elements to select which Output Ports to use. This parameter is disabled when Send to All Output Ports is enabled.

Position X

The X position of the screen relative to the texture origin.

Position Y

The Y position of the screen relative to the texture origin.

Size X

The size of the screen in the X-direction in pixels.

Size Y

The size of the screen in the Y-Direction in pixels.

X Cells

The number of cells in the grid in the X-direction.

Y Cells

The number of cells in the grid in the Y-direction.

Editor Color

The color set for the box visualization.

Lock in Designer

Lock position in the Designer.

Visible in Designer

Show/Hide in the Designer.

Cell Blending Quality

The quality at which to sample the image section inside the cell.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

DMX Quickstart

Normalized Attribute Values

Float to Int

Int/Byte To Float

Set Fixture Default Values on Begin/End Play

Reference Multiple Fixtures

Fixture Patch BP Functions

The following Blueprint tools are useful for getting, setting, and managing DMX data.

Normalized Attribute Values

If you would like to use floats instead of ints or bytes for managing DMX data you can use the normalization tools that convert to and from int/byte values to floats. See below for attribute examples.

Float to Int



Int/Byte To Float



Set Fixture Default Values on Begin/End Play

Below is an example of how to reset a fixture to its default values on Begin/End play. Using the Get Attribute Default Map and Send DMX nodes, users can reset all fixtures to their starting position.



Reference Multiple Fixtures

If you would like to get references to more than one fixture you can use one of the included getter functions that return an array of fixture patch references. You can then use a for loop to send to all fixture patches. See the image below for examples, and refer to the Blueprint API for details.



Reference Example 1





Reference Example 2



Fixture Patch BP Functions

There are many helper functions inside the fixture patch reference to help the user-managed data. See the image below for examples, and refer to the Blueprint API for details.



In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

DMX Quickstart

DMX Subsystem

Send DMX BP

DMX Send Raw BP

Receive DMX

On Protocol Received (DEPRECATED in 4.26)

On Fixture Patch Received

Get DMX Attribute Values

Included in the DMX plugin is a range of custom Blueprint nodes for simplifying DMX sending and receiving outside of C++. Additionally, contained in the plugin is a range of getter and setter functions mirroring common Unreal Engine architecture and logic, enabling a shallow learning curve to get into DMX programming. These functions provide access to parameters like attribute names, tag names, the active universe, channels, fixture references, and more.

All Blueprints are globally accessible and can be entirely implemented in UMG. There is no need for an actor in the scene. For organizational purposes, nodes have been built under a custom DMX subsystem providing clear organizational structure and easy searching for DMX specific nodes.

DMX Subsystem

The DMX Subsystem acts as a targeting system for organizing Blueprint attributes in both a code and user experience context. For each node contained within the subsystem, users are required to have the DMXSubsystem node as the target input.



Send DMX BP

This Blueprint sends out DMX on the specified protocol for the given fixture patch and the given attribute names and values defined in the input map. For this blueprint, the user must have a valid DMX Library asset with at least one registered controller, fixture type, and fixture patch. The protocol is defined by the input fixture patch.

Pin

Description

Target

The DMX Subsystem reference.

Fixture Patch

The fixture patch reference to send.

Address

The map of attribute names and the values to send for each (Key = Attribute Name, Value = Value to Send).

Return

EDMXSendResult



DMX Send Raw BP

This Blueprint sends DMX to a protocol universe given a protocol specification and an address/value map. This Blueprint is independent of the DMX Library and sends raw DMX data for a particular protocol and universe. SendDMX is the typical Blueprint while SendDMXRaw is mostly used for quick debugging and prototyping when no fixture patch is present nor available.



This Blueprint does not require a DMX Library.



Pin

Description

Target

The DMX Subsystem Reference.

Selected Protocol

The protocol you would like to send on.

Universe

The remote universe to send to.

Address

The map of addresses and values to send (Key = Address, Value = Value to Send).

The key must be greater than 0.



Return

EDMXSendResult



Receive DMX

On Protocol Received (DEPRECATED in 4.26)

With the Bind Event to On Protocol Received node, users are able to bind a custom event inside their event graph that will listen for any incoming DMX. If successfully received, the event will execute and provide information about the received packet including the protocol, the universe, and byte array.



This event can fire faster than tick depending on the number of received calls so be aware of what you execute to ensure efficient CPU usage. It is recommended to check your incoming data before running logic execution.



To use this node, simply bind the node to a custom event.



Pin

Description

Protocol

The protocol received.

Remote Universe

The remote universe received.

DMXBuffer

The full byte array for the universe received.

On Fixture Patch Received

With the On Fixture Patch Received node, users are able to listen for any incoming DMX for a particular fixture patch assigned in the DMX component. If successfully received, the event will execute and provide information about the received packet including the fixture patch receiving and all channel values of the fixture patch. This event is only executed when new values are received for the fixture patch assigned in the DMX component.



Pin

Description

Fixture Patch

The patch that is receiving DMX.

Value Per Attribute

All normalized values for attributes in the fixture patch assigned in the DMX component.

In order to receive incoming DMX in Unreal Engine, the sender must be transmitted to the proper IP address. This IP should be the IP that is being used for the project. This IP is set inside Project Settings > Plugins > DMX Plugin > Interface IP Address. By default, this will be set to 0.0.0.0 which selects the primary network interface card as determined by the operating system.

If you would like to receive from an alternate source find your IP address and make sure your DMX sending source is broadcasting on your network card's IP subnet.

For example, if your network IP address was 192.168.1.100 your sender should broadcast out on 192.168.1.255 in order for Unreal Engine to receive. Notice the 255 on the end, indicating to broadcast on your network interface card IP subnet.

Get DMX Attribute Values

The Get DMX Attribute Values Blueprint returns a map with the attribute names and their current values for the input fixture type. Here is an example of existing Blueprint attributes that allow getting current DMX values from a given DMX fixture patch.

Using GetDMXFixturePatch and GetDMXAttributeValues in combination, the user is able to expose the attributes for the selected patch using the Expose Attributes button in the details panel. This will list all available attributes for the specified fixture patch and output their current values.



Alternatively, if the user wants to input a dynamically-set fixture patch, they will not be able to expose the attributes as before but will be able to specify the attribute values they would like to get by calling the Find attribute on the Out Attributes Map. See the example below.



In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

DMX Quickstart

Matrix Fixture Blueprints

A matrix fixture differs from a standard fixture in that it has a group of "cells" that can be individually controlled. Each cell has the same attributes and functionality as the other cells in its group. An example of a matrix fixture is the "MagicPanel" which contains a group of cells made up of pixels. Each pixel has a set of attributes to control it such as "Red", "Green", "Blue", and "Dimmer".



To set up a matrix feature, you need to configure the Fixture Type in the DMX Library. In the Library, go to the Fixture Type panel, and under Fixture Settings, select the DMX Category and check Matrix Feature. Use the DMXImport when possible. Additionally, make sure to set the Entity Properties Name to MatrixFeature.



Click image to expand.

In the Modes Properties panel, you can set a number of settings to configure their matrix cells.

Property

Description

First Cell Channel

The first channel that the first cell in the matrix contains

X Cells

Number of cells in the x-direction

Y Cells

Number of cells in the y-direction

PixelMapping Distribution

Cell order for all cells in the group

Cell Attributes

Attributes assigned to each cell



Click image to expand.

Matrix Fixture Blueprints

There are a number of Blueprints available for setting and getting data for matrix cells. You can access these through the Fixture Patch reference to call Get Matrix Cell, as seen in the image below.



Click image to expand.

DMX Plugin Settings

In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

DMX Quickstart

The DMX Library asset is the main DMX plugin data structure that holds information in regards to:

Controllers

Fixture Types

Fixture Patches

The DMX Library asset is found under DMX > DMX Library when navigating the asset creation menu.

DMX Library

In order to understand and use the content on this page, make sure you are familiar with the following topics:

DMX Overview

DMX Quickstart

Input Ports

Output Ports

This page describes the settings for the DMX Plugin.

Plugin Setting

Description



Communication Settings



Input Ports

An array of input configurations for receiving DMX. Refer to the Input Ports section below for more details.

Output Ports

An array of output configurations for sending DMX. Refer to the Output Ports section below for more details

DMX Send Rate

The rate in hertz (Hz) to send out DMX. Default value is 30.

Send DMX by default

When enabled, the project sends DMX over the network. Default value is False.

Receive DMX by default

When enabled, the project receives DMX from the network. Default value is False.



Fixture Settings



Fixture Categories

Defines the fixture categories using a set of text elements. These categories are used inside your DMX Library inside the Fixture Type tab for the purposes of organizing and grouping the fixtures that you add to your scene.

By default, the plugin provides five generic categories.

Fixture Attributes

Internal naming convention used as an alias for imported fixture properties

Attribute Names: These names act as aliases for any functions that are imported into the project via GDTF files. Attributes are easily accessible from any part of the project and remove the dependence upon DMX libraries.

Additionally, attributes solve the problem of mapping unpredictable imported function names to a generic list of terms that are easy to reference via dropdowns anywhere in the project.

Attribute Keywords: Keywords are the input names mapped to the defined attribute name. Any number of keywords can be mapped to a single attribute name, just ensure each keyword is separated by a comma or space.

DMX Ports can be referenced and used within the DMX Library. You can have different DMX Libraries using different Ports configurations to avoid DMX data collisions.



Input Ports

Plugin Setting

Description

Port Name

User-defined name for the input port for easy identification.

Protocol Name

Specifies which DMX protocol to use. Options include:

Art-Net

sACN

Network Interface Card IP Address

The IP Address for the network card used for DMX control. By default, this is set to 0.0.0.0 which selects the primary network card determined by your operating system.

Local Universe Start

Location of the first Universe to receive DMX.

Amount of Universes

Number of Universes to use in the project.

Extern Universe Start

Offset to apply to the Universe start for external software or hardware.

For example, if Local Universe Start is set to 1 and Extern Universe Start is set to 20. Unreal will remap Universe 1 locally to Universe 20 on the receiving hardware.

Output Ports

Plugin Setting

Description

Port Name

User-defined name for the input port for easy identification.

Protocol Name

Specifies which DMX protocol to use. Options include:

Art-Net

sACN

Communication Type

The type of communication to use with the port. Options include:

Broadcast

Unicast

Network Interface Card IP Address

The IP Address for the network card used for DMX control. By default, this is set to 0.0.0.0 which selects the primary network card determined by your operating system.

Input into Engine

When enabled, output to this port is input to the engine. It will only show under output ports and will not be visible in Monitors as input.

Local Universe Start

Location of the first Universe to send DMX.

Amount of Universes

Number of Universes to use in the project.

Extern Universe Start

Offset to apply to the Universe start for external software or hardware.

For example, if Local Universe Start is set to 1 and Extern Universe Start is set to 20. Unreal will remap Universe 1 locally to Universe 20 on the receiving hardware.

Switchboard Quick Start

Switchboard Settings Reference

Rendering to Multiple Displays with nDisplay

Using Take Recorder

Stage Monitor

In-Camera VFX

Virtual Production Roles

Take Recording with Switchboard

Launching nDisplay with Switchboard

Syncing and Building

Source Control Buttons

Switchboard is a Python application for controlling multiple remote devices and relies on the companion application SwitchboardListener to communicate with them. SwitchboardListener is an Unreal Engine C++ application that runs a TCP socket server on each device to share JSON messages with Switchboard.

Switchboard's features include:

Start Unreal Engine remotely on a device in a Multi-User session.

Launch nDisplay on multiple devices.

Record with embedded Take Recorder controls.

Sync all devices to a specific changelist and build your Project and Unreal Engine from source.

Connect to and control the following devices: KiPro, Live Link Face, Shogun, and SoundDevices.

Add your own device plugins and extend Switchboard and SwitchboardListener for custom controls.

This page covers some of the features available in Switchboard. For getting started with Switchboard, follow the steps in the Switchboard Quick Start. See the Switchboard Settings Reference for specific details on all the settings available.

Virtual Production Roles

You can create device roles in the Virtual Production plugin and assign them to Unreal devices in Switchboard. Based on a device's role, you can run custom logic in Unreal Engine and use them for filtering events in Stage Monitor. The roles are stored in an .ini file in your project's Config\Tags folder.

The following steps show how to add roles:

In the Editor's main menu, choose Edit > Project Settings to open the Project Settings window.

In Project Settings, open the settings for the Virtual Production plugin in the Plugins section.





Click image to expand.



Select Edit… next to the Roles parameter to open the Gameplay Tag dropdown window.





Click image to expand.



Expand Add New Gameplay Tag and enter the name of a role. Select Add New Tag to add the role to the .ini file.





Click image to expand.



The roles are stored in the file DefaultGameplayTags.ini by default. You can create a new .ini file in Project Settings and use it as the Source file when creating new roles. Create a new file by expanding New Tag Source, entering the name of the file, and pressing the Add New Source button.





Click image to expand.



By default, Switchboard will look for roles in the file VPRoles.ini. In the Switchboard Settings, you can set the filename and assign one or more roles for each device. The roles are passed to Unreal Engine when it's launched. If a role is not supported, such as if the .ini file is out of date on a device, an error is logged in Switchboard.

To be able to see what roles exist in Switchboard, it must be connected to the SwitchboardListener connected to the device. If roles are available, you can see them in the device's settings in Switchboard.





Click image to expand.



Take Recording with Switchboard

You can record takes in a connected Unreal device using the TakeRecorder functionality embedded in Switchboard. Switchboard uses OSC to communicate with the Unreal Instance for recording. The Switchboard plugin includes a default OSC Listener to create this connection for you.

Make sure the following settings are set up properly:

Enable Start an OSC Server when the editor launches in the Virtual Production Editor plugin.

The OSC Server Port in the Virtual Production Editor plugin matches the OSC Client Port in the Switchboard Settings.

The OSC Server Address is reachable by Switchboard.

]



Click image to expand.



In Switchboard, the status icon turns green if the OSC connection is successful for the device.

Comparing the Switchboard status icons.







The status icon will turn orange after starting Unreal if the OSC connection is unsuccessful.



At the top of Switchboard, you can set the Sequence name, Slate name, and Take number.

The names should immediately be reflected in the TakeRecorder of the OSC-connected Unreal device.

Press the red button on the right to start and stop recording.

If a device is recording, its background is set to red in Switchboard.

After each recording, the Take number is incremented.



Check the Debug log to verify expected status changes for devices.



Launching nDisplay with Switchboard

You can set up Switchboard to communicate with all your nDisplay devices. When you choose to add an nDisplay device in Switchboard, you add the location of your nDisplay config file. Switchboard parses the config file and converts the cluster nodes specified in the file to Switchboard devices. See Switchboard Settings for more details on how the nDisplay devices can be further configured in Switchboard.



In addition to adding nDisplay devices, information on the status of the nDisplay cluster appears on the right side of the Switchboard window in the nDisplay Monitor panel. The following table describes the information included in the monitor. Whenever the values are unexpected, the color of the cell turns yellow as a warning.

You can execute commands remotely to the nDisplay cluster by entering a command in the Console text box (such as "stat fps" or "r.RayTracing.SceneCaptures 0") and clicking Exec.



Column

Description

Node

The nDisplay scene node.

Host

The device's IP address.

Connected

Displays yes or no.

Driver

The NVIDIA driver version.

PresentMode

The swap chain presentation mode.

Gpus

Indicates if the detected GPUs are being synchronized by a Quadro Sync card.

Display

Indicates if the detected displays are being synchronized.

SyncRate

The display refresh rate.

HouseSync

Indicates the presence of an external synchronization signal into the Quadro Sync card.

SyncSource

Indicates if the synchronization source is house sync or vsync.

Mosaics

Lists the display grid configuration.

Taskbar

Indicates whether the taskbar auto-hide setting is set or not.

InFocus

Indicates whether the nDisplay instance window is in focus. It is recommended to be in focus.

ExeFlags

Flags on the UnrealEngine executable. We recommend using the Disable Fullscreen Optimizations option.

OSVer

Operating system version.

CPUUtilization

Average CPU utilization. The number of overloaded cores are displayed in parentheses.

MemUtilization

Physical memory utilization

GpuUtilization

Average GPU utilization. Clock speed is specified in parentheses.

GpuTemperature

Max GPU Temperature in Celsius degrees across all sensors.

Syncing and Building

You can connect your source control to Switchboard, then sync and build your project and engine according to a certain changelist across all connected devices. You can see what changelists are on each connected device to know which ones need to be updated.

Follow these steps to add your source control information to Switchboard:

Open Switchboard Settings.

In the Switchboard Settings dialog, check the box next to Source Control.

In the section under Source Control:

Set P4 Project Path to your project's Perforce Stream.

If you want to build the engine from source, set P4 Engine Path to your engine's Perforce Stream. Setting this path is not required if you only plan to sync and build your project.

Set Workspace Name to the name of your Perforce Workspace.



In the section under Project Settings:

Set UProject to the location of your Unreal Engine project.

Set Engine Dir to the directory where the binary release of the engine is located.

If you want to build the engine from source, check the Build Engine checkbox. If you are only building your project, leave it unchecked.



When your source control information is added, the Engine and Project changelists appear in Switchboard above the list of devices. This means that there is only one place where the current changelist for all devices is specified.



In this screenshot, the Project changelist and Engine changelist are shown.

Each device also shows what Engine and Project changelists it has. If a device's changelist is behind the one selected at the top of Switchboard, its text color turns red.

Source Control Buttons

Icon

Action

Description



Refresh

Updates the source control information in Switchboard.



Sync

Syncs all connected devices to the changelist. If this button is on the device's row, Switchboard only syncs that device. Controls on the devices are locked during a sync.



Build

Builds on all connected devices. If this button is on the device's row, Switchboard only builds on that device. Controls on the devices are locked during a build.



Sync and Build

Syncs and builds on all connected devices. If you enabled Build Engine in the settings, this option will sync and build the engine before the project.

If you don't want to sync the engine or the project, select the --None-- entry in the changelist dropdown to ignore the engine or project in the next sync and build operation.

Depending on your project's needs and the devices you are using, you may need to add or extend the device functionality in Switchboard. This page covers creating your own device plugin in Python. With some C++ knowledge, it is possible to extend the listener to accept more types of messages but this is not covered here.

The following instructions step through how to create a new device plugin, SampleDevice, for Switchboard that you can use as a starting point.

For the device plugin to be discoverable on load in Switchboard, you must create a folder and Python file with the naming convention <plugin_name>\plugin_<plugin_name>.py in \Engine\Plugins\VirtualProduction\Switchboard\Source\Switchboard\switchboard\devices\.

For the SampleDevice plugin create the following file: \Engine\Plugins\VirtualProduction\Switchboard\Source\Switchboard\switchboard\devices\sampledevice\plugin_sampledevice.py.

Extend the Device`class defined in \Engine\Plugins\VirtualProduction\Switchboard\Source\Switchboard\switchboard\devices\device_base.py in the plugin_sampledevice.py` file:

Import Device from device_base.py.

Create a new class DeviceSampleDevice which inherits from Device.

Import LOGGER from switchboard/switchboard_logging.py to report errors.

Verify the file is discoverable by Switchboard. Launch Switchboard and expand the Add Device dropdown menu. SampleDevice appears in the list.



Adding a SampleDevice to your Switchboard won't create a widget in the view. To create a SampleDevice widget, extend DeviceWidget in plugin_sampledevice.py:

Import DeviceWidget from device_widget_base.py.

Create the new class DeviceWidgetSampleDevice which inherits from DeviceWidget.

Verify the widget appears in Switchboard. Launch Switchboard and add a SampleDevice. A minimal SampleDevice widget appears in the view.



Create a custom dialog when a new SampleDevice is added by creating a new class which inherits from AddDeviceDialog and assigning it to the static variable add_device_dialog in the DeviceSampleDevice class:

Import AddDeviceDialog from device_widget_base.py.

Import Qt modules from PySide2

Create a new class AddSampleDeviceDialog which inherits from AddDeviceDialog and set the device_type parameter to "SampleDevice" when calling the base class's constructor.

In the new class's constructor add a QLineEdit text field to the dialog.

Override the add_device_dialog static variable in DeviceSampleDevice with the new class.

`

Verify the new device dialog appears in Switchboard. Launch Switchboard and add a SampleDevice. The additional text field appears in the dialog.



Devices can also have a widget on the right side of Switchboard, tabbed with other extension dialogs, to share more information. To create this tab, override the classmethod plug_into_ui from the Device base class.

Create a new class SampleDeviceTabView which inherits from QtWidgets.QWidget.

Create the class member tab_view in DeviceSampleDevice to hold the instance of the widget.

Override the classmethod plug_into_ui in DeviceSampleDevice and initialize tab_view with the new class SampleDeviceTabView.



These steps showed how to create a new device plugin for Switchboard. For an advanced example, see the nDisplay device plugin for Switchboard.

Switchboard Settings Reference

Rendering to Multiple Displays with nDisplay

Take Recorder

Stage Monitor

In-Camera VFX

Prerequisites

Step 1 - Launching Switchboard Listener

Step 2 - Launching Switchboard

Step 3 - Adding a Device in Switchboard

Step 4 - On Your Own

The instructions on this page provide a step-by-step guide to getting started with Switchboard. By the end of this tutorial, you'll know how to set up Switchboard to connect to multiple devices.

Prerequisites

You must have the following set up before completing the next steps:

The Switchboard plugin enabled. After you've added the plugin and restarted the engine, Switchboard and SwitchboardListener options appear in the Toolbar.



Click image to expand

Dependencies installed. In the main menu, choose Edit > Editor Preferences > Plugins > Switchboard and click Install Dependencies.



Click image to expand

(Optional) If you're using Windows as your OS, you can choose to install a desktop shortcut for Switchboard. In the main menu, choose Edit > Project Settings > Plugins > Switchboard and click Add Shortcut.



Click image to expand

If you built the engine from source, you will need to build SwitchboardListener separately. You can either build the project in Visual Studio or run the following command in the root directory of the engine source code: Engine\Binaries\DotNET\UnrealBuildTool.exe Win64 Development SwitchboardListener.

Step 1 - Launching Switchboard Listener

On each device you want to connect to Switchboard, you will need to launch SwitchboardListener. In the Toolbar, select Switchboard Options > Launch Switchboard Listener, which launches the listener on the local machine with the default address 0.0.0.0:2980, or the address you specified for Listener Commandline Arguments in Editor Preferences.



The listener minimizes its window automatically on start to avoid issues with nDisplay devices. You can find the application in your OS's taskbar.



You can also select Launch Switchboard Listener on Login which launches the listener on the local machine every time you log into the computer.

Step 2 - Launching Switchboard

There are multiple ways to launch Switchboard:

Opening a project in Unreal Editor, and selecting Launch Switchboard from the Toolbar.



Using the desktop shortcut, if you installed it on your computer. Refer to Switchboard Prerequisites for steps on installing this shortcut.

Running Engine\Plugins\VirtualProduction\Switchboard\Source\Switchboard\Switchboard.bat.

The Add New Switchboard Configuration window appears when Switchboard is launched for the first time. You can either fill out the fields and select OK, or select Cancel and update them later in the Switchboard Settings. Both options open Switchboard in a window.



Switchboard Configuration Parameters:

Parameter

Description

Name

The name you want to use to identify your Switchboard project.

uProject

The local path to the uProject you want to control via Switchboard.

Engine Dir

The local path to the engine directory of the engine you want to use. It is possible to either specify a path to an engine you have built from source or an installed engine release. Example: "C:\Program Files\Epic Games\UE_5.00\Engine"

Perforce

Enable this checkbox to use Perforce as your source repository.

P4 Project Path

The depot path to the directory containing the uproject file specified above.

P4 Engine Path

The depot path to the engine directory specified above. May be omitted if you don't plan on building the engine from source.

Workspace Name

The name of the locally available perforce workspace that has the uproject directory mapped.

Step 3 - Adding a Device in Switchboard

Switchboard supports several types of devices. These devices are implemented as plugins for Switchboard. Refer to Switchboard Settings for the list of device plugins available by default, and steps on how to create your own device plugin.

The following example shows how to add an Unreal Device in

In Switchboard, select Add Device > Unreal to open the Add Unreal Device window.



In the Add Unreal Device window, assign a Name to the machine running Unreal Engine and the IP Address of the computer. Select OK. The device is added to the list of Unreal Devices in Switchboard.



You can also change the IP address and name of the device after it has been added.

Click Connect to listener to connect to the SwitchboardListener application running on the remote machine. The status icon turns blue when the device is connected.



Click Start Unreal to launch an instance of the Unreal Editor on the remote machine.



The status icon on the left turns either orange or green when the Unreal instance launches.

The green status indicates that the Unreal instance is connected through OSC so you can use Take Recorder from Switchboard.

The orange status indicates that it is not connected through OSC.



Click Stop Unreal to close the Unreal Editor on the remote machine.



Step 4 - On Your Own

This quick start showed you how to start Switchboard and SwitchboardListener, connect to remote devices, and control them from Switchboard. Refer to Switchboard Settings Reference for a complete list of options you can modify in Switchboard. Learn more about the following features to use in your project:

Sync and build your project and engine remotely.

Record a take remotely from Switchboard.

Launch and monitor your nDisplay cluster.

Switchboard Quick Start

Rendering to Multiple Displays with nDisplay

Take Recorder

Stage Monitor

Integrating Media



Switchboard Plugin Settings

Switchboard Settings

General Settings

Project Settings

Multi-User Server Settings

Unreal Device Settings

KiPro Device Settings

Live Link Face

Motive Device Setttings

nDisplay Device Settings

Shogun Device Settings

SoundDevices Device Settings

This page describes the settings you can change for Switchboard.

Switchboard Plugin Settings

To access the Switchboard plugin settings, in the main menu of the Unreal Editor choose Edit > Project Settings > Plugins > Switchboard.



You can set the OSC Listener in the plugin settings. Switchboard requires an OSC Listener to be able to use Take Recorder. Refer to Take Recording with Switchboard for more details. You can configure how Switchboard launches and install any required dependencies in the Editor Preferences for the Switchboard plugin. The following table describes the parameters you can set in Editor Preferences.



Parameter

Description

Switchboard

Virtual Environment Path

The default Python version for Switchboard is Python 3.7.7. To use a different version of Python, change this field to point to a different Python interpreter on your machine.

Switchboard Listener

Listener Commandline Arguments

SwitchboardListener expects the following arguments:

-ip: Sets the IP address that Switchboard Listener listens on

-port: Sets the port that Switchboard Listener listens on

Launch Switchboard Listener on Login

When enabled, Switchboard Listener is launched on the local machine every time you log into the computer.

Switchboard Settings

Settings that are common to all device plugins are in the general section of the Settings panel, including the values added during the initial project set up. After you add a device, settings for those devices are appended to the settings panel, and a tab appears on the left so you can choose to filter the settings based on the device type.



Some general settings are repeated in a device's settings so you can override the value per device if needed. If you override a setting in a specific device, a different background color appears. As long as the override is in place, changing the global setting will not cause a change for this setting in the device.



The following sections describe all the settings that can be modified in the Settings panel.

General Settings

Parameter

Description

Config Path

The path where Switchboard config files are stored. These files hold all of the switchboard state.

IP Address

The IP address of the machine running Switchboard and the internal OSC server. Change the address here if you have multiple network controllers in the computer running Switchboard.

Transport Path

Currently not used in Switchboard.

Listener Executable Name

The program name to use for launching the switchboard listener application

Project Settings

Parameter

Description

Project Name

The name of the Switchboard project. Will be used as a basis for the filename that settings and devices are stored in.

UProject

The local path to the UE project file.

Engine Directory

The local path to the Unreal Engine directory.

Build Engine

The flag to enable building the engine from source in Switchboard.

Map Path

The relative path from the Content folder to maps that will appear in the Level dropdown in Switchboard.

Map Filter

The file filter for limiting what maps appear in the Level dropdown.

OSC

OSC Server Port

The port for the OSC server in Switchboard to listen on.

OSC Client Port

The port of the OSC client specified in the Unreal Editor.

Source Control

Workspace Name

The name of the Perforce workspace that maps to the depot project path.

Perforce Project Path

The Perforce depot path for the Unreal project specified in UProject. Only the depot folder containing the uproject file needs to be specified.

Perforce Engine Path

The P4 Engine Path setting is only required if you plan to build the engine from source, and not just the project. Refer to Syncing and Building for more details.

Multi-User Server Settings

Parameter

Description

Server Name

The name appended to the Project Name to create the full server name.

Command Line Args

Optional arguments passed to the Multi-User Server executable.

Unicast Endpoint

The Unicast Endpoint specified for Mult-User on launch. This is the port that the server listens for connections, and corresponds to the UDP Messaging settings in the Project Settings. The default value is 0.0.0.0:9030.

Multicast Endpoint

This is the multicast group that Multi-User should subscribe to. All Unreal nodes participating in the same Multi-User session should have the same multicast endpoint. Modification of this variable is for advanced configurations.

Multiuser Executable Name

The name of the program for launching a Multi-User Server session.

Auto Launch

Enable this option to launch the Multi-User Server the first time either an Unreal or nDisplay device is started. The server always runs on the same device as Switchboard.

Clean History

Passes the argument -ConcertClean to the server so the server session's working directory is cleaned on launch.

Auto Build

Enable this option if the Multi-User Server should be rebuilt when the source changes in the Engine folder.

Auto Endpoint

Enable this option if the static endpoint of the Multi-User Server should be assigned when launching an Unreal Editor or nDisplay node. This is equivalent to adding a static endpoint to the Multi-User Server Unicast Endpoint in the Project Settings.

Unreal Multi-user Server Auto Join

Enable this option to have each Unreal or nDisplay device automatically join the Multi-User Server.

Unreal Device Settings

Parameter

Description

Is Recording Device

Enable this option if this device type is going to record sequences.

Buffer Size

The internal buffer size of the socket client connected to SwitchboardListener.

Command Line Arguments

Optional command line arguments that are passed to Unreal on start.

ExecCmds

Sets -ExecCmds (console commands) that are passed to Unreal on start as command line arguments.

DPCVars

Pass Device Profile Console variables in a comma separated list.

Listener Port

The port number the listener listens on. The default port is 2980.

Roles Filename

The filename of the .ini file that contains the Virtual Production Roles.

Stage Session ID

An ID that groups Stage Monitor providers and monitors. Instances with different Session IDs are invisible to each other in Stage Monitor.

Unreal Editor filename

The filename of the Unreal Editor executable.

Number of GPUs

The number of GPUs to use on a device in case there is more than one.

Process Priority

Overrides the priority of the process.

Skip Package Recovery

Automatically discards auto-saved packages at startup, skipping the restore prompt. Useful in multi-user scenarios, where restoring from auto-save may be undesirable.

Unicast Endpoint

The Unicast endpoint for the node. Typically this should be the default assigned value. Switchboard will use the name of the switchboard assigned IP address with :0.

Extra Static Endpoints

Additional static endpoints to set when the Unreal Editor is launched. This corresponds to the static endpoint setting for UDP Messaging in Project Settings.

Multicast Endpoint

Overrides the multicast endpoint.

Log Download Dir

Destination folder for collecting logs and Unreal Insights trace files from remote devices. By default, the path is in the project directory in the folder /Saved/Logs/Switchboard.

Reflect Editor Visibility to Game

Enable this option to reflect the state of the editor visibility of an object to the corresponding -game visibility, such as Hidden in Game, in a Multi-User session. In an nDisplay configuration you typically want to enable this for the operator station so that changes to level visibility will properly reflect the -game instances.

Rsync Server Port

The assigned port for the rsync server that runs on the Switchboard application. The rsync server is used to transfer larger data from the connected nodes to the main Switchboard instance.

Listener Timeout

The timeout period for a Switchboard Listener process. If the Switchboard Listener does not detect a message from the main Switchboard application within the given timeout period, then the connection to the Switchboard application is terminated.

For each Unreal instance:

Parameter

Description

IP address

The remote address on which the SwitchboardListener listens.

Roles

Dropdown menu enabling selection of a Virtual Production Role from those provided in the Roles .ini file.

Exclude from build

When enabled, the engine builds should not occur on this node.

Is Recording Device

Override for whether this device is used for recording.

Command Line Arguments

Override for optional command line arguments.

ExecCmds

Override for exec commands for Unreal.

DPCVars

Override for the Device Profile Console variables.

Number of GPUs

Override for the GPU count to use.

Process Priority

Override for the priority of this instance.

Skip Package Recovery

Override for whether auto-saved packages are automatically discarded at startup.

Unicast Endpoint

Overrides the unicast endpoint.

Extra Static Endpoints

Overrides the extra static endpoints.

Engine Directory

Override for the local path to the engine.

Workspace Name

Overrides the Perforce Workspace name.

uProject Path

Override for the local path to the uproject file.

KiPro Device Settings

Parameter

Description

Is Recording Device

Enable this option if this device type is going to record sequences.

IP address

The address of the KiPro web server.

Auto Play After Stop

Enable this option to playback automatically when the recording ends.

Live Link Face

Parameter

Description

Is Recording Device

Enable this option if this device type is going to record sequences.

IP address

Currently not used in Switchboard.

Motive Device Setttings

Parameter

Description

Is Recording Device

Enable this option if this device type is going to record sequences.

Motive Command Port

Communication port used for Motive devices.

IP address

The assigned IP address of the Motive Device

nDisplay Device Settings

Parameter

Description

nDisplay Config File

Both the .cfg and the JSON formats are supported.

Use All Available Cores

Enable this option to use all cores.

Texture Streaming

Toggle texture streaming.

Render API

The options are DirectX11 or DirectX12.

Render Mode

Allows selection of nDisplay render modes.

Render Sync Policy

Refer to Render Sync Policies for more details.

nDisplay Executable Filename

Sets the name of the executable for the project. This is useful for packaged builds.

Extra Cmd Line Args

Optional command line arguments that are passed to nDisplay on start.

ExecCmds

Sets -ExecCmds (console commands) that are passed to Unreal on start as command line arguments.

DPCVars

Pass Device Profile Console variables in a comma separated list.

Unattended

Enable this option to indicate that it is an unattended application and all dialog windows should be suppressed.

Number of GPUs

The number of GPUs to use on a device in case there is more than one.

Process Priority

Overrides the priority of the process.

Minimize Before Launch

Enable this option if all windows on the host computer should be minimized prior to launching the nDisplay node.

Logging

Custom logging that can be controlled per device.

Unicast Endpoint

The Unicast endpoint for the node. Typically this should be the default assigned value. Switchboard will use the name of the switchboard assigned IP address with :0.

Extra Static Endpoints

Additional static endpoints to set when the nDisplay Renderer is launched. This corresponds to the static endpoint setting for UDP Messaging in Project Settings.

Disable Ensures

Disable ensure conditions in the running instance. The ensure condition will still be logged but will not cause instances to terminate.

Disable All Screen Messages

Enable this option if on-screen messages should be disabled.

Listener Port

The port number the listener listens on. The default port is 2980.

Roles

Dropdown menu enabling selection of a Virtual Production Role from those provided in the Roles .ini file.

Stage Session ID

An ID that groups Stage Monitor providers and monitors. Instances with different Session IDs are invisible to each other in Stage Monitor.

For each nDisplay node:

Parameter

Description

IP address

The remote address on which the SwitchboardListener listens.

Roles

Dropdown menu enabling selection of a Virtual Production Role from those provided in the Roles .ini file.

Exclude from build

Overrides whether to exclude this node for enginge builds.

UE Command Line

The full command for launching the nDisplay renderer on this node.

Extra Cmd Line Args

Override for optional command line arguments.

ExecCmds

Override for exec commands for nDisplay

DPCVars

Override for the Device Profile Console variables.

Number of GPUs

Override for the GPU count to use.

Process Priority

Override for the priority of this instance.

Unicast Endpoint

Overrides the unicast endpoint.

Extra Static Endpoints

Overrides the extra static endpoints.

Engine Directory

Override for the local path to the engine.

Workspace Name

Overrides the Perforce Workspace name.

uProject Path

Override for the local path to the uproject file.

Shogun Device Settings

Parameter

Description

Is Recording Device

Enable this option if this device type is going to record sequences.

IP Address

The address of the device running Shogun.

Save Path

Path to Shogun's capture folder.

SoundDevices Device Settings

Parameter

Description

Is Recording Device

Enable this option if this device type is going to record sequences.

IP Address

The address of the SoundDevices web server.

In-Camera VFX

Rendering to Multiple Displays with nDisplay

Required Plugins

Setting up Timecode

Assigning Machine Roles

Assigning Roles in Switchboard

Assigning Roles in Command Line

Opening Stage Monitor

Using Stage Monitor

Critical State

Filtering

Exporting / Importing

Stage Monitor Event Types

Adding Event Types

Stage Monitor Settings

General Settings

Monitor Settings

Provider Settings

Export Settings

When operating a stage in a live environment, multiple machines running instances of Unreal Engine (UE) work in tandem and rely on each other. Operators may use some instances to render on a LED wall, some could be used to modify the scene in the Editor, and others may be used for compositing. With Stage Monitor, you can receive reports of different events from all these instances of UE and be able to troubleshoot any issues in the setup.





Click image to expand.



At the end of this overview, you will be familiar with how to use Stage Monitor and how to add custom events for your project.

Required Plugins

Add the following plugins to your Project to get started with Stage Monitor.

Plugin Name

Purpose

Stage Monitoring

Required - Main plugin enabling data providers and stage monitoring logic.

Virtual Production Utilities

Required - Enabled with StageMonitoring plugin to be able to use VirtualProduction role's feature.

Switchboard

Optional - Facilitates launching multiple instances of UE operating a stage. It can also be used to configure the role assigned to each instance.

Follow these steps to enable the plugins for your project:

From the Main Menu Bar, select Edit > Plugins.



In the Plugins window, find the Stage monitor plugin and check Enable.





Click image to expand.



When prompted, select Yes.



Click Restart Now to close the Editor and restart with your new Plugin activated.



Repeat the above process to enable the Virtual Production Utilities and Switchboard plugins.

These plugins may already be enabled by default, depending on the version of UE that you are working in. It's best to double-check that they're enabled while in the Plugins menu.

Setting up Timecode

Each instance of Unreal Engine generates its own timecode. With multiple machines communicating together, events can appear to be out of order in Stage Monitor if they're not synchronized. To effectively monitor UE instances, enable Timecode on all instances you want to monitor and use the same timecode provider. See Timecode and Genlock for more information on synchronizing timecode across machines.

Assigning Machine Roles

When operating a stage, each machine can perform a different role, such as renderer, editor, or compositor. Instances of UE can be assigned roles in a command-line argument or in Switchboard to utilize different logic based on their function. Stage Monitor uses these roles to determine what events an instance can generate and whether the instance should be monitored.

Assigning Roles in Switchboard

Switchboard will look for the file VPRoles.ini in each instance's project folder at \Config\Tags\VPRoles.ini. In the following example, the roles Render, Editor, and Compositor were added to the VPRoles.ini file:

In Switchboard, you can adjust the roles for each instance in the settings.





Click image to expand.



Assigning Roles in Command Line

You can assign each instance a role through a command-line argument. When launching the instance of UE, add the argument : -VPRole=RoleName, where RoleName is the role you assign to the machine, such as Editor.

Opening Stage Monitor

Stage Monitor data providers are started by default unless role filtering is used. When each instance is launched, they will look for a Stage Monitor, and once found they will start sending events. Periodically, an instance that is monitoring others will broadcast messages to discover data providers. Once a monitor is found, the data provider will start to send out any events that are emitted. Launch Stage Monitor to confirm that it sends and recieves information in the expected order.

Follow these steps to launch Stage Monitor:

Click the Window tab and Virtual Production > Stage monitor.



Activate the Stage Monitor using the Monitor Status toggle switch.



Once activated, you should be able to view connected instances in the upper menu.





Click image to expand.



Additionally, once activated you should see a steady stream of stage events populating the lower window.





Click image to expand.



Using Stage Monitor

Once the information starts flowing into Stage Monitor, it can be a lot to process. Here are some items to look for, and some tips to help you manage the event logs.

Critical State

Take Recorder uses the event type Critical State to designate when the scene is being recorded. While you're recording, any event could impact the result. This means that when a take has started, the stage enters Critical State, and when you stop the take, the stage exits Critical State. Since Critical State is an event type, you can set your own Critical States for any scenario.

To see Stage Monitor enter Critical State with TakeRecorder follow these steps.

Launch Stage Monitor and confirm that all instances of UE are connected and properly reporting events.

Launch Take Recorder by going to Window > Cinematics > Take Recorder.



In the Take Recorder, click the Start Take button.



After a brief pause, you will notice the Stage Monitor status indicator turn from green (not operational) to red (operational), indicating that the Stage Monitor is now in the Critical State.



Notice that while in the Critical State, events in the Event Log will be highlighted.



Click the Stop Take button in the Take Recorder to stop the take.



The video below shows this process in action.

Filtering

After a while, message logs become bigger and it might get harder to find something specific within them. Using the filtering menu, you can easily focus on the message types you are interested in, data providers that you want to isolate, and to only see events that happened while the stage was operational.

Launch the Stage Monitor by selecting Window > Virtual Production > Stage Monitor.



Under the Event Log, expand the Filters dropdown menu.



Select Message Type to filter by specific message types.



Select Provider to filter events by Event Provider.



Enable and select Role option to filter based on Role.



Enable and select Critical State Source option to filter based on Critical State sources.



Enable and select Time option to filter events by Time.



Exporting / Importing

Once a session is done, it is possible to export all events and providers to a JSON file. You can then review these logs externally, or directly in UE.

Launch the Stage Monitor by choosing Window > Virtual Production > Stage Monitor.



Near the upper left of the Stage Monitor, note the series of five buttons.



Click the disk icon to export the current log. After clicking the button you will be asked where you would like to save the log.



Click the orange dot on the left to enter review mode.



When entering review mode, you will see the name next to CurrentSession change to reflect the file you are reviewing.



While in review mode, click the folder icon to load a previously recorded log and review it.





Once a file has been opened, you can use the same filters to isolate specific events.

Stage Monitor Event Types

A couple of types of Stage Monitor events are triggered with the base version of UE. New types can be added through C++ by adding a dependency to the StageDataCore module, and inheriting FStageProviderEventMessage for events. Additionally, you can extend FStageProviderPeriodicMessage for repetitive messages. Below is a table listing common events, their file location, and their purpose.

Event Name

File Location

Description

Critical State Provider Message

StageMessages.h

Sent when entering or exiting Critical State.

Stage Provider Discovery Response Message

StageMessages.h

Part of the discovery protocol between monitors and providers.

Stage Provider Close Message

StageMessages.h

Sent when a provider is shutting down.

Frame Performance Provider Message

StageMonitorUtils.h

Periodically sent to refresh provider's frame data.

Hitch Detection Message

FramePerformanceProvider.h

Sent when a frame takes more time than the maximum allowed time desired.

Genlock State Event

GenlockWatchdog.h

Sent when CustomTimeStep is a genlocked one and its stage changed.

Genlock Hitch Event

GenlockWatchdog.h

Sent when CustomTimeStep is a genlocked one and a genlock signal (a frame) was missed.

Timecode Provider State Event

TimecodeProviderWatchdog.h

Sent when state of TimecodeProvider changes.

Timed Data Monitor Channel ConnectionState Event

TimecodeProviderWatchdog.h

Requires TimedDataMonitor plugin. Sent when a channel connection state changes.

Timed Data Monitor Channel Evaluation State Event

TimedDataMonitorSubsystem.h

Requires TimedDataMonitor plugin. Sent when a channel evaluation state changes.

Adding Event Types

Follow these steps to add custom Stage Monitor event types.

In the Editor's main menu, choose File > Open Visual Studio. If you don't see this option, select New C++ Class...

In Visual Studio's Solution Explorer find the module, defined in a .Build.cs file, where you want to emit stage events. Append StageDataCore to the PublicDependencyModuleNames range:

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "StageDataCore" });

In a C++ header file, define your stage event data structure and inherit from either FStageProviderEventMessage or FStageProviderPeriodicMessage . In the following header file MyStageEvents.h, FMyStageEvent is inheriting from FStageProviderEventMessage and expects the data to be int32:

In your code, whenever you want to emit an event, call IStageDataProvider::SendMessage<>() with your event as the template parameter. For example, emit the event created above with the following::

Since UE sends messages using UDP, a message could be lost or dropped and never received. Using the flag EStageMessageFlags::Reliable ensures that the Stage Monitor will receive the message.

If you are sending a periodic message, you can use EStageMessageFlags::None instead of the Reliable flag.

Stage Monitor Settings

You can find settings for Stage Monitor either directly within the tool, or under your project's Project Settings.

To access Stage Monitor settings from the Unreal Editor, go to Edit > Project Settings and Search Stage.





To access Stage Monitor settings from within the tool, start by launching the Stage Monitor by going to Window > Virtual Production > Stage Monitor.



Once in the tool click the cogs button.



Below is a review of the most important settings and their purposes.

General Settings



Setting Name

Description

Use Session ID

You can use a sessionId to differentiate between two stages operating on the same network. You can then pass that sessionId using the command line to each instance using -StageSessionId=.

Timeout Interval

Time required for a provider to consider a monitor to be disconnected as well as the time for a monitor to consider a provider to be disconnected.

Monitor Settings



Setting Name

Description

Supported Roles

Used to filter monitoring logic to only be used when an instance has a specific role. Useful when you auto start monitoring but don't want it to be used on render nodes for example.

Auto Start

By default, monitoring logic doesn't start automatically. You can start it in the monitor panel but if you want it to be started when an instance is launched, you can check that setting. If you are not using role filtering, this means that any instance will be monitoring, which can increase network traffic a lot in case of multiple instances being used.

Provider Settings



Setting Name

Description

Supported Roles

Only enable data provider logic when an instance has a role from that list.

Message Type Role Exclusion

By default, any data provider will emit any event that is triggered. This can clutter monitoring logs a lot especially when hitch detection is enabled. For example, when using the editor, for sure some hitches will be triggered when the user goes in menus. To filter that, you can use this setting to assign specific roles for a given event type to filter which kind of instance can trigger that event.

Update Interval

UE periodically sends this message from all data providers. It includes information about frame timing and is used as a heartbeat. It can give you a quick idea in the monitor panel about all your providers and how they are going. That setting controls the rate at which UE sends these messages.

Enable Hitch Detection

Enable basic hitch detection logic. This will use the stat thread so messages will be drawn on the viewport, including render nodes. To avoid that, you need to launch with -ExecCmds="DisableAllScreenMessages".

Minimum Frame Rate

When rendering or game thread takes more than that frame rate interval, a hitch event will be triggered.

Export Settings



Setting Name

Description

Keep Only Last Period Message

When exporting to JSON, only export the last message for all period types of events. This is used to reduce file size.

Exclude Message Types

Add the message type you want to exclude when exporting to JSON.

Live Link

Professional Video I/O

Getting Started with Timed Data Monitor

Timecode and Genlock

Sources and Channels

Buffer Visualizer

Calibration

Calibration Example

Timed Data Monitor State

Plugin Settings Reference

Calibration

UI

Unreal Engine can ingest a variety of data types from multiple sources at the same time. For example, in Virtual Production, the engine can receive captured frames from the camera on SDI as well as the position and orientation of the camera from the tracking system through Live Link. The Timed Data Monitor is a solution to configure and visualize how all this incoming timed data relates to each other and the engine's time.

The Timed Data Monitor currently supports sources from:

Live Link

SDI

You can extend the functionality of Timed Data Monitor to include other timed data sources through code. Use the TimedDataSource framework to register your custom data source with Timed Data Monitor.

The sections below cover how to use the Timed Data Monitor and the settings you can modify for your project.

Getting Started with Timed Data Monitor

Follow these steps to use the Timed Data Monitor with your project.

In the Editor's main menu, choose Edit > Plugins to open the Plugins window.

In the Plugins window, find the Timed Data Monitor plugin in the Virtual Production section.



Check the Enabled box.

In the popup, choose Yes.



Restart the Editor when prompted.



In the Editor's main menu, choose Window > Developer Tools > Timed Data Monitor to open the Timed Data Monitor window.



Timecode and Genlock

At the top of the Timed Data Monitor, you can view the CustomTimestep and TimecodeProvider used in the project. Without needing to switch to another window, you can also configure an offset for the TimecodeProvider.



For SDI inputs, these settings are changing the settings of the opened stream. It's not changing the actual MediaSource asset that was used when opening the input. If you find a good set of options, consider changing the associated asset.

Sources and Channels



Once the Timed Data Monitor plugin is enabled in Unreal Engine, any Live Link, SDI, or custom sources using the TimedDataSource framework in the project will automatically appear in the tool. Each source can contain multiple channels that are viewable by clicking the arrow in front of the source name. The table below describes the information represented in the UI for each source.

Column

Description

Enable / Disable Toggle

When enabled, the channel will be included during calibration and will affect the global status reported in the monitor.

Source Name

To the left of the source's name are the following UI items:

An arrow that expands the channel list for the source.

An icon of the source type. Currently, source types can be Live Link or SDI.

A colored circle representing the connection status of the source:

Green: Input is connected.

Yellow: Input is connected but no data is available.

Red: Input is not connected.

Last Sample Time

Timecode of the latest sample.

Eval.

Specifies how the input is evaluated. Evaluation types include:

Timecode: Uses timecode when evaluating the source.

Platform Time: Uses the engine's time when evaluating the source.

None: No special synchronization. Uses the latest sample time.

Time Correction

You can make additional fine adjustments to the time of a specific source. This is useful when the calibration process finds an alignment point for the sources, but they might not have been striped at the same time.

Buffer Size

Configures the size of the buffer for this source. When there is too much offset between two sources, this can be used to let one source buffer more data to get the alignment

B.U.

Number of buffer underflows detected.

B.O.

Number of buffer overflows detected.

F.D.

Number of frame drops detected.

Timing Diagram

The vertical line represents the evaluation time. The line is green when inside the buffer, and red when it's outside available samples.

Buffer Visualizer

The Buffer Visualizer is a separate window to show a visualization of all the channels together. This is a larger, more comprehensive view of what's shown for each channel in the Timing Diagram column.



The buffers are represented with the following UI elements:

Vertical Line: Represents the evaluation time. The line is green when inside the buffer, and red when it's outside the available samples.

Light gray rectangle: Represents the current timed samples available in the channel.

Dark gray rectangle: Represents the average of the timed samples available in the channel.

White rectangle: Represents the standard deviation of the oldest timed sample and newest timed sample available.

The bigger the white rectangle is, the more variation or jitter in the sample's buffer. When you see this larger variation, you will probably need to allow more buffer between the evaluation time and the newest sample available to be sure you are always able to evaluate a sample at the desired time.

To open the Buffer Visualizer in the Timed Data Monitor:

Select the Open a buffer visualizer button at the top of the Timed Data Monitor window.



Calibration





The Timed Data Monitor includes functionality to calibrate all the enabled sources to find an alignment point. Calibration can be initiated from the Timed Data Monitor UI or through Blueprints.

During calibration, the Timed Data Monitor will modify the global offset of the TimecodeProvider and buffer sizes of the sources so that all channels have samples in the range of the evaluation time. By default, the standard deviation of time differences will be used to find a spot with more statistical assurance that it will always be aligned. The algorithm can be modified from the project settings.

Calibration Example

In the video, there are multiple LiveLink sources connected but not aligned. In the viewport, the actors are out of sync. In the Buffer Visualization window, you can see the misalignment: some sources have their samples too early; some contain the evaluation time; and some that are too late. One source LLTS.5 has a smaller buffer amount than the others.

When the calibration process starts, the algorithm:

Grows the LLTS.5 buffer size to be able to align it with the other samples.

Modifies the global offset on the TimecodeProvider to get all sources aligned. The offset selected is the smallest required to align LLTS.0 with the other samples since it was the furthest from the evaluation point.

Once calibration finishes, the buffers are all in the range of the evaluation time and all the actors are now in sync.

Timed Data Monitor State

In the top right corner of the Timed Data Monitor is a visualization of the global state of the incoming data and how it relates to the engine's time. The possible states include:

State

Description

Disabled

Either no inputs are present or all inputs are disabled.

Synchronized

All enabled inputs have a sample matching the evaluation time.

Outside Range

One or more input doesn't have a sample matching the evaluation time.

No Samples

Inputs currently have no samples available.

The example below shows how the sources can affect the global state of the monitor. In the example, there are two Live Link sources:

The Time Correction for the first source is set to -0.1. This puts the source out of sync with the engine's time, as represented by the red vertical line in the Timing Diagram.

The Time Correction for the second source is set to 0.1. This puts the source in sync with the engine's time, as represented by the green vertical line in the Timing Diagram.

When both sources are enabled, the global state is set to Outside Range, because the first source is out of sync with the engine's time. Disabling the first source switches the state to Synchronized, since only the second source was in sync with the engine's time.





Plugin Settings Reference

In the Plugin settings, there are many ways to customize the calibration process and the functionality of Timed Data Monitor in general. The table below describes all the settings and how they impact functionality in the tool.



Calibration

Parameter

Description



Calibration Settings



Number of Retries

Specifies how many times the calibration algorithm will be run to try to find an alignment for all inputs.

Buffer Resize Allowed

When enabled, the calibration algorithm can increase the buffer size of one or more inputs.

Buffer Shrink Allowed

When enabled, the calibration algorithm can shrink the buffer size of one or more inputs.

Failed if Buffer Cant be Resize

When enabled, if a buffer could not be resized, then the calibration process would fail. A buffer can fail to resize if it would become too big, for example.

Use Standard Deviation

Use the standard deviation stat when considering if an input has a sample in the range of the evaluation time.

Number of Standard Deviation

Specifies how many standard deviations should be considered to consider a sample in range.

Reset Statistics Before Using Standard Deviation

Allow resetting stats before doing the calibration.

Amount Of Seconds to Wait After Statistic Reset

Time to wait to let statistics settle in after a reset.



Time Correction Settings



Buffer Resize Allowed

Time Correction algorithm can change the buffer size of one or more inputs if it finds that it's too big.

Buffer Shrink Allowed

Time correction algorithm can shrink buffer size of one or more inputs if it finds that it's too big.

Failed If Buffer Cant be Resize

If a buffer could not be resized (would be too big for example), fail the time correction process.

Number of Standard Deviation

Specifies how many standard deviations there should be.

UI

Parameter

Description

Refresh Rate

Interval at which the UI is refreshed.



Reset



Reset Buffer Stat Enabled

When clicking the Reset button in the UI, reset buffer statistics by default.

Clear Message Enabled

When clicking the Reset button in the UI, clear logged messages by default.

Reset Evaluation Time Enabled

When clicking the Reset button in the UI, reset time correction of each input by default.

Quick Start

Converting Colors in the Viewport

Converting Colors in Blueprints

Converting Colors in nDisplay

Converting Colors in Movie Render Queue

Converting Colors in Composure

Unreal Engine 5.1 supports OCIO v2.1. For more information about the features included in OCIO v2, refer to the OCIO documentation.

OpenColorIO (OCIO) is a color management system used primarily in film and virtual production. OCIO guarantees the colors of captured video remain consistent through the entire film pipeline. This pipeline includes initial camera capture, all the compositing applications that need to work with the captured media, and the final render.

Unreal Engine (UE) offers support for using OCIO to convert the colors of linear media in several ways:

When you use media sources like captured clips or live feeds in your project, you can apply color conversion to make those media sources match your computer-generated elements in UE.

You can use OCIO to apply color conversions to your Viewport and Play in Editor (PIE) windows. This means your reference frames in the editor will be consistent with your chosen color space.

You can re-apply another color conversion to the composited feed you output from Composure. This helps make your CG elements and live frames blend more convincingly, while preserving the colors of the original shots faithfully.

You can use Displays and Views to apply color conversions to multiple physical or virtual display devices from the same OCIO configuration.

You can apply color space transformations to nDisplay renders on monitors and LED walls.

When you export a video through Movie Render Queue, you can apply a color space transformation to your output video or image sequence.

All OCIO features in the engine rely on an OpenColorIO Configuration Asset, which you use to manage the color profiles that you want to work with.

The OpenColorIO Configuration Asset references an OCIO configuration (.ocio) file, which contains detailed specifications about multiple color profiles and how to transform between them. UE currently supports OCIO v2. For more details on OCIO configuration files, refer to the OpenColorIO v2 documentation.

This page contains links to documentation about creating an OpenColorIO Configuration Asset and applying color transformations in the engine.

Quick Start

This page guides you through creating an OpenColorIO Configuration Asset.



Create OpenColorIO Configuration Assets from OpenColorIO configuration files.

Converting Colors in the Viewport

The Editor supports applying OCIO color conversions to the Level Viewport through Viewport View Modes and to Play in Editor mode through Blueprints. This page shows how to apply color transformations to the Level Viewport and Play in Editor mode.



Apply color conversion to the Level Viewport and Play in Editor with OpenColorIO in Unreal Engine

Converting Colors in Blueprints

This page describes how to use Blueprints to apply color transformations.



Apply color transformation using Blueprints with OpenColorIO in Unreal Engine

Converting Colors in nDisplay

nDisplay supports applying OCIO color conversions to nDisplay renders for the entire cluster, the inner frustum, or individual cluster nodes. This can be useful for managing the color spaces of specific displays. This page explains how to use OCIO with nDisplay.



Using nDisplay color management tools.

Converting Colors in Movie Render Queue

Movie Render Queue supports applying OCIO color conversions to media exports. This page shows how to set the color conversion in Movie Render Queue.



Adjust the picture quality of your render with Movie Render Queue's Image Settings

Converting Colors in Composure

Composure supports applying OCIO color conversions to input and output media. This page explains how to apply color transformations in Composure.

Prerequisites

Using the Apply Color Space Transform Function

You can apply OpenColorIO (OCIO) color transformations with Blueprints on any input texture, including a MediaTexture that plays back a video source, and get the converted results in a RenderTarget. This page shows how to use the Apply Color Space Transform Blueprint function in your project.

Prerequisites

You must set up the following in your project to complete the sections below:

An OpenColorIO Configuration Asset. Refer to the OpenColorIO Quick Start for steps on creating this Asset.

A Blueprint Class, created from a Blueprint Actor that has an Event Tick.

Using the Apply Color Space Transform Function

Follow these steps to apply color conversions with Blueprints. These steps use the EditorUtilityActor Blueprint Class as an example.

Double-click your Blueprint Class to open it in the Blueprint Editor.

In the My Blueprint panel, under Variables > Components, click Add (+) Variable to create a new variable. Name the new variable InputTexture.



Next to the new InputTexture variable, click Make Public to make it visible outside this Blueprint.



Set the Variable Type for the variable InputTexture to Object Types > Texture > Object Reference.



Create two more variables and make them public:

OutputTexture with the Variable Type Texture Render Target 2D > Object Reference

ColorConversionSettings with the Variable Type Open Color IOColor Conversion Settings.



Drag the InputTexture variable into the Event Graph, and choose Get InputTexture. This creates a new InputTexture node in the Event Graph.



Repeat the process for the OutputTexture and ColorConversionSettings variables.



Right-click within the Event Graph, and add a new Apply Color Space Transform node.



Connect the nodes together:

Connect the output execution pin from the pre-supplied Event Tick node to the input execution pin of the Apply Color Space Transform node.

Connect the output data pin of the InputTexture node to the Input Texture input data pin on the Apply Color Space Transform node.

Connect the output data pin of the Output Texture node to the Output Render Target input data pin on the Apply Color Space Transform node.

Connect the output data pin of the Color Conversion Settings node to the Conversion Settings input data pin of the Apply Color Space Transform node.



Compile and Save the Blueprint. Close the Blueprint Editor.

Drag your Blueprint Asset into the level to create its Actor.

In the Outliner, select your Blueprint Actor to open its Details panel.

In the Details panel, expand the Default section, and set Input Texture to your desired input file.

Create a Render Target Asset in the Content Browser, and set Output Texture to point to the new Render Target Asset.



In the Details panel of the Blueprint Actor, expand the Color Conversion Settings section. Set Configuration Source to your OpenColorIO Configuration Asset, and adjust the Source Color Space and Destination Color Space to match the color space of the input and output media.

Drag your Render Target Asset onto an Actor in the Level to preview your media with the color transformation. You can continue to adjust the Source Color Space and Destination Color Space settings to preview different outputs.

Prerequisites

Convert the Level Viewport's Colors

Convert Colors in the In-Game Viewport

You can apply OCIO configurations directly within the Viewport by adjusting the Viewport View Modes and you can apply OCIO configurations to Play in Editor Mode by creating and configuring a Create In-Game OpenColorIO Display Extension Blueprint node.

This page shows you how to apply your OpenColorIO Configuration Asset to the Viewport and to your project in Play in Editor mode.

Prerequisites

You must set up the following in your project to complete the sections below:

An OpenColorIO Configuration Asset. Refer to the OpenColorIO Quick Start for steps on creating this Asset.

Convert the Level Viewport's Colors

Follow these steps to apply color conversion to the Level Viewport.

In the Viewport, click the View Mode button to open its dropdown menu. Choose OCIO Display to open the Display Configuration settings.

In the Display Configuration settings, choose Select an OCIO Asset and select your OCIO Configuration Asset to add it to the Viewport view settings.

The following two settings are the source and destination of the color transform. In this example, the source is Utility - Linear - sRGB, and the destination is Output - sRGB Monitor.

Click Enable Display to apply the OCIO color transformation to the Viewport.

When you enable these settings, the Viewport disables Tone Curve and inserts color conversion into the post processing stage of rendering. It does this right after UE applies the Tone Map but before everything else.

The following image shows how the viewport's color is changed by the OpenColorIO configuration.





OpenColorIO disabled / enabled in Viewport View Modes.

Convert Colors in the In-Game Viewport

To convert colors in the in-game viewport, you must add a Create In-Game OpenColorIO Display Extension Blueprint Node to your Camera Actor's Blueprint class, and associate your OCIO configuration with it.

Steps

Open your Camera Actors's Blueprint Class or create a new Camera Component Blueprint Class if you do not already have one and attach it to your Camera.

Create a new OpenColor IODIsplay Configuration variable by clicking and dragging from the In Display Configuration pin, or by creating a new variable in the My Blueprint tab.

Edit this variable in the Details panel by adding your OCIO Configuration Asset and adjusting the other settings to match your desired color configuration.

Create a new Create In-Game OpenColorIO Display Extension node and attach it to the EventBeginPlay node and your OCIO configuration variable as shown in the screenshot below.

Compile and Save your Blueprint.

From the Level Editor Viewport, click Play to open your project in Play in Editor mode to test your Blueprint.

Prerequisites

Importing OCIO Config Files

Create an OCIO Configuration Asset

Configure the OpenColorIO Configuration Asset

This page guides you through getting started with OpenColorIO in Unreal Engine (UE). It shows how to create an OpenColor Configuration Asset from your OCIO configuration file, and apply color transformations in Unreal Editor's Viewport.

Prerequisites

You must enable the OpenColorIO plugin to use OpenColorIO (OCIO) in UE. Refer to Working with Plugins for how to enable plugins in UE.

The OpenColorIO plugin is automatically enabled by UE when you create a new project.

Importing OCIO Config Files

You can import your OCIO configuration (.ocio) file into your project's Content folder shown in the Content Browser.

UE may display a warning when copying your config file directly into the Content folder. One such warning is that it does not recognize the .ocio file extension. If this happens, copy your OCIO config file into your project's Content folder using your computer's file explorer.

Example OCIO Config File

If you don't have your own .ocio configuration file, you can download and use the ACES OCIO config files from GitHub, or you can use the example .ocio config file simple.config.ocio and lookup tables (LUTs) included with the OpenColorIO plugin. This example config file is located in your engine install folder under Engine\Plugins\Compositing\OpenColorIO\Content\OCIO.

Browsing to the OpenColorIO plugin's contents in the Content Browser does not show these files since the Content Browser only shows .uasset files. Use your computer's file explorer to browse to the files.

Create an OCIO Configuration Asset

Follow these steps to create an OCIO Configuration Asset from your OCIO configuration file. This example uses the simple.config.ocio configuration file included in the OpenColorIO plugin.

In the Content Browser, right-click to open the context menu and select Miscellaneous > OpenColorIO Configuration to create an OCIO Configuration Asset. Rename the Asset.

Double-click your OCIO Configuration Asset to edit its settings. In this example, the Asset is named OCIO_Example.

For the Configuration File parameter, click Browse to locate and select an OCIO configuration (.ocio) file on your computer.

For the Desired Color Spaces parameter, click Add (+) to add a new color space entry.

In the new entry, open the drop-down list and select one of the color spaces defined in the config file that you want to use in UE.

Repeat the last two steps for each color profile you want to use, then Save your Asset. Only set up the color profiles you actually need to use in UE. This helps your configuration Asset remain as lightweight as possible.

Your OpenColorIO Configuration Asset is now set up so you can use it to apply color transformations to different systems in the engine.

Configure the OpenColorIO Configuration Asset

While the method to set up color conversions for systems in UE may be different, the color conversion settings with OpenColorIO are the same. You'll need to specify which OpenColorIO Configuration Asset to use, and the source and destination color spaces:

Configuration Source: The OpenColorIO Configuration Asset you're using.

Source Color Space: The input color space you want to convert from.

Destination Color Space: The output color space you want to convert to.

Destination Display View: The display view that you want to convert colors in

Add Color Correction Regions to your scene

Adjust Color Correction Region settings

Per Actor Color Correction

With Color Correction Regions, you can adjust and correct the colors of the environment and objects in your scene. For example, in an in-camera VFX scenario, you can match the lighting and shadows between the real-world set and the environment displayed on the LED walls.



At the end of this page, you will be familiar with adding Color Correction Regions to your level and modifying their settings.

There are two types of Color Correction Actors in Unreal Engine:

Color Correction Regions (CCR): Use CCR to apply color correction to any Actors inside a shaped volume (Sphere, Box, Cylinder, or Cone).

Color Correction Windows (CCW): Use CCW to apply color correction to any Actors behind a flat plane, relative to the position of your camera.

Add Color Correction Regions to your scene

To add a Color Correction Region (Either CCR or CCW) to your scene, follow these steps:

In the Editor's main menu, choose Edit > Plugins to open the Plugins window

In the Plugins window, find Color Correction Regions in the Other section. Check the Enabled checkbox to enable the plugin.

Restart the engine.

In the Editor's main menu, choose Edit > Project Settings to open the Project Settings window.

In the Project Settings window, go to Engine > Rendering, and change the Custom Depth Stencil Path to Enabled With Stencil.

Custom Depth Stencil Path must be set to Enabled With Stencil to use Color Correct Regions.

In the Place Actors panel, select the Volumes category.

Drag the Color Correction Region Asset or Color Correction Window Asset into the level.

After you place your CCR or CCW volume in your level, you can modify the following settings in the Details panel to apply color grading to your level.

Adjust Color Correction Region settings

CCR and CCW mostly use the same settings, however the Type and Priority settings are different for each type of Color Correction Region.

Property

Description

Type

Determines the shape of the region. CCR options:



Sphere

Box

Cylinder

Cone





Square

Circle





Priority

CCR: When multiple Color Correction Regions overlap, the priority of the regions determines what order the color grading of the regions are applied to the level. CCW: The Priority property does not appear in the Details panel for CCW. The priority of CCWs is based on the distance of the CCW from the camera. Regions closer to the camera have a higher priority and are applied first.

Intensity

Use this setting to control the strength of other Color Grading settings.

Inner and Outer

Use this setting to control the Region's falloff area.

Falloff

Use this setting with Inner and Outer to control the strength and area of falloff.

Invert

If checked, color grading is applied to everything in the level except for the area of this Color Correction Region.

Temperature Type

Select the type of color temperature control for this region. White Balance: White Balance is the conventional color temperature control method. Color Temperature: Color Temperature is the reverse of white balance Temperature (Legacy): Temperature (Legacy) uses an older algorithm to modify color temperature. This algorithm can be faster than White Balance or Color Temperature, but the end results may not be comparable to conventional color correction algorithms.

Temperature

Use this setting to adjust the applied color temperature in kelvins.

Tint

Use this setting to adjust the tint of the color correction. Lower values adjust the color towards pink, higher values adjust the color towards green

Color Grading Settings

Color grading settings such as Gamma, Highlights, Midtones, and Shadow.

Enabled

If unchecked, this region will not be visible in your scene and it will not apply any color corrections.

Per Actor Color Correction



You can use Per Actor Color Correction to selectively apply color correction to Actors in your scene.

There are two Per Actor CC modes:

Exclude Selected Actors: Use this setting to exclude selected Actors from this Color Correction Region. The region does not apply color correction to the selected Actors.

Affect Only Selected Actors: Use this setting to only include the selected Actors. This region only applies color correction to the selected Actors.

To enable Per Actor Color Correction, select your Color Correction Volume, go to the Details panel, and check the Enable Per Actor CC checkbox.



After enabling Per Actor CC, you can select Actors to include or exclude from this Color Correction Region by adding them to the Actor Selection.

Click the + icon to add an element to the Actor Selection.

Select your Actor from the dropdown menu, or use the eyedropper tool to select an Actor from your viewport.

Default Save Location

Standard Screenshot

High Resolution Screenshot

Parameters

High Resolution Screenshot Tool

Accessing the High Resolution Screenshot Tool

Using the High Resolution Screenshot Tool

Buffer Visualizations

OpenEXR Image Support

Custom Depth Mask

Unreal Engine 5 (UE5) offers a multitude of different ways of taking in-game screenshots of your project. This document describes which tools are available for taking screenshots in UE5 and how you can use them.

Default Save Location

By default any screenshots will be saved to the following location in your project folder.

Saved\Screenshots\Windows

When you do take a screenshot, the following message will be displayed in the lower right-hand corner of the screen.



Clicking on the message will display the folder containing your screenshots.

Standard Screenshot

The standard screenshot feature is available via the console command Shot (default key binding is F9). It can generate screenshots at the size of the screen resolution (or window resolution if the game is running in windowed mode).

High Resolution Screenshot

The high resolution screenshot console command is a great cross-platform tool for taking very high resolution screenshots. It is capable of generating screenshots of any size that are based off of the screen resolution (or window resolution if the game is running in window mode). The high resolution screenshot console command does this by rendering the game frame multiple times, one tile at a time at full resolution, and concatenating all tiles into a single image file.

The default behavior is to take a screenshot with a resolution 4 times greater than the game resolution and create an image file in the Screenshot folder.

When running the game through the editor (PIE) or as standalone, open the command console by hitting ~ (tilde) and type:

Parameters

The HighResShot console command takes a number of optional parameters that can control how the screenshot is taken:

Parameter

Description

XxY

Specifies the size of the image (width x height).

Multiplier

Multiplies the size of the screenshot by a value.

CaptureX CaptureY CaptureW CaptureH

Uses integers to define a region of the viewport to use for the screenshot.

bMaskUsingCustomDepth

Uses a boolean value (0 or 1) to toggle using the Custom Depth buffer as a mask for the capture. See Custom Depth Mask

bDumpBufferVisualizationTargets

Uses a boolean value (0 or 1) to toggle capturing each pass in the G Buffer as an image that gets exported.

bCaptureHDR

Uses a boolean value (0 or 1) to toggle the use of the .EXR file format to capture an HDR image.

bDateTimeAsFilename

Uses a boolean value (0 or 1) to toggle the use of a timestamp in the generated filename.

Typing the following will take a screenshot that is twice as big as the screen resolution:

Similarly, the command below will take a screenshot at 3840 wide by 2160 high:

High Resolution Screenshot Tool



With the High Resolution Screenshot Tool (HRSST) you can specify a specific region of your viewport to use when you take a screenshot. You can also adjust the size of the screenshot and output the results of the GBuffer.

Accessing the High Resolution Screenshot Tool

You can access the HRSST by first clicking on the Viewport Options and then selecting the High Resolution Screenshot option.



Once you have selected the High Resolution Screenshot, the HRSST will be displayed on screen.



You can move the HRSST anywhere inside of UE5. However, be aware of its position as sometime the HRSST can become hidden by other floating windows like the Content Browser.

Number

Description

1

A multiplier that sets the size of the screenshot.

2

Includes the Date and Timestamp in the image name.

3

Tells the tool to include each pass in the GBuffer as an image that gets exported.

4

Writes all exported images into .EXR format and enables full 16 bit color depth (HDR) export of all of available intermediate rendering stages.

5

Forces full 128bpp rendering.

6

Captures certain objects in the scene. See Custom Depth Mask

7

Specifies a region within the viewport that you wish to capture. You define a region by first clicking on the tool and selecting a region to capture. Do this by holding down the Left Mouse Button and dragging in the Editor viewport.

8

Clears any previous capture regions that you might have created. This button will only be visible when you have a region selected.

9

Expands the capture region to the entire editor window. This button will only be visible when you have a region selected.

10

Click this to take the screenshot.

Due to the high system requirements of a high resolution screenshot, very large multipliers might cause the graphics driver to become unresponsive and possibly crash. In these circumstances, please try using a lower number.

Using the High Resolution Screenshot Tool

To take a high resoloution screenshot:

Enable the HRSST. To do this, click on the Viewport Options, then select the High Resolution Screenshot option.

Once the tool has been enabled, press the Specify Region button to select a region of the editor viewport that you want to capture.

Adjust the Screenshot Size Multiplier to set the final size of the image file, then press the Camera icon to take the screenshot. Screenshots will be saved to Saved\Screenshots\Windows folder.

Buffer Visualizations

The HRSST can render each of the following buffers in the G-Buffer:

BaseColor

LightingModel

Metallic

Opacity

PostTonerMapHDRColor

PreTonerMapHDRColor

Roughness

SceneColor

SceneDepth

SceneDepthWorldUnits

SeparateTranslucencyA

SeparateTranslucencyRGB

Specular

SubsurfaceColor

WorldNormal

To enable the HRSST to export out the G-Buffer as images, first enable Include Buffer Visualization Targets, then press the capture button. The capture folder will now contain a screenshot for each of the G-Buffers listed above.

OpenEXR Image Support

The HRSST supports exporting images in the OpenEXR image format. This enables full 16 bit color depth (HDR) export of all available intermediate rendering stages. After you click the capture button, the HRSST writes out the following buffers to the OpenEXR image format.

BaseColor

LightingModel

Metallic

Opacity

PostTonerMapHDRColor

PreTonerMapHDRColor

Roughness

SceneColor

SceneDepth

SceneDepthWorldUnits

SeparateTranslucencyA

SeparateTranslucencyRGB

Specular

SubsurfaceColor

WorldNormal

To use OpenEXR image support, enable Write HDR format visualization targets, then press the capture button. The capture folder will now contain a screenshot for each of the G-Buffers listed above.

Custom Depth Mask

During the course of development, you might need the ability to capture certain objects in the game world for promotional material. However, having to manually cut out objects from the background can be both time consuming and frustrating. To help speed this process up the HRSST has an option called Use custom depth as mask, which can separate objects in the world from one another. Setting up and using this part of the tool is done by following these steps:

Select the objects that you want to capture. Then, in the Details panel, enable the Render CustomDepth Pass option.

Open the HRSST and select the region you want to capture. Make sure that the region you are trying to capture includes the meshes that have Render CustomDepth Pass enabled.

Enable the Use custom depth as mask option.

Take the screenshot by pressing the capture button.

View the screenshot by clicking on message that is displayed in the lower right hand corner of the screen.

Starting Out

Reference



The Panoramic Capture plugin for Unreal Engine lets you capture still images or movies that can then be viewed or played back in stereo, giving the illusion that the world is being rendered in real time. In the following sections, we will take a look at how to set up and use the Panoramic Capture plugin and also take a look at how you can view the stereo images you create.

Starting Out



A look at how to use the Panoramic Capture plugin to capture VR images.



Taking a look at how to fix some common issues with the Panoramic Capture tool.

Reference



Descriptions of the various properties available for use with Panoramic Capture.

1 - Project Setup

2 - Taking Stereo Images



In the following example, you will take a look at how you can set up, create, and view stereo panoramic screenshots—all from inside UE4. When you have completed this project, you will have created a panoramic image.

1 - Project Setup

In this section, we will create and then set up a new UE5 project.

Steps

Create a new Project from the Games > First Person template, with the following settings:

Blueprint

Target Platform Desktop

Quality Preset Maximum

Starter Content enabled



Click image to expand.

Press the Create button to load the new project.

This could be any project. The above values are listed simply to provide a starting point for creating a project.

With your project open, select Edit > Plugins from the main menu.



From the Plugins menu, under Movie Capture, enable the Panoramic Capture plugin. Restart the editor when prompted.



Click image to expand.

2 - Taking Stereo Images

In this step, you will use the Panoramic Capture plugin and the BP_Capture Blueprint to capture the images of the level in Stereo 3D.

Steps

Open the Content Drawer, and browse to PanoramicCapture Content > Assets.

By default, the Content Drawer does not show plugin content. To change this, select Settings, then enable Show Engine Content and Show Plugin Content.

Drag the BP_Capture Blueprint onto the scene.

Click Play to kick off the BP_Capture and start the capture process.



Click image to expand.

During the capture process, the editor might appear to be frozen or unresponsive for a few seconds up to a few minutes. This is due to the demanding rendering requirements of the Panoramic Capture plugin. When the editor becomes responsive again, you will be able to find the screenshots in the following location.

C:\PanoramicCaptureFrames\[Date & Time]\FinalColor\Frame_00000_FinalColor.png



Click image to expand.

Here is a view of the stereo image generated by BP_Capture.



Click image to expand.

The default output of the BP_Capture Blueprint is 8-bit (.png), with 32-bit (.exr) as an optional setting in the Blueprint.

Scalability Reference

Camera

Scalability Reference

Camera

Message Log

Plugin Content

BP_Capture

Render Passes

Slice Controls

Atlas Controls

Sampling Controls

Debug Controls

Output

Monoscopic

Message Log

All log information is now shown under the Panoramic Capture Log in the Message Log. If an error occurs, the Message Log will open automatically.



Plugin Content



Assets: Contains one Blueprint that sets all of the parameters for a quality 6k capture.

Materials: Contains the post processes used to capture the different render passes.

Viewer: Contains Blueprints to view stereoscopic stills and videos.

The Content Drawer does not show plugin content by default. Select Settings, then enable Show Engine Content and Show Plugin Content to show plugin content.

BP_Capture

Under PanoramicCapture Content > Assets, you will find BP_Capture. This Blueprint sets up all of the necessary parameters for a quality 6k capture. If you use the Blueprint in its default configuration, it will output one frame of stereoscopic output.



The output path is configurable, but defaults to C:\PanoramicCaptureFrames. Below is an example of the output directory when you output all passes.



In the following sections, you will find a detailed description of options and controls available for the Panoramic Capture plugin and what those options do to the image that is output. The options have been broken up into groups based on what those options do. To input a command, press the backtick or tilde key (`) to open up the UE5 console and then type SP. followed by the command you want to enter.

If you want to know more about any of the settings below, check out the StereoPanoramaManager.cpp file for more information.

Render Passes

Ambient Occlusion

Base Color

Metallic

Roughness

Scene Depth (always 32bit)

World Normals

Slice Controls

The Slice Control options are for controlling how many horizontal or vertical slices are taken for each image.

Property

Default Value

Description

SP.HorizontalAngularIncrement

1.0f

The number of degrees per horizontal step. Must be a factor of 360.

SP.VerticalAngularIncrement

90.0f

The number of degrees per vertical step. Must be a factor of 180.

SP.CaptureHorizontalFOV

90.0f

Horizontal FOV for scene capture component. Must be larger than SP.HorizontalAngularIncrement.

SP.EyeSeparation

6.4f

The separation of the stereo cameras.

Atlas Controls

The Atlas Controls actually control the atlas of shots collected from the slices, which are used to reconstruct the 360-degree image.

Property

Default Value

Description

SP.StepCaptureWidth

4096

The final spherical atlas width.

SP.ForceAlpha

false

Force the alpha value to completely opaque.

Sampling Controls

The Sampling Control options affect how the image is filtered.

Property

Default Value

Description

SP.CaptureSlicePixelWidth

2048

Capture Slice Pixel Dimension.

SP.EnableBilerp

true

0 - No Filtering 1- Bilinear Filter slice samples.

SP.SuperSamplingMethod

1

0 - No Supersampling, 1 - Rotated Grid SS.

Debug Controls

The Debug Control options allow you to see and adjust how the images are captured allowing you to easily track down any issues you might run into with the final output image.

Property

Default Value

Description

SP.ConcurrentCaptures

30

The number of scene captures to capture concurrently. Raising or lowering the value of SP.ConcurrentCaptures can greatly affect capture times. If you set this value too low, you will not be capturing the optimal number of scene captures for parallel processing. If you set this value too high, you will overwhelm the GPU.

SP.GenerateDebugImages

0

0 - No Debug Images. 1 - Save out each strip as it is generated. 2 - Save each entire slice.

SP.OutputDir

This will default to your project saved folder

The location where your images will be saved.

SP.ShouldOverrideInitialYaw

true

Override Initial Camera Yaw. Set to true if you don't want to use PlayerController View-Dir.

SP.ForcedInitialYaw

90.0f

Yaw value for initial Camera view direction. Set ShouldOverrideInitialYaw to true to use this value.

SP.FadeStereoToZeroAtSides

true

Fade stereo effect between left/right eye to zero at 90 degrees.

Please note that raising or lowering the value of SP.ConcurrentCaptures can greatly affect capture times. Set this too low and you will not be using the optimal number for parallel processing. Set this too high and you will overwhelm the GPU.

Output

Use these values to control bit depth and different render passes.

Property

Default Value

Optional Value

Description

SP.OutputBitDepth

8

32

Sets the output bit depth. Panoramic Capture supports 8-bit(.png) and 32-bit (.exr) formats.

SP.OutputFinalColor

0

1

Enables the Final Color render pass.

SP.OutputBaseColor

0

1

Enables the Base Color render pass.

SP.OutputSceneDepth

0

1

Enables the Scene Depth render pass. Scene Depth is always 32-bit.

SP.OutputWorldNormal

0

1

Enables the Final Color render pass.

SP.OutputAmbientOcclusion

0

1

Enables the Ambient Occlusion render pass.

SP.OutputMetallic

0

1

Enables the Metallic render pass.

Monoscopic

This value enables you to specify whether the output should be monoscopic or stereoscopic. Stereoscopic output is the default behavior.

Property

Default Value

Optional Value

Description

SP.Monoscopic

0

1

Use this value to specify the output as monoscopic. The default output is stereoscopic.

Slow Capture Process

Image Distortion

Not all Effects Work

In the following section, we will go over some of the most common errors and issues that you might run into when using the Panoramic Capture plugin, and how to go about solving or getting around them.

Slow Capture Process

The default capture of a stereoscopic image is 6K, which takes a significant amount of resources. You can reduce the resource impact of the image capture by lowering the value specified for SP.StepCaptureWidth, thereby reducing the size of the image capture. In the BP_Capture Blueprint, simply change the SP.StepCaptureWidth value from 6144 (6K) to 1024 (1K).

Image Distortion

Due to the manner in which the stereo images are created, you will get some image distortion/pinching at the top and bottom of the image. You can see an example of what this distortion/pinching looks like in the following image.



Click for full image.

While you can not eliminate this distortion, there are a few things you can do to help minimize it. Below you will find a few tips on how to address this distortion/pinching issue.

You can add a small gradient that fades to black at the bottom and or top of the image to help hide this distortion/pinching issue like in the image below.



Click for full image.

Be careful with objects that get too close to the camera, as this will cause divergence, which makes it hard for a user to focus on the 3D image. While in some cases image divergence will not be possible to avoid, thinking about your camera placement can help lessen the effect. The following video shows how you can have different levels divergence in your images.

When the user looks up, they will have issues getting the top part of the image to be in focus due to how close the top of the hang glider was to the capture camera. However, when the user looks down, they will have no focus issues as the ground was far enough away from the camera to not cause divergence.

Not all Effects Work

Effects that are created in screen space or effects that are camera facing will not work with the Panoramic Capture tool. This means that the following types of effects should be disabled so that your images do not have any errors in them.

Light Shafts

Screen-based Distortion effects

Camera Facing Meshes or Particles

Vignette

Please note that there could be other effects not listed here that also do not capture well. If you see any similar artifacts in your images, try disabling the effect and re-capturing the image to see if the artifact goes away.

In the following image, you can see what happens when you try to capture something that makes use of screen-based effects, or is camera facing. If you take a look at the highlighted areas of the image, you will notice what appears to be a hard line in the clouds that are off in the distance. This line is there because the capture tool works by capturing your scene in a series of zoomed-in images for both the horizontal and vertical axis. Because the effects that face the camera do not know that the camera has moved and do not update their orientation to reflect this, the result is artifacts like you see in the image.



Click for full image.

Topics

Setting up a production pipeline enables developers to bring professionals with diverse skill sets into a team's production process -- and Unreal Engine provides tools and features for a variety of workflows, ensuring a steady stream of content and feature development. To learn more, read about the following topics.

Topics



Asset Loading and Unloading



Deploy Unreal Engine on cloud hosting solutions.



Unreal Turnkey simplifies platform setup by automating SDK installation and management.



Reference material for Unreal Engine's build pipeline



A recommended naming convention to help organize your Assets.



Learn the ways that you can deploy Unreal Engine either to individual users or your organization.



Text files containing property settings for configuring gameplay or engine behavior.



Overview of the Derived Data Cache and the storage of assets in formats used by Unreal and its target platforms



Get multiple users on different computers into a shared Unreal Editor session, collaborating live to build content together.



How to create Unreal Engine plugins.



Virtualize assets to improve the efficiency of source control pulls for your team.



Objects that redirect references for moved assets from t+heir old location to their new location.



Introduction to using Blueprints and Python to control the Unreal Editor programmatically.



How to setup Perforce or SVN so that you can share assets with other on your team.



Describes how to use Unreal with the Autodesk ShotGrid integration.

Assets and Content Packs

Cooking and Chunking

Primary and Secondary Assets

Blueprint Class Assets and Data Assets

Blueprint Classes

Non-Blueprint Assets

Asset Manager and Streamable Managers

Asset Bundles

Registering and Loading Primary Assets From Disk

Registering and Loading Dynamically-Created Primary Assets

Unreal Engine (UE) handles Asset loading and unloading automatically. This provides developers a method to communicate with the Engine on when each asset is going to be needed. However, there may be cases where you want precise control over when and how Assets are discovered, loaded, and audited. For these cases, the Asset Manager can help.The Asset Manager is a unique, global object that exists in the Editor and packaged games. It can be overridden and customized for any project and provides a framework for managing Assets that can divide content into chunks that make sense in the context of your project, without losing the advantages of Unreal's loose package architecture. The Asset Manager provides a set of tools to help audit disk and memory usage, giving you the information you need to optimize the organization of your Assets for Cooking and Chunking when deploying your game.

Primary and Secondary Assets

The Asset management system in Unreal breaks all Assets into two types, Primary Assets and Secondary Assets. Primary Assets can be manipulated directly by the Asset Manager from their Primary Asset ID, which is obtained by calling the function GetPrimaryAssetId. In order to designate Assets made from a specific UObject class as Primary Assets, you can override the GetPrimaryAssetId function to return a valid FPrimaryAssetId structure. Secondary Assets are not handled directly by the Asset Manager, but instead are loaded automatically by the Engine in response to being referenced or used by Primary Assets. By default, only UWorld Assets (levels) are Primary, all other Assets are Secondary. In order to make a Secondary Asset into a Primary Asset, the GetPrimaryAssetId function for its class must be overridden to return a valid FPrimaryAssetId structure. A Primary Asset ID has two parts, a unique Primary Asset Type that identifies a group of Assets, and the name of that specific Primary Asset, which defaults to the Asset's name as it appears in the Content Browser.

Blueprint Class Assets and Data Assets

The Asset Manager handles two different types of Assets: Blueprint Classes, and non-Blueprint Assets like Levels and Data Assets (Asset instances of the UDataAsset class). Each Primary Asset Type is associated with a certain base class, and specifies whether it stores blueprint classes or not in the configuration described below.

Blueprint Classes

To create a new Blueprint Primary Asset, go to the Content Browser and create a new Blueprint class that is a descendant of a class that overrides the GetPrimaryAssetId function. This base class could be Primary Data Asset or any of its children, or an Actor subclass that overrides GetPrimaryAssetId. To access Blueprint Primary Assets, call functions like GetPrimaryAssetObjectClass from C++ code, or use Blueprint Asset Manager functions that include the word "Class" in their names. Once you have the class, you can treat it like any other Blueprint class and use it to spawn new instances, or you can use the Get Defaults function to access read-only data from the Class Default Object associated with the Blueprint.

For Blueprint classes that you never need to instantiate, you can store your data in a Data-Only Blueprint that inherits from UPrimaryDataAsset. You can also derive child classes, including Blueprint-based children, from your base class. For example, you could create a base class like UMyShape that extends UPrimaryDataAsset in C++, then make a Blueprint-based subclass called BP_MyRectangle with UMyShape as its parent, and then a Blueprint-based child of BP_MyRectangle called BP_MySquare. With the default settings, the PrimaryAssetId of the last class you created would be MyShape:BP_MySquare.

Non-Blueprint Assets

You can use non-Blueprint Assets in cases where your Primary Asset Type does not need to store Blueprint data. Non-Blueprint Assets are simpler to access in code, and are more memory-efficient. To create a new non-Blueprint Primary Asset in the editor, create a new Data Asset from the advanced content browser window, or use the custom UI for creating things like new levels. Creating an Asset in this way is not the same as creating a Blueprint class; the Asset you create is an instance of a class, and not a class itself. To access the class, load them with C++ functions like GetPrimaryAssetObject, or the Blueprint functions without Class in their name. Once loaded, you can access them directly to read their data.

Because these Assets are instances rather than classes, you cannot inherit classes or other Assets from them. If you need to do this, for example, if you want to create a child Asset that inherits its parent's values except for those it explicitly overrides, you should use a Blueprint Class instead.

Asset Manager and Streamable Managers

The Asset Manager object is a singleton that manages discovery and loading of Primary Assets. The base Asset Manager class that is included in the Engine provides basic management functionality, but can be extended to suit project-specific needs. A Streamable Manager structure, contained within the Asset Manager, performs the actual work of asynchronously loading objects, as well as keeping objects in memory via the use of Streamable Handles until they are no longer needed and can be unloaded. Unlike the singleton Asset Manager, there are multiple Streamable Managers in different parts of the Engine and for different use cases.

Asset Bundles

An Asset Bundle is a named list of specific Assets associated with a Primary Asset. Asset Bundles are created by tagging the UPROPERTY section of a TSoftObjectPtr or FStringAssetReference member of a UObject with the "AssetBundles" meta tag. The value of the tag will indicate the name of the bundle where the Secondary Asset should be stored. For example, the following Static Mesh Asset, stored in the member variable called MeshPtr, will be added to the Asset Bundle called "TestBundle" when the UObject is saved:

A second way to use Asset Bundles is by registering them at runtime with the project's Asset Manager class. In this case, a programmer will need to write code that fills in an FAssetBundleData structure and then passes that structure to the Asset Manager. You can do this by either by overriding the UpdateAssetBundleData function, or calling AddDynamicAsset with the Primary Asset ID you want to associate with the Secondary Assets in the bundle.

Registering and Loading Primary Assets From Disk

Most Primary Assets are visible in the Content Browser and exist as Asset files stored on disk, so that they can be edited by artists or designers. The easiest way for a programmer to create a class that can be used in this way is to inherit from the UDataAsset child class, UPrimaryDataAsset, which has built-in functionality for loading and saving Asset Bundle data. If you want to use a different base class, such as APawn, studying UPrimaryDataAsset is useful, since it is a minimal example of the features that you need to implment to get Asset Bundles working for your class. The following class is an example of how to specify a type of zone in a hypothetical game; the zone type tells the game what art Assets to use when building the visual representation of the world in the game's overall map screen:

Because this class inherits from UPrimaryDataAsset, it has a working version of GetPrimaryAssetId that uses the Asset's short name and native class. For example, a UMyGameZoneTheme saved under the name "Forest" would have a Primary Asset ID of "MyGameZoneTheme:Forest". Whenever a UMyGameZoneTheme Asset is saved in the Editor, the AssetBundleData member of PrimaryDataAsset will be updated to include it as a Secondary Asset.

Registering and loading our Primary Assets requires the following actions:

Make the Engine aware of the project's custom Asset Manager class, if one exists. You only need to override the default Asset Manager class, UAssetManager, if your project requires special functionality. If your project does not require special functionality, you can skip this step. To override it, modify the project's DefaultEngine.ini file, and set the AssetManagerClassName variable under the [/Script/Engine.Engine] section. The final value should be in the following format: [/Script/Engine.Engine] AssetManagerClassName=/Script/Module.UClassName Where "Module" refers to your project's module name, and "UClassName" refers to the name of the UClass you want to use. In our example, the module name for the project is "MyGame", and the class we want to use is called UFortAssetManager (meaning its UClass name is FortAssetManager), so the second line would read: AssetManagerClassName=/Script/FortniteGame.FortAssetManager

Register your Primary Assets with the Asset Manager. This can be done by configuring in the Project Settings menu, or by programming your Asset Manager class to register the Primary Assets during startup.

Configuring with Project Settings (under the Game / Asset Manager section) looks like this:





Paths to scan for primary Assets can be configured.



Setting

Effect

Primary Asset Types to Scan

Lists the types of Primary Assets to discover and register, as well as where to look for them and what to do with them.

Directories to Exclude

Directories that will explicitly not be scanned for Primary Assets. This is useful for excluding test Assets.

Primary Asset Rules

Lists the specific Rules Overrides, which dictate how Assets are handled. See Cooking and Chunking for more information.

Only Cook Production Assets

Assets designated as DevelopmentCook will cause errors during the cook process if this is checked. Good for ensuring that final, shipping builds are free of test Assets.

Primary Asset ID Redirects

When the Asset Manager looks up data about a Primary Asset whose ID appears in this list, the ID will be substituted for the alternate ID provided.

Primary Asset Type Redirects

When the Asset Manager looks up data about a Primary Asset, the type name provided in this list will be used instead of its native type.

Primary Asset Name Redirects

When the Asset Manager looks up data about a Primary Asset, the Asset name provided in this list will be used instead of its native name.

If you want to register Primary Assets directly in code, override the StartInitialLoading function in your Asset Manager class and call ScanPathsForPrimaryAssets from there. In this case, we recommend that you put all Primary Assets of the same type in a single subfolder. This will make discovery and registration faster.

Load the Asset. Use the Asset Manager functions LoadPrimaryAssets, LoadPrimaryAsset, and LoadPrimaryAssetsWithType to begin loading Primary Assets at the appropriate time. Unload Assets later with UnloadPrimaryAssets, UnloadPrimaryAsset, and UnloadPrimaryAssetsWithType. When using these load functions, you can specify a list of Asset Bundles. Loading this way will cause the Asset Manager to load the Secondary Assets that those Asset Bundles reference as described above.

Registering and Loading Dynamically-Created Primary Assets

Primary Asset Bundles can also be dynamically registered and loaded at runtime. There are two Asset Manager functions that are useful to understand for doing this:

ExtractSoftObjectPaths examines all UPROPERTY members of the UScriptStruct it is given, and identifies Asset references, which are then stored in an array of Asset names. This array can be used when creating an Asset Bundle. ExtractSoftObjectPaths parameters:

Parameter

Purpose

Struct

UStruct to search for Asset references.

StructValue

A void pointer to the struct.

FoundAssetReferences

Array used to return Asset references found in the struct.

PropertiesToSkip

Array of property names to exclusive from the return array.

RecursivelyExpandBundleData will find all references to Primary Assets and recursively expands to find all of their Asset Bundle dependencies. In this case, it means that the TheaterMapTileClass referenced by the ZoneTheme above will be added to the AssetBundleData. It then registers the named dynamic Asset and starts loading it. RecursivelyExpandBundleData parameters:

Parameter

Purpose

BundleData

Bundle Data containing Asset references. These will be expanded recursively, and can be useful for loading a set of related assets.

For example, our "MyGame" project could use the following code in its custom Asset Manager class to construct and load Assets based on "theater" data that was downloaded during the game:

Unreal Engine can be deployed on cloud hosting solutions, making it possible to use hosted virtual machines when working on your projects rather than relying on your local resources. The pages in this section provide instructions on where you can set up and access cloud deployments. The list below shows the available options.



A short tutorial describing how to set up Pixel Streaming for Unreal Engine on Microsoft Azure



A short tutorial describing how to set up Unreal Engine 5 on Amazon Web Services



A short tutorial describing how to set up Unreal Engine 5 on Microsoft Azure



A short tutorial describing how to set up Unreal Engine on Google Cloud

Prerequisites

Azure Account and Subscription

Azure VM Quotas

Packaging a Pixel Streaming Application

Using the Azure Portal and the Azure Marketplace

Basics

Scale

Wrapping Up

Connecting to Your Streaming Instances

Activating the Admin Dashboard

Updating Your Application

Adding Authenticated Accounts

Reviewing Logs

Deleting the Whole Deployment

Unreal Pixel Streaming is an Azure Marketplace offering, built by Microsoft in collaboration with Epic, that allows Azure subscribers to deploy and stream their UE app from remote GPU-enabled virtual machines ("VMs"). The solution takes a single .zip file of your packaged application and spins up anywhere from one to thousands of VM instances across multiple regions, providing a way for you to set up an auto-scaling deployment accessed through a single URL. This tutorial provides a step-by-step guide to deploying your first Pixel Streaming project on Azure.

Prerequisites

Azure Account and Subscription

You need an Azure account and at least one subscription for which you have the permissions to create resources. For information on creating a new subscription, refer to this guide. Subscriptions also require that you have a billing account set up.

While the Unreal Pixel Streaming solution is available at no cost, the resulting Azure resources do have an associated cost. If your account is linked to your employer or another party, check that they are prepared to accept responsibility for the costs involved before setting up your deployment instance.

For a more accurate estimate of your cost, review the pricing information on the Virtual Machine Pricing page, filter by desired region, and search for the "NV12s v3" to see the "pay as you go" pricing.

Azure VM Quotas

Azure subscriptions have a limit for how many VM resources can be used at once, called Quotas. Follow Microsoft's documentation to make sure you have a sufficient quota for your desired VM family in each region you wish to deploy to.

The quota you need for the default configuration is Standard NVSv3 Family vCPUs, and each NV12s_v3 instance you use requires 12 vCPUs. For example, if you want 2 instances running in East US and 2 instances running in North Europe, you need to request a quota increase for 24 vCPUs for this family in both regions.

Packaging a Pixel Streaming Application

This Azure solution can only be used in conjunction with an existing Pixel Streaming application you have created. Make sure you've followed the Getting Started documentation and tested your app locally before proceeding to a cloud deployment.

By default, this solution will completely override all the web server files in your Samples folder. If you have made customizations to the webpage or servers, make sure you have downloaded the Azure modifications and merged your changes according to the included README.txt file before proceeding.

Once you have a packaged Pixel Streaming application, compress the entirety of the Windows folder in to a .zip file.



Using the Azure Portal and the Azure Marketplace

Log into your Azure account

The Unreal Pixel Streaming offer is hosted on the Azure marketplace. Navigate to the offer page here.



Sign in to the Azure Marketplace using the button at the top right. Use the same account you use for all other Azure services.



Click Get It Now below the Unreal Engine icon. You also can use the heart icon to save it to your favorites for later.



A dialog pops up asking you to confirm your information and add this app to your account. Fill it out and click Continue.



The Azure Portal will open to the Unreal Pixel Streaming product in your account. From here click on Create to begin the process of configuring your deployment.



Basics

The first tab of the creation page covers the essentials for the Pixel Streaming deployment, like subscription details, instance type, and uploading your application.

In the Basics tab, first choose the Subscription and an empty Resource Group where the global resources will be deployed to, like a Traffic Manager, Key Vault, and Admin Dashboard. You may need to use the Create new button.



Select your primary Region for the global resources. Then you may choose an instance size for both the matchmaker VMs and UE App VMs. This template defaults to the recommended sizes.



Before continuing, check that you have the proper quota for the selected GPU VM size in your subscription as mentioned above. If you don't have a sufficient quota, this deployment will fail and you may need to start over.

Next, you must upload your zipped up Pixel Streaming app. Use the Browse button to open the Storage Accounts for your selected subscription.





If you don't yet have a storage account, you can add one using the + Storage Account button at the top. Give it a Name, a Location, a new Resource Group, and click OK. After a few moments, your new storage account should be available in the list. Select a listed storage account to open it.



Any files you want to upload to an Azure storage account must go into a Container. If you do not have a container yet, you can add one using the + Container button at the top. Give it a Name and click Create. Select a container from the list to open it.



Inside the selected container, click the Upload button at the top and use the folder icon to browse for the .zip file of your application, then click Upload. Depending on project size and network bandwidth, the upload could take several minutes to finish.



Once the app is finished uploading, select the file in the container and click Select.



If you have made custom modifications to the Matchmaker or Signalling server according to the included instructions, make sure to check the box below the prompt.



Lastly, set a username and password for the VMs. These credentials are used if you enable remote desktop on the instances, which can be helpful for debugging issues.



If you're finished with the basics tab, click on Next : Scale.

Scale

This tab is where you specify the size and scope of your deployment. With Unreal Pixel Streaming on Azure, an app can automatically be set up to run on many instances in multiple regions around the world.

We recommend that you start with a smaller, simpler deployment to test your application and avoid high billing costs. Creating large numbers of virtual machines in a large number of regions will have an exponential impact on how much your subscription is charged.

In the dropdown next to Select regions to deploy, choose up to 4 regions to deploy your UE app. Users who are connecting to your web URL will be directed to their nearest region (by lowest ping), so think about where users are most likely going to be located.

Keep in mind that each region has its own VM quota that you need to manage ahead of time, as described above, or else the deployment will fail.



GPU VM Instances Per Region controls how many virtual machines get launched in the selected regions. If Auto-scaling is enabled as described below, this number will go up or down based on demand.

Streams Per GPU VM is how many instances of the UE app are running on each VM, and is limited to 4. If your application is lightweight or doesn't require a high frame rate, sharing a GPU like this can be a good way to minimize cost. In general, sharing the VM resources between multiple running apps will have a negative impact on frame rates.



There is an option called Run with Azure Spot discount. Using spot instances provides significant cost savings by leveraging unused virtual machines at the tradeoff of not guaranteeing uninterrupted service. It can be a good option for testing or cost cutting, but VMs may be "evicted" at any time based on a number of settings you can learn more about.



Enabling Auto-scaling allows this deployment to spin up more GPU instances as more users are attempting to connect to your application, and spin them down when there are too many instances running idle. If you want a constant number of available instances, you can disable this feature. Review the options below before clicking Next : Stream Configs.



Refer to the following table for information about the available scaling parameters.

Parameter

Description

Percent Buffer Required Before Scale

The percentage of streams (UE App instances) that must be available, otherwise a scale-out operation will occur to maintain this buffer. This helps prevent new users from waiting for a new VM to spin up during times of increased load. Choose 0 to ignore this policy. Default is 25%.

Instance Count Buffer Required Before Scale

The number of streams (UE App instances) that must be available, otherwise a scale-out operation will occur to maintain this buffer. This helps prevent new users from waiting for a new VM to spin up during times of increased load. Set to 0 to ignore this policy. Default is 1.

Idle Minutes Before Scale-Down

The number of minutes when a new scale-up operation hasn't occurred before evaluating scaling down to a minimum buffer count. Default is 60.

Scale Down Amount

The maximum number of nodes to scale down by, in case a scale down occurs. Default is 1.

Min Instance Count While Idle

The minimum number of streams (UE App Instances) that the solution will scale down to during an idle period (i.e., low activity periods like night time). Default is 1.

Max Node Scale Count

The maximum number of GPU VMs containing the streams (UE App instances) that will be scaled out. Default is 20. Be sure to check your quota to support this number of instances.

Wrapping Up

In the Stream Configs tab, you can adjust the resolution and frame rate of your app. This can be helpful if you're optimizing for 2 streams per GPU.



In the Security tab, there is an option to use your own custom domain name from an existing Azure DNS resource, optionally with a HTTPS connection. This is disabled by default, but this documentation can get you started. To use HTTPS, you must have an Azure DNS resource enabled and have the public and private key pair in base64 encoded format.



You can also Enable Auth on Signalling Server if HTTPS is configured, which redirects users to a login page when they first try to access the application on the browser. Once authenticated, the user is redirected to the application. If this setting is enabled, you also need to enable the Admin Dashboard in the next step to add user accounts.



In the Networking tab, there are some advanced settings you can configure. One key setting to be aware of is the STUN and TURN server configuration. The public Google STUN server used by default will be able to connect most end users to the WebRTC stream of your UE app. However, many corporate networks, VPNs, and cellular networks will not allow your app to stream properly without relaying the stream through a TURN server. Read more about these options in our Hosting and Networking Guide.



In the Admin Dashboard tab you can enable the Admin Dashboard, which provides a simple interface for seeing basic traffic analytics, granting user access (if enabled), uploading new versions of your app, and changing the auto-scale parameters.

This feature requires an App Registration in Azure Active Directory, so you'll need the proper permissions in your organization. Follow this Microsoft documentation to create an app registration in another tab, and then copy-paste the Application (client) ID.





With all the settings configured, click Review + create. If it passes validation and everything looks correct, click Create to begin the deployment. It can take several minutes to create the necessary resources, especially the GPU VMs that need to boot up and download your app. When the deployment is complete, click Go to resource group.



Connecting to Your Streaming Instances

In the primary resource group of your deployment, select the Traffic Manager profile.



At the top right of the Essentials section will be the DNS name. This URL can be copied from here and pasted into a new browser tab. This is the universal URL by which all users can access the application. They will be re-routed to their nearest region's Matchmaker VM and redirected once more to the first available stream on a GPU instance.





Activating the Admin Dashboard

If you enabled the Admin Dashboard during the configuration, there is some extra setup required to activate it after all resources are deployed.

In the primary resource group, open the App Service with the "-dashboard" name.



In the top right of the Essentials section is the URL of this resource. Copy this address.



Navigate back to the AAD App Registration you created for this dashboard. On the right column of Essentials, click Add a Redirect URI.



Click Add a platform. Click on Web from the pop-out blade.



Paste in the URL of the dashboard App Service into the Redirect URI, and append this text to the end of it: /.auth/login/aad/callback. Click Configure.



There is a section in the middle of the page called Implicit grant and hybrid flows. Check the two boxes here for issuing access tokens and ID tokens. Click Save at the bottom of the page.



After a few minutes, if you visit the original URL you pasted in, you'll be presented with the Admin Dashboard. This URL can be found at any time back in the App Service.



Updating Your Application

If the Admin Dashboard is enabled, you can follow the steps below to update the Pixel Streaming deployment with a new build of the UE app. Without the Admin Dashboard, the whole setup and configuration must be run again. The Dashboard method will leverage the existing resources and resource groups, but a new deployment will create all new resources and will not overwrite or delete existing deployments.

Follow the same prerequisite steps to zip up the WindowsNoEditor folder of your app.

Select the Storage Account in the global resource group.



In the left panel, select Containers and open the Uploads container. Then upload the zip file here.



Browse to your Admin Dashboard in the browser. Select Settings from the left hand navigation.

Click Add New Version and adjust settings as needed. Select the .zip file you uploaded to your Storage Account using Select blob. Click Add Version when you are finished.





The Matchmakers and Signalling Servers check for updates every 30 seconds and redeploy any new versions on the fly.

If you want to control exactly how many instances are running without scaling up or down, you can change the Min Idle Instance Count and Max Instance Scale Count to the same number of desired instances. You can also disable auto-scale and instead manually set the number of instances through the Scaling page of the Virtual machine scale set (VMSS) in each region.

Adding Authenticated Accounts

If Enable Auth on SignallingServer was properly configured in the Security tab during deployment, you must add user accounts that have access to the stream. In the Admin Dashboard, click on Accounts from the left hand navigation, then click Add Account. Users must use the credentials you provide to access the app.



Reviewing Logs

To assist with debugging any issues with your deployment, you can review detailed logs of all activity from the Matchmakers and SignallingServers.

In the global resource group, click the name of the **Log Analytic**s workspace resource.



In the General section of the left hand panel, click Logs.



You may be presented with a popup dialog showing available Queries that are not necessarily relevant. Toggle the Always show Queries option and then click the X to close the prompt.



Click the double arrow to expand the Schema and Filter panel inside of the default New Query tab.



Click the arrow next to the Custom Logs item to expand it. If you do not see an item under Custom Logs, your deployment may not have been active long enough to record any and you can check back in a few minutes.

Double click on the armlog_newline_CL item. This adds it to your active Query.



Click the blue Run button to begin the query of the VM logs. Optionally, you can adjust the time range to some other value than the default 24 hours.



This produces a table of all the available logs from all the available VMs in your deployment, which can be quite verbose. You can sort the data by clicking on the columns, and you can search or filter the data by clicking on the magnifying glass at the top right of the table. Some relevant search terms might be "connected" or "download."



Deleting the Whole Deployment

To delete the Pixel Streaming deployment and stop all associated costs, you must delete the resource groups that were created. After the initial deployment you should have at least three resource groups in your subscription: one resource group for each region (for the GPU instances), one storage resource group (for the initial .zip file upload), and one global resource group (for the Traffic Manager and Admin Dashboard). The storage resource group can be reused for a future deployment.



The resource groups used for your deployment have a Tag in the Essentials area called RandomString: xyz. Clicking that tag shows only the relevant resource groups to make it easier to navigate and delete multiple groups.



To delete a resource group, first open it and then click the Delete resource group button at the top. You need to confirm your deletion. It may take several minutes for the deletion to fully process and remove the group from your subscription. Repeat as necessary for other resource groups.



If you set a custom domain, you also need to delete the records added to the DNS zone.

Prerequisites

Region Support

AWS Account

Account Permissions

Account Owner

Third-Party Account

On-Demand G Instance Quota

Remote Access

Using the AWS Console and AWS Marketplace AMIs

Log in to Your Account

Subscribe to the UE Product

Launch the Instance

Launch Option 1: CloudFormation

Launch Option 2: EC2 Console

View the Status of Your Instance

Connect to the Instance

Connection Option 1: NICE DCV

Connection Option 2: Windows RDP

Launch Unreal Engine 5

Cost Optimization

Stopping Your Instance

Restarting Your Stopped Instance

Terminating Your Instance

This tutorial provides a step-by-step guide to setting up an Unreal Engine 5 instance on Amazon Web Services (AWS).

Prerequisites

You need to meet the following prerequisites to successfully deploy Unreal Engine 5 on AWS.

Region Support

Make sure that the geographic region you are in (or the one closest to you) supports access to a GPU-enabled virtual workstation (g4dn instance). Check with AWS for a current list of regions where this is available.

The Unreal Engine 5 offering outlined here only supports g4dn instances at this time.

For the best performance, you want AWS services to be located as geographically close to you as possible. The Region with the lowest latency value is usually the one you want. For optimal performance, we recommend less than 50 ms latency.

To check which Region is closest to you, refer to AWS' Regions and Availability Zones webpage. You can use a website such as ping.psa.fun to measure the latency from your location to the different Regions. If your nearest Region does not support access to a G4 instance, check other nearby Regions.

AWS Account

You need access to an AWS account, either your own or through your employer or another party. Verify that your account has sufficient permissions to access all the AWS services required to complete the deployment.

While Unreal Engine 5 is available at no cost, AWS instances do have an associated cost. If your account is linked to your employer or another party, check that they are prepared to accept responsibility for the costs involved before setting up your deployment instance.

For a more accurate estimate of your cost, review the pricing information on the EC2 Pricing page or create a new EC2 estimate using the AWS Calculator. For a personalized cost per hour estimate, first select your closest region, then select the g4dn.2xlarge instance. When working, you can monitor your current costs using the AWS Billing Console.

For more information on linked accounts and consolidated billing, please refer to the Consolidated Billing Process AWS documentation.

Account Permissions

If you just created a new AWS account or are the owner of your account, you may be logging in as the root user. If you are logging in using an email address, rather than a username, you are using the root account.

For security purposes, we strongly recommend creating a new user and logging in with those credentials instead. Refer to AWS' documentation on creating new IAM users for more information.

If you are using a user account provided by your employer or a third party, you may need to request additional permission policies added in order to deploy Unreal Engine 5. The owner of your account may have rules about what policies you can access.

On-Demand G Instance Quota

Many resources in AWS are subject to quotas, also called limits. Each resource has a quota that represents the maximum value of that resource you can use. Quotas are how AWS manages resources for its clients, ensuring high availability and low latency, and avoiding resource overuse and unexpected charges.

Deploying Unreal Engine 5 on AWS requires connecting to a GPU-enabled virtual workstation (g4dn instance). You need a g4dn instance quota of at least 8 to use the recommended instance size.**

If you are using a new AWS account or have never used GPU instances before, check the value of your G4 instance quota and, if necessary, request an increase. Login to your AWS account and refer to AWS' documentation on service quotas to learn how to check your current quota or request an increase.

Remote Access

Accessing your G4 instance where Unreal Engine is deployed requires a remote access application. The instance comes with NICE DCV support for a low latency connection method. You can install the NICE DCV client ahead of time. The Windows RDP client is also effective for these purposes.

Using the AWS Console and AWS Marketplace AMIs

The AWS Console is your main interface to all AWS services. The AWS service that you use to launch the virtual computer that you use for your virtual workstation is Elastic Compute Cloud (EC2). Aninstance is a single virtual computer in EC2.

Instead of installing Unreal Engine from scratch on a basic Windows instance, start with an Amazon Machine Image (AMI) from the AWS Marketplace that already has Unreal Engine 5 installed and configured.

Log in to Your Account

Follow this link to log in to your AWS account.

As a reminder, make sure you log in as an IAM user and not as the root user for your account. If you need to create a new user, please refer to AWS' documentation on IAM users.

Subscribe to the UE Product

The Unreal Engine 5 AMI is hosted on the AWS Marketplace. Navigate to the product page found here.

Once you have opened the listing for the Unreal Engine AMI, click Continue to Subscribe in the upper right.



On the Subscribe to this software page, under Terms and Conditions, click Accept Terms. After a few minutes of processing, this adds the Unreal Engine 5 AMI to your AWS account so you can launch it in a variety of ways.



Launch the Instance

AWS provides several different ways to launch EC2 instances. We review two of the easiest methods, CloudFormation and the EC2 Console.

CloudFormation is an offering by AWS that allows you to deploy many different resources all at once based on a simple template file. Epic Games created a template that automatically creates a new IAM role that is necessary for licensing the NICE DCV remote desktop software included in the AMI.

Within the AWS Management Console, ensure you're in the region where you want your instance deployed by selecting a region from the dropdown menu at the top right of the page.



If you don't already have access to a private keypair used for creating EC2 instances, follow this guide to create one. Use RSA as the type, and **.pem** as the format. Make sure it is downloaded and securely stored.

Open this link to start the creation of a new stack in CloudFormation using our template.

As in Step 1 above, change the region of your AWS Management Console so you're creating this stack in the same region that you created your key pair.

Most fields are pre-filled with defaults that function correctly without any changes, but pay attention to the following:

Enter a valid Stack name.



Select a key pair name from the dropdown. This must be a key pair for which you have a local copy of the .pem file. If your list is empty, go back to step 1 to create one, or make sure you're in the correct region.



We recommend that you enable Termination Protection. This is optional, but helps prevent accidental loss of data if the stack or the created instance is deleted by a user.



Specify a VPC and Subnet from the dropdown lists. There is usually one default VPC and several default subnets in your current region, so the top item in the list is usually preferred.



Once your settings are configured, check the box to acknowledge that AWS CloudFormation might create IAM resources, then click Create Stack.



If everything was configured correctly you should be taken to the overview page of your newly created stack, where you can see a CREATE_IN_PROGRESS status. Click on the Resources tab.



The EC2Instance in the list of resources is the virtual machine you will be working with. If you don't see an EC2 Instance, it is still being created and will appear if you refresh the page after a few minutes. Click on the hyperlinked Physical ID to open up the EC2 Console. Continue in the Connect to the Instance section below.



After you subscribe to the Unreal Engine product on the Marketplace, you can follow these steps to launch your instance directly from there.

If you intend to connect to this instance using NICE DCV, you have to deploy using the CloudFormation template or follow these steps to keep the free license active past a short evaluation period.

On the Subscribe page of the Marketplace listing, click Continue to Configuration.



On the Configure this software page, verify the region selected is correct, and if not, update it using the dropdown menu. When you are done, click Continue to Launch.



On the Launch this software page, expand the Choose Action dropdown menu and select Launch through EC2, then click Launch.



You are sent to the Launch an instance page, start by entering a name for your instance.



Several default settings are already filled in for you. You can modify the Instance type, Storage, and Networking sections to review the settings for your instance. The default settings are usually acceptable, but if you are an advanced user, feel free to change them.

Under the Key pair section, select Create a new key pair from the drop down menu and then enter a key pair name.

A key pair consists of public and private key files that are used to encrypt data between two computers. AWS stores the public key file, but you need to store the private key file.



After entering your key pair name, click Download Key Pair.

You must download the private key file when you create a new key pair and store it securely on your local computer. You will not have another chance to download the private key file, so save it in a safe place on your computer where you can find it again.

After downloading the private key file, click Launch Instance.

View the Status of Your Instance

After you launch the instance, you should shortly see it display Success. Click on View all instances after the instance has successfully launched.



This takes you back to the Instances page, which shows a list of your running instances and their status. Initially, the Instance State is listed as pending, before changing to running, and the Status Checks field starts out as Initializing.



After about 5-10 minutes the Status Checks field changes to 2/2 checks passed and your instance is ready. Continue with Connect to the Instance below.

Connect to the Instance

Once your instance has been created and has finished the set-up process, you can connect to it using NICE DCV, Windows RDP, or another remote-connection application.

On the Instances page of the EC2 Console, click the Instance ID.



This opens the Instance summary page. In the upper right corner, click Connect.



A warning message appears telling you that you can't connect. Click RDP client, then click Get password.



Click Browse and select the key pair file you downloaded and saved previously. Once the RSA key is showing in the text window, click Decrypt Password.



The decrypted password appears.



Connection Option 1: NICE DCV

The Unreal Engine AMI comes with support for NICE DCV, a remote desktop software offered by Amazon and meant to provide a low latency and high quality experience. If you haven't already, you need to install the NICE DCV client.

Open NICE DCV Client. Copy the Public DNS and paste it into the Hostname / IP Address field, then click Connect.



A warning comes up about the server's security certificate. Click Trust and Connect.



Next, enter the login credentials. Use ./Administrator for the Username and copy-paste the decrypted password from your key pair file. Click Login. NICE DCV begins to connect.



Connection Option 2: Windows RDP

You can initiate a remote desktop session using the standard Windows Remote Desktop Connection app ("Windows RDP") installed with Windows 10. This is a good alternative if you don't want to install extra remote desktop clients on your computer, but it doesn't provide the extra features of apps like NICE DCV.

Launch the Windows RDP client. Copy the Public DNS and paste it into the Computer field in the Windows RDP login window, then click Connect.



Under More choices select Use a different account, then enter .\Administrator for the username. For the Password, enter the decrypted password from your key pair file. Click OK to connect to your instance.

If you have already set up another user account than Administrator, use that user name instead.



You then receive a warning about a certificate issue on the EC2 instance. Click Yes to continue with the connection, and optionally tick the box for Don't ask me again.



Launch Unreal Engine 5

After the login process completes, the Unreal Engine 5 EULA shows. Select the relevant option and click Verify EULA. You only need to do this on the very first connection to the instance.



Next, you are presented with the Epic Games log-in menu. Log in with your Epic Games account.



Once logged in, you are presented with a desktop with Unreal Engine 5 and the Epic Games Launcher already present. You can run Unreal Engine directly from the shortcut or run the Epic Games Launcher to login again and access content as you normally would.

Upon logging into the Launcher for the first time you may be presented with a prompt to update the launcher and a prompt to associate project files with the engine.



You can install any additional Windows software as you would to a local machine. We recommend you continue through the remaining part of this tutorial first to learn how to manage the instance so it is not running when not needed.

Cost Optimization

Due to the ongoing hourly cost of using an AWS instance, we recommend stopping or terminating your instance when you're not using it.

Stopping an instance is similar to shutting down your home or work computer. All running applications quit, but whatever data was stored on persistent storage (that is, the instance's hard drive) is preserved. Once the instance is stopped, you are no longer charged any hourly fees for its use (although you are charged a small amount to store the data that was on the instance's hard drive). A stopped instance is still listed in the EC2 instance list in the AWS Console and can be restarted at any time. Refer to the AWS documentation on stopping and starting instances for more information.

Terminating the instance is more final than stopping it. When an instance is terminated, it is stopped like above, but all the data that was stored in persistent storage is also deleted, so not only do you not incur any hourly charges, you also do not incur any charges for storage of data. Terminated instances remain visible in the console for a short time, but unlike stopped instances, they cannot be restarted. You can enable Termination Protection to avoid accidental loss of your data. If you enabled Termination Protection from the CloudFormation template, you must disable it on the instance before you can successfully terminate it. Refer to the AWS documentation on terminating instances for more information.

Stopping Your Instance

In the AWS Console, select your instance.

Click the Actions button at the top of the list of instances and select Instance State > Stop, then click Yes, Stop.

Restarting Your Stopped Instance

In the AWS Console, select your instance.

Click the Actions button at the top of the list of instances and select Instance State > Start.

Terminating Your Instance

In the AWS Console, select your instance.

Click the Actions button at the top of the list of instances and select Instance State > Terminate, then click Yes, Terminate.



Prerequisites

Azure Account and Subscription

Remote Access

Using the Azure Portal and the Azure Marketplace

Configuring the Virtual Machine

Connecting to the Instance

Launch Unreal Engine

Cost Optimization

Stopping Your VM

Restarting Your Stopped VM

Deleting Your VM

This tutorial provides a step-by-step guide to setting up an Unreal Engine 5 virtual machine (VM) instance on Microsoft Azure using the Azure Marketplace.

Prerequisites

Azure Account and Subscription

You need an Azure account and at least one subscription for which you have the proper permissions to create resources. For information on creating a new subscription, refer to this guide. Subscriptions also require that you have a billing account set up.

While Unreal Engine is available at no cost, Azure resources do have an associated cost. If your account is linked to your employer or another party, check that they are prepared to accept responsibility for the costs involved before setting up your deployment instance. For a more accurate estimate of your cost, review the pricing information on the Virtual Machine Pricing page, filter by desired region, and search for "NCas_T4_v3" to see the "pay as you go" pricing.

Remote Access

Accessing your Azure instance where Unreal Engine is deployed requires a remote access application. We will be using Windows Remote Desktop Connection (Windows RDP), which already comes installed on most editions of Windows 10.

Using the Azure Portal and the Azure Marketplace

Log into your Azure account.

The Unreal Engine VM offer is hosted on the Azure Marketplace. Navigate to the offer page here.



Sign in to the Azure Marketplace using the button at the top right. Use the same account you use for all other Azure services.



Click Get It Now below the Unreal Engine icon.



A dialog will pop up asking you to choose your software plan, select Unreal Engine 5, confirm your information, and add this app to your account. Fill it out and click Continue.



The Azure Portal will open up to the Unreal Engine product in your account. From here, choose Unreal Engine 5 under the Plan dropdown and then click Create to begin setting up the virtual machine.



Configuring the Virtual Machine

First, select a Subscription where your virtual machine will reside. You must select an existing subscription for which you have the permissions to create resources.



Select a Resource Group for the virtual machine. Resource groups are used to organize resources and can be re-used for other VMs. If you do not already have a resource group, click Create new. Give it a valid name and click OK.



Provide a valid name for the virtual machine itself.



Select a region to deploy this VM in. You should select a region that is as close as possible to you to minimize latency when using the VM. It must be a region that supports the NV12s_v3 VM size, and you will receive an error if it does not. Different regions may change the price estimation shown in Size below.



Leave the Image as "Unreal Engine", click See All Sizes, and select the Size "NCas_T4_v3". You may encounter a warning saying "Family vCPUs are insufficient to deploy these sizes". Click Request quota.



A blade appears with the options for increasing your quota. The NCas_T4_v3 needs 4 vCPUs per VM instance, so that is the minimum amount you need for this tutorial.



Click Save and Continue.



After a few minutes, you should receive confirmation of your new quota. If it is unsuccessful, you may need to select a different region or create a support ticket.

Under Administrator account, create your own Username and Password for this virtual machine, and make sure to remember these for later. You cannot access the machine without these credentials.



This VM comes with a 250 GB SSD by default. If you want to add an extra storage disk, you can configure settings with Next : Disks. Otherwise, select Review + create. If your organization has Software Assurance for Windows Server licenses, you can select this option before creating.



The next page is the confirmation for the VM you are about to create. If it looks good, click Create.



A new page appears, showing the progress of the deployment. It may take a few minutes until you receive a notification that the deployment is complete. Click Refresh to confirm, then click Go to resource.





Connecting to the Instance

You should now be on the Overview page of the VM resource, where you can see or configure all the technical settings of the instance. Now you have everything you need to start a remote desktop session into this workstation and start using it.

Launch the Windows RDP client on your PC. Copy the Public IP address from the instance overview into the Computer field in the login window, then click Connect.



Under More choices, select Use a different account. Enter the username and password that you defined earlier. You can optionally select Remember me then click OK.



You will get a warning about the certificate of the VM. Select Don't ask me again for connections to this computer, then select Yes.



Launch Unreal Engine

After a few moments, you may see a Windows boot screen at first, and then the Unreal Engine EULA shows. Select the relevant option and click Verify EULA. You only need to do this on the very first connection to the instance.



Next, you are presented with the Epic Games log-in menu. Log in with your Epic Games account.



Once you log in, you will see a desktop with Unreal Engine and the Epic Games Launcher already present. You can run Unreal Engine directly from the shortcut or run the Epic Games Launcher to login again and access content as you normally would.



Upon logging into the Launcher for the first time you may be presented with a prompt to update the launcher and a prompt to associate project files with the engine.

Cost Optimization

Due to the ongoing hourly cost of using an Azure VM, we recommend stopping your instance when you're not using it.

Stopping Your VM

From the VM overview page, click the Stop button at the top. This is similar to shutting down your home or work computer. All running applications quit, but whatever data was stored on persistent storage is preserved. Once the instance is stopped you are no longer charged any hourly fees for its use, although you are charged a small amount to store the data on its hard drive.

Restarting Your Stopped VM

From the VM overview page, click the Start button to turn a stopped instance back on. After a short time, the VM will be available to connect over RDP again, and any persistent storage volumes will be restored.



Deleting Your VM

If you are done using the VM indefinitely and want to clean up your resources, click Delete at the top of the overview page. You are prompted to confirm the deletion and you can also select the associate storage and networking resources to delete along with it. Once all these resources are deleted, you are no longer charged for them. This action cannot be undone.

You can also delete the entire Resource Group where all your created resources are stored.

In your Azure portal, navigate to your Subscription, and then select Resource groups from the blade on the left.



Select the relevant resource group from the available list.



From the resource group overview page, you can click Delete resource group from the top, or select and then Delete individual resources. You need to confirm your deletion.



This resource group page is also where you can access and manage these resources in the future.



Prerequisites

Google Cloud Account and Subscription

Remote Access

Using the Google Cloud Console and Cloud Marketplace

Configuring the virtual machine

Connecting to the instance

Launch Unreal Engine

Cost Optimization

Stopping Your VM

Restarting Your Stopped VM

Deleting Your VM

This tutorial provides you with a step-by-step guide to setting up an Unreal Engine virtual machine instance on Google Cloud using the Cloud Marketplace.

Prerequisites

Google Cloud Account and Subscription

You need access to a Google Cloud account and a project for which you have the proper permissions to create resources. For information on creating or managing projects on Google Cloud, see this guide.

While Unreal Engine is available at no cost, Google Cloud resources do have an associated cost. If your account is linked to your employer or another party, check that they are prepared to accept responsibility for the costs involved before setting up your deployment instance.

Remote Access

Accessing your Google Cloud instance where Unreal Engine is deployed requires a remote access application. We will be using Windows Remote Desktop Connection ("Windows RDP"), which already comes installed on most editions of Windows 10.

Using the Google Cloud Console and Cloud Marketplace

Log into your Google Cloud account

The Unreal Engine Image offer is hosted on the Cloud marketplace. Navigate to the offer page here for UE5.



Click Launch below the Unreal Engine icon.



The Unreal Engine VM configuration page opens. From here, you can configure and create the VM. You also get an estimate of the cost on the right.



Configuring the virtual machine

First, enter your deployment name.



Select a zone to deploy in. By default, this will be us-central1-c.

GPU availability is limited to certain zones.



Under Machine family, the default selected machine type will be n1-standard-16, with 16 vCPUs and 60 GB memory. Selecting a machine type with a higher vCPU count can speed up some UE features like shader compiling and building lighting, but 16 vCPUs is an acceptable start.



Select a GPU to deploy this VM with.

For the GPU type, NVIDIA Tesla T4 is selected by default. GPU options vary according to the zone you chose previously.

For the Number of GPUs, only select 1. Additional GPUs will incur a substantial cost and will not be used effectively by Unreal Engine.

Make sure to select Enable Virtual Workstation (NVIDIA GRID).



For the Boot Disk, Standard Persistent Disk is selected by default. To learn more about Boot disk types on Google Cloud, click here. Feel free to increase or decrease the boot disk size, but make sure it is greater than 200 GB for the installed applications and operating system.



For Networking, the default options are sufficient, you do not need to change them.



Click the checkbox to accept the GCP Marketplace Terms of Service and Epic Games Terms of Service, then click Deploy.



After you click Deploy, you are redirected to the Deployment Manager page. You can see your deployment in progress.



When your deployment is ready, a green checkmark confirming the successful deployment appears.



Connecting to the instance

To access your VM, open the dropdown menu next to the RDP button. Select Download the RDP file, then open the downloaded .rdp file.



When opening the .rdp file, you may be prompted with a warning about it having an unknown publisher. Select Don't ask me again for connections to this computer, then click Connect.

If you cannot connect to the VM initially, wait a few minutes. It may take up to 10 minutes for the VM to be ready for connection.



Once you establish a connection, you are prompted for a username and password. Your username should already be filled out with your Google Cloud username, or you can select Use a different account and enter your credentials. You can optionally select Remember me.



To get your password, go back to the Deployment Manager page. Open the dropdown menu next to RDP on the right side of the page, then select Set Windows password.



You are prompted to set your new Windows password. First, you need to select your username. By default, your Google Cloud username is used. Change your username if you use something different. Once you select your username, click SET.



After clicking SET, you are shown your new Windows password. Copy this password to your clipboard.

This password will not be shown again. To avoid continually resetting the password for this VM, save this in a secure location or pick a new password once you are logged into the VM.



Paste this password into the RDP credentials window, and click OK.

You may get a warning about the certificate of the VM. Select Don't ask me again for connections to this computer and then select Yes.



Launch Unreal Engine

After a few moments, you may see a Windows boot screen at first, and then the Unreal Engine EULA shows. Select the relevant option and click Verify EULA. You only need to do this on the very first connection to the instance.



Next, you are presented with the Epic Games log-in menu. Log in with your Epic Games account.



Once logged in, you are presented with a desktop with Unreal Engine and the Epic Games Launcher already present. You can run Unreal Engine directly from the shortcut or run the Epic Games Launcher to login again and access content as you normally would.



When logging into the Launcher for the first time, you may be prompted to update the launcher and to associate project files with the engine.

Cost Optimization

Due to the ongoing hourly cost of using a Google Cloud VM, we recommend stopping your instance when you are not using it.

Stopping Your VM

From the Compute Engine – VM Instances page, click the ⋮ button next to your instance to open the menu and select Stop. This is similar to shutting down your home or work computer. All running applications quit, but whatever data was stored on persistent storage is preserved. Once the instance is stopped, you are no longer charged any hourly fees for its use, although you are charged a small amount to store the data on its hard drive.



Restarting Your Stopped VM

From the same VM instances page, you can select Start/Resume in the same ⋮ menu to restart a stopped instance. After a few minutes, the VM will be available to connect over RDP again, and any persistent storage volumes will be restored.



Deleting Your VM

If you are completely done using the VM and want to clean up your resources, you can go back to the Deployment Manager page, select the deployment, then click Delete at the top of the page.



You are prompted to either delete the deployment and all resources or delete the deployment while keeping the resources.



Overview

Setting Up Turnkey

Usage

Turnkey is a system introduced in Unreal Engine 5 that automates most of the steps required for setting up platform support, including finding source files for installing SDKs and flashing dev kits.

Once your organization has set up a filesource repository for Turnkey, individual team members can use a one-click process to set up their system for any target platform. The guides listed on this page will show you how to host SDKs for Turnkey, and how to use Turnkey to download and install them on individual instances of Unreal Engine.

Overview

Turnkey is an AutomationTool script, accessed through RunUAT.bat, featuring many tools you can use to interact with SDKs. It accesses the repository you set up for your organization, then automatically downloads files and sets up SDKs from that repository.

When you run Turnkey to install an SDK, it performs the following processes:

Turnkey starts up and scans for SDKs using the information provided by TurnkeyManifest.xml.

Turnkey selects a platform based on the user's input.

The build system tells Turnkey what versions of the SDK are valid for the current Unreal Engine version.

The best SDK is selected from all of the valid SDKs available.

Turnkey uses a series of platform-specific rules to convert the version numbers to integers, and the largest number within the range of valid SDKs is selected. These rules are specified in the *PlatformSDK.cs files.

Turnkey downloads the SDK files to the user's machine.

If the SDK files are contained in a .zip file, they will be automatically decompressed in a temporary location.

The build system installs the downloaded SDKs.

This provides a way to quickly set up your Unreal Engine project even if there are a large number of available SDK versions, and streamlines maintenance whenever you need to update your available SDKs.

Setting Up Turnkey

To use Turnkey, you need to host your SDKs in a filesource repository, then set up TurnkeyManifest.xml and TurnkeyStudioSettings.xml files with the necessary information for Turnkey to discover them.

The pages listed below provide instructions on how to set up each of these components, as well as how to structure directories so that Turnkey's automation will recognize your SDK versions.



Information about how to write Turnkey manifests and set up copy providers for your organization.



How to set up the Google Drive API and host SDKs for use with Unreal Turnkey

Usage

Once you have set up Turnkey for your organization, users can interact with it either directly from within Unreal Engine, or using RunUAT.bat with a command-line interface. The pages listed below contain information about how to use each of these.



Using the new Platform dropdown in Unreal Editor to install SDKs and manage devices



Reference information for how to run Turnkey from RunUAT.bat using a commandline interface

Overview of a Manifest File

Providing Additional Manifests

FileSource Entries

String Formatting Reference

Platform owners distribute their SDKs to organizations on a case-by-case basis. While you still need to obtain your SDKs from a provider, you can place them in a common file source location for your organization. Turnkey can then access these files to download and install the SDKs to individual users' devices.

You can host SDK files for Turnkey in three different ways:

On a Perforce repository for your organization.

On a user's local machine.

On a shared drive on Google Drive.

Turnkey then uses a series of chained XML files to determine which SDKs are available for each platform. This process starts by reading a TurnkeyManifest.xml file and a TurnkeyStudioSettings.xml file located in your Unreal Engine (UE) installation directory, under the Engine/Build/Turnkey directory.



TurnkeyManifest.xml contains information about which SDKs are available, or points to other manifest files that contain the needed information, while TurnkeyStudioSettings.xml provides studio-wide information such as credentials needed to access Google Drive or signed certificates. Both TurnkeyManifest.xml and TurnkeyStudioSettings.xml can be chained to point to other .xml files in either local or remote directories.

In an ideal use case, your organization would distribute this TurnkeyManifest.xml to all its users alongside Unreal Engine source files within your version control system. This base manifest never changes, but instead contains references to other manifests located alongside your SDK files for each platform. Using this setup, you can quickly edit and update these manifests without altering any Unreal Engine source files.

Overview of a Manifest File

Turnkey manifests contain the following information:

A TurnkeyManifest tag encompassing the entire manifest.

An AdditionalManifests tag

Individual Manifest entries pointing to any other manifests you want to include alongside the current one.

FileSource entries containing information about available SDKs, including:

Platform

Type

Version

Name

Source

For example, the following would be an example of a working TurnkeyManifest supporting Win64 and Mac:

Providing Additional Manifests

The AdditionalManifests section contains individual Manifest entries that point to other XML files you want to include when Turnkey scans for files. The base TurnkeyManifest.xml in the Engine/Build/Turnkey directory is always the starting point for this process. and you can otherwise chain manifests as many times as you want, and you can organize them in any way.

The Manifest entries in this list follow the same formatting rules as file references for source files. Additional manifests can therefore be located anywhere that your source files are located, including remote repositories or a Google Drive folder. See the Formatting Rules section for more information about how to format a directory string.

FileSource Entries

FileSource entries list either specific SDKs that are available for your organization, or grouped SDK entries, depending on how you fill them out. The rules for each parameter within a FileSource entry are described below.

Platform

The name of the supported platform for this SDK. Turnkey uses this information to automatically determine the appropriate versioning rules for a given platform.

Platform names must match one of Unreal Engine's built-in platform names. For example, you should use "Win64" rather than "Windows," and "IOS" rather than "iPhone."

Type

The Type field describes whether you are listing a full SDK installation or a more minimal SDK, such as a flash kit. The valid SDK types are as follows:

Type

Description

Full

A complete installation of the SDK, as would be used by a developer.

AutoSDK

A package that Unreal Engine can use to configure your SDK installation as needed. Turnkey prefers AutoSDKs over Full SDKs when both are present.

Flash

A minimal installation with components for flashing a dev kit.

For more information on AutoSDKs, refer to the Unreal Engine AutoSDK Reference.

Version

The Version field contains the version number for the SDK. Every platform has a different expected version format, so it is important to list this information accurately.

You can capture the version number in the Source section by using a capture variable such as $[ExpVersion], then list $(ExpVersion) in this section as a substitution variable. See the section on File Expansions and Capture Variables for more details.

The version number is also converted into an integer when Turnkey scans for SDKs. Turnkey uses different rules for each platform, and if the Full and Flash SDKs use different versioning formats, it takes those into account as well. When Turnkey compares multiple valid versions of an SDK, it will favor the highest converted integer value among the versions listed.

For information about each platform's expected version number formatting, check the Help command in the Turnkey commandline.

Name

The Name field contains a human-readable display name for your SDK. This is purely for display purposes, and can be set to anything you want.

The Name field will accept substitution variables corresponding to capture variables that you used elsewhere in the FileSource. For example, if you used $[ExpVersion] to represent the version number, the Name field can use $(ExpVersion) to substitute the value that the capture variable finds. For more information about capture and substitution variables, refer to the File Expansions and Capture Variables section.

Source

The Source field contains a string describing the location of the SDK. This string is separated into two parts: a set of prefixes that tell Turnkey how to read the file path, and the file path itself.

For example, the following would be a source entry that looks for the Win64 SDKs on the local file system (using the file: prefix) and expects a 7zip file called Install.zip:

You can use the fileexpansion: prefix to enable capture variables to iterate through many SDKs with data from the file provider. For example, the following would be a source entry that uses the version number specified in the Version field:

Instead of looking at just one specific file path, it would look through every file path that matches this format.

The Source parameter can also use an optional CopyOverride specifier to restrict the directories Turnkey expands when using a Perforce repository. See the example below for a FileSource block that uses this specifier.

For a full list of prefixes and capture variables that are useable with source strings, refer to the Formatting Reference below.

Other Parameters

Although the above parameters are most commonly used, there are several others used in special cases.

The AllowedFlashDeviceTypes value is only used for SDKs with the Flash type. These are strings whose values only make sense to the targeted platform. The possible values can be found in the Help section of the Turnkey command line, listed under the information for the given platform. When Turnkey receives device information, it will get the Device Type as well as the installed software version. It will then use these to determine if it is up to date and select a Flash FileSource to install from.

Example

The following is an example of a FileSource entry that looks for AutoSDK files on a Perforce repository. This example looks for Setup.bat and Setup.sh files to expand into one FileSource per SDK version, per platform, and uses CopyOverride to restrict Turnkey from expanding recursively unless the user explicitly chooses one of these SDKs. This prevents Turnkey from unnecessarily expanding on too many Perforce files. This behavior is specific to Perforce because it can only operate on files, not directories.

String Formatting Reference

Strings in Turnkey manifests use several prefixes to determine how to read the given file path. Depending on which prefixes you use, file paths can incorporate custom variables that expand into additional information at read time. This makes it possible for you to specify an expected format for a file path, rather than explicitly listing file paths for specific files, and Turnkey will discover all files that match that format.

Copy Providers

Copy provider prefixes determine what type of location Turnkey should look for when it parses the file path that follows it. Turnkey recognizes three types of locations, and the prefixes for these location types each have rules for what kind of file path they expect.

Prefix

Description

Example File Path

file:

Turnkey will look at the local file system for the SDK installers.

This prefix expects a standard file path, including the drive where the file is located. This can include shared network drives.

MacOS requires an additional smb: prefix to mount an SMB share.

file:X:\SdkInstallers\$[ExpPlatform]\$[ExpVersion].Install.zip

file:smb:X:\SdkInstallers\$[ExpPlatform\$[ExpVersion].Install.zip

perforce:

Turnkey will connect to a Perforce stream to find the SDK installers.

This prefix expects a standard Perforce filespec, which must always include a specific file component, complete with a file extension. You may also be prompted to provide a clientspec the first time you use this to allow Turnkey to find the Perforce client's location.

perforce:\depot\SdkInstallers\$[ExpPlatform]\$[ExpVersion].Install.zip

googledrive:

Turnkey will connect to Google Drive to locate the SDK installers.

The first component in the file path represents the name of a shared drive to look in, while all subsequent components of the path are names of subfolders on that drive.

googledrive:/SdkInstallers/$[ExpPlatform]/$[ExpVersion].Install.zip

Using local files requires the least additional setup, as you can use SDK installers located directly on a user's machine. However, this setup requires the most additional maintenance, as each user must maintain a consistent local folder with the SDK installers located in it. You can use a shared network drive instead of a local drive on the user's machine, but depending on the speed of the shared drive, this might be slow.

Using Google Drive requires the most additional setup, as you must set up an account to use the Google Drive API and provide OAuth 2.0 credentials to users alongside their engine files. However, this setup provides a simpler point of maintenance for your organization's administrators once you have it set up. Refer to the guide on Setting Up Google Drive for Unreal Turnkey for more information.

Using a Perforce stream provides a balanced solution between these two methods, as it creates a central location for your organization to keep SDK files, but requires your organization to set up a Perforce stream and provide users with credentials to access it.

If you need to add support for other source control options to Turnkey, it is possible to add new types of copy providers with changes to the engine source code. See GoogleCopyProvider, PerforceCopyProvider, and NullCopyProvider for examples.

File Expansions and Capture Variables

The fileexpansion: prefix provides a way for Turnkey to search for paths matching a general format rather than paths to specific SDKs. This reduces the number of server calls for SDKs that you do not need to download, and tracks a wide range of SDKs rather than needing to write all their entries individually. For example, you can upload a new installer to your server, and as long as its directory structure fits the expected format listed in the FileSource entry, the file expansion will discover it without needing to modify the manifest.

When using the fileexpansion: prefix, you must follow it with a copy provider prefix such as file: or googledrive: as file expansions depend on information from the copy provider.

After adding fileexpansion: to your path, you can then substitute parts of your path with capture variables. These variables use a format $[xyz], where xyz is replaced with any arbitrary string you define. When Turnkey reads through the manifest, it will expand these with information from the user and the file provider.

As an example, if you use the following source string:

Turnkey will convert the $[ExpPlatform] and $[ExpVersion] capture variables to wildcard values (the * character). Turnkey will then pass those to the copy provider used after the fileexpansion: prefix, in this case a local file system. The provider then iterates through its available files and folders and returns a list of results that match the provided format, along with the values captured for each capture variable.

Turnkey creates a FileSource objects in C# for each of these entries, which can then be discovered as SDK installer download sources. The portions of the file path expanded on by the capture variables will be converted into $(xyz) style replacement variables, which the FileSource object can reference in other fields. For example, if you use $[ExpVersion] in a source path, you can also use $(ExpVersion) in the Version field.

Capture variables can represent any part of a file path, including filenames, directories, or even parts of a name.

For example, the above entry expects installers to exist in a folder for their platform, and it expects them to be contained in .zip files with names like Installer_1.00.zip or Installer_2.00.zip.

List Expansions

The listexpansion: prefix defines a variable with a list of possible values, which does not need to query a server. When you define a variable with listexpansion, you can use it in other entries in the FileSource.

For example, the following text defines a listexpansion under Platform, then refers to that list under Name:

When Turnkey reads this, it will create separate FileSource objects for Windows, Android, and iOS, and substitute $(ExpPlatform) appropriately for each one. This functionality does not require Turnkey to query a server, as it uses the list provided by the listexpansion. This can potentially make initial startup of Turnkey faster, if the list of platforms with SDKs is generated from a list expansion.

You can also use an XML variable to store the list items rather than listing them directly.

Built-In Variables

Turnkey reserves several built-in variables for defining file paths alongside user-defined capture and substitution variables.

Variable

Description

$(ThisManifestDir)

Expands to the directory of the TurnkeyManifest.xml file currently being processed. This includes the provider prefix for where the manifest is currently located, so if it was found in a Perforce directory, it would automatically contain the perforce: prefix without the need to define it yourself.

This variable makes it possible to relocate entire directory structures, as long as each directory's location relative to the manifest remains consistent.

$(EngineDir)

The root folder for your Unreal Engine installation. This is a useful point of reference if you are using files that are checked in to source control.

$(HOST_PLATFORM_NAME)

The name of the host platform. This will typically be Win64, Mac, or Linux.

$(UE_STUDIO_TURNKEY_LOCATION)

An environment variable that can be set to the location of a studio-wide Turnkey directory.

1. Required Setup

2. Setting Up Google Drive API

3. Providing Google Drive Credentials

4. Uploading Your SDKs to Google Drive

5. Creating Manifest Files

6. Final Result

Setting up Google Drive for Unreal Turnkey is more complex than using Perforce or a local repository, but it provides a common place to store and maintain SDK files once the initial setup is complete. To do this, you will need to set up the following resources for your organization:

A Google account for your organization with Google Drive enabled.

A Google Cloud Platform app with Google Drive API enabled, set up with OAuth 2.0 credentials.

Turnkey manifest files pointing to the Google Drive folder and the required credentials.

This document will guide you through the process of setting up these resources for your organization.

1. Required Setup

This guide assumes that you have a Google Drive account set up for your organization. For information on how to set one up, refer to Google's documentation.

This guide also assumes that you have generated the required SDK packages for your supported platform, and that they are contained in a .zip file. Each platform has different methods for creating a full SDK or creating a flash SDK. Some packages will already be zipped when you receive them, in which case you can upload them directly to Google Drive without any changes. However, some consoles' SDKs require extra steps.

For information on how to generate the required files for a full or flash SDK from files received from your SDK provider, refer to the Help command in the Turnkey commandline. This command will output instructions on how to configure your SDKs as well as the proper version numbering conventions.

While there is no required naming convention for these .zip files, we recommend you choose a consistent compression format and naming convention to make them easy to reference. We also highly recommend zipping your SDK files before uploading them to Google Drive, as download requests through Google Drive perform significantly faster for single, compressed files than they do for large numbers of files.

2. Setting Up Google Drive API

You need to set up an app with Google Drive API enabled to permit users to access your Google Drive folder and its files. You also need to set up secure credentials so that only authorized users can access your Drive folder.

This section will walk you through the process of enabling the API and OAuth 2.0 credentials:

Visit the Google Developer Console at https://console.developers.google.com/projectcreate and agree to the Terms of Service.

Fill out the project name, organization, and location fields, then click Create.



You will be navigated to the Google Cloud dashboard, and a notification will pop up confirming that your project is set up. Click Select Project in this notification.



In the APIs panel, click Go to APIs overview. This will open the APIs & Services page.



At the top of the APIs & Services page, click Enable APIs and Services. This will open the API Library.



Choose the Google Drive API. You can find it under the Google Workspace section.



Click the Enable button for this API.



The APIs & Services page for the Google Drive API will open. Click the Create Credentials button. This will open a form to add credentials to your project.



Fill out the form with the following settings:



Number

Setting

Value

1

Which API are you using?

Google Drive API

2

Where will you be calling the API from?

Other UI

3

What data will you be accessing?

User Data

Click the button labeled What credentials do I need?



A popup will appear prompting you to set up an OAuth Consent Screen. Click the option to Set Up Consent Screen.



This will open a new tab for configuring OAuth credentials. Under User Type, select Internal, then click Create.



Another form will open for editing your app registration. Under App Information, enter the Application Name and User support email for your application. The user support Email should be a point of contact members of your organization can use to troubleshoot issues.



Scroll down to Developer Contact Information and enter the Email addresses for whomever is managing your organization's Turnkey Drive folder.



Click the Save and Continue button.



Close the current tab and return to the Credentials page, then click the Refresh button. Give your credentials a name, then click Create OAuth Client ID.



Once this has been created, the Download credentials section will become available. Click the Download button to download a file named client_id.json, which will be needed to provide your users with access to your organization's Google Drive.

The credentials you have set up will allow an application to access your shared drive and download files from it.

3. Providing Google Drive Credentials

To discover files on your Google Drive, you will need to provide the security credentials to access it. This information is contained in a TurnkeyManifest.xml file under its <Studio_GoogleDriveCredentials> setting.

Move the client_id.json file you generated in the previous section into your engine installation's Engine/Build/Turnkey folder. Be sure to add the file to your organization's version control system to make it available for your users.

Open the TurnkeyManifest.xml file located inside this folder and add the following line to the top of the file:

Save the manifest and update it on your organization's version control system.

Your application can now connect to your Google Drive using the provided credentials.

The first time a user connects to your Google Drive, it will open a web page to authenticate the user. During this time, Turnkey will pause and display a message indicating that it is waiting for authentication, but you may need to check for the new browser window manually. After completing this step once, Google Drive will cache the user's login information for future use.

4. Uploading Your SDKs to Google Drive

Now that you have generated and assigned the credentials needed to access your Drive, you need to set up the Google Drive folder structure to store your files.

Create a shared drive for your organization named SdkInstallers.

Inside this drive, create folders for each platform you will support. Make sure the names of these folders match the names listed in your TurnkeyManifest.xml manifest file.

Create a subfolder for each SDK version you want to host within each platform's folder.

For each SDK version, create a .zip file named Install.zip. Place this file into its corresponding platform and version folder on your Google Drive.

Once these steps are completed, your SDKs are ready for distribution within your organization.

If you are using automatic file discovery with the $fileexpansion: prefix and the file expansion variable $[ExpVersion], make sure your version folder names match the version numbering convention used by the corresponding platform. You can check this information by using the Help command in the Turnkey commandline.

5. Creating Manifest Files

Finally, you need to edit your Turnkey manifest to point to the files on your Google Drive.

Open the TurnkeyManifest.xml located in your engine installation's Engine/Build/Turnkey folder.

Add the relevant <FileSource> information for the SDKs you have available. For example, the following would be a valid <FileSource> for TurnkeyManifest_Win64.xml:

Because the Source path includes fileexpansion: and the $[ExpVersion] capture variable, Turnkey will look through all available version folders within the Win64 folder and create a FileSource object for each valid version number. Each of these FileSource objects will substitute $(ExpVersion) with the version number found.

Refer to Setting Up Turnkey for Your Organization for more information on how to format manifests.

Upload each manifest to its corresponding platform folder on your SdkInstallers drive.

Make sure the base TurnkeyManifest.xml file in Engine/Build/Turnkey is saved and updated on your organization's version control system so that every user's engine installation has access to it.

Once your manifests have been created, your SDK files will be discoverable on Google Drive when Turnkey starts.

6. Final Result

After following this guide, your organization is now equipped with a shared drive where you can upload and access platform SDKs. Your organization's administrators can add or remove SDKs and edit manifests, while Unreal Engine users will be able to access them by making a request to Turnkey to install or update SDKs.

Prerequisites

Installing and Managing SDKs

Packaging Projects

Setting Up Target Devices

Launching Projects on Devices

Unreal Editor now features a dedicated Platforms dropdown in the toolbar. This dropdown accesses the Turnkey platform support system, providing a means for quickly installing and updating SDKs, as well as an interface for launching and testing on devices.



This page provides a reference for the tools available through this menu.

The editor functions here access the same system as the Turnkey commandline.

Prerequisites

To use the Platforms menu for installing SDKs, your organization must make the SDK files for your platforms available in a file source repository, and you must have a valid TurnkeyManifest XML file pointing to that repository. For more information about how to prepare a file source repository, refer to Setting up Turnkey for Your Organization.

Installing and Managing SDKs

Each platform supported by your project appears in the Content/SDK/Device Management section of the Platforms dropdown. To install SDKs, navigate to the menu entry for the platform whose SDK you want to install, then click Install Sdk.



If the platform you want does not appear in this list, navigate to Platforms With No Compiled Support, which will display all platforms that Unreal Engine supports but that you do not have SDKs set up for.



Selecting Install Sdk will start up Turnkey and initialize the download and installation process for the selected SDK. Prefer Full will favor a full SDK installation. Prefer Minimal will prefer the smallest possible SDK installation, such as a Flash SDK for testing purposes.

Depending on which SDK you are installing, additional prompts may appear for setting up specific SDK components, like Android Studio.

You can check the SDK status by looking at a platform's SDK Management section, which will display your current SDK and the range of compatible SDKs for your platform. You can check the SDK status for an individual device in the submenu for its platform. Locate the All Devices section and highlight the entry for a device to display this information.



Packaging Projects

To package a project, click the Platforms dropdown in the editor, then navigate to the platform that you want to package for and click Package Project. A dialog will prompt you to save the packaged project, then initiate the packaging process when you select a directory to save to.



You can change build targets and binary configurations with the settings in the submenu for your platform.

To configure packaging settings, you can either click Packaging Settings in the Platforms dropdown menu, or you can open Project Settings > Packaging Settings.

Setting Up Target Devices

If you click Device Manager in the dropdown, it will open the Device Manager window.



This window will display recognized devices and dev kits on your local network, including compatible mobile devices connected to your computer. You can use this menu to claim, release, or share devices. Only devices that you have claimed will appear in the Project Launcher. You can also use this menu to control devices remotely by powering them on or off, rebooting them, or connecting/disconnecting them.

If you select a device, the Running Processes tab will display a snapshot about current processes that device is running and their resource load, provided that device supports process snapshots. Additionally, the Device Details tab will list what features are available on that device.

Launching Projects on Devices

The Platforms dropdown has a Quick Launch section, and you can click one of the devices listed here to immediately install and launch a build on it using the default settings.



Quick Launch options are also available in the dropdown menu for the Play button.



Project Launcher

For advanced use cases, you can also click the Project Launcher button in the Platforms dropdown to bring up the Project Launcher window.



This menu will show any devices that you have set up using the Device Manager, and you can configure the profile that you want to use to launch it. By default the variant field is displayed, but toggling the Advanced button will show the project configuration and cooking settings. The Custom Launch Profiles menu enables you to set up custom profiles with detailed packaging and deployment options for even more advanced use cases on specific projects.



Accessing the Turnkey Commandline

Installing SDKs

Verifying SDKs

Executing Builds

Installing Builds

Help

Listing Platform Information

List SDKs

Managing Settings

Controlling Devices

Testing Turnkey

Turnkey is an Unreal AutomationTool (UAT) script accessed from RunUAT.bat. While the tools to use Turnkey from inside Unreal Editor will be sufficient for most users, the commandline provides more detailed and advanced options for managing SDKs. This guide will show you how to access the Turnkey commandline, and provide a reference for its various options.

Accessing the Turnkey Commandline

To access Turnkey with a commandline, follow these steps:

Open your commandline of choice, such as the Windows command prompt.

Navigate to your Unreal Engine install directory.

Input RunUAT.bat turnkey to run Turnkey.

The commandline will spend a few moments building the AutomationTool, then start the Turnkey script and show a list of numbered commands.



From this menu, you can input the number corresponding to a command and press Enter to run it. Most of these commands will display a submenu with additional options specific to that command.

In all menus, entering 0 will cancel the current operation. If you choose to cancel in a submenu you will navigate back to the main Turnkey menu, while if you cancel in the main menu it will stop the script and exit. The sections below list the other available commands and their submenus.

Using Turnkey Commandline Arguments

Alternatively, when you run the .bat file, you can add a series of specifiers to skip these prompts and immediately run the command. Use the argument -command=[command name] to select a command, then provide additional specifiers to handle the other options.

For example, the following input would run the InstallSdk command, with the platform set to Android:

For information about the available specifiers for each command, refer to the sections below.

Installing SDKs

When you use the InstallSdk command, Turnkey will prompt you to select what SDK type you want to install.



The options are as follows:

Full or Auto Sdk will attempt to install either an AutoSDK or a Full SDK, and will select an AutoSDK if it is available.

Full Sdk will download a Full SDK available for your project, featuring the full array of components.

AutoSdk will attempt to install an AutoSDK, if it is available.

Device Software / Flash will download the most appropriate Flash SDK available for your project, featuring only components necessary for flashing dev kits and testing.

If Turnkey does not find your selected SDK type, it will abort the operation and throw an error.

After choosing your SDK type, Turnkey will also prompt you to select which platform's SDK you want to install.



Enter the number for the platform you want to set up, and Turnkey will initiate the download and installation process for that platform's SDKs. If no SDK is available the process will fail, provide an error message, and navigate back to the main menu.

Specifiers

The following specifiers are compatible when using -command=InstallSdks in the commandline.

Specifier

Description

-Platform=

Selects a platform. Use the name of the platform as seen in the prompt for platform selection. For example, -Platform=Win64 would be valid, while -Platform=Windows would not. When you use this specifier, it will skip the platform selection submenu.

-Platform=All will iterate through all available platforms.



-NeededOnly

Specifies that Turnkey should look for an AutoSDK as the SDK type.

-BestAvailable

Specifies that Turnkey should look for a Full SDK as the SDK type. When combined with -NeededOnly, it will look for either a Full SDK or an AutoSDK.

-UpdateOnly

Specifies that Turnkey should update an already installed SDK rather than perform the full installation.

The Auto Install All Needed SDKs command will run Turnkey with the specifiers -command=InstallSdk -Platform=All -NeededOnly -BestAvailable. This is equivalent to choosing a Full or Auto SDK and selecting All of the Above for your platform.

The Auto Update Installed Sdks command will run Turnkey with the specifiers -command=InstallSdk -Platform=All -UpdateOnly -BestAvailable.

Verifying SDKs

The VerifySdk command will prompt you to select the platform whose SDK you want to verify. Turnkey will then output information about the current SDK installation and check that it matches the parameters that Unreal Engine expects.



Specifiers

-command=VerifySdk is compatible with the -Platform= specifier.

Executing Builds

The ExecuteBuild command builds a project for a selected platform. Selecting this option will bring up a list of target platforms, followed by another prompt listing the available projects to build.



Projects are based on recognized .uproject names. For instance, ShooterGame is listed as a sample project. Once you select your platform and project, Turnkey will initiate the cooking and packaging process for your project.

Specifiers

-command=ExecuteBuild is compatible with the -platform= specifier. It can also use the -project= specifier to select a recognized project name and skip the prompt for selecting one. For example, the following input will attempt to build ShooterGame for the Win64 platform:

Installing Builds

The functionality for installing builds with Turnkey is a work in progress in the Early Access build for UE5, and we are improving its reliability in the final release.

The InstallBuild command will bring up a list of previously created builds that are ready to install to devices, as well as a list of valid devices connected to your computer. Once you have selected both, Turnkey will install your build to the selected device.

Specifiers

-command=InstallBuild is compatible with the -platform= specifier. It can also use the -device= specifier. The format for devices is [Platform Type]@[Device Name], where the platform type is a platform recognized by Turnkey, and the device name is the ID of a device that is visible to your computer. For example: -device=Android@ABCXYZ123. You can use ListPlatforms to see a list of devices and their IDs.

Help

The Help command opens a help menu that provides information about how to set up and use Turnkey. This includes information about how to format FileSource entries in TurnkeyManifest.xml, and the specific versioning formats for some platforms.

Listing Platform Information

The ListPlatforms command lists information about SDKs and devices set up for a selected platform. This includes information about SDK versions that are compatible with your current version of Unreal as well as visible devices on your network.



Specifiers

-command=ListPlatforms is compatible with the -platform= specifier.

List SDKs

The ListSdks command will output a list of the SDKs available in your FileSource repository. Turnkey will prompt you to select a platform you want to list SDKs for.

Specifiers

-command=ListSdks is compatible with the -platform= specifier.

Managing Settings

The ManageSettings command will display a series of variables you can configure. These are related to copy provider settings for your organization as well as credentials for specific platforms. These variables are normally located in multiple different files, such as MobileProvision.ini or your TurnkeyStudioSettings.xml file, but this command provides a centralized place to override them.

Specifiers

-command=ManageSettings is compatible with the -ListOnly specifier. This will output a list of all the variables you can configure, along with descriptions of what each of them does. The List Settings command in the Turnkey menu runs -command=ManageSettings -ListOnly.

Controlling Devices

The Control command brings up a menu that can control devices remotely. After you select a platform, it will display all of the devices matching that platform that are visible to your computer.



You can then turn the device on or off, reboot it, or connect/disconnect it. This functionality is the same as seen in the Device Manager inside the Unreal Editor.

Testing Turnkey

The Test command will run a diagnostic test to ensure that your environment is set up correctly. The test will attempt to connect to the copy provider of your choice and check for needed directories. If any part of the process fails, it will report errors.



Modular Architecture

Topics

UnrealBuildTool (UBT) is a custom tool that manages the process of building Unreal Engine (UE) source code across a variety of build configurations. Read BuildConfiguration.cs to explore various user-configurable build options.

Modular Architecture

UE is split into many modules. Each module has a .build.cs file that controls how it is built, including options for defining module dependencies, additional libraries, include paths, etc. By default, these modules are compiled into DLLs and loaded by a single executable. You can choose to build a monolithic executable in the BuildConfiguration.cs file.

It is important to understand that the build process executes independently of any project files for the development environment, such as .sln or .vcproj files (for Visual Studio). These files are useful to have for editing purposes though, so there is a tool being provided to generate them dynamically (based on the contents of your project directory tree). You can run this tool with the GenerateProject.bat file located in your [Unreal Engine Root Directory].

Note: Running GenerateProject.bat from time-to-time will keep your code editor up-to-date with files that are being added to (or being removed) from disk.

Topics



An overview of UBT Targets, including property descriptions.



An overview of Unreal Build Tool Modules, including property descriptions.



Configure how the engine is built.



A brief overview of the code base for Unreal Engine, using an Include-What-You-Use (IWYU) dependency model.



A guide to automatically generate project files for games and modules in the current workspace.



Reference for Unreal Engine's BuildID system, which mitigates potential errors that may result from outdated DLL files.



Integrating third-party libraries into Unreal Engine



Unreal Build Tool supports running a variety of static code analyzers.

Read-Only Properties

Read/Write Properties

Unreal Build Tool (UBT) supports building several target types:

Game - A standalone game which requires cooked data to run.

Client - Same as Game, but does not include any server code. Useful for networked games.

Server - Same as Game, but does not include any client code. Useful for dedicated servers in networked games.

Editor - A target which extends the Unreal Editor.

Program - A standalone utility program built on top of the Unreal Engine.

Targets are declared through C# source files with a .target.cs extension, and are stored under your project's root directory. Each .target.cs file declares a class deriving from the TargetRules base class, and sets properties controlling how it should be built from its constructor. When asked to build a target, Unreal Build Tool will compile your .target.cs file and construct the class inside it to determine its settings.

The name of the class must match the name of the file it is declared in followed by 'Target' (so for example, MyProject.target.cs defines the class MyProjectTarget).

The typical structure for a target file is as follows:

Read-Only Properties

Platform that this target is being built for.

The configuration being built.

Architecture that the target is being built for (or an empty string for the default).

Path to the project file for the project containing this target.

The current build version.

Whether this is a low level test target.

Whether this is a test target explicitly defined. Explicitly defined test targets always inherit from TestTargetRules and define their own tests. Implicit test targets are created from existing targets when building with -Mode=Test and they include tests from all dependencies.

Controls the value of WITH_LOW_LEVEL_TESTS that dictates whether module-specific low level tests are compiled in or not.

Gets the host platform being built on.

Expose the bGenerateProjectFiles flag to targets, so we can modify behavior as appropriate for better intellisense.

Indicates whether target rules should be used to explicitly enable or disable plugins. Usually not needed for project generation unless project files indicate whether referenced plugins should be built or not.

Expose a setting for whether or not the engine is installed.

Read/Write Properties

The type of target.

Force the include order to a specific version. Overrides any Target and Module rules.

Path to the output file for the main executable, relative to the Engine or project directory. This setting is only typically useful for non-UE programs, since the engine uses paths relative to the executable to find other known folders (for example, Content).

Whether the target uses Steam.

Whether the target uses CEF3.

Whether the project uses visual Slate UI (as opposed to the low level windowing/messaging, which is always available).

Forces linking against the static CRT. This is not fully supported across the engine due to the need for allocator implementations to be shared (for example), and TPS libraries to be consistent with each other, but can be used for utility programs.

Enables the debug C++ runtime (CRT) for debug builds. By default we always use the release runtime, since the debug version isn't particularly useful when debugging Unreal Engine projects, and linking against the debug CRT libraries forces our third party library dependencies to also be compiled using the debug CRT (and often perform more slowly). Often it can be inconvenient to require a separate copy of the debug versions of third party static libraries simply so that you can debug your program's code.

Whether the output from this target can be publicly distributed, even if it has dependencies on modules that are in folders with special restrictions (eg. CarefullyRedist, NotForLicensees, NoRedist).

Specifies the configuration whose binaries do not require a -Platform-Configuration suffix.

Build all the modules that are valid for this target type. Used for CIS and making installed engine builds.

Set this to reference a VSTest run settings file from generated projects.

Additional plugins that are built for this target type but not enabled.

If this is true, then the BuildPlugins list will be used to populate RuntimeDependencies, rather than EnablePlugins.

A list of additional plugins which need to be included in this target. This allows referencing non-optional plugin modules which cannot be disabled, and allows building against specific modules in program targets which do not fit the categories in ModuleHostType.

Additional plugins that should be included for this target.

List of plugins to be disabled for this target. Note that the project file may still reference them, so they should be marked as optional to avoid failing to find them at runtime.

A list of Plugin names that are allowed to exist as dependencies without being defined in the uplugin descriptor.

Path to the set of PAK signing keys to embed in the executable.

Allows a Program Target to specify its own solution folder path.

Whether the target should be included in the default solution build configuration. Setting this to false will skip building when running in the IDE.

Whether this target should be compiled as a Dynamic-link library (DLL). Requires LinkType to be set to TargetLinkType.Monolithic.

Extra subdirectory to load config files out of, for making multiple types of builds with the same platform. This will get baked into the game executable as CUSTOM_CONFIG and used when staging to filter files and settings.

Subfolder to place executables in, relative to the default location.

Allow the target module to override Unreal Header Tool (UHT) code generation version.

Whether to enable the mesh editor.

Whether to compile the Chaos physics plugin.

Whether to use the Chaos physics interface. This overrides the physx flags to disable APEX and NvCloth.

Whether to compile in checked chaos features for debugging.

Whether to compile in chaos memory tracking features.

Whether scene query acceleration is done by UE. The physx scene query structure is still created, but we do not use it.

Whether to include PhysX support.

Whether to include PhysX APEX support.

Whether to include NvCloth.

Whether to include ICU unicode/i18n support in Core.

Whether to compile CEF3 support.

Whether to compile using ISPC.

Whether to compile IntelMetricsDiscovery.

Whether to compile in python support.

Whether to use Iris.

Whether to force compiling the target platform modules, even if they would not normally be built.

Whether to force compiling shader format modules, even if they would not normally be built.

Override for including extra shader formats.

Whether we should compile SQLite using the custom "Unreal" platform (true), or using the native platform (false).

Whether to utilize cache freed OS allocations with MallocBinned.

Whether to compile Recast navmesh generation.

Whether to compile with navmesh segment links.

Whether to compile with navmesh cluster links.

Enable exceptions for all modules.

Enable inlining for all modules.

Enable exceptions for all modules.

Enable RTTI for all modules.

Whether to include stats support even without the engine.

Whether to include plugin support.

Whether to allow accessibility code in both Slate and the OS layer.

Whether to enable support for live coding.

Whether to enable support for DirectX Math. (This feature is no longer supported.)

Whether to turn on logging for test/shipping builds.

Whether to turn on logging to memory for test/shipping builds.

Whether to check that the process was launched through an external launcher.

Whether to turn on checks (asserts) for test/shipping builds.

Whether to turn on UTF-8 mode, mapping TCHAR to UTF8CHAR.

Whether to use the EstimatedUtcNow or PlatformUtcNow. EstimatedUtcNow is appropriate in cases where PlatformUtcNow can be slow.

True if we need FreeType support.

True if we want to favor optimizing size over speed.

Allows fine tuning optimizations level for speed and\or code size

Whether to compile development automation tests.

Whether to compile performance automation tests.

Whether to override the defaults for automation tests (Debug/Development configs).

If true, event driven loader will be used in cooked builds.

Used to override the behavior controlling whether UCLASSes and USTRUCTs are allowed to have native pointer members, if disallowed they will be a UHT error and should be substituted with TObjectPtr members instead.

Whether the XGE controller worker and modules should be included in the engine build. These are required for distributed shader compilation using the XGE interception interface.

Enables "include what you use" by default for modules in this target. Changes the default PCH mode for any module in this project to PCHUsageMode.UseExplicitOrSharedPCHs.

Enforce "include what you use" rules; warns if monolithic headers (for example, Engine.h, UnrealEd.h, and so on) are used, and checks that source files include their matching header first.

Make static libraries for all engine modules as intermediates for this target.

Whether we should compile with support for OS X 10.9 Mavericks. Used for some tools that we need to be compatible with this version of OS X.

True if this is a console application that is being built.

True if debug symbols that are cached for some platforms should not be created.

Whether to force C++ source files to be combined into larger files for faster compilation.

Whether to merge module and generated unity files for faster compilation.

Use a heuristic to determine which files are currently being iterated on and exclude them from unity blobs, resulting in faster incremental compile times. The current implementation uses the read-only flag to distinguish the working set, assuming that files will be made writable by the source control system if they are being modified. This is true for Perforce, but not for Git.

Disable optimization for files that are in the adaptive non-unity working set.

Disables force-included PCHs for files that are in the adaptive non-unity working set.

Creates a dedicated PCH for each source file in the working set, allowing faster iteration on cpp-only changes.

Creates a dedicated PCH for each source file in the working set, allowing faster iteration on cpp-only changes.

Creates a dedicated source file for each header file in the working set to detect missing includes in headers.

The number of source files in a game module before unity build will be activated for that module. This allows small game modules to have faster iterative compile times for single files, at the expense of slower full rebuild times. This setting can be overridden by the bFasterWithoutUnity option in a module's Build.cs file.

Forces shadow variable warnings to be treated as errors on platforms that support it.

Whether to enable all warnings as errors. UE enables most warnings as errors already, but disables a few (such as deprecation warnings).

Indicates what warning/error level to treat unsafe type casts as on platforms that support it (for example, double->float or int64->int32).

Forces the use of undefined identifiers in conditional expressions to be treated as errors.

Forces frame pointers to be retained this is usually required when you want reliable callstacks (for example, mallocframeprofiler).

New Monolithic Graphics drivers have optional "fast calls" replacing various D3d functions.

An approximate number of bytes of C++ code to target for inclusion in a single unified C++ file.

Whether to stress test the C++ unity build robustness by including all C++ files files in a project from a single unified file.

Whether to add additional information to the unity files, such as '_of_X' in the file name.

Whether to force debug info to be generated.

Whether to globally disable debug info generation; see DebugInfoHeuristics.cs for per-config and per-platform options.

Whether to disable debug info generation for generated files. This improves link times for modules that have a lot of generated glue code.

Whether to disable debug info on PC/Mac in development builds (for faster developer iteration, as link times are extremely fast with debug info disabled).

Whether PDB files should be used for Visual C++ builds.

Whether PCH files should be used.

Set flags required for deterministic linking (experimental, may not be fully supported). Deterministic compiling is controlled via ModuleRules.cs.

Force set flags required for deterministic compiling and linking (experimental, may not be fully supported). This setting is only recommended for testing, instead:

Whether to just preprocess source files for this target, and skip compilation.

Generate dependency files by preprocessing. This is only recommended when distributing builds as it adds additional overhead.

Whether static code analysis should be enabled.

The output type to use for the static analyzer. This is only supported for Clang.

The mode to use for the static analyzer. This is only supported for Clang. Shallow mode completes quicker but is generally not recommended.

The minimum number of files that must use a pre-compiled header before it will be created and used.

When enabled, a precompiled header is always generated for game modules, even if there are only a few source files in the module. This greatly improves compile times for iterative changes on a few files in the project, at the expense of slower full rebuild times for small game projects. This can be overridden by setting MinFilesUsingPrecompiledHeaderOverride in a module's Build.cs file.

Whether to use incremental linking or not. Incremental linking can yield faster iteration times when making small changes. Currently disabled by default because it tends to behave a bit buggy on some computers (PDB-related compile errors).

Whether to allow the use of link time code generation (LTCG).

When Link Time Code Generation (LTCG) is enabled, whether to prefer using the lighter weight version on supported platforms.

Whether to enable Profile Guided Optimization (PGO) instrumentation in this build.

Whether to optimize this build with Profile Guided Optimization (PGO).

Whether to support edit and continue. Only works on Microsoft compilers.

Whether to omit frame pointers or not. Disabling is useful for memory profiling on the PC.

Whether to enable support for C++20 modules.

Whether to enable support for C++20 coroutines This option is provided to facilitate evaluation of the feature. Expect the name of the option to change. Use of coroutines within UE is untested and unsupported.

If true, then enable memory profiling in the build (defines USE_MALLOC_PROFILER=1 and forces bOmitFramePointers=false).

Enables "Shared PCHs", a feature which significantly speeds up compile times by attempting to share certain PCH files between modules that UBT detects, including those PCH's header files.

True if Development and Release builds should use the release configuration of PhysX/APEX.

True if Development and Release builds should use the checked configuration of PhysX/APEX. If bUseShippingPhysXLibraries is true this is ignored.

Tells the UBT to check if the module currently being built is violating EULA.

Tells the UBT to break the build if the module currently being built is violating EULA.

Whether to use the :FASTLINK option when building with /DEBUG to create local PDBs on Windows. Fast, but currently seems to have problems finding symbols in the debugger.

Outputs a map file as part of the build.

True if runtime symbols files should be generated as a post build step for some platforms. These files are used by the engine to resolve symbol names of call stack backtraces in logs.

Package full path (directory + filename) where to store input files used at link time. Normally used to debug a linker crash for platforms that support it.

Directory where to put crash report files for platforms that support it.

Bundle version for Mac apps.

Whether to deploy the executable after compilation on platforms that require deployment.

When enabled, allows XGE to compile pre-compiled header (PCH) files on remote machines. Otherwise, PCHs are always generated locally.

Whether headers in system paths should be checked for modification when determining outdated actions.

Whether to disable linking for this target.

Whether to ignore tracking build outputs for this target.

Indicates that this is a formal build, intended for distribution. This flag is automatically set to true when Build.version has a changelist set. The only behavior currently bound to this flag is to compile the default resource file separately for each binary so that the OriginalFilename field is set correctly. By default, we only compile the resource once to reduce build times.

Whether to clean Builds directory on a remote Mac before building.

Whether to write detailed timing info from the compiler and linker.

Whether to parse timing data into a tracing file compatible with chrome://tracing.

Whether to expose all symbols as public by default on POSIX platforms.

Allows overriding the toolchain to be created for this target. This must match the name of a class declared in the Unreal Build Tool (UBT) assembly.

Whether to allow engine configuration to determine if we can load unverified certificates.

Whether to load generated .ini files in cooked build, (GameUserSettings.ini loaded either way).

Whether to load non-ufs ini files in cooked build, (GameUserSettings.ini loaded either way).

Which C++ standard to use for compiling this target.

Which C standard to use for compiling this target.

The build version string.

Macros to define globally across the whole target.

Macros to define across all macros in the project.

Specifies the path to write a header containing public definitions for this target. Useful when building a DLL to be consumed by external build processes.

List of additional modules to be compiled into the target.

Path to a manifest to output for this target.

Path to a list of dependencies for this target, when precompiling.

Whether to ignore violations to the shared build environment (eg. editor targets modifying definitions).

Specifies a list of targets which should be built before this target is built.

Specifies a list of steps which should be executed before this target is built, in the context of the host platform's shell. The following variables will be expanded before execution: $(EngineDir), $(ProjectDir), $(TargetName), $(TargetPlatform), $(TargetConfiguration), $(TargetType), $(ProjectFile).

Specifies a list of steps which should be executed after this target is built, in the context of the host platform's shell. The following variables will be expanded before execution: $(EngineDir), $(ProjectDir), $(TargetName), $(TargetPlatform), $(TargetConfiguration), $(TargetType), $(ProjectFile).

Specifies additional build products produced as part of this target.

Additional arguments to pass to the compiler.

Additional arguments to pass to the linker.

Max amount of memory that each compile action may require. Used by ParallelExecutor to decide the maximum number of parallel actions to start at one time.

List of modules for which to disable unity builds.

List of modules for which to enable optimizations.

List of modules for which to disable optimizations.

When generating project files, specifies the name of the project file to use when there are multiple targets of the same type.

If this is non-null, then any platforms NOT listed will not be allowed to have modules in their directories be created.

The name of this target.

Specifies the engine version to maintain backwards-compatible default build settings with (for example, DefaultSettingsVersion.Release_4_23, DefaultSettingsVersion.Release_4_24). Specify DefaultSettingsVersion.Latest to always use defaults for the current engine version, at the risk of introducing build errors while upgrading.

What version of include order to use when compiling this target. Can be overridden via -ForceIncludeOrder on the command line. ModuleRules.IncludeOrderVersion takes precedence.

Whether this target supports hot reload.

Whether to compile with WITH_GAMEPLAY_DEBUGGER enabled and use GameplayDebugger.

Whether we are compiling editor code or not. Prefer the more explicit bCompileAgainstEditor instead.

Whether to compile code related to building assets. Consoles generally cannot build assets. Desktop platforms generally can.

Whether to compile WITH_EDITORONLY_DATA disabled. Only Windows will use this, other platforms force this to false.

Whether to compile the developer tools.

Whether to compile the developer tools that are for target platforms or connected devices (defaults to bBuildDeveloperTools).

Whether we should include any extra shader formats. By default this is only enabled for Program and Editor targets.

Enabled for all builds that include the engine project. Disabled only when building standalone apps that only link with Core.

Enabled for all builds that include the CoreUObject project. Disabled only when building standalone apps that only link with Core.

Enabled for builds that need to initialize the ApplicationCore module. Command line utilities do not normally need this.

Enabled for editor builds (TargetType.Editor). Can be overridden for programs (TargetType.Program) that would need to compile against editor code. Not available for other target types. Mainly drives the value of WITH_EDITOR.

Whether or not we should compile in support for SpeedTree.

Compile server-only code.

Compile with FName storing the number part in the name table. Saves memory when most names are not numbered and those that are are referenced multiple times. The game and engine must ensure they reuse numbered names similarly to name strings to avoid leaking memory.

When enabled, Push Model Networking support will be compiled in. This can help reduce CPU overhead of networking, at the cost of more memory. Always enabled in editor builds.

Whether to allow plugins which support all target platforms.

Whether to include PerfCounters support.

Whether to enable support for live coding.

Whether the final executable should export symbols.

If true, creates an additional console application. Hack for Windows, where it is not possible to conditionally inherit a parent's console Window depending on how the application is invoked; you have to link the same executable with a different subsystem setting.

Whether to unify C++ code into larger files for faster compilation.

Whether to disable force-included PCHs for project source files in the adaptive non-unity working set. Defaults to bAdaptiveUnityDisablesPCH.

Default treatment of uncategorized warnings.

Level to report deprecation warnings as errors.

Forces frame pointers to be retained; this is usually required when you want reliable callstacks (for example, mallocframeprofiler).

Add all the public folders as include paths for the compile environment.

Specifies how to link modules in this target (monolithic or modular). This is currently protected for backwards compatibility. Call the GetLinkType() accessor until support for the deprecated ShouldCompileMonolithic() override has been removed.

Specifies the name of the launch module. For modular builds, this is the module that is compiled into the target's executable.

Specifies the build environment for this target. See TargetBuildEnvironment for more information on the available options.

Read-Only Properties

Read/Write Properties

Modules are the building blocks of Unreal Engine (UE). The engine is implemented as a large collection of modules, and games supply their own modules to augment them. Each module encapsulates a set of functionality, and can provide a public interface and compile environment (with macros, include paths, and so on) for use by other modules.

Modules are declared through C# source files with a .build.cs extension, and are stored under your project's Source directory. The C++ source code belonging to a module is stored next to to the .build.cs file, or in subdirectories of it. Each .build.cs file declares a class deriving from the ModuleRules base class, and sets properties controlling how it should be built from its constructor. These .build.cs files are compiled by Unreal Build Tool (UBT) and constructed to determine the overall compile environment.

The typical structure for a .build.cs file is as follows.

Read-Only Properties

Returns true if a Plugin contains this module.

Returns true if there has been an override type specified on this module.

The AutoSDK directory for the active host platform.

The current engine directory.

Property for the directory containing this plugin. Useful for adding paths to third party dependencies.

Property for the directory containing this module. Useful for adding paths to third party dependencies.

Returns module's low level tests directory Tests.

Optional compilation order override rules for module's source files.

Returns if VcPkg is supported for the build configuration.

Read/Write Properties

Type of module.

Subfolder of Binaries/PLATFORM folder to put this module in when building Dynamic-Link Libraries (DLLs). This should only be used by modules that are found via searching like the TargetPlatform or ShaderFormat modules. If FindModule is not used to track them down, the modules will not be found.

Explicit private Precompiled Header (PCH) for this module. Implies that this module will not use a shared PCH.

Header file name for a shared PCH provided by this module. Must be a valid relative path to a public C++ header file. This should only be set for header files that are included by a significant number of other C++ modules.

Specifies an alternate name for intermediate directories and files for intermediates of this module. Useful when hitting path length limitations.

Whether this module should be treated as an engine module (for example, using engine definitions, PCHs, compiled with optimizations enabled in DebugGame configurations). Initialized to a default based on the rules assembly it was created from.

Set flags for deterministic compiles (experimental, may not be fully supported). Deterministic linking is controlled via TargetRules.

Use run time type information.

Direct the compiler to generate AVX instructions wherever SSE or AVX intrinsics are used, on the platforms that support it. Note that by enabling this you are changing the minspec for the PC platform, and the resultant executable will crash on machines without AVX support.

Enable buffer security checks. This should usually be enabled as it prevents severe security risks.

Enable exception handling.

Enable Objective-C exception handling.

Enable warnings for using undefined identifiers in #if expressions.

The static analyzer checkers that should be enabled rather than the defaults. This is only supported for Clang. For a full list, see Clang Checkers in the Clang documentation. You can also run clang -Xclang -analyzer-checker-help, or clang -Xclang -analyzer-checker-help-alpha for the list of experimental checkers.

The static analyzer default checkers that should be disabled. Unused if StaticAnalyzerCheckers is populated. This is only supported for Clang. This overrides the default disabled checkers, which are deadcode.DeadStores and security.FloatLoopCounter. For a full list, see Clang Checkers in the Clang documentation. You can also run clang -Xclang -analyzer-checker-help, or clang -Xclang -analyzer-checker-help-alpha for the list of experimental checkers.

The static analyzer non-default checkers that should be enabled. Unused if StaticAnalyzerCheckers is populated. This is only supported for Clang. For a full list, see Clang Checkers in the Clang documentation. You can also run clang -Xclang -analyzer-checker-help, or clang -Xclang -analyzer-checker-help-alpha for the list of experimental checkers.

Whether to merge the module and generated unity files for faster compilation.

The number of source files in this module before unity build will be activated for that module. If set to anything besides -1, will override the default setting which is controlled by MinGameModuleSourceFilesForUnityBuild.

Overrides BuildConfiguration.MinFilesUsingPrecompiledHeader if non-zero.

Module uses a #import so must be built locally when compiling with SN-DBS.

Redistribution override flag for this module.

Whether the output from this module can be publicly distributed, even if it has code/dependencies on modules that are not (for example, CarefullyRedist, NotForLicensees, NoRedist). This should be used when you plan to release binaries but not source.

List of folders which are allowed to be referenced when compiling this binary, without propagating restricted folder names.

Set of aliased restricted folder references.

Enforce "Include What You Use" (IWYU) rules when PCHUsage is set to ExplicitOrSharedPCH; warns when monolithic headers (for example, Engine.h, UnrealEd.h, and so on) are used, and checks that source files include their matching header first.

Whether to add all the default include paths to the module (for example, the Source/Classes folder, subfolders under Source/Public).

Whether to ignore dangling (for example, unresolved external) symbols in modules.

Whether this module should be precompiled. Defaults to the bPrecompile flag from the target. Clear this flag to prevent a module being precompiled.

Whether this module should use precompiled data. Always true for modules created from installed assemblies.

Whether this module can use PLATFORM_XXXX style defines, where XXXX is a confidential platform name. This is used to ensure engine or other shared code does not reveal confidential information inside an #if PLATFORM_XXXX block. However, Licensee game code may want to allow for them.

List of modules names (no path needed) with header files that our module's public headers needs access to, but we don't need to "import" or link against.

List of public dependency module names (no path needed) (automatically does the private/public include). These are modules that are required by our public source files.

List of modules name (no path needed) with header files that our module's private code files needs access to, but we don't need to "import" or link against.

List of private dependency module names. These are modules that our private code depends on but nothing in our public include files depend on.

Only for legacy reasons, should not be used in new code. List of module dependencies that should be treated as circular references. These modules must have already been added to either the public or private dependent module list.

List of system/library include paths - typically used for External (third party) modules. These are public stable header file directories that are not checked when resolving header dependencies.

List of all paths to include files that are exposed to other modules. (This setting is currently not needed as we discover all files from the Public folder).

List of all paths to include files that are exposed to other internal modules. (This setting is currently not needed as we discover all files from the Internal folder).

List of all paths to this module's internal include files, not exposed to other modules (at least one include to the Private path, more if we want to avoid relative paths).

List of system library paths (directory of .lib files) - for External (third party) modules please use the PublicAdditionalLibaries instead.

List of search paths for libraries at runtime (for example, .so files).

List of search paths for libraries at runtime (for example, .so files).

List of additional libraries (names of the .lib files including extension) - typically used for External (third party) modules.

List of additional pre-build libraries (names of the .lib files including extension) - typically used for additional targets which are still built, but using either TargetRules.PreBuildSteps or TargetRules.PreBuildTargets.

List of system libraries to use - these are typically referenced via name and then found via the system paths. If you need to reference a .lib file use the PublicAdditionalLibraries instead.

List of XCode frameworks (iOS and MacOS).

List of weak frameworks (for OS version transitions).

List of additional frameworks - typically used for External (third party) modules on Mac and iOS.

List of additional resources that should be copied to the app bundle for Mac or iOS.

List of type libraries that we need to generate headers for (Windows only).

List of delay load DLLs - typically used for External (third party) modules.

Private compiler definitions for this module.

Public compiler definitions for this module.

Additional modules this module may require at run-time.

List of files which this module depends on at runtime. These files will be staged along with the target.

List of additional properties to be added to the build receipt.

Which targets this module should be precompiled for.

External files which invalidate the makefile if modified. Relative paths are resolved relative to the .Build.cs file.

Subclass rules files which invalidate the makefile if modified.

Whether this module requires the IMPLEMENT_MODULE macro to be implemented. Most UE modules require this, since we use the IMPLEMENT_MODULE macro to do other global overloads (for example, operator new/delete forwarding to GMalloc).

Whether circular dependencies will be validated against the allow list circular module dependencies result in slower builds. Disabling this option is strongly discouraged. This option is ignored for Engine modules which will always be validated against the allow list.

Which standard to use for compiling this module.

Which standard to use for compiling this module.

Control visibility of symbols.

Name of this module.

Overridden type of module that will set different package flags. Cannot be used for modules that are a part of a plugin because that is set in the .uplugin file already.

When this module's code should be optimized.

Precompiled header usage for this module.

Which engine version's build settings to use by default.

What version of include order to use when compiling this module. Can be overridden via -ForceIncludeOrder on the command line or in a module's rules.

How to treat shadow variable warnings.

How to treat unsafe implicit type cast warnings (for example, double->float or int64->int32).

If unity builds are enabled this can be used to override if this specific module will be built using Unity. This is set using the per module configurations in BuildConfiguration.cs.

Whether this module qualifies included headers from other modules relative to the root of their Public folder. This reduces the number of search paths that have to be passed to the compiler, improving performance and reducing the length of the compiler command line.

BuildConfiguration

UEBuildConfiguration

WindowsPlatform

ModuleConfiguration

FASTBuild

HordeExecutor

ParallelExecutor

SNDBS

XGE

BuildMode

ProjectFileGenerator

IOSToolChain

WindowsTargetRules

CLionGenerator

CMakefileGenerator

CodeLiteGenerator

EddieProjectFileGenerator

KDevelopGenerator

MakefileGenerator

QMakefileGenerator

RiderProjectFileGenerator

VSCodeProjectFileGenerator

VCMacProjectFileGenerator

VCProjectFileGenerator

XcodeProjectFileGenerator

SourceFileWorkingSet

RemoteMac

HoloLensPlatform

Log

In addition to being added to the generated Unreal Engine (UE) project under the Config/UnrealBuildTool folder, Unreal Build Tool (UBT) reads settings from XML config files in the following locations on Windows:

Engine/Saved/UnrealBuildTool/BuildConfiguration.xml

USER/AppData/Roaming/Unreal Engine/UnrealBuildTool/BuildConfiguration.xml

My Documents/Unreal Engine/UnrealBuildTool/BuildConfiguration.xml

On Linux and Mac, the following paths are used instead:

/Users/USER/.config//Unreal Engine/UnrealBuildTool/BuildConfiguration.xml

/Users/USER/Unreal Engine/UnrealBuildTool/BuildConfiguration.xml

Keep reading to learn more about the following properties, which help to set and customize build configurations.

BuildConfiguration

Whether to ignore import library files that are out of date when building targets. Set this to true to improve iteration time. By default, we do not bother re-linking targets if only a dependent .lib file has changed, as chances are that the import library was not actually different unless a dependent header file of this target was also changed, in which case the target would automatically be rebuilt.

Whether debug info should be written to the console.

Whether the hybrid executor will be used (a remote executor and local executor).

Whether Horde remote compute may be used. (Highly experimental, disabled by default.)

Whether XGE may be used.

Whether FASTBuild may be used.

Whether SN-DBS may be used.

Enables support for very fast iterative builds by caching target data. Turning this on causes Unreal Build Tool (UBT) to emit 'UBT Makefiles' for targets when they are built the first time. Subsequent builds will load these Makefiles and begin outdatedness checking and build invocation very quickly. The caveat is that if source files are added or removed to the project, UBT will need to gather information about those in order for your build to complete successfully. Currently, you must run the project file generator after adding/removing source files to tell UBT to re-gather this information.

Number of actions that can be executed in parallel. If 0 then code will pick a default based on the number of cores and memory available. Applies to the ParallelExecutor, HybridExecutor, and LocalExecutor.

Consider logical cores when determining how many total CPU cores are available.

Instruct the executor to write compact output (for example, only errors), if supported by the executor. This field is used to hold the value when specified from the command line or XML.

Enables the debug C++ runtime (CRT) for debug builds. By default we always use the release runtime, since the debug version isn't particularly useful when debugging Unreal Engine projects, and linking against the debug CRT libraries forces our third party library dependencies to also be compiled using the debug CRT (and often perform more slowly). Often it can be inconvenient to require a separate copy of the debug versions of third party static libraries simply so that you can debug your program's code.

Whether the output from this target can be publicly distributed, even if it has dependencies on modules that are in folders with special restrictions (for example, CarefullyRedist, NotForLicensees, NoRedist).

Enable inlining for all modules.

Whether to enable support for live coding.

Whether the XGE controller worker and modules should be included in the engine build. These are required for distributed shader compilation using the XGE interception interface.

Whether to unify C++ code into larger files for faster compilation.

Whether to force C++ source files to be combined into larger files for faster compilation.

Whether to merge the module and generated unity files for faster compilation.

Use a heuristic to determine which files are currently being iterated on and exclude them from unity blobs, resulting in faster incremental compile times. The current implementation uses the read-only flag to distinguish the working set, assuming that files will be made writable by the source control system if they are being modified. This is true for Perforce, but not for Git.

Disable optimization for files that are in the adaptive non-unity working set.

Disables force-included Precompiled Headers (PCHs) for files that are in the adaptive non-unity working set.

Backing storage for bAdaptiveUnityDisablesProjectPCH.

Creates a dedicated PCH for each source file in the working set, allowing faster iteration on cpp-only changes.

Creates a dedicated PCH for each source file in the working set, allowing faster iteration on cpp-only changes.

Creates a dedicated source file for each header file in the working set to detect missing includes in headers.

The number of source files in a game module before unity build will be activated for that module. This allows small game modules to have faster iterative compile times for single files, at the expense of slower full rebuild times. This setting can be overridden by the bFasterWithoutUnity option in a module's .Build.cs file.

Default treatment of uncategorized warnings

Level to report deprecation warnings as errors

Whether to enable all warnings as errors. UE enables most warnings as errors already, but disables a few (such as deprecation warnings).

Indicates what warning/error level to treat unsafe type casts as on platforms that support it (for example, double->float or int64->int32).

Forces the use of undefined identifiers in conditional expressions to be treated as errors.

Forces frame pointers to be retained. This is usually required when you want reliable callstacks (for example, mallocframeprofiler).

New Monolithic Graphics drivers have optional "fast calls" replacing various D3d functions.

An approximate number of bytes of C++ code to target for inclusion in a single unified C++ file.

Whether to stress test the C++ unity build robustness by including all C++ files files in a project from a single unified file.

Whether to add additional information to the unity files, such as '_of_X' in the file name.

Whether to globally disable debug info generation; see DebugInfoHeuristics.cs for per-config and per-platform options.

Whether to disable debug info generation for generated files. This improves link times for modules that have a lot of generated glue code.

Whether to disable debug info on PC/Mac in development builds (for faster developer iteration, as link times are extremely fast with debug info disabled).

Whether PDB files should be used for Visual C++ builds.

Whether PCH files should be used.

Set flags required for deterministic linking (experimental, may not be fully supported). Deterministic compiling is controlled via ModuleRules.cs.

Force set flags required for deterministic compiling and linking (experimental, may not be fully supported). This setting is only recommended for testing, instead:

Generate dependency files by preprocessing. This is only recommended when distributing builds as it adds additional overhead.

Whether static code analysis should be enabled.

The output type to use for the static analyzer. This is only supported for Clang.

The mode to use for the static analyzer. This is only supported for Clang. Shallow mode completes quicker but is generally not recommended.

The minimum number of files that must use a pre-compiled header before it will be created and used.

When enabled, a precompiled header is always generated for game modules, even if there are only a few source files in the module. This greatly improves compile times for iterative changes on a few files in the project, at the expense of slower full rebuild times for small game projects. This can be overridden by setting MinFilesUsingPrecompiledHeaderOverride in a module's Build.cs file.

Whether to use incremental linking or not. Incremental linking can yield faster iteration times when making small changes. Currently disabled by default because it tends to behave a bit buggy on some computers (PDB-related compile errors).

Whether to allow the use of link time code generation (LTCG).

When Link Time Code Generation (LTCG) is enabled, whether to prefer using the lighter weight version on supported platforms.

Whether to enable Profile Guided Optimization (PGO) instrumentation in this build.

Whether to optimize this build with Profile Guided Optimization (PGO).

Whether to support edit and continue. Only works on Microsoft compilers.

Whether to omit frame pointers or not. Disabling is useful, for example, for memory profiling on the PC.

If true, then enable memory profiling in the build (defines USE_MALLOC_PROFILER=1 and forces bOmitFramePointers=false).

Enables "Shared PCHs", a feature which significantly speeds up compile times by attempting to share certain PCH files between modules that UBT detects are including those PCH's header files.

True if Development and Release builds should use the release configuration of PhysX/APEX.

True if Development and Release builds should use the checked configuration of PhysX/APEX. if bUseShippingPhysXLibraries is true this is ignored.

Tells the UBT to check if the module currently being built is violating EULA.

Tells the UBT to break build if the module currently being built is violating EULA.

Whether to use the :FASTLINK option when building with /DEBUG to create local PDBs on Windows. Fast, but currently seems to have problems finding symbols in the debugger.

Outputs a map file as part of the build.

True if runtime symbols files should be generated as a post build step for some platforms. These files are used by the engine to resolve symbol names of callstack backtraces in logs.

Package full path (directory + filename) where to store input files used at link time. Normally used to debug a linker crash for platforms that support it.

Directory where to put crash report files for platforms that support it.

Whether headers in system paths should be checked for modification when determining outdated actions.

Whether to clean Builds directory on a remote Mac before building.

Whether to write detailed timing info from the compiler and linker.

Whether to parse timing data into a tracing file compatible with chrome://tracing.

Whether to expose all symbols as public by default on POSIX platforms.

Which C++ standard to use for compiling this target.

Which C standard to use for compiling this target.

When enabled, SN-DBS will stop compiling targets after a compile error occurs. Recommended, as it saves computing resources for others.

Whether to use the no_watchdog_thread option to prevent VS2015 toolchain stalls.

Whether to display the XGE build monitor.

When enabled, XGE will stop compiling targets after a compile error occurs. Recommended, as it saves computing resources for others.

Specifies the file to use for logging.

Whether to strip iOS symbols or not (implied by Shipping config).

Enables address sanitizer (ASan). Only supported for Visual Studio 2019 16.7.0 and up.

Enables thread sanitizer (TSan).

Enables undefined behavior sanitizer (UBSan).

Enables memory sanitizer (MSan).

Turns on tuning of debug info for LLDB.

Enables the generation of .dsym files. This can be disabled to enable faster iteration times during development.

Whether to write a solution option (suo) file for the .sln.

Whether to write a .vsconfig file next to the sln to suggest components to install.

Whether to add the -FastPDB option to build command lines by default.

Whether to generate per-file intellisense data.

Whether to include a dependency on ShaderCompileWorker when generating project files for the editor.

UEBuildConfiguration

If true, force header regeneration. Intended for the build machine.

If true, do not build Unreal Header Tool (UHT), assume it is already built.

If true, fail if any of the generated header files is out of date.

True if hot-reload from IDE is allowed.

If true, the Debug version of Unreal Header Tool (UHT) will be built and run instead of the Development version.

If true, use Unreal Header Tool (UHT) internal to Unreal Build Tool (UBT).

WindowsPlatform

Maximum recommended root path length.

Maximum length of a path relative to the root directory. Used on Windows to ensure paths are portable between machines. Defaults to off.

Version of the compiler toolchain to use on Windows platform. A value of "default" will be changed to a specific version at UBT start up.

The specific toolchain version to use. This may be a specific version number (for example, "14.13.26128"), the string "Latest" to select the newest available version, or the string "Preview" to select the newest available preview version. By default, and if it is available, we use the toolchain version indicated by WindowsPlatform.DefaultToolChainVersion (otherwise, we use the latest version).

The specific Windows SDK version to use. This may be a specific version number (for example, "8.1", "10.0" or "10.0.10150.0"), or the string "Latest", to select the newest available version. By default, and if it is available, we use the Windows SDK version indicated by WindowsPlatform.DefaultWindowsSdkVersion (otherwise, we use the latest version).

The static analyzer to use.

The output type to use for the static analyzer.

Enables strict standard conformance mode (/permissive-) in Visual Studio 2017 or higher.

Determines the amount of memory that the compiler allocates to construct precompiled headers (/Zm).

Allow the target to specify extra options for linking that are not otherwise noted here.

(Experimental) Appends the -ftime-trace argument to the command line for Clang to output a JSON file containing a timeline for the compile. See the Clang Time Trace documentation for more info.

Outputs compile timing information so that it can be analyzed.

Print out files that are included by each source file.

ModuleConfiguration

List of modules for which to disable unity builds.

List of modules for which to enable optimizations.

List of modules for which to disable optimizations.

FASTBuild

Used to specify the location of fbuild.exe if the distributed binary isn't being used.

Controls network build distribution.

Used to specify the location of the brokerage. If null, FASTBuild will fall back to checking FASTBUILD_BROKERAGE_PATH.

Used to specify the FASTBuild coordinator IP or network name. If null, FASTBuild will fall back to checking FASTBUILD_COORDINATOR.

Controls whether to use caching at all. CachePath and FASTCacheMode are only relevant if this is enabled.

Cache access mode - only relevant if bEnableCaching is true.

Used to specify the location of the cache. If null, FASTBuild will fall back to checking FASTBUILD_CACHE_PATH.

Whether to force remote.

Whether to stop on error.

Which Microsoft Visual C++ (MSVC) C++ Runtime (CRT) Redist version to use.

HordeExecutor

How many processes that will be executed in parallel remotely.

Only run work remotely, for testing.

Retry actions locally when failed remotely.

ParallelExecutor

Maximum processor count for local execution.

Processor count multiplier for local execution. Can be below 1 to reserve CPU for other tasks. When using the local executor (not XGE), run a single action on each CPU core. Note that you can set this to a larger value to get slightly faster build times in many cases, but your computer's responsiveness during compiling may be much worse. This value is ignored if the CPU does not support hyper-threading.

Free memory per action in bytes, used to limit the number of parallel actions if the machine is memory starved. Set to 0 to disable free memory checking.

The priority to set for spawned processes. Valid Settings: Idle, BelowNormal, Normal, AboveNormal, High. Default Setting: BelowNormal.

When enabled, will stop compiling targets after a compile error occurs.

Whether to show compilation times along with the worst offenders or not.

Whether to show compilation times for each executed action.

Whether to log command lines for actions being executed.

Add target names for each action executed.

SNDBS

When set to false, SNDBS will not be enabled when running connected to the coordinator over VPN. Configure VPN-assigned subnets via the VpnSubnets parameter.

List of subnets containing IP addresses assigned by VPN.

XGE

When set to false, XGE will not be enabled when running connected to the coordinator over VPN. Configure VPN-assigned subnets via the VpnSubnets parameter.

List of subnets containing IP addresses assigned by VPN.

Whether to allow remote linking.

Whether to enable the VCCompiler=true setting. This requires an additional license for VC tools.

Minimum number of actions to use XGE execution.

Check for a concurrent XGE build and treat the XGE executor as unavailable if it's in use. This will allow UBT to fall back to another executor such as the parallel executor.

BuildMode

Whether to skip checking for files identified by the junk manifest.

ProjectFileGenerator

Disable native project file generators for platforms. Platforms with native project file generators typically require IDE extensions to be installed.

Default list of project file formats to generate.

True if intellisense data should be generated (takes a while longer).

True if we should include documentation in the generated projects.

True if all documentation languages should be included in generated projects, otherwise only INT files will be included.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if build system files should be included.

True if we should include config (.ini) files in the generated project.

True if we should include localization files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include csharp program projects in the generated solution. Pass -DotNet to enable this.

Whether to include temporary targets generated by Unreal Automation Tool (UAT) to support content only projects with non-default settings.

True if we should reflect Source sub-directories on disk in the primary project as project directories. This adds some visual clutter to the primary project but it is truer to the on-disk file organization.

Names of platforms to include in the generated project files.

Names of configurations to include in the generated project files. See UnrealTargetConfiguration for valid entries.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

Whether we should include configurations for "Test" and "Shipping" in generated projects. Pass -NoShippingConfigs to disable this.

Whether we should include configurations for "Debug" and "DebugGame" in generated projects. Pass -NoDebugConfigs to disable this.

Whether we should include configurations for "Development" in generated projects. Pass -NoDevelopmentConfigs to disable this.

IOSToolChain

The version of the iOS SDK to target at build time.

The version of the iOS to allow at build time.

If this is set, then we do not do any post-compile steps - except moving the executable into the proper spot on Mac.

WindowsTargetRules

Whether we should export a file containing .obj to source file mappings.

CLionGenerator

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include csharp program projects in the generated solution. Pass -DotNet to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

CMakefileGenerator

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include csharp program projects in the generated solution. Pass -DotNet to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

CodeLiteGenerator

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include C# program projects in the generated solution. Pass -DotNet to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

EddieProjectFileGenerator

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include csharp program projects in the generated solution. Pass "-DotNet" to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

KDevelopGenerator

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include csharp program projects in the generated solution. Pass "-DotNet" to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

MakefileGenerator

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include csharp program projects in the generated solution. Pass "-DotNet" to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

QMakefileGenerator

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include csharp program projects in the generated solution. Pass "-DotNet" to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

RiderProjectFileGenerator

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include csharp program projects in the generated solution. Pass "-DotNet" to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

VSCodeProjectFileGenerator

Includes all files in the generated workspace.

Whether VS Code project generation should include debug configurations to allow attaching to already running processes

Whether VS Code project generation should include debug configurations to allow core dump debugging

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include csharp program projects in the generated solution. Pass "-DotNet" to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

VCMacProjectFileGenerator

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include csharp program projects in the generated solution. Pass "-DotNet" to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

VCProjectFileGenerator

The version of Visual Studio to generate project files for.

Puts the most common include paths in the IncludePath property in the MSBuild project. This significantly reduces Visual Studio memory usage (measured 1.1GB -> 500mb), but seems to be causing issues with Visual Assist. Value here specifies maximum length of the include path list in KB.

Semi-colon separated list of paths that should not be added to the projects include paths. Useful for omitting third-party headers (for example, ThirdParty/WebRTC) from intellisense suggestions and reducing memory footprints.

Semi-colon separated list of paths that should not be added to the projects. Useful for omitting third-party files (for example, ThirdParty/WebRTC) from intellisense suggestions and reducing memory footprints.

Forces Unreal Build Tool (UBT) to be built in debug configuration, regardless of the solution configuration.

Whether to include a dependency on LiveCodingConsole when building targets that support live coding.

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets.

True if we should include csharp program projects in the generated solution. Pass "-DotNet" to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

XcodeProjectFileGenerator

True if we should include documentation in the generated projects.

True if build targets should pass the -useprecompiled argument.

True if we should include engine source in the generated solution.

True if shader source files should be included in generated projects.

True if we should include config (.ini) files in the generated project.

True if we should include template files in the generated project.

True if we should include program projects in the generated solution.

Whether to include C++ targets

True if we should include csharp program projects in the generated solution. Pass -DotNet to enable this.

Name of the primary project file - for example, the base file name for the Visual Studio solution file, or the Xcode project file on Mac.

If true, sets the primary project name according to the name of the folder it is in.

SourceFileWorkingSet

Sets the provider to use for determining the working set.

Sets the path to use for the repository. Interpreted relative to the Unreal Engine root directory (the folder above the Engine folder) - if relative.

Sets the path to use for the Git executable. Defaults to "git" (assuming it is in the PATH).

RemoteMac

These two variables will be loaded from the XML config file in XmlConfigLoader.Init().

The remote username.

If set, instead of looking for RemoteToolChainPrivate.key in the usual places (Documents/Unreal, Engine/UnrealBuildTool/SSHKeys or Engine/Build/SSHKeys), this private key will be used.

The authentication used for Rsync (for the -e rsync flag).

The authentication used for SSH (similar to RsyncAuthentication).

HoloLensPlatform

Version of the compiler toolchain to use on HoloLens. A value of "default" will be changed to a specific version at UBT startup.

Log

Whether to backup an existing log file, rather than overwriting it.

The number of log file backups to preserve. Older backups will be deleted.

What it Means to IWYU

IWYU Conventions

Verifying IWYU is Enabled

Running in IWYU Mode

General Tips

Include What You Use (IWYU), as the name implies, means that Unreal Engine (UE) source code only includes the dependencies that it needs to compile. The purpose of IWYU is to avoid including monolithic header files, such as Engine.h or UnrealEd.h, thereby mitigating superfluous dependencies. The following reference guide tells you what it means to IWYU, including a high-level explanation of how to enable IWYU, ensuring that your project adheres to IWYU conventions. Additionally, if you opt into using IWYU mode for your game project or projects, you will learn some general tips that will help you get the most out of working in IWYU mode.

IWYU mode is disabled by default for games and game plugins; however, IWYU mode is enabled by default for the Engine and Engine plugins.

What it Means to IWYU

In previous versions of Unreal Engine, the majority of engine functionality was included via large, module-centric header files, such as Engine.h and UnrealEd.h and fast compile times were dependent on those files being compiled quickly through Precompiled Header (PCH) files. As the engine grew, this became a bottleneck.

With IWYU, every file includes only what it needs, and any PCH file we choose to use, purely acts as a layer of optimization on top of the underlying source files. They can be modified to minimize build times, independently of changing the source files themselves, and without affecting whether the code compiles successfully or not.

When writing IWYU code, there are four specific conventions that we adopt:

All header files include their required dependencies.

*.cpp files include their matching *.h files first.

Precompiled Header (PCH) files are no longer explicitly included.

Monolithic header files are no longer included.

IWYU Conventions

The following descriptions of IWYU conventions should give you a good idea about what it means to IWYU.

All header files include their required dependencies.

There is a Core Minimal header file (CoreMinimal.h) containing a set of ubiquitous types (including FString, FName, TArray, etc.) from UE's Core programming environment.

The CoreMinimal.h header file (located under the UE root directory at \Engine\Source\Runtime\Core\Public\CoreMinimal.h) is included first by most of the Engine's header files.

Within the Core module, most header files include the CoreTypes.h header file first. This only includes typedefs for primitive C++ types, UE build macros, and directives to configure the compile environment.

The main takeaway is that every header file now includes everything that it needs to compile.

*.cpp files include their matching *.h file first.

To verify that all of your source files include all of their required dependencies, compile your game project in non-unity mode with PCH files disabled.

PCH files are no longer explicitly included.

Although PCH files are still used, they're force-included on the compiler command line by Unreal Build Tool (UBT).

Monolithic header files are no longer included.

The compiler will emit a warning if your Engine code includes monolithic header files (such as Engine.h or UnrealEd.h).

Monolithic header files still exist in Unreal Engine for compatibility with game projects, and (by default) a warning will not be emitted if your game projects include them.

Verifying IWYU is Enabled

Before establishing IWYU conventions, UE code typically included a PCH file at the top of every C++ file, which is contrary to what a developer wants their IWYU compliant code to include. Following IWYU conventions, PCH files can be thought of as layers of compile-time optizations that are applied separately from how the code was originally authored. So, rather than composing and including PCH files, we leave it to UBT to decide which PCH file to use (if any).

If you want to verify that IWYU is enabled, ensuring that a module complies with IWYU conventions, open the module's *.build.cs file and verify that PCHUsage is set to PCHUsageMode.UseExplicitOrSharedPCHs.



Setting PCHUsage to PCHUsageMode.UseExplicitOrSharedPCHs creates an explicit PCH file for a module only if it has a PrivatePCHHeaderFile setting in the module's *.build.cs file. Otherwise, the module will share a PCH with another module, saving the tool from generating more PCH files than necessary. Also, keep in mind that when you enable UseExplicitOrSharedPCHs mode, the source file must include its matching header file. Alternatively, if you want a module to opt-out of complying with IWYU conventions, you can set PCHUsage to PCHUsageMode.UseSharedPCHs.



Running in IWYU Mode

If you are running your game in IWYU mode, you will need to ensure that your .cpp file or files include their corresponding .h file or files first. This is a useful practice, because it enables the compiler to ensure that the .h file includes all of its required dependencies (when PCH files and unity builds are disabled). Unreal Build Tool (UBT) will emit a warning if you do not include the matching header file first (for its corresponding .cpp file).

If you want to disable the compiler from emitting warnings, you can set bEnforceIWYU to false in the module's *.build.cs file.



If you want to disable the warning for an entire target, you can set bEnforceIWYU to false in the *.target.cs file.

General Tips

If you want your game to opt-in to IWYU, there are a few tips to keep in mind:

Include CoreMinimal.h at the top of each header file.

To verify that all of your source files include all of their required dependencies, compile your game project in non-unity mode with PCH files disabled.

If you need to access UEngine or GEngine, which are defined in Runtime\Engine\Classes\Engine\Engine.h, you can #include Engine/Engine.h (distinguishing from the monolithic header file, which is located at Runtime\Engine\Public\Engine.h).

If you use a class that the compiler doesn't recognize, and don't know what you need to include may be missing the header file. This is especially the case if you are converting from non-IWYU code that compiled correctly. You can look up the class in the API Documentation, and find the necessary modules and header files at the bottom of the page.

Command-line Options

Additional Information

The following guide is meant for users who have downloaded and built Unreal Engine from its source code, which we have made available on GitHub. For more information, see Downloading Unreal Engine Source Code

If you download the latest Unreal Engine (UE) code, you might notice that there are no Visual Studio (VS) or Xcode project files included for compiling and running the engine or example games. You will need to run a script that generates project files for you to load:

Run the GenerateProjectFiles.bat file which is located in the UE root directory.

The project generator tool will analyze the module and target build files and generate new project files. This may take some time to complete.

For VS developers, this will generate a UE5.sln file in the same directory. You will use this solution file to build and run UE games and programs. For your first time compiling, we recommend building using the Development configuration with Win64 platform.

By default, we generate buildable projects for all available platforms that we detected SDKs for, so that you will be able to build and debug console and mobile platforms as well. If you want to generate projects only for the current platform you are running on (for example, Windows.), run the GenerateProjectFiles.bat with the -CurrentPlatform argument. The project files will be a little lighter.

Remember to re-run GenerateProjectFiles.bat after syncing new code changes from source control. If you forget to do this, you will most likely run into problems when compiling or running your game.

If you make local changes to modules such as adding or removing source files, you should re-run GenerateProjectFiles.bat again. We do not recommend manually making changes to project files.

Command-line Options

The project generator has some optional command-line arguments that you can use if you want to customize your generated project files to suit your needs more closely. Typically these options are not required or recommended.

Option

Description

-CurrentPlatform

Generates buildable projects for only the current desktop platform (Windows or Mac), instead of all detected available target platforms.

-2019

Generates projects in a format native to VS 2019. The Visual C++ 2019 compiler will be used to compile when this option is set.

-2022

Generates projects in a format native to VS 2022. The Visual C++ 2022 compiler will be used to compile when this option is set.

-ThirdParty

Adds headers and other files from third-party libraries to the project. This could be useful if you like to see symbols and files in Visual Assist for PhysX, Steamworks or Bink for example. However, it will make the project files take longer to load.

GAME_NAME -Game

Tells the project generator to generate projects that only include code and content for the specified project name, excluding all other discovered projects. Make sure to specify a project name as well. For example GenerateProjectFiles.bat ShooterGame.uproject -Game would generate projects that only have source and targets for ShooterGame. If you want to include Engine source code and Programs alongside a single game project, you can also pass the -Engine parameter, for example, GenerateProjectFiles.bat ShooterGame.uproject -Game -Engine.

-Engine

When used with -Game, causes Engine code, content, and programs to also be included in the generated solution. This is useful if you think you will need to work with engine source a lot while working on your game project.

-NoIntelliSense

Skips generation of IntelliSense data used for auto-completion and error squiggles in the IDE.

-AllLanguages

Includes engine documentation for all languages. By default, we only include files in the project for English.

-OnlyPublic

When specified, only public header files will be included in the generated projects for Engine modules. By default, all source files are included for Engine modules. This can give you faster project load times, but it might be more difficult to navigate engine code.

-NoShippingConfigs

Omits the Shipping and Test build configurations from the generated projects. This will reduce the number of target configurations you need to deal with.

-Platforms=PLATFORM_1+PLATFORM_2+...

Overrides the default set of platforms to generate buildable projects for, and instead generates projects for the platform or platforms that you specify. You can specify multiple platforms by separating them with a '+' character. This also causes the generated solution file to be named with a suffix that includes the platform name or names.

Additional Information

The GenerateProjectFiles.bat script is a simple wrapper around Unreal Build Tool, which is launched in a special mode that builds project files instead of building program executables. It invokes Unreal Build Tool with the -ProjectFiles command-line option.

The UE build system does not actually require project files to compile the code. Unreal Build Tool always locates source files using module and target build files. For this reason, if you add a new source file and trigger a compile, the new source file may be included in the build even though the project files have not been refreshed yet. Just something to keep in mind.

For VS projects, the generated solution file is UE5.sln and is saved to the root UE directory. However, the project files are saved to the UNREAL_ENGINE_ROOT/Engine/Intermediate/ProjectFiles/ directory. It is safe to delete these files at any time and regenerate projects, however, you may lose certain project-specific preferences such as command-line argument strings if you delete these files.

Advantages of Generate Project Files

There are certainly both pros and cons, but here are some important reasons why we decided to generate project files for UE:

UE is designed to work with many platforms, but different teams may only be working with a few specific platforms at any time. By generating project files, we can omit platform-specific files and build configurations that are not relevant.

UE programming methodology incorporates many sub-modules, and it was very important that we made it as easy as possible for programmers to add new modules.

The project generator emits highly-accurate definitions and includes paths which are used by VS IntelliSense while you are working on UE code.

Setting up a new project is much easier when project files are automatically generated.

We want to support multiple platforms and development environments (for example, VS and Xcode). Maintaining multiple sets of project files manually is error-prone and tedious.

We want to enable programmers to generate highly customized project files.

The directory structure of source files is automatically mirrored in the project file solution hierarchy. This is really convenient when browsing source files, but was difficult to maintain with manually authored projects.

UE build configurations are very complex and are difficult to maintain manually. The project generator makes this nearly transparent to developers.

Other Files Added with Generate Project Files

Along with source code for C++ modules, we automatically add several other files to the generated projects. This is just to make it easy to locate these files when doing searches. Some examples of other files that are added to the generated projects:

Shader source code (*.usf files)

Engine documentation files (*.udn files)

Program configuration files (*.in`i files)

Localization files (*.int files)

Program resource files and manifests (*.rc, .manifest)

Certain external (non-generated) project files (for example, UnrealBuildTool and Clean)

Project Files and Source Control

Project files are not checked in to source control. Merging source control conflicts to project files was tedious and highly error-prone. The new system avoids this entirely by treating project files as pure intermediates. Plus, solution files will be different for each team that is working on different game projects. Chances are that the project files that we use at Epic will not be useful to other teams without modifications.

Debugging Project Generator Code

Here are some useful tips to help you debug changes that you have made to project generator code:

Change your startup project to UnrealBuildTool.

Set the command-line parameters for debugging to -ProjectFiles.

Set the working directory to your local path for UNREAL_ENGINE_ROOT/Engine/Source/.

Compile and debug as normal.

Be aware that the project generator may delete the project files you are using in VS as you are working. For this reason, it is sometimes useful to load the Unreal Build Tool project directly into VS instead of debugging through the regular UE solution file.

Build Multiple Configurations

You can use the Batch Build feature in VS. You can find this under the Build menu. Simply select all of the configurations that you want to compile and click Build.

Integration With UnrealVS Extension

The UnrealVS Extension for VS includes a tool-bar button that you can click to re-generate project files for the currently loaded solution.

You can also bind a shortcut key to this feature. In VS, open Tools > Options > Environment > Keyboard, then search for UnrealVS.RefreshProjects.

Note that this feature is only enabled after you have a solution loaded (because the tool needs to know which code branch to generate projects for). If you have no UE5.sln file generated yet, you will need to run the GenerateProjectFiles.bat script directly first.

Automatically-Generated Build ID

Manually-Specified Build ID

The Unreal Engine (UE) BuildID system mitigates potential errors that may result from outdated DLL files. This system not only prevents crashes or failed library linkage, but also hard-to-track bugs that may arise from stale binaries, by loading only DLLs that were compiled at the same time as the executable file itself. The Build ID is typically generated automatically at compile-time, producing a new, unique value every time the Engine is built. However, you can override it with a manually specified value.

Automatically-Generated Build ID

At build time, every output directory that contains at least one compiled DLL receives a JSON file with the .modules extension, such as UnrealEditor.modules. This file lists each Module in the directory and the associated DLL for that Module, as well as a GUID for the build itself. Every time the Engine compiles, it generates a new GUID, so that DLLs from other compilation sessions will be recognizable, and the Engine can ignore them. When using source control to maintaining a binary build, you must check in the executable, all DLLs, and their associated .modules files together to ensure that the Build ID matches.

Manually-Specified Build ID

It is possible to force your Build ID to a specific value. You can accomplish this by adding a BuildId entry (as a string variable) to your Build/Build.version JSON file, but it is not recommended, as it removes the check to prevent using incompatible Modules. It is particularly easy to run outdated code if using a forced Build ID with Plugins that may be shared between multiple Projects.

Third-Party Plugin Template

Module Setup

Dynamic Libraries

Windows

FPlatformProcess::GetDllHandle

Delay Loading DLLs

Debugging DLL Loading Problems

macOS

Delay Loading DLLs

Debugging dylib Loading Problems

Linux

FPlatformProcess::GetDllHandle

Debugging SO Loading Problems

Runtime Dependencies

Troubleshooting

Windows.h

C++ Warnings and Errors

Default Packing and Alignment

RTTI Build Error

Linux

Dynamic Cast Error

This document explains how to integrate third-party libraries, including standard patterns for adding libraries, special considerations for dynamic libraries, dependency staging, and helpful information for errors you may encounter while integrating a third-party library into your Unreal project.

The Unreal Engine (UE) source code includes several third-party libraries, which are stored under UnrealEngine/Engine/Source/ThirdParty/.. This is a convention for engine modules, and not required. When developing plugins that use third-party libraries, it is more convenient to include the third-party software within the plugin directory.

Third-Party Plugin Template

The plugin browser in the editor has a template for integrating third-party libraries. To create a new plugin using this, select New Plugin from the plugin browser window and scroll down to the Third Party Plugin template.

Module Setup

Regular Unreal Engine C++ modules are configured using a .build.cs file, and third-party libraries are no different. To create a module that doesn't have any source code and exists for consumption by other modules, create a .build.cs for your plugin like this:

The .build.cs should be in a normal folder where the engine looks for modules, such as Engine/Source or MyProject/Source.

The ModuleType.External setting tells the engine not to look for (or compile) source code. It will use the other settings you define in that file by adding the listed include paths to the compile environment, setting the appropriate macros, and linking against the given static libraries.

Dynamic Libraries

Windows

Windows has a fairly inflexible model for loading DLLs. Each executable or DLL stores a list of the DLLs it depends on in its import table, and the OS scans this list when loading the module in order to satisfy those dependencies.

The names of dependency DLLs are stored by name only (for example, without any path information), and the operating system searches a short list of paths to try to find them. Since this happens without the application being able to specify the location of dependent DLLs, it can be the source of obscure errors at startup.

Any DLL loads explicitly triggered by the engine use the FPlatformProcess::GetDllHandle() function. This has special logic to read each DLLs import table before loading it, and attempts to resolve any DLL dependencies to files in the engine's list of search paths (for example, all project, engine, and plugin "Binaries" directories).

When the operating system comes to load the new DLL, if a DLL of the same name is already in memory, it will link against that rather than trying to load a new module from disk.

The GetDllHandle function produces a lot of verbose output to the log if it fails to load a dependency, which can be very valuable in tracking down errors.

If the DLL exists in a path not normally searched by the engine, an alternative strategy is to delay load it. Since the operating system only attempts to load the DLL the first time you call a function in it, you can execute explicitly logic to load it from a particular location. When the OS finally comes to doing the delay load, it will find the existing DLL with the same name already loaded into the process, and resolve to that instead of searching on disk.

Delay loading works by pointing imported functions to a thunk function that loads the real DLL. After the real DLL has been loaded, the import table is modified to point to the real DLLs function addresses rather than the thunk functions, and execution continues as normal.

This mechanism is not possible if you access variables in the DLL. The linker will give you an error if you try to delay load a DLL that is referenced in this way.

Delay-loaded DLLs can be specified from a build.cs file using a declaration like this:

Note that a path to the DLL is unnecessary (only the name is used) since the linker does not concern itself with how the operating system resolves the DLL dependencies it adds to the import table.

Dependency Walker is useful for examining the DLLs and functions imported from a module. The verbose engine log output also includes the "Dependency Walker" tool.

macOS

macOS executables and dylibs store the list of the dylibs they depend on in the form of install names. The install name can be an absolute or relative path to the dylib, or a path relative to one of three install paths: @executable_path, @load_path or @rpath. The most flexible of these options is @rpath, and that's what Unreal Engine uses.

UnrealBuildTool will automatically add RPATH search paths to the executable and dylibs it builds for all the third-party dylibs that are outside of Engine/Source and MyProject/Source subfolders. Storing third-party dylibs in Source subfolders is supported, but not recommended, as these folders are not part of the packaged game or binary version of the plugin, so the build system needs to handle them differently, copy them to a different location, among other things.

Install names are read from dylibs during linking, so the third-party library needs to have its install name set to @rpath/libfoo.dylib. This can be done in two ways, either by using -install_name linker option when building the library, or by using install_name_tool to modify it after the dylib was created, like this:

For frameworks, you should use PublicFrameworks instead of PublicAdditionalLibraries in the .build.cs file, but other than that, the same rules apply, so it's best to use @rpath for the framework install name as well.

Delay loading DLLs is not fully supported on macOS.

There's no equivalent of Windows /DELAYLOAD, so only one specific use of this feature is supported on macOS: linking with a library that may be unavailable on runtime. To implement that, UE uses weak linking.

From the command line, otool is useful to examine an executable or a dylib and look at its runtime dependencies. In particular, the -L and -l options are useful when debugging loading problems.

Command

Description

otool -L libname.dylib

Lists the install names and version numbers of all the dylibs the executable or dylib depends on. In case of a dylib, the first item on the list is its own install name.

otool -l libname.dylib

Displays all load commands of the file. Look for LC_LOAD_DYLIB and LC_RPATH to see what the dynamic linker will try to load automatically and what the RPATH search paths are.

Linux

There is no way to change the paths in which dlopen searches at runtime, so all paths to search for Linux will be set under the RPATH for each module. You can use readelf to find the full RPATH list that is searched.

All Unreal Engine modules will be dlopened as RTLD_LAZY | RTLD_LOCAL, while non-UE modules will all be first loaded as LAZY | LOCAL then re-opened as LAZY | RTLD_GLOBAL. This can cause specific issues where multiple UE modules have the same global symbol in which they will link to their local symbol versus a single global one, leading to odd crashes where global systems seem uninitialized. You can use gdb to print out locations it thinks it has stored versus the pointer you have of the global. If they are different, you most likely have multiple global definitions and modules binding to different ones.

Tool

Linux Manual Page

Brief Description

ldd

http://man7.org/linux/man-pages/man1/ldd.1.html

This will tell you runtime dependencies, and possibly any missing dependencies.

nm

http://man7.org/linux/man-pages/man1/nm.1p.html

This is similar to "Dependency Walker", which can tell you about exported symbols (and if needed, all symbols).

readelf

http://man7.org/linux/man-pages/man1/readelf.1.html

Another tool to dump info about exported symbols and elf section offsets, among other things.

LD_DEBUG

http://man7.org/linux/man-pages/man8/ld.so.8.html

Another way to figure out which symbols are being bound to which dynamic library.

strace

http://man7.org/linux/man-pages/man1/strace.1.html

This is a great tool to figure out the runtime system calls being used. This can tell which paths are being attempted to open/read from for dlopen.

Runtime Dependencies

To stage your third-party DLL next to the executable when you package your game, you can declare it as a runtime dependency from your build.cs file:

This assumes that the DLL already exists in the given directory, and that the plugin will manually load it from that location. If you want to have the DLL copied to the same output directory as the executable at build time, you do so via an overload of the RuntimeDependencies.Add method:

Other variables can be used for output paths of the DLL:

Variable

Description

$(EngineDir)

The engine directory

$(ProjectDir)

Directory containing the project file

$(ModuleDir)

Directory containing the .build.cs file

$(PluginDir)

Directory containing the .uplugin file

$(BinaryOutputDir)

Directory containing the binary that this module is compiled into (for example, the path to the DLL for editor builds, and path to the executable (EXE) for packaged builds)

$(TargetOutputDir)

Directory containing the executable (including in editor builds)

The RuntimeDependencies field is not limited to staging DLLs; you can also use it to inject additional files into the staging process. Those files can be stored in Unreal's PAK files, or kept loose on disk. DLLs are loaded by the operating system, so they can't normally be stored in the PAK file.

Possible values for StagedFileType are:

Value

Description

StagedFileType.UFS

Only accessed through Unreal filesystem functions, and may be included in a PAK file.

StagedFileType.NonUFS

Must be kept as part of the loose filesystem.

StagedFileType.DebugNonUFS

Debug file which must be kept as part of the loose filesystem. Will not be included unless debug files are set to be staged.

StagedFileType.SystemNonUFS

System file which must be kept as part of the loose filesystem. System files are not subject to automatic remapping or renaming by the platform layer.

Troubleshooting

Windows.h

The standard Windows header (Windows.h) is not included by default in most UE code. If you need it for third-party libraries, include it through the WindowsHWrapper.h file from the Core module.

Many Windows functions are defined as macros for switching between ANSI and Unicode variants, which can create issues when unrelated code defines symbols with the same name. To prevent this, we undefine many macros defined by Windows.h. We recommend that you explicitly call the ...A and ...W variants of functions where possible (for example, GetCommandLineA() or GetCommandLineW()).

Windows macros for TRUE and FALSE are not portable and are redefined to a value that causes a compile error if used. If you need to enable them for a block of code, wrap it in includes of AllowWindowsPlatformTypes.h and HideWindowsPlatformTypes.h, like this:

Similarly, Windows macros for atomic functions conflict with function names defined in WindowsPlatformAtomics.h. To restore those defines to their original values, include AllowWindowsPlatformAtomics.h/HideWindowsPlatformAtomics.h:

C++ Warnings and Errors

The Unreal Engine codebase has many warnings treated as errors by default. To relax some of these restrictions for third-party code, there are cross-platform macros to temporarily disable common warnings:

Default Packing and Alignment

For legacy reasons, Unreal Engine forces 4-byte packing on Win32. This can result in hard-to-debug alignment issues in classes that use 8-byte types such as doubles or longs. To restore the default packing around third-party code that defines 8-byte types in public structs, use the following macros:

RTTI Build Error

Linking your binary from source files compiled with different RTTI (run-time type information) flags may cause build errors on Windows. If you encounter RTTI build errors, you can either define a helper macro to mix RTTI on/off modules or, if you're building from source, you can enable RTTI for the entire engine by setting the bForceEnableRTTI to true in TargetRules.cs.

Linux does not allow mix and matching of RTTI modules. So if you have a module with RTTI, you need to enable it for the engine.

If you use dynamic cast on an object type that is not a UObject type when RTTI is off, you will encounter the "can't use dynamic_cast when RTTI is disabled error" because in CoreUObject/Public/Templates/Casts.h, #define dynamic_cast redirects CUObject modules. For UObject types, dynamic cast uses Unreal Engine's reflection system, but for other types, it uses regular dynamic_cast.

Use a Static Code Analyzer with UBT

Supported Analyzers

Examples

Command-line Options for Clang Analyzer

Unreal Build Tool (UBT) supports running several different static code analyzers. Static Code Analyzers use a variety of algorithms and techniques to inspect source code and find bugs without executing the code. This means faster analysis, earlier detection of memory leaks and logic errors, and reduced technical debt.

Use a Static Code Analyzer with UBT

The general command-line syntax for running a static code analyzer with UBT from your Unreal Engine root directory is:

TARGET, PLATFORM, and ANALYZER are required arguments in the above command you must replace with your desired values.

TARGET: A build target supported by UBT, see the documentation on Targets for more information.

PLATFORM: A platform supported by Unreal Engine. Visit the General Platform Support pages to learn about Unreal Engine platform support.

ANALYZER: A static code analyzer that UBT uses to analyze the provided target on the designated platform. Refer to the Supported Analyzers section below to view the available options.

Supported Analyzers

Analyzer

Description

Default

Default static analyzer for the selected compiler (if it has one).

VisualCpp

Built-in Visual C++ static analyzer. Only supported for Microsoft Visual C++ (MSVC) based platforms.

PVSStudio

PVS-Studio static analyzer. Only supported for MSVC-based platforms.

PVS-Studio requires a license file placed next to the installed PVS-Studio.exe executable. For more information about PVS-Studio and obtaining a license, visit the PVS-Studio documentation.



Clang

Clang static analyzer. This forces the compiler to Clang for MSVC-based platforms.

The Clang static analyzer is in Beta. Features available in Beta state give you the opportunity to learn how they work, plan your pipeline, and create test content. You should use caution when using these features in production, as we are still working to get to shipping-quality performance, stability, and platform support. We support backward compatibility for assets, and the APIs for these features are stable.



Examples

Run the following command from your Unreal Engine root directory to use the default static code analyzer with Unreal Editor as the target on a Windows 64-bit platform:

Run the following command from your Unreal Engine root directory to use the Visual C++ static code analyzer with the Lyra Starter Game as the target on a Windows 64-bit platform:

Command-line Options for Clang Analyzer

Option

Description

-StaticAnalyzerOutputType=html

Writes out web pages with navigation that describe the analysis warnings. These HTML files are written into the appropriate folders within the Engine/Intermediate/Build directory for the selected platform and target.

-StaticAnalyzerMode=shallow

Enables shallow analysis. This means analysis completes more quickly, but is less informative than standard analysis. We do not recommend using this mode for general purposes.

-StaticAnalyzerChecker=CHECKER

Provides a list of static analyzer checkers that you want to enable rather than the default list.

-StaticAnalyzerDisableChecker=CHECKER

Disables static analyzer default checkers. This option overrides the default disabled checkers which are deadcode.DeadStores and security.FloatLoopCounter. This option is unused if -StaticAnalyzerChecker is set.

-StaticAnalyzerAdditionalChecker=CHECKER

Enables additional non-default static analyzer checkers. This option is unused if -StaticAnalyzerChecker is set.

For a full list of Clang analyzer checkers, see Available Checkers in the Clang documentation.

Unreal Header Tool (UHT) is a custom parsing and code-generation tool that supports the UObject system. Code compilation happens in two phases:

UHT is invoked, which parses the C++ headers for Unreal-related class metadata and generates custom code to implement the various UObject-related features.

The normal C++ compiler is invoked to compile the results.

When compiling, it is possible for either tool to emit errors, so be sure to look carefully.

Overview

BuildGraph Reference

Guides

Overview



A host program and a set of utility libraries that enable you to script unattended processes related to Unreal Engine.



Customize your builds with the BuildGraph scripting system.

BuildGraph Reference



Learn syntax to write BuildGraph script conditions.



Learn about valid data types for BuildGraph attributes.



Learn how BuildGraph can help you create custom tasks.



Learn about BuildGraph Elements.

Guides



Add automation scripts to be compiled and run with Unreal Automation Tool.



This page provides sample BuildGraph Script usage.

How Automation Tool Works

Automation Projects

Running Automation Tool

Running Commands under the Debugger

Running Commands from the command line (Windows)

Running Commands from the terminal (Mac/Linux)

Command Line Syntax

Automation Tool is a host program and a set of utility libraries you can use to script unattended processes related to Unreal Engine (UE) when using C#. Internally, we use Automation Tool for a variety of tasks, including building, cooking, and running games, running automation tests, and scripting other operations to be executed on our build farm.

The source code for Automation Tool, and various scripts that run under it, can be found under Engine/Source/Programs/AutomationTool.

While we provide this tool as a courtesy, the level of support we can provide is limited.

How Automation Tool Works

Automation Projects

When run, Automation Tool finds all automation projects (saved as Visual Studio C# projects with an .Automation.csproj extension), compiles them, and then uses reflection to find the appropriate command to be executed. Those commands are implemented as classes derived from the BuildCommand base class, and are identified by the class name.

To learn more, read how to add an automation project and how to add a command.

Running Automation Tool

You can run commands under the Visual Studio debugger on Windows, or from the command line on Windows, Mac, and Linux.

To run Automation Tool under the Debugger in Visual Studio:

Right click the Automation Tool Project, and select Properties from the context menu.

Select the Debug tab, and enter your command name (here, we use SampleCommand) into the Start Options > Command line arguments: field.

Set a breakpoint in your script before pressing the F5 key (or clicking the Start button in the Visual Studio toolbar).

To run Automation Tool from the command line:

Open a Command Prompt window.

Change the working directory to Engine/Build/BatchFiles.

Enter the following into the command line: RunUAT.bat SampleCommand

To run Automation Tool from the terminal:

Open the terminal.

Change the working directory to Engine/Build/BatchFiles.

Enter the following into the command line: ./RunUAT.sh SampleCommand

Command Line Syntax

The general syntax of the Automation Tool command line is:

Here, two commands will be run sequentially. -ARG_1 and -ARG_2 are passed to COMMAND_1, -ARG_3 and -ARG_4 are passed to COMMAND_2, and so on.

Global options:

Option

Description

-Help

Shows help and options for Automation Tool in general, or (when specified after a command name) help for that particular command.

-List

Displays a list of all available Automation Tool commands.

-P4

Enable Perforce support.

-Submit

Allows automated processes to submit files.

-NoCompile

Prevents Automation Tool from compiling any .Automation.csproj files on startup.

If set, the following environment variables are used to configure Perforce support for build machines. They may be set via the Automation Tool command line in the VARNAME=VALUE syntax or inherited from the current session.

Environment Variable

Description

uebp_PORT

The Perforce server and port (for example, perforce:1666).

uebp_CLIENT_ROOT

Path to the local root directory of the current client (for example, D:\P4).

uebp_CL

The current changelist that is synced to.

uebp_CodeCL

The current code changelist that is synced to. This may be before the current changelist specified by uebp_CL.

uebp_USER

The Perforce user.

uebp_CLIENT

Name of the client used to access Perforce.

uebp_BuildRoot_P4

Path to the root of the current branch or stream (for example, //UE4/Release-4.22).

UnrealBuildTool

Writing BuildGraph Scripts

BuildGraph Scripting Reference

Using BuildGraph

BuildGraph is a script-based build automation system that features graphs of building blocks common to Unreal Engine (UE) projects. BuildGraph integrates with UnrealBuildTool, AutomationTool, and the Editor. BuildGraph can also be extended and customized for your projects.

BuildGraph scripts are written in XML, specifying a graph of user-defined nodes with dependencies between them. Each node consists of tasks executed in sequence to produce some sort of output (for example, compile this project, then cook, run this test, and so on). When asked to build a target (that is, a node or named output) BuildGraph will execute all of the nodes in the graph required to make that happen.

Unlike other build tools, BuildGraph is designed as a hybrid between a makefile-like scripting language and a build farm configuration script. It enables annotations for the type of machine that steps are supposed to be executed on, providing a list of recipients for failure notifications if a step fails, and groups nodes that should only be executed after an explicit user trigger. It also tracks the creation of output files from task execution in a way that lends to graph execution being distributed across a farm of machines (with nodes running in parallel where possible) and intermediate artifacts being transferred to and from a network share automatically.

Epic uses BuildGraph to prepare the Unreal Engine binary release, package samples for the marketplace, and implement pipelines for our own games (among other things). Several example BuildGraph scripts are provided in the [Unreal Engine Root Directory]/Engine/Build/Graph/Examples directory, and the script for creating a binary Unreal Engine distribution can be found at [Unreal Engine Root Directory]/Engine/Build/InstalledEngineBuild.xml.

Opening a script with Visual Studio will use the schema located at [Unreal Engine Root Directory]/Engine/Build/Graph/Schema.xsd to provide rich tooltips, validation, and Intellisense features while editing.

Writing BuildGraph Scripts

If you want to learn how to write your own BuildGraph scripts, it helps to know the various parts that go into making a Graph. Graphs are created with the following elements:

Tasks: Actions that are executed as part of a build process (compiling, cooking, and so on).

Nodes: A named sequence of ordered tasks that are executed to produce outputs. Before they can be executed, nodes may depend on other nodes executing their tasks first.

Agents: A group of nodes that are executed on the same machine (if running as part of a build system). Agents have no effect when building locally.

Triggers: Container for groups that should only be executed after manual intervention.

Aggregates: Groups of nodes and named outputs that can be referred to with a single name.

Scripts typically make frequent use of properties for reusable or conditionally defined values. Properties are declared with the <Property> element, and are scoped to the point of their first declaration. Properties referenced with the $(Property Name) notation are valid within all attribute strings, and will be expanded when the script is read. Properties that can be supplied by the user on the command-line can be declared with the <Option> element, and environment variables can be imported into properties using the <EnvVar> element.

Any element may be conditionally defined via the "If" attribute. See below for the syntax of conditional expressions.

BuildGraph is typically used for packaged games, so filtering and file manipulation are natively supported. Any attribute that accepts a list of files may consist of a Perforce style wildcard (matching any number of ..., * and ? patterns in any location), a full path name, or a reference to a tagged collection of files. Attributes are denoted by prefixing a # character. Files may be added to a tag set using the <Tag> task, which also enables the performance of union and difference style operations. Each node can declare multiple outputs in the form of a list of named tags, which other nodes can then depend on.

Graphs may be executed in parallel as part of a build system. To do so, the initial graph configuration is generated by running with the -Export=<Filename> argument (producing a JSON file listing the nodes and dependencies to execute). Each participating agent should be synced to the same changelist, and AutomationTool (UAT) should be re-run with the appropriate -SingleNode=<Name> argument. Outputs from different nodes are transferred between agents via shared storage (typically, a network share) the path to which can be specified on the command line using the -SharedStorageDir=<Path> argument. Note that the allocation of machines (and coordination between them) is assumed to be managed by an external system.

The syntax of elements used to define BuildGraph constructs is listed in the following sections.

BuildGraph Scripting Reference



Learn syntax to write BuildGraph script conditions.



Learn about valid data types for BuildGraph attributes.



Learn how BuildGraph can help you create custom tasks.



Learn about BuildGraph Elements.

Using BuildGraph



This page provides sample BuildGraph Script usage.

The following are references for the different scripting elements that make up BuildGraph scripts for Unreal Engine.

BuildGraph Script Conditions

BuildGraph Script Types

BuildGraph Script Tasks

BuildGraph Script Elements

Conditions

Atoms

Operators

If you want to build logical complexity into your BuildGraph scripts, you need to work with conditionals. The following section introduces you to how BuildGraph conditions are written, including a list of conditional operators.

Conditions

BuildGraph script conditions consist of atoms and operators that evaluate to true or false.

Atoms

Atoms can be numbers, strings, or identifiers that are coerced to their appropriate type for the operator using them. Atoms may be quoted with single (') or double (") quotes. They can also be an unquoted sequence of letters, digits, and underscore characters. All atoms are considered the same type, regardless of how they are declared. Additionally, atoms are considered case-insensitive for comparisons. This means that the strings "True" and 'true' are identical to the identifier true (despite the presence of quotes and differences in case).

Operators

A list of operators is specified below:

Operator

Description

Precedence

(x)

Subexpression used for grouping.

1

!x

Evaluates to true if x is false.

1

Exists(x)

Evaluates to true if the file x exists.

1

HasTrailingSlash(x)

Evaluates to true if x ends with a slash or backslash.

1

x == y

Evaluates to true if the two atoms are equal (case insensitive).

2

x != y

Evaluates to true if the two atoms are not equal (case insensitive).

2

x < y

Evaluates to true if the integer x is less than the integer y.

2

x <= y

Evaluates to true if the integer x is less than or equal to the integer y.

2

x > y

Evaluates to true if the integer x is greater than the integer y.

2

x >= y

Evaluates to true if the integer x is greater than or equal to the integer y.

2

x and y

Evaluates to true if both atoms are true.

3

x or y

Evaluates to true if either x is true, y is true, or both atoms are true.

4

The '<' and '>' characters must be escaped as "&lt;" and "&gt;" in XML.

The following table contains valid data types that can be contained by BuildGraph attributes:

Type

Description

String

An arbitrary string.

String List

A list of arbitrary strings separated by semicolons.

Boolean

The constant true or false.

Integer

An integer constant.

Regex

A regular expression, using C# syntax.

Name

A named entity. Any printable character, except ^ < > : " / \ | ? * ;. Single spaces are allowed (except at the start and end of a name).

Name List

A list of identifiers separated by semicolons.

Tag

A label given to a list of files beginning with the # character (for example, #My Files).

Tag List

A list of tags separated by semicolons (for example, #My Files;#Other Files).

Target

A node name, aggregate name, agent name, or tag name. Indicates a sequence of nodes that need to be executed. Note that this overlaps with the meaning of Target as it applies to UnrealBuildTool (which refers to a single program being built).

Target list

A list of target names separated by semicolons.

File Spec

A set of file and tag names separated by semicolons. Wildcards such as "...", "_", and "?" are permitted when referencing files (for example, Engine/.../_.bat). Unless otherwise specified, relative paths are resolved relative to the working root directory.

File Reference

A path to a file. Unless otherwise specified, relative paths are resolved to the working root directory.

Directory Reference

A path to a directory. Unless otherwise specified, relative paths are resolved relative to the working root directory.

Unreal Target Configuration

The configuration in which to build the target. Available configurations are: Debug, DebugGame, Development, Test, or Shipping.

Unreal Target Platform

A platform that Unreal Engine supports. Supported platforms can be found in Sharing and Releasing Projects. Please refer to your platform's documentation.

Condition

A conditional expression.

Build Operations: Cook, Package, Deploy, and Run

Custom Tasks

Predefined Tasks

Typically, project-specific utility scripts are implemented as Unreal Automation Tool (UAT) BuildCommand classes. There are times, however, when you need to automate custom tasks for your project. This is where BuildGraph can help, as you can extend BuildGraph with any number of automation tasks in ways that suit your specific needs. The following section goes over ways of creating custom tasks using BuildGraph, including a listing of predefined tasks that will give you a great starting point for creating custom tasks.

Custom Tasks

To create a new custom task, implement a class derived from the CustomTask class and apply the TaskElement attribute to it. The TaskElement constructor takes two arguments: the name of the XML element that it is represented by and the type of class containing its parameters (which is passed to the constructor at load time).

If you want to read parameter class fields from an XML file, attach the TaskParameter attribute to the task. Attaching the TaskParameter attribute indicates if the parameter is required or optional, including additional validation that should be applied to the argument.

Predefined Tasks

If you would like to have a starting point for creating tasks, we provide a variety of predefined tasks as templates for you to work from. If you are looking for a simple predefined task to start from, we recommend using LogTask as a good starting point. If you want to keep up with our latest improvements to BuildGraph, bookmark this page. The following list of predefined tasks will be updated periodically.

BuildCookRun is a powerful and commonly used command for packaging tasks. For more information, read the overview that covers Build Operations.

AgeStore

Task that strips symbols from a set of files. This task is named after the AGESTORE utility that comes with the Microsoft debugger tools SDK, but is actually a separate implementation. The main difference is that it uses the last modified time rather than last access time to determine which files to delete.

Attribute

Type

Required?

Description

Platform

UnrealTargetPlatform

Required

The target platform to age symbols for.

StoreDir

String

Required

The symbol server directory.

Days

Integer

Required

Number of days worth of symbols to keep.

BuildDir

String

Optional

The root of the build directory to check for existing buildversion named directories.

Filter

String

Optional

A substring to match in directory file names before deleting symbols. This allows the "age store" task to avoid deleting symbols from other builds in the case where multiple builds share the same symbol server. Specific use of the filter value is determined by the symbol server structure defined by the platform toolchain.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Aws

Spawns AWS CLI and waits for it to complete.

Attribute

Type

Required?

Description

Arguments

String

Optional

Arguments for the newly created process.

Environment

String

Optional

Environment variables.

EnvironmentFile

String

Optional

File to read environment from.

LogOutput

Boolean

Optional

Write output to the log.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Aws-AssumeRole

Assumes an AWS role.

Attribute

Type

Required?

Description

Arn

String

Required

Role to assume.

Session

String

Required

Name of this session.

Duration

Integer

Optional

Duration of the token in seconds.

Environment

String

Optional

Environment variables.

EnvironmentFile

String

Optional

File to read environment variables from.

OutputFile

String

Required

Output file for the new environment.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Aws-EcsDeploy

Creates a new AWS ECS task definition and updates the ECS service to use this new revision of the task def.

Attribute

Type

Required?

Description

TaskDefinitionFile

String

Required

Task definition file to use

DockerImage

String

Required

Docker image to set in new task definition (will replace %%DOCKER_PATTERN%% with this value).

Version

String

Optional

App version to set in new task definition (will replace %5.1% with this value).

Cluster

String

Required

Cluster ARN representing AWS ECS cluster to operate on.

Service

String

Required

Service name to update and deploy to.

Environment

String

Optional

Environment variables.

EnvironmentFile

String

Optional

File to read environment from.

LogOutput

Boolean

Optional

Write output to the log.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Command

Invokes an AutomationTool child process to run the given command.

Attribute

Type

Required?

Description

Name

String

Required

The command name to execute.

Arguments

String

Optional

Arguments to be passed to the command.

MergeTelemetryWithPrefix

String

Optional

If non-null, instructs telemetry from the command to be merged into the telemetry for this Unreal Automation Tool (UAT) instance with the given prefix. May be an empty (non-null) string.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Commandlet

Spawns the editor to run a commandlet.

Attribute

Type

Required?

Description

Name

String

Required

The commandlet name to execute.

Project

FileSpec

Optional

The project to run the editor with.

Arguments

String

Optional

Arguments to be passed to the commandlet.

EditorExe

FileReference

Optional

The editor executable to use. Defaults to the development UnrealEditor executable for the current platform.

ErrorLevel

Integer

Optional

The minimum exit code, which is treated as an error.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Compile

Compiles a target with Unreal Build Tool (UBT).

Attribute

Type

Required?

Description

Target

String

Optional

The target to compile.

Configuration

UnrealTargetConfiguration

Required

The configuration to compile.

Platform

UnrealTargetPlatform

Required

The platform to compile for.

Project

FileSpec

Optional

The project to compile with.

Arguments

String

Optional

Additional arguments for Unreal Build Tool.

AllowXGE

Boolean

Optional

Whether to allow using XGE for compilation.

AllowParallelExecutor

Boolean

Optional

Whether to allow using the parallel executor for this compile.

Clean

Boolean

Optional

Whether to allow cleaning this target. If unspecified, targets are cleaned if the -Clean argument is passed on the command line.

Tag

TagList

Optional

Tag to be applied to build products of this task.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Cook

Cook a selection of maps for a certain platform.

Attribute

Type

Required?

Description

Project

String

Required

Project file to be cooked.

Platform

String

Required

The cook platform to target (for example, Windows).

Maps

String

Optional

List of maps to be cooked, separated by '+' characters.

Versioned

Boolean

Optional

Additional arguments to be passed to the cooker.

Arguments

String

Optional

Additional arguments to be passed to the cooker.

EditorExe

String

Optional

Optional path to what editor executable to run for cooking.

Tag

TagList

Optional

Tag to be applied to build products of this task.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Copy

Copies files from one directory to another.

Attribute

Type

Required?

Description

Files

FileSpec

Optional

Optional filter to be applied to the list of input files.

From

FileSpec

Required

The pattern or patterns to copy from (for example, Engine/*.txt).

To

FileSpec

Required

The directory to copy to.

Overwrite

Boolean

Optional

Whether or not to overwrite existing files.

Tag

TagList

Optional

Tag to be applied to build products of this task.

ErrorIfNotFound

Boolean

Optional

Whether or not to throw an error if no files were found to copy.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

CsCompile

Compiles C# project files, and their dependencies.

Attribute

Type

Required?

Description

Project

String

Required

The C# project file to compile. Using semicolons, more than one project file can be specified.

Configuration

String

Optional

The configuration to compile.

Platform

String

Optional

The platform to compile.

Target

String

Optional

The target to build.

Properties

String

Optional

Properties for the command.

Arguments

String

Optional

Additional options to pass to the compiler.

EnumerateOnly

Boolean

Optional

Only enumerate build products - do not actually compile the projects.

Tag

TagList

Optional

Tag to be applied to build products of this task.

TagReferences

TagList

Optional

Tag to be applied to any non-private references the projects have (for example, those that are external and not copied into the output directory).

UseSystemCompiler

Boolean

Optional

Whether to use the system toolchain rather than the bundled UE SDK.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Delete

Delete a set of files.

Attribute

Type

Required?

Description

Files

FileSpec

Optional

List of file specifications separated by semicolons (for example, *.cpp;Engine/.../*.bat), or the name of a tag set.

Directories

String

Optional

List of directory names.

DeleteEmptyDirectories

Boolean

Optional

Whether to delete empty directories after deleting the files. Defaults to true.

Verbose

Boolean

Optional

Whether or not to use verbose logging.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Docker

Spawns Docker and waits for it to complete.

Attribute

Type

Required?

Description

Arguments

String

Required

Docker command line arguments.

Environment

String

Optional

Environment variables to set.

EnvironmentFile

String

Optional

File to read environment variables from.

WorkingDir

String

Optional

Base directory for running the command.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Docker-Build

Spawns Docker and waits for it to complete.

Attribute

Type

Required?

Description

BaseDir

String

Required

Base directory for the build.

Files

String

Required

Files to be staged before building the image.

DockerFile

String

Optional

Path to the Dockerfile. Uses the root of basedir if not specified.

DockerIgnoreFile

String

Optional

Path to a .dockerignore. Will be copied to basedir if specified.

UseBuildKit

Boolean

Optional

Use BuildKit in Docker.

ProgressOutput

String

Optional

Type of progress output (--progress).

Tag

String

Optional

Tag for the image.

Arguments

String

Optional

Optional arguments.

OverlayDirs

String

Optional

List of additional directories to overlay into the staged input files. Allows credentials to be staged and the like.

Environment

String

Optional

Environment variables to set.

EnvironmentFile

String

Optional

File to read environment variables from.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Docker-Compose-Down

Spawns Docker and waits for it to complete.

Attribute

Type

Required?

Description

File

String

Required

Path to the docker-compose file.

Arguments

String

Optional

Arguments for the command.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Docker-Compose-Up

Spawns Docker and waits for it to complete.

Attribute

Type

Required?

Description

File

String

Required

Path to the docker-compose file.

Arguments

String

Optional

Arguments for the command.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Docker-Push

Spawns Docker and waits for it to complete.

Attribute

Type

Required?

Description

Repository

String

Required

Repository.

Image

String

Required

Source image to push.

TargetImage

String

Optional

Name of the target image.

Environment

String

Optional

Additional environment variables.

EnvironmentFile

String

Optional

File to read environment from.

AwsEcr

Boolean

Optional

Whether to login to AWS ECR.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

DotNet

Spawns Docker and waits for it to complete.

Attribute

Type

Required?

Description

Arguments

String

Optional

Docker command line arguments.

BaseDir

String

Optional

Base directory for running the command.

Environment

String

Optional

Environment variables to set.

EnvironmentFile

String

Optional

File to read environment variables from.

ErrorLevel

Integer

Optional

The minimum exit code, which is treated as an error.

DotNetPath

FileReference

Optional

Override path to dotnet executable.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

FindModifiedFiles

Compiles C# project files, and their dependencies.

Attribute

Type

Required?

Description

Paths

String

Required

The C# project file to compile. Using semicolons, more than one project file can be specified.

Change

Integer

Optional

The configuration to compile.

MinChange

Integer

Optional

The configuration to compile.

MaxChange

Integer

Optional

The configuration to compile.

Output

FileReference

Optional

The file to write to.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Git

Spawns Git and waits for it to complete.

Attribute

Type

Required?

Description

Arguments

String

Optional

Git command line arguments.

BaseDir

String

Optional

Base directory for running the command.

ErrorLevel

Integer

Optional

The minimum exit code, which is treated as an error.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Git-Clone

Clones a Git repository into a local path.

Attribute

Type

Required?

Description

Dir

String

Required

Directory for the repository.

Remote

String

Optional

The remote to add.

Branch

String

Required

The branch to check out on the remote.

ConfigFile

String

Optional

Configuration file for the repo. This can be used to set up a remote to be fetched and/or provide credentials.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Helm

Spawns Helm and waits for it to complete.

Attribute

Type

Required?

Description

Chart

String

Required

Helm command line arguments.

Deployment

String

Required

Name of the release.

Namespace

String

Optional

The Kubernetes namespace.

KubeContext

String

Optional

The kubectl context.

KubeConfig

String

Optional

The kubectl config file to use.

Values

String

Optional

Values to set for running the chart.

ValuesFile

String

Optional

Values to set for running the chart.

Environment

String

Optional

Environment variables to set.

EnvironmentFile

String

Optional

File to parse environment variables from.

Arguments

String

Optional

Additional arguments.

WorkingDir

String

Optional

Base directory for running the command.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Kubectl

Spawns Kubectl and waits for it to complete.

Attribute

Type

Required?

Description

Arguments

String

Required

Command line arguments.

BaseDir

String

Optional

Base directory for running the command.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Log

Print a message (and other optional diagnostic information) to the output log.

Attribute

Type

Required?

Description

Message

String

Optional

Message to print out.

Files

FileSpec

Optional

If specified, causes the given list of files to be printed after the given message.

IncludeContents

Boolean

Optional

If specified, causes the contents of the given files to be printed out.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

ModifyConfig

Modifies a config file.

Attribute

Type

Required?

Description

File

FileSpec

Required

Path to the config file.

Section

String

Required

The section name to modify.

Key

String

Required

The property name to set.

Value

String

Required

The property value to set.

Tag

TagList

Optional

Tag to be applied to the extracted files.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

ModifyJsonValue

Modifies json files by setting a value specified in the key path.

Attribute

Type

Required?

Description

Files

FileSpec

Required

JSON file paths which will be modified.

KeyPath

String

Required

JSON key path to find in each file.

NewValue

Integer

Required

New value to apply.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Move

Moves files from one directory to another.

Attribute

Type

Required?

Description

Files

FileSpec

Optional

Optional filter to be applied to the list of input files.

From

FileSpec

Required

The pattern or patterns to copy from (for example, Engine/*.txt).

To

FileSpec

Required

The directory to copy to.

Overwrite

Boolean

Optional

Optionally if files should be overwritten, defaults to false.

Tag

TagList

Optional

Tag to be applied to build products of this task.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

MsBuild

Executes MsBuild.

Attribute

Type

Required?

Description

Project

String

Required

The C# project file to compile. Using semicolons, more than one project file can be specified.

Configuration

String

Optional

The configuration to compile.

Platform

String

Optional

The platform to compile.

Arguments

String

Optional

Additional options to pass to the compiler.

Verbosity

String

Optional

The MSBuild output verbosity.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

PakFile

Creates a PAK file from a given set of files.

Attribute

Type

Required?

Description

Files

FileSpec

Required

List of files, wildcards, and tag sets to add to the pak file, separated by ';' characters.

Output

FileReference

Required

PAK file to output.

ResponseFile

FileReference

Optional

Path to a Response File that contains a list of files to add to the PAK file - instead of specifying them individually.

RebaseDir

DirectoryList

Optional

Directories to rebase the files relative to. If specified, the shortest path under a listed directory will be used for each file.

Order

FileReference

Optional

Script that gives the order of files.

Sign

FileReference

Optional

Encryption keys for this PAK file.

Compress

Boolean

Optional

Whether to compress files.

Arguments

String

Optional

Additional arguments to pass to UnrealPak.

Tag

TagList

Optional

Tag to be applied to build products of this task.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Rename

Renames a file, or group of files.

Attribute

Type

Required?

Description

Files

FileSpec

Required

The file or files to rename.

From

String

Optional

The current file name, or pattern to match (for example, *.txt). Should not include any path separators.

To

String

Required

The new name for the file or files. Should not include any path separators.

Tag

TagList

Optional

Tag to be applied to the renamed files.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

SanitizeReceipt

Task that tags build products and/or runtime dependencies by reading from *.target files.

Attribute

Type

Required?

Description

Files

FileSpec

Required

Set of receipt files (*.target) to read, including wildcards and tag names, separated by semicolons.

EngineDir

DirectoryReference

Optional

Path to the Engine folder, used to expand $(EngineDir) properties in receipt files. Defaults to the Engine directory for the current workspace.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

SetVersion

Updates the local version files (Engine/Source/Runtime/Launch/Resources/Version.h, Engine/Build/Build.version, and Engine/Source/Programs/Shared/Metadata.cs) with the given version information.

Attribute

Type

Required?

Description

Change

Integer

Required

The changelist to set in the version files.

CompatibleChange

Integer

Optional

The engine compatible changelist to set in the version files.

Branch

String

Required

The branch string.

Build

String

Optional

The build version string.

Licensee

Boolean

Optional

Whether to set the IS_LICENSEE_VERSION flag to true.

Promoted

Boolean

Optional

Whether to set the ENGINE_IS_PROMOTED_BUILD flag to true.

SkipWrite

Boolean

Optional

If set, do not write to the files - just return the version files that would be updated. Useful for local builds.

Tag

TagList

Optional

Tag to be applied to build products of this task.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Sign

Signs a set of executable files with an installed certificate.

Attribute

Type

Required?

Description

Files

FileSpec

Required

List of file specifications separated by semicolons (for example, *.cpp;Engine/.../*.bat), or the name of a tag set.

Tag

TagList

Optional

Tag to be applied to build products of this task.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Spawn

Spawns an external executable and waits for it to complete.

Attribute

Type

Required?

Description

Exe

String

Required

Executable to spawn.

Arguments

String

Optional

Arguments for the newly created process.

WorkingDir

String

Optional

Working directory for spawning the new task.

Environment

String

Optional

Environment variables to set.

EnvironmentFile

String

Optional

File to read environment from.

LogOutput

Boolean

Optional

Write output to the log.

ErrorLevel

Integer

Optional

The minimum exit code, which is treated as an error.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Stage

Stages files listed in a build receipt to an output directory.

Attribute

Type

Required?

Description

Project

FileReference

Optional

The project that this target belongs to.

Target

String

Required

Name of the target to stage.

Platform

UnrealTargetPlatform

Required

Platform to stage.

Configuration

UnrealTargetConfiguration

Required

Configuration to be staged.

Architecture

String

Optional

Architecture to be staged.

ToDir

DirectoryReference

Required

Directory that the receipt files should be staged to.

Overwrite

Boolean

Optional

Whether to overwrite existing files.

Tag

TagList

Optional

Tag to be applied to build products of this task.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Strip

Strips debugging information from a set of files.

Attribute

Type

Required?

Description

Platform

UnrealTargetPlatform

Required

The platform toolchain to strip binaries.

BaseDir

DirectoryReference

Optional

The directory to find files in.

Files

FileSpec

Required

List of file specifications separated by semicolons (for example, Engine/.../*.pdb), or the name of a tag set.

OutputDir

DirectoryReference

Optional

Output directory for the stripped files. Defaults to the input path, overwriting the input files.

Tag

TagList

Optional

Tag to be applied to build products of this task.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Submit

Creates a new changelist and submits a set of files to a Perforce stream.

Attribute

Type

Required?

Description

Description

String

Required

The description for the submitted changelist.

Files

FileSpec

Required

The files to submit.

FileType

String

Optional

The Perforce file type for the submitted files (for example, binary+FS32).

Workspace

String

Optional

The workspace name. If specified, a new workspace will be created using the given stream and root directory to submit the files. If not, the current workspace will be used.

Stream

String

Optional

The stream for the workspace - defaults to the current stream. Ignored unless the Workspace attribute is also specified.

Branch

String

Optional

Branch for the workspace (legacy P4 depot path). May not be used in conjunction with Stream.

RootDir

DirectoryReference

Optional

Root directory for the stream. If not specified, it defaults to the current root directory.

RevertUnchanged

Boolean

Optional

Whether to revert unchanged files before attempting to submit.

Force

Boolean

Optional

Force the submit to happen - even if a resolve is needed (always accept the current version).

P4Verbose

Boolean

Optional

Allow verbose P4 output (spew).

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

SymStore

Task that strips symbols from a set of files.

Attribute

Type

Required?

Description

Platform

UnrealTargetPlatform

Required

The platform toolchain required to handle symbol files.

Files

String

Required

List of output files. PDBs will be extracted from this list.

StoreDir

String

Required

Output directory for the compressed symbols.

Product

String

Required

Name of the product for the symbol store records.

BuildVersion

String

Optional

BuildVersion associated with these symbols. Used for clean-up in AgeStore by matching this version against a directory name in a build share.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Tag

Applies a tag to a given set of files. The list of files is found by enumerating the tags and file specifications given by the Files parameter. From this list, any files not matched by the Filter parameter are removed, followed by any files matched by the Except parameter.

Attribute

Type

Required?

Description

BaseDir

DirectoryReference

Optional

Set the base directory to resolve relative paths and patterns against. If set, any absolute patterns (for example, /Engine/Build/...) are taken to be relative to this path. If not, they are taken to be truly absolute.

Files

FileSpec

Optional

Set of files to work from, including wildcards and tag names, separated by semicolons. If set, resolved relative to BaseDir, otherwise resolved to the branch root directory.

FileLists

FileSpec

Optional

Set of text files to add additional files from. Each file list should have one file per line.

Filter

FileSpec

Optional

Patterns to filter the list of files by, including tag names or wildcards. If set, may include patterns that apply to the base directory. If not specified, defaults to all files.

Except

FileSpec

Optional

Set of patterns to exclude from the matched list. May include tag names of patterns that apply to the base directory.

With

TagList

Required

Name of the tag to apply.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

TagReceipt

Task that tags build products and/or runtime dependencies by reading from *.target files.

Attribute

Type

Required?

Description

Files

FileSpec

Required

Set of receipt files (*.target) to read, including wildcards and tag names, separated by semicolons.

EngineDir

DirectoryReference

Optional

Path to the Engine folder, used to expand $(EngineDir) properties in receipt files. Defaults to the Engine directory for the current workspace.

ProjectDir

DirectoryReference

Optional

Path to the project folder, used to expand $(ProjectDir) properties in receipt files. Defaults to the Engine directory for the current workspace. (This has been DEPRECATED.)

BuildProducts

Boolean

Optional

Whether to tag the Build Products listed in receipts.

BuildProductType

String

Optional

Which type of Build Products to tag (see TargetReceipt.cs - UnrealBuildTool.BuildProductType for valid values).

RuntimeDependencies

Boolean

Optional

Whether to tag the Runtime Dependencies listed in receipts.

StagedFileType

String

Optional

Which type of Runtime Dependencies to tag (see TargetReceipt.cs - UnrealBuildTool.StagedFileType for valid values).

With

TagList

Required

Name of the tag to apply.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Unzip

Extract files from a ZIP archive.

Attribute

Type

Required?

Description

ZipFile

FileSpec

Required

Path to the ZIP file to extract.

ToDir

DirectoryReference

Required

Output directory for the extracted files.

UseLegacyUnzip

Boolean

Optional

Whether or not to use the legacy Unzip code.

Tag

TagList

Optional

Tag to be applied to the extracted files.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Upload

Uploads a set of files to Jupiter for future retrieval.

Attribute

Type

Required?

Description

FromDir

DirectoryReference

Required

The directory to read compressed files from.

Files

FileSpec

Optional

List of file specifications separated by semicolons (for example, *.cpp;Engine/.../*.bat), or the name of a tag set. Relative paths are taken from FromDir.

JupiterNamespace

String

Required

The jupiter namespace used to upload the build. Used to control who has access to the build.

JupiterKey

String

Required

The key of the build that will be used to download the build again. This has to be globally unique for this particular upload.

ArchiveType

String

Required

The type of archive these files are from, will be added to the metadata.

ProjectName

String

Required

The name of the project this set of files are associated with, will be added to the metadata.

Branch

String

Required

The source control branch these files were generated from, will be added to the metadata.

Changelist

String

Required

The source control revision these files were generated from, will be added to the metadata.

JupiterUrl

String

Required

Specify the url to the Jupiter instance to upload to.

AdditionalMetadata

String

Optional

Semi-colon separated list of '=' separated key value mappings to add to the metadata, for example, Foo=bar;spam=eggs.

LimitMemoryUsage

Boolean

Optional

If enabled file content is not kept in memory, results in lower memory usage but increased io as file contents needs to be read multiple times (for hashing as well as during upload).

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Wait

Waits a defined number of seconds.

Attribute

Type

Required?

Description

Seconds

Integer

Required

Number of seconds to wait.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

WriteTextFile

Writes text to a file.

Attribute

Type

Required?

Description

File

FileReference

Required

Path to the file to write.

Append

Boolean

Optional

Whether or not to append to the file rather than overwrite.

Text

String

Optional

The text to write to the file.

Files

FileSpec

Optional

If specified, causes the given list of files to be printed after the given message.

Tag

TagList

Optional

Tag to be applied to build products of this task.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Zip

Compresses files into a ZIP archive.

Attribute

Type

Required?

Description

FromDir

DirectoryReference

Required

The directory to read compressed files from.

Files

FileSpec

Optional

List of file specifications separated by semicolons (for example, *.cpp;Engine/.../*.bat), or the name of a tag set. Relative paths are taken from FromDir.

ZipFile

FileReference

Required

The ZIP file to create.

Tag

TagList

Optional

Tag to be applied to the created ZIP file.

If

Condition

Optional

Whether to execute this task. It is ignored if this condition evaluates to false.

Elements

Graph Structure

Node

Aggregate

Agent

Trigger

Property Manipulation

Property

Option

EnvVar

Flow Control

Include

Do

Switch

ForEach

Diagnostics

Warning

Error

BuildGraph scripts are written in XML. This document covers the types of data found within BuildGraph scripts, as well as their overall structure.

Elements

Elements describe the data that they contain, making them one of the basic building blocks of BuildGraph scripts. The following tables contain items that are provided as metadata, which are exported when running on the build system. Although they are not used directly by BuildGraph when executing tasks locally, they are tagged with [META].

Graph Structure

A BuildGraph script is typically defined with the following elements:

<Node>

<Aggregate>

<Agent>

<Trigger>

Node

<Node> is the smallest unit of execution in BuildGraph, with a set of inputs and outputs. Each <Node> consists of a sequence of tasks that are executed in order.

Attribute

Type

Required?

Description

Name

Name

Required

Name of the node.

Requires

Target List

Optional

List of nodes, aggregates, or tagged file sets produced by other nodes that this node requires to execute, separated by semicolons.

Produces

Tag List

Optional

Tagged file sets that this node makes available to other nodes, separated by semicolons.

After

Target List

Optional

List of nodes that this node should run after, if they are part of the current target, separated by semicolons. These are ignored if they are not part of the current target.

NotifyOnWarnings

Boolean

Optional

If false, this node will not produce notifications on warnings. Only used by build systems. Defaults to true. [META]

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

Aggregate

<Aggregate> declares a named aggregate that can be used as a synonym for either produced tag sets or a set of other nodes.

Attribute

Type

Required?

Description

Name

Name

Required

Name of the aggregate.

Requires

Target List

Required

List of dependencies for this aggregate. These may be nodes, tagged file sets, or agent groups.

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

Agent

<Agent> defines requirements for an agent on nodes that will be executed in sequence (without cleaning intermediate directories). <Agent> requirements are ignored when building locally but must be specified.

Attribute

Type

Required?

Description

Name

Name

Required

Name of the group.

Type

Identifier List

Optional

Type of agent to run on. The meaning of this string is inferred by the host build system, it does not have any intrinsic meaning. [META]

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

Trigger

<Trigger> serves as a container for portions of the graph that should only be executed with explicit user intervention. To execute nodes behind a trigger, pass -Trigger=<Name> to the command line.

Attribute

Type

Required?

Description

Name

Name

Required

Name of the trigger.

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

Property Manipulation

BuildGraph properties can be modified with the following elements:

<Property>

<Option>

<EnvVar>

Property

<Property> sets the value of a property. If a property in an outer scope has already been declared with the same name, <Property> overwrites it. Otherwise, a new property is declared at the current scope.

Attribute

Type

Required?

Description

Name

Name

Required

Name of the property to set.

Value

String

Required

New value for the property.

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

Option

<Option> defines a user option that can be set from the command line. <Option> may only appear at a global scope.

Attribute

Type

Required?

Description

Name

Name

Required

Name of the option (and property) to initialize with the option's value.

Description

String

Required

Description for the option to display when running BuildGraph with the -ListOnly argument.

Restrict

Regex

Optional

Regex that matches valid values for this option (eg. [a-zA-Z]+, true | false).

DefaultValue

String

Required

Default value for the option if the user does not set it explicitly.

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

EnvVar

<EnvVar> declares a property to contain the contents of an environment variable (or an empty string if it is not set). <EnvVar> may only appear at a global scope.

Attribute

Type

Required?

Description

Name

Name

Required

Name of the environment variable to introduce as a property.

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

Flow Control

You can control the flow of your BuildGraph scripts with the following elements:

<Include>

<Do>

<Switch>

<ForEach>

Include

<Include> processes the contents of another BuildGraph script as if it appeared within this file. <Include> may only appear at a global scope.

Attribute

Type

Required?

Description

Script

String

Required

Path to the script you want to include (relative to the current script).

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

Do

<Do> groups a sequence of elements and only processes them if a condition evaluates as true.

Attribute

Type

Required?

Description

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

Switch

<Switch> is similar to a C switch statement because it evaluates the conditions on a sequence of branches, processing the first statement with a condition that evaluates as true.

Example <Switch> statement:

Attribute

Type

Required?

Description

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

ForEach

<ForEach> expands the body of the element with a given property assigned to each item in a list that is separated by semicolons.

Example <ForEach> statement:

Attribute

Type

Required?

Description

Name

Name

Required

Property to assign to each value in the list.

Values

String List

Required

List of values that are separated by semicolons.

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

Diagnostics

You can perform diagnostics on your BuildGraph scripts with the following elements:

<Warning>

<Error>

Warning

<Warning> outputs a warning message before executing the graph. <Warning> may be included in nodes, agents, triggers, or at global scope. <Warning> will only provide an output if it's still part of the graph after it has been trimmed down to the target being executed.

Attribute

Type

Required?

Description

Message

String

Required

Text to be printed to the log.

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

Error

<Error> outputs an error message. <Error> may be included in nodes, agents, triggers, or at global scope. <Error> will only provide an output if it is still part of the graph after it has been trimmed down to the target being executed.

Attribute

Type

Required?

Description

Message

String

Required

Text to be printed to the log.

If

Condition

Optional

Condition to be evaluated. The element is ignored unless the condition evaluates to true.

Showing Options & Nodes

Setting an Option

Seeing Node Execution

Cleaning Previous Builds

Writing out an XML Schema

Generating a Preprocessed Script

Exporting a Preprocessed Graph to JSON

Executing a Single Node

BuildGraph is implemented as part of AutomationTool, which you can run directly from the Unreal Engine (UE) solution on Windows, or via the Engine/Build/BatchFiles/RunUAT.bat batch file from the command line. On Mac or Linux, it can be run with the Engine/Build/BatchFiles/RunUAT.sh shell script. If you would like to get an idea of how to use BuildGraph from the command line, we have written sample usage commands for your reference.

Showing Options & Nodes

To show all of the nodes and options available in a BuildGraph script:

Setting an Option

To set an option defined in the script:

Seeing Node Execution

To see what nodes will be executed for a target:

Cleaning Previous Builds

To clean any previous builds and execute a specific target:

Writing out an XML Schema

To write out an XML schema containing all registered tasks:

Generating a Preprocessed Script

To output a preprocessed version of your script (useful for debugging):

Exporting a Preprocessed Graph to JSON

To export a preprocessed graph to JSON (for dynamic configuration on build systems):

Executing a Single Node

To execute a single node on a build system (while transferring intermediates to and from shared storage):

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Setting Up Visual Studio

Downloading Unreal Engine Source Code

Automation Tool Overview

Create an Automation Project

Project Settings

Configure your Automation Project

Adjust Build Settings

Configure Project Properties

Verify Automation Project

Add a Project Reference

Add Code to an Automation Script

Automation Script Code

Execute an Automation Script

To create a project-specific automation script, you need to create a new C# project in a location that Unreal Automation Tool can detect it. This requires:

A source build of Unreal Engine.

A C# automation project discoverable from a subdirectory listed in *.uprojectdirs.

Create an Automation Project

The following steps guide you to create a new C# automation project:

Ensure that you have a source build of Unreal Engine.

Open command prompt and run GenerateProjectFiles.bat from your Unreal Engine root directory.

This will generate a UE5.sln file for Visual Studio.

Open the UE5.sln file in Visual Studio.

In Visual Studio, right-click the main Solution UE5 directory and select Add > New Project...

With the Add a new project window open, find and select C# Class Library. Do not select the Class Library (.NET Framework) Visual C# option. Unreal Automation Tool targets .NET 6.0 and an error will occur if you try to target the .NET Framework.

A menu pops up prompting you to choose settings for your new C# Class Library.

Set Project name to be the name of your automation script. For example purposes, call this SampleScript.Automation. Note: Ensure that your name follows the convention <SCRIPT_NAME>.Automation as UAT looks for the .Automation name format to properly register the automation script.

Set Location to be UNREAL_ENGINE_ROOT\Engine\Source\Programs.

Click Next to bring up an Additional Information window. Here you choose the Framework for this Class Library.

In the dropdown menu, choose .NET 6.0 (Long-term support) and click Create.

Visual Studio creates a new folder named SampleScript.Automation. Within the newly created SampleScript.Automation folder is a file named Class1.cs. Change the name of this file to SampleScript.cs. Visual Studio prompts you as to whether you wish to change all project references as well. Choose Yes.

Project Settings

Setting

Value

Note

Name

SampleScript.Automation

The automation project generation script looks for a *.csproj file with the *.Automation.csproj extension.

Location

PROJECT_ROOT\Build or UNREAL_ENGINE_ROOT\Source\Programs

You can save the project in a Project Build or Engine Source directory.

.NET Framework

6.0

Configure your Automation Project

Adjust Build Settings

Before you write an automation script, there are some build settings that require adjustment:

In the Visual Studio Solution Explorer, navigate to SampleScript.Automation and select it.

With this folder selected, go to Build > Configuration Manager... in the Visual Studio menu bar.

In the Configuration Manager window, find the SampleScript.Automation project.

Under the Project's Configuration dropdown menu, select Edit...

A new window titled Edit Project Configurations should appear.

In this window, select Release, click Rename, and change Release to Development.

A new window should appear asking you to confirm your choice to rename Release to Development. Click Yes and close both opened windows.

Configure Project Properties

Now you must configure the output path for your automation project:

In the Visual Studio Solution Explorer, navigate to SampleScript.Automation and select it.

Right-click this folder and select Properties.

Under the Build tab, choose your desired Base output path. For our purposes, if it is not already, set the output path to bin\.

Verify Automation Project

Before proceeding, first verify that our project has been successfully detected by Unreal Automation Tool as a new automation project. To verify that you have configured our project properly, close Visual Studio, open the command prompt, then run GenerateProjectFiles.bat. Open the generated UE5.sln file and navigate to UNREAL_ENGINE_ROOT\Programs\Automation. The new automation project SampleScript.Automation should now appear in this directory. This means that Unreal Automation Tool has successfully detected our new automation project.

Add a Project Reference

You can now register your automation project with Unreal Automation Tool:

In the Visual Studio Solution Explorer, navigate to SampleScript.Automation and select it.

Right-click SampleScript.Automation and select Add > Project Reference...

This opens a window titled Reference Manager - SampleScript.Automation.

Find AutomationUtils.Automation and check the box next to the name and click OK.

Add Code to an Automation Script

The Create an Automation Project and Configure your Automation Project sections instructed you to create an automation project named SampleScript.Automation. Within this folder, you also created a C# file named SampleScript.cs. This is the file where we add our automation script commands.

For our purposes, we will write a function that prints the terms of the Fibonacci sequence to the command line up to the number of terms specified by a command line argument that the user enters when our automation script is called. This example demonstrates the following features of automation scripts:

Help commands

Command line input

Command line output

Logging

Automation Script Code

Below is the sample code for this automation script example. Copy and paste this code sample into the SampleScript.cs.

Execute an Automation Script

You are now ready to run your automation script:

Open a command prompt and navigate to your UNREAL_ENGINE_ROOT directory.

Enter the command: RunUAT.bat SampleCommand -Terms=6

This command builds and runs AutomationTool executing the SampleCommand located in the SampleScript.cs file.

If everything goes correctly, you should see something similar to the following output in the command prompt:





Click image to expand.



You can also run: RunUAT.bat SampleCommand -help to display the information in the [Help(...)] message text from your SampleCommand class.





Click image to expand.



Content Browser

Recommended Asset Prefixes

As you develop projects in Unreal Engine (UE), the list of Assets in your Content Browser will expand. This runs the risk of creating redundant variations of assets you're experimenting with, or introducing ambiguity with overly similar names. For example, it is possible for you to have a folder named "Soldier" with a Blueprint, a texture, and a model that all have the name "Soldier" in them, but no clear way to tell which is which in a simple list.

For large projects, we recommend you establish a common naming convention for individual Assets early in development. This will make it easier for you and your team to locate files and prevent potential conflicts or ambiguity. The naming convention described below reflects how Epic Games names Assets in sample projects, such as the In-Camera VFX Production Test.

AssetTypePrefix identifies the type of Asset, refer to the table below for details.

AssetName is the Asset's name.

Descriptor provides additional context for the Asset, to help identify how it is used. For example, whether a texture is a normal map or an opacity map.

OptionalVariantLetterOrNumber is optionally used to differentiate between multiple versions or variations of an asset.

Consider using this naming convention for your own project's Assets, as it will provide multiple ways for your team to locate an Asset when searching the Content Browser.

This naming convention is only a recommendation to simplify setting up your project. Your requirements will always take precedence, and it is likely that you won't use all of these Asset types in your Project.

Recommended Asset Prefixes

This list is not exhaustive, as new features can require new Asset types. If you are using an Asset type not listed, use the existing list as a guideline for your naming convention for that Asset.

Asset

Prefix



General



HDRI

HDR_

Material

M_

Material Instance

MI_

Physics Asset

PHYS_

Physics Material

PM_

Post Process Material

PPM_

Skeletal Mesh

SK_

Static Mesh

SM_

Texture

T_

OCIO Profile

OCIO_



Blueprints



Actor Component

AC_

Animation Blueprint

ABP_

Blueprint Interface

BI_

Blueprint

BP_

Curve Table

CT_

Data Table

DT_

Enum

E_

Structure

F_

Widget Blueprint

WBP_

Particle Effects

Niagara Emitter

FXE_

Niagara System

FXS_

Niagara Function

FXF_

Skeletal Mesh Animations

Rig

Rig_

Skeleton

SKEL_

Montages

AM_

Animation Sequence

AS_

Blend Space

BS_



ICVFX



NDisplay Configuration

NDC_



Animation



Level Sequence

LS_

Sequencer Edits

EDIT_



Media



Media Source

MS_

Media Output

MO_

Media Player

MP_

Media Profile

MPR_



Other



Level Snapshots

SNAP_

Remote Control Preset

RCP_

Support for containers expands Unreal Engine's capabilities to support new cloud-based development workflows and deployment strategies. Unreal Engine containers can be used to enhance production pipelines, develop next-generation cloud applications, deploy enterprise solutions at unprecedented scale, and much more.

Although official support for containers in Unreal Engine is still a Beta feature, it is built upon the pre-existing open source infrastructure developed by TensorWorks and the Unreal Containers community initiative, which is already in production use by developers around the world today.

The sections below provide more information about Containers and how to use them in your development pipeline.



An overview of container support in Unreal Engine.



Get started using Unreal Engine containers.



Hardware and software requirements for building and running Unreal Engine containers.



How to build container images that are included with Unreal Engine from source.



Known limitations of container support in Unreal Engine.

Understanding Containers and Container Images

Development and Runtime Container Images

Available Container Images

Limitations

Available Resources

Support for containers expands Unreal Engine's capabilities to support new cloud-based development workflows and deployment strategies. Unreal Engine containers can be used to enhance production pipelines, develop next-generation cloud applications, deploy enterprise solutions at unprecedented scale, and much more.

Although official support for containers in Unreal Engine is still a Beta feature, it is built upon the pre-existing open source infrastructure developed by TensorWorks and the Unreal Containers community initiative, which is already in production use by developers around the world today.

Understanding Containers and Container Images

As described by the What is a Container? page on the Docker website, containers are a technology designed to package applications and their supporting dependencies into a single standard unit that is portable across computing infrastructure, both on-premises and in the cloud.

In a similar manner to virtual machines, containers are stored on disk as a container image, from which one or more containers can be run. Unlike virtual machines, containers share a single underlying operating system kernel and can share common data across separate container images. This makes them computationally lightweight and facilitates a larger number of concurrent deployments.

If you would like to learn more about containers, take a look at some of the resources available from various cloud providers:

IBM: What are Containers

Red Hat: A Practical Introduction to Container Terminology

Development and Runtime Container Images

There are two types of container images that are included in Unreal Engine: development images and runtime images.

Development images contain the Unreal Editor and build tools. They are used for tasks that require the editor, such as building and packaging Unreal Engine projects and plugins, rendering cinematics created using Sequencer, or running commandlets. Distribution of development images is governed by the terms of the Unreal Engine EULA.

Runtime images contain only the dependencies required to run packaged Unreal Engine projects. Developers extend runtime images by adding files for their packaged Unreal Engine projects, and creating new container images that can be deployed to cloud environments. Since runtime images do not contain the editor or build tools, their distribution is less restricted than development images.

For a more detailed explanation of the differences between development images and runtime images, see the Development images .vs. runtime images documentation page on the Unreal Containers community hub website.

Available Container Images

Starting with Unreal Engine 4.27, official development and runtime container images are included with each Engine release. The source code for these container images can be found in the Engine/Extras/Containers directory of the Unreal Engine source code, which you can download from GitHub, or from Perforce if you are an Unreal Engine licensee. Prebuilt versions of all container images are published to GitHub Container Registry and can be downloaded without requiring you to build them from source.

The following development images are provided:

Development Image Type

Description

dev

This is the full Linux development image for Unreal Engine, which includes an Installed Build of Unreal Engine, template projects, and full debug symbols.

dev-slim

This is a smaller version of the Linux development image that excludes template projects and debug symbols.

The following runtime images are provided:

Runtime Image Type

Description

runtime

This is the streamlined Linux runtime image for running packaged Unreal Engine applications inside containers, with or without GPU acceleration. To minimize the image's size, this image does not include support for audio output.

This container image currently only supports GPU acceleration on machines using NVIDIA GPUs.

runtime-pixel-streaming

This image extends the streamlined Linux runtime image to add the dependencies required for Pixel Streaming applications, including support for audio output. As a result, this image is noticeably larger than the default runtime image, although it is still far smaller than the Windows runtime image.

This container image currently only supports GPU acceleration with NVIDIA GPUs.

runtime-windows

This is the Windows runtime image for running packaged Unreal Engine applications inside containers, with or without GPU acceleration. Since Windows container images are already significantly larger than their Linux counterparts, and the dependencies required for Pixel Streaming applications are relatively small compared to the size of the Windows operating system itself, this image includes those dependencies as well.

Support for running Pixel Streaming applications inside GPU accelerated Windows containers is experimental and is not recommended for production use.

In addition to the development and runtime images, the following images are provided for specific use cases such as Pixel Streaming:

Special Image Type

Description

pixel-streaming-signalling-server

This is a Linux container image that includes the Cirrus signalling and web server used by the Pixel Streaming system.

multi-user-server

This is a Linux container image that includes the server used by Unreal Engine's Multi-User Editing system.

Limitations

Official support for containers in Unreal Engine is still in Beta and is subject to a number of limitations. See the Known Limitations page for details.

Available Resources

In addition to the official documentation for container support in Unreal Engine, the following resources are available:

The Unreal Containers community hub maintains extensive written documentation with links to related videos and source code repositories. The community hub website is accompanied by a Discord server for community discussions about the use and development of Unreal Engine containers.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Installing Unreal Engine

Creating a New Project

Containers Overview

1. Requirements

2. Verifying GitHub Access

3. Installing Docker

4. Authenticating with GitHub Container Registry

5. Pulling Prebuilt Container Images

6. Building a Project in a Development Container

Next Steps

The Containers Quick Start is designed to help you access the official container images for Unreal Engine and use them to run a simple container. This guide will walk you through the following tasks:

Install Docker on your computer.

Log in to GitHub Container Registry so that you can use Docker to download prebuilt Unreal Engine container images.

Download the prebuilt Linux development container image for Unreal Engine.

Start a container using the development image.

Build and package a project inside the container.

1. Requirements

To run the Unreal Engine container image for this Quick Start, your computer will need to meet the hardware and software requirements listed in the Linux containers section of the Hardware and Software Requirements page.

2. Verifying GitHub Access

Verify that you can access the Unreal Engine source code repository on GitHub: https://github.com/EpicGames/UnrealEngine. If you cannot access the repository then you will need to link your GitHub account with your Epic Games Account.

3. Installing Docker

Docker is the recommended tool for building and running the container images that are included with Unreal Engine. The steps for installing Docker will depend on the operating system that you are using. The links below provide instructions on how to do this on each platform it is available on:

Windows: Install Docker Desktop for Windows

macOS: Install Docker Desktop for Mac

Linux: Follow the appropriate instructions to install Docker Engine for your specific Linux distribution:

CentOS

Debian

Fedora

Ubuntu

Other Linux distributions

4. Authenticating with GitHub Container Registry

To download container images from GitHub Container Registry using Docker you will need to authenticate using a personal access token. If you do not already have a personal access token with the read:packages scope then you will need to follow the steps to create one.

Once you have created a personal access token with the required scope, use the docker login command to authenticate with GitHub Container Registry as described in the instructions from GitHub. This command will need to be run from the command-line interface, which is accessed differently depending on the operating system that you are using.

Windows: Open the Start menu and type "cmd" in the search box. The application "Command Prompt" should be displayed as the first search result. Open the Command Prompt by either clicking on it or pressing the Enter key.

macOS: Open Spotlight search by pressing Command + Space and type "terminal" in the search box. The application "Terminal" should be displayed as the first search result. Open the Terminal by either clicking on it or pressing the Enter key.

Linux: Open the search feature of your desktop environment (typically accessed by pressing the Super key) and type "terminal" in the search box. A terminal application should be displayed as the first search result. Open the terminal by either clicking on it or pressing the Enter key.

Once you have opened the command-line prompt then run the command shown below, replacing ACCESS_TOKEN with your personal access token and USERNAME with your GitHub username:

If the authentication process was successful then you should see the message "Login Succeeded" displayed.

5. Pulling Prebuilt Container Images

The official prebuilt container images for Unreal Engine are stored as image tags in the ghcr.io/epicgames/unreal-engine repository. To download the Linux development image for Unreal Engine 4.27, use the docker pull command shown below:

This will download a container image that encapsulates the files for Unreal Editor and build tools, which are quite large. Depending on the speed of your internet connection, the download process may take some time. When the download is complete, you should see the message "Status: Downloaded newer image for ghcr.io/epicgames/unreal-engine:dev-4.27" displayed.

6. Building a Project in a Development Container

If you do not have an Unreal Engine project available for testing purposes then you will need to follow the steps to create a new project. You can use any project to test the development container image so long as that project does not use any code plugins which are incompatible with Linux.

Open a command-line prompt and run the command shown below to start a new container using the development image, replacing PROJECT_PATH with the path to the directory that contains the .uproject file for your project:

This will start a container with access to the files for your project. Since the container is running Linux, it can be used to build and package the project for Linux devices. To package the project, run the command shown below, replacing PROJECT_NAME with the name of your project:

The C++ code modules for the project will be compiled, if the project is not a Blueprint-only project, and the project's assets will then be cooked and packaged. The packaged files will be placed in a subdirectory called Packaged inside the directory that contains the .uproject file.

To stop the container, run the command shown below:

Next Steps

Now that you are familiar with the basics of working with prebuilt container images, you can continue learning more about using Unreal Engine containers with the following resources:

In addition to downloading prebuilt container images, all images that are included with Unreal Engine can also be customized and built from source:

How-To: Building the Linux Container Images from Source

How-To: Building the Windows Container Images from Source

If you're unsure whether you need a development image or a runtime image, take a look at the interactive Quickstart Guide on the Unreal Containers community hub.

Explore the list of use cases that can benefit from Unreal Engine containers.

Requirements for Linux Containers

Requirements for Windows Containers

Installing Docker

Requirements for Linux Containers

The Linux container images that are included with Unreal Engine can be built and run on Windows, macOS or Linux. To build or run the container images, your computer will need to meet the following hardware requirements:

64-bit CPU with support for Second Level Address Translation (SLAT)

Hardware virtualization support enabled in the system BIOS

Minimum of 4 GB of system RAM

Your computer will also need to meet the following software requirements:

Windows: 64-bit Windows 10 Home, Pro, Enterprise, or Education, version 1903 or newer with Docker Desktop for Windows installed. See the Installing Docker section below for instructions on how to install Docker Desktop for Windows.

macOS: macOS version 10.14 or newer with Docker Desktop for Mac installed. See the Installing Docker section below for instructions on how to install Docker Desktop for Mac.

Linux: 64-bit version of CentOS 7 or newer, Debian 10 or newer, Fedora 32 or newer, Ubuntu 16.04 or newer, or any Linux distribution that meets Docker's prerequisites with Docker Engine installed. See the Installing Docker section below for instructions on how to install Docker Engine.

Requirements for Windows Containers

The Windows container images that are included with Unreal Engine can only be built and run on Windows. To build or run the container images, your computer will need to meet the following software requirements:

64-bit Windows 10 Pro, Enterprise, or Education, version 1809 or newer with Docker Desktop for Windows installed. See the Installing Docker section below for instructions on how to install Docker Desktop for Windows.

Installing Docker

Docker is the recommended tool for building and running the container images that are included with Unreal Engine. The steps for installing Docker will depend on the operating system that you are using. The links below provide instructions on how to do this on each platform it is available on:

Windows: Install Docker Desktop for Windows

macOS: Install Docker Desktop for Mac

Linux: Follow the appropriate instructions to install Docker Engine for your specific Linux distribution:

CentOS

Debian

Fedora

Ubuntu

Other Linux distributions

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Installing Unreal Engine

Containers Overview

Containers Quick Start

Requirements

Installing Docker

Building the Images for an Official Engine Release

Building the Images for a Custom Version of the Engine

Modifying Advanced Build Parameters

All container images that are included with Unreal Engine have prebuilt versions available for download from GitHub Container Registry. It is only necessary to build the images from source if you want to create development images for a custom version of Unreal Engine or to make modifications to the image source code.

Requirements

To build the Linux container images that are included with Unreal Engine, your computer will need to meet the hardware and software requirements listed in the Linux containers section of the Hardware and Software Requirements page.

Building the Linux container images from source under Windows is not supported. Although it is possible to build the images using either Docker Desktop or WSL2 under Windows 10 and Windows 11, this process requires additional configuration and troubleshooting to function correctly, and Epic Games does not provide support for doing so. Instead, you should build the Linux container images under Linux, either installed in a virtual machine or directly on the host machine.

Installing Docker

Docker is the recommended tool for building and running the container images that are included with Unreal Engine. The steps for installing Docker will depend on the operating system that you are using. The links below provide instructions on how to do this on each platform it is available on:

Windows: Install Docker Desktop for Windows

macOS: Install Docker Desktop for Mac

Linux: Follow the appropriate instructions to install Docker Engine for your specific Linux distribution:

CentOS

Debian

Fedora

Ubuntu

Other Linux distributions

Building the Images for an Official Engine Release

If you have downloaded the Unreal Engine source code from GitHub then you will need to run Setup.sh from the root of the source tree to download the engine's binary dependencies, just as you would when building the engine from source. If you do not perform this step, then the files required for building container images will be missing.

Navigate to the following subdirectory of the Unreal Engine source code:

The build scripts for the Linux container images search for Git credentials in files called username.txt and password.txt:

Create the username.txt file and populate it with your GitHub username.

Create the password.txt file and populate it with your GitHub personal access token.

To build the Linux container images for a given release of the Unreal Engine, run the command shown below in a Bash shell, replacing ENGINE_RELEASE with the appropriate release number (e.g. "4.27.0"):

This will build both the runtime images for Linux and the development images for Linux, followed by images for specific use cases such as Pixel Streaming. The development images will take the longest to build, since they download the Unreal Engine source code from GitHub and create an Installed Build of the Engine.

Building the Images for a Custom Version of the Engine

The build scripts only support retrieving the Unreal Engine source code from Git. Other version control systems such as Perforce are not supported. It is possible to use other version control systems by manually modifying the Dockerfiles for the development images but Epic Games does not provide support for doing so.

The build scripts for the Linux container images support specifying a custom Git repository and branch from which to retrieve the Unreal Engine source code instead of using the official GitHub repository. Custom repositories might include GitHub forks of the official Unreal Engine repository or private repositories stored on on-premises Git servers maintained by an organization for internal use.

How you populate the Git credentials in the username.txt and password.txt files will depend upon the type of Git repository being used:

GitHub fork:

Use your GitHub username and personal access token.

Custom Git server:

Populate the username.txt file with your Git username.

Populate the password.txt file with your Git password.

To build the Linux container images for a specific branch of a Git repository, run the command shown below in a Bash shell, replacing BRANCH with the name of the branch and REPOSITORY with the HTTPS URL for the Git repository (e.g. "https://github.com/EpicGames/UnrealEngine.git"):

Modifying Advanced Build Parameters

The build script build.sh includes the following advanced build parameters that can be modified by manually editing the file:

BASEIMAGE: This is a string that specifies the Linux base image that will be used when building the development images. This value defaults to an Ubuntu base image provided by NVIDIA that includes the OpenGL development headers.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Installing Unreal Engine

Containers Overview

Containers Quick Start

Requirements

Installing Docker

Building the Images

All container images that are included with Unreal Engine have prebuilt versions available for download from GitHub Container Registry. It is only necessary to build the images from source if you want to create development images for a custom version of Unreal Engine or to make modifications to the image source code.

Requirements

To build the Windows container images that ship with Unreal Engine, your computer will need to meet the hardware and software requirements listed in the Windows containers section of the Hardware and Software Requirements page.

Installing Docker

Docker is the recommended tool for building the container images that are included with Unreal Engine. To install Docker, follow the instructions to install Docker Desktop for Windows.

Once Docker Desktop is installed, you will need to switch from Linux containers mode (the default) to Windows containers mode.

Building the Images

If you have downloaded the Unreal Engine source code from GitHub then you will need to run Setup.bat from the root of the source tree to download the engine's binary dependencies, just as you would when building the engine from source. If you do not perform this step then the files required for building container images will be missing.

Navigate to the following subdirectory of the Unreal Engine source code:

To build the Windows container images, double-click the build.bat file. This will build the Windows runtime image for the same version of Windows that your machine is running.

Windows Development Images

Support for AMD GPUs in Container-Based Pixel Streaming

Official support for containers in Unreal Engine is still in Beta and is subject to a number of limitations.

Windows Development Images

The container images that are included with Unreal Engine currently only include Linux development images and not Windows development images. This is due to both technical and legal limitations that currently prevent us from distributing Windows development images.

For a discussion on the technical issues that affect Windows development images, see the blog post Preview the future of the ue4-docker project by Adam Rehn.

Support for AMD GPUs in Container-Based Pixel Streaming

Windows runtime images that support Pixel Streaming support GPU acceleration with both NVIDIA and AMD GPUs. Linux images only support NVIDIA GPUs, but support for AMD GPUs is planned for a future release.

Using Perforce as Source Control

What is UnrealGameSync (UGS)?

Who Benefits from Using UGS?

Developers

Creatives

Unreal Game Sync Documentation



When a team is working on an Unreal Engine (UE) project, they're working in an environment where code and content is continuously developed and integrated into the project. Oftentimes, while working in a collaborative development environment, success depends on a team's ability to effectively collaborate and communicate on problems that might arise during the development and integration process.

This is where a sync tool can help.

What is UnrealGameSync (UGS)?

Conceptually, UGS is a tool that promotes code and content integration in a collaborative development environment, enabling teammates distributed over time and distance to labor on the same project as it gets updated. Technically, UGS provides a graphical front-end to sync UE projects from Perforce, optionally building those projects with Microsoft's Visual Studio Compiler.

When they're using this tool, an Artist's workflow typically involves UGS syncing their project files, resolving merge conflicts, syncing editor binaries, updating version files, and optionally running their Unreal project.



For Programmers, their workflow typically involves UGS syncing their project files, resolving merge conflicts, updating version files, generating project files, optionally building UE4, and optionally running their Unreal project.



Resolving merge conflicts is enabled by default; however, you can disable this service in the Options shortcut menu. Additionally, disabling UGS from building your project precludes UGS from running it.

After installing UGS, members of any team will be able to quickly bootstrap and iterate on projects without the overhead that typically comes with using sync tools.

Who Benefits from Using UGS?

Anyone wanting to gain insight into or contribute to a UE game project, but more specifically; Developers, Designers, and Artists. In general, for all team members, it's safe to submit changes containing assets and source code because UGS syncs both code and content with ease.

Developers

Developers can sync to a changelist (CL) as soon as it's submitted, thereby enabling them to locally compile the source code matching the CL. Additionally, they can add comments to each change, flagging builds as good or bad for other developers.

When engineers are working on a fix for a broken build, they can notify the rest of the team that they're working on the fix by setting a flag.

Developers can safely make content changes from local builds without submitting unversioned assets because Engine version files (Version.h and Build.version) are updated to the synced CL.

Because UGS includes custom build steps, UGS enables developers to set up tools and utilities that are specific to their project.

Note that build system results can be surfaced alongside a list of submitted CLs (along with a link to build logs).

Creatives

If creatives, such as artists or designers, don't have Visual Studio (or if they don't need to compile the Editor), they can get a compressed Editor build of the project, which is compiled by the Continuous Integration System (CIS).

Getting a compressed Editor build of the project is particularly useful for artists because the compressed build can be synced and automatically decompressed.

Finally, it's important to note that other disciplines, such as Quality Assurance, Production, or Business units can also use UGS to gain insight into a project's status or collaborate with developers and creatives. If you're new to UGS and you want to start using it, check out the UGS Quick Start guide.

Unreal Game Sync Documentation



Learn how to get started using UnrealGameSync.



How to set up an Unreal Game Sync client



This page describes how to configure UGS for deployment as a studio.



All the options in the Unreal Game Sync menus



How to use precompiled binaries to optimize development for your project



Some tips and procedures for correcting common problems with UGS

Sync Filters

1 - Opening a Local File

2 - Opening a Workspace File

3 - Syncing from the Changelist Area

4 - Syncing from the Project Overview Area

5 - On Your Own!



The goal of this guide is to show you the primary workflow of syncing your Unreal Project (.uproject) using UnrealGameSync (UGS). After working through this tutorial, you will know how to open an Unreal Project with UGS, and how to sync from the Project Overview and Changelist Areas of the application's main menu.

Required Setup: The following steps assume that your team has distributed and set up UGS on your machine or machines.

1 - Opening a Local File

The following steps show you how to open a local Unreal Project file with UGS.

To open a .uproject on your local drive, click the Open project... link.

When the Open Project window opens, UGS enables the Local File radio button by default. To select a local file, click the Browse... button.

Navigate to and select the .uproject file before clicking Open.

We are using the Lyra Sample Game as an example Unreal Project.

To open the Unreal Project with UGS, click the Ok button.

2 - Opening a Workspace File

The following steps show you how to open a workspace Unreal Project file with UGS.

To open a .uproject file on your local drive, click the Open project... link.

When the Open Project window opens, UGS selects the Local File radio button by default. Select the Workspace radio button to get started.

The first field that needs to be populated is the Workspace's name. If you already have a Workspace to point UGS to, click the Browse... button next to the Name: field.

If you need to create a new Workspace, click the New... button to set up a New Workspace.



When the Select Workspace menu opens, it will show you a list of Workspaces that you can choose from. Go ahead and select a Workspace (1) and click the Ok button (2).

Now, click the Browse... button next to the Path: field.

With the Select Project menu open, expand the Workspace tree, select the .uproject file (1), and click the Ok button (2).

We are using the Lyra Sample Game as an example Unreal Project.

Now that you have specified the Workspace Name and Path, you are ready to open the Unreal Project with UGS by clicking the Ok button.

3 - Syncing from the Changelist Area

Now that you have opened a project with UGS, you will want to perform a common task with UGS, syncing from the Changelist Area.

Make sure that you have logged into Perforce before proceeding with the following steps.

Now that you have opened your project with UGS, locate the Changelist Area in the Main Menu.

Locate the change that you are using, it will have an arrow icon next to it.

To update to another change that was committed to the project's stream, double click on the other change while inside of the Changelist Area.

When the sync finishes, UGS updates the Output Log (3), the Changelist Area (2), and the Project Overview Area (1), which is where you will sync your project from in the next step.



4 - Syncing from the Project Overview Area

Now that you have performed a sync from the Changelist Area, having already opened the project with UGS, you will want to perform another common task with UGS, syncing from the Project Overview Area.

First, locate the Project Overview Area in the Main Menu.

Click the down arrow button next to the Sync Now - To... button link to open the shortcut menu.

Now, select the Latest Change option.

To learn more about navigating the interface, options, and menus built into UGS, check out the UGS Reference Guide.

At the end of the sync, UGS will notify you that you have successfully updated to the latest Change.



You have now reached the end of this guide, where you learned how to open a project and how to sync it from the Changelist and Project Overview Areas of the user interface. If you want to continue learning more about UGS on your own, including how to deploy a binary version of your project or how to navigate the interface with all of its menus and options, check out the next section of this guide.

5 - On Your Own!

Now that you have opened your project, having performed a couple of common sync methods with UGS, try the following:

Enable the Build and Run check boxes, which are found at the bottom of the UGS main menu to sync, build, and run your Unreal project.

If you are a developer looking to make use of the precompiled binaries feature for Creators who do not need to compile from source, read through the UGS Reference guide for more information on how to set up your build system to periodically submit a zip file containing Editor binaries to Perforce, enabling UGS to extract it to your creative's workspace.

This guide will go over the simplest route to setting up the UnrealGameSync (UGS) client for a new user, but if you need more detailed information or additional methods, check out the UGS Quick Start guide. This also assumes that your team has already set up their Perforce server, added all the proper source and content files, installed the proper version of Perforce on the machines you will use UGS with, and have distributed UGS to members who will use it.

If you need additional setup information, please refer to the UGS Overview.

Before you install UGS, confirm that you have set up a Perforce Workspace and have pointed it to the stream that you want to sync your project from. Try to make the local path to your workspace as short as possible.

Perforce (P4) setup is normally done by someone who has experience with the version control system, and has experience with using it with Unreal Engine (UE). If you are experiencing issues seeing files in Perforce, and have all the proper permissions, this may be due to having an out of date version of Perforce that does not handle the modern features used in Epic's tools. 2020.1 has been confirmed to work with UGS, but even more recent versions could as well.

Run the UGS Installer that was distributed by the owner of UGS at your studio. Make sure you have administrator privileges when running it.

When UGS starts up, you will see this UI:



In the Server and User fields, enter your Perforce connection settings that you use for connecting through P4V.

Set the Depot Path to where your binaries for UGS are being stored on Perforce.

After you've confirmed that these fields match your Perforce credentials and the location of the UGS binaries, click Connect.

After UGS successfully connects to your Perforce server, you will see the Getting Started menu. Click Open Project.



In the Open Project dialog box, click Browse and look for the Workspace you set up in step 1.

After clicking Open Project you can safely follow the Workspace method detailed in the UGS Quick Start Guide to get your project open. If you'd like to use the Local File method instead, see the Local File section of the UGS Quick Start Guide. The steps are also described here with updated screenshots.





Depending on how the Workspace was set up, you may need to uncheck Only show workspaces for this computer in the bottom left to see your workspace.

Now that you've selected your previously created workspace, click Browse next to the Path field, and select either a .uprojectdirs file (shown by enabling Show *.uprojectdirs files in the Select Project dialog), or a .uproject file from within one of the projects in that stream. For this example we'll be using a .uprojectidirs file, but you can just as easily select a .uproject file.





After this, the Path field will be filled in and you can click Ok to continue.



Before proceeding to sync everything to your machine and build / run your project, review the UGS Sync Filter Setup documentation, to see if Sync Filters will help your workflow.

Sync Filters are helpful for making sure that you're not syncing more data than you need. For example, if you have multiple large projects in the same stream, you can set up a filter to sync only the one you need to work on. These are very powerful, but they can lead to unintended consequences if they're too widely applied. Use them with care, and if in doubt, double check them with someone on your team that's comfortable with using sync filters.

After opening your project, you will see the main menu, which is typically where you'll be working from day-to-day.

For a full overview of this menu, refer to the UGS Menus Overview documentation.

Sync to the latest changelist for your build either by double-clicking the top-most changelist in the Changelists area by clicking Sync Now in the Project Overview area.

Select Latest in the Changelists area:



Click Sync Now:



The options for To… that apply to what changelist Sync Now syncs are Latest, Latest Good, and Latest Starred which are the absolute latest, the latest approved, and latest manually marked builds, respectively.

After your project is synchronized, you should be able to open the project in Visual Studio using the Visual Studio option in the Project Overview area, or open the project's Editor using the Unreal Editor option in the same area, if you're using precompiled binaries or you've built the Editor.

You may be prompted to build the project if you haven't before when opening the Editor, and you're not using precompiled binaries.



You can make building, opening the Visual Studio project, and running the project happen automatically using the After syncing options at the bottom of the window.



Orientation

Configuration

Auto-Update

Setting Up the Metadata Service

Setting up the MySql Backend

Troubleshooting

Disabling ONLY_FULL_GROUP_BY

Method 1: Running a Command

Method 2: Modifying the Option File

Setting up the Metadata Service

Integrating with your Build Process

Badges

PostBadgeStatus

Customizing for your Project

Branding

Project Config Files

Precompiled Binaries

Sync Filters

This page describes how to configure UnrealGameSync (UGS) for deployment as a studio.

Orientation

The source code for UnrealGameSync is under Engine/Source/Programs/UnrealGameSync.

The UnrealGameSync solution consists of the following projects:

Project

Description

UnrealGameSync

The main program.

UnrealGameSyncLauncher

Launcher for UGS, which automatically updates the main program executable when a new version is available.

MetadataServer

REST API that deploys alongside UGS to enable its full feature set, including commenting on builds, voting on build health and marking bad builds, and displaying Continuous Integration System (CIS) results submitted by PostBadgeStatus.

The Metadata Server must be deployed to the Windows Server machine with IIS 7.0 or higher and .NET 4.6.2 installed.



Installer

MSI installer for UnrealGameSyncLauncher. This is typically used to get the launcher on developer machines, which can then automatically update and run the program from Perforce.

Requires Wix 3.8 to build.



PostBadgeStatus

Utility to push build results to a MetadataServer instance.

Configuration

Deployment settings for UGS are specified in Engine/Source/Programs/UnrealGameSync/UnrealGameSync/DeploymentSettings.cs. You can modify this file with settings for your own team, then compile them into the executables you distribute.

These settings are:

Setting

Description

ApiUrl

URL of a running instance of the metadata service (see below) used to surface information to developers.

DefaultDepotPath

The default Perforce depot path that UnrealGameSyncLauncher should sync UnrealGameSync executables from.

See below for how this folder should be laid out.



bSendTelemetry

Whether to post telemetry about build times to the metadata service.

Auto-Update

To enable development on UGS out of band with different branches and projects, we distribute UGS via a self-patching mechanism that leverages Perforce for versioning.

A rarely updated launcher application is manually installed on each developers machine (UnrealGameSyncLauncher) using a Microsoft Installer (MSI) package (the 'Installer' project). Installing this creates a start-menu icon, and running it syncs the latest UGS executables from Perforce and runs them. That path is monitored, and if new executables are submitted, the program restarts and re-syncs them.

No workspace is required for these files to be synced; they are fetched from the Perforce server in a stateless way.

Wix 3.8 is required to build the installer.

The path that UnrealGameSyncLauncher uses to update the application is specified by the DefaultDepotPath variable compiled into the application via DeploymentSettings.cs (link above). This folder should be laid out as follows (example for DefaultDepotPath = "//depot/UnrealGameSync"):

//depot/UnrealGameSync/Release/UnrealGameSync.exe//depot/UnrealGameSync/Release/UnrealGameSync.exe.config//depot/UnrealGameSync/Release/UnrealGameSync.pdb//depot/UnrealGameSync/Release/Ionic.Zip.Reduced.dll

//depot/UnrealGameSync/UnstableRelease/UnrealGameSync.exe//depot/UnrealGameSync/UnstableRelease/UnrealGameSync.exe.config//depot/UnrealGameSync/UnstableRelease/UnrealGameSync.pdb//depot/UnrealGameSync/UnstableRelease/Ionic.Zip.Reduced.dll

There are two copies of UnrealGameSync checked in — one under the "Release" folder, and a second under the "UnstableRelease" folder.

The executable under the Release folder is used by default, but the UnstableRelease folder can be used to distribute test builds to users that opt in to it via the Application Settings dialog in UGS, or by holding down the shift key while starting the launcher.

New versions of UnrealGameSync can be pushed out simply by submitting new executables. The application will poll the folder for submitted changes, and restart and re-sync the binaries if any new changes are found.

Setting Up the Metadata Service

UGS can communicate with a web service to share information between team members. While it can run without this being set up, some of the more powerful collaboration features will not be available:

Surfacing build results and providing desktop notifications for build breakages

Allowing users to mark changes as good and bad, and indicate to other team members that they're investigating a problem with the build

Showing which users are synced to which changes

The metadata service is implemented with ASP.NET and requires setting up a MySql instance for the database backend.

It is recommended to host an IIS instance with the MetadataServer and the database backend on separate machines, as the database process should (ideally) be available to consume all available machine resources — however, this is not necessary.

Setting up the MySql Backend

Before continuing, note that the minimum requirement is MySQL 8.0.

To set up the MySql backend, perform the following steps:

Download the newest version of the MySql installer: https://dev.mysql.com/downloads/installer/

On Choosing a Setup Type, select Server Only.

In the Configuration Steps, set:

High Availability: Standalone MySql Server

Type and Networking: Either Server Computer if sharing with the IIS instance as mentioned above, or Dedicated Server if it is on a separate instance. Leave all the TCP/IP configuration and ports as their defaults.

Authentication Method: Use Strong Password Encryption

For Accounts and Roles:

Pick a root username and password.

Do not lose the password because this is the master account to the database.



Add another user as a service account that your IIS instance will use to connect.

Do not use the root account.



Windows Service (assuming the installation is on a Windows machine): You can leave these options alone.

Install MySql Workbench on your local workstation: https://dev.mysql.com/downloads/workbench/. With MySQL Workbench, you can view and manipulate the database. Also, you can perform administrative tasks such as backups and restores.

If you enable the ONLY_FULL_GROUP_BY function, you may run into errors while running the MySQL script. You can disable this function by either running a command (Method 1) or by modifying the MySQL option file (Method 2).

Start MySQL server from the command-line and run:

If you are a Windows user experiencing difficulty running MySQL server from the command-line, read the MySQL 8.0 Reference Manual, Starting MySQL from the Windows Command Line.

Required: If you do not know how to use MySQL options files, read the MySQL 8.0 Reference Manual, Using Option Files.

Locate and open the my.cnf option file.

Run this query to check sql_mode:

Review the query result, which should be similar to these values:

Edit my.cnf by entering the following sql_mode statement (under [mysqld]) with the values from the previous step:

Note that the statement does not include the ONLY_FULL_GROUP_BY value.

Restart the MySQL server.

For additional information, check out these MySQL 8.0 Reference Manual sections:

Server SQL Modes

MySQL Handling of GROUP BY

Setting up the Metadata Service

To set up the metadata service, perform the following steps:

Modify UGS executable to set ApiUrl

Ensure that ASP.NET Web Publishing tools are installed. You can find this package in the Visual Studio installation. If you don't have this package installed, building the project will fail with a "TransformXml task not found" error.

The project does not ship with a traditional web.config file, but instead comes with a web.template.config.xml, which is transformed against the .debug and .release XML files to dynamically produce a web.config. You want to check the web.template.config into source control, not web.config.

In the .debug and .release XML files, you can specify the path for where the MySql database will live via the "Connection String" property. This will look like a standard MySql Connection string:

service_account_username and service_account_password are the account credentials entered during the MySql setup process.

The database is seeded automatically the first time the site is launched.

To verify that the server is configured correctly, open servername.com/api/latest in a web browser. You should see something like this:

To ensure that the database initializes properly, the site will terminate if it cannot be created or found. If you deploy your site and receive a 404 error, this is likely the reason. Check your connection string and if on separate instances, the IIS instance can communicate with the database.

Integrating with your Build Process

Badges

UGS can surface build system results (and notifications that a build is "in progress") via Badges shown in the list of submitted changelists. If the build breaks, it will show a notification to developers that have submitted since it last succeeded. Clicking on a badge opens a web browser at a URL containing the build log.

This information is stored by the Metadata Service, and entries can be added to it using the PostBadgeStatus utility.

PostBadgeStatus

The command-line syntax for PostBadgeStatus is as follows:

Customizing for your Project

Branding

You can add a project logo to be displayed in UGS by placing a Build\UnrealGameSync.png file in the directory containing your project. The image will be scaled to a height of 126 pixels.

We recommend pixel dimensions of 200x126.



Feel free to download this reference image.

Project Config Files

You can customize the way that a project is presented to users with a project-specific config file. Project config files should be submitted to Perforce as <ProjectDir>/Build/UnrealGameSync.ini.

The following settings are available:

By default, UGS only displays build failure notifications resulting from changes to the project's source code. If you have any badges that should be shown to developers submitting content, allow them as follows:

If you add clickable buttons to a CL's description column, the corresponding buttons, when clicked, take users to a URL by running a regular expression over the CL description. For example, the following use case adds a badge next to every CL with a #jira tag with a link to the corresponding issue in Jira:

The following attributes were used in this example:

Attribute

Description

Pattern

Specifies a regex to match; it may capture portions of the matched text, which can be substituted later.

Label

Specifies a label appearing on the badge.

Group

Specifies an arbitrary identifier, grouping related badges rather than separating them with whitespace.

Color

Specifies hexadecimal RGB values for badges.

HoverColor

Specifies hexadecimal RGB values for badges on hover.

Url

Specifies the path to open with a C# Process. Open call when the badge is clicked.

Add a "Message of the day" along with a status panel color corresponding to a particular branch:

Icons are supported using :icon: syntax; however, :alert: is the only icon that is currently available.

Customize the size and arrangement of badges in the CIS column:

Define project-specific sync filters with the following:

UniqueId should be a randomly generated GUID.

Name displays in the UGS UI.

Paths can be separated by semicolons.

To modify existing category settings, specify its GUID, which is in the DefaultSyncCategories array in .../UnrealGameSync/Workspace.cs. By default, UGS will append your specified paths to the existing list, but setting Clear=true will replace it.

Precompiled Binaries

To enable users to download precompiled Editor builds instead of compiling locally, you can submit a zip file containing the required binaries to Perforce, and have UnrealGameSync sync and extract that instead. Doing so uses the same user interface as compiling locally, but any changes that don't have matching binaries will be greyed out. Once configured, users can opt in to using precompiled binaries by checking the Sync Precompiled Binaries item under the Options menu.

To configure a path for precompiled binaries, add a Build\UnrealGameSync.ini file under your project and reference a location on the Perforce server where they are submitted, like this:

It is recommended to use a location outside of your regular development stream for precompiled binaries, to avoid churn for anyone not using them. It is not necessary to maintain a separate workspace for this; UnrealGameSync will fetch them in a stateless way using the same login credentials that it uses to sync files.

It is not necessary to set up a metadata server to use precompiled binaries; the corresponding changelist for each zip file revision is parsed from the changelist description (it should start with the tag [CL 12345678]).

An example script showing how to create and submit editor binaries in the correct format is available at: Engine/Build/Graph/Examples/BuildEditorAndTools.xml

And a typical command-line to run it is as follows:

This will submit a zip file to //UE4/Dev-Binaries/++UE4+Main-Editor.zip, where ++UE4+Main is the name of the current branch with slashes escaped as '+' characters. The same path should be set as the value for ZippedBinariesPath in UnrealGameSync.ini.

Additional information about using BuildEditorAndTools.xml can be found in the comments at the start of the file.

Sync Filters

Sync Filters

User Interface

Custom Filter Syntax

UnrealGameSync.ini

Additional Reference Information

Sync Filters enable developers to update the client workspace with syntax that can be customized with UnrealGameSync (UGS). Keep reading to learn more about setting up Sync Filters for UGS.

User Interface

To access the Sync Filter menu, click the Options dropdown on the bottom right of the main UGS window, and then click Sync Filter...



Once inside the user interface, take note of the following options.



Element

Name

Description

1

Global Workspace Tab

These settings will be applied to all workspaces, unless a specific workspace conflicts, then the specific workspace will take precedence.

2

Current Workspace Tab

These settings will be combined with the global settings, and any conflicting settings will override the global settings.

3

General Settings

Sync all projects in stream syncs the entire contents of the stream, and Include all synced projects in solution will include any synced projects (and the solution) when the solution is generated for this workspace with UGS.

4

Sync Category Allowlist

Anything checked here will get synced, otherwise it will be ignored. For example, checking "Platform Support: PS4" will make UGS sync PS4 platform files, and unchecking "Platform Support: XboxOne" will make sure the XboxOne platform files are not synced.

5

Custom Sync Filters

Using the above syntax, or the syntax noted in modal dialogue behind the "Syntax" button, use this section to add single custom filters, line by line.

6

Combined Filters

Clicking this button will show you the summary of all filters you've created, including custom filters, the allowlisted filters, the defaulted excluded filters (not checked in categories), and general settings. If you need to see exactly what your filters list will look like, use this.

Custom Filter Syntax

Whether editing an UnrealGameSync.ini directly, or using the UGS UI, there is some syntax to be aware of when adding custom sync filters.

Specify a custom view of the stream using Perforce-style wildcards (one per line).

All files are visible by default.

To exclude files matching a pattern, prefix it with a '-' character (for example, -/Engine/Documentation/...).

Patterns may match any file fragment (eg. *.pdb), or may be rooted to the branch (eg. /Engine/Binaries/.../*.pdb).

The view for the current workspace will be appended to the view shared by all workspaces.

These syntax rules are available within the UGS UI as well in case you don't want to visit this page again.



UnrealGameSync.ini

For a quick primer on creating and editing a project-specific UnrealGameSync.ini, located at [Unreal Project Root Directory]\Build\UnrealGameSync.ini (and submitted to Perforce), read about Customizing for Your Project.

Additional Reference Information

A few reference items include the following additions.

Sync steps are run after any sync operation, with or without a following compilation step. This enables updating synced changelist information in custom version files.

When adding Build or Sync Steps, the following attributes are possible to use with the above syntax.

Attribute

Description

UniqueId

Randomly generated GUID.

OrderIndex

Ascending value that determines where this step is in the order of the steps list.

Description

Displays in the UGS UI.

StatusText

Displays when this step is being executed.

EstimatedDuration

How long the step will last in minutes, used for advancing the progress bar in the UGS UI the correct amount

Type

When a build step is created, it will have the type of Compile (default), Cook, or Other, which is used for deciding which attributes are valid to leverage. See the Types table below for details.

bNormalSync

Sets the flag that determines if the step should be run on each normal (user-initiated) sync.

bScheduledSync

Sets the flag that determines if the step should be run on each scheduled sync.

bShowAsTool

Sets the flag that determines if the steps should be shown as a tool in the "more tools" menu in the UGS status panel.

Attribute

Description

Type - Compile

Target is the name of the target for the compile step (for example, "BlankGame").

Platform is the platform that a compile step is intended for (for example, "Win64" or "Linux").

Configuration is the configuration for a compile step (for example, "Debug" or "Shipping").

Arguments are arguments to pass to the file or process being run.

Type - Cook

FileName is the path, including the file name, of the file to run for this step.

Type - Other

WorkingDir is the directory that the file should be run from.

bUseLogWindow enables whether or not to use the log window when reporting the step.

Arguments and FileName are the same as mentioned in Type - Compile and Type - Cook, respectively.

These paths are safe to be checked by default when you run the "clean workspace" tool in UGS.

These are files that should be excluded from the sync if using precompiled binaries.



Use the same syntax for custom filters in the UGS UI.



Project Overview

Changelists

Right-Click Context Menu

Log

Filter Menu

After Sync Options

Options Menu

Application Settings

Custom Build Steps

New Step

This page provides a reference for the menus and options available in UnrealGameSync (UGS).



Project Overview

Provides information about:

The stream opened.

The local path to the .uproject/.uprojectdirs file.

The latest sync status.

Option

Description

Settings

Change what file is being used to open the project.

Sync Now

Sync the project using the To… setting:

Latest Change: Sync to the absolute latest, could be unstable.

Latest Good Change: Sync to the latest change that has been used by another member of the organization (requires a metadata server).

Latest Starred Change: Sync to the latest change marked by someone using the Add Star context menu option in the Changelist area.

Unreal Editor

Run the project in the editor. Leverages the Precompiled Binary (PCB) editor when available.

SDK Info

View SDK availability in the stream.

Perforce

Open the stream in Helix Visual Client (P4V).

Visual Studio

Open the project in Visual Studio.

Windows Explorer

Open the project in Windows Explorer.

More -> Clean Workspace

Clean the Perforce Workspace

Show Log

Show the log of the latest sync in the Log section. Available upon a failed or cancelled sync operation.

Changelists

Sync to a particular changelist, and view information about each changelist.

Option

Description

Type

Code change, content change, or both.

Change

The changelist number in Perforce.

Time

Identifies when the change was submitted.

Author

Identifies who submitted the change.

Description

The description of the changelist written by its author.

CIS

The status of the Continuous Integration System (CIS) merge after this change. Requires a metadata server.

Status

Identifies who is currently using the build from a changelist, and their status with it. Requires a metadata server.

Right-Click Context Menu

Different options are available for each changelist, some of which are replicated from the Project Overview Area.



Option

Description



Currently Synced Changelist



Launch Editor

Available if the editor has been previously built for the given changelist.

Build

Build the changelist.

Rebuild

Rebuild the changelist.

Generate project files

Generate project files.

Open in Visual Studio

Opens the changelist in Visual Studio.



General Options



Sync

Sync with Perforce.

Sync (Just this Change)

Does not pick up changes in between the currently synced changelist and the selected changelist.

Mark as good

Visible to other users. Requires a metadata server.

Mark as bad

Visible to other users. Requires a metadata server.

Withdraw review

Cancels Mark as good or Mark as bad. Requires a metadata server.

Leave comment

Leave a comment that is visible to other UGS users. Requires a metadata server.

Start investigating

Mark the changelist as bad, along with all following changelists, and open up an investigation. Requires a metadata server.

Add Star

Add a star to the build that others can see, meaning it's a special or approved build. Requires a metadata server.

Copy Changelist

Copy the changelist number to your clipboard.

More Info…

Open the changelist in P4V.

Log

The log of the current sync operations, including Perforce operations and build operations. The right-click context menu allows for selecting and copying from the log.

Filter Menu



Option

Description

Type

Switch between code and content changelists, or both (default).

Badges

Filter based on CIS badges.

Show Build Machine Changes

Show build machine changelists as well as user changelists (off by default).

After Sync Options



Option

Description

Build

Use Unreal Build Tool (UBT) to build the project automatically in the Editor Build Configuration selected from the Options menu. Default is Debug.

Run

Automatically runs the output of the build step upon a successful build.

Open Solution

Open the solution in Visual Studio automatically after generating the project files.

Options Menu



Option

Description

Application Settings

Refer to the Application Settings table.

Scheduled Sync

Set what projects are synced and built, what changelist type, and when:



This can also be used to turn off the scheduled syncs.

Sync Precompiled Binaries

Sync PCBs automatically if available.

Auto-Resolve Conflicts

Automatically resolve Perforce conflicts.

Sync Filter…

Open up the sync filter options dialog. For more information on this dialog and its usage, refer to the UGS Sync Filter Setup documentation.

Editor Build Configuration

Select from Debug, DebugGame, or Development.

Customize Build Steps…

Refer to the Custom Build Steps table

Editor Command Line Arguments…



The Command Line Arguments window lets you edit, add, and remove command line arguments, as well as change the order they're passed. You can force this dialog on each launch if you find yourself editing command line arguments repeatedly.

Tab Names

Select from Stream, Workspace Name, Workspace Root, or Project File.

Show Changes

Independently toggle showing changes without reviews and showing changes by automated processes.

Time Zone

Select either Local or Perforce Server time.

Diagnostics…



Open the Diagnostics window for UGS. Clicking View logs in this dialog will take you to where UGS writes its logs. This can be very useful for diagnosing UGS-related issues.

Application Settings



Setting

Description

Startup and Shutdown

Configure the app to run on startup and keep running when minimized.

Default Perforce Settings

The credentials UGS will use to log into Perforce.

Updates

Where the program will look in Perforce to update itself, and if it's acceptable to use an unstable (test) version of the application.

Integration

Mechanisms for UGS to integrate with other applications and tools.

Custom Tools

Tools to use along with UGS.

Advanced



Option

Description

Retries on timeout

How many times to try again after a timeout.

TCP Buffer Size

The size of the TCP buffer in bytes.

Custom Build Steps

The Custom Build Steps window lets you modify and add new build steps.



Option

Description

Normal Sync

Run the step every time a user syncs.

Scheduled Sync

Run the step as part of a scheduled (automatic) sync.

Show as Tool

The step will be displayed in the Project Overview's More… option as a tool the user can run.

New Step…

Refer to the New Step table.

The New Step window shows all the fields necessary to define and execute a new build step task.



Field / Option

Description

Description

The name or short description of the step.

Status Text

The status text displayed when running the task.

Approximate Duration

How long it will take to run the step.

Compile

Build a target using UBT with the selected configuration, platforms, and additional command line arguments to UBT.

Cook

Cook through BuildCookRun given a specified profile.

Other

Run a generic executable from a given working directory with a given set of command line arguments. Also allows you to use the log window to show the program's output.

Variables



The Variables window will open up the environment variables for the task and allows editing them.

Basic Perforce Setup

Setting Up Streams

Generating and Uploading Precompiled Binaries

Using Precompiled Binaries from UGS

When you use UnrealGameSync (UGS) to sync and compile a build, it depends on your local machine having an IDE that can compile Unreal Engine (UE), and uses a series of scripts to automate the build process. However, many contributors on a project do not work with the code base or have access to an IDE. To make it possible for these users to run up-to-date builds of a project, UGS supports adding precompiled binaries (PCBs) to builds. You can submit PCBs to Perforce in a .zip file to associate them with a changelist. After that, UGS can sync and extract the .zip file's contents instead of compiling locally.

Doing this uses the same user interface as compiling locally, but any changes that don't have matching binaries will be greyed out. Once configured, users can opt in to using precompiled binaries by checking Sync Precompiled Binaries under the Options menu.

Basic Perforce Setup

The following procedure explains what users need in order to use precompiled binaries with their UE projects. This procedure assumes that the user already has Perforce set up for use as source control. To set up a Perforce server's contents for use with UGS, proceed as described here.

Users will need a single stream that contains their engine source code, dependencies that aren't generated by Unreal's build process, and their projects.

To make sure all required Unreal Engine files are present, users should copy from one of Epic's existing Perforce release streams.

Any of our release streams with the naming convention //UE/Release-4.xx should be fine to copy from. Make sure the .p4ignore.txt file is copied, as that will make sure no extra files are added to the copy of a stream after developers start building from it locally.

Users can also use the GitHub source build, run GitDependencies.exe, and upload the full source as well as dependencies that were gathered. Copying one of Epic's Perforce streams is still the recommended path, and a copy of the .p4ignore.txt file from a stream is required regardless of how the files are gathered, generated, and uploaded.

Either way you decide to set up your files within Perforce, make sure their file types and permissions match the release stream of whatever release you're setting up. If a file is marked as writable in our stream, it should also be writable in your stream.

A mismatch between what's writable and not might cause build or runtime failures. To check these permissions, open the stream in Perforce and check to the right of the filename.



If you find you need to change the file type or permissions in your stream, right click the file after opening it for edit, and click Change Filetype.



This will open up a menu that you're able to edit the file type and permissions to match our release stream.

If you get an Access Denied error for a specific file during a build or at runtime, it's most likely due to these permissions not being set up properly.

Any project that is used with UGS will need to be native and in the same stream as the files for the Unreal Engine. A native project is one that's discoverable from either the top level directory of Unreal's directory structure, or is discoverable one level deep from a path listed in a .uprojectidrs file (also at the top level of Unreal's directory structure).

Setting Up Streams

Users should use a separate stream to hold the Precompiled Binaries .zip file.

It's possible to use a single stream, but we highly recommend using a second, separate stream that all users with access to the first stream also have access to. This will avoid churn for team members that do not use PCBs.

It is not necessary to maintain a separate workspace for this; Unreal Game Sync will fetch the PCBs in a stateless way using the same login credentials that it uses to sync files.

To configure the stream where PCBs will be uploaded:

Add Build/UnrealGameSync.ini under the project's root directory and reference the Perforce location where the binaries will be uploaded. This is what UGS will search for when getting PCBs from Perforce.

An example Build\UnrealGameSync.ini entry:

UnrealGameSync.ini is required to be in the location [Unreal Project Root Directory]/Build/*

When specifying the ZippedBinariesPath, there are some details to remember:

The name //UE4/Dev-Binaries/++UE4+Main-Editor.zip needs to match the ArchiveStream argument mentioned in the upload section below, where ++UE4+Main is the name of the current branch with slashes escaped as '+' characters. The slashes should be present instead of the ‘+' characters when using the argument.

Any user account that has access to the PCB stream can upload a new set of PCBs to them, but how this is done is up to users, as this will vary depending on how a studio wants to deploy. A manual user can perform the upload, or an automated build node can also be responsible.

Generating and Uploading Precompiled Binaries

After the two streams are set up and users have permissions to access them, it's time to generate and upload the PCBs to the designated PCB stream.

To generate and upload the PCBs:

Sync the main stream's contents from Perforce.

Run a BuildGraph script that's based on our example, located at [UE Root]/Engine/Build/Graph/Examples/BuildEditorAndTools.xml, to generate and upload PCBs to the correct Perforce location (using the -ArchiveStream argument to specify the location). An example command using BuildEditorAndTools:

In this example, ShooterGame is a native project, and any projects users want to upload as PCBs need to be native as well.

Additional information about using BuildEditorAndTools.xml can be found in the comments at the start of the file.

ArchiveStream needs to match the ZippedBinariesPath specified earlier, but instead of the ‘+' characters to escape the slashes, slashes are used.

This example will submit a zip file to //UE4/Dev-Binaries/++UE4+Main-Editor.zip, where ++UE4+Main is the name of the current branch with slashes escaped as '+' characters. The same path should be set as the value for ZippedBinariesPath in UnrealGameSync.ini.

Make sure CL descriptions are in the right format. UGS expects each CL description to start with 'CL' followed by an 8-digit number (CL ########) so it knows which changelist the binaries are associated with.

PDBs are included in this .zip file, but they are stripped to reduce build size. This will allow callstacks to be gathered from crashes, but not allow for full debugging. If a team needs better symbol storage, they'll probably want to use a symbol server, which is left to their IT and Deployment teams to implement.

Using Precompiled Binaries from UGS

After the precompiled binaries have been successfully generated and uploaded to a secondary stream, using the files located in the primary stream, UGS should be able to detect and use PCBs with the main stream.

Enable the Sync Precompiled Binaries' option, and sync to latest. The pictured example is a stream without any precompiled binaries, but the option should be selectable if the binaries were set up correctly in the previous steps.



PCBs should be picked up and used instead of building the engine for anyone with this option selected.

Basic Troubleshooting

Troubleshooting Compile Errors

Specific Problems

Cannot detect Precompiled Binaries.

Cannot connect.

Failed sync or build due to too-long path.

UGS will not auto-update

Random Build Errors related to "can not find files".

Cooking from a UGS copy of the Editor fails.

Compiler limit: internal heap limit reached.

(Windows) Nothing happens when launching the game or editor, or the editor crashes right away with a weird error.

UGS crashes on launch.

Errors generating project files.

Error: System.ComponentModel.Win32Exception

Error: System.UnauthorizedAccessException

Could not find any Perforce workspace containing .../.uproject. Check your connection settings.

Connection to server failure.

System.Io.FileNotFoundException: Ionic.Zip.Reduced

UGS is not using the correct proxy server.

For many issues that you experience within UnrealGameSync (UGS), there is a tooltip that gives you more information on what is going wrong with an option you believe should be working correctly.

Basic Troubleshooting

When you need to ask a question to either Epic or your IT department about Unreal Game Sync, you should include basic information about your setup. This will help get you better, more efficient assistance. Some examples include:

Establish if you can reproduce the issue without using UGS. Often, issues that appear to be UGS-related, are not. For example:

If there is a crash, try opening the editor without using UGS.

If there is a Perforce sync issue, try using only Perforce instead of using it through UGS.

If you still see the issue without UGS involved, you will need to contact the team or department responsible for where the issue is actually occurring to get better assistance.

Establish if you are on the latest version of UGS. Version information can be accessed through either the Diagnostics menu (Main page > Options > Diagnostics... ), or it can be found in C:\Users[user]\AppData\Local\UnrealGameSync\ in UnrealGameSync.log. This can often be the cause of issues involving metadata and updates to UGS.

If you have determined that this is a UGS-specific issue, please refer to the common issues below first.

Troubleshooting Compile Errors

A large number of compile errors can be solved with simple troubleshooting steps:

Confirm which step in the Compile failed. For example, UnrealHeaderTool, ShaderCompileWorker, and so on.

Clean your Workspace through UnrealGameSync, by selecting More... > Clean Workspace in the Project Overview area. After that, attempt to sync or compile again.

Delete UE5.sln, then manually run GenerateProjectFiles.bat (Windows), or GenerateProjectFiles.command (Mac), and attempt to sync or compile again.

Attempt to manually compile using Visual Studio or XCode.

Attempt to sync or compile a Changelist marked as Good (indicated with a green circle)

If failure continues, select Options > Use Incremental Builds = False

Attempt to recompile

Ensure Sync Precompiled Editor is disabled

Only available in certain streams.

Confirm the workspace in Perforce has been configured properly.

This can be helpful in a lot of situations, but it does not cover if there are extra files within your workspace. If your workspace gets too complex to manage, you may need to contact your IT department for help, or remake your workspace and re-sync the data for it.

Specific Problems

Detecting PCBs can take a long time. UGS will first load all the CLs, then cross-reference them to see what PCBs are available. On a slower connection, this can take minutes, so be patient.

If the problem persists, this is likely a result of permissions issues with the stream where they're stored, or they are not getting created/uploaded correctly due to a build health issue. Contact your Perforce administrator and confirm your builds are successfully uploading the precompiled binaries, and that you have access.

The tooltip shown when hovering over Sync Precompiled Binaries will also give more information that is helpful when debugging this issue:



This is typically a Perforce or local network issue. We have seen problems with version 2019.2, and we recommend using a different version to start. Sometimes using P4V to relog into your Perforce server can help.

If, during a first time setup, you get the following error: Failed to sync application And your log contains: Couldn't find last changelist Make sure your Depot Path is set to the correct Perforce location provided to you by your Perforce administrator, and that the path is properly formatted with the two leading slashes, denoting a Perforce depot, and no terminating forward slash, as shown in the example below: //depot/path/to/UnrealGameSync/bin Then click Connect again.

If this is all set correctly, and your Perforce version is not 2019.2, you should contact your Perforce admin to confirm you have permissions for your depot path.

There is a 260 character path limit on most Windows versions that UGS is unable to circumvent. In fact, if UGS detects a path that will be longer than 260 characters, it will block syncing a project entirely. There is currently no way to disable this check in UGS.

To help with this, you may need to set up your workspace in a folder that is closer to the root (for example, D:/prj/workspace/ ). Also, try to enforce a file naming structure that shortens your file names as much as possible.

This can also occur in rare instances if you have decided to sync your project using a .uprojectdirs file instead of a .uproject file. This can be worked around by instead setting up the project in UGS with a .uproject file.

Select Settings



Select Browse for both the Name and the Path of the Workspace you are using.

Workspace Name:





Workspace Path:



Instead of selecting a .uprojectdirs file like in the setup tutorial, select a .uproject file within that stream.

Attempt to sync again.

Case 1: This one is typically due to file contention on the machine. This can be solved by closing UGS, confirming there are no active UGS processes running, and deleting [AppData]/Local/UnrealGameSync/Latest/ which typically contains the files in contention that prevent the update.

If the deletion of that folder fails, you should be shown what file is held in contention and what process is holding on to it. If you are unable to stop that process, rebooting should resolve that issue and allow you to delete that folder.

Afterwards, you can use the UnrealGameSyncLauncher to download the latest update.

You may need to remove UnrealGameSync from your startup applications before restarting, deleting the folder, re-adding UGS to the startup applications, and restarting from there depending on how you set up UGS.

Case 2: If a user either does not have the proper connection, or the proper permissions to see the Perforce path where the UGS updated binaries are, UGS can hang indefinitely, not allowing the user to proceed. If this is the case, either update the Depot Path in the connection settings, or speak with your Perforce admin to get the correct access to the files.

This is usually a Perforce related error, and not necessarily UGS-related. If your workspace has issues, first try force-syncing the entire engine directory, and if all else fails, create a new workspace.

This can also happen when Sync Filters are not configured properly, either with something important for building getting filtered out (for example, Win64 folders), or a dependency to a file that is covered by a sync filter has been introduced accidentally. Refer to the UGS Sync Filter Setup documentation for more information.

If you are getting an error similar to,ERROR: Failed to find command BuildCookRun, when attempting to cook or package from a precompiled binary version of the engine distributed through UGS, it could be due to needing the source folder for this operation.

Currently, even if you are not actually building the source code, you will need the source directory for cooking and packaging through the precompiled binaries used by UGS. If this is part of your workflow, check your sync filters to make sure you are not excluding the source directory, even if you are not working directly with it.

If you encounter an error similar to any of the following when compiling:

You will need to use a workaround.

Short-Term Workaround: Restart your machine as this clears cached memory and can temporarily unblock a compile.

Long-term Resolution: You should contact your IT department with a description of your problem. In some cases, increasing the maximum page file size through the Control Panel may help, but this is something that would need to be done through IT at most studios.

Most of the time, this occurs on a machine that has not been configured to run Unreal before. If you are on a new machine, have everything synced, and everything else seems to be in working order, but nothing happens when launching, try running the UEPrereqSetup_x64.exe application located at:

<Path to Workspace>/Engine/Extras/Redist/en-us

This should install the prerequisites needed to run Unreal on a machine that has not done so previously.

UnrealGameSync uses the P4 Command Line tools to query Perforce for updates. Not having Command Line tools installed is the most common cause of a crash on launch.

To resolve this problem:

Rerun the Perforce Client Installer

During installation, ensure command line tools are included

Check for P4 Command Line tools:

Open a Command window

Enter p4.

Press Enter.

If P4 Command Line tools are installed, a series of help commands are printed.

If P4 Command Line tools are not installed, the error message File not found is printed,

When generating project files, if you encounter an error similar to:

This is typically caused by missing Visual Studio Components.

Ensure all Visual Studio Components are installed according to the instructions in the Visual Studio Setup documentation.

If you encounter an error similar to:

error MSB3644: The reference assemblies for framework ".NETFramework,Version=v4.6.2" were not found.

Install the Microsoft SDK and Developer Pack

When building using UGS, if the following error appears:

This is caused by installing the .NET Framework and other developer packages, and trying to sync before restarting the computer.

To correct this problem, restart the computer, generate project files again, and rebuild.

This occurs typically with versions of UGS that haven't been updated in some time and looks like:

To resolve the problem:

Navigate to C:[user]\AppData\Local\UnrealGameSync

Delete UnrealGameSync.ini

Removing this file will remove user data, including:

Saved build configurations.

Editor command line arguments.

Favorited open projects.

Precompiled editor and incremental build elections.

If you are setting up UGS for the first time and add a project using the local file dialog, but still get the above error:

Try adding the same file through the Open Project > Workspace > New… dialog.

If you are not able to, this is a Perforce permissions issue and you will need to work with your Perforce administrator to make sure you have the correct access permissions for the stream and files that your workspace targets.

Attempting to connect to your Perforce server with an unrecognized port number will return the following error:

Perforce client error: Connect to server failed; check $P4PORT

To fix this problem:

Open a command/terminal window

Enter p4 set P4PORT=<_local P4 port from admin_>.

Press Enter.

Close and relaunch UGS.

Likewise, connecting with an unknown user will generate the error:

Access for user 'USERNAME' has not been enabled by 'p4 protect'

To fix this, open a command window and:

Enter p4 set P4USER=<perforce.username>.

Press Enter.

Close and relaunch UGS.

Verify that C:\Users[User.name]\AppData\Local\UnrealGameSync\Latest contains Ionic.Zip.Reduced.dll

If it does exist, you are likely missing a file from the workspace and should force sync the Engine\Binaries folder in your workspace

Otherwise, check that your anti-virus is not quarantining it. Follow the steps for your anti-virus to "trust" the file

If you're unsure how to do that, proceed as follows:

Terminate UGS from the task manager.

Delete the contents of C:\Users[User.name]\AppData\Local\UnrealGameSync\Latest.

Restart UGS.

Confirm after UGS opens that the file now exists.

If after opening the Diagnostics menu (bottom right corner of main window, Options -> Diagnostics at the very bottom of the list), the diagnostics menu shows that you're using your proxy server but syncing is still failing, proceed as follows:

Open a new project in UGS

Look for Using default Perforce server settings.

Click on Change.

Disable Use default connection settings.

Enter your proxy server and user name in the provided fields.

Click Ok.

Opening the UGS diagnostic should now show the correct server settings.



BuildGraph

Making an Installed Build

Installed Build Script Options

Including Additional Files

Registering an Installed Build

Choosing this Deployment Method

Developers always look for ways to efficiently deliver build solutions for a variety of hardware profiles and operating systems. An Installed Build is a fully featured Unreal Engine (UE) build that can be redistributed to quickly get your team up and running with the Engine. From a technical standpoint, an Installed build contains precompiled binaries for UE and a static library for each target platform in development and shipping configurations.

The Installed Build process automates build packages and tools that are needed to make an Installed Build version of UE. In summary, making an Installed Build is the process of setting up default target platforms, compiling UE with its tools and editor, running tests, and deploying the Installed Build version of UE to targeted platforms.

In addition to making your own build, you should download UE from Launcher, for more information see Downloading Unreal Engine Source Code.

Making an Installed Build

You can create Installed Builds using the BuildGraph scripting system with the Installed Build script located in folder with your dowloaded source code at [UERoot]/Engine/Build/InstalledBuild.xml.

To create an Installed Build:

Open Command Prompt on your system;

Input command line to run the Installed Build Script by invoking the AutomationTool. This command line may looks as following (replace [PLATFORM] with either Win64 or Mac, depending on your system):

Let's get familiar with the parts of this command line:

C:\EpicSource\UE_5.0\UnrealEngine-5.0\ - location of downloaded source code (could be different on your PC).

Engine\Build\BatchFiles\RunUAT.bat - location of Unreal Automation Tool command file, that you use for command of building;

-target="Make Installed Build [PLATFORM]" - target platform, you want to build Engine (replace [PLATFORM] with either Win64 or Mac);

-script=Engine/Build/InstalledEngineBuild.xml - location of the file, that contain options for installation process;

also, you can adjust additional Installed Build Script Options;

If you use additional Installed Build Script Options, your code will look as following (depends on settings you adjust):

By default, your Installed Build should be located in the LocalBuilds/Engine/ folder of your Unreal Engine directory. If you specified a different directory to publish to, navigate to that directory instead.

Configure your build using the following Installed Build Script Options:

Installed Build Script Options

The InstalledEngineBuild.xml script makes an Installed Build with all of the default options and platforms enabled; however, it can be configured using a set of specified options, enabling you to target which platforms to include, where to publish the build to, etc. You can view a list of available options for customizing the build process (along with a list of nodes that will be built), by passing the -listonly option to the script.

The available options are:

Option

Default

Description

-set:HostPlatformOnly=[true/false]

false

A helper option to make an installed build for your host platform only, so that you don't have to disable each platform individually.

-set:WithWin64=[true/false]

true

Include the Win64 target platform.

-set:WithWin32=[true/false]

true

Include the Win32 target platform.

-set:WithMac=[true/false]

true

Include the Mac target platform.

-set:WithAndroid=[true/false]

true

Include the Android target platform.

-set:WithIOS=[true/false]

true

Include the iOS target platform.

Enabling this option requires a Mac set up for remote building.

-set:WithTVOS=[true/false]

true

Include the tvOS target platform.

Enabling this option requires a Mac set up for remote building.

-set:WithLinux=[true/false]

true

Include the Linux target platform.

-set:WithLumin=[true/false]

true

Include the Lumin target platform.

-set:WithHTML5=[true/false]

true

Include the HTML5 target platform.

-set:WithPS4=[true/false]

false

Include the PS4 target platform.

Enabling this option requires the PS4 SDK.

-set:WithXboxOne=[true/false]

false

Include the XBoxOne target platform.

Enabling this option requires the Xbox One SDK.

-set:WithDDC=[true/false]

true

Build a stand-alone derived-data cache for the engine content and templates.

Building a stand-alone Derived Data Cache (DDC) for the Engine and Template content can be one of the slowest aspects of the build. If you don't need a stand-alone DDC, you can skip this step by appending -set:WithDDC=false to the command line.

-set:WithFullDebugInfo=[true/false]

false

Generate full debug info for binary editor and packaged application builds.

-set:SignExecutables=[true/false]

false

Sign the executables produced if you have to set up your machine to sign executables as part of the build process.

-set:AnalyticsTypeOverride=[ID]

N/A

Identifier for analytic events to send.

-set:GameConfigurations=[Configurations]

Development;Shipping

Specifies the configurations for packaged applications.

Including Additional Files

RuntimeDependencies (set in build.cs files for each module) automatically collate and determine which files are included in an Installed Build. However, there are some required files that cannot be included this way, so they're defined in [UERoot]/Engine/Build/InstalledEngineFilters.xml. The InstalledEngineFilters XML file also lists patterns of files that should be excluded from the build, determining the types of files that need to be stripped or signed, and finally, deciding what projects to build the DDC for. If you need to include any additional files with the Installed Build, the InstalledEngineFilters XML file is a great place to start.

Registering an Installed Build

UE has the concept of "foreign" projects and "non-foreign" projects. Foreign projects are those stored in a separate directory tree to the Engine, while non-foreign projects are stored in sub-directories of the engine root, referenced by the UEGames.uprojectdirs extension.

The "EngineAssociation" field in a .uproject file identifies which Editor version will open the project. For non-foreign projects, it is left blank, because being non-foreign implies the existence of an Editor in a (known) relative location, up from the directory hierarchy of the project. For foreign projects using Engine builds installed by the Launcher, the field will contain the official version number (such as "5.0"), and the Launcher can find the appropriate Editor binary (assuming it has been installed) based on its list of installed applications. For foreign projects using an Engine build distributed by means other than the Launcher, the Engine build's random unique identifier can be used to find the installed directory via a globally-accessible data repository, specifically, the registry on Windows, or a file in the library folder on Mac. If an association with an installed Editor build cannot be found, the user will be prompted to select a version, and the .uproject file will be updated with the selected version.

When distributing an Installed Build to a team, make sure that the build's identifier is common to everyone. This will prevent the Editor from prompting for version selection, and then updating the .uproject file with a locally-generated unique identifier. Setting a custom identifier can be done as follows:

On Windows, add a registry key to HKEY_CURRENT_USER\SOFTWARE\Epic Games\UnrealEngine\Builds that uses your identifier as its key, and the path to the Engine as its value. For example, the Key might be MyCustom419 , and the value might be D:\CustomUE.

On Mac, open /Users/MyName/Library/Application Support/Epic/UnrealEngine/Install.ini and add an entry to the [Installations] section that uses your identifier as the key, and the path to the Engine as the value. For example:

Choosing this Deployment Method

If you rarely need to change the engine, and if you're looking for a way to quickly (and efficiently) deliver build solutions for a variety of hardware profiles and operating systems, you can deploy an Installed Build of UE (or download the engine from our launcher).

Keep in mind, though, that if you're not looking for a read-only distribution of UE (that can be installed into C:\Program Files), then this method isn't for you, mainly because it's designed to create standalone, read-only engine content, source code, and third-party libraries. Although we provide Installed Engine Builds as a courtesy through the Epic Games Launcher, we don't consume this method for our internal games teams. Furthermore, we treat this as a standalone deployment product in its own right.

Specifying Configurable Variables

Config Files and Inheritance

Per-Instance Configurations

Configuration File Structure

Configuration Categories

File Hierarchy

Working with Configuration Files

File Format

Configuration files can be used to set values for properties that will be initialized when the project is loaded. Configuration is determined by key-value pairs, arranged in sections. One or more values can be associated with a given key.

Unreal Engine (UE) configuration files are used for object and variable default values. User input configuration can be used for key bindings. By default, DefaultEngine.ini and DefaultGame.ini are created when you create a new blank project with the Project Wizard. New projects that begin with templates may also generate DefaultEditor.ini and DefaultInput.ini configuration files if needed.

The SaveConfig() function can be called on a class with the Config class specifier. This saves any properties marked with the Config property specifier to the appropriate configuration file. Generally, variables saved by SaveConfig() are in a section title which follows the format [(package).(classname)]. For instance, the [/Script/Engine.Engine] section in DefaultEngine.ini points to the Engine class stored within the Engine package. There are some exceptions with hard-coded section names.

A number of the settings previously available only through editing configuration files are available in Unreal Editor in the Project Settings editor.

Specifying Configurable Variables

In order to specify which variables should be read in from configuration files, the class that contains those variables must first be given the Config specifier in its UCLASS macro.

A category (for example, Game) must be supplied for the Config specifier. This determines which configuration files the class's variables are read from and saved to. All possible categories are defined in FConfigCache.ini. For a list of all configuration file categories, see Configuration Categories.

Decorating a class with the Config specifier just indicates that that class can have variables read in from configuration files, and specifies which files the configurations are read from. To specify a particular variable as read in and saved to a configuration file, the Config specifier must also be supplied to a UPROPERTY() macro.

No category is supplied to the property's Config specifier. The ExampleVariable property can now be read from any Game configuration file in the configuration file hierarchy, as long as the information is specified with the following syntax:

Config Files and Inheritance

The Config, UCLASS, and UPROPERTY specifiers are inherited. This means that a child class can either read in or save out all variables specified as Config in the parent class, and they will be in the same configuration file category. The variables will all be under a section title with the child class's name. For example, the configuration file information for a ChildExampleClass which inherits from the ExampleClass above would look like the following lines, and be saved in the same Game configuration files.

Per-Instance Configurations

Unreal Engine has the ability to save the configuration of an object to any desired configuration file. If the PerObjectConfig specifier is used in the UCLASS macro, configuration information for this class will be stored per instance, where each instance has a section in the .ini file named after the object in the format [ObjectName ClassName]. This keyword is propagated to child classes.

Configuration File Structure

Each configuration category has its own hierarchy of files which specify engine-specific, project-specific, and platform-specific configurations.

Configuration Categories

Compat

DeviceProfiles

Editor

EditorGameAgnostic

EditorKeyBindings

EditorUserSettings

Engine

Game

Input

Lightmass

Scalability

File Hierarchy

The configuration file hierarchy is read in starting with Base.ini, with values in later files in the hierarchy overriding earlier values. All files in the Engine folder will be applied to all projects, while project-specific settings should be in files in the project directory. Finally, all project-specific and platform-specific differences are saved out to [Project Directory]/Saved/Config/[Platform]/[Category].ini.

The below file hierarchy example is for the Engine category of configuration files.

Engine/Config/Base.ini

Base.ini is usually empty.

Engine/Config/BaseEngine.ini

Engine/Config/[Platform]/base[Platform]Engine.ini

[Project Directory]/Config/DefaultEngine.ini

Engine/Config/[Platform]/[Platform]Engine.ini

[Project Directory]/Config/[Platform]/[Platform]Engine.ini

The configuration file in the Saved directory only stores the project-specific and platform-specific differences in the stack of configuration files.

Working with Configuration Files

File Format

Typical configuration files consist of sections of key-value pairs, arranged as follows:

+ - Adds a line if that property does not exist yet (from a previous configuration file or earlier in the same configuration file).

- - Removes an entry from the property (but it has to be an exact match).

. - Adds a new entry to the property regardless of whether that entry already exists..

! - Clears all entries from the property. The line must still have an = but what comes after it is ignored.

. is like + except it will potentially add a duplicate line. This is useful for the bindings (as seen in DefaultInput.ini), for instance, where the bottom-most binding takes effect, so if you add something like:

It will work appropriately. Using a + there would fail to add the last line, and your bindings would be incorrect. Due to configuration file combining, the above usage pattern can happen.

The syntax for arrays in .ini files are formatted as follows:

Most people seem to be under the impression that the semicolon denotes comments in configuration files, but they are not (FConfigFile::ProcessInputFileContents does not actually treat them, or any other string, as a comment delimiter). This behavior is intentional. Technically any character can represent a different key-value pair. Typically, a semicolon is placed at the beginning of a new line. It works like a comment, but it is not actually.

Where the DDC Is Stored

Types of DDCs

DDC Pak

Shared DDC

Using a Shared DDC

Setting Up Shared DDC

Disabling a Shared DDC

Building Derived Data

Mounting Your DDC Folder

Distributing with a DDC

DDC Settings

Where are DDC settings kept?

Common Questions

Q: Can I have multiple DDC settings?

Q: I am short on disk space. Can I move the Local DDC elsewhere?

Q: I have a slow network connection. Can I turn off the Shared DDC?

Q: Can I change the Shared DDC path?

Q: How can I diagnose DDC issues?

Q: What is the S3 DDC?

Q: What is IDDCUtilsModuleInterface?

Q: How do I create a DDC Pak?

DDC stands for Derived Data Cache.

Many Unreal Engine Assets require additional "derived data" before they can be used. (A simple example would be a Material that has a shader). Before the Material can be rendered, the shader must be compiled for the platform the editor is running on.

Because the derived data is large, and at times may need regenerating, it is not checked into source control. Instead it's kept in the Derived Data Cache (DDC).

Where the DDC Is Stored

Depending on how your project and system are configured, there can be several DDC caches in a hierarchy that ranges from fast to slow. When assessing derived data, your system will do the following to determine how quickly it can access it:

When a piece of derived data is needed, the fastest cache is checked first, then the next fastest, and so on, until the data is found.

When the data is found, it is copied into the fastest local cache so that it is quicker to access next time.

If the data is not found, then it is first generated, then asynchronously copied into the caches so it is available for you (and potentially your team) in the future.

Content stored in the DDC is disposable, and can be regenerated at any time using the data stored in the .uasset file. Storing these derived formats externally makes it possible to easily add or change the formats used by the engine without needing to modify the source Asset file.

Types of DDCs

Typically, you will have at least the following two caches:

Boot DDC: Startup files that are loaded into memory to increase boot times.

For Example: ProjectDir/DerivedDataCache/Boot.ddc

Local DDC: Derived data for your projects.

For Example: EngineDir/DerivedDataCache

However, your project may also be set up to use a DDC Pak or Shared DDC.

DDC Pak

If you download Unreal Engine from the Epic Games Store, the engine will come with a DDC Pak (.ddp). The DDC Pak contains derived data for all engine content, so you can start working without compiling shaders and so on. Similarly, some samples are shipped with a DDC Pak for the same reason.

Engine DDC Pak

For Example: EngineDir/DerivedDataCache/Compressed.ddp

Project DDC Pak

For Example: ProjectDir/DerivedDataCache/Compressed.ddp

Shared DDC

One of our strongest recommendations for teams in the same location is that they set up a shared DDC. This is a network drive that all team members and build machines can read/write to. This then writes off the cost of creating any required DDC data across the entire team. For example, when an artist edits a shader, the DDC data will be written straight to the DDC share.

Shared DDC: Will be either a network or mapped drive.

An example of a shared drive would be: \epicgames.net\root\DDC-Global-Fortnite

Using a Shared DDC

A studios should use a shared DDC that all users in a particular location can access. This way, only one person needs to build the derived Asset format(s) and they will be automatically available to all other users. There will occasionally be stalls when Assets need to be processed, but the results are stored and shared. Even on a fairly small team, sharing Asset processing work in this way will eliminate most processing time.

It is not advised to copy an entire DDC across the internet, or back up your DDC, or restore a DDC from a backup. While not necessarily harmful, this would be a waste of time—it takes longer to transfer the amount of data stored in the DDC than it does to generate it from scratch locally. If you have a large project and want to distribute pre-built DDC data, you should generate a DDC Pak.

Setting Up Shared DDC

As you may see in BaseEngine.ini, the editor is already set up to use a Shared DDC that can be enabled one of three ways.

Here are the options from most to least recommended.

Add an override (as pictured below) in the DefaultEngine.ini for your project that sets the path to a valid location for your team.

[DerivedDataBackendGraph] Shared=(Type=FileSystem, ReadOnly=false, Clean=false, Flush=false, DeleteUnused=true, UnusedFileAge=10, FoldersToClean=10, MaxFileChecksPerSec=1, ConsiderSlowAt=70, PromptIfMissing=false, Path=\YourCompanyServer\DDC, EnvPathOverride=UE-SharedDataCachePath, EditorOverrideSetting=SharedDerivedDataCache)

Set an environment variable (as pictured below) of UE-SharedDataCachePath (On Mac/Linux UE_SharedDataCachePath) to the folder to use.

In the editor, set the SharedDerivedDataCache variable.



Click image for full size.

You don't have to do anything special to \YourCompanyServer\DDC; as long as it is writable, the engine will create the structure it needs.

Disabling a Shared DDC

Developers working remotely with a project that has a shared DDC configured may experience poor performance due to the fact that it takes longer to access DDC data than it does to generate it. To temporarily disable a shared DCC, use one of the methods below:

Pass -ddc=noshared on the command line.

Set the environment variable to a local drive hard drive:

UE-SharedDataCachePath=None

On Mac: UE_SharedDataCachePath=None

Building Derived Data

The user who imports the Asset is the one who builds the derived data since they will most likely be using and testing that Asset in the Engine. However, there may be times when a new Asset needs to be processed. This happens automatically on an as-needed basis and should not result in much of an impact when running on fast hardware, though there may be occasional stalls.

You can fill your DDCs at any time by running the following command:

Epic Games does this on a nightly basis to ensure that the DDC is always primed, but it is not necessary as the general automatic caching feature should suffice.

Mounting Your DDC Folder

For the DDC to be used over your internal network, the folder that contains the DDC must be mounted to a network drive. If you are unfamiliar with how to do this, see Map A Network Drive on Windows.

Distributing with a DDC

Cooking is the preferred method for packaging games since cooked builds do not need or use a DDC. However, DDCs can be packaged for distribution if the need arises.

To package a DDC:

Run UE4Editor.exe from the UE4/Engine/Binaries/Win64 directory, passing the arguments shown below:

UE4Editor.exe ProjectName -run=DerivedDataCache -fill -DDC=CreatePak

This creates a DDC.ddp file in the UE4\ProjectName\DerivedDataCache directory.

The engine automatically detects and uses the .ddp file.

DDC Settings

Where are DDC settings kept?

DDC settings are kept in DefaultEngine.ini under the [DerivedDataBackendGraph] section. You can view the defaults in BaseEngine.ini.

Common Questions

Q: Can I have multiple DDC settings?

Yes! Just create a new [YourDDCSettings] entry in DefaultEngine.ini and then run the editor with -ddc=YourDDCSettings.

At Epic, we do this for three reasons:

For teams in offices that want to use their own DDC instead of the global one.

When creating DDC Paks we use one of several options that control what goes into the .pak file, such as [CreateInstalledEnginePak].

For people working from home who don't want to use a Shared DDC due to slower internet or not having VPN enabled.

You'll see that BaseEngine.ini contains several DDC entries by default, including NoShared, which is used for #3 above (-ddc=NoShared).

Q: I am short on disk space. Can I move the Local DDC elsewhere?

Yes! You can adjust this in your project under the Editor Preferences. Aditionaly you can set an environment variable of UE-LocalDataCachePath to a path of your choice. For example: UE-LocalDataCachePath=d:\DDC.

At the command prompt, type "setx UE-LocalDataCachePath d:\DDC".

Restart Unreal Engine, along with any application you launch it from, such as Epic Launcher, UGS, or Visual Studio.

This can be used when you are short of space on your primary drive, or when you are working on multiple branches and wish to ensure the data isn't duplicatednote

Q: I have a slow network connection. Can I turn off the Shared DDC?

Yes! There are two options, depending on whether you want this to be temporary or permanent:

If you set the environment variable for a DDC to None it will disable it. In this case, you would set UE-SharedDataCachePath=None.

Launch the editor with -ddc=noshared.

Q: Can I change the Shared DDC path?

Yes! You can change it by setting the UE-SharedDataCachePath mentioned above.

However, you should never set UE-SharedDataCachePath to a local path! Doing this means you would have both Local and Shared caches on your machine—twice the disk space for zero gain!

Q: How can I diagnose DDC issues?

If you think your editor is not correctly reading DDC data, then search your logfile for LogDerivedDataCache.

Here you can see:

There's no project or Engine Pak cache, which is what would be expected as I compiled this build myself from Perforce.

My local data cache path is mapped to d:\DDC and is writable.

I am using the Epic shared cache, which is writable.

You can also run with -logcmds="LogDerivedDataCache Verbose" to turn on verbose logging.

Q: What is the S3 DDC?

The Fortnite DDC is extremely large due to the amount of content we have. When Covid19 struck, we quickly realized that it was very inefficient for developers to pull all this data from a network share over the limited bandwidth of a VPN to the office, so instead we distribute the most commonly used data via S3.

Setting up the engine to use the S3DDC is extremely easy, but you will need to set up automation that generates the DDC content and uploads it to S3.

Q: What is IDDCUtilsModuleInterface?

This interface allows you to use ? Name arguments in your DDC settings that can then be resolved dynamically at runtime based on platform or domain.

Unfortunately, we don't ship an example of this, but implementing it is straightforward:

Q: How do I create a DDC Pak?

Creating a project-specific DDC:

UE4Editor.exe ProjectName -run=DerivedDataCache -fill -DDC=CreatePak

This commandlet will create a DDC for all content in the project. Alternatively, you can simply supply -DDC=CreatePak while running automation or even a user session to generate a more targeted set of content.

Creating an Engine DDC:

UE4Editor.exe -run=DerivedDataCache -fill -DDC=CreatePak

Getting Started

Take Recorder

Tutorials

Reference

With Multi-User Editing, you can connect multiple instances of Unreal Editor together to work collaboratively in a shared editing session, building a single virtual world together with your teammates and colleagues in real time.

Multi-User Editing has been designed and tested in large-scale virtual film & TV production teams, where potentially dozens of operators work together on set during a live shoot. These operators work in Unreal Engine to design, build, and light the virtual world, emulating the way crews build physical sets. This helps the director, cast, and crew visualize the results of blending live action and CG content together while they rehearse and film live action shots, instead of having to wait for post-production.

To see Multi-User Editing in action, watch the realtime virtual production demo from SIGGRAPH 2018.



Although Multi-User Editing was developed in the context of virtual film and TV production, the same kind of live collaboration is potentially useful for any scenario where you have multiple users that need to work on the same content. Any Unreal Engine development project may be able to use Multi-User Editing to reduce iteration times, get instant feedback on changes, and boost the team's creativity.

Getting Started



A conceptual overview of how the Multi-User Editing system works.



Provides step-by-step instructions that will get you up and running using Multi-User Editing for your Project.



A breakdown of the Multi-User Server user interface.

Take Recorder



How to enable Take Recording in a Multi-User Editing session.

Tutorials



Save your session changes in an archive that you can restore at any time.

Reference



Contains reference information for Project settings, console commands, and command-line parameters involved in Multi-User Editing.

During a Multi-UserEditing session, you can control which nodes are included in a Take Recording session. You can assign nodes as recording nodes which may contain additional data not visible in the Operator session, such as with nDisplay or game nodes in a multi-user session.

In the example below, there are two nodes connected to the session.

Computer A: the main operator who is controlling the stage using the multi-user feature.

Computer B: an editor node assisting the main operator session.



In the Take Recorder panel, you will also see a similar interface when using a new settings section.

There is a master property called Synchronize Take Recorder Transactions, which controls the trigger for sending multi-user recording events. When this property is disabled, the corresponding node will be greyed out which indicates that the user cannot trigger a multi-user recording.

The Multi-User Take Synchronization property also has a shortcut to the Exclusion Filters in the Multi-User Take Settings so that users can filter sources. Previously, it was not possible to use Take Recorder in a multi-user setting without assigning a filter to prevent transacting recorded takes.



In the image below, Synchronize Take Recorder Transaction is disabled, and the multi-user icon is gone which indicates that you will be recording locally.



In a connected session when Synchronize Take Recorder Transaction is enabled, connected nodes will have two properties that indicate their participation in a multi-user recording session.

Record on Client: this is the client that is doing the recording. In a Virtual Production stage, this will typically be a single machine that is the authority for the recording.

Transact Sources: these are the nodes that communicate the Sources in the Take Recorder for other nodes. In the image above, the source Actor_Blueprint is provided by the Operator node. Any changes to the source property made by the Operator node will be propagated to the other nodes. If the other nodes change the source, the change will not propagate to other nodes.

Once you have assigned sources and specified at least one node that is recording, the multi-user record icon will reappear, and you can begin recording.

It is possible to have multiple recording nodes active simultaneously. However, this configuration will produce multiple Take Recorder assets which will have the name of the recording node appended.For example, Scene_01_03 will become Scene_01_03_computer_A and Scene_01_03_computer_B if both computer_A and computer_B are Recording.The user is shown a warning if they have multiple active recording nodes.

If you do not provide a source, it is not possible to start a recording.



Synchronizing Transactions

Levels: Instant Sync

Other Assets: Sync on Save

Sequencer: Playback Sync and Optional UI Sync

Presence

Location and Viewpoint

Session Change History

Asset Change History

Avoiding Conflicts

Locking Dragged Selections

Locking Assets

Undo and Redo

Starting from a Common State

Session Validation

Transactions and Persisting Changes

Redundancy

Multi-User Editing and Source Control

Launching in -game mode

Networking

The Multi-User Editing workflow is built on a client-server model, where a single server hosts any number of sessions. Each session is a separate virtual workspace that any Unreal Editor instance on the same network can connect to in order to collaborate on the same Project content inside a shared environment.



While inside a session workspace, each user can interact with the Project content in any way made possible by their instance of Unreal Editor. For example:

Some users might work using a keyboard and mouse in a standard desktop PC setup — on different platforms, if needed.

Other users might choose to use the Editor's VR editing mode to visualize and work in the scene using a VR headset and controllers, or they might use a plugin like the Virtual Camera to enter the same scene using a mobile device.

Whenever any connected user makes a change to a Level or saves an Asset in the Project, their instance of Unreal Editor automatically forwards information about that change to the server. The server is responsible for keeping track of all these change records, or transactions, and for sending out those transactions to all other connected clients. Each client then applies those same changes locally within its own environment. In this way, everyone's view of their current Level and of other Assets in the Project remains up to date with the latest changes.

Synchronizing Transactions

The Multi-User Editing system chooses different strategies for synchronizing changes between connected clients depending on the type of Asset you're working with and the type of changes you make.

Levels: Instant Sync

All changes that you make to the contents of a Level are synchronized immediately with all other computers in the session. If you add or remove Actors, move Actors from place to place, swap Materials, or change the properties of an Actor, all other users in the session will see those changes take effect immediately. Dragging a tool to move, rotate, or scale an Actor causes multiple transactions to occur while you're dragging. Other users see these changes happen even before you release your mouse.

For example, in the following video, when the user on the left makes changes by dragging Actors from place to place, the user on the right sees those changes reflected immediately in their Viewport, even before the drag is released. Similarly, when the user on the right rotates the object, the user on the left sees the changes immediately.

You only see the effects of other users' changes if you're in the same Editor mode: that is, if you're both in editing mode, or if you're both in one of the Play In Editor (PIE) or Simulate modes.

Other Assets: Sync on Save

The Multi-User Editing system does not immediately synchronize most types of Assets in your Unreal Engine Project each time you make a change. This includes Asset types like Materials and Material Instances, Static Mesh Assets, Blueprint classes, and so on. In these cases, when you make changes to these Asset, you are the only one who sees the changes take effect in your environment immediately. When you save your changes, the Multi-User Editing system sends the transaction around to all other users in the session.

In this case, the transaction is not just a record of the change, but the actual saved Asset. Each instance of the Editor that receives one of these updated packages immediately hot-reloads it, making the changes visible.

For example, in the following video, when the user on the left changes a Material, their changes are not immediately synchronized. However, when the user saves their changes to the Asset, the transaction is processed and the changes show up for the user on the right.

After you save your Asset, you automatically acquire a lock on it. In addition, while you have unsaved changes to some kinds of Assets, the Multi-User Editing system marks those Assets as dirty for other users. See Avoiding Conflicts below.

Sequencer: Playback Sync and Optional UI Sync

The Multi-User Editing system treats Level Sequences and Master Sequences like Levels: when any user makes a change to a Sequence such as adding or removing a track, or adding a new keyframe, it immediately synchronizes that change to all other users in the session.

In addition, when one user plays a Sequence, the same Sequence plays immediately for all users that have that same Sequence open. Only the user who began playback will be able to stop it. After the Sequence has stopped, any user can restart playback.

You can also choose to have the Multi-User Editing system automatically open the Sequencer UI on all clients when one user opens it. Because the Multi-User Editing system synchronizes playback for all users that have the same Sequence open, enabling this UI synchronization option helps you make sure that all users see the same Sequence play back at the same time.

The following video shows how the Multi-User Editing system synchronizes Sequencer UI events, playback events, and editing events.

To enable UI sync for the Sequencer as shown above, use the Concert.EnableOpenRemoteSequencer console command. For details, see the Console Commands section of the Multi-User Editing Reference.

The Multi-User Editing system synchronizes playback events, but different computers may play back the animations at different frame rates. Do not expect the results to be frame-accurate from one instance of Unreal Editor to another.

Presence

The Multi-User Editing system offers a few different ways to see what the other users in your session are doing.

The presence information described in the following sections uses a display name and color to distinguish the connected users. Each user can customize these values using the Display Name and Avatar Color settings in their Project Settings. For details, see the Multi-User Editing Reference.

Location and Viewpoint

While you're working in the same Level as another user, you'll see an avatar that represents their position and viewpoint on the scene. As they interact with the scene, you'll also see lasers that indicate the objects highlighted by their mouse cursors or motion controllers.

For example, the following image shows avatars for two desktop users working in the same Level:



At any time, you can use the controls in the Connected Clients panel of the Multi-User Browser window to work with this presence information.



Icon

Description



Teleport immediately to the same location and viewpoint as this user.



Toggle displaying the avatar and laser pointers for this user.

You can also click the Level listed for any connected user to switch to that Level and teleport immediately to that user's location and viewpoint.

Session Change History

The Multi-User Browser window shows a list of all editing transactions that have occurred in the current session, and each time a user connected to or disconnected from the session.



Asset Change History

You can also view the list of changes made to each individual Asset. Right-click an Asset in the Content Browser, and select Multi-User > Asset History. You'll get a list of all the transactions that modified this particular Asset.



Avoiding Conflicts

When you allow multiple people work on the same content at the same time, they're likely to eventually try to change the same things at the same time. If you are too permissive about allowing this to happen, it can cause frustrations as people fight for control or lose the changes they make. On the other hand, if you are too strict, you may reduce people's ability to modify the things they need when they need to, which can slow down their work or block them entirely.

The Multi-User Editing system attempts to find a balance between these two extremes, preventing fighting and overwriting in the most common cases of contention between users.

Locking Dragged Selections

While you're actively dragging a selection in the Level Viewport — for example, to move, rotate, or resize it — you have exclusive control over those Actors. If another user attempts to modify any of the same Actors, either by dragging it with a tool in the Level Viewport or by setting properties in the Details panel, their changes will be immediately reverted.

As soon as you stop your drag interaction, other users become free to work with those Actors again, even if you still have them selected.

Locking Assets

If you want to prevent other users from modifying certain Assets, you can lock them. While an Asset is locked, only the user who locked it can save new modifications. Other users can still modify locked Assets locally in their own Project, but they can't save their modifications until the user who owns the lock unlocks it.

There are two ways to lock and unlock Assets:

Any time you begin modifying an unlocked Asset, you acquire a temporary lock on it until you save your changes.

You can also lock and unlock selected Assets without modifying them. Right-click them in the Content Browser and select Multi-User > Lock Asset(s) or Multi-User > Unlock Asset(s).



You can tell locked and modified Assets by the overlay on the Asset's thumbnail in the Content Browser. Mouse over the Asset to see details about the user who owns a lock or who has modified an Asset:



Overlay

Description



White indicates that you locked the Asset. You can continue modifying at any time. Other users cannot modify this Asset until you save or unlock it.



White with avatar indicates that another user has locked this Asset. You can still modify this Asset locally in your Project. If you do, you'll be notified that another user has it locked:

Click for full image.

You won't be able to save your modifications and sync that change to others until the user who owns the lock releases it.



Asterisk indicates the Asset is dirty (modified but unsaved) on another computer.

Only selected Asset types get marked with this icon. Be cautious about modifying Assets in this state — whoever saves their changes first gets a lock on the file and their change propagates to all other clients, potentially losing changes that others have made.

Undo and Redo

Each connected user has access only to their own history of operations. Within that history, each user can freely undo and redo their own actions, just as if they were working offline without being part of the session. However, a user cannot undo or redo any actions carried out by any other user in the session.

Starting from a Common State

To avoid long delays and high bandwidth usage, the server in the Multi-User Editing system does not transfer the entire contents of your Project between connected users. Instead, it relies on exchanging lightweight transaction records when it needs to achieve instant synchronization, and only circulates Assets like Levels, Static Meshes, Blueprints, and so on when those Assets get modified and saved during the course of a session.

The only way to make sure that incoming transactions are applied in exactly the same way for every connected user, and therefore that every user's content is kept in sync with every other user's content, is to have every connected user start with exactly the same content in exactly the same state. That way, as the same list of transactions is applied to each client in the same order, the overall state of each user's content is guaranteed to remain synchronized.

The typical way to get all users to start with the same content is to use a source control system such as Perforce, Git, or SVN, and to make sure that each user synchronizes their local copy to the same changelist or revision as everyone else before they connect to a session together. See the Multi-User Editing and Source Control section below for more.

Using source control isn't an absolute requirement; you can use Multi-User Editing without an external source control system. However, in that case it is up to you to find a way to share your Project content within your organization such that all the users you need to work together are reliably able start with the exact same Project content.

Session Validation

Every time a user attempts to connect to a session, the server checks certain attributes of their content and their working environment to see if they match the content the session was initially started with. If any of these checks fail, the server won't allow the user to join the session.

Version of UE - The server checks that the user trying to connect to the session is using the same version of Unreal Engine as the user who started the session. For example, if the user who started the session used version 5.0, and another user tries to join using version 4.27, the server won't allow the connection. This helps avoids problems caused by changes to Asset formats between different versions.

Project name - The server checks that the user trying to connect to the session has a Project open whose name matches the name of the Project that was used to create the session. If this check fails, the server assumes that the content in the two Projects can't be the same, and refuses the connection.

Source control revision - If the user who started the session was connected to a Source Control provider in the Unreal Editor, the server associates the changelist or revision of their Project with the session. When another user who has a Source Control provider active attempts to connect to that session, the server checks that their changelist or revision matches the one associated with the session.

Locally modified files - If you are connected to a Source Control provider, and you have any locally modified files, the server will prevent you from creating new sessions and joining existing sessions. This avoids the possibility of having users on the same changelist but with different versions of certain Assets.

Transactions and Persisting Changes

As you and your teammates work in a live session, the Editor applies transactions on top of your local Project content in a kind of virtual sandbox. Your Project files on disk are not actually modified at all as long as you remain in the session. The Multi-User Editing system takes care of keeping track of your changes, and shows you in the Unreal Editor the result of applying those transactions to your Project content.

At any time, any session participant can choose to persist the session changes: to take all the modifications made in the current session, and apply those changes back to their local files on disk. If you began your session while connected to a Source Control provider, you can also optionally check in those same changes in a new changelist or revision.



If you leave a session without persisting changes, the Editor automatically reverts back to the state your Project was in before you started or joined the session. It hot-reloads all the Assets in your Project that you modified while in the session, discarding the session modifications. Although you no longer see your session changes after you leave the session, you don't lose the transactions entirely. Each session still retains the record of all its transactions, even when all its users have left. If you re-join the same session later, the Multi-User Editing system re-applies all those same transactions in your Editor.

If you leave a session that you own without persisting changes, you'll also be prompted to persist the changes. This helps avoid the possibility of leaving changes unsaved within the session by accident. Even if you dismiss this prompt, you won't lose the pending changes forever. You can rejoin the session anytime and persist the changes later. Even if the server shuts down, the session changes aren't lost; see the next section for details.

Redundancy

The server retains each session until the user who created the session expressly deletes it, or until the server itself is shut down. Therefore, a crash or disconnection for any individual client, or even for all clients, never results in losing modifications. Users can simply reconnect to the server and pick up where they left off.

The server also protects itself against losing information due to unexpected shutdowns by saving its session records to disk.

If the server shuts down abnormally, then the next time you restart that server it will immediately restore all the sessions it had open at the state they were in when it shut down.

If you shut down the server cleanly, it archives all live sessions. You can restore the session from the archive later. See the next section for details.

Multi-User Editing and Source Control

The Multi-User Editing system offers some features that are similar to source control systems, such as having a server that stores a history of transactions, or having users acquire locks on the Assets they work on to reduce contention. However, Multi-User Editing is not a replacement for source control.

Multi-User Editing is best used to augment a standard collaboration workflow in which you use a dedicated source control system such as Perforce, SVN, or Git to regularly record the changes you make to your Project.

If you're using Perforce, you can also consider using UnrealGameSync (UGS) to make this process easier. For details, see the UGS documentation.

When you have such a version control system set up in your team, use Multi-User Editing for limited-time live collaborations on top of a specific, defined changelist.

At the start of each live session (a shoot, a day's work, a review meeting, or whatever applies to the work you do with your team), all participants decide on the changelist they'll start from. This is typically the latest revision. Everyone syncs to that revision.

At the end of the live session, one person commits those changes back to the team's usual source control system to preserve them.

After committing changes from a session back to source control, you can delete the session — you don't need it anymore.

Next time you need to work live with others, start a new session based on the latest changelist.

We don't recommend keeping a single Multi-User Editing session in use for a long period of time — that is, for days or weeks of work. Stop and commit your changes regularly to source control.

For more information about connecting the Unreal Editor UI to a Source Control provider, see Collaboration in Unreal Engine 4.

Launching in -game mode

If you use the -game command-line option to launch your project, you also need to include the -messaging option. This option enables the MessageBus system that the components of the Multi-User Editing system use to communicate with each other under the hood.

Networking

When you join a session, your instance of Unreal Editor connects to the server via UDP, on port 6666.

Each computer running the Unreal Editor that wants to connect to a server must be able to see the Private IP Address of that server's computer.

The server's computer must have port 6666 open to UDP traffic coming from the local network.

You should only expect this connection to work on a Local Area Network (LAN), or potentially if both endpoints are in the same Virtual Private Network (VPN). Do not expect to share your Unreal Editor sessions over an open Internet connection.

The instructions in the Getting Started page should be enough to get you up and running in a simple LAN. If you have trouble establishing connections between your clients and your server, you may be able to adjust the UDP Messaging settings for your Unreal Editor instances and your server. See Advanced Multi-User Networking.

1 - Activate the Plugin

2 - Set Up Multiple Computers

3 - Start a Server

4 - Start a Session

5 - Join the Session

6 - Work Together

7 - Persist Session Changes

8 - Clean Up

9 - On Your Own

This Quick Start page will get you up and running with the basics of the Multi-User Editing system. After going through the tutorial, you'll know:

How to set up multiple computers so that they're ready to join a session together.

How to start a server to manage your sessions.

How to start and join sessions, so that you can work together with your teammates.

How to persist the changes you make while working in a session back to the Project content on your local computer.

Prerequisites: Although you can run this tutorial using multiple instances of the Unreal Editor working on the same host, it's much more effective to connect multiple different computers to the same session. To start with:

Install the same version of Unreal Engine on each computer.

Make sure that all computers are connected to the same Local Area Network (LAN) or Virtual Private Network (VPN).

The images in this procedure use the



1 - Activate the Plugin

Before you can connect multiple instances of the Unreal Editor together to work in a shared session, you need to enable the Multi-User Editing Plugin for your Project.

Open your Project in the Unreal Editor.

From the main menu, select Edit > Plugins.

Under the Editor category, find the Multi-User Editing Plugin and check its Enabled box.

Click for full image.

Click Yes to confirm.



Click Restart Now to restart your Project and apply the change.

Click for full image.

2 - Set Up Multiple Computers

Each computer that you want to connect to the same Multi-User Editing session needs to have the same version of Unreal Engine installed.

Each computer also needs to have a copy of the same Unreal Engine Project, each with exactly the same content.

The typical way to achieve this is to store your Project in a version control system such as Perforce, Git, or Subversion, and to sync every computer to the same revision or changelist.

If you're using Perforce, you can also consider using UnrealGameSync (UGS) to make this process easier. For details, see the UGS documentation.

The Multi-User Editing system doesn't absolutely require you to use source control. You could simply copy your Project folder from one computer to all the other computers that you want to join the same session. You may find this useful for initial testing of the Multi-User Editing system. However, avoid relying on this approach. Using version control effectively within your team is the safest way to maintain and share your Project content.

Once you have a copy of your Project on each computer, you'll want to customize a few key settings. On each computer:

Open your Project in the Unreal Editor, and choose Edit > Project Settings from the main menu.

In the Project Settings window, open the Plugins > Multi-User Editing section.

Click for full image.

Change the following settings to add a shortcut button to the Editor UI, and to customize the presence information that each Unreal Editor instance shows to other instances while connected to a session.

Setting

Description

Enable Multi-User Toolbar Button

Adds a new button to the Toolbar in the main Unreal Editor window that provides shortcuts to the Multi-User Editing commands you'll need most often.

Display Name

Sets the name that the Multi-User Editing system uses when it displays presence information and session history for this computer.By default, the Multi-User Editing system attempts to use the login information for the current user of the host operating system, but you may want to override this value in some cases — for example, if you have the same user account logged in on multiple computers.

Avatar Color

Sets a color that the Multi-User Editing system associates with this computer when it displays presence information and session history.By default, this color is the same for all users (white), but you can make your session history much easier to understand if you assign a different color to each computer.

For details on all the settings available in this panel, see also the Multi-User Editing Reference.

Restart the Editor again for your new settings to take effect.

3 - Start a Server

Once you have your Project open in the Unreal Editor on each computer that you want to connect together, you'll need to start a server to manage the session shared by those computers. The easiest way to do this is from any one of those instances of the Unreal Editor.

Click the Multi-User Editing icon in the Toolbar. (It should say Browse, indicating that you aren't currently connected to a session.)



The Multi-User Browser window opens. This panel offers access to most of the session management tools that you'll need as you work in the Multi-User Editing system. You'll return to this window frequently.

Click for full image.

Even when you don't have the Toolbar icon active, you can also open this panel at any time by choosing Window > Multi-User Browser.

In the Multi-User Browser window, click the Launch icon on the far left of the Toolbar to start the Multi-User Editing Server on your computer.

Click for full image.

You'll see a new command window open. The server periodically prints status messages to this window as you manage sessions and make changes to your Project content. For example:

Click for full image.

You can also start a server from the command line on any computer that has Unreal Engine installed. For details, see the UnrealMultiUserServer Command-line Parameters section of the Multi-User Editing Reference page.

4 - Start a Session

Now you have a server running on one of your computers, but none of your Unreal Editor instances are connected to that server yet. In order for that to happen, you need to create a new session. The session manages and shares all the modifications that all connected users make to the Assets and Levels in the Project.

To create a new session:

On any one of your computers, open the Multi-User Browser window as shown in the previous section.

There won't be any sessions listed here yet. However, as long as the computer running your server is visible over the network to the computer running this instance of Unreal Editor, you should be able to create a new session.

Click the Create a New Session icon in the Toolbar of the Multi-User Browser window.

Click for full image.

You'll see a new row added to the list view for you to set up your new session.

Click for full image.

Type a name for your new session, and select the server that you want to manage the session from the drop-down list. (You'll only have one server in this list for now.) Then, select the checkbox icon at the far right to create the session.

Click for full image.

If you have a server running on the same LAN or VPN as the computer running Unreal Editor, but you can't create a new session or see your server listed in the Server drop-down list, you may need to stop and do some additional network configuration at this point. See Advanced Multi-User Networking.

You'll automatically connect to your new session. The layout of the Multi-User Browser window changes to show you the details about the session you've joined.

Click for full image.

In addition, the button in the Toolbar of the main Unreal Editor updates to indicate that you're connected.



5 - Join the Session

Now that you have a server running, and you've created a session on that server from the Unreal Editor on one of your computers, you'll be able to connect to that same session from other instances of the Unreal Editor running on other computers.

On each other computer you want to join the session:

Open the Multi-User Browser window. You'll see the session that you created on the other computer listed here.

Click for full image.

Select the session to see details about the Project and who's currently connected to the session.

Click for full image.

You can also mouse over any session to see its details:



Click the Join the selected session icon in the Toolbar to join. (Or, double-click the session name.)

Click for full image.

As soon as you're connected, the Multi-User Browser window changes to show you the details about the session you've joined. Now, you should see all connected users in the Clients list, and the history of changes made by all participants in the shared session.

Click for full image.

If any of the other computers already working in this session have already made any changes to the Level or the Assets in the Project before you joined, your instance of Unreal Editor will automatically fetch those transactions from the server and apply the changes in your local view of the shared session workspace. You'll now be locked in to working with the same content as all the other participants, but you'll be free to work with that content any way you need to in the Unreal Editor UI. You can do things like moving your camera viewpoint around in the Level Viewport, browsing to new folders in the Content Browser, switching tools, opening new windows and panels, and so on, without affecting other users.

Now that you have multiple computers connected together in a single session, we can make some changes on one computer and see how those changes are propagated to the other computers in the same session.

6 - Work Together

Now that you have multiple users connected in the same live session, you can all build the virtual world together. Work on your Unreal Engine Project as you usually would, but now you'll all see the results of each others' changes as soon as they're applied.

For details on what to expect while you're working live, see the Multi-User Editing Overview.

Click for full image.

7 - Persist Session Changes

At this point, you and your teammates have probably made some changes to a Level and to some Assets in the Project. However, these transactions are not yet reflected in the actual files that make up the Project content on your computer. If you want to keep the work that your team has done in the live session, you'll need to persist these changes. That means, you'll have to apply all the transactions handled by the Multi-User Editing system to your local Project files.

You persist changes using the Source Control tools in the Toolbar, regardless of whether you're using a source control provider or not.

Click the arrow next to the Source Control button in the Toolbar, and select Persist Session Changes.

In the Persist & Submit Files window, you'll see a list of all the files that were modified during the live session. Use the checkboxes to indicate what modified files you want to apply to the Project files on your local computer.

If you had a source control provider set up when you started or joined your session, you have the option to immediately submit the changes that you're persisting back to that provider in a new changelist or revision.

If you don't choose to submit immediately, the Multi-User Editing system will check out the modified files automatically from your source control provider, so that it can apply and save the changes made in the session to the local files on your computer. You'll then be able to make further modifications (either in your session or offline after you leave the session) and submit all the changes later using the standard Source Control workflow, if you choose.

If you do want to submit the changes you've made in the session to source control immediately:

Check the Submit to Source Control option at the bottom of the window.



Just like in the usual Source Control workflow, you must set a description of the changes that you're submitting. Expand the Changelist Description at the top of the window, and type a description in the box.



If you know that you'll need to make more modifications to the files you're submitting, you can check the Keep Files Checked Out option as in the usual Source Control workflow.



When you're happy with the list of files you want to submit, and you've set the source control options you want, click Submit.



You'll remain connected to your session, and you can keep working as long as you like.

8 - Clean Up

Now that you've applied the changes that you and your teammates made to your Levels and Assets during your live session back to your Project on disk, and optionally committed those changes back to your source control system, you likely won't need your session anymore. Although you can rejoin and pick up the same session where you left off at any time, it's good practice to regularly start new editing sessions from updated changelists, rather than keep working in older sessions for a long period of time.

When you don't need a session anymore, you can use the Multi-User Browser to delete it.

Only the user who initially created the session can delete it. Other users will not see the option in the Multi-User Browser, even if they participated in that session.

Disconnect from the session, if you haven't already. (You can't delete a session while you're connected to it.)

Click for full image.

If you have the Multi-User Editing button shown in the Toolbar, it says Leave while you're connected. You can simply click it to leave the session:



After you've disconnected, select your session in the Multi-User Browser and click the Delete icon in the Toolbar to delete it.

Click for full image.

Confirm the deletion.



If there are any other users connected to the session you've deleted, they will be automatically disconnected.

Finally, if you know that you won't need to reconnect to any shared sessions for a while, you can stop the server by focusing on its console window and pressing Ctrl+C.

Avoid simply closing the console window. The server considers this an abnormal shutdown. Any sessions that are still active when you close the console window will be automatically restored next time you start the server.

Now you're back to where you started this tutorial, but with all the changes that all users made during the shared editing session.

9 - On Your Own

If you've successfully gone through all the steps above, you've had a first taste of live collaboration workflows in the Unreal Editor. You've learned how to set up your Project on multiple computers, connect those computers together into a shared editing session, and work together with your teammates on building a virtual world. You probably already have ideas for how to put these workflows into practice within your own teams working on your own Projects — now you'll be able to benefit from instant collaboration, zero iteration time, and the creative cooperation made possible by the Multi-User Editing system.

If you start using the Multi-User Editing system routinely in your team, you may want to set up a default server name and session name in your Project Settings. When this is set up, the Toolbar button is updated to say Join instead of Browse. You can then click the Toolbar icon to join your default session with one click. You can also choose to connect automatically to that default session when you open your Project.

If you need multiple users to see the same animations playing back in sync, you can configure the Multi-User Editing system to synchronize operations in the Sequencer UI between different users. Each user needs to opt in to this by setting some console commands.

For details on the settings you'll need to modify, see the Multi-User Editing Reference.

Saving a Session to an Archive

Steps

End Result

Restoring an Archived Session

Steps

End Result

At any time, you can have the Multi-User Editing server save all of the transactions made in a single session into an archive on disk. Later, you can use this archive to create a new session that contains all the same changes.

The instructions on this page show how to save a session to an archive, and to restore the archive to an active session later.

You'll use the controls in the Multi-User Browser to do this. You can open this panel by choosing Window > Developer Tools > Multi-User Browser from the main menu, or by activating the Toolbar button for Multi-User Editing. For more, see the Quick Start.

Saving a Session to an Archive

Follow the instructions in this section to save an active session to an archive on disk.

Steps

Select the session you want to archive in the Multi-User Browser.

Click the Archive icon in the Toolbar, or right-click the session and choose Archive from the context menu.



Immediately below your session name, give the archive a descriptive name, then click the checkbox icon.



End Result

Your new archive appears in the list of sessions. It's distinguished from active sessions by its box icon, and by its lighter grey text.



The server saves session archives in the Engine\Programs\UnrealMultiUserServer\Saved\MultiUser folder under your Unreal Engine installation folder.

Restoring an Archived Session

Follow the instructions in this section to restore an archive back to an active session that you can join to resume editing.

Steps

To restore a session from an archive:

Make sure you have the same server running that you used to host the original session. Each server is responsible for saving its own sessions to archives locally on its own computer. That means that each server can only restore sessions that it archived.

Make sure that you have the same Project open that was originally used to create the session, and make sure the state of the Project's content matches the original state of the archived session.

Remember that when you restore an archived session, just like when you join an existing session, your Project content on disk must match the state that the Project content was in at the time the session was originally created.

Select the archive you want to restore in the Multi-User Browser.



Click the Restore icon in the Toolbar, or double-click the archive, or right-click the archive and choose Restore from the context menu.



Set the name of the new session that you want to create from the transactions stored in the archive, then click the checkbox icon.

]

End Result

The Multi-User Editing system starts a new session, owned by you, and immediately joins you to the session. The History will show the full record of all the transactions made while the session was live. As you work, you'll continue adding new transactions on top of this existing history.



Building the Multi-User Server

Enable the Multi-User Editing Plugin

Change Settings to Launch UI Mode

Switchboard Support

Running the Multi-User Server

From Multi-User Browser

From Switchboard

Multi-User Server UI Overview

Menu bar and Tabs

Command Console and Output Log

Sessions Information Tab

Toolbar Icons

Active Sessions

Archived Sessions

Active Session Tab

Connected Clients

Session History

Transaction Details

Session Content

Clients Information Tab

Clients Table

Packages Column

Enhanced Logging

Muting and Deleting Transactions

Archiving a Session

Deleting a Transaction

Muting a Transaction

A user interface was added to the Multi-User Server to inspect the running status of the server live. This enables operators and ICVFX stage managers to inspect, monitor, and diagnose problems during Multi-User Server operation.

This has benefits over the console server, which only provided a stream of connection information over a console command, and did not provide contextual information about the running server operation.

The console server is still available for operation on headless computers, or on computers where running a UI is not possible. For example, a Linux server or containerized operation.

Building the Multi-User Server

The Multi-User Server program needs to be built in order to run. If you are using precompiled binary builds, the server should be pre-built, and available upon launching the Engine. If you are building Unreal Engine from Source, we recommend you use UnrealGameSync to build compiled versions of the server for both console and UI versions.

In UnrealGameSync you can build the server during the normal sync operation by enabling the options Compile UnrealMultiUserServer and Compile UnrealMultiUserSlateServer. The latter is the name of the new UI based server.

Click Options in the bottom-right corner of the UnrealGameSync interface and select Customize Commands.



In the Modify Build Steps dialog, enable the checkbox next to Compile UnrealMultiUserServer and Compile UnrealMultiUserSlateServer.



Enable the Multi-User Editing Plugin

To use the Multi-User Server, you must enable the Multi-User Editing plugin in your project.

In the Editor go to Edit > Plugins to open the Plugin Browser.

Search for "Multi-User" and enable the Multi-User Editing plugin.



Restart the Unreal Editor before you proceed.

Change Settings to Launch UI Mode

After you enable the plugin you need to change the default server mode in the Multi-User Project Settings to make the plugin launch in UI mode.

In the Window menu select Multi-User Browser to open the plugin interface.



Click the Settings gear icon in the upper-right corner of the Multi-User Browser window. This will open the Multi-User Editor plugin settings.

Under Client Settings, change the Server Type property to Slate mode.



Switchboard Support

Launching the Multi-User Server in UI mode is also supported in Switchboard. The Switchboard application launches Multi-User Server in UI Mode by default.

You can change this behavior by adjusting the global settings in the Switchboard Settings menu.

In the Switchboard application menu go to Settings > Settings.



Scroll down to the Multi User Server section.

Uncheck the box next to Launch Multi-user server in UI mode to disable the user interface version. Switchboard will now launch Multi-User Server sessions in Console mode.



Running the Multi-User Server

You can run a new server from the Multi-User Browser Editor panel, or from Switchboard.

From Multi-User Browser

When the Multi-User Browser panel is open, the plugin will automatically search for available servers on the network.

You can launch a new server by clicking the Launch a Server button in the middle of the window, or the server icon on the left side of the toolbar.



The Multi-User Server UI opens in a new window.



From Switchboard

In the Switchboard application click the Multi-user Server launch icon in the bottom-left corner of the window.



Multi-User Server UI Overview

The Multi-User Server interface contains three regions.



Menu bar and Tabs.

Sessions and Client information panels.

Command Console and Output Log.

Menu bar and Tabs

The Window menu displays a context-sensitive list of browser windows available within the current UI tab (Sessions, Clients, or Active Session). You can use this list to restore windows that were previously closed.



Under Debug > View App Icons you can summon an information key that describes all the icons in the Multi-User Server interface.



Beneath the menu bar is a row of tabs which enable you to switch between the various UI panels in the Multi-User Server. The Sessions and Clients tabs are displayed by default. If you double-click an Active or Archived Session, a new tab panel will open containing detailed information about that session.



Command Console and Output Log

The Multi-User Server has an Output Log where you can review logs for information relevant to the operation of the server. You can find errors, warnings, and general diagnostic information that may assist you in troubleshooting the Multi-User Server operation.



Several options are available under the Filters drop-down menu to limit which Output Log entries are visible.

This interface also has a Command Console where you can modify various Console Variables that affect the operation of the Multi-User Server.

Sessions Information Tab

Similar to the existing Multi-User Browser available in the Unreal Editor, the Multi-User Server has a Sessions Panel where you can examine running and archived sessions.



Toolbar Icons

When an Active or Archived session is selected, you can perform three actions from the toolbar in the Sessions tab.

Icon

Description



Restore the selected session.



Archive the selected session.



Delete the selected session if permitted.

Active Sessions

All Active Sessions on the server are listed here, with summary information about their Server, Project name, Unreal Engine Version, and the Last Modified date. If you right-click an active session you can Archive, Rename, or Delete that session from the context menu.



You can double-click an active session to inspect that session in greater detail in a new tab.

Archived Sessions

All Archived Sessions on the server are listed here with the same summary information as above. If you right-click an archived session, you can Restore, Rename or Delete that session from the context menu.



You can double-click an archived session to inspect it in a new tab.

Active Session Tab

You can double-click any active session in the Sessions Information Panel to display more information about that session. Information about the session opens in a new tab bearing the name of the session. The information panel of an Active Session has four regions.



Connected Clients

Session History

Transaction Details

Session Content

Connected Clients

From an active session tab, you can click the Connected Clients button to inspect the clients currently connected to that session. The Connected Clients button will take you to the main Clients tab, with the content filtered to display only the active connections in that specific session. You can clear the filter and show all clients by using the gear icon in the Clients tab.

Session History

Once open, the active session tab displays a chronological history of all the individual transactions that occurred during that session. This panel also displays a brief summary of the operation and the Client where the changes originated.



You can use the search bar to look for specific transactions in the history timeline. Several display filters are available under the gear icon.



Transaction Details

You can select any individual transaction in the Session History and expand the Details section to expose more information about the changes that were made in that transaction.



Under Modified objects and properties you can hover the mouse over one of the listed items and a tooltip will display precisely which Asset was modified.

Session Content



The Session Content panel lists any changes made to the contents of the project. When new packages are added, they are listed with a plus icon to the left of the package name. This icon changes to a check sign when the package is saved.

Clients Information Tab

The Clients information tab displays network information about the Multi-User server, and a record of any clients that have participated in a session on that server.

Clients Table

The Clients table keeps track of all clients that have participated in the server, both connected and disconnected. Clients that are currently connected to an active session in the Multi-User server will display a green swatch in the bottom-left corner of the table. When a client disconnects from the server, the swatch turns gray.



The client table provides a summary view of the active network data that each client is sending and receiving. You can use the search bar to retrieve information about specific clients. You can also see detailed connection information about a specific client by right-clicking in the corner of the client and selecting one of the options in the context menu.



Open Log: Opens a new tab in which you can view log events related to this client.

Network Graph: Displays a real time graph of the client's network activity.

Outbound segment table: An itemized record of all transactions initiated by the client.

Inbound segment table: An itemized record of all transactions received by the client.

These tables provide information about the active data being sent or received by the client.

Item

Description

Sent

Total data sent by the client.

Received

Total data received by the client.

RTT

Round trip time in milliseconds.

Inflight

Current inflight data, waiting to be acknowledged by the receiver.

Lost

Information about packet loss.

This information is extremely useful when diagnosing passible packet loss in high throughput situations. You can identify connections that are unstable, or may be unreachable due to network congestion or configuration.

Packages Column

The Packages column on the right side of the server window displays package transfer information between clients. This view provides insights about the current transfer of large data to other clients. For example, Level Snapshot data or GPU Lightmass bakes.



The time at which the package was sent, size, and revision information is visible. The green checkmark in the State column indicates that the package was acknowledged by the receiver to be completely transferred, and therefore should exist on the node. When Enhanced Logging is enabled, you can also click the checkmark to determine the exact message that was used to send the package.

Enhanced Logging

Enhanced logging is available in the the Server Log panel at the bottom of the Clients tab. Click Enable logging in the middle of the Server Log panel to enable Enhanced Logging.



Enhanced logging displays a detailed view of the current transfer of message between the Multi-User Server and its Clients. It is an inspection of the types of messages transmitted. By default all message types are visible, along with the time it was sent, who sent it, where it was sent, and whether it was acknowledged by the client.

Various filters are available to the left of the search bar in the Server Log panel. Click the dropdown caret icon to display the filters.



Once enhanced logging is enabled in a server, you cannot turn it off. Logging information is written to a CSV file found in the same directory as your server log files. Long sessions can generate very large CSV files, so you should only enable this feature when troubleshooting issues.

Muting and Deleting Transactions

The Multi-User Server application has the capability for users to edit existing session data, enabling you to mute or delete transactions that were generated by clients. This feature is a useful way to identify and eliminate transactions that may be causing problems with user operation.

Archiving a Session

To use this feature, you must create an archived copy of the session you wish to edit, and open that archived session in the Multi-User Server. Right-click an Active Session in the Sessions tab and select Archive in the context menu. Double-click the archived session to open its information panel.



Once the archived session is open, you can select any transaction and mute or delete it.

Deleting a Transaction

To delete a transaction, right-click it in the archived session and select Edit > Delete from the context menu.



Note that deleting a transaction is destructive and cannot be undone. Muting transactions can achieve a similar effect, but enables you to unmute at a later time. If there is any chance you will want to recover the transaction later, consider muting instead.

Muting a Transaction

If you mute a transaction in an archived session, that transaction is not replayed when clients rejoin the session after it is unarchived. Muted transactions appear as dimmed entries in the transaction history. To mute a transaction right-click it in the transaction history and select Mute from the context menu.



This workflow yields essentially the same results as deleting transactions. However you can always unmute transactions at a later time, whereas deleted transactions cannot be recovered. Muting is the recommended workflow for either temporarily or permanently disabling a transaction.

When you attempt to mute a transaction, a warning dialog appears to inform you that by muting a transaction there is some risk of disrupting downstream dependencies.



Since some transactions may depend on earlier transactions, muting or deleting always requires a dependency analysis on the transaction history. This process is automatic, and will find transactions that relate to one another. Dependency analysis is not infallible, and in some cases it is indeterminate whether or not a transaction depends on another. In those cases you are given the option to include or exclude the transaction. In most cases it is best to err on the side of caution.

Same LAN, Same Subnet

Configuring the Editor

Configuring the Server

Same LAN, Different Subnet

Configuring the Server

Configuring the Editor

The instructions in the Multi-User Editing Quick Start show how to work with the Multi-User Editing system in a simple Local Area Network (LAN), where clients can automatically discover the Multi-User Editing server. However, automatic server discovery is not always possible. Sometimes, you may need to do some extra configuration on the computers that you want to connect through Multi-User Editing.

This page contains some strategies that may help you successfully establish a connection when the Unreal Editor cannot automatically discover your Multi-User Editing server.

Same LAN, Same Subnet

If the Unreal Editor and the Multi-User Editing server are on the same LAN and the same subnet, but they aren't able to discover each other automatically, the cause might be that one or both of them is not set to broadcast or listen to multicast traffic on the correct network interface of the computer. To force Unreal Engine to use a specific network interface, you'll need to specify it as the unicast endpoint IP.

Configuring the Editor

To set the unicast endpoint IP address in the Unreal Editor:

From the main menu, select Edit > Project Settings.

In the Project Settings window, go to the Plugins > UDP Messaging section, and find the Transport > Unicast Endpoint setting.

Set the value of this property to the IP address of the network interface you want the Unreal Editor to use. Always use port 0.For example, 192.168.10.73:0.

Configuring the Server

To set the unicast endpoint IP address for the Multi-User Editing server, you can follow the instructions given above to set up the unicast endpoint for the Unreal Editor, then launch the server from the Toolbar in the Editor. If you launch the server this way, it will automatically use the same unicast IP address as the editor that launched it.

Alternatively, you can follow the instructions below to configure the IP address manually:

If your server is already running, shut it down.

In your Unreal Engine installation folder, go to the Engine/Programs/UnrealMultiUserServer/Saved/Config/<platform> folder, and open the Engine.ini file in a text editor. If that file doesn't already exist, create it.

Add the following block of settings to the file:

Set the value of the UnicastEndpoint setting to the IP address of the network adapter you want the Unreal Editor to use. Always use port 0.

Save the file and restart your server.

Same LAN, Different Subnet

If you want to connect an instance of the Unreal Editor to a server that is not on the same subnet, you will need to do some extra configuration for both the server and the Editor. This involves setting up the server with a port for its unicast endpoint, then setting up the Unreal Editor to connect to the server's unicast IP address and port as a static endpoint.

Configuring the Server

You need to configure your Multi-User server to use a pre-defined port for its unicast endpoint. There are several ways you can accomplish this:

If you want to launch your Multi-User server manually, you can follow the same procedure given in the previous section for setting up the unicast endpoint in the configuration file. However, instead of port 0, use a different port number in the range 50000 - 60000.

If you want to launch your Multi-User server from the Unreal Editor, the easiest approach is to set the port number you want to use in the Server Port setting that you can find in the Project Settings window under the Plugins > Multi-User Editing section. This value will automatically override any port value you set for the unicast endpoint in the Plugins > UDP Messaging section.

See also the Multi-User Editing Reference

Alternatively, you could follow the procedure given in the previous section for setting up the unicast endpoint in the Project Settings window under the Plugins > UDP Messaging section. However, instead of port 0, use a different port number in the range 50000 - 60000.

If you choose this third approach, the server will always use a port number one higher than the one you set. This ensures that there won't be a conflict between the Editor and the server when they run on the same machine. When you configure the static endpoint for your other Unreal Editor instances in the following section, you will need to remember to add one to the port number you set in the Project Settings. For example, if you set 50000 as the port number for the unicast endpoint in the Editor that you use to launch the server, you will need to configure other instances of the Editor to connect to the static endpoint with port 50001.

Configuring the Editor

To make an instance of the Unreal Editor on a different subnet capable of connecting to the server, you need to specify the IP address and port of the server as a static endpoint.

To set up a static endpoint in the Unreal Editor:

From the main menu, select Edit > Project Settings.

In the Project Settings window, go to the Plugins > UDP Messaging section. Expand the advanced settings under the Transport section and find the Static Endpoints setting.



Press + to add a new item to the list, and set the value of the new item to the IP address and port that you set up for your server's unicast endpoint.



Project Settings

Multi-User Editing settings

Multi-User Transactions Settings

UnrealMultiUserServer Command-line Parameters

Unreal Editor Command-line Parameters

Console Commands

This page contains information about requirements, settings, command-line parameters, and console commands for the Multi-User Editing system.

Project Settings

Multi-User Editing settings

When you have the Multi-User Editing Plugin activated in your Project, you'll have access to the following settings in the Project Settings window, under Plugins > Multi-User Editing.

Click for full image.

Setting

Description

Client Settings

Enable Multi-User Toolbar Button

When enabled, the Toolbar in the main Unreal Editor window contains a button that provides shortcuts for carrying out common Multi-User Editing tasks:

Icon state

Button action



When you're disconnected, and you have a default server name or session name set below, click Join to join that default session.



When you're disconnected, and you don't have a default server name or session name set below, click Browse to launch the Multi-User Browser so you can find and join a session manually.



When you're connected to a session, you can click Leave to disconnect.



When you're connecting to a session, you can click Cancel to cancel connection.

You can also use the down arrow next to the Toolbar button at any time to access the Multi-User Browser, to open the Project Settings window to this page, or to start a Multi-User Server on your computer.

Auto Connect

Enable this setting to make the Unreal Editor immediately attempt to connect to the Default Server URL and Default Session Name set below each time you open this Project.

Default Server URL

Sets the name of the server that the Multi-User Editing system tries to connect to when you have the Auto Connect setting enabled or when you click the JoinSession Browser

Default Session Name

Sets the name of the session that the Multi-User Editing system tries to connect to when you have the Auto Connect setting enabled or when you click the Join button in the Toolbar.

If a session with that name doesn't exist yet on the default server, the server will start a new session.



Default Session to Restore

If you want to restore a saved session when you have the Auto Connect setting enabled or when you click the Join button in the Toolbar, enter the name of that saved session.

Default Save Session As

If you want the Multi-User Editing system to save the session it opens when you have the Auto Connect setting enabled or when you click the Join button in the Toolbar, enter the name you want that session to saved as.

Display Name

Sets the name that identifies you in all presence information visible to other users.

Avatar Color

Sets the color that the Multi-User Editing system associates with you in all presence information visible to other users.

Desktop Avatar Actor Class

Sets the class that the Multi-User Editing system uses to represent you in other users' Level Viewports when you're using a standard keyboard and mouse to interact with the Unreal Editor.If you want to change the default avatar, you can derive your own Blueprint class from the built-in DesktopPresence class and customize your class to meet your needs.

VRAvatar Actor Class

Sets the class that the Multi-User Editing system uses to represent you in other users' Level Viewports when you're using the VR Editing system to work in the Level using a VR headset and controllers.If you want to change the default avatar, you can derive your own Blueprint class from the built-in VRPresence class and customize your class to meet your needs.

Client Settings — Advanced

Server Port

Server Port value you set here takes precedence. See also Advanced Multi-User Networking

Discovery Timeout

If a previously discovered server does not respond to a message within this time span, it is considered stale and removed from the list in the Multi-User Browser.

Session Tick Frequency

Determines how frequently this instance of Unreal Editor processes session updates.

Latency Compensation

Determines how much compensation this instance of Unreal Editor should apply when treating incoming transactions that involve time-sensitive operations such as Sequencer playback.

Endpoint Settings

Enable Logging

Determines whether this instance of Unreal Editor should log detailed information about the current session. You can find these logs in your Project's Saved/Logs/Concert subfolder.

Activating this option can consume large amounts of disk space in a short time.

If you disable logging after you previously had it enabled, you'll need to remove those log files yourself in order to recover the disk space.

Purge Processed Message Delay

Determines how long this instance of Unreal Editor should wait before removing from memory any messages about the session state that it has already processed.

Remote Endpoint Timeout

If a remote instance of Unreal Editor does not respond to a message within this time span, it is considered stale and removed from the current session.

Multi-User Transactions Settings

You'll also have access to the following settings under Plugins > Multi-User Transactions.

Click for full image.

Avoid adjusting these settings until you have used the Multi-User Editing system extensively with the default values, and you have a good understanding of how it works. Altering these settings can affect the stability of the Multi-User Editing system.

Setting

Description

Transaction Settings

Snapshot Transactions Per Second

The number of transactions the Multi-User Editing system sends per second while you are interacting with a tool or control that synchronizes changes instantly with other clients — for example, while dragging an Actor in the Level Viewport, or while dragging a slider in an Actor's Details panel.

Include Object Class Filters

While this list is empty, the Multi-User Editing system automatically sends transactions for modifications to all class types. If you instead want to synchronize modifications only for specific classes, you can specify those classes in this list. The values that appear in this list by default are ones that have been tested and judged to be stable enough to expose.

Exclude Transaction Class Filters

If you want to restrict the Multi-User Editing system from synchronizing modifications to certain classes, you can specify those classes in this list. Any transaction that involves a change to an object with one of these excluded classes won't be synchronized.This list takes priority over the Include Object Class Filters list above.

By default, this list includes Landscape classes. Any modifications you make to a Landscape are not synchronized until you save the Level that contains that Landscape.

Allowed Transient Properties

Contains a list of transient class properties that are always synchronized, even if they would normally be filtered out. The default entries synchronize Actor visibility in the Editor. You can remove these default entries from the list if you want different users working in the same Level to be able to show and hide different sets of Actors.

If you need to change these values, make your changes directly in the [/Script/ConcertSyncCore.ConcertSyncConfig] section of the Saved/Config/<platform>/Engine.ini file rather than in the UI.

Transaction Settings — Advanced

Interactive Editor Hot Reload

Determines how Unreal Editor should handle the situation when it needs to replace an already loaded Asset with a different version of the same Asset. This happens when another user connected to your session modifies and saves an Asset. It also happens when you leave a session without persisting changes, and the Editor needs to replace content that was modified during the session with the content you initially had before you joined the session.

Leave this setting disabled to have the newly loaded content immediately replace the content you already had loaded. Enable this setting if you want to be prompted whether to reload each modified Asset.

Show Presence in PIE

Determines whether other users' presence information should be shown while you are in a Play In Editor (PIE) session.

Package Settings

Exclude Package Class Filters

Determines what saved packages will not propagate to the Multi-User server. You can filter by the package path and by a specific asset class. For example, adding /Game/Maps/ to Content Paths will prevent anything saved in /Game/Maps/ from propagating to the Multi-User server.

UnrealMultiUserServer Command-line Parameters

The Getting Started page shows how to launch the server component of the Multi-User Editing system from inside the UI of the Unreal Editor. However, you can also launch this server from the command line on any computer that has Unreal Engine installed.

If you run the server from the command line, you don't need to have your Project on that computer. The server only records transactions and modified Assets; it has no dependency on having the entire Project content available. Only the computers that join a session need to have copies of the Project content.

You'll find the Multi-User Editing server in your Unreal Engine installation folder, at Engine/Binaries/<platform>/UnrealMultiUserServer.exe. When you launch it, you can provide the following optional parameters on the command line to control its behavior.

Parameter

Description

-ConcertSession=

If specified, the server creates a new session with this name when it starts up. For example:-ConcertSession=DemoSession

-ConcertProject=

If you've specified a -ConcertSession, then the server will use the value of ConcertProject as the name of the Unreal Engine Project associated with the session. It will only permit connections from Unreal Editor instances that are running a Project with the same name. For example:-ConcertProject=MyUprojectName

-ConcertVersion=

If you've specified a -ConcertSession, then the server will use the value of ConcertVersion as the version of the Unreal Engine associated with the session. It will only permit connections from Unreal Editor instances that are built with the same version. For example:-ConcertVersion=4.22.0-123456

To get this version number, open the Unreal Editor and choose Help > About Unreal Editor... from the main menu.

-ConcertRevision=

If you've specified a -ConcertSession, then the server will use the value of ConcertRevsion as the base source control changelist associated with the session. It will only permit connections from Unreal Editor instances that are have Source Control active, and that have the same revision of the content checked out, with no local modifications. For example:-ConcertRevision=4725058

-ConcertIgnore

Add this value to the command line if you want to prevent the Multi-User Editing server from validating that connecting Unreal Editor instances match the Project name, Engine version, and content source control changelist associated with each session.

Although it can sometimes be useful to permit clients to connect despite minor discrepancies in their Project content, you should avoid relying on this setting for your typical workflow in order to avoid any unexpected behavior that may be caused by your content being out of sync on different clients.

-ConcertClean

Add this value to the command line if you want the server to remove all existing session files from its temporary storage directory when it starts up.

This removes all saved sessions.

-ConcertSaveSessionAs=

If you've specified a -ConcertSession, then the server uses the ConcertSaveSessionAs value to define the name it uses to save the session data in the event that it shuts down before the session has been deleted. Specifying the name in this way is equivalent to setting the Session Data Management > Save Session As value when you create a new session in the Unreal Editor UI.Once the session has been saved and the server shut down, you can start the server again with the ConcertSessionToRestore parameter to restore the state of that session.

-ConcertSessionToRestore=

If you've specified a -ConcertSession, then you can use this parameter to restore a session that this server previously saved with the specified name instead of creating a new session.

Unreal Editor Command-line Parameters

If you launch the Unreal Editor from the command line, you can use the following parameters to control the behavior of the Multi-User Editing system. These parameters set default values for some of the settings listed under Project Settings above.

Parameter

Description

-ConcertAutoConnect

Enables the Auto Connect setting for your Project. Immediately after starting up, the Unreal Editor will attempt to connect to the default server and session configured for it. You can pre-set this default session configuration in the Project Settings, or specify them on the command line using the parameters below.

-ConcertServer=

Sets the value of the Default Server URL setting for your Project.

-ConcertSession=

Sets the value of the Default Session Name setting for your Project.

-ConcertSaveSessionAs=

Sets the value of the Default Save Session As setting for your Project.

-ConcertSessionToRestore=

Sets the value of the Default Session to Restore setting for your Project.

-ConcertDisplayName=

Sets the value of the Display Name setting for your Project.

Console Commands

This section lists the Unreal Engine console commands that affect the Multi-User Editing system.

Command

Description

Concert.DefaultConnect

If you've set up a Default Server URL and a Default Session Name in your Project Settings, and if you're not already connected to a Multi-User Editing session, this console command immediately tries to connect you to the default server and session.

Concert.Disconnect

Disconnects you from the session you're currently connected to, if any.

Concert.EnableOpenRemoteSequencer

Anytime a user with this setting enabled opens a Level Sequence or Master Sequence in the Sequencer UI, the Multi-User Editing system automatically opens the Sequencer UI for all other users in the same session who also have this setting enabled, and loads the same Sequence.This setting is disabled by default. Use Concert.EnableOpenRemoteSequencer 1 to enable it, or Concert.EnableOpenRemoteSequencer 0 to disable it.

Concert.EnablePresence

When you have this setting enabled, you'll see an Actor in the Level Viewport that represents the current position and point of view of each other user working in the same Level that has a Desktop Avatar Actor Class or VRAvatar Actor Class set in their Project Settings.

Concert.EnableSequencePlayer

By default, the Multi-User Editing system only synchronizes Sequencer playback events between Unreal Editor instances that have the same Sequence open in the Sequencer UI.If you also want to synchronize Sequencer playback events to Unreal Editor instances that are running in -game mode, enable this setting.This setting is disabled by default. Use Concert.EnableOpenRemoteSequencer 1 to enable it, or Concert.EnableOpenRemoteSequencer 0 to disable it. You must enable it for each Unreal Editor instance that you start with the -game argument that you want to respond to those playback events.

Remember that if you use the -game option when you launch the engine, you also need to include the -messaging option.

Concert.OpenBrowser

Opens the Multi-User Browser window. Equivalent to choosing Window > Developer Tools > Multi-User Browser from the main menu or choosing Session Browser from the down arrow next to the Multi-User Editing button in the Toolbar.

Concert.OpenSettings

Opens the Project Settings window to the Plugins - Multi-User Editing page. Equivalent to choosing Multi-User Settings from the down arrow next to the Multi-User Editing button in the Toolbar.For details on these settings, see Project Settings above.



Plugin UI in the Editor

Anatomy of a Plugin

Plugin Folders

Code in Plugins

Engine Plugins

Content in Plugins

Plugins in Projects

Distributing a Plugin on the Epic Marketplace

Plugin Descriptor Files

Descriptor File Example

Descriptor File Format

Module Descriptors

Icons

Creating New Plugins

This page describes the development and management of Plugins for use with Unreal Engine 4 (UE4) tools and runtime.

In UE4, Plugins are collections of code and data that developers can easily enable or disable within the Editor on a per-project basis. Plugins can add runtime gameplay functionality, modify built-in Engine features (or add new ones), create new file types, and extend the capabilities of the Editor with new menus, tool bar commands, and sub-modes. Many existing UE4 subsystems were designed to be extensible using Plugins.

If you want to jump right in and create a Plugin now, please see the Creating New Plugins section.

Plugin UI in the Editor

You can see which Plugins are currently installed by opening the Plugin editing interface from the Edit menu.



The Plugin Editor is accessible from the main 'Window' menu. This interface displays all of the Plugins that are currently installed and can enable or disable Plugins individually.

You can browse categories of Plugins using the tree interface on the left. Selecting a category will show all Plugins in that category as well as Plugins in any sub-category. As you navigate through categories, a bread crumb trail displayed at the top of the UI will enable you to jump quickly to higher-level categories. The number displayed next to a category indicates how many Plugins are available in that category.



Plugins are displayed in the main list, along with each Plugin's name, icon, current version, text description, author (and optional web hyperlink), as well as whether or not the plugin is currently enabled.

The search control at the top will enable you to search Plugins displayed in the list by name.



You can enable or disable a Plugin for use with your active project by toggling the Enabled check box under the Plugin's description. You may need to restart the Editor for the change to take effect.

Anatomy of a Plugin

Plugins with code will have a Source folder. This folder will contain one or more directories with module source code for the Plugin. Note that, although Plugins often contain code, this is not actually a requirement. See the Code in Plugins section for more information.

Plugins with code will have a Binaries folder that contains compiled code for that Plugin, and temporary build product files will be stored in a separate Intermediate folder under the Plugin's directory.

Plugins can have their own Content folder that contains Asset files specific to that Plugin. See the Content in Plugins section for more information. Plugin configuration files should be placed using the same convention as other configuration files:

Engine plugins: [PluginName]/Config/Base[PluginName].ini

Game plugins: [PluginName]/Config/Default[PluginName].ini

Plugins do not support their own Derived Data Cache distribution.

Plugin Folders

In order for Plugins to be found, they must be located in one of the search paths for Plugins, either in your project, or in the Engine itself.

Plugin Type

Search Path

Engine

/[UE4 Root]/Engine/Plugins/[Plugin Name]/

Game

/[Project Root]/Plugins/[Plugin Name]/

You can also organize Plugins into subdirectories under the base Plugins folder. The engine will scan all of your sub-folders under the base Plugins folder for Plugins to load, but it will never scan subdirectories beneath a Plugin that has already been found.

Unreal Engine finds your Plugin by searching for .uplugin files on disk. We call these files Plugin Descriptors. They are text files that provide basic information about your Plugin. Plugin Descriptors are discovered and loaded automatically by the Engine, Editor, and UnrealBuildTool (UBT), whenever those programs are run. See the section on Plugin Descriptors to learn about creating and customizing these files.

Code in Plugins

When generating project files for Visual Studio or Xcode, any Plugins that have Source folders (containing .Build.cs files) will be added to your project files to make it easier to navigate to their source code. These Plugins will automatically be compiled by UBT when compiling your game project.

Plugins are allowed to have any number of Module source directories. Most Plugins will only have one Module, but it is possible to create multiple, for example, if a Plugin contains some Editor-only functionality, and other code that is intended to run during the game.

For the most part, Plugin source file layout is the same as any other C++ Module in the Engine.

Plugins are able to declare new reflected types (UCLASS, USTRUCT, etc.) in header files within a Module's Source directory (or one of its subdirectories). The Engine's build system will detect these files and generate code as needed to support the new types. You will need to follow the normal rules for using UObjects within C++ modules, such as including the generated header file and the Module's generated.inl file in one of your Module's source files.

UE4 supports interdependent Modules and Plugins. Project Modules can depend on Plugins by enabling the Plugins in its .uproject file. Similarly, Plugins indicate dependency by enabling other Plugins within their own .uplugin files. There is one important restriction, however, which is that Plugins and Modules are broken into hierarchical levels, and can only depend on other Plugins or Modules at the same level or higher. For example, although a Project Module can depend on an Engine Module, an Engine Module cannot depend on a Project Module. This is because the Engine (and all of its Plugins and Modules) is higher-level than any Project, as it must be able to build without a Project. The following diagram indicates the hierarchy of dependency levels between Projects and Modules:



Arrows indicate possible dependency. Each Plugin or Module type can depend on others at its own level or higher.

Engine Plugins

Unreal Engine 4 has some built-in Plugins included under the Engine directory. Engine Plugins are just like project Plugins, except that they are available for all projects. Typically, these plugins are created by engine and tools programmers to provide baseline functionality that can be used in multiple projects while being maintained in a single place. This can enable the user to add or override engine features without modifying engine code.

Content in Plugins

Unreal Engine supports plugins that contain game content as well as binary code. In order to use Content in a Plugin, the "CanContainContent" setting within the Plugin's descriptor must be set to "true".

Plugins in Projects

Plugins reside under the Plugins subfolder within your project's directory, and will be detected and loaded at Engine or Editor start-up time.

If the Plugin contains modules that have Source folders (and .Build.cs files), Plugin code will automatically be added to generated C++ project files, so that you can work on developing the Plugin alongside your project. Whenever you compile your project, any Plugins that have source available will also be compiled as a dependency of your game.

Plugins that do not have a Source folder are ignored by the project generator and will not appear in your C++ project files, but they will still be loaded at start-up as long as binary files exist.

At present, Plugin configuration files are not packaged with projects. This may be supported in the future, but currently requires manually copying the files to the project's Config folder.

Distributing a Plugin on the Epic Marketplace

To package your Plugin, click the *Package...* link to package your Plugin into a folder for distribution.



Plugin Descriptor Files

Plugin descriptors are files that end with .uplugin. The first part of the file name is always the name of your Plugin. Plugin descriptor files are always located in your Plugin's directory, where the Engine will discover them at start-up time.

Plugin descriptors are in the Json (JavaScript Object Notation) file format.

Descriptor File Example

This example plugin descriptor is from the Engine's UObjectPlugin.

Descriptor File Format

The descriptor file is a JSON-formatted list of variables from the FPluginDescriptor type. There is one additional field, "FileVersion", which is the only required field in the structure. "FileVersion" gives the version of the Plugin descriptor file, and should usually set to the highest version that is allowed by the Engine (currently, this is "3"). Because this version applies to the format of the Plugin Descriptor File, and not the Plugin itself, we do not expect that it will change very frequently, and it should not change with subsequent releases of your Plugin. For maximum compatibility with older versions of the Engine, you can use an older version number, but this is not recommended.

For details about the other supported fields, see the FPluginDescriptor API reference page.

bEnabledByDefault

For Plugins that contain code, the "Modules" field in the descriptor file will contain at least one entry. An example entry follows:

Each entry requires the "Name" and "Type" fields. "Name" is the unique name of the Plugin Module that will be loaded with the Plugin. At runtime, the Engine will expect appropriate Plugin binaries to exist in the Plugin's "Binaries" folder with the specified Module name. For Modules that have a Source directory, a matching ".Build.cs" file much exist within the Module's subfolder tree. "Type" sets the type of Module. Valid options are Runtime, RuntimeNoCommandlet, Developer, Editor, EditorNoCommandlet, and Program. This type determines which types of applications can load the Module. For example, some plugins may include modules that should only load when the Editor is running. Runtime modules will be loaded in all cases, even in shipped games. Developer modules will only be loaded in development runtime or Editor builds, but never in shipping builds. Editor modules will only be loaded when the editor is starting up. Your Plugin can use a combination of modules of different types.

For details about the other supported fields, see the FModuleDescriptor API reference page.

Icons

Along with the descriptor file, Plugins need an icon to display in the Editor's Plugin Browser. The image should be a 128x128 .png file called "Icon128.png" and kept in the Plugin's "/Resources/" directory.

Creating New Plugins

To create a new Plugin, use the New Plugin button in the Editor's Plugin Browser.



From there, you can select which type of Plugin you wish to create, enter a name, and set some basic parameters.



Your new Plugin will now appear in the Plugin Browser, and will be enabled in your current project.

How Virtual Assets Work

Benefits of Virtual Assets

Requirements for Virtual Assets

How to Deploy Virtual Assets

Guidelines for Virtual Assets

Caveats for Virtual Assets

As projects grow larger and reach later stages of development, both the size and number of assets increase. This results in several common pain points:

Syncing large projects from source control takes increasingly longer amounts of time for all developers. This potentially creates a high opportunity cost for syncing a new workspace.

Larger projects use a large amount of hard drive space for each individual developer.

Developers with slow internet speeds suffer from even slower syncs than their team members due to large file transfers and high data use.

Source control systems often perform duplicate work, distributing multiple copies of identical files.

Virtual Assets provide a faster and more efficient method for syncing data among all members of your team as your project grows in size. The core goal of the Virtual Asset system is to reduce the disk space requirements of projects by storing editor bulk data separately from core asset metadata.

This guide provides an overview of how Virtual Assets work and how to use them in your project.

How Virtual Assets Work

When working with Assets, users only need a minimal amount of information about their assets to display them in the editor. For example, a Texture only needs a thumbnail image and editor properties (such as coordinates and scale) to appear in the Content Browser. Otherwise, the bulk of the .uasset file for textures is pixel data, which the user might never call to load.

Virtual Assets separate this information into two parts:

Core asset metadata – portions that exist where the assets are in your source control.

Bulk data – The main part of the asset's data, held in a shared [Derived Data Cache (DDC)](setting-up-your-production-pipeline/derived-data-cache] in a separate location within your source control.

This makes it possible to sync only the core asset data when you sync your project in source control. You can then browse the assets as if you had them on your machine, and selectively sync and load their bulk data when needed. Virtual Assets also support the use of different feature development branches, which provides a way to keep experimental features from affecting other team members until they are stabilized.

Benefits of Virtual Assets

Virtual Assets provide the following benefits. These are most strongly felt on large projects with growing data footprints, but can benefit projects of all sizes.

Individual contributors only sync bulk data for files when they need them. This uses significantly less data, which can be beneficial if you do not have access to a high-speed connection, and reduces the amount of sync time needed to pull a project. This is especially useful on live service games with a large backlog of assets.

Bulk data lives primarily in your source control or in a derived data cache in a centralized location rather than on individual developers' hard drives. This means that your projects use less hard drive space for your team members. The savings depend on what types of assets are in your project, but a 5x or greater reduction in hard drive use is common.

If you have multiple workspaces for your project, this can result in duplicates of many identical files. If you use Virtual Assets with a shared DDC, these files are de-duplicated, further reducing the footprint on individual users' machines.

Requirements for Virtual Assets

The following requirements must be met to use Virtual Assets in your project.

Source Control

To use Virtual Assets, you need to integrate your project with Perforce. We recommend using the Unreal Editor check-in workflow as well, as this ensures that files will be virtualized when checked in.

Shared DDC (Optional)

Using a Derived Data Cache is not required to use Virtual Assets, but we do recommend it, as these can have better performance than accessing Perforce. DDC backends should only be used as your cache storage, as DDCs are not usually safe for use as persistent storage.

Internet Connectivity

Virtual Assets work well if your users have reasonable access to a shared data cache with a reliable, fast connection. Otherwise, the user may see noticeable hitches and may be better off taking all of the sync time and space upfront.

Virtual Assets also do not have a "work offline" mode. This means if you have users who are working while their internet is disconnected, Virtual Assets will not be able to retrieve bulk data when they request it. The editor will not crash, but they will need to reconnect to grab any bulk data they need.

How to Deploy Virtual Assets

Virtual Assets are currently a Beta feature and are disabled by default. You can enable them by adding the following properties in your project's DefaultEngine.ini file:

These settings enable virtualization for all assets that are currently supported. From this point on, any assets you commit to your repository will be virtualized automatically. The virtualized payloads are stored under your project's Saved directory, in a subdirectory named VirtualizedPayloads.

To check that a package is virtualized, hover over the asset in the content browser. If the tooltip's entry for Has Virtualized Data says true, the asset has been successfully converted to using the Virtual Asset system.



For more information about how to configure Virtual Assets, including the above config file, refer to the Virtual Asset Quickstart Guide.

How to Manually Target Files

If you want to virtualize assets without having to make changes to files, use the Unreal Virtualization Tool to convert them. The source code for this tool is located in Engine\Source\Programs\UnrealVirtualizationTool\. After you compile the Unreal Virtualization Tool, run it in a command line with the following arguments:

ClientSpecName: the name of the workspace to submit from.

Changelist: The change list to virtualize and submit.

All files contained in the targeted Changelist will be converted to using Virtual Assets, then submitted.

Define Your Project's Backend

Backend graphs define where Unreal Engine stores virtual assets in your project's backend. This is defined mainly by two lists:

CacheStorageHierarchy: Fast backends used to speed up pulling operations. It is preferable to find payloads in these backends, but not essential.

PersistentStorageHierarchy: Slower, but more reliable backends. You must always be able to find files in Persistent Storage.

When developers pull payloads, the system looks at the backends in CacheStorageHierarchy first, then if it does not find the requested data in one of those backends, it falls back to PersistentStorageHierarchy. If either list contains more than one backend entry, the system processes them in the same order they are listed, so they should be listed in order from fastest to slowest. Typically, CacheStorageHierarchy contains shared DDCs, whereas PersistentStorageHierarchy would refer to your source control system.

You can define a backend graph in your DefaultEngine.ini file alongside the other config variables for Virtual Assets. The following is an example backend graph with placeholder names:

To target a backend graph, set the BackendGraph variable under [Core.ContentVirtualization] to the name of the graph you want to use.

For more information about how to build a backend graph, refer to the Backend Graphs for Virtual Assets page.

Guidelines for Virtual Assets

The following sections provide advice for how you should incorporate Virtual Assets into your project.

Methods for Virtualizing Assets

If you are starting a new project, you should start using Virtual Assets immediately. This will give your team all the performance benefits without the problems that can occur if you add Virtual Assets later, providing the smoothest development experience.

If you are adding Virtual Assets to an existing project, then you need to consider whether you want to use manual, bulk, or rolling methods for adding this support. Which approach is right for your project depends on its scope and your production timeline.

Virtualizing an entire project all at once gains the best sync performance as quickly as possible, but becomes riskier the larger your project is. All binary content has to be checked in to make the switch possible. Additionally, all the bulk data for your project is pushed to the shared DDC at once, which poses potential security risks. This can result in significant disruptions to your project, which may be infeasable for especially large projects in later stages of production.

To avoid disruptions, you can use a script to periodically run the Unreal Virtualization Tool with a pre-determined set of changelists, effectively virtualizing your assets in batches. This makes it possible to handle different teams or features in stages while ultimately ensuring you apply Virtual Asset use globally.

Virtualizing only specific folders provides a greater degree of control over which assets have bulk data in your shared DDC, which also makes it easier to roll out Virtual Assets in stages. However, you will only improve sync performance in the features or folders that you have given direct attention to.

To get the most benefit immediately with the least disruption to your project, you should target the largest assets in your project. You can also safely target assets that haven't changed in a long time.

To ensure you apply the benefits of Virtual Assets widely, you can virtualize assets as team members save their files. While this will not catch assets that your team isn't actively working on, it ensures that Virtual Assets are introduced steadily over time.

If you are starting a new project, you should start using Virtual Assets immediately.

If your project is in mid or late production, you may not want to implement Virtual Assets on content you are heavily iterating, as this can disrupt your project. However, you could safely virtualize assets that your team has not changed for a long time.

To limit the impact of switching to Virtual Assets on your project's stability, but still benefit from them, you can also target only the largest assets in your project.

Caveats for Virtual Assets

Although Virtual Assets are beneficial, there are some cases where they can introduce complications to your project or lose effectiveness.

Additional Data Validation

When a user submits assets, they must commit the asset's bulk data even when they have only changed the primary metadata. You can enforce this from the editor, which can fetch data from the cache.

Network and Asset Usage

Several factors in a user's network connection can reduce the effectiveness of the Virtual Asset system:

Slow network connection to a DDC.

No access to a DDC.

Very few people using similar assets.

If any of the above are true, the bulk data pull might be so slow that users will compile and cook many or all assets locally. This uses the same amount of disk space and may take longer than just syncing upfront.

Primary Data Split

Virtualization splits the primary data into two pieces that are stored separately. This makes the data less portable than with non-virtualized data, and introduces complications if you need to ship a demo of your project.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Using Perforce as Source Control

Source Control Inside Unreal Editor

Derived Data Cache

1. Required Setup

2. Config File Setup

3. Virtualize a Package

4. Validate Your Virtualized Package

Configure Virtual Assets for Your Project

This guide explains how to virtualize a small sample or test project.

1. Required Setup

This guide does not require a specific platform or template project, and you can follow along with any Unreal Engine project. However, your project must be set up to use Perforce as source control, and you need to set up the in-editor check-in workflow. For more information about Perforce setup, refer to Using Perforce as Source Control and Source Control Inside Unreal Editor.

You also need to set up a shared Derived Data Cache (DDC) for your project to act as your fast cache storage. For more information, refer to Derived Data Cache.

2. Config File Setup

Open your project's DefaultEngine.ini file and add the following text:

This enables virtualization for all currently-supported assets. These settings have the following impact:

VABackendGraph_Filesystem defines a backend graph.

SourceControlCache defines your Perforce source control system as a backend for virtualized payloads and provides an alias to reference it with. Change the DepotRoot value to your project's root directory.

DDCCache defines your shared DDC as a backend for virtualized payloads and provides an alias to reference it with.

CacheStorageHierarchy sets DDCCache as your fast cache storage backend. If your project can find bulk data payloads here, it will prefer pulling that data from this source.

PersistentStorageHierarchy sets SourceControlCache as the persistent storage backend. This is a location where your project is guaranteed to find bulk data payloads if all other backends fail.

Refer to the Backend Graphs page for more details about defining backends for your project.

3. Virtualize a Package

After enabling Virtual Assets, any package you submit from the editor in your project should be virtualized when submitted. This will work for any editor submission method.

The Unreal Virtualization Tool can also submit change lists. The source code for the Unreal Virtualization Tool is located in Engine\Source\Programs\UnrealVirtualizationTool\. To use it, compile the tool, then run it in a command line with the following arguments:

Command

Description

ClientSpecName

The name of the workspace to submit from.

Changelist

The changelist to virtualize and submit.

Normally you should not virtualize assets without submitting them. However, this tool makes it possible by adding -NoSubmit to the command line. The packages in the changelist will be virtualized, but the changelist itself will not be submitted.

4. Validate Your Virtualized Package

To determine whether your package has successfully virtualized, hover your mouse over the asset in the content browser and check the Has Virtualized Data entry.



Alternatively, you can look at the file size of the asset. If the .uasset file is significantly smaller than it was before you virtualized it, the bulk data was separated from the .uasset and is now contained in the Saved/VirtualizedPayloads directory.

To investigate the contents of the package file, right-click the asset in the Content Browser, click Copy File Path, then input the following command in the console:

Replace [file path] with the file path you copied from the Content Browser.

This console command can take either a full path or a package path, and it will write a summary of the payloads in the output window. The output displays a list of the locally stored payloads followed by a list of the virtualized payloads. DumpPackagePayloadInfo does not use any cached information, such as the asset registry. Instead, it re-parses the package's information each time you use it, so the information it provides should always be up to date.

Configure Virtual Assets for Your Project

Now that you have a basic implementation of Virtual Assets in place, you can configure it to suit your project's needs. The following pages provide more information about the ways you can customize your setup:

Virtual Assets Overview has guidelines about how to configure and deploy Virtual Asset support in your project.

Backend Graphs for Virtual Assets provides information about setting up Virtualization Graphs.

Debugging Virtual Assets explains how to output information about Virtual Assets for troubleshooting and debugging.

Overview

Storage Lists

Priority

How to Use Backend Graphs

Create a Backend Graph

Select a Backend Graph for Your Project to Use

Recommended Backend Graph Setup

The Virtual Assets system stores bulk data payloads for assets in a backend, typically a source control repository, Derived Data Cache (DDC), or some other form of remote storage. When users need to edit a Virtual Asset, the system pulls the bulk data from the backend and loads it on their computer. However, all backend solutions have their own balance of speed, storage space, reliability, and practicality.

To get the best of all possible solutions, the Virtual Assets system uses backend graphs to look for files in multiple backends, using each type of backend for a different type of storage. Faster backends can contain temporary caches for frequently-used files, while slower ones can be used for long-term, persistent storage. This guide acts as a reference for how to configure backend graphs for your own projects so that you can tailor your project's use of virtual assets to optimize the process of running pulls.

Overview

Backend graphs are groups of parameters in your *Engine.ini file that define what backends are available to pull bulk data from, as well as the order of priority that the Virtual Assets system uses when determining which ones it should pull from first.

Storage Lists

Each backend graph is built mainly around two lists: CacheStorageHierarchy and PersistentStorageHierarchy.

PersistentStorageHierarchy is a list ofslower, but more reliable backends. All of your files should always be available within a persistent storage backend. A typical example of a persistent storage backend would be a source control repository such as Perforce, which offers a permanent, centralized storage solution for all of a team's files, but can vary in performance depending on individual users' internet connections.

CacheStorageHierarchy is a list of faster, but less reliable backends that are used to speed up pulls, especially for frequently-used files. A typical example of cache storage would be a Shared Derived Data Cache (DDC), which would be located on a shared network drive within your organization's workplace. Because this is part of your local network, the DDC would be faster. However, if your team is highly distributed or has a large number of remote team members, a local resource like this would not be available to them, and the system would either need to fall back on something else, or they would need to have their own alternatives.

Priority

When the Virtual Assets system tries to pull bulk data, it looks at backends in the cache storage list first, then falls back on persistent storage if it can't find the needed files. When it looks at either list, it will look at each backend in the order that they are listed in, so you should try to list them in order from fastest to slowest.

How to Use Backend Graphs

Create a Backend Graph

To create a backend graph, open your DefaultEngine.ini file and create a new category with the name of your backend graph. For your convenience, you should put it near Core.ContentVirtualization.

A backend graph requires the following entries:

CacheStorageHierarchy=(Entry=[Name of Cache])

PersistentStorageHierarchy=(Entry=[Name of Persistent Storage])

Entries for each backend you want to use, providing a name, type, and information needed to find a path to it, if applicable.

Backends are defined with a name, followed by an entry containing the needed data to find the backend. This provides an alias to use in the Storage Hierarchy lists. Each entry contains the following information:

Parameter

Description

Type

Describes the type of backend that the current alias uses. The available Types are as follows:

FileSystem – A local file system.

P4SourceControl – Your Perforce source control system.

DDCBackend – A shared DDC for your project.

DepotRoot

If using the P4SourceControl type, this is the root path for your depot.

Path

If using the FileSystem type, this is the root folder where you are storing payloads.

Each entry in the storage lists uses the format Entry=[BackendName], where [BackendName] is replaced with one of the backends you defined. If you list more than one, you need to separate them with commas. For example:

CacheStorageHierarchy=(Entry=DDCCache1, Entry=DDCCache2, Entry=DDCCache3)

When the system parses this information, it will look at each backend in the order it is listed. Therefore, you should list them in order from fastest to slowest.

The following is an example of a backend graph with placeholder names:

This information is added in your DefaultEngine.ini file. The header is the name of the backend graph, and it contains a list of aliases defining which backend graphs are available. For example, DDCCache points at a shared DDC, while SourceControlCache points at a source control system used in your project. These names are arbitrary and can be changed as meets your needs. Once you have defined these entries, you can put them in the CacheStorageHierarchy and PersistentStorageHierarchy lists.

Select a Backend Graph for Your Project to Use

After creating a backend graph, you need to configure your project to use one of them when using the Virtual Assets system.

Navigate to the Core.VirtualizationModule section of your DefaultEngine.ini file. The BackendGraph parameter is set to ContentVirtualizationBackendGraph_None by default.

Change ContentVirtualizationBackendGraph_None to the name of your own backend graph. After that, your project will use the graph you defined.

You can override backend graphs from the command line by using the following command:

Where [GraphName] is a variable that represents the name of the graph you want to use. To troubleshoot any issues relating to this graph, the log should show the name of the graph from the configuration file, including the name of the graph that is overriding it from the command line, and the name of the graph that gets mounted.

Recommended Backend Graph Setup

We recommend using your project's source control for the persistent storage solution and a shared DDC cache for your cache storage. You can create more complex schemes as needed for your organization, but this provides the best balance between improved performance and simplicity.

Validate Your Package Virtualized

Monitor Virtual Assets With the Statistics Panel

Debug Command Reference

Logging

This page contains information about how to view information and debug output about Virtual Assets in your projects.

Validate Your Package Virtualized

To determine whether your package has successfully been virtualized, hover your mouse over the asset in the content browser and check the Has Virtualized Data entry.



Alternatively, you can look at the file size of the asset. If the .uasset file is significantly smaller than it was before you virtualized it, the bulk data was separated from the .uasset and is now contained in the Saved/VirtualizedPayloads directory.

To investigate the contents of the package file, right-click the asset in the Content Browser, click Copy File Path, then input the following command in the console:

Replace [file path] with the file path you copied from the Content Browser.

This console command can take either a full path or a package path, and it will write a summary of the payloads in the output window. The output displays a list of the locally stored payloads followed by a list of the virtualized payloads.

DumpPackagePayloadInfo does not use any cached information, such as the asset registry. Instead, it will re-parse the package's information each time you use it, so the information it gives should always be up to date.

Monitor Virtual Assets With the Statistics Panel

The Statistics Panel shows information about how Virtual Assets behave on your machine. You can locate this panel in Tool > Audit > Virtual Assets.



The Virtual Assets Statistics Panel. The current panel displays the Read, Write, and Cache statistics for two different backends: the DDC backend and the project's source control.

Each row in the Virtual Assets tab represents a different backend that should be easy to identify based on your config file setup. Unreal Engine records stats for the following:

Read

Pulling payloads from the backends when needed.

Write

Pushing payloads to a backend when virtualizing.

Cache

When a payload is pulled from a slower backend, such as a source control system, it is pushed to the faster backend to make repeated access faster.

Debug Command Reference

This section provides the debug commands for debugging the Virtual Asset system in Unreal Engine. It provides commands for both the command line and the Console window in Unreal Editor where applicable. Most commands used in the command line can also be used in your config files. You can also use the command line versions of these commands in your Virtualization Graphs.

Disable The Virtual Asset System

Command line: -VADisable

Console: VA.DisableVirtualization

Disables the virtualization system and mounts the null implementation instead.

This is the same as setting SystemName in the [Core.ContentVirtualization] section in the DefaultEngine.ini file to None.

When disabled, all methods in the virtualization system interface will return their failure states.

Override The BackendGraph

Command line: -VABackendGraph=

Change which backend graph the virtualization system uses when initializing as though you were editing the ‘BackendGraph' value of the [Core.ContentVirtualization] section in the DefaultEngine.ini file

The name of the graph must match an existing graph set up for the project you are trying to run. If it does not exist then the virtualization system will give a fatal error on startup.

Disable Specific Backends

Command line: -VAMissBackends=[backend name]

Console: VA.MissBackends

Disable one or more backends from pulling payloads at all. This command can take any of the following inputs:

Input

Result

Backend name

The name of the backend you want to disable. You can provide multiple backend names by combining them with a +. For example, -VA-MissBackends=FastCache+SlowCache would disable both of the listed backends.

All

Prevent any backend from pulling.

Reset

Reset and enable all backends.

List

List currently disabled backends.

Simulate Bad Connections

Command line: `-VAMissChance=[percent chance of failure]

Console: `VA.MissChance`

Simulate a bad connection by setting a percent chance that payload pulls will automatically fail. For example, -VA-MissChance=50 will set a 50% chance of failure.

Fail a Specified Number of Payload Pulls

Console: VA.MissCount=[number of payload pulls to miss]

Automatically miss the next X payload pulls, where X is the number you specify with this command.

There is no command line version for VA.MissCount.

Validate Payload Pushes

Command line: -VAValidatePushes

Console: `VA.ValidatePushes`

Validates payloads by pulling them after each push and comparing them to the original file. This is the same as setting the ValidateAfterPushOperation option in your DefaultEngine.ini file.

Force Single-Threaded Mode

Command line: -VASingleThreaded

Console: VA.SingleThreaded

Forces the system to work in single-threaded mode, eliminating multi-threaded access as a potential source of bugs. This is the same as setting the ForceSingleThreaded option in your DefaultEngine.ini file.

Logging

When the virtualization system is initialized there is a detailed log showing the options and settings enabled. This includes fatal log messages if something is not set up correctly and has the potential to cause critical data failure.

During the normal course of operations, logging is kept to a minimum and should only display warnings and errors where appropriate. However, if you enable verbose logging the log will show additional information that is useful when debugging problems.

To enable logging, use the following commands on the command line:

Recommended Asset Naming Conventions

Asset Management

Viewing Redirectors in the Content Browser

Clean Up Redirectors in Unreal Editor

Clean Up Redirectors Using the ResavePackages Commandlet

Caveats

Renaming

Dangling Redirector

When you move or rename an asset in Unreal Engine (UE), it leaves a Redirector in the asset's old location. Packages that are not currently loaded but that reference the asset will therefore be able to find it in its new location.

Choosing a consistent naming scheme early in your project will avoid many of the problems experienced with Redirectors. Refer to Recommended Asset Naming Conventions for guidelines on how to name assets.

Viewing Redirectors in the Content Browser

There are two filters for viewing Redirectors in the Content Browser:

Filter > Other Filters > Show Redirectors will make Redirectors visible in the Content Browser, but won't filter out other types of assets.



Filter > Miscellaneous > Redirectors will exclusively show Redirectors in the Content Browser, similar to how other filters work.



Clean Up Redirectors in Unreal Editor

To remove Redirectors and force your asset references to re-target an asset's new location, right click a redirector and select Fixup. This will resave all packages that point to the redirector, and will delete the redirector if it was able to resave all things referencing it.

Clean Up Redirectors Using the ResavePackages Commandlet

You can also run the ResavePackages commandlet using the -FixupRedirectors option to clean up all redirectors in your project. The following is an example command line:

This version of the command line will check out all files that need to be fixed up from your version control system, then clean up their redirectors on the user's local machine. After that, the user must submit them. -autocheckin can be used by an automated process and it will also check the files in for you.

Caveats

Renaming

If you create an object, rename it, and then create a new object with the same name as the original, an error will occur. This is because a Redirector was created when the first object was renamed, and a Redirector and a resource cannot have the same name.

Dangling Redirector

There are a few known issues with Redirectors that can be reproduced as follows:

Scenario 1

Rename object A to B.

Delete B.

An error message will say that B could not be deleted because it is in use. This happens because the Redirector created during the rename will still point to B.

Scenario 2

Rename object A to B.

Rename object B back to A.

Delete A.

The redirector that was created for the first rename will be destroyed, but a new one will be created at B. As a result, A will not be able to be deleted because it is being referenced.

Fixing redirectors from the editor or SavePackages before deleting should solve these problems.

Installing the Editor Scripting Utilities Plugin

In the Unreal Editor user interface, you have access to a vast range of visual tools for setting up your Project, designing and building Levels, creating gameplay interactions, and more. But sometimes, once you've figured out what you need the Editor to do, you might want to invoke its tools and commands programmatically — either in a reusable script, or by constructing your own interfaces to drive the Editor.

This can help you:

Minimize or eliminate the need to repeat the same series of tasks over and over,

Automate or randomize the placement, layout and settings of Actors in your Levels,

Create your own Asset import and management pipelines,

Interoperate with other third-party applications and pipeline scripts,

Extend the Editor with additional tools, and even UIs, that you customize specifically for the needs of your Project or content.

The pages in this section show how you can run these kinds of in-Editor scripts using Blueprints, Python, and remote control ol.

Installing the Editor Scripting Utilities Plugin

If you're planning to do any Editor automation, regardless of the language or system you plan to use, you will almost certainly want to install the Editor Scripting Utilities plugin. This plugin simplifies many of the most common operations you'll need to do in the Editor, handling uncommon edge cases so that you don't have to understand all the internal details of how the Editor works in order to do something conceptually simple.

To install the plug-in:

From the main menu, choose Edit > Plugins to open the Plugins window.

Under the Scripting category, find the entry for the Editor Scripting Utilities and check its Enabled box.



If you're interested in using Python, you can also check the Enabled box for the Python plugin while you're here. For more, see Scripting the Editor using Python.

Restart the Editor and reload your Project.

Options for Running Blueprints in the Editor

Editor Utility Widgets

Editor Utility Blueprints

Call in Editor

Startup Objects

Accessing Editor-Only Blueprint Nodes

Editor Utility Subsystem

Blueprints are not only useful for creating runtime gameplay in your Project. They can also be a very effective tool for interacting with your Project content within the Unreal Editor. You can run Blueprint graphs on demand in the editor to work with Assets, lay out content in your Levels, trigger actions in the editor UI, or even extend the editor with your own custom UI panels.

This page describes some of the basics involved in using Blueprints to script and automate the Unreal Editor.

In past releases of Unreal Engine, we referred to Blueprint graphs designed to run in the editor as Blutilities—short for Blueprint Utilities. You may still see that term around, but now we've standardized on Editor Utility Widgets and Editor Utility Blueprints.

Options for Running Blueprints in the Editor

Once you've decided that you want to run Blueprint graphs within the Unreal Editor, there are several different techniques you can use to set up and trigger your Blueprint code.

Editor Utility Widgets

Editor Utility Widgets are UMG widgets that the Unreal Editor can render in the same kind of dockable panel used for all other tools in the editor UI. This approach is best if you need a rich UI to control your Blueprint. You can take advantage of all the visual styling options of UMG, combined with the rich scripting control of Blueprints. This is the most flexible and powerful option, but also quite simple to get started with, and is recommended for most editor scripting work.

For details on how to create an Editor Utility Widget and open it in the editor, see Editor Utility Widgets.

Editor Utility Blueprints

Editor Utility Blueprints are a specialized kind of class that is intended for logic that you need to run only within the Unreal Editor, never at runtime, and that does not need any custom UI.

One built-in use case for these classes is to support scripted actions: graphs that you trigger from the context menu that appears when you right-click an Actor in the Level or an Asset in the Content Browser.

For details, see Scripted Actions.

Call in Editor

When you create a custom event or a function in a Blueprint class, you can mark that event or function as callable in the editor. If you place an instance of that Blueprint class in a Level and select it, you can trigger your custom event or function in the Details panel. This approach is best to use anytime you need a Blueprint graph to work both at runtime and in the editor.

For details, see Calling Blueprints in the Editor.

Startup Objects

You can identify specific Editor Utility Widget classes and Editor Utility Blueprint classes in your Project as startup objects. Each time the editor loads up your Project, it automatically creates an instance of each of these startup objects and invokes a pre-defined function. This is a good option if you need a Blueprint class to always carry out certain actions when your Project is loaded, or if you need to always bind Blueprint logic to events that happen as you work on your Project content in the editor.

For details, see Running Blueprints at Editor Startup.

Accessing Editor-Only Blueprint Nodes

Most operations that involve modifying Asset files or working with the Unreal Editor UI can't work in your game at runtime. Therefore, you can only access editor-only features like these—that is, any functions that are defined in a module whose type is set to Editor—from Blueprint classes that are also editor-only.

For example, if you use a Blueprint class that derives from a parent class that can be used at runtime—such as the base Actor class—you'll see a limited set of functions listed under the Editor Scripting category in your Blueprint Editor. However, if you create an Editor Utility Blueprint, an Editor Utility Widget, or a normal Blueprint class that derives from any editor-only parent class, you'll see a much larger and more comprehensive set of functions that you can use:





Actor class

EditorUtilityActor class

If you've installed the Editor Scripting Utilities plugin, this is where you'll find the functions it exposes for working with Static Meshes and other kinds of Assets. See Scripting and Automating the Editor.

Editor Utility Subsystem

At startup, the Unreal Editor initializes a subsystem that is intended specifically for managing the behavior of the editor's scripting features. For example, this subsystem handles things like spawning and cleaning up Startup Objects, and handling the creation and destruction of new editor panels for Editor Utility Widgets.

You can also use the Editor Utility Subsystem yourself in your own C++ or Blueprint code. For example, you could retrieve the Editor Utility Subsystem and call its SpawnAndRegisterTab() method to programmatically open up a new panel in the editor UI that hosts an instance of an Editor Utility Widget class in your Project.

For more about subsystems and how you can access and use them in C++, Blueprint, and Python, see Programming Subsystems.

Supported Blueprint Classes

Steps

You can call Blueprint Custom Events and Blueprint Custom Functions on demand in the Unreal Editor. This can be especially useful any time you need to run the same Blueprint Graph both at runtime and in the Editor. For example, you can test or preview your runtime gameplay within the Editor UI. However, it can also be a simple way to trigger Blueprints within the Editor that require an Actor or a location in 3D space as a context.

Supported Blueprint Classes

Not all Blueprint Classes allow their Custom Events and Functions to run in the Unreal Editor.

The steps described below work for any Blueprint Class that you can place in a Level—that is, any class that derives directly or indirectly from Actor.

If you need access to Editor-only features like working with Assets in the Content Browser, you can derive your Blueprint Class from a placeable Editor-only base class, such as EditorUtilityActor. However, keep in mind that you won't be able to trigger your Blueprint at runtime when you use an Editor-only base class, because Editor-only classes are not included in packaged Unreal Engine applications.

Editor Utility Blueprint classes that derive from the Actor base class don't expose buttons in the Details panel for any Functions or Custom Events that are marked as callable in the Editor. If you absolutely need to use a button in the Details panel to drive your Blueprint logic, create your graphs in a normal Blueprint class and not in an Editor Utility Blueprint class. However, for a much more flexible and powerful approach to creating a custom UI to drive Blueprint logic in the Unreal Editor, consider using an Editor Utility Widget instead.

Steps

Any time you use a Custom Event node in the Event Graph of your Blueprint Class, you can set the Graph > Call in Editor option in the Details panel:



Similarly, when you create a new function on your Blueprint Class, you can select the node for your new function and set the same option in the Details panel:



Add an instance of your Blueprint Class into your Level if you haven't already.

Select the Blueprint Actor in the Level Viewport or in the World Outliner. The Details panel shows a button for each of the Call in Editor events and functions you've set up. You'll typically find them in the Default section, where Blueprint Classes also expose variables that are marked as Instance Editable.



If your Custom Event or function has any inputs, it will not be shown in the Details panel.

Click these buttons to trigger execution of the Event Graphs starting from your Custom Event nodes, or to trigger your custom functions.

Steps

End Result

Restricting an Action to a Specific Class

Dynamic Inputs

Scripted Actions are Editor Utility Blueprints that you launch in the Unreal Editor by right-clicking Assets in the Content Browser, or by right-clicking Actors either in the Level Viewport (shown above) or in the World Outliner.

This kind of workflow is especially useful any time you need your Blueprint logic to have contextual awareness about a certain set of Assets or Actors. Typically, a Scripted Action gets the list of Assets or Actors that are selected at the time you run the action, then modifies those objects or otherwise takes them into consideration in its graph.

The instructions on this page show you how to create and launch these kinds of Editor Utility Blueprints, and how you can customize them to apply only to specific types of Assets or Actors.

Steps

In this procedure, we'll create a new Editor Utility Blueprint class from one of the parent classes that support Scripted Actions, and we'll set up a new event graph for that class that will show up as a Scripted Action.

In the Content Browser, right-click the folder where you want to create your new class, and choose Editor Utilities > Editor Utility Blueprint from the context menu.

Decide whether you want your Scripted Action to operate on Assets that you select in the Content Browser, or on Actors that you select in the Level Viewport or World Outliner.

If you want your Scripted Action to operate on Assets, choose AssetActionUtility as the parent class, then press Select.

If you want your Scripted Action to operate on Actors, choose ActorActionUtility as the parent class, then press Select.



Give your new class a descriptive name in the Content Browser.

You won't see this class name when you run its Scripted Actions. You'll need it only to distinguish this class from the other Blueprint classes in your Project if you need to modify your Scripted Actions or add new ones later.

Double-click your new class to open it in the Blueprint Editor.

To create a Scripted Action for this class, you can either create a new function, or create a new Custom Event node in the Event Graph for the class.

Make sure that the Call In Editor box is checked on the function entry node or the Custom Event node. This is automatically done for you when you create a new function, but you'll have to do it yourself if you choose to use a Custom Event.

For example, this new function on an AssetActionUtility iterates through the list of Assets that are selected in the Content Browser, and prints the name of each one in the Level Viewport.

Click for full image.

The image below shows a similar function implemented on an ActorActionUtility.

Click for full image.

You'll find some useful Blueprint nodes for your Scripted Actions under the Development > Editor category, including the nodes shown in the examples above that return a list of the objects selected at the time your Scripted Action is run: Get Selected Assets, which returns an array of references to all the Assets selected in the Content Browser, and Get Selection Set, which returns an array of Actors that are currently selected in the Level.

You also will want to install the Editor Scripting Utilities Plugin, if you haven't already, to get access to additional function libraries for working with Assets and Level Actors. See Scripting and Automating the Editor.

Save and Compile your Blueprint class.

End Result

Once your Blueprint class is saved and compiled, you should see a new Scripted Actions sub-menu in the context menu for either Assets or Actors, depending on the parent class you chose for your Blueprint class. This sub-menu contains each of the functions or Custom Events that you set up in your Blueprint class.

For example, when you right-click one or more Assets in the Content Browser:



Or when you right-click one or more Actors in the Level Viewport or World Outliner:



Each function and Custom Event that you set up on your AssetActionUtility or ActorActionUtility class becomes available as a separate option in the context menu. You can create as many different Scripted Actions as you need within a single Blueprint class, or you can create multiple Blueprint classes and distribute your Scripted Actions across those classes.

Restricting an Action to a Specific Class

Depending on the work you need your Scripted Actions to carry out, you may want them to appear in the context menu only for specific types of objects.

For example, say you create a Scripted Action that changes Materials on selected Actors. In this case, you might want that action to only appear when the user right-clicks on Static Mesh Actors, but not when the user right-clicks on Light Actors or Blueprints.

The AssetActionUtility and ActorAssetUtility base classes both offer a built-in function named GetSupportedClass. This function determines the class of objects that need to be selected in order for the Scripted Actions in your Blueprint class to appear in the context menu. Each time the user right-clicks on a set of Assets or Actors, this function is called to get the class type supported by the AssetActionUtility or ActorAssetUtility class. If it returns a class type, that return value is compared against the set of Assets or Actors that the user currently has selected. If at least one of those Assets or Actors has a class that matches the class returned by GetSupportedClass, then the Scripted Actions will appear in the context menu. By default, the GetSupportedClass function returns nothing. This makes all Scripted Actions appear regardless of the classes of Assets or Actors you have selected.

If you want to change this default behavior, you can override the GetSupportedClass function in your class to return a specific class type:



For example, this implementation within an ActorAssetUtility returns the StaticMeshActor class:



With this implementation, the Scripted Actions in this class will appear in the context menu when the user has at least one Static Mesh Actor selected at the time they open the context menu:



But the Scripted Actions do not appear when the user only has other kinds of Actors selected:



If you have multiple Assets or Actors selected, the behavior is permissive: as long as at least one of the selected items matches the class returned by GetSupportedClass, your Scripted Actions will appear in the context menu. Even if you override GetSupportedClass to restrict the classes handled by your actions, you're not guaranteed to only have instances of that class selected when the action gets run. Keep this in mind when you implement your Blueprint graphs.

Dynamic Inputs

You can set up your Scripted Actions to require information from the user who invokes them. If you add one or more Inputs to your function entry node or Custom Event node, you'll be prompted to supply that input each time you run the Scripted Action in the editor. This can be useful any time your script needs some extra information that may be different each time you call the action.

For example, this function has three inputs: a string, an Actor Object Reference, and a Material Object Reference:



When you run the Scripted Action for this function, the editor pops up a small window for you to set these input values:



The editor validates that each input matches the type of value it is supposed to be. However, it doesn't guarantee that the inputs will have values at all, or that those values will make sense in any particular context. Keep in mind that your script should handle unspecified input values and validate the input values the user does provide.

Configuration Files

Event Dispatchers

Programming Subsystems

Steps

End Result

Binding to Editor Events

You can set up the Unreal Editor to always run predefined Blueprint graphs every time your Project is opened. This can help you to ensure that the editing environment is set up the way you are expecting, regardless of who opens your Project or what computer they open it on. For example, depending on the needs of your content development pipeline or production standards, you may need to initialize some editing systems that you have created, load or modify content, reimport Assets from disk to pick up latest modifications, open custom Editor Utility Widgets, or bind to events that may occur during the editing session.

The instructions on this page show how you can register Editor-only Blueprint classes as startup objects, so that the Unreal Editor will invoke functions on those objects every time it starts up.

These instructions work with any Editor Utility Blueprint that derives directly or indirectly from EditorUtilityObject, and with any Editor Utility Widget.

Steps

If you don't already have an Editor Utility Blueprint that derives from EditorUtilityObject, or an Editor Utility Widget, create one. For example, these instructions create a new Editor Utility Blueprint:

Right-click in the Content Browser and choose Editor Utility > Editor Utility Blueprint.



Choose a parent class. EditorUtilityObject is a safe choice, but you could choose any other class that derives from EditorUtilityObject. Click Create.



Enter a descriptive name for your new class, and press Enter.



Double-click your Blueprint class to open it in the Blueprint Editor.

Override the Run function for the class.

To do this, hover over the Functions group in the My Blueprint panel until the Override button appears. Click the Override button and select Run from the dropdown list.



The Blueprint Editor creates a new Event Run node in the Event Graph. Add the Blueprint logic you want to trigger here.

For example, this implementation writes a message to the log to indicate that the function was called, then spawns a cube in the middle of the editor's default startup Level.



Compile and Save your Blueprint class.

Shut down the Unreal Editor.

Find the DefaultEditorPerProjectUserSettings.ini file, which is located in your Project folder at Project/Config/<platform>/DefaultEditorPerProjectUserSettings.ini. Open it in a text editor.

Find the following section of the file:

If this section doesn't exist, create it.

For each Blueprint class that you want to act as a startup object, add the path to that class as a new value in the StartupObjects array. Start the path with /Game/, then add the path to the Blueprint class as shown in the Content Browser. Follow the object name with a period (.) character, then repeat the object name again.

For example, to register the object created under step 1 above, you would use:

If you need to register multiple startup objects, precede each additional line with a plus (+) character. For example, a possible configuration with three startup objects might look like this:

Save and close the .ini file.

Restart the Unreal Editor and reload your Project.

End Result

When you reload your Project, the editor Utilities Subsystem automatically creates an instance of each Blueprint class that you identified as a startup object. For each instance, it calls your custom implementation of the Run function.

For example, the Run function implemented in the preceding steps has two effects:

A line printed in the Output Log:

Click for full image.

A newly spawned cube in the center of the Level:

](07_NewCubInLevel.png)Click for full image.

Binding to Editor Events

One useful possibility for startup objects is to bind custom events in your Blueprint class to other events that may occur as a user works on your Project content in the Unreal Editor. Because the startup object is guaranteed to be invoked any time the Project content is opened by any user, this can help you to guarantee a consistent editing experience.

For example, this implementation of the Run function binds to an event triggered by the Import Subsystem any time the editor imports a new Asset. In this case, it prints the name of the Asset to the screen and the log. You could also use the information returned about the new Asset to carry out additional steps, like validating that the name or folder location of the new Asset matches the naming conventions and content conventions that you use in your Project. Putting this kind of check in a startup object helps guarantee that the same validation steps happen for all users that contribute content to your Project.

Click for full image.

Drag left from the Event input on the Bind Event to... node and choose Add Event > Add Custom Event to get a custom event node that exposes additional inputs, like the In Factory and In Created Object shown above.

Your startup object can only bind to other objects that exist at the time the editor starts up. In addition, the binding becomes lost if the bound object leaves memory—for example, if a Level is closed and reopened. For that reason, it's safest to bind to objects that will be available during the entire editing session, like the Subsystem shown in the example above.

For more about binding to Blueprint events, see Event Dispatchers and Binding and Unbinding Events. For more about Subsystems and how to access them, see Programming Subsystems.

What Can It Do

Getting Started

Reference

Unreal Editor offers a powerful set of tools for working with nearly every aspect of your Project's content. However, in some situations, using the Engine successfully as part of a larger content editing process requires making changes in the Project from outside the Editor UI. For example, broadcast TV and film productions need to offer operators easy and rapid control over a limited set of common capabilities, which they need to access through a custom UI that integrates with other software they use in the pipeline.

The Remote Control system makes this possible by running a web server inside the Unreal Engine that services WebSocket messages and HTTP requests made by remote web applications through a REST-like API.

In the right scenario, this offers several benefits:

You can create entirely new UIs that interact with Project content, focusing on the objects and properties that have meaning for your specific use case.

You can integrate these custom UIs with third-party applications you already use, or as a part of other web apps that you create for your organization.

You can operate the Engine remotely, from a different computer or mobile device that is connected to the same network as the computer running Unreal.

What Can It Do

The Remote Control API offers a similar level of control over the Unreal Editor and the Project Content to what you have when working in Blueprint and Python.

Your web application can call any function that is exposed to Blueprint and Python.

Your web application can read and write the values of any properties exposed to Blueprint and Python or a Remote Control Preset.

Without any coding, you can expose Project Content to the Remote Control API through a Remote Control Preset and connect them to widgets in a companion web application. See Remote Control Presets and Web Application for more details.

With some ingenuity and web development skill, you can use these relatively simple building blocks as a basis for constructing your own rich editing tools.

Remote Control is disabled by default in packaged projects or in -game to accomodate virtual production workflows. You can enable Remote Control by adding the following flags to the command line when launching the instance of the project.

Getting Started



Step-by-step instructions for getting started controlling the Unreal Editor remotely from a web page.

[DIR(output:"topic" parent:"setting-up-your-production-pipeline/scripting-and-automating-the-editor/RemoteControl"type: "tutorial")]

Reference



Details about the WebSocket endpoints offered by the Remote Control API for controlling the engine remotely.



Details about the HTTP endpoints offered by the Remote Control API for accessing properties and functions exposed in a Remote Control Preset.



Details about the HTTP endpoints offered by the Remote Control API.

Remote Control Quick Start

Remote Control API HTTP Reference

Remote Control Presets and Web Application

Remote Control Preset API HTTP Reference

WebSocket Messages

WebSocket Message Type - HTTP

WebSocket Message Type - Preset.Register

WebSocket Message Type - Preset.Unregister

Sample HTML/JavaScript File

This page describes the WebSocket message types offered by the Remote Control API. A sample HTML file with JavaScript functions is provided at the end of this page to show how to use and test these WebSocket messages.

By default, the WebSocket port in the engine is 30020. Connect to the WebSocket server at ws://127.0.0.1:30020 to start sending messages. You can change the WebSocket port for your project.

In the Editor's main menu, choose Edit > Edit Project Settings… to open the Project Settings window.

In the Project Settings window, select Remote Control in the Plugins section.

Change the field Remote Control WebSocket Server Port to the port that you want to use.



WebSocket Messages

The Remote Control API uses the JSON format for its WebSocket messages. All WebSocket messages sent to the server must be JSON objects with the following properties:

Property

Description

MessageName

Identifies the type of message to send. Options are:

HTTP

Preset.Register

Preset.Unregister

Parameters

Parameters for each message type. See the sections below for more details.

Id

Optional: A useful identifier for any deferred response from the server.

WebSocket Message Type - HTTP

Use this message type to call an HTTP route through a WebSocket message. See the Remote Control API HTTP Reference for more information on HTTP routes that can be called.

Example JSON message:

The WebSocket server sends back a JSON message with the response to the call:

WebSocket Message Type - Preset.Register

Use this message type to subscribe to events emitted by a Remote Control Preset. Example JSON message:

The following sections describe the events that are emitted by the preset and their JSON messages.

This message is sent any time someone modifies the value of a property exposed in the preset.

This message is sent any time a property is exposed to the preset. The response only includes the group to which the property was added.

This message is sent any time a property or function is removed from the preset.

This message is sent any time a property or function is renamed in the preset.

WebSocket Message Type - Preset.Unregister

Use this message type to unsubscribe from events emitted by a Remote Control Preset. Example JSON message:

Sample HTML/JavaScript File

Save the following code in a file named index.html.

Open the index.html file in your web browser. The page will say Connection Open if it was able to successfully connect to the WebSocket server.



Enter the name of a Remote Control Preset in the input field and change the preset's fields.

Open your browser's console log and verify that response messages were logged.

Remote Control Quick Start

Remote Control API HTTP Reference

Remote Control Presets and Web Application

Remote Control API WebSocket Reference

GET remote/presets

GET remote/preset/insert_preset_name

GET remote/preset/insert_preset_name/metadata

PUT remote/preset/insert_preset_name/metadata/insert_metadata_key

GET remote/preset/insert_preset_name/metadata/insert_metadata_key>

DELETE remote/preset/insert_preset_name/metadata/insert_metadata_key

GET remote/preset/insert_preset_name/property/insert_property_name

PUT remote/preset/insert_preset_name/property/insert_property_name

PUT remote/preset/insert_preset_name/function/insert_function_name

Example

This page describes the HTTP endpoints offered by the Remote Control API for Remote Control Presets and details the format of the message body you need to include when you call each endpoint.

The examples in this page are using the Blueprint Third-Person Template. To follow along with the examples, add a Remote Control Preset to the project, name it MyPreset, and expose the following properties and functions:

Directional Light's rotation property, renamed as Directional Light Rotation

Print Text function from the Kismet System Library, with Print to Log enabled



GET remote/presets

Use this endpoint to get the list of all available presets. The call returns a JSON payload with information on every Remote Control Preset in the project.

Example

Send the request with an empty request body. A successful request returns a 200 status and a response body with the following properties:

GET remote/preset/insert_preset_name

Use this endpoint to get details on specific presets in your project. In the URL, replace insert_preset_name with the name of a Remote Control Preset in your project. If the preset is found with the name specified, the call returns a JSON payload with information on the preset.

If a preset cannot be found with the specified name, the call returns a JSON payload with an error message:

Example

Sending the request GET http://localhost:30010/remote/preset/MyPreset with an empty request body returns a successful request with a 200 status and the following response body:

GET remote/preset/insert_preset_name/metadata

Use this endpoint to get all metadata associated with the preset. In the URL, replace insert_preset_name with the name of a Remote Control Preset in your project. The call returns a JSON payload with the metadata entries for that preset.

Example

Sending the request GET http://localhost:30010/remote/preset/MyPreset/metadata with an empty request body returns a successful request with a 200 status and the following response body:

Once you add Metadata entries with PUT remote/preset/insert_preset_name/metadata/insert_metadata_key, calling this endpoint will include those key-value pairs in this result.

PUT remote/preset/insert_preset_name/metadata/insert_metadata_key

Use this endpoint to create or update a metadata key-value pair for the preset. The metadata key can be any name but the request body must include the property "Value" in the JSON object; any other property will make the value an empty string. The call returns only the status of the request.

Example

Send the request PUT http://localhost:30010/remote/preset/MyPreset/metadata/MyKey with the following request body:

A successful request returns a 200 status. Verify the key-value pair was created by calling GET http://localhost:30010/remote/preset/MyPreset/metadata:

GET remote/preset/insert_preset_name/metadata/insert_metadata_key>

Use this endpoint to read the value associated with a metadata key. The call returns a JSON payload with the information requested.

Example

Send the request GET http://localhost:30010/remote/preset/MyPreset/metadata/MyKey with an empty request body. A successful request gives a 200 status with the following response body:

DELETE remote/preset/insert_preset_name/metadata/insert_metadata_key

Use this endpoint to remove a metadata key-value pair associated with the preset. The call returns only the status of the request.

Example

Sending the request DELETE http://localhost:30010/remote/preset/MyPreset/metadata/MyKey returns a successful request with a 200 status. Verify the key-value pair was deleted by calling GET http://localhost:30010/remote/preset/MyPreset/metadata:

GET remote/preset/insert_preset_name/property/insert_property_name

Use this endpoint to read a property exposed in the preset. The call returns a JSON payload with the requested information.

Example

Send the request GET http://localhost:30010/remote/preset/MyPreset/property/Directional Light Rotation with an empty request body.

A successful request returns a 200 status with the following response body:

PUT remote/preset/insert_preset_name/property/insert_property_name

Use this endpoint to update the value of a property exposed in the preset.

Example

Send the request PUT http://localhost:30010/remote/preset/MyPreset/property/Directional Rotation Light with the following request body:

A successful request returns a 200 status. Verify the change by looking at the property in the preset:



PUT remote/preset/insert_preset_name/function/insert_function_name

Use this endpoint to call a function exposed in the preset. The call returns a JSON payload with any return values from the function.

Example

Send the request PUT http://localhost:30010/remote/preset/MyPreset/function/Print Text (KismetSystemLibrary) with the following request body:

A successful request returns a 200 status with the following response body and "Hello, World" printed to the Output Log:

Remote Control Quick Start

Remote Control API HTTP Reference

Remote Control API WebSocket Reference

Remote Control Preset API HTTP Reference



With Remote Control Preset, collect and organize any UI parameters or functions in a single panel and expose them to the Remote Control API. These parameters and functions can be connected to widgets in a companion web application provided by the Remote Control Web Interface plugin to control the engine remotely. This web application has a built-in UI editor so you can customize its interface without any additional code to create or format it.

Since this is a web application, you can run multiple clients at the same time. Any properties that are modified in one client will have their changes propagated through the web server to all the other clients. This can help create a collaborative workflow in a live environment.







With Remote Control Protocols you can bind protocol input data to exposed properties, to control them through external devices.



Learn how to control the engine through the companion Remote Control Web Application and use its built-in UI editor to create your own UI without any additional code to create or format it.



This page outlines the interface elements and options contained within the Remote Control Panel.

Prerequisites

Exposing Properties to the Remote Control Panel and Remote Control API

Exposing Properties and Functions via Blueprint Library

Next Steps

With Remote Control Preset, you can collect and organize any UI parameters or functions in a single panel and expose them to the Remote Control API. These parameters and functions can be connected to widgets in a companion web application provided by the Remote Control Web Interface plugin to control the engine remotely.



This page covers how to expose properties and functions from the Unreal Editor to the Remote Control API. For more details on all the settings in the Remote Control Panel, refer to Remote Control Panel Reference.

Prerequisites

The Remote Control API plugin provides the web server that hosts the data and websocket connections for the Remote Control Preset.

Follow these steps to enable the plugin for your project.

Open your project in the Unreal Editor.

In the Editor's main menu, choose Edit > Plugins to open the Plugins window.

In the Plugins window, find the Remote Control API plugin in the Messaging category. Check its Enabled checkbox.



Restart the engine.

Exposing Properties to the Remote Control Panel and Remote Control API

The Remote Control Panel in the Unreal Editor is where you can collect properties from multiple objects in the level together for easy access. You can also add functions to the panel and call them from the panel. When properties and functions are exposed to the Remote Control Panel, they are also exposed to the Remote Control API. This helps an operator easily organize any items that they need to control in a live environment.

Follow these steps to add a Remote Control Preset and open the Remote Control Panel.

Press Add in the Content Drawer and navigate to the Miscellaneous section. Select Remote Control Preset.





Open the Remote Control Panel by double-clicking the Remote Control Preset Asset.



Check the Edit Mode checkbox.



In the Details panels for Assets, every property now has the settings menu for that property (three dots).



Left-click on the setting menu to see a closed or open eye icon.



The eye icon determines whether a property is added to the Remote Control Panel:

An open eye icon means the property is added to the Remote Control Panel.

A closed eye icon means the property is not added to the Remote Control Panel.

Clicking on an open eye icon closes it, and vice versa; the property is added or removed from the Remote Control Panel accordingly.

When the property is in the Remote Control Panel, it has the same interface as in the Details panel.



A Light Color property with RGB values in the Remote Control Panel (left) and in the Details panel (right).

Right-click on the Remote Control Preset and select Save to keep your changes.

Exposing Properties and Functions via Blueprint Library

This feature is experimental and may change in the next release.

You can use a Blueprint Library to expose properties, functions, and Actors to the Remote Control API and automate the process of populating a Remote Control Preset. Refer to Blueprint API for more details on how to expose these using Blueprints.

In the following example Blueprint, the function is set up to expose all trees of the class Light_BP.



Click image to expand.

When the function is run, the Remote Control Preset will show all the trees of the class Light_BP.



Click image to expand.

Next Steps

In this guide, you learned how to expose properties to the Remote Control API and create a Remote Control Preset. Refer to the following documentation for using these exposed properties in a live environment:

Remote Control Web Application

Remote Control Protocols

Remote Control Panel Interface

Menu

Exposed Properties

Remote Control Entity

Remote Control Protocols for DMX, MIDI, and OSC

DMX Protocol Mapping

MIDI Protocol Mapping

OSC Protocol Mapping

Protocol Ranges

Protocol Log

This page outlines the interface elements and options contained within the Remote Control Panel. You will learn how to organize the Remote Control Panel, connect external devices, and rename elements for simpler reference in the Remote Control API.

Remote Control Panel Interface



Click image to expand

Menu

Exposed Properties

Remote Control Entity

Remote Control Plugins for DMX, MIDI, and OSC

Protocol Log

Menu

The following table describes each element as it appears in the Menu, from left to right.



UI Element

Description

Create Group

Create multiple groups to organize similar properties and functions together.

Expose

Add other items to the panel where you want to expose functionality that is not merely a property. The following options are available to expose to the Remote Control API:

Blueprint Library Function

Subsystem Function

Actor Function

Actor

Actors by Class

Open Web App

Launches the [Remote Control Web Application]() in your browser.

Edit Mode

When enabled, you can expose properties from the Editor, add functions to the Preset, and modify the groups and positions of the properties and functions.

Enable Log

Shows the Protocol Log. See the Protocol Log section for more details.

Remote Control Preset Name

Displays the name of the Remote Control Preset Asset that's currently open.

Exposed Properties

The following table describes each element as it appears for each exposed property, from left to right.



Action

Description

Expand

(Optional) Shows additional information for the data value, if it exists.

Move

Rearrange properties, functions, and groups by dragging and dropping the elements in the panel.

Rename

Change the names of the properties, functions, or groups to make their references clearer and simpler in function calls.

Data Values

Matches the data format for the property in the Editor.

Reset

Return the property's value back to its default value.

Remove

Remove the property or function from the Panel and make it no longer exposed to the Remote Control API.

Remote Control Entity

This section appears when you select an exposed property. The following table describes the Metadata that you can associate with each property. Some of the properties might have more fields depending on their data format.



Metadata

Description

Label

The unique label for the property that matches the label in the Remote Control Preset. This can be used in the Remote Control API to access an exposed property.

ID

The engine's unique identifier for the property. This can be used in the Remote Control API to access an exposed property.

FieldName

The name of the associated field.

Widget

The default widget type to use for this property in the Remote Control Web Application.

Description

This field overrides the label that is displayed in the Remote Control Web Application.

Remote Control Protocols for DMX, MIDI, and OSC

In the Remote Control Panel, you can map exposed properties to an external device through DMX, MIDI, and OSC. The table below describes the UI for adding and viewing Protocol Mappings.



UI Element

Description

Protocol Mapping Option

Options include:

DMX

MIDI

OSC

Add Protocol

Creates a new Protocol Mapping for the currently selected option in the Protocol Mapping Option dropdown.

Viewing Options

Filter which protocol mappings you want to view.

Each Protocol Mapping also has its own Mapping and Ranges sections to define which external device and input to connect to. The sections below explain the differences between mappings for Protocol types, and the functionality of ranges shared between the Protocol types.

Use the autobinding button to capture the latest input for the current protocol and apply it to the mapping. This provides a convenient and faster alternative to specifying the properties manually.

For example, in either an existing or newly created MIDI binding, you can toggle autobinding, press a note on the device, and the mapping properties will be populated accordingly. To complete the autobinding and stop recording to any new input, toggle the autobinding button again so that it's no longer red.

The following are the available states for autobinding:

Grey: Not listening for input

Red: Listening for input

Green: With a bound input



DMX Protocol Mapping

The following table describes the options for connecting to a specific input on an external device with the DMX Protocol.



Field

Description

Universe

DMX Universe Mapping

Use LSB

When enabled, uses the least significant bit to swap the byte order, if the order is not standard when using 16-bit DMX values. Typically, the most significant bit is used.

Data Type

Specifies the precision and max value of the incoming data. Input will be clamped to the bounds of this type. Available types are:

8 bit

16 bit

24 bit

32 bit

Currently, the 24 bit option is stored internally and represented as a 32-bit integer.

Starting Channel

The first channel of DMX to which you are binding the property. Currently, only one channel is allowed to be bound to a parameter.

MIDI Protocol Mapping

The following table describes the options for connecting to a specific input on an external device with the MIDI Protocol.



Field

Description

Event Type

Specifies the type of Input Event. The default type is Control Change. The following are the available types:

Note Off

Note On

Note After Touch

Control Change

Program Change

Channel After Touch

Pitch Blend

Mapped Channel ID

Specifies which device to connect to using the MIDI device input identifier.

Channel

Input MIDI channel. Expected range of values are 0-16.

Device

Selects which device to map. Default is to use what's set in Project Settings. You can also override the device per protocol binding by setting the device by its Name or ID.

To specify the MIDI device in the Project Settings:

In the Editor, go to the main menu and select Project Settings to open the Project Settings window.

In the Project Settings window, navigate to Plugins > Remote Control MIDI Protocol.

Select the device by its Name or ID. The dropdown next to either field shows a list of available devices, or you can specify your device if it isn't currently connected.



If you plug a device in while the Editor is open, you can refresh the device list by clicking the Refresh button.



OSC Protocol Mapping

The following table describes the options for connecting to a specific input on an external device with the OSC Protocol.



Field

Description

Path Name

Specify the server address and path for the OSC device.

By default, the server is 127.0.0.1:8001. You can change or add more options in Project Settings:

In the Editor, go to the main menu and select Project Settings to open the Project Settings window.

In the Project Settings window, navigate to Plugins > Remote Control OSC Protocol.

Add a new Server Settings array element or modify an existing one, and set its Server Address to match your device.



Protocol Ranges

This section displays the ranges mapped to the external device. By default, a new protocol mapping adds two range inputs, corresponding to the predicted min and max values.

You can add more range steps by selecting the plus button to the right of the ranges section. If you enter different values for the range points, the property value will interpolate between the input points, like keyframes in animation.

The following table describes how to set property values for the ranges.



UI Element

Description

Input Range Point

The input point with which you can associate a specific property value.

Data Values

Sets the value of the property for that range point. The data format matches the associated property's type.

Use Current Property Value

Captures the current value of the property in the level.

Remove Input

Removes the range point.

A warning icon appears when you have more than one mapping for the same input on an external device.

Protocol Log

When Enable Log is checked in the Remote Control Panel's Menu, this section will show incoming data for the selected Protocol. In the example below, an OSC device with the name /1/fader4 is sending float values to the engine.



Prerequisites

Mapping Protocols in Remote Control

Adding a New Protocol

With Remote Control Protocols you can bind protocol input data to exposed properties, to control them using external devices. This page describes how to use the Remote Control plugins for the DMX, MIDI, and OSC plugins, and how to create your own Protocol plugin.

Prerequisites

Enable the Remote Control API plugin.

Enable the Remote Control plugin specific to the protocol you're using:

For DMX, enable the Remote Control Protocol DMX plugin.

For MIDI, enable the Remote Control Protocol MIDI plugin.

For OSC, enable the Remote Control Protocol OSC plugin.

Restart the editor.

Once you enable these plugins, create a Remote Control Preset Asset and expose properties to the Preset. Refer to Getting Started with Remote Control Presets for more details.

Mapping Protocols in Remote Control

Follow these steps to be able to control properties from your external device.

In the Remote Control Panel, select the property you want to map to a Protocol.



Select the Protocol from the dropdown list and press the plus button next to it to add a new mapping.



Modify the settings in the mapping section to connect to your external device. Refer to the Remote Control Panel Reference for more details on the fields.

You can quickly autobind an input by using the autobinding button located in the top right of the mapping panel. Refer to the Remote Control Panel Reference for more details.

In the Ranges section, add more range steps by selecting the plus button on the right. Enter different values in the range points to make the property interpolate between them when controlling from the external device.

Press the left-facing arrow next to a range value to capture its current value in the world.

Verify your mapping and inputs are set up correctly by using your external device and seeing the changes in the object's Details panel or the viewport.

Adding a New Protocol

To add your own protocol support to Remote Control, you need to implement IRemoteControlProtocol and FRemoteControlProtocolEntity.

Follow these steps to add your own implementation for a Remote Control Protocol.

Create a new blank plugin. See Creating a New Plugin for instructions.

The recommended naming convention is RemoteControlProtocol{Name}, where {Name} is the name of your protocol. For example the MIDI implementation is called RemoteControlProtocolMIDI.

Within the created *.uplugin file, add a dependency to the RemoteControl plugin:

In Visual Studio's Solution Explorer for your project, find the module, defined in a .Build.cs file. Append RemoteControl and RemoteControlProtocol to the PrivateDependencyModuleNames range.

Create a new class that implements IRemoteControlProtocol, or inherit from the base implementation FRemoteControlProtocol, with overrides for:

GetProtocolScriptStruct(): Provide the class of your Protocol Entity implementation. For the example with MIDI, it's FRemoteControlProtocolMIDIEntity::StaticStruct().

Bind(Entity): This is typically used to register the entity with a local collection to iterate over whenever input is received. The provided entity will be specific to your implementation which is described below.

Unbind(Entity): Similar to Bind, this is typically used to remove the provided entity from a collection.

UnbindAll(): Removes all entities from the collection.

Create a new struct that represents the protocol binding for a given entity (the exposed property) by inheriting from the FRemoteControlProtocolEntity struct, with overrides for:

GetRangePropertyName(): For example FFloatProperty if the input from the device is a float.

A transient, non-visible, and non-editable UPROPERTY() called RangeInputTemplate: You can specify additional constraints such as min and max values. This is used to create the appropriate editor widget. You can optionally store the property elsewhere and specify it by overriding IRemoteControlProtocol::GetRangeTemplateType().

Register your IRemoteControlProtocol implementation with:

For further examples, including how to create and register project settings, see the implementations for DMX, MIDI, and OSC Remote Control Protocol Plugins in the UE source code.

Prerequisites

Getting Started with the Remote Control Web Application

Presets

Tabs

Level Snapshots Integration

Sequencer Integration

Widgets

Properties

Widget and Property Settings

Widget Modes

Deleting Widgets

Parameters and functions exposed in the Remote Control Preset can be connected to widgets in a companion web application provided by the Remote Control Web Interface plugin to control the engine remotely. This web application has a built-in UI editor so you can customize its interface without any additional code to create or format it.



Since this is a web application, you can run multiple clients at the same time. Any properties that are modified in one client will have their changes propagated through the web server to all the other clients. This can help create a collaborative workflow in a live environment.

This page covers how to connect exposed properties and functions to widgets in the companion Remote Control web application, and build your own UI with the application's UI builder.

Prerequisites

The Remote Control Web Interface uses NodeJS to provide a companion web app with default widgets, such as gauges, sliders, and color pickers, for controlling the engine remotely without any additional code.

Follow these steps to connect the web application to your project:

Install NodeJS on your machine.

Minimum version: 8.

Maximum version: 14.15.5.

Open your project in the Unreal Editor.

In the Editor's main menu, choose Edit > Plugins to open the Plugins window.

In the Plugins window, find the Remote Control Web Interface plugin in the Messaging category. Check its Enabled checkbox.



Restart the engine.

Verify the web app launched successfully. In the Editor's main menu, choose Window > Developer Tools > Output Log and filter by "remote control web" to see a success log similar to: LogRemoteControlWebInterface:

[Success] Remote Control Web Interface is running - WebApp started, port: 7000



Getting Started with the Remote Control Web Application

Connect properties and functions in the Remote Control Panel to a web application. The web application will read any Remote Control Preset that you have open in your Unreal session. The following browsers are officially supported: Chrome, Firefox, and Safari.

To see updates in the Editor as you change property values in the web app, open Edit > Editor Preferences and, in the Performance section under General, disable Use Less CPU when in Background.



Follow these steps to launch the web application and add an exposed property:

Open your web browser on the same machine running the engine and enter the URL 127.0.0.1:7000. See the Remote Control Quick Start for details on how to expose the Remote Control API to other machines.



You can change which port the Remote Control Web Interface uses for your project. In the Editor's main menu, choose Edit > Project Settings… to open the Project Settings window. In the Project Settings window, select Remote Control in the Plugins section to see its settings, where you can change the default port.



You can also launch the web application from the Remote Control Preset. See Remote Control Panel Reference for more details.

When the page loads, you should see a blank Remote Control application. Click the Control toggle in the web application to switch to Design mode so you can start adding widgets.





Select the Properties tab.



Drag and drop one of the exposed properties into the right panel. When you add a property from the Properties panel, a Panel Widget is created if one doesn't currently exist, and the associated widget for the property is added to the Panel Widget.

In the following example, a Panel Widget was created and a Color Picker Widget added to the Panel Widget. The Color Picker is bound to the Contrast field for the scene's PostProcessVolume.



Switch to Control mode.



Modify the exposed property in the web app and verify the associated property is updated in the Editor.



Save your changes to the web application by saving the corresponding Remote Control Preset in the Unreal Editor. The next time you open the web application, the layout will be the same as when you last saved the Asset.

Presets

You can have multiple remote presets available in the web application, but you can only have one Remote Control Preset open at a time. In Design mode, go to the Presets section to see the available remote presets on the left side of the window and select the one you want to view. The name of the currently opened Remote Control Preset is displayed in the top right of the window.



Tabs

You can have multiple Tabs in your web application. This is helpful for creating different views for the operators in a live environment.

You can change a Tab's label and choose an icon from a library of icons to differentiate the Tabs.

You can also duplicate a Tab to use as a starting point for a new interface.



There are two unique tabs you can add to your web application that are already set up to work with other Unreal tools: Level Snapshots and Sequencer. The sections below describe these integrations with Remote Control.

Level Snapshots Integration

In the Remote Control Web Application, you can take new snapshots of the level or switch to a previously taken snapshot remotely. For more details on using Level Snapshots in your project, see Level Snapshots.



The Level Snapshots plugin must be enabled to use this feature in the Remote Control Web Application.

Sequencer Integration

In the Remote Control Web Application, you can view all the sequences in your project, filter them by name, and select a sequence to view. For more details on using sequences in your project, see [Sequencer](). By clicking the Play button icon to the right of a sequence, you can start or resume a sequence in the current level. There may be a short delay before the sequence begins to play.

Sequences in the page will be listed by their asset name and not the name listed in the outliner. Assets renamed after being placed in the world will still be listed by their name in the content browser.



This tab shows all sequences in the project, but you can only play the sequences that exist in the current level. The filter is only based on the asset path, so you currently cannot filter based on which sequences are in the level.

Widgets

Widgets are included in the web application to represent interactable data formats in the engine, and to provide formatting for the web page.



The following list shows all of the available widgets you can add to your UI:

Button

Color Picker

Dial

Dropdown

Joystick

Label

List

MiniColorPicker

Panel

Slider

Spacer

Tabs

Text

Toggle

Vector

A Panel widget is used to contain all the other widgets and must be placed before placing other widgets. A List widget is used to contain Panels and provide multiple UIs in the same Tab.



Properties

The properties and groups listed in the Properties tab of the Remote Control Web Application directly match the properties and groups in the Remote Control Preset.



Drag and drop a property from the left tray of the web application over the canvas area, to add a widget already bound to the property in your UI. If the property is released over a panel, it will automatically be added to it. If there are no panels it will create an empty one for you and wrap it inside.



Widget and Property Settings

When you select a widget in the web page during Design mode, a settings panel appears in the bottom left corner of the window. Different fields appear depending on the type of widget and data it represents.

For every widget type, you can change its label. If the widget is bound to a property, you can change which property it's connected to.

Widget Modes

Some data formats, such as vectors, can be represented in multiple ways in the UI.

Follow these steps to change the mode for your widget.

Select the widget you want to view to open its settings panel.

In the widget's settings panel, select the mode you want to use. For example, with vectors, you can choose a Joystick, Dial, or Sliders.



A game controller icon appears next to the property when you select a mode. Select this button to open the property in the mode you selected.



The mode appears at the bottom of the window.



Deleting Widgets

You can delete widgets individually, or delete all the widgets in a Panel at the same time. To delete a widget, select the widget to open its settings panel and select Delete Widget. To delete all the widgets in the Panel, select the Panel to open its settings panel and select Delete Widget.



Remote Control API HTTP Reference

Remote Control Presets and Web Application

Remote Control Preset API HTTP Reference

Remote Control API WebSocket Reference

1 - Set up the Project

2 - Manage the Server

3 - Send Requests

4 - On Your Own

The instructions on this page provide a step-by-step guide to getting started with the Remote Control API. By the end of this tutorial, you'll know how to set up a Project to listen to incoming requests from web applications, and you'll be ready to start making your own requests.

Prerequisites:

The Remote Control API server listens for incoming HTTP requests on port 30010. If this port is not available, you can change the Remote Control HTTP Server Port in the Web Remote Control section of Project Settings.

You'll need a basic level of knowledge about how to make requests bearing JSON payloads from a web client to an HTTP server endpoint.

The steps on this page use a Project set up from the Blueprint Third-Person Template. Substantially the same steps will work in any Project. However, if your Project doesn't use the same sky setup as the Template, the specific object paths and requests in step 3 - Send Requests may not work.

Do not attempt to open the hostname and port of your Unreal Engine application to the open Internet. Doing so may make your Project and your computer vulnerable to malicious actions from third parties.

Expect to use the Web Remote Control system only within your Local Area Network (LAN) or over a secure Virtual Private Network (VPN).

1 - Set up the Project

Before you can start making Web Remote Control requests, you'll need to install the Remote Control Plugin.

Steps

Open the Project that you want to use with Web Remote Control in the Unreal Editor.

From the main menu, choose Edit > Plugins to open the Plugins window.

In the Plugins window, find the Remote Control API plugin in the Messaging category. Check its Enabled checkbox.



Click Yes to accept the warning that this Plugin is in Beta status.

Click Restart Now to restart the Unreal Editor and reopen your Project.



End Result

Once your Project has re-opened in the Unreal Editor, you'll be ready to start the Web Remote Control server.

2 - Manage the Server

The Web Remote Control system relies on a web server launched and managed by the Unreal Editor process. For your security, this server only runs when you explicitly activate it. To control when the server runs, you use a few simple console commands:

Command

Description

WebControl.StartServer

Starts the web server and begins listening for incoming requests on port 30010.

WebControl.StopServer

Stops the web server, preventing any more requests to your Unreal Editor instance from being handled.

WebControl.EnableServerOnStartup

Starts the web server automatically whenever this Project is opened in the Unreal Engine in any supported mode: in the main Unreal Editor window, in a Play In Editor (PIE) session, or in the -game mode of the Unreal Editor.

For now, we'll simply start up the server in the main Editor window.

Steps

From the main menu, choose Window > Developer Tools > Output Log.

In the Cmd bar, enter the console command WebControl.StartServer.



You'll see a message that indicates that the server is now running:



End Result

Now that you have the server running, you can begin feeding it with requests.

3 - Send Requests

We suggest starting with the simplest possible use case for making your initial requests.

Use a tool dedicated to testing API requests and responses, such as Insomnia or Postman. This makes it easier to be certain that you're constructing the JSON payload for your requests correctly. Once you are comfortable with how the Web Remote Control endpoints work, and the kinds of responses they give, then move on to incorporating calls to those endpoints into your own web applications.

Start by making your first requests locally on the same computer that you have running your Project in the Editor. Once you know you have that working, then move on to making requests from clients on other computers or devices connected to your local network.

Steps

In your web client app, set up a request with the following body:

This request asks for the current value of the RelativeRotation property on the Level's main directional light: the Actor with the name Light Source in the World Outliner.

Send the message as a PUT request to the following endpoint:

You should see a response in your web client that contains the status code and information you requested:

If you select the Light Source Actor and look in the Details panel, you'll see that the values in the response match the values displayed there:



This illustrates how the Web Remote Control system is capable of breaking down objects — in this case, a Vector — into JSON values to exchange them with your web application.

Next, we'll change the light's rotation remotely.

This property is defined in the Engine source code as BlueprintReadOnly:

That means we'll need to call a BlueprintCallable function exposed by the same object to modify it. You can find this definition in the Engine/Source/Runtime/Engine/Classes/Components/SceneComponent.h file:

Set up a request with the following body:

Send the message as a PUT request to the following endpoint:

You should see that the angle of the directional light in your Level has now changed, putting the objects in the scene into shadow.



If you go back and make the same request you made in step 2 above at this point, you'll now receive the updated values that you just set.

We'll call one more function remotely to update the sky so that it takes the new angle of the sun into account. In this case, we will call a function that is defined in Blueprint within the BP_Sky_Sphere class:

Click for full image.

This function has the same effect as checking the Refresh Material box in the Details panel for the SkySphereBlueprint Actor.

Send this message to the same endpoint as above:

In this case, the function doesn't require any input parameters, so we can omit the parameters property entirely.

You'll see the sky change to night in your Level:



End Result

Following the steps above, you've seen how to get information about the content in a running Unreal Engine Project from a web client. You've also seen how to change the Project content remotely, by issuing requests from the web client to execute functions exposed by objects in the Editor environment: in this case, changing the sky.

Lighting and sky changed by remote control



4 - On Your Own

The same two endpoints you used in the simple procedure above are capable of deep and far-reaching changes in your Project's content. There is a lot more to know about using them, so see the Endpoint Reference for more details and examples.

The web server's address is set to 127.0.0.1 by default, which is only accessible to the computer running the Unreal Engine session. To allow other devices to access your Unreal session through the Remote Control API, change the DefaultBindAddress in your project's DefaultEngine.ini file to your machine's IP address.

Workflow

API

With the Remote Control C++ API, you can access different parts of the Remote Control Plugin. You can build custom integration and Remote Control adapters with Unreal Engine, and use custom transports to access the Remote Control entities.

This page introduces the Remote Control C++ API, with links to the Unreal Engine C++ API Reference for further details.

Workflow

Set up a server in your Unreal Engine Project to send and receive data between Unreal Engine and your C++ application. For example, you can use FUdpSocketBuilder and FIPv4Endpoint.

Create an external C++ application to send and receive data from the server in your Unreal Engine project.

Create a parser and manager in your Unreal Engine Project to process received data and call Remote Control functions.

API

The following classes make up the core functionality of the Remote Control C++ API:

IRemoteControlModule: Access functionality available at the Module scope, such as getting and resolving Remote Control Presets.

URemoteControlPreset: Includes access to:

Targets that contain exposed functions, properties, and Actors.

Getters that use unique IDs and labels for exposed entities such as property, function, and Actor so you can access the entity from Editor, Game Mode, Simulation, and Package.

A listener for property changes.

Delegates when an entity is exposed or unexposed.

FRemoteControlEntity: Access to exposed objects, properties, functions, and Actors, and their metadata

FRemoteControlProperty: Represents a property exposed to Remote Control, and includes access to FProperty and RemoteControlPropertyHandle for getting and setting values of the exposed property

FRemoteControlFunction: Access to the UFunction pointer and function argument so you can invoke the function on a specific object using UObject->ProcessEvent(UFunction*, ArgumentsMemory)

FRemoteControlActor: Access to the pointer for an exposed Actor.

IRemoteControlPropertyHandle: Access to getters and setters to modify the values of exposed properties, and access child properties for complex types.

You can get and set the value for a simple property type directly. Simple property types include int, float, double, string, vector, and rotator.

You cannot get and set a property value directly for complex types such as TArray, TMap, TSet, and Structs. Instead, you must access a child property handle, and if the child property is a simple property type you can get and set its value.

DisplayClusterRemoteControlInterceptor: Use this to set any property values replicable through nDisplay.

Remote Control Quick Start

Remote Control API WebSocket Reference

Remote Control Presets and Web Application

Remote Control Preset API HTTP Reference

GET remote/info

PUT remote/object/call

PUT remote/object/property

PUT remote/object/thumbnail

PUT remote/search/assets

PUT remote/object/describe

PUT remote/batch

PUT remote/object/event

About UObject Paths

This page describes the HTTP endpoints offered by the Remote Control API, and details the format of the message body you need to include when you call each endpoint.

GET remote/info

Use this endpoint to see all the HTTP routes available in the Remote Control API. The call returns a JSON payload with all the available HTTP routes and their descriptions.

Example

Send the request with an empty request body. A successful request returns a 200 status with the following response body:

PUT remote/object/call

Use this endpoint to call a function exposed by a specified UObject that is currently in memory in the Editor: typically an Actor in the current Level or an Asset in your Project.

You can call any function that is callable from Blueprint. This includes any function defined in C++ with the BlueprintCallable specifier, or any function that is defined and implemented entirely in Blueprint.

When you call this endpoint, you must pass a JSON payload with the following properties:

Property

Description

objectPath

The path that uniquely identifies the UObject you want to interact with. For more information on finding this path, see About UObject Paths below.

functionName

The name of the function you want to call from the specified UObject. If your function is defined in C++, its original name may not match the display name shown in Blueprint. In this case, use the function name defined in C++.

parameters

An object that defines the parameters you want to pass to the function.

The name of each property in this object should be the name of a parameter accepted by the function you call.

If your function is defined in C++, the original parameter name may not match the value you see in the Blueprint Editor. In this case, use the paramter name defined in C++. For example, in the code below, the second parameter needs to be specified as bSweep to match its C++ definition, although it is exposed in the equivalent Blueprint node as Sweep.

The value of the property may be any simple value such as a number or a Boolean value. Or, if the function requires you to pass an object, you can provide a JSON object that encapsulates the properties of that object. The Remote Control system will use the values you provide to attempt to create a new object of the necessary type. For example, in the code below, the NewLocation is automatically used to create a new Vector.

You don't have to include a property in this object for every parameter the function accepts. For any parameter that you omit, the Web Remote Control system will construct a default object of the appropriate type.

generateTransaction

Defines whether or not the Editor should record this function call in the Project's transaction history. Setting this property to true has the following effects:

Any changes made by the function will be undoable. The Editor records an entry in the Project's Undo History panel for this function call. A user working in the Unreal Editor can then roll back the effect of the change. This entry is always under the name Remote Call Transaction Wrap, regardless of the function you call:

If you're in a Multi-User Editing session, the change will be replicated to other connected users.

The call returns a JSON payload that contains the return value of the function called, along with any other output parameters specified in the function's definition.

Example

Request body:

A successful request gives a 200 status with the following response body:

In this case, the SweepHitResult is included in the return value because the original definition of the SetActorLocation() function in the Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.h file defines it as an output parameter: that is, a non-const reference to a data value that is produced by the function call.

PUT remote/object/property

Use this endpoint to access property values exposed by a specified UObject currently in memory in the Editor: typically an Actor or an Asset.

If the UObject you are accessing is an instance of a C++ class, this includes any class members defined in C++ as properties that are accessible to Blueprint, subject to the restrictions below.

If the UObject you are accessing is an instance of a Blueprint class, this includes any Blueprint variables owned by that class, subject to the restrictions below.

This endpoint can only access properties that meet certain criteria:

The property must be defined as public. It may not be private or protected.

It must not have any BlueprintGetter or BlueprintSetter functions defined. If it does, you must use those functions with the remote/object/call endpoint described above instead of trying to read or write the values directly using the remote/object/property endpoint.

If you are accessing the object in the Editor, the property must be set as EditAnywhere. In order to modify the value, the property must not be set as EditConst.

If you are accessing an object in -game mode or Play In Editor (PIE) mode, the property must be set as BlueprintVisible. In order to modify the value, the property must not be set as BlueprintReadOnly.

Depending on the way you construct your request message, you can:

Request all available properties exposed by the object, along with their current values.

Request the value of any property that offers at least read access.

Set the value of any properties that offer write access.

When you call this endpoint, you must pass a JSON payload with the following properties:

Property

Description

objectPath

The path that uniquely identifies the UObject you want to interact with. For more information on finding this path, see About UObject Paths below.

property

The name of the property you want to read or modify. If you omit this property in a call with READ_ACCESS, the response will list all readable properties available on the specified UObject.

access

Defines the kind of access request you are making for the property. This can be any of the following values:

READ_ACCESS specifies that you are making a request for the current value of a property, or for all properties on the specified UObject.

WRITE_ACCESS specifies that you want to set a new value for one or more properties, which you define in the propertyValue object.

WRITE_TRANSACTION_ACCESS is the same as WRITE_ACCESS, but records the property value change in the Project's transaction history. This is similar to the generateTransaction property of the remote/object/call endpoint. It has the following effects:

The Editor handles the property modification exactly as if it had been done in the Details panel of the Unreal Editor. This may invoke additional code inside the Editor to handle pre-change and post-change events linked to that property.

If you're in a Multi-User Editing session, the change will be replicated to other connected users.

This option makes the change undoable. If you set this property to true, the Editor records an entry in the Project's Undo History panel for this property change. A user working in the Unreal Editor can then roll back the effect of the change. This entry is always under the name Remote Set Object Property:

propertyValue

When you make a request with WRITE_ACCESS or WRITE_TRANSACTION_ACCESS, you use this object to specify the properties you want to modify, and the new value you want to set for each of those properties.

This must be a JSON object in which the name of each field matches the name of a writeable property on the specified UObject, and the value of each field is the new value that you want to set for that property.

The call returns a JSON payload that contains the information you requested, or the result of your write request.

Examples

Request body:

A successful request gives a 200 status with the following response body:

Request body:

A successful request gives a 200 status with the following response body:

Request body:

A successful request gives a 200 status with an empty response body.

PUT remote/object/thumbnail

Use this endpoint to retrieve the thumbnail image of an Asset in the Content Browser. The call returns a JSON payload that contains the thumbnail.

Example

Request body:

A successful request returns a 200 status with the thumbnail image in the response body:



PUT remote/search/assets

Use this endpoint to search for an Asset in the Asset Registry.

When you call this endpoint, you must pass a JSON payload with the following properties:

Property

Description

Query

The text you want to match in an asset's name. Leaving this field an empty string returns all results.

Filter

A JSON object to specify how you want to filter the requested assets with the following optional properties:

PackageNames: Restricts the search to exact matches of the specified packages. The format of the value is an array of strings, such as ["/Game/MyFolder/MyAsset"].

ClassNames: Restricts the search to exact matches of the specified class names. The format of the value is an array of strings.

PackagePaths: Restricts the search to any packages that contain the specified paths. For example, ["/Game/MyFolder"] will only return assets with "/Game/MyFolder" in their asset path. The format of the value is an array of strings.

RecursiveClassesExclusionSet: When searching for matching classes recursively, you can specify any classes you want to exclude from the results. The format of the value is an array of strings.

RecursivePaths: A boolean specifying whether to search subfolders of the paths specified in PackagePaths.

RecursiveClasses: A boolean specifying whether to look at subclasses of classes specified in ClassNames.

The call returns a JSON payload that contains the information you requested.

Example

Request body:

A successful request returns a 200 status with the following response body:

PUT remote/object/describe

Use this endpoint to see all the properties, functions, and other metadata about a UObject currently in memory in the Editor, such as an Actor or an Asset. The call returns a JSON payload that contains the information you requested.

Example

Request body:

A successful request returns a 200 status with the following response body:

PUT remote/batch

Use this endpoint to group multiple HTTP requests into a single remote call. The order of execution is determined by the order of the elements in the Requests array.

Each request element in the Requests array must be a JSON object with the following properties:

Request Property

Description

RequestId

A unique ID to be able to match the request with the corresponding response.

URL

The request target, such as /remote/object/describe.

Verb

Options for the HTTP method are PUT, POST, GET, and DELETE.

Body

The data that is sent to the server. Not at all requests have a body.

The call returns a JSON payload that contains an array of responses for the multiple requests. Each element in the array has the following properties:

Response Property

Description

RequestId

A unique ID to match the response to the corresponding request.

ResponseCode

The status code of the response. A successful response returns the status 200.

ResponseBody

Payload containing any requested data. Not all responses have a response body.

Example

Request body:

A successful request returns the following response body with an array of responses for each request:

PUT remote/object/event

This route is experimental. Enable it by adding the following console variable to your project's DefaultEngine.ini file.

Use this endpoint to receive the object's next event, such as receiving an update when an object's property changes. The route will not return until the event has occurred.

The following events are currently supported:

ObjectPropertyChanged

PreObjectPropertyChanged

Example

Request body:

A successful request will not return until the event has occurred. When the StaticMesh property changes, a response with a 200 status will be returned with the following body:

About UObject Paths

Every Asset and Actor that the Unreal Editor has loaded in memory has a path that uniquely identifies it. These paths are mostly for internal use within the Editor, so they aren't directly exposed to you in a way that's easy to access. And, because they're determined programmatically according to internal rules, they aren't always easy to predict.

In general, these object paths follow the format:

Programmers who work with the Engine in C++ may recognize this format as the same one accepted by functions like FindObject() and StaticFindObject().

For example, to deconstruct an Actor path shown in the request examples above:

/Game/ThirdPersonBP/Maps/

The path to the Asset in the Content Browser.

ThirdPersonExampleMap.ThirdPersonExampleMap:

The name of the package and the object it contains (for many Assets, these will be the same).

PersistentLevel.CubeMesh_5.StaticMeshComponent0

The path through a hierarchy of sub-objects to the object you want to affect.

Although these paths are not easily exposed to view, the following sections describe some ways you can get at them.

Paths in the Undo History

When you modify a UObject, you can view its path in the Undo History panel.

Click the filter icon at the bottom right of the panel and enable Show transactions details.



Make a minor change to the Asset or Actor you want to access, such as moving an Actor to a new location. This will record a new transaction in the Undo History.

In the Transaction Details panel, hover over the entries in the Modified objects and properties column. The Tooltip contains the path to the highlighted object.



Paths in the Editor Scripting Utilities

Depending on the types of tasks you want to carry out remotely, it may be helpful for your web application to be aware of the paths for the Actors available in the current Level, or for Assets that exist in the Content Browser. The Editor Scripting Utilities Plugin exposes some helpful functions for interacting with Assets and Levels that you can use to achieve this.

For example, to get a list of the paths for all Actors in the current Level, you can remotely call the GetAllLevelActors function exposed by the EditorLevelLibrary class in the EditorScriptingUtilities module. Send the following request body to the remote/object/call endpoint:

The ReturnValue field in the response body gives you an array of paths for all Actors in the Level. For example:

For details on installing the Editor Scripting Utilities Plugin, see Scripting and Automating the Editor.

During Play in Editor (PIE) mode, UEDPIE_X_ is added as a prefix to the Map's name, where X is the PIE instance ID. Using the first returned value above as an example, the object path during PIE would be:

Paths for Blueprint Function Libraries

To remotely call custom Blueprint Function Libraries with static methods, the object path must point to the Class Default Object (CDO), which is the one object that a UCLASS maintains. The following sections explain how to build the object path for C++ and Python objects.

The object path to a CDO in C++ follows the format:

The table below describes how to find the values for ModuleName and ClassName for your Blueprint Function Library.

ModuleName

ModuleName is the name of the DLL that contains the class you are looking for. In your Visual Studio project, there is a .build.cs file with the same name as the module, which specifies how that module should be built as well as the module's dependencies.

ClassName

ClassName is the name of the class, which has a UCLASS macro.

The object path to a CDO in Python follows the format:

ClassName is the name of the class, which has a @unreal.uclass() decorator.

Why Python?

Set Up Your Project to Use Python

Python 3.9.7

Ways to Run Python Code in Unreal Editor

The Python Console in the Output Log

The py Console Command

The File Menu

The Command Line

The init_unreal.py File

Startup Scripts

From Editor-only Blueprints

Python Environment and Paths in the Unreal Editor

About the Unreal Editor Python API

API Reference

Best Practices for Using the Python API

Working with Assets

Changing Editor Properties

Use Unreal Types Whenever Possible

Logging and Feedback

Supporting Undo and Redo

Progress Dialogs for Slow Operations

This page describes how to get started using Python in the Unreal Editor.

Why Python?

In recent years, Python has become the de facto language for production pipelines and interoperability between 3D applications, particularly in the media and entertainment industry. This is partially due to the wide range of applications that support it. As the complexity of production pipelines continues to soar, and the number of applications involved continues to grow, having a common scripting language makes it easier to create and maintain large-scale asset management systems.

Even without these outside considerations, or the need to work with other applications, Python is a great choice if you're looking to automate your workflows within the Unreal Editor. It's relatively easy for those new to programming to get started, it offers the ability to create complex and full-featured user interfaces through modules like PySide, and there are many other useful free modules available to the community to make your life easier.

You can use Python in the Unreal Editor to do things like:

Construct larger-scale asset management pipelines or workflows that tie the Unreal Editor to other 3D applications that you use in your organization.

Automate time-consuming Asset management tasks in the Unreal Editor, like generating Levels of Detail (LODs) for Static Meshes.

Procedurally lay out content in a Level.

Control the Unreal Editor from UIs that you create yourself in Python.

Set Up Your Project to Use Python

Python support in the Unreal Editor is provided by the Python Editor Script Plugin. You'll need to enable this plugin for your current Project before you can run Python scripts in the Editor.

Currently, you must enable the plugin separately for each Project.

To enable the plugin:

Open your Project, and choose Edit > Plugins from the main menu.

In the Plugins window, go to the Scripting section.Find the Python Editor Script Plugin in the right-hand panel, and check its Enabled box. You'll also want to enable the Editor Scripting Utilities plugin, which offers simplified APIs for many common Editor tasks. For details, see Scripting and Automating the Editor.

Restart the Editor.

Python 3.9.7

The Python Editor Script Plugin contains an embedded version of Python 3.9.7.

This means that you don't have to install Python separately on your computer.

Unreal uses Python 3.9.7 by default because it is an important part of the current VFX Reference Platform. To use a different version of Python, you can set the UE_PYTHON_DIR environment variable in your operating system to point to the installation you want to embed, then rebuild the Unreal Engine from source.

Ways to Run Python Code in Unreal Editor

There are several different ways that you can run Python scripts in the Unreal Editor, each designed for a slightly different usage scenario. You can choose whichever fits your needs.

Unlike Blueprints, the Python environment is only available in the Unreal Editor, not when your Project is running in the Unreal Engine in any mode, including Play In Editor, Standalone Game, cooked executable, etc. That means that you can use Python freely for scripting and automating the Editor or building asset production pipelines, but you cannot currently use it as a gameplay scripting language.

The Python Console in the Output Log

You can switch the Unreal Editor's console input bar to accept Python code instead of Unreal console commands.



You can do this in the Output Log panel, as shown above, or when you bring up the console input bar by pressing the ~ key.

When the console is in Python mode:

You can enter lines of Python code into this console and have the Editor execute each one immediately, exactly as if you were using an interactive Python console in a command window. This is the only way to execute Python code line-by-line; all other approaches listed below run a script file that you specify.

You can run multiple lines of code at a time by using Shift+Enter to separate each line, or by pasting in a multi-line block that you copy from a text editor.

You can execute Python script files by simply typing the file name into the console. If your Python script requires additional command-line arguments, include them after the name of your script.

Output from the built-in Python print function is also redirected to the Output Log panel.

The py Console Command

In the normal console, you can use the py command to run the rest of the line as Python code, exactly as if you had typed it into the Python console described above.

For example, this command runs the specified script file:



We don't recommend running this command in the value of the ExecCmd command-line parameter when you start the Editor. This can cause your script to run before the Editor environment is ready — for example, before the startup Level is fully loaded. See the sections below for better options.

The File Menu

The File menu in the main window of the Unreal Editor offers new options that you can use to run Python script files.

Use Execute Python Script if you want to browse to a new script file on your computer that you haven't run before.

Use the Recent Python scripts list to re-run any script that you ran previously. The file is read from disk again, so you changed the script in the meantime, your new version is run.



The Command Line

If you start the Unreal Editor from the command line or from a script, you can specify a Python script file in the command line arguments. If your Python script requires additional command-line arguments, include them after the name of your script.

There are two different ways to run a Python script from the command line. In both approaches, the Editor shuts down immediately after running your Python script.

Option 1: Full Editor

In this approach, the full Unreal Editor launches, opens your specified Project, loads the default startup level, then runs your Python script once everything is loaded and ready. This approach is good if you need your script to interact with content in your Project or in a Level that can take some time to load.

Add the ExecutePythonScript argument to the command line, and set its value to the path and filename of the Python script you want to run. For example:

The approach above requires that you enable the Editor Scripting Utilities plugin for your Project.

You must have already enabled the Python Scripting Plugin in the Unreal Engine Project that you specify on the command line.

Option 2: Commandlet

This approach is very fast to execute, and can even run your scripts in headless mode without opening the Editor UI, but it can be trickier to load Levels and other kinds of Assets that your script needs to interact with.

Add the following arguments to the command line: -run=pythonscript -script=<script_file_or_code>, where <script_file_or_code> takes either of the following values:

The path and filename of a Python script that you want to run.

Python statements and commands that you want to run. If needed, you can use \n in the string to escape line breaks.

For example:

or:

You must have already enabled the Python Scripting Plugin in the Unreal Engine Project that you specify on the command line.

The init_unreal.py File

If the Editor detects a script file called init_unreal.py in any of the paths it is configured to use (see "Python Paths in the Unreal Editor" below), it automatically runs that script immediately.

This is a good approach for situations where you are working on a Project or a Plugin and you know that everyone working with that content needs to run the same initialization code every time the Editor starts up. You could put your initialization code inside a script with this name, and put it into the Content/Python folder within that Project or Plugin.

Startup Scripts

In your Project Settings, you can specify any number of Python scripts that you want to run every time you open that Project. The Editor runs these scripts after the default startup Level is fully loaded.

Select Edit > Project Settings.... Under the Plugins list, select Python. Then, add your scripts to the Startup scripts setting:



Restart the Unreal Editor when done. The next time the Editor loads your Project, it should run your new startup scripts.

From Editor-only Blueprints

The Python Script Plugin exposes new nodes to Blueprint Visual Scripting that you can use to run Python code snippets or files during the evaluation of a Blueprint graph.

Python execution nodes are only available in Editor-only Blueprint classes, such as Editor Utility Widgets and Editor Utility Blueprints. Refer to Scripting the Editor using Blueprints. You can't use this method in any Blueprint classes that are available at runtime, such as a class that you derive directly from Actor.

You'll find the following nodes in the Python > Execution section of the Blueprint palette.



Execute Python Script

Executes the literal Python code that you pass in to or type in the Python Command input. It is the recommended way to call Python from Blueprints, and superscedes creating a new BlueprintFunctionLibrary(BPFL) type in Python.

The aformentioned BPFL method causes issues when an asset is saved or loaded due to Python-generated types being transient, and is no longer officially supported.

Execute Python Script can have can have custom input and output pins, which are available as variables within the Python script on the node and can be added by the properties of the node.

-Inputs are set prior to running the Python script on the node, and can be read in the script. -Outputs are read after running the Python script on the node, and can be set in the script.

Execute Python Script can contain multiple lines of Python code, and new-lines can be entered by using the keys Shift+Return.

The Success? output is true if the Python code was executed successfully, or false otherwise. If it is false, you can find the errors in the Output Log.

This node cannot run files. It can only execute lines of Python code.



Execute Python Command

Executes the literal Python code or file that you pass in to or type in the Python Script input. The node will attempt to determine based on your input whether it is literal code or a filename.

-The Return Value output is true if the Python code or file was executed successfully, or false otherwise. If it is false, you can find the errors in the Output Log.



Execute Python Command (Advanced)

Executes the literal Python code or file that you pass in to or type in the Python Script input. This node is similar to Execute Python Command, but offers some additional inputs and outputs that may be useful in some scenarios.

Execution Mode indicates how you want to interpret the Python Script input.

Select Execute File to force the command to treat your input as the name of a file, and to attempt to find and run that file. Any values returned by this script are printed to the log.

Select Execute Script to force the command to treat your input as literal Python code, and to execute it as-is. Any values returned by this script are printed to the log.

Select Evaluate Script to force the command to treat your input as literal Python code, evaluate it as-is, and return any values produced by the script in the Command Result output.

If you pass a filename to the Python Script input, the File Execution Scope determines whether that file is executed in the global scope (Public) or in a sandboxed scope (Private). If you want the code in your file to be able to access variables, functions, and so on that have already been defined in the Python environment, then you will need to choose Public. However, doing so also gives the Python file the ability to redefine variables and functions. This may accidentally cause unexpected behavior. Therefore, it may be safer to use the Private scope.

The Command Result output depends on the Execution Mode. When the Python Script input is executed or evaluated successfully, and the Execution Mode is Evaluate Script, this output returns the value produced by the script. When the Python Script input is executed or evaluated successfully, and the Execution Mode is either Execute File or Execute Script, this output returns None. When the Python Script input is not executed or evaluated successfully, this output contains the error information.

The Log Output provides access to the full list of messages written to the Python log during the execution of the input script or file. You can iterate through this array if you need to look for specific messages written by the script.

The Return Value output is true if the Python code was executed successfully, or false otherwise. If it is false, you can find the errors in the engine's Output Log, in the Log Output output pin, and in the Command Result.

Python Environment and Paths in the Unreal Editor

When you use a relative path to run a Python script, or to import another script module using the import command in one of your scripts, the script that you run or import can be in any path that is listed in the sys.path variable of your Python environment.

The Unreal Editor automatically adds several paths to this sys.path list:

The Content/Python sub-folder in your Project's folder.

The Content/Python sub-folder in the main Unreal Engine installation.

The Content/Python sub-folder in each enabled Plugin's folder.

The Documents/UnrealEngine/Python folder inside your user directory. For example, on Windows 10, this is equivalent to C:/Users/Username/Documents/UnrealEngine/Python

You can also add your own paths to this list using any of the following approaches:

In your Project Settings. Select Edit > Project Settings.... Under the Plugins list, select Python. Then, add the paths to the Additional Paths setting. Restart the Unreal Editor when done.

Add the paths to the value of the UE_PYTHONPATH (or PYTHONPATH if you disabled the Editor isolated interpreter environment option) environment variable in your operating system, then restart the Unreal Editor.

Add the paths directly to the sys.path list within a Python script, or in the Python console.

For more information, refer to the Python sys.path documentation

By default, Unreal Engine's embedded Python interpreter runs in isolated mode. You can disable isolated mode by selecting Edit > Project Settings > Plugins > Python > Isolate Interpreter Environment

For more information, refer to see the Python command line -I option documentation



The UE_PYTHONPATH environment variable is always parsed by the engine and its content is added to sys.path, regardless of the isolation mode options you select. UE_PYTHONPATH serves the same purpose as the PYTHONPATH variable, but it should never be modified by any third-party software.

About the Unreal Editor Python API

The Python Editor Script Plugin exposes a wide range of classes and functions that you can use to interact with the Unreal Editor, the Assets in your Project, and the content in your Levels. This API is all contained in the unreal module. To access it, import this module at the beginning of any Python script you run in the Editor's Python environment:

The unreal module exposes nearly everything that is exposed from C++ to Blueprints in your Editor environment. It's not pre-generated; it automatically reflects whatever is available in Blueprints in your Editor. As you enable new plugins in the Unreal Editor, anything those plugins expose to Blueprints also becomes available in Python as well. The same goes for any C++ code that you write in your Project and expose to Blueprints.

The Python API makes every effort to expose native Unreal APIs in a way that is as friendly as possible to Python developers. For example:

Simple data types are transparently converted back and forth between Python and native types whenever necessary.When you pass in a Python list, set or dict, it is automatically converted to an Unreal array, set, or map. When you retrieve a list, set, or dict returned by an API function, you are actually getting an instance of an Unreal class, but its API is fully consistent with the base Python list, set, or dict type.

Python classes maintain the same inheritance hierarchy as the native types they represent. That means, for example, that you can use the built-in Python functions isinstance() and type() to test whether an object derives from or matches a given class.

The API tries to strike a good balance between the naming conventions used in Unreal for C++ and Blueprints on one hand, and Python naming conventions on the other hand. Classes and objects in the Python API have the same names as they do in Blueprints. This is typically the same as their native types, omitting the prefix (e.g. U or T). Function and property names are automatically exposed as lower-case snake_case. So, for example, you typically call functions like unreal.StaticMeshActor.get_actor_transform(). Enumeration value names are automatically exposed as upper-case SNAKE_CASE.

All exposed functions can accept either ordered parameters, or named parameters in any order. For example, the following two function calls are exactly equivalent:

API Reference

For details on all of the classes and functions exposed by the Unreal Python API, see the API Reference here:

Unreal Editor Python API Reference

The API Reference is not an exhaustive list of everything that may be exposed to Python by plugins. If you've installed additional plugins that aren't included in the API Reference, and you need to see the way their scripting features are exposed to Python, you can generate your own local version of the API Reference that contains docs for the plugins you need. For instructions, see the readme file under Engine\Plugins\Experimental\PythonScriptPlugin\SphinxDocs in your Unreal Engine installation folder.

Best Practices for Using the Python API

This section covers a few things that it's important to keep in mind when you use the Python API.

Working with Assets

If you need to work with Assets in your Project, always use functions from the Unreal Python API to do it. Never use file management modules built in to Python to work directly with your Asset files on disk. For example, if you need to move an Asset to a different folder, do not use Python functions like os.rename or shutil.move. Unreal Projects and Assets contain internal content references that you can break if you do not respect this rule.

Instead, we recommend using the unreal.EditorAssetLibrary API that is provided by the Editor Scripting Utilities plugin, or the unreal.AssetTools class built in to the Unreal Python API.

Changing Editor Properties

You can use Python to get access to Objects in your Project and set up many configuration properties on those Objects programmatically. For example, your Python script could access Static Mesh Actors in the current Level, and set properties like whether the Actors can be damaged, or whether they should be hidden in the game. Or, you could retrieve their Static Mesh Components and set up properties on those Components, like their Lightmass settings, or even the Static Mesh Asset that they are linked to.

These properties may be exposed to Python in two different ways:

Items with the BlueprintReadOnly or BlueprintReadWrite flag are exposed as simple properties on the object.You can read and modify these properties like you access any Python object property.

Items with the ViewAnywhere or EditAnywhere flag are exposed as "editor properties".You can read and write these values using a special pair of functions exposed by every object: set_editor_property() and get_editor_property().

In the API Reference for each class, you'll find a list of Editor Properties immediately following the class description. These are all the values that you can set and get using these set_editor_property() and get_editor_property() functions. Whenever you need to set or get a configuration property on an object, check this list first to see if the property you want is listed there.

When you need to read a value that is exposed both as an object property and as an editor property, the result of accessing the property directly is usually the same as by calling the get_editor_property() function. However, the get_editor_property() function often has access to properties that aren't exposed directly on the Python object.

When you need to set a value that is exposed both as an object property and as an editor property, you should in most cases use the set_editor_property() function to set the value rather than set the value directly on the object. When you adjust properties in the UI, the Editor often performs additional operations behind the scenes: pre- and post-edit changes. These operations typically respond to the choices you make in some way, and keep the Editor UI in sync with the state of the object in the game world. If you modify these properties directly on the Python object, this Editor code won't be run automatically. On the other hand, when you call set_editor_property() to set the state of a property, you do trigger this pre- and post-edit code, exactly as if you changed the setting in the Details panel of the Editor UI.

For example, Media Player objects have a Play on Open setting:



This is exposed in the unreal.MediaPlayer class in the play_on_open class member:

Use Unreal Types Whenever Possible

Whenever you need utilities that are available in the Unreal Python API, like classes for math operations or manipulating 3D coordinates, we recommend using the Unreal utilities rather than using your own implementations. The Unreal versions are optimized for best performance in the Engine environment.

For example, when you need to manipulate coordinates in 3D space, use the unreal.Vector class:

Logging and Feedback

The unreal object exposes functions that you can use in your code to send log, warning, and error messages through the same messaging system used by all Engine and Editor subsystems. We recommend using this standardized logging framework anytime your script needs to send a message to the user.

Use unreal.log() for information messages. For your convenience, the Python print() function has also been implemented to pass through unreal.log() internally.

Use unreal.log_warning() to alert users of potential problems.

Use unreal.log_error() for severe problems that prevent your script from running as expected.

Your messages appear in the Output Log panel, along with the messages sent by other subsystems:



Supporting Undo and Redo

Your scripts can take full advantage of the Undo / Redo system built in to the Unreal Editor.

Each transaction that you define can contain any number of Python operations. Using these transactions, you can bundle large operations, or operations on many different objects, together into a single entry in the Undo / Redo history. Typically, if your script intends to perform a certain change on multiple objects, you don't want a separate entry in the Undo / Redo history for each change; you want one entry that will undo all changes to all objects.

To define a transaction, use the unreal.ScopedEditorTransaction scope. For example, if you run this code:

import unreal

Your Editor's Undo History panel now lists that transaction by name:



As a general rule, your scoped transactions can contain any operations that are also undoable in the Editor UI. However, not every Editor operation is undoable. For example, you can't undo importing a model in the Editor UI, so trying to import a model inside an unreal.ScopedEditorTransaction will not work as you may be expecting.

Progress Dialogs for Slow Operations

If your scripts need to work on many Assets or Actors in the same operation, they may take some time to complete. However, while the Unreal Editor is running a Python script, its UI becomes blocked to other user interactions. To give the user information about the progress of a large task, and avoid the Editor appearing to freeze or hang, you can use the unreal.ScopedSlowTask scope.

For example:



Prerequisite: Enable Developer Mode

PyCharm

VSCode

Type Hinting

Prerequisite: Enable Developer Mode

Before setting up autocomplete, you will need to tell the Unreal Engine (UE) Python Plugin to generate the necessary stubs. You can do this by checking Developer Mode in Editor Preferences > Plugins > Python, then restarting the editor. The generated stub file will be located at PROJECT_DIRECTORY/Intermediate/PythonStub.

PyCharm

Open the Settings window and navigate to Project > Python Interpreter, then click the gear and select Show all. In the Python Interpreter window, you can click the Paths button and click + to add the location of your stub file.



You will also need to raise the maximum Intellisense file size by navigating to Help > Edit Custom Properties and adding the following:

After restarting PyCharm, you will be able to see functions from the UE API in the autocomplete menu.

VSCode

Navigate to Settings > Extension > Python and find Auto Complete: Extra Paths. Click the link to open the settings.json file, and add the path to your stub file under python.autoComplete.extraPaths.





After restarting Visual Studio Code (VSCode), you should now be able to see functions from the UE API in the autocomplete menu.

Type Hinting

The Python plugin can now generate the stub with type hinting (for more information on type hinting, see PEP 484). Type hints appear in your Python IDE auto-completion menu. Type hints can be configured by first clicking on Edit > Editor Preferences in the Unreal Editor Menu Bar. This will open the Editor Preferences tab. Now navigate to Plugins > Python to see the available Python Script Plugin user settings. To use Type Hinting, Developer Mode must be enabled. Below is a table with the available Type Hinting Modes and descriptions.

Type Hinting Mode

Description

Auto-Completion

Hints the exact parameters and return type or types of a method.

Type Checker

Adds up all possible type coercions. For example, it will hint that you can pass a Python string in place of an unreal.Name. This makes the auto-completion menu busy and harder to read, though this option will work better if you turn on type checking in your IDE.

Off

Turns off type hinting altogether.

By default, the Type Hinting Mode is set to Auto-Completion.

Note that hinting is not perfect. In some cases, types are not known when generating the stub. In other cases, the C++ reflection API does not provide enough information to accurately hint when a parameter or the return value of a method can be None.

The stub file is regenerated each time the editor is started. As a result, you can restart the editor after exposing new functions to Python or enabling new plugins to ensure the stub file is up to date.

Creating New Levels of Detail

Reusing a LOD from Another Static Mesh

Creating Levels of Detail (LODs) for your meshes can be a good way to increase the performance and frame rate of your game without sacrificing visual quality.

In general, the more triangles your meshes have, and the smaller those triangles are on screen, the harder it is for your GPU to render them. Trying to render too many detailed meshes all at the same time can slow down your frame rate. However, you typically don't need every mesh in the scene to be rendered with the same fidelity: when a mesh is far away, you are often able to swap it out for a less-detailed version of the mesh that contains fewer triangles without a noticeable difference in visual quality.

Unreal Engine 5 offers a built-in LOD management system that automatically chooses the most appropriate version of a mesh to show at runtime, based on the amount of screen space the mesh is currently occupying in each frame. This system relies on you setting up these different alternative versions of your meshes in the Editor ahead of time.

The Editor can generate these Levels of Detail for your Static Mesh assets automatically, by progressively simplifying the mesh to thresholds that you specify. For more information about how this system works and how to set it up in the Static Mesh Editor, see Automatic LOD Generation.



Click image for full size.

However, even though the Editor can generate these LODs automatically, it may not be feasible for you to open every Static Mesh Asset in your project one-by-one in order to set them all up. You could bulk edit the Assets, but this doesn't help if you want to apply different settings to different Static Mesh Assets based on their characteristics. For example, you might want to apply different reduction settings based on the number of existing triangles in the mesh, or based on an Asset naming convention. It also doesn't help if you want to create your LODs as a sub-step within a larger custom Asset pipeline that you've scripted. For these kinds of cases, you can use Blueprints or Python to script the automatic LOD creation system.

Prerequisite: If you haven't already done so, you'll need to install the Editor Scripting Utilities Plugin. For details, see Scripting and Automating the Editor.

Creating New Levels of Detail

Choose your implementation method:

Blueprints

Python

You'll find the nodes you'll need to manage LODs under the Editor Scripting > Static Mesh category.

To use these nodes, your Blueprint class must be derived from an Editor-only class, such as the PlacedEditorUtilityBase class. For details, see Scripting the Editor using Blueprints.

The key node is Set Lods, which automatically creates levels of detail for the Static Mesh Asset you pass in. To use this node, you'll need to provide it with a set of reduction settings that define the screen size threshold and relative triangle percentage for each level of detail you want to create. See the example below.

The first EditorScriptingMeshReductionSettings item that you pass to the Reduction Settings input of the EditorScriptingMeshReductionOptions node has no effect. LOD 0 always contains all triangles in the mesh.

You can use Get Lod Count and Get Lod Screen Sizes to get information about the Levels of Detail that are currently set up for a Static Mesh.

You can also use Remove Lods to remove all existing LODs (except LOD 0, which always contains all triangles in the mesh).

Setting up LODs modifies the Static Mesh Asset. Assuming you want to keep the changes you make, you'll also need to use a node like Save Asset or Save Loaded Asset afterward.

The following example loads each Static Mesh Asset in an input path in turn. Whenever it finds one that has more vertices than a minimum threshold, it sets up three additional LODs for the Static Mesh, and saves it afterward.



Click image for full size.

You'll find the LOD management functions in the unreal.EditorStaticMeshLibrary class.

The key function is unreal.EditorStaticMeshLibrary.set_lods(), which automatically creates levels of detail for the Static Mesh Asset you pass in. To use this function, you'll need to pass in an EditorScriptingMeshReductionOptions object, which contains a set of EditorScriptingMeshReductionSettings that define the screen size threshold and relative triangle percentage for each level of detail you want to create. See the example below.

The first EditorScriptingMeshReductionSettings item that you set in the EditorScriptingMeshReductionOptions.reduction_settings array has no effect. LOD 0 always contains all triangles in the mesh.

You can use unreal.EditorStaticMeshLibrary.get_lod_count() and unreal.EditorStaticMeshLibrary.get_lod_screen_sizes to get information about the Levels of Detail that are currently set up for a Static Mesh.

You can also use unreal.EditorStaticMeshLibrary.remove_lods() to remove all existing LODs (except LOD 0, which always contains all triangles in the mesh).

Setting up LODs modifies the Static Mesh Asset. Assuming you want to keep the changes you make, you'll also need to use a function like unreal.EditorAssetLibrary.save_asset() or unreal.EditorAssetLibrary.save_loaded_asset() afterward.

The following example loads each Static Mesh Asset in an input path in turn. Whenever it finds one that has more vertices than a minimum threshold, it sets up three additional LODs for the Static Mesh, and saves it afterward.

An alternative approach is to set the LOD Group option for each Static Mesh Asset. This option makes the mesh use one of the pre-set LOD reduction settings that are defined in the [StaticMeshLODSettings] section of your project's BaseEngine.ini file, such as LevelArchitecture, SmallProp, LargeProp, or HighDetail.

For example:

For more information about how this system works and how to use it in the Editor, see Automatic LOD Generation.

Reusing a LOD from Another Static Mesh

As an alternative to generating LODs for a Static Mesh automatically using the process outlined above, you can take a LOD that already exists in a Static Mesh (called the source Static Mesh), and reuse it as a LOD for another Static Mesh (called the destination Static Mesh).

Choose your implementation method:

Blueprints

Python

To reuse an existing LOD in a Blueprint script, use the Editor Scripting > Static Mesh > Set Lod From Static Mesh node.



Click image for full size.

This node needs the following input:

A reference to the target. It requires Static Mesh Editor Subsystem Object.

A reference to the destination Static Mesh. This is the Static Mesh that you want to create a new LOD for. You'll need to load this Asset first, using the Editor Scripting > Asset > Load Asset node.

The index of the LOD that you want to create for the destination Static Mesh.

If the destination Static Mesh already has an LOD with the same index, it will be overwritten.

A reference to the source Static Mesh. This is the Static Mesh that has an existing LOD that you want to point to from the destination Static Mesh. As above, you'll need to load this Asset first, using the Editor Scripting > Asset > Load Asset node.

The index of the LOD within the source Static Mesh that you want to use for the destination Static Mesh.

A Boolean parameter that determines whether you want to try to merge Material slots in the source LOD with slots that already exist in the destination Static Mesh. If you enable this setting, then the function looks for any section in the source geometry that is assigned the same Material as a section in the destination mesh. If it finds any, it will try to remap the section in the LOD to match the existing section in the destination Static Mesh. This could save some memory in cases where both Static Meshes use the same Materials. If you leave this setting disabled, then all mesh sections from the source LOD are appended to the destination Static Mesh.

Setting the LOD modifies the destination Static Mesh Asset. Assuming you want to keep the changes you make, you'll also need to use a node like Save Asset or Save Loaded Asset afterward.

For example, the following script takes a specified LOD from a source Static Mesh, and reuses that geometry in a destination Static Mesh at a different specified LOD index:



Click image for full size.

When the Set Lod from Static Mesh node runs, a copy of the LOD from the source Static Mesh is added into the destination Static Mesh. There is no ongoing connection between the Static Mesh Assets, so any changes you make to the source Static Mesh from this point on will not automatically affect the destination Static Mesh.

To reuse a LOD in a Python script, call the unreal.EditorStaticMeshLibrary.set_lod_from_static_mesh() function. You need to pass this function:

The destination Static Mesh. This is the Static Mesh that you want to create a new LOD for. You'll need to load this Asset first, using the unreal.EditorAssetLibrary.load_asset() function.

The index of the LOD that you want to create for the destination Static Mesh. This value must be greater than 0. You cannot replace LOD 0 in the destination Static Mesh.

If the destination Static Mesh already has an LOD with the same index, it will be overwritten.

The source Static Mesh. This is the Static Mesh that has an existing LOD that you want to point to from the destination Static Mesh. As above, you'll need to load this Asset first, using the unreal.EditorAssetLibrary.load_asset() function.

The index of the LOD within the source Static Mesh that you want to use for the destination Static Mesh.

A Boolean parameter that determines whether you want to try to merge Material slots in the destination Static Mesh. If you set this parameter to True, then the function looks for any section in the source geometry that is assigned the same Material as a section in the destination mesh. If it finds any, it will try to remap the section in the LOD to match the existing section in the destination Static Mesh. If you set this parameter to False, then all mesh sections from the source LOD are appended to the destination Static Mesh.

Setting up this LOD modifies the Static Mesh Asset. Assuming you want to keep the changes you make, you'll also need to use a function like unreal.EditorAssetLibrary.save_asset() or unreal.EditorAssetLibrary.save_loaded_asset() afterward.

For example, the following script takes LOD 0 from a simplified source Static Mesh, and reuses that geometry as LOD 1 in a more complex destination Static Mesh:

When the unreal.EditorStaticMeshLibrary.set_lod_from_static_mesh() function runs, a copy of the LOD from the source Static Mesh is added into the destination Static Mesh. There is no ongoing connection between the Static Mesh Assets, so any changes you make to the source Static Mesh from this point on will not automatically affect the destination Static Mesh.

Adding Simplified Collision Shapes

Auto-Generating Convex Collisions

Removing All Simple Collisions

Using an LOD for Collisions

In order to make a Static Mesh part of the physics simulation in a Level, you have to set it up with a Collision Mesh. This represents the bounds of the Static Mesh object within the physics simulation. The physics system uses this Collision Mesh whenever it needs to check whether other physical objects collide with your mesh, and whenever you conduct a high-performance raycast to test for collisions against your mesh. You could use the visible geometry of the Static Mesh as its Collision Mesh, but the visible geometry is typically far too detailed. Physical interactions do not usually need this high level of accuracy in order to provide realistic results. Therefore, you can improve the performance of the physics system by making your Collision Meshes as simple as possible.

You can create simplified collision representations for your Static Meshes automatically in the Static Mesh Editor:



Click image for full size.

For details, see Setting Up Collisions With Static Meshes.

In some cases, you may need to create these Collision Mesh representations programmatically, instead of doing it by hand in the Static Mesh Editor. For example, if you need to set up a large number of Static Mesh objects in the same Project, it may not be feasible to open each one in turn. Or, you may want to carry out the collision setup as one step in a larger automated pipeline for importing and managing content.

The following sections illustrate how you can use Blueprints and Python to apply the different types of Collision Meshes shown above to your Static Mesh Assets automatically in the Unreal Editor.

You can't yet use Blueprint or Python to import another Static Mesh and use it as a custom Collision Mesh. To do this, you have to either:

Use the Static Mesh Editor user interface to import the Collision Mesh from a supported file format.

Import the Collision Mesh at the same time as the visible Static Mesh, using a special naming convention to indicate that it represents the geometry you want to use for collision testing. For details, see FBX Static Mesh Pipeline, or Datasmith Overview.

Choose your implementation method:

Blueprints

Python

You'll find the nodes you'll need to manage Static Mesh collisions under the Editor Scripting > Static Mesh category.

To use these nodes, your Blueprint class must be derived from an Editor-only class, such as the PlacedEditorUtilityBase class. For details, see Scripting the Editor using Blueprints.

Setting up collisions modifies the Static Mesh Asset. Assuming you want to keep the changes you make, you'll also need to use a node like Save Asset or Save Loaded Asset afterward.

You'll find most of the functions you'll need to manage Static Mesh collisions in the unreal.EditorStaticMeshLibrary class.

Setting up LODs modifies the Static Mesh Asset. Assuming you want to keep the changes you make, you'll also need to use a function like unreal.EditorAssetLibrary.save_asset() or unreal.EditorAssetLibrary.save_loaded_asset() afterward.

Adding Simplified Collision Shapes

To add a new simplified collision shape to a Static Mesh, use the Add Simple Collisions node (you need to add Static Mesh Editor Subsystem as a target for this node to work). Use the Shape Type input to control what kind of collision shape you want to add. These options match the ones available in the Collision menu of the Static Mesh Editor:



Click image for full size.

To add a new simplified collision shape to a Static Mesh, use the unreal.EditorStaticMeshLibrary.add_simple_collisions() function. Pass it:

The unreal.StaticMesh object you want to modify.

An item from the unreal.ScriptingCollisionShapeType enumeration that indicates what type of collision primitive you want to create. These options match the ones available in the Collision menu of the Static Mesh Editor.

For example:

Note that this adds a new collision shape to whatever other simplified collision shapes already existed for the Static Mesh, if any. If you want to remove the existing collision shapes first, see Removing All Simple Collisions below.



Click image for full size.

Auto-Generating Convex Collisions

To auto-generate a convex collision shape for a Static Mesh from its visible geometry, use the Set Convex Decomposition Collisions node (you need to add Static Mesh Editor Subsystem as a target for this node to work).



Click image for full size.

The inputs in this node exactly match the options you are asked to supply when you choose Collisions > Auto Convex Collisions in the Static Mesh Editor user interface. They control the complexity and fidelity of the generated Collision Meshes. In general, larger values lead to Collision Meshes that are closer to the visible geometry of the Static Mesh, but more expensive to simulate at runtime.

To auto-generate a convex collision shape for a Static Mesh from its visible geometry, use the unreal.EditorStaticMeshLibrary.set_convex_decomposition_collisions() function. Pass it:

The unreal.StaticMesh object you want to modify.

Three integers that define the maximum hull count, maximum number of vertices per hull, and hull precision. These parameters exactly match the options you are asked to supply when you choose Collisions > Auto Convex Collisions in the Static Mesh Editor user interface. They control the complexity and fidelity of the generated collision meshes. In general, larger values lead to collision meshes that are closer to the visible geometry of the Static Mesh, but more expensive to simulate at runtime.

For example:

All existing Collision Meshes are automatically removed from the Static Mesh before the new mesh is generated.

Note that this method tends to produce less predictable and regular results than using a simplified collision primitive. It's best used on irregular meshes, or when you can tune the generation settings visually in order to make sure that the results you generate are simple enough and a good match for the visible geometry of your Static Mesh.



Click image for full size.

Removing All Simple Collisions

You can clear all the Collision Meshes assigned to your Static Mesh using the Remove Collisions node (you need to add Static Mesh Editor Subsystem as a target for this node to work).



Click image for full size.

After this, the mesh will not be found by any "simple" physics collision tests, but will still be found by "detailed" tests that consider the visible geometry of the Static Mesh. See also Simple vs Complex Collision.

You can clear all the Collision Meshes assigned to your Static Mesh using the unreal.EditorStaticMeshLibrary.remove_collisions() function.

For example:

After this, the mesh will not be found by any "simple" physics collision tests, but will still be found by "detailed" tests that consider the visible geometry of the Static Mesh. See also Simple vs Complex Collision.

Using an LOD for Collisions

If you have already set up Levels of Detail (LODs) for your Static Mesh, you can use one of the less-detailed LODs as the Collision Mesh.

Call the set_editor_property() function on the unreal.StaticMesh object to set the lod_for_collision property to the index of the LOD you want to use. For example:

See also How To Set LOD Collision.

You can't yet set up a custom Collision Mesh via Blueprint or Python. To import a custom mesh and use it for a Static Mesh's Collision Mesh in the physics simulation, you have to either:

Use the Static Mesh Editor user interface to import the Collision Mesh from a supported file format.

Import the Collision Mesh at the same time as the visible Static Mesh, using a special naming convention to indicate that it represents the geometry you want to use for collision testing. For details, see FBX Static Mesh Pipeline.

Source Control Software

Unreal Engine comes with two fully-integrated methods that allow people to work together on their projects using version control software like Perforce and SVN.

Version control allows users on your team to share assets and code with one another, as well as providing a backup and history of changes so any files can be rolled back to an earlier version if something went wrong with the file.

Source Control Software



How to use Source Control software inside UE.



Save and restore specific layouts of your Level's Actors using Level Snapshots



How to setup Perforce so that you can share assets with other on your team.



How to setup SVN so that you can share assets with other on your team.



Content Browser

Redirectors

Project Settings

Configuration Files

Collaboration Workflow inside of Unreal Editor

Checking Out Files in Unreal Editor

Submitting to Source Control

Syncing Files

Adding Files

Deleting Files

Level Files

Config (.ini) Files

No matter which Source Control software you end up using, the manner in which you interface with that software from inside of UE is the same. The following guide will detail everything you need to know about using Source Control inside of UE.

Collaboration Workflow inside of Unreal Editor

Unreal Engine makes it very easy for multiple user collaboration on projects. In the following section, we will be going over how all of the various collaboration tools work inside of the Unreal Editor.

Checking Out Files in Unreal Editor

The main way to share content with collaborators is via the Content Browser. All source control operations are accessible via the context menu for files and folders. For instance, to Check Out a file (i.e. lock it for editing), Right-click on the asset in the Content Browser and then select the Check Out option.



You can set the editor to automatically check out files on save by enabling Prompt for Checkout on Asset Modification. You can find these options by going to Editor Preferences -> Loading & Saving -> Source Control.



You can also set the Unreal Editor to automatically add new files to Source Control when they are first saved inside of the Editor. You can find these options by going to Editor Preferences -> Loading & Saving -> Source Control. To do this, all you have to do is enable the Add New Files when Modified option which is on by default. When you start editing an asset, you will be presented with a notification in the bottom-right hand corner of the screen asking you whether you want to check the file(s) out:



This allows you to check out assets in advance of editing them. If you click the Check-Out link, then you will be presented with this dialog:



Number

Property Name

Description

1:

Check Out Selected

Checks out the files that are checked in the list.

2:

Make Writable

Clears the read-only flag (if one exists) allowing local edits to a file.

3:

Ask Me Later

Allows you to carry on working and check files out at a later time.

When you Right-click on an object in the Content Browser and then go under the Source Control option, you will see various symbols that show the current state of the assets.

Icon

Description



Checks out the files that are checked in the list.



Marked for addition to source control.



A newer version of a file exists in source control.



File is not under source control.



Checked out by anther user (hover over the asset to see who has the file checked out).



File is checked out for branch/copy (displayed with some providers when the file has been copied from another location

Submitting to Source Control

Submitting to Source Control inside of Unreal Engine is a vital part of the Source Control process as if you do not submit anything to Source Control, other users will not be able to see what you have been working on/created. A workflow that is convenient if you are working on many changes, or you are not tracking changes you are making too closely, is to make use of the Submit to Source Control option in the File menu of the Editor.



This will scan your project and the Engine for changes made to assets that can be submitted and then present you with the Submit Files dialog.



You can then enter a description of your changes and then click OK and you will then commit/submit the files to Source Control.

Syncing Files

If you want to get changes that other people have made, you can Right-click on files or folders in the Content Browser and select the Sync option. Alternatively, you can Sync using an external program such as Perforce (P4V). However, it is recommended that you shut the Editor down if you do this as it may lock some files for editing while open.

When a file is Out of Sync (i.e. a newer version exists on the Source Control server to the one you have locally), the following icon, , will be displayed by the asset in the Content Browser.

Adding Files

Similar to the Check-Out workflow, you can auto-add new files to source control using the Add New Files When Modified option in the preferences.

Files that are added appear with a symbol on them in the Content Browser and can also be checked in, in the same manner that files are checked out.

Deleting Files

Deleting assets that are already in Source Control is more complex as they are usually referenced by other assets. If you select a file in the Content Browser and press Delete (or select it from the Right-click menu), you will be presented with the Delete Assets dialog.



Number

Name

Description

1

Pending Deleted Assets

This is the asset(s) that you are going to delete.

2

Assets Referencing the Pending Deleted Assets

This shows asset(s) that are referencing the assets you are about to delete.

3

Replace References

Here you specify what assets you want other assets that reference this asset(s) to reference when this asset is deleted.

4

Force Delete

Here you can force delete an asset. However be very careful doing this as it can have a very negative impact on your project. You should only use this option as a last resort if nothing else works.

5

Cancel

This will cancel the delete operation.

Once you have chosen how to handle the deletion, the file will generally be replaced by a hidden Asset known as a Redirector. If you want to clean up the Redirector that is created when deleting assets, you can Right-click on a folder in the Content Browser and select the Fix Up Redirectors in Folders. This will fix up the references in your project and permanently delete the redirectors, marking the files for delete in source control. Presently, to commit these deletions, you need to use an external tool such as P4V or TortoiseSVN.

Level Files

Levels can be managed in source control just like any other asset via the Content Browser. However levels can also be worked with via the Level Browser's menu, which contains options for source control in the Source Control sub-menu.

Config (.ini) Files

Many configuration options for the Editor and Projects are stored in Configuration Files, or Config files for short. Some of these will need to be kept under source control (see above when adding the Config/ directory to source control). The settings editor provides a way to check these in and out so team members can share various settings. For example, in Edit -> Project Settings you will see the following indicator.



Checking out the file allows these settings to be edited. Unfortunately there is currently no way to check these files back into source control via the Editor, so you will need to use an external tool such as P4V or TortoiseSVN to check these files in outside of your Unreal Editor session.

Getting Started

Taking Snapshots

Working With Level Snapshots

Known Limitations

Creating Custom Filters

Custom Filter Basics

Advanced Custom Filters

Level Snapshot Filter Logic

Negating Level Snapshot Filters

Creating Blueprint Filters

Level Snapshot Plugin Settings

Level Snapshots Editor Plugin Settings

Level Snapshots enable you to save a particular configuration of the Actors in the World Outliner of your Level and instantly restore your scene to that state. This can dramatically streamline complex setups and avoid duplication and management of multiple variations of the same Level for different scenarios. Level Snapshots are especially useful for Virtual Production, as they enable users to reset virtual environments to their starting position between takes as well as track per-shot changes that may occur during a shoot while preserving the base starting point of the Level.

Users also have the flexibility to selectively restore only certain Actors or Properties from a Level Snapshot in order to account for bespoke needs in the moment that can vary from one situation to the next. For example, you can choose to restore only the lighting from a Level Snapshots or the position of a single actor. Experienced users can construct custom filters using Blueprints to manage the restoration of Actors / Properties on the most complex Level setups and automate common project-specific requests.

Getting Started

In order to enable the Level Snapshot feature, you need to install the Level Snapshots plugin.

In the Unreal Editor, go to the main menu and select Project Settings.

In the Project Settings window, navigate to Plugins > LevelSnapshots.

Enable the LevelSnapshots plugin.

(Optional) Enable the nDisplay Support For Level Snapshots plugin.

the editor will prompt you to restart.



Support for nDisplay in Level Snapshots is through a separate plugin. This is important for using In-Camera VFX. If you aren't using nDisplay for your project, you don't need to enable the nDisplay Support for Level Snapshots plugin.

Once the engine restart is complete, you can take Level Snapshots, access the Level Snapshots menu in the Main Toolbar, and open the Level Snapshots window.



Taking Snapshots

There are three ways to take a Level Snapshot:

By clicking the Level Snapshot button in the main toolbar.



By clicking the Take Snapshot button in the Level Snapshot window.



Click image to expand.

By activating Take Snapshot using the



All three of these methods will open the Create Level Snapshot window.

By default the new Level Snapshot shown in the Create Level Snapshot window will be named using the format , but you can rename the Level Snapshot as you choose. You can also add a description to give more information about the purpose of the saved Level Snapshot.



The Level Snapshot will be saved as an Asset in the directory shown under Root Directory in the Create Level Snapshot window, which will be named LevelSnapshots by default. The subdirectory location of a specific Level Snapshot will be based on the Map (Level) name and the date (year-month-day) the Level Snapshot was taken. You can change both the root directory and the subdirectory of a particular Level Snapshot. You can also change the default naming pattern for new Level Snapshots.

If you rename a Level Snapshot before saving it, be careful not to overwrite it with another Level Snapshot, because the revised name will become the new default unless you change or revert it.

Working With Level Snapshots

Level Snapshots contain a record of all the Actors in the World Outliner as well as the state of their Components and properties at the moment at which the Level Snapshot is taken. All the Actors are recorded, whether or not they are currently visible in the World Outliner when the Level Snapshot is taken, so you may need to check Actor visibility when using Level Snapshots to set up a scene in your Level. Similarly, the states of Assets (for example, Materials) are not recorded, so any changes to Assets need to be tracked independently using source control.

Once you have one or more Level Snapshots created, you can reset all the Actors to their saved state by selecting the Level Snapshot and clicking the Restore Level Snapshot button.

When you restore a Level Snapshot, any changes to Actors made since the Level Snapshot was taken will be reverted back to the states saved in the Level Snapshot.

New Actors added after the Snapshot was taken will be removed from the Level.

Actors removed after the Snapshot was taken will be added back to the Level.

All Actor transforms will be reverted to their saved states.

Any changes to Actor properties will be reverted to their saved states.



Click image to expand.

You can undo the Restore Level Snapshot action.

When you click a Level Snapshot, the right-hand side of the Level Snapshot window will show a list of all the Actors as well as their Components and properties that will be reverted to the states saved in the Level Snapshot.

You can use the checkboxes to manually apply or ignore specific changes, or use custom filters to specify which changes to apply or ignore; see Creating Custom Filters for more information on custom filters.

If you have multiple Levels in your Project, only the Level Snapshots associated with the currently open Level will be visible in the Level Snapshot window. Level Snapshots associated with other Levels will only be shown when those Levels are opened in the editor.

Known Limitations

This section describes known limitations when working with Level Snapshots.

The following Actors and Actor components are not tracked with Level Snapshots. If you want to use them with your Level, you will need to track them manually.

Landscapes

USD actors

Console variables

If you rename a sublevel after creating a Level Snapshot, the Level Snapshot system will consider all the Actors in the renamed sublevel new, instead of existing changed Actors. You will see this as the Level Snapshot system recommending to remove the Actors to get back to the original state.

Creating Custom Filters

The middle area of the Level Snapshot window contains the custom filters. You can use single filters, or use filter groups to create more complex filters including AND and OR Boolean operators. You can set favorite filters, and also save and load filters for later use.

When you hover over a filter, you will see a green or red bar on the left side, a checkbox, and a trash can.

Clicking the green bar will turn it red, which negates the filter, reversing its function. For example, if you had a filter that only included Actors with a particular tag, clicking it would cause those Actors to be excluded, and everything else to be included. Conversely, clicking the red bar turns it green, returning the filter to its original function. Refer to Negating Level Snapshot Filters for more information.

Clicking the checkbox disables the filter, and will gray it out to show it is not in use.

Clicking the trash can icon will delete the filter.



You can also negate the filter, undo negation, and enable or disable a filter from the filter properties. See the Level Snapshot Filter Reference for more details.

Custom Filter Basics

To create a basic custom filter, follow these steps:

Begin by clicking the +Filter Group button to add a new Filter Group.



Click the Add Filter dropdown, and either select one of the common filters, or expand the C++ Filters submenu to select a filter. If you have created a custom filter using Blueprints, you can select it from the Blueprint Filters submenu. You can also use the Search text box to find a particular filter to add.

You can set specific filters as favorites that can be quickly dragged into Filter Groups.



The most commonly-used filters are included in the menu under the heading Common Filters. This includes Actor Changed Transform, Actor Has Tag, and Property Has Name.



Once you have added a filter, select it to modify its properties. Most filters will have at least one property that you need to set before it is functional. For example, the Actor Has Tag Filter needs you to provide an Actor tag that it uses to filter the Level Snapshots. Refer to the Level Snapshot Filter Reference for more details.



Click image to expand.

Select a saved Level Snapshot, then click Refresh Results. The Actors saved in the Level Snapshot will now be filtered according to the filter you configured.



Click image to expand.

To save your new filter, open the Load / Save Filter dropdown, and select Save As. A new window opens, where you can name your filter and select the directory to save it in as an Asset.





Click image to expand.

You can also load saved filters by opening the Load / Save Filter dropdown, selecting the filter Asset you want to load from the displayed list , then clicking Load filter. If you have a large number of saved filters, you can use the Search bar to find a specific filter.

Advanced Custom Filters

Level Snapshot filters have advanced features that allow for complex combinations of filters to achieve specific results. This can be helpful when you are dealing with large Levels with many Actors and multiple saved Level Snapshots.

You can add multiple filters to the same Filter Group and combine them using an AND operator (represented by &). This means that both filters will be applied to the Level Snapshots and only those Actors that meet all the filter criteria will be shown.

Adding additional Filter Groups using the + Filter Group button allows you to combine filters using the OR operator. This means that Actors that fit the criteria of either Filter Group will be shown.

You can ignore a Filter Group by clicking the checkbox to disable it, or include an ignored Filter Group by clicking the checkbox to enable it.

You can delete Filter Groups by clicking the trash can icon.



Most filters use the Default Result Filter property, which can be set to:

Include, which includes the results of the filter and exclude everything else.

Exclude, which excludes the results of the filter and includes everything else.

Do Not Care, which includes or excludes Actors directly affected by the filter according to the negation setting, but does not care about the state of any other Actor.

Refer to the Level Snapshot Filter Reference for more details.



Negating a filter set to Exclude in the Default Result property will actually include the filter's results. Be careful to use well-defined logic as much as possible, so as not to confuse the function of your filter. Refer to Negating Level Snapshot Filters for more information.

Because of the potential for complex interactions between filters, we highly recommend that you carefully name your filters to identify their functionality, especially if other users will be using the filters you create.

Level Snapshot Filter Logic

All the default filters created using C++ and all custom filters created using Blueprints are fundamentally based on one of the following four validation checks:

Is Actor Valid: Decides whether an Actor can be restored.

Is Property Valid: Decides whether a property can be restored.

Is Deleted Actor Valid: Decides whether an Actor that was deleted from the Level (since the Level Snapshot was taken) should be respawned.

Is Added Actor Valid: Decides whether an Actor that was added to the Level (since the Level Snapshot was taken) should be despawned.

In most cases, we do not recommend using both Is Actor Valid and Is Property Valid filters at the same time, as the results will often not be useful. Specifically:

Do not mix the two in the same Filter Group in the Level Snapshot window.

Do not implement more than one function (IsActorValid, and so on) when creating a filter.

There are specific use cases where you may wish to carefully construct such a filter using C++ filters in multiple Filter Groups, or as a custom Blueprint filter. This would enable applying some of the settings of one Level Snapshot with a filter, and while also applying different settings from another Level Snapshot with another filter.

For example, consider a Virtual Production setup with two light options, and two set dressing options. Someone could ask for option 1 on lights, and option 2 on set dressing. With Level Snapshot Filter Blueprints you can create an interface to take and apply the appropriate settings from the different Level Snapshots. The full logic required for this setup can't be configured using only the Apply Snapshot to World button, so in this case you would need to construct a complicated filter.

Negating Level Snapshot Filters

When working with Level Snapshot filters, negating filters is a useful way to make a filter serve multiple purposes. In general, negating a filter has the following effects:

Include becomes Exclude.

Exclude becomes Include.

Do Not Care stays Do Not Care.

For example, suppose you used the ActorHasTag filter to only restore Actors with the tag "RestoreMe". The filter's IsActorValid function returns Include for Actors with the tag and Exclude for Actors without it. If you negate the filter in the UI, the behaviour is reversed: Actors with the "RestoreMe" tag will now be excluded and all other Actors will be included.

Certain default C++ filters have additional properties that can also affect the function of the filter. Be careful using negations with these filters to ensure you achieve the intended results when applying your filters to your Level Snapshots.

Creating Blueprint Filters

This section assumes you are already familiar with Blueprints. For more information, refer to the Blueprints documentation.

In order to create a new Level Snapshots Blueprint Filter, follow these steps:

Create a new Blueprint using the Level Snapshot Blueprint Filter base class.



Click image to expand.

Select an Override Function from the available options:

Is Actor Valid: Decides whether an Actor can be restored.

Is Added Actor Valid: Decides whether an Actor that was added to the Level (since the Level Snapshot was taken) should be despawned.

Is Deleted Actor Valid: Decides whether an Actor that was deleted from the Level (since the Level Snapshot was taken) should be respawned.

Is Property Valid: Decides whether a Property can be restored.



Click image to expand.

The selected Override function (in the example below, Is Actor Valid) opens in a new graph, with some default nodes.



Click image to expand.

Drag off the Parameters output pin of the Is Actor Valid node, and add a Break node.



Click image to expand.

From this point, you can define the logic for your new filter branched off of either the Snapshot Actor output or the Level Actor output. This will determine which one is validated against the filter's conditions. For the rest of this example, we will create a filter which checks whether a Snapshot Actor is a Skylight.

Remove the default parent, then add whatever node is appropriate to validate and connect it to the Break node. In the example below, we selected a Cast to Skylight node and connected its Object input pin to the Snapshot Actor output pin of the Break node.



Click image to expand.

Connect the Is Actor Valid node output pin to the Cast To Skylight node input pin. Duplicate the Return node, and connect one to the main output pin of the Cast To Skylight node, and the other to the Cast Failed output pin.

Choose Include for the Return Value of the Return node connected to the main output pin of the Cast To Skylight node, and choose Exclude for the Return Value of the node connected to the Cast Failed output pin.



Click image to expand.

Save and Compile the Blueprint. The resulting filter, when used on a Level Snapshot, will only include Skylight Actors in the Level Snapshot.

If your Blueprint filter includes a variable that you expose as instance editable (shown by the open eye icon next to the variable in the My Blueprint panel), it will appear in the properties of that Level Snapshot filter when used.



Level Snapshot Plugin Settings

The Level Snapshot Plugin has settings that can be accessed directly from the Level Snapshot window by clicking the gears icon in the upper-right corner.



The Plugin Settings window will open, showing the Level Snapshot Plugin Settings.



The settings include how to use hashes when filtering Level Snapshots for performance improvements. For filtering, every Actor needs to be loaded into memory, but loading Actors can take a long time. The Level Snapshots plugin solves this by computing a hash for the Actor when a snapshot is taken, so that when filtering, it can recompute the hash using the Actor in the world. If the hashes match, it can skip loading the saved Actor data.

Setting

Description



Behavior



Skipped Classes

Level Snapshots ignore any classes and properties that you specify in this list.

Float Comparison Precision

When comparing float properties, Level Snapshots ignore floats with changes beyond this significant digit.

Double Comparison Precision

When comparing double properties, Level Snapshots ignore doubles with changes beyond this significant digit.



Performance Hash Settings



Hash Cutoff Seconds

For most Actors, it takes about 600 micro seconds to compute a hash, but there can be some Actors that can take longer. For such actors, it can be faster to load the saved Actor data into memory than computing its hash. Therefore if hashing takes longer than Hash Cutoff Seconds, the plugin skips hashing altogether and immediately loads the Actor data.

Use Hash for Loading

Whether to compare the world Actor to its saved hash when loading a snapshot. Enabling this option boosts performance

Can Use CRC

When enabled, Level Snapshots computes a hash using the CRC32 algorithm when taking and analyzing snapshots. Disabling this option means taking a snapshot will be faster since CRC32 will no longer be computed, and when loading a snapshot, CRC32 is no longer available to check whether an Actor has changed.

Can Use MD5

When enabled, Level Snapshots computes a hash using the MD5 algorithm when taking and analyzing snapshots. Disabling this option means taking a snapshot will be faster since MD5 will no longer be computed, and when loading a snapshot, MD5 is no longer available to check whether an Actor has changed.

Snapshot Diff Algorithm

CanUseCRC and CanUseMD5 determine whether CRC32 and MD5 are computed when taking a snapshot. If both are enabled, both are computed, so this setting determines which algorithm to use when diffing assets. When taking a snapshot, the plugin tracks how long it took to compute the CRC32 and the MD5 hashes, so if the UseFastest option is selected, the plugin can check which algorithm was faster when the snapshot was taken and use the faster one.

Level Snapshots Editor Plugin Settings

You can also customize settings for the Level Snapshots Editor in the plugin settings.



Setting

Description



Data



Root Level Snapshot Save Dir

The root directory to save the Level Snapshot assets. Default is /Game/LevelSnapshots.

Level Snapshot Save Dir

The folder under the root directory to save the Level Snapshot assets in. The default format is {map}/{year}-{month}-{day}.

Default Level Snapshot Name

The name for the Level Snapshot asset. The default format is {map}_{user}_{time}.



Editor



Enable Level Snapshots Toolbar Button

Enabled by default.

Use Creation Form

Enabled by default.

Click Actor Group to Select Actor in Scene

When enabled, clicking on an Actor group under Modified Actors will select the Actor in the scene. The previous selection will be deselected. Disabled by default.

Preferred Creation Form Window Width

Slider, defaults to 1000.

Preferred Creation Form Window Height

Slider, defaults to 1000.

Shared Filter Properties

Actor Changed Transform Filter Properties

Actor Dependent Property Filter Properties

Actor Has Tag Filter Properties

Constant Filter Properties

Property Has Name Filter Properties

Property Type Filter Properties

Transform Property Filter Properties

Only the properties of the default C++ filters are described here. Custom filters created with Blueprints will have whatever properties you assign.

Shared Filter Properties

Property Name

Description



Filter



Name

The display name in the editor. Defaults to the class name if left blank.

Filter Behavior

Determines whether to pass on or negate the results of the filter.

Ignore Filter

Determines whether or not to ignore the filter.



Config



Default Result*

Options are:

Include: The Actor / property is included.

Exclude: The Actor / property is excluded.

Do Not Care:

Another filter will decide. If all filters are set to Do Not Care, include the Actor / property.

Use this for filters that only implement one function: IsActorValid or IsPropertyValid.

* This property is not shared by every filter.

Actor Changed Transform Filter Properties



Property Name

Description



Config



Transform Check Rule

Determines whether to allow Actors that changed location or that stayed in the same place. Options:

Is Valid when Transform Changed: Return True if the Snapshot and World Actors have different transforms.

Is Valid when Transforms Stayed Same: Return True if the Snapshot and World Actors have the same transforms.

Ignore Location

If enabled, do not compare the Actor's locations.

Ignore Rotation

If enabled, do not compare the Actor's rotations.

Ignore Scale

If enabled, do not compare the Actor's scales.

Actor Dependent Property Filter Properties

This filter is complex, and is based on other filters. It is intended for experienced users and should be used carefully.



Property Name

Description



Config



Actor Filter

IsActorValid is run on this filter. IsPropertyValid is run on one of the below filters depending on this filter. Select a filter from the dropdown list, and configure its properties accordingly.

Include Property Filter

Used by IsPropertyValid when Actor Filter > IsActorValid returns Include. Select a filter from the dropdown list, and configure its properties accordingly.

Exclude Property Filter

Used by IsPropertyValid when Actor Filter > IsActorValid returns Exclude. Select a filter from the dropdown list, and configure its properties accordingly.

Do Not Care Handling

Determines what filter IsPropertyValid is supposed to use when IsActorValid returns DoNotCare. Options:

Use Include Filter: When IsActorValid returns Include, use RunOnIncludedActorFilter.

Use Exclude Filter: When IsActorValid returns Exclude, use RunOnExcludedActorFilter.

Use Do Not Care Filter: When IsActorValid returns DoNotCare, use RunOnDoNotCareActorFilter.

Do Not Care Property Filter

Used by IsPropertyValid when ActorFilter > IsActorValid returns DoNotCare and DoNotCareHandling == UseDoNotCareFilter. Select a filter from the dropdown list, and configure its properties accordingly.

Actor Has Tag Filter Properties



Property Name

Description



Config



Tag Checking Behavior

Determines how to match Allowed Tags in each Actor. Options:

Has All Tags: Actors must have all tags to pass.

Has Any Tag: Actors must have at least one of the tags to pass.

Allowed Tags

The tags to check the Actor for. The property is a set containing multiple elements that are text strings for the tags.

Actor to Check

Determines which of the Actors to check the tags on. Options:

World Actor: Checks only the tags of the World Actors.

Snapshot Actor: Checks only the tags of the Snapshot Actors.

Both: Checks the tags of both groups of Actors.

Constant Filter Properties



Property Name

Description



Config



Is Actor Valid Result

Options:

Include

Exclude

Do Not Care

Is Property Valid Result

Options:

Include

Exclude

Do Not Care

Is Deleted Actor Valid Result

Options:

Include

Exclude

Do Not Care

Is Added Actor Valid Result

Options:

Include

Exclude

Do Not Care

Property Has Name Filter Properties



Property Name

Description



Config



Name Matching Rule

How to compare the Property Name to Allowed Names. Options:

Contains Exactly: The name must contain the input substring (case sensitive).

Contains Ignore Case: The name must contain the input substring (case insensitive).

Matches Exactly: The name must match the input substring (case sensitive).

Matches Ignore Case: The name must match the input substring (case insensitive).

Allowed Names

The names to check the property against. The property is a set containing multiple elements that are text strings for the names.

Property Type Filter Properties



Property Name

Description



Config



Allowed Types

The property types you want to allow. The property is a set containing multiple elements that are text strings for the types.

Transform Property Filter Properties



Property Name

Description



Transform



Location

Options:

Include

Exclude

Do Not Care

Rotation

Options:

Include

Exclude

Do Not Care

Scale

Options:

Include

Exclude

Do Not Care



Content Browser





Configuration Files

Workflow

Using Perforce with UE4

Setting up a Perforce Server on your Local Machine

P4 Typemap

Server on your Local Network

Cloud Provider

Setting up a Local Workspace

Adding Files to Perforce

Connecting from Unreal Editor

Unreal Engine (UE) comes with an integrated method that allows people to work together on their projects using version control software called Perforce. Source Control allows users on your team to share assets and code with one another, as well as providing a backup and history of changes so any files can be rolled back to an earlier version if something went wrong with the file.

Workflow

In general and mostly for historical reasons, working with assets in the Unreal Editor follows the workflow of Perforce. Files known as Assets (extension .uasset and .umap) are mainly what the Editor works with. These files are binary, so cannot be opened as text or merged in a text-based merge tool. For this reason, when working on a file the Editor will lock that file (this is known as Checking Out in Perforce nomenclature) so that other users cannot concurrently edit it. When the user is done with editing the file(s) they have locked, they check in, or commit those files, uploading the changes to the server and releasing the lock on the file.

Using Perforce with UE4

Setting up a Perforce Server on your Local Machine

To avoid potential integration issues with our tools, such as UnrealGameSync, we recommend running a case-insensitive Perforce server.

There are two ways of running the Perforce server, P4D and P4S. P4D runs while an instance of the command line is running, so it is usually only used for spot-maintenance tasks. P4S is the service-based equivalent of P4D as it allows you to run the server in the background. The service is usually installed and started when you install the Perforce server tools.

Sometimes the service does not get run automatically. To turn the service on in Windows, first go into the Control Panel -> Administrative Tools ->Services applet. Then find the Perforce service in the list and start it:



Once the service is running, you can connect to your server using P4Admin. If this is the first connection to your server, then you can make a new user in the initial connection dialog:



Fill in the connection information for your Perforce server and press okay. Once you have connected to the server in P4Admin, you can make new depots, users, and groups pretty easily. Use P4V and the Unreal Editor to connect to the server with the credentials you supplied in the initial connection dialog.

Check out the P4Admin Documentation for more in-depth information on the ins and outs of Perforce.

P4 Typemap

Before you start adding files to your depot, you should set up your P4 Typemap so Perforce knows how to treat Unreal file types. Setting the typemap will affect how files get set to read only or writable inside of Perforce. However to do this, you will need to open a new command prompt and set up some p4 environment variables.

Replace the values above with your respective username and connection address. Open the typemap by entering the following in the command prompt.

You will then see a text window open; this is your server's typemap. The typemap below is an example that we have used in the past:

Once edited, save the file by pressing Ctrl+S on your keyboard and then exit. The command prompt should then show Typemap saved.

Server on your Local Network

You can set up a server on your local network for people to use to collaborate with one another. To do this, follow the steps above on the server and connect using the server's name or IP from your clients.

Cloud Provider

There are various cloud providers that allow you to host Perforce servers off-site and to collaborate remotely. A quick search online for Perforce Hosting should turn up a few results. Each hosting provider is different, but all should end up with a set of credentials that you can use to connect. See also Connecting from Unreal Editor below for a note about connecting to Perforce cloud providers.

Setting up a Local Workspace

To work with files that are under Perforce control, you will need to set up a Workspace so that the files can be managed on your local machine. You can do this via P4V by opening up the Workspaces tab in the View dropdown:



To create a new workspace, right-click in the Workspace window and select the New Workspace option. Then enter a name for your workspace and a location where you want the files to be on your local machine, the Workspace Root.



Once you have a server and a workspace, you will want to start adding files to it. For the moment, this needs to be done initially outside the Editor via P4V. If you already have a workspace that someone else has set up with some files already, you can skip ahead. When you create a new project, you can choose whether it incorporates C++ code and Blueprint elements. If you are using C++ code in your project, you will see a Source/ directory as well. You should initially add only the following directories of your project:



Folders and files highlighted in Green should be added to your depot. The Binaries folder in Yellow is optional, depending on how your team wants to work together. It is not required if every team member is going to compile their editor/game themselves, but should be included in the initial add if any team members will just be grabbing a version from the depot to create content. Note that the server typemap setup above should mean that coders can compile their binaries without them being set to be Read-Only by Perforce.

Adding Files to Perforce

Adding files to Perforce is something that can be accomplished in the few following steps.

To add files/folders to Perforce, first select the files/folders in P4V and then right-click and select the Mark For Add option.



This will add the files to your default change list. All files that you add can be seen in the Pending change lists tab:



To submit something, first right-click on the change list and then select Submit. Then enter a change list description and click the Submit button.



If you want to start work on a project that someone else has already started, you will need to get the latest revision from Perforce using P4V. To do this, find the project in the Depot View in P4V and then Right-click on the project you want to get and select Get Latest Revision. This will download all the files to the location you specified for your Workspace Root above.

Connecting from Unreal Editor

You can connect to your Perforce server right from the Editor by clicking on the Source Control icon on the Toolbar:



Once open, choose Perforce as the provider from the Source Control Login dialog and enter your login credentials. If you have a workspace already set up (that the current project is inside of), your login credentials should be populated automatically.



When using some servers, including many cloud providers - you may need to enter the Host and Password to access your depot from the Editor. You can do this by opening the advanced field at the bottom of the Perforce login dialog:





Content Browser





Configuration Files

Using Subversion (SVN) with Unreal Engine

Setting Up a SVN Server

Setting up a SVN server on your Local Machine

Server on your Local Network

Secure Access

Cloud Provider

Checking Out to a Local Working Copy

Adding files to Subversion

Connecting to Subversion from Unreal Editor

Using SVN on Mac OSX with Secure Connections

Unreal Engine comes with an integrated method that allows people to work together on their projects using version control software called Subversion or SVN for short. Version control allows users on your team to share assets and code with one another, as well as providing a backup and history of changes so any files can be rolled back to an earlier version if something went wrong with the file.

Using Subversion (SVN) with Unreal Engine

If Perforce is not an option for you, then you can use Subversion (SVN). SVN is similar to Perforce in how users handle data. The following guide will walk you through how to setup a SVN source control server for your UE4 projects.

Setting Up a SVN Server

Setting up an SVN server can be done using the Subversion command-line tools, but in this case for ease of use, we are going to describe how to set up a server using VisualSVN on Windows.

You can download SVN for Windows by clicking here and downloading the program from the SVN website.

Setting up a SVN server on your Local Machine

After SVN had been installed, open SVN up and in VisualSVN, Right-click on the Repositories tree item and select Create New Repository:



If asked, choose a Regular Files System for now.



Then enter a name for your repository.



Next choose whether you want some initial folders adding to the repo:



Adding the Trunk, Branches, and Tags directories can be useful if you plan on doing concurrent C++ code development with other people. Initial security settings can also be set up at this time. If you are unsure of what to set here, leave it as the defaults and all Subversion users have Read/Write access. Once created, you should see your repository in the tree view.

Server on your Local Network

You can set up a server on your local network for people to use to collaborate with one another. To do this, follow the steps above on the server and connect using the server's URL from your clients.

Secure Access

Many users like to use a secure connection to access their repositories. These connections have URLs starting with https:// and have a number of things to be aware of when setting them up. To use HTTPS, the server needs to provide a trusted certificate so that clients know that they are connecting to a secure server. VisualSVN can issue a local certificate so that internal users can connect securely. You can find details of this by Right-clicking on the root of the tree view, selecting Properties, and navigating to the Certificate tab:



Note that to connect to an SVN server using a secure connection, the certificate issued by the server needs to be issued to the same name that users use to connect to it. For example; if users access the server using the URL https://my-server/svn, then the certificate needs to be issued to "my-server" (without quotes), similarly if users connect via IP address https://192.168.0.1/svn then the certificate should be issued to "192.168.0.1" (without quotes).

Cloud Provider

There are various cloud providers that allow you to host SVN servers off-site and to collaborate remotely. A quick search online for SVN Hosting should turn up a few results. Each hosting provider is different, but all should end up with a URL, username, and password that you can use to connect to the server.

Checking Out to a Local Working Copy

To work with files that are under SVN control, you will need to set up a Working Copy so that the files can be managed on your local machine. For the moment, you cannot do this inside of the Unreal Editor. You can do this via the SVN command line tools, but in this case for ease of use, we are going to describe how to set up a working copy using TortoiseSVN on Windows.

You can download TortoiseSVN for Windows by clicking here and downloading the program from the TortoiseSVN website.

When you create a new project, you can choose whether it incorporates C++ code and Blueprint elements. If you are using C++ code in your project, you will see a Source/ directory as well. You should initially add the following directories of your project:



Folders and files highlighted in Green should be added to your depot. The Binaries folder in Yellow is optional, depending on how your team wants to work together. It is not required if every team member is going to compile their editor/game themselves, but should be included in the initial add if any team members will just be grabbing a version from the depot to create content.

If you are trying to edit a project that someone else has already created, you can skip ahead as the following will not apply to you.

To create your working copy, you should Check Out the (assumed empty) root of your repository. To do this, Right-click on your project's folder in Windows Explorer and select SVN Checkout.



Then enter the URL of your repository and where it should be checked out (make sure this is not creating a subdirectory you do not want).



Next click OK and it should create a hidden .svn directory that SVN uses to store information about the working copy.

Adding files to Subversion

To add the files to your repository, select the items in Windows Explorer and then Right-click to add and select the TortoiseSVN->Add option.



When you do this, SVN will mark the files you selected for addition to the repository. Next, Right-click in the directory containing your project and select TortoiseSVN->SVN Commit.



This will scan the directory for any changes/adds that you have made and display them in the Commit dialog.



Now enter a commit message and click OK to upload your additions to the server. If you want to start work on a project that someone else has already started, you will need to get the latest revision from SVN using TortoiseSVN. To do this, you should perform the SVN Checkout stage above and make sure you have Fully Recursive set for your checkout depth. This should download the all the existing files to your local machine.

Connecting to Subversion from Unreal Editor

You can connect to your SVN server from the Unreal Editor by clicking on the Source Control icon in the Toolbar.



Once open, choose Subversion as the provider from the Source Control Login dialog and enter your login credentials. The password field is optional and does not need to be filled in every time. If it is entered correctly once, SVN will remember it.



Using SVN on Mac OSX with Secure Connections

Because of how the Mac stores security information such as passwords, you may need to perform some extra steps to get your Editor to connect to servers via https:// connections. You may need to perform these steps if you see errors in your logs like:

To fix this, first open a command prompt and type.

This will change the directory to where the SVN binaries that are shipped with UE4 are found (substituting the engine installation directory).

Then type the following.

Substituting your username and repository URL appropriately. This should then present you with a password prompt:

Enter your password and it will be stored in the keychain. After this, the Editor should be able to connect correctly to your server following the regular instructions above.

Setting up an Unreal Engine Project

Launching Unreal Editor

The ShotGrid Menu

Loading Content from ShotGrid into Unreal Editor

Publishing Content from Unreal Editor to ShotGrid

Publishing Content from Maya and Rendering in Unreal

Debug Logging



Epic Games has partnered with Autodesk to integrate Unreal Engine into the ShotGrid production management system. You can now make Unreal Editor a key player in your ShotGrid content pipeline: you can load assets from ShotGrid to work on in the Unreal Editor, and publish the Assets and Actors in your Unreal Engine Project back to ShotGrid for other people in your organization to work on.

If you're new to ShotGrid, see its features page and Help Center to get started learning about what it can do for you.

If you haven't used a desktop application that integrates with ShotGrid before, read over it's Integrations User Guide for some basics about the workflows and apps that it introduces to get your team working together across separate content creation tools.

While this integration covers all of the ShotGrid Pipeline Toolkit's base features, we don't consider it a fully finished pipeline that solves all your needs for working with Unreal Engine content in the context of a full-scale production. We expect this integration to evolve over time based on your feedback, and in time, we'll get to that point. For now, consider this integration as a helpful starting point if you already use ShotGrid (or are considering adopting it), and as a base for experienced pipeline developers to build on top of.

Setting up an Unreal Engine Project

Any Unreal Engine Project can work with ShotGrid. However, you first have to enable the ShotGrid Plugin in your Project.

From the main menu in Unreal Editor, select Edit > Plugins to open the Plugins window.

In the Editor section, find the ShotGrid Plugin and check its Enabled checkbox.



Restart your Project when prompted.

You won't see any difference in the Unreal Editor UI yet — this is normal. Refer to the next section to learn how to launch Unreal Editor from the ShotGrid Desktop application.

Enabling the ShotGrid plugin also enables the Python Editor Script Plugin for your Project. While this plugin is enabled, you can run Python code in the Unreal Editor to work with your content. For details, see Scripting the Editor using Python.

Launching Unreal Editor

In order to activate the ShotGrid integration in your sessoin, you must launch the Unreal Editor from the ShotGrid Desktop application.

If you haven't used ShotGrid on the web before, refer to the Setting up a ShotGrid Project documentation to get started.

Launch ShotGrid Desktop and log in to your organization's ShotGrid site with your user account.

Open any ShotGrid project that has been configured to work with Unreal Editor.

ShotGrid Desktop then scans your computer for installations of Unreal Engine, and offers shortcuts on the Apps page:



Click one of these shortcuts.

In the Unreal Project Browser, select a Project that already has the ShotGrid Plugin enabled, and click Open.

The ShotGrid Menu

When Unreal Editor is running in the context of a ShotGrid project, a ShotGrid menu is added to the main Toolbar:



You can also open the same menu by right-clicking on Assets in the Content Browser.

Some aspects of the ShotGrid integration are context-aware and provide additional functionality based on your selection.



Option

Description

Toggle Debug Logging

Determines whether the ShotGrid integration writes debug messages to the Output Log and to a log file on disk. Refer to the Debug Logs below.

Open Log Folder

Opens the location on your computer that contains your ShotGrid log files.

Jump to ShotGrid

Opens the current ShotGrid project in your system's default web browser.

Work Area Info...

Opens the ShotGrid Your Current Work Area tool, which shows your current project, environment settings, and toolkit apps that are running. For details, refer to the ShotGrid documentation.

Load...

Opens the ShotGrid Loader tool. Refer to Loading Content from ShotGrid into Unreal Editor below.

Publish...

Opens the ShotGrid Publish tool. See Publishing Content from Unreal to ShotGrid below. You'll typically want to open this tool by right-clicking the Assets or Actors you want to publish. When you open this panel from the Toolbar, it does not support dragging and dropping Assets or Actors from your Unreal session.

ShotGrid Panel...

Opens the ShotGrid Panel tool. Use this to get a view on all the activity happening in your ShotGrid project without having to leave the Unreal Editor. For details, refer to the ShotGrid documentation.

Loading Content from ShotGrid into Unreal Editor

The ShotGrid Toolkit includes a Loader app you can use in the Unreal Editor to import content published to ShotGrid by artists into your Unreal Project.

To launch the Loader app, choose Load... from the ShotGrid menu.

In the Loader, you can browse the full collection of assets that have ever been published to your ShotGrid project, or that are related to your ShotGrid Tasks:



Choose one or more assets that you want to import, and import them into the Content Browser. To do so, you can either right-click assets and choose Import into Content Browser from the context menu, or click the Actions button for any selected asset and select Import into Content Browser.

The Unreal integration currently supports importing FBX files from ShotGrid. It uses the built-in FBX import pipeline to convert them into Static Meshes in Unreal.

ShotGrid Toolkit's template system helps organize imported published content into folders within the Unreal Editor's Content Browser based on metadata from the production tracking database. You can use this to leverage data from ShotGrid to automate best practices within your Project for naming conventions.





For details about using the Loader app, refer to the ShotGrid Loader Documentation.

Publishing Content from Unreal Editor to ShotGrid

The ShotGrid Toolkit includes a Publish app, which you can use in the Unreal Editor to export content that you've created or modified in Unreal Editor out to the ShotGrid project. Other artists, working in Unreal Editor or in other applications, can then use their own ShotGrid Loader apps to import that content and work on it downstream. Or, others in your organization can review the work you did in Unreal Editor within the ShotGrid web application.

To launch the Publish app, right-click the Asset(s) in the Content Browser you want to publish, and choose Publish... from the ShotGrid menu.

The Publish app lists all of the items that you had selected that it is able to export.



The Unreal integration currently supports publishing:

Static Mesh Assets. These are exported to ShotGrid as FBX files, using the built-in FBX exporter.

Level Sequences. These are rendered to movie files and exported to ShotGrid for viewing in RV, either in the ShotGrid web application or on the desktop.

In the Publish app, you can add a description and thumbnail for each Unreal Asset you're publishing. This helps downstream artists and reviewers understand what you've published.

When you have all your published assets set up the way you want them, click Publish to export them all to FBX and make them available to other ShotGrid applications in your project's shared storage location.

For details about using the Publish app, refer to the ShotGrid Integrations User Guide.

Publishing Content from Maya and Rendering in Unreal

The tk-config-unrealbasic Pipeline Configuration includes a Publish hook for Maya that offers a full Maya-to-Unreal-to-ShotGrid asset review workflow that automatically performs the following actions when triggerd:

Exports the model from Maya as an FBX file.

Publishes the exported FBX to the ShotGrid database and on disk.

Imports the FBX file to an Unreal Editor template project for turntables.

Executes a real-time turntable render fo the model in Unreal Editor with Movie Render Queue.

Uploads the render to ShotGrid for review.



You can customize the Unreal Editor template project to meet the needs of your asset review requirements.

Debug Logging

The ShotGrid integration logs messages about everything it does to the Output Log in the Unreal Editor. These messages are logged with the LogPython category:



It also logs the same messages to the tk-unreal.log and tk-desktop.log files in the ShotGrid log folder for your platform. You can go straight to this folder at any time by choosing Open Log Folder from the ShotGrid menu.

These log messages can be useful for you to observe what tasks the integration is carrying out, and to diagnose problems or unexpected behavior. However, by default the integration logs messages at the most verbose level. If you want to reduce the number of messages printed to your Output Log, you can disable logging by choosing Toggle Debug Logging from the ShotGrid menu.

Before you Start

1 - Adding Unreal Engine Software to ShotGrid

2 - Set up the ShotGrid Project

3 - Set up the ShotGrid Project Configurations

Next steps



The process for setting up a ShotGrid project to work with Unreal Engine 5 is similar to the process for other applications in your content pipeline, such as Autodesk Maya or 3ds Max, or the Foundry's Nuke. You will configure your ShotGrid project to use a Toolkit engine: a collection of tools and scripts designed to make your ShotGrid project aware of Unreal Engine, and that integrate ShotGrid tools and workflows into the Unreal Editor interface.

The configuration outlined on this page is only done once for each ShotGrid project that you want to use with Unreal Engine, typically by a ShotGrid administrator. If you have already set up ShotGrid projects and configured them to integrate with other content creation tools, this process should be familiar to you. If not, refer to the following resources:

The Integrations User Guide gives a high-level overview of how to get started with ShotGrid integrations.

The Integrations Admin Guide describes more about pipeline configurations.

Before you Start

We recommend using the project configuration set up for you in the tk-config-unrealbasic repository on GitHub. This configuration extends the basic ShotGrid toolkit config with the elements that make up the Unreal integration. We also offer a second example project configuration in the tk-config-unreal repository that is equivalent to ShotGrid's default2 config.

To use this configuration from GitHub, you must have Git installed on your computer. If you don't already have Git installed, download it here.

Download and install the ShotGrid Desktop application from the Apps menu of your site.



1 - Adding Unreal Engine Software to ShotGrid

In this step, you'll add the Unreal Engine integration as new Software for your organization.

Log in to your organization's ShotGrid URL in a web browser. Then, from the user menu in the top right, select Software.



On the Software page, click Add Software.



Set the Software Name to Unreal Engine, and set the Engine to tk-unreal.



Click Create Software. When you return to the Software page, you should see a new entry in the list for Unreal Engine.



End Result

ShotGrid is now aware of the Unreal Engine integration. Follow the steps in the next section to make any of your organization's ShotGrid projects work with the Unreal Editor.

2 - Set up the ShotGrid Project

In this step, you will add a Pipeline Configuration to your ShotGrid project and deploy it using a distributed configuration. This shares the configuration to everyone on the project with access to the ShotGrid website. You can also set up a centralized configuration on disk, if desired, by following the instructions in ShotGrid's documentation.

To add a Pipeline Configuration to your ShotGrid Project:

Download the latest release of tk-config-unrealbasic as a .zip file from GitHub.



On your ShotGrid Site, open your project and navigate to Other > Pipeline Configurations.



On the Pipeline Configurations page, click Add Pipeline Configuration.



Set the Config Name to Primary, and set the Plugin Ids to basic.*.



Click Create Pipeline Configuration. When you return to the Pipeline Configurations page, you should see a new entry in the list for Primary.



Click in the Uploaded Config field, and select Upload File. Provide the .zip file that you downloaded from GitHub here.



End Result

Your ShotGrid project is now ready to use the Unreal Engine integration. The uploaded Pipeline Configuration will be automatically downloaded by each user from the site and installed by the ShotGrid Desktop. Subsequent updates to the configuration files inside of the .zip file will be detected and updated for each user if and when an administrator modifies the uploaded configuration.

3 - Set up the ShotGrid Project Configurations

In this step, you will install your Pipeline Configuration in ShotGrid Desktop and launch a ShotGrid-aware instance of Unreal Engine.

To install the Pipeline Configuration:

Open ShotGrid Desktop and click on the project you just uploaded a Pipeline Configuration for on the ShotGrid website.



When you click on the project, it detects the uploaded Pipeline Configuration and downloads it, along with all of the necessary ShotGrid components (engines, apps, and frameworks) from GitHub.



End Result

When the project setup is complete, ShotGrid Desktop scans your computer for installations of Unreal Engine and lists them on the Apps page for your project. Click on the icon to launch the latest available version or the dropdown to choose a specific one.



If you launch Unreal Engine from ShotGrid Desktop and open an Unreal Engine project that has the ShotGrid plugin enabled, you'll be able to use the ShotGrid integration as described on the [Using Unreal Engine with Autodesk ShotGrid](#using-unreal-engine-with-autodesk-shortgrid page.

Next steps

For more about how you can extend the toolkit configuration for your project, refer to Autodesk's Beyond Your First Project documentation.

For more about how to manage project configurations in ShotGrid, refer to Autodesk's Configuration staging and rollout documentation.

To see how the Unreal project configuration is set up, refer to the tk-config-unreal-basic repository.

To explore the implementation of the Unreal toolkit engine, including the Python hooks it uses and exposes, refer to the tk-unreal repository.

Console Variables List

Show Options

Search

Preset Search

Global Search

Presets

Multi-User

Plugin Settings

The Console Variables Editor is a panel that displays information about all the console variables set in the project, and provides a central location to view and modify all the variables. You can create presets to use the same console variables and values across multiple projects. The Console Variables Editor also supports controlling variables across multiple computers in a Multi-User session.



The Console Variables Editor plugin also adds Blueprint API for accessing and controlling console variable presets created in the Console Variables Editor. Refer to the Blueprint API Reference for more details.

To use the Console Variables Editor, enable the Console Variables Editor plugin in your project. Refer to Working with Plugins for steps on enabling plugins in a project.



In the main menu, choose Window > Console Variables to open the Console Variables Editor. You can dock this panel anywhere in Unreal Editor.



Console Variables List

The list contains all currently tracked console variables and executed commands. When you first open the Console Variables Editor, a blank preset is loaded with no console variables added. If Add All Changed Console Variables to Current Preset is set to True in the plugin settings, then you may see variables in the list already since console variables are often set through Project Settings.

To add console variables and commands to the list, click (+) Add Console Variable and search for a command or variable in the input box. As you enter text, a list appears below the text field showing matched console variable names, but console commands, such as stat unit, may not appear in the suggested list.

If the console variable you enter is valid, it then appears in the list. If you enter a console variable or command with a valid value, the command is executed with that value and the console variable appears in the list with its new value.



When you add a variable to the list, the current value is saved as the preset value. Each individual variable can be reset to its startup value or have its changes temporarily reverted by unchecking the row's checkbox.



You can remove a console variable from the list by hovering over the right side of its row and clicking Remove. When you remove the console variable from the list, its value is reset to the value it had when the plugin was loaded.



Hover over the console variable to see a tooltip with its description and what its values mean.



Each row in the console variables list has a group of cells in the order specified in the table below. You can sort the list by Sort Order Number, Console Variable Name, and Source by clicking on the respective column header.

Column

Description

Sort Order Number

The order the console variables are displayed in the list. You can drag and drop rows to change the order if you're sorting by this column.

If you sort by another column, you can update the sort order of the list to match by clicking Set Sort Order. Refer to Show Options for more details.

Checkbox

You can temporarily disable changes made to individual console variables by unchecking the row. When unchecked, the console variable's value is set to the value the console variable had when the plugin was loaded at startup.

When you recheck the row, the value is set to the last cached value before you unchecked the row. Changes made to the console variable while the row is unchecked are not reflected when you recheck the row.

Currently, only console variables can be toggled.

Console Variable Name

Displays the name of the console variable. If you hover over the name, you can see the help text for the console variable if it exists.

Value

An editable field for the console variable that matches the type of the variable or command.

When you change the value fields, the console command or variable is executed. If multi-user is enabled, users in the multi-user session will have these variables set to the updated value or have commands executed on their local machines.

Hovering over the variable's value shows the following three values:

Custom Value

Preset Value

Startup Value

If the current value of a variable is different from the preset value, the option to reset the value appears beside the value widget. When you click Reset, the variable is set to the preset value again.

Source

Describes the last method used to set the variable. If the last method was through the Console Variables Editor, the Source type is Console.

Show Options

Click Show Options to customize which rows appear in the list. Refer to the table below for descriptions of each option.



Option

Description



Show



Show Constructor

When enabled, shows any console variables that are set by a default constructor in code. That is, if an engine class starts up and sets a console variable.

Show Scalability

When enabled, shows any console variables set by Scalability options.

Show Game Setting

When enabled, shows any console variables set by UGameUserSettings(config=GameUserSettings).

Show Project Setting

When enabled, shows any console variables set by Project Settings.

Show System Settings ini

When enabled, shows any console variables set by System Settings.

Show Device Profile

When enabled, shows any console variables set by Device Profiles.

Show Game Override

When enabled, shows any console variables set by an override in game, such as a platform requiring a certain value to run properly.

Show Console Variables ini

When enabled, shows any console variables set in the Startup section of Engine/Config/ConsoleVariables.ini.

Show Command line

When enabled, shows any console variables set in Command-Line Arguments.

Show Code

When enabled, shows any console variables set by source code outside of a constructor, typically in a plugin.

Show Console

When enabled, shows any console variables set by you in a Blueprint, the CMD input, or the Console Variables Editor.

Show Only Modified

When enabled, shows any console variables whose current values differ from their preset value.



Sort



Set Sort Order

When selected, the current order of the console variables list is saved.



Options



Track All Variable Changes

This option is the same as Add All Changed Console Variables to Current Preset in the plugin settings.

Search

There are two types of searches: preset search and global search. Any text you enter becomes search tokens. Pipe characters separate text into OR tokens, and spaces combine text into AND tokens.

For example, if the text you enter is "lumen|screen percentage", then the search tokens are "lumen" and "screen percentage". The search returns results that either contain "lumen", or contain both "screen" and "percentage".

Preset Search

Preset search is the default option when searching. Any console variables in the preset, whose Name, Source, or help text doesn't match the search tokens, are filtered out of the list.



Global Search

You enable global search by clicking Search All after typing text in the search field. Any console variables in Unreal Engine, whose Name matches the search tokens, appears in the list. The search tokens you enter appear below the search field. Any matching variables will be shown as rows in the list and can be manipulated just like rows in a preset.



Toggle search tokens on or off by clicking them.



Right-click, or ctrl+click, tokens to remove tokens individually.



Click Remove to remove all search tokens and revert to preset search.



You can add a console variable from the global search list to your preset by hovering over the row and clicking Add CVAR when it appears in the row. If you enabled tracking all variable changes, then variables you change in this view are added to the current preset as well.



Presets

Open the Presets panel to save and load presets. When you load a preset, all variables in the current list are removed from the list but their values are not affected. All variables in the newly loaded preset are set to their saved values unless a given row is unchecked.



Multi-User

If you have the Multi-User plugin enabled in your project, the Multi-User option appears in the Console Variables Editor, and you can choose to propagate variable changes and command calls to other users in your session.

When you click Multi-User Controls, settings for Multi-User appear at the bottom of the Console Variables Editor. You can enable or disable console variables synchronization for individual session members from this control panel.



Plugin Settings

You can customize the functionality and display of the Console Variable Editor in the plugin settings under Project Settings > Plugins > Console Variables Editor. The table below describes all the plugin settings.



Setting

Description

Unchecked Row Display Type

Determines how values are displayed in an unchecked row's value input. The following are the display options for unchecked rows:

Show Current Value

Show Last Entered Value

Add All Changed Console Variables to Current Preset

When enabled, any console variables that are changed outside of the Console Variables Editor are added to the list. Only console variables will be tracked this way; commands will not be added when entering them outside of the Console Variables Editor.

Changed Console Variable Skip List

If Add All Changed Console Variables to Current Preset is enabled, any console variables listed here will be filtered out when they are changed outside of the Console Variables Editor.

Working with Gameplay Debugger

Debug Camera Controller

Basic extension

Custom categories

The Gameplay Debugger Tool (GDT) is useful for watching real-time data at runtime, even on clients in networked games using replication. It works in Play In Editor (PIE), Simulate In Editor (SIE), and standalone game sessions, and all of the data is displayed as an overlay on the game viewport. The system provides a framework that can be extended to enable debugging of game-specific data.

Unreal Engine implementation can show:

Basic data from Pawn

Basic data from AIController

Information about Behavior Tree and Blackboard data

Information about executed Environment Queries (EQS)

Information from perception system

Navmesh around player or selected Pawn with all details like links or areas

Usually there is a lot of data so GDT use categories to limit amount of information on screen. Data from only enabled categories is replicated which saves replication channel's bandwidth. There are 5 default categories and 5 categories to use by projects:



Navmesh

Basic

Behavior Tree

EQS

Perception

and 5 categories to use by projects

Existing categories can be extended to show more game-specific data too.

Below we have screen-shots captured on a client with a few enabled categories: Basic, EQS, NavMesh and Behavior Tree.



Gameplay Debugger can be activated with the apostrophe (') key by default or with EnableGDT cheat. Key binding is set in file and can be easily changed. To select an enemy for debugging press the apostrophe (') key while pointing to that enemy onscreen. Use the numeric keyboard to switch between visible categories. The GameplayDebugger module has to be added to project's dependency modules to be activated and usable.

Working with Gameplay Debugger

While working in the Editor, GDT can be used in PIE or in Simulate. A bound key or the EnableGDT cheat can be used to activate GDT in PIE. Simulate mode is little different from PIE; to activate this debug tool in Simulate you need to enable the Debug AI show flag. There is an option to change visible categories in Simulate too. The GameplayDebuggingReplicator Actor is used for that. This Actor can be found in the Scene Outliner, and this Actor's properties are used to control GDT.



Debug Camera Controller

The DebugCameraController also has the following features:

Orbit functionality - this allows you to orbit the camera around a selected position, or the center of a selected Actor, so you can review assets more thoroughly.

Buffer visualization overview - this gives you an option to select buffers for fullscreen view, and makes it possible to examine the contents of the graphic card buffers.

View mode cycling - this gives you the ability to examine the different types of scene data being processed.

The new features augment in-game debugging capabilities when you are using the Debug Camera Controller in Play-In-Editor (PIE). The ability to examine view modes and graphics buffers helps you diagnose unexpected scene results in-game.

To open the debug camera controller in PIE, enter ToggleDebugCamera on the console command line, or use the semicolon (;) hotkey.

Basic extension

Gameplay Debugger can be only extended with C++ code. For Blueprint projects it can only be used as-is to display basic debug information. It is easy to extend the Gameplay Debugger to collect and display game-specific data. To accomplish this, you need custom classes inherited from the UGameplayDebuggingComponent class and the AGameplayDebuggingHUDComponent class. The first class is used to collect and eventually replicate the data, and the second class is used to display all the collected data onscreen.

Below is a simple class which collects game specific data:

The next class is used to display new data on screen:

The Gameplay Debugger needs to know about new classes, and that information can be set in the DefaultEngine.ini configuration file.

Custom categories

A few more steps are needed to add a project-specific category to the Gameplay Debugger.

Let's extend the GDTComponent class.

Here we extend the HUD component, to display data in a new view.

Now the new category is ready, and it can be used to debug project specific data.



To draw debug information in colors, the PrintString function can use tags in strings, to change the active color. This makes it easier to draw strings with different colors.

The last PrintString function generates a string with 4 different colors.



The Oodle suite of cross-platform data compression solutions are now fully integrated with Unreal Engine. With Oodle, you can make games smaller to download, make levels load faster, and compress network packets for improved player experience.

There are three different Oodle solutions integrated into Unreal Engine:

Oodle Data

Oodle Network

Oodle Texture

Each Oodle solution can be enabled or disabled independently, using its own plugin. All three are enabled by default in Unreal Engine.



Refer to the individual pages for each Oodle solution for details on how to use them.



An overview of using Oodle Data to optimize delivering your package files to users.



An overview of using Oodle Network to improve streaming performance for your project.



An overview of using the Oodle Texture encoding solution to optimize textures in your project.

Packaging Projects

Key Concepts for Oodle Data

Compression Methods

Compression Level (Effort Level)

Enabling Oodle Data

Properties / Settings

Example Settings

Platform-Specific Exceptions

Oodle Data provides a compression format for .pak files and IOStore files. It is supplied as a plugin which should be enabled by default.



The parameters and settings for using Oodle Data with IOStore files are identical to those for .pak files in Unreal Engine.

When packaging, you will know you are using Oodle Data if you see a log similar to the following, with your specific settings listed for method and level:

Oodle v2.9.0 initializing with method=Kraken, level=3=Fast

In other contexts where you need Oodle Data to decode the packages files, you will see the following in the log:

LogPluginManager: Mounting plugin OodleData

Key Concepts for Oodle Data

Oodle Data exposes two controls for managing the output: The compression method and the compression level. It is important to understand the distinction between them:

The compression method trades off how small the data gets with how fast it is to decode.

The compression level determines how long it takes to encode the data.

The decoder at runtime never needs to know what method was used.

Compression Methods

There are four different compression methods available, representing different levels of compression and decode speed.

Method

Description

Kraken

High compression with good decode speed, the usual default.

Mermaid

Less compression and faster decode speed; effective when CPU usage is limited or on platforms with less CPU power.

Selkie

Even less compression and faster than Mermaid.

Leviathan

More compression and slower to decode than Kraken.

Compression Level (Effort Level)

Compression Level is a number between -4 and 9, representing encoding speed. Compression level values are referred to as follows:

Level

Name

Other Information

-4

HyperFast4

-3

HyperFast3

-2

HyperFast2

-1

HyperFast1

0

None

Just copies the raw bytes.

1

SuperFast

2

VeryFast

3

Fast

Good for daily use.

4

Normal

5

Optimal1

6

Optimal2

Recommended baseline optimal encoder.

7

Optimal3

8

Optimal4

9

Optimal5

Enabling Oodle Data

Due to various overrides, there are several different places where you need to enable and configure Oodle Data. The baseline method for enabling it is using the Packaging settings in the Project Settings window.

In the Project Packaging settings, you will have to expand the Advanced parameters to see these.



These settings can also be edited directly in your BaseGame.ini file under the [/Script/UnrealEd.ProjectPackagingSettings] header.

Properties / Settings

These are the relevant properties in the Project Packaging area, with the equivalent .ini file setting.

Property

.ini File Setting

Description

Create compressed cooked packages

bCompressed

When enabled, Unreal will compress output packages unless overridden.

Pak File Compression Format(s)

PakFileCompressionFormats

Sets the list of compression formats. Set it to Oodle to use Oodle Data.

Pak File Compression Commandline Options

PakFileAdditionalCompressionOptions

Specifies additional options to pass to the compression format. For Oodle, we recommend this be set to -compressionblocksize=256KB.

Use this Compression Format not hardware override

bForceUseProjectCompressionFormatIgnoreHardwareOverride

If set, the HardwareCompressionFormat in the DataDrivenPlatformInfo.ini file will be ignored, and these settings will be used. So, you could set things up using the above settings, use HardwareCompressionFormat to ignore them, and then ignore THAT with this setting, getting back to where you started.

Pak File Compression Method

PakFileCompressionMethod

Specifies the compression method as previously described (for example, Kraken).

Encoder Effort Level for Debug & Development

PakFileCompressionLevel_DebugDevelopment

Specifies the amount of time to spend encoding. This is a number from the previously-described Compression Level settings (3 by default).

Encoder Effort Level for Test & Shipping

PakFileCompressionLevel_TestShipping

Specifies the amount of time to spend encoding. This is a number from the previously-described Compression Level settings (5 by default).

Encoder Effort Level for Distribution

PakFileCompressionLevel_Distribution

Specifies the amount of time to spend encoding. This is a number from the previously-described Compression Level settings (7 by default).

Example Settings

In your BaseGame.ini file, this is a representative set of settings:

Platform-Specific Exceptions

If a given target platform supports hardware data compression, it is likely exposed in the DataDrivenPlatformInfo.ini file in the platform's configuration directory, for example:

However, if you want to bypass the hardware data compression and use Oodle Data anyway, you can set bForceUseProjectCompressionFormatIgnoreHardwareOverride=True in the platform's (Platform)Game.ini file settings.

This will cause the packaging for the target platform to use Oodle Data, rather than the (in this example) hardware zlib.

Networking and Multiplayer

Setting Up Oodle Network

Enabling Oodle Network

Capture Packet Data

Training

Configuring

Packaging

Oodle Network exposes a compression system for network streams. Integrating this into your project is a bit more hands-on compared with other Oodle solutions, requiring packet captures, familiarity with BaseEngine.ini, and offline ‘training' of the compressor. It uses the offline training step to dramatically speed up the compression time.

Setting Up Oodle Network

The following is a summary of the steps necessary to use Oodle Network:

Verify the Oodle Network plugin is enabled.

Capture packet data of your online gameplay, using the most realistic data possible.

Train the compressor, creating dictionary files for use at runtime.

Configure Oodle Network to use those files.

Ensure those files are packaged with your game.

More information about these steps is available in the sections below.

Enabling Oodle Network



The plugin itself should be enabled by default, and you should see that noted in the startup log:

LogPluginManager: Mounting plugin OodleNetwork

However, you need to tell Unreal Engine to use this plugin when working with network streams. To do this, you need to edit your BaseEngine.ini file, in four places:

BaseEngine.ini

Those variables will cause Unreal Engine to use Oodle Network for network streams. The first three entries specify the component for the relevant Net Drivers. If no components are specified for a given Net Driver, then Unreal Engine checks the PacketHandlerComponents section.

When debugging, you may need to connect an actual client to do any code-level debugging, as packet handlers are only created on active connections.

Additionally, Oodle Network will look for the following BaseEngine.ini file block for configuration:

BaseEngine.ini

Setting

Description

bEnableOodle

When set to false, Oodle will not compress any data.

PacketLogFile

This defines the prefix for the filename to write out when capturing packet data.

ServerDictionary

The path to the server-side dictionary file created from the training step. This file needs to be included when packaging your game.

ClientDictionary

The path to the client-side dictionary file created from the training step. This file needs to be included when packaging your game.

ServerEnableMode

Provides a way to conditionally disable compression for certain memory constrained platforms. Options:

AlwaysEnabled: Self-explanatory; Oodle Network is always enabled when you set this option.

WhenCompressedPacketReceived: When you set this option, the server-side dictionary is not initialized unless a compressed packet is received.

ClientEnableMode

Provides a way to conditionally disable compression for certain memory constrained platforms. Options:

AlwaysEnabled: Self-explanatory; Oodle Network is always enabled when you set this option.

WhenCompressedPacketReceived: When you set this option, the client-side dictionary is not initialized unless a compressed packet is received.

Capture Packet Data

Packet capturing is done by playing your game with Oodle Network enabled in a special mode. This playthrough should be representative of typical play, as the quality of these packet captures affects the quality of the compression you get.

Whichever executable is acting as the server should be run with -OodleCapturing:

UE4Editor.exe ShooterGame -game **-OodleCapturing** -windowed -log

Clients should be connected without -OodleCapturing:

UE4Editor.exe ShooterGame -game -windowed -log

Packet captures are written to the Saved/Oodle directory for the project and configuration. You need to collect many packet captures (50 MB or more) to create a properly representative data set for training. Training takes place using all the packet captures in a directory.

Training

The Oodle Network trainer is a commandlet that reads all of the packet captures and creates dictionaries out of them. These dictionaries are used for compressing the network streams between server and clients.

This is the command to run the trainer commandlet:

The default dictionary size is 4MB and can be overridden with the -DictionarySize=(size in bytes) command line option.

The trainer reads the packet captures from the same directory that Oodle Network writes them to, and writes the resulting dictionaries to the Content/Oodle directory:

A log will report the compression rates achieved with the generated dictionaries:

At this point, training is complete.

If your game changes patch to patch in appreciable ways, you need to retrain Oodle Network on new packet captures, and release new dictionaries with the patch.

Configuring

The server-side and client-side dictionaries should be specified in the BaseEngine.ini file:

Once configured, you should be able to use the stat OodleNetwork command and view the real-time compression rates in games where stats are enabled.

Packaging

As long as Oodle Network is enabled for your target platform, the dictionary files should be automatically included. You can confirm this by listing the contents of your pak file and searching for the relevant entry:

If you get an error retrieving an encryption key, try packaging with -skipencryption for this test.

Texture Format Support and Settings

Enabling Oodle Texture

Key Concepts for Oodle Texture

Understanding RDO

Understanding Lambda

Configuring Oodle Texture

Global Configuration

Configuring Texture LOD Groups

Configuring Individual Textures

Oodle Texture provides fast, high quality encoding of textures to the various BCn/DXTn formats. Once Oodle Texture is configured it will operate automatically in the background. You can set Oodle Texture globally, and then define it more specifically for LOD groups and individual textures.

Oodle Texture does not encode ASTC or other mobile formats.

Enabling Oodle Texture

The plugin for Oodle Texture is enabled by default in Unreal Engine.



In addition to the plugin, Oodle Texture requires a setting in the DefaultEngine.ini file.

As Oodle Texture is enabled by default in Unreal Engine, these lines should already be present in your BaseEngine.ini file.

We strongly recommend leaving bEnableInEditor=true to maintain consistent behavior between the editor and packaged builds. If set to false, artists reviewing encoding results in the Editor will see different results than the cook system produces. You can verify Oodle Texture is enabled by examining the log:

LogTextureFormatOodle: Display: Oodle Texture 2.9.0 init RDO On with DefaultRDOLambda=30

When Oodle is used for a given texture, the format will contain the prefix OODLE_:

LogTexture: Display: Building textures: test (OODLE_AutoDXT, 256X256)

Key Concepts for Oodle Texture

There are two concepts you need to understand in order to make use of Oodle Texture: RDO (Rate Distortion Optimization) and Lambda.

Understanding RDO

RDO is a term that refers to trading quality (distortion) for size (rate). For texture encoding, this sounds odd — DXTn/BCn textures do not vary in size with quality, they are a fixed size based on the format, resolution, and mip count.

Oodle Texture optionally expose a way to manage the resulting encoded texture data so that when a uasset containing a texture is compressed for distribution via the IOStore / .pak file system, it compresses smaller. Thus, RDO in Oodle Texture only reduces distribution sizes.

Additionally, it is tuned to work with the Kraken compression format. Refer to Oodle Data for more information.

Understanding Lambda

The parameter that determines how much distortion is introduced, and thus how much smaller the resulting file is, is referred to as lambda.

Lambda can be set between 0 and 100, with lower numbers representing lower distortion, and therefore higher quality results. A lambda value of around 30 still produces high quality results. A lambda value of 0 disables RDO entirely, resulting in the theoretical best quality. However, even when seeking best quality, we recommend using a lambda value of 1 as the cost / benefit ratio is still very good, resulting in very little distortion for reasonable distribution size gains.

Generally speaking, we expect lambda to be set globally and not often overridden. Determining a value appropriate for your project will be a collaborative effort based on distribution size needs. It is best to have your global lambda be your highest value (lowest quality) one, and selectively set higher quality / lower lambda on LOD groups or specific textures, as needed.

Textures other than diffuse / albedo maps will likely require a lower lambda (usually 5-20), especially normal maps, as distortion that is not visible to the naked eye can be more noticeable with textures like specular highlights.

Configuring Oodle Texture

Oodle Texture is primarily configured using the DefaultEngine.ini file, but also exposes lambda on texture LOD groups and on a per-texture basis.

Global Configuration

The TextureFormatOodle section in the DefaultEngine.ini file contains the global settings for Oodle Texture.

Setting

Definition

DefaultRDOLambda

This is the RDO lambda that will be used if not set anywhere else.

GlobalLambdaMultiplier

This scales the lambda passed to the encoder. It is provided as a last-minute control to manage distribution sizes without having to chase down individual textures or LOD groups. The value is directly applied to the lambda, meaning a multiplier value greater than 1 adds distortion and reduces quality, and a multiplier value between 0 and 1 reduces distortion and adds quality. The result is rounded to the nearest integer for use. This can not disable RDO (the result will be at least 1).

bForceAllBC23ToBC7

When enabled, any time a BC2 or BC3 (i.e. DXT3 and DXT5) format is requested, Oodle will compress a BC7 texture instead. BC7 is usually better quality, but depending on your minimum specifications might not be available.

bForceRDOOff

When enabled, RDO will be disabled at all times, independent of any texture-specific RDO setting.

bDebugColor

When enabled, textures will be compressed as a solid color representing their encoded format for visual identification.

Format

Color

BC1

Red (0xff0000)

BC2

Dark Green (0x008000)

BC3

Green (0x00ff00)

BC4

Dark Yellow (0x808000)

BC5

Yellow (0xffff00)

BC6

Purple (R = .5f, G = 0.0f, B = .8f)

BC7 (Opaque)

Dark Blue (0x8080ff)

BC7 (Transparent)

Blue (0x0000ff)

Configuring Texture LOD Groups

The LOD Group parameter representing RDO lambda is called Lossy Compression Amount. This parameter is defined for LOD groups in the DefaultDeviceProfiles.ini file.

Lossy Compression Amount can take the following values:

Value

Description

TLCA_Default

If set on a texture, inherit from the LOD group. If set on an LOD group, inherit from DefaultRDOLambda.

TLCA_None

Disable RDO (0)

TLCA_Lowest

5 - Best quality, largest file size.

TLCA_Low

15

TLCA_Medium

30

TLCA_High

40

TLCA_Highest

60 - Worst quality, smallest file size.

Configuring Individual Textures

RDO Lambda can also be set for individual textures using the Lossy Compression Amount parameter, and takes the same values shown above.

To set the parameter for a single texture:

Double-click the texture you want to set RDO Lambda for in the Content Browser to open it in the Texture Editor window.

In the Details panel, expand the Compression section and click the arrow icon to show the Advanced options.



Use the dropdown menu next to the Lossy Compression Amount parameter to select the desired value.



Terminology and Supported PSO Types

PSOs on Different Platforms and Graphics APIs

Collection Flow

Partitioning the Cache

Controlling PSO Compilation

User Cache File

Q&A

Earlier graphics APIs, such as Direct3D 11, needed to make dozens of separate calls to configure GPU parameters on the fly before issuing draw calls. More recent graphics APIs, such as Direct3D 12 (D3D12), Vulkan, and Metal, support using packages of pre-configured GPU state information, called Pipeline State Objects (PSOs), to change GPU states more quickly.

Although this greatly improves rendering efficiency, generating a new PSO on-demand can take 100 or more milliseconds, as the application has to configure every possible parameter. This makes it necessary to generate PSOs long before they are needed for them to be efficient.

In a highly programmable real-time rendering environment such as Unreal Engine (UE), any application with a large amount of content has too many GPU state parameters that can change to make it practical to manually configure PSOs in advance. To work around this complication, UE can collect data about the GPU state from an application build at runtime, then use this cached data to generate new PSOs far in advance of when they are used. This narrows down the possible GPU states to only the ones used in the application. The PSO descriptions gathered from running the application are called PSO caches.

The steps to collect PSOs in Unreal are:

Play the game.

Log what is actually drawn.

Include this information in the build.

After that, on subsequent playthroughs the game can create the necessary GPU states earlier than they are needed by the rendering code.

This document describes the available PSO types in UE and the detailed processes for generating PSO caches.

Terminology and Supported PSO Types

This document universally refers to GPU state with the term Pipeline State Object (PSO), a name used in D3D12 API. Other APIs use slightly different names. For example, Vulkan uses pipeline, and Metal uses pipeline state. However, conceptually they all are similar.

The term PSO Cache refers to a file with PSO descriptions that is included in the build, so the game can create these states early. In other words, PSO caches are lists of PSOs to create early.

Unreal Engine supports two types of PSOs:

Graphics PSOs, which represent the state of the application's graphics pipeline and consist of many configurable variables.

Compute PSOs, which usually take the form of compute shaders.

In addition to the above PSO types, ray tracing PSOs also exist, but UE 5.0 does not support PSO caching for ray tracing data.

Most information in this document concerns Graphics PSO collection. Compute PSOs are included in the build differently (all compute shaders in the shader library will automatically have PSO entries created for them during the cook).

Recorded Caches and Stable Caches

The most important data in a PSO is shader information. However, shaders in Unreal can change between multiple builds as developers tweak materials. To avoid throwing out entire PSO caches after a long playthrough of an application, PSO cache files are divided into two varieties:

.upipelinecache files, or recorded PSO caches. These are recorded when running a build of your application.

Shaders in recorded caches are identified by the SHA hash of their bytecode.

.spcfiles, or stable PSO caches. These are generated when cooking map files, and contain shader information that will predictably change when developers change maps or shaders in the project.

These are identified by stable, high-level descriptions that are expected to stay the same between multiple builds, such as a material name, a vertex factory name, or a shader type. This description is called a stable key, and is represented by a .shk file (previously .scl.csv).

This ensures that recorded data is relatively robust against frequent changes. While you may still need to re-record PSO caches if there are extremely large-scale changes to your application, you can leave them alone once your application's overall content is finalized.

PSOs on Different Platforms and Graphics APIs

The cache described in this document contains high-level PSO descriptions, which in the engine's code maps to FGraphicsPipelineStateInitializer. However, PSO data is not universal. Each Rendering Hardware Interface (RHI) in Unreal Engine has different properties and may execute different rendering paths.

This results in the contents for PSO caches varying between different platforms and rendering levels. Information between these PSO caches is not interchangeable. For example, the cache collected with a game running with D3D12 RHI is not usable for the same game running on Vulkan.

If you are shipping on a platform that can use more than one graphics API, and you make it possible for your application to choose between them, you will need to include more than one cache file (one per API) in the build. For example, on Android, OpenGL ES remains a relevant API at the time of writing. If you ship an application on Android with both GLES and Vulkan, you need to collect and include two separate cache files, one for each RHI.

GLES does not have a concept of PSO. Instead, it uses a similar concept called a program object.

Platforms with fixed hardware usually neither need nor benefit from this higher-level PSO cache – they either have their own solutions or are able to avoid the runtime performance penalty altogether. Refer to the particular platform's documentation if developing for such a platform.

Legacy API like D3D11 are also not supported by this cache.

Collection Flow

This section assumes that you begin collecting data for a PSO cache from scratch, with a build that has no pre-recorded cache included in it. The collection process for PSO caches is iterative, meaning that rather than starting from a clean slate, you can add to it over time without losing previous data. However, it is usually a good idea to regenerate your PSO caches if the cache files are old, as their contents may not be relevant after substantial code or content changes since they were originally collected.



The sections below contain the steps needed to collect PSO caches and implement them in your project.

1. Setup and Required Settings

The following steps will set up your project to record PSO caches.

Open the project's DefaultEngine.ini or its (Platform)Engine.ini.

The (Platform)Engine.ini file is usually located in the (Project)/Config/(Platform) directory. Using this directory prevents other platforms that may not need the PSO cache from picking up the setting.

Set the following value in your Engine.ini file:

In your DefaultGame.ini file, set the following values:

If you're starting from scratch, make sure there are no files in (Project)/Build/(Platform)/PipelineCache. This is the location where the cooker finds recorded cache files. This folder may not exist at all if this is the first time you collect PSOs.

Make sure the CVar r.ShaderPipelineCache.Enabled is set to 1.

2. Collecting Recorded PSO Caches

To record PSO caches, follow these steps:

Run the packaged application with the -logPSO command line switch.

Execute as many paths in the application as possible. For example, play through all of your application's levels and change your graphics settings.

Each time you run your application, it will produce recorded cache files (rec.pipelinecache) under Saved/CollectedPSOs. Collect them and put them in a new directory anywhere on your computer. This guide uses the directory C:\PSOCache.

When collecting recorded PSO caches, your end goal is to see every possible material or visual effect that a user can see in your application, so you should be thorough in visiting as many locations as possible and doing so with many different combinations of graphics settings.

You do not need to collect all of your PSO caches in a single run. You can perform multiple runs over the course of developing your application, or you can split this task among multiple people. Recorded PSO caches will not be removed until you do so manually, so you can gradually accumulate them during development.

3. Converting PSO Caches (also known as expansion)

To convert your PSO data from the previous steps into a useful format, follow these steps:

Cook your project's content. You can do this by packaging your application.

Open (Project)/Saved/Cooked/[Platform]/[ProjectName]/Metadata/PipelineCaches. Copy the stable shader key (.shk) files from this directory into the folder where you put your rec.pipelinecache files. For example, C:\PSOCache.

Run the ShaderPipelineCacheTools commandlet using the arguments below (assuming your current directory is the engine installation directory):

The filename you provide should be constructed of the following:

[YourPrefix] – An arbitrary string, usually designating the moment of time when the collection happened. For example, this could be the changelist of a current build.

[ProjectName] – The name of your project. For example: ShooterGame. This must match your project's name exactly or else it won't be picked up.

[ShaderFormatName] – The shader format for your project, which must match the shader format's name exactly. For D3D12 this is PCD3D_SM5.

A full name for the project ShooterGame using the above conventions would be as follows: CL11122333_ShooterGame_PCD3D_SM5.spc

4. Including PSO Caches in Your Application

Place your .spc file produced in the previous section into the Build/[PlatformName]/PipelineCaches folder. For example: Build/Windows/PipelineCaches.

Cook or package your project again. Your PSO cache files should be picked up by the cooker, and your log should include something like the following near the end:

To verify this worked, check the line that shows the number of binary PSOs written, which is written at the very end of the log. The number of graphics PSOs on this line must be greater than 0.

5. Testing PSO Coverage

To determine whether your PSO cache has sufficient coverage, run the newly packaged application with the -logpso command and observe the log output. You should see lines similar to the following:

The number must agree with the number of binary PSOs written in the packaging log. For example, if the log reported that it wrote 35381 binary PSOs, expect to see 35381 entries.

You should also check if the build prints "Encountered a new graphics PSO" in the log. This should not be happening if you are seeing the same content under the same conditions (for example, the same scalability settings) as during the collection of the cache.

Partitioning the Cache

As of this writing, the resulting PSO cache is a single monolithic file that is included with the game build. The default behavior of the game is to attempt to open it on start and begin compiling PSOs from it. However, not all PSOs are relevant at all times. For example, some may have been collected from a different level, and some were recorded with different graphics settings.

To avoid compiling all of them needlessly, each PSO is currently associated with a bitmask called a game usage mask. The application can use the SetGameUsageMaskWithComparison function to avoid compiling PSOs recorded on a different level or with different graphics (quality) settings. The following is an example of such a function:

If there are more than 60 maps in game or you want to encode more granular quality settings, you can generate the mask differently, like treating uint64 as the structure of several bitfields, and then using a custom comparison function to compare them. For example:

This function needs to be set by the application early during startup, such as when loading/saving user settings (UGameUserSettings). It is used in each of the following cases:

During the recording process – recorded PSOs will be associated with the current usage mask.

During compilation – only PSOs matching the current usage mask will be compiled from the cache.

Since the compilation starts very early, you may want to default to starting it paused (see below) and re-enabling explicitly after the correct mask has been set.

Limitations and Future Work

Currently, the concept of masks inherently relies on manual collection. By contrast, Compute PSOs, which are added to the cache automatically during the cook, all have masks of 0xffffffffffffffff (all 1s). Implementing programmatic population of the PSO cache means applying automatic caching to (some) graphics PSOs as well, and the user mask concept may evolve into a different approach or be retired altogether.

If your game content is split into multiple downloads, it is hard to split the PSO cache into chunks to correspond to independent bundles of content (this document does not cover splitting the cache, refer instead to Cooking and Chunking).

Controlling PSO Compilation

PSOs included in the cache need to be compiled so they are ready when the rendering code needs them. In a new project using default settings, a bundled PSO cache file is opened automatically after the application starts, and compilation starts automatically. If this is not desirable (for example, because you need to set a custom usage mask), you can pause the compilation using r.ShaderPipelineCache.StartupMode=0 and later resume it with FShaderPipelineCache::ResumeBatching().

There are several Startup Modes that you can use when compiling PSOs:

Value

Mode

Description

0

Paused

Compilation is suspended until resumed.

1

Fast

Using Fast mode is recommended during the loading screens or otherwise non-interactive parts of the game

2

Background

Background mode is more suitable for compilation while the player is navigating the UI.

3

Precompile

Combines properties of both Fast and Background. Uses a separate precompile usage mask (configured with r.ShaderPipelineCache.PreCompileMask) to compile PSOs that match it in the Fast mode, but uses Background mode for the rest (that only match the regular usage mask).

You can also query the number of outstanding PSOs to compile by calling FShaderPipelineCache::NumPrecompilesRemaining() if the game wants to keep the loading screen for longer, until the compilation is complete.

Modes have more fine-grained settings, which means you can set the size of a batch taken for the precompilation all at once and the target time to spend precompiling per frame. The actual time it takes to compile a PSO is out of the game's control.

User Cache File

Even if you provide the PSO cache with the game, the user can run into content not covered during the collection. Some drivers can provide their own cache, but to be more independent from driver behavior, the game by default attempts to collect and save missed PSOs to local user cache files. These are located in the game's Saved directory ( FPaths::ProjectSavedDir() ), the same directory as for the game's user settings. The application loads those user cache files on start and merges their contents with the files included in the build.

User cache PSO files are in recorded cache format. This means they reference the shaders using their SHA hashes, and won't be usable across large game updates that change a lot of content. Because of that, each file embeds a game version, which is checked against the running application. It is configured in DefaultGame.ini, as in the example below, and needs to be increased each time the application issues a possibly incompatible update, such as an update that contains content changes or significant rendering code changes.

By default, GameVersion is taken from the EngineVersion, which in turn usually closely tracks Perforce changelists, making user caches written by any two different builds incompatible (even without relevant changes).

To prevent the cache file from growing indefinitely large, the application "garbage collects" entries in it immediately upon loading. This is based on the last used time of an entry and is configurable via a CVar r.ShaderPipelineCache.UserCacheUnusedElementRetainDays (the default value is 30 days).

Vulkan and OpenGL ES RHIs have their own, lower-level pipeline cache inside the RHI. After a PSO is compiled (whatever the source - cache or creation by the code) it will be saved into that cache and picked up on the next start. There may be no need to enable the user cache file when using those graphics APIs.

Q&A

How often do I need to collect PSOs?

Ideally, you should re-capture your project's PSO data each time content is added, updated, or changed in a significant way. However, in practice, this is not possible due to the rapid pace at which development happens. Since each project has different PSO collection requirements, establishing a rigid schedule is not possible. A rule of thumb is that you need to update the PSO cache if you feel your build has started hitching often. In particular, never measure the performance of a build that does not have an up-to-date cache, or at least don't use those measurements in comparisons.

Do I need to make special PSO caching levels?

While you can capture all needed PSO data from your project's standard levels, some projects may benefit from creating special PSO capture levels. These levels can be set up so they spawn all assets of a particular type and then capture their PSO data. This is especially true if your project has content that takes time to unlock or is dynamically spawned.

I haven't collected any PSOs, but my build has a PSO cache!?

If you have Niagara content, this is expected. Compute PSOs are added to the cache automatically during the cooking process (if you enabled the cache for the project).

I have a PSO cache in my build, but the game still hitches.

First, verify the following:

The game is running on a graphical API that is supported by the cache (For example, D3D12, but not D3D11),

The file is opened at the start of your game.

The right PSOs are being compiled in the background.

To do this, examine the log file and look for the LogRHI logging category. You should see lines like this:

The number of entries and tasks will vary, but it should not be 0.

Second, check how many new PSOs are being found. For that, run the build with the -logPSO command line switch (or with the user cache file enabled), and see how often you encounter a line like this:

The number given after PSO: will vary. If you see a substantial count and their appearance coincides with the hitches, there is likely a problem with your cache. Please collect the cache again on the current content. You may even need to start from scratch.

If you do not have these lines, or you are running on D3D11, but your build is still hitching, the hitches may not be directly PSO related. In that case, we recommend profiling the game with a CPU profiler to understand the nature of the hitches.

Setup

Significance Manager Base Functionality

RegisterObject / UnregisterObject

GetSignificance / QuerySignificance

Update

Project-Side Functionality

FSignificanceFunction

FPostSignificanceFunction

Meeting performance targets for a shipping game generally includes reducing scene complexity in order to meet the target resolution or frame rate. Level-of-detail systems for geometry, animation, and even audio are commonly used, but there are some cases where these distance-based, per-Actor methods are not sufficient. This is especially true in the case of multiplayer games with high numbers of players or AI-controlled characters that can converge in a single area.

The Significance Manager provides a centralized framework that supports the ability to write flexible, project-specific code for evaluating and prioritizing Objects relative to one another. Using this evaluation, Objects can modify their behavior by doing things like shutting off Components like Particle Emitters, or by running complex AI code less frequently.

The Significance Manager itself does not actually improve performance; rather, it provides a system that can be overridden and customized to suit your project's specific needs.

Setup

Because the Significance Manager exists within a Plugin, it must be enabled in the Edit > Plugins menu, and its Module must be added to your project's *.Build.cs file.



The Significance Manager is located in the Programming section of the Plugins menu.

After enabling the Significance Manager Plugin, you may need to restart the Engine.

With the Plugin enabled, add "SignficanceManager" to PublicDependencyModuleNames in your project's *.Build.cs file. The following example line comes from the "Basic C++" project template, modified to use the Significance Manager:

Significance Manager Base Functionality

The Significance Manager Plugin contains a single class, USignificanceManager, which acts as an extensible framework for evaluating the "significance" of managed Objects. These Objects can then adjust their behavior in custom ways to decrease their impact on performance based on their significance values. The specific behaviors that will result in improved performance are custom-defined by the Objects themselves in game code. For example, an Actor that plays a subtle audio cue or particle effect might opt not to do so in the event that it has a low significance value. A more advanced use case might involve grouping similar Actors together and enacting a per-Actor-type budget. One possible use for this would be to ensure that Player-controlled Pawns always run at high detail when they're close to the camera, and then compensating for cases where several players are clustered around the camera by limiting the number of AI-controlled Pawns running at high detail accordingly.

RegisterObject / UnregisterObject

Objects can be registered with the Significance Manager and will be grouped together with other registered Objects based on a user-designated name. The registration process includes the ability for users to specify the functions used to evaluate the significance of the Object, and the optional function that will be run after the evaluation has been made. During registration, the Object's initial significance will be calculated with the Transforms used in the most recent call to the Significance Manager's Update function, if possible.This also provides an opportunity to perform higher-level processing, such as building internal data structures based on the list of known, registered Objects (perhaps different lists for different types), which can be helpful if your game implements category-based budgets for different types of Objects.

GetSignificance / QuerySignificance

These functions report the cached significance value of an Object. If the Object is not registered with the Significance Manager, that value will be zero. The QuerySignificance function, unlike GetSignificance, will also indicate that the Object is not registered by returning false.

Update

This function takes an array of Transforms and evaluates each managed Object for significance based on each Transform, using the significance function associated with the Object. The final result will be the highest value returned (lowest if bSortSignificanceAscending is set to true). This function can be overridden to suit the needs of the game, for example, by implementing new pre- or post-processing steps to the system. After evaluating an Object's significance, its Post Significance Function will be called, if one has been specified. This function will be called immediately if the Object's Post Significance Type is Concurrent. If its type is Sequential, it will be called in order, from most significant to least, with all other managed Objects using Sequential post-updates. If no Transforms are supplied, the significance value will be zero.

Significance-evaluation and post-significance-evaluation functions run in parallel, which adds the requirement that these functions be thread-safe. Post-significance-evaulation functions can avoid this requirement by running sequentially (see the FPostSignificanceFunction section below for details).

The Update function does not run automatically. In most cases, developers will want to call it every frame, and only once per frame. A good place to call it might be in an overridden version of UGameViewportClient, as demonstrated in the following code:

Project-Side Functionality

The Significance Manager only provides the framework for determining the significance of an Object, leaving the actual calculation to be defined by the project. When you register an Object with the Significance Manager, you also register functions matching the following types:

FSignificanceFunction

FPostSignificanceFunction

These functions will be called on the Object during Significance Manager updates.

FSignificanceFunction

This is the primary evaluation function that you must write in order to use the Significance Manager. It takes an Object parameter and a single Transform, and calculates the significance of the Object, which it returns as a float. During the Significance Manager's update process, this function will be called once for each Transform that was passed in. The final result will be determined by the Significance Manager's Update function; by default, it will be the highest value. Each registered Object is required to be associated with a function of type FSignificanceFunction when it is registered.

FPostSignificanceFunction

A function of this type will be supplied with the Object itself, its old significance value, its new significance value (unless the Object is being unregistered, in which case this value is one), and a bool indicating whether the Object is currently being unregistered. Unlike the significance-evaluation function, this has no return value. It is provided as a way for the game to handle changes to the Object's significance or place in the overall order of managed Objects. The Significance Manager will call this function based on how the Object was registered, as follows:

Post Significance Type

Behavior

None

Function is expected to be null. No post-significance-evaluation callback.

Concurrent

Function is expected not to be null, and will be called immediately upon evaluating the Object's significance. Functions called this way must be thread-safe, as they will run in parallel.

Sequential

Function is expected not to be null, and will be called in sorted order with other Sequential Objects after all are evaluated for significance.

The requirement for thread-safe code is waived in this case.

Stats System Overview

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Play In Editor Settings

Stat Command Table

Select Commands

Levels

StartFile

StopFile

Unit

To profile their Unreal Engine (UE) projects, developers can enter the following stat commands into the console while running their game in Play In Editor (PIE) mode.



Click for full image.

To locate a stat command from the Editor's Stat menu, select the dropdown arrow next to the Viewport Setting button.



Click for full image.

Running the editor with the LOG command enables developers to record useful information from a stat dump, and to do so, enable the editor (game project) to generate a log file by running it with the LOG command (for example, UnrealEditor.exe -silent LOG=MyLog.txt).

Stat Command Table

Type stat followed by a space and any of these commands to activate them:

Command Name

Command Description

AI

Displays Perception System and Overall AI performance information.

AI_EQS

Displays performance, debug, and memory statistics for the Environment Query System (EQS).

AIBehaviorTree

Displays performance and memory statistics for Behavior Tree.

AICrowd

Displays performance and step information for the Crowd Manager.

Anim

Shows how long skinned meshes are taking to compute per tick.

AsyncLoad / AsyncLoadGameThread

Displays Async loading performance statistics.

Audio / AudioThreadCommands

Audio statistics, such as wave instances or buffer performance.

Canvas

Canvas statistics, showing performance information for Canvas user interface items, such as tiles, borders, and text.

Collision / CollisionTags

Displays performance, debug, and memory information for collisions.

CommandListMarkers

Displays a list of commands with their performance information.

Component

Displays a list of components with their performance information.

Compression

Displays compression statistics.

CPULoad

Shows CPU utilization.

CPUStalls

Shows information about CPU stalls.

D3D11RHI

Displays Direct3D 11 RHI statistics.

DDC

Displays Derived Data Cache (DDC) statistics.

DumpHitches

Anytime a "hitch" is detected based on t.HitchFrameTimeThreshold, it will be written to the log.

Dumpticks

Dumps info about tick functions.

Engine

Shows general rendering stats like frame time as well as counters from the number of triangles being rendered.

FPS

Displays Frames per Second (FPS) counter.

Game

Gives feedback on how long the various Gameplay Ticks are taking.

GameplayTags

Displays Gameplay Tag information.

GC

Displays garbage collection statistics.

GeometryCache

Shows performance and memory statistics for the Geometry Cache system.

GPU

Displays GPU statistics for the frame.

GPUParticles

Displays performance information for GPU particles.

Help

Lists all stat commands.

Hitches

Set t.HitchFrameTimeThreshold to define the time in seconds that is considered a hitch. Will also dump all hitches to the log/visual studio debug, for example [0327.87] LogEngine:Warning: HITCH @ 00m:01s:643ms,1643,72,2.

IMEWindows

Displays information for the Windows Text Input Method System.

InitViews

Displays information on how long visibility culling took and how effective it was. Visible section count is the single most important stat with respect to rendering thread performance, and that is dominated by Visible Static Mesh Elements under STAT INITVIEWS; however, Visible Dynamic Primitives also factors in.

KismetCompiler

Displays Kismet Compiler information.

KismetReinstancer

Displays Kismet Reinstancer information.

Levels

Displays Level Streaming information.

LightRendering

Gives feedback on how long lighting and shadows are taking to render.

LinkerCount

Displays Linker counter.

LinkerLoad

Displays Linker Load information.

List

Display groups of statistics or saved sets or statistics within a specified group with usage <Groups/Sets/Group><br>.

LLM

Displays Low Level Memory Tracker (LLM) counters.

LLMFull

Displays full group of LLM counters.

LLMOverhead

Displays LLM overhead counters.

LLMPlatform

Displays LLM platform counters.

LoadTime / LoadTimeVerbose

Shows load time performance information.

MapBuildData

Displays the map's build data.

MathVerbose

Shows performance information of math operations.

Memory

Shows statistics on how much memory is being used by various subsystems in Unreal Engine.

MemoryAllocator

Shows memory allocation information.

MemoryPlatform

Shows memory platform information.

MemoryStaticMesh

Shows memory statistics about static meshes.

NamedEvents

Enables named events for external profilers.

Navigation

Shows performance and memory information for the navigation system.

NET

Displays networking system statistics.

Object / ObjectVerbose

Displays object memory and performance information.

Online

Shows online system counters.

Pakfile

Displays Pakfile system statistics.

ParallelCommandListMarkers

Displays a list of parallel commands with their performance information.

Particles

Shows particle system performance information.

Physics

Displays physics performance statistics.

PhysXTasks

Displays PhysX task information.

PhysXVehicleManager

Displays PhysX Vehicle Manager statistics.

PlayerController

Displays PlayerController performance information.

Quick

Quickly displays groups of overall performance data.

RenderTargetPool

Shows memory and performance statistics for Render Target Pool.

RenderThreadCommands

Lists render thread commands with performance information.

RHI

Displays RHI memory and performance statistics.

RHICMDLIST

Shows RHI command list with performance statistics.

SceneMemory

Shows scene memory counters.

SceneRendering

Shows general rendering statistics. This is a good starting point to find general areas of slow performance in the rendering process.

SceneUpdate

Displays information about updating the world, including the time taken to add, update, and remove lights as well as add and remove primitives in the scene.

Script

Shows script statistics.

ShaderCompiling

Displays shader compiling information.

Shaders

Shows shader compression statistics.

ShadowRendering

Shows how long shadow calculations are taking, separate from actual shadow render time which is covered in stat LightRendering.

Slate / SlateVerbose

Displays Slate performance statistics.

SlateMemory

Shows Slate memory counters.

SoundCues

Shows active SoundCues.

SoundMixes

Shows active SoundMixes.

Sounds

<?> <sort=distance|class|name|waves|default> <-debug> <off> Shows active SoundCues and SoundWaves.

SoundWaves

Shows active SoundWaves.

SplitScreen

Shows Split Screen information.

StartFile

Starts a statistics capture, creating a new file in the Profiling directory.

Stop this operation with the stat StopFile command.

StatSystem

Shows performance and memory information for the Stat System.

StopFile

Finishes statistics capture that was started by the stat StartFile command, closing the file that was created in the Profiling directory.

Streaming

Displays basic statistics on streaming assets, like how much memory streaming textures are using, or how many streaming textures there are in the scene.

StreamingDetails

More detailed statistics on streaming, like breaking down general texture streaming into more specific groups (lightmaps, static textures, and dynamic textures).

StreamingOverview

Shows an overview of statistics on streaming assets.

TargetPlatform

Shows target platform information.

TaskGraphTasks

Shows performance data for TaskGraph tasks.

Text

Shows performance statistics for text.

TextureGroup

Displays texture group memory counters.

Threading

Displays threading information.

ThreadPoolAsyncTasks

Shows ThreadPool Async task counters.

Threads

Displays thread information.

Tickables

Shows performance statistics for Tickables.

TickGroups

Shows performance statistics for Tick groups.

UI

Shows UI performance information.

Unit

Overall frame time as well as the game thread, rendering thread, and GPU times.

This is a great stat command to start with because it helps developers focus their profiling work.

UnitGraph

To see a graph with the stat unit data, use stat Raw to see the unfiltered data.

UObjectHash

Displays hashed UObject information.

UObjects

Shows performance statistics for UObjects in the game.

Select Commands

Levels

The stat levels command displays level streaming information, which are grouped under the persistent level.

This command is useful for developers wanting to view a list of currently active levels, including whether they are visible, pre-loading, loading, or unloading. Additionally, this command displays how many seconds it took to go from a load request to load finish.

To view streaming level information, enter stat levels into PIE Console. To determine what state a level is in, refer to the Level Color Codes table below.

Color Code

Description

Green

Level is loaded and visible.

Red

Level is unloaded.

Orange

Level is in the process of being made visible.

Yellow

Level is loaded but not visible.

Blue

Level is unloaded but still residing in memory, and it will be cleaned up when garbage collection occurs.

Purple

Level is pre-loading.

StartFile



Click for full image.

The stat startfile command starts a statistics capture, and creates a new file in a Profiling directory. Typically, the engine saves statistics captures under <PROJECT_DIRECTORY>\Saved\Profiling\UnrealStats.

To profile a project's performance with Session Frontend Profiler, capture statistical samples and log them to *.uestats files.

To capture and log statistics to a *.uestats file, enter stat startfile into PIE Console.

To prevent StartFile from bloating the disk with large uestats files, run stat StopFile. Additionally, even if PIE Mode is closed, StartFile continues running in the background, which can result in bloated log files, so make sure to run the StopFile command to stop logging the project's performance.

To load statistics into Session Frontend Profiler:

From the Unreal Editor Menu Bar, select Tools > Session Frontend.

With Session Frontend open, select the Profiler tab.

To open a file for profiling, select Load. A File Explorer winow will appear for you to select the uestats file you wish to open for profiling.

After selecting a uestats file, click Open to load the file.

After Session Frontend loads the file, the capture data is visible in the Profiler for further analysis. Read the Profiler Tool Reference to learn more about reviewing profile captures in Session Frontend.



Tool for managing applications and deploying to consoles.

StopFile



Click for full image.

The stat stopfile command stops a statistics capture that was started by the StartFile command. Additionally, the StopFile command closes the file that was created in the Profiling directory.

To prevent StartFile from bloating the disk with large uestats files, run stat StopFile. Additionally, even if PIE Mode is closed, StartFile will continue running in the background, which can result in bloated log files, so make sure to run the StopFile command to stop logging the project's performance.

To stop capturing and logging statistics, enter stat stopfile into PIE Console.

Unit

Typically, developers want to determine if a bottleneck (negative performance impact) exists in the Game thread, in the Draw (rendering) thread, or on the GPU.



Click for full image.

The stat unit command displays performance information for the project's Frame, Game, Draw, GPU, RHIT, and DynRes threads.

Name

Description

Frame

Frame time is the total amount of time spent generating one frame of the game. Since both the Game and Draw threads sync up before finishing a frame, Frame time is often close to the time being shown in one of these threads.

Game

If Frame time is close to Game time, the game's performance is likely being bottlenecked (negatively impacted) by the game thread.

Draw

If Frame time is close to Draw time, the game's performance is likely being bottlenecked by the rendering thread

GPU

GPU time measures how long the video card takes to render the scene. Since GPU time is synced to the frame, it will likely be similar to Frame time.

RHIT

Typically, RHI Thread time is synced to the frame, and it will likely be similar to Frame time.

DynRes

If supported (and enabled), Dynamic Resolution shows Primary Screen Percentage by Secondary Screen Percentage.

To determine the project's bottleneck, launch the game in a non-debug build, and enter stat unit into PIE Console.

Setting Up Unreal Insights

Option 1: Launch Unreal Insights from the Explorer

Option 2: Build from Visual Studio

Option 3: From the Command Prompt

Option 4: From the Editor

Trace

Unreal Insights Session Browser

Timing Insights Window

Memory Insights

Networking Insights

Reference

Slate Insights

Unreal Insights identifies areas in your project that require optimization. It is a telemetry capture and analyzing suite that provides you the capability to capture events from the application at high data rates.

The major components of Unreal Insights consist of Trace events, the Unreal Trace Server which records and saves traces from the application, and Unreal Insights which analyzes and visualizes the data.



The stored trace sessions are self-describing and compatible between different engine release versions. They are stored in .utrace files. With generated companion data being stored in .ucache files next to the trace file.

Setting Up Unreal Insights

When building Unreal Insights you will have multiple options available.

Check if you already have a prebuilt copy of Unreal Insights with your engine by navigating to Engine\Binaries\Win64\UnrealInsights.exe



You can build Unreal Insights from your Program's directory in your Solution Explorer.



Navigate to Start > Command Prompt then build Unreal Insights from your command directory.

Start Unreal Insights from the Unreal Editor by navigating to Tools > Unreal Insights > Run Unreal Insights. Insights will attempt to compile automatically.



When running a Trace to profile your project data, you have multiple workflow options available depending on your Unreal Engine build and operating system. Refer to Trace and the Trace Quick Start Guide for additional documentation.

Trace

Trace is a structured logging framework for tracing instrumentation events from a running process.

The Unreal Trace Server is run in the background as a single server instance and can be shared between multiple projects or branches. It is a lightweight program that has minimal impact on performance and does not include a User Interface. It is launched by a separate server process executable UnrealTraceServer.exe located in the Engine/Binaries/Win64 directory folder.



The Trace Server has two functionalities:

The Trace Recorder listens on port 1981 for incoming trace connections and records the live trace stream.

The Trace Store stores the recorded traces as files to a path like C:/Users/<user>/AppData/Local/UnrealEngine/Common/UnrealTrace/Store/001/. It watches this folder for changes and exposes the list of available traces to Unreal Insights UI.

Refer to the Trace, Trace Quick Start Guide, and the Trace Developer Guide for additional documentation.

Unreal Insights Session Browser

After starting Unreal Insights, it will open the Unreal Insight Session Browser, which contains the Trace Store panel (1), a directory which contains the Trace Sessions (2), and a Connection menu panel (3).



The Connection menu (4) contains a Trace Recorder IP address (5), a Running Instance IP address (6), and an Initial channel to enable specific traces when connected (7).



When the tool starts up, the Unreal Insights window opens first. In the top section of the window, labeled Trace Sessions, you will see a list of all pre-recorded sessions that you can load for analysis. These correspond to the .utrace files in your Trace Store Directory. You can double-click any of these trace sessions, or select a trace session and click Open Trace. Alternatively, you can search for .utrace files in other locations by using the Open Trace dropdown arrow.

To immediately start an analysis of a respective trace file, drag and drop a .utrace file from Explorer over the Unreal Insights window.

If a live Trace session connects to the tool, it will also appear in the list. Live sessions have the word LIVE in the status column, and update in real time while you analyze them, but are otherwise identical to pre-recorded sessions. The tool can connect multiple sessions at the same time, and it will automatically record data for all of them as the data streams in. You can analyze these sessions in real time by loading them from the list (just as you would with pre-recorded sessions).

Timing Insights Window

The Timing Insights window collects performance data. you will see per-frame performance data for different tracks along the CPU and GPU tracks. A new toolbar was added to the Timing view, splitting the Tracks drop down menu into multiple menus where you can look at different visualizations of the time your project spends on various tasks.

You can select blocks of time to view in aggregate, sort or categorize data, and review log output. You can show or hide the respective panels.



The Timing Insights window features the Frames panel (1), the Timing panel filters (2), the Timing panel (3), the Log panel (4),Timers and Counters tabs (5) and the Callers and Callees panels (6).

See Timing Insights for additional documentation.

Memory Insights

Memory Insights is a new component that provides you the capability to investigate memory usage and call stack tracing in your project.



The runtime component traces events for every allocation, reallocation, or free event that occurs during runtime, then reconstructs that memory usage pattern during analysis.



Refer to the Memory Insights documentation for instructions on how to set up, trace, query, and sort your data.

Networking Insights

Unreal Insights includes Networking Insights to analyze, optimize and debug network traffic.

Refer to the Networking Insights for additional documentation.

Reference

To get the most out of the many features that ship with Unreal Insights, You can customize your project's output with macros and command-line options.

Refer to the Reference page for additional documentation.

Slate Insights

Slate Insights extends Unreal Insights to help developers improve the performance of their UI by providing tools to identify the root cause of a specific Slate and UMG update.

Refer to the Slate Insights page for additional documentation.

A Tour of Trace

Tracing Runtime

1. Run Unreal Insights:

2. Insights Session Browser:

3. Run Your Game Project:

Trace is a structured logging framework for tracing instrumentation events from a running process. The framework produces a stream of high-frequency traced events that is self-describing, easily consumed, and easily shared. The modules TraceLog and TraceAnalysis are the principal modules that constitute the framework.

The major components of Unreal Insights consist of Trace events, the Unreal Trace Server which records and saves traces from the application, and Unreal Insights which analyzes and visualizes the data.



The stored trace sessions are self-describing and compatible between Engine versions. They are stored in .utrace files. With generated companion data being stored in .ucache files next to the trace file.

A Tour of Trace

In Unreal, Trace is launched by a separate server process executable UnrealTraceServer.exe located in the Engine/Binaries/Win64 directory folder.



The executable is automatically launched by Unreal Editor builds when you make a connection from the Unreal Trace sessions browser. The Unreal Trace server runs in the background as a single server instance and can be shared between multiple projects and branches.

It is a lightweight program that has minimal impact on performance and does not include a User Interface.If you wish to shut down the process manually, you can do so by accessing your System's Task Manager.



The System Task Manager displays the running Server Trace in the Processes tab.

It can receive and record data from multiple sources simultaneously, and runs in the background as a single instance that does not need to be terminated in order to launch a new version.

Currently, we only support one user per machine that is running a Unreal Trace Server. If multiple users are logged in simultaneously, then traces will be stored in the first user's trace directory, therefore leaving them inaccessible for other users.

Tracing Runtime

Navigate to your Engine\Binaries\Win64 folder and double-click UnrealInsights.exe.



When you launch the Unreal Insights Session Browser, you will notice that there are currently no live sessions available.



Launch the Command Prompt from your operating system and run Your Project.

You may need to change the file directory path to match your local installation path.

Tail Tracing

Tail Tracing tracks events over the last few seconds (depending on the buffer size), therefore any machines that may be able to display a lead-up.

The default size of the buffer is 4MB, however if you wish to modify or deactivate it, you can do so by entering the following command using the Command line:

Setting X to 0 MB will deactivate it, other values will change the buffer size accordingly.

Improved Late Connect

In previous versions of Unreal Insights, if your connection to the Insights program was late, then any one-time events(Important Events) would be missed before you could make a connection.

Important events are now cached on the Unreal Engine client side, therefore they are sent to late-connecting machines during connection.

Insights can instruct remote running Unreal Engine instances to connect to the remote trace servers from its local UI instance without needing to involve the local machine.

Late connect can be initiated by navigating to Unreal Insights > Connect, or from the Editor cmd console by typing any of the following commands:

Unreal Insights has a file-based caching system which provides the application the capability to attach additional information to a trace. This can be used to retrieve previously calculated results faster, or store data that would otherwise be lost such as symbols. The cache is stored in a .ucache file next to the trace file.

Screenshot Tracing

You can enable Screenshot Tracing from the command line by using the argument:

When screenshot tracing is enabled, you can use the console command trace.screenshot to take a screenshot of your project during that frame. To assist with debugging visually in Unreal Insights, You will notice a red vertical line that will display in the Timing Insights timeline.



Trace User Guide

You can use different workflows to run traces in Unreal Insights. Refer to the Trace User Guide for more information.

Trace Developer Guide

You can develop your own traces in Unreal Insights. Refer to the Trace Developer Guide for more information.

Setting Up Unreal Insights

Option 1: Launch Unreal Insights from the Explorer

Option 2: Build from Visual Studio

Option 3: From the Command Prompt

Option 4: From the Editor

Default Tracing Workflow (Win64, Binary Launcher)

1. Run Unreal Insights:

2. Insights Session Browser:

3. Run Your Game Project:

4. Live Insights Session Browser:

5. Check Your Trace Status:

6. Open Your Trace Session:

Late Connect

Setting Up Unreal Insights

When building Unreal Insights you will have multiple options available.

Check if you already have a prebuilt copy of Unreal Insights with your engine by navigating to Engine\Binaries\Win64\UnrealInsights.exe



You can build Unreal Insights from your Program's directory in your Solution Explorer.



Navigate to Start > Command Prompt, then build Unreal Insights from your command directory.

Start Unreal Insights from the Unreal Editor by navigating to Tools > Unreal Insights > Run Unreal Insights. Insights will attempt to compile automatically.



When running a Trace to profile your project data, you have multiple workflow options available depending on your Unreal Engine build and operating system.

Default Tracing Workflow (Win64, Binary Launcher)

Navigate to your Engine\Binaries\Win64 folder and double-click UnrealInsights.exe.



When you launch the Unreal Insights Session Browser, you will notice that there are currently no live sessions available.



Launch the Command Prompt from your operating system and run the Lyra Game Sample.

If you have downloaded a sample of Lyra from the Epic Games Launcher, you can run Lyra from the default path UnrealProjects\Lyra\Lyra.uproject.

Navigate back to the Unreal Insights Session Browser and observe that a new session has appeared with the "LIVE" status, indicating it is currently recording.



In Lyra, press the tilde (`) twice to open the console, then type in the command:



The channels Gpu, Bookmark, Frame, Cpu, and Log are enabled by default.

If Unreal Insights is already running before starting your project, then Unreal Insights will connect to the local trace server automatically and the default trace channels will be enabled.

Navigate back to the Unreal Insights Session Browser, then double-click your .utrace file to open it for analysis in a new Unreal Timing Insights window.

To open a Trace file, you can drag and drop your .utrace file from the explorer onto the Unreal Insights Session Browser. Alternatively, you can open a .utrace file from a specific folder by clicking the Arrow button next to Open Trace, and selecting Open File from the drop-down menu.



Opening a trace launches a new instance of Unreal Insights. Timing Insights is the default component opened and provides you the capability to interact with a trace session to see how much time your project spends on various tasks.

Refer to the Timing Insights documentation for more information on how to view your data for analysis.

Advanced Controls of Tracing

Unreal Insights provides several Trace commands for you to control how your data is profiled.

Trace.SnapshotFile <filename>: This writes a snapshot of the current in-memory trace buffer to a file. If you are already tracing actively, it does not interrupt the active trace, but instead records a second trace file in parallel just for this snapshot.

Trace.Bookmark <name>: This emits a Bookmark event with the given string name. Bookmarks appear in Timing Insights as a vertical line at the time the Bookmark was recorded. Previously this was available through the API only as TRACE_BOOKMARK().

Trace.Screenshot <Name> <bIncludeUI>: As mentioned above, you can run this console command to generate a vertical line and optionally include the UI by specifying true or false for a screenshot in Timing Insights.



You may want to have visibility on specific trace channels like CPU or GPU profiling data, or to disable tracing a channel. Refer to the Trace and Reference documentation for additional information on Trace commands.

Late Connect

There may be instances where you forget to run the UnrealInsights.exe before launching your project, or perhaps you have discovered a situation you want to record without initially tracing from the beginning. You can Late Connect to Unreal Insights by following the steps below.

Before continuing, check the Unreal Insights Session Browser to ensure a live session is not already running. You can stop the connection by entering the console command:

Build, Cook, or Run your project as you normally would.

Open Unreal Insights.

Click Connection to open the Connection tab. Confirm your desired connection settings, then click Connect.



After a successful connection, click the Trace Store tab. A new LIVE session will appear in the Session list.



Using Built-in Event Types

Timers

Counters

Memory

Miscellaneous Utilities

Creating Custom Events

Defining events

Arrays

Attachments

Strings

Normal Events

Important Events

Channels

Tracing events

Important Events

Analyzing Custom Events

Analyzers

Thread IDs

Unreal Insights Plugins

Going Further

Writing a Custom Analyzer

Trace is a structured logging framework for tracing instrumentation events from a running process. The framework is designed to produce a stream of high-frequency traced events that are self-describing, easily consumed, and easily shared. The modules TraceLog and TraceAnalysis are the principal modules that constitute the framework.

The major components of Unreal Insights are Trace events, the Unreal Trace Server which records and saves traces from the application, and Timing Insights which analyzes and visualizes the data.



The stored trace sessions are self-descriptive and backward compatible. They are stored in .utrace files, with generated companion data being stored in .ucache files next to the trace file.

Trace data travels in packets, known as the Transport. Each packet starts with an internal identifier indicating which thread the events came from and a size. Packets are LZ4-compressed unless they are too small to benefit from compression.

Using Built-in Event Types

Unreal Engine has a range of predefined event types. These types cover common profiling information such as performance timers and memory allocations. The events are exposed by macros or interfaces found in the Source/Runtime/Core/Public/ProfilingDebugging folder.

We strongly recommend you use these APIs before implementing your own custom event types. By using the built-in event types, you benefit from the built-in analyzers and visualizations.

Timers

The most common profiling task is measuring the performance of an application. In the Source/Runtime/Core/Public/ProfilingDebugging/CpuProfilingTrace.h file you can find the functionality to emit timer events. We recommend you use the macro family TRACE_CPUPROFILER_EVENT_SCOPE_, which provides a method to easily measure how long the application spends in a scope:

This code sample will produce a "Fancy work" timer that appears in the Timing Insights timeline. The example uses a static string. Dynamic strings are supported, but there is an extra performance and memory overhead compared to static strings.

Many built-in macros include the TRACE_CPUPROFILER_EVENT_SCOPE, for example, SCOPE_CYCLE_COUNTER, QUICK_SCOPE_CYCLE_COUNTER, and SCOPED_NAMED_EVENT (if -statnamedevents is set).

Counters

The Source/Runtime/Core/Public/ProfilingDebugging/CountersTrace.h file contains a generic interface for declaring and tracing named values. You can use the interface to track these values over time. The interface supports integer, float, and memory values including common operations (set, increment, decrement).

For example:

This code sample produces two counters (AlienHits and AlienBytes) which appear in the Timing Insight's Counters tab.

Memory

Memory tracing is implemented as a wrapper for GMalloc which covers allocations that are normally made. Additionally, the virtual allocator functions on relevant platforms. However, if you implement your own custom allocators, you can instrument them using the functions located in the Source/Runtime/Core/Public/ProfilingDebugging/MemoryTrace.h file.

Memory tracing takes advantage of the LLM[testing-and-optimizing-your-content\unreal-insights\memory-insights] tagging system and implements code with LLM_SCOPE events that help allocation tracing to track tags. We recommend using those macros directly since both LLM and Memory tracing can take advantage of them. However, in specific cases the Source/Runtime/Core/Public/ProfilingDebugging/TagTrace.h file contains macros to add custom instrumentation for only memory tracing.

Miscellaneous Utilities

In the Source/Runtime/Core/Public/ProfilingDebugging/MiscTrace.h file, you can find a set of utility macros that help with context when profiling. For example, Frame markers, and Bookmarks. Bookmarks can be helpful to identify important changes in your application at a glance. You can add your own by using the TRACE_BOOKMARK macro.

For example:

Bookmarks display in the timelines when using Unreal Insights, providing you with a visual indication of this change and in the log view for easier searching. Bookmarks are meant to be used for infrequent changes in the game state. If you need a higher frequency, event timers or counters are a better choice.

Creating Custom Events

If the built-in events are insufficient for your needs, you can implement your own Custom events. Custom events provide you a method to define your own custom payload, however you need to implement analyzers to handle the events and extract the data.

Defining events

A trace session is made up of a stream of events. Events are statically described in the application and composed of a logger name, event name, event flags, and a number of fields that are defined as follows:

The EventName and FieldName parameters define the event and specify a field that it should include. Events are grouped by "loggers", a concept that helps to organize events into a namespace and ease subscription when analyzing a Trace stream. The optional Flags parameter will modify how events are traced.

Refer to the table below:

Event Flag

Description

NoSync

By default, events are synchronized with events being traced on other threads. Events with the NoSync flag skip this synchronization. They're smaller and faster to trace at the expense of being uncoordinated with other threads during analysis.

Important

Marks the event as Important. See the Important Events section below for more information on normal and important events. Important events also require the NoSync flag since they are processed out-of-band with normal events.

Fields are named and strongly typed. Field types can be the standard integer or floating-point primitives (such as uint8, uint32, float), as well as arrays and strings.

Field type

Description

Example

uint8, uint16, uint32, uint64

Common integer types.

<< FieldName(-10)

float, double

Common floating point types.

<< FieldName(1.0f)

UE::Trace::Widestring

Wide strings.

<< FieldName(Ptr, NumChars*)

UE::Trace::Ansistring

Ansi strings.

<< FieldName(Ptr, NumChars*)

Type[]

Arrays.

<< FieldName(Ptr, NumElements)

*Number of characters excluding null terminator.

Fields are written to the stream without padding. There is no support for nested structures or events as fields, but a common pattern is to refer to previous events by embedding a unique id field and resolving in analysis.

Events are usually defined at a global scope in a .cpp file. If you need to trace events from multiple translation units, you can use the UE_TRACE_EVENT_BEGIN_[EXTERN|DEFINE]pair.

You can add variable-length fields to a Trace event by defining them as arrays with unspecified sizes.

Array-type fields have no storage cost in an event's payload if no data is set on the field. Array data follows the main event's data in the trace stream and is rejoined at analysis time. Tracing an array field only requires a pointer to the array data and an integer count indicating the number of elements in the array.

For example:

Initially, Trace did not support variable length fields. Attachments were introduced as opaque binary blobs that the system appends to events. We recommend using Array-type fields instead of attachments because they benefit from being structured and reflected at analysis time.

Attachment support incurs a cost that every logged event has to pay, whereas array-type fields do not. In the future, attachments may become opt-in to optimize away this overhead.

Trace events support string-type fields using the Trace::AnsiString or Trace::WideString types when declaring event fields with UE_TRACE_EVENT_FIELD().

String-type fields are written much the same as primitive-type fields, with a few additional extras; ASCII-type fields will automatically truncate wide strings to 7-bit characters, and an optional string length can be given (preferable for performance if string length is already known).

When you trace an event at a UE_TRACE_LOG site, the system writes a header and the event's field values into a buffer that is local to the current thread as Thread Local Storage(TLS). TLS buffers have a small fixed size and link together to form a list. Trace's worker thread traverses the list of buffers, sending event data that has been committed (and is therefore completely visible). The benefit of using TLS is that it avoids conflicts between tracing threads. Order of operations across threads is significant for event types and must be reconstructed when trace data is analyzed, such as memory tracing events where memory addresses can be reused. If synchronization is required for an event, Trace precedes each event with an atomically incrementing 24-bit serial number. Events are by default synchronized, but developers can use the NoSync flag to opt-out of this feature. NoSync avoids incurring the associated performance cost and decreases its size, but removes the ability to coordinate with other threads during analysis.

Tracing can start and stop at any point in the runtime. However, some events are crucial for analysis and are only emitted once during the process lifetime. For example an event describing the processor frequency or events specifying a human readable name for a timer. To be able to emit these events on every new connection, Trace provides a way to mark events as important.

Important events are stored in a special buffer which is kept during the process's entire lifetime, which means developers have to consider the memory cost when using this feature.

Channels

Channels in Trace help to constrain the stream of events based on the user's interest. This improves CPU and memory usage by only tracing events that are relevant to what the user is trying to observe. You can define a Channel with the following syntax:

There is an EXTERN/DEFINE pair for more specific use cases. By default, channels are disabled and must be explicitly opted into. Refer to the Trace for how to enable channels.

Channels can be combined in the log macro to gate tracing of an event with multiple channels. A UE_TRACE_LOG(..., ItvChannel|BbcChannel) will only emit an event if both the Itv and Bbc channels are enabled.

Channels use the OR operator to create a composite mask, similar to how a bitmask is constructed from different flags.

Tracing events

Log an event at runtime using the UE_TRACE_LOG macro:

If the Channel ItvChannel is enabled, this adds a 'RainbowLogger.ZippyEvent' event to the Trace stream.

Not all fields need to be written, but there is no delta or run-length compression when tracing events. All defined fields are present, even if no data is written to them. There is no padding between fields. A traced event is essentially analogous to a struct declared with #pragma pack(1). We recommend developers think strategically to use these features to their complete capability.

While UE_TRACE_LOG represents a singular point in time, it is sometimes useful to represent a time range. UE_TRACE_LOG_SCOPE allows an event to be emitted as a start point and an end point. See the Important events for details on how this can be used. The scope allows you to determine which other events occur inside the scope but does not provide timestamps. If you need to correlate with other events using time, you can use UE_TRACE_LOG_SCOPE_T.

This system makes heavy use of macros to hide a large amount of boilerplate so that definitions and log sites compile to nothing when Trace is off without requiring developers to use #if and #endif pairs throughout their code.

Tracing important events has some additional requirements. Due to these events being stored in a cache shared across threads, the logging macro needs to know in advance how much variable memory is going to be consumed. For example, consider the following event:

This event will be traced as below:

Notice that the total size of the variable data is passed to the ellipsis argument of the log macro.

Analyzing Custom Events

Now that you have defined a new event, enabled the related Channel or Channels, and added at least one log site, you can consume and analyze the events and publish them. We use a pattern of Analyzers and Providers to do this. Analyzers extract the data from each event and feed it to the corresponding provider, which serves the data to the UI or other output.

Analyzers derive from the IAnalyzer interface and implement two primary methods:

OnAnalysisBegin to subscribe to events.

OnEvent to receive those subscriptions.

Providers derive from the IProvider interface. There are no mandatory methods to implement them, but make sure access to the data in the provider is thread-safe, since the analyzer thread and the UI thread access to the provider is unsynchronized.

Analyzers and providers need to be added to the analyzer session to receive events. A common pattern is to feed a pointer to the provider and to the analyzer on construction:

Analyzers

Analyzers subscribe to events using the logger name and the name of the events. The subscription interface associates each event type with an user defined index known as route ID (usually defined in an enum).

When analysis encounters an event that the analyzer has subscribed to, the analyzer's OnEvent method is called with the registered route ID. The event context provides methods to extract the data for each field, thread and timing information. This API reflects the self-describing nature of Trace streams. There is no binary or runtime-code dependency on interpreting Trace streams.

Thread IDs

The primary thread ID is not the same as the system thread ID, although the system ID is available. This removes the need for special handling to guard against cases where the Operating System might reuse a thread ID. As a result, you may encounter the reuse of system IDs from one thread to the next, but the ID coming from Trace should be unique.

Unreal Insights Plugins

Generally, the components in Unreal Insights consume and visualize the data in the providers. If you implemented a custom provider, you may need to implement a custom visualization. SlateInsights and RenderGraphInsights are two example plugins that are distributed with the engine and serve as a reference.

Going Further

Trace and Unreal Insights are designed to be flexible and extendable for advanced users. Beyond using the Unreal Insights application and implementing plugins, it is possible to use the components in different ways.

Writing a Custom Analyzer

If you want to output data in a different way to generate reports or provide a similar need, you can implement a standalone program and use a custom analyzer to extract the events you are interested in, and output the data in the format you require. An example of this can be found in the FStoreBrowser::UpdateMetadata() method located in the \Engine\Source\Developer\TraceInsights\Private\Insights\StoreService\StoreBrowser.cpp file. In this method we create an analysis context. The analyzer FDiagnosticsSessionAnalyzer is added, which looks for one specific event type ("Session/Session2"). When reading the trace all other events are skipped, and once the session event is found no further processing is needed. The information is used to display the metadata for traces in the session browser.

Timing Insights Main Toolbar

Frames

Timing

All Tracks

CPU/GPU

Other

Plugins

View Mode

Quick Find Widget

Timers

Asset Load Time

Executing Commands Without Opening the UI

Export Functionality

Source File For CPU Timers

Callers and Callees

Counters

Log

The Timing Insights window is where you can find per-frame performance data for different tracks, including the CPU and GPU tracks. The Timing view has a new toolbar, splitting the Tracks drop-down menu into multiple menus where you can look at different visualizations of the time your project spends on various tasks.



The Timing Insights window features the Frames panel (1), the Timing panel (2), the Log panel (3), the Timers and Counters tabs (4), and the Callers and Callees panels (5).

Timing Insights Main Toolbar

The toolbar provides the capability to select blocks of time to view in groups, sort, or categorize data, and review log output.

You can toggle the visibility to display data for that frame in the Timing, Timers, Callers, Callees, Counters, and Log tracks by clicking on each respective track.



You can select blocks of time to view in aggregate, show or hide the respective panels. sort or categorize data, and review log output. To do this, click on a single frame in the Frames panel, or click and drag a section of the scrub bar at the top of the Timing panel, known as the Time Ruler.

Frames

The Frames panel displays the total time taken by each frame using a bar graph format. This is useful for identifying general trends, such as low performance or framerate drops when a level is loaded, an unoptimized scene is visible, or spawning a large number of Actors simultaneously.



The frames panel displays the Frames, Timing, Timers, Callers, Callees, Counters, and Log tracks.

Hovering the cursor over a bar causes that frame's index and running time to appear.



If you right-click on on the bar, the following Zoom context menu options will appear:



Option

Description

Auto Zoom

Toggles auto zoom, which fits the entire session time range into the frames display window.

Zoom Timing View on Frame Selection

Toggles whether the timing view is zoomed when a frame is selected.

These options are also available to edit in the UnrealInsightsSettings.ini file.

Timing

You can show or hide each track individually by clicking the arrow next to it.



Clicking the All Tracks dropdown arrow displays a list of all available tracks.



Clicking the CPU/GPU dropdown arrow displays theCPU and GPU tracks and thread group options.



Clicking the Other dropdown arrow displays options for visibility of the Main Graph, File Activity, Asset Loading, and Frames Tracks.



Clicking the Plugins dropdown arrow displays Tracks and options that are exposed by plugins, including information about Slate, Gameplay, Animation, and RDG Tracks.



The View Mode dropdown arrow displays controls for various options for the Timing View.



Timing View Option

Description

Compact Mode (key shortcut: C)

Toggles compact mode which displays the timing tracks with reduced height supporting tracks.

Auto Hide Empty Tracks (key shortcut: V)

Auto-hides empty tracks without timing events. This option is persistent to the UnrealInsightsSettings.ini file.

Depth Limit (key shortcut: X) * Unlimited / 4 Lanes / Single Lane

Toggles the display of different CPU depth options. The X key can be used as a shortcut to cycle through the different CPU depth options.

Coloring Mode (CPU Thread tracks)

You can assign a color to CPU / GPU timing events based on their duration (inclusive time).

The color key is as follows:

≥ 10ms : red.

≥ 1ms : yellow.

≥ 100μs : green.

≥ 10μs : cyan.

≥ 1μs : blue.

< 1μs : grey.



Allow Panning on Screen Edges

When enabled, panning continues when the mouse cursor reaches the edges of the screen.

The Quick Find widget is used to search and filter events displayed in the Timing view. The widget can be opened from the Timing view context menu by right-clicking on a Timing event or by using the CTRL + F shortcut when the Timing view has focus.



The Quick Find widget search logic is defined using Groups and Filters. Group nodes contain child Filter nodes and define the logic applied to the children's result. Filter nodes are leaf nodes and contain a filter each.

Each filter contains:

The filter type, that can be selected from a drop down menu.

The filter operator, also selectable using a drop down menu.

The filter value, that can be entered using a text box.

Once the filter logic is created, it can be used to search for events or filter the tracks from the Timing View.

Filter

Description

Find First

Searches for the first event matching the filter in the order of the event's start time. If a match is found it is selected and the Timing view brings it into view.

Find Previous

Searches for the previous event matching the filter starting from the current selected event's start time. If no event is selected, it acts as a Find First.

Find Next

Searches for the next event matching the filter starting from the current selected event's start time. If no event is selected, it acts as a Find Last.

Find Last

Searches for the last event matching the filter in the order of the event's start time. If a match is found it is selected and the Timing view brings it into view.

Apply Filter

Highlights all timing events that pass the filter logic from the tracks.

Clear filters

Stops highlighting events based on the filter's logic.

If you make changes to the filter's logic, you must click Apply Filter again to highlight events based on the new logic.

Timers

The Timers panel lists all timer events that run within the time range designated in the Timing panel. In addition to grouped data based on time range, the list can be sorted in ascending or descending order by the values in any active column.

Group Name

Description

Flat

Creates a single group. Includes all Timers.

Timer Name

Creates one group for one letter.

Timer Type

Creates one group for each timer type.

Instance Count

Creates one group for each logarithmic range(1-10,10-100, 100-1000.)

To change sort order, or to activate or deactivate columns, right-click on the column. The following options are available:

Sorting Option

Additional Sort Option

Description

Sort Ascending (by Timer, Group Name, Instance Count, Total exclusive, Total inclusive.)

Sorts Column by Ascending order.

Sort Descending (by Timer, Group Name, Instance Count, Total exclusive, Total inclusive.)

Sorts Column by Descending order.

Sort By:

Timer or Group Name

Instance Count

Total Inclusive Time

Total Exclusive Time

Sort Ascending

Sort Descending

Name of timer or group.

Number of select instances.

Total inclusive duration of selected timer's instances.

Total exclusive duration of selected timer's instances.

Column Visibility Group

Description

View Column

Hides or shows the following columns.

Timer Or Group Name

Meta Group Name

Type

Instance Count

Total Inclusive Time

Max Inclusive Time

Average Inclusive Time

Median Inclusive Time

Min Inclusive Time

Total Exclusive Time

Max Exclusive Time

Acerga Exclusive Time

Median Exclusive Time

Min Exclusive Time



Show All Columns

Resets tree view to show all columns.

Reset Columns to Min/Max/Median Preset

Resets columns to Min/Max/Median Preset.

Reset Columns to Default

Resets columns to default.

When starting Timing Insights from the command line the Asset Load Time channel can be used to enable named CPU timers for UObject::Serialize and toggle tracing Blueprint names.

In the past, tracking Blueprint names was enabled by default, but this would add a lot of cost to the trace runtime event. Now, if you want to enable Blueprint name tracing, you must turn on this argument in the command line.

To enable asset load time tracking from the command line, you can use the argument

Because there are many timers added when Blueprint names are toggled on, they are hidden in Trace Insights by default. After enabling Asset Load Time tracking, you can display Blueprint names by adding the argument:

Timing Insights can be run directly from the command line without opening the UI. You can either specify a single command directly in the command line, or you can execute a series of commands by using a response file. In each case, a set of data is exported to a .csv or .tsv file.

Command

Description

TimingInsights.ExportThreads

Exports a list of GPU and CPU threads.

TimingInsights.ExporTimers

This command exports a list of GPU and CPU timers.

TimingInsights.ExportTimingEvents

Exports a list of GPU and CPU timing events. The list of events that is exported can be filtered by thread, timer, or by time range.

TimingInsights.ExportTimerStatistics

This command exports the list of GPU and CPU timers and their aggregated statistics.

These commands can be useful for running automated tests.

The Timers panel includes the capability to export your timing event data by selecting one or more timers and right-clicking on the context menu.



Timer Options Include:

Option

Description

Open Source in Visual Studio

Opens the source file of the selected message in Visual Studio.

Visual Studio must already be open before using this option otherwise it may only open its Start page.



Other Miscellaneous export options include the following:

Option

Description

Copy To Clipboard (CTRL+C)

Copies the selection of timers and their events to clipboard.

Export (CTRL+S)

Exports the selected timers and their grouped statistics to a text file.

You can navigate to the Timing view and mark the time you are interested in saving from the main timeline view by clicking and dragging on the Time bar.

Observe the grouped stats are updated in the Timers panel to reflect the time selection.

From the Timers panel, manually select the timers you are interested in saving or use Ctrl+A to select all timers.

Next, press CTRL+S or select Export from the context menu and choose a *.tsv,*.txt or *.csv file to save the selected timers and their aggregated statistics (for selected time range).

Export Timing Events

Exports the timing events to a text file.

Navigate to the Timing view, and mark the time you are interested in exporting from the main timeline view, by clicking and dragging on the Time bar.

If no time selection is made, the entire timeline will be exported.

In the Timing panel, click on the CPU/GPU thread tracks to show or hide the tracks you want to export.

Select the timers you are interested in, or use Ctrl+A to select all timers.

Select Export Timing Events (Selection)... from context menu and choose a tab-seperated value (*.tsv/*.txt) or comma-seperated value (*.csv) file.

You can export the "Threads" and "Timers" in order to match the thread id and timer id with the names of threads and timers.

More Export Options / Export Threads

Exports the list of timers to a text file. (.tsv or .csv).

More Export Options / Export Timing Events (All)

Exports all the timing events for all CPU/GPU threads to a text file (.tsv or .csv).

The exported file can be massive in size, Even a small session could have several million timing events.



In the Timers panel, the source file and line number is visible in the tooltip of each timer.



Callers and Callees

The Callers and the Callees panels display a hierarchical list of task events. When you select an event from the Timing view hovering over the information icon of an individual task will display the Id, Name, Type, Source, Number of instances (Num Instances) including detailed information on the Instance count, and total Inclusive and Exclusive time.



Counters

The Counters panel lists all stats incremented during the same time period as the Timers panel. You can rearrange the panel by updating the sort order and column organization.

The following Groups are available:

Group Name

Description

Flat

Creates a single group. Includes all Counters.

Stats Name

Creates one group for one letter.

Meta Group Name

Creates groups based on metadata group names of counters.

Counter Type

Creates one group for each counter type.

Data Type

Creates one group for each data type.

Count

Creates one group for each logarithmic range.(1-10,10-100, 100-1000)

Log

The Log view displays all logs generated by calls to the macro UE_LOG from the Trace session. The logs can be filtered by verbosity and category, similar to the Output Log window in the Editor.



Selecting a time period in the Timing panel highlights all log entries that fall within that time. If you select multiple log entries, the Timing panel highlights the time range between those entries. The log panel features a search box that filters out all log messages that don't match the text you enter. In addition to filtering, clicking any row will pan the Timing panel to the time when that row's text was logged. You can save logs by selecting one or more messages and right-clicking on the context menu and selecting one of the following options from the drop down menu:

Menu Option

Description

Copy (CTRL+C)

Copies the selected log (with all its properties) to clipboard.

Copy Message (SHIFT+C)

Copies the message text of the selected log to clipboard

Copy Range (CTRL+SHIFT+C)

Copies all the logs in the selected time range (highlighted in blue) to the clipboard.

Copy All

Copies all the logs to clipboard

Save Range As… (CTRL+S)

Saves all the logs in the selected time range (highlighted in blue) to a text file (tab-separated values or comma-separated values).

Save All As…

Saves all the (filtered) logs to a text file (tab-separated values or comma separated values)

Open Source in Visual Studio

Opens the source file of the selected message in Visual Studio (or the registered IDE).

Visual Studio must already be open before using this option otherwise it may only open its Start page.



Context Switches

Context Switches

A Context Switch stores the state of a process or a thread, so it can be restored and resume execution at a later point. When attempting to profile Context Switches with a Launcher Build, You will want to ensure that you enable "Editor Symbols for Debugging" from the Options for your Engine Version.



Context Switches are supported on Windows, XB1/XSX, and PS4/PS5 platforms.

You can enable the ContextSwitch trace channel in the command line:



On Windows, depending on your user permission settings your project runtime should be "run as administrator".



Open your trace file in Unreal Insights, If a session has the ContextSwitch trace event enabled, then the following information will be displayed in the Timing Insights view:

a) Additional CPU Core tracks. One for each CPU core in the recorded trace; shows timing events indicating what thread does execute on the respective CPU core. "Unknown" timing events indicate execution of threads from other applications / processes or from the OS.

b) Each CPU Thread has a header lane with core number events indicating on which core the respective thread is executing. The time range when a thread is executing and when it is preempted it is highlighted.



c) CPU/GPU drop down menu shows additional options re Context Switches:



d). The context menu of a "Core" timing event in a Cpu Thread track shows additional options:



e). The context menu of a "Thread" timing event in a CPU Core track shows additional options:



Enabling CPU Task Trace

Task Dependencies

Enabling CPU Task Trace

Follow the steps below to profile a CPU Task:

Enable the Task and CPU trace channels when running your application from the command line by using the following command:

Navigate to the Unreal Insights Session Browser. and open your .trace file in Unreal Insights by selecting a trace from the Trace Store directory. If a session has Task events, the following functionality is available in the Timing Insights view.

a) When hovering over a Timing Event, if the current event is inside a task, extra information is displayed in the tooltip.



b) Navigate to the Other > Tasks submenu from the Timing View track. You can use this to display task graph related visualizations.



Tasks Submenu Option

Description

Show Task Critical Path

Show or Hide relations representing the critical task containing the current path.

Show Task Transitions

Show or hide transitions between the stages of the current task.

Show Task Connections

Show or hide task connections between the following options:

The current task's prerequisites completed time and the current task's started time.

The current task's completed time and the current task's subsequent started time.

The current task's nested tasks added time and their started time.

Show Transitions of Prerequisites

Show or hide stage transitions for the current task's prerequisites.

Show Transitions of Subsequents

Show or hide stage transitions for the current task's subsequents.

Show Tansitions of Parent Tasks

Show or hide transitions for the current task's parent Tasks

Show Transitions of Nested Tasks

Show or hide stage transitions for the current task's nested tasks.

Show Task Overview Track

Show or hide the Task Overview Track when a task is selected.

Show Detailed Info on the Task Overview Track

Shows the current task's prerequisites/nested tasks/ subsequent in the Task Overview Track.

c) Right-click anywhere in the Timing View panel to open the timing view context menu. This menu is used to display new options that can be used to sort tracks on the Task graph.

Menu Option

Description

Top Docked

Docks this track to the top.

Scrollable

Moves this track to the list of scrollable tracks.

Bottom Docked

Docks this track to the bottom.

d) When you navigate to Tasks, the Show Task Dependencies menu options display in the drop-down menu, when a timing event is selected, and if there is a task that encompasses the selected timing event.

The following data is displayed:

Relations in the form of arrows are drawn on the timing view to show the lifetime and stages of the task. This includes information on when it was created, launched, scheduled, started, finished and completed.



Relations are drawn between the current task and its prerequisite, subsequent, and nested tasks.



A new top docked track appears showing the stages of the task as timing events.

Task Dependencies

When activating one or more of these options, all of the relations mentioned in the previous section are drawn for the prerequisite, subsequent, and nested tasks of the current task.

As an example, instead of a single relation from the prerequisite task's Completed Time to the current task's Scheduled Time, you now see the relations depicting the created, launched, scheduled, started, finished and completed stages of each prerequisite task enabled:



When analyzing your data, we recommend trying to activate each option one at a time as the number of relations can quickly become overwhelming.

When the Critical Path option is enabled, relations showing the critical path of the current task are drawn. The critical path is defined as the execution chain in the current task's graph that has the longest execution time. Each component task's execution time is defined as the difference between the component's FinishedTime and StartTime (FinishedTime - StartTime).

This Engine feature is new, therefore the formula is subject to change with optimizations in the future.



If a trace has Task data, then the Tasks minor tab becomes visible. To populate the tab, select an interval on the timing view. The tab updates to show all the tasks in the selected interval. The tab shows each of the included timestamp options: created, launched, scheduled, started, finished, and completed timestamps. By default, these timestamps are shown Relative to previous, which means they are relative to the previous stage, for instance scheduled is relative to launched. Double-clicking on a task in the table draws its relations as if it was selected by selecting a timing event in the timing view.



Setup

Hierarchy Sorting

Preset Options

Column Sorting

Unreal Cooking Insights provides you with the ability to gather and display information about the way packages are cooked in your project. Large cooking times can significantly affect the productivity of teams that are working on larger projects. By showing the times it takes to cook each package, this tool can help reduce cooking times.

Setup

You can run a trace for cooking insights from the command line by using the command:

Alternatively, you can run the following command to target a specific host and platform:

When loading a trace that contains cook data, the Packages table will be populated with the load time, save time, and cooking time for each package when the analysis is complete.



Hierarchy Sorting

When selecting the Hierarchy filter, you can choose from the following Grouping options.



Hierarchy Grouping Option

Description

Flat (All)

Creates a single group that includes all items.

Unique Values - Asset Class

Creates a group for each unique value.

Path Breakdown - Package Name

Creates a tree hierarchy out of the path structure of string values.

Preset Options

When observing your package data, you can navigate to Preset to configure your tree view.



You can choose from the following Presets:

Preset Option

Description

Default

Shows the default packages info.

Package Path

Groups packages by the package path.

Asset Class

Groups packages by their most important Assets.

Column Sorting

Cooking Insights groups specific package data in the following columns.

Column Name

Description

Hierarchy

Hierarchy of the package's tree.

Id

The Id of the package.

LoadTime

The amount of time it took to load the package.

SaveTime

The amount of time it took to save the package.

BeginCache

The total time spent in the BeginCacheForCookedPlatformData function for the package.

IsCachedCooked

The total time spent in the IsCachedCookedPlatformDataLoaded function for the package.

Asset Class

The class of the most significant Asset in the package.

You can sort columns into the following sorting categories.

Sorting Option

Description

Sort Ascending

Sort your chosen column in ascending order.

Sort Descending

Sort your chosen column in descending order.

Sort By

Sort your column by the following values:

Package Hierarchy

Id

LoadTime

SaveTime

BeginCache

IsCachedCooked

AssetClass



You can also customize the table by showing and hiding columns individually by using the following options.

Column Visibility

Description

View Column

Hides or shows columns.

Show All Columns

Resets the tree view to show all columns.

Reset Columns to Default

Resets columns to default.

Recording a Session

Run or Build Unreal Insights

Run Your Game Project with Memory Tracing

Open your Trace from the Insights Session Browser

Unreal Engine 5 (UE5) expands the capabilities of Unreal Insights by adding improved memory tracking and profiling support into its Memory Insights feature. Developers can now see more detailed information about memory allocation and deallocation, including the Low Level Memory (LLM ) tags and callstacks associated with each block of memory at any point in time. Memory Insights features a query system that can find live allocations at a certain point in time, recognize increases or decreases in memory usage, differentiate short-term and long-term allocations, and find memory leaks.

Recording a Session

To begin using Memory Insights to record a trace in the memory channel, follow the steps below:

Navigate to Start > Command Prompt and enter the following:

Alternatively, you can navigate to your Engine\Binaries\Win64 folder and double-click to run the UnrealInsights.exe.



Launch the Command Prompt from your operating system and run your project sample:

Recording a session of your project requires the memory trace channel to be active from the beginning of the process. Otherwise, it won't be possible to start tracing allocation events in a late-connect session. Additionally, if you're running a trace on a packaged project, you need to ensure that it is packaged in Development mode.

You can use the trace command metadata and assetmetadata to provide additional filtering options for asset names and class names. For example, you can calculate the cost of memory allocation per asset, or per class name.

Navigate back to the Unreal Insights Session Browser, then double-click your .utrace file to open it for analysis in the Unreal Engine Timing Insights window. Select Menu > Memory Insights to open the Memory Insights window.



Memory Allocation - Graph Tracks

Unreal Insights captures complete call stacks for each allocation event to provide you with an analysis of your project's allocated memory. The main interface for Memory Insights consists of a timeline showing an overview of memory usage during the session.



The Memory Insights tracker shows information about the number of live allocations in memory. Pictured above is the Main Memory graph along with the Live Allocation and Free Event Count.

The Main Memory Graph shows the total amount of tracked memory in your project, including information on each tag that is gathered from the LLM. Additionally, there are graphs that display the total number of live allocations:

Graph Type

Color

Description

Total Allocated Memory

Blue

Shows the total amount of memory allocated at each point in time, based on detailed allocation tracking.

Live Allocation Count

Yellow

Shows the total number of active allocations at any point in time.

Allocation/Free Event Count

Green/Orange

Shows the number of allocation and free events per unit, which is represented as a "slice" of time.

Each of these graphs is based on detailed allocation tracking. They start at a time value of 0 and have a granularity of approximately 1ms. The other graphs with the LLM prefix tags(RenderTargets, SceneRender, UObject) are based on a Low-Level Memory tracking runtime system.

These tags will start tracking several seconds after the session has started and contain a per-frame granularity.

By default we emit one timestamp at each 4096 allocation / free event, You can change this amount if needed by modifying the MarkerSamplePeriod located in Engine/Source/Runtime/Core/Private/ProfilingDebugging/MemoryAllocationTrace.cpp. For example, setting this variable to a value of 0 will emit a timestamp after each allocation / free event.

The Memory Insights timeline supports overlaying tracks onto the Timing View. When using the Memory Insights view there are four panels available, the Timing, Investigation, LLM Tags, and Modules panels.

You can click Timing to toggle the display of the Timing View window. Here you can observe and filter the performance data of different tracks relating to memory usage.



The Investigation panel lets you make different queries about allocations.



The LLM Tags panel controls the visibility of different LLM tags. This data is traced directly from your operating system.



You can group LLM tags, Assets, and Source files

When call stack symbols are resolved, the result is stored in the cache file. You can view these files by clicking Modules. This panel lets you open old trace files and use symbols.



You can observe the columns for the number of of symbols that are Discovered, Cached, Resolved, and Failed. List items that failed are highlighted in red, and list items that resolved properly are highlighted in green. Yellow indicates that some of the symbols have resolved and some have failed.



The previous runtime implementation of memory tracking is implemented in the LowLevelMemTracker class located in the folder Engine\Source\Runtime\Core\Public\HAL\LowLevelMemTracker.h. Both the LLM Tags panel and the LLM graphs use data traced directly from this system. The detailed allocation data comes from a separate and specific trace implementation.

Memory Insights contains new querying features and tracked memory allocation information. You can identify blocks of memory that UE5 allocates and frees within certain time windows, before or after a specific moment in time, or check for memory leaks. You can access the query system by going to the Investigation tab after opening a trace log.

Investigation - Allocation Queries

While the timeline provides an overview of memory usage, evaluating how individual allocations behave over a span of time is done by using "queries". A Query is defined by a Rule and one or more Timestamps, such as the labels A and B.



The Investigation panel contains query rules to evaluate data.

The available Query Rules are as follows:

Query Rule

Time Variable

Description

Active Alloc

A

Displays all active allocations at time A.

Before

A

Displays all allocations before time A.

After

A

Displays all allocations after time A.

Decline

A and B

Displays all allocations that were allocated before time A and freed between time A and time B.

Growth

A and B

Displays all allocations that were allocated between time A and B and freed after time B.

Growth Vs Decline

A and B

Identifies both "growth" allocations (allocated between time A and time B and freed after time B) and "decline" allocations (allocated before time A and freed between time A and time B). The decline allocations are changed to have a negative size, so the size aggregation shows variation between A and B. The result of this query is a comparison of what was allocated at time A with what was allocated at time B. A grouping of memory allocations by tags or call stack will show variation (B - A) for each group.

Free Events

A and B

Displays all allocations that were freed between time A and B.

Alloc Events

A and B

Displays all allocations that were allocated between time A and B.

Short Living Allocs

A and B

Displays all allocations that were allocated after time A and freed before time B. This rule can be used to identify allocations that could be stack allocations, meaning that this identifies temporary or short-lived allocations.

Long Living Allocs

A and B

Displays all allocations that were allocated before time A and freed after time B.

Memory Leaks

A, B, and C

Displays all allocations that were allocated between time A and B and not freed until after time C. This is useful to find memory that would be expected to be released at a given time, for example during a level transition.

Limited Lifetime

A, B, and C

Displays all allocations that were allocated between time A and B and freed between time B and C.

Decline of Long Living Allocs

A, B, and C

Displays all allocations that were allocated before time A and freed between time B and C.

Specific Lifetime

A, B, C, and D

Displays all allocations that were allocated between time A and B and freed between time C and D.

Queries are made by selecting a rule and dragging the labeled markers in the timeline to desired locations, or by specifying a time in the Investigation tab.



Once the desired rules and times have been selected press the Run Query button in the Investigation tab to make the query.



Depending on the query and data set that is being captured the queries may take a considerable amount of time to execute.

Allocation Breakdown View

When the query is run a new window appears, upon completion of the query the Alloc table is populated with the result. By default, these results will be displayed in a flat list.

Each allocation is displayed with a Count, Size, LLM Tag,, Callstack Size and the Function that made the allocations.



Hovering over the function or the information icon will display additional details and the full call stack.





The full call stack is displayed when hovering over the Information icon.

Sorting

By clicking on the table headers, you can sort the list by different columns.



Sort Column

Description

Allocation Hierarchy

Sorts by the hierarchy of the allocation tree.

Allocation Count

Sorts by the numbers of allocations.

Size

Sorts by the size of the allocations.

LLM Tag

Sorts by the LLM tag of the allocations.

Top Function (Callstack)

Sorts by the resolved top function from the call stack of the allocations.

CallStack Size

Number of callstack frames.

Grouping

Preset options can be used to group allocations together.



Preset Option

Description

Default

Displays the default allocations

Detailed

Configures the tree view to show detailed allocation information.

Heap

Investigates how different types of memory are used. See Multiple Address spaces .

Size

Finds any large allocations quickly.

Tags

Displays the allocations per system.

Asset

Configures the tree view to show a breakdown of allocations by their Asset tag.

Class Name

Configures the tree view to show a breakdown of allocations by their Class name.

Callstack

Investigates which call stack allocations are coming from.

Inverted Callstack

Configures the tree view to show a breakdown of allocations by Inverted Callstack.

Address(4k Page)

Groups allocations into 4k aligned memory pages based on their address.

You can right-click on items in the context menu and select the action to Open in Visual Studio.

Pressing the R key shortcut will expand the critical path in the current tree.



Navigating to Hierarchy and clicking All will open a dropdown menu to change the default Flat view into additional, alternative groups.



You can group the Hierarchy from the list of the following options.

Hierarchy Group

Description

Flat

Creates a single group that includes all items.

Size

Groups allocations based on their size.

Tag

Creates a tree based on tag hierarchy.

Callstack

Creates a tree based on the Callstack of each allocation.

Inverted Callstack

Creates a tree based on the Callstack of each allocation.

Heap

Creates a tree based on Heap.

Unique Values - Event Distance

Creates a group for each Event Distance value

Unique Values - Start Time

Creates a group for each Start Time value

Unique Values - End Time

Creates a group for each End Time value

Unique Values - Duration

Creates a group for each Duration value

Unique Values - Address

Creates a group for each Address value

Unique Values - Memory Page

Creates a group for each Memory Page value

Unique Values - Size

Creates a group for each Size value

Unique Values - LLM Tag

Creates a group for each LLM Tag value

Unique Values - Asset

Creates a group for each Asset value

Unique Values - Class Name

Creates a group for each Class Name value

Unique Values - Top Function

Creates a group for each Top Function value

Unique Values - Top Source File

Creates a group for each Top Source File value

Unique Values - Callstack Size

Creates a group for each CallStack Size value

Path Breakdown - LLM Tag

Creates a tree hierarchy out of the structure of LLM Tag string values.

Path Breakdown - Asset

Creates a tree hierarchy out of the structure of Asset Tag string values.

Path Breakdown - Top Source File

Creates a tree hierarchy out of the structure of Top Source File string values.

Advanced Filtering

The search text box provides a method to quickly filter the result based on the hierarchical node text. The set of allocations produced by the query can be further filtered to isolate a group of allocations, by clicking Filter Configurator next to the search text box.



It is possible to build advanced queries using groups and AND/OR keywords.

Call Stack Symbol Resolving

Call Stack Symbol Tracing from your project is accomplished using program counter addresses. In analysis, these addresses need to be resolved to readable strings along with information about the corresponding source files.

This requires that Memory Insights has access to the correct version of the file containing the debug information. either a .pdb or .elf file (depending on the platform). Insights will search for the correct file according to the following list:

Any new paths entered by the user in this session.

Path of the executable (If available on some platforms, this will be compiled into the binary).

Paths from the UE_INSIGHTS_SYMBOLPATH environment variable. This variable accepts semicolon-separated paths.

Paths from the user configuration file.

When symbols are resolved, the results are stored in the cache file. You can view these files by clicking the Modules panel. You can then open these files by right-clicking your selected file and selecting one of the following options from the dropdown menu.



It provides you a method to send the trace file to other users without requiring them to have access to that debug information.

Load Method

Description

Load symbols from file

Loads symbols for a module by specifying a file. If successful, it tries to load other failed modules from the same directory.

Load symbols from directory

Loads symbols for a module by specifying a directory. If successful, it tries to load other failed modules from the same directory.



Symbol resolving is currently available on Win64, XB1/XSX, PS4/PS5 and Switch.



Multiple Address Spaces

Memory tracing tracks memory in different heaps. Conceptually, any allocation must belong to a root heap, representing one type of memory. For example, on desktop platforms, one root heap is the system memory and the other is the video memory on the graphics card. Each root heap has its own address space. Under each root heap, heap allocations are made that can host allocations. Usually, this means virtual memory allocations which back up allocations, however, block-style allocators can also be represented with heap allocations. This provides the investigation of the use of those blocks of memory.

Setup

Using Networking Insights

Networking Insights Window

Packet Overview Panel

Packet Content Panel

Connection Selection Panel

Net Stats Panel

NetStatsCounters

Example Data

Replicated Objects

RPCs

Split Bunches

SubObjects

Unreal Insights includes Networking Insights to analyze, optimize and debug network traffic. Users can record trace information to visualize network behavior with the following features:

Game Instance control to display visible machines during the network sessions being recorded

Connection Mode control to visualize outgoing or incoming data

Packet Overview panel that displays packet timelines (and sizes) being transmitted or received during a game

Packet Content panel that shows a packet's content, such as replicated objects, properties, and remote function calls

Net Stats panel that displays trace events for selected packets, including statistics about the total, maximum, and average exclusive (or inclusive) packet sizes.



Setup

Before continuing, ensure that you are running Unreal Insights.

Using Networking Insights

To analyze data start your project instances with the following command-line option:

VerbosityLevel should be set to a value of greater than zero. For example, if a game instance starts with -NetTrace=1, Unreal Insights will collect and report network trace data for analysis by opening the session in Unreal Insights.

The editor runs its own data store for trace data, which means that you need to specify the tracehost in order to collect network trace data while running in the editor. To specify the tracehost, use: -NetTrace=1 -tracehost=localhost -trace=net

You can trace simple stats associated with network trace data by using the macros UE_NET_TRACE_PACKET_STATSCOUNTER and UE_NET_TRACE_FRAME_STATSCOUNTER. Data traced with either of these macros will be displayed in the NetStatsCounters tab.

Networking Insights Window

The Networking Insights window is where you'll find networking session data.

For additional commands, tips, and information on other Unreal Insights windows , refer to the Reference documentation.



The Networking Insights window features the Connection Selection panel(1), the Packet Overview panel(2), the Packet Content panel(3), and Net Stats panel(4).



Packet Overview Panel

The Packet Overview panel displays a bar graph that shows the size (in bits) for every packet received or transmitted. This is useful for identifying large packets that need further investigation. Left-click the bar to select a packet.

The reported size of each packet is before compression, so the actual data on the wire may be smaller than what the report shows.



Hovering over a packet displays its information. This information includes:

Packet Index

Sequence Number

Content Size in bits

Total Size in bytes, with unused bits

A timestamp for when the packet was sent or received

The packet's current status (delivered or undelivered)

The connection state in which the packet was received

Engine frame number of when the packet was sent or received

Dropped packets are displayed in red. To select multiple packets, click to select an inital packet, then hold the Shift key and click other packets. You can highlight an event in the Packet View, to help you see how many bits that specific event is using in the packet. This makes it possible to quickly see how much bandwidth an event is using relative to other data.

You can choose to highlight either: +The aggregated bitcount for all instances of the event; or +The maximum bitcount used by a single event.

Packet Content Panel

The Packet Content panel displays the actual content of the currently selected packet. The packet's content displays as a hierarchical event graph starting with bit zero on the left side. This is the main tool to investigate the data contents in each packet down to the property level.



The packet content panel displaying bunches of data contained in a packet. This includes information about replicated objects and properties.



The first level displays the bunches contained in a packet. Each bunch is named after the channel that it belongs to. If the reported bunch has its debug name set when reported, the debugname will be used instead of the channelname to provide additional context (where available).

The second level typically displays replicated objects contained in the bunch. If the event has an assigned NetId(NetGUID), the ID is on display as well.

Events further down the event hierarchy display replicated properties, including how many bits they wrote.

Hovering over an event displays all of the event's information.

The panel features controls to find a packet, or to find events belonging to a specific NetId.

You can navigate the Packet Content Panel and Packet Overview Panel using your keyboard. The up and down arrow keys will move between levels. The left and right arrow keys will move between events on the same level. If you hold the CTRL or CMD key and press the left or right arrow keys, you will move between packets.

Connection Selection Panel

The top of the Packet Overview panel has controls that let users select the data to display.



The connection dropdown lists located at the top of the Packet Overview panel. This example shows Player 0's connection in a server game instance, with incoming data selected.



Three dropdown lists are available in the Connection Selection panel:

Dropdown List

Description

Game Instance

Displays the created Game Instance for each unique NetDriver observed during a recording session. For example, when using PIE, there are separate instances for the server and each client.

Connection

This dropdown selects a specific connection, displaying every observed connection during the selected Game Instance's session.

Connection Mode

This dropdown controls whether to visualize incoming our outgoing data.

Net Stats Panel

The Net Stats panel lists all trace events for the selected packet range in the Packet Overview panel.



The Net Stats panel with events grouped by level



In addition to aggregating data based on a selected range, users can sort the list in ascending or descending order by the values in any active column. Right-click anywhere in the list to change the sort order, or to activate or deactivate columns. The following columns are available:

Type

Level

Instance Count

Total Inclusive Size (bits)

Max Inclusive Size (bits)

Total Exclusive Size

Max Exclusive Size

To filter events by name, use the "search net events or groups" field. Users can group according to these event types:

Group Name

Description

Level

Creates one group for each level.

Flat

Creates a single group. Includes all Net Events.

Name

Creates one group for one letter

Grouping by Level helps users understand their data better because the same name can appear on different levels. The following table describes these levels:

Level

Description

0

Typically channel information that displays all bunches using the channel name.

1

Replicated Object (Actor), most events at this level show the serialized object.

2

Reports events originating from property replication or from RPCs.

3

Reports events when serializing properties.

4

Reports additional events when serializing properties, array content, and more.

The Net Stats panel features a !0 toggle to filter out event types that have no data in the selected range.

NetStatsCounters

The NetStatsCounters tab is where you can view stats counters related to the replication system for the selected packet or range of packets.



There are two different categories of stats:

FrameStats: Stats counters for the entire frame. This is typically used for reporting stat counters related to networking, for work that is shared between all connections. For example, how many objects are currently being updated on this frame.

PacketStats: Stats counters related to each specific packet. For example, how many objects were scheduled to be serialized, and how many actually did fit into the packet.

Example Data

Information about network packet content tracing macro is in the Unreal Insights Reference.

To better understand the data that Networking Insights visualizes, we offer the following examples:

Replicated Objects



This is the initial replication of a new Actor--ReplicationGraphDebugActor, NetGUID 10.



Before the bunch containing the new actor, there is a NetGUID bunch containing all of the exported references from the new Actor, including NetGUIDS.

RPCs



This is an RPC named ClientAckGoodMove that targets PlayerPawn_C with NetGUID 14.



GUIDs must be mapped.

Split Bunches

Event data generated from transmitting a split bunch report with the first part--when receiving a split bunch, parts are reported first, and when all parts are received, events are reported with the final part.



This is a split outgoing bunch. Note that the events in the bunch are larger than the Bunch.



The next few packets look like the following:





Incoming split bunches exhibit the opposite pattern, where events report with the last partial bunch.



SubObjects



This is a SubObject example--note that the second Actor after BotPawn_C shares the same bunch.



Setup

Using Slate Insights

Slate Frame View

Invalidation Trace Flags

Update Trace Flags

While developing the user-interface (UI) for applications, UI programmers can have a difficult time finding the source of changes that trigger UI updates. Slate Insights assists developers improve the performance of their UI by providing the tools to identify the root cause of a specific Slate and UMG update.





The Slate Frame View running in Slate Insights.



While using the Slate Insights plugin, developers can use Slate Frame View to get a list of widgets being painted, invalidated, or updated per frame. Slate Insights enables developers to debug and optimize their UI.

Setup

Using Slate Insights

To begin using Slate Insights in the editor, you can either enable the plugin from inside the editor or from the *.uproject file. To enable the Slate Insights plugin from the editor, locate it under Editor > Plugins > Built-In > Slate Insights.



Otherwise, enable the plugin from the project's *.uproject file.



If you built the editor from source, you will need to compile and run the editor for your project after enabling the required plugin.



After enabling the required plugin, restart the editor. follow these steps to trace data for Slate Insights.

Open the game project in the editor, and open Editor Preferences.

Under Level Editor - Play > Play in Standalone Game, enter -trace=slate into the Additional Launch Parameters text box.

Learn more command-line options in the Unreal Insights Reference.

Set the project's Active Play Mode to Standalone Game.



If Unreal Insights hasn't been built, find the Unreal Insights project under Engine\Source\Programs\UnrealInsights, and build the application.

Run the UnrealInsights application. Find the application under Engine\Binaries[Platform].

With Unreal Insights running, run the project to record the application's trace data.

Traces automatically write to the following project directory: %appdata%/local/UnrealEngine/Common/UnrealTrace/Store/001 .

Because trace sessions can grow in size over time, make sure to actively monitor and manage the *.utrace files.

After recording the project's trace data, close the standalone application.

To start the analysis in Unreal Insights, select the project's trace session (1) and click Open (2).



To open the Slate Frame View tab, select Menu > Slate Frame View

For general information about navigation and using Unreal Insights, read the Unreal Insights Overview.

Analyze the UI data with Slate Frame View.

Slate Frame View

After capturing the application's trace data with Unreal Insights, open the *.utrace file to begin analyzing the UI states with Slate Frame View.



Slate Frame View features two report areas, Invalidation and Update. Each area features its own collection of trace flags.

Invalidation Trace Flags

The Invalidation Trace Flags area reports Widget information, including a corresponding Amount and one or more Reason for the widget invalidation. When expanding widgets to review their invalidation reasons, Slate Frame View highlights one or more flags from the "LPUCRV" flag list, defined as follows.

Flag

Definition

L

Layout flag. True means the widget's desired size changed.

P

Paint flag. True means the widget needs repainting but nothing affects its size.

U

Volatile flag. True means the widget volatility changed.

C

Child order flag. True means a child was added or removed, implying a layout exists.

R

Render transform flag. True means the widget render transform changed.

V

Visibility flag. True means the widget visibility changed, implying a layout exists.

Update Trace Flags

The Update Trace Flags area reports Widget information, including a corresponding Amount and one or more Reason for the widget update. When expanding widgets to review their update reasons, Slate Frame View highlights one or more flags from the "UTPV" flag list, defined as follows.

Flag

Definition

U

Tick flag. True means the widget was updated.

T

Active timer update flag. True means the widget had an active timer.

P

Repaint flag. True means the widget was dirty and repainted.

V

Volatile flag. True means the widget was volatile and repainted.

Trace Channels

Controlling Runtime

Macros

Command-Line Options for UnrealInsights.exe

Console Commands

Controlling Unreal Insights

Command-Line Options

Keyboard Input Shortcuts

Timing Insights Window

Frames Panel

Timing Panel

Networking Insights Window

Trace Channels

Trace is capable of emitting large amounts of data. Channels prove you with control of the data rate when tracing. Each event type is tied to one or more channels, if the required channels are not enabled then the event will not be emitted to the trace stream.

Channel presets groups many channels and provides scenario-based entry points. Users can define their own presets using config files added to the [Trace.ChannelPresets] category.

Available trace channels are included in the table below. You can observe a list of channels that include details on each Channel's File Path, Supported Platforms and Notes:



The plural forms of the name are automatically deduced, "bookmark" and "bookmarks" are treated identically.



Channel

Notes

Supported Platforms

File Path

Log

Logs Messages.

Runtime\Core\Private\Logging\LogTrace.cpp

BookMark

Low frequency markers signifying important transitions, providing a quick overview for users. Such as level loading or engine boot phases.

Runtime\Core\Private\ProfilingDebugging\MiscTrace.cpp

Frame

Game and Rendering frames.

Runtime\Core\Private\ProfilingDebugging\MiscTrace.cpp

Stats

Stats counters. Based on the Stats system.

Runtime\Core\Private\Stats\StatsTrace.cpp

Counter

Generic counters. Allows tracing of values (float, integer) over time. Counters Trace API. It also enables the CSV Profiler Trace.

Runtime\Core\Private\ProfilingDebugging\CountersTrace.cpp

CPU

-statnamedevents

Runtime\Core\Private\ProfilingDebugging\CpuProfilerTrace.cpp

ContextSwitch

Trace context switch events. On Windows, game/editor runtime should be "run as administrator".

Win64

XBox

PS4/PS5

Runtime\Core\Private\ProfilingDebugging\PlatformEvents.cpp

Task

Task Graph trace channel.

Runtime\Core\Private\Async\TaskTrace.cpp

GPU

Named gpu timers. Based on GpuProfiler data.

Runtime\RHI\Private\GpuProfilerTrace.cpp

RHICommands

Cpu/Gpu named timers for RHI commands.

Runtime\RHI\Private\RHICommandList.cpp

RenderCommands

Cpu/Gpu named timers for commands executed on the rendering thread.

Runtime\RenderCore\Private\RenderingThread.cpp

File

File I/O trace channel (Open, ReOpen, Read, Write, Close events).

Win64

Mac,

XBox

PS4.

Runtime\Core\Private\ProfilingDebugging\PlatformFileTrace.cpp

LoadTime

Asset Loading Insights trace channel. Package load times (specific trace events) + named cpu timers specific to package loading. Requires "cpu" channel. Also adds the "LoadPackageInternal" cpu timing events (with metadata). See usage of SCOPED_LOADTIMER and SCOPED_CUSTOM_LOADTIMER macros.

Runtime\Core\Public\ProfilingDebugging\LoadTimeTracker.h Runtime\Core\Private\Serialization\LoadTimeTrace.cpp

SaveTime

Named CPU timers specific to package saving. This requires the "CPU" channel. Adds cpu timers named with "UPackage_Save_" prefix. See the usage of the SCOPED_SAVETIMER macro for additional details.

Runtime\CoreUObject\Private\UObject\SavePackage\SavePackageUtilities.h / .cpp

Cook

Displays named CPU timers specific to cooking. This requires the "CPU" channel. It will add the "CookByTheBook" cpu timing events and add the "SaveCookedPackage" cpu timing events (with metadata).

Editor\UnrealEd\Private\Cooker\CookProfiling.h/.cpp

Net

Networking trace channel. Requires -NetTrace=1 (it enables the "Frame" channel)

Runtime\Net\Core\Private\Net\Core\Trace\Reporters\NetTraceReporter.cpp

Module

Module loading information

Runtime\Core\Private\ProfilingDebugging\ModuleDiagnostics.cpp

Win64

XBox

PS4/PS5

Switch

Callstack

Callstack descriptions. Allows allocations to be associated with callstacks.

Requires Module channel to be enabled for symbol resolution to be possible.



Runtime\Core\Private\ProfilingDebugging\CallstackTrace.cpp

Win64

XBox

PS4/PS5

Switch

MemAlloc

Memory allocations. Uses Module and Callstack.

Runtime\Core\Private\ProfilingDebugging\MemoryAllocationTrace.cpp

Win64

XBox

PS4/PS5

Switch

MemTag

Memory tag statistics. Traces snapshots of memory usage per tag at regular rate. Relies on LLM subsystem for tracing. Implies "-llm". Available after Init().

Runtime\Core\Private\HAL\LowLevelMemTracker.cpp

VisualLogger

Visual Logger starts recording to file.

Runtime\Engine\Private\VisualLogger\VisualLoggerTraceDevice.cpp

Physics

Chaos Visual Debugger.

Runtime\Experimental\Chaos\Private\ChaosVisualDebugger\ChaosVisualDebuggerTrace.cpp

Animation

Animation Insights(GameplayInsights/RewindDebugger) plugin.

Runtime\Engine\Private\Animation\AnimTrace.cpp

Object

GameplayInsights/RewindDebugger plugin. UObject classes, worlds, instances and events.

Runtime\Engine\Private\ObjectTrace.cpp

ObjectProperties

GameplayInsights/RewindDebugger plugin.

Plugins\Animation\GameplayInsights\Source\GameplayInsights\Private\ObjectPropertyTrace.cpp

NetworkPrediction

Network Prediction Insights plugin.

Plugins\Runtime\NetworkPrediction\Source\NetworkPrediction\Private\NetworkPredictionTrace.cpp

RDG

RDG Insights plugin.

Runtime\RenderCore\Private\RenderGraphTrace.cpp

Slate

Slate Insights plugin.

Runtime\SlateCore\Private\Trace\SlateTrace.cpp

Niagara

Niagara plugin.

Plugins\FX\Niagara\Source\Niagara\Private\NiagaraTrace.cpp

Messaging

UDP Messaging plugin.

Plugins\Messaging\UdpMessaging\Source\UdpMessaging\Private\UdpMessagingTracing.cpp

TraceSourceFilters

Trace Source Filtering plugin.

Plugins\Developer\TraceSourceFiltering\Source\SourceFilteringTrace\Private\SourceFilterTrace.cpp

PoseSearch

PoseSearch plugin.

Plugins\Experimental\Animation\PoseSearch\Source\Runtime\Private\Trace\PoseSearchTraceLogger.cpp

Concert

Concert plugin.

Plugins\Developer\Concert\ConcertMain\Source\ConcertTransport\Private\ConcertLogGlobal.cpp

LevelSnapshots

Level Snapshots plugin.

Plugins\VirtualProduction\LevelSnapshots\Source\LevelSnapshots\Private\LevelSnapshotsLog.cpp

Some plugins or runtime code enables or disables channels automatically, they are listed in the table below:

Plugin

Channel Description

Gameplay Insights/ Rewind Debugger

Toggles the Object channel when Play in Editor (PIE) is started, and toggles ObjectProperties, Animation, and Frame when a recording is started.

TraceSourceFiltering

When the plugin is enabled, the TraceSourceFilters channel is toggled on.

NetworkPrediction

When the plugin is enabled, the NetworkPrediction channel is toggled on.

PoseSearch

When the plugin is enabled, the Pose Search channel is toggled on.

Visual Logger

When recording the Visual Logger channel is toggled on.

-NetTrace=1

When enabled from the command line, the Net and Frame channels are toggled on.

Controlling Runtime

Macros

To get the most out of the many features that ship with Unreal Insights, You can customize your project's output with macros and command-line options. Additionally, mouse and keyboard input shortcuts provide users with the capability to navigate Insights windows more efficiently. You can reference the table below to determine which macros you may want to adjust based on the data that you want to see in Unreal Insights:

Macro name

Default State

Source File

Area Description

UE_TRACE_ENABLED

On

Engine/Source/Runtime/TraceLog/Public/Trace/Config.h

Master control for the entire system.

UE_TASK_TRACE_ENABLED

On

Engine/Source/Runtime/Core/Public/Async/TaskTrace.h

Controls tracing of Task Graph events. -trace=default,task

LOGTRACE_ENABLED

On

Engine/Source/Runtime/Core/Public/Logging/LogTrace.h

Controls whether log messages are reported to Unreal Insights. -trace=log

MISCTRACE_ENABLED

On

Engine/Source/Runtime/Core/Public/ProfilingDebugging/MiscTrace.h

Controls tracing for bookmarks, frames, threads, and thread groups. -trace=bookmark,frame

CPUPROFILERTRACE_ENABLED

On

Engine/Source/Runtime/Core/Public/ProfilingDebugging/CpuProfilerTrace.h

Controls tracing for CPU timers and timing events. -trace=cpu

LOADTIMEPROFILERTRACE_ENABLED

On

Engine/Source/Runtime/CoreUObject/Public/Serialization/LoadTimeTrace.h

Controls tracing for events related to load assets. -trace=loadtime

STATSTRACE_ENABLED

On

Engine/Source/Runtime/Core/Public/Stats/StatsTrace.h

Controls tracing for stats counters. -trace=stats

PLATFORMFILETRACE_ENABLED

On



The default enabled behavior only applies for Windows, Mac, and PS4 platforms.



Controls tracing for file activity, such as opening, closing, reading, and writing files. -trace=file

PLATFORM_SUPPORTS_PLATFORM_EVENTS

On

Engine/Source/Runtime/Core/Private/ProfilingDebugging/PlatformEvents.h

On for platforms with support for platform events (context switch events). -trace=ContextSwitch

GPUPROFILERTRACE_ENABLED

On

Engine/Source/Runtime/RHI/Public/GpuProfilerTrace.h

Controls GPU timers and timing events. -trace=gpu

UE_NET_TRACE_ENABLED

On

Engine/Source/Runtime/Net/Core/Public/Net/Core/Trace/NetTrace.h Engine/Source/Runtime/Net/Core/Public/Net/Core/Trace/Config.h

Controls tracing of network packet content. -trace=net

UE_MEMORY_TAGS_TRACE_ENABLED

On

Engine/Source/Runtime/Core/Public/ProfilingDebugging/TagTrace.h

Enables tracing of tag scopes. If disabled traced allocation will not have an associated tag. -trace=memtag

UE_CALLSTACK_TRACE_ENABLED

On

Engine/Source/Runtime/Core/Public/ProfilingDebugging/CallstackTrace.h

Enables tracing of callstacks. If disabled traced allocations will not contain callstacks. -trace=callstack

Command-Line Options for UnrealInsights.exe

Command-Line Option

Usage

Description

-OpenTraceId

-OpenTraceId=id

Forces Unreal Insights to start analyzing the specified ID in "Viewer mode"

-OpenTraceFile

-OpenTraceFile=file.utrace

Forces Unreal Insights to start analyzing the specified file in "Viewer mode"

-Store

-Store=address:port

-StoreHost=address and -StorePort=port

Console Commands

Command

Description

Trace.Send <Host> [ChannelSet]

Starts tracing to a trace store. is the IP address or hostname of the trace store. [ChannelSet] is an optional comma-separated list of trace channels/presets to be enabled.

Trace.File [<File>] [ChannelSet]

Begins tracing events to a file. If a file path is not specified, then the default path directory for the utrace file is: YourProject/Saved/Profiling. If a name is not specified, the name of the utrace file is generated automatically based on the current timestamp. Supports Late Connect.

Use Examples:

trace.file [ChannelSet]paths to YourProject}/Saved/Profiling/ the *.utrace. Filename is generated automatically.

trace.file MyFile.utrace [ChannelSet] paths to YourProject/Saved/Profiling/MyFile.utrace.

trace.file C:/Path/ [ChannelSet] is an absolute path, the filename is generated automatically.

trace.file Path/ [ChannelSet] is a relative path to YourProject/Saved/Profiling/, the filename is generated automatically.



Trace.Start[ChannelSet]

Keeps the default enabled channels.

Trace.Stop

Stops tracing profiling events.

Trace.Enable[ChannelSet]

Enables a set of channels.

Trace.Disable[ChannelSet]

Disables a set of channels. If no channel set is specified, all channels will be disabled.

Trace.Pause

Pauses all trace channels currently sending events.

Trace.Resume

Resumes tracing that was previously paused (re-enables the pushed channels).

Trace.Status

Prints the trace status to the console.

Controlling Unreal Insights

Command-Line Options

When combined with macros, the following command-line options enable trace data:

Command-Line Option

Description

-trace -trace=<channel1>

-trace=cpu,frame,bookmark

-tracehost=<ip>

-tracehost, refer to the Unreal Insights

-tracefile, -tracefile =<filename>

Performs a "WriteTo" file trace control command. This will run the trace default command.

-tracefiletrunc

-tracetailmb= N

N specifies the size of the trace tail buffer in MiB. The default size of the trace tail buffer is 4 MiB.

-notraceserver

If specified, the game or editor will not start the local trace server.

-statnamedevents

logs trace data for stat named events. Can be enabled by GCycleStatsShouldEmitNamedEvents = 1; or from calling "Stat NamedEvents" as a console command.

-verbosenamedevents

logs trace data for verbose named events. Can be enabled by GCycleStatsShouldEmitVerboseNamedEvents = 1; or from calling "Stat VerboseNamedEvents" as a console command. An example of a verbose cycle status: "CPU Stall - [...]", "Other TaskGraph Stalls", "FQueuedThread::Run.WaitForWork".

Keyboard Input Shortcuts



All input operations and control references are limited and subject to change.



Timing Insights Window

The following mouse and keyboard commands help you navigate Timing Insights more efficiently:

Keyboard Input Shortcut

Function

Left mouse click

Select a frame

The timing view centers on the selected frame.



Right mouse click

Open context menu

Left/right mouse drag

Horizontal zoom

Mouse wheel

Horizontal zoom

Shift + mouse wheel

Vertical zoom

Input Shortcut

Function

Left/right mouse drag

Horizontal or vertical pan

Ctrl + left/right mouse drag

Horizontal pan

Shift + left/right mouse drag

Vertical pan

Mouse wheel

Zoom

Ctrl + mouse wheel

Horizontal scroll

Shift + mouse wheel

Vertical scroll

Right mouse click

Open context menu

Options available for Graph track.



Left mouse click on Timing Event

Select the timing event

Left mouse click on empty space

Clear selection

Ctrl + double left mouse click

Select time range of selected timing event

Pressing ENTER performs the same function.



Left/right mouse drag over Time Ruler

Select time region

Aggregated states automatically update in Timers and Counters views.



Ctrl+F

Toggles the Quick Find menu.

F

Frame the last selection and then alternate between framing the time range or the timing event

The last selection can be a time range or a timing event.



G

Toggle Graph track visibility, showing Game and Rendering frames, including a placeholder for Counter series

Y

Toggle GPU Timing track visibility

U

Toggle CPU Timing track visibility

I

Toggle I/O Overview and Activity track visibility

O

Toggle visibility of background events for file activities in the I/O Activity track

L

Toggle Asset Loading track visibility

C

Switch between normal and compact mode, affecting how timing events are visualized

V

Auto hide empty timelines

Empty timelines are ones without timing events.



X

Chooses the next event depth limit: Single Lane, 4 Lanes, Unlimited.

B

Toggle visibility of bookmarks

Bookmarks display by default.



M

Toggle visibility of time markers (all trace logs instead of just bookmarks)

Time markers do not display by default.



Zoom

Ctrl + left/right/Up/Down arrows

Horizontal and vertical pan

Left/right/Up/Down arrows

Select timing event that is its previous or next sibling/parent/largest child

Enter

Select time range of selected timing event

Pressing Ctrl + Double Left Mouse Click performs the same function.



Networking Insights Window

The following mouse and keyboard commands help you navigate Networking Insights more efficiently:

Input Shortcut

Function

Left mouse click on packet

Selects the respective packet

Shift + left mouse click on different packet

Selects a range of packets

Ctrl + A

Select all packets

Left/right arrows

Selects previous/next package

Shift + left/right arrows

Extends selection (multiple packages) toward Left/right side

Ctrl + shift + left/right arrows

Shrink selection (multiple packages) from Left/right side

Double click an Event

Highlights all packets containing the event in the Packet Content view while masking out all other events

Using the Zen Loader

Limitations

Inspecting the contents of container files

Troubleshooting

Loading

Staging

Zen Loader Internals

Zen Store

Zen Loader is the new runtime loader for Unreal Engine 5(UE5). Zen Loader reduces CPU overhead by using an optimized package and object dependency graph that is computed offline during the staging phase. Instead of packing all assets into one or more .pak file(s), Zen Loader packages all package data, bulk data and shader data into a set of .utoc and .ucas container files.

The .pak files are used for loose files that are accessed less frequently. When a Pak file is mounted, then the corresponding container file will be mounted too. The .utoc file describes the container file, including chunk size and offset, compression format, and whether the chunks are encrypted. The .uca file contains the actual data.Using container files avoids file system abstractions and provides the loader with the ability to find data chunks with minimal CPU overhead using a new I/O abstraction layer called the I/O dispatcher. It uses platform specific backends to benefit from hardware capabilities and APIs.



Using the Zen Loader

The container files are produced by default during staging with the Unreal Automation Tool(UAT), and the presence of these container files will activate the Zen loader in runtime.

See the Unreal Automation Overview for additional information on how to run commands for your project.

The Event Driven Loader(EDL) runtime loader is deprecated and will be removed in future releases, but you can still use it with UAT during staging by using the command:

Alternatively, you can navigate to your c:MyProject/Config/DefaultGame.ini file, then in the [ProjectPackagingSettings] section add the following line:

Setting the bUseIoStore boolean to the value of False will tell the Zen Loader to not use IOStore.

Limitations

The I/O Dispatcher is a new I/O abstraction layer that loads data addressed by a chunk ID, this means that the data can't be loaded or searched for using the standard file/directory format that is based in the I/O API. The Asset Registry supports similar capabilities for searching for assets in directories. When using the Zen loader, it is no longer possible for Bulkdata to load inline data after the initial serialization has finished, which means that once data is unloaded it cannot be retrieved again. Any data set that requires frequent access needs to be stored as non-inline data during the cooking phase. The Zen loader performs offline preprocessing of object dependencies at stage time. This prevents any required package redirects at runtime, and systems like core redirects and delegate resolvers are ignored during loading.

Inspecting the contents of container files

In the table below, you can view the commands supported by UnrealPak that are compatible for container files.

Command

Description

-list

Lists the chunks in a container.

-diff

Compares the contents of two containers.

-extract

Extracts the contents of a container.

IoStore -describe

Provides detailed information on the container's dependencies, packages, and import and exports. The describe command takes the path to the global.ucas file and uses an output format similar to the one from the PkgInfo commandlet for .uasset files:

UnrealPak.exeIoStore-Describe=MyProject/Saved/StagedBuilds/Windows/MyProject/Content/Paks/Global.ucas-DumpToFile=Output.txt-CryptoKeys=MyProject/Saved/Cooked/Windows/MyProject/Metadata/Crypto.jsonactive_button_content



Troubleshooting

Below you will find some helpful troubleshooting commands to assist you in identifying errors or warnings during each stage.

Loading

During the Loading stage, the Zen loader uses the LogStreaming log channel and Verbose/VeryVerbose logging can be temporarily enabled on the command line by using the command:

For larger projects, logging can be time consuming. You can filter the logs on specific packages by setting your selected package names or package IDs with the command:

If you are running with a debugger attached you can use the command:

This will provide an automatic breakpoint at certain load phases of the specified packages.

Staging

During the staging phase, UAT will generate a command list of one or more response files that specify all the packages stored in each container by using the command:

You can locate this command, and others from the UAT log file located in your directory path:

Zen Loader Internals

The Zen loader is based on the Event Driven Loader(EDL) and requires the same output types from the cooker such as name tables, import / export maps, and preload dependencies. The legacy EDL runtime logic has been moved offline and is produced during the staging phase.

This optimization to offline preprocessing reduces the amount of time it takes for the runtime package dependency tracking to process from seconds down to milliseconds.

Additional changes Include:

Package summaries, export blobs, bulk data and shaders are placed in container files.

The most important package metadata and all package interdependencies are collected into a package store that is indexed by package IDs.

The .uasset package header is transformed to an optimized package summary.

Import maps with outer chains have been removed and replaced with direct references by export object hashes.

Name tables have a new optimized batch format.

Preload dependencies have been flattened into per-package export bundle nodes, each specifying a sequence of CreateExport and SerializeExport calls and dependencies to other export bundle nodes.

Zen Store

Zen Store is an experimental feature that enables you to store cooked assets to a local storage server instead of loose files into the local filesystem. Refer to the Zen Store for additional information.

Zen Store is an experimental feature that enables you to store cooked assets to a local storage server instead of loose files into the local filesystem. The storage server enables games to run on development kits without the need to deploy the game content. The storage server can be enabled by navigating to your C:\MyProject\Config\DefaultGame.ini file and implementing the following settings:

The storage server makes it possible to read chunks over HTTP, by using the command:

This enables games to run on development kits without the need to deploy the game content.



Automation Tests moved to Plugins

Test Design Guidelines

Running Automation Tests

Essentials

The Automation System is built on top of the Functional Testing Framework, which is designed to do gameplay level testing, which works by performing one or more automated tests. Most tests that are written will be functional tests, low-level core or Editor tests that need to be written for using the Automation Framework system. These tests that are written can be broken down into the following categories depending on their purpose or function:

Test Type

Description

Unit

API level verification tests. See TimespanTest.cpp or DateTimeTest.cpp for examples of these.

Feature

System-level tests that verify such things as PIE, in-game stats, and changing resolution. See EditorAutomationTests.cpp or EngineAutomationTests.cpp for examples of these.

Smoke

Smoke tests are just considered a speed promise by the implementer. They are intended to be fast so they can run every time the Editor, game, or commandlet starts. They are also selected by default in the UI.

All Smoke tests are intended to complete within 1 second. Only mark Unit Tests or fast Feature Tests as Smoke Tests.



Content Stress

More thorough testing of a particular system to avoid crashes, such as loading all maps or loading and compiling all Blueprints. See EditorAutomationTests.cpp or EngineAutomationTests.cpp for examples of these.

Screenshot Comparison

This enables your QA testing to quickly compare screenshots to identify potential rendering issues between versions or builds.

Automation Tests moved to Plugins

For a long time, automation tests were spread across Unreal Engine and the Editor which meant that when you shipped your title, these were included. These have now been moved to their own plugins that can be individually enabled. This also means that since these tests are located in plugins, you can choose to include them with your packaged builds when you compile. Plugins also can store content so that it no longer has to be kept in the Engine Content folder.

Because of this change, the type of test being created will dictate where it should be stored. Use the table below to look at the test type and which plugin it should be stored with:

Test Type

Plugin to store it in

Unit

These can continue to be stored in the same module as the code.

Project Agnostic Runtime Tests

RuntimeTests Plugin

Project Agnostic Editor Tests

EditorTests Plugin

Functional Tests

EngineTest Game folder

Some tests are still in the Engine that has yet to be moved to a Plugin. These will be moved out over time to corresponding Plugins that can be found in the Plugins Browser listed under Testing.

Enabling Automation Test Plugins

To enable the plugins for the different tests available, go to the file menu and select Window > Plugins to open the Plugin Browser Window.



In the left panel, select the Testing category and enable the test plugins you want to use.





Click image for full size.



Once you have selected these, you will be prompted to restart the Editor. Click the Restart Now button.



Test Design Guidelines

When you are testing your games or projects, the following are some general guidelines that Epic follows for its automation testing:

Do not assume the state of the game or the Editor. Tests can be run out of order or parallel across machines.

Leave the state of the files on disk the way you found them. If a test generates a file, delete it when the test is done.

Assume the test was left in a bad state the last time it was run. A good habit would be to generate files to attempt to delete them before the test starts.

Running Automation Tests

Open any project.

Enable the Plugins available to use for testing and restart the Editor.

In the Editor, go to Window > Test Automation.





Click image for full size.



For this menu option to be visible, you must first enable at least one automation tests plugin.

In the Automation tab of the Sessions Frontend under the Test Name column, enable the following:





Click image for full size.



Editor

Project

System

In the Automation tab toolbar, click the Start Tests button.





Click image for full size.



As the tests complete, you can follow the progress in the Test Name window.





Click image for full size.



Essentials

The Automation System provides the ability to perform Unit Testing, Feature Testing, and Content Stress Testing using the power of the Unreal Message Bus to increase stability.

Automation Spec

What can it do?

How does it work?

How do I use it?

Using the API

Finding Elements

By::Id()

By::Path()

Path Syntax

By::Cursor()

By::Delegate()

Performing Actions

Elements

Sequences

Actions

Waiting

Putting It All Together

Final Notes

The Automation Driver is an Unreal Engine feature that enables programmers to simulate user input through the application using fluent syntax. The Automation Driver is very similar in feature set to other external libraries you might find for browser input simulation and is primarily used, like these other libraries, to write functional tests that simulate user behavior.



What can it do?

The Automation Driver simulates input, which means that it can simulate cursor movement, clicks, pressing, typing, scrolling, drag-and-drop, and more. In this initial revision of the Automation Driver, it supports the full suite of traditional desktop input, basically all keyboard and mouse-related inputs. In the future, we may expand this to include touch gestures, controller input, and even motion detection.

The Automation Driver specializes in simulating this input in a fluent, readable way that is easy to maintain and relatively non-brittle. And most importantly, because the Automation Driver simulates input at the platform layer, its public API is not dependent on Slate. With a little work, it can be extended to work with scene actors or beyond.

This feature is also platform agnostic, so it can be used on any platform as long as it can simulate the primary input types for that platform.

How does it work?

Within Core, there is a set of interfaces that nearly all external input goes through. The Automation Driver creates shim implementations of these interfaces, and via some basic dependency injection, it can swap out the real implementations with its "pass-through" variations. These "pass-through" variations then have the opportunity to delegate what platform input gets through to the application and what does not, as well as faking its own input entirely, which is how the Automation Driver does its work.

How do I use it?

By default, the Automation Driver is disabled. You can activate it by calling the Enable() function on the Module API. You can disable it by calling the Disable() function.

Once activated, the Automation Driver begins blocking nearly all platform input received by the application. At this point, you can now create your own driver instance.

Once you have your own driver instance, you can start simulating input. Here is a quick example of how you might simulate input for a sign-up form:

Using the API

There are two primary APIs for interacting with the Automation Driver - a synchronous and an asynchronous API. The synchronous API is the easiest to write code for, but you cannot run the code on the GameThread. This is because the synchronous API blocks and waits for the input simulation to complete before continuing. While the input simulation is still queued as latent logic to run on the GameThread, the blocking synchronous driver API ensures the simulated input never gets handled by creating a deadlock - avoid doing this.

All of the examples in this primer are going to use the synchronous API, assuming the logic is not being executed on the GameThread.

If you find this a challenging concept, you should read about the new Automation Spec test types.

Finding Elements

The first step to generating any useful input is going to be identifying key parts of the application to interact with. The Automation Driver does this via Locators, and there are a handful of fluent ways to use some of the existing locators that are capable of discovering Slate-based elements.

Locating elements based by Id is the most ideal method of doing so. It is significantly less likely to break as it requires that a programmer tag a widget with an explicit Automation Driver metadata Id.

Tagging a widget is trivial and can be done like the following:

It is best that Ids be as specific as possible so that they are unlikely to collide with any other Id, making them much easier to reference. Ids can be referenced by path, and thus scoped by other Ids and elements. But it is best to generate a unique Id so that the test does not have to rely on a brittle scope context.

For example, if your Id is guaranteed unique, then you can locate that widget like so:

And if your Id is not unique, but represents a unique set of elements, then you can locate all those elements at once using the following:

Invoking the GetElements() method on the element collection is what actually initiates element discovery, so be aware of that in case the elements you are looking for come and go. You may need to explicitly wait for them to appear.

Locating elements by path is the most brittle and powerful way to type of location currently available. The By::Path() locator enables you obtain specific elements via a hierarchy of tag, id and/or type matching.

Here are some examples of the syntax:

Syntax

Description

#SignUpFormFirstNameField

# represents that the following text is an explicit Id. In the case of an SWidget, it needs to be tagged with the Automation Driver Id metadata.

FormField

Plain text represents general tags, and in the case of a SWidget, it needs to have a Tag or TagMetadata with a matching plain text value.

<STextBlock>

<> represents types, and in the case of a SWidget, it should be the explicit type used in the SNew construction. You can easily create paths using types by looking at the Widget Reflector.

/

Hierarchy is represented by forward slashes, and a single forward slash represents that the next value must match a direct child of the element matched before it.

//

Hierarchy is represented by forward slashes, and a double forward slash represents that the next value must match any descendant of the element matched before it.

In the future, more syntax options will be added to the path locator, but these are the options that are currently available.

There is no support for escape characters, which means that the path locator cannot successfully match Tags or Ids that contain preceding < or # characters.

To check out additional syntax usage examples, read through: Engine/Source/Developer/AutomationDriver/Private/Specs/AutomationDriver.spec.cpp

This locator returns the element directly under the cursor's current position.

If none of these existing locators can do what you need them to do, you can pass your own delegate or lambda via By::Delegate() or its various overloads. The Automation Driver will then invoke that block of code on the game thread when attempting to locate the elements.

Performing Actions

There are two primary ways to perform actions with the Automation Driver. When working with a single element (or a small set of elements), the easiest way is to use the actions available directly on FDriverElementRef. The other option is to create a FDriverSequenceRef, which enables you to queue up a long series of actions that can be performed against many different elements (or no specific elements at all).

Several available actions can be performed directly from it after a driver element reference is obtained, for example:

In this example, after obtaining the reference to the #Submit element, we are directly invoking the default Click method. All actions directly available off a driver element reference only impact the element they are being invoked from. So with the above Click example, the Automation Driver will first attempt to move the cursor to the #Submit element. If the element does not exist in the Slate DOM, then the driver will wait for up to the implicitly configured timespan defined in the Automation Driver Configuration. If the element appears before timing out, then it will attempt to move the cursor over the element. If the element is off screen, the driver will attempt to locate a method of moving the element onto the screen, such as scrolling it into view. Once in view, the cursor is moved over the element, and only then is the full click simulated.

All driver element reference methods work in this fashion, so their actions attempt to only impact the element.

A driver sequence is a more robust way of issuing actions for the driver. With a sequence, you can perform actions ignorant of the elements it may be affecting, or you can perform actions against a specific set of elements. Additionally, sequences can be invoked multiple times, which makes them very reusable and great for helper libraries.

A sequence does not perform its actions until Perform() is called. Once an action has been added to the sequence, it cannot be removed. Additional actions cannot be added to a sequence while it is being performed, but more can be added once it finishes.

If any action fails, then the whole sequence fails and execution stops at that point in the series.

For full details on all the types of actions that can simulated, refer to the following files:

Engine/Source/Developer/AutomationDriver/Public/IDriverElement.h

Engine/Source/Developer/AutomationDriver/Public/IDriverSequence.h

The set of actions is currently limited to keyboard and mouse input, which generally includes:

Mouse Move

Mouse Wheel Scrolling

Click

Double Click

Press and Hold Button

Release Button

Type

Ctrl+Shift+S

Press and Hold Key

Release Key

Focus

This includes supplemental intelligent actions, such as scrolling until a specific element comes into view, getting the text, size or location displayed by an element, and more.

Although we are not actively developing this feature, we may add support for the following:

Scene/Actor interaction

Controller Input

Touch Input/Gesture

Motion Detection

When building user-simulating automation tests, it is common to wait for various events to happen, and the Automation Driver has built-in support to make the act of waiting easier.

All Automation Driver actions automatically wait the configured ImplicitWait timespan for any dependent scenarios to occur before timing out and failing an action. An example of this would be waiting for an element to exist and become visible before simulating a click event for it.

You can configure the ImplicitWait timespan dynamically and adjust it mid-simulation as needed via the configuration options on the Automation Driver. For example:

The current default ImplicitWait timespan is 3 seconds, and you can also perform explicit or conditional waits, for example:

You can also specify your own delegate or lambda conditional that must be successful before continuing with the simulation. Finally, every wait has a required timeout argument and an optional interval timespan, which defines how frequently the wait condition should be reevaluated.

Putting It All Together

Since the Automation Driver API cannot be executed on the GameThread, it can be a bit challenging to write simulations, but if you couple the Automation Driver with the new Spec test type, this becomes trivial.

Here is a snippet of one of the over one hundred and twenty tests to spec expectations (tests), which are used to ensure that the Automation Driver itself is functioning properly.

Read the Automation Spec test type documentation to better understand what is going on in the following snippet:

The main takeaway is that the lambda passed to BeforeEach() executes on the GameThread and is setting up the scenario for the test, creating the Widgets, and positioning the window accordingly. The It() lambda is where the actual input simulation is happening, and if you look closely, you can see that this one passes the EAsyncExecution::ThreadPool value to the It(). This causes the lambda to be executed on a thread separate from the GameThread, where it is safe to simulate input. Because of this, you can put a breakpoint in your Automation Driver code and step through the various actions as they are performed. Finally, AfterEach() cleans up the environment, and it is executed back on the GameThread.

Final Notes

Always be mindful when working with Automation Driver code that you aren't working on the GameThread and therefore, it is not safe to make copies of non-thread safe SharedPtrs. This is an important callout because Slate exclusively uses non-thread safe SharedPtrs.

If you must access something using a non-thread safe SharedPtr, you should make the dedicated BeforeEach() blocks for your test, which can enable you to bounce between threads while simulating and checking behavior.

If you know the SharedPtr will not be destroyed while executing the test, the other alternative is to cache it on the test class itself, so the SharedPtr can be accessed by the lambdas but not cloned, thus not causing race conditions with the reference counting. We do this with the SuiteViewModel in the above snippet.

It is generally best to perform all your Automation Driver simulation in a dedicated BeforeEach() block, and then do your expectation checking in the It() on the GameThread.

Automation Driver

How to Set up a Spec

How to Define Your Expectations

Describe

It

Defining a Basic Expectation

How a Spec Expectation Translates to a Test

Additional Features

BeforeEach and AfterEach

AsyncExecution

Latent Completion

Parameterized Tests

Redefine

Disabling Tests

Mature Examples

We have added a new type of automation test to our existing automation testing framework. This new type is known as a Spec. "Spec" is a term for a test that is built following the Behavior Driven Design (BDD) methodology. It is a very common methodology used in web development testing, which we adapted to our C++ framework.

There are several reasons to start writing Specs, including that they:

Are self-documenting

Are fluent and often DRYer

DRY (Don't Repeat Yourself)



Are much easier when writing threaded or latent test code

Isolate expectations (tests)

Can be used for nearly all flavors of tests (Functional, Integration, and Unit)

How to Set up a Spec

There are two methods for defining the header for your spec, and both are similar to the existing method we use to define test types.

The easiest method is to use the DEFINE_SPEC macro, which takes the exact same parameters as all the rest of the test define macros.

The only other alternative is to use the BEGIN_DEFINE_SPEC and END_DEFINE_SPEC macros. These macros allow you to define your own members as part of the test. As you will see in the next section, there is value to have things relative to the this pointer.

The only other callout is that you need to write the implementation for the Define() member of your Spec class, instead of the RunTests() member - as you would for any other test type.

Specs should be defined in a file with the .spec.cpp extension and not have the word "Test" in the name. For example, the FItemCatalogService class might have the files ItemCatalogService.h, ItemCatalogService.cpp, and ItemCatalogService.spec.cpp.

This is a suggested guideline and not a technical restriction.

How to Define Your Expectations

A big part of BDD is that instead of testing a specific implementation, you are testing expectations of a public API. This makes your test much less brittle and thus easier to maintain, and more likely to work if multiple different implementations of the same API ever crop up.

In a Spec, you define your expectations via the use of two different primary functions, Describe() and It().

Describe

Describe() is used as a way to scope complicated expectations, such that they are more readable and DRYer. Using Describe() makes your code DRYer based on the interaction it has with other supporting functions such as BeforeEach() and AfterEach(), which is covered below:

Describe() takes a string that describes the scope of the expectations within it, and a lambda that defines those expectations.

You can cascade Describe() by putting a Describe() in another Describe().

Keep in mind that Describe() is not a test and is not executed during an actual test run. They are only executed once when first defining the expectations (or tests) within the Spec.

It

It() is the bit of code that defines an actual expectation for the Spec. You can call It() from the root Define() method or from within any Describe() lambda. It() should be used ideally to just assert the expectation, but can also be used to do the final bits of setup for the scenario being tested.

Generally, it is a best practice to start an It() call description string with the word "should", which implies "it should".

Defining a Basic Expectation

Here is an example of putting it all together to define a very simple expectation:

As you can see, this causes the tests to be self-documenting, especially if the programmer takes the time to describe the expectation correctly without combining disparate expectations together. It is intended that combining all the Describe() and the It() calls should make a mostly readable sentence, for example:

The following is a more complicated example of what a mature Spec currently looks like in the Automation Test UI:



In this example, Driver, Element, and Click are each Describe() calls, with the various "should..." messages being defined by It() calls.

Each of these It() calls becomes an individual test to be executed, and thus can be executed in isolation if one fails while others do not. This makes maintaining tests easier because it is less troublesome to debug them. Also because the tests are self documenting and isolated, when one fails, the person reading the test report has a much more specific understanding as to what is not working - rather than just knowing that a very large bucket named Core failed. This means problems get routed to the right person quicker, and less time is spent investigating issues.

Finally, clicking on any of the above tests will take you directly to the It() statement that defined it.

How a Spec Expectation Translates to a Test

The following is a detailed explanation; however, understanding the underlying behavior of the Spec test type will make some of the following complex features easier to understand.

The Spec test type executes the root Define() function once, but not until it is needed. As this runs, it collects every non-Describe lambda. After the Define() finishes, it then goes back through all the lambdas or code blocks it collected, and generates an array of latent commands for each It().

Therefore, every BeforeEach(), It(), and AfterEach() lambda code block is put together in a chain of execution for a single test. When asked to run a specific test, the Spec test type will queue all the commands for that particular test for execution. When this happens, each block does not continue until the previous block has signaled it has finished executing.

Additional Features

The Spec test type offers several other features that make it easier to write complicated tests. In particular, it generally removes the need to directly use the Automation Test Framework's latent command system, which is both powerful and cumbersome.

Here are a list of features supported by the Spec test type that can help with more complicated scenarios:

BeforeEach and AfterEach

AsyncExecution

Latent Completion

Parameterized Tests

Redefine

Disabling Tests

BeforeEach() and AfterEach() are core functions to writing anything beyond the most trivial Spec. BeforeEach() enables you to run code before the subsequent It() code runs. The AfterEach() does the same thing, but will run the code after the It() code runs.

Remember that each "test" is only composed of a single It() call.

For example:

In our example, the code blocks are executed from top to bottom, due to the BeforeEach() being defined, then the It(), then the AfterEach(). While it is not a requirement, we suggest you maintain this logical ordering of the calls. But you could mix up the order of the above three calls and the result would always produce the same test.

Also in the above example, it is checking an expectation in AfterEach(), and this is very abnormal and a side-effect of testing the Spec test type itself. As such, we do not recommend using the AfterEach() for anything other than clean up.

You can also make multiple BeforeEach() and AfterEach() calls, and they will be called in the order that they are defined. As with the first BeforeEach() call being executed before the second BeforeEach() call, fterEach() behaves much the same way — with the first call executing before the subsequent call.

Additionally, BeforeEach() and AfterEach() are affected by the Describe() scope they are called in. Both will only execute for It() calls that are within the scope in which they are also called.

Here is a complicated example, with improperly ordered calls, which all work out correctly.

The Spec test type also enables you to easily define how a single code block should be executed. This is done by simply passing the appropriate EAsyncExecution type into the overloaded version of BeforeEach(), It(), and/or AfterEach().

For example:

Each of the above code blocks will execute differently but in a guaranteed sequential order. The BeforeEach() block will run as a task in the TaskGraph, the It() will run on an open thread in the thread pool, and the AfterEach() will spin up its own dedicated thread just to run a block of code.

These options are extremely handy when having to simulate scenarios that are thread sensitive, such as with the Automation Driver.

The AsyncExecution feature can be combined with the Latent Completion feature.

Sometimes, you need to write a test needing to perform an action that takes multiple frames, such as when performing a query. In these scenarios, you can use the overloaded LatentBeforeEach(), LatentIt(), and LatentAfterEach() members. Each of these members are identical to the non-latent variations, except their lambdas take a simple delegate called Done.

When using the latent variations, the Spec test type will not continue execution to the next code block in the test sequence until the actively running latent code block invokes the Done delegate.

As you can see in the example, you can pass the Done delegate as a payload to other callbacks to make it accessible to the latent code. So when the above test is executed, it will not continue to execute any AfterEach() code blocks for the It() until the Done delegate is executed, even though the It() code block has finished execution already.

The Latent Completion feature can be combined with the AsyncExecution feature.

Sometimes, you need to create tests in a data-driven way. And at times, this means reading inputs from a file and generating tests from those inputs. Other times, it may simply be ideal to reduce code duplication. Either way, the Spec test type allows for parameterized tests in a very natural way.

As you can see in the above example, all you need to do to create parameterized tests is to dynamically call the other Spec functions passing the parameterized data as part of the lambda payload while generating a unique description.

In some cases, using parameterized tests could just create test bloat. It may be reasonable to simply execute all the scenarios from the input as part of a single test. You should consider the number of inputs and the resulting tests that are produced. The major benefit to creating your data-driven tests in a parameterized way is that each test gets to run in isolation, making reproduction easy.

When working with parameterized tests, it can sometimes be convenient at runtime to make a change to an external file driving the inputs and have the tests automatically refresh. Redefine() is a member of the Spec test type, which, when called, re-performs the Define() process. This causes all the code blocks for the tests to be re-gathered and collated.

The most convenient method to do the above would be to create a bit of code that listens for the input file changes and calls Redefine() on the test as needed.

Every Describe(), BeforeEach(), It(), and AfterEach() member of the Spec test type has a variation with a preceding 'x'. For example, xDescribe(), xBeforeEach(), xIt(), and xAfterEach(). These variations are a simpler way of disabling a code block or Describe(). If xDescribe() is used, then all code within xDescribe() is also disabled.

This can be easier than commenting out expectations that need iteration.

Mature Examples

You can find mature examples of the Spec test type in Engine/Source/Developer/AutomationDriver/Private/Specs/AutomationDriver.spec.cpp. This spec currently includes over one hundred and twenty expectations and makes use of most of the advanced features at some point.

Our Launcher team also has multiple mature uses of the Spec framework, and one of the most mature uses are the Specs written around BuildPatchServices.

Prerequisites

Steps

Install the HTTP Server

Run the HTTP Server

Viewing Test Results

Setting Up Seperate Test Sessions

Result

The Automation System provides a way to run tests of various systems in Unreal Engine, but it has some limitations for providing visibility of data that can hamper its use for distributed testing. The Automation System can generate an HTML report instead of a log file, but over time these reports have become more complex, and if the HTML report is not self-contained locally, you cannot open it directly on a modern web browser.

As a solution to this limitation, you can use an Automation Test Report Server to output test results to a shared drive. You can then connect to the server to read the report.

Because there is no back-end to the Automation Test Report Server aside from serving files, it is a very basic, non-demanding web server that you can easily set up on most hardware. This means external third parties running tests remotely can set up a server on their own to share test results.

Prerequisites

To set up an Automation Test Report Server, you must have the following prerequisite libraries and programs:

Node.js

Bower

Git

If you do not have these prerequisites installed, you will encounter errors.

You can perform this setup process on a local host, but because you cannot share a local host, you will need to set it up with a valid DNS and IP address for the server to be accessible remotely.

Setting up a web domain and address is beyond the scope of this documentation. Use whatever solution is most appropriate to meet your requirements.

Steps

To set up your Automation Test Report Server, follow the procedure below.

In the instructions below, replace the placeholder sections as follows:

(path to result): The path where the test results output will be stored. For example, C:\http_server\local.

(stream root) : The path where the source control stream or the UE installation is located. For example, C:\Epic\UE.

Install the HTTP Server

Make sure you have installed all the needed prerequisites.

Open a command prompt window.

Make sure %USERPROFILE%\AppData\Roaming\npm is in your command prompt path.

Run the following command:

This will install the Bower web server globally.

Run the following command:

This will recursively copy over the images, config files, and templates for the HTTP server that will be referenced by the generated test reports.

Run the following command:

This will tell Bower to install the javascript libraries that are referenced in the copied config files.

Run the HTTP Server

Run the following command:

This changes to the working directory for the HTTP server, and starts it running.

Leave the command prompt open. Closing the command prompt will shut down the server.

Viewing Test Results

When you run your Automation tests, use the following command to specify the (path to result) directory for the output. This sets up your tests to output directly to the folder where you set up the web server and its resources.

Open the IP address of your web server in a browser. You can use http://localhost:8080/ internally, but you will need to set up a proper web address for distributed work, as noted previously.

If the output path is the same as the server path, you can use it directly. However, if you are using a subdirectory to store your files, you will need to add it to the path.

For example, if you output to something like: C:\http_server\local\mypath, then the url should be: http://localhost:8080/mypath.

The web server will provide a list of files. Any reports output to the correct directory will be visible immediately.

If you provide a session name and move Index.html and index.json (normally found in the target directory) along with the directory, you can access the results of a specific test session by name.

When you finish reviewing results, you can close the command prompt and shut down the server.

Setting Up Seperate Test Sessions

To better organize your test results and prevent overwriting, you can separate different test sessions into different directories.

Define a directory name of your choosing to make identifying particular tests easier. For this example, we will use Session1.

Output the result of your Automation tests to (path to result)\Session1.

When you run a different set of tests, change the name. You can either increment the session number, or use a completely different descriptive name, for every new set of tests. This will avoid overwriting previous results.

To access your results through the web browser, append the directory name for the appropriate test session to the path.

Result

If everything functions correctly, you will see something resembling the image below, showing a list of tests executed and their respective statuses.



Automation System Overview

Screenshot Comparison Tool

Automation System User Guide

Enabling the Plugin

Building a Test Plan

Actions

Expected Results

Import Options

Test Plan Creation Workflow

As a part of the Automation System, the FBX Test Builder is a plugin that enables you to create your own tests for individual FBX files. The FBX Test Builder creates a Test Plan for a single FBX file that can be used to import or reimport and check against an array of expected results. The Test Plans that are created are stored in a JSON file which shares the same name as the FBX file that is being tested except without its extension.



The FBX Test Builder enables you to create your Test Plans that allow you to perform a selected operation on the FBX file and then check against an array of expected results to whether it passes or fails the completed tests.

Enabling the Plugin

Before you can start building your FBX automation tests, you will first need to enable the FBXAutomationTestBuilder plugin by going to Edit > Plugins > Testing.





Click for full size.



After enabling the plugin, you will need to restart Unreal Engine before you can access it.





Click for full size.



The FBX Test Builder can be accessed by using the file menu to select Window > Automation Tools > FBX Test Builder.





Click for full size.



Building a Test Plan

When you use the FBX Test Builder, it operates by using a selected Action (or operation) that will be performed and a series of Expected Results that determine whether the test that is performed passes or fails for the given FBX file. This set of actions and results is called a Test Plan.

Actions

For each Test Plan, there are five key Actions that can be performed and each Action has its criteria for it to be used to perform a test correctly. These Actions and their criteria are outlined below:



Action

Steps

Import

Import the FBX file

Verify the expected result

Reimport

This must be run after an Import Test Plan where the imported assets were not deleted

Reimport the FBX file

Verify the expected result

Add LOD (Level of Detail)

This must be run after an Import Test Plan where the imported assets were not deleted

The FBX file name must be terminated by _lod00

There must be an FBX file with the same name that is terminated by _lod0X (where X is greater than 0)

Add a LOD

Verify the expected result

Reimport LOD (Level of Detail)

Reimport the previously imported LODs with the Import or Add LOD Action.

Import Reload

Import the FBX file

Save the packages

Unload the created UObject from memory

Reload the saved packages

Verify the expected result

Expected Results

For each Test Plan, a list of Expected Results will be evaluated to determine if the test passes or fails.



Settings

Description

Expected Presets Type

The predefined data that should be checked.

Check Type

Description

Required Data Types

Error Number

Data should contain the number of error [int0].

Integer

Warning Number

Data should contain the number of warning [int0].

Integer

Created Static Mesh Number

Data should contain the number of Static Mesh created [int0].

Integer

Created Skeletal Mesh Number

Data should contain the number of Skeletal Mesh created [int0].

Integer

Materials Created Number

Data should contain the number of Material created [int0] under the target Content folder.

Integer

Material Slot Imported Name

Data should be the slot index [int0] and the expected original imported Material Slot Name [string0].

Integer and String

Vertex Number

Data should be the total number of vertices for all LODs [int0].

Integer

LOD Number

Data should be the expected number of LODs [int0.]

Integer

Vertex Number LOD

Data should be the LOD index [int0] and total number of vertices for LOD [int1].

Two Integers

Mesh Materials Number

Data should contain the number of Materials indexed by the mesh [int0].

Integer

Mesh LOD Section Number

Data should be the LOD index [int0] and the expected number of sections for a mesh [int1].

Two Integers

Mesh LOD Section Vertex Number

Data should be the LOD index [int0], section index [int1], and the expected number of vertices [int2].

Three Integers

Mesh LOD Section Triangle Number

Data should be the LOD index [int0], section index [int1], and the expected number of triangles [int2].

Three Integers

Mesh LOD Section Material Name

Data should be the LOD index [int0], section index [int1], and the expected name of the Material [string0].

Integer and String

Mesh LOD Section Material Index

Data should be the LOD index [int0], section index [int1], and the expected Material index of the Mesh's Materials [int2].

Three Integers

Mesh LOD Section Material Imported Name

Data should be the LOD index [int0], section index [int1], and the expected original imported Material Slot Name [string0].

Two Integers and a String

LOD UV Channel Number

Data should be the LOD index [int0] and the number of UV channels [int1] for the specified LOD.

Two Integers

Bone Number

Data should contain the number of bones created [int0].

Integer

Bone Position

Data should contain the bone index [int0] and the position XYZ [float0, float1, and float2]. Optionally, you can pass a tolerance value [float3].

Integer and four Floats

Animation Frame Number

Data should contain the number of frames [int0].

Integer

Animation Length

Data should contain the animation length [float0].

Float



Expected Presets Data Integer

Enter the expected integer value that should be checked for the specified FBX file.

Expected Presets Data Float

Enter the expected float value that should be checked for the specified FBX file.

Expected Presets Data Double

Enter the expected double value that should be checked for the specified FBX file.

Expected Presets Data String

Enter the expected string value that should be checked for the specified FBX file.

For setting up the Expected Result, an example FBX with a box mesh that contains six different materials and textures will be used as the test case.



Click the Add (+) button to add an Expected Result and then choose a Expected Preset Type that you'd like to use to check.



Choose a Expected Presets Data type that corresponds to the Expected Presets Type you want to test. In this example, Mesh Materials Number type is selected to check the included FBX contains six materials when imported.



The Mesh Materials Number preset type only expects an integer (use the tooltip for the preset or the table above reference what data is required) that checks the number of Materials being imported. Click the Expected Presets Data Integer once to add an expected result check to the array.



For array element 0, enter the number of Materials that should be imported with the FBX. In the case of this example, six Materials are expected.



Make sure to setup the necessary Import Options so that everything that is required by the Expected Preset Type you selected is imported correctly. For example, the Box FBX will need to import the materials and textures from the FBX so the options for Import Materials and Import Textures should be enabled.



Click the Save JSON button and the Test Plan will be added to the Session Frontend Automation tab where you can find it under Engine/Import/FBX/[NameOfTheFBX].





FBX Test Editor

Session Frontend Automation Tab

After running the test, the operation system will test if the Mesh Materials Number (6) of the specified LOD(0) match with the imported Asset.





Click image for full view.



If the test should fail, select the failed test in the Automation tab to see the reason why under the Automation Test Results panel.





Click image for full view.



The Message Log will also pop up to indicate whether the test was successful or failed and why it failed regardless of having the Session Frontend window open.

Import Options

After having set up the Expected Results Test Plan, you must also make sure that the actions you want to test are set to import/reimport correctly. For example, if you are testing an FBX that imports a set number of Materials, you would want to make sure that Import Materials is enabled. These options are the same ones that are available when importing your own assets into the Editor via the Content Browser.



For more information, see the FBX Import Options page.

Test Plan Creation Workflow

Follow the steps below to create your Test Plans for FBX testing:

Copy the FBX you want to test to the following location:

Any FBX placed in this folder location will automatically populate the Select an FBX file drop-down list.



Use the Select a Test Plane drop-down and choose Create new plan or select one that already exists to edit it.



Fill in the following sections:

General:



Test Plan Name - Give a name to this test plan that you can use to select from the test plan list.

Action - Select the type of operation that will be executed on the FBX file, such as import, reimport, add LOD, reimport LOD, or import reload.

LOD Index - If using reimport LOD, enter the LOD index you want to reimport here.

Delete Folder Assets - Whether to delete the imported asset at the end of the Test Plan.

Expected Results:



Set an Expected Presets Type and fill in the necessary data types that are required to complete the test.

Import Options:



Set the necessary Import Options required to successfully import this particular FBX for testing.

Click Save JSON button for your test plan to be saved and added to the available tests that will be run for this FBX file during automation testing.



Creating a Test

Functional Test Class Features

Testing Via Level Script

Testing Via Child Class Method

Creating And Using Expected Test Results

Creating a Test

Setting up a test is done by placing a Functional Test Actor in a Level. That Actor can then be scripted to run a set of tests by the Level Script in the Level Blueprint. The test itself can be built into the Functional Test itself (as a child code class or Blueprint), or assembled directly in the Level Script.



A Level Blueprint running a placeholder Functional Test.



Functional Test Class Features

The Functional Test class provides the following important functions:

Function Name

Description

PrepareTest

The PrepareTest function can be overridden in a code or Blueprint child class. This function is the first to run, along with the OnTestPrepare delegate, and can be overridden to perform the initial setup required for your test. If this setup requires multiple frames, for example, if the setup requires streaming data to be loaded into the Level, building pathing data, or connecting to a server, this function should start those processes.

IsReady

This function is called on every tick after the initial PrepareTest call, and will continue to be called until OnTestStart is run. By default, this function returns true, which permits OnTestStarted to be called immediately. If the initialization processes set in motion by PrepareTest are incomplete, this function should return false to prevent the main test code from starting prematurely.

OnTestStart

This delegate is called when the Functional Testing Manager begins the test. Bind this to your test functionality, and be sure to call FinishTest at the end.

OnTestFinished

Once the test ends, this delegate will be called. Because testing often affects the Level or Actors within the Level in a way that impacts subsequent tests, using this opportunity to clean up can be vitally important to maintaining a usable testing environment.

The Functional Test class also provides the following support features:

Function or Property Name

Description

OnAdditionalTestFinishedMessageRequest

Implementing OnAdditionalTestFinishedMessageRequest is useful as a way to log additional information into the test summary.

RegisterAutoDestroyActor

Actors passed to this function will be destroyed automatically when the test ends. This is a good way to clean up Actors that were spawned as part of a test.

LogMessage

This function logs the text you provide to the LogFunctionalTest category in the Output Log. It is intended as a way to log progress while a test is running.

Observation Point

If an Actor is assigned to this Property, the Player will be teleported to its location and rotation when the test starts.

Enabled

This variable can be set to false to disable the test.

Testing Via Level Script

To run a Functional Test in the Level Script, first place a Functional Test Actor in the Level. With the Functional Test selected, open the Level Script and place the OnTestStart delegate and a reference to your Functional Test. By dragging off of the Functional Test's pin, you can create one or more FinishTest nodes. At this point, you can build your test so that it connects the OnTestStart delegate to the FinishTest node (or nodes, if your test contains branches). You may also create the OnTestFinished function if your test has done anything that requires cleanup. When this setup is complete, the Automation System will be able to run this test properly. This method is acceptable for simple tests, generally those that require little to no setup, and don't need to be run multiple times or on more than one Level.

Adding events or references to an Actor (such as your Functional Test Actor) within the Level Script requires that the Actor in question is selected in the Level Editor or World Outliner.

Testing Via Child Class Method

If a Functional Test requires a more complex setup, or is intended to run multiple times (either in a single Level, or on multiple Levels), overriding AFunctionalTest is the recommended method. Extending the base Functional Test class in code or with Blueprints grants the ability to use PrepareTest and IsReady functions, which are important for running more complex or inter-dependent tests, or tests with setup times longer than one frame. Implementation of these tests via the Level Script is the same as before, although the bulk of the test code can now be contained in the new Functional Test class itself, rather than the Level Script, making the test easy to use in multiple Levels, or multiple times within the same Level.

Creating And Using Expected Test Results

Some tests have results that are large, complex, precise, or otherwise unsuited to manually-written solutions. In cases like this, it is usually helpful to run a single test, personally verify that the results are correct, and then save those results for comparison against the results of future tests. This concept is implemented as Ground Truth Data in the Functional Testing Editor plugin.



Using Ground Truth Data requires enabling the Functional Test Editor plugin.



The concept of Ground Truth Data, implemented in the UGroundTruthData class, is used to store and compare these results. A Ground Truth Data Object stores an Object of your choosing as the "correct" result of whatever test you are performing. This Object can then be compared in any way you like to a corresponding Object in your live simulation, and your logic can then determine if this constitutes passing or failing the test. For example, if your game requires precise, dependable physics simulation, such as a golf game, you might have a test where a simulated player hits a hole-in-one. Your Ground Truth Data could contain the golf ball as the Object, and you could compare the location of your live simulation's golf ball to the saved one (which, presumably, has landed in the hole), allowing for only a very small error without failing the test. A test like this could be designed as follows:

Spawn a "test" golf ball at a certain location and initial velocity. Give it a fixed amount of time to travel. At this point, your golf ball should be in the ideal position. You can now attempt to load the "correct" golf ball from the Ground Truth Data for this test.

If the Ground Truth Data does not return an acceptable Object (the returned Object is null or the wrong class, for example), then save the test golf ball we created to the Ground Truth Data as the expected result. If it turns out that the golf ball didn't land where it should have, the Ground Truth Data can always be reset by manually setting its ResetGroundTruth variable to false in the Blueprint Editor.

After checking the ResetGroundTruth box in the Blueprint Editor, it will automatically uncheck itself, but your data will be reset.

If the Ground Truth Data does return an Object which can be cast to the desired class (in this example, Actor is sufficient), a comparison between that Object and the test golf ball can be made to evaluate whether or not the test should pass.



This test checks for consistent location of a "test golf ball" that has been given four seconds of travel time.

Tests set up in this manner can run the test and set the expected test result with the same script. The expected result can be reset by editing the Ground Truth Data in the Editor.

Unreal Frontend

Screenshot Capture Methods

Screenshot Browser

Screenshot Comparison View

Screenshot Workflow

The Screenshot Comparison browser enables you or your quality assurance (QA) teams to quickly compare screenshots that are captured in the Unreal Engine Editor. The screenshots generated via an automation test can be viewed using the Unreal Session Frontend tool where a history of screenshots is maintained enabling obvious rendering errors to be identified between builds.



Populated screenshot tests from Epic's own automation testing project.



Screenshot Capture Methods

There are a couple of ways you can construct a screenshot test; the easiest way is to start using the Screenshot Functional Actor or to take a screenshot during an existing Functional Test.

The Functional Screenshot Test Actor uses a camera to capture the screenshot and because of this shares a lot of settings with the existing Post Process and Camera settings that are available. The settings listed below, are specific to the Functional Screenshot Test that are used to capture the screenshots you want.



Setting

Description

Resolution

The desired resolution of the screenshot. If none is provided, the default resolution of the platform setup in the Automation Settings will be used.

Delay

The delay before the screenshot will be taken.

Disable Noisy Rendering Features

Disables Anti-aliasing, Motion Blur, Screen Space Reflections, Eye Adaptation (Auto-Exposure), and Contact Shadows because these features contribute a lot of noise in the final rendered image if you're explicitly looking for changes.

Visualize Buffer

Allows you to screenshot a buffer other than the default final lit scene image. This is useful if you're trying to build a test for a specific GBuffer that may be harder to tell if errors are introduced.

Tolerance

These are quick defaults for tolerance. By default, Low is used because there's some constant variability in every pixel's color introduced by Temporal Anti-Aliasing.

Zero

Low

Medium

High

Custom



Tolerance Amount

For each channel and brightness levels, you can control a region where the colors are found to be essentially the same. Generally, this is necessary as modern rendering techniques tend to introduce noise constantly to hide aliasing.

RGBA Channels

Set values for any of the RGBA channels separately.

Min Brightness

The minimum tolerance brightness value to accept.

Max Brightness

The maximum tolerance brightness value to accept.



Maximum Local Error

After you've accounted for color tolerance changes, you now need to control for local acceptable error. Depending on how pixels were colored on triangle edges, there may be a few percent of the pixels that fall outside of the tolerance levels. Unlike the Maximum Global Error, the Maximum Local Error works by focusing on a smaller subset of the image. These chunks will be compared to the local error in an attempt to local to locate hot spots of change that are important that otherwise would be ignored by the global error.

Maximum Global Error

After you've accounted for color tolerance changes, you now need to control for the total acceptable error. Depending on how pixels were colored on triangle edges, there may be a few percent of the pixels that fall outside of the tolerance levels.

Ignore Anti-Aliasing

If this is enabled, neighboring pixels will be searched for the expected pixel as what to what may have happened, such as the pixel shifting a little bit.

Ignore Colors

If this is enabled, the luminance of the scene is all that will be compared for the screenshot test.

In the Editor Preferences, the default resolution of all captured screenshots for comparison can be set for all placed Functional Screenshot Test Actors. This can be set by going to Edit > Editor Preferences > Automation > Screenshots.





Click image for full size.



The screenshot resolution set on individual Functional Screenshot Test Actors will override this value.

Functional Screenshot Test Actor

The Functional Screenshot Test Actor is a component that can be placed in your level and used to capture a screenshot as part of the automation tests that are run from Unreal Frontend. There are two varieties of screenshot tests that you can run; a normal screenshot that captures the scene view or one that is used to capture your games user interface (UI).

To access these Functional Screenshot Actors, use the Place Actors panel to drag one in your scene. You can find the Functional Screenshot Test and Functional UIScreenshot Test located in the All Classes tab.







Functional Screenshot Test

Functional UI Screenshot Test

Taking a Screenshot as part of another Functional Test

In addition to taking a standalone screenshot, you can also take a screenshot during a Functional Test enabling you to utilize screenshot comparisons during other scripted actions.



Blueprint example used to capture a screenshot during another Functional Test.



One thing to keep in mind is that you can customize the screenshot settings that are applied when capturing the screenshot. There are two useful Blueprint nodes you can should consider setting to default tolerances when capturing gameplay or rendering functionality for comparison.



The Default Screenshot Options node for gameplay and rendering are useful to set the default Tolerance level for the Screenshot Test Actor. When capturing gameplay differences, the Gameplay node can be useful to disable noise in the shot and buffers that aren't necessarily needed. If you're explicitly testing rendering functionality, the Rendering node should be used instead, otherwise, the default settings of the Functional Screenshot Test Actor will be used for each instance placed in the level.

Screenshot Browser

The Screenshot Comparison browser is where all your screenshot comparisons will populate, and as you introduce new ones or if a screenshot comparison fails, this view is where you will take care of it. From this browser, you can review the failures and make the correct decision, which might be to update the screenshot if a feature change has necessitated the updated screenshot or enter a bug report for your game if you suspect there is an issue.

To access the Screenshot Comparison browser, you'll first need to open Unreal (Session) Frontend. You can do this from inside the Editor by selecting Window > Developer Tools > Session Frontend.



The Screenshot Comparison Browser from Epic's internal test project for Automation Testing.

When screenshots are captured they will be saved to the project's folder in the Saved > Automation > Comparisons folder. You can use the text box to enter your save location if necessary.



When several tests have been run, you'll have your own populated images for comparison. This will give you access to several options for what to do with these images when connected to Source Control. If you're not connected to any form of source control, these dialog options will be disabled.





Add New

Replace/Add As Alternative

Action

Description

Add

Adds the screenshot to the ground truth folder and adds it to a pending change list in your Source Control.

Replace

Deletes all examples of ground truth data and replaces them with the newest screenshot as the new ground truth data.

Add As Alternative

Occasionally, two images can both be correct. Perhaps due to small differences in hardware or driver or maybe even extensions the hardware supports. Because we only bucket screenshots based on Platform_RHI_ShaderModel, it's possible further refinement is needed. That's where Add As Alternative comes into play. It adds another ground truth version of the image, and when comparing images, the system will always pick the ground truth screenshot matching closest based on the metadata. This option will be grayed out if the screenshot is from an identical device.

Always use Delete All Reports before running a fresh set of tests. Because the tool accumulates individual reports over time, there's no good place for the tool to automatically clean up reports from a previous run in the applications. This ensures that you start with a clean slate before running the next tests.

Ground Truth Screenshot

The Ground Truth version of your screenshot is the version that you know is correct. For screenshot comparison, the ground truth screenshot will be used as the comparison for any later screenshots that are taken. Should the latest screenshot not match it will cause a testing failure.

The first time you run a screenshot automation test, a warning in the Message Log and the Screenshot Browser will indicate that you need to add the newly taken screenshot as your Ground Truth image.





Message Log Warning

Screenshot Browser Warning

In the Screenshot Browser tab, click the Add New button to create a change list to submit your Ground Truth image.



If your Add New button is grayed out, make sure you're connected to your source control to enable it.

Screenshot Comparison View

From the Screenshot Comparison browser, if you click on any of the images, a window will open that enables you to blend between the ground truth and the incoming image. This makes it easier to see all the differences in context with one another.



The three images here (from left to right) are as follows:

Ground Truth is the image that you know to be correct.

Difference is the difference between the two images used for the comparison slider.

Incoming is the latest captured screenshot after an automation test has been run.





Click image for full size.



Click on any of the three images to open the comparison slider window. This screen enables you to drag the slider between the Ground Truth and the Incoming captured screenshot for comparison.





In this example, there is a noticeable difference between the set Ground Truth image that is known to be correct and the latest run automation test that capturing the Incoming screenshot.

Screenshot Workflow

You will start by picking a method that you would like to use to take the screenshot:

Screenshot Functional Test Actor

Taking a screenshot as part of another Functional Test

When you run the test locally, or on a build farm, you will receive a warning letting you know that you need to approve the first screenshot.





Click image for full size.



In the Screenshot Browser, you add it as the Ground Truth image by clicking Add New.





Click image for full size.



For other platforms, the build farm can take care of the initial screenshot and you can remotely approve the screenshots taken on those platforms by providing the network path in the Screenshot Browser, which appears at the top of the automation report.

The next time you run a Screenshot Comparison test, the screenshots should pass or fail. Use the Screenshot Browser to select a screenshot test and compare the differences.





Click image for full size.



For ones that fail, they will automatically show up in the Screenshot Browser tab for comparison so that you can choose to Replace or Add as alternative to the Ground Truth image.





Click image for full size.



If you are using Source Control, the Screenshot Browser will add them to a pending change list so that you the images can be checked in after the tests complete.

Automation Testing

Creating a New Automation Test

Simple Tests

Complex Tests

Latent Commands

Automation Testing

Automation Testing is the lowest level of automated testing, and is best suited for low-level tests of the core functionality of Unreal Engine. This system exists outside of the UObject ecosystem, so it is not visible to Blueprints or the Engine's Reflection System. These tests are built in code and can be run from the Console Command Line, either in the Editor or with Command-Line Parameters from your operating system. Automation Tests can be broken into two types: Simple and Complex. Both types are implemented as derived classes based on FAutomationTestBase.

Creating a New Automation Test

Automation Tests are declared by macros, and implemented by overriding virtual functions from the FAutomationTestBase class. Simple Tests are declared using the IMPLEMENT_SIMPLE_AUTOMATION_TEST macro, while Complex Tests require the IMPLEMENT_COMPLEX_AUTOMATION_TEST macro. Both macros feature the same three parameters, in the following order:

Parameter

Description

TClass

The desired class name of the test. The macro will create a class of this name, e.g. FPlaceholderTest, in which your test can be implemented.

PrettyName

A string specifying the hierarchical test name that will appear in the UI. For example, "TestGroup.TestSubgroup.Placeholder Test" in our minimal example (below).

TFlags

A combination of EAutomationTestFlags values, used for specifying Automation Test requirements and behaviors. See the EAutomationTestFlags API Page for details.

Once the new Automation Test class has been declared by one of the two macros, its functionality can be implemented. The following functions must be written:

Function

Parameter

Description

RunTest

This function performs the actual test, returning true to indicate that the test passed, or false to indicate that it failed.

Parameters

This parameter can be parsed or passed through to other functions as appropriate for the specific Functional Test.





GetTests

This function must be overridden for Complex Tests only; Simple Tests have an auto-generated version of this function built into their declaration macro.

OutBeautifiedNames

This array of strings must be populated with the UI-visible PrettyName of each individual Test.

OutTestCommands

This array of strings is expected to be parallel to OutBeautifiedNames and must be populated with the Parameters to be passed into RunTest.

The current convention is to put all Automation Tests into the Private\Tests directory within the relevant module. When an Automation Test matches one-to-one with a particular class, please name the test file [ClassFilename]Test.cpp, e.g. a test that applies only to FText would be written in TextTest.cpp.

The smallest and simplest test possible would be a Simple Test that automatically succeeds (or fails). Building a test like this can be useful as a first step to ensuring that your testing setup is correct before building more meaningful tests.

Simple Tests

Simple Tests are used to describe single atomic tests, and are useful as unit or feature tests. For example, simple tests can be used to test if the current map loads in Play In Editor or whether text wrapping is working properly in Slate. The following example tests the functionality of the SetRes command:

Complex Tests

Complex Tests are used to run the same code on a number of inputs. These are generally content stress tests. For instance, loading all maps or compiling all Blueprints would be good fits for complex automation tests. Note that both the RunTest and GetTests functions must be overridden. The following example tests the loading all of a project's maps:

Parameters

Latent Commands

Latent Commands can be queued up during RunTest, causing sections of the code to run across multiple frames. To create a Latent Action, it must be defined via the DEFINE_LATENT_AUTOMATION_COMMAND macro. This macro takes one parameter, known as CommandName, which defines the class name that will be created for this type of Latent Command. To finish creating the Latent Command, the new class will require a function body for its Update function. Here is an example of a simple Latent Command which runs until the Unit Test Manager is finished running tests:

If the Latent Command you wish to create requires an argument, such as a parameter string, the DEFINE_LATENT_AUTOMATION_COMMAND macro can be used. This macro takes two additional parameters, known as ParamType and ParamName, which define the type and name of the parameter to be passed in. In this example, a Latent Command is used to start connecting to a source control provider and then wait until the connection attempt finishes:

When the Update function returns true, the Latent Command is considered complete. A return value of false indicates that the Automation Test should stop executing immediately and try again next frame. To use a Latent Command in your test code, invoke the ADD_LATENT_AUTOMATION_COMMAND with the constructor of the Latent Command you wish to run. If the Latent Command was established with a parameter, pass in the value that the parameter should take as a constructor argument. In your RunTest function, the following code will wait for all Unit Tests to finish, then attempt to connect to a previously-named source control provider:



Activities related to loading or streaming data, or anything else that isn't guaranteed to run in a single frame, are candidates for Latent Command usage. For example, in the Editor, loading a map happens immediately, but in game, loading a map happens on the next frame, so Latent Commands must be used to ensure consistent behavior when an Automation Test needs to load a map.



Enabling Plugins

User Interface

Session Browser

Toolbar

Tests Window and Results

Export

Copy



Session Frontend with the Automation tab in focus.

The Automation tab is part of the Unreal (Session) Frontend of Unreal Engine. It is located here because it enables you to run automation tests on any other devices that are connected to your machine or are on your local network.

There are two ways you can access the frontend suite:

Session Frontend - Opens the local Editor as an automation worker to run automation on external devices.

Navigate to Tools > Session Frontend

Unreal Frontend - Opens a standalone version of the Frontend that includes the Session Frontend, Device Manager, and Project Launcher.

Navigate to your [Unreal Engine Root Directory] > Engine > Binaries > Win64 > UnrealFrontend.exe

Enabling Plugins

In the latest versions of Unreal Engine, all the Automation Tests have been moved from the Engine Content folder to their plugins that must be enabled before they will be visible in the Automation tab.





To enable the plugins, select Edit > Plugins > Testing.

Plugins Browser with Automation Tests

If you are using the standalone Unreal Frontend, all the automation tests will be available without any additional steps to enable it.

User Interface

When you open the Session Frontend, you will have access to a few tabs, such as the Console, Automation, Screenshot Comparison, and Profiler. For all your automation testing needs, the Automation tab will house all of the functionality you need with some additional functionality falling under the Screenshot Comparison tab for rendering functionality comparison.



Click image for full view.

If you do not see anything listed in the Automation tab window, select an active session from the Session Browse on the left. For example, under This Application the machine named PC-xxx is selected.

Session Browser

The Sessions Browser enables you to connect to specific instances of the Editor. You will only see the Automation window populate with the available automation tests once a session has been selected.



Toolbar

The toolbar in the Automation tab enables you to control how you start, refresh, and filter errors and warnings for your automation tests.



Click image for full view.

Icon

Title

Description



Start Tests

Starts and stops the currently selected automation test(s) that are enabled. The number of tests that will be run is also listed under the button for reference.



Run Level Test

If the currently loaded level is a test map, you can click this button to select the tests and run it immediately.



Refresh Tests

This will refresh the Test Name list for any test that is added to the project.



Find Workers

This will find local workers that can be used to perform the tests.



Errors

Toggles a filter for the Test window that displays any tests that ran into an error while attempting to complete.



Warnings

Toggles a filter for the Test window that displays any tests that ran into a warning while attempting to complete.



Dev Content

When enabled, developer directories will be included for automation tests.



Device Groups

Enables you to group the tests based on a series of options, such as the machine name, platform, operating system version, and much more.



Excluded Tests

Toggle Excluded Tests only.



Preset

Enables you to add your own presets for automation tests with the selected tests and settings so that you can use them again at a later date.

Tests Window and Results

In the Automation Tests Window and the Automation Test Results panel, you'll find information relevant to the tests that have been run, such as the Machine that it was completed, number of tests that were run, the number of fails, and much more.



Click image for full view.

You can use the Device Groups button to determine how information should be grouped in the results panel when starting a new run of automation tests.



Click image for full view.

When looking at the results, use the Display selection to show the Name of the test or the Time the test took to complete.



Click image for full view.

Export

Once the tests have been completed, it is possible to export the results to a CSV file via the Export drop-down.



Click image for full view.

Choose from the available filters that you'd like to export and then select the Export Data button.



When your data is exported, a pop-up will indicate if it was successful and the save location of the CSV file.



The Export drop-down will only be active once reports have been generated, and the Export Data button will only become active if there are reports that meet the filter criteria.

Copy

Once the tests have been completed, you can select any lines that appear in the Automation Test Results panel and click the Copy button to copy them to your clipboard and paste elsewhere.



Click image for full view.

Gauntlet is a framework to run sessions of projects in Unreal Engine that perform tests and validate results. It is specifically designed for, but not limited to, running Unreal sessions on a variety of platforms. An Unreal session is all of the processes needed to execute a game with the Unreal engine. For example, a multiplayer game may require four clients and a server.

Gauntlet does not require any specific game-side automation code or test framework — how your game performs tests is entirely up to you. There is however a Gauntlet Plugin that provides a useful TestController class to assist with puppeteering and monitoring a game instance. It is well suited to smoke tests that require several steps to execute, but it is entirely optional.



Framework to run sessions of projects in Unreal Engine that perform tests and validate results.



Instructions on how to run a Gauntlet test and an explanation of what happens during the process.

Architecture

Level 1

Level 2

Level 3

Gauntlet Core Interfaces

Core Classes

TestExecutor

ITestNode

Unreal Test Node

Gauntlet is a framework to run sessions of projects in Unreal Engine that perform tests and validate results. It is specifically designed for, but not limited to, running Unreal sessions on a variety of platforms. An Unreal session is all of the processes needed to execute a game with the Unreal engine. For example, a multiplayer game may require four clients and a server.

Gauntlet does not require any specific game-side automation code or test framework — how your game performs tests is entirely up to you. There is however a Gauntlet Plugin that provides a useful TestController class to assist with puppeteering and monitoring a game instance. It is well suited to smoke tests that require several steps to execute, but it is entirely optional.

Gauntlet Does

Platform independent implementations of builds, devices, and tests as low-level units that provide the functional operations necessary to be configured and combined.

Provide high-level classes that can launch complicated configurations (e.g. 5v5 clients and a server) for games.

Provide utility functions for parsing log files, crashes, and accessing /saved data from devices.

Gauntlet Does Not

Require specific Unreal-side code. The intention is that the execution within Unreal uses whatever makes the most sense. It could be something extensive such as the Unreal Automation Framework, or just some command-line parameters that the game interprets.

Create builds. You need to provide Gauntlet with a network or locally cooked build.

Architecture

Gauntlet offers three tiers of functionality. Earlier tiers may be (and are!) used in isolation for things like scripting device interactions, non-Unreal unit testing, etc whereas the latter tiers abstract a great amount of complexity behind simple user-configurable options.

Level 1

Interfaces (devices, builds, apps) that abstract the concept of devices, builds, installations, and processes.

ITargetDevice

IBuildSource

IBuild

IAppInstall

IAppInstance

A framework that supports sequential, parallel, and dependent execution of user-created tests.

TestExecutor

ITestNode

Level 2

Device and AppInstance implementations for all platforms Unreal supports (PC, Mac, PS4, Xbox One, Switch, iOS, Android).

TargetDeviceWindows

TargetDeviceMac

TargetDevicePS4

TargetDeviceXboxOne

TargetDeviceSwitch

TargetDeviceIOS

TargetDeviceAndroid

Classes that support the configuration and launch of one or more "roles" that exist in an Unreal session (e.g. four clients, one server)

UnrealAppConfig

UnrealSessionRole

UnrealSession

UnrealSessionInstance

Level 3

Classes that implement ITestNode and IBuildSource in the context of an Unreal Session

UnrealBuildSource

UnrealTestConfiguration

UnrealTestContext

UnrealTestNode

RunUnreal - a class that inherits from UAT's BuildCommand and configures a number of parameters before constructing a list of tests and then executing them.

Gauntlet Core Interfaces



Core Classes

The TestExecutor class handles creation, queuing, and monitoring of a set of tests. Multiple tests can be executed in parallel if the TestNode supports such a thing. An example of where care is needed is port usage for Unreal Servers. For the first test a default port is fine, but when tests are executing in parallel both the server and client must use unique ports.

ITestNode is an interface class that describes the API all test nodes must implement.

Unreal Test node implements ITestNode, largely by configuring an UnrealSession object and calling its relevant functions.

ElementalDemo Test Node

Run the ElementalDemo Example

ElementalDemo Test Explanation

In this guide, you will run an existing Gauntlet test available for the Elemental demo in Unreal Engine. This will familiarize you with the process for running tests and give you an idea what is happening at each step along the way.

ElementalDemo Test Node



Run the ElementalDemo Example

Open a command prompt and change directory to Engine/Build/BatchFiles within your Unreal Engine root directory.

Enter the following in the command prompt:

Once that process completes, enter the following in the command prompt:

ElementalDemo Test Explanation

BuildCookRun generated a Win64 build of ElementalDemo in Samples/ElementalDemo/Saved/StagedBuilds.

RunUnreal launched Gauntlet, which:

Created an instance of the ElementalDemoTest node, which provided basic rules for running the test.

Discovered local builds for the ElementalDemo Project.

Validated that a Win64 Development build was available.

Launched ElementalDemo.

Monitored the running process for any issues.

Detected that ElementalDemo had exited.

Checked for common issues such as crashes, asserts, and fatal errors.

Along the way, provided the ElementalDemoTest node verifies that the test was still running and that no errors had occurred, create a summary report.

Unreal Insights

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Stat Commands

Types

Grouping Stats

Example Usage

Declaring and Defining Stats

For a Single File

For Multiple Files

Examples

Custom Memory Stats with Pools

Header File Sample

Source File Sample

Regular Memory Stats Without Pools

Performance Data Using Cycle Counters

Performance Data Using GetStatId

Logging Performance Data

Method

Code Sample

Utility Class and Methods

Code Sample

Generic Data Using FLOAT or DWORD Counters

Methods to Update Counters

Helper Methods to Manage Counters

The Stats System enables you to collect and display performance data so that it can be used to optimize your game.

For help with Stat Commands, type stat into the console, or refer to the PrintStatsHelpToOutputDevice(); method.

Types

The Stats System supports the following types:

Stats Type

Description

Cycle Counter

A generic cycle counter used to count the number of cycles during the object's lifetime.

Float/Dword Counter

A counter that is cleared every frame.

Float/Dword Accumulator

A counter that is not cleared every frame, being a persistent stat that can be reset.

Memory

A special type of counter that is optimized for memory tracking.

Grouping Stats

Each stat must be grouped, which usually corresponds with displaying the specified stat group. For example, stat statsystem displays stats' related data.

To define a stat group, use one of the following methods:

Method

Description

DECLARE_STATS_GROUP(GroupDesc, GroupId, GroupCat)

Declares a stats group that is enabled by default.

DECLARE_STATS_GROUP_VERBOSE(GroupDesc, GroupId, GroupCat)

Declares a stats group that is disabled by default.

DECLARE_STATS_GROUP_MAYBE_COMPILED_OUT(GroupDesc, GroupId, GroupCat)

Declares a stats group that is disabled by default and which may be stripped by the compiler.

Where:

GroupDesc is a text description of the group

GroupId is a UNIQUE id of the group

GroupCat is reserved for future use

CompileIn, the compiler may strip it out if it is set to true

Depending on the usage scope, grouping can be done in the source or header file.

Example Usage

Declaring and Defining Stats

Now, you can declare and define a stat, but before you do, note that a stat can be used in:

Only one cpp file

The function scope

The module scope

The whole project

For a Single File

For the scope of a single file, you must use one of the following methods, depending on the stat type:

Method

Description

DECLARE_CYCLE_STAT(CounterName, StatId, GroupId)

Declares a cycle counter stat.

DECLARE_SCOPE_CYCLE_COUNTER(CounterName, StatId, GroupId)

Declares a cycle counter stat and uses it at the same time. Additionally, it is limited to one function scope.

QUICK_SCOPE_CYCLE_COUNTER(StatId)

Declares a cycle counter stat that will belong to a stat group named 'Quick'.

RETURN_QUICK_DECLARE_CYCLE_STAT(StatId, GroupId)

Returns a cycle counter, and is sometimes used by a few specialized classes.

DECLARE_FLOAT_COUNTER_STAT(CounterName, StatId, GroupId)

Declares a float counter, and is based on the double type (8 bytes).

DECLARE_DWORD_COUNTER_STAT(CounterName, StatId, GroupId)

Declares a dword counter, and is based on the qword type (8 bytes).

DECLARE_FLOAT_ACCUMULATOR_STAT(CounterName, StatId, GroupId)

Declares a float accumulator.

DECLARE_DWORD_ACCUMULATOR_STAT(CounterName, StatId, GroupId)

Declares a dword accumulator.

DECLARE_MEMORY_STAT(CounterName, StatId, GroupId)

Declares a memory counter the same as a dword accumulator, but it will be displayed with memory specific units.

DECLARE_MEMORY_STAT_POOL(CounterName, StatId, GroupId, Pool)

Declares a memory counter with a pool.

For Multiple Files

If you want to have stats accessible to the whole project (or for a wider range of files) you need to use extern version. These methods are the same as the previously mentioned but with _EXTERN and the end of the name:

DECLARE_CYCLE_STAT_EXTERN(CounterName, StatId, GroupId, API)DECLARE_FLOAT_COUNTER_STAT_EXTERN(CounterName, StatId, GroupId, API)DECLARE_DWORD_COUNTER_STAT_EXTERN(CounterName, StatId, GroupId, API)DECLARE_FLOAT_ACCUMULATOR_STAT_EXTERN(CounterName, StatId, GroupId, API)DECLARE_DWORD_ACCUMULATOR_STAT_EXTERN(CounterName, StatId, GroupId, API)DECLARE_MEMORY_STAT_EXTERN(CounterName, StatId, GroupId, API)DECLARE_MEMORY_STAT_POOL_EXTERN(CounterName, StatId, GroupId, Pool, API)

Then in the source file, you need to define these stats with the following, which defines stats that are declared with _EXTERN:

Where:

CounterName is a text description of the stat

StatId is a UNIQUE id of the stat

GroupId is the id of the group that the stat will belong to, the GroupId from DECLARE_STATS_GROUP*

Pool is a platform-specific memory pool

API is the *_API of a module, and it can be empty if the stat will only be used in that module

Examples

Custom Memory Stats with Pools

First you need to add a new pool to enum EMemoryCounterRegion, which can be global or platform specific:

The following is an example that will allow using the pools everywhere (see CORE_API).

The pool name must start with MCR_.

Header File Sample

Source File Sample

Regular Memory Stats Without Pools

Or, if you prefer, you can DECLARE_MEMORY_STAT_EXTERN in the header file and then DEFINE_STAT in the source file.

Updating the memory stats is done the same way as in the version with pools.

Performance Data Using Cycle Counters

First, you need to add cycle counters:

Or, you can DECLARE_CYCLE_STAT_EXTERN in the header file and then DEFINE_STAT in the source file.

Now, you can grab the performance data:

Sometimes, you do not want to grab the stats every time the function is called, so you can use a conditional cycle counter — it is not very common, but it may be useful:

If you want to grab the performance data from one function, you can use the following construction:

You can also do the following:

This is mostly used for temporary stats.

All of the previously mentioned cycle counters are used to generate the hierarchy so that you can get more detailed information about performance data. However, there is also the option of setting a flat cycle counter:

Performance Data Using GetStatId

A few tasks implemented in Unreal Engine use a different approach in terms of getting the performance data. They implement method GetStatId(), and if there is no GetStatId(), the code will not compile.

Here is an example:

Logging Performance Data

If you just want to log performance data, we provide the following functionality:

Method

The following method captures the time (passed in seconds), and adds delta time to the variable that is passed in:

SCOPE_SECONDS_COUNTER(double& Seconds)

Utility Class and Methods

Class

Description

FScopeLogTime

Utility class that logs the time (passed in seconds), adding cumulative stats to passed-in variable, and printing the performance data to the log in the destructor.



Method





Description



SCOPE_LOG_TIME(Name, CumulativePtr)

Using the provided name, prints the performance data and gathers cumulative stats.

SCOPE_LOG_TIME_IN_SECONDS(Name, CumulativePtr)

The same functionality as SCOPE_LOG_TIME, but it prints in seconds.

SCOPE_LOG_TIME_FUNC()

Using the function name, it prints the performance data, and it cannot be nested.

SCOPE_LOG_TIME_FUNC_WITH_GLOBAL(CumulativePtr)

The same functionality as SCOPE_LOG_TIME_FUNC, but it gathers cumulative stats.

Generic Data Using FLOAT or DWORD Counters

Generally, the first thing you need to do is add your counters, such as the following:

Then, to update and manage your counters, you can use the following methods:

Methods to Update Counters

Method

Description

INC_DWORD_STAT(StatId)

Increases a dword stat by 1.

DEC_DWORD_STAT(StatId)

Decreases a dword stat by 1.

INC_DWORD_STAT_BY(StatId, Amount)

Increases a dword stat by the specified value.

DEC_DWORD_STAT_BY(StatId, Amount)

Decreases a dword stat by the specified value.

SET_DWORD_STAT(StatId, Value)

Sets a dword stat to the specified value.

INC_FLOAT_STAT_BY(StatId, Amount)

Increases a float stat by the specified value.

DEC_FLOAT_STAT_BY(StatId, Amount)

Decreases a float stat by the specified value.

SET_FLOAT_STAT(StatId, Value)

Sets a float stat to the specified value.

Helper Methods to Manage Counters

Method

Description

GET_STATID(StatId)

Returns an instance of the TStatId of the stat.

This is advanced.



GET_STATDESCRIPTION(StatId)

Returns a description of the stat.

The Visual Logger Viewport

The Actor List

The Actor Snapshot View

The Text Window

The Timeline

Adding Visual Logger Support

Taking Actor Snapshots

Logging Text

Drawing Debug Shapes

The Visual Logger is a powerful debugging tool that creates and records visual representations of the gameplay state, and provides the ability to review this data in the Editor. Developers can see debug output live during a play session, or review it in the Editor after the session is over, making it much easier to resolve gameplay bugs that are hard to track down based only on user reports or game footage. The ability to record information for later review is especially important when working with rare or difficult-to-reproduce bugs. For example, an unexpected AI behavior may be caused by a game state variable that changes for a single frame can be studied after the fact by recording the data and scrubbing through the frames around the moment when the bug happened.

To activate the Visual Logger, use the menu in Windows > Developer Tools > Visual Logger. In Unreal Engine versions prior to 4.7, enter the console command "VisLog". If you are in the Editor, the Visual Logger viewport will also open.



Using the Visual Logger during a session of the Epic Games sample, StrategyGame. The purple line indicates the AI's path, and the red location marker shows the selected point in the timeline.

The Visual Logger Viewport

In the Editor, the Visual Logger viewport provides the ability to review Visual Logger output from pre-recorded sessions, enabling developers to review a bug after the fact.



The Visual Logger viewport in the Editor.

The viewport contains a list of all Actors that logged any visualization data, a detailed snapshot of the status of the Actor selected in the Actor list, a text window for displaying debug message output, and a time bar to enable scrubbing through the recorded data.

The Actor List

The highlighted area in the following image shows the list of Actors that have logged information to the Visual Logger during the recorded session. There is also a search bar to help users find a specific Actor's log information quickly.



The Actor list and its search bar.

The Actor Snapshot View

Any data that an Actor collects with the UE_VLOG macro will appear in the highlighted area of the following image. The Visual Logger will display data coming from the Actor selected in the Actor list, at the time indicated by the timeline scrubber. Data that the Visual Logger captures as part of the snapshot can be categorized and customized in your game's code, and you can expand or collapse these categories.

Making multiple visual logging calls in the same frame and from the same Actor will overwrite the previously-captured data.



The Actor snapshot area with custom categories expanded.

The Text Window

The Visual Logger's text window shows log messages from the current frame, broken up into categories. Multiple log messages recorded in the same category and the same frame will show up as a list.



The text window area where debug messages appear.

The Timeline

The timeline view features a bar that advances (or rewinds) the logger to any point in time you choose. In the image below, the scrubber is at the 23.53 second mark, and the Actor list has "StrategyAIController_1" selected. By scrubbing the time bar, you can view the selected Actor's status and the text window at different times in the recorded log data.



The timeline area.

Adding Visual Logger Support

There are three types of data that you can add to the Visual Logger:

Data Type

Output Description

Actor Snapshots

These will appear in the Actor snapshot area, and should update once per frame while the actor exists.

Log Messages

All text that you log with the Visual Logger will appear in the text window. Text appears on a single-frame basis.

Debug Shapes

You can draw a variety of shapes into the game world. These shapes can last for multiple frames, and have many adjustable parameters, such as size and color.

Taking Actor Snapshots

To add data to the Actor Shapshot View, you must first implement the IVisualLoggerDebugSnapshotInterface interface function as follows:

This interface contains only one function, GrabDebugSnapshot, which does nothing by default. You can override this function to feed information to the Visual Logger. Because GrabDebugSnapshot should only run in builds with Visual Logging enabled, it is a good practice to check the ENABLE_VISUAL_LOG macro around any code related to it. For example, the function declaration in your Actor class would include a block of code that looks like this:

The following sample code was part of a GDC demo that added Visual Logging to a customized version of the First-Person Shooter template's Character class called AGDCCharacter. This code adds a single entry under the "GDC Sample" category. The entry is labeled "Projectile Class" and contains the type of projectile that the Character spawns when firing.

This function will run automatically on the first call to the Visual Logger. Add any information that you want to see in the Actor Snapshot View into this function.



Visual Logger with the Actor Snapshot of an AGDCCharacter.

Logging Text

You can log to the Text Window with the UE_VLOG macro. The Text Window displays information on a per-frame bases, so only text logged in the current frame will show up as you scrub through the recorded data. You can log text from anywhere, and the UE_VLOG macro will cleanly remove itself from compilation in builds that don't support the Visual Logging system, so it is safe to use without checking the ENABLE_VISUAL_LOG macro. The macro takes parameters indicating the Actor associated with the text, the log category and verbosity level (used for filtering the display), and the text itself.

In the following sample code, our customized Character uses UE_VLOG to log information after firing a projectile:



Visual Logger showing debug text from our AGDCCharacter.

If you want to send a duplicate message to the standard log, you can use the UE_VLOG_UELOG macro instead of calling UE_VLOG followed by UE_LOG with the same data.

Drawing Debug Shapes

The ability to log shape information in the game world is a powerful feature because it helps you visualize what is going on. The following image shows some of the different types of shapes that the Visual Logger supports.



Path information, cylinder, cone, capsule, and box shapes.

The following macros provide support for logging shapes. Each macro requires an Actor that owns the shape, a log category and verbosity level, several additional, shape-defining parameters (depending on the shape), and the text that will accompany the shape. The following table provides information about the available shapes and the additional parameters each shape requires.

Shape

Description

Additional Parameters

UE_VLOG_SEGMENT

A one-pixel-thick line segment.

FVector Start Point

FVector End Point

FColor Color

UE_VLOG_SEGMENT_THICK

A line segment with variable thickness.

FVector Start Point

FVector End Point

FColor Color

float Thickness

UE_VLOG_LOCATION

A sphere.

FVector Location

float Radius

FColor Color

UE_VLOG_BOX

An axis-aligned box.

FVector Center Location

FColor Color

UE_VLOG_OBOX

A rotated box.

FVector Center Location

FMatrix Box Rotation

FColor Color

UE_VLOG_CONE

A cone.

FVector Origin Point

FVector Cone Direction

float Cone Length

float Cone Angle In Degrees

FColor Color

UE_VLOG_CYLINDER

A cylinder.

FVector Start Point

FVector End Point

float Cylinder Radius

FColor Color

UE_VLOG_CAPSULE

A capsule.

FVector Center Point

float Half-Height

float Radius

FMatrix Capsule Rotation

FColor Color

UE_VLOG_MESH

A 3D Mesh.

TArray<FVector> Mesh Vertices

TArray<int32> Triangle Indices (must be in groups of three)

FColor Color

UE_VLOG_CONVEXPOLY

A 2D convex-hull polygon.

TArray<FVector> Hull Points

FColor Color

UE_VLOG_ARROW

A line segment with an arrowhead.

FVector Tail Location

FVector Head Location

FColor Color

Overview

Running Build Tool With Sanitizers

UnrealBuildTool (UBT) supports Clang sanitizers for Linux and Android. This page contains information about which sanitizers are supported and how to use them in your builds.

Overview

There are many types of programming errors that are not normally caught at compile time, as the compiler recognizes them as valid use of C++ syntax. Even though the syntax is correct, gaps in the logic can lead to undesired behavior, such as:

Memory leaks

Race conditions

Uninitialized memory

Out-of-bound access in arrays

Integer overflow

Normally, these can only be diagnosed at runtime through trial-and-error debugging. By building your application with Clang's sanitizers enabled, you can find these errors more rapidly with a log output that directly reports them.

You can find thorough details on Clang's sanitizers and their benefits in Clang's documentation.

Running Build Tool With Sanitizers

To instrument a sanitizer in your build, run UnrealBuildTool with the UBT argument for the desired sanitizer, and the sanitizer will be linked in your final executable. For example, the following command line builds your project with Address Sanitizer (ASan) linked in your build:

When you run your application, you will see the sanitizer's error detection output in your logs. You can run these builds directly through a command line, or you can open your project's Properties in Visual Studio, then add the sanitizer's command to NMake > Build Command Line.

Clang's sanitizers typically consume extra memory and slow down the programs they are linked in by at least 2x and sometimes as much as 15x, depending on the sanitizer. Review Clang's specifications for each sanitizer for more information.

Supported Sanitizers

The following sanitizers are supported by UBT:

Sanitizer

UBT Command

Description

Address Sanitizer (ASan)

-EnableASan

Detects a variety of memory access problems, including out-of-bound access errors and memory leaks.

HWASan (Android only)

-EnableHWASan

Hardware-accelerated version of ASan for Android. Should use 20-30% less memory.

Thread Sanitizer (TSan) (Doesn't work on Android)

-EnableTSan

Detects threading issues like race conditions.

Undefined Behavior Sanitizer (UBSan)

-EnableUBSan

Detects anything that C++ recognizes as undefined behavior, like out-of-bounds errors, integer overflow, or uninitialized memory.

MinUBSan (Android only)

-EnableMinUBSan

Minimalistic version of UBSan for Android.

Memory Sanitizer (MSan) (Linux only)

-EnableMSan

Detects attempts to read uninitialized memory.

Building UELibrary

Built-In API

Expanding the API

Unreal Engine as a Library (UELibrary) repackages the functionality of Unreal Engine (UE) into a library, enabling other applications to spawn and control their own UE5 instances. UELibrary provides a simple, platform-agnostic API to drive UE5. UE5 provides the source code to UELibrary along with a sample application, so developers can examine the process and even add their own engine, plugin, or project-level API functions.

This feature creates a library that includes "Engine Tools" as defined in the Unreal Engine End User License Agreement ("EULA"). Please read and understand your rights with respect to Engine Tools under the EULA, in particular, the limitations to distributing products that contain Engine Tools. For more information, visit our FAQ and Custom License Page.

Building UELibrary

You can build UELibrary for monolithic Editor builds on Win64. UELibrary builds alongside the Engine, and will produce its .lib file with a name and path somewhere under /Engine/Intermediate/Build/, according to the build configuration you chose. For example, the Development Editor configuration on Win64 outputs /Engine/Intermediate/Build/Win64/UnrealEditor/Development/UELibrary/UnrealEditor-UELibrary.lib. To build it as part of a project, you must add the following code to your project's *.Target.cs file:

You can interact with UELibrary through the built-in API outlined below, or you can expand the API to suit your application's needs.

Built-In API

The built-in API gives control over four basic features: starting the Engine, passing in Windows messages, ticking the Engine, and shutting the Engine down.

Exposed Function Signature

Purpose

int UELibrary_Init(HINSTANCE hInst, HWND hWnd, const char* CmdLine)

Starts UE5 with a Command Line, registering it to the owning application and window you provide. Be sure to include a .uproject file and a map to load in the Command Line. A non-zero return value indicates an error. You can only call this once per session; running multiple UE5 instances (or rendering to multiple windows) is not supported.

int UELibrary_Tick()

Ticks the Engine. We recommend calling this frequently, as most UE5 applications expect to tick 30 to 60 times per second, or more in the case of VR applications. A non-zero return value indicates an error.

The Engine will determine the time difference between this tick and the one before it. Calling it infrequently will result in the Engine simulating a large period of time in a single tick the next time you call it. The Engine has built-in rules like time dilation and maximum delta time for a single tick that you should consider if you plan to call this function infrequently. VR applications or hardware may stop rendering at low tick rates in order to protect users from motion sickness.

LRESULT UELibrary_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

Passes Windows messages into the Engine. This is a passthrough to WndProc, and returns whatever value WndProc returns.

int UELibrary_Shutdown()

Shuts down UE5. This is permanent; you cannot restart UE5 after shutting it down. A non-zero return value indicates an error.

This simple API is exposed by default, and gives you the tools you need to operate UE5 externally. You can expand the API if you need additional capabilities.

Expanding the API

You can also expand the API to suit your needs, exposing additional existing or new functionality for external use. To do this, you must first modify your project's *.Target.cs file as described above. Write any additional functions your application needs and use the UELIBRARYAPI macro to expose them.

While you might want to implement your new functionality directly in the engine, we advise against this. Use project-level implementations as described.

BuildGraph

Packaging Methods

UE Toolbar

Project Launcher

Command Line

Content Cooking

Cook By the Book

Cook On the Fly

Deploying a Build

As part of the packaging process, the Automation Tool (sometimes abbreviated as UAT for Unreal Automation Tool) is used to work through a set of utility scripts for manipulating Unreal Engine (UE) projects. For the packaging process, the Automation Tool uses a particular command called BuildCookRun. This command can cook content for a platform, package it up into a platform's native format for distribution, deploys it to the device, and automatically runs the project (where applicable). Packaging your project does not solely require the direct use of UAT, though. Use the Platforms button of the UE Toolbar to select from available platforms or Command Line to cook and package content for a platform.

As part of the BuildCookRun command in UAT, the following stages outline the different stages of the packaging pipeline:

Build: This stage compiles the executeables for the selected platform.

Cook: This stage cooks content by executing the UE in a special mode.

Stage: This stage copies the executables and content to a staging area; a standalone directory outside of the development directory.

Package: This stage packages the project into a platform's native distribution format.

Deploy: This stage deploys the build to a target device.

Run: This stage starts the packaged project on the target platform.

For a list of predefined tasks, read the BuildGraph Script Tasks reference page.

Packaging Methods

Because you can deploy content in several different ways to a target platform for testing, debugging, or in preparation for release, you can test your packages in multiple different ways:

Use UE Toolbar to quickly test a part of your currently loaded Level for testing and debugging.

Use the Project Launcher to use a default profile or create a custom one to perform actions like profiling or debugging for your project's latest build.

Take an already packaged game and deploy it to a platform, such as a console or mobile device.

Follow sections below to learn more about these packaging methods and how you can package your games using them.

UE Toolbar

Use Platforms button of the UE Toolbar to select a platform to package your project for. When you package a project using this option, it will save the packaged project to a folder that you select but will not deploy it to the device.



From drop-down menu under Platforms, you can perform the following actions:

Build and launch a project on the available device you need. When clicked, the launch process automatically Cooks the necessary content, build code, and launch on the selected platform. The build is a quick way to test functionality during active development without the need to compile and run the entirety of the project every time you need to test something.



Choose the target platform and adjust the Build Configuration for it (Development, Shipping, and so on).



Access to the Project Launcher, Device Manager, Packaging Settings, and Supported Platforms.



If you do not see the platform you want to deploy to or it is grayed out in this menu, here are some things you can check:

Make sure that you have the correct SDK installed for that platform (if required) and that it is supported by the Engine version you are currently using. Often, this can be checked in the platform's UEBuild.cs file located in Engine/Source/Programmings/UnrealBuiltTools/Platforms. For example, if you needed to see which SDK is supported for Android, you could look in the UEBuildAndroid.cs file.

Be sure that any Visual Studio extensions or necessary files are installed.

Some platforms (like console) require external tools to connect the device. Make sure this is working properly, and the device is detected.

Use the Device Manager in the Engine to "claim" any devices as needed, which ensures it can only be used for your local machine.

Project Launcher

The Project Launcher affords you the ability to deploy for different platforms all from one location and even from a single launch profile. For open Project Launcher click Platforms > Project Launcher.

Each platform that is deployed to has its own default launch profile (listed in the main window). You can also choose to create a custom one that enables you to build a project in a specific way with many advanced settings. These include being able to apply command line arguments, test downloadable content (DLC) and patching releases, and much more.



For additional information, see the Project Launcher reference page.

From the Project Launcher, you can create a Custom Launch Profile that can be used on all platforms or even just the ones you specify. These profiles enable you to build your content in specific ways by setting how it is cooked, packaged, and deployed using the available build operations.

To add your own Custom Launch Profile, click the Add button on the right side of the window.



After doing so, the Custom Launch Profile is immediately open. Be sure to give it a Name and Description so that you can quickly identify it later.



Command Line

The Automation Tool enables you to cook and package your game using Command Line, and since all build operations are performed by UAT, it can be run directly on the Command Line with RunUAT.bat file when provided with valid arguments.

The RunUAT files can be found in Engine/Build/BatchFiles. For Windows, use the RunUAT.bat file and for Mac/Linux use the RunUAT.sh.

A basic cook can be performed using the following command line arguments following either the UnrealEditor.exe or UnrealEditor-cmd.exe files:

The commandlet must be specified via -run=cook and a platform to cook for must be specified. It will generate the cooked data for the platform that is specified and saves it to the following location:

Authoring your command line arguments by hand can be quite involved and has more potential to create accidental errors. Because of this, it is recommended to use a Custom Launch Profile to accurately generate a Command Line for your build. Any parameters entered in the custom launch profile will automatically generate the Command Line and display it in the Output Log window when it is used to cook and build the project. Any text that follows BuildCookRun onward can be directly passed as your command line arguments using RunUAT.bat.

The following is an example of the generated output from the Project Launcher and the equivalent Command Line that would need to be manually authored to use for RunUAT.bat:

Project Launcher Log Window

Manually Authored

For additional information, see the Content Cooking page.

Content Cooking

In UE, content is stored in particular formats that are supported (PNG for textures data or WAV for audio) for a platform. However, this content may not be in a format that can be used by the platform you are developing for. The process of Cooking converts Assets used by the UE into ones that can be read on the platforms being deployed to. In some cases, the cooked content is converted to a proprietary format (like with console) that can only be read by by that platform.

Cooking content for different platforms can be done by using Command Line or by using the Project Launcher, and its UE interface. For some platforms, all content must be cooked before it can be used on the device for it to work correctly. You may need to check with the platform you are developing for if this is the case.

There are two ways to cook content for your projects; By the book and On the fly.



Cook By the Book

Cook By the book (CBTB) performs the entirety of the cook process ahead of time allowing for the build to deploy the cooked Assets all at once rather than as needed while playing the Level (if you were using a cook server). This option is useful for developers who are not iterating on individual Assets or for those who want the game to perform at full-speed without waiting for a server to deliver the necessary cooked content. Typically, performance testing and playtests will want to use this method.

When performing a CBTB, there is no extra setup required for the build. Use the Project Launcher to create a Custom Launch Profile and in the Cook section, use the drop-down selection to choose By the book.



If you have any game-specific command lines to add, you can expand the Advanced Settings and add the arguments to the Additional Cooker Options.



An example would be:

For additional information about this cook method and its available settings, refer to the Project Launcher reference page.

Cook On the Fly



When you choose to cook content On the fly (COTF), it will delay cooking it until after the game has been deployed to the platform. Only the executable and some other basic files are installed, which use network communication with a Cook Server to make requests on-demand as the content is needed. COTF allows for faster iteration for developers who will be making changes to content regularly or those who will only be exploring sections of the game.

To cook on the fly, you will first need to start a Cook Server on a machine which has the full project available to it. This can be either your local machine or a remote server which performs the cook. The Cook Server can be run by starting the UE in Command Line mode using the following arguments with the UnrealEditor-cmd.exe:

On the developer's local machine, access a Custom Launch Profile from the Project Launcher and in the Deploy Section, set the method to File Server. Optionally, you can use the Default Deploy Platform to select a single platform or use the toggles to enable multiple platforms to build and deploy to.



For the executable to know where to load content from, it needs to be made aware of the IP address of the machine that is running the Cook Server. To do this, you will need to pass the following command line argument on the client's Command Line (where x.x.x.x represents your host's IPs):

The argument can be specified in your custom launch profile under the Launch section in the Additional Command Line Parameters text box. If the IP address is left unspecified, the build will load from existing local files and not attempt to connect to the Cook Server.



For additional information about this cook method and its available settings, refer to the Project Launcher reference page.

Deploying a Build

To deploy a build from the Project Launcher, you must have a project that cooked and packaged. There are a couple of ways you can deploy this type of build to a platform. In your Custom Launch Profile under the Deploy section, set the way you want to deploy the build.



File Server will cook and deploy the content at runtime as it is needed to the device.

Copy to Device will copy the entire cooked build to the device.

Do Not Deploy will not deploy the build to any device once the cook and package complete.

Copy Repository will copy a build from a specified file location to deploy to any device.

For additional information about this deployment methods and their available settings, refer to the Project Launcher reference page.

Cooking Content from the Command Line

Options

Unreal Engine stores content assets in particular formats which it uses internally, such as PNG for texture data or WAV for audio. However, this content needs to be converted to different formats for the various platforms, either because the platform uses a proprietary format, does not support the format Unreal uses to store the asset, or a more memory- or performance-effective format exists. The process of converting content from the internal format to the platform-specific format is referred to as cooking.

Cooking Content from the Command Line

To cook data for your game, you need to use the Cook commandlet.

The basic cook is performed via the following:

Or

The commandlet must be specified via -run=cook and a platform to cook must also be specified. This will generate cooked data for the platform specified and saved it to the location below:

Options

Option

Description

-targetplatform=<Plat1>+<Plat2>

Specifies the platform(s) to be cooked. The list of available platforms are WindowsNoEditor, WindowsServer, LinuxServer, PS4, XboxOne, IOS, and Android.

-iterate

Specifies the cooker only cook items that are out of date. Without this option, the sandbox directory is deleted and everything is recooked.

-Map=<Map1>+<Map2>+...

Specifies the map(s) to build.

-cookonthefly

Specifies that the cooker be started in server mode. This will launch a server which waits for a game to connect and then serves the cooked data as needed. When this option is used, the game requires -filehostip=<Server IP> specified on its command line so it can connect with the server.

-MapIniSection=<ini file section>

Specifies a section from the ini files which contains map names. The cooker will cook all maps specified in the section specified.

-UnVersioned

Saves all of the cooked packages without versions. These are then assumed to be the current version on load.

-CookAll

Cooks everything.

-Compressed

Tells the cooker to compress the cooked packages.

Asset Management

Understanding Primary Asset Rules

Chunk Organization

Defining Chunks In Your Project

Defining Chunks With the Asset Manager

Defining Chunks With Rules Overrides in Configs

Defining Chunks With Primary Asset Labels

Packaging Chunks

Analyzing Asset-to-Chunk Assignments

Asset Audit Window

Size Map

Reference Viewer

When you cook your project, Unreal Engine can divide up your game's assets into separate chunks that can be independently distributed, such as with DLC and patches. A chunk is a numbered collection of assets recognized by the engine's asset management system, and when a project cooks, each chunk generates a .pak file which you can then distribute through a content delivery system.

You can designate assets as belonging to specific chunks using the Asset Manager or using Primary Asset Labels. Both use a system of rules and metadata to construct chunks, which are then read during the cooking process. The sections below outline how to use these tools and how to interact with chunks in the editor.

Understanding Primary Asset Rules

A primary asset is an asset that can be manipulated directly by the asset manager, while secondary assets are assets that are loaded automatically when a primary asset references them. Primary assets are the type referenced in the cooking and chunking process.

Primary asset rules are used to determine which primary assets have management authority over which secondary assets, as well as how to handle assets during the cooking process. These rules are defined by the FPrimaryAssetRules structure, and are used by the Asset Manager to determine how to handle Assets at cook time. For detailed information on the options available within FPrimaryAssetRules, check its API Page . You may also want to look up the Cooking Rules defined on the EPrimaryAssetCookRule API Page.

One of the functions of primary asset rules is organizing chunks. By defining a rule and giving it a Chunk ID, all primary assets that fall under that rule are divided into a chunk with that ID number. Any secondary assets that those primary assets have authority over will be chunked alongside it.

Chunk Organization

Any asset not given a specific Chunk ID or given a negative Chunk ID will be packaged as part of chunk 0, which is the "default" chunk that is distributed with your game's base data. Any chunks with a higher ID value than 0 are separated into different .pak files at cook time. You can organize chunks in any way that suits your project. For example, the ShooterGame sample project has three chunks:

Chunk 1 for the "Sanctuary" map

Chunk 2 for the "Highrise" map

Chunk 0 for all other data

ShooterGame recognizes maps as primary assets, therefore any secondary asset used by a map, like a texture or a mesh, will use the chunk ID of the map that owns it, provided that the map has authority over it.

As another example, if you are creating a MOBA or any other "hero-based" game, you would divide different heroes' base assets into specific chunks, and then you might divide any additional costumes or skins into their own chunks as well so that they can be distributed separately.

Defining Chunks In Your Project

Unreal Engine provides several methods for manipulating primary asset rules and defining chunks. You can define primary asset rules in the Asset Manager, edit them directly in your *Game.ini file, or you can use Primary Asset Labels in the Content Browser.

Defining Chunks With the Asset Manager

You can manually edit primary asset rules for your project by opening your Project Settings and navigating to Game > Asset Manager.



Editing Primary Asset Rules in the Asset Manager's settings. Click image to enlarge.

Primary Asset Types to Scan designates the asset types that you want the asset manager to recognize as primary assets. The primary asset rules list lets you designate the Priority and Chunk ID of individual primary assets.

Defining Chunks With Rules Overrides in Configs

Rules Overrides in configs can be used to establish the priority and Chunk settings for a specific Primary Asset. To build our three-Chunk setup for ShooterGame using Rules Overrides instead of Primary Asset Labels, the following section should be created in DefaultGame.ini:

Cooking and chunking rules in the DefaultGame.ini file. We have added an explicit reference to the startup map, "ShooterEntry", in this example.

This sets our main game maps to be in specific chunks, which will cause all of their references to be added to those chunks as well. The final entry, governing Chunk 0, ensures that anything referenced by the map that loads when the game first starts up will be in Chunk 0, which is also the default Chunk. The priority value of -1 sets priority to the default value, which is 1.

Defining Chunks With Primary Asset Labels

Primary Asset Labels are a type of data asset that designates other assets for cooking and chunking. These can be much quicker compared with creating rules for individual assets.



An example of a Primary Asset Label in the Content Browser.

To create a Primary Asset Label, right-click inside the content browser, then click Miscellaneous > Data Asset.



In the Pick Data Asset Class menu, select PrimaryAssetLabel and click Select.



The Pick Data Asset Class menu pops up when you create a new Data Asset. Click image to enlarge.

Your new primary asset label will be created in the Content Browser. If you double-click it, you can edit its data.



The settings for the HighriseLabel Primary Asset Label in ShooterGame. Click image to enlarge.

Primary Asset Labels include both a Chunk ID and Priority, just like Primary Asset Rules in the Asset Manager. However, you can apply those rules to multiple assets at a time in a Primary Asset Label. The Explicit Assets field lets you designate a list of specific assets, or you can designate an Asset Collection as belonging to this label. Alternatively, you can check Label Assets in My Directory, and the primary asset label will then affect all assets in the same folder in the content browser.

Packaging Chunks

Once you have defined your Chunk IDs, packaging your project will automatically create .pak files for each chunk. You can locate them in your project's Saved/StagedBuilds/[PlatformName]/[ProjectName]/Content/Paks folder.



Packaged .pak files are located in the StagedBuilds folder, under a subfolder for your platform and project, inside the Content/Paks directory.

The .pak files are generated based on the platform that you are packaging for, so they are not interchangeable between platforms. Once you have generated them, you can use them in your delivery system of choice.

Analyzing Asset-to-Chunk Assignments

UE4 provides several built-in tools to audit your Chunks. Using these tools, you can see which Assets are assigned to which Chunks, what source is giving them those assignments, and information about the size of chunked assets.

Asset Audit Window

To open the Asset Audit Window, open the Windows dropdown menu, expand Developer Tools, and choose Asset Audit.



Click image to enlarge.

The Asset Audit Window will display, but it will be blank.



The Asset Audit Window, as it appears when it is initially opened. Click image to enlarge.

Clicking the Add Chunks button will fill in the window with a summary of all Chunks that exist in the current project.



In ShooterGame, Assets are distributed between three Chunks. Click image to enlarge.

To inspect an individual Chunk, right-click it and choose either the Size Map or the Reference Viewer.



Click image to enlarge.

Size Map

The Size Map provides a visual representation of the type and size of each Asset contained within a Chunk. Assets are displayed as colored boxes with their icon or thumbnail in the box, and are scaled to represent the size of the Asset. Boxes nested within other boxes represent a parent-child reference relationship. For example, a texture that is referenced by a Material would appear inside the Material's box, because loading the Material implicitly involves loading the texture.

In ShooterGame, Chunk 0 contains the Assets needed to display the game's menu and get into a match, while Chunks 1 and 2 are used for the game's playable Maps. As a result, Chunk 0 is smaller than the other Chunks, and also has a wider variety of Asset types. Here we can see the Asset breakdown and total shipping disk size for Chunks 0 and 1:



Chunk 0 of ShooterGame contains many independent Assets, but is relatively small. Click image to enlarge.



Chunk 1 (pictured) and Chunk 2 contain the individual Maps in which the game takes place, so they feature a single, large group of connected Assets. Click image to enlarge.

The Size Map also supports visualization of the memory usage (in the Editor) of the Assets it contains. In-Editor memory size can be substantially different from a shipped product's disk space usage for the same group of Assets.



Chunk 0 displayed in Memory Size mode. This mode scales box sizes based on the memory usage of the Assets in the Editor. Click image to enlarge.

Individual Assets can be examined or edited by right-clicking the Asset's box. You can use the mouse wheel to zoom in or out, or double-click an Asset to expand it so that it fills the window.



The context menu for the "loading screen" texture Asset. Click image to enlarge.

Reference Viewer

The Reference Viewer generates a graph which represents inter-Asset references as a network of connections between the Assets themselves. Chunks and individual Assets can be examined with this tool. In our ShooterGame example, examining Chunk 1 reveals only two directly connected Assets: The "Sanctuary" Map, and the Primary Asset Label associated with Chunk 1.



The Reference Viewer's graph of Assets directly referenced by Chunk 1 in ShooterGame. The sanctuary map asset's node has been right-clicked. Click image to enlarge.

Right-clicking a node in the Content Browser or Reference Viewer and choosing "Re-Center Graph" (or double-clicking the node in the Reference Viewer) will display that node's references. In the following image, we have recentered from Chunk 1 to the "Map:/Game/Maps/Sanctuary" node, revealing that the "Sanctuary" Map is referenced by two nodes (Chunk 1 and Chunk 1's Primary Asset Label) to its left, and references many child nodes to its right, such as the "M_FFA_Wall_01" Material:



Examination of ShooterGame's "Sanctuary" Map (part of Chunk 1) in the Reference Viewer. Click image to enlarge.

The graph shown above is not complete. It has been limited by the options set in the Reference Viewer. Limiting the scope of the graph can greatly reduce the time taken by the Engine in building it. For detailed information on those options, see the Reference Viewer page.

Crawling through references in this way, you can see exactly why a given Asset is associated with another Asset, or a Chunk. This can help to discover and remove unnecessary Asset references, or adjust your Chunking strategy to better fit your project's needs.

Generic UnrealGame App

In the Main toolbar of the Unreal Editor, there is a button labeled Platforms, with a drop-down menu.



In the drop-down menu, you will see a list of possible platforms you can launch the current Level on. Generally, you would not need Windows or Mac, as you can use the Play button for that without needing to cook your data. This page will primarily cover the information you need for launching on mobile platforms.

For Android, there will be multiple selections. See the Android Texture Formats page for more information.

If you have multiple devices for a particular platform, you can choose between them here. Clicking on the platform (and device), the Editor will start to cook the Level, install the data on the device, and run the Level on the device.

This method will only install the current Level on the device for fast iteration, and switching between Levels is unsupported with this method. If you want to have all of your Levels installed to the device at once, see the Packaging Projects documentation.

Generic UnrealGame App

If you are making a content-only project, the executable that runs for One-Click Deploy is actually the generic "UnrealGame" game (since it can be used with any content-only project). When it runs on a device, the icon that gets installed is just labeled as UnrealGame. However, when you package a game, the name of your project is used in the final packaged build. When you install the packaged build, the icon will have your name (as well as your icons if you updated the default icons).

Advanced Mode (UnrealFrontend)

There is an additional tool for performing advanced building, cooking, deploying, packaging, and launching options. It is called Unreal Frontend and is located in the following locations depending on your platform:

Platform

Location

PC

[ENGINE INSTALL LOCATION]\Engine\Binaries\Win64\UnrealFrontend.exe

Mac

[ENGINE INSTALL LOCATION]\Engine\Binaries\Mac\UnrealFrontend.app

This tool will let you only cook certain maps, change the commandline, or even run your game without precooking all the data (called "Cook on the Fly" mode). These are advanced tools - for more information, see Unreal Frontend.

Open Project Launcher

Adjustment of Custom Project

Project

Build

Cook

Package

Deploy

Use Unreal Editor for packaging a release version of you project for distribution. This page shows you how to package a release-versioned project on the example of packaging project for Windows Platform. Follow steps below to package your project via the Project Launcher. Packaging process details depend on the platform for which you make a project: a Windows game, shipping a mobile project, or targeting another platform. The steps you take with the finished packaged content will be different.

This is an example of packaging a 1.0 release of ThirdPersonGame, aimed at Windows 64-bit, localized in English.

Open Project Launcher

Click Platforms button of the Unreal Editor Toolbar and select Project Launcher.



Create a new Custom Launch Profile by clicking the Add button.



Set a name and description for your profile.

Adjustment of Custom Project

There are a number of settings for the release process.

Under Project section you can set the specific project, or use Any Project.



Set the Build configuration to Shipping.



Optionally, expand Advanced Settings if you need to build Unreal Automation Tool (UAT) as a part of the release.



Select By the Book as the cooking method in the dropdown menu.



Check the boxes for all platforms you would like to cook content for. In this example for Windows testing, WindowsNoEditor is selected.



Check the boxes for all cultures to cook localizations for.



Check the boxes for which maps to cook.



In Release/DLC/Patching Settings:

Check the Create a release version of the game for distribution. checkbox.

Enter a version number for this release.



Expand Advanced Settings and make sure the following options are enabled, as well as any others you need for your specific project's distribution method:

Compress content.

Save packages without versions.

Store all content in a single file (UnrealPak).



Also under Advanced Settings, set the Cooker build configuration to Shipping.



Set the build to Package & store locally.



Set the Deploy to Do not Deploy.



Once you have set all the above settings, navigate back to the main profile window using the Back button in the top right corner.



Click on the launch icon next to your Release profile.



The project launcher will go through the building, cooking, and packaging process. This may take some time depending on the complexity of your project.



Once the operation is complete, close the window or click on Done. You can test the patch now with the steps below.



Save the asset registry and pak file from [ProjectName]\Releases[ReleaseVersion][Platform]. In this example, this is ThirdPersonGame\Releases\1.0\WindowsNoEditor.

The asset registry and pak file will be needed for any future patches or DLC to check against.

On Windows, you can test running the project from [ProjectName]\Saved\StagedBuilds\WindowsNoEditor.

While Steam will allow you to upload full packages of your game and do the updating process for you, using release versions as outlined here is still the recommended practice when distributing through Steam. This will make the process smoother if you decide to add additional supported platforms or distribution methods later on.

Releasing Your Project

Build Operations: Cook, Package, Deploy, and Run

Project Launcher interface

Custom Launch Profiles

Name and Description

Project

Build

Cook

Package

Archive

Deploy

Launch

The Project Launcher is used to cook and deploy builds of your projects to specified platforms for testing, debugging, and releasing your project. The following reference page breaks down the elements that make up the Project Launcher and the settings you can use when creating your own Custom Launch Profiles for deploying your content to different platforms.



Project Launcher interface

To open the Project Launcher click Platform and select Project Launcher.



The Project Launcher interface can be broken up into two main areas:



Default Launch Profiles

Custom Launch Profiles

From the Default Launch Profiles window, you can see the available platforms and select from the devices that you want to deploy builds to. At the top of this window, you can specify a Project (if it's different than the current one you have opened) and a toggle for Advanced settings for these default launch profiles.

When you click the Advanced toggle button, you'll get additional options next to the default launch profiles that enables you to select a Build Configuration and a Cook method.



In the Custom Launch Profiles window, you can create your own profiles that enable you to specify many more options for how content is built and deployed, which is detailed more in the Custom Launch Profiles section.

Custom Launch Profiles

From the Project Launcher, you can create a Custom Launch Profile that can be used with all platforms or even specific ones, like the Nintendo Switch. These profiles enable you to build your content in specific ways by setting how it is cooked, packaged, and even deployed using the available build operations.

To add your own Custom Launch Profile, click the +Add button in the Custom Launch Profiles section.



After doing so, your Custom Launcher Profile will immediately open. Be sure to give it a name so that you can identify it later on.



Name and Description

In the header bar, you'll find the Name and Description that you can apply to this custom profile. To edit these, double-click on either section's text to start editing them.



Project

In the Project section, you can specify what project you want this profile to be associated with or if it can be used with any project. By default Any Project is set, but it can be set to a specific one. This can be useful when you are developing your project for multiple platforms, and those platforms require particular ways to deploy, test, debug, and even release them.



Build

The Build section enables you to specify the type of configuration you want to build and deploy against depending on your project's progression in development and how you need to test, debug, or release your project.



Setting

Description

Build Configuration

Choose from the available configurations you want to build and test with your project.



Configuration

Description

DebugGame

This configuration builds the Engine as optimized but leaves the game code debuggable. It is ideal only for debugging game modules.

Development

This configuration is equivalent to a release build. Unreal Editor uses the Development configuration by default. When your project is compiled using this configuration, it enables you to see code changes made to your project reflected in the Editor.

Shipping

This is the configuration for optimal performance and shipping your game. This configuration strips out console commands, stats, and profiling tools. This configuration should be used when you are ready to release your game.



Build UAT

When enabled, the Unreal Automation Tool will be built as part of the build.

Additional Command Line Parameters

Parameters specified here will be passed to the app on launch

Cook

In the Cook section, there are two ways you can cook content for your projects: By the book and On the fly.

The Cook By the book option enables you to specify which content should be cooked and cooks everything in advance before launching the game.



Setting

Description

Cooked Platform

Select from the available target platforms listed that you would like this custom launch profile to be able to cook content for.

Cooked Cultures

Select from the available localization cultures you would like this content to be cooked for.

Cooked Maps

Select from the available maps in your title that you would like to cook.



Release/DLC/Patching Settings



Create a release version of the game for distribution

Enables you to create a release version of your title that will be used for distribution.

Name of the new release to create

Give your release a new name that will be used during the cook.

Release version this is based on

This is the release version to base the next release / DLC / patch on.

Generate Patch

If enabled, content will be diffed against source content and only changed files will be included in the new pak file.

Build DLC

If enabled, DLC will be built without the content released with the original game.

Name of the DLC to build

Give a name to the DLC that is going to be built.

Include Engine Content

If enabled, DLC will include Engine content which was not included in the original release. If it is not checked, an error will be produced when accessing content from the Engine directory.



Advanced Settings



Iterative Cooking: Only cook content modified from previous cook

If enabled, only modified content will be cooked resulting in much faster cooking times. It is recommended to enable this option whenever possible.

Stage base release pak files

If enabled, unchanged pak files present in the base release version will be staged.

Compress Content

If enabled, content generated will be compressed. These will be smaller but potentially take longer to load as it decompresses.

Add a new patch tier

If enabled, a new numbered pak file will be generated with the patch content.

Save Packages Without Versions

If enabled, the version is assumed to be the current at load. This is potentially dangerous but results in smaller patch sizes.

Store all content in a single file (UnrealPak)

If enabled, the content will be deployed as a single UnrealPak file instead of many separate files.

Encrypt INI files (only with Use Pak File enabled)

If enabled, ini files stored inside the UnrealPak file will be encrypted.

Generate Chunks

If enabled, the content will be deployed as multiple UnrealPak files instead of many separate files.

Don't include Editor content in the build

If enabled, the cooker will skip Editor content and not include it in the build.

HTTP Chunk Install Data Path

Create HTTP Chunk Install Data

If enabled, the content will be split into multiple Pak files and stored as data that can be downloaded.

HTTP Chunk Install Data Path

Specify the file path for the Chunk Install Data.

HTTP Chunk Install Release Name

Name of this version of the HTTP Chunk Install Data.

Cooker Build Configuration

Sets the build configuration to use for the cooker commandlet.

Additional Cooker Options

Additional cooker command line parameters can be specified here.

The Cook On the fly option enables content to be cooked at runtime as needed before it is being sent to the device.



Setting

Description

Only Cook Modified Content

If enabled, only modified content will be cooked, resulting in much faster cooking times. It is recommended to use this option whenever possible.

Additional Cooker Options

Additional cooker command line parameters can be specified here.

Package

In the Package section, you can choose how the build is packaged and whether it should be stored locally or in a shared repository that can be accessed.



Setting

Description

Package Method



Package & Store Locally



Local Directory Path

Is this build for distribution to the public

If checked the build will be marked as for release to the public (distribution)

Include an installer for prerequisitea of packaged games

If checked the build will include the prerequisites installer on platforms that support it.

Use container files for optimized loading (I/O Store)

If checked the build will use container files for optimized loading (I/O Store).

Make a binary config file for faster runtime startup times

Bakes the config (.ini, with plugins) data into a binary file, along with optional custom data.

Optional I/O Store Reference Block Database:

The path to a global UTOC in a derictory of previously released iostore containers.

The path to a crypto JSON to decrypt the reference block containers, if indeed.



Package & Store In Repository



Repository Path

Archive

In the Archive section, you can specify whether or not to archive the build and the directory path if it is going to be archived for later reference.



Deploy

In the Deploy section, you'll need to decide how you would like to deploy your current build to a device; using a File server, Copy to device, or Copy repository.

Use the following selections to determine which deployment method to use:



File Server will cook and deploy the content at runtime as it is needed to the device.

Copy to Device will copy the entire cooked build to the device.

Do Not Deploy will not deploy the build to any device once the cook and package complete.

Copy Repository will copy a build from a specified file location to deploy to any device.

The available settings you can use when selecting File Server.



Setting

Description

Default Deploy Platform

Set the default target platform(s) you want to deploy content.



Advanced Settings



Hide the file server's console window

If enabled, the file server's console window will be hidden from your desktop.

Streaming server (experimental)

If enabled, the file server will use an experimental implementation that can serve multiple files simultaneously.

The available settings you can use when selecting Copy to Device.



Setting

Description

Default Deploy Platform

Set the default target platform(s) you want to deploy content.



Advanced Settings



Only deploy modified content

If enabled, only modified content will be deployed, resulting in much faster deployment times. It is recommended to use this option whenever possible.

The available settings you can use when selecting Copy Repository.



Setting

Description

Repository Path

Set the file path to the repository that you want to copy to device.

Default Deploy Platform

Set the default target platform(s) you want to deploy content.

Launch



Setting

Description

Launch As

Select how you would like the launch this instance of your build.



Standalone Client

Launches this instance as a standalone game client.

Listen Server

Launches this instances a game client that can accept connections from other clients.

Dedicated Server

Launches this instance as a dedicated game server.

Unreal Editor

Launches this instance as an Unreal Editor.



Initial Culture

Select the culture that you're initially targeting to use when launching the build.

Initial Map

Select the initial map you want the project to use when launching the build.

Additional Command Line Parameters

Enter any necessary command line parameters you want to use when launching the build.

Synchronize Screen Refresh Rate (VSync)

Enable this for the build to attempt to run the project at the same refresh rate as the monitor it's being run on.



Features

Getting Started

Interface

Launcher

Build

Cook

Device Browser

Session Browser

Session Console

Automation

Unreal Remote Agent

UnrealFrontend (UFE) is a tool intended to simplify and speed up daily video game development and testing tasks, such as preparing game builds, deploying them to a device, and launching them. UFE is designed to be the central interface for all game deployment, profiling, and testing tasks.

Features

UFE provides the following features:

Feature

Description

Launcher

Build, cook, deploy and launch your game. UFE allows you to simultaneously deploy to multiple target devices running different target platforms, either locally connected or anywhere on the network. You will be able to launch multiple instances per device (on supporting platforms) and configure different roles per instance in order to drastically speed up your workflow for testing your single or multiplayer cross-platform games.

Sessions

Remotely monitor and interact with any of your currently active game sessions running on the network. The new Session Browser will allow you to locate instances of your game currently running on the network. The Session Console shows you a real-time feed of each game instance's output log, and it allows you to remotely execute console commands on one or more target devices. It will soon be possible to share your active sessions remotely with other developers or artists in order to get a second opinion without them having to come to your desk.

Automation

Automatically test code and content and verify their integrity. This is a new feature not available in previous versions of the engine. You will be able to write unit/feature/stress tests for your game's custom C++ classes and content, and you can create automated tests for verifying common workflows, such as verifying that all maps and packages are loading without errors. We are also working on integrating automation tests into our build system, so that it will be possible to run them automatically and detect potential problems as part of the continuous integration process.

Profiling

Remotely analyze the performance of your game and locate bottlenecks. If you are familiar with our previous suite of profiling tools in UE3, you will be excited to hear that we are working on integrating all these disparate tools into a single user experience inside UFE.

Device Management

Manage your devkits, mobile devices and other test computers. Simple device discovery was already available in previous versions of UFE, but in UE4 it will be a lot more powerful. We are dropping the restriction that a target device has to be connected to the local PC, either physically or through the device's SDK. You will be able to detect locally connected and networked devices and share them with others. Windows and Mac computers are now also able to act as target devices for deployment, launching, and automation.

Getting Started

Unreal Frontend is available as both a tab for Unreal Editor and a standalone application. While their functionality is equivalent, the lightweight standalone application is likely the preferred tool for QA personnel and programmers. Artists may prefer the in-editor version, because they already have Unreal Editor opened most of the day. The Unreal Editor tab can be accessed from the Window menu:



The standalone application is located in the /Engine/Binaries/Win64 and /Engine/Binaries/Mac directories:



Please note that if you are using a source build of the engine, you will need to build UnrealFrontend from Visual Studio or XCode first.

Interface

The UnrealFrontend user interface is made up of the following components:



Device Browser

Launcher

Session Browser

Automation

Session Console

Launcher

The Launcher tab allows you to build, cook, deploy, and launch your game. There will eventually be many different ways to accomplish this, but as of this writing, only the following settings are supported:

Build: Create new build.

Cook: On the fly (Windows and selected consoles).

Deploy: File server (local Windows and selected consoles), Deploy to device (local Windows).

Launch: Using default role (i.e. single instance per device + same settings for all).

All settings in the Launcher are combined into profiles. This allows you to maintain different groups of settings in parallel, which is particularly handy for QA personnel who need to run many different tests a day. When you open the Launcher for the first time, no profiles will be present, and you will have to create a new one:



Once a profile is created, a number of settings categories will be shown:

Build



Setting

Description

Game

Specifies the game project to build.

Build Configuration

Sets the configuration to use when building the game.

Cook



Setting

Description

Cooked Platforms

Specifies which platforms the game content is to be cooked for.

Uncooked content is currently unsupported on any platform.



Cooked Languages

Specifies the language the game content is to be cooked for.

Cooked Maps

Specifies the maps to cook.

Only cook modified content

If enabled, the cooker will ignore any content that has not been modified.

Save packages without versions

Cooker Build Configuration

Sets the configuration to determine which binary to use for cooking.

Additional Cooker Options

Device Browser

The Device Browser is currently quite limited in functionally, but it will eventually allow for managing and sharing all target devices on the network (including the transfer of log files). It automatically detects devices that are available locally and also provides an interface for manually adding devices that cannot be discovered.

There is currently no true concept of device ownership. To what extent we will implement it (including the locking of devices that are shared amongst multiple developers) is still TBD.



Note: Currently, we only support devices that can be discovered locally. At the time of this writing, this includes the local Windows PC (both Win32 and Win64 platforms) and selected console devices on the network.

Session Browser

When launching a game on one or more devices, the Launcher will create a new session that consists of every game instance that is running, and which can be tracked in the Session Browser. It plays a very central role in UFE, because the currently selected session (or session instances) determines the functionality of other UFE tabs, such as the Session Console tab, the Automation tab and the upcoming Profiler.



Like the Device Browser, the Session Browser is still limited in functionally. It currently consists of a split list

The top list shows all discovered sessions and the bottom list shows the game instances that are part of a selected session. A session does not necessarily consist of only games, but may also include auxiliary tools, such as content cookers and file servers.

When running UFE from within the Unreal Editor, there is currently always an Unnamed Session being shown (which represents the Unreal Editor instance itself).

Session Console

The Session Console is the central hub for gathering the log output from all game instances that are currently selected in the Session Browser. Which logs are being displayed depends on the currently selected instances in the Session Browser. The list of log messages (4a) can then be filtered using a search string or category and verbosity filters (4b). It is possible to send console commands to selected game instances (4c). Commands sent to multiple instances will be executed by each instance. Last but not least, it is also possible to export all or selected log messages to a file (4d).



As of this writing, only the log since the discovery of a session will be available. We will change this soon to allow for retrieving log that was generated prior to running UFE.

Automation

The Automation panel provides access to automated testing functionality. Each instance in a session (including the local Unreal Editor instance when running UFE in-editor) is able to perform automated unit/feature/stress tests for code and content verification at any given time.



Control Panel

Filter Panel

Test list

Results

After selecting one or more instances in the Session Browser, the Test List will display all tests that are available for those instances. You can then select which tests you actually want to run by selecting the checkbox of one or more tests, or you can filter the list of tests using the Filter Panel. To execute the selected tests, press the start button in the Control Panel. The results of the tests (including error messages) are then aggregated in the Results View.

It is possible to run automated tests on multiple instances in parallel (by selecting multiple instances). We are currently working on the implementation of test groups that will allow for different levels of parallelization (various types of load balancing, redundant testing etc.). Please check the documentation for the Automation system on details about how to create new tests.

Unreal Remote Agent

Unreal Remote Agent (URA) is a standalone program that runs in the system tray of remote PCs (and eventually Macs) to make those PCs and console devices connected to them available over the network. URA, previously required to deploy and launch games, is currently not supported and in the process of being upgraded.

Unreal Engine supports building and publishing games to the Valve Steam Deck. This section contains guides for setting up your Steam Deck development environment, how to use Steam Deck features, and how to package and publish your game for the Steam Deck.



Get started with Steam Deck development in Unreal Engine

Initial Steam Deck Setup

Initial Pairing Setup

Add a Steam Deck Device to Unreal Editor

This quick-start guide shows you how to build and run an Unreal Engine project on the Valve Steam Deck.

After completing this guide you will be able to:

Pair a Steam Deck to your development system.

Add a Steam Deck device to Unreal Engine.

Run an Unreal Engine project on your Steam Deck.

Unreal Engine currently supports deploying to a Steam Deck from the Windows editor.

Requirements:

To build Unreal Engine projects for Steam deck you need:

A Steam Deck

The SteamOS Devkit client

Initial Steam Deck Setup

Before pairing your Steam Deck, ensure the system software is up to date by navigating to Steam > Settings > System > Software Updates on your Steam Deck.

Initial Pairing Setup

Before deploying your project, you need to pair your Steam Deck to your development machine.

Install the SteamOS Devkit Client and open it on your development machine.

Make sure your Steam Deck is connected to the same network as your development machine.

Once connected, on your Steam Deck go to Steam > System > Network Settings and make a note of your Steam Deck's IP Address.

On your Steam Deck, go to Settings > System and select Enable Development Mode** under the System Settings section.

On your Steam Deck, go to Settings > Developer and select Pair New Host under the Development Kit section to begin the pairing process.

In the SteamOS Devkit Client, under the Devkit tab, enter the IP of your Steam Deck in the Connect to Steam Deck by IP box, then click Connect.

On your Steam Deck, approve the pairing request from your PC to complete the pairing process.

Add a Steam Deck Device to Unreal Editor

After you have paired your device, you need to update an Engine.ini file to add your Steam Deck to Unreal Editor.

Open any Engine.ini file (for example, Engine/Config/BaseEngine.ini) in a text editor.

After opening the Engine.ini file, add a line to the file for each Steam Deck you want to connect, following the format below:

Engine.ini example

IpAddr (Required) - The IP Address of your Steam Deck

Name (Optional) - The name you want Unreal Engine to display for this Steam Deck

Username (Required) - The username must always be ‘deck' for Steam Decks connected to Unreal Engine.

After you have edited your Engine.ini file, restart Unreal Editor. You can then find your Steam Deck under the Platforms context menu



To launch your Unreal Engine project on your Steam Deck, go to the Platforms context menu then find and select your Steam Deck. Unreal Engine then launches your project on your Steam Deck.

Setup

Layout

Platforms

The AutoSDK system provides a mechanism for distributing target platform SDKs and configuring them for use by the engine on demand. It was designed for build machines to serve multiple branches with different SDK requirements without needing to manually manage installed packages, but may also be used by developers that do not require a full SDK install. Typically, only a minimal toolset is available by default (for example, a compiler or deployment software).

UnrealBuildTool, AutomationTool, and the Unreal Editor are all designed to work seamlessly with AutoSDK, and the switch between SDKs is handled by UnrealBuildTool (UBT), which is invoked by the other tools.

For any engine verison, UnrealBuildTool has a preferred SDK version that it will attempt to use. These versions are typically defined by classes derived from UEBuildPlatform in the UBT source code.

Setup

Epic is not able to distribute SDKs for legal reasons, so this directory tree serves a template showing how to structure it. We recommend you start with an empty AutoSDK folder and copy files from here as you add a particular SDK version.

Do not configure the AutoSDK system to use this folder. It is just a template, and the system will not work without adding additional files.

So that multiple branches on a single machine can share it, the AutoSDK folder should be submitted to source control separately to the game or engine code.

Any developer wishing to use AutoSDK can sync it and set the UE_SDKS_ROOT environment variable to point to the path on their local machine for UBT, which contains it.

Layout

The AutoSDK directory structure is loosely defined and generally left to the discretion of each platform, but the directory structure follows this general pattern.

Directory Structure

Definition

/HostPlatform/

Host platform that the SDKs can be used on.

/HostPlatform/TargetPlatform/

Directory containing the "TargetPlatform" SDKs for "HostPlatform" (for example, "/HostWin64/Android/").

/HostPlatform/TargetPlatform/1.0/

Directory containing the "TargetPlatform" 1.0 SDK for "HostPlatform".

/HostPlatform/TargetPlatform/1.0/Setup.bat

Optional batch file that is run when setting up this SDK. "setup.sh" on Mac/Linux.

/HostPlatform/TargetPlatform/1.0/Unsetup.bat

Optional batch file that is run when removing this SDK. "unsetup.sh" on Mac/Linux.

When run, Setup.bat will output a text file to the same directory called OutputEnvVars.txt, containing a list of environment variables to set in the form of NAME=VALUE as well as special directives to modify the PATH environment variable, such as ADDPATH=Foo and STRIPPATH=Foo.

Setup scripts written by Epic for supported SDK versions are included under this directory.

Platforms

More information about adding SDKs for each platform is given by README.md files in HostPlatform/TargetPlatform subfolders.

iOS

Android

The best way to set device-specific configurations is to create a custom Config/DefaultDeviceProfiles.ini inside your project. You can set many properties in a device profile, such as a texture pool size; it is the recommended way of handling scalability on different mobile devices or in scalability settings buckets on PC/Mac.

For more on setting up configuration files, see the main Configuration Files documentation.

iOS

Device profiles can be used to set your game's resolution for iOS devices. The r.MobileContentScaleFactor property is relative to the 'nominal iOS resolution' for a device. For example, a Retina iPad has actual resolution 2048x1536, but nominal resolution 1024x768, so you would use 2.0 to get native resolution there. You can also use fractional values like 1.5 if you want more resolution but not the full performance hit from running at native resolution.

The iOS device profiles can be seen in BaseDeviceProfiles in Engine/Config. These categories are set through a plugin system, with the default plugin being iOSDeviceProfileSelector. The iOS device categories are simply the name of the device.

Android

Android has hierarchical device profile categories (see BaseDeviceProfiles.ini in Engine/Config for examples). These categories are set through a plugin system, with the default plugin being AndroidDeviceProfileSelector.

Memory Buckets

You can specify how different Platforms with different memory capabilities will run your Unreal Engine 4 (UE4) project, and what options they will use by adding Memory Buckets. To add this capability you will first need to open up your projects Engine.ini file (use Android/AndroidEngine.ini, IOS/IOSEngine.ini, or any of the PlatformNameEngine.ini files to set on a per platform basis) in a text editing program. Several defaults are already set up for your convenience. For example, the following is already entered in AndroidEngine.ini:

You can specify which Memory Bucket should be associated with which device setting in DeviceProfiles.ini. For example, to adjust how much memory the Texture Streaming Pool should use, you would add the following to your DeviceProfiles.ini file:

Where "Mobile" is replaced with the name of the specific platform you're adding the Device Profile for. You can also use Memory Buckets to specify the rendering settings that will be used. In the following example, the TextureLODGroup for Textures that use the World setting have been setup so that if UE4 detects a device using Tiniest Memory Bucket it will adjust the MaxLODSize from 1024 to 256, reducing the needed memory for textures that have their LOD group set to World.

Low-latency frame syncing mode modifies the way thread syncing is performed between the game, rendering and RHI threads, and the GPU, to greatly reduce and control input latency. In previous engine releases, the game thread synced with the rendering thread at the end of the frame. When the r.OneFrameThreadLag CVar is enabled (as the default), this syncing ensures that the game thread does not get more than one whole frame ahead of the rendering thread. Platform-specific graphics drivers generally stall the thread that calls Present() to prevent the game running faster than the frames are presenting. The driver allows the swap chain to be filled, and then stalls the calling thread when there is no more room. Before UE4's parallel rendering was introduced, this syncing behavior was correct, as the game thread would wait on the rendering thread, which would then be stalled by the graphics driver/OS. However, with the introduction of parallel rendering, the RHI thread is now the thread that calls Present(), so it is that thread which is throttled by the driver. The game thread continues to sync with only the rendering thread, which allows both these threads to get much further ahead of the GPU and flipped frames than it used to. In a 30 Hz title with rhi.SyncInterval set to 2, this can lead to a worst case input latency of up to 130 ms.

To achieve the same input latency as pre-parallel rendering, it is necessary to synchronize the game thread to the RHI thread instead. In addition, when vsyncing is enabled, the swap chain provides a regular, predictable syncing interval, meaning the point in time when the swap chain flips the front/back buffers. We can accurately control input latency by syncing the start of the game thread frame to an arbitrary point relative to the vsync. By carefully choosing this point, we can trade input latency for performance, or the reverse.

The new low-latency frame-syncing mode adds a new CVar called r.GTSyncType (game thread sync thread). This CVar drives how the frame syncing mechanism work using the following values:

Value

Description

0

Game thread syncs with rendering thread (old behaviour, and default).

1

Game thread syncs to the RHI thread (equivalent to UE4 before parallel rendering)

2

Game thread syncs with the swap chain present +/- an offset in milliseconds.

To achieve mode 2 syncing, the engine tracks presented frames with an index that is passed to the driver when Present() is called. This index is retrieved from platform frame flip statistics, which indicates the exact time when each frame flipped. The engine uses these values to predict when the next frame flip is due, then kicks off the next game thread frame based on this time.

The CVar rhi.SyncSlackMS drives the offset we apply to the next predicted vsync time. Decreasing this value will reduce input latency at the cost of shortening the engine pipeline, making it more likely for hitches to cause dropped frames. Likewise, increasing this value will lengthen the engine pipeline, giving the title more resilience to hitches at the cost of increased input latency.

Generally, titles using this new frame-syncing system should aim to reduce rhi.SyncSlackMS as much as possible whilst maintaining acceptable frame rates.

Take as an example, a 30 Hz title with the following CVar settings:

rhi.SyncInterval 2

r.GTSyncType 2

r.OneFrameThreadLag 1

r.Vsync 1

rhi.SyncSlackMS 0

This would have a best case input latency of ~66ms (two 30 Hz frames). Increasing rhi.SyncSlackMS to 10 would result in a ~76ms best-case input latency.

r.GTSyncType 2 works for 60 Hz titles too (i.e rhi.SyncInterval is set to 1), but the benefit of this will be less noticeable as the input latency is halved to start with, given the doubled frame rate vs 30hz.

On unsupported platforms, r.GTSyncType 2 will fall back to mode 1 instead.

What are TV Safe Zones

Difference between Title Safe Zones & Action Safe Zones

TV Safe Zone Commands

Activating the Title Safe Zone Debug Preview

Adjusting the Size of the Safe & Action Zones

Adjusting the Alpha of the Safe & Action Zone Overlay

TV Safe Zone Troubleshooting

During working on UI for Unreal Engine (UE) projects, it's important to avoid placing UI elements (text or widgets) too close to the edges of the screen. If you place UI elements near edge of the screen, it can cause them to be distorted depends on device. Use TV Safe Zone Debugging tool for ensure that UI items are located as you need. Get familiar with this document for understanding how to use TV Safe Zone Debugging tool in UE projects.

What are TV Safe Zones

A TV Safe Zone or Safe Area is the term used in television production to describe the area of the television picture that ensures the content can be cleanly viewed by a majority of TV viewers. Generally speaking, the most important content for a TV show will be placed in this area to ensure that it will not be distorted when viewed on a wide range of TV sets.

You can read more about TV Safe Zones and Safe Areas on the following Wikipedia page: TV Safe area.

Difference between Title Safe Zones & Action Safe Zones

UE has two different types of TV Safe Zones: the Title Safe Zone and the Action Safe Zone.

Title Safe Zone - The Title Safe Zone is for UI or Text elements, to make sure they are not cut off or distorted when viewed.

Action Safe Zone - The Action Safe Zone is used to allow characters or enemies to wander partially offscreen.

The area outside of the Action Safe zone will probably be clipped on displays with overscan, while areas between the Action Safe zone and Title Safe zone may be partially clipped. It's OK to have some action (such as other characters or enemies) occur in that region. The Action Safe zone is the same size as the Title Safe zone on many platforms.

TV Safe Zone Commands

Following section provides commands you can use with the TV Safe Zone. Also section describes two different ways you can enable and use the TV Safe Zone Debugging tool in your UE project.

Use following TV Safe Zone commands via the UE console.

Command Name

Value

Description

r.DebugSafeZone.Mode

0

Disables all overlays.

r.DebugSafeZone.Mode

1

Enables Title safe zone.

r.DebugSafeZone.Mode

2

Enables Action safe zone.

r.DebugSafeZone.OverlayAlpha

0 to 1

Controls how opaque the debug visualization overlay is (Default is 0.3)

r.DebugSafeZone.TitleRatio

0 to 1

Controls the action safe zone margins returned in FDisplayMetrics (Default is 0.9).

r.DebugActionZone.ActionRatio

0 to 1

Controls the action safe zone margins returned in FDisplayMetrics (Default is 0.9).

You can also place the TV Safe Zone commands in your projects DefaultEngine.ini file under the [SystemSettings] section.

Activating the Title Safe Zone Debug Preview

To correctly display the ratio of the safe areas, you must run the project in either Windowed Fullscreen or Fullscreen mode. If you don't, the safe zone will not display correctly, or will display a smaller size than expected.

Following section shows how to activate the Safe Zones in the Debug preview.

From the Main Toolbar, go to the Play buttons panel and click to open drop-down menu. In the Play Modes menu, select New Editor Window (PIE). This launches the game in a new window.



Enlarge window with launched project for fullscreen view.



Press the TILDE ( ~ ) key to open the Unreal Console. Do the following:

Type r.DebugSafeZone.TitleRatio 0.9, and press the ENTER key to apply it.

Type r.DebugSafeZone.OverlayAlpha 0.4, and press the ENTER key to apply it.

Type r.DebugSafeZone.Mode 1, and press the ENTER key to apply it.



You should now see a slightly transparent red border placed around the entire play window, as seen in the image below.



Click image for full view.

Adjusting the Size of the Safe & Action Zones

You can adjust the size of either the Safe or Action Zones by entering the following commands into the Unreal Console.

Command Name

Value

Description

r.DebugSafeZone.TitleRatio

0 to 1 Range

Controls the Safe Zone margins returned in FDisplayMetrics (Default is 0.9).

r.DebugActionZone.ActionRatio

0 to 1 Range

Controls the Action Safe Zone margins returned in FDisplayMetrics (Default is 0.9).

It is not possible to have both the Safe and Action Zone active at the same time. To view another zone, you will have to disable the one you are currently viewing and then enable the one you want to view.

In the images below, the command r.DebugActionZone.ActionRatio was used to decrease to size of the Action Zone from 0.99 all the way down to 0.1.

Dragging the slider will show what happens when adjusting the size of the Safe Zone.



Adjusting the Alpha of the Safe & Action Zone Overlay

You can increase or decrease the opacity of the Safe & Action Zones by entering the following command into the Unreal console.

Command Name

Value

Description

r.DebugSafeZone.OverlayAlpha

0 to 1

Controls the opacity of the Safe & Action Zones overlays(Default is 0.3).

In the images below you can see what happens to the opacity of the Safe & Action Zone overlays when the value of r.DebugSafeZone.OverlayAlpha was set from a value of 1.0 to a value of 0.1.

Dragging the slider will show what happens when adjusting the opacity of the Overlay Alpha.



TV Safe Zone Troubleshooting

In the following section we will go over some pieces of information you need to be aware of to ensure that you are using the TV Safe Zone tool correctly.

Right now the safe areas are defined in terms of the full screen size (the API wasn't really designed for non-consoles) rather than returning the ratios directly to let them be used in windowed mode. This could be changed in the future, but for now you need to be running in windowed fullscreen or fullscreen for the ratio to be correct.

The UI isn't currently expected to be able to handle this changing at runtime, so if you change the TitleRatio / ActionRatio via the console while running you'll probably need to switch game modes to see the changes (e.g., go from front-end to in-game or vis-versa, or 'open FrontEndScene' again).

When using this tool on the PS4, you only need the first command, r.DebugSafeZone.Mode 1 as the Safe Zone values are driven by the system setting you can pick in the PS4 OS menus.

1. Project Setup

2. Overview of Project Defaults

Project Template: Top Down

C++ Project vs. Blueprint-Only

Target Platform: Mobile

Quality Preset: Scalable

3. Setting Up Your Project for Android

4. Setting Up Your Project for iOS

5. Testing Your Project On-Device

6. Final Result

This guide provides details about how to set up a new Unreal Engine game project for Mobile platforms. While Mobile devices have a wide range of specifications and some may support more robust rendering features, the settings detailed here will work with the broadest range of new projects.

1. Project Setup



Click image for full size.

Open Unreal Editor. When the Unreal Project Browser appears, click Games.

Configure your project as follows:

Project Template: Top Down

Target Platform: Mobile

Quality Preset: Scalable

Project Name: MobileTestGame

You can create a project that uses either Blueprint or C++.

Click Create to create the project and open it in Unreal Editor.

2. Overview of Project Defaults

This section provides details on the project defaults from the previous section and why these are recommended for new Mobile projects.

Project Template: Top Down

While all game templates are equipped for Mobile user interfaces, the point-and-click interface for the top-down game is ideally suited for touchscreen use. You can just as easily use the third-person template.

C++ Project vs. Blueprint-Only

Blueprint-only projects can publish to iOS and Android, but there are many features for configuring these platforms that are only available in C++.

You can build and test iOS projects on an iOS device with Blueprint-only projects, even from a Windows machine. However, iOS applications require Xcode to sign and provision a project for shipping on the App Store, so you will need a Mac with Xcode to ship your game eventually.

Android projects benefit from additional debugging options and tools when using a C++ project.

Target Platform: Mobile

Selecting Mobile as your target hardware will disable several features that are either not supported by Mobile devices at all, not commonly supported, or that are too resource-intensive for the lower-end Mobile devices that Unreal Engine supports.

Engine – Rendering

Bloom is disabled.

Separate Translucency is disabled.

Motion Blur is disabled.

Ambient Occlusion is disabled.

Anti-Aliasing Method is set to None.

Project – Maps and Modes

Use Splitscreen is disabled.

Slate

Explicit Canvas Child ZOrder is enabled.

Quality Preset: Scalable

The Scalable setting provides a minimal rendering feature set that disables several post-processes and favors performance over fidelity.

Engine – Rendering

Motion Blur is disabled.

Auto Exposure is disabled.

Anti-Aliasing Method is set to None.

You can change the target Platform and Quality Preset in Project Settings > Target Hardware. You can also change individual settings as necessary for your project, or you can override them on a per-device basis in your Device Profiles.

3. Setting Up Your Project for Android

For full details on setting up your project for Android, refer to the Android Quickstart Guide. The following is a summary of the required steps:

Install the latest version of Android Studio that is compatible with Unreal Engine. Refer to the Android Development Requirements page for information about the Android Studio, SDK, and NDK versions that are compatible with your current version of Unreal Engine. Refer to the Android SDK and NDK setup guide for information about the specific settings you need in Android Studio.

Run the SetupAndroid.bat, SetupAndroid.command, or SetupAndroid.sh script located in your engine's Extras > Android folder.

Open Project Settings > Android, locate the prompt for configuring your project for the Android platform, then click Configure Now. This will add the Build/Android folder to your project.

If you have not accepted the Android SDK license, click Accept SDK License in your Project Settings as well.

If you need to support the Google Play Store, scroll down to the Google Play Services section, locate the prompt for configuring for Google Play, then click Configure Now.

Add an Android Package Name with a reverse-domain style string taking the format com.(OrganizationName).(ProjectName). For this example project, the package name is com.YourCompany.MobileTestGame.

Set up your Android device in Developer Mode, then connect it to your local area network with wi-fi or connect it to your computer with a USB cable. See Setting Up Your Android Device for Development for more details.

4. Setting Up Your Project for iOS

To build a project for iOS, you need an Apple Developer Account and a MacOS computer with Xcode. For full details on setting up your project for iOS, refer to the iOS Quickstart Guide. The following is a summary of the required steps:

Connect Xcode with your Developer Account in Xcode > Preferences > Accounts.

Connect your iOS device to your Mac with a USB cable, then connect Xcode to your device in Window > Devices and Simulators.

Create an Identifier (App ID) for your app on your Apple Developer page. For the Bundle Identifier, provide a reverse-domain string taking the format com.(OrganizationName).(ProjectName). For this example project, the package name is com.YourCompany.MobileTestGame.

Register your device on the Apple Developer page.

Set Xcode to automatically manage code signing for your project. Make sure the Bundle Identifier uses the same name you used in your App ID.

Create a Provisioning Profile on the Apple Developer page using your Identifier, the Signing Certificate generated by Xcode, and your registered device. Download it to a convenient location, then click and drag it onto Xcode in your dock.

Open your project in Unreal Editor. In Project Settings > Platforms > iOS, set the Bundle Identifier to the same name you used in your App ID. After the editor discovers your Provisioning Profile and Signing Certificate, check the box for each of them.

5. Testing Your Project On-Device

To test your project on a device, connect it to your computer with a USB cable, then click the Platforms dropdown. Your device should appear in the Quick Launch section. If you click the device's name, Unreal Engine will build your project and deploy it to that device.

6. Final Result

After following the steps in this guide, your Mobile project is now ready to build, deploy, and test on both Android and iOS.

Mobile devices often introduce latency in an application's development pipeline due to the differences between the hardware and operating systems of desktop and mobile devices. Unreal Engine has specialized tools for mobile projects that can simplify the process of testing on mobile devices and improve your iteration time. The guides in this section describe the available tools and how you can take advantage of them.



Previewing your games inside the Unreal Engine is based on the selected Mobile Platforms.



UPL is a simple XML-based language for manipulating XML and returning strings.



Optimizing content and features for mobile games.

Level Editor

Designing Visuals, Rendering, and Graphics

General Mobile Development

Using the Mobile Previewer

Enabling Vulkan Mobile Preview

Platform Material Quality Settings

Preview Rendering Level Selections

Mobile Device Preview Options



1:Mobile / HTML5 - Open GL ES2, 2:Shader Model 4.0 - DX10/ OpenGL 3.3+, 3:Shader Model 5.0 - DX11/ OpenGL 4.3+.

In Unreal Engine (UE), you can use the Mobile Previewer to preview what your scene will look like on different mobile devices directly in the Viewport. When enabling the different preview rendering levels, the Materials in your scene will be recompiled to best emulate the look and feature set of the renderer preview that you selected. The Mobile Previewer enables you to switch back and forth between rendering levels seamlessly, without having to restart the Editor.

Using the Mobile Previewer

The Mobile Previewer enables you to quickly change between different renderers for your current UE session so that you can get an idea of what your game will look like on the device(s) that you're targeting while allowing you to work in the UE. To learn how to change to a different renderer preview, follow these steps:

While you do not need to restart the UE for the new preview rendering level to take effect, the first time you change to a preview rendering level the UE will need to time to recompile the shaders. Subsequent changes to previously used rendering levels should be nearly instantaneous.

From the Main Toolbar, select the Settings button to expand the listed menu items. Under the Scalability section, hover over the Preview Rendering Level to expose the different rendering levels options you can select from.



Hover the mouse over the section rendering level you'd like to preview and click to select it.You will see the Changing Preview Rendering Level progress bar pop-up. Wait for this to finish and recompile shaders.



The Preview Mode button appears next to the Sequencer button, the button shows the icon for the selected preview mode. Clicking it disables the Mobile Previewer.



Once a rendering level has been selected, the Materials in the viewport will automatically update to reflect the new rendering method using the Material Qualities enabled or disabled for that target platform. (See the Platform Material Quality Settings section of this page for more details on how to adjust these further.)

Android Vulkan Preview

Desktop Shader Model 5 (SM5) Preview

The Mobile Previewer is intended to match mobile devices as closely as possible but it may not always be indicative of what your project is going to look like on the target device. You should always make sure to fully test your project on your target device and only use the mobile previewer to see if your work is headed in the right direction.

Mobile Previewer in PIE

You can use the Mobile Preview ES3.1 (PIE) option to launch a standalone version of your UE mobile project that will use the same rendering path as if the project was run on a mobile device. This is a great way to preview the changes you are making without having to go through the entire cooking and deploying process. To launch your UE project in a Standalone game that uses the Mobile Preview, you will need to do the following:

From the Main Toolbar, click on the drop-down button of the Play panel to expose the Change Play Mode and Play Settings settings.



Select Mobile Preview ES3.1 (PIE) option and your project will then be launched in a new window that simulates what your project should look like on a mobile device.



Enabling Vulkan Mobile Preview

You can use the Vulkan Mobile Preview (PIE) option to launch a standalone version of your UE mobile project using the Vulkan render. This is a great way to preview the changes you are making without having to go through the entire cooking and deploying process. To launch your UE project in a Standalone game that uses the Vulkan Mobile Preview, you will need to do the following:

To enable the Vulkan Previewer you will need to first open up the Editor Preferences by going to the Main Toolbar and clicking on Edit and then select Editor Preferences.



In the Editor Preferences menu, locate the General heading and then click on the Experimental section.



Click for full image.

Locate the PIE section and then click on the Allow Vulkan Mobile Preview option to enable it.



Click for full image.

Close the Editor Preferences and then from the Main Toolbar, click on the drop-down button of the Play panel to expose the Change Play Mode and Play Settings settings.



Select the Vulkan Mobile Preview (PIE) option and your project will then be launched in a new window that simulates what your project should look like on a mobile device.



Platform Material Quality Settings

In the Project Settings under the Platforms category, you can select different platform Material Quality sections to enable or disable specific features for the target platform.



Click for full image.

For any of these changes to take effect, be sure to click the Update Preview Shaders button.



Preview Rendering Level Selections

When you select your Preview Rendering Level, you will have a few options to select from. Use the table below to select the option that best fits your target device.

Device Target

Description



High-End Mobile / Metal



Default High-End Mobile

This will emulate the default high-end mobile material quality settings without using any material quality overrides specified in the Project Settings.

Android GLES 3.1

Provides a preview emulation of supported Android OpenGL ES3.1 quality settings. The Material Quality settings can be set in the Project Settings > Android Material Quality - ES31 section.

Android Vulkan

Provides a preview emulation of supported Android Vulkan quality settings. The Material Quality settings can be set in the Project Settings > Android Material Quality - Vulkan section.

iOS Metal

Provides a preview emulation of supported iOS Metal quality settings. The Material Quality settings can be set in the Project Settings > iOS Material Quality - Metal section.



Mobile / HTML5



Default Mobile / HTML5

This will emulate the default mobile material quality settings without using any material quality overrides specified in the Project Settings.

Android

Provides a preview emulation of supported Android OpenGL ES2 quality settings. The Material Quality settings can be set in the Project Settings > Android Material Quality - ES2 section.

Some of the available Preview Rendering Levels are not visible until you've enabled them as a target platform via the Project Settings, namely, Android OpenGLES 3.1 and Android Vulkan. iOS Metal defaults to on, however, it will also be removed as an available preview option if its target platform is disabled.

Mobile Device Preview Options

Due to the wide range of mobile phone bezel designs, it can be challenging to make sure that parts of your UI are not obscured by the mobile device's bevel. To help make sure your UI is not obscured by the device, you can use the Device Launch option to overlay different mobile phone bezel designs. To use this in your UE project, all you need to do is the following.

First, open up your Editor Preferences by going to the Main Toolbar and clicking on Edit and then select Editor Preferences.



In the Editor Preferences menu, locate the General heading and then click on the Experimental section.



Click for full image.

Locate the PIE section and then click on the Enable mobile PIE with preview device launch options to enable the bezel overlays. Close the Editor Preferences menu and restart UE for applying this settings.



Click for full image.

From the Main Toolbar, click on the drop-down button of the Play panel to expose the Change Play Mode and Play Settings settings.



From the displayed menu, go to Mobile Preview (PIE) > Android and then select the device you want to test against from the list.



Click for full image.

Now click the Launch button to launch your project. When your project loads it will be using the device preview like in the following image.



Enable Tracing

Variable Types

Variable Manipulation

Writing Messages

Conditional Execution

Loops

Inserting Text

Search and Replace

XML Manipulation

Copying of Files

Removing FIles

Packaging or Deploying

Supported Nodes

Unreal Plugin Language (UPL) is a simple XML-based language for manipulating XML and returning strings. It contains an section which is evaluated once per architecture before any other sections. The state is maintained and carried forward to the next section evaluated so the order the sections are executed matters. While UPL is a general system for modifying and querying XML it is specifically used to allow plug-ins to effect the global configuration of the package that they are a part of. For example, this allows a plug-in to modify an Android APK AndroidManfiest.xml file or an IOS IPA plist file. UBT will also query a plug-in's UPL xml file for strings to be included in files that must be common to the package such as some .java files on Android.

Enable Tracing

If you need to see the instructions executed in your plugin context add the following to enable tracing:

After this instruction all the nodes actually executed in your context will be written to the log until you do a . You can also get a dump of all the variables in your context with this command:

Variable Types

Bool, Int, and String variable types are supported. Any attribute may reference a variable and will be replaced with the string equivalent before evaluation using this syntax:

The following variables are initialized automatically:

With the exception of the above variables, all are in the context of the plugin to prevent namespace collision; trying to set a new value to any of the above, with the exception of Output, will only affect the current context.

Variable Manipulation

The following nodes allow manipulation of variables:

Variables may also be set from a property in an ini file:

Strings may also be set from an environment variable using the node. The environment variable must be specified as the 'value' attribute and wrapped in a pair of ' %' characters.

You can also check if a specific environment variable is defined (again, wrapped in '%' characters):

A general example for using environment variable nodes:

Boolean variables may also be set to the result of applying operators:

Integer variables may use these arithmetic operations:

Strings are manipulated with the following:

String length may be retrieved with:

The index of a search string may be found in source with:

The following shortcut string comparisons may also be used instead of using and checking the result:

Writing Messages

Messages are written to the log with this node:

Conditional Execution

Conditional execution uses the following form:

The and blocks are optional. The condition must be in a boolean variable. The boolean operator nodes may be combined to create a final state for more complex conditions:

The "isIntel" could also be done like this:

Two shortcut nodes are available for conditional execution:The following code:

Is the equivalent of:

The following code:

Is the equivalent of:

Execution may be stopped with:

Loops

Loops may be created using these nodes:

The body will execute until the condition is false or a is hit. The will restart execution of the loop if the condition is still true or exit.

<break/> outside a <while> body will act the same as <return></return>.

Here is an example loop which writes 1 to 5 to the log, skipping 3. Note the update of the while condition should be done before the continue otherwise it may not exit.

It is possible to use variable replacement in generating the result variable name as well. This makes the creation of arrays in loops possible:

This may be retrieved using the following (value is treated as the variable name):

It is possible to use variable replacement in generating the result variable name as well. This makes the creation of arrays in loops possible:

This may be retrieved using the following (value is treated as the variable name):

For boolean and integer types, you may use and .

Inserting Text

Nodes for inserting text into the section are as follows:

The first one will insert either text or nodes into the returned section string. Please note you must use escaped characters for:

<insertValue value=""> /pre> - Evaluates variables in value before insertion. If value contains double quote ("), you must escape it with quote.<loadLibrary name="" failmsg=""> - Is a shortcut to insert a system.LoadLibrary try/catch block with an optional logged message for failure to load case.

Search and Replace

You can do a search and replace in the Output with:

You can also manipulate the actual $S(Output) directly, the above are more efficient:

XML Manipulation

XML manipulation uses the following nodes:

The current element is referenced with tag="$". Element variables are referenced with $varname since using $E(varname) will be expanded to the string equivalent of the XML. The addElement, addElements, and removeElement by default are applied to all matching tags. An optional once="true" attribute may be added to only apply to first matching tag.

The , , and are updated with:

Any attributes in the above commands are copied to the element added to the manifest so you can do the following, for example:

Copying of Files

Finally, these nodes allow copying of files useful for staging jar and so files:

If force is false the file(s) are replaced only if length or timestamp don't match. The default for this is true.

The following should be used as the base for the src and dst paths:

While it is possible to write outside the APK directory, it is not recommended.

Removing FIles

If you must remove files (like development-only files from distribution builds) you can use this node:

It is restricted to only removing files from the BuildDir. Here is example usage to remove the Oculus Signature Files (osig) from the assets directory:

Packaging or Deploying

The following sections are evaluated during the packaging or deploy stages:

Supported Nodes

Here is the complete list of supported nodes:

Performance Tiers

Shader Complexity View Mode

Mobile Content Scale Factor

Mobile Material Quality Settings

Mobile Rendering Options

Misc Lighting and Shader Permutation Reduction Settings for Mobile

Additional Suggestions

When developing for Mobile platforms, there are some things you should keep in mind when targeting specific devices or that are general good practices depending on the list of devices you want to release your title for. This includes developing with a specific lighting tier to get the most out of performance on a device and why a particular lighting tier may work best for your target audience. You will also find some suggestions to keep in mind for any project you work on that will be developed with Mobile in mind.

Performance Tiers

Unreal Engine 5 (UE) supports a variety of lighting features on mobile devices. Using these features costs performance and may cause your game to perform poorly on slower mobile devices. While it is possible to mix and match most of UE's mobile lighting features, it can be useful to categorize these features into the following tiers. When building a mobile game, you should decide which features to use based on the quality of graphics your game requires and the types of devices you need to support. Check the development requirements for iOS Development and Android Development for more information on what devices have been tested here at Epic and which tiers we think are most appropriate for that device.

LDR (Low Dynamic Range)

Low Dynamic Range (LDR) mode is the lowest performance tier supported in UE and is recommended for games that do not require lighting or Post Processing features.

To use this mode, you must disable Mobile HDR for your project in the Rendering section of the Project Settings.



Advantages

Limitations

Recommendations

Provides the fastest and lowest overhead mode available for mobile devices, which enables your game to run well on slower mobile devices.

Still provides full access to the Material Editor for defining custom shaders and even performing simple shading that can be used to fake lighting.

The scene's color is written out in gamma space with each color channel clamped to the range of [0,1].

Translucent primitives are blended in gamma space. In most cases, this will require you to author your translucent textures and Materials differently than you would in HDR or for a normal PC title.

Post Processing features are unavailable in this mode.

Make sure all of your Materials have their shading model set to Unlit for maximum performance.

Placed lighting should not be used in your scene when depending on maximum performance.

Consider performing as many operations in the Materials Vertex Shader as possible. You can do this by enabling Customized UVs, connecting nodes to them and then in the pixel shader using a Texture Coordinate node to target the Customized UV.

Basic Lighting

In this tier, you will leverage Static Lighting and fully rough Materials to create Levels with interesting lighting while maximizing performance to reach a broader range of mobile devices.

To use this mode, you must enable Mobile HDR for your project in the Rendering section of the Project Settings.



Advantages

Limitations

Recommendations

Access to Static Lighting and Global Illumination features.

Full HDR pipeline with access to some Post Processing features, like Tone Mapping.

Translucency is blended in linear space, enabling you to author content as your normally would for Desktop.

Since all Materials need to be marked as Fully Rough, your Materials will not have interesting specular reflection.

If you choose to disable Lightmap Directionality, Normal Maps will have no effect.

Author all of your Materials with the Fully Rough flag set.

Consider disabling the flag for Lightmap Directionality in your Materials for additional performance.

Use only Static Lights in your maps.

Disable some Post Processing features completely, like Bloom. Also, stick to the basic set of film and color controls.

Full HDR (High Dynamic Range) Lighting

In this tier, you take advantage of most of the HDR lighting features available for mobile in UE, as well as some of the Post Processing features. Using these features requires quite a bit of performance in exchange for high-quality lighting features.

To use this mode, you must enable Mobile HDR for your project in the Rendering section of the Project Settings.



Advantages

Recommendations

Access to Static Lighting and Global Illumination features.

Full HDR pipeline with access to some Post Processing features.

Translucent is blended in linear space, enabling you to author content as you normally would for Desktop.

Realistic specular reflections on surfaces with support for varying roughness.

Consider enabling Bloom to take full advantage of the HDR lighting pipeline.

Realistic specular reflections in combination with HDR lighting can lead to specular aliasing. To reduce this effect, enable the Material property for Normal Curvature to Roughness to reduce specular aliasing due to high-frequency information in your normal map. You can also consider enabling anti-aliasing via the Project Settings > Rendering to help reduce the artifact.

Take time to consider the placement of Reflection Capture Actors to achieve the best results. See Reflections: Placing Reflection Captures for more information.

Use only Static Lights and Lightmaps in your scene for the best performance.

Full HDR Lighting with per-pixel lighting from the Sun

In this tier, you take advantage of all of the HDR lighting features available for mobile in UE. This tier is the same as Full HDR Lighting and has the same advantages and recommendations with the exception that here you can add a single Directional Light to your scene that automatically uses per-pixel lighting for higher quality.

To use this mode, you must enable Mobile HDR for your project in the Rendering section of the Project Settings.



Advantages

Recommendations

All of the features and advantages listed for the Full HDR tier.

Per-pixel diffuse and specular lighting for a single Directional Light.

High-quality precomputed Distance Field shadows for a single Directional Light.

All of the recommendations and advantages of the Full HDR tier.

Use only Static Lights in your except for a single Directional Light, which should be set to Stationary.

Shader Complexity View Mode

The Shader Complexity view mode in the Mobile Previewer to get a sense of what your Material costs will be for specific devices you are targeting. The colors indicated on screen will tell you how expensive the Material is for the device you're targeting; green means good performance, bright red means very expensive, and white or pink means that the Material is very expensive.

To use it, in the Main Viewport click the View Modes list and select Optimization Viewmodes and choose Shader Complexity, or you can use the keyboard shortcut Alt + 8.



These are some examples taken from Mobile Sun Temple to give you an idea of Material cost when viewed using Shader Complexity:







The pillar Materials are fairly expensive here, and the translucent volumetric sheets are very expensive. In this scene, I asked to have the translucent sheets should be removed, as they cost too much.

Here the pillars are quite expensive as they use all five texture lookups and do quite a bit of layering. Otherwise, this is just about efficient enough for 30fps.

Here, the tree is causing pixels to be extremely expensive. If the player could ever get up close or cover the screen with that Material, the cost would be enormous.

Mobile Content Scale Factor

Mobile Content Scale Factor is a way to scale the resolution of your project to best fit the screen resolution of the mobile device being used to view your project. You can create and store multiple device profiles by creating a new configuration (.ini) file called DefaultDeviceProfiles.ini in your project's config folder.

Inside of this file, you can specify what will happen to the resolution of your project for specific devices by entering the following command followed by one of the values from the iOS and Android sections below:

In the following image, you can see an example of the Mobile Content Scale Factor being set in a configuration file:



Click for full image.

This particular configuration file is from the Tappy Chicken project and shows what will happen to the resolution of Tappy Chicken when it is played on various mobile devices. The top section of this file handles the resolution scaling for iOS devices and the bottom section handles resolution scaling for Android devices. Take note that each r.MobileContentScaleFactor has a number after it. The number is used after the command to determine if the project's resolution should be scaled up or down.

Mobile Content Scale Factor for iOS

For iOS devices, inputting the following numbers will produce the following results:

The iOS scale factor is directly related to Apple's scale factor system and the actual resolution for any scale factor other than 0.0 will be corrected to match the aspect ratio of the screen and clamped to the native resolution of the device.

Value

Result

0.0

This will use the native resolution of the device.

1.0

On a Retina device is the non-retina resolution.

2.0

Full native resolution on iPhone 5S, iPad Air, etc.

3.0

Full native resolution for iPhone 6+.

Mobile Content Scale Factor for Android

For Android devices, inputting the following numbers will produce the following results:

Please note that inputting values other than 0.0 will use this value as the scale factor for a standard 1280x720 or 720x1280 resolution depending on the orientation of the device.

Value

Result

0.0

This will use the native resolution of the device.

1.0

This will try and give you a resolution of 1280 x 720 for Landscape and 720 x 1280 for portrait.

2.0

This will try and give you a resolution of 2560 x 1440 for Landscape and 1440 x 2560 for portrait.

Mobile Material Quality Settings

When building content for a UE project that will run on both low and high-end mobile devices, you will often run into issues where a feature or your artwork is working on one set of devices but not another. While there are a lot of ways to address issues like this, many of these are both time and resource intensive which can be error prone at times. To address these types of issues UE has the Material Quality Level system. This system enables you to build one single Material that can then be used on a wide range of devices, giving you full control over which devices use which features.

In the following sections, we'll cover these systems and how you can use them in your own UE projects:

Previewing Material Quality Level

You can view what the different Material Quality Level settings will look like inside the Editor by going to the Main Toolbar and then then selecting Settings > Material Quality Level to choose the level you want to preview.



The following images show what a Material will look like when the Material Quality Level has been set to Low, Medium, and High.

Dragging the slider will show what happens when changing the Material Quality Level from Low to Medium to High



Setting Material Quality Level

To set the Material Quality Level for your devices, you can do so in the following ways:

Bring up the console by hitting the ` (backtick) key and entering r.MaterialQualityLevel followed by one of the following values:



Material Quality Level Number

Setting

0

Low

1

High

2

Medium

3

Epic

Please note that 1 for high and 2 for medium is correct and not a typo.

Using a configuration (.ini) file, you can set the Material Quality for the devices you plan to target using the following method from within the Editor:

From the Main Toolbar go to Windows > Developer Tools and then click on Device Profiles.



In the Device Profiles find the Android_Low profile and click on the first Wrench icon to open up the profile options.



In the Console Variables section under the Rendering option, click on the Plus icon and in the input window that pops up, input R.MaterialQualityLevel and then press the Enter key to add that command to the list.



Once the new entry has been added, change the value from the default value from 1 to 0 so that when this project is viewed on lower end Android devices it will use the fastest possible Material settings.



Previewing Different Quality Levels

By adjusting the Preview Rendering Level, you can use the Unreal Editor to see how your project will look when running on different hardware. You can adjust this by going to the Main Toolbar and then select Settings > Preview Rendering Level and select the preview level you want to use.



Material Quality Level Switch

The Quality Switch Material Expression enables you to define different levels of complexity within a single Material. For example, if you have a complex math operation, or heavy texture reads that will work on higher-end mobile devices but not on lower-end ones. You can use this node to specify simplified versions to be displayed on lower-end mobile devices that do not have the power to display higher-end graphics.



To use the Quality Switch in your Materials, you will need to first add the Quality Switch Material Expression node to the Material Graph and then plug its output into any of the inputs on the Main Material node. In the following image, the M_Brick_Clay_Old Material (that can be found in the Starter Content) is setup so that when the Quality Level is switched, the complexity of the Material will be reduced.



Click for full image.

Mobile Material Options

If you open up any Material and click on the Main Material Node then look in the Details panel under the Mobile section you will find the following properties:

Property

Setting

Float Precision Mode

How to use full (highp) presition in the pixel shader. Highp is slower than the default (mediump), but can be used to work around precision-related rendering errors. Use Full-Precision for MaterialExpressions Only if you still want to keep the precisions of the halfs in .ush/.usf. This setting has no effect on older mobile devices that do not support high precision.

Use Lightmap Directionality

Uses lightmap directionality and per-pixel normals. If disabled, the lightmaps will be flatter looking visually but cheaper to use.

Mobile High Quality BRDF

Uses the high quality BRDF functions on mobile to get better visual effects but adds GPU cost.

Use Alpha to Coverage

Uses alpha to coverage for masked material on mobile, make sure MSAA is enabled as well.



Use these properties to help reduce the rendering cost of that Material when viewed on less powerful mobile devices by completely eliminating the rendering path for those features.

Mobile Material Rendering Overrides

You can override the available rendering option a platform will use by adjusting the the Material Quality settings for different target devices located under the Project Settings > Platforms.



You can override the available rendering option a platform will use by adjusting the Quality Options listed. In order to use the overrides, you must first click on the Enable Quality Overrides option and then select the option you want to override for a given Quality Level.



Once all of the options you want have been selected, press the Update Preview Shaders button to recompile all the Materials to work with the options specified.



Mobile Rendering Options

Inside of your Project's Settings menu under the Rendering section, you will find a number of properties that control how lighting and optimization will be handled inside of your mobile project. In the following sections we will take a look at these settings and what effect they will have on your project.

Accessing your Project's Settings

Once the Project Settings menu is open, locate the Engine section and then click on the Rendering category. Use the following sections to adjust the settings below:

Mobile

Misc Lightning

VR

Mobile Shader Permutation Reduction



Mobile and VR Rendering Options

Under the Mobile and VR category, you can set properties that directly affect the lighting and look of your mobile project. Read on below to explore these settings for your own projects.



Property Name

Description

Mobile

The listed options found under the Mobile section of the Project Settings that should be adjusted for mobile performance.

Disable Vertex Fogging in mobile shaders

If true, vertex fog will be omitted from all mobile shaders. If your game does not use fog, you should choose this setting to increase shading performance.

Maximum number of CSM cascades to render

The maximum number of cascades with which to render dynamic directional light shadows when using the mobile renderer.

Mobile Anti-Aliasing Method

This is the Multi-Sample Anti-Aliasing (MSAA) setting to use on mobile. If MSAA is not available, the current default AA method will be used.



VR

The listed options found under the VR section of the Project Settings that should be adjusted for mobile performance.

Mobile HDR

If true, mobile renders in full HDR. Disable this setting for games that do not require lighting features for better performance on slow devices.



Misc Lighting and Shader Permutation Reduction Settings for Mobile

Under the Misc Lighting and Mobile Shader Permutation Reduction section, you will find a number of different option that can be enabled or disabled to effect shaders generated for Materials, which in-turn will reduce app size, save memory and improve load times.



Property Name

Description

Misc Lighting

The listed options found under the Misc Lighting section of the Project Settings that should be adjusted for mobile performance.

Allow Static Lighting

Whether to allow any static lighting to be generated and used, like lightmaps and shadow maps. Games that only use dynamic lighting or that are unlit should set this to 0 to save some static lighting overhead.



Mobile Shader Permutation Reduction

The listed options found under Mobile Shader Permutation Reduction that should be adjusted for mobile performance.

Support Combined Static and CSM Shadowing

Allows primitives to receive both static and CSM shadows from a stationary light. Disabling will free a mobile texture sampler and reduce shader permutation.

Support CSM on levels with Force No Precomputed Lighting enabled

When Allow Static Lighting is enabled, shaders to support CSM without any precomputed lighting are not normally generated. This setting allows CSM for this case at the cost of extra shader permutations.

Support Pre-baked Distance Field Shadow Maps

Generates shaders for static primitives render Lightmass-baked distance field shadow maps from stationary directional lights.

Support Movable Directional Light

Generates shaders for primitives to receive movable directional lights.

Max Movable Point Lights

The number of dynamic spotlights or point lights to support on mobile devices. Setting this to 0 for games which do not require dynamic spotlights or point lights will reduce the number of shaders generated.

Support Movable Spotlights

Generates shaders for primitives to receive lighting from movable spotlights. This incurs an additional cost when processing movable lights.



Changing any of these settings will require you to restart the editor before they take effect.

If you disable a shader permutation that your lighting setup requires, your lighting or shadowing will not render correctly and there will be an on-screen message indicating the setting that needs to be re-enabled for it to work properly.

Additional Suggestions

The following suggestions will help to set up your content for optimal performance on mobile platforms. These are listed from most severe to least impactful.

Make sure lighting is built before running on a device.

Most Post Processing features are disabled for mobile platforms as they are too expensive, like vignette or screen space reflections. Some GPU intensive features like Bloom and Depth of Field are enabled by default so that PC and mobile look the same but many features can cost 60 milliseconds or more with the default settings on some devices. The console command showflag.PostProcessing 0 can be used to turn off these features to get a general idea of their costs.

Make sure to use Precomputed Visibility and that it is set up properly. To do this, place Precomputed Visibility Volumes around areas where the player can walk or jump and then build lighting. You need to make sure to place these in the Persistent Level that is used when building lighting and when running the game, so do not build a Sublevel by itself. You can verify that Precomputed Visibility is working by entering the console command Stat Initviews on device or in the Level Previewer and making sure that Statically Occluded Primitives is greater than 0. Use the console command r.ShowPrecomputedVisibilityCells 1 to visualize the cells in the Editor.

Use masked and transparent Materials sparingly. Only use them in places where they cover a small part of the screen. iOS devices are very optimal in shading opaque surfaces, as they will only shade each pixel once, but for masked and translucency, every single layer will have to be shaded. The total GPU time of a frame can be doubled or more by having overdraw. Use the Shader Complexity view mode to investigate any hot spots.

Draw calls of the entire scene should be <=700 for any single view. Areas with poor occlusion, like looking over a large landscape, is going to be biggest challenges for this. This can be seen with Stat OpenGLRHI on device or Stat D3D11RHI in the Previewer on PC.

Triangle count of the entire scene should be <=500k for any view. This has been determined to be the maximum poly count that can hit 30fps on both iPad4 and iPad Air. This can be seen with Stat OpenGLRHI on device or Stat D3D11RHI in the Previewer on PC.

Materials should use as few texture lookups and instructions as possible. You have five texture samplers available, but using all of those makes for a fairly expensive Materials. For now, use the PC instruction count to optimize and the Previewer Shader Complexity to visualize the total cost.

Only use independent texture fetches in Materials. This means UVs in the pixel shader (BaseColor, Roughness, and so on.) must not be manipulated in any way, such as Scaling. Use the CustomizedUVs feature instead to do the Scaling in the Vertex Shader. Some special features like environment mapping require math on the UVs and that is OK for special cases.

It is recommended to use square textures as they have less memory waste. Always use power of two dimensions for these (256x256, 512x512, 1024x1024). Use the console command ListTextures in the Previewer to see where all the texture memory is going.

Supported Rendering Features

Post Process Volume

General Rendering Features

Lighting Features

Light Type and Mobility Features

Material Features

Textures

Many mobile devices have significant hardware limitations compared with desktop hardware and game consoles, especially in terms of compatibility with graphics features. To address this, Unreal Engine has an alternate rendering path for mobile devices. This rendering path uses simplified or performance-oriented models for many of Unreal's rendering features, such as shadows and textures, and it removes many unsupported post-processes. The guides in this section provide details about configuration options and features in the mobile renderer.

The following links contain specialized topics in Mobile rendering.



Guide to the Mobile Renderer's modes and feature levels



Supported Rendering Features

This section lists features that are compatible with Mobile feature levels.

Post Process Volume

Feature

Mobile Forward (Open GL ES 3.2, Metal, Vulkan, Switch)

Mobile Deferred (Metal, Vulkan, Switch)

Mobile Forward w/ HDR Disabled (Head-mounted Mobile XR)



Lens



Mobile Depth of Field Properties

Yes

Yes

No

Mobile DoF - High Quality Gaussian DoF

Yes

Yes

No

Bloom - Standard

Yes

Yes

No

Bloom - Convolution

No

No

No

Chromatic Abberation Properties

Yes

Yes

No

Dirt Mask Properties

Yes

Yes

No

Lens Flare Properties

Yes

Yes

No

Image Effects Properties

Yes

Yes

No

Cinematic Depth of Field Properties

No

No

No



Exposure



Metering Mode - Auto Exposure Histogram

Yes

Yes

No

Metering Mode - Auto Exposure Basic

Yes

Yes

No

Metering Mode - Manual

Yes

Yes

Yes



Color Grading



Color Grading Properties

Yes

Yes

No



Film



Film Properties

Yes

Yes

No



Rendering Features



Post Process Material Properties

Yes

Yes

No

Ambient Cubemap Properties

No

No

No

Ambient Occlusion Properties

Yes

Yes

No

Global Illumination Properties

No

No

No

Motion Blur Properties

No

No

No

General Rendering Features

Feature

Mobile Forward (Open GL ES 3.2, Metal, Vulkan, Switch)

Mobile Deferred (Metal, Vulkan, Switch)

Mobile Forward w/ HDR Disabled (Head-mounted Mobile XR)



Anti-Aliasing



Fast Approximation Anti-Aliasing (FXAA)

Yes

Yes

No

Multi-Sample Anti-Aliasing (MSAA)

Yes

No

Yes

Temporal Anti-Aliasing (TAA)

Yes

Yes

No

Temporal Super Resolution

No

No

No



Systems/Tools Features



Nanite Virtualize Geometry

No

No

No

Texture Streaming

Yes

Yes

Yes

Streaming Virtual Textures

Yes

Yes

Yes

Runtime Virtual Textures

Yes

Yes

Yes

Mesh Decals

Yes

Yes

No

Mesh Distance Fields

Yes

Yes

No



Level of Detail (LOD)



Hierarchical Level of Detail (HLOD)

Yes

Yes

Yes

Dither Fading

Yes

Yes

Yes



Cull Distance Volumes

Yes

Yes

Yes

Precomputed Visibility Volumes

Yes

Yes

Yes

Hardware (GPU) Occlusion Queries

Yes

Yes

Yes

Software (CPU) Occlusion Queries (Removed)

No

No

No

Lighting Features

Feature

Mobile Forward (Open GL ES 3.2, Metal, Vulkan, Switch)

Mobile Deferred (Metal, Vulkan, Switch)

Mobile Forward w/ HDR Disabled (Head-mounted Mobile XR)



Atmosphere and Fog



Sky Atmosphere

Yes

Yes

Yes

Volumetric Clouds

No

No

No

Exponential Height Fog

Yes

Yes

Yes

Volumetric Fog

No

No

No

Lighting and Shadowing

Dynamic Lighting

Yes

Yes

Yes

Precomputed/Baked Lighting

Yes

Yes

Yes

Image Based Lighting

Yes

Yes

Yes

Hardware Ray Tracing Features

No

No

No

Path Tracer

No

No

No



Virtual Shadow Maps



Modulated Shadows

Yes

Yes

Yes

Capsule Shadows

No

No

No

Contact Shadows

No

No

No

Precomputed Translucent Shadows

No

No

No

Dynamic Translucency Shadows

No

No

No



Global Illumination



Lumen GI and Reflections: Software Ray Tracing

No

No

No

Lumen GI and Reflections: Hardware Ray Tracing

No

No

No

Precomputed / Baked Global Illumination

Yes

Yes

Yes

Screen Space Global Illumination

No

No

No

Standalone Ray Traced Global Illumination (Deprecated)

No

No

No



Reflections



Reflection Captures (Box/Sphere)

Yes

Yes

Yes

Scene Capture Cubemap

Yes

Yes

Yes

Scene Capture 2D

Yes

Yes

Yes

Planar Reflections

Yes

Yes

Yes

Screen Space Reflections

No

No

No

Standalone Ray Traced Reflections (Deprecated)

No

No

No

High Precision Normals

No

No

No

Reflection Capture Resolution

Yes

Yes

Yes

HDR Cubemap

Yes

Yes

Yes

Direct Specular

Yes

Yes

Yes

GGX Specular

Yes

Yes

Yes

Light Type and Mobility Features

Feature

Mobile Forward (Open GL ES 3.2, Metal, Vulkan, Switch)

Mobile Deferred (Metal, Vulkan, Switch)

Mobile Forward w/ HDR Disabled (Head-mounted Mobile XR)



Static Mobility - Light Type



Directional Light

1 directional light of any type

1 directional light of any type

1 directional light of any type

Sky Light

Yes

Yes

Yes

Point Light

Yes

Yes

Yes

Spot Light

Yes

Yes

Yes

Rect Light

No

No

No



Static Mobility - General Features



Indirect Lighting Intensity

Yes

Yes

Yes

Lighting Channels

Yes

Yes

Yes

Light Transmission

No

No

No

Light Functions

No

Yes

No



Source Angle

Yes

Yes

Yes

Light Shafts

Yes

Yes

No

Modulated Shadows

No

No

No



SLS Captured Scene

Yes

Yes

Yes

SLS Specified Cubemap

Yes

Yes

Yes

Specified Cubemap Resolution

Yes

Yes

Yes



Static Mobility - Point/Spot/Rect Light Features



IES Texture

Yes

Yes

Yes

Rect Light - Source Texture

No

No

No



Stationary Mobility - Light Type



Directional Light

1 directional light of any type

1 directional light of any type

1 directional light of any type

Sky Light

Yes

Yes

Yes

Point Light

Yes

Yes

Yes

Spot Light

Yes

Yes

Yes

Rect Light

No

No

No



Directional Light

Yes

Yes

Yes

Rect Light

No

No

No



Indirect Lighting Intensity

Yes

Yes

Yes

Lighting Channels

Yes

Yes

Yes

Light Transmission

No

No

No

Light Function

No

Yes

No



Stationary Mobility - Directional Light Features



Cascade Shadow Maps

Yes

Yes

Yes

Light Shafts

Yes

Yes

Yes

Modulated Shadows

Yes

Yes

Yes

Stationary Mobility - Sky Light Features

SLS Captured Scene

Yes

Yes

Yes

SLS Specified Cubemap

Yes

Yes

Yes

Specified Cubemap Resolution

Yes

Yes

Yes



Stationary Mobility - Point/Spot/Rect Light Features



IES Texture

Yes

Yes

Yes

Rect Light - Source Texture

No

No

No



Movable Mobility - Light Type



Directional Light

1 directional light of any type

1 directional light of any type

1 directional light of any type

Sky Light

Yes

Yes

Yes

Point Light

Yes

Yes

Yes

Spot Light

Yes

Yes

Yes

Rect Light

No

No

No



Movable Mobility - Dynamic Shadow Casting



Directional Light

Yes

Yes

Yes

Sky Light

No

No

No

Point Light

No

No

No

Spot Light

Yes

Yes

Yes

Rect Light

No

No

No



Indirect Lighting Intensity

No

No

No

Lighting Channels

Yes

Yes

Yes

Light Transmission

No

No

No

Light Function

No

Yes

No



Movable Mobility - Directional Light Features



Cascade Shadow Maps

Yes

Yes

Yes

Light Shafts

Yes

Yes

Yes

Modulated Shadows

No

No

No

Distance Field Shadows

Yes

Yes

Yes



SLS Captured Scene

Yes

Yes

Yes

SLS Specified Cubemap

Yes

Yes

Yes

Specified Cubemap Resolution

Yes

Yes

Yes



IES Texture

No

Yes

No

Rect Light - Source Texture

No

No

No

Material Features

Feature

Mobile Forward (Open GL ES 3.2, Metal, Vulkan, Switch)

Mobile Deferred (Metal, Vulkan, Switch)

Mobile Forward w/ HDR Disabled (Head-mounted Mobile XR)



Material Inputs



Base Color

Yes

Yes

Yes

Metallic

Yes

Yes

Yes

Specular

Yes

Yes

Yes

Roughness

Yes

Yes

Yes

Anisotropy

No

No

No

Emissive Color

Yes

Yes

Yes

Opacity

Yes

Yes

Yes

Opacity Mask

Yes

Yes

Yes

Normal

Yes

Yes

Yes

Tangent

No

No

No

World Position Offset

Yes

Yes

Yes

Cloth

No

No

No

Fuzz Color

No

No

No

Iris mask

No

No

No

Iris Distance

No

No

No

Subsurface Color

Yes

Yes

Yes

Custom Data 0—7

Yes

Yes

Yes

Ambient Occlusion

Yes

Yes

Yes

Refraction

Yes

Yes

No

Pixel Depth Offset

Yes

Yes

Yes

Shading Model

Yes

Yes

Yes

Clear Coat

Yes

Yes

Yes

Clear Coat Roughness

Yes

Yes

Yes

Backlit (for Hair)

No

No

No



Material Domain



Surface

Yes

Yes

Yes

Deferred Decal

Yes

Yes

No

Light Function

No

Yes

No

Volume

No

No

No

Post Process

Yes

Yes

No

User Interface

Yes

Yes

Yes

Virtual Texture

No

No

No



Unlit

Yes

Yes

Yes

Default Lit

Yes

Yes

Yes

Subsurface

Yes

Yes

Yes

Preintegrated Skin

Yes

Yes

Yes

Clear Coat

Yes

Yes

Yes

Subsurface Profile

Yes

Yes

Yes

Two Sided Foliage

No

No

No

Hair

No

No

No

Cloth

No

No

No

Eye

No

No

No

Single Layer Water

Yes

Yes

Yes

Thin Translucent

No

No

No

From Material Expression

Yes

Yes

Yes



Decals



Translucent

Yes

Yes

No

Normal

No

Yes

No

Emissive

Yes

Yes

No

DBuffer Translucent Color, Normal, Roughness

No

Yes

No

DBuffer Translucent Color

No

Yes

No

DBuffer Translucent Color, Normal

No

Yes

No

DBuffer Translucent Normal

No

Yes

No

DBuffer Translucent Normal, Roughness

No

Yes

No

DBuffer Translucent Roughness

No

Yes

No

Alpha Composite (Premultiplied Alpha)

Yes

Yes

No

Ambient Occlusion

No

No

No

Textures

Feature

Mobile Forward (Open GL ES 3.2, Metal, Vulkan, Switch)

Mobile Deferred (Metal, Vulkan, Switch)

Mobile Forward w/ HDR Disabled (Head-mounted Mobile XR)



Compression Settings



Default (DXT1/5, BC1/3 on DX11)

Yes

Yes

Yes

Normal Map (DXT 5, BC5 on DX11)

Yes

Yes

Yes

Masks (no sRGB)

Yes

Yes

Yes

Grayscale (R8, RGB8, sRGB)

Yes

Yes

Yes

Displacement Map (8/16-bit)

Yes

Yes

Yes

HDR (RGB, no sRGB)

Yes

Yes

Yes

User Interface 2D (RGBA)

Yes

Yes

Yes

Alpha (no sRGB, BC4 on DX11)

Yes

Yes

Yes

Distance Field Font (R8)

Yes

Yes

Yes

HDR Compressed (RGB, BC6H, DX11)

No

No

No

BC7 (DX11, optional A)

Yes

Yes

Yes

### Particle Effects

Feature

Mobile Forward (Open GL ES 3.2, Metal, Vulkan, Switch)

Mobile Deferred (Metal, Vulkan, Switch)

Mobile Forward w/ HDR Disabled (Head-mounted Mobile XR)



Niagara Particle System



CPU Particles

Yes

Yes

Yes

CPU Particle Collision

Yes

Yes

Yes

GPU Particles

Yes

Yes

Yes

GPU Depth Collision

No

No

No

Mesh Particles

Yes

Yes

Yes

Beam Emitter

Yes

Yes

Yes

Ribbon Emitter

Yes

Yes

Yes

Anim Trail

Yes

Yes

Yes

Vector Field

Yes

Yes

Yes

Particle Lights

No

Yes

No

GPU Distance Field Collision

No

No

No

GPU Raytracing Collision (Experimental)

No

No

No

Fluid Simulation

No

No

No

Some features on this page are Experimental or Beta features. Use caution when using these in your projects, and avoid shipping projects using Experimental features.

Feature Levels

Mobile HDR

Using Deferred Shading

Using the Desktop Renderer on Mobile (Experimental for Android, Beta for iOS)

The Unreal Engine (UE) Mobile renderer provides a separate rendering path from the desktop and console renderer, optimized for mobile devices such as mobile phones and tablets. This renderer can be configured in a variety of ways to suit specific devices and applications. This page provides a reference for where those options are and how to configure them.

Feature Levels

The basic Feature Levels for Mobile are as follows:

Feature Level

Description

OpenGL ES 3.2

The default feature level for Android devices. You can configure the material settings for this feature level in Project Settings > Platforms > Android Material Quality - ES32.

Android Vulkan

A high-end renderer available for some specific Android devices. For more information on how to use Vulkan in your projects and what GPUs support it, see our guide on the Android Vulkan Mobile Renderer.

Metal 2.0

The feature level used for iOS devices. You can configure material settings for this feature level in Project Settings > Platforms > iOS Material Quality.

Support for advanced Mobile rendering features varies depending on which Feature Level your application is using. Refer to each feature's documentation in the Mobile Rendering Features section for more information.

Mobile HDR

The Mobile High-Definition Rendering (HDR) option is required to use a variety of high-end post-processes and rendering features.

Using Deferred Shading

Deferred shading provides support for high-quality reflections, multiple dynamic lights, lit decals, and other advanced lighting features that are not normally available in the default forward rendering mode for Mobile.





To enable Deferred Shading, add the following CVar to your DefaultEngine.ini:

DefaultEngine.ini

Using the Desktop Renderer on Mobile (Experimental for Android, Beta for iOS)

Unreal now provides forward and deferred desktop renders for iOS devices and Android devices using Vulkan. This functionality is currently Experimental for Vulkan, and Beta for iOS.

The iOS implementation is considered Beta in terms of feature readiness.

The Android Vulkan implementation is considered Experimental.



The Infiltrator Demo running on iPad Pro with the desktop forward renderer.

To enable the desktop renderer for iOS, open your Project Settings, then navigate to Platforms > iOS > Rendering and enable Metal Desktop Renderer.



To enable the desktop renderer for Android Vulkan, navigate to Platforms > Android > Build and enable Support Vulkan Desktop [Experimental].

You also need to set r.Android.DisableVulkanSM5Support to 0 to allow the use of SM5.



You must restart the Unreal Editor for your changes to take effect. You can then configure forward and deferred rendering features the same way you would in a desktop application.

For more information about these rendering options, refer to the Forward Shading Renderer guide.

How to Enable the Mobile Deferred Shading Mode

Overview

Guidelines for Using Mobile Deferred Shading and Mobile Forward Shading

Supported Rendering Features for Mobile Deferred Shading

Device Compatibility

While forward shading processes geometry and lighting at draw time, deferred shading separates them into two separate passes. This separates the computation of lighting from the computation of geometry, and provides more efficient implementation for materials and advanced lighting features.

The mobile deferred shading model provides these benefits, but also takes advantage of tile-based GPUs to reduce the performance impact on system memory and CPU. This provides better rendering quality and better performance on mobile devices that support tile memory.

This page provides the following information:

An overview of the benefits and limitations of mobile deferred shading.

Information on which devices are compatible with the mobile deferred shading model.

Instructions on how to configure mobile deferred shading for your project.

How to Enable the Mobile Deferred Shading Mode

To enable mobile deferred shading:

Open your Project Settings.

Navigate to Engine - Rendering > Mobile.

Click the dropdown for Mobile Shading and set it to Deferred Shading, then restart the editor.



When you build your project for mobile devices, they will use the mobile deferred shading model.

Overview

Deferred shading splits the rendering process into two passes:

A geometry pass that handles BaseColor, Metallic, and Roughness parameters and stores them in a temporary buffer, usually called GBuffer.

A lighting pass that reads the material attributes from GBuffer, computes lighting for it, then writes shaded pixels into the framebuffer.

Meanwhile, forward shading computes material interactions with lights and shadows at draw time. This means that materials must include light and shadow code alongside all other parameters. Deferred shading can omit this information and use simpler shaders and materials that take less time to compile.

Because deferred shading does not need to bind shadow and reflection textures, it also requires less graphics state management for each draw call, which provides better performance on CPU. This means the Render Hardware Interface (RHI)** thread does less work, which in turn frees up big cores for other threads, which causes fewer conflicts among available threads.

Deferred shading separates the processing and memory costs of lighting from the costs of rendering geometry, which makes debugging and optimization for lighting more flexible.

Mobile Deferred Shading

To achieve deferred shading efficiently on mobile devices, the mobile deferred shading model puts GBuffer in tile memory inside the GPU, meaning that the GBuffer is never stored in system memory. It also does not allocate memory when a device supports the LAZILY_ALLOCATED memory type. Devices that support memoryless render target use less memory with mobile deferred shading, but devices that don't support them will allocate system memory for GBuffer and use slightly more memory.

Example of Performance Improvements

The Material below uses a simple color and roughness input. With mobile forward rendering, it uses 147 instructions and 2 samplers. With mobile deferred, it uses only 34 instructions and 0 samplers, as it no longer needs to include lighting and shading instructions. This results in reduced framerate hitches and overall lower memory use.



Left: A basic material using simple color and roughness inputs. Top-Right: Statistics for this material using Mobile Forward. Bottom-Right: Statistics for this material using Mobile Forward.

Guidelines for Using Mobile Deferred Shading and Mobile Forward Shading

Mobile deferred shading is preferable when:

Your target devices use tile-based mobile GPUs.

Your game does not use pre-computed lighting.

You need advanced lighting features not offered by forward shading.

You need to improve performance and save memory for complex lighting.

Typical examples of projects that fit the above profile are games with large outdoor environments and heavy dependence on dynamic lighting. Most devices that Unreal Engine supports fulfill the hardware requirements for deferred shading, and the performance benefits for deferred shading are significant. Therefore, we advise using mobile deferred shading for most mobile projects in UE. However, the forward shading model is still preferable if you primarily use pre-computed lighting, and it provides benefits when using local lights or a large number of reflection captures.

Supported Rendering Features for Mobile Deferred Shading

This section lists rendering features that the Mobile Deferred shading mode supports which are not available in the Mobile Forward shading mode.

Lighting Features

The Mobile Deferred shading mode provides the following lighting features:

Light Functions

Light Profiles

IES Light Profiles

Lit decals

Increased local light rendering efficiency

Rendering Limitations

If your project uses pre-computed lighting, deferred shading only provides DefaultLit and Unlit shading models. If your project uses pre-computed lighting, we strongly advise that you use forward shading instead of deferred shading.

Translucency is available in the deferred shading mode, but translucency passes always use forward shading. Make sure translucent materials such as glass or water have their Lighting Mode set to Surface ForwardShading.

Deferred rendering can not support Multi-Sample Anti-Aliasing (MSAA) **due to the amount of space it would need in GBuffer. It also would have a more resource-intensive shading pass due to the need to shade each sample rather than each pixel.

Lit decals are not supported with static lighting in deferred mode, as it would require an additional buffer for decals. This is not feasible on mobile devices due to memory constraints. However, emissive decals work fine with static lighting.

Because of space limitations in GBuffer, decals use octahedron encoding for normals to reduce their size. This encoding makes it impossible to blend or modify normals in GBuffer. However, you can fully overwrite them instead.

Supporting multiple shading models at the same time is very expensive with mobile deferred shading. Therefore, you should limit your use of complex shading models only to objects that need them.

Device Compatibility

Unreal Engine supports Mobile Deferred shading on all platforms that use the Mobile renderer, including PC platforms, iOS, Android Vulkan, and Android GLES. The following sections provide details on how each family of devices uses its Tile Memory to support this shading mode, and on the limitations of certain devices.

Tile Memory Usage

Each mobile platform has different ways to perform shading in tile memory.

iOS uses a functionality similar to framebuffer_fetch to access GBuffer on tile memory.

Android Vulkan uses Vulkan's sub-passes.

Android GLES requires extensions, and there is no universal method for all GPUs.

Mali and PowerVR use PLS extensions.

Adreno GPUs use the framebuffer_fetch extension.

Other GPUs use an immediate-mode renderer, so these tile memory techniques do not apply. In these cases, GBuffer is allocated as a regular texture in system memory and may not provide memory benefits.

Hardware Limitations

Mali Devices running Android Vulkan have strict limitations on color and input attachments:

16 bytes or 128-bit per-pixel in GBuffer

Can only use up to 4 input attachments.

Can only fetch up to 3 color attachments and 1 depth attachment during the lighting pass.

The Mobile Deferred shading mode adopts these limitations by default to ensure consistency across all devices. To remove these limitations, set the MobileUsesExtendedGBuffer parameter in your *Engine.ini file to true. The mobile deferred shading mode will then expand GBuffer to use the full capabilities of the user's device.

Mobile applications commonly use a variety of services to engage users, deliver content, and interface with the OS. The guides in this section provide information about how to implement these services in Unreal Engine projects.



Using in-game advertisements to monetize your game.



Product documentation including reference and guides for Unreal Engine 4



Using in-app purchases to offer additional paid content for your game.



Using Mobile Achievements to increase player engagement.



Using Mobile Service Leaderboards in your game.

Configuration

Showing the Ad Banner

Hiding the Ad Banner

In-game advertisements enable you to display ads to players of your game on mobile platforms. This provides a means of monetizing your game while allowing it to remain completsharing-and-releasing-projects/general-mobile-development/supporting-mobile-services



Configuration

See the appropriate platform-specific page below for details on configuring in-game advertisements for each platform:

Using Ad Mob In-Game Ads on Android

Showing the Ad Banner

The Show Ad Banner function is used to display an ad banner in your game. Call it somewhere in the logic where you want to show an ad, such as when the main menu is shown.

In Blueprints:

The example below is from the Unreal Match 3 sample game, which displays an ad banner when the victory/defeat screen is shown using the Construct event of that Widget Blueprint:



See the Show Ad Banner reference for more information on the node.

Hiding the Ad Banner

The Hide Ad Banner functions hides the visible ad banner. Call it when you no longer want the ad to be displayed, such as when you exit the main menu.

In Blueprints:

The example below is from the Unreal Match 3 sample game, which hides the ad banner when the victory/defeat screen is exited using the Destruct event of that Widget Blueprint:



See the Hide Ad Banner reference for more information on the node.

Steps

End Result

Local notifications are messages that can be displayed outside of your Unreal Engine 4 (UE4) application, alerting users to changes or updates that have been made. In the following How-To we will take a look at how to set up local notifications that will work on both Android and iOS devices.

The current implementation of Local Notifications for both Android and iOS is very simplistic in its setup and execution. This system also will only work with local notifications and not notifications that are sent via a remote server.

Choose Your mobile platform

Android

iOS

Steps

First, create a new Project from the Games > Blank template with the following options:

Blueprint enabled

Mobile / Tablet enabled

Scalable 3D or 2D enabled

No Starter Content enabled

Once the project has opened, open the Level Blueprint by clicking on the Blueprints button that is on Main Toolbar and then from the displayed list, select the Open Level Blueprint option.



Click for full image.

To make this How-To easy to follow along with, we are using the Level Blueprint to set up and call the required Local Notifications Blueprint nodes. While setting up Local Notifications in the Level Blueprint will work, you should consider adding this logic where it makes the most sense for your project.

In the Variables section, create the following three text variables so that we can display messages to the user when the local notification is shown:



Click for full image.

Variable Name

Value

Title

Title: This is the Title!

Body

Body: This is the body!

Action

Action: I am taking this Action!

To make sure that the user can see the local notifications when they are called to be displayed, add Event Begin Play and Register for Remote Notifications nodes to the Event Graph.



Click for full image.

When adding this to your UE4 project, make sure that the Register for Remote Notifications node is called right when your project first loads. This way you will not have to worry about calling it again when trying to display notifications.

To make sure that users can see the notifications when they are fired off, you will need to connect the output of the Event Begin Play to the input on the Register for Remote Notifications. This will make sure that the user gives the operating system (OS) the permission to display the notifications.



Click for full image.

Now that we have given the OS permission to display the notification, next we need to set up what will happen when the user clicks on the notification. To handle this type of interaction, add Get Launch Notification, Print String and Branch nodes to the Event Graph.



Click for full image.

Connect the Output of the Get Launch Notification node to the input on the Branch node and then connect the True output of the Branch node to the input on the Print String node.



Click for full image.

Now, connect the Notification Launched App to the Condition input on the Branch node and the Activation Event to the In String on the Print String node.



Click for full image.

When adding this to your project you can omit the Print String node. This was added to make sure that the correct Activation Event was being used.

Now, we need to set up what the notification will say and how much time should pass before the notification is displayed. To accomplish this, you will first need to add the following Blueprint nodes to the Event Graph.

Schedule Local Notifications from Now

Delay

Title, Body, and Action Text Variables



Click for full image.

With the required nodes added to the Event Graph, connect the Completed output of the Delay node to the input on the Schedule Local Notifications from Now, and then connect each of the Text variables to their respective inputs on the Schedule Local Notifications from Now node. When completed, your Event Graph should match the image below.



Click for full image.

Set the Duration on the Delay node to five (5) seconds. This will help make sure that there is enough time to either close the app or put the app in the background before the local notification is called and displayed.



Click for full image.

The Delay node was only added to ensure that there would be enough time to close the app or send it to the background before the notification went off. When adding this to your project you do not have to use the Delay node.

Next, set the Seconds from Now input on the Schedule Local Notifications from Now node to 30 seconds. This will display the notification 30 seconds after this piece of code has been run.



Click for full image.

Set the Activation Event on the Schedule Local Notifications from Now to a value of 42.



Click for full image.

The Activation Event input enables you to associate a string value that can be used to call a specific notification. This allows you to set up and use different notifications that can be displayed when certain conditions are met.

With all of the needed nodes for Local Notifications to work now added to the Event graph, the last thing left to do is connect the False output of the Branch node to the input on the Delay node. When completed your Event Graph should look like the following image.



Click for full image.

Press the Compile button to compile the level Blueprint and the Save button to your level.

Finally, on the Main Toolbar click on the Advanced Options drop down next to the Launch icon and then select the device you want to test this on.

Local Notifications for iOS projects are only available using source builds at present time.

First, download and compile a source code build of Unreal Engine. You can find instructions on how to download the source code from GitHub on the UE4 On GitHub page as well as the Downloading Unreal Engine Source Code guide.



Click for full image.

Once you have compiled the Editor, open it and create a new Project from the Games > Blank template with the following options:

C++ enabled

Mobile / Tablet enabled

Scalable 3D or 2D enabled

No Starter Content enabled

When the project has opened, go to the Edit and then select Project Settings.

From the Project Settings menu, click on All Settings and then in the search box input Enable Remote Notifications Support.



Click for full image.

Enable Remote Notifications Support is only available when using a C++ based project. If you are using a Blueprint based project, this option will be grayed out.

Once the project has opened, open the Level Blueprint by clicking on the Blueprints button that is on Main Toolbar and then from the displayed list, select the Open Level Blueprint option.



Click for full image.

To make this How-To easy to follow along with, we are using the Level Blueprint to set up and call the required Local Notifications Blueprint nodes. While setting up Local Notifications in the Level Blueprint will work, you should consider adding this logic where it makes the most sense for your project.

In the Variables section, create the following three text variables so that we can display messages to the user when the local notification is shown:



Click for full image.

Variable Name

Value

Title

Title: This is the Title!

Body

Body: This is the body!

Action

Action: I am taking this Action!

To make sure that the user can see the local notifications when they are called to be displayed, add Event Begin Play and Register for Remote Notifications nodes to the Event Graph.



Click for full image.

When adding this to your UE4 project, make sure that the Register for Remote Notifications node is called right when your project first loads. This way you will not have to worry about calling it again when trying to display notifications.

To make sure that users can see the notifications when they are fired off, you will need to connect the output of the Event Begin Play to the input on the Register for Remote Notifications. This will make sure that the user gives the operating system (OS) the permission to display the notifications.



Click for full image.

Now that we have given the OS permission to display the notification, next we need to set up what will happen when the user clicks on the notification. To handle this type of interaction, add Get Launch Notification, Print String, and Branch nodes to the Event Graph.



Click for full image.

Connect the Output of the Get Launch Notification node to the input on the Branch node and then connect the True output of the Branch node to the input on the Print String node.



Click for full image.

Now, connect the Notification Launched App to the Condition input on the Branch node and the Activation Event to the In String on the Print String node.



Click for full image.

When adding this to your project you can omit the Print String node. This was added to make sure that the correct Activation Event was being used.

Now, we need to set up what the notification will say and how much time should pass before the notification is displayed. To accomplish this, you will first need to add the following Blueprint nodes to the Event Graph.

Schedule Local Notifications from Now

Delay

Title, Body, and Action Text Variables



Click for full image.

With the required nodes added to the Event Graph, connect the Completed output of the Delay node to the input on the Schedule Local Notifications from Now, and then connect each of the Text variables to their respective inputs on the Schedule Local Notifications from Now node. When completed, your Event Graph should match the image below.



Click for full image.

Set the Duration on the Delay node to five (5) seconds. This will help make sure that there is enough time to either close the app or put the app in the background before the local notification is called and displayed.



Click for full image.

The Delay node was only added to ensure that there would be enough time to close the app or send it to the background before the notification went off. When adding this to your project you do not have to use the Delay node.

Next, set the Seconds from Now input on the Schedule Local Notifications from Now node to 30 seconds. This will display the notification 30 seconds after this piece of code has been run.



Click for full image.

Set the Activation Event on the Schedule Local Notifications from Now to a value of 42.



Click for full image.

The Activation Event input enables you to associate a string value that can be used to call a specific notification. This allows you to set up and use different notifications that can be displayed when certain conditions are met.

With all of the needed nodes for Local Notifications to work now added to the Event graph, the last thing left to do is connect the False output of the Branch node to the input on the Delay node. When completed your Event Graph should look like the following image.



Click for full image.

Press the Compile button to compile the level Blueprint and the Save button to your level.

Finally, on the Main Toolbar click on the Advanced Options drop down next to the Launch icon and then select the device you want to test this on.

End Result

Once the project has been deployed to your mobile device, you should hear and see a notification pop up five seconds after your app has been opened like in the video below.

Configuration

Restoring Purchases

In-app purchases enable you to offer additional content and features to players. This can be used as a means of monetizing a free-to-play game or providing additional paid content for your game.

Configuration

See the apropriate platform-specific page below for details on configuring in-app purchases for each platform:

Using In-App Purchases on Android

Reading Purchase Information



You can read the in-app purchase information using the Read In-App Purchase Information Blueprint node (or associated C++ function call). Like most other online subsystems functions, it takes a Player Controller as input, as well as an array of your product identifiers. Note that Make In-App Purchase below takes a single identifier, while Read can process an array of information. The function returns an array of In App Purchase structs, and each element of the array can be broken out to get the name, description, price, and other data to display in your UI or use in your gameplay logic.

Completing a Purchase



To make an in-app purchase, use the Make an In-App Purchase Blueprint node (or associated C++ function call). It takes the Player Controller as input, as well as a Product Request struct. A Product Request is just the product identifier from iTunes Connect or the Google Play Developer console (in this case, match3theme_night), as well as whether or not the product is consumable.

The Make an In-App Purchase node is latent, so any gameplay behavior you want to have rely on whether the purchase succeeds or fails should use those two execution pins. They will only execute after a response has come back from the online service. The node also returns the completion status of the purchase (such as Success, Failed, Restored) and the detailed In App Purchase Information struct.

There is a non-latent version of this function (the Blueprint node will display without the clock). The exit execution pin here does not wait for a response from the online service, and you will generally want to use the latent version.

Restoring Purchases



To restore purchases, use the Restore In-App Purchases Blueprint node (or associated C++ function call). It only takes in the Player Controller, and returns an array of all the purchase information associated with that Player Controller. You can then process that array to compare against the particular Identifier (or Identifiers) that your gameplay logic needs.

Configuration

Caching your Achievements

Reading Values from your Achievements

Writing Values to your Achievements

Showing the Platform Specific Achievement Screen

Whether you are using them as goals to strive for, badges of honor, or simple story mile markers, Achievements are a great way to keep players engaged with your game.





Configuration

See the appropriate platform-specific page below for details on configuring achievements for each platform:

Using Google Play Achievements

Caching your Achievements

Cache Achievements will request from the platform's game service the list of achievements and the values the current player has for said achievements. You'll be able to use the Get Cached Achievement Value if this node returns successfully.

Note that it is a latent node, and thusly has a number of execution output pins. The top most is a "pass through," that works like any other execution output pin. The other two pins (On Success, and On Failure) will execute when the online service returns (or fails to return) a value. When the execution returns a success

In Blueprints:

The example below is from the Global Game Instance Blueprint in the Unreal Match 3 sample game. After the user logs into the device's game platform (Game Center, Google Play), we run the Cache Achievements node and actually halt execution (by not having anything execute off the top output execution pin) at this point to give the service time to return all the achievements:



Reading Values from your Achievements

The Get Cached Achievement Progress will return the progress of a given Achievement ID for the provided Player Controller, and only work if a Cache Achievements node was run earlier and returned successfully.

For iOS Game Center, this value is actually a floored float, as they store it as an integer. A float is received for Google Play Services.

In Blueprints:

The example below is from the Global Game Instance Blueprint in the Unreal Match 3 sample game. Once the achievements are cached, we run through a loop pulling achievement names, as well as their target scores, from arrays, and do a quick comparison to any offline values found. We then accept the higher value of the service or the local values:



Writing Values to your Achievements

The Write Achievement Progress will send a message up to the platform's achievement system to write a percentage (0.0% - 100.0%) based Progress to the provided achievement for the given user (Player Controller and User Tag). For "one off" achievements you will always pass in 100.0 for Progress, while for incremental achievements, you'll be passing in some lesser percentage until the user reaches 100.0 for that achievement.

For iOS Game Center, this value is actually sent as an integer, as they only have 1-100 incremental achievements. A float is sent for Google Play Services.

Note that it is a latent node, and thusly has a number of execution output pins. The top most is a "pass through," that works like any other execution output pin. The other two pins (On Success, and On Failure) will execute when the online service returns (or fails to return) a value. When the execution returns a success the Written Achievement Name, Written Progress, and Written User Tag will return non-null values equal to what you passed into the node.

In Blueprints:

The example below is from the Global Game Instance Blueprint in the Unreal Match 3 sample game. There's a loop that compares the current achievement value to the metrics required to increase that achievement, and if progress has been made, the Write Achievement event is called:



This was done because latent nodes can't be used in Functions.

Showing the Platform Specific Achievement Screen

The Show Platform Specific Achievement Screen will show the achievements of the provided Player Controller for the current platform.

In Blueprints:

The example below is from the GameOverButtons Blueprint Widget in the Unreal Match 3 sample game. When the ShowAchievements button is pressed, the game will attempt to show the achievement screen for the current platform.



Configuration

Reading from a Leaderboard

Writing to a Leaderboard

Showing the Platform Specific Leadboard

Leaderboards enable you to track and display high scores for players on a per-platform basis. This lets players compete for bragging rights and helps to build community.





Configuration

See the appropriate platform-specific page below for details on configuring leaderboards for each platform:

Using Google Play Services Leaderboards

Reading from a Leaderboard

The Read Leaderboard Integer node will request from the platform's game service (currently iOS Game Center, or Google Play Services), the value stored on the given Stat Name for the provided Player Controller.

Note that it is a latent node, and thusly has a number of execution output pins. The top most is a "pass through," that works like any other execution output pin. The other two pins (On Success, and On Failure) will execute when the online service returns (or fails to return) a value. The value of Leaderboard Value before a successful return (or if the service fails to get a response) will be 0.

In Blueprints:

The example below is from the Global Game Instance Blueprint in the Unreal Match 3 sample game. In these few nodes we're calling the Read Leaderboard Integer node for the Player Controller at Player Index 0 on the Stat Name (Leaderboard) "Match3HighScore":



Writing to a Leaderboard

The Write Leaderboard Integer node will send the given integer Stat Value to the leaderboard specified in Stat Name for the provided Player Controller.

In Blueprints:

The example below is from the VictoryScreen Blueprint in the Unreal Match 3 sample game. When the victory (or defeat) screen is shown, it will check to see if on load Unreal Match 3 was able to retrieve a high score, then if it was able to it will submit the latest high score to the leaderboard. There is some additional checking before this to see if the new highscore is more than the one that was pulled during the app startup, but even if that wasn't there, the iOS and Android leaderboard systems will only accept values greater than what they currently store.



Showing the Platform Specific Leadboard

The Show Platform Specific Leaderboard Screen will show the leaderboard specified by Category Name on the device.

In Blueprints:

The example below is from the GameOverButtons Blueprint Widget in the Unreal Match 3 sample game. When the ShowScores button is pressed, the game will attempt to show the leaderboard.



Many mobile devices have significant hardware limitations compared with desktop hardware and game consoles, especially in terms of compatibility with graphics features. To address this, Unreal Engine has an alternate rendering path for mobile devices. This rendering path uses simplified or performance-oriented models for many of Unreal's rendering features, such as shadows and textures, and it removes many unsupported post-processes. The guides in this section provide details about configuration options and features in the mobile renderer.



How to enable mesh auto-instancing on mobile.



Enabling and customizing frame pacing for mobile devices



Guidelines and best practices for how to optimize Mobile performance while getting the highest possible fidelity from Mobile HDR features

Mesh Drawing Pipeline

Testing and Optimizing Your Content

Steps

Result

Limitations

The Unreal Engine Mesh Drawing Pipeline implements a mesh auto-instancing feature that merges draw calls, which can greatly improve graphics performance. This functionality is now available for mobile devices with some additional settings configuration.

Steps

Locate the Config folder for your project and open DefaultEngine.ini.

Add the following lines:

Save your changes and close the file.

Enabling this feature will cause shaders to be rebuilt for mobile platforms. If you have Unreal Editor set to Android Preview mode, the editor will recompile shaders accordingly. Large projects may have a long iteration time.

Result

By enabling the above settings for your project, auto-instancing will be enabled for all devices. r.Mobile.SupportGPUScene enables auto-instancing on mobile devices. However, they will use the same buffer as a desktop build. Mali devices only support buffers of up to 64 kb and are unable to support this feature normally. r.Mobile.UseGPUSceneTexture will make the auto-instancing process use a texture instead of a buffer to store the required information, enabling Mali devices to use auto-instancing as well.

Limitations

In addition to the limitations mentioned for draw call merging on the Mesh-Drawing Pipeline page, there are some limitations to auto-instancing that are specific to mobile devices:

Auto-instancing on mobile mainly benefits projects that are heavily CPU-bound rather than GPU-bound. While it is unlikely that enabling auto-instancing will harm a GPU-bound project, you are less likely to see significant performance improvements from using it.

If a game is heavily memory-bound, it may be more beneficial to turn off r.Mobile.UseGPUSceneTexture and use the buffer instead, with the understanding that it will not work on Mali devices.

The effectiveness of auto-instancing is highly dependent on the exact specifications of your project. Therefore, we recommend that you create a build with auto-instancing enabled and profile it in order to determine whether you will see substantial performance gains. For more information about profiling, refer to the Performance and Profiling section.



Setting Device Profiles

Scalability

Configuration Files

Editing Frame Pacing Settings in Device Profiles

Guidelines for High Refresh Rates

Swappy Frame Pacing for Android

Controlling Frame Pacing in C++

Frame Pacing is a system that restricts an application to rendering frames at a lower framerate than a device's native refresh rate. This enables the application to prioritize consistency and stability in rendering, providing for a smoother user experience compared with letting the framerate run uncapped. In Unreal Engine 4 (UE4), frame pacing can be set on a per-device basis using the Device Profiles contained in your project's configs.

Editing Frame Pacing Settings in Device Profiles

Frame pacing can be controlled through CVars in the DeviceProfiles.ini file containing your desired devices.

For iOS devices, you can add device profiles under [/Script/IOSRuntimeSettings.IOSRuntimeSettings]

For Android devices, you can add device profiles under [/Script/AndroidRuntimeSettings.AndroidRuntimeSettings]

The parameters that control frame pacing are as follows:

Parameter

Usage

Description

FrameRateLock = [value]

FrameRateLock=True

If set to true, allows any frame pacing.

bEnableDynamicMaxFPS = [value]

bEnableDynamicMaxFPS=True

If set to true, allows 120Hz on capable devices.



Available in 4.24 and earlier



rhi.synchinterval = [value]

rhi.synchinterval = 1

Legacy variable for 4.24 and older for setting the refresh rate of frame pacing. Assumes a 60Hz refresh rate for a value of 1.



Available in 4.25 and later



r.setframepace [value]

r.setframepace 30

New method recommended for iOS and Android in 4.25. Sets the refresh rate directly to the value provided.

a.UseSwappyForFramePacing = [value]

a.UseSwappyForFramePacing=1

Set to 0 by default. Setting this value to 1 will enable Google's Swappy frame pacing solution in place of the standard UE4 frame pacer for Android devices. Swappy uses the same CVars as the UE4 frame pacer.

Guidelines for High Refresh Rates

The maximum refresh rate for frame pacing is normally capped at 60Hz, but enabling bEnableDynamixMaxFPS increases this limit to 120Hz. Mobile devices supporting refresh rates greater than 60 Hz include the following:

Samsung Galaxy S20

OnePlus 7T

Google Pixel 4

iPad Pro 2nd generation and newer

Swappy Frame Pacing for Android

In addition to the legacy frame pacing system, Unreal Engine 4.25 integrates Google's Swappy frame pacer from the Android Game SDK.

Android hardware normally uses a frame buffer to display past frames when late frame submissions are detected, which prevents screen tearing. However, games' renderers are often unaware of this process and out of synch with it, causing them to get ahead of the displayed frame. This causes the display time for frames to vary wildly and creates significant input latency with touchscreen controls, as stalls will usually occur after input has been sampled.

Swappy is an Android-specific frame pacing solution designed to stabilize this behavior, providing not only the benefits of frame pacing, but also enabling a game's render cycle and Android devices' refresh cycle to communicate more effectively. This is an alternative to the legacy UE4 frame pacer that is used for all other hardware.

Enabling Swappy

As of 4.25, Swappy is not currently the default frame pacer for Android projects in Unreal due to a need for more testing, but it nets consistently smoother performance compared to the legacy frame pacer. Enabling it is recommended, and we are planning to use Swappy as the new default frame pacer for Android in future versions of the engine.

To enable Swappy for your Android projects, add a.UseSwappyForFramePacing=1 to the Android profiles you would like to use it. You can add it to Android_Default to activate it for all Android devices.

Controlling Frame Pacing in C++

To control frame pacing in C++, you can call static functions from the FPlatformRHIFramePacer interface. Frame pace is passed as a 32-bit integer when used as a parameter in these functions.

FPlatformRHIFramePacer::SupportsFramePace checks whether the specified frame pace is compatible with the current device's refresh rate. FPlatformRHIFramePacer::SetFramePace sets the pace to a specified integer value, and FPlatformRHIFramePacer::GetFramePace returns the current frame pace.

Knowing Your Performance Budget

Common Performance Factors

Package Size and Boot Time

Analyzing Package Size on Disk

Analyzing Boot Time

This page provides guidelines and best practices for how to optimize mobile performance while getting the best possible fidelity from Mobile HDR features. This includes:

Information about what factors contribute to your performance budget on mobile devices

Best-practices for packaging projects with Mobile HDR features enabled

A walkthrough of the tools available to gauge performance bottlenecks within your Unreal Engine applications

The following links contain helpful information for regarding general performance topics on Android:

developer.android.com/topic/performance/vitals/launch-time

developer.android.com/topic/performance/vitals/render

Knowing Your Performance Budget

The target device for your application has a finite amount of resources available, both for keeping objects in memory and processing them. When building your application, you must decide what to spend those resources on. You should familiarize yourself with your device's capabilities in terms of the speed, threads, and bandwidth for your CPU and GPU, as well as your device's memory, graphics memory, and available disk space.

You should also benchmark your device to understand how it will run and where it will encounter performance bottlenecks. You can benchmark a device by running a demanding application or tech demo on it, then observing its performance stats.

Console Commands for Displaying Performance Stats

You can check performance stats using a series of console commands. To open the developer console on a mobile device, tap the display using four fingers at once. This will open an onscreen keyboard and a prompt where you can enter console commands.



The console window displayed in a mobile application.

The console and the four-finger tap command are only available in Development builds. It is not available in Shipping or Testing.

Within the console, you can enter commands to display debug information to the screen. The following table includes a list of commands that provide performance information:

Command

Description

Stat GPU

Displays the amount of time in milliseconds used by the GPU for different processes.

Some devices running Vulkan may support stat GPU, but it is not supported directly on most mobile devices.



Stat Unit

Displays the amount of time in milliseconds used by the CPU for different processes. Also displays the game thread, rendering thread, and GPU times.

Stat UnitGraph

Displays a graph showing CPU and GPU utilization over time. This can help identify spikes.

Stat TextureGroup

Displays the amount of memory used by different pools of textures.

For more console commands you can use to analyze your application's performance on-device, refer to Stat Commands.

Common Performance Factors

Now that you know where to look for performance data on your device, this section will familiarize you with the factors that most often affect performance in Unreal Engine's mobile renderers. By understanding which of these elements is impacting your application and how, you can quickly identify and address problems using Unreal Engine's diagnostic tools.

Normal Maps vs. High-Vertex Meshes

Unreal Engine's mobile renderers are efficient at rendering large numbers of vertices, whereas high-quality normal maps on mobile renderers can have issues with bit depth and have a greater performance cost than a high-polygon model.

On lower-end hardware, normal maps can greatly enhance the quality of reflections and lighting on the surface of a model. However, subtle shapes like body panels on a car can exceed the 8-bit deltas normally used for these maps, resulting in visible banding in the final render.

You can use 16-bit normal maps to compensate for this, but the pixel cost for 16-bit normals exceeds the vertex cost of a higher density mesh. 16-bit normals are uncompressed in the engine, which means they are also eight times the size of a regular normal map.

In the example below, we use high-density body panels with no normal maps. When targeting the Galaxy Tab S6, our body panels combine to about 500,000 vertices.



Best Practices for High-Resolution Normal Maps

Baking high-resolution vertices into a normal map for a low-poly model can be a complex process, and many factors can reduce the quality of a normal map texture by the time it is inside the engine. There are many tool sets for baking normal maps, but we recommend XNormal. The process we use for Xnormal is roughly as follows:

Bake the normal map in Xnormal as an 8k TIFF with 4xAA.

Import the TIFF into photoshop, then downres it to a 1k texture.

Apply a Guassian Blur with a value of .35px.

Convert the image from 16-bit to 8-bit.

Export the image to a 24-bit TGA.

Import the final normal map into Unreal.

To ensure the surface normals used in the baking process are the same as what is present in the engine, you should export the optimized normals from inside Unreal. Import the baking model into Unreal, choose to create its own normals, then export the baking model from Unreal to be baked in Xnormal. This is an important step when creating high quality normal maps, as Xnormal needs to be aware of the surface normals of the mesh to apply the offsets from the high resolution model.

Finally, there are two options that will reduce artifacts when rendering static meshes:

Use Full Precision UVs

Use High Precision Tangent Basis

Both of these settings are available in the Static Mesh editor, in the Details panel under the LODs.



Draw Calls

Draw calls are lookups for assets, which happen every frame. The number of draw calls your application uses depends on the number of unique meshes in your scene, as well as the number of unique material IDs each mesh is using. Currently, a high number of draw calls are the biggest contributor to low graphical performance, and you should reduce them as much as possible.

As an example, a highly optimized car model might only have five or six separate meshes, and each one of those components might only have a single material.

A good target for draw calls in an optimized scene is roughly 700 on a Galaxy Tab S6, and less than 500 on lower-end hardware. In projects for HMI, which tend to use highly unique or complex materials, 100 draw calls would be a good target on a Galaxy Tab S6, while less than 50 would be preferable.

You can output your draw call count with the console command Stat RHI.

Keep in mind that draw call count will change based on whether you are in PIE or on device. |

The easiest way to reduce draw calls is to reduce the number of unique meshes in your world. You can do this by combining as many objects as possible into one mesh using a digital content creation (DCC) toolset, such as Maya, 3DSMax, or Blender, before importing them to Unreal.

There are several possible options for reducing the number of unique materials on a mesh.

The simplest method is to use a program like Substance Painter, which integrates multiple materials into the same texture. This enables you to take advantage of a vast number of material types in a very simple Unreal material, which you can then use as the basis for material instances with simple texture inputs. This can also reduce material instruction counts, which further improves performance.



Click for full view

The second method uses masking for a more procedural approach. Materials can denote certain characteristics of a surface, like color, roughness, or metallic qualities. Instead of using a separate material for different parts of a mesh, you can use masks to separate parts of a mesh's UVs and apply different settings to each section. You can create a basic mask using a black and white texture, but it is more efficient to use vertex color.





In the example below, vertex colors are used to define different material types, and the material defines parameters which can influence the look of those pieces individually. Vertex color masking is more efficient and creates a sharper separation, as it does not rely on texture resolution.



A material using vertex colors to separate different material types.

Materials

Material complexity can increase the pixel cost of a render. The more instructions there are for each pixel, the more time the render needs to spend calculating its final value. Opaque materials are the least expensive, but can differ greatly based on the shading model or the base shader code.

You can find a readout on the instruction count of a material in the Stats window inside the Material Editor.



The Stats window displaying instruction count. Click for full view.

The instruction count will also increase depending on the number of math functions there are in a material. The more nodes there are, the more expensive the material will be to render. Some specific operations also have a higher cost. Try to limit the instruction count when building more complex materials.

Translucent and transparent materials are some of the most expensive material types. Individual layers of translucency have an expensive per-pixel cost, and when multiple layers of transparency are stacked and rendered, there is a much greater cost. This is known as overdraw.

Headlights and taillights for vehicles are examples of problem areas with transparency. In many cases, we use hand-painted texture maps instead to reduce material complexity. Complex shapes and depth can be illustrated well, even with a flat texture.



Optimizing Texture Resolution

High-resolution textures require a lot of space, both to store on a device and in a device's texture memory, and larger textures require more pixels to render and process. While they can increase fidelity, there are diminishing returns to texture size given your device's screen resolution and the viewing angle of the texture. It is important to use the smallest texture possible to obtain the desired level of fidelity.

To determine your texture needs, first you need to finalize the camera location and the field of view (FOV) from which you will view your model. This will help determine the screen space of all the meshes and materials.

Once a camera location is determined, you can use a special debug texture to determine the texture resolution to use for the various materials. This texture uses the behavior of mipmaps to determine what resolution is necessary for different components, applying different colors in each mipmap. This makes it easy to identify which mip the material is using, and what texture resolution should be used.

Plug the included texture into the Emissive channel of an unlit material, then apply that material to your mesh. When viewing the mesh from the proper camera distance, the color coding will indicate which mip level the engine is using to render. The highest level observed should be the native texture size of your Normal and Ambient Occlusion maps.



Package Size and Boot Time

When packaging an application and its assets, there is a tradeoff between package size on disk and runtime bootup performance.

When ZLib compression is enabled, the package size of your application will be smaller. However, this requires more CPU time loading the application, which can slow down bootup speed. For optimal boot time, you can disable compression.



You can find Zlib compression settings in Project Settings > Packaging. Click for full view.

Recommended Streaming Settings

The following streaming settings are recommended in DefaultEngine.ini. These provide extra time at the start of an application for asynchronous loading of assets, which can improve startup time.

Recommended Packaging Settings

The following packaging settings are recommended in DefaultEngine.ini. These settings reduce the amount of compression being utilized when packaging assets, as uncompressed .pak files load significantly faster than ZLib compressed files on startup.

Analyzing Package Size on Disk

Unreal Engine features several useful tools that can provide insight into the data footprint of assets.

Size Map

The Size Map reads and compares the relative memory consumption of assets in the editor. To use it, you must enable the AssetManagerEditor plugin. After that, you can access it by right-clicking on a folder in the Content Browser and selecting Size Map from the context menu.



The Size Map displays a window with icons representing the amount of memory that folders and files consume. The larger the icon, the more space a file consumes.



For more information about using the Size Map, refer to Cooking and Chunking.

The Size Map reads the footprint of assets as they are used within the editor. After you package your project, memory consumption will be different. This is due to the different types of compression which happen during the cook process. As a rule of thumb, the size map will represent the largest possible size that an asset could take up.

Statistics

The Statistics tool offers more detailed information about asset usage within a level. You can locate it in the Window dropdown.



The Statistics window breaks down the number of assets in your level files, and can display either all levels or only specific levels. Primitive Stats lists information about the number of triangles, memory consumption, and count.



The Statistics Window displaying Primitive Stats.

Other data displayed in this list includes texture usage and static mesh lighting information. The Statistics window's list mode can quickly illustrate which assets are consuming the most memory. The Cooker Stats data is also extremely useful as it lists all the assets which were cooked in the last package process.

Memory Reports

While the Statistics and Size Map tools show you the data footprint of your files inside the Unreal Editor, the console command Memreport -full can be used from an installation of your application launched on a target device. This provides a detailed and accurate look at your files' size as they will exist with your device's compression settings.

Once the app is built in Development configuration and loaded to the device, you can pull up the console window and enter the command. This memory snapshot is saved within the project's directory, on the device. The directory will usually be Game/[YourApp]/[YourApp]/Saved/Profiling/Memreports/, but this can vary.

The .memreport file is a text file which can be read in most text editors. The beginning of the text includes some information about the allocated memory and pool sizes, while the bulk of the text shows a record of what levels were loaded, RHI stats, render targets, scene information, and more. All of this information is valuable as it represents the actual data which made it through the cooking and packaging process.

If you search for the term Listing all textures, you will find a list of every texture in your application, along with detailed information about the texture type, group, size, and memory footprint. The list is sorted by memory size, with larger textures presented first. This is a quick and easy way to spot what textures are consuming the most memory.

Analyzing Boot Time

The factors that affect boot time include the following:

The amount of time required to load and decompress initial assets

The overall size of your application

Any plugins that need to be activated in your user's installation

The amount of string data that needs to be parsed

Any memory allocation or fragmentation on the user's device

There are several different tools available to analyze your application's boot time, but Unreal Insights is the most recommended, as it can profile performance data remotely from a target device. For full information about this toolset, refer to the Unreal Insights section.

Getting Started

iOS and tvOS for Windows Users

Development Guides

Packaging and Publishing

Debugging

Optimization

Unreal Engine supports publishing to iOS and tvOS devices. Developing for these platforms requires some specialized setup, as a machine running MacOS is required to make signed builds for C++ projects in Apple's ecosystem, and you need to use Xcode to debug builds on iOS and tvOS devices. This section will provide guides on how to use these tools, how to streamline your workflow if your team primarily uses Windows, and how to make the most of iOS and tvOS's features. Additionally, although iOS and tvOS's workflows are mostly the same, these guides cover the handful of differences between them.

Getting Started



Set up an Unreal Engine project for iOS, tvOS, or iPadOS.



Create a Provisioning Profile and Signing Certificate so you can package iOS, iPadOS, and tvOS applications.



Set up your testing and debugging pipeline for tvOS connecting over a local area network.

iOS and tvOS for Windows Users



How to remotely compile on a Mac from a Windows machine to create an iOS build.



Use the Windows Metal Shader Compiler for iOS

Development Guides



Guidelines for working with external input devices in iOS, tvOS and iPadOS 14 and later



Identify strings in your project code that need to be translated.



Setting up launch screen storyboards in your Unreal Engine projects for iOS



Using iOS Game Center Achievements to increase player engagement.

Packaging and Publishing



Apple Arcade requires support for both ARM64 and x86-64 architectures on Macs. Learn how to support Macs with both of these architectures, and how to create merged binaries for Apple Arcade.



Learn how to package iOS Projects in Unreal Engine

Debugging



Download and read iOS and tvOS logs and crash reports either directly from device or from TestFlight.



Use Xcode to launch your project on device and debug with break points and LLDB commands.



Replicate inputs from an iOS device on your PC for testing.

Optimization



Factors that affect the size of a packaged iOS game.

Current Development Requirements

Current SDK Information

Current Compatible Devices

Apple Silicon Support

Version History

This page contains the software development kit (SDK) requirements needed to develop Unreal Engine (UE) projects for iOS, iPadOS, and tvOS devices, as well as compatible hardware for the current version of UE.

Current Development Requirements

Current SDK Information

Current UE Version: 5.1

Supported Target SDK versions: iOS 15 or later

Recommended MacOS and Xcode Versions

Latest MacOS 13 Ventura

Latest Xcode 14

Minimum MacOS and Xcode Versions

MacOS 12.x Monterey

Xcode 13.4.1

Current Compatible Devices

UE 5.0 supports iOS, iPadOS, and tvOS devices that support version 14 and higher for their respective SDKs and use an Apple A8 processor or later. The following are the minimum compatible device models:

iOS 15

iPhone 6S or later

iPod Touch 7th generation

iPadOS 15

iPad 5th generation or later

iPad Air 2* or later

iPad Mini 4* or later

iPad Pro (all models)

tvOS 15

Apple TV HD*

Apple TV 4K (first generation)

Apple TV 4K (second generation)

*Apple A8/A8X-based devices (iPad Air 2, iPad Mini 4 and Apple TV HD) require a project setting for support to be enabled.

Apple Silicon Support

In UE 5.1, Unreal Editor when you build a project in Xcode on an Apple Silicon device, it is automatically set to compile with native Apple Silicon support for both editor and standalone builds. However, ARM64 support for Unreal Editor is experimental, as some Unreal Marketplace plugins and third-party libraries do not have ARM64 support yet. To build your editor for x86 instead, change your target device from My Mac to My Mac (Rosetta).



For information about supporting devices using an M1 chip or later, refer to Supporting Universal Binaries for Apple Arcade.

Version History

UE Version

Supported MacOS Versions

Xcode Version

iOS, iPadOS, and tvOS SDK Version

Supported iOS Devices

Supported iPadOS Devices

Supported tvOS Devices

Notes

5.1

MacOS 12.x Monterey

Latest MacOS 13 Ventura

Xcode 14, Xcode 13.4.1

OS version 15 or later.

iPhone 6S or later

iPod Touch 7th generation

iPad 5th generation or later

iPad Air 2 or later

iPad Mini 4 or later

iPad Pro (all models)

Apple TV HD

Apple TV 4K (first generation)

Apple TV 4K (second generation)

Apple Silicon support is available for shipped projects, but experimental for Unreal Editor in 5.1.

5.0

MacOS Catalina 10.15.7

MacOS Big Sur 11.6.4

Latest MacOS 12 Monterey

Xcode 13, Xcode 12.4

OS version 14 or later.

iPhone 6S or later

iPod Touch 7th generation

iPad 5th generation or later

iPad Air 2 or later

iPad Mini 4 or later

iPad Pro (all models)

Apple TV HD

Apple TV 4K (first generation)

Apple TV 4K (second generation)

Xcode 12.4 is supported, but Xcode 13 is required to test locally on iOS 15 devices.

1. Requirements

2. Software Setup

3. Creating Your Project

4. Connecting Your Device With Xcode and Registering it With Your Apple Developer Account

5. Provisioning and Signing

6. Packaging Your Project

Final Result

This quick start guide explains all the steps required to build an Unreal Engine project for Apple's iOS, iPadOS, and tvOS platforms. By completing this guide, you will:

Set up Xcode on your Mac.

Connect to your device in Xcode.

Register your device with your Apple Developer account.

Create a Provisioning Profile and Certificates for your project.

Configure your project for iOS.

Build and run your project on an iOS device.

This guide covers creating signed builds for C++ projects. For Blueprint-only projects on Windows, there is an alternate workflow for building iOS projects. Refer to Packaging iOS Projects for more information.

Additionally, while this guide refers to iPhone and iOS as an example, note that the same setup steps are used for tvOS. To connect to a tvOS device, refer to the Connecting to a tvOS Device page.

1. Requirements

To build projects for Apple's platforms, you need the following:

A computer running MacOS with Unreal Engine installed.

An installation of Xcode that is compatible with your current version of Unreal Engine.

An Apple Developer Account.

An iOS device that is compatible with your current version of Unreal Engine.

The following software versions are compatible with the current version of Unreal Engine:

Current UE Version: 5.1

Supported Target SDK versions: iOS 15 or later

Recommended MacOS and Xcode Versions

Latest MacOS 13 Ventura

Latest Xcode 14

Minimum MacOS and Xcode Versions

MacOS 12.x Monterey

Xcode 13.4.1

The following iOS hardware versions are compatible with the current version of Unreal Engine:

iOS 15

iPhone 6S or later

iPod Touch 7th generation

iPadOS 15

iPad 5th generation or later

iPad Air 2* or later

iPad Mini 4* or later

iPad Pro (all models)

tvOS 15

Apple TV HD*

Apple TV 4K (first generation)

Apple TV 4K (second generation)

*Apple A8/A8X-based devices (iPad Air 2, iPad Mini 4 and Apple TV HD) require a project setting for support to be enabled.

For software compatibility information about older versions of Unreal Engine, refer to the iOS Development Requirements page.

2. Software Setup

If you do not already have Xcode installed on your Mac, download and install it from the App Store. You will need to sign in with your Apple ID.



Open Xcode. In the toolbar, open Xcode > Settings.



Open the Locations tab, then verify that the Command Line Tools path is set to the current version of Xcode. If this path is not set, you will not be able to open Unreal Editor, as the Metal shader compiler will not be able to find Xcode.



3. Creating Your Project

To set up a Mobile project, open Unreal Editor and create a new project with the following specifications:



Click image for full size.

Open Unreal Editor. When the Unreal Project Browser appears, click Games.

Configure your project as follows:

Project Template: Top Down

Target Platform: Mobile

Quality Preset: Scalable

Project Name: MobileTestGame

You can create a project that uses either Blueprint or C++.

Click Create to create the project and open it in Unreal Editor.

The above specifications and project name are from the Creating a Mobile Project guide. Refer to that page for more details on these specifications.

4. Connecting Your Device With Xcode and Registering it With Your Apple Developer Account

To use your iOS device for testing, you need to connect it to your computer, make sure it is recognized by Xcode, and register it in your Apple Developer Account as a testing device for your apps. The device registration will be used later for creating a Provisioning Profile. Follow these steps to set up your device:

Connect your iOS Device to your computer with a USB cable.

Open Xcode, then click Window > Devices and Simulators.

Unlock your device to grant Xcode access to it. When you see the Trust This Device prompt on your iOS device, click Yes, then provide your passcode. Xcode will fetch debug symbols for the device.

Log in to your Apple Developer account at developer.apple.com. If you do not have an Apple ID and a developer account, create one.

While Epic's software is available free of charge, Apple Developer accounts cost a fee of $99 per year. Keep this in mind when registering your account.

Once you have logged in, click Certificates, Identifiers & Profiles.

Click Devices, then click Register a Device.

Fill out the following information about your device:

Set the Platform to iOS, tvOS, watchOS.

Set the Device Name to a unique, recognizable name.

Look at the information about your device in Xcode in Window > Devices and Simulators. Copy the Identifier, then return to the Register a Device page and paste it into the UUID field.

Click Continue when you are finished.

Double-check that the information about your device is correct. If you input the wrong UUID, you may see the wrong type of device listed. Click Register to finish registering your device with your Apple developer account. When registration is complete, click Done.

5. Provisioning and Signing

The following is a short summary of how to obtain a Code Signing Certificate and Provisioning Profile for your app, which are required to package an iOS project. For fully detailed steps, refer to the



Connect your Apple Developer ID with Xcode in Xcode > Preferences > Accounts.

Create an Identifier (App ID) for your app. Provide a Bundle Identifier name with the format com.(OrganizationName).(ProjectName). In this example, the Bundle Identifier is com.YourCompany.MobileTestProject.

Open your project's Xcode project file, then make sure it has the same Bundle Identifier as you specified for your App ID. Do the same in Unreal Editor in Project Settings > Platforms > iOS.

Under Signing & Capabilities, enable Automatically Manage Signing, then set your Team to the name associated with your Apple Developer account. Xcode will automatically generate a code signing certificate. Alternatively, you can create one manually in the Certificates, Identifiers, and Profiles section of the Apple Developer Page.

Open the Apple Developer page, then open Certificates, Identifiers, and Profiles. Create a new Provisioning Profile using your Identifier, your registered device, and your signing certificate. Download it to a convenient location, such as a Provisioning folder.

Go to the Apple Certificate Authority Page and download the latest WWDR Intermediate Certificate. Open the Keychain Access app and drag the certificate into the System keychain. This is not necessary to package your project for testing, but it is necessary for shipping.

Open your project in Unreal Editor, then open Project Settings > Platforms > iOS. Give the editor a few moments to discover your Provisioning Profile and your Signing Certificate, then select each of them.

6. Packaging Your Project

After completing the above sections, click the Platforms dropdown, then click iOS > Package Project. If all of your components are set up correctly, your project will package successfully. You can also use the Quick Launch option to launch on your selected device directly.

Final Result

After following the steps in this guide, you will have an iOS project set up, ready to launch on your test device,

iOS Quick Start Guide

Connecting to tvOS Devices

Building for iOS on Windows

1. Overview and Requirements

2. Connecting Xcode With Your Apple Developer Account

3. Creating Your Identifier (App ID)

4A. Creating a Code Signing Certificate from Xcode

4B. Generating a Signing Certificate Manually

6. Creating a Provisioning Profile

7. Adding Your Provisioning Profile and Signing Certificate to Unreal Editor and Sharing Them With Your Team

8. Packaging Your Project

Final Result

Appendix A: Obtaining an Apple Worldwide Developer Relations (WWDR) Certificate

Appendix B: Additional Build Options

To publish iOS, iPadOS, and tvOS games, you need a Code Signing Certificate identifying you as a valid Apple developer, as well as a Provisioning Profile identifying the services and permissions needed for your app. While Xcode automatically manages this process for building code, you need to provide these manually in your Unreal Engine project settings so that the Unreal Engine build system can cook and package a project. This guide will explain all the steps needed to set up valid Certificates and Provisioning Profiles.

This guide covers the full setup for building Unreal Engine C++ projects with MacOS and Xcode. While you need a MacOS machine with Xcode to build your project to ship on the app store, Unreal Engine provides several other paths for building iOS apps for development and testing purposes, including paths for working on Windows. Refer to Appendix B: Additional Build Options for more information.

1. Overview and Requirements

To build and distribute an Unreal Engine project for an iOS, tvOS, or iPadOS device, you need the following requirements:

A computer running MacOS.

An installation of Xcode that is compatible with your current version of Unreal Engine.

An Apple Developer Account.

An Unreal Engine Project.

Refer to the iOS, iPadOS, and tvOS Development Requirements page for more information about the MacOS and Xcode versions required for use with the current version of Unreal Engine. Refer to the iOS Quickstart Guide guide for instructions about how to set up Xcode to work with Unreal Engine.

You need an Apple Developer Account to create code signing certificates and provisioning profiles. If you do not already have one, visit developer.apple.com and create an Apple ID and a Developer Account.

While Epic's software is available free of charge, Apple Developer accounts cost a fee of $99 per year. Keep this in mind when registering your account.

Finally, you need to do the following on your Apple Developer Account:

Connect Xcode with your Developer Account.

Create an Identifier (App ID) for your app.

Create a Provisioning Profile for a deployment of your app.

Create a Signing Certificate identifying yourself as the creator of your app.

Register your iOS device with your account.

Once you have each of these components, you need to download the Provisioning Profile and Signing Certificate and add them to your Project Settings. After that, you can package projects and push them to your device. The sections below will detail each of these steps.

2. Connecting Xcode With Your Apple Developer Account

To make sure your Certificates and Provisioning Profiles are recognized correctly, connect Xcode with the Apple ID for your Apple Developer Account.

Open Xcode, then click Xcode > Preferences.

Click the Accounts tab.

Click Add (+) to add an account. Provide the information for your Apple Developer Account.

3. Creating Your Identifier (App ID)

All iOS apps require an Identifier with a Bundle ID. Your Provisioning Profile references this information in a later step. To create an Identifier, follow these steps:

Login to your Apple Developer Account.



Click Certificates, Identifiers, and Profiles.



Click Identifiers, then click Register an App ID.



Select App IDs and click Continue.

Select App and click Continue.

In the Register an App ID menu, fill in your Description and Bundle ID. The Bundle ID should be a reverse-domain string taking the format com.(OrganizationDomainName).(AppName). In this example, the app is called com.YourCompany.MobileTestGame.

Take note of the application name you provide for the App ID, as this information must match the name of your Unreal Engine project. You also need the Bundle ID to match in both your Xcode project and the Project Settings in Unreal Editor.

Select any permissions and services your app needs, then click Continue.

Confirm that all your settings are correct, then click Register.

4A. Creating a Code Signing Certificate from Xcode

If you have connected Xcode with your Apple Developer account, you can generate a Development Certificate automatically with these steps:

Open your project's solution in Xcode, then select your project in the navigation panel. This will display the project's settings.

In the General settings, provide your project's bundle identifier. This should be a reverse-domain style string reading com.(OrganizationName).(ProjectName). In this example, it reads com.YourCompany.MobileTestGame.

Click Signing and Capabilities. Set the Team to the name given by your Apple Developer profile.

Enable Automatically Manage Signing. Xcode will connect with the Apple Developer site and generate a Code Signing Certificate for Development.

This Certificate will only be available on the Mac you configured it on, and it will only be usable for development, not shipping. Refer to [Generating a Signing Certificate Manually(#4B.GeneratingASigningCertificateManually) to create a Certificate that is usable by your team.

4B. Generating a Signing Certificate Manually

Development Certificates generated by Xcode make it possible to deploy your project for testing, but to ship your project you may need to create a Signing Certificate that is configured for distribution on the app store. You may also need to create a Certificate that is usable by your team on other devices. Follow these steps to manually create a Certificate with your Apple Developer account:

Open the Keychain Access app. Click Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority.

In the Certificate Information dialog, provide your Apple Developer Email address and your name. Click Continue, then save the signing request to a convenient location, such as the desktop.

Open the Apple Developer Page. In the Certificates, Identifiers, and Profiles menu, click Certificates, then click Create a Certificate.

Select iOS App Development, then click Continue. If you are creating a certificate to ship your app, you need to use iOS Distribution (App Store and Ad Hoc) instead.



Click Choose File, then select the Certificate Signing Request file you generated. Click Continue to generate your Certificate.

Download the Certificate and open it to add it to your System Keychain.

6. Creating a Provisioning Profile

Your app's Provisioning Profile ties together your identity as an Apple Developer and information about your test devices with information about the app itself. To create a Provisioning Profile, follow these steps:

In the Certificates, Identifiers & Profiles menu on the Apple Developer page, click Profiles, then click Generate a Profile.

Select iOS App Development, then click Continue.



This page uses an iOS app as an example, but you can select the provisioning profile type that is appropriate to your target device. For example, if you are creating a tvOS app, choose tvOS App Development.

Click the App ID dropdown and select the App ID you generated in the previous section, then click Continue.



Choose the Signing Certificate for Development that you generated in the previous section, then click Continue.

If you need to share your Signing Certificate and Provisioning Profile with your team, create a Certificate manually.

Choose your registered device as a test device, then click Continue.

Provide a Provisioning Profile Name. In this example, the profile is called MobileTestGame_Development. Click Generate.

Download the Provisioning Profile and place it in a convenient location. Click and drag it onto the Xcode app icon in your dock to install it.

7. Adding Your Provisioning Profile and Signing Certificate to Unreal Editor and Sharing Them With Your Team

Xcode does not need a Provisioning Profile to build code if you have it set to automatically manage code signing. However, Unreal Engine's build system and the iPhone Packager need to refer to your Provisioning Profile and Signing Certificate to cook and package your project's executable for iOS.

Follow these steps to provide them in Unreal Engine's project settings:

Place your Provisioning Profile and Signing Certificate in a folder somewhere in your Unreal Engine project's directory. In this example, they are both placed in MobileTestProject/Provisioning. This will not interfere with any build processes, but it will make it possible to add your Provisioning profile and Signing Certificate to your version control system so that you can share them with your team.

Open Unreal Editor, then open Project Settings > Platforms > iOS. Make sure your Bundle Identifier is set to the same name as in both Xcode and your Apple Developer Account.

Wait for a moment for the editor to discover your Provisioning Profile and Signing Certificate. If the entries for your Provisioning Profile and your Certificate both turn green, they are recognized as valid profiles and will be used automatically. You can select the check box to manually set them as well.

You can perform the steps in this section on a Windows machine for Blueprint-only projects and remote builds.

The Signing Certificate you select in your Project Settings must match the one used to generate your Provisioning Profile, otherwise your project will fail to package.

If you are using a Signing Certificate generated by automatic code signing in Xcode, it will appear in your Project Settings automatically. However, it will not be available on other computers. You should manually create a Certificate if you want to share it.

8. Packaging Your Project

Click Platforms > iOS > Package Project to package for iOS. If all of your settings are correct and your Provisioning Profile and Signing Certificate are both valid, you create an iOS build.

Click the Platforms dropdown again. If your iOS device appears in the Quick Launch options, select it to deploy a build directly to your device.

Final Result

After following the steps in this guide, you have all the needed components to build and distribute iOS projects. When you need to create a Provisioning Profile for testing or shipping, refer to this guide again and configure your Identifier, Certificate, and Provisioning Profile accordingly.

Appendix A: Obtaining an Apple Worldwide Developer Relations (WWDR) Certificate

Apple requires an Apple Worldwide Developer Relations Certificate to build apps. This should be provided by Xcode automatically, but in some situations, you may need to manually install it on your Mac.

Go to the Apple Certificate Authority Page and download the latest WWDR Intermediate Certificate.

Open the Keychain Access app and drag the certificate into the System keychain.

Appendix B: Additional Build Options

The steps in this guide are for the full Signing and Provisioning process needed to distribute an app. There are several other options available during development and testing:

Blueprint-only iOS projects do not need to go through the Signing and Provisioning process to package builds or push them to devices for testing – you can package them directly out of the box. This path will also work on Windows. Refer to Building for iOS on Windows for more information.

Because most teams using Unreal Engine use Windows machines for development, a remote build process is available. This will create a secure connection with a MacOS device and have it automate a build. Refer to the Building for iOS on Windows guide for more information.

iOS Quick Start Guide

Debugging iOS Projects With Xcode

Connecting a tvOS Device

AppleTV devices use similar methods for launching and debugging projects in Xcode as iOS devices. However, because recent tvOS devices do not have a USB port, you need to use your local area network to access them instead. This page will show you how to set up a tvOS device so that you can connect to it using either Unreal Editor's Device Manager or Xcode.

Connecting a tvOS Device

Ideally, both Unreal Editor's Device Manager and Xcode should recognize your tvOS device automatically over the local area network. Follow this checklist to ensure that it is visible to your computer:

Make sure your tvOS device is connected to your local network with an Ethernet cable. While it is possible to connect to an Apple TV with WiFi, Ethernet connections are more stable and reliable.

In Unreal Editor, from the main menu, select Window > Developer Tools > Device Manager.

In the Device Manager window, verify that your tvOS device is visible.

If your tvOS device is not visible, click Connect to IP, then type in the IP address of the Apple TV.

Once your Apple TV is visible in the Device Manager, you can follow the same workflows for launching and debugging projects as iOS devices.

Although iOS and tvOS require a MacOS machine to make signed builds for C++ projects, Unreal Engine has several tools to make it easier to work on iOS projects when working on a Windows machine. This makes it easier for teams with mixed machines and cross-platform development needs to collaborate with users that work primarily in MacOS.



How to remotely compile on a Mac from a Windows machine to create an iOS build.



Use the Windows Metal Shader Compiler for iOS

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Provisioning Profiles and Signing Certificates

Blueprint-Only iOS Projects on Windows

Creating a signed build for iOS requires a Mac and an Apple Developer account. However, for teams that primarily use Windows machines, Unreal Engine 4 (UE4) can establish an SSH connection between a Windows PC and a Mac to create iOS builds remotely. This requires you to allow incoming SSH connections on your Mac, and then you need to set up the SSH key and credentials to access the Mac on your Windows machine. This guide will walk you through this process.

Blueprint-Only iOS Projects on Windows

If you are creating a Blueprint-only iOS project, you do not need to use the full remote-build process detailed in the sections below. Instead, you can use your Windows machine to create your iOS build directly, provided that you have set up your iOS developer certificate and provision profile in the editor. However, if you add C++ code to your project in the future, you will need to follow the steps on this page.

For information on how to sign your build, refer to our guide on iOS Provisioning.

1. Required Setup

To use iOS remote builds, you need at least one Mac capable of building your iOS project, as well as at least one Windows PC. Both machines must have an internet or local area network connection, and both must have the same UE4 project.

Your Windows machine must have iTunes installed to ensure you have the necessary binaries for iOS projects. We recommend that you download and install iTunes from Apple's web site rather than from the Windows Store, as the Windows version includes extra binaries that sometimes interfere with the remote-build process. To obtain iTunes directly from Apple, scroll down to the section labeled "Looking for other versions?" and click Windows.



Your Mac must have your iOS Developer Certificates installed to the System Keychain, and you must set up your Provisioning Profile for your project, per the iOS Provisioning setup.

Once you have set up your Mac to create builds for your project, you should run a build directly on that machine at least once to ensure that it works before proceeding to the next section.

Setting Bash as the Default Shell Scripting Language on Your Mac (4.26 and Earlier)

As of January 2021, Apple has changed the default shell scripting language from to zsh, which sometimes creates errors launching Unreal Engine builds on iOS. If this happens, the output logs will contain the zsh and rsync errors similar to the following:

If you experience this issue, follow these steps to set bash as your default scripting language instead:

Open the Apple Menu, then click System Preferences.

Open Users & Groups.



Click the lock icon, then enter your account name and password.

Control-click your user name in the list of users, then choose Advanced Options.



Click the Login shell dropdown menu, then set your shell to bin/bash instead of bin/zsh.



If you package and launch your application again with these settings, it should successfully launch.

These steps apply to Unreal Engine 4.26.0 and earlier. Future releases will support zsh.

2. Enabling Remote Login On Your Mac

Once you have set up your project, you will need to configure your Mac to allow SSH connections.

Open your Mac's System Preferences, then navigate to Sharing.



Check the box for Remote Login.



Open System Preferences > Network.

Note the computer's IP Address. You will need this for setting up the remote connection on your Windows PC.



Once you have completed these steps, your Mac will be able to accept an incoming SSH connection from your PC.

3. Windows Configuration and Generating Your SSH Key

Complete the following steps on your Windows machine to configure it for remote iOS builds.

Open your project in Unreal Editor, then open Project Settings.



Navigate to Platforms > iOS > Build.



In the Remote Server Name field, enter either the name of the Mac you are using to build the project, or its IP address.

In the Remote User Name field, enter the username that you would normally use to log in to the Mac.

Click Generate SSH Key. This will open a Command Prompt window with a series of prompts that will generate the SSH key.



If you receive a message that your host could not be authenticated, enter "yes" in the prompt to continue.

Enter the password that belongs to the user you specified in Remote User Name in the previous section.

The prompt will ask you for a passphrase. If you choose not to enter a passphrase, you can use the remote connection without requiring any user interaction.

When prompted, enter the password and username for the Mac again to complete the process.

Now that you have generated an SSH key, you will be able to start a remote connection on your Windows machine to your Mac for creating iOS builds.

Workaround For Unprotected Private Key

You might see an error that reads as follows:

If you do not see this error, you can proceed with the next step (Optional Team Setup). If you do see this error, use the following steps to resolve it:

Navigate to your RemoteToolChainPrivate.key.

Right-click the file and select Properties.

Click the Security tab.

Click Edit.

Remove all group or user names.

Click Add.

Click Object Types. Make sure all boxes are checked, then click OK.

In the text box, type Users, then press Enter.

Make sure that permissions for Users are set to Read and Read & Execute.

This will change the file's primary group so that it is not the same as your username, which is what confuses SSH when it checks group permissions. The process should then work as normal.

SubInACL could previously be used for this purpose, but is no longer available from Microsoft.

4. Optional Team Setup

To share this data for other projects in the future, specify the Remote Server Name and Remote User Name in one of the *Engine.ini files on your computer.

Select the button next to the Remote Server Name property to open the Configuration Editor.



Set the properties for each individual .ini file for which you want to share the SSH data.



Repeat these steps for Remote User Name.

By sharing these .ini files, you can keep the SSH information available for multiple projects or users. The SSH keys themselves are stored in the Engine/Build/SSHKeys folder. You can check this directory into your source control system to share them with your team.

5. Final Result

After completing the above steps, you can initiate a remote build by clicking File > Package Project > iOS in the Unreal Editor on your Windows machine. A SSH connection and send the command to your Mac to begin making a build.

Steps

Final Result

Unreal Engine can compile shaders for Apple's Metal API on a Windows machine, greatly simplifying the workflow for iOS applications. To enable this functionality, you need to install Apple's Metal Developer Tools for Windows. Unreal Engine will automatically use this toolset once it is set up.

Steps

To install Metal Developer Tools for Windows, follow these steps:

Sign in to your Apple Developer Account in your web browser, then navigate to the Downloads section.

In the tabs on the upper-right of the Downloads page, click the Release tab.



In the Software Downloads page, click the Applications button.



Scroll down the page until you find the entry for Metal Developer Tools for Windows, then click the Download button to download the installer.



The download entry for the Metal Developer Tools for Windows. Click to enlarge image.

Run the installer to install the Metal Developer Tools.

Final Result

Once you have completed setup for the Metal Developer Tools for Windows, your Windows installation of Unreal Engine will be able to compile shaders for Metal 2.0. No additional setup is required.

Obtaining Gamepad Button Glyphs

In iOS, tvOS, and iPadOS 14 and later, Apple supports a wide variety of input devices, including gamepads, keyboard, mouse, and trackpad. This includes the ability to remap gamepad buttons for Xbox, PlayStation, and MFi gamepad controllers at the OS-level. The OS provides handling for the button glyph displays for these devices, enabling applications to obtain glyphs that are accurate to users' custom mappings. This is required for all apps targeting OS version 14 and later.

Apple requires that your in-game button displays must be accurate to the user's OS-level input bindings. The App Store and Apple Arcade may reject your Apps for distribution if you do not comply with this requirement.

Unreal Engine supports input handling, enabling your applications to take full advantage of the expanded range of devices. As long as users correctly connect their input to their Apple device, no additional setup is required to use this functionality. However, functionality is included to assist in complying with Apple's requirements for the UI.

Obtaining Gamepad Button Glyphs

Use the Get Gamepad Button Glyph node in Blueprint to retrieve glyphs accurate to your users' mappings.



The Get Button Glyph node, with the text Gamepad_Facebutton_Top provided in the Button Key field.

Its parameters are as follows:

Parameter

Type

Description

Button Key

String

The FKey name for the intended button, as defined in InputCoreTypes.h, converted to a string.

Controller Index

Integer

The index of the connected controller that you want to fetch button glyphs for.

Return Value

Texture2D

A 2D texture containing the button glyph to use in your UI widgets.

As an example, if you wanted to obtain the button glyph for the top face button on a controller, you would use the string Gamepad_Facebutton_Top.

When requesting buttons like this, you should request the button that you expect the user to use based on the default mapping. If the user has remapped the buttons within the OS, the function will automatically return the re-mapped button they're using instead. For instance, if the user swaps the X and Y buttons on an Xbox controller, Gamepad_Facebutton_Top would return the X button glyph instead of Y.

Steps

End Result

Localization files can be added to Unreal Engine to identify and translate strings in an iOS projects code.

This document describes how to set up string translation through the creation of localization files and folders.

Developers are required to add localization files for at least one language prior to submitting their iOS project.

Steps

Create a Localizations folder in the Unreal Engine project directory (if one does not already exist) under the following path: {UEProjectDir}/Build/IOS/Resources/Localizations/.

Navigate to the Localizations folder and create one folder per language. These folders must be named according to the following format: {LanguageCode}.lproj. For example, an English language localization folder should be named EN.lproj, where EN is the language code for English.

Localization folders must be named using the language's two-character code as listed in the ISO 639-2 standard.

In each language folder create a text file named InfoPlist.strings. This file is used to translate strings listed in the info.plist file of your iOS project.

In each language folder create a text file named Localizable.strings. This file is used to translate strings from all the code files of your iOS project.

For example, for an application named "Lovely Game", your Objective-C code could contain the following lines:

The following table shows some examples of how you modify the InfoPlist.strings file and Localizable.strings file for various languages.

Language

InfoPlist.strings File Code

Localizable.strings File Code

English

"CFBundleDisplayName" = "Lovely Game"; "NSCameraUsageDescription" = "The camera is needed to take a picture";

/* All right */"All right" = "All right"; /* Cancel */"Cancel" = "Cancel";

Chinese

"CFBundleDisplayName" = "可爱的游戏"; "NSCameraUsageDescription" = "需要摄像头用于拍照";

/* OK */ "OK" = "确定";/* Cancel */"Cancel" = "取消";

French

"CFBundleDisplayName" = "Beau Jeu"; "NSCameraUsageDescription" = "L'appareil photo est nécessaire pour prendre une photo";

/* All right */"All right" = "D'accord";/* Cancel */"Cancel" = "Annuler";

End Result

The newly-created Localizations folder will be copied any time Unreal Engine packages your iOS project.

Once packaged, your iOS project will have all of its strings translated and will be ready to submit to Apple.

Simple Launch Storyboards

Guidelines for Images

Creating a Custom Launch Storyboard in Xcode

Setting Up an Xcode Project

Creating the Launch Storyboard

Adding an Image to the Launch Storyboard

Image Guidelines

Adding the Custom Storyboard

Further Reading

Launch Storyboards are launch screens for iOS applications. Unlike traditional launch screens, which are static images, storyboards support animation, and are capable of scaling to fit the resolution and DPI of the user's device. Developers can use this to create highly polished launch screens with relative ease that fit a wide range of devices. This how-to will walk you through implementing storyboards in your own Unreal Engine (UE) projects.

Storyboards are mandatory for all apps for both the App Store and Apple Arcade. Apple no longer accept submissions featuring static launch screens.

Simple Launch Storyboards

It is recommended that you create a fully featured custom storyboard using the sections below. UE provides a method for creating simple, single-image storyboards for placeholder and testing purposes, ensuring that you always have a way of packaging a valid iOS project. This workflow can be used in any operating system, regardless of whether you are creating a C++ project or not.

To configure a simple storyboard, open Project Settings and navigate to the Platforms > iOS > Launch Screen section.



If you leave Custom Launch Storyboard unchecked, the image provided in Launch Screen Image will be converted into a storyboard when you build your project. An image with the Unreal Engine logo is provided by default as a fallback.

Guidelines for Images

Launch screen images must be PNG files with no alpha channel. It is a good idea to make the dimensions square (for example, 2048x2048) so that they can scale and crop to the largest number of devices as easily as possible.

Creating a Custom Launch Storyboard in Xcode

To create a custom storyboard, you will need a Mac with Xcode. You do not need to create a C++ project in Unreal to follow these steps, but you will need Xcode to generate the storyboard.

Setting Up an Xcode Project

If you are creating a C++ project, you can create your launch screen directly in the Xcode project for your UE game. Alternatively, you can create your launch screen in any valid Xcode project outside of your UE project and move it into UE later. This is useful if you want to keep your storyboard project separate for organizational reasons, or if you are creating a Blueprint project.

Follow these steps to create a stand-alone Xcode project:

Open Xcode and click File > New > Project.





Click to enlarge image.



In the templates menu, make sure you are creating an iOS project, then click Single View App, then Next.





Click to enlarge image.



In the options menu, fill in your product name, organization name, and organization identifier. In this example, this results in a Bundle Identifier of com.EpicGames.TestLaunchStoryboard.

In the User Interface dropdown, click Storyboard. Once you have filled out all necessary information, click Next.





Click to enlarge image.



Place your new project in a folder that is convenient. In this example, it will be in Users/UserName/Xcode Projects.

You will not need to compile this project. You are only making this project for the sake of creating the storyboard, which we will manually move to our UE project.

Creating the Launch Storyboard

Now that we have a project set up, follow these steps to create the storyboard that you will use for your launch screen:

In the Project Navigator, right-click your Project, click New Group, and create a new group called Storyboard.



Click File > New File...





Click to enlarge image.



In the file template menu, navigate to the User Interface section, select Launch Screen, then click Next.





Click to enlarge image.



Save the file when prompted. Place it in the Storyboard folder, making sure it is in the group of the same name, and change the name of the file to LaunchScreen, with no spaces.





Click to enlarge image.



Click the Create button to finish creating the storyboard. A file called LaunchScreen.storyboard will appear in your Storyboard Group, with a simple text label and a copyright notice.





Click to enlarge image.



Select the View Controller. In the Identity Inspector, set the Storyboard ID to "LaunchScreen." Under the Restoration ID section, check the Use Storyboard ID checkbox.





Click to enlarge image.



Setting the Storyboard and Restoration IDs for the View Controller is necessary for the storyboard to be recognized on startup. If you skip this step, the application will hang on a black screen before displaying the storyboard.

Adding an Image to the Launch Storyboard

The storyboard created in the previous section is functional enough that it could be used in your project as is. In this section, we will add an image to the storyboard so that you know how to integrate outside assets into your Xcode project.

Create an image to serve as the background for the storyboard. This image should be a PNG with no transparency.

In the Project Navigator, right-click the Storyboard group, click New Group, and call your new group Assets.

In Finder, make sure there is an Assets folder inside the Storyboard folder, and place your PNG in the Assets folder.





Click to enlarge image.



Drag your PNG into the Assets group in the Project Navigator to add it to the Xcode project.



Click the + (plus) button at the top of the Xcode window to open the library.





Click to enlarge image.



In the library, locate the Image View object, then drag it into your Storyboard. It will replace the default View and all of the text populating it.





Click to enlarge image.



Select Image View, then in the Attributes panel, click the source Image dropdown and select your PNG. If the Attributes panel is not shown, click the icon that looks like a chevron with a line through it, next to the Ruler icon.





Click to enlarge image.



In the Attributes panel, set the Content Mode to Aspect Fill.



Select the Size Inspector by clicking the Ruler icon. Click all four Constraints in the Autoresizing section. This will ensure that the Image View resizes based on all four directions.





Click to enlarge image.



As long as the image is located somewhere in your Xcode project, your Image View will be able to utilize it. However, we recommend keeping the image in an Assets folder for the purpose of adding it to your Unreal Engine project per the next section.

Image Guidelines

We recommend using square images for launch storyboards for the sake of maximizing compatibility with a wide range of aspect ratios. However, if you are targeting a specific device or a specific aspect ratio, you can tailor your images to fit that aspect ratio safely.

Adding the Custom Storyboard

To add your storyboard to the UE project:

Create a folder in your engine install directory called Project/Build/IOS/Resources/Interface.

Locate the Storyboard folder for your Xcode project in Finder.

Copy both LaunchScreen.storyboard and the accompanying Assets folder into Project/Build/IOS/Resources/Interface.





Click to enlarge image.



If you do not have the required files in the Project folder, the system will fall back to the Engine directory to look for them instead.

In the Unreal Editor, open Project Settings and navigate to Platforms > iOS > Launch Screen.

Enable the Custom Launch Storyboard checkbox.



Now when you package your iOS project, instead of using the default launch storyboard, the project will use the custom storyboard you placed in the IOS/Resources/Graphics folder. While the Xcode project does not depend on a specific folder structure for referencing the image file, the UE project requires it to be located in an Assets folder alongside the LaunchScreen.storyboard file.

Further Reading

After following this guide, you should have everything you need to implement a basic launch storyboard in your UE project. For additional information about configuring and editing storyboards for iOS, refer to Apple's documentation for launch screens and storyboards.

Configuration

Users with iOS version 10 and above will no longer have access to the iOS Game Center Application. All of the functionality of the Game Center app has been moved into the iOS operating system (OS). Because of this, you will need to create a UI that will display all of the items that used to be displayed by Game Center.



Configuration

Please see Leaderboards, Achievements and Challenges for information on setting up the iOS Game Center for your application.

For your Unreal Project:

In the Edit menu in Unreal Editor, select Project Settings to view the configuration options for your project.

On the left, Select the Platforms: iOS tab.

Set Enable Game Center Support to True.

If you are planning to release your application on both Android and iOS devices, please see



Caching your Achievements

Cache Achievements will request from the platform's game service the list of achievements and the values the current player has for said achievements. You'll be able to use the Get Cached Achievement Value if this node returns successfully.

Note that it is a latent node, and thusly has a number of execution output pins. The top most is a "pass through," that works like any other execution output pin. The other two pins (On Success, and On Failure) will execute when the online service returns (or fails to return) a value. When the execution returns a success

In Blueprints:

The example below is from the Global Game Instance Blueprint in the Unreal Match 3 sample game. After the user logs into the device's game platform (Game Center, Google Play), we run the Cache Achievements node and actually halt execution (by not having anything execute off the top output execution pin) at this point to give the service time to return all the achievements:



Reading Values from your Achievements

The Get Cached Achievement Progress will return the progress of a given Achievement ID for the provided Player Controller, and only work if a Cache Achievements node was run earlier and returned successfully.

For iOS Game Center, this value is actually a floored float, as they store it as an integer. A float is received for Google Play Services.

In Blueprints:

The example below is from the Global Game Instance Blueprint in the Unreal Match 3 sample game. Once the achievements are cached, we run through a loop pulling achievement names, as well as their target scores, from arrays, and do a quick comparison to any offline values found. We then accept the higher value of the service or the local values:



Writing Values to your Achievements

The Write Achievement Progress will send a message up to the platform's achievement system to write a percentage (0.0% - 100.0%) based Progress to the provided achievement for the given user (Player Controller and User Tag). For "one off" achievements you will always pass in 100.0 for Progress, while for incremental achievements, you'll be passing in some lesser percentage until the user reaches 100.0 for that achievement.

For iOS Game Center, this value is actually sent as an integer, as they only have 1-100 incremental achievements. A float is sent for Google Play Services.

Note that it is a latent node, and thusly has a number of execution output pins. The top most is a "pass through," that works like any other execution output pin. The other two pins (On Success, and On Failure) will execute when the online service returns (or fails to return) a value. When the execution returns a success the Written Achievement Name, Written Progress, and Written User Tag will return non-null values equal to what you passed into the node.

In Blueprints:

The example below is from the Global Game Instance Blueprint in the Unreal Match 3 sample game. There's a loop that compares the current achievement value to the metrics required to increase that achievement, and if progress has been made, the Write Achievement event is called:



This was done because latent nodes can't be used in Functions.

Showing the Platform Specific Achievement Screen

The Show Platform Specific Achievement Screen will show the achievements of the provided Player Controller for the current platform.

In Blueprints:

The example below is from the GameOverButtons Blueprint Widget in the Unreal Match 3 sample game. When the ShowAchievements button is pressed, the game will attempt to show the achievement screen for the current platform.



Prerequisites

Compatibility Notes

Creating Binaries for ARM64 and x86-64

Creating Separate Binaries

Creating Universal Binaries With UAT

With the introduction of Apple's M1 processor, Macs from 2021 onward are manufactured using the same ARM64 architecture as iOS devices. Meanwhile, the previous generation of Intel-based Macs use an x86-64 architecture.

Although Apple provides an instruction translator called Rosetta2 to help support legacy applications, Apple Arcade requires developers to provide a single universal binary for games, with explicit support for both architectures. This ensures the best possible performance and stability on both generations of hardware.

This page provides the following resources for building Unreal Engine (UE) projects with this level of support:

Information about Unreal Engine's compatibility with both architectures.

Instructions on how to support both architectures separately.

Instructions on how to build universal binaries that support both architectures.

Prerequisites

The instructions on this page assume that you are building your projects using Xcode running on macOS. You should familiarize yourself with Unreal Automation Tool (UAT) and the BuildCookRun command before proceeding.

Compatibility Notes

In UE 5.1, Unreal Editor when you build a project in Xcode on an Apple Silicon device, it is automatically set to compile with native Apple Silicon support for both editor and standalone builds. However, ARM64 support for Unreal Editor is experimental, as some Unreal Marketplace plugins and third-party libraries do not have ARM64 support yet. To build your editor for x86 instead, change your target device from My Mac to My Mac (Rosetta).



Unreal Engine can output packaged builds for projects with support for ARM64 by setting the target architecture to arm64. See the instructions below for more details.

Creating Binaries for ARM64 and x86-64

Creating Separate Binaries

To build binaries for each architecture, you need to use Unreal Automation Tool's BuildCookRun command to start a build and set the target architecture.

First, navigate to your Unreal Engine's install directory in your command line:

Then, execute RunUAT.sh with the BuildCookRun argument to start the build:

Adding the -architecture= command to BuildCookRun will specify which architecture you are building for.

For example, the following command will create a build for ARM64:

And the following command will build for x86:

The first time you build your project for each architecture will probably take longer than usual. After that, UAT caches cooked data, and subsequent builds will be faster.

You can build projects that support both x86-64 and ARM64 architectures by compiling their binaries separately, and distributing builds with those binaries to different machines as appropriate. However, you need to create merged, universal binaries for Apple Arcade, and having a universal binary is more convenient for distribution overall.

Creating Universal Binaries With UAT

To build a project with universal binaries, use the following as your architecture in BuildCookRun:

This will build a project that supports both ARM64 and x86-64 architectures. You can distribute these builds to either type of device, and they will use the appropriate binaries for their architecture automatically.

Choose your operating system:

Windows

macOS

Linux

Steps

In the following section, we will take a look at using the UE Editor to create an .IPA of your project, which can be installed later without the need for the Editor.

If you are localizing your iOS project, you will need to also translate strings in your code. See the Localize ‘plist' and ‘NSLocalizedString' in an iOS Project page for instructions on how to do this.

Connect your device to your computer if it is not already connected.

Open your project in Unreal Editor.

In the File menu, select Package Project > iOS.

In the directory dialog, select a location for the .ipa file to be saved.

A packaging message will appear in the bottom right corner of the editor while the game is being packaged.

A message is displayed when the project is successfully packaged.

End Result

When completed you will now have an .IPA that is ready to be deployed to your iOS device.



Steps

In the following section, we will take a look at creating a .IPA of your project that can be installed without the need for Unreal Editor.

Connect your device to your computer if it is not already connected.

Open your project in Unreal Editor.

In the File menu, select Package Project > iOS.

In the directory dialog, select your project's directory as this is where the packaged project (.ipa file) will be located.

A packaging message will appear in the bottom right corner of the Editor while the game is being packaged.

A message is displayed when the project is successfully packaged.

From Xcode go to Window and then select Devices and Simulators.

In the Devices section, press the Plus sign icon to start the app install process.

Locate and select the .ipa file that UE4 created and then press the Open button to begin the install process.

The progress of the install will be displayed across the top of the Devices window.

End Result

When completed you will see the IPA added to your iOS device.



iOS and tvOS both require Xcode to debug code in C++ projects. There are unique processes for launching and debugging on both types of devices, as well as accessing crash reports and logs. The how-to guides below will provide instructions on how to use these processes with Unreal Engine.



Download and read iOS and tvOS logs and crash reports either directly from device or from TestFlight.



Use Xcode to launch your project on device and debug with break points and LLDB commands.



Replicate inputs from an iOS device on your PC for testing.

1. Accessing Logs Directly from Device

2. Accessing Logs from TestFlight

Generating a .dSYM File

Extracting the Crash Report and Re-Symbolicating

Accessing iOS and tvOS Logs and Crash Reports

iOS applications built with Unreal Engine produce crash logs that developers can use to debug their projects and fix code issues. However, for security reasons, the debug symbols are not available with the crash logs themselves. You will see keys and numbers, but to see names of functions or information about variables in a human-readable format, you need to match your logs to a database of symbols for your project.

There are several processes for re-symbolicating your logs and reading them, depending on how you delivered your debug builds to devices. TestFlight is Apple's application for delivering test builds to a large number of possible devices, and it provides logs from those builds to developers. You can also obtain logs directly through USB debugging.

You need a Mac and Xcode to read logs for iOS projects. Other operating systems and IDEs will not work with the workflows on this page.

1. Accessing Logs Directly from Device

If you are debugging directly through USB or Ethernet, follow these steps to view a symbolicated crash log:

In Xcode, from the main menu, select Window > Devices and Simulators.

Click the iPhone you want to obtain crash data from, then click View Device Logs.

Control-click the log you want to read, then click Re-Symbolicate and export Log.

This will provide a human-readable log with debug symbols.

2. Accessing Logs from TestFlight

When an application delivered through TestFlight crashes, it produces an XCrashPoint file containing crash information. To read these files, you need to have a .dSYM file with debug symbols for your project, then you need to extract the crash report and re-symbolicate it.

For specific information about deploying applications through TestFlight and accessing logs, refer to Apple's documentation on TestFlight. This section will provide information about how to symbolicate them once you have obtained them.

Generating a .dSYM File

To generate a .dSYM file, follow these steps:

Open Unreal Editor.

Open your Project Settings, then navigate to Platforms > iOS > Build.

Enable Generate dSYM file for code debugging and profiling.



Package your project.

The .dSYM file for your project will appear in your project folder, under /Binaries/iOS.

.dSYM files have a timestamp showing when they were packaged. Take note of this information so you can match .dSYM files to the correct build.

Extracting the Crash Report and Re-Symbolicating

To obtain your crash report and re-symbolicate it so that you can read it, follow these steps:

Obtain an XCrashPointfile from TestFlight. You can use the following command line input to do this.

export PATH="/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources:$PATH"

Control-click on the .XCrashPoint file, then click Extract .crash file. You can also export this information using the following command line input:

export PATH="/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources:$PATH"

Open XCode, then look at the terminal. Use it to navigate to your Xcode .package.

Use the symbolicatecrash tool by running the following command line:

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer" cp -i /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash ././symbolicatecrash unsymbolicated.crash symbols.dSYM > symbolicated.crash

The above instructions use default directories. Use the locations of your .crash and .dSYM files when you run these command lines.

Xcode will then provide a crash log with function names and variables visible.

1. Required Setup

2. Cooking Content for iPhone

3. Compiling and Launching Your Project in Xcode

4. Additional Information

To debug Unreal Engine games on iOS, you will need to cook and package your project, then use Xcode to rebuild your code with debugging support. This page will walk you through the steps you should follow any time you need to debug a new build.

1. Required Setup

To create a build for iOS or tvOS devices, you must set up your code signing certificate and provisioning profile for your application, otherwise it will fail to build and deploy to your iOS device in later steps. Refer to iOS Provisioning for more information on this process.

If you are building a C++ project, you must also have an XCode project for your application. Locate your project's .uproject file, control-click it, then click Generate Xcode Project to create one if you have not already.

2. Cooking Content for iPhone

Before you can debug on iPhone, you need to use the Unreal Editor** to cook and package your game's content. The reason you need to do this is because XCode can compile your game's source code, but it cannot cook content. Therefore, any time there are significant changes to your game's content, you should remember to re-package everything before you move to XCode for debugging.

You can package your game by clicking File > Package Project > iOS in the Unreal Editor. For more information about the prerequisites needed to package iOS projects, refer to Packaging iOS Projects.

3. Compiling and Launching Your Project in Xcode

Once you have packaged your game, you need to rebuild it in Xcode with debugging support enabled. This will replace the binaries and executable generated by Unreal Engine's packaging process.

Open your application's Xcode project. In Xcode, from the main menu, select Product > Scheme > Edit Scheme.



Click the Run category, then change your Build Configuration to DebugGame.



If you are using a source code build of Unreal Engine, you can use the Debug configuration to debug the engine code.

Change the target device from My Mac to the iPhone you have connected.



Click the Build and Run button to start building the project from Xcode and launch it on the device.



Once you have completed these steps, the project will build and launch on your device. From here, you can use breakpoints, logs, and LLDB commands to debug your project and examine information at runtime.

4. Additional Information

For more information about how to use Xcode's debugging features, refer to Apple's developer documentation on Debugging With Xcode.

For more information about LLDB, refer to the Getting Started with LLDB page in Apple's documentation archive.

Getting the Unreal Remote 2 App

Enable Remote Session Plugin

The Remote Session Plugin is meant to replicate the inputs from an iOS device, connected on the same network as your PC, so you can test your game or app from the editor, or from a locally running packaged version of the game or app. The Unreal Remote 2 app works with the Remote Session Plugin to help you test your game or app.

Getting the Unreal Remote 2 App

Go to the App store on your iOS device. Search for Unreal Remote 2. Tap Get to download.

The Unreal Remote 2 app downloads and installs on your device. The device should be connected to the same network as your PC.

Start the application on the iOS device, and enter your PC's IP address. Then tap Connect.

Enable Remote Session Plugin

In the Unreal Editor, click Edit > Plugins. The Plugins panel displays.

In the left navigation panel, scroll down to Experimental. Locate the Remote Session Plugin. You can also use the Search bar to locate the Plugin by typing in "remote".

If you use the Search bar and type in "remote," you might see the Slate Remote Plugin in your search results. This is an older version of the plugin and should not be enabled--only enable the Remote Session Plugin.

Check the box for Enabled. A warning message appears stating that you need to restart the Editor for the change to take effect.

Click Restart Now to restart the Editor.

In the Unreal Editor, click the dropdown arrow on the Play button. This displays a menu of play state options. Select either New Editor Window (PIE) or Standalone Game. A new window opens.

Make sure Unreal Engine Editor is the active window. The interaction from the Unreal Remote app on the iOS device will be received by the input manager. All Blueprint nodes (and corresponding C++ APIs) in the following categories will return usable values:

Touch events

Touch input

Gesture events

Motion events

Motion values

Target Configuration

Game Content References

Disabling Slate

Obj List

Low-Level Memory Tracker

There are a number of things that affect the size of a packaged iOS game, from the content it references to the build configuration you choose.

Target Configuration

One of the biggest changes comes from targeting the Shipping configuration instead of Development, which saves about 31 MB. The Shipping configuration uses higher optimization settings, and removes debugging symbols and much of the logging and profiling code, resulting in much smaller executable sizes.

Game Content References

It is important to understand that any content referenced in your game will get cooked; some common gotchas are referring to huge otherwise unused textures as the default for a texture sample in a material function or material, or referencing unused content in an disconnected node or unused variable in your Blueprint. These count as referenced even if all of your material instances replace them with something else. You can look in the cooked asset folder and if you spot any unexpected assets, use the Reference Viewer to track down who refers to it.

If you cook via the Launch button on the toolbar, only the content referenced by your chosen maps will be cooked, but if you package your project, all of the content in your game will be cooked, even unreferenced content.

Disabling Slate

Content-only projects have a larger executable since they cannot make any assumptions about which plugins and libraries you are using. You can usually shrink your executable a little bit by switching to C++, and disabling unnecessary plugins and libraries at compile time (via EnabledPlugins and the Project.Build.cs and Project.Target.cs files). However, we have an optimization to remove more than 30 MB of Slate assets in content-only games since they cannot use Slate. If you make a C++ project that does not use Slate, you can save this space by setting bUsesSlate = false in the constructor of your TargetRules class in Project.Target.cs.

Obj List

The Obj List command can be used to better understand which types of assets are consuming the most memory in your project. When the Obj List command is entered into the UE4 console it will return list like in the following image.



Click for full image.

You can then use this list to figure out which items are using the most memory and make optimizations accordlying.

Low-Level Memory Tracker

The Low-Level Memory Tracker, or LLM, is a tool that tracks memory usage in Unreal Engine projects. LLM uses a scoped-tag system to keep an account of all memory allocated by the Unreal Engine and the operating system (OS). You can use LLM to help figure out where your memory is going. To read more about using LLM check out the following document that goes over using the LLM in your UE4 project.

Low-Level Memory Tracker

Current SDK Requirements

Current Device Compatibility

Getting Started

Development Guides

Packaging and Publishing

Debugging

Optimization

Unreal Engine supports publishing to Android mobile devices and has several features to help in publishing to the Google Play Store. This section contains guides for setting up your Android development environment, how to use Android features and services, and how to prepare your game to ship.

Current SDK Requirements

Current UE Version: 5.1

Android Studio Version: 4.0

Minimum SDK Version for compilation: 30

Recommended: 32

Minimum target SDK for shipping on devices: 26

NDK Version: r25b

AGDE v22.2.69+ required for AGDE debugging.

Current Device Compatibility

The current version of Unreal Engine supports Android devices meeting the following specifications:

Android 8 or higher

64-bit Arm-based CPU

Compatible GPUs

Mali T8xx, G71, G72, G76, G77, G78 and G710 series

Adreno 5xx, 6xx or 7xx series

PowerVR GM9xxx series

Xclipse 920

Compatible Graphics APIs

OpenGL ES 3.2

Vulkan supported on Android 10 or later devices with compatible drivers

Getting Started



How to set up your Android development environment for Unreal Engine



Setting up for development for the Android platform.



Going over how to set your Android devices up for Unreal Engine development.

Development Guides



Using the AdMob in-game advertisement system on Android.



Setting up and using the Android Mainfest file.



Using in-app purchases to offer additional paid content for your Android game.



Using leaderboards in your game.



Using Google Play Achievements to increase player engagement.



Going over setting up the Android Virtual Keyboard.



How to install different Android SDKs, set environment variables, and work with texture formats.



Information about Vulkan compatibility and how to use the Vulkan mobile renderer in Android projects



Overview of setting up optional custom Android Launch screens for Android projects.

Packaging and Publishing



Getting your project ready for Release to the Google Play store.



API reference and implementation guidelines for the GooglePAD API



Taking a look at packaging your final Android project.



Taking a look at using the Android Configuration Rules System in your UE projects.



A reference for device profile rules and scalability settings.

Debugging



How to debug your Android project in Android Studio



Use AGDE to debug Android projects in Visual Studio



Use Android File Server as a substitute for ADB for pushing and editing files for Unreal Engine projects.

Optimization



Learn about options for decreasing the size of your project's binary files on Android.

Current Development Requirements

Current SDK Information

Current Compatible Devices

Version History

This page contains the software development kit (SDK) requirements needed to develop Unreal Engine (UE) projects for Android devices, as well as compatible hardware for the current version of UE.

Current Development Requirements

Current SDK Information

Current UE Version: 5.1

Android Studio Version: 4.0

Minimum SDK Version for compilation: 30

Recommended: 32

Minimum target SDK for shipping on devices: 26

NDK Version: r25b

AGDE v22.2.69+ required for AGDE debugging.

Current Compatible Devices

UE 5.0 supports Android devices meeting the following specifications:

Android 8 or higher

64-bit Arm-based CPU

Compatible GPUs

Mali T8xx, G71, G72, G76, G77, G78 and G710 series

Adreno 5xx, 6xx or 7xx series

PowerVR GM9xxx series

Xclipse 920

Compatible Graphics APIs

OpenGL ES 3.2

Vulkan supported on Android 10 or later devices with compatible drivers

Version History

UE Version

Android Studio Version

Minimum Android SDK Version

Android NDK Version

Notes

5.1

Android Studio 4.0

Recommended: SDK 32 Minimum: SDK 30

NDK r25b

While SDK 30 is the minimum needed to compile on your system, SDK 26 is the minimum SDK you can target for shipping projects on devices.

5.0

Android Studio 4.0

SDK 23

NDK r21e

Minimum SDK version required to use Android File Server (AFS) is 26.

4.26.2 - 4.27

Android Studio 4.0

NDK r21b

4.25

Android Studio 3.5.3

NDK r21b

While we recommend using NDK r21b on Unreal Engine 4.25, it also supports NDK r20b to address compatibility issues on some low-end devices.

4.21 - 4.24

NDK r14b

4.19 - 4.20

NDK r12b

Recommended Setup

1. Install Android Studio

2. Set Up Android Studio for First-Time Use

3. Set up Command-Line Tools for Android

4. Finalize the Android Studio Installation on Your OS

5. Set Up Android NDK

How to Manually Target SDK Paths

Choose your operating system:

Windows

macOS

Linux

Unreal Engine uses the Android Software Development Kit (SDK) distributed with Android Studio for all essential Android development components, including the Android Native Development Kit (NDK). This page provides a walkthrough for setting up Android Studio and ensuring that Unreal Engine recognizes these components correctly, and some troubleshooting tips for managing NDK installations and earlier engine builds.

Due to an update to the Android SDK Command-line Tools in February 2023, users on Unreal Engine 4.27 through 5.1 need to edit the SetupAndroid script used in this tutorial. If you are experiencing problems with NDK setup, refer to the section on setting up Command-Line Tools for Android for more details.

Recommended Setup

Make sure that Unreal Editor and the Epic Games Launcher are both closed to ensure that there are no problems with either the installation of NDK components or setting your environment variables for the engine.

If you need to support an earlier installation of Unreal Engine refer to the section on Manually Targeting SDK Paths. You can find the needed NDK version for your version of Unreal Engine in the Android Development Requirements page.

1. Install Android Studio

Before setting up the required SDK and NDK components on your computer, you need to install Android Studio.

Refer to Android Development Requirements for information about which Android Studio and NDK versions are compatible with your current version of Unreal Engine.

Navigate to the Android Studio Archive in your web browser. Scroll down to Android Studio 4.0, click to unfold the dropdown, and download the appropriate installer or zip file for your operating system.





Click image for full size.



Run the Android Studio installer. In the Android Studio Setup dialog, click Next to continue.





Click image for full size.



In the Choose Components dialog, click Next to continue. You can leave the default components enabled.





Click image for full size.



In the Install Locations dialog, make sure the installation location is set to the default. Click Next to continue.





Click image for full size.



If you choose a custom install location, SetupAndroid.bat will not be able to find files unless you edit it first. We highly recommend keeping the default installation location.

In the Choose Start Menu Folder, click Install to begin the installation process.





Click image for full size.



When the installation finishes, click Next to begin setting up components.





Click image for full size.



When setup completes, make sure the Start Android Studio box is checked and click Finish to exit the installer.

2. Set Up Android Studio for First-Time Use

When you start your new install of Android Studio for the first time, follow these steps:

When the Import Android Studio Settings dialog appears, select do not import settings, then click OK to continue.



When the Data Sharing dialog appears, choose whether or not you want to send usage statistics to Google. This is an option you may choose at your discretion, and either choice will continue to the next step.





Click image for full size.



The Android Studio Setup Wizard will appear. Click Next to continue. If you are prompted for an update, click the X button to dismiss the prompt, as you need to specifically install version 4.0.





Click image for full size.



In the Install Type dialog, select Custom and click Next.





Click image for full size.



In the Select default JDK Location dialog, make sure the installation location is set to the default. Click Next to continue.





Click image for full size.



In the Select UI Theme dialog, choose your preferred theme and click Next.





Click image for full size.



In the SDK Component Setup leave the default components enabled and click Next.





Click image for full size.



If Emulator Settings window appears, adjust available settings or leave it by default.





Click image for full size.



In the Verify Settings dialog, check to make sure that you are using the default SDK path. Click Finish to finalize your setup and begin downloading components.





Click image for full size.



If you do not use the default SDK path, it is possible for SetupAndroid.bat to fail during a later step, as it will be unable to locate needed files.

When components are finished downloading, click Finish again to end setup.

3. Set up Command-Line Tools for Android

Unreal Engine's Android SDK setup depends on Command-Line Tools for Android version 8.0. Before moving on to finalize the installation, you need to make sure this version is installed and that UE's SetupAndroid script is targeting it correctly.

Originally, the SetupAndroid script targeted the Latest version, which referred to 8.0. Due to an update in February 2023, Latest now refers to 9.0, and you will need to re-target 8.0 manually if you are using a version of Unreal Engine that depends on it. This is required for UE 4.27, 5.0, and 5.1. The steps below take this into account and will walk you through fixing the SetupAndroid script.

In the Welcome to Android Studio dialog, you will see a prompt in the lower-right corner asking to update your Android Studio to the latest version. Hover over it and dismiss it without updating. This will reveal the Configure and Get Help dropdowns.

Open the Configure dropdown and click SDK Manager.





Click image for full size.



In the Android SDK system settings, click the SDK Tools tab. This will display a list of optional components.





Click image for full size.



Check the box for Android SDK Command-line Tools version 8.0. Click Apply to download and install this component.

Click OK to dismiss the window and close the welcome dialog.

Navigate to your Unreal Engine install directory -- for example, C:/Program Files/Epic Games/UE_5.0.

Open Engine/Extras/Android.

Inside this directory, locate the SetupAndroid script appropriate for your operating system. SetupAndroid.bat is for Windows, SetupAndroid.command is for Mac, and SetupAndroid.sh is for Linux.





Click image for full size.



Open your operating system's SetupAndroid script in a text editor. Locate the line specifying the variable SDKMANAGERPATH. In SetupAndroid.bat this line reads as follows:

Replace the directory latest with 8.0. It should read as follows:

Save the script and close your text editor.

4. Finalize the Android Studio Installation on Your OS

After completing all of the above steps, you need to finalize your installation to make sure your environment is fully set up before proceeding. Each operating system requires a different step to finalize installation.

Operating System

Required Action

Windows

Restart your computer.

Linux

Close your terminal window and reopen it.

macOS

Either close your terminal window and reopen it, or log out and log back in.

5. Set Up Android NDK

With the necessary Android SDK components installed, you can use the SetupAndroid script to download and install the appropriate version of Android NDK.

Open the Engine/Extras directory and run the appropriate SetupAndroid script for your operating system. SetupAndroid.bat is for Windows, SetupAndroid.command is for Mac, and SetupAndroid.sh is for Linux.

The script prompts you to accept the Android SDK license agreement. Type Y and press Enter to accept.





Click image for full size.



When the installation completes, press any key to dismiss the command prompt.

Restart your computer for all changes to take effect.

The install directory for NDK should be C:/Users/[Username]/AppData/Local/Android/SDK/ndk/, where "username" is your login name for your computer. You should see a folder containing the required NDK version in this location.

How to Manually Target SDK Paths

If you followed the instructions above without encountering problems, Unreal Engine will automatically associate the SDK paths for the Android SDK, the current Android NDK version, and the Java Development Kit (JDK). However, if you are using an earlier version of the Unreal Engine alongside Android Studio, you may need to manually target your SDK paths to be compatible. This is most likely to be the case if you have an installation of Unreal Engine alongside an earlier version that used CodeWorks.

Do not install CodeWorks and Android Studio at the same time, otherwise you will receive errors. If you need to support an earlier version of Unreal Engine alongside 4.25 or later, use the Android Studio setup in this document, then follow the instructions in this section to target the path for the version of Android Studio you need.

You can find the SDK paths by opening Edit > Project Settings, navigating to the Platforms > Android > Android SDK section.



When these fields are left blank, they fall back on a set of default paths used by the installation process in the previous sections. If you have multiple installations of these components, or have installed them in non-standard directories, you can manually provide their paths here. Alternatively, you can open BaseEngine.ini and provide them under the [/Script/AndroidPlatformEditor.AndroidSDKSettings] section.

If the entries for SDKPath, NDKPath, and JDKPath do not exist in your BaseEngine.ini, they will use the default path to the Android home directory.

Mobile Previewer

Setting Up Your Android Device For Development

Setting Up Android SDK and NDK

Packaging Android Projects

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Setting Up Your Android Device For Development

Setting Up Android SDK and NDK

1 - Android Development Prerequisites

2 - Creating Your Project

3 - Setting Up Unreal Editor for Android

4 - Configuring Editor and PIE for Mobile Previews

5 - Launching on an Android Device

6 - Packaging Android Builds

7 - On Your Own



This Quick Start Guide will walk you through all of the essentials for setting up Unreal Engine (UE) for Android game development, including the following topics:

Setting up your test device and computer for Android game development.

Configuring new projects for mobile development.

Setting up Unreal Editor for packaging Android builds.

Setting the Editor to preview with mobile rendering feature levels.

Testing your project on-device from the Editor.

Packaging a standalone build of your project.

When you have completed this guide, you will be prepared to take an Android project from initial setup to testing and packaging.

1 - Android Development Prerequisites

In order to create and deploy an Android project, you will need to install several Android development prerequisites included with UE and ensure that your device is ready for testing.

Follow the guide in Setting Up Android SDK and NDK for Unreal to install Android Studio and set up the required SDK components for Android development in UE.

On the device that you want to use for testing, open the Settings and enable Developer Mode.

Locate Developer Options in your device's Settings, then enable USB Debugging.



Click to full view

Plug your device into your computer, then allow your computer to access your device's data.

Permit your computer to install any needed drivers for your device.

Once you have completed these steps, you will be ready to develop new Android projects.

For more details about device setup, refer to our guide on Setting up Your Android Device for Development.

2 - Creating Your Project

The following section shows the process of creation a new UE5 project, based on the Third Person template. This example demonstrates how quickly you can get a UE5 project running on an Android device.

Launch Unreal Editor. In the Unreal Project Browser, use the following settings to create a new project:

Project Category: Games

Template: Third Person

Target Hardware: Mobile

Quality Level: Scalable

Name your project AndroidQuickStart and click the Create button to finish creating the project.



Click to enlarge image.

Choosing Mobile for your target hardware and Scalable for your target quality level will ensure that your project accounts for the user interface and hardware limitations of mobile devices.

3 - Setting Up Unreal Editor for Android

Next, you need to make sure your Project Settings in Unreal Editor are configured for Android APK builds.

Click Edit > Project Settings to bring up the Project Settings window.



Inside of the Project Settings window, navigate to Platforms > Android.

Under APK Packaging, find the Android Package Name and fill it with an appropriate company and project name. In this instance it uses com.EpicGames.AndroidQuickStart.



Click to enlarge image.

Under APK Packaging, find the Minimum SDK Version and Target SDK Version, fill it with an appropriate Android API version of devices, you create project for. In this instance it uses SDK Version 19 and SDK Version 28 accordingly.



Click to enlarge image.

Under APK Packaging, there will be a warning that reads "Project is not configured for the Android platform". Click the Configure Now button to automatically set up your project to write the required platform files.

If the Accept SDK License button is enabled, click it in order to accept Android's SDK license agreement. If you have previously accepted this agreement, then you will not need to complete this step.



Click to enlarge image.

Under Google Play Services, there will be a warning that reads "Project is not configured for the Google Play services". Click the Configure Now button to automatically set up your project to write the required files.



Click to enlarge image.

Your project will now be enabled to create Android builds and launch on an Android device.

4 - Configuring Editor and PIE for Mobile Previews

You can set Unreal Editor's Play-In-Editor (PIE) mode to provide a preview of how your game will look in the Mobile renderer.

In the Toolbar, click Settings > Preview Rendering Level, then select one of the available rendering levels for Android.



Click the dropdown of the Play panel in the Toolbar. Choose one of the available Mobile Preview modes corresponding to the rendering level you selected.



The Editor will now display your game in a way that is visually consistent with your target renderer. Additionally, when you press the PIE button, your game will launch in a standalone window set to a standard mobile aspect ratio and configured to emulate a touchscreen using your mouse. These settings will not affect packaging for mobile devices, but they will ensure that you have an accurate preview when working in the Editor.

Refer to the Mobile Previewer reference for more information about how you can configure the Mobile Previewer.

5 - Launching on an Android Device

To test your current Level on an Android-based device, you will need to do the following:

First need to make sure you have the Level you want to test open. In this example, it uses the ThirdPersonMap Level from the Blueprint based project that was created in the last step.



With the ThirdPersonMap now open, go to the Main Toolbar and click on Platforms button that displays more options.



From the Platforms menu under the Quick Launch section select your Android device from the list by clicking on it.



While your Level is being launched on your device, the progress will be displayed in the bottom right-hand corner of the screen like in the following image.



When the deployment has finished, the project should automatically start running on your Android device. If the project fails to automatically start, you can start it by finding the App on your device and tapping on it to launch it.



Click to enlarge image.

6 - Packaging Android Builds

The above steps provide a way to package and immediately launch a project on device. To package a standalone APK for distribution and testing, follow these steps:

Go to the Main Toolbar and click on Platforms > Android. Enable the Android (Multi:ASTC,DXT,ETC2) option and click on Package Project.



Click to enlarge image.

When the Package Project dialogue appears, choose the directory where you want to save it. Here we save it in AndroidQuickStart/Build.



Click Select Folder and Unreal Editor will begin packaging your project. Wait for it to finish packaging.

If you navigate to the folder where you output your build, the folder will contain the APK and OBB files necessary to install your game on an Android device. There are also a pair of .bat files that you can use to automatically install or uninstall your build to a connected device.



For more detailed information on configuring the Packaging settings for Android builds, refer to the Packaging Android Projects reference page.

7 - On Your Own

With what you have learned in this Quick Start you are now prepared to package and distribute your UE5 projects to general Android devices. You should expand on UE5's provided templates by creating new gameplay and levels in order to create fully functional mobile game. Depending on your project's needs and the devices that you are specificially targeting, further configuration will be required in order to optimize your builds. The following links will provide you with more information for taking the next steps in building your projects:

Android Development Reference - General reference information for Android developers in UE.

Android Development Requirements - Reference for compatible hardware as well as SDK and OS requirements to use specific versions of UE.

Android Debugging - How-to guide for debugging Android projects on-device.

Mobile Rendering - Information about Mobile-specific rendering features.

Mobile Services - Information about implementing online services and notifications.

Shipping with Android - Guidelines about preparing your game for distribution.

Android Quick Start

Debugging Android Projects





Packaging Android Projects

1. Installing Android USB Drivers to Your Computer

2. Enabling Developer Mode on Your Android Device

3. Enabling USB Debugging

4. Verifying That Your Device is Connected

End Result

In the following section you will go over all you need to know to set up your Android device so that it can be used to run your Unreal Engine (UE) project.

1. Installing Android USB Drivers to Your Computer

Connect your Android device to your development PC via USB.

Your device driver software should automatically install. If not, visit Android's OEM USB Drivers page to find more driver installation links and additional information.

Disconnect your Android device from USB and then immediately plug it back in. After the device is recognized by the PC, the following message will appear on your Android device asking you if you want to allow this PC to talk to your device. A message box will ask what you want the USB connection to do. Tap the checkmark box that says Always allow this computer and then tap the OK button.

2. Enabling Developer Mode on Your Android Device

Open the Settings menu on your Android device.

Scroll down and select About Phone. Depending on your Android device, you may have an About Device, About Tablet, or About Shield option instead.

This may be in a More section on newer Android versions.

Tap the Build Number 7 times to activate developer mode.



Once developer mode has been activated, a success message will display on the screen similar to the one below.



3. Enabling USB Debugging

Open the Settings menu on your Android device.

Navigate back to the Settings menu and select Developer Options which should now available.



In the Developer Options menu, enable USB debugging by tapping it.



When prompted, tap the OK button.



4. Verifying That Your Device is Connected

To verify that everything has been setup correctly and that your Android device is ready for Unreal Engine development, you can do the following:

Open a Windows Command Prompt by pressing the Windows + R keys to open up the Run command dialogue box.

Inside of the Open input, type cmd and the press the OK button to open the Windows Command Prompt.



Inside of the Windows Command Prompt, input adb devices and then press the Enter key to display all connected Android devices.



Open the Terminal app from /Applications/Utilities.



Type adb devices in the command prompt and you should see all devices that are connected to your Mac.



If you still do not see your device after you input the adb devices command you can try the following items:

If the device is listed but shows Unauthorized next to the name, that indicates that you did not accept your development PC's computer's RSA key fingerprint.

If your device does not show up despite it being plugged in and setup, input the following commands in the following order into the Windows Command Prompt to restart the Android Debug Bridge or (ADB) service:

Property Name

Description

ADB kill - server

This will stop the ADB service.

ADB start - server

This will start the ADB service.

In some cases, a correctly configured Android device might not show up if it is connected as a Media Device (MTP). If this happens, try connecting as Camera (PTP) by selecting the Camera (PTP) option in your Use USB to options.

End Result

Once you have completed the above sections, your Android device will be ready for deployment and debugging. For further reading, we recommend that you refer to the Android Quick Start Guide to learn about configuring your project for Android in the UE.

Configuration

C++ Projects



Configuration

To configure your project to use the AdMob in-game advertisement system on Android:

In the Edit menu in Unreal Editor, select Project Setings to view the configuration options for your project.



On the left, Select the Platforms: Android tab. Navigate to the Google Play Services section and configure project for Google Play services platform.



Click to full view

In the Google Play Services section, check the Enable Google Play Support option.

Enter the App ID for your game in the Games App ID field.

Add an element to the Ad Mob Ad Unit IDs array for each AdMob ID you want to associate and enter the ID in the text box.

Enter your Google Play License Key in the Google Play License Key field.



Click to full view

All of these values are available in the Google Play Developer Console for your App and Game Services, or in the Google Ad Mob interface.

Finally, you'll need to add com.android.vending.BILLING to the Extra Permissions array in the Advanced APKPackaging section of the Android settings:



Click to full view

C++ Projects

If your project is a C++ project you will also need to add the appropriate modules to your Target.cs file, for example:

Look at the Unreal Match 3 Target.cs file, Match3\Source\Match3.Target.cs, to see how this fits into the entire file.

Showing the Ad Banner

The Show Ad Banner function is used to display an ad banner in your game. Call it somewhere in the logic where you want to show an ad, such as when the main menu is shown.

In Blueprints:

The example below is from the Unreal Match 3 sample game, which displays an ad banner when the victory/defeat screen is shown using the Construct event of that Widget Blueprint:



See the Show Ad Banner reference for more information on the node.

Hiding the Ad Banner

The Hide Ad Banner functions hides the visible ad banner. Call it when you no longer want the ad to be displayed, such as when you exit the main menu.

In Blueprints:

The example below is from the Unreal Match 3 sample game, which hides the ad banner when the victory/defeat screen is exited using the Destruct event of that Widget Blueprint:



See the Hide Ad Banner reference for more information on the node.

Android Manifest Location

Android Manifest Layout

Extra Tags for Manifest

Extra Tags for Application

Extra Settings for Application

Extra Tags for com.epicgames.unreal Game Activity

The AndroidManifest.xml file is used to store various Android system permissions and settings that are set in the Advanced APK Packaging section of your Projects Settings. The following document shows how you can input commands that will be added to the AndroidManifest.xml file to meet the needs of your Unreal Engine (UE) project.

Android Manifest Location

Before you can locate the AndroidManifest.xml file for your project, you will first need to either package the project or deploy the project to your Android device. Once the project has been built or deployed you will then find the AndroidManifest.xml file in (YourProjectName)\Intermediate\Android\arm64.



Click for full image.

You should never edit the AndroidManifest.xml file under any circumstances. Any edits that need to be made to the AndroidManifest.xml file should be done inside the UE Editor in the Advanced APK Packing section.

Android Manifest Layout

In a typical AndroidManifest.xml file you will find the following three sections.

Application Definition

Activity

Requirements

Please note that the above Android Manifest file is not a working manifest file and is only shown for reference purposes.

Extra Tags for Manifest

Navigate to Extra Tags for <manifest> node in the Advanced APK Packaging section. You can add additional tags for the Manifest by clicking on the Plus sign icon to add a new element to the tags array and then inputting the tag or tags you want to use into the input box. For this example the following tag was used, android:sharedUserId="Foo".



Click for full image.

Tags that are input into the Extra Tags for <manifest> node section will be added to the manifest section of the AndroidManifest.xml file.

Extra Tags for Application

Navigate to Extra Tags for <application> node in the Advanced APK Packaging section. You can add additional tags for the Application by clicking on the Plus sign icon to add a new element to the Application array and then inputting the tag you want to use. For this example the following tag was used, android:hardwareAccelerated="True".



Click for full image.

Items that are input into the Extra Tags for <application> node section will be added to the Application Definition section of the AndroidManifest.xml file.

Extra Settings for Application

Navigate to Extra Settings for <application> section (\n to separate lines) in the Advanced APK Packaging section. You can add additional settings for the Application to use by inputting the settings you want to use into the Extra Settings for section. If you have more than one setting you want to use, separate each setting by adding \n. For this example the the following two items were added, android:banner="Foo" and android:vmSafeMode="True".



Click for full image.

Items that are input into the Extra Settings for <application> section will be added to the Activity section of the AndroidManifest.xml file.

Extra Tags for com.epicgames.unreal Game Activity

You can add additional tags for the Extra Tags for com.epicgames.unreal.GameActivity activity node by clicking on the Plus sign icon to add a new element to the Extra Tags for com.epicgames.unreal.GameActivity node array and then inputting the tag you want to use.



Click for full image.

Using In-App Purchases

Configuration

Testing

Helpful Links

Configuration

Set up your in-app purchase in Google Play:

Google Play requires the id to be all lowercase, and it's best to have the ID for iOS and Android match for ease of Blueprint setup.



Make a note of the ID you use, as well as if the item is consumable or non-consumable.

If you have a Blueprint project, you're set to go. If you have a code project and have not already set up your project to use online subsystems, add the following block to your project's Build.cs file:

In Project Settings > Platforms > Android, find the Advanced APKPackaging section.

Add an element to Extra Permissions called com.android.vending.BILLING.



Edit [ProjectName]/Config/Android/AndroidEngine.ini:

Reading Purchase Information



You can read the in-app purchase information using the Read In-App Purchase Information Blueprint node (or associated C++ function call). Like most other online subsystems functions, it takes a Player Controller as input, as well as an array of your product identifiers. Note that Make In-App Purchase below takes a single identifier, while Read can process an array of information. The function returns an array of In App Purchase structs, and each element of the array can be broken out to get the name, description, price, and other data to display in your UI or use in your gameplay logic.

Completing a Purchase



To make an in-app purchase, use the Make an In-App Purchase Blueprint node (or associated C++ function call). It takes the Player Controller as input, as well as a Product Request struct. A Product Request is just the product identifier from iTunes Connect or the Google Play Developer console (in this case, match3theme_night), as well as whether or not the product is consumable.

The Make an In-App Purchase node is latent, so any gameplay behavior you want to have rely on whether the purchase succeeds or fails should use those two execution pins. They will only execute after a response has come back from the online service. The node also returns the completion status of the purchase (such as Success, Failed, Restored) and the detailed In App Purchase Information struct.

There is a non-latent version of this function (the Blueprint node will display without the clock). The exit execution pin here does not wait for a response from the online service, and you will generally want to use the latent version.

Testing

To test on Android, you need to upload the packaged APK to Google Play, as well as set up the correct testing profiles. You'll also need your custom key store.

Helpful Links

Administering In-app Billing (Creating products)

Testing Android

Configuration



Configuration

Please see Leaderboards | Play Games Services | Google Developers for information on setting up the Google Play Game Services for your application.

For your Unreal Project:

In the Edit menu in Unreal Editor, select Project Settings to view the configuration options for your project.



On the left, Select the Platforms: Android tab. Navigate to the Google Play Services section and configure project for Google Play services platform.



Click to full view

In the Google Play Services section, check the Enable Google Play Support option.

Enter the App ID for your game in the Games App ID field.

Enter your Google Play License Key in the Google Play License Key field.

Add an element to the Leaderboard Map.

In the Leaderboard Map you'll need to enter a Name that is only used within your Unreal Project and the Leaderboard ID you set up in your Google Play Services.



Click to full view

All of these values are available in the Google Play Developer Console for your App and Game Services.

Since the Name value in the achievement map is only a mapping for the Google Play Services Leaderboard ID, and iOS is directly referred to by their Leaderboard Reference, and if you are releasing on both Android and iOS platforms, enter the Leaderboard Reference from your iOS Game Center settings as your Name so you only have to call one node regardless of platform.

Reading from a Leaderboard

The Read Leaderboard Integer node will request from the platform's game service (currently iOS Game Center, or Google Play Services), the value stored on the given Stat Name for the provided Player Controller.

Note that it is a latent node, and thusly has a number of execution output pins. The top most is a "pass through," that works like any other execution output pin. The other two pins (On Success, and On Failure) will execute when the online service returns (or fails to return) a value. The value of Leaderboard Value before a successful return (or if the service fails to get a response) will be 0.

In Blueprints:

The example below is from the Global Game Instance Blueprint in the Unreal Match 3 sample game. In these few nodes we're calling the Read Leaderboard Integer node for the Player Controller at Player Index 0 on the Stat Name (Leaderboard) "Match3HighScore":



Writing to a Leaderboard

The Write Leaderboard Integer node will send the given integer Stat Value to the leaderboard specified in Stat Name for the provided Player Controller.

In Blueprints:

The example below is from the VictoryScreen Blueprint in the Unreal Match 3 sample game. When the victory (or defeat) screen is shown, it will check to see if on load Unreal Match 3 was able to retrieve a high score, then if it was able to it will submit the latest high score to the leaderboard. There is some additional checking before this to see if the new highscore is more than the one that was pulled during the app startup, but even if that wasn't there, the iOS and Android leaderboard systems will only accept values greater than what they currently store.



Showing the Platform Specific Leadboard

The Show Platform Specific Leaderboard Screen will show the leaderboard specified by Category Name on the device.

In Blueprints:

The example below is from the GameOverButtons Blueprint Widget in the Unreal Match 3 sample game. When the ShowScores button is pressed, the game will attempt to show the leaderboard.



Configuration



Configuration

Please see Achievements | Play Games Services | Google Developers for information on setting up the Google Play Game Services for your application.

For your Unreal Project:

In the Edit menu in Unreal Editor, select Project Settings to view the configuration options for your project.



On the left, Select the Platforms: Android tab. Navigate to the Google Play Services section and configure project for Google Play services platform.



Click to full view

In the Google Play Services section, check the Enable Google Play Support option.

Enter the App ID for your game in the Games App ID field.

Enter your Google Play License Key in the Google Play License Key field.

Add an element to the Achievement Map.

In the Achievement Map you'll need to enter a Name that is only used within your Unreal Project and the Achievement ID you set up in your Google Play Services.



Click to full view

All of these values are available in the Google Play Developer Console for your App and Game Services.

Since the Name value in the achievement map is only a mapping for the Google Play Services Achievement ID, and iOS is directly referred to by their Achievement Reference, and if you are releasing on both Android and iOS platforms, enter the Achievement Reference from your iOS Game Center settings as your Name so you only have to call one node regardless of platform.

Caching your Achievements

Cache Achievements will request from the platform's game service the list of achievements and the values the current player has for said achievements. You'll be able to use the Get Cached Achievement Value if this node returns successfully.

Note that it is a latent node, and thusly has a number of execution output pins. The top most is a "pass through," that works like any other execution output pin. The other two pins (On Success, and On Failure) will execute when the online service returns (or fails to return) a value. When the execution returns a success

In Blueprints:

The example below is from the Global Game Instance Blueprint in the Unreal Match 3 sample game. After the user logs into the device's game platform (Game Center, Google Play), we run the Cache Achievements node and actually halt execution (by not having anything execute off the top output execution pin) at this point to give the service time to return all the achievements:



Reading Values from your Achievements

The Get Cached Achievement Progress will return the progress of a given Achievement ID for the provided Player Controller, and only work if a Cache Achievements node was run earlier and returned successfully.

For iOS Game Center, this value is actually a floored float, as they store it as an integer. A float is received for Google Play Services.

In Blueprints:

The example below is from the Global Game Instance Blueprint in the Unreal Match 3 sample game. Once the achievements are cached, we run through a loop pulling achievement names, as well as their target scores, from arrays, and do a quick comparison to any offline values found. We then accept the higher value of the service or the local values:



Writing Values to your Achievements

The Write Achievement Progress will send a message up to the platform's achievement system to write a percentage (0.0% - 100.0%) based Progress to the provided achievement for the given user (Player Controller and User Tag). For "one off" achievements you will always pass in 100.0 for Progress, while for incremental achievements, you'll be passing in some lesser percentage until the user reaches 100.0 for that achievement.

For iOS Game Center, this value is actually sent as an integer, as they only have 1-100 incremental achievements. A float is sent for Google Play Services.

Note that it is a latent node, and thusly has a number of execution output pins. The top most is a "pass through," that works like any other execution output pin. The other two pins (On Success, and On Failure) will execute when the online service returns (or fails to return) a value. When the execution returns a success the Written Achievement Name, Written Progress, and Written User Tag will return non-null values equal to what you passed into the node.

In Blueprints:

The example below is from the Global Game Instance Blueprint in the Unreal Match 3 sample game. There's a loop that compares the current achievement value to the metrics required to increase that achievement, and if progress has been made, the Write Achievement event is called:



This was done because latent nodes can't be used in Functions.

Showing the Platform Specific Achievement Screen

The Show Platform Specific Achievement Screen will show the achievements of the provided Player Controller for the current platform.

In Blueprints:

The example below is from the GameOverButtons Blueprint Widget in the Unreal Match 3 sample game. When the ShowAchievements button is pressed, the game will attempt to show the achievement screen for the current platform.



Steps

End Result

All Unreal Engine (UE) Android-based projects offer support for using either the standard pop up dialog input box or the operating system's virtual keyboard. The following document shows how to set up and call either virtual keyboard in your UE projects.





Steps

To enable the Virtual Keyboard in your project, you will need to do the following:

From the Main Menu go to Edit and then click on the Project Settings option.



In the Project Settings menu go to Platforms > Android and under the APK Packaging section look for and click on the check mark box next to the Enable improved virtual keyboard option to enable it.



Click for full image.

Right-click in the Content Browser and then go to User Interface > Widget Blueprint option, giving this new Blueprint a name of InputText.



Click for full image.

Double - click on the Input Text UMG widget to open it up and from the Palette drag a TextBox into the UMG graph.



Click for full image.

Position the TextBox so that it is in the middle of the Canvas panel and then press the Compile and Save buttons.



Click for full image.

Keep in mind that your application is responsible for ensuring input elements are visible and not obscured behind the virtual keyboard. You can use the supplied OnVirtualKeyboardShown and OnVirtualKeyboardHidden event handlers to make sure that UI elements do not obscure the virtual keyboard.

Open up the Level Blueprint and add the following nodes to the Event Graph.

Event Begin Play

Create Widget

Add to Viewport



Click for full image.

Connect the Event Begin Play node to the Create Widget node and then connect the Create Widget node to the Add Viewport node. When completed your Level Blueprint should look like the following image.



Click for full image.

Next, in the Create Widget Blueprint node, in the Class input, add the InputText Widget Blueprint that was created earlier.



Click for full image.

Save the level, giving it a name of AndroidVirtualKeyboard then open up your Project Settings and go to Maps & Modes. In the Default Maps input the AndroidVirtualKeyboard map into the Editor Startup Map and the Game Default Map.



Click for full image.

Click on the Platforms button small and from the displayed list, select the Android device you want to deploy your UE project to.



Click for full image.

End Result

Once your project launches on your Android device, press on the text input box and when you do, you should now be able to input the text you want using the Android system keyboard like in the following video.

You can also disable the virtual keyboard using the Android.NewKeyboard console variable followed by one of the following numbers. Doing this is particularly useful when the user is using a language requiring a different IME (Input Method Editor).

Command Name

Input

Description

Android.NewKeyboard

0

Uses the check mark box setting that was set in the UE editor.

Android.NewKeyboard

1

Forces the new keyboard to be used.

Android.NewKeyboard

2

Forces the dialog to be used.

Choose your operating system:

Windows

macOS

Linux

Overview

Android SDK Requirements

Installing Components

CodeWorks for Android 1R7u1

Environment Variables

Android Tips and Tricks

Android Texture Formats

Choosing a Format

Overview

The Android Development Reference pages contain a high-level explanation of the various software components and system settings you will need to make sure you have installed and setup on the computer you are using to develop your Unreal Engine (UE) Android project.

Android SDK Requirements

Here is what we currently require for Android game development in UE:

Components

Environment Variables

Android SDK

Java Development Kit

Ant Scripting Tool

Android NDK

ANDROID_HOME

JAVA_HOME

ANT_HOME

NDKROOT

Installing Components

There are several methods for getting the components. If you have already installed one of these, look in the corresponding section for additional requirements:

CodeWorks for Android 1R7u1

CodeWorks for Android 1R7u1 (by NVIDIA) is a one-stop shop for Android development needs. If you install CodeWorks for Android 1R7u1, all of your requirements to develop for Android will be met.

The installer for CodeWorks for Android 1R7u1 is included with Unreal Engine for Windows. It can be found here:

The important pieces are:

Android SDK (Base, Platform Tools, Build Tools)

Android 4.4.2 (API 19) - SDK Platform

Android 5.0.1 (API 21) - SDK Platform

Android 6.0.0 (API 23) - SDK Platform

Android N (API 24) - SDK Platform

Android SDK Support Library

Android Toolchain

Android NDK 12b

Java SDK

Apache Ant

USB Driver

Optional Install

Gradle

Developer Tools ( Optional Install)

Nsight Tegra, Visual Studio Edition

USB Driver

If you use the default installation set, a pretty minimal set of components will be installed. If you customize the install, you can add more items (like profilers, etc). Note that during installation, one or two of the sub-installers may appear to hang, but they will eventually finish. The install could take as long as 30 to 45 minutes. If you never plan to write code, you may want to select Customize, and only install the SDK, Ant, and Java (skipping the NDK and Nsight debugger) to make for the quickest installation. The Nsight portion of CodeWorks for Android 1R7u1 is used for debugging an Android game on a device. It is not required to compile C++ code.



CodeWorks for Android 1R7u1, (by NVIDIA) is a one-stop shop for Android development needs. If you install CodeWorks for Android 1R7u1, all of your requirements to develop for Android will be met.

The installer for CodeWorks for Android 1R7u1 is included with Unreal Engine for Mac and can be found here:

The important pieces are:

Android SDK (Base, Platform Tools, Build Tools)

Android 4.4.2 (API 19) - SDK Platform

Android 5.0.1 (API 21) - SDK Platform

Android 6.0.0 (API 23) - SDK Platform

Android N (API 24) - SDK Platform

Android SDK Support Library

Android Toolchain

Android NDK 12b

Java SDK

Apache Ant

USB Driver

Optional Install

Gradle

Developer Tools

Nsight Tegra, Visual Studio Edition (Optional Install)

USB Driver

If you use the default installation set, a pretty minimal set of components will be installed. If you customize the install, you can add more items (like profilers, etc). Note that during installation, one or two of the sub-installer may appear to hang, but they will eventually finish. The install could take as long as 30 to 45 minutes on some computers. If you never plan to write code, you may want to select Customize, and only install the SDK, Ant, and Java (skipping the NDK and Nsight debugger) to make for the quickest installation. The Nsight portion of CodeWorks for Android 1R7u1 is used for debugging an Android game on a device so it is not required to compile C++ code.



Environment Variables

Unless you installed CodeWorks for Android 1R7u1 from the provided UE installer, you will need to verify that some environment variables are set properly.

Once you have completed the installation (either by setting environment variables in the System Control Panel or by installing CodeWorks for Android 1R7u1), you will need to restart both the Editor and Launcher applications. This is due to how Windows applications store environment variables and then pass the old versions along to applications they start.

If you continue seeing the message about the Android SDK not being installed properly, it is recommended that you reboot your computer.

To set an environment variable:

Right-click on your Computer icon OR press Windows-Break on your keyboard.

Select Advanced system settings on the left.

Click Environment Variables...

For each variable (see below):

Look for the environment variable (from below) to already be set in at least one of the lists (either System or User).

If not found, then click New... next in the System section

Enter the name and value.

Click OK.

Click OK to close the Environment Variables window.

Here are the variables that we depend on, and where they should point:

ANDROID_HOME

Set this to the directory where you installed the Android SDK or the sdk directory if you installed ADT.

It must contain a directory called platform-tools.

JAVA_HOME

Set this to where the JDK is installed. It will probably be called something like jdk1.8.0_121.

It must contain a directory called bin with javac.exe in it.

ANT_HOME

Set this to where you unzipped Ant.

It must contain a directory called bin with ant.bat in it.

NDKROOT

Set this to where you unzipped the NDK. It will probably be called something like android-ndk-r11c.

It must contain a file called ndk-build.cmd

Unless you installed CodeWorks for Android 1R7u1, you will need to verify that some environment variables are set properly.

Once you have completed the installation (either by editing your .bash_profile file or by installing CodeWorks for Android 1R7u1), you will need to restart both the Editor and Launcher applications.

To set an environment variable you need to edit the .bash_profile file in your home directory. The file is hidden in Finder, so you'll need to use Terminal to open it for editing. If you're not familiar with Unix terminal commands please do the following.

Open Terminal app from /Applications/Utilities.

Type touch .bash_profile to create the file if it doesn't exist yet.

Type open .bash_profile to open the file in a text editor.

Copy the following lines to the file (replacing paths to point to where you installed SDK and tools) and save it:

export ANDROID_HOME="/Users/epicgames/Devel/NVPACK/android-sdk-macosx"

export NDKROOT="/Users/epicgames/Devel/NVPACK/android-ndk-r12b"

export ANT_HOME="/Users/epicgames/Devel/NVPACK/apache-ant-1.8.2"

Here are the name of the variables that we depend on and where they should point to.

ANDROID_HOME

Set this to the directory where you installed the Android SDK or the SDK directory if you installed ADT.

It must contain a directory called platform-tools.

ANT_HOME

Set this to where you unzipped Ant.

It must contain a directory called bin with a file called ANT in it.

NDKROOT

Set this to where you unzipped the NDK and look for something similar to android-ndk-r12b.

It must contain a file called ndk-build.

Android Tips and Tricks

If you do not see your device listed in the Launch menu, here are some things to try:

Wait a few seconds and look again, as the background scanning for connected devices can take a short amount of time.

Check that your USB debugging connection is working.

Open a command prompt (Press Windows+R, and run cmd.exe)

Type the following command: adb devices

If you do not see any devices listed, your USB driver is not installed properly. How to install the driver depends on the model of your Android device. Search online for your device model and "USB driver", then install the driver.

Additionally, you will need to make sure your device has Developer mode enabled with USB debugging is turned on. See the Android Developer Using Hardware Devices guide for more information (specifically items 2 and 3).

Afterwards make sure the adb devices command works; without this, the engine will not be able to do anything with your Android device.

If your device shows up in the Launch menu but gets stuck deploying to the device, it is most likely because the device is not authorized for your PC to talk to it. If you click on the Show Log line in the progress bar, you may see that the last line indicates that it is calling adb uninstall.

As above, use cmd.exe to run the adb devices command.

If the device is listed but shows unauthorized, that indicates that you need to get the device to ask if you want to authorize the PC.

You may need to unplug and reconnect your device to make it show up.

It is recommended you check the Always allow checkbox.

If you do not see your device listed in the Launch menu, here are some things to try:

Wait a few seconds and look again, as the background scanning for connected devices can take a short amount of time to register the device.

Check that your USB debugging connection is working.

Open the Terminal app and then try the following.

Type the following command into the terminal: adb devices.

If you do not see any devices listed, your USB driver is not installed properly. How to install the driver depends on the model of your Android device. Search online for your device model and USB driver, then install the required driver.

Additionally, you will need to make sure your device has Developer mode enabled with USB debugging is turned on. See the Android Developer Using Hardware Devices guide for more information (specifically items 2 and 3).

Afterwards make sure the adb devices command works; without this, the engine will not be able to do anything with your Android device.

If your device shows up in the Launch menu but gets stuck deploying to the device, it is most likely because the device is not authorized to interact with your Mac. If you click on the Show Log line in the progress bar and see that the last line indicates that it is calling adb uninstall, try the following.

Open up the Terminal app and run the adb devices command.

If the device is listed but shows unauthorized, that indicates that you need to get the device to ask if you want to authorize the Mac.

It is recommended you check the Always allow check box to always allow your Mac to talk to this device.

Android Texture Formats

Not all Android devices are made the same. In particular, there are 4 different kinds of rendering hardware. They each support different formats of compressed textures.

Format

Description

ETC1

Supported by all Android based devices but cannot compress alpha textures (they are stored uncompressed). Recommend using an RGB and a separate alpha texture if need alpha to get better compression.

ETC2

Supported by all OpenGL 3.x class devices and supports alpha compression.

ATC

Supported by Qualcomm Adreno GPUs and supports alpha compression.

DXT

Supported by Nvidia Tegra GPUs and supports alpha compression.

PVRTC

supported by PowerVR GPUs and supports alpha compression.

ASTC

Latest Texture compression format allowing more quality control by specifying block size and supports alpha compression. Available on some devices at this point and will be required for Vulkan Level 1.

When you deploy or package your game for Android, the data will be converted to a format usable by an Android device (we call this process "cooking"). Because different devices support different compressed formats, you have a choice of what format you want to be cooked. In the Launch or Package submenu, you will see Android followed by the possible formats.

The first one (Android) actually takes all formats and puts them into the cooked packages. This will take longer, and will make larger packages, but will guarantee the minimal memory usage by choosing the best format at runtime. It will work on any device (as will Android (ETC1)).

Unreal Engine version 4.8 and later will now support the use of ES31 and AEP rendering on Tegra K1 devices. Please note that due to the limited number of devices that currently support ES31 and AEP rendering, very little performance and compatibility testing has been completed at this time. If you are developing a project that is aimed at using one of these devices, it is highly recommended that you perform extensive performance and compatibility testing to ensure that the device delivers your project in the manner you intended.

Choosing a Format

You most likely will want to choose an optimal format for your device. If you know the type of GPU in your device, you can look at the table above to choose a format. However, if you do not know, then you can choose Android or Android (ETC1). When you run the game, if you tap the screen with 4 fingers at once, a dialog will pop up. This dialog is usually used to enter a console command (like stat fps), but it will also display the formats that your device supports. Once you have that list, you can use that to choose an ideal type when deploying/packaging. If you choose a format that your device does not support, it will fail to load.

Vulkan Video Drivers for PC Development

Checking Vulkan Device Compatibility

Supported Vulkan Devices

Building for Vulkan

Enabling Vulkan Preview Rendering in Editor

Enabling the Vulkan Mobile Preview Render

Unreal Engine (UE) has built-in support for the Vulkan graphics API. Vulkan is a low-overhead, cross-platform 3D graphics library that gives developers more control over the GPU and lower level CPU usage for their Android base mobile projects. The following document shows how you can enable and use Vulkan in your UE Android projects.

Vulkan Video Drivers for PC Development

To make sure that you can visualize the rendering options Vulkan has available on your development PC, you will need to make sure you download and install the latest version of video card drivers for your graphics card. Below you will find the minimal driver version you need to use to be able to preview what Vulkan will look like on your development PC.

NVIDIA: 390.0 or later

AMD: 17 or later

Checking Vulkan Device Compatibility

Determining if your smartphone supports the Vulkan rendering API can be challenging due to the wide range of Android smartphones on the market. To help you quickly find out if your smartphone supports the Vulkan API, it is recommended to install the following program from Google Play Store: Hardware Caps Viewer for Vulkan.

The Vulkan Hardware Capability Viewer is a client tool aimed at developers needing to gather hardware implementation details for devices that support the new Vulkan Graphics API.

Supported Vulkan Devices

The following devices have Vulkan-specific profiles available in addition to non-Vulkan profiles:

Adreno 6xx

Mali G72

Mali G76

Mali G77

PowerVR GM9xxx

If your device uses Android 9 or higher and you have Vulkan enabled as a feature level for your project, it will use the Vulkan-enabled version of these GPU families' device profiles.

Please note that the ability to use the Vulkan API depends on if your mobile carrier has released the Vulkain update for your specific device variant. To find if this support has been pushed to your mobile device, you will need to contact your mobile carrier.

Building for Vulkan

To build a UE project that has support for the Vulkan API you will need to do the following:

Before you begin, make sure that you have your Android smartphone plugged into your development PC via USB and that your Android smartphone has developer mode enabled.

Launch the UE Editor and create a new project using the Games > Blank template using the following settings:

Blueprint Project enabled

Mobile enabled

Maximum Quality enabled

Starter Content disabled

When that is completed, press the Create button to create and load the new project.



Click image for full view.

Once the project has loaded, go to Edit > Project Settings, then under Engine, go to the Rendering section and make sure that Mobile HDR has been enabled under VR.



Click image for full view.

In the Project Settings, navigate to the Platforms, go to the Android section, make sure that the following options are enabled under Build:

Support OpenGL ES3.2

Support Vulkan



Click image for full view.

From the menu bar, click on the Platform button, go to Android, make sure, that Android(ASTC) option is selected and click on Package Project.



Select a location for UE to save the Android build and then press the Select Folder button to start the packaging process.



When the packaging process has been completed, open up the folder that the packaged build was placed in. Inside this folder, you should see two BAT files. Locate the BAT file that has the word Install in the name and double-click on it to install it to your device.



Once installed on your device, press on the UE icon that has your project name under it to launch the project on the device.



Click image for full view.

Enabling Vulkan Preview Rendering in Editor

If you have enabled Vulkan in your project as described above, a preview rendering option will appear automatically. On the Main Toolbar, click on the Settings button and go to the Preview Rendering Level option. Select the Android Vulkan option to enable the Vulkan preview in the UE Viewport.



The Viewport should read Feature Level: Android Vulkan ES31 in the lower-right corner.

After doing this, the Editor will need to recompile the entire shader cache to include the required Vulkan options. Depending on the size of your project and power of your development computer, this process could take anywhere from a few minutes, to an hour or more to complete.

Enabling the Vulkan Mobile Preview Render

To enable Vulkan Render with the Mobile Preview Render, do the following in your project:

From the Main Toolbar, go to the Edit option and then select the Editor Preferences option from the main menu.



In the General section under the Experimental category, expand the PIE section then select the checkmark box next to the Allow Vulkan Mobile Preview option.



Click image for full view.

On the Main Toolbar, click on options menu on the Play panel and select the Vulkan Mobile Preview (PIE) from the drop down list.



Click on the Play button that is on the Main Toolbar to launch your UE project in a new preview window with Vulkan Render enabled. If everything has been setup successfully, you should see something similar to the image below.



Click image for full view.

If you do not see (SF_VULKAN_ES31) at the top of the preview window next to the project name, that means the project is not using the Vulkan API. Should this happen, make sure that your video card drivers are up to date.

Configuring Launch Images

Support for custom launch screens in Android projects is available inside the Project Settings under the Platforms > Android > Launch Images section. You can set the background, portrait, or landscape images used as well as whether or not the feature is enabled/disabled (refer to the table below for more information).

Launch Images Options

Option

Description

Show Launch Image

Shows the launch image as a startup splash screen. If enabled, either or both launch images selected for the project will be included depending on the orientation setting in the project.

Download Background Vertical Image

Used as the background for OBB downloading when a device is in a vertical orientation.

Download Background Horizontal Image

Used as the background for OBB downloading when a device is in a horizontal orientation.

Launch Portrait

Used as a splash screen for applications with Portrait, Reverse Portrait, Sensor Portrait, Sensor or Full Sensor orientation.

Launch Landscape

Used as a splash screen for applications with Landscape, Sensor Landscape, Reverse Landscape, Sensor or Full Sensor orientation.

You can change your application's orientation settings in Project Settings. Navigate to Platforms > Android > APK Packaging and click the Orientation dropdown to select what orientations you want to be valid for your application.



Configuring Launch Images

To configure your project to use the Launch Images:

Inside your project from the Main menu, select Edit > Project Settings.



In the Project Settings, on the left under Platforms select Android to display the project settings for Android apps.



Scroll down to the Launch Images section and make sure the Show launch image check box is enabled.



Click the ... icon next to each image to open a browser where you can select your image from your computer.



Once you have selected the images you want to use they will be added to the project and included during the startup splash screen.



Examples for portrait and landscape images may be found in the Engine/Build/Android/Java/res/drawable folder as PNG files.

Generating Key

Placing the Key

Applying the Key

Deploying to the Google Play Store

Choose your operating system:

Windows

macOS

Linux

In the following document, we will cover what you need to do in order to get your UE mobile project ready to be released on the Google Play store.

Please keep in mind that this document will only focus on items that are relevant to getting UE based projects on the Google Play store. If you are looking for more general information about the Google Play store, please consult the official Google Developer Console Help.

Generating Key

Before you can submit or even upload your project to the Google Play store, you will need to generate a Keystore. A keystore is a unique key that will ensure that your project will be linked to your Google Play account and no one else's. In the following section we will go over how you generate this key as well as where it needs to be placed to ensure that your project will use it when being packaged.

Open a Command Line prompt window and navigate to the directory where Android Studio installed the keytool.exe file. This will be the \jre\bin folder if you are using default installation directories.





With the Command Line prompt window now open, input the following Command Line argument and then press the Enter key.





Instead of typing this in by hand you can also copy the above text and then click with the right mouse button to paste what you copied into the Command Line argument window.

Now enter a password for your Key Store. Make sure that this is something you will remember as you will have to enter it one more time after this. For this example, we will be using 123password for our Keystore password.





Next you will need to enter a First and Last name into the Command Line window. For this example, input the name TestGuy and then press the Enter key.





Now enter the name of your Organizational Unit. For this example, input the name MyCompany and then press the Enter key to continue.





Then enter the name of your organization. For this example, input MyGame and then press the Enter key to continue.





Now enter the name of the City or Locality you are in. For this example, input MyCity and then press the Enter key to continue.





Then enter the name of the State or Province that city is located. For this example, input NC and then press the Enter key to continue.





Now input the country code where the city and state are located. For this example, input 00 and then press the Enter key to continue.





You will now be asked to verify that all the information that you have entered is correct. Type Yes or Y into the Command Line window and then press the Enter key to continue.





Because we are only storing a single key into this Keystore, all you need to do next is press the Enter key when asked to enter a password.





The last line in the Command Line window should now say, [Storing ExampleKey.keystore] if everything has been setup correctly.





Once the key has been created it will be placed in the \jre\bin folder containing keytool.exe.





Placing the Key

Once you have the key generated, it will need to be placed in the following location inside of your UE project.





Applying the Key

After the key has been placed in your (Your Game Folder)\Build\Android folder, you will need to apply it to your UE project by doing the following.

Inside of UE, go to Edit > Project Settings > Platforms > Android.



Under the APK Packing section, make sure to set the Store Version to the number one if this is the first time you are uploading the project to the store.



Each time you re-cook your project to re upload to the store, you will need to increase the Store Version number. If you do not do this, your new APK file will fail to be uploaded over the old one.

Next under Distribution Signing, make sure the following fields are filled in with the Keystore information that was used above to generate the Keystore.



Property Name

Description

Name used in example

Key Store

This is the name given to the .Keystore file.

ExampleKey.keystore

Key Alias

This is the name of the .Keystore file. - ExampleKey.keystore

MyKey

Key Store Password

The password that was used to secure the key

123password

Once all of this has been filled, go to the Packaging section of your project and under the Project section make sure that both Full Rebuild and For Distribution are enabled.



Deploying to the Google Play Store

Now all that is left is to upload your project to the Google Play store. For a full breakdown of how to upload your project to the Google Play store, please check out the official Google Developer Console help page.

Packaging Android Projects

Packaging and Publishing

Enabling the GooglePAD Plugin

Creating Asset Packs

Asset Pack Delivery Modes

Creating Chunks

Including Chunks in your App Bundle Build

Excluding Chunks From the OBB File

API Reference

Requests and Error Handling

Getting the Location of Downloaded Files

Requesting Information about Asset Packs

Requesting or Cancelling a Download

Getting Cellular Data Status

Monitoring Download Status

Removing Asset Packs

Recommended Implementation

Google Play Asset Delivery (GooglePAD) is the Google Play Store's solution for delivering asset packs to applications once they are installed on a device. This solution is intended for use alongside the Android App Bundle distribution format. While the App Bundle distributes a customized .apk to the end user, handling code and binaries for the initial installation, the Play Asset Delivery system provides models, textures, sounds, shaders, and other large asset files separately from the .apk. This makes it possible for apps distributed through Google Play to manage the space taken up by content by delivering content as it is needed.

For more general information about Google Play Asset Delivery, refer to the (official Android documentation)[https://android-developers.googleblog.com/2020/06/introducing-google-play-asset-delivery.html].

Unreal Engine includes GooglePAD integration through a plugin, making this system simple to implement in your own projects. This plugin provides a function library with calls for managing downloads and requesting information from the Play Asset Delivery system. UGooglePADFunctionLibrary is available in both C++ and Blueprint.

For additional information on shipping with Android App Bundles, see the page on Packaging Android Projects.

Enabling the GooglePAD Plugin

The GooglePAD plugin is enabled by default, but if you want to disable it, you can find it in the Unreal Editor's Plugins window, under the Android section. To use GooglePAD, you must also use Android App Bundles as your packaging format.



To fully enable the plugin, open Project Settings and navigate to Plugins > GooglePAD > Packaging. Click the Enable Plugin checkbox, and the module will be available on startup for Android projects.



If you want to use GooglePAD for install-time assets, you also need to navigate to Platforms > Android > APK Packaging and disable Package Data inside APK. The main .obb file will then be delivered as an install-time asset pack automatically.





Click to enlarge image



Creating Asset Packs

Asset packs for GooglePAD are packaged inside Android App Bundle builds, and managed by the Google Play Store when they are uploaded. This section explains how to package and organize asset packs for inclusion in your App Bundle.

Asset Pack Delivery Modes

Chunks are Unreal Engine's format for organizing external assets. Chunk 0 represents the base installation of the game, while all other chunks are .pak files containing assets outside of the game's main installation.

To use GooglePAD, you must group your game's assets into chunks, and you must group those chunks into asset packs based on the delivery mode you want to use for them. Google Play Asset Delivery supports the following delivery modes for asset packs:

Delivery Mode

File Size Limitation (Per Asset Pack)

Description

Install-Time

1 GB

Asset pack that is delivered at the time of installation. The main .obb from your project is automatically bundled into this asset pack.

Fast-Follow

512 MB

Asset pack downloaded automatically after the app is installed. The app does not need to be open for this to download. Only one Fast-Follow asset pack is allowed per project.

On-Demand

512 MB

Asset packs downloaded when the app is running.

You can create a total of 50 asset packs per application. You can only have one Install-Time and one Fast-Follow asset pack per project, but can use as many On-Demand asset packs as you want as long as you do not exceed this limit.

Creating Chunks

Open your Project Settings and navigate to Project > Packaging and make sure Generate Chunks is enabled.



Now you can organize assets into chunks using the asset manager or primary asset labels. Refer to Cooking and Chunking page for more details on how to use these features.

Once you have designated which assets belong to specific chunks, packaging your project will output your chunks as .pak files. You can find them in your project folder under Saved\StagedBuilds[PlatformName][ProjectName]\Content\Paks.





Click to enlarge image.



Including Chunks in your App Bundle Build

Each delivery mode for Play Asset Delivery has different requirements for incorporating chunks into App Bundles.

For Install-Time assets, you do not need to make any changes.

For Fast-Follow or On-Demand assets, select the .pak files you want to include and move them to your project's Build/Android/gradle/assetpacks directory. Each delivery mode has a different subfolder:

Fast-Follow asset packs must be placed in Build/Android/gradle/assetpacks/fast-follow/[assetpackname]/src/main/assets

On-Demand asset packs must be placed in Build/Android/gradle/assetpacks/on-demand/[assetpackname]/src/main/assets

Replace [assetpackname] with the name of the asset pack that the chunks will be bundled into. You can create multiple different named asset packs with different sets of .pak files. However, the names of your asset packs must be unique, and they may not be re-used between fast-follow and on-demand. This name will be the one that you use when querying for asset packs with the API.

Finally, you need to add a build.gradle file in the asset pack folder containing the following code:

After you have met these requirements, package the project as an app bundle again, and it will include each of these asset packs in your build. When you upload the App Bundle to the Google Play Store, the asset packs will be available for download using the GooglePAD API.

This workflow will be streamlined further in Unreal Engine 4.26.

Excluding Chunks From the OBB File

By default, .pak files are included in the OBB file generated alongside your project. To exclude them, you need to open your DefaultEngine.ini file and filter them using OBB filters under Android Runtime Settings.

In the example above, the OBB filters will catch any .pak files containing any of the text provided. For instance, +ObbFilters="-*pakchunk1*" will omit any pak file whose name contains "pakchunk1".

API Reference

The following sections detail the available functions in the GooglePAD function library and their usage.

Requests and Error Handling

All requests in the GooglePAD function library return an EGooglePADErrorCode denoting whether or not the operation succeeded and, if not, what specific error prevented the request from being completed. The possible error codes are as follows:

EGooglePADErrorCode

Description

AssetPack_NO_ERROR

No error with the request. Proceed with the requested information as normal.

AssetPack_APP_UNAVAILABLE

The requesting app is unavailable.

AssetPack_UNAVAILABLE

The requested asset pack is not available for your app's current version.

AssetPack_INVALID_REQUEST

The request is invalid.

AssetPack_DOWNLOAD_NOT_FOUND

The requested download has not been found.

AssetPack_API_NOT_AVAILABLE

The Asset Pack API is not available.

AssetPack_NETWORK_ERROR

Unable to obtain details about an Asset Pack due to a timeout or other network error.

AssetPack_ACCESS_DENIED

The download is not permitted due to current device circumstances, usually because the user is not signed into a Google account.

AssetPack_INSUFFICIENT_STORAGE

An asset pack download failed due to insufficient storage.

AssetPack_PLAY_STORE_NOT_FOUND

The Play Store app is either not installed on this device or not the official version.

AssetPack_NETWORK_UNRESTRICTED

Returned if ShowCellularDataConfirmation is called but no Asset Packs are waiting for wi-fi. This means that downloads can proceed without waiting for confirmation from the user.

AssetPack_INTERNAL_ERROR

An unknown error occurred in downloading an asset pack.

AssetPack_INITIALIZATION_NEEDED

AssetPackManager_init has not yet been called, therefore the API has not been enabled yet.

AssetPack_INITIALIZATION_FAILED

There was an error initializing the Asset Pack API.

In addition to this return value, request functions will have an out variable providing the requested information. If you get a result of AssetPack_NO_ERROR, you can proceed with the provided information normally. Otherwise, you should use flow control to react to the provided error code appropriately.

Getting the Location of Downloaded Files

The function GetAssetPackLocation fetches the location of an asset pack that has been downloaded and caches information about it locally. If the asset is available, it will output an integer handle that can be used to access the cached information as needed.

Calling GetAssetsPath and providing the location handle will output a string with the asset path for the desired asset pack. GetStorageMethod will output an EGooglePADStorageMethod stating the way the asset pack is stored on the user's device. Once you know the asset path and storage method, you can then use appropriate calls to access the assets.

The possible storage methods are as follows:

EGooglePADStorageMethod

Description

AssetPack_STORAGE_FILES

The asset pack is unpacked into a folder containing individual asset files. These assets can be accessed via standard file APIs.

AssetPack_STORAGE_APK

The asset pack is installed as an APK containing packed asset files. These assets can be accessed via the Asset Manager.

AssetPack_STORAGE_UNKNOWN

No information is available about the asset pack, most likely due to an error.

AssetPack_STORAGE_NOT_INSTALLED

The asset pack is not installed, and is therefore unavailable.

Once you are done using the above information, you must pass the location handle to ReleaseAssetPackLocation to free the cached location info.

If GetAssetPackLocation returns an error code of AsetPack_UNAVAILABLE or AssetPack_DOWNLOAD_NOT_FOUND, then the desired asset pack is unavailable and must be downloaded.

Requesting Information about Asset Packs

The function RequestInfo takes in a TArray of asset pack names and returns an EGooglePADErrorCode denoting their current status. RequestInfo is not required to initiate a download, but can be used to determine whether remote asset packs are valid.

Requesting or Cancelling a Download

The function RequestDownload takes in a TArray of strings representing the names of the asset packs you would like to download, then sends a request to the remote service to begin downloading those asset packs. If RequestDownload shows no errors, the asset packs will be downloaded and transferred to the app asynchronously in the background.

Because this functionality is asynchronous, the RequestDownload function does not return information about the downloaded asset pack, other than an error code denoting whether the request was successful. You must use the functions detailed in the Monitoring Download Status section below to check for the download's current status, and to access the asset pack itself you must use GetAssetPackLocation once the download is complete.

The function CancelDownload also uses a list of asset pack names, and will cancel downloading the designated asset packs.

Getting Cellular Data Status

The function ShowCellularDataConfirmation will prompt the user for whether they want to download data using their cellular network. If the prompt is already present, you can use GetShowCellularDataConfirmationStatus to return an EGooglePADCellularDataConfirmStatus stating whether or not the user has approved the download.

Results of AssetPack_CONFIRM_UNKNOWN and AssetPack_CONFIRM_PENDING mean the user has not given approval yet, and the application should stand by until approval is given.

A result of AssetPack_CONFIRM_USER_CANCELLED means that the user has chosen not to allow the use of cellular data, and downloads should not be permitted at this time.

A result of AssetPack_CONFIRM_USER_APPROVED means that the user has given express approval to use cellular data and downloads should be allowed to proceed. Additionally, If this function returns an EGooglePADErrorCode with a result of AssetPack_NETWORK_UNRESTRICTED, the user is on their wi-fi network and does not need to use cellular data, therefore downloads should be permitted without the need to continue checking this function.

Monitoring Download Status

GetDownloadState will locally cache the download status of an asset pack and return a download handle providing access to the cached information. This function takes in the name of the asset pack that you want to download and outputs the handle as an integer. You should keep the download handle cached so that you can continue to monitor the download, otherwise, you will need to re-acquire it.

With a valid download handle, you can call GetDownloadStatus to return the status of the desired asset pack as an EGooglePADDownloadStatus. This enum represents the status of a download as one of several possible states, which are as follows:

EGooglePADDownloadStatus

Description

AssetPack_UNKNOWN

Nothing is currently known about the asset pack.

AssetPack_DOWNLOAD_PENDING

An async request to download the asset pack has been made and is currently pending.

AssetPack_DOWNLOADING

The asset pack download is currently in-progress.

AssetPack_TRANSFERRING

The asset pack is being transferred to the app.

AssetPack_DOWNLOAD_COMPLETED

Download and transfer are both complete, and the assets are now available to the app.

AssetPack_DOWNLOAD_FAILED

The request to download the asset pack has failed.

AssetPack_DOWNLOAD_CANCELED

The request to download the asset pack has been cancelled.

AssetPack_WAITING_FOR_WIFI

The asset pack download is waiting for wi-fi bandwidth to proceed.

AssetPack_NOT_INSTALLED

The asset pack is not currently installed.

AssetPack_INFO_FAILED

A request for information about the asset pack has failed.

AssetPack_REMOVAL_PENDING

An async request to remove the asset pack has been made and is currently pending.

AssetPack_REMOVAL_FAILED

An async request to remove the asset pack has failed.

You can also use the download state handle to call GetBytesDownloaded, which will return the number of bytes currently downloaded to the user's device, and GetTotalBytesToDownload, which will return the total target size of the download.

Once you have finished using the download status information, you must call ReleaseDownloadState and provide the handle to release the cached download information from memory.

Removing Asset Packs

The function RequestRemoval takes in an asset pack name and removes the specified asset pack from the user's device asynchronously. The asset pack's removal status can be monitored with GetDownloadStatus as above.

Recommended Implementation

Implementation of the GooglePAD API can be modeled as a cycle of different states for each download.

State

Description

Accessing Asset Pack

Use GetAssetPackLocation to check if you already have an asset pack downloaded. You should run this first to avoid attempting to download assets you already have.

Use GetAssetsPath and GetStorageMethod to determine the file path and access method appropriate for the asset pack.

You must call ReleaseAssetPackLocation to free the memory for the cached location of the asset pack.

Initiating Download

If the desired asset pack isn't available locally, call RequestDownload to initiate the download.

In case of connectivity issues, you may need to repeat RequestDownload until it is successful.

Checking for Cellular Data Confirmation

Use ShowCelllarDataConfirmation to ensure that the application has permission to continue the download.

After the initial cellular data confirmation prompt, use GetShowCellularDataConfirmationStatus to output the current state of the prompt. This should occur continuously on a Tick function until the prompt is either canceled or confirmed.

Monitoring Download Status

Once RequestDownload has run successfully, use GetDownloadState to cache the download state and obtain a handle to access it with. This needs to be called only once, and you should cache the handle as long as you need it.

Use GetBytesDownloaded and GetTotalBytesToDownload to check the progress of the download. GetBytesDownloaded should run continuously on tick until you stop monitoring progress.

Use GetDownloadStatus to determine the exact state the download is in. This should also be monitored continuously on tick. When the state returns as AssetPack_DOWNLOAD_COMPLETED, you can stop monitoring the status of the download and access the asset pack.

When you are finished, you must call RelaseDownloadState to free the memory for the cached download state.

Implementing your solution in a custom GameState class will enable you to track a download continuously even as you change scenes and game modes. Alternatively, you may want to implement your solution in a front-end game mode that loads on startup so that you can perform necessary patches and updates before starting the game. The exact details of your solution will depend on your project's specific needs for updating assets.

Android Development Reference

Development Requirements

Debugging Android Projects

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Setting Up Android SDK and NDK

Setting Up Your Android Device For Development

Essential Setup

1. Packaging Your Project

2. Deploying A Packaged Project to Device

Packaging App Bundles

Choose your operating system:

Windows

macOS

Linux

This page takes a look how to package your Unreal Engine (UE) project for deployment to an Android device. The Android packaging process in UE is simple to use and outputs several convenient files for installing and uninstalling your project from phones for testing.

Essential Setup

First, it is better to fulfill the following requirements and project setup:

You will need Android Studio set up on your computer. See Setting up Android SDK and NDK.

Your Android device must have Development Mode and USB Debugging enabled. See Setting Up Your Android Device For Development.

You will need to configure your Project Settings for Android and accept the Android SDK license agreement. See the Android Quick Start Guide.

If you have not already created a project, create one using the Third Person Template, with Target Platform set to Mobile and quality set to Scalable.

1. Packaging Your Project

This section explaines how to package the project as a .APK file.

In the example package configuration is set to Development for testing this game, but when your game is complete, you can package it using Shipping configuration. Navigate to Platforms > Android and select Shipping for setting packaging configuration to Shipping.

In the File menu, go to Package Project > Android and select the Texture format you want to package. This example uses Android ETC2 as it is supported by all devices.



Click image for full view.





Click image for full view.

Different devices support different Texture formats depending on the hardware they run on. See, Android Development Reference for a detailed breakdown of the various formats.

Format

Description

ETC2

Supported by all OpenGL 3.x class devices and supports alpha compression.

DXT

Supported by Nvidia Tegra GPUs and supports alpha compression.

ASTC

Latest Texture compression format allowing more quality control by specifying block size and supports alpha compression. Available on some devices at this point.

If you are using an older version of Unreal Engine to support an existing project, you will also have access to the following legacy Texture formats.

Format

Description

ETC1

Supported by all Android based devices but cannot compress alpha textures (they are stored uncompressed). Recommend using an RGB and a separate alpha texture if need alpha to get better compression.

ETC1a

Uses ETC1 for non-alpha textures and ETC2 for alpha texture. If the device does not support ETC2, alpha textures will be uncompressed into RGBA at runtime. This format can be used on both ETC1 and ETC2 devices, but ETC1 for non-alpha textures may not be as high-quality as ETC2.

ATC

Supported by Qualcomm Adreno GPUs and supports alpha compression.

PVRTC

Supported by PowerVR GPUs and supports alpha compression.

You will be prompted for a location to save your packaged game, which should default to your project folder. Create a new folder and call it AndroidBuilds.







Click image for full view.

While your project is being packaged a packaging message will appear in the bottom right corner showing the progress of the packing.



Once packaging is successful, a Packaging Complete message will appear in the bottom right of the Editor.



Navigate to the folder you created in step two.







Click image for full view.

2. Deploying A Packaged Project to Device

Now that you have packaged your project as a .APK, this section will instruct you on how to deploy your build to a device.

Plug your Android device into your PC with a USB cable. If prompted, allow your PC to change files.

Double-click on the Install_[ProjectName]_Development.bat batch file to install the project on your Android device.



If you do not have your device plugged in via USB, running the .BAT file will do nothing.

Plug your Android device into your PC with a USB cable. If prompted, allow your PC to change files.

Open up the Android_ETC2 folder and then Double-click on the Install_[ProjectName]_Development_armv7-es3.command file to install the project on your Android device.

If you do not have your device plugged in via USB, running the .command file will do nothing.

Plug your Android device into your PC with a USB cable. If prompted, allow your PC to change files.

Open the Android_ETC2 folder, where you'll find the files that were created during the packaging process.



Click image for full view.

You should see the Installation and Uninstallation shell scripts (.sh) along with the Android Application Package (.apk) that contains all of the files you need to install the project onto any Android device that supports the ETC1 compression scheme.

Now, open up the terminal from this folder's location by right-clicking inside of the folder and selecting Open in Terminal.



Click image for full view.

Enter ./Install_LinuxAndroidProject_Development-arm64.es2.sh into the terminal to install the project onto your Android device.



Click image for full view.

If you're having trouble running the shell script, try entering adb devices into the terminal to verify that your device is connected to your computer.

During the installation process, the shell script should flush the following output to your terminal



Click image for full view.

When the shell script has completed the installation process, you should see an Installation successful message.

When you have completed this How-To, your project should appear on your Android device per the following image:



Click image for full view.

In addition, you will have packaged .APK files and accompanying helpers to deploy them to other devices for testing.

Packaging App Bundles

Android App Bundles are a distribution format offered by Google as an alternative to packaging .APKs. Instead of creating different .APKs for different subsets of devices, you can create a single Android App Bundle build (.aab) and upload it to the Google Play Store. The store's dynamic distribution system then uses the contents of the App Bundle to generate a .APK optimized for the user's specific device when they download the application.

In addition to greatly condensing the work involved in maintaining builds on the Google Play Store, App Bundle builds can distribute .APKs with up to 150 MB instead of the previous limit of 100 MB. This limit applies to the final .APK and not the App Bundle used to generate it.

To create an App Bundle Build, open your Project Settings and navigate to the Platforms > Android section. In the App Bundles section, enable Generate Bundle (AAB).



Click image for full view.

Now when you package a project for Android, you will generate a .aab file to upload to Google Play. You will also generate a universal .apk for testing purposes.

As a limitation of the Google Play Store, Android App Bundles can not be distributed with .obb files.

The other settings available for configuring App Bundle builds enable you to fine-tune the degree of sensitivity that the App Bundle will use in generating the final .apks for your project.

Setting

Description

Generate Universal APK from Bundle

Enabling this setting will allow the App Bundle to generate a universal .apk file for end-users, which can be run on any kind of device. This does not affect the universal .apk that is generated for testing on your machine.

Enable ABI Split

The App Bundle will generate separate .apks based on the Application Binary Interface used by the user's CPU. For example: arm64-v8a, x86, x86_64.

Enable language split

The App Bundle will generate separate .apks based on the user's language. Only strings localized for the user will be downloaded.

Enable density split

The App Bundle will generate separate .apks based on image resolution and DPI. Only icons and splash screens compatible with the user's device will be downloaded.

As an example, if you enabled ABI split but disabled language split, the .aab would tailor the final APK to a user's device based on the compatible ABI for their device, but every user would receive resources for all languages regardless of their device or language settings.

The default settings will result in the smallest possible size for the final .apk, while disabling these settings will result in larger .APKs.

For information on how to upload either .APKs or .AABs to the Google Play Store, refer to the guide on Shipping with Android.

Config Rules File

Config Rules Variables

Config Rules Commands

Config Rules Special Variables

Config Rules Profiles

Config Rules Dialog

Config Rules Build Files

The Android Configuration Rules system gives Android developers using Unreal Engine control over determining if a particular Android-based device has the needed hardware and software to run their project. The following information and steps will enable you to develop your UE4 projects for the devices and software you intend to support.

Config Rules File

To get started, create a new text file called configrules.txt and place it in your projects Build/Android directory.



Click for full image.

Once you have the configrules.txt file created and placed in the Build/Android directory, open it up in your text editor of choice and add the following text, making sure that it is the first item in the file.

The above text is the version code parsed by the ConfigRulesTool during packaging, and must be present in this form (one space between "//" and "version:", and no spaces after the colon). The number starts at one and should be incremented any time you update the file. UE4 will then use this number to determine if a newer version should be used than what is currently embedded in the Android Package (APK).

Any line that starts with a // or semicolon(;) is treated as a comment and ignored.

Commands are used to manipulate case-sensitive variables which either trigger an immediate action or are passed on to the engine. Any variables still defined after the Config Rules runs may be queried from C++ with the following function:

Example:

It is also possible to get access to a TMap with the key/value entries if you would like to iterate over them:

Example:

Config Rules Variables

Variables may be used in values with the following syntax:

This means that the following:

Would be replaced with the values of SRC_DeviceMake and SRC_DeviceModel separated by a space.

The following variables are defined automatically before configrules.txt is parsed:

Variable Name

Description

Example Value

memory

Total memory in megabytes.

3550

hardware

The chipset (either Hardware from /proc/cpuinfo or getprop ro.hardware).

Qualcomm Technologies, Inc SDM845

ro.hardware

The result from "getprop ro.hardware".

blueline

processor

Processor type from /proc/cpuinfo.

AArch64 Processor rev 12 (aarch64)

processorCount

Processor count from /proc/cpuinfo.

8

useAffinity

Whether or not to set thread affinity to little cores for some threads.

true

hasNEON

Indicates processor supports NEON features (SIMD).

true

isARM64

Indicates processor supports ARM64 ABI.

true

littleCoreMask

Bitmask indicating which cores are little.

0x0f

bigCoreMask

Bitmask indicating which cores are big.

0xf0

SRC_GpuVendor

Vendor from GLES20.glGetString(GLES20.GL_VENDOR).

Qualcomm

SRC_GpuFamily

GPU family from GLES20.glGetString(GLES20.GL_RENDERER).

Adreno (TM) 630

SRC_GlVersion

GL version from GLES20.glGetString(GLES20.GL_VERSION).

OpenGL ES 3.2 V@313.0 (GIT@3f88ca2, I42f6fe38fb) (Date:07/13/18)

SRC_AndroidVersion

Android version from android.os.Build.VERSION.RELEASE.

9

SRC_DeviceMake

Device manufacturer from android.os.Build.MANUFACTURER.

Google

SRC_DeviceModel

Device model from android.os.Build.MODEL.

Pixel 3

SRC_DeviceBuildNumber

Device build number from android.os.Build.DISPLAY.

PD1A.180720.030

SRC_VulkanVersion

Version of Vulkan support.

1.1.0

SRC_VulkanAvailable

Indicates if Vulkan is supported by the device.

true

SRC_UsingHoudini

Indicates ARM emulated on Intel processor by Houdini.

false

SRC_SDKLevel

SDK level from android.os.Build.VERSION.SDK_INT.

28

supportsFloatingPointRenderTargets

Indicates GPU supports FP render targets.

true

TextureFormats

Comma-separated list of supported texture formats by GPU.

ASTC,ATC,ETC2,ETC1

navigationBarHeight

Height of Android navigation bar in pixels.

132

statusBarHeight

Height of Android status bar in pixels.

66

screenWidth

Screen width in pixels.

1080

screenHeight

Screen height in pixels.

2160

Config Rules Commands

Commands can be used with valid arguments in the forum of action:argument. These are defined below along with use case examples.

Set allows you to assign one or more variables and their specified values:

If you have more than one variable, you can use a comma (,) to separate them:

clear allows you to clear the value assigned to variables.

You can clear more than one variable at a time using a comma (,) to separate the values you want to clear.

condition evaluates the list of conditions and if all are true it applies optional set and clear commands.

The comparisons are made up of three parts in parentheses separated by commas. The three parts are SourceType, CompareType, and MatchString.

SourceType specifies the first argument for comparison and will usually be a variable name. The following are the three special SourceType values that can be used:

Command Name

Description

SRC_PreviousRegexMatch

The group returned from the last regex expression condition.

SRC_CommandLine

The command line embedded in the APK.

[EXIST]

Used with MatchString to see if a variable exists or not.

MatchString is any string value to use for the comparison or the variable name for the [EXIST] case.

CompareType may be one of the following:

Command Name

Description

CMP_Exist

True if variable name in MatchString is set.

CMP_NotExist

True if variable name in MatchString is not set.

CMP_Equal

True if variable name in MatchString is not set.

CMP_NotEqual

True if SourceType not equal to MatchString.

CMP_EqualIgnore

True if SourceType equals MatchString, ignoring case.

CMP_NotEqualIgnore

True if SourceType does not equal Matchstring, ignoring case.

CMP_Less

True if value of SourceType < value of MatchString.

CMP_LessEqual

True if value of SourceType <= value of MatchString.

CMP_Greater

True if value of SourceType > value of MatchString.

CMP_GreaterEqual

True if value of SourceType >= value of MatchString

CMP_Regex

True if regex in MatchString found in SourceType (matching group is available in SRC_PreviousRegexMatch for additional condition checks)

The following examples show how you might setup and use the Android Config Rules Commands in your UE4 projects:

The following code will set myvar to arm64 if isARM64 is true:

The following code will set myvar to arm64 if isARM64 is true and clears notsupported:

The following code uses Regex to extract the number in Adreno (TM) 630 and compares it to see if it is less than 510 to flag an error.:

chipset is a shortcut to set a group of variables if the hardware string is equal to either ro.hardware or hardware. It sets useAffinity, chipset, GPU, processorCount, bigCoreMask, and littleCoreMask. useAffinity controls whether or not taskgroup threads are restricted to the little cores with the littleCoreMask.:

Here are some examples:

Config Rules Special Variables

There are two special variables which trigger actions if set:

The value of log after any command is evaluated will be written to the logcat output and cleared.

This will dump all the variables currently set and their values to logcat.

Config Rules Profiles

You can set the Profile variable to override the device profile used instead of the one that would be picked by the AndroidDeviceProfileMatchingRules in DefaultDeviceProfiles.ini. If this value is not modified the normal rules will still apply. The following example would force the Android_Galaxy_S9Plus_Adreno setting for SM-G965 models:

Config Rules Dialog

You can customize the error and warning dialog messages that are displayed using the following variables:

caption

exitbutton

continuebutton

updatebutton

helpbutton

The value placed in the caption or buttons is looked up in the string table to get the localized text for the dialog. You should make these string names unique and place them in a ConfigurationStrings.xml file in your project's Build/Android/res/values directory for each localized language your project supports. (values-fr, for example, would be for French).

An example of where the ConfigurationStrings.xml file should be placed is shown below.



Click for full image.

Error - You can signal an error by setting the error variable. The dialog will show the string table entry for the value you assign to it. All processing of the configrules.txt will stop once this is set and the user will not be able to continue into your application.

Warning - A Warning dialog is triggered by setting the warning variable. The dialog will provide a continue option and optionally update and/or help buttons if the corresponding variables are set. The help button will launch an external browser to the URL specified by the link variable. Evaluation of configrules.txt will continue until the end or error is set before the dialog is shown so you can change it again with different conditions if necessary.

The following example code was setup to display an error is the user tried to use an Android device that does not support ARM64.

When the above example is encountered, the error message that is displayed will come from the following string table.

Config Rules Build Files

The following additions to your project are required for the configrules.txt file to be included in your APK by compressing, and optionally encrypting, it. Start by registering the following Unreal Plugin Language (UPL) code in your project's Build.cs file:

Next you will want to create a new file called MyGame_UPL.xm****l which is placed in the same directory with the Build.cs file.



Click for full image.

Open up the MyGame_UPL.xml file and then add the following code, saving the file when done (change the ConfigRulesKey to contain your unique encryption key):

Setting Device Profiles

Scalability

Configuration Files

Console Variables in C++

Configs and Order of Priority

Android Device Profiles

Device Profile Matching Rules

Enabling Vulkan

Scalability Settings

Understanding Scalability Values

Overriding Scalability Settings

Setting Scalability Values in Device Profiles

Changing Scalability Settings at Runtime

Using the Settings Menu in Unreal Editor

Changing Scalability Settings with Console Commands

Changing Scalability Settings in Blueprint

Changing Scalability Settings in C++

Unreal Engine uses device profiles and scalability settings to customize rendering settings on a per-hardware basis. Scalability settings define levels of quality for individual features like shadows, foliage, and mesh detail, condensing an array of different settings into one easily scaled value. Device profiles then map those settings to devices that are compatible with them.

Android has a large array of profiles matched to specific GPU families. This guide will explain the device-matching rules, how to edit them, and how you can work with scalability settings to create profiles that fit your game's specific needs.

Configs and Order of Priority

Configs in Unreal Engine are read from both your Engine's install directory and your project folder. The Engine/Config folder sets the base config settings for the Engine. After that, they override each other in the following order:



Engine/Config/Base*.ini

Project/Config/Base*.ini

Engine/Config/Android/Android*.ini

Project/Config/Android/Android*.ini

As an example, the AndroidDeviceProfiles.ini file in Engine/Config/Android takes precedence over BaseDeviceProfiles.ini in both Engine/Config and Project/Config. The AndroidDeviceProfiles.ini in Project/Config/Android takes precedence over all of the above.

Android Device Profiles

The standard Android device profiles are Android_Low, Android_Mid, and Android_High. The Android_High profile represents the full range of features that Unreal Engine supports on the highest-end Android devices, while Android_Low represents the minimum feature set for the lowest-end Android devices.

We also categorize more specific device profiles based on the GPU families supported by Unreal Engine, due to the fact that mobile devices with the same GPU typically have similar performance characteristics. These GPU-specific device profiles usually map one of the standard profiles (like Android_High) to specific devices, but occasionally they need to provide special case tweaks.

For example, the following device profiles are for Adreno 5xx devices in Unreal Engine 4.24:

BaseDeviceProfiles.ini

The standard Android_Adreno5xx device profile inherits from Android_High for all of its base settings, with only one override for rDisjointTimerQueries. The Android_Adreno5xx_No_Vulkan profile then inherits from the standard Android_Adreno5xx profile, and provides another override disabling support for the Vulkan renderer due to issues on older Adreno5xx devices.

Depending on your game's content you may need to override existing profiles or provide new ones within your project's AndroidDeviceProfiles.ini. You can extend these GPU-specific profiles further to represent even more specific devices within these GPU families if need be, or you can re-write any previously defined profiles completely.

Device Profile Matching Rules

When an Unreal Engine application launches, it loads information about the device that is running it. The application then iterates through a list of rules that identify devices based on these parameters. These can be found in **BaseDeviceProfiles.ini**, under the section [/Script/AndroidDeviceProfileSelector.AndroidDeviceProfileMatchingRules]. When the application finds a rule that matches the device information retrieved, it stops running through the list and uses that device profile.

The format for an entry in this list is as follows:

The rules themselves are string comparisons taking the following format:

Depending on what value you supply to SourceType, it will output a source string that the system will then compare MatchString to.

The values that are valid for SourceType and their corresponding source string outputs are as follows:

SourceType Value

Description

Example Output

SRC_DeviceModel

The model number of the device.

"Nexus 6"

SRC_DeviceMake

The manufacturer of the device.

"NVidia"

SRC_GPUFamily

The GPU family of the GPU in this device.

"Adreno (TM) 320", "NVIDIA Tegra"

SRC_GlVersion

The OpenGL version this device is running.

OpenGL ES 3

SRC_AndroidVersion

The version of the Android operating system used by this device.

Any numeric value.

SRC_VulkanAvailable

Checks to see if the application was packaged with Vulkan enabled, and if the device supports the required version of Vulkan specified in your Project Settings.

False if Vulkan is not available, true if it is.

SRC_VulkanVersion

The version of Vulkan this device uses, if available.

Any numeric value.

SRC_PreviousRegexMatch

The value of a previous regex match within the same MatchProfile entry.

Any information previously output by a regex match.

The comparison types available are as follows:

Comparison Type

Description

CMP_Regex

Performs a comparison that uses regex operators in the MatchString.

CMP_Equal

Check that the values of the two strings are exactly the same.

CMP_EqualIgnore

As CMP_Equal, but ignores case-sensitivity.

CMP_NotEqual

Check that the values of the two strings are not the same.

CMP_NotEqualIgnore

As CMP_NotEqual, but ignores case-sensitivity.

CMP_Less

Checks to see if the numeric value of the source string is less than the MatchString.

CMP_LessIgnore

As CMP_Less, but ignores case-sensitivity.

CMP_LessEqual

As CMP_Less, but returns true if the source and MatchString are equal as well.

CMP_LessEqualIgnore

As CMP_LessEqual, but ignores case-sensitivity.

CMP_Greater

Checks to see if the numeric value of the source string is greater than the MatchString.

CMP_GreaterIgnore

As CMP_Greater, but ignores case-sensitivity.

CMP_GreaterEqual

As CMP_Greater, but returns true if the source and MatchString are equal as well.

CMP_GreaterEqualIgnore

As CMP_GreaterEqual, but ignores case-sensitivity.

As an example, the following is an entry for Mali T8xx devices in 4.24:

BaseDeviceProfiles.ini

This MatchProfile entry has three rules:

There must be a regex match for the GPU family with the string "^Mali\-T8".

The Android version must have one or more digits, and the digits will be remembered until a non-digit is found.

The Android version obtained from the second rule must be less than 8.

If all of these criteria are met, it will use the profile Android_Mali_T8xx_No_Vulkan.

The device profile rules are listed first by manufacturer, and then in ascending order from the lowest-end specifications to the highest. The standard Android profiles are listed as fallbacks in case none of the rules fit and the specific device cannot be identified.

If you add any rules to this list, make sure that you place them in the appropriate order relative to other devices within the same family.

Enabling Vulkan

A special parameter called VulkanAvailable is used to discern whether or not a device can use the Android Vulkan renderer. It first checks to see if the game itself has Vulkan support enabled, then checks to see if the device has Vulkan drivers. If both of these conditions are met, then VulkanAvailable is considered true.

Devices that support Vulkan have profiles both with and without Vulkan enabled to account for projects that do not use Vulkan even though it is available on the target device. All profiles have a parameter called r.Android.DisableVulkanSupport, which by default is set to 1. Vulkan-enabled device profiles override this parameter to 0.

Enabling Vulkan is only recommended for devices running Android 9 or higher, as the earliest devices with Vulkan support had a number of bugs in their drivers.

Scalability Settings

Unreal Engine's base Scalability Settings are defined in Engine/Config/BaseScalability.ini, which can be found in your engine install directory. The Scalability Settings for Android devices are defined in Engine/Config/Android/AndroidScalability.ini.



Understanding Scalability Values

Scalability settings take in broad sets of parameters and condense them under broad categories that can then be defined with simple values between 0 and 3. For example, this is the scalability mapping for ShadowQuality level 0 in BaseScalability.ini:

BaseScalability.ini

Each of the values listed represent highly specific features, and each of them has their own scale. For example, some work in terms of pixel resolution, some work in terms of a scale factor that multiplies a default value, and some are more arbitrary. These can be overwhelming to define on a per-feature basis, and they need to be tweaked in-between releases as hardware is frequently updated.

Therefore, we use ShadowQuality to condense a group of related settings under a single, human-readable value. The above entry defines how all of these values behave when sg.ShadowQuality is set to 0 in a config file. Similar entries exist for ShadowQuality@1 through 3.

The guidelines for these default scalability values are as follows:

Scalability Value

Description

0

Low quality. The lowest settings that are compatible with the minimum range of hardware that Unreal Engine supports.

1

Medium quality. Settings that are comfortable on a broad range of hardware in-between the lowest-end and highest-end devices that Unreal Engine has been tested on.

2

High quality. Settings that are comfortable on most high-end hardware that Unreal Engine has been tested on.

3

Epic quality. The highest values possible for a given feature on the current version of Unreal Engine.

Overriding Scalability Settings

To override scalability settings, you can create an AndroidScalability.ini in your project's own Config directory. For example, if you have a project called AndroidQuickStart, you would place it in AndroidQuickStart/Config/Android.



Any scalability settings created in this file will take precedence over the settings defined in Engine/Config/Android/AndroidScalability.ini.

Setting Scalability Values in Device Profiles

To refer to a scalability value in device profiles, use the prefix sg. followed by the name of the value you want to set. For example, if you wanted to set ShadowQuality to 1 in a device profile, you would use the following:

Any settings that you list after this scalability value will take precedence over its original value. However, it is strongly recommended that you change scalability parameters inside your *Scalability.ini files and observe the scalability groups consistently instead changing small-scale parameters inside of device profiles. This ensures that Preview Rendering Level inside the Editor accurately applies mobile scalability values.

Changing Scalability Settings at Runtime

The initial scalability settings selected by a device profile are simply the defaults, and scalability can easily be changed at runtime through a variety of methods.

Using the Settings Menu in Unreal Editor

For testing purposes, you may change the scalability settings in your game inside Unreal Editor by clicking the Settings dropdown in the toolbar and navigating to Engine Scalability Settings.



Click image for full size.

Any changes made in this menu are applied immediately.

Changing Scalability Settings with Console Commands

You may also refer to any scalability setting as a console command. For example, if you type sg.FoliageQuality 2 inside the console and press Enter key, it will change the value of all the CVars under FoliageQuality accordingly.



The values in the Engine Scalability Settings menu will reflect this change.



You may also output the current value of a scalability setting by typing in its name as a console command, with no numeric value. For example, if you type sg.FoliageQuality and press enter, the console will print both the current value of FoliageQuality and the last place where it was set.



Changing Scalability Settings in Blueprint

While you can use console commands through Blueprint to change scalability settings, they are also accessible through dedicated functions as a part of Game User Settings, which you can get a reference to using the Get Game User Settings node.



Click image for full size.

You can use this functionality together with UMG to build menus where your users can change these settings. This enables users to customize a game's graphics and performance as desired.

Changing Scalability Settings in C++

In C++, Game User Settings can be accessed with the static function UGameUserSettings::GetGameUserSettings. You can then use its dedicated get and set functions to get and set the quality level on scalability settings.

Steps

End Result

You can use Android Studio to debug the C++ and Java code used in your Unreal Engine (UE) projects. This tutorial will guide you on how to set up Android Studio for this process.

Steps

In the following section, we will go over how to download and set setup Android Studio so that it will work with a UE project.

If you have not already done so, download and install the version of Android Studio that is compatible with your current build of Unreal Engine. Refer to the Development Requirements page for information on which version to use, and the Android SDK and NDK Setup guide for information about how to set up your environment.

Build the APK that you want to debug and then deploy it to your Android device you will be using for debugging.



Click image for full size.

Open the Android Studio Launcher and from the displayed options, then select the Open an existing Android Studio Project.



Click image for full size.

From the Open File or Project menu, navigate to C:\YourProjectName\Intermediate\Android\APK\Gradle and select the Gradle directory, then press the OK button.



Once Android Studio is open, go to the Run Menu and select the Edit Configurations option.



Click image for full size.

Click on the Debugger tab and set the debug type to Dual.



Click image for full size.

Next, go to the LLDB Startup Command tab, press plus icon (+) and then input the following line, pressing the OK button to complete the process.

Note that TEXT("string") should be used instead of L("string") in your C++ code.



Click image for full size.

Make sure to press the Enter key or the command will not take.

Now, open up any of your project's .cpp files and add breakpoints to items you want to debug.



Click image for full size.

From the main menu, select Run > Debug 'app-app'.



Click image for full size.

When the Select Deployment Type windows is displayed, select your device from the list and press the OK button.



Click image for full size.

End Result

Once all of that has been completed, wait for the debugger to attach to your Android Device.



Click image for full size.

Depending on the size of your project, it could take some time for the debugger to attach. This also does not install the data on the device if you don't use the Package data inside APK option. Doing so will make the redeploying for debugging slower since the APK will be larger. Another option is to first do a Launch on in the editor before using Android Studio for debugging to install the current level on the device. Alternatively, you can package and install the OBB on the device if you need more than the current level data.

1. Downloading and Installing the AGDE

1A. Setting Up JDK

2. Launching a Project With AGDE

3. Attaching AGDE to an Application

More Information

Unreal Engine (UE) supports debugging with the Android Game Development Extension (AGDE) Plugin for Visual Studio, which provides debugging and profiling tools for Android projects in Visual Studio without the need to switch environments to Android Studio. This is the recommended debugging environment for Android projects in UE for Windows users.

This guide will walk you through the process of downloading and enabling this plugin, and provide links to helpful resources for using it.

1. Downloading and Installing the AGDE

To install the AGDE plugin and set up your project's solution to work with it, follow these steps:

Make sure you have installed Visual Studio 2019 and are using it as your default Visual Studio version for Unreal Engine.

Download the AGDE plugin from the



Install the AGDE Plugin to Visual Studio.

Locate the .uproject file for your project, right-click it to open the context menu, then click Generate Project Files to regenerate your Visual Studio solution.

The new solution files will have the plugin enabled by default.

1A. Setting Up JDK

When you open Visual Studio, you may see an error stating that your JDK installation is not the correct version. This will prevent Unreal Automation Tool (UAT) from packaging projects due to gradle errors. Follow these steps to install the correct version:

Download the required version of Java SE from the Java SE Archives. For example, if the Visual Studio error says you need JDK 11, download Java SE 11.

Do not install a newer version of JDK than the one recommended in Visual Studio, as there may be compatibility issues.

After your download completes, install Java SE to your computer. Take note of the directory where you installed it.

Open the Search Bar and find Edit the System Environment Variables. Click this option to open the System Properties dialog.

Click the Environment Variables button.

Select the JAVA_HOME environment variable (if available), click Edit, and set the directory to the location where you installed JDK.





Reboot your computer so the environment variable changes take effect.

Once you have finished, your computer will now use a version of JDK that is compatible with the AGDE plugin.

2. Launching a Project With AGDE

AGDE can debug or attach to Unreal Engine applications on your Android device. This requires you to set some configuration options in Visual Studio, and you also need to package an APK before using AGDE, as it can compile your Android project's code but can not cook content. Follow these steps to launch your project on your device.

Use the BuildCookRun command to package your project for Android. You can also use Turnkey or the Platforms dropdown in Unreal Editor.





Refer to Build Operations and Cooking Content for more information about the cooking and packaging process.

Open your project's Visual Studio solution.

Set your Solution Configuration to DebugGame and your Solution Platform to Android.

Plug the Android device you want to test with into your computer with a USB cable. When the device asks if you want to grant permission for USB debugging or permission for the computer to access the device's data, grant it.

When using a USB connection, make sure the cable and port on your computer both support data.

The button to build and debug your project should now display the device's name. Either click it or press F5 to begin debugging. You may need to wait for the debugger.

If you encounter a SIGILL error, press F5 to skip through the error and continue running AGDE.

The project will build and launch on your device, and you will be able to use Visual Studio's debugging tools just like you would for a Windows application.

3. Attaching AGDE to an Application

To attach to a running instance of your Unreal Engine application, follow these steps:

Click the Debug dropdown in the toolbar, then click Attach to Process.





Set the Connection Type to Android Game Development Extension.

Click the Connection Target dropdown and click the entry for your device.

Select the process for your application, then click Attach.





More Information

For more information on AGDE's features, refer to the following documentation:

Overview: https://developer.android.com/games/agde

Project Configuration: https://developer.android.com/games/agde/adapt-existing-project

Debugger Guide: https://developer.android.com/games/agde/debugger

Profiling: https://developer.android.com/games/agde/measure

Configuration and Setup

Packaging Settings

Deployment Settings (Logging and Compression)

Connection Settings

Manually Starting and Stopping AFS With Blueprints

UnrealAndroidFileTool

Command Reference

Android File Server (AFS) is an Unreal Engine (UE) plugin that embeds a file server with your Android application when you package a Development, Debug, or Test project (or optionally a Shipping project, see below) build. As long as the file server is running, you can use the UnrealAndroidFileTool to manage, push, and view files. In builds that include AFS, Unreal Engine uses it for deploying Quick Launches. Together, AFS and UnrealAndroidFileTool are an alternative to using Android Debug Bridge (ADB), providing many of the same capabilities tailored to Unreal Engine's workflow.

Instead of using the device's SD card external storage for handling Quick Launches, AFS uses the package sandbox storage. This makes it possible to use file operations without requiring storage permissions or scoped access, which can be cumbersome to continually re-enable as you develop a project and deploy builds. AFS can also operate over WiFi connections, USB connections, or both for faster deployment.

Configuration and Setup

This section explains how to configure AFS's packaging and connections. You can find these settings in Project Settings > Plugins > AndroidFileServer. This section lists each of the available parameters to configure.



Packaging Settings

The Packaging section contains settings configuring what type of builds will include AFS and what capabilities the file server will have. AFS is enabled by default, and non-shipping builds will automatically embed a file server with your project unless it is disabled. AFS is not included in Shipping builds by default, but there are settings to enable it.

Parameter

Description

Use AndroidFileServer

If enabled, your project will include the embedded file server for packaged and Quick Launch builds. If disabled, AFS will not be used in your project, and Unreal Engine falls back to using ADB.

Allow Network Connection

If enabled, AFS allows WiFi connections and connections through USB. Refer to Connection Settings for more details.

Security Token

A unique string you can use to secure AFS and prevent it from being started remotely by anyone without the token. Refer to Using Security Tokens for more details.

Include in Shipping

If enabled, AFS will be included in Shipping builds. Refer to Using AFS in Shipping Builds for more details.

Allow External Start in Shipping

Paired with Include in Shipping, this allows external requests to start the file server with UnrealAndroidFileTool or for Quick Launch.

Compile AFSProject

If enabled, Unreal Engine will compile AFS as a separate APK when it packages your project. Refer to Compiling AFSProject for more information.

Shipping builds do not normally include AFS, but you can enable Include in Shipping and Allow External Start in Shipping to add it. If you only enable Include in Shipping, you can still use AFS, but it won't be used for Quick Launches, and you will need to manually start and stop it from inside your application.

When using non-Shipping builds, or with External Start enabled for Shipping builds, a receiver is registered to allow remote start and stop of the file server. You can then use the UnrealAndroidFileTool to connect to your device's file server and manage files. Otherwise, with AFS enabled, you need to start the file server manually from inside your Unreal Engine application. Refer to Manually Starting and Stopping AFS with Blueprints for more information.

If you fill in the Security Token field, your file server will require any incoming connection requests from UnrealAndroidFileTool to provide a matching Security Token. Refer to the UnrealAndroidFileTool reference for more information.

The Security Token offers only basic security, and is not encrypted in any way. You can use the Android File Server Blueprint library to provide more robust security of your own in Shipping builds. When using the Security Token, make sure not to give the token to anyone outside of your organization.

If Compile AFSProject is enabled, a standalone APK containing the file server will be packaged which matches your project's configuration and key signing. You may install this APK to the device to manage new or existing files with the adb install -r option. Afterwards, you may reinstall your actual APK with the same option without affecting the internal or external data files. This is especially useful if you need to manage files on a Shipping build that doesn't have the server built-in.

Shipping builds compile AFSProject regardless of whether Compile AFSProject is enabled.

Deployment Settings (Logging and Compression)

The settings in the Deployment section control what information the file server reports in your logs.

Parameter

Description

Use Compression (Beta)

Applies compression to data files on your file server. In UE 5.0, currently this has minimal impact on transfer time.

Log Files

Shows a list of files being pushed to the device.

Report Stats

Shows a listing of how many files are pushed to the device and the number of bytes pushed over your connection.

When the log output settings are enabled, Unreal Engine logs information about AFS's installation process in the Console window during Quick Launches.

If USB and Network are both enabled, the AFS log will show a prefix denoting what type of connection the file was sent through.

Prefix

Description

1>

File was sent over USB.

2>

File was sent over Wifi.

For example, the following line indicates that a map file was sent through USB:

If you are using both USB and WiFi, one connection will take over while the other is busy.

Connection Settings

The Connection section contains options for configuring what kind of connections AFS will use to connect your computer to a device.

Parameter

Description

Connection Type

Determines whether to use USB, WiFi, or both to connect with your file server.

Use Manual IP Address

If enabled, the Quick Launch will use the Android device at the IP provided in the Manual IP Address field. Otherwise, it will try to discover the IP address over USB if connected.

Manual IP Address

The IP address of an Android device you want to connect to for Quick Launch. The device must be connected to your local WiFi network.

The Connection Type dropdown selects what kind of connection to use to push files.

Connection Type

Description

USB

Pushes files over a USB connection to your Android device.

WiFi Network

Pushes files over a WiFi connection to an Android device on the same local area WiFi network as your computer. This requires the Allow Network Connection setting to be enabled.

USB and Network Combined

Simultaneously uses a USB connection and a WiFi connection to push files. Whenever one connection is occupied transferring a file or a batch of files, the other will take over for the next file in the queue. This results in faster file transfers. This is integrated as part of the deployment process.

Unless you override it, the default port for AFS is 57099.

If you enable the Use Manual IP Address setting and provide an IP address for your Android device, when you deploy your build, AFS will connect to that device instead of the default device in the normal Device Manager workflow. The device must still be connected to the same WiFi network as your computer.

Manually Starting and Stopping AFS With Blueprints

You can use the Android File Server Blueprint library to manually start, stop, and check the status of your file server from inside your UE application.



Node

Description

Start File Server

Starts the file server using the designated Port for connections. You can choose whether to allow USB or Network connections when you use this node to start the server. The return value is a boolean indicating whether the server started successfully.

Stop File Server

Shuts down the file server if it is running. You can choose to close only specific connection types. The return value is a boolean indicating whether the server shut down successfully.

Is File Server Running

Returns the current status of the file server with EAFSActiveType. This will return None (0) if it is inactive, or if it is active, it will return one of the following:

USB only

Network only

USB and Network combined



While AFS can provide basic security using a unique token generated for your project, these Blueprint nodes are useful for creating more secure ways to start and stop AFS compared with using the default broadcast receiver.

UnrealAndroidFileTool

UnrealAndroidFileTool is a command-line tool that can connect with the file server deployed on your device to manually manage files. You can find it in your engine's install directory under Engine/Binaries/DotNET/Android/UnrealAndroidFileTool. This directory includes folders for Linux, MacOS, and Windows versions of the executable.



If you need versions of UnrealAndroidFileTool executable for all three operating systems, open Project Settings > Platforms > Android and enable Generate Install Files for all platforms. If this setting is not enabled, Unreal Engine will only provide the executable that matches the editor host type in the packaged target directory.



When you run this executable through a command line, it will show a menu with all of its available functions. You can run the executable with any of these commands appended in your command line.



Command Reference

Commands for UnrealAndroidFileTool consist of a set of parameters telling the tool what to establish a connection with, followed by a command to send to the file server. For example, the following would run the shell command on a device with a specific serial number and look at the files for a specific project:

Paths in AFS use the normal conventions for command line paths, but they also support several shortcuts for navigating the file hierarchy:

Text

Description

^^

Refers to the current base directory you set with the cd command. Refer to Query and Navigation Commands for more information.

^-n

Move up a specified number of directories, where n is the desired number. For example, ^-3 would move up three directories. This makes it easier to handle relative paths without using multiple instances of /..

^[key]

Used at the start of a filepath to either act as a shortcut or query a given key, where [key] is replaced with the key's text. For instance, ^ext/ is the external package directory, and ^commandfile is a shortcut to the UECommandLine.txt file. See the table below for a list of useful shortcuts.

The following are some common shortcuts using ^[key]. You do not have to use these, but they are convenient.

Shortcut

Description

Shortcuts to Directories

^ext/

External storage directory.

^int/

Internal storage directory.

^storage/

External storage directory (requires READ_EXTERNAL_STORAGE and/or WRITE_EXTERNAL_STORAGE permissions).

^obb/

The obb directory.

^unreal/

The UnrealGame directory.

^project/

The UnrealGame/[project] directory.

^engine/

The UnrealGame/Engine directory.

^game/

The UnrealGame/[project]/[project] directory.

^saved/

The Saved directory.

^logs/

The Logs directory.

Shortcuts to Specific Files

^commandfile

The UECommandLine.txt file.

^logfile

The project log file.

^mainobb

The main .obb filepath.

^patchobb

The patch .obb filepath.

Non-filepath Queries

^packagename

Package name of the project.

^version

Package version code.

^ip

IP address of the device on the network.

The following parameters can be placed before a file server command to configure your connection for specific target devices and projects.

Command

Description

-s [device serial number]

Sends the command to the device with the given serial number.

-ip [IP address]

Connects to a device with the given IP address.

-t [port]

Overrides the port used to connect to the device. If not otherwise specified, the default port will be 57099.

-p [package name]

The reverse-domain package name for the application you want to connect with. For example: com.OrganizationName.ProjectName. Package names are case-sensitive and must exactly match the string given in your project settings.

-k [security token]

Provides the security token needed to connect to the file server, as described under Using Security Tokens.

The following table is a reference for the commands you can use to get information about available devices and recognized packages, or to stop remote servers.

Command

Description

help [command]

If you use the help command alongside the name of another command that has parameters, UnrealAndroidFileTool provides more information about that command and how to format it.

devices

Displays a list of connected devices that you can access. Devices with an @ prefix are authorized devices. Do not include the @ when providing a serial number with -s.

packages

Displays a list of packages with the AFS receiver enabled.

stop-all [-w]

Send a stop request to all packages with receivers. If you add -w, UnrealAndroidFileTool will wait for all listen binds to terminate before you can interact with it again.

terminate

Stops the designated remote server.

Any command that interacts with a file server, such as push, pull, or shell, implicitly requests for it to start, so there are no commands for starting a server.

You can use the following commands to enter and exit Interactive Mode. Interactive Mode functions similarly to ADB, opening a connection with the device and giving you a way to send multiple commands without having to run UnrealAndroidFileTool.exe for each command. UnrealAndroidFileTool will remain in Interactive Mode until you exit.

Command

Description

shell

Enters interactive mode.

quit or exit

Exit interactive mode.

The following commands fetch information about directories and files on your device, or provide navigation for your base directory during interactive mode.

Command

Description

query [key]

Show all variables with a specific key.

getprop [key]

Get the property associated with the given key.

cd [path]

Set the base directory. You can then use ^^ to refer to this directory instead of manually typing it out.

pwd

Show the current base directory.

direxists [path]

Outputs whether the directory at the provided path exists.

ls [-l,-s,-R,-f] [path]

Shows the contents of the directory at the provided path. The listed specifiers designate what information to output:

-l: List permissions. -s: List size. -R: List recursive directory tree. -f: List flat.

The following commands interact with or modify files on your device.

Command

Description

mkdir [path]

Create a directory at the given path.

rmdir [path]

Delete a directory at the given path.

fileexists [file]

Outputs whether the named file exists.

rm [file]

Delete the named file.

cp [source] [destination]

Copies the [source] file to the given [destination] directory on the device.

mv [source] [destination]

Moves a [source] file to the given [destination] directory on your mobile device.

pull [source] [destination]

Copies a [source] file from your mobile device to the given [destination] directory on your PC.

push [-c] [source] [destination]

Copies a [source] file on your PC to the given [destination] directory on your mobile device. If you add the -c parameter, UnrealAndroidFileTool will compress the data.

cat [file]

Writes file contents from the device to the output log.

deploy [-c] [file]

Reads a text file with deployment source/destination pairs. If you add the -c parameter, UnrealAndroidFileTool will compress the files.

The following commands interact with or modify the UECommandLine.txt file for your project on your remote device.

Command

Description

command [data]

Writes data to the UECommandLine.txt file. If you provide no data, it will show the contents of the file.

addcommand [data]

Appends data to the UECommandLine.txt file.

delcommand [data]

Removes data from the UECommandLine.txt file.



Changes Since UE4

Advanced Optimizations

Mobile storefronts limit the amount of data that can be sent to a device, especially when delivering games over cellular data. Many stores impose mandatory limits on the size of APKs and OBBs. Because of this, it is a best practice to reduce the size of mobile applications as much as possible. Content delivery systems like [Google Play Asset Delivery]() and [ChunkDownloader]() can reduce the size of your core executable significantly by separating assets from binaries, but it is helpful to optimize your binary size as well.

This page provides a guide for the Unreal Engine (UE) tools that you can use to optimize your Android projects' binaries.

Changes Since UE4

UE5 ships with updated compiler and linker flags that enable dead code elimination and identical code folding. Some UE4 code has been also rewritten for UE5 to reduce code bloat; this provides significant savings. These changes are enabled by default and do not require you to take any action.

Advanced Optimizations

Other, more advanced binary optimizations are only available with specific Android SDK versions and must be manually activated. You can change your minimum SDK version in Project Settings > Platforms > Android, or you can change it in your *Engine.ini file:

To enable advanced optimizations, add the following setting to your *AndroidEngine.ini file:

After that, the optimizations available for your SDK version will be applied when packaging your project. These optimizations are summarized below.

On Android SDK 23 or Higher

The following optimizations are available if your project's minimum Android SDK version is 23.

Projects on SDK 23 and up use the new GNU hash ELF section instead of the previous format. This provides better performance and faster startup times.

Additionally, your project will take advantage of APS relocation table compression, an Android-specific compression format. In our tests, a relocation table with a size of 62 MB was reduced to roughly 8 MB using this format.

If you set your minimum SDK version to 23 or higher, Android OS can load .so binaries from your application's APK directly, eliminating the need to unpack and install them on the device separately from a compressed APK.

Unreal Engine enforces APK compression by default, but you can disable it with the following config variable in your *Engine.ini file:

If you set bExtractNativeLibs to false, your application will load .so binaries directly and avoid compression. However, if your APK is under the Google Play Store's 150 MB cellular data limit, we recommend disabling this setting because Google Play Store's on-the-fly compression provides smaller file sizes than the zip compression in an APK and reduces cellular traffic caused by your application.

If you leave bExtractNativeLibs enabled, it will generate a smaller APK, but the OS will unpack it and install the .so binaries separately, effectively consuming more disk space. However, this is recommended for stores other than the Google Play Store.

On Android SDK 28 or Higher

The following optimizations are available if your project's minimum Android SDK version is 28.

Projects with a minimum SDK version of 28 or higher can take advantage of RELR relocation table compression, which is even more efficient than APS. For example, a 62 MB relocation table was reduced to roughly 600 KB when using RELR, which is a reduction of two orders of magnitude. RELR also provides higher performance than APS.

Developing for Head-Mounted XR Experiences with OpenXR

Developing for Handheld Augmented Reality Experiences

Getting Started with XR

Making Interactive XR Experiences

Creating UI for XR Experiences

Shared Experiences in XR

Supported XR Platforms in Unreal Engine

Performance and Profiling with XR

Using XR for Content Creation

XR refers to the collection of the following experiences:

Augmented reality: Where sensory information overlays the user's view of the real world through a handheld or wearable device.

Virtual reality: Where a virtual environment replaces the user's view through a wearable device.

Mixed reality: Where an experience is a blend between augmented reality and virtual reality.

Unreal Engine supports both developing for XR platforms and using XR devices in your content creation pipeline. The sections below contain links to documentation on how you can work with XR devices in your projects.

Developing for Head-Mounted XR Experiences with OpenXR

OpenXR is a royalty-free, open standard that provides high-performance access to XR platforms and devices. With OpenXR, you can create an immersive experience in Unreal Engine that can run on any system that supports the OpenXR APIs. Currently, OpenXR in Unreal Engine only supports head-mounted devices.

This section describes how OpenXR works in Unreal Engine.



Develop on head-mounted AR and VR devices with OpenXR in Unreal Engine.

Developing for Handheld Augmented Reality Experiences

Handheld AR experiences are fundamentally different from head-mounted XR experiences. This section explains how to get started with handheld AR and how to use the unique features included on these platforms.



Develop on handheld AR devices in Unreal Engine

Getting Started with XR

This section explains the basics of creating XR applications in Unreal Engine.



Set up your project and apply best practices for AR and VR devices with Unreal Engine.

Making Interactive XR Experiences

There are many different kinds of input for XR, such as hand tracking, motion controllers, and eye tracking. This section describes how to add input to your XR applications in Unreal Engine.



Add user input to your AR and VR projects in Unreal Engine

Creating UI for XR Experiences

For XR experiences, the user interface (UI) must be 3D so you can interact with it in the virtual environment. This section guides you through how to create UI for XR applications in Unreal Engine.



Design user interfaces for XR experiences in Unreal Engine

Shared Experiences in XR

This section describes how to create content that can be shared across multiple XR devices.



Create an immersive experience for multiple users in Unreal Engine

Supported XR Platforms in Unreal Engine

This page provides information on the XR platforms and devices supported in Unreal Engine and how to set them up.



Set up your augmented reality and virtual reality devices for development with Unreal Engine

Performance and Profiling with XR

This section guides you through how to profile your XR applications and what to consider when you need to improve performance.



Tools and strategies for profiling your XR projects in Unreal Engine

Using XR for Content Creation

Unreal Engine also supports using XR in your content creation pipeline, such as building environments in virtual reality and streaming tracking data from devices into the engine for animation. These pages show how to use your XR devices with Unreal Engine for more than developing on them.



Use LiveLink with XR devices through the LiveLinkXR plugin



Add tracking and input data from VR peripherals with the Live Link VRPN plugin.



Use the Live Link Face app, ARKit, and Live Link to capture facial animations and apply them to characters in Unreal Engine.

OpenXR Runtimes

Extending OpenXR in Unreal Engine

Supported Platforms

Developing with OpenXR

OpenXR is a royalty-free, open standard that provides high-performance access to XR platforms and devices. Epic Games is one of the founding members of the OpenXR Working Group, along with the Khronos Group and industry partners. This multi-company group is working to solve XR fragmentation with a cross-platform standard.

With OpenXR, you can create an immersive experience in Unreal Engine that can run on any system that supports the OpenXR APIs. Currently, OpenXR in Unreal Engine only supports head-mounted devices. To develop XR projects for handheld devices, refer to Developing for Handheld Augmented Reality Experiences.



OpenXR and the OpenXR logo are trademarks of the Khronos Group Inc.

This page contains links to documentation about the devices supported by OpenXR and how to develop for head-mounted devices with OpenXR in Unreal Engine.

OpenXR Runtimes

Each platform has an OpenXR runtime, which is the implementation of the OpenXR APIs for that platform. This page describes all the supported OpenXR runtimes and how to set up your projects to work with them.



Learn how to install the OpenXR runtime and set up your projects for OpenXR.

Plugin Priority

Your Unreal Engine project can ship with the following plugins enabled: OpenXR, Oculus, SteamVR, and Windows Mixed Reality. When you launch your app, the list of plugins is checked in order of the plugin's priority from highest to lowest. The first plugin in the list, whose runtime the app can connect to, is selected.

The following is the current order of plugin priority in Unreal Engine, from highest to lowest:

Oculus

OpenXR

Windows Mixed Reality

SteamVR

Extending OpenXR in Unreal Engine

The OpenXR plugin in Unreal Engine supports extension plugins so you can add functionality to OpenXR without relying on engine releases. There are OpenXR extension plugins included in the engine release.

The plugins currently available in Unreal Engine to extend the OpenXR plugin include:

OpenXRHandTracking

OpenXREyeTracker

XRVisualization

OpenXRMsftHandInteraction

Oculus OpenXR

HP Motion Controller

You can also install extension plugins from the Marketplace or make your own.

Supported Platforms

These pages provide information on the platforms and head-mounted devices that support OpenXR in Unreal Engine, and how to deploy your applications to them.



How you can develop for HoloLens devices in Unreal Engine.





How you can develop for SteamVR in Unreal Engine.



How you can develop for Windows Mixed Reality VR devices in Unreal Engine



How you can develop for Oculus devices in Unreal Engine.

Developing with OpenXR

After setting up your OpenXR runtime and XR device for development, follow these guides to develop with OpenXR on your device.



Set up your project and apply best practices for AR and VR devices with Unreal Engine.



Add user input to your AR and VR projects in Unreal Engine



Design user interfaces for XR experiences in Unreal Engine



Create an immersive experience for multiple users in Unreal Engine



Tools and strategies for profiling your XR projects in Unreal Engine

Developing for Head-Mounted Experiences with OpenXR

Making Interactive XR Experiences

Windows Mixed Reality

HoloLens

Oculus

SteamVR

OpenXR Runtime Environment Variable

OpenXR Runtime

To develop OpenXR projects in Unreal Engine (UE), you must install the OpenXR runtime for the platform and hardware you are developing for. The following sections cover how to install the correct OpenXR runtime and which plugins are needed for each platform.

Currently, some of the platform-specific plugins in UE are incompatible with the OpenXR plugin. Make sure you disable the Oculus, SteamVR and Windows Mixed Reality plugins when using the OpenXR plugin in your Unreal project.

Windows Mixed Reality

Complete the following items to begin using your Windows Mixed Reality devices with OpenXR in the Unreal Editor:

Complete the steps in Microsoft's Getting Started with OpenXR documentation to install the OpenXR runtime for Windows Mixed Reality on your computer.

Enable the OpenXR plugin in your Unreal project.

Optional:Install the Microsoft OpenXR Plugin

HoloLens

Complete the following items to begin using your HoloLens devices with OpenXR in the Unreal Editor:

Complete the steps in HoloLens Prerequisites to set up your computer and device.

Disable the Windows Mixed Reality plugin in your Unreal project.

Enable the OpenXR plugin in your Unreal project.

Install the latest OpenXR runtime on your HoloLens. Follow the instructions in Microsoft's documentation to update the OpenXR runtime on your device.

Optional: Install the Microsoft OpenXR Plugin

To use HoloLens specific features, such as HoloLens remoting, you need to download and install the Microsoft OpenXR plugin from the Marketplace

Oculus

Complete the following items to begin using your Oculus devices with OpenXR in the Unreal Editor:

Complete the steps in Oculus Prerequisites to set up your computer and device.

Enable the OpenXR plugin in your Unreal project.

SteamVR

Complete the following items to begin using your SteamVR devices with OpenXR in the Unreal Editor:

Complete the steps in SteamVR Prerequisites to set up your computer and device.

Enable the OpenXR plugin in your Unreal project.

OpenXR Runtime Environment Variable

If there are several OpenXR runtimes on your computer, you will need to set an environment variable so that Unreal Engine can find the correct OpenXR runtime.

While each OpenXR compatible runtime should support any OpenXR device, for best results, install the official runtime (SteamVR for Vive/Index, Oculus app for Quest, etc). You can do this manually but we use, and recommend using OpenXR Explorer. It allows for easy switching between OpenXR runtimes, shows lists of the runtime's supported extensions, and allows for inspection of common properties and enumerations, with direct links to relevant parts of the OpenXR specification.

Getting Started with Handheld AR

Supported Platforms

Handheld AR Features

Unreal Engine supports handheld AR development with a unified framework so your applications can target multiple mobile platforms with minimal platform checks. Handheld AR platforms provide a variety of features that you can use in your Unreal Engine projects, such as facial tracking, environment probes, and object occlusion.

Currently, you cannot use OpenXR to develop with handheld AR devices. To develop XR projects with OpenXR, refer to Developing for Head-Mounted Experiences with OpenXR.

This page contains links to documentation on how to develop for handheld AR devices in Unreal Engine.

Getting Started with Handheld AR

Unreal Engine includes a template project for handheld AR. This template provides a simple base for handheld augmented reality projects, which you can modify to suit your project's needs. These pages explain how to use the template and how to get started developing with handheld AR in Unreal Engine.



A guide to setting up a project with the Handheld AR Template and preparing your mobile device to test it



A reference page for where key features of the Handheld AR Template are implemented and how they function

Supported Platforms

These pages provide information on the platforms and mobile devices that support handheld augmented reality in Unreal Engine and how to deploy your applications to them.



How you can develop for ARCore-supported devices in Unreal Engine



How you can develop for ARKit-supported devices in Unreal Engine

Handheld AR Features

The following is a list of handheld AR features you can add to your projects and whether they're supported on the platforms.

Feature

Description

ARCore Support

ARKit Support

Plane Detection

You can detect vertical or horizontal planes in the real world. Once the planes are detected, you can then place virtual objects in that location so they can appear to be attached to the real-world object, such as on a table top.

Yes

Yes

Object Occlusion

Real-world objects can occlude your virtual objects, that is, your virtual objects appear to be rendered behind the real-world object.

Yes

Yes

People Occlusion

Similar to object occlusion, people can occlude virtual objects.

No

Yes

Environment Probe

You can estimate the intensity and direction of the real-world lighting. You can then apply this light estimation to your virtual objects to blend them with the real world.

Yes

Yes

ARPins

You can attach your virtual objects to real-world locations with ARPins. You can also save these ARPins to the cloud and share them with other devices so multiple users can view the same content in the same location.

Yes, locally and through the cloud with Cloud Anchors and Azure Spatial Anchors.

Yes, locally and through the cloud with Geo Anchors, Cloud Anchors, and Azure Spatial Anchors.

Augmented Images

You can provide reference images that your app can detect and augment.

Yes

Yes

Facial Tracking

You can detect feature points on the user's face for tracking and augmenting.

Yes

Yes, through either the ARKit API or the Live Link Face app.

Geotracking

You can track specific geographic locations using the device's GPS and world tracking based on downloaded images. This feature is dependent on whether images have been collected for the area.

No

Yes, for more details, refer to Apple's documentation.

Camera Intrinsics

You can retrieve information about the device's physical camera, such as focal length and image resolution.

Yes

Yes

Handheld AR Template Quickstart

How To Perform AR Hit Testing

Open an AR Project

Show World Origin

Explore Other AR Functions



For this guide, we are using the Handheld AR template.

In the following How To, we will take a look at how the example project created by the Handheld AR template demonstrates drawing the world origin. Knowing where the augmented reality system (ARKit/ARCore) has placed the world origin, can be useful information when troubleshooting. Devices often decide what they consider World Location 0,0,0 (World Origin) based on unpredictable factors, potentially making it difficult to debug issues with the location, movement or spawning of content where tracked geometry transform information is not referenced. This becomes a bigger problem when working with baked lighting, as static content expects the World Origin to be in a specific spot.

Steps

Open an AR Project

Open the Project Browser and create a new Handheld AR Blueprint project, or open an existing augmented reality project.If you need assistance creating a new augmented reality project, see the Handheld AR Template Quickstart documentation.

Open the Find in Blueprints menu item.



Search for Debug Draw World Origin. In the results, double-click the Debug Draw World Origin function.



Show World Origin

The example project demonstrates a simple method of drawing the world origin. Drawing the world origin is a useful debugging exercise to help determine what the augmented reality system has determined as the world origin. As shown below, the world origin always starts at 0.0, 0.0, 0.0.

Draw Debug String - This function is placing the text string "WORLD ORIGIN" at the world origin (0.0, 0.0, 0.0) location.

Draw Debug Arrow(s) - These functions are drawing short arrows along X, Y, and Z axes respectively, starting from the world origin (0.0, 0,0, 0,0).



Explore Other AR Functions

Exploring a project based on the Handheld AR Blueprint template provides an opportunity to examine the actual use of the various augmented reality functions in context. There are dozens of new augmented reality functions, so take some time to dig into a new project and explore the implementation details demonstrated.

A good place to start exploring the project and the new augmented reality functions is to open the Content Browser, navigate to Content\HandheldARBP\Blueprints\UI and open the BP_DebugMenu asset in the Blueprint Editor.

1. Overview of User Journey and Features

2. Compatibility

3. Setting Up the Template

4. Packaging and Deploying on Your Device

Android Setup

iOS Setup

Packaging and Launching

5. Navigating the Application

Scanning and Object Placement

Manipulating Objects.

Navigating the UI and Menus

Snapshot

Reset

Options Menu

Info Menu

6. Template Quick Reference

7. On Your Own

The Handheld AR Template is available for Unreal Engine projects using UE 4.27 or later. This template provides a simple base for augmented reality projects targeting Android and iOS devices, which you can modify to suit your project's needs.

This guide walks you through the features the AR Template comes with, how to launch and navigate it on a mobile device, and where you can locate its features in the Unreal Editor so you can begin creating your own handheld AR applications.

1. Overview of User Journey and Features

The AR Template is a simple handheld AR application with a user journey that follows these steps:

The user opens the application.

The application displays a prompt to begin scanning the environment. The user must provide camera permissions to continue.

When the user confirms the prompt, the application scans the environment with the user's camera, then defines a virtual scene by adding planes to the environment.

The application prompts the user to select a plane to interact with.

When the user selects a plane, they can place a virtual object on it.

Once a virtual object is placed, the user can manipulate it with a variety of transformation tools. A HUD provides configuration options, the ability to take snapshots of the AR scene, and the option to reset back to selecting a plane.

This template showcases the following features:

An application flow controlled by a simple state machine.

Scanning an environment to gather data for:

Defining interactive planes in a virtual scene.

Lighting and scene depth information.

Using a UMG widget to display the environment captured from the camera.

Touchscreen-based interactions in the virtual scene.

Manipulating virtual objects.

Selecting planes defined by the user's environment.

Use of gesture-based touch input for different types of interactions.

A basic UI with options for different styles targeting different types of applications.

Capturing images from the fully composited AR scene and saving them to your camera roll.

2. Compatibility

The Handheld AR Template works on any device that fulfills the following requirements:

The device must be supported by Unreal Engine.

The device must support ARKit (iOS) or ARCore (Android).

Refer to the



For a list of iOS devices that support ARKit, refer to the Apple Developer ARKit documentation

For a list of Android devices that support ARCore, refer to the Google Developer AR documentation.

3. Setting Up the Template

To use the AR Template, you need to create a project using the template as a base, then set up your project for packaging on your desired Mobile device. This section walks you through the steps needed.

Open Unreal Editor. In the Select or Create New Project menu, scroll down to New Project Categories and select Games, then click Next.



The AR template is also available using Architecture, Engineering, and Construction as well as Automotive, Product Design, and Manufacturing.

In the Select Template menu, choose the Handheld AR template. Choose a Name and Location for your project. In this example, the project is called ARTemplateGame. Once you have finalized your settings, click Create Project.



After finishing these steps, the project opens in Unreal Editor, with HandheldARBlankMap as the default map.

4. Packaging and Deploying on Your Device

To complete your project setup, you need to prepare your project to package on your mobile device. Both Android and iOS require different setup steps in your project settings.

Android Setup

To prepare your handheld AR project for Android, complete the following steps:

Install the required version of Android Studio on your computer.

Run the AndroidSetup script in your engine folder to make sure the required SDK and NDK components are installed on your computer. Depending on your operating system, you may need to reboot your computer to make sure changes take effect.

In your Project Settings, locate the Android settings and click the Configure Now button under APK Packaging to configure your project for the Android platform. If you have not already accepted the Android SDK license, click the Accept SDK License button as well.

Make sure your device is set to Developer Mode and is set up to accept USB connections with your computer.

You can find more detailed information about these steps in the Android Setup section.

iOS Setup

To prepare your handheld AR project for iOS, follow these steps:

Install the latest version of Xcode on your Mac.

Obtain a provisioning profile and signing certificate from the Apple Developer Portal for your project.

The provisioning profile should have permissions to use your device's camera.

Open your Project Settings and import the provisioning profile and signing certificate.

You can find more detailed information about these steps in the iOS Setup section.

Packaging and Launching

Once you have performed the necessary setup to support your mobile device, you can package your project by clicking File > Package Project and selecting a packaging option for the appropriate device. This creates a packaged build that you can deploy on a device later.

You can also launch directly on your device by clicking the Launch dropdown in the main toolbar, then selecting your device from the list of devices shown. You can check the status of your device in the Device Manager menu to verify that it is connected. The engine then automatically packages your project and pushes it to your device before launching.

5. Navigating the Application

This section provides a walkthrough of the user journey for the out-of-the-box configuration of the Handheld AR Template.

Scanning and Object Placement

When the Handheld AR Template launches, it uses your device's camera to display your surroundings. A prompt asks you to scan your environment.



Click the Begin Scan button to start. This gathers the data needed to build the 3D scene for virtual objects.

The application asks you to allow permissions to take pictures and record video. These permissions are required for the camera to scan and display the environment.

Once your mobile device has finished scanning, the application displays several planes and prompt you to select one by tapping it on your screen. Planes are displayed with colored waves across the surface. The application only displays one plane at a time to reduce visual noise, and sets the closest plane to being visible.



After you select a plane, the bottom toolbar UI appears, and you can place a virtual object.



The template can place one virtual object at a time, but you can use the workflow for placing this object to place others in your own applications.

Manipulating Objects.

In the Handheld AR Template, you can Translate, Scale, or Rotate a virtual object using the touchscreen.

To translate an object, tap it and drag it along the ground where you want to place it. Any one-finger touch displays the translation HUD. Objects are confined to the bounds of the plane they are placed on. Those bounds are displayed on the HUD when you start translating the object.

To scale an object, use your thumb and forefinger to pinch or expand the object. The template recognizes pinches that are mostly vertical relative to the orientation of the screen. The UI displays the new size of the object in centimeters as you scale it.

To rotate an object, place two fingers on the screen and swipe them left or right. The system recognizes swipes and drags that are mostly horizontal relative to the screen as being rotations. This displays the rotation HUD, which includes a circle around the base of the object and its current world rotation in degrees.

Navigating the UI and Menus

By default, the Handheld AR Template's UI is displayed at the bottom of the screen. This includes a toolbar as well as a floating Info button in the lower-left corner.

The Snapshot button takes a picture with your virtual objects displayed on the screen and saves it to your device's camera roll. A prompt displaying the text Snapshot Saved confirms that the snapshot was successfully taken.

As of 4.27, the Handheld AR Template saves screenshots to the camera roll on Android, but not on iOS.

The Reset button removes the virtual object and return the user to the prompt for selecting a plane.

The Options button opens a menu that provides configuration options.



Toggling Snapping makes virtual objects snap to discrete 1 cm increments when translating or scaling. Rotations snaps to 5 degree angles.

Toggling Interact HUD turns the HUD off until you interact with the screen. This lets you take clean screenshots from within the app.

The UI Style selector cycles through three UI styles. The Light and Dark styles show the default UI with the toolbar at the bottom of the screen. The Game style shows a more stylized HUD with all the tools arranged in a circular element instead of a horizontal one. The Game style supports all of the same functions and flows as the Light and Dark styles, but demonstrates a different layout for using them.



The Info Menu displays a simple visual guide to the gestures for manipulating virtual objects.



6. Template Quick Reference

All assets for the Handheld AR Template are located in the Handheld AR folder in the Content Browser. The Handheld AR template primarily depends on the following assets:

Asset Name

Path

Summary

BP_ARGameMode

HandheldAR/Blueprints/GameFramework/BP_ARGameMode

The game mode used in the Handheld AR Template. Initializes the AR Pawn.

BP_ARPawn

HandheldAR/Blueprints/GameFramework/BP_ARPawn

The Pawn class for the Handheld AR Template. Initializes the HUD and handles setup of the virtual scene, as well as input from the user.

BP_MainMenu

HandheldAR/Blueprints/UI/BP_MainMenu

The main UI for the Handheld AR Template. Controls other menus and initializes the AR scene from the camera.

BP_Plane

HandheldAR/Blueprints/Placeable/BP_Plane

A plane that placeable objects can be placed on. These are set up by the AR Pawn after scanning the environment.

BP_Placeable

HandheldAR/Blueprints/Placeable/BP_Placeable

A base Blueprint class for placeable objects that the user can interact with.

For more information about these actors and where to look for key functionality, refer to the Handheld AR Template Reference page.

7. On Your Own

Now that you have set up the Handheld AR Template and can explore it on your mobile device, you can start using it as a jumping-off point for developing handheld AR applications of your own. Check the Handheld AR Template Reference page for more detailed information about the classes that make up this template and how you can modify them.

Basics

Application Flow

Actors

AR Pawn

Initialization

State Control

Camera Depth Scene Texture

Light Intensity Estimation

AR Plane Creation

Gesture Processing and Manipulating the Virtual Scene

Placeable Objects

Controlling Visuals

Placing Objects on AR Planes

AR Planes

HUD and UI Widgets

UI Styles and BP_StylizedUI

Main Menu

Initialization and Event Binding

Starting the AR Session

Handling State Changes

Sub-Menus

Start Menu

Bottom Menu

Option Menu

Info Menu

Buttons

The Handheld AR Template is a starting point for creating augmented reality projects for iOS and Android devices. While the Handheld AR Template Quickstart provides the steps for setting up the template and deploying it on a mobile device, this guide will provide more technical guidance on how the template works, where its key features are implemented, and how to modify its functionality.

Basics

The Handheld AR Template is displayed with two parts:

The feed from the user's camera.

The virtual scene, which exists in Unreal Engine's 3D world.

The user's camera feed is captured automatically when they start an AR Session, while the virtual scene is rendered on top of that. As a representation of the user, the Pawn contains logic for interacting with objects within the virtual scene, including planes defined by the initial scan and placeable objects. A HUD is overlaid on this composited display, providing configuration options and other tools.

For more information about the user journey for the Handheld AR Template, refer to the Handheld AR Template Quickstart.

Application Flow

The Handheld AR Template opens directly to HandheldARBlankMap both in the Editor and on application startup. This map does not feature any Actors apart from the helper Actors used to point to documentation on mobile device setup. Its main function is to override the Game Mode to BP_ARGameMode so that the application will use the Game Framework classes that are responsible for running the application and setting up the virtual scene.



BP_ARGameMode starts the player with BP_ARPawn, which is responsible for initializing the UI by adding BP_MainMenu to the user's viewport. Once BP_MainMenu is set up, it provides a prompt to the user to start scanning the environment. This begins an AR session and displays the user's camera feed, then tells BP_ARPawn to define a series of planes based on the available flat surfaces in the environment.

BP_ARPawn uses a simple state machine to track what step of the user journey the application is currently on. This state machine tracks these factors:

Has the user scanned their environment and set up planes in the virtual scene?

Has the user selected a plane to interact with?

Has the user placed an object on the selected plane?

Based on the user's progress through the user journey, the Pawn changes the way the application responds to their input and triggers prompts in the HUD to walk them through setup steps.

Actors

AR Pawn

The Handheld AR Template uses a custom Pawn called BP_ARPawn. This Pawn is responsible for initialization, building and updating the virtual scene, and handling the user's input.

The AR Pawn adds BP_MainMenu to the user's viewport on BeginPlay. BP_MainMenu is then responsible for setting up the AR scene and handling prompts based on the current state of the application.

The AR Pawn implements a simple state machine to support the different steps in the user journey outlined in the above sections. The state is controlled by a series of booleans under the State category.



These include:

ScanningIsDone: The initial scanning process is complete and planes are placed in the virtual scene.

PlaneIsSelected: The user has selected a plane.

ObjectIsPlaced: The user has placed the virtual object on a plane and can now interact with it.

As the user follows the prompts from the HUD, these change from false to true, triggering the application to move to the next step in the user journey. The Pawn refers to these when processing touch input and when handling the Tick event to update the scene.

The AR Pawn is also responsible for fetching the camera depth scene texture, which is used for placing objects in the virtual scene. This information is fetched as soon as the user gives the application permission to use the camera, but before the application completes its AR scan. The depth texture is stored in CameraDepthTexture, which is then used in the Create Plane Candidate function when the Pawn updates the visuals for planes. If CameraDepthTexture is not available, it uses CameraDepthFallback instead.

During the Tick event, the AR Pawn calls the Feed Light Estimate function. This obtains current light estimate data from the AR session. If the data is valid, it updates the directional light and skylight in the map with color and intensity settings based on the camera feed. This creates lighting in the virtual scene that roughly matches lighting in the user's real-world environment.

Once the AR session has finished scanning the environment, the AR Pawn begins updating the PlaneCandidate Actor in the virtual scene. This process checks to see if tracked objects in the environment fit valid AR Plane Geometry. Typically, a device's sensors can detect anywhere between five and twenty objects.

After that, the Pawn calls Create Plane Candidate to spawn a BP_Plane Actor and place it in the appropriate location in the virtual scene. Plane candidates are updated once per second. To reduce visual complexity on screen, this process is set up so that the AR Pawn only tracks one plane candidate at any given time, favoring the closest object tracked by the AR session. As the user moves around the environment, they will see different plane candidates appear and disappear.

When the user selects a plane candidate, the BP_Plane is locked in place as the SelectedPlane instead.

The AR Pawn is the only blueprint that consumes input, so it is responsible for all gesture recognition.

The InputTouch event handles single-touch inputs for either selecting a plane or placing a virtual object, depending on whether or not the user has a plane selected. Because two-finger gestures and swipes are not available until the user selects a virtual object, this touch input is very simple and does not require any special input actions.



After the user has both placed a plane and selected a virtual object, input is handled by the OneFingerAction and TwoFingerAction input actions, as well as an input axis called TwoFingerMapping. These are defined in the input bindings under Project Settings > Input.



The OneFingerAction and TwoFingerAction input actions are represented with events in the AR Pawn's event graph. These events do not trigger any functions when interacting with planes and objects. Instead, they record data that the AR Pawn can use to pick what type of gesture is appropriate during general input handling.



The Tick event calls Reset Recognized Gesture to clean up information about previous gestures, then calls the One Finger Gesture Recognition and Two Finger Gesture Recognition functions to process the data gathered from the input action events. This includes the deltas for position, direction, and travelled distance of touch inputs.

These functions set an enum for the appropriate gesture, called Current Transformation. A switch on Current Transformation then chooses whether to use the Translate, Rotate, or Scale functions on the selected placeable object. The object itself handles these transformation functions.



Placeable Objects



The BP_Placeable blueprint is the base class for all placeable objects in the Handheld AR Template, including planes. It encapsulates everything related to a placeable virtual object: visuals, transformation logic, and HUD interaction logic with a widget component. On BeginPlay, the placeable object will choose an asset based on what type of product you are creating with the Assign Product Asset function. The model selected depends on the category you choose when setting up the template.

Application Category

Model

Games



Automotive, Product Design, and Manufacturing



Architecture, Engineering, and Construction



Placeable objects use the Set Visuals function to control the display of both the model's materials and the UI widgets displayed alongside them. This function is called from Set Placeable Position, Set Placeable Rotation, and Set Placeable Scale.

If an interaction is active, the Tick event will call Update Interaction. This function will update the placeable object's UI widget with new information based on how the user moves, rotates, or scales it. There are several utility functions for getting text appropriate to each transformation.

The AR Pawn spawns a BP_Placeable actor from the Input Touch event and assigns it to the Placeable Object variable.

AR Planes

The Handheld AR Template represents virtual planes with BP_Plane actors. These are created by the AR Pawn using the Update Plane Candidate and Create Plane Candidate functions. Create Plane Candidate in turn calls Initialize Plane, which handles setup of BP_Plane's materials and color.

The static mesh attached to BP_Plane is a simple plane consisting of two triangles, with complex collision turned on and the Collision Presets set to BlockAllDynamic. This makes it possible to detect the surface of the plane with any type of trace.

The default state of a BP_Plane actor is its unselected state. In this state, it uses DM_Scan as its material instance, displaying ripples to indicate that the device is currently scanning the environment.



The Get Platform Scan Material function sets DM_Scan to either ScanMaterial01 or ScanMaterial02, depending on whether or not the user is on an Android or iOS device.

The Initialize Plane function will attempt to use the camera scene depth taken by the AR Pawn to set DM_Scan to visually cut it off so that it fits better into the environment. It will also set the color using Get Plane Color in the AR Pawn. This function fetches the AR geometry index and uses that to select a color. If the AR toolkit finds new geometry in the environment, the colors may change.

When the user selects a plane to place an object on, the AR Pawn will call the BPPlane Is Selected event dispatcher. The main menu uses this event to switch to the place object state. When the user places an object on a plane, the plane is hidden, creating a more immersive display. Ideally, the plane should match the scanned object in the user's environment closely enough that interactions feel intuitive even if the plane is not being displayed.

When the user uses the translate function on a placeable object, the AR Pawn will call the Switch to Material Translate function to change the plane's material instance to DM_Plain, which shows a less intrusive outline compared with DM_Scan. This makes it easier for the user to see the bounds where they can move the object.

HUD and UI Widgets

This section provides a reference for the elements that make up the HUD in the Handheld AR Template. The information below explains how the UI classes are organized and how they provide key features, such as styling and mode changes.

UI Styles and BP_StylizedUI

All menus in the Handheld AR Template use BP_StylisedUI as their parent class. This class encapsulates all functions and relevant data needed to switch the UI style between the Light, Dark, and Game themes. These themes are contained in the DT_Styles data table, which contains information for common UI colors, fonts, and icons.



The Get Style Data function fetches information about the currently selected style and outputs this information for use in other functions.



BP_MainMenu uses the Call Switch Style function to trigger style switching in each of its sub-menus.



These bind events for changing their UI to the Switch Style event dispatcher, which is defined in BP_StylizedUI.



Other widgets, such as UI_CapsuleButton, define their own Change Style function, which is called manually by their parent menus.



This design both provides a data-driven method for defining UI styles, and also ensures that there is minimal duplication necessary to support large-scale changes in UI style and layout.

Main Menu

BP_MainMenu acts as a container and manager for all the other menus. After the AR Pawn adds it to the viewport, it initializes all the other menus, binds their event dispatchers, and binds the event dispatchers that correspond to specific steps in the user journey as well. It is also responsible for starting the AR session. Because it does not have any visual elements of its own to style, it extends the base User Widget class instead of BP_StylizedUI.

During the On Initialized event, the main menu initializes the UI, sets the default UI style to Light, then binds the event dispatchers for all of the UI's main functions. These include steps through the template's user journey, displaying the initial tutorial popup, as well as the flow for taking screenshots or transitioning between other sub-menus and confirming settings changes.



This is a highly extensive event graph, but think of it as acting like the glue between the visual elements in the sub-menus and the application's main functionality.

The AR session starts when the user presses the button in BP_StartMenu to begin scanning.



Handling State Changes

The Main Menu's tick function then listens for the AR session to reach the Running state. When this happens, it tells BP_StartMenu to enter the scanning state, which triggers several cosmetic changes to the UI to help highlight the state change.



Similarly, the Tick function also listens for when the user starts to place an object. These changes correspond to the state machine found in the AR Pawn.

Sub-Menus

Several sub-menus are embedded in the Main Menu. These menus primarily handle their cosmetic elements and layout, deferring to Event Dispatchers to handle their functionality except for internal styling purposes. All sub-menus are based on BP_StylizedUI to provide common functions for supporting style changes.



BP_StartMenu is the menu that initially displays when the user starts the application, and handles overlays and prompts walking the user through the user journey, providing feedback as they move from one step to the next. The Start Menu is overlaid over the entire screen, and contains a separate overlay for each discrete user journey state. For example, the Start Menu shows UI_Scanning when the user is in the middle of scanning their environment for planes, while it shows UI_PlaceObject once they have selected a plane and are ready to place an object on it.



When the user has gone through the user journey and placed an object, BP_BottomMenu displays at the bottom of the screen, providing a way to access the Options Menu, the Info Menu, and the Snapshot and Reset functions.

The Bottom Menu has a separate overlay for the horizontal layout used by the Light and Dark themes, as well as the circular layout used in the Game theme. Both of these layouts' versions of the buttons bind the same custom events to avoid duplication.





BP_OptionMenu is the menu that displays when the user taps the Options button in the Bottom Menu. This provides a handful of configuration options, including the ability to switch UI styles. The UI buttons in this menu are bound to functions in the Main Menu to provide better visibility to the AR Pawn as well as other functions that may need to trigger in other parts of the UI.





BP_InfoMenu appears when the user taps the Info button in the Bottom Menu. This displays the gestures for working with placeable objects.

Buttons

UI_CapsuleButton and UI_ToggleButton are used by all menus. They are custom made to support a wide range of common functions, including style changes and specific button behaviors such as toggling.

Handheld AR Template Quickstart





iOS and Android Release Support

Augmented Reality API

Supported Handheld Platforms

iOS

Android

Getting Started with Unreal AR

Augmented reality (AR) is a technology that overlays a computer-generated image on a user's view of the real world, providing a composite view.

The Unreal Engine AR framework provides a rich, unified framework for building augmented reality apps with the Unreal Engine for both iOS and Android handheld platforms. The unified framework provides a single path of development for both platforms, allowing developers to build augmented reality apps for both platforms using a single code path. The Handheld AR Blueprint template provides a complete example project demonstrating the augmented reality functionality available in the Unreal Engine.



Augmented reality provides user experiences that add 2D or 3D elements to a live view from a device's camera in a way that makes those elements appear to inhabit the real world.

iOS and Android Release Support

The unified AR framework includes support for basic AR functionality like Alignment, Light Estimation, Pinning, Session State, Trace Results, and Tracking.

However, the augmented reality story for Android and iOS is constantly evolving. As of Unreal Engine 4.23, we now support some of the advanced functionality available in the latest ARCore and ARKit releases.

ARCore 1.7

Augmented Faces

Augmented Images

Cloud Anchors

Vertical Plane Detection

ARKit 3.0

2D Image Detection

3D Object Detection

Face Tracking

Persistent Experiences

Shared Experiences

People Occlusion*

Motion Capture (2D, 3D, LiveLink)*

* Unreal Engine 4.23.1 provides beta support for this feature.

Epic Games developer Joe Graf has written several informative blogs discussing ARKit functionality in UE4.

2D Image Detection in UE4 4.20

ARKit 2.0 support in UE4 4.20

AR Environment Probes in UE4 4.20

Augmented Reality API

The unified AR framework provides a framework to build augmented reality apps with Unreal Engine for both iOS and Android handheld platforms. The unified AR framework provides a new library of C++ and Blueprint functions that allow developers to build augmented reality apps for both platforms using a single code path. These new functions also make working with augmented reality easier. More detailed information can be found in the Unreal Engine API Reference.

The Handheld AR Blueprint template provides a complete example project demonstrating the new augmented reality functionality available in Unreal Engine. A good place to start exploring the project and the new augmented reality functions is to open the Content Browser, navigate to Content\HandheldARBP\Blueprints\UI and open the BP_DebugMenu asset in the Blueprint Editor.

Supported Handheld Platforms

Currently, we support the iOS and Android platforms. Please read through the following pages to learn which devices are supported on each platform.

Apple's iOS Device Compatibility Reference

ARCore Supported Devices Overview

It's worth mentioning that support for handheld iOS and Android devices isn't new to the Unreal Engine, so if you're already working with Unreal Engine and iOS or Android devices, you'll only need a minimal amount of additional configuration to get started with augmented reality in Unreal Engine.

iOS

For detailed iOS augmented reality prerequisite information, see the ARKit Prerequisits topic. Additionally, basic configuration of Unreal Engine and iOS devices is covered in the iOs and tvOS section of the Unreal Engine documentation.

Android

For detailed Android augmented reality prerequisite information, see the



Getting Started with Unreal AR

Now that you understand some basic information about using Unreal Engine with augmented reality, it's time to get started by running through the Handheld AR Template Quickstart tutorial.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Handheld AR Template Quickstart

Steps

Create a New Handheld AR Project

Hit Testing Against Tracked Geometry vs World Objects

Explore Other AR Functions



For this guide, we are using the Handheld AR template.

In the following How To, we will take a look at how the example project created by the Handheld AR template demonstrates standard hit testing and tracked object hit testing. Hit testing (line tracing) is not new to Unreal Engine, or Blueprints. However, it's important to recognize that hit testing in the Unreal world, and augmented reality require different approaches. The example project contains a standard pattern for hit testing in the Unreal world, and in augmented reality on handheld devices.

Other AR devices, such as AR headsets, will require a different approach than discussed in the below How To.

Steps

Create a New Handheld AR Project

Open the Project Browser and create a new Handheld AR Blueprint project, or open an existing augmented reality project.If you need assistance creating a new augmented reality project, see the Handheld AR Template Quickstart documentation.

Open the BP_ARPawn Blueprint class.

Select the Event Graph tab.

Hit Testing Against Tracked Geometry vs World Objects

The example project demonstrates the use of Line Trace For Objects and Line Trace Tracked Objects in the context of a normal workflow. Line Trace For Objects is being used to check for a hit against Unreal World objects, while Line Trace Tracked Objects is being used to check for a hit against tracked objects (augmented reality tracked geometry). Line tracing is not new to Unreal Engine, but the new Line Trace Tracked Objects function allows the detection of the additional tracked geometry in the world.

As the below example shows, we check for world objects first. We do this because spawned world objects are often rendered closer to the origin of the line trace, so the user will see them before the tracked geometry. If we tested tracked geometry first, we'd miss the thing we were trying to touch every time.



Click for full image.

Test If User Touched World ObjectThis is the standard use of the Line Trace For Objects function (in World Hit Test), checking against an array of potential Unreal world objects, and returning "true" or "false". In this case, if the return value is "true", AR Hit Result is called, updating one of Debug Menu items. If the return value is "false", then the execution path moves along to new augmented reality function Line Trace Tracked Objects.



Click for full image.



Click for full image.

Test If User Touched Tracked Geometry, Spawn ObjectLine Trace Tracked Objects is a new augmented reality function for line trace testing against tracked objects (geometry perceived by the augmented reality tracking system). Line Trace Tracked Objects returns a list of results sorted by distance from camera. In this case, if the return value is greater than 0 (we hit a tracked object), then AR Hit Result is called, updating one of the Debug Menu items, and Spawn Actor BP Placeable is called, creating a pawn at the tracked location that was hit. If the return value contains no hit results (we did not hit a tracked object), AR Hit Result is called, updating one of the Debug Menu items.



Click for full image.

Although many of this project's actions end up updating the app's Debug Menu, that is specific to this particular project. You can, of course, use the hit data from a line trace in any manner that's required. The difference here is that Line Trace Tracked Object provides the ability to detect and react to the augmented reality tracked geometry.

Explore Other AR Functions

Exploring a project based on the Handheld AR Blueprint template provides an opportunity to examine the actual use of the various augmented reality functions in context. There are dozens of new augmented reality functions, so take some time to dig into the project and explore the implementation details.

A good place to start exploring the project and the new augmented reality functions is to open the Content Browser, navigate to Content\HandheldARBP\Blueprints\UI and open the BP_DebugMenu asset in the Blueprint Editor.

Handheld AR Template Quickstart

Augmented Reality Overview

Developing for Handheld Augmented Reality Experiences

Face AR Capture Overview

Face AR Capture Setup

The AR Face Component

Driving Joints with Face Capture

Corrective Blend Shapes with Joints

More Corrective Blend Shapes

Creating a Pose Asset for Facial Animation

Remapping Curve Names in a LiveLinkRemap Asset

Handling Head Rotation

Deploying to iPhone X

Project Features

Calibration

Live Link Broadcasting

Show Flag Checkboxes

Show Debug Mesh

Show Debug Values

Show Unit Stats

Help & About

Connecting the App to Your Computer



The Face AR Sample project showcases Apple's ARKit facial tracking capabilities within Unreal Engine. You can download the Face AR Sample project from the Epic Games Launcher under the Learn tab.

New to Unreal Engine 4.20 is support for Apple's ARKit face tracking system. Using a front-facing TrueDepth camera, this API enables the user to track the movements of their face and to use that movement in Unreal Engine. The tracking data can be used to drive digital characters, or can be repurposed in any way the user sees fit. Optionally, the Unreal Engine ARKit implementation enables you to send facial tracking data directly into the Engine via the Live Link plugin, including current facial expression and head rotation. In this way, users can utilize their phones as motion capture devices to puppeteer an on-screen character.

The Face AR Sample project is a fully functional sample; however, some setup and configuration information is provided to assist you in exploring the project. You should keep in mind that as Apple's ARKit and Epic's OpenXR support evolves, specific project implementation details may change.

For more information about face tracking with Apple's ARKit, please see Apple's official documentation: Creating Face-Based AR Experiences

Mobile facial animation capture system is only available on iOS devices with a front-facing TrueDepth camera, such as the iPhone X, iPhone XS, iPhone XS Max, iPhone XR, iPad Pro (11-inch), and the iPad Pro (12.9-inch, 3rd generation).

Face AR Capture Overview

At a high level, the facial capture system with ARKit uses the Apple TrueDepth camera to track the motion of a user's face. In the process, it compares the pose of the face against 51 individual face poses. These poses are native to the Apple ARKit SDK, and each pose targets a specific portion of the face, such as the left eye, right eye, sides of the mouth, etc. As a given part of the user's face approaches the shape of a pose, the value of that pose blends between 0.0 and 1.0. For example, if the user closes their left eye, the LeftEyeBlink pose would blend from 0.0 to 1.0. As a user's face moves, all 51 poses are being evaluated by the SDK and assigned a value. The Unreal Engine ARKit integration captures the incoming values from the 51 blended face poses, feeding those into the Engine via the Live Link plugin. Those 51 pose values can then drive the motion of a real-time character's face. So, all that you really need to utilize face capture to animate a character's head is to ensure the character content is set up to use data from those 51 shapes. Because those shapes each feed back individual 0.0.to 1.0 values, they are perfect for driving the motion of a list of blend shapes on a character.

If the blend shapes created on the Unreal character are named precisely the same as those in the official list of shapes from Apple, then the connection is automatic. However, if the shape names differ between the Apple mesh and the Unreal character, then a remapping Asset must be used. For more details on remapping blend shape names, see the Remapping Curve Names in a LiveLinkRemap Asset section.

For a complete list of the blend shapes brought in by Apple's ARKit, please refer to Apple's official documentation: ARFaceAnchor.BlendShapeLocation

Face AR Capture Setup

Setting up a face capture system for animating a character's face with ARKit requires a few steps:

Set Up Character Blend Shapes and Import the Character into Unreal Engine.

Create a character with blend shape based facial animation, accounting for the 51 blend shapes defined in Apple's ARKit guidelines. Ideally, the geometry for these blend shapes should be named the same as the functions listed by Apple (eyeBlinkLeft, eyeLookDownLeft, etc.). However, there is a little leeway here as the names can be remapped if necessary.

Import this character into the Engine, making sure to import Blend Shapes in the import options.

Enable face tracking in the DefaultEngine.ini file for your Project by adding the following lines to your DefaultEngine.ini file. (the DefaultEngine.ini can be found in your Project's Config folder)

[/Script/AppleARKit.AppleARKitSettings] bEnableLiveLinkForFaceTracking=true

Create and apply a Data Asset in your Project to enable face tracking.

Right-click in the Content Browser and choose Miscellaneous > Data Asset.

From the Pick Data Asset Class window that appears, choose ARSessionConfig and click Select.

Double-click this new Asset to open it and set the set the following options:

World Alignment: Camera

Session Type: Face

Horizontal Plane Detection: Off

Vertical Plane Detection: Off

Enable Auto Focus: Off

Light Estimation Mode: Off

Enable Automatic Camera Overlay: Off

Enable Automatic Camera Tracking: Off

Candidate Images: Ignore

Max Num Simultaneous Images Tracked: 1

Environment Capture Probe Type: None

World Map Data: Ignore

Candidate Objects: Ignore

In the Level Blueprint for your face tracking level, from Begin Play, call the Start AR Session function, and set the Session Config property to the ARSessionConfig data Asset you just created.

Create an Animation Blueprint that uses a LiveLinkPose node, with Subject Name set to iPhoneXFaceAR. This will feed the ARKit face values into the Unreal Engine animation system, which will in turn drive the blend shapes on your character.

The AR Face Component

The ARKit face tracking system uses an internal face mesh that it wraps to the user's face and uses as a basis to mimic expressions. In Unreal Engine, this mesh is exposed by the AppleARKitFaceMesh component. This can be added to an existing Blueprint and set up to visualize what the ARKit SDK is seeing, and help you correlate that to how your character's face moves.

AppleARKitFaceMesh component properties:

Name

Description

Wants Collision

If enabled, this adds collision geometry to the face mesh. This is very expensive in terms of performance, and should only be used in instances where your app needs to trace against the mesh. For example, if you need to stick something to the face, or get a location on the face.

Auto Bind to Local Face Mesh

If enabled, this will automatically bind this component to the local ARKit face geometry on the device. ARKit will then update this component on every tick and handle the loss of tracking.

Transform Setting

Component Only: Only uses the transforms of the component. Use this only if you are not planning on tracking the face.

Component Location Tracked Rotation: Uses the components location, but tracks rotation from the user's head rotation while using the app.

Component with Tracked: Concatenates the transforms of both the component and tracked data together.

Tracking Only: Ignores the transforms of the component, and only uses the tracked data.

Flip Tracked Rotation

If enabled, reverses the tracked rotation. Useful if you want a mirror image type of effect on your character.

Face Material

Applies a material to the face mesh of the AppleARKitFaceMesh component. By default, the AppleARKitFaceMesh component is not visible. We generally recommend you add an unlit wireframe material to this property to make the mesh easily visible, as was done in the Face AR Sample project,

Live Link Subject Name

Used as a unique identifier as part of the Live Link animation pipeline.

Driving Joints with Face Capture

Most character faces for games or real-time projects are not animated with blend shapes alone. Generally, there is also some sort of facial skeleton helping to control movement of facial parts. Although the Live Link implementation for face capture in ARKit can automatically drive facial blend shapes, with the help of a Pose Asset you can also drive facial joints.

It is important to note that bone setups are not required when using ARKit for facial animation. It is documented here in the event you either already have joints in your facial setup, or know that you will need them.

Corrective Blend Shapes with Joints

In certain cases, such as when using joints animate a face, you may find that you will also need a blend shape that is triggered at the same time in order to make the motion look appropriate. Such blend shapes are often referred to as corrective blend shapes.

For example, look at this image where the Kite Boy's jaw is opening only with joint rotation, and how it is improved by layering a corrective blend shape on top of it.







On the left is the boy's mouth opening with joint rotation only. Notice that the lower part of the jaw looks too wide. The middle shows the jaw opening with joint rotation, but now with a corrective blend shape layered on it. The jaw is stretching properly and looks more natural. On the right is the corrective blend shape by itself, it contracts the mouth and chin to aid in the stretching process. The idea is that these two systems, joint rotation and corrective blend shapes, will always work together; never one without the other.

More Corrective Blend Shapes

In the Face AR Sample's Animation Blueprint, you'll notice in the Animation Graph a section that is just adding on corrective blend shapes. This is for special correctives such as when the eye is looking in diagonal directions, such as both left and down. Such poses are generally handled by way of additional blend shapes not included in the original list provided with ARKit, and blending them on based on the value of standard shapes.

For example, if you have a special corrective blend shape for when the right eye is looking diagonally down and left, then you could use your Animation Blueprint to read the values of eyeLookDownRight and eyeLookInRight, and use that data to activate a completely separate blend shape. This can bee seen in the Face AR Sample AnimBP.

Creating a Pose Asset for Facial Animation

To create the necessary Pose Asset to drive facial animation from ARKit data:

Create an animation in your DCC app in which:

The first frame is the rest pose, keyframed with no changes.

For frames 2 and on, each frame should be a different keyframed skeletal pose that achieves the pose from Apple's ARKit list. For example, Frame 2 could be eyeBlinkLeft, Frame 3 could be eyeLookDownLeft, and so on.

You do not need to create every single pose requested by the ARKit list, only those that would require joints to move for your rig. For instance, in the case of our Face AR Sample file, jawOpen is handled by way of joint rotation. However, there is also a blend shape that squishes the face in a bit for a more natural look while the jaw is opening.

Note: you can see an example of what this animation will look like in the Face AR Sample project, with the animation Asset named KiteBoyHead_JointsAnim.

You must keep a list of what poses are in the animation, and the order in which they appear. We recommend that you do this in a spreadsheet, so you can easily paste the names into Unreal Engine later.

Import your animation into the Unreal Engine, making sure it is associated with your character's skeleton.

Right-click on the animation in the Unreal Engine and choose Create > Create Pose Asset.

The Asset will have a list of poses for each frame of the animation. You can copy and paste a list of names straight from a spreadsheet to rename them.

Special thanks goes to the team at 3Lateral, who were a great help in setting up the rig for the Kite Boy's face.

Remapping Curve Names in a LiveLinkRemap Asset

In the My Blueprint panel's Function group, choose Override and select Get Remapped Curve Names.

This opens up a function graph with inputs and outputs. The goal is to use this graph to change the incoming name from the expected list of names from Apple's SDK, to a name that corresponds to blend shape names on your character. For instance, if you had a character whose blend shapes were named appropriately, but had "Character_" appended to them, you would use a graph like this:



Click for full image.

Notice that it takes the incoming name from the Apple SDK, appends "Character_" to the front, and outputs the result.

Handling Head Rotation

For some projects you may need access to rotation of the tracked face. In the Unreal Engine implementation of ARKit, we pass in the rotation data alongside the face shape values. Within the KiteBlyHead_JointsAndBlends_Anim Animation Blueprint, you will see a section where this data is broken out and applied to the joints of the neck and head via Modify Bone nodes, as shown here:



Click for full image.

The data is sent out by way of 3 curves: HeadYaw, HeadPitch, and HeadRoll.

Deploying to iPhone X

The Face AR Sample project should be deployed to an iPhone X to fully explore its feature set. While there are deployment docs in place already, see iOS Game Development, you may find it easier to use the Project Launcher to deploy the Face AR Sample project to your device.

Open Project Launcher (use the small arrow to the right of the Launch button on the main toolbar).

At the bottom of the window click the + button across from Custom Launch Profiles to create a new profile.

Set the following settings:

Build Configuration: Development

How would you like to Cook Content: By the Book (also check iOS in the build list)

Cooked Maps: FaceTrackingMap_Simplified (we do not recommend deploying FaceTrackingMap2, as it is not optimized for mobile rendering)

How would you like to package the build: Do not package

How would you like to deploy the build: Copy to Device: All_iOS_On_ (on Mac, you may see your specific device - choose it if you do)

Click Back when finished.

Plug in your device, making sure iTunes can see it.

Click the Launch This Profile button for your new profile.

Project Features

The Face AR Sample project should be deployed to an iPhone X in order to be explored properly. Once on devices, users can test out all of the features of the system, which include:

Calibration

Live Link Broadcasting

Show/Hide Debug and Stats Data

Mirroring Control

Calibration

By default, the character's face may not seem to mimic your own. In many cases, there are slight discrepancies between expectations and the final pose, generally due to data interpretation from the SDK to the character. This is most easily seen as a slight parting of the Kite Boy's lips when the user is in a neutral pose with the mouth closed while using the app.

To counteract this problem the app has a calibration system. In the app, the calibration system can be opened by way of the settings button in the lower left corner, then entering Calibration Mode. The app will guide you through the process from there.



In the Editor, the Face AR Sample project also has a calibration process.

While Simulating in Editor, select the KiteBoy in the scene.

You will see the In Editor Calibration event button in the Details Panel. Click the button to calibrate in the same manner as the app.

In both cases, the project is recording the current facial capture values received by the SDK, and scaling those to the new zero. The function to gather those values is in different locations depending on whether you are on device or within the editor (in the pawn within app, within the Kite Boy Blueprint in editor). Once gathered, the values are processed in the Animation Blueprint using a Modify Curve node with its Apply Mode setting set to Remap Curve.



Live Link Broadcasting

Aside from just being used for amusement, the Face AR Sample showcases how the iPhone X and ARKit can be used as a powerful digital puppeteering and motion capture device. This is done somewhat outside of the standard Live Link workflow, but has been simplified on the app.

It is important that the device and the computer are on the same physical network—check the WiFi settings on your iPhone to make sure.



Within the app, tap the Settings button.

Tap the Live LInk Connection button,

Enter your IP address into the provided line.

Relax your face as shown in the image.

Tap Connect.

You are given the option of saving your IP address. This will save your IP address between sessions. However, we intentionally do not save the state of the Save IP Address checkbox, so you must confirm the setting each time you relaunch the app.

Show Flag Checkboxes

The Face AR Sample app includes a few checkboxes for features that can be turned on and off to display specific features.

Show Debug Mesh

Show Debug Values

Show Unit Stats

This checkbox shows and hides Apple's ARKit debug mesh. This is the mesh the SDK is using to track the motion of the user's face. Within the app, this is rendered with a very simple unlit wireframe material.



If using the Face AR Sample app as a facial motion capture puppeteering device, it is recommended that you only show the Debug Mesh. This is faster, more performant, and has less of an impact on device thermals. This is important, as performance of the device diminishes if it overheats.

Show Debug Values give you direct visualization of the numeric float data being passed from ARKit into the Unreal Engine. These values are separate from any calibration offsets that are in place. Use the debug values to help diagnose discrepancies between the incoming ARKit data, and the expected result in your apps.



Show Unit Stats is the same as typing STAT UNIT into the console within the app. This just opens up the standard unit stats in the Engine, so you can see performance numbers on the device.



Help & About

The Help & About screen is an in-app overview of the Face AR Sample, similar to what you see on this page.

Connecting the App to Your Computer

One of the more exciting features of the Face AR Sample project is that it can be used as a motion capture device on your computer. The app has been streamlined to make this process as painless as possible, but before you begin, verify that the device and your computer are on the same physical network.

It is important that the device and the computer are on the same physical network—check the WiFi settings on your iPhone to make sure.

Launch the Face AR Sample project on your computer.

Open the FaceTrackingMap2 map in the editor and navigate to a viewing position directly in front of the character.

Press Simulate in the Editor (located under the arrow next to the Play in Editor button).

On your device, launch the Face AR Sample app.

After a few seconds, the settings button appears in the lower left corner. Tap it.

Choose LiveLink Connection from the Settings panel.

Enter your computer's IP address into the provided line.

Tap Connect.

Creating an XR Project

XR Best Practices

Next Steps

Unreal Engine supports development for head-mounted XR devices and handheld augmented reality devices. The sections below contain links to documentation on how to get started developing for these XR devices in Unreal Engine.

Creating an XR Project

These pages are all the templates and sample projects you can use as a starting point for your XR projects. The pages also describe the settings and blueprints required for developing with XR.



Describes how to get started doing collaborative VR and desktop design reviews with the Collab Viewer Templates.



Learn how to set up a new AR project from a blank template.



Learn how to get started and use the VR Template as a starting point for your VR projects.



Describes how to get started with the HoloLens Viewer Template.



A guide to setting up a project with the Handheld AR Template and preparing your mobile device to test it



A reference page for where key features of the Handheld AR Template are implemented and how they function



Learn how to set up a new AR project from a blank template.

XR Best Practices

This page provides recommendations on how to develop your XR projects, covering information ranging from user comfort to content optimization and limitations of the platforms.



Best practices for creating and optimizing content for XR projects

Next Steps

After setting up your XR project, follow these guides to add more functionality to your project and to improve its performance.



Add user input to your AR and VR projects in Unreal Engine



Design user interfaces for XR experiences in Unreal Engine



Create an immersive experience for multiple users in Unreal Engine



Tools and strategies for profiling your XR projects in Unreal Engine

Industry-Specific Templates

Workflow

VR Support

Getting Started

How-To Guides

Reference

The Collab Viewer Templates join multiple people together in a shared experience of the same 3D content. They are intended to make it easier and quicker for your team to review and communicate about designs in realtime, so that you can identify problems and iterate on the content more efficiently.

Industry-Specific Templates

Unreal Engine offers two Collab Viewer Templates to work with, that are customized for specific user needs.

OEM/Manufacturing: This template has custom content intended for automotive design. It includes different types of lights present in the scene to demonstrate effects on car surfaces under different conditions.



Click image to expand.

AEC: This template has custom content intended for architecture, engineering, and construction, including a sample building to demonstrate how to set up an architectural mockup.



Click image to expand.

Every participant in a Collab Viewer session can use a computer set up with a standard mouse and keyboard, or with a VR headset and motion controllers. The Templates offer a variety of built-in tools for interacting with the scene content at runtime. Every participant can move objects around, change objects to a see-through X-Ray material, play animations that "explode" content into different spatial arrangements, and more. Everyone sees an avatar of each other person in the session, and can use a laser pointer tool to point out features of the environment:



Click image to expand.

The Collab Viewer Templates handle most of the difficult problems inherent in multi-viewer experiences, including setting up connections and replicating presence information between multiple computers. Use one as a starting point for your design review experiences, so that you can spend less time setting up networking and more time thinking about your designs. And, while they are most useful for evaluating and communicating your designs in a team environment, they offer enough interaction and navigation controls to be a good a starting point even for single-person experiences around your 3D content.

All of the interaction and navigation controls are provided by Blueprint classes in the Project, so you can customize them, learn from them, or even copy them into your own Projects. For more about working with Blueprint, see Blueprint Visual Scripting.

The pages in this section describe everything you need to know to get started with the Collab Viewer Templates, and to use them for your own content.

For a video walkthrough of the Collab Viewer Templates that demonstrates many of the concepts and procedures described in this documentation, see the recorded webinar:

Workflow

The typical usage pattern for a Collab Viewer Template is:

Create a new Project from the Template, or bring the Template content into your own existing Project.

Set up the Project with the content you want to share with others.This typically involves the same kinds of data import and look development tasks that you would do in any Unreal Engine Project. For details on specific considerations that you'll need to keep in mind when setting up your content, such as collisions and navigation meshes, see Adding Your Own Content to the Collab Viewer.

Use the tools built in to the Unreal Editor to package your Project to an executable file.

Share that file with the people who need to be part of the collaborative review.

One person launches the packaged Unreal Engine application and starts it up in server mode.

Each other person who wants to be part of the same viewing session launches their copy of the application on a separate computer and joins the server session.

For a detailed tutorial that walks you through the steps above using the default content in the Template, see the Quick Start.

VR Support

The Collab Viewer Templates use the OpenXR plugin by default to support VR headset interactions. The custom plugins for individual platforms such as Oculus VR and Steam VR are still supported and can be re-enabled if necessary.

Getting Started



A complete, step-by-step guide to getting up and running with the Collab Viewer Template.

How-To Guides

Reference



Describes how to control the camera and interact with content at runtime in the Collab Viewer Templates.



Describes requirements and considerations that apply when you connect multiple computers together into a design review experience.

Annotating in Desktop Mode

Paint Strokes

Text Annotations

Annotating in VR Mode

Paint Strokes

Text Annotations

Deleting an Annotation

Paint Stroke

Text Annotation

Annotations are handy for taking quick notes as you and other participants fly or walk around your collaborative view. You can write or draw on any vertical or horizontal plane.

Annotating in Desktop Mode

Paint Strokes

To use your laser pointer to paint brush strokes:

Begin or join your team's collaborative view and move to a position next to the area you want to annotate.

Press Spacebar to open the Interaction Menu. Highlight Annotation, then select Paint Stroke.



Click for full image.

Face the area you want to paint and use the left mouse button to paint. When you start painting, the edges of the surface you're painting on are highlighted.



Click for full image.

Each time you click and release the button, you create a new brush stroke.



Click for full image.

Text Annotations

To add text annotations:

Begin or join your team's collaborative view and move to a position next to the area you want to annotate.

Press Spacebar to open the Interaction Menu. Highlight Annotation, then select Annotate Text.



Face the area where you want to add text and click the left mouse button. A blank 2D label will be added connected to the geometry where your mouse is pointing. Each time you click, you create a new label.



You can select an individual label and add text using the keyboard.

You can move the labels by selecting either the yellow circle close to the label or the circle in contact with the geometry.



Annotating in VR Mode

Paint Strokes

To use your controller to paint brush strokes:

Begin or join your team's collaborative view and move to a position next to the area you want to annotate.

Select VR mode from the toolbar or press P on your keyboard to activate VR mode.



To open the Interaction Menu on your VR controller:

Oculus Touch: Open the menu with the A button on the right controller or the X button on the left.

Valve Index Controller: Open the menu with the A button on either controller.

HTC Vive Controller: Open the menu with the Menu button on either controller.

In the Interaction Menu, highlight Annotation > Paint Stroke with the pointer and press the controller's trigger to confirm your choice.



Press the trigger on your controller to paint, and release it to end the brush stroke.



Text Annotations

To use your controller to add text annotations:

Begin or join your team's collaborative view and move to a position next to the area you want to annotate.

Select VR mode from the toolbar or press P on your keyboard to activate VR mode.

To open the Interaction Menu on your VR controller:

Oculus Touch: Open the menu with the A button on the right controller or the X button on the left.

Valve Index Controller: Open the menu with the A button on either controller.

HTC Vive Controller: Open the menu with the Menu button on either controller.

In the Interaction Menu, highlight Annotation > Annotate Text with the pointer and press the controller's trigger to confirm your choice.



Press the trigger on your controller to place a label where your pointer indicates. Each trigger press will create a new label.



You can select an individual label and add text using a virtual keyboard.



You can move the labels by selecting either the yellow circle close to the label or the circle in contact with the geometry.

Deleting an Annotation

Paint Stroke

To delete a paint stroke:

Open the Interaction Menu.

Highlight Annotation, then select Delete Stroke.

Point your laser at the brush stroke, then select it to delete it.



Click for full image.

Text Annotation

To delete a text annotation:

Click the X button on the label you want to delete. It will turn red when you hover over it to indicate which label will be deleted.



Measuring

Measuring Along an Axis (Desktop Mode)

Using Xray to Measure from an Obscured Object

Deleting a Measurement

You and others on your team can take measurements within your collaborative view. You can use the Shift key to snap a measurement to the x-, y-, or z-axis.

Measuring

To measure:

Begin or join your team's collaborative view and move to a position next to the area you want to measure.

Open the Interaction Menu. (In desktop mode, press Spacebar. In VR mode, press the shoulder buttons on the right-hand controller.)

In the Interaction Menu, highlight Measurement, then select Add.



Click for full image.

Select the start point for the measurement, then select the end point for the measurement.



Click for full image.

Measuring Along an Axis (Desktop Mode)

If you want the measurement to snap along the x-, y-, or z-axis, press and hold the Shift key as you release the mouse button to place the second end point.





This option is available only in desktop mode.

Using Xray to Measure from an Obscured Object

To measure from an object that is obscured by other objects, before you begin your measurement, in the Interaction Menu, highlight Xray, then select Apply. Select the objects that obscure the object that you want to use as your end point.

Deleting a Measurement

To delete a measurement:

Open the Interaction Menu. (In desktop mode, press Spacebar. In VR mode, press the shoulder buttons on the right-hand controller.)

Highlight Measurement, then select Delete.

Point your laser at the measurement that you want to delete, then select it.

1 - Packaging and Distributing

2 - One Person Starts a Server

3 - Other People Join

4 - On Your Own

This page contains detailed, step-by-step instructions for getting started with the Collab Viewer Template on your local network with its default content. By the end of this page, you'll know how to start up the runtime experience the Collab Viewer Template provides for you, what your options are for interacting and moving around the scene, and how to get multiple other people on your network to join the same shared experience with you.

The workflow here uses the AEC Collab Viewer template as an example, but the workflows function equally well for the OEM/Manufacturing template.

1 - Packaging and Distributing

2 - One Person Starts a Server

3 - Other People Join

4 - On Your Own

1 - Packaging and Distributing

To take advantage of all the features of the Collab Viewer Template, you'll first need to package your Project to an .exe file. When you want multiple people to connect to a single session, each person needs to run the application from a copy of that packaged .exe file. Therefore, one person on the team needs to package the Project from the Unreal Editor, then distribute that .exe file to everyone else who you need to join the same session.

To package and share your Project:

Create a new Project from the Collab Viewer Template, if you haven't already, and open it in the Unreal Editor.

Select a template category.



Click for full image.

Select the Collab Viewer template.

Select Create Project.

From the main toolbar, choose Platforms Menue > Windows > Package Project.



Click for full image.

Browse to the folder on your computer where you want the Unreal Editor to place the packaged version of your Project, and click Select Folder.

The Unreal Editor begins the packaging process.



When the packaging process is finished, go to the folder that you selected in step 3 above. You'll find a folder called WindowsNoEditor with contents similar to the following: Each person who wants to join the same session in the Collab Viewer will need to have all of the files in this folder on their local computer. It's up to you how best to achieve this for your organization.For example, you could zip up the files in this folder and place the archives in a shared location on your local network. Other users could then copy them to their computer and extract them.

For more information about packaging, and how you can configure the process, see also Packaging Projects.

You must follow this packaging and distribution process each time you change the content in your Project. The 3D models in your Level are not replicated automatically between networked users; they are compiled into the packaged application. In order for everyone in a session to see the latest content, everyone needs to be using the same version of the packaged application.

2 - One Person Starts a Server

In this step, you'll start up a server—a special instance of the Collab Viewer application that other people can connect to.

Double-click the .exe file for your packaged application.In the example below, the Project is named CollabProject, so its packaged application is named CollabProject.exe.

In the welcome screen, set a display name for yourself. This name appears above the head of your avatar, so that other people in the same session can identify you.



Click for full image.

Click the arrow to go to the next step.

Leave the next setting at its default value of Host a session.



Click for full image.

Click the arrow to complete the server setup.

If you only want to use the Collab Viewer Template to make a single-person experience without the ability for other users in your network to join in, you could instead choose the Single Session option here. It gives you exactly the same runtime experience as starting as a host, except that your application doesn't become visible to other people in your network.

You'll start in the main sample Level.



Click for full image.

Use the desktop controls or VR controls to move around the scene and interact.

You can press the Spacebar key (or either thumbstick button in VR) to open an Interaction Menu that lets you make selected objects transparent (Xray), teleport to preset Bookmark locations, move objects around in 3D space, scale your viewpoint, cut and remove a section of the geometry, or load new Datasmith assets during runtime.



Click for full image.

You can also use the menu at the top right to switch between different movement modes—fly, walk, orbit—and, if you have a compatible VR headset set up, to switch into VR.



To learn more, see:

Interacting with the Collab Viewer

Measuring in the Collab Viewer

Annotating in the Collab Viewer

Saving and Loading a Session

While you're working, your computer becomes visible as a server to other computers in your network. As other people join your session, you'll see their avatars appear.

3 - Other People Join

In this step, each person who joins the session launches a separate instance of the packaged application on a different computer, and they all connect to the same server.

Each individual should follow these instructions to join the session:

Double-click the .exe file for your packaged application. For example, in this case, the Project is named CollabProject, so its packaged application is named CollabProject.exe.

In the welcome screen, set a display name for yourself. This name appears above the head of your avatar, so that other people in the same session can identify you.



Click for full image.

Click the arrow to go to the next step.

Change the next setting to Join a session.



Click for full image.

Click the arrow to go to the next step.

The application scans the network, and lists all available servers.



Click for full image.

If you see the server you want in the list, click its name to join the session.



If you don't see the server you want, try the Refresh button to re-scan the network for servers.

If the application can't detect the server, but you know its IP address, activate the Manually specify an IP Address switch. Enter the IP address in the field provided, and click Join.



Click for full image.

You'll start in the main Level. You'll be able to see an avatar for the person running the server, and one for each other person who joins the session:



Click for full image.

The avatars are slightly different for each user:

Each avatar is accompanied by the display name its user entered in the welcome menu.

Each avatar is assigned a random color.

Users in the Walk and VR modes have an avatar that resembles a human shape as on the right in the image above. Users in other navigation modes are represented by a camera as on the left in the image above.

All avatars move and rotate around the scene as their corresponding user moves and looks around, so that you can see where other users are focusing their attention.

Use the desktop controls or VR controls to move around the scene and interact.

4 - On Your Own

Now that you understand how to run the Collab Viewer Template and connect with others, you're ready to get started using the same runtime experience to review your own content. Continue on with the instructions in the Adding Your Own Content to the Collab Viewer Template guide for instructions on getting your own content added to the Project and set up to work in the same runtime experience.

Saving a Session

Loading a Session

Load States in the Unreal Editor

The host and other participants in a collaborative view can save annotations, measurements, Xray transparency state, 3D Cut sections, and the position of items moved by Transform.

Saving a Session

To save your session, select the Save button, type a name for the session, then press Enter.



Click for full image.

Each participant saves their session in their own local copy of the collaborative view package. Sessions are saved in the YourProjectName/Saved/SaveGames sub-folder.

The current positions and rotations of you and other participants are not saved.

You cannot modify a saved session or use the name of an existing saved session.

You cannot save and restore sessions while in VR mode.

Loading a Session

To load a saved session, select the menu next to the Save button, then select a session.



Click for full image.

The list of sessions includes those you have saved, as well as those saved by any other participants who are currently connected.

Load States in the Unreal Editor

You can now reload saved states directly in the editor:

Copy the .sav files representing the states you want to reload as well as the MainSaveGame.sav file from your Saved / SaveGames folder from your application into the same folder in your project.

In the editor, open the CollaborativeViewer > Blueprints > Tools folder, select the Editor_CollabViewerUtility_BP. Right-click and select Run Editor Utility Widget.

A widget containing the Default state selector will appear, you can now select one of the copied states from the drop down list.

You might need to move the camera in the viewport to refresh the parameters.



Click for full image.

Using Your Own 3D Models

Controlling Transform and XRay Behavior

Changing the Starting Level

Loading Datasmith Files at Runtime

The Collab Viewer Template comes with some pre-set content so that you can get started with it right away—see the Quick Start for step-by-step instructions. However, once you're familiar with the collaborative review experience, you'll want to get your own content working inside that experience.

This page describes how to do some of the most common related tasks:

Getting your own 3D models into the template, and setting them up to be compatible with the built-in navigation modes. See Using Your Own 3D Models.

Controlling how the content behaves with the interaction tools built in to the Collab Viewer Template. See Controlling Transform and XRay Behavior.

Changing the Collab Viewer Template to start in a different Level from the one that contains the default pre-set content. See Changing the Starting Level.

Loading your own Datasmith content at runtime. See Loading Datasmith Files at Runtime.

Using Your Own 3D Models

The Collab Viewer template comes with some pre-set content so that you can get started with it right away, but you'll want to swap in your own models so that you can experience them in the same collaborative viewing experience.

The most important thing to keep in mind about this process is that players can only walk and teleport to surfaces that have collision meshes and Nav Meshes. You'll need to make sure that each floor or surface that you want people to be able to explore has a collision volume and Nav Mesh associated with it.

Steps

Getting your own content to work inside the default Level in the Collab Viewer Template involves the following conceptual steps:

Remove the existing content from the Level, such as 3D models and lights, and add your own content.The sample Assets, such as the building, gear assembly, and trees, are organized in a sublevel named SampleLevel. If you want to start your Level from scratch, you can simply remove this existing sublevel and place your content into the main persistent Level (or a new sublevel you create). If you want to keep some of the scene elements from the sample scene, such as the sky sphere and lights, you can move those items to the main persistent Level. Or, you can select and delete the items you don't want anymore, such as the Building, Gears, and Trees folders in the World Outliner.

Place your content and set it up visually exactly as you want people to see it in the packaged application.

Make sure that each surface you want players to be able to walk on or teleport to has a collision mesh set up for it.Depending on how you import your content, you may be able to do this in the 3D design application you use to model the geometry. Otherwise, you can do this by opening your Static Mesh in the Static Mesh Editor, and using the tools in the Collision menu.



Click image to expand.

See also Setting up Collisions with Static Meshes, or Setting up Collisions with Static Meshes in Blueprint and Python if you want to automate the collision setup.

As an alternative, you can use Blocking Volumes to add invisible box-shaped collision volumes into the Level. This is a simple way to get collisions working in your Level without the need to modify your Static Meshes. However, since these volumes aren't attached to your Static Meshes, you may need to move them by hand if you move the geometry in your Level around.

Make sure you have at least one Player Start Actor in the Level. If you need more, you can drag more Player Start Actors from the Basic tab of the Place Actors panel into the Viewport.



Click image to expand.

When a new person joins the session, they start at the position of a randomly selected Player Start Actor. You should have at least one Player Start Actor in your Level, wherever it makes sense for new people to begin. You'll probably want to place the Actors just above a walkable surface, so that if a player switches to Walk mode they won't fall through the surface.

It's a good idea to add a few of these Actors around the same location, so that new people are less likely to overlap the exact location of other players when they join the session.

Make sure that each surface you want players to be able to teleport to has a Nav Mesh by including it in a Nav Mesh Bounds Volume. The default persistent Level has one already that you can resize to cover your 3D models, or you can create your own. You can have as many of these volumes as you need for your Level.To create a Nav Mesh:

If your Level doesn't already have a Nav Mesh Bounds Volume, add one by dragging it into the Viewport from the Volumes tab of the Place Actors panel.



Click image to expand.

Select the Nav Mesh Bounds Volume in the Viewport or the World Outliner, and move its Transform gizmo in the Viewport to the approximate center of the area you want to cover.

In the Details panel, use the Brush Settings to change the size and shape of the volume.



Click image to expand.

Click the Build icon in the Toolbar to rebuild pre-calculated data for your Level, or select Build > Navigation > Build Paths to rebuild only the navigation data.



Click image to expand.

Press P to see the generated Nav Mesh and verify that it covers the areas you're expecting. It is rendered as a green surface that hovers slightly above the collision meshes that intersect the volume.



Click image to expand.

Build your lighting if necessary.

Repackage and redistribute your Project as instructed in the Quick Start page.

End Result

If you've followed all the steps above, you should be able to get multiple users connected to a single design review session, with everyone seeing the custom content you added to the Level.

Controlling Transform and XRay Behavior

You can influence the behavior of the Transform and Xray interactions at runtime by the way you set up your content.

The Mobility setting of each Actor determines whether or not you can use the Transform interaction to move that object at runtime. If you want to be able to move the object at runtime, set its Mobility to Movable. If you want to be able to highlight and select the object, but not to be able to move it around in space, set its Mobility to Static.

The hierarchy of parent and child Actors that you see in the World Outliner affects both the Transform and Xray interactions.

When you use the Transform interaction to move an object at runtime, all of that object's children move along with the parent automatically, maintaining their current offset from the parent.

For example, in this case all the parts of the transmission are parented to Building_Parent: the large flat foundation Actor.



Therefore, at runtime, moving the foundation Actor also moves its child Actors. However, you can still move each child Actor on its own. The next time you move the parent, the children keep their new offsets.

Resetting a child Actor to its original position resets it to its original offset from the parent Actor, not its original position and rotation in world space. Resetting a parent Actor to its original position moves all of its children so that they keep their current offset from the parent.

When you use the Xray Isolate interaction mode, and you select an object in the scene, all other objects that are in the same hierarchy as the selected object are automatically hidden.

For example, in the case of the default scene content, all the objects that make up the main building are under a single top-level parent in the hierarchy. Therefore, when you use Xray Isolate to select any part of the building, all other parts of the building are hidden—that is, all Actors that are parented under the same top-level Building_Parent item.



Click image to expand.

The trees and exterior terrain are unaffected, because they are not under the Building_Parent hierarchy.

The Simulate Physics setting must be off for any Actor that you want to be able to interact with using either the Xray or Transform command. You'll find this in the Details panel under the Physics section.



Changing the Starting Level

The main menu of the Collab Viewer Template is set up to load the CollaborativeViewer_P Level when users complete the main menu. However, you may want to create a new Level to hold your content, and have the main menu start your own Level instead. If you choose to do this, you'll need to change the logic in the main menu so that it opens your Level when the user joins the session.

Steps

To set the starting Level for the Collab Viewer:

Find the Widget_MainMenu Asset in the Content Browser, in the CollaborativeViewer/UMG/MainMenu folder.



Click image to expand.

Double-click the Asset to open it, and click Graph to open the Widget Blueprint view.



Click image to expand.

Find the group labeled Commit user selections. Within this group, find a subgroup named Begin hosting a session.



Click image to expand.

Change the Level Name input on the OpenLevel node to the name of the Level you want viewers to start in when they connect to a session.



Click image to expand.

Compile and Save the widget, then repackage your Project.

End Result

The next time you start your Project and complete the main menu, you will start inside the custom Level that you set up in the procedure above.

Loading Datasmith Files at Runtime

This feature is considered experimental. Currently, it will only function for the single player application, and will be disabled on multiplayer.

You can now load a Datasmith file at runtime. At the moment, it is limited to the .udatasmith file format.



Datasmith runtime loading from the main menu.



The pop-up window to select a file to import in the Collab Viewer.

Press the + (add) button to add a new Destination slot to import a new file.

To delete one existing imported actor you should first select the corresponding destination and then press the bin icon.

The Source button will bring up an explorer window to select a file format to import.

The location line allows the user to change the root position of the imported hierarchy.

Desktop Controls

Toolbar

Common Desktop Controls

Fly Mode Controls

Walk Mode Controls

Orbit Mode Controls

VR Controls

The Interaction Menu

3D Cut Operation

World Scaling

Testing in VR in the Unreal Editor

This page describes the different ways you can control the camera and interact with content at runtime in the Collab Viewer Templates, in both desktop and VR modes.

Desktop Controls

Toolbar

You can use the toolbars at the top of the window to teleport, switch navigation modes, and save the current session.

Icon

Description



Voice Over IP is enabled by default in the project. Toggle it on or off by clicking this icon.



Activates Fly mode. In Fly mode, you can fly freely around the scene in all directions. In this mode, you pass through all geometry regardless of collision settings on the Actors. See Fly Mode Controls.

Returning to Walk mode after being in Fly mode re-enables gravity. Depending on your location, you will either free-fall until you reach the ground, or you will snap to the closest ground surface.





Activates Walk mode. In Walk mode, you're held down to the ground by gravity. As you walk around the scene, you collide with any objects in the Level that are set up with collision volumes. See Walk Mode Controls.



Activates Orbit mode. In Orbit mode, you select a point of interest in the Level. Then, as you rotate the camera, you move around that point of interest, keeping it in the center of the screen. See Orbit Mode Controls.



Activates VR mode, if you have a supported VR headset installed and working. See VR controls.



Saves the current state of the viewer, including annotations and measurements. See Saving and Loading a Session

Switch between modes quickly with the following hotkeys:

Activate Fly mode by pressing U on your keyboard.

Activate Walk mode by pressing I on your keyboard.

Activate Orbit mode by pressing O on your keyboard.

Activate VR mode by pressing P on your keyboard.

Common Desktop Controls

The following controls work the same way in all desktop movement modes: Fly mode, Walk mode, and Orbit mode.

To...

Do...

Activate the laser pointer

Move the mouse cursor to the object you want to highlight, then left-click.

Open the Interaction Menu

Press Spacebar. For details on using the items in this menu, see The Interaction Menu.

Move to a preset bookmark location

Press any number key from 0-9 that has been mapped to a specific bookmark location. See Working with Bookmarks in the Collab Viewer Template.

Exit the application

Press Esc.

Fly Mode Controls

In addition to the Common Desktop Controls, the following controls work in Fly mode.

To...

Do...

Look around the world from your current position

Right-click and drag.

Move forward, to the left, backward, or to the right from your current position

Hold the right mouse button and press W, A, S and D.

Move straight up or down (along the world's global Z axis)

Hold the right mouse button and press Q and E.

Walk Mode Controls

In addition to the Common Desktop Controls, the following controls work in Walk mode.

To...

Do...

Look around the world from your current position

Right-click and drag.

Move forward, to the left, backward, or to the right from your current position

Hold the right mouse button and press W, A, S and D.

Orbit Mode Controls

In addition to the Common Desktop Controls, the following controls work in Orbit mode.

To...

Do...

Orbit the camera around the point of interest

Right-click and drag.

Change the camera's point of interest to a new location, remaining at the current zoom level

Middle-click.

Choose a new point of interest, and zoom to fit the selected object in the viewport

Double middle-click.

Zoom in or out on the current point of interest

Turn the mouse wheel.

Pan the camera left, right, up, or down

Middle-click and drag.

VR Controls

To...

Do...

Teleport to a new location

Oculus Touch: Press and hold the B button on the right controller or the Y button on the left.

Valve Index Controller: Press and hold the B button on either controller.

HTC Vive Controller: Press and hold the Grip button on either controller. You'll see an arc emitted from your controller, and a target marker superimposed on the ground. The target marker represents your Teleport location. Move your controller in real world space to place the marker as close as possible to the place you want to move.



The pointer of the marker represents your facing direction after the teleport. You can control this facing direction by rotating your wrist. Release the button you're holding to complete the teleport.

Activate the laser pointer

Press the main trigger button on either controller, and move the controller around in real world space.

Open the Interaction Menu

Push the right-hand controller thumbstick forward or back. Use the thumbstick to highlight the option you want to activate, then press the thumbstick button to confirm your choice. For details on using the items in this menu, see The Interaction Menu.

Exit the application

Press Esc on your computer keyboard.

The Interaction Menu

The Interaction Menu offers you several commands and modes for interacting with the content in your scene at runtime.



To open the Interaction Menu, press Spacebar in any desktop mode. See VR Controls for how to open the menu on your VR controller.

Command

Description

Transform

Use the options in the Transform sub-menu to move selected objects around in the scene.

Transform > Move

Activates the Transform Move mode. When you select an object in the scene with your laser pointer, you can drag the laser pointer to move the selected object around in 3D space.

Transform > Reset

Activates the Transform Reset mode. When you select an object in the scene with your laser pointer, you instantly reset the selected object to its original position and rotation.

Transform > Reset All

Instantly returns all objects in the scene to their original positions and rotations.

Annotation

Use the options in the Annotation sub-menu to add and remove annotations. See Annotating in the Collab Viewer.

Annotation > Paint

Activates the Annotation Paint mode. While this mode is active, you can paint on a grid.

Annotation > Delete Stroke

Activates the Annotation Delete Stroke mode. While this mode is active, you can select a paint stroke with your laser pointer to delete it.

Annotation > Annotate Text

Activates the Annotate Text mode. While this mode is active, you can place, edit, and delete 2D text labels.

Snapshot > Take

Select to take a snapshot. Snapshots are saved as .PNG files in the YourProjectName/Saved/Snapshot sub-folder of the collaborative view package.

Xray

Use the options in the Xray sub-menu to apply and remove a see-through Material to selected objects in the scene.

Xray > Apply

Activates the Xray Apply mode. While this mode is active, any object you select in the scene with your laser pointer gets the see-through Material applied to it.

Xray > Isolate

Activates the Xray Isolate mode. While this mode is active, and you select an item in the scene with your laser pointer, the see-through Material is applied to all other Actors in the same hierarchy as the one you select.

Xray > Reset All

Instantly removes the see-through Material from all objects in the Level, returning them to their original Materials.

Measurement

Use the options in the Measurement sub-menu to add and remove measurements. See Measuring in the Collab Viewer.

Measurement > Add

Activates the Measurement Add mode. While this mode is active, a measurement is drawn between each pair of points that you select.

Measurement > Delete

Activates the Measurement Delete mode. While this mode is active, you can select a measurement with your laser pointer to delete it.

Measurement > To Centimeter

Use this option to set your unit of measure to centimeters.

Measurement > To Meter

Use this option to set your unit of measure to meters.

Scale

Use the Scaling mode to change your world scaling. Default is 1:1

Bookmark

Opens a list of all Bookmarks in the current Level. Select any Bookmark in the sub-menu to teleport to its viewpoint. See also Working with Bookmarks.

Bookmark > Create Bookmark

Use this option to create a new Bookmark during runtime.

3D Cut Plane

Use the options in the 3D Cut Plane sub-menu to select a section of geometry to remove.

3D Cut Plane > Add/Edit

Use this option to place or transform the 3D Cut volume.

3D Cut Plane > Remove

Use this option to remove the 3D Cut volume.

3D Cut Plane > Include / Exclude

Use this option to toggle between removing the geometry inside or outside the 3D Cut volume.

When an interaction mode is active, such as Xray Apply, the name of the mode appears in the lower right of the viewport.

3D Cut Operation

You can cut geometry based on a 3D cube volume, selecting whether to preserve the geometry inside or outside of the volume. The 3D cube can be translated, rotated, and scaled. It also functions with geometry loaded at runtime, the material of geometry intersecting the volume will be switched temporarily to a custom grey material which supports the operation.



A cutting volume that removes the inside of the volume.



A cutting volume showing only what is inside of the volume.

World Scaling

Each participant can now choose their own scale for the world. They can scale up to view and interact with a real scale model as if it was a mockup, or scale down for more precise movement to observe details. The scale affects the participants' displacement as well as their visual representation. The scaling function can be accessed directly from the HUD or from the Menu.



Click image to expand. The scale can be tuned with a slide bar in the menu and through direct keyboard input on the top HUD.



Click image to expand. The bottom left participant (blue) has a scale 10 times bigger than the world and other participants.

Testing in VR in the Unreal Editor

When you launch a packaged or standalone version of the Collab Template with VR set up on your computer, you'll be able to switch to VR mode using the icon in the Toolbar.

However, if you want to use VR controls while testing your Project in the Unreal Editor, you'll need to follow these steps:

Find the BP_CollaborativeViewer_GameInstance Asset in the Content Browser under CollaborativeViewer/Blueprints/GameInstance.

Double-click the Asset to open it in the Blueprint Editor.

In the My Blueprint panel, select the NavigationMode variable.

In the Details panel, under the Default Value section, select VR for the Navigation Mode option.

Compile and Save the Blueprint.

To launch the preview, use the drop-down arrow next to the Play button in the Toolbar to select VR Preview.

Remember to turn this setting back off before you package your application! If you don't, the resulting package will not work as you expect.

Placing a Bookmark

Steps

End Result

Saving Bookmarks during a Session

The Collab Viewer offers a built-in type of Blueprint Asset called a BP_Bookmark, which you can use to set up predetermined locations and camera views in your Level. Users can easily teleport to these predetermined locations at runtime.

This page explains how to place new Bookmarks into your Level, and how to set up hotkeys that teleport the user between different Bookmarks when they press number keys on the keyboard.

Placing a Bookmark

You can place new Bookmarks anywhere in your Level. However, it's best to make sure that each new Bookmark is:

At ground level.

Immediately above a Static Mesh that has a Collision Mesh set up for it, as instructed in Adding Your Own Content to the Collab Viewer.

Otherwise, if the user is in Walk mode or in VR, they may fall to the ground or through the ground after the teleport.

Steps

To place a Bookmark:

Each Bookmark is represented in the Level by an instance of the BP_Bookmark Blueprint class. You'll find this class in the CollaborativeViewer/Blueprints/Commands/Bookmark/BPs folder of the Content Browser.

To set up a new Bookmark, drag the BP_Bookmark from the Content Browser into your Level.

Select the Bookmark Actor in the Viewport or the Outliner and move it to the position and rotation that you want it in the Level.

Make sure you're moving the Bookmark Actor, and not just its child Camera Component.

Piloting the Actor is a fast and easy way to set its viewpoint the way you want it. See Pilot Actors in the Viewport.

In the Details panel, find the Hotkey setting in the ~ Bookmarks section, and set the hotkey that you want to assign to the new Bookmark.You can enter the number you want to assign directly in the Hotkey field, or use the Assign Unused Hotkey button to assign the Bookmark the lowest available numeric key.

End Result

Users who join the session in desktop mode can teleport to your bookmark location by pressing the hotkey you assigned, by using the Bookmarks menu in the toolbar, or by using the Bookmark item in the Interaction Menu.

See also Interacting with the Collab Viewer Template.

Saving Bookmarks during a Session

During a session in the Collab Viewer, you can record your current position as a new bookmark. The new bookmark will then appear in the Bookmark menu list as an option, and it will be saved and available on reload.

To save a bookmark:

Move to the location where you want to save a bookmark.

Open the Interaction menu, and select Bookmark.

In the Bookmark menu, select Create Bookmark.



Give your new Bookmark a name, and click the +Add button.



You can delete saved Bookmarks by clicking the bin icon next to a saved Bookmark in the Create Bookmark menu.

Setting Up Initial and Exploded Positions

Switching Between Positions at Runtime

A common way to interact with an assembly made up of smaller parts is to explode it: to break its component parts apart from each other in space, so that viewers can see each individual part on its own as well as how they all fit together.

The Collab Viewer Template includes a Blueprint class that you can use to set up an exploded view of your parts, and to toggle the assembly smoothly between its default view and its exploded view at runtime.

Setting Up Initial and Exploded Positions

To set up an exploded view for your own content:

Remove any BP_Explode Actors that you have in your scene already. (You can have multiple BP_Explode Actors in your Level, but the Interaction Menu currently only lists one explode animation at a time.)

Make sure you're working in the same Level as the content that you want your Actor to manage. The BP_Explode Blueprint can only work for content within the same Level as itself. For example, if you're working with the default sample content, open the Levels window (Window > Levels) and double-click SampleLevel.

Find the BP_Explode Blueprint class in the Content Browser, under the CollaborativeViewer/Blueprints/Commands/Explode folder, and drag it into the Viewport.

Select the new Blueprint Actor in the Viewport or the Outliner.

At the top of the Details panel, give your Actor a descriptive name. This name will be visible at runtime in the Interaction Menu so you can trigger and reverse the explode animation.



In the Details panel, find the Explode group. You'll use this group of controls to set up the default and exploded views for your assembly.



In the Actors Root list, you'll need to identify which Actors this Blueprint should animate in the Level.

You can add each Actor to the list separately.

If all the Actors you want to animate are children of the same parent Actor in the World Outliner, you only need to add the parent to this list.

For example, in the image shown above for the previous step, the Building_Parrent Actor is selected. This Actor is the parent of all the default content items that are part of the building. This makes the Blueprint capable of animating all the Actors that make up that building, but not the trees, the transmission assembly, or the exterior ground.

When you have all the Actors you need in the list, move them all in the Viewport (if necessary) so that they appear in the arrangement that you want to be their default starting position. Click the Set Initial Location button to record these transforms.

Click image to expand.

Now, move all the Actors in the Viewport to the positions you want them to be in when exploded. Click the Set Explode Location button to lock in these transforms.

Click image to expand.

You can test the recorded transforms in the Unreal Editor by clicking the View Explode and View Initial Location buttons. When you click these buttons, all the animated parts should swap between the preset positions in the Level Viewport. They won't animate smoothly the way they do at runtime, but you'll be able to check that the Actor positions in 3D space are set up the way you're expecting.



The BP_Explode Actor keeps lists of the Actors it manages. If you need to modify the objects owned by the BP_Explode—for example, to delete some Actors from the Level or change their parenting hierarchy—you must re-set both the initial and explode locations right away before you attempt to view either the initial or explode locations in the Editor. If you don't, these lists of Actors may become out of date. This may result in losing the desired placement of some Actors in your scene.

You can add multiple BP_Explode Actors to your Level to animate different parts of your assembly. However, only the first one will appear in the Interaction Menu.

If you do create multiple BP_Explode Actors, don't include any Actor in more than one BP_Explode. If you do, its positions may not end up where you're expecting.

Switching Between Positions at Runtime

To switch between the exploded and default views at runtime:

Run or test your game, and open the Interaction Menu. (In desktop mode, press Spacebar. In VR mode, press the shoulder buttons on the right-hand controller.) You'll see an item at the bottom of the menu with the name of the BP_Explode Actor you created.

Highlight this menu item and select Execute to make all parts registered with the same BP_Explode move smoothly from their current location in the Level to their exploded position.

If you re-open the Interaction Menu while the assembly is exploded, you'll see a Execute command option. Select this to return the exploded parts from their current location back to their default starting positions.

The following video shows the custom animation we built in the previous section in operation at runtime.

Connecting over a Local Area Network

Connecting Across Networks

Bandwidth Requirements

Other Resources

This page describes some of the network requirements and considerations involved in getting multiple computers to connect together into the same runtime design review session using the Collab Viewer Template.

Connecting over a Local Area Network

The instructions in the Quick Start page show how to connect multiple computers that are running within a simple local area network. You should have no problems connecting in this scenario as long as:

All computers are connected to the same network.

All computers have the standard Unreal Engine networking port 7777 open for communication within that network.

No intermediate network components, such as routers or network address traversal (NAT) services, are set up to block the connection.

If you have problems connecting, please contact your network administrator.

Connecting Across Networks

If you need to have computers join a session across multiple sub-nets or over the open Internet, you will almost certainly need to do some extra network configuration. The exact steps you'll need to follow depend on your network configuration. However, in general:

Your server host needs to be visible to all clients from a specific IP address. This may involve setting up NAT traversal rules on your router and opening your firewall to external communications on port 7777.

Do not expect automatic server detection to work outside of the same network. Clients will need to manually specify the IP address of the server they want to connect to.

To avoid latency and lags, the Collab Viewer is best used locally within the same network.

Bandwidth Requirements

Because the Collab Viewer Template only replicates lightweight data across the network, such as the 3D transforms of the users in the session and their laser pointers, network bandwidth usage should be relatively low. If you need exact measurements, you can profile how the template performs on your network using the Network Profiler.

Other Resources

For additional information on how networking works in the Unreal Engine, see the documentation in the Networking and Multiplayer section.

Setting Up a Blank Project

Adding a Pawn and Game Mode

Creating an AR Session

Step 4 - On Your Own

This guide shows how to create a new empty project in Unreal Engine and add the necessary Blueprints and configurations to turn it into an AR experience.

If you want to start with an AR project that is set up already, see the following AR templates:

HoloLens Viewer

Handheld AR Template for iOS and Android

Setting Up a Blank Project

Follow these steps to create a new Unreal Engine project and level with minimal rendering features enabled. Blank projects open with the default level, which includes a Sky Sphere and Atmosphere Fog objects. These objects will persistently overlay everything in AR, so it's useful to start with an empty level when creating an AR experience to control what will be displayed.

Launch Unreal Engine from the Epic Games Launcher.

In the Unreal Project Browser window, choose Games .



Click image to expand.



Select the Blank Template.



Click image to expand.



For the Project Defaults, choose the following:

Blueprint

Scalable

Raytracing Disabled

Mobile

No Start Content



Click image to expand.



From the Editor Choose File > New Level… and choose Empty Level. Make sure to name and save your level. In this example, the level is named Main.



In the main navigation, choose Edit > Project Settings.

In the Project Settings window, select Maps & Modes under the Project section. Set the Editor Startup Map and the Game Default Map to the new level Main.



Click image to expand.



Adding a Pawn and Game Mode

In Unreal Engine, a pawn is the physical representation of the user and defines how the user interacts with the world. The Game Mode object defines the rules of the experience, such as which pawn object to use. In order to build a new AR project, you need to set up the pawn so you can interact with the environment when you run your app.

Follow the steps below to create a Pawn and Game Mode for your AR project.

Right-click in the Content Drawer and choose Blueprint Class from the list. In the Pick Parent Class window, select Pawn. Name the asset ARPawn.





Double-click the ARPawn object in the Content Drawer to open it in the Blueprint Editor. In the Blueprint Editor, choose Add Component and search for Camera.



Make sure the Camera component's parent is DefaultSceneRoot.



Right-click in the Content Drawer and choose Blueprint Class from the list. In the Pick Parent Class window, select Game Mode Base. Name the asset ARGameMode.



Double-click ARGameMode to edit the settings. Set Default Pawn Class to ARPawn.



Click image to expand.



In the main navigation, choose Edit > Project Settings to open the Project Settings window.

In the Project Settings window under the Project section on the left, select Maps & Modes.

Set Default GameMode to ARGameMode

Set Default Pawn Class to ARPawn.



Click image to expand.



Creating an AR Session

The function Start AR Session requires an ARSessionConfig object, which defines all the AR-specific capabilities for the project. See UARSessionConfig for more information on what each setting is.

Follow the steps below to add the AR session logic to your project.

Right-click in the Content Drawer. Choose Miscellaneous > Data Asset to open the Pick Data Asset Class window.



In the Pick Data Asset Class window, choose ARSessionConfig. Name the data asset ARSessionConfig. Open the asset and select Save to confirm the default AR options.



Double-click the ARPawn asset to open it in the Blueprint Editor. Add the function Set Tracking Origin. Set the Origin value to Floor Level.



Add the function Start AR Session. Set Session Config asset to ARSessionConfig.



Add the function Stop AR Session.



When you launch your project on your device, you will now be able to navigate your AR environment. See the documentation for your AR platform for detailed steps on how to launch your Unreal project on your device.

Step 4 - On Your Own

In this guide, you learned how to create a new AR project, and add the necessary Blueprints to get started building an AR app.

VR Project Settings

VR .ini Settings

VR Frame Rate Optimization

VR World Scale

VR and Simulation Sickness

VR Camera Setup

VR Content Considerations

Known Limitations

Normal Mapping Issues

Virtual reality (VR) is an immersive new medium, with unique aspects to consider when authoring and presenting content to users on these platforms. Considerations include user comfort, content optimization, and limitations of the platforms. Use this page as a reference for these topics as you develop your projects for VR.

VR Project Settings

VR projects can be created as a Blueprint or C++ project.

When you create a new project targeting VR platforms, start with the VR Template in the Games category. The VR Template provides everything you need to start develping VR projects in Unreal Engine 5.

If you don't want to use the VR Template as a base for your project, you can create a new blank C++ or Blueprint project with the following settings:

Quality Preset: Scalable

Raytracing: Disabled

Starter Content: Disabled



These settings create an Unreal project with minimal rendering features enabled. This ensures that the project starts with a good framerate, and you can add any other rendering features you need.

After you create the project, set the following project settings to improve the performance of your apps:

Go to Edit > Project Settings > Description, and enable Start In VR.

From Edit > Project Settings > Rendering > Forward Renderer, enable Forward Shading.

In Edit > Project Settings > Rendering > Default Settings, set the Anti-Aliasing Method to Multisample Anti-Aliasing (MSAA).

From Edit > Project Settings > Rendering > VR, enable Instanced Stereo.

For mobile VR experiences, enable Mobile Multi-View in Edit > Project Settings > Rendering > VR.

Also set Mobile HDR to False

VR .ini Settings

See the Scalability Reference for explanations and examples on scaling the graphics of your app to improve its performance or quality. The following table describes some console variables and their recommended values for VR projects.

Console Variable

Recommended Value

Description

vr.PixelDensity

1

1 is the ideal resolution for the HMD that is currently being used. Lower values will perform faster but will be undersampled (more blurry), while values over 1 will perform slower and will supersample (extra sharp).

r.SeparateTranslucency

0

This can be expensive for mobile VR experiences because of fill rate limits. It's recommended to disable this feature.

r.HZBOcclusion

0

See the Hierarchical Z-Buffer Occlusion section in the Visibility Culling page for more details.

The following .ini settings are from the UE4-powered VR demo Showdown. You can use these settings as a starting point by copying them to your project's Config/DefaultEngine.ini file under SystemSettings.

VR Frame Rate Optimization

Most VR applications implement their own procedures to control the VR frame rate. Because of this, you should disable several general UE4 project settings that can interfere with VR applications.

Follow these steps to disable general framerate settings in UE:

From the editor's main menu, choose Edit > Project Settings to open the Project Settings window.

In the Project Settings window, choose General Settings in the Engine section.

In the Framerate section:

Disable Smooth Frame Rate.

Disable Use Fixed Frame Rate.

Set Custom TimeStep to None.



VR World Scale

Ensuring the correct scale of your world is one of the most important ways to help deliver the best user experience possible on VR platforms. Having the wrong scale can lead to all kinds of sensory issues for users, and could even cause simulation sickness. Objects are most easily viewed in VR when they are in a range of 0.75 to 3.5 meters from the player's camera. Inside of UE4, 1 Unreal Unit (UU) is equal to 1 Centimeter (CM). This means that objects inside of Unreal are best viewed when they are 75 UU to 350 UU away from the player's camera (when using VR).

Distance

Distance in Unreal Units (UU)

1 centimeter

1 Unreal Unit

1 meter

100 Unreal Units

1 kilometer

100,000 Unreal Units

You can adjust the scale of your world using the World to Meters variable located under World Settings. Increasing or decreasing this number will make the user feel larger or smaller in relation to the world around them. Assuming your content was built with 1 Unreal Unit = 1 cm, setting World To Meters to 10 will make the world seem very large, while setting World To Meters to 1000 will make the world seem very small.



VR and Simulation Sickness

Simulation sickness is a form of motion sickness that can affect users during immersive experiences. The following list describes some best practices to limit the discomfort that users can experience in VR.

Maintain framerate: Low framerates can cause simulation sickness. Optimizing your project as much as possible can improve the experience for the user. See the following table for the recommended frame rates that you need to target for your XR platform.

HMD Device

Target Frame Rate

Oculus Rift S

90

Oculus Quest 1

72

Oculus Quest 2

Situational: 72/80/90/120

HTC Vive

90

HTC Vive Pro

90

Valve Index

90 minimum, up to 144

HP Reverb

90

Windows Mixed Reality VR

90

PSVR

Situational: 60/120, 90/90, and 120/120

HoloLens 2

60

Keep users in control of the camera: Cinematic cameras, or anything that takes control of camera movements away from the player, contribute to user discomfort in immersive experiences. Camera effects, such as head bobbing and camera shaking, should be avoided because they can lead to user discomfort if the user is not controlling them.

Field of View (FOV) must match the device: The FOV value is set through the device's SDK and internal configuration, and matches the physical geometry of the headset and lenses. Because of this, the FOV should not be modified in UE, and should not be modifiable by the user. If the FOV value is changed, the world can appear to warp when you turn your head, leading to discomfort.

Use lights and colors that are more dim, and avoid smearing: When designing elements for VR, you might need to use dimmer lights and colors than you normally would. Strong and vibrant lighting in VR can cause simulation sickness to occur more quickly. Using cooler shades and dimmer lights can help prevent user discomfort. This also helps with preventing smearing between bright and dark areas on the display.

Movement speed should not change: Users should start at full speed instead of gradually accelerating to full speed.

Avoid post process effects that greatly affect what the user sees: Avoid post process effects such as Depth of Field and Motion Blur to prevent user discomfort.

Visual Effects such as Motion Blur and Depth of Field should be avoided.

Consider things like character height, width, speed, and camera location as they need to be slightly modified for VR characters.

VR Camera Setup

VR camera setup in UE4 depends entirely on whether your VR experience is seated or standing:

Seated experience: You will need to artificially raise the camera origin to the desired player height for the project. And call the Set Tracking Origin function, with Origin set to "Eye Level".



Standing experience: Make sure the camera origin is set to 0, relative to the pawn's root, which is typically on the ground. Attach a camera component to a scene component at the base of the pawn, at the ground level. And call Set Tracking Origin with the Origin parameter set to Floor Level.





VR Content Considerations

When creating VR content, remember that users can look at that content from multiple angles. Use the following list as a reference as you create content for VR:

Scale: The scale of objects in a VR world should mimic reality as closely as possible. Making objects bigger or smaller than their real world counterparts could lead to confusion or simulation sickness.

Missing Polygon Faces: In non-immersive experiences, it is a common practice to remove polygon faces from objects that cannot be seen by the player. However, in VR experiences, players may have more freedom to look around. Missing polygon faces can sometimes lead to users being able to see things that they're not supposed to see.

Lighting Types: You should use Static Lights and Lightmaps for VR projects. This is the cheapest lighting option to render. If you need to use dynamic lighting, make sure to limit the amount of dynamic lights to as few as possible, and make sure that they never touch one another.

VR and VFX: Some VFX tricks, like using SubUV Textures to simulate fire or smoke, do not hold up very well when viewed in VR. In many cases, you will need to use static meshes instead of 2D particles to simulate effects like explosions or smoke trails. Near-field effects, or effects that happen very close to the camera, work well in VR, but only when the effects are made up of Static Mesh particles.

VR and Transparency: In 3D graphics, rendering transparency is extremely costly, because transparency will generally have to be reevaluated per frame to ensure that nothing has changed. Because of this reevaluation, rendering transparency in VR can be so costly that its cost outweighs its benefits. However, to get around this issue, you can use the DitherTemporalAA Material Function. This Material Function will allow a Material to look like it is using transparency and can help avoid common transparency issues, such as self-sorting. Click for full image.

Fake everything you can: Finding clever ways to recreate expensive rendering options, like dynamic shadows or lighting, can be a huge win for hitting your performance goals in VR. In Showdown, having the characters cast dynamic shadows proved to be too expensive per-frame, which meant that dynamic shadows had to be cut from the project. However, this made the characters look like they were floating while moving. To fix this, fake blob shadows were introduced that could dynamically adjust their position and intensity based on how close the character was to an object in the world. This helped give the illusion that a character was casting shadows when they came close to the ground (or other objects).

Click for full image.

Known Limitations

Below you will find a list of features that might not work as expected in VR because of how HMDs are designed, along with possible workarounds to address them.

Screen Space Reflections(SSR): While SSR will still work in VR, the reflections they produce could have issues matching up to what it is reflecting in the world. Instead of using SSR, use Reflection Probes as they are much cheaper and suffer less from reflection-alignment issues.

Screen Space Global Illumination: Screen space techniques can generate differences between the displays for the two eyes in the HMD. These differences can cause user discomfort. See Lighting Types for recommended lighting types in VR for replacements.

Ray Tracing: VR apps using ray tracing currently aren't able to maintain the resolution and frame rate needed for a comfortable VR experience.

User Interface: 2D UI is not supported in stereo rendering since it does not work well when viewed in stereo. Instead of 2D UI, use a widget component placed in the 3D world. See Creating 3D Widget Interaction for more on how to create these widgets.

Normal Mapping Issues

When viewing Normal maps on objects in VR, you will notice that they do not have the impact that they might have once had. This is because Normal mapping does not account for having a binocular display or motion parallax. As a result, Normal maps often look flat when viewed with a VR device. However, that does not mean that you should not or will not need to use Normal maps; it just means that you need to more closely evaluate if the data in the Normal map would be better off made out of geometry. Below, you will find a technique that can be used in place of Normal maps.

Parallax Mapping: Parallax mapping takes Normal mapping to the next level by accounting for depth cues that Normal mapping does not. A Parallax mapping shader can better display depth information, making objects appear to have more detail than they do. This is because no matter which angle you look at, a Parallax map will always correct itself to show you the correct depth information from your viewpoint. The best use of a Parallax map would be for things like cobblestone pathways and surfaces with fine detail.

XR Development

Developing for Head-Mounted Experiences with OpenXR

Making Interactive XR Experiences

Supported Devices

OpenXR

Pawn, Game Mode, and Player Start

Input

Movement

Teleport

Snap Turn

Setting Allowed Areas for Movement

Grab

GrabType

Menu

VR Spectator

The VR Template is designed to be a starting point for all of your virtual reality (VR) projects in Unreal Engine. It includes encapsulated logic for teleport locomotion, an example VR spectator Blueprint and common input actions, such as grabbing and attaching items to your hand.



This page shows you how to get started with the VR Template and how to use it to create your own VR experiences.

Supported Devices

The VR Template is compatible with the following devices:

Oculus Mobile

Quest 1

Quest 2

Oculus PC

Rift S

Quest with Oculus Link

Steam VR

Valve Index

HTC Vive

Windows Mixed Reality

Before you can use the VR Template, your device will need to be set up for development in Unreal Engine. See the documentation in XR Development for your device to ensure it's set up correctly.

OpenXR

The VR Template uses the OpenXR framework, the multi-company standard for VR and AR development. With the OpenXR plugin in Unreal Engine, the template's logic works on multiple platforms and devices without any platform-specific checks or calls.

The OpenXR plugin in Unreal Engine supports extension plugins. You can find extension plugins in the Marketplace or create your own to add functionality to OpenXR that isn't currently in the engine by default.

Pawn, Game Mode, and Player Start

The following objects determine the rules of the VR Template experience and how it's set up.

UE Object

Name of Object in VR Template

Location

Description

Pawn

VRPawn

Content > VRTemplate > Blueprints

In Unreal Engine, a Pawn is the physical representation of the user and defines how the user interacts with the virtual world. In the VR Template, the Pawn contains the logic for input events from the motion controllers.

Game Mode

VRGameMode

Content > VRTemplate > Blueprints

The Game Mode object defines the rules of the experience, such as which Pawn object to use. The Game Mode is set in Project Settings, in the Maps & Modes section.

Player Start

Player Start

World Outliner

The Player Start Actor defines where the Pawn is spawned in the virtual world. For VR experiences, the Player Start's origin is the tracking origin in the virtual world. Since the VR Template is designed for standing experiences in VR, the Player Start is located at floor level.

Input

Input in the VRTemplate is based on the Action and Axis Mappings Input System in Unreal Engine. See Input with OpenXR for more information on how to set up input with OpenXR.



Movement

Movement in VR experiences is referred to as locomotion. In the VR Template, there are two types of locomotion: Teleport and Snap Turn. In the Blueprint Editor, open the VRPawn to see how both are implemented.

Teleport

To teleport to different locations in the Level:

Move your right Motion Controller's thumbstick or trackpad in the direction you want to move. The Teleport visualizer appears in the level to indicate where you will move to.

Release the thumbstick or trackpad to teleport to the selected location.



Snap Turn

To rotate your virtual character without moving your head, move your left Motion Controller's thumbstick or trackpad in the direction you want to turn.



Setting Allowed Areas for Movement

The Level uses a Navigation Mesh to mark where the user is allowed to move. See the NavModifierVolume asset NavModifier_NoTeleport as an example of how this can be implemented. The asset's Area Class parameter is set to NavArea_Null, which prevents the user from moving to that volume.



The teleport visualizer disappears when it's in the NavModifier_NoTeleport volume.

Press the P key on your keyboard to toggle the visualization of navigable areas.



Grab

The VR Template shows a couple different ways to pick up objects and attach them to your hands.

To grab an object in the level:

Reach out to a grabbable object, then press and hold the Grip button on your Motion Controller.

This creates a Sphere Trace around the position of your Motion Controller's GripLocation. If there's an Actor with a GrabComponent in that sphere, it becomes attached to the hand that pressed the Grip button.

Release the Grip button on the same Motion Controller to detach the object from your hand.

To enable grabbing on an actor, add the GrabComponent blueprint to the actor and select the Grab Type in the Details window. On BeginPlay, the collision profile of the component's parent is set to PhysicsActor, which is the trace channel used for the Sphere Trace in VRPawn.

You can open the GrabComponent Blueprint class to see how the grab system is implemented in the VR template.

GrabType

You can set the type of grab in an object's GrabComponent to define how the object attaches to your hand.

The following grab types are defined in the GrabType Enum asset:

Free: The Actor stays in the position and orientation relative to where the Motion Controller grabbed it. See the small cubes as an example.



Snap: The Actor has a specific position and orientation relative to the Motion Controller. See the pistols as an example.



Custom: With this option, you can add your own logic for the grab action, using the OnGrabbed and OnDropped events. You can also utilize other exposed variables, such as the bIsHeld boolean variable, which is a flag that specifies whether an object is currently held by the user. Examples of other types of custom grab actions that can be created include two-handed grabs, dials, levers, and other complex behaviors, such as Actors that don't overlap geometry when held.

You can define a haptic effect that occurs when grabbing an object by setting the OnGrabHaptic Effect variable in the GrabComponent for the object. An example of a haptic effect includes Motion Controller vibrations.

Important functions used in GrabComponent are abstracted into a common interface using the Blueprint Interface asset VRInteraction BPI. With this Blueprint Interface asset, the VRPawn can simplify its logic and avoid using multiple checks for each kind of object. For more on Blueprint Interface and their benefits, see Blueprint Interface.

Menu

Pressing the menu button on your motion controller opens the VR Template's menu. The menu is built with Unreal Motion Graphics (UMG). See





In the Content Browser, Content > VRTemplate > Blueprints > WidgetMenu is the UMG asset for designing and creating logic for the menu, and the Menu Blueprint defines how the controller interacts with the Widget.

VR Spectator

With Spectator Screen Mode, others can view the VR experience while someone uses the head-mounted display (HMD). The VR Template implements an example of Spectator Screen Mode using the VR Spectator Blueprint.

There are two ways to enable Spectator Mode in the VR Template:

Press Tab to toggle Spectator Mode during the session.

Set VRSpectator bSpectatorEnabled to true.

VR Spectator is not compatible with Mobile VR devices, such as Oculus Quest..

You can control the VR Spectator to view the user with the HMD in the virtual world, with your mouse and keyboard or a gamepad using the following inputs:

Action

Mouse & Keyboard Input

Gamepad Input

Toggle VRSpectator

Tab

Bottom Face button

Move Forward

W

Left Thumbstick up

Move Backward

S

Left Thumbstick down

Move Left

A

Left Thumbstick left

Move Right

D

Left Thumbstick right

Move Up

E or Spacebar

Right shoulder button

Move Down

Q

Left shoulder button

Pitch

Move mouse forward or backward

Right thumbstick Y axis

Yaw

Move mouse left or right

Right thumbstick X axis

Change Field of View (FOV)

Move mouse wheel

Right trigger / left trigger

Reset FOV

Click middle mouse button

N/A

Toggle Fade In and Out

F

Top Face button

Reset Rotation

R

N/A

You can use the VR Spectator as a starting point for implementing multiplayer experiences on the same PC.

Getting Started

Working with the Interaction Menu

Teleporting Content

Interacting with Your 3D Content

The HoloLens Viewer Template is an adaptation of the Collab Viewer Template that works on the Microsoft HoloLens 2. You can use it to see your 3D content overlaid on your actual surroundings in the HoloLens viewer. You can also interact with your models, moving them around and annotating them in real-world space.

Prerequisites - Before you try to get the HoloLens Viewer Template working, we strongly recommend that you first get comfortable with both of the following:

Streaming content from Unreal Engine to the HoloLens 2. See the HoloLens Streaming Quick Start. You will need to have completed all the configuration steps described in this Quick Start.

The basic features of the Collab Viewer Template on Windows.

The HoloLens Viewer Template has the same restrictions on supported hardware and operating systems as all other use of Unreal Engine with HoloLens 2. In particular, it requires Windows update 1903 or greater. For more details, see the HoloLens 2 Prerequisites.

Getting Started

The HoloLens Viewer Template comes with some basic Assets drawn from the Collab Viewer and Product Viewer Templates:



Unlike the Collab Viewer and Product Viewer Templates, the engine model in the HoloLens Viewer Template has no surroundings: no skydome, no buildings. Because you'll be superimposing the virtual world on top of your real surroundings in the HoloLens, you'll typically want the models you work with to be on their own in an empty environment.

The engine model gives you a simple set of 3D objects that you can use to get started. At any time, you can remove it from the Level and replace it with your own 3D content.

When you have the 3D content in your Level set up the way you want it, you can start streaming your Project content to the HoloLens by selecting the VR Preview option in the Unreal Editor Toolbar, as described in the HoloLens Streaming Quick Start.

The HoloLens Viewer Template only streams to the HoloLens 2 device from the Unreal Editor, not from a packaged .exe.

Working with the Interaction Menu

Like the Collab Viewer Template, you'll use a menu to choose different modes of interaction with your models.

To summon the Interaction Menu in the HoloLens Template, use the "watch" gesture: point the index finger from one hand at the wrist of the other hand, as shown below:

Click for full image.

As you move your index finger, a small dot cursor tracks the item you're pointing to. Move your index finger to highlight menu items and open sub-menus. To select an item, highlight it with your dot cursor and tap forward with your index finger.

Click for full image.

The menu fades away after a few seconds with no interaction, or when you're working in an interaction mode. You can call it back at any time by repeating the watch gesture.

Teleporting Content

You can place your virtual 3D content anywhere you want it in real-world space.

Open the Interaction Menu and select the Teleport > To Location option.

Click for full image.

Gaze at the location in real-world space where you want to move your virtual 3D content. A marker will show the current location:

Click for full image.

When you have the gaze marker at the desired location, pinch your fingers to confirm the new location.

Click for full image.

Interacting with Your 3D Content

The Interaction Menu of the HoloLens Viewer offers a subset of the interactions that you can carry out in the Collab Viewer, summarized in the table below.

In all interaction modes, you select objects by hovering over them with your dot cursor and making the "pinch" gesture.

Command

Description

Xray

Use the options in the Xray sub-menu to apply and remove a see-through Material to selected objects in the scene.

Xray > Apply

Activates the Xray Apply mode. While this mode is active, any object you select in the scene with your dot cursor gets the see-through Material applied to it.

Xray > Isolate

Activates the Xray Isolate mode. While this mode is active, and you select an item in the scene with your dot cursor, the see-through Material is applied to all other Actors in the same hierarchy as the one you select.

Xray > Reset All

Instantly removes the see-through Material from all objects in the Level, returning them to their original Materials.

Transform

Use the options in the Transform sub-menu to move selected objects around in the scene.

Transform > Move

Activates the Transform Move mode. When you select an object in the scene with your dot cursor, you can keep your fingers pinched and drag the selected object around in 3D space. Release the pinch to stop moving the object.

Transform > Reset

Activates the Transform Reset mode. When you select an object in the scene with your dot cursor, you instantly reset the selected object to its original position and rotation.

Transform > Reset All

Instantly returns all objects in the scene to their original positions and rotations.

Annotation

Use the options in the Annotation sub-menu to add and remove annotations.

Annotation > Paint

Activates the Annotation Paint mode. While this mode is active, you can draw lines in mid-air by pinching your fingers and moving your hand in real-world space. Release your pinch to stop drawing the line.

Annotation > Delete Stroke

Activates the Annotation Delete Stroke mode. While this mode is active, you can select a paint stroke with your dot cursor to delete it.

Teleport

Teleports the origin of virtual space to a new position in real-world space. See Teleporting Content above.

The HoloLens Template doesn't currently offer the ability to connect live to other viewers, save and load object positions, take screenshots, or measure distances.

Input in OpenXR for Head-Mounted Experiences

Motion Controllers

Hand Tracking

Training Streams

Next Steps

There are many different kinds of input for XR, such as hand tracking, motion controllers, and eye tracking. This page contains links to documentation about how to add input to your XR projects.

Input in OpenXR for Head-Mounted Experiences

The OpenXR runtime uses interaction profiles to support various hardware controllers and provide action bindings for whichever controller is connected. This page explains the concepts of input and controller mapping emulation with OpenXR in Unreal Engine.

Motion Controllers

Motion Controllers represent the controller or hands used for input with XR devices. Motion Controllers can be accessed through a Motion Controller Component, which is typically attached to your project's Pawn. The Motion Controller Component inherits from the Scene Component, which supports location-based behavior, and moves the Pawn it is attached to based on the tracking data from the hardware. This component provides the functionality to render the Motion Controller and to expose the controller for user interactions defined by the Pawn.

These pages show how to set up motion controllers in your project.



Showing you how to pick up and drop objects using Motion Controllers.



Information on how to setup Motion Controllers for VR interaction.

Hand Tracking

There are currently two platforms that support hand tracking with Unreal Engine: HoloLens 2 and Oculus Quest. The following sections explain how to get started with using hand tracking for input on these platforms.

HoloLens 2

Hand tracking on HoloLens 2 is available through the Microsoft OpenXR plugin. Hand tracking functionality defined in the Microsoft OpenXR plugin is compatible with the OpenXR and XRMotionController functions. Refer to Microsoft's hand tracking documentation for more details on visualizing the user's hands and using them as input.



Oculus Quest

Hand tracking on Oculus Quest is available through the Oculus VR plugin. Currently, you cannot use hand tracking with an OpenXR project. The APIs for hand tracking on Oculus Quest are provided through an Oculus-custom component. Refer to Oculus's hand tracking documentation for more details on visualizing the user's hands and using them as input.



Training Streams

Watch these training streams to learn how to add input to your XR projects.

Next Steps

After setting up input in your XR project, follow these guides to add more functionality to your project and to improve its performance.



Design user interfaces for XR experiences in Unreal Engine



Create an immersive experience for multiple users in Unreal Engine



Tools and strategies for profiling your XR projects in Unreal Engine

Poses

The OpenXR runtime uses interaction profiles to support various hardware controllers and provide action bindings for whichever controller is connected. OpenXR input mapping in Unreal Engine relies on the Action Mappings Input System to connect actions to the OpenXR interaction profiles. See Creating New Inputs for a guide on how to use the Action Mappings Input System.

The OpenXR input system is designed to provide cross-device compatibility by emulating any controller mapping that isn't explicitly specified with Action Mappings in the Unreal project. When emulating controller mappings, the OpenXR runtime chooses controller bindings that closely match the user's controller. Because OpenXR provides this cross-compatibility for you, you should only add bindings for controllers you support and can test with. Any bindings you specify for a controller define what actions are connected to that controller. If you only partially apply bindings to a controller, then the controller won't support any missing bindings. In the example below, the project has two actions: Jump and Pickup.

Jump is mapped to keys on multiple controllers, such as Vive Index (L) Trigger and Oculus Touch (L) Trigger.

Pickup is only mapped to Valve Index (L) A Touch. In this case, the OpenXR runtime will not emulate any of the other controllers for the Pickup action, because those controllers have bindings for Jump but not for Pickup. If the keys for the other controllers were removed from Jump, then the OpenXR runtime would be able to emulate the controllers for both Jump and Pickup.



Some runtimes may only support a single interaction profile and do not have the ability to emulate any other profile. You should add bindings for as many devices as you have access to and plan to support.

Poses

OpenXR provides two poses to represent how a user would hold their hand when performing the actions:

Grip: Represents the position and orientation of the user's closed hand in order to hold a virtual object.

Aim: Represents a ray from the user's hand or controller used to point at a target. See the OpenXR specification for more details on the two poses. In Unreal Engine, these two poses are represented as motion sources and are returned in the results when you call Enumerate Motion Sources, if they're available for your device.

Unreal Engine uses a different coordinate system than what's described in the OpenXR specification. Unreal uses the left-handed coordinate system: +X forward, +Z up, and +Y right.

Enable the OpenXRMsftHandInteraction plugin to replicate the OpenXR grip and aim poses of tracked hands on runtimes that support this extension plugin, such as the HoloLens.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Motion Controller Component Setup

Motion Controller Setup

Component, Variable, & Event Setup

Holding and Dropping of Items

Pick Up Object Event

Drop Object Event

Completed Blueprint

Adding Motion Controller support to your UE4 projects can add a level of real sense of immersion and realism. One way to take this immersion and realism to the next level is add the ability to pick up objects placed in the world with your Motion Controllers. In the following document we will take a look at how you can add Motion Controller support your UE4 VR project.

Motion Controller Setup

In the following sections we will go over how to setup your Motion Controllers so that they can pick up and drop items that are placed in the level.

Component, Variable, & Event Setup

Before we can start to add nodes to the Event graph, we first need to create and set up a few Components and Variables. In the following section, we will go over what Components and Variables are needed and what setting they should have.

Component / Variable Type

Name

Value

Scene

HeldObjectLocation

X: 38, Y: 0, Z: 0

Boolean

IsHoldingObject

false



Click for full image.

Make sure that the Held Object Location is parented to the MC_Left as this is where the picked up object will be placed when picked up.

You will also need to create two Custom Events and name them the following:

Node Name

Value

PickUpObject

N/A

DropObject

N/A



Holding and Dropping of Items

The Holding and Dropping of Items section call the different Custom Events that handle picking objects up and holding objects as well as dropping them. The user initiates this by pressing or releasing the Left Motion Controller Trigger. One thing to take note of here is that we are using a Branch statement to make sure that we can only pick one object up at a time. The reason this is important is we only want the user to be able to pick up one object at a time.



Click on the Copy Node Graph in the upper left hand corner to copy the Blueprint code for this section.

Pick Up Object Event

The Pick-Up Object Event section handles all of the logic for finding objects that can be picked up and picking them up. While this is one function, it does have two parts that it can be broken down into. In the following section, we will take a look at these two parts and what they do.

The first part of the Pick-Up Object Event deals with finding the object in the world that meets the requirements for being picked up. To do this, a ray is cast 1,000 CM into the world from the forward facing direction of the user's Left Hand Motion Controller. This ray is also told to ignore any object that does not have an Object Type of Physics Body.



Click on the Copy Node Graph in the upper left-hand corner to copy the Blueprint code for this section.

For testing purposes, the Draw Debug Type has been set to Duration allowing us to the ray that was cast into the world. When you are ready to use this in production, make sure to set the Draw Debug Type to None.

The second part of the Pick-Up Object Event deals with what happens once we find an object we can pick up. When an object is found the Break Hit Result node is used to get more information about what we hit. In this case, we are using it to find out what Actor and Component where hit. Physics is then disabled on that object, and the object is then attached to our Held Object Location that is attached to our Left-Hand Motion Controller. Finally, we set the variable IsHoldingObject to true so that we can not pick something else up.



Drop Object Event

The Drop Object Event section handles all the logic for dropping objects that have been picked up and also making sure that everything is reset, so we are ready to pick something else up.The first thing that the Drop Event does is check to make sure that the user is holding something that can be dropped. If they are holding something, then that object is then detached from their Motion Controller and has its physics re-enabled allowing it to fall to the ground. Finally the Hit Component and Picked Up Actors variables are cleared of any old data making sure they are ready to store the newly picked up object.



Completed Blueprint

With the Blueprint now complete, we just need to add some objects to the world to pick up. Since the objects we are looking to pick up must have a physics body, you can just add a few Static Mesh and set their Mobility to Movable and also make sure to enable Simulate Physics.



Click for full image.

Then place the VRPawn in the world and make sure to set Auto Possess Player to Player 1 and launch your project using the VR preview. Next, put on your Rift HMD and pick up your Touch controllers and aim the Left Touch Controller in front of an object you want to pick up and squeeze the trigger to pick it up. Release the trigger to drop the object and pick up another one like in the following video.

You can copy and paste the completed Blueprint below into your VRPawn Blueprint. Remember that when you copy over to a new Blueprint, you will need to create all of the required Variables and Components.



Click on the Copy Node Graph in the upper left hand corner to copy the Blueprint code for this section.

Supported Platforms

Motion Controller Setup

Motion Controller Component Visualization

Training Streams

No matter which Virtual Reality platform you are developing for, adding support for Motion Controllers can add a level of immersion and interaction that is just not possible to achieve with a controller or mouse and keyboard. In the following How - To we will take a look at how to add Motion Controller support to the VR Platforms that support it.

Supported Platforms

The Motion Controller component that is found in the Components tab will work on the following VR platforms.

Oculus VR

Steam VR

Gear VR

Playstation VR

Google VR

If you do not see the platform you are developing for listed above, make sure to check that platform's documentation for how to go about setting use of Motion Controllers.

Motion Controller Setup

In the following section we will take a look at how to add and setup the components that are needed for Motion Controllers to work.

This How - To has been written assuming that you have setup your Pawn to work with the VR Head Mounted Display (HMD) that you are developing for. If you are not sure how to do this, check please check out the getting started guide for the VR Head Mounted Display (HMD) you are developing for.

First, inside the Content Drawer locate and open up your Player Pawn Blueprint.



Click for full image.

In the Components section click on the Add Component button to expose the components that can be added to this Blueprint.



Click for full image.

Input Motion in the search box and then click on the Motion Controller component to add it to the components list, giving it a name of MC_Left..



Select the newly added Motion Controller component and over in the Details panel under the Motion Controller section make sure the Motion Source is set to Left.



Click for full image.

Next, select the Motion Controller Component in the Components panel and click the Add Component button and then search for and add a Static Mesh Component, calling it SM_Left.



Make sure that the Static Mesh Component is a child of the Motion Controller Component otherwise the Static Mesh will not follow along when the Motion Controller is moved.

Now, in the Details panel of the Static Mesh Component under the Static Mesh section input a Static Mesh to represent what the Motion Controllers will look like. For this example we are using a simple box, but feel free to use any Static Mesh you have available.



Click for full image.

Now, duplicate the entire Left hand Motion Controller setup and re-place the word Left with Right. Also make sure to change the which hand this Motion Controller is used for by going to the Motion Controller component and then changing Motion Source from Left to Right.



Click for full image.

Compile and save your Pawn Blueprint, make sure it is placed in your test level and then launch your project. When you put on your HMD and pick up your Motion Controlers you should be able to now do what is shown in the following video.

Motion Controller Component Visualization

Motion Controllers have a Visualization category that enables you to quickly and more easily add a display model Static Mesh to your Motion Controllers. By default, the system attempts to load a Static Mesh model matching the device driving the Motion Controller. The visualization fields offer the following options:



Property Name

Description

Display Device Model

Used to automatically render a model associated with the set hand.

Display Model Source

Determines the source of the desired model. Ny default, the active XR system(s) will be queried and (if available) will provide a model for the associated device. Note: This may fail if there's no default model; use 'Custom' to specify your own mode.

Custom Display Mesh

A mesh override that'll be displayed attached to this Motion Controller.

Display Mesh Material Overrides

Material overrides for the specified Display mesh.

Training Streams

3D Widgets and Interactions

Attaching Items to the Head-Mounted Display

Visualizing Play Area Bounds for Head-Mounted XR Experiences

Stereo Layers for Head-Mounted Experiences

Loading Screens for Head-Mounted Experiences

Next Steps

Add user interfaces (UI) to your XR project to present information and create interactable objects. This page contains links to documentation about creating UI for XR applications in Unreal Engine.

3D Widgets and Interactions

For XR experiences, the user interface (UI) must be 3D so you can interact with it in the virtual environment. These pages guide you through how to create interactable 3D widgets in Unreal Engine.

Attaching Items to the Head-Mounted Display

You can attach items to the HMD using the Camera Component on the Pawn. This is useful for creating a head-up display (HUD) and attaching any items that need to follow the player. This page guides you through attaching items to your HMD.



Information on attaching items to any HMD.

Visualizing Play Area Bounds for Head-Mounted XR Experiences

Users can define the size of their play area on their XR device. This page describes how to visualize the boundaries of the user's play area in your project.



Visualize the user's stage in their head-mounted experience with OpenXR

Stereo Layers for Head-Mounted Experiences

You can send textures to the head-mounted display (HMD) in a separate rendering pass from the rest of the project. These textures can be displayed without any post-processing effects.

These pages describe the different types of stereo layers and how to use them in your project.



Send textures to the HMD in a separate rendering pass from the rest of the project, to display without any post-processing effects.

Loading Screens for Head-Mounted Experiences

For apps targeting HMDs, you can use a texture as a loading screen to ease transitions between levels. This page shows how to add loading screens to your project.



Learn how to use a texture as a loading screen to ease transitions between levels in XR experiences.

Next Steps

After adding user interfaces to your XR project, follow these guides to add more functionality and to improve your project's performance.



Add user input to your AR and VR projects in Unreal Engine



Create an immersive experience for multiple users in Unreal Engine



Tools and strategies for profiling your XR projects in Unreal Engine

Get Play Area Bounds

Teleportation Visualization

Users can specify the bounds of their play area, sometimes called the stage, on their device. You can access these bounds in Unreal Engine with the OpenXR APIs.



On Oculus devices, the Guardian boundary appears when the user gets close.

This page shows how you can visualize the play area bounds in your project. For setting up play area bounds on your device, refer to your device's documentation.

Get Play Area Bounds

The Get Play Area Bounds function returns the length of the largest rectangle that can be found inside your play area. Play area bounds are visualized by your OpenXR compatible runtime when the user gets close to the boundary. It can also be useful to inform the user when they are moving close to the boundary with custom visualizations in your application.



The Get Play Area Bounds function has three reference spaces it can return: Eye Level, Floor Level, and Stage. These three spaces map to the OpenXR reference spaces View, Local, and Stage, respectively. In most cases, we recommend you return the Stage reference space. For more details on the OpenXR reference spaces, refer to the OpenXR Specification.

If the Get Play Area Bounds function doesn't return any data, the OpenXR runtime you're using might not have implemented the OpenXR functionality for play area bounds.

Teleportation Visualization

An example of visualizing play area bounds is teleportation visualization. The VR Template provides an implementation of this visualization during teleport.



The teleport visualization is defined in the Blueprint VRTeleportVisualizer located in Content/VRTemplate/Blueprints. The following is a description of the logic for visualizing the boundaries.

On Begin Play:

The Blueprint calls Get Play Area Bounds using the Stage reference space.

The Blueprint then assigns the X and Y data to a User Variable in the Niagara System NS_PlayAreaBounds.

NS_PlayAreaBounds dynamically draws a rectangle using the X and Y values returned from Get Play Area Bounds.



On Tick:

The Blueprint moves NS_PlayAreaBounds relative to the teleport location, identified by NS_TeleportRing.

This results in an accurate visualization of where the player will be, relative to the play area bounds, after teleportation.



OpenXR Stereo Layers send a separate texture to the head-mounted display (HMD) and re-project the texture in a separate rendering pass than the rest of the project. This can be useful for user interface (UI) elements that you want attached to the HMD without additional effects applied to them, such as post-processing or anti-aliasing.



Send textures to the HMD in a separate rendering pass from the rest of the project, to display without any post-processing effects.



Learn how to add an OpenXR Stereo Layer to your project.

Stereo Layer Types

Layer Shape

Layer Draw Order

Stereo Layer Properties

OpenXR Stereo Layers send a separate texture to the head-mounted display (HMD) and re-project the texture in a separate rendering pass than the rest of the project. This can be useful for user interface (UI) elements that you want attached to the HMD without additional effects applied to them, such as post-processing or anti-aliasing.

Stereo Layers are rendered to the HMD, but they do not appear in the VR Preview window on your desktop.

This page is an overview of the OpenXR Stereo Layers feature. To learn how to add Stereo Layers to your OpenXR app, see the OpenXR Stereo Layers Quick Start.

Stereo Layer Types

You can set which space the Stereo Layer's position and rotation are relative to. The following are the available types:

Face-Locked: The Stereo Layer stays in the same place in the HMD view, regardless of its position or rotation.



Tracker-Locked: The Stereo Layer position is relative to the real-world tracking space around the player.



World-Locked: The Stereo Layer position is relative to the virtual world space and the object to which it's attached as a Component.



Mixing Face-Locked layer priorities with World-Locked and Tracker-Locked layers by setting the vr.StereoLayers.bMixLayerPriorities console variable is not supported.

Layer Shape

You can set the shape of the layer. Currently, only the Quad layer shape is supported in the OpenXR implementation of Stereo Layers.

Layer Draw Order

Stereo Layers exist outside the virtual world and are drawn based on the Priority setting for each layer. The draw order is determined by the following:

Layers with higher priority are rendered on top of layers with lower priority.

Face-Locked layers are rendered on top of World-Locked or Tracker-Locked layers regardless of priority.

When multiple layers have the same priority, those layers are rendered in no-specified order. Use different priorities if you need a specific ordering for the layers.

Stereo Layer Properties

Stereo Layers have some properties that affect the way in which it is rendered. The following table describes each one of these settings and its effect on the Stereo Layers.

Setting Name

Description

Live Texture

True, if the Stereo Layer texture needs to update itself every frame (scene capture, video, and so on).

Supports Depth

True, if the Stereo Layer needs to support depth intersections with the scene geometry, if available on the platform. This option is currently not supported by OpenXR.

No Alpha Channel

True, if the texture should not use its own alpha channel (1.0 will be substituted).

Texture

Texture displayed on the Stereo Layer (if stereoscopic textures are supported on the platform, and more than one texture is provided, this will be the right eye).

Quad Preserve Texture Ratio

True, if the quad should internally set its Y value based on the set texture's dimensions.

Stereo Layer Type

Specifies how and where the quad is rendered to the screen.

Stereo Layer Shape

Specifies the shape of the layer. Only the Quad layer shape is supported in OpenXR.

Priority

Render priority among all Stereo Layers; higher priority render on top of lower priority.

Left Texture

Texture displayed on the Stereo Layer for the left eye, if stereoscopic textures are supported on the platform.

Quad Size

Size of the rendered Stereo Layer quad.

UVRect

UV coordinates mapped to the quad face.

Cylinder Radius

Radial size of the rendered Stereo Layer cylinder.

Cylinder Overly Arc

Arc angle for the Stereo Layer cylinder.

Cylinder Height

Height of the Stereo Layer cylinder.

This page describes how to get started with Stereo Layers in your OpenXR project.

The steps and images on this page use the VR Template Project as a starting point. The steps should apply to any project set up for OpenXR.

To add an OpenXR Stereo Layer to your project's Pawn:

In the Content Drawer, navigate to Content > VRTemplate > Blueprints and double-click the VRPawn Asset to open it in the Blueprint Editor.



In the Components panel of the Blueprint Editor, click the Add Component button and search for Stereo Layer.



Drag the new Stereo Layer Component on top of the Camera Component to make it a Child Actor of the Camera.



Select the Stereo Layer Component from the Components list to open its Details panel. Under the Transform section, set the X value of Location to 100.



Switch to the Viewport tab of the Blueprint Editor to see the location of the Stereo Layer relative to the Pawn's Camera.



In the Details panel, under the Stereo Layer section:

Assign a texture to the Texture parameter. In this example, the T_Grid texture is used.

Set the Stereo Layer Shape to Quad Layer.



Compile the Blueprint and close the Blueprint Editor.



Press Play in VR to launch your project on the headset and verify that the texture is displayed in front of you and locked to the HMD.



To change where the Stereo Layer appears, change the Stereo Layer Type parameter. See the OpenXR Stereo Layers Overview for details on the available options.

Developing for Head-Mounted Experiences with OpenXR

Set Loading Screen Node

Show and Hide Loading Screen Nodes

Using Loading Screen Nodes

For apps targeting head-mounted displays (HMDs), you can use a texture as a loading screen to ease transitions between levels. At the end of this guide, you will be familiar with the Blueprint nodes used for loading screens and will know how to use them within your project.

Set Loading Screen Node

The loading screen must be defined before you can display it in the HMD.

On the Set Loading Screen node, you can select the texture that you want to use for the loading screen from the Texture pin's Select Asset dropdown.

Then, change the Offset vector to specify the texture's position relative to the position of the HMD.



Media playback through Media Framework is not currently supported with Loading Screens in XR.

Show and Hide Loading Screen Nodes

Once the Set Loading Screen node has been created, connect its output pin to the Show Loading Screen node's execution pin to display it in the HMD.

When you want the loading screen to no longer display, you can connect it to the Hide Loading Screen node's execution pin.



Sometimes it's necessary to add a short delay, using the Delay node, after the Show Loading Screen to ensure the loading screen is visible before the next operation.

Using Loading Screen Nodes

In the following example, a map is loaded using Level Streaming as the map transition.

Follow these general steps to add a loading screen to your project:

In the Unreal Editor, open your Map in the Level Editor.

Click Blueprints > Open Level Blueprint.



In the Event Graph, add the following nodes:

Delay

Set Loading Screen

Show Loading Screen

Load Stream Level

Hide Loading Screen



Connect the output pin from the Event BeginPlay node to the input of the Set Loading Screen node.

On the Set Loading Screen node:

Select a texture from the Texture dropdown.

Set the Scale 2D vector to (1.0, 1.0) — a nonzero value — to see the texture.

Set the Offset 3D vector for the loading screen to (1.0, 0.0, 0.5). The loading screen should appear in front of you within the HMD, but this position can be different depending on your headset.



Connect the output pin of the Set Loading Screen node to the input of the Show Loading Screen node.



Connect the output of the Show Loading Screen node to the input of the Delay node. The delay node will set a specific time duration for the loading screen to display.

Set the Delay node's Duration parameter to 3.0 seconds to make the loading screen display for at least three seconds when you launch the app.



Connect the output pin from the Delay node to the input of the Load Stream Level node.

On the Load Stream Level node:

Set the Level Name parameter to a different Level in your project.

Enable Make Visible After Load.

Enable Should Block on Load.



Connect the output pin of the Load Stream Level node to the input of the Hide Loading Screen node. Placing the Hide Loading Screen node after the Load Stream Level node ensures that the Level has finished loading before being displayed.



Launch the Level on your HMD to see the loading screen appear as the Level changes.

You can also call Hide Loading Screen from Event BeginPlay in the Level Blueprint for the Level you're loading next to ensure the loading screen isn't hidden until the Level has finished loading. You won't need to enable Should Block on Load in the Load Stream Level node when using this method. |

Setting Up Objects To Follow The HMD

HMD and Player World Position

No matter which Head Mounted Display (HMD) you are developing for Unreal Engine 4 (UE4) offers a unified approach to attaching items to the HMD. Not only will this unified approach work with any HMD, the items that are attached will move perfectly in-sync with the HMD. In the following document, we will go over all you need to know about attaching items to the HMD.

Now if you want to get the position of the player in the world you can just get the Camera Actor's position.

Setting Up Objects To Follow The HMD

You can setup a Static Mesh, Particle Effect, UI elements and many more items to follow the movment of the HMD by doing the following.

First open up your Pawn Blueprint and navigate to the Viewport tab.



Click for full image.

From the Component tab, click on Add Component and then input the word Cube into the search box clicking on the Cube mesh that is displayed to add it as a component



Click for full image.

Select the Cube Static Mesh and drag it onto the Camera so that the Cmera is now the parent of the Cube Static Mesh.



Now compile your Blueprint and then launch your project using the VR preview option from inside the UE4 editor. When you put an HMD on then move your head around the Cube you attached will now accurately follow your head movements like in the video below.

HMD and Player World Position

You can also quickly get the exact world location player and their HMD by getting the location of the Camera Component using the following Blueprint setup.



In the above image whenever a user presses the T key on the keyboard the X, Y and Z position of the Camera in the world will then be output to the screen and log window.



ARPins

Spectator Screen for Head-Mounted Experiences

Collaborative Viewer

Next Steps

Make your XR project a shared experience for multiple users by using XR features to share content, and by adding networking. This page contains links to documentation about creating shared XR experiences in Unreal Engine.

ARPins

You can attach your virtual objects to real-world locations with ARPins. You can also save these ARPins to the cloud and share them with other devices so multiple users can view the same content in the same location.

This section guides you through how you can create ARPins in your project.



ARPins are a fixed real-world location in augmented reality (AR) to which you can attach virtual content within Unreal Engine.

Spectator Screen for Head-Mounted Experiences

View the user wearing the head-mounted device (HMD) interacting with the virtual environment on the desktop with Spectator Screen. This page shows how to set up Spectator Screen in your project.



This document provides an Overview of the Virtual Reality Spectator Screen in Unreal Engine 4.

Collaborative Viewer

You can use the Collab Viewer template as a starting point for your project. The template contains networking functionality so multiple people can join together in a shared experience of the same 3D content. This page describes what functionality is included in the Collab Viewer template and how to use it.

Next Steps

After making your XR project a shared experience, follow these guides to add more functionality to your project and to improve its performance.



Add user input to your AR and VR projects in Unreal Engine



Design user interfaces for XR experiences in Unreal Engine



Tools and strategies for profiling your XR projects in Unreal Engine

ARPins are a fixed real-world location in augmented reality (AR) to which you can attach virtual content within Unreal Engine. From this page, you can access all ARPin documentation.



Learn how to set a fixed real-world location in AR to which you can attach virtual content within Unreal Engine



With ARPin, you can mark a fixed real-world location in AR to which you can attach virtual content within Unreal Engine

ARPins

Step 1 - Adding and Saving ARPins

Setting Up the Spawn Actor Function

Adding the Pin Component

Step 2 - Removing ARPins

Step 3 - Loading ARPins

Step 4 - On Your Own

This Quick Start guide will walk you through how to set a fixed real-world location in AR to which you can attach virtual content in Unreal. In this example, we will use the HoloLens as our platform.

By following this guide, you will know how to:

Save ARPins locally on device.

Delete local ARPins.

Load local ARPins.

Before getting started, make sure your project is set up for AR. See Setting Up a New AR Project before continuing.

ARPin Local Storage only works with certain platforms. As of 5.1, the Windows Mixed Reality plugin and some OpenXR extension plugins, such as the Microsoft OpenXR plugin, are supported. See ARPin documentation for more information on platform support.

Step 1 - Adding and Saving ARPins

Follow these steps to spawn a virtual object in 3D space and save its data with ARPin. First, you need to set up the SpawnActor Function and then connect it to a Pin Component to pin the object to a specific location.

This guide uses the location of the user's hand provided by the HoloLens platform as the spawn locationTo be able to access the Motion Controller information on HoloLens, follow these steps:

Add the component Motion Controller to ARPawn in the Blueprint Editor.



In the Details panel, set the Motion Source to the Right hand in order to match the hand that's placing the pins.



Setting Up the Spawn Actor Function

Follow these steps to set up the Spawn Actor function. This section uses a custom Blueprint Actor called Pin Object for the virtual content.

Double-click the project's Pawn to open it in the Blueprint Editor.

Add the following functions by right-clicking in the Event Graph tab of the Blueprint Editor and searching for the names:

Is ARPin Local Store Supported

Is ARPin Local Store Ready





Click image to expand.



Use the boolean return values from the two functions as input to an AND logic node. Connect the result of the AND node to a Branch node. This setup makes sure both scenarios are true before executing any ARPin functions.



From the Branch node, add the SpawnActor from Class function. Then, set the node's Class parameter to Pin Object.

Add a Make Transform function to specify the local transform where the object will be spawned relative to the spawn position. Keep the default values for the local space because the world transform will be specified later.





Click image to expand.



For details on how to add input actions to your project, see Input for general input actions.

Adding the Pin Component

Follow these steps to pin the object that was spawned in the previous section. The SpawnActor from Class function returns an Object. However, the Pin Component function expects a Scene Component. In order to pin the object, grab the object's RootComponent, which is a Scene Component that defines the object's transformation.

Add the function Pin Component.

Drag the Return Value pin from the SpawnActor node and select Get Root Component.





Click image to expand.



Right-click in the Event Graph and search for the variable that holds the location where you want to pin the object. In order to spawn where your hand is on HoloLens, search for Get Motion Controller. Add it to the graph.

Pass the variable in as a Target to the function GetWorldTransform. Then, pass the Return Value of the function to the Pin to World Transform input of the Pin Component node. The world transform defines the world space location the component pins to.





Click image to expand.



Add the function Save ARPin to Local Store and pass the ARPin Object Reference, which is returned by Pin Component to the In Pin input for the Save ARPin to Local Store node. Make sure each pin has a unique save name. Then, convert the world transform to a String to set the save name.





Click image to expand.



Run the app on your AR device. When you perform the Select (R) action, the pin object appears and the ARPin Local Store adds an entry for the ARPin.



For HoloLens, you can view all the pins that are saved locally in the Windows Developer Portal.

Step 2 - Removing ARPins

Follow the steps below to remove ARPins from the local storage and destroy the virtual content associated with them.

Call Get All Pins and add a For Each Loop node to iterate through the returned array of ARPins.





Click image to expand.



Add the function Remove Pin to stop updating the pinned component.





Click image to expand.



Add the function Destroy Actor to remove the virtual pin object. Call Get Pinned Component and Get Owner to get the Actor from the ARPin and its pinned Scene Component.





Click image to expand.



Add the function Remove All ARPins from Local Store to remove all the saved pins from the local store after iterating through all the ARPins and destroying their pinned components.





Click image to expand.



Run the app on your AR device. When you perform the Select (L) action, the pin object disappears and the ARPin Local Store removes the entry for the ARPin.



Step 3 - Loading ARPins

Follow these steps to load all ARPins saved on the device in a previous session of the app and spawn the virtual content again for the ARPins.

Call Load ARPins from Local Store to access all the ARPins that are saved locally on device.





Click image to expand.



Load ARPins from Local Store returns a map of ARPin names. In order to iterate through the items in the map, convert the map to an array by using the Values function. To access every item in the array, add a For Each Loop node.





Click image to expand.



In the loop body, call SpawnActor from Class with a default Make Transform function. Use the default values for the transform unless you want to offset the object from where it's going to be spawned.





Click image to expand.



Convert the returned object to a Scene Component with Get Root Component and pass to Pin Component to ARPin.





Click image to expand.



Run the app on your AR device and create a few ARPins. Restart the app and see all the pins you created previously appear in the same place when the app starts.



To differentiate the loaded pins from newly created pins, a different material for the object was used.

Step 4 - On Your Own

In this guide, you created ARPins that are stored locally on the device. To create pins that are stored using a cloud computing service such as Azure and can be shared between multiple devices and platforms, see Microsoft's documentation for Azure Spatial Anchors in Unreal Engine.

ARPin Local Storage Quick Start

Storing ARPin Data

Storing ARPins Locally

Storing ARPins in the Cloud

Azure Spatial Anchors

Cloud Anchors with ARCore

Geo Anchors with ARKit

ARPins are a fixed real-world location in augmented reality (AR) to which you can attach virtual content within Unreal Engine. The ARPin API is the same across all platforms, but each platform has its own implementation for the ARPin data. If the underlying platform supports tracking real world locations or real world geometry, this functionality improves the stability of the ARPin locations so they stay locked to the corresponding real world position or geometry.



Storing ARPin Data

In addition to the virtual content being locked to a specific position or geometry, some platforms also support storing the location data locally or in the cloud. Being able to store the location data means that virtual content can appear consistent between app sessions and, with some implementations, multi-user experiences.

The following table describes which AR platforms support storing ARPin data locally or with Microsoft Azure cloud services.

Platform

ARPin Platform Implementation

ARPin Persistence Platform Implementation

Support for ARPin Local Storage functions?

Support for Azure Spatial Anchors?

ARCore

Anchor

Cloud Anchor

No

Yes

ARKit

ARAnchor

ARGeoAnchor

No

Yes

HoloLens

Spatial Anchor

Azure Spatial Anchors

Yes, using either of the following plugins:

Windows Mixed Reality

Microsoft OpenXR



Yes, using either of the following plugins:

Azure Spatial Anchors for WMR

Microsoft OpenXR



Magic Leap

PersistentCoordinateFrame (PCF)

PersistentCoordinateFrame (PCF)

Yes, with the Magic Leap ARPin functions.

No

Storing ARPins Locally

By storing the data locally on the AR device, content can persist between app sessions. For details on how to add ARPin functionality to your project, see the ARPin Quick Start.

Storing ARPins in the Cloud

You can store ARPins in the cloud through Azure Spatial Anchors, Cloud Anchors with ARCore, and Geo Anchors with ARKit.

Azure Spatial Anchors

Storing data in the cloud means the virtual content and real-world locations can be shared at any point in time between multiple devices and platforms. Azure Spatial Anchors is a cloud implementation included as a plugin in Unreal Engine for storing and retrieving ARPin data using Microsoft Azure. Azure Spatial Anchors are supported on multiple AR platforms including:

Windows Mixed Reality (HoloLens)

Android devices that support ARCore

iOS devices that support ARKit

Azure Spatial Anchors requires an Azure account to use.

In order to use Azure Spatial Anchors in your project, enable the Azure Spatial Anchors plugin and the Azure Spatial Anchors plugin specific to your platform.

]



Click image to expand.



For more on how to use Azure Spatial Anchors in your project, see Microsoft's documentation on Azure Spatial Anchors in Unreal Engine.

Cloud Anchors with ARCore

In addition to being able to use Azure Spatial Anchors on ARCore-supported devices, Google's platform implementation for ARPin in the cloud, Cloud Anchors, is exposed in Unreal Engine through the UGoogleARCoreServicesFunctionLibrary.

To use the API:

Create a cloud ARPin from an existing ARPin by calling UGoogleARCoreServicesFunctionLibrary::CreateAndHostCloudARPin().

When the cloud ARPin is created, access its cloud ID--the uuid that is unique to the pin--by calling UCloudARPin::GetCloudID().

At any given time, you can resolve a previously created cloud ARPin with UGoogleARCoreServicesFunctionLibrary::CreateAndResolveCloudARPin(). If the resolve is successful, the cloud ARPin will provide the pin's world transform, showing where the pin was created in the physical world.

Geo Anchors with ARKit

In addition to being able to use Azure Spatial Anchors on ARKit-supported devices, Apple's platform implementation for ARPin in the cloud, ARGeoAnchor, is exposed in Unreal Engine as a subclass of UARTrackedGeometry.

To use the API:

Query UARGeoTrackingSupport::GetGeoTrackingSupport().

Call the functions on the returned object if it's available. For example to create a new Geo Anchor, use the function UARGeoTrackingSupport::AddGeoAnchorAtLocation().

Supported Platforms

Getting Started with Spectator Screen Mode

Spectator Screen Blueprint Nodes

Switching Modes

Optimizing Spectator Screen Mode

Currently Known Issues for Version 4.17

Please refer to our PlayStation VR (PS VR) Spectator Screen documentation if you're developing for PlayStation.

If you've ever wanted to be a Virtual Reality (VR) Spectator (from a third-person perspective) while others are interacting with a VR environment (from a first-person perspective), then Unreal Engine 4's (UE4) VR Spectator Screen is the ideal feature for you. While running the VR Spectator Screen, you'll be able to observe other players with your computer monitor (or television), which is valuable when you're gathering feedback on an immersive VR experience.

Images Courtesy of GhostPaint.com





VR Spectator Screen Perspective

VR Player's HMD Perspective

On the left side, you (the spectator) are watching this artist paint a brick wall in VR, while on the right side, the artist is focusing on the painting in VR.

Depending on the Head Mounted Display (HMD) manufacturer, a VR Spectator Screen could be synonymous with a VR Social Screen; or VR Spectator Mode could be synonymous with VR Mirror Mode. Within the context of this documentation, the Spectator Screen is a standard output device (such as a computer monitor or television) that is connected to a VR device. Additionally, enabling Spectator Mode means that you can observe (or, in certain scenarios, interact) with the VR experience while a player uses a HMD in a VR environment.

Supported Platforms

The following platforms currently support Spectator Screen Mode in UE4:

HTC Vive

Oculus Rift

Steam VR

PlayStation VR (PS VR)

Although we expect this feature to be supported by other personal computing devices and consoles, we don't anticipate Mobile VR devices (platforms) to support this feature.

Getting Started with Spectator Screen Mode

With the exception of PS VR, Spectator Screen Mode is enabled by default in UE4.

When working with textures in Spectator Screen Mode, the upper left coordinate represents minimum coordinate values, while the lower right coordinate represents maximum coordinate values.



Spectator Screen Blueprint Nodes

For the Example Usage, we're using the following Blueprint interface:

Node

Description

Set Spectator Screen Texture

This node changes the texture being displayed on the Social (Spectator) Screen.

Set Spectator Screen Mode Texture Plus Eye Layout

This node sets up the layout for the TexturePlusEye function in ESpectatorScreenMode.

Set Spectator Screen Mode

This node sets the Social (Spectator) Screen mode.

Example Usage

Go ahead and set up a VR project for one of the platforms that support a Spectator Screen.

Now, you'll want to create a new Blueprint script, specifying the image that you want to render to the Spectator Screen. For illustrative purposes, the following Blueprint nodes respond to three Keyboard inputs:

For example, when the 1 key is pressed, this first Blueprint node specifies a static texture, which will be drawn in the Texture area.



When the 2 key is pressed, this second Blueprint node specifies a layout where the HMD eye view is being drawn to the entire screen (with the Texture being drawn in the upper left quadrant of the screen). Additionally, this node specifies the Texture layout while making sure to draw the Eye layout first.



The Eye and Texture rectangle minimum and maximum values are normalized between [0.0, 1.0].

Finally, when the 3 key is pressed, this third Blueprint node enables (thereby switching to) TexturePlusEye mode.



End Result

In summary, your new Blueprint sets the Spectator Screen's Texture (along with its Eye and Texture layout) along with the Spectator Screen Mode that you'd like to use.



Although the Texture can serve as a render target (which you can write to from a SceneCaptureComponent2D), or a container for User Interface elements, it's important to note that SceneCapture can be computationally expensive.

If you want to test different Textures or layouts at runtime, you can switch the Texture (or even the layout) while Spectator Screen Mode is active.

Switching Modes

If you'd like to switch to a new Spectator Screen Mode, you can open the Console and input vr.SpectatorScreenMode Value. For example, entering vr.SpectatorScreenMode 2 enables Distorted mode, which is currently supported by Oculus Rift.



Supported Modes

Depending on your platform, certain Screen Spectator Modes are supported, including the following:

Value

Mode

Oculus Rift

SteamVR

PS VR

Notes

0

Disabled

✓

✓

For the best performance on HMDs, this mode disables Spectator Screen output.

1

SingleEyeLetterboxed

✓

✓

✓

This mode is primarily intended for debugging purposes, showing only one letterboxed eye on the screen.

2

Undistorted

✓

✓

✓

This is a debug mode, showing the entire rendered area for both eyes.

3

Distorted

✓

This mode is only supported by Oculus. Specifically, this is an Oculus specific debug mode, showing chromatic abberations, etc.

4

SingleEye

✓

✓

✓

Much like the Undistorted mode, this a debug mode for only one eye. Because this mode stretches the scene, it may be useful for identifying small artifacts in the scene.

5

SingleEyeCroppedToFill

✓

✓

✓

This mode crops the eye to fill the entire screen.

6

Texture

✓

✓

✓

This mode shows a full screen view of a specified UTexture.

7

TexturePlusMirror

✓

✓

✓

This mode shows a Texture in one render rectangle, whereas, the eye is shown in another render rectangle.

Optimizing Spectator Screen Mode

Currently, there is no standard optimization setting for Spectator Screen mode. If you'd like to implement your own optimization solution for Spectator Screen mode, it's recommended to perform scene captures at 30 fps (assuming your VR application is running at 60, 90, or 120 fps). Additionally, it's recommended to limit the Spectator Screen output to 30 fps. Please be aware that if you attempt to limit Spectator Screen output on certain hardware, you might run into rendering issues if the VR framerate is running at 90 fps (basically, every third frame will be dropped).

Currently Known Issues for Version 4.17

RenderTargets created at runtime are not assigned as the Spectator Texture until one frame has passed, thereby silently failing until the application's first frame has already been rendered.

Currently, if a RenderTarget is destroyed (released) while being assigned as the Spectator Texture, the application might crash.



This node sets the Social (Spectator) Screen mode.

Inputs

Pin Location

Name

Description



(In) Exec

Input execution pin.



Mode

The Social (Spectator) Screen Mode.

Output

Pin Location

Name

Description



(Out) Exec

Output execution pin.



This node sets up the layout for the TexturePlusEye function in ESpectatorScreenMode.

Inputs

Pin Location

Name

Description



(In) Exec

Input execution pin.



Eye Rect Min

0.0 and 1.0



Eye Rect Max

0.0 and 1.0



Texture Rect Min

0.0 and 1.0



Texture Rect Max

0.0 and 1.0



Draw Eye First

If this flag is set to True, the Eye is drawn before the Texture; however, if this flag is set to false, the Texture will be drawn before the Eye.



Clear Black

If this flag is set to True, the Render Target will be drawn black before either rectangle is drawn.

Output

Pin Location

Name

Description



(Out) Exec

Output execution pin.



This node changes the texture being displayed on the Social (Spectator) Screen.

Inputs

Pin Location

Name

Description



(In) Exec

Input execution pin.



In Texture

A reference to the new Texture (2D) Object.

Output

Pin Location

Name

Description



(Out) Exec

Output execution pin.

Because of the hardware requirements of virtual reality, as well as the stronger impact poor performance can have on your users' comfort, maintaining good VR project performance is key. Unreal Engine 4 contains a suite of tools that allow you to view the performance of your project on both the CPU and the GPU. By interpreting those results, and then applying best content and gameplay code practices, you can provide the best possible experience with your project.

XR Performance Features

VR Performance Testing

VR Profiling Tools

VR Profiling Interpretations and Considerations

Variable Rate Shading and Fixed Foveated Rendering

Project Settings

Console Variables

Known Limitations

Instanced Stereo

Multiview Support for Mobile

Forward Rendering

Performance Profiling

Post Process Settings

Due to the demanding rendering requirements XR requires a number of performance optimizations and new rendering modes that are specific to XR have been introduced to Unreal Engine (UE). In the following document we will take a look at these features and how to use them in your UE XR projects.

Variable Rate Shading and Fixed Foveated Rendering

Variable Rate Shading (VRS) is a feature supported on newer GPUs that provides various methods for adjusting the shading rate of pixels in a render target (or targets). The default shading rate in any setup is 1:1, where 1 pixel-shader invocation applies to 1 target pixel on the screen. With VRS, you can specify alternate shading rates, specifically 1x2, 2x1, 2x2, 2x4, 4x2, and 4x4. For example, for 2x2 shading rate, you would see a single pixel shader invocation for a group of 2x2 pixels (4 pixels), and for 4x4 you'd see a single pixel-shader invocation for a 4x4 group (16 pixels).

Shading rate can be applied either on a per-material basis, or via a shading rate image attachment (via Tier 2 VRS).

Fixed Foveated Rendering is a technique which can make use of image-based VRS in VR headsets to adjust the shading rate for a target, reducing the shading rate towards the periphery of the view. Due to optical distortion, the GPU ends up throwing away increasing amounts of pixel detail towards the edge of the image, so by applying a VRS image that reduces shading rate further out from the image center, you can improve performance with little perceptual degradation in image quality.

Fixed-foveation uses an attachment generated via compute shader:



The center (black) areas on both sides correspond to the center of each stereo view; darker areas are higher shading rate, with black being full (1x1, 1 pixel-shader invocation per pixel), dark red at half-rate in both x and y (2x2, 1 pixel shader invocation per 4 pixels), and lighter red quarter rate (4x4, 1 pixel shader invocation per 16 pixels).

Initial results with VRS attachments applied to the base pass and transparency passes show significant promise. Currently this is still proof of concept, and it could be applied elsewhere other than base and transparency passes.

Project Settings

To access VRS settings, from the main menu, go to Edit > Project Settings. Then, in the Project Settings window, go to Engine > Rendering > VR.



Console Variables

You can use the following console variables:

Variable

Description

r.vrs.Enable

Enable or disable VRS across the engine (material-based VRS and any active image-based VRS).

r.VRS.EnableImage

Enable or disable image-based VRS only. Per-material VRS will still function if it is enabled and supported.

vr.VRS.HMDFixedFoveationLevel

HMD fixed foveated rendering quality and performance setting.

vr.VRS.HMDFixedFoveationDynamic

Enable or disable whether fixed-foveation level should adjust based on GPU utilization.

Known Limitations

Only available on Windows devices with DirectX 12 and VRS Tier 2 support, Windows devices with Vulkan and VK_KHR_fragment_shading_rate extension support, and Oculus Quest.

Not compatible with NVIDIA's DLSS.

Eye-tracked foveated rendering is currently not supported.

Instanced Stereo

Instanced Stereo Rendering was introduced to help lessen the performance impact of XR in UE. The feature can be enabled by checking the Instanced Stereo option that can be found under Edit > Project Settings > Engine > Rendering > VR.



Click for full image.

After Instanced Stereo rendering has been enabled, it will require an engine restart, and shader recompile. The base pass, and early-z pass, works with static meshes, skeletal meshes, sprite particles, and mesh particles with the feature turned on (both serial and parallel rendering paths). Instanced Stereo currently works on PC (DirectX) and PS4 with support for other platforms coming after the initial 4.11 release. Here is a video showing Standard Stereo Rendering in VR, versus Instanced Stereo Rendering in VR.

Multiview Support for Mobile

Certain (supported) mobile devices can now support VR Multiview. Mobile Multiview is similar to Instanced Stereo rendering that is available to desktop PC's, and works by providing an optimized path for Stereo Rendering on the mobile device's CPU. To enable this feature, you will need to do the following:

Due to the experimental nature of this feature, it will only work on modern Mali-based GPUs. As this feature matures, and support for more mobile devices come online, this warning will be removed.

From the Main Toolbar, go to Edit > Projects Settings, to open the Editor's Project Settings.

Then, go to Engine > Rendering > VR, and look for the Mobile Multi-View option.

Enable the Mobile Multi-View option, and restart Unreal Engine for the changes to take effect.



For this feature to work, you will need your Android build settings to be setup like the following:

Make sure that Support OpenGL ES2 is enabled in the Android > Build section.

Make sure that both Mobile HDR and Instanced Stereo Rendering are disabled.

Currently, Mobile Multiview will only work with modern Mali-based GPU's.

If you package a project with this feature on, but don't have a compatible GPU, it will be disabled at runtime.

Forward Rendering



By default, Unreal Engine uses a Deferred Renderer as it provides the most versatility and grants access to more rendering features. However, there are some trade-offs in using the Deferred Renderer that might not be right for all VR experiences. Forward Rendering provides a faster baseline, with faster rendering passes, which may lead to better performance on VR platforms. Not only is Forward Rendering faster, it also provides better anti-aliasing options than the Deferred Renderer, which may lead to better visuals.

Please see the Forward Shading Renderer documentation for more information on this feature.

Performance Profiling

To track down assets that are too expensive for VR, you need to profile what your project is doing on the CPU and GPU as much as possible over the lifetime of your project.

GPU Profiling - To activate the GPU profiler, all you need to do is press CTRL + SHIFT + ,(Comma Key) together, while running your project. After the keys have been pressed, you will see a new window come up that should look similar to the image below.

CPU Profiler - Profiling what your project is doing on the CPU is a bit more involved than profiling for the GPU. To find out more on how to do this, please refer to the Performance Profiler documents.

Post Process Settings

Due to the demanding rendering requirements of VR, many of the advanced Post Processing features that are enabled by default should be disabled, or your project could suffer from performance problems. To accomplish this in your project, you will need to do the following.

Add a Post Process(PP) volume to your level if there is not one already there.

Select the PP volume, and in the Post Process Volume section, enable the Infinite Extent (Unbound) option so that the settings in the PP volume will be applied to the entire level.

![Enable unbound option for the post process volume(enable-unbound-post-process-volume.png)

Expand the Settings of the Post Process Volume, and then go through each section to disable any active PP settings by enabling that property; clicking on it, and then setting the value from the default (usually 1.0) to 0, thus disabling the feature.



When doing this, you won't need to hit every section and set all of the properties to 0. Instead, first disable the really heavy hitting features like Lens Flares, Screen Space reflections, Temporal AA, SSAO, Bloom and anything else that might have an impact on performance.

VR Profiling Interpretations and Considerations

VR Profiling Tools

Getting General Stats

Real-Time GPU Profiler

In general, maintaining VR frame rates is extremely challenging even on recommended hardware. Frame rate consistency is more important than in regular real-time rendering as dropping frames can make your experience uncomfortable for the user.

With that in mind, you need to leave yourself a buffer to ensure you can absorb frames which may run longer than average. We don't allow pipelining multiple frames due to the input/tracking latency it would introduce. This means the game thread is only one frame ahead of the render thread at all times and the GPU and render thread are in sync on the same frame. You have slightly less than 11ms of GPU time, because of the overhead of reprojection. Long frame times in the game thread due to gameplay code overhead, the render thread due to draw call overhead, or the GPU due to transform or shading overhead can cause you to miss frame time. All three need to be considered and balanced.

If you follow the console variable settings in the Best Practices guide, your render thread performance should be around where it needs to be for performance. From there, it's important to optimize your content and gameplay code to ensure that you make frame rate. On the content side, keep everything as simple as it can be.

General practices for simplifying content include the following.

Avoid dynamic lights and shadows.

Avoid heavy use of translucency.

Instance in visible batches. If one element of your instanced group is visible, the whole group will be drawn.

Make LODs for everything.

Keep material complexity and number of materials per object low.

Bake out anything that you can get away with.

Avoid large geometry that can encompass the player.

Use precomputed visibility volumes where possible.

See the Bullet Train and Showdown slide decks for examples of how Epic has produced content for virtual reality that looks more complex than it actually is. Also, be aware that most screen space tricks don't behave as you'd expect in stereo. They generally look flat or simply wrong.

Be sure to profile your work throughout the project and ensure you're always maintaining frame rate. Slowly adding complexity until you reach a tipping point is much easier to manage than trying to find areas to scale back down to meet the target performance a few days before shipping.

Reducing draw calls really comes down to two techniques. Make sure that you combine as many materials as possible and make sure to make heavy use of instanced static mesh components.Again, when instancing, remember that whatever is instanced will always be drawn in its entirety if one part is visible. This can greatly diminish the benefits of instancing in certain cases, so be sure to instance in batches where most of the objects in the batch will likely be visible or invisible from the same point.

The other thing that you may consider doing is using cull volumes to ensure that non-visible rooms are completely culled out when outside of them. Our occlusion is slightly more liberal in what it chooses to draw, and cull volumes help make this a bit more conservative in those choices. Additionally, you can toggle visibility on Actors (or entire sublevels) to get the same effect, if your content is built like that.

Another important thing to remember is that if something has an alpha of zero, it may still be drawn. So, if you don't want to render it, be sure to actually hide it to prevent it from being rendered.

Getting General Stats

Both Oculus and SteamVR provide external tools to watch the performance. It is advisable to use these to see actual frame timings with the compositor overhead.

From the UE4 side, when in the game, there are a few ways to get general stats:

Console Command

Description

stat unit

This will give you general game thread, draw thread, and GPU time, as well as overall frame timing. This is most useful for gathering whether the total frametime is where it needs to be, and what the game thread time is, but it should not be used for Draw Thread and GPU time.

startfpschart / stopfpschart

If you want to get an idea of what percentage of time is spent above 90Hz, you can run these commands. It'll capture and aggregate stats data over the window between when you started and stopped, and then dump a file that has bucketed framerate information. Note that since sometimes the game reports slightly under 90Hz when actually at 90, it's best to check the 80+ buckets to determine the actual time spent at framerate.

stat gpu

This command, added in 4.14, gives similar stats to the GPU profiler, but in a form that you can watch and monitor from in the game. Great for checking quick costs on GPU work.

Real-Time GPU Profiler

To use the new real-time GPU profiler, type stat gpu in the game or editor. The stats are cumulative and non-hierarchical, so you can see the major categories without having to dig down through a tree of events. For example, shadow projection is the sum of all the shadow projections for all lights (across all the views).



The realtime stats are particularly useful if you want to gather stats during gameplay (e.g. for graphing later). You can use the realtime display to profile features enabled on console variables or quality settings, or for in-editor optimization where you want to see the results instantly.

Stats are declared in code as float counters, e.g. DECLARE_FLOAT_COUNTER_STAT(TEXT("Postprocessing"), Stat_GPU_Postprocessing, STATGROUP_GPU);

Renderthread code blocks can be instrumented with SCOPED_GPU_STAT macros, which work similarly to SCOPED_DRAW_EVENT, e.g: SCOPED_GPU_STAT(RHICmdList, Stat_GPU_Postprocessing);

Unlike the draw events, GPU stats are cumulative. You can add multiple entries for the same stat, and these will get aggregated.

Anything not marked up explicitly should be included in the catch-all [unaccounted] stat. If that gets high, then it indicates something is not being caught in the explicit stats and more tracking macros should be added.

Oculus Performance Head-Up Display

SteamVR Frame Timing Tool

RenderDoc

This page contains information about profilng tools specifically designed for VR projects and devices. For general performance troubleshooting and information, you can use Unreal Insights to gather details about the performance of your project.

Oculus Performance Head-Up Display

Oculus Performance Head-Up Display is a tool that can be used to display performance information, whether in the editor or a packaged build. This tool will help verify the actual CPU and GPU timings, excluding any throttling done by the application. For an overview of the screens and what the values mean, refer to Oculus' documentation.

In general, you'll want to look at the graphs and values on the Application Render Timing screen. These will give you the CPU and GPU timings as the Oculus compositor sees them, and will be more accurate for Draw and GPU timings.

To use Oculus PerfHud with Unreal Engine, you will need to do the following:

First, go to C:\Program Files\Oculus\Support\oculus-diagnostics and locate the OculusDebugTool.exe.



Double - click on the OculusDebugTool.exe to open it up and set the Visible HUD to the Performance option.



Now launch your project and put your Oculus Rift HMD on and you will see the performance information related to your UE project being displayed on the Rift. To change what type of information is displayed, you will need to change what is input into the Visible HUD option like in the image below.



SteamVR Frame Timing Tool

The SteamVR Frame Timing Tool lets you see how your VR project is performing in both the Editor or in a packaged build. This tool will help verify the actual CPU and GPU timings, excluding any throttling done by the application. For an overview of how to open the tool as well as what all of the values relate to, refer to the Valve Developer Community page. Please note that there is nothing inside of UE that needs to be done in order for the SteamVR Frame Timing tools to work. All of the functionality is provided by the SteamVR Application.

RenderDoc

RenderDoc is an external tool you can also use for profiling Unreal Engine projects. To use it with Unreal Engine:

Download the latest RenderDoc.

In RenderDoc, configure it to launch your game (e.g. UE5Editor.exe, with appropriate command line arguments).

Run ToggleDrawEvents from the command line of your app to get human readable events.

Press F12 to capture a frame.

Profiler Tool Reference

GPU Profiling

VR Performance Testing

VR Profiling Tools

While profiling tools can provide data about how your project is performing in VR, there are some points to consider when interpreting those values.

Delays can appear in odd places in the GPU and CPU profilers, most often as occlusion or scene graph traversal time. If those numbers are abnormally high, it's possible that it's a false positive.

Often when profiling, you'll notice that you pop between 90 Hz and 45 Hz. The difference is accounted for because the Compositor acts much like a vsync. If you miss framerate, it delays you until the next frame entirely. So, you tend to go down in brackets of 90 / n, where n is a whole number. Because the fps reporting is an average, it won't always report as a whole number, unless the drop is sustained. If you're bouncing back and forth between making framerate and not, you may see some fraction of a jump.

If you'd like to remove this for testing, sometimes it's useful to run the game emulating stereo rendering, instead of running in the device itself. To do so:

Launch the game with -game -emulatestereo -res=2160x1200 on the commandline

Ensure vsync is off with r.vsync 0 in the console

Update the screen percentage to emulate the oversampling we have to do for VR with r.screenpercentage 137 in the console

This will emulate the GPU and CPU performance characteristics without the annoyances of the variable framerate.

It's worth explicitly noting that if you're hitting 90 frames a second most of the time, and then make a change and notice a drastic drop, you're probably falling prey to the Compositor "vsync" issue noted above. As soon as you tip over the cliff, you'll see drastic changes in numbers.

Supported XR Devices

Supported XR Platforms

ARCore

ARKit

HoloLens

Oculus

SteamVR

Windows Mixed Reality

Unreal Engine supports many XR devices for both development and content creation. This page contains links to documentation about the XR platforms and devices that you can use with Unreal Engine.

Supported XR Devices

The following XR devices have been tested and verified to work with Unreal Engine.

Device

Platform Type

Device Type

Supported SDK Version

Support Status

Notes



AR Devices



Android devices running Android 7.0 (Nougat) and later

Mobile

Handheld

ARCore 1.22

Supported, refer to Handheld AR Features for more details on the features supported.

Refer to Developing for Handheld Augmented Reality Experiences for information on how to develop for this device.

HoloLens 2

Mobile

Head-Mounted

Windows 10 May 2019 update or later

Supported

Refer to Developing for Head-Mounted Experiences with OpenXR for information on how to develop for this device.

iOS devices running iOS 11.0 and later

Mobile

Handheld

ARKit 4.0

Supported, refer to Handheld AR Features for more details on the features supported.

Refer to Developing for Handheld Augmented Reality Experiences for information on how to develop for this device.



VR Devices



ACER Windows Mixed Reality VR

Desktop

Head-Mounted

N/A

Support is minimal

Refer to Developing for Head-Mounted Experiences with OpenXR for information on how to develop for this device.

HP Reverb

Desktop

Head-Mounted

N/A

Supported

Refer to Developing for Head-Mounted Experiences with OpenXR for information on how to develop for this device.

HP Reverb 2

Desktop

Head-Mounted

N/A

Supported

Refer to Developing for Head-Mounted Experiences with OpenXR for information on how to develop for this device.

HP Windows Mixed Reality VR

Desktop

Head-Mounted

N/A

Supported

Refer to Developing for Head-Mounted Experiences with OpenXR for information on how to develop for this device.

HTC Vive

Desktop

Head-Mounted

N/A

Support is minimal

Refer to Developing for Head-Mounted Experiences with OpenXR for information on how to develop for this device.

HTC Vive Pro

Desktop

Head-Mounted

N/A

Supported

Refer to Developing for Head-Mounted Experiences with OpenXR for information on how to develop for this device.

Oculus Quest 1

Mobile

Head-Mounted

Quest SDK Android API Level 29

Supported

Refer to Developing for Oculus for information on how to develop for this device.

Oculus Quest 2

Mobile

Head-Mounted

Quest SDK Android API Level 29

Supported

Refer to Developing for Oculus for information on how to develop for this device.

Oculus Quest 1 / 2 with Link

Desktop

Head-Mounted

N/A

Supported

Refer to Developing for Oculus for information on how to develop for this device.

Oculus Rift

Desktop

Head-Mounted

N/A

Support is minimal

Refer to Developing for Oculus for information on how to develop for this device.

Oculus Rift S

Desktop

Head-Mounted

N/A

Supported

Refer to Developing for Oculus for information on how to develop for this device.

PSVR

Console

Head-Mounted

N/A

Supported

Refer to UDN or the Forums for information on how to develop for this device.

Samsung Windows Mixed Reality VR

Desktop

Head-Mounted

N/A

Support is minimal

Refer to Developing for Head-Mounted Experiences with OpenXR for information on how to develop for this device.

Valve Index

Desktop

Head-Mounted

N/A

Supported

Refer to Developing for Head-Mounted Experiences with OpenXR for information on how to develop for this device.

Supported XR Platforms

The following sections contain information on the XR platforms supported in Unreal Engine.

ARCore

ARCore is a handheld augmented reality platform from Google that is supported in Unreal Engine. This page describes how ARCore is supported in Unreal Engine, and how to set up your environment to develop with ARCore.



How you can develop for ARCore-supported devices in Unreal Engine

ARKit

ARKit is a handheld augmented reality platform from Apple that is supported in Unreal Engine. This page describes how ARKit is supported in Unreal Engine, and how to set up your environment to develop with ARKit.



How you can develop for ARKit-supported devices in Unreal Engine

HoloLens

HoloLens is a head-mounted augmented reality device from Microsoft that is supported in Unreal Engine through the OpenXR APIs. This page describes how HoloLens is supported in Unreal Engine, and how to set up your environment to develop with HoloLens.



How you can develop for HoloLens devices in Unreal Engine.

Oculus

Oculus is a head-mounted virtual reality platform from Meta that is supported in Unreal Engine. Oculus has both mobile and desktop VR devices, and you can develop for the platform with either the OpenXR or Oculus VR plugin. This page provides more details on how Oculus is supported in Unreal Engine, and how to set up your environment to develop with Oculus.



How you can develop for Oculus devices in Unreal Engine.

SteamVR

SteamVR is a head-mounted virtual reality platform from Valve that is supported in Unreal Engine through the OpenXR APIs. This page describes how SteamVR is supported in Unreal Engine, and how to set up your environment to develop with SteamVR.





How you can develop for SteamVR in Unreal Engine.

Windows Mixed Reality

Windows Mixed Reality is a head-mounted virtual reality platform from Microsoft that is supported in Unreal Engine through the OpenXR APIs. This page describes how Windows Mixed Reality is supported in Unreal Engine, and how to set up your environment to develop with Windows Mixed Reality.



How you can develop for Windows Mixed Reality VR devices in Unreal Engine

Developing with the ARCore APIs

Getting Started with Development

Profiling

ARCore is a handheld augmented reality platform from Google that is supported in Unreal Engine. This page describes how ARCore is supported in Unreal Engine, and how to set up your environment to develop with ARCore. Refer to Supported XR Devices for the full list of which devices and which SDK versions Unreal Engine supports.

Developing with the ARCore APIs

To develop for ARCore in Unreal Engine you must set up the following:

Updated hardware and software. Refer to Android Development Requirements.

Codeworks for Android installed.

Android version 26 or greater installed.

A supported, configured, and connected handheld Android device.

Google ARCore plugin enabled in your project.

Once you're set up for developing with ARCore, you can use the unique ARCore functionality to develop for your Android devices. Refer to Handheld AR Features for what features are supported in Unreal Engine.

Getting Started with Development

After setting up your project with the Google ARCore plugin, follow these guides to get started developing for ARCore devices.



A guide to setting up a project with the Handheld AR Template and preparing your mobile device to test it



A reference page for where key features of the Handheld AR Template are implemented and how they function



ARPins are a fixed real-world location in augmented reality (AR) to which you can attach virtual content within Unreal Engine.

Profiling

The following guides show how to profile your XR application and what to consider when you need to improve performance.

XR Performance and Profiling in Unreal Engine

Testing and Optimizing Your Content in Unreal Engine

Debugging Android Projects in Visual Studio with AGDE

Android

Handheld AR Template Quickstart

Support for Android devices is not new to the Unreal Engine; however, there are some additional requirements when working with augmented reality and Unreal. In addition to the standard Unreal Engine configuration for Android, there is an additional step of installing the ARCore app on the Android device. If you are already working with Unreal Engine and Android devices, this may be the only step that is required to start working with augmented reality and Unreal Engine.

General Prerequisites

The basic configuration of Unreal Engine and Android devices is covered in detail in the Android Game Development section of the Unreal Engine documentation.

ARCore 1.18 Prerequisites

A development machine that meets our Recommended Specifications.

Unreal Engine 4.26 or greater installed.

Codeworks for Android installed.

Android Version 26 or greater installed.

A supported, configured, and connected handheld Android device.

ARCore 1.7 Prerequisites

A development machine that meets our Recommended Specifications.

Unreal Engine 4.23 or greater installed.

Codeworks for Android installed.

Android Version 26 or greater installed.

A supported, configured, and connected handheld Android device.

ARCore 1.2 Prerequisites

A development machine that meets our Recommended Specifications.

Unreal Engine 4.20 or greater installed.

Codeworks for Android installed.

Android Version 26 or greater installed.

A supported, configured, and connected handheld Android device.

ARCore 1.1 Prerequisites

A development machine that meets our Recommended Specifications.

Unreal Engine 4.19 or greater installed.

Codeworks for Android installed.

Android Version 24 or greater installed.

A supported, configured, and connected handheld Android device.

Supported: Use the Supported Devices link to identify the current list of Android devices supported for ARCore.

Configured: Unique to augmented reality with Unreal Engine is the requirement to install the ARCore app on the device.

ARCore can be downloaded from the Google Play Store manually.

Or, if ARCore is not detected on the handheld device, the device will prompt to download ARCore from Google Play Store.

Developing with the ARKit APIs

Getting Started with Development

Profiling

Known Limitations

ARKit is a handheld augmented reality platform from Apple that is supported in Unreal Engine. This page describes how ARKit is supported in Unreal Engine, and how to set up your environment to develop with ARKit. Refer to Supported XR Devices for the full list of which devices and which SDK versions Unreal Engine supports.

Developing with the ARKit APIs

To develop for ARKit in Unreal Engine you must set up the following:

Updated hardware and software. Refer to iOS Development Requirements.

Xcode 12 or later installed.

iOS 14 or later installed

A supported, configured, and connected handheld iOS device with an A12 Bionic chip or greater.

Apple ARKit plugin enabled in your project.

Once you're set up for developing with ARKit, you can use the unique ARKit functionality to develop for your iOS devices. Refer to Handheld AR Features for what features are supported in Unreal Engine.

Getting Started with Development

After setting up your project with the Apple ARKit plugin, follow these guides to get started developing for ARKit devices.



A guide to setting up a project with the Handheld AR Template and preparing your mobile device to test it



A reference page for where key features of the Handheld AR Template are implemented and how they function



ARPins are a fixed real-world location in augmented reality (AR) to which you can attach virtual content within Unreal Engine.

Profiling

The following guides show how to profile your XR application and what to consider when you need to improve performance.

XR Performance and Profiling in Unreal Engine

Testing and Optimizing Your Content in Unreal Engine

Debugging iOS and tvOS Projects

Known Limitations

The following are known limitations of features in ARKit:

Candidate images for image detection must have unique friendly names. If multiple candidate images share the same friendly name, only the image with the first instance of the friendly name will be recognized.

General Prerequisites

Support for iOS devices is not new to the Unreal Engine. If you are already working with Unreal Engine and iOS devices, you may not require any additional configuration to start working with augmented reality and Unreal Engine.

General Prerequisites

The basic configuration of Unreal Engine and iOS devices is covered in detail in the iOS Game Development section of the Unreal Engine documentation.

Starting with Unreal Engine 4.23.1, all ARKit versions require Xcode 11 or greater.

ARKit 1.5 Prerequisites

A development machine that meets our Recommended Specifications.

Unreal Engine 4.20 or greater installed.

Xcode 9 or greater installed.

A supported, configured, and connected handheld iOS device.

ARKit 2.0 Prerequisites

A development machine that meets our Recommended Specifications.

Unreal Engine 4.20 or greater installed.

Xcode 10 or greater installed.

A supported, configured, and connected handheld iOS device.

ARKit 3.0 Prerequisites

A development machine that meets our Recommended Specifications.

Unreal Engine 4.23.1 or greater installed.

Xcode 11 or greater installed.

iOS 13 or greater installed

A supported, configured, and connected handheld iOS device with an A12 Bionic chip or greater.

ARKit 4.0 Prerequisites

A development machine that meets our Recommended Specifications.

Unreal Engine 4.26 or greater installed.

Xcode 12 or greater installed.

iOS 14 or greater installed.

A supported, configured, and connected handheld iOS device with an A12 Bionic chip or greater.



Developing with OpenXR APIs

Getting Started with Development

Profiling

HoloLens is a head-mounted augmented reality device from Microsoft that is supported in Unreal Engine through the OpenXR APIs. This page describes how HoloLens is supported in Unreal Engine, and how to set up your environment to develop with HoloLens. Refer to Supported XR Devices for the full list of supported XR devices in Unreal Engine.

Microsoft provides an emulator for developing and testing apps without a physical HoloLens device. Refer to Microsoft's documentation on Input Simulation for more details on how to use the in-editor emulation.

Currently, you can develop for HoloLens devices by using the OpenXR plugin and the Microsoft OpenXR Plugin plugin.

When you develop a project with the OpenXR plugin, your application can run on any device that supports the OpenXR APIs.

To use HoloLens specific features, such as HoloLens remoting, you need to download and install the Microsoft OpenXR plugin from the Marketplace.

The Windows Mixed Reality plugin is no longer supported and should be disabled before you start developing your HoloLens project.

Refer to the Developing with OpenXR APIs section below for more details.

Developing with OpenXR APIs

To develop for HoloLens using OpenXR in Unreal Engine you must perform the following steps:

Ensure your hardware and software are up to date. Refer to Microsoft's Installation checklist for more information

Enable Developer Mode on your HoloLens device

Install the OpenXR Runtime for HoloLens

Enable the following plugins in your Unreal Engine project:

OpenXR

HoloLens

OpenXREyeTracker

OpenXRHandTracking

OpenXRMsftHandInteraction

XRVisualization

Install the Microsoft OpenXR plugin from the Marketplace

Once you're set up for developing with OpenXR, you can use the OpenXR APIs to develop for not only HoloLens devices but any device that supports the OpenXR APIs. Refer to Developing for Head-Mounted Experiences with OpenXR for more details.

Getting Started with Development

After setting up your project, follow these guides to get started with XR development in Unreal Engine.



Set up your project and apply best practices for AR and VR devices with Unreal Engine.



Add user input to your AR and VR projects in Unreal Engine



Design user interfaces for XR experiences in Unreal Engine



Tools and strategies for profiling your XR projects in Unreal Engine

Profiling

The following guides show how to profile your XR application and what to consider when you need to improve performance.

XR Performance and Profiling in Unreal Engine

Testing and Optimizing Your Content in Unreal Engine

Microsoft's documentation on Profiling with Unreal Insights

Packaging Projects

Configure the Plugins for HoloLens

Install Supporting Files from the Epic Games Launcher

Configure the Project Settings for HoloLens Packaging

Package a Project for the HoloLens

Results

Before an Unreal project can be distributed to users, it must be properly packaged. Follow the instructions below to build a package for the HoloLens 2.

Configure the Plugins for HoloLens

Steps

In your Unreal project, make sure that the Microsoft OpenXR Plugin is enabled. See Developing for Hololens for more information about downloading and installing the Microsoft OpenXR plugin

The Windows Mixed Reality plugin is no longer supported and should be disabled before you start developing your HoloLens project.

Install Supporting Files from the Epic Games Launcher

If this is the first time that you have built a package for the HoloLens, you may need to download supporting files from the Epic Games Launcher.

Steps

Go to the Library tab in the Epic Games Launcher.

Select the pulldown arrow next to Launch, then select Options.



From the Unreal Engine Installation Options menu, select HoloLens 2 and click Apply.



Configure the Project Settings for HoloLens Packaging

Steps

Go to Edit > Project Settings > Project > Description > About and enter the following information:

Project Name: The name of your project.

Company Name: The name of your company.

Company Distinguished Name: Enter CN= followed by your company name.



Go to Project Settings > Project > Description > Settings and enable Start in VR.



Go to Project Settings > Platforms > HoloLens > Packaging > Signing Certificate and select Generate new.



You will be prompted to create a Private Key Password. For testing purposes, click None.



If you are packaging for HoloLens Emulation, go to Project Settings > Platforms > HoloLens > Holo Lens and select Build for HoloLens Emulation.



If you are packaging for the HoloLens Device, go to Project Settings > Platforms > HoloLens > Holo Lens and select Build for HoloLens Device.



Package a Project for the HoloLens

Steps

In the Editor, Select Platforms > HoloLens > Package Project .



Enter a specific destination folder for the package (or accept the default).

The packaging status is displayed in the bottom right-hand of the screen. Details of the process are available in the Output Log.



Results

Once the packaging process finishes, you should see something similar to the screenshot below in your project directory. If you accepted the default destination folder, a HoloLens directory was created during the packaging process. To deploy your app, see the instructions in the HoloLens 2 Emulator Quick Start or HoloLens 2 Device Quick Start topics.



In order to understand and use the content on this page, make sure you are familiar with the following topics:

Developing for HoloLens

1 - Verify System Requirements

2 - Required Setup

3 - Install a Package to the HoloLens 2

4 - On Your Own!



You can deploy and run an Unreal app directly on the device.

1 - Verify System Requirements

Steps

Verify that you have installed the necessary prerequisites to run the HoloLens 2. See Windows Mixed Reality Development Requirements for more information.

2 - Required Setup

Before you can deploy an Unreal application to the HoloLens, you must configure the HoloLens and become familiar with its basic operations.

For more information on initial HoloLens setup and configuration, see Get started with HoloLens.

Steps

Make sure that your HoloLens is charged.

If this is your first time launching the HoloLens, turn it on and proceed with the calibration process.

Log in with your account or create a new account.

On the HoloLens, open the Settings menu



Open Update & Security.



Open For developers.



Enable Use developer features.



Enable the Device Portal.



3 - Install a Package to the HoloLens 2

If you do not already have an app built and available for the HoloLens, see Packaging an App for the HoloLens 2 for more information on packaging an app for the HoloLens 2.

In the steps you will load two files, an *.appxbundle file and an *.appx file. The *.appxbundle file is the game's package. The *.appx file is the dependency package containing supporting files for the target architecture (arm64 or x64). The dependency package only needs to be installed a single time per device. If you have already installed the dependency file, just continue with the installation without selecting an optional package. If you reflash your device, you will lose everything that had been deployed to the device, including the dependency packages.

In your browser, enter 127.0.0.1:10080 to open the Windows Device Portal.

Ensure that your device is plugged into your PC over USB, and that IPOverUSB is installed from the Windows 10 SDK.



In the Windows Device Portal, select Views > Apps from the toolbar.



Click the Choose File button, and browse to the location of your project, such as \Unreal Projects\TestProject\Hololens.





Select the .appxbundle file to specify the package you want to install.



Select the Allow me to select optional packages option, and select Next.

The *.appx file is the dependency package and only needs to be installed a single time per device. If you have already installed the dependency file, just continue with the installation without selecting an optional package.



Select the Choose File button, and browse to the location of your project, such as \Unreal Projects\TestProject\Hololens.





Select the *.appx file for the platform you are targeting (x64 for the Emulator, arm64 for the device), and click Next.



Click the Install button.



Wait for the app to finish installing.



Once the app installation is complete, scroll through All Apps on the to find your app.



4 - On Your Own!

Try running the new Unreal app on your HoloLens.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Developing for HoloLens

1 - Verify System Requirements

2 - Install the HoloLens 2 Emulator

3 - Run the HoloLens 2 Emulator

4 - Install a Package to the HoloLens 2 Emulator

5 - On Your Own!



The HoloLens Emulator lets you test holographic applications on your PC without a physical HoloLens. The emulator uses a Hyper-V virtual machine. The human and environmental inputs that are usually read by Hololens sensors are simulated from your keyboard, mouse, or Xbox controller. Applications don't need to be modified to run on the emulator; applications don't know that they aren't running on a real HoloLens.

1 - Verify System Requirements

Steps

Verify that you have installed the necessary prerequisites to run the HoloLens 2 Emulator. See HoloLens 2 Prerequisites for more information.

2 - Install the HoloLens 2 Emulator

Steps

Download and install the HoloLens 2 Emulator.



Review the default settings and proceed, but make sure to install the Emulator, the Emulator Image, and the Visual Studio Templates.



Once the HoloLens 2 Emulator is installed, you should see a success message. Click the Close button.



If the emulator fails to install, review the HoloLens 2 Prerequisites.

3 - Run the HoloLens 2 Emulator

Steps

Run the HoloLens 2 Emulator by pressing the Windows key, typing in HoloLens, and selecting HoloLens 2 Emulator.



The HoloLens 2 Emulator loads into a separate window.

Review the HoloLens 2 Emulator controls.

Walk forward, back, left, and right: Use the W,A,S, and D keys on your keyboard, or the left stick on an Xbox controller.

Look up, down, left, and right: Click and drag the mouse, use the arrow keys on your keyboard, or the right stick on an Xbox controller.

Air tap gesture: Right-click the mouse, press the Enter key on your keyboard, or use the A button on an Xbox controller.

Bloom/System gesture: Press the Windows key or F2 key on your keyboard or press the B button on an Xbox controller.

Hand movement for scrolling: Simultaneously hold the Alt key and the right mouse button, and drag the mouse up or down, or in an Xbox controller, hold the right trigger and A button down, and move the right stick up and down.

Hand movement and orientation: Hold the Alt key and drag the mouse up or down, left or right to move the hand, or use the arrow keys and Q or E to rotate, and tilt the hand. For an Xbox controller, hold the left or right bumper, and use the left thumbstick to move the hand left, right, forward, and back, the right thumbstick to rotate it, and up or down on the Dpad to raise or lower the hand.

4 - Install a Package to the HoloLens 2 Emulator

If you do not already have an app built and available for the HoloLens 2 Emulator, see Packaging an Unreal Project for the HoloLens 2 for more information on packaging for the HoloLens 2 Emulator.

In the steps below, you will load two files, an *.appxbundle file and an *.appx file. The *.appxbundle file is the game's package. The *.appx file is the dependency package containing supporting files for the target architecture (arm64 or x64). The dependency package only needs to be installed a single time per device. If you have already installed the dependency file, just continue with the installation without selecting an optional package. If you reflash your device, you'll lose everything that had been deployed to the device, including any dependency packages.

From the right-hand menu, open the Device Portal for the HoloLens 2 Emulator.



The Windows Device Portal will open up in a browser window.



In the Windows Device Portal, select Views > Apps from the toolbar.



Click the Choose File button, and browse to the location of your project, such as \Unreal Projects\TestProject\Hololens.





Select the .appxbundle file to specify the package you want to install.



Select the Allow me to select optional packages option, and select Next.

The *.appx file is the dependency package and only needs to be installed a single time per device. If you have already installed the dependency file, just continue with the installation without selecting an optional package.



Select the Choose File button, and browse to the location of your project, such as \Unreal Projects\TestProject\Hololens.





Select the *.appx file for the platform you are targeting (x64 for the emulator, arm64 for the device), and click Next.



Click the Install button.



Wait for the app to finish installing.



Once the app installation is complete, scroll through All Apps on the Emulator to find your app.



5 - On Your Own!

Now that you have your app installed on the HoloLens 2 Emulator, try running the app to load an Unreal Project.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Developing for HoloLens

1 - Verify System Requirements

2 - Required Setup

3 - Configure HoloLens Streaming

4 - End Result

5 - On Your Own!



With HoloLens streaming, you can experience your app on the HoloLens while it runs in the Unreal Editor on your PC. The HoloLens sends eye tracking, gesture, voice, current device pose, and spatial mapping input to your PC, which then sends (or streams) rendered frames back to your HoloLens.

HoloLens streaming boosts app performance, and provides a more streamlined development workflow as you do not need to package and deploy your app before running it.

1 - Verify System Requirements

Steps

Verify that you have installed the necessary prerequisites to run the HoloLens. See OpenXR Prerequisites for more information.

2 - Required Setup

Before setting up Unreal Engine and the HoloLens for streaming, it is important that the HoloLens is initially configured, and that you are familiar with basic HoloLens operations.

For more information on initial HoloLens setup and configuration, see Get started with HoloLens.

Steps

Make sure that your HoloLens is charged.

If this is your first time launching the HoloLens, turn it on and proceed with the calibration process.

Log in with your account or create a new account.

Open the Settings menu.



Open Update & Security.



Open For developers.



Enable Use developer features.



Enable the Device Portal.



3 - Configure HoloLens Streaming

Steps

On your HoloLens, go to the Microsoft Store, then download and install the Holographic Remoting Player app.



On your HoloLens, start the Holographic Remoting Player app.



Run Remote Connection (note the IP address that appears for use in a later step).



In your Unreal project, make sure that the Microsoft OpenXR plugin is enabled (Plugins > Mixed Reality > Microsoft OpenXR). If the Microsoft OpenXR is not enabled, enable it and restart the editor when prompted.



Go to Project Settings > Platforms > Windows Mixed Reality > OpenXR Holographic Remoting.



Enable Enable Remoting for Editor and enter the IP address of your HoloLens in Remote Device IP.



In order for the HoloLens to connect to your PC, the HoloLens must be connected to the same network as your PC. If you are having trouble connecting to the HoloLens, the instructions for configuring the Device Portal for HoloLens may provide some additional guidance.

Click Connect.



4 - End Result

The Hololens should now be connected to the PC, and ready for streaming. Launch the project with VR Preview. You should see the screen go blank in the HoloLens, then the screen will show a window in the middle of your vision. This window is a mirror of the Unreal Engine Viewport window running on your PC.



5 - On Your Own!

Now that HoloLens Streaming is configured and working, try loading a new Unreal Project on your PC.

Developing with OpenXR APIs

Developing with Windows Mixed Reality APIs

Getting Started with Development

Profiling

Windows Mixed Reality is a head-mounted virtual reality platform from Microsoft that is supported in Unreal Engine through the OpenXR APIs. This page describes how Windows Mixed Reality is supported in Unreal Engine, and how to set up your environment to develop with Windows Mixed Reality. Refer to Supported XR Devices for the full list of which devices Unreal Engine supports.

To develop Unreal Engine projects for Windows Mixed Reality VR devices you should use the OpenXR plugin and the Microsoft OpenXR plugin.

Refer to the Developing with OpenXR APIs and Developing with Windows Mixed Reality APIs sections below for more details.

Developing with OpenXR APIs

To develop for Windows Mixed Reality VR devices using OpenXR in Unreal Engine you must set up the following:

Updated hardware and software. Refer to Microsoft's Installation checklist

OpenXR Runtime for Windows Mixed Reality

OpenXR plugin enabled in your project

Microsoft OpenXR plugin installed from the Marketplace and enabled

Once you're set up for developing with OpenXR, you can use the OpenXR APIs to develop for not only Windows Mixed Reality VR devices but any device that supports the OpenXR APIs. Refer to Developing for Head-Mounted Experiences with OpenXR for more details.

Developing with Windows Mixed Reality APIs

To develop for Windows Mixed Reality VR devices using Windows Mixed Reality APIs in Unreal Engine you must set up the following:

Updated hardware and software. Refer to Microsoft's Installation checklist

Windows Mixed Reality plugin enabled in your project.

Once you're set up for developing with the Windows Mixed Reality plugin, you can use the Windows Mixed Reality APIs to create experiences for your Windows Mixed Reality VR devices.

Getting Started with Development

After setting up your project with the OpenXR or Windows Mixed Reality plugin, follow these guides to get started developing for XR.



Set up your project and apply best practices for AR and VR devices with Unreal Engine.



Add user input to your AR and VR projects in Unreal Engine



Design user interfaces for XR experiences in Unreal Engine



Tools and strategies for profiling your XR projects in Unreal Engine

Profiling

The following guides show how to profile your XR application and what to consider when you need to improve performance.

XR Performance and Profiling in Unreal Engine

Testing and Optimizing Your Content in Unreal Engine

Microsoft's documentation on Profiling with Unreal Insights

Unreal Engine 5.0

Unreal Engine 4.27

Unreal Engine 4.26

Unreal Engine 4.25

Unreal Engine 4.24

Unreal Engine 4.23

Unreal Engine 4.22

Unreal Engine 4.21

In this page you'll find hardware and software development kit (SDK) requirements needed to start developing for the Windows Mixed Reality platform.

Unreal Engine 5.0

Hardware Requirements

Recommended Desktop Hardware

Microsoft's System and Hardware Requirements

Hardware and Software Specifications



Software Requirements



Desktop Operating System

Windows 10 May 2019 update or later.

Unreal Engine 4.27

Hardware Requirements

Recommended Desktop Hardware

Microsoft's System and Hardware Requirements

Hardware and Software Specifications



Software Requirements



Desktop Operating System

Windows 10 May 2019 update or later.

Unreal Engine 4.26

Hardware Requirements

Recommended Desktop Hardware

Microsoft's System and Hardware Requirements

Hardware and Software Specifications



Software Requirements



Desktop Operating System

Windows 10 May 2019 update or later.

Unreal Engine 4.25

Hardware Requirements

Recommended Desktop Hardware

See Hardware and Software Specifications.



Software Requirements



Desktop Operating System

Windows 10 October 2018 Update (Version 1809) or later.

Unreal Engine 4.24

Hardware Requirements

Recommended Desktop Hardware

See Hardware and Software Specifications.



Software Requirements



Desktop Operating System

Windows 10 October 2018 Update (Version 1809) or later.

Unreal Engine 4.23

Hardware Requirements

Recommended Desktop Hardware

See Hardware and Software Specifications.



Software Requirements



Desktop Operating System

Windows 10 October 2018 Update (Version 1809) or later.

Unreal Engine 4.22

Hardware Requirements

Recommended Desktop Hardware

See Hardware and Software Specifications.



Software Requirements



Desktop Operating System

Windows 10 October 2018 Update (Version 1809) or later.

Unreal Engine 4.21

Hardware Requirements

Recommended Desktop Hardware

See Hardware and Software Specifications.



Software Requirements



Desktop Operating System

Windows 10 Fall Creators Update or later.

Getting Started

Guides

Reference

Sample Content

Images courtesy of McLaren

With Pixel Streaming, you run a packaged Unreal Engine application on a desktop PC or a server in the cloud, along with a small stack of web services that are included with the Unreal Engine. People connect using any modern Web browser on their platform of choice, whether desktop or mobile, and stream the rendered frames and audio from the Unreal Engine application. There's no need for users to install or download anything. It's just like streaming a video from YouTube or Netflix — except that users can also interact with the application using keyboard, mouse, touch input, and even custom HTML5 UI that you create in your player Web page.

Getting Started



Describes the components that make up the Pixel Streaming system and how they work together at a high level.



Get up and running streaming an Unreal Engine application from one computer to other computers and mobile devices on the same network.

Guides



Advanced networking configuration and other considerations for hosting the Pixel Streaming system.



How to customize the web page that plays back streamed video and audio, and how to exchange events between the page and the UE5 application.



Editor streaming is an experimental feature that leverages the power of Pixel Streaming to allow users to stream and interact with the Unreal Engine editor remotely. Additionally, there is now a new toolbar specifically for Pixel Streaming functions within the editor.



New and exciting features in Pixel Streaming that are still in development, but ready for play!



The Pixel Streaming servers and web frontend are now externally hosted on GitHub, consisting of the Signalling Server, Matchmaker and SFU. This is often referred to as the "Pixel Streaming Infrastructure"



Information about how quality, latency, and resiliency are achieved in Pixel Streaming while additionally giving guidance about cases where optimizing for either image quality, latency, or resiliency is more important than a balanced stream.



Ways your Unreal Engine application can interact with the Pixel Streaming system at runtime.

Reference



Supported browsers, networking ports, and configuration options for the components of the Pixel Streaming system.

Sample Content



The Pixel Streaming Demo showcase demonstrates how you can design Unreal Engine content for viewers to experience as a live stream in a Web browser or mobile device.

Benefits

Architecture

Components

Connection Process

People typically experience your Unreal Engine application on the same device that runs the gameplay logic and renders the game world to the screen, regardless of whether you build for a desktop platform, mobile OS, or console. Multiplayer networked games may distribute parts of the gameplay logic among multiple instances of the application, but each individual instance still does the work of rendering the game world locally for its own player. Even when you use the HTML5 deployment option to create a version of your Project that can run inside a Web browser, the game logic and rendering still happens locally within each user's Web browser.

With Pixel Streaming, however, you run your Unreal Engine application remotely, on a computer that users probably never see. For example, this could be a physical desktop somewhere inside your organization, or a virtual machine provided by a cloud hosting service. The Unreal Engine uses the resources available to that computer — CPU, GPU, memory, and so on — to run the game logic and render every frame. It continuously encodes this rendered output into a media stream, which passes through a lightweight stack of Web services. Users can then view that broadcast stream in standard Web browsers running on other computers and mobile devices.



The result for the user is just like watching a video stream from a service like YouTube or Netflix, except for two things:

Instead of playing back a pre-recorded video clip, the stream is playing back the rendered frames and audio generated by the Unreal Engine in real time.

Users can control the experience from their browsers, sending keyboard, mouse, and touch events, plus custom events emitted from the player Web page, back to the Unreal Engine.

Benefits

Using the Pixel Streaming system offers several possible benefits:

It makes mobile devices and lightweight Web browsers capable of displaying better quality graphics than otherwise possible. They can show complex scenes at high resolutions, using rendering features that are only possible when rendering in a native desktop application with a powerful GPU.

The user doesn't need to download large executables or content files in advance, and doesn't need to install anything. The only thing the user needs to download is the media stream as it plays.

You can support multiple platforms without creating and distributing multiple separate packages. You package your application once for Windows or Linux, and people can use any platform to experience your content. Users can view the stream in any modern browser that supports the WebRTC connection model, which includes Google Chrome and Mozilla Firefox on desktop, iOS, and Android platforms. (See the Pixel Streaming Reference.)

The Pixel Streaming system contains a minimal number of components that are relatively easy for anyone to set up inside a local network. However, it's powerful enough for teams with experience in deploying web services to use as a basis for creating custom cloud-hosted platforms.

Pixel Streaming uses the WebRTC peer-to-peer communication framework for the lowest possible latency between the user and the Unreal Engine application.

Architecture

The following image summarizes the components of a simple Pixel Streaming setup:



Components

Pixel Streaming Plugin - This Plugin runs inside the Unreal Engine. It encodes the final results of every rendered frame using video compression, packs those video frames along with the game audio into a media stream, and sends that stream to one or more connected browsers over direct peer-to-peer connections.

Signalling and Web Server - The Signalling and Web Server is responsible for negotiating connections between browsers and the Pixel Streaming Plugin and for providing browsers with the HTML and JavaScript environment that plays back the media stream.

Connection Process

When you start up all the Pixel Streaming components, the Pixel Streaming Plugin running inside the Unreal Engine first establishes a connection to the Signalling and Web Server.

A client connects to the signaling server, which serves it an HTML page that contains a player widget and control code written in JavaScript.

When the user starts the stream, the signaling server negotiates the establishment of a direct connection between the client browser and the Unreal Engine application.

In order for this connection to work, the browser and the Unreal Engine application need to know each other's IP address. If both are running on the same network, they are typically visible to each other directly at their own IP addresses. However, network address translation (NAT) services running between the two endpoints may change the externally visible IP address of either party. Resolving this usually involves the use of a STUN or TURN server, which tells each component what its externally visible IP address is. For details, see the Hosting and Networking Guide.

As soon as the connection between the client and the Unreal Engine application is established, the Pixel Streaming Plugin starts streaming media directly to the browser. Input from the client is sent by the player page's JavaScript environment directly back to the Unreal Engine application.

The Signalling and Web Server maintains its connection to the browser and to the Unreal Engine application even after the media stream starts playing, so that it has the ability to handle disconnections initiated by the browser.

For step-by-step instructions on setting up the architecture shown above, see Getting Started.

Prerequisites

1 - Prepare Your Unreal Engine Application

End Result

2 - Get the Pixel Streaming Servers

3 - Start the Servers

End Result

4 - Connect!

End Result

5 - On Your Own

Follow the steps below to stream the rendered output from your Unreal Engine Project over your local network to browsers and mobile devices.

The images for the steps on this page illustrate the procedure using a Project built from the Third-Person Blueprint template. However, the same steps should work for any Unreal Engine Project.

Prerequisites

Check your OS and hardware - The Pixel Streaming Plugin can only encode video on computers running Windows and Linux operating systems, with certain specific types of GPU hardware. For details, see the Pixel Streaming Reference.

Install node.js - If you don't already have node.js installed on your computer, you'll need to download and install it.

Open network ports - Make sure you have the following network ports open for communication on your local network: 80, 8888. If you need to change these defaults, see the Pixel Streaming Reference.

Stop other web servers - If your computer is running any other Web servers, stop them for now.

IP addresses - You'll need to know the IP address of your computer if you intend to test Pixel Streaming over the internet.However it's a good idea to get started with Pixel Streaming within a LAN or VPN first, which means you can use localhost or 127.0.0.1 as your Pixel Streaming IP address. If you are trying to connect from a machine on a different network, you'll likely need to configure your signalling server to use a STUN/TURN server. See the Pixel Streaming Reference page for details on how to configure your signalling server with peerConnectionOptions that specify a STUN/TURN server.

1 - Prepare Your Unreal Engine Application

In this step, you will create a standalone executable file for your Project.

The Pixel Streaming Plugin only works when you run your Project as a packaged application, or when you launch it from the Unreal Editor using the Standalone Game option.

In order for the Pixel Streaming Plugin to extract and stream audio from your application, you need to start the Unreal Engine with a special command-line flag: -AudioMixer. The procedure below shows how to set this up for both scenarios.

Open your Project in the Unreal Editor.

From the main menu in the Unreal Editor, select Edit > Plugins.

Under the Graphics category, find the Pixel Streaming Plugin and check its Enabled box.

Click Restart Now to restart your Project and apply the change.

Back in the Unreal Editor, choose Edit > Project Settings from the main menu.

If your Project involves a character, and you want to enable input from touch devices such as phones and tablets to move that character around the Level, you may want to show the on-screen touch controllers.Under the Engine > Input category, find and enable the Always Show Touch Interface setting. This is optional, and not required for all Projects. However, for Projects like the Third-Person Template, this makes sure that users with touch devices can control the streamed application (as long as the Project's Player Controller supports touch input).

From the main menu, choose Edit > Editor Preferences...

Under the Level Editor > Play category, find the Additional Launch Parameters setting, and set its value to -AudioMixer -PixelStreamingIP=localhost -PixelStreamingPort=8888.

Package your Project for Windows. From the main menu in the Unreal Editor, choose Files > Package Project > Windows (64-bit).

Browse to the folder on your computer where you want the Unreal Editor to place the packaged version of your Project, and click Select Folder.

The Unreal Editor begins the packaging process.

When the packaging process is finished, go to the folder that you selected in step 6 above. You'll find a folder called Windows with contents similar to the following:

Every time you start your packaged application, you need to pass it the same command-line flags set in step 8 above. One way to do this is to set up a shortcut:

Press Alt and drag your .exe file to create a new shortcut in the same folder (or anywhere else you like on your computer).

Right-click the shortcut and choose Properties from the context menu.

On the Shortcut tab of the Shortcut Properties window, append the text -AudioMixer -PixelStreamingIP=localhost -PixelStreamingPort=8888 at the end of the Target field, and click OK.

Once you've gotten the Pixel Streaming system up and running, you may also want to add the -RenderOffScreen command-line parameter. If your Unreal Engine application window ever gets accidentally minimized, the Pixel Streaming video and input streams will stop working. -RenderOffScreen avoids this possibility by running the application in a headless mode without any visible window.

End Result

You now have a packaged, standalone Unreal Engine application that has the Pixel Streaming Plugin enabled, ready to stream its rendered frames and audio.

2 - Get the Pixel Streaming Servers

Recent changes to Pixel Streaming have moved the front end and web server elements of Pixel Streaming to an external repository. We refer to this as the Pixel Streaming Infrastructure.

There are a few ways to access the Pixel Streaming infrastructure.

Directly access the github repository as found here: https://github.com/EpicGames/PixelStreamingInfrastructure

Use git clone --branch UE5.1 https://github.com/EpicGames/PixelStreamingInfrastructure.git in your preferred terminal (make sure you have git installed).

Navigate to \Engine\Plugins\Media\PixelStreaming\Resources\WebServers and run the get_ps_servers command (make sure to use the .bat script for Windows and .sh script for Linux accordingly). This will automatically pull the relevant branch of the Pixel Streaming infrastructure into that folder.

The git command mentioned above will pull the 5.1 branch of the infrastructure. If you need a different branch, please modify the git command accordingly.

For more information about the Pixel Streaming front end and webserver changes, see Pixel Streaming Infrastructure

3 - Start the Servers

In this step, you will start the web services that will help to establish peer-to-peer connections between your Unreal Engine application and clients' browsers. If you have not done the previous step, you will not have access to these servers.

The following steps assume you are using Windows. However, Linux is the same process except that you run the scripts in the SignallingWebServer\platform_scripts\bash folder instead.

In the location you pulled the Pixel Streaming Infrastructure, find the location of the Signalling Server under the folder SignallingWebServer.





To prepare for the Signalling Server, start by opening PowerShell as Administrator and running SignallingWebServer\platform_scripts\cmd\setup.ps1. This will install all the required dependencies.

Start the Signalling Server by running SignallingWebServer\platform_scripts\cmd\Start_SignallingServer.ps1. When the server has started and is ready to accept connections, you'll see the following lines in the console window:

Now, start the Unreal Engine application from the shortcut that you created in the previous section. Or, if you prefer to launch your application from the command line, execute the following command:

For convenience, when you package your Unreal Engine application, these servers are also copied to the folder that contains your packaged executable. You'll find them under the Engine sub-folder, at the same paths indicated above. You can launch the servers from there instead of launching them from your Unreal Engine installation folder.However, remember that if you need to modify any files in these folders, particularly the player page or configuration file for the Signalling and Web Server, you should modify them in the original location. If you modify them in your package folder, your changes may be overwritten the next time you package your application.

End Result

When the Unreal Engine application connects to the Signalling and Web Server, you should see the following line of output in the console window opened by the Signalling and Web Server:

Streamer connected: ::1

This means that you now have the Unreal Engine application running with the Pixel Streaming Plugin enabled, and the front-end Signalling and Web Server is ready to route connecting clients to the Unreal Engine application.

If necessary, you can stop and restart the Unreal Engine application and the Signalling and Web Server independently. As long as they're both running at the same time, they should be able to reconnect automatically.

At this point, you have everything you need set up and working on your computer. All that's left is to connect a browser.

4 - Connect!

In this step, you'll connect Web browsers running on multiple different devices to your Pixel Streaming broadcast.

On the same computer that is running your Unreal Engine application, Alt-Tab to switch the focus away from the Unreal Engine application, and start a supported Web browser (Google Chrome and Mozilla Firefox are safe choices).

In the address bar, navigate to http://127.0.0.1. This IP address of the local machine, so the request should be served by the Signalling Server:

Click the page to connect, then click again on the Play button to start the stream.

You'll now be connected to your application, and you should see the rendered output streaming into the middle of the player Web page: The default player page is already set up to forward keyboard, mouse, and touchscreen input to the Unreal Engine, so you can control the application and navigate around exactly the way you would if you were controlling the app directly.

Click the Add (+) button at the left of the window to expand some built-in options for controlling the stream:

Setting

Description

Enlarge Display to Fill Window

Determines whether the media player should resize to fit the current size of the browser window, or whether it should remain at a fixed size and position.

Is Quality Controller?

Makes the encoder of the Pixel Streaming Plugin use the current browser connection to determine the bandwidth available, and therefore the quality of the stream encoding.Although Pixel Streaming adapts the quality of the stream to match the available bandwidth, the video frames are only encoded once by the Pixel Streaming Plugin. That one encoding is used for all clients. Therefore, only one client connection can "own" the quality used for adaptive streaming. If the other clients have a much better connection to the server, they may end up seeing a lower quality stream than necessary. On the other hand, if other clients have a much worse connection to the server, they may end up with lag or jitter.By default, each time a new browser connects, it adopts the ownership of the stream. Use this checkbox from any other connected browser to retake ownership.

Match Viewport Resolution

Visualizes statistics about the connection between the browser and the Unreal Engine application.

Offer to Receive

The browser will start the WebRTC handshake instead of the Unreal Engine application. This is an advanced setting for people customising the front end.

Prefer SFU

Will attempt to use the Selective Forwarding Unit, will only work if you have one running.

Use Microphone

Will start receiving audio input from your microphone and play it back through the stream. This currently only works locally.

Force Mono Audio

Will start sending all audio as mono instead of stereo.

Force TURN

Will attempt to connect exclusively via the TURN server. Will not work without an active TURN server.

Control Scheme

Will dictate if the stream captures your mouse or keeps it free.

Hide Browser Cursor

Will toggle visibility of your cursor while it's over the stream. Useful if you are using a custom cursor in your project.

Show FPS

Will display the current FPS

Request Keyframe

Will ask the stream for a keyframe. This is helpful if your stream is choppy and needs to catch up.

Encoder Settings

Allows you to specify a min and max QP. Lower numbers mean higher quality, but higher bitrate. Max value is 51. -1 will disable any hard limits.

WebRTC Settings

Allows you to specify your desired FPS that WebRTC streams, as well as a min and max bitrate. Try not to set this too high as WebRTC may start dropping frames.

Stream Settings

Currently experimental, will be used to support multiple video tracks/streams in future.

Restart Stream

Restarts the peer connection to the stream. Should be used if you change above settings to ensure they are applied.

See the contents of the player.html and app.js files under the Signalling Web Server folder to find out how these controls are implemented.

Now, find other computers and/or mobile devices in your network. Repeat the same steps, but instead of using 127.0.0.1, direct the browser to the IP address of the computer running the Unreal Engine application and the Signalling Server.

End Result

You now have one instance of the Unreal Engine running on your computer, broadcasting a media stream to multiple devices over your local network. Each connected device sees the same view of the same Level, all rendered on the same original desktop PC.

By default, all connected devices share control over the Unreal Engine application, forwarding all keyboard, mouse, and touchscreen inputs.







Desktop

iPhone

Android

5 - On Your Own

The steps above walk you through a relatively simple setup that uses a single server host and a default player page. With a little more effort, you can take the Pixel Streaming system much farther. For example:

You can completely redesign the player HTML page to meet the needs of your Project. Control who can send input to the Unreal Engine application, and even create HTML5 UI elements on the page that emit custom gameplay events to the Unreal Engine.For details, see Customizing the Player Web Page. For a working example, see the Pixel Streaming Demo available in the Learn tab of the Epic Games Launcher.

If you need to provide pixel streaming services over the open Internet, or across subnets, you will likely need to do some more advanced network configuration. Or, you may prefer to have each connecting client stream content from a separate instance of the Unreal Engine, or through a separate player page that offers different controls.For details on topics like these, see the Hosting and Networking Guide.

Each component of the Pixel Streaming system has a number of configuration properties that you can use to control encoding resolution, screen size, IP addresses and communication ports, and more.For information on all these properties and how to set them, see the Pixel Streaming Reference.

To check out new experimental features in Pixel Streaming, see the Experimental Pixel Streaming Features page.

The Stream Tuning Guide page can help provide extra control over your stream quality and settings.

STUN and TURN Servers

Multiple Player Endpoints

Multiple Full Stacks with Matchmaking

Scaling on Demand

What is the SFU?

When to Use an SFU

SFU Configuration

Host Machine Hardware Capabilities

Even without prior experience developing or deploying web services, you should be able to get the Pixel Streaming setup described in the Overview and Getting Started pages to work within a simple local area network. However, if you try to deploy your service over more complex networks or over the open Internet, or if you want to redesign the user experience and connection flow, you might need to rethink your setup.

The signalling server, web server, and matchmaker server that accompany Pixel Streaming are a reference implementation only. We do not view them as being a complete solution for all cases, rather, we encourage you to modify them for your own purposes. To this end, we provide the signalling server, web server, and matchmaker in the newly made Pixel Streaming Infrastructure(external website) so they can be freely distributed as per the Unreal Engine EULA (see Distribution and sublicensing of Examples).

For more information regarding the Pixel Streaming front end and web servers, please refer to the Pixel Streaming Infrastructure page.

STUN and TURN Servers

In order for the Signaling and Web Server to be able to negotiate a direct connection between the Unreal Engine application and the browser, each party needs to send the other its own IP address. The browser needs to be able to access the IP address sent by the UE5 application, and vice-versa.

Within a simple local area network, each endpoint can usually assume that the other party can access it using the private IP address known to its own network card. Over the open Internet, across subnets, or when network address translation (NAT) services intervene between the browser and the UE5 application, this is not usually the case. Instead, each party needs to find out its own publicly visible IP address by querying a server that implements the STUN (Session Traversal Utilities for NAT) protocol. After the STUN server tells each endpoint its publicly visible IP address, the Signaling and Web Server can continue brokering their direct connection.



Alternatively, you can use a TURN server to relay the media stream between the UE5 application and the browser. With the TURN protocol, the TURN server connects to the UE5 application on one hand, and connects to the browser on the other hand. The UE5 application sends all of its streamed data to the TURN server, which forwards the data on to the browser. In this case, there is no direct connection between the UE5 application and the browser. (If you need to support mobile devices over wireless carrier networks, you may have no choice but to use a TURN server. Mobile networks often prevent clients from successfully connecting via the WebRTC protocol.)

The STUN and TURN protocols together, along with the ability to fall back from one server to another, make up the ICE (Interactive Connectivity Establishment) framework.

You can find several open-source implementations of STUN and TURN servers on the Internet. There are even public STUN servers that you can use for free instead of hosting your own, although you should exercise caution when using a service that you are not hosting yourself. (Because of the throughput and bandwidth involved in relaying media through the TURN protocol, public TURN services are rarely available for free.)

For convenience, the Samples/platform_scripts/ folder contains scripts to run CoTURN on Windows and Linux. CoTURN is a free and open source STUN/TURN server that is production ready. We have removed the STUN and TURN reference servers we shipped in the past as these were not production-grade.

To set up Pixel Streaming to use ICE connections, you need to set the host names of the STUN and TURN servers you want to use in the peerConnectionOptions configuration parameter for the Signaling and Web Server. For details on how to format this parameter, and how to supply it, see the Pixel Streaming Reference.

In addition, if you're hosting your own STUN or TURN server, you must make sure that the IP address and port you specify for it in the peerConnectionOptions parameter are visible on the open Internet.

Multiple Player Endpoints

You may want all users to be in the same Unreal Engine session, but not have exactly the same ability to control that session.

For example, you might want to create an experience like a presentation, where the presenter has full control over the Unreal Engine from their browser, but other users are only able to view the stream. Or, you may want to create customized sets of controls for different users, so that they can cooperate to control different aspects of the experience in real time.

For these kinds of scenarios, you can have one Unreal Engine instance running with one stack of web services, but create different player HTML pages on the Signaling and Web Server:



In this scenario, you could customize each different HTML player page and its JavaScript environment to expose only the controls you want. Then, each class of users would need to request a different URL from the Signaling and Web Server. For example, maybe the presenter loads http://yourhostname/presenter.html and other users load http://yourhostname/attendee.html.

For more details on how to customize the player page, see Customizing the Player Web Page.

Multiple Full Stacks with Matchmaking

Instead of having all users connect to the same stream, you may want each person to end up in their own interactive experiences. To do this, you can run a separate stack of Pixel Streaming components for each user, and direct each user to a separate Signaling and Web Server to start a connection.

You can set up each stack of Pixel Streaming components on a separate host, or you can put more than one stack on the same host as long as you configure the port settings for the components within each stack so that they all communicate over different ports. See the Pixel Streaming Reference for details on these port settings.

If you plan to run multiple instances of the Unreal Engine using Pixel Streaming on the same computer, note that many consumer-level graphics cards such as the NVIDIA GeForce line can only run a maximum of three encoders at the same time. Professional-grade cards such as the Quadro and Tesla do not have the same limitation.

To help set up this kind of configuration, the Pixel Streaming system can use a matchmaker server that tracks which Signaling and Web Servers are available, and whether they are being used by a client connection.



Instead of each client needing to connect to its own Signaling and Web Server URL, they first connect to the Matchmaker Server. The Matchmaker takes care of redirecting each requester to its own Signaling and Web Server, which sets up the peer-to-peer connection between the client and its UE5 application. As long as that connection is active, the Matchmaker Server will not redirect any new incoming browser connections to the same Signaling and Web Server.

The Pixel Streaming system includes a reference implementation for a Matchmaker Server, under the Samples/PixelStreaming/WebServers/Matchmaker folder. You can use this server as-is; or, you can customize the matchmaker.js file to fit your needs, as long as you handle the same messages from the Signaling and Web Server.

To set up the Matchmaker Server:

Before you start your Signalling and Web Server, start the Matchmaker Server by running its run.bat file. By default, the server listens for HTTP connections from clients on port 90, and it listens for connections from Signalling and Web Servers on port 9999. You can override those settings by providing the following configuration parameters on the command line:

Parameter

Description

--HttpPort

Defines the port the Matchmaker Server listens to for incoming HTTP connections from browsers.

--MatchmakerPort

Defines the port the Matchmaker Server listens to for incoming status messages from Signaling and Web Servers.

For example:

> node cirrus --HttpPort 88 --MatchmakerPort 9988

Set the following configuration parameters for the Signalling and Web Server:

Parameter

Description

--UseMatchmaker

Set this parameter to true to make the Signalling Web Server send its current status to the Matchmaker Server.

--MatchmakerAddress

The IP address of the Matchmaker Server that this Signalling and Web Server will connect to.

--MatchmakerPort

The port that this Signalling and Web Server will use when it needs to send messages to the Matchmaker Server. Make sure that this value matches the --MatchmakerPort value you set for the Matchmaker Server.

--PublicIp

The publicly visible IP address of the Signalling and Web Server. When the Matchmaker Server redirects a user to this Signalling and Web Server, it sends them to this IP address. Therefore, it has to be visible to the connecting browser.

--HttpPort

The port that the Signalling and Web Server listens to for HTTP connections. When the Matchmaker Server redirects a user to this Signalling and Web Server, it sends them to this port.

For instructions on how you can set these parameters, see the Pixel Streaming Reference.

Scaling on Demand

If you want to use a strategy like the one described above, where a separate full stack serves each incoming client connection, you might not want to have a preset number of Unreal Engine applications running. If you have fewer users than servers, you'll be wasting resources; conversely, if you have fewer servers than users, people may need to wait until a connection is free. Instead, you might want to spin up a new server instance each time a client tries to connect.

With the components of the Pixel Streaming system and the optional Matchmaker Server, you should have all the pieces you need to set up a dynamically scaling hosting system like this. However, for now, this level of cloud deployment is up to you to set up on your own cloud service provider.

What is the SFU?

A Selective Forwarding Unit (SFU) is a server which intelligently routes media streams between participants.In Pixel Streaming the role of the SFU is to receive stream data from the Unreal Engine application and deliver it to the recipients peers (typically connected web browsers), optionally subsetting the data to adapt to the prevailing network conditions of each recipient peer.

When using the SFU Pixel Streaming implements the simulcast strategy for adapting stream bandwidth. In the simulcast strategy, the Unreal Instance generates multiple streams at different resolutions. The SFU then selects which quality variant of the stream to transmit to the recipient based on the recipient's network conditions.

Note, at this time the SFU feature of Pixel Streaming is experimental.



When to Use an SFU

SFUs enables a one-to-many stream where there can be more peers connected than would be typically available if all the peers were connected to the Pixel Streaming application in a peer-to-peer fashion. The use of an SFU is often appropriate when your Pixel Streaming application requires multiple connected recipients and those recipients are in varying network conditions that call for different quality stream quality levels (e.g. lower bitrates, resolutions, or framerates).

SFU Configuration

Configuration of the SFU can be achieved by modifying the config.js file found in Samples/PixelStreaming/WebServers/SFU.

The SFU is configured by default to provide two quality levels. One full resolution stream and one half resolution stream. This configuration can be changed using -SimulcastParameters= (See the Pixel Streaming reference for details).

If you are create more than three simulcast streams you may hit up against limits when using the H.264 hardware encoders on consumer GPUs that often have a limit of three encoding sessions.

Host Machine Hardware Capabilities

If you choose to use a service provider such as Amazon (AWS) or Microsoft Azure to host your Unreal Engine application and Pixel Streaming web services, you may have a choice between multiple different tiers of hosts with different hardware capabilities. Keep in mind that the capabilities of the host may affect the quality of the stream that you can offer.

For example, if you opt for hosts with less powerful GPUs or less memory, you may not be able to get the maximum video quality possible in your streams.

HTML Page Requirements

Player File Location and URL

Customizing Player Input Options

Disabling User Input

Customizing the Player Widget Style

Accessing the Pixel Streaming Blueprint API

Communicating from the Player Page to UE5

Using the emitCommand Function

Using the emitUIInteraction Function

Communicating from UE5 to the Player Page

Timing Out Inactive Connections

The Pixel Streaming Signaling and Web Server provides a sample player page that is already set up to stream in media from your Unreal Engine application and to send mouse, keyboard, and touch events back to the application. (For instructions, see Getting Started.) You can use this default player page as-is, if it meets your needs.

Recent changes to Pixel Streaming have moved the front end and web server elements of Pixel Streaming to an external repository. We refer to this as the Pixel Streaming Infrastructure.

There are a few ways to access the Pixel Streaming infrastructure.

Directly access the github repository as found here: https://github.com/EpicGames/PixelStreamingInfrastructure

Use git clone --branch UE5.1 https://github.com/EpicGames/PixelStreamingInfrastructure.git in your preferred terminal (make sure you have git installed).

Navigate to \Engine\Plugins\Media\PixelStreaming\Resources\WebServers and run the get_ps_servers command (make sure to use the .bat script for Windows and .sh script for Linux accordingly). This will automatically pull the relevant branch of the Pixel Streaming infrastructure into that folder.

The git command mentioned above will pull the 5.1 branch of the infrastructure. If you need a different branch, please modify the git command accordingly.

For more information about the Pixel Streaming front end and webserver changes, see Pixel Streaming Infrastructure

However, with a little creativity and some knowledge of web technologies like JavaScript and HTML, you can take full control over the player page, creating your own custom UIs for interacting with your Unreal Engine content remotely. You can trigger and respond to gameplay events, issue console commands to control the Unreal Engine's behavior, and more.

We recommend using the default player page as a starting point for creating your own custom player page. You'll find this page at PixelStreamingInfrastructure\SignallingWebServer\Public\player.html under your Unreal Engine installation folder. Then, use the information on this page to learn how to extend your page and tie it in with your Project's gameplay logic.

Additionally, if you have cloned the Pixel Streaming Infrastructure repository and made upstream changes, you can fork the repo and make a pull request.



Default player page



Customized player with HTML5 UI

HTML Page Requirements

Your custom HTML player page must follow a few minimal requirements.

You must include the /scripts/webRtcPlayer.js file. This file handles communication between the browser and the Unreal Engine application, receiving and showing the media stream from the server. Do not modify this JavaScript file unless absolutely necessary.

We highly recommend that you also include the /scripts/app.js file as well. This file sets up event listeners that process the keyboard, mouse, and touch events. It also contains several functions and hooks that you can take advantage of in your player page, described in the sections below on this page. If you have some knowledge of JavaScript, you should feel free to dig into the code of this file and modify the default behavior to suit your needs. For example, if you want to disable keyboard inputs but leave mouse and touch events working, you will need to customize this file by finding and commenting out the code that handles keyboard events.

The page must have a div element with the ID player. This element is replaced with the video frames streamed from the UE5 application.

You must call the load function provided by the app.js file when your page loads. For example, you can do this by adding an onload handler to the body tag:

Player File Location and URL

You have a few options for where you can place your custom HTML player page, and how client browsers can access it.

You can make a folder called custom_html inside the root folder of your Signaling and Web Server, and place your custom HTML player page inside this folder. It will then be accessible by appending its filename to the IP address or hostname of the computer running the Signaling and Web Server.For example, a file named custom_html/myplayerpage.html would be accessible at http://127.0.0.1/myplayerpage.html.

You can customize the HomepageFile parameter for the Signaling and Web Server, and set the path to the filename of your custom HTML player page relative to the root folder of the Signaling and Web Server. It will then be accessible when you access the IP address or hostname of the computer running the Signaling and Web Server.For example, if you save a file to Engine/Source/Programs/PixelStreaming/WebServers/SignallingWebServer/myfolder/myplayerpage.html, and you set the HomepageFile parameter to myfolder/myplayerpage.html, the page would be accessible without needing to provide a file name in the URL: http://127.0.0.1/.

You can also use the AdditionalRoutes parameter for the Signaling and Web Server to customize the mapping between URL paths and local folders on your computer.

For additional details on these parameters, see also the Pixel Streaming Reference.

Customizing Player Input Options

The app.js file offers some JavaScript configuration parameters that you can override in your custom player page to control the way the player widget responds to user interactions. The inputOptions object exposes the following properties:

Property

Default

Description

controlScheme

ControlSchemeType.LockedMouse

Determines whether or not the player widget captures and locks the mouse when the player interacts with the widget. Accepts the following values:

ControlSchemeType.LockedMouse - When this control scheme is active, clicking on the player widget causes it to capture and lock the mouse cursor. Any further movements of the mouse are passed immediately to the input controller in the Unreal Engine application. This typically allows the user to move and rotate the camera by simply dragging the mouse. To release the cursor from the control of the player widget, the user can press the Esc key.

ControlSchemeType.HoveringMouse - When this control scheme is active, the mouse cursor hovers over the player widget without interacting with it. In order to send the mouse movements to the input controller of the Unreal Engine application, the user needs to click and hold the left button of the mouse.

suppressBrowserKeys

true

When this setting is enabled, the player widget will intercept function keys (F1 to F12) and the Tab key, and pass those keypress events through to the Unreal Engine application rather than allowing the browser to process them normally. This means, for example, that while this setting is active, pressing F5 will not refresh the player page in the browser. Instead, that event is passed through to the Unreal Engine application, and has its usual function of switching the view to visualize shader complexity.

fakeMouseWithTouches

false

When this option is enabled, and the user is viewing the stream on a device with a touch screen such as a smartphone or tablet, this setting causes single-finger touch events to be interpreted by the Unreal Engine application as mouse clicks and drag events. Enabling this setting can provide users on mobile devices with the ability to partially control your Unreal Engine application, even when the application's input controller does not specifically handle touch input events.

You can set these values in your player page by including a code block like the following. Make sure that you run this code any time after you load the app.js file into the page, but before you call its load function.

Disabling User Input

To disable user input entirely for one or more types of input device, you can override the following functions in the JavaScript environment for your player page with empty implementations:

registerHoveringMouseEvents - Disables all input mouse events when the inputOptions.controlScheme is set to ControlSchemeType.HoveringMouse.

registerLockedMouseEvents - Disables all input mouse events when the inputOptions.controlScheme is set to ControlSchemeType.LockedMouse.

registerTouchEvents - Disables touch events on mobile devices and tablets.

registerKeyboardEvents - Disables all keyboard events.

For example, you could include this block of JavaScript in your player HTML page to disable all inputs. As above, run this code any time after you load the app.js file into the page, but before you call its load function.

To keep one or more types of inputs active, comment out or remove the line that corresponds to the type of input you want to keep.

Customizing the Player Widget Style

In your custom HTML player page, you should have defined the Pixel Streaming player widget: a div element with id="player". You can use standard HTML and CSS methods to add styling to this widget.

However, the widget may occasionally need to reinitialize its size. This typically occurs when the browser window is resized (if the widget is set to automatically fill the available space), or when the resolution of the input video stream is updated. When this happens, the style attribute of the player element is overwritten with new values, which can potentially overwrite values that you have set in your own HTML or JavaScript.

To avoid this, you can set your custom CSS values in a special global variable named styleAdditional. Whenever app.js needs to resize the player and clear its style, it will append the values you set in the styleAdditional variable to the end of the new style attributes it assigns to the player element. For example, the following value changes the mouse cursor to a hand when the user hovers the mouse over the player widget:

Accessing the Pixel Streaming Blueprint API

The Pixel Streaming Plugin that runs within the Unreal Engine exposes a Blueprint API that you can use in your gameplay logic to handle custom UI events sent by the player HTML page, and to emit events from the Unreal Engine to the player page.

To access this Blueprint API, add the PixelStreamingInputComponent to an Actor in your level. Your application's PlayerController is a safe choice. You can do this by clicking Add Component in the Blueprint menu and selecting the Pixel Streaming Input component from the dropdown.



Click image to enlarge.

Prior to UE 4.27, the PixelStreamingInput Component was automatically added when you loaded the Pixel Streaming plugin. This was problematic, and now requires users to add this to their project themselves, as seen above.

Communicating from the Player Page to UE5

The app.js file provides two JavaScript functions that you can call in your HTML player page to allow the user to send events and commands from the browser to the Unreal Engine application:

You can use emitCommand to send console commands back to Unreal Engine. For example, stat fps to show the frame rate. See Using the emitCommand Function below.

emitUIInteraction sends any arbitrary string or JavaScript object to the game. Use this function to send your own custom commands from your player UI, which you can respond to in your gameplay logic to produce any effect you need in your application. See Using the emitUIInteraction Function below.

Using the emitCommand Function

When you call the emitCommand function, you must pass it a JavaScript object. This object must contain a key that matches one of the following strings:

ConsoleCommand - Use this key to execute a console command on the remote Unreal Engine application. The value of this key should be a string that contains the command you want to run, along with any parameters it needs. For example:

Due to the power of the Unreal Engine console commands, the emitCommand function can present a security risk. In order for this function to work, you also need to provide the -AllowPixelStreamingCommands parameter on the command line when you launch your Unreal Engine application or start it from the Unreal Editor using the Standalone Game option.

Using the emitUIInteraction Function

When you call the emitUIInteraction function, you can pass it a single string or JavaScript object. For example:

or

If you pass a JavaScript object, the emitUIInteraction function converts it to a JSON string internally. It then passes the resulting string back to the Pixel Streaming Plugin in your Unreal Engine application, which raises an event on the input controller. In your application's gameplay logic, you bind your own custom event to handle these inputs, using the Bind Event to OnPixelStreamingInputEvent node. For example:



Click to enlarge image.

You need to bind this event once, typically at the start of your game. Each time any player HTML page connected to an instance of your Unreal Engine application calls the emitUIInteraction`function, your custom event is automatically invoked, regardless of the input passed to emitUIInteraction`.

The custom event you assign (for example, the UI Interaction node in the image above) has an output named Descriptor, which you can use to retrieve the string that was sent to your Unreal Engine application by the emitUIInteraction function. You can use that value to determine how your gameplay code needs to respond each time emitUIInteraction is called.

For example, the following Blueprint tests to see whether the input given to emitUIInteraction contains the string "MyCustomCommand", and calls a custom function to handle the event:



Click to enlarge image.

If you originally passed a JavaScript object to emitUIInteraction, you can retrieve the value of any key from that JSON object using the Pixel Streaming > Get Json String Value node. For example, the following Blueprint tests for a key named LoadLevel. If that key is present, it calls a custom function to handle the event:



Click to enlarge image.

If you need to retrieve a nested key, use the dot notation common in JavaScript for your key. For example, PlayerCharacter.Name or PlayerCharacter.Skin.

Communicating from UE5 to the Player Page

You can make your Unreal Engine application emit custom events to all connected player HTML pages, which you can respond to in the player's JavaScript environment. This lets you change your web page UI in response to gameplay events.

To set this up:

In your Unreal Engine application, any time you want to emit an event to the player page, use the Pixel Streaming > Send Pixel Streaming Response node. Specify a custom string argument to the node to indicate to the player page what event has happened.



Click to enlarge image.

In the JavaScript of your player page, you'll need to write a custom event handler function that will be invoked each time the page receives a response event from the Unreal Engine application. It will be passed the original string argument that was sent by the Send Pixel Streaming Response node. For example:

Register your listener function by calling the addResponseEventListener function provided by app.js. You pass this function a unique name for your event listener, and your function. For example:

If you ever need to remove your event listener, call removeResponseEventListener and pass the same name. For example:

If you want to pass more complex data, you can format the string you pass to the Send Pixel Streaming Response node as JSON. For example: Then, in your JavaScript event handler function, use JSON.parse(data) to decode the string back into a JavaScript object.

Timing Out Inactive Connections

In some kinds of Pixel Streaming deployments, you may want to automatically disconnect users who have been inactive for a certain period of time. For example, if you have a limited pool of Unreal Engine applications available, with access to those instances controlled by a matchmaking server, you may need to drop inactive older connections in order to make sure that you have application instances available to handle new incoming connection requests.

You can configure your Pixel Streaming player page to detect when a user appears to be away from keyboard (AFK)—that is, when the user has not interacted with the player widget within a customizable time interval. The AFK system warns the user:



If the user continues not to respond, the AFK system ultimately disconnects their session.

Any user interaction with the player panel resets the AFK timer. This includes mouse moves and drags, mouse button presses, keyboard presses, touch events on mobile devices, and custom interactions you set up with the emitCommand and emitUIInteraction functions.

To use the AFK system, set the following three properties in the JavaScript of your player page. Do this after you load the app.js file, but before you call its load function.

Property

Description

afk.enabled

Determines whether the AFK system should check for user interactions. The default is false; set this value to true to time out inactive connections.

afk.warnTimeout

Sets the maximum time interval, in seconds, that the user can remain away from keyboard before seeing a warning overlay in the player widget. The default is 120, or two minutes.

afk.closeTimeout

After the afk.warnTimeout interval has elapsed and the user sees a warning message about being disconnected, this variable sets the time interval, in seconds, before the user's connection is automatically disconnected unless they interact with the player widget. The default is 10.

If you want to customize the content of the overlay, you can redefine the updateAfkOverlayText() function in your player page. In your implementation, set the afk.overlay.innerHTML property to the HTML that you want the player widget to display when users have been away longer than the AFK timeout value.

Pixel Streaming Toolbar

Use Remote Signalling Server

Embedded Signalling Server Options

Virtual Camera

Codecs

Editor Streaming

How do I use it?

How do I stream my editor in the cloud?

Stream Level Editor

Pixel Streaming Toolbar

The Pixel Streaming toolbar is your go to menu for controlling Pixel Streaming within the editor.



To access the Pixel Streaming toolbar, ensure you have the Pixel Streaming plugin enabled.



Toggling this option stops the editor from creating an embedded signalling server when you use the Level and Full editor streaming options. You will have to manually launch a signalling server external to the editor and specify its URL. The default values should be sufficient in most use cases however.



These values specify the ports of the embedded signalling server that's created when you use the editor streaming functions. Unless you specifically need to change these, the default values should cover most use cases.

The virtual camera is a new experimental feature added to Pixel Streaming. For more detail on how to use this feature, please refer to the Virtual Camera page.



These options will specify what encoder your stream will use. For more information about each codec as well as comparisons, please read refer to the Support Codecs page.

Editor Streaming

Editor streaming allows you to stream the Unreal Engine editor to any browsers, including mobile devices. This opens new potential for remote interaction with the editor as well as providing security benefits and enabling a new way for users to collaborate. Furthermore, eliminating the need to run the hardware locally can open up new, efficient work pipelines.

Editor streaming leverages the base Pixel Streaming module, meaning users who are familiar with Pixel Streaming their applications will feel right at home with editor streaming.

How do I use it?

Editor streaming is designed to be as easy to use as possible. To start editor streaming:

Ensure you have the Pixel Streaming plugin enabled.



Once the editor restarts, you'll notice a new "Pixel Streaming" menu on your toolbar.



Open up the menu and click "Stream Full Editor".



Voila! Your editor is now being streamed. Open a browser and navigate to your public IP (127.0.0.1 works for testing a local stream)



Open up the toolbar again and you'll notice a few IPs that you may be able to access your stream from (network configuration permitting)



The above mentioned steps will launch a signaling server that's embedded within the Unreal Engine. For users who are more familiar with a workflow in which they launch the signaling server found in the "PixelStreamingInfrastructure" repo (found here), simply check the "Use Remote Signaling Server" check box and enter the IP address of this signaling server before beginning streaming.

How do I stream my editor in the cloud?

Streaming the editor from a cloud instance can be achieved in much the same manner as streaming your regular pixel streamed applications, albeit with a few minor modifications:

If you're application launch args contains: -res=1920x1080 or similar, you'll want to replace this with -EditorPixelStreamingRes=1920x1080

If you're application launch args contains: -resx=1920 -resy=1080 or similar, you'll want to replace this with -EditorPixelStreamingResX=1920 -EditorPixelStreamingResY=1080

If you're application launch args contains: -renderoffscreen, you'll want to add -EditorPixelStreamingStartOnLaunch=true to start streaming without needing to interact with the toolbar

If you wish to use a signaling server that isn't the server embedded within the engine, you'll want to add -EditorPixelStreamingUseRemoteSignallingServer=true

An example of what your final command will look like is: Engine\Binaries\Win64\UnrealEditor-Cmd.exe -project Path\To\Your\Project.uproject -RenderOffscreen -EditorPixelStreamingRes=1920x1080 -EditorPixelStreamingStartOnLaunch=true -PixelStreamingURL=ws://127.0.0.1:8888

Editor streaming when rendering off screen is currently experimental and may be unstable.

Stream Level Editor

Alongside full editor streaming, we've also added the option to exclusively stream the level viewport of the editor. With only the level viewport streamed, connected peers will not see any surrounding elements, including but not limited to the outliner, content browser and any and all pop up menus.

To use level streaming, simply select "Stream Level Editor" from the toolbar option instead of "Stream Full Editor"



Pixel Streaming Player

Setting up your Pixel Streaming Player

VCam

How to use VCam

The below features are exciting new tools we've implemented into Pixel Streaming. Though they provide new possibilities, it's important to note that these are unstable and should be used with caution.

Pixel Streaming Player

The Pixel Streaming player allows you to display active pixel streams within your Unreal Engine project as a display within 3D space. This allows you to display cloud hosted content as a media source within local applications.

Setting up your Pixel Streaming Player

Enable the Pixel Streaming and Pixel Streaming Player plugins.

Create a new Blueprint class (actor). Save and name this anything you like.

Open the new blueprint class and add 2 components, PixelStreamingSignalling and PixelStreamingPeer.



Drag the PixelStreamingSignalling component into the event graph. From this node drag and create a "Connect" node. Connect BeginPlay to the new node and enter "ws://localhost" into the URL value.



Select the PixelStreamingSignalling component and add the; "On Config", "On Offer" and "On Ice Candidate" events from the details window. Add the "On Ice Candidate" event from the PixelStreamingPeer node as well.



From "On Config (PixelStreamingSignalling)" node, drag and create "Set Config (Pixel Streaming Peer)". Ensure the config values are connected between "Set Config" and "On Config".



From "On Offer (PixelStreamingSignalling)", drag off and create "Create Answer". Ensure the offer value is connected between "Offer" and "Create Answer". From the out node of "Create Answer", drag and create "Send Answer" node. Ensure Return Value of "Create Answer" connects to the answer value of "Send Answer".



From "Ice CandidatePixelStreamingSignalling)", Drag and create "Receive Ice Candidate" and connect the candidate values.



From "Ice Candidate(PixelStreamingPeer)", drag and create "Send Ice Candidate (PixelStreamingSignalling)" node. Connect candidate values.



If the above is done correctly, your finished blueprint should look like this:



Select the PixelStreamingPeer component in the blueprint. In the details window under Properties, you should see Pixel Streaming Video Sink. Select the drop down and choose "Pixel Streaming Media Texture". Name and save accordingly.



Drag your blueprint actor into the scene. Create a simple plane object and re-size and shape it into a suitable display.

Drag your saved Pixel Streaming media texture directly from the content browser onto the plane in the scene. This will automatically create a material and apply it to the object.

Start a basic local Pixel Stream external to this project. (Start signalling server and run application with relevant Pixel Streaming args)

Play your scene. You should now see your external Pixel Stream displayed on the plane in your scene!



VCam

VCam is a new feature that allows you to attach a VCam component to an in scene actor and stream the video content of the level viewport to an output provider.

At this stage, VCam is mostly intended for virtual production use cases. It can can be paired with the Live Link VCam iOS application and used for ARKit tracking. This is useful for piloting virtual cameras in Unreal Engine, with Pixel Streaming handling touch events and streaming the level viewport as a real time video feed back to the iOS device. For more information on Live Link VCam, please head to this site here: iOS Live Link VCam

How to use VCam

Ensure you have the Virtual Camera plugin enabled



Add the VCam component to any in scene actor (in the below example it has been attached to the Pixel Streaming player blueprint created in the guide above).



In the VCam component, navigate to "Output Providers" and add "Pixel Streaming Provider" in the drop down. Expand the new Output section.



To start and stop your stream, simply toggle the "Is Active" check box under Output.

Once started, open a local browser and navigate to "127.0.0.1" to see your streamed display, or open the Live Link iOS application and navigate to "127.0.0.1" and hit connect.



If you wish to interact with the stream through the browser, you will need to open the control panel in browser and change the Control Scheme to "Hovering"

Why?

Acquiring the Infrastructure

Download the Zip

Use Git Command

Use the Provided Scripts

Infrastructure Layout

Engine Versions

The Pixel Streaming Infrastructure contains the servers and frontend components of the Pixel Streaming plugin. It contains the scripts needed to run Pixel Streaming (the Signalling Server, Matchmaker and SFU) and is designed to be both easy to access and modify. Previously, these scripts were found in the Samples/PixelStreaming directory of your project and engine. If you want to continue using Pixel Streaming moving forward, it's recommended to use the new infrastructure as all the latest front end updates to Pixel Streaming will be made there.

Why?

We moved the Pixel Streaming front end to its own repository for a number of reasons:

To improve the release cadence of Pixel Streaming. With the infrastructure existing in its own repository, it is not bound to updates to Unreal Engine.

Encourage and allow easier contribution from Unreal Engine licensees and users.

Acquiring the Infrastructure

There are 3 different ways to acquire the Pixel Streaming infrastructure. The methods below are the most commonly used and should cover most use cases.

Download the Zip

You can directly download the infrastructure in zip format by heading to: https://github.com/EpicGames/PixelStreamingInfrastructure. Navigate to the branch of the infrastructure you need (e.g. 4.27 or 5.0) and press the green code button. You should see the option to download ZIP.

Use Git Command

If you have Git installed locally, you can acquire the infrastructure via command line, for example:

git clone --branch UE5.1 https://github.com/EpicGames/PixelStreamingInfrastructure.git in your preferred terminal (make sure you have git installed).

The git command mentioned above will pull the 5.1 branch of the infrastructure. If you need a different branch, please modify the git command accordingly.

Use the Provided Scripts

With the Pixel Streaming plugin enabled, you will find scripts to automatically pull the required branch of the infrastructure.

Navigate to \Engine\Plugins\Media\PixelStreaming\Resources\WebServers and run the get_ps_servers command (make sure to use the .bat script for Windows and .sh script for Linux accordingly). This will automatically pull the relevant branch of the Pixel Streaming infrastructure into that folder.

This method is recommended because the downloaded infrastructure will be automatically packaged with your Pixel Streaming enabled project. If you don't use this method, you can still ensure the infrastructure packages with your project by manually placing the infrastructure in the above location.

Infrastructure Layout

After pulling the infrastructure through one of the methods above, you'll end up with a local file setup as shown below. You can browse the infrastructure directly on GitHub as well.



The Pixel Streaming component locations are as follows:

Matchmaker: This file contains all the scripts required to configure and run the Matchmaker.



SFU: This file contains everything needed to configure and run the Selective Forwarding Unit.



SignallingWebServer: This is the location for your mandatory Pixel Streaming elements, such as the Signalling Server, Web Server and front end.



The platform_scripts directory is the go to location for all the scripts used to start each Pixel Streaming element. You will find scripts for Windows and Linux in cmd and bash respectively.

For information about using the Matchmaker and the Selective Forwarding Unit, refer to the Hosting and Networking Guide

For help setting up a basic Pixel Stream, refer to Getting Started with Pixel Streaming

Engine Versions

There are different branches of the Pixel Streaming Infrastructure for each different version of the engine. As the Pixel Streaming plugin has variances between each version of the engine, it's vital that you use the compatible version of the Pixel Streaming infrastructure. The available versions of the Pixel Streaming infrastructure are: 4.26, .4.27. 5.0 and 5.1. There is also a master branch available that is used for our active development. This will have the latest features, but is also experimental and is not guaranteed to be stable.

Older versions of the Pixel Streaming infrastructure (e.g. 4.26 and 4.27) are not receiving new updates/features. However we do plan to maintain them and push bug fixes as required.

WebRTC

Image Quality

WebRTC Encoder Bitrate Adaptation

Maintain Image Quality Despite Network Conditions

Latency

Achieve the Lowest Possible Latency

Resiliency

Make the Stream Resilient to Poor Network Conditions

Optimizing Your Application for Pixel Streaming

The default Pixel Streaming configuration is made to balance image quality, latency, and resiliency of the stream under the assumption that it will be deployed on the internet and consumed by users in a variety of network conditions. If this assumption matches your use case then you should not need to modify your Pixel Streaming configuration. However, Pixel Streaming is a flexible technology and can be used in many other use cases. This guide intends to inform the reader about how quality, latency, and resiliency are achieved in Pixel Streaming while additionally giving guidance about cases where optimizing for either image quality, latency, or resiliency is more important than a balanced stream.

WebRTC

The balancing of image quality, latency, and resiliency in Pixel Streaming is largely handled by a technology called WebRTC. WebRTC is widely used in video conferencing and real time streaming, examples include Facebook Messenger, Discord, Amazon Chime, and Google Stadia. WebRTC is designed to facilitate low latency, fault tolerant, multimedia and data transmission between multiple participants.

In the case of Pixel Streaming the WebRTC participants are the Unreal Engine application using the Pixel Streaming plugin and some number of WebRTC capable clients, typically web browsers. WebRTC does not have modes or predefined configurations for specific use cases, due to the wide variety of use cases it has. Instead WebRTC will try to balance quality, latency, and resiliency against network conditions and resource constraints.

However, we have exposed a number of parameters in Pixel Streaming that allow users who have specific requirements around image quality, latency, and resiliency to favor one of those.

Note that any prioritization of one of these does impact the other two, it is your decision if these tradeoffs are acceptable in your use case. In the following sections we will give guidance on how to:

Maintain image quality despite network conditions

Achieve the lowest possible latency

Make the stream resilient to poor network conditions

Image Quality

The image quality of the video stream is ultimately determined by how much compression is used when the Unreal Engine imagery is encoded before being transmitted by WebRTC. This compression occurs inside the Pixel Streaming application and by default is entirely controlled by WebRTC.

WebRTC Encoder Bitrate Adaptation

WebRTC will repeatedly determine the available network bandwidth between the Pixel Streaming application and the WebRTC client, calculate a suitable bitrate value and then update the video stream encoder with that latest bitrate estimate. The video stream encoder will then use that bitrate as an upper bound and will not produce an encoded image that exceeds that bitrate.

This system produces highly compressed images (e.g blocky and pixelated) when network conditions are poor and less compressed images when network conditions are capable of playing a high quality video stream. In other words, this system adapts the compression of the video stream based on network conditions.

Maintain Image Quality Despite Network Conditions

Answer: Use -PixelStreamingEncoderMaxQP=N (where N is an integer between 1 and 51, inclusive).

We elaborate on the meaning of QP and the tradeoff that using this parameter introduces below.

Ultimately the only factor truly determining the image quality of the video stream is the compression performed by the video stream encoder. The compression of any given frame is measured using a metric called the "quantization parameter" (QP). In Pixel Streaming the encoders we use have a QP range of 1 - 51 (inclusive), where:

1 is the best quality/least compressed encoding

51 is the worst quality/most compressed encoding

By default we do not restrict this QP range, which means the video stream encoder can select an appropriate QP based on the target bitrate that WebRTC has passed it. However, in the case where we have an application that must never produce poor imagery (e.g. a luxury product configurator) then we may wish to restrict the QP range that the encoder can use.

If MaxQP is restricted such that the bitrate produced exceeds network conditions or the -PixelStreamingWebRTCMaxBitrate then the streamed frame rate will be reduced as frames are dropped.

Pixel Streaming video encoder QP can be controlled as a launch argument using:

-PixelStreamingEncoderMinQP=

-PixelStreamingEncoderMaxQP=

Typically, MaxQP is the only parameter you will need to change to bound the image quality. The MaxQP that is suitable for your application requires some experimentation as it depends on how compressible your application visuals are (particularly in the presence of movement). However, in our experience a MaxQP of 20 is acceptable for most users that wish to put an upper bound on how much compression they are willing to accept.

Transmitted bitrate and QP can be tracked using the in-page settings"/"stats panel that Pixel Streaming ships with or by using chrome://webrtc-internals in Chromium-based browsers or about:webrtc in Firefox.

The following images illustrate the impact that QP has on image quality and bitrate:

QP impact on image quality and bitrate



We highlight that the relationship between QP and bitrate is logarithmic, meaning the change in QP, for example, between a QP of 4 and 5 represents a much larger difference in bitrate than a change in QP between 20 and 21.

Latency

Latency in Pixel Streaming is controlled by a combination of factors, some in your control, and some not. While you cannot control the end user's device hardware, the public internet, or the speed of light; there are, however, a number of other factors you can control that impact Pixel Streaming's latency. We highlight these factors in the following section.

In order to minimize latency you may wish to adjust the following factors; however, be aware that some of these adjustments may impact stream quality and resiliency.

Latency Factors

Guidance

Selected video encoder.

Do not use the experimental VP8/VP9 software encoders as these introduce more latency than the hardware accelerated H.264 encoders.

Geographic location of your application.

Host the Pixel Streaming application as geographically close to the target users as possible. This may require hosting in multiple regions.

The hardware you use to host your application.

We recommend hardware that supports hardware accelerated H.264 encoding on the GPU. Additionally, we recommend profiling your application on your target CPU to ensure usage is not at 100% as this can stall the WebRTC transmission thread.

Maximum bitrate and resolution.

Reducing resolution and maximum bitrate can reduce data transmission and encoding complexity, which makes encoding, packetization, and decoding faster. This latency reduction is usually not worth the tradeoff in quality.

Synchronization of audio and video.

If you are willing to accept audio/visual desync then you can improve latency with -PixelStreamingWebRTCDisableAudioSync which will transmit audio and video in separate streams.

Disable audio.

If you don't need audio, save bandwidth by disabling its transmission with -PixelStreamingWebRTCDisableReceiveAudio and -PixelStreamingWebRTCDisableTransmitAudio.

Disable motion blur or scene complexity.

Disabling motion blur or any effect that increases visual complexity can, in some scenes, significantly decrease encoding complexity, thus resulting in a lower bitrate.

In general, the biggest latency reductions will come from geographic proximity and the quality of the network between the Pixel Streaming application and the user.

Resiliency

In this context resiliency is how stable the stream is in the presence of packet loss, network jitter, and data corruption. WebRTC already has a number of internal, dynamically adjusted, mechanisms it uses to manage stream resiliency. For example, WebRTC can increase the size of its "jitter buffer" that it uses to store received packets to compensate for network delays and retransmissions, at the cost of increased latency. While the jitter buffer is not directly controllable, there are other factors we can control during video stream encoding to increase stream resiliency through data redundancy.

Video stream resiliency in Pixel Streaming can be increased by adjusting the following:

Resiliency Factors

Guidance

Encoder keyframe interval

Sending keyframes allows the stream and decoder to recover after heavy data loss. The interval keyframes are sent on can be controlled using -PixelStreaming.Encoder.KeyframeInterval. Note, keyframes do take more bandwidth than normal frames, so if packet loss is being incurred by network saturation sending more keyframes may not help.

Encoder intraframe refresh

Video stream recovery information can be encoded across multiple frame slices. This information makes the stream more resilient in the presence of data loss; however, this does take more bandwidth for the entire stream and introduces a scanline type artifact when stream recovery occurs. Note, this option is only available on NVIDIA GPUs at this time and can enabled in Pixel Streaming by using -NVENCIntraRefreshPeriodFrames=N and -NVENCIntraRefreshCountFrames=M (where N is how many frames before sending intraframe refresh again and M is how many frames to encode with intraframe refresh data).

Generally, stream resiliency is mostly impacted by network quality and the amount of data being transmitted. Therefore, if it is acceptable for your Pixel Streaming application to trade decreased quality for increased resiliency, then reducing the amount of data transmitted by leaving the QP range unrestricted or by reducing your application resolution are also viable options.

Optimizing Your Application for Pixel Streaming

The following are additional suggestions we have to optimize your application for Pixel Streaming:

The presence of color banding artifacts can be greatly reduced by adding a post process introducing film grain into your scene, however; bandwidth will be increased.

If you can afford extra latency and you are not supporting multiple peers per Pixel Streaming application then you may wish to experiment with the experimental VP8/VP9 software encoders using -PixelStreamingEncoder= as they produce better quality encodings for the same bitrate as the H.264 encoders.

To achieve many Pixel Streaming applications running on a single GPU (multi-tenancy) your application will have to be profiled heavily or you may have to accept a reduced frame rate/resolution.

If you intend to run your application at scale in the cloud, it will be much simpler and cheaper if your Unreal application is built for Linux due to the greater support of Linux by technologies like Kubernetes.

Freeze Frame

Communicating from UE5 to the Player Page

Responding to Pixel Streaming Events

Blueprint Events

C++ Events

When you have the Pixel Streaming system set up as described in the Quick Start guide you don't need to do anything special in the gameplay code of your Unreal Engine application to manage the system at runtime. However, the Pixel Streaming Plugin does offer some optional ways for you control and interact with the Pixel Streaming system to achieve specific effects. This page describes these additional options.

Freeze Frame

Encoding every frame rendered by the Unreal Engine application into a media stream has some downsides: it takes resources on the computer running Unreal Engine, sending all of those frames over the network uses up bandwidth, and depending on the available bandwidth the encoding may degrade the quality of the rendered images.

To minimize the use of GPU resources and network bandwidth, you may at times want to temporarily disable the Pixel Streaming Plugin from encoding and sending every frame, showing connected clients a single static image instead. For example:

If the client is not actively interacting with the application and nothing in the virtual world is moving, you may want your application to freeze on the last rendered frame until something changes.

You may want to show clients an arbitrary image, such as a loading screen or a message caption.

To allow this, the Pixel Streaming Plugin offers Blueprint nodes that you can use to pause and resume encoding. You'll find these nodes in the Pixel Streaming Freeze Frame category in the Blueprint Editor:



When you want to replace the media stream with a static image, use the Freeze Frame node.



This node accepts an optional reference to a Texture Asset. If you provide one, connected clients will see the Texture you specify in their player window. If you don't provide one, connected clients will see the last rendered frame generated by the Unreal Engine application at the time you called this node.

When you want to resume streaming every frame, use the Unfreeze Frame node.



Freezing on a single frame or image texture does not affect input coming from the browser. By default, the player page will still forward keyboard and mouse events to the Unreal Engine while frozen.

Communicating from UE5 to the Player Page

You can make your Unreal Engine application emit custom events to all connected player HTML pages, which you can respond to in the player's JavaScript environment. This lets you change your web page UI in response to gameplay events.

To set this up:

In your Unreal Engine application, any time you want to emit an event to the player page, use the Pixel Streaming > Send Pixel Streaming Response node. Specify a custom string argument to the node to indicate to the player page what event has happened.



Click to enlarge image.

Or for a more extensive example (this one sends a response to the player when they hit the 3 key):



Click to enlarge image.

In the JavaScript of your player page, you'll need to write a custom event handler function that will be invoked each time the page receives a response event from the Unreal Engine application. It will be passed the original string argument that was sent by the Send Pixel Streaming Response node. For example:

Register your listener function by calling the addResponseEventListener function provided by app.js. You pass this function a unique name for your event listener, and your function. For example:

If you ever need to remove your event listener, call removeResponseEventListener and pass the same name. For example:

If you want to pass more complex data, you can format the string you pass to the Send Pixel Streaming Response node as JSON. For example:



Responding to Pixel Streaming Events

The Pixel Streaming system offers a way for your application's gameplay code to respond to selected events that occur over the lifetime of the Pixel Streaming session. These events come in two flavors: blueprint events and native C++ events:

Blueprint Events

These delegates can be accessed through the UE5's Blueprint Editor.

Event

Description

OnConnectedToSignallingServer

Emitted when this instance of the Unreal Engine application connects to the Cirrus Signalling Server.

OnDisconnectedFromSignallingServer

Emitted when this instance of the Unreal Engine application disconnects from the Cirrus Signalling Server.

OnNewConnection

Emitted when a new client connects to the instance of the Unreal Engine application.

OnConnectionClosed

Emitted when a client that is connected to this instance of the Unreal Engine application disconnects.

On All Connections Closed

Emitted when the last client that is connected to this instance of the Unreal Engine application disconnects. After this event is emitted, there will be no clients viewing your application's media stream. You might use this as an opportunity for your gameplay logic to reset the application to an initial state in preparation for a new client to join.

OnStatChanged

Reports different pixel streaming stats in the format of FPixelStreamingPlayerId, FName, float (Player ID, stat name and stat value).

To respond to these events, you bind to them using the Pixel Streamer Delegates class. You'll typically set up this binding at the beginning of gameplay; for example, you might do this in response to the Event BeginPlay event. Once the binding is set up, your custom event will get triggered each time the bound event is triggered.

In the Blueprint Graph Editor, drag right from any node's execution pin and choose Pixel Streamer Delegates > Get Pixel Streamer Delegates.



Drag right from its Return Value and expand the Pixel Streamer Delegates category. You'll see a number of new options for binding and unbinding events.



Choose the Bind... option for the event you want to respond to, such as Bind Event to On All Connections Closed. You'll get a new node with an Event input. Connect its input execution pin to the output execution pin from Get Pixel Streamer Delegates.



If you already have a custom event that you want to trigger, connect the Output Delegate pin in its title bar to the Event input on the Bind node you just created. Otherwise, drag left from the Event input and choose Add Event > Add Custom Event to create a new custom event.



Connect your custom event to the Blueprint logic you want to run in response to the Pixel Streaming event.

For example, this implementation calls a custom function defined in the same Blueprint to reset the application to its initial state:



C++ Events

Developers can register their own handlers to these Pixel Streaming delegates. We recommend developers refer to this page https://docs.unrealengine.com/5.0/en-US/multicast-delegates-in-unreal-engine for the specific details on C++ delegate usage in Unreal Engine. A simple example of using the Pixel Streaming delegates is:

Supported Graphics Hardware

Supported Operating Systems

Supported Client Browsers

Supported Encoders

Default Network Ports

Pixel Streaming Console Commands and Launch Arguments

Required Launch Arguments

Unreal Engine Launch Arguments

Optional Console Command Launch Arguments

Pixel Streaming Plugin Configuration

Encoder Configuration

WebRTC Configuration

Signalling Server Configuration Parameters

Matchmaker Server Command-Line Parameters

SFU Server Parameters

This page describes options, settings, and command-line parameters exposed by the various parts of the Pixel Streaming system.

Supported Graphics Hardware

The computer that runs the Unreal Engine application with the Pixel Streaming Plugin must have one of the following types of graphics hardware:

NVIDIA GPU hardware that supports Hardware-Accelerated Video Encoding (NVENC). See the matrix of supported devices from NVIDIA.

AMD GPU hardware that supports the Advanced Media Framework (AMF).

If you receive the error message No compatible GPU found, or failed to load their respective encoder libraries when you try to use the Pixel Streaming Plugin, it is very likely that your GPU does not support NVENC or AMF.

Supported Operating Systems

The Pixel Streaming Plugin supports Windows and Linux platforms. OSX is not supported.

However, the Pixel Streaming Plugin and the accompanying Signalling and Web Server have only been tested on Windows 10 and Ubuntu 18.04/20.04. They have not been tested on any other operating systems, including Windows 7 or 8.

Supported Client Browsers

Pixel Streaming playback works on any modern browser that supports the WebRTC protocol. For example, it has been tested and is known to work in recent versions of the following browsers without additional configuration:

Google Chrome (desktop and mobile)

Microsoft Edge (desktop)

Mozilla Firefox (desktop and mobile)

Apple Safari (desktop and mobile)

Other browsers such as Microsoft Edge and Opera may require add-ons or plugins, and may not work on all systems.

Supported Encoders

Encoder

Acceleration

Encoding Speeds at 1080p/4K

Benefits

Quality at low bitrate

CPU/GPU usage per peer.

H.264

GPU (Nvidia or AMD)

~4.6ms/~15.5ms

Fast encoding/decoding speed. Widely supported across many devices at hardware level.

Blocky

GPU only encodes one session regardless of peer count.

VP8

CPU

~10.5/~25ms

Produces a better image quality at a lower bitrate.

Average

CPU performance scales linearly with peers.

VP9

CPU

~15ms/~50ms

Has highest image quality at lowest bitrates, compared to other encoders.

Good

CPU performance scales linearly with peers.

With a 1080p stream, as bitrate increases above 20mbps the quality of all 3 encoders would be similar. The encoding speeds listed here are estimates and were taken on an RTX 3060 and an AMD 3900X. We recommend using the H.264 codec as this is the codec we develop and test against.

Default Network Ports

The components of the Pixel Streaming system communicate using the default ports specified below. You'll need to make sure that these ports are open on the host that runs each of these components.

Component

Ports

Signalling Server host

80 - for all HTTP requests coming from clients.To change this value, set the --httpPort parameter for the Signalling Server.

443 - for all HTTPS requests coming from clients, when the Signalling Server is running in HTTPS mode.To change this value, set the --httpsPort parameter for the Signalling Server.

8888 - for all incoming connection requests from the Unreal Engine application.To change this value, set both the --streamerPort parameter for the Signalling Server and the -PixelStreamingPort parameter for the UE4 application.

Matchmaker Server host

90 - for all HTTP requests coming from clients.To change this value, use the --httpPort parameter for the Matchmaker Server.

9999 - for all messages sent by the Signalling Server.To change this value, set both the --matchmakerPort parameter for the Matchmaker Server and the --matchmakerPort parameter for the Signalling Server.

SFU Ports

8889- Opens connection between the Signalling Server and the SFU.

Pixel Streaming Console Commands and Launch Arguments

This section contains console commands and launch arguments that are useful for applications that use Pixel Streaming.

Required Launch Arguments

The following launch arguments must be specified when launching an Unreal Engine application that uses Pixel Streaming:\

Command Line Argument

Description

-PixelStreamingIP=<value> or <domain>

Specifies the IP address or domain name of the computer running the Signalling and Web Server.

-PixelStreamingPort=<value>

Specifies the port that the Signalling and Web Server is listening on for incoming communications from the Unreal Engine application. The Signalling and Web Server uses the default value of 8888.

-PixelStreamingURL=<value>

Only required if -PixelStreamingIP and -PixelStreamingPort are not present. If used replaces both -PixelStreamingIP and -PixelStreamingPort.

This must include the websocket protocol too. For example: ws://127.0.0.1:8888 or wss://127.0.0.1:8888.

A typical Pixel Streaming application launch is as follows:

Or:

Unreal Engine Launch Arguments

The following arguments are not specific to Pixel Streaming. However, many Pixel Streaming applications may find them useful, particularly in cloud deployments.

Command Line Argument

Description

-RenderOffscreen

Run the Unreal Engine application headless, without any visible rendering at all on the local computer. The application will not display any windows, and will not render in full screen. You can use this parameter in conjunction with -ForceRes to stop the Unreal Engine from automatically adjusting resolution based on the resolution of the primary display.

If you omit this parameter, the Unreal Engine application window will be rendered normally. If this application window is ever minimized, the Pixel Streaming video and input capture will stop working. We therefore recommend always including this parameter, unless you need to be able to see the rendered output from the Unreal Engine application locally on the same computer while it is running.

-ForceRes

When combined with -ResX and -ResY this will force the Unreal Engine to a specified resolution. This is useful in a cloud deployment where there typically is no display resolution.

-ResX <value>

Sets the width component of the resolution that the Unreal Engine application should launch with.

-ResY <value>

Sets the height component of the resolution that the Unreal Engine application should launch with.

-AudioMixer

Forces the Unreal Engine to use software mixing for audio, this may be required if an audio device is not present..

-Unattended

Suppresses the generation of dialog boxes in the event that an error is encountered. This is helpful when running Unreal Engine offscreen or in a container as messages boxes can hang indefinitely in those scenarios.

-StdOut and -FullStdOutLogOutput

The combination of these two flags produces the maximum logging output, which is useful when debugging or viewing live logs in an SSH terminal.

Optional Console Command Launch Arguments

You can specify the following settings at runtime as console variables or at launch as program arguments.

The system provides defaults for each setting that will be used when these settings are not specified. Most users will have no need to change these settings. In fact, many of these values are controlled by WebRTC internally and overriding them will likely result in worse performance.

Pixel Streaming Plugin Configuration

Changing the following settings will configure the Pixel Streaming Plugin.

Console Variable

Command Line Argument

Default Value

Description

PixelStreaming.HUDStats

-PixelStreamingHudStats

false

Whether to show PixelStreaming stats on the in-game HUD.

PixelStreaming.DisableLatencyTester

-PixelStreamingDisableLatencyTester

false

Disables the ability to trigger latency tests that pass through the Pixel Streaming Plugin pipeline.

PixelStreaming.KeyFilter

-PixelStreamingKeyFilter=<values>

""

A comma separated list of keys to ignore from streaming clients. For example, "W,A,S,D" might be used to filter out the default movement keys.

N/A

-AllowPixelStreamingCommands

false

Whether the user should be able to send console commands via the emitConsoleCommand javascript.

N/A

-PixelStreamingHideCursor

false

Whether to hide the UE application cursor.

-SimulcastParameters

-SimulcastParameters="[layer_list]"

-SimulcastParameters=1.0,5000000,100000000,2.0,1000000,5000000

The format of a layer is [scale_down_factor],[min_bitrate],[max_bitrate]. You should always declare at least one layer and it's recommended to have at least a scale down factor of 1. E.g. Scale down factor of 2 means half resolution.

Encoder Configuration

Changing the following settings will configure the underlying video encoders that the Pixel Streaming Plugin uses.

Console Variable

Command Line Argument

Default Value

Description

PixelStreaming.Encoder.TargetBitrate

-PixelStreamingEncoderTargetBitrate=<value>

-1

Target bitrate (bps). Setting this ignores the bitrate WebRTC wants (not recommended). Set to -1 to disable.

PixelStreaming.Encoder.MaxBitrateVBR

-PixelStreamingEncoderMaxBitrate=<value>

20000000

Max bitrate (bps).

Does not work in CBR rate control mode with NVENC.

PixelStreaming.Encoder.DumpDebugFrames

-PixelStreamingDebugDumpFrame=<value>

false

Dumps frames from the encoder to a file on disk for debugging purposes.

PixelStreaming.Encoder.MinQP

-PixelStreamingEncoderMinQP=<value>

-1

0-51, lower values result in better quality but higher bitrate. Note: -1 will disable any hard limit on a minimum QP.

PixelStreaming.Encoder.MaxQP

-PixelStreamingEncoderMaxQP=<value>

-1

0-51, lower values result in better quality but higher bitrate. Note: -1 will disable any hard limit on a maximum QP.

PixelStreaming.Encoder.RateControl

-PixelStreamingEncoderRateControl=<value>

"CBR"

PixelStreaming video encoder RateControl mode. Supported modes are "ConstQP", "VBR", "CBR". Note: CBR is the only one we recommend.

PixelStreaming.Encoder.EnableFillerData

-PixelStreamingEnableFillerData=<value>

false

Maintains constant bitrate by filling with junk data. Note: Not required with CBR and MinQP = -1.

PixelStreaming.Encoder.Multipass

-PixelStreamingEncoderMultipass=<value>

"FULL"

How many passes the encoder does per frame. See the NVENC docs for more details. Supported modes are "DISABLED", "QUARTER", "FULL"

PixelStreaming.Encoder.H264Profile

-PixelStreamingH264Profile=<value>

"BASELINE"

H264 profile used by the encoder. Supported modes are "AUTO", "BASELINE", "MAIN", "HIGH", "HIGH444", STEREO, SVC_TEMPORAL_SCALABILITY, PROGRESSIVE_HIGH, CONSTRAINED_HIGH.

Baseline is the only profile guaranteed to be supported by WebRTC capable devices on the receiving side.

WebRTC Configuration

Changing the following settings will configure the WebRTC library that the Pixel Streaming Plugin uses internally.

Console Variable

Command line argument

Default

Description

N/A

-LogCmds=PixelStreamingWebRTC <LogLevel>

Log

Specifies the log level of WebRTC. This is useful for debugging WebRTC. Helpful log levels are: Log, Verbose, VeryVerbose

PixelStreaming.WebRTC.DegradationPreference

-PixelStreamingWebRTCDegradationPreference=<value>

"MAINTAIN_FRAMERATE"

Degradation preference is WebRTC's strategy to destructively adapt the bitrate (changing resolution/dropping frames) when changing the encoder bitrate/QP is not sufficient.

PixelStreaming.WebRTC.MaxFps

-PixelStreamingWebRTCMaxFps=<value>

60

The maximum FPS WebRTC will try to capture/encode/transmit.

PixelStreaming.WebRTC.StartBitrate

-PixelStreamingWebRTCStartBitrate=<value>

10000000

Start bitrate (bps) that WebRTC will try to begin the stream with.

Value must be between Min and Max bitrates.

PixelStreaming.WebRTC.MinBitrate

-PixelStreamingWebRTCMinBitrate=<value>

100000

Minimum bitrate (bps) that WebRTC will not request below.

Be careful not to set this value too high, otherwise WebRTC will just drop frames.

PixelStreaming.WebRTC.MaxBitrate

-PixelStreamingWebRTCMaxBitrate=<value>

100000000

Maximum bitrate (bps) that WebRTC will not request above.

Be careful not to set this value too high, as a local (ideal) network will actually attempt to reach this value.

PixelStreaming.WebRTC.LowQpThreshold

-PixelStreamingWebRTCLowQpThreshold=<value>

25

Only used when PixelStreaming.Encoder.LowQP=-1. Value between 1 and 51. If WebRTC is getting frames below this QP, it will try to make an adaptation decision.

PixelStreaming.WebRTC.HighQpThreshold

-PixelStreamingWebRTCHighQpThreshold=<value>

37

Only used when PixelStreaming.Encoder.MaxQP=-1. Value between 1-51. If WebRTC is getting frames above this QP, it will try to make an adaptation decision.

PixelStreaming.WebRTC.DisableReceiveAudio

-PixelStreamingWebRTCDisableReceiveAudio

false

Disables receiving audio from the browser into UE.

If audio is not required can improve latency in some cases.

PixelStreaming.WebRTC.DisableTransmitAudio

-PixelStreamingWebRTCDisableTransmitAudio

false

Disables transmission of UE audio to the browser.

If audio is not required can improve latency in some cases.

PixelStreaming.WebRTC.DisableAudioSync

-PixelStreamingWebRTCDisableAudioSync

true

Disables the synchronization of audio and video tracks in WebRTC.

This improves latency if synchronization is not required.

Signalling Server Configuration Parameters

There are two ways you can set these parameters:

On the command line, when you start the Signalling and Web Server by running Start_SignallingServer.ps1 or node cirrus.js. In this case, prefix each parameter name with -- (two dashes), then follow it with a space, then the value you want to set. For example: --httpPort 81.

In a configuration file. By default, the Signalling and Web Server (cirrus.js) looks for a file named config.json in the same folder. In this case, set each parameter and the value you want to set for it as a key-value pair in the JSON object defined in the file. If you've already started the Signalling and Web Server at least once, see the parameters that are already listed in the /Samples/PixelStreaming/WebServers/SignallingWebServer/config.json file for an example.

Parameter

Description

--PublicIp <value>

The public IP of the computer running the Signalling and Web Server.

--HttpPort <value>

The port that the Signalling and Web Server uses for HTTP connections with client browsers.

--StreamerPort <value>

The port that the Signalling and Web Server listens to for incoming connections from the Unreal Engine application.

--peerConnectionOptions <value>

Specifies the hostnames or IP addresses of any STUN and TURN servers you want the Unreal Engine application and browser to query when they need to discover their own external IP addresses.For more information on STUN and TURN servers, see the Hosting and Networking Guide.This parameter must be a string that lists the server URLs in the order you want them to be contacted. It must have the following format:"{ \"iceServers\": [{\"urls\": [<url1>,<url2>,<url3>,...]}] }"For example:"{ \"iceServers\": [{\"urls\": [\"stun:34.250.222.95:19302\"]}] }"or"{ \"iceServers\": [{\"urls\": [\"stun:34.250.222.95:19302\",\"turn:34.250.222.95:19312\"]}] }"The TURN server implementation that ships with the Unreal Engine requires a user name and password, as follows:"{\"iceServers\":[{\"urls\":[\"stun: 34.250.222.95:19302\",\"turn: 34.250.222.95:19312\"],\"username\":\"<TURN_Username>\",\"credential\":\"<TURN_Password>\"}]}"Other STUN and TURN implemetations may have different requirements for their credentials.

The value must be formatted as a string, even if you use a JSON configuration file to provide the parameter. Always surround it in double-quotes, and use backslashes to escape any quotes inside the string, as shown above.

--HomepageFile <value>

The filename of the default page the server will provide to connecting client browsers that do not request a specific URL.The default value is player.htm.

--AdditionalRoutes <value>

Specifies additional folders that the Signalling and Web Server should serve.This parameter must be a JSON object, which means you can only provide it in the JSON configuration file, not on the command line.It must be an object in which each key is a part of a URL, and the value of each key is a local path that the server should serve to requesting clients. For example, if you set:"AdditionalRoutes" = { "/myfolder", "C:\some_local_path" }then when a client requests http://server-name/myfolder/index.html the server will provide the file named C:\some_local_path\index.html.

--LogToFile <value>

Determines whether the Signalling and Web Server writes log messages to files in the ./logs folder.The default value is true.

--UseHttps <value>

Set this parameter to true in order to make the Signalling Server accept only HTTPS connections on the httpsPort.You will also need to put your client-key.pem and client-cert.pem files into the certificates folder under the Signalling and Web Server's root folder.

--HttpsPort <value>

The port to listen to for HTTPS connections. Only used when UseHttps is enabled.The default value is 443.

--UseMatchmaker <value>

Determines whether the Signalling and Web Server sends its current status to a Matchmaker Server, in order to help client browsers find a Signalling Server and Unreal Engine application that are not currently in use.

--MatchmakerAddress <value>

The IP address of the Matchmaker Server that the Signalling and Web Server should contact.

--MatchmakerPort <value>

The port that the Matchmaker Server listens to for incoming messages from Signalling and Web Servers.

--SFUPort <value>

Opens connection between the Signalling Server and the SFU.

--ConfigFile <value>

Specifies the path and file name of the configuration file that the Signalling Server should use to retrieve the values of the properties above. Can only be set on the command line.

Matchmaker Server Command-Line Parameters

Provide these parameters on the command line when you start the Matchmaker Server by running its run.bat file, or when you start it by running node.exe matchmaker.js.

Parameter

Description

--httpPort <value>

Sets the port number that the Matchmaker listens to for HTTP connections from clients.The default value is 90.

--matchmakerPort <value>

Sets the port number that the Matchmaker listens to for incoming messages from Cirrus signalling servers.The default value is 9999.

SFU Server Parameters

Parameter

Description

--PublicIP=<value>

The public IP address that your SFU server will use.

Hardware and Software Specifications

Recommended Software for Developing on Linux

Recommended Hardware

Cross-Compile Toolchain

Native Toolchain

Version History

This page contains the software development kit (SDK) and hardware requirements needed to develop Unreal Engine (UE) projects for Linux devices.

Recommended Software for Developing on Linux

Recommended Software

Operating System

Ubuntu 22.04 (5.0.2+), Centos 7

Compiler

clang 13.0.1 (5.1), clang 15.0.1 (5.2)

IDE

Visual Studio Code, Rider

Recommended Hardware

Recommended Development Hardware

Processor

Quad-core Intel or AMD, 2.5 GHz or faster

Memory

32 GB RAM

Video Card

NVIDIA GeForce 960 GTX or Higher with latest NVIDIA binary drivers

Video RAM

8 GB or more

RHI Version

Vulkan: AMD (21.11.3+) and NVIDIA (515.48+)

Running the Engine

Operating System

Any reasonable new Linux distro from CentOS 7.x and up

Linux Kernel Version

kernel 3.x or newer

Additional Dependencies

glibc 2.17 or newer

Cross-Compile Toolchain

Cross-compiling makes it possible for game developers to target Linux from Windows. At this time, cross-compiling is only supported for Windows, and Mac users currently have to resort to Native Compiling. Additionally, we support, test, and provide libraries and toolchains for the Linux-x86_64 platform.

Why Cross-Compilation

Cross-compilation makes it possible for game developers, working in a Windows-centric workflow, to target Linux. At this time, cross-compilation is only supported for Windows. Mac users currently have to resort to native compilation. We support, test, and provide the libraries and toolchains for the Linux-x86_64 platform.

Getting the Toolchain

To download the Cross-Compilation Toolchain, refer to the download links in table in the Version History section below.

Native Toolchain

Unreal Engine's setup shell script (Setup.sh) automatically downloads a native toolchain, which guarantees your compiler and linker to work with our codebase. With the native toolchain, you compile against a fixed sysroot (glibc at the very least), so that, for example, if you compile a game on Ubuntu 18.04, you will be able to start the binary on CentOS 7.

Version History

UE Version

Recommended Operating System

Recommended IDE

Compiler

Cross-Compile Toolchain

Native Toolchain

5.2

Ubuntu 22.04, CentOS 7

Visual Studio Code, Rider

clang 15.0.1

-v21 clang-15.0.1-based

-v21 clang-15.0.1-based

5.1

Ubuntu 22.04, CentOS 7

Visual Studio Code, Rider

clang 13.0.1

-v20 clang-13.0.1-based

-v20 clang-13.0.1-based

5.0.2+

Ubuntu 22.04, CentOS 7

Visual Studio Code, Rider

clang 13.0.1

-v20 clang-13.0.1-based

-v20 clang-13.0.1-based

5.0

Ubuntu 20.04, CentOS 7

Visual Studio Code, Rider

clang 11.0.1

-v19 clang-11.0.1-based

-v19 clang-11.0.1-based

Cooking and Chunking

General Information

Chunk Downloader Plugin

Google Play Asset Delivery (GooglePAD)

Unreal Engine can divide content into .pak files and deliver them to users separately from the main executable. This functionality supports DLC and patching for live services.

General Information

The following pages contain information about the UE cooking and chunking process, how to prepare .pak files for distribution, and reference information for mounting chunks.



How to divide assets into chunks and cook them into packaging files



Creating updated content packages which allow you to update your project after release.



This page describes how to create a patch for an existing project.

Chunk Downloader Plugin

The ChunkDownloader plugin is a general patching solution intended for games that need to deliver a large number of small files.



How to set up a Project Settings and Plugins for working with ChunkDownloader



Setting up a local host web site



How to integrate ChunkDownloader into your project, using Visual Studio and Blueprints, and how to test out the system on your local machine.

Google Play Asset Delivery (GooglePAD)

The GooglePAD plugin uses Google's Play Asset Delivery system on the Google Play store. This patching solution is a companion to the Android App Bundle system, which delivers customized APKs that are optimized for users' individual devices.

You can read more about GooglePAD in the Google Play Asset Delivery Reference.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Setting Up the ChunkDownloader Plugin

Recommended Assets

Required Setup

Organizing Your Chunking Scheme

Final Result

Unreal Engine (UE) can deliver assets outside of the main executable of your applications in the form of packaging files. To do this, you need to organize your assets into chunks, groups of asset files that are recognized by the cooking process. This tutorial shows you how to organize assets into chunks in the Unreal Editor. When you have finished, you will have a sample project that will produce packaging files you can deliver with a patching system.

Recommended Assets

For this guide, the following assets are used: Crunch, Boris, and Khaimera from Paragon, which you can download from the Unreal Marketplace for free. As long as you have assets that you can safely group into separate folders, you do not need to use these specific assets. The Paragon Character Assets make a convenient test case since UE already organizes them this way.



Required Setup

Before proceeding any further, you should review the Setting Up the ChunkDownloader Plugin.

As described in reference quide, you need:

Create C++ project based on a Blank template. Name this project PatchingDemo.

Enable ChunkDownloader plugin in the Plugins menu.

Enable Use Pak File and Generate Chunks in Project Settings > Project > Packaging.

Edit your project's ProjectName]Build.cs file in Visual Studio.

Generate Visual Studio project files.

Build your project in Visual Studio.

Organizing Your Chunking Scheme

Now that you have enabled chunking and set up your plugins, you need to organize your assets and package them into chunks.

For more information about the chunking process, refer to Cooking and Chunking.

Right-click inside the ParagonBoris folder, navigate to Create Advanced Asset > Miscellaneous, then create a new Data Asset.



Choose PrimaryAssetLabel as the base class for the new Data Asset.



You can create subclasses of PrimaryAssetLabel in C++ to add extra metadata. If you create subclasses for PrimaryAssetLabel in Blueprint, they will not work for chunking purposes.

Name the new Primary Asset Label Label_Boris.



Open Label_Boris and fill in the following properties:



Property

Value

Chunk ID

This should be a unique value for each folder. Here we use 1001 for Boris.

Priority

This should be a value greater than 0. Here we set them all to 1.

Cook Rule

Set to Always Cook.

Label Assets in My Directory

Set to Enabled.

Is Runtime Label

Set to Enable

Repeat steps 1 through 4 for ParagonCrunch and ParagonKhaimera. In this example we set the ChunkID to 1002 for Crunch and 1003 for Khaimera.

Package or cook content for your project.

Final Result

If everything is set up correctly, you will see the packaging files in your build directory, under /Windows/PatchingDemo/Content/Paks, when UE has finished packaging them. UE will name each of them for the Chunk ID that you designated, and they each will contain the assets for your three characters.



You can also navigate click Tools > Audit > Asset Audit to view your chunks in the Asset Audit Window.



You can find more information about Asset Audit in Cooking and Chunking.



Different Methods for Patching

Platform-Agnostic Patching Method

Windows Patching

Once you have released your project, you will probably make updates to it after the initial release. This process is known as patching. Patching usually includes new content that addresses known issues, or that fixes vulnerabilities in the original release.

Different Methods for Patching

There are several methods for creating patches, but they all use one of two approaches. One approach keeps files from the original release or previous patches, but adds a pointer to new content. The other approach is to transform the content in the original build using a binary patch.

Note: You can build patches in Unreal Engine 4 (UE4) for many different platforms. However, we do not support distribution of patches for your project. Each platform has their own system for uploading patch files, and for distributing those patch files to users. For information on these platform-specific distribution systems, see the documentation for that platform's Software Development Kit (SDK).

Platform-Agnostic Patching Method

There is a method for creating patches in Unreal Engine 4 that will technically work on any platform. This method packages the entire build with new content, while the changes between the two builds are placed in a sidecar file that is added to the original file. The new PAK file is labeled with a "_p" suffix. For example, if the original build file is called `MyGamesStuff.pak`, your patch file would be called `MyGamesStuff_p.pak`.

Windows Patching

Windows uses the method described in Platform-Agnostic Patching Method .

For more information on platform-agnostic patching, see How to Create a Patch.

How to Create a Patch Using the Project Launcher

Create a Launch Profile for Testing the Patch

Customize the Launch Profile

Launch the Test Version of the Patch

Create and Customize a Launch Profile for Shipping the Patch

How to Create a Patch Using the Command Line

Installing a Patch



During patching, the Unreal Engine (UE) compares all the content post-cook to the originally released cooked content, and uses that to determine what is included in a patch. The smallest piece of content is a single package (like a .ulevel or .uasset), so if anything changes in a package then the entire package will be included in the patch. The method you use to get the patch's PAK (.pak) file to the users will depend on your distribution platforms, but this procedure will allow you to create a much smaller PAK file that just contains the updated content.

You can patch a project you have previously released using a versioned release. Some things to keep in mind are:

Lock down the serialization code paths at the time of release.

Keep the released cooked content, as the UnrealPak tool uses this to determine which content should be in the patch package file.

At runtime, mount both PAK files, with a higher priority for the patch file so any content within it is loaded first.

There are several methods for patching projects created in Unreal Engine. The method used here is platform-agnostic, meaning it technically can be used for any platform. However, the only two platforms that you would intentionally use this method with are Windows and Xbox One. Other platforms have specific patching methods. You can find documentation on these platform-specific methods in the section for the platform you are planning to develop for.

This method can eventually use a lot of data storage, because this method keeps all old files, and merely points the game to the newest files that exist. Platform-specific methods often use less space.

How to Create a Patch Using the Project Launcher

This example provides information about creating a patch for the UE project.

Create a Launch Profile for Testing the Patch

If you have base build of your project, you can create a Launch Profile for the patch in the Project Launcher. You might want to create one Launch Profile for creating a test version of your patch, and another Launch Profile for your actual patch release.

Open the Project Launcher, by clicking Platforms > Project Launcher.



Create a new Custom Launch Profile using the +Add button. This first Launch Profile is specifically for a test version of your patch. Type in a Name and Description that makes that clear.



There are a number of settings in the Project Launcher that you can customize for a Launch Profile. You can further customize each setting by clicking the Show Advanced and set Advance Settings using dropdown menus. You can also click the top dropdown in the Cook, Package or Deploy sections, and your selection can change the available options.



Launch Profile Section Name

Description of Advanced Settings

Project

You can browse to the specific project to use, or use Any Project to patch the current project.

Build

Options are DebugGame, Development and Shipping. Click the Advanced Settings dropdown to build the Unreal Automation Tool (UAT) as part of the patch process.

Cook

Click the dropdown to select Cook by the Book or Cook on the Fly. You can also select Do Not Cook. You can click the Advanced Settings dropdown to select Only Cook Modified Content. Additional options display for Advanced Settings, and for Release/DLC/Patching, when you select Cook by the Book.

Package

Options are Package and Store Locally, Package and Store in Repository, or Do Not Package.

Archive

If you want to archive the build, check the box in this section.

Deploy

Options are Copy to Device, Copy Repository, File Server, or Do Not Deploy.

Launch

Options are Using Default Role, Using Custom Roles, and Do Not Launch.

Customize the Launch Profile

Follow these steps to customize your new Launch Profile.

In the Project section, click the dropdown to browse to your project.



In the Build section, click the dropdown and select Shipping. Optionally, expand Advanced Settings if you need to build Unreal Automation Tool (UAT) as part of the patch process because you are creating the patch on a build machine.



In the Cook section, click the dropdown and select By the Book. This gives you options for Cooked Platforms, Cooked Cultures, and Cooked Maps. Check the Cook settings for your project.



The Cook settings determine which content in your project is cooked for this patch, and that content is then compared to the original package file.

Click the arrow to expand Release/DLC/Patching Settings.



Under Release Version This is Based On, type the release version. Then check the box for Generate Patch.



Click the arrow to expand Advanced Settings. Make sure the following boxes are checked, as well as any others you need for your specific project's distribution method.

Compress Content

Save Packages Without Versions

Store All Content in a Single File (UnrealPak)



Also in Advanced Settings, click the dropdown for Cooker Build Configuration and select Shipping.



In the Package section, click the dropdown and select Package and Store Locally. The local directory is entered by default; if you want to change it, click Browse and select the directory where you want to store the package.



In the Deploy section, click the dropdown and select Do Not Deploy.



Select Do Not Deploy to test the patch. When you have tested your patch and are ready to build a shipping version, follow the steps in this section and just choose a different Deploy method.

Launch the Test Version of the Patch

Navigate back to the main profile window using the Back button in the top right corner.



Click on the launch icon next to your Patching profile.



The project launcher will go through the building, cooking, and packaging process. This may take some time depending on the complexity of your project.



Once the operation is complete, close the window or click on Done.



Create and Customize a Launch Profile for Shipping the Patch

Create a new Custom Launch Profile using the Plus (+) button. This profile is for shipping your patch, so type a Name and Description to make that clear.

Follow steps 1-11 in the Customize the Launch Profile section. If needed, change the custom settings if your test version was significantly different from what you want to ship.

In the Deploy section, click the dropdown and select the deployment option you want to use.

When you've finished making the Shipping Launch Profile, follow the steps in the Launch the Test Version of the Patch section.

How to Create a Patch Using the Command Line

The Project Launcher is not the only option for creating a platform-agnostic patch for your project. You can also create a patch using command-line instructions with UAT.

First you need to create a base build. This is probably your shipping build. You need to use the command line parameter -Createreleaseversion=<releasenumber> when creating this build. This will create version 1.0 of your project.

Example:

This will save a build in the <ProjectPath>\Releases\1.0\ directory which will be required when generating the patch.

Once you have a numbered base build, you can create a patch that is based on that previous build. You need to use the command line parameter -basedonreleaseversion=<releasenumber> when creating this patch.

Example:

Installing a Patch

The platform-agnostic patching process creates a PAK file in following directory: [ProjectName]\Saved\StagedBuilds[PlatformName][ProjectName]\Content\Paks. Depending on the platform your project is created for, the PAK file contains the new or changed content that should be distributed to users. For example, on Windows, you would create an installer to copy that PAK file into the user's [ProjectName]\Releases[VersionNumber][PlatformName] folder, next to the original content PAK file.

The patch PAK file will automatically be mounted when it is located on the device in any of the PAK search directories set in FPakPlatformFile::GetPakFolders. To prioritize patches, the mounting system uses a _p at the end of the filename to determine that it gets priority over other PAK files. It can be renamed, but you need to include the _p.pak at the end of the file name.

If you build two patches from the same release version, they are both complete patches, so you should remove the first patch while installing the second patch.

Steps

Final Result

The ChunkDownloader patching system is a built-in plugin for Unreal Engine that provides patching functionality. This page shows how to set up Project Settings and Plugins of your Unreal Engine project for using ChunkDowloader.

This example uses C++ project based on Blank template. This project has name PatchingDemo.



Click image to enlarge.

This example uses C++ project based on Blank template. The project has name PatchingDemo.

Steps

Open your Project Settings, navigate to Project > Packaging, then make sure that Use Pak File and Generate Chunks are both enabled.



Open the Plugins window and enable the Chunk Downloader plugin. Restart the Unreal Editor for your changes to take effect.



Open your project's [ProjectName]Build.cs file in Visual Studio. This file locates under [ProjectName]/Source/[ProjectName].



Edit file by adding ChunkDownloader to your ModuleRules as PrivateDependencyModuleNames. For this add the following section to the ModuleRules in the file.

Save your changes to this file.

Right-click on your [ProjectName].uproject file and click Generate Visual Studio project files.



Return to your project's solution in Visual Studio, then Build the project.



Final Result

Now, ChunkDownloader is available to use in your project. You can proceed with implementing this in your game's code to download and mount packaging files (see Preparing Assets for Chunking).

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Setting Up the ChunkDownloader Plugin

Preparing Assets for Chunking

1. Required Setup

2. Building the Manifest File

3. Hosting Files on a Local Test Server

Final Result

The ChunkDownloader patching solution for Unreal Engine requires you to distribute packaging files to a web server and to build a Manifest File. Manifest File is a text file containing a list of all of the files the user expects to download, as well as the expected file size for each one.

When the patching process starts, the Manifest File is the first thing, that ChunkDownloader will download to the user's device. ChunkDownloader uses information from the Manifest File to request and download each of the packaging files one-by-one. The expected file size enables the system to recognize how much progress is made for each file.

1. Required Setup

This guide uses the project from Setting Up the ChunkDownloader Plugin and Preparing Assets for Chunking.

As described in reference quides, you need:

Create C++ project based on a Blank template. Name this project PatchingDemo.

Enable ChunkDownloader plugin in the Plugins menu.

Enable Use Pak File and Generate Chunks in Project Settings > Project > Packaging.

Edit your project's [ProjectName]Build.cs file in Visual Studio.

Generate Visual Studio project files.

Build your project in Visual Studio.

Add to this project the Paragon assets for Boris, Crunch, and Khaimera.

Adjust Data Asset based on Primary Asset Label for each asset you added.

2. Building the Manifest File

To create a Manifest File, follow these steps:

Create a folder called PatchingDemoKey inside the base directory of your project. In this example, path of this folder is PatchingDemo/PatchingDemoKey.

Create a new file called BuildManifest-Windows.txt.



Open this file in a text editor. Add the first line with a $NUM_ENTRIES field and set its value equal to the number of packaging files you are tracking. For this example, it equals 9.

BuildManifest-Windows.txt

Add a new line with a $BUILD_ID field and set its value to PatchingDemoKey. This value should be match the folder name, where you place Manifest File.

BuildManifest-Windows.txt

All next lines should have information about packaging files you need download. Each line describe each packaging file with the following information:

The filename.

The file size in bytes. To find this, right-click your packaging file and view its Properties.



Make sure to use the File Size for the, not the Size on Disk.

The version. You can set this to any string.

The index. This should match the chunk index values you used for your Primary Asset Labels.

The file path, relative to where the Manifest File will be located.

Each field must be on the same line, separated by tabs, otherwise they will not be parsed correctly. For example, our line for pakchunk1001 reads as follows:

BuildManifest-Windows.txt

Copy the packaging files from /Windows/PatchingDemo/Content/Paks/ into the PatchingDemoKey folder alongside the Manifest File, inside a subfolder called Windows.



You will need to repeat this process whenever you package your project or want to change what files are available to users. The final Manifest File for our example reads as follows:

BuildManifest-Windows.txt

Files with chunk index 0 also located in the [Build_Folder]/Windows/PatchingDemo/Content/Paks. You don't need add information about them to the Manifest File and copy them to the PatchingDemoKey.

3. Hosting Files on a Local Test Server

Now that you have packaged your files, you need to host them on a server that your game can download them from, and you need to tell ChunkDownloader where to find the server. For demonstration purposes, this example shows you how to set up a simple local web site.

In Windows Explorer, open the Start Menu, search for Turn Windows Features on or off, and open it.



Inside the Windows Features menu, enable Internet Information Services and click OK.



Open the Internet Information Services Manager (IIS Manager), then enable Directory Browsing.



In the Connections menu on the left side of the window, click PC-[User].



In the PC-[User] menu, double-click MIME Types.



In the MIME Types menu, click Add.



In the Add MIME Type window, set the File Name extension to .pak, then set the MIME type to application/octet-stream. Do the same for .ucas and .utoc.



This will ensure that IIS simply downloads the file when requested.



Navigate to the Default Web Site folder. By default this is C:\inetpub\wwwroot. Create a folder called PatchingDemoCDN.



Copy the PatchingDemoKey folder into PatchingDemoCDN.



Open your project's DefaultGame.ini file, then add the following information to define the CDN Base URL:

DefaultGame.ini

This URL points ChunkDownloader to the website where the files are located. The PatchingDemoLive qualifier enables you to use different CDN deployment configurations depending on your target platform.

The URL used in this example only points to the local web site we set up in the earlier steps. If you are trying to connect to a server with a local area network or a remote CDN, you will require additional configuration and security.

Final Result

Now that you have your assets divided into packaging files and staged on a local web site, you can access them with your patching solution in Unreal Engine.

In order to understand and use the content on this page, make sure you are familiar with the following topics:

Preparing Assets for Chunking

Setting Up the ChunkDownloader Plugin

Hosting a Manifest and Assets for ChunkDownloader

1. Required Setup and Recommended Assets

2. Initializing and Shutting Down ChunkDownloader

Working on PatchingDemoGameInstance.h

Working on PatchingDemoGameInstance.cpp

3. Downloading Packaging Files

Working on PatchingDemoGameInstance.h

Working on PatchingDemoGameInstance.cpp

4. Setting Up a Patching Game Mode

Working on Patching Game Mode

5. Displaying the Downloaded Content

6. Testing Your Game

End Result

On Your Own

ChunkDownloader is a patching solution for Unreal Engine (UE). It downloads assets from a remote service and mounts them in memory for use in your games, enabling you to provide updates and assets easily. This guide shows you how to implement ChunkDownloader in your own projects. By the end of this guide you will be able to:

Initialize and shutdown of the ChunkDownloader, using Visual Studio.

Download packaging files from your host web site, using Visual Studio.

Set up Game Mode Blueprint for implementing ChunkDownloader in UE.

Display the downloaded content in Level Editor Viewport or in your game.

Access content from mounted packaging files safely.

Test adjusted system in UE project on your local machine.

1. Required Setup and Recommended Assets

Before proceeding any further, you should review the following guides and follow each of their steps:

Setting Up the ChunkDownloader Plugin

Preparing Assets for Chunking

Hosting a Manifest and Assets for ChunkDownloader

As described in reference quides, you need:

Create C++ project based on a Blank template. Name this project PatchingDemo.

Enable ChunkDownloader plugin in the Plugins menu.

Enable Use Pak File and Generate Chunks in Project Settings > Project > Packaging.

Edit your project's [ProjectName]Build.cs file in Visual Studio.

Generate Visual Studio project files.

Build your project in Visual Studio.

Add to this project the Paragon assets for Boris, Crunch, and Khaimera.

Adjust Data Asset based on Primary Asset Label for each asset you added.

Cook or package project and have packaging files in your build folder.

Distribute packaging files to your locally hosted web site.

Create Manifest File called BuildManifest-Windows.txt.

Define DefaultGame.ini file for your project.

2. Initializing and Shutting Down ChunkDownloader

ChunkDownloader is an implementation of the FPlatformChunkInstall interface, one of many interfaces that can interchangeably load different modules depending on what platform your game is running on. All modules need to be loaded and initialized before they can be used, and they also need to be shut down and cleaned up.

The simplest way to do this with ChunkDownloader is through a custom GameInstance class. Not only GameInstance have appropriate initialization and shutdown functions you can tie into, it also will provide continuous access to ChunkDownloader while your game is running. The following steps will walk you through this implementation.

Create a New C++ Class using GameInstance as the base class. Name it PatchingDemoGameInstance.



Click image to enlarge.

When the compilation process is complete, the files PatchingDemoGameInstance.h and PatchingDemoGameInstance.cpp will open automatically in Visual Studio.

Working on PatchingDemoGameInstance.h

When files will open, code in the PatchingDemoGameInstance.h should looks as following:

PatchingDemoGameInstance.h

Change string class UPatchingDemoGameInstance : public UGameInstance to

PatchingDemoGameInstance.h

All subsequent variables, functions and properties, that you will declare in the PatchingDemoGameInstance.h file, will need to be added under UPatchingDemoGameInstance class.

Declare the following function overrides under a public header:

PatchingDemoGameInstance.h

The Init function runs when your game starts up, making it an ideal place to initialize ChunkDownloader. Similarly, the Shutdown function runs when your game stops, so you can use it to shut down the ChunkDownloader module.

Declare the following variable under a protected header:

PatchingDemoGameInstance.h

Declare the following function under a protected header:

PatchingDemoGameInstance.h

Working on PatchingDemoGameInstance.cpp

Open PatchingDemoGameInstance.cpp. Add the following #includes at the top of the file under #include "PatchingDemoGameInstance.h":

PatchingDemoGameInstance.cpp

This will give you access to ChunkDownloader and some useful tools for managing assets and delegates.

Create the following implementation for the Init function:

PatchingDemoGameInstance.cpp

Let's summarize what this code does:

The function defines DeploymentName and ContentBuildID to match the values used in DefaultGame.ini. These are currently fixed values for testing, but in a full build you would use an HTTP request to fetch the ContentBuildID. The function uses the information in these variables to make a request to your web site for the manifest.

The function calls FChunkDownloader::GetOrCreate to set up ChunkDownloader and get a reference to it, then stores it in a TSharedRef. This is the preferred way to get references to this or similar platform interfaces.

The function calls FChunkDownloader::Initialize using the desired platform name, in this case, Windows. This example gives it a value of 8 for TargetDownloadsInFlight, which sets the maximum number of downloads that ChunkDownloader will handle at once.

The function calls FChunkDownloader::LoadCachedBuild using the DeploymentName. This will check if there are already downloaded files on disk, which enables ChunkDownloader to skip downloading them a second time if they are up to date with the newest Manifest File.

The function calls FChunkDownloader::UpdateBuild to download an updated version of the Manifest File.

This is how the system supports update patches without requiring an entirely new executable.

UpdateBuild takes the DeploymentName and ContentBuildID alongside a callback that outputs whether or not the operation succeeded or failed.

It also uses OnManifestUpdateComplete to set bIsDownloadManifestUpToDate so that the GameInstance can globally recognize that this phase of patching is done.

Following these steps ensures that ChunkDownloader is initialized and ready to start downloading content, and informs other functions of the Manifest's status.

Create the following implementation for the Shutdown function:

PatchingDemoGameInstance.cpp

Calling FChunkDownloader::Shutdown will stop any downloads ChunkDownloader currently has in progress, then clean up and unload the module.

Create the following implementation for the OnManifestUpdateComplete function:

PatchingDemoGameInstance.cpp

This function will be used as an asynch callback, when the Manifest updating finishes.

3. Downloading Packaging Files

Now that you have appropriate initialization and shutdown functions for ChunkDownloader, you can expose its functionality for downloading packaging files.

Working on PatchingDemoGameInstance.h

In PatchingDemoGameInstance.h, below your #includes, add the following dynamic multicast delegate:

PatchingDemoGameInstance.h

This delegate outputs a boolean that will tell you whether or not a patch download operation succeeded. Delegates are commonly used to respond to asynchronous operations like downloading or installing files.

In your UPatchingDemoGameInstance class add the following function declaration for GetLoadingProgress under a public header:

PatchingDemoGameInstance.h

Add the following delegate declaration under a public header:

PatchingDemoGameInstance.h

These give you a place to hook into with Blueprint, when a patching operation is finished.

Add the following declaration for ChunkDownloadList under a protected header:

PatchingDemoGameInstance.h

You will use this list to hold all the Chunk IDs that you want to download later. In the development setting, you would initialize this with a list of assets, as needed. But for testing purposes, you will simply expose the defaults so you can fill them, using the Blueprint Editor.

Add the following declaration for PatchGame under a public header:

PatchingDemoGameInstance.h

This function provides a Blueprint-exposed way to start the patching process. It returns a boolean indicating whether or not it succeeded or failed. This is a typical pattern in download management and other kinds of asynchronous tasks.

Add the following function declarations under a protected header:

PatchingDemoGameInstance.h

You will use these to respond to async callbacks in the download process.

Working on PatchingDemoGameInstance.cpp

Create the following implementation for the GetLoadingProgress function:

PatchingDemoGameInstance.cpp

Create the following implementation for PatchGame:

PatchingDemoGameInstance.cpp

This function goes through the following steps:

First, it checks if the Manifest is currently up to date. If you have not initialized ChunkDownloader and successfully gotten a fresh copy of the Manifest, bIsDownloadManifestUpToDate will be false, and this function will return false, indicating a failure to start patching.

Next, if the patching process can continue, the function gets a reference to ChunkDownloader. It then iterates through the download list and checks the status of each chunk.

Two callbacks are defined:

The DownloadCompleteCallback will be called, when each individual chunk finishes downloading. It will output a message, when each of them successfully downloads or fails to download.

The LoadingModeCompleteCallback will fire, when all chunks have been downloaded.

The function calls FChunkDownloader::DownloadChunks to begin downloading desired chunks, which are listed in ChunkDownloadList. This list must be filled with the chunk IDs you want before calling this function. It also passes the DownloadCompleteCallback.

The function calls FChunkDownloader::BeginLoadingMode with the callback you defined earlier.

Loading Mode will tell ChunkDownloader to start monitoring its download status.

While chunks can download passively in the background without calling Loading Mode, using it will output download stats, enabling you to create a UI that can track download progress for the user.

You can also use the callback function to run specific functionality, when an entire batch of chunks is downloaded.

Create the following implementations for OnDownloadComplete and OnLoadingModeBegin functions:

PatchingDemoGameInstance.cpp

OnLoadingModeComplete will pass through to OnDownloadComplete, which will proceed to mount chunks in a later step. OnMountComplete will indicate that all chunks have finished mounting, and the content is ready to use.

Create the following implementation for OnDownloadComplete function:

PatchingDemoGameInstance.cpp

This is another complex function, so you will break down what it is doing. This runs when your packaging files have been successfully downloaded to a user's device.

It gets a reference to ChunkDownloader.

The function sets up a Json array and fills it with information from ChunkDownloadList. This will be used to make your request.

The function uses MountCompleteCallback to output whether or not the patch was successfully applied.

The function calls ChunkDownloader::MountChunks using the Json list and MountCompleteCallback to start mounting the downloaded chunks.

If the download was successful, the function activates the OnPatchComplete delegate with a value of true. If it wasn't successful, it activates with a value of false. UE_LOG outputs error messages according to the point of failure.

4. Setting Up a Patching Game Mode

To initiate the patching process, you can make a Level and Game Mode specifically to call PatchGame and output patching stats to the screen.

In Unreal Editor, create a new Blueprints folder in the Content Browser. Then, create a New Blueprint using PatchingDemoGameInstance as the base class.



Name the new Blueprint class CDGameInstance.



You will use this Blueprint as a more accessible way to edit settings and track the chunk download process.

Create a new Game Mode Blueprint called PatchingGameMode.



Create a Maps folder, then create two new Levels called PatchingDemoEntry and PatchingDemoTest. The PatchingDemoEntry Level should be based on an Empty Map, and the PatchingDemoTest Level should be based on the Default Map.



Open your Project Settings and navigate to Project > Maps & Modes. Set the following parameters:



Click image to enlarge.

ID

Parameter

Value

1

Game Instance Class

CDGameInstance

2

Editor Startup Map

PatchingDemoTest

3

Game Default Map

PatchingDemoEntry

Open CDGameInstance in the Blueprint editor. In the Defaults panel, add three entries to the Chunk Download List. Give them values of 1001, 1002, and 1003. These are your Chunk IDs.



Working on Patching Game Mode

Open PatchingGameMode in the Blueprint Editor and navigate to the EventGraph.

Create a Get Game Instance node, then cast it to CDGameInstance.

Drag As CDGameInstance pin, then click Promote to Variable to create a reference to the game instance. Call the new variable Current Game Instance.

Drag the output pin of Set Current Game Instance, then create a call to Patch Game.

Drag the Return Value of Patch Game, then click Promote to Variable to create a boolean in which to store its value. Call the new variable Is Patching In Progress.



Click image to enlarge.

Create an integer variable with the name Try Patch Count and drag Get Try Patch Count node to the Graph.

Drag the output pin of the Get Try Patch Count node and Create Increament Int node.

Drag the output pin of the Is Patching In Progress and create Branch node, connect its False pin to the Increament Int node.

Drag the output pin of the Increament Int node and create another Branch node, drag its False pin and create a Delay node.

Connect Complited pin of the Delay node with input pin of the Patch Game node.

Create Greater node. Connect its A Input pin to the Result pin of the Increament Int node. Connect its Return input to the Condition pin of the second Branch node.



Click image to enlarge.

Drag the Tick Event and create a new Branch node. Attach Is Patching In Progress to its Condition input.

Drag the True pin on your Branch node, then create a Print String node, which you will use for displaying of the download percent, and a Print String node, which you will use for displaying of the mount percent.

Create a Get Current Game Instance node, then drag its output pin and create a call to Get Loading Progress.

Drag from the Download Percent pin of Get Loading Progress node and create a Build String (float) node.

Input Current Loading Progress in the text field of the Prefix pin and input % in the text field of the Suffix pin.

Drag from the Mount Percent pin of Get Loading Progress node and create a Build String (float) node.

Input Current Mount Progress in the text field of the Prefix pin and input % in the text field of the Suffix pin.

Connect Return Value of the Build String (Float) for loading progress with the first Print String node.

Connect Return Value of the Build String (Float) for mounting progress with the second Print String node.

From the Print String node, create a Branch node, then create an AND node and connect it to the Condition pin.

Create a Greater Equal node to check if Download Percent is 100.0 or higher, then do the same thing for Mount Percent. Connect both of these to the AND node. If both of these conditions are true, use Open Level to open your PatchingGameTest Level.



Click image to enlarge.

Now when your game runs, it will open the Entry Map, run ChunkDownloader, and output the progress on downloading and mounting the chunks in your Chunk Download list. When the download finishes, it will then transition to your Test Map.

If you try to run this using Play In Editor, the download will not start. You need to test ChunkDownloader with packaged builds.

5. Displaying the Downloaded Content

To display our character meshes, you will need to get references to them. This section will walk you through a simple example of how to spawn actors.

Open the PatchingDemoTest Level, then open the Level Blueprint.

Create a new variable called Meshes.

For its Variable Type, choose Skeletal Mesh.

Hover over the entry in the types list and select Object Reference.



Click the icon next to the Variable Type of Meshes to change it to an Array. Compile your Blueprint to apply the change.



In the Default Value for Meshes, add three entries and select the skeletal meshes for Boris, Crunch, and Khaimera.



In the EventGraph for the Level, drag from the BeginPlay Event, then create a For Each Loop and connect it to your Meshes array.

Drag the Array Element pin on your For Each Loop, then create an Is Valid node.

Create a Spawn Actor From Class node and connect it to the Is Valid pin for the Is Valid node. Choose Skeletal Mesh Actor for the Class.

Drag the Array Index in the For Each Loop and create an Multiply node. Set the float value to 256.

Create one more Multiply node. Connect Return value pin of previous Multiply node to the B Input Value pin of created Multiply Node. Convert B Input Value pin of this Multiply node to the Vector by right-clicking on the B Input Value pin and selecting Convert to > Vector. Give the Vector a value of (1.0, 0.0, 0.0).

This will make a coordinate 256 units away from the origin for each time you go through the For Each Loop. This will give each of your meshes some space when you spawn them.

Use the vector from the previous step as the Location in a Make Transform node, then connect the Return Value to the Spawn Transform input of the Spawn Actor node.

Drag the Return Value of the Spawn Actor node, then get a reference to its Skeletal Mesh Component. Use that to call Set Skeletal Mesh.

Drag the Array Element pin of the For Each Loop node and connect the output of this node to the New Mesh input pin for Set Skeletal Mesh.



Click image to enlarge.

Move the Player Start inside the level to (256.0, 800.0, 100.0).



Click image to enlarge.

Save your progress and compile your Blueprints.

When the Level loads, the skeletal meshes for each of your characters will spawn. If the object reference does not work, then the chunks for each character are not yet mounted, their assets will not be available, and they will not spawn.



6. Testing Your Game

Finally, you need to test your project in a standalone build. Pak mounting does not work in PIE mode, so this is a necessary step to test your patching functionality.

Package your project.

Copy the packaging files and manifest to corresponding folders on your IIS test website.

Make sure the IIS process and website are both running.

Run your packaged executable.

End Result

You should see a black screen with the patching output in the upper-left side of the screen, then, when both the patching and mounting status reach 100%, your game should load into the default map and display Boris, Crunch, and Khaimera. If something goes wrong with the patching or mounting process, none of them will appear.

On Your Own

From here, there are several next steps you can take to flesh out your chunk download scheme:

Build a UI that appears during loading mode and displays progress bars and prompts for the player.

Build UI prompts for errors such as timeouts and installation failures.

Create a custom subclass of PrimaryAssetLabel to include additional metadata about your assets. For example, Battle Breakers' custom PrimaryAssetLabel class includes a Parent Chunk that must be loaded as a prerequisite to use the current chunk.

Learning Resource Projects

To help you more quickly understand the various ways you can use Unreal Engine and the assets that can be created with it, we have assembled a collection of learning resources for you to download, play with, and deconstruct.



Templates available with Unreal Engine and how to use them



Learning Resource Projects

Learning resource projects are all available through the Learn tab of the Epic Games Launcher.



Full scenes demonstrating particular features or approaches to specific challenges.



This sample project demonstrates specific concepts and techniques to use in Unreal Engine.



Full sample games demonstrating the implementation of various genres.



Companion documentation for free content distributed by Epic in the Marketplace.

Installing the Content Examples Sample Project

Available Content

The Content Examples project is designed as a showcase of different technology available to you in Unreal Engine. The project is set up as a collection of Levels, each level teaching a different aspect of the engine. As you move through the level, you will see a series of numbered stands, each of which having its own example asset.

Content examples are designed to be an interactive method of learning. For some of them, you will be required to play the level in order to interact with the assets.

You should feel free to open any examples within the Content Example levels, change or edit them, make your own versions of them, and learn from how they were assembled. You may also use any of the examples in your own levels.

Installing the Content Examples Sample Project

To install the Content Examples sample project, follow these directions.

Navigate to the Learn tab in the Epic Games Launcher. Locate the Content Examples project in the Engine Feature Samples section. Click the Download button to download the Content Examples project.



Click image for full size.

Select Create Project to create a new project from the Content Examples sample.



Click image for full size.

Set the Folder location where you will create your project. If needed, change the Version of the Engine to the version you will be running.



Click image for full size.

Once the project is open, you can navigate through the entry hallway to lea`rn how to use the project file. Select File > Open Level to browse all the available content.



Click image for full size.

Choose a Map that you would like to explore. Select Open to open that map.



Click image for full size.

Available Content

The following levels are available for you to explore in the Content Examples project.

Level Name

Content

Animation

This map provides examples of how to apply animation to an Actor. This can be done through one-off events, looping events, through a Blueprint, or by defining behavioral type sequences through Animation Blueprints. It also shows various animation asset techniques, and skeletal retargeting.

Animation_Basics

This map introduces the basics of animation. Learn about skeletal meshes, root motion, blend spaces, and more.

Animation Retargeting

This map provides examples of how to reuse animations on different characters, regardless of their proportions and skeletal hierarchies. Learn about techniques like Translation Retargeting, IK Rig and the IK Retargeter. The retargeting process can be done either at runtime, or for offline creation of new animation assets.

Audio

This map shows a variety of sound Actors and assets. Learn how to apply them in your levels. Also included are examples of how to set up Audio Volumes for effects like reverberation and volume control.

Blueprint_Communication

This map introduces ways that Blueprints can communicate with each other. Included are demonstrations of direct communication via casting, using Event Dispatchers, and sending data between Blueprints using Interfaces.

Blueprint_Input_Examples

This map shows examples of possessable Blueprint Pawns. Learn how to capture inputs from the player, then use them in different ways to drive various Blueprints.

Blueprint_Mouse_Interaction

This map introduces you how to use mouse inputs to control your game. Learn how to set up your Player Controller to enable mouse clicks.

Blueprint_Splines

This map shows you how to use Spline Components with Blueprints to create paths that can be used in a number of different ways.

BlueprintRenderToTarget

This map shows how to use the Blueprint render-to-target feature to implement a Texture creator, a Heightfield painter, and a GPU fluid surface simulation.

Blueprints_Advanced

This map introduces useful tips and techniques for using Blueprints in your levels. Included are randomization examples, creation of object arrays, and gameplay behavior examples like tracking spotlights and working doors.

Blueprints_Overview

This map introduces the basics of using Blueprint visual scripting in your projects.

Cascade_Legacy_Effects

This map shows examples of how to use the Cascade particle effects engine. Note: Cascade has been deprecated, and is no longer being actively developed. You should view the Niagara example maps for the latest technology.

Cascade_Legacy_Particles

This map shows additional examples of how to use the Cascade particle effects engine. Note: Cascade has been deprecated, and is no longer being actively developed. You should view the Niagara example maps for the latest technology.

Chaos Destruction

This map introduces you to the basics of Destruction using the Chaos engine. Learn about geometry collections, fracture methods, and more.

Character_Rendering

This map introduces examples of character rending for eye materials and hair shading.

Cloth

This map shows tips and techniques to use Chaos cloth in your games. Note: Cloth can be authored using the Skeletal Mesh Editor in Unreal Engine 5.

CommonUI

This map shows how to use CommonUI to create layered, multiplatform user interfaces.

Control Rig

This map shows how to use Control Rig to manipulate a Skeletal Mesh to create dynamic animations. Contro Rigs can be driven through Animation Blueprints or by Sequencer. Also shown are various Control Rig asset techniques, layering rigs, rig sharing, and splines.

Decals

This map shows you how to project Materials and material elements onto a surface. You can use decals to add unique effects on specific areas of a surface, for decoration or variation.

ExampleProjectWelcome

This is the welcome hall that opens when you first open the Content Examples project. It explains how to navigate the project.

FBX_Import_Options

This map shows some of the key settings to use when importing FBX files. FBX file import can be used for both static and skeletal meshes.

IKRig

This map provides examples of how to use an IK rig to pose a Skeletal Mesh. Data can be driven by Animation Blueprints, using interactive solvers like Full Body IK. Also shown are various IK Rig asset techniques, and how to use UK additively with animations.

Landscapes

There are three examples provided inside the Landscape Content Example map which showcase how mountains, hills, and valleys can be created using the Landscape tools. The second and third examples demonstrate the use of two additional tools, the Spline tool (used to create pathways) and the Foliage tool (used to quickly scatter and place Static Meshes like trees).

Level_Scripting

This map shows a variety of uses for Blueprint scripting within your level. Learn how triggers can be used with the Level Script Blueprint to handle a range of gameplay interactions.

Level_Streaming

This map introduces the concept of level streaming, showing you different ways to bring content into your levels at runtime.

Lighting

This map gives an overview of lights and their key properties in the engine. Included are examples of light types, light mobility, shadow settings, and more.

Material_Advanced

This map includes advanced examples of Material setup.

Material_Instances

This map shows you how to set up Material Instances. You can set up a master material, and child materials that inherit the parameters from the master material.

Material_Nodes

This map is an introduction to the different Material inputs. Learn from these examples how the different inputs affect the look of the material overall.

Material_Properties

This map provides an overview of all Material properties.

Math_Hall

This map introduces basic math functions, material functions, and trigonometry. Learn how math can be used in game scripting, in examples like making objects face a player, and using vectors to measure distances.

MorphTargets

This map gives an overview of how to use morph targets on a Skeletal Mesh to change its shape or material.

NavMesh

This map provides an overview of how to use NavMesh for AI navigation. For example, you can use this to navigate around obstacles.

Network_Features

This map showcases examples of the Blueprint networking features.

Niagara_Advanced_Particles

This map shows advanced Niagara particle effect examples. Learn how to do Nearest Neighbor queries, Simulation Stages, Iterative Constraints, Mesh Reproduction, export your particle data to Blueprints, and more.

Niagara_Fluids

This map shows examples made with the Niagara Fluids plugin. See examples of 2D and 3D gas and liquid simulations. Learn how to set up collisions, lighting, parented simulation, and about quality / performance tradeoffs. Note: You must run the simulations in PIE. Make sure your graphics card is updated to the latest drivers.

Niagara_Particles

This map is an introductions to the Niagara Particle Effects engine. Learn by immersing yourself in Niagara simulations of increasing complexity.

Paper2D

This map introduces how to use the Paper2D Plugin to create 2D games. Learn how to create sprites, flipbooks, and apply physics with a locked axis.

ParallaxOcclusionMapping

This map shows you how to use Parallax Occlusion Mapping to give textures the appearance of displacement using the pixel shader. This is similar to Bump Offset, but gives more accurate intersections by ray tracing through a height map.

PhysicalAnimation

The examples in this map show how to blend character animation with physics.

Physics

This map is an introduction to Physics in Unreal Engine. Learn how to apply forces to objects, and about different types of constraints.

PivotPainter

This map explains how to use the PivotPainter script from 3ds Max in Unreal Engine. The examples were created using Per Object Painter. This MAXScript is used to store model pivot and rotation information in the model's vertex data. This information can then be used to change the shape, position, or orientation of objects dynamically in the engine. Advanced examples show you how to animate grass and trees.

PivotPainter2

Pivot Painter 2 is a 3ds MAXScript that can be used to generate complex procedural animations. Pivot Painter 2 has an improved workflow in 3ds Max, improved data accuracy, and increased the number of output options.

PostProcessing

This map shows examples of Post-Processing effects you can apply to change the look of your level. Explore options like film, bloom, lens flares, and many more.

ProceduralMesh

This map explains how to use the Procedural Mesh tool to generate shapes using vertex positions, triangles, normals, UVs, and tangents.

Skin Rendering

This map shows how to use Subsurface Profiles to create realistic-looking human skin.

StaticMeshes

This map introduces you to Static Meshes and their many different properties. Learn how to make a mesh static or movable in-game. See examples of UV texture mapping, applying materials to a mesh, vertex colors, the MeshPaint tool, and more.

UMG

Learn all about how to build user interfaces for your game using UMG. See examples of sliders, buttons, progress bars, and more.

Volumes

Learn how to add Volumes to your level to achieve different effects. Volumes are used to define an area within which you will apply a specific behavior. For example, you can cull objects within a volume based on the distance from the camera.

Engine Feature Examples are projects and asset packs that illustrate different engine feature sets. They may be small stand-alone examples, like in the Content Examples project, or larger showcases for a particular visual style or scene.

The corresponding documentation is designed to provide some insight into how each sample was created, using direct feedback from the Epic artists responsible. Feel free to open up and analyze any element of these examples, as well as use them in your own projects.



An overview of the features used to create the City Sample learning example.



How to setup the Car Configurator sample project, render a commercial with Movie Render Queue, and edit with the Variant Manager.



Learn how to take 3D motion design to the next level with Unreal Engine's Broadcast Hype Chamber Sample.



How to set up the DMX Previs sample, view the light show previs, and explore the DMX-controlled fixtures and effects.



How to set up the In-Camera VFX Production Test sample, and explore the features, project structure, and settings used during production.



How to set up the Meerkat demo, render it with Movie Render Queue, and explore its animation and optimization features



The Pixel Streaming Demo showcase demonstrates how you can design Unreal Engine content for viewers to experience as a live stream in a Web browser or mobile device.



Fully realize your virtual production workflows in Unreal Engine by learning about Slay and its cinematic techniques.



The Virtual Studio showcases Unreal Engine's ability to exchange video feeds with professional grade SDI cards and devices.

Variant Manager Template Overview

Hardware Ray Tracing and Path Tracing Features

Volumetric Cloud Component

Control Rig

Cinematics and Sequencer

Movie Render Queue

How To Use the Car Configurator

Downloading the Sample

Navigating the User Interface

Rendering the Commercial View

Variant Manager

Lumen Global Illumination and Reflections

Path Tracer

Volumetric Clouds

Chaos Cloth Solver

Control Rig

Sequencer

Movie Render Queue

Adding Art Assets to the Configurator

The automotive industry is increasingly turning to real-time solutions, such as Unreal Engine (UE), to drive their visualization and commercial projects. The Car Configurator sample is built using Epic Games' best practices for the creation of a vehicle configurator, a common use case for 3D visualization artists in the automotive industry.

The Car Configurator sample demonstrates the use of the following features:

Variant Manager

Lumen

Path Tracer

Volumetric Clouds

Chaos Cloth Solver

Control Rig

Sequencer

Movie Render Queue

How To Use the Car Configurator

Downloading the Sample

The project sample is freely available via the Samples tab in the Unreal Engine section of the Epic Games Launcher. Other asset packs used in the making of the sample can be found for free in the Marketplace tab.

Automotive Materials Pack

Automotive Salt Flats Environment

To create a project with the Car Configurator sample, use the following steps:

Open the Epic Games Launcher and click on the Unreal Engine button on the sidebar. Then open the Samples tab.



Scroll down to the UE Feature Samples and select the Car Configurator sample. Click the Free button to add this project to your Vault.



Click the Create Project button and follow the on-screen instructions to download the sample and start a new project.



Open your new project in the Unreal Editor.

This project requires the following plugins (enabled by default):

Movie Render Queue

Color Correct Regions

Control Rig

Variant Manager

This may require you to restart the Editor.

Navigating the User Interface

The Car Configurator is built using the Product Configurator template as a base. Using the Variant Manager, you can choose from a variety of saved Static Mesh configurations called Variants to customize your Audi A5.



You can control the configurator using the interface buttons located at the bottom of the screen:

Number

Description

1

Configurator Mode

2

Commercial Mode

3

Car Paint Color

4

Wheel Style

5

Trim Color

6

Leather Color

7

Seat Upholstery Style

8

Toggle Path Tracer

9

Take Screenshot

10

Mute/Unmute

11

Camera Views

The Car Configurator also includes focus points, represented by white flashing circles. These have been animated using Control Rig, Unreal Engine's Blueprint-based animation control system:

Open/Close Doors: Open and close the car doors.

Open/Close Convertible Soft Top: Open and close the convertible top by clicking on the roof control switch located by the rearview mirror in any of the interior views.

Open/Close Trunk: Open and close the trunk lid.

Horn: Honk the horn.

Start/Stop the Engine: Click the Engine Start button to start or stop the engine. When the engine is started, the dash gauges and Audi Virtual Cockpit are powered and the front lights and tail lights are lit up.

Rendering the Commercial View

Clicking the Play button in the Configurator will transport your customized vehicle to the Commercial mode.



In Commercial mode, your vehicle becomes the star of your very own TV spot. This takes your vehicle through several camera shots often seen in car commercials. You can control the commercial using the following interface options:

Number

Description

1

Stop

2

Play

3

Pause

4

Render Video

Powered by Sequencer, the camera races across the salt flats, moving to highlight the wheels and interior. The car commercial takes advantage of Ray Tracing for real-time lighting and shadows, and can be saved to your computer thanks to the Movie Render Queue runtime feature. Optional Path Tracer use

Variant Manager

The Car Configurator is built on the Product Configurator template and uses the Variant Manager to store the various asset configurations used to customize your vehicle.

Move the slider to see the different Trim variants



Each configuration option is stored in an entry called a Variant. Each variant points to a property on an Actor that is changed when the variant is activated. Variants are arranged into Variant Sets and the data is used by the BP_Configurator Blueprint to populate the user interface with options. In the image above, you can see that when different trim options are selected the Variant Manager applies that value to different static mesh components on the vehicle Actor.

For more information on using the Variant Manager, please see the Variant Manager documentation.

Lumen Global Illumination and Reflections

Unreal Engine uses the Lumen Global Illumination and Reflection system to provide dynamic global illumination and shadows.



The Car Configurator sample uses Lumen's ability to provide diffuse interreflection and indirect specular reflection to accurately reflect the salt flats environment off the tire rims and car, making the most of the Clear Coat properties of the Materials used from the Automotive Materials pack.

For more information on lighting your level with Lumen, see the Lumen documentation.

Path Tracer

Path Tracer is Unreal Engine's progressive, hardware-accelerated rendering mode. Designed to generate physically correct global illumination and reflection and refraction of materials, enabling Path Tracer can provide you with photorealistic renders with little to no additional setup.





Path Tracer features full integration with Sequencer and Movie Render Queue making it ideal for Film and TV quality render outputs.

The Car Configurator sample gives you the option to toggle path tracing on from the interface to provide photorealistic output for screen captures or rendering during Commercial mode.

For information on using Path Tracer in your own projects, see the Path Tracer documentation.

Volumetric Clouds

The Volumetric Clouds found in the sample use a physically-based cloud rendering system and a material-driven approach to create the sky that is seen on the salt flats.



The Epic Games team uses volumetric clouds to bring aesthetic touches to the salt flats, while also getting bounced light reflection on the car paint. The Volumetric Cloud component uses a Material Instance of the default cloud Material to accomplish these effects.

For more information on using the Volumetric Clouds system, please see our Volumetric Clouds documentation.

Chaos Cloth Solver

The Car Configurator sample uses the Chaos Cloth Solver to simulate the physics interactions of the cloth convertible top.



Using the Cloth Painting workflow directly in the Engine, the Epic Games team is able to assign a variety of properties such as friction, constraints, drag, and stiffness to closely simulate the look and feel of the Audi A5's canvas soft top.

For more information on the Chaos Cloth Solver and in-engine Clothing Tool, please see the Clothing Tool documentation.

Control Rig

The Control Rig system is a scriptable node-based rigging system that provides rigging and animation tools directly in the engine.



In the Car Configurator, the Epic Games team uses Control Rig in two ways. The first is to create an adaptable skeletal mesh version of the car and create the animations for the wheels, doors, and trunk. The second is to create the animation for the convertible top.

The Audi A5 uses a skeleton with pivot locations for each movable element in the car. With this method, the main vehicle geometry does not need to be bound to the vehicle, and the skeletal mesh can be imported into Unreal quickly. Once imported, the mesh is added to a Blueprint, which attaches the rest of the vehicle components to the pivots and binds the skeleton to the Control Rig at runtime. This makes it easier to update the pivot locations if needed without having to go back to our DCC application.

Due to its complexity, the cloth convertible top is a separate piece with its own skeleton and Control Rig. A state machine tracks if the top is open or closed, and runs the correct transition animation when it is selected in the configurator application.

For more information on using Control Rig to animate in-engine, please see the Control Rig documentation.

Sequencer

Powering the Commercial mode, Sequencer is a robust keyframe animation system which you can use to create in-game cinematics.



The Commercial mode uses a series of level sequences with animated cameras to showcase various configurable features on the car. The Epic Games team then uses Movie Render Queue to render and save the level sequences and assemble them using a non-linear editing program. This edited sequence is brought back into Unreal as a master sequence, where audio is added and the cameras, animation, and overall timing is refined. These sequences are found in the CarConfigurator/Commercial/Sequences folder.

For more information on using Sequencer in your projects, please see the Sequencer documentation.

Movie Render Queue

Used to output the final commercial render, Movie Render Queue is an engine feature that can export high-quality media. When used with Real-Time Ray Tracing, the final render can take advantage of advanced anti-aliasing, radial motion blur, and reduced noise in ray tracing:



The Epic Games team uses Blueprint to enable Movie Render Queue at runtime. With this, you can render and save a video of your commercial directly from the configurator.

For more information on using the Movie Render Queue feature, please see the Movie Render Queue documentation.

Adding Art Assets to the Configurator

You can add new art assets to the Car Configurator by adding a new variant to the Level Variant Set. This process is similar for both Materials and Static Mesh assets. The example below describes how to add a new paint color to the configurator.

The Audi A5 in this sample makes use of the Automotive Materials Pack for paint, leather, and trim options. To add additional colors to the interface, follow these steps:

Create a custom folder to hold your new Material and any texture samples that it may need. Do this by right clicking on the CarConfigurator folder and selecting New Folder. Name the new folder Custom.

If you are not adding a color that is already available within the sample, you will need to either create your paint sample using the tools available within the Automotive Material Pack, or import and set up your Material. For this sample, you are duplicating an existing paint sample and editing it. For more information on importing textures and creating new Materials, see our Material How-To documentation.

Next, open the CarConfigurator/Shared folder and double click on the CarVariants Level Variant Set to open it in the Variant Manager.



To make sure that your new color is applied to all the required static meshes, you can duplicate an existing Variant. Open the Paint, Trim, or Leather Variant Sets and right click on the last variant in the list. From the menu, choose the Duplicate option.



Right click on your new variant and choose Rename. Create a new name that is appropriate for the color.



Click the BP_AudiA5 in the Properties panel to display the Properties and Values for the car. For each value in the Values column, click the drop down menu and select your new color, excluding the SM_trunkDetails Material.



Changing the Material for SM_trunkDetails changes the license plate on the car.

Set the thumbnail image for your new variant by switching on the variant and positioning the Viewport camera to best display your new option.



Then right click the variant in the Variant Manager choose the Set from viewport option.



Test the sample by clicking the Play button in the Editor. Your new variant should appear in the user interface.

Getting Started

Playing Graphics and Animation

Hypechamber Control

Hypechamber Advanced

Using Remote Control to Play Graphics and Animations

Editing Team Themes

Creating Your Own Team

Batch Rendering with Movie Render Queue

Real-time technology is becoming an increasingly important part of motion graphics and sports. Epic Games partnered with Capacity Studios to deliver a high-quality Broadcast Hype Chamber Sample which demonstrates how to design, develop, and play out numerous animation elements for your esports show.

Enter the Hype Chamber and learn how to drive a sports motion graphics package with advanced blueprinting and data table workflows.

By exploring this sample and this page, you'll learn about:

How to use motion graphics animation for live playout or pre-rendered animation. This sample includes 10 motion graphics examples.

How to build a highly customizable graphic package where artists can switch 3D models, textures, materials, and lighting, all driven by a single blueprint controller. When you change team names, all the elements in the scene will swap accordingly.

How to extend the workflow by adding a new team to the data table.

Getting Started

Download the sample from the Learn tab of the Epic Games Launcher and open the project in Unreal Engine.

Playing Graphics and Animation

In the Unreal Editor's Toolbar, click Play to run the level.

In the World Outliner, select BP_HypeChamber_Controller to open its Details panel. These are options that you can change during Play in Editor mode.

Hypechamber Control



Click Play Graphic to play the 3D graphics and animation.



Click Reset Graphic to reset everything to its initial state.



Change Team ASelect to change the team that appears in the Level. For graphics or modes with two teams, TeamASelect appears on the left side, and Team BSelect appears on the right side.



Mode Select changes what displays in the Level. A different motion graphic and animation is associated with each mode. You have the following options:

INT Matchup

INT Matchup Infinite

INT Team Hype Chamber

INT Player Name

INT Text

INT_Logo

FS Open

FS Team Hype Chamber Wide

FS Team Hype Chamber Close

FS Backgrounds

BUMP Team Victory

Hypechamber Advanced

The Hype Chamber Controller has the following settings for customizing media output and post processing when playing the motion graphics and animations.



Parameter

Description

Disable SDI

Disable active media capture output.

Enable SDI

Enable media capture output based on Media Output Generic.

Update Advanced

Update quality and ray tracing settings to values set by the Hype Chamber Controller.

Update Logos

Update background logos and colors featured in screenwalls.

Use Mode Select

When enabled, you can control which scene is used with the Hype Chamber Controller. You'll need to disable this before using Movie Render Queue.

Screen Mode

The type of content to fill the Hype Chamber Screens. Defaults to a render target of a motion graphics scene.

Master Post Process

A reference to the scene post processing volume with the highest priority.

Media Output Generic

Defines the media capture output of content. Defaults to use a Blackmagic SDI configuration.

Resolution

The output resolution size for the media capture.

Quality

The sg.resolution quality command input.

Max Roughness

Maximum roughness amount of the Post Process volume ray tracing.

Max Bounces

The maximum number of bounces of the Post Process volume ray tracing.

Samples Per Pixel

Number of samples per pixel of the Post Process volume ray tracing.

Using Remote Control to Play Graphics and Animations

In EsportsSample/_ArtistElements/Blueprints, double-click the RC_Esports Remote Control Preset to open it in the Remote Control Panel. The parameters in the BP_Esports_Controller's Details panel are the same parameters exposed in the RC_Esports preset.



Launch the Remote Control Web Application to control the team graphics and text remotely by entering the URL 127.0.0.1:7000 on your local machine, or your computer's IP address with port 7000 on a second device. Refer to Remote Control Web Application for more information about using the web application.



Editing Team Themes

To edit the current team themes, in the Content Browser, navigate to EsportsSample/_ArtistElements/Blueprints/Data and double-click DT_Esport_Themes to open it in the Data Table Asset Editor.

Each row is all the data for one team, from the team name to the team's color palette. Click a row and edit its data in the Row Editor to make changes to the team's theme.



To change what parameters define a team's theme, navigate to EsportsSample/_ArtistElements/Blueprints/Structures and double-click ST_RL_Design to open it in the Structure Asset Editor.



In Esports/_ArtistElements/Blueprints, double-click BP_Esport_Controller to open it in the Blueprint Editor. In the UpdateData section, the DT_Esport_Themes data table is looked up by row name to populate the team data in the Level. When you add parameters, make sure they're connected to Assets defined in the TeamAValues and TeamBValues nodes.



Click image for full size.

Creating Your Own Team

Follow these steps to add a new team to the selection.

In the Content Browser, navigate to EsportsSample/_ArtistElements/Blueprints/Enums and double-click EN_Teams to open it in the Enum Asset Editor.



Click New to add an entry to the Enum.

Set the new entry's Display Name to the abbreviated name of the team and Description to the full name of the team. In this example, the new team's Display Name is WIP and its Description is Work in Progress.

Navigate to EsportsSample/_ArtistElements/Blueprints/Data and click (+) Add to add a new row.

Set the new row's name to the abbreviated name of the team and Team Name to the full name of the team. In this example, the row's name is WIP and the Team Name is Work in Progress.



You can now change the Hypechamber Controls in the Level's BP_HypeChamber_Controller to select your new team.

Batch Rendering with Movie Render Queue

In the Content Browser, navigate to EsportsSample/_ArtistElements/Blueprints. Right-click the EUW_VersioningUtility Editor Utility Widget Asset and choose Run Editor Utility Widget.

The Editor Utility Widget opens in a new window.



This widget provides controls for batch rendering sequences with various configurations of teams using Movie Render Queue. The following parameters affect the rendering job.

Parameter

Description

Mode Select

Select which graphic animation should be configured and played when rendering.

Target Sequence

The Level Sequence targeted by Mode Select. Can be opened while in the editor to preview graphics.

Team AList

The list of teams to be rendered out with the selected graphic. In graphics or modes with two teams, this controls the team featured on the left.

Team BList

The secondary list of teams to be rendered out with the selected graphic. In graphics or modes with two teams, this controls the team featured on the right.

Text Ver

Selects which version of the text mode animations is used in the renders. The input text defaults to what is currently set as the Text Line 1 and Text Line 2 inputs.

Background Ver

Selects which version of the background mode animations is in the renders.

Hype Chamber Con

A debug reference to the BP_Hypechamber_Controller in the scene.

Render Preset

The Movie Render Queue Render Preset Asset to render jobs.

Output Folder

The output directory of the rendered Assets.

Pipeline Executor Job

A debug view to show that a valid executor job is showing.

Next Render Executor

A debug view to show the next executor job.

Queue Index

A debug status of which job is currently being rendered from the Team A and Team B list

Job Count

The total count of jobs listed to be rendered. This is based on the number of teams featured in the Team A List.

Click (+) Start Render to start the render jobs.



Accessing the City Sample Project

Recommended System Specifications

Navigating the City Sample Project

City Sample In-Game Controls

City Sample In-Game Menu Options

High-End Visuals

Lumen Global Illumination and Reflections

Nanite Virtualized Geometry

Temporal Super Resolution

Virtual Shadow Maps

Post Processing Local Exposure

Procedurally Generated and Populated City

Collaboratively Constructing Large Worlds

One File Per Actor

World Partition

Data Layers

Simulating Real-World Systems

MetaHumans

Artificial Intelligence System

Chaos Vehicles

Tuning Vehicle Handling

Dynamic Vehicle Deformation

Procedural Audio and MetaSounds

Vehicle Audio

Music Redesign

City Soundscape and Procedural Audio Generation

Creating Your Own Procedural City Guides

The City Sample project is a playground where designers and developers alike can explore how various new and improved systems are brought together to create expansive and engaging environments. This sample is built using the same assets and design techniques used in The Matrix Awakens: An Unreal Engine 5 Experience technical demo released on PlayStation 5 and Xbox Series S|X hardware.

The new and improved features of Unreal Engine 5 enable you to build large, highly-detailed worlds that are brought to life with Mass AI and fully dynamic lighting. The city is designed and built using procedural generation using the Rules Processor.

The following features are used in this sample project:

World Partition works in conjunction with One File Per Actor to improve level streaming and editor workflow efficiency.

Nanite enables the use of high-fidelity virtualized micropolygon geometry.

Lumen generates dynamic global illumination and reflections using Hardware Ray Tracing.

The Virtual Shadow Maps system provides consistent, high resolution shadowing for the city.

Mass AI manages the behavior and visualization of traffic and crowds based on the MetaHuman library.

Chaos physics drives the vehicle and the destruction systems.

The MetaSounds system fills the city with urban sounds.

Niagara is used for particle systems.

And more!

Accessing the City Sample Project

You can download the City Sample from the Samples tab of the Epic Games Launcher or from the Unreal Engine Marketplace.

Recommended System Specifications

The City Sample is a graphically intensive project that requires a powerful video card and system to run at a stable framerate. It is recommended to install the project on a solid state drive (SSD), Nanite and Virtual Shadow Maps depend on fast speeds for the best possible performance.

Windows 10 with support for DirectX 12

12-core CPU at 3.4 GHz

64 GB of System RAM

GeForce RTX-2080 / AMD Radeon 6000 or higher

At least 8 GB of VRAM

This sample project requires that your machine have up-to-date graphics drivers and DirectX 12. Nanite and Virtual Shadow Maps require DirectX 12.

On lower spec systems, you can adjust the viewport screen percentage setting to get better performance by reducing the resolution of the Level Editor viewport. You can set this in the Viewport Options located in the upper-left corner of the editor viewport using the Screen Percentage slider.



Navigating the City Sample Project

When you open City Sample, you are greeted by the Startup map that provides some on-screen information for using this sample project and its recommended system requirements. The project includes two maps: a big city and a small city. Select one of these maps to open from the Content Browser in the Content > Map folder.

The Big City (Big_City_LLV) map is the same one generated for The Matrix Awakens technical demo. This particular map is resource intensive and may not perform well on machines with lower than recommended specifications. It's roughly 4 kilometers by 4 kilometers in size.

The Small City (Small_City_LVL) is a smaller city generated using the same assets and configurations as the larger one. It is designed to showcase all of the rendering, physics, artificial intelligence, sounds, and gameplay features as the larger city.

The City Sample is a showcase for developing and designing worlds using World Partition and Data Layers. Unlike Unreal Engine 4, there are no sub-Levels that would traditionally be used to load in objects. Instead, World Partition loads them on-demand, and breaks up the scene into separate, editable parts.

When you load either city level, you'll find the World Partition window is docked on the right side of the editor viewport, and displays a simplified map of the world.



Part of the World Partition tools is the Data Layers Outliner that provides a listing of data layers that contain objects that make up the scene. The Data Layers Outliner can be opened from the main menu under Window > World Partition > Data Layers Outliner.

The Data Layers can be disabled as-needed from this window. Use the Visibility (eye) icon next to a listed layer to stop it from being rendered, or, to disable that layer completely, use the checkbox.



When a Data Layer is selected, the properties are displayed in the bottom portion of the window.



When opening the Small City for the first time, you'll notice that it's ready to go and all assets are loaded. However, when opening Big City, none of the cells are loaded. You'll want to use the World Partition window in the editor to do that. Right-click on any single cell, or use the mouse to left-click and drag to select multiple cells before right-clicking. Then, choose Load Selected Cells.

You can quickly navigate the map by double-clicking on any cell in the World Partition window to move the camera to that location on the map.

City Sample In-Game Controls

The City Sample is a playable experience where players walk, drive, and fly around the city. You can use a keyboard and mouse or gamepad. Below are the controls for each.

Item Name

Controller

Keyboard and Mouse

Move Forward

Left Joystick

W

Move Backward

Left Joystick

S

Move Left

Left Joystick

A

Move Right

Left Joystick

D

Look

Right Joystick

Mouse Move

Menu

Start or Options Button

O

Enable Flying Mode

Y

X

Sprint

Right Bumper

Left-SHIFT or L-SHIFT

Dismiss Controls

X

Z

Item Name

Controller

Keyboard and Mouse

Throttle

Right Trigger

W

Brake/Reverse

Left Trigger

S

Steer Left

Left Joystick

A

Steer Right

Left Joystick

D

Look

Right Joystick

Mouse Move

Handbrake

B

Spacebar

Enter/Exist Vehicle

A

C

Menu

Start or Options Menu

O

Dismiss Controls

X

Z

Item Name

Controller

Keyboard and Mouse

Move Forward

Left Joystick

W

Move Backward

Left Joystick

S

Move Left

Left Joystick

A

Move Right

Left Joystick

D

Look

Right Joystick

Mouse Move

Altitude Up (Ascend)

Right Trigger

E

Altitude Down (Descend)

Left Trigger

Q

Speed Up

Right Bumper

F

Speed Down

Left Bumper

R

Menu

Start or Options Button

O

Enable Walking Mode

Y

X

Dismiss Controls

X

Z

Item Name

Controller

Keyboard and Mouse

Menu Navigation

Left and Right Bumper

[ and ]

Menu Item Navigation Up

D-pad Up

Up Arrow

Menu Item Navigation Down

D-pad Down

Down Arrow

Adjust Settings

D-pad Left and D-pad Right

Left Arrow and Right Arrow

Item Name

Controller

Keyboard and Mouse

Move Forward

Left Joystick

W

Move Backward

Left Joystick

S

Move Left

Left Joystick

A

Move Right

Left Joystick

D

Look

Right Joystick

Mouse Move

Altitude Up (Ascend)

Right Trigger

E

Altitude Down (Descend)

Left Trigger

Q

Reset Camera

Y

Auto Focus (Hold)

A

X

Close Menu

Start or Options Button

O

Hide User Interface

X

Z

City Sample In-Game Menu Options

After opening the in-game Menu, a user interface will appear in the bottom right corner of the screen. It includes options to change the lighting, the crowd and traffic densities, and enable visualization options for features like Nanite. It also includes a dedicated photography mode with common camera features like exposure, aperture, and depth of field settings.

You can navigate the menus using the keyboards Left / Right Bracket keys or if you're using a controller, use the Left / Right Bumpers. The following in-game menus are available.

The Photo Mode menu contains Camera and Focus settings to configure exposure, aperture, and focus.



Menu Setting

Description



Camera



Exposure Compensation

Adjusts the exposure of the rendered frame to be brighter or darker.

Aperture

Changes the size of the opening for the camera lens. Lower f-stop values increase the amount of light coming into the opening of the lens, which can increase focus to create depth of field.

Focal Length

Sets the angle of view used by the camera. Larger focal lengths capture less of the scene but enlarge objects further away and increase depth of field. Smaller focal lengths capture more of the scene but decrease the amount of depth of field that occurs.



Camera



Focus Distance

Sets the shortest distance in which the lens can focus the image.

The World Settings menu contains various settings that affect lighting, density of crowd, traffic, and parked vehicles, and various visualization options.



Menu Setting

Description



Simulation



Night Mode

Toggles between daytime and nighttime lighting.

Sun Rotation

Sets the degree angle the sun is rotated.



Density



Crowd

Sets the density of the crowds that populate the city streets.

Traffic

Sets the density of the traffic that populates the city streets.

Parked Cars

Sets the density of the cards parked alongside the city streets.



Visualizations



Crowd & Traffic

Toggles a visualization mode that replaces parked cars (blue), driving cars (green), and individuals in a crowd (white).

Post-processing Filter

Toggles a post processing filter similar to the one used in the Matrix: Awakens technical demo.

Nanite View

Toggles between the different visualization modes of Nanite.

Default is the game view.

Primitives are the number of which have Nanite enabled for them.

Instances applies a different color for each individual instance of a Static Mesh in the scene.

Clusters displays colored representations of all groupings of triangles being rendered in the current scene view.

Triangles displays all triangles of the Nanite meshes that make up the scene.

Material ID applies a separate color for each material of a Nanite primitive.

The Controller Settings menu displays the controller button mappings for walking, driving, drone, and photo modes. The menu also contains settings for camera control with look sensitivity and inverting the vertical axis.



Menu Setting

Description



Camera Control



Haptic Feedback

Toggles haptic feedback vibration while playing.

Invert Vertical Axis

Inverts the vertical axis of movement.

Look Sensitivity

Adjust the sensitivity scale applied to the camera movement when looking around.

Changes to these settings also affect Keyboard and Mouse.

High-End Visuals

The City Sample demonstrates Unreal Engine 5's high-end visuals for building large open worlds.

The City Sample requires DirectX 12 for its high-end visuals. Some features work in a limited capacity or not at all with systems that don't meet the Recommended System Specifications of this project.

Lumen Global Illumination and Reflections

Lumen is used to provide dynamic global illumination and reflections across the city. Lumen provides dynamic, photorealistic lighting for scenes with many areas being indirectly lit. It adapts to changes in direct lighting and geometry, combining new and old techniques to achieve high-quality results within real-time budgets.

Lumen is built with the next-generation consoles and high-end PCs in mind.





The City Sample uses Hardware Ray Tracing, which supports a larger range of geometry types such as skinned meshes. Hardware Ray Tracing also scales up better to higher qualities since it intersects against the actual triangles of geometry and has the option to evaluate lighting at the ray hit instead of the lower quality surface cache.

For Static Meshes using Nanite, Hardware Ray Tracing can only operate on the Fallback Mesh generated from Nanite's Fallback Triangle Percent in the Static Mesh Editor. Screen Traces are used to cover the mismatch between the full triangle mesh rendered by Nanite and the fallback mesh being ray traced by Lumen.

Lumen works with all movable light sources, including emissive materials as light sources. Skylighting uses Lumen's Final Gather for sky shadowing, which allows for indoor areas to be much darker than outdoor areas, and that helps bring out lightly colored surfaces that reflect more light. The City Sample is being lit by only Directional Light, Sky Light, and Emissive Materials from surfaces.





While you explore the city in-game, use the menu to access the World Settings where you can adjust the Sun Rotation. Or, while working in the editor, you can use the keyboard shortcut Right Ctrl + L and drag your mouse to move the Directional Light around.

For more information and details about how it works, see Lumen Global Illumination and Reflections and Lumen Technical Details.

Nanite Virtualized Geometry

Nanite virtualized geometry is used on all of the Static Meshes in the City Sample, and none make use of traditional levels of detail. Nanite renders pixel scale detail and handles high object counts by intelligently doing work on only the detail that can be perceived, and no more. It does for geometry what Virtual Texturing does for texture detail.

Nanite's internal mesh format and rendering technology means that its representation changes dynamically as you move through the world, updating the level of detail on the fly and culling parts that aren't rendered on screen. Objects closer to the player camera receive more detail, while further objects receive less, all the while keeping on screen detail uniform.



The City Sample is made up of billions of polygons from tens of thousands of objects placed throughout the world. Nanite makes it possible to use film-quality assets in real-time with little to no additional setup other than enabling Nanite on the Static Mesh. It's even possible to drop a high-polygon ZBrush sculpt directly in game.

Use any one of the visualization modes that Nanite offers to see how it renders the scene. You can select from the list of visualization using the View Modes menu under Nanite Visualization rollout menu.



Nanite's Overview visualization mode.

For more information about how to use and configure Nanite for your own projects, see the Nanite Virtualized Geometry documentation.

Temporal Super Resolution

The geometric detail and fidelity required for large, open worlds with thousands to millions of instances totaling billions of polygons have increased the demands of games developed for next-generation consoles and high-end PCs. That level of fidelity can mean that games can consume a significant amount of their performance budgets before including rendering a frame at native 4K resolution.

Temporal Super Resolution (TSR) is an anti-aliasing method built to meet the fidelity demands of large, densely populated worlds. It uses a platform-agnostic temporal upscaling algorithm by taking a lower input resolution and outputting rendered frames at quality near 4K resolution. This means that you can increase performance without rendering native 4K but still achieve quality that rivals 4K from rendered lowerer resolutions.

In the comparison below, you can see the quality and performance differences between captured frames rendered at native 4K and one rendered at 1080p that has been upscaled to 4K. Temporal Super Resolution makes it possible to achieve image quality near native 4K resolutions while reducing GPU frame time by nearly half in this shot from City Sample.





You can right-click and save each of the images in the comparison slider at their full-resolution to inspect the quality similarities.

Virtual Shadow Maps

Virtual Shadow Maps (VSM) is Unreal Engine 5's new shadow mapping method used to deliver consistent, high-resolution shadowing that works with film-quality assets and large, dynamically lit open worlds that use Nanite, Lumen, and World Partition features.

Traditional dynamic shadowing techniques have often been limited to small and medium-sized worlds, forcing designers and artists to sacrifice quality for performance. By contrast, Virtual Shadow Maps offer a single unified shadowing method that automatically applies quality where it is needed most. Shadows can now have consistent quality for small and large objects over greater distances — with realistic soft penumbra and contact hardening.

In the comparison below looking down on the cityscape, you can see the quality and consistency differences that Virtual Shadows have over Cascaded Shadow Maps. With Virtual Shadow Maps, the entirety of the city is shadowed in a consistent way from large to small detail. Small parts of the building, like the spires and equipment on the rooftops are captured in fine detail, even the cars and larger objects on the ground in the distances have shadows.

Compare that with Cascaded Shadow Maps where you must decide where in the scene you want to have that detail. Shadows maps are not well-suited for high quality detail over large areas without incurring significant performance cost. Note how shadows in the distance are not sharp and shadowing on the ground appears to just shade everything rather than individual objects.





See the Virtual Shadow Maps documentation to learn more about how to use and configure it for your own projects.

Post Processing Local Exposure

Local Exposure is a new technique developed for Unreal Engine 5 that automatically applies local adjustments to exposure — within artist-controlled parameters — to preserve both highlight and shadow detail, on top of the existing global exposure system. It's not uncommon to have scenes with challenging high dynamic ranges using dynamic lighting in which applying a single global exposure adjustment is simply not enough to avoid having blown out highlights and completely dark shadows.

In games with a dynamic time-of-day system or like City Sample where you can change the lighting dynamically, scenes can easily be under or over-exposed in parts of the rendered image. Take for example the scene below, the sun lit area is very bright and the area under the bridge, without using Local Exposure adjustments, is very shadowed. Local Exposure helps achieve more consistent results when carefully crafted lighting per-scene is not feasible, like in City Sample where players can explore the environment at will.





Procedurally Generated and Populated City

The City in the City Sample project has been designed and created with procedural generation using SideFX's Houdini software extensively to build all aspects of the city, from the shape of the city island to all the parts in between for the roads and highway, buildings, sidewalks, street furniture, and more. The "generation" of the city happens only inside Houdini using custom tools and inputs provided by the user.

The result — a huge point cloud — is exported from Houdini and imported into Unreal Engine 5 where the Rule Processor — an Unreal Engine tool developed for this project — converts the point clouds into thousands of instances.

When Epic games developed The Matrix Awakens, it was known that the project would be an open world city that would need to be fully detailed and very large. This project is using many new features of Unreal Engine 5 and at the time of its development, it was known that many other departments would be creating content and they would need to be able to simultaneously work together. The relatively small size of the environment team and the amount of detail being targeted for the project meant two things: Nanite would remove typical polygon budget limits, and modular assets would be needed that could be instanced thousands of times across the world.

Houdini is used to handle all the upfront work of generating the city shape, the road networks, connecting freeway system, building placement and provides a ton of metadata that can be used in Unreal Engine 5 to procedurally generate the final city. Using these tools in Houdini enabled an infinite number of different cities to be generated in a short period of time by the designers.

The generated city data contains all sorts of metadata that can be used by other tools in the Unreal Engine 5, including the Artificial Intelligence system that drives the traffic and crowd simulations. Buildings are constructed from a volume. The building generator uses a shape grammar language to style the building volume. Each different building style has a different set of rules. A given volume can also be split into two different styles: one for the bottom of the building and one for the remaining top section.

The City Sample project includes the source files needed to procedurally generate your own city using Houdini and Houdini Engine. You will need a license from SideFX in order to use the City Building Generator asset in the engine with Houdini. The Houdini source files are located in the CitySample root folder and are named CitySample_HoudiniFiles.zip.

The City Sample was developed using the following versions:

Houdini: 18.5.532

Houdini Engine: 3.5.2

Guided walk throughs for using these files to generate your own city with roads and freeway network will follow in the near future.

Houdini uses a node graph that flows from top to bottom. Each node is a program that executes a task on its input and outputs the result to be passed to other nodes, just like a material graph in Unreal Engine. The main city is built in stages that follow this structure:

City Layout

Roads

Freeway

Lots and Sidewalks

Traffic, Buildings and Ground

Street Furniture, Decals and Audio

Parts are built in a dependency order such that the Freeway is dependent on the Road network, and building placement requires the Freeway to be built to avoid placing buildings on top of it.

In order to build the city and support all the procedurally generated instances that make up the world, Nanite needed to be used as much as possible. It meant that a mega mesh could be built and needed to use instances to do so. Each building in the city is made up of hundreds of instances, and all props on the street, such as furniture, decals, and even trash are using Nanite. Very little custom geometry is used in the city, which ensures that the project's memory usage stays within the set budget.

However, it was inevitable that some amount of custom geometry would be required. Custom meshes are used for collisions, the freeway deck, road decals, and custom roofs for non-rectangular buildings.

Collaboratively Constructing Large Worlds

Unreal Engine 5 makes it easier to work collaboratively within your projects to manage and edit your assets and scene.

One File Per Actor

The Entire world in City Sample uses the One File Per Actor (OFPA) system. It writes a separate file for each unique instance of an Actor placed within the Level rather than writing its data into a single map file.

For developers working in the Level Editor, nothing about your workflow has changed. You can still edit a Level by opening a single map file and making your changes. However, for those who work collaboratively using a version control system, the underlying system now tracks each Actor as a separate file, meaning that designers and artists can edit different objects and layers of the same Level without encountering conflicts when committing changes.

To learn more about setting up and using this feature in your own projects, see One File Per Actor.

World Partition

Developing games with large, open worlds in mind requires dividing the map into many smaller sections that can be loaded and unloaded as the map is traversed. Loading a multi-kilometer area all at once and having it populated with objects isn't always possible. Development tools in the past have required developers to manually divide their Levels into sublevels and carefully manage when they are streamed in and out. Viewing sections of the world in context with each other could often be difficult.

The World Partition system solves this problem and simplifies the process as it automatically divides objects in the level into cells based on their grid position. The cells manage the content within them and adjust accordingly as objects are added and removed so that you never need to manually manage assets. During gameplay, World Partition automatically loads and unloads cells as you move through the world.



The Level Editor with part of the Big City loaded using World Partition.

To learn more about setting up and using this system in your own open world projects, see World Partition.

Data Layers

Where the World Partition system divides the level into cells that can be loaded and unloaded at will, Data Layers are a system within World Partition used for organizing objects into layers that can be loaded and unloaded as needed. Data Layers replace the older Layers system found in Unreal Engine 4 that required a lot of manual curation of content to manage.

The City Sample makes use of Data Layers by organizing them into different sets of objects found in the world, such as procedural ones, rooftop props, freeway, and so on. The Data Layers Outliner contains a list of all layers that contain objects found in the scene. From there, you can add, remove, or set visibility of objects using these layers.



For more information about setting up and using layers to organize objects in your scenes, see World Partition - Data Layers.

Simulating Real-World Systems

MetaHumans

The City Sample is populated with thousands of unique digital human characters adapted from a subset of MetaHumans and accessories. The MetaHuman characters are generated using MetaHuman Creator. MetaHuman Creator enables you to generate many diverse and unique photorealistic characters with consistent quality.



A crowd of generated MetaHuman characters used in City Sample and The Matrix Awakens.

The MetaHuman Creator makes it possible to design and develop film-quality characters that can be used for playable and non-playable characters (NPCs). For example, you can see in the images below that the background NPCs are consistent in quality to the playable hero character IO.



(Left to Right) City Samples playable hero character IO, Male Character, and Female Character.

MetaHuman characters come fully rigged and ready to animate. They also include their own levels of detail to balance quality with performance, making it possible to fill the city with animated film-quality characters.



City street crossing with many unique high quality characters.

Using Drone mode while in-game, you can see hundreds of crowd characters. The closest ones are fully rigged and animated MetaHuman characters, and the more distant ones are custom generated, vertex-animated Static Meshes generated from the MetaHumans.



City Sample sidewalks populated with MetaHuman characters using the Mass AI Crowd System.

To start creating your own film-quality digital humans, start using the MetaHuman Creator today. To learn more about the MetaHuman creator and how you can use MetaHumans in your own Unreal Engine 5 projects, see visit MetaHuman documentation.

Artificial Intelligence System

The Artificial Intelligence features of Unreal Engine 5 bring the city and world around it to life. Many of these features are new to the engine and are considered experimental at this time. You can dive into the City Sample and explore how they work for this project.

For more information about these features developed for Unreal Engine 5 and used in the City Sample, see the Artificial Intelligence documentation.

MassEntity provides a framework for data-oriented calculations that can be used in places where performance is key — including the simulation of thousands of AI agents in the scene, but not exclusive to the AI domain. It also ensures entities inside the world are persistent. This system is used for both the Traffic and Crowd systems in City Sample.

The Mass Spawner is an entry point to bring Mass Entities into the world. The Mass Spawner dictates two things: what type of entity is spawned and where it is spawned. The City Sample uses multiple spawners, one each for crowds, intersections, traffic, and parked vehicles.

When you select one of the Mass Spawner Actors placed in the level, the Details panel contains information about how the entities are used. The Entity Type (1) specifies what type of entity is being spawned and the Spawn Data Generators (2) specifies where it will be spawned in the world.



When specifying what should be spawned by the Mass Spawner, you should make a new asset type called the Mass Entity Definition. It dictates Traits for that entity being spawned, such as visuals, level of detail, behaviors and more.

A new Mass Entity Definition Data Asset type is used by the Mass Spawner to specify what should be spawned. This data asset dictates Traits about entities being spawned, such as their behavior, visuals, level of detail, and more.



When deciding where to spawn entities, distribution along a ZoneGraph (see next section) provided through the procedural data from Houdini is used to generate spawn points along the ZoneGraph for the Crowd and Traffic Systems to use.



Generated data used for choosing where to spawn Crowd and Traffic entities in the city.

For parked vehicles using the spawner, a point cloud of locations is generated along city streets from the procedural data.



Point cloud locations along city streets used for spawned parked vehicles.

The Mass Spawner supports many distribution possibilities for entities in the world. The example below is a visualization of the Traffic and Crowd Systems spawned throughout the world. Green represents driving vehicles, Blue are parked vehicles, and White are crowds.



Learn more about this feature by visiting Mass Entity in the Unreal Engine 5 documentation.

The ZoneGraph is a lightweight design-driven flow for AI that follows a point-by-point corridor structure. It can store meaningful tags (static and dynamic) that can be leveraged for AI behaviors.



The Zone Shape component can be added to the world from the Place Actors panel. See the Big City level's World Outliner and look for the Zone Shapes folder to see how these are being used.

StateTree is a new generic state machine with an intuitive user interface shown in a decision tree structure. The StatTree dictates the behavior of Crowds. These StateTree assets are linked directly in the Mass Entity Definition data asset of the Crowd.



You can find these StateTree assets specified in the Mass Entity Definition data asset of Crowds. The Traffic System does not run on StateTree behavior. For example, see the data asset named CrowdStateTree in the Content/AI folder.

Learn more about this feature by visiting StateTree in the Unreal Engine 5 documentation.

Smart Objects are a collection of Actors placed in a level that the AI agents and players can interact with.The system is configurable and adds an unprecedented level of interactivity to your scene.

These did not ship as part of the developed city, but you can explore them on your own in the MassCrowd test map included with the sample project.

Learn more about this feature by visiting Smart Objects in the Unreal Engine 5 documentation.

Chaos Vehicles

Vehicles in the City Sample are driven by the Chaos Vehicles System. This physics-based system enables you to set up and configure vehicles for different styles of gameplay like an arcade racer or something that provides more realistic handling.



The City Sample also allows you to drive a variety of four-wheeled vehicles, each with their own physics configuration for handling.



The Chaos Vehicle system also supports a robust deformation system using Control Rig to create unique deformations for each vehicle.



For more information about setting up and using vehicles in Unreal Engine 5, see Chaos Vehicles.

Tuning Vehicle Handling

Each vehicle Blueprint contains a Vehicle Movement Component that defines the physical and mechanical properties of the vehicle, including its engine torque, transmissions, gearing, mass, and center of mass. The Vehicle Movement Component also has an array of data-only Wheel Blueprints for the front and rear wheels. Wheel Blueprints control many of the vehicle's handling and braking properties with settings for tire friction, suspension, braking torque and more.

Vehicle data Blueprints for each vehicle are located in the Content/Vehicles/[Vehicle_Name] folder. For example, Content/Vehicle/vehCar_vehicle02.

The drivable vehicle Blueprints end with "_Sandbox" in their name, like `BP_vehCar_vehicle02_Sandbox.` These cars can be dropped in a level and are drivable.

Dynamic Vehicle Deformation

The vehicles in City Sample make use of Control Rig with the Chaos Vehicle system to apply unique deformations to each vehicle. This means that each crash is achieved dynamically by utilizing the vehicle's driving dynamics. Collisions are detected using several physics bodies placed around the vehicle's body, and constraint plasticity provides the ability for physics constraints to permanently deform after passing a specified threshold.

The vehicle Control Rig contains movable constraints that are locked along a single axis. As they are moved along that axis, they will deform part of the car's body. In the City Sample, a single Control Rig is used for all drivable vehicles to apply dynamic deformation. It is named CR_Frame_Destructible and located in the Content/Vehicle/Animation folder of the Content Browser.

Since a single Control Rig is used for all vehicles, you will want to use the Preview Mesh assignment slot to swap out different drivable vehicles to preview their deformation.



Deformation Control Rig for different drivable vehicles.

Procedural Audio and MetaSounds

In addition to all the tools that give you freedom in visuals, game mechanics, and building open worlds, Unreal Engine 5 also allows greater control over your game's audio with MetaSounds.

MetaSounds provide audio designers access to a fully featured Digital Signal Processing (DSP) graph and sample-accurate control of sound modulation and events whether you're playing pre-designed sounds or synthesizing in real-time — all of which is powered by a robust interface for reacting to game data from both code and Blueprint.

MetaSounds empower designers with production efficiency tools, like the Preset and Composition Systems that enable designers to define and reuse their MetaSound graphs. It also enables them to build a library of powerful, customized MetaSound nodes that can streamline workflows while making MetaSounds accessible across teams.

In addition to the developed MetaSounds system, the City Sample also includes experimental designs, tools, and systems for bringing procedurally generated worlds to life with sound.

Learn more about this system by visiting MetaSounds in the Unreal Engine 5 documentation.

Vehicle Audio

The drivable vehicles in the City Sample take advantage of an experimental tool called MotoSynth. It is a granular-based engine simulation tool that utilizes recordings of car accelerations and decelerations to granularly resynthesize acceleration and deceleration movement in real-time. Additionally, the drivable vehicles use MetaSounds for various decorative engine sounds, including idle loops, drifting noises, and RPM max-out sounds.





Stereo Mixer for Vehicle Sounds

MotoSynth Controls

The non-playable character (or NPC) vehicles are entirely powered by MetaSounds. They take advantage of procedural audio generation features around seeded randomization. A procedurally randomized mixture of traditional pitch-blended engine loops, synthesized filtered noise, and synthesized sub-tones are dynamically modulated based on the NPC vehicle's speed.



Music Redesign

MetaSounds are a powerful design environment, allowing designers to kit-bash and reuse existing sounds and music material.The City Sample features two remix variations reusing original music stems created for the demonstration, creating brand new variations of the music including a night-mode variant that is reminiscent of club music.



City Soundscape and Procedural Audio Generation

The World Audio Data System is an experimental suite of tools and features centered around working with procedural data propagation and design. It includes a custom Processor Rule to convert Houdini point cloud metadata and bake it down into a Soundscape ColorPoint Spatial Hashmap, and then distributing the cached hashmap data to individual Actors designed to stream in and out with World Partition spread across the 16 square-kilometer Big City.

These World Audio Data Actors contain Colorpoint caches and take advantage of World Partition Streaming to maintain a low memory footprint.



Most of the ambient sound around the city is controlled by Soundscape, an experimental state-based procedural ambient sound system. Soundscape enables designers to define spawning behavior for sounds around the Listener, including conditional spawning behavior based on ColorPoint metadata. Most of the sound that spawn in the City Sample depends on ColorPoint data cached and loaded dynamically through the World Audio Data System. This allows designers to designate which types of sounds are allowed to spawn based on spatial metadata, such as ambient highway sounds around the freeway, ambient traffic noises on large streets, and so on.

In addition to ColorPoint data, Soundscape also listens for dynamic ColorPoint data being fed to Soundscape through a Mass AI processor to keep track of the location of idling MetaHuman and NPC vehicles. The locations are used for ambient honking and MetaHuman shouts and other vocalizations. Soundscape plays a key role in making the city sound alive.



Creating Your Own Procedural City Guides

The City Sample project provides all the source files necessary to generate your own procedural city using Houdini and Unreal Engine 5.

In the first guide you will use Houdini to setup and generate procedural data used to create your own city with its own road network, freeway system, building zones, and more. The data exported from Houdini is then used in the second guide to populate and build your city using Unreal Engine tools and features.





Prerequisites for this Guide

Additional Notes about this guide

Step 1 - Required Houdini Project Setup

Step 2 - Creating a Directory for Your City

Step 3 - Starting the City Creation Process by Defining the City Shape

Step 4 - Creating the City Arteries

Step 5 - Adjusting Road Network Options

Step 6 - Draw City Zone and Adjust Cityscape

Step 7 - Drawing the Freeway Path Through the City

Step 8 - Assemble Your Inputs in the City Processor

Step 9 - Create a Freeway Connection to the City

Step 10 - Adjust the Cityscape and Buildings Volume

Step 11 - Generate the City Caches and Export Data

Step 12 - On Your Own!

The City Sample project is a technical demonstration of how you can use procedurally generated data from SideFX's Houdini Engine in Unreal Engine 5 to create a working simulated world. The City Sample uses the data generated from Houdini to populate assets, drive simulations for artificial intelligence, traffic, and audio, and much more.

This guide is part one of a two-part series that walks you through the process of creating your own city with a road network and freeway system in Houdini Engine using Epic-developed tools.

In this guide, you'll learn how to:

Access the Houdini Source files to create your own city.

Setup and configure Houdini with the provided source files.

Setup the basis for your city shape, size, and layout.

Specify zones and define the silhouette of your city.

Create a road network that supports a freeway system.

Generate all the necessary data which can be exported and ready for import into Unreal Engine 5.

Prerequisites for this Guide

SideFX Houdini

We recommend you use version 18.5.532 since it's the version used to develop the City Sample project.

You need to run Houdini once to generate the startup files necessary for the Required Houdini Project Setup.

At least 2 gigabytes (GB) of free hard disk space to extract the data and generate small-sized cities. For bigger cities, you can expect to use from 5 to 10 GB of space.

Refer to the City Sample Recommended System Specifications.

Download the City Sample Unreal Engine 5 project through the Epic Games Launcher.

Additional Notes about this guide

This guide assumes you have working knowledge of Houdini and using its tools.

The workflow and files used in this guide work with the Windows 10 operating system. While Unreal Engine and Houdini support Mac and Linux, the workflows and source files have not been tested with those systems and we cannot guarantee they will work as intended.

Step 1 - Required Houdini Project Setup

Before you can effectively use Houdini to start generating your city, you first need to set up a few things on your computer, including extracting the source files needed to complete this guide. You also need to specify and create some directories used later in this guide to store data for your city.

In the root directory where your City Sample project is saved, locate the CitySample_HoudiniFiles.zip file. It contains the Houdini source files required to complete this guide.



Create a new folder to save the source files to. For the purposes of this guide, the save location used is D:\CitySampleSource. The remainder of this guide assumes you are using a similarly named and placed folder path.

Extract the content of CitySample_HoudiniFiles.zip file to your folder. Once extracted, a folder named Small_City is added. The file path should look like D:\CitySampleSource\Small_City.



In your Windows system's Documents folder located in C:\Users{your_user_name}\Documents\houdini18.5, open the file named houdini.env with a text editor.



At the bottom of the houdini.env file, add the following new line:

Your edit should look like:



Be sure to replace the file path with the one you used while extracting the Houdini source files. Also, it is important to use forward slashes (/) in the folder path like the example above. Windows defaults to using backslashes ().

Save the houdini.env file.

Start Houdini.

Once Houdini starts, when you open the Asset Manager, you should see a list of Sample Houdini Operators. You can view them from the main menu under Asset > Asset Manager. Expand the Operator Type Libraries > Scanned Asset Library Directories to view them, they are located at the bottom where you should see a listing of .hda (Houdini Digital Asset) files from the folder path you specified in this section.



Step 2 - Creating a Directory for Your City

In this step, you will create a new folder to store city data from Houdini generated throughout this guide. This folder will also contain duplicated parts of the files included with the "CitySample_HoudiniSource.zip" so that you don't inadvertently overwrite them if you create additional cities using Houdini.

Create a new folder in your CitySampleSource folder to store the data for your city. For the purpose of this guide, the folder is named MyCity and is located in D:\CitySampleSource\MyCity.



Copy the content located in D:\CitySampleSource\Small_City\houdini to the MyCity folder. For example, D:\CitySampleSource\MyCity.

Now that you have copied the Houdini source files to your own named city folder, in the remainder of this guide you will create your own city and save it to this location.

Step 3 - Starting the City Creation Process by Defining the City Shape

In Houdini, you will create and define the shape of your city using the City Layout operator created specifically for the City Sample project. The City Layout operator takes input for the shape of your city, arterial splines used to define main through-roads in the city, and specified zones for types and heights of buildings in sections of the city.

This step has you starting by defining the shape of your city using a Houdini Geometry object and Curve.

In the Network pane, use the right-click context menu to create a Geometry object.



Double-click on the Geometry object to open its graph, and use the right-click context menu to add a Curve node.



With the Curve node selected, left-click in the viewport to place points that make up your city shape. To give you an idea of size, the Small City in the City Sample project is approximately 1 kilometer (km) wide, and the Big City is approximately 5 km wide.



We recommend using a Top view when drawing the city shape, and use a large enough area.

In the Network panel, use the right-click context menu to add a City Layout node to the graph. Connect the output of the Curve node to the first input of the City Layout node in the graph. This generates a street layout using the drawn curve points.



If the City_Layout operator is not visible in the context menu, refer to Step 1: Required Houdini Project Setup to ensure the files and paths are set up properly for your project.

Once the inputs are connected, the layout of the city is contained within the drawn curve shape. You can re-select the Curve node at any time and drag the points around until you achieve the desired shape of your city layout. The output is automatically updated in the viewport.



In the Network pane, select the City Layout (1) node in the graph. Using the text field for City Name (2), give your city a name. For the purposes of this guide, the name is "MyCity."



Click image for full size.

Save the scene to your source folder created earlier in this guide and give it a name. For example, D:/CitySampleSource/MyCity/MyCity.hip.

In this step, you took the first steps of creating your city shape with the City Layout operator. With the Curve wired in, an overlay of the city block sizes can give you an idea of the road flow within the city.

Step 4 - Creating the City Arteries

Now that you have defined the shape of your city, you can look at creating major roadways that travel through parts of your city. These roadways are referred to as arteries and you can create several to break up your city.

In this step, you will create one or more splines to define major roadways through the city, and explore the Road Network Options of the City Layout operator to ensure clean results.

In the Network pane, use the right-click context menu and add a Curve to the graph. With the Curve selected, draw two points by left clicking within the Viewport.



Connect the Curve (1) to the second input (Arterial Splines) of the City Layout (2) node.



Re-selecting the second Curve node and moving either of its two points will automatically adjust the layout of the city.

[Optional] Add additional Curves to create additional arterial splines. Wire both Curves to a Merge node, then wire the Merge node to the second input of the City Layout node. The example below uses two curves and represents what is used throughout the rest of this guide.



Click image for full size.

[Optional] Make adjustments to the shape of the city by selecting the Curve node used to define the city shape. Select its points and move them as needed.

With splines defining the major roadways and creating a more natural look and flow to your city, explore adding or moving their placement to change the dynamics of the roadways through the city. Use the City Layout properties to further explore roadway layouts within your defined city shape.



Look at adjusting the density to change the subdivision grid used as a base for creating the road lines. Adjust the angle property to create city streets that have a more natural and consistent flow.

Before moving onto the next step, ensure that your layout and road network appear without error. Adding multiple arteries or having a unique city shape could cause issues. Look for signs of issues and make adjustments accordingly.

Step 5 - Adjusting Road Network Options

In this step, you will continue refining the city by making adjustments to its roadways using the Road Network Options found in the City Layout properties. You will learn how to use the full preview mode and look at making smaller changes to merge city blocks or merging of roads near intersections to create smoother traffic flow.

In the Network pane, select the City Layout node (1). In the pane (2) above the Network pane, you can modify the details and properties of the node.



Click image for full size.

In the City Layout properties pane in the preview_options section, enable the checkbox for full preview. This property enables a more accurate preview of the network with all the clean up that happens down the graph, but it also requires more computing power thus reducing interactivity.







Click the Road Network Options tab to adjust properties of the generated road network. It is important to adjust these properties to ensure a smooth road network for traffic flow in the city by occluded intersections, or having roads that are too short or too close to one another.



Be mindful of not creating one-way roads. You should not have any through streets, and use road length minimums to ensure good traffic flow.

In the examples below, the city is using multiple arterial splines to define major roadways, effectively splitting the city into four quadrants. This includes roads that travel in different directions for each quadrant but also creates areas where multiple roads meet at intersections. Explore using the Road Network Properties to merge city blocks and city streets along the major through roads.





Road Network: Default Settings

Road Network: Adjusted Block Percent and Fuse Factor

Click images for full size.

Step 6 - Draw City Zone and Adjust Cityscape

Now that your city is taking shape with multiple arterial roadways, zones can be defined to better define your cityscape. In this step, you will learn how to define a single area using a Curve with the City Zone operator plugged into the City Layout node. The City Zone operator properties enable you to define the height using multiple points on a graph and set how that curve is represented.

In the Network pane, use the right-click context menu and add a Curve to the graph to create a zone that defines what types of buildings and structures reside in that area of the city. In the Viewport, draw an area around the city shape you want to define as a zone.



In the Network pane, use the right-click context menu to add a City_Zone operator. Wire the Curve (1) to the Zone (2) node. Wire the Zone (2) node to the third input (City Zones) (3) input of the City Layout node.



In the Network pane, select the City Zone node. Its properties are displayed in the pane above the graph.



Height defines the maximum height of the defined zone.

Point No. selects between the available points that are on the graph. By default there are only two points, one at 0 and another at 1. Automatically add points by clicking in the graph.

Position and Value moves a selected point along the X and Y-axes of the graph to define the falloff and maximum height of the zone shape.

Interpolation defines the type of curve applied to the shape relative to Position and Value

Use the City Zone properties to adjust the attributes of the zone.



[Optional] Repeat the previous steps to add additional zones and use a Merge node to wire them to the City Layout node.



With the City Layout node selected, enable preview_zones under the preview_options section to display the defined City Zones.

For the purposes of this guide, two zones are defined within the city. One that has more high-rise skyscrapers and primarily takes up one quadrant of the city and another with slightly less height split between two quadrants. Later in this guide, you will generate the building volumes that populate the city. These zones help define the look of your cityscape.

Step 7 - Drawing the Freeway Path Through the City

With most cities, there are ways to navigate around using a multi-lane freeway that bypasses pedestrians, crosswalks, and intersections with traffic lights. The City Sample provides tools and operators to set your own freeway path or loop that contains entry and exit points.

In this step, you will learn how you can add a freeway path to your own city with entry and exit points that connect to the arterial roadways (red) using a Curve and Freeway Util Curve Attribute operator.

In the Network pane, use the right-click context menu to add a Curve node. In the Viewport, click points where you want the freeway path to go.



Optionally, you can use Polywire and Merge nodes to better visualize the freeway path over the city layout. With the Polywire node selected, use the properties to set the Wire Radius to a high enough value that it makes the path easy to see.



Use the right-click context menu to add a Freeway Util Curve Attribute operator to the graph.



With the Freeway Util Curve Attribute node selected, there are two properties you can modify:



Number of Lanes: You can set it to 4 or 6 lanes.

Closed: Enable the checkbox for any freeway path you want to be a closed loop.

When choosing a freeway path that does not loop on itself, ensure its bounds connect to the arterial roadways (red) and that it runs within the continuity of the road.

Once you have finished setting your freeway path or loop, you can remove the Merge and Polywire nodes from the graph, as they are for visualization and are no longer needed. Wire the Curve node to the Freeway Util Curve Attributes node to finish the set up.



With the Freeway Util Curve Attributes operator, you can create multiple freeway paths and decide whether to use a closed loop or path with their own entry and exit points to the city streets below. When creating your own city, explore using different numbers of lanes and connection points to the freeway from various parts of the city.

Step 8 - Assemble Your Inputs in the City Processor

Now that you have done a lot of the foundational work for your city, defining its shape, setting up its roadways and freeway system, it is time to assemble your work using the City Processor operator. This is where all this data you have compiled and set up over the previous steps in this guide starts to come together with the various zones, freeway, arterial roadways, and so on.



Set Houdini to Manual mode using the selection box in the bottom-right of the editor window. By default, Houdini is set up to cook content automatically. In this instance it is better to delay cooking this content until all inputs have been connected.



In the Network pane, use the right-click context menu to add a City Processor operator.

Wire the second output of the City Layout node (1) to the first input of the City Processor node (2).



You can ignore the warning on the City Processor node as it will be resolved in the next step.

Wire the Freeway Util Curve Attributes node (1) to the second input of the City Processor node (2).



Set Houdini back to Auto Update mode, which triggers the City Processor node to cook the input data.



Re-enabling Auto Update mode triggers processing of the City Processor, which can take several minutes to complete.

Once processing completes, you can preview your generated city based on all the input data from the previous steps.

In the example below, you can see how the freeway way path is placed throughout part of the city, the two arterial roadways stretching across the city, the multiple quadrants with city streets flowing in different directions, and the two defined zones, one with taller buildings and the other with a gradual increase in size but not quite as tall.



Step 9 - Create a Freeway Connection to the City

Now that the city has been processed and takes into account the various data from city operators, the freeway needs to connect its path to the city streets below.

In the Network pane, double-click on the City Processor node to open its network graph, then access the Freeway part of the graph.



Click image for full size.

In the graph in the commented (blue) section named FREEWAY OUTPUT, look for the FREEWAY node. Right-click it and select Allow Editing of Contents from the context menu.



Click image for full size.

Double-click to open the FREEWAY node to see its network of nodes. Look to the left side under the blue notes called Process Freeway, Connections and Ramp for the connections_blank node.



Click image for full size.

Double-click the connections_blank node to access its network of nodes. Locate the all_connections node and double-click it to open its graph.



Click image for full size.

Click Display on the ROAD_REFERENCE node.



Hold Ctrl and select the ROAD_REFERENCE and merge_freeway nodes. Click Display Template (pink) on the nodes.



In the graph, select the connection_set_1 node and in its properties window, enable Preview Mode for faster feedback while making edits.



In the properties window, click the plus (+) button next to the Connections property. This adds a curve used to connect the freeway path to a street.



Click image for full size.

Click Edit Curve 0.



With the Handle tool enabled, click two points: one close to the freeway path and the second on the street you want to connect to. You can make adjustments to the two points by holding Ctrl + left-click for street connections, or holding Shift + left-click for freeway connections.



Ensure the streets and connections have the same number of lanes. Change this using the Number of Lanes slider for the added Connection curve.

When clicking the final point in place, you should see a result similar to the image below.



Repeat the steps above to add additional entry and exit ways to the freeway path as needed.

In the graph, select the connection_set_1 node, and in its properties window, disable Preview Mode once you've completed connections to the freeway.

The connection_set_1 properties provide various settings to adjust how the freeway connects to the streets below. You can explore the available properties when adding a new Connection element to the array. Look at the Interpolation, Elevation, and Banking properties to make adjustments to how the connection meets the street.



Step 10 - Adjust the Cityscape and Buildings Volume

The City Processor enables you to control different aspects of how the city is generated for export later in this guide. The City_Lot_Processor operator provides properties for both the lots and the buildings that fill them. Their respective properties enable you to define different attributes related to size, setbacks for sidewalks, style of buildings, variation beyond default settings, and so on.

In this step, you will learn where these settings live and make adjustments as you see fit. You are encouraged to try out different settings to create different styles and variations using these properties.

In the Network pane, open the City Processor node. In its network graph, examine 3. LOTS (orange) and select the City_Lot_Processor node (yellow circle).



Click image for full size.

With the City_Lot_Processor node selected, look at the properties pane where you can select the LOTS and BUILDINGS tabs.



You can use the City Lot Processor properties to make adjustments to the lots and buildings generated. For lots, this includes lot size, removal distance from the freeway, and consideration for sidewalks. For buildings, you can define their style, height, and size.

Explore the settings found in each of these panels and try out different variations for your own city.

Changing these properties causes the buildings volumes and lots around the city to regenerate. Each change will complete its regeneration before another than can be made. If your city is large, it can take more than several minutes to complete the regeneration process.





City Lot Processor Properties: Lots

City Lot Processor Properties: Buildings

Step 11 - Generate the City Caches and Export Data

In this final step, you will use the City Processor properties pane to set whether you want to use the Procedural Dependency Graph (PDG) with selected processing options for some part. Doing so will generate and export the necessary data which you can later import into Unreal Engine 5 to create your city there.

Set Houdini to Manual mode to delay the regeneration process when making changes to the City Processor node.



In the Network pane, select the City Processor node.

In the City Processor properties pane, choose whether to generate the city caches and export data using the PDG by adding or removing the checkbox next to use PDG.



PDG is used to improve the processing speed, depending on your machine and number of processes. Consider the following:

With PDG, there are three sub-steps that need to be processed. Click the processes for process city base, PDG process, and process city furniture. PDG processing happens at the building generation stage and is especially useful when the city is large because it parallelizes the building generation that requires the most computing power.



Without PDG, click process city without PDG to generate the different caches.



Once processing is complete, do the following based on the state of use PDG:

If enabled, click EXPORT ALL PBC to export the geometry and the Point Cloud Alembics (PBC).



If disabled, first use the Caches and Exports tab to ensure that the results you are seeing are read from disk. At the bottom, under the geometry and pbc export section, click EXPORT ALL PBC.



In this final step, you now have processed and exported all the data necessary to move onto the second part of this series of guides where you can import your city's Houdini data into Unreal Engine using the City Sample project.

Follow along with the City Sample: Generating a City and Freeway in Unreal Engine 5 to complete development of your own city and see it come together in Unreal Engine.



Step 12 - On Your Own!

Now that you've finished generating all the data and files necessary to fully realize your city in Unreal Engine's City Sample project, there are plenty of things that you can continue to explore using the procedural tools developed by Epic Games for the Houdini Engine to generate a city.

Below are some suggestions you can explore on your own:

Revisit Step 3 and explore creating various shapes and sizes for your city with different spline shapes.

Revisit Step 4 and add multiple arterial roadways to your city. Use these to create interesting shapes and zones for your city.

Revisit Step 5 and explore the settings within the City Layout node. You can experiment with changing settings under the City Layout Options, Road Network Options, and Road Network Sizes for your city.

Revisit Step 6 to set up and draw different zone types around the city. This is useful for creating areas with high rise buildings, and areas with moderately sized buildings. Use the Zone Shape graph to define the shape of the curve for each zone.

Revisit Step 7 to experiment with different types of freeway layouts, such as drawing multiple freeways and having a closed loop freeway. This guide only demonstrates a single linear freeway. Use the Freeway Util Curve Attribute node to set whether the freeway should be closed and try using multiple connected freeways that use four and six lanes.

Revisit Step 10 and look at the City Lot Processor properties where you can experiment with different Lot and Buildings settings. For Lots, you can set distances that lots should be from freeways, their minimum size, control how sidewalks are affected, and more. For Buildings, you have finer control over building heights, lot size between roads, applying a noise amount to vary building sizes outside of specified zones set up in Step 6, and much more. Experiment with different settings but be aware that each change will be automatically processed and updated in the Houdini viewport, which can take a few moments to several minutes to complete.

Prerequisites for this Guide

Additional Notes about this guide

Step 1 - Project Setup and Configuration

Step 2 - Importing the City Data into Unreal Engine 5

Step 3 - Preparing an Open World Level

Step 4 - Running the Rule Processor Generation

Step 5 - Setting up Point Cloud Data for the Zone Graph for Traffic

Step 6 - Running the Zone Graph Generation for Traffic

Step 7 - Generate World Partition HLODs for Your City

Step 8 - End Results

The City Sample project is a technical demonstration of how you can use procedurally generated data from SideFX's Houdini Engine in Unreal Engine 5 to create a working simulated world. The City Sample uses the data generated from Houdini to populate assets, drive artificial intelligence simulations, audio simulations, and much more.

This guide is part two of a two-part series that walks you through importing data which you generated in Houdini Engine into Unreal Engine 5.

To complete this part of the guide, you must have first followed City Sample - Generating a City and Freeway using Houdini.

In this guide, you will learn how to:

Import data you generated from Houdini Engine into Unreal Engine 5.

Prepare an open world environment to support your city.

Use the Rule Processor to import Houdini procedural data to generate your city.

Use the point cloud data with Zone Graph for Traffic simulation.

Generate Hierarchical Level of Detail meshes for World Partition.

Prerequisites for this Guide

Completion of City Sample - Generating a City and Freeway using Houdini

SideFX Houdini

We recommend using version 18.5.532 since it's the version that was used to develop the City Sample project.

At least 2 gigabytes (GB) of free hard disk space to extract the data and generate small-sized cities. For bigger cities, you can expect to use from 5 to 10 GB of space.

Refer to the City Sample Recommended System Specifications.

Download the City Sample Unreal Engine 5 project through the Epic Games Launcher.

Additional Notes about this guide

The workflow and files used in this guide work with the Windows 10 operating system. While Unreal Engine and Houdini support Mac and Linux, the workflows and source files have not been tested with those systems and we cannot guarantee they will work as intended.

This guide also assumes you have knowledge of Windows operating systems when using something like Command Prompt.

Step 1 - Project Setup and Configuration

Before you can use your own city's data you generated while following the City Sample: Generating a City and Freeway using Houdini guide, you'll first need to open and set up a few things in Unreal Engine 5.

Open the City Sample project with Unreal Engine 5.



In the Content Browser under the Content > City, create a folder with the exact same name as the city you created in Houdini. For example, the sample Houdini city file you created in Part 1 was named "MyCity". Therefore, name the folder you create in the Content Browser MyCity.



Open your named city folder and create two new folders named Geometry and PBC.



The City Sample project includes the Houdini Engine Plugin, which is already enabled. From the main menu, open the Houdini Engine dropdown menu and select Create Session.



If a session cannot be created, check the Output Log for additional context as to why it failed to do so.

At this point, you have opened the City Sample project and created folder locations to import the data you generated in Houdini for your own city. You have a new folder named for your city, and two folders within it named Geometry and PBC.

Step 2 - Importing the City Data into Unreal Engine 5

With your own city's folders created and a Houdini Engine session started in the previous step, you can now import your data into Unreal Engine 5.

In Windows, open the file location where you saved your Houdini city data. In the first part of the Quick Start Guide for Generating a City and Freeway using Houdini, you set the folder path as D:/CitySampleSource/MyCity.



Inside the Windows MyCity folder, open the PBC folder. In Unreal Engine, use the Content Browser to open the City > MyCity > PBC folder. Select all the files in the PBC folder in Windows and drag them to the PBC folder in Unreal Engine.

Once the import process completes, your PBC folder should look like the one below with the imported point cloud data generated by Houdini.



Inside the Windows MyCity folder, open the EXPORT folder. In Unreal Engine, use the Content Browser to open the City > MyCity > Geometry folder. Select all the files in the EXPORT folder in Windows and drag them to the Geometry folder in Unreal Engine.

This video has been sped up to show the full import process of a smaller city created in Houdini being imported. The import process can take some time depending on the size of your city. For example, the cities included with the City Sample project can take less than 10 minutes for the Small_City to import and upwards of 40 minutes for the Big_City to import.

Use the File menu to Save All.

At this point, you should see all your geometry and point cloud data files have been imported and saved as assets in the folders you created in Step 1 of this guide. These assets are used in the steps that follow to start generating your city.

Step 3 - Preparing an Open World Level

In this step, you will create a new level from a templated City Open World level. This template level provides a starting point for creating your own city like the one from City Sample, with its own lighting and skybox set up and Blueprint spawners used to populate data.

Using the File menu, select New Level (1). Choose City Open World Empty (2) from the available templates and click Create (3).



Once the new level has been created, use the File menu to Save Current Level As (1). Save the map in the Content > Maps (2) folder and enter the Name (3) of your city into the text field. For example, this guide uses MyCity as the level name.



Click Save in the Save Level As window.



You now have a level that you can use to generate and build your city.



Step 4 - Running the Rule Processor Generation

All the data needed to start generating your city has been imported into the engine and you have a map with which to load and save it. In this step, you'll use the Rules Processor for the City and Freeway point cloud data you imported into the engine. The Rules Processor maps the generated point cloud data from Houdini Engine to rules that tell Unreal Engine how to use that data to populate the world.

From the main menu, use Window > Rule Processor to open RuleProcessor_City. This opens the window where the files you generated in Houdini will be used to generate the city in Unreal Engine.



Click image for full size.

In the RuleProcessor_City window, replace the Point Cloud column's assigned assets with ones of the same name from the City > [YourCityName] > PBC folder. For example, this guide uses the files imported in Step 2 located in the City > MyCity > PBC folder.

In the RuleProcessor_City window, click Run Rules to process your imported city files.



A pop-up window asks you to confirm the processing. When ready, click OK.



The time it takes to generate your city can vary based on the size of your city. It can take 15 minutes to an hour to finish processing.

Repeat the process for the Freeway PBC files located in the PBC folder. From the main menu, use Window > Rule Processor to open Rule Processor_Freeway. Replace the Point Cloud column's assets with ones of the same name from the City > [YourCityName] > PBC. For example, this guide uses the files imported in Step 2 located in the City > MyCity > PBC folder.

In the RuleProcessor_Freeway window, click Run Rules to process your imported freeway files.



A pop-up window asks you to confirm the processing. When ready, click OK.



The time it takes to generate your city can vary based on the size of your city. It can take 15 minutes to an hour to finish processing.

In the World Partition panel, left-click and drag to select all the cells in the world partition map. Right-click and select Load Selected Cells.

Using the Rule Processor for the City and Freeway point cloud data provides Unreal Engine with information to generate your city based on sets of rules. This lets the engine place assets to build out the city.

Once the Rules Processor has completed processing the data, the city can be loaded into the Level Viewport using the World Partition Editor. Once loaded, you can fly out and inspect your city.



Step 5 - Setting up Point Cloud Data for the Zone Graph for Traffic

Now that you have a city you can work with, there are two Blueprint Spawners included with the level that configure and set up the city. This means you need to duplicate some Data Assets used with the Small City for your own city. These data assets rely on point cloud data you imported.

In the Level Viewport, use the Show dropdown menu to ensure that Navigation is enabled.



In the Content Browser, navigate to the Content > AI > Traffic folder.



In the ParkingSpaces folder, make a copy of the CitySampleSmallCityParkingSpaces Data Asset. Rename it, replacing "SmallCity" with the name of your city. For example, this guide uses CitySampleMyCityParkingSpaces.



Open the CitySampleMyCityParkingSpace Data Asset. In the Parking Spaces Point Cloud assignment slot, replace City_cars_parked with the one of the same name found in your city's Content > City > [YourCityName] > PBC folder. This guide uses Content/City/MyCity/PBC.



Return to the folder Content > AI > Traffic.

In the TrafficLights folder, make a copy of the CitySampleSmallCityTrafficLights Data Asset. Rename it, replacing "SmallCity" with the name of your city. For example, this guide uses CitySampleMyCityTrafficLights.



Open the CitySampleMyCityTrafficLights Data Asset. In the Traffic Lights Point Cloud assignment slot, replace City_traffic with the one of the same name found in your city's Content > City > [YourCityName] > PBC folder.



In the World Outliner, enter "Builder" into the Search text field (1). This returns both the CityTrafficBuilder_BP and FreewayTrafficBuilder_BP Blueprints. Next to each of these line items, hover over each of them and click the Pin (2) icon next to their names to force them to load in the Level for purposes of editing it.



With the CityTrafficBuilder_BP loaded, select it in the World Outliner (1). Use the Details panel to replace the existing point cloud data with the one you imported for your city. Under the section named Mantle, assign your City_traffic point cloud data to the Epic Intersections Mantle Point Cloud** assignment slot (2).



Click image for full size.

With the FreewayTrafficBuilder_BP loaded, select it in the World Outliner (1). Use the Details panel to replace the existing point cloud data with the one you imported for your city. Under the section named Mantle, assign your Freeway_traffic_data point cloud data to the Epic Freeway Mantle Point Cloud assignment slot (2).



Click image for full size.

In the World Outliner, search for and select BP_MassTrafficIntersectionSpawner (1). Use the Details panel and locate the Traffic Light Instance Data (2) assignment slot found under Mass > Spawn Data Generators > Index [0] > Generator Instance > Traffic Lights. Replace the Data Asset with the one you created earlier in this part of the guide named CitySampleMyCityTrafficLights**.



Click image for full size.

In the World Outliner, search for and select BP_MassTrafficParkedVehicleSpawner (1). Use the Details panel and locate the Parking Spaces (2) assignment slot found under Mass > Spawn Data Generators > Index [0] > Generator Instance > Entity Type to Parking Space Type. Replace the Data Asset with the one you created earlier in this part of the guide named CitySampleMyCityParkingSpaces**.



Click image for full size.

You should now have two Data Assets that are duplicates of the Parking Spaces and Traffic Lights ones used with the Small City. In these Data Assets, you have assigned your own city's point cloud data for use in the next section for Zone Graph Generation.

Step 6 - Running the Zone Graph Generation for Traffic

At this point, you have created some Data Assets to use with the various Blueprint Spawners found in your city level. You've assigned some of the generated point cloud data from Houdini Engine to these Spawners through the Data Assets.

In this step, you will use an Editor Utility Widget made specifically for performing tasks of generating a Zone Graph for lanes of traffic using the point cloud data you assigned to Data Assets and Blueprint Spawners in the previous section.

In the Content Browser, navigate to Content > AI > ZoneGraphBuilder. Right-click on the Editor Utility Widget named WBP_CitySampleZoneGraphBuilder and click on Run Editor Utility Widget.



Click image for full size.

In the Editor Utility Widget window, click both buttons for Build Zone Shapes next to City Traffic Builder (1) and Freeway Traffic Builder (2), then click Do All The Things! (3).



In the Content Browser, navigate to the Content > AI > Traffic > ParkingSpaces folder. Open the CitySampleMyCityParkingSpaces Data Asset.



In the Parking Spaces Point Cloud assignment slot, replace the City_cars_parked (1) with the one from your city's Content > City > [YourCityName] > PBC folder, then click the Populate Parking Spaces from Point Cloud (2) button.



In the Content Browser, navigate to the Content > AI > Traffic > TrafficLights folder. Open the CitySampleMyCityTrafficLights Data Asset.



In the Traffic Lights Point Cloud assignment slot, replace the City_traffic (1) with the one from your city's Content > City > [YourCityName] > PBC folder, then click the Populate Traffic Lights from Point Cloud (2) button.



Once you have run the Zone Graph Editor Utility Widget and populated the data from both the Parking Spaces and Traffic Lights Data Assets, you can now visualize the navigation that is generated from that data inside the Level Viewport. If you do not see the navigation data (like below), use the Level Viewport's Show menu to ensure that Navigation is enabled, or press the hotkey P to toggle it on and off.



Step 7 - Generate World Partition HLODs for Your City

An important part of building your city — no matter its size — is that it likely has parts that need to be seen from far distances. The World Partition system handles far distances through Hierarchical Level of Detail (or HLODs) that can combine many objects into single, large Actors that can be streamed in and out dynamically. See World Partition - Hierarchical Level of Detail to learn more about them.

For your city, the next step is to generate your own HLODs that can be streamed in and out dynamically using World Partition. The size of your city can contribute to how long it takes for HLODs to be generated for your level. You can use the in-editor tools to do this through the Build menu, or by closing the project and using a Windows Command Prompt to do so, with the latter method taking less time.

Using Windows Command Prompt with Command Line Arguments

In Windows, open a Command Prompt window.

Enter the following command into window, accounting for your own project's folder location:

Press Enter to start the process.

The command line arguments are set up as follows:

The engine file path to the UnrealEditor-Win64-DebugGame-Cmd.exe

The file path to the CitySample project. If the project is located in the Engine directory, you can use just the name of the project.

The map file you want to open.

The remaining command arguments to run World Partition and build HLODs.

Using In-Editor Tools to Build HLODs

From the main menu, click Build and select Build HLODs from the menu.



Save your Level.

While working in the Level Editor, you may not notice anything has changed. This is because when you work with World Partition to edit the level, you are choosing what cells from the World Partition Editor to load in. However, if you were to Play-in-Editor (PIE) or Simulate prior to building the HLODs, you'd have seen that only objects within a certain distance are loading in. Anything beyond that distance is empty and not loaded for performance reasons.

Once HLODs are built, they are dynamically loaded and unloaded by World Partition during PIE and Simulate modes. In the examples below, if HLODs are not built, you'll only see parts of the city loaded near the camera within a set range. However, once HLODs are built, World Partition will load the HLODs for anything beyond the set range.





Before Building HLODs

After Building HLODs

Step 8 - End Results

In this final step, you'll place a Player Start in your City level where you want to spawn in when you launch the game.

Find a location in your city you want to designate as a starting location when you use Play-in-Editor (PIE) to launch the project.

Right-click in the Level Viewport near the ground and use the context menu to select Place Actor > Player Start.



Depending on where you clicked in the scene, your placed Player Start may be intersecting another object or above the ground. Move the Player Start so that it doesn't display any error messages, such as "Bad Size."



Left, good Player Start placement; Right, bad Player Start placement.

Using the Level Viewport controls, press the Play-in-Editor button.



The first time you play-in-editor or simulate can take a moment to load. Subsequent times will load more quickly.

At this point, you should have a city that you've successfully built using the source files provided for Houdini Engine for you to build a procedural city and be able to import and set it up in Unreal Engine 5. You should also be able to explore and play through your own city, similarly to how Small City and Big City have been set up.

DMX Overview

Getting Started

Viewing the Show from Multiple Perspectives

Show Playback Controls

Disable Cinematic Camera

Modifying the Show in Real-Time

Changing Spotlight Distance

Adjusting Beam Quality

Changing Catwalk Cell Count

Exporting Media with Movie Render Queue

Live Event Previs Project File Structure

Content Browser

World Outliner

Fixtures and Hardware

Fixtures

Lighting Console

DMX

Plugins

The DMX Previs sample is a fully-animated digital light show using the DMX plugin in Unreal Engine. This sample was created in collaboration with Moment Factory to show an example of live event previsualization that is as close as possible to the real-life technical counterpart. To leverage Unreal Engine's rendering capabilities and to showcase the newly developed proxy fixture system, the sample features a complex lighting rig that fills the entire open space.

This video shows repeated, flashing lights at certain points that may cause discomfort or potentially trigger seizures for people with photosensitive epilepsy. Viewer discretion is advised.

Exploring and modifying this sample will help you learn how you can:

Use the DMX plugin Sequencer integration to record and play back an entire live event show programmed on an external lighting desk.

Use the extensible fixture system to create your own DMX-enabled virtual twins to real hardware devices.

Customize and tweak your fixture's rendering functions for both real-time previs and high-quality media export.

This project is both CPU-intensive for DMX Track playback in Sequencer and GPU-intensive for high-quality volumetric beam rendering. See the Fixtures and Hardware section for details on the hardware specifications used for this project.

Getting Started

Download the DMX Previs sample project from the Epic Games Launcher under the Learn tab.

Open the project in Unreal Engine.

Press Play to view the previs sequence.



To view the show with optimal performance, build the project with the Shipping configuration.

Follow these steps to set the project's build configuration to Shipping:

In the Editor's main menu, choose File > Package Project > Build Configuration, and select Shipping.

Choose File > Package Project > Windows to package the project with the Shipping configuration.



Viewing the Show from Multiple Perspectives

After opening the project and pressing Play in the Editor, the sequence begins with the cinematic camera view.

To view the show from other perspectives in the virtual auditorium, you can switch camera views with the playback controls defined in the project's Level Blueprint or disable the cinematic camera in Sequencer. Both methods are described below.



Image courtesy of Moment Factory.

Show Playback Controls

Once the Unreal session has started, you can use the following playback controls:

Key

Description

F9

Show the FPS counter, in both Standalone and Shipping builds.

Space Bar

Pause or resume the sequence and the DMX playback.

T

Toggle between cinematics and freecam. In freecam mode, you can move the camera to get a closer look at the light fixtures and view the show from other angles.

V

Cycle between predefined cinecamera views.

R

Restart the sequence and DMX playback.

Escape

Exit the session.

Disable Cinematic Camera

You can cycle through freecam and cinematics using the T toggle key. Press V to cycle between predefined camera locations. Follow the steps below to completely turn off the cinematic camera during the show.

In the Content Browser, open DMXPrevis_Animations in Content > Sequences.



In the Sequencer window, right-click on the Camera Cuts track and select Mute from the options.



Press Play. You will be able to move the camera freely and view the show from different angles.

Modifying the Show in Real-Time

During DMX track playback in Sequencer, it's useful to be able to modify the show as you are viewing it. This section describes how to change the look and feel of some of the light fixtures.

The project contains more assets than the ones described in this section. Explore all the light fixtures in the project; each type has its own Blueprint and functionality.

Changing Spotlight Distance

Follow these steps to modify the light distance value of some of the lights. Decreasing this value can help to improve performance during playback; increasing the value creates more volumetric beam effects.

In the World Outliner, type Spot in the search bar and select all the filtered assets.



In the Details panel, change the Light Distance Max property value from 5000.0 to a smaller value for better performance or a higher value for increased volumetric effect.





Adjusting Beam Quality

All the fixtures used are specifically customised for the project and have adaptive quality logic for balancing speed and quality in real-time. The logic for adaptive quality is defined in the M_Beam_Inhibitive_Master Material, located in Content > DMX > FixtureMaterials.



This Material dynamically adjusts the volumetric beam shader sample counts as a function of the live DMX Zoom angle.

The wider the beam is, the lower the sample count to retain high performance with minimal visual impact.

The narrower the beam is, the higher the sample count for increased beam sharpness.

You can adjust the quality settings in the Material Editor for the M_Beam_inhibitive_Master Material. The settings are located in the Parameter Defaults panel.



Low Quality Level: Defines the lowest possible multiple for the predefined sample count.

Max Quality Level: Defines the highest possible multiple for the predefined sample count.

Use MRQ Override: Forces a specific multiplier for all fixture material and material instances regardless of the low and max values set. This property is useful to set when exporting high quality videos or image sequences of the project.

Zoom Based Intensity: When enabled, the light function can lower in intensity when the zoom is wider but be closer to the intended brightness when the zoom is narrower. This mimics the behaviour of real lights where the brightness on any given surface is lower when the beam is wider.





In the left image, the Max Quality Level is set to 1 creating grainier beams. In the right image, the Max Quality Level is set to 5 so the beams appear sharper.

Quality Levels set to values greater than 1 are meant for offline renderings using Movie Render Queue. For this project, the Quality Level was typically set to 2 for both Low and Max Quality Levels to generate footage.

Changing Catwalk Cell Count

Follow these steps to change the cell count for the DMX Fixture Matrix used in the Catwalk.

In the project's Content Browser, double-click the DMXLib_v4 asset to open the DMX Library Editor.



In the Fixture Types tab, select CatwalkStrip under Matrix/Pixel Bar. This example is going to modify its Mode Properties.



In the Mode Properties panel, change the Y Cells property value from 5 to 20.



In the World Outliner, select all the CatwalkStrips assets.

In the Details panel under the DMX Matrix Fixture section, click Generate Preview Mesh to update the mesh in the viewport with the changes you made in the DMX Library.



In the viewport, all the CatwalkStrips now have more cells.





Exporting Media with Movie Render Queue

In a typical live event previs workflow, designers and artists will work at lower quality levels for quicker iterations. For review purposes, it's useful to render high-quality image sequences or Apple ProRes files.

This sample includes two presets for Movie Render Queue to generate high-resolution media. The presets are located in Content > Cinematics > MoviePipeline > Presets. The two presets have different resolutions:

UHD: Preset for Ultra High Definition (3840x2160) export to Apple ProRes 422 HQ.

FHD: Preset for Full High Definition (1920x1080) export to Apple ProRes 422 HQ.



Follow these steps to export high quality media using Movie Render Queue.

In the project's World Outliner, select all the spotlights and set their Light Distance Max property to 12,000.



In the project's Content Browser, navigate to DMX > FixtureMaterials.

Open the M_Beam_Inhibitive_Master Material in the Material Editor.

In the Parameter Defaults panel of the Material Editor:

Set Low Quality Level to 2.0.

Set Max Quality Level to 2.0.



Close the Material Editor.

In the main Editor, choose Window > Cinematics > Movie Render Queue to open the Movie Render Queue window.



Press the Add Render button and select the DMXPrevis_Animations Level Sequence.



Under the Settings column, click the dropdown arrow and select the desired preset, UHD or FHD.



Click Render (Local) to export the rendered frames locally.



You can set the MRQ Override parameter in M_B_Inhibitive_Master to 1.0 in order to override the Low and Max Quality Levels.

Live Event Previs Project File Structure

This sample project includes a variety of assets to recreate an auditorium and full light show with DMX. To help you explore everything in the project, see the descriptions of all the folders below.

Content Browser



The Content folder contains the following sub-folders:

Assets: General project and level assets for the stage and auditorium.

Audio: The show soundtrack.

Blueprints:



Cinematics: Movie Render Queue settings for Ultra High Definition (UHD) and Full High Definition (FHD) offline renders.

DMX: All DMX-related content.

Disks: Project-specific DMX fixture gobos, which control the shape and pattern of a light. A given light can have multiple gobos throughout the show and can be animated.

EffectTables: Defines the effects for the DMX-enabled light types used in the project.

FixtureMaterials: Project-specific and optimized DMX Fixture materials. This is an extension of what was shipped with the DMX plugin.

FixturesBP: Project-specific Lighting Fixture blueprints. This is an extension of what was shipped with the DMX plugin.

GoboWheel: Same as the contents of the Disks folder but as separate textures.

Plugins: Useful DMX tools and widgets.

SpecialFXBP: Project-specific pyro, laser, and fireworks fixture assets. It also contains the DMX-controlled sphere that is in the middle of the stage.

DMXLib_v4: The project core DMX library, which contains all the Fixture definitions, Universes, and patching.

Effects:

Bloom: Project-specific, high-quality, convoluted bloom Texture without streaks.

Fireworks: Project-specific fireworks Blueprints and Niagara particle system.

Flash: Audience cell phone lights and Niagara particle system.

RockLevitation: Levitating rock Niagara particle system.

WaterMaterials: High-quality water materials for the project.

Maps: Different parts of the level are contained in their own separate maps:

Main: The persistent level that contains the sequencer track, post-process volume, and soundtrack.

DMXControlled: This level contains all DMX-controlled elements, lighting fixtures, and effects.

Terrain: This level contains the terrain and rock formation.

Venue: This level contains the venue and structural-related actors, such as the arena, audience, and trusses.

MegaScans: Quixel MegaScan assets used for terrain and environment.

Movies: Contains Media Framework assets for movie playback.

Clock_LED: Contains the image sequence for animating the Clock LED that surrounds the catwalk.

Drapes: Contains the image sequence for the drapes' video projection.

MSPresets: MegaScan preset assets.

Sequences: Contains the Level Sequence.

Showfile: The showfile (.zip) from the grandMA2 lighting console. You can uncompress the file and use it on your console.

Splash: The project's splash image when it loads in the Unreal Editor.

Tropical_Jungle_Pack: The asset pack used for the environment.

World Outliner

Explore all the assets in the World Outliner, especially the following items and folders:

Cams: The list of cameras used by Sequencer cinematics and predefined camera locations.

DMX_FX and DMX_LX: DMX-controlled fixtures and effects.

DMXPrevis_Animations: The Level Sequence that drives the show, soundtrack, and DMX track.

Fixtures and Hardware

This sample was designed to use the following fixtures and hardware.

Fixtures

Fixture Name

Fixture Type

Quantity



Lighting Fixtures



Audience Strip - No pixels

Custom LED

50

Audience Wash LED Par

Elation SixPar 300

12

Catwalk Strip - 5 pixels

Custom LED

20

Matrix Strip - 5 pixels

Custom LED

32

Scenic Wash LED Par

Elation SixPar 300

14

SpotMH1

Elation Proteus Maximus

64

SpotMH2

Robe Megapointe

94

Strobe RGB

Elation Protron 3K LED Strobe

122

Stage Strip - 5 pixels

Custom LED

24

Sun Strip - 5 pixels

Custom LED

90

Truss Toner

Elation SixPar 300

220

WashMH1

Ireos Space Canon

8

WashMH2

GLP X4

16

Vomitory LED Par

Elation SixPar 300

2

Total Lighting Fixture Count

768



SFX Fixtures



Fireworks

N/A

8

Laser RGB

N/A

6

Pyrotechnic Launcher

N/A

33

Total SFX Fixture Count

47

Lighting Console

Hardware

Quantity

grandMA2 light

1

MA Lighting NPU

1

DMX

Specs

Description

Channels

7368

DMX Universes

15

Protocol

Art-Net

Unique Cues

144

Timecode Sync

MIDI

Plugins

The following plugins provide the core functionality shown in this sample:

DMX Engine

DMX Fixtures

DMX Pixel Mapping

DMX Protocol

Level Sequence Editor

Movie Render Queue

In-Camera VFX

Rendering to Multiple Displays with nDisplay

Level Snapshot

GPU Lightmass Global Illumination

Stage Setup and Hardware

Getting Started

mGPU and Multi-Screen Cluster

Remote Control

Using Remote Control

Designing the Web Application

Color Grading and OCIO

GPU Lightmass and Multi-User

Level Snapshots

Filtering with Level Snapshots

Using Presets with Level Snapshots

Project Structure

Assets

Environments

Environment Structure

OCIO

Stage Levels

Stages

NantStudios

Simple Nant Studios

Tools

Cvars

The In-Camera VFX Production Test is a Virtual Production sample that uses Unreal Engine and an LED Volume to feature traveling vehicle shots, multi-camera setups, and multi-user setup for making quick changes between takes. This sample was created in collaboration with filmmakers' collective Bullitt. The team produced final pixels in-camera over four days on Nant Studios' LED stage in Los Angeles.

The short produced from the project.

Exploring and modifying the sample will help you learn how you can:

Structure your Virtual Production project so multiple artists can collaborate simultaneously on scenes during production.

Use GPU Lightmass with Multi-User to bake lighting on one computer and share to all computers in the session for faster lighting changes.

Render the inner frustum using mGPU on a multi-screen nDisplay cluster.

Apply color correction and OCIO profiles to your nDisplay renders to achieve the desired look for each scene.

Build the UI of your Remote Control Web Application to meet your production's needs and make quick changes on set from a tablet.

Apply cvars to improve performance in the project.

This guide covers how the production team used Unreal Engine's features in the project to make the final result. Use this project as an example for designing your production. For learning the basics of in-camera VFX, refer to the In-Camera VFX Quick Start. For behind the scenes footage of this production, refer to the Unreal Engine Spotlight.

Stage Setup and Hardware



Click image to expand.

Four nDisplay nodes were used to render the following volume, with 2 LED panels assigned to each node:

Walls: Total resolution of 15312 x 2112 over 5 LED panels.

Ceiling: Total resolution of 4160 x 5280 over 3 LED panels.

This real production sample is both CPU-intensive and GPU-intensive so it can render on this large LED volume at a camera-ready resolution. The diagram below shows every device contributing to the production and the connections between devices on stage. To learn about the roles of each device in the shoot, refer to In-Camera VFX Overview for details. To learn what hardware is recommended for an in-camera VFX shoot, refer to In-Camera VFX Recommended Hardware.



Diagram showing what devices were used and how they communicated with each other on stage. Click image to expand.

Getting Started

In addition to the nDisplay Config that represents the topology of the real stage used in production, a simple nDisplay Config is included in the project so you can view the scenes on a single computer without an LED volume. This section shows how to use the simple nDisplay Config to render the scene and make changes in a multi-user session on a single computer.

Follow these steps to launch an instance of the Unreal Editor and another instance of Unreal Engine with the nDisplay renderer in a multi-user session on your computer.

Download the In-Camera VFX Production Test sample project from the Epic Games Launcher under the Learn tab.

Go to the Unreal Engine folder on your computer and run Engine\Binaries\Win64\SwitchboardListener.exe to launch SwitchboardListener on your computer. The listener will minimize its window automatically on start to avoid issues with nDisplay devices. You can find the application in your OS's taskbar.

The following is an example of a full path: C:\Program Files\Epic Games\UE_4.27\Engine\Binaries\Win64\SwitchboardListener.exe

In the Unreal Engine folder, run Engine\Plugins\VirtualProduction\Switchboard\Source\Switchboard\Switchboard.bat to launch Switchboard on your computer. If this is your first time running Switchboard, it will install any required dependencies before opening the application window.

The following is an example of a full path: C:\Program Files\Epic Games\UE_4.27\Engine\Plugins\VirtualProduction\Switchboard\Source\Switchboard\Switchboard.bat

Create a new Switchboard Configuration.

If this is your first time running Switchboard, the Add New Switchboard Configuration window appears when Switchboard launches.

If you have run Switchboard before, click Configs > New Config in the top left corner of the window to open the Add New Switchboard Configuration window.



In the Add New Switchboard Configuration window:

Set Config Path to the name and location where you want to store your Switchboard Configuration file.

Set uProject to the location of the In-Camera VFX Production Test sample project file, TheOrigin.uproject.

Make sure Engine Dir is pointing to the Engine folder for your Unreal Engine.

Click Ok to create the Switchboard Configuration.



Set Level to CaveEntrance_NantStudiosSimple.



Add an nDisplay device to Switchboard:

Click Add Device and select nDisplay from the dropdown.



In the Add nDisplay Device window, click Browse and navigate to Content\TheOrigin\Content\Stages\NantStudiosSimple\Config\NDC_NantStudiosSimple.uasset in the sample project's folder.



Click OK to see one nDisplay device added to Switchboard.



Add an Unreal device to Switchboard:

Click Add Device again and select Unreal from the dropdown.



In the Add Unreal Device window, set the IP Address to the local computer: 127.0.0.1.



Click OK and see one Unreal device added to Switchboard.



Click the Connect to Listener button for the nDisplay Render_2 device to connect to SwitchboardListener.



Click the Start Unreal button for the nDisplay Render_2 device to launch Unreal with the nDisplay renderer in a multi-user session.



All windows automatically minimize and the full screen nDisplay render appears. The view might be dark but you will change the view in a later step.

Open the minimized Switchboard window, and click the Connect to listener button for the Unreal device to connect to SwitchboardListener.



Click the Start Unreal button for the Unreal device to launch an instance of the Unreal Editor in the Multi-User Session.



In the Editor, on the toolbar click Open Level Snapshots Editor.



In the Level Snapshots Editor, double-click the CaveEntrance_NantStudiosSimple_SetupA Level Snapshot and click Restore Level Snapshot.



In the Unreal Editor's World Outliner panel, select the nDisplay Root Actor NDC_NantStudios_Simple to see its updated position.





The nDisplay view updates with the changes you make in the Unreal Editor instance.



Select InnerCamera_A under the nDisplay Root Actor and move it around the scene to see the inner frustum move in the nDisplay view.



These steps showed how to run the project on a single computer. You can use similar steps and modify the nDisplay Config that represents the real stage to test on your own LED volume.

mGPU and Multi-Screen Cluster



The production leveraged multi-GPU to improve performance during the shoot. Rather than relying on a single GPU to render all viewports, a second GPU was dedicated to rendering only what appeared in-camera, to allow for the highest fidelity where it counted most. Refer to the nDisplay Overview to learn how to use mGPU in a project.

Unreal Engine includes the Stage Monitor tool so you can receive reports associated with specific events from all the nDisplay cluster nodes in one application. You can have the tool enter a critical state while filming so you can easily notice events that could affect your shot. For more on how to use this tool, refer to Stage Monitor.

Remote Control

With Remote Control, the production team, while on set, was able to control the displays and virtual environment dynamically from a web application running on a tablet. Exposed controls from the project included lighting, color grading of the displays, and modifying the position and rotation of the stage in the virtual environment.



Using Remote Control

In the Getting Started section, you used an Unreal Editor instance to make changes to the scene and see the updates immediately in the nDisplay render. This section shows how to do the same thing using the Remote Control Web Application designed for the project.

Follow these steps to view the Remote Control Web Application designed for this project, and move the nDisplay Root Actor remotely:

In the Content Browser, go to TheOrigin > Content > Tools > RemoteControl and double-click RCP_NantStudios to open the Remote Control Preset in the Remote Control Panel.



The Remote Control Panel shows all the exposed parameters in the Remote Control Preset. Launch the web application by clicking the angled arrow icon in the top right of the panel.



If there is no option to launch the web application in the Remote Control Panel, ensure the web application was built properly. You may need to modify the Remote Control section of the Project Settings to build it on your computer. Scan the Output Log in the Unreal Editor for errors.

You might need to rebind properties to work with the level and stage you have open.



Switch to the Stage tab of the Remote Control Web Application.

Move the joysticks to change the location of the nDisplay Root Actor.



Designing the Web Application

The Remote Control Web Interface is a plugin that provides a companion web application to Remote Control. The web application includes a UI builder so you can create and customize your own web application without any code.

To switch to the UI builder of the Remote Control Web Application, toggle the Control button to Design, and modify the UI for the project. Save the Remote Control Preset Asset to save changes to the Remote Control Web Application's UI design.



The following list describes the controls exposed in each tab of the Remote Control Web Application designed for this production.

Stage: Combines the controls for the Stage Position and Rotation within the Level.



Viewport Settings: Combines the controls for the global Viewport Screen Percentage and per-viewport Screen Percentage parameters.



Color Correction: Combines the controls for global Color Correction and per-viewport Color Correction parameters.



LightCard: Combines the controls for Light Cards.



Snapshot: Shows all Level Snapshots in the project, and combines controls for taking and applying Level Snapshots. See Level Snapshots for more details.



Color Grading and OCIO

In order to preserve accurate and consistent color across the pipeline, the art and stage teams leveraged OpenColorIO (OCIO) to standardize color space conversions. These color space conversions accounted for display differences between monitors, LED panels, and production cameras.

A sample OCIO configuration and its look- up tables (LUTs) are included in the OCIO Plugin. This project has an example OCIO Configuration Asset that references this OCIO configuration and is assigned to both nDisplay Config Assets. You can find the OCIO Configuration Asset in TheOrigin/Content/OCIO.

To learn more about creating OCIO configurations and color space conversions for your displays, see In-Camera VFX Camera Calibration.

Follow these steps to use your own OCIO configuration in the project:

In the Content Browser, right-click and select Miscellaneous > OpenColorIOConfiguration to create a new OpenColorIO Configuration Asset.



Double-click the new asset to open its editor.

In the Asset Editor, under the Config section, set the Configuration File field to the path of your OCIO configuration file on disk.



Click Reload and Rebuild to load the OCIO configuration.

When the OCIO configuration is successfully loaded, expand the Color Space section.

Add the Source and Destination color spaces you wish to use. The options available are determined by the OCIO config you specified.



To apply this configuration to your nDisplay viewport, open the level containing your nDisplay Config Asset, and search for OCIO in the Details Panel of the actor. Ensure that you have Enable Viewport OCIO set to true.

Expand All Viewports Color Configuration:

Specify the Config asset you want to use.

Set the Source and Destination color spaces.



These steps demonstrate how to add your own OCIO configuration to the project. You can also set OCIO configurations per viewport and separately on the inner frustum. For more information, refer to Color Management in nDisplay.

GPU Lightmass and Multi-User

The production team used the new GPU Lightmass feature to bake the scenes' lighting and thus minimize how long the production had to wait for lighting changes in their multi-GPU and multi-user environment. Light baking occurred on a single multi-GPU workstation and then was distributed over the network through the multi-user session. This meant that the scene could be baked quickly and reloaded on the LED walls without needing to close and relaunch the cluster.

Follow these steps to use GPU Lightmass to bake lighting for the scene:

In the Toolbar, click the arrow next to Build and select GPU Lightmass from the dropdown.



In the GPU Lightmass window, click Build Lighting to begin your bake.



When the lighting finishes building, in the main menu choose File > Save All to transmit the changes to the other computers in the multi-user session.



Instead of sharing all changes with the other computers in the multi-user session, you can also choose what changes to transmit.

In the main menu, choose File > Choose Files to Save…



Select only the levels and build data you want to save and transfer.



Click Save Selected to transmit the changes to the other computers in the multi-user session.

For more on the settings you can change for your lightmass bakes, refer to GPU Lightmass.

Transferring GPU Lightmass bakes through the multi-user session is an experimental feature. Scenes that produce large BuildData files may experience issues with the transfer. If this happens, you can:

Check your updated levels and BuildData into source control.

Through source control, sync the changes to your render nodes to distribute the updated lightmaps.

Level Snapshots

The production team used Level Snapshots to save configurations of the Actors in a Level for each scene. Once Level Snapshots were created, the team was able to restore the scene later to exactly how it was set up for a specific shot. Level Snapshots also track changes to the nDisplay Root Actor, so modifications to the inner frustum and color grading can be saved and applied to the nDisplay renders at any time.

The following sections describe how to use the filters and presets included in the project. To learn about creating your own filters and other features in the tool, refer to Level Snapshots.

Filtering with Level Snapshots

Included in the project is an example Blueprint Level Snapshot Filter that lets you filter Actors in the Level Snapshot changes by their Class. You can find the filter LSF_FilterByClass in TheOrigin/Content/Tools/LevelSnapshotFilters. This section shows how to use this filter in the project.



Diagram showing what devices were used and how they communicated with each other on stage. Click image to expand.

Follow these steps to filter Level Snapshot changes and apply them to your project:

In Unreal Editor's Content Browser, go to TheOrigin > Content > StageLevels > NantStudiosSimple > StageLevels and double-click CaveEntrance_NantStudiosSimple to open the Level.

In the Toolbar, click the arrow next to the Level Snapshots button and select Open Level Snapshots Editor from the dropdown.



There are two Level Snapshots already created for the Level CaveEntrance_NantStudiosSimple. Double-click CaveEntrance_NantStudiosSimple_SetupA to see how the Actors saved in the Level Snapshot differ from the current state of the Level.



Click Filter Group.



Click Add Filter and in the dropdown choose Blueprint Filters > LSF Filter by Class.



Click LSF Filter by Class in the Filter Group.



In the Default section next to Class, click the dropdown and search for Light Card.



Click the Refresh Results button to apply the filter changes.



Now, only changes to Light Card Actors are shown. To turn off the filter, right-click the filter and select Ignore Filter.



Click Refresh Results and see the nDisplay Root Actor appear in the list again.



Using Presets with Level Snapshots

With Level Snapshot Presets, you can set up logic using Blueprint and C++ filters and save it as a preset. Later, you can load the preset to use this logic again. Included in the project is an example Level Snapshot Preset located in TheOrigin/Content/Tools/LevelSnapshotPresets.

This preset strings multiple instances of the Filter by Class Blueprint Filter together with the OR boolean so only Actors that match any of those Classes will appear. The Classes used in the preset are: LightCards, Stages, Cameras, SyncTestBall, ColorCorrectRegion, and PostProcessVolume.

Follow these steps to use the Level Snapshot Preset in the project.

In the Content Browser, go to TheOrigin > Content > StageLevels > NantStudiosSimple > StageLevels and double-click CaveEntrance_NantStudiosSimple to open the Level.

In the Toolbar, click the arrow next to the Level Snapshots button and select Open Level Snapshots Editor from the dropdown.



There are two Level Snapshots already created for the Level CaveEntrance_NantStudiosSimple. Click Load/Save Filter and choose ExampleStagePreset.



Double-click CaveEntrance_NantStudiosSimple_SetupA to see how the Actors saved in the Level Snapshot differ from the current state of the Level.



When the Level Snapshot is opened, only the Actors that fit the filter loaded from the preset are shown.



Project Structure

The In-Camera VFX Production Test is a great example to see how to structure an Unreal Project for Virtual Production. The following folders define the overall structure for the project's content and separate it into relevant categories.

[Assets[(#assets)

Envs

OCIO

StageLevels

Stages

Tools

Assets

This folder typically contains all assets for creating Characters, Environments, and FX. Level Assets are not included here. The following list is how the assets were categorized for this sample project.

Atlases

Decals

FX

IES

Landscape

Materials

MS_Presets

Props

Rocks

Scatter

Sky

Textures

Vegetation

Environments

Three environments from the shoot are included in the project:

CaveEntrance



CavePath



SpaceJunkyard



Since source control only lets you exclusively check out binary assets, such as .umap files, each artist working on an environment at the same time must work in their own level. The solution to this is to divide an environment up into multiple sublevels based on the type of Actors in each.

For example, a lighting artist would work in the lighting sublevel, and an FX artist in the FX sublevel. It is also common to have multiple GEO levels that divide the environment up into regions, each being worked on by a different artist. The number and types of sublevels used should be dependent on the needs of the production.

The following are the folders used for each environment in this project:

LevelSnapshots: Level Snapshot Assets associated with the Level.

SubLevels: In this project, each Level was separated into the Caustics, FX, Geo, and Lighting sublevels.

Level Asset: Level Assets follow a {LevelName}_{Descriptor} structure. The _P suffix is given to the Persistent Level, which acts as a container for the sublevels. Open this Level Asset to view the full environment composed of all the sublevels.

OCIO

This folder contains the OpenColorIO Configuration Assets. There is one Asset for this project: ExampleOCIO. For more details on using OCIO in this project, refer to the Color Grading and OCIO section on this page.



Stage Levels

The folder contains all the Level Assets that have both the environment and stage Actors. Open these assets when you want to render with nDisplay. The stage levels are categorized by the stage used in the Level Asset. This sample project uses the following structure to match the stages:

NantStudios

CaveEntrance_NantStudios

CavePath_NantStudios

SpaceJunkyard_NantStudios

NantStudiosSimple

CaveEntrance_NantStudiosSimple

CavePath_NantStudiosSimple

SpaceJunkyard_NantStudiosSimple

Stages

This folder contains the nDisplay Configurations which describe the topology of the LED volumes. The production used one stage for all the shots: Nant Studios. A simpler version of the stage is provided as well so you can render the front walls on a single desktop.



Click image to expand.

Config: An nDisplay Config Asset for the stage that defines the topology of the LED volume and how to render on it.



LEDMeshes: Static Meshes and materials with the LED panel resolution used in the nDisplay Config Asset.



LiveLinkPresets: These are previously created configurations for Live Link that are required to load LiveLink sources on the nDisplay nodes at launch. The default preset is specified in Project Settings > Live Link > Default Live Link Preset. They can also be used to quickly reload different sources in an editor environment.

NantStudios_Stage: A Level Asset that contains only the Actors that represent the stage, such as the nDisplay Root Actor, ICVFX Cameras, and Light Cards.

Config: An nDisplay Config Asset for the stage that defines the topology of the LED volume and how to render on it. The topology looks the same as the Nant Studios configuration, but only two of the front walls are set up to render.

NantStudiosSimple_Stage: A Level Asset that contains only the Actors that represent the stage, such as the nDisplay Root Actor, ICVFX Cameras, and Light Cards.

Tools

This folder contains custom Blueprint controls, Level Snapshot Filters and Presets, and Remote Control Presets. The following list describes each tool.

CaveMaterialControl: A blueprint controller for various Material Parameter Collections used by objects in the scene. Contains controls for things such as caustic speed, light shaft intensity, and global color shifts for the rocks.

HierarchicalInstanceConverter

HolePunch: A spherical actor used to create a hole in the geometry of the cave. This was used on the day of the shoot to create an additional light shaft.

InnerFrustumCamera: A CineCameraActor with a LiveLinkComponent. This Blueprint simplifies the camera tracking by not requiring the user to manually add an instanced LiveLinkComponent to the scene actor.

LevelSnapshotFilters: Custom Blueprint Filters for Level Snapshots.

LevelSnapshotPresets: Presets of groups of filters for Level Snapshots.

RemoteControl: Remote Control Presets.

SyncTestBall: This tool creates a bouncing red ball used to test synchronization. Place the ball in the scene so that it appears on the seam between two walls. A visible tearing of the ball occurs at the seam if the synchronization is not functioning properly.

Cvars

To improve performance while rendering with nDisplay on stage, the production team used the cvars in the table below to tweak settings. You can set cvars during an nDisplay session in Switchboard and have them applied to the cluster.

To set cvars in Switchboard:

Open Switchboard.

Under the nDisplay Monitor tab, in the Console: text box, enter the cvar and the desired value, if applicable.

Click Exec.



The following values are what were used for the In-Camera VFX Production Test. You might need to use different values depending on the content in your project and what look you want to achieve.

Cvar

Value

Description

r.ExrReadAndProcessOnGPU

N/A

Switches EXR playback between CPU and GPU. When enabled for the GPU, Unreal Engine 4 can load large, uncompressed EXR files directly into a Structured Buffer and process them on the GPU.



Ray Tracing



r.RayTracing.ForceAllRayTracingEffects

0

Forces all ray tracing effects either on or off. Options for value include:

-1: Do not force (default)

0: Disable all ray tracing effects

1: Enable all ray tracing effects

Setting this cvar to 0 turns off all the additional ray tracing features that are enabled by default. When using GPU Lightmass, which requires ray tracing, you can still use GPU-accelerated light baking. This cvar can also be useful for figuring out how much performance is required with ray tracing enabled.

r.RayTracing.Reflections.MaxRoughness

0.2

Sets the maximum roughness for visible ray tracing reflections (default = -1 (max roughness driven by post processing volume)). This guarantees that only Materials with roughness values lower than 0.2 will have ray-traced reflections.

r.RayTracing.Reflections.MaxRayDistance

500

Sets the maximum ray distance for ray traced reflection rays. When ray shortening is used, the skybox will not be sampled in the RT reflection pass and will be composited later, together with local reflection captures. Negative values turn off this optimization (default = -1 (infinite rays)). Using a value other than -1 will help reduce the amount of ray tracing that is done in a scene.

r.RayTracing.Reflections.SortMaterials

0

Determines whether reflected materials will be sorted before shading. Options:

0: Disabled

1: Enabled, using Trace > Sort > Trace (Default)

r.DiffuseIndirect.Denoiser

2

Denoising options (default = 1)

r.RayTracing.Reflections

0

Turn OFF only ray tracing reflections in your level. This is useful in case you still want to use ray-traced shadows or other ray tracing features, and not pay the cost of ray-traced reflections. Options:

-1: Value driven by the postprocess volume (default)

0: Use traditional rasterized SSR.

1: Use ray-traced reflections.

r.RayTracing.Geometry.Landscape

0

Include landscapes in ray tracing effects (default = 1 (landscape enabled in ray tracing)) In order to optimize the levels that needed ray-traced reflections, we disabled landscape ray-tracing as it was not adding much to the final look, and disabling it gave us some performance boost.

r.RayTracing.Reflections.ScreenPercentage

50

Screen percentage the reflections should be ray traced at (default = 100). If your scene doesn't have very shiny and clean reflections you can reduce this value and you will gain some performance.



Upscaling Resolution



r.ScreenPercentage

75

Render in lower resolution and upscale for better performance (combined with the blendable post process setting). 75 is a good value for low aliasing and performance, verify with 'show TestImage'.

In percent, use >0 and <=100, larger numbers are possible (supersampling) but the downsampling quality is improvable. Numbers <0 are treated like 100.

r.TemporalAA.Algorithm

1

Algorithm to use for Temporal AA Options:

0: Gen 4 TAAU (default)

1: Gen 5 TAAU (experimental) This will turn ON our new Gen5 TAAU in case some resolution upscaling is needed .

r.TemporalAA.Upsampling

1

Whether to perform primary screen percentage with temporal AA or not. Options:

0: Perform the spatial upscale pass independently of TAA (default).

1: TemporalAA performs the spatial and temporal upscale using the screen percentage method.



SSGI



r.SSGI.Enable

0

Whether to enable or disable Screen Space GI Options:

0: Disable

1: Enable Turns OFF Screen Space GI.

r.SSGI.HalfRes

1

Whether to perform SSGI at half resolution. Options:

0: Disable (defaults)

1: Enable

r.SSGI.Quality

1

Quality setting to control the number of rays shot with SSGI, between 1 and 4 (defaults to 4).



Volumetric Fog



r.VolumetricFog.GridPixelSize

6

XY size of a cell in the voxel grid, in pixels. Lower values produce better Volumetric Fog Quality but it will affect performance.

r.VolumetricFog.GridSizeZ

96

How many Volumetric Fog cells to use in the Z axis. Higher values can help increase accuracy and reduce noise but it can impact performance.

r.VolumetricFog

0

Whether to enable the Volumetric Fog feature. Options

0: Disabled

1: Enabled This can be used to quickly turn OFF Volumetric Fog and determine how much performance it uses.



Rendering



ShowFlag.DirectLighting

0

This cvar is useful for quickly disabling direct lighting in order to understand what is baked and what isn't, and its performance implications. Options:

0: Disable the showflag.

1: Enable the showflag.

2: Do not override this showflag (default).

r.SetNearClipPlane

150

Set the near clipping plane (in cm). This cvar will allow you to modify the Near Clip Plane in case you want to quickly remove any geometry that is in front of your render camera.

r.TextureStreaming

0

Defines whether texture streaming is enabled, which can be changed at run time. Options

0: Disabled

1: Enabled (default)

r.Streaming.PoolSize

3600

-1: Default texture pool size, otherwise the value is the size in MB. This cvar can be used to increase the texture pool size at runtime in order to allow higher mipmaps to be loaded, if the pool size originally was set too low and your hardware allows a higher texture pool size.

r.DFShadowScatterTileCulling

1

Whether to use the rasterizer to scatter objects onto the tile grid for culling. Options

0: Disabled

1: Enabled

r.ForceLOD

5

LOD level to force, -1 is disabled. This is useful for testing how much performance or quality can be gained by forcing a specific LOD on the scene.

Cinematics and Sequencer

Movie Render Queue

Groom Asset Editor User Guide

Required Setup

Viewing the Meerkat Sequence

Optimization Settings

Toggling High-Resolution Environment Meshes

Changing the Eagle's Groom Resolution

Rendering the Meerkat Demo With Movie Render Queue

Adding the Meerkat Control Rig to a Shot

Real-time rendering technology is an increasingly important tool in the filmmaking process, from previsualization to the final render, as it enables filmmakers to review and iterate on digital scenes and effects very quickly. The Meerkat Demo by Weta Digital is a short film rendered entirely in Unreal Engine, built to explore the highest level of quality possible while maintaining as fast a rendering speed as possible. With the right graphics card the Meerkat short will run at real time. This document will guide you through the process of outputting a high-quality render of the Meerkat short yourself using the Movie Render Queue plugin.

This sample is available for Unreal Engine 4.26 and later. Be aware that it is an especially graphically intensive scene, and needs a powerful video card to run at a stable framerate.

Required Setup

To set up a project with the Meerkat sample, follow these steps:

Open the Epic Games Launcher, click the Unreal Engine section, then open the Learn tab.



The Learn tab is located in the Unreal Engine section of the Epic Games launcher, at the top of the screen. Click image to enlarge.

Scroll down the page to Engine Feature Samples, click the entry for the Meerkat Demo sample, then click Free to add the sample to your Vault.



The Meerkat Demo in the Engine Feature Samples section. Click image to enlarge.

Click Create Project and follow the on-screen instructions to download the Meerkat Demo sample content and start a new project.



The Create project button in the content page for the Meerkat demo. Click image to enlarge.

Open your new project in the Unreal Editor.

Open the Edit > Plugins window and navigate to the Built-In > Rendering section. Make sure that the Movie Render Queue plugin is enabled and, if necessary, restart the editor.



Enabling the Movie Render Queue plugin. Click image to enlarge.

Viewing the Meerkat Sequence

Once you have loaded Unreal Editor and opened the Meerkat Demo project, go to the Content Browser and double click Master_SEQ.



This will open Sequencer and load the Master_SEQ level sequence.



The Master_SEQ level sequence loaded in the Sequencer tab. Click image to enlarge.

You can scrub the timeline through the different shots by clicking in the timeline.



The timeline for the Master_SEQ level sequence. Click image to enlarge.

If you want to be able to see the shots through the cinematic cameras set up in the scene, you can click on the camera icon for Shots. Your viewport will then look through the camera corresponding to the position of the timeline.



The toggle button for Cinematic camera mode as it appears in the Sequencer tab. Click image to enlarge.

You can also change your viewport mode from Perspective to Cinematic Viewport.



Changing to Cinematic Viewport Mode using the Viewport controls. click image to enlarge.

For more information about working with Sequencer, refer to the Sequencer Editor section.

Optimization Settings

To improve performance, the Meerkat demo uses low-resolution settings by default. If you want the highest-quality visual, there are several optimization settings you can change.

Toggling High-Resolution Environment Meshes

In the World Outliner, click the VisualSettings_BP Blueprint. In the Details tab, under Default, you will find the Highres Env Meshes setting. Your scene will have improved fidelity with it turned on, but it will run slightly faster with it turned off.





Move the slider to compare the scene without high-resolution environment meshes versus with them turned on.

Changing the Eagle's Groom Resolution

The Eagle in the Meerkat demo uses a Groom hair asset to represent its feathers. By default, it uses a low-resolution groom to improve performance, but you can change this to a high-resolution asset instead.

In the World Outliner, click the Characters group, then select amlEagle_BP and look at its Details tab.

Select the Groom property, which is listed under amlEagle_BP(self) in the Details tab.



The Groom properties can be accessed from the Details tab. Click image to enlarge.

There are both a Groom Asset and Binding Asset, and each has a dropdown menu to the right of the icon.

Click the Groom Asset menu, then change the groom from amlEagle_groomLowRes_r036_GRO to amlEagle_highRes_GRO.

Click the Binding Asset, then change it from amlEagle_groomLowRes_r036_GRB to amlEagle_highRes_GRB.





Move the slider to compare the Eagle with low-resolution groom assets versus high-resolution assets. Note the finer detail in the feathers.

For more information about working with Groom assets, refer to the Groom Asset Editor User Guide.

Rendering the Meerkat Demo With Movie Render Queue

To render the Meerkat Demo, you need the Movie Render Queue, which is used for outputting high-quality renders of Sequencer movies. Review the steps in Required Setup to ensure that you have the Movie Render Queue plugin enabled, then follow the steps below to set up a rendering job:

Launch the Movie Render Queue by selecting Window > Cinematics > Movie Render Queue.



In the top-left corner of the Movie Render Queue window, click the + Render button. Select Master_SEQ from the dropdown menu.



Accessing Master_SEQ from the + Render dropdown. Click image to enlarge.

This will add an entry to the Movie Render Queue's list of jobs to render.

In the entry for Master_SEQ, click Unsaved Config under the Settings column to open the Settings Window.



In the Settings Window, click the Presets dropdown in the top right corner and select the MoviePipelineConfig_Temporal preset.



Selecting the MoviePipelineConfig_Temporal preset and applying it to the shot. Click image to enlarge.

You now have the settings needed for rendering the Meerkat demo. In the Settings window, you will see a list along the left side of the window that represents items that have been set specifically for this project. You can edit these settings to change the output directory for the rendered images, change the type of image that will be saved, or edit post-processing settings. Click the Accept button on the bottom right corner to close the window.



The Settings window with the applied settings from MoviePipelineConfig_Temporal. Click image to enlarge.

Note: The image above displays a warning icon in the Settings window. If you click it, you can see the warning details. The TAA samples in the project are set to 16, but the warning will appear anyway. You can ignore this warning.

To launch the render, click the Render (Local) button in the lower-right corner of the Movie Render Queue window.



Finalized settings in the Movie Render Queue window. Click image to enlarge.

A Render Preview window will appear, showing information related to the render.



The Movie Render Queue preview window displays information about rendering progress. Click image to enlarge.

For more information about how to use Movie Render Queue, refer to the Movie Render Queue section of the Sequencer workflow guides.

Adding the Meerkat Control Rig to a Shot

This project includes a control rig for the Meerkat, which you can use to explore some keyframe animation inside Unreal Editor. To use this control rig, you need to add the amlMeerkat_BP into a shot in Sequencer. The easiest way to do this is to create a new level sequence.

Select Cinematics > Add Level Sequence.

In the Save Asset As window, navigate to the Levels folder, name the level sequence MeerkatAnim_SEQ, then click Save. The level sequence you just saved will become the active sequence in Sequencer.



Saving the new sequence to use with the Meerkat control rig. Click image to enlarge.

You can return to the original sequence by locating Master_SEQ in the Content Browser and double-clicking it.

In the Content Browser, open the Content > Assets > meerkat > Blueprints folder and locate the amlMeerkat_BP asset.



The Meerkcat control rig asset in the Content Browser. Click image to enlarge.

Click and drag the amlMeerkat_BP asset into MeerkatAnim_SEQ.



Clicking and dragging the Meerkat control rig Blueprint into the sequence. Click image to enlarge.

You now have a copy of the Meerkat asset with a control rig that you can use in your level sequence.



Keyframing the Meerkat control rig in the Sequencer timeline. Click image to enlarge.

You can edit its parameters in the timeline or manipulate the control rig directly in the viewport.



Manipulating the control rig in the level viewport. Click image to enlarge.

If you are trying to use the Meerkat control rig and you do not have a high-end graphics card, you can turn the visibility of the groom component off to hide the fur, which will improve performance.

To do this, click on the Meerkat in your viewport to display its information in the details panel. Under SkeletalMeshComponent click on Groom(Inherited), scroll down to Rendering and turn off the Visible flag.



The location of the Groom component's visibility checkbox. Click image to enlarge.

Getting Started

Controlling the Player Page

Understanding the Custom UI Events

The Pixel Streaming Demo showcase demonstrates how you can design Unreal Engine content for people to experience as a live stream, using a Web browser on either a desktop or mobile device. It includes:

An HTML player page that plays back a media stream generated by your Unreal Engine application, and that offers custom UI elements for controlling the Engine remotely.

An Unreal Engine Project that is already set up to generate a media stream using the Pixel Streaming Plugin, and to respond to the custom commands issued from the HTML player page.

You can use this sample as a model for building your own custom HTML5 player that interacts with your Unreal Engine content.

Prerequisites:

Make sure that you understand the basics of the Pixel Streaming system.

Follow all the instructions in the Getting Started guide at least once to make sure that you have everything that you need installed and working with the default player page.

Getting Started

Find the Pixel Streaming showcase on the Learn tab of the Epic Games Launcher, and use it to start a new Unreal Engine Project.

In Windows Explorer, browse to the location of the Project on your computer, and find the WebInterface folder.

Copy the contents of this folder to the Samples/PixelStreaming/WebServers/SignallingWebServer/custom_html folder under your Unreal Engine installation folder. If that custom_html folder doesn't yet exist, create it first.

Open the PixelStreamingDemo.uproject file in the Unreal Editor.

Follow the process described in the Getting Started with Pixel Streaming page to:

Package the Project or start it from the Unreal Editor as Standalone Game.

Start the Signaling and Web Server.

Open a Web browser, and navigate to the PixelDemo.htm player page being hosted by your Signaling and Web Server. For example:http://<your-server-ip-address>/PixelDemo.htm

Controlling the Player Page

When you have the Pixel Streaming system set up correctly, and you use a supported Web browser to access the custom PixelDemo.htm player page, you can use the controls described in the following sections to interact with the running Unreal Engine application.



Click for full image.

Use the menu on the left hand side of the page to change the current character, skin, environment, and time of day.

The Toolbar provides some additional controls over the UI and the viewer:

Control

Effect



Shows and hides the left-hand menu.



Toggles the camera between its fully zoomed-in and fully zoomed-out positions.

720p, 1080p, 4k

Sets the rendering resolution of the Unreal Engine application running on the server.

Not all GPUs are capable of encoding video feeds at 4K resolution.

Due to a current limitation, once you cap the bandwidth to a given value, you will not be able to raise that limit again until you restart your Unreal Engine application.

The viewer widget itself offers direct mouse and touch control over the Unreal Engine application:

Control

Effect

Click and drag, or touch and drag

Rotates the camera around the current character.

Mouse wheel

Zooms the camera in and out.



Switches the viewer to full-screen mode. Press the Esc key to exit.

Click the Add (+) button at the top right of the page to toggle an overlay that provides additional controls over the stream. Most of these settings are the same as the ones in the default player.htm page, and are described in the Getting Started guide. The new settings are:

Control

Effect

Prioritise Quality

When active, the rendering resolution of the Unreal Engine application is automatically adjusted to match the current size of the player widget in the HTML player page. As you make the browser window smaller, and the size of the player widget decreases, the rendering resolution of the Unreal Engine application on the server decreases to match. Similarly, if you enter full-screen mode on the player page, the Unreal Engine application scales up its window to match the resolution of the client's screen.

Match Viewport Resolution

When active, the Pixel Streaming system automatically limits the number of frames per second produced by the Unreal Engine application when the available bandwidth for the connection is limited. See the descriptions for the Streamer.PrioritiseQuality, Streamer.LowBitrate, Streamer.HighBitrate and Streamer.MinFPS console commands in the Pixel Streaming Reference.

Understanding the Custom UI Events

The custom HTML player page, PixelDemo.htm, uses the scripts/app.js file provided with the Pixel Streaming Signaling and Web Server to capture mouse, keyboard, and touch events and relay them back to the Unreal Engine application. In addition, it relies on its own custom PixelDemo.js file for some additional functionality.

Most of the UI elements in the player page are implemented by calling the emitUIInteraction() function to pass different information back to the Unreal Engine application. To understand how any piece of the UI works under the hood:

First, find the UI item you want to understand in the PixelDemo.htm file, and see what JavaScript function is set to trigger when that button is pressed.For example, each item in the left-hand menu triggers a function called onConfigButton(), and passes it two numbers.

Look for the definition of that function in the PixelDemo.js file.For example, the onConfigButton() function writes these two numbers into a JavaScript object as the values of the Category and Item fields respectively, then it passes that JavaScript object to the emitUIInteraction() function:

In the Unreal Engine Project, these events are responded to by the Blueprints/Pawn/Orbit_Controller class. Double-click this class to open up its Event Graph.

In the Bind JSON Events area, you'll see how the Bind Event to OnPixelStreamingInputEvent node is used to register the OnJSONEvent event as a handler each time emitUIInteraction() is called in a connected browser.

Click for full image.

Each time the OnJSONEvent event triggers, the Blueprint calls Get Json String Value to check the keys and values stored in the JavaScript object that was passed by the player page to the emitUIInteraction() function. It uses those values to decide what other events it should trigger.For example, when the event receives an input that contains a Category field, it calls the Change Config Option event.

Click for full image.

This event in turn checks the value of the Category field, and uses that value to determine whether it should change the character, the skin, the environment, or the time of day.

Click for full image.

Each of these events in turn checks the Item value to decide what type of character, skin, environment, or time of day it should activate.

Click for full image.

The controls in the overlay at the top right of the page, such as Prioritise Quality and Match Viewport Resolution, work a slightly different way. The app.js file adds event listeners to these HTML elements when it is loaded. Each time the user enables or disables one of these elements, the listener function in the app.js file is triggered to respond directly to the change.

Cinematics and Sequencer

Movie Render Queue

Master Sequences, Shots, and Takes

Setup

Viewing the Slay Sequence

Quixel Megascan Assets

Shot-Based Workflow

Level Visibility

Using Spawnables

Artist Collaboration

Camera Animation

Lighting and Materials

Lighting Workflows

Material Workflows

Render Settings

Post Process Volume

Viewport Optimization

Movie Render Queue Settings

Virtual production is supported in Unreal Engine through the use of various cinematic tools, rendering features, and workflows. The Slay sample, built by Mold3D Studio, was created to demonstrate techniques, rendering features, and workflows that can be achieved when considering virtual production in Unreal Engine.

This document provides an overview of how to view the Slay sample, as well as the workflows and production techniques that were used to create it.

The Slay sample content is a graphically intensive scene. It requires at least an Intel Core i9 Series processor and GeForce RTX 2080 Ti, or similar.

When opening the project or Level for the first time, there may be a long initial load time as numerous assets are loaded and compiled for the first time.

Setup

To set up a project with the Slay sample, follow these steps:

Open the Epic Games Launcher, click the Unreal Engine section, then open the Learn tab.



Scroll down the page to the Slay sample, then click Free to add the sample to your Vault.



Click Create Project and follow the on-screen instructions to download the Slay sample content and start a new project.



Open your new project in the Unreal Editor.

You should now see the temple_P Level in your viewport.



Viewing the Slay Sequence

To view the Slay sequence, click the Cinematics button in the main toolbar and select TF_Edit.



This will open the Master Sequence for the Slay cinematic. You can see the multiple shots used to assemble the full sequence in this view.



Select the Camera button on the Shot Track to look through the Cameras for each shot, and click the Play button to play the sequence.



Quixel Megascan Assets

The Temple Level was built using a combination of unique assets and Quixel Megascan assets. These assets were used in Slay to provide background details, props, and foliage. Using Quixel Megascan assets in your project can save time and resources when creating large environments.



You can view some of the Quixel Megascan assets used in the Slay sample by navigating to the Quixel Megascan website. Some notable examples include:

Gravestones in the Temple courtyard.



Location or era-specific props placed around the Level.



Grass and other foliage placed in the gardens and other areas.



Shot-Based Workflow

The Slay sequence was created using Sequencer and its Shot-Based workflow. This was done so that each shot contains all necessary content for that shot only, rather than a larger single sequence. This setup allows for quick modifications to the sequence as a whole, as shots can be edited, trimmed, and re-arranged, just like in any non-linear editing software.

In the Master Sequence TF_Edit, you can see all the shots arranged in the Shot Track. Additionally there are Audio Tracks for playing audio that has been timed to the sequence edit, and a Fade Track for controlling the fade to and from black.



Double-click any shot to open and view its contents.

Level Visibility

The first shot of Slay is an exterior view of the Temple. Because of this unique angle, it was necessary to create a custom Landscape and assets for a Level that only is visible for the duration of Shot TF0010_02. The Level's visibility is controlled by the Level Visibility Track, and can be seen in shot TF0010_02 (Shot 1)

With the Level Visibility Track placed inside the shot, it will evaluate only for the duration of the shot. In this case, the Level containing the lower-resolution Landscape for use when inside the Temple is hidden, and the Level containing higher-resolution Landscape and other assets is displayed instead.



You can manually preview the higher-resolution Landscape Level by navigating to the Levels panel, enabling Terrain_TF0010, and disabling Terrain.

Using Spawnables

Spawnables are Actors that are spawned and typically exist only for the duration of a single sequence. These are used extensively in several shots throughout the Slay sequence in order to address problems unique to each shot. Since each shot is its own sequence, spawnables will only exist for the duration of a shot, making it easier to manage these Actors.

An example of a spawnable Actor can be seen in Shot TF0020_01 (Shot 2). In this example, the original static mesh door is hidden and replaced with a spawnable Skeletal Mesh door, containing animation to match the character's movement as she opens it. When the shot ends, the door is unspawned automatically.



Artist Collaboration

In the Slay sample, each shot is its own sequence, and therefore its own asset. Shots also contain Subscene Tracks which are their own sequence assets as well. Because of this division of assets, it is much simpler to enable multiple artists to work on a single sequence or shot at the same time, without file conflicts occurring. Subscenes can also be duplicated, enabling the same contents to be reused and shared across multiple instances.

In several shots, you can see Subscene Tracks for both Lighting and FX, which enable artists from these disciplines to work within these sequences instead of the main shot sequence. In this way, subscenes are not only useful for limiting file conflicts, but also for Sequencer organization.



You can double-click a Subscene section to open it and view its contents.



When a shot or subscene is opened from a parent sequence, it will be displayed within the context of the Master Sequence. This means that even though you are viewing only a single subscene, all tracks from the Master Sequence and current shot also remain visible. You can edit lights, add visual effects, and perform other actions with full visual context of the scene.



This context view can be enabled or disabled by toggling Evaluate Sub Sequences In Isolation from Sequencer's Playback Menu.

Camera Animation

The Camera animation for Slay was created entirely in Sequencer. In some cases, additive camera animation is also used to enhance the camera movement. This is done using Camera Animation Sequences, which are a form of Template Sequence.



Double-clicking one of these Template Animations will open the corresponding template sequence, where you can view the animation that is being used.



Lighting and Materials

Lighting, Materials, and Effect usage plays a critical role in the Slay sample. Proper utilization of the Master Sequence and Shot ecosystem enables artists to more effectively light and apply material adjustments for each shot.

Lighting Workflows

As mentioned previously, lighting and other workflows can occur within Subscenes. Here, a typical lighting workflow would be to add your necessary Light Actors to the sequence as Spawnables. This is done so that the lights will only remain visible for the duration of the shot, and do not need to be manually turned on or off.



Other lighting techniques can be used to enhance your shots, such as using Light Blockers to block out certain areas of a scene from the main Level's light. Afterward you can more directly control the lighting of a shot using your spawnable lights.

For example, in Shot TF0020_01 (Shot 2), if you disable the Camera button to stop piloting it, then navigate in the viewport to view the Temple entrance area, you should see a large Light Blocker being used. This is used so that a more controlled lighting environment can be created for the shot.



With the light blocker in place, other lights can be spawned to better enhance the lighting in this shot, such as the spotlight shining through the nearby lattice, which casts soft shadows on the door.



In some other cases, it may be necessary to hide certain meshes to let light pass through and shine on your Actors. In Shot TF0080_01, part of the Temple structure is hidden in order to let the sunlight cast on the Oni character.



Lighting Channels are also used in Slay to control how lights affect the environment and characters. In this case, spawnable lights are only affecting Channel 2. This same channel is then enabled on all Characters, causing them to be lit by these lights. The environment is not lit by these lights because those meshes only have Channel 0 enabled.



Material Workflows

If a Material is set up with parameters, you can reference these parameters in Sequencer to make overriding material parameter adjustments. In Slay, this was done to make minor adjustments to materials for specific shots. Similar to the previous lighting and shot-based workflows, these edits can be made on a per-shot basis without persisting to the next shot.

In Shot's TF00110_01 Lighting Subsequence, you can see the Roughness and other parameters on Oni's armor material are adjusted using Material Element Tracks. The Material Element number corresponds to the same Material Element ID on the mesh.



Clicking Add Parameter (+) will reveal a list of the available material parameters for that element. Select a parameter to add it as a track.



Render Settings

The Slay sample was created to be rendered as Final Pixel out, showcasing the high quality images that can be rendered with Unreal Engine. Because of this, there are several important parameters that are being set that increase the fidelity of the scene in both the viewport and when rendered using Movie Render Queue.

Post Process Volume

Post Processing is used in the scene to control Ray Tracing effects such as Global Illumination, Reflections, and Shadows. Color correction is also applied using Color Grading and the Filmic Tonemapper properties.

To view the post process properties being used in Slay, select the Post Process Volume in the Level. It can be found by searching for it in the Outliner.



You can preview the effects of the Post Process Volume by enabling or disabling the Enabled property in its details. Using post processing can help you in making your scenes appear more vibrant.





Viewport Optimization

As Slay is a graphically intense project, it became necessary to optimize the editor viewport experience to ensure smooth, reliable performance when working in Unreal Engine. This was done by setting certain Console Variables within the DefaultEngine.ini Configuration File.

Some examples of the variables being set are:

To view the other console variables in use, you can navigate to the Config folder located in the install location of the Slay project and open DefaultEngine.ini in a text editor.

Movie Render Queue Settings

The final picture for Slay is rendered using Unreal Engine's Movie Render Queue tool. Movie Render Queue supports several features for producing high-quality renders, such as its temporal subsampling feature which is used to apply a high-quality radial motion blur effect. Additionally, Console Variables are used in Slay to increase graphical fidelity during the rendering process.

To open the Movie Render Queue window, click the Render button in Sequencer's Toolbar.



The specific render settings used for Slay are saved as a Movie Pipeline Master Config Asset. To apply this preset to the render, click the Settings dropdown menu and select Slay_MovieRenderQueue_Preset.



To see the settings being used, click the Slay_MovieRenderQueue_Preset settings text. This will open the Render Settings window which contains the various output, quality, and other settings applied during the rendering process.



In order to reduce image noise, as well as to produce smoother edges and motion blur, Anti-Aliasing is used with Temporal Sample Count set to 19.



To increase graphical fidelity in several areas including Motion Blur, Subsurface Scattering, and Raytracing, the following Console Variables are used:



Getting Started with the Video I/O Setup

Media Sources and Playback

Media Bundle Setup

Proxy Media Sources

Keying and Compositing

Capturing Output Video

On-screen Capture Controls

Video Wall

Modular Studio Kit

The Virtual Studio showcases the Unreal Engine's ability to integrate with professional quality video cards from AJA Video Systems and Blackmagic Design. If you have a supported card, you can use this Project to get started integrating the Unreal Engine into your video production pipeline.

This showcase is set up to feature a real-life presenter, composited on the fly behind a virtual desk inside a virtual soundstage. You can leverage the same concept and setup to support other use cases for bringing live video into an Unreal Engine Level and capturing the rendered results to an output feed.

For background information on the video configurations set up in this showcase, see the Quick Start guides for AJA Video and Blackmagic Design, and the page on Supporting Multiple Media Configurations.

Getting Started with the Video I/O Setup

The Virtual Studio showcase is set up with three different media configuration, each one defined by a separate Media Profile Asset.

AJAMediaProfile_24fps_10bit exchanges SDI input video feeds and output captures with a device from AJA Video Systems.It's set up by default to get input from ports 1 and 2 on a Corvid 44 card, at 24 frames per second, using a 10-bit stream.

BlackmagicMediaProfile_24fps_10bit exchanges SDI input video feeds and output captures with a device from Blackmagic Design.It's set up by default to get input from ports 1 and 2 on a DeckLink Duo 2 card, at 24 frames per second, using a 10-bit stream.

FileMediaProfile is set up by default to get input from an .mp4 file on disk.This is the default configuration that will be active when you start your Project, so that you can immediately see some video playing even if you don't have a supported AJA or Blackmagic card installed.This configuration is not set up to capture any video from the Unreal Engine or Unreal Editor — it has no media outputs configured at all. So, while this configuration is active, you'll have video feeds coming in to the Level, but not going out.

To switch between these different configurations, press the down arrow in the Toolbar next to the current Media Profile, choose Select Profile from the drop-down menu, then choose the Media Profile you want to activate:



If you need to change the default port assignments or media settings (like frames per second, image resolution or color depth) to match the media setup you're working with on your computer, you can double-click any of these Media Profile Assets to open them up and edit their properties. You'll find the Media Profile Assets under the VirtualSet/MediaProfiles folder:



For more information on how Media Profiles work, see Supporting Multiple Media Configurations.

Media Sources and Playback

The Virtual Studio showcase uses two Media Bundles to bring in input video feeds and make them appear in the Level Viewport.

Only one is set up to be visible by default. This feed appears composited into the scene behind the presenter's desk.

The second video feed is hidden in the Unreal Editor, so you won't see it by default until you switch cameras — either in the Media Capture panel, or using the on-screen capture controls at runtime. For details, see Onscreen Capture Controls below. To force this second feed to show up in the Viewport in the Unreal Editor:

Select the VirtualSetMediaInput2 Actor in the World Outliner.

in the Details panel, enable the Plate > Show Plate in Editor option.

This second feed is also composited behind the presenter's desk, but at an angle designed to be viewed from a camera to the presenter's right.

Media Bundle Setup

Each of the two video input planes behind the presenter's desk is set up using a Media Bundle: VirtualSet/Media/VideoBundle_01 and VirtualSet/Media/VideoBundle_02. Each of these bundles has a corresponding folder that holds its Media Framework Assets, named with the _InnerAssets suffix.



To learn how to set up Media Bundles from scratch, see the AJA Media I/O Quick Start Guide or Blackmagic Media I/O Quick Start Guide .

One thing to note about the Media Bundles in the Virtual Studio showcase is that they don't use the default Blueprint class that is used by most Media Bundle Assets.

Typically, when you drop a Media Bundle Asset into a Level, a new BP_MediaBundle_Plane_16-9 Actor is automatically spawned to represent the video in the 3D space of the Level. This default Blueprint contains a Plane Component, which is automatically set up to refer to the Media Texture created in the bundle's _InnerAssets folder. It also contains a MediaSound component that handles playing back the audio from the associated media source.

In the Virtual Studio, the Media Bundle Assets are instead represented in the Level by a custom subclass of the BP_MediaBundle_Plane_16-9 Blueprint Actor: VirtualSet/Blueprints/VirtualSetMediaInput. This subclass acts just like its parent, except that it also expects to have a specific camera Actor assigned to it as a child in the World Outliner. You'll notice that each of the two video planes in the Level has a camera as a child:



This custom VirtualSetMediaInput subclass adds the ability to show and hide the plate in the Editor viewport, and to configure the distance between the plate and its assigned camera. When you select either the VirtualSetMediaInput1 or VirtualSetMediaInput2 Actor, you can set these options in the Plate category of the Details panel:



Double-click the Blueprint class to see its Construction Script and other functions if you want to see how these settings are implemented.

Proxy Media Sources

Each of the two Media Bundles in the Level is configured to pick up its video feed from a different Proxy Media Source Asset. For example, if you double-click VideoBundle_01, you'll see that it is set up to use the MediaProxySource_01 Asset as its source:



Similarly, VideoBundle_02 is set up to use the MediaProxySource_02 Asset as its source.

If you open the Project Settings panel (select Edit > Project Settings from the main menu), and find the Plugins > Media Profile section, you'll see that each of those two Proxy Media Source Assets is also referenced in the Media Source Proxy list:

Click for full image.

The order of slots in this list corresponds to the order of the slots in the current Media Profile. For example, the BlackmagicMediaProfile_24fps_10bit is set up with two input Media Sources. Slot 0 reads an input feed from port 1 on the card, while slot 1 reads the input feed from port 2 on the card:



The result of this configuration is that while the Blackmagic Media Profile is active, the VideoBundle_01 draws its input feed from port 1 on the card through one proxy, while the VideoBundle_02 draws its input feed from port 2 on the card through a different proxy. When you change Media Profiles, those proxies automatically re-map the input feeds to the first two input sources defined in the new Media Profile, instantly changing the video feeds that you see in the Level.

For more information on how Media Proxies work, see Supporting Multiple Media Configurations.

Keying and Compositing

The Media Bundles are placed behind the central desk with the intention of putting a seated presenter into the virtual 3D Level. In order to make this effect work, you'll need to remove the background behind the presenter in your input video stream. To do this, you typically record the presenter seated in front of a green screen (or blue screen), and remove the background through chroma-keying or luminance filtering.

Media Bundles, like the ones used in this showcase, are automatically set up to use a Material Instance that can perform this chroma-keying and luminance filtering for you live in the Unreal Engine.

To set this up:

In the Content Browser, find and open the Media Bundle you want to set up.

In the Toolbar of the Media Bundle Editor, click the Open Material Editor button to edit the Material Instance that the Media Bundle uses to draw the video feed on to an object in the Level.

In the Details panel of the Material Instance Editor, find the Keyer_00 - Setup section, and enable the EnableKeyer property.

With the EnableKeyer property activated, the Material Instance makes new properties visible in the other Keyer sections in the Details panel. You can use these properties to configure the color that you want to remove from the video stream, filter the stream based on the luminance of the pixels, crop, and color correct the stream.

Capturing Output Video

In order to capture video from the Unreal Engine using the instructions in this section, you need to have a supported SDI card from AJA Video Systems or Blackmagic Design.

To start sending video from the Unreal Editor to your AJA or Blackmagic card:

From the main menu, select Window > Media Capture. You can use the tools in this window to identify which Media Outputs you want to receive output from the Unreal Engine. You can also specify which cameras in the Level or which Render Targets you want to send video to each of those outputs.In the image below, the Media Capture window is set up to broadcast from the two cameras in the Level to the MediaOutput_01 Proxy Media Output Asset. The Project Settings for the Virtual Studio sample are set up to redirect the video sent to MediaOutput_01 to the first output source configured in the active Media Profile. If you're using either the AjaMediaProfile_24fps_10bit or BlackmagicMediaProfile_24fps_10bit Media Profile, this will end up sending the output to the fourth port on the card.

Click the Capture icon at the top of the window to start capturing.

At the bottom of the window, you'll see a preview that shows the viewpoint of the first camera in the Locked Camera Actors list. If you have a video device attached to the fourth port on your card, you should see the same video being sent out over that port. The Media Capture window places a button above the preview for each camera that appears in the Locked Camera Actors list. Use these buttons to switch the output between the different viewpoints.

The showcase is also set up to send captures to the video card at runtime, using an on-screen control UI. To get started:

Click the arrow next to the Play button in the toolbar, and choose either the New Editor Window (PIE) or Standalone Game options.

Video capture from the Editor will only work when you play your Project in a New Editor Window (PIE) or a Standalone Game. It won't work in the default Selected Viewport mode, or in Simulate mode.In addition, the viewport resolution of your Project (that is, the size of the rendered image the Unreal Engine generates each frame) must match the output resolution set in the active Media Profile, so that it will be the right size for the output video feed.

You'll start with the front view of the presenter's desk, some controls on the top left, and a thumbnail image for each camera in the Level.

Click for full image.

To change the current camera view, you can click any camera thumbnail, or you can click the Next Camera button (1) to cycle through the cameras.

Toggle the Enable Video Output checkbox (2) to start and stop sending the current viewport to the video card.

The on-screen runtime capture controls are also set up to send the selected camera feed to the MediaOutputProxy_01 Asset, which the Project Settings forward on to the first output configured in the current Media Profile. For details on how this is set up, see the On-screen Capture Controls section below.

On-screen Capture Controls

You'll find the Assets for the on-screen camera control UI in the Virtual Set/Blueprints folder:



The CameraSwitcherUI UMG widget contains the main on-screen elements, including the Next Camera button and the checkbox for toggling the capture of the current view.

Behind the scenes, all the work that happens when you click in the UI is handled by the CameraSwitcher Blueprint class. You can look in its event graphs to see the implementation of all the camera switching logic. The logic that relates to starting and stopping the video capture is in two main places:

In the Event Graph, the Create Media Capture node creates a new Media Capture object from the MediaOutputProxy_01 Asset that is set up in the VideoOutputSettings variable, and stores it in a variable called Media Capture.

Click for full image.

In the Enable Video Output function, that Media Capture variable is used to start and stop capturing the viewport.

Click for full image.

The CameraSwitcher needs to be set up with a list of all the VirtualSetMediaInput objects that should be managed by the UI. When the Level is loaded, the CameraSwitcherUI automatically creates a new thumbnail for each input in this list.

One instance of the CameraSwitcher Blueprint class is added to the Level. If you select this Actor in the viewport or in the World Outliner, you can use the settings in the Details panel to control its behavior.



Property

Description

Video Output

Enable Output by Default

Enable this setting to have the CameraSwitcher immediately start capturing video output and sending it to the Media Output set in the Video Output Settings when you run the Project.

Video Output Settings

Sets the Media Output Asset that the CameraSwitcher uses to create a Media Capture and send video output to the SDI device. The settings for this Asset determines which device, and which port on that device, receives the captured video stream. By default, this uses the VirtualSet/Media/MediaOutputProxy_01 Asset, which is set up in the Project Settings to send its output to the first output port defined in the active Media Profile (if any).

Cameras

Camera List

Lists all the VirtualSetMediaInput Actors that the CameraSwitcher can manage at runtime.When you run the Project, the CameraSwitcher UI creates a camera thumbnail image for each Actor in this list, showing the video input stream being managed by that Actor.

User Interface

Show UI

Determines whether the on-screen CameraSwitcher UI is visible when you run the Project.

Video Wall

The large video wall to the presenter's left doesn't rely on any input from any of the Media Profiles. It's mostly built using the basic building blocks provided by the Media Framework.

Click for full image.

You'll find the Media Framework Assets used for the video wall inside the Virtual_Studio_Kit/Textures/Video folder.



EngineFeatures is a File Media Source that is set up to read video from an .mp4 file, which you can find in the Project's Movies folder. WallMediaPlayer controls the playback of the video from that EngineFeatures file source. And when that WallMediaPlayer Asset was created, it automatically created a corresponding MediaTexture Asset, T_WallMediaPlayer, to receive the frames read from the video source.For a step-by-step guide to creating these kinds of Assets to play back your own video files, see the Play a Video File how-to page.

The M_WallVideoPlayer Material samples the pixels from the T_WallMediaPlayer Media Texture and sends them to the Emissive output. This gives the video a little extra glow when it is rendered on the screen.

Finally, WallPlayerSetup is a Blueprint whose construction script starts the video wall playing back in a loop. An instance of this class is already placed in the Level, so the video begins playing on the wall each time the Level is loaded and the class is spawned. That way, the video wall is always playing in the background, regardless of whether you're in the Unreal Editor or running your Project.



Click for full image.

Modular Studio Kit

The Virtual Studio sample contains a library of modular Assets that includes Static Meshes, Materials, Textures, and more. You can use these Assets to create your own studio layouts similar to the one you see in the default Level described in the sections above.

You'll find this Asset library in the Content Browser, under the Virtual_Studio_Kit folder:

Click for full image.

There are also several Levels in the Maps folder that contain prebuilt studios:

Click for full image.

You can open these up in the Unreal Editor to see examples of the kind of virtual studio layouts you can construct using only the Assets in the kit.

Drag the slider to see sample studio layouts



Unlike the default TrackerlessStudio Level that opens when you start working in the Virtual Studio sample, the other sample studio Levels in the Maps folder are not set up with cameras and media plates by default. If you want to bring SDI video feeds into one of these sample Levels, you'll have to set it up with new CineCamera Actors and VirtualSetMediaInput Actors. Follow through the sections above to understand the way the default Level is set up, and use this as a model that you apply in your own Level.

Sample Game Projects are simplified gaming experiences created by Epic's developers and artists to allow you to see an approach to a specific game type. Naturally, these will not represent the only way to create that particular type of game; rather, they show one possible approach.

We intend users to analyze and pick apart these examples taking the parts that are most useful to them. The documentation over each one is designed to aid in this process and provide some insight into how each game was designed and created. You may feel free to use any of these systems or elements in your own games.



Explore how to develop projects in UE5 using techniques from the Lyra Sample Game.



Take a guided tour of Valley of the Ancient, the UE5 Early Access showcase project.

Downloading the Lyra Starter Game

Downloading Lyra for Engine Source Builds

Playing the Game Sample

Lyra Framework Systems

Topics

Lyra is a learning resource designed as a sample game project to help you understand the frameworks of Unreal Engine 5 (UE5). Its architecture is designed to be modular, including a core system and plugins that are updated regularly along with the development of UE5.

Cross-Platform compatibility and scalability.

Online Multiplayer and cross-play support for Epic Online Services and Console Online Subsystems.

Features a choice between three different Game modes: Elimination (Team Deathmatch), Control (Capture the Control point) and Exploder (a top down party game).

A customized Gameplay Ability System.

Niagara FX.

Unreal Motion Graphics (UMG) widget classes and UI Icons for the project's gameplay concepts including menu settings, controller key sticks, and displays for health, mana, and ammo. These UI features are designed with modularity so you could use their systems in your own game independent of Lyra.

Optimized, hand-crafted content including locomotion animation assets, sounds, and a weapon system compatible with any Pawn.

New UE5 Mannequins, Manny, and Quinn. These Mannequins are playable characters that share the same core skeleton hierarchy as MetaHumans, with a compatible animation system.

Downloading the Lyra Starter Game

You can download the Lyra Game Sample from the Epic Games Launcher, by clicking the Samples tab and navigating to Lyra Game Sample, or by clicking on the Marketplace tab and typing "Lyra" into the Search field.



From the Lyra sample page, you can select Create Project to make a new copy of the sample on your hard drive. If you are using a launcher version of Unreal Engine then you can place it anywhere on your hard drive.



Downloading Lyra for Engine Source Builds

You can download your own source build of Unreal Engine, refer to Downloading Unreal Engine SourceCode.

When you have finished downloading your Unreal Engine source build, you will want to download and install Lyra inside the top level directory of your custom-built engine. After selecting a top level directory, it will create a LyraStarterGame subdirectory, then create a LyraStarterGame.uproject file including the source code and content.



To launch your installed copy of the sample, you can either double click the .uproject file or launch the sample directly from the Library tab of the launcher.



If you are using a custom-built version of the engine, you can recreate project files and launch Lyra as a project from inside your source code editor such as Visual Studio.

If you right click the LyraStarterGame.uproject file you can associate it with a different installed version of the engine if you have multiple copies installed, or generate project files for compiling with a source code editor.



Playing the Game Sample

When you launch Lyra, the DefaultEditorOverview level will be loaded as the Default Map. From the Editor, you can click on Play In Editor(PIE) to launch the default level.



When in PIE, Your Player Controller will take possession of the Lyra Pawn. In the level there are several portals that load into an Experience.



The table below provides a brief description into each map:

Game Mode Map

Description

Content File Path

Control

Secure the control points along with your teammates to increase your score and win.

/ShooterMaps/Maps/L_Convolution_Blockout

Elimination

Find and eliminate enough enemies to win in this classic head-to-head team match.

/ShooterMaps/Maps/L_Expanse

Front End

Contains the Main Menu of the Lyra sample game.

/Game/System/FrontEnd/Maps/L_LyraFrontEnd

Default Map

The base example of the user facing map.

/Game/System/DefaultEditorMap/L_DefaultEditorOverview

Shooter Gym

A small test level to test the ShooterCore plugin functionality.

/ShooterCore/Maps/L_ShooterGym

Exploder

Destroy blocks, collect power-ups, and avoid getting exploded in this top-down party game.

/TopDownArena/Maps/L_TopDownArenaGym

The maps for each game mode can be loaded directly in the editor by using File > Open Level and navigating to the content file paths listed above.



Most of the maps are located inside game feature plugins. After loading a map like Expanse for the first time, the Editor Viewport will be empty because it is a World Partition map.



To see the level Actors, select the world partition grid cells by clicking and dragging in the bottom right World Partition details panel, then right click and select Load Selected Cells to load that part of the map.



Using PIE while one of the Game Mode levels is open will load the appropriate game mode as if you had walked into the appropriate portal on the default map.

For more information on Lyra's Game maps and menus, refer to the A Tour of Lyra reference page.

Lyra Framework Systems

Lyra makes use of the Gameplay Feature Plugins, this means that the Content folder only contains generic assets and the main lobby, however, the plugins folder contains the different core elements that create the Lyra Starter Game.



When a game experience is chosen inside the lobby, the game will load the plugins that are required. For example, choosing the Expanse Team Deathmatch_ map will load **ShooterCore** for the pawn and mechanics, and **ShooterMaps** for the level.

Plugin Folder Name

Description

Lyra Example Content

Contains shared materials, such as grids.

Shooter Core Content

The core elements of the LyraShooterGame experience. This includes gameplay logic for game modes, specific Gameplay Abilities like Dash, and Blueprints for Actors such as teleporters and grenades, Bots, Weapons and User Interface elements.

ShooterMaps Content

The maps used by the LyraShooterGame (Expanse and Convolution), with associated materials and content.

TopDownArena Content

The content for the TopDownArena experience, from the map generator to power ups.

Experiences are defined using a LyraExperienceDefinition class. You can access the Default Gameplay Experience from the World Settings by navigating to the Toolbar > Window > World Settings > Game Mode.



You can think of experiences as a much more advanced version of a GameMode. Multiple Experiences can exist inside a plugin, for example the experiences Team Death Match and Control Points both use the ShooterCore plugins and are derived from the same parent class(B_LyraShooterGameVase, a child class of the LyraExperienceDefinition.)

These classes contain the information that are used in Lyra's input and gameplay mechanics. While other options contain information like the scoring system (based on Elimination for Team Deathmatch and Capture for Control Points)

Topics



The Common User plugin provides a common interface between C++, Blueprint Scripting, and the Online Subsystem(OSS) or other online backends.



An overview of how Lyra uses the Gameplay Ability System for its Gameplay.



An overview of the Animation System in Lyra



An overview of Game Settings for the Lyra Game Sample.



An overview of how Geometry Tools was used in Lyra to create parametric level level design geometry objects in Blueprints, and the workflows that Level Designers use to build the level with these pieces.



An overview of how Lyra uses its Input Settings system to solve many common input configuration setups.



An overview of the Lyra Interaction System for the Lyra Game sample.



Explore the Inventory and Equipment systems used in the Lyra Sample Game.



An overview of Scalability and Device Profiles in the Lyra Game Sample.



Reference page of Lyra in Unreal Engine



Documents the major changes to Lyra for each engine version and includes information that help you upgrade existing games to take advantage of the newest release of Unreal Engine 5.



A step-by-step tutorial describing how to use the Lyra sample game for working with Epic Online Services.

Design Philosophy

Installing the Plugin

Using the Online Services Interface

Lyra and Common User

Common User Subsystem

User Initialization Flow

Requesting User Initialization

Other Operations

Common Session Subsystem

Requesting Session Initialization

Common User Plugin

The Common User plugin provides a common interface between C++, Blueprint Scripting, and the Online Subsystem (OSS) or other online backends. It is distributed as part of the Lyra Starter Game and as a standalone plugin that can be used in any project.

Design Philosophy

OSS was designed to be a generic interface for accessing platform-specific functions such as login, authentication and multiplayer sessions. It provides a standard interface that can be called from general Unreal Engine code to do a variety of operations. Because it is a generic and flexible library, it does not provide direct support for the high level flow of a typical gameplay session. Common User is an optional plugin that provides utility functions that help support features like an engagement screen, game controller handling, and hosting multiplayer games.

The features of Common User are exposed using Engine Subsystems that can be called from C++ or Blueprint. The Lyra Starter Game provides an example of how to use these features and integrate them into a game. Common User works with the existing OSS in addition to other systems like the experimental Online Services Interface. Because it is defined in a game plugin, it can be modified or subclassed to work with proprietary online systems.Common User will be updated to support many game-related online features such as Leaderboards and Achievements. It currently provides support for the core operations(Login, Authentication, and Sessions) required to ship a commercial multiplayer game on multiple platforms.

Installing the Plugin

To install the plugin into your game:

Acquire the content and source code of the Lyra Starter Game from our Unreal Engine Github, or the Learn Tab on the Unreal Engine Launcher.

Common User is not designed to be used in a Blueprint-only project.

If you have access to platforms that are not included in the public release of the engine, you will need to use the version of the sample that includes those platforms.

Navigate to the c:Lyra/Plugins folder located on your system, then copy the CommonUser folder into your game project's folder.

In the editor, navigate to the Toolbar and click Edit > Plugins, then from the Plugin browser search for and enable the Common User plugin.



You will need to enable any platform-specific online service plugins required for your project.

Recompile your project to enable the subsystems.

Observe the .ini files located in the c:Lyra/Config and the c:Lyra/Platforms/PlatformName/Config folders, then copy any values that you wish to use with your own .ini files.

The settings and comments located in the Lyra config files can be used as a general guide for setting up your own project config settings, and the in-editor Project Settings can be used to commit some of the changes. See the Lyra Scalability and Device Profiles for more information.

Blueprints will now have access to the Common User subsystems. To enable support for C++, you need to add CommonUser to the PrivateDependencyModuleNames section of your ModuleName.Build.cs file.

See Unreal Engine Modules for additional documentation.

Using the Online Services Interface

By default, the Common User plugin uses the existing Online Subsystem interface available in UE4.

In future releases of UE5 this interface will be replaced by a new Online Services interface(OSSv2) which provides improvement in asynchronous commands and error handling.

Online Services is experimental, therefore the initial release of the Common User plugin does not use it by default. To swap the plugin to use the new interface, you can modify the CommonUser.Build.cs and change the bUseOnlineSubsystemV1 boolean to the value of false, then navigate to the game's Config/DefaultEngine.ini config file, and add the following line.

This enables the build dependencies required to use the new interface. To use EOS OnlineServices, you need to disable the Epic Online Services(EOS) OnlineSubsystem in any config file containing the section [OnlineSubsystemEOS].

For example, in the Lyra/Config/Custom/EOS/DefaultEngine.ini file, you should set the bEnabled boolean value to false.

Using the experimental Online Services interface is recommended for games that are designed to be compatible with future releases of the engine. If you are developing a custom online backend or plan to use EOS as your primary backend, then you can enable Online Services support.

Lyra and Common User

Lyra interacts with the Common User plugin in both C++ and Blueprint. Below are some examples of how Lyra uses the systems provided by this plugin:

The CommonGame C++ plugin includes classes like the CommonGameInstance(UCommonGameInstance). A game-specific GameInstance subclass can inherit from the CommonGameInstance class to integrate with features of the CommonUser and CommonUI plugins. You can use the code inside the class as an example of how to integrate your project with a different UI system.

The LyraFrontEndStateComponent(ULyraFrontendStateComponent) accesses the CommonUser subsystems directly from source code. This class is part of the logic that uses CommonUI to display the platform-specific Press Start screen (W_LyraStartup) before the main menu(W_LyraFrontEnd) is shown.

Multiple Widgets like W_LyraStartup access the CommonUserSubsystem directly and use functions or async nodes to handle user operations.

The LyraUserFacingExperienceDefinition(ULyraUserFacingExperienceDefinition) class describes how to launch a game session with menu options that are standard with a multiplayer FPS. It is used by Widgets like W_HostSessionScreen to create a session description that is passed into the CommonSessionSubsystem to host or join a game session.

The Lyra Starter Game is designed to be a working example of the Epic Online Services (EOS) subsystem. By default, Lyra uses the Null subsystem, which only supports multiplayer in the editor or on local area networks. To enable support for EOS, you can either use the LyraGameEOS target when creating a packaged build or add the following option to your command line:

This will load the EOS-specific config files from your c:Lyra/Config/Custom/EOS directory. These config files should be modified to use the EOS identifiers specific to your project.

Plugin Subsystems

Common User Subsystem

The Common User Subsystem (UCommonUserSubsystem) is designed to handle the user login, authentication, and permission check operations. These operations are required to use features like saved games that are tied to a player's profile. In an online-enabled game, user login is the first step that occurs because it is required before other online features will work. The Common User Subsystem handles initializing OSS interfaces like Identity, and provides access for other Subsystems or Gameplay code. This subsystem defines the enumerations and structures used to describe the state of an individual user. In the table below, you can observe the important types used throughout the system:

System Type Name

Description

ECommonUserOnlineContext

An Enumeration that identifies which lower level online system should be used for an operation. Blueprints and high-level C++ code will generally use the default context (Game) which combines information from multiple sources. On platforms like consoles that have their own authentication layer, the Platform context can be used to explicitly access it. The Service context can then be used to explicitly access services like EOS that work on top of the platform layer to provide features like crossplay.

UCommonUserInfo

An Object that is used to store the state of each individual user that is being managed by the system. Each user has their own Unique Net Id which is used to identify that user in classes like the PlayerState. In a single player game there will only be one User Info, but in a local multiplayer game there can be multiple User Info Objects that correspond to a platform-specific user(or a guest on platforms that do not support multiple local users.)

ECommonUserInitializationState

Describes the overall Login/Initialization state of a user. This state is modified as a user goes through the login steps described in the User Initialization Flow section below.

ECommonUserPrivilege

An Enumeration that describes the different capabilities and actions that users may perform as part of a Gameplay session.

ECommonUserAvailability

Describes the general level of availability for a privilege or other feature. For example, if the user has authenticated their account but the internet connection is currently offline, the availability of the privilege CanPlayOnline would be set to CurrentlyUnavailable.

User Initialization Flow

Logging in and authenticating a user is a complex, multi-step, and platform-specific process that takes a few seconds to perform. Below are the order of steps involved in the User Initialization flow:

The person that wants to play the game needs to be identified as a user. On platforms like PC and Mobile, this happens before the game has started and the user's identity is sent from a launcher process. On platforms like consoles that support multiple logged in local users, an engagement screen(Press Start) must be used to identify the physical controller that the player wants to use to play the game.

The user needs to be logged in and authenticated by using the platform interfaces. In some cases this happens automatically for the first identified user, while in other cases a platform-specific screen needs to be shown that explicitly maps a physical controller to a platform user.

The privileges for that user need to be queried to determine if they are allowed to play the game. These privileges include platform-specific checks for valid software licenses or banned accounts.

An initialization state of LoggedInLocalOnly is reached. The user is able to play the game locally and will have full access to profile-related operations like save games. However, they may not be able to play online or use other network privileges. To complete online initialization additional steps are required.

The user may need to be logged in and authenticated a second time, possibly with a different online service.

A different set of privileges for that user needs to be specifically queried for online play. This may include checking for active subscriptions and age restrictions.

After passing the second set of privilege checks, the user is fully initialized for online play (LoggedInOnline) and is able to create or join multiplayer sessions.

At any step in the process, a user can be forcibly logged out by the platform. This may require the game to be restarted because profile actions like save games are no longer available. In many cases this will require restarting the entire initialization flow.

A primary goal of the Common User Subsystem is to provide you with the functionality that allows individual games to ignore the complexity involved in this process.

Requesting User Initialization

A state machine is built into the Common User subsystem that keeps track of which step a user is on during the initialization process. There are multiple methods you can use for starting this process.

User Initialization Method

Description

Initialize for Local Play Login for Online Play

These Blueprint nodes can be placed in the Event graph of a Widget or other Blueprint to request a local-only or online login for a specific local player and physical controller. This is the simplest setup and it will activate the complete exec pin when initialization has succeeded or failed.

OnUserInitializeComplete

A delegate that can be bound from either Blueprint or C++ and is activated whenever a user completes initialization.

TryToInitializeUser

A function used to start a more advanced initialization process that will eventually execute the OnUserInitializeComplete delegate.

Listen for Login Key Input

A function used to create an initial engagement screen(Press Start) or allow the capability to add controllers in local multiplayer. This is achieved by registering a temporary input handler that listens for certain controller buttons or keyboard keys, then calls TryToInitializeUser with the correct parameters.

LoginLocalUser

A function that can be called from C++ if you want to manage the initialization manually..

These functions are used in the Lyra menu widgets(W_LyraStartup) and C++, to show an explicit engagement screen on multi-user platforms, or attempt to automatically log in user_0 on controller_0 for PC and Mobile platforms. This is done by calling the ShouldWaitForStartInput function, however if you are creating a single player game, you may want to always show an engagement screen. An explicit login for online play is requested in widgets like W_ExperieceSelectionScreen that can start online sessions.

There is no controller parameter for this online login because the user should have already completed local initialization.

Other Operations

The Common User Subsystem provides other useful functions that you can use to query or change information for a particular user. You can look at the blueprint functions using the Common User Subsystem or read the CommonUserSubsystem.h file for details.

Common User Subsystem Function

Description

OnHandleSystemMessage

A delegate that can be bound to display error messages related to online functions. The UCommonGameInstance class in Lyra shows a simple error popup, and SendSystemMessage can be used to trigger this UI from gameplay code.

OnUserPrivilegeChanged

A delegate that can be bound to handle any privilege change for a user. This is used to provide game-level handling for cases like losing network connectivity.

GetUserInfoForLocalPlayerIndex GetUserInfoForPlatformUserIndex GetUserInfoForUniqueNetId

The main method of querying information about a user. They return CommonUserInfo objects that can be queried for their network id, display nickname, and privileges.

GetOnlineIdentity GetOnlineSubsystem

A lower-level wrapper function that can be used by gameplay code or other subsystems to access the cached interface data. These functions are specific to the online interface being used.

Common Session Subsystem

The Common Session Subsystem(UCommonSessionSubsystem) is designed to provide a simple interface to access online features that include creating, searching, and joining online Gameplay sessions. The OSS Session Interface provides platform-independent wrappers for operations that can interact with a platform's native matchmaking interface and a cross platform system like EOS. Depending on the game and platform, a multiplayer session may be physically hosted by a dedicated server or by a player who is also playing the game. Player-hosted(listen) servers are run on a console or user-owned PC that must be accessed by using a form of Peer-to-Peer(P2P) NAT traversal(like EOS). The goal for all multiplayer gameplay sessions is to connect two instances of the game together so they can use all features of the Unreal Engine Networking system. However, before connecting the two instances, intermediate structures(known as Lobbies or Sessions depending on the situation) need to be created and queried.

Requesting Session Initialization

There are multiple methods that you can use to initialize a session using the Common Session Subsystem but the table below lists the basic options available:

Initialization Method

Description

HostSession

Can be called with a Host Request that describes the specific Gameplay mode and map that will be loaded. This can be used to create a single player session that does not register with the online backend, so your UI does not need to understand the difference between them. Once the session has been created, the specified map will be loaded and gameplay will begin.

FindSessions

Can be called to ask an online system for a list of joinable sessions that match the search request.It takes a Request(UCommonSession_SearchSessionRequest) and a SearchingPlayer (APlayerController) parameter to look for public matchmaking games that satisfy the provided arguments. The OnSearchFinished delegate implemented on the Request object will be called when the search is completed and the search result objects (which are filled in on the request object) can be used to join a session.

JoinSession

Takes a search result object and attempts to connect and join that multiplayer session. If successful, the game will connect to that peer or dedicated server and attempt to join the game as a network client.

QuickPlaySession

Starts the process to look for any existing public sessions that match the host parameters and will join them if possible. This method combines the other three initialization functions and is called with a host request. If joining a session is not possible, then it will start a new session. CommonSessionSubsystem provides a basic implementation, but games can override quickplay-related functions in a game-specific subclass if needed.

Lyra interacts with the Common Session subsystem in several Widget Blueprints:

Widget Blueprint

Description

W_ExperienceSelectionScreen

Handles quick play in addition to choosing to either host or search for sessions.

W_SessionBrowserScreen

Handles searching and joining existing sessions.

W_HostSessionScreen

Allows specifying the hosting rules and creating a new local or multiplayer session.

These Widgets rely on assets from the LyraUserFacingExperienceDefinition class located in your c:Lyra/Source/LyraGame/GameModes directory. This class defines the types of specific Maps and Gameplay modes that can be used in the game. The Lyra source code also includes checks to ensure that sessions are properly cleaned up in memory when a player leaves a game or has login failures.

Both the CommonSession Subsystem and Lyra are designed to search and create P2P hosted sessions that use the EOS Lobby interface (when support is enabled as described above.) It works with the local sessions that are created while testing multiplayer in the editor with the OnlineSubsystemNullNull subsystem. To enable full support for other online backends In the initial release of the plugin, you may need to change some of the options passed to the internal session objects like FOnlineSessionSearch.

What is the Gameplay Ability System and Why Use It?

ULyraAbilitySystemComponent

ALyraPlayerState

ALyraGameState

Game Phase Abilities

Input Tag Activation Support

Expanded Tag Relationship System

ULyraGlobalAbilitySystem

ULyraAbilitySet

ULyraGameplayAbility

Activation Group

Activation Policy

K2_CanActivateAbility

Additional Costs

Added and Removed Events

Camera Modes

Type Tags

Native Ability Subclasses

Blueprint Ability Subclasses

FLyraGameplayEffectContext

What extra data is included?

How is the extra data accessed?

ULyraAttributeSet

ULyraHealthSet

ULyraCombatSet

How Healing and Damage Work

Heal Execution

Damage Execution

Additional Information

How do Damage Numbers Work?

How are Lyra Characters initialized?

Blueprint Asset Naming Conventions

Lyra uses the Gameplay Ability System (GAS) to orchestrate most of its gameplay. Abilities can be innate to hero data like jump, granted from an action like a Game feature, gained through Experience, or granted from Equipment.

What is the Gameplay Ability System and Why Use It?

The Gameplay Ability System is a plugin that provides a framework for quickly implementing and iterating on gameplay mechanics. When writing code for complex gameplay mechanics that can include multiplayer, you may write a lot of common boilerplate functionality that applies over many different game types.

GAS attempts to abstract mechanics into common game design patterns, and provides a framework that solves common gameplay implementation problems while letting context vary from project to project.

Writing boilerplate code is often error-prone and time consuming, especially for multiplayer games. For example, you don't want to spend a significant amount of time ensuring your Health values are replicating correctly, or copying the same lines of code over when you decide to have an Energy value that behaves identically.

The GAS addresses these issues by providing a foundation that fulfills common gameplay functionality as much as possible, while staying mechanic-neutral. Instead of forcing concepts such as Health, Ammo, Melee Attack, or Poison Debuff, GAS provides tools to define, replicate, and work with Attributes, Abilities, and Effects, which can then be specialized to fulfill the needs of the given gameplay mechanic.

Lyra implements abilities for common actions such as using weapons, movement-related actions like jumping and dashing, and passive listening actions such as triggering respawn after death. Abilities are also used for less obvious purposes such as summoning match information UI or managing gameplay phases. These are detailed in sections below.

GAS is structured around the following core classes. Lyra extends many of these to provide additional functionality:

Core Class

Description

UAbilitySystemComponent

An Ability System Component (ASC) can be added to any Actor to provide it with GAS functionality. This keeps track of the state for that specific Actor, and handles replication.

UAttributeSet

A collection of Attributes, or numeric values with a specific meaning within your game mechanics. Attributes can represent game resources such as ‘Health', reference values that can affect other game rules, such as ‘Base Attack Power', or even stateless quantities such as ‘Applied Damage'. Attribute Sets are responsible for defining, managing and replicating one or more Attribute properties.

FGameplayTag

An arbitrary hierarchical identifier that can be applied to a game object. These can be used to identify, categorize, and filter game entities. They can be granted or revoked by Gameplay Effects and Abilities, and can affect their behavior. One example is a ‘Gameplay.DamageImmunity' tag that prevents damage on an owner's avatar/pawn.

UGameplayAbility

A game action that can be granted to, and performed by, a GAS-enabled Actor, along with information to determine its requirements, costs, and other behaviors. Examples range from basic melee attacks to a self-contained game menu flow to a triggered behavior caused by another game action.

UGameplayEffect

The consequences of a game action. Effects can temporarily or permanently modify attributes, grant or revoke tags, enable access to other abilities, and much more. Gameplay Effects are the most common way in which GAS-enabled Actors interact with each other.

The main benefits of GAS are:

Network Replication: You don't need to worry about ensuring your attributes or debuffs are applying or replicating properly. GAS takes care of the inner logic for you.

Modularity: Adding or changing game mechanics is often as easy as implementing and granting a new ability. By breaking down gameplay functionality into separate assets, the ability system can provide a common communication layer between radically different game objects or mechanics. For example, Health can be compartmentalized into its own Attribute Set and interacted with through Gameplay Effects from a variety of systems.

Fast iteration: GAS makes it easy to change individual game rules without the need to modify the entire system. Data sources for game calculations can be easily swapped, and changing the consequences of an action can be modified from the corresponding Gameplay Effect.

ULyraAbilitySystemComponent

The Lyra Ability System Component (ULyraAbilitySystemComponent) extends the Ability System Component (UAbilitySystemComponent) functionality to interface with the Lyra framework. It is added to all LyraPlayerState instances and can be found in your c:Lyra\Source\LyraGame\AbilitySystem\LyraAbilitySystemComponent.h file directory.

ALyraPlayerState

Lyra Player States(ALyraPlayerState) own the Ability System Components used for all player-specific abilities and behaviors. Human players and AI bots will each have one. You can access this class in your c:\Lyra\Source\LyraGame\Player\LyraPlayerState.h file directory. The main benefit of adding an Ability System Component to the Player State class is that it helps separate the GAS state logic from the underlying Pawn data.

Separating this logic is useful in games where the player's Pawn will need to often be respawned, or if a Player is switching control between multiple Pawns, or in instances of gameplay where they may not currently be in possession of a Pawn.

This guarantees that some of its Abilities, Attributes, and Effects persist between possessing Pawns. This logic provides an easier process to retain the GAS state between the game phase changes. However, special care is required when initializing and de-initializing the Pawn-specific GAS state every time you Possess or Unpossess a Pawn.

Lyra accommodates this through the ULyraHeroComponent and the ULyraPawnExtensionComponent. These Components are responsible for granting a specific set of Abilities, Attributes, and Gameplay Effects to the PlayerState's AbilitySystemComponent when it's possessed by a valid Controller. These are revoked automatically when the Pawn is eliminated, unpossessed, or otherwise removed from play.

You can navigate to the ULyraHeroComponent from the c:\ReleaseWorkspace\Samples\Games\Lyra\Source\LyraGame\Hero\LyraHeroComponent.h directory and the ULyraPawnExtensionComponent from the c:\Lyra\Source\LyraGame\Pawn\LyraPawnExtensionComponent.h file directory.

ALyraGameState

High-level game phase logic is managed server-side by the Lyra Game State (ALyraGameState) class, located in your C:\Lyra\Source\LyraGame\LyraGameState.h file. Game States exist on both the client and server, and use an Ability System Component with Game Phases that are implemented as abilities. These Game Phases are activated and deactivated to affect how gameplay events are handled. As an example, ShooterCore implements three phases:

Phase

Description

Warmup

During this phase, a damage immunity Gameplay Effect is applied to all players, then starts a replicated countdown, removes the immunity, and transitions to Playing state.

Playing

In this phase, the Game has begun and is currently in play. Scoring and time limits are tracked, and will transition to PostGame when appropriate.

PostGame

This phase reapplies damage immunity and disables controls on all players, then transitions to the next match round.

While Game States exist on both the Client and Server, Game Mode is server-only

Game Phase Abilities

Game Phase abilities extend from the ULyraGamePhaseAbility class, with each ability encapsulating an individual state. The Game State logic assumes ability activation is phase start, and ability end is phase end. This provides you with the capability to listen for the start or end of specific phases, using the Gameplay Tag GamePhaseTag.

You can switch phases from Blueprint using the Lyra Game Phase Subsystem (ULyraGamePhaseSubsytem), which ends the previous phase ability (if it's running) and activates a new one.

Input Tag Activation Support

Abilities granted through the Gameplay Ability Set (UGameplayAbilitySet) will automatically check for activation if a matching Input Tag is received from[Lyra's Input system](). This streamlines ability activation without having to rely on opaque numeric Input ID numbers or manually handling Input Action events. Examples include jumping (GA_Hero_Jump) and weapon firing (GA_Weapon_Fire), described below.

Expanded Tag Relationship System

GAS Abilities and Effects provide the functionality to block or cancel specific Abilities based on which Gameplay Tags have been granted to their owner, typically by other Abilities or Gameplay Effects.

This information is held by each specific Ability and Effect, which may be inconvenient when you need to make overarching changes to these relationships. For example, as your game grows and its rules become more complex, it can lead to errors and inconsistencies when updating your game rules.

Lyra provides an improvement to this workflow by introducing the Lyra Ability Tag Relationship Mapping (ULyraAbilityTagRelationshipMapping) data assets. These hold a list of blocking, canceling, and required tag relationships. They can be created through the Content Browser > Add > Miscellaneous > Data Asset.

You can specify an Ability Tag Relationship Mapping asset as part of an ULyraPawnData asset, and it will be assigned to the corresponding Lyra Ability System Component when the Pawn is possessed. When the Ability System Component holds a reference to a valid tag relationship mapping, it will apply these as an additional layer of activation and cancellation conditions for ability activation.

ULyraGlobalAbilitySystem

The Lyra Global Ability System (ULyraGlobalAbilitySystem) provides a quick means of keeping track of and interacting with all Lyra Ability System Components in a level.

A Lyra Ability System Component will automatically register with the subsystem during initialization. Currently, the subsystem provides Blueprint-callable functions to grant or remove Abilities and Gameplay effects from all registered Ability System Components.

For example, Lyra's Elimination mode applies a Gameplay Effect (GE_PregameLobby) globally during the warm-up phase of a match. It grants a damage immunity tag to all players and triggers a Gameplay Cue that enables a UI element indicating that the match hasn't started yet.

ULyraAbilitySet

The Lyra Ability Set (ULyraAbilitySet) is a Data Asset type that can be created from the Content Browser. It holds a list of Gameplay Abilities, Gameplay Effects, and Attribute Sets which will be granted to a Lyra Character when the Ability Set is applied.

Parties that grant Lyra Ability Sets, such as Game Features or Equipment, are responsible for tracking which Actors they are granted to. A helper struct, FLyraAbilitySet_GrantedHandles, is used for bookkeeping and removal.

Method

Description

Granted Gameplay Abilities

A list of Lyra Gameplay Abilities to grant, along with the default level to grant the ability at and an optional Input Tag to associate with the ability.

Granted Gameplay Effects

A list of Gameplay Effects to grant, along with the default level to grant the effect at.

Granted Attributes

A list of Attribute Sets to grant.

Ability Sets can be granted in a variety of ways:

Method To Grant Ability Set

Description

ULyraExperienceDefinition ULyraPawnData

A list of Ability Sets is defined in the ULyraPawnData asset. These assets can be referenced from the ULyraExperience Definition, and its Ability Sets will be granted to the player's Pawn automatically upon initialization. This is mediated by ULyraPlayerState when the Experience is loaded.

These abilities are granted to the Player State, not the Pawn it possesses. They may be granted before a Pawn is possessed and persist even if the possessed Pawn changes. They won't be Activated until the Pawn itself is possessed, even if their Activation Policy is set to On Spawn. Plan accordingly.



Game Feature Actions

UGameFeatureAction_AddAbilities can grant Ability Sets to an Actor upon activation. These Actions can be added to Game Feature plugins or the Experience Definition itself.

Equipment

ULyraEquipmentDefinitions can also grant AbilitySets to the Actor they're added to. This is mediated by the ULyraPlayerState when the Experience is loaded.

These abilities are granted to the Player State, not the Pawn it possesses. They may be granted before a Pawn is possessed and persist even if the possessed Pawn changes. They won't be Activated until the Pawn itself is possessed, even if their Activation Policy is set to On Spawn. Plan accordingly.



ULyraGameplayAbility

The Lyra Gameplay Ability (ULyraGameplayAbility) is extended from the UGameplayAbility class to provide extra utility and interface with the Lyra framework.

Activation Group

The Activation Group determines if an ability can be freely activated, or if the ability blocks or interrupts other exclusive abilities. You can achieve additional complex blocking behaviors using the following Tag Relationship assets:

Activation Group

Description

Independent

The ability doesn't block or replace other abilities. Most abilities should be set to this tag by default.

Exclusive Replaceable

The ability doesn't block other exclusive abilities but will be canceled if another Exclusive ability is activated.

Exclusive Blocking

While the ability is running, no other exclusive abilities may be activated.

Most game actions, such as shooting, switching weapons, and melee attacks are set to Independent and Blocking. Concurrency and Cancellation are mediated by Tag Relationships. Leaderboards and other in-game menus are set to Exclusive Blocking to ensure that only one menu is visible at a time.

Activation Policy

Allows ability activation to be automatically handled by the Lyra framework.

Activation Policy

Description

None

Activation is done manually by game code or Blueprint.

On Spawn

The ability is activated as soon as a valid Avatar is assigned to the PlayerState. The Weapon Reload Gameplay Ability (GA_Weapon_AutoReload) is set to On Spawn. It activates immediately and runs passively, checking at periodic intervals if the current magazine is empty. The ability does not end until the Pawn is unpossessed.

On Input Triggered

The ability is activated once as soon as the associated Input Tag is triggered. Aim Down Sights (ADS), Grenade, and other similar abilities are set to On Input Triggered. They are activated once and do not reactivate automatically if the button is held.

While Input Active

The ability is activated continuously for as long as the associated Input Tag is triggered. Weapon Fire abilities like GA_Weapon_Fire_Shotgun are set to While Input Active. They play a firing Animation Montage, then wait until the refire time has elapsed, and then will end the ability. This is because the Retrigger Instanced Ability is set to false, redundant activation messages are ignored until the ability is finished.

We recommend caution using this activation if the Retrigger Instanced Ability is set, otherwise you could spam activation and get undesired effects.



K2_CanActivateAbility

Some Lyra Abilities use the K2_CanActivateAbility function to implement activation checks in Blueprints instead of C++. The function returns true or false to allow activation and provides you with context gameplay tags to determine what may have prevented an activation. This is exposed to all Gameplay Abilities, not just Lyra's.

Additional Costs

Normal Gameplay Abilities only allow for a single Cost and Cooldown Gameplay Effect. The Additional Costs list provides you additional costs you can specify without setting them to Gameplay Effects, which enables more complex activation conditions.

Additional costs are integrated into the standard cost flow and can be checked and committed manually with the corresponding Check Cost and Commit Cost nodes, or Commit Ability (if you also want to commit the cooldown).

Actual costs are implemented as ULyraAbilityCost objects. You can create custom costs by extending this class in C++ and overriding the CheckCost and ApplyCost virtual functions.

Lyra implements several additional costs using ULyraAbilityCost_PlayerTagStack, which consumes a number of stacks from the specified Gameplay Tag on the Player State. These assume they are being called from an Ability deriving from ULyraGameplayAbility_FromEquipment.

Lyra Ability Cost

Description

ULyraAbilityCost_InventoryItem

Consumes a given quantity of the associated item in the character's inventory. This is used for consumable inventory items.

ULyraAbilityCost_ItemTagStack

Consumes a number of stacks from the specified item in the character's inventory. If the cost cannot be paid, this reports a Gameplay Tag back to other abilities to handle the cost. This is used in Lyra for Ammo consumption and reload tracking. GA_Weapon_Fire_Shotgun and similar abilities use an Item Tag Stack additional cost set to Lyra.ShooterGame.Weapon.MagazineAmmo. Every time the weapon fires, the MagazineAmmo stack is decreased by the consumed amount. This prevents them from activating if the player runs out of ammo in the current weapon's magazine.

Added and Removed Events

Lyra Abilities provide additional Blueprint Events that enable the ability to handle being added to or removed from a character without the need to rely on activation. These are useful for initial setup and cleanup.

Blueprint Event

Description

On Ability Added

The Event is called as soon as the ability is granted. The Avatar or Input Component may not yet be valid, so be careful what you access.

On Pawn Avatar Set

Called when the pawn is fully initialized, and both its Avatar and Input Component are valid.

On Ability Removed

This Event is called when the ability is about to be removed from the ASC, usually due to the Pawn being Unpossessed or Destroyed

Camera Modes

Lyra Abilities can override the Camera Mode through the Set Camera Mode and Clear Camera Mode Blueprint nodes. One example is the use of a death camera mode while a pawn is dying, triggered by the GA_Hero_Death ability.

Type Tags

Lyra's abilities commonly include a type Gameplay Tag in their ‘Ability Tags' property to classify them hierarchically. This type tag is widely used to manage blocking, canceling, and required tag settings on other abilities, or through the Tag Relationship system.

As examples, the character-centric action abilities include type tags such as ‘Ability.Type.Action.Dash' and ‘Ability.Type.Action.Jump'. But there are also passive abilities that outlive the characters with tags such as ‘Ability.Type.Passive.AutoRespawn'. Character death will cancel all other character action abilities, without affecting some others.

Native Ability Subclasses

Some Lyra Abilities have C++ implementations, to either enforce specific activation conditions, perform complex math logic(that would be cumbersome to implement in a Blueprint), or interact with sensitive low-level gameplay systems. See the table below for some example Abilities.

Gameplay Ability

Description

ULyraGameplayAbility_Death

Automatically configured to trigger off of a Death Gameplay Event. Cancels all other abilities, and signals the Pawn's Health Component to begin the Death process (which in turn triggers the rest of the game notifications and state changes). The visual effects are performed by a BP ability extension of this class (GA_Hero_Death).

ULyraGameplayAbility_Jump

Provides functionality to trigger Jump and StopJumping inputs on the pawn's Character Movement Component while checking that the ability owner is a valid, locally controlled Pawn.

ULyraGameplayAbility_Reset

When activated, this ability instantly resets the owning player with a new pawn in its initial spawned state and cancels all other abilities.

ULyraGameplayAbility_FromEquipment

Provides functionality to interact with Lyra's Equipment system and retrieve the item associated with the ability.

ULyraGameplayAbility_RangedWeapon

Native implementation of weapon firing. Interacts with the associated weapon to determine ammo count, hit accuracy, and others. Provides ray casting functionality to calculate bullet trajectories within a firing cone, find and validate hit targets.

Blueprint Ability Subclasses

These are some examples of how the Blueprint subclasses make use of the extended ability functionality in Lyra.

Blueprint Subclass

Gameplay AbilityDescription

GA_AbilityWithWidget

The base class for any ability that provides additional UI features. This manages the widget state for the ability, so it can display status, cooldown, and other ability information. One example is Lyra's Melee ability, with a custom touch input widget for mobile platforms. The OnAbilityAdded event registers the widget extensions with the UI Extension Subsystem, this saves the extension handles. The OnAbilityRemoved event unregisters and clears the extension handles.

GA_Melee

Contains an Asset Tag of Ability.Type.Action.Melee that grants the Event.Movement.Melee tag while active. This ability is Triggered by the tag InputTag.Weapon.Ads, when this tag becomes activated the On Activation event will Commit ability costs in the following order:

Find the currently equipped weapon, and play its associated animation montage.

Check for authority (server only), then perform a capsule trace in front of the player.

If the trace hits a Pawn, additional checks are run, like a team comparison to avoid friendly fire and a secondary check to make sure the target is not occluded by level geometry.

If a valid hit is registered, the character is moved towards the target through a RootMotion force.

Next, a melee damage gameplay effect is applied on the target, and a melee hit gameplay cue is triggered on the owner.

Finally, a Melee Impact sound is played on all clients through a multicast RPC.



GA_Weapon_Fire

Fire and Reload abilities are granted through an Ability Set inside the Lyra Equipment Definition (ULyraEquipmentDefinition) class when the associated weapon is picked up. The activation requirements are handled by the ULyraGameplayAbility_RangedWeapon class, and the targeting logic is done in C++ by the same class. The Weapon Fire Gameplay Ability is activated by the tag InputTag.Weapon.FireAuto (input binding) and the Input.Weapon.Fire tag (gameplay event). It is Inhibited by the Ability.Weapon.NoFiring tag that is set from the reload ability, if the magazine is empty. The Asset Tag of Ability.Type.Action.WeaponFire grants the Event.Movement.WeaponFire tag. While the tag is active the On Ability Added event will set up a listener for the Ability.PlayMontageOnActivateFail.Message tag. This event is triggered when the player attempts to fire the weapon while no ammo is left. When the message is received, it plays a failed to fire montage (dry fire). This montage is only played if the player is still alive, and the animation will only be retriggered if a set amount of time has elapsed to prevent animation spamming. When On Activation is called, If the character is locally controlled, it will perform native targeting traces and builds the targeting data in the following order:

Ability costs (ammo consumption) are committed natively.

The targeting data is network predicted and sent to the server, where it's validated and confirmed by the ULyraWeaponStateComponent.

If the targeting data is confirmed by the server, then the BP event OnRangedWeaponTargetDataReady is called, passing all found targets. This allows the ability to apply damage, play hit effects.

Plays the firing Animation montage.

Sets a timer to Fire Delay, which is the effective delay between shots.

When Fire Delay or the timer finishes, ends the ability. Additional firing attempts are handled by the activation logic.



GA_Weapon_ReloadMagazine

This Gameplay Ability is activated by the InputTag.Weapon.Reload, which is an Asset of the Ability.Type.Action.Reload tag. This grants the Event.Movement.Reload tag. While active, it will limit movement options. The reload logic revolves around three gameplay tag stacks on the associated weapon. The Lyra.ShooterGame.Weapon.MagazineSize is the maximum amount of ammo allowed per magazine for the current weapon. Lyra.ShooterGame.Weapon.MagazineAmmo is the remaining amount of ammo in the current magazine. When the amount reaches zero, the weapon must be reloaded to continue firing. Lyra.ShooterGame.Weapon.SpareAmmo is the remaining amount of ammo not in the current magazine. It overrides the K2_CanActivateAbility function, which is a Blueprint implementation of the following activation check logic:

Checks if MagazineAmmo is less than MagazineSize. If false, the magazine is full, and reloading should not continue.

Checks if SpareAmmo is greater than zero. If false, the player is out of ammo for this weapon.

Check for the MagazineAmmo stack count of the associated item. If there's no ammo remaining in the current magazine, it applies a tag to inhibit activation of weapon firing abilities.

Plays the weapon reload animation montage, then listens for the GameplayEvent.ReloadDone event. This event is sent through an Animation Notify on the mannequin's montage.

When the event is received, checks for authority (server), then performs the reload logic, which is simply changing values for the Lyra.ShooterGame.Weapon.MagazineAmmo and Lyra.ShooterGame.Weapon.SpareAmmo in the associated weapon on the character's inventory. Then ends the ability.

If for any reason the event was not processed, the ability ends locally once the montage is stopped or interrupted. On End Ability is called to remove the shooting inhibition tag set on activation if it was set earlier.



GA_Grenade

This ability is activated by the InputTag.Weapon.Grenade Asset tag of the Ability.Type.Action.Grenade. This uses GE_Grenade_Cooldown as a cooldown effect. On Pawn Avatar Set registers the widget with the UI Extension Subsystem on the local client, ensuring that only one widget is added per ability instance. On Activation checks for ability costs and cooldowns and commits them. It ends the ability if either check fails. It will then execute in the following process:

Commits the ability cost and cooldown.

Calculates the grenade spawn location and rotation.

Checks for authority. If the authority is on the server, then it spawns the grenade Actor at the calculated values and sets the owning Lyra Character as the instigator.

The spawned B_Grenade Actor is responsible for doing the detonation checks and applying relevant Gameplay Effects.

B_Grenade detonates automatically on collision with an enemy pawn. It applies friendly fire to the instigating character (the one who threw the grenade), but not to their teammates.

Plays the grenade throw montage, then broadcasts the remaining cooldown time through the Gameplay Message Subsystem, so the associated widget can sync up its cooldown display.

Ends the ability immediately, without waiting for the montage to complete.



GA_ADS (Aim Down Sights)

Inherits from GA_AbilityWithWidget to handle the HUD display buttons. This ability is Activated by the InputTag.Weapon.ADS tag, an Asset Tag of Ability.Type.Action.ADS that grants the Event.Movement.ADS tag. While active it is Local predicted, meaning it runs on the client immediately, then the server syncs to catch up. On Activation:

Applies a custom camera mode to narrow the Field of View(FOV).

Caches and overrides the character's walk speed. Because the ability is locally predicted, this will run on the owning client and server, then replicate to non-local clients.

Applies a temporary input mapping context, overriding the movement inputs to one with a lower multiplier. By decreasing the input magnitude, any further movement inputs produce a lower acceleration and are replicated to the server with the lower acceleration value, forcing the character to walk while aiming.

For the local player, updates the UI and plays the ‘aim started' sound.

Waits until the input button is released, and ends the ability once it does.

Clears the custom camera mode.

If locally controlled, the UI updates and plays the ‘aim ended' sound.

Restores the controlled character's walk speed and removes the input mapping context to restore normal movement speed.



GA_Hero_Dash

Inherits from the GA_AbilityWithWidget. This ability is activated by the InputTag.Ability.Dash, an Asset tag of the Ability.Type.Action.Dash. This grants the Event.Movement.Dash. while active it uses a cooldown effect: GE_HeroDash_Cooldown: On Activation the cooldown:

Checks the ability costs. If the costs can be paid, commits them, otherwise ends the ability.

Checks for local control, and ends the ability on the server.

In the local client, the dash direction is chosen based on input and look direction. If there's no movement input, then the ability ends on the client (dash will only happen if there's a dash direction input).

Selects an animation montage to play based on the movement direction and the character's orientation.

The character stops crouching if it's crouched.

If the ability doesn't have authority (local client), replicates the dash direction and chosen montage through a server RPC.

On both the owning client and the server, plays the chosen montage, then applies a root motion force in the dash direction.

Sends a message through the messaging subsystem, so the client-side UI can synchronize its cooldown time.

On the server, triggers the dash effect gameplay cue, so it is replicated to all clients

When the root motion force is completed, delays for a few additional moments then ends the ability. This keeps the granted ability tags for a few extra moments and inhibits other actions such as shooting or jumping.



GE_InstantHeal

Granted by the B_AbilitySpawner, which has a ALyraWeaponSpawner class that overrides the GiveWeapon function to apply a gameplay effect to the receiving Pawn and applies an instant heal gameplay effect.

FLyraGameplayEffectContext

The Lyra Gameplay Effect Context extends from the default Gameplay Effect Context (FGameplayEffectContext) struct provided by the GAS to define additional data members and functions to be sent to Gameplay Cue Notifies. Because FGameplayEffectContext is a struct type, it needs a replacement type that can be correctly recognized by Unreal and the Gameplay Ability System. The Lyra Gameplay Effect Context overrides multiple functions:

Function

Description

Duplicate()

Performs a deep copy of HitResults and the other members that can't be memory-copied.

GetScriptStruct()

Returns a FLyraGameplayEffectContext::StaticStruct() to provide the correct reflection data to Blueprint.

NetSerialize()

Adds replication for any extra members defined.

A struct template (TStructOpsTypeTraits<>) is defined for the Lyra Gameplay Effect Context. This helper struct will bind both the duplication and serialization functionality and make them available to the replication system.

The Lyra Ability System Globals (ULyraAbilitySystemGlobals) class extends the Ability System Globals (UAbilitySystemGlobals) class and overrides the AllocGameplayEffectContext() function to construct and return a Lyra Gameplay Effect Context struct.

This ensures the Gameplay Ability System allocates the extended structure whenever a new Gameplay Effect Context object is created.

Currently, the Gameplay Effect Context struct provides the unique Cartridge ID associated with Shooter Core's ranged weapon hits and provides extra utility to access the Physical Material and Ability Source Object.

Because it is a type of struct, the Lyra Gameplay Effect Context struct can't directly include a Blueprint-exposed function to access its data.

A method to work around this limitation is to implement accessors as static functions in a Blueprint Function Library, pass the Context Handle as an input parameter, then cast it to the derived struct type internally.

The helper function FLyraGameplayEffectContext::ExtractEffectContext takes care of casting context pointers to the specialized types. Currently, this is used in the FLyraGameplayAbilityTargetData_SingleTargetHit structure.

Similar methods can be used to cast the Effect Context Handle passed to the Gameplay Cue through FGameplayCueParameters, allowing access to the extra functionality.

ULyraAttributeSet

The Lyra Attribute Set (ULyraAttributeSet) is extended from the default Attribute Set class. This Lyra-specific base class provides a convenient ATTRIBUTE_ACCESSORS macro to automate the Gameplay Attribute property and value for Get, Set, and Initialize functionality.

FLyraAttributeEvent is used to streamline attribute changed events at the Attribute Set level.

Function

Description

GetWorld()

Convenience getter that gets a reference to the world.

GetLyraAbilitySystemComponent()

Convenience getter that gets a reference to the lyra ability system component.

Lyra provides two specialized Attribute Set classes:

ULyraHealthSet

The Lyra Health Set (ULyraHealthSet) Include the following attributes that manage the character's current and maximum health:

Attribute

Description

Health

The current health value, capped at MaxHealth.

MaxHealth

Determines the maximum allowed health value.

Healing

Accumulates the amount of healing applied to the character. Affects the Health value, then gets automatically reset to zero.

Damage

Accumulates the amount of damage applied to the character. Affects the Health value.

This attribute set is also responsible for clamping the current Health value to MaxHealth, and for keeping track of when Health has run out. It implements a FLyraAttributeEvent delegate, which is fired when health runs out.

Other classes bind to this delegate to receive out of health notifications, like the ULyraHealthComponent, which is responsible for handling death and exposing the Health value to the game.

ULyraCombatSet

The Lyra Combat Set (ULyraCombatSet) provides support for damage and healing. Gameplay Effects deal with modifying either one of these attributes or relying on Lyra's custom executions to adjust the Health total.

Attribute

Description

BaseDamage:

The base amount of damage to be dealt in a damage execution. It is fed as an input to the damage execution calculation to determine actual damage dealt.

BaseHeal:

The amount of health to restore when the execution runs.

How Healing and Damage Work

By default, the Health attribute is hidden from modifiers, so it cannot be changed directly by Gameplay Effects like regular attributes. Instead, its value is set indirectly through the Healing attribute, and through the Custom Executions ULyraHealExecution and ULyraDamageExecution.

Treating damage and healing as attributes has the benefit of decoupling individual damage instances from the modified attribute, and makes working with damage values easier. It helps prevent accidental modification of important attributes. Because the Health value is hidden from Gameplay Effect modifiers, there's no risk of applying timed or infinite effects on top of its base value, which could cause issues in the long run.

ULyraHealExecution snapshots the BaseHeal attribute on the source, then it clamps to zero to prevent negative healing. Finally, it modifies the Health attribute on the Target. Because this is done in source, the Health value can be modified without issue.

ULyraDamageExecution tallies the BaseDamage and Health attribute values. BaseDamage is captured on the Source and snapshotted, while Health is captured on the Target. Then it checks for the impact location (so it knows where to spawn the damage numbers effect).

It checks with the target's Team for friendly fire and applies attenuations based on distance and Physical Material. Finally, it modifies the Health attribute on the Target. Because this is done in source code, the Health value can be modified without issue.

The damage numbers Gameplay Cue is set to receive the change in the Health attribute as its magnitude and derives the display from its raw (not normalized) value.

Additional Information

How do Damage Numbers Work?

When a damaging Ability is activated, it runs a test to determine what it has hit, then the Ability applies a damage Gameplay Effect to the target Actor.

The GameplayEffectParent_Damage_Basic(or any children that inherit from it), are applied by weapon casts and grenades. Damage is then applied through Execution which converts BaseDamage to Health and filters friendly fire, then the Gameplay Cue GameplayCue.Character.DamageTaken is applied on magnitude to the LyraHealthSet.Health cue.

GCN_Character_DamageTaken is invoked on clients. It is only displayed if the effect instigator is a local player. Damage is determined by the Gameplay Cue's raw magnitude. Location is determined by the hit result's location values, which are passed to the local Controller's ULyraNumberPopComponent. This component handles the display and the pooling, and spawns and configures a Niagara Emitter at the hit location to display the actual damage.

How are Lyra Characters initialized?

Because of the interaction between the Pawn's possession flow, Game Feature registration, and the various replicated game framework values, a playable character's initialization flow is not always predictable: events can happen out of order, while the client is still waiting for server data.

Lyra solves this by implementing a UPawnExtensionComponent. Its main job is to ensure all relevant initialization conditions for the pawn are met before granting the pawn's AbilitySets and activating any On Spawn Lyra Abilities.

The Pawn Extension Component also keeps track of any abilities granted due to the Pawn and removes them from the possessor's Player State when the character is destroyed or unpossessed.

You can assign Ability Sets to a Pawn through the ULyraPawnData asset. These can be created from the Content Browser, and the default Pawn Data is determined by the Experience Definition.

To initialize the Pawn and assign its abilities, the following conditions must be met:

The default Pawn Data is valid.

The Pawn is possessed by a valid local Controller or has server authority.

The associated Player State and Input Component have been replicated to the Pawn, and are valid.

Blueprint Asset Naming Conventions

Abbreviation

Meaning

GA_

Gameplay Abilities

GE_

Gameplay Effects

GCN_

Gameplay Cue Notifies (UGameplayCueNotify)

GCNL_

Latent Gameplay Cue Notifies (Inherits from AGameplayCueNotify_Actor and subclasses.)

Phase_

Game Phase Abilities

AbilitySet_

Ability Set

IA_

Input Action

InputData_

Lyra Input Config

W_

Widget UI

B_

All other blueprints such as pawn types, item spawners, etc.

Blueprint ThreadSafe Update Animation

Anim Node functions

State Aliases

Upper/Lower Body Layering

Lyra's character animations were created almost entirely in Blueprints using Unreal Engine 5's improvements to the Animation Blueprint system. The system setup is inspired by both Paragon and Fortnite, which achieve similar results through the use of custom C++ functionality.

Asset Overview

The AnimBP_Mannequin_Base Animation Blueprint contains the AnimGraph window, which you can use to observe the architecture of Animation Nodes that contribute to the final output pose of the Character Mannequin. You can navigate to this Animation Blueprint by clicking on the Content Drawer > Characters > Heroes > Animations > AnimBP_Mannequin_Base.





The Mannequin Base Animation Blueprint's AnimGraph and Blueprint Thread Safe Update Animation function.



The AnimBP_Mannequin_Base is set up to support common techniques that are used across the Lyra game's Sample Weapons and Gameplay Abilities.

Blueprint ThreadSafe Update Animation

When developing animations for your character classes, there are some practices to be aware of to ensure your animations are running at optimal performance. In Lyra, we use Multi Threaded Animation to calculate animation values instead of the Event Graph .

The Animation Fast Path helps you keep processes that calculate values outside of the Game Thread. You can enable this from the editor by navigating to Edit > Project Settings > Engine > General Settings > Anim Blueprints, then enabling Allow Multi Threaded Animation Update.



You can view the function responsible for gathering the animation data and processing these calculations by opening the Class Defaults of the AnimBP_Mannequin_Base, then navigating to the My Blueprint > Functions category and clicking the BlueprintThreadSafeUpdateAnimation function.



When using Thread Safe functions you can not access data directly from game objects as you could in the Event Graph. For example, if you were attempting to copy the Gameplay float value for the Character's speed it would not be considered thread-safe, therefore we recommend the use of Property Access to accommodate these instances.



Anim Node functions

In Lyra, the state-specific logic is created by using Anim Node Functions. This has the benefit of keeping the Animation logic organized. If you need to calculate a value while the character is in the Idle Animation, then you can put that logic into the Idle state. To see an example follow the steps below:

Navigate to the AnimBP_Mannequin_Base > Anim Graph and double-click the LocomotionSM State Machine to open a window that displays the Locomotion states.



The Locomotion State Machine includes State Aliases to transition between different Animation states.

You can double-click the Idle state and select the Output Animation Pose node, then under Functions in the Details panel, you can see the Anim Node Functions that provide a setup for the initial values of our nodes.





In our example image, we opened the Idle state machine to view the Anim Node functions used in its Output Animation Pose.



Function

Description

On Initial Update

Called before the node is updated for the first time.

On Become Relevant

Called when the node becomes relevant.

On Update

Called when the node is updated.

Navigate to My Blueprint > Functions > State Node Functions and double-click the UpdateIdleState function to view the logic used to calculate the final output pose of the Idle State locomotion node.



In previous Engine versions, Legacy state machine events are fired after the animation update.

State Aliases

As your projects begin to grow in size, you may have multiple animation states that your characters need to transition to. This can result in a State Machine with multiple transitional lines that can make it difficult to view in the Graph. State Aliases are used to simplify the transition logic while providing control over each individual transition between states. In Lyra, you can view an example of a State Alias being used by navigating to the AnimBP_Mannequin_Base > Anim Graph > LocomotionSM graph, then select the JumpSources state node.





The Locomotion State Machine graph with the Jump Sources node highlighted to observe the State Aliases available.



In the Details panel, you can view the Locomotion States which can directly transition to the Jump state.



When a Lyra Character is Idle, and the Player uses the Jump action, then the Lyra Character will enter into a jumping state. Eventually, they will transition into a falling state and then will either enter back into a cycle or idle state.

Upper/Lower Body Layering

BlendNodes are used to blend animations together. Most of the locomotion animations used in Lyra are full body, meaning that the animation is playing on the entire skeleton (like the jog_fwd animation), then they are combined with a variety of upper body actions that the player can use at any time (such as weapon fire or reload animations).

This is achieved through using the Layered blend per bone node, which you can view by opening the AnimBP_Mannequin_Base > AnimGraph, then navigating to the comment Upperbody/lowerbody split.



When you select the Layered blend per bone node, you can view the Details panel which includes Blend Masks that provide explicit control over the weight of individual bones involved with a blend.



Linked Layer Animation Blueprint

The Animation Blueprint Linking system enables dynamic switching between different sub-sections on the Animation Graph. The main Animation Blueprint has multiple places where you can override the pose through Linked Layer Animation Blueprints. In Lyra, this means that depending on which weapon the player is holding, you can have different locomotion behavior, animation assets, or pose corrections. You can keep their functionality separate and allow multiple users to work on the animation simultaneously, or reduce dependencies between assets while still sharing the same core functionality.

Anim Layer Interface

ALI_ItemAnimLayers is an Anim Layer Interface that specifies where you can override an animation in the Animation Blueprint. In Lyra, this is done for locomotion states in addition to layers for aiming and skeletal controls.



The FullBody_Aiming animation layer, which is a part of the Item Anim Layers interface.

ABP_ItemAnimLayersBase is the base Linked Layer Animation Blueprint that all of the weapons use. You can access this Blueprint from Content > Characters > Heroes > Mannequin > Animations > LinkedLayers.

Accessing Data From the Main AnimBP

Inside of the ABP_ItemAnimLayersBase Animation Blueprint there is a custom function Get Main Anim BPThreadSafe, that is used to get a reference to the main Animation Blueprint (AnimBP_Mannequin_Base).





The Get Main Anim BPThreadSafe function as it appears in the Item Anim Layers Base Animation Blueprint



This provides the use of Property Access to access all of its data and avoids having to re-calculate any values the linked layer may use like Acceleration or Velocity.



Using Anim Node Functions for animation selection

In Lyra, Linked Anim Layers use Property Access along with Anim Node Functions to run logic when an animation updates (On Update) or becomes relevant (On Become Relevant).



In the example below, we are choosing a directional start animation every time the animation becomes relevant.



Linked Layer Child Animation Blueprint

In Lyra, every weapon has a Child Animation Blueprint that inherits from the ABP_ItemAnimLayersBase. Animators can slot in animations and edit any variables per-weapon as seen in the image of the ABP_PistolAnimLayers Animation Blueprint shown below.



Distance Matching and Stride Warping

Distance Matching adjusts the playrate of an animation in instances where it is difficult to match the motion between Animation assets and Gameplay, for example locomotion animation assets like starts, stops, and landing animations.



Stride Warping is used to dynamically adjust the length of the character's stride in instances where the playrate adjustment will not, such as when the character enters into the Jog state.





By combining both of these techniques, you can dynamically choose to favor one technique over the other. During start states, we begin with using Distance Matching to preserve the pose, then blend in by using Stride Warping as we approach the Jog state.



Orientation warping

Orientation Warping can be used with the root motion angle of a Character's movement and bend the lower body of a Character to match the angle. In Lyra, Strafe animations are created for four cardinal directions, because the player can move with 360 degrees of freedom, we use Orientation Warping to procedurally adjust their pose. This technique is used during starts because we have limited animation coverage.



Turn in place

Turn in place animation selection is done from inside Lyra's base Linked Animation Blueprint's Idle state machine. Different animations that are based on the turn angle, and how long the player waits before triggering them can be customized in the per-weapon Anim Set section of the Child Anim Blueprints by navigating to the Class Defaults > Anim Set - Turn In Place > Turn In Place Transitions.



In Lyra, the Character Actor is oriented to the Controller's yaw. To minimize foot sliding, a counter to the rotation is used by a Rotate Root Bone node and is offset by the Root Yaw Offset.



This additional offset is used when passing the yaw values to the Aim Offset in the FullBody Aiming layer. Depending on what action the player is doing, we want to allow the Root Yaw Offset to change its mode to one of the following states from the table below.

Offset Mode

Description

Accumulate

During idles, Accumulate will completely counter the Actor's rotation.

Hold

During starts, Hold will preserve whichever original offset this animation started with

Blend Out

When going into a jog cycle, Blend Out will smoothly blend it, and follow the default "orient to controller" behavior.

This is done with a Request Root Yaw Offset Mode function that each of the states can call when needed.



When a character is idle and the offset mode is set to Accumulate, then we want to apply the animation's root rotation to the Root Yaw Offset. This information is baked into curves using the Turn Yaw Anim Modifier, and it requires the source animation to have Root Motion enabled.



Additional Notes

Gameplay Tag Bindings

Lyra uses the Gameplay Ability System for most of the player's actions. You can respond to these events in the Animation Blueprint by using Gameplay Tag Bindings. You can navigate to the Gameplay Tags inside the AnimBP_Mannequin_Base Blueprint from the Class Defaults > Details > Gameplay Tags > Gameplay Tag Property Map.



Montages

Montages have been updated to support Blend profiles and Montages.

Enabling Both simultaneously is currently not supported in 5.0





Notifies

Additional Animation Notify information has been exposed to State Machine transitions. In Lyra, we use this to control precise timing on when we can transition out of specific states.



Debugging

By using the Pose Watch Manager, you can add pose watches to specific points on the graph to inspect the runtime poses and quickly navigate to them. You can navigate to Window > Pose Watch Manager to open the Pose Watch Manager.



For debugging, you can use the Rewind Debugger , in addition to the tips and tricks located on the Animation Productivity Tips And Tricks page.

Lyra Game Settings

Making a Setting

Custom Settings

Edit Conditions

User Interface

Data Sources

Lyra Game Settings

Lyra features a GameSettings plugin that is used to simplify the process of creating a User Interface (UI) and its underlying data. The plugin is responsible for managing the data that you may want to store in a configuration file or server.

As an example: Your player is a Photographer exploring a Forest, and you have been tasked with documenting rare wildlife. When your character enters a certain portion of the level, the Game Settings plugin can manage data located on a server to communicate with the level to determine which rare wildlife should appear in the area your character is currently in.

There are several key parts of the framework,

UGameSettingRegistry - The Game Setting Registry is a set of settings. A single registry can be exposed partially or in its entirety to the user, however, you will be required to register at least one of your Game's Settings. If there are other systems in your game that require settings that do not have primary game settings, then we recommend you use another registry.

UGameSetting - Defines the base class of all settings. Any setting in the list of the UI is considered a Game Setting. This class handles core concepts like name, description, dependencies, and edit conditions.

UGameSettingValue - Implements the base class of any setting that has a value that needs to be get and set. A few settings will directly inherit from this class, instead, they'll use:

UGameSettingCollection - Defines organization settings. A Game Setting Collection is used to group settings together. For example, if you wanted a collection to generate headers in a list, then that collection represents that headered group.

FGameSettingEditCondition - Each setting has a set of attached edit conditions. These edit conditions provide you with the ability to encode logic that queries if a setting is disabled, hidden, or destroyed.

Making a Setting

Most of the setting's methods you write in code will look like the following,

All settings must have a DevName that is unique across the registry and require a DisplayName.

DescriptionRichText is required for most settings and is checked to ensure every setting where it is required. Rich text is the standard for UMG Rich text widget formatting because the plain text is parsed out when indexing the search. The DynamicGetter and DynamicSetter provide access to settings at runtime. To continually access data using:

would be redundant to declare for each setting, instead, the dynamic getters and setters take an FGameSettingDataSourceDynamic which is built using the provided macros.

The DynamicSetter and DynamicGetter require that you can access the data from the LocalPlayer using Metadata Property Specifiers (UFUNCTION/UPROPERTY). Using specifiers ensures these conditions on initialization.

Custom Settings

Using the built-in classes for your settings accommodates most needs. However, there may be instances where you require more complex logic for your settings. For example, you may need to retrieve all the available languages packaged with your game.

UGameSettingValueDiscrete_Language directly mutates the language and culture settings we have stored.

Edit Conditions

All edit conditions subclasses from FGameSettingEditCondition handle one responsibility to disable, hide, prevent resetting, or remove a setting from analytics if any of the following conditions should apply:

FWhenCondition - Provides the ability to write your condition as inline lambda.

FWhenPlatformHasTrait - Used for hiding or disabling settings based on platform traits. Example traits such as:

Does the platform support keyboard and mouse?

Does the platform support changes in screen resolution?

You will notice after looking at several source code examples, we do not use checks such as #if PLATFORM_FEATURE when eliminating settings or other general areas of Lyra, instead we rely on platform traits, because we can use the option to test other platforms when testing in PIE, and everything can be dynamically re-evaluated. We therefore encourage you to use FWhenPlatformHasTrait, when possible.

FWhenPlayingAsPrimaryPlayer - When you do not want other local players to have access to certain settings, you can use these instances to edit certain conditions that will make it exclusively available to the first player.

For example, the Resolution setting located in the class LyraGameSettingRegistry_Video.cpp:

Edit conditions track whether settings are toggled to enabled, disabled, or hidden. They are designed to ensure that if the user is attempting to change your project settings during runtime, then you can provide an explanation that can be traced back to the debugger. In the image below, the edit condition for Window Mode has been toggled to Disabled. As a result, the engine reports a message back to the user, so they understand why a setting can't be changed.



User Interface

The User interface consists of the classes UGameSettingVisualData, and UGameSettingPanel. The Game Setting Panel is responsible for processing the display, which you can provide with a registry and a filter to have the panel show your settings. To determine how those settings are defined, the Game Setting Visual Data contains the rules your settings will use for connecting a UGameSettingListEntryBase to the UGameSetting class.





The Game Settings Registry Visual Data contains details on how the panel should display.



Data Sources

Tool Library

Baking To Static Mesh Assets

Non-Destructive Level Design

Swapping Between Tools and Assets

Source Keys and Generated Mesh Cold Storage

New Level Setup for the Tool / Asset Swapping System

Swapping System Common Issues

Additional Notes

Geometry Scripting is a new Experimental plugin introduced in Unreal Engine 5 which provides a base Actor class for Procedural Mesh Actors (GeneratedDynamicMeshActor) and a library of Blueprint functions that can be used to generate that Actor's mesh. For example, the simple Blueprint displayed below results in a Parametric Box object that can be resized using Width / Depth / Height Blueprint variables exposed in the Actor's Details panel.





The Geometry Script Library includes a large set of over 160 functions that include various types of shape generators, extrudes and revolves, mesh booleans, and utility functions for configuring material assignments and copying to and from Static Mesh Assets.

Tool Library

Lyra Tech Artists used procedural mesh generation in Blueprint Actors to build a library of parametric level design elements as Blueprint Actors. These Blueprints are called Tools (Blueprint Actor Tools) in the Lyra project, and are found in the Content directory of the Tools subfolder. To use one of the Tools, drag it into the Level, and then configure the part to your liking by using the settings in the Actor Details panel.

We settled on "Tool" to describe these parametric objects in this document. However, Generator and Generated Mesh have also been used in some places in the Blueprint user interfaces.

For example, in the image below-left is the default B_Tool_AdvancedWindow, and then two other variations built by changing the options / parameters / materials on the Actor.



Lyra was built using the Blueprint Actor Tools listed in the table below:

Blueprint Actor Tool

Description

Image

B_ASimpleCubeTool B_GeneratedTube B_GeneratedTube_Advanced B_Tool_AdvancedWindow

Useful for creating meshes that have square corners on the outside and rounded corners on openings. and where the opening can be dragged around with a 3D Gizmo. This includes a Mirror and custom boolean cutting plane options.



B_Tool_CornerExtrude B_Tool_CornerExtrude1

Creates a corner mesh with a uniform Width and uniform corner Radius.



B_Tool_Panel_BGM

Creates a mesh with Corner Radius control. This is a boolean (add / subtract / intersection) inset mesh of uniform width and with a unique material ID. Mesh dimensions are controlled with a draggable 3D gizmo, and contains a Mirror and custom boolean cutting plane options.



B_Tool_RampMakerControl_BGM

A user-defined tool that consists of a simple rectangular box with Width, Height, and Depth controls along a spline. You can edit and view the Spline points in Game View mode (G-key toggle). Using Alt+Left Mouse to drag will append a new spline point to the end spline point. This Tool bakes out a single mesh.



B_Tool_Repeater

Distributes an array of boxes with user defined dimensions along an editable spline, an example of this can be seen with B_Tool_Stairs_BGM



Baking To Static Mesh Assets

When using the Parametric Tool Actors, a Level Designer can efficiently prototype level layouts, and can use them in PIE (Play-in Editor) to do basic tests. The Dynamic Mesh Actor used as the basis for these Blueprints does not use the traditional UE StaticMesh Asset. Instead, It uses a Dynamic Mesh Component, a new type of component designed for efficient editing.

The Dynamic Mesh Component provides rapid parametric design, however it does not support UE Rendering features like Lumen or Nanite. Additionally, the Dynamic Mesh Component Actor does not support Instancing, meaning that a duplicate of a Tool is a completely separate mesh. Changing the parameters of the original Tool does not affect the duplicate.

This can be challenging when designing a level if the same element is used in multiple places, because the only option for the designer is to manually update the settings on each duplicate. Therefore, adhere to the standard UE rendering architecture and design workflows, as the Blueprint Tools Actors need to be baked to Static Mesh Assets.

To support this, the Tool Actors have a Generation Management section in their Details panel, which includes two action buttons, Generate New Static Mesh and Bake to Static Mesh.



To bake out a Static Mesh version of the Tool instance, click the Generate New Static Mesh button. This automatically creates a new StaticMesh Asset at the path defined by the other settings on the Actor.

As an example, in the image above, the Asset is created in the ShooterMaps/Content/Meshes/ Generated folder directory, and given an auto-generated name prefixed with Mesh_.

Instances of this Static Mesh Asset can now be placed in the level. When the Generate button is clicked, the Tool Actor keeps track of which Assets were created and stored in the Target Static Mesh field. The user can then click Bake to Static Mesh to update that Static Mesh Asset at any time. This makes it easier to edit the Instances in the level by editing the Tool.

When referring to the word "Instance" in this context, we are referring to an Actor in the level that references a Static Mesh Asset, for example an "Instance of the Asset", and not an Instanced Static Mesh Component instance.

In the gif below, you can observe a demonstration of this process. We begin by initially creating a new Asset from the Generate New Static Mesh button, then we place three separate instances, and update the Asset by editing and re-baking the Tool.



The Generate New Static Mesh and Bake To Static Mesh functionality is implemented in Blueprints using Geometry Scripting. The functions are located inside the Blueprint Subclass of a Generated Dynamic Mesh Actor called BakedGeneratedDynamicMeshActor.

You can navigate to this Dynamic Mesh Actor in the /Content/Tools/BakedGeneratedMeshSystem directory folder. All the Tool Blueprint Actors are subclasses of this base class.

Non-Destructive Level Design

The Bake to Static Mesh functionality described in the section above provides an efficient way to do non-destructive Level Design using the parametric mesh Tools. The Level Designer configures a level element using a Tool, then bakes it to an Asset to place instances in the level. The baked asset supports Nanite and Lumen, efficient Instanced rendering, and all other Static Mesh features in UE.

The one drawback of this system is that the Tool Actor must exist in the level, as a sort of "template" for the Static Mesh Asset / Instances. If the Tool is deleted, the settings would be lost. One option to do this is to set the Tool to be hidden, however this means you have to explicitly show it to do any editing, then hide it again afterwards. Another option is to place the Tools somewhere in the level that is "out of the way". In Lyra, this is done by placing the Tools below the actual level.

This is why when you open the L_Expanse map, for example, you may discover that there are many apparently-random objects placed below the main level. These are the Tools that were used to generate and edit the level Assets. Why they appear to have no coherent organization is explained in the following section.



Swapping Between Tools and Assets

The Asset Baking system described above provides for non-destructive level design parametric Tool Actors, but still comes with some challenges. Specifically, finding the Tool used to author a particular Asset placed in the level is difficult. Additionally, it is not efficient to make tweaks to a placed Asset by iteratively editing and re-baking a Tool that is in some other location.

To support better workflows, a system for swapping between the placed Static Mesh Asset (Static Mesh Actor) and the Tool Actor was built entirely in Blueprints. This system uses the Actor Action Utility Blueprints, which provide the capability for creating Blueprint operations that appear in a right-click context menu in the Editor.

For additional information, refer to Scripted Actions.

There are two Action Utilities located in the /Content/Tools/BakedGeneratedMeshSystem/EditorActions/ folder.

The first, SwapGeneratedActor_ToSM is used to replace a Tool Actor with an instance of its Baked Static Mesh Asset. This Editor action adds an item Swap to Static Mesh to the context menu for the BakedGeneratedDynamicMeshActor subclasses. When it is run, the following process occurs:

Checks if a baked Asset is already configured in the Actor. If no baked Asset already exists, then automatically run the Generate New Static Mesh and Bake to Static Mesh operations on the Tool Actor.

Create a new Baked Static Mesh Actor and assign the baked Asset.

Set the Transform on the new Actor to be the same as the current Transform on the Tool.

Copy the Name, Data Layer, and Outliner position from the Tool Actor to the new Static Mesh Actor.

Reposition the Tool Actor to be below the Level.

Append a prefix to the Tool Actor's name in the Outliner

This name is configured to be ZZSTORED_ in Lyra.



The second Editor Action, SwapGeneratedActor_FromSM, is used to swap from the placed Static Mesh instance (Baked Static Mesh Actor) to the source Tool Actor. This adds a Swap to Generated Mesh action to the context menu for Baked Static Mesh Actors. When you run this Action, the StaticMesh Actor is deleted, then the transform on the Tool Actor is updated to take the position of the deleted StaticMesh Actor.

You can make parametric edits, update the baked Asset, and then run the Swap to Static Mesh Action to switch back to a Static Mesh.





Source Keys and Generated Mesh Cold Storage

Level Designers use the Tools, Baking functionality, and Swapping actions described above to create and edit the level. Now, you can explore the technical details about how the swapping is implemented entirely in Blueprints.

As mentioned before, the Baked Generated Dynamic Mesh Actor keeps track of its current baked Asset in the Target Static Mesh field. When the Asset is generated, a new Source Generator Key string is randomly generated too. This string is displayed in the Actor Details panel.

These fields can be manually initialized in addition to using the Generate New Static Mesh button.



The Static Mesh Actors created by the Swap to Static Mesh Action are a Blueprint subclass of the base StaticMeshActor called Baked Static Mesh Actor. This subclass has an additional field for the Source Generator Key. When a new Baked Static Mesh Actor is created by the Action, its Source Generator Key is set to the same string as the Tool it is based on.



This Source Generator Key string is the basis for the Swapping system. When given a Baked Static Mesh Actor, you can use the Key to determine which Tool it is derived from. Additionally, you can find all the Baked Static Mesh Actor instances when given a Key from the Tool.

One method to search is to iterate through all Actors. We added another Blueprint object to the system to centralize this information and provide a place for various utility functions (like those searches). This is the GeneratedMeshColdStorage Blueprint, which is an Editor Utility Actor.

One of these Actors must be placed in the level for the swapping system to function. It has no geometry and no effect on the game. It manages an array of known Tool Actors, in the Stored Actors list, as shown below.



The Generated Mesh Cold Storage object has two public Blueprint functions, Store Actor and Extract Actor. These are used by the Swap to and from Actions to store or restore the Tool Actors.



New Level Setup for the Tool / Asset Swapping System

Below are step-by-step instructions for setting up a new level with the baking / swapping system described above.

Drag an instance of the Tools/BakedGeneratedMeshSystem/GeneratedMeshColdStorage Asset from the Content Browser into the level.

Drag an instance of Tools/B_Tool_AdvancedWindow Asset into the level.

Select this new Actor (B_Tool_AdvancedWindow).

Scroll down to the Generation Management section of the Actor Details panel, and click Generate New Static Mesh.

Right-click on the Actor in the level and select Swap to Static Mesh from the Scripted Actor Actions submenu in the Actor context menu. This will replace the Tool Actor with a Static Mesh Actor.

Hold the Alt key and drag on the 3D gizmo in the level to make a duplicate of the selected Static Mesh Actor.

Select one of the two Static Mesh Actors, right-click, and select Swap to Generated Mesh from the Scripted Actor Actions submenu in the Actor context menu. This will replace the StaticMesh Actor with the Tool Actor.

Scroll up to the Wall section in the Actor Details Panel and increase the Wall Width. This will only affect the Tool Actor.

Scroll down to the Generation Management section of the Actor Details panel, and click Bake to Static Mesh. The Static Mesh Actor will update to look the same as the Tool Actor.

Right-click on the Actor in the level and select Swap to Static Mesh from the Scripted Actor Actions submenu in the Actor context menu. This replaces the Tool Actor with a Static Mesh Actor again.

Swapping System Common Issues

The Asset / Tool swapping system described above is included in the Lyra L_Expanse level. Most level elements are based on Tools which exist in the level, and you can experiment with non-destructive level design by swapping between the Tool and the placed Assets.

During the course of Lyra development, we observed several frequent errors in usage which are useful for you to be aware of.

If the generated Static Mesh Assets are placed manually, instead of the swapping Actors, the resulting Actors will become Static Mesh Actors, not Baked Static Mesh Actors. In this situation, the Actor does not have the Source Key field, therefore there is no link to the source Tool, and the Swap to Static Mesh context menu Action will not be available.

The Swap to Static Mesh Action does not automatically bake the Tool to the Asset, except on the first invocation. You must explicitly click the Bake button, otherwise the Tool and baked Asset can become out-of-sync. You can fix this by swapping back and baking.

Once a Tool has been baked to an Asset, and that Asset is used in the level, do not use the Generate New Static Mesh button on that Tool again. Doing so generates a new Source Key, and any existing Asset instances then have a Source Key that doesn't refer to any existing Tool (it will not be possible to swap back).

If a Tool is duplicated in the level to make a variation, then both copies have the same Source Key and the same target Static Mesh Asset. In this case, Generate New Static Mesh must be run to resolve this collision.

The generated Static Mesh Asset does not have scope of the Source Key, only the Static Mesh Actors do. Therefore, if all Actors using an Asset in the Level are deleted, the link to the source Tool is lost (the Tool will still exist in the level, but it will be difficult to find). To fully delete an Asset, the Tool must be deleted first, and then the placed Actors, and then the Asset.

If a Tool is deleted, its settings are irrevocably lost. This does not affect any placed instances, however there is no way to recover the deleted Tool to further update the instances.

The Source Key fields are strings, and can be manually edited in the details panel. If this is done, the link between Asset instances and the Tool will be lost. However, this means that broken links can be repaired by manually updating the strings to be the same in the Tool and Instances.

We plan to improve on these limitations in future iterations of the Lyra sample.

Additional Notes

Assigned Materials: When swapping between Tools and Asset Instances, in addition to copying the world Transform, the assigned Materials are also copied. This provides for different Instances of the Asset in the level to have different Material assignments while still providing for swap to / from the Tool, and the Tool (when "swapped in") will reflect the correct Materials. However, any Material assignments made directly on the Tool will be lost.

Actor Settings: Asset / Instance Swapping also preserves Data Layers, position in the Outliner, and Actor names where possible. it does try to hide / show the Tool Actors, in addition to moving them below the level. However, Unreal Editor does not save this hide / show state, so it is reset when the level is reloaded (this is why the Actors are visible below the level).

This copying is done from the low-level engine APIs that copy Actor properties, therefore many other Actor settings will be copied back and forth. However, it is not possible to copy Actor properties that do not exist on both objects. To handle such a case, the setting must be explicitly handled in the Copy To / From Actions.

Cooking/Game Builds: In UE 5.0, the Generated Dynamic Mesh Actor base class used for the Tools is Editor-Only. This means that placed Tool Actors will be visible in PIE, but they will not be included in the built cooked game.

UGameFeatureAction_AddInputConfig

ULyraSettingsLocal

Lyra Input Modifiers

Lyra's Input Settings System was designed to resolve many common issues with input configuration setups experienced in games. It is based on the Enhanced Input system.

UGameFeatureAction_AddInputConfig



The UGameFeatureAction_AddInputConfig is a Game Feature Action that is responsible for registering the Enhanced Input PlayerMappableInputConfig data assets. The PlayerMappableInputConfigs contain input mappings to be added to the local player, such as pressing the "W" key to move the character forward.

This means each game feature plugin registers its own set of key bindings used with its experience. The input mappings are registered whenever the game feature plugin is loaded; this means the user can change their keybindings for any experience even if it is not currently active, such as on the main menu.

Input mappings will not be "activated" on the player until the associated Game Feature is activated. Mappings will only be activated if their platform conditions are met. For example, the mouse and keyboard mappings will only be activated if there is an associated SupportsMouseAndKeyboard platform trait.



These platform traits can be helpful for defining platform-specific input mappings, especially on platforms that may have varying inputs available. For example, a modern mobile platform has fewer physical buttons to use than a controller on a Console platform.

The Type field is useful if you want to extend the existing functionality to change mapping configurations when the input device changes. You can do so with the Common Input Subsystem's OnInputMethodChanged delegate.

ULyraSettingsLocal

Once a Game Feature registers an input config, they are stored in the game settings. The settings are aware of all input mappings and which ones are currently active. The ULyraInputComponent uses these registered configs to add the mappings to Enhanced Input when the player is initialized.

The settings have callbacks for when a mapping config is activated or deactivated so that anything with a local player can get access to that information, which can be useful both in gameplay situations and for updating the settings menu.

Along with holding the currently registered input mappings and custom keybinds, the settings provide a place for you to declare any modifications to their experience such as aim sensitivity, inverting the look axis, and more. These settings can then be used by Input Modifiers to implement the desired input behavior.

Lyra Input Modifiers

Input Modifiers are pre-processors that alter the raw input values before sending them to Input Triggers. This is how Lyra applies settings such as gamepad sensitivity, dead zones, and even aim assist. As an example, we can look at how we apply Gamepad Sensitivity based on the user's settings, ULyraInputModifierGamepadSensitivity.

First, we have defined a Data Asset for "Aim Sensitivity", ULyraAimSensitivityData. This maps a gamepad sensitivity enum to an associated float scalar value. Having this defined in a data asset provides us the capability to reuse it in multiple places, in addition to making the values easily accessible to designers or gameplay programmers.

The ModifyRaw_Implementation function is what performs all of the input manipulations. Because the function takes in a const UEnhancedPlayerInput* parameter, you can use it to get the owning local player. Once you have the owning player, you can get the associated settings of that player. From here, you can get the current gamepad sensitivity setting and look it up in our Aim Sensitivity Data Asset to get a float value to scale by.

Lyra Interaction System

Interaction Ability Tasks

Important Lyra Interaction Terminology

Lyra Interaction System

Lyra uses its interaction Interface/IInterface through its own Gameplay Ability/UGameplayAbility (ULyraGameplayAbility_Interact) which establishes a cause and effect relationship between how the player Interacts with objects in Lyra, and how those objects interact with the player.

Using the LyraGameplayAbility_Interact class, you can manage the logic of how your interactions are called.

ULyraGameplayAbility_Interact.h

AbilityTask_WaitForInteractableTargets_SingleLineTrace is a Gameplay Ability Task, which performs a line trace and waits in a looped timer until it hits an Actor that implements the interface.

As an example:

A player controlling a LyraPawnActor is low on health, the player directs the Pawn towards a collectible health item pickup. Upon aligning the player's crosshair with the Collectible, and pressing the "Use/Interact" key, a Line Trace is fired from the Pawn. When the trace hits the Collectible, the interaction interface implemented on the Collectible will handle the logic to restore the Player's health to its full amount.

Interaction Ability Tasks

UAbilityTask_WaitForInteractableTargets is used to make a new method of tracing for interactable targets.

As an example:

A player controlling a LyraPawnActor approaches a door that they want to open. Upon aligning the player's crosshair with the door and pressing the "Use" key, a radial menu appears with the options to "Unlock/Lock" the door, or attempt to open the door.

For additional information on Line Traces in Unreal, See Tracing

UAbilityTask_WaitForInteractableTargets.h

Your chosen AbilityTask for tracing delivers a set of Interactable targets from the FInteractionQuery struct.

struct FInteractionQuery

to the method UAbilityTask_WaitForInteractableTargets::UpdateInteractableOptions:

which will call IInteractableTarget::GatherInteractionOptions on each interactable target.

Once you update the set of interactable objects, the interaction ability (GA_Interact) calls the TriggerInteraction function when the player focuses on an object to interact with and receives input from the player that they want to interact with that particular object.

Once you invoke the current Option, there are two methods by which interactions can occur. The first method grants an ability to the player's Ability System Component through the function FInteractionOption::InteractionAbilityToGrant, using this function is recommended for simple logic such as the Weapon Pickup Actor.

Alternatively, if you're interacting with an object that contains its own Ability System Component to handle complex logic, then you can invoke the FInteractionOption::TargetAbilitySystem and the FInteractionOption::TargetInteractionHandle functions, this invokes the ability on the interactable object, instead of invoking the ability on the Lyra Character's (Avatar) Ability System Component.

The interaction function FInteractionOption::InteractionAbilityToGrant is inherited from the base class of your ULyraGameplayAbility_Interact interaction ability, which runs the task function AbilityTask_GrantNearbyInteraction, as a ranged loop and timer that collects nearby abilities and grants them to your character before you attempt to interact with them. You can increase the InteractionScanRate float to be at a larger radius than your InteractionRange, otherwise, replication will not deliver the ability to the client soon enough.

The ability is invoked through the event





GA_Collect_Interaction represents only one kind of interaction, it is an ability that provides you the capability to pick up objects on the ground and add them to your inventory. There is no limit to your imagination, you can make an ability to eat Apples on the ground that will refill your player's health, or you could make an ability to open doors, get into a vehicle, or open a chest.

This decoupling behavior provides you with all kinds of different interactions from the central passive interaction scanner.

InteractableTarget - An Actor or Component that implements the IInteractableTarget interface, this determines what objects in the world can be interacted with.

InteractionOption - The "Affordance" or "Option", for example, an apple might provide both a "Collect" and a "Consume".

InteractionInstigator - The Pawn (LyraPawnActor) that initiates the interaction. They may or may not implement the IInteractionInstigator interface, which allows further customization of options and how they are presented.

Lyra Inventory and Equipment

Inventory

Inventory Item Fragments

Item Pickups

Equipment

Relationship with UI

Quick Bar

Custom Reticles

Key Inventory Types

Key Equipment Types

Beyond Lyra

Lyra Inventory and Equipment

An Inventory is a collection of items that are in your possession, but they may also be stowed away, perhaps hidden inside a container such as a backpack.

Equipment is an item pulled out of that container or backpack that is being held, worn, or used.

For example, consider a Rifle item given to a Player Character. It initially only exists virtually in the player's inventory, including its ammunition. By pressing a weapon-swapping button, the Rifle becomes equipped. This appears as a 3D mesh in the character's hands, with the rifle's firing and reloading abilities added.

Below are some key distinctions between Inventory and Equipment:

Category

Inventory Items

Equipment Items

Visualization

Icons are used in the User Interface (UI) or for in-game pickups.

Visible Actors that are spawned while in use and often attached to the owner.

Lifetime

Instances exist as long as the owner holds onto them, then they are destroyed when dropped.

Instances are created when the item is equipped, then destroyed when unequipped.

Gameplay

The state is maintained using Gameplay Tag stacks.

No state is maintained between equip/unequip cycles.Can grant ability sets while equipped.

Ownership

Owned by the Controller from the InventoryManagerComponent.

Owned by the Pawn from the EquipmentManagerComponent.

Network Replication

Server and Autonomous Proxy only.

Server, Autonomous Proxy, and Simulated Proxies.

Data Definition

Composed from extensible inventory fragments.

Limited to data properties.

Association

The item definition usually specifies the associated equipment definition.

The equipment definition does not reference the inventory definition.

Naming Convention

Prefixed with ‘ID_' (ID_Rifle)

Prefixed with ‘WID_' (WID_Rifle)

Inventory

An Inventory item is an object that can be acquired or picked up. It affects gameplay and presentation through its array of Inventory Fragments. Fragments can alter the owner's stats through Gameplay tags, appear in the inventory UI, or let the item become equipped.

Inventory Item Fragments

Lyra has a variety of fragments you can be apply to inventory items:

Inventory Fragment

Description

InventoryFragment_PickupIcon

Determines in-world representation of an item ready to be picked up.

InventoryFragment_EquippableItem

Pairs this inventory item with an equipment definition used when the owner equips the item

InventoryFragment_SetStats

Grants a set of gameplay tag-based stacks upon pickup, such as ammunition.

InventoryFragment_QuickbarIcon

Determines HUD icons used for items that occupy a slot in the player's quick bar UI.

InventoryFragment_ReticleConfig

Specifies alternative HUD reticle classes to instantiate when this inventory item is equipped.

You can customize Lyra's Inventory Fragment Item effects by implementing new fragment types.

Item Pickups

The ALyraWeaponSpawner class contains an example of how pickups function together with inventory items. These items are used in Lyra shooter maps as B_WeaponSpawner (for weapon pickups) and B_AbilitySpawner instances (for health pickups).

Equipment

Equipment is an item that can be equipped to a player, potentially changing their gameplay visuals, UI, or granting passive or active Abilities. Typically an equipped item is instantiated based on an inventory item.

Unlike inventory items, equipment items only exist when equipped.

Relationship with UI

Quick Bar

The Quick Bar is a player HUD area where equipable inventory items are shown, such as weapons. It uses information from the item's inventory fragments for display and the inventory instance's stat tags for the ammunition status.

As you choose different quick bar slots, weapons in the player's inventory are equipped, and unequipped.

See the W_QuickBar and W_QuickBarSlot widget Blueprints for implementation details.

Custom Reticles

Different items, when equipped, may cause a player's HUD to change. For example, the Pistol's reticle is designed for focused shooting, while the Shotgun's reticle is designed for a widespread visualization of multiple hit locations.

Reticles are specified from a fragment in the item's inventory item definition. Refer to the W_ShooterHUDLayout and W_WeaponReticleHost Widget Blueprints.

Key Inventory Types

Type

Notes

InventoryManagerComponent

Manages a collection of inventory items.

Converts shared InventoryItemDefinitions into InventoryItemInstances.

Duplicate items can be represented from multiple InventoryItemInstances or from a single one with a StackCount.

Owned by a LyraPlayerController.

InventoryItemDefinition (asset)

Asset Example: ID_Pistol.

Holds the array of InventoryFragments that provides more information about different aspects of the item.

For equipable items, the InventoryItem has a fragment that specifies the EquipmentDefinition asset

InventoryFragment

An optional chunk of data describing an aspect of the item. An item will typically have more than one of these.

InventoryItemInstance

Created when an item is added to an inventory

References its original InventoryItemDefinition

Represents a single item, such as a Rifle, along with ‘stacks' of stat tags. These stacks represent features of the item, such as remaining ammo and capacity.

Does not have subclasses.

PickupDefinition (asset)

A data asset type that holds information about a pickup item's inventory item definition, its presentation, and respawning behavior.

Example: WeaponPickupData_Heal_Small.

Key Equipment Types

Type

Notes

EquipmentManagerComponent

Manages items equipped on a specific Pawn.

Only one weapon can be equipped on a character at a time.

Holds bookkeeping of equipped instances. (array of AppliedEquipmentEntry)

Owned by a Pawn.

EquipmentDefinition (asset)

Defines things to do to the pawn on which it is equipped.

List of Actors to spawn at equip time.

List of Abilities to grant.

EquipmentInstance

Created when equipped on a Pawn.

Has OnEquipped / OnUnequipped virtual and Bluerint-implementable functions.

Holds tag stacks in an FGameplayTagStackContainer.

Holds the Instigator. (The object responsible for equipping. For the quickbar, this is an InventoryItemInstance.)

Can access the owning Pawn.

Subclassing EquipmentInstances exist. (WeaponInstance, RangedWeaponInstance)

Does not have access to which EquipmentDefinition it was created from.

AppliedEquipmentEntry

Bookkeeping entry, one per equipped item.

Pairs the EquipmentInstance with its source EquipmentDefinition.

Holds items applied to the owning Pawn (granted abilities, spawned Actors.)

RangedWeaponInstance / WeaponInstance

Specializations of EquipmentInstance that do some type-specific internal bookkeeping.

Beyond Lyra

Although items in Lyra have both inventory and equipment representations, the systems can function independently.

For example, consider an item the player is given that grants a defensive bonus, such as a magical luck charm. This item may have an inventory definition that specifies a HUD icon and a new fragment type that applies a shielding Gameplay Effect to its owner. Since it's a passive effect that does not need to be equipped, there would be no need for an equipment item definition.

Setting up Scalability and Device Profiles For A Project

Scalability and Device Settings Systems

Console Variables

Device Profiles

Scalability Groups

Game User Settings

Texture Group Settings

Setting Priority

Engine Configuration: BaseScalability.ini

Device Profiles: Console Variables

Editor Command Line

Manually Searching

Overriding Settings In Config Files

Setting Up Device Profiles

Undoing an Existing Engine Setting

Scalability Groups

Device Profiles

Platform Configuration Files

Game User Settings

Setting up Scalability and Device Profiles For A Project

Unreal Engine provides a wide variety of Scalability settings that can affect your project's performance and visual quality. Usually, the engine default settings will accommodate most of your needs, however, you may want to change these settings for better performance or higher quality. Projects can launch on multiple platforms, therefore the Scalability settings may require different values for different platforms. The behavior of Platforms such as the PC is open to encompass a wide range of different types of hardware, as a result, these settings may need to be adjusted by individual users to best match their particular system.

Scalability and Device Settings Systems

To achieve your goals in Scalability, multiple engine systems can be used together to create project profile configurations that work across all platforms and users. Below, you will find an explanation of the different engine systems involved in this process.

Console Variables

Most performance and quality settings are implemented in the engine as Console Variables (CVars). These are named variables that store numbers, strings, or enumeration values. Console variables have a default set in source code, which can then be overridden by game-specific config files or the other systems described below. Most variables can be set while the game is running or from the command line, which provides a preview of quality and performance settings before committing them to a value. You can add data-driven CVars to your project by clicking on the Toolbar and navigating to Edit > Engine >Data Driven Cvar > CVars Array and clicking on the Add(+) button.



Pictured above are the Data Driven CVars Array located in the Project Settings.



Device Profiles

The engine uses Device Profiles to define a hierarchy for different types of physical devices that may run your project. You can find these settings by navigating to the Toolbar and clicking on Tools >Instrumentation > Platforms > Device Profiles.



As an example, in the default engine settings there is a base "Android" device profile that is used for every Android device.



In the Device Profiles settings you can access Existing Device Profiles(1), additionally, you can edit your own Console Variables in the CVars column(2).



Below the base profile are multiple performance buckets such as "Android_High", and specific CPU/GPU types below that profile. When the project is launched the engine uses a customizable process to determine which specific device profile to use, then applies the settings associated with that profile, starting from the top level such as "Android" and overriding it with any values set in the more specific profiles below it.

Scalability Groups

The scalability system is used to define a related set of performance settings that can be selected at runtime. For example, the engine default PostProcessQuality group defines settings for Motion Blur and Bloom and is split into 4 levels ranging from Low to Epic as well as a Cinematic level for maximum quality. When the project or user chooses a specific scalability group quality level, it will apply all of the console variables in that quality level.



Scalability groups apply their console variable settings before device profiles. Settings defined in specific device profiles will override those in scalability groups chosen by the user. This means that device profiles can specify a base scalability group console variable like sg.PostProcessQuality before overriding individual settings.

It is possible to create platform-specific scalability group settings by using the general platform config override system described below. However, it is not possible to set up different scalability groups for specific device profiles.

In general, scalability groups are useful on open platforms like PC because they allow users to take advantage of a varying range of PC hardware components.

Game User Settings

The UGameUserSettings class stores all settings that an individual user can change from an options UI menu. The user's specified settings are stored in a GameUserSettings.ini file on the specific device that runs your project. On some platforms that restrict file access, platform-specific options need to be enabled to allow the game user settings to save and load properly. The default engine class stores the user's choice of quality for each scalability group in addition to specific settings such as window resolution. Many projects may want to use a game-specific subclass, which is done by creating a native subclass and then modifying the GameUserSettings Class Name. This can be done from the DefaultEngine.ini file, by navigating to the [/Script/Engine.Engine] section, or by navigating to Edit > Project Settings > Engine > General Settings > Default Classes > Advanced > Game User Settings Class.



In your game-specific settings class, you can add new settings or change how settings are applied at runtime. Default values for a specific game can be set in the game's DefaultGameUserSettings.ini file, which will be used for any new users. The Game User Settings are exposed to Blueprint and have useful functions that can be called from either a Blueprint-based settings UI or in source code.

For example, the RunHardwareBenchmark function runs an automated benchmark that detects the relative CPU and GPU speed of the local machine and uses the Scalability.ini settings starting with PerfIndexThresholds to estimate the best scalability group settings for a particular machine. ApplyHardwareBenchmarkResults can then be called to apply and save the settings.

Texture Group Settings

When textures are created in the editor, they can be assigned to different groups such as "World" or "UI". These groups specify what Texture Settings are applied at runtime. Each group has different settings for maximum size, mip levels, and texture group settings that can be customized for specific device profiles. Packaging takes these settings into account. You can set a lower maximum resolution for mobile builds and the install package will only include the mip levels that could be streamed on that device. Texture group settings do not use console variables directly because they cannot be modified at runtime.

Setting Priority

Before settings are applied, they are loaded from config files. The core Configuration File Hierarchy is used to determine what settings will be applied. This priority matters for any settings loaded from config files that cannot be modified at runtime. For settings that use the Console Variable system and can be modified at runtime, they are applied in the following order with higher numbers overriding lower numbers. This order is defined in the EConsoleVariableFlags enum:

Priority Order

Flag

Description

1

SetByConstructor

The default value set in a console variable's constructor.

2

SetByScalability

Values set by scalability group quality levels.

3

SetByGameSetting

Low priority values set by the engine's GameUserSettings.

4

SetByProjectSetting

Sets the ProjectSettings from the DefaultEngine.ini file from sections such as [/Script/Engine.RendererSettings].

These settings are usually set by the Project Settings menu located in the editor.



5

SetBySystemSettingsIni

The [ConsoleVariables] and [SystemSettings] sections of DefaultEngine.ini.

6

SetByDeviceProfile

From device profiles, with the more specific profiles overriding generic ones.

7

SetByGameOverride

High priority values set by a game's GameUserSettings subclass, this should be used for settings that need to override device profiles.

8

SetByConsoleVariablesIni

The engine ConsoleVariables.ini file, mostly used for testing in development.

9

SetByCommandline

Used by some command line options.

10

SetByCode

Used by various debugging tools.

11

SetByConsole

The highest priority, set by typing "NameOfCVar Value" in the console of a running game



As an example the engine override process is demonstrated in this diagram that begins with the Scalability Group system. First, the engine checks the [PostProcessing@2] category (displayed as High in the UI) in the engine-provided BaseScalability.ini file which contains the Console Variables(CVar) for bloom.

Then, the engine will check to see if any of these settings have been overridden by the category [PostProcessing@2] in the game-specific DefaultScalability.ini file or platform-specific files like WindowsScalability.ini.

Next, the Engine checks CVars specified in the [SystemSettings] category beginning with the BaseEngine.ini file. Any overrides in DefaultEngine.ini or a platform-specific ini are applied as before.

The call order continues down into the Device Profiles system. First, the Device Profile Matching Rules are run to determine the lowest level device profile that should be applied (Android Galaxy in this case).

Next, it starts applying rules by first applying the highest level device profile (Android) that matches the device. It starts by checking the CVars in the engine-provided BaseDeviceProfiles.ini, then checks the game-specific DefaultDeviceProfiles.ini to see if any of the CVars have been overridden.

This process continues down the hierarchy and checks the AndroidMid and the Android Galaxy device profile settings in a similar process to the Android call described above. Once all device profiles have been applied, it would continue on to apply any overrides at higher priority levels described above.

Setting Game-Specific Overrides

If you want to change a specific setting for your game, then you need to set up the configuration files. The settings are stored in several different locations, so this is a multi-step process that begins with finding the correct setting. In the examples below, we will demonstrate the process of starting with a general concept such as "bloom quality" to finding a specific setting like r.BloomQuality. You can find this setting from either an .ini file, the in-editor Console Variable list, or in the source code.

Engine Configuration: BaseScalability.ini

Begin by navigating to your Engine/Config folder, and clicking on the BaseScalability.ini file. Once you have opened the file, you can look for the PostProcessQuality group section to find the variable r.BloomQuality.

Device Profiles: Console Variables

Open the Device Profile editor by navigating to Tools->Platforms->Device Profiles. Once in the editor, locate the Windows profile, then in the CVars column, click the Edit icon next to Windows.



This opens a window with a categorized list of all Console Variables that can be set from Device Profiles:



The Bloom Quality variable pictured in the image above is listed in the Rendering category.



Editor Command Line

Open up a running game or editor window, hit the tilde key(~) to open the full console, then in the Cmd line text field, type in "Bloom". The autocomplete section will list all console variables that include "Bloom" and can be set at runtime, which includes r.BloomQuality.

Manually Searching

You can search all .ini files in the engine for a term like "bloom" using a code editor such as Visual Studio that supports a text search within the engine directories. Alternatively, you can search the Engine API code base for specific terms. Once you find your specified console variable or config setting, we recommend you search all engine .ini files for that setting so you know where it is set, then you can apply your game or platform-specific setting.

Overriding Settings In Config Files

If you want a Console Variable setting to always be the same across all platforms and scalability groups, this can be done from the [ConsoleVariables] section of the DefaultEngine.ini file. As an example, we can override bloom quality in all cases by adding the following to the DefaultEngine.ini file.

If the setting you are seeking is in the BaseScalability.ini or another config file, then you can override it by creating a new config file in your project. To do this, create or edit the file in your project's config directory that matches the same name as the engine, but instead use the Base to replace the Default. You can add or find a section with the same name as the variable in the Engine. For instance, to change the bloom quality for the Low quality post process scalability group, you can add this text to the DefaultScalability.ini file.

If the engine sets a Console Variable in a platform-specific config file such as WindowsEngine.ini, then you can override this setting for a specific platform using the same platform-specific config files. Additionally, you can change any platform-specific settings that do not use the device profile or console variable system. To do this, make a new platform-specific config file that matches the same config in the engine. For example, to override the Engine/Config/Windows/WindowsEngine.ini file, You can make a new ProjectName/Config/Windows/WindowsEngine.ini file, and make the same type of changes described above.

For platforms such as consoles that use the top level Platforms directory in the engine, we recommend that you make a parallel directory in your project folder. You can create a PlatformNameScalability.ini file in the correct directory, and this will provide you with the ability to override scalability groups for specific platforms such as Android.

Setting Up Device Profiles

To accomodate device-specific differences, you will need to set up your project-specific device profile hierarchies. The easiest way to do this is using the Device Profile editor found by navigating to Tools > Platforms > Device Profiles. Once you are in the editor, click the Edit icon next to the device profile you want to set values for:



We recommend that you edit the highest-level profile that includes all devices you want to change. Then, edit the console variables list to add or remove settings for the profile you want to change:



This screen will not save your changes. Unlike other settings screens in the editor you will need to open the DefaultDeviceProfiles.ini file using the button at the top of the editor, then when you are finished editing, click Save as Defaults to write the changes out to your project's DefaultDeviceProfiles.ini file. If your editor is connected to source control you may need to click that same area to check out or add that file to source control. This editor save will only write the modified profiles, but you may want to manually fix the resulting .ini file to make it easier to read.

Texture LODGroups settings for specific platforms can be set from the Device Profiles window, by clicking the Edit icon in the TextureLODGroups column.



If you have a lot of platforms that will run your project, then it may be easier to choose to override the engine defaults by adding a [/Script/Engine.TextureLODSettings] section to your DefaultDeviceProfiles.ini. You can also add additional device profiles by adding new DeviceProfileNameAndTypes entries to the [DeviceProfiles] section. Following these methods, your settings will now be working as you intend. However, because of the setting priority hierarchy described in the table above, the engine settings at a higher priority may conflict with Project-specific settings at a lower priority.

For example, if the engine sets a variable in the DefaultDeviceProfiles.ini, but you want to set it by scalability groups, then you will have to undo the engine's device profile setting.

Undoing an Existing Engine Setting

In some cases, you need to undo the engine's default value for a setting because it causes a conflict with your desired setting. Usually, this behavior is because you want to move a setting to a different level in the setting priority list, or move things between scalability groups. As an example, we want to move Bloom Quality from the PostProcess Scalability bucket to the Effects bucket. This can be done by opening your DefaultScalability.ini file and adding lines similar to the examples below:

This uses an advanced configuration system syntax where you use a line starting with a ‘-' to cancel the engine change in one category (the line in the DefaultScalability needs to match the line in BaseScalability exactly other than the -), and then move it to a new category.

Overriding an Array such as the CVars array located in the BaseDeviceProfiles.ini file, can be accomplished using two different methods. If you use the Device Profile window in the editor and save your settings, then it will create a DefaultDeviceProfile with multiple -CVars= lines that will cancel each individual default element in the array.

If you want to wipe out an entire array set by the engine and replace it, you can use the line:

then add new elements by using the line:

Additionally, if the base array uses the @Array=Key syntax, then it is treated like a Map, and you can override lines using that key.

As an example, the lines below can be added to the DefaultDeviceProfiles.ini file to set the World Normal Map textures to automatically reduce to a dimension of 2048x2048 (if they are larger than that amount).

The line @TextureLODGroups=Group located in the BaseDeviceProfiles.ini, means you do not need to remove the old value with a - or a ! preface :

Lyra Examples

The Lyra game sample serves as an example for how to combine these different features for your specific project. In the sections below you will observe how the different components come together.

Scalability Groups

The Lyra/Config/DefaultScalability.ini file was created manually, by copying and renaming the BaseScalability.ini file located in the Engine/Config folder, then editing it to remove any redundant sections.

The file has two sets of changes that tweak how the scalability groups work:

The Performance Thresholds used by the automated benchmark tools have now been raised from the original engine defaults, as a result faster computers are required to reach High or Epic quality levels.

The foliage.DensityScale and grass.DensityScale Console Variable settings have been moved out of the FoliageQuality category and into the ViewDistanceQuality category.

This is done to make a simplified options menu UI because it is unnecessary to single out foliage quality for a specific game.

Device Profiles

The DefaultDeviceProfiles.ini file was created using the Save To Defaults option in the Device Profile window located in the editor, then these values were manually edited to add additional profiles, and modified later using the Device Profile window to tweak individual settings.

It includes the following changes:

A default texture group override was added to define settings for a game-specific "UI With MIPs" category, which is named in the editor using the [EnumRemap] section in DefaultEngine.ini.

A new Mobile device profile was added to serve as a base profile for IOS and Android.

The new Mobile profile was defined with a new CVar setting and override texture groups to reduce the maximum Mip size on mobile devices to save on memory and download size. These sizes are applied at cooking time.

The IOS and Android device profiles were modified to set their base profile to the new Mobile profile.

Platform Configuration Files

Platform configuration files provide an example to create files for your own project. Config files for public platforms are available in the Default*.ini file located in the Config folder. Supported platforms that require licensing from the platform holder, such as game consoles, are available in the Lyra/Config/PlatformName/PlatformName*.ini directory.

If you have a license for a non-public platform, you can contact your Epic partner. See Epic Online Services for additional information.

Lyra includes a custom configuration option that can be used to create distribution-specific variants of a game. For example, if your game is shipping on multiple Windows-based stores, you can create subfolders inside the Config/Custom folder that contains the .ini files that override the store-specific settings.

These .ini file overrides are enabled with the development command line option:

Alternatively, you can use the CustomConfig parameter located in a Target.cs file. Platform-specific custom config files can be added by creating files named using a file path similar to Config/Custom/CustomConfigName/PlatformName/PlatformNameEngine.ini.

Game User Settings

For handling user specific device settings, Lyra uses the ULyraSettingsLocal class as a subclass of UGameUserSettings. Lyra uses the same settings UI to modify the local settings such as Volume and Graphics Quality which are only stored on the device, and the ULyraSettingsShared class to handle key bindings which can be written to cloud storage and used on multiple devices.

Refer to the GameSettings plugin documentation for further information.

A Tour Of Lyra

Lyra Main Play Menu

QuickPlay

Start a Game

Browse

Options

Menu Options

Display

Graphics

Graphics Quality

Advanced Graphics

Volume

Sound

Sensitivity

Default Keyboard & Mouse

Shooter Keyboard & Mouse

Gamepad

Sensitivity

Controller Deadzone

A Tour Of Lyra

When launching Lyra, you will be greeted with the main menu.



Main Menu Option

Description

Play Game

Launches the Play Menu of Lyra that contains the options to Quickplay, Start a Game, and Browse.

Options

For Game Languages, Video and Audio Settings, Key bindings and inputs, and Accessibility options.

Credits

Contains an example of a game Credits UI template.

Quit Lyra

Exits the game.

Lyra Main Play Menu

When you click Play Game from the initial main menu, the Main Play Menu is displayed.



QuickPlay

The QuickPlay menu joins an existing session of any game type or starts a new online game that others can join.

Start a Game

Start a Game creates a new session of any type with other players or bots. Online or local is available. When choosing to start a game, you will have the opportunity to select your game mode from the available options.

Game Mode

Description

Control

Secure the control points along with your teammates to increase your score and win.

Elimination

Find and eliminate enough enemies to win in this classic head-to-head team match.

Exploder

Destroy blocks, collect power-ups, and avoid getting exploded in this top-down party game.



Browse

The Browse menu searches for an active game session online and on your local network.



Options

The options menu contains settings for Game Languages, Video and Audio Settings, Key bindings and inputs, and Accessibility options.

Menu Options



Window Mode

Provides a template of modes or screen settings to display the game.

Full Screen:Fullscreen displays the game on your entire screen and hides your operating system interface. This may prevent your interaction with other windows, however, the project will run at a better performance.

Windowed FullScreen: Windowed Fullscreen displays the game in a Fullscreen resolution while providing the capability to interact between other windows or applications on your operating system interface.

Windowed: Windowed mode provides you with the capability to drag the edges of the window to maximize or minimize the window screen, and interact between other windows and applications.



Resolution

Controls the number of pixels that are displayed on the dimensions of your screen size. The supported Screen Dimensions include:

1280 x 720

1600 x 900

1920 x 1080

2560 x 1440

3840 x 2160

Fullscreen: Resolution determines the GPU output resolution.

Depending on your Graphics card and monitor screen size, this may result in a rendering display of black bars appearing on your screen.



Windowed: Resolution determines the size of the window.

Windowed Fullscreen: Resolution is inactive.



Performance Stats

Configures the display of performance statistics.

Client FPS

Displays the Client Frame Rate. The available display options are:

None

Text Only

Graph Only

Text and Graph



Server FPS

Displays the Server Frame Rate. The available display options are:

None

Text Only

Graph Only

Text and Graph



Frame Time

The total frame time.

Idle Time

The amount of time spent waiting idle for frame pacing. The available display options are:

None

Text Only

Graph Only

Text and Graph



CPU Game Time

The amount of time spent on the main game thread. The available display options are:

None

Text Only

Graph Only

Text and Graph



CPU Render Time

The amount of time spent on the rendering thread. The available display options are:

None

Text Only

Graph Only

Text and Graph



CPU RHI Time

The amount of time spent on the Render Hardware interface thread. The available display options are:

None

Text Only

Graph Only

Text and Graph



GPU Render Time

The amount of time spent on the GPU. The available display options are:

None

Text Only

Graph Only

Text and Graph



Network

Ping

The round trip latency of your connection to the server. The available display options are:

None

Text Only

Graph Only

Text and Graph



Incoming Packet Loss

The percentage of incoming packages lost. The available display options are:

None

Text Only

Graph Only

Text and Graph



Outgoing Packet Loss

The percentage of outgoing packages lost. The available display options are:

None

Text Only

Graph Only

Text and Graph



Incoming Packet Rate

Rate of Incoming packets(per second)The available display options are:

None

Text Only

Graph Only

Text and Graph



Outgoing Packet Rate

Rate of outgoing packets(per second)The available display options are:

None

Text Only

Graph Only

Text and Graph



Incoming Packet Size

The average size (in bytes) of packets received in the last second The available display options are:

None

Text Only

Graph Only

Text and Graph



Outgoing Packet Size

The average size (in bytes) of packets sent in the last second The available display options are:

None

Text Only

Graph Only

Text and Graph





Color Blind Mode

Toggles the display to render in Color Blind Mode from the following options:

Deuteranope

Protanope

Tritanope



Color Blind Strength

Uses the provided images to test out the varying strengths of color correction within a range between 0-10.

Brightness

Adjusts the brightness between a value of 0 and 100%.



Auto-Set Quality

Auto-Set Quality automatically configures the Graphics Quality options based on the benchmark of your hardware.

Quality Presets

Quality Presets provide you with the following adjustable video quality options:

Low

Medium

High

Epic



3D Resolution

3D Resolution determines the resolution of objects that are rendered in the game, this is controlled from a slider with a range between 0-100%.

3D Resolution will not affect the resolution of the Main Menu UI.



View Distance

View Distance determines how far away objects are culled for performance. The following options are available:

Near

Medium

Far

Epic



Shadows

Shadows determine the resolution and view distance of dynamic shadows. Shadows improve visual quality and depth perception, however, may decrease performance. The following options are available:

Off

Medium

High

Epic



Anti-Aliasing

Anti-Aliasing reduces jagged artifacts along geometry edges. Increasing this setting will make edges look smoother, however, it may decrease performance. The following options are available:

Off

Medium

High

Epic



Textures

Textures determine the resolution quality of textures in the game. Increasing this setting will make objects more detailed, however, it may reduce performance. The following options are available:

Low

Medium

High

Epic



Effects

Effects determine the quality of visual effects and lighting in the game. Increasing this setting increases the quality of visual effects, however, it may reduce performance. The following options are available:

Low

Medium

High

Epic



Global Illumination

Global Illumination controls the quality of dynamically calculated indirect lighting bounces, Sky Shadowing, and Ambient Occlusion. Setting this to High or above will use accurate ray-tracing methods to solve lighting, however, may result in a decrease in performance. The following options are available:

Low

Medium

High

Epic



Reflections

Reflections determine the resolution and accuracy of reflections. Setting this too high or above will use accurate ray-tracing methods to solve reflections, however, may result in a decrease in performance. The following options are available:

Low

Medium

High

Epic



Post Processing

Post Processing Includes Motion Blur, Depth of Field, and Bloom. Increasing this setting will improve the quality of post-process effects, however, may result in a decrease in performance. The following Post Processing menu options are available:

Low

Medium

High

Epic





Vertical Sync

Vertical Sync eliminates screen tearing by always rendering and presenting a full frame. Disabling vertical sync can give a higher frame rate and better input response, however, it may result in horizontal screen tearing. Vertical Sync is toggled by the following options:

Off

On



Frame Rate Limit(On Battery)

Sets the Frame rate limit when running on battery. Set this lower for a more consistent frame rate or higher for the best experience on faster machines. You may need to disable VSync to reach high frame rates.

30 FPS

40 FPS

120 FPS

144 FPS

160 FPS

165 FPS

180 FPS

200 FPS

240 FPS

360 FPS

Unlimited



Frame Rate Limit (Menu)

Frame rate limit when in the menu. Set this lower for a more consistent frame rate or higher for the best experience on faster machines. You may need to disable VSync to reach high frame rates.

30 FPS

40 FPS

120 FPS

144 FPS

160 FPS

165 FPS

180 FPS

200 FPS

240 FPS

360 FPS

Unlimited



Frame Rate Limit (Background)

Frame rate limit when in the background. Set this lower for a more consistent frame rate or higher for the best experience on faster machines. You may need to disable Vsync to reach high frame rates.

30 FPS

40 FPS

120 FPS

144 FPS

160 FPS

165 FPS

180 FPS

200 FPS

240 FPS

360 FPS

Unlimited



Frame Rate Limit

Frame rate limit sets the highest frame rate that is allowed. Set this lower for a more consistent frame rate or higher for the best experience on faster machines. You may need to disable Vsync to reach high frame rates.

30 FPS

40 FPS

120 FPS

144 FPS

160 FPS

165 FPS

180 FPS

200 FPS

240 FPS

360 FPS

Unlimited





Overall

Adjusts the overall volume of Music, Sound Effects, Dialogue, and Voice chat. This is controlled from a slider with a range between 0-100%.

Music

Adjusts the volume of Music. This is controlled from a slider with a range between 0-100%.

Sound Effects

Adjusts the volume of Sound Effects. This is controlled from a slider with a range between 0-100%.

Dialogue

Adjusts the volume of dialogue for game characters and voice-overs. This is controlled from a slider with a range between 0-100%.

Voice Chat

Adjusts the volume of voice chat. This is controlled from a slider with a range between 0-100%.



Subtitles

Configures the visual appearance of Subtitles.You can access a full list of sub-settings by clicking Options.

Toggles Subtitles ON or OFF.

Performance Stats

Configures the display of performance statistics.

Text Size

Adjusts the size of the subtitle text through the following options:

Extra Small

Small

Medium

Large

Extra Large



Text Color

Choose different colors for the subtitle text.

White

Yellow



Text Border

Choose different borders for the text.

None

Outline

DropShadow



Background Opacity

Choose a different background or letterboxing for subtitles Clear

Low

Medium

High

Solid



Audio Output Device

Changes the audio output device for the game audio. The options below will display the audio output devices currently available to your Operating System. * Default

Changing this setting will not affect voice chat



Background Audio

Turns the game audio on/off when the game is in the background. When on, the game audio will continue to play when the game is minimized, or another window is focused. Available options include:

Off

All Sounds



3D Headphones

Enable binaural audio. Provides 3D audio spatialization, so you can hear the location of sounds more precisely including above, below, and behind you. Recommended for use with stereo headphones only. Available options include:

Off

On



High Dynamic Range Audio

Enables high dynamic range audio. Changes the runtime processing chain to increase the dynamic range of the audio mixdown. Appropriate for theater or more cinematic experiences.Available options include:

Off

On





X-Axis Sensitivity

Sets the sensitivity of the mouse's Horizontal(x) axis. With higher settings the camera will move faster when looking left and right with the mouse.

Y-Axis Sensitivity

Sets the sensitivity of the mouse's Vertical(y) axis. With higher settings the camera will move faster when looking up and down with the mouse.

Targeting Sensitivity

Sets the modifier for reducing mouse sensitivity when targeting. 100% will have no slow down when targeting.Lower settings will have more slow down when targeting.

Invert Vertical Axis

Enable the Inversion of the Vertical look axis. Options to toggle are:

Off

On



Invert Horizontal Axis

Enable the Inversion of the Horizontal look axis. Options to toggle are:

Off

On





Move Forward

Key Bindings for Move Forward.

Move Backwards

Key Bindings for Move Backward.

Move Left

Key Bindings for Move Left.

Move Right

Key Bindings for Move Right.

Fire Weapon

Key Bindings for Fire Weapon.

Jump

Key Bindings for Jump.

Crouch

Key Bindings for Crouch.

Reload Weapon

Key Bindings for Reload Weapon.

Dash

Key Bindings for Dash.

Auto-Run

Key Bindings for Auto-Run

Fire Weapon(Auto)

Key Bindings for Fire Weapon(Auto)



Show Scoreboard

Key Bindings for Show Scoreboard.

Aim Down Sight

Key Bindings for Aim Down Sight.

Throw Grenade

Key Bindings for Throw Grenade.

Emote

Key Bindings for Emote.

Quick Slot 1

Key Bindings for Quick Slot 1.

Quick Slot 2

Key Bindings for Quick Slot 2.

Quick Slot 3

Key Bindings for Quick Slot 3.

Melee

Key Bindings for Melee.

Quickslot Cycle Backward

Key Bindings for Quickslot Cycle Backward.

Quickslot Cycle Forward

Key Bindings for Quickslot Cycle Forward



Controller Hardware

Toggles the type of controller you're using. Options to choose include:

Xbox Controller

Dual sense



Vibration

Turns controller vibration on or off.

Off

On



Invert Vertical Axis

Enables the inversion of the Vertical look axis.

Off

On



Invert Horizontal Axis

Enables the inversion of the Horizontal look axis.

Off

On





Look Sensitivity

How Quickly your view rotates.

1(Slow)

2(Slow+)

3(Slow++)

4(Normal)

5(Normal+)

6(Normal++)

7(Fast)

8(Fast+)

9(Fast++)

10(Insane)



Aim Sensitivity(ADS)

How quickly your view rotates while aiming down sight(ADS).

1(Slow)

2(Slow+)

3(Slow++)

4(Normal)

5(Normal+)

6(Normal++)

7(Fast)

8(Fast+)

9(Fast++)

10(Insane)





Left Stick DeadZone

Increase or decrease the area surrounding the Left stick that we ignore input from. Setting this value too low may result in the character continuing to move even after removing your finger from the stick.

Right Stick DeadZone

Increase or decrease the area surrounding the Right stick that we ignore input from. Setting this value too low may result in the character continuing to move even after removing your finger from the stick.

Upgrading To the Latest Engine Release

Unreal Engine 5.1

Unreal Engine 5.0

The Lyra Starter Game is updated with each major release of the Unreal Engine. These updates take advantage of the newest features of the engine and fix other issues specific to Lyra.This page documents the major changes made to Lyra for each engine version and includes information that can help you upgrade existing games to the newest release of Unreal Engine 5.

Upgrading To the Latest Engine Release

Games like Lyra that include C++ code will need manual updates to work correctly with new major releases of the Unreal engine. Major upgrades of the engine from 5.0.x to 5.1.x may deprecate older features or settings, and may change existing functions and variables used by your project. Therefore, some game-specific code and data will need to be updated to work properly after the upgrade.

Using Lyra as an example, follow the steps below to update a game:

You should read the release notes for the new engine version, ensuring you keep track of any major changes and upgrade notes that may affect your game.

Download and install the new version of the engine.(understanding-the-basics/installing-unreal-engine) You may want to install this to a different directory than your current engine version, so you can compare the older and newer versions of the game.

Download and install the new version of the Lyra Starter Game sample that matches the new version of the engine so you can see how it was updated. If you install this to a different directory, you can compare it to the old version.

Refer to the Unreal Engine 5 migration guide to check compatibility with the newest version of the engine.

Load your project in your C++ code editor and attempt to compile it. This will likely fail.

Fix any deprecation warnings by using the instructions included in the deprecation message.

For any errors about invalid or missing classes or structs, you will need to add a new #include line to the top of the file. If you are using Visual Studio, you can navigate to Edit > Find and Replace > Find In Files then search for the missing type name. Look for the header file that defines that type and add a new #include.

For errors about virtual function overrides, you will need to update the parameters of your overridden function in both the header and .cpp file.

For any errors about invalid variables on a class or struct, you will need to use a different method of accessing that variable. This is usually solved by calling an accessor function like Get() or GetVariableName() that will return the actual value.

If you are unsure about how to fix an error, search the release notes or reach out to the community forums for more information.

By comparing the older and newer versions of the Lyra Starter Game, you can see how to handle complex changes to the source code. The version-specific information below will help you upgrade your game if it includes any code or content from Lyra.

Unreal Engine 5.1

In Unreal Engine 5.1, the Lyra Sample Game was updated to fix issues with the sample and take advantage of the newest features added to the engine.

Upgrade Notes for 5.1:

Several engine headers were reorganized to improve compile times. This exposed some issues with the Lyra source files. These issues can be fixed by adding a #pragma once line to the headers missing them, and adding lines like #include EditorStyle.h to source files that have errors about missing types.

Several raw pointer properties in gameplay framework classes were changed to use TObjectPtr or TWeakObjectPtr. Any code that needs a raw pointer can be fixed by adding a call to the Get() function.

The ENSURE_ABILITY_IS_INSTANTIATED_OR_RETURN macro was removed from GameplayAbility.h. This macro can be copied from GameplayAbility.cpp to other ability source code files.

Several virtual functions related to game feature plugins were modified to add new parameters. Overridden functions in classes like ULyraGameFeaturePolicy will need to be updated.

The geometry mesh Blueprint Tools/BakedGeneratedMeshSystem/BaseClasses/BakedGeneratedMeshActor was updated for 5.1. Although the 5.0 asset will continue to function, Nanite settings will not be configured properly unless the 5.1 version is used.

Improvements in 5.1:

The pawn initialization flow in the LyraHeroComponent and LyraPawnExtensionComponent was rewritten to use the new IGameFrameworkInitStateInterface and the Init State system on the GameFrameworkComponentManager. This fixes several race conditions in network replication and is easier to extend with new feature-specific components.

Added Android device profiles for devices with different capabilities, and adjusted other platform settings.

Added UI for loading common maps to the editor toolbar.

Added basic handling for multiplayer game invites using Epic Online Services.

Added prototype and test content into the new ShooterExplorer and ShooterTest plugins.

Improved the keybinding screen with a warning screen when binding a key that is already assigned.

Bug Fixes in 5.1:

The ShouldEnableAllGameFeaturePlugins function in LyraGame.Target.cs was changed to return false, which means that game feature plugins are now enabled like normal plugins. This fixes plugins to work the same for both custom-compiled and launcher-installed versions of the engine.

Fixed an issue where running Lyra would change the keybind for exiting Play In Editor in other projects.

Changed abilities to properly use the Healing and Damage attributes instead of applying a negative modifier to Health.

Updated code and Blueprints to use the new PlatformUser and InputDeviceId types instead of deprecated controller ids.

Unreal Engine 5.0

The 5.0 version of Lyra Sample Game was updated along with 5.0.2 to fix several bugs in the original release. These fixes are included in all later releases of the sample.

Bug Fixes in 5.0.2:

Fixed automation scripts to handle different installation directories.

Fixed the inverted mouse setting.

Updated mannequin retargeting and control rig assets.

Updated antialiasing settings in mobile device profiles.

Added missing editor icons.

Epic Account and Engine Setup

Epic Online Services Product Setup

Installing and Configuring Lyra

Testing EOS in an Editor Build

Packaging LyraGameEOS

Next Steps

The Lyra Starter Game is an example project that is designed for developing and shipping a multiplayer game. It uses its online multiplayer support and integrates with the Epic Online Services (EOS) backend. However, if you downloaded Lyra from the Epic Games Launcher, then it will not work with EOS without some additional setup.

Epic Account and Engine Setup

To use EOS in Lyra, you will need to set up accounts for access to both EOS and the Unreal engine source code:

To test multiplayer, you need at least 2 Epic Accounts. You can create a new account by navigating to the Epic Games Store page, then click Sign In, and Sign Up with a new email address and password.

For efficiency, you can use a second browser to login with your second account.

To enable full EOS support, you need one Account that has access to the Unreal Engine source code. Check that your primary Epic Account is synced with GitHub as described in Unreal on GitHub.



Once you have source code access, follow Downloading Unreal Engine Source Code to download and install the engine source code. Install the Release branch of the engine. You can use either Visual Studio 2019 or Visual Studio 2022.

Downloading the source code and running Setup.bat can take some time. We recommend you continue with account creation while waiting for the setup to complete.

You need to enable 2-factor authentication on both accounts to gain access to the EOS developer tools. This can be done from the Account Management page, by navigating to Password & Security, or can be prompted when you perform step 5.



Both Epic Accounts need access to the EOS Developer Portal (Dev Portal). When you navigate to the Dev Portal, a prompt appears to accept licenses and to choose between starting On your own, or As an Organization. Choose As an Organization to create an organization with your primary Account.



While you are logged into your primary Account and Organization using the Dev Portal, you will need to add your secondary Account to the Organization. Click the Organization section on the left in the Developer Portal table of contents, then from the Team tab, click the Invite button. You are then prompted to fill in the email address of your secondary Account.



The role does not matter for development testing so you can select Community Tools before clicking Invite. You can rename your Organization by clicking Settings. Optionally, you can make an organization for your secondary Account, however, it is not necessary for this tutorial.

Your secondary Account will receive an invite link in the email. You will need to visit this URL while signing in to your secondary Account.

You can paste the URL into the browser where your secondary Account is already signed in to accept the invite.

After accepting the invite, the secondary Account will not be used for anything other than logging in during testing.

Epic Online Services Product Setup

When you have an Epic Account with Developer access and an Organization, you need to set up a product on the backend to use in your local copy of Lyra. To develop and test Lyra on the PC platform, an additional setup needs to be completed for both EOS and Epic Account Services (EAS).

Epic Account Services provides authentication and social tools designed to integrate with EOS. The use of EAS is not required if you have access to another authentication system provided by a platform or publisher. Lyra uses EAS to handle development login as well as integration with Epic Games Store.

The steps in this section are all performed in the EOS Dev Portal and cover the same information as the EOS setup guide and the Epic Account Services getting started page:

First, you need to set up a Product. You can create a new product by selecting Create Product. You can then select your product to see the options for the various EOS features.



Next, you need to set up a Client and Client policy for your version of Lyra. From the Product Settings, click the Clients tab. This prompts you to read and accept legal agreements After doing so, the Clients page displays prompts for additional licenses. For this tutorial, you need to accept the licenses for Epic Account Services.



Click Add New Client to create a new client named "Lyra Test Client". Then click Add New Client Policy.



In the Client policy name field, enter "Peer to Peer client" as it can be reused for multiple products. For the Client policy type, select Peer2Peer as it provides everything needed by Lyra. Click Save & Exit twice to save your new policy and client.



To allow the use of EOS for development testing, you need to set up an Application to connect your product with EAS. To use your game with EOS, you need to set up an EOS Application on the service. This links your game with Epic Account Services. To do this, select Epic Account Services, This prompts you to read and accept legal agreements. After doing so, click the Permissions (1) field of your Lyra Test Product. Or, you can click Create Application (2) and click the Permissions tab in the upper right.



The Brand Settings need to be set up before the release, however, it is not required for development and testing.



On the Permissions page, enable both Online Presence (1) and Friends (2) as Lyra needs them to enable social features. Click Save Changes (3).



Select Linked Clients (1), then click the drop-down arrow next to Select Clients and choose the Lyra Test Client (2) to link it to this application, then click Save Changes(3).



You can navigate to the Product Settings page and from the General tab, scroll down to view all the information you will require later.



The final step for EOS setup is to install the Developer Authentication Tool. This makes multiplayer testing easier because you can log in to each account once instead of having to do a 2-factor authentication check every single time you launch the game.

There is a copy of the authentication tool inside the Engine/Source/ThirdParty/EOSSDK/Tools folder of your UE5 source installation directory, or it can be found inside the EOS SDK download.

Installing and Configuring Lyra

You now have a fully downloaded version of the engine and a completely set up EOS product. The steps below walk you through the process of installing, configuring, and building Lyra so it can be used with EOS. These steps are similar to those in the Lyra documentation.

Open the Epic Games Launcher (log in with your primary Account), and select Unreal Engine > Samples. Click Lyra Starter Game and then Create Project.



Do not accept the default settings. Instead, name your project.

If you are planning on adapting Lyra into another game, you should use that name here.

Select the root folder where you installed your engine source code. click Browse to select that folder, then click Create to download the project. After this, you should have both an Engine subfolder and a subfolder matching the project name (LyraStarterGame by default) you just selected.

You will need to install the UnrealVS extension located in the Engine/Extras/UnrealVS folder. This provides you with easy management of the startup project and command line parameters inside of Visual Studio.

Navigate to the root of your engine source code, then install and run GenerateProjectFiles.bat to create a new solution file called UE5.sln. Double-click that file to load Visual Studio. After a loading time, your version of the LyraStarterGame is listed in the Solution Explorer under the Games category (including LyraGameEOS).



Right-click LyraStarterGame, select Set As Startup Project then build it.

This will compile Lyra and all the engine features required and may take a while. If you have any compile errors, you need to resolve them before continuing.

Once Lyra has been built from source, you can run it from the Debug menu and explore the project sample.

You need an additional set-up so the project is configured for EOS. Lyra comes with EOS-specific config files that are enabled using the CustomConfig feature of the Common User Plugin.

You will need to modify the DefaultEngine.ini located in the Config/Custom/EOS folder inside your project. Open the file and search for the following line:

You can remove the starting semi-colon to uncomment the line.







You need to modify the Artifacts line for the EOS product you made earlier. The information you require is visible on the Product Settings page of the EOS dashboard. The process for doing this is described in the EOS OSS Plugin documentation, however, below are the important fields:

Artifact Name is used to label this unique combination of settings and should match the value of the DefaultArtifactName=OSSv1EOS line.

Navigate to the Developer Portal. Copy the Product ID, Client ID, and Client Secret from the same text fields in the Product and Clients sections.

Click Copy to copy those values to your clipboard, then Paste them into your text editor.

The Sandbox ID describes how to find data for features like achievements, you can use the ID for the default Live sandbox. Deployment ID can be set to the Release ID as the game is still in development. Once you are further into development you may want to create multiple sandboxes and deployments for testing and release.

The Encryption Key is used to encrypt client-written files saved in the cloud, but Lyra does not actually use that feature. You can set this value to "0" or any random 64-bit number in quotations.

After modifying the config file, save.

Testing EOS in an Editor Build

You can now begin the steps to test the game in the editor and packaged builds.

Inside Visual Studio, enable the UnrealVS toolbar, and add the following line to the command line section:

Debug the project to launch with the new command line, this launches in standalone game mode and uses the EOS config files. When finished, an error message displays "Login Failure Not Implemented".

Click OK and the Lyra main menu will load. This error message means your project is trying to use EOS but is failing to log in because you did not specify enough information on the command line. If you do not see a login failure error message, there may be an error with the config file, therefore you should search the output log for any errors related to EOS.



Now, run the Developer Authentication Tool you unzipped in the Epic Online Services Product Setup step. When you run the EOS_DevAuthTool program, it prompts you for a port to use, enter 6666.



On Windows, you may receive an additional prompt asking for firewall access. You need to allow access.



Next, click Login to open an embedded browser where you can log in with your primary Epic Account. After entering your two-factor code, it prompts you for a Credential name, enter "Player1" or something similar.



Repeat this process for your secondary Account, but give it a different credential name like "Player2". Your two Accounts will stay logged into the EOS backend for that testing session. Eventually, you will need to reboot the dev tool and log in again to refresh the authentication.

Navigate back to Visual Studio and add the following options to your command line in UnrealVS:

-AUTH_LOGIN=localhost:6666 -AUTH_PASSWORD=Player1 -AUTH_TYPE=developer

However, you need to replace the port and credential name with the one you picked above. For example, the full command line at this point could be:



Click Debug to launch the game again. This time, it uses the extra info on the command line to log in to EOS. A browser window opens to warn you about an unverified application, this is because of the incomplete Brand Settings. Click accept twice to authorize linking the Application to your Epic Account. This takes you back into the game and displays the main menu with no error message. Press shift+F3 to open the Epic Account overlay that indicates you are fully logged in.

This account is the host for your multiplayer game, so click Play Lyra then Start a Game to load the hosting screen. Ensure Network is set to Online, then select Elimination to start the match.



You may want to set your graphics quality to Low and enable windowed mode in the settings menu to make sure your computer can handle two copies of the game.

Return to Visual Studio and detach this client from the Debug menu. Prepare your secondary account login by changing the -AUTH_PASSWORD value in the command line in UnrealVS to the second credential name (Player2). Click Debug to launch the game again. When the second instance starts, you are prompted to authorize the Application for your second Account, and then shown the main menu.

To ensure everything is working, click Browse to show the Server Browser, and check the game hosted by your first instance of the game is still running.



Select the game. If you join the game successfully then the process is complete. You are now in a multiplayer game with 2 players(and bots).

Packaging LyraGameEOS

After you verify that EOS works in a development editor build, you can follow additional steps to create a packaged version of LyraGameEOS.

These steps only work if you followed the full process of installing Lyra into a copy of the engine built from the source code, as the launcher-installed version is not capable of customizing the build process.

Set up your project in a Development build and load the editor to create a packaged EOS version of the game.

You can clear the command line after the project name, UnrealVS will keep a history of command lines in the dropdown menu.

Once the editor loads, Navigate to the toolbar, click Platforms > Windows > Build Target, then select LyraGameEOS to build a customized version of the game that bakes the -CustomConfig=EOS setting into the executable.

Navigate to the Toolbar > Platforms > Windows > Package Project to choose an output directory. Once you select a directory it will start the cook and package process.

Check the output log for any errors.



If packaging Lyra fails and the log shows an error message related to UAT, you may be encountering a bug that was present in the original 5.0 release of the Lyra game sample. This can be fixed by downloading the Lyra sample for the 5.0.2 (or later) version of the sample or installing Lyra into a Samples/Games subfolder of your engine base install (C:\UE5\Samples\Games\LyraStarterGame).

If the cook and package process succeeds, it places a packaged copy of the game in the directory you selected. This packaged build can be zipped up and sent to another computer for real-world multiplayer testing.

If you run this packaged build from the Epic Games Store, it passes the correct user credentials in. However, for development testing you need to make a shortcut or batch file and add the command line:

Next Steps

After following these steps, you now have a fully working version of Lyra usable for multiplayer development and testing using EOS. With a working version of an EOS-enabled Lyra Game sample, you can use it as a base for other development tasks with the eventual goal of releasing your game. To adapt the Lyra multiplayer code for another existing game, you can either build your game on top of the entire Lyra code base, or you can copy the CommonUser plugin and config files into your own game as described in the documentation.

Lyra was designed to work on all supported console, mobile, and PC desktop platforms, however, the current version of the sample was primarily tested on PC using an internal version of the Epic Games Store. To prepare for publishing your own game on the Epic Games Store, we recommend you work with your publisher to complete the Brand Review process and start a conversation with the publishing team.

If you need help developing a cross-platform version of the game or have issues with the EOS setup steps in this tutorial, you can create a discussion on the EOS Community Forums or contact EOS support.

Overview

Accessing the Valley of the Ancient Sample

Recommended System Specs

Familiarizing Yourself With the UE5 Editor

The Content Drawer

Accessing Editor Modes

Navigating the Sample

High-End Visuals, Fast Iteration

A Direct Path to Quixel Megascans Assets

Nanite Virtualized Geometry

Lumen Global Illumination

Tailoring Meshes With New Modeling Tools

Populating a Landscape with Packed Level Instances

Chaos Destruction Workflow

Setting the Mood With Sky Atmosphere and Volumetric Niagara Effects

Collaboratively Constructing a Large World

One File Per Actor

World Partition

Data Layers

Flexible Real-Time Animation

Motion Warping

Control Rig Improvements

Full-Body IK Solver

Building Modular Gameplay

Extending Gameplay With Game Feature Plugins

Flexible Controls With the Enhanced Input System

Dynamic Interactive Audio

MetaSounds

Quartz Audio Synchronization

Final Notes

Valley of the Ancient is a short gameplay segment demonstrating early access features in Unreal Engine 5. Players control Echo, who appeared in the UE5 announcement trailer, as she explores an arid landscape and finds a portal to a mysterious dark realm. Inside, she navigates through a series of obstacles and battles the massive Ancient One. This sample provides a snapshot of the many quality of life features, rendering enhancements, and workflow innovations available in UE5.

This document will take you on a guided tour through these exciting new features, and how the team at Epic Games used them to both push the limits of what is possible with real-time rendering technology while also greatly streamlining the workflow for building a vast, high-fidelity scene.

Overview

The highlights of Valley of the Ancient include:

High-end visuals rendered with Nanite and Lumen.

A large world crafted with a library of Megascans assets and our new geometry tools.

Destructible assets created with an improved Chaos fracture workflow.

New paradigms for organizing level files and actors that make it easier to collaborate with many team members on one map.

Flexible real-time animation using full-body Inverse Kinematics (IK) and motion warping to fit character motion with gameplay.

Modular gameplay systems that can be loaded and unloaded in their entirety at runtime.

Procedural sound effects created using the new MetaSounds system.

A dynamic music system using Quartz to synchronize gameplay and music.

Accessing the Valley of the Ancient Sample

You can download both the Unreal Engine 5 Early Access build and the Valley of the Ancient sample in the UE5 tab in the Epic Games Launcher.





Click to enlarge image.



Scroll down to the entry labeled Sample project showcases new features in UE5 and click Get the Sample to download it.



Recommended System Specs

This sample is especially graphically intensive, and requires a powerful video card to run at a stable framerate. We also recommend installing it on an SSD, as Nanite and Virtual Textures depend on fast read speeds for the best possible results. The recommended hardware specifications are as follows:

Recommended System Specs (100% Screen Percentage)

Minimum System Specs (50% Screen Percentage)

12-core CPU at 3.4 GHz

64 GB of system RAM

GeForce RTX 2080 / AMD Radeon 5700 XT or higher

12-core CPU at 3.4 GHz

32 GB of system RAM

GeForce GTX 1080 / AMD RX Vega 64

Nanite is only supported by Nvidia Maxwell generation GPUs and AMD GCN generation GPUs or higher. Make sure you also have the most up to date drivers for your graphics card.

On lower spec systems, you can adjust the viewport screen percentage setting to get better performance. On the minimum spec, we recommend 50% or lower. You can set this in the Viewport Options Menu located in the upper-left corner of your editor viewport, using the Screen Percentage slider.



Alternatively, you can use the console command r.ScreenPercentage to set this value at runtime.

Familiarizing Yourself With the UE5 Editor

While the Unreal Editor in UE5 retains all the functionality from Unreal Engine 4, it has several workflow and user experience improvements which you should familiarize yourself with briefly before exploring the Valley of the Ancient sample.



The Content Drawer

The Content Drawer is located in the lower left corner of the editor. You can click the button for the Content Drawer, or you can press CTRL+Spacebar to summon and dismiss it.



Clicking Dock in Layout will also create a permanently docked Content Browser, similarly to how it functioned in UE4. You can simultaneously use both a docked Content Browser and the Content Drawer, and you can also manage Content Browsers by clicking the Content dropdown in the main toolbar. This increases the flexibility of the content browser and provides more usable screen real estate inside the editor when it is not in use.

The Content Browser itself has a revised layout with a folder tree permanently displayed on the left hand side, as well as a new Settings menu where you can configure how it displays assets, including view types, thumbnail sizes, and content filters.

Accessing Editor Modes

You can now toggle Editor Modes using the icons in the main toolbar.



This includes modes that will be familiar to UE4 users, as well as several new modes with powerful new features. They are as follows:

Number

Editor Mode

Description

1

Select

The default editing mode for selecting assets in the game world and editing their Details.

2

Landscape

Sculpt, paint, and manage landscapes.

3

Foliage

Paint and adjust foliage inside your environment.

4

Mesh Painting

Tools for vertex painting on meshes in your environment. Supports colors, weights, or textures.

5

Fracture

Tools for generating fractures in Static Meshes using the Chaos destruction system.

6

Brush Editing

Classic brush geometry editor. Use the pen tool to draw brushes in orthogonal viewports, then use other tools to refine shapes as desired.

7

Animation

Tools for manipulating Control Rigs, quickly applying poses, and setting up simple tweens.

8

Modeling

A full polygonal geometry editing suite. Model from basic primitives or modify individual meshes in your game world.

Navigating the Sample

When the sample opens, it will start in the Startup map. Most content for the Valley of the Ancient is contained in the AncientWorld map, which you can find in the AncientContent > Maps folder.

Most files supporting this world are located in the game's Content directory, but the assets for the Hover Drone and Ancient One are contained in Game Feature Plugins separated from the game's base project. The Hover Drone's assets are contained in the HoverDrone Content directory, while the Light Dart ability and the battle with the Ancient One are contained in the AncientBattle Content directory. To make these directories visible, click the Settings button in the Content Drawer, then toggle Show Plugin Content.



While Valley of the Ancient showcases a large world, there are no sub-scenes as you would traditionally use for level streaming in UE4. Instead, this sample uses World Partition and Data Layers to break up a scene into separate, editable parts.

To navigate the world, click Window > World Partition. This will open the World Partition window, which displays a simplified map of your world.



You can use your mouse wheel to zoom in on different regions of the world, and you can click-drag through the cells in this map to select them. Right-click after selecting some cells, then click Load Selected Cells to load them up in the main viewport. Similarly, you can use Unload Selected Cells to remove cells that you do not want to be visible, reducing the load on your computer.

We recommend that you avoid loading all of the world partition cells at once, and that you load only the sections of the level that you want to view or edit. The number of cells you can load will depend on the amount of memory your system has available. See the World Partition section below for more details about this system.



To view the layers that make up the dark and light worlds, click Window > Data Layers to bring up the Data Layers window.



You can use this window to enable or disable any of the layers that make up the scene. To view the dark world, enable the Dark World data layer. To view the light world, enable the Campfire Replace, Foliage, and Hero Area Mountain Range data layers. The Campfire Geometry data layer should always be present. You can experiment with enabling and disabling these layers to compare both versions of the world.

More details about these systems, how they are implemented in the sample, and their workflow benefits are available in Collaboratively Constructing a Large World.

High-End Visuals, Fast Iteration

Unreal Engine 5 aims to provide not only a new standard in high-fidelity visuals, but also the most accessible pipeline for real-time high-resolution applications in the world. In this section, we will detail how UE5's new rendering features contributed to the level of detail in the Valley of the Ancient, as well as the speed and convenience of the team's process for constructing it.

A Direct Path to Quixel Megascans Assets



Quixel Megascans assets gathered from Moab, Utah make up the backbone of the static mesh and texture library for Valley of the Ancient, representing roughly 90% of the assets in the environment. These are located in the AncientContent > Megascans folder inside the Content Drawer.



All of these are available in the Canyons of Utah Megascans pack. Moreover, Quixel Bridge is now integrated directly into Unreal Editor, removing the need for any external programs when importing or managing Megascans assets. UE5 automatically generates the needed material instances and meshes, and they can be used directly in-game. In the sections below, you will see not only how easily UE5 handles these high-resolution assets, but also how its tools gave the environment art team an impressive range of flexibility in crafting the landscape.

Nanite Virtualized Geometry

None of these assets use traditional LODs or require additional optimization. Instead, all of them have Nanite enabled. Nanite streams static mesh assets from disk, then represents them using virtualized geometry, dynamically scaling the number of polygons they use based on the resolution of the user's viewport. Virtual texturing behaves similarly for texture detail. This representation changes as the user moves through a scene, updating the level of detail on the fly. Closer objects receive more detail, while farther objects receive less -- but the total detail onscreen is roughly uniform.



Thanks to Nanite, the Valley of the Ancient environment can use hundreds of incredibly polygon-dense Megascans assets directly in the scene without any additional preparation. Even cliff faces weighing in at tens of millions of polygons and using massive textures render instantly, with no additional setup necessary on the part of technical artists. Even a high-polygon Zbrush sculpt can be used directly in a game.

To see Nanite in action, click the View Mode dropdown and change it from Lit to Nanite Visualization > Triangles.



This will display the triangle output from Nanite in real time.





Nanite does not support deformations, so it functions only with static meshes. However, this is more than enough to vastly simplify the pipeline for developing environments. Meanwhile, although Nanite can not use skeletal deformations, the towering Ancient One in the finale uses static meshes attached to a skeletal mesh, taking advantage of Nanite to render its ultra-high-resolution armor.





For more information about how to use and configure Nanite, refer to the Nanite documentation.

Lumen Global Illumination

Lighting for this detailed valley is powered by Lumen, Unreal Engine 5's new fully dynamic global illumination and reflections system. Lumen creates dynamic, believable scenes where indirect lighting adapts to changes in direct lighting and geometry, combining new and old techniques to achieve high-quality real-time results. Lumen is built with next-generation consoles and high-end PCs in mind, and is targeting 30-60 FPS on these platforms when Unreal Engine 5.0 ships.





Lumen is scalable, and supports a wide range of DX11 and DX12-capable hardware using Software and Hardware Ray Tracing modes. Valley of the Ancient uses Software Ray Tracing, which combines Screen Traces (or screen space tracing) with a Surface Cache representation to generate indirect lighting in the scene. Lumen uses Screen Traces to cover the mismatch that can happen with the lower quality Surface Cache, which is generated from the individual mesh's Signed Distance Field. You can visualize the Surface Cache using Show > Visualize > Lumen Scene. The Surface Cache only operates for the first 200 meters before falling back to screen traces for the distance scene.

Lumen is versatile and has quality options that enable it to work with both Nanite's virtualized geometry and traditional Static Mesh geometry, and screen traces enable skinned meshes to receive and contribute to indirect lighting, but they are limited by what's visible on screen. You can visualize Lumen's combined techniques by clicking Show > Visualize > Lumen Global Illumination inside an editor viewport.





Lumen works with all movable light sources, including emissive materials as light sources. Skylighting uses Lumen's Final Gather for sky shadowing, which allows indoor areas to be much darker than outdoor areas, and helps bring out lightly-colored surfaces that reflect more light.

A comparison of the campfire area with Lumen/Skylighting enabled, Lumen disabled, and both Lumen/SkyLighting disabled.



Thanks to the balance of quality, speed, and the "it just works" nature of Lumen, the team was able to light Valley of the Ancient's massive landscape intuitively without needing to worry about all the configuration options that are present with traditional lighting techniques. For more information about Lumen and more details about how it works, see Lumen Global Illumination and Reflections and Lumen Technical Details.

Tailoring Meshes With New Modeling Tools



Many of the Megascans meshes in the environment are not "stock" meshes as originally imported, but rather have been altered inside Unreal Editor to suit the unique needs of the landscape. The environment artists for Valley of the Ancient achieved this with the new Modeling Editor Mode in UE5.

While you can use the modeling editor to build meshes from scratch the same way you would in any DCC tool, you can also select any static mesh or instanced static mesh in the environment and modify its geometry. While editing these on a per-polygon basis would be cumbersome, the Modeling editor mode features numerous deformers and sculpting tools that can perform quick alterations on dense meshes.

For example, let's say you have a cliff face asset like SM_umshejnga_High2, but you need a version of it that curves. You can toggle the Modeling editor mode, select that mesh in the viewport, and then apply a Bend deformer to it. After a few seconds of tweaking, you can apply your deformation to the mesh and see the result.







Initial mesh.

Bend deformer active.

Final result with bend deformer applied.

Click images for full size.

Without having to re-do any UVs, you can create a variety of unique meshes from one high-resolution base mesh, with comparable quality to the original. This enables artists to gain maximum flexibility from assets of any resolution, and realize concepts with unique needs, without ever leaving the level editor.

Populating a Landscape with Packed Level Instances

The landscape in the Valley of the Ancient is large enough that even with the tools discussed so far, it would take an exceptionally long time to construct an environment with so much detail by placing Megascans assets individually. The environment art team for Valley of the Ancient therefore leveraged Packed Level Instances to kitbash large-scale assemblies.

Level Instances are essentially nested levels that you can add to any world that implements the World Partition system. While you do not need to use Level Instances for World Partitions to work, they are a handy tool for organizing chunks of content in your world into reusable parts, or for breaking a level up into more manageable pieces for editing outside of your main level.

To create a Level Instance, select a group of objects in the world, right-click, and click Create From Selection.



This opens the New Level Instance menu, where you can choose the type of Level Instance you want to create.



When you click OK, you can save your new Level Instance as a level file in your project, and it will generate a corresponding Blueprint asset along with it. All of the actors you selected will be replaced by a Level Instance actor that contains them. You can edit the Level Instance using its level file, and place a copy of the Level Instance using its Blueprint asset.



Manipulating Level Instances is as simple as manipulating other actors in your level. You can also edit the component parts of a Level Instance in-place. In the Details panel for a placed Level Instance, click the Edit button under Level Instance Editing to focus on that Level Instance. You can then edit the component parts of the Level Instance in the context of the rest of your world.



When you have finished, click Commit Changes to finalize your adjustments and return to editing your world. A prompt will appear to ask if you want to save your changes, and any copies of that Level Instance will take the same changes.



The Valley of the Ancient sample primarily uses Packed Level Instances to create assemblies. Unlike standard Level Instances, These ignore any actors that are not static meshes, and convert static meshes to instanced static meshes, reducing the number of draw calls created by their component assets.

This workflow provided a way for the environment art team to independently build a library of large-scale assemblies and edit them non-destructively. These varied from small, versatile assets that make up the observable landscape around the player, as well as massive geoforms that can compose large chunks of distant landscape. While many of these assemblies are composed with static mesh assets found inside the editor, some were custom-built by the team using the Megascans assets as a base. This gave the team a flexible assembly line to set-dress over four square kilometers of land with photo-realistic detail in just a few weeks.

You can find the map files for these assemblies in the AncientGameContent/Maps/MASS folder, and you can find the Level Instance actors that correspond to them in the AncientGameContent/Geometry folder. Refer to Level Instancing for more information about how to use these tools.

Chaos Destruction Workflow

The process of developing the destructible meshes for Valley of the Ancient, such as the columns in the dark world and the mound that the Ancient One rises from during the finale, drove many improvements to the Chaos Destruction workflow in UE5. The workflow that the team developed uses a combination of the new Modeling and Fracture editor modes.

The destruction team relied heavily on the Modeling tools to prepare the meshes and create targeted fractures. Simplify, Planar Cut (PlnCut), Offset, and Displace (to add a noisier surface) made it possible for the initial fractures to be sculpted from the source meshes themselves. The Boolean tool was used throughout this process to remove any overlapping Meshes penetrating through each other, leaving only the geometry on the surface. Stray polygons or floating islands of geometry were removed using the TriSel tool.



In the Fracture editing mode, the team used the Mesh Fracture tool to separate the destructible mesh into large chunks. This tool effectively uses another mesh to take a "bite" out of the geometry, functioning similarly to a Boolean subtraction tool, but leaving both parts of the mesh in place. The chunks created by this tool act as the primary fractures for the destructible object, providing a degree of control over how they look when they crumble. After creating these chunks, the team applied a more traditional, Voronoi fracture (using the Uniform or Cluster fracture tools) to break it into smaller pieces.







Applying a mesh cut to a column.

Column after applying mesh cut.

Applying a voronoi fracture.

Click images for full size.

Thanks to the Noise settings introduced in UE5, these fractures have natural-looking, non-uniform edges.



The team used the AutoUV tool to UV the internal surfaces of the fractured assets. This tool generates a texture that maps to a gradient based on the depth of the mesh. This provides a way to blend materials together to make different parts of the cross-section have different surface qualities based on depth, providing a more natural appearance. For instance, parts of the mesh deeper inside the cross-section can have a dustier, more dry look, while parts closer to the surface can look darker and more weathered.

Finally, the team cached the physics simulation for the assets using a Chaos Cache Manager. This is a system that can record a simulation in-editor and play it back ingame, ensuring that it proceeds the same way every time once it is triggered. This provides a way to show complex, detailed destruction in-game while conserving on processing, and also makes it possible to author destruction in a way that suits specific in-game needs for level design. For instance, the first column that Echo destroys will never fall in such a way that it will block the entrance, and the Ancient One's mound won't leave behind debris that prevents Echo from traversing the arena. After recording a simulation with a cache manager, placing a copy of it in a level will place all of the other assets associated with it.



The original simulation setups for these assets have been stripped in the final build of the project. However, the geometry collections and cache managers for them are located in AncientBattle Content > Maps > Destruction. You can examine the collections in c_Destruction > 3_Lt_Hand for an example of the assets used for targeted fractures, and you can view the L_AncientBattle_Gameplay level to see all the cache managers used in the dark world.

Improvements to the flexibility of this workflow are ongoing. In the meantime, the implementation in the Valley of the Ancient provides a proof of concept for how we are improving the quality, accessibility, and flexibility of Chaos destruction in UE5.

Setting the Mood With Sky Atmosphere and Volumetric Niagara Effects

To complete the atmosphere in the Valley of the Ancient, we use the new Sky Atmosphere system.



By placing a Sky Atmosphere actor in your scene, you can configure information about a simulated planet, including its ground radius in kilometers, physical parameters for its atmosphere, and art direction overrides. This system works in conjunction with a Directional Light set as the Atmosphere Sun Light, as well as a Sky Light. With all of these elements in place, the Sky Atmosphere system generates realistic atmosphere, volumetric clouds, and fog on a global scale. The environment lighting in this scene is completely dynamic thanks to the Sky Light's real time capture and convolution process.





In the Valley of the Ancient, the light world uses a Sky Atmosphere actor, showcasing a more subtle atmosphere that is reflective of real-world Earth. It also features animated volumetric clouds, which are dynamically lit in real-time. Meanwhile, the dark world uses a more traditional skydome to achieve its more stylized, fantastical look.





Light World Scene

Dark World Scene

Click image for full size.

For the finishing touches, such as the mist and sand blowing across the rocky terrain, the team used Niagara particles in conjunction with volumetric paint data to direct them through the environment.



You can find the actors for these particle systems in the Dark World data layer: BP_NiagaraPainted_FarFog, BP_NiagaraPainted_FogDetail, and BP_NiagaraPainted_SandStripe.



Each of them uses two Niagara Data Interface textures: a VolumetricPaintingDensityMap, and a VolumetricPaintingVelocityMap.



The density map uses RGB information coupled with an alpha channel to determine the height and density of particles relative to the terrain, while the velocity map determines the direction that these particles move in. The team used a custom-built volumetric painting tool to paint these layers in the environment and output these textures. In the image below, the grid overlaid on the environment represents the density map, while the arrows represent the flow map. BP_NiagaraPainted_FogDetail (fog flipbooks) is layered on top of BP_TerrainFogMaster (volumetric fog) with identical 3D density to add details.



With this method, the Valley of the Ancient simulates over 100,000 GPU particles across the dark world's landscape using just three Niagara systems. All the Niagara systems are then fitted to the environment and Volumetric Fog, which uses the same volumetric painting data, to add bespoke detail. While the tools for volumetric painting are still in development, this offers a proof of concept for its performance and utility when combined with the power of Niagara.

Collaboratively Constructing a Large World

In the past, users would divide a level into sub-scenes and use either the level streaming system or the World Composition system to stream them in and out of a persistent level. This requires meticulous organization and makes it difficult for users to collaborate, as typically only one user can modify a scene at a time without encountering version control issues.

In Unreal Engine 5, we have re-invented the way you interact with level files to make this process cleaner and more intuitive. Not only can you edit massive worlds from just one level file, but you can do so in a collaborative environment with dozens of other developers with minimal conflicts. This section will detail the tools that make this possible, and how they benefited the team's collaboration when building the Valley of the Ancient.

One File Per Actor

The entire world in Valley of the Ancient uses UE5's new One File Per Actor (OFPA) system. When enabled, this system writes a separate file for each unique instance of an actor placed within a level rather than writing its data into a single map file.

As a user interacting with the level editor, nothing about your workflow is changed. To edit a level, you still open a single level file in the editor. However, since the underlying file system tracks each actor as a separate file, level designers and environment artists can edit different regions or layers of the same level and rarely, if ever, encounter a conflict when committing their changes to a version control system.

Valley of the Ancient has OFPA enabled globally. You can find this setting under World Settings in the Advanced section of the World parameters, where it is labeled Use External Actors.



At your option, you can enable this for individual actors or globally for an entire project. Refer to the One File Per Actor documentation for more information.

Thanks to this system, the developers on Valley of the Ancient were able to commit their changes rapidly throughout a day of work and quickly see each other's changes in-editor, all without worrying about resolving versioning conflicts. Tweaks to gameplay scripting and environment art could occur alongside each other constantly, enabling a rapid pace of iteration and a highly collaborative environment art pipeline.

World Partition

Large worlds in games depend on dividing a map into many sections that can be loaded and unloaded as the player traverses the landscape, as it is not feasible to load an entire multi-kilometer map all at once. In past toolsets, this required developers to manually divide their maps into sub-levels and carefully manage when they streamed in and out. Viewing sections of the world in context with each other could often be difficult.

The new World Partition system greatly simplifies this process. Once World Partition is enabled for a level, it automatically divides objects into cells based on their grid position and updates the content of those cells as you adjust the world in the level editor, so you never need to manually assign objects to cells. During gameplay, World Partition automatically loads and unloads cells as players traverse through the game world, without the need for manually managing them or designating streaming volumes.

World Partition is enabled in the World Settings for the AncientWorld scene, under World Partition Setup.



You can view the World Partition window by clicking Window > World Partition. Inside, you can click and drag editor cells to select them, and load or unload them for editing purposes. You can also use this window for quick navigation in the editor by moving the camera to a selected cell.



You can check the World Partition settings of individual actors in their Details, under the World Partition section. This can also be edited in class defaults inside the Blueprint editor.



By default, most actors in the environment use their position within the World Partition grid to decide what cell they belong to. Echo is notably set to always be loaded, as she is the player character.

As you can see, the World Partition system greatly streamlines the process of building a large world. While it is still managing many files similar to sub-levels behind the scenes, artists and designers are free to focus on the environment and the user experience they wish to create, while the technical details are automated. For more information about how to configure World Partitions in your games, refer to the World Partition section.

Data Layers

Data Layers are a system for organizing the objects in the world into separate layers that can optionally be loaded and unloaded at-will. This system provides another alternative to sub-levels, designed to work in tandem with World Partition. It can provide another organizational tool for your projects, or it can drive gameplay features and give you an extra degree of control over your world.

You can open the Data Layers window by clicking Window > Data Layers. You can use this menu to create, organize, and load or unload Data Layers in the editor.



You can see the Data Layer information for an actor by scrolling to the Data Layers section of its Details. You can use the dropdowns here to change the actor's data layer, or click and drag a data layer from the Data Layers window into one of these entries.



You can also click and drag actors from the World Outliner onto a Data Layer to assign multiple actors to a Data Layer at once.



Valley of the Ancient uses Data Layers to drive the transition between the light world and the dark world. When Echo activates the portal, it unloads several data layers representing the light world and loads another set representing the dark world.





Light World

Dark World

Click images for full size.

These are activated and deactivated using in-game events, triggered by the Dark World Rift object. Both are built in the same level file, overlapping the same space, making them truly different versions of the same world.

The Campfire Data Layer is used for both worlds, creating a common frame of reference for the player as Echo shifts from one world to the other. There is no need for a redundant version of this set piece, and the only thing that changes its appearance is the atmosphere and lighting used in the light and dark worlds.





During development, this also provided a valuable tool for separating gameplay and set dressing elements, as environment artists could work in their own Data Layers without needing to interact with overlapping triggers or gameplay objects, and designers could focus on objects that were relevant to ingame events.

For more information, refer to the Data Layers page.

Flexible Real-Time Animation

UE5 also introduces several improvements to real-time animation with skeletal meshes, focused on characters and how they interact with the world. The Valley of the Ancient puts these to use in driving the interactions for both Echo as well as the massive Ancient One she confronts at the end of the demo.

Motion Warping

The new Motion Warping system provides a way for animations to adapt their root motion based on warp points in the environment. This makes it possible to use one animation flexibly in a variety of situations, greatly condensing the workload for handling complex environmental interactions.

As an example, in the Valley of the Ancient demo, Echo can vault over debris and obstacles in the dark world.



In previous workflows, making this kind of ingame action would require the team to either adopt highly restrictive conventions about the physical parameters of obstacles, create specific animations for specific obstacles, or break these actions up into component animations with complex rules about how and when to play them.

In this project, however, Echo's vault is handled entirely by the VaultOver_Montage asset.



This asset uses new MotionWarping Notify States to mark segments of the animation where the character's root motion can be warped to fit the environment. Each one responds to a Sync Point placed in the environment. In this case, they are called FrontEdge, BackEdge, and BackFloor, and they correspond to different reference points on a vaultable object. FrontEdge represents the location where Echo's hand touches the object to pull herself up, BackEdge represents the point where she kicks off with a quick hop, and BackFloor represents the point where she lands on the other side of the object.

These points are set inside a GameplayAbility called GA_Vault, which triggers the vaulting behavior based on the VaultingTriggerVolume attached to BP_EchoCharacter. While there are built-in Blueprint nodes for setting individual motion warping sync points, this ability uses a custom node that computes all of the sync points at once based on data about the vaultable actor.



When these three points are provided to Echo's MotionWarping component, the VaultOver_Montage will automatically align her root motion to these points when it plays. This factors in the duration of the MotionWarping notify states, as well as their settings for how the motion warp for those segments should behave.

Thanks to this system, Echo can easily vault over a variety of objects in the environment with just one animation. Regardless of their height or depth, her animation will adjust itself to fit each of the destination points provided in a way that feels natural. This enables developers to gain an immense amount of flexibility out of a small library of animation assets.

For more information about how to implement Motion Warping, refer to the Motion Warping documentation.

Control Rig Improvements

Both Echo and the mighty Ancient One implement Unreal Engine's Control Rig, making it possible to animate both of them inside Unreal Editor. In UE5, we have expanded the tools available with Control Rig to include:

The Pose Library, which keeps a list of reusable poses that you can quickly assign to parts of your model as you build animations.

The Tween Tool, which can generate in-between keyframes and weight them according to information about surrounding keyframes.

The Snapper Tool, which can pin parts of your control rig to objects inside your game world.

These provide many quality-of-life improvements and shortcuts for composing a library of animations. In the Valley of the Ancient sample, the Ancient One's animations were authored entirely in the Unreal Editor using Control Rig and Sequencer by the Aaron Sims Creative team, who designed and built the model.



Both the Ancient One and Echo are set up with control rigs, which you can use to explore these new features. You can find Echo's rig in AncientContent > Characters > Echo > Rig, and the Ancient One's control rig in AncientBattle Content > Characters > AncientOne > Rig.



For a more thorough overview of Control Rig's improvements in UE5, refer to the Control Rig documentation.

Full-Body IK Solver

Both characters also implement the new Full-body IK (FBIK) Solver, which provides an extra layer to how they respond to the environment. FBIK is applied inside each character's Control Rig asset as a node in the Forwards Solve graph. This solver applies corrections to a model on a post-process layer after all the standard animations for the mesh are processed.



As an example of this in action, when the Ancient performs its energy beam attack, the placement of its arm is controlled by Blueprint logic as it tracks Echo's position, and the full-body IK solver handles the corrections for the rest of its body as it fires the beam.



As a more subtle example, Echo uses FBIK to adapt to the varying terrain within the game world, adjusting her feet to the angle of the ground and changing the position of her hips when moving on uneven surfaces. This creates more varied and natural movement, especially as she navigates up and down slopes or over obstacles.



For more information about how to implement Full-Body IK, refer to the Full-Body IK documentation.

Building Modular Gameplay

UE5 also provides a framework for modularly building gameplay, and the Valley of the Ancient leverages these systems during the transition to the dark world. Not only does Echo's environment change, but new sets of input bindings and mechanics are introduced at runtime.

Extending Gameplay With Game Feature Plugins



In the light world, Echo uses a remote-controlled mote of light to get a bird's eye view of her surroundings. In the dark world, she can throw a light dart to destroy obstacles and damage enemies. Each of these systems is a discrete Game Feature Plugin. Inspired by the Fortnite pipeline, this system makes it possible to develop features independently from one another and integrate them into the main game at-will. You can even load and unload them at runtime.

To create a new Game Feature, open the Plugins window and click Create Plugin. You can select a Game Feature for your base plugin type.



The plugin can then be found inside your project's Plugins directory.

When using standard plugins, the game can refer to classes and assets from those plugins, but the plugins do not have visibility into the base game's code or assets. With Game Features, that dependency flow is reversed. They depend on the base game, but the base game can not reference classes or functions from a game feature. This makes their implementation similar to mods, extending or modifying elements from the base game.

In Valley of the Ancient, the Light Dart and the Ancient One are both contained in the AncientBattle game feature. The basic systems that Echo needs to gain and use special abilities are already built into her base Actor, but the Light Dart provides a specific implementation of it. The Ancient One and other actors capable of responding to damage are also contained in this Game Feature, making the combat system fully encapsulated within this module. This feature's content is located in the AncientBattle Content folder.

To view this game feature's content in the Content Drawer, click the Settings button, then check Show Plugin Content and locate the AncientBattle Content folder.



All assets related to the Light Dart, including animations, visual effects, UI elements, and Blueprints are located inside this folder. At the top level of this folder there is a AncientBattle Game Feature Data asset.



This asset contains instructions on how the plugin should behave when it is loaded and unloaded. The Light Dart plugin specifically has instructions to add the LightDart Gameplay Ability to Echo, set her up with input that will activate the ability, and attach needed components to her.

During gameplay, these features are toggled inside the BP_DarkWorldRift Blueprint when triggering the transition to the dark world.



No additional references to the LightDart are necessary in the game's main codebase or assets. Once it is added to Echo, all of its components are ready to use thanks to the instructions in its Game Feature Data.

This system enables developers to easily control what sets of features are active at a given time. It is especially useful when dealing with mechanics that work within a limited timeframe or scope. Here we use it to toggle Echo's Light Dart when she transitions between worlds, but it is just as easily adaptable to limited events in online games, brief cinematic segments, or major mode changes during gameplay.

For more information about Game Feature plugins and how to implement them in your projects, refer to the Game Feature Plugins documentation.

Flexible Controls With the Enhanced Input System

UE5 features a new Enhanced Input System, which is used in Valley of the Ancient for Echo's controls. This system not only handles Echo's movement and abilities, but also provides methods for handling the context-sensitive elements of those inputs, including situational data for specific controls and adding or removing inputs based on player states.

Whereas the input system in UE4 processed raw inputs with events in an Actor's event graph, Enhanced Input models controls as Input Actions, which are represented by assets in the Content Drawer. Most of the Input Actions for Valley of the Ancient are located in Content > AncientGameContent > Input. The Input Actions specific to the dark world are contained in AncientBattle_Content > Input, and the Input Actions specific to the hover drone are contained in HoverDrone_Content > Input.



These include not only common controls, like IA_MoveForward and IA_MoveRight, but also highly situational ones, like IA_SitStand, which is used when Echo stands up from the campfire. You can open Input Actions to configure what type of value they return, including different types of axis values. You can also provide a list of Triggers, which add contextual requirements to activate the input, or Modifiers, which process the value of the input before passing it to gameplay.



Triggers and Modifiers make it possible to handle dead zones, responsiveness curves, or contextual actions that are required to activate the input, all without manually filtering input data in gameplay code for your Actors. You can add more Triggers or Modifiers to your projects by defining them as either Blueprint or C++ classes.

Once an InputAction is defined in your Content Drawer, you can access it using an event in Blueprint. The InputActions for controlling Echo are handled in BP_EchoCharacter.



While these events function similarly to standard Input events, they provide more contextual information about the Input Action, including when an action starts, finishes, is in-progress, or gets forcibly canceled, as well as the time that the action is active. The value of the input event is defined by the Value Type listed in the InputAction asset. Any Modifiers listed for the InputAction will be applied before this value is output.

Input Mapping Contexts handle mapping InputActions to physical controls. You can find these assets alongside the InputActions. IM_ThirdPerson_Controls_InputMapping contains the majority of Echo's controls, while IM_LightDartInputMappings contains the added controls for the Light Dart ability and jogging.



These are organized similarly to the action and axis mappings in the input system from UE4, but in addition to mapping InputActions to physical inputs, they also can apply Modifiers and Triggers to specific control implementations. For instance, Echo reads IA_MoveForward to determine forwards and backwards movement. While the W key has no Modifiers added to it, the S key uses a Negate modifier, which will cause it to read as negative input.

One of the advantages of Input Mapping Contexts is that they can be added and removed for individual players at runtime. For example, the AncientBattle Game Feature plugin adds IM_LightDartInputMappings when it is loaded.



This Game Feature action was created specifically for this project in C++. You can see another example of input mappings being added and removed at runtime in the HoverDroneControlsComponent, a C++ class in the HoverDrone Gameplay Feature that extends the EnhancedInputComponent.

This example illustrates how the Enhanced Input system provides a highly extensible and flexible framework for managing a game's inputs. You can easily expand upon and adapt a game's inputs over the course of development without destructive changes to gameplay code, and this system has many tools for contextual or special case inputs. For more information, refer to the Enhanced Input System documentation.

Dynamic Interactive Audio

In addition to all of the tools that give you freedom in building visuals, game mechanics, and worlds, Unreal Engine 5 also provides more control over your game's audio with an all-new audio system. This section will show you how Valley of the Ancient uses these new tools to provide an extra sense of polish and dynamism for Echo's final encounter with the Ancient One.

MetaSounds

MetaSounds is the new high-performance audio system for Unreal Engine 5, providing a fully featured Dynamic Signal Processing (DSP) graph for audio designers. This system can synthesize procedural sound effects and music from the ground up, and features a Blueprint API that provides a way for designers to manipulate sounds based on gameplay events and in-game data. This provides sound designers with robust flexibility during development, supporting fast iteration, complex and dynamic sounds, and the ability to effortlessly adapt sound effects to game design changes.

For an example of the power and versatility of MetaSounds, you can find sfx_Golem_RobotBlast_Meta in the AncientBattle Content folder under Audio > MetaSounds.



This MetaSound uses a mixture of procedurally generated audio and .wav samples to create the sound effect for charging the Ancient One's beam. The first sections handle the bulk of synthesizing and modulating the main charge-up sound, which is completely procedural.



The Intro Wave and Shot Waves sections add an extra layer of texture to the sound with some supplemental .wav files. The Intro Wave section triggers when the beam initially starts to charge up. The Shot Waves section also has a sound that triggers when the beam begins charging, but also has components that trigger after the charge-up sound has fully played.



The middle sections of the graph handle mixing and filtering between each of these different sections into a final Stereo Mix, then feed into the Output node to play the final sound.



Triggers, parameters, and .wav files act as inputs, then the MetaSounds flow graph processes that information based on DSP nodes and mixes it into a final sound output. This system provides audio designers with a workflow for sound that is as powerful and flexible as the Material editor, capable of adapting to both typical sound parameters as well as in-game data, making it possible for them to work more closely and efficiently with a game development team within one sound design environment.

For example, during development of the battle sequence, a lot of iteration time was spent fine-tuning the amount of time the Ancient One spends charging up its beam. In other sound design workflows, this might entail re-authoring the sound based on changes to gameplay. Instead, the sfx_Golem_RobotBlast_meta MetaSound uses a Time input called ChargeDuration to determine how long the sound should play. Since the main charging sound is entirely procedural, it automatically adjusts its length based on the given input.

To see this in action, select ChargeDuration from the Inputs list, change it from its default value of 4.0 seconds, then try playing the sound.



Thanks to this functionality, the game design team could change the Ancient One's charge duration as often as necessary without the need to re-author this sound.

There are many other Input parameters available to work with, including Triggers that you can activate from gameplay code using the Audio Parameter Interface. You can use these to create MetaSounds that procedurally handle starts, stops, and intermediate events. For instance, where an action like a gun firing would previously require multiple sounds for starting, stopping, and looping fire, this system can condense it all into just one MetaSound.



You can also manipulate other audio parameters using this API. This makes it possible for MetaSounds to fully encapsulate the sound playback logic for complex sound effects, all with sample-accurate timing.

MetaSounds' capacity for flexible design and infinite variation is complemented by significant performance improvements. The MetaSounds graph is rendered asynchronously, similarly to how individual sound effects are normally decoded, which provides an extra degree of flexibility in handling CPU resources. More importantly, since MetaSounds is a true audio rendering system, each MetaSound represents a single in-game voice, regardless of its complexity. This means that the playback you hear in the MetaSounds editor will always be accurate to its in-game sound, and in-game voice management is more predictable compared with earlier systems. This also condenses the workflow for evaluating audio performance, as in the future UE5 will be able to profile the performance of specific MetaSounds individually.

For more in-depth information on MetaSounds, refer to the MetaSounds documentation.

Quartz Audio Synchronization

Normally, discrepancies between the way the gameplay and audio threads are processed makes it difficult to synchronize events between them with accurate timing. Quartz provides a clock for scheduling sample-accurate audio playback from gameplay events. When you schedule a sound using Quartz, you can set up delegates based on specific timing relative to scheduled playback. The Quartz Clock will provide event delegates for that sound's playback so that gameplay can anticipate the intended timing and synchronize other gameplay events when appropriate. This makes it possible to create sample accurate dynamic music systems, as well as game systems with a high level of synchronicity with audio.

Valley of the Ancient uses Quartz in its dynamic music system, called the Underscore Subsystem, which schedules events based on musical beats and bars. Notably, the Ancient One chooses when to fire its laser based on the timing of the music cue during its showdown with Echo. Classes for this system are contained in Underscore C++ Classes.



Music for this system is contained in a special data asset called an UnderscoreCue, which contains the data for the music cue's time signature, different musical sections, transitions, and other information relating to musical states and events. The battle music for the Ancient One's battle is contained in the Arena_Battle_Cue asset, which is located in AncientContent > Audio > UnderscoreCues.



This contains the references to the clips that make up this music cue, as well as the music's BPM and Time Signature. This data is a description of the music, used by the music system to set up the Quartz Clock and manage timing transitions between each section. The introduction is set up to transition into the main body of the battle music, which is broken up into several different states. These states occur based on many different in-game events, and the music concludes with a beat-synchronous ending. Thanks to Quartz, all of this occurs with seamless, sample-accurate precision.

To see an example of how these sections relate to in-game events, you can find hooks for this system throughout BP_Laser and BP_AncientOne, which are in the AncientBattle Content directory. In addition to the logic for the laser itself, BP_Laser contains calls to bind events to the Underscore Subsystem, enabling the music to trigger the laser.



It also contains calls to the Underscore Subsystem to tell the music when to transition to other sections of the song, including when the beam finishes firing and when the Ancient One is defeated.



These are just a few examples of how the Underscore subsystem uses Quartz to facilitate dynamic music systems and precise interactions between gameplay and audio.

Final Notes



As you can see, Unreal Engine 5 features a range of incredible tools that make ambitious, high-fidelity projects more accessible to build than ever before. The Valley of the Ancient brings all of these tools together to provide both a sample of the production values you can achieve, as well as a case study in how the very same tools also streamline the development process for games. With UE5, developers will achieve better-quality visuals with fewer steps, larger worlds with less busywork, and more detailed interactions and environments with tools that empower creators.

Live Link

Professional Video I/O

Quixel Bridge Plugin for Unreal Engine

Quixel Bridge

Content Guides

Plugins for Third-Party Applications

Epic Games distributes free content on the Marketplace tab of the Epic Games Launcher. This content includes plugins and content packs for a variety of industries and use cases, including the professional quality characters and environment art originally made for Epic's Paragon and Infinity Blade games.

You can find all the free content by going to the Marketplace tab and choosing Free > Epic Games Content:



Click image for full size.

Quixel Bridge

Quixel Bridge is a plugin for Unreal Engine that has a free asset library of thousands of photo-realistic assets. Use Quixel Bridge to bring in Megascans and MetaHumans. To find out more, visit the Quixel Bridge page.



Quixel Bridge lets you access the Megascans library to bring environments, materials, and MetaHumans into Unreal Engine.

Content Guides

Follow the links below for companion documentation for some of the free content packs from Epic that you can find on the Marketplace.



A breakdown of what assets the Automotive Materials pack contains and how to use them



A breakdown of the Materials availabe in the Twinmotion Materials Pack.

Plugins for Third-Party Applications

You'll also find plugins in the free content from Epic Games that link the Unreal Editor and Engine with third-party applications and hardware. These include:

Live Link plugins for Autodesk Maya and Motionbuilder connect them to Unreal Editor through a live connection, bringing animation data directly into your Level.

Professional Video I/O plugins for AJA Media Systems and Blackmagic Design exchange video feeds with SDI interfaces.



Describes how to enable and use the Live Link Plugin and features within the animation system in Unreal Engine.



Contains information about getting professional quality video into and out of the Unreal Engine.

Overview

Get Bridge for Unreal Engine

Launching Bridge in Unreal Engine

Updating Bridge

Sign up or Log in to Bridge for Unreal Engine

What is the Unreal Unlimited plan?

Using Bridge for Unreal Engine

System requirements

Navigation

Home

Collections

MetaHumans

Favorites

Local

Search & Filter

Asset Information

Download Settings

Preferences

Format & Resolution

Nanite

Export Settings

Adding Assets to Your Project

Drag & Drop

Download and Add to Scene

Download to Project

Add to Scene

Updating to the latest version

Overview

Quixel Bridge plugin for Unreal Engine gives you full featured access to the Megascans library within the Level Editor. You can browse collections, search for specific assets, and add assets to your Unreal Engine projects.

Get Bridge for Unreal Engine

Bridge for Unreal Engine is a plugin included with your installation of Unreal Engine 5. To ensure that your Quixel Bridge plugin is enabled, select Edit > Plugins. Type bridge into the search bar and click the checkbox to enable the plugin.



Click image for full size.

If you don't see the Quixel Bridge plugin here, then you may need to install it from the Epic Games Launcher. Open the Epic Games Launcher, click Library, then scroll down to the section called Vault. Type Bridge into the search bar. Select Install to Engine. When you relaunch the engine, you should be able to enable the plugin as described above.



Click image for full size.

Launching Bridge in Unreal Engine

Quixel Bridge can be accessed from a number places inside the editor:

Click the Content dropdown in the toolbar and select Quixel Bridge.



Click image for full size.

From the top menu, select Window > Quixel Bridge.



Click image for full size.

From the Content Drawer, right-click and select Add Quixel Content.



Click image for full size.

If you can't find Quixel Bridge as directed above, select Edit > Plugins. Type Bridge in the search bar, and click the checkbox to enable the plugin.

You may be prompted to restart Unreal Engine for the changes to take effect.



Click image for full size.

Updating Bridge

When you launch Unreal Engine, and open the Bridge tab, you may see a message indicating that Bridge is out of date.



Click image for full size.

To update Bridge, close Unreal Engine and return to the Epic Games Launcher. In the Unreal Engine > Library tab, locate the version of Unreal Engine that you have installed. Underneath it, you will see Installed Plugins. If a new version of an installed plugin is available, you will see an exclamation mark.



Click Installed Plugins. From the pop-up window, next to Quixel Bridge click Update.



You can now relaunch Unreal Engine.

Sign up or Log in to Bridge for Unreal Engine

Bridge for Unreal Engine works with your Epic Games account and currently supports the Unreal Unlimited plan.

To log in, click the user icon in the top right corner of the Quixel Bridge panel and select Sign In.



Click image for full size.

You can log in using your existing Epic Games account, or sign up for a new account. To get free, unlimited access to the Megascans library, make sure you're on the Unreal Unlimited plan.

What is the Unreal Unlimited plan?

Megascans is completely free for all users of Unreal Engine. If you have an Unreal Engine license, sign in with your Epic Games account and go to quixel.com/pricing to get unlimited access to the Megascans library. You will also have unlimited downloads within Bridge and Mixer.

This unlimited Megascans access is licensed for use with Unreal Engine and Twinmotion only and treats Megascans assets as UE-Only Content under the Unreal Engine End User License Agreement.

You can find more details on the Quixel Bridge FAQ page.

Using Bridge for Unreal Engine

System requirements

Quixel Bridge for Unreal Engine runs on Windows, MacOS, and Linux.

Bridge requires an active internet connection to display and download the content library. When you do not have an internet connection available, you can access local content that is on disk by navigating to the Local tab in the left navigation pane.

Navigation

On the left of the Quixel Bridge panel, there are buttons to navigate to the different tabs:

Home

Collections

MetaHumans

Favorites

Local

The Home tab is split into sections displaying the latest collections, trending assets, and the newest uploads across every category.



Click image for full size.

The left navigation is structured as a category tree with different levels of subcategories.



Click image for full size.

All the available asset types are listed in the Home tab. You can filter by category and subcategories.

Atlases, Displacements, and Brushes are not supported in Bridge for Unreal Engine.

The Collections section contains curated content with references and renders across different biomes as well as essentials, architectural selections, tutorial assets and community collections.



Click image for full size.

If you're using the MetaHuman Creator app to create characters, you can access them in Quixel Bridge for Unreal from the My Metahumans tab in the left navigation panel.



Click image for full size.

Any asset in Quixel Bridge can be marked as a Favorite for quick access in the future.



Click image for full size.

To mark an asset as a favorite, hover over the asset and click the heart icon.

The Local section shows all the assets that you have already downloaded and are available on your machine.



Click image for full size.

Search & Filter

The Megascans content library contains thousands of assets and is continuously growing.

To search for an asset or a collection, click in the search bar. As you begin typing, suggested results will appear below the search bar.



Click image for full size.

If one of the suggested results is the item you need, select it to be taken to that asset. To see all the results for your search query, press Enter/Return. The search results will list all of the matching content, including suggestions of popular assets, related collections, and matching asset categories.

Additionally, you can use the filter bar to refine any search result with specific filters such as: asset type, color, biome, state, size, and more. To hide or show the filter bar, click the Filter icon in top right.



Click image for full size.

Asset Information

To view more information for an asset, select the asset to open its information panel.



Click image for full size.

Icons display information about the asset, for example asset size or whether a surface is tileable or not. You also see related assets that are similar to the current asset.

At the bottom of the asset right panel, choose the download resolution before downloading or adding an asset to your project.

Click the Export Settings button to adjust how to import the assets into your scene.

Download Settings

Preferences

By default, all the assets you download from Bridge for Unreal Engine are placed at the following location on disk:

Win: C:\Users\user\Documents\Megascans Library

Mac: ~\Documents\Megascans Library

Linux: ~\Documents\Megascans Library

To change this path, click the user icon in the top right corner of the Bridge window and select Preferences.



Click image for full size.

In the Preferences dialog enter the Library Path that you want to save your assets to and click Save.



Click image for full size.

Format & Resolution

Download Settings of assets are available in the asset's information panel.

All 3D assets in Bridge for Unreal Engine are downloaded in UAsset format and are available in the following resolutions:

Nanite

High

Medium

Low

All other asset types, such as Surfaces, 3D plants, Decals and Imperfections are available in the following resolutions:

Highest

High

Medium

Low

Nanite

Bridge for Unreal Engine 5 now serves in a fully Nanite-ready tier for 3D assets. These assets are downloaded as pre-converted Nanite meshes which are loaded into the project upon import.

The assets work right out of the box and do not require any project settings to be configured beforehand.

Export Settings

Export Settings of assets are available in the asset's information panel. Click the Export Settings button to open them.



Click image for full size.

The Export Settings dialog allows you to specify parameters to control how the assets will be exported or added into your project. They must be configured before adding an asset into the scene.



Click image for full size.

Auto-Populate Foliage Painter: enabling this will automatically populate foliage editor's asset list in the project with the latest imported assets. This setting must be checked before exporting assets and is only applicable to scatter and plant assets.

Apply to Selection: enabling this will apply the exported material to the selected objects in the scene.

Master Material Overrides: This section lets you choose your own custom master materials instead of the default master materials provided by the plugin.

Material Blend Settings: This section allows you to blend materials using already imported materials in the content browser. The plugin comes with a Vertex Blend Shader which is used for material blending.

Adding Assets to Your Project

There are a couple of ways to download and add assets to your UE project.

Drag and Drop.

Download and Add to Scene.

These two methods are described further in the following sections.

Drag & Drop

You can drag and drop a single asset or multiple assets together into your scene.

To add an asset to your scene, select the asset in the Bridge panel. Drag it into the viewport.



Click image for full size.

If the asset has not previously been downloaded, this will automatically initiate download. It will download the resolution specified in the asset's information panel.

While the asset is downloading, a preview of the asset will appear in your scene. This preview is a placeholder until the full asset finishes downloading.

If this is the first time you are downloading something in Bridge for Unreal Engine, the following new folders are created in your Content browser.

Megascans: this is where the assets are saved inside your UE project.

MSPresets: this contains all the template master materials that are used to render the downloaded assets in your scene.

Once the final asset has been downloaded, it will replace the preview in the scene.

All surfaces, imperfections, and decals appear on a spherical mesh when dragged and dropped into the viewport.

Download and Add to Scene

You can also download then add assets to your scene in two separate steps.

One way to download an asset is to hover over the asset in the grid, then click the green Quick Download button.



Click image for full size.

Alternatively, select the asset to open the Asset Information panel and click Download. You can choose at which resolution to download the asset.



Click image for full size.

Once downloaded, all assets are accessible from the Local tab.



Click image for full size.

To navigate to the asset's location on disk, right-click the downloaded asset and select Go to Files.



Click image for full size.

Inside the Editor, the downloaded assets appear in the Content > Megascans folder in the Content Drawer.



Click image for full size.

After downloading, there are two ways to add to scene. The first way is to hover over the downloaded asset. Click the blue Quick Add button.



Click image for full size.

Alternatively, select the asset to open the asset information panel. Then, click the Add button at the bottom of the panel. You can choose at which resolution to export the asset.



Click image for full size.

Make sure you have set up your Export Settings before adding assets to your scene. This will ensure that the assets are downloaded and added at the proper resolution for your project.

Updating to the latest version

New version updates are available often for Quixel Bridge. These include feature improvements and bug fixes.

To check what version you're using or if an update is available, click the User button, then About Bridge.



Click image for full size.

A dialog displays information about the current version, and whether an update is available.



Click image for full size.

If you've installed Unreal Engine using the Epic Games Launcher, you can also make sure you have the latest version installed there. From the Library tab, locate the installed engine version you are using. Under it, click Installed Plugins to see a list of all plugins you have installed to that engine version. If an update is available, click Update to install it.

Live changes to source code are available through GitHub. You can access C++ source code via GitHub.

Physically Based Materials

Material Properties

Cubemaps

Overview

Common Exposed Parameters

Master Materials

The Automotive Materials Pack, available on the Unreal Engine Marketplace, is a collection of automotive-themed physically based Materials ready for use in Unreal Engine (UE). The pack is designed to be an out-of-the-box solution for professional rendering of automotive finishes, featuring:

164 Materials Instances, driven by 10 Master Materials. All materials utilize PBR best practices.

High-quality 4K Textures, using the Quixel Megascans library of hand scanned 2D and 3D assets.

Support for both Object UVs and Triplanar mapping to work even when models have imperfect UV mapping.

Full support for all lighting methods, including ray tracing.

Overview

The Automotive Materials Pack is a state-of-the-art collection of Master Materials and example content created to provide 3D visualization professionals with a high-quality solution for creating exceptional automotive Materials.These Materials follow Physically-based Rendering (PBR) best practices and are designed for ease of use. 4K textures from the Quixel Megascans library are used to achieve stunning visual fidelity. Additionally, all materials are set up to use Triplanar Mapping to minimize texture stretching and seams. Finally, every Material is optimized for a variety of lighting solutions and is ray tracing ready.



The vehicles meshes used in the examples below are not included in the Automotive Materials Pack.

Master Materials and Material Instances

In Unreal Engine (UE), an instance of a Material can be used to change the look and properties of that Material without requiring an expensive recompile. These Material Instances are created from a Master Material, which contains several properties that have been designated as parameters. The Material Instance can see these parameters and you can use them to create multiple variations of a Master Material quickly.

Creating and using Master Materials in UE4 is an advanced workflow. For more information on Materials and their use, read the following documentation:

Material Inputs

Material Tutorials

Instanced Materials

Inside of the Automotive Material Pack you will find the following Materials types:

Additive

Brake Rotor

Car Paint

Decal

Emissive

Glass

Masked

Opaque

Textile

Tint

Physically Based Rendering

All Master Materials in the Automotive Material Pack have been designed from scratch to achieve the most realistic and accurate results possible with Unreal's physically based rendering system. This means, for example:

In the real world, almost all surfaces behave either as a metal or as a non-metal (dielectric). Similarly, all Materials in the pack are either fully metallic or fully non-metallic. This is determined by a node in the Master Material, exposed to Material Instances as a single IsMetallic checkbox. This ensures that all surfaces reflect a physically accurate proportion of specular and diffuse light.

The Specular input is not used in any Materials. This avoids introducing any reflections that do not accurately match the behavior of light in the real world. The Specular value is typically left at the default value of 0.5.

The Roughness map controls the glossiness of the surface. Smoother surfaces, where the roughness map is closer to black, have sharper, more focused reflections. Rougher surfaces, where the roughness map is closer to white, have blurrier, less distinct reflections.

For a more in-depth explanation of what physically based rendering is and how to use it in UE4, see the Physically-Based Materials.

Triplanar Mapping

The pack includes a Material Function that performs efficient triplanar mapping. Triplanar mapping is a way of applying texture maps to an object that does not use UV mappings to map the object's 3D surfaces to 2D texture space. Instead, triplanar mapping applies the texture map to three orthogonal planes, then projects these three planes to the surface of the object.

This is the default behavior for all Materials in the pack. This means that you can use all Materials successfully on objects that do not have UVs, as is often the case for parts that come from CAD applications.

This triplanar mapping function has several useful features:

Uses local space positions to avoid textures appearing to slide across the surfaces of the objects.

Materials keep the same texel ratio when objects are scaled.

The image below illustrates how triplanar mapping uses planar maps projected along the X (red), Y (green), and Z (blue) axis to create a complete procedural UV projection with minimal seams or stretching:



However, because the calculations use local space positions, the triplanar UVs are dependent on the original geometry and rotation of the object's geometry relative to its pivot. For best results applying textures, author your objects so that flat surfaces lie close to the XY, XZ, and YZ planes of the objects' local space. If your Static Meshes do have UVs, and you want to use these UVs for texture mapping, enable the Use Object UVs option on your Material Instance.

Ray Tracing Support

All Master Materials are set up to optimize performance for ray tracing by using the RayTracingQualitySwitchReplace node to execute a different branch of the Material graph on the second bounce.



For the second bounce, all surface normals are considered flat, and the surface roughness is considered either fully rough or fully reflective.

Common Exposed Parameters

Parameter Category

Settings

Base Color

Contains options for Color (RGBA), Color Maps, and Tinting options.

Metalness

Contains options for Metallic settings. Turning on IsMetallic applies a uniform texture to control the Metallic attribute of the material. Different Metallic Maps can be applied to differentiate between metallic and non-metallic surfaces on the same object.

Roughness

Contains settings for adjusting the Roughness of your Material. A Roughness Map can be applied to create specific wear patterns. The amount of Roughness can be randomized using Min and Max values. Roughness can be used to determine the glossiness of the Material.

Normal

Applies the chosen Normal Map to the material. Normal Intensity uses a value to control the effect.

Imperfections

Allows for the adding of Stains, Fingerprints, and Dust to a Material. A mask texture can be used to apply specific patterns.

UVs

Allows for the use of an object's own UV map. Triplanar Mapping is enabled by default.

If you are unsure what a particular parameter is or how it is used, hovering your mouse over it will display additional information.



Master Materials

Inside the Masters folder, you will find several types of Master Materials.

Additive

Useful for creating LCD screens, clocks, HUDs, and other forms of display, the Additive Material features an Intensity setting that makes the display brighter when the camera is facing it and less intense when viewed from the side.

Parameter Category

Settings

Base Color

Controls what is displayed on the screen. Facing Intensity affects the brightness when viewing near the center. Edge Intensity affects the brightness when viewing closer to the edges.

In the example below, the Base Color texture map has been changed to represent a GPS unit:



Brake Rotor

Created to use radial UV mapping, the Brake Rotor Material contains settings for Imperfections such as cracks and stains, as well as the ability to use a Metallic map to add rust. Perfect for creating any Material that requires a radial finish.

Parameter Category

Settings

Base Color

Applies a Color Map or color tint to the Material.

Metalness

Controls whether the Material is meant to be metallic.

Roughness

Used to apply wear patterns. Also determines the glossiness of the Material.

Cracks

Applies crack patterns to the Material. Can control both scale and intensity.

Imperfections

Supports stain imperfections.

Below, you can see a brake rotor that uses the Material. Metal wear lines have been added, along with stains:



Car Paint

Designed for car exteriors and brake calipers, the Car Paint Material features support for Flakes, Orange Peel, Chameleon effects, Clear Coat, and Imperfections.

Parameter Category

Settings

Basic

Applies a Color Map or color tint to the Material. Contains the setting for the Chameleon effect, which allows for a second color to be chosen. The first color will fade into the second color based on viewing angle.

Clear Coat

Applies a clear coat to the Material that affects glossiness. The intensity of this effect can be adjusted.

Flakes

Applies a flake effect to the paint's undercoat.

Imperfections

Supports fingerprint and dust imperfections. Can control both scale and intensity.

Orange Peel

Applies the dimple effect that is often seen in car paint.

The Chameleon effect blends the primary paint color with a secondary color based on the viewing angle:





You can see an example of the Clear Coat feature below:





The Flake parameter simulates metal flakes suspended in the paint undercoat and is used to achieve a variety of different finishes:





The Orange Peel parameter represents the imperfections that can happen during the automitve paint process:





Decal

The Decal Material is projected onto a surface and will adjust to follow its contours, manking it perfect for adding logos, stripes, and other decals to the vehicle.

Parameter Category

Settings

Base Color

Color Map controls the decal that is displayed. Tint options control the final color of the decal.

Below you can see the Unreal Engine logo applied as a decal to the hood of the car:



Emissive

Useful for headlights, tail lights, and LED lights, the Emissive Material features color tint and intensity settings that vary depending on the viewing angle.

Parameter Category

Settings

Light

Color Tint determines the final color of the Material. Facing Intensity affects the brightness when viewing near the center. Edge Intensity affects the brightness when viewing closer to the edges.

Here you can see the Emissive Material applied to the brake light:



Glass

The Glass Material can be used to create windows, transparent light covers, and windshields. Windshields require a bit of setup and are made of 2 meshes: one interior and one exterior:

[

Number

Description

1

Interior Static Mesh using interior glass Material. Translucency Sort Priority property is set to 0.

2

Exterior Static Mesh using exterior glass Material. Translucency Sort Priority property is set to 1.

The interior mesh uses the interior windshield Material and hasTranslucency Sort Priority set to 0. While the exterior mesh uses the exterior windshield Material and has Translucency Sort Priority set to 1.

You can see the technique used below. The exterior windshield mesh is reflecting the environment.



Parameter Category

Settings

Glass

Contains options for glass color, roughness, and darkening towards the edges.

Transparency

Contains options to apply a sun cover around the edge of the windshield.

Imperfections

Supports dust, fingerprints or stain imperfections.

Masked

The Masked Material is used to create perforation or grill patterns for plastics and metals. This is great for components such as speaker covers, and supports clear coat and imperfections in the form of dust and fingerprints.

Parameter Category

Settings

Base Color

Applies a Color Map or color tint to the Material. The color map contains your masked texture.

Metalness

Controls whether the Material is meant to be metallic.

Roughness

Applies roughness. Can be used to control the glossiness of the Material.

Clear Coat

Applies a shiny clear coat.

Imperfections

Supports dust and fingerprint imperfections.



Opaque

A flexible Master Material, the Opaque Material is used to make anything that is opaque or has a coating such as metal, carbon fiber, leather, plastic, wood, rubber, or reflectors. It features clear coat and imperfection options, along with a range of color and roughness options.

Parameter Category

Settings

Base Color

Applies a Color Map or color tint to the Material.

Metalness

Controls whether the Material is meant to be metallic.

Roughness

Applies roughness. Can be used to control the glossiness of the Material.

Clear Coat

Applies a shiny clear coat.

Imperfections

Supports dust and fingerprint imperfections.

Below is an example of the flexibility of this Master Material. The leather of the seats, nylon straps of the seatbelts, and plastic of the interior paneling are all created using the Opaque Master Material:



Textile

Designed to create carpet, headliners, suede, perforated leather or anything with textile properties, the Textile Material features perforation, softness, and imperfection settings.

Parameter Category

Settings

Base Color

Applies a Color Map or color tint to the Material.

Roughness

Applies roughness. Can be used to control the glossiness of the Material.

Softness

Applies a softness effect to the Material in the form of core darkness, brightness at the edges, and subsurface color.

Wear

Applies a wear pattern to the Material.

Perforation

Applies a mask that simulates perforation. A color tint can be added to the holes. Depth and size can also be controlled.

In the example below, we can see the Textile Master Material used to create a brown suede:



Tint

Used in the setup of taillights, the Tint Material is used to modulate and tint the vehicle lights. Similar to the windshield, taillights can be setup using 3 meshes:



Number

Description

1

Glass Material

2

Tint Material

3

Emissive Material

Parameter Category

Settings

Base Color

Controls the tint color. Can have an additional edge tint that blends to when the viewing angle changes.

Physically Based Materials

Shading Models

Cubemaps

Overview

Master Materials

Physically Based Rendering

Triplanar Mapping

Parallax Occlusion Mapping

Raytracing Support

Commonly Exposed Parameters

Master Materials

Decals

Glass

Light Source

Masked

Opaque

Opaque POM

Textile

Wood

Window

The Twinmotion Materials pack, available on the Unreal Engine Marketplace, is a collection of architectural visualization-themed physically based Materials ready for use in Unreal Engine (UE). Based on the Twinmotion asset library, this assortment of materials features:

497 Materials Instances, driven by 10 Master Materials. All materials utilize PBR best practices.

Based on the popular Twinmotion asset library and utilizing the Quixel Megascans library of hand-scanned 2D assets.

Support for both Object UVs and triplanar mapping even when models have imperfect UV mapping.

Utilizes the latest parallax occlusion mapping (POM) techniques to procedurally generate materials such as brick, concrete blocks, ceiling tiles, and cobblestone.

Full support for all lighting methods, including ray tracing.

Overview

The Twinmotion Materials pack provides 3D visualization professionals with a state-of-the-art collection of Master Materials and example content for creating remarkable indoor and outdoor spaces. Every Material follows physically based-rendering best practices, and all are designed for ease of use. Parallax occlusion mapping is used to procedurally generate brick and tile materials. Finally, every Material is optimized for a variety of lighting solutions and is ray-tracing ready.

Master Materials

In UE, an instance of a Material can be used to change the look and properties of that Material without requiring an expensive recompile. These Material Instances are created from a Master Material, which contains several properties that have been designated as parameters. The Material Instance exposes these parameters and gives you a way to create multiple variations of a Master Material quickly.

Creating and using Master Materials in UE4 is an advanced workflow. For more information on Materials and their use, read the following documentation:

Material Inputs

Making Tutorials

Instanced Materials

Inside of the Twinmotion Material pack you will find the following Materials types:

Decals

Glass

Light Source / Black Body

Masked

Opaque

Opaque POM

Textile

Wood

Window

Physically Based Rendering

All Master Materials in the Twinmotion Material Pack are original materials built to achieve the most realistic and accurate results possible with Unreal's Physically-based Rendering system. This means, for example:

In the real world, almost all surfaces behave either as a metal or as a non-metal (dielectric). Similarly, all Materials in the pack are either fully metallic or fully non-metallic. This is determined by a node in the Master Material, exposed to Material Instances as a single IsMetallic checkbox. This ensures that all surfaces reflect a physically accurate proportion of specular and diffuse light.

The Specular input is not exposed in any Materials to avoid introducing any reflections that do not accurately match the behavior of light in the real world. The Specular value is typically left at the default value of 0.5.

The Roughness map controls the glossiness of the surface. Smoother surfaces, where the roughness map is closer to black, have sharper, more focused reflections. Rougher surfaces, where the roughness map is closer to white, have blurrier, less distinct reflections.

For a more in-depth explanation of what physically based rendering is and how to use it in UE4, see the Physically-based Materials documentation.

Triplanar Mapping

The pack includes a material function that performs efficient triplanar mapping. Triplanar mapping is a way of applying texture maps to an Object that does not use UV mappings to map the Object's 3D surfaces to a 2D texture space. Instead, triplanar mapping applies the texture map to three orthogonal planes, then projects these three planes to the surface of the Object.

This is the default behavior for all Materials in the pack. This means that you can use all Materials successfully on Objects that do not have UVs, as is often the case for parts that come from CAD applications.

This triplanar mapping function has several useful features:

It uses local space positions to avoid textures appearing to slide across the surfaces of the Objects.

Materials keep the same texel ratio when Objects are scaled.

The image below illustrates how triplanar mapping uses planar maps projected along the X (red), Y (green), and Z (blue) axes to create a complete procedural UV projection with minimal seams or stretching:



Since triplanar mapping is based on positions, each Material can use the actual physical size of an Object. This ensures material size consistency and provides accurate tiling:



Number

Object

Size

1

Floor

4 m x 4 m

2

Wooden Planks

2 m x1 m

3

Ceramic Tile

0.25 m x 0.25 m

Each Material also handles UV rotations properly:



Parallax Occlusion Mapping

Parallax occlusion mapping (POM) is a technique for creating definition in a Material by displacing an Object's UVs and simulating depth within a texture plane. In UE4, the height map is used to determine the height or depth of a pixel, with white being zero depth and black being maximum depth. This information is then used to determine if a pixel is occluded, or blocked from view, based on the camera angle. The result is additional definition within cracks and seams that add increased detail to Materials:





Raytracing Support

All Master Materials are set up to optimize performance for ray tracing by using the RayTracingQualitySwitchReplace node to execute a different branch of the Material graph on the second bounce.



For the second bounce, all surface normals are considered flat, and the surface roughness is considered either fully rough or fully reflective.

Commonly Exposed Parameters

Parameter Catagory

Settings

Base Color

Contains options for Color (RGBA), Color Maps, and Tinting options.

Metalness

Contains options for Metallic settings. Turning on Is Metallic applies a uniform texture to control Metallic attribute of the material. Different Metallic Maps can be applied to differentiate between metallic and non-metallic surfaces on the same Object.

Roughness

Contains settings for adjusting the Roughness of your Material. A Roughness Map can be applied to create specific wear patterns. The amount of Roughness can be randomized using Min and Max values. Roughness can be used to determine the glossiness of the Material.

Normal

Applies the chosen Normal Map to the material. Normal Intensity uses a value to control the effect.

UVs

Allows for the use of an Object's own UV map. Triplanar Mapping is enabled by default.

Master Materials

Decals

A versatile Material useful for creating road lines, dirt scattering, and other similar details in your scene. This Master Material works by projecting itself onto a surface and will adjust to follow its contours.

Parameter Catagory

Settings

Base Color

Color Map controls the decal that is displayed. Tint options control the final color of the decal.

Mask

Allows the application of an additional mask to further customize the shape of your decal.

Roughness

Applies surface irregularities and physical variation. Can be used to control the glossiness of the Material.

Normal

Applies the chosen Normal Map to the material. Normal Intensity uses a value to control the effect.

UVs

Allows for the use of an Object's own UV map. Triplanar Mapping is enabled by default.

Here we can see a few examples of decal materials being applied to a streat using the Asphalt 02 Material. The sidewalk, yellow lines, leaves, and STOP sign are all decals. The Autumn Leaves decal has had an additional Mask property applied to give it some further variation:



Glass

A flexible Master Material, Glass is one of the most used Materials in architectural visualization. This Material can be used to create clear, frosted, sanded or textured glass. It also supports glass with decals for the creation of specific window patterns.

Parameter Catagory

Settings

Glass

Supports adjusting of Glass Color and Opacity to create a variety of glass types. Adjusting Roughness represents subsurface irregularities in the glass and can be used to control glossiness. Glass Refraction amount and Distortion can be adjusted for additional variation.

Decal

Allows the application of a decal. This can be used to apply a variety of masks and effects, such as window advertisements.

Below you can see an example of the Glass Master Material with a decal applied to create a frosted glass top for an end table:



Light Source

The Light Source Master Material is used for anything that emits light. This Material is flexible enough to create any light source, from fluorescent lighting to neon signs.

Parameter Catagory

Settings

Base Color

Controls the color of your light using a Color Map and Tint options. Intensity controls the brightness of the light in candelas. Can be used to create anything emissive such as fluorescent lights, neon lights, or LED light bulbs.

Panning

Applies motion to your light source to create moving patterns.

Here you can see the Emissive Master Material used to create an emissive light bulb in a standing lamp:



Masked

The Masked Master Material can be used to create a variety of fences or grills. The mask texture, stored in the alpha channel of the base color map, controls the pattern and there are metallic options to make your screen from a variety of materials.

Parameter Catagory

Settings

Base Color

Applies a Color Map or Tint to the Material. The alpha channel is used to store the mask texture.

Metallic

Controls whether the Material is meant to be metallic. The Metallic Map can be used to distinguish between painted or rusted metal and raw metal on the same surface.

Roughness

Roughness Min and Max values apply surface irregularities and physical variation.

We can see below a Masked Material applied to a plane, then used as a security grate for a window:



Opaque

One of the most flexible Materials in the pack, the Opaque Master Material is used for any basic material such as metal, plastic, concrete, or walls. The addition of a Tint Mask can be used to control the coloring for even more versatility.

Parameter Catagory

Settings

Base Color

Applies a Color Map or Tint to the Material. A Tint Mask can be used to apply additional control to your color.

Metalness

Controls whether the Material is meant to be metallic. The Metallic Map can be used to distinguish between painted or rusted metal and raw metal on the same surface.

Roughness

Applies surface irregularities and physical variation. Can be used to control the glossiness of the Material.

Below we can see a scene built almost entirely from Materials that use the Opaque Master Material:



Opaque POM

Many Materials that include cracks or grooves benefit from POM. This technique procedurally uses height information to displace an Object's UV coordinates and simulate depth. This version of the Opaque Master Material incorporates POM to provide greater definition to materials such as brick, tile, stones, and roof tiles.

Parameter Catagory

Settings

Base Color

Applies a Color Map or Tint to the Material. A Tint Mask can be used to apply additional control to your color.

Metalness

Controls whether the Material is meant to be metallic. The Metallic Map can be used to distinguish between painted or rusted metal and raw metal on the same surface.

Roughness

Applies surface irregularities and physical variation. Can be used to control the glossiness of the Material.

Height

Required for Parallax Occlusion Mapping. Adds more depth and realism to Normal and Bump Mapping.

Here we can see an example of bricks that utilize the Opaque POM Master material. Note the definition of the cracks and seams:



Textile

A dependable Material for carpet, cloth, and leather, the Textile Master Material uses color and softness settings to create an assortment of materials.

Parameter Catagory

Settings

Base Color

Controls the pattern and color of the Material using the Color Map and Tint settings.

Roughness

Applies surface irregularities and physical variation. Can be used to control the glossiness of the Material.

Softness

Applies a fuzzy shading effect similar to velvet. These shading settings include Core Darkness, Edge Brightness, and control of a Subsurface coloring that is seen when light diffuses into the material.

Below we can see the effect of the softness settings on this carpet sample:





Wood

The Wood Master Material provides settings to create a variety of finished wood materials, such as parquet wood flooring, veneer, planks, and varnished wood. Raw wood materials such as plywood or older wood planks use the Opaque Master Material.

Parameter Catagory

Settings

Base Color

Color Map controls the color and pattern of the Material.

Roughness

Applies surface irregularities and physical variation. Can be used to control the glossiness of the Material.

Clear Coat

Applies a clear coat to the Material that affects glossiness. The intensity of this effect can be adjusted.

Scratches

Applies a scratch map to the Material to represent wear and tear. The intensity of the scratches can be adjusted.

Here we can see several different Materials showing off the versatility of this Master Material:

Several different examples of parquet flooring creating using the Wood Master Material



Window

Designed specifically for exterior windows in an outdoor setting, the Window Master Material can display a fake interior while realistically reflecting the outdoor environment. The Material uses a cubemap to determine the interior and can include blinds and a distortion effect.

Parameter Catagory

Settings

Window

Applies a color to the glass. The Roughness setting can be used to control glossiness. The Distortion setting allows for the manipulation of the fisheye effect when viewing the fake interior.

Fake Interior

Applies an Interior Cubemap to simulate a room behind the glass. Blinds are automatically applied, and the value of the parameter controls how far they are pulled down.

The Window Master Material is ideal for the exteriors of large buildings. Here we can see the glass distortions and fake interiors:



Disclaimer

The API reference is an early work in progress, and some information may be missing or out of date. It serves mainly as a low level index of Engine classes and functions. For tutorials, walkthroughs and detailed guides to programming with Unreal, please see the Unreal Engine Programming home on the web.

To explore the API from some of the most frequently encountered Unreal concepts and types, see the API getting started page.

Contents

Getting started · All constants · All functions · All enums · All classes · Class hierarchy

Runtime

AdvancedWidgets

Advertising

Support for mobile advertising providers.

AIModule

Controller for AI pawns and functionality to support behavior trees.

Analytics

Event-driven analytics reporting. Reports events over networked providers.

AnalyticsET

ET analytics provider

AnalyticsVisualEditing

AnimationCore

AnimGraphRuntime

AppFramework

ApplicationCore

AssetRegistry

Maintains a database of engine assets.

AudioAnalyzer

AudioCaptureCore

AudioCaptureRtAudio

AudioCodecEngine

AudioExtensions

AudioLinkEngine

AudioMixer

AudioMixerCore

AudioPlatformConfiguration

AugmentedReality

AutomationMessages

Declares message types for the Automation system.

AutomationTest

AutomationWorker

Declares message types for automation workers.

AVEncoder

AVIWriter

BinkAudioDecoder

BlueprintRuntime

BuildPatchServices

BuildSettings

CADKernel

Cbor

CEF3Utils

Chaos

ChaosCore

ChaosSolverEngine

ChaosVehiclesCore

ChaosVehiclesEngine

CinematicCamera

ClothingSystemRuntimeCommon

ClothingSystemRuntimeInterface

ClothingSystemRuntimeNv

ColorManagement

CookOnTheFly

Core

Core engine programming environment. Includes math library, standard container classes and support functionality.

CoreOnline

CoreUObject

Implements UObject and C++ reflection system.

CrunchCompression

CUDA

D3D12RHI

DatasmithCore

DeveloperSettings

DirectLink

DynamicPlayRate

Engine

Defines actors and components, and implements the game framework.

EngineMessages

Declares message types for the engine framework.

EngineSettings

Encapsulation of engine setting objects.

EyeTracker

FieldSystemEngine

Foliage

GameplayMediaEncoder

GameplayTags

Management of hierarchical tables of text-based tags. Allows management of bulk gameplay data.

GameplayTasks

GeForceNOWWrapper

GeometryCollectionEngine

GeometryCore

GeometryFramework

HeadMountedDisplay

Interface for HMD devices.

HTTP

HTTP request/response parsing interface.

HttpNetworkReplayStreaming

HttpServer

Icmp

IESFile

ImageCore

Storage and format conversion routines for image data.

ImageWrapper

Wrappers around various image file formats.

ImageWriteQueue

InputCore

Key definitions and related code

InputDevice

Interface for external controller implementations.

InstallBundleManager

InteractiveToolsFramework

InterchangeCore

InterchangeEngine

Json

JsonUtilities

JSON conversion routines for UObject types.

Landscape

Launch

Entry point for the engine

LauncherPlatform

LevelSequence

LiveLinkAnimationCore

LiveLinkInterface

LiveLinkMessageBusFramework

LocalFileNetworkReplayStreaming

MaterialShaderQualitySettings

Media

MediaAssets

MediaUtils

MeshConversion

MeshConversionEngineTypes

MeshDescription

MeshUtilitiesCommon

Messaging

Generalized messaging system. Allows passing strongly typed messages between endpoints using arbitrary transport protocols.

MessagingCommon

MessagingRpc

MoviePlayer

Platform and format-agnostic movie player

MoviePlayerProxy

MovieScene

MovieSceneCapture

MovieSceneTracks

MRMesh

NavigationSystem

Navmesh

Functionality to support the navigation mesh.

NetCommon

NetCore

NetworkFile

Cook-on-the-fly network filesystem.

NetworkFileSystem

Cook-on-the-fly network filesystem.

Networking

Platform networking support.

NetworkReplayStreaming

NonRealtimeAudioRenderer

NullDrv

Placeholder RHI implementation for systems that do not need to render.

NullNetworkReplayStreaming

OpenGLDrv

OpenGL RHI implementation.

Overlay

PacketHandler

PakFile

Reads from a monolithic PAK file in a packaged build.

PerfCounters

PhysicsCore

PhysXCooking

PortalMessages

PortalProxies

PortalRpc

PortalServices

PreLoadScreen

Projects

Functionality for manipulating .uproject and .uplugin files

PropertyPath

RawMesh

Raw mesh data used to construct optimized runtime rendering streams.

ReliabilityHandlerComponent

RenderCore

Core data structures and utilities shared by modules that perform rendering.

Renderer

Manages and renders scenes, the renderable information associated with each world. Includes the definition of all drawing policies and shaders.

RHI

Interface for rendering APIs.

RHICore

RigVM

RSA

SandboxFile

Redirects reads and writes through a user-specified sandbox directory.

Serialization

SessionMessages

Message objects used to communicate with running engine sessions.

SessionServices

Service interfaces used by the session management modules.

SignalProcessing

SkeletalMeshDescription

Slate

Unreal's declarative UI framework. Used to build the Unreal Editor, and for in-game UI.

SlateCore

Core declarations and types for Slate

SlateNullRenderer

SlateRHIRenderer

Default Slate rendering implementation which uses the default RHI API.

Sockets

Platform-abstracted socket implementation.

SoundFieldRendering

SSL

StageDataCore

StaticMeshDescription

StorageServerClient

StreamingFile

Cook-on-the-fly network filesystem.

StreamingPauseRendering

Module for handling rendering during blocking loads.

SynthBenchmark

Benchmarking routines used to assess system performance.

TextureUtilitiesCommon

TimeManagement

TraceLog

TypedElementFramework

TypedElementRuntime

UMG

Unreal Motion Graphics. Unreal's data-driven UI framework built on top of Slate. Work in progress.

VectorVM

Vector virtual machine. Experimental, intended for use in future features.

Voice

Voice capture interface

Voronoi

VulkanRHI

WebBrowser

WebSockets

WidgetCarousel

XmlParser

Simple XML parser.

Editor

ActorPickerMode

Actor picker for setting up attachments.

AddContentDialog

AdvancedPreviewScene

AIGraph

AnimationBlueprintEditor

AnimationBlueprintLibrary

AnimationEditor

AnimationModifiers

AnimGraph

Editor for animation graphs.

AssetPlacementEdMode

AssetTagsEditor

AudioEditor

BehaviorTreeEditor

Editor for behavior trees.

BlueprintEditorLibrary

BlueprintGraph

Extends graph editor functionality for Blueprints.

Blutility

Editor for Blueprint Utilities.

Cascade

Editor for particle systems.

ClassViewer

Browser and picker functionality for C++ and Blueprint classes.

ClothingSystemEditor

ClothingSystemEditorInterface

ClothPainter

CommonMenuExtensions

ComponentVisualizers

Editor specific code for drawing Actor components.

ConfigEditor

ContentBrowser

Browser and picker functionality for assets.

ContentBrowserData

CSVtoSVG

CurveAssetEditor

Editor for standalone curve assets.

CurveEditor

CurveTableEditor

Editor for curve table assets.

DataLayerEditor

DataTableEditor

Editor for tables of generic text data.

DerivedDataEditor

DetailCustomizations

Built-in customizations for the display of object properties.

DeviceProfileEditor

Editor for target device profiles.

DeviceProfileServices

Device profile manager.

DistCurveEditor

Editor for distribution curves.

Documentation

Support for displaying UDN documentation in the Editor.

EditorConfig

EditorFramework

EditorInteractiveToolsFramework

EditorSettingsViewer

Editor for UObject-based settings.

EditorStyle

Slate style for the Editor.

EditorSubsystem

EditorWidgets

Slate widgets used in various places in the Editor.

EnvironmentLightingViewer

FoliageEdit

Foliage editing and support classes.

FontEditor

Editor for font assets.

GameplayTasksEditor

GameProjectGeneration

Functionality for generating new game projects and associated data.

GraphEditor

Base editor functionality for node-based graphs, used in Blueprints, Materials etc.

HardwareTargeting

HierarchicalLODOutliner

InputBindingEditor

Editor for input bindings.

InternationalizationSettings

Settings for Editor region & language.

IntroTutorials

Implements editor tutorials.

Kismet

Blueprint editor.

KismetCompiler

Compiler for Blueprints.

KismetWidgets

Widgets used in the Blueprint editor.

LandscapeEditor

Landscape editing and support classes.

LandscapeEditorUtilities

Layers

Editor for creating & managing groups of actors by layer.

LevelAssetEditor

LevelEditor

Level editing and viewing tools. Container for many Editor functions.

LevelInstanceEditor

LocalizationCommandletExecution

LocalizationDashboard

MainFrame

Root window for the Editor.

MaterialEditor

Editor for materials, material functions & material instances.

MergeActors

MeshPaint

Vertex and texture painting tools.

MovieSceneCaptureDialog

MovieSceneTools

Tools for working with Sequencer movie scenes. Work in progress.

NewLevelDialog

Dialog allowing creation of a new level.

OverlayEditor

PackagesDialog

Dialog used to display package status & operations (saving, checking out etc.).

Persona

Editor for Skeletal meshes, skeletons and animation-related systems.

PhysicsAssetEditor

Physical asset editor, allowing setup of physics for skeletal meshes.

PIEPreviewDeviceProfileSelector

PIEPreviewDeviceSpecification

PinnedCommandList

PixelInspectorModule

PlacementMode

Drag-and-drop object placement tools.

PListEditor

Editor for Mac/iOS plist XML files.

PluginWarden

ProjectSettingsViewer

Viewer for project settings.

ProjectTargetPlatformEditor

Allows editing which platforms your project will support.

PropertyEditor

Functionality for editing UProperties in the details panel & property grid.

RewindDebuggerInterface

SceneDepthPickerMode

SceneOutliner

Browsing and picking functionality for Actors.

Sequencer

Tool for animating and coordinating object animations on timelines. Work in progress.

SequenceRecorder

SequencerWidgets

Slate widget definitions for Sequencer.

SerializedRecorderInterface

SkeletalMeshEditor

SkeletonEditor

SourceControlWindows

Windows used for various source control operations.

StaticMeshEditor

Editor for static meshes.

StatsViewer

Auditing tools for various statistics.

StatusBar

StringTableEditor

StructViewer

SubobjectDataInterface

SubobjectEditor

SwarmInterface

Interface for the swarm distributed lighting build system.

TextureEditor

Editor for textures.

ToolMenusEditor

TranslationEditor

Editor for translating localized text.

TurnkeySupport

UATHelper

UMGEditor

Editor for UMG assets.

UndoHistory

Inspector for the the undo/redo history.

UnrealEd

Core editor functionality.

UnrealEdMessages

Automation messages for the Editor.

ViewportInteraction

ViewportSnapping

In-viewport actor snapping functionality.

VirtualTexturingEditor

VREditor

WorkspaceMenuStructure

Base functionality for shared menu structure used in asset editors.

WorldBrowser

Editor for configuring streaming levels.

WorldPartitionEditor

Developer

AITestSuite

AnimationDataController

AnimationWidgets

AssetTools

Tools, widgets and helper functions for dealing with assets.

AudioFormatADPCM

Support for ADPCM decoding

AudioFormatBink

AudioFormatOgg

Support for OGG Vorbis decoding

AudioFormatOpus

Support for Opus decoding

AudioSettingsEditor

AutomationController

Entry point for the automation system.

AutomationDriver

AutomationWindow

Widgets & windows used to interact with the automation system.

BSPUtils

CollectionManager

System for managing collections of assets.

CollisionAnalyzer

Tool used to check collisions.

CookedEditor

DatasmithExporter

DerivedDataCache

Manages the cache of engine-optimized data derived from source assets.

DesktopPlatform

Generaized abstraction of a desktop platform's services.

DesktopWidgets

DeveloperToolSettings

DeviceManager

User interface for interacting with connected devices.

DirectoryWatcher

Platform-agnostic tracking of filesystem changes.

EditorAnalyticsSession

ExternalImagePicker

Widgets used to pick images on disk that are not used as textures.

FunctionalTesting

Tests engine functionality.

GameplayDebugger

Gameplay debugging utilities.

GeometryProcessingInterfaces

GraphColor

HierarchicalLODUtilities

HotReload

IoStoreUtilities

LauncherServices

Provides functionality to cook, package, deploy & launch games.

Localization

LocalizationService

LogVisualizer

UI for analyzing log output.

MaterialBaking

MaterialUtilities

Merge

Widgets used to merge conflicting revisions of UAssets. Currently only provides experimental support for merging blueprints.

MeshBoneReduction

Utility to remove bones from skeletons based on skeletal mesh LODs.

MeshBuilder

MeshBuilderCommon

MeshDescriptionOperations

MeshMergeUtilities

MeshReductionInterface

MeshUtilities

Mesh processing utilities including triangle stripping and LOD generation.

MeshUtilitiesEngine

MessageLog

Rich localized text logging functionality.

NaniteBuilder

OutputLog

Basic text logging functionality.

PakFileUtilities

PhysicsUtilities

Profiler

Core functionality & user interface for the Profiler.

ProfilerClient

Interface for talking to client sessions that can be profiled.

ProfilerMessages

Messages that are used by the profiler.

ProfilerService

Captures and dispatches profiling data.

ProjectLauncher

QuadricMeshReduction

RealtimeProfiler

Displays real-time profiler stats in the profiler window.

RigVMDeveloper

ScreenShotComparison

User interface for comparing captured screenshots.

ScreenShotComparisonTools

Support functionality for screenshot comparisons.

ScriptDisassembler

SessionFrontend

User interface for interacting with running sessions of the engine.

Settings

Base functionality for dealing with UObject-based settings.

SettingsEditor

Editing functionality for UObject-based settings.

ShaderCompilerCommon

Common functionality for compiling shaders.

ShaderFormatOpenGL

Wrapper around OpenGL shader compiler.

ShaderFormatVectorVM

ShaderPreprocessor

Preprocesses shader source.

SharedSettingsWidgets

Widgets used in various setting's detail customizations.

SkeletalMeshUtilitiesCommon

SlateReflector

Implementation of the Slate widget reflector.

SourceCodeAccess

Interface to source code editor plugins.

SourceControl

Interface for communicating with source control providers.

StandaloneRenderer

TargetDeviceServices

Exposes locally connected or remotely discovered network target devices.

TargetPlatform

Per-target platform functionality, including resources, devices & platform capabilities.

TaskGraph

Visualization widgets for the task graph system.

TextureBuild

TextureCompressor

Texture processing routines. Wrapper around compression formats, mipmap generation etc.

TextureFormat

TextureFormatDXT

DXT texture support.

TextureFormatIntelISPCTexComp

TextureFormatUncompressed

Uncompressed texture format handler.

ToolMenus

ToolWidgets

TraceAnalysis

TraceInsights

TraceServices

TreeMap

TurnkeyIO

UncontrolledChangelists

Virtualization

VisualGraphUtils

VulkanShaderFormat

Zen

Plugins

AbilitySystemGameFeatureActions

ActorLayerUtilities

ActorLayerUtilitiesEditor

ActorPalette

ActorSequence

ActorSequenceEditor

AdjustEditor

ADOSupport

AESGCMHandlerComponent

AESHandlerComponent

AISupportModule

AjaMedia

AjaMediaEditor

AjaMediaFactory

AjaMediaOutput

AlembicHairTranslatorModule

AlembicImporter

AlembicLibrary

AnalyticsBlueprintLibrary

AnalyticsMulticast

AnalyticsMulticastEditor

AndroidCameraEditor

AndroidCameraFactory

AndroidDeviceProfileCommandlets

AndroidDeviceProfileSelector

AndroidMediaEditor

AndroidMediaFactory

AndroidPermission

AnimationBudgetAllocator

AnimationLocomotionLibraryEditor

AnimationLocomotionLibraryRuntime

AnimationModifierLibrary

AnimationSharing

AnimationSharingEd

AnimationWarpingEditor

AnimationWarpingRuntime

ApexDestruction

ApexDestructionEditor

AppleARKit

AppleARKitFaceSupport

AppleARKitPoseTrackingLiveLink

AppleImageUtils

AppleImageUtilsBlueprintSupport

AppleProResMedia

AppleVision

AppleVisionBlueprintSupport

ArchVisCharacter

ARUtilities

AssetManagerEditor

AssetReferenceRestrictions

AssetSearch

AssetTags

AudioCapture

AudioCaptureEditor

AudioCaptureTimecodeProvider

AudioGameplay

AudioGameplayVolume

AudioModulation

AudioModulationEditor

AudioSynesthesia

AudioSynesthesiaCore

AudioSynesthesiaEditor

AudioWidgets

AutomationDriverTests

AutomationUtils

AutomationUtilsEditor

AvfMediaEditor

AvfMediaFactory

AvidDNxMedia

AxFImporter

AzureSpatialAnchors

BackChannel

BinkMediaPlayer

BinkMediaPlayerEditor

BlackmagicMedia

BlackmagicMediaEditor

BlackmagicMediaFactory

BlackmagicMediaOutput

BlankPlugin

Example of a minimal plugin. This can be used as a starting point when creating your own plugin.

BlendSpaceMotionAnalysis

BlueprintFileUtils

BlueprintMaterialTextureNodes

BlueprintStats

Provides Blueprint statistics.

Bridge

BspMode

Geometry placement tools.

CableComponent

Component which simulates a cable between two points.

CADInterfaces

CADKernelSurface

CADLibrary

CADTools

CameraCalibration

CameraCalibrationCore

CameraCalibrationCoreEditor

CameraCalibrationEditor

CameraShakePreviewer

CascadeToNiagaraConverter

ChaosCaching

ChaosCachingEditor

ChaosCloth

ChaosClothEditor

ChaosNiagara

ChaosSolverEditor

ChaosVehicles

ChaosVehiclesEditor

CharacterAI

ChunkDownloader

CLionSourceCodeAccess

CodeEditor

CodeView

Provides an in-editor code view of game classes and structures with direct IDE accessibility.

ColorCorrectRegions

ColorCorrectRegionsEditor

CommonConversationEditor

CommonConversationGraph

CommonConversationRuntime

CommonInput

CommonUI

CommonUIEditor

CommonUILayout

CompositePlane

Composure

ComposureEditor

ComposureLayersEditor

ComputeFramework

ComputeFrameworkEditor

Concert

ConcertSyncClient

ConcertSyncCore

ConcertSyncServer

ConcertSyncTest

ConcertSyncUI

ConcertTakeRecorder

ConcertTransport

ConsoleVariablesEditor

ContentBrowserAliasDataSource

ContentBrowserAssetDataSource

ContentBrowserClassDataSource

ContentBrowserFileDataSource

ContextualAnimation

ControlFlows

ControlRig

ControlRigDeveloper

ControlRigEditor

ControlRigSpline

ControlRigSplineEditor

CoreTechSurface

CryptoKeys

CryptoKeysOpenSSL

CurveEditorTools

CustomizableSequencerTracks

CustomizableSequencerTracksEditor

CustomMeshComponent

Component class that allows you to specify custom geometry via C++ or Blueprints.

DatabaseSupport

DataCharts

DataChartsEditor

DataprepCore

DataprepEditor

DataprepEditorScriptingUtilities

DataprepGeometryOperations

DataprepLibraries

DataRegistry

DataRegistryEditor

DatasmithC4DDynamicImporter

DatasmithC4DTranslator

DatasmithCADTranslator

DatasmithContent

DatasmithContentEditor

DatasmithDeltaGenTranslator

DatasmithDispatcher

DatasmithExternalSource

DatasmithFBXTranslator

DatasmithGLTFTranslator

DatasmithIFCTranslator

DatasmithImporter

DatasmithNativeTranslator

DatasmithOpenNurbsTranslator

DatasmithPLMXMLTranslator

DatasmithRuntime

DatasmithTranslator

DatasmithVREDTranslator

DatasmithWireTranslator2020

DataValidation

DirectLinkExtension

DirectLinkTest

DisasterRecoveryClient

DisplayCluster

DisplayClusterConfiguration

DisplayClusterConfigurator

DisplayClusterEditor

DisplayClusterMessageInterception

DisplayClusterMultiUser

DisplayClusterPostprocess

DisplayClusterProjection

DisplayClusterRemoteControlInterceptor

DisplayClusterShaders

DisplayClusterStageMonitoring

DMXBlueprintGraph

DMXDisplayCluster

DMXEditor

DMXFixtures

DMXPixelMappingBlueprintGraph

DMXPixelMappingCore

DMXPixelMappingEditor

DMXPixelMappingEditorWidgets

DMXPixelMappingRenderer

DMXPixelMappingRuntime

DMXProtocol

DMXProtocolArtNet

DMXProtocolBlueprintGraph

DMXProtocolEditor

DMXProtocolsACN

DMXRuntime

DTLSHandlerComponent

DummyMeshReconstructor

DynamicMesh

EditorDebugTools

EditorScriptingUtilities

EditorTests

ElectraBase

ElectraCDM

ElectraPlayerFactory

ElectraPlayerPlugin

ElectraPlayerRuntime

ElectraSamples

ElectraSubtitles

EncoderAMF

EncoderNVENC

EnhancedInput

EnvironmentQueryEditor

Editor for AI-navigation environment query templates. Allows the design of queries for such things as cover and spawn points.

EOSShared

EOSVoiceChat

ExampleAssetEditor

ExampleCustomDataInterface

ExampleDeviceProfileSelector

Example device profile sused show selection of device profiles on hardware

ExrReaderGpu

ExternalSource

FacialAnimation

FacialAnimationEditor

FastbuildController

FbxAutomationTestBuilder

FieldSystemEditor

FileLogging

FlurryEditor

FoliageSupport

FractureEditor

FullBodyIK

FunctionalTestingEditor

GameFeatures

GameFeaturesEditor

GameplayAbilities

Framework for asynchronous tasks which run over time while a player uses in-game abilities/powers.

GameplayAbilitiesEditor

Editor for gameplay abilities.

GameplayBehaviorsModule

GameplayCameras

GameplayInsights

GameplayInsightsEditor

GameplayTagsEditor

Editor for gameplay tag tables.

Gauntlet

GeometryAlgorithms

GeometryCache

GeometryCacheAbcFile

GeometryCacheEd

GeometryCacheSequencer

GeometryCacheStreamer

GeometryCacheTracks

GeometryCacheUSD

GeometryCollectionEditor

GeometryCollectionSequencer

GeometryCollectionTracks

GeometryFlowCore

GeometryFlowMeshProcessing

GeometryFlowMeshProcessingEditor

GeometryMode

Geometry editing tools.

GeometryProcessingAdapters

GeometryScriptingCore

GeometryScriptingEditor

GeoReferencing

GeoReferencingEditor

GitSourceControl

GizmoEdMode

GLTFCore

GLTFImporter

GoogleARCoreBase

GoogleARCoreRendering

GoogleARCoreServices

GooglePAD

GooglePADEditor

GPULightmass

GPULightmassEditor

HairModelingToolset

HairStrandsCore

HairStrandsEditor

HAPMedia

HDRIBackdrop

HLMedia

HLMediaEditor

HLMediaFactory

HoloLensPlatformEditor

HoloLensTargetPlatform

Hotfix

HPMotionController

HTNPlanner

HTNTestSuite

HTTPChunkInstaller

IKRig

IKRigDeveloper

IKRigEditor

ImagePlate

ImagePlateEditor

ImgMedia

ImgMediaEditor

ImgMediaEngine

ImgMediaFactory

InputBlueprintNodes

InputEditor

InterchangeDispatcher

InterchangeEditor

InterchangeEditorPipelines

InterchangeExport

InterchangeFbxParser

InterchangeImport

InterchangeMessages

InterchangeNodes

InterchangePipelines

InterchangeResultsBrowser

IOSReplayKit

JsonBlueprintGraph

JsonBlueprintUtilities

Landmass

LandmassEditor

LauncherChunkInstaller

LedWallCalibration

LedWallCalibrationEditor

LensDistortion

LevelSequenceEditor

LevelSnapshotFilters

LevelSnapshots

LevelSnapshotsEditor

LidarPointCloudEditor

LidarPointCloudRuntime

LightGizmos

LightWeightInstancesEditor

LinearTimecode

LiveLink

LiveLinkCamera

LiveLinkCameraEditor

LiveLinkCameraRecording

LiveLinkComponents

LiveLinkControlRig

LiveLinkCurveDebugUI

LiveLinkEditor

LiveLinkFreeD

LiveLinkGraphNode

LiveLinkLens

LiveLinkMasterLockit

LiveLinkMasterLockitEditor

LiveLinkMovieScene

LiveLinkMultiUser

LiveLinkOverNDisplay

LiveLinkPrestonMDR

LiveLinkPrestonMDREditor

LiveLinkSequencer

LiveLinkVRPN

LiveLinkXR

Lobby

LocationServicesAndroidEditor

LocationServicesBPLibrary

LocationServicesIOSEditor

LoginFlow

MassActors

MassAIBehavior

MassAIDebug

MassAIMovement

MassAIMovementEditor

MassAIReplication

MassAITestSuite

MassCommon

MassCrowd

MassEntity

MassEntityEditor

MassEntityTestSuite

MassGameplayDebug

MassGameplayEditor

MassLOD

MassMovement

MassReplication

MassRepresentation

MassSignals

MassSimulation

MassSmartObjects

MassSpawner

MaterialAnalyzer

MatineeToLevelSequence

MDLImporter

MediaCompositing

MediaCompositingEditor

MediaFrameworkUtilities

MediaFrameworkUtilitiesEditor

MediaIOCore

MediaIOEditor

MediaMovieStreamer

MediaPlayerEditor

MegascansPlugin

MeshLODToolset

MeshModelingTools

MeshModelingToolsEditorOnly

MeshModelingToolsExp

MeshPaintEditorMode

MeshPaintingToolset

MessagingDebugger

Provides a visual debugger for the messaging sub-system.

MetasoundEditor

MetasoundEngine

MetasoundEngineTest

MetasoundFrontend

MetasoundGenerator

MetasoundGraphCore

MetasoundStandardNodes

MfMediaEditor

MfMediaFactory

MicrosoftSpatialSound

MIDIDevice

MLAdapter

MLAdapterTestSuite

MLDeformer

MLDeformerEditor

MobileLauncherProfileWizard

MobilePatchingUtils

ModelingComponents

ModelingComponentsEditorOnly

ModelingEditorUI

ModelingOperators

ModelingOperatorsEditorOnly

ModelingToolsEditorMode

ModelProto

ModelProtoFileReader

ModularGameplay

MotionTrajectory

MotionWarping

MotoSynth

MotoSynthEditor

MoviePipelineMaskRenderPass

MovieRenderPipelineCore

MovieRenderPipelineEditor

MovieRenderPipelineRenderPasses

MovieRenderPipelineSettings

MultiUserClient

MultiUserClientLibrary

nDisplaySupport

NetcodeUnitTest

NetworkPrediction

NetworkPredictionExtras

NetworkPredictionExtrasLatentLoad

NetworkPredictionInsights

NeuralNetworkInference

NeuralNetworkInferenceEditor

NeuralNetworkInferenceProfiling

NeuralNetworkInferenceQA

NeuralNetworkInferenceShaders

NewGizmoEnable

Niagara

NiagaraAnimNotifies

NiagaraCore

NiagaraEditor

Editor for particles using the VectorVM.

NiagaraEditorWidgets

NiagaraFluids

NiagaraShader

NiagaraVertexFactories

NUTUnrealEngine

OculusAudio

OculusAudioEditor

OculusEditor

OculusHMD

OculusInput

OculusMR

OculusOpenXRHMD

OneSkyLocalizationService

OnlineBlueprintSupport

Blueprint online functionality. Latent functions, leaderboards etc.

OnlineServicesCommon

OnlineServicesEOS

OnlineServicesInterface

OnlineSubsystem

Interfaces for all online subsystems

OnlineSubsystemAmazon

Amazon account support

OnlineSubsystemEOS

OnlineSubsystemEOSPlus

OnlineSubsystemFacebook

Facebook integration layer

OnlineSubsystemGoogle

OnlineSubsystemNull

Placeholder OnlineSubsystem implementation when no other implementation is available.

OnlineSubsystemOculus

OnlineSubsystemSteam

Online support for Steam

OnlineSubsystemTwitch

OnlineSubsystemUtils

Online utility functions and classes

OodleNetworkHandlerComponent

OpenColorIO

OpenColorIOEditor

OpenCVHelper

OpenCVLensCalibration

OpenCVLensDistortion

OpenExrWrapper

OpenImageDenoise

OpenXRAR

OpenXREditor

OpenXREyeTracker

OpenXRHandTracking

OpenXRHMD

OpenXRInput

OpenXRMsftHandInteraction

OptimusCore

OptimusDeveloper

OptimusEditor

OptimusTools

OptionalMobileFeaturesBPLibrary

OSC

OSCModulationMixing

PanoramicCapture

Paper2D

Runtime component for Paper 2D engine support, containing the asset and component classes, etc...

Paper2DEditor

Contains the editor-specific classes and asset editors for working with Paper2D types (sprite editor, flipbook editor, etc...)

PaperSpriteSheetImporter

PaperTiledImporter

Importer for JSON tile maps and associated data, exported from Tiled 0.90 or later

ParametricSurface

ParametricSurfaceExtension

Party

PatchCheck

PBIK

PerforceSourceControl

Adds support for Perforce source control.

PerformanceMonitor

PFMExporter

PhysXVehicles

PhysXVehiclesEditor

PixelStreaming

PixWinPlugin

PlanarCut

PlasticSourceControl

PlatformCrypto

PlatformCryptoOpenSSL

PlatformCryptoTypes

PlayTimeLimit

PluginBrowser

PluginUtils

PointCloud

PoseSearch

PoseSearchEditor

PreLoadScreenMoviePlayer

ProceduralMeshComponent

ProceduralMeshComponentEditor

PropertyAccessEditor

PropertyAccessNode

ProxyLODMeshReduction

PythonAutomationTest

PythonScriptPlugin

PythonScriptPluginPreload

Qos

RawInput

Reflex

Rejoin

RemoteControl

RemoteControlCommon

RemoteControlInterception

RemoteControlProtocol

RemoteControlProtocolDMX

RemoteControlProtocolDMXEditor

RemoteControlProtocolMIDI

RemoteControlProtocolMIDIEditor

RemoteControlProtocolOSC

RemoteControlProtocolWidgets

RemoteControlUI

RemoteControlWebInterface

RemoteDatabaseSupport

RemoteSession

RemoteSessionEditor

RenderGraphInsights

ReplayTracks

ReplayTracksEditor

ReplicationGraph

ResonanceAudio

ResonanceAudioEditor

RewindDebugger

RewindDebuggerVLog

RHITests

RiderSourceCodeAccess

RigLogicEditor

RigLogicLib

RigLogicLibTest

RigLogicModule

RuntimePhysXCooking

RuntimeTests

SampleToolsEditorMode

ScreenReader

SequencerAnimTools

SequencerPlaylists

SequencerScripting

SequencerScriptingEditor

Shotgrid

SignificanceManager

SimpleHMD

SkeletalMerging

SkeletalMeshReduction

SlateInsights

SlateScreenReader

SlateScriptingCommands

SmartObjectsEditorModule

SmartObjectsModule

SmartObjectsTestSuite

SmartSnapping

Support for snapping to arbitrary Z-planes. Work in progress.

SoundCueTemplates

SoundCueTemplatesEditor

SoundFields

SoundMod

Support for audio tracker modules using libxmp.

SoundModImporter

Importer for SoundMod assets.

SoundUtilities

SoundUtilitiesEditor

SourceFilteringCore

SourceFilteringEditor

SourceFilteringTrace

Spatialization

SpatializationEditor

SpeedTreeImporter

Importer for SpeedTree SRT files.

StageDataProvider

StageMonitor

StageMonitorCommon

StageMonitorEditor

StateTreeEditorModule

StateTreeModule

StateTreeTestSuite

StaticMeshEditorModeling

SteamAudio

SteamAudioEditor

SteamController

SteamShared

SteamSockets

SteamVR

SteamVREditor

SteamVRInput

SteamVRInputDevice

StructUtils

StructUtilsEditor

StructUtilsTestSuite

StylusInput

SubversionSourceControl

Adds support for Subversion source control.

SunPosition

SwitchboardEditor

Synthesis

SynthesisEditor

TakeMovieScene

TakeRecorder

TakeRecorderSources

TakesCore

TakeSequencer

TakeTrackRecorders

TcpMessaging

TemplateSequence

TemplateSequenceEditor

TestSamples

Text3D

Text3DEditor

TextToSpeech

TextureAlignMode

Interactive UV editing tools for geometry.

TextureFormatOodle

TextureShare

TextureShareCore

TextureShareD3D11

TextureShareD3D12

ThirdPartyHelperAndDLLLoader

TimecodeSynchronizer

TimecodeSynchronizerEditor

TimedDataMonitor

TimedDataMonitorEditor

TraceDataFiltering

UdpMessaging

Adds a UDP based transport and tunneling layer to the messaging sub-system.

UEOpenExrRTTI

UnrealInsightsInterface

UnrealUSDWrapper

UObjectPlugin

Example of a plugin which declares its own UObject type.

USDClasses

USDExporter

USDMultiUser

USDSchemas

USDStage

USDStageEditor

USDStageEditorViewModels

USDStageImporter

USDTests

USDUtilities

UVEditor

UVEditorTools

UVEditorToolsEditorOnly

VariantManager

VariantManagerContent

VariantManagerContentEditor

VCamCore

VCamCoreEditor

VCamInput

VirtualCamera

VirtualCameraEditor

VirtualHeightfieldMesh

VirtualHeightfieldMeshEditor

VisualStudioCodeSourceCodeAccess

VisualStudioSourceCodeAccess

Bridge to allow the editor to interop with Visual Studio.

VPBookmark

VPBookmarkEditor

VPMaterialsEditor

VPUtilities

VPUtilitiesEditor

WarpUtils

Water

WaterEditor

WebAuth

WebBrowserNativeProxy

WebMMedia

WebMMediaEditor

WebMMediaFactory

WebMMoviePlayer

WebRemoteControl

WebSocketNetworking

WindowsDeviceProfileSelector

Used to determine the device settings for Windows platforms.

WindowsMoviePlayer

Windows-specific movie player using Media Foundation.

WmfMedia

WmfMediaEditor

WmfMediaFactory

WorldBuilding

WorldPartitionHLODUtilities

XGEController

XRVisualization

ZoneGraph

ZoneGraphAnnotations

ZoneGraphDebug

ZoneGraphEditor

ZoneGraphTestSuite

Choose your operating system:

Windows

macOS

Linux

Disclaimer

Actions

Categories

Disclaimer

The Blueprint API reference is an early work in progress, and some information may be missing or out of date. It strives to reflect all available nodes, but it is not guaranteed to be an exhaustive list.

Actions

Add Comment...

Comment:

Add Math Expression...

Collapsed composite node

Add Reroute Node...

Reroute Node (reroutes wires)

Add Return Node...

The node terminates the function's execution. It returns output parameters.

Add Timeline...

Timeline node allows values to be keyframed over time. Double click to open timeline editor.

Categories

Abilities

Abilities

Ability

Ability

Accessibility

Accessibility

Activatable Widget

Activatable Widget

Activatable Widget Container

Activatable Widget Container

Activatable Widget Stack

Activatable Widget Stack

Active VCam Update

Active VCam Update

Actor

Actor

Add Event

Event nodes start execution in response to something happening. Examples would be a button press or a collision.

Advanced

Advanced

AI

AI

Alignment

Alignment

Analytics

Analytics

Android File Server

Android File Server

Android Permission

Android Permission

Anim Notify

Anim Notify

Animation

Animation

Animation Asset

Animation Asset

Animation Blueprint Library

Animation Blueprint Library

Animation Blueprint Linking

Animation Blueprint Linking

Animation Budget

Animation Budget

Animation Character Movement

Animation Character Movement

Animation Data

Animation Data

Animation Data Model

Animation Data Model

Animation Editor Extensions

Animation Editor Extensions

Animation Graph

Animation Graph

Animation Sharing

Animation Sharing

Appearance

Appearance

Apple Vision

Apple Vision

AR

AR

AR Augmented Reality

AR Augmented Reality

AR Gameplay

AR Gameplay

AR Gameplay

AR Gameplay

AR Settings

AR Settings

AR Shared World

AR Shared World

AR Utilities

AR Utilities

Asserts

Asserts

Asset Data

Asset Data

Asset Import Data

Asset Import Data

Asset Manager

Asset Manager

Asset Player

Asset Player

Asset Registry

Asset Registry

Asset Tags

Asset Tags

Asset Validation

Asset Validation

Assets

Assets

Async Action

Async Action

Attribute

Attribute

Attribute Data

Attribute Data

Attributes

Attributes

Audio

Audio

Audio Analyzer

Audio Analyzer

Audio Capture

Audio Capture

Audio Delegates

Audio Delegates

Audio Engine Subsystems

Audio Engine Subsystems

Audio Gameplay

Audio Gameplay

Audio Gameplay Condition

Audio Gameplay Condition

Audio Gameplay Volume

Audio Gameplay Volume

Audio Link

Audio Link

Audio Volume

Audio Volume

Augmented Reality

Augmented Reality

Auto Player Activation

Auto Player Activation

Automation

Automation

Azure Spatial Anchors

Azure Spatial Anchors

Base Button Group

Base Button Group

Baseline

Baseline

Behavior

Behavior

Behaviour

Behaviour

Bink

Bink

Blueprint

Blueprint

Blueprint Upgrade Tools

Blueprint Upgrade Tools

Bookmarks

Bookmarks

Buoyancy

Buoyancy

Button

Button

Cable

Cable

Cache

Cache

Caching

Caching

Calibration

Calibration

Camera

Camera

Camera Anim Inst

Camera Anim Inst

Camera Animation

Camera Animation

Camera Collision

Camera Collision

Camera Fades

Camera Fades

Camera Lens Effect

Camera Lens Effect

Camera Modifier

Camera Modifier

Camera Shake

Camera Shake

Camera Shakes

Camera Shakes

Canvas

Canvas

Canvas Panel

Canvas Panel

Canvas Render Target 2D

Canvas Render Target 2D

Capture

Capture

Carousel

Carousel

Carousel Nav Bar

Carousel Nav Bar

Chaos

Chaos

Chaos Physics

Chaos Physics

Character

Character

Cheat Manager

Cheat Manager

Check Box

Check Box

Child Actor Component

Child Actor Component

Child Layout

Child Layout

Cine Camera

Cine Camera

Cinematic

Cinematic

Cinematics

Cinematics

Class

Class

Classes

Classes

Clips

Clips

Clothing

Clothing

Clothing Simulation

Clothing Simulation

Collision

Collision

Combo Box

Combo Box

Common Action Widget

Common Action Widget

Common Border

Common Border

Common Border Style

Common Border Style

Common Bound Action Bar

Common Bound Action Bar

Common Button

Common Button

Common Button Internal

Common Button Internal

Common Button Style

Common Button Style

Common Input Subsystem

Common Input Subsystem

Common Text

Common Text

Common Text Style

Common Text Style

Common UI

Common UI

Common UISubsystem

Common UISubsystem

Common User Widget

Common User Widget

Common Visibility Switcher

Common Visibility Switcher

Common Widget Switcher

Common Widget Switcher

Component Conversion

Component Conversion

Component Space Pose Context

Component Space Pose Context

Components

Components

Compositing Pass

Compositing Pass

Composure

Composure

Compsure

Compsure

Compute

Compute

Console Variables Editor

Console Variables Editor

Content Browser

Content Browser

Content Layout

Content Layout

Contextual Anim

Contextual Anim

Contextual Animation System

Contextual Animation System

Control

Control

Control Actor

Control Actor

Control Rig

Control Rig

Control Rig Blueprint

Control Rig Blueprint

Control Rig Editor Extensions

Control Rig Editor Extensions

Controller

Controller

Conversation

Conversation

Conversion Utils

Conversion Utils

Cosmetic

Cosmetic

Crowd

Crowd

Curve

Curve

Curve Data

Curve Data

Curves

Curves

Custom Attributes

Custom Attributes

CVars

CVars

Data Driven CVar

Data Driven CVar

Data Layer

Data Layer

Data Layers

Data Layers

Data Registry

Data Registry

Data Set

Data Set

Data Table

Data Table

Dataprep

Dataprep

Dataprep Consumer

Dataprep Consumer

Datasmith

Datasmith

Datasmith Consumer Internal

Datasmith Consumer Internal

Datasmith Runtime

Datasmith Runtime

Datasmith Runtime Helper

Datasmith Runtime Helper

Datasmith User Data

Datasmith User Data

Date Time Text Block

Date Time Text Block

Debug

Debug

Debug Camera

Debug Camera

Default

Default

Deformer

Deformer

Delay

Delay

Destruction Listener

Destruction Listener

Development

Development

Direct Link

Direct Link

Distance Matching

Distance Matching

Distortion

Distortion

DMX

DMX

DMX Component

DMX Component

DMX Fixture

DMX Fixture

DMX Matrix Fixture

DMX Matrix Fixture

DMXGDTF

DMXGDTF

Documentation

Documentation

Dynamic Entry Box

Dynamic Entry Box

Dynamic Mesh

Dynamic Mesh

Dynamic Mesh Actor

Dynamic Mesh Actor

Dynamic Mesh Component

Dynamic Mesh Component

Editor

Editor

Editor Scripting

Editor Scripting

Editor Scripting

Editor Scripting

Effects

Effects

Engine Subsystems

Engine Subsystems

EQS

EQS

Event

Event

Event Dispatchers

Event Dispatchers

Events

Events

Execution

Execution

Execution Context

Execution Context

Expandable Area

Expandable Area

Expansion

Expansion

Export Context

Export Context

Eye Tracking

Eye Tracking

Field

Field

File Utils

File Utils

Filter

Filter

Fixture Settings

Fixture Settings

Fly To Location

Focus

Focus

Foliage

Foliage

Force Feedback

Force Feedback

FRig VMCompiler

FRig VMCompiler

Functional Testing

Functional Testing

FXConverter Utilities

FXConverter Utilities

Game

Game

Game Instance Subsystems

Game Instance Subsystems

Game Options

Game Options

Game State

Game State

Gameplay

Game

Gameplay Abilities

Gameplay Abilities

Gameplay Attributes

Gameplay Attributes

Gameplay Behavior

Gameplay Behavior

Gameplay Cue

Gameplay Cue

Gameplay Cue Notify

Gameplay Cue Notify

Gameplay Effects

Gameplay Effects

Gameplay Tags

Gameplay Tags

Gameplay Tasks

Gameplay Tasks

General

General

Geo Referencing

Geo Referencing

Geometry Script

Geometry Script

Google ARCore

Google ARCore

Google Arcore Augmentedimages

Google Arcore Augmentedimages

Google ARCore Services

Google ARCore Services

Google PAD

Google PAD

GPULightmass

GPULightmass

Groom

Groom

Group

Group

Guid

Guid

Head Mounted Display

Head Mounted Display

Hotfix

Hotfix

HUD

HUD

IKRig Goals

IKRig Goals

Image Conversion

Image Conversion

Img Media

Img Media

Imported Sequences

Imported Sequences

Inertial Blend

Inertial Blend

Initialization Context

Initialization Context

Input

These are nodes that provide input from various sources (keyboard, mouse, gamepad etc.)

Inputs

Inputs

Interaction

Interaction

Interactor

Interactor

Interchange

Interchange

Invalidation Box

Invalidation Box

IOSReplay Kit

IOSReplay Kit

Json

Json

Landscape

Landscape

Landscape Splines

Landscape Splines

Layer

Layer

Layer Utils

Layer Utils

Layers

Layers

Layout

Layout

Lazy Content

Lazy Content

Lazy Image

Lazy Image

Lens Bloom Settings

Lens Bloom Settings

Lens Distortion

Lens Distortion

Lens Distortion

Lens Distortion

Lens Effect

Lens Effect

Lens Table

Lens Table

Level

Level

Level Editor

Level Editor

Level Sequence

Level Sequence

Level Sequence Editor

Level Sequence Editor

Level Snapshots

Level Snapshots

Level Streaming

Level Streaming

Level Variant Sets

Level Variant Sets

Lidar Point Cloud

Lidar Point Cloud

Light Weight Instance

Light Weight Instance

Lighting

Lighting

Linked Anim Graph

Linked Anim Graph

List View

List View

List View Base

List View Base

Live Link

Live Link

Live Link Debug

Live Link Debug

Live Link Debugger

Live Link Debugger

Load Guard

Load Guard

Local Player Subsystems

Local Player Subsystems

Location

Location

LOD

LOD

Log

Log

Mapping

Mapping

Mass

Mass

Material Editing

Material Editing

Math

Math

Media

Media

Media Profile

Media Profile

Media Proxy

Media Proxy

Menu Anchor

Menu Anchor

Mesh

Mesh

Mesh Description

Mesh Description

Mesh Merge

Mesh Merge

Mesh Merging Library

Mesh Merging Library

Mesh Reconstruction

Mesh Reconstruction

Meta Sounds

Meta Sounds

MIDI Device Controller

MIDI Device Controller

MIDI Device Input Controller

MIDI Device Input Controller

MIDI Device Manager

MIDI Device Manager

MIDI Device Output Controller

MIDI Device Output Controller

Miscellaneous

Miscellaneous

MLDeformer

MLDeformer

Mobile

Mobile

Mobile Patching

Mobile Patching

Mobility

Mobility

Mock Ability

Mock Ability

Mock Ability System

Mock Ability System

Mock Grenade

Mock Grenade

Mock Physics Cues

Mock Physics Cues

Modeling Objects

Modeling Objects

Modifier

Modifier

Montage

Montage

Motion Controller

Motion Controller

Motion Controller Update

Motion Controller Update

Motion Trajectory

Motion Trajectory

Motion Warping

Motion Warping

Moto Synth

Moto Synth

Movement

Movement

Movie Render Pipeline

Movie Render Pipeline

Movie Scene

Movie Scene

Multi- User Client

Multi- User Client

Multi- User Presence

Multi- User Presence

Multi- User Source Control

Multi- User Source Control

N Display

N Display

Nav Mesh

Nav Mesh

NDisplay

NDisplay

NDisplay Projection

NDisplay Projection

Network Physics

Network Physics

Networking

Networking

Neural Network Inference QA

Neural Network Inference QA

Niagara

Niagara

Niagara Actor

Niagara Actor

Notifies

Notifies

Numeral Formating

Numeral Formating

Numeric Interpolation

Numeric Interpolation

Numeric Text Block

Numeric Text Block

Oculus

Oculus

Oculus Library

Oculus Library

Oculus MR

Oculus MR

Online

Online

Open Color IO

Open Color IO

Open CV

Open CV

Open CV

Open CV

Optimus Node Graph

Optimus Node Graph

Output

Output

Outputs

Outputs

Painting

Painting

Panel

Panel

Particle System

Particle System

Passthrough

Passthrough

Pawn

Pawn

Pawn Action

Pawn Action

Perf

Perf

Performance

Performance

Performance

Performance

Persona Editor Extensions

Persona Editor Extensions

PFMExporter

PFMExporter

Physical Animation

Physical Animation

Physics

Physics

Physics Volume

Physics Volume

Pixel Streaming

Pixel Streaming

Pixel Streaming Audio Component

Pixel Streaming Audio Component

Pixel Streaming Delegates

Pixel Streaming Delegates

Pixel Streaming Freeze Frame

Pixel Streaming Freeze Frame

Pixel Streaming Input

Pixel Streaming Input

Pixel Streaming Transmit

Pixel Streaming Transmit

Platform

Platform

Player

Player

Player Compositing Target

Player Compositing Target

Player Controller

Player Controller

Player State

Player State

Point Cloud

Point Cloud

Pose

Pose

Pose Asset

Pose Asset

Pose Context

Pose Context

Pose Search

Pose Search

Preview

Preview

Prim Utils

Prim Utils

Procedural Foliage Simulation

Procedural Foliage Simulation

Progress

Progress

Property Value

Property Value

Provider

Provider

Py Automation Test

Py Automation Test

Python

Python

Quantization

Quantization

Quartz Clock

Quartz Clock

Quartz Clock Handle

Quartz Clock Handle

Quartz Subsystem

Quartz Subsystem

Rail Components

Rail Components

Raw Input

Raw Input

Ray Tracing

Ray Tracing

RC

RC

Reflex

Reflex

Remote Control Preset

Remote Control Preset

Remote Control Web Interface

Remote Control Web Interface

Rendering

Rendering

Replay

Replay

Report

Report

Reporting

Reporting

Resonance Audio

Resonance Audio

Resonance Audio Room Effect Settings

Resonance Audio Room Effect Settings

Retainer

Retainer

Reticle

Reticle

Rig VM

Rig VM

Rig VMArray Node

Rig VMArray Node

Rig VMComment Node

Rig VMComment Node

Rig VMController

Rig VMController

Rig VMEnum Node

Rig VMEnum Node

Rig VMGraph

Rig VMGraph

Rig VMInjection Info

Rig VMInjection Info

Rig VMLibrary Node

Rig VMLibrary Node

Rig VMLink

Rig VMLink

Rig VMNode

Rig VMNode

Rig VMParameter Node

Rig VMParameter Node

Rig VMPin

Rig VMPin

Rig VMPrototype Node

Rig VMPrototype Node

Rig VMReroute Node

Rig VMReroute Node

Rig VMUnit Node

Rig VMUnit Node

Rig VMVariable Node

Rig VMVariable Node

Root Motion

Root Motion

Rotate

Rotate

Safe Zone

Safe Zone

Save Game

Save Game

Scale

Scale

Scouting

Scouting

Scripting

Scripting

Scroll

Scroll

Scrolling

Scrolling

Selection

Selection

Sequence Evaluator

Sequence Evaluator

Sequence Player

Sequence Player

Sequence Recording

Sequence Recording

Sequencer

Sequencer

Sequencer Playlists

Sequencer Playlists

Services

Services

Settings

Settings

Simulation

Simulation

Size

Size

Skeletal Control

Skeletal Control

Skeletal Mesh Utilities

Skeletal Mesh Utilities

Skeleton

Skeleton

Skeleton Merge

Skeleton Merge

Skills

Skills

Sky Light

Sky Light

Slate Screen Reader

Slate Screen Reader

Slot

Slot

Smart Object

Smart Object

Sound Utilities BPLibrary

Sound Utilities BPLibrary

Spawning

Spawning

Spec

Spec

Spin Box

Spin Box

Spline

Spline

Spline Mesh

Spline Mesh

Spring Arm

Spring Arm

Sprite

Sprite

State Machine

State Machine

Static Mesh

Static Mesh

Static Mesh Utilities

Static Mesh Utilities

Steam VR

Steam VR

Steam VR Input

Steam VR Input

Stereo

Stereo

Streaming

Streaming

Subobject Data

Subobject Data

Subobject Data Subsystem

Subobject Data Subsystem

Sun Position

Sun Position

Switch Actor

Switch Actor

Switchboard

Switchboard

Switcher

Switcher

Sync Group

Sync Group

Synchronization

Synchronization

Synth

Synth

Synthesis

Synthesis

Synthesis Utilities Library

Synthesis Utilities Library

Tab List

Tab List

Take

Take

Take Recorder

Take Recorder

Take Recorder Actor Source

Take Recorder Actor Source

Task

Task

Teleporter

Teleporter

Test

Test

Text Box

Text Box

Text To Speech

Texture

Texture

Texture Share

Texture Share

Tick

Tick

Tile View

Tile View

Time Synth

Time Synth

Timed Data Monitor

Timed Data Monitor

Tone Generator

Tone Generator

Tool Menus

Tool Menus

Training Data

Training Data

Transactions

Transactions

Transform from Bounds

Transformation

Transformation

Tree View

Tree View

Trigger

Trigger

Tutorial

Tutorial

Typed Element Framework

Typed Element Framework

Typed Element Interfaces

Typed Element Interfaces

Update Context

Update Context

URig Hierarchy

URig Hierarchy

URig Hierarchy Controller

URig Hierarchy Controller

USD

USD

USD Foliage Exporter

USD Foliage Exporter

User Interface

User Interface

User List Entry

User List Entry

User Object List Entry

User Object List Entry

Utilities

Utility nodes for dealing with flow control, arrays, strings, names, text etc.

Utility

Utility

UVREditor Interactor

UVREditor Interactor

Validation

Validation

Variables

Access to get and set variables within this Blueprint.

Variant

Variant

Variant Manager

Variant Manager

Variant Set

Variant Set

Vehicle

Vehicle

Vehicles

Vehicles

Vertex Paint

Vertex Paint

View

View

Viewport

Viewport

Viewport Stats Subsystem

Viewport Stats Subsystem

Viewport World Interaction

Viewport World Interaction

Virtual Camera

Virtual Camera

Virtual Camera

Virtual Camera

Virtual Production

Virtual Production

Virtual Texture

Virtual Texture

VPBookmarks

VPBookmarks

VR

VR

VREditor Interactor

VREditor Interactor

VREditor Mode

VREditor Mode

Water

Water

Water Body

Water Body

Water Mesh Preview

Water Mesh Preview

Wave

Wave

Wave Function Collapse

Wave Function Collapse

WFCFunctions

WFCFunctions

Widget

Widget

Widget Event

Widget Event

Wind

Wind

World Partition

World Partition

World Subsystems

World Subsystems

World Utils

World Utils

XR

XR

Zone

Zone

Zone Graph Annotations

Zone Graph Annotations

